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