winemac: Add support for "query" events which wait for synchronous responses.
This commit is contained in:
parent
bf824ed38c
commit
69e631e04e
|
@ -32,6 +32,10 @@
|
||||||
|
|
||||||
@interface WineApplication : NSApplication <NSApplicationDelegate>
|
@interface WineApplication : NSApplication <NSApplicationDelegate>
|
||||||
{
|
{
|
||||||
|
CFRunLoopSourceRef requestSource;
|
||||||
|
NSMutableArray* requests;
|
||||||
|
dispatch_queue_t requestsManipQueue;
|
||||||
|
|
||||||
NSMutableArray* eventQueues;
|
NSMutableArray* eventQueues;
|
||||||
NSLock* eventQueuesLock;
|
NSLock* eventQueuesLock;
|
||||||
|
|
||||||
|
@ -83,6 +87,8 @@ - (double) ticksForEventTime:(NSTimeInterval)eventTime;
|
||||||
|
|
||||||
- (void) windowGotFocus:(WineWindow*)window;
|
- (void) windowGotFocus:(WineWindow*)window;
|
||||||
|
|
||||||
|
- (BOOL) waitUntilQueryDone:(int*)done timeout:(NSDate*)timeout;
|
||||||
|
|
||||||
- (void) keyboardSelectionDidChange;
|
- (void) keyboardSelectionDidChange;
|
||||||
|
|
||||||
- (void) flipRect:(NSRect*)rect;
|
- (void) flipRect:(NSRect*)rect;
|
||||||
|
@ -93,7 +99,6 @@ - (void) wineWindow:(WineWindow*)window
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
void OnMainThread(dispatch_block_t block);
|
|
||||||
void OnMainThreadAsync(dispatch_block_t block);
|
void OnMainThreadAsync(dispatch_block_t block);
|
||||||
|
|
||||||
void LogError(const char* func, NSString* format, ...);
|
void LogError(const char* func, NSString* format, ...);
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#import "cocoa_window.h"
|
#import "cocoa_window.h"
|
||||||
|
|
||||||
|
|
||||||
|
static NSString* const WineAppWaitQueryResponseMode = @"WineAppWaitQueryResponseMode";
|
||||||
|
|
||||||
|
|
||||||
int macdrv_err_on;
|
int macdrv_err_on;
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,6 +59,8 @@ @interface WineApplication ()
|
||||||
@property (copy, nonatomic) NSArray* cursorFrames;
|
@property (copy, nonatomic) NSArray* cursorFrames;
|
||||||
@property (retain, nonatomic) NSTimer* cursorTimer;
|
@property (retain, nonatomic) NSTimer* cursorTimer;
|
||||||
|
|
||||||
|
static void PerformRequest(void *info);
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,6 +75,20 @@ - (id) init
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
|
CFRunLoopSourceContext context = { 0 };
|
||||||
|
context.perform = PerformRequest;
|
||||||
|
requestSource = CFRunLoopSourceCreate(NULL, 0, &context);
|
||||||
|
if (!requestSource)
|
||||||
|
{
|
||||||
|
[self release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
CFRunLoopAddSource(CFRunLoopGetMain(), requestSource, kCFRunLoopCommonModes);
|
||||||
|
CFRunLoopAddSource(CFRunLoopGetMain(), requestSource, (CFStringRef)WineAppWaitQueryResponseMode);
|
||||||
|
|
||||||
|
requests = [[NSMutableArray alloc] init];
|
||||||
|
requestsManipQueue = dispatch_queue_create("org.winehq.WineAppRequestManipQueue", NULL);
|
||||||
|
|
||||||
eventQueues = [[NSMutableArray alloc] init];
|
eventQueues = [[NSMutableArray alloc] init];
|
||||||
eventQueuesLock = [[NSLock alloc] init];
|
eventQueuesLock = [[NSLock alloc] init];
|
||||||
|
|
||||||
|
@ -80,8 +99,8 @@ - (id) init
|
||||||
|
|
||||||
warpRecords = [[NSMutableArray alloc] init];
|
warpRecords = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
if (!eventQueues || !eventQueuesLock || !keyWindows || !orderedWineWindows ||
|
if (!requests || !requestsManipQueue || !eventQueues || !eventQueuesLock ||
|
||||||
!originalDisplayModes || !warpRecords)
|
!keyWindows || !orderedWineWindows || !originalDisplayModes || !warpRecords)
|
||||||
{
|
{
|
||||||
[self release];
|
[self release];
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -100,6 +119,13 @@ - (void) dealloc
|
||||||
[keyWindows release];
|
[keyWindows release];
|
||||||
[eventQueues release];
|
[eventQueues release];
|
||||||
[eventQueuesLock release];
|
[eventQueuesLock release];
|
||||||
|
if (requestsManipQueue) dispatch_release(requestsManipQueue);
|
||||||
|
[requests release];
|
||||||
|
if (requestSource)
|
||||||
|
{
|
||||||
|
CFRunLoopSourceInvalidate(requestSource);
|
||||||
|
CFRelease(requestSource);
|
||||||
|
}
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +172,18 @@ - (void) transformProcessToForeground
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) waitUntilQueryDone:(int*)done timeout:(NSDate*)timeout
|
||||||
|
{
|
||||||
|
PerformRequest(NULL);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
[[NSRunLoop currentRunLoop] runMode:WineAppWaitQueryResponseMode beforeDate:timeout];
|
||||||
|
} while (!*done && [timeout timeIntervalSinceNow] >= 0);
|
||||||
|
|
||||||
|
return *done;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL) registerEventQueue:(WineEventQueue*)queue
|
- (BOOL) registerEventQueue:(WineEventQueue*)queue
|
||||||
{
|
{
|
||||||
[eventQueuesLock lock];
|
[eventQueuesLock lock];
|
||||||
|
@ -1102,16 +1140,36 @@ - (void)applicationWillResignActive:(NSNotification *)notification
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* OnMainThread
|
* PerformRequest
|
||||||
*
|
*
|
||||||
* Run a block on the main thread synchronously.
|
* Run-loop-source perform callback. Pull request blocks from the
|
||||||
|
* array of queued requests and invoke them.
|
||||||
*/
|
*/
|
||||||
void OnMainThread(dispatch_block_t block)
|
static void PerformRequest(void *info)
|
||||||
{
|
{
|
||||||
dispatch_sync(dispatch_get_main_queue(), block);
|
WineApplication* app = (WineApplication*)NSApp;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
__block dispatch_block_t block;
|
||||||
|
|
||||||
|
dispatch_sync(app->requestsManipQueue, ^{
|
||||||
|
if ([app->requests count])
|
||||||
|
{
|
||||||
|
block = (dispatch_block_t)[[app->requests objectAtIndex:0] retain];
|
||||||
|
[app->requests removeObjectAtIndex:0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
block = nil;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!block)
|
||||||
|
break;
|
||||||
|
|
||||||
|
block();
|
||||||
|
[block release];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1121,9 +1179,19 @@ void OnMainThread(dispatch_block_t block)
|
||||||
*/
|
*/
|
||||||
void OnMainThreadAsync(dispatch_block_t block)
|
void OnMainThreadAsync(dispatch_block_t block)
|
||||||
{
|
{
|
||||||
dispatch_async(dispatch_get_main_queue(), block);
|
WineApplication* app = (WineApplication*)NSApp;
|
||||||
|
|
||||||
|
block = [block copy];
|
||||||
|
dispatch_sync(app->requestsManipQueue, ^{
|
||||||
|
[app->requests addObject:block];
|
||||||
|
});
|
||||||
|
[block release];
|
||||||
|
CFRunLoopSourceSignal(app->requestSource);
|
||||||
|
CFRunLoopWakeUp(CFRunLoopGetMain());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* LogError
|
* LogError
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "macdrv_cocoa.h"
|
#include "macdrv_cocoa.h"
|
||||||
#import "cocoa_app.h"
|
#import "cocoa_app.h"
|
||||||
|
#import "cocoa_event.h"
|
||||||
|
|
||||||
|
|
||||||
static int owned_change_count = -1;
|
static int owned_change_count = -1;
|
||||||
|
|
|
@ -28,9 +28,16 @@ @interface WineEventQueue : NSObject
|
||||||
NSLock* eventsLock;
|
NSLock* eventsLock;
|
||||||
|
|
||||||
int fds[2]; /* Pipe signaling when there are events queued. */
|
int fds[2]; /* Pipe signaling when there are events queued. */
|
||||||
|
int kq; /* kqueue for waiting in OnMainThread(). */
|
||||||
|
|
||||||
|
macdrv_event_handler event_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) postEvent:(const macdrv_event*)inEvent;
|
- (void) postEvent:(const macdrv_event*)inEvent;
|
||||||
- (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window;
|
- (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window;
|
||||||
|
|
||||||
|
- (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
void OnMainThread(dispatch_block_t block);
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
#import "cocoa_window.h"
|
#import "cocoa_window.h"
|
||||||
|
|
||||||
|
|
||||||
|
static NSString* const WineEventQueueThreadDictionaryKey = @"WineEventQueueThreadDictionaryKey";
|
||||||
|
|
||||||
|
|
||||||
@interface MacDrvEvent : NSObject
|
@interface MacDrvEvent : NSObject
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
|
@ -58,11 +61,24 @@ @implementation WineEventQueue
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
|
[self doesNotRecognizeSelector:_cmd];
|
||||||
|
[self release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithEventHandler:(macdrv_event_handler)handler
|
||||||
|
{
|
||||||
|
NSParameterAssert(handler != nil);
|
||||||
|
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
fds[0] = fds[1] = -1;
|
struct kevent kev;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
fds[0] = fds[1] = kq = -1;
|
||||||
|
|
||||||
|
event_handler = handler;
|
||||||
events = [[NSMutableArray alloc] init];
|
events = [[NSMutableArray alloc] init];
|
||||||
eventsLock = [[NSLock alloc] init];
|
eventsLock = [[NSLock alloc] init];
|
||||||
|
|
||||||
|
@ -81,6 +97,24 @@ - (id) init
|
||||||
[self release];
|
[self release];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kq = kqueue();
|
||||||
|
if (kq < 0)
|
||||||
|
{
|
||||||
|
[self release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
EV_SET(&kev, fds[0], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rc = kevent(kq, &kev, 1, NULL, 0, NULL);
|
||||||
|
} while (rc == -1 && errno == EINTR);
|
||||||
|
if (rc == -1)
|
||||||
|
{
|
||||||
|
[self release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +124,7 @@ - (void) dealloc
|
||||||
[events release];
|
[events release];
|
||||||
[eventsLock release];
|
[eventsLock release];
|
||||||
|
|
||||||
|
if (kq != -1) close(kq);
|
||||||
if (fds[0] != -1) close(fds[0]);
|
if (fds[0] != -1) close(fds[0]);
|
||||||
if (fds[1] != -1) close(fds[1]);
|
if (fds[1] != -1) close(fds[1]);
|
||||||
|
|
||||||
|
@ -217,6 +252,69 @@ - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)
|
||||||
[eventsLock unlock];
|
[eventsLock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout
|
||||||
|
{
|
||||||
|
macdrv_event event;
|
||||||
|
NSDate* timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout];
|
||||||
|
BOOL timedout;
|
||||||
|
|
||||||
|
event.type = QUERY_EVENT;
|
||||||
|
event.window = (macdrv_window)[(WineWindow*)query->window retain];
|
||||||
|
event.query_event.query = macdrv_retain_query(query);
|
||||||
|
query->done = FALSE;
|
||||||
|
|
||||||
|
[self postEvent:&event];
|
||||||
|
timedout = ![NSApp waitUntilQueryDone:&query->done timeout:timeoutDate];
|
||||||
|
return !timedout && query->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* OnMainThread
|
||||||
|
*
|
||||||
|
* Run a block on the main thread synchronously.
|
||||||
|
*/
|
||||||
|
void OnMainThread(dispatch_block_t block)
|
||||||
|
{
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
|
||||||
|
WineEventQueue* queue = [threadDict objectForKey:WineEventQueueThreadDictionaryKey];
|
||||||
|
__block BOOL finished;
|
||||||
|
|
||||||
|
if (!queue)
|
||||||
|
{
|
||||||
|
/* Fall back to synchronous dispatch without handling query events. */
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), block);
|
||||||
|
[pool release];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
finished = FALSE;
|
||||||
|
OnMainThreadAsync(^{
|
||||||
|
block();
|
||||||
|
finished = TRUE;
|
||||||
|
[queue signalEventAvailable];
|
||||||
|
});
|
||||||
|
|
||||||
|
while (!finished)
|
||||||
|
{
|
||||||
|
MacDrvEvent* macDrvEvent;
|
||||||
|
struct kevent kev;
|
||||||
|
|
||||||
|
while (!finished &&
|
||||||
|
(macDrvEvent = [queue getEventMatchingMask:event_mask_for_type(QUERY_EVENT)]))
|
||||||
|
{
|
||||||
|
queue->event_handler(&macDrvEvent->event);
|
||||||
|
macdrv_cleanup_event(&macDrvEvent->event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!finished)
|
||||||
|
kevent(queue->kq, NULL, 0, &kev, 1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* macdrv_create_event_queue
|
* macdrv_create_event_queue
|
||||||
|
@ -224,15 +322,22 @@ - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)
|
||||||
* Register this thread with the application on the main thread, and set
|
* Register this thread with the application on the main thread, and set
|
||||||
* up an event queue on which it can deliver events to this thread.
|
* up an event queue on which it can deliver events to this thread.
|
||||||
*/
|
*/
|
||||||
macdrv_event_queue macdrv_create_event_queue(void)
|
macdrv_event_queue macdrv_create_event_queue(macdrv_event_handler handler)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
|
||||||
|
|
||||||
WineEventQueue* queue = [[WineEventQueue alloc] init];
|
WineEventQueue* queue = [threadDict objectForKey:WineEventQueueThreadDictionaryKey];
|
||||||
if (queue && ![NSApp registerEventQueue:queue])
|
if (!queue)
|
||||||
{
|
{
|
||||||
[queue release];
|
queue = [[[WineEventQueue alloc] initWithEventHandler:handler] autorelease];
|
||||||
queue = nil;
|
if (queue)
|
||||||
|
{
|
||||||
|
if ([NSApp registerEventQueue:queue])
|
||||||
|
[threadDict setObject:queue forKey:WineEventQueueThreadDictionaryKey];
|
||||||
|
else
|
||||||
|
queue = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
@ -249,9 +354,10 @@ void macdrv_destroy_event_queue(macdrv_event_queue queue)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
WineEventQueue* q = (WineEventQueue*)queue;
|
WineEventQueue* q = (WineEventQueue*)queue;
|
||||||
|
NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
|
||||||
|
|
||||||
[NSApp unregisterEventQueue:q];
|
[NSApp unregisterEventQueue:q];
|
||||||
[q release];
|
[threadDict removeObjectForKey:WineEventQueueThreadDictionaryKey];
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
}
|
}
|
||||||
|
@ -308,6 +414,9 @@ void macdrv_cleanup_event(macdrv_event *event)
|
||||||
case KEYBOARD_CHANGED:
|
case KEYBOARD_CHANGED:
|
||||||
CFRelease(event->keyboard_changed.uchr);
|
CFRelease(event->keyboard_changed.uchr);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_EVENT:
|
||||||
|
macdrv_release_query(event->query_event.query);
|
||||||
|
break;
|
||||||
case WINDOW_GOT_FOCUS:
|
case WINDOW_GOT_FOCUS:
|
||||||
[(NSMutableSet*)event->window_got_focus.tried_windows release];
|
[(NSMutableSet*)event->window_got_focus.tried_windows release];
|
||||||
break;
|
break;
|
||||||
|
@ -318,4 +427,50 @@ void macdrv_cleanup_event(macdrv_event *event)
|
||||||
[pool release];
|
[pool release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_create_query
|
||||||
|
*/
|
||||||
|
macdrv_query* macdrv_create_query(void)
|
||||||
|
{
|
||||||
|
macdrv_query *query;
|
||||||
|
|
||||||
|
query = calloc(1, sizeof(*query));
|
||||||
|
query->refs = 1;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_retain_query
|
||||||
|
*/
|
||||||
|
macdrv_query* macdrv_retain_query(macdrv_query *query)
|
||||||
|
{
|
||||||
|
OSAtomicIncrement32Barrier(&query->refs);
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_release_query
|
||||||
|
*/
|
||||||
|
void macdrv_release_query(macdrv_query *query)
|
||||||
|
{
|
||||||
|
if (OSAtomicDecrement32Barrier(&query->refs) <= 0)
|
||||||
|
{
|
||||||
|
[(WineWindow*)query->window release];
|
||||||
|
free(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_set_query_done
|
||||||
|
*/
|
||||||
|
void macdrv_set_query_done(macdrv_query *query)
|
||||||
|
{
|
||||||
|
macdrv_retain_query(query);
|
||||||
|
|
||||||
|
OnMainThreadAsync(^{
|
||||||
|
query->done = TRUE;
|
||||||
|
macdrv_release_query(query);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#import "cocoa_opengl.h"
|
#import "cocoa_opengl.h"
|
||||||
|
|
||||||
#include "macdrv_cocoa.h"
|
#include "macdrv_cocoa.h"
|
||||||
#include "cocoa_app.h"
|
#include "cocoa_event.h"
|
||||||
|
|
||||||
|
|
||||||
@interface WineOpenGLContext ()
|
@interface WineOpenGLContext ()
|
||||||
|
|
|
@ -41,6 +41,7 @@ static const char *dbgstr_event(int type)
|
||||||
"MOUSE_MOVED",
|
"MOUSE_MOVED",
|
||||||
"MOUSE_MOVED_ABSOLUTE",
|
"MOUSE_MOVED_ABSOLUTE",
|
||||||
"MOUSE_SCROLL",
|
"MOUSE_SCROLL",
|
||||||
|
"QUERY_EVENT",
|
||||||
"WINDOW_CLOSE_REQUESTED",
|
"WINDOW_CLOSE_REQUESTED",
|
||||||
"WINDOW_DID_MINIMIZE",
|
"WINDOW_DID_MINIMIZE",
|
||||||
"WINDOW_DID_UNMINIMIZE",
|
"WINDOW_DID_UNMINIMIZE",
|
||||||
|
@ -94,10 +95,38 @@ static macdrv_event_mask get_event_mask(DWORD mask)
|
||||||
event_mask |= event_mask_for_type(WINDOW_LOST_FOCUS);
|
event_mask |= event_mask_for_type(WINDOW_LOST_FOCUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mask & QS_SENDMESSAGE)
|
||||||
|
{
|
||||||
|
event_mask |= event_mask_for_type(QUERY_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
return event_mask;
|
return event_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_query_event
|
||||||
|
*
|
||||||
|
* Handler for QUERY_EVENT queries.
|
||||||
|
*/
|
||||||
|
static void macdrv_query_event(HWND hwnd, macdrv_event *event)
|
||||||
|
{
|
||||||
|
BOOL success = FALSE;
|
||||||
|
macdrv_query *query = event->query_event.query;
|
||||||
|
|
||||||
|
switch (query->type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
FIXME("unrecognized query type %d\n", query->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("success %d\n", success);
|
||||||
|
query->status = success;
|
||||||
|
macdrv_set_query_done(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* macdrv_handle_event
|
* macdrv_handle_event
|
||||||
*/
|
*/
|
||||||
|
@ -138,6 +167,9 @@ void macdrv_handle_event(macdrv_event *event)
|
||||||
case MOUSE_SCROLL:
|
case MOUSE_SCROLL:
|
||||||
macdrv_mouse_scroll(hwnd, event);
|
macdrv_mouse_scroll(hwnd, event);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_EVENT:
|
||||||
|
macdrv_query_event(hwnd, event);
|
||||||
|
break;
|
||||||
case WINDOW_CLOSE_REQUESTED:
|
case WINDOW_CLOSE_REQUESTED:
|
||||||
macdrv_window_close_requested(hwnd);
|
macdrv_window_close_requested(hwnd);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -138,6 +138,8 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
|
||||||
extern void set_window_surface(macdrv_window window, struct window_surface *window_surface) DECLSPEC_HIDDEN;
|
extern void set_window_surface(macdrv_window window, struct window_surface *window_surface) DECLSPEC_HIDDEN;
|
||||||
extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha) DECLSPEC_HIDDEN;
|
extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
extern void macdrv_handle_event(macdrv_event *event) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern void macdrv_window_close_requested(HWND hwnd) DECLSPEC_HIDDEN;
|
extern void macdrv_window_close_requested(HWND hwnd) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_window_frame_changed(HWND hwnd, CGRect frame) DECLSPEC_HIDDEN;
|
extern void macdrv_window_frame_changed(HWND hwnd, CGRect frame) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_window_got_focus(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
|
extern void macdrv_window_got_focus(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
typedef struct macdrv_opaque_view* macdrv_view;
|
typedef struct macdrv_opaque_view* macdrv_view;
|
||||||
typedef struct macdrv_opaque_opengl_context* macdrv_opengl_context;
|
typedef struct macdrv_opaque_opengl_context* macdrv_opengl_context;
|
||||||
struct macdrv_event;
|
struct macdrv_event;
|
||||||
|
struct macdrv_query;
|
||||||
|
|
||||||
struct macdrv_display {
|
struct macdrv_display {
|
||||||
CGDirectDisplayID displayID;
|
CGDirectDisplayID displayID;
|
||||||
|
@ -145,6 +146,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
||||||
MOUSE_MOVED,
|
MOUSE_MOVED,
|
||||||
MOUSE_MOVED_ABSOLUTE,
|
MOUSE_MOVED_ABSOLUTE,
|
||||||
MOUSE_SCROLL,
|
MOUSE_SCROLL,
|
||||||
|
QUERY_EVENT,
|
||||||
WINDOW_CLOSE_REQUESTED,
|
WINDOW_CLOSE_REQUESTED,
|
||||||
WINDOW_DID_MINIMIZE,
|
WINDOW_DID_MINIMIZE,
|
||||||
WINDOW_DID_UNMINIMIZE,
|
WINDOW_DID_UNMINIMIZE,
|
||||||
|
@ -192,6 +194,9 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
||||||
int y;
|
int y;
|
||||||
unsigned long time_ms;
|
unsigned long time_ms;
|
||||||
} mouse_scroll;
|
} mouse_scroll;
|
||||||
|
struct {
|
||||||
|
struct macdrv_query *query;
|
||||||
|
} query_event;
|
||||||
struct {
|
struct {
|
||||||
CGRect frame;
|
CGRect frame;
|
||||||
} window_frame_changed;
|
} window_frame_changed;
|
||||||
|
@ -202,12 +207,26 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
||||||
};
|
};
|
||||||
} macdrv_event;
|
} macdrv_event;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NUM_QUERY_TYPES
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct macdrv_query {
|
||||||
|
int refs;
|
||||||
|
int type;
|
||||||
|
macdrv_window window;
|
||||||
|
int status;
|
||||||
|
int done;
|
||||||
|
} macdrv_query;
|
||||||
|
|
||||||
static inline macdrv_event_mask event_mask_for_type(int type)
|
static inline macdrv_event_mask event_mask_for_type(int type)
|
||||||
{
|
{
|
||||||
return ((macdrv_event_mask)1 << type);
|
return ((macdrv_event_mask)1 << type);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern macdrv_event_queue macdrv_create_event_queue(void) DECLSPEC_HIDDEN;
|
typedef void (*macdrv_event_handler)(macdrv_event *event);
|
||||||
|
|
||||||
|
extern macdrv_event_queue macdrv_create_event_queue(macdrv_event_handler handler) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_destroy_event_queue(macdrv_event_queue queue) DECLSPEC_HIDDEN;
|
extern void macdrv_destroy_event_queue(macdrv_event_queue queue) DECLSPEC_HIDDEN;
|
||||||
extern int macdrv_get_event_queue_fd(macdrv_event_queue queue) DECLSPEC_HIDDEN;
|
extern int macdrv_get_event_queue_fd(macdrv_event_queue queue) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
@ -215,6 +234,11 @@ extern int macdrv_get_event_from_queue(macdrv_event_queue queue,
|
||||||
macdrv_event_mask mask, macdrv_event *event) DECLSPEC_HIDDEN;
|
macdrv_event_mask mask, macdrv_event *event) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_cleanup_event(macdrv_event *event) DECLSPEC_HIDDEN;
|
extern void macdrv_cleanup_event(macdrv_event *event) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
extern macdrv_query* macdrv_create_query(void) DECLSPEC_HIDDEN;
|
||||||
|
extern macdrv_query* macdrv_retain_query(macdrv_query *query) DECLSPEC_HIDDEN;
|
||||||
|
extern void macdrv_release_query(macdrv_query *query) DECLSPEC_HIDDEN;
|
||||||
|
extern void macdrv_set_query_done(macdrv_query *query) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
||||||
/* window */
|
/* window */
|
||||||
struct macdrv_window_features {
|
struct macdrv_window_features {
|
||||||
|
|
|
@ -157,7 +157,7 @@ struct macdrv_thread_data *macdrv_init_thread_data(void)
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(data->queue = macdrv_create_event_queue()))
|
if (!(data->queue = macdrv_create_event_queue(macdrv_handle_event)))
|
||||||
{
|
{
|
||||||
ERR("macdrv: Can't create event queue.\n");
|
ERR("macdrv: Can't create event queue.\n");
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
|
|
Loading…
Reference in New Issue