Ken Thomases : winemac: Add infrastructure to convert from Cocoa event time to Wine tick count.

Alexandre Julliard julliard at winehq.org
Mon Jan 28 13:43:19 CST 2013


Module: wine
Branch: master
Commit: a22be47fcf172793a67b851fd8c4b00c97b71072
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a22be47fcf172793a67b851fd8c4b00c97b71072

Author: Ken Thomases <ken at 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;




More information about the wine-cvs mailing list