Module: wine Branch: master Commit: bc75a9baffd889deef00a2acfdb19ae4bdce29ca URL: http://source.winehq.org/git/wine.git/?a=commit;h=bc75a9baffd889deef00a2acfd...
Author: Ken Thomases ken@codeweavers.com Date: Sun Feb 17 19:28:34 2013 -0600
winemac: Implement DISPLAYS_CHANGED event for when display configuration has changed.
---
dlls/winemac.drv/cocoa_app.m | 15 +++++++++ dlls/winemac.drv/display.c | 65 ++++++++++++++++++++++++++++++++++++++- dlls/winemac.drv/event.c | 5 +++ dlls/winemac.drv/gdi.c | 10 +++++- dlls/winemac.drv/macdrv.h | 6 +++ dlls/winemac.drv/macdrv_cocoa.h | 1 + dlls/winemac.drv/window.c | 33 ++++++++++++++++++++ 7 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index 2651cfc..479b4d0 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -312,6 +312,20 @@ int macdrv_err_on; } }
+ - (void) sendDisplaysChanged + { + macdrv_event event; + WineEventQueue* queue; + + event.type = DISPLAYS_CHANGED; + event.window = NULL; + + [eventQueuesLock lock]; + for (queue in eventQueues) + [queue postEvent:&event]; + [eventQueuesLock unlock]; + } +
/* * ---------- NSApplication method overrides ---------- @@ -340,6 +354,7 @@ int macdrv_err_on; - (void)applicationDidChangeScreenParameters:(NSNotification *)notification { primaryScreenHeightValid = FALSE; + [self sendDisplaysChanged]; }
- (void)applicationDidResignActive:(NSNotification *)notification diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index a1bea38..2a96631 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -2,7 +2,7 @@ * MACDRV display settings * * Copyright 2003 Alexander James Pasadyn - * Copyright 2011, 2012 Ken Thomases for CodeWeavers Inc. + * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +38,42 @@ static inline CGDirectDisplayID monitor_to_display_id(HMONITOR handle) }
+static int display_mode_bits_per_pixel(CGDisplayModeRef display_mode) +{ + CFStringRef pixel_encoding; + int bits_per_pixel = 0; + + pixel_encoding = CGDisplayModeCopyPixelEncoding(display_mode); + if (pixel_encoding) + { + if (CFEqual(pixel_encoding, CFSTR(kIO32BitFloatPixels))) + bits_per_pixel = 128; + else if (CFEqual(pixel_encoding, CFSTR(kIO16BitFloatPixels))) + bits_per_pixel = 64; + else if (CFEqual(pixel_encoding, CFSTR(kIO64BitDirectPixels))) + bits_per_pixel = 64; + else if (CFEqual(pixel_encoding, CFSTR(kIO30BitDirectPixels))) + bits_per_pixel = 30; + else if (CFEqual(pixel_encoding, CFSTR(IO32BitDirectPixels))) + bits_per_pixel = 32; + else if (CFEqual(pixel_encoding, CFSTR(IO16BitDirectPixels))) + bits_per_pixel = 16; + else if (CFEqual(pixel_encoding, CFSTR(IO8BitIndexedPixels))) + bits_per_pixel = 8; + else if (CFEqual(pixel_encoding, CFSTR(IO4BitIndexedPixels))) + bits_per_pixel = 4; + else if (CFEqual(pixel_encoding, CFSTR(IO2BitIndexedPixels))) + bits_per_pixel = 2; + else if (CFEqual(pixel_encoding, CFSTR(IO1BitIndexedPixels))) + bits_per_pixel = 1; + + CFRelease(pixel_encoding); + } + + return bits_per_pixel; +} + + /*********************************************************************** * EnumDisplayMonitors (MACDRV.@) */ @@ -156,3 +192,30 @@ BOOL CDECL macdrv_GetMonitorInfo(HMONITOR monitor, LPMONITORINFO info) macdrv_free_displays(displays); return (i < num_displays); } + + +/*********************************************************************** + * macdrv_displays_changed + * + * Handler for DISPLAYS_CHANGED events. + */ +void macdrv_displays_changed(const macdrv_event *event) +{ + HWND hwnd = GetDesktopWindow(); + + /* A system display change will get delivered to all GUI-attached threads, + so the desktop-window-owning thread will get it and all others should + ignore it. */ + if (GetWindowThreadProcessId(hwnd, NULL) == GetCurrentThreadId()) + { + CGDirectDisplayID mainDisplay = CGMainDisplayID(); + CGDisplayModeRef mode = CGDisplayCopyDisplayMode(mainDisplay); + size_t width = CGDisplayModeGetWidth(mode); + size_t height = CGDisplayModeGetHeight(mode); + int mode_bpp = display_mode_bits_per_pixel(mode); + + CGDisplayModeRelease(mode); + SendMessageW(hwnd, WM_MACDRV_UPDATE_DESKTOP_RECT, mode_bpp, + MAKELPARAM(width, height)); + } +} diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index f03fef4..b9131f7 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -33,6 +33,7 @@ static const char *dbgstr_event(int type) { static const char * const event_names[] = { "APP_DEACTIVATED", + "DISPLAYS_CHANGED", "KEY_PRESS", "KEY_RELEASE", "KEYBOARD_CHANGED", @@ -84,6 +85,7 @@ static macdrv_event_mask get_event_mask(DWORD mask) if (mask & QS_POSTMESSAGE) { event_mask |= event_mask_for_type(APP_DEACTIVATED); + event_mask |= event_mask_for_type(DISPLAYS_CHANGED); event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED); event_mask |= event_mask_for_type(WINDOW_DID_MINIMIZE); event_mask |= event_mask_for_type(WINDOW_DID_UNMINIMIZE); @@ -116,6 +118,9 @@ void macdrv_handle_event(macdrv_event *event) case APP_DEACTIVATED: macdrv_app_deactivated(); break; + case DISPLAYS_CHANGED: + macdrv_displays_changed(event); + break; case KEY_PRESS: case KEY_RELEASE: macdrv_key_event(hwnd, event); diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 333cb0c..6ded900 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -2,7 +2,7 @@ * Mac graphics driver initialisation functions * * Copyright 1996 Alexandre Julliard - * Copyright 2011, 2012 Ken Thomases for CodeWeavers, Inc. + * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -200,6 +200,14 @@ static void device_init(void) }
+void macdrv_reset_device_metrics(void) +{ + EnterCriticalSection(&device_data_section); + device_data_valid = FALSE; + LeaveCriticalSection(&device_data_section); +} + + static MACDRV_PDEVICE *create_mac_physdev(void) { MACDRV_PDEVICE *physDev; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 8c4ce54..113cda1 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -68,6 +68,7 @@ static inline const char *wine_dbgstr_cgrect(CGRect cgrect) */
extern CGRect macdrv_get_desktop_rect(void) DECLSPEC_HIDDEN; +extern void macdrv_reset_device_metrics(void) DECLSPEC_HIDDEN;
/************************************************************************** @@ -78,6 +79,9 @@ extern CGRect macdrv_get_desktop_rect(void) DECLSPEC_HIDDEN; enum macdrv_window_messages { WM_MACDRV_SET_WIN_REGION = 0x80001000, + WM_MACDRV_UPDATE_DESKTOP_RECT, + WM_MACDRV_RESET_DEVICE_METRICS, + WM_MACDRV_DISPLAYCHANGE, };
struct macdrv_thread_data @@ -142,4 +146,6 @@ extern void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_dat extern void macdrv_keyboard_changed(const macdrv_event *event) DECLSPEC_HIDDEN; extern void macdrv_key_event(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
+extern void macdrv_displays_changed(const macdrv_event *event) DECLSPEC_HIDDEN; + #endif /* __WINE_MACDRV_H */ diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 23f0edf..5ffd7c7 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -126,6 +126,7 @@ extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDE /* event */ enum { APP_DEACTIVATED, + DISPLAYS_CHANGED, KEY_PRESS, KEY_RELEASE, KEYBOARD_CHANGED, diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 65f7955..c7513f0 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1192,6 +1192,39 @@ LRESULT CDECL macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) release_win_data(data); } return 0; + case WM_MACDRV_UPDATE_DESKTOP_RECT: + if (hwnd == GetDesktopWindow()) + { + CGRect new_desktop_rect; + RECT current_desktop_rect; + + macdrv_reset_device_metrics(); + new_desktop_rect = macdrv_get_desktop_rect(); + if (!GetWindowRect(hwnd, ¤t_desktop_rect) || + !CGRectEqualToRect(cgrect_from_rect(current_desktop_rect), new_desktop_rect)) + { + SendMessageTimeoutW(HWND_BROADCAST, WM_MACDRV_RESET_DEVICE_METRICS, 0, 0, + SMTO_ABORTIFHUNG, 2000, NULL); + SetWindowPos(hwnd, 0, CGRectGetMinX(new_desktop_rect), CGRectGetMinY(new_desktop_rect), + CGRectGetWidth(new_desktop_rect), CGRectGetHeight(new_desktop_rect), + SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE); + SendMessageTimeoutW(HWND_BROADCAST, WM_MACDRV_DISPLAYCHANGE, wp, lp, + SMTO_ABORTIFHUNG, 2000, NULL); + } + } + return 0; + case WM_MACDRV_RESET_DEVICE_METRICS: + macdrv_reset_device_metrics(); + return 0; + case WM_MACDRV_DISPLAYCHANGE: + if ((data = get_win_data(hwnd))) + { + if (data->cocoa_window && data->on_screen) + sync_window_position(data, SWP_NOZORDER | SWP_NOACTIVATE); + release_win_data(data); + } + SendMessageW(hwnd, WM_DISPLAYCHANGE, wp, lp); + return 0; }
FIXME("unrecognized window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp);