Move the resource restore/destroy functionality of

dmxAttachScreen/dmxDetachScreen into dmxEnableScreen/dmxDisableScreen
so that screens can be attached but not enabled.
This commit is contained in:
David Reveman 2008-09-26 13:46:25 -04:00
parent 671a1c4737
commit 80d2040d94
10 changed files with 273 additions and 154 deletions

View file

@ -521,6 +521,9 @@ static int ProcDMXAddScreen(ClientPtr client)
&attr, 0, NULL, 0, NULL, 0, NULL,
0, 0);
if (status == Success)
dmxEnableScreen(stuff->physicalScreen);
xfree(name);
rep.type = X_Reply;

View file

@ -175,6 +175,8 @@ typedef struct _DMXScreenInfo {
int beShmEventBase;
#endif
Display *beAttachedDisplay; /**< Disabld X server's display */
char *authType;
int authTypeLen;
char *authData;

View file

@ -132,6 +132,8 @@ attach_screen (DBusMessage *message,
return ret;
}
dmxEnableScreen(screen);
return Success;
}

View file

@ -321,22 +321,36 @@ int dmxAddInput(DMXInputAttributesPtr attr, int *id)
if (attr->inputType == 2)
{
DMXInputInfo *dmxInput = &dmxScreens[attr->physicalScreen].input;
int ret;
DMXScreenInfo *dmxScreen = &dmxScreens[attr->physicalScreen];
int ret;
ret = dmxInputAttach (dmxInput);
if (ret == Success)
if (dmxScreen->beDisplay)
{
int j;
ret = dmxInputAttach (&dmxScreen->input);
if (ret != Success)
return ret;
dmxInputEnable (&dmxScreen->input);
for (j = currentMaxClients; --j >= 0; )
if (clients[j])
FindClientResourcesByType (clients[j], RT_PASSIVEGRAB,
dmxBERestorePassiveGrab,
(pointer) dmxInput);
*id = attr->physicalScreen;
(pointer) &dmxScreen->input);
}
else
{
dmxScreen->beDisplay = dmxScreen->beAttachedDisplay;
ret = dmxInputAttach (&dmxScreen->input);
dmxScreen->beDisplay = NULL;
if (ret != Success)
return ret;
}
*id = attr->physicalScreen;
return ret;
}
@ -347,10 +361,25 @@ int dmxAddInput(DMXInputAttributesPtr attr, int *id)
/** Remove the input with physical id \a id. */
int dmxRemoveInput(int id)
{
int ret;
if (id < 0 || id >= dmxNumScreens)
return BadValue;
return dmxInputDetach (&dmxScreens[id].input);
if (dmxScreens[id].beDisplay)
{
dmxInputDisable (&dmxScreens[id].input);
ret = dmxInputDetach (&dmxScreens[id].input);
}
else
{
dmxScreens[id].beDisplay = dmxScreens[id].beAttachedDisplay;
ret = dmxInputDetach (&dmxScreens[id].input);
dmxScreens[id].beDisplay = NULL;
}
return ret;
}
/** Return the value of #dmxNumScreens -- the total number of backend
@ -1417,10 +1446,9 @@ dmxAttachScreen (int idx,
void *error,
const char *errorName)
{
ScreenPtr pScreen;
ScreenPtr pScreen;
DMXScreenInfo *dmxScreen;
DMXScreenInfo oldDMXScreen;
int i;
DMXScreenInfo oldDMXScreen;
/* Return failure if dynamic addition/removal of screens is disabled */
if (!dmxAddRemoveScreens) {
@ -1449,7 +1477,7 @@ dmxAttachScreen (int idx,
dmxScreen = &dmxScreens[idx];
/* Cannot attach to a screen that is already opened */
if (dmxScreen->beDisplay) {
if (dmxScreen->name && *dmxScreen->name) {
dmxLogErrorSet (dmxWarning, errorSet, error, errorName,
"Attempting to attach back-end server to screen #%d "
"but back-end server is already attached to this "
@ -1465,24 +1493,16 @@ dmxAttachScreen (int idx,
dmxScreen->scrnWin = window;
dmxScreen->virtualFb = FALSE;
/* Copy the display name to the new screen */
dmxScreen->display = strdup(attr->displayName);
if (attr->name)
dmxScreen->name = strdup(attr->name);
else
dmxScreen->name = strdup(attr->displayName);
dmxScreen->authType = dmxMemDup (authType, authTypeLen);
dmxScreen->authTypeLen = authTypeLen;
dmxScreen->authData = dmxMemDup (authData, authDataLen);
dmxScreen->authDataLen = authDataLen;
/* Open display and get all of the screen info */
if (!dmxOpenDisplay(dmxScreen)) {
if (!dmxOpenDisplay(dmxScreen,
attr->displayName,
authType,
authTypeLen,
authData,
authDataLen)) {
dmxLogErrorSet (dmxWarning, errorSet, error, errorName,
"Can't open display: %s",
dmxScreen->display);
attr->displayName);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
@ -1495,6 +1515,96 @@ dmxAttachScreen (int idx,
dmxSetErrorHandler(dmxScreen);
dmxGetScreenAttribs(dmxScreen);
if (!dmxGetVisualInfo(dmxScreen)) {
dmxLogErrorSet (dmxWarning, errorSet, error, errorName,
"No matching visuals found");
XFree(dmxScreen->beVisuals);
dmxCloseDisplay (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
return 1;
}
dmxGetColormaps(dmxScreen);
dmxGetPixmapFormats(dmxScreen);
/* Verify that the screen to be added has the same info as the
* previously added screen. */
if (!dmxCompareScreens(dmxScreen,
&oldDMXScreen,
errorSet,
error,
errorName))
{
dmxLog(dmxWarning,
"New screen data (%s) does not match previously\n",
dmxScreen->name);
dmxLog(dmxWarning,
"attached screen data\n");
dmxLog(dmxWarning,
"All data must match in order to attach to screen #%d\n",
idx);
XFree(dmxScreen->beVisuals);
XFree(dmxScreen->beDepths);
XFree(dmxScreen->bePixmapFormats);
dmxCloseDisplay (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
return 1;
}
/* Create the default font */
if (!dmxBELoadFont(pScreen, defaultFont))
{
dmxErrorSet (errorSet, error, errorName,
"Failed to load default font");
XFree(dmxScreen->beVisuals);
XFree(dmxScreen->beDepths);
XFree(dmxScreen->bePixmapFormats);
dmxCloseDisplay (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
return 1;
}
/* We used these to compare the old and new screens. They are no
* longer needed since we have a newly attached screen, so we can
* now free the old screen's resources. */
if (oldDMXScreen.beVisuals)
XFree(oldDMXScreen.beVisuals);
if (oldDMXScreen.beDepths)
XFree(oldDMXScreen.beDepths);
if (oldDMXScreen.bePixmapFormats)
XFree(oldDMXScreen.bePixmapFormats);
if (attr->name)
dmxScreen->name = strdup(attr->name);
else
dmxScreen->name = strdup(attr->displayName);
dmxScreen->beAttachedDisplay = dmxScreen->beDisplay;
dmxScreen->beDisplay = NULL;
return 0; /* Success */
}
void
dmxEnableScreen (int idx)
{
ScreenPtr pScreen;
DMXScreenInfo *dmxScreen;
int i;
pScreen = screenInfo.screens[idx];
dmxScreen = &dmxScreens[idx];
dmxLogOutput(dmxScreen, "Enable screen #%d\n", idx);
dmxScreen->beDisplay = dmxScreen->beAttachedDisplay;
#ifdef MITSHM
dmxScreen->beShm = dmxShmInit (pScreen);
if (dmxScreen->beShm)
@ -1547,56 +1657,6 @@ dmxAttachScreen (int idx,
}
if (!dmxGetVisualInfo(dmxScreen)) {
dmxLogErrorSet (dmxWarning, errorSet, error, errorName,
"No matching visuals found");
XFree(dmxScreen->beVisuals);
dmxCloseDisplay (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
return 1;
}
dmxGetColormaps(dmxScreen);
dmxGetPixmapFormats(dmxScreen);
/* Verify that the screen to be added has the same info as the
* previously added screen. */
if (!dmxCompareScreens(dmxScreen, &oldDMXScreen, errorSet, error, errorName))
{
dmxLog(dmxWarning,
"New screen data (%s) does not match previously\n",
dmxScreen->name);
dmxLog(dmxWarning,
"attached screen data\n");
dmxLog(dmxWarning,
"All data must match in order to attach to screen #%d\n",
idx);
XFree(dmxScreen->beVisuals);
XFree(dmxScreen->beDepths);
XFree(dmxScreen->bePixmapFormats);
dmxCloseDisplay (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
return 1;
}
/* Create the default font */
if (!dmxBELoadFont(pScreen, defaultFont))
{
dmxErrorSet (errorSet, error, errorName, "Failed to load default font");
XFree(dmxScreen->beVisuals);
XFree(dmxScreen->beDepths);
XFree(dmxScreen->bePixmapFormats);
dmxCloseDisplay (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
return 1;
}
/* Initialize the BE screen resources */
dmxBEScreenInit(idx, screenInfo.screens[idx]);
@ -1640,19 +1700,17 @@ dmxAttachScreen (int idx,
dmxBEMapRootWindow(idx);
/* We used these to compare the old and new screens. They are no
* longer needed since we have a newly attached screen, so we can
* now free the old screen's resources. */
XFree(oldDMXScreen.beVisuals);
XFree(oldDMXScreen.beDepths);
XFree(oldDMXScreen.bePixmapFormats);
/* TODO: should oldDMXScreen.name be freed?? */
#ifdef RANDR
RRGetInfo (screenInfo.screens[0]);
#endif
return 0; /* Success */
dmxInputEnable (&dmxScreen->input);
for (i = currentMaxClients; --i >= 0; )
if (clients[i])
FindClientResourcesByType (clients[i], RT_PASSIVEGRAB,
dmxBERestorePassiveGrab,
(pointer) &dmxScreen->input);
}
/*
@ -2006,11 +2064,65 @@ static void dmxBEDestroyWindowTree(int idx)
}
}
void
dmxDisableScreen (int idx)
{
ScreenPtr pScreen;
DMXScreenInfo *dmxScreen;
int i;
pScreen = screenInfo.screens[idx];
dmxScreen = &dmxScreens[idx];
dmxLogOutput(dmxScreen, "Disable screen #%d\n", idx);
dmxInputDisable (&dmxScreen->input);
#ifdef XV
dmxBEXvScreenFini (pScreen);
#endif
#ifdef RANDR
dmxBERRScreenFini (pScreen);
#endif
/* Save all relevant state (TODO) */
/* Free all non-window resources related to this screen */
for (i = currentMaxClients; --i >= 0; )
if (clients[i])
FindAllClientResources(clients[i], dmxBEDestroyResources,
(pointer)idx);
/* Free scratch GCs */
dmxBEDestroyScratchGCs(idx);
/* Free window resources related to this screen */
dmxBEDestroyWindowTree(idx);
/* Free default stipple */
dmxBESavePixmap(pScreen->PixmapPerDepth[0]);
dmxBEFreePixmap(pScreen->PixmapPerDepth[0]);
if (pScreen->pScratchPixmap)
dmxBEFreePixmap(pScreen->pScratchPixmap);
/* Free the remaining screen resources and close the screen */
dmxBECloseScreen(pScreen);
/* Screen is now disabled */
dmxScreen->beDisplay = NULL;
#ifdef RANDR
RRGetInfo (screenInfo.screens[0]);
#endif
}
/** Detach back-end screen. */
int dmxDetachScreen(int idx)
{
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
int i;
DMXScreenInfo *dmxScreen;
/* Return failure if dynamic addition/removal of screens is disabled */
if (!dmxAddRemoveScreens) {
@ -2028,6 +2140,8 @@ int dmxDetachScreen(int idx)
/* Cannot remove a screen that does not exist */
if (idx < 0 || idx >= dmxNumScreens) return 1;
dmxScreen = &dmxScreens[idx];
if (idx == 0) {
dmxLog(dmxWarning,
"Attempting to remove screen #%d\n",
@ -2036,7 +2150,7 @@ int dmxDetachScreen(int idx)
}
/* Cannot detach from a screen that is not opened */
if (!dmxScreen->beDisplay) {
if (!dmxScreen->beAttachedDisplay && !dmxScreen->beDisplay) {
dmxLog(dmxWarning,
"Attempting to remove screen #%d but it has not been opened\n",
idx);
@ -2045,17 +2159,18 @@ int dmxDetachScreen(int idx)
dmxLogOutput(dmxScreen, "Detaching screen #%d\n", idx);
#ifdef XV
dmxBEXvScreenFini (screenInfo.screens[idx]);
#endif
#ifdef RANDR
dmxBERRScreenFini (screenInfo.screens[idx]);
#endif
if (dmxScreen->beDisplay)
dmxDisableScreen (idx);
/* Detach input */
dmxInputDetach (&dmxScreen->input);
dmxScreen->beDisplay = dmxScreen->beAttachedDisplay;
dmxCloseDisplay (dmxScreen);
dmxScreen->beAttachedDisplay = NULL;
dmxScreen->beDisplay = NULL;
dmxScreen->scrnWidth = 1;
dmxScreen->scrnHeight = 1;
dmxScreen->rootX = 0;
@ -2067,30 +2182,6 @@ int dmxDetachScreen(int idx)
dmxScreen->beDepth = 24;
dmxScreen->beBPP = 32;
/* Save all relevant state (TODO) */
/* Free all non-window resources related to this screen */
for (i = currentMaxClients; --i >= 0; )
if (clients[i])
FindAllClientResources(clients[i], dmxBEDestroyResources,
(pointer)idx);
/* Free scratch GCs */
dmxBEDestroyScratchGCs(idx);
/* Free window resources related to this screen */
dmxBEDestroyWindowTree(idx);
/* Free default stipple */
dmxBESavePixmap(screenInfo.screens[idx]->PixmapPerDepth[0]);
dmxBEFreePixmap(screenInfo.screens[idx]->PixmapPerDepth[0]);
if (screenInfo.screens[idx]->pScratchPixmap)
dmxBEFreePixmap(screenInfo.screens[idx]->pScratchPixmap);
/* Free the remaining screen resources and close the screen */
dmxBECloseScreen(screenInfo.screens[idx]);
if (dmxScreen->name)
{
free (dmxScreen->name);
@ -2109,6 +2200,8 @@ int dmxDetachScreen(int idx)
dmxScreen->authType = NULL;
}
dmxScreen->authTypeLen = 0;
if (dmxScreen->authData)
{
free (dmxScreen->authData);

View file

@ -122,6 +122,9 @@ typedef void (*dmxErrorSetProcPtr) (void *error,
const char *format,
...);
extern void dmxEnableScreen(int idx);
extern void dmxDisableScreen(int idx);
extern int dmxAttachScreen (int idx,
DMXScreenAttributesPtr attr,
unsigned int window,

View file

@ -309,20 +309,23 @@ dmxAddScreen(const char *name,
return dmxScreen;
}
Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen)
Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen,
const char *display,
const char *authType,
int authTypeLen,
const char *authData,
int authDataLen)
{
dmxScreen->beDisplay = NULL;
if (!dmxScreen->display || !*dmxScreen->display)
if (!display || !*display)
return FALSE;
if (dmxScreen->authType && *dmxScreen->authType)
XSetAuthorization (dmxScreen->authType,
dmxScreen->authTypeLen,
dmxScreen->authData,
dmxScreen->authDataLen);
if (authType && *authType)
XSetAuthorization ((char *) authType, authTypeLen,
(char *) authData, authDataLen);
if (!(dmxScreen->beDisplay = XOpenDisplay(dmxScreen->display)))
if (!(dmxScreen->beDisplay = XOpenDisplay(display)))
return FALSE;
dmxScreen->alive = 1;
@ -606,7 +609,12 @@ static Bool dmxSetPixmapFormats(ScreenInfo *pScreenInfo,
* display properties */
static Bool dmxDisplayInit(DMXScreenInfo *dmxScreen)
{
if (!dmxOpenDisplay(dmxScreen))
if (!dmxOpenDisplay(dmxScreen,
dmxScreen->display,
dmxScreen->authType,
dmxScreen->authTypeLen,
dmxScreen->authData,
dmxScreen->authDataLen))
{
if (dmxScreen->display && *dmxScreen->display)
dmxLog(dmxWarning,

View file

@ -45,7 +45,12 @@ extern DMXScreenInfo *dmxAddScreen(const char *name,
const char *authData,
int authDataLen,
int virtualFb);
extern Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen);
extern Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen,
const char *display,
const char *authType,
int authTypeLen,
const char *authData,
int authDataLen);
extern void dmxCloseDisplay(DMXScreenInfo *dmxScreen);
extern void dmxSetErrorHandler(DMXScreenInfo *dmxScreen);
extern void dmxGetScreenAttribs(DMXScreenInfo *dmxScreen);

View file

@ -1593,12 +1593,10 @@ dmxInputRemoveDevices (DMXInputInfo *dmxInput)
}
int
dmxInputAttach (DMXInputInfo *dmxInput)
dmxInputEnable (DMXInputInfo *dmxInput)
{
int i;
dmxInputAddDevices (dmxInput);
for (i = 0; i < dmxInput->numDevs; i++)
{
dmxLogInput (dmxInput, "Activate device id %d: %s\n",
@ -1615,10 +1613,10 @@ dmxInputAttach (DMXInputInfo *dmxInput)
}
int
dmxInputDetach (DMXInputInfo *dmxInput)
dmxInputDisable (DMXInputInfo *dmxInput)
{
int i;
for (i = 0; i < dmxInput->numDevs; i++)
{
dmxLogInput (dmxInput, "Disable device id %d: %s\n",
@ -1627,6 +1625,20 @@ dmxInputDetach (DMXInputInfo *dmxInput)
DisableDevice (dmxInput->devs[i]);
}
return 0;
}
int
dmxInputAttach (DMXInputInfo *dmxInput)
{
dmxInputAddDevices (dmxInput);
return 0;
}
int
dmxInputDetach (DMXInputInfo *dmxInput)
{
ProcessInputEvents ();
dmxInputRemoveDevices (dmxInput);

View file

@ -96,6 +96,12 @@ dmxInputUngrabPointer (DMXInputInfo *dmxInput,
DeviceIntPtr pDevice,
WindowPtr pWindow);
int
dmxInputEnable (DMXInputInfo *dmxInput);
int
dmxInputDisable (DMXInputInfo *dmxInput);
int
dmxInputAttach (DMXInputInfo *dmxInput);

View file

@ -1190,19 +1190,6 @@ void dmxBECloseScreen(ScreenPtr pScreen)
xfree(dmxScreen->beDefColormaps);
dmxScreen->beDefColormaps = NULL;
#if 0
/* Do not free visuals, depths and pixmap formats here. Free them
* in dmxCloseScreen() instead -- see comment below. */
XFree(dmxScreen->beVisuals);
dmxScreen->beVisuals = NULL;
XFree(dmxScreen->beDepths);
dmxScreen->beDepths = NULL;
XFree(dmxScreen->bePixmapFormats);
dmxScreen->bePixmapFormats = NULL;
#endif
#ifdef GLXEXT
if (dmxScreen->glxVisuals) {
XFree(dmxScreen->glxVisuals);
@ -1211,10 +1198,6 @@ void dmxBECloseScreen(ScreenPtr pScreen)
}
#endif
/* Close display */
dmxCloseDisplay (dmxScreen);
dmxScreen->beDisplay = NULL;
dmxClearQueue (&dmxScreen->request);
dmxClearQueue (&dmxScreen->ignore);
}
@ -1287,7 +1270,10 @@ Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
if (dmxScreen->beDisplay) {
dmxBECloseScreen(pScreen);
#if 1
/* Close display */
dmxCloseDisplay (dmxScreen);
dmxScreen->beDisplay = NULL;
/* Free visuals, depths and pixmap formats here so that they
* won't be freed when a screen is detached, thereby allowing
* the screen to be reattached to be compared to the one
@ -1301,7 +1287,6 @@ Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
XFree(dmxScreen->bePixmapFormats);
dmxScreen->bePixmapFormats = NULL;
#endif
}
DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);