diff options
author | marha <marha@users.sourceforge.net> | 2011-09-12 11:27:51 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-09-12 11:27:51 +0200 |
commit | dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 (patch) | |
tree | bdf833cc6a4fc9035411779e10dd9e8478201885 /xorg-server/hw/dmx | |
parent | 0b40f5f4b54453a77f4b09c431f8efc6875da61f (diff) | |
download | vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.gz vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.bz2 vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.zip |
Synchronised line endinge with release branch
Diffstat (limited to 'xorg-server/hw/dmx')
-rw-r--r-- | xorg-server/hw/dmx/Makefile.am | 178 | ||||
-rw-r--r-- | xorg-server/hw/dmx/dmxcb.c | 446 | ||||
-rw-r--r-- | xorg-server/hw/dmx/dmxextension.c | 3240 | ||||
-rw-r--r-- | xorg-server/hw/dmx/dmxgcops.c | 1210 | ||||
-rw-r--r-- | xorg-server/hw/dmx/dmxwindow.c | 2034 | ||||
-rw-r--r-- | xorg-server/hw/dmx/doc/Makefile.am | 68 | ||||
-rw-r--r-- | xorg-server/hw/dmx/glxProxy/glxcmds.c | 7290 | ||||
-rw-r--r-- | xorg-server/hw/dmx/glxProxy/glxsingle.c | 2032 | ||||
-rw-r--r-- | xorg-server/hw/dmx/glxProxy/glxvendor.c | 1170 | ||||
-rw-r--r-- | xorg-server/hw/dmx/glxProxy/render2swap.c | 572 | ||||
-rw-r--r-- | xorg-server/hw/dmx/input/dmxevents.c | 1532 |
11 files changed, 9886 insertions, 9886 deletions
diff --git a/xorg-server/hw/dmx/Makefile.am b/xorg-server/hw/dmx/Makefile.am index 369edf802..fb727e656 100644 --- a/xorg-server/hw/dmx/Makefile.am +++ b/xorg-server/hw/dmx/Makefile.am @@ -1,89 +1,89 @@ -
-SUBDIRS = input config examples doc doxygen man
-bin_PROGRAMS = Xdmx
-
-if XINERAMA
-PANORAMIX_SRCS = $(top_srcdir)/Xext/panoramiX.c
-endif
-
-if GLX
-SUBDIRS += glxProxy
-GLX_LIBS = glxProxy/libglxproxy.a
-GLX_SRCS = $(PANORAMIX_SRCS) dmx_glxvisuals.c dmx_glxvisuals.h
-GLX_INCS = -I$(top_srcdir)/hw/xfree86/dixmods/extmod
-GLX_DEFS = @GL_CFLAGS@
-endif
-
-AM_CFLAGS = \
- -DHAVE_DMX_CONFIG_H \
- $(DIX_CFLAGS) \
- $(GLX_INCS) \
- $(GLX_DEFS) \
- $(DMX_CFLAGS) \
- @DMXMODULES_CFLAGS@
-
-Xdmx_SOURCES = dmx.c \
- dmxcb.c \
- dmxcb.h \
- dmxclient.h \
- dmxcmap.c \
- dmxcmap.h \
- dmx-config.h \
- dmxcursor.c \
- dmxcursor.h \
- dmxdpms.c \
- dmxdpms.h \
- dmxextension.c \
- dmxextension.h \
- dmxfont.c \
- dmxfont.h \
- dmxgc.c \
- dmxgc.h \
- dmxgcops.c \
- dmxgcops.h \
- dmx.h \
- dmxinit.c \
- dmxinit.h \
- dmxinput.c \
- dmxinput.h \
- dmxlog.c \
- dmxlog.h \
- dmxpict.c \
- dmxpict.h \
- dmxpixmap.c \
- dmxpixmap.h \
- dmxprop.c \
- dmxprop.h \
- dmxscrinit.c \
- dmxscrinit.h \
- dmxshadow.c \
- dmxshadow.h \
- dmxstat.c \
- dmxstat.h \
- dmxsync.c \
- dmxsync.h \
- dmxvisual.c \
- dmxvisual.h \
- dmxwindow.c \
- dmxwindow.h \
- $(top_srcdir)/mi/miinitext.c \
- $(top_srcdir)/fb/fbcmap_mi.c \
- $(GLX_SRCS)
-
-
-#if COMPOSITE
-#Xdmx_SOURCES += fakecw.c
-#endif
-
-XDMX_LIBS = \
- $(GLX_LIBS) \
- @XDMX_LIBS@ \
- input/libdmxinput.a \
- config/libdmxconfig.a
-
-Xdmx_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
-Xdmx_DEPENDENCIES= $(XDMX_LIBS)
-Xdmx_LDADD = $(XDMX_LIBS) $(XDMX_SYS_LIBS) $(XSERVER_SYS_LIBS)
-
-relink:
- $(AM_V_at)rm -f Xdmx$(EXEEXT) && $(MAKE) Xdmx$(EXEEXT)
+ +SUBDIRS = input config examples doc doxygen man +bin_PROGRAMS = Xdmx + +if XINERAMA +PANORAMIX_SRCS = $(top_srcdir)/Xext/panoramiX.c +endif + +if GLX +SUBDIRS += glxProxy +GLX_LIBS = glxProxy/libglxproxy.a +GLX_SRCS = $(PANORAMIX_SRCS) dmx_glxvisuals.c dmx_glxvisuals.h +GLX_INCS = -I$(top_srcdir)/hw/xfree86/dixmods/extmod +GLX_DEFS = @GL_CFLAGS@ +endif + +AM_CFLAGS = \ + -DHAVE_DMX_CONFIG_H \ + $(DIX_CFLAGS) \ + $(GLX_INCS) \ + $(GLX_DEFS) \ + $(DMX_CFLAGS) \ + @DMXMODULES_CFLAGS@ + +Xdmx_SOURCES = dmx.c \ + dmxcb.c \ + dmxcb.h \ + dmxclient.h \ + dmxcmap.c \ + dmxcmap.h \ + dmx-config.h \ + dmxcursor.c \ + dmxcursor.h \ + dmxdpms.c \ + dmxdpms.h \ + dmxextension.c \ + dmxextension.h \ + dmxfont.c \ + dmxfont.h \ + dmxgc.c \ + dmxgc.h \ + dmxgcops.c \ + dmxgcops.h \ + dmx.h \ + dmxinit.c \ + dmxinit.h \ + dmxinput.c \ + dmxinput.h \ + dmxlog.c \ + dmxlog.h \ + dmxpict.c \ + dmxpict.h \ + dmxpixmap.c \ + dmxpixmap.h \ + dmxprop.c \ + dmxprop.h \ + dmxscrinit.c \ + dmxscrinit.h \ + dmxshadow.c \ + dmxshadow.h \ + dmxstat.c \ + dmxstat.h \ + dmxsync.c \ + dmxsync.h \ + dmxvisual.c \ + dmxvisual.h \ + dmxwindow.c \ + dmxwindow.h \ + $(top_srcdir)/mi/miinitext.c \ + $(top_srcdir)/fb/fbcmap_mi.c \ + $(GLX_SRCS) + + +#if COMPOSITE +#Xdmx_SOURCES += fakecw.c +#endif + +XDMX_LIBS = \ + $(GLX_LIBS) \ + @XDMX_LIBS@ \ + input/libdmxinput.a \ + config/libdmxconfig.a + +Xdmx_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) +Xdmx_DEPENDENCIES= $(XDMX_LIBS) +Xdmx_LDADD = $(XDMX_LIBS) $(XDMX_SYS_LIBS) $(XSERVER_SYS_LIBS) + +relink: + $(AM_V_at)rm -f Xdmx$(EXEEXT) && $(MAKE) Xdmx$(EXEEXT) diff --git a/xorg-server/hw/dmx/dmxcb.c b/xorg-server/hw/dmx/dmxcb.c index bc3281f56..d0eb35117 100644 --- a/xorg-server/hw/dmx/dmxcb.c +++ b/xorg-server/hw/dmx/dmxcb.c @@ -1,223 +1,223 @@ -/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- * This code queries and modifies the connection block. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxcb.h"
-#include "dmxinput.h"
-#include "dmxlog.h"
-
-extern int connBlockScreenStart;
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-extern int PanoramiXPixWidth;
-extern int PanoramiXPixHeight;
-extern int PanoramiXNumScreens;
-#endif
-
- int dmxGlobalWidth, dmxGlobalHeight;
-
-/** We may want the wall dimensions to be different from the bounding
- * box dimensions that Xinerama computes, so save those and update them
- * here.
- */
-void dmxSetWidthHeight(int width, int height)
-{
- dmxGlobalWidth = width;
- dmxGlobalHeight = height;
-}
-
-/** Computes the global bounding box for DMX. This may be larger than
- * the one computed by Xinerama because of the DMX configuration
- * file. */
-void dmxComputeWidthHeight(DMXRecomputeFlag flag)
-{
- int i;
- DMXScreenInfo *dmxScreen;
- int w = 0;
- int h = 0;
-
- for (i = 0; i < dmxNumScreens; i++) {
- /* Don't use root* here because this is
- * the global bounding box. */
- dmxScreen = &dmxScreens[i];
- if (w < dmxScreen->scrnWidth + dmxScreen->rootXOrigin)
- w = dmxScreen->scrnWidth + dmxScreen->rootXOrigin;
- if (h < dmxScreen->scrnHeight + dmxScreen->rootYOrigin)
- h = dmxScreen->scrnHeight + dmxScreen->rootYOrigin;
- }
- if (!dmxGlobalWidth && !dmxGlobalHeight) {
- dmxLog(dmxInfo, "Using %dx%d as global bounding box\n", w, h);
- } else {
- switch (flag) {
- case DMX_NO_RECOMPUTE_BOUNDING_BOX:
- dmxLog(dmxInfo,
- "Using old bounding box (%dx%d) instead of new (%dx%d)\n",
- dmxGlobalWidth, dmxGlobalHeight, w, h);
- w = dmxGlobalWidth;
- h = dmxGlobalHeight;
- break;
- case DMX_RECOMPUTE_BOUNDING_BOX:
- dmxLog(dmxInfo,
- "Using %dx%d as global bounding box, instead of %dx%d\n",
- w, h, dmxGlobalWidth, dmxGlobalHeight);
- break;
- }
- }
-
- dmxGlobalWidth = w;
- dmxGlobalHeight = h;
-}
-
-/** A callback routine that hooks into Xinerama and provides a
- * convenient place to print summary log information during server
- * startup. This routine does not modify any values. */
-void dmxConnectionBlockCallback(void)
-{
- xWindowRoot *root = (xWindowRoot *)(ConnectionInfo+connBlockScreenStart);
- int offset = connBlockScreenStart + sizeof(xWindowRoot);
- int i;
- Bool *found = NULL;
-
- MAXSCREENSALLOC(found);
- if (!found)
- dmxLog(dmxFatal, "dmxConnectionBlockCallback: out of memory\n");
-
- dmxLog(dmxInfo, "===== Start of Summary =====\n");
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- if (dmxGlobalWidth && dmxGlobalHeight
- && (dmxGlobalWidth != PanoramiXPixWidth
- || dmxGlobalHeight != PanoramiXPixHeight)) {
- dmxLog(dmxInfo,
- "Changing Xinerama dimensions from %d %d to %d %d\n",
- PanoramiXPixWidth, PanoramiXPixHeight,
- dmxGlobalWidth, dmxGlobalHeight);
- PanoramiXPixWidth = root->pixWidth = dmxGlobalWidth;
- PanoramiXPixHeight = root->pixHeight = dmxGlobalHeight;
- } else {
- dmxGlobalWidth = PanoramiXPixWidth;
- dmxGlobalHeight = PanoramiXPixHeight;
- }
- dmxLog(dmxInfo, "%d screens configured with Xinerama (%d %d)\n",
- PanoramiXNumScreens, PanoramiXPixWidth, PanoramiXPixHeight);
- FOR_NSCREENS(i) found[i] = FALSE;
- } else {
-#endif
- /* This never happens because we're
- * either called from a Xinerama
- * callback or during reconfiguration
- * (which only works with Xinerama on).
- * In any case, be reasonable. */
- dmxLog(dmxInfo, "%d screens configured (%d %d)\n",
- screenInfo.numScreens, root->pixWidth, root->pixHeight);
-#ifdef PANORAMIX
- }
-#endif
-
- for (i = 0; i < root->nDepths; i++) {
- xDepth *depth = (xDepth *)(ConnectionInfo + offset);
- int voffset = offset + sizeof(xDepth);
- xVisualType *visual = (xVisualType *)(ConnectionInfo + voffset);
- int j;
-
- dmxLog(dmxInfo, "%d visuals at depth %d:\n",
- depth->nVisuals, depth->depth);
- for (j = 0; j < depth->nVisuals; j++, visual++) {
- XVisualInfo vi;
-
- vi.visual = NULL;
- vi.visualid = visual->visualID;
- vi.screen = 0;
- vi.depth = depth->depth;
- vi.class = visual->class;
- vi.red_mask = visual->redMask;
- vi.green_mask = visual->greenMask;
- vi.blue_mask = visual->blueMask;
- vi.colormap_size = visual->colormapEntries;
- vi.bits_per_rgb = visual->bitsPerRGB;
- dmxLogVisual(NULL, &vi, 0);
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- int k;
- FOR_NSCREENS(k) {
- DMXScreenInfo *dmxScreen = &dmxScreens[k];
-
- if (dmxScreen->beDisplay) {
- XVisualInfo *pvi =
- &dmxScreen->beVisuals[dmxScreen->beDefVisualIndex];
- if (pvi->depth == depth->depth &&
- pvi->class == visual->class)
- found[k] = TRUE;
- } else {
- /* Screen #k is detatched, so it always succeeds */
- found[k] = TRUE;
- }
- }
- }
-#endif
- }
- offset = voffset + depth->nVisuals * sizeof(xVisualType);
- }
-
- dmxInputLogDevices();
- dmxLog(dmxInfo, "===== End of Summary =====\n");
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- Bool fatal = FALSE;
- FOR_NSCREENS(i) {
- fatal |= !found[i];
- if (!found[i]) {
- dmxLog(dmxError,
- "The default visual for screen #%d does not match "
- "any of the\n", i);
- dmxLog(dmxError,
- "consolidated visuals from Xinerama (listed above)\n");
- }
- }
- if (fatal)
- dmxLog(dmxFatal,
- "dmxConnectionBlockCallback: invalid screen(s) found");
- }
-#endif
- MAXSCREENSFREE(found);
-}
+/* + * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Rickard E. (Rik) Faith <faith@redhat.com> + * + */ + +/** \file + * This code queries and modifies the connection block. */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxcb.h" +#include "dmxinput.h" +#include "dmxlog.h" + +extern int connBlockScreenStart; + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +extern int PanoramiXPixWidth; +extern int PanoramiXPixHeight; +extern int PanoramiXNumScreens; +#endif + + int dmxGlobalWidth, dmxGlobalHeight; + +/** We may want the wall dimensions to be different from the bounding + * box dimensions that Xinerama computes, so save those and update them + * here. + */ +void dmxSetWidthHeight(int width, int height) +{ + dmxGlobalWidth = width; + dmxGlobalHeight = height; +} + +/** Computes the global bounding box for DMX. This may be larger than + * the one computed by Xinerama because of the DMX configuration + * file. */ +void dmxComputeWidthHeight(DMXRecomputeFlag flag) +{ + int i; + DMXScreenInfo *dmxScreen; + int w = 0; + int h = 0; + + for (i = 0; i < dmxNumScreens; i++) { + /* Don't use root* here because this is + * the global bounding box. */ + dmxScreen = &dmxScreens[i]; + if (w < dmxScreen->scrnWidth + dmxScreen->rootXOrigin) + w = dmxScreen->scrnWidth + dmxScreen->rootXOrigin; + if (h < dmxScreen->scrnHeight + dmxScreen->rootYOrigin) + h = dmxScreen->scrnHeight + dmxScreen->rootYOrigin; + } + if (!dmxGlobalWidth && !dmxGlobalHeight) { + dmxLog(dmxInfo, "Using %dx%d as global bounding box\n", w, h); + } else { + switch (flag) { + case DMX_NO_RECOMPUTE_BOUNDING_BOX: + dmxLog(dmxInfo, + "Using old bounding box (%dx%d) instead of new (%dx%d)\n", + dmxGlobalWidth, dmxGlobalHeight, w, h); + w = dmxGlobalWidth; + h = dmxGlobalHeight; + break; + case DMX_RECOMPUTE_BOUNDING_BOX: + dmxLog(dmxInfo, + "Using %dx%d as global bounding box, instead of %dx%d\n", + w, h, dmxGlobalWidth, dmxGlobalHeight); + break; + } + } + + dmxGlobalWidth = w; + dmxGlobalHeight = h; +} + +/** A callback routine that hooks into Xinerama and provides a + * convenient place to print summary log information during server + * startup. This routine does not modify any values. */ +void dmxConnectionBlockCallback(void) +{ + xWindowRoot *root = (xWindowRoot *)(ConnectionInfo+connBlockScreenStart); + int offset = connBlockScreenStart + sizeof(xWindowRoot); + int i; + Bool *found = NULL; + + MAXSCREENSALLOC(found); + if (!found) + dmxLog(dmxFatal, "dmxConnectionBlockCallback: out of memory\n"); + + dmxLog(dmxInfo, "===== Start of Summary =====\n"); +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + if (dmxGlobalWidth && dmxGlobalHeight + && (dmxGlobalWidth != PanoramiXPixWidth + || dmxGlobalHeight != PanoramiXPixHeight)) { + dmxLog(dmxInfo, + "Changing Xinerama dimensions from %d %d to %d %d\n", + PanoramiXPixWidth, PanoramiXPixHeight, + dmxGlobalWidth, dmxGlobalHeight); + PanoramiXPixWidth = root->pixWidth = dmxGlobalWidth; + PanoramiXPixHeight = root->pixHeight = dmxGlobalHeight; + } else { + dmxGlobalWidth = PanoramiXPixWidth; + dmxGlobalHeight = PanoramiXPixHeight; + } + dmxLog(dmxInfo, "%d screens configured with Xinerama (%d %d)\n", + PanoramiXNumScreens, PanoramiXPixWidth, PanoramiXPixHeight); + FOR_NSCREENS(i) found[i] = FALSE; + } else { +#endif + /* This never happens because we're + * either called from a Xinerama + * callback or during reconfiguration + * (which only works with Xinerama on). + * In any case, be reasonable. */ + dmxLog(dmxInfo, "%d screens configured (%d %d)\n", + screenInfo.numScreens, root->pixWidth, root->pixHeight); +#ifdef PANORAMIX + } +#endif + + for (i = 0; i < root->nDepths; i++) { + xDepth *depth = (xDepth *)(ConnectionInfo + offset); + int voffset = offset + sizeof(xDepth); + xVisualType *visual = (xVisualType *)(ConnectionInfo + voffset); + int j; + + dmxLog(dmxInfo, "%d visuals at depth %d:\n", + depth->nVisuals, depth->depth); + for (j = 0; j < depth->nVisuals; j++, visual++) { + XVisualInfo vi; + + vi.visual = NULL; + vi.visualid = visual->visualID; + vi.screen = 0; + vi.depth = depth->depth; + vi.class = visual->class; + vi.red_mask = visual->redMask; + vi.green_mask = visual->greenMask; + vi.blue_mask = visual->blueMask; + vi.colormap_size = visual->colormapEntries; + vi.bits_per_rgb = visual->bitsPerRGB; + dmxLogVisual(NULL, &vi, 0); + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + int k; + FOR_NSCREENS(k) { + DMXScreenInfo *dmxScreen = &dmxScreens[k]; + + if (dmxScreen->beDisplay) { + XVisualInfo *pvi = + &dmxScreen->beVisuals[dmxScreen->beDefVisualIndex]; + if (pvi->depth == depth->depth && + pvi->class == visual->class) + found[k] = TRUE; + } else { + /* Screen #k is detatched, so it always succeeds */ + found[k] = TRUE; + } + } + } +#endif + } + offset = voffset + depth->nVisuals * sizeof(xVisualType); + } + + dmxInputLogDevices(); + dmxLog(dmxInfo, "===== End of Summary =====\n"); + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + Bool fatal = FALSE; + FOR_NSCREENS(i) { + fatal |= !found[i]; + if (!found[i]) { + dmxLog(dmxError, + "The default visual for screen #%d does not match " + "any of the\n", i); + dmxLog(dmxError, + "consolidated visuals from Xinerama (listed above)\n"); + } + } + if (fatal) + dmxLog(dmxFatal, + "dmxConnectionBlockCallback: invalid screen(s) found"); + } +#endif + MAXSCREENSFREE(found); +} diff --git a/xorg-server/hw/dmx/dmxextension.c b/xorg-server/hw/dmx/dmxextension.c index 00b95a96d..db5709ee6 100644 --- a/xorg-server/hw/dmx/dmxextension.c +++ b/xorg-server/hw/dmx/dmxextension.c @@ -1,1620 +1,1620 @@ -/*
- * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Author:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * This file provides the only interface to the X server extension support
- * in programs/Xserver/Xext. Those programs should only include dmxext.h
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "dmx.h"
-#include "dmxinit.h"
-#include "dmxextension.h"
-#include "dmxwindow.h"
-#include "dmxcb.h"
-#include "dmxcursor.h"
-#include "dmxpixmap.h"
-#include "dmxgc.h"
-#include "dmxfont.h"
-#include "dmxcmap.h"
-#include "dmxpict.h"
-#include "dmxinput.h"
-#include "dmxsync.h"
-#include "dmxscrinit.h"
-#include "input/dmxinputinit.h"
-
-#include "windowstr.h"
-#include "inputstr.h" /* For DeviceIntRec */
-#include <X11/extensions/dmxproto.h> /* For DMX_BAD_* */
-#include "cursorstr.h"
-
-/* The default font is declared in dix/globals.c, but is not included in
- * _any_ header files. */
-extern FontPtr defaultFont;
-
-/** This routine provides information to the DMX protocol extension
- * about a particular screen. */
-Bool dmxGetScreenAttributes(int physical, DMXScreenAttributesPtr attr)
-{
- DMXScreenInfo *dmxScreen;
-
- if (physical < 0 || physical >= dmxNumScreens) return FALSE;
-
- dmxScreen = &dmxScreens[physical];
- attr->displayName = dmxScreen->name;
-#ifdef PANORAMIX
- attr->logicalScreen = noPanoramiXExtension ? dmxScreen->index : 0;
-#else
- attr->logicalScreen = dmxScreen->index;
-#endif
-
- attr->screenWindowWidth = dmxScreen->scrnWidth;
- attr->screenWindowHeight = dmxScreen->scrnHeight;
- attr->screenWindowXoffset = dmxScreen->scrnX;
- attr->screenWindowYoffset = dmxScreen->scrnY;
-
- attr->rootWindowWidth = dmxScreen->rootWidth;
- attr->rootWindowHeight = dmxScreen->rootHeight;
- attr->rootWindowXoffset = dmxScreen->rootX;
- attr->rootWindowYoffset = dmxScreen->rootY;
-
- attr->rootWindowXorigin = dmxScreen->rootXOrigin;
- attr->rootWindowYorigin = dmxScreen->rootYOrigin;
-
- return TRUE;
-}
-
-/** This routine provides information to the DMX protocol extension
- * about a particular window. */
-Bool dmxGetWindowAttributes(WindowPtr pWindow, DMXWindowAttributesPtr attr)
-{
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- attr->screen = pWindow->drawable.pScreen->myNum;
- attr->window = pWinPriv->window;
-
- attr->pos.x = pWindow->drawable.x;
- attr->pos.y = pWindow->drawable.y;
- attr->pos.width = pWindow->drawable.width;
- attr->pos.height = pWindow->drawable.height;
-
- if (!pWinPriv->window || pWinPriv->offscreen) {
- attr->vis.x = 0;
- attr->vis.y = 0;
- attr->vis.height = 0;
- attr->vis.width = 0;
- return pWinPriv->window ? TRUE : FALSE;
- }
-
- /* Compute display-relative coordinates */
- attr->vis.x = pWindow->drawable.x;
- attr->vis.y = pWindow->drawable.y;
- attr->vis.width = pWindow->drawable.width;
- attr->vis.height = pWindow->drawable.height;
-
- if (attr->pos.x < 0) {
- attr->vis.x -= attr->pos.x;
- attr->vis.width = attr->pos.x + attr->pos.width - attr->vis.x;
- }
- if (attr->pos.x + attr->pos.width > pWindow->drawable.pScreen->width) {
- if (attr->pos.x < 0)
- attr->vis.width = pWindow->drawable.pScreen->width;
- else
- attr->vis.width = pWindow->drawable.pScreen->width - attr->pos.x;
- }
- if (attr->pos.y < 0) {
- attr->vis.y -= attr->pos.y;
- attr->vis.height = attr->pos.y + attr->pos.height - attr->vis.y;
- }
- if (attr->pos.y + attr->pos.height > pWindow->drawable.pScreen->height) {
- if (attr->pos.y < 0)
- attr->vis.height = pWindow->drawable.pScreen->height;
- else
- attr->vis.height = pWindow->drawable.pScreen->height - attr->pos.y;
- }
-
- /* Convert to window-relative coordinates */
- attr->vis.x -= attr->pos.x;
- attr->vis.y -= attr->pos.y;
-
- return TRUE;
-}
-
-void dmxGetDesktopAttributes(DMXDesktopAttributesPtr attr)
-{
- attr->width = dmxGlobalWidth;
- attr->height = dmxGlobalHeight;
- attr->shiftX = 0; /* NOTE: The upper left hand corner of */
- attr->shiftY = 0; /* the desktop is always <0,0>. */
-}
-
-/** Return the total number of devices, not just #dmxNumInputs. The
- * number returned should be the same as that returned by
- * XListInputDevices. */
-int dmxGetInputCount(void)
-{
- int i, total;
-
- for (total = i = 0; i < dmxNumInputs; i++) total += dmxInputs[i].numDevs;
- return total;
-}
-
-/** Return information about the device with id = \a deviceId. This
- * information is primarily for the #ProcDMXGetInputAttributes()
- * function, which does not have access to the appropriate data
- * structure. */
-int dmxGetInputAttributes(int deviceId, DMXInputAttributesPtr attr)
-{
- int i, j;
- DMXInputInfo *dmxInput;
-
- if (deviceId < 0) return -1;
- for (i = 0; i < dmxNumInputs; i++) {
- dmxInput = &dmxInputs[i];
- for (j = 0; j < dmxInput->numDevs; j++) {
- DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
- if (deviceId != dmxLocal->pDevice->id) continue;
- attr->isCore = !!dmxLocal->isCore;
- attr->sendsCore = !!dmxLocal->sendsCore;
- attr->detached = !!dmxInput->detached;
- attr->physicalScreen = -1;
- attr->physicalId = -1;
- attr->name = NULL;
- switch (dmxLocal->extType) {
- case DMX_LOCAL_TYPE_LOCAL:
- attr->inputType = 0;
- break;
- case DMX_LOCAL_TYPE_CONSOLE:
- attr->inputType = 1;
- attr->name = dmxInput->name;
- attr->physicalId = dmxLocal->deviceId;
- break;
- case DMX_LOCAL_TYPE_BACKEND:
- case DMX_LOCAL_TYPE_COMMON:
- attr->inputType = 2;
- attr->physicalScreen = dmxInput->scrnIdx;
- attr->name = dmxInput->name;
- attr->physicalId = dmxLocal->deviceId;
- break;
- }
- return 0; /* Success */
- }
- }
- return -1; /* Failure */
-}
-
-/** Reinitialized the cursor boundaries. */
-static void dmxAdjustCursorBoundaries(void)
-{
- int i;
-
- dmxReInitOrigins();
- dmxInitOverlap();
- dmxComputeWidthHeight(DMX_NO_RECOMPUTE_BOUNDING_BOX);
- dmxConnectionBlockCallback();
- for (i = 0; i < dmxNumInputs; i++) {
- DMXInputInfo *dmxInput = &dmxInputs[i];
- if (!dmxInput->detached) dmxInputReInit(dmxInput);
- }
-
- dmxCheckCursor();
-
- for (i = 0; i < dmxNumInputs; i++) {
- DMXInputInfo *dmxInput = &dmxInputs[i];
- if (!dmxInput->detached) dmxInputLateReInit(dmxInput);
- }
-}
-
-/** Add an input with the specified attributes. If the input is added,
- * the physical id is returned in \a deviceId. */
-int dmxAddInput(DMXInputAttributesPtr attr, int *id)
-{
- int retcode = BadValue;
-
- if (attr->inputType == 1) /* console */
- retcode = dmxInputAttachConsole(attr->name, attr->sendsCore, id);
- else if (attr->inputType == 2) /* backend */
- retcode = dmxInputAttachBackend(attr->physicalScreen,
- attr->sendsCore,id);
-
- if (retcode == Success) {
- /* Adjust the cursor boundaries */
- dmxAdjustCursorBoundaries();
-
- /* Force completion of the changes */
- dmxSync(NULL, TRUE);
- }
-
- return retcode;
-}
-
-/** Remove the input with physical id \a id. */
-int dmxRemoveInput(int id)
-{
- return dmxInputDetachId(id);
-}
-
-/** Return the value of #dmxNumScreens -- the total number of backend
- * screens in use (these are logical screens and may be larger than the
- * number of backend displays). */
-unsigned long dmxGetNumScreens(void)
-{
- return dmxNumScreens;
-}
-
-/** Make sure that #dmxCreateAndRealizeWindow has been called for \a
- * pWindow. */
-void dmxForceWindowCreation(WindowPtr pWindow)
-{
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- if (!pWinPriv->window) dmxCreateAndRealizeWindow(pWindow, TRUE);
-}
-
-/** Flush pending syncs for all screens. */
-void dmxFlushPendingSyncs(void)
-{
- dmxSync(NULL, TRUE);
-}
-
-/** Update DMX's screen resources to match those of the newly moved
- * and/or resized "root" window. */
-void dmxUpdateScreenResources(ScreenPtr pScreen, int x, int y, int w, int h)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- WindowPtr pRoot = pScreen->root;
- WindowPtr pChild;
- Bool anyMarked = FALSE;
-
- /* Handle special case where width and/or height are zero */
- if (w == 0 || h == 0) {
- w = 1;
- h = 1;
- }
-
- /* Change screen size */
- pScreen->width = w;
- pScreen->height = h;
-
- /* Reset the root window's drawable's size */
- pRoot->drawable.width = w;
- pRoot->drawable.height = h;
-
- /* Set the root window's new winSize and borderSize */
- pRoot->winSize.extents.x1 = 0;
- pRoot->winSize.extents.y1 = 0;
- pRoot->winSize.extents.x2 = w;
- pRoot->winSize.extents.y2 = h;
-
- pRoot->borderSize.extents.x1 = 0;
- pRoot->borderSize.extents.y1 = 0;
- pRoot->borderSize.extents.x2 = w;
- pRoot->borderSize.extents.y2 = h;
-
- /* Recompute this screen's mmWidth & mmHeight */
- pScreen->mmWidth =
- (w * 254 + dmxScreen->beXDPI * 5) / (dmxScreen->beXDPI * 10);
- pScreen->mmHeight =
- (h * 254 + dmxScreen->beYDPI * 5) / (dmxScreen->beYDPI * 10);
-
- /* Recompute this screen's window's clip rects as follows: */
- /* 1. Mark all of root's children's windows */
- for (pChild = pRoot->firstChild; pChild; pChild = pChild->nextSib)
- anyMarked |= pScreen->MarkOverlappedWindows(pChild, pChild,
- (WindowPtr *)NULL);
-
- /* 2. Set the root window's borderClip */
- pRoot->borderClip.extents.x1 = 0;
- pRoot->borderClip.extents.y1 = 0;
- pRoot->borderClip.extents.x2 = w;
- pRoot->borderClip.extents.y2 = h;
-
- /* 3. Set the root window's clipList */
- if (anyMarked) {
- /* If any windows have been marked, set the root window's
- * clipList to be broken since it will be recalculated in
- * ValidateTree()
- */
- RegionBreak(&pRoot->clipList);
- } else {
- /* Otherwise, we just set it directly since there are no
- * windows visible on this screen
- */
- pRoot->clipList.extents.x1 = 0;
- pRoot->clipList.extents.y1 = 0;
- pRoot->clipList.extents.x2 = w;
- pRoot->clipList.extents.y2 = h;
- }
-
- /* 4. Revalidate all clip rects and generate expose events */
- if (anyMarked) {
- pScreen->ValidateTree(pRoot, NULL, VTBroken);
- pScreen->HandleExposures(pRoot);
- if (pScreen->PostValidateTree)
- pScreen->PostValidateTree(pRoot, NULL, VTBroken);
- }
-}
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-
-/** Change the "screen" window attributes by resizing the actual window
- * on the back-end display (if necessary). */
-static void dmxConfigureScreenWindow(int idx,
- int x, int y, int w, int h)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
- ScreenPtr pScreen = screenInfo.screens[idx];
-
- /* Resize "screen" window */
- if (dmxScreen->scrnX != x ||
- dmxScreen->scrnY != y ||
- dmxScreen->scrnWidth != w ||
- dmxScreen->scrnHeight != h) {
- dmxResizeScreenWindow(pScreen, x, y, w, h);
- }
-
- /* Change "screen" window values */
- dmxScreen->scrnX = x;
- dmxScreen->scrnY = y;
- dmxScreen->scrnWidth = w;
- dmxScreen->scrnHeight = h;
-}
-
-/** Change the "root" window position and size by resizing the actual
- * window on the back-end display (if necessary) and updating all of
- * DMX's resources by calling #dmxUpdateScreenResources. */
-static void dmxConfigureRootWindow(int idx, int x, int y, int w, int h)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
- WindowPtr pRoot = screenInfo.screens[idx]->root;
-
- /* NOTE: Either this function or the ones that it calls must handle
- * the case where w == 0 || h == 0. Currently, the functions that
- * this one calls handle that case. */
-
- /* 1. Resize "root" window */
- if (dmxScreen->rootX != x ||
- dmxScreen->rootY != y ||
- dmxScreen->rootWidth != w ||
- dmxScreen->rootHeight != h) {
- dmxResizeRootWindow(pRoot, x, y, w, h);
- }
-
- /* 2. Update all of the screen's resources associated with this root
- * window */
- if (dmxScreen->rootWidth != w ||
- dmxScreen->rootHeight != h) {
- dmxUpdateScreenResources(screenInfo.screens[idx], x, y, w, h);
- }
-
- /* Change "root" window values */
- dmxScreen->rootX = x;
- dmxScreen->rootY = y;
- dmxScreen->rootWidth = w;
- dmxScreen->rootHeight = h;
-}
-
-/** Change the "root" window's origin by updating DMX's internal data
- * structures (dix and Xinerama) to use the new origin and adjust the
- * positions of windows that overlap this "root" window. */
-static void dmxSetRootWindowOrigin(int idx, int x, int y)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
- ScreenPtr pScreen = screenInfo.screens[idx];
- WindowPtr pRoot = pScreen->root;
- WindowPtr pChild;
- int xoff;
- int yoff;
-
- /* Change "root" window's origin */
- dmxScreen->rootXOrigin = x;
- dmxScreen->rootYOrigin = y;
-
- /* Compute offsets here in case <x,y> has been changed above */
- xoff = x - pScreen->x;
- yoff = y - pScreen->y;
-
- /* Adjust the root window's position */
- pScreen->x = dmxScreen->rootXOrigin;
- pScreen->y = dmxScreen->rootYOrigin;
-
- /* Recalculate the Xinerama regions and data structs */
- XineramaReinitData(pScreen);
-
- /* Adjust each of the root window's children */
- if (!idx) ReinitializeRootWindow(screenInfo.screens[0]->root, xoff, yoff);
- pChild = pRoot->firstChild;
- while (pChild) {
- /* Adjust child window's position */
- pScreen->MoveWindow(pChild,
- pChild->origin.x - wBorderWidth(pChild) - xoff,
- pChild->origin.y - wBorderWidth(pChild) - yoff,
- pChild->nextSib,
- VTMove);
-
- /* Note that the call to MoveWindow will eventually call
- * dmxPositionWindow which will automatically create a
- * window if it is now exposed on screen (for lazy window
- * creation optimization) and it will properly set the
- * offscreen flag.
- */
-
- pChild = pChild->nextSib;
- }
-}
-
-/** Configure the attributes of each "screen" and "root" window. */
-int dmxConfigureScreenWindows(int nscreens,
- CARD32 *screens,
- DMXScreenAttributesPtr attribs,
- int *errorScreen)
-{
- int i;
-
- for (i = 0; i < nscreens; i++) {
- DMXScreenAttributesPtr attr = &attribs[i];
- int idx = screens[i];
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
-
- if (errorScreen) *errorScreen = i;
-
- if (!dmxScreen->beDisplay) return DMX_BAD_VALUE;
-
- /* Check for illegal values */
- if (idx < 0 || idx >= dmxNumScreens) return BadValue;
-
- /* The "screen" and "root" windows must have valid sizes */
- if (attr->screenWindowWidth <= 0 || attr->screenWindowHeight <= 0 ||
- attr->rootWindowWidth < 0 || attr->rootWindowHeight < 0)
- return DMX_BAD_VALUE;
-
- /* The "screen" window must fit entirely within the BE display */
- if (attr->screenWindowXoffset < 0 ||
- attr->screenWindowYoffset < 0 ||
- attr->screenWindowXoffset
- + attr->screenWindowWidth > (unsigned)dmxScreen->beWidth ||
- attr->screenWindowYoffset
- + attr->screenWindowHeight > (unsigned)dmxScreen->beHeight)
- return DMX_BAD_VALUE;
-
- /* The "root" window must fit entirely within the "screen" window */
- if (attr->rootWindowXoffset < 0 ||
- attr->rootWindowYoffset < 0 ||
- attr->rootWindowXoffset
- + attr->rootWindowWidth > attr->screenWindowWidth ||
- attr->rootWindowYoffset
- + attr->rootWindowHeight > attr->screenWindowHeight)
- return DMX_BAD_VALUE;
-
- /* The "root" window must not expose unaddressable coordinates */
- if (attr->rootWindowXorigin < 0 ||
- attr->rootWindowYorigin < 0 ||
- attr->rootWindowXorigin + attr->rootWindowWidth > 32767 ||
- attr->rootWindowYorigin + attr->rootWindowHeight > 32767)
- return DMX_BAD_VALUE;
-
- /* The "root" window must fit within the global bounding box */
- if (attr->rootWindowXorigin
- + attr->rootWindowWidth > (unsigned)dmxGlobalWidth ||
- attr->rootWindowYorigin
- + attr->rootWindowHeight > (unsigned)dmxGlobalHeight)
- return DMX_BAD_VALUE;
-
- /* FIXME: Handle the rest of the illegal value checking */
- }
-
- /* No illegal values found */
- if (errorScreen) *errorScreen = 0;
-
- for (i = 0; i < nscreens; i++) {
- DMXScreenAttributesPtr attr = &attribs[i];
- int idx = screens[i];
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
-
- dmxLog(dmxInfo, "Changing screen #%d attributes "
- "from %dx%d+%d+%d %dx%d+%d+%d +%d+%d "
- "to %dx%d+%d+%d %dx%d+%d+%d +%d+%d\n",
- idx,
- dmxScreen->scrnWidth, dmxScreen->scrnHeight,
- dmxScreen->scrnX, dmxScreen->scrnY,
- dmxScreen->rootWidth, dmxScreen->rootHeight,
- dmxScreen->rootX, dmxScreen->rootY,
- dmxScreen->rootXOrigin, dmxScreen->rootYOrigin,
- attr->screenWindowWidth, attr->screenWindowHeight,
- attr->screenWindowXoffset, attr->screenWindowYoffset,
- attr->rootWindowWidth, attr->rootWindowHeight,
- attr->rootWindowXoffset, attr->rootWindowYoffset,
- attr->rootWindowXorigin, attr->rootWindowYorigin);
-
- /* Configure "screen" window */
- dmxConfigureScreenWindow(idx,
- attr->screenWindowXoffset,
- attr->screenWindowYoffset,
- attr->screenWindowWidth,
- attr->screenWindowHeight);
-
- /* Configure "root" window */
- dmxConfigureRootWindow(idx,
- attr->rootWindowXoffset,
- attr->rootWindowYoffset,
- attr->rootWindowWidth,
- attr->rootWindowHeight);
-
-
- /* Set "root" window's origin */
- dmxSetRootWindowOrigin(idx,
- attr->rootWindowXorigin,
- attr->rootWindowYorigin);
- }
-
- /* Adjust the cursor boundaries */
- dmxAdjustCursorBoundaries();
-
- /* Force completion of the changes */
- dmxSync(NULL, TRUE);
-
- return Success;
-}
-
-/** Configure the attributes of the global desktop. */
-int dmxConfigureDesktop(DMXDesktopAttributesPtr attribs)
-{
- if (attribs->width <= 0 || attribs->width >= 32767 ||
- attribs->height <= 0 || attribs->height >= 32767)
- return DMX_BAD_VALUE;
-
- /* If the desktop is shrinking, adjust the "root" windows on each
- * "screen" window to only show the visible desktop. Also, handle
- * the special case where the desktop shrinks such that the it no
- * longer overlaps an portion of a "screen" window. */
- if (attribs->width < dmxGlobalWidth || attribs->height < dmxGlobalHeight) {
- int i;
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- if (dmxScreen->rootXOrigin
- + dmxScreen->rootWidth > attribs->width ||
- dmxScreen->rootYOrigin
- + dmxScreen->rootHeight > attribs->height) {
- int w, h;
- if ((w = attribs->width - dmxScreen->rootXOrigin) < 0) w = 0;
- if ((h = attribs->height - dmxScreen->rootYOrigin) < 0) h = 0;
- if (w > dmxScreen->scrnWidth) w = dmxScreen->scrnWidth;
- if (h > dmxScreen->scrnHeight) h = dmxScreen->scrnHeight;
- if (w > dmxScreen->rootWidth) w = dmxScreen->rootWidth;
- if (h > dmxScreen->rootHeight) h = dmxScreen->rootHeight;
- dmxConfigureRootWindow(i,
- dmxScreen->rootX,
- dmxScreen->rootY,
- w, h);
- }
- }
- }
-
- /* Set the global width/height */
- dmxSetWidthHeight(attribs->width, attribs->height);
-
- /* Handle shift[XY] changes */
- if (attribs->shiftX || attribs->shiftY) {
- int i;
- for (i = 0; i < dmxNumScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- WindowPtr pChild = pScreen->root->firstChild;
- while (pChild) {
- /* Adjust child window's position */
- pScreen->MoveWindow(pChild,
- pChild->origin.x - wBorderWidth(pChild)
- - attribs->shiftX,
- pChild->origin.y - wBorderWidth(pChild)
- - attribs->shiftY,
- pChild->nextSib,
- VTMove);
-
- /* Note that the call to MoveWindow will eventually call
- * dmxPositionWindow which will automatically create a
- * window if it is now exposed on screen (for lazy
- * window creation optimization) and it will properly
- * set the offscreen flag.
- */
-
- pChild = pChild->nextSib;
- }
- }
- }
-
- /* Update connection block, Xinerama, etc. -- these appears to
- * already be handled in dmxConnectionBlockCallback(), which is
- * called from dmxAdjustCursorBoundaries() [below]. */
-
- /* Adjust the cursor boundaries */
- dmxAdjustCursorBoundaries();
-
- /* Force completion of the changes */
- dmxSync(NULL, TRUE);
-
- return Success;
-}
-#endif
-
-/** Create the scratch GCs per depth. */
-static void dmxBECreateScratchGCs(int scrnNum)
-{
- ScreenPtr pScreen = screenInfo.screens[scrnNum];
- GCPtr *ppGC = pScreen->GCperDepth;
- int i;
-
- for (i = 0; i <= pScreen->numDepths; i++)
- dmxBECreateGC(pScreen, ppGC[i]);
-}
-
-#ifdef PANORAMIX
-static Bool FoundPixImage;
-
-/** Search the Xinerama XRT_PIXMAP resources for the pixmap that needs
- * to have its image restored. When it is found, see if there is
- * another screen with the same image. If so, copy the pixmap image
- * from the existing screen to the newly created pixmap. */
-static void dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type,
- pointer p)
-{
- if ((type & TypeMask) == (XRT_PIXMAP & TypeMask)) {
- PixmapPtr pDst = (PixmapPtr)p;
- int idx = pDst->drawable.pScreen->myNum;
- PanoramiXRes *pXinPix = (PanoramiXRes *)value;
- PixmapPtr pPix;
- int i;
-
- dixLookupResourceByType((pointer*) &pPix, pXinPix->info[idx].id,
- RT_PIXMAP, NullClient, DixUnknownAccess);
- if (pPix != pDst) return; /* Not a match.... Next! */
-
- FOR_NSCREENS(i) {
- PixmapPtr pSrc;
- dmxPixPrivPtr pSrcPriv = NULL;
-
- if (i == idx) continue; /* Self replication is bad */
-
- dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id,
- RT_PIXMAP, NullClient, DixUnknownAccess);
- pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
- if (pSrcPriv->pixmap) {
- DMXScreenInfo *dmxSrcScreen = &dmxScreens[i];
- DMXScreenInfo *dmxDstScreen = &dmxScreens[idx];
- dmxPixPrivPtr pDstPriv = DMX_GET_PIXMAP_PRIV(pDst);
- XImage *img;
- int j;
- XlibGC gc = NULL;
-
- /* This should never happen, but just in case.... */
- if (pSrc->drawable.width != pDst->drawable.width ||
- pSrc->drawable.height != pDst->drawable.height)
- return;
-
- /* Copy from src pixmap to dst pixmap */
- img = XGetImage(dmxSrcScreen->beDisplay,
- pSrcPriv->pixmap,
- 0, 0,
- pSrc->drawable.width, pSrc->drawable.height,
- -1,
- ZPixmap);
-
- for (j = 0; j < dmxDstScreen->beNumPixmapFormats; j++) {
- if (dmxDstScreen->bePixmapFormats[j].depth == img->depth) {
- unsigned long m;
- XGCValues v;
-
- m = GCFunction | GCPlaneMask | GCClipMask;
- v.function = GXcopy;
- v.plane_mask = AllPlanes;
- v.clip_mask = None;
-
- gc = XCreateGC(dmxDstScreen->beDisplay,
- dmxDstScreen->scrnDefDrawables[j],
- m, &v);
- break;
- }
- }
-
- if (gc) {
- XPutImage(dmxDstScreen->beDisplay,
- pDstPriv->pixmap,
- gc, img, 0, 0, 0, 0,
- pDst->drawable.width, pDst->drawable.height);
- XFreeGC(dmxDstScreen->beDisplay, gc);
- FoundPixImage = True;
- } else {
- dmxLog(dmxWarning, "Could not create GC\n");
- }
-
- XDestroyImage(img);
- return;
- }
- }
- }
-}
-#endif
-
-/** Restore the pixmap image either from another screen or from an image
- * that was saved when the screen was previously detached. */
-static void dmxBERestorePixmap(PixmapPtr pPixmap)
-{
-#ifdef PANORAMIX
- int i;
-
- /* If Xinerama is not active, there's nothing we can do (see comment
- * in #else below for more info). */
- if (noPanoramiXExtension) {
- dmxLog(dmxWarning, "Cannot restore pixmap image\n");
- return;
- }
-
- FoundPixImage = False;
- for (i = currentMaxClients; --i >= 0; )
- if (clients[i])
- FindAllClientResources(clients[i], dmxBERestorePixmapImage,
- (pointer)pPixmap);
-
- /* No corresponding pixmap image was found on other screens, so we
- * need to copy it from the saved image when the screen was detached
- * (if available). */
- if (!FoundPixImage) {
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
-
- if (pPixPriv->detachedImage) {
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- XlibGC gc = NULL;
-
- for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
- if (dmxScreen->bePixmapFormats[i].depth ==
- pPixPriv->detachedImage->depth) {
- unsigned long m;
- XGCValues v;
-
- m = GCFunction | GCPlaneMask | GCClipMask;
- v.function = GXcopy;
- v.plane_mask = AllPlanes;
- v.clip_mask = None;
-
- gc = XCreateGC(dmxScreen->beDisplay,
- dmxScreen->scrnDefDrawables[i],
- m, &v);
- break;
- }
- }
-
- if (gc) {
- XPutImage(dmxScreen->beDisplay,
- pPixPriv->pixmap,
- gc,
- pPixPriv->detachedImage,
- 0, 0, 0, 0,
- pPixmap->drawable.width, pPixmap->drawable.height);
- XFreeGC(dmxScreen->beDisplay, gc);
- } else {
- dmxLog(dmxWarning, "Cannot restore pixmap image\n");
- }
-
- XDestroyImage(pPixPriv->detachedImage);
- pPixPriv->detachedImage = NULL;
- } else {
- dmxLog(dmxWarning, "Cannot restore pixmap image\n");
- }
- }
-#else
- /* If Xinerama is not enabled, then there is no other copy of the
- * pixmap image that we can restore. Saving all pixmap data is not
- * a feasible option since there is no mechanism for updating pixmap
- * data when a screen is detached, which means that the data that
- * was previously saved would most likely be out of date. */
- dmxLog(dmxWarning, "Cannot restore pixmap image\n");
- return;
-#endif
-}
-
-/** Create resources on the back-end server. This function is called
- * from #dmxAttachScreen() via the dix layer's FindAllResources
- * function. It walks all resources, compares them to the screen
- * number passed in as \a n and calls the appropriate DMX function to
- * create the associated resource on the back-end server. */
-static void dmxBECreateResources(pointer value, XID id, RESTYPE type,
- pointer n)
-{
- int scrnNum = (uintptr_t)n;
- ScreenPtr pScreen = screenInfo.screens[scrnNum];
-
- if ((type & TypeMask) == (RT_WINDOW & TypeMask)) {
- /* Window resources are created below in dmxBECreateWindowTree */
- } else if ((type & TypeMask) == (RT_PIXMAP & TypeMask)) {
- PixmapPtr pPix = value;
- if (pPix->drawable.pScreen->myNum == scrnNum) {
- dmxBECreatePixmap(pPix);
- dmxBERestorePixmap(pPix);
- }
- } else if ((type & TypeMask) == (RT_GC & TypeMask)) {
- GCPtr pGC = value;
- if (pGC->pScreen->myNum == scrnNum) {
- /* Create the GC on the back-end server */
- dmxBECreateGC(pScreen, pGC);
- /* Create any pixmaps associated with this GC */
- if (!pGC->tileIsPixel) {
- dmxBECreatePixmap(pGC->tile.pixmap);
- dmxBERestorePixmap(pGC->tile.pixmap);
- }
- if (pGC->stipple != pScreen->PixmapPerDepth[0]) {
- dmxBECreatePixmap(pGC->stipple);
- dmxBERestorePixmap(pGC->stipple);
- }
- if (pGC->font != defaultFont) {
- (void)dmxBELoadFont(pScreen, pGC->font);
- }
- /* Update the GC on the back-end server */
- dmxChangeGC(pGC, -1L);
- }
- } else if ((type & TypeMask) == (RT_FONT & TypeMask)) {
- (void)dmxBELoadFont(pScreen, (FontPtr)value);
- } else if ((type & TypeMask) == (RT_CURSOR & TypeMask)) {
- dmxBECreateCursor(pScreen, (CursorPtr)value);
- } else if ((type & TypeMask) == (RT_COLORMAP & TypeMask)) {
- ColormapPtr pCmap = value;
- if (pCmap->pScreen->myNum == scrnNum)
- (void)dmxBECreateColormap((ColormapPtr)value);
-#if 0
- /* TODO: Recreate Picture and GlyphSet resources */
- } else if ((type & TypeMask) == (PictureType & TypeMask)) {
- /* Picture resources are created when windows are created */
- } else if ((type & TypeMask) == (GlyphSetType & TypeMask)) {
- dmxBEFreeGlyphSet(pScreen, (GlyphSetPtr)value);
-#endif
- } else {
- /* Other resource types??? */
- }
-}
-
-/** Create window hierachy on back-end server. The window tree is
- * created in a special order (bottom most subwindow first) so that the
- * #dmxCreateNonRootWindow() function does not need to recursively call
- * itself to create each window's parents. This is required so that we
- * have the opportunity to create each window's border and background
- * pixmaps (where appropriate) before the window is created. */
-static void dmxBECreateWindowTree(int idx)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
- WindowPtr pRoot = screenInfo.screens[idx]->root;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot);
- WindowPtr pWin;
-
- /* Create the pixmaps associated with the root window */
- if (!pRoot->borderIsPixel) {
- dmxBECreatePixmap(pRoot->border.pixmap);
- dmxBERestorePixmap(pRoot->border.pixmap);
- }
- if (pRoot->backgroundState == BackgroundPixmap) {
- dmxBECreatePixmap(pRoot->background.pixmap);
- dmxBERestorePixmap(pRoot->background.pixmap);
- }
-
- /* Create root window first */
- dmxScreen->rootWin = pWinPriv->window = dmxCreateRootWindow(pRoot);
- XMapWindow(dmxScreen->beDisplay, dmxScreen->rootWin);
-
- pWin = pRoot->lastChild;
- while (pWin) {
- pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
-
- /* Create the pixmaps regardless of whether or not the
- * window is created or not due to lazy window creation.
- */
- if (!pWin->borderIsPixel) {
- dmxBECreatePixmap(pWin->border.pixmap);
- dmxBERestorePixmap(pWin->border.pixmap);
- }
- if (pWin->backgroundState == BackgroundPixmap) {
- dmxBECreatePixmap(pWin->background.pixmap);
- dmxBERestorePixmap(pWin->background.pixmap);
- }
-
- /* Reset the window attributes */
- dmxGetDefaultWindowAttributes(pWin,
- &pWinPriv->cmap,
- &pWinPriv->visual);
-
- /* Create the window */
- if (pWinPriv->mapped && !pWinPriv->offscreen)
- dmxCreateAndRealizeWindow(pWin, TRUE);
-
- /* Next, create the bottom-most child */
- if (pWin->lastChild) {
- pWin = pWin->lastChild;
- continue;
- }
-
- /* If the window has no children, move on to the next higher window */
- while (!pWin->prevSib && (pWin != pRoot))
- pWin = pWin->parent;
-
- if (pWin->prevSib) {
- pWin = pWin->prevSib;
- continue;
- }
-
- /* When we reach the root window, we are finished */
- if (pWin == pRoot)
- break;
- }
-}
-
-/* Refresh screen by generating exposure events for all windows */
-static void dmxForceExposures(int idx)
-{
- ScreenPtr pScreen = screenInfo.screens[idx];
- WindowPtr pRoot = pScreen->root;
- Bool anyMarked = FALSE;
- WindowPtr pChild;
-
- for (pChild = pRoot->firstChild; pChild; pChild = pChild->nextSib)
- anyMarked |= pScreen->MarkOverlappedWindows(pChild, pChild,
- (WindowPtr *)NULL);
- if (anyMarked) {
- /* If any windows have been marked, set the root window's
- * clipList to be broken since it will be recalculated in
- * ValidateTree()
- */
- RegionBreak(&pRoot->clipList);
- pScreen->ValidateTree(pRoot, NULL, VTBroken);
- pScreen->HandleExposures(pRoot);
- if (pScreen->PostValidateTree)
- pScreen->PostValidateTree(pRoot, NULL, VTBroken);
- }
-}
-
-/** Compare the new and old screens to see if they are compatible. */
-static Bool dmxCompareScreens(DMXScreenInfo *new, DMXScreenInfo *old)
-{
- int i;
-
- if (new->beWidth != old->beWidth) return FALSE;
- if (new->beHeight != old->beHeight) return FALSE;
- if (new->beDepth != old->beDepth) return FALSE;
- if (new->beBPP != old->beBPP) return FALSE;
-
- if (new->beNumDepths != old->beNumDepths) return FALSE;
- for (i = 0; i < old->beNumDepths; i++)
- if (new->beDepths[i] != old->beDepths[i]) return FALSE;
-
- if (new->beNumPixmapFormats != old->beNumPixmapFormats) return FALSE;
- for (i = 0; i < old->beNumPixmapFormats; i++) {
- if (new->bePixmapFormats[i].depth !=
- old->bePixmapFormats[i].depth) return FALSE;
- if (new->bePixmapFormats[i].bits_per_pixel !=
- old->bePixmapFormats[i].bits_per_pixel) return FALSE;
- if (new->bePixmapFormats[i].scanline_pad !=
- old->bePixmapFormats[i].scanline_pad) return FALSE;
- }
-
- if (new->beNumVisuals != old->beNumVisuals) return FALSE;
- for (i = 0; i < old->beNumVisuals; i++) {
- if (new->beVisuals[i].visualid !=
- old->beVisuals[i].visualid) return FALSE;
- if (new->beVisuals[i].screen !=
- old->beVisuals[i].screen) return FALSE;
- if (new->beVisuals[i].depth !=
- old->beVisuals[i].depth) return FALSE;
- if (new->beVisuals[i].class !=
- old->beVisuals[i].class) return FALSE;
- if (new->beVisuals[i].red_mask !=
- old->beVisuals[i].red_mask) return FALSE;
- if (new->beVisuals[i].green_mask !=
- old->beVisuals[i].green_mask) return FALSE;
- if (new->beVisuals[i].blue_mask !=
- old->beVisuals[i].blue_mask) return FALSE;
- if (new->beVisuals[i].colormap_size !=
- old->beVisuals[i].colormap_size) return FALSE;
- if (new->beVisuals[i].bits_per_rgb !=
- old->beVisuals[i].bits_per_rgb) return FALSE;
- }
-
- if (new->beDefVisualIndex != old->beDefVisualIndex) return FALSE;
-
- return TRUE;
-}
-
-/** Restore Render's picture */
-static void dmxBERestoreRenderPict(pointer value, XID id, pointer n)
-{
- PicturePtr pPicture = value; /* The picture */
- DrawablePtr pDraw = pPicture->pDrawable; /* The picture's drawable */
- int scrnNum = (uintptr_t)n;
-
- if (pDraw->pScreen->myNum != scrnNum) {
- /* Picture not on the screen we are restoring*/
- return;
- }
-
- if (pDraw->type == DRAWABLE_PIXMAP) {
- PixmapPtr pPixmap = (PixmapPtr)pDraw;
-
- /* Create and restore the pixmap drawable */
- dmxBECreatePixmap(pPixmap);
- dmxBERestorePixmap(pPixmap);
- }
-
- dmxBECreatePicture(pPicture);
-}
-
-/** Restore Render's glyphs */
-static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n)
-{
- GlyphSetPtr glyphSet = value;
- int scrnNum = (uintptr_t)n;
- dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
- DMXScreenInfo *dmxScreen = &dmxScreens[scrnNum];
- GlyphRefPtr table;
- char *images;
- Glyph *gids;
- XGlyphInfo *glyphs;
- char *pos;
- int beret;
- int len_images = 0;
- int i;
- int ctr;
-
- if (glyphPriv->glyphSets[scrnNum]) {
- /* Only restore glyphs on the screen we are attaching */
- return;
- }
-
- /* First we must create the glyph set on the backend. */
- if ((beret = dmxBECreateGlyphSet(scrnNum, glyphSet)) != Success) {
- dmxLog(dmxWarning,
- "\tdmxBERestoreRenderGlyph failed to create glyphset!\n");
- return;
- }
-
- /* Now for the complex part, restore the glyph data */
- table = glyphSet->hash.table;
-
- /* We need to know how much memory to allocate for this part */
- for (i = 0; i < glyphSet->hash.hashSet->size; i++) {
- GlyphRefPtr gr = &table[i];
- GlyphPtr gl = gr->glyph;
-
- if (!gl || gl == DeletedGlyph) continue;
- len_images += gl->size - sizeof(gl->info);
- }
-
- /* Now allocate the memory we need */
- images = calloc(len_images, sizeof(char));
- gids = malloc(glyphSet->hash.tableEntries*sizeof(Glyph));
- glyphs = malloc(glyphSet->hash.tableEntries*sizeof(XGlyphInfo));
-
- pos = images;
- ctr = 0;
-
- /* Fill the allocated memory with the proper data */
- for (i = 0; i < glyphSet->hash.hashSet->size; i++) {
- GlyphRefPtr gr = &table[i];
- GlyphPtr gl = gr->glyph;
-
- if (!gl || gl == DeletedGlyph) continue;
-
- /* First lets put the data into gids */
- gids[ctr] = gr->signature;
-
- /* Next do the glyphs data structures */
- glyphs[ctr].width = gl->info.width;
- glyphs[ctr].height = gl->info.height;
- glyphs[ctr].x = gl->info.x;
- glyphs[ctr].y = gl->info.y;
- glyphs[ctr].xOff = gl->info.xOff;
- glyphs[ctr].yOff = gl->info.yOff;
-
- /* Copy the images from the DIX's data into the buffer */
- memcpy(pos, gl+1, gl->size - sizeof(gl->info));
- pos += gl->size - sizeof(gl->info);
- ctr++;
- }
-
- /* Now restore the glyph data */
- XRenderAddGlyphs(dmxScreen->beDisplay, glyphPriv->glyphSets[scrnNum],
- gids,glyphs, glyphSet->hash.tableEntries, images,
- len_images);
-
- /* Clean up */
- free(images);
- free(gids);
- free(glyphs);
-}
-
-/** Reattach previously detached back-end screen. */
-int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
-{
- ScreenPtr pScreen;
- DMXScreenInfo *dmxScreen;
- CARD32 scrnNum = idx;
- DMXScreenInfo oldDMXScreen;
- int i;
-
- /* Return failure if dynamic addition/removal of screens is disabled */
- if (!dmxAddRemoveScreens) {
- dmxLog(dmxWarning,
- "Attempting to add a screen, but the AddRemoveScreen\n");
- dmxLog(dmxWarning,
- "extension has not been enabled. To enable this extension\n");
- dmxLog(dmxWarning,
- "add the \"-addremovescreens\" option either to the command\n");
- dmxLog(dmxWarning,
- "line or in the configuration file.\n");
- return 1;
- }
-
- /* Cannot add a screen that does not exist */
- if (idx < 0 || idx >= dmxNumScreens) return 1;
- pScreen = screenInfo.screens[idx];
- dmxScreen = &dmxScreens[idx];
-
- /* Cannot attach to a screen that is already opened */
- if (dmxScreen->beDisplay) {
- dmxLog(dmxWarning,
- "Attempting to add screen #%d but a screen already exists\n",
- idx);
- return 1;
- }
-
- dmxLogOutput(dmxScreen, "Attaching screen #%d\n", idx);
-
- /* Save old info */
- oldDMXScreen = *dmxScreen;
-
- /* Copy the name to the new screen */
- dmxScreen->name = strdup(attr->displayName);
-
- /* Open display and get all of the screen info */
- if (!dmxOpenDisplay(dmxScreen)) {
- dmxLog(dmxWarning,
- "dmxOpenDisplay: Unable to open display %s\n",
- dmxScreen->name);
-
- /* Restore the old screen */
- *dmxScreen = oldDMXScreen;
- return 1;
- }
-
- dmxSetErrorHandler(dmxScreen);
- dmxCheckForWM(dmxScreen);
- dmxGetScreenAttribs(dmxScreen);
-
- if (!dmxGetVisualInfo(dmxScreen)) {
- dmxLog(dmxWarning, "dmxGetVisualInfo: No matching visuals found\n");
- XFree(dmxScreen->beVisuals);
- XCloseDisplay(dmxScreen->beDisplay);
-
- /* Restore the old screen */
- *dmxScreen = oldDMXScreen;
- return 1;
- }
-
- dmxGetColormaps(dmxScreen);
- dmxGetPixmapFormats(dmxScreen);
-
- /* Verify that the screen to be added has the same info as the
- * previously added screen. */
- if (!dmxCompareScreens(dmxScreen, &oldDMXScreen)) {
- dmxLog(dmxWarning,
- "New screen data (%s) does not match previously\n",
- dmxScreen->name);
- dmxLog(dmxWarning,
- "attached screen data (%s)\n",
- oldDMXScreen.name);
- dmxLog(dmxWarning,
- "All data must match in order to attach to screen #%d\n",
- idx);
- XFree(dmxScreen->beVisuals);
- XFree(dmxScreen->beDepths);
- XFree(dmxScreen->bePixmapFormats);
- XCloseDisplay(dmxScreen->beDisplay);
-
- /* Restore the old screen */
- *dmxScreen = oldDMXScreen;
- return 1;
- }
-
- /* Initialize the BE screen resources */
- dmxBEScreenInit(idx, screenInfo.screens[idx]);
-
- /* TODO: Handle GLX visual initialization. GLXProxy needs to be
- * updated to handle dynamic addition/removal of screens. */
-
- /* Create default stipple */
- dmxBECreatePixmap(pScreen->PixmapPerDepth[0]);
- dmxBERestorePixmap(pScreen->PixmapPerDepth[0]);
-
- /* Create the scratch GCs */
- dmxBECreateScratchGCs(idx);
-
- /* Create the default font */
- (void)dmxBELoadFont(pScreen, defaultFont);
-
- /* Create all resources that don't depend on windows */
- for (i = currentMaxClients; --i >= 0; )
- if (clients[i])
- FindAllClientResources(clients[i], dmxBECreateResources,
- (pointer)(uintptr_t)idx);
-
- /* Create window hierarchy (top down) */
- dmxBECreateWindowTree(idx);
-
- /* Restore the picture state for RENDER */
- for (i = currentMaxClients; --i >= 0; )
- if (clients[i])
- FindClientResourcesByType(clients[i],PictureType,
- dmxBERestoreRenderPict,
- (pointer)(uintptr_t)idx);
-
- /* Restore the glyph state for RENDER */
- for (i = currentMaxClients; --i >= 0; )
- if (clients[i])
- FindClientResourcesByType(clients[i],GlyphSetType,
- dmxBERestoreRenderGlyph,
- (pointer)(uintptr_t)idx);
-
- /* Refresh screen by generating exposure events for all windows */
- dmxForceExposures(idx);
-
- dmxSync(&dmxScreens[idx], TRUE);
-
- /* We used these to compare the old and new screens. They are no
- * longer needed since we have a newly attached screen, so we can
- * now free the old screen's resources. */
- XFree(oldDMXScreen.beVisuals);
- XFree(oldDMXScreen.beDepths);
- XFree(oldDMXScreen.bePixmapFormats);
- /* TODO: should oldDMXScreen.name be freed?? */
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension)
- return dmxConfigureScreenWindows(1, &scrnNum, attr, NULL);
- else
-#endif
- return 0; /* Success */
-}
-
-/*
- * Resources that may have state on the BE server and need to be freed:
- *
- * RT_NONE
- * RT_WINDOW
- * RT_PIXMAP
- * RT_GC
- * RT_FONT
- * RT_CURSOR
- * RT_COLORMAP
- * RT_CMAPENTRY
- * RT_OTHERCLIENT
- * RT_PASSIVEGRAB
- * XRT_WINDOW
- * XRT_PIXMAP
- * XRT_GC
- * XRT_COLORMAP
- * XRT_PICTURE
- * PictureType
- * PictFormatType
- * GlyphSetType
- * ClientType
- * EventType
- * RT_INPUTCLIENT
- * XETrapType
- * RTCounter
- * RTAwait
- * RTAlarmClient
- * RT_XKBCLIENT
- * RTContext
- * TagResType
- * StalledResType
- * SecurityAuthorizationResType
- * RTEventClient
- * __glXContextRes
- * __glXClientRes
- * __glXPixmapRes
- * __glXWindowRes
- * __glXPbufferRes
- */
-
-#ifdef PANORAMIX
-/** Search the Xinerama XRT_PIXMAP resources for the pixmap that needs
- * to have its image saved. */
-static void dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type,
- pointer p)
-{
- if ((type & TypeMask) == (XRT_PIXMAP & TypeMask)) {
- PixmapPtr pDst = (PixmapPtr)p;
- int idx = pDst->drawable.pScreen->myNum;
- PanoramiXRes *pXinPix = (PanoramiXRes *)value;
- PixmapPtr pPix;
- int i;
-
- dixLookupResourceByType((pointer*) &pPix, pXinPix->info[idx].id,
- RT_PIXMAP, NullClient, DixUnknownAccess);
- if (pPix != pDst) return; /* Not a match.... Next! */
-
- FOR_NSCREENS(i) {
- PixmapPtr pSrc;
- dmxPixPrivPtr pSrcPriv = NULL;
-
- if (i == idx) continue; /* Self replication is bad */
-
- dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id,
- RT_PIXMAP, NullClient, DixUnknownAccess);
- pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
- if (pSrcPriv->pixmap) {
- FoundPixImage = True;
- return;
- }
- }
- }
-}
-#endif
-
-/** Save the pixmap image only when there is not another screen with
- * that pixmap from which the image can be read when the screen is
- * reattached. To do this, we first try to find a pixmap on another
- * screen corresponding to the one we are trying to save. If we find
- * one, then we do not need to save the image data since during
- * reattachment, the image data can be read from that other pixmap.
- * However, if we do not find one, then we need to save the image data.
- * The common case for these are for the default stipple and root
- * tile. */
-static void dmxBESavePixmap(PixmapPtr pPixmap)
-{
-#ifdef PANORAMIX
- int i;
-
- /* If Xinerama is not active, there's nothing we can do (see comment
- * in #else below for more info). */
- if (noPanoramiXExtension) return;
-
- FoundPixImage = False;
- for (i = currentMaxClients; --i >= 0; )
- if (clients[i])
- FindAllClientResources(clients[i], dmxBEFindPixmapImage,
- (pointer)pPixmap);
-
- /* Save the image only if there is no other screens that have a
- * pixmap that corresponds to the one we are trying to save. */
- if (!FoundPixImage) {
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
-
- if (!pPixPriv->detachedImage) {
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-
- pPixPriv->detachedImage = XGetImage(dmxScreen->beDisplay,
- pPixPriv->pixmap,
- 0, 0,
- pPixmap->drawable.width,
- pPixmap->drawable.height,
- -1,
- ZPixmap);
- if (!pPixPriv->detachedImage)
- dmxLog(dmxWarning, "Cannot save pixmap image\n");
- }
- }
-#else
- /* NOTE: The only time there is a pixmap on another screen that
- * corresponds to the one we are trying to save is when Xinerama is
- * active. Otherwise, the pixmap image data is only stored on a
- * single screen, which means that once it is detached, that data is
- * lost. We could save the data here, but then that would require
- * us to implement the ability for Xdmx to keep the pixmap up to
- * date while the screen is detached, which is beyond the scope of
- * the current project. */
- return;
-#endif
-}
-
-/** Destroy resources on the back-end server. This function is called
- * from #dmxDetachScreen() via the dix layer's FindAllResources
- * function. It walks all resources, compares them to the screen
- * number passed in as \a n and calls the appropriate DMX function to
- * free the associated resource on the back-end server. */
-static void dmxBEDestroyResources(pointer value, XID id, RESTYPE type,
- pointer n)
-{
- int scrnNum = (uintptr_t)n;
- ScreenPtr pScreen = screenInfo.screens[scrnNum];
-
- if ((type & TypeMask) == (RT_WINDOW & TypeMask)) {
- /* Window resources are destroyed below in dmxBEDestroyWindowTree */
- } else if ((type & TypeMask) == (RT_PIXMAP & TypeMask)) {
- PixmapPtr pPix = value;
- if (pPix->drawable.pScreen->myNum == scrnNum) {
- dmxBESavePixmap(pPix);
- dmxBEFreePixmap(pPix);
- }
- } else if ((type & TypeMask) == (RT_GC & TypeMask)) {
- GCPtr pGC = value;
- if (pGC->pScreen->myNum == scrnNum)
- dmxBEFreeGC(pGC);
- } else if ((type & TypeMask) == (RT_FONT & TypeMask)) {
- dmxBEFreeFont(pScreen, (FontPtr)value);
- } else if ((type & TypeMask) == (RT_CURSOR & TypeMask)) {
- dmxBEFreeCursor(pScreen, (CursorPtr)value);
- } else if ((type & TypeMask) == (RT_COLORMAP & TypeMask)) {
- ColormapPtr pCmap = value;
- if (pCmap->pScreen->myNum == scrnNum)
- dmxBEFreeColormap((ColormapPtr)value);
- } else if ((type & TypeMask) == (PictureType & TypeMask)) {
- PicturePtr pPict = value;
- if (pPict->pDrawable->pScreen->myNum == scrnNum) {
- /* Free the pixmaps on the backend if needed */
- if (pPict->pDrawable->type == DRAWABLE_PIXMAP) {
- PixmapPtr pPixmap = (PixmapPtr)(pPict->pDrawable);
- dmxBESavePixmap(pPixmap);
- dmxBEFreePixmap(pPixmap);
- }
- dmxBEFreePicture((PicturePtr)value);
- }
- } else if ((type & TypeMask) == (GlyphSetType & TypeMask)) {
- dmxBEFreeGlyphSet(pScreen, (GlyphSetPtr)value);
- } else {
- /* Other resource types??? */
- }
-}
-
-/** Destroy the scratch GCs that are created per depth. */
-static void dmxBEDestroyScratchGCs(int scrnNum)
-{
- ScreenPtr pScreen = screenInfo.screens[scrnNum];
- GCPtr *ppGC = pScreen->GCperDepth;
- int i;
-
- for (i = 0; i <= pScreen->numDepths; i++)
- dmxBEFreeGC(ppGC[i]);
-}
-
-/** Destroy window hierachy on back-end server. To ensure that all
- * XDestroyWindow() calls succeed, they must be performed in a bottom
- * up order so that windows are not destroyed before their children.
- * XDestroyWindow(), which is called from #dmxBEDestroyWindow(), will
- * destroy a window as well as all of it's children. */
-static void dmxBEDestroyWindowTree(int idx)
-{
- WindowPtr pWin = screenInfo.screens[idx]->root;
- WindowPtr pChild = pWin;
-
- while (1) {
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
-
- /* Destroy the window */
- dmxBEDestroyWindow(pChild);
-
- /* Make sure we destroy the window's border and background
- * pixmaps if they exist */
- if (!pChild->borderIsPixel) {
- dmxBESavePixmap(pChild->border.pixmap);
- dmxBEFreePixmap(pChild->border.pixmap);
- }
- if (pChild->backgroundState == BackgroundPixmap) {
- dmxBESavePixmap(pChild->background.pixmap);
- dmxBEFreePixmap(pChild->background.pixmap);
- }
-
- while (!pChild->nextSib && (pChild != pWin)) {
- pChild = pChild->parent;
- dmxBEDestroyWindow(pChild);
- if (!pChild->borderIsPixel) {
- dmxBESavePixmap(pChild->border.pixmap);
- dmxBEFreePixmap(pChild->border.pixmap);
- }
- if (pChild->backgroundState == BackgroundPixmap) {
- dmxBESavePixmap(pChild->background.pixmap);
- dmxBEFreePixmap(pChild->background.pixmap);
- }
- }
-
- if (pChild == pWin)
- break;
-
- pChild = pChild->nextSib;
- }
-}
-
-/** Detach back-end screen. */
-int dmxDetachScreen(int idx)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
- int i;
-
- /* Return failure if dynamic addition/removal of screens is disabled */
- if (!dmxAddRemoveScreens) {
- dmxLog(dmxWarning,
- "Attempting to remove a screen, but the AddRemoveScreen\n");
- dmxLog(dmxWarning,
- "extension has not been enabled. To enable this extension\n");
- dmxLog(dmxWarning,
- "add the \"-addremovescreens\" option either to the command\n");
- dmxLog(dmxWarning,
- "line or in the configuration file.\n");
- return 1;
- }
-
- /* Cannot remove a screen that does not exist */
- if (idx < 0 || idx >= dmxNumScreens) return 1;
-
- /* Cannot detach from a screen that is not opened */
- if (!dmxScreen->beDisplay) {
- dmxLog(dmxWarning,
- "Attempting to remove screen #%d but it has not been opened\n",
- idx);
- return 1;
- }
-
- dmxLogOutput(dmxScreen, "Detaching screen #%d\n", idx);
-
- /* Detach input */
- dmxInputDetachAll(dmxScreen);
-
- /* Save all relevant state (TODO) */
-
- /* Free all non-window resources related to this screen */
- for (i = currentMaxClients; --i >= 0; )
- if (clients[i])
- FindAllClientResources(clients[i], dmxBEDestroyResources,
- (pointer)(uintptr_t)idx);
-
- /* Free scratch GCs */
- dmxBEDestroyScratchGCs(idx);
-
- /* Free window resources related to this screen */
- dmxBEDestroyWindowTree(idx);
-
- /* Free default stipple */
- dmxBESavePixmap(screenInfo.screens[idx]->PixmapPerDepth[0]);
- dmxBEFreePixmap(screenInfo.screens[idx]->PixmapPerDepth[0]);
-
- /* Free the remaining screen resources and close the screen */
- dmxBECloseScreen(screenInfo.screens[idx]);
-
- /* Adjust the cursor boundaries (paints detached console window) */
- dmxAdjustCursorBoundaries();
-
- return 0; /* Success */
-}
+/* + * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Author: + * Rickard E. (Rik) Faith <faith@redhat.com> + * Kevin E. Martin <kem@redhat.com> + * + */ + +/** \file + * This file provides the only interface to the X server extension support + * in programs/Xserver/Xext. Those programs should only include dmxext.h + */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include <stdlib.h> + +#include "dmx.h" +#include "dmxinit.h" +#include "dmxextension.h" +#include "dmxwindow.h" +#include "dmxcb.h" +#include "dmxcursor.h" +#include "dmxpixmap.h" +#include "dmxgc.h" +#include "dmxfont.h" +#include "dmxcmap.h" +#include "dmxpict.h" +#include "dmxinput.h" +#include "dmxsync.h" +#include "dmxscrinit.h" +#include "input/dmxinputinit.h" + +#include "windowstr.h" +#include "inputstr.h" /* For DeviceIntRec */ +#include <X11/extensions/dmxproto.h> /* For DMX_BAD_* */ +#include "cursorstr.h" + +/* The default font is declared in dix/globals.c, but is not included in + * _any_ header files. */ +extern FontPtr defaultFont; + +/** This routine provides information to the DMX protocol extension + * about a particular screen. */ +Bool dmxGetScreenAttributes(int physical, DMXScreenAttributesPtr attr) +{ + DMXScreenInfo *dmxScreen; + + if (physical < 0 || physical >= dmxNumScreens) return FALSE; + + dmxScreen = &dmxScreens[physical]; + attr->displayName = dmxScreen->name; +#ifdef PANORAMIX + attr->logicalScreen = noPanoramiXExtension ? dmxScreen->index : 0; +#else + attr->logicalScreen = dmxScreen->index; +#endif + + attr->screenWindowWidth = dmxScreen->scrnWidth; + attr->screenWindowHeight = dmxScreen->scrnHeight; + attr->screenWindowXoffset = dmxScreen->scrnX; + attr->screenWindowYoffset = dmxScreen->scrnY; + + attr->rootWindowWidth = dmxScreen->rootWidth; + attr->rootWindowHeight = dmxScreen->rootHeight; + attr->rootWindowXoffset = dmxScreen->rootX; + attr->rootWindowYoffset = dmxScreen->rootY; + + attr->rootWindowXorigin = dmxScreen->rootXOrigin; + attr->rootWindowYorigin = dmxScreen->rootYOrigin; + + return TRUE; +} + +/** This routine provides information to the DMX protocol extension + * about a particular window. */ +Bool dmxGetWindowAttributes(WindowPtr pWindow, DMXWindowAttributesPtr attr) +{ + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + + attr->screen = pWindow->drawable.pScreen->myNum; + attr->window = pWinPriv->window; + + attr->pos.x = pWindow->drawable.x; + attr->pos.y = pWindow->drawable.y; + attr->pos.width = pWindow->drawable.width; + attr->pos.height = pWindow->drawable.height; + + if (!pWinPriv->window || pWinPriv->offscreen) { + attr->vis.x = 0; + attr->vis.y = 0; + attr->vis.height = 0; + attr->vis.width = 0; + return pWinPriv->window ? TRUE : FALSE; + } + + /* Compute display-relative coordinates */ + attr->vis.x = pWindow->drawable.x; + attr->vis.y = pWindow->drawable.y; + attr->vis.width = pWindow->drawable.width; + attr->vis.height = pWindow->drawable.height; + + if (attr->pos.x < 0) { + attr->vis.x -= attr->pos.x; + attr->vis.width = attr->pos.x + attr->pos.width - attr->vis.x; + } + if (attr->pos.x + attr->pos.width > pWindow->drawable.pScreen->width) { + if (attr->pos.x < 0) + attr->vis.width = pWindow->drawable.pScreen->width; + else + attr->vis.width = pWindow->drawable.pScreen->width - attr->pos.x; + } + if (attr->pos.y < 0) { + attr->vis.y -= attr->pos.y; + attr->vis.height = attr->pos.y + attr->pos.height - attr->vis.y; + } + if (attr->pos.y + attr->pos.height > pWindow->drawable.pScreen->height) { + if (attr->pos.y < 0) + attr->vis.height = pWindow->drawable.pScreen->height; + else + attr->vis.height = pWindow->drawable.pScreen->height - attr->pos.y; + } + + /* Convert to window-relative coordinates */ + attr->vis.x -= attr->pos.x; + attr->vis.y -= attr->pos.y; + + return TRUE; +} + +void dmxGetDesktopAttributes(DMXDesktopAttributesPtr attr) +{ + attr->width = dmxGlobalWidth; + attr->height = dmxGlobalHeight; + attr->shiftX = 0; /* NOTE: The upper left hand corner of */ + attr->shiftY = 0; /* the desktop is always <0,0>. */ +} + +/** Return the total number of devices, not just #dmxNumInputs. The + * number returned should be the same as that returned by + * XListInputDevices. */ +int dmxGetInputCount(void) +{ + int i, total; + + for (total = i = 0; i < dmxNumInputs; i++) total += dmxInputs[i].numDevs; + return total; +} + +/** Return information about the device with id = \a deviceId. This + * information is primarily for the #ProcDMXGetInputAttributes() + * function, which does not have access to the appropriate data + * structure. */ +int dmxGetInputAttributes(int deviceId, DMXInputAttributesPtr attr) +{ + int i, j; + DMXInputInfo *dmxInput; + + if (deviceId < 0) return -1; + for (i = 0; i < dmxNumInputs; i++) { + dmxInput = &dmxInputs[i]; + for (j = 0; j < dmxInput->numDevs; j++) { + DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j]; + if (deviceId != dmxLocal->pDevice->id) continue; + attr->isCore = !!dmxLocal->isCore; + attr->sendsCore = !!dmxLocal->sendsCore; + attr->detached = !!dmxInput->detached; + attr->physicalScreen = -1; + attr->physicalId = -1; + attr->name = NULL; + switch (dmxLocal->extType) { + case DMX_LOCAL_TYPE_LOCAL: + attr->inputType = 0; + break; + case DMX_LOCAL_TYPE_CONSOLE: + attr->inputType = 1; + attr->name = dmxInput->name; + attr->physicalId = dmxLocal->deviceId; + break; + case DMX_LOCAL_TYPE_BACKEND: + case DMX_LOCAL_TYPE_COMMON: + attr->inputType = 2; + attr->physicalScreen = dmxInput->scrnIdx; + attr->name = dmxInput->name; + attr->physicalId = dmxLocal->deviceId; + break; + } + return 0; /* Success */ + } + } + return -1; /* Failure */ +} + +/** Reinitialized the cursor boundaries. */ +static void dmxAdjustCursorBoundaries(void) +{ + int i; + + dmxReInitOrigins(); + dmxInitOverlap(); + dmxComputeWidthHeight(DMX_NO_RECOMPUTE_BOUNDING_BOX); + dmxConnectionBlockCallback(); + for (i = 0; i < dmxNumInputs; i++) { + DMXInputInfo *dmxInput = &dmxInputs[i]; + if (!dmxInput->detached) dmxInputReInit(dmxInput); + } + + dmxCheckCursor(); + + for (i = 0; i < dmxNumInputs; i++) { + DMXInputInfo *dmxInput = &dmxInputs[i]; + if (!dmxInput->detached) dmxInputLateReInit(dmxInput); + } +} + +/** Add an input with the specified attributes. If the input is added, + * the physical id is returned in \a deviceId. */ +int dmxAddInput(DMXInputAttributesPtr attr, int *id) +{ + int retcode = BadValue; + + if (attr->inputType == 1) /* console */ + retcode = dmxInputAttachConsole(attr->name, attr->sendsCore, id); + else if (attr->inputType == 2) /* backend */ + retcode = dmxInputAttachBackend(attr->physicalScreen, + attr->sendsCore,id); + + if (retcode == Success) { + /* Adjust the cursor boundaries */ + dmxAdjustCursorBoundaries(); + + /* Force completion of the changes */ + dmxSync(NULL, TRUE); + } + + return retcode; +} + +/** Remove the input with physical id \a id. */ +int dmxRemoveInput(int id) +{ + return dmxInputDetachId(id); +} + +/** Return the value of #dmxNumScreens -- the total number of backend + * screens in use (these are logical screens and may be larger than the + * number of backend displays). */ +unsigned long dmxGetNumScreens(void) +{ + return dmxNumScreens; +} + +/** Make sure that #dmxCreateAndRealizeWindow has been called for \a + * pWindow. */ +void dmxForceWindowCreation(WindowPtr pWindow) +{ + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + if (!pWinPriv->window) dmxCreateAndRealizeWindow(pWindow, TRUE); +} + +/** Flush pending syncs for all screens. */ +void dmxFlushPendingSyncs(void) +{ + dmxSync(NULL, TRUE); +} + +/** Update DMX's screen resources to match those of the newly moved + * and/or resized "root" window. */ +void dmxUpdateScreenResources(ScreenPtr pScreen, int x, int y, int w, int h) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + WindowPtr pRoot = pScreen->root; + WindowPtr pChild; + Bool anyMarked = FALSE; + + /* Handle special case where width and/or height are zero */ + if (w == 0 || h == 0) { + w = 1; + h = 1; + } + + /* Change screen size */ + pScreen->width = w; + pScreen->height = h; + + /* Reset the root window's drawable's size */ + pRoot->drawable.width = w; + pRoot->drawable.height = h; + + /* Set the root window's new winSize and borderSize */ + pRoot->winSize.extents.x1 = 0; + pRoot->winSize.extents.y1 = 0; + pRoot->winSize.extents.x2 = w; + pRoot->winSize.extents.y2 = h; + + pRoot->borderSize.extents.x1 = 0; + pRoot->borderSize.extents.y1 = 0; + pRoot->borderSize.extents.x2 = w; + pRoot->borderSize.extents.y2 = h; + + /* Recompute this screen's mmWidth & mmHeight */ + pScreen->mmWidth = + (w * 254 + dmxScreen->beXDPI * 5) / (dmxScreen->beXDPI * 10); + pScreen->mmHeight = + (h * 254 + dmxScreen->beYDPI * 5) / (dmxScreen->beYDPI * 10); + + /* Recompute this screen's window's clip rects as follows: */ + /* 1. Mark all of root's children's windows */ + for (pChild = pRoot->firstChild; pChild; pChild = pChild->nextSib) + anyMarked |= pScreen->MarkOverlappedWindows(pChild, pChild, + (WindowPtr *)NULL); + + /* 2. Set the root window's borderClip */ + pRoot->borderClip.extents.x1 = 0; + pRoot->borderClip.extents.y1 = 0; + pRoot->borderClip.extents.x2 = w; + pRoot->borderClip.extents.y2 = h; + + /* 3. Set the root window's clipList */ + if (anyMarked) { + /* If any windows have been marked, set the root window's + * clipList to be broken since it will be recalculated in + * ValidateTree() + */ + RegionBreak(&pRoot->clipList); + } else { + /* Otherwise, we just set it directly since there are no + * windows visible on this screen + */ + pRoot->clipList.extents.x1 = 0; + pRoot->clipList.extents.y1 = 0; + pRoot->clipList.extents.x2 = w; + pRoot->clipList.extents.y2 = h; + } + + /* 4. Revalidate all clip rects and generate expose events */ + if (anyMarked) { + pScreen->ValidateTree(pRoot, NULL, VTBroken); + pScreen->HandleExposures(pRoot); + if (pScreen->PostValidateTree) + pScreen->PostValidateTree(pRoot, NULL, VTBroken); + } +} + +#ifdef PANORAMIX +#include "panoramiXsrv.h" + +/** Change the "screen" window attributes by resizing the actual window + * on the back-end display (if necessary). */ +static void dmxConfigureScreenWindow(int idx, + int x, int y, int w, int h) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + ScreenPtr pScreen = screenInfo.screens[idx]; + + /* Resize "screen" window */ + if (dmxScreen->scrnX != x || + dmxScreen->scrnY != y || + dmxScreen->scrnWidth != w || + dmxScreen->scrnHeight != h) { + dmxResizeScreenWindow(pScreen, x, y, w, h); + } + + /* Change "screen" window values */ + dmxScreen->scrnX = x; + dmxScreen->scrnY = y; + dmxScreen->scrnWidth = w; + dmxScreen->scrnHeight = h; +} + +/** Change the "root" window position and size by resizing the actual + * window on the back-end display (if necessary) and updating all of + * DMX's resources by calling #dmxUpdateScreenResources. */ +static void dmxConfigureRootWindow(int idx, int x, int y, int w, int h) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + WindowPtr pRoot = screenInfo.screens[idx]->root; + + /* NOTE: Either this function or the ones that it calls must handle + * the case where w == 0 || h == 0. Currently, the functions that + * this one calls handle that case. */ + + /* 1. Resize "root" window */ + if (dmxScreen->rootX != x || + dmxScreen->rootY != y || + dmxScreen->rootWidth != w || + dmxScreen->rootHeight != h) { + dmxResizeRootWindow(pRoot, x, y, w, h); + } + + /* 2. Update all of the screen's resources associated with this root + * window */ + if (dmxScreen->rootWidth != w || + dmxScreen->rootHeight != h) { + dmxUpdateScreenResources(screenInfo.screens[idx], x, y, w, h); + } + + /* Change "root" window values */ + dmxScreen->rootX = x; + dmxScreen->rootY = y; + dmxScreen->rootWidth = w; + dmxScreen->rootHeight = h; +} + +/** Change the "root" window's origin by updating DMX's internal data + * structures (dix and Xinerama) to use the new origin and adjust the + * positions of windows that overlap this "root" window. */ +static void dmxSetRootWindowOrigin(int idx, int x, int y) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + ScreenPtr pScreen = screenInfo.screens[idx]; + WindowPtr pRoot = pScreen->root; + WindowPtr pChild; + int xoff; + int yoff; + + /* Change "root" window's origin */ + dmxScreen->rootXOrigin = x; + dmxScreen->rootYOrigin = y; + + /* Compute offsets here in case <x,y> has been changed above */ + xoff = x - pScreen->x; + yoff = y - pScreen->y; + + /* Adjust the root window's position */ + pScreen->x = dmxScreen->rootXOrigin; + pScreen->y = dmxScreen->rootYOrigin; + + /* Recalculate the Xinerama regions and data structs */ + XineramaReinitData(pScreen); + + /* Adjust each of the root window's children */ + if (!idx) ReinitializeRootWindow(screenInfo.screens[0]->root, xoff, yoff); + pChild = pRoot->firstChild; + while (pChild) { + /* Adjust child window's position */ + pScreen->MoveWindow(pChild, + pChild->origin.x - wBorderWidth(pChild) - xoff, + pChild->origin.y - wBorderWidth(pChild) - yoff, + pChild->nextSib, + VTMove); + + /* Note that the call to MoveWindow will eventually call + * dmxPositionWindow which will automatically create a + * window if it is now exposed on screen (for lazy window + * creation optimization) and it will properly set the + * offscreen flag. + */ + + pChild = pChild->nextSib; + } +} + +/** Configure the attributes of each "screen" and "root" window. */ +int dmxConfigureScreenWindows(int nscreens, + CARD32 *screens, + DMXScreenAttributesPtr attribs, + int *errorScreen) +{ + int i; + + for (i = 0; i < nscreens; i++) { + DMXScreenAttributesPtr attr = &attribs[i]; + int idx = screens[i]; + DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + + if (errorScreen) *errorScreen = i; + + if (!dmxScreen->beDisplay) return DMX_BAD_VALUE; + + /* Check for illegal values */ + if (idx < 0 || idx >= dmxNumScreens) return BadValue; + + /* The "screen" and "root" windows must have valid sizes */ + if (attr->screenWindowWidth <= 0 || attr->screenWindowHeight <= 0 || + attr->rootWindowWidth < 0 || attr->rootWindowHeight < 0) + return DMX_BAD_VALUE; + + /* The "screen" window must fit entirely within the BE display */ + if (attr->screenWindowXoffset < 0 || + attr->screenWindowYoffset < 0 || + attr->screenWindowXoffset + + attr->screenWindowWidth > (unsigned)dmxScreen->beWidth || + attr->screenWindowYoffset + + attr->screenWindowHeight > (unsigned)dmxScreen->beHeight) + return DMX_BAD_VALUE; + + /* The "root" window must fit entirely within the "screen" window */ + if (attr->rootWindowXoffset < 0 || + attr->rootWindowYoffset < 0 || + attr->rootWindowXoffset + + attr->rootWindowWidth > attr->screenWindowWidth || + attr->rootWindowYoffset + + attr->rootWindowHeight > attr->screenWindowHeight) + return DMX_BAD_VALUE; + + /* The "root" window must not expose unaddressable coordinates */ + if (attr->rootWindowXorigin < 0 || + attr->rootWindowYorigin < 0 || + attr->rootWindowXorigin + attr->rootWindowWidth > 32767 || + attr->rootWindowYorigin + attr->rootWindowHeight > 32767) + return DMX_BAD_VALUE; + + /* The "root" window must fit within the global bounding box */ + if (attr->rootWindowXorigin + + attr->rootWindowWidth > (unsigned)dmxGlobalWidth || + attr->rootWindowYorigin + + attr->rootWindowHeight > (unsigned)dmxGlobalHeight) + return DMX_BAD_VALUE; + + /* FIXME: Handle the rest of the illegal value checking */ + } + + /* No illegal values found */ + if (errorScreen) *errorScreen = 0; + + for (i = 0; i < nscreens; i++) { + DMXScreenAttributesPtr attr = &attribs[i]; + int idx = screens[i]; + DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + + dmxLog(dmxInfo, "Changing screen #%d attributes " + "from %dx%d+%d+%d %dx%d+%d+%d +%d+%d " + "to %dx%d+%d+%d %dx%d+%d+%d +%d+%d\n", + idx, + dmxScreen->scrnWidth, dmxScreen->scrnHeight, + dmxScreen->scrnX, dmxScreen->scrnY, + dmxScreen->rootWidth, dmxScreen->rootHeight, + dmxScreen->rootX, dmxScreen->rootY, + dmxScreen->rootXOrigin, dmxScreen->rootYOrigin, + attr->screenWindowWidth, attr->screenWindowHeight, + attr->screenWindowXoffset, attr->screenWindowYoffset, + attr->rootWindowWidth, attr->rootWindowHeight, + attr->rootWindowXoffset, attr->rootWindowYoffset, + attr->rootWindowXorigin, attr->rootWindowYorigin); + + /* Configure "screen" window */ + dmxConfigureScreenWindow(idx, + attr->screenWindowXoffset, + attr->screenWindowYoffset, + attr->screenWindowWidth, + attr->screenWindowHeight); + + /* Configure "root" window */ + dmxConfigureRootWindow(idx, + attr->rootWindowXoffset, + attr->rootWindowYoffset, + attr->rootWindowWidth, + attr->rootWindowHeight); + + + /* Set "root" window's origin */ + dmxSetRootWindowOrigin(idx, + attr->rootWindowXorigin, + attr->rootWindowYorigin); + } + + /* Adjust the cursor boundaries */ + dmxAdjustCursorBoundaries(); + + /* Force completion of the changes */ + dmxSync(NULL, TRUE); + + return Success; +} + +/** Configure the attributes of the global desktop. */ +int dmxConfigureDesktop(DMXDesktopAttributesPtr attribs) +{ + if (attribs->width <= 0 || attribs->width >= 32767 || + attribs->height <= 0 || attribs->height >= 32767) + return DMX_BAD_VALUE; + + /* If the desktop is shrinking, adjust the "root" windows on each + * "screen" window to only show the visible desktop. Also, handle + * the special case where the desktop shrinks such that the it no + * longer overlaps an portion of a "screen" window. */ + if (attribs->width < dmxGlobalWidth || attribs->height < dmxGlobalHeight) { + int i; + for (i = 0; i < dmxNumScreens; i++) { + DMXScreenInfo *dmxScreen = &dmxScreens[i]; + if (dmxScreen->rootXOrigin + + dmxScreen->rootWidth > attribs->width || + dmxScreen->rootYOrigin + + dmxScreen->rootHeight > attribs->height) { + int w, h; + if ((w = attribs->width - dmxScreen->rootXOrigin) < 0) w = 0; + if ((h = attribs->height - dmxScreen->rootYOrigin) < 0) h = 0; + if (w > dmxScreen->scrnWidth) w = dmxScreen->scrnWidth; + if (h > dmxScreen->scrnHeight) h = dmxScreen->scrnHeight; + if (w > dmxScreen->rootWidth) w = dmxScreen->rootWidth; + if (h > dmxScreen->rootHeight) h = dmxScreen->rootHeight; + dmxConfigureRootWindow(i, + dmxScreen->rootX, + dmxScreen->rootY, + w, h); + } + } + } + + /* Set the global width/height */ + dmxSetWidthHeight(attribs->width, attribs->height); + + /* Handle shift[XY] changes */ + if (attribs->shiftX || attribs->shiftY) { + int i; + for (i = 0; i < dmxNumScreens; i++) { + ScreenPtr pScreen = screenInfo.screens[i]; + WindowPtr pChild = pScreen->root->firstChild; + while (pChild) { + /* Adjust child window's position */ + pScreen->MoveWindow(pChild, + pChild->origin.x - wBorderWidth(pChild) + - attribs->shiftX, + pChild->origin.y - wBorderWidth(pChild) + - attribs->shiftY, + pChild->nextSib, + VTMove); + + /* Note that the call to MoveWindow will eventually call + * dmxPositionWindow which will automatically create a + * window if it is now exposed on screen (for lazy + * window creation optimization) and it will properly + * set the offscreen flag. + */ + + pChild = pChild->nextSib; + } + } + } + + /* Update connection block, Xinerama, etc. -- these appears to + * already be handled in dmxConnectionBlockCallback(), which is + * called from dmxAdjustCursorBoundaries() [below]. */ + + /* Adjust the cursor boundaries */ + dmxAdjustCursorBoundaries(); + + /* Force completion of the changes */ + dmxSync(NULL, TRUE); + + return Success; +} +#endif + +/** Create the scratch GCs per depth. */ +static void dmxBECreateScratchGCs(int scrnNum) +{ + ScreenPtr pScreen = screenInfo.screens[scrnNum]; + GCPtr *ppGC = pScreen->GCperDepth; + int i; + + for (i = 0; i <= pScreen->numDepths; i++) + dmxBECreateGC(pScreen, ppGC[i]); +} + +#ifdef PANORAMIX +static Bool FoundPixImage; + +/** Search the Xinerama XRT_PIXMAP resources for the pixmap that needs + * to have its image restored. When it is found, see if there is + * another screen with the same image. If so, copy the pixmap image + * from the existing screen to the newly created pixmap. */ +static void dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type, + pointer p) +{ + if ((type & TypeMask) == (XRT_PIXMAP & TypeMask)) { + PixmapPtr pDst = (PixmapPtr)p; + int idx = pDst->drawable.pScreen->myNum; + PanoramiXRes *pXinPix = (PanoramiXRes *)value; + PixmapPtr pPix; + int i; + + dixLookupResourceByType((pointer*) &pPix, pXinPix->info[idx].id, + RT_PIXMAP, NullClient, DixUnknownAccess); + if (pPix != pDst) return; /* Not a match.... Next! */ + + FOR_NSCREENS(i) { + PixmapPtr pSrc; + dmxPixPrivPtr pSrcPriv = NULL; + + if (i == idx) continue; /* Self replication is bad */ + + dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id, + RT_PIXMAP, NullClient, DixUnknownAccess); + pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc); + if (pSrcPriv->pixmap) { + DMXScreenInfo *dmxSrcScreen = &dmxScreens[i]; + DMXScreenInfo *dmxDstScreen = &dmxScreens[idx]; + dmxPixPrivPtr pDstPriv = DMX_GET_PIXMAP_PRIV(pDst); + XImage *img; + int j; + XlibGC gc = NULL; + + /* This should never happen, but just in case.... */ + if (pSrc->drawable.width != pDst->drawable.width || + pSrc->drawable.height != pDst->drawable.height) + return; + + /* Copy from src pixmap to dst pixmap */ + img = XGetImage(dmxSrcScreen->beDisplay, + pSrcPriv->pixmap, + 0, 0, + pSrc->drawable.width, pSrc->drawable.height, + -1, + ZPixmap); + + for (j = 0; j < dmxDstScreen->beNumPixmapFormats; j++) { + if (dmxDstScreen->bePixmapFormats[j].depth == img->depth) { + unsigned long m; + XGCValues v; + + m = GCFunction | GCPlaneMask | GCClipMask; + v.function = GXcopy; + v.plane_mask = AllPlanes; + v.clip_mask = None; + + gc = XCreateGC(dmxDstScreen->beDisplay, + dmxDstScreen->scrnDefDrawables[j], + m, &v); + break; + } + } + + if (gc) { + XPutImage(dmxDstScreen->beDisplay, + pDstPriv->pixmap, + gc, img, 0, 0, 0, 0, + pDst->drawable.width, pDst->drawable.height); + XFreeGC(dmxDstScreen->beDisplay, gc); + FoundPixImage = True; + } else { + dmxLog(dmxWarning, "Could not create GC\n"); + } + + XDestroyImage(img); + return; + } + } + } +} +#endif + +/** Restore the pixmap image either from another screen or from an image + * that was saved when the screen was previously detached. */ +static void dmxBERestorePixmap(PixmapPtr pPixmap) +{ +#ifdef PANORAMIX + int i; + + /* If Xinerama is not active, there's nothing we can do (see comment + * in #else below for more info). */ + if (noPanoramiXExtension) { + dmxLog(dmxWarning, "Cannot restore pixmap image\n"); + return; + } + + FoundPixImage = False; + for (i = currentMaxClients; --i >= 0; ) + if (clients[i]) + FindAllClientResources(clients[i], dmxBERestorePixmapImage, + (pointer)pPixmap); + + /* No corresponding pixmap image was found on other screens, so we + * need to copy it from the saved image when the screen was detached + * (if available). */ + if (!FoundPixImage) { + dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); + + if (pPixPriv->detachedImage) { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + XlibGC gc = NULL; + + for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) { + if (dmxScreen->bePixmapFormats[i].depth == + pPixPriv->detachedImage->depth) { + unsigned long m; + XGCValues v; + + m = GCFunction | GCPlaneMask | GCClipMask; + v.function = GXcopy; + v.plane_mask = AllPlanes; + v.clip_mask = None; + + gc = XCreateGC(dmxScreen->beDisplay, + dmxScreen->scrnDefDrawables[i], + m, &v); + break; + } + } + + if (gc) { + XPutImage(dmxScreen->beDisplay, + pPixPriv->pixmap, + gc, + pPixPriv->detachedImage, + 0, 0, 0, 0, + pPixmap->drawable.width, pPixmap->drawable.height); + XFreeGC(dmxScreen->beDisplay, gc); + } else { + dmxLog(dmxWarning, "Cannot restore pixmap image\n"); + } + + XDestroyImage(pPixPriv->detachedImage); + pPixPriv->detachedImage = NULL; + } else { + dmxLog(dmxWarning, "Cannot restore pixmap image\n"); + } + } +#else + /* If Xinerama is not enabled, then there is no other copy of the + * pixmap image that we can restore. Saving all pixmap data is not + * a feasible option since there is no mechanism for updating pixmap + * data when a screen is detached, which means that the data that + * was previously saved would most likely be out of date. */ + dmxLog(dmxWarning, "Cannot restore pixmap image\n"); + return; +#endif +} + +/** Create resources on the back-end server. This function is called + * from #dmxAttachScreen() via the dix layer's FindAllResources + * function. It walks all resources, compares them to the screen + * number passed in as \a n and calls the appropriate DMX function to + * create the associated resource on the back-end server. */ +static void dmxBECreateResources(pointer value, XID id, RESTYPE type, + pointer n) +{ + int scrnNum = (uintptr_t)n; + ScreenPtr pScreen = screenInfo.screens[scrnNum]; + + if ((type & TypeMask) == (RT_WINDOW & TypeMask)) { + /* Window resources are created below in dmxBECreateWindowTree */ + } else if ((type & TypeMask) == (RT_PIXMAP & TypeMask)) { + PixmapPtr pPix = value; + if (pPix->drawable.pScreen->myNum == scrnNum) { + dmxBECreatePixmap(pPix); + dmxBERestorePixmap(pPix); + } + } else if ((type & TypeMask) == (RT_GC & TypeMask)) { + GCPtr pGC = value; + if (pGC->pScreen->myNum == scrnNum) { + /* Create the GC on the back-end server */ + dmxBECreateGC(pScreen, pGC); + /* Create any pixmaps associated with this GC */ + if (!pGC->tileIsPixel) { + dmxBECreatePixmap(pGC->tile.pixmap); + dmxBERestorePixmap(pGC->tile.pixmap); + } + if (pGC->stipple != pScreen->PixmapPerDepth[0]) { + dmxBECreatePixmap(pGC->stipple); + dmxBERestorePixmap(pGC->stipple); + } + if (pGC->font != defaultFont) { + (void)dmxBELoadFont(pScreen, pGC->font); + } + /* Update the GC on the back-end server */ + dmxChangeGC(pGC, -1L); + } + } else if ((type & TypeMask) == (RT_FONT & TypeMask)) { + (void)dmxBELoadFont(pScreen, (FontPtr)value); + } else if ((type & TypeMask) == (RT_CURSOR & TypeMask)) { + dmxBECreateCursor(pScreen, (CursorPtr)value); + } else if ((type & TypeMask) == (RT_COLORMAP & TypeMask)) { + ColormapPtr pCmap = value; + if (pCmap->pScreen->myNum == scrnNum) + (void)dmxBECreateColormap((ColormapPtr)value); +#if 0 + /* TODO: Recreate Picture and GlyphSet resources */ + } else if ((type & TypeMask) == (PictureType & TypeMask)) { + /* Picture resources are created when windows are created */ + } else if ((type & TypeMask) == (GlyphSetType & TypeMask)) { + dmxBEFreeGlyphSet(pScreen, (GlyphSetPtr)value); +#endif + } else { + /* Other resource types??? */ + } +} + +/** Create window hierachy on back-end server. The window tree is + * created in a special order (bottom most subwindow first) so that the + * #dmxCreateNonRootWindow() function does not need to recursively call + * itself to create each window's parents. This is required so that we + * have the opportunity to create each window's border and background + * pixmaps (where appropriate) before the window is created. */ +static void dmxBECreateWindowTree(int idx) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + WindowPtr pRoot = screenInfo.screens[idx]->root; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot); + WindowPtr pWin; + + /* Create the pixmaps associated with the root window */ + if (!pRoot->borderIsPixel) { + dmxBECreatePixmap(pRoot->border.pixmap); + dmxBERestorePixmap(pRoot->border.pixmap); + } + if (pRoot->backgroundState == BackgroundPixmap) { + dmxBECreatePixmap(pRoot->background.pixmap); + dmxBERestorePixmap(pRoot->background.pixmap); + } + + /* Create root window first */ + dmxScreen->rootWin = pWinPriv->window = dmxCreateRootWindow(pRoot); + XMapWindow(dmxScreen->beDisplay, dmxScreen->rootWin); + + pWin = pRoot->lastChild; + while (pWin) { + pWinPriv = DMX_GET_WINDOW_PRIV(pWin); + + /* Create the pixmaps regardless of whether or not the + * window is created or not due to lazy window creation. + */ + if (!pWin->borderIsPixel) { + dmxBECreatePixmap(pWin->border.pixmap); + dmxBERestorePixmap(pWin->border.pixmap); + } + if (pWin->backgroundState == BackgroundPixmap) { + dmxBECreatePixmap(pWin->background.pixmap); + dmxBERestorePixmap(pWin->background.pixmap); + } + + /* Reset the window attributes */ + dmxGetDefaultWindowAttributes(pWin, + &pWinPriv->cmap, + &pWinPriv->visual); + + /* Create the window */ + if (pWinPriv->mapped && !pWinPriv->offscreen) + dmxCreateAndRealizeWindow(pWin, TRUE); + + /* Next, create the bottom-most child */ + if (pWin->lastChild) { + pWin = pWin->lastChild; + continue; + } + + /* If the window has no children, move on to the next higher window */ + while (!pWin->prevSib && (pWin != pRoot)) + pWin = pWin->parent; + + if (pWin->prevSib) { + pWin = pWin->prevSib; + continue; + } + + /* When we reach the root window, we are finished */ + if (pWin == pRoot) + break; + } +} + +/* Refresh screen by generating exposure events for all windows */ +static void dmxForceExposures(int idx) +{ + ScreenPtr pScreen = screenInfo.screens[idx]; + WindowPtr pRoot = pScreen->root; + Bool anyMarked = FALSE; + WindowPtr pChild; + + for (pChild = pRoot->firstChild; pChild; pChild = pChild->nextSib) + anyMarked |= pScreen->MarkOverlappedWindows(pChild, pChild, + (WindowPtr *)NULL); + if (anyMarked) { + /* If any windows have been marked, set the root window's + * clipList to be broken since it will be recalculated in + * ValidateTree() + */ + RegionBreak(&pRoot->clipList); + pScreen->ValidateTree(pRoot, NULL, VTBroken); + pScreen->HandleExposures(pRoot); + if (pScreen->PostValidateTree) + pScreen->PostValidateTree(pRoot, NULL, VTBroken); + } +} + +/** Compare the new and old screens to see if they are compatible. */ +static Bool dmxCompareScreens(DMXScreenInfo *new, DMXScreenInfo *old) +{ + int i; + + if (new->beWidth != old->beWidth) return FALSE; + if (new->beHeight != old->beHeight) return FALSE; + if (new->beDepth != old->beDepth) return FALSE; + if (new->beBPP != old->beBPP) return FALSE; + + if (new->beNumDepths != old->beNumDepths) return FALSE; + for (i = 0; i < old->beNumDepths; i++) + if (new->beDepths[i] != old->beDepths[i]) return FALSE; + + if (new->beNumPixmapFormats != old->beNumPixmapFormats) return FALSE; + for (i = 0; i < old->beNumPixmapFormats; i++) { + if (new->bePixmapFormats[i].depth != + old->bePixmapFormats[i].depth) return FALSE; + if (new->bePixmapFormats[i].bits_per_pixel != + old->bePixmapFormats[i].bits_per_pixel) return FALSE; + if (new->bePixmapFormats[i].scanline_pad != + old->bePixmapFormats[i].scanline_pad) return FALSE; + } + + if (new->beNumVisuals != old->beNumVisuals) return FALSE; + for (i = 0; i < old->beNumVisuals; i++) { + if (new->beVisuals[i].visualid != + old->beVisuals[i].visualid) return FALSE; + if (new->beVisuals[i].screen != + old->beVisuals[i].screen) return FALSE; + if (new->beVisuals[i].depth != + old->beVisuals[i].depth) return FALSE; + if (new->beVisuals[i].class != + old->beVisuals[i].class) return FALSE; + if (new->beVisuals[i].red_mask != + old->beVisuals[i].red_mask) return FALSE; + if (new->beVisuals[i].green_mask != + old->beVisuals[i].green_mask) return FALSE; + if (new->beVisuals[i].blue_mask != + old->beVisuals[i].blue_mask) return FALSE; + if (new->beVisuals[i].colormap_size != + old->beVisuals[i].colormap_size) return FALSE; + if (new->beVisuals[i].bits_per_rgb != + old->beVisuals[i].bits_per_rgb) return FALSE; + } + + if (new->beDefVisualIndex != old->beDefVisualIndex) return FALSE; + + return TRUE; +} + +/** Restore Render's picture */ +static void dmxBERestoreRenderPict(pointer value, XID id, pointer n) +{ + PicturePtr pPicture = value; /* The picture */ + DrawablePtr pDraw = pPicture->pDrawable; /* The picture's drawable */ + int scrnNum = (uintptr_t)n; + + if (pDraw->pScreen->myNum != scrnNum) { + /* Picture not on the screen we are restoring*/ + return; + } + + if (pDraw->type == DRAWABLE_PIXMAP) { + PixmapPtr pPixmap = (PixmapPtr)pDraw; + + /* Create and restore the pixmap drawable */ + dmxBECreatePixmap(pPixmap); + dmxBERestorePixmap(pPixmap); + } + + dmxBECreatePicture(pPicture); +} + +/** Restore Render's glyphs */ +static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n) +{ + GlyphSetPtr glyphSet = value; + int scrnNum = (uintptr_t)n; + dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); + DMXScreenInfo *dmxScreen = &dmxScreens[scrnNum]; + GlyphRefPtr table; + char *images; + Glyph *gids; + XGlyphInfo *glyphs; + char *pos; + int beret; + int len_images = 0; + int i; + int ctr; + + if (glyphPriv->glyphSets[scrnNum]) { + /* Only restore glyphs on the screen we are attaching */ + return; + } + + /* First we must create the glyph set on the backend. */ + if ((beret = dmxBECreateGlyphSet(scrnNum, glyphSet)) != Success) { + dmxLog(dmxWarning, + "\tdmxBERestoreRenderGlyph failed to create glyphset!\n"); + return; + } + + /* Now for the complex part, restore the glyph data */ + table = glyphSet->hash.table; + + /* We need to know how much memory to allocate for this part */ + for (i = 0; i < glyphSet->hash.hashSet->size; i++) { + GlyphRefPtr gr = &table[i]; + GlyphPtr gl = gr->glyph; + + if (!gl || gl == DeletedGlyph) continue; + len_images += gl->size - sizeof(gl->info); + } + + /* Now allocate the memory we need */ + images = calloc(len_images, sizeof(char)); + gids = malloc(glyphSet->hash.tableEntries*sizeof(Glyph)); + glyphs = malloc(glyphSet->hash.tableEntries*sizeof(XGlyphInfo)); + + pos = images; + ctr = 0; + + /* Fill the allocated memory with the proper data */ + for (i = 0; i < glyphSet->hash.hashSet->size; i++) { + GlyphRefPtr gr = &table[i]; + GlyphPtr gl = gr->glyph; + + if (!gl || gl == DeletedGlyph) continue; + + /* First lets put the data into gids */ + gids[ctr] = gr->signature; + + /* Next do the glyphs data structures */ + glyphs[ctr].width = gl->info.width; + glyphs[ctr].height = gl->info.height; + glyphs[ctr].x = gl->info.x; + glyphs[ctr].y = gl->info.y; + glyphs[ctr].xOff = gl->info.xOff; + glyphs[ctr].yOff = gl->info.yOff; + + /* Copy the images from the DIX's data into the buffer */ + memcpy(pos, gl+1, gl->size - sizeof(gl->info)); + pos += gl->size - sizeof(gl->info); + ctr++; + } + + /* Now restore the glyph data */ + XRenderAddGlyphs(dmxScreen->beDisplay, glyphPriv->glyphSets[scrnNum], + gids,glyphs, glyphSet->hash.tableEntries, images, + len_images); + + /* Clean up */ + free(images); + free(gids); + free(glyphs); +} + +/** Reattach previously detached back-end screen. */ +int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr) +{ + ScreenPtr pScreen; + DMXScreenInfo *dmxScreen; + CARD32 scrnNum = idx; + DMXScreenInfo oldDMXScreen; + int i; + + /* Return failure if dynamic addition/removal of screens is disabled */ + if (!dmxAddRemoveScreens) { + dmxLog(dmxWarning, + "Attempting to add a screen, but the AddRemoveScreen\n"); + dmxLog(dmxWarning, + "extension has not been enabled. To enable this extension\n"); + dmxLog(dmxWarning, + "add the \"-addremovescreens\" option either to the command\n"); + dmxLog(dmxWarning, + "line or in the configuration file.\n"); + return 1; + } + + /* Cannot add a screen that does not exist */ + if (idx < 0 || idx >= dmxNumScreens) return 1; + pScreen = screenInfo.screens[idx]; + dmxScreen = &dmxScreens[idx]; + + /* Cannot attach to a screen that is already opened */ + if (dmxScreen->beDisplay) { + dmxLog(dmxWarning, + "Attempting to add screen #%d but a screen already exists\n", + idx); + return 1; + } + + dmxLogOutput(dmxScreen, "Attaching screen #%d\n", idx); + + /* Save old info */ + oldDMXScreen = *dmxScreen; + + /* Copy the name to the new screen */ + dmxScreen->name = strdup(attr->displayName); + + /* Open display and get all of the screen info */ + if (!dmxOpenDisplay(dmxScreen)) { + dmxLog(dmxWarning, + "dmxOpenDisplay: Unable to open display %s\n", + dmxScreen->name); + + /* Restore the old screen */ + *dmxScreen = oldDMXScreen; + return 1; + } + + dmxSetErrorHandler(dmxScreen); + dmxCheckForWM(dmxScreen); + dmxGetScreenAttribs(dmxScreen); + + if (!dmxGetVisualInfo(dmxScreen)) { + dmxLog(dmxWarning, "dmxGetVisualInfo: No matching visuals found\n"); + XFree(dmxScreen->beVisuals); + XCloseDisplay(dmxScreen->beDisplay); + + /* Restore the old screen */ + *dmxScreen = oldDMXScreen; + return 1; + } + + dmxGetColormaps(dmxScreen); + dmxGetPixmapFormats(dmxScreen); + + /* Verify that the screen to be added has the same info as the + * previously added screen. */ + if (!dmxCompareScreens(dmxScreen, &oldDMXScreen)) { + dmxLog(dmxWarning, + "New screen data (%s) does not match previously\n", + dmxScreen->name); + dmxLog(dmxWarning, + "attached screen data (%s)\n", + oldDMXScreen.name); + dmxLog(dmxWarning, + "All data must match in order to attach to screen #%d\n", + idx); + XFree(dmxScreen->beVisuals); + XFree(dmxScreen->beDepths); + XFree(dmxScreen->bePixmapFormats); + XCloseDisplay(dmxScreen->beDisplay); + + /* Restore the old screen */ + *dmxScreen = oldDMXScreen; + return 1; + } + + /* Initialize the BE screen resources */ + dmxBEScreenInit(idx, screenInfo.screens[idx]); + + /* TODO: Handle GLX visual initialization. GLXProxy needs to be + * updated to handle dynamic addition/removal of screens. */ + + /* Create default stipple */ + dmxBECreatePixmap(pScreen->PixmapPerDepth[0]); + dmxBERestorePixmap(pScreen->PixmapPerDepth[0]); + + /* Create the scratch GCs */ + dmxBECreateScratchGCs(idx); + + /* Create the default font */ + (void)dmxBELoadFont(pScreen, defaultFont); + + /* Create all resources that don't depend on windows */ + for (i = currentMaxClients; --i >= 0; ) + if (clients[i]) + FindAllClientResources(clients[i], dmxBECreateResources, + (pointer)(uintptr_t)idx); + + /* Create window hierarchy (top down) */ + dmxBECreateWindowTree(idx); + + /* Restore the picture state for RENDER */ + for (i = currentMaxClients; --i >= 0; ) + if (clients[i]) + FindClientResourcesByType(clients[i],PictureType, + dmxBERestoreRenderPict, + (pointer)(uintptr_t)idx); + + /* Restore the glyph state for RENDER */ + for (i = currentMaxClients; --i >= 0; ) + if (clients[i]) + FindClientResourcesByType(clients[i],GlyphSetType, + dmxBERestoreRenderGlyph, + (pointer)(uintptr_t)idx); + + /* Refresh screen by generating exposure events for all windows */ + dmxForceExposures(idx); + + dmxSync(&dmxScreens[idx], TRUE); + + /* We used these to compare the old and new screens. They are no + * longer needed since we have a newly attached screen, so we can + * now free the old screen's resources. */ + XFree(oldDMXScreen.beVisuals); + XFree(oldDMXScreen.beDepths); + XFree(oldDMXScreen.bePixmapFormats); + /* TODO: should oldDMXScreen.name be freed?? */ + +#ifdef PANORAMIX + if (!noPanoramiXExtension) + return dmxConfigureScreenWindows(1, &scrnNum, attr, NULL); + else +#endif + return 0; /* Success */ +} + +/* + * Resources that may have state on the BE server and need to be freed: + * + * RT_NONE + * RT_WINDOW + * RT_PIXMAP + * RT_GC + * RT_FONT + * RT_CURSOR + * RT_COLORMAP + * RT_CMAPENTRY + * RT_OTHERCLIENT + * RT_PASSIVEGRAB + * XRT_WINDOW + * XRT_PIXMAP + * XRT_GC + * XRT_COLORMAP + * XRT_PICTURE + * PictureType + * PictFormatType + * GlyphSetType + * ClientType + * EventType + * RT_INPUTCLIENT + * XETrapType + * RTCounter + * RTAwait + * RTAlarmClient + * RT_XKBCLIENT + * RTContext + * TagResType + * StalledResType + * SecurityAuthorizationResType + * RTEventClient + * __glXContextRes + * __glXClientRes + * __glXPixmapRes + * __glXWindowRes + * __glXPbufferRes + */ + +#ifdef PANORAMIX +/** Search the Xinerama XRT_PIXMAP resources for the pixmap that needs + * to have its image saved. */ +static void dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type, + pointer p) +{ + if ((type & TypeMask) == (XRT_PIXMAP & TypeMask)) { + PixmapPtr pDst = (PixmapPtr)p; + int idx = pDst->drawable.pScreen->myNum; + PanoramiXRes *pXinPix = (PanoramiXRes *)value; + PixmapPtr pPix; + int i; + + dixLookupResourceByType((pointer*) &pPix, pXinPix->info[idx].id, + RT_PIXMAP, NullClient, DixUnknownAccess); + if (pPix != pDst) return; /* Not a match.... Next! */ + + FOR_NSCREENS(i) { + PixmapPtr pSrc; + dmxPixPrivPtr pSrcPriv = NULL; + + if (i == idx) continue; /* Self replication is bad */ + + dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id, + RT_PIXMAP, NullClient, DixUnknownAccess); + pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc); + if (pSrcPriv->pixmap) { + FoundPixImage = True; + return; + } + } + } +} +#endif + +/** Save the pixmap image only when there is not another screen with + * that pixmap from which the image can be read when the screen is + * reattached. To do this, we first try to find a pixmap on another + * screen corresponding to the one we are trying to save. If we find + * one, then we do not need to save the image data since during + * reattachment, the image data can be read from that other pixmap. + * However, if we do not find one, then we need to save the image data. + * The common case for these are for the default stipple and root + * tile. */ +static void dmxBESavePixmap(PixmapPtr pPixmap) +{ +#ifdef PANORAMIX + int i; + + /* If Xinerama is not active, there's nothing we can do (see comment + * in #else below for more info). */ + if (noPanoramiXExtension) return; + + FoundPixImage = False; + for (i = currentMaxClients; --i >= 0; ) + if (clients[i]) + FindAllClientResources(clients[i], dmxBEFindPixmapImage, + (pointer)pPixmap); + + /* Save the image only if there is no other screens that have a + * pixmap that corresponds to the one we are trying to save. */ + if (!FoundPixImage) { + dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); + + if (!pPixPriv->detachedImage) { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + pPixPriv->detachedImage = XGetImage(dmxScreen->beDisplay, + pPixPriv->pixmap, + 0, 0, + pPixmap->drawable.width, + pPixmap->drawable.height, + -1, + ZPixmap); + if (!pPixPriv->detachedImage) + dmxLog(dmxWarning, "Cannot save pixmap image\n"); + } + } +#else + /* NOTE: The only time there is a pixmap on another screen that + * corresponds to the one we are trying to save is when Xinerama is + * active. Otherwise, the pixmap image data is only stored on a + * single screen, which means that once it is detached, that data is + * lost. We could save the data here, but then that would require + * us to implement the ability for Xdmx to keep the pixmap up to + * date while the screen is detached, which is beyond the scope of + * the current project. */ + return; +#endif +} + +/** Destroy resources on the back-end server. This function is called + * from #dmxDetachScreen() via the dix layer's FindAllResources + * function. It walks all resources, compares them to the screen + * number passed in as \a n and calls the appropriate DMX function to + * free the associated resource on the back-end server. */ +static void dmxBEDestroyResources(pointer value, XID id, RESTYPE type, + pointer n) +{ + int scrnNum = (uintptr_t)n; + ScreenPtr pScreen = screenInfo.screens[scrnNum]; + + if ((type & TypeMask) == (RT_WINDOW & TypeMask)) { + /* Window resources are destroyed below in dmxBEDestroyWindowTree */ + } else if ((type & TypeMask) == (RT_PIXMAP & TypeMask)) { + PixmapPtr pPix = value; + if (pPix->drawable.pScreen->myNum == scrnNum) { + dmxBESavePixmap(pPix); + dmxBEFreePixmap(pPix); + } + } else if ((type & TypeMask) == (RT_GC & TypeMask)) { + GCPtr pGC = value; + if (pGC->pScreen->myNum == scrnNum) + dmxBEFreeGC(pGC); + } else if ((type & TypeMask) == (RT_FONT & TypeMask)) { + dmxBEFreeFont(pScreen, (FontPtr)value); + } else if ((type & TypeMask) == (RT_CURSOR & TypeMask)) { + dmxBEFreeCursor(pScreen, (CursorPtr)value); + } else if ((type & TypeMask) == (RT_COLORMAP & TypeMask)) { + ColormapPtr pCmap = value; + if (pCmap->pScreen->myNum == scrnNum) + dmxBEFreeColormap((ColormapPtr)value); + } else if ((type & TypeMask) == (PictureType & TypeMask)) { + PicturePtr pPict = value; + if (pPict->pDrawable->pScreen->myNum == scrnNum) { + /* Free the pixmaps on the backend if needed */ + if (pPict->pDrawable->type == DRAWABLE_PIXMAP) { + PixmapPtr pPixmap = (PixmapPtr)(pPict->pDrawable); + dmxBESavePixmap(pPixmap); + dmxBEFreePixmap(pPixmap); + } + dmxBEFreePicture((PicturePtr)value); + } + } else if ((type & TypeMask) == (GlyphSetType & TypeMask)) { + dmxBEFreeGlyphSet(pScreen, (GlyphSetPtr)value); + } else { + /* Other resource types??? */ + } +} + +/** Destroy the scratch GCs that are created per depth. */ +static void dmxBEDestroyScratchGCs(int scrnNum) +{ + ScreenPtr pScreen = screenInfo.screens[scrnNum]; + GCPtr *ppGC = pScreen->GCperDepth; + int i; + + for (i = 0; i <= pScreen->numDepths; i++) + dmxBEFreeGC(ppGC[i]); +} + +/** Destroy window hierachy on back-end server. To ensure that all + * XDestroyWindow() calls succeed, they must be performed in a bottom + * up order so that windows are not destroyed before their children. + * XDestroyWindow(), which is called from #dmxBEDestroyWindow(), will + * destroy a window as well as all of it's children. */ +static void dmxBEDestroyWindowTree(int idx) +{ + WindowPtr pWin = screenInfo.screens[idx]->root; + WindowPtr pChild = pWin; + + while (1) { + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + + /* Destroy the window */ + dmxBEDestroyWindow(pChild); + + /* Make sure we destroy the window's border and background + * pixmaps if they exist */ + if (!pChild->borderIsPixel) { + dmxBESavePixmap(pChild->border.pixmap); + dmxBEFreePixmap(pChild->border.pixmap); + } + if (pChild->backgroundState == BackgroundPixmap) { + dmxBESavePixmap(pChild->background.pixmap); + dmxBEFreePixmap(pChild->background.pixmap); + } + + while (!pChild->nextSib && (pChild != pWin)) { + pChild = pChild->parent; + dmxBEDestroyWindow(pChild); + if (!pChild->borderIsPixel) { + dmxBESavePixmap(pChild->border.pixmap); + dmxBEFreePixmap(pChild->border.pixmap); + } + if (pChild->backgroundState == BackgroundPixmap) { + dmxBESavePixmap(pChild->background.pixmap); + dmxBEFreePixmap(pChild->background.pixmap); + } + } + + if (pChild == pWin) + break; + + pChild = pChild->nextSib; + } +} + +/** Detach back-end screen. */ +int dmxDetachScreen(int idx) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + int i; + + /* Return failure if dynamic addition/removal of screens is disabled */ + if (!dmxAddRemoveScreens) { + dmxLog(dmxWarning, + "Attempting to remove a screen, but the AddRemoveScreen\n"); + dmxLog(dmxWarning, + "extension has not been enabled. To enable this extension\n"); + dmxLog(dmxWarning, + "add the \"-addremovescreens\" option either to the command\n"); + dmxLog(dmxWarning, + "line or in the configuration file.\n"); + return 1; + } + + /* Cannot remove a screen that does not exist */ + if (idx < 0 || idx >= dmxNumScreens) return 1; + + /* Cannot detach from a screen that is not opened */ + if (!dmxScreen->beDisplay) { + dmxLog(dmxWarning, + "Attempting to remove screen #%d but it has not been opened\n", + idx); + return 1; + } + + dmxLogOutput(dmxScreen, "Detaching screen #%d\n", idx); + + /* Detach input */ + dmxInputDetachAll(dmxScreen); + + /* Save all relevant state (TODO) */ + + /* Free all non-window resources related to this screen */ + for (i = currentMaxClients; --i >= 0; ) + if (clients[i]) + FindAllClientResources(clients[i], dmxBEDestroyResources, + (pointer)(uintptr_t)idx); + + /* Free scratch GCs */ + dmxBEDestroyScratchGCs(idx); + + /* Free window resources related to this screen */ + dmxBEDestroyWindowTree(idx); + + /* Free default stipple */ + dmxBESavePixmap(screenInfo.screens[idx]->PixmapPerDepth[0]); + dmxBEFreePixmap(screenInfo.screens[idx]->PixmapPerDepth[0]); + + /* Free the remaining screen resources and close the screen */ + dmxBECloseScreen(screenInfo.screens[idx]); + + /* Adjust the cursor boundaries (paints detached console window) */ + dmxAdjustCursorBoundaries(); + + return 0; /* Success */ +} diff --git a/xorg-server/hw/dmx/dmxgcops.c b/xorg-server/hw/dmx/dmxgcops.c index 07165f731..500e2cdf1 100644 --- a/xorg-server/hw/dmx/dmxgcops.c +++ b/xorg-server/hw/dmx/dmxgcops.c @@ -1,605 +1,605 @@ -/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * This file provides support for GC operations. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxgc.h"
-#include "dmxgcops.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-
-#include "mi.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "dixfontstr.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \
-do { \
- if ((_pDraw)->type == DRAWABLE_WINDOW) { \
- dmxWinPrivPtr pWinPriv = \
- DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \
- (_draw) = (Drawable)pWinPriv->window; \
- } else { \
- dmxPixPrivPtr pPixPriv = \
- DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \
- (_draw) = (Drawable)pPixPriv->pixmap; \
- } \
-} while (0)
-
-#define DMX_GCOPS_OFFSCREEN(_pDraw) \
- (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \
- (dmxOffScreenOpt && \
- (_pDraw)->type == DRAWABLE_WINDOW && \
- (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \
- !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window)))
-
-/** Fill spans -- this function should never be called. */
-void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC,
- int nInit, DDXPointPtr pptInit, int *pwidthInit,
- int fSorted)
-{
- /* Error -- this should never happen! */
-}
-
-/** Set spans -- this function should never be called. */
-void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC,
- char *psrc, DDXPointPtr ppt, int *pwidth, int nspans,
- int fSorted)
-{
- /* Error -- this should never happen! */
-}
-
-/** Transfer \a pBits image to back-end server associated with \a
- * pDrawable's screen. If primitive subdivision optimization is
- * enabled, then only transfer the sections of \a pBits that are
- * visible (i.e., not-clipped) to the back-end server. */
-void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
- int depth, int x, int y, int w, int h,
- int leftPad, int format, char *pBits)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- XImage *img;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- img = XCreateImage(dmxScreen->beDisplay,
- dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
- depth, format, leftPad, pBits, w, h,
- BitmapPad(dmxScreen->beDisplay),
- (format == ZPixmap) ?
- PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));
-
- if (img) {
- Drawable draw;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- if (dmxSubdividePrimitives && pGC->pCompositeClip) {
- RegionPtr pSubImages;
- RegionPtr pClip;
- BoxRec box;
- BoxPtr pBox;
- int nBox;
-
- box.x1 = x;
- box.y1 = y;
- box.x2 = x + w;
- box.y2 = y + h;
- pSubImages = RegionCreate(&box, 1);
-
- pClip = RegionCreate(NullBox, 1);
- RegionCopy(pClip, pGC->pCompositeClip);
- RegionTranslate(pClip,
- -pDrawable->x, -pDrawable->y);
- RegionIntersect(pSubImages, pSubImages, pClip);
-
- nBox = RegionNumRects(pSubImages);
- pBox = RegionRects(pSubImages);
-
- while (nBox--) {
- XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
- pBox->x1 - box.x1,
- pBox->y1 - box.y1,
- pBox->x1,
- pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1);
- pBox++;
- }
- RegionDestroy(pClip);
- RegionDestroy(pSubImages);
- } else {
- XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
- img, 0, 0, x, y, w, h);
- }
- XFree(img); /* Use XFree instead of XDestroyImage
- * because pBits is passed in from the
- * caller. */
-
- dmxSync(dmxScreen, FALSE);
- } else {
- /* Error -- this should not happen! */
- }
-}
-
-/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end
- * server associated with \a pSrc drawable's screen. If the offscreen
- * optimization is enabled, only copy when both \a pSrc and \a pDst are
- * at least partially visible. */
-RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable srcDraw, dstDraw;
-
- if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
- dstx, dsty, 0L);
-
- DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
- DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
-
- XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
- srcx, srcy, w, h, dstx, dsty);
- dmxSync(dmxScreen, FALSE);
-
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
- dstx, dsty, 0L);
-}
-
-/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst
- * drawable on the back-end server associated with \a pSrc drawable's
- * screen. If the offscreen optimization is enabled, only copy when
- * both \a pSrc and \a pDst are at least partially visible. */
-RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int width, int height,
- int dstx, int dsty, unsigned long bitPlane)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable srcDraw, dstDraw;
-
- if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
- dstx, dsty, bitPlane);
-
- DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
- DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
-
- XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
- srcx, srcy, width, height, dstx, dsty, bitPlane);
- dmxSync(dmxScreen, FALSE);
-
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
- dstx, dsty, bitPlane);
-}
-
-/** Render list of points, \a pptInit in \a pDrawable on the back-end
- * server associated with \a pDrawable's screen. If the offscreen
- * optimization is enabled, only draw when \a pDrawable is at least
- * partially visible. */
-void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XPoint *)pptInit, npt, mode);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of connected lines, \a pptInit in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XPoint *)pptInit, npt, mode);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of disjoint segments, \a pSegs in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
- int nseg, xSegment *pSegs)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XSegment *)pSegs, nseg);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of rectangle outlines, \a pRects in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
- int nrects, xRectangle *pRects)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XRectangle *)pRects, nrects);
-
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of arc outlines, \a parcs in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *parcs)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XArc *)parcs, narcs);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render a filled polygons in \a pDrawable on the back-end server
- * associated with \a pDrawable's screen. If the offscreen
- * optimization is enabled, only draw when \a pDrawable is at least
- * partially visible. */
-void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
- int shape, int mode, int count, DDXPointPtr pPts)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XPoint *)pPts, count, shape, mode);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of filled rectangles, \a prectInit in \a pDrawable on
- * the back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
- int nrectFill, xRectangle *prectInit)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XRectangle *)prectInit, nrectFill);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end
- * server associated with \a pDrawable's screen. If the offscreen
- * optimization is enabled, only draw when \a pDrawable is at least
- * partially visible. */
-void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *parcs)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XArc *)parcs, narcs);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on
- * the back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- unsigned long n, i;
- int w;
- CharInfoPtr charinfo[255];
- Drawable draw;
-
- GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
- Linear8Bit, &n, charinfo);
-
- /* Calculate text width */
- w = 0;
- for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
-
- if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, chars, count);
- dmxSync(dmxScreen, FALSE);
- }
-
- return x+w;
-}
-
-/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
- * on the back-end server associated with \a pDrawable's screen. If
- * the offscreen optimization is enabled, only draw when \a pDrawable
- * is at least partially visible. */
-int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, unsigned short *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- unsigned long n, i;
- int w;
- CharInfoPtr charinfo[255];
- Drawable draw;
-
- GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
- (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
- &n, charinfo);
-
- /* Calculate text width */
- w = 0;
- for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
-
- if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, (XChar2b *)chars, count);
- dmxSync(dmxScreen, FALSE);
- }
-
- return x+w;
-}
-
-/** Render string of 8-bit \a chars (both foreground and background) in
- * \a pDrawable on the back-end server associated with \a pDrawable's
- * screen. If the offscreen optimization is enabled, only draw when \a
- * pDrawable is at least partially visible. */
-void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, chars, count);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render string of 16-bit \a chars (both foreground and background) in
- * \a pDrawable on the back-end server associated with \a pDrawable's
- * screen. If the offscreen optimization is enabled, only draw when \a
- * pDrawable is at least partially visible. */
-void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, unsigned short *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, (XChar2b *)chars, count);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Image Glyph Blt -- this function should never be called. */
-void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- /* Error -- this should never happen! */
-}
-
-/** Poly Glyph Blt -- this function should never be called. */
-void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- /* Error -- this should never happen! */
-}
-
-/** Push Pixels -- this function should never be called. */
-void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
- int w, int h, int x, int y)
-{
- /* Error -- this should never happen! */
-}
-
-/**********************************************************************
- * Miscellaneous drawing commands
- */
-
-/** When Xinerama is active, the client pixmaps are always obtained from
- * screen 0. When screen 0 is detached, the pixmaps must be obtained
- * from any other screen that is not detached. Usually, this is screen
- * 1. */
-static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
-{
-#ifdef PANORAMIX
- PanoramiXRes *pXinPix;
- int i;
- DMXScreenInfo *dmxScreen;
-
- if (noPanoramiXExtension) return NULL;
- if (pDrawable->type != DRAWABLE_PIXMAP) return NULL;
-
- if (Success != dixLookupResourceByType((pointer*) &pXinPix,
- pDrawable->id, XRT_PIXMAP,
- NullClient, DixUnknownAccess))
- return NULL;
-
- FOR_NSCREENS_FORWARD_SKIP(i) {
- dmxScreen = &dmxScreens[i];
- if (dmxScreen->beDisplay) {
- PixmapPtr pSrc;
- dmxPixPrivPtr pSrcPriv;
-
- dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id,
- RT_PIXMAP, NullClient, DixUnknownAccess);
- pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
- if (pSrcPriv->pixmap) {
- *draw = pSrcPriv->pixmap;
- return dmxScreen;
- }
- }
- }
-#endif
- return NULL;
-}
-
-/** Get an image from the back-end server associated with \a pDrawable's
- * screen. If \a pDrawable is a window, it must be viewable to get an
- * image from it. If it is not viewable, then get the image from the
- * first ancestor of \a pDrawable that is viewable. If no viewable
- * ancestor is found, then simply return without getting an image. */
-void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
- unsigned int format, unsigned long planeMask, char *pdstLine)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- XImage *img;
- Drawable draw;
-
- /* Cannot get image from unviewable window */
- if (pDrawable->type == DRAWABLE_WINDOW) {
- WindowPtr pWindow = (WindowPtr)pDrawable;
- if (!pWindow->viewable) {
- while (!pWindow->viewable && pWindow->parent) {
- sx += pWindow->origin.x - wBorderWidth(pWindow);
- sx += pWindow->origin.y - wBorderWidth(pWindow);
- pWindow = pWindow->parent;
- }
- if (!pWindow->viewable) {
- return;
- }
- }
- DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
- if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
- return;
- } else {
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
- /* Try to find the pixmap on a non-detached Xinerama screen */
- dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
- if (!dmxScreen) return;
- }
- }
-
- img = XGetImage(dmxScreen->beDisplay, draw,
- sx, sy, w, h, planeMask, format);
- if (img) {
- int len = img->bytes_per_line * img->height;
- memmove(pdstLine, img->data, len);
- XDestroyImage(img);
- }
-
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Get Spans -- this function should never be called. */
-void dmxGetSpans(DrawablePtr pDrawable, int wMax,
- DDXPointPtr ppt, int *pwidth, int nspans,
- char *pdstStart)
-{
- /* Error -- this should never happen! */
-}
+/* + * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Kevin E. Martin <kem@redhat.com> + * + */ + +/** \file + * This file provides support for GC operations. */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxsync.h" +#include "dmxgc.h" +#include "dmxgcops.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" + +#include "mi.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "dixfontstr.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \ +do { \ + if ((_pDraw)->type == DRAWABLE_WINDOW) { \ + dmxWinPrivPtr pWinPriv = \ + DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \ + (_draw) = (Drawable)pWinPriv->window; \ + } else { \ + dmxPixPrivPtr pPixPriv = \ + DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \ + (_draw) = (Drawable)pPixPriv->pixmap; \ + } \ +} while (0) + +#define DMX_GCOPS_OFFSCREEN(_pDraw) \ + (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \ + (dmxOffScreenOpt && \ + (_pDraw)->type == DRAWABLE_WINDOW && \ + (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \ + !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window))) + +/** Fill spans -- this function should never be called. */ +void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC, + int nInit, DDXPointPtr pptInit, int *pwidthInit, + int fSorted) +{ + /* Error -- this should never happen! */ +} + +/** Set spans -- this function should never be called. */ +void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC, + char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, + int fSorted) +{ + /* Error -- this should never happen! */ +} + +/** Transfer \a pBits image to back-end server associated with \a + * pDrawable's screen. If primitive subdivision optimization is + * enabled, then only transfer the sections of \a pBits that are + * visible (i.e., not-clipped) to the back-end server. */ +void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC, + int depth, int x, int y, int w, int h, + int leftPad, int format, char *pBits) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + XImage *img; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + img = XCreateImage(dmxScreen->beDisplay, + dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual, + depth, format, leftPad, pBits, w, h, + BitmapPad(dmxScreen->beDisplay), + (format == ZPixmap) ? + PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad)); + + if (img) { + Drawable draw; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + if (dmxSubdividePrimitives && pGC->pCompositeClip) { + RegionPtr pSubImages; + RegionPtr pClip; + BoxRec box; + BoxPtr pBox; + int nBox; + + box.x1 = x; + box.y1 = y; + box.x2 = x + w; + box.y2 = y + h; + pSubImages = RegionCreate(&box, 1); + + pClip = RegionCreate(NullBox, 1); + RegionCopy(pClip, pGC->pCompositeClip); + RegionTranslate(pClip, + -pDrawable->x, -pDrawable->y); + RegionIntersect(pSubImages, pSubImages, pClip); + + nBox = RegionNumRects(pSubImages); + pBox = RegionRects(pSubImages); + + while (nBox--) { + XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, + pBox->x1 - box.x1, + pBox->y1 - box.y1, + pBox->x1, + pBox->y1, + pBox->x2 - pBox->x1, + pBox->y2 - pBox->y1); + pBox++; + } + RegionDestroy(pClip); + RegionDestroy(pSubImages); + } else { + XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, + img, 0, 0, x, y, w, h); + } + XFree(img); /* Use XFree instead of XDestroyImage + * because pBits is passed in from the + * caller. */ + + dmxSync(dmxScreen, FALSE); + } else { + /* Error -- this should not happen! */ + } +} + +/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end + * server associated with \a pSrc drawable's screen. If the offscreen + * optimization is enabled, only copy when both \a pSrc and \a pDst are + * at least partially visible. */ +RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable srcDraw, dstDraw; + + if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst)) + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, + dstx, dsty, 0L); + + DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw); + DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw); + + XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc, + srcx, srcy, w, h, dstx, dsty); + dmxSync(dmxScreen, FALSE); + + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, + dstx, dsty, 0L); +} + +/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst + * drawable on the back-end server associated with \a pSrc drawable's + * screen. If the offscreen optimization is enabled, only copy when + * both \a pSrc and \a pDst are at least partially visible. */ +RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long bitPlane) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable srcDraw, dstDraw; + + if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst)) + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height, + dstx, dsty, bitPlane); + + DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw); + DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw); + + XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc, + srcx, srcy, width, height, dstx, dsty, bitPlane); + dmxSync(dmxScreen, FALSE); + + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height, + dstx, dsty, bitPlane); +} + +/** Render list of points, \a pptInit in \a pDrawable on the back-end + * server associated with \a pDrawable's screen. If the offscreen + * optimization is enabled, only draw when \a pDrawable is at least + * partially visible. */ +void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XPoint *)pptInit, npt, mode); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of connected lines, \a pptInit in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XPoint *)pptInit, npt, mode); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of disjoint segments, \a pSegs in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC, + int nseg, xSegment *pSegs) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XSegment *)pSegs, nseg); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of rectangle outlines, \a pRects in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, + int nrects, xRectangle *pRects) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XRectangle *)pRects, nrects); + + dmxSync(dmxScreen, FALSE); +} + +/** Render list of arc outlines, \a parcs in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *parcs) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XArc *)parcs, narcs); + dmxSync(dmxScreen, FALSE); +} + +/** Render a filled polygons in \a pDrawable on the back-end server + * associated with \a pDrawable's screen. If the offscreen + * optimization is enabled, only draw when \a pDrawable is at least + * partially visible. */ +void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC, + int shape, int mode, int count, DDXPointPtr pPts) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XPoint *)pPts, count, shape, mode); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of filled rectangles, \a prectInit in \a pDrawable on + * the back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, + int nrectFill, xRectangle *prectInit) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XRectangle *)prectInit, nrectFill); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end + * server associated with \a pDrawable's screen. If the offscreen + * optimization is enabled, only draw when \a pDrawable is at least + * partially visible. */ +void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *parcs) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XArc *)parcs, narcs); + dmxSync(dmxScreen, FALSE); +} + +/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on + * the back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, char *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + unsigned long n, i; + int w; + CharInfoPtr charinfo[255]; + Drawable draw; + + GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, + Linear8Bit, &n, charinfo); + + /* Calculate text width */ + w = 0; + for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + + if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) { + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, chars, count); + dmxSync(dmxScreen, FALSE); + } + + return x+w; +} + +/** Render string of 16-bit \a chars (foreground only) in \a pDrawable + * on the back-end server associated with \a pDrawable's screen. If + * the offscreen optimization is enabled, only draw when \a pDrawable + * is at least partially visible. */ +int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, unsigned short *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + unsigned long n, i; + int w; + CharInfoPtr charinfo[255]; + Drawable draw; + + GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, + (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, + &n, charinfo); + + /* Calculate text width */ + w = 0; + for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + + if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) { + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, (XChar2b *)chars, count); + dmxSync(dmxScreen, FALSE); + } + + return x+w; +} + +/** Render string of 8-bit \a chars (both foreground and background) in + * \a pDrawable on the back-end server associated with \a pDrawable's + * screen. If the offscreen optimization is enabled, only draw when \a + * pDrawable is at least partially visible. */ +void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, char *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, chars, count); + dmxSync(dmxScreen, FALSE); +} + +/** Render string of 16-bit \a chars (both foreground and background) in + * \a pDrawable on the back-end server associated with \a pDrawable's + * screen. If the offscreen optimization is enabled, only draw when \a + * pDrawable is at least partially visible. */ +void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, unsigned short *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, (XChar2b *)chars, count); + dmxSync(dmxScreen, FALSE); +} + +/** Image Glyph Blt -- this function should never be called. */ +void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) +{ + /* Error -- this should never happen! */ +} + +/** Poly Glyph Blt -- this function should never be called. */ +void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) +{ + /* Error -- this should never happen! */ +} + +/** Push Pixels -- this function should never be called. */ +void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, + int w, int h, int x, int y) +{ + /* Error -- this should never happen! */ +} + +/********************************************************************** + * Miscellaneous drawing commands + */ + +/** When Xinerama is active, the client pixmaps are always obtained from + * screen 0. When screen 0 is detached, the pixmaps must be obtained + * from any other screen that is not detached. Usually, this is screen + * 1. */ +static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw) +{ +#ifdef PANORAMIX + PanoramiXRes *pXinPix; + int i; + DMXScreenInfo *dmxScreen; + + if (noPanoramiXExtension) return NULL; + if (pDrawable->type != DRAWABLE_PIXMAP) return NULL; + + if (Success != dixLookupResourceByType((pointer*) &pXinPix, + pDrawable->id, XRT_PIXMAP, + NullClient, DixUnknownAccess)) + return NULL; + + FOR_NSCREENS_FORWARD_SKIP(i) { + dmxScreen = &dmxScreens[i]; + if (dmxScreen->beDisplay) { + PixmapPtr pSrc; + dmxPixPrivPtr pSrcPriv; + + dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id, + RT_PIXMAP, NullClient, DixUnknownAccess); + pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc); + if (pSrcPriv->pixmap) { + *draw = pSrcPriv->pixmap; + return dmxScreen; + } + } + } +#endif + return NULL; +} + +/** Get an image from the back-end server associated with \a pDrawable's + * screen. If \a pDrawable is a window, it must be viewable to get an + * image from it. If it is not viewable, then get the image from the + * first ancestor of \a pDrawable that is viewable. If no viewable + * ancestor is found, then simply return without getting an image. */ +void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, + unsigned int format, unsigned long planeMask, char *pdstLine) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + XImage *img; + Drawable draw; + + /* Cannot get image from unviewable window */ + if (pDrawable->type == DRAWABLE_WINDOW) { + WindowPtr pWindow = (WindowPtr)pDrawable; + if (!pWindow->viewable) { + while (!pWindow->viewable && pWindow->parent) { + sx += pWindow->origin.x - wBorderWidth(pWindow); + sx += pWindow->origin.y - wBorderWidth(pWindow); + pWindow = pWindow->parent; + } + if (!pWindow->viewable) { + return; + } + } + DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw); + if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable)) + return; + } else { + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + if (DMX_GCOPS_OFFSCREEN(pDrawable)) { + /* Try to find the pixmap on a non-detached Xinerama screen */ + dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw); + if (!dmxScreen) return; + } + } + + img = XGetImage(dmxScreen->beDisplay, draw, + sx, sy, w, h, planeMask, format); + if (img) { + int len = img->bytes_per_line * img->height; + memmove(pdstLine, img->data, len); + XDestroyImage(img); + } + + dmxSync(dmxScreen, FALSE); +} + +/** Get Spans -- this function should never be called. */ +void dmxGetSpans(DrawablePtr pDrawable, int wMax, + DDXPointPtr ppt, int *pwidth, int nspans, + char *pdstStart) +{ + /* Error -- this should never happen! */ +} diff --git a/xorg-server/hw/dmx/dmxwindow.c b/xorg-server/hw/dmx/dmxwindow.c index 16b79b830..704fcff54 100644 --- a/xorg-server/hw/dmx/dmxwindow.c +++ b/xorg-server/hw/dmx/dmxwindow.c @@ -1,1017 +1,1017 @@ -/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * This file provides support for window-related functions. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxcmap.h"
-#include "dmxvisual.h"
-#include "dmxinput.h"
-#include "dmxextension.h"
-#include "dmxpict.h"
-
-#include "windowstr.h"
-
-static void dmxDoRestackWindow(WindowPtr pWindow);
-static void dmxDoChangeWindowAttributes(WindowPtr pWindow,
- unsigned long *mask,
- XSetWindowAttributes *attribs);
-
-static void dmxDoSetShape(WindowPtr pWindow);
-
-/** Initialize the private area for the window functions. */
-Bool dmxInitWindow(ScreenPtr pScreen)
-{
- if (!dixRegisterPrivateKey(&dmxWinPrivateKeyRec, PRIVATE_WINDOW, sizeof(dmxWinPrivRec)))
- return FALSE;
-
- return TRUE;
-}
-
-
-Window dmxCreateRootWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- Window parent;
- Visual *visual;
- unsigned long mask;
- XSetWindowAttributes attribs;
- ColormapPtr pCmap;
- dmxColormapPrivPtr pCmapPriv;
-
- /* Create root window */
-
- parent = dmxScreen->scrnWin; /* This is our "Screen" window */
- visual = dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual;
-
- dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow),
- RT_COLORMAP, NullClient, DixUnknownAccess);
- pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
-
- mask = CWEventMask | CWBackingStore | CWColormap | CWBorderPixel;
- attribs.event_mask = ExposureMask;
- attribs.backing_store = NotUseful;
- attribs.colormap = pCmapPriv->cmap;
- attribs.border_pixel = 0;
-
- /* Incorporate new attributes, if needed */
- if (pWinPriv->attribMask) {
- dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs);
- mask |= pWinPriv->attribMask;
- }
-
- return XCreateWindow(dmxScreen->beDisplay,
- parent,
- pWindow->origin.x - wBorderWidth(pWindow),
- pWindow->origin.y - wBorderWidth(pWindow),
- pWindow->drawable.width,
- pWindow->drawable.height,
- pWindow->borderWidth,
- pWindow->drawable.depth,
- pWindow->drawable.class,
- visual,
- mask,
- &attribs);
-}
-
-/** Change the location and size of the "screen" window. Called from
- * dmxextension.c dmxConfigureScreenWindow(). */
-void dmxResizeScreenWindow(ScreenPtr pScreen,
- int x, int y, int w, int h)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- unsigned int m;
- XWindowChanges c;
-
- if (!dmxScreen->beDisplay)
- return;
-
- /* Handle resizing on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = x;
- c.y = y;
- c.width = w;
- c.height = h;
-
- XConfigureWindow(dmxScreen->beDisplay, dmxScreen->scrnWin, m, &c);
- dmxSync(dmxScreen, False);
-}
-
-/** Change the location and size of the "root" window. Called from
- * #dmxCreateWindow. */
-void dmxResizeRootWindow(WindowPtr pRoot,
- int x, int y, int w, int h)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pRoot->drawable.pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot);
- unsigned int m;
- XWindowChanges c;
-
- /* Handle resizing on back-end server */
- if (dmxScreen->beDisplay) {
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = x;
- c.y = y;
- c.width = (w > 0) ? w : 1;
- c.height = (h > 0) ? h : 1;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- }
-
- if (w == 0 || h == 0) {
- if (pWinPriv->mapped) {
- if (dmxScreen->beDisplay)
- XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
- pWinPriv->mapped = FALSE;
- }
- } else if (!pWinPriv->mapped) {
- if (dmxScreen->beDisplay)
- XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
- pWinPriv->mapped = TRUE;
- }
-
- if (dmxScreen->beDisplay)
- dmxSync(dmxScreen, False);
-}
-
-void dmxGetDefaultWindowAttributes(WindowPtr pWindow,
- Colormap *cmap,
- Visual **visual)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
-
- if (pWindow->drawable.class != InputOnly &&
- pWindow->optional &&
- pWindow->optional->visual != wVisual(pWindow->parent)) {
-
- /* Find the matching visual */
- *visual = dmxLookupVisualFromID(pScreen, wVisual(pWindow));
-
- /* Handle optional colormaps */
- if (pWindow->optional->colormap) {
- ColormapPtr pCmap;
- dmxColormapPrivPtr pCmapPriv;
-
- dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow),
- RT_COLORMAP, NullClient, DixUnknownAccess);
- pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
- *cmap = pCmapPriv->cmap;
- } else {
- *cmap = dmxColormapFromDefaultVisual(pScreen, *visual);
- }
- } else {
- *visual = CopyFromParent;
- *cmap = (Colormap)0;
- }
-}
-
-static Window dmxCreateNonRootWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- Window parent;
- unsigned long mask = 0L;
- XSetWindowAttributes attribs;
- dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
-
- /* Create window on back-end server */
-
- parent = pParentPriv->window;
-
- /* The parent won't exist if this call to CreateNonRootWindow came
- from ReparentWindow and the grandparent window has not yet been
- created */
- if (!parent) {
- dmxCreateAndRealizeWindow(pWindow->parent, FALSE);
- parent = pParentPriv->window;
- }
-
- /* Incorporate new attributes, if needed */
- if (pWinPriv->attribMask) {
- dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs);
- mask |= pWinPriv->attribMask;
- }
-
- /* Add in default attributes */
- if (pWindow->drawable.class != InputOnly) {
- mask |= CWBackingStore;
- attribs.backing_store = NotUseful;
-
- if (!(mask & CWColormap) && pWinPriv->cmap) {
- mask |= CWColormap;
- attribs.colormap = pWinPriv->cmap;
- if (!(mask & CWBorderPixel)) {
- mask |= CWBorderPixel;
- attribs.border_pixel = 0;
- }
- }
- }
-
- /* Handle case where subwindows are being mapped, but created out of
- order -- if current window has a previous sibling, then it cannot
- be created on top of the stack, so we must restack the windows */
- pWinPriv->restacked = (pWindow->prevSib != NullWindow);
-
- return XCreateWindow(dmxScreen->beDisplay,
- parent,
- pWindow->origin.x - wBorderWidth(pWindow),
- pWindow->origin.y - wBorderWidth(pWindow),
- pWindow->drawable.width,
- pWindow->drawable.height,
- pWindow->borderWidth,
- pWindow->drawable.depth,
- pWindow->drawable.class,
- pWinPriv->visual,
- mask,
- &attribs);
-}
-
-/** This function handles lazy window creation and realization. Window
- * creation is handled by #dmxCreateNonRootWindow(). It also handles
- * any stacking changes that have occured since the window was
- * originally created by calling #dmxDoRestackWindow(). If the window
- * is shaped, the shape is set on the back-end server by calling
- * #dmxDoSetShape(), and if the window has pictures (from RENDER)
- * associated with it, those pictures are created on the back-end
- * server by calling #dmxCreatePictureList(). If \a doSync is TRUE,
- * then #dmxSync() is called. */
-void dmxCreateAndRealizeWindow(WindowPtr pWindow, Bool doSync)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- if (!dmxScreen->beDisplay) return;
-
- pWinPriv->window = dmxCreateNonRootWindow(pWindow);
- if (pWinPriv->restacked) dmxDoRestackWindow(pWindow);
- if (pWinPriv->isShaped) dmxDoSetShape(pWindow);
- if (pWinPriv->hasPict) dmxCreatePictureList(pWindow);
- if (pWinPriv->mapped) XMapWindow(dmxScreen->beDisplay,
- pWinPriv->window);
- if (doSync) dmxSync(dmxScreen, False);
-}
-
-/** Create \a pWindow on the back-end server. If the lazy window
- * creation optimization is enabled, then the actual creation and
- * realization of the window is handled by
- * #dmxCreateAndRealizeWindow(). */
-Bool dmxCreateWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- Bool ret = TRUE;
-
- DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->CreateWindow)
- ret = pScreen->CreateWindow(pWindow);
-#endif
-
- /* Set up the defaults */
- pWinPriv->window = (Window)0;
- pWinPriv->offscreen = TRUE;
- pWinPriv->mapped = FALSE;
- pWinPriv->restacked = FALSE;
- pWinPriv->attribMask = 0;
- pWinPriv->isShaped = FALSE;
- pWinPriv->hasPict = FALSE;
-#ifdef GLXEXT
- pWinPriv->swapGroup = NULL;
- pWinPriv->barrier = 0;
-#endif
-
- if (dmxScreen->beDisplay) {
- /* Only create the root window at this stage -- non-root windows are
- created when they are mapped and are on-screen */
- if (!pWindow->parent) {
- dmxScreen->rootWin = pWinPriv->window
- = dmxCreateRootWindow(pWindow);
- if (dmxScreen->scrnX != dmxScreen->rootX
- || dmxScreen->scrnY != dmxScreen->rootY
- || dmxScreen->scrnWidth != dmxScreen->rootWidth
- || dmxScreen->scrnHeight != dmxScreen->rootHeight) {
- dmxResizeRootWindow(pWindow,
- dmxScreen->rootX,
- dmxScreen->rootY,
- dmxScreen->rootWidth,
- dmxScreen->rootHeight);
- dmxUpdateScreenResources(screenInfo.screens[dmxScreen->index],
- dmxScreen->rootX,
- dmxScreen->rootY,
- dmxScreen->rootWidth,
- dmxScreen->rootHeight);
- pWindow->origin.x = dmxScreen->rootX;
- pWindow->origin.y = dmxScreen->rootY;
- }
- } else {
- dmxGetDefaultWindowAttributes(pWindow,
- &pWinPriv->cmap,
- &pWinPriv->visual);
-
- if (dmxLazyWindowCreation) {
- /* Save parent's visual for use later */
- if (pWinPriv->visual == CopyFromParent)
- pWinPriv->visual =
- dmxLookupVisualFromID(pScreen,
- wVisual(pWindow->parent));
- } else {
- pWinPriv->window = dmxCreateNonRootWindow(pWindow);
- }
- }
-
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
-
- return ret;
-}
-
-/** Destroy \a pWindow on the back-end server. */
-Bool dmxBEDestroyWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- if (pWinPriv->window) {
- XDestroyWindow(dmxScreen->beDisplay, pWinPriv->window);
- pWinPriv->window = (Window)0;
- return TRUE;
- }
-
- return FALSE;
-}
-
-/** Destroy \a pWindow on the back-end server. If any RENDER pictures
- were created, destroy them as well. */
-Bool dmxDestroyWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- Bool needSync = FALSE;
-#ifdef GLXEXT
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-#endif
-
- DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
-
- /* Destroy any picture list associated with this window */
- needSync |= dmxDestroyPictureList(pWindow);
-
- /* Destroy window on back-end server */
- needSync |= dmxBEDestroyWindow(pWindow);
- if (needSync) dmxSync(dmxScreen, FALSE);
-
-#ifdef GLXEXT
- if (pWinPriv->swapGroup && pWinPriv->windowDestroyed)
- pWinPriv->windowDestroyed(pWindow);
-#endif
-
- if (pScreen->DestroyWindow)
- ret = pScreen->DestroyWindow(pWindow);
-
- DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
-
- return ret;
-}
-
-/** Change the position of \a pWindow to be \a x, \a y. */
-Bool dmxPositionWindow(WindowPtr pWindow, int x, int y)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- unsigned int m;
- XWindowChanges c;
-
- DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->PositionWindow)
- ret = pScreen->PositionWindow(pWindow, x, y);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window is now on-screen and it is mapped and it has not
- been created yet, create it and map it */
- if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, TRUE);
- } else if (pWinPriv->window) {
- /* Position window on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = pWindow->origin.x - wBorderWidth(pWindow);
- c.y = pWindow->origin.y - wBorderWidth(pWindow);
- c.width = pWindow->drawable.width;
- c.height = pWindow->drawable.height;
- if (pWindow->drawable.class != InputOnly) {
- m |= CWBorderWidth;
- c.border_width = pWindow->borderWidth;
- }
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
-
- return ret;
-}
-
-static void dmxDoChangeWindowAttributes(WindowPtr pWindow,
- unsigned long *mask,
- XSetWindowAttributes *attribs)
-{
- dmxPixPrivPtr pPixPriv;
-
- if (*mask & CWBackPixmap) {
- switch (pWindow->backgroundState) {
- case None:
- attribs->background_pixmap = None;
- break;
-
- case ParentRelative:
- attribs->background_pixmap = ParentRelative;
- break;
-
- case BackgroundPixmap:
- pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->background.pixmap);
- attribs->background_pixmap = pPixPriv->pixmap;
- break;
-
- case BackgroundPixel:
- *mask &= ~CWBackPixmap;
- break;
- }
- }
-
- if (*mask & CWBackPixel) {
- if (pWindow->backgroundState == BackgroundPixel)
- attribs->background_pixel = pWindow->background.pixel;
- else
- *mask &= ~CWBackPixel;
- }
-
- if (*mask & CWBorderPixmap) {
- if (pWindow->borderIsPixel)
- *mask &= ~CWBorderPixmap;
- else {
- pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->border.pixmap);
- attribs->border_pixmap = pPixPriv->pixmap;
- }
- }
-
- if (*mask & CWBorderPixel) {
- if (pWindow->borderIsPixel)
- attribs->border_pixel = pWindow->border.pixel;
- else
- *mask &= ~CWBorderPixel;
- }
-
- if (*mask & CWBitGravity)
- attribs->bit_gravity = pWindow->bitGravity;
-
- if (*mask & CWWinGravity)
- *mask &= ~CWWinGravity; /* Handled by dix */
-
- if (*mask & CWBackingStore)
- *mask &= ~CWBackingStore; /* Backing store not supported */
-
- if (*mask & CWBackingPlanes)
- *mask &= ~CWBackingPlanes; /* Backing store not supported */
-
- if (*mask & CWBackingPixel)
- *mask &= ~CWBackingPixel; /* Backing store not supported */
-
- if (*mask & CWOverrideRedirect)
- attribs->override_redirect = pWindow->overrideRedirect;
-
- if (*mask & CWSaveUnder)
- *mask &= ~CWSaveUnder; /* Save unders not supported */
-
- if (*mask & CWEventMask)
- *mask &= ~CWEventMask; /* Events are handled by dix */
-
- if (*mask & CWDontPropagate)
- *mask &= ~CWDontPropagate; /* Events are handled by dix */
-
- if (*mask & CWColormap) {
- ColormapPtr pCmap;
- dmxColormapPrivPtr pCmapPriv;
-
- dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow),
- RT_COLORMAP, NullClient, DixUnknownAccess);
- pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
- attribs->colormap = pCmapPriv->cmap;
- }
-
- if (*mask & CWCursor)
- *mask &= ~CWCursor; /* Handled by the cursor code */
-}
-
-/** Change the window attributes of \a pWindow. */
-Bool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- XSetWindowAttributes attribs;
-
- DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
-#if 0
- if (pScreen->ChangeWindowAttributes)
- ret = pScreen->ChangeWindowAttributes(pWindow, mask);
-#endif
-
- /* Change window attribs on back-end server */
- dmxDoChangeWindowAttributes(pWindow, &mask, &attribs);
-
- /* Save mask for lazy window creation optimization */
- pWinPriv->attribMask |= mask;
-
- if (mask && pWinPriv->window) {
- XChangeWindowAttributes(dmxScreen->beDisplay, pWinPriv->window,
- mask, &attribs);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
- pScreen);
-
- return ret;
-}
-
-/** Realize \a pWindow on the back-end server. If the lazy window
- * creation optimization is enabled, the window is only realized when
- * it at least partially overlaps the screen. */
-Bool dmxRealizeWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->RealizeWindow)
- ret = pScreen->RealizeWindow(pWindow);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window hasn't been created and it's not offscreen, then
- create it */
- if (!pWinPriv->window && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, FALSE);
- }
-
- if (pWinPriv->window) {
- /* Realize window on back-end server */
- XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
- dmxSync(dmxScreen, False);
- }
-
- /* Let the other functions know that the window is now mapped */
- pWinPriv->mapped = TRUE;
-
- DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
-
- dmxUpdateWindowInfo(DMX_UPDATE_REALIZE, pWindow);
- return ret;
-}
-
-/** Unrealize \a pWindow on the back-end server. */
-Bool dmxUnrealizeWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->UnrealizeWindow)
- ret = pScreen->UnrealizeWindow(pWindow);
-#endif
-
- if (pWinPriv->window) {
- /* Unrealize window on back-end server */
- XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
- dmxSync(dmxScreen, False);
- }
-
- /* When unrealized (i.e., unmapped), the window is always considered
- off of the visible portion of the screen */
- pWinPriv->offscreen = TRUE;
- pWinPriv->mapped = FALSE;
-
-#ifdef GLXEXT
- if (pWinPriv->swapGroup && pWinPriv->windowUnmapped)
- pWinPriv->windowUnmapped(pWindow);
-#endif
-
- DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
-
- dmxUpdateWindowInfo(DMX_UPDATE_UNREALIZE, pWindow);
- return ret;
-}
-
-static void dmxDoRestackWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- WindowPtr pNextSib = pWindow->nextSib;
- unsigned int m;
- XWindowChanges c;
-
- if (pNextSib == NullWindow) {
- /* Window is at the bottom of the stack */
- m = CWStackMode;
- c.sibling = (Window)0;
- c.stack_mode = Below;
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- } else {
- /* Window is not at the bottom of the stack */
- dmxWinPrivPtr pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
-
- /* Handle case where siblings have not yet been created due to
- lazy window creation optimization by first finding the next
- sibling in the sibling list that has been created (if any)
- and then putting the current window just above that sibling,
- and if no next siblings have been created yet, then put it at
- the bottom of the stack (since it might have a previous
- sibling that should be above it). */
- while (!pNextSibPriv->window) {
- pNextSib = pNextSib->nextSib;
- if (pNextSib == NullWindow) {
- /* Window is at the bottom of the stack */
- m = CWStackMode;
- c.sibling = (Window)0;
- c.stack_mode = Below;
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- return;
- }
- pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
- }
-
- m = CWStackMode | CWSibling;
- c.sibling = pNextSibPriv->window;
- c.stack_mode = Above;
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- }
-}
-
-/** Handle window restacking. The actual restacking occurs in
- * #dmxDoRestackWindow(). */
-void dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->RestackWindow)
- pScreen->RestackWindow(pWindow, pOldNextSib);
-#endif
-
- if (pOldNextSib != pWindow->nextSib) {
- /* Track restacking for lazy window creation optimization */
- pWinPriv->restacked = TRUE;
-
- /* Restack window on back-end server */
- if (pWinPriv->window) {
- dmxDoRestackWindow(pWindow);
- dmxSync(dmxScreen, False);
- }
- }
-
- DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_RESTACK, pWindow);
-}
-
-static Bool dmxWindowExposurePredicate(Display *dpy, XEvent *ev, XPointer ptr)
-{
- return (ev->type == Expose && ev->xexpose.window == *(Window *)ptr);
-}
-
-/** Handle exposures on \a pWindow. Since window exposures are handled
- * in DMX, the events that are generated by the back-end server are
- * redundant, so we eat them here. */
-void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn,
- RegionPtr other_exposed)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- XEvent ev;
-
- DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
-
- dmxSync(dmxScreen, False);
-
- if (pWinPriv->window) {
- while (XCheckIfEvent(dmxScreen->beDisplay, &ev,
- dmxWindowExposurePredicate,
- (XPointer)&pWinPriv->window)) {
- /* Handle expose events -- this should not be necessary
- since the base window in which the root window was
- created is guaranteed to be on top (override_redirect),
- so we should just swallow these events. If for some
- reason the window is not on top, then we'd need to
- collect these events and send them to the client later
- (e.g., during the block handler as Xnest does). */
- }
- }
-
-#if 1
- if (pScreen->WindowExposures)
- pScreen->WindowExposures(pWindow, prgn, other_exposed);
-#endif
- DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
-}
-
-/** Move \a pWindow on the back-end server. Determine whether or not it
- * is on or offscreen, and realize it if it is newly on screen and the
- * lazy window creation optimization is enabled. */
-void dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- unsigned int m;
- XWindowChanges c;
-
- DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->CopyWindow)
- pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window is now on-screen and it is mapped and it has not
- been created yet, create it and map it */
- if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, TRUE);
- } else if (pWinPriv->window) {
- /* Move window on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = pWindow->origin.x - wBorderWidth(pWindow);
- c.y = pWindow->origin.y - wBorderWidth(pWindow);
- c.width = pWindow->drawable.width;
- c.height = pWindow->drawable.height;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_COPY, pWindow);
-}
-
-/** Resize \a pWindow on the back-end server. Determine whether or not
- * it is on or offscreen, and realize it if it is newly on screen and
- * the lazy window creation optimization is enabled. */
-void dmxResizeWindow(WindowPtr pWindow, int x, int y,
- unsigned int w, unsigned int h, WindowPtr pSib)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- dmxWinPrivPtr pSibPriv;
- unsigned int m;
- XWindowChanges c;
-
- if (pSib)
- pSibPriv = DMX_GET_WINDOW_PRIV(pSib);
-
- DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
-#if 1
- if (pScreen->ResizeWindow)
- pScreen->ResizeWindow(pWindow, x, y, w, h, pSib);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window is now on-screen and it is mapped and it has not
- been created yet, create it and map it */
- if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, TRUE);
- } else if (pWinPriv->window) {
- /* Handle resizing on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = pWindow->origin.x - wBorderWidth(pWindow);
- c.y = pWindow->origin.y - wBorderWidth(pWindow);
- c.width = pWindow->drawable.width;
- c.height = pWindow->drawable.height;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_RESIZE, pWindow);
-}
-
-/** Reparent \a pWindow on the back-end server. */
-void dmxReparentWindow(WindowPtr pWindow, WindowPtr pPriorParent)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
-
- DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->ReparentWindow)
- pScreen->ReparentWindow(pWindow, pPriorParent);
-#endif
-
- if (pWinPriv->window) {
- if (!pParentPriv->window) {
- dmxCreateAndRealizeWindow(pWindow->parent, FALSE);
- }
-
- /* Handle reparenting on back-end server */
- XReparentWindow(dmxScreen->beDisplay, pWinPriv->window,
- pParentPriv->window,
- pWindow->origin.x - wBorderWidth(pWindow),
- pWindow->origin.x - wBorderWidth(pWindow));
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_REPARENT, pWindow);
-}
-
-/** Change border width for \a pWindow to \a width pixels. */
-void dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- unsigned int m;
- XWindowChanges c;
-
- DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
-#if 1
- if (pScreen->ChangeBorderWidth)
- pScreen->ChangeBorderWidth(pWindow, width);
-#endif
-
- /* NOTE: Do we need to check for on/off screen here? */
-
- if (pWinPriv->window) {
- /* Handle border width change on back-end server */
- m = CWBorderWidth;
- c.border_width = width;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
-}
-
-static void dmxDoSetShape(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- int nBox;
- BoxPtr pBox;
- int nRect;
- XRectangle *pRect;
- XRectangle *pRectFirst;
-
- /* First, set the bounding shape */
- if (wBoundingShape(pWindow)) {
- pBox = RegionRects(wBoundingShape(pWindow));
- nRect = nBox = RegionNumRects(wBoundingShape(pWindow));
- pRectFirst = pRect = malloc(nRect * sizeof(*pRect));
- while (nBox--) {
- pRect->x = pBox->x1;
- pRect->y = pBox->y1;
- pRect->width = pBox->x2 - pBox->x1;
- pRect->height = pBox->y2 - pBox->y1;
- pBox++;
- pRect++;
- }
- XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
- ShapeBounding, 0, 0,
- pRectFirst, nRect,
- ShapeSet, YXBanded);
- free(pRectFirst);
- } else {
- XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
- ShapeBounding, 0, 0, None, ShapeSet);
- }
-
- /* Next, set the clip shape */
- if (wClipShape(pWindow)) {
- pBox = RegionRects(wClipShape(pWindow));
- nRect = nBox = RegionNumRects(wClipShape(pWindow));
- pRectFirst = pRect = malloc(nRect * sizeof(*pRect));
- while (nBox--) {
- pRect->x = pBox->x1;
- pRect->y = pBox->y1;
- pRect->width = pBox->x2 - pBox->x1;
- pRect->height = pBox->y2 - pBox->y1;
- pBox++;
- pRect++;
- }
- XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
- ShapeClip, 0, 0,
- pRectFirst, nRect,
- ShapeSet, YXBanded);
- free(pRectFirst);
- } else {
- XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
- ShapeClip, 0, 0, None, ShapeSet);
- }
-
- if (XShapeInputSelected(dmxScreen->beDisplay, pWinPriv->window)) {
- ErrorF("Input selected for window %x on Screen %d\n",
- (unsigned int)pWinPriv->window, pScreen->myNum);
- }
-}
-
-/** Set shape of \a pWindow on the back-end server. */
-void dmxSetShape(WindowPtr pWindow, int kind)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(SetShape, dmxScreen, pScreen);
-#if 1
- if (pScreen->SetShape)
- pScreen->SetShape(pWindow, kind);
-#endif
-
- if (pWinPriv->window) {
- /* Handle setting the current shape on the back-end server */
- dmxDoSetShape(pWindow);
- dmxSync(dmxScreen, False);
- } else {
- pWinPriv->isShaped = TRUE;
- }
-
- DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
-}
+/* + * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Kevin E. Martin <kem@redhat.com> + * + */ + +/** \file + * This file provides support for window-related functions. */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxsync.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" +#include "dmxcmap.h" +#include "dmxvisual.h" +#include "dmxinput.h" +#include "dmxextension.h" +#include "dmxpict.h" + +#include "windowstr.h" + +static void dmxDoRestackWindow(WindowPtr pWindow); +static void dmxDoChangeWindowAttributes(WindowPtr pWindow, + unsigned long *mask, + XSetWindowAttributes *attribs); + +static void dmxDoSetShape(WindowPtr pWindow); + +/** Initialize the private area for the window functions. */ +Bool dmxInitWindow(ScreenPtr pScreen) +{ + if (!dixRegisterPrivateKey(&dmxWinPrivateKeyRec, PRIVATE_WINDOW, sizeof(dmxWinPrivRec))) + return FALSE; + + return TRUE; +} + + +Window dmxCreateRootWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + Window parent; + Visual *visual; + unsigned long mask; + XSetWindowAttributes attribs; + ColormapPtr pCmap; + dmxColormapPrivPtr pCmapPriv; + + /* Create root window */ + + parent = dmxScreen->scrnWin; /* This is our "Screen" window */ + visual = dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual; + + dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow), + RT_COLORMAP, NullClient, DixUnknownAccess); + pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap); + + mask = CWEventMask | CWBackingStore | CWColormap | CWBorderPixel; + attribs.event_mask = ExposureMask; + attribs.backing_store = NotUseful; + attribs.colormap = pCmapPriv->cmap; + attribs.border_pixel = 0; + + /* Incorporate new attributes, if needed */ + if (pWinPriv->attribMask) { + dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs); + mask |= pWinPriv->attribMask; + } + + return XCreateWindow(dmxScreen->beDisplay, + parent, + pWindow->origin.x - wBorderWidth(pWindow), + pWindow->origin.y - wBorderWidth(pWindow), + pWindow->drawable.width, + pWindow->drawable.height, + pWindow->borderWidth, + pWindow->drawable.depth, + pWindow->drawable.class, + visual, + mask, + &attribs); +} + +/** Change the location and size of the "screen" window. Called from + * dmxextension.c dmxConfigureScreenWindow(). */ +void dmxResizeScreenWindow(ScreenPtr pScreen, + int x, int y, int w, int h) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + unsigned int m; + XWindowChanges c; + + if (!dmxScreen->beDisplay) + return; + + /* Handle resizing on back-end server */ + m = CWX | CWY | CWWidth | CWHeight; + c.x = x; + c.y = y; + c.width = w; + c.height = h; + + XConfigureWindow(dmxScreen->beDisplay, dmxScreen->scrnWin, m, &c); + dmxSync(dmxScreen, False); +} + +/** Change the location and size of the "root" window. Called from + * #dmxCreateWindow. */ +void dmxResizeRootWindow(WindowPtr pRoot, + int x, int y, int w, int h) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pRoot->drawable.pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot); + unsigned int m; + XWindowChanges c; + + /* Handle resizing on back-end server */ + if (dmxScreen->beDisplay) { + m = CWX | CWY | CWWidth | CWHeight; + c.x = x; + c.y = y; + c.width = (w > 0) ? w : 1; + c.height = (h > 0) ? h : 1; + + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + } + + if (w == 0 || h == 0) { + if (pWinPriv->mapped) { + if (dmxScreen->beDisplay) + XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window); + pWinPriv->mapped = FALSE; + } + } else if (!pWinPriv->mapped) { + if (dmxScreen->beDisplay) + XMapWindow(dmxScreen->beDisplay, pWinPriv->window); + pWinPriv->mapped = TRUE; + } + + if (dmxScreen->beDisplay) + dmxSync(dmxScreen, False); +} + +void dmxGetDefaultWindowAttributes(WindowPtr pWindow, + Colormap *cmap, + Visual **visual) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + + if (pWindow->drawable.class != InputOnly && + pWindow->optional && + pWindow->optional->visual != wVisual(pWindow->parent)) { + + /* Find the matching visual */ + *visual = dmxLookupVisualFromID(pScreen, wVisual(pWindow)); + + /* Handle optional colormaps */ + if (pWindow->optional->colormap) { + ColormapPtr pCmap; + dmxColormapPrivPtr pCmapPriv; + + dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow), + RT_COLORMAP, NullClient, DixUnknownAccess); + pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap); + *cmap = pCmapPriv->cmap; + } else { + *cmap = dmxColormapFromDefaultVisual(pScreen, *visual); + } + } else { + *visual = CopyFromParent; + *cmap = (Colormap)0; + } +} + +static Window dmxCreateNonRootWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + Window parent; + unsigned long mask = 0L; + XSetWindowAttributes attribs; + dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent); + + /* Create window on back-end server */ + + parent = pParentPriv->window; + + /* The parent won't exist if this call to CreateNonRootWindow came + from ReparentWindow and the grandparent window has not yet been + created */ + if (!parent) { + dmxCreateAndRealizeWindow(pWindow->parent, FALSE); + parent = pParentPriv->window; + } + + /* Incorporate new attributes, if needed */ + if (pWinPriv->attribMask) { + dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs); + mask |= pWinPriv->attribMask; + } + + /* Add in default attributes */ + if (pWindow->drawable.class != InputOnly) { + mask |= CWBackingStore; + attribs.backing_store = NotUseful; + + if (!(mask & CWColormap) && pWinPriv->cmap) { + mask |= CWColormap; + attribs.colormap = pWinPriv->cmap; + if (!(mask & CWBorderPixel)) { + mask |= CWBorderPixel; + attribs.border_pixel = 0; + } + } + } + + /* Handle case where subwindows are being mapped, but created out of + order -- if current window has a previous sibling, then it cannot + be created on top of the stack, so we must restack the windows */ + pWinPriv->restacked = (pWindow->prevSib != NullWindow); + + return XCreateWindow(dmxScreen->beDisplay, + parent, + pWindow->origin.x - wBorderWidth(pWindow), + pWindow->origin.y - wBorderWidth(pWindow), + pWindow->drawable.width, + pWindow->drawable.height, + pWindow->borderWidth, + pWindow->drawable.depth, + pWindow->drawable.class, + pWinPriv->visual, + mask, + &attribs); +} + +/** This function handles lazy window creation and realization. Window + * creation is handled by #dmxCreateNonRootWindow(). It also handles + * any stacking changes that have occured since the window was + * originally created by calling #dmxDoRestackWindow(). If the window + * is shaped, the shape is set on the back-end server by calling + * #dmxDoSetShape(), and if the window has pictures (from RENDER) + * associated with it, those pictures are created on the back-end + * server by calling #dmxCreatePictureList(). If \a doSync is TRUE, + * then #dmxSync() is called. */ +void dmxCreateAndRealizeWindow(WindowPtr pWindow, Bool doSync) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + + if (!dmxScreen->beDisplay) return; + + pWinPriv->window = dmxCreateNonRootWindow(pWindow); + if (pWinPriv->restacked) dmxDoRestackWindow(pWindow); + if (pWinPriv->isShaped) dmxDoSetShape(pWindow); + if (pWinPriv->hasPict) dmxCreatePictureList(pWindow); + if (pWinPriv->mapped) XMapWindow(dmxScreen->beDisplay, + pWinPriv->window); + if (doSync) dmxSync(dmxScreen, False); +} + +/** Create \a pWindow on the back-end server. If the lazy window + * creation optimization is enabled, then the actual creation and + * realization of the window is handled by + * #dmxCreateAndRealizeWindow(). */ +Bool dmxCreateWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + Bool ret = TRUE; + + DMX_UNWRAP(CreateWindow, dmxScreen, pScreen); +#if 0 + if (pScreen->CreateWindow) + ret = pScreen->CreateWindow(pWindow); +#endif + + /* Set up the defaults */ + pWinPriv->window = (Window)0; + pWinPriv->offscreen = TRUE; + pWinPriv->mapped = FALSE; + pWinPriv->restacked = FALSE; + pWinPriv->attribMask = 0; + pWinPriv->isShaped = FALSE; + pWinPriv->hasPict = FALSE; +#ifdef GLXEXT + pWinPriv->swapGroup = NULL; + pWinPriv->barrier = 0; +#endif + + if (dmxScreen->beDisplay) { + /* Only create the root window at this stage -- non-root windows are + created when they are mapped and are on-screen */ + if (!pWindow->parent) { + dmxScreen->rootWin = pWinPriv->window + = dmxCreateRootWindow(pWindow); + if (dmxScreen->scrnX != dmxScreen->rootX + || dmxScreen->scrnY != dmxScreen->rootY + || dmxScreen->scrnWidth != dmxScreen->rootWidth + || dmxScreen->scrnHeight != dmxScreen->rootHeight) { + dmxResizeRootWindow(pWindow, + dmxScreen->rootX, + dmxScreen->rootY, + dmxScreen->rootWidth, + dmxScreen->rootHeight); + dmxUpdateScreenResources(screenInfo.screens[dmxScreen->index], + dmxScreen->rootX, + dmxScreen->rootY, + dmxScreen->rootWidth, + dmxScreen->rootHeight); + pWindow->origin.x = dmxScreen->rootX; + pWindow->origin.y = dmxScreen->rootY; + } + } else { + dmxGetDefaultWindowAttributes(pWindow, + &pWinPriv->cmap, + &pWinPriv->visual); + + if (dmxLazyWindowCreation) { + /* Save parent's visual for use later */ + if (pWinPriv->visual == CopyFromParent) + pWinPriv->visual = + dmxLookupVisualFromID(pScreen, + wVisual(pWindow->parent)); + } else { + pWinPriv->window = dmxCreateNonRootWindow(pWindow); + } + } + + dmxSync(dmxScreen, False); + } + + DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen); + + return ret; +} + +/** Destroy \a pWindow on the back-end server. */ +Bool dmxBEDestroyWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + + if (pWinPriv->window) { + XDestroyWindow(dmxScreen->beDisplay, pWinPriv->window); + pWinPriv->window = (Window)0; + return TRUE; + } + + return FALSE; +} + +/** Destroy \a pWindow on the back-end server. If any RENDER pictures + were created, destroy them as well. */ +Bool dmxDestroyWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + Bool ret = TRUE; + Bool needSync = FALSE; +#ifdef GLXEXT + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); +#endif + + DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen); + + /* Destroy any picture list associated with this window */ + needSync |= dmxDestroyPictureList(pWindow); + + /* Destroy window on back-end server */ + needSync |= dmxBEDestroyWindow(pWindow); + if (needSync) dmxSync(dmxScreen, FALSE); + +#ifdef GLXEXT + if (pWinPriv->swapGroup && pWinPriv->windowDestroyed) + pWinPriv->windowDestroyed(pWindow); +#endif + + if (pScreen->DestroyWindow) + ret = pScreen->DestroyWindow(pWindow); + + DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen); + + return ret; +} + +/** Change the position of \a pWindow to be \a x, \a y. */ +Bool dmxPositionWindow(WindowPtr pWindow, int x, int y) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + Bool ret = TRUE; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + unsigned int m; + XWindowChanges c; + + DMX_UNWRAP(PositionWindow, dmxScreen, pScreen); +#if 0 + if (pScreen->PositionWindow) + ret = pScreen->PositionWindow(pWindow, x, y); +#endif + + /* Determine if the window is completely off the visible portion of + the screen */ + pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); + + /* If the window is now on-screen and it is mapped and it has not + been created yet, create it and map it */ + if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) { + dmxCreateAndRealizeWindow(pWindow, TRUE); + } else if (pWinPriv->window) { + /* Position window on back-end server */ + m = CWX | CWY | CWWidth | CWHeight; + c.x = pWindow->origin.x - wBorderWidth(pWindow); + c.y = pWindow->origin.y - wBorderWidth(pWindow); + c.width = pWindow->drawable.width; + c.height = pWindow->drawable.height; + if (pWindow->drawable.class != InputOnly) { + m |= CWBorderWidth; + c.border_width = pWindow->borderWidth; + } + + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + dmxSync(dmxScreen, False); + } + + DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen); + + return ret; +} + +static void dmxDoChangeWindowAttributes(WindowPtr pWindow, + unsigned long *mask, + XSetWindowAttributes *attribs) +{ + dmxPixPrivPtr pPixPriv; + + if (*mask & CWBackPixmap) { + switch (pWindow->backgroundState) { + case None: + attribs->background_pixmap = None; + break; + + case ParentRelative: + attribs->background_pixmap = ParentRelative; + break; + + case BackgroundPixmap: + pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->background.pixmap); + attribs->background_pixmap = pPixPriv->pixmap; + break; + + case BackgroundPixel: + *mask &= ~CWBackPixmap; + break; + } + } + + if (*mask & CWBackPixel) { + if (pWindow->backgroundState == BackgroundPixel) + attribs->background_pixel = pWindow->background.pixel; + else + *mask &= ~CWBackPixel; + } + + if (*mask & CWBorderPixmap) { + if (pWindow->borderIsPixel) + *mask &= ~CWBorderPixmap; + else { + pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->border.pixmap); + attribs->border_pixmap = pPixPriv->pixmap; + } + } + + if (*mask & CWBorderPixel) { + if (pWindow->borderIsPixel) + attribs->border_pixel = pWindow->border.pixel; + else + *mask &= ~CWBorderPixel; + } + + if (*mask & CWBitGravity) + attribs->bit_gravity = pWindow->bitGravity; + + if (*mask & CWWinGravity) + *mask &= ~CWWinGravity; /* Handled by dix */ + + if (*mask & CWBackingStore) + *mask &= ~CWBackingStore; /* Backing store not supported */ + + if (*mask & CWBackingPlanes) + *mask &= ~CWBackingPlanes; /* Backing store not supported */ + + if (*mask & CWBackingPixel) + *mask &= ~CWBackingPixel; /* Backing store not supported */ + + if (*mask & CWOverrideRedirect) + attribs->override_redirect = pWindow->overrideRedirect; + + if (*mask & CWSaveUnder) + *mask &= ~CWSaveUnder; /* Save unders not supported */ + + if (*mask & CWEventMask) + *mask &= ~CWEventMask; /* Events are handled by dix */ + + if (*mask & CWDontPropagate) + *mask &= ~CWDontPropagate; /* Events are handled by dix */ + + if (*mask & CWColormap) { + ColormapPtr pCmap; + dmxColormapPrivPtr pCmapPriv; + + dixLookupResourceByType((pointer*) &pCmap, wColormap(pWindow), + RT_COLORMAP, NullClient, DixUnknownAccess); + pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap); + attribs->colormap = pCmapPriv->cmap; + } + + if (*mask & CWCursor) + *mask &= ~CWCursor; /* Handled by the cursor code */ +} + +/** Change the window attributes of \a pWindow. */ +Bool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + Bool ret = TRUE; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + XSetWindowAttributes attribs; + + DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen); +#if 0 + if (pScreen->ChangeWindowAttributes) + ret = pScreen->ChangeWindowAttributes(pWindow, mask); +#endif + + /* Change window attribs on back-end server */ + dmxDoChangeWindowAttributes(pWindow, &mask, &attribs); + + /* Save mask for lazy window creation optimization */ + pWinPriv->attribMask |= mask; + + if (mask && pWinPriv->window) { + XChangeWindowAttributes(dmxScreen->beDisplay, pWinPriv->window, + mask, &attribs); + dmxSync(dmxScreen, False); + } + + DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen, + pScreen); + + return ret; +} + +/** Realize \a pWindow on the back-end server. If the lazy window + * creation optimization is enabled, the window is only realized when + * it at least partially overlaps the screen. */ +Bool dmxRealizeWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + Bool ret = TRUE; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + + DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen); +#if 0 + if (pScreen->RealizeWindow) + ret = pScreen->RealizeWindow(pWindow); +#endif + + /* Determine if the window is completely off the visible portion of + the screen */ + pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); + + /* If the window hasn't been created and it's not offscreen, then + create it */ + if (!pWinPriv->window && !pWinPriv->offscreen) { + dmxCreateAndRealizeWindow(pWindow, FALSE); + } + + if (pWinPriv->window) { + /* Realize window on back-end server */ + XMapWindow(dmxScreen->beDisplay, pWinPriv->window); + dmxSync(dmxScreen, False); + } + + /* Let the other functions know that the window is now mapped */ + pWinPriv->mapped = TRUE; + + DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen); + + dmxUpdateWindowInfo(DMX_UPDATE_REALIZE, pWindow); + return ret; +} + +/** Unrealize \a pWindow on the back-end server. */ +Bool dmxUnrealizeWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + Bool ret = TRUE; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + + DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen); +#if 0 + if (pScreen->UnrealizeWindow) + ret = pScreen->UnrealizeWindow(pWindow); +#endif + + if (pWinPriv->window) { + /* Unrealize window on back-end server */ + XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window); + dmxSync(dmxScreen, False); + } + + /* When unrealized (i.e., unmapped), the window is always considered + off of the visible portion of the screen */ + pWinPriv->offscreen = TRUE; + pWinPriv->mapped = FALSE; + +#ifdef GLXEXT + if (pWinPriv->swapGroup && pWinPriv->windowUnmapped) + pWinPriv->windowUnmapped(pWindow); +#endif + + DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen); + + dmxUpdateWindowInfo(DMX_UPDATE_UNREALIZE, pWindow); + return ret; +} + +static void dmxDoRestackWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + WindowPtr pNextSib = pWindow->nextSib; + unsigned int m; + XWindowChanges c; + + if (pNextSib == NullWindow) { + /* Window is at the bottom of the stack */ + m = CWStackMode; + c.sibling = (Window)0; + c.stack_mode = Below; + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + } else { + /* Window is not at the bottom of the stack */ + dmxWinPrivPtr pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib); + + /* Handle case where siblings have not yet been created due to + lazy window creation optimization by first finding the next + sibling in the sibling list that has been created (if any) + and then putting the current window just above that sibling, + and if no next siblings have been created yet, then put it at + the bottom of the stack (since it might have a previous + sibling that should be above it). */ + while (!pNextSibPriv->window) { + pNextSib = pNextSib->nextSib; + if (pNextSib == NullWindow) { + /* Window is at the bottom of the stack */ + m = CWStackMode; + c.sibling = (Window)0; + c.stack_mode = Below; + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + return; + } + pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib); + } + + m = CWStackMode | CWSibling; + c.sibling = pNextSibPriv->window; + c.stack_mode = Above; + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + } +} + +/** Handle window restacking. The actual restacking occurs in + * #dmxDoRestackWindow(). */ +void dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + + DMX_UNWRAP(RestackWindow, dmxScreen, pScreen); +#if 0 + if (pScreen->RestackWindow) + pScreen->RestackWindow(pWindow, pOldNextSib); +#endif + + if (pOldNextSib != pWindow->nextSib) { + /* Track restacking for lazy window creation optimization */ + pWinPriv->restacked = TRUE; + + /* Restack window on back-end server */ + if (pWinPriv->window) { + dmxDoRestackWindow(pWindow); + dmxSync(dmxScreen, False); + } + } + + DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen); + dmxUpdateWindowInfo(DMX_UPDATE_RESTACK, pWindow); +} + +static Bool dmxWindowExposurePredicate(Display *dpy, XEvent *ev, XPointer ptr) +{ + return (ev->type == Expose && ev->xexpose.window == *(Window *)ptr); +} + +/** Handle exposures on \a pWindow. Since window exposures are handled + * in DMX, the events that are generated by the back-end server are + * redundant, so we eat them here. */ +void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn, + RegionPtr other_exposed) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + XEvent ev; + + DMX_UNWRAP(WindowExposures, dmxScreen, pScreen); + + dmxSync(dmxScreen, False); + + if (pWinPriv->window) { + while (XCheckIfEvent(dmxScreen->beDisplay, &ev, + dmxWindowExposurePredicate, + (XPointer)&pWinPriv->window)) { + /* Handle expose events -- this should not be necessary + since the base window in which the root window was + created is guaranteed to be on top (override_redirect), + so we should just swallow these events. If for some + reason the window is not on top, then we'd need to + collect these events and send them to the client later + (e.g., during the block handler as Xnest does). */ + } + } + +#if 1 + if (pScreen->WindowExposures) + pScreen->WindowExposures(pWindow, prgn, other_exposed); +#endif + DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen); +} + +/** Move \a pWindow on the back-end server. Determine whether or not it + * is on or offscreen, and realize it if it is newly on screen and the + * lazy window creation optimization is enabled. */ +void dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + unsigned int m; + XWindowChanges c; + + DMX_UNWRAP(CopyWindow, dmxScreen, pScreen); +#if 0 + if (pScreen->CopyWindow) + pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc); +#endif + + /* Determine if the window is completely off the visible portion of + the screen */ + pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); + + /* If the window is now on-screen and it is mapped and it has not + been created yet, create it and map it */ + if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) { + dmxCreateAndRealizeWindow(pWindow, TRUE); + } else if (pWinPriv->window) { + /* Move window on back-end server */ + m = CWX | CWY | CWWidth | CWHeight; + c.x = pWindow->origin.x - wBorderWidth(pWindow); + c.y = pWindow->origin.y - wBorderWidth(pWindow); + c.width = pWindow->drawable.width; + c.height = pWindow->drawable.height; + + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + dmxSync(dmxScreen, False); + } + + DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen); + dmxUpdateWindowInfo(DMX_UPDATE_COPY, pWindow); +} + +/** Resize \a pWindow on the back-end server. Determine whether or not + * it is on or offscreen, and realize it if it is newly on screen and + * the lazy window creation optimization is enabled. */ +void dmxResizeWindow(WindowPtr pWindow, int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + dmxWinPrivPtr pSibPriv; + unsigned int m; + XWindowChanges c; + + if (pSib) + pSibPriv = DMX_GET_WINDOW_PRIV(pSib); + + DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen); +#if 1 + if (pScreen->ResizeWindow) + pScreen->ResizeWindow(pWindow, x, y, w, h, pSib); +#endif + + /* Determine if the window is completely off the visible portion of + the screen */ + pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow); + + /* If the window is now on-screen and it is mapped and it has not + been created yet, create it and map it */ + if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) { + dmxCreateAndRealizeWindow(pWindow, TRUE); + } else if (pWinPriv->window) { + /* Handle resizing on back-end server */ + m = CWX | CWY | CWWidth | CWHeight; + c.x = pWindow->origin.x - wBorderWidth(pWindow); + c.y = pWindow->origin.y - wBorderWidth(pWindow); + c.width = pWindow->drawable.width; + c.height = pWindow->drawable.height; + + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + dmxSync(dmxScreen, False); + } + + DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen); + dmxUpdateWindowInfo(DMX_UPDATE_RESIZE, pWindow); +} + +/** Reparent \a pWindow on the back-end server. */ +void dmxReparentWindow(WindowPtr pWindow, WindowPtr pPriorParent) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent); + + DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen); +#if 0 + if (pScreen->ReparentWindow) + pScreen->ReparentWindow(pWindow, pPriorParent); +#endif + + if (pWinPriv->window) { + if (!pParentPriv->window) { + dmxCreateAndRealizeWindow(pWindow->parent, FALSE); + } + + /* Handle reparenting on back-end server */ + XReparentWindow(dmxScreen->beDisplay, pWinPriv->window, + pParentPriv->window, + pWindow->origin.x - wBorderWidth(pWindow), + pWindow->origin.x - wBorderWidth(pWindow)); + dmxSync(dmxScreen, False); + } + + DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen); + dmxUpdateWindowInfo(DMX_UPDATE_REPARENT, pWindow); +} + +/** Change border width for \a pWindow to \a width pixels. */ +void dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + unsigned int m; + XWindowChanges c; + + DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen); +#if 1 + if (pScreen->ChangeBorderWidth) + pScreen->ChangeBorderWidth(pWindow, width); +#endif + + /* NOTE: Do we need to check for on/off screen here? */ + + if (pWinPriv->window) { + /* Handle border width change on back-end server */ + m = CWBorderWidth; + c.border_width = width; + + XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c); + dmxSync(dmxScreen, False); + } + + DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen); +} + +static void dmxDoSetShape(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + int nBox; + BoxPtr pBox; + int nRect; + XRectangle *pRect; + XRectangle *pRectFirst; + + /* First, set the bounding shape */ + if (wBoundingShape(pWindow)) { + pBox = RegionRects(wBoundingShape(pWindow)); + nRect = nBox = RegionNumRects(wBoundingShape(pWindow)); + pRectFirst = pRect = malloc(nRect * sizeof(*pRect)); + while (nBox--) { + pRect->x = pBox->x1; + pRect->y = pBox->y1; + pRect->width = pBox->x2 - pBox->x1; + pRect->height = pBox->y2 - pBox->y1; + pBox++; + pRect++; + } + XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window, + ShapeBounding, 0, 0, + pRectFirst, nRect, + ShapeSet, YXBanded); + free(pRectFirst); + } else { + XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window, + ShapeBounding, 0, 0, None, ShapeSet); + } + + /* Next, set the clip shape */ + if (wClipShape(pWindow)) { + pBox = RegionRects(wClipShape(pWindow)); + nRect = nBox = RegionNumRects(wClipShape(pWindow)); + pRectFirst = pRect = malloc(nRect * sizeof(*pRect)); + while (nBox--) { + pRect->x = pBox->x1; + pRect->y = pBox->y1; + pRect->width = pBox->x2 - pBox->x1; + pRect->height = pBox->y2 - pBox->y1; + pBox++; + pRect++; + } + XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window, + ShapeClip, 0, 0, + pRectFirst, nRect, + ShapeSet, YXBanded); + free(pRectFirst); + } else { + XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window, + ShapeClip, 0, 0, None, ShapeSet); + } + + if (XShapeInputSelected(dmxScreen->beDisplay, pWinPriv->window)) { + ErrorF("Input selected for window %x on Screen %d\n", + (unsigned int)pWinPriv->window, pScreen->myNum); + } +} + +/** Set shape of \a pWindow on the back-end server. */ +void dmxSetShape(WindowPtr pWindow, int kind) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); + + DMX_UNWRAP(SetShape, dmxScreen, pScreen); +#if 1 + if (pScreen->SetShape) + pScreen->SetShape(pWindow, kind); +#endif + + if (pWinPriv->window) { + /* Handle setting the current shape on the back-end server */ + dmxDoSetShape(pWindow); + dmxSync(dmxScreen, False); + } else { + pWinPriv->isShaped = TRUE; + } + + DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen); +} diff --git a/xorg-server/hw/dmx/doc/Makefile.am b/xorg-server/hw/dmx/doc/Makefile.am index 9a20f9487..0713884cd 100644 --- a/xorg-server/hw/dmx/doc/Makefile.am +++ b/xorg-server/hw/dmx/doc/Makefile.am @@ -1,34 +1,34 @@ -# Copyright 2005 Red Hat, Inc.
-#
-# Permission to use, copy, modify, distribute, and sell this software
-# and its documentation for any purpose is hereby granted without
-# fee, provided that the above copyright notice appear in all copies
-# and that both that copyright notice and this permission notice
-# appear in supporting documentation, and that the name of Red Hat
-# not be used in advertising or publicity pertaining to distribution
-# of the software without specific, written prior permission. Red
-# Hat makes no representations about the suitability of this software
-# for any purpose. It is provided "as is" without express or implied
-# warranty.
-#
-# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-# NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-if ENABLE_DEVEL_DOCS
-if HAVE_XMLTO
-
-# Main DocBook/XML files (DOCTYPE book)
-docbook = dmx.xml scaled.xml
-
-# Generate DocBook/XML output formats with or without stylesheets
-include $(top_srcdir)/devbook.am
-
-endif HAVE_XMLTO
-endif ENABLE_DEVEL_DOCS
-
-EXTRA_DIST = DMXSpec.txt DMXSpec-v1.txt
+# Copyright 2005 Red Hat, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software +# and its documentation for any purpose is hereby granted without +# fee, provided that the above copyright notice appear in all copies +# and that both that copyright notice and this permission notice +# appear in supporting documentation, and that the name of Red Hat +# not be used in advertising or publicity pertaining to distribution +# of the software without specific, written prior permission. Red +# Hat makes no representations about the suitability of this software +# for any purpose. It is provided "as is" without express or implied +# warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +if ENABLE_DEVEL_DOCS +if HAVE_XMLTO + +# Main DocBook/XML files (DOCTYPE book) +docbook = dmx.xml scaled.xml + +# Generate DocBook/XML output formats with or without stylesheets +include $(top_srcdir)/devbook.am + +endif HAVE_XMLTO +endif ENABLE_DEVEL_DOCS + +EXTRA_DIST = DMXSpec.txt DMXSpec-v1.txt diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.c b/xorg-server/hw/dmx/glxProxy/glxcmds.c index eb589f428..f79264ea9 100644 --- a/xorg-server/hw/dmx/glxProxy/glxcmds.c +++ b/xorg-server/hw/dmx/glxProxy/glxcmds.c @@ -1,3645 +1,3645 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-#include "dmxsync.h"
-
-#include "glxserver.h"
-#include <GL/glxtokens.h>
-#include "g_disptab.h"
-#include <pixmapstr.h>
-#include <windowstr.h>
-#include "glxutil.h"
-#include "glxext.h"
-#include "unpack.h"
-
-#include "GL/glxproto.h"
-#include "glxvendor.h"
-#include "glxvisuals.h"
-#include "glxswap.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-extern __GLXFBConfig **__glXFBConfigs;
-extern int __glXNumFBConfigs;
-
-extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id );
-extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid );
-extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen );
-extern int glxIsExtensionSupported( char *ext );
-extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
-
-#define BE_TO_CLIENT_ERROR(x) \
- ( (x) >= __glXerrorBase ? \
- (x) - dmxScreen->glxErrorBase + __glXerrorBase \
- : (x) )
-
-Display *GetBackEndDisplay( __GLXclientState *cl, int s )
-{
- if (! cl->be_displays[s] ) {
- cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) );
- }
- return cl->be_displays[s];
-}
-
-/*
-** Create a GL context with the given properties.
-*/
-static int CreateContext(__GLXclientState *cl,
- GLXContextID gcId,
- VisualID vid, GLXFBConfigID fbconfigId,
- int screen,
- GLXContextID shareList,
- int isDirect )
-{
- ClientPtr client = cl->client;
- xGLXCreateContextReq *be_req;
- xGLXCreateNewContextReq *be_new_req;
- VisualPtr pVisual;
- ScreenPtr pScreen;
- __GLXcontext *glxc, *shareglxc;
- __GLXvisualConfig *pGlxVisual;
- __GLXscreenInfo *pGlxScreen;
- VisualID visual = vid;
- GLint i;
- int from_screen = screen;
- int to_screen = screen;
- DMXScreenInfo *dmxScreen;
- VisualID be_vid = 0;
- GLXFBConfigID be_fbconfigId = 0;
- int num_be_screens;
- Display *dpy;
-
- /*
- ** Check if screen exists.
- */
- if (screen >= screenInfo.numScreens) {
- client->errorValue = screen;
- return BadValue;
- }
-
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- /*
- ** Find the display list space that we want to share.
- **
- */
- if (shareList == None) {
- shareglxc = NULL;
- } else {
- dixLookupResourceByType((pointer*) &shareglxc, shareList,
- __glXContextRes, NullClient, DixUnknownAccess);
- if (!shareglxc) {
- client->errorValue = shareList;
- return __glXBadContext;
- }
- }
-
- /*
- ** Allocate memory for the new context
- */
- glxc = calloc(1, sizeof(__GLXcontext));
- if (!glxc) {
- return BadAlloc;
- }
-
- pScreen = screenInfo.screens[screen];
- pGlxScreen = &__glXActiveScreens[screen];
-
- if (fbconfigId != None) {
- glxc->pFBConfig = glxLookupFBConfig( fbconfigId );
- if (!glxc->pFBConfig) {
- client->errorValue = fbconfigId;
- free( glxc );
- return BadValue;
- }
- visual = glxc->pFBConfig->associatedVisualId;
- }
- else {
- glxc->pFBConfig = NULL;
- }
-
- if (visual != None) {
- /*
- ** Check if the visual ID is valid for this screen.
- */
- pVisual = pScreen->visuals;
- for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
- if (pVisual->vid == visual) {
- break;
- }
- }
- if (i == pScreen->numVisuals) {
- client->errorValue = visual;
- free( glxc );
- return BadValue;
- }
-
- pGlxVisual = pGlxScreen->pGlxVisual;
- for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
- if (pGlxVisual->vid == visual) {
- break;
- }
- }
- if (i == pGlxScreen->numVisuals) {
- /*
- ** Visual not support on this screen by this OpenGL implementation.
- */
- client->errorValue = visual;
- free( glxc );
- return BadValue;
- }
-
- if ( glxc->pFBConfig == NULL ) {
- glxc->pFBConfig = glxLookupFBConfigByVID( visual );
-
- if ( glxc->pFBConfig == NULL ) {
- /*
- * visual does not have an FBConfig ???
- client->errorValue = visual;
- free( glxc );
- return BadValue;
- */
- }
- }
- }
- else {
- pVisual = NULL;
- pGlxVisual = NULL;
- }
-
- glxc->pScreen = pScreen;
- glxc->pGlxScreen = pGlxScreen;
- glxc->pVisual = pVisual;
- glxc->pGlxVisual = pGlxVisual;
-
- /*
- * allocate memory for back-end servers info
- */
- num_be_screens = to_screen - from_screen + 1;
- glxc->real_ids = (XID *)malloc(sizeof(XID) * num_be_screens);
- if (!glxc->real_ids) {
- return BadAlloc;
- }
- glxc->real_vids = (XID *)malloc(sizeof(XID) * num_be_screens);
- if (!glxc->real_vids) {
- return BadAlloc;
- }
-
- for (screen = from_screen; screen <= to_screen; screen++) {
- int sent = 0;
- pScreen = screenInfo.screens[screen];
- pGlxScreen = &__glXActiveScreens[screen];
- dmxScreen = &dmxScreens[screen];
-
- if (glxc->pFBConfig) {
- __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id,
- screen );
- be_fbconfigId = beFBConfig->id;
- }
-
- if (pGlxVisual) {
-
- be_vid = glxMatchGLXVisualInConfigList( pGlxVisual,
- dmxScreen->glxVisuals,
- dmxScreen->numGlxVisuals );
-
- if (!be_vid) {
- /* visual is not supported on the back-end server */
- free( glxc->real_ids );
- free( glxc->real_vids );
- free( glxc );
- return BadValue;
- }
- }
-
- glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen));
-
- /* send the create context request to the back-end server */
- dpy = GetBackEndDisplay(cl,screen);
- if (glxc->pFBConfig) {
- /*Since for a certain visual both RGB and COLOR INDEX
- *can be on then the only parmeter to choose the renderType
- * should be the class of the colormap since all 4 first
- * classes does not support RGB mode only COLOR INDEX ,
- * and so TrueColor and DirectColor does not support COLOR INDEX*/
- int renderType = glxc->pFBConfig->renderType;
- if ( pVisual ) {
- switch ( pVisual->class ){
- case PseudoColor:
- case StaticColor:
- case GrayScale:
- case StaticGray:
- renderType = GLX_COLOR_INDEX_TYPE;
- break;
- case TrueColor:
- case DirectColor:
- default:
- renderType = GLX_RGBA_TYPE;
- break;
- }
- }
- if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- LockDisplay(dpy);
- GetReq(GLXCreateNewContext,be_new_req);
- be_new_req->reqType = dmxScreen->glxMajorOpcode;
- be_new_req->glxCode = X_GLXCreateNewContext;
- be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
- be_new_req->fbconfig = (unsigned int)be_fbconfigId;
- be_new_req->screen = DefaultScreen(dpy);
- be_new_req->renderType = renderType;
-
- be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
- be_new_req->isDirect = 0;
- UnlockDisplay(dpy);
- glxc->real_vids[screen-from_screen] = be_fbconfigId;
- sent = 1;
- }
- else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
-
- xGLXCreateContextWithConfigSGIXReq *ext_req;
- xGLXVendorPrivateReq *vpreq;
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivate,
- sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq,
- vpreq);
- ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
- ext_req->reqType = dmxScreen->glxMajorOpcode;
- ext_req->glxCode = X_GLXVendorPrivate;
- ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
- ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
- ext_req->fbconfig = (unsigned int)be_fbconfigId;
- ext_req->screen = DefaultScreen(dpy);
- ext_req->renderType = renderType;
- ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
- ext_req->isDirect = 0;
- UnlockDisplay(dpy);
- glxc->real_vids[screen-from_screen] = be_fbconfigId;
- sent = 1;
- }
- }
-
- if (!sent) {
- LockDisplay(dpy);
- GetReq(GLXCreateContext,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCreateContext;
- be_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
- be_req->visual = (unsigned int)be_vid;
- be_req->screen = DefaultScreen(dpy);
- be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
- be_req->isDirect = 0;
- UnlockDisplay(dpy);
- glxc->real_vids[screen-from_screen] = be_vid;
- }
- SyncHandle();
-
- }
-
- /*
- ** Register this context as a resource.
- */
- if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
- free( glxc->real_ids );
- free( glxc->real_vids );
- free( glxc );
- client->errorValue = gcId;
- return BadAlloc;
- }
-
- /*
- ** Finally, now that everything is working, setup the rest of the
- ** context.
- */
- glxc->id = gcId;
- glxc->share_id = shareList;
- glxc->idExists = GL_TRUE;
- glxc->isCurrent = GL_FALSE;
-
- return Success;
-}
-
-int __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
-
- return( CreateContext(cl, req->context,req->visual, None,
- req->screen, req->shareList, req->isDirect) );
-
-}
-
-int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
-
- return( CreateContext(cl, req->context,None, req->fbconfig,
- req->screen, req->shareList, req->isDirect) );
-
-}
-
-int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
-
- return( CreateContext(cl, req->context, None, req->fbconfig,
- req->screen, req->shareList, req->isDirect) );
-
-}
-
-int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryMaxSwapBarriersSGIXReq *req =
- (xGLXQueryMaxSwapBarriersSGIXReq *)pc;
- xGLXQueryMaxSwapBarriersSGIXReply reply;
-
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = 0;
- reply.max = QueryMaxSwapBarriersSGIX(req->screen);
-
- if (client->swapped) {
- __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
- (char *)&reply);
- }
-
- return Success;
-}
-
-int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
- DrawablePtr pDraw;
- __GLXpixmap *pGlxPixmap = NULL;
- __glXWindow *pGlxWindow = NULL;
- int rc;
-
- rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess);
- if (rc != Success) {
- dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable,
- __glXPixmapRes, NullClient, DixUnknownAccess);
- if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable,
- __glXWindowRes, NullClient, DixUnknownAccess);
- if (pGlxWindow) pDraw = pGlxWindow->pDraw;
- }
-
- if (!pDraw) {
- client->errorValue = req->drawable;
- return __glXBadDrawable;
- }
-
- return BindSwapBarrierSGIX(pDraw, req->barrier);
-}
-
-int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
- DrawablePtr pDraw, pMember = NULL;
- __GLXpixmap *pGlxPixmap = NULL;
- __glXWindow *pGlxWindow = NULL;
- int rc;
-
- rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess);
- if (rc != Success) {
- dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable,
- __glXPixmapRes, NullClient, DixUnknownAccess);
- if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable,
- __glXWindowRes, NullClient, DixUnknownAccess);
- if (pGlxWindow) pDraw = pGlxWindow->pDraw;
- }
-
- if (!pDraw) {
- client->errorValue = req->drawable;
- return __glXBadDrawable;
- }
-
- if (req->member != None) {
- rc = dixLookupDrawable(&pMember, req->member, client, 0,
- DixGetAttrAccess);
- if (rc != Success) {
- dixLookupResourceByType((pointer*) &pGlxPixmap, req->member,
- __glXPixmapRes, NullClient,
- DixUnknownAccess);
- if (pGlxPixmap) pMember = pGlxPixmap->pDraw;
- }
-
- if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxWindow, req->member,
- __glXWindowRes, NullClient,
- DixUnknownAccess);
- if (pGlxWindow) pMember = pGlxWindow->pDraw;
- }
-
- if (!pMember) {
- client->errorValue = req->member;
- return __glXBadDrawable;
- }
- }
-
- return JoinSwapGroupSGIX(pDraw, pMember);
-}
-
-
-/*
-** Destroy a GL context as an X resource.
-*/
-int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
- xGLXDestroyContextReq *be_req;
- GLXContextID gcId = req->context;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- dixLookupResourceByType((pointer*) &glxc, gcId, __glXContextRes,
- NullClient, DixUnknownAccess);
- if (glxc) {
- /*
- ** Just free the resource; don't actually destroy the context,
- ** because it might be in use. The
- ** destroy method will be called by the resource destruction routine
- ** if necessary.
- */
- FreeResourceByType(gcId, __glXContextRes, FALSE);
-
- from_screen = to_screen = glxc->pScreen->myNum;
-
- } else {
- client->errorValue = gcId;
- return __glXBadContext;
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- /*
- * send DestroyContext request to all back-end servers
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXDestroyContext,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXDestroyContext;
- be_req->context = glxc->real_ids[s-from_screen];
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-/*****************************************************************************/
-
-/*
-** For each client, the server keeps a table of all the contexts that are
-** current for that client (each thread of a client may have its own current
-** context). These routines add, change, and lookup contexts in the table.
-*/
-
-/*
-** Add a current context, and return the tag that will be used to refer to it.
-*/
-static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw)
-{
- int i;
- int num = cl->numCurrentContexts;
- __GLXcontext **table = cl->currentContexts;
-
- if (!glxc) return -1;
-
- /*
- ** Try to find an empty slot and use it.
- */
- for (i=0; i < num; i++) {
- if (!table[i]) {
- table[i] = glxc;
- return i+1;
- }
- }
- /*
- ** Didn't find a free slot, so we'll have to grow the table.
- */
- if (!num) {
- table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
- cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr));
- cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens *sizeof(GLXContextTag));
- } else {
- table = (__GLXcontext **) realloc(table,
- (num+1)*sizeof(__GLXcontext *));
- cl->currentDrawables = (DrawablePtr *) realloc(
- cl->currentDrawables ,
- (num+1)*sizeof(DrawablePtr));
- cl->be_currentCTag = (GLXContextTag *) realloc(cl->be_currentCTag,
- (num+1)*screenInfo.numScreens*sizeof(GLXContextTag));
- }
- table[num] = glxc;
- cl->currentDrawables[num] = pDraw;
- cl->currentContexts = table;
- cl->numCurrentContexts++;
-
- memset(cl->be_currentCTag + num*screenInfo.numScreens, 0,
- screenInfo.numScreens * sizeof(GLXContextTag));
-
- return num+1;
-}
-
-/*
-** Given a tag, change the current context for the corresponding entry.
-*/
-static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
- GLXContextTag tag)
-{
- __GLXcontext **table = cl->currentContexts;
- table[tag-1] = glxc;
-}
-
-/*
-** Given a tag, and back-end screen number, retrives the current back-end
-** tag.
-*/
-int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s)
-{
- if (tag >0) {
- return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] );
- }
- else {
- return 0;
- }
-}
-
-/*
-** Given a tag, and back-end screen number, sets the current back-end
-** tag.
-*/
-static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag)
-{
- if (tag >0) {
- cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag;
- }
-}
-
-/*
-** For this implementation we have chosen to simply use the index of the
-** context's entry in the table as the context tag. A tag must be greater
-** than 0.
-*/
-__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
-{
- int num = cl->numCurrentContexts;
-
- if (tag < 1 || tag > num) {
- return 0;
- } else {
- return cl->currentContexts[tag-1];
- }
-}
-
-DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag)
-{
- int num = cl->numCurrentContexts;
-
- if (tag < 1 || tag > num) {
- return 0;
- } else {
- return cl->currentDrawables[tag-1];
- }
-}
-
-/*****************************************************************************/
-
-static void StopUsingContext(__GLXcontext *glxc)
-{
- if (glxc) {
- if (glxc == __glXLastContext) {
- /* Tell server GL library */
- __glXLastContext = 0;
- }
- glxc->isCurrent = GL_FALSE;
- if (!glxc->idExists) {
- __glXFreeContext(glxc);
- }
- }
-}
-
-static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
-{
- glxc->isCurrent = GL_TRUE;
-}
-
-/*****************************************************************************/
-/*
-** Make an OpenGL context and drawable current.
-*/
-static int MakeCurrent(__GLXclientState *cl,
- GLXDrawable drawable,
- GLXDrawable readdrawable,
- GLXContextID context,
- GLXContextTag oldContextTag)
-{
- ClientPtr client = cl->client;
- DrawablePtr pDraw = NULL;
- DrawablePtr pReadDraw = NULL;
- xGLXMakeCurrentReadSGIReply new_reply;
- xGLXMakeCurrentReq *be_req;
- xGLXMakeCurrentReply be_reply;
- xGLXMakeContextCurrentReq *be_new_req;
- xGLXMakeContextCurrentReply be_new_reply;
- GLXDrawable drawId = drawable;
- GLXDrawable readId = readdrawable;
- GLXContextID contextId = context;
- __GLXpixmap *pGlxPixmap = 0;
- __GLXpixmap *pReadGlxPixmap = 0;
- __GLXcontext *glxc, *prevglxc;
- GLXContextTag tag = oldContextTag;
- WindowPtr pWin = NULL;
- WindowPtr pReadWin = NULL;
- __glXWindow *pGlxWindow = NULL;
- __glXWindow *pGlxReadWindow = NULL;
- __glXPbuffer *pGlxPbuffer = NULL;
- __glXPbuffer *pGlxReadPbuffer = NULL;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
- PanoramiXRes *pXinReadDraw = NULL;
-#endif
- int from_screen = 0;
- int to_screen = 0;
- int s, rc;
-
- /*
- ** If one is None and the other isn't, it's a bad match.
- */
- if ((drawId == None && contextId != None) ||
- (drawId != None && contextId == None)) {
- return BadMatch;
- }
-
- /*
- ** Lookup old context. If we have one, it must be in a usable state.
- */
- if (tag != 0) {
- prevglxc = __glXLookupContextByTag(cl, tag);
- if (!prevglxc) {
- /*
- ** Tag for previous context is invalid.
- */
- return __glXBadContextTag;
- }
- } else {
- prevglxc = 0;
- }
-
- /*
- ** Lookup new context. It must not be current for someone else.
- */
- if (contextId != None) {
- dixLookupResourceByType((pointer*) &glxc, contextId, __glXContextRes,
- NullClient, DixUnknownAccess);
- if (!glxc) {
- client->errorValue = contextId;
- return __glXBadContext;
- }
- if ((glxc != prevglxc) && glxc->isCurrent) {
- /* Context is current to somebody else */
- return BadAccess;
- }
- } else {
- /* Switching to no context. Ignore new drawable. */
- glxc = 0;
- }
-
- if (drawId != None) {
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
- if (rc == Success) {
- if (pDraw->type == DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X Window.
- */
- VisualID vid;
- pWin = (WindowPtr)pDraw;
- vid = wVisual(pWin);
-
- new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
- new_reply.writeType = GLX_WINDOW_TYPE;
-
- /*
- ** Check if window and context are similar.
- */
- if ((vid != glxc->pVisual->vid) ||
- (pWin->drawable.pScreen != glxc->pScreen)) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- from_screen = to_screen = pWin->drawable.pScreen->myNum;
-
- } else {
- /*
- ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
- ** is, but it must first be created with glxCreateGLXPixmap).
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
- __glXPixmapRes, NullClient,
- DixUnknownAccess);
- if (pGlxPixmap) {
- /*
- ** Check if pixmap and context are similar.
- */
- if (pGlxPixmap->pScreen != glxc->pScreen ||
- pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
- client->errorValue = drawId;
- return BadMatch;
- }
- pDraw = pGlxPixmap->pDraw;
-
- new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
- pGlxPixmap->pGlxVisual->vid);
-
- new_reply.writeType = GLX_PIXMAP_TYPE;
-
- from_screen = to_screen = pGlxPixmap->pScreen->myNum;
-
- }
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
- __glXWindowRes, NullClient,
- DixUnknownAccess);
- if (pGlxWindow) {
- /*
- ** Drawable is a GLXWindow.
- **
- ** Check if GLX window and context are similar.
- */
- if (pGlxWindow->pScreen != glxc->pScreen ||
- pGlxWindow->pGlxFBConfig != glxc->pFBConfig) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- pDraw = pGlxWindow->pDraw;
- new_reply.writeVid = pGlxWindow->pGlxFBConfig->id;
- new_reply.writeType = GLX_GLXWINDOW_TYPE;
- }
-
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxPbuffer, drawId,
- __glXPbufferRes, NullClient,
- DixUnknownAccess);
- if (pGlxPbuffer) {
- if (pGlxPbuffer->pScreen != glxc->pScreen ||
- pGlxPbuffer->pFBConfig != glxc->pFBConfig) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- pDraw = (DrawablePtr)pGlxPbuffer;
- new_reply.writeVid = pGlxPbuffer->pFBConfig->id;
- new_reply.writeType = GLX_PBUFFER_TYPE;
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- } else {
- pDraw = 0;
- }
-
- if (readId != None && readId != drawId ) {
- rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess);
- if (rc == Success) {
- if (pReadDraw->type == DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X Window.
- */
- VisualID vid;
- pReadWin = (WindowPtr)pDraw;
- vid = wVisual(pReadWin);
-
- new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
- new_reply.readType = GLX_WINDOW_TYPE;
-
- /*
- ** Check if window and context are similar.
- */
- if ((vid != glxc->pVisual->vid) ||
- (pReadWin->drawable.pScreen != glxc->pScreen)) {
- client->errorValue = readId;
- return BadMatch;
- }
-
- } else {
-
- /*
- ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
- ** is, but it must first be created with glxCreateGLXPixmap).
- */
- client->errorValue = readId;
- return __glXBadDrawable;
- }
- }
-
- if (!pReadDraw) {
- dixLookupResourceByType((pointer*) &pReadGlxPixmap, readId,
- __glXPixmapRes, NullClient,
- DixUnknownAccess);
- if (pReadGlxPixmap) {
- /*
- ** Check if pixmap and context are similar.
- */
- if (pReadGlxPixmap->pScreen != glxc->pScreen ||
- pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
- client->errorValue = readId;
- return BadMatch;
- }
- pReadDraw = pReadGlxPixmap->pDraw;
-
- new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
- pReadGlxPixmap->pGlxVisual->vid );
- new_reply.readType = GLX_PIXMAP_TYPE;
-
- }
- }
-
- if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxReadWindow, readId,
- __glXWindowRes, NullClient,
- DixUnknownAccess);
- if (pGlxReadWindow) {
- /*
- ** Drawable is a GLXWindow.
- **
- ** Check if GLX window and context are similar.
- */
- if (pGlxReadWindow->pScreen != glxc->pScreen ||
- pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) {
- client->errorValue = readId;
- return BadMatch;
- }
-
- pReadDraw = pGlxReadWindow->pDraw;
- new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id;
- new_reply.readType = GLX_GLXWINDOW_TYPE;
- }
- }
-
- if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxReadPbuffer, readId,
- __glXPbufferRes, NullClient,
- DixUnknownAccess);
- if (pGlxReadPbuffer) {
- if (pGlxReadPbuffer->pScreen != glxc->pScreen ||
- pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- pReadDraw = (DrawablePtr)pGlxReadPbuffer;
- new_reply.readVid = pGlxReadPbuffer->pFBConfig->id;
- new_reply.readType = GLX_PBUFFER_TYPE;
- }
- }
-
- if (!pReadDraw) {
- /*
- ** Drawable is neither a Window nor a GLXPixmap.
- */
- client->errorValue = readId;
- return __glXBadDrawable;
- }
-
- } else {
- pReadDraw = pDraw;
- pReadGlxPixmap = pGlxPixmap;
- pReadWin = pWin;
- new_reply.readVid = new_reply.writeVid;
- new_reply.readType = new_reply.writeType;
- }
-
- if (prevglxc) {
-
- if (prevglxc->pGlxPixmap) {
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- prevglxc->pGlxPixmap->refcnt--;
- __glXFreeGLXPixmap( prevglxc->pGlxPixmap );
- prevglxc->pGlxPixmap = 0;
- }
-
- if (prevglxc->pGlxReadPixmap) {
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- prevglxc->pGlxReadPixmap->refcnt--;
- __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap );
- prevglxc->pGlxReadPixmap = 0;
- }
-
- if (prevglxc->pGlxWindow) {
- /*
- ** The previous drawable was a glx window, release it.
- */
- prevglxc->pGlxWindow->refcnt--;
- __glXFreeGLXWindow( prevglxc->pGlxWindow );
- prevglxc->pGlxWindow = 0;
- }
-
- if (prevglxc->pGlxReadWindow) {
- /*
- ** The previous drawable was a glx window, release it.
- */
- prevglxc->pGlxReadWindow->refcnt--;
- __glXFreeGLXWindow( prevglxc->pGlxReadWindow );
- prevglxc->pGlxReadWindow = 0;
- }
-
- if (prevglxc->pGlxPbuffer) {
- /*
- ** The previous drawable was a glx Pbuffer, release it.
- */
- prevglxc->pGlxPbuffer->refcnt--;
- __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer );
- prevglxc->pGlxPbuffer = 0;
- }
-
- if (prevglxc->pGlxReadPbuffer) {
- /*
- ** The previous drawable was a glx Pbuffer, release it.
- */
- prevglxc->pGlxReadPbuffer->refcnt--;
- __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer );
- prevglxc->pGlxReadPbuffer = 0;
- }
-
- ChangeCurrentContext(cl, glxc, tag);
- ChangeCurrentContext(cl, glxc, tag);
- StopUsingContext(prevglxc);
- } else {
- tag = AddCurrentContext(cl, glxc, pDraw);
- }
- if (glxc) {
-
- glxc->pGlxPixmap = pGlxPixmap;
- glxc->pGlxReadPixmap = pReadGlxPixmap;
- glxc->pGlxWindow = pGlxWindow;
- glxc->pGlxReadWindow = pGlxReadWindow;
- glxc->pGlxPbuffer = pGlxPbuffer;
- glxc->pGlxReadPbuffer = pGlxReadPbuffer;
-
- if (pGlxPixmap) {
- pGlxPixmap->refcnt++;
- }
-
- if (pReadGlxPixmap) {
- pReadGlxPixmap->refcnt++;
- }
-
- if (pGlxWindow) {
- pGlxWindow->refcnt++;
- }
-
- if (pGlxReadWindow) {
- pGlxReadWindow->refcnt++;
- }
-
- if (pGlxPbuffer) {
- pGlxPbuffer->refcnt++;
- }
-
- if (pGlxReadPbuffer) {
- pGlxReadPbuffer->refcnt++;
- }
-
- StartUsingContext(cl, glxc);
- new_reply.contextTag = tag;
- } else {
- new_reply.contextTag = 0;
- }
- new_reply.length = 0;
- new_reply.type = X_Reply;
- new_reply.sequenceNumber = client->sequence;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
-
- if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
- dixLookupResourceByClass((pointer*) &pXinDraw,
- pDraw->id, XRC_DRAWABLE,
- client, DixReadAccess);
- }
-
- if (pReadDraw && pReadDraw != pDraw &&
- new_reply.readType != GLX_PBUFFER_TYPE) {
- dixLookupResourceByClass((pointer*) &pXinReadDraw,
- pReadDraw->id, XRC_DRAWABLE,
- client, DixReadAccess);
- }
- else {
- pXinReadDraw = pXinDraw;
- }
- }
-#endif
-
-
- /* send the MakeCurrent request to all required
- * back-end servers.
- */
- for (s = from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- unsigned int be_draw = None;
- unsigned int be_read_draw = None;
-
- if (pGlxPixmap) {
- be_draw = pGlxPixmap->be_xids[s];
- }
- else if (pGlxPbuffer) {
- be_draw = pGlxPbuffer->be_xids[s];
- }
-#ifdef PANORAMIX
- else if (pXinDraw) {
- dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
- }
-#endif
- else if (pGlxWindow) {
- pWin = (WindowPtr)pGlxWindow->pDraw;
- }
-
- if (pWin && be_draw == None) {
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_draw) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
-
- /*
- * Before sending the MakeCurrent request - sync the
- * X11 connection to the back-end servers to make sure
- * that drawable is already created
- */
- dmxSync( dmxScreen, 1 );
-
- if (drawId == readId) {
- LockDisplay(dpy);
- GetReq(GLXMakeCurrent, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXMakeCurrent;
- be_req->drawable = be_draw;
- be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
- be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
- if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
-
- /* The make current failed */
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag );
- }
- else {
-
- if (pReadGlxPixmap) {
- be_read_draw = pReadGlxPixmap->be_xids[s];
- }
- else if (pGlxReadPbuffer) {
- be_read_draw = pGlxReadPbuffer->be_xids[s];
- }
-#ifdef PANORAMIX
- else if (pXinReadDraw) {
- dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client,
- DixReadAccess);
- }
-#endif
- else if (pGlxReadWindow) {
- pReadWin = (WindowPtr)pGlxReadWindow->pDraw;
- }
-
- if (pReadWin && be_read_draw == None) {
- be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
- if (!be_read_draw) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pReadWin, TRUE );
- be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
- dmxSync( dmxScreen, 1 );
- }
- }
-
- if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- LockDisplay(dpy);
- GetReq(GLXMakeContextCurrent, be_new_req);
- be_new_req->reqType = dmxScreen->glxMajorOpcode;
- be_new_req->glxCode = X_GLXMakeContextCurrent;
- be_new_req->drawable = be_draw;
- be_new_req->readdrawable = be_read_draw;
- be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
- be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
- if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
-
- /* The make current failed */
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag );
- }
- else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) {
- xGLXMakeCurrentReadSGIReq *ext_req;
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXMakeCurrentReadSGIReply ext_reply;
-
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq,
- vpreq);
- ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq;
- ext_req->reqType = dmxScreen->glxMajorOpcode;
- ext_req->glxCode = X_GLXVendorPrivateWithReply;
- ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
- ext_req->drawable = be_draw;
- ext_req->readable = be_read_draw;
- ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
- ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
- if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
-
- /* The make current failed */
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag );
-
- }
- else {
- return BadMatch;
- }
- }
-
- XFlush( dpy );
- }
-
- if (client->swapped) {
- __glXSwapMakeCurrentReply(client, &new_reply);
- } else {
- WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply);
- }
-
- return Success;
-}
-
-int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
-
- return( MakeCurrent(cl, req->drawable, req->drawable,
- req->context, req->oldContextTag ) );
-}
-
-int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
-
- return( MakeCurrent(cl, req->drawable, req->readdrawable,
- req->context, req->oldContextTag ) );
-}
-
-int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
-
- return( MakeCurrent(cl, req->drawable, req->readable,
- req->context, req->oldContextTag ) );
-}
-
-int __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
- xGLXIsDirectReply reply;
- __GLXcontext *glxc;
-
- /*
- ** Find the GL context.
- */
- dixLookupResourceByType((pointer*) &glxc, req->context, __glXContextRes,
- NullClient, DixUnknownAccess);
- if (!glxc) {
- client->errorValue = req->context;
- return __glXBadContext;
- }
-
- reply.isDirect = 0;
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __glXSwapIsDirectReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
- }
-
- return Success;
-}
-
-int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
-/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
- xGLXQueryVersionReply reply;
-
- /*
- ** Server should take into consideration the version numbers sent by the
- ** client if it wants to work with older clients; however, in this
- ** implementation the server just returns its version number.
- */
- reply.majorVersion = __glXVersionMajor;
- reply.minorVersion = __glXVersionMinor;
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __glXSwapQueryVersionReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
- }
- return Success;
-}
-
-int __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
- xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
- __GLXcontext *glxc = NULL;
-
- if (req->contextTag != 0) {
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (glxc) {
- from_screen = to_screen = glxc->pScreen->myNum;
- }
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXWaitGL,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXWaitGL;
- be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- UnlockDisplay(dpy);
- SyncHandle();
-
- XSync(dpy, False);
- }
-
- return Success;
-}
-
-int __glXWaitX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
- xGLXWaitXReq *be_req;
- int from_screen = 0;
- int to_screen = 0;
- int s;
- __GLXcontext *glxc = NULL;
-
- if (req->contextTag != 0) {
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (glxc) {
- from_screen = to_screen = glxc->pScreen->myNum;
- }
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXWaitX,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXWaitX;
- be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- UnlockDisplay(dpy);
- SyncHandle();
-
- XFlush( dpy );
- }
-
- return Success;
-}
-
-int __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXCopyContextReq *be_req;
- xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
- GLXContextID source = req->source;
- GLXContextID dest = req->dest;
- GLXContextTag tag = req->contextTag;
- unsigned long mask = req->mask;
- __GLXcontext *src, *dst;
- int s;
- int from_screen = 0;
- int to_screen = 0;
-
- /*
- ** Check that each context exists.
- */
- dixLookupResourceByType((pointer*) &src, source, __glXContextRes,
- NullClient, DixUnknownAccess);
- if (!src) {
- client->errorValue = source;
- return __glXBadContext;
- }
- dixLookupResourceByType((pointer*) &dst, dest, __glXContextRes,
- NullClient, DixUnknownAccess);
- if (!dst) {
- client->errorValue = dest;
- return __glXBadContext;
- }
-
- /*
- ** They must be in the same address space, and same screen.
- */
- if (src->pGlxScreen != dst->pGlxScreen) {
- client->errorValue = source;
- return BadMatch;
- }
-
- /*
- ** The destination context must not be current for any client.
- */
- if (dst->isCurrent) {
- client->errorValue = dest;
- return BadAccess;
- }
-
- if (tag) {
- __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
-
- if (!tagcx) {
- return __glXBadContextTag;
- }
- if (tagcx != src) {
- /*
- ** This would be caused by a faulty implementation of the client
- ** library.
- */
- return BadMatch;
- }
- }
-
- from_screen = to_screen = src->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXCopyContext,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCopyContext;
- be_req->source = (unsigned int)src->real_ids[s-from_screen];
- be_req->dest = (unsigned int)dst->real_ids[s-from_screen];
- be_req->mask = mask;
- be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
- xGLXGetVisualConfigsReply reply;
- __GLXscreenInfo *pGlxScreen;
- __GLXvisualConfig *pGlxVisual;
- CARD32 buf[__GLX_TOTAL_CONFIG];
- unsigned int screen;
- int i, p;
-
- screen = req->screen;
- if (screen >= screenInfo.numScreens) {
- /* The client library must send a valid screen number. */
- client->errorValue = screen;
- return BadValue;
- }
- pGlxScreen = &__glXActiveScreens[screen];
-
- reply.numVisuals = pGlxScreen->numGLXVisuals;
- reply.numProps = __GLX_TOTAL_CONFIG;
- reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
- __GLX_TOTAL_CONFIG) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
-
- for (i=0; i < pGlxScreen->numVisuals; i++) {
- pGlxVisual = &pGlxScreen->pGlxVisual[i];
- if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
- /* not a usable visual */
- continue;
- }
- p = 0;
- buf[p++] = pGlxVisual->vid;
- buf[p++] = pGlxVisual->class;
- buf[p++] = pGlxVisual->rgba;
-
- buf[p++] = pGlxVisual->redSize;
- buf[p++] = pGlxVisual->greenSize;
- buf[p++] = pGlxVisual->blueSize;
- buf[p++] = pGlxVisual->alphaSize;
- buf[p++] = pGlxVisual->accumRedSize;
- buf[p++] = pGlxVisual->accumGreenSize;
- buf[p++] = pGlxVisual->accumBlueSize;
- buf[p++] = pGlxVisual->accumAlphaSize;
-
- buf[p++] = pGlxVisual->doubleBuffer;
- buf[p++] = pGlxVisual->stereo;
-
- buf[p++] = pGlxVisual->bufferSize;
- buf[p++] = pGlxVisual->depthSize;
- buf[p++] = pGlxVisual->stencilSize;
- buf[p++] = pGlxVisual->auxBuffers;
- buf[p++] = pGlxVisual->level;
- /*
- ** Add token/value pairs for extensions.
- */
- buf[p++] = GLX_VISUAL_CAVEAT_EXT;
- buf[p++] = pGlxVisual->visualRating;
- buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
- buf[p++] = pGlxVisual->transparentPixel;
- buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentRed;
- buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentGreen;
- buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentBlue;
- buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentAlpha;
- buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentIndex;
- buf[p++] = GLX_SAMPLES_SGIS;
- buf[p++] = pGlxVisual->multiSampleSize;
- buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
- buf[p++] = pGlxVisual->nMultiSampleBuffers;
- buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
- buf[p++] = pGlxVisual->visualSelectGroup;
-
- WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
- (char *)buf);
- }
- return Success;
-}
-
-/*
-** Create a GLX Pixmap from an X Pixmap.
-*/
-static int CreateGLXPixmap(__GLXclientState *cl,
- VisualID visual, GLXFBConfigID fbconfigId,
- int screenNum, XID pixmapId, XID glxpixmapId )
-{
- ClientPtr client = cl->client;
- xGLXCreateGLXPixmapReq *be_req;
- xGLXCreatePixmapReq *be_new_req;
- DrawablePtr pDraw;
- ScreenPtr pScreen;
- VisualPtr pVisual;
- __GLXpixmap *pGlxPixmap;
- __GLXscreenInfo *pGlxScreen;
- __GLXvisualConfig *pGlxVisual;
- __GLXFBConfig *pFBConfig;
- int i, s, rc;
- int from_screen, to_screen;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
-#endif
-
- rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP,
- DixAddAccess);
- if (rc != Success)
- return rc;
-
- /*
- ** Check if screen of visual matches screen of pixmap.
- */
- pScreen = pDraw->pScreen;
- if (screenNum != pScreen->myNum) {
- return BadMatch;
- }
-
- if (fbconfigId == 0 && visual == 0) {
- return BadValue;
- }
-
- if (fbconfigId != None) {
- pFBConfig = glxLookupFBConfig( fbconfigId );
- if (!pFBConfig) {
- client->errorValue = fbconfigId;
- return BadValue;
- }
- visual = pFBConfig->associatedVisualId;
- }
- else {
- pFBConfig = NULL;
- }
-
- if (visual != None) {
- /*
- ** Find the VisualRec for this visual.
- */
- pVisual = pScreen->visuals;
- for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
- if (pVisual->vid == visual) {
- break;
- }
- }
- if (i == pScreen->numVisuals) {
- client->errorValue = visual;
- return BadValue;
- }
- /*
- ** Check if depth of visual matches depth of pixmap.
- */
- if (pVisual->nplanes != pDraw->depth) {
- client->errorValue = visual;
- return BadMatch;
- }
-
- /*
- ** Get configuration of the visual.
- */
- pGlxScreen = &__glXActiveScreens[screenNum];
- pGlxVisual = pGlxScreen->pGlxVisual;
- for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
- if (pGlxVisual->vid == visual) {
- break;
- }
- }
- if (i == pGlxScreen->numVisuals) {
- /*
- ** Visual not support on this screen by this OpenGL implementation.
- */
- client->errorValue = visual;
- return BadValue;
- }
-
-
- /* find the FBConfig for that visual (if any) */
- if ( pFBConfig == NULL ) {
- pFBConfig = glxLookupFBConfigByVID( visual );
-
- if ( pFBConfig == NULL ) {
- /*
- * visual does not have an FBConfig ???
- client->errorValue = visual;
- return BadValue;
- */
- }
- }
- }
- else {
- pVisual = NULL;
- pGlxVisual = NULL;
- pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum];
- }
-
- pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap));
- if (!pGlxPixmap) {
- return BadAlloc;
- }
- pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens);
- if (!pGlxPixmap->be_xids) {
- free( pGlxPixmap );
- return BadAlloc;
- }
-
- pGlxPixmap->pDraw = pDraw;
- pGlxPixmap->pGlxScreen = pGlxScreen;
- pGlxPixmap->pGlxVisual = pGlxVisual;
- pGlxPixmap->pFBConfig = pFBConfig;
- pGlxPixmap->pScreen = pScreen;
- pGlxPixmap->idExists = True;
- pGlxPixmap->refcnt = 0;
-
- /*
- ** Bump the ref count on the X pixmap so it won't disappear.
- */
- ((PixmapPtr) pDraw)->refcnt++;
-
- /*
- * send the request to the back-end server(s)
- */
- from_screen = to_screen = screenNum;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
-
- dixLookupResourceByClass((pointer*) &pXinDraw,
- pDraw->id, XRC_DRAWABLE,
- client, DixReadAccess);
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
-
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- Pixmap be_pixmap;
- DrawablePtr pRealDraw = pDraw;
-
-#ifdef PANORAMIX
- if (pXinDraw) {
- dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0,
- DixAddAccess);
- }
-#endif
-
- be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap;
-
- /* make sure pixmap already created on back-end */
- dmxSync( dmxScreen, 1 );
-
- if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
-
- LockDisplay(dpy);
- pGlxPixmap->be_xids[s] = XAllocID(dpy);
- GetReq(GLXCreatePixmap,be_new_req);
- be_new_req->reqType = dmxScreen->glxMajorOpcode;
- be_new_req->glxCode = X_GLXCreatePixmap;
- be_new_req->screen = DefaultScreen(dpy);
- be_new_req->fbconfig = be_FBConfig->id;
- be_new_req->pixmap = (unsigned int)be_pixmap;
- be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- be_new_req->numAttribs = 0;
- UnlockDisplay(dpy);
- SyncHandle();
- }
- else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
- __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
- xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req;
- xGLXVendorPrivateReq *vpreq;
-
- LockDisplay(dpy);
- pGlxPixmap->be_xids[s] = XAllocID(dpy);
- GetReqExtra(GLXVendorPrivate,
- sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,
- vpreq);
- ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
- ext_req->reqType = dmxScreen->glxMajorOpcode;
- ext_req->glxCode = X_GLXVendorPrivate;
- ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
- ext_req->screen = DefaultScreen(dpy);
- ext_req->fbconfig = be_FBConfig->id;
- ext_req->pixmap = (unsigned int)be_pixmap;
- ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
- else if (pGlxVisual) {
- LockDisplay(dpy);
- pGlxPixmap->be_xids[s] = XAllocID(dpy);
- GetReq(GLXCreateGLXPixmap,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCreateGLXPixmap;
- be_req->screen = DefaultScreen(dpy);
- be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList(
- pGlxVisual,
- dmxScreen->glxVisuals,
- dmxScreen->numGlxVisuals );
- be_req->pixmap = (unsigned int)be_pixmap;
- be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
- else {
- client->errorValue = ( visual ? visual : fbconfigId );
- free( pGlxPixmap );
- return BadValue;
- }
-
- XFlush( dpy );
- }
-
- if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
- free( pGlxPixmap );
- return BadAlloc;
- }
-
- return Success;
-}
-
-int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
-
- return( CreateGLXPixmap(cl, req->visual, None,
- req->screen, req->pixmap, req->glxpixmap) );
-}
-
-int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
-
- return( CreateGLXPixmap(cl, None, req->fbconfig,
- req->screen, req->pixmap, req->glxpixmap) );
-}
-
-int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
- XID glxpixmap = req->glxpixmap;
- __GLXpixmap *pGlxPixmap;
- int s;
- int from_screen, to_screen;
-
- /*
- ** Check if it's a valid GLX pixmap.
- */
- dixLookupResourceByType((pointer*) &pGlxPixmap, glxpixmap,
- __glXPixmapRes, NullClient, DixUnknownAccess);
- if (!pGlxPixmap) {
- client->errorValue = glxpixmap;
- return __glXBadPixmap;
- }
- FreeResource(glxpixmap, FALSE);
-
- /*
- * destroy the pixmap on the back-end server(s).
- */
- from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- /* make sure pixmap exist in back-end */
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXDestroyGLXPixmap,req);
- req->reqType = dmxScreen->glxMajorOpcode;
- req->glxCode = X_GLXDestroyGLXPixmap;
- req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
-
- return Success;
-}
-
-/*****************************************************************************/
-
-/*
-** NOTE: There is no portable implementation for swap buffers as of
-** this time that is of value. Consequently, this code must be
-** implemented by somebody other than SGI.
-*/
-int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag)
-{
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- xGLXSwapBuffersReq *be_req;
- WindowPtr pWin = NULL;
- __GLXpixmap *pGlxPixmap = NULL;
- __GLXcontext *glxc = NULL;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
-#endif
- __glXWindow *pGlxWindow = NULL;
- int from_screen = 0;
- int to_screen = 0;
- int s, rc;
-
- /*
- ** Check that the GLX drawable is valid.
- */
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
- if (rc == Success) {
- from_screen = to_screen = pDraw->pScreen->myNum;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X window.
- */
- pWin = (WindowPtr)pDraw;
- } else {
- /*
- ** Drawable is an X pixmap, which is not allowed.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
- __glXPixmapRes, NullClient, DixUnknownAccess);
- if (pGlxPixmap) {
- /*
- ** Drawable is a GLX pixmap.
- */
- pDraw = pGlxPixmap->pDraw;
- from_screen = to_screen = pGlxPixmap->pScreen->myNum;
- }
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
- __glXWindowRes, NullClient, DixUnknownAccess);
- if (pGlxWindow) {
- /*
- ** Drawable is a GLXWindow.
- */
- pDraw = pGlxWindow->pDraw;
- from_screen = to_screen = pGlxWindow->pScreen->myNum;
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is neither a X window nor a GLX pixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc) {
- return __glXBadContextTag;
- }
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- dixLookupResourceByClass((pointer*) &pXinDraw,
- pDraw->id, XRC_DRAWABLE,
- client, DixReadAccess);
- }
-#endif
-
- /* If requested, send a glFinish to all back-end servers before swapping. */
- if (dmxGLXFinishSwap) {
- for (s=from_screen; s<=to_screen; s++) {
- Display *dpy = GetBackEndDisplay(cl,s);
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- xGLXSingleReq *finishReq;
- xGLXSingleReply reply;
-
-#define X_GLXSingle 0 /* needed by GetReq below */
-
- LockDisplay(dpy);
- GetReq(GLXSingle,finishReq);
- finishReq->reqType = dmxScreen->glxMajorOpcode;
- finishReq->glxCode = X_GLsop_Finish;
- finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0);
- (void) _XReply(dpy, (xReply*) &reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
- }
- }
-
- /* If requested, send an XSync to all back-end servers before swapping. */
- if (dmxGLXSyncSwap) {
- for (s=from_screen; s<=to_screen; s++)
- XSync(GetBackEndDisplay(cl,s), False);
- }
-
-
- /* send the SwapBuffers request to all back-end servers */
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- unsigned int be_draw = 0;
-
- if (pGlxPixmap) {
- be_draw = (unsigned int)pGlxPixmap->be_xids[s];
- }
-#ifdef PANORAMIX
- else if (pXinDraw) {
- dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
- }
-#endif
- else if (pGlxWindow) {
- pWin = (WindowPtr)pGlxWindow->pDraw;
- }
-
- if (pWin && !be_draw) {
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_draw) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
-
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXSwapBuffers,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXSwapBuffers;
- be_req->drawable = be_draw;
- be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 );
- UnlockDisplay(dpy);
- SyncHandle();
- XFlush(dpy);
- }
-
- return Success;
-}
-
-int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
- GLXContextTag tag = req->contextTag;
- XID drawId = req->drawable;
- __GLXpixmap *pGlxPixmap = NULL;
- __GLXcontext *glxc = NULL;
- __glXWindow *pGlxWindow = NULL;
- int rc;
-
- /*
- ** Check that the GLX drawable is valid.
- */
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
- if (rc == Success) {
- if (pDraw->type != DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X pixmap, which is not allowed.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- dixLookupResourceByType((pointer*) &pGlxPixmap, drawId,
- __glXPixmapRes, NullClient, DixUnknownAccess);
- if (pGlxPixmap) {
- /*
- ** Drawable is a GLX pixmap.
- */
- pDraw = pGlxPixmap->pDraw;
- }
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- dixLookupResourceByType((pointer*) &pGlxWindow, drawId,
- __glXWindowRes, NullClient, DixUnknownAccess);
- if (pGlxWindow) {
- /*
- ** Drawable is a GLXWindow.
- */
- pDraw = pGlxWindow->pDraw;
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is neither a X window nor a GLX pixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc) {
- return __glXBadContextTag;
- }
- }
-
- if (pDraw &&
- pDraw->type == DRAWABLE_WINDOW &&
- DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) {
- return SGSwapBuffers(cl, drawId, tag, pDraw);
- }
-
- return __glXDoSwapBuffers(cl, drawId, tag);
-}
-
-
-/************************************************************************/
-
-/*
-** Render and Renderlarge are not in the GLX API. They are used by the GLX
-** client library to send batches of GL rendering commands.
-*/
-
-/*
-** Execute all the drawing commands in a request.
-*/
-int __glXRender(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXRenderReq *req;
- xGLXRenderReq *be_req;
- int size;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- /*
- ** NOTE: much of this code also appears in the byteswapping version of this
- ** routine, __glXSwapRender(). Any changes made here should also be
- ** duplicated there.
- */
-
- req = (xGLXRenderReq *) pc;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXRenderReq;
- size = (req->length << 2) - sz_xGLXRenderReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXRender,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXRender;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- _XSend(dpy, (const char *)pc, size);
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-/*
-** Execute a large rendering request (one that spans multiple X requests).
-*/
-int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXRenderLargeReq *req;
- xGLXRenderLargeReq *be_req;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- /*
- ** NOTE: much of this code also appears in the byteswapping version of this
- ** routine, __glXSwapRenderLarge(). Any changes made here should also be
- ** duplicated there.
- */
-
- req = (xGLXRenderLargeReq *) pc;
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXRenderLargeReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- GetReq(GLXRenderLarge,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXRenderLarge;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- be_req->length = req->length;
- be_req->requestNumber = req->requestNumber;
- be_req->requestTotal = req->requestTotal;
- be_req->dataBytes = req->dataBytes;
- Data(dpy, (const char *)pc, req->dataBytes);
- UnlockDisplay(dpy);
- SyncHandle();
-
- }
-
- return Success;
-}
-
-
-/************************************************************************/
-
-int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req;
-
- req = (xGLXVendorPrivateReq *) pc;
-
- switch( req->vendorCode ) {
-
- case X_GLvop_DeleteTexturesEXT:
- return __glXVForwardSingleReq( cl, pc );
- break;
-
- case X_GLXvop_SwapIntervalSGI:
- if (glxIsExtensionSupported("SGI_swap_control")) {
- return __glXVForwardSingleReq( cl, pc );
- }
- else {
- return Success;
- }
- break;
-
-#if 0 /* glx 1.3 */
- case X_GLXvop_CreateGLXVideoSourceSGIX:
- break;
- case X_GLXvop_DestroyGLXVideoSourceSGIX:
- break;
- case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
- break;
- case X_GLXvop_DestroyGLXPbufferSGIX:
- break;
- case X_GLXvop_ChangeDrawableAttributesSGIX:
- break;
-#endif
-
- case X_GLXvop_BindSwapBarrierSGIX:
- return __glXBindSwapBarrierSGIX( cl, pc );
- break;
-
- case X_GLXvop_JoinSwapGroupSGIX:
- return __glXJoinSwapGroupSGIX( cl, pc );
- break;
-
- case X_GLXvop_CreateContextWithConfigSGIX:
- return __glXCreateContextWithConfigSGIX( cl, pc );
- break;
-
- default:
- /*
- ** unsupported private request
- */
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
- }
-
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
-
-}
-
-int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateWithReplyReq *req;
-
- req = (xGLXVendorPrivateWithReplyReq *) pc;
-
- switch( req->vendorCode ) {
-
- case X_GLvop_GetConvolutionFilterEXT:
- case X_GLvop_GetConvolutionParameterfvEXT:
- case X_GLvop_GetConvolutionParameterivEXT:
- case X_GLvop_GetSeparableFilterEXT:
- case X_GLvop_GetHistogramEXT:
- case X_GLvop_GetHistogramParameterivEXT:
- case X_GLvop_GetMinmaxEXT:
- case X_GLvop_GetMinmaxParameterfvEXT:
- case X_GLvop_GetMinmaxParameterivEXT:
- case X_GLvop_AreTexturesResidentEXT:
- case X_GLvop_IsTextureEXT:
- return( __glXVForwardPipe0WithReply(cl, pc) );
- break;
-
- case X_GLvop_GenTexturesEXT:
- return( __glXVForwardAllWithReply(cl, pc) );
- break;
-
-
-#if 0 /* glx1.3 */
- case X_GLvop_GetDetailTexFuncSGIS:
- case X_GLvop_GetSharpenTexFuncSGIS:
- case X_GLvop_GetColorTableSGI:
- case X_GLvop_GetColorTableParameterfvSGI:
- case X_GLvop_GetColorTableParameterivSGI:
- case X_GLvop_GetTexFilterFuncSGIS:
- case X_GLvop_GetInstrumentsSGIX:
- case X_GLvop_InstrumentsBufferSGIX:
- case X_GLvop_PollInstrumentsSGIX:
- case X_GLvop_FlushRasterSGIX:
- case X_GLXvop_CreateGLXPbufferSGIX:
- case X_GLXvop_GetDrawableAttributesSGIX:
- case X_GLXvop_QueryHyperpipeNetworkSGIX:
- case X_GLXvop_QueryHyperpipeConfigSGIX:
- case X_GLXvop_HyperpipeConfigSGIX:
- case X_GLXvop_DestroyHyperpipeConfigSGIX:
-#endif
- case X_GLXvop_QueryMaxSwapBarriersSGIX:
- return( __glXQueryMaxSwapBarriersSGIX(cl, pc) );
- break;
-
- case X_GLXvop_GetFBConfigsSGIX:
- return( __glXGetFBConfigsSGIX(cl, pc) );
- break;
-
- case X_GLXvop_MakeCurrentReadSGI:
- return( __glXMakeCurrentReadSGI(cl, pc) );
- break;
-
- case X_GLXvop_QueryContextInfoEXT:
- return( __glXQueryContextInfoEXT(cl,pc) );
- break;
-
- default:
- /*
- ** unsupported private request
- */
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
- }
-
-}
-
-int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
- xGLXQueryExtensionsStringReply reply;
- GLint screen;
- size_t length;
- int len, numbytes;
- char *be_buf;
-
-#ifdef FWD_QUERY_REQ
- xGLXQueryExtensionsStringReq *be_req;
- xGLXQueryExtensionsStringReply be_reply;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
- int slop;
-#endif
-
- screen = req->screen;
-
- /*
- ** Check if screen exists.
- */
- if ((screen < 0) || (screen >= screenInfo.numScreens)) {
- client->errorValue = screen;
- return BadValue;
- }
-
-#ifdef FWD_QUERY_REQ
- dmxScreen = &dmxScreens[screen];
-
- /* Send the glXQueryServerString request */
- dpy = GetBackEndDisplay(cl,screen);
- LockDisplay(dpy);
- GetReq(GLXQueryExtensionsString,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXQueryServerString;
- be_req->screen = DefaultScreen(dpy);
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- len = (int)be_reply.length;
- numbytes = (int)be_reply.n;
- slop = numbytes * __GLX_SIZE_INT8 & 3;
- be_buf = (char *)malloc(numbytes);
- if (!be_buf) {
- /* Throw data on the floor */
- _XEatData(dpy, len);
- } else {
- _XRead(dpy, (char *)be_buf, numbytes);
- if (slop) _XEatData(dpy,4-slop);
- }
- UnlockDisplay(dpy);
- SyncHandle();
-
-#else
-
- be_buf = __glXGetServerString(GLX_EXTENSIONS);
- numbytes = strlen(be_buf) + 1;
- len = __GLX_PAD(numbytes) >> 2;
-
-#endif
-
- length = len;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = len;
- reply.n = numbytes;
-
- if (client->swapped) {
- glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
- } else {
- WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
- WriteToClient(client, (int)(length << 2), (char *)be_buf);
- }
-
- return Success;
-}
-
-int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
- xGLXQueryServerStringReply reply;
- int name;
- GLint screen;
- size_t length;
- int len, numbytes;
- char *be_buf;
-#ifdef FWD_QUERY_REQ
- xGLXQueryServerStringReq *be_req;
- xGLXQueryServerStringReply be_reply;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
- int slop;
-#endif
-
- name = req->name;
- screen = req->screen;
- /*
- ** Check if screen exists.
- */
- if ((screen < 0) || (screen >= screenInfo.numScreens)) {
- client->errorValue = screen;
- return BadValue;
- }
-
-#ifdef FWD_QUERY_REQ
- dmxScreen = &dmxScreens[screen];
-
- /* Send the glXQueryServerString request */
- dpy = GetBackEndDisplay(cl,screen);
- LockDisplay(dpy);
- GetReq(GLXQueryServerString,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXQueryServerString;
- be_req->screen = DefaultScreen(dpy);
- be_req->name = name;
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- len = (int)be_reply.length;
- numbytes = (int)be_reply.n;
- slop = numbytes * __GLX_SIZE_INT8 & 3;
- be_buf = (char *)malloc(numbytes);
- if (!be_buf) {
- /* Throw data on the floor */
- _XEatData(dpy, len);
- } else {
- _XRead(dpy, (char *)be_buf, numbytes);
- if (slop) _XEatData(dpy,4-slop);
- }
- UnlockDisplay(dpy);
- SyncHandle();
-
-#else
- be_buf = __glXGetServerString(name);
- numbytes = strlen(be_buf) + 1;
- len = __GLX_PAD(numbytes) >> 2;
-#endif
-
- length = len;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = length;
- reply.n = numbytes;
-
- if (client->swapped) {
- glxSwapQueryServerStringReply(client, &reply, be_buf);
- } else {
- WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
- WriteToClient(client, (int)(length << 2), be_buf);
- }
-
- return Success;
-}
-
-int __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
- xGLXClientInfoReq *be_req;
- const char *buf;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- cl->GLClientmajorVersion = req->major;
- cl->GLClientminorVersion = req->minor;
- free(cl->GLClientextensions);
- buf = (const char *)(req+1);
- cl->GLClientextensions = strdup(buf);
-
- to_screen = screenInfo.numScreens - 1;
-
- for (s=from_screen; s<=to_screen; s++)
- {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXClientInfo,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXClientInfo;
- be_req->major = req->major;
- be_req->minor = req->minor;
- be_req->length = req->length;
- be_req->numbytes = req->numbytes;
- Data(dpy, buf, req->numbytes);
-
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-int __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXUseXFontReq *req;
- xGLXUseXFontReq *be_req;
- FontPtr pFont;
- __GLXcontext *glxc = NULL;
- int from_screen = 0;
- int to_screen = 0;
- int s;
- dmxFontPrivPtr pFontPriv;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- req = (xGLXUseXFontReq *) pc;
-
- if (req->contextTag != 0) {
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (glxc) {
- from_screen = to_screen = glxc->pScreen->myNum;
- }
- }
-
- /*
- ** Font can actually be either the ID of a font or the ID of a GC
- ** containing a font.
- */
- dixLookupResourceByType((pointer*) &pFont, req->font, RT_FONT,
- NullClient, DixUnknownAccess);
- if (!pFont) {
- GC *pGC;
- dixLookupResourceByType((pointer*) &pGC, req->font,
- RT_GC, NullClient,
- DixUnknownAccess);
- if (!pGC) {
- client->errorValue = req->font;
- return BadFont;
- }
- pFont = pGC->font;
- }
-
- pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
-
- for (s=from_screen; s<=to_screen; s++) {
- dmxScreen = &dmxScreens[s];
- dpy = GetBackEndDisplay(cl,s);
-
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXUseXFont,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXUseXFont;
- be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- be_req->font = pFontPriv->font[s]->fid;
- be_req->first = req->first;
- be_req->count = req->count;
- be_req->listBase = req->listBase;
- UnlockDisplay(dpy);
- SyncHandle();
-
- XSync( dpy, False );
- }
-
- return Success;
-}
-
-/*
- * start GLX 1.3 here
- */
-
-int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
- xGLXGetFBConfigsReply reply;
- __GLXFBConfig *pFBConfig;
- CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS];
- int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS;
- unsigned int screen = req->screen;
- int numFBConfigs, i, p;
- __GLXscreenInfo *pGlxScreen;
-
- if (screen >= screenInfo.numScreens) {
- /* The client library must send a valid screen number. */
- client->errorValue = screen;
- return BadValue;
- }
-
- pGlxScreen = &__glXActiveScreens[screen];
- numFBConfigs = __glXNumFBConfigs;
-
- reply.numFBConfigs = numFBConfigs;
- reply.numAttribs = numAttribs;
- reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.numFBConfigs);
- __GLX_SWAP_INT(&reply.numAttribs);
- }
- WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
-
- for (i=0; i < numFBConfigs; i++) {
- int associatedVisualId = 0;
- int drawableTypeIndex;
- pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ];
-
- p = 0;
- /* core attributes */
- buf[p++] = GLX_FBCONFIG_ID;
- buf[p++] = pFBConfig->id;
- buf[p++] = GLX_BUFFER_SIZE;
- buf[p++] = pFBConfig->indexBits;
- buf[p++] = GLX_LEVEL;
- buf[p++] = pFBConfig->level;
- buf[p++] = GLX_DOUBLEBUFFER;
- buf[p++] = pFBConfig->doubleBufferMode;
- buf[p++] = GLX_STEREO;
- buf[p++] = pFBConfig->stereoMode;
- buf[p++] = GLX_AUX_BUFFERS;
- buf[p++] = pFBConfig->maxAuxBuffers;
- buf[p++] = GLX_RED_SIZE;
- buf[p++] = pFBConfig->redBits;
- buf[p++] = GLX_GREEN_SIZE;
- buf[p++] = pFBConfig->greenBits;
- buf[p++] = GLX_BLUE_SIZE;
- buf[p++] = pFBConfig->blueBits;
- buf[p++] = GLX_ALPHA_SIZE;
- buf[p++] = pFBConfig->alphaBits;
- buf[p++] = GLX_DEPTH_SIZE;
- buf[p++] = pFBConfig->depthBits;
- buf[p++] = GLX_STENCIL_SIZE;
- buf[p++] = pFBConfig->stencilBits;
- buf[p++] = GLX_ACCUM_RED_SIZE;
- buf[p++] = pFBConfig->accumRedBits;
- buf[p++] = GLX_ACCUM_GREEN_SIZE;
- buf[p++] = pFBConfig->accumGreenBits;
- buf[p++] = GLX_ACCUM_BLUE_SIZE;
- buf[p++] = pFBConfig->accumBlueBits;
- buf[p++] = GLX_ACCUM_ALPHA_SIZE;
- buf[p++] = pFBConfig->accumAlphaBits;
- buf[p++] = GLX_RENDER_TYPE;
- buf[p++] = pFBConfig->renderType;
- buf[p++] = GLX_DRAWABLE_TYPE;
- drawableTypeIndex = p;
- buf[p++] = pFBConfig->drawableType;
- buf[p++] = GLX_X_VISUAL_TYPE;
- buf[p++] = pFBConfig->visualType;
- buf[p++] = GLX_CONFIG_CAVEAT;
- buf[p++] = pFBConfig->visualCaveat;
- buf[p++] = GLX_TRANSPARENT_TYPE;
- buf[p++] = pFBConfig->transparentType;
- buf[p++] = GLX_TRANSPARENT_RED_VALUE;
- buf[p++] = pFBConfig->transparentRed;
- buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
- buf[p++] = pFBConfig->transparentGreen;
- buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
- buf[p++] = pFBConfig->transparentBlue;
- buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
- buf[p++] = pFBConfig->transparentAlpha;
- buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
- buf[p++] = pFBConfig->transparentIndex;
- buf[p++] = GLX_MAX_PBUFFER_WIDTH;
- buf[p++] = pFBConfig->maxPbufferWidth;
- buf[p++] = GLX_MAX_PBUFFER_HEIGHT;
- buf[p++] = pFBConfig->maxPbufferHeight;
- buf[p++] = GLX_MAX_PBUFFER_PIXELS;
- buf[p++] = pFBConfig->maxPbufferPixels;
-
- /*
- * find the visual of the back-end server and match a visual
- * on the proxy.
- * do only once - if a visual is not yet associated.
- */
- if (pFBConfig->associatedVisualId == (unsigned int)-1) {
- DMXScreenInfo *dmxScreen = &dmxScreens[screen];
- __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ];
- __GLXvisualConfig *pGlxVisual = NULL;
- int v;
- int found = 0;
- for (v=0; v<dmxScreen->numGlxVisuals; v++) {
- if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) {
- pGlxVisual = &dmxScreen->glxVisuals[v];
- break;
- }
- }
-
- if (pGlxVisual) {
- for (v=0; v<pGlxScreen->numVisuals; v++) {
- if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) {
- associatedVisualId = pGlxScreen->pGlxVisual[v].vid;
- found = 1;
- break;
- }
- }
- }
-
- if (!found) {
- associatedVisualId = 0;
- pFBConfig->drawableType &= ~(GLX_WINDOW_BIT);
- buf[drawableTypeIndex] = pFBConfig->drawableType;
- }
-#ifdef PANORAMIX
- else if (!noPanoramiXExtension) {
- /* convert the associated visualId to the panoramix one */
- pFBConfig->associatedVisualId =
- PanoramiXTranslateVisualID(screen, v);
- }
-#endif
- }
- else {
- associatedVisualId = pFBConfig->associatedVisualId;
- }
-
- buf[p++] = GLX_VISUAL_ID;
- buf[p++] = associatedVisualId;
-
- /* SGIS_multisample attributes */
- buf[p++] = GLX_SAMPLES_SGIS;
- buf[p++] = pFBConfig->multiSampleSize;
- buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
- buf[p++] = pFBConfig->nMultiSampleBuffers;
-
- /* SGIX_pbuffer specific attributes */
- buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX;
- buf[p++] = pFBConfig->optimalPbufferWidth;
- buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX;
- buf[p++] = pFBConfig->optimalPbufferHeight;
-
- buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
- buf[p++] = pFBConfig->visualSelectGroup;
-
- if (client->swapped) {
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs);
- }
- WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf);
- }
- return Success;
-}
-
-int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
- xGLXGetFBConfigsReq new_req;
-
- new_req.reqType = req->reqType;
- new_req.glxCode = req->glxCode;
- new_req.length = req->length;
- new_req.screen = req->screen;
-
- return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) );
-}
-
-
-int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
- int screen = req->screen;
- GLXFBConfigID fbconfigId = req->fbconfig;
- XID windowId = req->window;
- XID glxwindowId = req->glxwindow;
- DrawablePtr pDraw;
- ScreenPtr pScreen;
- __glXWindow *pGlxWindow;
- __GLXFBConfig *pGlxFBConfig = NULL;
- VisualPtr pVisual;
- VisualID visId;
- int i, rc;
- pointer val;
-
- /*
- ** Check if windowId is valid
- */
- rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
- DixAddAccess);
- if (rc != Success)
- return rc;
-
- /*
- ** Check if screen of window matches screen of fbconfig.
- */
- pScreen = pDraw->pScreen;
- if (screen != pScreen->myNum) {
- return BadMatch;
- }
-
- /*
- ** Find the FBConfigRec for this fbconfigid.
- */
- if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
- client->errorValue = fbconfigId;
- return __glXBadFBConfig;
- }
- visId = pGlxFBConfig->associatedVisualId;
-
- /*
- ** Check if the fbconfig supports rendering to windows
- */
- if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) {
- return BadMatch;
- }
-
- if (visId != None) {
- /*
- ** Check if the visual ID is valid for this screen.
- */
- pVisual = pScreen->visuals;
- for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
- if (pVisual->vid == visId) {
- break;
- }
- }
- if (i == pScreen->numVisuals) {
- client->errorValue = visId;
- return BadValue;
- }
-
- /*
- ** Check if color buffer depth of fbconfig matches depth
- ** of window.
- */
- if (pVisual->nplanes != pDraw->depth) {
- return BadMatch;
- }
- } else
- /*
- ** The window was created with no visual that corresponds
- ** to fbconfig
- */
- return BadMatch;
-
- /*
- ** Check if there is already a fbconfig associated with this window
- */
- if (Success == dixLookupResourceByType(&val,
- glxwindowId, __glXWindowRes,
- NullClient, DixUnknownAccess)) {
- client->errorValue = glxwindowId;
- return BadAlloc;
- }
-
- pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow));
- if (!pGlxWindow) {
- return BadAlloc;
- }
-
- /*
- ** Register this GLX window as a resource
- */
- if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) {
- return BadAlloc;
- }
-
- pGlxWindow->pDraw = pDraw;
- pGlxWindow->type = GLX_GLXWINDOW_TYPE;
- pGlxWindow->idExists = True;
- pGlxWindow->refcnt = 0;
- pGlxWindow->pGlxFBConfig = pGlxFBConfig;
- pGlxWindow->pScreen = pScreen;
-
- return Success;
-}
-
-int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
- XID glxwindow = req->glxwindow;
- pointer val;
-
- /*
- ** Check if it's a valid GLX window.
- */
- if (Success != dixLookupResourceByType(&val,
- glxwindow, __glXWindowRes,
- NullClient, DixUnknownAccess)) {
- client->errorValue = glxwindow;
- return __glXBadDrawable;
- }
- /*
- ** The glx window destructor will check whether it's current before
- ** freeing anything.
- */
- FreeResource(glxwindow, RT_NONE);
-
- return Success;
-}
-
-int __glXQueryContext(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- __GLXcontext *ctx;
- xGLXQueryContextReq *req;
- xGLXQueryContextReply reply;
- int nProps;
- int *sendBuf, *pSendBuf;
- int nReplyBytes;
-
- req = (xGLXQueryContextReq *)pc;
- dixLookupResourceByType((pointer*) &ctx, req->context, __glXContextRes,
- NullClient, DixUnknownAccess);
- if (!ctx) {
- client->errorValue = req->context;
- return __glXBadContext;
- }
-
- nProps = 3;
-
- reply.length = nProps << 1;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.n = nProps;
-
- nReplyBytes = reply.length << 2;
- sendBuf = (int *)malloc(nReplyBytes);
- pSendBuf = sendBuf;
- *pSendBuf++ = GLX_FBCONFIG_ID;
- *pSendBuf++ = (int)(ctx->pFBConfig->id);
- *pSendBuf++ = GLX_RENDER_TYPE;
- *pSendBuf++ = (int)(ctx->pFBConfig->renderType);
- *pSendBuf++ = GLX_SCREEN;
- *pSendBuf++ = (int)(ctx->pScreen->myNum);
-
- if (client->swapped) {
- __glXSwapQueryContextReply(client, &reply, sendBuf);
- } else {
- WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply);
- WriteToClient(client, nReplyBytes, (char *)sendBuf);
- }
- free((char *)sendBuf);
-
- return Success;
-}
-
-int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- __GLXcontext *ctx;
- xGLXQueryContextInfoEXTReq *req;
- xGLXQueryContextInfoEXTReply reply;
- int nProps;
- int *sendBuf, *pSendBuf;
- int nReplyBytes;
-
- req = (xGLXQueryContextInfoEXTReq *)pc;
- dixLookupResourceByType((pointer*) &ctx,
- req->context, __glXContextRes,
- client, DixReadAccess);
-
- if (!ctx) {
- client->errorValue = req->context;
- return __glXBadContext;
- }
-
- nProps = 4;
-
- reply.length = nProps << 1;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.n = nProps;
-
- nReplyBytes = reply.length << 2;
- sendBuf = (int *)malloc(nReplyBytes);
- pSendBuf = sendBuf;
- *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
- *pSendBuf++ = (int)(ctx->share_id);
- *pSendBuf++ = GLX_VISUAL_ID_EXT;
- *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0);
- *pSendBuf++ = GLX_SCREEN_EXT;
- *pSendBuf++ = (int)(ctx->pScreen->myNum);
- *pSendBuf++ = GLX_FBCONFIG_ID;
- *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0);
-
- if (client->swapped) {
- __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
- } else {
- WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
- WriteToClient(client, nReplyBytes, (char *)sendBuf);
- }
- free((char *)sendBuf);
-
- return Success;
-}
-
-int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
- xGLXCreatePbufferReq *be_req;
- int screen = req->screen;
- GLXFBConfigID fbconfigId = req->fbconfig;
- GLXPbuffer pbuffer = req->pbuffer;
- __glXPbuffer *pGlxPbuffer;
- int numAttribs = req->numAttribs;
- int *attr;
- ScreenPtr pScreen;
- __GLXFBConfig *pGlxFBConfig;
- __GLXFBConfig *be_pGlxFBConfig;
- XID be_xid;
- Display *dpy;
- DMXScreenInfo *dmxScreen;
- int s;
- int from_screen, to_screen;
-
- /*
- ** Look up screen and FBConfig.
- */
- if (screen >= screenInfo.numScreens) {
- /* The client library must send a valid screen number. */
- client->errorValue = screen;
- return BadValue;
- }
- pScreen = screenInfo.screens[screen];
-
- /*
- ** Find the FBConfigRec for this fbconfigid.
- */
- if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
- client->errorValue = fbconfigId;
- return __glXBadFBConfig;
- }
-
- /*
- ** Create the GLX part of the Pbuffer.
- */
- pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer));
- if (!pGlxPbuffer) {
- return BadAlloc;
- }
-
- pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens );
- if (!pGlxPbuffer->be_xids) {
- free(pGlxPbuffer);
- return BadAlloc;
- }
-
- /*
- * Allocate an XID on the back-end server(s) and send him the request
- */
- from_screen = to_screen = screen;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- dpy = GetBackEndDisplay(cl,s);
- be_xid = XAllocID(dpy);
- dmxScreen = &dmxScreens[s];
- be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s );
-
- attr = (int *)( req+1 );
-
- LockDisplay(dpy);
- GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCreatePbuffer;
- be_req->screen = be_pGlxFBConfig->screen;
- be_req->fbconfig = be_pGlxFBConfig->id;
- be_req->pbuffer = be_xid;
- be_req->numAttribs = numAttribs;
-
- /* Send attributes */
- if ( attr != NULL ) {
- CARD32 *pc = (CARD32 *)(be_req + 1);
-
- while (numAttribs-- > 0) {
- *pc++ = *attr++; /* token */
- *pc++ = *attr++; /* value */
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- pGlxPbuffer->be_xids[s] = be_xid;
- }
-
-
- pGlxPbuffer->idExists = True;
- pGlxPbuffer->refcnt = 0;
- pGlxPbuffer->pFBConfig = pGlxFBConfig;
- pGlxPbuffer->pScreen = pScreen;
-
- /*
- ** Register the resource.
- */
- if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) {
- return BadAlloc;
- }
-
- return Success;
-
-}
-
-int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
- xGLXDestroyPbufferReq *be_req;
- GLXPbuffer pbuffer = req->pbuffer;
- Display *dpy;
- int screen;
- DMXScreenInfo *dmxScreen;
- __glXPbuffer *pGlxPbuffer;
- int s;
- int from_screen, to_screen;
-
- /*
- ** Check if it's a valid Pbuffer
- */
- dixLookupResourceByType((pointer*) &pGlxPbuffer, pbuffer,
- __glXPbufferRes, NullClient, DixUnknownAccess);
- if (!pGlxPbuffer) {
- client->errorValue = pbuffer;
- return __glXBadPbuffer;
- }
-
- screen = pGlxPbuffer->pScreen->myNum;
-
- from_screen = to_screen = screen;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- dpy = GetBackEndDisplay(cl,s);
- dmxScreen = &dmxScreens[s];
-
- /* send the destroy request to the back-end server */
- LockDisplay(dpy);
- GetReq(GLXDestroyPbuffer, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXDestroyPbuffer;
- be_req->pbuffer = pGlxPbuffer->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- FreeResource(pbuffer, RT_NONE);
-
- return Success;
-}
-
-int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
- xGLXGetDrawableAttributesReq *be_req;
- xGLXGetDrawableAttributesReply reply;
- ClientPtr client = cl->client;
- GLXDrawable drawId = req->drawable;
- GLXDrawable be_drawable = 0;
- DrawablePtr pDraw = NULL;
- Display *dpy;
- int screen, rc;
- DMXScreenInfo *dmxScreen;
- CARD32 *attribs = NULL;
- int attribs_size = 0;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
-#endif
-
- if (drawId != None) {
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
- if (rc == Success && pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr)pDraw;
- be_drawable = 0;
- screen = pWin->drawable.pScreen->myNum;
- } else {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- if (!pDraw) {
- __GLXpixmap *pGlxPixmap;
- dixLookupResourceByType((pointer*) &pGlxPixmap,
- drawId, __glXPixmapRes,
- NullClient, DixUnknownAccess);
- if (pGlxPixmap) {
- pDraw = pGlxPixmap->pDraw;
- screen = pGlxPixmap->pScreen->myNum;
- be_drawable = pGlxPixmap->be_xids[screen];
- }
- }
-
- if (!pDraw) {
- __glXWindow *pGlxWindow;
- dixLookupResourceByType((pointer*) &pGlxWindow,
- drawId, __glXWindowRes,
- NullClient, DixUnknownAccess);
- if (pGlxWindow) {
- pDraw = pGlxWindow->pDraw;
- screen = pGlxWindow->pScreen->myNum;
- be_drawable = 0;
- }
- }
-
- if (!pDraw) {
- __glXPbuffer *pGlxPbuffer;
- dixLookupResourceByType((pointer*) &pGlxPbuffer,
- drawId, __glXPbufferRes,
- NullClient, DixUnknownAccess);
- if (pGlxPbuffer) {
- pDraw = (DrawablePtr)pGlxPbuffer;
- screen = pGlxPbuffer->pScreen->myNum;
- be_drawable = pGlxPbuffer->be_xids[screen];
- }
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- /* if the drawable is a window or GLXWindow -
- * we need to find the base id on the back-end server
- */
- if (!be_drawable) {
- WindowPtr pWin = (WindowPtr)pDraw;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- if (Success != dixLookupResourceByClass((pointer*) &pXinDraw,
- pDraw->id, XRC_DRAWABLE,
- client, DixReadAccess)) {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
- DixReadAccess);
- }
-#endif
-
- if (pWin) {
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_drawable) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
- else {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
-
- /* send the request to the back-end server */
- dpy = GetBackEndDisplay(cl,screen);
- dmxScreen = &dmxScreens[screen];
-
- /* make sure drawable exists on back-end */
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXGetDrawableAttributes, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXGetDrawableAttributes;
- be_req->drawable = be_drawable;
- be_req->length = req->length;
- if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- if (reply.numAttribs) {
- attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
- attribs = (CARD32 *) malloc(attribs_size);
- if (attribs == NULL) {
- UnlockDisplay(dpy);
- SyncHandle();
- return BadAlloc;
- }
-
- _XRead(dpy, (char *) attribs, attribs_size);
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
-
- /* send the reply back to the client */
- reply.sequenceNumber = client->sequence;
- if (client->swapped) {
- __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs);
- }
- else {
- WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply);
- WriteToClient(client, attribs_size, (char *)attribs);
- }
-
- free(attribs);
-
- return Success;
-}
-
-int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
- xGLXChangeDrawableAttributesReq *be_req;
- ClientPtr client = cl->client;
- GLXDrawable drawId = req->drawable;
- GLXDrawable be_drawable = 0;
- DrawablePtr pDraw = NULL;
- Display *dpy;
- int screen, rc;
- DMXScreenInfo *dmxScreen;
-
- if (drawId != None) {
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess);
- if (rc == Success && pDraw->type == DRAWABLE_WINDOW) {
- be_drawable = 0;
- screen = pDraw->pScreen->myNum;
- } else {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- if (!pDraw) {
- __GLXpixmap *pGlxPixmap;
- dixLookupResourceByType((pointer*) &pGlxPixmap,
- drawId, __glXPixmapRes,
- NullClient, DixUnknownAccess);
- if (pGlxPixmap) {
- pDraw = pGlxPixmap->pDraw;
- screen = pGlxPixmap->pScreen->myNum;
- be_drawable = pGlxPixmap->be_xids[screen];
- }
- }
-
- if (!pDraw) {
- __glXWindow *pGlxWindow;
- dixLookupResourceByType((pointer*) &pGlxWindow,
- drawId, __glXWindowRes,
- NullClient, DixUnknownAccess);
- if (pGlxWindow) {
- pDraw = pGlxWindow->pDraw;
- screen = pGlxWindow->pScreen->myNum;
- be_drawable = 0;
- }
- }
-
- if (!pDraw) {
- __glXPbuffer *pGlxPbuffer;
- dixLookupResourceByType((pointer*) &pGlxPbuffer,
- drawId, __glXPbufferRes,
- NullClient, DixUnknownAccess);
- if (pGlxPbuffer) {
- pDraw = (DrawablePtr)pGlxPbuffer;
- screen = pGlxPbuffer->pScreen->myNum;
- be_drawable = pGlxPbuffer->be_xids[screen];
- }
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- /* if the drawable is a window or GLXWindow -
- * we need to find the base id on the back-end server
- */
- if (!be_drawable) {
- WindowPtr pWin = (WindowPtr)pDraw;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- PanoramiXRes *pXinDraw;
- if (Success != dixLookupResourceByClass((pointer*) &pXinDraw,
- pDraw->id, XRC_DRAWABLE,
- client, DixReadAccess)) {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
- DixReadAccess);
- }
-#endif
-
- if (pWin) {
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_drawable) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
- else {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
-
- /* send the request to the back-end server */
- dpy = GetBackEndDisplay(cl,screen);
- dmxScreen = &dmxScreens[screen];
-
- /* make sure drawable exists on back-end */
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReqExtra(GLXChangeDrawableAttributes,
- 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXChangeDrawableAttributes;
- be_req->drawable = be_drawable;
- be_req->numAttribs = req->numAttribs;
- be_req->length = req->length;
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return Success;
-}
-
-int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag)
-{
- ClientPtr client = cl->client;
- xGLXRenderLargeReq *req;
- GLint maxSize, amount;
- GLint totalRequests, requestNumber;
- GLint dataLen;
- GLbyte *data;
- __GLXcontext *glxc;
- int s;
- int from_screen, to_screen;
-
- maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq);
- dataLen = cl->largeCmdBytesTotal;
- totalRequests = (dataLen / maxSize);
- if (dataLen % maxSize) totalRequests++;
-
- glxc = __glXLookupContextByTag(cl, contextTag);
- if (!glxc) {
- client->errorValue = contextTag;
- return __glXBadContext;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- /*
- ** Send enough requests until the whole array is sent.
- */
- requestNumber = 1;
- data = cl->largeCmdBuf;
- while (dataLen > 0) {
- amount = dataLen;
- if (amount > maxSize) {
- amount = maxSize;
- }
-
- for (s=from_screen; s<=to_screen; s++) {
-
- Display *dpy = GetBackEndDisplay(cl,s);
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
-
- LockDisplay(dpy);
- GetReq(GLXRenderLarge,req);
- req->reqType = dmxScreen->glxMajorOpcode;
- req->glxCode = X_GLXRenderLarge;
- req->contextTag = GetCurrentBackEndTag(cl,contextTag,s);
- req->length += (amount + 3) >> 2;
- req->requestNumber = requestNumber++;
- req->requestTotal = totalRequests;
- req->dataBytes = amount;
- Data(dpy, ((const char*)data), amount);
- dataLen -= amount;
- data = ((GLbyte *) data) + amount;
- UnlockDisplay(dpy);
- SyncHandle();
- }
- }
-
- return Success;
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" +#include "dmxfont.h" +#include "dmxsync.h" + +#include "glxserver.h" +#include <GL/glxtokens.h> +#include "g_disptab.h" +#include <pixmapstr.h> +#include <windowstr.h> +#include "glxutil.h" +#include "glxext.h" +#include "unpack.h" + +#include "GL/glxproto.h" +#include "glxvendor.h" +#include "glxvisuals.h" +#include "glxswap.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +extern __GLXFBConfig **__glXFBConfigs; +extern int __glXNumFBConfigs; + +extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id ); +extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid ); +extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen ); +extern int glxIsExtensionSupported( char *ext ); +extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); + +#define BE_TO_CLIENT_ERROR(x) \ + ( (x) >= __glXerrorBase ? \ + (x) - dmxScreen->glxErrorBase + __glXerrorBase \ + : (x) ) + +Display *GetBackEndDisplay( __GLXclientState *cl, int s ) +{ + if (! cl->be_displays[s] ) { + cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) ); + } + return cl->be_displays[s]; +} + +/* +** Create a GL context with the given properties. +*/ +static int CreateContext(__GLXclientState *cl, + GLXContextID gcId, + VisualID vid, GLXFBConfigID fbconfigId, + int screen, + GLXContextID shareList, + int isDirect ) +{ + ClientPtr client = cl->client; + xGLXCreateContextReq *be_req; + xGLXCreateNewContextReq *be_new_req; + VisualPtr pVisual; + ScreenPtr pScreen; + __GLXcontext *glxc, *shareglxc; + __GLXvisualConfig *pGlxVisual; + __GLXscreenInfo *pGlxScreen; + VisualID visual = vid; + GLint i; + int from_screen = screen; + int to_screen = screen; + DMXScreenInfo *dmxScreen; + VisualID be_vid = 0; + GLXFBConfigID be_fbconfigId = 0; + int num_be_screens; + Display *dpy; + + /* + ** Check if screen exists. + */ + if (screen >= screenInfo.numScreens) { + client->errorValue = screen; + return BadValue; + } + + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + /* + ** Find the display list space that we want to share. + ** + */ + if (shareList == None) { + shareglxc = NULL; + } else { + dixLookupResourceByType((pointer*) &shareglxc, shareList, + __glXContextRes, NullClient, DixUnknownAccess); + if (!shareglxc) { + client->errorValue = shareList; + return __glXBadContext; + } + } + + /* + ** Allocate memory for the new context + */ + glxc = calloc(1, sizeof(__GLXcontext)); + if (!glxc) { + return BadAlloc; + } + + pScreen = screenInfo.screens[screen]; + pGlxScreen = &__glXActiveScreens[screen]; + + if (fbconfigId != None) { + glxc->pFBConfig = glxLookupFBConfig( fbconfigId ); + if (!glxc->pFBConfig) { + client->errorValue = fbconfigId; + free( glxc ); + return BadValue; + } + visual = glxc->pFBConfig->associatedVisualId; + } + else { + glxc->pFBConfig = NULL; + } + + if (visual != None) { + /* + ** Check if the visual ID is valid for this screen. + */ + pVisual = pScreen->visuals; + for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { + if (pVisual->vid == visual) { + break; + } + } + if (i == pScreen->numVisuals) { + client->errorValue = visual; + free( glxc ); + return BadValue; + } + + pGlxVisual = pGlxScreen->pGlxVisual; + for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { + if (pGlxVisual->vid == visual) { + break; + } + } + if (i == pGlxScreen->numVisuals) { + /* + ** Visual not support on this screen by this OpenGL implementation. + */ + client->errorValue = visual; + free( glxc ); + return BadValue; + } + + if ( glxc->pFBConfig == NULL ) { + glxc->pFBConfig = glxLookupFBConfigByVID( visual ); + + if ( glxc->pFBConfig == NULL ) { + /* + * visual does not have an FBConfig ??? + client->errorValue = visual; + free( glxc ); + return BadValue; + */ + } + } + } + else { + pVisual = NULL; + pGlxVisual = NULL; + } + + glxc->pScreen = pScreen; + glxc->pGlxScreen = pGlxScreen; + glxc->pVisual = pVisual; + glxc->pGlxVisual = pGlxVisual; + + /* + * allocate memory for back-end servers info + */ + num_be_screens = to_screen - from_screen + 1; + glxc->real_ids = (XID *)malloc(sizeof(XID) * num_be_screens); + if (!glxc->real_ids) { + return BadAlloc; + } + glxc->real_vids = (XID *)malloc(sizeof(XID) * num_be_screens); + if (!glxc->real_vids) { + return BadAlloc; + } + + for (screen = from_screen; screen <= to_screen; screen++) { + int sent = 0; + pScreen = screenInfo.screens[screen]; + pGlxScreen = &__glXActiveScreens[screen]; + dmxScreen = &dmxScreens[screen]; + + if (glxc->pFBConfig) { + __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id, + screen ); + be_fbconfigId = beFBConfig->id; + } + + if (pGlxVisual) { + + be_vid = glxMatchGLXVisualInConfigList( pGlxVisual, + dmxScreen->glxVisuals, + dmxScreen->numGlxVisuals ); + + if (!be_vid) { + /* visual is not supported on the back-end server */ + free( glxc->real_ids ); + free( glxc->real_vids ); + free( glxc ); + return BadValue; + } + } + + glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen)); + + /* send the create context request to the back-end server */ + dpy = GetBackEndDisplay(cl,screen); + if (glxc->pFBConfig) { + /*Since for a certain visual both RGB and COLOR INDEX + *can be on then the only parmeter to choose the renderType + * should be the class of the colormap since all 4 first + * classes does not support RGB mode only COLOR INDEX , + * and so TrueColor and DirectColor does not support COLOR INDEX*/ + int renderType = glxc->pFBConfig->renderType; + if ( pVisual ) { + switch ( pVisual->class ){ + case PseudoColor: + case StaticColor: + case GrayScale: + case StaticGray: + renderType = GLX_COLOR_INDEX_TYPE; + break; + case TrueColor: + case DirectColor: + default: + renderType = GLX_RGBA_TYPE; + break; + } + } + if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { + LockDisplay(dpy); + GetReq(GLXCreateNewContext,be_new_req); + be_new_req->reqType = dmxScreen->glxMajorOpcode; + be_new_req->glxCode = X_GLXCreateNewContext; + be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; + be_new_req->fbconfig = (unsigned int)be_fbconfigId; + be_new_req->screen = DefaultScreen(dpy); + be_new_req->renderType = renderType; + + be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); + be_new_req->isDirect = 0; + UnlockDisplay(dpy); + glxc->real_vids[screen-from_screen] = be_fbconfigId; + sent = 1; + } + else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) { + + xGLXCreateContextWithConfigSGIXReq *ext_req; + xGLXVendorPrivateReq *vpreq; + LockDisplay(dpy); + GetReqExtra(GLXVendorPrivate, + sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq, + vpreq); + ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq; + ext_req->reqType = dmxScreen->glxMajorOpcode; + ext_req->glxCode = X_GLXVendorPrivate; + ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; + ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; + ext_req->fbconfig = (unsigned int)be_fbconfigId; + ext_req->screen = DefaultScreen(dpy); + ext_req->renderType = renderType; + ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); + ext_req->isDirect = 0; + UnlockDisplay(dpy); + glxc->real_vids[screen-from_screen] = be_fbconfigId; + sent = 1; + } + } + + if (!sent) { + LockDisplay(dpy); + GetReq(GLXCreateContext,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCreateContext; + be_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; + be_req->visual = (unsigned int)be_vid; + be_req->screen = DefaultScreen(dpy); + be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); + be_req->isDirect = 0; + UnlockDisplay(dpy); + glxc->real_vids[screen-from_screen] = be_vid; + } + SyncHandle(); + + } + + /* + ** Register this context as a resource. + */ + if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { + free( glxc->real_ids ); + free( glxc->real_vids ); + free( glxc ); + client->errorValue = gcId; + return BadAlloc; + } + + /* + ** Finally, now that everything is working, setup the rest of the + ** context. + */ + glxc->id = gcId; + glxc->share_id = shareList; + glxc->idExists = GL_TRUE; + glxc->isCurrent = GL_FALSE; + + return Success; +} + +int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; + + return( CreateContext(cl, req->context,req->visual, None, + req->screen, req->shareList, req->isDirect) ); + +} + +int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; + + return( CreateContext(cl, req->context,None, req->fbconfig, + req->screen, req->shareList, req->isDirect) ); + +} + +int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; + + return( CreateContext(cl, req->context, None, req->fbconfig, + req->screen, req->shareList, req->isDirect) ); + +} + +int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryMaxSwapBarriersSGIXReq *req = + (xGLXQueryMaxSwapBarriersSGIXReq *)pc; + xGLXQueryMaxSwapBarriersSGIXReply reply; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = 0; + reply.max = QueryMaxSwapBarriersSGIX(req->screen); + + if (client->swapped) { + __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, + (char *)&reply); + } + + return Success; +} + +int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc; + DrawablePtr pDraw; + __GLXpixmap *pGlxPixmap = NULL; + __glXWindow *pGlxWindow = NULL; + int rc; + + rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess); + if (rc != Success) { + dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) pDraw = pGlxWindow->pDraw; + } + + if (!pDraw) { + client->errorValue = req->drawable; + return __glXBadDrawable; + } + + return BindSwapBarrierSGIX(pDraw, req->barrier); +} + +int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc; + DrawablePtr pDraw, pMember = NULL; + __GLXpixmap *pGlxPixmap = NULL; + __glXWindow *pGlxWindow = NULL; + int rc; + + rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess); + if (rc != Success) { + dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) pDraw = pGlxWindow->pDraw; + } + + if (!pDraw) { + client->errorValue = req->drawable; + return __glXBadDrawable; + } + + if (req->member != None) { + rc = dixLookupDrawable(&pMember, req->member, client, 0, + DixGetAttrAccess); + if (rc != Success) { + dixLookupResourceByType((pointer*) &pGlxPixmap, req->member, + __glXPixmapRes, NullClient, + DixUnknownAccess); + if (pGlxPixmap) pMember = pGlxPixmap->pDraw; + } + + if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, req->member, + __glXWindowRes, NullClient, + DixUnknownAccess); + if (pGlxWindow) pMember = pGlxWindow->pDraw; + } + + if (!pMember) { + client->errorValue = req->member; + return __glXBadDrawable; + } + } + + return JoinSwapGroupSGIX(pDraw, pMember); +} + + +/* +** Destroy a GL context as an X resource. +*/ +int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; + xGLXDestroyContextReq *be_req; + GLXContextID gcId = req->context; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int s; + + dixLookupResourceByType((pointer*) &glxc, gcId, __glXContextRes, + NullClient, DixUnknownAccess); + if (glxc) { + /* + ** Just free the resource; don't actually destroy the context, + ** because it might be in use. The + ** destroy method will be called by the resource destruction routine + ** if necessary. + */ + FreeResourceByType(gcId, __glXContextRes, FALSE); + + from_screen = to_screen = glxc->pScreen->myNum; + + } else { + client->errorValue = gcId; + return __glXBadContext; + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + /* + * send DestroyContext request to all back-end servers + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXDestroyContext,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXDestroyContext; + be_req->context = glxc->real_ids[s-from_screen]; + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +/*****************************************************************************/ + +/* +** For each client, the server keeps a table of all the contexts that are +** current for that client (each thread of a client may have its own current +** context). These routines add, change, and lookup contexts in the table. +*/ + +/* +** Add a current context, and return the tag that will be used to refer to it. +*/ +static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw) +{ + int i; + int num = cl->numCurrentContexts; + __GLXcontext **table = cl->currentContexts; + + if (!glxc) return -1; + + /* + ** Try to find an empty slot and use it. + */ + for (i=0; i < num; i++) { + if (!table[i]) { + table[i] = glxc; + return i+1; + } + } + /* + ** Didn't find a free slot, so we'll have to grow the table. + */ + if (!num) { + table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); + cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr)); + cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens *sizeof(GLXContextTag)); + } else { + table = (__GLXcontext **) realloc(table, + (num+1)*sizeof(__GLXcontext *)); + cl->currentDrawables = (DrawablePtr *) realloc( + cl->currentDrawables , + (num+1)*sizeof(DrawablePtr)); + cl->be_currentCTag = (GLXContextTag *) realloc(cl->be_currentCTag, + (num+1)*screenInfo.numScreens*sizeof(GLXContextTag)); + } + table[num] = glxc; + cl->currentDrawables[num] = pDraw; + cl->currentContexts = table; + cl->numCurrentContexts++; + + memset(cl->be_currentCTag + num*screenInfo.numScreens, 0, + screenInfo.numScreens * sizeof(GLXContextTag)); + + return num+1; +} + +/* +** Given a tag, change the current context for the corresponding entry. +*/ +static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, + GLXContextTag tag) +{ + __GLXcontext **table = cl->currentContexts; + table[tag-1] = glxc; +} + +/* +** Given a tag, and back-end screen number, retrives the current back-end +** tag. +*/ +int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s) +{ + if (tag >0) { + return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] ); + } + else { + return 0; + } +} + +/* +** Given a tag, and back-end screen number, sets the current back-end +** tag. +*/ +static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag) +{ + if (tag >0) { + cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag; + } +} + +/* +** For this implementation we have chosen to simply use the index of the +** context's entry in the table as the context tag. A tag must be greater +** than 0. +*/ +__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) +{ + int num = cl->numCurrentContexts; + + if (tag < 1 || tag > num) { + return 0; + } else { + return cl->currentContexts[tag-1]; + } +} + +DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag) +{ + int num = cl->numCurrentContexts; + + if (tag < 1 || tag > num) { + return 0; + } else { + return cl->currentDrawables[tag-1]; + } +} + +/*****************************************************************************/ + +static void StopUsingContext(__GLXcontext *glxc) +{ + if (glxc) { + if (glxc == __glXLastContext) { + /* Tell server GL library */ + __glXLastContext = 0; + } + glxc->isCurrent = GL_FALSE; + if (!glxc->idExists) { + __glXFreeContext(glxc); + } + } +} + +static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) +{ + glxc->isCurrent = GL_TRUE; +} + +/*****************************************************************************/ +/* +** Make an OpenGL context and drawable current. +*/ +static int MakeCurrent(__GLXclientState *cl, + GLXDrawable drawable, + GLXDrawable readdrawable, + GLXContextID context, + GLXContextTag oldContextTag) +{ + ClientPtr client = cl->client; + DrawablePtr pDraw = NULL; + DrawablePtr pReadDraw = NULL; + xGLXMakeCurrentReadSGIReply new_reply; + xGLXMakeCurrentReq *be_req; + xGLXMakeCurrentReply be_reply; + xGLXMakeContextCurrentReq *be_new_req; + xGLXMakeContextCurrentReply be_new_reply; + GLXDrawable drawId = drawable; + GLXDrawable readId = readdrawable; + GLXContextID contextId = context; + __GLXpixmap *pGlxPixmap = 0; + __GLXpixmap *pReadGlxPixmap = 0; + __GLXcontext *glxc, *prevglxc; + GLXContextTag tag = oldContextTag; + WindowPtr pWin = NULL; + WindowPtr pReadWin = NULL; + __glXWindow *pGlxWindow = NULL; + __glXWindow *pGlxReadWindow = NULL; + __glXPbuffer *pGlxPbuffer = NULL; + __glXPbuffer *pGlxReadPbuffer = NULL; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; + PanoramiXRes *pXinReadDraw = NULL; +#endif + int from_screen = 0; + int to_screen = 0; + int s, rc; + + /* + ** If one is None and the other isn't, it's a bad match. + */ + if ((drawId == None && contextId != None) || + (drawId != None && contextId == None)) { + return BadMatch; + } + + /* + ** Lookup old context. If we have one, it must be in a usable state. + */ + if (tag != 0) { + prevglxc = __glXLookupContextByTag(cl, tag); + if (!prevglxc) { + /* + ** Tag for previous context is invalid. + */ + return __glXBadContextTag; + } + } else { + prevglxc = 0; + } + + /* + ** Lookup new context. It must not be current for someone else. + */ + if (contextId != None) { + dixLookupResourceByType((pointer*) &glxc, contextId, __glXContextRes, + NullClient, DixUnknownAccess); + if (!glxc) { + client->errorValue = contextId; + return __glXBadContext; + } + if ((glxc != prevglxc) && glxc->isCurrent) { + /* Context is current to somebody else */ + return BadAccess; + } + } else { + /* Switching to no context. Ignore new drawable. */ + glxc = 0; + } + + if (drawId != None) { + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); + if (rc == Success) { + if (pDraw->type == DRAWABLE_WINDOW) { + /* + ** Drawable is an X Window. + */ + VisualID vid; + pWin = (WindowPtr)pDraw; + vid = wVisual(pWin); + + new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); + new_reply.writeType = GLX_WINDOW_TYPE; + + /* + ** Check if window and context are similar. + */ + if ((vid != glxc->pVisual->vid) || + (pWin->drawable.pScreen != glxc->pScreen)) { + client->errorValue = drawId; + return BadMatch; + } + + from_screen = to_screen = pWin->drawable.pScreen->myNum; + + } else { + /* + ** An X Pixmap is not allowed as a parameter (a GLX Pixmap + ** is, but it must first be created with glxCreateGLXPixmap). + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + if (!pDraw) { + dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, + __glXPixmapRes, NullClient, + DixUnknownAccess); + if (pGlxPixmap) { + /* + ** Check if pixmap and context are similar. + */ + if (pGlxPixmap->pScreen != glxc->pScreen || + pGlxPixmap->pGlxVisual != glxc->pGlxVisual) { + client->errorValue = drawId; + return BadMatch; + } + pDraw = pGlxPixmap->pDraw; + + new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : + pGlxPixmap->pGlxVisual->vid); + + new_reply.writeType = GLX_PIXMAP_TYPE; + + from_screen = to_screen = pGlxPixmap->pScreen->myNum; + + } + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, drawId, + __glXWindowRes, NullClient, + DixUnknownAccess); + if (pGlxWindow) { + /* + ** Drawable is a GLXWindow. + ** + ** Check if GLX window and context are similar. + */ + if (pGlxWindow->pScreen != glxc->pScreen || + pGlxWindow->pGlxFBConfig != glxc->pFBConfig) { + client->errorValue = drawId; + return BadMatch; + } + + pDraw = pGlxWindow->pDraw; + new_reply.writeVid = pGlxWindow->pGlxFBConfig->id; + new_reply.writeType = GLX_GLXWINDOW_TYPE; + } + + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxPbuffer, drawId, + __glXPbufferRes, NullClient, + DixUnknownAccess); + if (pGlxPbuffer) { + if (pGlxPbuffer->pScreen != glxc->pScreen || + pGlxPbuffer->pFBConfig != glxc->pFBConfig) { + client->errorValue = drawId; + return BadMatch; + } + + pDraw = (DrawablePtr)pGlxPbuffer; + new_reply.writeVid = pGlxPbuffer->pFBConfig->id; + new_reply.writeType = GLX_PBUFFER_TYPE; + } + } + + if (!pDraw) { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + } else { + pDraw = 0; + } + + if (readId != None && readId != drawId ) { + rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess); + if (rc == Success) { + if (pReadDraw->type == DRAWABLE_WINDOW) { + /* + ** Drawable is an X Window. + */ + VisualID vid; + pReadWin = (WindowPtr)pDraw; + vid = wVisual(pReadWin); + + new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); + new_reply.readType = GLX_WINDOW_TYPE; + + /* + ** Check if window and context are similar. + */ + if ((vid != glxc->pVisual->vid) || + (pReadWin->drawable.pScreen != glxc->pScreen)) { + client->errorValue = readId; + return BadMatch; + } + + } else { + + /* + ** An X Pixmap is not allowed as a parameter (a GLX Pixmap + ** is, but it must first be created with glxCreateGLXPixmap). + */ + client->errorValue = readId; + return __glXBadDrawable; + } + } + + if (!pReadDraw) { + dixLookupResourceByType((pointer*) &pReadGlxPixmap, readId, + __glXPixmapRes, NullClient, + DixUnknownAccess); + if (pReadGlxPixmap) { + /* + ** Check if pixmap and context are similar. + */ + if (pReadGlxPixmap->pScreen != glxc->pScreen || + pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) { + client->errorValue = readId; + return BadMatch; + } + pReadDraw = pReadGlxPixmap->pDraw; + + new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : + pReadGlxPixmap->pGlxVisual->vid ); + new_reply.readType = GLX_PIXMAP_TYPE; + + } + } + + if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxReadWindow, readId, + __glXWindowRes, NullClient, + DixUnknownAccess); + if (pGlxReadWindow) { + /* + ** Drawable is a GLXWindow. + ** + ** Check if GLX window and context are similar. + */ + if (pGlxReadWindow->pScreen != glxc->pScreen || + pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) { + client->errorValue = readId; + return BadMatch; + } + + pReadDraw = pGlxReadWindow->pDraw; + new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id; + new_reply.readType = GLX_GLXWINDOW_TYPE; + } + } + + if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxReadPbuffer, readId, + __glXPbufferRes, NullClient, + DixUnknownAccess); + if (pGlxReadPbuffer) { + if (pGlxReadPbuffer->pScreen != glxc->pScreen || + pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) { + client->errorValue = drawId; + return BadMatch; + } + + pReadDraw = (DrawablePtr)pGlxReadPbuffer; + new_reply.readVid = pGlxReadPbuffer->pFBConfig->id; + new_reply.readType = GLX_PBUFFER_TYPE; + } + } + + if (!pReadDraw) { + /* + ** Drawable is neither a Window nor a GLXPixmap. + */ + client->errorValue = readId; + return __glXBadDrawable; + } + + } else { + pReadDraw = pDraw; + pReadGlxPixmap = pGlxPixmap; + pReadWin = pWin; + new_reply.readVid = new_reply.writeVid; + new_reply.readType = new_reply.writeType; + } + + if (prevglxc) { + + if (prevglxc->pGlxPixmap) { + /* + ** The previous drawable was a glx pixmap, release it. + */ + prevglxc->pGlxPixmap->refcnt--; + __glXFreeGLXPixmap( prevglxc->pGlxPixmap ); + prevglxc->pGlxPixmap = 0; + } + + if (prevglxc->pGlxReadPixmap) { + /* + ** The previous drawable was a glx pixmap, release it. + */ + prevglxc->pGlxReadPixmap->refcnt--; + __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap ); + prevglxc->pGlxReadPixmap = 0; + } + + if (prevglxc->pGlxWindow) { + /* + ** The previous drawable was a glx window, release it. + */ + prevglxc->pGlxWindow->refcnt--; + __glXFreeGLXWindow( prevglxc->pGlxWindow ); + prevglxc->pGlxWindow = 0; + } + + if (prevglxc->pGlxReadWindow) { + /* + ** The previous drawable was a glx window, release it. + */ + prevglxc->pGlxReadWindow->refcnt--; + __glXFreeGLXWindow( prevglxc->pGlxReadWindow ); + prevglxc->pGlxReadWindow = 0; + } + + if (prevglxc->pGlxPbuffer) { + /* + ** The previous drawable was a glx Pbuffer, release it. + */ + prevglxc->pGlxPbuffer->refcnt--; + __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer ); + prevglxc->pGlxPbuffer = 0; + } + + if (prevglxc->pGlxReadPbuffer) { + /* + ** The previous drawable was a glx Pbuffer, release it. + */ + prevglxc->pGlxReadPbuffer->refcnt--; + __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer ); + prevglxc->pGlxReadPbuffer = 0; + } + + ChangeCurrentContext(cl, glxc, tag); + ChangeCurrentContext(cl, glxc, tag); + StopUsingContext(prevglxc); + } else { + tag = AddCurrentContext(cl, glxc, pDraw); + } + if (glxc) { + + glxc->pGlxPixmap = pGlxPixmap; + glxc->pGlxReadPixmap = pReadGlxPixmap; + glxc->pGlxWindow = pGlxWindow; + glxc->pGlxReadWindow = pGlxReadWindow; + glxc->pGlxPbuffer = pGlxPbuffer; + glxc->pGlxReadPbuffer = pGlxReadPbuffer; + + if (pGlxPixmap) { + pGlxPixmap->refcnt++; + } + + if (pReadGlxPixmap) { + pReadGlxPixmap->refcnt++; + } + + if (pGlxWindow) { + pGlxWindow->refcnt++; + } + + if (pGlxReadWindow) { + pGlxReadWindow->refcnt++; + } + + if (pGlxPbuffer) { + pGlxPbuffer->refcnt++; + } + + if (pGlxReadPbuffer) { + pGlxReadPbuffer->refcnt++; + } + + StartUsingContext(cl, glxc); + new_reply.contextTag = tag; + } else { + new_reply.contextTag = 0; + } + new_reply.length = 0; + new_reply.type = X_Reply; + new_reply.sequenceNumber = client->sequence; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + + if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) { + dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } + + if (pReadDraw && pReadDraw != pDraw && + new_reply.readType != GLX_PBUFFER_TYPE) { + dixLookupResourceByClass((pointer*) &pXinReadDraw, + pReadDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } + else { + pXinReadDraw = pXinDraw; + } + } +#endif + + + /* send the MakeCurrent request to all required + * back-end servers. + */ + for (s = from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + unsigned int be_draw = None; + unsigned int be_read_draw = None; + + if (pGlxPixmap) { + be_draw = pGlxPixmap->be_xids[s]; + } + else if (pGlxPbuffer) { + be_draw = pGlxPbuffer->be_xids[s]; + } +#ifdef PANORAMIX + else if (pXinDraw) { + dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); + } +#endif + else if (pGlxWindow) { + pWin = (WindowPtr)pGlxWindow->pDraw; + } + + if (pWin && be_draw == None) { + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_draw) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + + /* + * Before sending the MakeCurrent request - sync the + * X11 connection to the back-end servers to make sure + * that drawable is already created + */ + dmxSync( dmxScreen, 1 ); + + if (drawId == readId) { + LockDisplay(dpy); + GetReq(GLXMakeCurrent, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXMakeCurrent; + be_req->drawable = be_draw; + be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); + be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); + if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) { + + /* The make current failed */ + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + UnlockDisplay(dpy); + SyncHandle(); + + SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag ); + } + else { + + if (pReadGlxPixmap) { + be_read_draw = pReadGlxPixmap->be_xids[s]; + } + else if (pGlxReadPbuffer) { + be_read_draw = pGlxReadPbuffer->be_xids[s]; + } +#ifdef PANORAMIX + else if (pXinReadDraw) { + dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client, + DixReadAccess); + } +#endif + else if (pGlxReadWindow) { + pReadWin = (WindowPtr)pGlxReadWindow->pDraw; + } + + if (pReadWin && be_read_draw == None) { + be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; + if (!be_read_draw) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pReadWin, TRUE ); + be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; + dmxSync( dmxScreen, 1 ); + } + } + + if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { + LockDisplay(dpy); + GetReq(GLXMakeContextCurrent, be_new_req); + be_new_req->reqType = dmxScreen->glxMajorOpcode; + be_new_req->glxCode = X_GLXMakeContextCurrent; + be_new_req->drawable = be_draw; + be_new_req->readdrawable = be_read_draw; + be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); + be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); + if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) { + + /* The make current failed */ + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + UnlockDisplay(dpy); + SyncHandle(); + + SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag ); + } + else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) { + xGLXMakeCurrentReadSGIReq *ext_req; + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXMakeCurrentReadSGIReply ext_reply; + + LockDisplay(dpy); + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq, + vpreq); + ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq; + ext_req->reqType = dmxScreen->glxMajorOpcode; + ext_req->glxCode = X_GLXVendorPrivateWithReply; + ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI; + ext_req->drawable = be_draw; + ext_req->readable = be_read_draw; + ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); + ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); + if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) { + + /* The make current failed */ + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + UnlockDisplay(dpy); + SyncHandle(); + + SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag ); + + } + else { + return BadMatch; + } + } + + XFlush( dpy ); + } + + if (client->swapped) { + __glXSwapMakeCurrentReply(client, &new_reply); + } else { + WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply); + } + + return Success; +} + +int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; + + return( MakeCurrent(cl, req->drawable, req->drawable, + req->context, req->oldContextTag ) ); +} + +int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; + + return( MakeCurrent(cl, req->drawable, req->readdrawable, + req->context, req->oldContextTag ) ); +} + +int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; + + return( MakeCurrent(cl, req->drawable, req->readable, + req->context, req->oldContextTag ) ); +} + +int __glXIsDirect(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; + xGLXIsDirectReply reply; + __GLXcontext *glxc; + + /* + ** Find the GL context. + */ + dixLookupResourceByType((pointer*) &glxc, req->context, __glXContextRes, + NullClient, DixUnknownAccess); + if (!glxc) { + client->errorValue = req->context; + return __glXBadContext; + } + + reply.isDirect = 0; + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __glXSwapIsDirectReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); + } + + return Success; +} + +int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; +/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */ + xGLXQueryVersionReply reply; + + /* + ** Server should take into consideration the version numbers sent by the + ** client if it wants to work with older clients; however, in this + ** implementation the server just returns its version number. + */ + reply.majorVersion = __glXVersionMajor; + reply.minorVersion = __glXVersionMinor; + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __glXSwapQueryVersionReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); + } + return Success; +} + +int __glXWaitGL(__GLXclientState *cl, GLbyte *pc) +{ + xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; + xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc; + int from_screen = 0; + int to_screen = 0; + int s; + __GLXcontext *glxc = NULL; + + if (req->contextTag != 0) { + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (glxc) { + from_screen = to_screen = glxc->pScreen->myNum; + } + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXWaitGL,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXWaitGL; + be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + UnlockDisplay(dpy); + SyncHandle(); + + XSync(dpy, False); + } + + return Success; +} + +int __glXWaitX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXWaitXReq *req = (xGLXWaitXReq *)pc; + xGLXWaitXReq *be_req; + int from_screen = 0; + int to_screen = 0; + int s; + __GLXcontext *glxc = NULL; + + if (req->contextTag != 0) { + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (glxc) { + from_screen = to_screen = glxc->pScreen->myNum; + } + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXWaitX,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXWaitX; + be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + UnlockDisplay(dpy); + SyncHandle(); + + XFlush( dpy ); + } + + return Success; +} + +int __glXCopyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCopyContextReq *be_req; + xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; + GLXContextID source = req->source; + GLXContextID dest = req->dest; + GLXContextTag tag = req->contextTag; + unsigned long mask = req->mask; + __GLXcontext *src, *dst; + int s; + int from_screen = 0; + int to_screen = 0; + + /* + ** Check that each context exists. + */ + dixLookupResourceByType((pointer*) &src, source, __glXContextRes, + NullClient, DixUnknownAccess); + if (!src) { + client->errorValue = source; + return __glXBadContext; + } + dixLookupResourceByType((pointer*) &dst, dest, __glXContextRes, + NullClient, DixUnknownAccess); + if (!dst) { + client->errorValue = dest; + return __glXBadContext; + } + + /* + ** They must be in the same address space, and same screen. + */ + if (src->pGlxScreen != dst->pGlxScreen) { + client->errorValue = source; + return BadMatch; + } + + /* + ** The destination context must not be current for any client. + */ + if (dst->isCurrent) { + client->errorValue = dest; + return BadAccess; + } + + if (tag) { + __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); + + if (!tagcx) { + return __glXBadContextTag; + } + if (tagcx != src) { + /* + ** This would be caused by a faulty implementation of the client + ** library. + */ + return BadMatch; + } + } + + from_screen = to_screen = src->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXCopyContext,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCopyContext; + be_req->source = (unsigned int)src->real_ids[s-from_screen]; + be_req->dest = (unsigned int)dst->real_ids[s-from_screen]; + be_req->mask = mask; + be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; + xGLXGetVisualConfigsReply reply; + __GLXscreenInfo *pGlxScreen; + __GLXvisualConfig *pGlxVisual; + CARD32 buf[__GLX_TOTAL_CONFIG]; + unsigned int screen; + int i, p; + + screen = req->screen; + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + pGlxScreen = &__glXActiveScreens[screen]; + + reply.numVisuals = pGlxScreen->numGLXVisuals; + reply.numProps = __GLX_TOTAL_CONFIG; + reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 * + __GLX_TOTAL_CONFIG) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); + + for (i=0; i < pGlxScreen->numVisuals; i++) { + pGlxVisual = &pGlxScreen->pGlxVisual[i]; + if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) { + /* not a usable visual */ + continue; + } + p = 0; + buf[p++] = pGlxVisual->vid; + buf[p++] = pGlxVisual->class; + buf[p++] = pGlxVisual->rgba; + + buf[p++] = pGlxVisual->redSize; + buf[p++] = pGlxVisual->greenSize; + buf[p++] = pGlxVisual->blueSize; + buf[p++] = pGlxVisual->alphaSize; + buf[p++] = pGlxVisual->accumRedSize; + buf[p++] = pGlxVisual->accumGreenSize; + buf[p++] = pGlxVisual->accumBlueSize; + buf[p++] = pGlxVisual->accumAlphaSize; + + buf[p++] = pGlxVisual->doubleBuffer; + buf[p++] = pGlxVisual->stereo; + + buf[p++] = pGlxVisual->bufferSize; + buf[p++] = pGlxVisual->depthSize; + buf[p++] = pGlxVisual->stencilSize; + buf[p++] = pGlxVisual->auxBuffers; + buf[p++] = pGlxVisual->level; + /* + ** Add token/value pairs for extensions. + */ + buf[p++] = GLX_VISUAL_CAVEAT_EXT; + buf[p++] = pGlxVisual->visualRating; + buf[p++] = GLX_TRANSPARENT_TYPE_EXT; + buf[p++] = pGlxVisual->transparentPixel; + buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; + buf[p++] = pGlxVisual->transparentRed; + buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; + buf[p++] = pGlxVisual->transparentGreen; + buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; + buf[p++] = pGlxVisual->transparentBlue; + buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; + buf[p++] = pGlxVisual->transparentAlpha; + buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; + buf[p++] = pGlxVisual->transparentIndex; + buf[p++] = GLX_SAMPLES_SGIS; + buf[p++] = pGlxVisual->multiSampleSize; + buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; + buf[p++] = pGlxVisual->nMultiSampleBuffers; + buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; + buf[p++] = pGlxVisual->visualSelectGroup; + + WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, + (char *)buf); + } + return Success; +} + +/* +** Create a GLX Pixmap from an X Pixmap. +*/ +static int CreateGLXPixmap(__GLXclientState *cl, + VisualID visual, GLXFBConfigID fbconfigId, + int screenNum, XID pixmapId, XID glxpixmapId ) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPixmapReq *be_req; + xGLXCreatePixmapReq *be_new_req; + DrawablePtr pDraw; + ScreenPtr pScreen; + VisualPtr pVisual; + __GLXpixmap *pGlxPixmap; + __GLXscreenInfo *pGlxScreen; + __GLXvisualConfig *pGlxVisual; + __GLXFBConfig *pFBConfig; + int i, s, rc; + int from_screen, to_screen; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; +#endif + + rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP, + DixAddAccess); + if (rc != Success) + return rc; + + /* + ** Check if screen of visual matches screen of pixmap. + */ + pScreen = pDraw->pScreen; + if (screenNum != pScreen->myNum) { + return BadMatch; + } + + if (fbconfigId == 0 && visual == 0) { + return BadValue; + } + + if (fbconfigId != None) { + pFBConfig = glxLookupFBConfig( fbconfigId ); + if (!pFBConfig) { + client->errorValue = fbconfigId; + return BadValue; + } + visual = pFBConfig->associatedVisualId; + } + else { + pFBConfig = NULL; + } + + if (visual != None) { + /* + ** Find the VisualRec for this visual. + */ + pVisual = pScreen->visuals; + for (i=0; i < pScreen->numVisuals; i++, pVisual++) { + if (pVisual->vid == visual) { + break; + } + } + if (i == pScreen->numVisuals) { + client->errorValue = visual; + return BadValue; + } + /* + ** Check if depth of visual matches depth of pixmap. + */ + if (pVisual->nplanes != pDraw->depth) { + client->errorValue = visual; + return BadMatch; + } + + /* + ** Get configuration of the visual. + */ + pGlxScreen = &__glXActiveScreens[screenNum]; + pGlxVisual = pGlxScreen->pGlxVisual; + for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { + if (pGlxVisual->vid == visual) { + break; + } + } + if (i == pGlxScreen->numVisuals) { + /* + ** Visual not support on this screen by this OpenGL implementation. + */ + client->errorValue = visual; + return BadValue; + } + + + /* find the FBConfig for that visual (if any) */ + if ( pFBConfig == NULL ) { + pFBConfig = glxLookupFBConfigByVID( visual ); + + if ( pFBConfig == NULL ) { + /* + * visual does not have an FBConfig ??? + client->errorValue = visual; + return BadValue; + */ + } + } + } + else { + pVisual = NULL; + pGlxVisual = NULL; + pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum]; + } + + pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap)); + if (!pGlxPixmap) { + return BadAlloc; + } + pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens); + if (!pGlxPixmap->be_xids) { + free( pGlxPixmap ); + return BadAlloc; + } + + pGlxPixmap->pDraw = pDraw; + pGlxPixmap->pGlxScreen = pGlxScreen; + pGlxPixmap->pGlxVisual = pGlxVisual; + pGlxPixmap->pFBConfig = pFBConfig; + pGlxPixmap->pScreen = pScreen; + pGlxPixmap->idExists = True; + pGlxPixmap->refcnt = 0; + + /* + ** Bump the ref count on the X pixmap so it won't disappear. + */ + ((PixmapPtr) pDraw)->refcnt++; + + /* + * send the request to the back-end server(s) + */ + from_screen = to_screen = screenNum; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + + dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + Pixmap be_pixmap; + DrawablePtr pRealDraw = pDraw; + +#ifdef PANORAMIX + if (pXinDraw) { + dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0, + DixAddAccess); + } +#endif + + be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap; + + /* make sure pixmap already created on back-end */ + dmxSync( dmxScreen, 1 ); + + if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); + + LockDisplay(dpy); + pGlxPixmap->be_xids[s] = XAllocID(dpy); + GetReq(GLXCreatePixmap,be_new_req); + be_new_req->reqType = dmxScreen->glxMajorOpcode; + be_new_req->glxCode = X_GLXCreatePixmap; + be_new_req->screen = DefaultScreen(dpy); + be_new_req->fbconfig = be_FBConfig->id; + be_new_req->pixmap = (unsigned int)be_pixmap; + be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + be_new_req->numAttribs = 0; + UnlockDisplay(dpy); + SyncHandle(); + } + else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) { + __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); + xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req; + xGLXVendorPrivateReq *vpreq; + + LockDisplay(dpy); + pGlxPixmap->be_xids[s] = XAllocID(dpy); + GetReqExtra(GLXVendorPrivate, + sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq, + vpreq); + ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq; + ext_req->reqType = dmxScreen->glxMajorOpcode; + ext_req->glxCode = X_GLXVendorPrivate; + ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; + ext_req->screen = DefaultScreen(dpy); + ext_req->fbconfig = be_FBConfig->id; + ext_req->pixmap = (unsigned int)be_pixmap; + ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + else if (pGlxVisual) { + LockDisplay(dpy); + pGlxPixmap->be_xids[s] = XAllocID(dpy); + GetReq(GLXCreateGLXPixmap,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCreateGLXPixmap; + be_req->screen = DefaultScreen(dpy); + be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList( + pGlxVisual, + dmxScreen->glxVisuals, + dmxScreen->numGlxVisuals ); + be_req->pixmap = (unsigned int)be_pixmap; + be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + else { + client->errorValue = ( visual ? visual : fbconfigId ); + free( pGlxPixmap ); + return BadValue; + } + + XFlush( dpy ); + } + + if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) { + free( pGlxPixmap ); + return BadAlloc; + } + + return Success; +} + +int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + + return( CreateGLXPixmap(cl, req->visual, None, + req->screen, req->pixmap, req->glxpixmap) ); +} + +int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + + return( CreateGLXPixmap(cl, None, req->fbconfig, + req->screen, req->pixmap, req->glxpixmap) ); +} + +int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; + XID glxpixmap = req->glxpixmap; + __GLXpixmap *pGlxPixmap; + int s; + int from_screen, to_screen; + + /* + ** Check if it's a valid GLX pixmap. + */ + dixLookupResourceByType((pointer*) &pGlxPixmap, glxpixmap, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (!pGlxPixmap) { + client->errorValue = glxpixmap; + return __glXBadPixmap; + } + FreeResource(glxpixmap, FALSE); + + /* + * destroy the pixmap on the back-end server(s). + */ + from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + /* make sure pixmap exist in back-end */ + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXDestroyGLXPixmap,req); + req->reqType = dmxScreen->glxMajorOpcode; + req->glxCode = X_GLXDestroyGLXPixmap; + req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + + + return Success; +} + +/*****************************************************************************/ + +/* +** NOTE: There is no portable implementation for swap buffers as of +** this time that is of value. Consequently, this code must be +** implemented by somebody other than SGI. +*/ +int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag) +{ + ClientPtr client = cl->client; + DrawablePtr pDraw; + xGLXSwapBuffersReq *be_req; + WindowPtr pWin = NULL; + __GLXpixmap *pGlxPixmap = NULL; + __GLXcontext *glxc = NULL; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; +#endif + __glXWindow *pGlxWindow = NULL; + int from_screen = 0; + int to_screen = 0; + int s, rc; + + /* + ** Check that the GLX drawable is valid. + */ + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); + if (rc == Success) { + from_screen = to_screen = pDraw->pScreen->myNum; + + if (pDraw->type == DRAWABLE_WINDOW) { + /* + ** Drawable is an X window. + */ + pWin = (WindowPtr)pDraw; + } else { + /* + ** Drawable is an X pixmap, which is not allowed. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + if (!pDraw) { + dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) { + /* + ** Drawable is a GLX pixmap. + */ + pDraw = pGlxPixmap->pDraw; + from_screen = to_screen = pGlxPixmap->pScreen->myNum; + } + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, drawId, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) { + /* + ** Drawable is a GLXWindow. + */ + pDraw = pGlxWindow->pDraw; + from_screen = to_screen = pGlxWindow->pScreen->myNum; + } + } + + if (!pDraw) { + /* + ** Drawable is neither a X window nor a GLX pixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXBadContextTag; + } + } + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess); + } +#endif + + /* If requested, send a glFinish to all back-end servers before swapping. */ + if (dmxGLXFinishSwap) { + for (s=from_screen; s<=to_screen; s++) { + Display *dpy = GetBackEndDisplay(cl,s); + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + xGLXSingleReq *finishReq; + xGLXSingleReply reply; + +#define X_GLXSingle 0 /* needed by GetReq below */ + + LockDisplay(dpy); + GetReq(GLXSingle,finishReq); + finishReq->reqType = dmxScreen->glxMajorOpcode; + finishReq->glxCode = X_GLsop_Finish; + finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0); + (void) _XReply(dpy, (xReply*) &reply, 0, False); + UnlockDisplay(dpy); + SyncHandle(); + } + } + + /* If requested, send an XSync to all back-end servers before swapping. */ + if (dmxGLXSyncSwap) { + for (s=from_screen; s<=to_screen; s++) + XSync(GetBackEndDisplay(cl,s), False); + } + + + /* send the SwapBuffers request to all back-end servers */ + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + unsigned int be_draw = 0; + + if (pGlxPixmap) { + be_draw = (unsigned int)pGlxPixmap->be_xids[s]; + } +#ifdef PANORAMIX + else if (pXinDraw) { + dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); + } +#endif + else if (pGlxWindow) { + pWin = (WindowPtr)pGlxWindow->pDraw; + } + + if (pWin && !be_draw) { + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_draw) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXSwapBuffers,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXSwapBuffers; + be_req->drawable = be_draw; + be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 ); + UnlockDisplay(dpy); + SyncHandle(); + XFlush(dpy); + } + + return Success; +} + +int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + DrawablePtr pDraw; + xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; + GLXContextTag tag = req->contextTag; + XID drawId = req->drawable; + __GLXpixmap *pGlxPixmap = NULL; + __GLXcontext *glxc = NULL; + __glXWindow *pGlxWindow = NULL; + int rc; + + /* + ** Check that the GLX drawable is valid. + */ + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); + if (rc == Success) { + if (pDraw->type != DRAWABLE_WINDOW) { + /* + ** Drawable is an X pixmap, which is not allowed. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + if (!pDraw) { + dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, + __glXPixmapRes, NullClient, DixUnknownAccess); + if (pGlxPixmap) { + /* + ** Drawable is a GLX pixmap. + */ + pDraw = pGlxPixmap->pDraw; + } + } + + if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { + dixLookupResourceByType((pointer*) &pGlxWindow, drawId, + __glXWindowRes, NullClient, DixUnknownAccess); + if (pGlxWindow) { + /* + ** Drawable is a GLXWindow. + */ + pDraw = pGlxWindow->pDraw; + } + } + + if (!pDraw) { + /* + ** Drawable is neither a X window nor a GLX pixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXBadContextTag; + } + } + + if (pDraw && + pDraw->type == DRAWABLE_WINDOW && + DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) { + return SGSwapBuffers(cl, drawId, tag, pDraw); + } + + return __glXDoSwapBuffers(cl, drawId, tag); +} + + +/************************************************************************/ + +/* +** Render and Renderlarge are not in the GLX API. They are used by the GLX +** client library to send batches of GL rendering commands. +*/ + +/* +** Execute all the drawing commands in a request. +*/ +int __glXRender(__GLXclientState *cl, GLbyte *pc) +{ + xGLXRenderReq *req; + xGLXRenderReq *be_req; + int size; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int s; + + /* + ** NOTE: much of this code also appears in the byteswapping version of this + ** routine, __glXSwapRender(). Any changes made here should also be + ** duplicated there. + */ + + req = (xGLXRenderReq *) pc; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXRenderReq; + size = (req->length << 2) - sz_xGLXRenderReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXRender,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXRender; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + _XSend(dpy, (const char *)pc, size); + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +/* +** Execute a large rendering request (one that spans multiple X requests). +*/ +int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc) +{ + xGLXRenderLargeReq *req; + xGLXRenderLargeReq *be_req; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int s; + + /* + ** NOTE: much of this code also appears in the byteswapping version of this + ** routine, __glXSwapRenderLarge(). Any changes made here should also be + ** duplicated there. + */ + + req = (xGLXRenderLargeReq *) pc; + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXRenderLargeReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + GetReq(GLXRenderLarge,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXRenderLarge; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + be_req->length = req->length; + be_req->requestNumber = req->requestNumber; + be_req->requestTotal = req->requestTotal; + be_req->dataBytes = req->dataBytes; + Data(dpy, (const char *)pc, req->dataBytes); + UnlockDisplay(dpy); + SyncHandle(); + + } + + return Success; +} + + +/************************************************************************/ + +int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req; + + req = (xGLXVendorPrivateReq *) pc; + + switch( req->vendorCode ) { + + case X_GLvop_DeleteTexturesEXT: + return __glXVForwardSingleReq( cl, pc ); + break; + + case X_GLXvop_SwapIntervalSGI: + if (glxIsExtensionSupported("SGI_swap_control")) { + return __glXVForwardSingleReq( cl, pc ); + } + else { + return Success; + } + break; + +#if 0 /* glx 1.3 */ + case X_GLXvop_CreateGLXVideoSourceSGIX: + break; + case X_GLXvop_DestroyGLXVideoSourceSGIX: + break; + case X_GLXvop_CreateGLXPixmapWithConfigSGIX: + break; + case X_GLXvop_DestroyGLXPbufferSGIX: + break; + case X_GLXvop_ChangeDrawableAttributesSGIX: + break; +#endif + + case X_GLXvop_BindSwapBarrierSGIX: + return __glXBindSwapBarrierSGIX( cl, pc ); + break; + + case X_GLXvop_JoinSwapGroupSGIX: + return __glXJoinSwapGroupSGIX( cl, pc ); + break; + + case X_GLXvop_CreateContextWithConfigSGIX: + return __glXCreateContextWithConfigSGIX( cl, pc ); + break; + + default: + /* + ** unsupported private request + */ + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + } + + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + +} + +int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateWithReplyReq *req; + + req = (xGLXVendorPrivateWithReplyReq *) pc; + + switch( req->vendorCode ) { + + case X_GLvop_GetConvolutionFilterEXT: + case X_GLvop_GetConvolutionParameterfvEXT: + case X_GLvop_GetConvolutionParameterivEXT: + case X_GLvop_GetSeparableFilterEXT: + case X_GLvop_GetHistogramEXT: + case X_GLvop_GetHistogramParameterivEXT: + case X_GLvop_GetMinmaxEXT: + case X_GLvop_GetMinmaxParameterfvEXT: + case X_GLvop_GetMinmaxParameterivEXT: + case X_GLvop_AreTexturesResidentEXT: + case X_GLvop_IsTextureEXT: + return( __glXVForwardPipe0WithReply(cl, pc) ); + break; + + case X_GLvop_GenTexturesEXT: + return( __glXVForwardAllWithReply(cl, pc) ); + break; + + +#if 0 /* glx1.3 */ + case X_GLvop_GetDetailTexFuncSGIS: + case X_GLvop_GetSharpenTexFuncSGIS: + case X_GLvop_GetColorTableSGI: + case X_GLvop_GetColorTableParameterfvSGI: + case X_GLvop_GetColorTableParameterivSGI: + case X_GLvop_GetTexFilterFuncSGIS: + case X_GLvop_GetInstrumentsSGIX: + case X_GLvop_InstrumentsBufferSGIX: + case X_GLvop_PollInstrumentsSGIX: + case X_GLvop_FlushRasterSGIX: + case X_GLXvop_CreateGLXPbufferSGIX: + case X_GLXvop_GetDrawableAttributesSGIX: + case X_GLXvop_QueryHyperpipeNetworkSGIX: + case X_GLXvop_QueryHyperpipeConfigSGIX: + case X_GLXvop_HyperpipeConfigSGIX: + case X_GLXvop_DestroyHyperpipeConfigSGIX: +#endif + case X_GLXvop_QueryMaxSwapBarriersSGIX: + return( __glXQueryMaxSwapBarriersSGIX(cl, pc) ); + break; + + case X_GLXvop_GetFBConfigsSGIX: + return( __glXGetFBConfigsSGIX(cl, pc) ); + break; + + case X_GLXvop_MakeCurrentReadSGI: + return( __glXMakeCurrentReadSGI(cl, pc) ); + break; + + case X_GLXvop_QueryContextInfoEXT: + return( __glXQueryContextInfoEXT(cl,pc) ); + break; + + default: + /* + ** unsupported private request + */ + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + } + +} + +int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; + xGLXQueryExtensionsStringReply reply; + GLint screen; + size_t length; + int len, numbytes; + char *be_buf; + +#ifdef FWD_QUERY_REQ + xGLXQueryExtensionsStringReq *be_req; + xGLXQueryExtensionsStringReply be_reply; + DMXScreenInfo *dmxScreen; + Display *dpy; + int slop; +#endif + + screen = req->screen; + + /* + ** Check if screen exists. + */ + if ((screen < 0) || (screen >= screenInfo.numScreens)) { + client->errorValue = screen; + return BadValue; + } + +#ifdef FWD_QUERY_REQ + dmxScreen = &dmxScreens[screen]; + + /* Send the glXQueryServerString request */ + dpy = GetBackEndDisplay(cl,screen); + LockDisplay(dpy); + GetReq(GLXQueryExtensionsString,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXQueryServerString; + be_req->screen = DefaultScreen(dpy); + _XReply(dpy, (xReply*) &be_reply, 0, False); + len = (int)be_reply.length; + numbytes = (int)be_reply.n; + slop = numbytes * __GLX_SIZE_INT8 & 3; + be_buf = (char *)malloc(numbytes); + if (!be_buf) { + /* Throw data on the floor */ + _XEatData(dpy, len); + } else { + _XRead(dpy, (char *)be_buf, numbytes); + if (slop) _XEatData(dpy,4-slop); + } + UnlockDisplay(dpy); + SyncHandle(); + +#else + + be_buf = __glXGetServerString(GLX_EXTENSIONS); + numbytes = strlen(be_buf) + 1; + len = __GLX_PAD(numbytes) >> 2; + +#endif + + length = len; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = len; + reply.n = numbytes; + + if (client->swapped) { + glxSwapQueryExtensionsStringReply(client, &reply, be_buf); + } else { + WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); + WriteToClient(client, (int)(length << 2), (char *)be_buf); + } + + return Success; +} + +int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; + xGLXQueryServerStringReply reply; + int name; + GLint screen; + size_t length; + int len, numbytes; + char *be_buf; +#ifdef FWD_QUERY_REQ + xGLXQueryServerStringReq *be_req; + xGLXQueryServerStringReply be_reply; + DMXScreenInfo *dmxScreen; + Display *dpy; + int slop; +#endif + + name = req->name; + screen = req->screen; + /* + ** Check if screen exists. + */ + if ((screen < 0) || (screen >= screenInfo.numScreens)) { + client->errorValue = screen; + return BadValue; + } + +#ifdef FWD_QUERY_REQ + dmxScreen = &dmxScreens[screen]; + + /* Send the glXQueryServerString request */ + dpy = GetBackEndDisplay(cl,screen); + LockDisplay(dpy); + GetReq(GLXQueryServerString,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXQueryServerString; + be_req->screen = DefaultScreen(dpy); + be_req->name = name; + _XReply(dpy, (xReply*) &be_reply, 0, False); + len = (int)be_reply.length; + numbytes = (int)be_reply.n; + slop = numbytes * __GLX_SIZE_INT8 & 3; + be_buf = (char *)malloc(numbytes); + if (!be_buf) { + /* Throw data on the floor */ + _XEatData(dpy, len); + } else { + _XRead(dpy, (char *)be_buf, numbytes); + if (slop) _XEatData(dpy,4-slop); + } + UnlockDisplay(dpy); + SyncHandle(); + +#else + be_buf = __glXGetServerString(name); + numbytes = strlen(be_buf) + 1; + len = __GLX_PAD(numbytes) >> 2; +#endif + + length = len; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = length; + reply.n = numbytes; + + if (client->swapped) { + glxSwapQueryServerStringReply(client, &reply, be_buf); + } else { + WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); + WriteToClient(client, (int)(length << 2), be_buf); + } + + return Success; +} + +int __glXClientInfo(__GLXclientState *cl, GLbyte *pc) +{ + xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; + xGLXClientInfoReq *be_req; + const char *buf; + int from_screen = 0; + int to_screen = 0; + int s; + + cl->GLClientmajorVersion = req->major; + cl->GLClientminorVersion = req->minor; + free(cl->GLClientextensions); + buf = (const char *)(req+1); + cl->GLClientextensions = strdup(buf); + + to_screen = screenInfo.numScreens - 1; + + for (s=from_screen; s<=to_screen; s++) + { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReq(GLXClientInfo,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXClientInfo; + be_req->major = req->major; + be_req->minor = req->minor; + be_req->length = req->length; + be_req->numbytes = req->numbytes; + Data(dpy, buf, req->numbytes); + + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +int __glXUseXFont(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXUseXFontReq *req; + xGLXUseXFontReq *be_req; + FontPtr pFont; + __GLXcontext *glxc = NULL; + int from_screen = 0; + int to_screen = 0; + int s; + dmxFontPrivPtr pFontPriv; + DMXScreenInfo *dmxScreen; + Display *dpy; + + req = (xGLXUseXFontReq *) pc; + + if (req->contextTag != 0) { + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (glxc) { + from_screen = to_screen = glxc->pScreen->myNum; + } + } + + /* + ** Font can actually be either the ID of a font or the ID of a GC + ** containing a font. + */ + dixLookupResourceByType((pointer*) &pFont, req->font, RT_FONT, + NullClient, DixUnknownAccess); + if (!pFont) { + GC *pGC; + dixLookupResourceByType((pointer*) &pGC, req->font, + RT_GC, NullClient, + DixUnknownAccess); + if (!pGC) { + client->errorValue = req->font; + return BadFont; + } + pFont = pGC->font; + } + + pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex); + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + + for (s=from_screen; s<=to_screen; s++) { + dmxScreen = &dmxScreens[s]; + dpy = GetBackEndDisplay(cl,s); + + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXUseXFont,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXUseXFont; + be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); + be_req->font = pFontPriv->font[s]->fid; + be_req->first = req->first; + be_req->count = req->count; + be_req->listBase = req->listBase; + UnlockDisplay(dpy); + SyncHandle(); + + XSync( dpy, False ); + } + + return Success; +} + +/* + * start GLX 1.3 here + */ + +int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; + xGLXGetFBConfigsReply reply; + __GLXFBConfig *pFBConfig; + CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS]; + int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS; + unsigned int screen = req->screen; + int numFBConfigs, i, p; + __GLXscreenInfo *pGlxScreen; + + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + + pGlxScreen = &__glXActiveScreens[screen]; + numFBConfigs = __glXNumFBConfigs; + + reply.numFBConfigs = numFBConfigs; + reply.numAttribs = numAttribs; + reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + __GLX_SWAP_INT(&reply.numFBConfigs); + __GLX_SWAP_INT(&reply.numAttribs); + } + WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); + + for (i=0; i < numFBConfigs; i++) { + int associatedVisualId = 0; + int drawableTypeIndex; + pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ]; + + p = 0; + /* core attributes */ + buf[p++] = GLX_FBCONFIG_ID; + buf[p++] = pFBConfig->id; + buf[p++] = GLX_BUFFER_SIZE; + buf[p++] = pFBConfig->indexBits; + buf[p++] = GLX_LEVEL; + buf[p++] = pFBConfig->level; + buf[p++] = GLX_DOUBLEBUFFER; + buf[p++] = pFBConfig->doubleBufferMode; + buf[p++] = GLX_STEREO; + buf[p++] = pFBConfig->stereoMode; + buf[p++] = GLX_AUX_BUFFERS; + buf[p++] = pFBConfig->maxAuxBuffers; + buf[p++] = GLX_RED_SIZE; + buf[p++] = pFBConfig->redBits; + buf[p++] = GLX_GREEN_SIZE; + buf[p++] = pFBConfig->greenBits; + buf[p++] = GLX_BLUE_SIZE; + buf[p++] = pFBConfig->blueBits; + buf[p++] = GLX_ALPHA_SIZE; + buf[p++] = pFBConfig->alphaBits; + buf[p++] = GLX_DEPTH_SIZE; + buf[p++] = pFBConfig->depthBits; + buf[p++] = GLX_STENCIL_SIZE; + buf[p++] = pFBConfig->stencilBits; + buf[p++] = GLX_ACCUM_RED_SIZE; + buf[p++] = pFBConfig->accumRedBits; + buf[p++] = GLX_ACCUM_GREEN_SIZE; + buf[p++] = pFBConfig->accumGreenBits; + buf[p++] = GLX_ACCUM_BLUE_SIZE; + buf[p++] = pFBConfig->accumBlueBits; + buf[p++] = GLX_ACCUM_ALPHA_SIZE; + buf[p++] = pFBConfig->accumAlphaBits; + buf[p++] = GLX_RENDER_TYPE; + buf[p++] = pFBConfig->renderType; + buf[p++] = GLX_DRAWABLE_TYPE; + drawableTypeIndex = p; + buf[p++] = pFBConfig->drawableType; + buf[p++] = GLX_X_VISUAL_TYPE; + buf[p++] = pFBConfig->visualType; + buf[p++] = GLX_CONFIG_CAVEAT; + buf[p++] = pFBConfig->visualCaveat; + buf[p++] = GLX_TRANSPARENT_TYPE; + buf[p++] = pFBConfig->transparentType; + buf[p++] = GLX_TRANSPARENT_RED_VALUE; + buf[p++] = pFBConfig->transparentRed; + buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; + buf[p++] = pFBConfig->transparentGreen; + buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; + buf[p++] = pFBConfig->transparentBlue; + buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; + buf[p++] = pFBConfig->transparentAlpha; + buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; + buf[p++] = pFBConfig->transparentIndex; + buf[p++] = GLX_MAX_PBUFFER_WIDTH; + buf[p++] = pFBConfig->maxPbufferWidth; + buf[p++] = GLX_MAX_PBUFFER_HEIGHT; + buf[p++] = pFBConfig->maxPbufferHeight; + buf[p++] = GLX_MAX_PBUFFER_PIXELS; + buf[p++] = pFBConfig->maxPbufferPixels; + + /* + * find the visual of the back-end server and match a visual + * on the proxy. + * do only once - if a visual is not yet associated. + */ + if (pFBConfig->associatedVisualId == (unsigned int)-1) { + DMXScreenInfo *dmxScreen = &dmxScreens[screen]; + __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ]; + __GLXvisualConfig *pGlxVisual = NULL; + int v; + int found = 0; + for (v=0; v<dmxScreen->numGlxVisuals; v++) { + if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) { + pGlxVisual = &dmxScreen->glxVisuals[v]; + break; + } + } + + if (pGlxVisual) { + for (v=0; v<pGlxScreen->numVisuals; v++) { + if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) { + associatedVisualId = pGlxScreen->pGlxVisual[v].vid; + found = 1; + break; + } + } + } + + if (!found) { + associatedVisualId = 0; + pFBConfig->drawableType &= ~(GLX_WINDOW_BIT); + buf[drawableTypeIndex] = pFBConfig->drawableType; + } +#ifdef PANORAMIX + else if (!noPanoramiXExtension) { + /* convert the associated visualId to the panoramix one */ + pFBConfig->associatedVisualId = + PanoramiXTranslateVisualID(screen, v); + } +#endif + } + else { + associatedVisualId = pFBConfig->associatedVisualId; + } + + buf[p++] = GLX_VISUAL_ID; + buf[p++] = associatedVisualId; + + /* SGIS_multisample attributes */ + buf[p++] = GLX_SAMPLES_SGIS; + buf[p++] = pFBConfig->multiSampleSize; + buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; + buf[p++] = pFBConfig->nMultiSampleBuffers; + + /* SGIX_pbuffer specific attributes */ + buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX; + buf[p++] = pFBConfig->optimalPbufferWidth; + buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX; + buf[p++] = pFBConfig->optimalPbufferHeight; + + buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; + buf[p++] = pFBConfig->visualSelectGroup; + + if (client->swapped) { + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs); + } + WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf); + } + return Success; +} + +int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc; + xGLXGetFBConfigsReq new_req; + + new_req.reqType = req->reqType; + new_req.glxCode = req->glxCode; + new_req.length = req->length; + new_req.screen = req->screen; + + return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) ); +} + + +int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; + int screen = req->screen; + GLXFBConfigID fbconfigId = req->fbconfig; + XID windowId = req->window; + XID glxwindowId = req->glxwindow; + DrawablePtr pDraw; + ScreenPtr pScreen; + __glXWindow *pGlxWindow; + __GLXFBConfig *pGlxFBConfig = NULL; + VisualPtr pVisual; + VisualID visId; + int i, rc; + pointer val; + + /* + ** Check if windowId is valid + */ + rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW, + DixAddAccess); + if (rc != Success) + return rc; + + /* + ** Check if screen of window matches screen of fbconfig. + */ + pScreen = pDraw->pScreen; + if (screen != pScreen->myNum) { + return BadMatch; + } + + /* + ** Find the FBConfigRec for this fbconfigid. + */ + if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { + client->errorValue = fbconfigId; + return __glXBadFBConfig; + } + visId = pGlxFBConfig->associatedVisualId; + + /* + ** Check if the fbconfig supports rendering to windows + */ + if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) { + return BadMatch; + } + + if (visId != None) { + /* + ** Check if the visual ID is valid for this screen. + */ + pVisual = pScreen->visuals; + for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { + if (pVisual->vid == visId) { + break; + } + } + if (i == pScreen->numVisuals) { + client->errorValue = visId; + return BadValue; + } + + /* + ** Check if color buffer depth of fbconfig matches depth + ** of window. + */ + if (pVisual->nplanes != pDraw->depth) { + return BadMatch; + } + } else + /* + ** The window was created with no visual that corresponds + ** to fbconfig + */ + return BadMatch; + + /* + ** Check if there is already a fbconfig associated with this window + */ + if (Success == dixLookupResourceByType(&val, + glxwindowId, __glXWindowRes, + NullClient, DixUnknownAccess)) { + client->errorValue = glxwindowId; + return BadAlloc; + } + + pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow)); + if (!pGlxWindow) { + return BadAlloc; + } + + /* + ** Register this GLX window as a resource + */ + if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) { + return BadAlloc; + } + + pGlxWindow->pDraw = pDraw; + pGlxWindow->type = GLX_GLXWINDOW_TYPE; + pGlxWindow->idExists = True; + pGlxWindow->refcnt = 0; + pGlxWindow->pGlxFBConfig = pGlxFBConfig; + pGlxWindow->pScreen = pScreen; + + return Success; +} + +int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; + XID glxwindow = req->glxwindow; + pointer val; + + /* + ** Check if it's a valid GLX window. + */ + if (Success != dixLookupResourceByType(&val, + glxwindow, __glXWindowRes, + NullClient, DixUnknownAccess)) { + client->errorValue = glxwindow; + return __glXBadDrawable; + } + /* + ** The glx window destructor will check whether it's current before + ** freeing anything. + */ + FreeResource(glxwindow, RT_NONE); + + return Success; +} + +int __glXQueryContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + __GLXcontext *ctx; + xGLXQueryContextReq *req; + xGLXQueryContextReply reply; + int nProps; + int *sendBuf, *pSendBuf; + int nReplyBytes; + + req = (xGLXQueryContextReq *)pc; + dixLookupResourceByType((pointer*) &ctx, req->context, __glXContextRes, + NullClient, DixUnknownAccess); + if (!ctx) { + client->errorValue = req->context; + return __glXBadContext; + } + + nProps = 3; + + reply.length = nProps << 1; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.n = nProps; + + nReplyBytes = reply.length << 2; + sendBuf = (int *)malloc(nReplyBytes); + pSendBuf = sendBuf; + *pSendBuf++ = GLX_FBCONFIG_ID; + *pSendBuf++ = (int)(ctx->pFBConfig->id); + *pSendBuf++ = GLX_RENDER_TYPE; + *pSendBuf++ = (int)(ctx->pFBConfig->renderType); + *pSendBuf++ = GLX_SCREEN; + *pSendBuf++ = (int)(ctx->pScreen->myNum); + + if (client->swapped) { + __glXSwapQueryContextReply(client, &reply, sendBuf); + } else { + WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply); + WriteToClient(client, nReplyBytes, (char *)sendBuf); + } + free((char *)sendBuf); + + return Success; +} + +int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + __GLXcontext *ctx; + xGLXQueryContextInfoEXTReq *req; + xGLXQueryContextInfoEXTReply reply; + int nProps; + int *sendBuf, *pSendBuf; + int nReplyBytes; + + req = (xGLXQueryContextInfoEXTReq *)pc; + dixLookupResourceByType((pointer*) &ctx, + req->context, __glXContextRes, + client, DixReadAccess); + + if (!ctx) { + client->errorValue = req->context; + return __glXBadContext; + } + + nProps = 4; + + reply.length = nProps << 1; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.n = nProps; + + nReplyBytes = reply.length << 2; + sendBuf = (int *)malloc(nReplyBytes); + pSendBuf = sendBuf; + *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; + *pSendBuf++ = (int)(ctx->share_id); + *pSendBuf++ = GLX_VISUAL_ID_EXT; + *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0); + *pSendBuf++ = GLX_SCREEN_EXT; + *pSendBuf++ = (int)(ctx->pScreen->myNum); + *pSendBuf++ = GLX_FBCONFIG_ID; + *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0); + + if (client->swapped) { + __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); + } else { + WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); + WriteToClient(client, nReplyBytes, (char *)sendBuf); + } + free((char *)sendBuf); + + return Success; +} + +int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc; + xGLXCreatePbufferReq *be_req; + int screen = req->screen; + GLXFBConfigID fbconfigId = req->fbconfig; + GLXPbuffer pbuffer = req->pbuffer; + __glXPbuffer *pGlxPbuffer; + int numAttribs = req->numAttribs; + int *attr; + ScreenPtr pScreen; + __GLXFBConfig *pGlxFBConfig; + __GLXFBConfig *be_pGlxFBConfig; + XID be_xid; + Display *dpy; + DMXScreenInfo *dmxScreen; + int s; + int from_screen, to_screen; + + /* + ** Look up screen and FBConfig. + */ + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + pScreen = screenInfo.screens[screen]; + + /* + ** Find the FBConfigRec for this fbconfigid. + */ + if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { + client->errorValue = fbconfigId; + return __glXBadFBConfig; + } + + /* + ** Create the GLX part of the Pbuffer. + */ + pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer)); + if (!pGlxPbuffer) { + return BadAlloc; + } + + pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens ); + if (!pGlxPbuffer->be_xids) { + free(pGlxPbuffer); + return BadAlloc; + } + + /* + * Allocate an XID on the back-end server(s) and send him the request + */ + from_screen = to_screen = screen; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + dpy = GetBackEndDisplay(cl,s); + be_xid = XAllocID(dpy); + dmxScreen = &dmxScreens[s]; + be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s ); + + attr = (int *)( req+1 ); + + LockDisplay(dpy); + GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXCreatePbuffer; + be_req->screen = be_pGlxFBConfig->screen; + be_req->fbconfig = be_pGlxFBConfig->id; + be_req->pbuffer = be_xid; + be_req->numAttribs = numAttribs; + + /* Send attributes */ + if ( attr != NULL ) { + CARD32 *pc = (CARD32 *)(be_req + 1); + + while (numAttribs-- > 0) { + *pc++ = *attr++; /* token */ + *pc++ = *attr++; /* value */ + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + pGlxPbuffer->be_xids[s] = be_xid; + } + + + pGlxPbuffer->idExists = True; + pGlxPbuffer->refcnt = 0; + pGlxPbuffer->pFBConfig = pGlxFBConfig; + pGlxPbuffer->pScreen = pScreen; + + /* + ** Register the resource. + */ + if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) { + return BadAlloc; + } + + return Success; + +} + +int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; + xGLXDestroyPbufferReq *be_req; + GLXPbuffer pbuffer = req->pbuffer; + Display *dpy; + int screen; + DMXScreenInfo *dmxScreen; + __glXPbuffer *pGlxPbuffer; + int s; + int from_screen, to_screen; + + /* + ** Check if it's a valid Pbuffer + */ + dixLookupResourceByType((pointer*) &pGlxPbuffer, pbuffer, + __glXPbufferRes, NullClient, DixUnknownAccess); + if (!pGlxPbuffer) { + client->errorValue = pbuffer; + return __glXBadPbuffer; + } + + screen = pGlxPbuffer->pScreen->myNum; + + from_screen = to_screen = screen; +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + for (s=from_screen; s<=to_screen; s++) { + dpy = GetBackEndDisplay(cl,s); + dmxScreen = &dmxScreens[s]; + + /* send the destroy request to the back-end server */ + LockDisplay(dpy); + GetReq(GLXDestroyPbuffer, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXDestroyPbuffer; + be_req->pbuffer = pGlxPbuffer->be_xids[s]; + UnlockDisplay(dpy); + SyncHandle(); + } + + FreeResource(pbuffer, RT_NONE); + + return Success; +} + +int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; + xGLXGetDrawableAttributesReq *be_req; + xGLXGetDrawableAttributesReply reply; + ClientPtr client = cl->client; + GLXDrawable drawId = req->drawable; + GLXDrawable be_drawable = 0; + DrawablePtr pDraw = NULL; + Display *dpy; + int screen, rc; + DMXScreenInfo *dmxScreen; + CARD32 *attribs = NULL; + int attribs_size = 0; +#ifdef PANORAMIX + PanoramiXRes *pXinDraw = NULL; +#endif + + if (drawId != None) { + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); + if (rc == Success && pDraw->type == DRAWABLE_WINDOW) { + WindowPtr pWin = (WindowPtr)pDraw; + be_drawable = 0; + screen = pWin->drawable.pScreen->myNum; + } else { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (!pDraw) { + __GLXpixmap *pGlxPixmap; + dixLookupResourceByType((pointer*) &pGlxPixmap, + drawId, __glXPixmapRes, + NullClient, DixUnknownAccess); + if (pGlxPixmap) { + pDraw = pGlxPixmap->pDraw; + screen = pGlxPixmap->pScreen->myNum; + be_drawable = pGlxPixmap->be_xids[screen]; + } + } + + if (!pDraw) { + __glXWindow *pGlxWindow; + dixLookupResourceByType((pointer*) &pGlxWindow, + drawId, __glXWindowRes, + NullClient, DixUnknownAccess); + if (pGlxWindow) { + pDraw = pGlxWindow->pDraw; + screen = pGlxWindow->pScreen->myNum; + be_drawable = 0; + } + } + + if (!pDraw) { + __glXPbuffer *pGlxPbuffer; + dixLookupResourceByType((pointer*) &pGlxPbuffer, + drawId, __glXPbufferRes, + NullClient, DixUnknownAccess); + if (pGlxPbuffer) { + pDraw = (DrawablePtr)pGlxPbuffer; + screen = pGlxPbuffer->pScreen->myNum; + be_drawable = pGlxPbuffer->be_xids[screen]; + } + } + } + + if (!pDraw) { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + /* if the drawable is a window or GLXWindow - + * we need to find the base id on the back-end server + */ + if (!be_drawable) { + WindowPtr pWin = (WindowPtr)pDraw; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess)) { + client->errorValue = drawId; + return __glXBadDrawable; + } + + dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, + DixReadAccess); + } +#endif + + if (pWin) { + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_drawable) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + else { + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + + /* send the request to the back-end server */ + dpy = GetBackEndDisplay(cl,screen); + dmxScreen = &dmxScreens[screen]; + + /* make sure drawable exists on back-end */ + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReq(GLXGetDrawableAttributes, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXGetDrawableAttributes; + be_req->drawable = be_drawable; + be_req->length = req->length; + if (!_XReply(dpy, (xReply *) &reply, 0, False)) { + UnlockDisplay(dpy); + SyncHandle(); + return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); + } + + if (reply.numAttribs) { + attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32; + attribs = (CARD32 *) malloc(attribs_size); + if (attribs == NULL) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + + _XRead(dpy, (char *) attribs, attribs_size); + } + + UnlockDisplay(dpy); + SyncHandle(); + + + /* send the reply back to the client */ + reply.sequenceNumber = client->sequence; + if (client->swapped) { + __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs); + } + else { + WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply); + WriteToClient(client, attribs_size, (char *)attribs); + } + + free(attribs); + + return Success; +} + +int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc; + xGLXChangeDrawableAttributesReq *be_req; + ClientPtr client = cl->client; + GLXDrawable drawId = req->drawable; + GLXDrawable be_drawable = 0; + DrawablePtr pDraw = NULL; + Display *dpy; + int screen, rc; + DMXScreenInfo *dmxScreen; + + if (drawId != None) { + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess); + if (rc == Success && pDraw->type == DRAWABLE_WINDOW) { + be_drawable = 0; + screen = pDraw->pScreen->myNum; + } else { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + if (!pDraw) { + __GLXpixmap *pGlxPixmap; + dixLookupResourceByType((pointer*) &pGlxPixmap, + drawId, __glXPixmapRes, + NullClient, DixUnknownAccess); + if (pGlxPixmap) { + pDraw = pGlxPixmap->pDraw; + screen = pGlxPixmap->pScreen->myNum; + be_drawable = pGlxPixmap->be_xids[screen]; + } + } + + if (!pDraw) { + __glXWindow *pGlxWindow; + dixLookupResourceByType((pointer*) &pGlxWindow, + drawId, __glXWindowRes, + NullClient, DixUnknownAccess); + if (pGlxWindow) { + pDraw = pGlxWindow->pDraw; + screen = pGlxWindow->pScreen->myNum; + be_drawable = 0; + } + } + + if (!pDraw) { + __glXPbuffer *pGlxPbuffer; + dixLookupResourceByType((pointer*) &pGlxPbuffer, + drawId, __glXPbufferRes, + NullClient, DixUnknownAccess); + if (pGlxPbuffer) { + pDraw = (DrawablePtr)pGlxPbuffer; + screen = pGlxPbuffer->pScreen->myNum; + be_drawable = pGlxPbuffer->be_xids[screen]; + } + } + } + + if (!pDraw) { + /* + ** Drawable is not a Window , GLXWindow or a GLXPixmap. + */ + client->errorValue = drawId; + return __glXBadDrawable; + } + + /* if the drawable is a window or GLXWindow - + * we need to find the base id on the back-end server + */ + if (!be_drawable) { + WindowPtr pWin = (WindowPtr)pDraw; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + PanoramiXRes *pXinDraw; + if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, + pDraw->id, XRC_DRAWABLE, + client, DixReadAccess)) { + client->errorValue = drawId; + return __glXBadDrawable; + } + + dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, + DixReadAccess); + } +#endif + + if (pWin) { + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + if (!be_drawable) { + /* it might be that the window did not created yet on the */ + /* back-end server (lazy window creation option), force */ + /* creation of the window */ + dmxCreateAndRealizeWindow( pWin, TRUE ); + be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; + } + } + else { + client->errorValue = drawId; + return __glXBadDrawable; + } + } + + + /* send the request to the back-end server */ + dpy = GetBackEndDisplay(cl,screen); + dmxScreen = &dmxScreens[screen]; + + /* make sure drawable exists on back-end */ + dmxSync( dmxScreen, 1 ); + + LockDisplay(dpy); + GetReqExtra(GLXChangeDrawableAttributes, + 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLXChangeDrawableAttributes; + be_req->drawable = be_drawable; + be_req->numAttribs = req->numAttribs; + be_req->length = req->length; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag) +{ + ClientPtr client = cl->client; + xGLXRenderLargeReq *req; + GLint maxSize, amount; + GLint totalRequests, requestNumber; + GLint dataLen; + GLbyte *data; + __GLXcontext *glxc; + int s; + int from_screen, to_screen; + + maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq); + dataLen = cl->largeCmdBytesTotal; + totalRequests = (dataLen / maxSize); + if (dataLen % maxSize) totalRequests++; + + glxc = __glXLookupContextByTag(cl, contextTag); + if (!glxc) { + client->errorValue = contextTag; + return __glXBadContext; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + /* + ** Send enough requests until the whole array is sent. + */ + requestNumber = 1; + data = cl->largeCmdBuf; + while (dataLen > 0) { + amount = dataLen; + if (amount > maxSize) { + amount = maxSize; + } + + for (s=from_screen; s<=to_screen; s++) { + + Display *dpy = GetBackEndDisplay(cl,s); + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + + LockDisplay(dpy); + GetReq(GLXRenderLarge,req); + req->reqType = dmxScreen->glxMajorOpcode; + req->glxCode = X_GLXRenderLarge; + req->contextTag = GetCurrentBackEndTag(cl,contextTag,s); + req->length += (amount + 3) >> 2; + req->requestNumber = requestNumber++; + req->requestTotal = totalRequests; + req->dataBytes = amount; + Data(dpy, ((const char*)data), amount); + dataLen -= amount; + data = ((GLbyte *) data) + amount; + UnlockDisplay(dpy); + SyncHandle(); + } + } + + return Success; +} diff --git a/xorg-server/hw/dmx/glxProxy/glxsingle.c b/xorg-server/hw/dmx/glxProxy/glxsingle.c index 834c7b8d9..33cc612a7 100644 --- a/xorg-server/hw/dmx/glxProxy/glxsingle.c +++ b/xorg-server/hw/dmx/glxProxy/glxsingle.c @@ -1,1016 +1,1016 @@ -/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-#include "dmxcb.h"
-
-#include "glxserver.h"
-#include "glxext.h"
-#include "g_disptab.h"
-/* #include "g_disptab_EXT.h" */
-#include "unpack.h"
-#include "glxutil.h"
-
-#include "GL/glxproto.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-/*
- * GetReqSingle - this is the equivalent of GetReq macro
- * from Xlibint.h but it does not set the reqType field (the opcode).
- * this is because the GL single opcodes has different naming convension
- * the other X opcodes (ie. X_GLsop_GetFloatv).
- */
-#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
-#define GetReqSingle(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x##name##Req))>>2;\
- dpy->bufptr += SIZEOF(x##name##Req);\
- dpy->request++
-
-#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
-#define GetReqSingle(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x/**/name/**/Req))>>2;\
- dpy->bufptr += SIZEOF(x/**/name/**/Req);\
- dpy->request++
-#endif
-
-#define X_GLXSingle 0 /* needed by GetReqExtra */
-
-extern Display *GetBackEndDisplay( __GLXclientState *cl, int s );
-extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s);
-
-static int swap_vec_element_size = 0;
-
-static void SendSwappedReply( ClientPtr client,
- xGLXSingleReply *reply,
- char *buf,
- int buf_size )
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->retval);
- __GLX_SWAP_INT(&reply->size);
-
- if ( (buf_size == 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has single component - need to swap pad3
- */
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(&reply->pad3);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4
- * i.e GetConvolutionFilter
- */
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(&reply->pad3);
- }
- }
- else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has vector of elements which needs to be swapped
- */
- int vsize = buf_size / swap_vec_element_size;
- char *p = buf;
- int i;
-
- for (i=0; i<vsize; i++) {
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(p);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(p);
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(p);
- }
-
- p += swap_vec_element_size;
- }
-
- /*
- * swap pad words as well - for case that some single reply uses
- * them as well
- */
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4);
- __GLX_SWAP_INT(&reply->pad5);
- __GLX_SWAP_INT(&reply->pad6);
-
- }
-
- WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply);
- if (buf_size > 0)
- WriteToClient(client, buf_size, (char *)buf);
-
-}
-
-int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int buf_size;
- int s;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXSingleReq;
- buf_size = (req->length << 2) - sz_xGLXSingleReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqSingle(GLXSingle,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (req->glxCode == X_GLsop_Flush) {
- XFlush(dpy);
- }
-
- }
-
- return Success;
-}
-
-int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- xGLXSingleReply reply;
- xGLXSingleReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf = NULL;
- int be_buf_size;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return __glXBadContext;
- }
-
- pc += sz_xGLXSingleReq;
- buf_size = (req->length << 2) - sz_xGLXSingleReq;
-
- dmxScreen = &dmxScreens[glxc->pScreen->myNum];
- dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum);
-
- /*
- * send the request to the first back-end server
- */
- LockDisplay(dpy);
- GetReqSingle(GLXSingle,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)malloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- /*
- * send the reply to the client
- */
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = be_reply.length;
- reply.retval = be_reply.retval;
- reply.size = be_reply.size;
- reply.pad3 = be_reply.pad3;
- reply.pad4 = be_reply.pad4;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) free(be_buf);
-
- return Success;
-}
-
-int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- xGLXSingleReply reply;
- xGLXSingleReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf = NULL;
- int be_buf_size = 0;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXSingleReq;
- buf_size = (req->length << 2) - sz_xGLXSingleReq;
-
- /*
- * send the request to the first back-end server(s)
- */
- for (s=to_screen; s>=from_screen; s--) {
- dmxScreen = &dmxScreens[s];
- dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqSingle(GLXSingle,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)malloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (s > from_screen && be_buf_size > 0) {
- free(be_buf);
- }
- }
-
- /*
- * send the reply to the client
- */
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = be_reply.length;
- reply.retval = be_reply.retval;
- reply.size = be_reply.size;
- reply.pad3 = be_reply.pad3;
- reply.pad4 = be_reply.pad4;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) free(be_buf);
-
- return Success;
-}
-
-int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXForwardSingleReq( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h,
- int *elementbits_return, int *rowbytes_return )
-{
- GLint elements, esize;
- GLint rowsize, padding;
-
- if (w < 0 || h < 0) {
- return -1;
- }
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_STENCIL_INDEX:
- case GL_DEPTH_COMPONENT:
- elements = 1;
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- elements = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- elements = 2;
- break;
- case GL_RGB:
- case GL_BGR:
- elements = 3;
- break;
- case GL_RGBA:
- case GL_BGRA:
- case GL_ABGR_EXT:
- elements = 4;
- break;
- default:
- return -1;
- }
- /*
- ** According to the GLX protocol, each row must be padded to a multiple of
- ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel
- ** store modes of the GL.
- */
- switch (type) {
- case GL_BITMAP:
- if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
- rowsize = ((w * elements)+7)/8;
- padding = rowsize % 4;
- if (padding) {
- rowsize += 4 - padding;
- }
- if (elementbits_return) *elementbits_return = elements;
- if (rowbytes_return) *rowbytes_return = rowsize;
- return rowsize * h;
- } else {
- return -1;
- }
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- esize = 1;
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- esize = 1;
- elements = 1;
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- esize = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- esize = 2;
- elements = 1;
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- esize = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- esize = 4;
- elements = 1;
- break;
- default:
- return -1;
- }
- rowsize = w * elements * esize;
- padding = rowsize % 4;
- if (padding) {
- rowsize += 4 - padding;
- }
-
- if (elementbits_return) *elementbits_return = esize*elements*8;
- if (rowbytes_return) *rowbytes_return = rowsize;
-
- return rowsize * h;
-}
-
-static int intersectRect( int x1, int x2, int y1, int y2,
- int X1, int X2, int Y1, int Y2,
- int *ix1, int *ix2, int *iy1, int *iy2 )
-{
- int right = (x2 < X2 ? x2 : X2);
- int bottom = (y2 < Y2 ? y2 : Y2);
- int left = (x1 > X1 ? x1 : X1);
- int top = (y1 > Y1 ? y1 : Y1);
- int width = right - left + 1;
- int height = bottom - top + 1;
-
- if ( (width <= 0) || (height <= 0) ) {
- *ix1 = *ix2 = *iy1 = *iy2 = 0;
- return 0;
- }
- else {
- *ix1 = left;
- *ix2 = right;
- *iy1 = top;
- *iy2 = bottom;
- return width * height;
- }
-
-}
-
-int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- xGLXReadPixelsReply reply;
- xGLXReadPixelsReply be_reply;
- GLbyte *be_pc;
- GLint x,y;
- GLsizei width, height;
- GLenum format, type;
- GLboolean swapBytes, lsbFirst;
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- char *buf;
- int buf_size;
- int s;
- int win_x1, win_x2;
- int win_y1, win_y2;
- int ebits, rowsize;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- if (client->swapped) {
- __GLX_SWAP_INT(&req->contextTag);
- }
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXSingleReq;
- x = *(GLint *)(pc + 0);
- y = *(GLint *)(pc + 4);
- width = *(GLsizei *)(pc + 8);
- height = *(GLsizei *)(pc + 12);
- format = *(GLenum *)(pc + 16);
- type = *(GLenum *)(pc + 20);
- swapBytes = *(GLboolean *)(pc + 24);
- lsbFirst = *(GLboolean *)(pc + 25);
-
- if (client->swapped) {
- __GLX_SWAP_INT(&x);
- __GLX_SWAP_INT(&y);
- __GLX_SWAP_INT(&width);
- __GLX_SWAP_INT(&height);
- __GLX_SWAP_INT(&format);
- __GLX_SWAP_INT(&type);
- swapBytes = !swapBytes;
- }
-
- buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize);
- if (buf_size > 0) {
- buf = (char *) malloc( buf_size );
- if ( !buf ) {
- return BadAlloc;
- }
- }
- else {
- buf_size = 0;
- buf = NULL;
- }
-
- if (buf_size > 0) {
- /*
- * Get the current drawable this context is bound to
- */
- pDraw = __glXLookupDrawableByTag( cl, req->contextTag );
- win_x1 = pDraw->x + x;
- win_x2 = win_x1 + width - 1;
- win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y;
- win_y2 = win_y1 + height - 1;
- if (pDraw->type != DRAWABLE_WINDOW) {
- from_screen = to_screen = 0;
- }
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- int scr_x1 = dmxScreen->rootXOrigin;
- int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1;
- int scr_y1 = dmxScreen->rootYOrigin;
- int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1;
- int wx1, wx2, wy1, wy2;
- int sx, sy, sw, sh;
- int npixels;
-
- /*
- * find the window portion that is on the current screen
- */
- if (pDraw->type == DRAWABLE_WINDOW) {
- npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2,
- win_x1, win_x2, win_y1, win_y2,
- &wx1, &wx2, &wy1, &wy2 );
- }
- else {
- wx1 = win_x1;
- wx2 = win_x2;
- wy1 = win_y1;
- wy2 = win_y2;
- npixels = (wx2-wx1+1) * (wy2-wy1+1);
- }
-
- if (npixels > 0) {
-
- /* send the request to the back-end server */
- LockDisplay(dpy);
- GetReqExtra(GLXSingle,__GLX_PAD(26),be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLsop_ReadPixels;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq);
-
- sx = wx1 - pDraw->x;
- sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height);
- sw = (wx2-wx1+1);
- sh = (wy2-wy1+1);
-
- *(GLint *)(be_pc + 0) = sx; /* x */
- *(GLint *)(be_pc + 4) = sy; /* y */
- *(GLsizei *)(be_pc + 8) = sw; /* width */
- *(GLsizei *)(be_pc + 12) = sh; /* height */
- *(GLenum *)(be_pc + 16) = format;
- *(GLenum *)(be_pc + 20) = type;
- *(GLboolean *)(be_pc + 24) = swapBytes;
- *(GLboolean *)(be_pc + 25) = lsbFirst;
-
- _XReply(dpy, (xReply*) &be_reply, 0, False);
-
- if (be_reply.length > 0) {
- char *be_buf;
- int be_buf_size = be_reply.length << 2;
-
- be_buf = (char *) malloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
-
- /* copy pixels data to the right location of the */
- /* reply buffer */
- if ( type != GL_BITMAP ) {
- int pbytes = ebits / 8;
- char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes;
- char *src = be_buf;
- int pad = (pbytes * sw) % 4;
- int r;
-
- for (r=0; r<sh; r++) {
- memcpy( dst, src, pbytes*sw );
- dst += rowsize;
- src += (pbytes*sw + (pad ? 4-pad : 0) );
- }
- }
- else {
- /* this is a GL_BITMAP pixel type, should copy bits */
- int r;
- int src_rowsize = bits_to_bytes(sw * ebits);
- int src_pad = src_rowsize % 4;
- if ( src_pad ) {
- src_rowsize += (4 - src_pad);
- }
-
- for (r=0; r<sh; r++) {
- unsigned char dst_mask = 0x80 >> (sx % 8);
- unsigned char src_mask = 0x80;
- char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8;
- char *src = be_buf + r*src_rowsize;
- int b;
-
- for (b=0; b<sw*ebits; b++) {
- if ( *src & src_mask ) {
- *dst |= dst_mask;
- }
- else {
- *dst &= ~dst_mask;
- }
-
- if (dst_mask > 1) dst_mask >>= 1;
- else {
- dst_mask = 0x80;
- dst++;
- }
-
- if (src_mask > 1) src_mask >>= 1;
- else {
- src_mask = 0x80;
- src++;
- }
- }
- }
-
- }
-
- free( be_buf );
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- free( buf );
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- } /* of npixels > 0 */
-
- } /* of for loop */
-
- } /* of if buf_size > 0 */
-
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = buf_size >> 2;
-
- if (client->swapped) {
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- }
-
- WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply);
- if (buf_size > 0) {
- WriteToClient(client, buf_size, (char *)buf);
- free( buf );
- }
-
- return Success;
-}
-
-int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- GLbyte *lpc = pc;
-
- lpc += sz_xGLXSingleReq;
- __GLX_SWAP_INT(lpc+0);
- __GLX_SWAP_INT(lpc+4);
- __GLX_SWAP_INT(lpc+8);
- __GLX_SWAP_INT(lpc+12);
-
- /* reverse swapBytes */
- *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16);
-
- return( __glXForwardPipe0WithReplySwap( cl, pc ) );
-}
-
-int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- GLbyte *lpc = pc;
-
- lpc += sz_xGLXSingleReq;
- __GLX_SWAP_INT(lpc+0);
- __GLX_SWAP_INT(lpc+4);
- __GLX_SWAP_INT(lpc+8);
-
- /* reverse swapBytes */
- *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12);
-
- return( __glXForwardPipe0WithReplySwap( cl, pc ) );
-}
-
-
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" +#include "dmxfont.h" +#include "dmxcb.h" + +#include "glxserver.h" +#include "glxext.h" +#include "g_disptab.h" +/* #include "g_disptab_EXT.h" */ +#include "unpack.h" +#include "glxutil.h" + +#include "GL/glxproto.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +/* + * GetReqSingle - this is the equivalent of GetReq macro + * from Xlibint.h but it does not set the reqType field (the opcode). + * this is because the GL single opcodes has different naming convension + * the other X opcodes (ie. X_GLsop_GetFloatv). + */ +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define GetReqSingle(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x##name##Req))>>2;\ + dpy->bufptr += SIZEOF(x##name##Req);\ + dpy->request++ + +#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ +#define GetReqSingle(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x/**/name/**/Req))>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req);\ + dpy->request++ +#endif + +#define X_GLXSingle 0 /* needed by GetReqExtra */ + +extern Display *GetBackEndDisplay( __GLXclientState *cl, int s ); +extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s); + +static int swap_vec_element_size = 0; + +static void SendSwappedReply( ClientPtr client, + xGLXSingleReply *reply, + char *buf, + int buf_size ) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->retval); + __GLX_SWAP_INT(&reply->size); + + if ( (buf_size == 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has single component - need to swap pad3 + */ + if (swap_vec_element_size == 2) { + __GLX_SWAP_SHORT(&reply->pad3); + } + else if (swap_vec_element_size == 4) { + __GLX_SWAP_INT(&reply->pad3); + __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4 + * i.e GetConvolutionFilter + */ + } + else if (swap_vec_element_size == 8) { + __GLX_SWAP_DOUBLE(&reply->pad3); + } + } + else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has vector of elements which needs to be swapped + */ + int vsize = buf_size / swap_vec_element_size; + char *p = buf; + int i; + + for (i=0; i<vsize; i++) { + if (swap_vec_element_size == 2) { + __GLX_SWAP_SHORT(p); + } + else if (swap_vec_element_size == 4) { + __GLX_SWAP_INT(p); + } + else if (swap_vec_element_size == 8) { + __GLX_SWAP_DOUBLE(p); + } + + p += swap_vec_element_size; + } + + /* + * swap pad words as well - for case that some single reply uses + * them as well + */ + __GLX_SWAP_INT(&reply->pad3); + __GLX_SWAP_INT(&reply->pad4); + __GLX_SWAP_INT(&reply->pad5); + __GLX_SWAP_INT(&reply->pad6); + + } + + WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply); + if (buf_size > 0) + WriteToClient(client, buf_size, (char *)buf); + +} + +int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int buf_size; + int s; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXSingleReq; + buf_size = (req->length << 2) - sz_xGLXSingleReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqSingle(GLXSingle,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + UnlockDisplay(dpy); + SyncHandle(); + + if (req->glxCode == X_GLsop_Flush) { + XFlush(dpy); + } + + } + + return Success; +} + +int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + xGLXSingleReply reply; + xGLXSingleReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size; + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return __glXBadContext; + } + + pc += sz_xGLXSingleReq; + buf_size = (req->length << 2) - sz_xGLXSingleReq; + + dmxScreen = &dmxScreens[glxc->pScreen->myNum]; + dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum); + + /* + * send the request to the first back-end server + */ + LockDisplay(dpy); + GetReqSingle(GLXSingle,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + /* + * send the reply to the client + */ + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = be_reply.length; + reply.retval = be_reply.retval; + reply.size = be_reply.size; + reply.pad3 = be_reply.pad3; + reply.pad4 = be_reply.pad4; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + xGLXSingleReply reply; + xGLXSingleReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size = 0; + int from_screen = 0; + int to_screen = 0; + int s; + + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXSingleReq; + buf_size = (req->length << 2) - sz_xGLXSingleReq; + + /* + * send the request to the first back-end server(s) + */ + for (s=to_screen; s>=from_screen; s--) { + dmxScreen = &dmxScreens[s]; + dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqSingle(GLXSingle,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + if (s > from_screen && be_buf_size > 0) { + free(be_buf); + } + } + + /* + * send the reply to the client + */ + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = be_reply.length; + reply.retval = be_reply.retval; + reply.size = be_reply.size; + reply.pad3 = be_reply.pad3; + reply.pad4 = be_reply.pad4; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXForwardSingleReq( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardPipe0WithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXSingleReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXSingleReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + + return( __glXForwardAllWithReply( cl, pc ) ); +} + +static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h, + int *elementbits_return, int *rowbytes_return ) +{ + GLint elements, esize; + GLint rowsize, padding; + + if (w < 0 || h < 0) { + return -1; + } + switch (format) { + case GL_COLOR_INDEX: + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + elements = 1; + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + elements = 1; + break; + case GL_LUMINANCE_ALPHA: + elements = 2; + break; + case GL_RGB: + case GL_BGR: + elements = 3; + break; + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + elements = 4; + break; + default: + return -1; + } + /* + ** According to the GLX protocol, each row must be padded to a multiple of + ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel + ** store modes of the GL. + */ + switch (type) { + case GL_BITMAP: + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { + rowsize = ((w * elements)+7)/8; + padding = rowsize % 4; + if (padding) { + rowsize += 4 - padding; + } + if (elementbits_return) *elementbits_return = elements; + if (rowbytes_return) *rowbytes_return = rowsize; + return rowsize * h; + } else { + return -1; + } + case GL_BYTE: + case GL_UNSIGNED_BYTE: + esize = 1; + break; + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + esize = 1; + elements = 1; + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + esize = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + esize = 2; + elements = 1; + break; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + esize = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + esize = 4; + elements = 1; + break; + default: + return -1; + } + rowsize = w * elements * esize; + padding = rowsize % 4; + if (padding) { + rowsize += 4 - padding; + } + + if (elementbits_return) *elementbits_return = esize*elements*8; + if (rowbytes_return) *rowbytes_return = rowsize; + + return rowsize * h; +} + +static int intersectRect( int x1, int x2, int y1, int y2, + int X1, int X2, int Y1, int Y2, + int *ix1, int *ix2, int *iy1, int *iy2 ) +{ + int right = (x2 < X2 ? x2 : X2); + int bottom = (y2 < Y2 ? y2 : Y2); + int left = (x1 > X1 ? x1 : X1); + int top = (y1 > Y1 ? y1 : Y1); + int width = right - left + 1; + int height = bottom - top + 1; + + if ( (width <= 0) || (height <= 0) ) { + *ix1 = *ix2 = *iy1 = *iy2 = 0; + return 0; + } + else { + *ix1 = left; + *ix2 = right; + *iy1 = top; + *iy2 = bottom; + return width * height; + } + +} + +int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc) +{ + xGLXSingleReq *req = (xGLXSingleReq *)pc; + xGLXSingleReq *be_req; + xGLXReadPixelsReply reply; + xGLXReadPixelsReply be_reply; + GLbyte *be_pc; + GLint x,y; + GLsizei width, height; + GLenum format, type; + GLboolean swapBytes, lsbFirst; + ClientPtr client = cl->client; + DrawablePtr pDraw; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + char *buf; + int buf_size; + int s; + int win_x1, win_x2; + int win_y1, win_y2; + int ebits, rowsize; + __GLX_DECLARE_SWAP_VARIABLES; + + if (client->swapped) { + __GLX_SWAP_INT(&req->contextTag); + } + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXSingleReq; + x = *(GLint *)(pc + 0); + y = *(GLint *)(pc + 4); + width = *(GLsizei *)(pc + 8); + height = *(GLsizei *)(pc + 12); + format = *(GLenum *)(pc + 16); + type = *(GLenum *)(pc + 20); + swapBytes = *(GLboolean *)(pc + 24); + lsbFirst = *(GLboolean *)(pc + 25); + + if (client->swapped) { + __GLX_SWAP_INT(&x); + __GLX_SWAP_INT(&y); + __GLX_SWAP_INT(&width); + __GLX_SWAP_INT(&height); + __GLX_SWAP_INT(&format); + __GLX_SWAP_INT(&type); + swapBytes = !swapBytes; + } + + buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize); + if (buf_size > 0) { + buf = (char *) malloc( buf_size ); + if ( !buf ) { + return BadAlloc; + } + } + else { + buf_size = 0; + buf = NULL; + } + + if (buf_size > 0) { + /* + * Get the current drawable this context is bound to + */ + pDraw = __glXLookupDrawableByTag( cl, req->contextTag ); + win_x1 = pDraw->x + x; + win_x2 = win_x1 + width - 1; + win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y; + win_y2 = win_y1 + height - 1; + if (pDraw->type != DRAWABLE_WINDOW) { + from_screen = to_screen = 0; + } + + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + int scr_x1 = dmxScreen->rootXOrigin; + int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1; + int scr_y1 = dmxScreen->rootYOrigin; + int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1; + int wx1, wx2, wy1, wy2; + int sx, sy, sw, sh; + int npixels; + + /* + * find the window portion that is on the current screen + */ + if (pDraw->type == DRAWABLE_WINDOW) { + npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2, + win_x1, win_x2, win_y1, win_y2, + &wx1, &wx2, &wy1, &wy2 ); + } + else { + wx1 = win_x1; + wx2 = win_x2; + wy1 = win_y1; + wy2 = win_y2; + npixels = (wx2-wx1+1) * (wy2-wy1+1); + } + + if (npixels > 0) { + + /* send the request to the back-end server */ + LockDisplay(dpy); + GetReqExtra(GLXSingle,__GLX_PAD(26),be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = X_GLsop_ReadPixels; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq); + + sx = wx1 - pDraw->x; + sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height); + sw = (wx2-wx1+1); + sh = (wy2-wy1+1); + + *(GLint *)(be_pc + 0) = sx; /* x */ + *(GLint *)(be_pc + 4) = sy; /* y */ + *(GLsizei *)(be_pc + 8) = sw; /* width */ + *(GLsizei *)(be_pc + 12) = sh; /* height */ + *(GLenum *)(be_pc + 16) = format; + *(GLenum *)(be_pc + 20) = type; + *(GLboolean *)(be_pc + 24) = swapBytes; + *(GLboolean *)(be_pc + 25) = lsbFirst; + + _XReply(dpy, (xReply*) &be_reply, 0, False); + + if (be_reply.length > 0) { + char *be_buf; + int be_buf_size = be_reply.length << 2; + + be_buf = (char *) malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + + /* copy pixels data to the right location of the */ + /* reply buffer */ + if ( type != GL_BITMAP ) { + int pbytes = ebits / 8; + char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes; + char *src = be_buf; + int pad = (pbytes * sw) % 4; + int r; + + for (r=0; r<sh; r++) { + memcpy( dst, src, pbytes*sw ); + dst += rowsize; + src += (pbytes*sw + (pad ? 4-pad : 0) ); + } + } + else { + /* this is a GL_BITMAP pixel type, should copy bits */ + int r; + int src_rowsize = bits_to_bytes(sw * ebits); + int src_pad = src_rowsize % 4; + if ( src_pad ) { + src_rowsize += (4 - src_pad); + } + + for (r=0; r<sh; r++) { + unsigned char dst_mask = 0x80 >> (sx % 8); + unsigned char src_mask = 0x80; + char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8; + char *src = be_buf + r*src_rowsize; + int b; + + for (b=0; b<sw*ebits; b++) { + if ( *src & src_mask ) { + *dst |= dst_mask; + } + else { + *dst &= ~dst_mask; + } + + if (dst_mask > 1) dst_mask >>= 1; + else { + dst_mask = 0x80; + dst++; + } + + if (src_mask > 1) src_mask >>= 1; + else { + src_mask = 0x80; + src++; + } + } + } + + } + + free( be_buf ); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + free( buf ); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + } /* of npixels > 0 */ + + } /* of for loop */ + + } /* of if buf_size > 0 */ + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = buf_size >> 2; + + if (client->swapped) { + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + } + + WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply); + if (buf_size > 0) { + WriteToClient(client, buf_size, (char *)buf); + free( buf ); + } + + return Success; +} + +int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + GLbyte *lpc = pc; + + lpc += sz_xGLXSingleReq; + __GLX_SWAP_INT(lpc+0); + __GLX_SWAP_INT(lpc+4); + __GLX_SWAP_INT(lpc+8); + __GLX_SWAP_INT(lpc+12); + + /* reverse swapBytes */ + *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16); + + return( __glXForwardPipe0WithReplySwap( cl, pc ) ); +} + +int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + GLbyte *lpc = pc; + + lpc += sz_xGLXSingleReq; + __GLX_SWAP_INT(lpc+0); + __GLX_SWAP_INT(lpc+4); + __GLX_SWAP_INT(lpc+8); + + /* reverse swapBytes */ + *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12); + + return( __glXForwardPipe0WithReplySwap( cl, pc ) ); +} + + diff --git a/xorg-server/hw/dmx/glxProxy/glxvendor.c b/xorg-server/hw/dmx/glxProxy/glxvendor.c index 9dbc46daa..0b6ba4134 100644 --- a/xorg-server/hw/dmx/glxProxy/glxvendor.c +++ b/xorg-server/hw/dmx/glxProxy/glxvendor.c @@ -1,585 +1,585 @@ -/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-
-#include "glxserver.h"
-#include "glxext.h"
-#include "g_disptab.h"
-/* #include "g_disptab_EXT.h" */
-#include "unpack.h"
-#include "glxutil.h"
-
-#include "GL/glxproto.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-/*
- * GetReqVendorPrivate - this is the equivalent of GetReq macro
- * from Xlibint.h but it does not set the reqType field (the opcode).
- * this is because the GL single opcodes has different naming convension
- * the other X opcodes (ie. X_GLsop_GetFloatv).
- */
-#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
-#define GetReqVendorPrivate(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x##name##Req))>>2;\
- dpy->bufptr += SIZEOF(x##name##Req);\
- dpy->request++
-
-#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
-#define GetReqVendorPrivate(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x/**/name/**/Req))>>2;\
- dpy->bufptr += SIZEOF(x/**/name/**/Req);\
- dpy->request++
-#endif
-
-extern Display *GetBackEndDisplay( __GLXclientState *cl, int s );
-extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s);
-
-static int swap_vec_element_size = 0;
-
-static void SendSwappedReply( ClientPtr client,
- xGLXVendorPrivReply *reply,
- char *buf,
- int buf_size )
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->retval);
- __GLX_SWAP_INT(&reply->size);
-
- if ( (buf_size == 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has single component - need to swap pad3
- */
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(&reply->pad3);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4);
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(&reply->pad3);
- }
- }
- else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has vector of elements which needs to be swapped
- */
- int vsize = buf_size / swap_vec_element_size;
- char *p = buf;
- int i;
-
- for (i=0; i<vsize; i++) {
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(p);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(p);
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(p);
- }
-
- p += swap_vec_element_size;
- }
-
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4);
- __GLX_SWAP_INT(&reply->pad5);
- __GLX_SWAP_INT(&reply->pad6);
-
- }
-
- WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)reply);
- if (buf_size > 0)
- WriteToClient(client, buf_size, (char *)buf);
-
-}
-
-int __glXVForwardSingleReq( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- xGLXVendorPrivateReq *be_req;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int buf_size;
- int s;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXVendorPrivateReq;
- buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqVendorPrivate(GLXVendorPrivate,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->vendorCode = req->vendorCode;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-int __glXVForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- xGLXVendorPrivateReq *be_req;
- xGLXVendorPrivReply reply;
- xGLXVendorPrivReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf = NULL;
- int be_buf_size;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return __glXBadContext;
- }
-
- pc += sz_xGLXVendorPrivateReq;
- buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
-
- dmxScreen = &dmxScreens[glxc->pScreen->myNum];
- dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum);
-
- /*
- * send the request to the first back-end server
- */
- LockDisplay(dpy);
- GetReqVendorPrivate(GLXVendorPrivate,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->vendorCode = req->vendorCode;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag, glxc->pScreen->myNum);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)malloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- /*
- * send the reply to the client
- */
- memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply );
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) free(be_buf);
-
- return Success;
-}
-
-int __glXVForwardAllWithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- xGLXVendorPrivateReq *be_req;
- xGLXVendorPrivReply reply;
- xGLXVendorPrivReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf = NULL;
- int be_buf_size = 0;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXVendorPrivateReq;
- buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
-
- /*
- * send the request to the first back-end server(s)
- */
- for (s=to_screen; s>=from_screen; s--) {
- dmxScreen = &dmxScreens[s];
- dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqVendorPrivate(GLXVendorPrivate,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->vendorCode = req->vendorCode;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)malloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (s > from_screen && be_buf_size > 0) {
- free(be_buf);
- }
- }
-
- /*
- * send the reply to the client
- */
- memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply );
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) free(be_buf);
-
- return Success;
-}
-
-int __glXVForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- return( __glXVForwardSingleReq( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" +#include "dmxfont.h" + +#include "glxserver.h" +#include "glxext.h" +#include "g_disptab.h" +/* #include "g_disptab_EXT.h" */ +#include "unpack.h" +#include "glxutil.h" + +#include "GL/glxproto.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +/* + * GetReqVendorPrivate - this is the equivalent of GetReq macro + * from Xlibint.h but it does not set the reqType field (the opcode). + * this is because the GL single opcodes has different naming convension + * the other X opcodes (ie. X_GLsop_GetFloatv). + */ +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define GetReqVendorPrivate(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x##name##Req))>>2;\ + dpy->bufptr += SIZEOF(x##name##Req);\ + dpy->request++ + +#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ +#define GetReqVendorPrivate(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->length = (SIZEOF(x/**/name/**/Req))>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req);\ + dpy->request++ +#endif + +extern Display *GetBackEndDisplay( __GLXclientState *cl, int s ); +extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s); + +static int swap_vec_element_size = 0; + +static void SendSwappedReply( ClientPtr client, + xGLXVendorPrivReply *reply, + char *buf, + int buf_size ) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->retval); + __GLX_SWAP_INT(&reply->size); + + if ( (buf_size == 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has single component - need to swap pad3 + */ + if (swap_vec_element_size == 2) { + __GLX_SWAP_SHORT(&reply->pad3); + } + else if (swap_vec_element_size == 4) { + __GLX_SWAP_INT(&reply->pad3); + __GLX_SWAP_INT(&reply->pad4); + } + else if (swap_vec_element_size == 8) { + __GLX_SWAP_DOUBLE(&reply->pad3); + } + } + else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) { + /* + * the reply has vector of elements which needs to be swapped + */ + int vsize = buf_size / swap_vec_element_size; + char *p = buf; + int i; + + for (i=0; i<vsize; i++) { + if (swap_vec_element_size == 2) { + __GLX_SWAP_SHORT(p); + } + else if (swap_vec_element_size == 4) { + __GLX_SWAP_INT(p); + } + else if (swap_vec_element_size == 8) { + __GLX_SWAP_DOUBLE(p); + } + + p += swap_vec_element_size; + } + + __GLX_SWAP_INT(&reply->pad3); + __GLX_SWAP_INT(&reply->pad4); + __GLX_SWAP_INT(&reply->pad5); + __GLX_SWAP_INT(&reply->pad6); + + } + + WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)reply); + if (buf_size > 0) + WriteToClient(client, buf_size, (char *)buf); + +} + +int __glXVForwardSingleReq( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + xGLXVendorPrivateReq *be_req; + __GLXcontext *glxc; + int from_screen = 0; + int to_screen = 0; + int buf_size; + int s; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXVendorPrivateReq; + buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; + + /* + * just forward the request to back-end server(s) + */ + for (s=from_screen; s<=to_screen; s++) { + DMXScreenInfo *dmxScreen = &dmxScreens[s]; + Display *dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqVendorPrivate(GLXVendorPrivate,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->vendorCode = req->vendorCode; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + UnlockDisplay(dpy); + SyncHandle(); + } + + return Success; +} + +int __glXVForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + xGLXVendorPrivateReq *be_req; + xGLXVendorPrivReply reply; + xGLXVendorPrivReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size; + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return __glXBadContext; + } + + pc += sz_xGLXVendorPrivateReq; + buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; + + dmxScreen = &dmxScreens[glxc->pScreen->myNum]; + dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum); + + /* + * send the request to the first back-end server + */ + LockDisplay(dpy); + GetReqVendorPrivate(GLXVendorPrivate,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->vendorCode = req->vendorCode; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag, glxc->pScreen->myNum); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + /* + * send the reply to the client + */ + memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply ); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXVForwardAllWithReply( __GLXclientState *cl, GLbyte *pc ) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + xGLXVendorPrivateReq *be_req; + xGLXVendorPrivReply reply; + xGLXVendorPrivReply be_reply; + __GLXcontext *glxc; + int buf_size; + char *be_buf = NULL; + int be_buf_size = 0; + int from_screen = 0; + int to_screen = 0; + int s; + + DMXScreenInfo *dmxScreen; + Display *dpy; + + glxc = __glXLookupContextByTag(cl, req->contextTag); + if (!glxc) { + return 0; + } + from_screen = to_screen = glxc->pScreen->myNum; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + from_screen = 0; + to_screen = screenInfo.numScreens - 1; + } +#endif + + pc += sz_xGLXVendorPrivateReq; + buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq; + + /* + * send the request to the first back-end server(s) + */ + for (s=to_screen; s>=from_screen; s--) { + dmxScreen = &dmxScreens[s]; + dpy = GetBackEndDisplay(cl,s); + + LockDisplay(dpy); + GetReqVendorPrivate(GLXVendorPrivate,be_req); + be_req->reqType = dmxScreen->glxMajorOpcode; + be_req->glxCode = req->glxCode; + be_req->length = req->length; + be_req->vendorCode = req->vendorCode; + be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); + if (buf_size > 0) + _XSend(dpy, (const char *)pc, buf_size); + + /* + * get the reply from the back-end server + */ + _XReply(dpy, (xReply*) &be_reply, 0, False); + be_buf_size = be_reply.length << 2; + if (be_buf_size > 0) { + be_buf = (char *)malloc( be_buf_size ); + if (be_buf) { + _XRead(dpy, be_buf, be_buf_size); + } + else { + /* Throw data on the floor */ + _XEatData(dpy, be_buf_size); + return BadAlloc; + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + if (s > from_screen && be_buf_size > 0) { + free(be_buf); + } + } + + /* + * send the reply to the client + */ + memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply ); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + SendSwappedReply( client, &reply, be_buf, be_buf_size ); + } + else { + WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply); + if (be_buf_size > 0) + WriteToClient(client, be_buf_size, (char *)be_buf); + } + + if (be_buf_size > 0) free(be_buf); + + return Success; +} + +int __glXVForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + return( __glXVForwardSingleReq( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardPipe0WithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 0; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 2; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 4; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + +int __glXVForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + __GLX_SWAP_INT(&req->contextTag); + + swap_vec_element_size = 8; + + /* + * swap extra data in request - assuming all data + * (if available) are arrays of 4 bytes components ! + */ + if (req->length > sz_xGLXVendorPrivateReq/4) { + int *data = (int *)(req+1); + int count = req->length - sz_xGLXVendorPrivateReq/4; + __GLX_SWAP_INT_ARRAY(data, count ); + } + + return( __glXVForwardAllWithReply( cl, pc ) ); +} + diff --git a/xorg-server/hw/dmx/glxProxy/render2swap.c b/xorg-server/hw/dmx/glxProxy/render2swap.c index 70ed5e802..81bb501ea 100644 --- a/xorg-server/hw/dmx/glxProxy/render2swap.c +++ b/xorg-server/hw/dmx/glxProxy/render2swap.c @@ -1,286 +1,286 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "glxserver.h"
-#include "unpack.h"
-#include "g_disptab.h"
-
-GLint __glEvalComputeK(GLenum target)
-{
- switch (target) {
- case GL_MAP1_VERTEX_4:
- case GL_MAP1_COLOR_4:
- case GL_MAP1_TEXTURE_COORD_4:
- case GL_MAP2_VERTEX_4:
- case GL_MAP2_COLOR_4:
- case GL_MAP2_TEXTURE_COORD_4:
- return 4;
- case GL_MAP1_VERTEX_3:
- case GL_MAP1_TEXTURE_COORD_3:
- case GL_MAP1_NORMAL:
- case GL_MAP2_VERTEX_3:
- case GL_MAP2_TEXTURE_COORD_3:
- case GL_MAP2_NORMAL:
- return 3;
- case GL_MAP1_TEXTURE_COORD_2:
- case GL_MAP2_TEXTURE_COORD_2:
- return 2;
- case GL_MAP1_TEXTURE_COORD_1:
- case GL_MAP2_TEXTURE_COORD_1:
- case GL_MAP1_INDEX:
- case GL_MAP2_INDEX:
- return 1;
- default:
- return 0;
- }
-}
-
-void __glXDispSwap_Map1f(GLbyte *pc)
-{
- GLint order, k;
- GLfloat u1, u2, *points;
- GLenum target;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
- target = *(GLenum *)(pc + 0);
- order = *(GLint *)(pc + 12);
- u1 = *(GLfloat *)(pc + 4);
- u2 = *(GLfloat *)(pc + 8);
- points = (GLfloat *)(pc + 16);
- k = __glEvalComputeK(target);
-
- if (order <= 0 || k < 0) {
- /* Erroneous command. */
- compsize = 0;
- } else {
- compsize = order * k;
- }
- __GLX_SWAP_FLOAT_ARRAY(points, compsize);
-
-}
-
-void __glXDispSwap_Map2f(GLbyte *pc)
-{
- GLint uorder, vorder, ustride, vstride, k;
- GLfloat u1, u2, v1, v2, *points;
- GLenum target;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 24);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
- __GLX_SWAP_FLOAT(pc + 16);
- __GLX_SWAP_FLOAT(pc + 20);
-
- target = *(GLenum *)(pc + 0);
- uorder = *(GLint *)(pc + 12);
- vorder = *(GLint *)(pc + 24);
- u1 = *(GLfloat *)(pc + 4);
- u2 = *(GLfloat *)(pc + 8);
- v1 = *(GLfloat *)(pc + 16);
- v2 = *(GLfloat *)(pc + 20);
- points = (GLfloat *)(pc + 28);
-
- k = __glEvalComputeK(target);
- ustride = vorder * k;
- vstride = k;
-
- if (vorder <= 0 || uorder <= 0 || k < 0) {
- /* Erroneous command. */
- compsize = 0;
- } else {
- compsize = uorder * vorder * k;
- }
- __GLX_SWAP_FLOAT_ARRAY(points, compsize);
-
-}
-
-void __glXDispSwap_Map1d(GLbyte *pc)
-{
- GLint order, k, compsize;
- GLenum target;
- GLdouble u1, u2, *points;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_INT(pc + 20);
-
- target = *(GLenum*) (pc + 16);
- order = *(GLint*) (pc + 20);
- k = __glEvalComputeK(target);
- if (order <= 0 || k < 0) {
- /* Erroneous command. */
- compsize = 0;
- } else {
- compsize = order * k;
- }
- __GLX_GET_DOUBLE(u1,pc);
- __GLX_GET_DOUBLE(u2,pc+8);
- __GLX_SWAP_DOUBLE_ARRAY(pc+24, compsize);
- pc += 24;
-
-#ifdef __GLX_ALIGN64
- if (((unsigned long)pc) & 7) {
- /*
- ** Copy the doubles up 4 bytes, trashing the command but aligning
- ** the data in the process
- */
- __GLX_MEM_COPY(pc-4, pc, compsize*8);
- points = (GLdouble*) (pc - 4);
- } else {
- points = (GLdouble*) pc;
- }
-#else
- points = (GLdouble*) pc;
-#endif
-}
-
-void __glXDispSwap_Map2d(GLbyte *pc)
-{
- GLdouble u1, u2, v1, v2, *points;
- GLint uorder, vorder, ustride, vstride, k, compsize;
- GLenum target;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_DOUBLE(pc + 16);
- __GLX_SWAP_DOUBLE(pc + 24);
- __GLX_SWAP_INT(pc + 32);
- __GLX_SWAP_INT(pc + 36);
- __GLX_SWAP_INT(pc + 40);
-
- target = *(GLenum *)(pc + 32);
- uorder = *(GLint *)(pc + 36);
- vorder = *(GLint *)(pc + 40);
- k = __glEvalComputeK(target);
- if (vorder <= 0 || uorder <= 0 || k < 0) {
- /* Erroneous command. */
- compsize = 0;
- } else {
- compsize = uorder * vorder * k;
- }
- __GLX_GET_DOUBLE(u1,pc);
- __GLX_GET_DOUBLE(u2,pc+8);
- __GLX_GET_DOUBLE(v1,pc+16);
- __GLX_GET_DOUBLE(v2,pc+24);
- __GLX_SWAP_DOUBLE_ARRAY(pc+44, compsize);
- pc += 44;
- ustride = vorder * k;
- vstride = k;
-
-#ifdef __GLX_ALIGN64
- if (((unsigned long)pc) & 7) {
- /*
- ** Copy the doubles up 4 bytes, trashing the command but aligning
- ** the data in the process
- */
- __GLX_MEM_COPY(pc-4, pc, compsize*8);
- points = (GLdouble*) (pc - 4);
- } else {
- points = (GLdouble*) pc;
- }
-#else
- points = (GLdouble*) pc;
-#endif
-}
-
-void __glXDispSwap_CallLists(GLbyte *pc)
-{
- GLenum type;
- GLsizei n;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 0);
- type = *(GLenum *)(pc + 4);
- n = *(GLsizei *)(pc + 0);
-
- switch (type) {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_2_BYTES:
- case GL_3_BYTES:
- case GL_4_BYTES:
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- __GLX_SWAP_SHORT_ARRAY(pc+8, n);
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- __GLX_SWAP_INT_ARRAY(pc+8, n);
- break;
- case GL_FLOAT:
- __GLX_SWAP_FLOAT_ARRAY(pc+8, n);
- break;
- }
-
-}
-
-void __glXDispSwap_DrawArrays(GLbyte *pc)
-{
- __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *)pc;
- __GLXdispatchDrawArraysComponentHeader *compHeader;
- int i;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&hdr->numVertexes);
- __GLX_SWAP_INT(&hdr->numComponents);
- __GLX_SWAP_INT(&hdr->primType);
-
- pc += sizeof(__GLXdispatchDrawArraysHeader);
- compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
-
- /* compute stride (same for all component arrays) */
- for (i=0; i<hdr->numComponents; i++) {
- __GLX_SWAP_INT(&compHeader[i].datatype);
- __GLX_SWAP_INT(&compHeader[i].numVals);
- __GLX_SWAP_INT(&compHeader[i].component);
-
- }
-
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#include "glxserver.h" +#include "unpack.h" +#include "g_disptab.h" + +GLint __glEvalComputeK(GLenum target) +{ + switch (target) { + case GL_MAP1_VERTEX_4: + case GL_MAP1_COLOR_4: + case GL_MAP1_TEXTURE_COORD_4: + case GL_MAP2_VERTEX_4: + case GL_MAP2_COLOR_4: + case GL_MAP2_TEXTURE_COORD_4: + return 4; + case GL_MAP1_VERTEX_3: + case GL_MAP1_TEXTURE_COORD_3: + case GL_MAP1_NORMAL: + case GL_MAP2_VERTEX_3: + case GL_MAP2_TEXTURE_COORD_3: + case GL_MAP2_NORMAL: + return 3; + case GL_MAP1_TEXTURE_COORD_2: + case GL_MAP2_TEXTURE_COORD_2: + return 2; + case GL_MAP1_TEXTURE_COORD_1: + case GL_MAP2_TEXTURE_COORD_1: + case GL_MAP1_INDEX: + case GL_MAP2_INDEX: + return 1; + default: + return 0; + } +} + +void __glXDispSwap_Map1f(GLbyte *pc) +{ + GLint order, k; + GLfloat u1, u2, *points; + GLenum target; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + + target = *(GLenum *)(pc + 0); + order = *(GLint *)(pc + 12); + u1 = *(GLfloat *)(pc + 4); + u2 = *(GLfloat *)(pc + 8); + points = (GLfloat *)(pc + 16); + k = __glEvalComputeK(target); + + if (order <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = order * k; + } + __GLX_SWAP_FLOAT_ARRAY(points, compsize); + +} + +void __glXDispSwap_Map2f(GLbyte *pc) +{ + GLint uorder, vorder, ustride, vstride, k; + GLfloat u1, u2, v1, v2, *points; + GLenum target; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 24); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + __GLX_SWAP_FLOAT(pc + 16); + __GLX_SWAP_FLOAT(pc + 20); + + target = *(GLenum *)(pc + 0); + uorder = *(GLint *)(pc + 12); + vorder = *(GLint *)(pc + 24); + u1 = *(GLfloat *)(pc + 4); + u2 = *(GLfloat *)(pc + 8); + v1 = *(GLfloat *)(pc + 16); + v2 = *(GLfloat *)(pc + 20); + points = (GLfloat *)(pc + 28); + + k = __glEvalComputeK(target); + ustride = vorder * k; + vstride = k; + + if (vorder <= 0 || uorder <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = uorder * vorder * k; + } + __GLX_SWAP_FLOAT_ARRAY(points, compsize); + +} + +void __glXDispSwap_Map1d(GLbyte *pc) +{ + GLint order, k, compsize; + GLenum target; + GLdouble u1, u2, *points; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + + target = *(GLenum*) (pc + 16); + order = *(GLint*) (pc + 20); + k = __glEvalComputeK(target); + if (order <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = order * k; + } + __GLX_GET_DOUBLE(u1,pc); + __GLX_GET_DOUBLE(u2,pc+8); + __GLX_SWAP_DOUBLE_ARRAY(pc+24, compsize); + pc += 24; + +#ifdef __GLX_ALIGN64 + if (((unsigned long)pc) & 7) { + /* + ** Copy the doubles up 4 bytes, trashing the command but aligning + ** the data in the process + */ + __GLX_MEM_COPY(pc-4, pc, compsize*8); + points = (GLdouble*) (pc - 4); + } else { + points = (GLdouble*) pc; + } +#else + points = (GLdouble*) pc; +#endif +} + +void __glXDispSwap_Map2d(GLbyte *pc) +{ + GLdouble u1, u2, v1, v2, *points; + GLint uorder, vorder, ustride, vstride, k, compsize; + GLenum target; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_DOUBLE(pc + 16); + __GLX_SWAP_DOUBLE(pc + 24); + __GLX_SWAP_INT(pc + 32); + __GLX_SWAP_INT(pc + 36); + __GLX_SWAP_INT(pc + 40); + + target = *(GLenum *)(pc + 32); + uorder = *(GLint *)(pc + 36); + vorder = *(GLint *)(pc + 40); + k = __glEvalComputeK(target); + if (vorder <= 0 || uorder <= 0 || k < 0) { + /* Erroneous command. */ + compsize = 0; + } else { + compsize = uorder * vorder * k; + } + __GLX_GET_DOUBLE(u1,pc); + __GLX_GET_DOUBLE(u2,pc+8); + __GLX_GET_DOUBLE(v1,pc+16); + __GLX_GET_DOUBLE(v2,pc+24); + __GLX_SWAP_DOUBLE_ARRAY(pc+44, compsize); + pc += 44; + ustride = vorder * k; + vstride = k; + +#ifdef __GLX_ALIGN64 + if (((unsigned long)pc) & 7) { + /* + ** Copy the doubles up 4 bytes, trashing the command but aligning + ** the data in the process + */ + __GLX_MEM_COPY(pc-4, pc, compsize*8); + points = (GLdouble*) (pc - 4); + } else { + points = (GLdouble*) pc; + } +#else + points = (GLdouble*) pc; +#endif +} + +void __glXDispSwap_CallLists(GLbyte *pc) +{ + GLenum type; + GLsizei n; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 0); + type = *(GLenum *)(pc + 4); + n = *(GLsizei *)(pc + 0); + + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_2_BYTES: + case GL_3_BYTES: + case GL_4_BYTES: + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + __GLX_SWAP_SHORT_ARRAY(pc+8, n); + break; + case GL_INT: + case GL_UNSIGNED_INT: + __GLX_SWAP_INT_ARRAY(pc+8, n); + break; + case GL_FLOAT: + __GLX_SWAP_FLOAT_ARRAY(pc+8, n); + break; + } + +} + +void __glXDispSwap_DrawArrays(GLbyte *pc) +{ + __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *)pc; + __GLXdispatchDrawArraysComponentHeader *compHeader; + int i; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(&hdr->numVertexes); + __GLX_SWAP_INT(&hdr->numComponents); + __GLX_SWAP_INT(&hdr->primType); + + pc += sizeof(__GLXdispatchDrawArraysHeader); + compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; + + /* compute stride (same for all component arrays) */ + for (i=0; i<hdr->numComponents; i++) { + __GLX_SWAP_INT(&compHeader[i].datatype); + __GLX_SWAP_INT(&compHeader[i].numVals); + __GLX_SWAP_INT(&compHeader[i].component); + + } + +} diff --git a/xorg-server/hw/dmx/input/dmxevents.c b/xorg-server/hw/dmx/input/dmxevents.c index 4e1238c9f..41bc4bf2d 100644 --- a/xorg-server/hw/dmx/input/dmxevents.c +++ b/xorg-server/hw/dmx/input/dmxevents.c @@ -1,766 +1,766 @@ -/*
- * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- * Provide support and helper functions for enqueing events received by
- * the low-level input drivers. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#define DMX_EVENTS_DEBUG 0
-
-#include "dmxinputinit.h"
-#include "dmxevents.h"
-#include "dmxcb.h"
-#include "dmxcommon.h"
-#include "dmxcursor.h"
-#include "dmxmotion.h"
-#include "dmxsigio.h"
-#include "dmxmap.h"
-
-#include <X11/keysym.h>
-#include "opaque.h"
-#include "inputstr.h"
-#include "inpututils.h"
-#include "mipointer.h"
-#include "mi.h"
-#include "exglobals.h"
-
-#include "xkbsrv.h"
-#include "XIstubs.h"
-
-static int dmxGlobalX, dmxGlobalY; /* Global cursor position */
-static int dmxGlobalInvalid; /* Flag indicating dmxCoreMotion
- * should move the mouse anyway. */
-
-#if DMX_EVENTS_DEBUG
-#define DMXDBG0(f) dmxLog(dmxDebug,f)
-#define DMXDBG1(f,a) dmxLog(dmxDebug,f,a)
-#define DMXDBG2(f,a,b) dmxLog(dmxDebug,f,a,b)
-#define DMXDBG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
-#define DMXDBG4(f,a,b,c,d) dmxLog(dmxDebug,f,a,b,c,d)
-#define DMXDBG5(f,a,b,c,d,e) dmxLog(dmxDebug,f,a,b,c,d,e)
-#define DMXDBG6(f,a,b,c,d,e,g) dmxLog(dmxDebug,f,a,b,c,d,e,g)
-#define DMXDBG7(f,a,b,c,d,e,g,h) dmxLog(dmxDebug,f,a,b,c,d,e,g,h)
-#else
-#define DMXDBG0(f)
-#define DMXDBG1(f,a)
-#define DMXDBG2(f,a,b)
-#define DMXDBG3(f,a,b,c)
-#define DMXDBG4(f,a,b,c,d)
-#define DMXDBG5(f,a,b,c,d,e)
-#define DMXDBG6(f,a,b,c,d,e,g)
-#define DMXDBG7(f,a,b,c,d,e,g,h)
-#endif
-
-static int dmxApplyFunctions(DMXInputInfo *dmxInput, DMXFunctionType f)
-{
- int i;
- int rc = 0;
-
- for (i = 0; i < dmxInput->numDevs; i+= dmxInput->devs[i]->binding)
- if (dmxInput->devs[i]->functions)
- rc += dmxInput->devs[i]->functions(dmxInput->devs[i]->private, f);
- return rc;
-}
-
-static int dmxCheckFunctionKeys(DMXLocalInputInfoPtr dmxLocal,
- int type,
- KeySym keySym)
-{
- DMXInputInfo *dmxInput = &dmxInputs[dmxLocal->inputIdx];
-
-#if 1 /* hack to detect ctrl-alt-q, etc */
- static int ctrl = 0, alt = 0;
- /* keep track of ctrl/alt key status */
- if (type == KeyPress && keySym == 0xffe3) {
- ctrl = 1;
- }
- else if (type == KeyRelease && keySym == 0xffe3) {
- ctrl = 0;
- }
- else if (type == KeyPress && keySym == 0xffe9) {
- alt = 1;
- }
- else if (type == KeyRelease && keySym == 0xffe9) {
- alt = 0;
- }
- if (!ctrl || !alt)
- return 0;
-#else
- unsigned short state = 0;
-
- if (dmxLocal->sendsCore)
- state = dmxLocalCoreKeyboard->pDevice->key->state;
- else if (dmxLocal->pDevice->key)
- state = dmxLocal->pDevice->key->state;
-
- DMXDBG3("dmxCheckFunctionKeys: keySym=0x%04x %s state=0x%04x\n",
- keySym, type == KeyPress ? "press" : "release", state);
-
- if ((state & (ControlMask|Mod1Mask)) != (ControlMask|Mod1Mask))
- return 0;
-#endif
-
- switch (keySym) {
- case XK_g:
- if (type == KeyPress)
- dmxApplyFunctions(dmxInput, DMX_FUNCTION_GRAB);
- return 1;
- case XK_f:
- if (type == KeyPress)
- dmxApplyFunctions(dmxInput, DMX_FUNCTION_FINE);
- return 1;
- case XK_q:
- if (type == KeyPress && dmxLocal->sendsCore)
- if (dmxApplyFunctions(dmxInput, DMX_FUNCTION_TERMINATE)) {
- dmxLog(dmxInfo, "User request for termination\n");
- dispatchException |= DE_TERMINATE;
- }
- return 1;
- }
-
- return 0;
-}
-
-
-DMXScreenInfo *dmxFindFirstScreen(int x, int y)
-{
- int i;
-
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- if (dmxOnScreen(x, y, dmxScreen))
- return dmxScreen;
- }
- return NULL;
-}
-
-
-/**
- * Enqueue a motion event.
- */
-static void enqueueMotion(DevicePtr pDev, int x, int y)
-{
- GETDMXLOCALFROMPDEV;
- DeviceIntPtr p = dmxLocal->pDevice;
- int valuators[3];
- int detail = 0; /* XXX should this be mask of pressed buttons? */
- ValuatorMask mask;
- valuators[0] = x;
- valuators[1] = y;
-
- valuator_mask_set_range(&mask, 0, 2, valuators);
- QueuePointerEvents(p, MotionNotify, detail,
- POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
- return;
-}
-
-
-void
-dmxCoreMotion(DevicePtr pDev, int x, int y, int delta, DMXBlockType block)
-{
- DMXScreenInfo *dmxScreen;
- DMXInputInfo *dmxInput;
- ScreenPtr pScreen;
- int localX;
- int localY;
- int i;
-
- if (!dmxGlobalInvalid && dmxGlobalX == x && dmxGlobalY == y)
- return;
-
- DMXDBG5("dmxCoreMotion(%d,%d,%d) dmxGlobalX=%d dmxGlobalY=%d\n",
- x, y, delta, dmxGlobalX, dmxGlobalY);
-
- dmxGlobalInvalid = 0;
- dmxGlobalX = x;
- dmxGlobalY = y;
-
- if (dmxGlobalX < 0)
- dmxGlobalX = 0;
- if (dmxGlobalY < 0)
- dmxGlobalY = 0;
- if (dmxGlobalX >= dmxGlobalWidth)
- dmxGlobalX = dmxGlobalWidth + delta -1;
- if (dmxGlobalY >= dmxGlobalHeight)
- dmxGlobalY = dmxGlobalHeight + delta -1;
-
- if ((dmxScreen = dmxFindFirstScreen(dmxGlobalX, dmxGlobalY))) {
- localX = dmxGlobalX - dmxScreen->rootXOrigin;
- localY = dmxGlobalY - dmxScreen->rootYOrigin;
- if ((pScreen = miPointerGetScreen(inputInfo.pointer))
- && pScreen->myNum == dmxScreen->index) {
- /* Screen is old screen */
- if (block)
- dmxSigioBlock();
- if (pDev)
- enqueueMotion(pDev, localX, localY);
- if (block)
- dmxSigioUnblock();
- } else {
- /* Screen is new */
- DMXDBG4(" New screen: old=%d new=%d localX=%d localY=%d\n",
- pScreen->myNum, dmxScreen->index, localX, localY);
- if (block)
- dmxSigioBlock();
- mieqProcessInputEvents();
- miPointerSetScreen(inputInfo.pointer, dmxScreen->index,
- localX, localY);
- if (pDev)
- enqueueMotion(pDev, localX, localY);
- if (block)
- dmxSigioUnblock();
- }
-#if 00
- miPointerGetPosition(inputInfo.pointer, &localX, &localY);
-
- if ((pScreen = miPointerGetScreen(inputInfo.pointer))) {
- dmxGlobalX = localX + dmxScreens[pScreen->myNum].rootXOrigin;
- dmxGlobalY = localY + dmxScreens[pScreen->myNum].rootYOrigin;
- ErrorF("Global is now %d, %d %d, %d\n", dmxGlobalX, dmxGlobalY,
- localX, localY);
- DMXDBG6(" Moved to dmxGlobalX=%d dmxGlobalY=%d"
- " on screen index=%d/%d localX=%d localY=%d\n",
- dmxGlobalX, dmxGlobalY,
- dmxScreen ? dmxScreen->index : -1, pScreen->myNum,
- localX, localY);
- }
-#endif
- }
- /* Send updates down to all core input
- * drivers */
- for (i = 0, dmxInput = &dmxInputs[0]; i < dmxNumInputs; i++, dmxInput++) {
- int j;
- for (j = 0; j < dmxInput->numDevs; j += dmxInput->devs[j]->binding)
- if (!dmxInput->detached
- && dmxInput->devs[j]->sendsCore
- && dmxInput->devs[j]->update_position)
- dmxInput->devs[j]->update_position(dmxInput->devs[j]->private,
- dmxGlobalX, dmxGlobalY);
- }
- if (!dmxScreen) ProcessInputEvents();
-}
-
-
-
-#define DMX_MAX_AXES 32 /* Max axes reported by this routine */
-static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
- int *v, int firstAxis, int axesCount,
- DMXMotionType type, DMXBlockType block)
-{
- DeviceIntPtr pDevice = dmxLocal->pDevice;
- xEvent xE[2 * DMX_MAX_AXES/6];
- deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *)xE;
- deviceValuator *xv = (deviceValuator *)xev+1;
- int thisX = 0;
- int thisY = 0;
- int count;
- ValuatorMask mask;
-
- memset(xE, 0, sizeof(xE));
-
- if (axesCount > DMX_MAX_AXES) axesCount = DMX_MAX_AXES;
-
- if ((valuator_get_mode(pDevice,0) == Relative) && axesCount == 2) {
- /* The dmx console is a relative mode
- * device that sometimes reports
- * absolute motion. It only has two
- * axes. */
- if (type == DMX_RELATIVE) {
- thisX = -v[0];
- thisY = -v[1];
- dmxLocal->lastX += thisX;
- dmxLocal->lastY += thisY;
- if (dmxLocal->update_position)
- dmxLocal->update_position(dmxLocal->private,
- dmxLocal->lastX, dmxLocal->lastY);
- } else { /* Convert to relative */
- if (dmxLocal->lastX || dmxLocal->lastY) {
- thisX = v[0] - dmxLocal->lastX;
- thisY = v[1] - dmxLocal->lastY;
- }
- dmxLocal->lastX = v[0];
- dmxLocal->lastY = v[1];
- }
- v[0] = thisX;
- v[1] = thisY;
- }
-
- if (axesCount <= 6) {
- /* Optimize for the common case when
- * only 1 or 2 axes change. */
- xev->time = GetTimeInMillis();
- xev->type = DeviceMotionNotify;
- xev->detail = 0;
- xev->deviceid = pDevice->id | MORE_EVENTS;
-
- xv->type = DeviceValuator;
- xv->deviceid = pDevice->id;
- xv->num_valuators = axesCount;
- xv->first_valuator = firstAxis;
- switch (xv->num_valuators) {
- case 6: xv->valuator5 = v[5];
- case 5: xv->valuator4 = v[4];
- case 4: xv->valuator3 = v[3];
- case 3: xv->valuator2 = v[2];
- case 2: xv->valuator1 = v[1];
- case 1: xv->valuator0 = v[0];
- }
- count = 2;
- } else {
- int i;
- for (i = 0, count = 0; i < axesCount; i += 6) {
- xev->time = GetTimeInMillis();
- xev->type = DeviceMotionNotify;
- xev->detail = 0;
- xev->deviceid = pDevice->id | MORE_EVENTS;
- xev += 2;
-
- xv->type = DeviceValuator;
- xv->deviceid = pDevice->id;
- xv->num_valuators = (i+6 >= axesCount ? axesCount - i : 6);
- xv->first_valuator = firstAxis + i;
- switch (xv->num_valuators) {
- case 6: xv->valuator5 = v[i+5];
- case 5: xv->valuator4 = v[i+4];
- case 4: xv->valuator3 = v[i+3];
- case 3: xv->valuator2 = v[i+2];
- case 2: xv->valuator1 = v[i+1];
- case 1: xv->valuator0 = v[i+0];
- }
- xv += 2;
- count += 2;
- }
- }
-
- if (block)
- dmxSigioBlock();
- valuator_mask_set_range(&mask, firstAxis, axesCount, v);
- QueuePointerEvents(pDevice, MotionNotify, 0,
- POINTER_ABSOLUTE, &mask);
-
- if (block)
- dmxSigioUnblock();
-}
-
-static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
- XEvent *e, DMXBlockType block)
-{
- int type;
- int event = -1;
- XDeviceKeyEvent *ke = (XDeviceKeyEvent *)e;
- XDeviceMotionEvent *me = (XDeviceMotionEvent *)e;
- DeviceIntPtr pDevice = dmxLocal->pDevice;
- int valuators[MAX_VALUATORS];
- ValuatorMask mask;
-
- if (!e)
- return -1; /* No extended event passed, cannot handle */
-
- if ((XID)dmxLocal->deviceId != ke->deviceid) {
- /* Search for the correct dmxLocal,
- * since backend and console events are
- * picked up for the first device on
- * that X server. */
- int i;
- DMXInputInfo *dmxInput = &dmxInputs[dmxLocal->inputIdx];
- for (i = 0; i < dmxInput->numDevs; i++) {
- dmxLocal = dmxInput->devs[i];
- if ((XID)dmxLocal->deviceId == ke->deviceid)
- break;
- }
- }
-
- if ((XID)dmxLocal->deviceId != ke->deviceid
- || (type = dmxMapLookup(dmxLocal, e->type)) < 0)
- return -1; /* No mapping, so this event is unhandled */
-
- switch (type) {
- case XI_DeviceValuator: event = DeviceValuator; break;
- case XI_DeviceKeyPress: event = KeyPress; break;
- case XI_DeviceKeyRelease: event = KeyRelease; break;
- case XI_DeviceButtonPress: event = ButtonPress; break;
- case XI_DeviceButtonRelease: event = ButtonRelease; break;
- case XI_DeviceMotionNotify: event = MotionNotify; break;
- case XI_DeviceFocusIn: event = DeviceFocusIn; break;
- case XI_DeviceFocusOut: event = DeviceFocusOut; break;
- case XI_ProximityIn: event = ProximityIn; break;
- case XI_ProximityOut: event = ProximityOut; break;
- case XI_DeviceStateNotify: event = DeviceStateNotify; break;
- case XI_DeviceMappingNotify: event = DeviceMappingNotify; break;
- case XI_ChangeDeviceNotify: event = ChangeDeviceNotify; break;
- case XI_DeviceKeystateNotify: event = DeviceStateNotify; break;
- case XI_DeviceButtonstateNotify: event = DeviceStateNotify; break;
- }
-
-#define EXTRACT_VALUATORS(ke, valuators) \
- valuators[0] = ke->axis_data[0]; \
- valuators[1] = ke->axis_data[1]; \
- valuators[2] = ke->axis_data[2]; \
- valuators[3] = ke->axis_data[3]; \
- valuators[4] = ke->axis_data[4]; \
- valuators[5] = ke->axis_data[5]; \
-
- switch (type) {
- case XI_DeviceKeyPress:
- case XI_DeviceKeyRelease:
- EXTRACT_VALUATORS(ke, valuators);
- valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
- if (block)
- dmxSigioBlock();
- QueueKeyboardEvents(pDevice, event, ke->keycode, &mask);
- if (block)
- dmxSigioUnblock();
- break;
- case XI_DeviceButtonPress:
- case XI_DeviceButtonRelease:
- EXTRACT_VALUATORS(ke, valuators);
- valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
- if (block)
- dmxSigioBlock();
- QueuePointerEvents(pDevice, event, ke->keycode,
- POINTER_ABSOLUTE, &mask);
- if (block)
- dmxSigioUnblock();
- break;
- case XI_ProximityIn:
- case XI_ProximityOut:
- EXTRACT_VALUATORS(ke, valuators);
- valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
- if (block)
- dmxSigioBlock();
- QueueProximityEvents(pDevice, event, &mask);
- if (block)
- dmxSigioUnblock();
- break;
-
- break;
-
- case XI_DeviceMotionNotify:
- dmxExtMotion(dmxLocal, me->axis_data, me->first_axis, me->axes_count,
- DMX_ABSOLUTE, block);
- break;
- case XI_DeviceFocusIn:
- case XI_DeviceFocusOut:
- case XI_DeviceStateNotify:
- case XI_DeviceMappingNotify:
- case XI_ChangeDeviceNotify:
- case XI_DeviceKeystateNotify:
- case XI_DeviceButtonstateNotify:
- /* These are ignored, since DMX will
- * generate its own events of these
- * types, as necessary.
-
- * Perhaps ChangeDeviceNotify should
- * generate an error, because it is
- * unexpected? */
- break;
- case XI_DeviceValuator:
- default:
- dmxLog(dmxWarning,
- "XInput extension event (remote=%d -> zero-based=%d)"
- " not supported yet\n", e->type, type);
- return -1;
- }
- return 0;
-}
-
-static int dmxGetButtonMapping(DMXLocalInputInfoPtr dmxLocal, int button)
-{
- ButtonClassPtr b = dmxLocal->pDevice->button;
-
- if (button > b->numButtons) { /* This shouldn't happen. */
- dmxLog(dmxWarning, "Button %d pressed, but only %d buttons?!?\n",
- button, b->numButtons);
- return button;
- }
- return b->map[button];
-}
-
-/** Return DMX's notion of the pointer position in the global coordinate
- * space. */
-void dmxGetGlobalPosition(int *x, int *y)
-{
- *x = dmxGlobalX;
- *y = dmxGlobalY;
-}
-
-/** Invalidate the global position for #dmxCoreMotion. */
-void dmxInvalidateGlobalPosition(void)
-{
- dmxGlobalInvalid = 1;
-}
-
-/** Enqueue a motion event for \a pDev. The \a v vector has length \a
- * axesCount, and contains values for each of the axes, starting at \a
- * firstAxes.
- *
- * The \a type of the motion may be \a DMX_RELATIVE, \a DMX_ABSOLUTE, or
- * \a DMX_ABSOLUTE_CONFINED (in the latter case, the pointer will not be
- * allowed to move outside the global boundaires).
- *
- * If \a block is set to \a DMX_BLOCK, then the SIGIO handler will be
- * blocked around calls to \a enqueueMotion(). */
-void dmxMotion(DevicePtr pDev, int *v, int firstAxes, int axesCount,
- DMXMotionType type, DMXBlockType block)
-{
- GETDMXLOCALFROMPDEV;
-
- if (!dmxLocal->sendsCore) {
- dmxExtMotion(dmxLocal, v, firstAxes, axesCount, type, block);
- return;
- }
- if (axesCount == 2) {
- switch (type) {
- case DMX_RELATIVE:
- dmxCoreMotion(pDev, dmxGlobalX - v[0], dmxGlobalY - v[1], 0, block);
- break;
- case DMX_ABSOLUTE:
- dmxCoreMotion(pDev, v[0], v[1], 0, block);
- break;
- case DMX_ABSOLUTE_CONFINED:
- dmxCoreMotion(pDev, v[0], v[1], -1, block);
- break;
- }
- }
-}
-
-static KeySym dmxKeyCodeToKeySym(DMXLocalInputInfoPtr dmxLocal,
- KeyCode keyCode)
-{
- KeySym keysym = NoSymbol;
- int effectiveGroup;
- XkbSrvInfoPtr xkbi;
-
- if (!dmxLocal || !dmxLocal->pDevice || !dmxLocal->pDevice->key)
- goto out;
-
- xkbi = dmxLocal->pDevice->key->xkbInfo;
- effectiveGroup = XkbGetEffectiveGroup(xkbi, &xkbi->state, keyCode);
-
- if (effectiveGroup == -1)
- goto out;
-
- keysym = XkbKeySym(xkbi->desc, keyCode, effectiveGroup);
- DMXDBG2("dmxKeyCodeToKeySym: Translated keyCode=%d to keySym=0x%04x\n",
- keyCode, keysym);
-
-out:
- return keysym;
-}
-
-static KeyCode dmxKeySymToKeyCode(DMXLocalInputInfoPtr dmxLocal, KeySym keySym,
- int tryFirst)
-{
- /* FIXME: this is quite ineffective, converting to a core map first and
- * then extracting the info from there. It'd be better to run the actual
- * xkb map */
- XkbSrvInfoPtr xkbi = dmxLocal->pDevice->key->xkbInfo;
- KeySymsPtr pKeySyms = XkbGetCoreMap(dmxLocal->pDevice);
- int i;
-
- /* Optimize for similar maps */
- if (XkbKeycodeInRange(xkbi->desc, tryFirst)
- && pKeySyms->map[(tryFirst - xkbi->desc->min_key_code)
- * pKeySyms->mapWidth] == keySym)
- return tryFirst;
-
- for (i = pKeySyms->minKeyCode; i <= pKeySyms->maxKeyCode; i++) {
- if (pKeySyms->map[(i - pKeySyms->minKeyCode)
- * pKeySyms->mapWidth] == keySym) {
- DMXDBG3("dmxKeySymToKeyCode: Translated keySym=0x%04x to"
- " keyCode=%d (reverses to core keySym=0x%04x)\n",
- keySym, i, dmxKeyCodeToKeySym(dmxLocalCoreKeyboard,i));
- return i;
- }
- }
- return 0;
-}
-
-static int dmxFixup(DevicePtr pDev, int detail, KeySym keySym)
-{
- GETDMXLOCALFROMPDEV;
- int keyCode;
-
- if (!dmxLocal->pDevice->key) {
- dmxLog(dmxWarning, "dmxFixup: not a keyboard device (%s)\n",
- dmxLocal->pDevice->name);
- return NoSymbol;
- }
- if (!keySym)
- keySym = dmxKeyCodeToKeySym(dmxLocal, detail);
- if (keySym == NoSymbol)
- return detail;
- keyCode = dmxKeySymToKeyCode(dmxLocalCoreKeyboard, keySym, detail);
-
- return keyCode ? keyCode : detail;
-}
-
-/** Enqueue an event from the \a pDev device with the
- * specified \a type and \a detail. If the event is a KeyPress or
- * KeyRelease event, then the \a keySym is also specified.
- *
- * FIXME: make the code do what the comment says, or remove this comment.
- * If \a block is set to \a DMX_BLOCK, then the SIGIO handler will be
- * blocked around calls to dmxeqEnqueue(). */
-
-void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
- XEvent *e, DMXBlockType block)
-{
- GETDMXINPUTFROMPDEV;
- xEvent xE;
- DeviceIntPtr p = dmxLocal->pDevice;
- int valuators[3];
- ValuatorMask mask;
-
- DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail);
-
- switch (type) {
- case KeyPress:
- case KeyRelease:
- if (!keySym)
- keySym = dmxKeyCodeToKeySym(dmxLocal, detail);
- if (dmxCheckFunctionKeys(dmxLocal, type, keySym))
- return;
- if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard)
- xE.u.u.detail = dmxFixup(pDev, detail, keySym);
-
- /*ErrorF("KEY %d sym %d\n", detail, (int) keySym);*/
- QueueKeyboardEvents(p, type, detail, NULL);
- return;
-
- case ButtonPress:
- case ButtonRelease:
- detail = dmxGetButtonMapping(dmxLocal, detail);
- valuator_mask_zero(&mask);
- QueuePointerEvents(p, type, detail,
- POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
- return;
-
- case MotionNotify:
- valuators[0] = e->xmotion.x;
- valuators[1] = e->xmotion.y;
- valuators[2] = e->xmotion.state; /* FIXME: WTF?? */
- valuator_mask_set_range(&mask, 0, 3, valuators);
- QueuePointerEvents(p, type, detail,
- POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
- return;
-
- case EnterNotify:
- case LeaveNotify:
- case KeymapNotify:
- case MappingNotify: /* This is sent because we change the
- * modifier map on the backend/console
- * input device so that we have complete
- * control of the input device LEDs. */
- return;
- default:
- if (type == ProximityIn || type == ProximityOut) {
- if (dmxLocal->sendsCore)
- return; /* Not a core event */
- break;
- }
- if (type >= LASTEvent) {
- if (dmxTranslateAndEnqueueExtEvent(dmxLocal, e, block))
- dmxLogInput(dmxInput, "Unhandled extension event: %d\n", type);
- } else {
- dmxLogInput(dmxInput, "Unhandled event: %d (%s)\n",
- type, dmxEventName(type));
- }
- return;
- }
-
-}
-
-/** A pointer to this routine is passed to low-level input drivers so
- * that all special keychecking is unified to this file. This function
- * returns 0 if no special keys have been pressed. If the user has
- * requested termination of the DMX server, -1 is returned. If the user
- * has requested a switch to a VT, then the (1-based) number of that VT
- * is returned. */
-int dmxCheckSpecialKeys(DevicePtr pDev, KeySym keySym)
-{
- GETDMXINPUTFROMPDEV;
- int vt = 0;
- unsigned short state = 0;
-
- if (dmxLocal->sendsCore)
- state = XkbStateFieldFromRec(&dmxLocalCoreKeyboard->pDevice->key->xkbInfo->state);
- else if (dmxLocal->pDevice->key)
- state = XkbStateFieldFromRec(&dmxLocal->pDevice->key->xkbInfo->state);
-
- if (!dmxLocal->sendsCore) return 0; /* Only for core devices */
-
- DMXDBG2("dmxCheckSpecialKeys: keySym=0x%04x state=0x%04x\n", keySym,state);
-
- if ((state & (ControlMask|Mod1Mask)) != (ControlMask|Mod1Mask)) return 0;
-
- switch (keySym) {
- case XK_F1:
- case XK_F2:
- case XK_F3:
- case XK_F4:
- case XK_F5:
- case XK_F6:
- case XK_F7:
- case XK_F8:
- case XK_F9:
- case XK_F10:
- vt = keySym - XK_F1 + 1;
- break;
-
- case XK_F11:
- case XK_F12:
- vt = keySym - XK_F11 + 11;
- break;
-
- case XK_q: /* To avoid confusion */
- case XK_BackSpace:
- case XK_Delete:
- case XK_KP_Delete:
- dmxLog(dmxInfo, "User request for termination\n");
- dispatchException |= DE_TERMINATE;
- return -1; /* Terminate */
- }
-
- if (vt) {
- dmxLog(dmxInfo, "Request to switch to VT %d\n", vt);
- dmxInput->vt_switch_pending = vt;
- return vt;
- }
-
- return 0; /* Do nothing */
-}
+/* + * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Rickard E. (Rik) Faith <faith@redhat.com> + * + */ + +/** \file + * Provide support and helper functions for enqueing events received by + * the low-level input drivers. */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#define DMX_EVENTS_DEBUG 0 + +#include "dmxinputinit.h" +#include "dmxevents.h" +#include "dmxcb.h" +#include "dmxcommon.h" +#include "dmxcursor.h" +#include "dmxmotion.h" +#include "dmxsigio.h" +#include "dmxmap.h" + +#include <X11/keysym.h> +#include "opaque.h" +#include "inputstr.h" +#include "inpututils.h" +#include "mipointer.h" +#include "mi.h" +#include "exglobals.h" + +#include "xkbsrv.h" +#include "XIstubs.h" + +static int dmxGlobalX, dmxGlobalY; /* Global cursor position */ +static int dmxGlobalInvalid; /* Flag indicating dmxCoreMotion + * should move the mouse anyway. */ + +#if DMX_EVENTS_DEBUG +#define DMXDBG0(f) dmxLog(dmxDebug,f) +#define DMXDBG1(f,a) dmxLog(dmxDebug,f,a) +#define DMXDBG2(f,a,b) dmxLog(dmxDebug,f,a,b) +#define DMXDBG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c) +#define DMXDBG4(f,a,b,c,d) dmxLog(dmxDebug,f,a,b,c,d) +#define DMXDBG5(f,a,b,c,d,e) dmxLog(dmxDebug,f,a,b,c,d,e) +#define DMXDBG6(f,a,b,c,d,e,g) dmxLog(dmxDebug,f,a,b,c,d,e,g) +#define DMXDBG7(f,a,b,c,d,e,g,h) dmxLog(dmxDebug,f,a,b,c,d,e,g,h) +#else +#define DMXDBG0(f) +#define DMXDBG1(f,a) +#define DMXDBG2(f,a,b) +#define DMXDBG3(f,a,b,c) +#define DMXDBG4(f,a,b,c,d) +#define DMXDBG5(f,a,b,c,d,e) +#define DMXDBG6(f,a,b,c,d,e,g) +#define DMXDBG7(f,a,b,c,d,e,g,h) +#endif + +static int dmxApplyFunctions(DMXInputInfo *dmxInput, DMXFunctionType f) +{ + int i; + int rc = 0; + + for (i = 0; i < dmxInput->numDevs; i+= dmxInput->devs[i]->binding) + if (dmxInput->devs[i]->functions) + rc += dmxInput->devs[i]->functions(dmxInput->devs[i]->private, f); + return rc; +} + +static int dmxCheckFunctionKeys(DMXLocalInputInfoPtr dmxLocal, + int type, + KeySym keySym) +{ + DMXInputInfo *dmxInput = &dmxInputs[dmxLocal->inputIdx]; + +#if 1 /* hack to detect ctrl-alt-q, etc */ + static int ctrl = 0, alt = 0; + /* keep track of ctrl/alt key status */ + if (type == KeyPress && keySym == 0xffe3) { + ctrl = 1; + } + else if (type == KeyRelease && keySym == 0xffe3) { + ctrl = 0; + } + else if (type == KeyPress && keySym == 0xffe9) { + alt = 1; + } + else if (type == KeyRelease && keySym == 0xffe9) { + alt = 0; + } + if (!ctrl || !alt) + return 0; +#else + unsigned short state = 0; + + if (dmxLocal->sendsCore) + state = dmxLocalCoreKeyboard->pDevice->key->state; + else if (dmxLocal->pDevice->key) + state = dmxLocal->pDevice->key->state; + + DMXDBG3("dmxCheckFunctionKeys: keySym=0x%04x %s state=0x%04x\n", + keySym, type == KeyPress ? "press" : "release", state); + + if ((state & (ControlMask|Mod1Mask)) != (ControlMask|Mod1Mask)) + return 0; +#endif + + switch (keySym) { + case XK_g: + if (type == KeyPress) + dmxApplyFunctions(dmxInput, DMX_FUNCTION_GRAB); + return 1; + case XK_f: + if (type == KeyPress) + dmxApplyFunctions(dmxInput, DMX_FUNCTION_FINE); + return 1; + case XK_q: + if (type == KeyPress && dmxLocal->sendsCore) + if (dmxApplyFunctions(dmxInput, DMX_FUNCTION_TERMINATE)) { + dmxLog(dmxInfo, "User request for termination\n"); + dispatchException |= DE_TERMINATE; + } + return 1; + } + + return 0; +} + + +DMXScreenInfo *dmxFindFirstScreen(int x, int y) +{ + int i; + + for (i = 0; i < dmxNumScreens; i++) { + DMXScreenInfo *dmxScreen = &dmxScreens[i]; + if (dmxOnScreen(x, y, dmxScreen)) + return dmxScreen; + } + return NULL; +} + + +/** + * Enqueue a motion event. + */ +static void enqueueMotion(DevicePtr pDev, int x, int y) +{ + GETDMXLOCALFROMPDEV; + DeviceIntPtr p = dmxLocal->pDevice; + int valuators[3]; + int detail = 0; /* XXX should this be mask of pressed buttons? */ + ValuatorMask mask; + valuators[0] = x; + valuators[1] = y; + + valuator_mask_set_range(&mask, 0, 2, valuators); + QueuePointerEvents(p, MotionNotify, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); + return; +} + + +void +dmxCoreMotion(DevicePtr pDev, int x, int y, int delta, DMXBlockType block) +{ + DMXScreenInfo *dmxScreen; + DMXInputInfo *dmxInput; + ScreenPtr pScreen; + int localX; + int localY; + int i; + + if (!dmxGlobalInvalid && dmxGlobalX == x && dmxGlobalY == y) + return; + + DMXDBG5("dmxCoreMotion(%d,%d,%d) dmxGlobalX=%d dmxGlobalY=%d\n", + x, y, delta, dmxGlobalX, dmxGlobalY); + + dmxGlobalInvalid = 0; + dmxGlobalX = x; + dmxGlobalY = y; + + if (dmxGlobalX < 0) + dmxGlobalX = 0; + if (dmxGlobalY < 0) + dmxGlobalY = 0; + if (dmxGlobalX >= dmxGlobalWidth) + dmxGlobalX = dmxGlobalWidth + delta -1; + if (dmxGlobalY >= dmxGlobalHeight) + dmxGlobalY = dmxGlobalHeight + delta -1; + + if ((dmxScreen = dmxFindFirstScreen(dmxGlobalX, dmxGlobalY))) { + localX = dmxGlobalX - dmxScreen->rootXOrigin; + localY = dmxGlobalY - dmxScreen->rootYOrigin; + if ((pScreen = miPointerGetScreen(inputInfo.pointer)) + && pScreen->myNum == dmxScreen->index) { + /* Screen is old screen */ + if (block) + dmxSigioBlock(); + if (pDev) + enqueueMotion(pDev, localX, localY); + if (block) + dmxSigioUnblock(); + } else { + /* Screen is new */ + DMXDBG4(" New screen: old=%d new=%d localX=%d localY=%d\n", + pScreen->myNum, dmxScreen->index, localX, localY); + if (block) + dmxSigioBlock(); + mieqProcessInputEvents(); + miPointerSetScreen(inputInfo.pointer, dmxScreen->index, + localX, localY); + if (pDev) + enqueueMotion(pDev, localX, localY); + if (block) + dmxSigioUnblock(); + } +#if 00 + miPointerGetPosition(inputInfo.pointer, &localX, &localY); + + if ((pScreen = miPointerGetScreen(inputInfo.pointer))) { + dmxGlobalX = localX + dmxScreens[pScreen->myNum].rootXOrigin; + dmxGlobalY = localY + dmxScreens[pScreen->myNum].rootYOrigin; + ErrorF("Global is now %d, %d %d, %d\n", dmxGlobalX, dmxGlobalY, + localX, localY); + DMXDBG6(" Moved to dmxGlobalX=%d dmxGlobalY=%d" + " on screen index=%d/%d localX=%d localY=%d\n", + dmxGlobalX, dmxGlobalY, + dmxScreen ? dmxScreen->index : -1, pScreen->myNum, + localX, localY); + } +#endif + } + /* Send updates down to all core input + * drivers */ + for (i = 0, dmxInput = &dmxInputs[0]; i < dmxNumInputs; i++, dmxInput++) { + int j; + for (j = 0; j < dmxInput->numDevs; j += dmxInput->devs[j]->binding) + if (!dmxInput->detached + && dmxInput->devs[j]->sendsCore + && dmxInput->devs[j]->update_position) + dmxInput->devs[j]->update_position(dmxInput->devs[j]->private, + dmxGlobalX, dmxGlobalY); + } + if (!dmxScreen) ProcessInputEvents(); +} + + + +#define DMX_MAX_AXES 32 /* Max axes reported by this routine */ +static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, + int *v, int firstAxis, int axesCount, + DMXMotionType type, DMXBlockType block) +{ + DeviceIntPtr pDevice = dmxLocal->pDevice; + xEvent xE[2 * DMX_MAX_AXES/6]; + deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *)xE; + deviceValuator *xv = (deviceValuator *)xev+1; + int thisX = 0; + int thisY = 0; + int count; + ValuatorMask mask; + + memset(xE, 0, sizeof(xE)); + + if (axesCount > DMX_MAX_AXES) axesCount = DMX_MAX_AXES; + + if ((valuator_get_mode(pDevice,0) == Relative) && axesCount == 2) { + /* The dmx console is a relative mode + * device that sometimes reports + * absolute motion. It only has two + * axes. */ + if (type == DMX_RELATIVE) { + thisX = -v[0]; + thisY = -v[1]; + dmxLocal->lastX += thisX; + dmxLocal->lastY += thisY; + if (dmxLocal->update_position) + dmxLocal->update_position(dmxLocal->private, + dmxLocal->lastX, dmxLocal->lastY); + } else { /* Convert to relative */ + if (dmxLocal->lastX || dmxLocal->lastY) { + thisX = v[0] - dmxLocal->lastX; + thisY = v[1] - dmxLocal->lastY; + } + dmxLocal->lastX = v[0]; + dmxLocal->lastY = v[1]; + } + v[0] = thisX; + v[1] = thisY; + } + + if (axesCount <= 6) { + /* Optimize for the common case when + * only 1 or 2 axes change. */ + xev->time = GetTimeInMillis(); + xev->type = DeviceMotionNotify; + xev->detail = 0; + xev->deviceid = pDevice->id | MORE_EVENTS; + + xv->type = DeviceValuator; + xv->deviceid = pDevice->id; + xv->num_valuators = axesCount; + xv->first_valuator = firstAxis; + switch (xv->num_valuators) { + case 6: xv->valuator5 = v[5]; + case 5: xv->valuator4 = v[4]; + case 4: xv->valuator3 = v[3]; + case 3: xv->valuator2 = v[2]; + case 2: xv->valuator1 = v[1]; + case 1: xv->valuator0 = v[0]; + } + count = 2; + } else { + int i; + for (i = 0, count = 0; i < axesCount; i += 6) { + xev->time = GetTimeInMillis(); + xev->type = DeviceMotionNotify; + xev->detail = 0; + xev->deviceid = pDevice->id | MORE_EVENTS; + xev += 2; + + xv->type = DeviceValuator; + xv->deviceid = pDevice->id; + xv->num_valuators = (i+6 >= axesCount ? axesCount - i : 6); + xv->first_valuator = firstAxis + i; + switch (xv->num_valuators) { + case 6: xv->valuator5 = v[i+5]; + case 5: xv->valuator4 = v[i+4]; + case 4: xv->valuator3 = v[i+3]; + case 3: xv->valuator2 = v[i+2]; + case 2: xv->valuator1 = v[i+1]; + case 1: xv->valuator0 = v[i+0]; + } + xv += 2; + count += 2; + } + } + + if (block) + dmxSigioBlock(); + valuator_mask_set_range(&mask, firstAxis, axesCount, v); + QueuePointerEvents(pDevice, MotionNotify, 0, + POINTER_ABSOLUTE, &mask); + + if (block) + dmxSigioUnblock(); +} + +static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, + XEvent *e, DMXBlockType block) +{ + int type; + int event = -1; + XDeviceKeyEvent *ke = (XDeviceKeyEvent *)e; + XDeviceMotionEvent *me = (XDeviceMotionEvent *)e; + DeviceIntPtr pDevice = dmxLocal->pDevice; + int valuators[MAX_VALUATORS]; + ValuatorMask mask; + + if (!e) + return -1; /* No extended event passed, cannot handle */ + + if ((XID)dmxLocal->deviceId != ke->deviceid) { + /* Search for the correct dmxLocal, + * since backend and console events are + * picked up for the first device on + * that X server. */ + int i; + DMXInputInfo *dmxInput = &dmxInputs[dmxLocal->inputIdx]; + for (i = 0; i < dmxInput->numDevs; i++) { + dmxLocal = dmxInput->devs[i]; + if ((XID)dmxLocal->deviceId == ke->deviceid) + break; + } + } + + if ((XID)dmxLocal->deviceId != ke->deviceid + || (type = dmxMapLookup(dmxLocal, e->type)) < 0) + return -1; /* No mapping, so this event is unhandled */ + + switch (type) { + case XI_DeviceValuator: event = DeviceValuator; break; + case XI_DeviceKeyPress: event = KeyPress; break; + case XI_DeviceKeyRelease: event = KeyRelease; break; + case XI_DeviceButtonPress: event = ButtonPress; break; + case XI_DeviceButtonRelease: event = ButtonRelease; break; + case XI_DeviceMotionNotify: event = MotionNotify; break; + case XI_DeviceFocusIn: event = DeviceFocusIn; break; + case XI_DeviceFocusOut: event = DeviceFocusOut; break; + case XI_ProximityIn: event = ProximityIn; break; + case XI_ProximityOut: event = ProximityOut; break; + case XI_DeviceStateNotify: event = DeviceStateNotify; break; + case XI_DeviceMappingNotify: event = DeviceMappingNotify; break; + case XI_ChangeDeviceNotify: event = ChangeDeviceNotify; break; + case XI_DeviceKeystateNotify: event = DeviceStateNotify; break; + case XI_DeviceButtonstateNotify: event = DeviceStateNotify; break; + } + +#define EXTRACT_VALUATORS(ke, valuators) \ + valuators[0] = ke->axis_data[0]; \ + valuators[1] = ke->axis_data[1]; \ + valuators[2] = ke->axis_data[2]; \ + valuators[3] = ke->axis_data[3]; \ + valuators[4] = ke->axis_data[4]; \ + valuators[5] = ke->axis_data[5]; \ + + switch (type) { + case XI_DeviceKeyPress: + case XI_DeviceKeyRelease: + EXTRACT_VALUATORS(ke, valuators); + valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); + if (block) + dmxSigioBlock(); + QueueKeyboardEvents(pDevice, event, ke->keycode, &mask); + if (block) + dmxSigioUnblock(); + break; + case XI_DeviceButtonPress: + case XI_DeviceButtonRelease: + EXTRACT_VALUATORS(ke, valuators); + valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); + if (block) + dmxSigioBlock(); + QueuePointerEvents(pDevice, event, ke->keycode, + POINTER_ABSOLUTE, &mask); + if (block) + dmxSigioUnblock(); + break; + case XI_ProximityIn: + case XI_ProximityOut: + EXTRACT_VALUATORS(ke, valuators); + valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); + if (block) + dmxSigioBlock(); + QueueProximityEvents(pDevice, event, &mask); + if (block) + dmxSigioUnblock(); + break; + + break; + + case XI_DeviceMotionNotify: + dmxExtMotion(dmxLocal, me->axis_data, me->first_axis, me->axes_count, + DMX_ABSOLUTE, block); + break; + case XI_DeviceFocusIn: + case XI_DeviceFocusOut: + case XI_DeviceStateNotify: + case XI_DeviceMappingNotify: + case XI_ChangeDeviceNotify: + case XI_DeviceKeystateNotify: + case XI_DeviceButtonstateNotify: + /* These are ignored, since DMX will + * generate its own events of these + * types, as necessary. + + * Perhaps ChangeDeviceNotify should + * generate an error, because it is + * unexpected? */ + break; + case XI_DeviceValuator: + default: + dmxLog(dmxWarning, + "XInput extension event (remote=%d -> zero-based=%d)" + " not supported yet\n", e->type, type); + return -1; + } + return 0; +} + +static int dmxGetButtonMapping(DMXLocalInputInfoPtr dmxLocal, int button) +{ + ButtonClassPtr b = dmxLocal->pDevice->button; + + if (button > b->numButtons) { /* This shouldn't happen. */ + dmxLog(dmxWarning, "Button %d pressed, but only %d buttons?!?\n", + button, b->numButtons); + return button; + } + return b->map[button]; +} + +/** Return DMX's notion of the pointer position in the global coordinate + * space. */ +void dmxGetGlobalPosition(int *x, int *y) +{ + *x = dmxGlobalX; + *y = dmxGlobalY; +} + +/** Invalidate the global position for #dmxCoreMotion. */ +void dmxInvalidateGlobalPosition(void) +{ + dmxGlobalInvalid = 1; +} + +/** Enqueue a motion event for \a pDev. The \a v vector has length \a + * axesCount, and contains values for each of the axes, starting at \a + * firstAxes. + * + * The \a type of the motion may be \a DMX_RELATIVE, \a DMX_ABSOLUTE, or + * \a DMX_ABSOLUTE_CONFINED (in the latter case, the pointer will not be + * allowed to move outside the global boundaires). + * + * If \a block is set to \a DMX_BLOCK, then the SIGIO handler will be + * blocked around calls to \a enqueueMotion(). */ +void dmxMotion(DevicePtr pDev, int *v, int firstAxes, int axesCount, + DMXMotionType type, DMXBlockType block) +{ + GETDMXLOCALFROMPDEV; + + if (!dmxLocal->sendsCore) { + dmxExtMotion(dmxLocal, v, firstAxes, axesCount, type, block); + return; + } + if (axesCount == 2) { + switch (type) { + case DMX_RELATIVE: + dmxCoreMotion(pDev, dmxGlobalX - v[0], dmxGlobalY - v[1], 0, block); + break; + case DMX_ABSOLUTE: + dmxCoreMotion(pDev, v[0], v[1], 0, block); + break; + case DMX_ABSOLUTE_CONFINED: + dmxCoreMotion(pDev, v[0], v[1], -1, block); + break; + } + } +} + +static KeySym dmxKeyCodeToKeySym(DMXLocalInputInfoPtr dmxLocal, + KeyCode keyCode) +{ + KeySym keysym = NoSymbol; + int effectiveGroup; + XkbSrvInfoPtr xkbi; + + if (!dmxLocal || !dmxLocal->pDevice || !dmxLocal->pDevice->key) + goto out; + + xkbi = dmxLocal->pDevice->key->xkbInfo; + effectiveGroup = XkbGetEffectiveGroup(xkbi, &xkbi->state, keyCode); + + if (effectiveGroup == -1) + goto out; + + keysym = XkbKeySym(xkbi->desc, keyCode, effectiveGroup); + DMXDBG2("dmxKeyCodeToKeySym: Translated keyCode=%d to keySym=0x%04x\n", + keyCode, keysym); + +out: + return keysym; +} + +static KeyCode dmxKeySymToKeyCode(DMXLocalInputInfoPtr dmxLocal, KeySym keySym, + int tryFirst) +{ + /* FIXME: this is quite ineffective, converting to a core map first and + * then extracting the info from there. It'd be better to run the actual + * xkb map */ + XkbSrvInfoPtr xkbi = dmxLocal->pDevice->key->xkbInfo; + KeySymsPtr pKeySyms = XkbGetCoreMap(dmxLocal->pDevice); + int i; + + /* Optimize for similar maps */ + if (XkbKeycodeInRange(xkbi->desc, tryFirst) + && pKeySyms->map[(tryFirst - xkbi->desc->min_key_code) + * pKeySyms->mapWidth] == keySym) + return tryFirst; + + for (i = pKeySyms->minKeyCode; i <= pKeySyms->maxKeyCode; i++) { + if (pKeySyms->map[(i - pKeySyms->minKeyCode) + * pKeySyms->mapWidth] == keySym) { + DMXDBG3("dmxKeySymToKeyCode: Translated keySym=0x%04x to" + " keyCode=%d (reverses to core keySym=0x%04x)\n", + keySym, i, dmxKeyCodeToKeySym(dmxLocalCoreKeyboard,i)); + return i; + } + } + return 0; +} + +static int dmxFixup(DevicePtr pDev, int detail, KeySym keySym) +{ + GETDMXLOCALFROMPDEV; + int keyCode; + + if (!dmxLocal->pDevice->key) { + dmxLog(dmxWarning, "dmxFixup: not a keyboard device (%s)\n", + dmxLocal->pDevice->name); + return NoSymbol; + } + if (!keySym) + keySym = dmxKeyCodeToKeySym(dmxLocal, detail); + if (keySym == NoSymbol) + return detail; + keyCode = dmxKeySymToKeyCode(dmxLocalCoreKeyboard, keySym, detail); + + return keyCode ? keyCode : detail; +} + +/** Enqueue an event from the \a pDev device with the + * specified \a type and \a detail. If the event is a KeyPress or + * KeyRelease event, then the \a keySym is also specified. + * + * FIXME: make the code do what the comment says, or remove this comment. + * If \a block is set to \a DMX_BLOCK, then the SIGIO handler will be + * blocked around calls to dmxeqEnqueue(). */ + +void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, + XEvent *e, DMXBlockType block) +{ + GETDMXINPUTFROMPDEV; + xEvent xE; + DeviceIntPtr p = dmxLocal->pDevice; + int valuators[3]; + ValuatorMask mask; + + DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail); + + switch (type) { + case KeyPress: + case KeyRelease: + if (!keySym) + keySym = dmxKeyCodeToKeySym(dmxLocal, detail); + if (dmxCheckFunctionKeys(dmxLocal, type, keySym)) + return; + if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard) + xE.u.u.detail = dmxFixup(pDev, detail, keySym); + + /*ErrorF("KEY %d sym %d\n", detail, (int) keySym);*/ + QueueKeyboardEvents(p, type, detail, NULL); + return; + + case ButtonPress: + case ButtonRelease: + detail = dmxGetButtonMapping(dmxLocal, detail); + valuator_mask_zero(&mask); + QueuePointerEvents(p, type, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); + return; + + case MotionNotify: + valuators[0] = e->xmotion.x; + valuators[1] = e->xmotion.y; + valuators[2] = e->xmotion.state; /* FIXME: WTF?? */ + valuator_mask_set_range(&mask, 0, 3, valuators); + QueuePointerEvents(p, type, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); + return; + + case EnterNotify: + case LeaveNotify: + case KeymapNotify: + case MappingNotify: /* This is sent because we change the + * modifier map on the backend/console + * input device so that we have complete + * control of the input device LEDs. */ + return; + default: + if (type == ProximityIn || type == ProximityOut) { + if (dmxLocal->sendsCore) + return; /* Not a core event */ + break; + } + if (type >= LASTEvent) { + if (dmxTranslateAndEnqueueExtEvent(dmxLocal, e, block)) + dmxLogInput(dmxInput, "Unhandled extension event: %d\n", type); + } else { + dmxLogInput(dmxInput, "Unhandled event: %d (%s)\n", + type, dmxEventName(type)); + } + return; + } + +} + +/** A pointer to this routine is passed to low-level input drivers so + * that all special keychecking is unified to this file. This function + * returns 0 if no special keys have been pressed. If the user has + * requested termination of the DMX server, -1 is returned. If the user + * has requested a switch to a VT, then the (1-based) number of that VT + * is returned. */ +int dmxCheckSpecialKeys(DevicePtr pDev, KeySym keySym) +{ + GETDMXINPUTFROMPDEV; + int vt = 0; + unsigned short state = 0; + + if (dmxLocal->sendsCore) + state = XkbStateFieldFromRec(&dmxLocalCoreKeyboard->pDevice->key->xkbInfo->state); + else if (dmxLocal->pDevice->key) + state = XkbStateFieldFromRec(&dmxLocal->pDevice->key->xkbInfo->state); + + if (!dmxLocal->sendsCore) return 0; /* Only for core devices */ + + DMXDBG2("dmxCheckSpecialKeys: keySym=0x%04x state=0x%04x\n", keySym,state); + + if ((state & (ControlMask|Mod1Mask)) != (ControlMask|Mod1Mask)) return 0; + + switch (keySym) { + case XK_F1: + case XK_F2: + case XK_F3: + case XK_F4: + case XK_F5: + case XK_F6: + case XK_F7: + case XK_F8: + case XK_F9: + case XK_F10: + vt = keySym - XK_F1 + 1; + break; + + case XK_F11: + case XK_F12: + vt = keySym - XK_F11 + 11; + break; + + case XK_q: /* To avoid confusion */ + case XK_BackSpace: + case XK_Delete: + case XK_KP_Delete: + dmxLog(dmxInfo, "User request for termination\n"); + dispatchException |= DE_TERMINATE; + return -1; /* Terminate */ + } + + if (vt) { + dmxLog(dmxInfo, "Request to switch to VT %d\n", vt); + dmxInput->vt_switch_pending = vt; + return vt; + } + + return 0; /* Do nothing */ +} |