winemac: Implement DISPLAYS_CHANGED event for when display configuration has changed.

This commit is contained in:
Ken Thomases 2013-02-17 19:28:34 -06:00 committed by Alexandre Julliard
parent be6af9a169
commit bc75a9baff
7 changed files with 133 additions and 2 deletions

View File

@ -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 ---------- * ---------- NSApplication method overrides ----------
@ -340,6 +354,7 @@ int macdrv_err_on;
- (void)applicationDidChangeScreenParameters:(NSNotification *)notification - (void)applicationDidChangeScreenParameters:(NSNotification *)notification
{ {
primaryScreenHeightValid = FALSE; primaryScreenHeightValid = FALSE;
[self sendDisplaysChanged];
} }
- (void)applicationDidResignActive:(NSNotification *)notification - (void)applicationDidResignActive:(NSNotification *)notification

View File

@ -2,7 +2,7 @@
* MACDRV display settings * MACDRV display settings
* *
* Copyright 2003 Alexander James Pasadyn * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * 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.@) * EnumDisplayMonitors (MACDRV.@)
*/ */
@ -156,3 +192,30 @@ BOOL CDECL macdrv_GetMonitorInfo(HMONITOR monitor, LPMONITORINFO info)
macdrv_free_displays(displays); macdrv_free_displays(displays);
return (i < num_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));
}
}

View File

@ -33,6 +33,7 @@ static const char *dbgstr_event(int type)
{ {
static const char * const event_names[] = { static const char * const event_names[] = {
"APP_DEACTIVATED", "APP_DEACTIVATED",
"DISPLAYS_CHANGED",
"KEY_PRESS", "KEY_PRESS",
"KEY_RELEASE", "KEY_RELEASE",
"KEYBOARD_CHANGED", "KEYBOARD_CHANGED",
@ -84,6 +85,7 @@ static macdrv_event_mask get_event_mask(DWORD mask)
if (mask & QS_POSTMESSAGE) if (mask & QS_POSTMESSAGE)
{ {
event_mask |= event_mask_for_type(APP_DEACTIVATED); 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_CLOSE_REQUESTED);
event_mask |= event_mask_for_type(WINDOW_DID_MINIMIZE); event_mask |= event_mask_for_type(WINDOW_DID_MINIMIZE);
event_mask |= event_mask_for_type(WINDOW_DID_UNMINIMIZE); event_mask |= event_mask_for_type(WINDOW_DID_UNMINIMIZE);
@ -116,6 +118,9 @@ void macdrv_handle_event(macdrv_event *event)
case APP_DEACTIVATED: case APP_DEACTIVATED:
macdrv_app_deactivated(); macdrv_app_deactivated();
break; break;
case DISPLAYS_CHANGED:
macdrv_displays_changed(event);
break;
case KEY_PRESS: case KEY_PRESS:
case KEY_RELEASE: case KEY_RELEASE:
macdrv_key_event(hwnd, event); macdrv_key_event(hwnd, event);

View File

@ -2,7 +2,7 @@
* Mac graphics driver initialisation functions * Mac graphics driver initialisation functions
* *
* Copyright 1996 Alexandre Julliard * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * 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) static MACDRV_PDEVICE *create_mac_physdev(void)
{ {
MACDRV_PDEVICE *physDev; MACDRV_PDEVICE *physDev;

View File

@ -68,6 +68,7 @@ static inline const char *wine_dbgstr_cgrect(CGRect cgrect)
*/ */
extern CGRect macdrv_get_desktop_rect(void) DECLSPEC_HIDDEN; 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 enum macdrv_window_messages
{ {
WM_MACDRV_SET_WIN_REGION = 0x80001000, WM_MACDRV_SET_WIN_REGION = 0x80001000,
WM_MACDRV_UPDATE_DESKTOP_RECT,
WM_MACDRV_RESET_DEVICE_METRICS,
WM_MACDRV_DISPLAYCHANGE,
}; };
struct macdrv_thread_data 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_keyboard_changed(const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_key_event(HWND hwnd, 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 */ #endif /* __WINE_MACDRV_H */

View File

@ -126,6 +126,7 @@ extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDE
/* event */ /* event */
enum { enum {
APP_DEACTIVATED, APP_DEACTIVATED,
DISPLAYS_CHANGED,
KEY_PRESS, KEY_PRESS,
KEY_RELEASE, KEY_RELEASE,
KEYBOARD_CHANGED, KEYBOARD_CHANGED,

View File

@ -1192,6 +1192,39 @@ LRESULT CDECL macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
release_win_data(data); release_win_data(data);
} }
return 0; 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, &current_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); FIXME("unrecognized window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp);