diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c index 674049933..1ea6de817 100644 --- a/hw/dmx/dmxextension.c +++ b/hw/dmx/dmxextension.c @@ -66,6 +66,7 @@ #include "inputstr.h" /* For DeviceIntRec */ #include /* For DMX_BAD_* */ #include "cursorstr.h" +#include "propertyst.h" #define dmxErrorSet(set, error, name, fmt, ...) \ if (set) (*set) (error, name, fmt, ##__VA_ARGS__) @@ -1139,8 +1140,11 @@ static void dmxBECreateWindowTree(int idx) { DMXScreenInfo *dmxScreen = &dmxScreens[idx]; WindowPtr pRoot = WindowTable[idx]; + WindowPtr pRoot0 = WindowTable[0]; dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot); WindowPtr pWin; + WindowPtr pWin0; + PropertyPtr pProp; /* Create the pixmaps associated with the root window */ if (!pRoot->borderIsPixel) { @@ -1157,6 +1161,9 @@ static void dmxBECreateWindowTree(int idx) /* Create root window first */ dmxScreen->rootWin = pWinPriv->window = dmxCreateRootWindow(pRoot); + for (pProp = wUserProps (pRoot0); pProp; pProp = pProp->next) + dmxBESetWindowProperty (pRoot, pProp); + #ifdef RENDER if (pWinPriv->hasPict) dmxCreatePictureList (pRoot); #endif @@ -1167,6 +1174,7 @@ static void dmxBECreateWindowTree(int idx) XLIB_EPILOGUE (dmxScreen); pWin = pRoot->lastChild; + pWin0 = pRoot0->lastChild; while (pWin) { pWinPriv = DMX_GET_WINDOW_PRIV(pWin); @@ -1194,18 +1202,26 @@ static void dmxBECreateWindowTree(int idx) /* Create the window */ dmxCreateAndRealizeWindow(pWin, TRUE); + for (pProp = wUserProps (pWin0); pProp; pProp = pProp->next) + dmxBESetWindowProperty (pWin, pProp); + /* Next, create the bottom-most child */ if (pWin->lastChild) { pWin = pWin->lastChild; + pWin0 = pWin0->lastChild; continue; } /* If the window has no children, move on to the next higher window */ while (!pWin->prevSib && (pWin != pRoot)) + { pWin = pWin->parent; + pWin0 = pWin0->parent; + } if (pWin->prevSib) { pWin = pWin->prevSib; + pWin0 = pWin0->prevSib; continue; } diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c index 2811a239d..575111d85 100644 --- a/hw/dmx/dmxinit.c +++ b/hw/dmx/dmxinit.c @@ -939,10 +939,8 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[]) /* Make sure there is a global width/height available */ dmxComputeWidthHeight(DMX_NO_RECOMPUTE_BOUNDING_BOX); - /* FIXME: The following is temporarily placed here. When the DMX - * extension is available, it will be move there. - */ dmxInitFonts(); + dmxInitProps(); #ifdef RENDER /* Initialize the render extension */ diff --git a/hw/dmx/dmxprop.c b/hw/dmx/dmxprop.c index dbf43e36c..5d1dc5614 100644 --- a/hw/dmx/dmxprop.c +++ b/hw/dmx/dmxprop.c @@ -61,8 +61,14 @@ #include "dmx.h" #include "dmxprop.h" +#include "dmxwindow.h" #include "dmxlog.h" +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + /** Holds the window id of all DMX windows on the backend X server. */ #define DMX_ATOMNAME "DMX_NAME" @@ -345,3 +351,233 @@ void dmxPropertyWindow(DMXScreenInfo *dmxScreen) XChangeProperty(dpy, win, atom, XA_STRING, 8, PropModeAppend, (unsigned char *)buf, strlen(buf)); } + +static int (*dmxSaveProcVector[256]) (ClientPtr); + +static int +dmxProcChangeProperty (ClientPtr client) +{ + WindowPtr pWin; + PropertyPtr pProp; + int err; + REQUEST(xChangePropertyReq); + + err = (*dmxSaveProcVector[X_ChangeProperty]) (client); + if (err != Success) + return err; + + if (dixLookupWindow (&pWin, + stuff->window, + serverClient, + DixReadAccess) != Success || + dixLookupProperty (&pProp, + pWin, + stuff->property, + serverClient, + DixReadAccess) != Success) + return Success; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) + { + PanoramiXRes *win; + int j; + + if ((win = (PanoramiXRes *) SecurityLookupIDByType (serverClient, + stuff->window, + XRT_WINDOW, + DixReadAccess))) + { + FOR_NSCREENS_FORWARD(j) { + if (dixLookupWindow (&pWin, + win->info[j].id, + serverClient, + DixReadAccess) == Success) + dmxBESetWindowProperty (pWin, pProp); + } + } + + return Success; + } +#endif + + dmxBESetWindowProperty (pWin, pProp); + + return Success; +} + +static void +dmxDeleteProperty (WindowPtr pWin, + Atom property) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWin); + + if (!dmxScreen->beDisplay) + return; + + XLIB_PROLOGUE (dmxScreen); + XDeleteProperty (dmxScreen->beDisplay, + pWinPriv->window, + XInternAtom (dmxScreen->beDisplay, + NameForAtom (property), + FALSE)); + XLIB_EPILOGUE (dmxScreen); +} + +static int +dmxProcDeleteProperty (ClientPtr client) +{ + WindowPtr pWin; + int err; + REQUEST(xDeletePropertyReq); + + err = (*dmxSaveProcVector[X_DeleteProperty]) (client); + if (err != Success) + return err; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) + { + PanoramiXRes *win; + int j; + + if ((win = (PanoramiXRes *) SecurityLookupIDByType (serverClient, + stuff->window, + XRT_WINDOW, + DixReadAccess))) + { + FOR_NSCREENS_FORWARD(j) { + if (dixLookupWindow (&pWin, + win->info[j].id, + serverClient, + DixReadAccess) == Success) + dmxDeleteProperty (pWin, stuff->property); + } + } + + return Success; + } +#endif + + if (dixLookupWindow (&pWin, + stuff->window, + serverClient, + DixReadAccess) == Success) + dmxDeleteProperty (pWin, stuff->property); + + return Success; +} + +static void +dmxRotateProperties (WindowPtr pWin, + Atom *atoms, + Atom *buf, + int nAtoms, + int nPositions) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWin); + int i; + + if (!dmxScreen->beDisplay) + return; + + XLIB_PROLOGUE (dmxScreen); + for (i = 0; i < nAtoms; i++) + buf[i] = XInternAtom (dmxScreen->beDisplay, + NameForAtom (atoms[i]), + FALSE); + + XRotateWindowProperties (dmxScreen->beDisplay, + pWinPriv->window, + buf, + nAtoms, + nPositions); + + XLIB_EPILOGUE (dmxScreen); +} + +static int +dmxProcRotateProperties (ClientPtr client) +{ + WindowPtr pWin; + int err; + Atom *buf, *atoms; + REQUEST(xRotatePropertiesReq); + + err = (*dmxSaveProcVector[X_RotateProperties]) (client); + if (err != Success) + return err; + + atoms = (Atom *) & stuff[1]; + buf = (Atom *) xalloc (stuff->nAtoms * sizeof (Atom)); + if (!buf) + return Success; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) + { + PanoramiXRes *win; + int j; + + if ((win = (PanoramiXRes *) SecurityLookupIDByType (serverClient, + stuff->window, + XRT_WINDOW, + DixReadAccess))) + { + FOR_NSCREENS_FORWARD(j) { + if (dixLookupWindow (&pWin, + win->info[j].id, + serverClient, + DixReadAccess) == Success) + dmxRotateProperties (pWin, atoms, buf, stuff->nAtoms, + stuff->nPositions); + } + } + + xfree (buf); + + return Success; + } +#endif + + if (dixLookupWindow (&pWin, + stuff->window, + serverClient, + DixReadAccess) == Success) + dmxRotateProperties (pWin, atoms, buf, stuff->nAtoms, + stuff->nPositions); + + xfree (buf); + + return Success; +} + +/** Initialize property support. In addition to the screen function call + * pointers, DMX also hooks in at the ProcVector[] level. Here the old + * ProcVector function pointers are saved and the new ProcVector + * function pointers are initialized. */ +void dmxInitProps (void) +{ + int i; + + for (i = 0; i < 256; i++) + dmxSaveProcVector[i] = ProcVector[i]; + + ProcVector[X_ChangeProperty] = dmxProcChangeProperty; + ProcVector[X_DeleteProperty] = dmxProcDeleteProperty; + ProcVector[X_RotateProperties] = dmxProcRotateProperties; +} + +/** Reset property support by restoring the original ProcVector function + * pointers. */ +void dmxResetProps (void) +{ + int i; + + for (i = 0; i < 256; i++) + ProcVector[i] = dmxSaveProcVector[i]; +} diff --git a/hw/dmx/dmxprop.h b/hw/dmx/dmxprop.h index 50135cd64..ea9a7e072 100644 --- a/hw/dmx/dmxprop.h +++ b/hw/dmx/dmxprop.h @@ -43,4 +43,6 @@ extern void *dmxPropertyIterate(DMXScreenInfo *start, void *closure), void *closure); extern int dmxPropertySameDisplay(DMXScreenInfo *dmxScreen, const char *name); +extern void dmxInitProps (void); +extern void dmxResetProps (void); #endif diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c index b191a5a38..411a1ff14 100644 --- a/hw/dmx/dmxwindow.c +++ b/hw/dmx/dmxwindow.c @@ -53,6 +53,7 @@ #endif #include "windowstr.h" +#include "propertyst.h" static void dmxDoRestackWindow(WindowPtr pWindow); static void dmxDoChangeWindowAttributes(WindowPtr pWindow, @@ -1205,3 +1206,31 @@ dmxDoUpdateWindowPixmap(WindowPtr pWindow) } } +/* TODO: translate X resource data */ +void +dmxBESetWindowProperty (WindowPtr pWindow, + PropertyPtr pProp) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWindow); + + if (!dmxScreen->beDisplay) + return; + + XLIB_PROLOGUE (dmxScreen); + XChangeProperty (dmxScreen->beDisplay, + pWinPriv->window, + XInternAtom (dmxScreen->beDisplay, + NameForAtom (pProp->propertyName), + FALSE), + XInternAtom (dmxScreen->beDisplay, + NameForAtom (pProp->type), + FALSE), + pProp->format, + PropModeReplace, + pProp->data, + pProp->size); + XLIB_EPILOGUE (dmxScreen); +} + diff --git a/hw/dmx/dmxwindow.h b/hw/dmx/dmxwindow.h index f0fb344cc..5147cf250 100644 --- a/hw/dmx/dmxwindow.h +++ b/hw/dmx/dmxwindow.h @@ -38,6 +38,7 @@ #define DMXWINDOW_H #include "windowstr.h" +#include "property.h" /** Window private area. */ typedef struct _dmxWinPriv { @@ -95,6 +96,8 @@ extern void dmxResizeRootWindow(WindowPtr pRoot, extern Bool dmxBEDestroyWindow(WindowPtr pWindow); +extern void dmxBESetWindowProperty(WindowPtr pWindow, PropertyPtr pProp); + /* Support for shape extension */ extern void dmxSetShape(WindowPtr pWindow);