XQuartz: RandR: Don't crash if X11 is launched while there are no attached displays
If CG reports no displays when launching, we could crash in RandR. Instead, just provide a fake 800x600 display until we are notified about displays being attached. Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
This commit is contained in:
parent
f25ca898c5
commit
60af79e35e
|
@ -464,11 +464,15 @@ void QuartzSpaceChanged(uint32_t space_id) {
|
||||||
void QuartzCopyDisplayIDs(ScreenPtr pScreen,
|
void QuartzCopyDisplayIDs(ScreenPtr pScreen,
|
||||||
int displayCount, CGDirectDisplayID *displayIDs) {
|
int displayCount, CGDirectDisplayID *displayIDs) {
|
||||||
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
||||||
int size = displayCount * sizeof(CGDirectDisplayID);
|
|
||||||
|
|
||||||
free(pQuartzScreen->displayIDs);
|
free(pQuartzScreen->displayIDs);
|
||||||
|
if(displayCount) {
|
||||||
|
size_t size = displayCount * sizeof(CGDirectDisplayID);
|
||||||
pQuartzScreen->displayIDs = malloc(size);
|
pQuartzScreen->displayIDs = malloc(size);
|
||||||
memcpy(pQuartzScreen->displayIDs, displayIDs, size);
|
memcpy(pQuartzScreen->displayIDs, displayIDs, size);
|
||||||
|
} else {
|
||||||
|
pQuartzScreen->displayIDs = NULL;
|
||||||
|
}
|
||||||
pQuartzScreen->displayCount = displayCount;
|
pQuartzScreen->displayCount = displayCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons,
|
* Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons,
|
||||||
* 2010 Jan Hauffa.
|
* 2010 Jan Hauffa.
|
||||||
* 2010 Apple Inc.
|
* 2010-2011 Apple Inc.
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
@ -124,13 +124,16 @@ static Bool QuartzRandRSetCGMode (CGDirectDisplayID screenId,
|
||||||
static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
|
static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
|
||||||
QuartzModeCallback callback,
|
QuartzModeCallback callback,
|
||||||
void *data) {
|
void *data) {
|
||||||
|
Bool retval = FALSE;
|
||||||
|
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
||||||
|
|
||||||
|
/* Just an 800x600 fallback if we have no attached heads */
|
||||||
|
if(pQuartzScreen->displayIDs) {
|
||||||
CFDictionaryRef curModeRef, modeRef;
|
CFDictionaryRef curModeRef, modeRef;
|
||||||
long curBpp;
|
long curBpp;
|
||||||
CFArrayRef modes;
|
CFArrayRef modes;
|
||||||
QuartzModeInfo modeInfo;
|
QuartzModeInfo modeInfo;
|
||||||
int i;
|
int i;
|
||||||
BOOL retval = FALSE;
|
|
||||||
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
|
||||||
CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
|
CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
|
||||||
|
|
||||||
curModeRef = CGDisplayCurrentMode(screenId);
|
curModeRef = CGDisplayCurrentMode(screenId);
|
||||||
|
@ -163,6 +166,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
|
||||||
else if (cb == CALLBACK_ERROR)
|
else if (cb == CALLBACK_ERROR)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
|
switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
|
||||||
case CALLBACK_SUCCESS:
|
case CALLBACK_SUCCESS:
|
||||||
|
@ -225,15 +229,17 @@ static Bool QuartzRandRSetCGMode (CGDirectDisplayID screenId,
|
||||||
static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
|
static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
|
||||||
QuartzModeCallback callback,
|
QuartzModeCallback callback,
|
||||||
void *data) {
|
void *data) {
|
||||||
|
Bool retval = FALSE;
|
||||||
|
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
||||||
|
|
||||||
|
/* Just an 800x600 fallback if we have no attached heads */
|
||||||
|
if(pQuartzScreen->displayIDs) {
|
||||||
CGDisplayModeRef curModeRef, modeRef;
|
CGDisplayModeRef curModeRef, modeRef;
|
||||||
CFStringRef curPixelEnc, pixelEnc;
|
CFStringRef curPixelEnc, pixelEnc;
|
||||||
CFComparisonResult pixelEncEqual;
|
CFComparisonResult pixelEncEqual;
|
||||||
CFArrayRef modes;
|
CFArrayRef modes;
|
||||||
QuartzModeInfo modeInfo;
|
QuartzModeInfo modeInfo;
|
||||||
int i;
|
int i;
|
||||||
Bool retval = FALSE;
|
|
||||||
|
|
||||||
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
|
||||||
CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
|
CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
|
||||||
|
|
||||||
curModeRef = CGDisplayCopyDisplayMode(screenId);
|
curModeRef = CGDisplayCopyDisplayMode(screenId);
|
||||||
|
@ -280,6 +286,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
|
||||||
|
|
||||||
CFRelease(modes);
|
CFRelease(modes);
|
||||||
CFRelease(curPixelEnc);
|
CFRelease(curPixelEnc);
|
||||||
|
}
|
||||||
|
|
||||||
switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
|
switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
|
||||||
case CALLBACK_SUCCESS:
|
case CALLBACK_SUCCESS:
|
||||||
|
@ -347,9 +354,13 @@ static int QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
|
||||||
|
|
||||||
static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL doRegister) {
|
static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL doRegister) {
|
||||||
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
||||||
CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
|
|
||||||
Bool captureDisplay = (pMode->refresh != FAKE_REFRESH_FULLSCREEN && pMode->refresh != FAKE_REFRESH_ROOTLESS);
|
Bool captureDisplay = (pMode->refresh != FAKE_REFRESH_FULLSCREEN && pMode->refresh != FAKE_REFRESH_ROOTLESS);
|
||||||
|
CGDirectDisplayID screenId;
|
||||||
|
|
||||||
|
if(pQuartzScreen->displayIDs == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
screenId = pQuartzScreen->displayIDs[0];
|
||||||
if(XQuartzShieldingWindowLevel == 0 && captureDisplay) {
|
if(XQuartzShieldingWindowLevel == 0 && captureDisplay) {
|
||||||
if(!X11ApplicationCanEnterRandR())
|
if(!X11ApplicationCanEnterRandR())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -379,6 +390,7 @@ static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL
|
||||||
if(pQuartzScreen->currentMode.ref)
|
if(pQuartzScreen->currentMode.ref)
|
||||||
CFRelease(pQuartzScreen->currentMode.ref);
|
CFRelease(pQuartzScreen->currentMode.ref);
|
||||||
pQuartzScreen->currentMode = *pMode;
|
pQuartzScreen->currentMode = *pMode;
|
||||||
|
if(pQuartzScreen->currentMode.ref)
|
||||||
CFRetain(pQuartzScreen->currentMode.ref);
|
CFRetain(pQuartzScreen->currentMode.ref);
|
||||||
|
|
||||||
if(XQuartzShieldingWindowLevel != 0 && !captureDisplay) {
|
if(XQuartzShieldingWindowLevel != 0 && !captureDisplay) {
|
||||||
|
@ -406,13 +418,8 @@ static int QuartzRandRSetModeCallback (ScreenPtr pScreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
|
static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
|
||||||
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
|
||||||
|
|
||||||
*rotations = RR_Rotate_0; /* TODO: support rotation */
|
*rotations = RR_Rotate_0; /* TODO: support rotation */
|
||||||
|
|
||||||
if (pQuartzScreen->displayCount == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return QuartzRandREnumerateModes(pScreen, QuartzRandRRegisterModeCallback, NULL);
|
return QuartzRandREnumerateModes(pScreen, QuartzRandRRegisterModeCallback, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,9 +434,6 @@ static Bool QuartzRandRSetConfig (ScreenPtr pScreen,
|
||||||
reqMode.height = pSize->height;
|
reqMode.height = pSize->height;
|
||||||
reqMode.refresh = rate;
|
reqMode.refresh = rate;
|
||||||
|
|
||||||
if (pQuartzScreen->displayCount == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Do not switch modes if requested mode is equal to current mode. */
|
/* Do not switch modes if requested mode is equal to current mode. */
|
||||||
if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->currentMode))
|
if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->currentMode))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -446,17 +450,24 @@ static Bool _QuartzRandRUpdateFakeModes (ScreenPtr pScreen) {
|
||||||
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
|
||||||
QuartzModeInfo activeMode;
|
QuartzModeInfo activeMode;
|
||||||
|
|
||||||
if (!QuartzRandRCopyCurrentModeInfo(pQuartzScreen->displayIDs[0], &activeMode)) {
|
if(pQuartzScreen->displayCount > 0) {
|
||||||
|
if(!QuartzRandRCopyCurrentModeInfo(pQuartzScreen->displayIDs[0], &activeMode)) {
|
||||||
ErrorF("Unable to determine current display mode.\n");
|
ErrorF("Unable to determine current display mode.\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
memset(&activeMode, 0, sizeof(activeMode));
|
||||||
|
activeMode.width = 800;
|
||||||
|
activeMode.height = 600;
|
||||||
|
activeMode.refresh = 60;
|
||||||
|
}
|
||||||
|
|
||||||
if(pQuartzScreen->fullscreenMode.ref)
|
if(pQuartzScreen->fullscreenMode.ref)
|
||||||
CFRelease(pQuartzScreen->fullscreenMode.ref);
|
CFRelease(pQuartzScreen->fullscreenMode.ref);
|
||||||
if(pQuartzScreen->currentMode.ref)
|
if(pQuartzScreen->currentMode.ref)
|
||||||
CFRelease(pQuartzScreen->currentMode.ref);
|
CFRelease(pQuartzScreen->currentMode.ref);
|
||||||
|
|
||||||
if (pQuartzScreen->displayCount > 1) {
|
if(pQuartzScreen->displayCount > 1) {
|
||||||
activeMode.width = pScreen->width;
|
activeMode.width = pScreen->width;
|
||||||
activeMode.height = pScreen->height;
|
activeMode.height = pScreen->height;
|
||||||
if(XQuartzIsRootless)
|
if(XQuartzIsRootless)
|
||||||
|
@ -479,6 +490,7 @@ static Bool _QuartzRandRUpdateFakeModes (ScreenPtr pScreen) {
|
||||||
/* This extra retain is for currentMode's copy.
|
/* This extra retain is for currentMode's copy.
|
||||||
* fullscreen and rootless share a retain.
|
* fullscreen and rootless share a retain.
|
||||||
*/
|
*/
|
||||||
|
if(pQuartzScreen->currentMode.ref)
|
||||||
CFRetain(pQuartzScreen->currentMode.ref);
|
CFRetain(pQuartzScreen->currentMode.ref);
|
||||||
|
|
||||||
DEBUG_LOG("rootlessMode: %d x %d\n", (int)pQuartzScreen->rootlessMode.width, (int)pQuartzScreen->rootlessMode.height);
|
DEBUG_LOG("rootlessMode: %d x %d\n", (int)pQuartzScreen->rootlessMode.width, (int)pQuartzScreen->rootlessMode.height);
|
||||||
|
|
|
@ -193,6 +193,7 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScr
|
||||||
*width = 800;
|
*width = 800;
|
||||||
*height = 600;
|
*height = 600;
|
||||||
PseudoramiXAddScreen(*x, *y, *width, *height);
|
PseudoramiXAddScreen(*x, *y, *width, *height);
|
||||||
|
QuartzCopyDisplayIDs(pScreen, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue