Commit a22be47f authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

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

parent 6e59740e
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
{ {
NSMutableArray* eventQueues; NSMutableArray* eventQueues;
NSLock* eventQueuesLock; NSLock* eventQueuesLock;
NSTimeInterval eventTimeAdjustment;
} }
- (void) transformProcessToForeground; - (void) transformProcessToForeground;
...@@ -40,6 +42,9 @@ ...@@ -40,6 +42,9 @@
- (BOOL) registerEventQueue:(WineEventQueue*)queue; - (BOOL) registerEventQueue:(WineEventQueue*)queue;
- (void) unregisterEventQueue:(WineEventQueue*)queue; - (void) unregisterEventQueue:(WineEventQueue*)queue;
- (void) computeEventTimeAdjustmentFromTicks:(unsigned long long)tickcount uptime:(uint64_t)uptime_ns;
- (double) ticksForEventTime:(NSTimeInterval)eventTime;
@end @end
void OnMainThread(dispatch_block_t block); void OnMainThread(dispatch_block_t block);
......
...@@ -108,6 +108,16 @@ int macdrv_err_on; ...@@ -108,6 +108,16 @@ int macdrv_err_on;
[eventQueuesLock unlock]; [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 @end
/*********************************************************************** /***********************************************************************
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
*/ */
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include "macdrv_cocoa.h" #include "macdrv_cocoa.h"
#import "cocoa_app.h" #import "cocoa_app.h"
...@@ -33,6 +35,13 @@ enum { ...@@ -33,6 +35,13 @@ enum {
}; };
struct cocoa_app_startup_info {
NSConditionLock* lock;
unsigned long long tickcount;
uint64_t uptime_ns;
};
/*********************************************************************** /***********************************************************************
* run_cocoa_app * run_cocoa_app
* *
...@@ -50,12 +59,14 @@ enum { ...@@ -50,12 +59,14 @@ enum {
*/ */
static void run_cocoa_app(void* info) 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]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[WineApplication sharedApplication]; [WineApplication sharedApplication];
[NSApp setDelegate:(WineApplication*)NSApp]; [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() /* Retain the lock while we're using it, so macdrv_start_cocoa_app()
doesn't deallocate it in the middle of us unlocking it. */ doesn't deallocate it in the middle of us unlocking it. */
...@@ -78,11 +89,13 @@ static void run_cocoa_app(void* info) ...@@ -78,11 +89,13 @@ static void run_cocoa_app(void* info)
* *
* Returns 0 on success, non-zero on failure. * 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; int ret = -1;
CFRunLoopSourceRef source; 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; NSDate* timeLimit;
CFRunLoopSourceContext source_context = { 0 }; CFRunLoopSourceContext source_context = { 0 };
...@@ -94,29 +107,34 @@ int macdrv_start_cocoa_app(void) ...@@ -94,29 +107,34 @@ int macdrv_start_cocoa_app(void)
toTarget:[NSThread class] toTarget:[NSThread class]
withObject:nil]; 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]; timeLimit = [NSDate dateWithTimeIntervalSinceNow:5];
source_context.info = lock; source_context.info = &startup_info;
source_context.perform = run_cocoa_app; source_context.perform = run_cocoa_app;
source = CFRunLoopSourceCreate(NULL, 0, &source_context); source = CFRunLoopSourceCreate(NULL, 0, &source_context);
if (source && lock && timeLimit) if (source && startup_info.lock && timeLimit)
{ {
CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes); CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes);
CFRunLoopSourceSignal(source); CFRunLoopSourceSignal(source);
CFRunLoopWakeUp(CFRunLoopGetMain()); 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; ret = 0;
} }
} }
if (source) if (source)
CFRelease(source); CFRelease(source);
[lock release]; [startup_info.lock release];
[pool release]; [pool release];
return ret; return ret;
} }
...@@ -112,7 +112,7 @@ struct macdrv_display { ...@@ -112,7 +112,7 @@ struct macdrv_display {
/* main */ /* main */
extern int macdrv_err_on; 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 */ /* display */
......
...@@ -40,7 +40,7 @@ static BOOL process_attach(void) ...@@ -40,7 +40,7 @@ static BOOL process_attach(void)
if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE; if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
macdrv_err_on = ERR_ON(macdrv); 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"); ERR("Failed to start Cocoa app main loop\n");
return FALSE; return FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment