static int mac_shadow_detect_monitors(macShadowSubsystem* subsystem) { size_t wide, high; MONITOR_DEF* monitor; CGDirectDisplayID displayId; displayId = CGMainDisplayID(); CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId); subsystem->pixelWidth = CGDisplayModeGetPixelWidth(mode); subsystem->pixelHeight = CGDisplayModeGetPixelHeight(mode); wide = CGDisplayPixelsWide(displayId); high = CGDisplayPixelsHigh(displayId); CGDisplayModeRelease(mode); subsystem->retina = ((subsystem->pixelWidth / wide) == 2) ? TRUE : FALSE; if (subsystem->retina) { subsystem->width = wide; subsystem->height = high; } else { subsystem->width = subsystem->pixelWidth; subsystem->height = subsystem->pixelHeight; } subsystem->numMonitors = 1; monitor = &(subsystem->monitors[0]); monitor->left = 0; monitor->top = 0; monitor->right = subsystem->width; monitor->bottom = subsystem->height; monitor->flags = 1; return 1; }
static BOOL display_mode_matches_descriptor(CGDisplayModeRef mode, const struct display_mode_descriptor* desc) { DWORD mode_io_flags; double mode_refresh; CFStringRef mode_pixel_encoding; if (!desc) return FALSE; if (CGDisplayModeGetWidth(mode) != desc->width || CGDisplayModeGetHeight(mode) != desc->height) return FALSE; mode_io_flags = CGDisplayModeGetIOFlags(mode); if ((desc->io_flags ^ mode_io_flags) & (kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeStretchedFlag | kDisplayModeInterlacedFlag | kDisplayModeTelevisionFlag)) return FALSE; mode_refresh = CGDisplayModeGetRefreshRate(mode); if (!mode_refresh) mode_refresh = 60; if (fabs(desc->refresh - mode_refresh) > 0.1) return FALSE; #if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 if (CGDisplayModeGetPixelWidth != NULL && CGDisplayModeGetPixelHeight != NULL) { if (CGDisplayModeGetPixelWidth(mode) != desc->pixel_width || CGDisplayModeGetPixelHeight(mode) != desc->pixel_height) return FALSE; } else #endif if (CGDisplayModeGetWidth(mode) != desc->pixel_width || CGDisplayModeGetHeight(mode) != desc->pixel_height) return FALSE; mode_pixel_encoding = CGDisplayModeCopyPixelEncoding(mode); if (!CFEqual(mode_pixel_encoding, desc->pixel_encoding)) { CFRelease(mode_pixel_encoding); return FALSE; } CFRelease(mode_pixel_encoding); return TRUE; }
/*********************************************************************** * copy_display_modes * * Wrapper around CGDisplayCopyAllDisplayModes() to include additional * modes on Retina-capable systems, but filter those which would confuse * Windows apps (basically duplicates at different DPIs). * * For example, some Retina Macs support a 1920x1200 mode, but it's not * returned from CGDisplayCopyAllDisplayModes() without special options. * This is especially bad if that's the user's default mode, since then * no "available" mode matches the initial settings. */ static CFArrayRef copy_display_modes(CGDirectDisplayID display) { CFArrayRef modes = NULL; #if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 if (&kCGDisplayShowDuplicateLowResolutionModes != NULL && CGDisplayModeGetPixelWidth != NULL && CGDisplayModeGetPixelHeight != NULL) { CFDictionaryRef options; struct display_mode_descriptor* desc; CFMutableDictionaryRef modes_by_size; CFIndex i, count; CGDisplayModeRef* mode_array; options = CFDictionaryCreate(NULL, (const void**)&kCGDisplayShowDuplicateLowResolutionModes, (const void**)&kCFBooleanTrue, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); modes = CGDisplayCopyAllDisplayModes(display, options); if (options) CFRelease(options); if (!modes) return NULL; desc = create_original_display_mode_descriptor(display); modes_by_size = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); count = CFArrayGetCount(modes); for (i = 0; i < count; i++) { BOOL better = TRUE; CGDisplayModeRef new_mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); BOOL new_is_original = display_mode_matches_descriptor(new_mode, desc); CFDictionaryRef key = create_mode_dict(new_mode); /* If a given mode is the user's default, then always list it in preference to any similar modes that may exist. */ if (new_is_original) better = TRUE; else { CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(new_mode); CGDisplayModeRef old_mode; if (pixel_encoding) { BOOL bpp30 = CFEqual(pixel_encoding, CFSTR(kIO30BitDirectPixels)); CFRelease(pixel_encoding); if (bpp30) { /* This is an odd pixel encoding. It seems it's only returned when using kCGDisplayShowDuplicateLowResolutionModes. It's 32bpp in terms of the actual raster layout, but it's 10 bits per component. I think that no Windows program is likely to need it and they will probably be confused by it. Skip it. */ CFRelease(key); continue; } } old_mode = (CGDisplayModeRef)CFDictionaryGetValue(modes_by_size, key); if (old_mode) { BOOL old_is_original = display_mode_matches_descriptor(old_mode, desc); if (old_is_original) better = FALSE; else { /* Otherwise, prefer a mode whose pixel size equals its point size over one which is scaled. */ size_t width_points = CGDisplayModeGetWidth(new_mode); size_t height_points = CGDisplayModeGetHeight(new_mode); size_t new_width_pixels = CGDisplayModeGetPixelWidth(new_mode); size_t new_height_pixels = CGDisplayModeGetPixelHeight(new_mode); size_t old_width_pixels = CGDisplayModeGetPixelWidth(old_mode); size_t old_height_pixels = CGDisplayModeGetPixelHeight(old_mode); BOOL new_size_same = (new_width_pixels == width_points && new_height_pixels == height_points); BOOL old_size_same = (old_width_pixels == width_points && old_height_pixels == height_points); if (new_size_same && !old_size_same) better = TRUE; else if (!new_size_same && old_size_same) better = FALSE; else { /* Otherwise, prefer the mode with the smaller pixel size. */ if (old_width_pixels < new_width_pixels || old_height_pixels < new_height_pixels) better = FALSE; } } } } if (better) CFDictionarySetValue(modes_by_size, key, new_mode); CFRelease(key); } free_display_mode_descriptor(desc); CFRelease(modes); count = CFDictionaryGetCount(modes_by_size); mode_array = HeapAlloc(GetProcessHeap(), 0, count * sizeof(mode_array[0])); CFDictionaryGetKeysAndValues(modes_by_size, NULL, (const void **)mode_array); modes = CFArrayCreate(NULL, (const void **)mode_array, count, &kCFTypeArrayCallBacks); HeapFree(GetProcessHeap(), 0, mode_array); CFRelease(modes_by_size); } else #endif modes = CGDisplayCopyAllDisplayModes(display, NULL); return modes; }
static BOOL write_display_settings(HKEY parent_hkey, CGDirectDisplayID displayID) { BOOL ret = FALSE; char display_key_name[19]; HKEY display_hkey; CGDisplayModeRef display_mode; DWORD val; CFStringRef pixel_encoding; size_t len; WCHAR* buf = NULL; snprintf(display_key_name, sizeof(display_key_name), "Display 0x%08x", CGDisplayUnitNumber(displayID)); /* @@ Wine registry key: HKLM\Software\Wine\Mac Driver\Initial Display Mode\Display 0xnnnnnnnn */ if (RegCreateKeyExA(parent_hkey, display_key_name, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &display_hkey, NULL)) return FALSE; display_mode = CGDisplayCopyDisplayMode(displayID); if (!display_mode) goto fail; val = CGDisplayModeGetWidth(display_mode); if (RegSetValueExA(display_hkey, "Width", 0, REG_DWORD, (const BYTE*)&val, sizeof(val))) goto fail; val = CGDisplayModeGetHeight(display_mode); if (RegSetValueExA(display_hkey, "Height", 0, REG_DWORD, (const BYTE*)&val, sizeof(val))) goto fail; val = CGDisplayModeGetRefreshRate(display_mode) * 100; if (RegSetValueExA(display_hkey, "RefreshRateTimes100", 0, REG_DWORD, (const BYTE*)&val, sizeof(val))) goto fail; val = CGDisplayModeGetIOFlags(display_mode); if (RegSetValueExA(display_hkey, "IOFlags", 0, REG_DWORD, (const BYTE*)&val, sizeof(val))) goto fail; #if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 if (CGDisplayModeGetPixelWidth != NULL && CGDisplayModeGetPixelHeight != NULL) { val = CGDisplayModeGetPixelWidth(display_mode); if (RegSetValueExA(display_hkey, "PixelWidth", 0, REG_DWORD, (const BYTE*)&val, sizeof(val))) goto fail; val = CGDisplayModeGetPixelHeight(display_mode); if (RegSetValueExA(display_hkey, "PixelHeight", 0, REG_DWORD, (const BYTE*)&val, sizeof(val))) goto fail; } #endif pixel_encoding = CGDisplayModeCopyPixelEncoding(display_mode); len = CFStringGetLength(pixel_encoding); buf = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); CFStringGetCharacters(pixel_encoding, CFRangeMake(0, len), (UniChar*)buf); buf[len] = 0; CFRelease(pixel_encoding); if (RegSetValueExW(display_hkey, pixelencodingW, 0, REG_SZ, (const BYTE*)buf, (len + 1) * sizeof(WCHAR))) goto fail; ret = TRUE; fail: HeapFree(GetProcessHeap(), 0, buf); if (display_mode) CGDisplayModeRelease(display_mode); RegCloseKey(display_hkey); if (!ret) RegDeleteKeyA(parent_hkey, display_key_name); return ret; }