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