1706f2543Smrg/* 2706f2543Smrg * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. 3706f2543Smrg * 4706f2543Smrg * All Rights Reserved. 5706f2543Smrg * 6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 7706f2543Smrg * a copy of this software and associated documentation files (the 8706f2543Smrg * "Software"), to deal in the Software without restriction, including 9706f2543Smrg * without limitation on the rights to use, copy, modify, merge, 10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 11706f2543Smrg * and to permit persons to whom the Software is furnished to do so, 12706f2543Smrg * subject to the following conditions: 13706f2543Smrg * 14706f2543Smrg * The above copyright notice and this permission notice (including the 15706f2543Smrg * next paragraph) shall be included in all copies or substantial 16706f2543Smrg * portions of the Software. 17706f2543Smrg * 18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21706f2543Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25706f2543Smrg * SOFTWARE. 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg/* 29706f2543Smrg * Authors: 30706f2543Smrg * Kevin E. Martin <kem@redhat.com> 31706f2543Smrg * 32706f2543Smrg */ 33706f2543Smrg 34706f2543Smrg/** \file 35706f2543Smrg * This file provides support for window-related functions. */ 36706f2543Smrg 37706f2543Smrg#ifdef HAVE_DMX_CONFIG_H 38706f2543Smrg#include <dmx-config.h> 39706f2543Smrg#endif 40706f2543Smrg 41706f2543Smrg#include "dmx.h" 42706f2543Smrg#include "dmxsync.h" 43706f2543Smrg#include "dmxwindow.h" 44706f2543Smrg#include "dmxpixmap.h" 45706f2543Smrg#include "dmxcmap.h" 46706f2543Smrg#include "dmxvisual.h" 47706f2543Smrg#include "dmxinput.h" 48706f2543Smrg#include "dmxextension.h" 49706f2543Smrg#include "dmxpict.h" 50706f2543Smrg 51706f2543Smrg#include "windowstr.h" 52706f2543Smrg 53706f2543Smrgstatic void dmxDoRestackWindow(WindowPtr pWindow); 54706f2543Smrgstatic void dmxDoChangeWindowAttributes(WindowPtr pWindow, 55706f2543Smrg unsigned long *mask, 56706f2543Smrg XSetWindowAttributes *attribs); 57706f2543Smrg 58706f2543Smrgstatic void dmxDoSetShape(WindowPtr pWindow); 59706f2543Smrg 60706f2543Smrg/** Initialize the private area for the window functions. */ 61706f2543SmrgBool dmxInitWindow(ScreenPtr pScreen) 62706f2543Smrg{ 63706f2543Smrg if (!dixRegisterPrivateKey(&dmxWinPrivateKeyRec, PRIVATE_WINDOW, sizeof(dmxWinPrivRec))) 64706f2543Smrg return FALSE; 65706f2543Smrg 66706f2543Smrg return TRUE; 67706f2543Smrg} 68706f2543Smrg 69706f2543Smrg 70706f2543SmrgWindow dmxCreateRootWindow(WindowPtr pWindow) 71706f2543Smrg{ 72706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 73706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 74706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 75706f2543Smrg Window parent; 76706f2543Smrg Visual *visual; 77706f2543Smrg unsigned long mask; 78706f2543Smrg XSetWindowAttributes attribs; 79706f2543Smrg ColormapPtr pCmap; 80706f2543Smrg dmxColormapPrivPtr pCmapPriv; 81706f2543Smrg 82706f2543Smrg /* Create root window */ 83706f2543Smrg 84706f2543Smrg parent = dmxScreen->scrnWin; /* This is our "Screen" window */ 85706f2543Smrg visual = dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual; 86706f2543Smrg 87706f2543Smrg dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow), 88706f2543Smrg RT_COLORMAP, NullClient, DixUnknownAccess); 89706f2543Smrg pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap); 90706f2543Smrg 91706f2543Smrg mask = CWEventMask | CWBackingStore | CWColormap | CWBorderPixel; 92706f2543Smrg attribs.event_mask = ExposureMask; 93706f2543Smrg attribs.backing_store = NotUseful; 94706f2543Smrg attribs.colormap = pCmapPriv->cmap; 95706f2543Smrg attribs.border_pixel = 0; 96706f2543Smrg 97706f2543Smrg /* Incorporate new attributes, if needed */ 98706f2543Smrg if (pWinPriv->attribMask) { 99706f2543Smrg dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs); 100706f2543Smrg mask |= pWinPriv->attribMask; 101706f2543Smrg } 102706f2543Smrg 103706f2543Smrg return XCreateWindow(dmxScreen->beDisplay, 104706f2543Smrg parent, 105706f2543Smrg pWindow->origin.x - wBorderWidth(pWindow), 106706f2543Smrg pWindow->origin.y - wBorderWidth(pWindow), 107706f2543Smrg pWindow->drawable.width, 108706f2543Smrg pWindow->drawable.height, 109706f2543Smrg pWindow->borderWidth, 110706f2543Smrg pWindow->drawable.depth, 111706f2543Smrg pWindow->drawable.class, 112706f2543Smrg visual, 113706f2543Smrg mask, 114706f2543Smrg &attribs); 115706f2543Smrg} 116706f2543Smrg 117706f2543Smrg/** Change the location and size of the "screen" window. Called from 118706f2543Smrg * #dmxConfigureScreenWindow(). */ 119706f2543Smrgvoid dmxResizeScreenWindow(ScreenPtr pScreen, 120706f2543Smrg int x, int y, int w, int h) 121706f2543Smrg{ 122706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 123706f2543Smrg unsigned int m; 124706f2543Smrg XWindowChanges c; 125706f2543Smrg 126706f2543Smrg if (!dmxScreen->beDisplay) 127706f2543Smrg return; 128706f2543Smrg 129706f2543Smrg /* Handle resizing on back-end server */ 130706f2543Smrg m = CWX | CWY | CWWidth | CWHeight; 131706f2543Smrg c.x = x; 132706f2543Smrg c.y = y; 133706f2543Smrg c.width = w; 134706f2543Smrg c.height = h; 135706f2543Smrg 136706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, dmxScreen->scrnWin, m, &c); 137706f2543Smrg dmxSync(dmxScreen, False); 138706f2543Smrg} 139706f2543Smrg 140706f2543Smrg/** Change the location and size of the "root" window. Called from 141706f2543Smrg * #dmxConfigureRootWindow. */ 142706f2543Smrgvoid dmxResizeRootWindow(WindowPtr pRoot, 143706f2543Smrg int x, int y, int w, int h) 144706f2543Smrg{ 145706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pRoot->drawable.pScreen->myNum]; 146706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot); 147706f2543Smrg unsigned int m; 148706f2543Smrg XWindowChanges c; 149706f2543Smrg 150706f2543Smrg /* Handle resizing on back-end server */ 151706f2543Smrg if (dmxScreen->beDisplay) { 152706f2543Smrg m = CWX | CWY | CWWidth | CWHeight; 153706f2543Smrg c.x = x; 154706f2543Smrg c.y = y; 155706f2543Smrg c.width = (w > 0) ? w : 1; 156706f2543Smrg c.height = (h > 0) ? h : 1; 157706f2543Smrg 158706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 159706f2543Smrg } 160706f2543Smrg 161706f2543Smrg if (w == 0 || h == 0) { 162706f2543Smrg if (pWinPriv->mapped) { 163706f2543Smrg if (dmxScreen->beDisplay) 164706f2543Smrg XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window); 165706f2543Smrg pWinPriv->mapped = FALSE; 166706f2543Smrg } 167706f2543Smrg } else if (!pWinPriv->mapped) { 168706f2543Smrg if (dmxScreen->beDisplay) 169706f2543Smrg XMapWindow(dmxScreen->beDisplay, pWinPriv->window); 170706f2543Smrg pWinPriv->mapped = TRUE; 171706f2543Smrg } 172706f2543Smrg 173706f2543Smrg if (dmxScreen->beDisplay) 174706f2543Smrg dmxSync(dmxScreen, False); 175706f2543Smrg} 176706f2543Smrg 177706f2543Smrgvoid dmxGetDefaultWindowAttributes(WindowPtr pWindow, 178706f2543Smrg Colormap *cmap, 179706f2543Smrg Visual **visual) 180706f2543Smrg{ 181706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 182706f2543Smrg 183706f2543Smrg if (pWindow->drawable.class != InputOnly && 184706f2543Smrg pWindow->optional && 185706f2543Smrg pWindow->optional->visual != wVisual(pWindow->parent)) { 186706f2543Smrg 187706f2543Smrg /* Find the matching visual */ 188706f2543Smrg *visual = dmxLookupVisualFromID(pScreen, wVisual(pWindow)); 189706f2543Smrg 190706f2543Smrg /* Handle optional colormaps */ 191706f2543Smrg if (pWindow->optional->colormap) { 192706f2543Smrg ColormapPtr pCmap; 193706f2543Smrg dmxColormapPrivPtr pCmapPriv; 194706f2543Smrg 195706f2543Smrg dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow), 196706f2543Smrg RT_COLORMAP, NullClient, DixUnknownAccess); 197706f2543Smrg pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap); 198706f2543Smrg *cmap = pCmapPriv->cmap; 199706f2543Smrg } else { 200706f2543Smrg *cmap = dmxColormapFromDefaultVisual(pScreen, *visual); 201706f2543Smrg } 202706f2543Smrg } else { 203706f2543Smrg *visual = CopyFromParent; 204706f2543Smrg *cmap = (Colormap)0; 205706f2543Smrg } 206706f2543Smrg} 207706f2543Smrg 208706f2543Smrgstatic Window dmxCreateNonRootWindow(WindowPtr pWindow) 209706f2543Smrg{ 210706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 211706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 212706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 213706f2543Smrg Window parent; 214706f2543Smrg unsigned long mask = 0L; 215706f2543Smrg XSetWindowAttributes attribs; 216706f2543Smrg dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent); 217706f2543Smrg 218706f2543Smrg /* Create window on back-end server */ 219706f2543Smrg 220706f2543Smrg parent = pParentPriv->window; 221706f2543Smrg 222706f2543Smrg /* The parent won't exist if this call to CreateNonRootWindow came 223706f2543Smrg from ReparentWindow and the grandparent window has not yet been 224706f2543Smrg created */ 225706f2543Smrg if (!parent) { 226706f2543Smrg dmxCreateAndRealizeWindow(pWindow->parent, FALSE); 227706f2543Smrg parent = pParentPriv->window; 228706f2543Smrg } 229706f2543Smrg 230706f2543Smrg /* Incorporate new attributes, if needed */ 231706f2543Smrg if (pWinPriv->attribMask) { 232706f2543Smrg dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs); 233706f2543Smrg mask |= pWinPriv->attribMask; 234706f2543Smrg } 235706f2543Smrg 236706f2543Smrg /* Add in default attributes */ 237706f2543Smrg if (pWindow->drawable.class != InputOnly) { 238706f2543Smrg mask |= CWBackingStore; 239706f2543Smrg attribs.backing_store = NotUseful; 240706f2543Smrg 241706f2543Smrg if (!(mask & CWColormap) && pWinPriv->cmap) { 242706f2543Smrg mask |= CWColormap; 243706f2543Smrg attribs.colormap = pWinPriv->cmap; 244706f2543Smrg if (!(mask & CWBorderPixel)) { 245706f2543Smrg mask |= CWBorderPixel; 246706f2543Smrg attribs.border_pixel = 0; 247706f2543Smrg } 248706f2543Smrg } 249706f2543Smrg } 250706f2543Smrg 251706f2543Smrg /* Handle case where subwindows are being mapped, but created out of 252706f2543Smrg order -- if current window has a previous sibling, then it cannot 253706f2543Smrg be created on top of the stack, so we must restack the windows */ 254706f2543Smrg pWinPriv->restacked = (pWindow->prevSib != NullWindow); 255706f2543Smrg 256706f2543Smrg return XCreateWindow(dmxScreen->beDisplay, 257706f2543Smrg parent, 258706f2543Smrg pWindow->origin.x - wBorderWidth(pWindow), 259706f2543Smrg pWindow->origin.y - wBorderWidth(pWindow), 260706f2543Smrg pWindow->drawable.width, 261706f2543Smrg pWindow->drawable.height, 262706f2543Smrg pWindow->borderWidth, 263706f2543Smrg pWindow->drawable.depth, 264706f2543Smrg pWindow->drawable.class, 265706f2543Smrg pWinPriv->visual, 266706f2543Smrg mask, 267706f2543Smrg &attribs); 268706f2543Smrg} 269706f2543Smrg 270706f2543Smrg/** This function handles lazy window creation and realization. Window 271706f2543Smrg * creation is handled by #dmxCreateNonRootWindow(). It also handles 272706f2543Smrg * any stacking changes that have occured since the window was 273706f2543Smrg * originally created by calling #dmxDoRestackWindow(). If the window 274706f2543Smrg * is shaped, the shape is set on the back-end server by calling 275706f2543Smrg * #dmxDoSetShape(), and if the window has pictures (from RENDER) 276706f2543Smrg * associated with it, those pictures are created on the back-end 277706f2543Smrg * server by calling #dmxCreatePictureList(). If \a doSync is TRUE, 278706f2543Smrg * then #dmxSync() is called. */ 279706f2543Smrgvoid dmxCreateAndRealizeWindow(WindowPtr pWindow, Bool doSync) 280706f2543Smrg{ 281706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 282706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 283706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 284706f2543Smrg 285706f2543Smrg if (!dmxScreen->beDisplay) return; 286706f2543Smrg 287706f2543Smrg pWinPriv->window = dmxCreateNonRootWindow(pWindow); 288706f2543Smrg if (pWinPriv->restacked) dmxDoRestackWindow(pWindow); 289706f2543Smrg if (pWinPriv->isShaped) dmxDoSetShape(pWindow); 290706f2543Smrg if (pWinPriv->hasPict) dmxCreatePictureList(pWindow); 291706f2543Smrg if (pWinPriv->mapped) XMapWindow(dmxScreen->beDisplay, 292706f2543Smrg pWinPriv->window); 293706f2543Smrg if (doSync) dmxSync(dmxScreen, False); 294706f2543Smrg} 295706f2543Smrg 296706f2543Smrg/** Create \a pWindow on the back-end server. If the lazy window 297706f2543Smrg * creation optimization is enabled, then the actual creation and 298706f2543Smrg * realization of the window is handled by 299706f2543Smrg * #dmxCreateAndRealizeWindow(). */ 300706f2543SmrgBool dmxCreateWindow(WindowPtr pWindow) 301706f2543Smrg{ 302706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 303706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 304706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 305706f2543Smrg Bool ret = TRUE; 306706f2543Smrg 307706f2543Smrg DMX_UNWRAP(CreateWindow, dmxScreen, pScreen); 308706f2543Smrg#if 0 309706f2543Smrg if (pScreen->CreateWindow) 310706f2543Smrg ret = pScreen->CreateWindow(pWindow); 311706f2543Smrg#endif 312706f2543Smrg 313706f2543Smrg /* Set up the defaults */ 314706f2543Smrg pWinPriv->window = (Window)0; 315706f2543Smrg pWinPriv->offscreen = TRUE; 316706f2543Smrg pWinPriv->mapped = FALSE; 317706f2543Smrg pWinPriv->restacked = FALSE; 318706f2543Smrg pWinPriv->attribMask = 0; 319706f2543Smrg pWinPriv->isShaped = FALSE; 320706f2543Smrg pWinPriv->hasPict = FALSE; 321706f2543Smrg#ifdef GLXEXT 322706f2543Smrg pWinPriv->swapGroup = NULL; 323706f2543Smrg pWinPriv->barrier = 0; 324706f2543Smrg#endif 325706f2543Smrg 326706f2543Smrg if (dmxScreen->beDisplay) { 327706f2543Smrg /* Only create the root window at this stage -- non-root windows are 328706f2543Smrg created when they are mapped and are on-screen */ 329706f2543Smrg if (!pWindow->parent) { 330706f2543Smrg dmxScreen->rootWin = pWinPriv->window 331706f2543Smrg = dmxCreateRootWindow(pWindow); 332706f2543Smrg if (dmxScreen->scrnX != dmxScreen->rootX 333706f2543Smrg || dmxScreen->scrnY != dmxScreen->rootY 334706f2543Smrg || dmxScreen->scrnWidth != dmxScreen->rootWidth 335706f2543Smrg || dmxScreen->scrnHeight != dmxScreen->rootHeight) { 336706f2543Smrg dmxResizeRootWindow(pWindow, 337706f2543Smrg dmxScreen->rootX, 338706f2543Smrg dmxScreen->rootY, 339706f2543Smrg dmxScreen->rootWidth, 340706f2543Smrg dmxScreen->rootHeight); 341706f2543Smrg dmxUpdateScreenResources(screenInfo.screens[dmxScreen->index], 342706f2543Smrg dmxScreen->rootX, 343706f2543Smrg dmxScreen->rootY, 344706f2543Smrg dmxScreen->rootWidth, 345706f2543Smrg dmxScreen->rootHeight); 346706f2543Smrg pWindow->origin.x = dmxScreen->rootX; 347706f2543Smrg pWindow->origin.y = dmxScreen->rootY; 348706f2543Smrg } 349706f2543Smrg } else { 350706f2543Smrg dmxGetDefaultWindowAttributes(pWindow, 351706f2543Smrg &pWinPriv->cmap, 352706f2543Smrg &pWinPriv->visual); 353706f2543Smrg 354706f2543Smrg if (dmxLazyWindowCreation) { 355706f2543Smrg /* Save parent's visual for use later */ 356706f2543Smrg if (pWinPriv->visual == CopyFromParent) 357706f2543Smrg pWinPriv->visual = 358706f2543Smrg dmxLookupVisualFromID(pScreen, 359706f2543Smrg wVisual(pWindow->parent)); 360706f2543Smrg } else { 361706f2543Smrg pWinPriv->window = dmxCreateNonRootWindow(pWindow); 362706f2543Smrg } 363706f2543Smrg } 364706f2543Smrg 365706f2543Smrg dmxSync(dmxScreen, False); 366706f2543Smrg } 367706f2543Smrg 368706f2543Smrg DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen); 369706f2543Smrg 370706f2543Smrg return ret; 371706f2543Smrg} 372706f2543Smrg 373706f2543Smrg/** Destroy \a pWindow on the back-end server. */ 374706f2543SmrgBool dmxBEDestroyWindow(WindowPtr pWindow) 375706f2543Smrg{ 376706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 377706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 378706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 379706f2543Smrg 380706f2543Smrg if (pWinPriv->window) { 381706f2543Smrg XDestroyWindow(dmxScreen->beDisplay, pWinPriv->window); 382706f2543Smrg pWinPriv->window = (Window)0; 383706f2543Smrg return TRUE; 384706f2543Smrg } 385706f2543Smrg 386706f2543Smrg return FALSE; 387706f2543Smrg} 388706f2543Smrg 389706f2543Smrg/** Destroy \a pWindow on the back-end server. If any RENDER pictures 390706f2543Smrg were created, destroy them as well. */ 391706f2543SmrgBool dmxDestroyWindow(WindowPtr pWindow) 392706f2543Smrg{ 393706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 394706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 395706f2543Smrg Bool ret = TRUE; 396706f2543Smrg Bool needSync = FALSE; 397706f2543Smrg#ifdef GLXEXT 398706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 399706f2543Smrg#endif 400706f2543Smrg 401706f2543Smrg DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen); 402706f2543Smrg 403706f2543Smrg /* Destroy any picture list associated with this window */ 404706f2543Smrg needSync |= dmxDestroyPictureList(pWindow); 405706f2543Smrg 406706f2543Smrg /* Destroy window on back-end server */ 407706f2543Smrg needSync |= dmxBEDestroyWindow(pWindow); 408706f2543Smrg if (needSync) dmxSync(dmxScreen, FALSE); 409706f2543Smrg 410706f2543Smrg#ifdef GLXEXT 411706f2543Smrg if (pWinPriv->swapGroup && pWinPriv->windowDestroyed) 412706f2543Smrg pWinPriv->windowDestroyed(pWindow); 413706f2543Smrg#endif 414706f2543Smrg 415706f2543Smrg if (pScreen->DestroyWindow) 416706f2543Smrg ret = pScreen->DestroyWindow(pWindow); 417706f2543Smrg 418706f2543Smrg DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen); 419706f2543Smrg 420706f2543Smrg return ret; 421706f2543Smrg} 422706f2543Smrg 423706f2543Smrg/** Change the position of \a pWindow to be \a x, \a y. */ 424706f2543SmrgBool dmxPositionWindow(WindowPtr pWindow, int x, int y) 425706f2543Smrg{ 426706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 427706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 428706f2543Smrg Bool ret = TRUE; 429706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 430706f2543Smrg unsigned int m; 431706f2543Smrg XWindowChanges c; 432706f2543Smrg 433706f2543Smrg DMX_UNWRAP(PositionWindow, dmxScreen, pScreen); 434706f2543Smrg#if 0 435706f2543Smrg if (pScreen->PositionWindow) 436706f2543Smrg ret = pScreen->PositionWindow(pWindow, x, y); 437706f2543Smrg#endif 438706f2543Smrg 439706f2543Smrg /* Determine if the window is completely off the visible portion of 440706f2543Smrg the screen */ 441706f2543Smrg pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); 442706f2543Smrg 443706f2543Smrg /* If the window is now on-screen and it is mapped and it has not 444706f2543Smrg been created yet, create it and map it */ 445706f2543Smrg if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) { 446706f2543Smrg dmxCreateAndRealizeWindow(pWindow, TRUE); 447706f2543Smrg } else if (pWinPriv->window) { 448706f2543Smrg /* Position window on back-end server */ 449706f2543Smrg m = CWX | CWY | CWWidth | CWHeight; 450706f2543Smrg c.x = pWindow->origin.x - wBorderWidth(pWindow); 451706f2543Smrg c.y = pWindow->origin.y - wBorderWidth(pWindow); 452706f2543Smrg c.width = pWindow->drawable.width; 453706f2543Smrg c.height = pWindow->drawable.height; 454706f2543Smrg if (pWindow->drawable.class != InputOnly) { 455706f2543Smrg m |= CWBorderWidth; 456706f2543Smrg c.border_width = pWindow->borderWidth; 457706f2543Smrg } 458706f2543Smrg 459706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 460706f2543Smrg dmxSync(dmxScreen, False); 461706f2543Smrg } 462706f2543Smrg 463706f2543Smrg DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen); 464706f2543Smrg 465706f2543Smrg return ret; 466706f2543Smrg} 467706f2543Smrg 468706f2543Smrgstatic void dmxDoChangeWindowAttributes(WindowPtr pWindow, 469706f2543Smrg unsigned long *mask, 470706f2543Smrg XSetWindowAttributes *attribs) 471706f2543Smrg{ 472706f2543Smrg dmxPixPrivPtr pPixPriv; 473706f2543Smrg 474706f2543Smrg if (*mask & CWBackPixmap) { 475706f2543Smrg switch (pWindow->backgroundState) { 476706f2543Smrg case None: 477706f2543Smrg attribs->background_pixmap = None; 478706f2543Smrg break; 479706f2543Smrg 480706f2543Smrg case ParentRelative: 481706f2543Smrg attribs->background_pixmap = ParentRelative; 482706f2543Smrg break; 483706f2543Smrg 484706f2543Smrg case BackgroundPixmap: 485706f2543Smrg pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->background.pixmap); 486706f2543Smrg attribs->background_pixmap = pPixPriv->pixmap; 487706f2543Smrg break; 488706f2543Smrg 489706f2543Smrg case BackgroundPixel: 490706f2543Smrg *mask &= ~CWBackPixmap; 491706f2543Smrg break; 492706f2543Smrg } 493706f2543Smrg } 494706f2543Smrg 495706f2543Smrg if (*mask & CWBackPixel) { 496706f2543Smrg if (pWindow->backgroundState == BackgroundPixel) 497706f2543Smrg attribs->background_pixel = pWindow->background.pixel; 498706f2543Smrg else 499706f2543Smrg *mask &= ~CWBackPixel; 500706f2543Smrg } 501706f2543Smrg 502706f2543Smrg if (*mask & CWBorderPixmap) { 503706f2543Smrg if (pWindow->borderIsPixel) 504706f2543Smrg *mask &= ~CWBorderPixmap; 505706f2543Smrg else { 506706f2543Smrg pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->border.pixmap); 507706f2543Smrg attribs->border_pixmap = pPixPriv->pixmap; 508706f2543Smrg } 509706f2543Smrg } 510706f2543Smrg 511706f2543Smrg if (*mask & CWBorderPixel) { 512706f2543Smrg if (pWindow->borderIsPixel) 513706f2543Smrg attribs->border_pixel = pWindow->border.pixel; 514706f2543Smrg else 515706f2543Smrg *mask &= ~CWBorderPixel; 516706f2543Smrg } 517706f2543Smrg 518706f2543Smrg if (*mask & CWBitGravity) 519706f2543Smrg attribs->bit_gravity = pWindow->bitGravity; 520706f2543Smrg 521706f2543Smrg if (*mask & CWWinGravity) 522706f2543Smrg *mask &= ~CWWinGravity; /* Handled by dix */ 523706f2543Smrg 524706f2543Smrg if (*mask & CWBackingStore) 525706f2543Smrg *mask &= ~CWBackingStore; /* Backing store not supported */ 526706f2543Smrg 527706f2543Smrg if (*mask & CWBackingPlanes) 528706f2543Smrg *mask &= ~CWBackingPlanes; /* Backing store not supported */ 529706f2543Smrg 530706f2543Smrg if (*mask & CWBackingPixel) 531706f2543Smrg *mask &= ~CWBackingPixel; /* Backing store not supported */ 532706f2543Smrg 533706f2543Smrg if (*mask & CWOverrideRedirect) 534706f2543Smrg attribs->override_redirect = pWindow->overrideRedirect; 535706f2543Smrg 536706f2543Smrg if (*mask & CWSaveUnder) 537706f2543Smrg *mask &= ~CWSaveUnder; /* Save unders not supported */ 538706f2543Smrg 539706f2543Smrg if (*mask & CWEventMask) 540706f2543Smrg *mask &= ~CWEventMask; /* Events are handled by dix */ 541706f2543Smrg 542706f2543Smrg if (*mask & CWDontPropagate) 543706f2543Smrg *mask &= ~CWDontPropagate; /* Events are handled by dix */ 544706f2543Smrg 545706f2543Smrg if (*mask & CWColormap) { 546706f2543Smrg ColormapPtr pCmap; 547706f2543Smrg dmxColormapPrivPtr pCmapPriv; 548706f2543Smrg 549706f2543Smrg dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow), 550706f2543Smrg RT_COLORMAP, NullClient, DixUnknownAccess); 551706f2543Smrg pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap); 552706f2543Smrg attribs->colormap = pCmapPriv->cmap; 553706f2543Smrg } 554706f2543Smrg 555706f2543Smrg if (*mask & CWCursor) 556706f2543Smrg *mask &= ~CWCursor; /* Handled by the cursor code */ 557706f2543Smrg} 558706f2543Smrg 559706f2543Smrg/** Change the window attributes of \a pWindow. */ 560706f2543SmrgBool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask) 561706f2543Smrg{ 562706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 563706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 564706f2543Smrg Bool ret = TRUE; 565706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 566706f2543Smrg XSetWindowAttributes attribs; 567706f2543Smrg 568706f2543Smrg DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen); 569706f2543Smrg#if 0 570706f2543Smrg if (pScreen->ChangeWindowAttributes) 571706f2543Smrg ret = pScreen->ChangeWindowAttributes(pWindow, mask); 572706f2543Smrg#endif 573706f2543Smrg 574706f2543Smrg /* Change window attribs on back-end server */ 575706f2543Smrg dmxDoChangeWindowAttributes(pWindow, &mask, &attribs); 576706f2543Smrg 577706f2543Smrg /* Save mask for lazy window creation optimization */ 578706f2543Smrg pWinPriv->attribMask |= mask; 579706f2543Smrg 580706f2543Smrg if (mask && pWinPriv->window) { 581706f2543Smrg XChangeWindowAttributes(dmxScreen->beDisplay, pWinPriv->window, 582706f2543Smrg mask, &attribs); 583706f2543Smrg dmxSync(dmxScreen, False); 584706f2543Smrg } 585706f2543Smrg 586706f2543Smrg DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen, 587706f2543Smrg pScreen); 588706f2543Smrg 589706f2543Smrg return ret; 590706f2543Smrg} 591706f2543Smrg 592706f2543Smrg/** Realize \a pWindow on the back-end server. If the lazy window 593706f2543Smrg * creation optimization is enabled, the window is only realized when 594706f2543Smrg * it at least partially overlaps the screen. */ 595706f2543SmrgBool dmxRealizeWindow(WindowPtr pWindow) 596706f2543Smrg{ 597706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 598706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 599706f2543Smrg Bool ret = TRUE; 600706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 601706f2543Smrg 602706f2543Smrg DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen); 603706f2543Smrg#if 0 604706f2543Smrg if (pScreen->RealizeWindow) 605706f2543Smrg ret = pScreen->RealizeWindow(pWindow); 606706f2543Smrg#endif 607706f2543Smrg 608706f2543Smrg /* Determine if the window is completely off the visible portion of 609706f2543Smrg the screen */ 610706f2543Smrg pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); 611706f2543Smrg 612706f2543Smrg /* If the window hasn't been created and it's not offscreen, then 613706f2543Smrg create it */ 614706f2543Smrg if (!pWinPriv->window && !pWinPriv->offscreen) { 615706f2543Smrg dmxCreateAndRealizeWindow(pWindow, FALSE); 616706f2543Smrg } 617706f2543Smrg 618706f2543Smrg if (pWinPriv->window) { 619706f2543Smrg /* Realize window on back-end server */ 620706f2543Smrg XMapWindow(dmxScreen->beDisplay, pWinPriv->window); 621706f2543Smrg dmxSync(dmxScreen, False); 622706f2543Smrg } 623706f2543Smrg 624706f2543Smrg /* Let the other functions know that the window is now mapped */ 625706f2543Smrg pWinPriv->mapped = TRUE; 626706f2543Smrg 627706f2543Smrg DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen); 628706f2543Smrg 629706f2543Smrg dmxUpdateWindowInfo(DMX_UPDATE_REALIZE, pWindow); 630706f2543Smrg return ret; 631706f2543Smrg} 632706f2543Smrg 633706f2543Smrg/** Unrealize \a pWindow on the back-end server. */ 634706f2543SmrgBool dmxUnrealizeWindow(WindowPtr pWindow) 635706f2543Smrg{ 636706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 637706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 638706f2543Smrg Bool ret = TRUE; 639706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 640706f2543Smrg 641706f2543Smrg DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen); 642706f2543Smrg#if 0 643706f2543Smrg if (pScreen->UnrealizeWindow) 644706f2543Smrg ret = pScreen->UnrealizeWindow(pWindow); 645706f2543Smrg#endif 646706f2543Smrg 647706f2543Smrg if (pWinPriv->window) { 648706f2543Smrg /* Unrealize window on back-end server */ 649706f2543Smrg XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window); 650706f2543Smrg dmxSync(dmxScreen, False); 651706f2543Smrg } 652706f2543Smrg 653706f2543Smrg /* When unrealized (i.e., unmapped), the window is always considered 654706f2543Smrg off of the visible portion of the screen */ 655706f2543Smrg pWinPriv->offscreen = TRUE; 656706f2543Smrg pWinPriv->mapped = FALSE; 657706f2543Smrg 658706f2543Smrg#ifdef GLXEXT 659706f2543Smrg if (pWinPriv->swapGroup && pWinPriv->windowUnmapped) 660706f2543Smrg pWinPriv->windowUnmapped(pWindow); 661706f2543Smrg#endif 662706f2543Smrg 663706f2543Smrg DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen); 664706f2543Smrg 665706f2543Smrg dmxUpdateWindowInfo(DMX_UPDATE_UNREALIZE, pWindow); 666706f2543Smrg return ret; 667706f2543Smrg} 668706f2543Smrg 669706f2543Smrgstatic void dmxDoRestackWindow(WindowPtr pWindow) 670706f2543Smrg{ 671706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 672706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 673706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 674706f2543Smrg WindowPtr pNextSib = pWindow->nextSib; 675706f2543Smrg unsigned int m; 676706f2543Smrg XWindowChanges c; 677706f2543Smrg 678706f2543Smrg if (pNextSib == NullWindow) { 679706f2543Smrg /* Window is at the bottom of the stack */ 680706f2543Smrg m = CWStackMode; 681706f2543Smrg c.sibling = (Window)0; 682706f2543Smrg c.stack_mode = Below; 683706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 684706f2543Smrg } else { 685706f2543Smrg /* Window is not at the bottom of the stack */ 686706f2543Smrg dmxWinPrivPtr pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib); 687706f2543Smrg 688706f2543Smrg /* Handle case where siblings have not yet been created due to 689706f2543Smrg lazy window creation optimization by first finding the next 690706f2543Smrg sibling in the sibling list that has been created (if any) 691706f2543Smrg and then putting the current window just above that sibling, 692706f2543Smrg and if no next siblings have been created yet, then put it at 693706f2543Smrg the bottom of the stack (since it might have a previous 694706f2543Smrg sibling that should be above it). */ 695706f2543Smrg while (!pNextSibPriv->window) { 696706f2543Smrg pNextSib = pNextSib->nextSib; 697706f2543Smrg if (pNextSib == NullWindow) { 698706f2543Smrg /* Window is at the bottom of the stack */ 699706f2543Smrg m = CWStackMode; 700706f2543Smrg c.sibling = (Window)0; 701706f2543Smrg c.stack_mode = Below; 702706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 703706f2543Smrg return; 704706f2543Smrg } 705706f2543Smrg pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib); 706706f2543Smrg } 707706f2543Smrg 708706f2543Smrg m = CWStackMode | CWSibling; 709706f2543Smrg c.sibling = pNextSibPriv->window; 710706f2543Smrg c.stack_mode = Above; 711706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 712706f2543Smrg } 713706f2543Smrg} 714706f2543Smrg 715706f2543Smrg/** Handle window restacking. The actual restacking occurs in 716706f2543Smrg * #dmxDoRestackWindow(). */ 717706f2543Smrgvoid dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib) 718706f2543Smrg{ 719706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 720706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 721706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 722706f2543Smrg 723706f2543Smrg DMX_UNWRAP(RestackWindow, dmxScreen, pScreen); 724706f2543Smrg#if 0 725706f2543Smrg if (pScreen->RestackWindow) 726706f2543Smrg pScreen->RestackWindow(pWindow, pOldNextSib); 727706f2543Smrg#endif 728706f2543Smrg 729706f2543Smrg if (pOldNextSib != pWindow->nextSib) { 730706f2543Smrg /* Track restacking for lazy window creation optimization */ 731706f2543Smrg pWinPriv->restacked = TRUE; 732706f2543Smrg 733706f2543Smrg /* Restack window on back-end server */ 734706f2543Smrg if (pWinPriv->window) { 735706f2543Smrg dmxDoRestackWindow(pWindow); 736706f2543Smrg dmxSync(dmxScreen, False); 737706f2543Smrg } 738706f2543Smrg } 739706f2543Smrg 740706f2543Smrg DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen); 741706f2543Smrg dmxUpdateWindowInfo(DMX_UPDATE_RESTACK, pWindow); 742706f2543Smrg} 743706f2543Smrg 744706f2543Smrgstatic Bool dmxWindowExposurePredicate(Display *dpy, XEvent *ev, XPointer ptr) 745706f2543Smrg{ 746706f2543Smrg return (ev->type == Expose && ev->xexpose.window == *(Window *)ptr); 747706f2543Smrg} 748706f2543Smrg 749706f2543Smrg/** Handle exposures on \a pWindow. Since window exposures are handled 750706f2543Smrg * in DMX, the events that are generated by the back-end server are 751706f2543Smrg * redundant, so we eat them here. */ 752706f2543Smrgvoid dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn, 753706f2543Smrg RegionPtr other_exposed) 754706f2543Smrg{ 755706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 756706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 757706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 758706f2543Smrg XEvent ev; 759706f2543Smrg 760706f2543Smrg DMX_UNWRAP(WindowExposures, dmxScreen, pScreen); 761706f2543Smrg 762706f2543Smrg dmxSync(dmxScreen, False); 763706f2543Smrg 764706f2543Smrg if (pWinPriv->window) { 765706f2543Smrg while (XCheckIfEvent(dmxScreen->beDisplay, &ev, 766706f2543Smrg dmxWindowExposurePredicate, 767706f2543Smrg (XPointer)&pWinPriv->window)) { 768706f2543Smrg /* Handle expose events -- this should not be necessary 769706f2543Smrg since the base window in which the root window was 770706f2543Smrg created is guaranteed to be on top (override_redirect), 771706f2543Smrg so we should just swallow these events. If for some 772706f2543Smrg reason the window is not on top, then we'd need to 773706f2543Smrg collect these events and send them to the client later 774706f2543Smrg (e.g., during the block handler as Xnest does). */ 775706f2543Smrg } 776706f2543Smrg } 777706f2543Smrg 778706f2543Smrg#if 1 779706f2543Smrg if (pScreen->WindowExposures) 780706f2543Smrg pScreen->WindowExposures(pWindow, prgn, other_exposed); 781706f2543Smrg#endif 782706f2543Smrg DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen); 783706f2543Smrg} 784706f2543Smrg 785706f2543Smrg/** Move \a pWindow on the back-end server. Determine whether or not it 786706f2543Smrg * is on or offscreen, and realize it if it is newly on screen and the 787706f2543Smrg * lazy window creation optimization is enabled. */ 788706f2543Smrgvoid dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 789706f2543Smrg{ 790706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 791706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 792706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 793706f2543Smrg unsigned int m; 794706f2543Smrg XWindowChanges c; 795706f2543Smrg 796706f2543Smrg DMX_UNWRAP(CopyWindow, dmxScreen, pScreen); 797706f2543Smrg#if 0 798706f2543Smrg if (pScreen->CopyWindow) 799706f2543Smrg pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc); 800706f2543Smrg#endif 801706f2543Smrg 802706f2543Smrg /* Determine if the window is completely off the visible portion of 803706f2543Smrg the screen */ 804706f2543Smrg pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); 805706f2543Smrg 806706f2543Smrg /* If the window is now on-screen and it is mapped and it has not 807706f2543Smrg been created yet, create it and map it */ 808706f2543Smrg if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) { 809706f2543Smrg dmxCreateAndRealizeWindow(pWindow, TRUE); 810706f2543Smrg } else if (pWinPriv->window) { 811706f2543Smrg /* Move window on back-end server */ 812706f2543Smrg m = CWX | CWY | CWWidth | CWHeight; 813706f2543Smrg c.x = pWindow->origin.x - wBorderWidth(pWindow); 814706f2543Smrg c.y = pWindow->origin.y - wBorderWidth(pWindow); 815706f2543Smrg c.width = pWindow->drawable.width; 816706f2543Smrg c.height = pWindow->drawable.height; 817706f2543Smrg 818706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 819706f2543Smrg dmxSync(dmxScreen, False); 820706f2543Smrg } 821706f2543Smrg 822706f2543Smrg DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen); 823706f2543Smrg dmxUpdateWindowInfo(DMX_UPDATE_COPY, pWindow); 824706f2543Smrg} 825706f2543Smrg 826706f2543Smrg/** Resize \a pWindow on the back-end server. Determine whether or not 827706f2543Smrg * it is on or offscreen, and realize it if it is newly on screen and 828706f2543Smrg * the lazy window creation optimization is enabled. */ 829706f2543Smrgvoid dmxResizeWindow(WindowPtr pWindow, int x, int y, 830706f2543Smrg unsigned int w, unsigned int h, WindowPtr pSib) 831706f2543Smrg{ 832706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 833706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 834706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 835706f2543Smrg dmxWinPrivPtr pSibPriv; 836706f2543Smrg unsigned int m; 837706f2543Smrg XWindowChanges c; 838706f2543Smrg 839706f2543Smrg if (pSib) 840706f2543Smrg pSibPriv = DMX_GET_WINDOW_PRIV(pSib); 841706f2543Smrg 842706f2543Smrg DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen); 843706f2543Smrg#if 1 844706f2543Smrg if (pScreen->ResizeWindow) 845706f2543Smrg pScreen->ResizeWindow(pWindow, x, y, w, h, pSib); 846706f2543Smrg#endif 847706f2543Smrg 848706f2543Smrg /* Determine if the window is completely off the visible portion of 849706f2543Smrg the screen */ 850706f2543Smrg pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); 851706f2543Smrg 852706f2543Smrg /* If the window is now on-screen and it is mapped and it has not 853706f2543Smrg been created yet, create it and map it */ 854706f2543Smrg if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) { 855706f2543Smrg dmxCreateAndRealizeWindow(pWindow, TRUE); 856706f2543Smrg } else if (pWinPriv->window) { 857706f2543Smrg /* Handle resizing on back-end server */ 858706f2543Smrg m = CWX | CWY | CWWidth | CWHeight; 859706f2543Smrg c.x = pWindow->origin.x - wBorderWidth(pWindow); 860706f2543Smrg c.y = pWindow->origin.y - wBorderWidth(pWindow); 861706f2543Smrg c.width = pWindow->drawable.width; 862706f2543Smrg c.height = pWindow->drawable.height; 863706f2543Smrg 864706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 865706f2543Smrg dmxSync(dmxScreen, False); 866706f2543Smrg } 867706f2543Smrg 868706f2543Smrg DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen); 869706f2543Smrg dmxUpdateWindowInfo(DMX_UPDATE_RESIZE, pWindow); 870706f2543Smrg} 871706f2543Smrg 872706f2543Smrg/** Reparent \a pWindow on the back-end server. */ 873706f2543Smrgvoid dmxReparentWindow(WindowPtr pWindow, WindowPtr pPriorParent) 874706f2543Smrg{ 875706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 876706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 877706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 878706f2543Smrg dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent); 879706f2543Smrg 880706f2543Smrg DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen); 881706f2543Smrg#if 0 882706f2543Smrg if (pScreen->ReparentWindow) 883706f2543Smrg pScreen->ReparentWindow(pWindow, pPriorParent); 884706f2543Smrg#endif 885706f2543Smrg 886706f2543Smrg if (pWinPriv->window) { 887706f2543Smrg if (!pParentPriv->window) { 888706f2543Smrg dmxCreateAndRealizeWindow(pWindow->parent, FALSE); 889706f2543Smrg } 890706f2543Smrg 891706f2543Smrg /* Handle reparenting on back-end server */ 892706f2543Smrg XReparentWindow(dmxScreen->beDisplay, pWinPriv->window, 893706f2543Smrg pParentPriv->window, 894706f2543Smrg pWindow->origin.x - wBorderWidth(pWindow), 895706f2543Smrg pWindow->origin.x - wBorderWidth(pWindow)); 896706f2543Smrg dmxSync(dmxScreen, False); 897706f2543Smrg } 898706f2543Smrg 899706f2543Smrg DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen); 900706f2543Smrg dmxUpdateWindowInfo(DMX_UPDATE_REPARENT, pWindow); 901706f2543Smrg} 902706f2543Smrg 903706f2543Smrg/** Change border width for \a pWindow to \a width pixels. */ 904706f2543Smrgvoid dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width) 905706f2543Smrg{ 906706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 907706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 908706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 909706f2543Smrg unsigned int m; 910706f2543Smrg XWindowChanges c; 911706f2543Smrg 912706f2543Smrg DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen); 913706f2543Smrg#if 1 914706f2543Smrg if (pScreen->ChangeBorderWidth) 915706f2543Smrg pScreen->ChangeBorderWidth(pWindow, width); 916706f2543Smrg#endif 917706f2543Smrg 918706f2543Smrg /* NOTE: Do we need to check for on/off screen here? */ 919706f2543Smrg 920706f2543Smrg if (pWinPriv->window) { 921706f2543Smrg /* Handle border width change on back-end server */ 922706f2543Smrg m = CWBorderWidth; 923706f2543Smrg c.border_width = width; 924706f2543Smrg 925706f2543Smrg XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); 926706f2543Smrg dmxSync(dmxScreen, False); 927706f2543Smrg } 928706f2543Smrg 929706f2543Smrg DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen); 930706f2543Smrg} 931706f2543Smrg 932706f2543Smrgstatic void dmxDoSetShape(WindowPtr pWindow) 933706f2543Smrg{ 934706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 935706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 936706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 937706f2543Smrg int nBox; 938706f2543Smrg BoxPtr pBox; 939706f2543Smrg int nRect; 940706f2543Smrg XRectangle *pRect; 941706f2543Smrg XRectangle *pRectFirst; 942706f2543Smrg 943706f2543Smrg /* First, set the bounding shape */ 944706f2543Smrg if (wBoundingShape(pWindow)) { 945706f2543Smrg pBox = RegionRects(wBoundingShape(pWindow)); 946706f2543Smrg nRect = nBox = RegionNumRects(wBoundingShape(pWindow)); 947706f2543Smrg pRectFirst = pRect = malloc(nRect * sizeof(*pRect)); 948706f2543Smrg while (nBox--) { 949706f2543Smrg pRect->x = pBox->x1; 950706f2543Smrg pRect->y = pBox->y1; 951706f2543Smrg pRect->width = pBox->x2 - pBox->x1; 952706f2543Smrg pRect->height = pBox->y2 - pBox->y1; 953706f2543Smrg pBox++; 954706f2543Smrg pRect++; 955706f2543Smrg } 956706f2543Smrg XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window, 957706f2543Smrg ShapeBounding, 0, 0, 958706f2543Smrg pRectFirst, nRect, 959706f2543Smrg ShapeSet, YXBanded); 960706f2543Smrg free(pRectFirst); 961706f2543Smrg } else { 962706f2543Smrg XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window, 963706f2543Smrg ShapeBounding, 0, 0, None, ShapeSet); 964706f2543Smrg } 965706f2543Smrg 966706f2543Smrg /* Next, set the clip shape */ 967706f2543Smrg if (wClipShape(pWindow)) { 968706f2543Smrg pBox = RegionRects(wClipShape(pWindow)); 969706f2543Smrg nRect = nBox = RegionNumRects(wClipShape(pWindow)); 970706f2543Smrg pRectFirst = pRect = malloc(nRect * sizeof(*pRect)); 971706f2543Smrg while (nBox--) { 972706f2543Smrg pRect->x = pBox->x1; 973706f2543Smrg pRect->y = pBox->y1; 974706f2543Smrg pRect->width = pBox->x2 - pBox->x1; 975706f2543Smrg pRect->height = pBox->y2 - pBox->y1; 976706f2543Smrg pBox++; 977706f2543Smrg pRect++; 978706f2543Smrg } 979706f2543Smrg XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window, 980706f2543Smrg ShapeClip, 0, 0, 981706f2543Smrg pRectFirst, nRect, 982706f2543Smrg ShapeSet, YXBanded); 983706f2543Smrg free(pRectFirst); 984706f2543Smrg } else { 985706f2543Smrg XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window, 986706f2543Smrg ShapeClip, 0, 0, None, ShapeSet); 987706f2543Smrg } 988706f2543Smrg 989706f2543Smrg if (XShapeInputSelected(dmxScreen->beDisplay, pWinPriv->window)) { 990706f2543Smrg ErrorF("Input selected for window %x on Screen %d\n", 991706f2543Smrg (unsigned int)pWinPriv->window, pScreen->myNum); 992706f2543Smrg } 993706f2543Smrg} 994706f2543Smrg 995706f2543Smrg/** Set shape of \a pWindow on the back-end server. */ 996706f2543Smrgvoid dmxSetShape(WindowPtr pWindow, int kind) 997706f2543Smrg{ 998706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 999706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1000706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); 1001706f2543Smrg 1002706f2543Smrg DMX_UNWRAP(SetShape, dmxScreen, pScreen); 1003706f2543Smrg#if 1 1004706f2543Smrg if (pScreen->SetShape) 1005706f2543Smrg pScreen->SetShape(pWindow, kind); 1006706f2543Smrg#endif 1007706f2543Smrg 1008706f2543Smrg if (pWinPriv->window) { 1009706f2543Smrg /* Handle setting the current shape on the back-end server */ 1010706f2543Smrg dmxDoSetShape(pWindow); 1011706f2543Smrg dmxSync(dmxScreen, False); 1012706f2543Smrg } else { 1013706f2543Smrg pWinPriv->isShaped = TRUE; 1014706f2543Smrg } 1015706f2543Smrg 1016706f2543Smrg DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen); 1017706f2543Smrg} 1018