From 1ee93853c2fff0917d43ad498f75f4608eb35238 Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Wed, 3 Apr 2013 18:56:35 -0500 Subject: [PATCH] winemac: Make macdrv_event structs heap-allocated and reference-counted. --- dlls/winemac.drv/cocoa_app.m | 56 +++++----- dlls/winemac.drv/cocoa_event.h | 8 +- dlls/winemac.drv/cocoa_event.m | 148 ++++++++++++++++----------- dlls/winemac.drv/cocoa_status_item.m | 12 +-- dlls/winemac.drv/cocoa_window.m | 139 +++++++++++++------------ dlls/winemac.drv/event.c | 8 +- dlls/winemac.drv/macdrv_cocoa.h | 7 +- 7 files changed, 206 insertions(+), 172 deletions(-) diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index b14c550eb8e..e0a29ee78c1 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -243,18 +243,18 @@ - (void) invalidateGotFocusEvents - (void) windowGotFocus:(WineWindow*)window { - macdrv_event event; + macdrv_event* event; [NSApp invalidateGotFocusEvents]; - event.type = WINDOW_GOT_FOCUS; - event.window = (macdrv_window)[window retain]; - event.window_got_focus.serial = windowFocusSerial; + event = macdrv_create_event(WINDOW_GOT_FOCUS, window); + event->window_got_focus.serial = windowFocusSerial; if (triedWindows) - event.window_got_focus.tried_windows = [triedWindows retain]; + event->window_got_focus.tried_windows = [triedWindows retain]; else - event.window_got_focus.tried_windows = [[NSMutableSet alloc] init]; - [window.queue postEvent:&event]; + event->window_got_focus.tried_windows = [[NSMutableSet alloc] init]; + [window.queue postEvent:event]; + macdrv_release_event(event); } - (void) windowRejectedFocusEvent:(const macdrv_event*)event @@ -287,29 +287,25 @@ - (void) keyboardSelectionDidChange kTISPropertyUnicodeKeyLayoutData); if (uchr) { - macdrv_event event; + macdrv_event* event; WineEventQueue* queue; - event.type = KEYBOARD_CHANGED; - event.window = NULL; - event.keyboard_changed.keyboard_type = self.keyboardType; - event.keyboard_changed.iso_keyboard = (KBGetLayoutType(self.keyboardType) == kKeyboardISO); - event.keyboard_changed.uchr = CFDataCreateCopy(NULL, uchr); + event = macdrv_create_event(KEYBOARD_CHANGED, nil); + event->keyboard_changed.keyboard_type = self.keyboardType; + event->keyboard_changed.iso_keyboard = (KBGetLayoutType(self.keyboardType) == kKeyboardISO); + event->keyboard_changed.uchr = CFDataCreateCopy(NULL, uchr); - if (event.keyboard_changed.uchr) + if (event->keyboard_changed.uchr) { [eventQueuesLock lock]; for (queue in eventQueues) - { - CFRetain(event.keyboard_changed.uchr); - [queue postEvent:&event]; - } + [queue postEvent:event]; [eventQueuesLock unlock]; - - CFRelease(event.keyboard_changed.uchr); } + + macdrv_release_event(event); } CFRelease(inputSource); @@ -410,17 +406,18 @@ - (void) wineWindow:(WineWindow*)window - (void) sendDisplaysChanged:(BOOL)activating { - macdrv_event event; + macdrv_event* event; WineEventQueue* queue; - event.type = DISPLAYS_CHANGED; - event.window = NULL; - event.displays_changed.activating = activating; + event = macdrv_create_event(DISPLAYS_CHANGED, nil); + event->displays_changed.activating = activating; [eventQueuesLock lock]; for (queue in eventQueues) - [queue postEvent:&event]; + [queue postEvent:event]; [eventQueuesLock unlock]; + + macdrv_release_event(event); } // We can compare two modes directly using CFEqual, but that may require that @@ -1187,18 +1184,19 @@ - (void)applicationDidChangeScreenParameters:(NSNotification *)notification - (void)applicationDidResignActive:(NSNotification *)notification { - macdrv_event event; + macdrv_event* event; WineEventQueue* queue; [self invalidateGotFocusEvents]; - event.type = APP_DEACTIVATED; - event.window = NULL; + event = macdrv_create_event(APP_DEACTIVATED, nil); [eventQueuesLock lock]; for (queue in eventQueues) - [queue postEvent:&event]; + [queue postEvent:event]; [eventQueuesLock unlock]; + + macdrv_release_event(event); } - (void)applicationWillFinishLaunching:(NSNotification *)notification diff --git a/dlls/winemac.drv/cocoa_event.h b/dlls/winemac.drv/cocoa_event.h index e74875ec5f0..c1afc733579 100644 --- a/dlls/winemac.drv/cocoa_event.h +++ b/dlls/winemac.drv/cocoa_event.h @@ -22,6 +22,9 @@ #include "macdrv_cocoa.h" +@class WineWindow; + + @interface WineEventQueue : NSObject { NSMutableArray* events; @@ -33,7 +36,7 @@ @interface WineEventQueue : NSObject macdrv_event_handler event_handler; } - - (void) postEvent:(const macdrv_event*)inEvent; + - (void) postEvent:(macdrv_event*)inEvent; - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window; - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout processEvents:(BOOL)processEvents; @@ -42,3 +45,6 @@ - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout; @end void OnMainThread(dispatch_block_t block); + +macdrv_event* macdrv_create_event(int type, WineWindow* window) DECLSPEC_HIDDEN; +macdrv_event* macdrv_retain_event(macdrv_event *event) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/cocoa_event.m b/dlls/winemac.drv/cocoa_event.m index 76fb54320c5..78a2f945878 100644 --- a/dlls/winemac.drv/cocoa_event.m +++ b/dlls/winemac.drv/cocoa_event.m @@ -35,25 +35,31 @@ @interface MacDrvEvent : NSObject { @public - macdrv_event event; + macdrv_event* event; } - - (id) initWithEvent:(const macdrv_event*)event; + - (id) initWithEvent:(macdrv_event*)event; @end @implementation MacDrvEvent - - (id) initWithEvent:(const macdrv_event*)inEvent + - (id) initWithEvent:(macdrv_event*)inEvent { self = [super init]; if (self) { - event = *inEvent; + event = macdrv_retain_event(inEvent); } return self; } + - (void) dealloc + { + if (event) macdrv_release_event(event); + [super dealloc]; + } + @end @@ -151,28 +157,26 @@ - (void) postEventObject:(MacDrvEvent*)event [eventsLock lock]; - if ((event->event.type == MOUSE_MOVED || - event->event.type == MOUSE_MOVED_ABSOLUTE) && + if ((event->event->type == MOUSE_MOVED || + event->event->type == MOUSE_MOVED_ABSOLUTE) && (lastEvent = [events lastObject]) && - (lastEvent->event.type == MOUSE_MOVED || - lastEvent->event.type == MOUSE_MOVED_ABSOLUTE) && - lastEvent->event.window == event->event.window) + (lastEvent->event->type == MOUSE_MOVED || + lastEvent->event->type == MOUSE_MOVED_ABSOLUTE) && + lastEvent->event->window == event->event->window) { - if (event->event.type == MOUSE_MOVED) + if (event->event->type == MOUSE_MOVED) { - lastEvent->event.mouse_moved.x += event->event.mouse_moved.x; - lastEvent->event.mouse_moved.y += event->event.mouse_moved.y; + lastEvent->event->mouse_moved.x += event->event->mouse_moved.x; + lastEvent->event->mouse_moved.y += event->event->mouse_moved.y; } else { - lastEvent->event.type = MOUSE_MOVED_ABSOLUTE; - lastEvent->event.mouse_moved.x = event->event.mouse_moved.x; - lastEvent->event.mouse_moved.y = event->event.mouse_moved.y; + lastEvent->event->type = MOUSE_MOVED_ABSOLUTE; + lastEvent->event->mouse_moved.x = event->event->mouse_moved.x; + lastEvent->event->mouse_moved.y = event->event->mouse_moved.y; } - lastEvent->event.mouse_moved.time_ms = event->event.mouse_moved.time_ms; - - macdrv_cleanup_event(&event->event); + lastEvent->event->mouse_moved.time_ms = event->event->mouse_moved.time_ms; } else [events addObject:event]; @@ -182,7 +186,7 @@ - (void) postEventObject:(MacDrvEvent*)event [self signalEventAvailable]; } - - (void) postEvent:(const macdrv_event*)inEvent + - (void) postEvent:(macdrv_event*)inEvent { MacDrvEvent* event = [[MacDrvEvent alloc] initWithEvent:inEvent]; [self postEventObject:event]; @@ -215,7 +219,7 @@ - (MacDrvEvent*) getEventMatchingMask:(macdrv_event_mask)mask index = 0; for (event in events) { - if (event_mask_for_type(event->event.type) & mask) + if (event_mask_for_type(event->event->type) & mask) break; index++; @@ -233,18 +237,14 @@ - (MacDrvEvent*) getEventMatchingMask:(macdrv_event_mask)mask - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window { - NSMutableIndexSet* indexes = [[[NSMutableIndexSet alloc] init] autorelease]; + NSIndexSet* indexes; [eventsLock lock]; - [events enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){ + indexes = [events indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ MacDrvEvent* event = obj; - if ((event_mask_for_type(event->event.type) & mask) && - (!window || event->event.window == (macdrv_window)window)) - { - macdrv_cleanup_event(&event->event); - [indexes addIndex:idx]; - } + return ((event_mask_for_type(event->event->type) & mask) && + (!window || event->event->window == (macdrv_window)window)); }]; [events removeObjectsAtIndexes:indexes]; @@ -254,16 +254,16 @@ - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*) - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout processEvents:(BOOL)processEvents { - macdrv_event event; + 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); + event = macdrv_create_event(QUERY_EVENT, (WineWindow*)query->window); + event->query_event.query = macdrv_retain_query(query); query->done = FALSE; - [self postEvent:&event]; + [self postEvent:event]; + macdrv_release_event(event); timedout = ![NSApp waitUntilQueryDone:&query->done timeout:timeoutDate processEvents:processEvents]; return !timedout && query->status; } @@ -309,8 +309,7 @@ void OnMainThread(dispatch_block_t block) while (!finished && (macDrvEvent = [queue getEventMatchingMask:event_mask_for_type(QUERY_EVENT)])) { - queue->event_handler(&macDrvEvent->event); - macdrv_cleanup_event(&macDrvEvent->event); + queue->event_handler(macDrvEvent->event); } if (!finished) @@ -385,56 +384,83 @@ int macdrv_get_event_queue_fd(macdrv_event_queue queue) } /*********************************************************************** - * macdrv_get_event_from_queue + * macdrv_copy_event_from_queue * * Pull an event matching the event mask from the event queue and store * it in the event record pointed to by the event parameter. If a * matching event was found, return non-zero; otherwise, return 0. * - * The caller is responsible for calling macdrv_cleanup_event on any + * The caller is responsible for calling macdrv_release_event on any * event returned by this function. */ -int macdrv_get_event_from_queue(macdrv_event_queue queue, - macdrv_event_mask mask, macdrv_event *event) +int macdrv_copy_event_from_queue(macdrv_event_queue queue, + macdrv_event_mask mask, macdrv_event **event) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; WineEventQueue* q = (WineEventQueue*)queue; MacDrvEvent* macDrvEvent = [q getEventMatchingMask:mask]; if (macDrvEvent) - *event = macDrvEvent->event; + *event = macdrv_retain_event(macDrvEvent->event); [pool release]; return (macDrvEvent != nil); } /*********************************************************************** - * macdrv_cleanup_event - * - * Performs cleanup of an event. For event types which carry resources - * such as allocated memory or retained objects, frees/releases those - * resources. + * macdrv_create_event */ -void macdrv_cleanup_event(macdrv_event *event) +macdrv_event* macdrv_create_event(int type, WineWindow* window) { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + macdrv_event *event; - switch (event->type) + event = calloc(1, sizeof(*event)); + event->refs = 1; + event->type = type; + event->window = (macdrv_window)[window retain]; + return event; +} + +/*********************************************************************** + * macdrv_retain_event + */ +macdrv_event* macdrv_retain_event(macdrv_event *event) +{ + OSAtomicIncrement32Barrier(&event->refs); + return event; +} + +/*********************************************************************** + * macdrv_release_event + * + * Decrements the reference count of an event. If the count falls to + * zero, cleans up any resources, such as allocated memory or retained + * objects, held by the event and deallocates it + */ +void macdrv_release_event(macdrv_event *event) +{ + if (OSAtomicDecrement32Barrier(&event->refs) <= 0) { - case KEYBOARD_CHANGED: - CFRelease(event->keyboard_changed.uchr); - break; - case QUERY_EVENT: - macdrv_release_query(event->query_event.query); - break; - case WINDOW_GOT_FOCUS: - [(NSMutableSet*)event->window_got_focus.tried_windows release]; - break; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + switch (event->type) + { + case KEYBOARD_CHANGED: + CFRelease(event->keyboard_changed.uchr); + break; + case QUERY_EVENT: + macdrv_release_query(event->query_event.query); + break; + case WINDOW_GOT_FOCUS: + [(NSMutableSet*)event->window_got_focus.tried_windows release]; + break; + } + + [(WineWindow*)event->window release]; + free(event); + + [pool release]; } - - [(WineWindow*)event->window release]; - - [pool release]; } /*********************************************************************** diff --git a/dlls/winemac.drv/cocoa_status_item.m b/dlls/winemac.drv/cocoa_status_item.m index 1725abac574..27908ab6c29 100644 --- a/dlls/winemac.drv/cocoa_status_item.m +++ b/dlls/winemac.drv/cocoa_status_item.m @@ -79,12 +79,12 @@ - (void) removeFromStatusBar - (void) postClickedEventWithCount:(int)count { - macdrv_event event; - event.type = STATUS_ITEM_CLICKED; - event.window = NULL; - event.status_item_clicked.item = (macdrv_status_item)self; - event.status_item_clicked.count = count; - [queue postEvent:&event]; + macdrv_event* event; + event = macdrv_create_event(STATUS_ITEM_CLICKED, nil); + event->status_item_clicked.item = (macdrv_status_item)self; + event->status_item_clicked.count = count; + [queue postEvent:event]; + macdrv_release_event(event); } - (void) clicked:(id)sender diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 68644fa40a8..43be348d015 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -678,17 +678,18 @@ - (void) setShape:(NSBezierPath*)newShape - (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed { CGPoint pt = CGEventGetLocation([theEvent CGEvent]); - macdrv_event event; + macdrv_event* event; - event.type = MOUSE_BUTTON; - event.window = (macdrv_window)[self retain]; - event.mouse_button.button = [theEvent buttonNumber]; - event.mouse_button.pressed = pressed; - event.mouse_button.x = pt.x; - event.mouse_button.y = pt.y; - event.mouse_button.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; + event = macdrv_create_event(MOUSE_BUTTON, self); + event->mouse_button.button = [theEvent buttonNumber]; + event->mouse_button.pressed = pressed; + event->mouse_button.x = pt.x; + event->mouse_button.y = pt.y; + event->mouse_button.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; - [queue postEvent:&event]; + [queue postEvent:event]; + + macdrv_release_event(event); } - (void) makeFocused @@ -750,15 +751,14 @@ - (void) postKey:(uint16_t)keyCode modifiers:(NSUInteger)modifiers event:(NSEvent*)theEvent { - macdrv_event event; + macdrv_event* event; CGEventRef cgevent; WineApplication* app = (WineApplication*)NSApp; - event.type = pressed ? KEY_PRESS : KEY_RELEASE; - event.window = (macdrv_window)[self retain]; - event.key.keycode = keyCode; - event.key.modifiers = modifiers; - event.key.time_ms = [app ticksForEventTime:[theEvent timestamp]]; + event = macdrv_create_event(pressed ? KEY_PRESS : KEY_RELEASE, self); + event->key.keycode = keyCode; + event->key.modifiers = modifiers; + event->key.time_ms = [app ticksForEventTime:[theEvent timestamp]]; if ((cgevent = [theEvent CGEvent])) { @@ -771,7 +771,9 @@ - (void) postKey:(uint16_t)keyCode } } - [queue postEvent:&event]; + [queue postEvent:event]; + + macdrv_release_event(event); } - (void) postKeyEvent:(NSEvent *)theEvent @@ -785,15 +787,15 @@ - (void) postKeyEvent:(NSEvent *)theEvent - (void) postMouseMovedEvent:(NSEvent *)theEvent absolute:(BOOL)absolute { - macdrv_event event; + macdrv_event* event; if (absolute) { CGPoint point = CGEventGetLocation([theEvent CGEvent]); - event.type = MOUSE_MOVED_ABSOLUTE; - event.mouse_moved.x = point.x; - event.mouse_moved.y = point.y; + event = macdrv_create_event(MOUSE_MOVED_ABSOLUTE, self); + event->mouse_moved.x = point.x; + event->mouse_moved.y = point.y; mouseMoveDeltaX = 0; mouseMoveDeltaY = 0; @@ -805,22 +807,23 @@ - (void) postMouseMovedEvent:(NSEvent *)theEvent absolute:(BOOL)absolute mouseMoveDeltaX += [theEvent deltaX]; mouseMoveDeltaY += [theEvent deltaY]; - event.type = MOUSE_MOVED; - event.mouse_moved.x = mouseMoveDeltaX; - event.mouse_moved.y = mouseMoveDeltaY; + event = macdrv_create_event(MOUSE_MOVED, self); + event->mouse_moved.x = mouseMoveDeltaX; + event->mouse_moved.y = mouseMoveDeltaY; /* Keep the remainder after integer truncation. */ - mouseMoveDeltaX -= event.mouse_moved.x; - mouseMoveDeltaY -= event.mouse_moved.y; + mouseMoveDeltaX -= event->mouse_moved.x; + mouseMoveDeltaY -= event->mouse_moved.y; } - if (event.type == MOUSE_MOVED_ABSOLUTE || event.mouse_moved.x || event.mouse_moved.y) + if (event->type == MOUSE_MOVED_ABSOLUTE || event->mouse_moved.x || event->mouse_moved.y) { - event.window = (macdrv_window)[self retain]; - event.mouse_moved.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; + event->mouse_moved.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; - [queue postEvent:&event]; + [queue postEvent:event]; } + + macdrv_release_event(event); } - (void) setLevelWhenActive:(NSInteger)level @@ -1006,7 +1009,7 @@ - (void) flagsChanged:(NSEvent *)theEvent - (void) scrollWheel:(NSEvent *)theEvent { CGPoint pt; - macdrv_event event; + macdrv_event* event; CGEventRef cgevent; CGFloat x, y; BOOL continuous = FALSE; @@ -1014,11 +1017,10 @@ - (void) scrollWheel:(NSEvent *)theEvent cgevent = [theEvent CGEvent]; pt = CGEventGetLocation(cgevent); - event.type = MOUSE_SCROLL; - event.window = (macdrv_window)[self retain]; - event.mouse_scroll.x = pt.x; - event.mouse_scroll.y = pt.y; - event.mouse_scroll.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; + event = macdrv_create_event(MOUSE_SCROLL, self); + event->mouse_scroll.x = pt.x; + event->mouse_scroll.y = pt.y; + event->mouse_scroll.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; if (CGEventGetIntegerValueField(cgevent, kCGScrollWheelEventIsContinuous)) { @@ -1055,8 +1057,8 @@ - (void) scrollWheel:(NSEvent *)theEvent /* The x,y values so far are in pixels. Win32 expects to receive some fraction of WHEEL_DELTA == 120. By my estimation, that's roughly 6 times the pixel value. */ - event.mouse_scroll.x_scroll = 6 * x; - event.mouse_scroll.y_scroll = 6 * y; + event->mouse_scroll.x_scroll = 6 * x; + event->mouse_scroll.y_scroll = 6 * y; if (!continuous) { @@ -1066,19 +1068,21 @@ - (void) scrollWheel:(NSEvent *)theEvent scroll distance, the user is sure to get some action out of each click. For example, this is important for rotating though weapons in a first-person shooter. */ - if (0 < event.mouse_scroll.x_scroll && event.mouse_scroll.x_scroll < 120) - event.mouse_scroll.x_scroll = 120; - else if (-120 < event.mouse_scroll.x_scroll && event.mouse_scroll.x_scroll < 0) - event.mouse_scroll.x_scroll = -120; + if (0 < event->mouse_scroll.x_scroll && event->mouse_scroll.x_scroll < 120) + event->mouse_scroll.x_scroll = 120; + else if (-120 < event->mouse_scroll.x_scroll && event->mouse_scroll.x_scroll < 0) + event->mouse_scroll.x_scroll = -120; - if (0 < event.mouse_scroll.y_scroll && event.mouse_scroll.y_scroll < 120) - event.mouse_scroll.y_scroll = 120; - else if (-120 < event.mouse_scroll.y_scroll && event.mouse_scroll.y_scroll < 0) - event.mouse_scroll.y_scroll = -120; + if (0 < event->mouse_scroll.y_scroll && event->mouse_scroll.y_scroll < 120) + event->mouse_scroll.y_scroll = 120; + else if (-120 < event->mouse_scroll.y_scroll && event->mouse_scroll.y_scroll < 0) + event->mouse_scroll.y_scroll = -120; } - if (event.mouse_scroll.x_scroll || event.mouse_scroll.y_scroll) - [queue postEvent:&event]; + if (event->mouse_scroll.x_scroll || event->mouse_scroll.y_scroll) + [queue postEvent:event]; + + macdrv_release_event(event); } @@ -1100,16 +1104,16 @@ - (void)windowDidDeminiaturize:(NSNotification *)notification { if (!ignore_windowDeminiaturize) { - macdrv_event event; + macdrv_event* event; /* Coalesce events by discarding any previous ones still in the queue. */ [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_DID_MINIMIZE) | event_mask_for_type(WINDOW_DID_UNMINIMIZE) forWindow:self]; - event.type = WINDOW_DID_UNMINIMIZE; - event.window = (macdrv_window)[self retain]; - [queue postEvent:&event]; + event = macdrv_create_event(WINDOW_DID_UNMINIMIZE, self); + [queue postEvent:event]; + macdrv_release_event(event); } ignore_windowDeminiaturize = FALSE; @@ -1131,18 +1135,18 @@ - (void)windowDidMove:(NSNotification *)notification - (void)windowDidResignKey:(NSNotification *)notification { - macdrv_event event; + macdrv_event* event; if (causing_becomeKeyWindow) return; - event.type = WINDOW_LOST_FOCUS; - event.window = (macdrv_window)[self retain]; - [queue postEvent:&event]; + event = macdrv_create_event(WINDOW_LOST_FOCUS, self); + [queue postEvent:event]; + macdrv_release_event(event); } - (void)windowDidResize:(NSNotification *)notification { - macdrv_event event; + macdrv_event* event; NSRect frame = [self contentRectForFrameRect:[self frame]]; [NSApp flipRect:&frame]; @@ -1151,18 +1155,17 @@ - (void)windowDidResize:(NSNotification *)notification [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED) forWindow:self]; - event.type = WINDOW_FRAME_CHANGED; - event.window = (macdrv_window)[self retain]; - event.window_frame_changed.frame = NSRectToCGRect(frame); - [queue postEvent:&event]; + event = macdrv_create_event(WINDOW_FRAME_CHANGED, self); + event->window_frame_changed.frame = NSRectToCGRect(frame); + [queue postEvent:event]; + macdrv_release_event(event); } - (BOOL)windowShouldClose:(id)sender { - macdrv_event event; - event.type = WINDOW_CLOSE_REQUESTED; - event.window = (macdrv_window)[self retain]; - [queue postEvent:&event]; + macdrv_event* event = macdrv_create_event(WINDOW_CLOSE_REQUESTED, self); + [queue postEvent:event]; + macdrv_release_event(event); return NO; } @@ -1170,16 +1173,16 @@ - (void)windowWillMiniaturize:(NSNotification *)notification { if (!ignore_windowMiniaturize) { - macdrv_event event; + macdrv_event* event; /* Coalesce events by discarding any previous ones still in the queue. */ [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_DID_MINIMIZE) | event_mask_for_type(WINDOW_DID_UNMINIMIZE) forWindow:self]; - event.type = WINDOW_DID_MINIMIZE; - event.window = (macdrv_window)[self retain]; - [queue postEvent:&event]; + event = macdrv_create_event(WINDOW_DID_MINIMIZE, self); + [queue postEvent:event]; + macdrv_release_event(event); } ignore_windowMiniaturize = FALSE; diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 6f35d9d1397..af5b30df64d 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -223,14 +223,14 @@ void macdrv_handle_event(const macdrv_event *event) */ static int process_events(macdrv_event_queue queue, macdrv_event_mask mask) { - macdrv_event event; + macdrv_event *event; int count = 0; - while (macdrv_get_event_from_queue(queue, mask, &event)) + while (macdrv_copy_event_from_queue(queue, mask, &event)) { count++; - macdrv_handle_event(&event); - macdrv_cleanup_event(&event); + macdrv_handle_event(event); + macdrv_release_event(event); } if (count) TRACE("processed %d events\n", count); return count; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 67da3a34138..c12545a5e8e 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -175,6 +175,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display, typedef uint32_t macdrv_event_mask; typedef struct macdrv_event { + int refs; int type; macdrv_window window; union { @@ -272,9 +273,9 @@ static inline macdrv_event_mask event_mask_for_type(int type) 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_from_queue(macdrv_event_queue queue, - macdrv_event_mask mask, macdrv_event *event) DECLSPEC_HIDDEN; -extern void macdrv_cleanup_event(macdrv_event *event) DECLSPEC_HIDDEN; +extern int macdrv_copy_event_from_queue(macdrv_event_queue queue, + macdrv_event_mask mask, macdrv_event **event) DECLSPEC_HIDDEN; +extern void macdrv_release_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;