From 13578b852b7631f99cf1fd5e2e5469edc5aae369 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Tue, 8 Feb 2011 11:37:52 -0800 Subject: [PATCH 1/6] XQuartz: RandR: Capture the display when switching modes with RandR This will prevent native windows from resizing as we change resolutions. Signed-off-by: Jeremy Huddleston --- hw/xquartz/quartz.c | 2 ++ hw/xquartz/quartz.h | 2 ++ hw/xquartz/quartzRandR.c | 13 +++++++++++++ hw/xquartz/xpr/xprAppleWM.c | 2 ++ hw/xquartz/xpr/xprFrame.c | 4 ++++ 5 files changed, 23 insertions(+) diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index 222a5eab0..11e5a74d7 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -82,6 +82,8 @@ Bool XQuartzIsRootless = TRUE; Bool XQuartzServerVisible = FALSE; Bool XQuartzFullscreenMenu = FALSE; +int32_t XQuartzShieldingWindowLevel = 0; + /* =========================================================================== diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h index b83391db9..67a7919b2 100644 --- a/hw/xquartz/quartz.h +++ b/hw/xquartz/quartz.h @@ -124,6 +124,8 @@ extern Bool XQuartzFullscreenMenu; /* Show the menu bar (autohide) while in FS extern Bool XQuartzFullscreenDisableHotkeys; extern Bool XQuartzOptionSendsAlt; /* Alt or Mode_switch? */ +extern int32_t XQuartzShieldingWindowLevel; /* CGShieldingWindowLevel() or 0 */ + Bool QuartzAddScreen(int index, ScreenPtr pScreen); Bool QuartzSetupScreen(int index, ScreenPtr pScreen); void QuartzInitOutput(int argc,char **argv); diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c index 296f9b669..57e975550 100644 --- a/hw/xquartz/quartzRandR.c +++ b/hw/xquartz/quartzRandR.c @@ -346,6 +346,14 @@ static int QuartzRandRRegisterModeCallback (ScreenPtr pScreen, static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL doRegister) { QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen); CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0]; + Bool captureDisplay = (pMode->refresh != FAKE_REFRESH_FULLSCREEN && pMode->refresh != FAKE_REFRESH_ROOTLESS); + + if(XQuartzShieldingWindowLevel == 0 && captureDisplay) { + CGCaptureAllDisplays(); + XQuartzShieldingWindowLevel = CGShieldingWindowLevel(); // 2147483630 + DEBUG_LOG("Display captured. ShieldWindowID: %u, Shield level: %d\n", + CGShieldingWindowID(screenId), XQuartzShieldingWindowLevel); + } if (pQuartzScreen->currentMode.ref && CFEqual(pMode->ref, pQuartzScreen->currentMode.ref)) { DEBUG_LOG("Requested RandR resolution matches current CG mode\n"); @@ -369,6 +377,11 @@ static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL pQuartzScreen->currentMode = *pMode; CFRetain(pQuartzScreen->currentMode.ref); + if(XQuartzShieldingWindowLevel != 0 && !captureDisplay) { + CGReleaseAllDisplays(); + XQuartzShieldingWindowLevel = 0; + } + return TRUE; } diff --git a/hw/xquartz/xpr/xprAppleWM.c b/hw/xquartz/xpr/xprAppleWM.c index 1a3d427b7..21e6f98fa 100644 --- a/hw/xquartz/xpr/xprAppleWM.c +++ b/hw/xquartz/xpr/xprAppleWM.c @@ -69,6 +69,8 @@ static int xprSetWindowLevel( if(XQuartzIsRootless) wc.window_level = normal_window_levels[level]; + else if(XQuartzShieldingWindowLevel) + wc.window_level = XQuartzShieldingWindowLevel + 1; else wc.window_level = rooted_window_levels[level]; diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c index 8ee3a28a6..15598e942 100644 --- a/hw/xquartz/xpr/xprFrame.c +++ b/hw/xquartz/xpr/xprFrame.c @@ -173,6 +173,8 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, if(XQuartzIsRootless) wc.window_level = normal_window_levels[pFrame->level]; + else if(XQuartzShieldingWindowLevel) + wc.window_level = XQuartzShieldingWindowLevel + 1; else wc.window_level = rooted_window_levels[pFrame->level]; mask |= XP_WINDOW_LEVEL; @@ -287,6 +289,8 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) { if(winRec) { if(XQuartzIsRootless) wc.window_level = normal_window_levels[winRec->level]; + else if(XQuartzShieldingWindowLevel) + wc.window_level = XQuartzShieldingWindowLevel + 1; else wc.window_level = rooted_window_levels[winRec->level]; mask |= XP_WINDOW_LEVEL; From 968652983f8e6ae6889b48e15f4098ff6ad4a15a Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Tue, 8 Feb 2011 12:26:35 -0800 Subject: [PATCH 2/6] XQuartz: RandR: Provide an alert box when entering a RandR mode for the first time. Signed-off-by: Jeremy Huddleston --- hw/xquartz/X11Application.h | 3 ++ hw/xquartz/X11Application.m | 29 ++++++++++++++++++ .../English.lproj/Localizable.strings | Bin 2698 -> 4410 bytes hw/xquartz/quartzRandR.c | 4 +++ 4 files changed, 36 insertions(+) diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h index b3ad19b53..256ff187a 100644 --- a/hw/xquartz/X11Application.h +++ b/hw/xquartz/X11Application.h @@ -73,6 +73,8 @@ void X11ApplicationServerReady (void); void X11ApplicationShowHideMenubar (int state); void X11ApplicationLaunchClient (const char *cmd); +Bool X11ApplicationCanEnterRandR (void); + void X11ApplicationMain(int argc, char **argv, char **envp); #define PREFS_APPSMENU "apps_menu" @@ -86,6 +88,7 @@ void X11ApplicationMain(int argc, char **argv, char **envp); #define PREFS_NO_TCP "nolisten_tcp" #define PREFS_DONE_XINIT_CHECK "done_xinit_check" #define PREFS_NO_QUIT_ALERT "no_quit_alert" +#define PREFS_NO_RANDR_ALERT "no_randr_alert" #define PREFS_OPTION_SENDS_ALT "option_sends_alt" #define PREFS_FAKE_BUTTON2 "fake_button2" #define PREFS_FAKE_BUTTON3 "fake_button3" diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index b855c8358..3521517a2 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -883,6 +883,35 @@ void X11ApplicationLaunchClient (const char *cmd) { [string release]; } +/* This is a special function in that it is run from the *SERVER* thread and + * not the AppKit thread. We want to block entering a screen-capturing RandR + * mode until we notify the user about how to get out if the X11 client crashes. + */ +Bool X11ApplicationCanEnterRandR(void) { + NSString *title, *msg; + + if([X11App prefs_get_boolean:@PREFS_NO_RANDR_ALERT default:NO] || XQuartzShieldingWindowLevel != 0) + return TRUE; + + title = NSLocalizedString(@"Enter RandR mode?", @"Dialog title when switching to RandR"); + msg = NSLocalizedString(@"An application has requested X11 to change the resolution of your display. X11 will restore the display to its previous state when the requesting application requests to return to the previous state. Alternatively, you can use the ⌥⌘A key sequence to force X11 to return to the previous state.", + @"Dialog when switching to RandR"); + + if(!XQuartzIsRootless) + QuartzShowFullscreen(FALSE); + + switch(NSRunAlertPanel(title, msg, NSLocalizedString(@"Allow", @""), NSLocalizedString (@"Cancel", @""), NSLocalizedString (@"Always Allow", @""))) { + case NSAlertOtherReturn: + [X11App prefs_set_boolean:@PREFS_NO_RANDR_ALERT value:YES]; + [X11App prefs_synchronize]; + case NSAlertDefaultReturn: + return YES; + + default: + return NO; + } +} + static void check_xinitrc (void) { char *tem, buf[1024]; NSString *msg; diff --git a/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings b/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings index 03415026eda1b31bd485e1ceba866771569b505f..bf2089ca1399c895dc701dfc23fa9bd44a1d8b8f 100644 GIT binary patch literal 4410 zcmeI0PfHv@5XFDz{RBBSN^+2};#oov4djwQOhO{$GVadm;Oxw1XV;CFeDox|>gnyC z{Ua)R2#5$y&s2AH^?R>g`{ytF?BO_}Afu$_0>_Mk86`Q61()PhIDRs>alNhVyFK>l zvBL>9jvH#`IHu$_SILdVXH?8=R(%y_aeU{11KzTO;|=Z+<~gKCZ{v>cvWp`s%eZFJ z?$~GO$e1vpq+md1`>&~JY`jqNVo}j^t(?HA;|L)7( z7aZZZA~)`e$$m!_gSK+2(1@C8JJLPNhi4zv^BGsZPlZ!gO`mb~P*&`8l<%YAcR=0t zHs8_3tJ;_@WtBpm8~$|;7slk=lvo@KUO`M#w_9|O8^=<;ecV+Srgc(`Z8>cI;%PEE zHZ74llu0GJqffK)2QmgY-rL%fWcBqoPm{r?)=5U~iX-bQ2IL40F~UEkU!PgGib(U% zF(N#tF<%UyW5cTaZ;W1j6X#iflg{|rdfn7|(FDgYn_In6%I`aGblPEWXRUXZ$5ZE# zKTxO1EnfXI^u^!o(_fo)WKJ@t&krj5{bmtEW12AE?b#_?LnqqYaTPl@<~S;9bMi6E z=-AH5n9^9kRF{iUVtdV1o5P5a)m$18Zw2xk^2XAI+p|sk^EMYHe;n(eTS?jR-E#8k z)xkT+8-}Vk6sBg;?W~_csJ1^P>E4PXXdRDsq^hLeP5YKNl5$pdPY8AJ{;jh0d}VZ# zP?o`ecpoKf1uvN1o}MxEjG>2OC{?hOi{91ejE&E_K^2C6-LJ&cpkH^7i8>nGgp_W$ w;y1oBG4ANj;1x)`(SH}B;yCvz$>7-bJ}{l}K09#4t<2W9pP0w}BM<5Q1Czw=+W-In delta 16 Xcmdm`)Fry1k!kXL4zJDCocq}UH%taF diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c index 57e975550..ede7969c7 100644 --- a/hw/xquartz/quartzRandR.c +++ b/hw/xquartz/quartzRandR.c @@ -40,6 +40,8 @@ #include "quartz.h" #include "darwin.h" +#include "X11Application.h" + #include #include @@ -349,6 +351,8 @@ static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL Bool captureDisplay = (pMode->refresh != FAKE_REFRESH_FULLSCREEN && pMode->refresh != FAKE_REFRESH_ROOTLESS); if(XQuartzShieldingWindowLevel == 0 && captureDisplay) { + if(!X11ApplicationCanEnterRandR()) + return FALSE; CGCaptureAllDisplays(); XQuartzShieldingWindowLevel = CGShieldingWindowLevel(); // 2147483630 DEBUG_LOG("Display captured. ShieldWindowID: %u, Shield level: %d\n", From 8cf3348e90846f5b04236479042228fb98ac8f70 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Tue, 8 Feb 2011 11:38:35 -0800 Subject: [PATCH 3/6] XQuartz: RandR: Add RandR modes for the primary display in multi-monitor configs We now support using RandR to set the resolution of the primary display (and place a shielding window on other displays) in multi-monitor configurations. Signed-off-by: Jeremy Huddleston --- hw/xquartz/quartzRandR.c | 10 ---------- hw/xquartz/xpr/xprScreen.c | 7 +++++++ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c index ede7969c7..05641a65d 100644 --- a/hw/xquartz/quartzRandR.c +++ b/hw/xquartz/quartzRandR.c @@ -413,16 +413,6 @@ static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) { if (pQuartzScreen->displayCount == 0) return FALSE; - if (pQuartzScreen->displayCount > 1) { - /* RandR operations are not well-defined for an X11 screen spanning - multiple CG displays. Create two entries for the current virtual - resolution including/excluding the menu bar. */ - - QuartzRandRRegisterMode(pScreen, &pQuartzScreen->rootlessMode); - QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fullscreenMode); - return TRUE; - } - return QuartzRandREnumerateModes(pScreen, QuartzRandRRegisterModeCallback, NULL); } diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index cba358f8b..6e6d06e6b 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -196,6 +196,13 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScr return; } + /* If the displays are captured, we are in a RandR game mode + * on the primary display, so we only want to include the first + * display. The others are covered by the shield window. + */ + if (CGDisplayIsCaptured(kCGDirectMainDisplay)) + displayCount = 1; + displayList = malloc(displayCount * sizeof(CGDirectDisplayID)); if(!displayList) FatalError("Unable to allocate memory for list of displays.\n"); From de32d4dcf57c10fc100c1b33630127947a8c8460 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Sun, 27 Feb 2011 15:49:10 -0800 Subject: [PATCH 4/6] Revert "rootless: Remove ROOTLESS_WORKAROUND" Christof Wolf has reported a regression that seems to be caused by this change, so reverting the change in the 1.9 branch. We'll investigate a proper fix in master for 1.10. This reverts commit c89f0521044083a11d538ebfeaabee6fc7fb9a03. Signed-off-by: Jeremy Huddleston --- configure.ac | 2 +- miext/damage/damage.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 85d5c980e..0a063918e 100644 --- a/configure.ac +++ b/configure.ac @@ -1923,7 +1923,7 @@ if test "x$XQUARTZ" = xyes; then AC_CHECK_LIB([Xplugin],[xp_init],[:]) - CFLAGS="${CFLAGS} -DROOTLESS_SAFEALPHA -DNO_ALLOCA" + CFLAGS="${CFLAGS} -DROOTLESS_WORKAROUND -DROOTLESS_SAFEALPHA -DNO_ALLOCA" PKG_CHECK_MODULES(XPBPROXY, $APPLEWMPROTO $LIBAPPLEWM xfixes x11) diff --git a/miext/damage/damage.c b/miext/damage/damage.c index 566995c41..0fe1fb603 100644 --- a/miext/damage/damage.c +++ b/miext/damage/damage.c @@ -89,7 +89,11 @@ getDrawableDamageRef (DrawablePtr pDrawable) ScreenPtr pScreen = pDrawable->pScreen; pPixmap = 0; - if (pScreen->GetWindowPixmap) + if (pScreen->GetWindowPixmap +#ifdef ROOTLESS_WORKAROUND + && ((WindowPtr)pDrawable)->viewable +#endif + ) pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable); if (!pPixmap) From 0343aed1f082baf4bfbd730c1c3582f1410b8741 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Sun, 27 Feb 2011 16:18:27 -0800 Subject: [PATCH 5/6] XQuartz: Don't use deprecated CoreGraphics API on SL and Lion Signed-off-by: Jeremy Huddleston --- hw/xquartz/xpr/xprScreen.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index 6e6d06e6b..972278b75 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -299,9 +299,34 @@ xprAddScreen(int index, ScreenPtr pScreen) DEBUG_LOG("index=%d depth=%d\n", index, depth); if(depth == -1) { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 depth = CGDisplaySamplesPerPixel(kCGDirectMainDisplay) * CGDisplayBitsPerSample(kCGDirectMainDisplay); +#else + CGDisplayModeRef modeRef; + CFStringRef encStrRef; + + modeRef = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); + if(!modeRef) + goto have_depth; + + encStrRef = CGDisplayModeCopyPixelEncoding(modeRef); + CFRelease(modeRef); + if(!encStrRef) + goto have_depth; + + if(CFStringCompare(encStrRef, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + depth = 24; + } else if(CFStringCompare(encStrRef, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + depth = 15; + } else if(CFStringCompare(encStrRef, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + depth = 8; + } + + CFRelease(encStrRef); +#endif } +have_depth: switch(depth) { case 8: // pseudo-working dfb->visuals = PseudoColorMask; @@ -326,7 +351,7 @@ xprAddScreen(int index, ScreenPtr pScreen) // case 24: default: if(depth != 24) - ErrorF("Unsupported color depth requested. Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d CGDisplaySamplesPerPixel=%d CGDisplayBitsPerSample=%d)\n", darwinDesiredDepth, depth, (int)CGDisplaySamplesPerPixel(kCGDirectMainDisplay), (int)CGDisplayBitsPerSample(kCGDirectMainDisplay)); + ErrorF("Unsupported color depth requested. Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d)\n", depth, darwinDesiredDepth); dfb->visuals = TrueColorMask; //LARGE_VISUALS; dfb->preferredCVC = TrueColor; dfb->depth = 24; From 69a9171dbbafd6a7db702d48770d28fb54717545 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Tue, 1 Mar 2011 20:02:46 -0800 Subject: [PATCH 6/6] XQuartz: pbproxy: Protect against possible collision between Cocoa and X11 Cursor types Signed-off-by: Jeremy Huddleston --- hw/xquartz/pbproxy/x-selection.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xquartz/pbproxy/x-selection.h b/hw/xquartz/pbproxy/x-selection.h index 614c8b091..d4a39e58f 100644 --- a/hw/xquartz/pbproxy/x-selection.h +++ b/hw/xquartz/pbproxy/x-selection.h @@ -33,7 +33,9 @@ #include "pbproxy.h" +#define Cursor X_Cursor #include +#undef Cursor #include