Module: wine Branch: master Commit: a22be47fcf172793a67b851fd8c4b00c97b71072 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a22be47fcf172793a67b851fd8...
Author: Ken Thomases ken@codeweavers.com Date: Sun Jan 27 16:19:33 2013 -0600
winemac: Add infrastructure to convert from Cocoa event time to Wine tick count.
---
dlls/winemac.drv/cocoa_app.h | 5 +++++ dlls/winemac.drv/cocoa_app.m | 10 ++++++++++ dlls/winemac.drv/cocoa_main.m | 36 +++++++++++++++++++++++++++--------- dlls/winemac.drv/macdrv_cocoa.h | 2 +- dlls/winemac.drv/macdrv_main.c | 2 +- 5 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h index 490c2ee..0955dea 100644 --- a/dlls/winemac.drv/cocoa_app.h +++ b/dlls/winemac.drv/cocoa_app.h @@ -33,6 +33,8 @@ { NSMutableArray* eventQueues; NSLock* eventQueuesLock; + + NSTimeInterval eventTimeAdjustment; }
- (void) transformProcessToForeground; @@ -40,6 +42,9 @@ - (BOOL) registerEventQueue:(WineEventQueue*)queue; - (void) unregisterEventQueue:(WineEventQueue*)queue;
+ - (void) computeEventTimeAdjustmentFromTicks:(unsigned long long)tickcount uptime:(uint64_t)uptime_ns; + - (double) ticksForEventTime:(NSTimeInterval)eventTime; + @end
void OnMainThread(dispatch_block_t block); diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index bcdfee0..638e642 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -108,6 +108,16 @@ int macdrv_err_on; [eventQueuesLock unlock]; }
+ - (void) computeEventTimeAdjustmentFromTicks:(unsigned long long)tickcount uptime:(uint64_t)uptime_ns + { + eventTimeAdjustment = (tickcount / 1000.0) - (uptime_ns / (double)NSEC_PER_SEC); + } + + - (double) ticksForEventTime:(NSTimeInterval)eventTime + { + return (eventTime + eventTimeAdjustment) * 1000; + } + @end
/*********************************************************************** diff --git a/dlls/winemac.drv/cocoa_main.m b/dlls/winemac.drv/cocoa_main.m index d920036..f0e501d 100644 --- a/dlls/winemac.drv/cocoa_main.m +++ b/dlls/winemac.drv/cocoa_main.m @@ -19,6 +19,8 @@ */
#import <AppKit/AppKit.h> +#include <mach/mach.h> +#include <mach/mach_time.h>
#include "macdrv_cocoa.h" #import "cocoa_app.h" @@ -33,6 +35,13 @@ enum { };
+struct cocoa_app_startup_info { + NSConditionLock* lock; + unsigned long long tickcount; + uint64_t uptime_ns; +}; + + /*********************************************************************** * run_cocoa_app * @@ -50,12 +59,14 @@ enum { */ static void run_cocoa_app(void* info) { - NSConditionLock* lock = info; + struct cocoa_app_startup_info* startup_info = info; + NSConditionLock* lock = startup_info->lock;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[WineApplication sharedApplication]; [NSApp setDelegate:(WineApplication*)NSApp]; + [NSApp computeEventTimeAdjustmentFromTicks:startup_info->tickcount uptime:startup_info->uptime_ns];
/* Retain the lock while we're using it, so macdrv_start_cocoa_app() doesn't deallocate it in the middle of us unlocking it. */ @@ -78,11 +89,13 @@ static void run_cocoa_app(void* info) * * Returns 0 on success, non-zero on failure. */ -int macdrv_start_cocoa_app(void) +int macdrv_start_cocoa_app(unsigned long long tickcount) { int ret = -1; CFRunLoopSourceRef source; - NSConditionLock* lock; + struct cocoa_app_startup_info startup_info; + uint64_t uptime_mach = mach_absolute_time(); + mach_timebase_info_data_t mach_timebase; NSDate* timeLimit; CFRunLoopSourceContext source_context = { 0 };
@@ -94,29 +107,34 @@ int macdrv_start_cocoa_app(void) toTarget:[NSThread class] withObject:nil];
- lock = [[NSConditionLock alloc] initWithCondition:COCOA_APP_NOT_RUNNING]; + startup_info.lock = [[NSConditionLock alloc] initWithCondition:COCOA_APP_NOT_RUNNING]; + startup_info.tickcount = tickcount; + + mach_timebase_info(&mach_timebase); + startup_info.uptime_ns = uptime_mach * mach_timebase.numer / mach_timebase.denom; + timeLimit = [NSDate dateWithTimeIntervalSinceNow:5];
- source_context.info = lock; + source_context.info = &startup_info; source_context.perform = run_cocoa_app; source = CFRunLoopSourceCreate(NULL, 0, &source_context);
- if (source && lock && timeLimit) + if (source && startup_info.lock && timeLimit) { CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes); CFRunLoopSourceSignal(source); CFRunLoopWakeUp(CFRunLoopGetMain());
- if ([lock lockWhenCondition:COCOA_APP_RUNNING beforeDate:timeLimit]) + if ([startup_info.lock lockWhenCondition:COCOA_APP_RUNNING beforeDate:timeLimit]) { - [lock unlock]; + [startup_info.lock unlock]; ret = 0; } }
if (source) CFRelease(source); - [lock release]; + [startup_info.lock release]; [pool release]; return ret; } diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 550c63e..70be367 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -112,7 +112,7 @@ struct macdrv_display { /* main */ extern int macdrv_err_on;
-extern int macdrv_start_cocoa_app(void) DECLSPEC_HIDDEN; +extern int macdrv_start_cocoa_app(unsigned long long tickcount) DECLSPEC_HIDDEN;
/* display */ diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index 2a9e0ac..a21390d 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -40,7 +40,7 @@ static BOOL process_attach(void) if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
macdrv_err_on = ERR_ON(macdrv); - if (macdrv_start_cocoa_app()) + if (macdrv_start_cocoa_app(GetTickCount64())) { ERR("Failed to start Cocoa app main loop\n"); return FALSE;