summaryrefslogtreecommitdiff
path: root/xserver/dix
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 18:19:47 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 18:19:47 +0000
commit04f51aaa1f5b0cac419d2891812446c790b9c581 (patch)
tree7d104a653aff8d7488bc039ba435118115c18807 /xserver/dix
parent4a168ba45f33263ee86fc398ff32f108cffb1330 (diff)
Importing xserver from X.Org 7.2RC2
Diffstat (limited to 'xserver/dix')
-rw-r--r--xserver/dix/BuiltInAtoms329
-rw-r--r--xserver/dix/CHANGES17
-rw-r--r--xserver/dix/Makefile.am40
-rw-r--r--xserver/dix/Makefile.in853
-rw-r--r--xserver/dix/atom.c213
-rw-r--r--xserver/dix/buildatoms43
-rw-r--r--xserver/dix/colormap.c2699
-rw-r--r--xserver/dix/cursor.c457
-rw-r--r--xserver/dix/devices.c1613
-rw-r--r--xserver/dix/dispatch.c3992
-rw-r--r--xserver/dix/dispatch.h146
-rw-r--r--xserver/dix/dixfonts.c2133
-rw-r--r--xserver/dix/dixutils.c938
-rw-r--r--xserver/dix/events.c4599
-rw-r--r--xserver/dix/extension.c484
-rw-r--r--xserver/dix/ffs.c36
-rw-r--r--xserver/dix/gc.c1286
-rw-r--r--xserver/dix/globals.c161
-rw-r--r--xserver/dix/glyphcurs.c193
-rw-r--r--xserver/dix/grabs.c436
-rw-r--r--xserver/dix/initatoms.c84
-rw-r--r--xserver/dix/main.c792
-rw-r--r--xserver/dix/pixmap.c151
-rw-r--r--xserver/dix/privates.c456
-rw-r--r--xserver/dix/property.c683
-rw-r--r--xserver/dix/resource.c903
-rw-r--r--xserver/dix/strcasecmp.c48
-rw-r--r--xserver/dix/swaprep.c1299
-rw-r--r--xserver/dix/swapreq.c1100
-rw-r--r--xserver/dix/tables.c527
-rw-r--r--xserver/dix/window.c3924
-rw-r--r--xserver/dix/xpstubs.c79
32 files changed, 30714 insertions, 0 deletions
diff --git a/xserver/dix/BuiltInAtoms b/xserver/dix/BuiltInAtoms
new file mode 100644
index 000000000..910c62706
--- /dev/null
+++ b/xserver/dix/BuiltInAtoms
@@ -0,0 +1,329 @@
+File: .../x11/server/dix/BuiltInAtoms
+
+This file is of a fixed format and is used to generate both the file
+include/XAtom.h and dix/initatoms.c. Neither of those files should be
+edited directly. Changing the atoms in this file, or even the order in
+which they occur, is equivalent to forcing a new (minor) version number
+on the server. Take care.
+
+The format of the file is that each built in atom starts in column 1
+with no text, other than spaces and tabs, on that line other than a
+mandatory trailing "@" at the end of the line. For each atom (Foo)
+below the defines will be of the form
+ #define XA_Foo <n>
+and the string value of the atom will be "Foo".
+
+The comment lines in this file are not guaranteed to be accurate. To see the
+current truth, look at the Xlib documentation as well as the protocol spec.
+
+Atoms occur in five distinct name spaces within the protocol. Any particular
+atom may or may not have some client interpretation within each of the name
+spaces. For each of the built in atoms, the intended semantics and the space
+within which it is defined is indicated.
+
+Those name spaces are
+ Property names
+ Property types
+ Selections
+ Font properties
+ Type of a ClientMessage event (none built into server)
+
+For the font properties mentioned here, see the spec for more information.
+
+ -- Selections --
+
+PRIMARY @
+ Selection.
+SECONDARY @
+ Selection.
+
+ -- Property types and names --
+
+ARC @
+ Property type:
+ x, y: INT16
+ width, height: CARD16,
+ angle1, angle2: INT16
+ATOM @
+ Property type:
+ atom: ATOM
+BITMAP @
+ Property type:
+ bitmap: PIXMAP
+ This is asserted to be of depth 1.
+CARDINAL @
+ Property type:
+ card: CARD32 or CARD16 or CARD8
+ the datum size is dependent on the property format
+COLORMAP @
+ Property type:
+ colormap: COLORMAP
+CURSOR @
+ Property type:
+ cursor: CURSOR
+CUT_BUFFER0 @
+CUT_BUFFER1 @
+CUT_BUFFER2 @
+CUT_BUFFER3 @
+CUT_BUFFER4 @
+CUT_BUFFER5 @
+CUT_BUFFER6 @
+CUT_BUFFER7 @
+ Property name: (type: STRING)
+ Used to implement cut buffer ring, in particular Andrew uses
+ this mechanism. Anyone else using this sort of IPC mechanism
+ should use these properties.
+
+ Data is normally fetched and stored out of CUT_BUFFER0; the
+ RotateProperties request is used to rotate these buffers.
+DRAWABLE @
+ Property type:
+ drawable: DRAWABLE
+FONT @
+ Property type:
+ font: FONT
+INTEGER @
+ Property type:
+ card: INT32 or INT16 or INT8
+ the datum size is dependent on the property format
+PIXMAP @
+ Property type:
+ pixmap: PIXMAP
+POINT @
+ Property type:
+ x, y: INT16
+RECTANGLE @
+ Property type:
+ x, y: INT16
+ width, height: CARD16
+RESOURCE_MANAGER @
+ Property name: (type: STRING)
+ Contents of the user's resource manager data base.
+RGB_COLOR_MAP @
+ Property type:
+ colormap: COLORMAP
+ red-max: CARD32
+ red-mult: CARD32
+ green-max: CARD32
+ green-mult: CARD32
+ blue-max: CARD32
+ blue-mult: CARD32
+ base-pixel: CARD32
+
+ The fields `red_max', `green_max', and `blue_max' give the maximum
+ red, green, and blue values, respectively. Each color
+ coefficient ranges from 0 to its max, inclusive. For example,
+ a common colormap allocation is 3/3/2: 3 planes for red, 3
+ planes for green, and 2 planes for blue. Such a colormap would
+ have red_max == 7, green_max = 7, and blue_max = 3. An alternate
+ allocation that uses only 216 colors is red_max = 5, green_max =
+ 5, and blue_max = 5.
+
+ The fields `red_mult', `green_mult', and `blue_mult' give the
+ scale factors used to compose a full pixel value. (See next
+ paragraph.) For a 3/3/2 allocation red_mult might be 32,
+ green_mult might be 4, and blue_mult might be 1. For a
+ 6-colors-each allocation, red_mult might be 36, green_mult might
+ be 6, and blue_mult might be 1.
+
+ The field `base_pixel' gives the base pixel value used to
+ compose a full pixel value. Normally base_pixel is obtained
+ from a call to XAllocColorPlanes(). Given integer red, green,
+ and blue coefficients in their appropriate ranges, one can
+ compute a corresponding pixel value with the expression:
+
+ r * red_mult + g * green_mult + b * blue_mult + base_pixel
+
+ For gray-scale colormaps, only the colormap, red_max, red_mult,
+ and base_pixel fields are defined; the other fields are
+ ignored. To compute a gray-scale pixel value, use:
+
+ gray * red_mult + base_pixel
+
+ This is provided to allow applications to share color maps.
+
+RGB_BEST_MAP @
+RGB_BLUE_MAP @
+RGB_DEFAULT_MAP @
+RGB_GRAY_MAP @
+RGB_GREEN_MAP @
+RGB_RED_MAP @
+ Property name: (type: RGB_COLOR_MAP)
+ The needs of most applications can be met with five colormaps.
+ Polite applications may need only a small RGB space, and can
+ use a portion of the default color map. Applications doing
+ high-quality RGB rendering will need an entire colormap,
+ filled with as large an RGB space as possible, e.g. 332. For
+ color separations, an application may need maximum device
+ resolution for each of red, green, and blue, even if this
+ requires three renderings with three colormaps.
+
+ Each of the above five names would be used for sharing color
+ maps.
+STRING @
+ Property type:
+ sequence of Bytes
+VISUALID @
+ Property type:
+ visual: VISUALID
+WINDOW @
+ Property type:
+ window: WINDOW
+WM_COMMAND @
+ Property name: (type: STRING)
+ Command line arguments used to invoke this application. The
+ arguments are delimited by null characters (ASCII 0).
+WM_HINTS @
+ Property type:
+ flags: CARD32
+ input: BOOL32
+ initial-state: CARD32
+ icon-pixmap: PIXMAP
+ icon-window: WINDOW
+ icon_mask: BITMAP
+ icon-x, icon-y: INT32
+ flags contains the following bits
+ 0x00000001 input hint
+ 0x00000002 state hint
+ 0x00000004 icon pixmap hint
+ 0x00000008 icon window hint
+ 0x00000010 icon position hint
+ values for initial-state
+ 0 unspecified -> application does not
+ care and WM should pick one.
+ 1 normal
+ 2 zoomed
+ 3 iconic
+ 4 inactive -> application believes
+ itself to be seldomly used. WM may wish to
+ place it on an inactive menu.
+ This type is potentially extensible. The order is critical;
+ append to the end only.
+ Property name: (type: WM_HINTS)
+ Additional hints set by the client for use by the window
+ manager.
+WM_CLIENT_MACHINE @
+ Property name: (type: STRING)
+ used to communicate with the window manager. The host name
+ of the machine the client is running on may be set here.
+WM_ICON_NAME @
+ Property name: (type: STRING)
+ what the application would like the label to be for
+ the iconic form of the window.
+WM_ICON_SIZE @
+ Property type:
+ minWidth, min-height: CARD32
+ maxWidth, max-height: CARD32
+ widthInc, height-inc: CARD32
+ Property name: (type: ICON_SIZE)
+ The window manager may set this property on the root window
+ to specify the icon sizes it allows.
+WM_NAME @
+ Property name: (type: STRING)
+ used to communicate with the window manager. This is
+ what the application would like the label for the window.
+WM_NORMAL_HINTS @
+ Property name: (type: SIZE_HINTS)
+ used to communicate with the window manager. This is size
+ hints for a window in its "normal" state.
+WM_SIZE_HINTS @
+ Property type:
+ flags: CARD32
+ x, y: INT32
+ width, height: CARD32
+ min-width, min-height: CARD32
+ max-width, max-height: CARD32
+ width-inc, height-inc: CARD32
+ min-aspect-x, min-aspect-y: CARD32
+ max-aspect-x, max-aspect-y: CARD32
+ flags contains the following bits
+ 0x00000001 user specified x and y
+ 0x00000002 user specified width and height
+ 0x00000004 program specified position
+ 0x00000008 program specified size
+ 0x00000010 program specified minimum size
+ 0x00000020 program specified maximum size
+ 0x00000040 program specified resize increment
+ 0x00000080 program specified aspect ratio
+ This type is potentially extensible. The order is critical;
+ append to the end only.
+WM_ZOOM_HINTS @
+ Property name: (type: SIZE_HINTS)
+ used to communicate with the window manager. This is size
+ hints for a window in its "zoomed" state.
+
+ -- Font properties --
+
+MIN_SPACE @
+ Font property: CARD32
+NORM_SPACE @
+ Font property: CARD32
+MAX_SPACE @
+ Font property: CARD32
+END_SPACE @
+ Font property: CARD32
+SUPERSCRIPT_X @
+ Font property: INT32
+SUPERSCRIPT_Y @
+ Font property: INT32
+SUBSCRIPT_X @
+ Font property: INT32
+SUBSCRIPT_Y @
+ Font property: INT32
+UNDERLINE_POSITION @
+ Font property: INT32
+UNDERLINE_THICKNESS @
+ Font property: CARD32
+STRIKEOUT_ASCENT @
+ Font property: INT32
+STRIKEOUT_DESCENT @
+ Font property: INT32
+ITALIC_ANGLE @
+ Font property: INT32
+X_HEIGHT @
+ Font property: INT32
+QUAD_WIDTH @
+ Font property: INT32
+WEIGHT @
+ Font property: CARD32
+POINT_SIZE @
+ Font property: CARD32
+RESOLUTION @
+ Font property: CARD32
+
+The following optional properties on fonts have values that are atoms. The
+atom print name is the useful information.
+
+COPYRIGHT @
+ of the font distribution
+NOTICE @
+ trademark/copyright of the character shapes
+FONT_NAME @
+ name of this particular instance of a font
+FAMILY_NAME @
+ name of the 'font family' to which it belongs
+FULL_NAME @
+ full text name of the font
+
+The following aren't in order but putting them at the end avoids encoding
+changes.
+
+CAP_HEIGHT @
+ Font property: CARD32
+
+
+WM_CLASS @
+ Property name: (type: STRING)
+ Used (possibly by some window managers; definitely by
+ session managers) to look up resources in the resource
+ data base on behalf of the client who set this property.
+ There are 2 elements:
+ {char *resource_name; char *resource_class;}
+ delimited by a null character (ascii 0)
+
+WM_TRANSIENT_FOR @
+ Property name: (type: WINDOW)
+ Used by transient top-level windows, such as dialog
+ boxes, to point to their logical "parents". The window
+ manager can then take down the dialog boxes when the
+ "parent" gets iconified, for instance.
diff --git a/xserver/dix/CHANGES b/xserver/dix/CHANGES
new file mode 100644
index 000000000..d8fb7c31a
--- /dev/null
+++ b/xserver/dix/CHANGES
@@ -0,0 +1,17 @@
+The following changes have been made to this directory since R3 (for
+a full description, see doc/Server/r4.tbl.ms):
+
+ o Windows restructured (memory reduction, devPrivates and speedups)
+ o GCs restructured (memory reduction, devPrivates and wrappers)
+ o Screens restructured (window ops merged in, devPrivates)
+ o Pixmaps restructured (drawable changes mostly)
+ o Cursors restructured (shares glyph bits now)
+ o Visuals restructured (screen index removed, fields rearranged)
+ o Devices restructured (input extension changes)
+ o Out of memory changes. Many interfaces now return OutOfMemory
+ status.
+ o Synchronous grab code rewritten. Should conform to our
+ understanding of the protocol now. Be careful when time
+ stamping events (don't allow time to run backwards).
+ o Resource types redesigned and rewritten.
+ o Internal fake color allocation routine for software cursors.
diff --git a/xserver/dix/Makefile.am b/xserver/dix/Makefile.am
new file mode 100644
index 000000000..d26d9ea7a
--- /dev/null
+++ b/xserver/dix/Makefile.am
@@ -0,0 +1,40 @@
+noinst_LTLIBRARIES = libdix.la libxpstubs.la
+
+AM_CFLAGS = $(DIX_CFLAGS) \
+ -DVENDOR_STRING=\""@VENDOR_STRING@"\" \
+ -DVENDOR_RELEASE="@VENDOR_RELEASE@"
+
+libdix_la_SOURCES = \
+ atom.c \
+ colormap.c \
+ cursor.c \
+ devices.c \
+ dispatch.c \
+ dispatch.h \
+ dixfonts.c \
+ dixutils.c \
+ events.c \
+ extension.c \
+ ffs.c \
+ gc.c \
+ globals.c \
+ glyphcurs.c \
+ grabs.c \
+ initatoms.c \
+ main.c \
+ pixmap.c \
+ privates.c \
+ property.c \
+ resource.c \
+ swaprep.c \
+ swapreq.c \
+ tables.c \
+ window.c \
+ strcasecmp.c
+
+libxpstubs_la_SOURCES = \
+ xpstubs.c
+
+INCLUDES = -I$(top_srcdir)/Xprint
+
+EXTRA_DIST = buildatoms BuiltInAtoms CHANGES
diff --git a/xserver/dix/Makefile.in b/xserver/dix/Makefile.in
new file mode 100644
index 000000000..e3f3a7bd7
--- /dev/null
+++ b/xserver/dix/Makefile.in
@@ -0,0 +1,853 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = dix
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \
+ $(top_builddir)/include/xorg-server.h \
+ $(top_builddir)/include/dix-config.h \
+ $(top_builddir)/include/xgl-config.h \
+ $(top_builddir)/include/xorg-config.h \
+ $(top_builddir)/include/xkb-config.h \
+ $(top_builddir)/include/xwin-config.h \
+ $(top_builddir)/include/kdrive-config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdix_la_LIBADD =
+am_libdix_la_OBJECTS = atom.lo colormap.lo cursor.lo devices.lo \
+ dispatch.lo dixfonts.lo dixutils.lo events.lo extension.lo \
+ ffs.lo gc.lo globals.lo glyphcurs.lo grabs.lo initatoms.lo \
+ main.lo pixmap.lo privates.lo property.lo resource.lo \
+ swaprep.lo swapreq.lo tables.lo window.lo strcasecmp.lo
+libdix_la_OBJECTS = $(am_libdix_la_OBJECTS)
+libxpstubs_la_LIBADD =
+am_libxpstubs_la_OBJECTS = xpstubs.lo
+libxpstubs_la_OBJECTS = $(am_libxpstubs_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libdix_la_SOURCES) $(libxpstubs_la_SOURCES)
+DIST_SOURCES = $(libdix_la_SOURCES) $(libxpstubs_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
+ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
+AFB_FALSE = @AFB_FALSE@
+AFB_TRUE = @AFB_TRUE@
+AGP_FALSE = @AGP_FALSE@
+AGP_TRUE = @AGP_TRUE@
+AIGLX_FALSE = @AIGLX_FALSE@
+AIGLX_TRUE = @AIGLX_TRUE@
+ALLOCA = @ALLOCA@
+ALPHA_VIDEO_FALSE = @ALPHA_VIDEO_FALSE@
+ALPHA_VIDEO_TRUE = @ALPHA_VIDEO_TRUE@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+APPDEFAULTDIR = @APPDEFAULTDIR@
+APPGROUP_FALSE = @APPGROUP_FALSE@
+APPGROUP_TRUE = @APPGROUP_TRUE@
+APP_MAN_DIR = @APP_MAN_DIR@
+APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
+AR = @AR@
+ARM_VIDEO_FALSE = @ARM_VIDEO_FALSE@
+ARM_VIDEO_TRUE = @ARM_VIDEO_TRUE@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASE_FONT_PATH = @BASE_FONT_PATH@
+BSD_KBD_MODE_FALSE = @BSD_KBD_MODE_FALSE@
+BSD_KBD_MODE_TRUE = @BSD_KBD_MODE_TRUE@
+BUILDDOCS_FALSE = @BUILDDOCS_FALSE@
+BUILDDOCS_TRUE = @BUILDDOCS_TRUE@
+BUILD_DATE = @BUILD_DATE@
+BUILD_KBD_MODE_FALSE = @BUILD_KBD_MODE_FALSE@
+BUILD_KBD_MODE_TRUE = @BUILD_KBD_MODE_TRUE@
+BUILD_LINUXDOC_FALSE = @BUILD_LINUXDOC_FALSE@
+BUILD_LINUXDOC_TRUE = @BUILD_LINUXDOC_TRUE@
+BUILD_PDFDOC_FALSE = @BUILD_PDFDOC_FALSE@
+BUILD_PDFDOC_TRUE = @BUILD_PDFDOC_TRUE@
+BUILD_XORGCFG_FALSE = @BUILD_XORGCFG_FALSE@
+BUILD_XORGCFG_TRUE = @BUILD_XORGCFG_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFB_FALSE = @CFB_FALSE@
+CFB_TRUE = @CFB_TRUE@
+CFLAGS = @CFLAGS@
+COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@
+COMPOSITE_FALSE = @COMPOSITE_FALSE@
+COMPOSITE_TRUE = @COMPOSITE_TRUE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CUP_FALSE = @CUP_FALSE@
+CUP_TRUE = @CUP_TRUE@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBE_FALSE = @DBE_FALSE@
+DBE_TRUE = @DBE_TRUE@
+DEBUG_FALSE = @DEBUG_FALSE@
+DEBUG_TRUE = @DEBUG_TRUE@
+DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@
+DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DGA_FALSE = @DGA_FALSE@
+DGA_TRUE = @DGA_TRUE@
+DIX_CFLAGS = @DIX_CFLAGS@
+DLLTOOL = @DLLTOOL@
+DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@
+DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@
+DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@
+DMXMODULES_LIBS = @DMXMODULES_LIBS@
+DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@
+DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@
+DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@
+DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@
+DMX_BUILD_LNX_FALSE = @DMX_BUILD_LNX_FALSE@
+DMX_BUILD_LNX_TRUE = @DMX_BUILD_LNX_TRUE@
+DMX_BUILD_USB_FALSE = @DMX_BUILD_USB_FALSE@
+DMX_BUILD_USB_TRUE = @DMX_BUILD_USB_TRUE@
+DMX_FALSE = @DMX_FALSE@
+DMX_TRUE = @DMX_TRUE@
+DPMSExtension_FALSE = @DPMSExtension_FALSE@
+DPMSExtension_TRUE = @DPMSExtension_TRUE@
+DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@
+DRIPROTO_LIBS = @DRIPROTO_LIBS@
+DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
+DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DRI_DRIVER_PATH = @DRI_DRIVER_PATH@
+DRI_FALSE = @DRI_FALSE@
+DRI_TRUE = @DRI_TRUE@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EVI_FALSE = @EVI_FALSE@
+EVI_TRUE = @EVI_TRUE@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FBDEVHW_FALSE = @FBDEVHW_FALSE@
+FBDEVHW_TRUE = @FBDEVHW_TRUE@
+FFLAGS = @FFLAGS@
+FILE_MAN_DIR = @FILE_MAN_DIR@
+FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+FONTCACHE_FALSE = @FONTCACHE_FALSE@
+FONTCACHE_TRUE = @FONTCACHE_TRUE@
+FREEBSD_KLDLOAD_FALSE = @FREEBSD_KLDLOAD_FALSE@
+FREEBSD_KLDLOAD_TRUE = @FREEBSD_KLDLOAD_TRUE@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GLX_DEFINES = @GLX_DEFINES@
+GLX_FALSE = @GLX_FALSE@
+GLX_TRUE = @GLX_TRUE@
+GL_CFLAGS = @GL_CFLAGS@
+GL_LIBS = @GL_LIBS@
+H3600_TS_FALSE = @H3600_TS_FALSE@
+H3600_TS_TRUE = @H3600_TS_TRUE@
+I386_VIDEO_FALSE = @I386_VIDEO_FALSE@
+I386_VIDEO_TRUE = @I386_VIDEO_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_LIBXF86CONFIG_FALSE = @INSTALL_LIBXF86CONFIG_FALSE@
+INSTALL_LIBXF86CONFIG_TRUE = @INSTALL_LIBXF86CONFIG_TRUE@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_SETUID_FALSE = @INSTALL_SETUID_FALSE@
+INSTALL_SETUID_TRUE = @INSTALL_SETUID_TRUE@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INT10_STUB_FALSE = @INT10_STUB_FALSE@
+INT10_STUB_TRUE = @INT10_STUB_TRUE@
+INT10_VM86_FALSE = @INT10_VM86_FALSE@
+INT10_VM86_TRUE = @INT10_VM86_TRUE@
+INT10_X86EMU_FALSE = @INT10_X86EMU_FALSE@
+INT10_X86EMU_TRUE = @INT10_X86EMU_TRUE@
+KDRIVEFBDEV_FALSE = @KDRIVEFBDEV_FALSE@
+KDRIVEFBDEV_TRUE = @KDRIVEFBDEV_TRUE@
+KDRIVEVESA_FALSE = @KDRIVEVESA_FALSE@
+KDRIVEVESA_TRUE = @KDRIVEVESA_TRUE@
+KDRIVE_CFLAGS = @KDRIVE_CFLAGS@
+KDRIVE_FALSE = @KDRIVE_FALSE@
+KDRIVE_HW_FALSE = @KDRIVE_HW_FALSE@
+KDRIVE_HW_TRUE = @KDRIVE_HW_TRUE@
+KDRIVE_INCS = @KDRIVE_INCS@
+KDRIVE_LIBS = @KDRIVE_LIBS@
+KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@
+KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@
+KDRIVE_TRUE = @KDRIVE_TRUE@
+LDFLAGS = @LDFLAGS@
+LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
+LIBDRM_LIBS = @LIBDRM_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_MAN_DIR = @LIB_MAN_DIR@
+LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
+LINUXDOC = @LINUXDOC@
+LINUX_ALPHA_FALSE = @LINUX_ALPHA_FALSE@
+LINUX_ALPHA_TRUE = @LINUX_ALPHA_TRUE@
+LINUX_IA64_FALSE = @LINUX_IA64_FALSE@
+LINUX_IA64_TRUE = @LINUX_IA64_TRUE@
+LNXACPI_FALSE = @LNXACPI_FALSE@
+LNXACPI_TRUE = @LNXACPI_TRUE@
+LNXAPM_FALSE = @LNXAPM_FALSE@
+LNXAPM_TRUE = @LNXAPM_TRUE@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MAKE_HTML = @MAKE_HTML@
+MAKE_PDF = @MAKE_PDF@
+MAKE_PS = @MAKE_PS@
+MAKE_TEXT = @MAKE_TEXT@
+MESA_SOURCE = @MESA_SOURCE@
+MFB_FALSE = @MFB_FALSE@
+MFB_TRUE = @MFB_TRUE@
+MISC_MAN_DIR = @MISC_MAN_DIR@
+MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
+MITSHM_FALSE = @MITSHM_FALSE@
+MITSHM_TRUE = @MITSHM_TRUE@
+MKFONTDIR = @MKFONTDIR@
+MKFONTSCALE = @MKFONTSCALE@
+MMX_CAPABLE_FALSE = @MMX_CAPABLE_FALSE@
+MMX_CAPABLE_TRUE = @MMX_CAPABLE_TRUE@
+MULTIBUFFER_FALSE = @MULTIBUFFER_FALSE@
+MULTIBUFFER_TRUE = @MULTIBUFFER_TRUE@
+NEED_STRLCAT_FALSE = @NEED_STRLCAT_FALSE@
+NEED_STRLCAT_TRUE = @NEED_STRLCAT_TRUE@
+NEED_VSNPRINTF_FALSE = @NEED_VSNPRINTF_FALSE@
+NEED_VSNPRINTF_TRUE = @NEED_VSNPRINTF_TRUE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PPC_VIDEO_FALSE = @PPC_VIDEO_FALSE@
+PPC_VIDEO_TRUE = @PPC_VIDEO_TRUE@
+PROJECTROOT = @PROJECTROOT@
+PS2PDF = @PS2PDF@
+RANLIB = @RANLIB@
+RAWCPP = @RAWCPP@
+RAWCPPFLAGS = @RAWCPPFLAGS@
+RECORD_FALSE = @RECORD_FALSE@
+RECORD_TRUE = @RECORD_TRUE@
+RES_FALSE = @RES_FALSE@
+RES_TRUE = @RES_TRUE@
+RGB_DB = @RGB_DB@
+SCREENSAVER_FALSE = @SCREENSAVER_FALSE@
+SCREENSAVER_TRUE = @SCREENSAVER_TRUE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@
+SOLARIS_ASM_INLINE_FALSE = @SOLARIS_ASM_INLINE_FALSE@
+SOLARIS_ASM_INLINE_TRUE = @SOLARIS_ASM_INLINE_TRUE@
+SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@
+SOLARIS_USL_CONSOLE_FALSE = @SOLARIS_USL_CONSOLE_FALSE@
+SOLARIS_USL_CONSOLE_TRUE = @SOLARIS_USL_CONSOLE_TRUE@
+SPARC64_VIDEO_FALSE = @SPARC64_VIDEO_FALSE@
+SPARC64_VIDEO_TRUE = @SPARC64_VIDEO_TRUE@
+STRIP = @STRIP@
+SUN_KBD_MODE_FALSE = @SUN_KBD_MODE_FALSE@
+SUN_KBD_MODE_TRUE = @SUN_KBD_MODE_TRUE@
+SYS_LIBS = @SYS_LIBS@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_FALSE = @TSLIB_FALSE@
+TSLIB_LIBS = @TSLIB_LIBS@
+TSLIB_TRUE = @TSLIB_TRUE@
+USE_CURSES_FALSE = @USE_CURSES_FALSE@
+USE_CURSES_TRUE = @USE_CURSES_TRUE@
+USE_RGB_BUILTIN_FALSE = @USE_RGB_BUILTIN_FALSE@
+USE_RGB_BUILTIN_TRUE = @USE_RGB_BUILTIN_TRUE@
+VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@
+VENDOR_RELEASE = @VENDOR_RELEASE@
+VENDOR_STRING = @VENDOR_STRING@
+VENDOR_STRING_SHORT = @VENDOR_STRING_SHORT@
+VERSION = @VERSION@
+X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
+X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
+XACE_FALSE = @XACE_FALSE@
+XACE_TRUE = @XACE_TRUE@
+XCALIBRATE_FALSE = @XCALIBRATE_FALSE@
+XCALIBRATE_TRUE = @XCALIBRATE_TRUE@
+XCSECURITY_FALSE = @XCSECURITY_FALSE@
+XCSECURITY_TRUE = @XCSECURITY_TRUE@
+XDMAUTH_FALSE = @XDMAUTH_FALSE@
+XDMAUTH_TRUE = @XDMAUTH_TRUE@
+XDMCP_CFLAGS = @XDMCP_CFLAGS@
+XDMCP_FALSE = @XDMCP_FALSE@
+XDMCP_LIBS = @XDMCP_LIBS@
+XDMCP_TRUE = @XDMCP_TRUE@
+XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@
+XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@
+XDMX_LIBS = @XDMX_LIBS@
+XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@
+XEGLMODULES_LIBS = @XEGLMODULES_LIBS@
+XEGL_FALSE = @XEGL_FALSE@
+XEGL_LIBS = @XEGL_LIBS@
+XEGL_TRUE = @XEGL_TRUE@
+XEPHYR_CFLAGS = @XEPHYR_CFLAGS@
+XEPHYR_FALSE = @XEPHYR_FALSE@
+XEPHYR_INCS = @XEPHYR_INCS@
+XEPHYR_LIBS = @XEPHYR_LIBS@
+XEPHYR_TRUE = @XEPHYR_TRUE@
+XEVIE_FALSE = @XEVIE_FALSE@
+XEVIE_TRUE = @XEVIE_TRUE@
+XF86BIGFONT_FALSE = @XF86BIGFONT_FALSE@
+XF86BIGFONT_TRUE = @XF86BIGFONT_TRUE@
+XF86CONFIGFILE = @XF86CONFIGFILE@
+XF86UTILS_FALSE = @XF86UTILS_FALSE@
+XF86UTILS_TRUE = @XF86UTILS_TRUE@
+XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@
+XGLMODULES_LIBS = @XGLMODULES_LIBS@
+XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@
+XGLXMODULES_LIBS = @XGLXMODULES_LIBS@
+XGLX_FALSE = @XGLX_FALSE@
+XGLX_LIBS = @XGLX_LIBS@
+XGLX_TRUE = @XGLX_TRUE@
+XGL_FALSE = @XGL_FALSE@
+XGL_LIBS = @XGL_LIBS@
+XGL_MODULE_PATH = @XGL_MODULE_PATH@
+XGL_TRUE = @XGL_TRUE@
+XINERAMA_FALSE = @XINERAMA_FALSE@
+XINERAMA_TRUE = @XINERAMA_TRUE@
+XINPUT_FALSE = @XINPUT_FALSE@
+XINPUT_TRUE = @XINPUT_TRUE@
+XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@
+XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@
+XKB_COMPILED_DIR = @XKB_COMPILED_DIR@
+XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@
+XLIB_CFLAGS = @XLIB_CFLAGS@
+XLIB_LIBS = @XLIB_LIBS@
+XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@
+XNESTMODULES_LIBS = @XNESTMODULES_LIBS@
+XNEST_FALSE = @XNEST_FALSE@
+XNEST_LIBS = @XNEST_LIBS@
+XNEST_TRUE = @XNEST_TRUE@
+XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@
+XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@
+XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@
+XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@
+XORG_BUS_FREEBSDPCI_FALSE = @XORG_BUS_FREEBSDPCI_FALSE@
+XORG_BUS_FREEBSDPCI_TRUE = @XORG_BUS_FREEBSDPCI_TRUE@
+XORG_BUS_IX86PCI_FALSE = @XORG_BUS_IX86PCI_FALSE@
+XORG_BUS_IX86PCI_TRUE = @XORG_BUS_IX86PCI_TRUE@
+XORG_BUS_LINUXPCI_FALSE = @XORG_BUS_LINUXPCI_FALSE@
+XORG_BUS_LINUXPCI_TRUE = @XORG_BUS_LINUXPCI_TRUE@
+XORG_BUS_NETBSDPCI_FALSE = @XORG_BUS_NETBSDPCI_FALSE@
+XORG_BUS_NETBSDPCI_TRUE = @XORG_BUS_NETBSDPCI_TRUE@
+XORG_BUS_PPCPCI_FALSE = @XORG_BUS_PPCPCI_FALSE@
+XORG_BUS_PPCPCI_TRUE = @XORG_BUS_PPCPCI_TRUE@
+XORG_BUS_SPARCPCI_FALSE = @XORG_BUS_SPARCPCI_FALSE@
+XORG_BUS_SPARCPCI_TRUE = @XORG_BUS_SPARCPCI_TRUE@
+XORG_BUS_SPARC_FALSE = @XORG_BUS_SPARC_FALSE@
+XORG_BUS_SPARC_TRUE = @XORG_BUS_SPARC_TRUE@
+XORG_CFLAGS = @XORG_CFLAGS@
+XORG_CORE_LIBS = @XORG_CORE_LIBS@
+XORG_FALSE = @XORG_FALSE@
+XORG_INCS = @XORG_INCS@
+XORG_LIBS = @XORG_LIBS@
+XORG_LOADER_SPARC_FALSE = @XORG_LOADER_SPARC_FALSE@
+XORG_LOADER_SPARC_TRUE = @XORG_LOADER_SPARC_TRUE@
+XORG_OS = @XORG_OS@
+XORG_OS_KBD = @XORG_OS_KBD@
+XORG_OS_SUBDIR = @XORG_OS_SUBDIR@
+XORG_TRUE = @XORG_TRUE@
+XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@
+XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@
+XPRINT_CFLAGS = @XPRINT_CFLAGS@
+XPRINT_FALSE = @XPRINT_FALSE@
+XPRINT_LIBS = @XPRINT_LIBS@
+XPRINT_TRUE = @XPRINT_TRUE@
+XP_USE_FREETYPE_FALSE = @XP_USE_FREETYPE_FALSE@
+XP_USE_FREETYPE_TRUE = @XP_USE_FREETYPE_TRUE@
+XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@
+XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@
+XSDLSERVER_FALSE = @XSDLSERVER_FALSE@
+XSDLSERVER_TRUE = @XSDLSERVER_TRUE@
+XSDL_INCS = @XSDL_INCS@
+XSDL_LIBS = @XSDL_LIBS@
+XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@
+XSERVERCFLAGS_LIBS = @XSERVERCFLAGS_LIBS@
+XSERVERLIBS_CFLAGS = @XSERVERLIBS_CFLAGS@
+XSERVERLIBS_LIBS = @XSERVERLIBS_LIBS@
+XSERVER_LIBS = @XSERVER_LIBS@
+XTRAP_FALSE = @XTRAP_FALSE@
+XTRAP_TRUE = @XTRAP_TRUE@
+XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@
+XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@
+XVFB_FALSE = @XVFB_FALSE@
+XVFB_LIBS = @XVFB_LIBS@
+XVFB_TRUE = @XVFB_TRUE@
+XVMC_FALSE = @XVMC_FALSE@
+XVMC_TRUE = @XVMC_TRUE@
+XV_FALSE = @XV_FALSE@
+XV_TRUE = @XV_TRUE@
+XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@
+XWINMODULES_LIBS = @XWINMODULES_LIBS@
+XWIN_CLIPBOARD_FALSE = @XWIN_CLIPBOARD_FALSE@
+XWIN_CLIPBOARD_TRUE = @XWIN_CLIPBOARD_TRUE@
+XWIN_FALSE = @XWIN_FALSE@
+XWIN_GLX_WINDOWS_FALSE = @XWIN_GLX_WINDOWS_FALSE@
+XWIN_GLX_WINDOWS_TRUE = @XWIN_GLX_WINDOWS_TRUE@
+XWIN_LIBS = @XWIN_LIBS@
+XWIN_MULTIWINDOWEXTWM_FALSE = @XWIN_MULTIWINDOWEXTWM_FALSE@
+XWIN_MULTIWINDOWEXTWM_TRUE = @XWIN_MULTIWINDOWEXTWM_TRUE@
+XWIN_MULTIWINDOW_FALSE = @XWIN_MULTIWINDOW_FALSE@
+XWIN_MULTIWINDOW_TRUE = @XWIN_MULTIWINDOW_TRUE@
+XWIN_NATIVEGDI_FALSE = @XWIN_NATIVEGDI_FALSE@
+XWIN_NATIVEGDI_TRUE = @XWIN_NATIVEGDI_TRUE@
+XWIN_PRIMARYFB_FALSE = @XWIN_PRIMARYFB_FALSE@
+XWIN_PRIMARYFB_TRUE = @XWIN_PRIMARYFB_TRUE@
+XWIN_RANDR_FALSE = @XWIN_RANDR_FALSE@
+XWIN_RANDR_TRUE = @XWIN_RANDR_TRUE@
+XWIN_SERVER_NAME = @XWIN_SERVER_NAME@
+XWIN_SYSTEM_LIBS = @XWIN_SYSTEM_LIBS@
+XWIN_TRUE = @XWIN_TRUE@
+XWIN_XV_FALSE = @XWIN_XV_FALSE@
+XWIN_XV_TRUE = @XWIN_XV_TRUE@
+YACC = @YACC@
+__XCONFIGFILE__ = @__XCONFIGFILE__@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_AS = @ac_ct_AS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DLLTOOL = @ac_ct_DLLTOOL@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+driverdir = @driverdir@
+exec_prefix = @exec_prefix@
+extdir = @extdir@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+logdir = @logdir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moduledir = @moduledir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sdkdir = @sdkdir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+xglmoduledir = @xglmoduledir@
+xpconfigdir = @xpconfigdir@
+noinst_LTLIBRARIES = libdix.la libxpstubs.la
+AM_CFLAGS = $(DIX_CFLAGS) \
+ -DVENDOR_STRING=\""@VENDOR_STRING@"\" \
+ -DVENDOR_RELEASE="@VENDOR_RELEASE@"
+
+libdix_la_SOURCES = \
+ atom.c \
+ colormap.c \
+ cursor.c \
+ devices.c \
+ dispatch.c \
+ dispatch.h \
+ dixfonts.c \
+ dixutils.c \
+ events.c \
+ extension.c \
+ ffs.c \
+ gc.c \
+ globals.c \
+ glyphcurs.c \
+ grabs.c \
+ initatoms.c \
+ main.c \
+ pixmap.c \
+ privates.c \
+ property.c \
+ resource.c \
+ swaprep.c \
+ swapreq.c \
+ tables.c \
+ window.c \
+ strcasecmp.c
+
+libxpstubs_la_SOURCES = \
+ xpstubs.c
+
+INCLUDES = -I$(top_srcdir)/Xprint
+EXTRA_DIST = buildatoms BuiltInAtoms CHANGES
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dix/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign dix/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libdix.la: $(libdix_la_OBJECTS) $(libdix_la_DEPENDENCIES)
+ $(LINK) $(libdix_la_LDFLAGS) $(libdix_la_OBJECTS) $(libdix_la_LIBADD) $(LIBS)
+libxpstubs.la: $(libxpstubs_la_OBJECTS) $(libxpstubs_la_DEPENDENCIES)
+ $(LINK) $(libxpstubs_la_LDFLAGS) $(libxpstubs_la_OBJECTS) $(libxpstubs_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/colormap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cursor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devices.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dispatch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dixfonts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dixutils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyphcurs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grabs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initatoms.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixmap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/privates.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/property.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resource.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcasecmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swaprep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swapreq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tables.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xpstubs.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/xserver/dix/atom.c b/xserver/dix/atom.c
new file mode 100644
index 000000000..d9d74f1da
--- /dev/null
+++ b/xserver/dix/atom.c
@@ -0,0 +1,213 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+#include <string.h>
+#include "misc.h"
+#include "resource.h"
+#include "dix.h"
+
+#define InitialTableSize 100
+
+typedef struct _Node {
+ struct _Node *left, *right;
+ Atom a;
+ unsigned int fingerPrint;
+ char *string;
+} NodeRec, *NodePtr;
+
+static Atom lastAtom = None;
+static NodePtr atomRoot = (NodePtr)NULL;
+static unsigned long tableLength;
+static NodePtr *nodeTable;
+
+void FreeAtom(NodePtr patom);
+
+_X_EXPORT Atom
+MakeAtom(char *string, unsigned len, Bool makeit)
+{
+ register NodePtr * np;
+ unsigned i;
+ int comp;
+ register unsigned int fp = 0;
+
+ np = &atomRoot;
+ for (i = 0; i < (len+1)/2; i++)
+ {
+ fp = fp * 27 + string[i];
+ fp = fp * 27 + string[len - 1 - i];
+ }
+ while (*np != (NodePtr) NULL)
+ {
+ if (fp < (*np)->fingerPrint)
+ np = &((*np)->left);
+ else if (fp > (*np)->fingerPrint)
+ np = &((*np)->right);
+ else
+ { /* now start testing the strings */
+ comp = strncmp(string, (*np)->string, (int)len);
+ if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string))))
+ np = &((*np)->left);
+ else if (comp > 0)
+ np = &((*np)->right);
+ else
+ return(*np)->a;
+ }
+ }
+ if (makeit)
+ {
+ register NodePtr nd;
+
+ nd = (NodePtr) xalloc(sizeof(NodeRec));
+ if (!nd)
+ return BAD_RESOURCE;
+ if (lastAtom < XA_LAST_PREDEFINED)
+ {
+ nd->string = string;
+ }
+ else
+ {
+ nd->string = (char *) xalloc(len + 1);
+ if (!nd->string) {
+ xfree(nd);
+ return BAD_RESOURCE;
+ }
+ strncpy(nd->string, string, (int)len);
+ nd->string[len] = 0;
+ }
+ if ((lastAtom + 1) >= tableLength) {
+ NodePtr *table;
+
+ table = (NodePtr *) xrealloc(nodeTable,
+ tableLength * (2 * sizeof(NodePtr)));
+ if (!table) {
+ if (nd->string != string)
+ xfree(nd->string);
+ xfree(nd);
+ return BAD_RESOURCE;
+ }
+ tableLength <<= 1;
+ nodeTable = table;
+ }
+ *np = nd;
+ nd->left = nd->right = (NodePtr) NULL;
+ nd->fingerPrint = fp;
+ nd->a = (++lastAtom);
+ *(nodeTable+lastAtom) = nd;
+ return nd->a;
+ }
+ else
+ return None;
+}
+
+_X_EXPORT Bool
+ValidAtom(Atom atom)
+{
+ return (atom != None) && (atom <= lastAtom);
+}
+
+_X_EXPORT char *
+NameForAtom(Atom atom)
+{
+ NodePtr node;
+ if (atom > lastAtom) return 0;
+ if ((node = nodeTable[atom]) == (NodePtr)NULL) return 0;
+ return node->string;
+}
+
+void
+AtomError()
+{
+ FatalError("initializing atoms");
+}
+
+void
+FreeAtom(NodePtr patom)
+{
+ if(patom->left)
+ FreeAtom(patom->left);
+ if(patom->right)
+ FreeAtom(patom->right);
+ if (patom->a > XA_LAST_PREDEFINED)
+ xfree(patom->string);
+ xfree(patom);
+}
+
+void
+FreeAllAtoms()
+{
+ if(atomRoot == (NodePtr)NULL)
+ return;
+ FreeAtom(atomRoot);
+ atomRoot = (NodePtr)NULL;
+ xfree(nodeTable);
+ nodeTable = (NodePtr *)NULL;
+ lastAtom = None;
+}
+
+void
+InitAtoms()
+{
+ FreeAllAtoms();
+ tableLength = InitialTableSize;
+ nodeTable = (NodePtr *)xalloc(InitialTableSize*sizeof(NodePtr));
+ if (!nodeTable)
+ AtomError();
+ nodeTable[None] = (NodePtr)NULL;
+ MakePredeclaredAtoms();
+ if (lastAtom != XA_LAST_PREDEFINED)
+ AtomError ();
+}
+
+
diff --git a/xserver/dix/buildatoms b/xserver/dix/buildatoms
new file mode 100644
index 000000000..dfbbca8a9
--- /dev/null
+++ b/xserver/dix/buildatoms
@@ -0,0 +1,43 @@
+#!/bin/sh
+hfile=../../../include/Xatom.h
+cfile=initatoms.c
+rm -f $hfile $cfile
+umask 222
+awk '
+BEGIN {
+ hfile = "'$hfile'";
+ cfile = "'$cfile'";
+ hformat = "#define XA_%s ((Atom) %d)\n";
+ printf("#ifndef XATOM_H\n") > hfile;
+ printf("#define XATOM_H 1\n\n") > hfile;
+ printf("/* THIS IS A GENERATED FILE\n") > hfile;
+ printf(" *\n") > hfile;
+ printf(" * Do not change! Changing this file implies a protocol change!\n") > hfile;
+ printf(" */\n\n") > hfile;
+
+ printf("/* THIS IS A GENERATED FILE\n") > cfile;
+ printf(" *\n") > cfile;
+ printf(" * Do not change! Changing this file implies a protocol change!\n") > cfile;
+ printf(" */\n\n") > cfile;
+ printf("#include \"X.h\"\n") > cfile;
+ printf("#include \"Xatom.h\"\n") > cfile;
+ printf("#include \"misc.h\"\n") > cfile;
+ printf("#include \"dix.h\"\n") > cfile;
+ printf("void MakePredeclaredAtoms()\n") > cfile;
+ printf("{\n") > cfile;
+
+ }
+
+NF == 2 && $2 == "@" {
+ printf(hformat, $1, ++atomno) > hfile ;
+ printf(" if (MakeAtom(\"%s\", %d, 1) != XA_%s) AtomError();\n", $1, length($1), $1) > cfile ;
+ }
+
+END {
+ printf("\n") > hfile;
+ printf(hformat, "LAST_PREDEFINED", atomno) > hfile ;
+ printf("#endif /* XATOM_H */\n") > hfile;
+ printf("}\n") > cfile ;
+ }
+' BuiltInAtoms
+exit 0
diff --git a/xserver/dix/colormap.c b/xserver/dix/colormap.c
new file mode 100644
index 000000000..b8f2f4af6
--- /dev/null
+++ b/xserver/dix/colormap.c
@@ -0,0 +1,2699 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "misc.h"
+#include "dix.h"
+#include "colormapst.h"
+#include "os.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "windowstr.h"
+
+extern XID clientErrorValue;
+extern int colormapPrivateCount;
+
+static Pixel FindBestPixel(
+ EntryPtr /*pentFirst*/,
+ int /*size*/,
+ xrgb * /*prgb*/,
+ int /*channel*/
+);
+
+static int AllComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int RedComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int GreenComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int BlueComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static void FreePixels(
+ register ColormapPtr /*pmap*/,
+ register int /*client*/
+);
+
+static void CopyFree(
+ int /*channel*/,
+ int /*client*/,
+ ColormapPtr /*pmapSrc*/,
+ ColormapPtr /*pmapDst*/
+);
+
+static void FreeCell(
+ ColormapPtr /*pmap*/,
+ Pixel /*i*/,
+ int /*channel*/
+);
+
+static void UpdateColors(
+ ColormapPtr /*pmap*/
+);
+
+static int AllocDirect(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*prmask*/,
+ Pixel * /*pgmask*/,
+ Pixel * /*pbmask*/
+);
+
+static int AllocPseudo(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pmask*/,
+ Pixel ** /*pppixFirst*/
+);
+
+static Bool AllocCP(
+ ColormapPtr /*pmap*/,
+ EntryPtr /*pentFirst*/,
+ int /*count*/,
+ int /*planes*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pMask*/
+);
+
+static Bool AllocShared(
+ ColormapPtr /*pmap*/,
+ Pixel * /*ppix*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Pixel /*rmask*/,
+ Pixel /*gmask*/,
+ Pixel /*bmask*/,
+ Pixel * /*ppixFirst*/
+);
+
+static int FreeCo(
+ ColormapPtr /*pmap*/,
+ int /*client*/,
+ int /*color*/,
+ int /*npixIn*/,
+ Pixel * /*ppixIn*/,
+ Pixel /*mask*/
+);
+
+static int TellNoMap(
+ WindowPtr /*pwin*/,
+ Colormap * /*pmid*/
+);
+
+static void FindColorInRootCmap (
+ ColormapPtr /* pmap */,
+ EntryPtr /* pentFirst */,
+ int /* size */,
+ xrgb* /* prgb */,
+ Pixel* /* pPixel */,
+ int /* channel */,
+ ColorCompareProcPtr /* comp */
+);
+
+#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
+#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
+#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
+#if COMPOSITE
+#define ALPHAMASK(vis) ((vis)->nplanes < 32 ? 0 : \
+ (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask))
+#else
+#define ALPHAMASK(vis) 0
+#endif
+
+#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
+
+/* GetNextBitsOrBreak(bits, mask, base) --
+ * (Suggestion: First read the macro, then read this explanation.
+ *
+ * Either generate the next value to OR in to a pixel or break out of this
+ * while loop
+ *
+ * This macro is used when we're trying to generate all 2^n combinations of
+ * bits in mask. What we're doing here is counting in binary, except that
+ * the bits we use to count may not be contiguous. This macro will be
+ * called 2^n times, returning a different value in bits each time. Then
+ * it will cause us to break out of a surrounding loop. (It will always be
+ * called from within a while loop.)
+ * On call: mask is the value we want to find all the combinations for
+ * base has 1 bit set where the least significant bit of mask is set
+ *
+ * For example,if mask is 01010, base should be 0010 and we count like this:
+ * 00010 (see this isn't so hard),
+ * then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
+ * we add that to bits getting (0100 + 0100) =
+ * 01000 for our next value.
+ * then we add 0010 to get
+ * 01010 and we're done (easy as 1, 2, 3)
+ */
+#define GetNextBitsOrBreak(bits, mask, base) \
+ if((bits) == (mask)) \
+ break; \
+ (bits) += (base); \
+ while((bits) & ~(mask)) \
+ (bits) += ((bits) & ~(mask));
+/* ID of server as client */
+#define SERVER_ID 0
+
+typedef struct _colorResource
+{
+ Colormap mid;
+ int client;
+} colorResource;
+
+/* Invariants:
+ * refcnt == 0 means entry is empty
+ * refcnt > 0 means entry is useable by many clients, so it can't be changed
+ * refcnt == AllocPrivate means entry owned by one client only
+ * fShared should only be set if refcnt == AllocPrivate, and only in red map
+ */
+
+
+/**
+ * Create and initialize the color map
+ *
+ * \param mid resource to use for this colormap
+ * \param alloc 1 iff all entries are allocated writable
+ */
+_X_EXPORT int
+CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
+ ColormapPtr *ppcmap, int alloc, int client)
+{
+ int class, size;
+ unsigned long sizebytes;
+ ColormapPtr pmap;
+ register EntryPtr pent;
+ int i;
+ register Pixel *ppix, **pptr;
+
+ class = pVisual->class;
+ if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
+ return (BadMatch);
+
+ size = pVisual->ColormapEntries;
+ sizebytes = (size * sizeof(Entry)) +
+ (MAXCLIENTS * sizeof(Pixel *)) +
+ (MAXCLIENTS * sizeof(int));
+ if ((class | DynamicClass) == DirectColor)
+ sizebytes *= 3;
+ sizebytes += sizeof(ColormapRec);
+ pmap = (ColormapPtr) xalloc(sizebytes);
+ if (!pmap)
+ return (BadAlloc);
+#if defined(_XSERVER64)
+ pmap->pad0 = 0;
+ pmap->pad1 = 0;
+#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
+ pmap->pad2 = 0;
+#endif
+#endif
+ pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));
+ sizebytes = size * sizeof(Entry);
+ pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
+ pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->mid = mid;
+ pmap->flags = 0; /* start out with all flags clear */
+ if(mid == pScreen->defColormap)
+ pmap->flags |= IsDefault;
+ pmap->pScreen = pScreen;
+ pmap->pVisual = pVisual;
+ pmap->class = class;
+ if ((class | DynamicClass) == DirectColor)
+ size = NUMRED(pVisual);
+ pmap->freeRed = size;
+ bzero ((char *) pmap->red, (int)sizebytes);
+ bzero((char *) pmap->numPixelsRed, MAXCLIENTS * sizeof(int));
+ for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
+ *pptr = (Pixel *)NULL;
+ if (alloc == AllocAll)
+ {
+ if (class & DynamicClass)
+ pmap->flags |= AllAllocated;
+ for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeRed = 0;
+ ppix = (Pixel *)xalloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ xfree(pmap);
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsRed[client] = size;
+ }
+
+ if ((class | DynamicClass) == DirectColor)
+ {
+ pmap->freeGreen = NUMGREEN(pVisual);
+ pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
+ pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->freeBlue = NUMBLUE(pVisual);
+ pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
+ pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
+ (MAXCLIENTS * sizeof(Pixel *)));
+
+ bzero ((char *) pmap->green, (int)sizebytes);
+ bzero ((char *) pmap->blue, (int)sizebytes);
+
+ memmove((char *) pmap->clientPixelsGreen,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ memmove((char *) pmap->clientPixelsBlue,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ bzero((char *) pmap->numPixelsGreen, MAXCLIENTS * sizeof(int));
+ bzero((char *) pmap->numPixelsBlue, MAXCLIENTS * sizeof(int));
+
+ /* If every cell is allocated, mark its refcnt */
+ if (alloc == AllocAll)
+ {
+ size = pmap->freeGreen;
+ for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeGreen = 0;
+ ppix = (Pixel *) xalloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ xfree(pmap->clientPixelsRed[client]);
+ xfree(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsGreen[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsGreen[client] = size;
+
+ size = pmap->freeBlue;
+ for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeBlue = 0;
+ ppix = (Pixel *) xalloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ xfree(pmap->clientPixelsGreen[client]);
+ xfree(pmap->clientPixelsRed[client]);
+ xfree(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsBlue[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsBlue[client] = size;
+ }
+ }
+ if (!AddResource(mid, RT_COLORMAP, (pointer)pmap))
+ return (BadAlloc);
+ /* If the device wants a chance to initialize the colormap in any way,
+ * this is it. In specific, if this is a Static colormap, this is the
+ * time to fill in the colormap's values */
+ pmap->flags |= BeingCreated;
+
+
+ /*
+ * Allocate the array of devPrivate's for this colormap.
+ */
+
+ if (colormapPrivateCount == 0)
+ pmap->devPrivates = NULL;
+ else
+ {
+ pmap->devPrivates = (DevUnion *) xcalloc (
+ sizeof(DevUnion), colormapPrivateCount);
+ if (!pmap->devPrivates)
+ {
+ FreeResource (mid, RT_NONE);
+ return BadAlloc;
+ }
+ }
+
+ if (!(*pScreen->CreateColormap)(pmap))
+ {
+ FreeResource (mid, RT_NONE);
+ return BadAlloc;
+ }
+ pmap->flags &= ~BeingCreated;
+ *ppcmap = pmap;
+ return (Success);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeColormap (pointer value, XID mid)
+{
+ int i;
+ register EntryPtr pent;
+ ColormapPtr pmap = (ColormapPtr)value;
+
+ if(CLIENT_ID(mid) != SERVER_ID)
+ {
+ (*pmap->pScreen->UninstallColormap) (pmap);
+ WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid);
+ }
+
+ /* This is the device's chance to undo anything it needs to, especially
+ * to free any storage it allocated */
+ (*pmap->pScreen->DestroyColormap)(pmap);
+
+ if(pmap->clientPixelsRed)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ xfree(pmap->clientPixelsRed[i]);
+ }
+
+ if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
+ {
+ for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
+ pent >= pmap->red;
+ pent--)
+ {
+ if(pent->fShared)
+ {
+ if (--pent->co.shco.red->refcnt == 0)
+ xfree(pent->co.shco.red);
+ if (--pent->co.shco.green->refcnt == 0)
+ xfree(pent->co.shco.green);
+ if (--pent->co.shco.blue->refcnt == 0)
+ xfree(pent->co.shco.blue);
+ }
+ }
+ }
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ {
+ xfree(pmap->clientPixelsGreen[i]);
+ xfree(pmap->clientPixelsBlue[i]);
+ }
+ }
+
+ if (pmap->devPrivates)
+ xfree(pmap->devPrivates);
+
+ xfree(pmap);
+ return(Success);
+}
+
+/* Tell window that pmid has disappeared */
+static int
+TellNoMap (WindowPtr pwin, Colormap *pmid)
+{
+ xEvent xE;
+
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = None;
+ xE.u.colormap.new = TRUE;
+ xE.u.colormap.state = ColormapUninstalled;
+#ifdef PANORAMIX
+ if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
+#endif
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ if (pwin->optional) {
+ pwin->optional->colormap = None;
+ CheckWindowOptionalNeed (pwin);
+ }
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got uninstalled */
+_X_EXPORT int
+TellLostMap (WindowPtr pwin, pointer value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapUninstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got installed */
+_X_EXPORT int
+TellGainedMap (WindowPtr pwin, pointer value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap (pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapInstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+
+int
+CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client)
+{
+ ColormapPtr pmap = (ColormapPtr) NULL;
+ int result, alloc, size;
+ Colormap midSrc;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+
+ pScreen = pSrc->pScreen;
+ pVisual = pSrc->pVisual;
+ midSrc = pSrc->mid;
+ alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
+ AllocAll : AllocNone;
+ size = pVisual->ColormapEntries;
+
+ /* If the create returns non-0, it failed */
+ result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
+ if(result != Success)
+ return(result);
+ if(alloc == AllocAll)
+ {
+ memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
+ memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
+ }
+ pSrc->flags &= ~AllAllocated;
+ FreePixels(pSrc, client);
+ UpdateColors(pmap);
+ return(Success);
+ }
+
+ CopyFree(REDMAP, client, pSrc, pmap);
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ CopyFree(GREENMAP, client, pSrc, pmap);
+ CopyFree(BLUEMAP, client, pSrc, pmap);
+ }
+ if (pmap->class & DynamicClass)
+ UpdateColors(pmap);
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return(Success);
+}
+
+/* Helper routine for freeing large numbers of cells from a map */
+static void
+CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst)
+{
+ int z, npix;
+ EntryPtr pentSrcFirst, pentDstFirst;
+ EntryPtr pentSrc, pentDst;
+ Pixel *ppix;
+ int nalloc;
+
+ switch(channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case REDMAP:
+ ppix = (pmapSrc->clientPixelsRed)[client];
+ npix = (pmapSrc->numPixelsRed)[client];
+ pentSrcFirst = pmapSrc->red;
+ pentDstFirst = pmapDst->red;
+ break;
+ case GREENMAP:
+ ppix = (pmapSrc->clientPixelsGreen)[client];
+ npix = (pmapSrc->numPixelsGreen)[client];
+ pentSrcFirst = pmapSrc->green;
+ pentDstFirst = pmapDst->green;
+ break;
+ case BLUEMAP:
+ ppix = (pmapSrc->clientPixelsBlue)[client];
+ npix = (pmapSrc->numPixelsBlue)[client];
+ pentSrcFirst = pmapSrc->blue;
+ pentDstFirst = pmapDst->blue;
+ break;
+ }
+ nalloc = 0;
+ if (pmapSrc->class & DynamicClass)
+ {
+ for(z = npix; --z >= 0; ppix++)
+ {
+ /* Copy entries */
+ pentSrc = pentSrcFirst + *ppix;
+ pentDst = pentDstFirst + *ppix;
+ if (pentDst->refcnt > 0)
+ {
+ pentDst->refcnt++;
+ }
+ else
+ {
+ *pentDst = *pentSrc;
+ nalloc++;
+ if (pentSrc->refcnt > 0)
+ pentDst->refcnt = 1;
+ else
+ pentSrc->fShared = FALSE;
+ }
+ FreeCell(pmapSrc, *ppix, channel);
+ }
+ }
+
+ /* Note that FreeCell has already fixed pmapSrc->free{Color} */
+ switch(channel)
+ {
+ case REDMAP:
+ pmapDst->freeRed -= nalloc;
+ (pmapDst->clientPixelsRed)[client] =
+ (pmapSrc->clientPixelsRed)[client];
+ (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
+ (pmapSrc->numPixelsRed)[client] = 0;
+ break;
+ case GREENMAP:
+ pmapDst->freeGreen -= nalloc;
+ (pmapDst->clientPixelsGreen)[client] =
+ (pmapSrc->clientPixelsGreen)[client];
+ (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
+ (pmapSrc->numPixelsGreen)[client] = 0;
+ break;
+ case BLUEMAP:
+ pmapDst->freeBlue -= nalloc;
+ pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
+ pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
+ pmapSrc->numPixelsBlue[client] = 0;
+ break;
+ }
+}
+
+/* Free the ith entry in a color map. Must handle freeing of
+ * colors allocated through AllocColorPlanes */
+static void
+FreeCell (ColormapPtr pmap, Pixel i, int channel)
+{
+ EntryPtr pent;
+ int *pCount;
+
+
+ switch (channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ case REDMAP:
+ pent = (EntryPtr) &pmap->red[i];
+ pCount = &pmap->freeRed;
+ break;
+ case GREENMAP:
+ pent = (EntryPtr) &pmap->green[i];
+ pCount = &pmap->freeGreen;
+ break;
+ case BLUEMAP:
+ pent = (EntryPtr) &pmap->blue[i];
+ pCount = &pmap->freeBlue;
+ break;
+ }
+ /* If it's not privately allocated and it's not time to free it, just
+ * decrement the count */
+ if (pent->refcnt > 1)
+ pent->refcnt--;
+ else
+ {
+ /* If the color type is shared, find the sharedcolor. If decremented
+ * refcnt is 0, free the shared cell. */
+ if (pent->fShared)
+ {
+ if(--pent->co.shco.red->refcnt == 0)
+ xfree(pent->co.shco.red);
+ if(--pent->co.shco.green->refcnt == 0)
+ xfree(pent->co.shco.green);
+ if(--pent->co.shco.blue->refcnt == 0)
+ xfree(pent->co.shco.blue);
+ pent->fShared = FALSE;
+ }
+ pent->refcnt = 0;
+ *pCount += 1;
+ }
+}
+
+static void
+UpdateColors (ColormapPtr pmap)
+{
+ xColorItem *defs;
+ register xColorItem *pdef;
+ register EntryPtr pent;
+ register VisualPtr pVisual;
+ int i, n, size;
+
+ pVisual = pmap->pVisual;
+ size = pVisual->ColormapEntries;
+ defs = (xColorItem *)ALLOCATE_LOCAL(size * sizeof(xColorItem));
+ if (!defs)
+ return;
+ n = 0;
+ pdef = defs;
+ if (pmap->class == DirectColor)
+ {
+ for (i = 0; i < size; i++)
+ {
+ if (!pmap->red[i].refcnt &&
+ !pmap->green[i].refcnt &&
+ !pmap->blue[i].refcnt)
+ continue;
+ pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
+ ((Pixel)i << pVisual->offsetGreen) |
+ ((Pixel)i << pVisual->offsetBlue);
+ pdef->red = pmap->red[i].co.local.red;
+ pdef->green = pmap->green[i].co.local.green;
+ pdef->blue = pmap->blue[i].co.local.blue;
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ else
+ {
+ for (i = 0, pent = pmap->red; i < size; i++, pent++)
+ {
+ if (!pent->refcnt)
+ continue;
+ pdef->pixel = i;
+ if(pent->fShared)
+ {
+ pdef->red = pent->co.shco.red->color;
+ pdef->green = pent->co.shco.green->color;
+ pdef->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ pdef->red = pent->co.local.red;
+ pdef->green = pent->co.local.green;
+ pdef->blue = pent->co.local.blue;
+ }
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ if (n)
+ (*pmap->pScreen->StoreColors)(pmap, n, defs);
+ DEALLOCATE_LOCAL(defs);
+}
+
+/* Get a read-only color from a ColorMap (probably slow for large maps)
+ * Returns by changing the value in pred, pgreen, pblue and pPix
+ */
+_X_EXPORT int
+AllocColor (ColormapPtr pmap,
+ unsigned short *pred, unsigned short *pgreen, unsigned short *pblue,
+ Pixel *pPix, int client)
+{
+ Pixel pixR, pixG, pixB;
+ int entries;
+ xrgb rgb;
+ int class;
+ VisualPtr pVisual;
+ int npix;
+ Pixel *ppix;
+
+ pVisual = pmap->pVisual;
+ (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
+ rgb.red = *pred;
+ rgb.green = *pgreen;
+ rgb.blue = *pblue;
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ /* If the colormap is being created, then we want to be able to change
+ * the colormap, even if it's a static type. Otherwise, we'd never be
+ * able to initialize static colormaps
+ */
+ if(pmap->flags & BeingCreated)
+ class |= DynamicClass;
+
+ /* If this is one of the static storage classes, and we're not initializing
+ * it, the best we can do is to find the closest color entry to the
+ * requested one and return that.
+ */
+ switch (class) {
+ case StaticColor:
+ case StaticGray:
+ /* Look up all three components in the same pmap */
+ *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->red[pixR].co.local.green;
+ *pblue = pmap->red[pixR].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ *pPix = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue) |
+ ALPHAMASK(pVisual);
+
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->green[pixG].co.local.green;
+ *pblue = pmap->blue[pixB].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ npix = pmap->numPixelsGreen[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixG;
+ pmap->clientPixelsGreen[client] = ppix;
+ npix = pmap->numPixelsBlue[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixB;
+ pmap->clientPixelsBlue[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ pmap->numPixelsGreen[client]++;
+ pmap->numPixelsBlue[client]++;
+ break;
+
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap = (ColormapPtr)
+ SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap,
+ RT_COLORMAP, SecurityReadAccess);
+
+ if (pmap->class == prootmap->class)
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ pPix, PSEUDOMAP, AllComp);
+ }
+ if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
+ client, AllComp) != Success)
+ return (BadAlloc);
+ break;
+
+ case DirectColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap = (ColormapPtr)
+ SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap,
+ RT_COLORMAP, SecurityReadAccess);
+
+ if (pmap->class == prootmap->class)
+ {
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ &pixR, REDMAP, RedComp);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb,
+ &pixG, GREENMAP, GreenComp);
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb,
+ &pixB, BLUEMAP, BlueComp);
+ *pPix = pixR | pixG | pixB;
+ }
+ }
+
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ client, RedComp) != Success)
+ return (BadAlloc);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, client, GreenComp) != Success)
+ {
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ client, BlueComp) != Success)
+ {
+ (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ *pPix = pixR | pixG | pixB | ALPHAMASK(pVisual);
+
+ break;
+ }
+
+ /* if this is the client's first pixel in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((pmap->numPixelsRed[client] == 1) &&
+ (CLIENT_ID(pmap->mid) != client) &&
+ !(pmap->flags & BeingCreated))
+ {
+ colorResource *pcr;
+
+ pcr = (colorResource *) xalloc(sizeof(colorResource));
+ if (!pcr)
+ {
+ (void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
+ return (BadAlloc);
+ }
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ return (BadAlloc);
+ }
+ return (Success);
+}
+
+/*
+ * FakeAllocColor -- fake an AllocColor request by
+ * returning a free pixel if availible, otherwise returning
+ * the closest matching pixel. This is used by the mi
+ * software sprite code to recolor cursors. A nice side-effect
+ * is that this routine will never return failure.
+ */
+
+_X_EXPORT void
+FakeAllocColor (register ColormapPtr pmap, register xColorItem *item)
+{
+ Pixel pixR, pixG, pixB;
+ Pixel temp;
+ int entries;
+ xrgb rgb;
+ int class;
+ register VisualPtr pVisual;
+
+ pVisual = pmap->pVisual;
+ rgb.red = item->red;
+ rgb.green = item->green;
+ rgb.blue = item->blue;
+ (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ switch (class) {
+ case GrayScale:
+ case PseudoColor:
+ item->pixel = 0;
+ if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
+ -1, AllComp) == Success) {
+ item->pixel = temp;
+ break;
+ }
+ /* fall through ... */
+ case StaticColor:
+ case StaticGray:
+ item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ break;
+
+ case DirectColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ -1, RedComp) != Success)
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
+ << pVisual->offsetRed;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, -1, GreenComp) != Success)
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
+ GREENMAP) << pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ -1, BlueComp) != Success)
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
+ << pVisual->offsetBlue;
+ item->pixel = pixR | pixG | pixB;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ item->pixel = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue);
+ break;
+ }
+}
+
+/* free a pixel value obtained from FakeAllocColor */
+_X_EXPORT void
+FakeFreeColor(register ColormapPtr pmap, Pixel pixel)
+{
+ register VisualPtr pVisual;
+ Pixel pixR, pixG, pixB;
+
+ switch (pmap->class) {
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->red[pixel].refcnt == AllocTemporary)
+ pmap->red[pixel].refcnt = 0;
+ break;
+ case DirectColor:
+ pVisual = pmap->pVisual;
+ pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pmap->red[pixR].refcnt == AllocTemporary)
+ pmap->red[pixR].refcnt = 0;
+ if (pmap->green[pixG].refcnt == AllocTemporary)
+ pmap->green[pixG].refcnt = 0;
+ if (pmap->blue[pixB].refcnt == AllocTemporary)
+ pmap->blue[pixB].refcnt = 0;
+ break;
+ }
+}
+
+typedef unsigned short BigNumUpper;
+typedef unsigned long BigNumLower;
+
+#define BIGNUMLOWERBITS 24
+#define BIGNUMUPPERBITS 16
+#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
+#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
+#define UPPERPART(i) ((i) >> BIGNUMLOWERBITS)
+#define LOWERPART(i) ((i) & (BIGNUMLOWER - 1))
+
+typedef struct _bignum {
+ BigNumUpper upper;
+ BigNumLower lower;
+} BigNumRec, *BigNumPtr;
+
+#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
+ ((x)->upper == (y)->upper && (x)->lower > (y)->lower))
+
+#define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \
+ ((r)->lower = LOWERPART(u)))
+
+#define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \
+ ((r)->lower = BIGNUMLOWER-1))
+
+static void
+BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
+{
+ BigNumLower lower, carry = 0;
+
+ lower = x->lower + y->lower;
+ if (lower >= BIGNUMLOWER) {
+ lower -= BIGNUMLOWER;
+ carry = 1;
+ }
+ r->lower = lower;
+ r->upper = x->upper + y->upper + carry;
+}
+
+static Pixel
+FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel)
+{
+ EntryPtr pent;
+ Pixel pixel, final;
+ long dr, dg, db;
+ unsigned long sq;
+ BigNumRec minval, sum, temp;
+
+ final = 0;
+ MaxBigNum(&minval);
+ /* look for the minimal difference */
+ for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
+ {
+ dr = dg = db = 0;
+ switch(channel)
+ {
+ case PSEUDOMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ db = (long) pent->co.local.blue - prgb->blue;
+ case REDMAP:
+ dr = (long) pent->co.local.red - prgb->red;
+ break;
+ case GREENMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ break;
+ case BLUEMAP:
+ db = (long) pent->co.local.blue - prgb->blue;
+ break;
+ }
+ sq = dr * dr;
+ UnsignedToBigNum (sq, &sum);
+ sq = dg * dg;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ sq = db * db;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ if (BigNumGreater (&minval, &sum))
+ {
+ final = pixel;
+ minval = sum;
+ }
+ }
+ return(final);
+}
+
+static void
+FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size,
+ xrgb *prgb, Pixel *pPixel, int channel,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Pixel pixel;
+ int count;
+
+ if ((pixel = *pPixel) >= size)
+ pixel = 0;
+ for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
+ {
+ if (pent->refcnt > 0 && (*comp) (pent, prgb))
+ {
+ switch (channel)
+ {
+ case REDMAP:
+ pixel <<= pmap->pVisual->offsetRed;
+ break;
+ case GREENMAP:
+ pixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ pixel <<= pmap->pVisual->offsetBlue;
+ break;
+ default: /* PSEUDOMAP */
+ break;
+ }
+ *pPixel = pixel;
+ }
+ }
+}
+
+/* Tries to find a color in pmap that exactly matches the one requested in prgb
+ * if it can't it allocates one.
+ * Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
+ * load *pPixel with that value, otherwise set it to 0
+ */
+int
+FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb,
+ Pixel *pPixel, int channel, int client,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Bool foundFree;
+ Pixel pixel, Free = 0;
+ int npix, count, *nump = NULL;
+ Pixel **pixp = NULL, *ppix;
+ xColorItem def;
+
+ foundFree = FALSE;
+
+ if((pixel = *pPixel) >= size)
+ pixel = 0;
+ /* see if there is a match, and also look for a free entry */
+ for (pent = pentFirst + pixel, count = size; --count >= 0; )
+ {
+ if (pent->refcnt > 0)
+ {
+ if ((*comp) (pent, prgb))
+ {
+ if (client >= 0)
+ pent->refcnt++;
+ *pPixel = pixel;
+ switch(channel)
+ {
+ case REDMAP:
+ *pPixel <<= pmap->pVisual->offsetRed;
+ case PSEUDOMAP:
+ break;
+ case GREENMAP:
+ *pPixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ *pPixel <<= pmap->pVisual->offsetBlue;
+ break;
+ }
+ goto gotit;
+ }
+ }
+ else if (!foundFree && pent->refcnt == 0)
+ {
+ Free = pixel;
+ foundFree = TRUE;
+ /* If we're initializing the colormap, then we are looking for
+ * the first free cell we can find, not to minimize the number
+ * of entries we use. So don't look any further. */
+ if(pmap->flags & BeingCreated)
+ break;
+ }
+ pixel++;
+ if(pixel >= size)
+ {
+ pent = pentFirst;
+ pixel = 0;
+ }
+ else
+ pent++;
+ }
+
+ /* If we got here, we didn't find a match. If we also didn't find
+ * a free entry, we're out of luck. Otherwise, we'll usurp a free
+ * entry and fill it in */
+ if (!foundFree)
+ return (BadAlloc);
+ pent = pentFirst + Free;
+ pent->fShared = FALSE;
+ pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
+
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ pent->co.local.red = prgb->red;
+ pent->co.local.green = prgb->green;
+ pent->co.local.blue = prgb->blue;
+ def.red = prgb->red;
+ def.green = prgb->green;
+ def.blue = prgb->blue;
+ def.flags = (DoRed|DoGreen|DoBlue);
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free;
+ break;
+
+ case REDMAP:
+ pent->co.local.red = prgb->red;
+ def.red = prgb->red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoRed;
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free << pmap->pVisual->offsetRed;
+ break;
+
+ case GREENMAP:
+ pent->co.local.green = prgb->green;
+ def.red = pmap->red[0].co.local.red;
+ def.green = prgb->green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoGreen;
+ if (client >= 0)
+ pmap->freeGreen--;
+ def.pixel = Free << pmap->pVisual->offsetGreen;
+ break;
+
+ case BLUEMAP:
+ pent->co.local.blue = prgb->blue;
+ def.red = pmap->red[0].co.local.red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = prgb->blue;
+ def.flags = DoBlue;
+ if (client >= 0)
+ pmap->freeBlue--;
+ def.pixel = Free << pmap->pVisual->offsetBlue;
+ break;
+ }
+ (*pmap->pScreen->StoreColors) (pmap, 1, &def);
+ pixel = Free;
+ *pPixel = def.pixel;
+
+gotit:
+ if (pmap->flags & BeingCreated || client == -1)
+ return(Success);
+ /* Now remember the pixel, for freeing later */
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ nump = pmap->numPixelsRed;
+ pixp = pmap->clientPixelsRed;
+ break;
+
+ case GREENMAP:
+ nump = pmap->numPixelsGreen;
+ pixp = pmap->clientPixelsGreen;
+ break;
+
+ case BLUEMAP:
+ nump = pmap->numPixelsBlue;
+ pixp = pmap->clientPixelsBlue;
+ break;
+ }
+ npix = nump[client];
+ ppix = (Pixel *) xrealloc (pixp[client], (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ {
+ pent->refcnt--;
+ if (!pent->fShared)
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->freeRed++;
+ break;
+ case GREENMAP:
+ pmap->freeGreen++;
+ break;
+ case BLUEMAP:
+ pmap->freeBlue++;
+ break;
+ }
+ return(BadAlloc);
+ }
+ ppix[npix] = pixel;
+ pixp[client] = ppix;
+ nump[client]++;
+
+ return(Success);
+}
+
+/* Comparison functions -- passed to FindColor to determine if an
+ * entry is already the color we're looking for or not */
+static int
+AllComp (EntryPtr pent, xrgb *prgb)
+{
+ if((pent->co.local.red == prgb->red) &&
+ (pent->co.local.green == prgb->green) &&
+ (pent->co.local.blue == prgb->blue) )
+ return (1);
+ return (0);
+}
+
+static int
+RedComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.red == prgb->red)
+ return (1);
+ return (0);
+}
+
+static int
+GreenComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.green == prgb->green)
+ return (1);
+ return (0);
+}
+
+static int
+BlueComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.blue == prgb->blue)
+ return (1);
+ return (0);
+}
+
+
+/* Read the color value of a cell */
+
+_X_EXPORT int
+QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList)
+{
+ Pixel *ppix, pixel;
+ xrgb *prgb;
+ VisualPtr pVisual;
+ EntryPtr pent;
+ Pixel i;
+ int errVal = Success;
+
+ pVisual = pmap->pVisual;
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel & rgbbad) {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ i = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (i >= numred)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->red = pmap->red[i].co.local.red;
+ i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (i >= numgreen)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->green = pmap->green[i].co.local.green;
+ i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (i >= numblue)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->blue = pmap->blue[i].co.local.blue;
+ }
+ }
+ else
+ {
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel >= pVisual->ColormapEntries)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ }
+ else
+ {
+ pent = (EntryPtr)&pmap->red[pixel];
+ if (pent->fShared)
+ {
+ prgb->red = pent->co.shco.red->color;
+ prgb->green = pent->co.shco.green->color;
+ prgb->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ prgb->red = pent->co.local.red;
+ prgb->green = pent->co.local.green;
+ prgb->blue = pent->co.local.blue;
+ }
+ }
+ }
+ }
+ return (errVal);
+}
+
+static void
+FreePixels(register ColormapPtr pmap, register int client)
+{
+ register Pixel *ppix, *ppixStart;
+ register int n;
+ int class;
+
+ class = pmap->class;
+ ppixStart = pmap->clientPixelsRed[client];
+ if (class & DynamicClass)
+ {
+ n = pmap->numPixelsRed[client];
+ for (ppix = ppixStart; --n >= 0; )
+ {
+ FreeCell(pmap, *ppix, REDMAP);
+ ppix++;
+ }
+ }
+
+ xfree(ppixStart);
+ pmap->clientPixelsRed[client] = (Pixel *) NULL;
+ pmap->numPixelsRed[client] = 0;
+ if ((class | DynamicClass) == DirectColor)
+ {
+ ppixStart = pmap->clientPixelsGreen[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
+ FreeCell(pmap, *ppix++, GREENMAP);
+ xfree(ppixStart);
+ pmap->clientPixelsGreen[client] = (Pixel *) NULL;
+ pmap->numPixelsGreen[client] = 0;
+
+ ppixStart = pmap->clientPixelsBlue[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
+ FreeCell(pmap, *ppix++, BLUEMAP);
+ xfree(ppixStart);
+ pmap->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmap->numPixelsBlue[client] = 0;
+ }
+}
+
+/**
+ * Frees all of a client's colors and cells.
+ *
+ * \param value must conform to DeleteType
+ * \unused fakeid
+ */
+int
+FreeClientPixels (pointer value, XID fakeid)
+{
+ ColormapPtr pmap;
+ colorResource *pcr = (colorResource *)value;
+
+ pmap = (ColormapPtr) LookupIDByType(pcr->mid, RT_COLORMAP);
+ if (pmap)
+ FreePixels(pmap, pcr->client);
+ xfree(pcr);
+ return Success;
+}
+
+int
+AllocColorCells (int client, ColormapPtr pmap, int colors, int planes,
+ Bool contig, Pixel *ppix, Pixel *masks)
+{
+ Pixel rmask, gmask, bmask, *ppixFirst, r, g, b;
+ int n, class;
+ int ok;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (pmap->class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = (colorResource *) xalloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (pmap->class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, planes, planes, planes,
+ contig, ppix, &rmask, &gmask, &bmask);
+ if(ok == Success)
+ {
+ for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
+ {
+ while(!(rmask & r))
+ r += r;
+ while(!(gmask & g))
+ g += g;
+ while(!(bmask & b))
+ b += b;
+ *masks++ = r | g | b;
+ }
+ }
+ }
+ else
+ {
+ ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
+ &ppixFirst);
+ if(ok == Success)
+ {
+ for (r = 1, n = planes; --n >= 0; r += r)
+ {
+ while(!(rmask & r))
+ r += r;
+ *masks++ = r;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ xfree(pcr);
+
+ return (ok);
+}
+
+
+int
+AllocColorPlanes (int client, ColormapPtr pmap, int colors,
+ int r, int g, int b, Bool contig, Pixel *pixels,
+ Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ int ok;
+ Pixel mask, *ppixFirst;
+ register Pixel shift;
+ register int i;
+ int class;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = (colorResource *) xalloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
+ prmask, pgmask, pbmask);
+ }
+ else
+ {
+ /* Allocate the proper pixels */
+ /* XXX This is sort of bad, because of contig is set, we force all
+ * r + g + b bits to be contiguous. Should only force contiguity
+ * per mask
+ */
+ ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
+ &mask, &ppixFirst);
+
+ if(ok == Success)
+ {
+ /* now split that mask into three */
+ *prmask = *pgmask = *pbmask = 0;
+ shift = 1;
+ for (i = r; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *prmask |= shift;
+ }
+ for (i = g; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pgmask |= shift;
+ }
+ for (i = b; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pbmask |= shift;
+ }
+
+ /* set up the shared color cells */
+ if (!AllocShared(pmap, pixels, colors, r, g, b,
+ *prmask, *pgmask, *pbmask, ppixFirst))
+ {
+ (void)FreeColors(pmap, client, colors, pixels, mask);
+ ok = BadAlloc;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ xfree(pcr);
+
+ return (ok);
+}
+
+static int
+AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig,
+ Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ Pixel *ppixRed, *ppixGreen, *ppixBlue;
+ Pixel *ppix, *pDst, *p;
+ int npix, npixR, npixG, npixB;
+ Bool okR, okG, okB;
+ Pixel *rpix = 0, *gpix = 0, *bpix = 0;
+
+ npixR = c << r;
+ npixG = c << g;
+ npixB = c << b;
+ if ((r >= 32) || (g >= 32) || (b >= 32) ||
+ (npixR > pmap->freeRed) || (npixR < c) ||
+ (npixG > pmap->freeGreen) || (npixG < c) ||
+ (npixB > pmap->freeBlue) || (npixB < c))
+ return BadAlloc;
+
+ /* start out with empty pixels */
+ for(p = pixels; p < pixels + c; p++)
+ *p = 0;
+
+ ppixRed = (Pixel *)ALLOCATE_LOCAL(npixR * sizeof(Pixel));
+ ppixGreen = (Pixel *)ALLOCATE_LOCAL(npixG * sizeof(Pixel));
+ ppixBlue = (Pixel *)ALLOCATE_LOCAL(npixB * sizeof(Pixel));
+ if (!ppixRed || !ppixGreen || !ppixBlue)
+ {
+ if (ppixBlue) DEALLOCATE_LOCAL(ppixBlue);
+ if (ppixGreen) DEALLOCATE_LOCAL(ppixGreen);
+ if (ppixRed) DEALLOCATE_LOCAL(ppixRed);
+ return(BadAlloc);
+ }
+
+ okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
+ okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
+ okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
+
+ if (okR && okG && okB)
+ {
+ rpix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + (c << r)) *
+ sizeof(Pixel));
+ if (rpix)
+ pmap->clientPixelsRed[client] = rpix;
+ gpix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client],
+ (pmap->numPixelsGreen[client] + (c << g)) *
+ sizeof(Pixel));
+ if (gpix)
+ pmap->clientPixelsGreen[client] = gpix;
+ bpix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client],
+ (pmap->numPixelsBlue[client] + (c << b)) *
+ sizeof(Pixel));
+ if (bpix)
+ pmap->clientPixelsBlue[client] = bpix;
+ }
+
+ if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
+ {
+ if (okR)
+ for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
+ pmap->red[*ppix].refcnt = 0;
+ if (okG)
+ for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
+ pmap->green[*ppix].refcnt = 0;
+ if (okB)
+ for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
+ pmap->blue[*ppix].refcnt = 0;
+ DEALLOCATE_LOCAL(ppixBlue);
+ DEALLOCATE_LOCAL(ppixGreen);
+ DEALLOCATE_LOCAL(ppixRed);
+ return(BadAlloc);
+ }
+
+ *prmask <<= pmap->pVisual->offsetRed;
+ *pgmask <<= pmap->pVisual->offsetGreen;
+ *pbmask <<= pmap->pVisual->offsetBlue;
+
+ ppix = rpix + pmap->numPixelsRed[client];
+ for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixRed + c)
+ *pDst++ |= *p << pmap->pVisual->offsetRed;
+ }
+ pmap->numPixelsRed[client] += npixR;
+ pmap->freeRed -= npixR;
+
+ ppix = gpix + pmap->numPixelsGreen[client];
+ for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixGreen + c)
+ *pDst++ |= *p << pmap->pVisual->offsetGreen;
+ }
+ pmap->numPixelsGreen[client] += npixG;
+ pmap->freeGreen -= npixG;
+
+ ppix = bpix + pmap->numPixelsBlue[client];
+ for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixBlue + c)
+ *pDst++ |= *p << pmap->pVisual->offsetBlue;
+ }
+ pmap->numPixelsBlue[client] += npixB;
+ pmap->freeBlue -= npixB;
+
+
+ for (pDst = pixels; pDst < pixels + c; pDst++)
+ *pDst |= ALPHAMASK(pmap->pVisual);
+
+ DEALLOCATE_LOCAL(ppixBlue);
+ DEALLOCATE_LOCAL(ppixGreen);
+ DEALLOCATE_LOCAL(ppixRed);
+
+ return (Success);
+}
+
+static int
+AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig,
+ Pixel *pixels, Pixel *pmask, Pixel **pppixFirst)
+{
+ Pixel *ppix, *p, *pDst, *ppixTemp;
+ int npix;
+ Bool ok;
+
+ npix = c << r;
+ if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
+ return(BadAlloc);
+ if(!(ppixTemp = (Pixel *)ALLOCATE_LOCAL(npix * sizeof(Pixel))))
+ return(BadAlloc);
+ ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
+
+ if (ok)
+ {
+
+ /* all the allocated pixels are added to the client pixel list,
+ * but only the unique ones are returned to the client */
+ ppix = (Pixel *)xrealloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
+ if (!ppix)
+ {
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ pmap->red[*p].refcnt = 0;
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ ppix += pmap->numPixelsRed[client];
+ *pppixFirst = ppix;
+ pDst = pixels;
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixTemp + c)
+ *pDst++ = *p;
+ }
+ pmap->numPixelsRed[client] += npix;
+ pmap->freeRed -= npix;
+ }
+ DEALLOCATE_LOCAL(ppixTemp);
+ return (ok ? Success : BadAlloc);
+}
+
+/* Allocates count << planes pixels from colormap pmap for client. If
+ * contig, then the plane mask is made of consecutive bits. Returns
+ * all count << pixels in the array pixels. The first count of those
+ * pixels are the unique pixels. *pMask has the mask to Or with the
+ * unique pixels to get the rest of them.
+ *
+ * Returns True iff all pixels could be allocated
+ * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
+ * (see AllocShared for why we care)
+ */
+static Bool
+AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes,
+ Bool contig, Pixel *pixels, Pixel *pMask)
+{
+ EntryPtr ent;
+ Pixel pixel, base, entries, maxp, save;
+ int dplanes, found;
+ Pixel *ppix;
+ Pixel mask;
+ Pixel finalmask;
+
+ dplanes = pmap->pVisual->nplanes;
+
+ /* Easy case. Allocate pixels only */
+ if (planes == 0)
+ {
+ /* allocate writable entries */
+ ppix = pixels;
+ ent = pentFirst;
+ pixel = 0;
+ while (--count >= 0)
+ {
+ /* Just find count unallocated cells */
+ while (ent->refcnt)
+ {
+ ent++;
+ pixel++;
+ }
+ ent->refcnt = AllocPrivate;
+ *ppix++ = pixel;
+ ent->fShared = FALSE;
+ }
+ *pMask = 0;
+ return (TRUE);
+ }
+ else if (planes > dplanes)
+ {
+ return (FALSE);
+ }
+
+ /* General case count pixels * 2 ^ planes cells to be allocated */
+
+ /* make room for new pixels */
+ ent = pentFirst;
+
+ /* first try for contiguous planes, since it's fastest */
+ for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
+ --dplanes >= 0;
+ mask += mask, base += base)
+ {
+ ppix = pixels;
+ found = 0;
+ pixel = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ while (pixel < entries)
+ {
+ save = pixel;
+ maxp = pixel + mask + base;
+ /* check if all are free */
+ while (pixel != maxp && ent[pixel].refcnt == 0)
+ pixel += base;
+ if (pixel == maxp)
+ {
+ /* this one works */
+ *ppix++ = save;
+ found++;
+ if (found == count)
+ {
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = pixels[count];
+ maxp = pixel + mask;
+ while (1)
+ {
+ ent[pixel].refcnt = AllocPrivate;
+ ent[pixel].fShared = FALSE;
+ if (pixel == maxp)
+ break;
+ pixel += base;
+ *ppix++ = pixel;
+ }
+ }
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ pixel = save + 1;
+ if (pixel & mask)
+ pixel += mask;
+ }
+ }
+
+ dplanes = pmap->pVisual->nplanes;
+ if (contig || planes == 1 || dplanes < 3)
+ return (FALSE);
+
+ /* this will be very slow for large maps, need a better algorithm */
+
+ /*
+ we can generate the smallest and largest numbers that fits in dplanes
+ bits and contain exactly planes bits set as follows. First, we need to
+ check that it is possible to generate such a mask at all.
+ (Non-contiguous masks need one more bit than contiguous masks). Then
+ the smallest such mask consists of the rightmost planes-1 bits set, then
+ a zero, then a one in position planes + 1. The formula is
+ (3 << (planes-1)) -1
+ The largest such masks consists of the leftmost planes-1 bits set, then
+ a zero, then a one bit in position dplanes-planes-1. If dplanes is
+ smaller than 32 (the number of bits in a word) then the formula is:
+ (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
+ If dplanes = 32, then we can't calculate (1<<dplanes) and we have
+ to use:
+ ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
+
+ << Thank you, Loretta>>>
+
+ */
+
+ finalmask =
+ (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
+ (((Pixel)1)<<(dplanes-planes-1));
+ for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
+ {
+ /* next 3 magic statements count number of ones (HAKMEM #169) */
+ pixel = (mask >> 1) & 033333333333;
+ pixel = mask - pixel - ((pixel >> 1) & 033333333333);
+ if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
+ continue;
+ ppix = pixels;
+ found = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ base = lowbit (mask);
+ for (pixel = 0; pixel < entries; pixel++)
+ {
+ if (pixel & mask)
+ continue;
+ maxp = 0;
+ /* check if all are free */
+ while (ent[pixel + maxp].refcnt == 0)
+ {
+ GetNextBitsOrBreak(maxp, mask, base);
+ }
+ if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
+ continue;
+ /* this one works */
+ *ppix++ = pixel;
+ found++;
+ if (found < count)
+ continue;
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = (pixels)[count];
+ maxp = 0;
+ while (1)
+ {
+ ent[pixel + maxp].refcnt = AllocPrivate;
+ ent[pixel + maxp].fShared = FALSE;
+ GetNextBitsOrBreak(maxp, mask, base);
+ *ppix++ = pixel + maxp;
+ }
+ }
+
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ return (FALSE);
+}
+
+/**
+ *
+ * \param ppixFirst First of the client's new pixels
+ */
+static Bool
+AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b,
+ Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst)
+{
+ Pixel *pptr, *cptr;
+ int npix, z, npixClientNew, npixShared;
+ Pixel basemask, base, bits, common;
+ SHAREDCOLOR *pshared, **ppshared, **psharedList;
+
+ npixClientNew = c << (r + g + b);
+ npixShared = (c << r) + (c << g) + (c << b);
+ psharedList = (SHAREDCOLOR **)ALLOCATE_LOCAL(npixShared *
+ sizeof(SHAREDCOLOR *));
+ if (!psharedList)
+ return FALSE;
+ ppshared = psharedList;
+ for (z = npixShared; --z >= 0; )
+ {
+ if (!(ppshared[z] = (SHAREDCOLOR *)xalloc(sizeof(SHAREDCOLOR))))
+ {
+ for (z++ ; z < npixShared; z++)
+ xfree(ppshared[z]);
+ return FALSE;
+ }
+ }
+ for(pptr = ppix, npix = c; --npix >= 0; pptr++)
+ {
+ basemask = ~(gmask | bmask);
+ common = *pptr & basemask;
+ if (rmask)
+ {
+ bits = 0;
+ base = lowbit (rmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, rmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | bmask);
+ common = *pptr & basemask;
+ if (gmask)
+ {
+ bits = 0;
+ base = lowbit (gmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, gmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | gmask);
+ common = *pptr & basemask;
+ if (bmask)
+ {
+ bits = 0;
+ base = lowbit (bmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + g);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, bmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(psharedList);
+ return TRUE;
+}
+
+
+/** FreeColors
+ * Free colors and/or cells (probably slow for large numbers)
+ */
+_X_EXPORT int
+FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask)
+{
+ int rval, result, class;
+ Pixel rmask;
+
+ class = pmap->class;
+ if (pmap->flags & AllAllocated)
+ return(BadAccess);
+ if ((class | DynamicClass) == DirectColor)
+ {
+ rmask = mask & RGBMASK(pmap->pVisual);
+ result = FreeCo(pmap, client, REDMAP, count, pixels,
+ mask & pmap->pVisual->redMask);
+ /* If any of the three calls fails, we must report that, if more
+ * than one fails, it's ok that we report the last one */
+ rval = FreeCo(pmap, client, GREENMAP, count, pixels,
+ mask & pmap->pVisual->greenMask);
+ if(rval != Success)
+ result = rval;
+ rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
+ mask & pmap->pVisual->blueMask);
+ if(rval != Success)
+ result = rval;
+ }
+ else
+ {
+ rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
+ result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
+ }
+ if ((mask != rmask) && count)
+ {
+ clientErrorValue = *pixels | mask;
+ result = BadValue;
+ }
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return (result);
+}
+
+/**
+ * Helper for FreeColors -- frees all combinations of *newpixels and mask bits
+ * which the client has allocated in channel colormap cells of pmap.
+ * doesn't change newpixels if it doesn't need to
+ *
+ * \param pmap which colormap head
+ * \param color which sub-map, eg, RED, BLUE, PSEUDO
+ * \param npixIn number of pixels passed in
+ * \param ppixIn number of base pixels
+ * \param mask mask client gave us
+ */
+static int
+FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask)
+{
+ Pixel *ppixClient, pixTest;
+ int npixClient, npixNew, npix;
+ Pixel bits, base, cmask, rgbbad;
+ Pixel *pptr, *cptr;
+ int n, zapped;
+ int errVal = Success;
+ int offset, numents;
+
+ if (npixIn == 0)
+ return (errVal);
+ bits = 0;
+ zapped = 0;
+ base = lowbit (mask);
+
+ switch(color)
+ {
+ case REDMAP:
+ cmask = pmap->pVisual->redMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetRed;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ case GREENMAP:
+ cmask = pmap->pVisual->greenMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetGreen;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsGreen[client];
+ npixClient = pmap->numPixelsGreen[client];
+ break;
+ case BLUEMAP:
+ cmask = pmap->pVisual->blueMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetBlue;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsBlue[client];
+ npixClient = pmap->numPixelsBlue[client];
+ break;
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ cmask = ~((Pixel)0);
+ rgbbad = 0;
+ offset = 0;
+ numents = pmap->pVisual->ColormapEntries;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ }
+
+
+ /* zap all pixels which match */
+ while (1)
+ {
+ /* go through pixel list */
+ for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
+ {
+ pixTest = ((*pptr | bits) & cmask) >> offset;
+ if ((pixTest >= numents) || (*pptr & rgbbad))
+ {
+ clientErrorValue = *pptr | bits;
+ errVal = BadValue;
+ continue;
+ }
+
+ /* find match in client list */
+ for (cptr = ppixClient, npix = npixClient;
+ --npix >= 0 && *cptr != pixTest;
+ cptr++) ;
+
+ if (npix >= 0)
+ {
+ if (pmap->class & DynamicClass)
+ {
+ FreeCell(pmap, pixTest, color);
+ }
+ *cptr = ~((Pixel)0);
+ zapped++;
+ }
+ else
+ errVal = BadAccess;
+ }
+ /* generate next bits value */
+ GetNextBitsOrBreak(bits, mask, base);
+ }
+
+ /* delete freed pixels from client pixel list */
+ if (zapped)
+ {
+ npixNew = npixClient - zapped;
+ if (npixNew)
+ {
+ /* Since the list can only get smaller, we can do a copy in
+ * place and then realloc to a smaller size */
+ pptr = cptr = ppixClient;
+
+ /* If we have all the new pixels, we don't have to examine the
+ * rest of the old ones */
+ for(npix = 0; npix < npixNew; cptr++)
+ {
+ if (*cptr != ~((Pixel)0))
+ {
+ *pptr++ = *cptr;
+ npix++;
+ }
+ }
+ pptr = (Pixel *)xrealloc(ppixClient, npixNew * sizeof(Pixel));
+ if (pptr)
+ ppixClient = pptr;
+ npixClient = npixNew;
+ }
+ else
+ {
+ npixClient = 0;
+ xfree(ppixClient);
+ ppixClient = (Pixel *)NULL;
+ }
+ switch(color)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->clientPixelsRed[client] = ppixClient;
+ pmap->numPixelsRed[client] = npixClient;
+ break;
+ case GREENMAP:
+ pmap->clientPixelsGreen[client] = ppixClient;
+ pmap->numPixelsGreen[client] = npixClient;
+ break;
+ case BLUEMAP:
+ pmap->clientPixelsBlue[client] = ppixClient;
+ pmap->numPixelsBlue[client] = npixClient;
+ break;
+ }
+ }
+ return (errVal);
+}
+
+
+
+/* Redefine color values */
+_X_EXPORT int
+StoreColors (ColormapPtr pmap, int count, xColorItem *defs)
+{
+ register Pixel pix;
+ register xColorItem *pdef;
+ register EntryPtr pent, pentT, pentLast;
+ register VisualPtr pVisual;
+ SHAREDCOLOR *pred, *pgreen, *pblue;
+ int n, ChgRed, ChgGreen, ChgBlue, idef;
+ int class, errVal = Success;
+ int ok;
+
+
+ class = pmap->class;
+ if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
+ {
+ return(BadAccess);
+ }
+ pVisual = pmap->pVisual;
+
+ idef = 0;
+ if((class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+ ok = TRUE;
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ if (pdef->pixel & rgbbad)
+ {
+ errVal = BadValue;
+ clientErrorValue = pdef->pixel;
+ continue;
+ }
+ pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (pix >= numred)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoRed)
+ {
+ pmap->red[pix].co.local.red = pdef->red;
+ }
+ else
+ {
+ pdef->red = pmap->red[pix].co.local.red;
+ }
+
+ pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (pix >= numgreen)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->green[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoGreen)
+ {
+ pmap->green[pix].co.local.green = pdef->green;
+ }
+ else
+ {
+ pdef->green = pmap->green[pix].co.local.green;
+ }
+
+ pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pix >= numblue)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->blue[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoBlue)
+ {
+ pmap->blue[pix].co.local.blue = pdef->blue;
+ }
+ else
+ {
+ pdef->blue = pmap->blue[pix].co.local.blue;
+ }
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ } else
+ clientErrorValue = pdef->pixel;
+ }
+ }
+ else
+ {
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+
+ ok = TRUE;
+ if (pdef->pixel >= pVisual->ColormapEntries)
+ {
+ clientErrorValue = pdef->pixel;
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ }
+ else
+ continue;
+
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ pent = &pmap->red[pdef->pixel];
+
+ if(pdef->flags & DoRed)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.red->color = pdef->red;
+ if (pent->co.shco.red->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.red = pdef->red;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->red = pent->co.shco.red->color;
+ else
+ pdef->red = pent->co.local.red;
+ }
+ if(pdef->flags & DoGreen)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.green->color = pdef->green;
+ if (pent->co.shco.green->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.green = pdef->green;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->green = pent->co.shco.green->color;
+ else
+ pdef->green = pent->co.local.green;
+ }
+ if(pdef->flags & DoBlue)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.blue->color = pdef->blue;
+ if (pent->co.shco.blue->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.blue = pdef->blue;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->blue = pent->co.shco.blue->color;
+ else
+ pdef->blue = pent->co.local.blue;
+ }
+
+ if(!ok)
+ {
+ /* have to run through the colormap and change anybody who
+ * shares this value */
+ pred = pent->co.shco.red;
+ pgreen = pent->co.shco.green;
+ pblue = pent->co.shco.blue;
+ ChgRed = pdef->flags & DoRed;
+ ChgGreen = pdef->flags & DoGreen;
+ ChgBlue = pdef->flags & DoBlue;
+ pentLast = pmap->red + pVisual->ColormapEntries;
+
+ for(pentT = pmap->red; pentT < pentLast; pentT++)
+ {
+ if(pentT->fShared && (pentT != pent))
+ {
+ xColorItem defChg;
+
+ /* There are, alas, devices in this world too dumb
+ * to read their own hardware colormaps. Sick, but
+ * true. So we're going to be really nice and load
+ * the xColorItem with the proper value for all the
+ * fields. We will only set the flags for those
+ * fields that actually change. Smart devices can
+ * arrange to change only those fields. Dumb devices
+ * can rest assured that we have provided for them,
+ * and can change all three fields */
+
+ defChg.flags = 0;
+ if(ChgRed && pentT->co.shco.red == pred)
+ {
+ defChg.flags |= DoRed;
+ }
+ if(ChgGreen && pentT->co.shco.green == pgreen)
+ {
+ defChg.flags |= DoGreen;
+ }
+ if(ChgBlue && pentT->co.shco.blue == pblue)
+ {
+ defChg.flags |= DoBlue;
+ }
+ if(defChg.flags != 0)
+ {
+ defChg.pixel = pentT - pmap->red;
+ defChg.red = pentT->co.shco.red->color;
+ defChg.green = pentT->co.shco.green->color;
+ defChg.blue = pentT->co.shco.blue->color;
+ (*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ /* Note that we use idef, the count of acceptable entries, and not
+ * count, the count of proposed entries */
+ if (idef != 0)
+ ( *pmap->pScreen->StoreColors) (pmap, idef, defs);
+ return (errVal);
+}
+
+int
+IsMapInstalled(Colormap map, WindowPtr pWin)
+{
+ Colormap *pmaps;
+ int imap, nummaps, found;
+
+ pmaps = (Colormap *) ALLOCATE_LOCAL(
+ pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap));
+ if(!pmaps)
+ return(FALSE);
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, pmaps);
+ found = FALSE;
+ for(imap = 0; imap < nummaps; imap++)
+ {
+ if(pmaps[imap] == map)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ DEALLOCATE_LOCAL(pmaps);
+ return (found);
+}
diff --git a/xserver/dix/cursor.c b/xserver/dix/cursor.c
new file mode 100644
index 000000000..b9ede1f76
--- /dev/null
+++ b/xserver/dix/cursor.c
@@ -0,0 +1,457 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "dixfontstr.h"
+#include "opaque.h"
+
+typedef struct _GlyphShare {
+ FontPtr font;
+ unsigned short sourceChar;
+ unsigned short maskChar;
+ CursorBitsPtr bits;
+ struct _GlyphShare *next;
+} GlyphShare, *GlyphSharePtr;
+
+static GlyphSharePtr sharedGlyphs = (GlyphSharePtr)NULL;
+
+#ifdef XFIXES
+static CARD32 cursorSerial;
+#endif
+
+static void
+FreeCursorBits(CursorBitsPtr bits)
+{
+ if (--bits->refcnt > 0)
+ return;
+ xfree(bits->source);
+ xfree(bits->mask);
+#ifdef ARGB_CURSOR
+ xfree(bits->argb);
+#endif
+ if (bits->refcnt == 0)
+ {
+ register GlyphSharePtr *prev, this;
+
+ for (prev = &sharedGlyphs;
+ (this = *prev) && (this->bits != bits);
+ prev = &this->next)
+ ;
+ if (this)
+ {
+ *prev = this->next;
+ CloseFont(this->font, (Font)0);
+ xfree(this);
+ }
+ xfree(bits);
+ }
+}
+
+/**
+ * To be called indirectly by DeleteResource; must use exactly two args.
+ *
+ * \param value must conform to DeleteType
+ */
+_X_EXPORT int
+FreeCursor(pointer value, XID cid)
+{
+ int nscr;
+ CursorPtr pCurs = (CursorPtr)value;
+
+ ScreenPtr pscr;
+
+ if ( --pCurs->refcnt > 0)
+ return(Success);
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ (void)( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(pCurs->bits);
+ xfree( pCurs);
+ return(Success);
+}
+
+
+/*
+ * We check for empty cursors so that we won't have to display them
+ */
+static void
+CheckForEmptyMask(CursorBitsPtr bits)
+{
+ register unsigned char *msk = bits->mask;
+ int n = BitmapBytePad(bits->width) * bits->height;
+
+ bits->emptyMask = FALSE;
+ while(n--)
+ if(*(msk++) != 0) return;
+#ifdef ARGB_CURSOR
+ if (bits->argb)
+ {
+ CARD32 *argb = bits->argb;
+ int n = bits->width * bits->height;
+ while (n--)
+ if (*argb++ & 0xff000000) return;
+ }
+#endif
+ bits->emptyMask = TRUE;
+}
+
+/**
+ * does nothing about the resource table, just creates the data structure.
+ * does not copy the src and mask bits
+ *
+ * \param psrcbits server-defined padding
+ * \param pmaskbits server-defined padding
+ * \param argb no padding
+ */
+CursorPtr
+AllocCursorARGB(unsigned char *psrcbits, unsigned char *pmaskbits, CARD32 *argb,
+ CursorMetricPtr cm,
+ unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
+ unsigned backRed, unsigned backGreen, unsigned backBlue)
+{
+ CursorBitsPtr bits;
+ CursorPtr pCurs;
+ int nscr;
+ ScreenPtr pscr;
+
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits));
+ if (!pCurs)
+ {
+ xfree(psrcbits);
+ xfree(pmaskbits);
+ return (CursorPtr)NULL;
+ }
+ bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
+ bits->source = psrcbits;
+ bits->mask = pmaskbits;
+#ifdef ARGB_CURSOR
+ bits->argb = argb;
+#endif
+ bits->width = cm->width;
+ bits->height = cm->height;
+ bits->xhot = cm->xhot;
+ bits->yhot = cm->yhot;
+ bits->refcnt = -1;
+ CheckForEmptyMask(bits);
+
+ pCurs->bits = bits;
+ pCurs->refcnt = 1;
+#ifdef XFIXES
+ pCurs->serialNumber = ++cursorSerial;
+ pCurs->name = None;
+#endif
+
+ pCurs->foreRed = foreRed;
+ pCurs->foreGreen = foreGreen;
+ pCurs->foreBlue = foreBlue;
+
+ pCurs->backRed = backRed;
+ pCurs->backGreen = backGreen;
+ pCurs->backBlue = backBlue;
+
+ /*
+ * realize the cursor for every screen
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ if (!( *pscr->RealizeCursor)( pscr, pCurs))
+ {
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ ( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(bits);
+ xfree(pCurs);
+ return (CursorPtr)NULL;
+ }
+ }
+ return pCurs;
+}
+
+/**
+ *
+ * \param psrcbits server-defined padding
+ * \param pmaskbits server-defined padding
+ */
+CursorPtr
+AllocCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
+ CursorMetricPtr cm,
+ unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
+ unsigned backRed, unsigned backGreen, unsigned backBlue)
+{
+ return AllocCursorARGB (psrcbits, pmaskbits, (CARD32 *) 0, cm,
+ foreRed, foreGreen, foreBlue,
+ backRed, backGreen, backBlue);
+}
+
+int
+AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
+ unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
+ unsigned backRed, unsigned backGreen, unsigned backBlue,
+ CursorPtr *ppCurs, ClientPtr client)
+{
+ FontPtr sourcefont, maskfont;
+ unsigned char *srcbits;
+ unsigned char *mskbits;
+ CursorMetricRec cm;
+ int res;
+ CursorBitsPtr bits;
+ CursorPtr pCurs;
+ int nscr;
+ ScreenPtr pscr;
+ GlyphSharePtr pShare;
+
+ sourcefont = (FontPtr) SecurityLookupIDByType(client, source, RT_FONT,
+ SecurityReadAccess);
+ maskfont = (FontPtr) SecurityLookupIDByType(client, mask, RT_FONT,
+ SecurityReadAccess);
+
+ if (!sourcefont)
+ {
+ client->errorValue = source;
+ return(BadFont);
+ }
+ if (!maskfont && (mask != None))
+ {
+ client->errorValue = mask;
+ return(BadFont);
+ }
+ if (sourcefont != maskfont)
+ pShare = (GlyphSharePtr)NULL;
+ else
+ {
+ for (pShare = sharedGlyphs;
+ pShare &&
+ ((pShare->font != sourcefont) ||
+ (pShare->sourceChar != sourceChar) ||
+ (pShare->maskChar != maskChar));
+ pShare = pShare->next)
+ ;
+ }
+ if (pShare)
+ {
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec));
+ if (!pCurs)
+ return BadAlloc;
+ bits = pShare->bits;
+ bits->refcnt++;
+ }
+ else
+ {
+ if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm))
+ {
+ client->errorValue = sourceChar;
+ return BadValue;
+ }
+ if (!maskfont)
+ {
+ register long n;
+ register unsigned char *mskptr;
+
+ n = BitmapBytePad(cm.width)*(long)cm.height;
+ mskptr = mskbits = (unsigned char *)xalloc(n);
+ if (!mskptr)
+ return BadAlloc;
+ while (--n >= 0)
+ *mskptr++ = ~0;
+ }
+ else
+ {
+ if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm))
+ {
+ client->errorValue = maskChar;
+ return BadValue;
+ }
+ if ((res = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits)) != 0)
+ return res;
+ }
+ if ((res = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits)) != 0)
+ {
+ xfree(mskbits);
+ return res;
+ }
+ if (sourcefont != maskfont)
+ {
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits));
+ if (pCurs)
+ bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
+ else
+ bits = (CursorBitsPtr)NULL;
+ }
+ else
+ {
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec));
+ if (pCurs)
+ bits = (CursorBitsPtr)xalloc(sizeof(CursorBits));
+ else
+ bits = (CursorBitsPtr)NULL;
+ }
+ if (!bits)
+ {
+ xfree(pCurs);
+ xfree(mskbits);
+ xfree(srcbits);
+ return BadAlloc;
+ }
+ bits->source = srcbits;
+ bits->mask = mskbits;
+#ifdef ARGB_CURSOR
+ bits->argb = 0;
+#endif
+ bits->width = cm.width;
+ bits->height = cm.height;
+ bits->xhot = cm.xhot;
+ bits->yhot = cm.yhot;
+ if (sourcefont != maskfont)
+ bits->refcnt = -1;
+ else
+ {
+ bits->refcnt = 1;
+ pShare = (GlyphSharePtr)xalloc(sizeof(GlyphShare));
+ if (!pShare)
+ {
+ FreeCursorBits(bits);
+ return BadAlloc;
+ }
+ pShare->font = sourcefont;
+ sourcefont->refcnt++;
+ pShare->sourceChar = sourceChar;
+ pShare->maskChar = maskChar;
+ pShare->bits = bits;
+ pShare->next = sharedGlyphs;
+ sharedGlyphs = pShare;
+ }
+ }
+ CheckForEmptyMask(bits);
+ pCurs->bits = bits;
+ pCurs->refcnt = 1;
+#ifdef XFIXES
+ pCurs->serialNumber = ++cursorSerial;
+ pCurs->name = None;
+#endif
+
+ pCurs->foreRed = foreRed;
+ pCurs->foreGreen = foreGreen;
+ pCurs->foreBlue = foreBlue;
+
+ pCurs->backRed = backRed;
+ pCurs->backGreen = backGreen;
+ pCurs->backBlue = backBlue;
+
+ /*
+ * realize the cursor for every screen
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ if (!( *pscr->RealizeCursor)( pscr, pCurs))
+ {
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ ( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(pCurs->bits);
+ xfree(pCurs);
+ return BadAlloc;
+ }
+ }
+ *ppCurs = pCurs;
+ return Success;
+}
+
+/** CreateRootCursor
+ *
+ * look up the name of a font
+ * open the font
+ * add the font to the resource table
+ * make a cursor from the glyphs
+ * add the cursor to the resource table
+ *************************************************************/
+
+CursorPtr
+CreateRootCursor(char *pfilename, unsigned glyph)
+{
+ CursorPtr curs;
+ FontPtr cursorfont;
+ int err;
+ XID fontID;
+
+ fontID = FakeClientID(0);
+ err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync,
+ (unsigned)strlen( pfilename), pfilename);
+ if (err != Success)
+ return NullCursor;
+
+ cursorfont = (FontPtr)LookupIDByType(fontID, RT_FONT);
+ if (!cursorfont)
+ return NullCursor;
+ if (AllocGlyphCursor(fontID, glyph, fontID, glyph + 1,
+ 0, 0, 0, ~0, ~0, ~0, &curs, serverClient) != Success)
+ return NullCursor;
+
+ if (!AddResource(FakeClientID(0), RT_CURSOR, (pointer)curs))
+ return NullCursor;
+
+ return curs;
+}
diff --git a/xserver/dix/devices.c b/xserver/dix/devices.c
new file mode 100644
index 000000000..607510203
--- /dev/null
+++ b/xserver/dix/devices.c
@@ -0,0 +1,1613 @@
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "site.h"
+#ifndef XKB_IN_SERVER
+#define XKB_IN_SERVER
+#endif
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+#endif
+#ifdef XACE
+#include "xace.h"
+#endif
+
+#include "dispatch.h"
+#include "swaprep.h"
+#include "dixevents.h"
+
+DeviceIntPtr
+AddInputDevice(DeviceProc deviceProc, Bool autoStart)
+{
+ register DeviceIntPtr dev;
+
+ if (inputInfo.numDevices >= MAX_DEVICES)
+ return (DeviceIntPtr)NULL;
+ dev = (DeviceIntPtr) xalloc(sizeof(DeviceIntRec));
+ if (!dev)
+ return (DeviceIntPtr)NULL;
+ dev->name = (char *)NULL;
+ dev->type = 0;
+ dev->id = inputInfo.numDevices;
+ inputInfo.numDevices++;
+ dev->public.on = FALSE;
+ dev->public.processInputProc = (ProcessInputProc)NoopDDA;
+ dev->public.realInputProc = (ProcessInputProc)NoopDDA;
+ dev->public.enqueueInputProc = EnqueueEvent;
+ dev->deviceProc = deviceProc;
+ dev->startup = autoStart;
+ dev->sync.frozen = FALSE;
+ dev->sync.other = NullGrab;
+ dev->sync.state = NOT_GRABBED;
+ dev->sync.event = (xEvent *) NULL;
+ dev->sync.evcount = 0;
+ dev->grab = NullGrab;
+ dev->grabTime = currentTime;
+ dev->fromPassiveGrab = FALSE;
+ dev->key = (KeyClassPtr)NULL;
+ dev->valuator = (ValuatorClassPtr)NULL;
+ dev->button = (ButtonClassPtr)NULL;
+ dev->focus = (FocusClassPtr)NULL;
+ dev->proximity = (ProximityClassPtr)NULL;
+ dev->kbdfeed = (KbdFeedbackPtr)NULL;
+ dev->ptrfeed = (PtrFeedbackPtr)NULL;
+ dev->intfeed = (IntegerFeedbackPtr)NULL;
+ dev->stringfeed = (StringFeedbackPtr)NULL;
+ dev->bell = (BellFeedbackPtr)NULL;
+ dev->leds = (LedFeedbackPtr)NULL;
+ dev->next = inputInfo.off_devices;
+#ifdef XKB
+ dev->xkb_interest= NULL;
+#endif
+ dev->nPrivates = 0;
+ dev->devPrivates = NULL;
+ dev->unwrapProc = NULL;
+ inputInfo.off_devices = dev;
+ return dev;
+}
+
+Bool
+EnableDevice(register DeviceIntPtr dev)
+{
+ register DeviceIntPtr *prev;
+
+ for (prev = &inputInfo.off_devices;
+ *prev && (*prev != dev);
+ prev = &(*prev)->next)
+ ;
+ if ((*prev != dev) || !dev->inited ||
+ ((*dev->deviceProc)(dev, DEVICE_ON) != Success))
+ return FALSE;
+ *prev = dev->next;
+ dev->next = inputInfo.devices;
+ inputInfo.devices = dev;
+ return TRUE;
+}
+
+Bool
+DisableDevice(register DeviceIntPtr dev)
+{
+ register DeviceIntPtr *prev;
+
+ for (prev = &inputInfo.devices;
+ *prev && (*prev != dev);
+ prev = &(*prev)->next)
+ ;
+ if (*prev != dev)
+ return FALSE;
+ (void)(*dev->deviceProc)(dev, DEVICE_OFF);
+ *prev = dev->next;
+ dev->next = inputInfo.off_devices;
+ inputInfo.off_devices = dev;
+ return TRUE;
+}
+
+int
+InitAndStartDevices()
+{
+ register DeviceIntPtr dev, next;
+
+ for (dev = inputInfo.off_devices; dev; dev = dev->next)
+ dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
+ for (dev = inputInfo.off_devices; dev; dev = next)
+ {
+ next = dev->next;
+ if (dev->inited && dev->startup)
+ (void)EnableDevice(dev);
+ }
+ for (dev = inputInfo.devices;
+ dev && (dev != inputInfo.keyboard);
+ dev = dev->next)
+ ;
+ if (!dev || (dev != inputInfo.keyboard)) {
+ ErrorF("No core keyboard\n");
+ return BadImplementation;
+ }
+ for (dev = inputInfo.devices;
+ dev && (dev != inputInfo.pointer);
+ dev = dev->next)
+ ;
+ if (!dev || (dev != inputInfo.pointer)) {
+ ErrorF("No core pointer\n");
+ return BadImplementation;
+ }
+ return Success;
+}
+
+static void
+CloseDevice(register DeviceIntPtr dev)
+{
+ KbdFeedbackPtr k, knext;
+ PtrFeedbackPtr p, pnext;
+ IntegerFeedbackPtr i, inext;
+ StringFeedbackPtr s, snext;
+ BellFeedbackPtr b, bnext;
+ LedFeedbackPtr l, lnext;
+
+ if (dev->inited)
+ (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
+ xfree(dev->name);
+ if (dev->key)
+ {
+#ifdef XKB
+ if (dev->key->xkbInfo)
+ XkbFreeInfo(dev->key->xkbInfo);
+#endif
+ xfree(dev->key->curKeySyms.map);
+ xfree(dev->key->modifierKeyMap);
+ xfree(dev->key);
+ }
+ xfree(dev->valuator);
+#ifdef XKB
+ if ((dev->button)&&(dev->button->xkb_acts))
+ xfree(dev->button->xkb_acts);
+#endif
+ xfree(dev->button);
+ if (dev->focus)
+ {
+ xfree(dev->focus->trace);
+ xfree(dev->focus);
+ }
+ xfree(dev->proximity);
+ for (k=dev->kbdfeed; k; k=knext)
+ {
+ knext = k->next;
+#ifdef XKB
+ if (k->xkb_sli)
+ XkbFreeSrvLedInfo(k->xkb_sli);
+#endif
+ xfree(k);
+ }
+ for (p=dev->ptrfeed; p; p=pnext)
+ {
+ pnext = p->next;
+ xfree(p);
+ }
+ for (i=dev->intfeed; i; i=inext)
+ {
+ inext = i->next;
+ xfree(i);
+ }
+ for (s=dev->stringfeed; s; s=snext)
+ {
+ snext = s->next;
+ xfree(s->ctrl.symbols_supported);
+ xfree(s->ctrl.symbols_displayed);
+ xfree(s);
+ }
+ for (b=dev->bell; b; b=bnext)
+ {
+ bnext = b->next;
+ xfree(b);
+ }
+ for (l=dev->leds; l; l=lnext)
+ {
+ lnext = l->next;
+#ifdef XKB
+ if (l->xkb_sli)
+ XkbFreeSrvLedInfo(l->xkb_sli);
+#endif
+ xfree(l);
+ }
+#ifdef XKB
+ while (dev->xkb_interest) {
+ XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
+ }
+#endif
+ xfree(dev->sync.event);
+ xfree(dev);
+}
+
+void
+CloseDownDevices()
+{
+ register DeviceIntPtr dev, next;
+
+ for (dev = inputInfo.devices; dev; dev = next)
+ {
+ next = dev->next;
+ CloseDevice(dev);
+ }
+ for (dev = inputInfo.off_devices; dev; dev = next)
+ {
+ next = dev->next;
+ CloseDevice(dev);
+ }
+ inputInfo.devices = NULL;
+ inputInfo.off_devices = NULL;
+ inputInfo.keyboard = NULL;
+ inputInfo.pointer = NULL;
+}
+
+void
+RemoveDevice(register DeviceIntPtr dev)
+{
+ register DeviceIntPtr prev,tmp,next;
+
+ prev= NULL;
+ for (tmp= inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
+ next = tmp->next;
+ if (tmp==dev) {
+ CloseDevice(tmp);
+ if (prev==NULL)
+ inputInfo.devices = next;
+ else
+ prev->next = next;
+ inputInfo.numDevices--;
+ if (inputInfo.keyboard == tmp)
+ inputInfo.keyboard = NULL;
+ else if (inputInfo.pointer == tmp)
+ inputInfo.pointer = NULL;
+ return;
+ }
+ }
+
+ prev= NULL;
+ for (tmp= inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
+ next = tmp->next;
+ if (tmp==dev) {
+ CloseDevice(tmp);
+ if (prev==NULL)
+ inputInfo.off_devices = next;
+ else
+ prev->next = next;
+ inputInfo.numDevices--;
+ if (inputInfo.keyboard == tmp)
+ inputInfo.keyboard = NULL;
+ else if (inputInfo.pointer == tmp)
+ inputInfo.pointer = NULL;
+ return;
+ }
+ }
+ ErrorF("Internal Error! Attempt to remove a non-existent device\n");
+ return;
+}
+
+int
+NumMotionEvents()
+{
+ return inputInfo.pointer->valuator->numMotionEvents;
+}
+
+void
+RegisterPointerDevice(DeviceIntPtr device)
+{
+ inputInfo.pointer = device;
+#ifdef XKB
+ device->public.processInputProc = CoreProcessPointerEvent;
+ device->public.realInputProc = CoreProcessPointerEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(device,ProcessPointerEvent);
+#else
+ device->public.processInputProc = ProcessPointerEvent;
+ device->public.realInputProc = ProcessPointerEvent;
+#endif
+ device->ActivateGrab = ActivatePointerGrab;
+ device->DeactivateGrab = DeactivatePointerGrab;
+ if (!device->name)
+ {
+ char *p = "pointer";
+ device->name = (char *)xalloc(strlen(p) + 1);
+ strcpy(device->name, p);
+ }
+}
+
+void
+RegisterKeyboardDevice(DeviceIntPtr device)
+{
+ inputInfo.keyboard = device;
+#ifdef XKB
+ device->public.processInputProc = CoreProcessKeyboardEvent;
+ device->public.realInputProc = CoreProcessKeyboardEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(device,ProcessKeyboardEvent);
+#else
+ device->public.processInputProc = ProcessKeyboardEvent;
+ device->public.realInputProc = ProcessKeyboardEvent;
+#endif
+ device->ActivateGrab = ActivateKeyboardGrab;
+ device->DeactivateGrab = DeactivateKeyboardGrab;
+ if (!device->name)
+ {
+ char *k = "keyboard";
+ device->name = (char *)xalloc(strlen(k) + 1);
+ strcpy(device->name, k);
+ }
+}
+
+_X_EXPORT DevicePtr
+LookupKeyboardDevice()
+{
+ return inputInfo.keyboard ? &inputInfo.keyboard->public : NULL;
+}
+
+_X_EXPORT DevicePtr
+LookupPointerDevice()
+{
+ return inputInfo.pointer ? &inputInfo.pointer->public : NULL;
+}
+
+DevicePtr
+LookupDevice(int id)
+{
+ DeviceIntPtr dev;
+
+ for (dev=inputInfo.devices; dev; dev=dev->next) {
+ if (dev->id == (CARD8)id)
+ return (DevicePtr)dev;
+ }
+ for (dev=inputInfo.off_devices; dev; dev=dev->next) {
+ if (dev->id == (CARD8)id)
+ return (DevicePtr)dev;
+ }
+ return NULL;
+}
+
+void
+QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
+{
+ if (inputInfo.keyboard) {
+ *minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode;
+ *maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode;
+ }
+}
+
+Bool
+SetKeySymsMap(register KeySymsPtr dst, register KeySymsPtr src)
+{
+ int i, j;
+ int rowDif = src->minKeyCode - dst->minKeyCode;
+ /* if keysym map size changes, grow map first */
+
+ if (src->mapWidth < dst->mapWidth)
+ {
+ for (i = src->minKeyCode; i <= src->maxKeyCode; i++)
+ {
+#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c))
+#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c))
+ for (j = 0; j < src->mapWidth; j++)
+ dst->map[DI(i, j)] = src->map[SI(i, j)];
+ for (j = src->mapWidth; j < dst->mapWidth; j++)
+ dst->map[DI(i, j)] = NoSymbol;
+#undef SI
+#undef DI
+ }
+ return TRUE;
+ }
+ else if (src->mapWidth > dst->mapWidth)
+ {
+ KeySym *map;
+ int bytes = sizeof(KeySym) * src->mapWidth *
+ (dst->maxKeyCode - dst->minKeyCode + 1);
+ map = (KeySym *)xalloc(bytes);
+ if (!map)
+ return FALSE;
+ bzero((char *)map, bytes);
+ if (dst->map)
+ {
+ for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
+ memmove((char *)&map[i*src->mapWidth],
+ (char *)&dst->map[i*dst->mapWidth],
+ dst->mapWidth * sizeof(KeySym));
+ xfree(dst->map);
+ }
+ dst->mapWidth = src->mapWidth;
+ dst->map = map;
+ }
+ memmove((char *)&dst->map[rowDif * dst->mapWidth],
+ (char *)src->map,
+ (int)(src->maxKeyCode - src->minKeyCode + 1) *
+ dst->mapWidth * sizeof(KeySym));
+ return TRUE;
+}
+
+static Bool
+InitModMap(register KeyClassPtr keyc)
+{
+ int i, j;
+ CARD8 keysPerModifier[8];
+ CARD8 mask;
+
+ keyc->maxKeysPerModifier = 0;
+ for (i = 0; i < 8; i++)
+ keysPerModifier[i] = 0;
+ for (i = 8; i < MAP_LENGTH; i++)
+ {
+ for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
+ {
+ if (mask & keyc->modifierMap[i])
+ {
+ if (++keysPerModifier[j] > keyc->maxKeysPerModifier)
+ keyc->maxKeysPerModifier = keysPerModifier[j];
+ }
+ }
+ }
+ keyc->modifierKeyMap = (KeyCode *)xalloc(8*keyc->maxKeysPerModifier);
+ if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier)
+ return (FALSE);
+ bzero((char *)keyc->modifierKeyMap, 8*(int)keyc->maxKeysPerModifier);
+ for (i = 0; i < 8; i++)
+ keysPerModifier[i] = 0;
+ for (i = 8; i < MAP_LENGTH; i++)
+ {
+ for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
+ {
+ if (mask & keyc->modifierMap[i])
+ {
+ keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) +
+ keysPerModifier[j]] = i;
+ keysPerModifier[j]++;
+ }
+ }
+ }
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[])
+{
+ int i;
+ register KeyClassPtr keyc;
+
+ keyc = (KeyClassPtr)xalloc(sizeof(KeyClassRec));
+ if (!keyc)
+ return FALSE;
+ keyc->curKeySyms.map = (KeySym *)NULL;
+ keyc->curKeySyms.mapWidth = 0;
+ keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode;
+ keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode;
+ keyc->modifierKeyMap = (KeyCode *)NULL;
+ keyc->state = 0;
+ keyc->prev_state = 0;
+ if (pModifiers)
+ memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH);
+ else
+ bzero((char *)keyc->modifierMap, MAP_LENGTH);
+ bzero((char *)keyc->down, DOWN_LENGTH);
+ for (i = 0; i < 8; i++)
+ keyc->modifierKeyCount[i] = 0;
+ if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
+ {
+ xfree(keyc->curKeySyms.map);
+ xfree(keyc->modifierKeyMap);
+ xfree(keyc);
+ return FALSE;
+ }
+ dev->key = keyc;
+#ifdef XKB
+ dev->key->xkbInfo= NULL;
+ if (!noXkbExtension) XkbInitDevice(dev);
+#endif
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitButtonClassDeviceStruct(register DeviceIntPtr dev, int numButtons,
+ CARD8 *map)
+{
+ register ButtonClassPtr butc;
+ int i;
+
+ butc = (ButtonClassPtr)xalloc(sizeof(ButtonClassRec));
+ if (!butc)
+ return FALSE;
+ butc->numButtons = numButtons;
+ for (i = 1; i <= numButtons; i++)
+ butc->map[i] = map[i];
+ butc->buttonsDown = 0;
+ butc->state = 0;
+ butc->motionMask = 0;
+ bzero((char *)butc->down, DOWN_LENGTH);
+#ifdef XKB
+ butc->xkb_acts= NULL;
+#endif
+ dev->button = butc;
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
+ ValuatorMotionProcPtr motionProc,
+ int numMotionEvents, int mode)
+{
+ int i;
+ register ValuatorClassPtr valc;
+
+ valc = (ValuatorClassPtr)xalloc(sizeof(ValuatorClassRec) +
+ numAxes * sizeof(AxisInfo) +
+ numAxes * sizeof(unsigned int));
+ if (!valc)
+ return FALSE;
+ valc->GetMotionProc = motionProc;
+ valc->numMotionEvents = numMotionEvents;
+ valc->motionHintWindow = NullWindow;
+ valc->numAxes = numAxes;
+ valc->mode = mode;
+ valc->axes = (AxisInfoPtr)(valc + 1);
+ valc->axisVal = (int *)(valc->axes + numAxes);
+ for (i=0; i<numAxes; i++)
+ valc->axisVal[i]=0;
+ dev->valuator = valc;
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitFocusClassDeviceStruct(DeviceIntPtr dev)
+{
+ register FocusClassPtr focc;
+
+ focc = (FocusClassPtr)xalloc(sizeof(FocusClassRec));
+ if (!focc)
+ return FALSE;
+ focc->win = PointerRootWin;
+ focc->revert = None;
+ focc->time = currentTime;
+ focc->trace = (WindowPtr *)NULL;
+ focc->traceSize = 0;
+ focc->traceGood = 0;
+ dev->focus = focc;
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
+ KbdCtrlProcPtr controlProc)
+{
+ register KbdFeedbackPtr feedc;
+
+ feedc = (KbdFeedbackPtr)xalloc(sizeof(KbdFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->BellProc = bellProc;
+ feedc->CtrlProc = controlProc;
+#ifdef XKB
+ defaultKeyboardControl.autoRepeat = TRUE;
+#endif
+ feedc->ctrl = defaultKeyboardControl;
+ feedc->ctrl.id = 0;
+ if ((feedc->next = dev->kbdfeed) != 0)
+ feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1;
+ dev->kbdfeed = feedc;
+#ifdef XKB
+ feedc->xkb_sli= NULL;
+ if (!noXkbExtension)
+ XkbFinishDeviceInit(dev);
+#endif
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
+{
+ register PtrFeedbackPtr feedc;
+
+ feedc = (PtrFeedbackPtr)xalloc(sizeof(PtrFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultPointerControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->ptrfeed) )
+ feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
+ dev->ptrfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+
+LedCtrl defaultLedControl = {
+ DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
+
+BellCtrl defaultBellControl = {
+ DEFAULT_BELL,
+ DEFAULT_BELL_PITCH,
+ DEFAULT_BELL_DURATION,
+ 0};
+
+IntegerCtrl defaultIntegerControl = {
+ DEFAULT_INT_RESOLUTION,
+ DEFAULT_INT_MIN_VALUE,
+ DEFAULT_INT_MAX_VALUE,
+ DEFAULT_INT_DISPLAYED,
+ 0};
+
+_X_EXPORT Bool
+InitStringFeedbackClassDeviceStruct (
+ DeviceIntPtr dev, StringCtrlProcPtr controlProc,
+ int max_symbols, int num_symbols_supported, KeySym *symbols)
+{
+ int i;
+ register StringFeedbackPtr feedc;
+
+ feedc = (StringFeedbackPtr)xalloc(sizeof(StringFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl.num_symbols_supported = num_symbols_supported;
+ feedc->ctrl.num_symbols_displayed = 0;
+ feedc->ctrl.max_symbols = max_symbols;
+ feedc->ctrl.symbols_supported = (KeySym *)
+ xalloc (sizeof (KeySym) * num_symbols_supported);
+ feedc->ctrl.symbols_displayed = (KeySym *)
+ xalloc (sizeof (KeySym) * max_symbols);
+ if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
+ {
+ if (feedc->ctrl.symbols_supported)
+ xfree(feedc->ctrl.symbols_supported);
+ if (feedc->ctrl.symbols_displayed)
+ xfree(feedc->ctrl.symbols_displayed);
+ xfree(feedc);
+ return FALSE;
+ }
+ for (i=0; i<num_symbols_supported; i++)
+ *(feedc->ctrl.symbols_supported+i) = *symbols++;
+ for (i=0; i<max_symbols; i++)
+ *(feedc->ctrl.symbols_displayed+i) = (KeySym) NULL;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->stringfeed) )
+ feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
+ dev->stringfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
+ BellCtrlProcPtr controlProc)
+{
+ register BellFeedbackPtr feedc;
+
+ feedc = (BellFeedbackPtr)xalloc(sizeof(BellFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->BellProc = bellProc;
+ feedc->ctrl = defaultBellControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->bell) )
+ feedc->ctrl.id = dev->bell->ctrl.id + 1;
+ dev->bell = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
+{
+ register LedFeedbackPtr feedc;
+
+ feedc = (LedFeedbackPtr)xalloc(sizeof(LedFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultLedControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->leds) )
+ feedc->ctrl.id = dev->leds->ctrl.id + 1;
+#ifdef XKB
+ feedc->xkb_sli= NULL;
+#endif
+ dev->leds = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
+{
+ register IntegerFeedbackPtr feedc;
+
+ feedc = (IntegerFeedbackPtr)xalloc(sizeof(IntegerFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultIntegerControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->intfeed) )
+ feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
+ dev->intfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+_X_EXPORT Bool
+InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
+ ValuatorMotionProcPtr motionProc,
+ PtrCtrlProcPtr controlProc, int numMotionEvents)
+{
+ DeviceIntPtr dev = (DeviceIntPtr)device;
+
+ return(InitButtonClassDeviceStruct(dev, numButtons, map) &&
+ InitValuatorClassDeviceStruct(dev, 2, motionProc,
+ numMotionEvents, 0) &&
+ InitPtrFeedbackClassDeviceStruct(dev, controlProc));
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
+ CARD8 pModifiers[], BellProcPtr bellProc,
+ KbdCtrlProcPtr controlProc)
+{
+ DeviceIntPtr dev = (DeviceIntPtr)device;
+
+ return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) &&
+ InitFocusClassDeviceStruct(dev) &&
+ InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc));
+}
+
+_X_EXPORT void
+SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
+ ClientPtr client)
+{
+ int i;
+ xEvent event;
+
+ event.u.u.type = MappingNotify;
+ event.u.mappingNotify.request = request;
+ if (request == MappingKeyboard)
+ {
+ event.u.mappingNotify.firstKeyCode = firstKeyCode;
+ event.u.mappingNotify.count = count;
+ }
+#ifdef XKB
+ if (!noXkbExtension &&
+ ((request == MappingKeyboard) || (request == MappingModifier))) {
+ XkbApplyMappingChange(inputInfo.keyboard,request,firstKeyCode,count,
+ client);
+ }
+#endif
+
+ /* 0 is the server client */
+ for (i=1; i<currentMaxClients; i++)
+ {
+ if (clients[i] && clients[i]->clientState == ClientStateRunning)
+ {
+#ifdef XKB
+ if (!noXkbExtension &&
+ (request == MappingKeyboard) &&
+ (clients[i]->xkbClientFlags != 0) &&
+ (clients[i]->mapNotifyMask&XkbKeySymsMask))
+ continue;
+#endif
+ event.u.u.sequenceNumber = clients[i]->sequence;
+ WriteEventsToClient(clients[i], 1, &event);
+ }
+ }
+}
+
+/*
+ * n-squared algorithm. n < 255 and don't want to copy the whole thing and
+ * sort it to do the checking. How often is it called? Just being lazy?
+ */
+Bool
+BadDeviceMap(register BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
+{
+ register int i, j;
+
+ for (i = 0; i < length; i++)
+ if (buff[i]) /* only check non-zero elements */
+ {
+ if ((low > buff[i]) || (high < buff[i]))
+ {
+ *errval = buff[i];
+ return TRUE;
+ }
+ for (j = i + 1; j < length; j++)
+ if (buff[i] == buff[j])
+ {
+ *errval = buff[i];
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+Bool
+AllModifierKeysAreUp(dev, map1, per1, map2, per2)
+ register DeviceIntPtr dev;
+ register CARD8 *map1, *map2;
+ int per1, per2;
+{
+ register int i, j, k;
+ register CARD8 *down = dev->key->down;
+
+ for (i = 8; --i >= 0; map2 += per2)
+ {
+ for (j = per1; --j >= 0; map1++)
+ {
+ if (*map1 && BitIsOn(down, *map1))
+ {
+ for (k = per2; (--k >= 0) && (*map1 != map2[k]);)
+ ;
+ if (k < 0)
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+int
+ProcSetModifierMapping(ClientPtr client)
+{
+ xSetModifierMappingReply rep;
+ REQUEST(xSetModifierMappingReq);
+ KeyCode *inputMap;
+ int inputMapLen;
+ register int i;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ register KeyClassPtr keyc = keybd->key;
+
+ REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
+
+ if (client->req_len != ((stuff->numKeyPerModifier<<1) +
+ (sizeof (xSetModifierMappingReq)>>2)))
+ return BadLength;
+
+ inputMapLen = 8*stuff->numKeyPerModifier;
+ inputMap = (KeyCode *)&stuff[1];
+
+ /*
+ * Now enforce the restriction that "all of the non-zero keycodes must be
+ * in the range specified by min-keycode and max-keycode in the
+ * connection setup (else a Value error)"
+ */
+ i = inputMapLen;
+ while (i--)
+ {
+ if (inputMap[i]
+ && (inputMap[i] < keyc->curKeySyms.minKeyCode
+ || inputMap[i] > keyc->curKeySyms.maxKeyCode))
+ {
+ client->errorValue = inputMap[i];
+ return BadValue;
+ }
+ }
+
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, keybd, TRUE))
+ return BadAccess;
+#endif
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.success = MappingSuccess;
+
+ /*
+ * Now enforce the restriction that none of the old or new
+ * modifier keys may be down while we change the mapping, and
+ * that the DDX layer likes the choice.
+ */
+ if (!AllModifierKeysAreUp(keybd, keyc->modifierKeyMap,
+ (int)keyc->maxKeysPerModifier,
+ inputMap, (int)stuff->numKeyPerModifier)
+ ||
+ !AllModifierKeysAreUp(keybd, inputMap, (int)stuff->numKeyPerModifier,
+ keyc->modifierKeyMap,
+ (int)keyc->maxKeysPerModifier))
+ {
+ rep.success = MappingBusy;
+ }
+ else
+ {
+ for (i = 0; i < inputMapLen; i++)
+ {
+ if (inputMap[i] && !LegalModifier(inputMap[i], (DevicePtr)keybd))
+ {
+ rep.success = MappingFailed;
+ break;
+ }
+ }
+ }
+
+ if (rep.success == MappingSuccess)
+ {
+ KeyCode *map;
+ /*
+ * Now build the keyboard's modifier bitmap from the
+ * list of keycodes.
+ */
+ map = (KeyCode *)xalloc(inputMapLen);
+ if (!map && inputMapLen)
+ return BadAlloc;
+ if (keyc->modifierKeyMap)
+ xfree(keyc->modifierKeyMap);
+ keyc->modifierKeyMap = map;
+ memmove((char *)map, (char *)inputMap, inputMapLen);
+
+ keyc->maxKeysPerModifier = stuff->numKeyPerModifier;
+ for (i = 0; i < MAP_LENGTH; i++)
+ keyc->modifierMap[i] = 0;
+ for (i = 0; i < inputMapLen; i++)
+ {
+ if (inputMap[i])
+ keyc->modifierMap[inputMap[i]] |=
+ (1<<(((unsigned int)i)/keyc->maxKeysPerModifier));
+ }
+ }
+
+ if (rep.success == MappingSuccess)
+ SendMappingNotify(MappingModifier, 0, 0, client);
+
+ WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
+
+ return(client->noClientException);
+}
+
+int
+ProcGetModifierMapping(ClientPtr client)
+{
+ xGetModifierMappingReply rep;
+ register KeyClassPtr keyc = inputInfo.keyboard->key;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.numKeyPerModifier = keyc->maxKeysPerModifier;
+ rep.sequenceNumber = client->sequence;
+ /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
+ rep.length = keyc->maxKeysPerModifier << 1;
+
+ WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
+
+ /* Use the (modified by DDX) map that SetModifierMapping passed in */
+ (void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3),
+ (char *)keyc->modifierKeyMap);
+ return client->noClientException;
+}
+
+int
+ProcChangeKeyboardMapping(ClientPtr client)
+{
+ REQUEST(xChangeKeyboardMappingReq);
+ unsigned len;
+ KeySymsRec keysyms;
+ register KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
+
+ len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);
+ if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
+ return BadLength;
+ if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+ (stuff->firstKeyCode > curKeySyms->maxKeyCode))
+ {
+ client->errorValue = stuff->firstKeyCode;
+ return BadValue;
+ }
+ if ( ((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
+ curKeySyms->maxKeyCode) ||
+ (stuff->keySymsPerKeyCode == 0))
+ {
+ client->errorValue = stuff->keySymsPerKeyCode;
+ return BadValue;
+ }
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
+ return BadAccess;
+#endif
+ keysyms.minKeyCode = stuff->firstKeyCode;
+ keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
+ keysyms.mapWidth = stuff->keySymsPerKeyCode;
+ keysyms.map = (KeySym *)&stuff[1];
+ if (!SetKeySymsMap(curKeySyms, &keysyms))
+ return BadAlloc;
+ SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
+ client);
+ return client->noClientException;
+
+}
+
+int
+ProcSetPointerMapping(ClientPtr client)
+{
+ REQUEST(xSetPointerMappingReq);
+ BYTE *map;
+ xSetPointerMappingReply rep;
+ register unsigned int i;
+ DeviceIntPtr mouse = inputInfo.pointer;
+
+ REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
+ if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2)
+ return BadLength;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.success = MappingSuccess;
+ map = (BYTE *)&stuff[1];
+ if (stuff->nElts != mouse->button->numButtons)
+ {
+ client->errorValue = stuff->nElts;
+ return BadValue;
+ }
+ if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
+ return BadValue;
+ for (i=0; i < stuff->nElts; i++)
+ if ((mouse->button->map[i + 1] != map[i]) &&
+ BitIsOn(mouse->button->down, i + 1))
+ {
+ rep.success = MappingBusy;
+ WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+ return Success;
+ }
+ for (i = 0; i < stuff->nElts; i++)
+ mouse->button->map[i + 1] = map[i];
+ SendMappingNotify(MappingPointer, 0, 0, client);
+ WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+ return Success;
+}
+
+int
+ProcGetKeyboardMapping(ClientPtr client)
+{
+ xGetKeyboardMappingReply rep;
+ REQUEST(xGetKeyboardMappingReq);
+ KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+
+ REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
+
+ if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+ (stuff->firstKeyCode > curKeySyms->maxKeyCode))
+ {
+ client->errorValue = stuff->firstKeyCode;
+ return BadValue;
+ }
+ if (stuff->firstKeyCode + stuff->count >
+ (unsigned)(curKeySyms->maxKeyCode + 1))
+ {
+ client->errorValue = stuff->count;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.keySymsPerKeyCode = curKeySyms->mapWidth;
+ /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
+ rep.length = (curKeySyms->mapWidth * stuff->count);
+ WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+ WriteSwappedDataToClient(
+ client,
+ curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
+ &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
+ curKeySyms->mapWidth]);
+
+ return client->noClientException;
+}
+
+int
+ProcGetPointerMapping(ClientPtr client)
+{
+ xGetPointerMappingReply rep;
+ ButtonClassPtr butc = inputInfo.pointer->button;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.nElts = butc->numButtons;
+ rep.length = ((unsigned)rep.nElts + (4-1))/4;
+ WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
+ (void)WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
+ return Success;
+}
+
+void
+NoteLedState(DeviceIntPtr keybd, int led, Bool on)
+{
+ KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
+ if (on)
+ ctrl->leds |= ((Leds)1 << (led - 1));
+ else
+ ctrl->leds &= ~((Leds)1 << (led - 1));
+}
+
+_X_EXPORT int
+Ones(unsigned long mask) /* HACKMEM 169 */
+{
+ register unsigned long y;
+
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return (((y + (y >> 3)) & 030707070707) % 077);
+}
+
+int
+ProcChangeKeyboardControl (ClientPtr client)
+{
+#define DO_ALL (-1)
+ KeybdCtrl ctrl;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ XID *vlist;
+ int t;
+ int led = DO_ALL;
+ int key = DO_ALL;
+ BITS32 vmask, index2;
+ int mask, i;
+ REQUEST(xChangeKeyboardControlReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
+ vmask = stuff->mask;
+ if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
+ return BadLength;
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, keybd, TRUE))
+ return BadAccess;
+#endif
+ vlist = (XID *)&stuff[1]; /* first word of values */
+ ctrl = keybd->kbdfeed->ctrl;
+ while (vmask)
+ {
+ index2 = (BITS32) lowbit (vmask);
+ vmask &= ~index2;
+ switch (index2)
+ {
+ case KBKeyClickPercent:
+ t = (INT8)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.click;
+ else if (t < 0 || t > 100)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.click = t;
+ break;
+ case KBBellPercent:
+ t = (INT8)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.bell;
+ else if (t < 0 || t > 100)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell = t;
+ break;
+ case KBBellPitch:
+ t = (INT16)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_pitch;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell_pitch = t;
+ break;
+ case KBBellDuration:
+ t = (INT16)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_duration;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell_duration = t;
+ break;
+ case KBLed:
+ led = (CARD8)*vlist;
+ vlist++;
+ if (led < 1 || led > 32)
+ {
+ client->errorValue = led;
+ return BadValue;
+ }
+ if (!(stuff->mask & KBLedMode))
+ return BadMatch;
+ break;
+ case KBLedMode:
+ t = (CARD8)*vlist;
+ vlist++;
+ if (t == LedModeOff)
+ {
+ if (led == DO_ALL)
+ ctrl.leds = 0x0;
+ else
+ ctrl.leds &= ~(((Leds)(1)) << (led - 1));
+ }
+ else if (t == LedModeOn)
+ {
+ if (led == DO_ALL)
+ ctrl.leds = ~0L;
+ else
+ ctrl.leds |= (((Leds)(1)) << (led - 1));
+ }
+ else
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+#ifdef XKB
+ if (!noXkbExtension) {
+ XkbEventCauseRec cause;
+ XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
+ XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
+ ctrl.leds, &cause);
+ ctrl.leds = keybd->kbdfeed->ctrl.leds;
+ }
+#endif
+ break;
+ case KBKey:
+ key = (KeyCode)*vlist;
+ vlist++;
+ if ((KeyCode)key < inputInfo.keyboard->key->curKeySyms.minKeyCode ||
+ (KeyCode)key > inputInfo.keyboard->key->curKeySyms.maxKeyCode)
+ {
+ client->errorValue = key;
+ return BadValue;
+ }
+ if (!(stuff->mask & KBAutoRepeatMode))
+ return BadMatch;
+ break;
+ case KBAutoRepeatMode:
+ i = (key >> 3);
+ mask = (1 << (key & 7));
+ t = (CARD8)*vlist;
+ vlist++;
+#ifdef XKB
+ if (!noXkbExtension && key != DO_ALL)
+ XkbDisableComputedAutoRepeats(keybd,key);
+#endif
+ if (t == AutoRepeatModeOff)
+ {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = FALSE;
+ else
+ ctrl.autoRepeats[i] &= ~mask;
+ }
+ else if (t == AutoRepeatModeOn)
+ {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = TRUE;
+ else
+ ctrl.autoRepeats[i] |= mask;
+ }
+ else if (t == AutoRepeatModeDefault)
+ {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
+ else
+ ctrl.autoRepeats[i] =
+ (ctrl.autoRepeats[i] & ~mask) |
+ (defaultKeyboardControl.autoRepeats[i] & mask);
+ }
+ else
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ break;
+ default:
+ client->errorValue = stuff->mask;
+ return BadValue;
+ }
+ }
+ keybd->kbdfeed->ctrl = ctrl;
+#ifdef XKB
+ /* The XKB RepeatKeys control and core protocol global autorepeat */
+ /* value are linked */
+ if (!noXkbExtension) {
+ XkbSetRepeatKeys(keybd,key,keybd->kbdfeed->ctrl.autoRepeat);
+ }
+ else
+#endif
+ (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl);
+ return Success;
+#undef DO_ALL
+}
+
+int
+ProcGetKeyboardControl (ClientPtr client)
+{
+ int i;
+ register KeybdCtrl *ctrl = &inputInfo.keyboard->kbdfeed->ctrl;
+ xGetKeyboardControlReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 5;
+ rep.sequenceNumber = client->sequence;
+ rep.globalAutoRepeat = ctrl->autoRepeat;
+ rep.keyClickPercent = ctrl->click;
+ rep.bellPercent = ctrl->bell;
+ rep.bellPitch = ctrl->bell_pitch;
+ rep.bellDuration = ctrl->bell_duration;
+ rep.ledMask = ctrl->leds;
+ for (i = 0; i < 32; i++)
+ rep.map[i] = ctrl->autoRepeats[i];
+ WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
+ return Success;
+}
+
+int
+ProcBell(ClientPtr client)
+{
+ register DeviceIntPtr keybd = inputInfo.keyboard;
+ int base = keybd->kbdfeed->ctrl.bell;
+ int newpercent;
+ REQUEST(xBellReq);
+ REQUEST_SIZE_MATCH(xBellReq);
+ if (stuff->percent < -100 || stuff->percent > 100)
+ {
+ client->errorValue = stuff->percent;
+ return BadValue;
+ }
+ newpercent = (base * stuff->percent) / 100;
+ if (stuff->percent < 0)
+ newpercent = base + newpercent;
+ else
+ newpercent = base - newpercent + stuff->percent;
+#ifdef XKB
+ if (!noXkbExtension)
+ XkbHandleBell(FALSE,FALSE, keybd, newpercent, &keybd->kbdfeed->ctrl, 0,
+ None, NULL, client);
+ else
+#endif
+ (*keybd->kbdfeed->BellProc)(newpercent, keybd,
+ (pointer) &keybd->kbdfeed->ctrl, 0);
+ return Success;
+}
+
+int
+ProcChangePointerControl(ClientPtr client)
+{
+ DeviceIntPtr mouse = inputInfo.pointer;
+ PtrCtrl ctrl; /* might get BadValue part way through */
+ REQUEST(xChangePointerControlReq);
+
+ REQUEST_SIZE_MATCH(xChangePointerControlReq);
+ ctrl = mouse->ptrfeed->ctrl;
+ if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse))
+ {
+ client->errorValue = stuff->doAccel;
+ return(BadValue);
+ }
+ if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse))
+ {
+ client->errorValue = stuff->doThresh;
+ return(BadValue);
+ }
+ if (stuff->doAccel)
+ {
+ if (stuff->accelNum == -1)
+ ctrl.num = defaultPointerControl.num;
+ else if (stuff->accelNum < 0)
+ {
+ client->errorValue = stuff->accelNum;
+ return BadValue;
+ }
+ else ctrl.num = stuff->accelNum;
+ if (stuff->accelDenum == -1)
+ ctrl.den = defaultPointerControl.den;
+ else if (stuff->accelDenum <= 0)
+ {
+ client->errorValue = stuff->accelDenum;
+ return BadValue;
+ }
+ else ctrl.den = stuff->accelDenum;
+ }
+ if (stuff->doThresh)
+ {
+ if (stuff->threshold == -1)
+ ctrl.threshold = defaultPointerControl.threshold;
+ else if (stuff->threshold < 0)
+ {
+ client->errorValue = stuff->threshold;
+ return BadValue;
+ }
+ else ctrl.threshold = stuff->threshold;
+ }
+ mouse->ptrfeed->ctrl = ctrl;
+ (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl);
+ return Success;
+}
+
+int
+ProcGetPointerControl(ClientPtr client)
+{
+ register PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl;
+ xGetPointerControlReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.threshold = ctrl->threshold;
+ rep.accelNumerator = ctrl->num;
+ rep.accelDenominator = ctrl->den;
+ WriteReplyToClient(client, sizeof(xGenericReply), &rep);
+ return Success;
+}
+
+void
+MaybeStopHint(register DeviceIntPtr dev, ClientPtr client)
+{
+ GrabPtr grab = dev->grab;
+
+ if ((grab && SameClient(grab, client) &&
+ ((grab->eventMask & PointerMotionHintMask) ||
+ (grab->ownerEvents &&
+ (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+ PointerMotionHintMask)))) ||
+ (!grab &&
+ (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+ PointerMotionHintMask)))
+ dev->valuator->motionHintWindow = NullWindow;
+}
+
+int
+ProcGetMotionEvents(ClientPtr client)
+{
+ WindowPtr pWin;
+ xTimecoord * coords = (xTimecoord *) NULL;
+ xGetMotionEventsReply rep;
+ int i, count, xmin, xmax, ymin, ymax;
+ unsigned long nEvents;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ TimeStamp start, stop;
+ REQUEST(xGetMotionEventsReq);
+
+ REQUEST_SIZE_MATCH(xGetMotionEventsReq);
+ pWin = SecurityLookupWindow(stuff->window, client, TRUE);
+ if (!pWin)
+ return BadWindow;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ nEvents = 0;
+ start = ClientTimeToServerTime(stuff->start);
+ stop = ClientTimeToServerTime(stuff->stop);
+ if ((CompareTimeStamps(start, stop) != LATER) &&
+ (CompareTimeStamps(start, currentTime) != LATER) &&
+ mouse->valuator->numMotionEvents)
+ {
+ if (CompareTimeStamps(stop, currentTime) == LATER)
+ stop = currentTime;
+ coords = (xTimecoord *)ALLOCATE_LOCAL(mouse->valuator->numMotionEvents
+ * sizeof(xTimecoord));
+ if (!coords)
+ return BadAlloc;
+ count = (*mouse->valuator->GetMotionProc) (mouse, coords,
+ start.milliseconds,
+ stop.milliseconds,
+ pWin->drawable.pScreen);
+ xmin = pWin->drawable.x - wBorderWidth (pWin);
+ xmax = pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth (pWin);
+ ymin = pWin->drawable.y - wBorderWidth (pWin);
+ ymax = pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin);
+ for (i = 0; i < count; i++)
+ if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
+ (ymin <= coords[i].y) && (coords[i].y < ymax))
+ {
+ coords[nEvents].time = coords[i].time;
+ coords[nEvents].x = coords[i].x - pWin->drawable.x;
+ coords[nEvents].y = coords[i].y - pWin->drawable.y;
+ nEvents++;
+ }
+ }
+ rep.length = nEvents * (sizeof(xTimecoord) >> 2);
+ rep.nEvents = nEvents;
+ WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
+ if (nEvents)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
+ WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
+ (char *)coords);
+ }
+ if (coords)
+ DEALLOCATE_LOCAL(coords);
+ return Success;
+}
+
+int
+ProcQueryKeymap(ClientPtr client)
+{
+ xQueryKeymapReply rep;
+ int i;
+ CARD8 *down = inputInfo.keyboard->key->down;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 2;
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
+ {
+ bzero((char *)&rep.map[0], 32);
+ }
+ else
+#endif
+ for (i = 0; i<32; i++)
+ rep.map[i] = down[i];
+ WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
+ return Success;
+}
diff --git a/xserver/dix/dispatch.c b/xserver/dix/dispatch.c
new file mode 100644
index 000000000..05795407f
--- /dev/null
+++ b/xserver/dix/dispatch.c
@@ -0,0 +1,3992 @@
+/************************************************************
+
+Copyright 1987, 1989, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+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.
+
+The above copyright notice and this permission notice 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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XACE
+#include "xace.h"
+#endif
+#ifdef XAPPGROUP
+#include "appgroup.h"
+#endif
+#ifdef XKB
+#ifndef XKB_IN_SERVER
+#define XKB_IN_SERVER
+#endif
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+_X_EXPORT Selection *CurrentSelections;
+_X_EXPORT int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+_X_EXPORT CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int nClients; /* number of authorized clients */
+
+_X_EXPORT CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+_X_EXPORT volatile char dispatchException = 0;
+_X_EXPORT volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue; /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+ (a.pScreen == b.pScreen))
+
+_X_EXPORT void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+ checkForInput[0] = c0;
+ checkForInput[1] = c1;
+}
+
+_X_EXPORT void
+UpdateCurrentTime()
+{
+ TimeStamp systime;
+
+ /* To avoid time running backwards, we must call GetTimeInMillis before
+ * calling ProcessInputEvents.
+ */
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] != *checkForInput[1])
+ ProcessInputEvents();
+ if (CompareTimeStamps(systime, currentTime) == LATER)
+ currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+_X_EXPORT void
+UpdateCurrentTimeIf()
+{
+ TimeStamp systime;
+
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] == *checkForInput[1])
+ currentTime = systime;
+}
+
+void
+InitSelections()
+{
+ if (CurrentSelections)
+ xfree(CurrentSelections);
+ CurrentSelections = (Selection *)NULL;
+ NumCurrentSelections = 0;
+}
+
+void
+FlushClientCaches(XID id)
+{
+ int i;
+ register ClientPtr client;
+
+ client = clients[CLIENT_ID(id)];
+ if (client == NullClient)
+ return ;
+ for (i=0; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client != NullClient)
+ {
+ if (client->lastDrawableID == id)
+ {
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ }
+ else if (client->lastGCID == id)
+ {
+ client->lastGCID = INVALID;
+ client->lastGC = (GCPtr)NULL;
+ }
+ }
+ }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
+#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
+
+Bool SmartScheduleDisable = FALSE;
+long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long SmartScheduleTime;
+ClientPtr SmartLastClient;
+int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long SmartLastPrint;
+#endif
+
+void Dispatch(void);
+void InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+ ClientPtr pClient;
+ int i;
+ int client;
+ int bestPrio, best = 0;
+ int bestRobin, robin;
+ long now = SmartScheduleTime;
+ long idle;
+
+ bestPrio = -0x7fffffff;
+ bestRobin = 0;
+ idle = 2 * SmartScheduleSlice;
+ for (i = 0; i < nready; i++)
+ {
+ client = clientReady[i];
+ pClient = clients[client];
+ /* Praise clients which are idle */
+ if ((now - pClient->smart_check_tick) >= idle)
+ {
+ if (pClient->smart_priority < 0)
+ pClient->smart_priority++;
+ }
+ pClient->smart_check_tick = now;
+
+ /* check priority to select best client */
+ robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+ if (pClient->smart_priority > bestPrio ||
+ (pClient->smart_priority == bestPrio && robin > bestRobin))
+ {
+ bestPrio = pClient->smart_priority;
+ bestRobin = robin;
+ best = client;
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ {
+ fprintf (stderr, " use %2d\n", best);
+ SmartLastPrint = now;
+ }
+#endif
+ pClient = clients[best];
+ SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+ /*
+ * Set current client pointer
+ */
+ if (SmartLastClient != pClient)
+ {
+ pClient->smart_start_tick = now;
+ SmartLastClient = pClient;
+ }
+ /*
+ * Adjust slice
+ */
+ if (nready == 1)
+ {
+ /*
+ * If it's been a long time since another client
+ * has run, bump the slice up to get maximal
+ * performance from a single client
+ */
+ if ((now - pClient->smart_start_tick) > 1000 &&
+ SmartScheduleSlice < SmartScheduleMaxSlice)
+ {
+ SmartScheduleSlice += SmartScheduleInterval;
+ }
+ }
+ else
+ {
+ SmartScheduleSlice = SmartScheduleInterval;
+ }
+ return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+ register int *clientReady; /* array of request ready clients */
+ register int result;
+ register ClientPtr client;
+ register int nready;
+ register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+ long start_tick;
+#endif
+
+ nextFreeClientID = 1;
+ InitSelections();
+ nClients = 0;
+
+ clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ while (!dispatchException)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+
+ nready = WaitForSomething(clientReady);
+
+#ifdef SMART_SCHEDULE
+ if (nready && !SmartScheduleDisable)
+ {
+ clientReady[0] = SmartScheduleClient (clientReady, nready);
+ nready = 1;
+ }
+#endif
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
+
+ while (!dispatchException && (--nready >= 0))
+ {
+ client = clients[clientReady[nready]];
+ if (! client)
+ {
+ /* KillClient can cause this to happen */
+ continue;
+ }
+ /* GrabServer activation can cause this to be true */
+ if (grabState == GrabKickout)
+ {
+ grabState = GrabActive;
+ break;
+ }
+ isItTimeToYield = FALSE;
+
+ requestingClient = client;
+#ifdef SMART_SCHEDULE
+ start_tick = SmartScheduleTime;
+#endif
+ while (!isItTimeToYield)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+#ifdef SMART_SCHEDULE
+ if (!SmartScheduleDisable &&
+ (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+ {
+ /* Penalize clients which consume ticks */
+ if (client->smart_priority > SMART_MIN_PRIORITY)
+ client->smart_priority--;
+ break;
+ }
+#endif
+ /* now, finally, deal with client requests */
+
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+
+ client->sequence++;
+#ifdef DEBUG
+ if (client->requestLogIndex == MAX_REQUEST_LOG)
+ client->requestLogIndex = 0;
+ client->requestLog[client->requestLogIndex] = MAJOROP;
+ client->requestLogIndex++;
+#endif
+ if (result > (maxBigRequestSize << 2))
+ result = BadLength;
+ else
+#ifdef XACE
+ {
+ XaceHook(XACE_AUDIT_BEGIN, client);
+ result = (* client->requestVector[MAJOROP])(client);
+ XaceHook(XACE_AUDIT_END, client, result);
+ }
+#else
+ result = (* client->requestVector[MAJOROP])(client);
+#endif /* XACE */
+
+ if (result != Success)
+ {
+ if (client->noClientException != Success)
+ CloseDownClient(client);
+ else
+ SendErrorToClient(client, MAJOROP,
+ MinorOpcodeOfRequest(client),
+ client->errorValue, result);
+ break;
+ }
+#ifdef DAMAGEEXT
+ FlushIfCriticalOutputPending ();
+#endif
+ }
+ FlushAllOutput();
+#ifdef SMART_SCHEDULE
+ client = clients[clientReady[nready]];
+ if (client)
+ client->smart_stop_tick = SmartScheduleTime;
+#endif
+ requestingClient = NULL;
+ }
+ dispatchException &= ~DE_PRIORITYCHANGE;
+ }
+#if defined(DDXBEFORERESET)
+ ddxBeforeReset ();
+#endif
+ KillAllClients();
+ DEALLOCATE_LOCAL(clientReady);
+ dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+_X_EXPORT int
+ProcBadRequest(ClientPtr client)
+{
+ return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ REQUEST(xCreateWindowReq);
+ int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ LEGAL_NEW_RESOURCE(stuff->wid, client);
+ if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess)))
+ return BadWindow;
+ len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+ stuff->y, stuff->width, stuff->height,
+ stuff->borderWidth, stuff->class,
+ stuff->mask, (XID *) &stuff[1],
+ (int)stuff->depth,
+ client, stuff->visual, &result);
+ if (pWin)
+ {
+ Mask mask = pWin->eventMask;
+
+ pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+ if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+ return BadAlloc;
+ pWin->eventMask = mask;
+ }
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeWindowAttributesReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ if (len != Ones(stuff->valueMask))
+ return BadLength;
+ result = ChangeWindowAttributes(pWin,
+ stuff->valueMask,
+ (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+ xGetWindowAttributesReply wa;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ GetWindowAttributes(pWin, client, &wa);
+ WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+ return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->parent)
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ DestroySubwindows(pWin, client);
+ return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeSaveSetReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+ {
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+}
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+ register WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess);
+ if (!pParent)
+ return(BadWindow);
+ if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+ {
+ if ((pWin->backgroundState == ParentRelative) &&
+ (pParent->drawable.depth != pWin->drawable.depth))
+ return BadMatch;
+ if ((pWin->drawable.class != InputOnly) &&
+ (pParent->drawable.class == InputOnly))
+ return BadMatch;
+ result = ReparentWindow(pWin, pParent,
+ (short)stuff->x, (short)stuff->y, client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ return (BadMatch);
+}
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapWindow(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapSubwindows(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapWindow(pWin, FALSE);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapSubwindows(pWin);
+ return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xConfigureWindowReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ if (Ones((Mask)stuff->mask) != len)
+ return BadLength;
+ result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xCirculateWindowReq);
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+ if ((stuff->direction != RaiseLowest) &&
+ (stuff->direction != LowerHighest))
+ {
+ client->errorValue = stuff->direction;
+ return BadValue;
+ }
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ CirculateWindow(pWin, (int)stuff->direction, client);
+ return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+ rep->depth = pDraw->depth;
+ rep->width = pDraw->width;
+ rep->height = pDraw->height;
+
+ /* XXX - Because the pixmap-implementation of the multibuffer extension
+ * may have the buffer-id's drawable resource value be a pointer
+ * to the buffer's window instead of the buffer itself
+ * (this happens if the buffer is the displayed buffer),
+ * we also have to check that the id matches before we can
+ * truly say that it is a DRAWABLE_WINDOW.
+ */
+
+ if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+ ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+ {
+ register WindowPtr pWin = (WindowPtr)pDraw;
+ rep->x = pWin->origin.x - wBorderWidth (pWin);
+ rep->y = pWin->origin.y - wBorderWidth (pWin);
+ rep->borderWidth = pWin->borderWidth;
+ }
+ else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+ {
+ rep->x = rep->y = rep->borderWidth = 0;
+ }
+
+ return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+ xGetGeometryReply rep;
+ int status;
+
+ if ((status = GetGeometry(client, &rep)) != Success)
+ return status;
+
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+ xQueryTreeReply reply;
+ int numChildren = 0;
+ register WindowPtr pChild, pWin, pHead;
+ Window *childIDs = (Window *)NULL;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ reply.type = X_Reply;
+ reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ reply.sequenceNumber = client->sequence;
+ if (pWin->parent)
+ reply.parent = pWin->parent->drawable.id;
+ else
+ reply.parent = (Window)None;
+ pHead = RealChildHead(pWin);
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ numChildren++;
+ if (numChildren)
+ {
+ int curChild = 0;
+
+ childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+ if (!childIDs)
+ return BadAlloc;
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ childIDs[curChild++] = pChild->drawable.id;
+ }
+
+ reply.nChildren = numChildren;
+ reply.length = (numChildren * sizeof(Window)) >> 2;
+
+ WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+ if (numChildren)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+ DEALLOCATE_LOCAL(childIDs);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+ Atom atom;
+ char *tchar;
+ REQUEST(xInternAtomReq);
+
+ REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+ if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+ {
+ client->errorValue = stuff->onlyIfExists;
+ return(BadValue);
+ }
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+ if (atom != BAD_RESOURCE)
+ {
+ xInternAtomReply reply;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = atom;
+ WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+ char *str;
+ xGetAtomNameReply reply;
+ int len;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if ( (str = NameForAtom(stuff->id)) )
+ {
+ len = strlen(str);
+ reply.type = X_Reply;
+ reply.length = (len + 3) >> 2;
+ reply.sequenceNumber = client->sequence;
+ reply.nameLength = len;
+ WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+ (void)WriteToClient(client, len, str);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+ WindowPtr pWin;
+ TimeStamp time;
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(stuff->time);
+
+ /* If the client's time stamp is in the future relative to the server's
+ time stamp, do not set the selection, just return success. */
+ if (CompareTimeStamps(time, currentTime) == LATER)
+ return Success;
+ if (stuff->window != None)
+ {
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ }
+ else
+ pWin = (WindowPtr)None;
+ if (ValidAtom(stuff->selection))
+ {
+ int i = 0;
+
+ /*
+ * First, see if the selection is already set...
+ */
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection)
+ i++;
+ if (i < NumCurrentSelections)
+ {
+ xEvent event;
+
+ /* If the timestamp in client's request is in the past relative
+ to the time stamp indicating the last time the owner of the
+ selection was set, do not set the selection, just return
+ success. */
+ if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+ == EARLIER)
+ return Success;
+ if (CurrentSelections[i].client &&
+ (!pWin || (CurrentSelections[i].client != client)))
+ {
+ event.u.u.type = SelectionClear;
+ event.u.selectionClear.time = time.milliseconds;
+ event.u.selectionClear.window = CurrentSelections[i].window;
+ event.u.selectionClear.atom = CurrentSelections[i].selection;
+ (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+ NoEventMask, NoEventMask /* CantBeFiltered */,
+ NullGrab);
+ }
+ }
+ else
+ {
+ /*
+ * It doesn't exist, so add it...
+ */
+ Selection *newsels;
+
+ if (i == 0)
+ newsels = (Selection *)xalloc(sizeof(Selection));
+ else
+ newsels = (Selection *)xrealloc(CurrentSelections,
+ (NumCurrentSelections + 1) * sizeof(Selection));
+ if (!newsels)
+ return BadAlloc;
+ NumCurrentSelections++;
+ CurrentSelections = newsels;
+ CurrentSelections[i].selection = stuff->selection;
+ }
+ CurrentSelections[i].lastTimeChanged = time;
+ CurrentSelections[i].window = stuff->window;
+ CurrentSelections[i].pWin = pWin;
+ CurrentSelections[i].client = (pWin ? client : NullClient);
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind= SelectionSetOwner;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->selection;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (ValidAtom(stuff->id))
+ {
+ int i;
+ xGetSelectionOwnerReply reply;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->id) i++;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ if (i < NumCurrentSelections)
+ reply.owner = CurrentSelections[i].window;
+ else
+ reply.owner = None;
+ WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+ Bool paramsOkay;
+ xEvent event;
+ WindowPtr pWin;
+ REQUEST(xConvertSelectionReq);
+
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+ if (stuff->property != None)
+ paramsOkay &= ValidAtom(stuff->property);
+ if (paramsOkay)
+ {
+ int i;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+ if ((i < NumCurrentSelections) &&
+ (CurrentSelections[i].window != None)
+#ifdef XACE
+ && XaceHook(XACE_RESOURCE_ACCESS, client,
+ CurrentSelections[i].window, RT_WINDOW,
+ SecurityReadAccess, CurrentSelections[i].pWin)
+#endif
+ )
+ {
+ event.u.u.type = SelectionRequest;
+ event.u.selectionRequest.time = stuff->time;
+ event.u.selectionRequest.owner =
+ CurrentSelections[i].window;
+ event.u.selectionRequest.requestor = stuff->requestor;
+ event.u.selectionRequest.selection = stuff->selection;
+ event.u.selectionRequest.target = stuff->target;
+ event.u.selectionRequest.property = stuff->property;
+ if (TryClientEvents(
+ CurrentSelections[i].client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab))
+ return (client->noClientException);
+ }
+ event.u.u.type = SelectionNotify;
+ event.u.selectionNotify.time = stuff->time;
+ event.u.selectionNotify.requestor = stuff->requestor;
+ event.u.selectionNotify.selection = stuff->selection;
+ event.u.selectionNotify.target = stuff->target;
+ event.u.selectionNotify.property = None;
+ (void) TryClientEvents(client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ if (grabState != GrabNone && client != grabClient)
+ {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ BITSET(grabWaiters, client->index);
+ IgnoreClient(client);
+ return(client->noClientException);
+ }
+ OnlyListenToOneClient(client);
+ grabState = GrabKickout;
+ grabClient = client;
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_GRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+
+ return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+ int i;
+
+ grabState = GrabNone;
+ ListenToAllClients();
+ for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+ ;
+ if (i >= 0)
+ {
+ i <<= 5;
+ while (!GETBIT(grabWaiters, i))
+ i++;
+ BITCLEAR(grabWaiters, i);
+ AttendClient(clients[i]);
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_UNGRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ UngrabServer(client);
+ return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+ REQUEST(xTranslateCoordsReq);
+
+ register WindowPtr pWin, pDst;
+ xTranslateCoordsReply rep;
+
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+ SecurityReadAccess);
+ if (!pDst)
+ return(BadWindow);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+ {
+ rep.sameScreen = xFalse;
+ rep.child = None;
+ rep.dstX = rep.dstY = 0;
+ }
+ else
+ {
+ INT16 x, y;
+ rep.sameScreen = xTrue;
+ rep.child = None;
+ /* computing absolute coordinates -- adjust to destination later */
+ x = pWin->drawable.x + stuff->srcX;
+ y = pWin->drawable.y + stuff->srcY;
+ pWin = pDst->firstChild;
+ while (pWin)
+ {
+#ifdef SHAPE
+ BoxRec box;
+#endif
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth (pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ &pWin->borderSize, x, y, &box))
+
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ rep.child = pWin->drawable.id;
+ pWin = (WindowPtr) NULL;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ /* adjust to destination coordinates */
+ rep.dstX = x - pDst->drawable.x;
+ rep.dstY = y - pDst->drawable.y;
+ }
+ WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+ return(client->noClientException);
+}
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+ int err;
+ REQUEST(xOpenFontReq);
+
+ REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+ client->errorValue = stuff->fid;
+ LEGAL_NEW_RESOURCE(stuff->fid, client);
+ err = OpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+ FontPtr pFont;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityDestroyAccess);
+ if ( pFont != (FontPtr)NULL) /* id was valid */
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadFont);
+ }
+}
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+ xQueryFontReply *reply;
+ FontPtr pFont;
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ client->errorValue = stuff->id; /* EITHER font or gc */
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ /* can't use VERIFY_GC because it might return BadGC */
+ pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->id;
+ return(BadFont); /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+ {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+ int rlength;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+ reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+ if(!reply)
+ {
+ return(BadAlloc);
+ }
+
+ reply->type = X_Reply;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->sequenceNumber = client->sequence;
+ QueryFont( pFont, reply, nprotoxcistructs);
+
+ WriteReplyToClient(client, rlength, reply);
+ DEALLOCATE_LOCAL(reply);
+ return(client->noClientException);
+ }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+ REQUEST(xQueryTextExtentsReq);
+ xQueryTextExtentsReply reply;
+ FontPtr pFont;
+ GC *pGC;
+ ExtentInfoRec info;
+ unsigned long length;
+
+ REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->fid;
+ return(BadFont);
+ }
+ pFont = pGC->font;
+ }
+ length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+ length = length << 1;
+ if (stuff->oddLength)
+ {
+ if (length == 0)
+ return(BadLength);
+ length--;
+ }
+ if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+ return(BadAlloc);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.drawDirection = info.drawDirection;
+ reply.fontAscent = info.fontAscent;
+ reply.fontDescent = info.fontDescent;
+ reply.overallAscent = info.overallAscent;
+ reply.overallDescent = info.overallDescent;
+ reply.overallWidth = info.overallWidth;
+ reply.overallLeft = info.overallLeft;
+ reply.overallRight = info.overallRight;
+ WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListFonts(register ClientPtr client)
+{
+ REQUEST(xListFontsReq);
+
+ REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+
+ return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+ REQUEST(xListFontsWithInfoReq);
+
+ REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+ PixmapPtr pPixmap = (PixmapPtr)value;
+ return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ REQUEST(xCreatePixmapReq);
+ DepthPtr pDepth;
+ register int i;
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (stuff->width > 32767 || stuff->height > 32767)
+ {
+ /* It is allowed to try and allocate a pixmap which is larger than
+ * 32767 in either dimension. However, all of the framebuffer code
+ * is buggy and does not reliably draw to such big pixmaps, basically
+ * because the Region data structure operates with signed shorts
+ * for the rectangles in it.
+ *
+ * Furthermore, several places in the X server computes the
+ * size in bytes of the pixmap and tries to store it in an
+ * integer. This integer can overflow and cause the allocated size
+ * to be much smaller.
+ *
+ * So, such big pixmaps are rejected here with a BadAlloc
+ */
+ return BadAlloc;
+ }
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+CreatePmap:
+ pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth);
+ if (pMap)
+ {
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ return(client->noClientException);
+ }
+ return (BadAlloc);
+}
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+ SecurityDestroyAccess);
+ if (pMap)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadPixmap);
+ }
+}
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+ int error;
+ GC *pGC;
+ register DrawablePtr pDraw;
+ unsigned len;
+ REQUEST(xCreateGCReq);
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ client->errorValue = stuff->gc;
+ LEGAL_NEW_RESOURCE(stuff->gc, client);
+ SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+ pGC = (GC *)CreateGC(pDraw, stuff->mask,
+ (XID *) &stuff[1], &error);
+ if (error != Success)
+ return error;
+ if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+ return (BadAlloc);
+ return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+ GC *pGC;
+ REQUEST(xChangeGCReq);
+ int result;
+ unsigned len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+ len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+
+ result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+ register GC *dstGC;
+ register GC *pGC;
+ int result;
+ REQUEST(xCopyGCReq);
+
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+ SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+ if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+ return (BadMatch);
+ result = CopyGC(pGC, dstGC, stuff->mask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+ register GC *pGC;
+ int result;
+ REQUEST(xSetDashesReq);
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+ if (stuff->nDashes == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+ (unsigned char *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+ int nr;
+ int result;
+ register GC *pGC;
+ REQUEST(xSetClipRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+ if (nr & 4)
+ return(BadLength);
+ nr >>= 3;
+ result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ register WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->drawable.class == InputOnly)
+ {
+ client->errorValue = stuff->window;
+ return (BadMatch);
+ }
+ if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+ {
+ client->errorValue = stuff->exposures;
+ return(BadValue);
+ }
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ (Bool)stuff->exposures);
+ return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+ register DrawablePtr pDst;
+ register DrawablePtr pSrc;
+ register GC *pGC;
+ REQUEST(xCopyAreaReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ pSrc = pDst;
+
+ SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+ pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY);
+ if (pGC->graphicsExposures)
+ {
+ (*pDst->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+ if (pRgn)
+ REGION_DESTROY(pDst->pScreen, pRgn);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+ register DrawablePtr psrcDraw, pdstDraw;
+ register GC *pGC;
+ REQUEST(xCopyPlaneReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if (pdstDraw->pScreen != psrcDraw->pScreen)
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ psrcDraw = pdstDraw;
+
+ SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+ /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+ if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+ (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+ {
+ client->errorValue = stuff->bitPlane;
+ return(BadValue);
+ }
+
+ pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY, stuff->bitPlane);
+ if (pGC->graphicsExposures)
+ {
+ (*pdstDraw->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+ if (pRgn)
+ REGION_DESTROY(pdstDraw->pScreen, pRgn);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ if (npoint)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+ (xPoint *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ if (npoint > 1)
+ (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+ int nsegs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ if (nsegs & 4)
+ return(BadLength);
+ nsegs >>= 3;
+ if (nsegs)
+ (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+ int nrects;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ if (nrects & 4)
+ return(BadLength);
+ nrects >>= 3;
+ if (nrects)
+ (*pGC->ops->PolyRectangle)(pDraw, pGC,
+ nrects, (xRectangle *) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
+ (stuff->shape != Convex))
+ {
+ client->errorValue = stuff->shape;
+ return BadValue;
+ }
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ if (things)
+ (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+ stuff->coordMode, things,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ if (things)
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+ (xRectangle *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+ int whichbyte = 1;
+
+ if (*((char *) &whichbyte))
+ return LSBFirst;
+ return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+ switch (bpp) {
+ case 1: /* yuck */
+ if (BITMAP_BIT_ORDER != order)
+ BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+ ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+ break;
+ case 4:
+ break; /* yuck */
+ case 8:
+ break;
+ case 16:
+ if (IMAGE_BYTE_ORDER != order)
+ TwoByteSwap ((unsigned char *) base, nbytes);
+ break;
+ case 32:
+ if (IMAGE_BYTE_ORDER != order)
+ FourByteSwap ((unsigned char *) base, nbytes);
+ break;
+ }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ long length; /* length of scanline server padded */
+ long lengthProto; /* length of scanline protocol padded */
+ char *tmpImage;
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ if (stuff->format == XYBitmap)
+ {
+ if ((stuff->depth != 1) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+ return BadMatch;
+ length = PixmapBytePad(stuff->width, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ tmpImage = (char *)&stuff[1];
+ lengthProto = length;
+
+ if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
+ (sizeof(xPutImageReq) >> 2)) != client->req_len)
+ return BadLength;
+
+ ReformatImage (tmpImage, lengthProto * stuff->height,
+ stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+ ClientOrder(client));
+
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+ stuff->width, stuff->height,
+ stuff->leftPad, stuff->format, tmpImage);
+
+ return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable,
+ int x, int y, int width, int height,
+ Mask planemask, xGetImageReply **im_return)
+{
+ register DrawablePtr pDraw;
+ int nlines, linesPerBuf;
+ register int linesDone;
+ long widthBytesLine, length;
+ Mask plane = 0;
+ char *pBuf;
+ xGetImageReply xgi;
+#ifdef XACE
+ RegionPtr pVisibleRegion = NULL;
+#endif
+
+ if ((format != XYPixmap) && (format != ZPixmap))
+ {
+ client->errorValue = format;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+ if(pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + x < 0 ||
+ pDraw->x + x + width > pDraw->pScreen->width ||
+ pDraw->y + y < 0 ||
+ pDraw->y + y + height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual (((WindowPtr) pDraw));
+ }
+ else
+ {
+ if(x < 0 ||
+ x+width > (int)pDraw->width ||
+ y < 0 ||
+ y+height > (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+
+ SET_DBE_SRCBUF(pDraw, drawable);
+
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ widthBytesLine = PixmapBytePad(width, pDraw->depth);
+ length = widthBytesLine * height;
+
+ }
+ else
+ {
+ widthBytesLine = BitmapBytePad(width);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * height *
+ Ones(planemask & (plane | (plane - 1)));
+
+ }
+
+ xgi.length = length;
+
+ if (im_return) {
+ pBuf = (char *)xalloc(sz_xGetImageReply + length);
+ if (!pBuf)
+ return (BadAlloc);
+ if (widthBytesLine == 0)
+ linesPerBuf = 0;
+ else
+ linesPerBuf = height;
+ *im_return = (xGetImageReply *)pBuf;
+ *(xGetImageReply *)pBuf = xgi;
+ pBuf += sz_xGetImageReply;
+ } else {
+ xgi.length = (xgi.length + 3) >> 2;
+ if (widthBytesLine == 0 || height == 0)
+ linesPerBuf = 0;
+ else if (widthBytesLine >= IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else
+ {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height)
+ {
+ /* we have to make sure intermediate buffers don't need padding */
+ while ((linesPerBuf > 1) &&
+ (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+ {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+ {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+ return (BadAlloc);
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+ }
+
+#ifdef XACE
+ if (pDraw->type == DRAWABLE_WINDOW &&
+ !XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw))
+ {
+ pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+ if (pVisibleRegion)
+ {
+ REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+ }
+ }
+#endif
+
+ if (linesPerBuf == 0)
+ {
+ /* nothing to do */
+ }
+ else if (format == ZPixmap)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ planemask,
+ (pointer) pBuf);
+#ifdef XACE
+ if (pVisibleRegion)
+ XaceCensorImage(client, pVisibleRegion, widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note that this is NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (!im_return)
+ {
+ ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+ BitsPerPixel (pDraw->depth),
+ ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ else /* XYPixmap */
+ {
+ for (; plane; plane >>= 1)
+ {
+ if (planemask & plane)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ plane,
+ (pointer)pBuf);
+#ifdef XACE
+ if (pVisibleRegion)
+ XaceCensorImage(client, pVisibleRegion,
+ widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note: NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (im_return) {
+ pBuf += nlines * widthBytesLine;
+ } else {
+ ReformatImage (pBuf,
+ (int)(nlines * widthBytesLine),
+ 1,
+ ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+#ifdef XACE
+ if (pVisibleRegion)
+ REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+#endif
+ if (!im_return)
+ DEALLOCATE_LOCAL(pBuf);
+ return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+ REQUEST(xGetImageReq);
+
+ REQUEST_SIZE_MATCH(xGetImageReq);
+
+ return DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+ int err;
+ REQUEST(xPolyTextReq);
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = PolyText(client,
+ pDraw,
+ pGC,
+ (unsigned char *)&stuff[1],
+ ((unsigned char *) stuff) + (client->req_len << 2),
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+ VisualPtr pVisual;
+ ColormapPtr pmap;
+ Colormap mid;
+ register WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xCreateColormapReq);
+ int i, result;
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+ {
+ client->errorValue = stuff->alloc;
+ return(BadValue);
+ }
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid != stuff->visual)
+ continue;
+ result = CreateColormap(mid, pScreen, pVisual, &pmap,
+ (int)stuff->alloc, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ client->errorValue = stuff->visual;
+ return(BadMatch);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+ ColormapPtr pmap;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+ SecurityDestroyAccess);
+ if (pmap)
+ {
+ /* Freeing a default colormap is a no-op */
+ if (!(pmap->flags & IsDefault))
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+ Colormap mid;
+ ColormapPtr pSrcMap;
+ REQUEST(xCopyColormapAndFreeReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap,
+ RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+ {
+ result = CopyColormapAndFree(mid, pSrcMap, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->srcCmap;
+ return(BadColor);
+ }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ (*(pcmp->pScreen->InstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ if(pcmp->mid != pcmp->pScreen->defColormap)
+ (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+ xListInstalledColormapsReply *preply;
+ int nummaps;
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+
+ if (!pWin)
+ return(BadWindow);
+
+ preply = (xListInstalledColormapsReply *)
+ ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+ pWin->drawable.pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ if(!preply)
+ return(BadAlloc);
+
+ preply->type = X_Reply;
+ preply->sequenceNumber = client->sequence;
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+ preply->nColormaps = nummaps;
+ preply->length = nummaps;
+ WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+ DEALLOCATE_LOCAL(preply);
+ return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+ ColormapPtr pmap;
+ int retval;
+ xAllocColorReply acr;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pmap)
+ {
+ acr.type = X_Reply;
+ acr.length = 0;
+ acr.sequenceNumber = client->sequence;
+ acr.red = stuff->red;
+ acr.green = stuff->green;
+ acr.blue = stuff->blue;
+ acr.pixel = 0;
+ if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+ &acr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return (retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+ return (client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int retval;
+
+ xAllocNamedColorReply ancr;
+
+ ancr.type = X_Reply;
+ ancr.length = 0;
+ ancr.sequenceNumber = client->sequence;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+ {
+ ancr.screenRed = ancr.exactRed;
+ ancr.screenGreen = ancr.exactGreen;
+ ancr.screenBlue = ancr.exactBlue;
+ ancr.pixel = 0;
+ if( (retval = AllocColor(pcmp,
+ &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+ &ancr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+ return (client->noClientException);
+ }
+ else
+ return(BadName);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorCellsReply accr;
+ int npixels, nmasks, retval;
+ long length;
+ Pixel *ppixels, *pmasks;
+
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ nmasks = stuff->planes;
+ length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ pmasks = ppixels + npixels;
+
+ if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks,
+ (Bool)stuff->contiguous, ppixels, pmasks)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ accr.type = X_Reply;
+ accr.length = length >> 2;
+ accr.sequenceNumber = client->sequence;
+ accr.nPixels = npixels;
+ accr.nMasks = nmasks;
+ WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorPlanesReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorPlanesReply acpr;
+ int npixels, retval;
+ long length;
+ Pixel *ppixels;
+
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ acpr.type = X_Reply;
+ acpr.sequenceNumber = client->sequence;
+ acpr.nPixels = npixels;
+ length = (long)npixels * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+ (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+ (Bool)stuff->contiguous, ppixels,
+ &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ acpr.length = length >> 2;
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xFreeColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ if(pcmp->flags & AllAllocated)
+ return(BadAccess);
+ count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+ retval = FreeColors(pcmp, client->index, count,
+ (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+ if (count % sizeof(xColorItem))
+ return(BadLength);
+ count /= sizeof(xColorItem);
+ retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xColorItem def;
+ int retval;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+ stuff->nbytes, &def.red, &def.green, &def.blue))
+ {
+ def.flags = stuff->flags;
+ def.pixel = stuff->pixel;
+ retval = StoreColors(pcmp, 1, &def);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xQueryColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ int count, retval;
+ xrgb *prgbs;
+ xQueryColorsReply qcr;
+
+ count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+ prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+ if(!prgbs && count)
+ return(BadAlloc);
+ if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+ {
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return (retval);
+ }
+ }
+ qcr.type = X_Reply;
+ qcr.length = (count * sizeof(xrgb)) >> 2;
+ qcr.sequenceNumber = client->sequence;
+ qcr.nColors = count;
+ WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+ WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+ }
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ return(client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xLookupColorReq);
+
+ REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ xLookupColorReply lcr;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+ {
+ lcr.type = X_Reply;
+ lcr.length = 0;
+ lcr.sequenceNumber = client->sequence;
+ lcr.screenRed = lcr.exactRed;
+ lcr.screenGreen = lcr.exactGreen;
+ lcr.screenBlue = lcr.exactBlue;
+ (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+ &lcr.screenGreen,
+ &lcr.screenBlue,
+ pcmp->pVisual);
+ WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+ return(client->noClientException);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+
+ register PixmapPtr src;
+ register PixmapPtr msk;
+ unsigned char * srcbits;
+ unsigned char * mskbits;
+ unsigned short width, height;
+ long n;
+ CursorMetricRec cm;
+
+
+ REQUEST(xCreateCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+ RT_PIXMAP, SecurityReadAccess);
+ msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+ RT_PIXMAP, SecurityReadAccess);
+ if ( src == (PixmapPtr)NULL)
+ {
+ client->errorValue = stuff->source;
+ return (BadPixmap);
+ }
+ if ( msk == (PixmapPtr)NULL)
+ {
+ if (stuff->mask != None)
+ {
+ client->errorValue = stuff->mask;
+ return (BadPixmap);
+ }
+ }
+ else if ( src->drawable.width != msk->drawable.width
+ || src->drawable.height != msk->drawable.height
+ || src->drawable.depth != 1
+ || msk->drawable.depth != 1)
+ return (BadMatch);
+
+ width = src->drawable.width;
+ height = src->drawable.height;
+
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+
+ n = BitmapBytePad(width)*height;
+ srcbits = (unsigned char *)xalloc(n);
+ if (!srcbits)
+ return (BadAlloc);
+ mskbits = (unsigned char *)xalloc(n);
+ if (!mskbits)
+ {
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)srcbits, n);
+ (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+ XYPixmap, 1, (pointer)srcbits);
+ if ( msk == (PixmapPtr)NULL)
+ {
+ register unsigned char *bits = mskbits;
+ while (--n >= 0)
+ *bits++ = ~0;
+ }
+ else
+ {
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)mskbits, n);
+ (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+ height, XYPixmap, 1, (pointer)mskbits);
+ }
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ pCursor = AllocCursor( srcbits, mskbits, &cm,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+ if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ int res;
+
+ REQUEST(xCreateGlyphCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+ stuff->mask, stuff->maskChar,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue,
+ &pCursor, client);
+ if (res != Success)
+ return res;
+ if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_CURSOR, SecurityDestroyAccess);
+ if (pCursor)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadCursor);
+ }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+ xQueryBestSizeReply reply;
+ register DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ REQUEST(xQueryBestSizeReq);
+
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+ if ((stuff->class != CursorShape) &&
+ (stuff->class != TileShape) &&
+ (stuff->class != StippleShape))
+ {
+ client->errorValue = stuff->class;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+ return (BadMatch);
+ pScreen = pDraw->pScreen;
+ (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+ &stuff->height, pScreen);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.width = stuff->width;
+ reply.height = stuff->height;
+ WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+ return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+ int blankingOption, exposureOption;
+ REQUEST(xSetScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ blankingOption = stuff->preferBlank;
+ if ((blankingOption != DontPreferBlanking) &&
+ (blankingOption != PreferBlanking) &&
+ (blankingOption != DefaultBlanking))
+ {
+ client->errorValue = blankingOption;
+ return BadValue;
+ }
+ exposureOption = stuff->allowExpose;
+ if ((exposureOption != DontAllowExposures) &&
+ (exposureOption != AllowExposures) &&
+ (exposureOption != DefaultExposures))
+ {
+ client->errorValue = exposureOption;
+ return BadValue;
+ }
+ if (stuff->timeout < -1)
+ {
+ client->errorValue = stuff->timeout;
+ return BadValue;
+ }
+ if (stuff->interval < -1)
+ {
+ client->errorValue = stuff->interval;
+ return BadValue;
+ }
+
+ if (blankingOption == DefaultBlanking)
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ else
+ ScreenSaverBlanking = blankingOption;
+ if (exposureOption == DefaultExposures)
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+ else
+ ScreenSaverAllowExposures = exposureOption;
+
+ if (stuff->timeout >= 0)
+ ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+ else
+ ScreenSaverTime = defaultScreenSaverTime;
+ if (stuff->interval >= 0)
+ ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+ else
+ ScreenSaverInterval = defaultScreenSaverInterval;
+
+ SetScreenSaverTimer();
+ return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+ xGetScreenSaverReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+ rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+ rep.preferBlanking = ScreenSaverBlanking;
+ rep.allowExposures = ScreenSaverAllowExposures;
+ WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+ REQUEST(xChangeHostsReq);
+ int result;
+
+ REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+ if(stuff->mode == HostInsert)
+ result = AddHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else if (stuff->mode == HostDelete)
+ result = RemoveHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+ xListHostsReply reply;
+ int len, nHosts, result;
+ pointer pdata;
+ /* REQUEST(xListHostsReq); */
+
+ REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XACE
+ /* untrusted clients can't list hosts */
+ if (!XaceHook(XACE_HOSTLIST_ACCESS, client, SecurityReadAccess))
+ {
+ return BadAccess;
+ }
+#endif
+ result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+ if (result != Success)
+ return(result);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.nHosts = nHosts;
+ reply.length = len >> 2;
+ WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+ if (nHosts)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+ WriteSwappedDataToClient(client, len, pdata);
+ }
+ xfree(pdata);
+ return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+ int result;
+ REQUEST(xSetAccessControlReq);
+
+ REQUEST_SIZE_MATCH(xSetAccessControlReq);
+ if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ ClientPtr killclient;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (stuff->id == AllTemporary)
+ {
+ CloseDownRetainedResources();
+ return (client->noClientException);
+ }
+
+ if ((killclient = LookupClient(stuff->id, client)))
+ {
+ CloseDownClient(killclient);
+ /* if an LBX proxy gets killed, isItTimeToYield will be set */
+ if (isItTimeToYield || (client == killclient))
+ {
+ /* force yield and return Success, so that Dispatch()
+ * doesn't try to touch client
+ */
+ isItTimeToYield = TRUE;
+ return (Success);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadValue);
+ }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+ unsigned char *ptr;
+ unsigned long nbytes, total;
+ long nfonts;
+ int n, result;
+ int error;
+ REQUEST(xSetFontPathReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+
+ nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+ total = nbytes;
+ ptr = (unsigned char *)&stuff[1];
+ nfonts = stuff->nFonts;
+ while (--nfonts >= 0)
+ {
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return(BadLength);
+ total -= n;
+ ptr += n;
+ }
+ if (total >= 4)
+ return(BadLength);
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+ &error);
+ if (!result)
+ {
+ result = client->noClientException;
+ client->errorValue = error;
+ }
+ return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+ xGetFontPathReply reply;
+ int stringLens, numpaths;
+ unsigned char *bufferStart;
+ /* REQUEST (xReq); */
+
+ REQUEST_SIZE_MATCH(xReq);
+ bufferStart = GetFontPath(&numpaths, &stringLens);
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = (stringLens + numpaths + 3) >> 2;
+ reply.nPaths = numpaths;
+
+ WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+ if (stringLens || numpaths)
+ (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+ return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+ REQUEST(xSetCloseDownModeReq);
+
+ REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+ if ((stuff->mode == AllTemporary) ||
+ (stuff->mode == RetainPermanent) ||
+ (stuff->mode == RetainTemporary))
+ {
+ client->closeDownMode = stuff->mode;
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return (BadValue);
+ }
+}
+
+int ProcForceScreenSaver(register ClientPtr client)
+{
+ REQUEST(xForceScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+
+ if ((stuff->mode != ScreenSaverReset) &&
+ (stuff->mode != ScreenSaverActive))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+ return client->noClientException;
+}
+
+int ProcNoOperation(register ClientPtr client)
+{
+ REQUEST_AT_LEAST_SIZE(xReq);
+
+ /* noop -- don't do anything */
+ return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+ int i;
+ for (i = 0; i<256; i++)
+ {
+ if(!ProcVector[i])
+ {
+ ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+ ReplySwapVector[i] = ReplyNotSwappd;
+ }
+#ifdef K5AUTH
+ if (!k5_Vector[i])
+ {
+ k5_Vector[i] = k5_bad;
+ }
+#endif
+ }
+ for(i = LASTEvent; i < 128; i++)
+ {
+ EventSwapVector[i] = NotImplemented;
+ }
+
+}
+
+/**********************
+ * CloseDownClient
+ *
+ * Client can either mark his resources destroy or retain. If retained and
+ * then killed again, the client is really destroyed.
+ *********************/
+
+char dispatchExceptionAtReset = DE_RESET;
+
+void
+CloseDownClient(register ClientPtr client)
+{
+ Bool really_close_down = client->clientGone ||
+ client->closeDownMode == DestroyAll;
+
+ if (!client->clientGone)
+ {
+ /* ungrab server if grabbing client dies */
+ if (grabState != GrabNone && grabClient == client)
+ {
+ UngrabServer(client);
+ }
+ BITCLEAR(grabWaiters, client->index);
+ DeleteClientFromAnySelections(client);
+ ReleaseActiveGrabs(client);
+ DeleteClientFontStuff(client);
+ if (!really_close_down)
+ {
+ /* This frees resources that should never be retained
+ * no matter what the close down mode is. Actually we
+ * could do this unconditionally, but it's probably
+ * better not to traverse all the client's resources
+ * twice (once here, once a few lines down in
+ * FreeClientResources) in the common case of
+ * really_close_down == TRUE.
+ */
+ FreeClientNeverRetainResources(client);
+ client->clientState = ClientStateRetained;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ }
+ client->clientGone = TRUE; /* so events aren't sent to client */
+ if (ClientIsAsleep(client))
+ ClientSignal (client);
+ ProcessWorkQueueZombies();
+ CloseDownConnection(client);
+
+ /* If the client made it to the Running stage, nClients has
+ * been incremented on its behalf, so we need to decrement it
+ * now. If it hasn't gotten to Running, nClients has *not*
+ * been incremented, so *don't* decrement it.
+ */
+ if (client->clientState != ClientStateInitial &&
+ client->clientState != ClientStateAuthenticating )
+ {
+ --nClients;
+ }
+ }
+
+ if (really_close_down)
+ {
+ if (client->clientState == ClientStateRunning && nClients == 0)
+ dispatchException |= dispatchExceptionAtReset;
+
+ client->clientState = ClientStateGone;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ FreeClientResources(client);
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+ SmartLastClient = NullClient;
+#endif
+ xfree(client);
+
+ while (!clients[currentMaxClients-1])
+ currentMaxClients--;
+ }
+}
+
+static void
+KillAllClients()
+{
+ int i;
+ for (i=1; i<currentMaxClients; i++)
+ if (clients[i]) {
+ /* Make sure Retained clients are released. */
+ clients[i]->closeDownMode = DestroyAll;
+ CloseDownClient(clients[i]);
+ }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ * Find all clients that are gone and have terminated in RetainTemporary
+ * and destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+ register int i;
+ register ClientPtr client;
+
+ for (i=1; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && (client->closeDownMode == RetainTemporary)
+ && (client->clientGone))
+ CloseDownClient(client);
+ }
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+ client->index = i;
+ client->sequence = 0;
+ client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+ client->clientGone = FALSE;
+ if (i)
+ {
+ client->closeDownMode = DestroyAll;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ else
+ {
+ client->closeDownMode = RetainPermanent;
+ client->lastDrawable = (DrawablePtr)NULL;
+ client->lastDrawableID = INVALID;
+ }
+ client->lastGC = (GCPtr) NULL;
+ client->lastGCID = INVALID;
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+ client->noClientException = Success;
+#ifdef DEBUG
+ client->requestLogIndex = 0;
+#endif
+ client->requestVector = InitialVector;
+ client->osPrivate = ospriv;
+ client->swapped = FALSE;
+ client->big_requests = FALSE;
+ client->priority = 0;
+ client->clientState = ClientStateInitial;
+#ifdef XKB
+ if (!noXkbExtension) {
+ client->xkbClientFlags = 0;
+ client->mapNotifyMask = 0;
+ QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+ }
+#endif
+ client->replyBytesRemaining = 0;
+#ifdef XAPPGROUP
+ client->appgroup = NULL;
+#endif
+ client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+ client->smart_priority = 0;
+ client->smart_start_tick = SmartScheduleTime;
+ client->smart_stop_tick = SmartScheduleTime;
+ client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+int
+InitClientPrivates(ClientPtr client)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalClientSize == sizeof(ClientRec))
+ ppriv = (DevUnion *)NULL;
+ else if (client->index)
+ ppriv = (DevUnion *)(client + 1);
+ else
+ {
+ ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+ if (!ppriv)
+ return 0;
+ }
+ client->devPrivates = ppriv;
+ sizes = clientPrivateSizes;
+ ptr = (char *)(ppriv + clientPrivateLen);
+ for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+
+ /* Allow registrants to initialize the serverClient devPrivates */
+ if (!client->index && ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+ register int i;
+ register ClientPtr client;
+ xReq data;
+
+ i = nextFreeClientID;
+ if (i == MAXCLIENTS)
+ return (ClientPtr)NULL;
+ clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+ if (!client)
+ return (ClientPtr)NULL;
+ InitClient(client, i, ospriv);
+ InitClientPrivates(client);
+ if (!InitClientResources(client))
+ {
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ data.reqType = 1;
+ data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+ {
+ FreeClientResources(client);
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ if (i == currentMaxClients)
+ currentMaxClients++;
+ while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+ nextFreeClientID++;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+ REQUEST(xReq);
+ register xConnClientPrefix *prefix;
+ int whichbyte = 1;
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ return (client->noClientException = -1);
+ if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+ {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
+ }
+ stuff->reqType = 2;
+ stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+ ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+ if (client->swapped)
+ {
+ swaps(&stuff->length, whichbyte);
+ }
+ ResetCurrentRequest(client);
+ return (client->noClientException);
+}
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+ register xWindowRoot *root;
+ register int i;
+ int numScreens;
+ char* lConnectionInfo;
+ xConnSetupPrefix* lconnSetupPrefix;
+
+ if (reason)
+ {
+ xConnSetupPrefix csp;
+
+ csp.success = xFalse;
+ csp.lengthReason = strlen(reason);
+ csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+ (void)WriteToClient(client, (int)csp.lengthReason, reason);
+ return (client->noClientException = -1);
+ }
+
+ numScreens = screenInfo.numScreens;
+ lConnectionInfo = ConnectionInfo;
+ lconnSetupPrefix = &connSetupPrefix;
+
+ /* We're about to start speaking X protocol back to the client by
+ * sending the connection setup info. This means the authorization
+ * step is complete, and we can count the client as an
+ * authorized one.
+ */
+ nClients++;
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+#ifdef XAPPGROUP
+ XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+ ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+ ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+ ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+ ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+ /* fill in the "currentInputMask" */
+ root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+ for (i=0; i<numScreens; i++)
+ {
+ register unsigned int j;
+ register xDepth *pDepth;
+
+ root->currentInputMask = WindowTable[i]->eventMask |
+ wOtherEventMasks (WindowTable[i]);
+ pDepth = (xDepth *)(root + 1);
+ for (j = 0; j < root->nDepths; j++)
+ {
+ pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+ pDepth->nVisuals * sizeof(xVisualType));
+ }
+ root = (xWindowRoot *)pDepth;
+ }
+
+ if (client->swapped)
+ {
+ WriteSConnSetupPrefix(client, lconnSetupPrefix);
+ WriteSConnectionInfo(client,
+ (unsigned long)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ else
+ {
+ (void)WriteToClient(client, sizeof(xConnSetupPrefix),
+ (char *) lconnSetupPrefix);
+ (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = lconnSetupPrefix;
+ clientinfo.setup = (xConnSetup *)lConnectionInfo;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+ char *reason, *auth_proto, *auth_string;
+ register xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ (unsigned short)prefix->nbytesAuthProto,
+ auth_proto,
+ (unsigned short)prefix->nbytesAuthString,
+ auth_string);
+ /*
+ * If Kerberos is being used for this client, the clientState
+ * will be set to ClientStateAuthenticating at this point.
+ * More messages need to be exchanged among the X server, Kerberos
+ * server, and client to figure out if everyone is authorized.
+ * So we don't want to send the connection setup info yet, since
+ * the auth step isn't really done.
+ */
+ if (client->clientState == ClientStateCheckingSecurity)
+ client->clientState = ClientStateCheckedSecurity;
+ else if (client->clientState != ClientStateAuthenticating)
+ return(SendConnSetup(client, reason));
+ return(client->noClientException);
+}
+
+_X_EXPORT void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
+ XID resId, int errorCode)
+{
+ xError rep;
+
+ rep.type = X_Error;
+ rep.sequenceNumber = client->sequence;
+ rep.errorCode = errorCode;
+ rep.majorCode = majorCode;
+ rep.minorCode = minorCode;
+ rep.resourceID = resId;
+
+ WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].pWin == pWin)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].client == client)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+ client->noClientException = -1;
+}
diff --git a/xserver/dix/dispatch.h b/xserver/dix/dispatch.h
new file mode 100644
index 000000000..dd07096af
--- /dev/null
+++ b/xserver/dix/dispatch.h
@@ -0,0 +1,146 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+/*
+ * This prototypes the dispatch.c module (except for functions declared in
+ * global headers), plus related dispatch procedures from devices.c, events.c,
+ * extension.c, property.c.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef DISPATCH_H
+#define DISPATCH_H 1
+
+DISPATCH_PROC(InitClientPrivates);
+DISPATCH_PROC(ProcAllocColor);
+DISPATCH_PROC(ProcAllocColorCells);
+DISPATCH_PROC(ProcAllocColorPlanes);
+DISPATCH_PROC(ProcAllocNamedColor);
+DISPATCH_PROC(ProcBell);
+DISPATCH_PROC(ProcChangeAccessControl);
+DISPATCH_PROC(ProcChangeCloseDownMode);
+DISPATCH_PROC(ProcChangeGC);
+DISPATCH_PROC(ProcChangeHosts);
+DISPATCH_PROC(ProcChangeKeyboardControl);
+DISPATCH_PROC(ProcChangeKeyboardMapping);
+DISPATCH_PROC(ProcChangePointerControl);
+DISPATCH_PROC(ProcChangeProperty);
+DISPATCH_PROC(ProcChangeSaveSet);
+DISPATCH_PROC(ProcChangeWindowAttributes);
+DISPATCH_PROC(ProcCirculateWindow);
+DISPATCH_PROC(ProcClearToBackground);
+DISPATCH_PROC(ProcCloseFont);
+DISPATCH_PROC(ProcConfigureWindow);
+DISPATCH_PROC(ProcConvertSelection);
+DISPATCH_PROC(ProcCopyArea);
+DISPATCH_PROC(ProcCopyColormapAndFree);
+DISPATCH_PROC(ProcCopyGC);
+DISPATCH_PROC(ProcCopyPlane);
+DISPATCH_PROC(ProcCreateColormap);
+DISPATCH_PROC(ProcCreateCursor);
+DISPATCH_PROC(ProcCreateGC);
+DISPATCH_PROC(ProcCreateGlyphCursor);
+DISPATCH_PROC(ProcCreatePixmap);
+DISPATCH_PROC(ProcCreateWindow);
+DISPATCH_PROC(ProcDeleteProperty);
+DISPATCH_PROC(ProcDestroySubwindows);
+DISPATCH_PROC(ProcDestroyWindow);
+DISPATCH_PROC(ProcEstablishConnection);
+DISPATCH_PROC(ProcFillPoly);
+DISPATCH_PROC(ProcForceScreenSaver);
+DISPATCH_PROC(ProcFreeColormap);
+DISPATCH_PROC(ProcFreeColors);
+DISPATCH_PROC(ProcFreeCursor);
+DISPATCH_PROC(ProcFreeGC);
+DISPATCH_PROC(ProcFreePixmap);
+DISPATCH_PROC(ProcGetAtomName);
+DISPATCH_PROC(ProcGetFontPath);
+DISPATCH_PROC(ProcGetGeometry);
+DISPATCH_PROC(ProcGetImage);
+DISPATCH_PROC(ProcGetKeyboardControl);
+DISPATCH_PROC(ProcGetKeyboardMapping);
+DISPATCH_PROC(ProcGetModifierMapping);
+DISPATCH_PROC(ProcGetMotionEvents);
+DISPATCH_PROC(ProcGetPointerControl);
+DISPATCH_PROC(ProcGetPointerMapping);
+DISPATCH_PROC(ProcGetProperty);
+DISPATCH_PROC(ProcGetScreenSaver);
+DISPATCH_PROC(ProcGetSelectionOwner);
+DISPATCH_PROC(ProcGetWindowAttributes);
+DISPATCH_PROC(ProcGrabServer);
+DISPATCH_PROC(ProcImageText16);
+DISPATCH_PROC(ProcImageText8);
+DISPATCH_PROC(ProcInitialConnection);
+DISPATCH_PROC(ProcInstallColormap);
+DISPATCH_PROC(ProcInternAtom);
+DISPATCH_PROC(ProcKillClient);
+DISPATCH_PROC(ProcListExtensions);
+DISPATCH_PROC(ProcListFonts);
+DISPATCH_PROC(ProcListFontsWithInfo);
+DISPATCH_PROC(ProcListHosts);
+DISPATCH_PROC(ProcListInstalledColormaps);
+DISPATCH_PROC(ProcListProperties);
+DISPATCH_PROC(ProcLookupColor);
+DISPATCH_PROC(ProcMapSubwindows);
+DISPATCH_PROC(ProcMapWindow);
+DISPATCH_PROC(ProcNoOperation);
+DISPATCH_PROC(ProcOpenFont);
+DISPATCH_PROC(ProcPolyArc);
+DISPATCH_PROC(ProcPolyFillArc);
+DISPATCH_PROC(ProcPolyFillRectangle);
+DISPATCH_PROC(ProcPolyLine);
+DISPATCH_PROC(ProcPolyPoint);
+DISPATCH_PROC(ProcPolyRectangle);
+DISPATCH_PROC(ProcPolySegment);
+DISPATCH_PROC(ProcPolyText);
+DISPATCH_PROC(ProcPutImage);
+DISPATCH_PROC(ProcQueryBestSize);
+DISPATCH_PROC(ProcQueryColors);
+DISPATCH_PROC(ProcQueryExtension);
+DISPATCH_PROC(ProcQueryFont);
+DISPATCH_PROC(ProcQueryKeymap);
+DISPATCH_PROC(ProcQueryTextExtents);
+DISPATCH_PROC(ProcQueryTree);
+DISPATCH_PROC(ProcReparentWindow);
+DISPATCH_PROC(ProcRotateProperties);
+DISPATCH_PROC(ProcSetClipRectangles);
+DISPATCH_PROC(ProcSetDashes);
+DISPATCH_PROC(ProcSetFontPath);
+DISPATCH_PROC(ProcSetModifierMapping);
+DISPATCH_PROC(ProcSetPointerMapping);
+DISPATCH_PROC(ProcSetScreenSaver);
+DISPATCH_PROC(ProcSetSelectionOwner);
+DISPATCH_PROC(ProcStoreColors);
+DISPATCH_PROC(ProcStoreNamedColor);
+DISPATCH_PROC(ProcTranslateCoords);
+DISPATCH_PROC(ProcUngrabServer);
+DISPATCH_PROC(ProcUninstallColormap);
+DISPATCH_PROC(ProcUnmapSubwindows);
+DISPATCH_PROC(ProcUnmapWindow);
+
+#endif /* DISPATCH_H */
diff --git a/xserver/dix/dixfonts.c b/xserver/dix/dixfonts.c
new file mode 100644
index 000000000..f10011e4b
--- /dev/null
+++ b/xserver/dix/dixfonts.c
@@ -0,0 +1,2133 @@
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+/* The panoramix components contained the following notice */
+/*
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+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.
+
+The above copyright notice and this permission notice 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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int num_fpes = 0;
+_X_EXPORT FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int num_slept_fpes = 0;
+static int size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+_X_EXPORT int
+FontToXError(err)
+ int err;
+{
+ switch (err) {
+ case Successful:
+ return Success;
+ case AllocError:
+ return BadAlloc;
+ case BadFontName:
+ return BadName;
+ case BadFontPath:
+ case BadFontFormat: /* is there something better? */
+ case BadCharRange:
+ return BadValue;
+ default:
+ return err;
+ }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+ int err;
+ FontPtr pf;
+ XID fid;
+
+ fid = FakeClientID(0);
+ err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+ (unsigned) strlen(defaultfontname), defaultfontname);
+ if (err != Success)
+ return FALSE;
+ pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+ if (pf == (FontPtr) NULL)
+ return FALSE;
+ defaultFont = pf;
+ return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted. this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+ int i;
+ FontPathElementPtr *new;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+ fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+ return;
+ }
+ }
+ if (num_slept_fpes == size_slept_fpes) {
+ new = (FontPathElementPtr *)
+ xrealloc(slept_fpes,
+ sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+ if (!new)
+ return;
+ slept_fpes = new;
+ size_slept_fpes += 4;
+ }
+ slept_fpes[num_slept_fpes] = fpe;
+ num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+ int i,
+ j;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ for (j = i; j < num_slept_fpes; j++) {
+ slept_fpes[j] = slept_fpes[j + 1];
+ }
+ num_slept_fpes--;
+ return;
+ }
+ }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ if (count < 0)
+ return;
+ /* wake up any fpe's that may be waiting for information */
+ for (i = 0; i < num_slept_fpes; i++) {
+ fpe = slept_fpes[i];
+ (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+ }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+ fpe->refcount--;
+ if (fpe->refcount == 0) {
+ (*fpe_functions[fpe->type].free_fpe) (fpe);
+ xfree(fpe->name);
+ xfree(fpe);
+ }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ ScreenPtr pScr;
+ int err = Successful;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ int aliascount = 20;
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+ Mask FontFormat =
+
+ ((screenInfo.imageByteOrder == LSBFirst) ?
+ BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+ ((screenInfo.bitmapBitOrder == LSBFirst) ?
+ BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+ BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+ BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+ BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+ BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+ BitmapFormatScanlinePad64 |
+#endif
+
+ BitmapFormatScanlineUnit8;
+
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (c->current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current_fpe];
+ err = (*fpe_functions[fpe->type].open_font)
+ ((pointer) client, fpe, c->flags,
+ c->fontname, c->fnamelen, FontFormat,
+ BitmapFormatMaskByte |
+ BitmapFormatMaskBit |
+ BitmapFormatMaskImageRectangle |
+ BitmapFormatMaskScanLinePad |
+ BitmapFormatMaskScanLineUnit,
+ c->fontid, &pfont, &alias,
+ c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+ c->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) xrealloc(c->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove(newname, alias, newlen);
+ c->fontname = newname;
+ c->fnamelen = newlen;
+ c->current_fpe = 0;
+ if (--aliascount <= 0)
+ break;
+ continue;
+ }
+ if (err == BadFontName) {
+ c->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ if (err != Successful)
+ goto bail;
+ if (!pfont) {
+ err = BadFontName;
+ goto bail;
+ }
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ pfont->refcnt++;
+ if (pfont->refcnt == 1) {
+ UseFPE(pfont->fpe);
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+ if (!(*pScr->RealizeFont) (pScr, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+ err = AllocError;
+ goto bail;
+ }
+ }
+ }
+ }
+ if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+ err = AllocError;
+ goto bail;
+ }
+ if (patternCache && pfont != c->non_cachable_font)
+ CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
+ pfont);
+bail:
+ if (err != Successful && c->client != serverClient) {
+ SendErrorToClient(c->client, X_OpenFont, 0,
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
+ ClientWakeup(c->client);
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+ xfree(c->fpe_list);
+ xfree(c->fontname);
+ xfree(c);
+ return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+ OFclosurePtr c;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)xalloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ xfree(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (pointer) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+ if (!c)
+ return BadAlloc;
+ c->fontname = (char *) xalloc(lenfname);
+ c->origFontName = pfontname;
+ c->origFontNameLen = lenfname;
+ if (!c->fontname) {
+ xfree(c);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c->fontname);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove(c->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->fontid = fid;
+ c->current_fpe = 0;
+ c->num_fpes = num_fpes;
+ c->fnamelen = lenfname;
+ c->slept = FALSE;
+ c->flags = flags;
+ c->non_cachable_font = cached;
+
+ (void) doOpenFont(client, c);
+ return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ * \param value must conform to DeleteType
+ */
+_X_EXPORT int
+CloseFont(pointer value, XID fid)
+{
+ int nscr;
+ ScreenPtr pscr;
+ FontPathElementPtr fpe;
+ FontPtr pfont = (FontPtr)value;
+
+ if (pfont == NullFont)
+ return (Success);
+ if (--pfont->refcnt == 0) {
+ if (patternCache)
+ RemoveCachedFontPattern (patternCache, pfont);
+ /*
+ * since the last reference is gone, ask each screen to free any
+ * storage it may have allocated locally for it.
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+ pscr = screenInfo.screens[nscr];
+ if (pscr->UnrealizeFont)
+ (*pscr->UnrealizeFont) (pscr, pfont);
+ }
+ if (pfont == defaultFont)
+ defaultFont = NULL;
+#ifdef XF86BIGFONT
+ XF86BigfontFreeFontShm(pfont);
+#endif
+ fpe = pfont->fpe;
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+ FreeFPE(fpe);
+ }
+ return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ * \param pReply caller must allocate this storage
+ */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+ FontPropPtr pFP;
+ int r,
+ c,
+ i;
+ xFontProp *prFP;
+ xCharInfo *prCI;
+ xCharInfo *charInfos[256];
+ unsigned char chars[512];
+ int ninfos;
+ unsigned long ncols;
+ unsigned long count;
+
+ /* pr->length set in dispatch */
+ pReply->minCharOrByte2 = pFont->info.firstCol;
+ pReply->defaultChar = pFont->info.defaultCh;
+ pReply->maxCharOrByte2 = pFont->info.lastCol;
+ pReply->drawDirection = pFont->info.drawDirection;
+ pReply->allCharsExist = pFont->info.allExist;
+ pReply->minByte1 = pFont->info.firstRow;
+ pReply->maxByte1 = pFont->info.lastRow;
+ pReply->fontAscent = pFont->info.fontAscent;
+ pReply->fontDescent = pFont->info.fontDescent;
+
+ pReply->minBounds = pFont->info.ink_minbounds;
+ pReply->maxBounds = pFont->info.ink_maxbounds;
+
+ pReply->nFontProps = pFont->info.nprops;
+ pReply->nCharInfos = nProtoCCIStructs;
+
+ for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+ i < pFont->info.nprops;
+ i++, pFP++, prFP++) {
+ prFP->name = pFP->name;
+ prFP->value = pFP->value;
+ }
+
+ ninfos = 0;
+ ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+ prCI = (xCharInfo *) (prFP);
+ for (r = pFont->info.firstRow;
+ ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+ r++) {
+ i = 0;
+ for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+ chars[i++] = r;
+ chars[i++] = c;
+ }
+ (*pFont->get_metrics) (pFont, ncols, chars,
+ TwoD16Bit, &count, charInfos);
+ i = 0;
+ for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+ *prCI = *charInfos[i];
+ prCI++;
+ ninfos++;
+ }
+ }
+ return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ xListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) xfree(resolved);
+ resolved = (char *) xalloc(resolvedlen + 1);
+ if (resolved)
+ memmove(resolved, tmpname, resolvedlen + 1);
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ (void)AddFontNamesName(c->names, c->savedName,
+ c->savedNameLen);
+ }
+ else
+ (void)AddFontNamesName(c->names, name, namelen);
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+ goto bail;
+ }
+
+finish:
+
+ names = c->names;
+ nnames = names->nnames;
+ client = c->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ reply.type = X_Reply;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+ WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+ (void) WriteToClient(client, stringLens + nnames, bufferStart);
+ DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ FreeFontNames(names);
+ xfree(c);
+ if (resolved) xfree(resolved);
+ return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
+ unsigned max_names)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+ return BadAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c);
+ return BadAlloc;
+ }
+ c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsAndAliases(client, c);
+ return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ xListFontsWithInfoReply *reply;
+ int length;
+ xFontProp *pFP;
+ int i;
+ int aliascount = 0;
+ xListFontsWithInfoReply finalReply;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+ if (!c->current.patlen)
+ goto finish;
+ while (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+ if (!c->current.list_started)
+ {
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+ (client, fpe, c->current.pattern, c->current.patlen,
+ c->current.max_names, &c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful)
+ {
+ name = 0;
+ pFontInfo = &fontInfo;
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &name, &namelen, &pFontInfo,
+ &numFonts, c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias)
+ {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+ &numFonts, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ c->savedNumFonts = numFonts;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, name, namelen);
+ c->current.patlen = namelen;
+ c->current.max_names = 1;
+ c->current.current_fpe = 0;
+ c->current.private = 0;
+ c->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit. Always wait for BadFontName to let the FPE
+ * have a chance to clean up.
+ */
+ else if (err == BadFontName)
+ {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->current.max_names == 0 ||
+ c->current.current_fpe == c->num_fpes)
+ {
+ c->haveSaved = FALSE;
+ c->saved.max_names -= (1 - c->current.max_names);
+ c->current = c->saved;
+ }
+ }
+ else if (c->current.max_names == 0)
+ break;
+ }
+ else if (err == Successful)
+ {
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+ {
+ reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+ if (!reply)
+ {
+ err = AllocError;
+ break;
+ }
+ c->reply = reply;
+ c->length = length;
+ }
+ if (c->haveSaved)
+ {
+ numFonts = c->savedNumFonts;
+ name = c->savedName;
+ namelen = strlen(name);
+ }
+ reply->type = X_Reply;
+ reply->length = (sizeof *reply - sizeof(xGenericReply) +
+ pFontInfo->nprops * sizeof(xFontProp) +
+ namelen + 3) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->minBounds = pFontInfo->ink_minbounds;
+ reply->maxBounds = pFontInfo->ink_maxbounds;
+ reply->minCharOrByte2 = pFontInfo->firstCol;
+ reply->maxCharOrByte2 = pFontInfo->lastCol;
+ reply->defaultChar = pFontInfo->defaultCh;
+ reply->nFontProps = pFontInfo->nprops;
+ reply->drawDirection = pFontInfo->drawDirection;
+ reply->minByte1 = pFontInfo->firstRow;
+ reply->maxByte1 = pFontInfo->lastRow;
+ reply->allCharsExist = pFontInfo->allExist;
+ reply->fontAscent = pFontInfo->fontAscent;
+ reply->fontDescent = pFontInfo->fontDescent;
+ reply->nReplies = numFonts;
+ pFP = (xFontProp *) (reply + 1);
+ for (i = 0; i < pFontInfo->nprops; i++)
+ {
+ pFP->name = pFontInfo->props[i].name;
+ pFP->value = pFontInfo->props[i].value;
+ pFP++;
+ }
+ WriteSwappedDataToClient(client, length, reply);
+ (void) WriteToClient(client, namelen, name);
+ if (pFontInfo == &fontInfo)
+ {
+ xfree(fontInfo.props);
+ xfree(fontInfo.isStringProp);
+ }
+ --c->current.max_names;
+ }
+ }
+finish:
+ length = sizeof(xListFontsWithInfoReply);
+ bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+ finalReply.type = X_Reply;
+ finalReply.sequenceNumber = client->sequence;
+ finalReply.length = (sizeof(xListFontsWithInfoReply)
+ - sizeof(xGenericReply)) >> 2;
+ WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->reply);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ xfree(c);
+ return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
+ int max_names)
+{
+ int i;
+ LFWIclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list)
+ {
+ xfree(c);
+ goto badAlloc;
+ }
+ memmove(c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++)
+ {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->reply = 0;
+ c->length = 0;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->savedNumFonts = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsWithInfo(client, c);
+ return Success;
+badAlloc:
+ return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+ register FontPtr pFont = c->pGC->font, oldpFont;
+ Font fid, oldfid;
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+ FontPathElementPtr fpe;
+ GC *origGC = NULL;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+ if (c->slept)
+ {
+ /* Client has died, but we cannot bail out right now. We
+ need to clean up after the work we did when going to
+ sleep. Setting the drawable pointer to 0 makes this
+ happen without any attempts to render or perform other
+ unnecessary activities. */
+ c->pDraw = (DrawablePtr)0;
+ }
+ else
+ {
+ err = Success;
+ goto bail;
+ }
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client and avoid further
+ rendering while we clean up after ourself. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ c->pDraw = (DrawablePtr)0;
+ }
+
+ client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+ while (c->endReq - c->pElt > TextEltHeader)
+ {
+ if (*c->pElt == FontChange)
+ {
+ if (c->endReq - c->pElt < FontShiftSize)
+ {
+ err = BadLength;
+ goto bail;
+ }
+
+ oldpFont = pFont;
+ oldfid = fid;
+
+ fid = ((Font)*(c->pElt+4)) /* big-endian */
+ | ((Font)*(c->pElt+3)) << 8
+ | ((Font)*(c->pElt+2)) << 16
+ | ((Font)*(c->pElt+1)) << 24;
+ pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ client->errorValue = fid;
+ err = BadFont;
+ /* restore pFont and fid for step 4 (described below) */
+ pFont = oldpFont;
+ fid = oldfid;
+
+ /* If we're in START_SLEEP mode, the following step
+ shortens the request... in the unlikely event that
+ the fid somehow becomes valid before we come through
+ again to actually execute the polytext, which would
+ then mess up our refcounting scheme badly. */
+ c->err = err;
+ c->endReq = c->pElt;
+
+ goto bail;
+ }
+
+ /* Step 3 (described below) on our new font */
+ if (client_state == START_SLEEP)
+ pFont->refcnt++;
+ else
+ {
+ if (pFont != c->pGC->font && c->pDraw)
+ {
+ ChangeGC( c->pGC, GCFont, &fid);
+ ValidateGC(c->pDraw, c->pGC);
+ if (c->reqType == X_PolyText8)
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+ else
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+ }
+
+ /* Undo the refcnt++ we performed when going to sleep */
+ if (client_state == SLEEPING)
+ (void)CloseFont(c->pGC->font, (Font)0);
+ }
+ c->pElt += FontShiftSize;
+ }
+ else /* print a string */
+ {
+ unsigned char *pNextElt;
+ pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+ if ( pNextElt > c->endReq)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ if (client_state == START_SLEEP)
+ {
+ c->pElt = pNextElt;
+ continue;
+ }
+ if (c->pDraw)
+ {
+ lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+ c->pElt + TextEltHeader);
+ }
+ else lgerr = Successful;
+
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ int len;
+ GC *pGC;
+ PTclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to do a few things
+ to ensure successful and atomic-appearing execution of the
+ remainder of the request. First, copy the remainder of the
+ request into a safe malloc'd area. Second, create a scratch GC
+ to use for the remainder of the request. Third, mark all fonts
+ referenced in the remainder of the request to prevent their
+ deallocation. Fourth, make the original GC look like the
+ request has completed... set its font to the final font value
+ from this request. These GC manipulations are for the unlikely
+ (but possible) event that some other client is using the GC.
+ Steps 3 and 4 are performed by running this procedure through
+ the remainder of the request in a special no-render mode
+ indicated by client_state = START_SLEEP. */
+
+ /* Step 1 */
+ /* Allocate a malloc'd closure structure to replace
+ the local one we were passed */
+ new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ len = c->endReq - c->pElt;
+ c->data = (unsigned char *)xalloc(len);
+ if (!c->data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(c->data, c->pElt, len);
+ c->pElt = c->data;
+ c->endReq = c->pElt + len;
+
+ /* Step 2 */
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ if ((err = CopyGC(c->pGC, pGC, GCFunction |
+ GCPlaneMask | GCForeground |
+ GCBackground | GCFillStyle |
+ GCTile | GCStipple |
+ GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) !=
+ Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ origGC = c->pGC;
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doPolyText,
+ (pointer) c);
+
+ /* Set up to perform steps 3 and 4 */
+ client_state = START_SLEEP;
+ continue; /* on to steps 3 and 4 */
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */
+ c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ *c->pElt, c->pElt + TextEltHeader);
+ }
+ c->pElt = pNextElt;
+ }
+ }
+
+bail:
+
+ if (client_state == START_SLEEP)
+ {
+ /* Step 4 */
+ if (pFont != origGC->font)
+ {
+ ChangeGC(origGC, GCFont, &fid);
+ ValidateGC(c->pDraw, origGC);
+ }
+
+ /* restore pElt pointer for execution of remainder of the request */
+ c->pElt = c->data;
+ return TRUE;
+ }
+
+ if (c->err != Success) err = c->err;
+ if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
+ unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+ PTclosureRec local_closure;
+
+ local_closure.pElt = pElt;
+ local_closure.endReq = endReq;
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_PolyText8)
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.pGC = pGC;
+ local_closure.did = did;
+ local_closure.err = Success;
+ local_closure.slept = FALSE;
+
+ (void) doPolyText(client, &local_closure);
+ return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ FontPathElementPtr fpe;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ GC *pGC;
+ unsigned char *data;
+ ITclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to
+ save some state. Similar problem to that handled
+ in doPolyText, but much simpler because the
+ request structure is much simpler. */
+
+ new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+ if (!data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(data, c->data, c->nChars * c->itemSize);
+ c->data = data;
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+ GCForeground | GCBackground | GCFillStyle |
+ GCTile | GCStipple | GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) != Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ c->nChars, c->data);
+ }
+
+bail:
+
+ if (err != Success && c->client != serverClient) {
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
+ unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+ ITclosureRec local_closure;
+
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.pGC = pGC;
+ local_closure.nChars = nChars;
+ local_closure.data = data;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_ImageText8)
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.did = did;
+ local_closure.slept = FALSE;
+
+ (void) doImageText(client, &local_closure);
+ return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+ int i;
+
+ for (i = 0; i < num_fpe_types; i++) {
+ if ((*fpe_functions[i].name_check) (pathname))
+ return i;
+ }
+ return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (force) {
+ /* Sanity check that all refcounts will be 0 by the time
+ we get to the end of the list. */
+ int found = 1; /* the first reference is us */
+ int j;
+ for (j = i+1; j < n; j++) {
+ if (list[j] == list[i])
+ found++;
+ }
+ if (list[i]->refcount != found) {
+ ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+ list[i]->name_length, list[i]->name,
+ list[i]->refcount, found);
+ list[i]->refcount = found; /* ensure it will get freed */
+ }
+ }
+ FreeFPE(list[i]);
+ }
+ xfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+ FontPathElementPtr fpe;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ fpe = list[i];
+ if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+ return fpe;
+ }
+ return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+ int i, err = 0;
+ int valid_paths = 0;
+ unsigned int len;
+ unsigned char *cp = paths;
+ FontPathElementPtr fpe = NULL, *fplist;
+
+ fplist = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * npaths);
+ if (!fplist) {
+ *bad = 0;
+ return BadAlloc;
+ }
+ for (i = 0; i < num_fpe_types; i++) {
+ if (fpe_functions[i].set_path_hook)
+ (*fpe_functions[i].set_path_hook) ();
+ }
+ for (i = 0; i < npaths; i++)
+ {
+ len = (unsigned int) (*cp++);
+
+ if (len == 0)
+ {
+ if (persist)
+ ErrorF ("Removing empty element from the valid list of fontpaths\n");
+ err = BadValue;
+ }
+ else
+ {
+ /* if it's already in our active list, just reset it */
+ /*
+ * note that this can miss FPE's in limbo -- may be worth catching
+ * them, though it'd muck up refcounting
+ */
+ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+ if (fpe)
+ {
+ err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+ if (err == Successful)
+ {
+ UseFPE(fpe);/* since it'll be decref'd later when freed
+ * from the old list */
+ }
+ else
+ fpe = 0;
+ }
+ /* if error or can't do it, act like it's a new one */
+ if (!fpe)
+ {
+ fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+ if (!fpe)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->name = (char *) xalloc(len + 1);
+ if (!fpe->name)
+ {
+ xfree(fpe);
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->refcount = 1;
+
+ strncpy(fpe->name, (char *) cp, (int) len);
+ fpe->name[len] = '\0';
+ fpe->name_length = len;
+ fpe->type = DetermineFPEType(fpe->name);
+ if (fpe->type == -1)
+ err = BadValue;
+ else
+ err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+ if (err != Successful)
+ {
+ if (persist)
+ {
+ ErrorF("Could not init font path element %s, removing from list!\n",
+ fpe->name);
+ }
+ xfree (fpe->name);
+ xfree (fpe);
+ }
+ }
+ }
+ if (err != Successful)
+ {
+ if (!persist)
+ goto bail;
+ }
+ else
+ {
+ fplist[valid_paths++] = fpe;
+ }
+ cp += len;
+ }
+
+ FreeFontPath(font_path_elements, num_fpes, FALSE);
+ font_path_elements = fplist;
+ if (patternCache)
+ EmptyFontPatternCache(patternCache);
+ num_fpes = valid_paths;
+
+ return Success;
+bail:
+ *bad = i;
+ while (--valid_paths >= 0)
+ FreeFPE(fplist[valid_paths]);
+ xfree(fplist);
+ return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+ int err = Success;
+
+ if (npaths == 0) {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ return BadValue;
+ } else {
+ err = SetFontPathElements(npaths, paths, error, FALSE);
+ }
+ return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+ unsigned char *cp,
+ *pp,
+ *nump,
+ *newpath;
+ int num = 1,
+ len,
+ err,
+ size = 0,
+ bad;
+
+ /* get enough for string, plus values -- use up commas */
+ len = strlen(path) + 1;
+ nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+ if (!newpath)
+ return BadAlloc;
+ pp = (unsigned char *) path;
+ cp++;
+ while (*pp) {
+ if (*pp == ',') {
+ *nump = (unsigned char) size;
+ nump = cp++;
+ pp++;
+ num++;
+ size = 0;
+ } else {
+ *cp++ = *pp++;
+ size++;
+ }
+ }
+ *nump = (unsigned char) size;
+
+ err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+ DEALLOCATE_LOCAL(newpath);
+
+ return err;
+}
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+ int i;
+ unsigned char *c;
+ int len;
+ FontPathElementPtr fpe;
+
+ len = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ len += fpe->name_length + 1;
+ }
+ font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+ if (!font_path_string)
+ return NULL;
+
+ c = font_path_string;
+ *length = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ *c = fpe->name_length;
+ *length += *c++;
+ memmove(c, fpe->name, fpe->name_length);
+ c += fpe->name_length;
+ }
+ *count = num_fpes;
+ return font_path_string;
+}
+
+_X_EXPORT int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+ if (fpe_functions[pfont->fpe->type].load_glyphs)
+ return (*fpe_functions[pfont->fpe->type].load_glyphs)
+ (client, pfont, 0, nchars, item_size, data);
+ else
+ return Successful;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ for (i = 0; i < num_fpes; i++)
+ {
+ fpe = font_path_elements[i];
+ if (fpe_functions[fpe->type].client_died)
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+}
+
+void
+InitFonts ()
+{
+ patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+ if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+ PrinterFontRegisterFpeFunctions();
+ FontFileCheckRegisterFpeFunctions();
+ check_fs_register_fpe_functions();
+ } else
+#endif
+ {
+#ifdef KDRIVESERVER
+ BuiltinRegisterFpeFunctions();
+#endif
+ FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+ fs_register_fpe_functions();
+#endif
+ }
+}
+
+int
+GetDefaultPointSize ()
+{
+ return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+ if (requestingClient && requestingClient->fontResFunc != NULL &&
+ !requestingClient->clientGone)
+ {
+ return (*requestingClient->fontResFunc)(requestingClient, num);
+ }
+ else {
+ static struct _FontResolution res;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[0];
+ res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+ /*
+ * XXX - we'll want this as long as bitmap instances are prevalent
+ so that we can match them from scalable fonts
+ */
+ if (res.x_resolution < 88)
+ res.x_resolution = 75;
+ else
+ res.x_resolution = 100;
+ res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+ if (res.y_resolution < 88)
+ res.y_resolution = 75;
+ else
+ res.y_resolution = 100;
+ res.point_size = 120;
+ *num = 1;
+ return &res;
+ }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func,
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ SetPathFunc set_path_func)
+{
+ FPEFunctions *new;
+
+ /* grow the list */
+ new = (FPEFunctions *) xrealloc(fpe_functions,
+ (num_fpe_types + 1) * sizeof(FPEFunctions));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types].name_check = name_func;
+ fpe_functions[num_fpe_types].open_font = open_func;
+ fpe_functions[num_fpe_types].close_font = close_func;
+ fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+ fpe_functions[num_fpe_types].list_fonts = list_func;
+ fpe_functions[num_fpe_types].start_list_fonts_with_info =
+ start_lfwi_func;
+ fpe_functions[num_fpe_types].list_next_font_with_info =
+ next_lfwi_func;
+ fpe_functions[num_fpe_types].init_fpe = init_func;
+ fpe_functions[num_fpe_types].free_fpe = free_func;
+ fpe_functions[num_fpe_types].reset_fpe = reset_func;
+ fpe_functions[num_fpe_types].client_died = client_died;
+ fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+ fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+ start_list_alias_func;
+ fpe_functions[num_fpe_types].list_next_font_or_alias =
+ next_list_alias_func;
+ fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+ return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+ if (patternCache) {
+ FreeFontPatternCache(patternCache);
+ patternCache = 0;
+ }
+ FreeFontPath(font_path_elements, num_fpes, TRUE);
+ font_path_elements = 0;
+ num_fpes = 0;
+ xfree(fpe_functions);
+ num_fpe_types = 0;
+ fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+ return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+ SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+ return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+ return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+ FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+ return 0;
+}
+
+static int fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+ /* if server has reset, make sure the b&w handlers are reinstalled */
+ if (last_server_gen < serverGeneration) {
+ last_server_gen = serverGeneration;
+ fs_handlers_installed = 0;
+ }
+ if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+ if (!RegisterBlockAndWakeupHandlers(block_handler,
+ FontWakeup, (pointer) 0))
+ return AllocError;
+ fs_handlers_installed++;
+ }
+ QueueFontWakeup(fpe);
+ return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+ if (all) {
+ /* remove the handlers if no one else is using them */
+ if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+ RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+ (pointer) 0);
+ }
+ }
+ RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+ ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
+ :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
+ :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
+ :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
+ : 0)
+
+#define GLYPH_SIZE(ch, nbytes) \
+ GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+ (ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+ int r,
+ l;
+ int bpr;
+ int byte;
+ static unsigned maskTab[] = {
+ (1 << 7), (1 << 6), (1 << 5), (1 << 4),
+ (1 << 3), (1 << 2), (1 << 1), (1 << 0),
+ };
+
+ bpr = GLYPH_SIZE(cip, 4);
+ for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+ pointer row = (pointer) cip->bits + r * bpr;
+
+ byte = 0;
+ for (l = 0; l <= (cip->metrics.rightSideBearing -
+ cip->metrics.leftSideBearing); l++) {
+ if (maskTab[l & 7] & row[l >> 3])
+ putchar('X');
+ else
+ putchar('.');
+ }
+ putchar('\n');
+ }
+}
+
+#endif
diff --git a/xserver/dix/dixutils.c b/xserver/dix/dixutils.c
new file mode 100644
index 000000000..a395d4474
--- /dev/null
+++ b/xserver/dix/dixutils.c
@@ -0,0 +1,938 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+/*
+
+(c)Copyright 1988,1991 Adobe Systems Incorporated. All rights reserved.
+
+Permission to use, copy, modify, distribute, and sublicense this software and its
+documentation for any purpose and without fee is hereby granted, provided that
+the above copyright notices appear in all copies and that both those copyright
+notices and this permission notice appear in supporting documentation and that
+the name of Adobe Systems Incorporated not be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission. No trademark license to use the Adobe trademarks is hereby
+granted. If the Adobe trademark "Display PostScript"(tm) is used to describe
+this software, its functionality or for any other purpose, such use shall be
+limited to a statement that this software works in conjunction with the Display
+PostScript system. Proper trademark attribution to reflect Adobe's ownership
+of the trademark shall be given whenever any such reference to the Display
+PostScript system is made.
+
+ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY
+PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ADOBE
+DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
+INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE TO YOU
+OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,NEGLIGENCE, STRICT
+LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER
+SUPPORT FOR THE SOFTWARE.
+
+Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
+Incorporated which may be registered in certain jurisdictions.
+
+Author: Adobe Systems Incorporated
+
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "misc.h"
+#include "windowstr.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+#ifdef XACE
+#include "xace.h"
+#endif
+
+/*
+ * CompareTimeStamps returns -1, 0, or +1 depending on if the first
+ * argument is less than, equal to or greater than the second argument.
+ */
+
+_X_EXPORT int
+CompareTimeStamps(TimeStamp a, TimeStamp b)
+{
+ if (a.months < b.months)
+ return EARLIER;
+ if (a.months > b.months)
+ return LATER;
+ if (a.milliseconds < b.milliseconds)
+ return EARLIER;
+ if (a.milliseconds > b.milliseconds)
+ return LATER;
+ return SAMETIME;
+}
+
+/*
+ * convert client times to server TimeStamps
+ */
+
+#define HALFMONTH ((unsigned long) 1<<31)
+_X_EXPORT TimeStamp
+ClientTimeToServerTime(CARD32 c)
+{
+ TimeStamp ts;
+ if (c == CurrentTime)
+ return currentTime;
+ ts.months = currentTime.months;
+ ts.milliseconds = c;
+ if (c > currentTime.milliseconds)
+ {
+ if (((unsigned long) c - currentTime.milliseconds) > HALFMONTH)
+ ts.months -= 1;
+ }
+ else if (c < currentTime.milliseconds)
+ {
+ if (((unsigned long)currentTime.milliseconds - c) > HALFMONTH)
+ ts.months += 1;
+ }
+ return ts;
+}
+
+/*
+ * ISO Latin-1 case conversion routine
+ *
+ * this routine always null-terminates the result, so
+ * beware of too-small buffers
+ */
+
+static unsigned char
+ISOLatin1ToLower (unsigned char source)
+{
+ unsigned char dest;
+ if ((source >= XK_A) && (source <= XK_Z))
+ dest = source + (XK_a - XK_A);
+ else if ((source >= XK_Agrave) && (source <= XK_Odiaeresis))
+ dest = source + (XK_agrave - XK_Agrave);
+ else if ((source >= XK_Ooblique) && (source <= XK_Thorn))
+ dest = source + (XK_oslash - XK_Ooblique);
+ else
+ dest = source;
+ return dest;
+}
+
+
+_X_EXPORT void
+CopyISOLatin1Lowered(unsigned char *dest, unsigned char *source, int length)
+{
+ register int i;
+
+ for (i = 0; i < length; i++, source++, dest++)
+ *dest = ISOLatin1ToLower (*source);
+ *dest = '\0';
+}
+
+int
+CompareISOLatin1Lowered(unsigned char *s1, int s1len,
+ unsigned char *s2, int s2len)
+{
+ unsigned char c1, c2;
+
+ for (;;)
+ {
+ /* note -- compare against zero so that -1 ignores len */
+ c1 = s1len-- ? *s1++ : '\0';
+ c2 = s2len-- ? *s2++ : '\0';
+ if (!c1 ||
+ (c1 != c2 &&
+ (c1 = ISOLatin1ToLower (c1)) != (c2 = ISOLatin1ToLower (c2))))
+ break;
+ }
+ return (int) c1 - (int) c2;
+}
+
+#ifdef XACE
+
+/* SecurityLookupWindow and SecurityLookupDrawable:
+ * Look up the window/drawable taking into account the client doing
+ * the lookup and the type of access desired. Return the window/drawable
+ * if it exists and the client is allowed access, else return NULL.
+ * Most Proc* functions should be calling these instead of
+ * LookupWindow and LookupDrawable, which do no access checks.
+ * XACE note: need to see if client->lastDrawableID can still be used here.
+ */
+
+_X_EXPORT WindowPtr
+SecurityLookupWindow(XID rid, ClientPtr client, Mask access_mode)
+{
+ client->errorValue = rid;
+ if(rid == INVALID)
+ return NULL;
+ return (WindowPtr)SecurityLookupIDByType(client, rid, RT_WINDOW, access_mode);
+}
+
+
+_X_EXPORT pointer
+SecurityLookupDrawable(XID rid, ClientPtr client, Mask access_mode)
+{
+ register DrawablePtr pDraw;
+
+ if(rid == INVALID)
+ return (pointer) NULL;
+ pDraw = (DrawablePtr)SecurityLookupIDByClass(client, rid, RC_DRAWABLE,
+ access_mode);
+ if (pDraw && (pDraw->type != UNDRAWABLE_WINDOW))
+ return (pointer)pDraw;
+ return (pointer)NULL;
+}
+
+/* We can't replace the LookupWindow and LookupDrawable functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+_X_EXPORT WindowPtr
+LookupWindow(XID rid, ClientPtr client)
+{
+ return SecurityLookupWindow(rid, client, SecurityUnknownAccess);
+}
+
+_X_EXPORT pointer
+LookupDrawable(XID rid, ClientPtr client)
+{
+ return SecurityLookupDrawable(rid, client, SecurityUnknownAccess);
+}
+
+#else /* not XACE */
+
+WindowPtr
+LookupWindow(XID rid, ClientPtr client)
+{
+ WindowPtr pWin;
+
+ client->errorValue = rid;
+ if(rid == INVALID)
+ return NULL;
+ if (client->lastDrawableID == rid)
+ {
+ if (client->lastDrawable->type == DRAWABLE_WINDOW)
+ return ((WindowPtr) client->lastDrawable);
+ return (WindowPtr) NULL;
+ }
+ pWin = (WindowPtr)LookupIDByType(rid, RT_WINDOW);
+ if (pWin && pWin->drawable.type == DRAWABLE_WINDOW) {
+ client->lastDrawable = (DrawablePtr) pWin;
+ client->lastDrawableID = rid;
+ client->lastGCID = INVALID;
+ client->lastGC = (GCPtr)NULL;
+ }
+ return pWin;
+}
+
+
+pointer
+LookupDrawable(XID rid, ClientPtr client)
+{
+ register DrawablePtr pDraw;
+
+ if(rid == INVALID)
+ return (pointer) NULL;
+ if (client->lastDrawableID == rid)
+ return ((pointer) client->lastDrawable);
+ pDraw = (DrawablePtr)LookupIDByClass(rid, RC_DRAWABLE);
+ if (pDraw && (pDraw->type != UNDRAWABLE_WINDOW))
+ return (pointer)pDraw;
+ return (pointer)NULL;
+}
+
+#endif /* XACE */
+
+_X_EXPORT ClientPtr
+LookupClient(XID rid, ClientPtr client)
+{
+ pointer pRes = (pointer)SecurityLookupIDByClass(client, rid, RC_ANY,
+ SecurityReadAccess);
+ int clientIndex = CLIENT_ID(rid);
+
+ if (clientIndex && pRes && clients[clientIndex] && !(rid & SERVER_BIT))
+ {
+ return clients[clientIndex];
+ }
+ return (ClientPtr)NULL;
+}
+
+
+int
+AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode,
+ Bool toRoot, Bool remap)
+{
+ int numnow;
+ SaveSetElt *pTmp = NULL;
+ int j;
+
+ numnow = client->numSaved;
+ j = 0;
+ if (numnow)
+ {
+ pTmp = client->saveSet;
+ while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (pointer)pWin))
+ j++;
+ }
+ if (mode == SetModeInsert)
+ {
+ if (j < numnow) /* duplicate */
+ return(Success);
+ numnow++;
+ pTmp = (SaveSetElt *)xrealloc(client->saveSet, sizeof(*pTmp) * numnow);
+ if (!pTmp)
+ return(BadAlloc);
+ client->saveSet = pTmp;
+ client->numSaved = numnow;
+ SaveSetAssignWindow(client->saveSet[numnow - 1], pWin);
+ SaveSetAssignToRoot(client->saveSet[numnow - 1], toRoot);
+ SaveSetAssignRemap(client->saveSet[numnow - 1], remap);
+ return(Success);
+ }
+ else if ((mode == SetModeDelete) && (j < numnow))
+ {
+ while (j < numnow-1)
+ {
+ pTmp[j] = pTmp[j+1];
+ j++;
+ }
+ numnow--;
+ if (numnow)
+ {
+ pTmp = (SaveSetElt *)xrealloc(client->saveSet, sizeof(*pTmp) * numnow);
+ if (pTmp)
+ client->saveSet = pTmp;
+ }
+ else
+ {
+ xfree(client->saveSet);
+ client->saveSet = (SaveSetElt *)NULL;
+ }
+ client->numSaved = numnow;
+ return(Success);
+ }
+ return(Success);
+}
+
+void
+DeleteWindowFromAnySaveSet(WindowPtr pWin)
+{
+ register int i;
+ register ClientPtr client;
+
+ for (i = 0; i< currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && client->numSaved)
+ (void)AlterSaveSetForClient(client, pWin, SetModeDelete, FALSE, TRUE);
+ }
+}
+
+/* No-op Don't Do Anything : sometimes we need to be able to call a procedure
+ * that doesn't do anything. For example, on screen with only static
+ * colormaps, if someone calls install colormap, it's easier to have a dummy
+ * procedure to call than to check if there's a procedure
+ */
+_X_EXPORT void
+NoopDDA(void)
+{
+}
+
+typedef struct _BlockHandler {
+ BlockHandlerProcPtr BlockHandler;
+ WakeupHandlerProcPtr WakeupHandler;
+ pointer blockData;
+ Bool deleted;
+} BlockHandlerRec, *BlockHandlerPtr;
+
+static BlockHandlerPtr handlers;
+static int numHandlers;
+static int sizeHandlers;
+static Bool inHandler;
+static Bool handlerDeleted;
+
+/**
+ *
+ * \param pTimeout DIX doesn't want to know how OS represents time
+ * \param pReadMask nor how it represents the det of descriptors
+ */
+void
+BlockHandler(pointer pTimeout, pointer pReadmask)
+{
+ register int i, j;
+
+ ++inHandler;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ (* screenInfo.screens[i]->BlockHandler)(i,
+ screenInfo.screens[i]->blockData,
+ pTimeout, pReadmask);
+ for (i = 0; i < numHandlers; i++)
+ (*handlers[i].BlockHandler) (handlers[i].blockData,
+ pTimeout, pReadmask);
+ if (handlerDeleted)
+ {
+ for (i = 0; i < numHandlers;)
+ if (handlers[i].deleted)
+ {
+ for (j = i; j < numHandlers - 1; j++)
+ handlers[j] = handlers[j+1];
+ numHandlers--;
+ }
+ else
+ i++;
+ handlerDeleted = FALSE;
+ }
+ --inHandler;
+}
+
+/**
+ *
+ * \param result 32 bits of undefined result from the wait
+ * \param pReadmask the resulting descriptor mask
+ */
+void
+WakeupHandler(int result, pointer pReadmask)
+{
+ register int i, j;
+
+ ++inHandler;
+ for (i = numHandlers - 1; i >= 0; i--)
+ (*handlers[i].WakeupHandler) (handlers[i].blockData,
+ result, pReadmask);
+ for (i = 0; i < screenInfo.numScreens; i++)
+ (* screenInfo.screens[i]->WakeupHandler)(i,
+ screenInfo.screens[i]->wakeupData,
+ result, pReadmask);
+ if (handlerDeleted)
+ {
+ for (i = 0; i < numHandlers;)
+ if (handlers[i].deleted)
+ {
+ for (j = i; j < numHandlers - 1; j++)
+ handlers[j] = handlers[j+1];
+ numHandlers--;
+ }
+ else
+ i++;
+ handlerDeleted = FALSE;
+ }
+ --inHandler;
+}
+
+/**
+ * Reentrant with BlockHandler and WakeupHandler, except wakeup won't
+ * get called until next time
+ */
+_X_EXPORT Bool
+RegisterBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
+ WakeupHandlerProcPtr wakeupHandler,
+ pointer blockData)
+{
+ BlockHandlerPtr new;
+
+ if (numHandlers >= sizeHandlers)
+ {
+ new = (BlockHandlerPtr) xrealloc (handlers, (numHandlers + 1) *
+ sizeof (BlockHandlerRec));
+ if (!new)
+ return FALSE;
+ handlers = new;
+ sizeHandlers = numHandlers + 1;
+ }
+ handlers[numHandlers].BlockHandler = blockHandler;
+ handlers[numHandlers].WakeupHandler = wakeupHandler;
+ handlers[numHandlers].blockData = blockData;
+ handlers[numHandlers].deleted = FALSE;
+ numHandlers = numHandlers + 1;
+ return TRUE;
+}
+
+_X_EXPORT void
+RemoveBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
+ WakeupHandlerProcPtr wakeupHandler,
+ pointer blockData)
+{
+ int i;
+
+ for (i = 0; i < numHandlers; i++)
+ if (handlers[i].BlockHandler == blockHandler &&
+ handlers[i].WakeupHandler == wakeupHandler &&
+ handlers[i].blockData == blockData)
+ {
+ if (inHandler)
+ {
+ handlerDeleted = TRUE;
+ handlers[i].deleted = TRUE;
+ }
+ else
+ {
+ for (; i < numHandlers - 1; i++)
+ handlers[i] = handlers[i+1];
+ numHandlers--;
+ }
+ break;
+ }
+}
+
+void
+InitBlockAndWakeupHandlers ()
+{
+ xfree (handlers);
+ handlers = (BlockHandlerPtr) 0;
+ numHandlers = 0;
+ sizeHandlers = 0;
+}
+
+/*
+ * A general work queue. Perform some task before the server
+ * sleeps for input.
+ */
+
+WorkQueuePtr workQueue;
+static WorkQueuePtr *workQueueLast = &workQueue;
+
+void
+ProcessWorkQueue(void)
+{
+ WorkQueuePtr q, *p;
+
+ p = &workQueue;
+ /*
+ * Scan the work queue once, calling each function. Those
+ * which return TRUE are removed from the queue, otherwise
+ * they will be called again. This must be reentrant with
+ * QueueWorkProc.
+ */
+ while ((q = *p))
+ {
+ if ((*q->function) (q->client, q->closure))
+ {
+ /* remove q from the list */
+ *p = q->next; /* don't fetch until after func called */
+ xfree (q);
+ }
+ else
+ {
+ p = &q->next; /* don't fetch until after func called */
+ }
+ }
+ workQueueLast = p;
+}
+
+void
+ProcessWorkQueueZombies(void)
+{
+ WorkQueuePtr q, *p;
+
+ p = &workQueue;
+ while ((q = *p))
+ {
+ if (q->client && q->client->clientGone)
+ {
+ (void) (*q->function) (q->client, q->closure);
+ /* remove q from the list */
+ *p = q->next; /* don't fetch until after func called */
+ xfree (q);
+ }
+ else
+ {
+ p = &q->next; /* don't fetch until after func called */
+ }
+ }
+ workQueueLast = p;
+}
+
+_X_EXPORT Bool
+QueueWorkProc (
+ Bool (*function)(ClientPtr /* pClient */, pointer /* closure */),
+ ClientPtr client, pointer closure)
+{
+ WorkQueuePtr q;
+
+ q = (WorkQueuePtr) xalloc (sizeof *q);
+ if (!q)
+ return FALSE;
+ q->function = function;
+ q->client = client;
+ q->closure = closure;
+ q->next = NULL;
+ *workQueueLast = q;
+ workQueueLast = &q->next;
+ return TRUE;
+}
+
+/*
+ * Manage a queue of sleeping clients, awakening them
+ * when requested, by using the OS functions IgnoreClient
+ * and AttendClient. Note that this *ignores* the troubles
+ * with request data interleaving itself with events, but
+ * we'll leave that until a later time.
+ */
+
+typedef struct _SleepQueue {
+ struct _SleepQueue *next;
+ ClientPtr client;
+ ClientSleepProcPtr function;
+ pointer closure;
+} SleepQueueRec, *SleepQueuePtr;
+
+static SleepQueuePtr sleepQueue = NULL;
+
+_X_EXPORT Bool
+ClientSleep (ClientPtr client, ClientSleepProcPtr function, pointer closure)
+{
+ SleepQueuePtr q;
+
+ q = (SleepQueuePtr) xalloc (sizeof *q);
+ if (!q)
+ return FALSE;
+
+ IgnoreClient (client);
+ q->next = sleepQueue;
+ q->client = client;
+ q->function = function;
+ q->closure = closure;
+ sleepQueue = q;
+ return TRUE;
+}
+
+Bool
+ClientSignal (ClientPtr client)
+{
+ SleepQueuePtr q;
+
+ for (q = sleepQueue; q; q = q->next)
+ if (q->client == client)
+ {
+ return QueueWorkProc (q->function, q->client, q->closure);
+ }
+ return FALSE;
+}
+
+_X_EXPORT void
+ClientWakeup (ClientPtr client)
+{
+ SleepQueuePtr q, *prev;
+
+ prev = &sleepQueue;
+ while ( (q = *prev) )
+ {
+ if (q->client == client)
+ {
+ *prev = q->next;
+ xfree (q);
+ if (client->clientGone)
+ /* Oops -- new zombie cleanup code ensures this only
+ * happens from inside CloseDownClient; don't want to
+ * recurse here...
+ */
+ /* CloseDownClient(client) */;
+ else
+ AttendClient (client);
+ break;
+ }
+ prev = &q->next;
+ }
+}
+
+Bool
+ClientIsAsleep (ClientPtr client)
+{
+ SleepQueuePtr q;
+
+ for (q = sleepQueue; q; q = q->next)
+ if (q->client == client)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Generic Callback Manager
+ */
+
+/* ===== Private Procedures ===== */
+
+static int numCallbackListsToCleanup = 0;
+static CallbackListPtr **listsToCleanup = NULL;
+
+static Bool
+_AddCallback(
+ CallbackListPtr *pcbl,
+ CallbackProcPtr callback,
+ pointer data)
+{
+ CallbackPtr cbr;
+
+ cbr = (CallbackPtr) xalloc(sizeof(CallbackRec));
+ if (!cbr)
+ return FALSE;
+ cbr->proc = callback;
+ cbr->data = data;
+ cbr->next = (*pcbl)->list;
+ cbr->deleted = FALSE;
+ (*pcbl)->list = cbr;
+ return TRUE;
+}
+
+static Bool
+_DeleteCallback(
+ CallbackListPtr *pcbl,
+ CallbackProcPtr callback,
+ pointer data)
+{
+ CallbackListPtr cbl = *pcbl;
+ CallbackPtr cbr, pcbr;
+
+ for (pcbr = NULL, cbr = cbl->list;
+ cbr != NULL;
+ pcbr = cbr, cbr = cbr->next)
+ {
+ if ((cbr->proc == callback) && (cbr->data == data))
+ break;
+ }
+ if (cbr != NULL)
+ {
+ if (cbl->inCallback)
+ {
+ ++(cbl->numDeleted);
+ cbr->deleted = TRUE;
+ }
+ else
+ {
+ if (pcbr == NULL)
+ cbl->list = cbr->next;
+ else
+ pcbr->next = cbr->next;
+ xfree(cbr);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+_CallCallbacks(
+ CallbackListPtr *pcbl,
+ pointer call_data)
+{
+ CallbackListPtr cbl = *pcbl;
+ CallbackPtr cbr, pcbr;
+
+ ++(cbl->inCallback);
+ for (cbr = cbl->list; cbr != NULL; cbr = cbr->next)
+ {
+ (*(cbr->proc)) (pcbl, cbr->data, call_data);
+ }
+ --(cbl->inCallback);
+
+ if (cbl->inCallback) return;
+
+ /* Was the entire list marked for deletion? */
+
+ if (cbl->deleted)
+ {
+ DeleteCallbackList(pcbl);
+ return;
+ }
+
+ /* Were some individual callbacks on the list marked for deletion?
+ * If so, do the deletions.
+ */
+
+ if (cbl->numDeleted)
+ {
+ for (pcbr = NULL, cbr = cbl->list; (cbr != NULL) && cbl->numDeleted; )
+ {
+ if (cbr->deleted)
+ {
+ if (pcbr)
+ {
+ cbr = cbr->next;
+ xfree(pcbr->next);
+ pcbr->next = cbr;
+ } else
+ {
+ cbr = cbr->next;
+ xfree(cbl->list);
+ cbl->list = cbr;
+ }
+ cbl->numDeleted--;
+ }
+ else /* this one wasn't deleted */
+ {
+ pcbr = cbr;
+ cbr = cbr->next;
+ }
+ }
+ }
+}
+
+static void
+_DeleteCallbackList(
+ CallbackListPtr *pcbl)
+{
+ CallbackListPtr cbl = *pcbl;
+ CallbackPtr cbr, nextcbr;
+ int i;
+
+ if (cbl->inCallback)
+ {
+ cbl->deleted = TRUE;
+ return;
+ }
+
+ for (i = 0; i < numCallbackListsToCleanup; i++)
+ {
+ if ((listsToCleanup[i] = pcbl) != 0)
+ {
+ listsToCleanup[i] = NULL;
+ break;
+ }
+ }
+
+ for (cbr = cbl->list; cbr != NULL; cbr = nextcbr)
+ {
+ nextcbr = cbr->next;
+ xfree(cbr);
+ }
+ xfree(cbl);
+ *pcbl = NULL;
+}
+
+static CallbackFuncsRec default_cbfuncs =
+{
+ _AddCallback,
+ _DeleteCallback,
+ _CallCallbacks,
+ _DeleteCallbackList
+};
+
+/* ===== Public Procedures ===== */
+
+Bool
+CreateCallbackList(CallbackListPtr *pcbl, CallbackFuncsPtr cbfuncs)
+{
+ CallbackListPtr cbl;
+ int i;
+
+ if (!pcbl) return FALSE;
+ cbl = (CallbackListPtr) xalloc(sizeof(CallbackListRec));
+ if (!cbl) return FALSE;
+ cbl->funcs = cbfuncs ? *cbfuncs : default_cbfuncs;
+ cbl->inCallback = 0;
+ cbl->deleted = FALSE;
+ cbl->numDeleted = 0;
+ cbl->list = NULL;
+ *pcbl = cbl;
+
+ for (i = 0; i < numCallbackListsToCleanup; i++)
+ {
+ if (!listsToCleanup[i])
+ {
+ listsToCleanup[i] = pcbl;
+ return TRUE;
+ }
+ }
+
+ listsToCleanup = (CallbackListPtr **)xnfrealloc(listsToCleanup,
+ sizeof(CallbackListPtr *) * (numCallbackListsToCleanup+1));
+ listsToCleanup[numCallbackListsToCleanup] = pcbl;
+ numCallbackListsToCleanup++;
+ return TRUE;
+}
+
+_X_EXPORT Bool
+AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
+{
+ if (!pcbl) return FALSE;
+ if (!*pcbl)
+ { /* list hasn't been created yet; go create it */
+ if (!CreateCallbackList(pcbl, (CallbackFuncsPtr)NULL))
+ return FALSE;
+ }
+ return ((*(*pcbl)->funcs.AddCallback) (pcbl, callback, data));
+}
+
+_X_EXPORT Bool
+DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
+{
+ if (!pcbl || !*pcbl) return FALSE;
+ return ((*(*pcbl)->funcs.DeleteCallback) (pcbl, callback, data));
+}
+
+void
+CallCallbacks(CallbackListPtr *pcbl, pointer call_data)
+{
+ if (!pcbl || !*pcbl) return;
+ (*(*pcbl)->funcs.CallCallbacks) (pcbl, call_data);
+}
+
+void
+DeleteCallbackList(CallbackListPtr *pcbl)
+{
+ if (!pcbl || !*pcbl) return;
+ (*(*pcbl)->funcs.DeleteCallbackList) (pcbl);
+}
+
+void
+InitCallbackManager()
+{
+ int i;
+
+ for (i = 0; i < numCallbackListsToCleanup; i++)
+ {
+ DeleteCallbackList(listsToCleanup[i]);
+ }
+ if (listsToCleanup) xfree(listsToCleanup);
+
+ numCallbackListsToCleanup = 0;
+ listsToCleanup = NULL;
+}
diff --git a/xserver/dix/events.c b/xserver/dix/events.c
new file mode 100644
index 000000000..c57a30ed8
--- /dev/null
+++ b/xserver/dix/events.c
@@ -0,0 +1,4599 @@
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+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.
+
+The above copyright notice and this permission notice 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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, 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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XACE
+#include "xace.h"
+#endif
+
+#ifdef XEVIE
+extern WindowPtr *WindowTable;
+extern int xevieFlag;
+extern int xevieClientIndex;
+extern DeviceIntPtr xeviemouse;
+extern DeviceIntPtr xeviekb;
+extern Mask xevieMask;
+extern Mask xevieFilters[128];
+extern int xevieEventSent;
+extern int xevieKBEventSent;
+int xeviegrabState = 0;
+xEvent *xeviexE;
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "dispatch.h"
+
+#define EXTENSION_EVENT_BASE 64
+
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+ PointerMotionMask | Button1MotionMask | \
+ Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+ Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+ MotionMask )
+#define PointerGrabMask ( \
+ ButtonPressMask | ButtonReleaseMask | \
+ EnterWindowMask | LeaveWindowMask | \
+ PointerMotionHintMask | KeymapStateMask | \
+ MotionMask )
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+ (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+_X_EXPORT CallbackListPtr EventCallback;
+_X_EXPORT CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+_X_EXPORT InputInfo inputInfo;
+
+static struct {
+ QdEventPtr pending, *pendtail;
+ DeviceIntPtr replayDev; /* kludgy rock to put flag for */
+ WindowPtr replayWin; /* ComputeFreezes */
+ Bool playingEvents;
+ TimeStamp time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static struct {
+ CursorPtr current;
+ BoxRec hotLimits; /* logical constraints of hot spot */
+ Bool confined; /* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+ RegionPtr hotShape; /* additional logical shape constraint */
+#endif
+ BoxRec physLimits; /* physical constraints of hot spot */
+ WindowPtr win; /* window of logical position */
+ HotSpot hot; /* logical pointer position */
+ HotSpot hotPhys; /* physical pointer position */
+#ifdef PANORAMIX
+ ScreenPtr screen; /* all others are in Screen 0 coordinates */
+ RegionRec Reg1; /* Region 1 for confining motion */
+ RegionRec Reg2; /* Region 2 for confining virtual motion */
+ WindowPtr windows[MAXSCREENS];
+ WindowPtr confineWin; /* confine window */
+#endif
+} sprite; /* info about the cursor sprite */
+
+#ifdef XEVIE
+_X_EXPORT WindowPtr xeviewin;
+_X_EXPORT HotSpot xeviehot;
+#endif
+
+static void DoEnterLeaveEvents(
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode
+);
+
+static WindowPtr XYToWindow(
+ int x,
+ int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+ EnterWindowMask, /* EnterNotify */
+ LeaveWindowMask, /* LeaveNotify */
+ FocusChangeMask, /* FocusIn */
+ FocusChangeMask, /* FocusOut */
+ KeymapStateMask, /* KeymapNotify */
+ ExposureMask, /* Expose */
+ CantBeFiltered, /* GraphicsExpose */
+ CantBeFiltered, /* NoExpose */
+ VisibilityChangeMask, /* VisibilityNotify */
+ SubstructureNotifyMask, /* CreateNotify */
+ StructureAndSubMask, /* DestroyNotify */
+ StructureAndSubMask, /* UnmapNotify */
+ StructureAndSubMask, /* MapNotify */
+ SubstructureRedirectMask, /* MapRequest */
+ StructureAndSubMask, /* ReparentNotify */
+ StructureAndSubMask, /* ConfigureNotify */
+ SubstructureRedirectMask, /* ConfigureRequest */
+ StructureAndSubMask, /* GravityNotify */
+ ResizeRedirectMask, /* ResizeRequest */
+ StructureAndSubMask, /* CirculateNotify */
+ SubstructureRedirectMask, /* CirculateRequest */
+ PropertyChangeMask, /* PropertyNotify */
+ CantBeFiltered, /* SelectionClear */
+ CantBeFiltered, /* SelectionRequest */
+ CantBeFiltered, /* SelectionNotify */
+ ColormapChangeMask, /* ColormapNotify */
+ CantBeFiltered, /* ClientMessage */
+ CantBeFiltered /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+ 0x7c /* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+ int x,
+ int y,
+ Bool generateEvent
+){
+ ScreenPtr pScreen;
+ BoxRec box;
+ int i;
+
+ /* x,y are in Screen 0 coordinates. We need to decide what Screen
+ to send the message too and what the coordinates relative to
+ that screen are. */
+
+ pScreen = sprite.screen;
+ x += panoramiXdataPtr[0].x;
+ y += panoramiXdataPtr[0].y;
+
+ if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+ x, y, &box))
+ {
+ FOR_NSCREENS(i)
+ {
+ if(i == pScreen->myNum)
+ continue;
+ if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+ {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+
+ sprite.screen = pScreen;
+ sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+ sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+ x -= panoramiXdataPtr[pScreen->myNum].x;
+ y -= panoramiXdataPtr[pScreen->myNum].y;
+
+ return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+ ScreenPtr pScreen = sprite.screen;
+ BoxRec newBox = sprite.physLimits;
+
+ /* Translate the constraining box to the screen
+ the sprite is actually on */
+ newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+ newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+ (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents
+){
+ HotSpot new;
+
+ if (!cursor)
+ return;
+
+ new = sprite.hotPhys;
+
+ /* I don't care what the DDX has to say about it */
+ sprite.physLimits = sprite.hotLimits;
+
+ /* constrain the pointer to those limits */
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape) /* more work if the shape is a mess */
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+ if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ XineramaSetCursorPosition (new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+
+ /* Tell DDX what the limits are */
+ XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+ if(pWin == WindowTable[0]) {
+ memcpy(sprite.windows, WindowTable,
+ PanoramiXNumScreens*sizeof(WindowPtr));
+ } else {
+ PanoramiXRes *win;
+ int i;
+
+ win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+ if(!win)
+ return FALSE;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+ if(!sprite.windows[i]) /* window is being unmapped */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+ QdEventPtr qe,
+ WindowPtr pWin
+){
+
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ int x, y, off_x, off_y, i;
+ BoxRec lims;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+ if (sprite.hot.x < lims.x1)
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+ sprite.hot.y = lims.y2 - 1;
+
+ if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
+ ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+#ifdef XEVIE
+ xeviehot.x = sprite.hot.x;
+ xeviehot.y = sprite.hot.y;
+#endif
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ /* Motion events entering DIX get translated to Screen 0
+ coordinates. Replayed events have already been
+ translated since they've entered DIX before */
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ sprite.hot.x = XE_KBPTR.rootX;
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ XineramaSetCursorPosition(
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviehot.x = sprite.hot.x;
+ xeviehot.y = sprite.hot.y;
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+ if (syncEvents.playingEvents)
+ {
+ XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ int x, y, off_x, off_y, i;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+ if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+ sprite.hotShape = &sprite.Reg1;
+ else
+ sprite.hotShape = NullRegion;
+
+ sprite.confined = FALSE;
+ sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+ XineramaCheckPhysLimits(sprite.current, generateEvents);
+ }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ XineramaCheckPhysLimits(cursor, FALSE);
+ (*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+
+#endif /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+ if ((event < LASTEvent) || (event >= 128))
+ FatalError("SetMaskForEvent: bogus event number");
+ filters[event] = mask;
+}
+
+_X_EXPORT void
+SetCriticalEvent(int event)
+{
+ if (event >= 128)
+ FatalError("SetCriticalEvent: bogus event number");
+ criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+ xEvent xE;
+
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+ y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+ if (syncEvents.playingEvents)
+ xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+ else
+ xE.u.keyButtonPointer.time = currentTime.milliseconds;
+ xE.u.u.type = MotionNotify;
+ (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+ BoxRec box;
+ int x = *px, y = *py;
+ int incx = 1, incy = 1;
+
+ if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+ return;
+ box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+ /* this is rather crude */
+ do {
+ x += incx;
+ if (x >= box.x2)
+ {
+ incx = -1;
+ x = *px - 1;
+ }
+ else if (x < box.x1)
+ {
+ incx = 1;
+ x = *px;
+ y += incy;
+ if (y >= box.y2)
+ {
+ incy = -1;
+ y = *py - 1;
+ }
+ else if (y < box.y1)
+ return; /* should never get here! */
+ }
+ } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+ *px = x;
+ *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents,
+ Bool confineToScreen,
+ ScreenPtr pScreen)
+{
+ HotSpot new;
+
+ if (!cursor)
+ return;
+ new = sprite.hotPhys;
+ if (pScreen)
+ new.pScreen = pScreen;
+ else
+ pScreen = new.pScreen;
+ (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+ &sprite.physLimits);
+ sprite.confined = confineToScreen;
+ (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+#endif
+ if ((pScreen != sprite.hotPhys.pScreen) ||
+ (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ if (pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys = new;
+ (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+}
+
+static void
+CheckVirtualMotion(
+ register QdEventPtr qe,
+ register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaCheckVirtualMotion(qe, pWin);
+ return;
+ }
+#endif
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen;
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ BoxRec lims;
+
+ if (sprite.hot.pScreen != pWin->drawable.pScreen)
+ {
+ sprite.hot.pScreen = pWin->drawable.pScreen;
+ sprite.hot.x = sprite.hot.y = 0;
+ }
+ lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+ if (sprite.hot.x < lims.x1)
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+ sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+ if (wBoundingShape(pWin))
+ ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+#ifdef XEVIE
+ xeviehot.x = sprite.hot.x;
+ xeviehot.y = sprite.hot.y;
+#endif
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaConfineCursorToWindow(pWin, generateEvents);
+ return;
+ }
+#endif
+
+ if (syncEvents.playingEvents)
+ {
+ CheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+ : NullRegion;
+#endif
+ CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+ pScreen);
+ }
+}
+
+_X_EXPORT Bool
+PointerConfinedToScreen()
+{
+ return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaChangeToCursor(cursor);
+ return;
+ }
+#endif
+
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ CheckPhysLimits(cursor, FALSE, sprite.confined,
+ (ScreenPtr)NULL);
+ (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+ cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (b == a) return TRUE;
+ return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+ register WindowPtr win;
+ register GrabPtr grab = inputInfo.pointer->grab;
+
+ if (syncEvents.playingEvents)
+ return;
+ if (grab)
+ {
+ if (grab->cursor)
+ {
+ ChangeToCursor(grab->cursor);
+ return;
+ }
+ if (IsParent(grab->window, sprite.win))
+ win = sprite.win;
+ else
+ win = grab->window;
+ }
+ else
+ win = sprite.win;
+ for (; win; win = win->parent)
+ if (win->optional && win->optional->cursor != NullCursor)
+ {
+ ChangeToCursor(win->optional->cursor);
+ return;
+ }
+}
+
+_X_EXPORT WindowPtr
+GetCurrentRootWindow()
+{
+ return ROOT;
+}
+
+_X_EXPORT WindowPtr
+GetSpriteWindow()
+{
+ return sprite.win;
+}
+
+_X_EXPORT CursorPtr
+GetSpriteCursor()
+{
+ return sprite.current;
+}
+
+_X_EXPORT void
+GetSpritePosition(int *px, int *py)
+{
+ *px = sprite.hotPhys.x;
+ *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+_X_EXPORT int
+XineramaGetCursorScreen()
+{
+ if(!noPanoramiXExtension) {
+ return sprite.screen->myNum;
+ } else {
+ return 0;
+ }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+ /* If the ddx/OS is careless about not processing timestamped events from
+ * different sources in sorted order, then it's possible for time to go
+ * backwards when it should not. Here we ensure a decent time.
+ */
+ if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+ currentTime.months++;
+ else
+ XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+ if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+ MonthChangedOrBadTime(xE); \
+ currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+ lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE);
+}
+
+/**************************************************************************
+ * The following procedures deal with synchronous events *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+ register QdEventPtr tail = *syncEvents.pendtail;
+ register QdEventPtr qe;
+ xEvent *qxE;
+
+ NoticeTime(xE);
+
+#ifdef XKB
+ /* Fix for key repeating bug. */
+ if (device->key != NULL && device->key->xkbInfo != NULL &&
+ xE->u.u.type == KeyRelease)
+ AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* The RECORD spec says that the root window field of motion events
+ * must be valid. At this point, it hasn't been filled in yet, so
+ * we do it here. The long expression below is necessary to get
+ * the current root window; the apparently reasonable alternative
+ * GetCurrentRootWindow()->drawable.id doesn't give you the right
+ * answer on the first motion event after a screen change because
+ * the data that GetCurrentRootWindow relies on hasn't been
+ * updated yet.
+ */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ if (xE->u.u.type == MotionNotify)
+ {
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ }
+#endif
+ sprite.hotPhys.x = XE_KBPTR.rootX;
+ sprite.hotPhys.y = XE_KBPTR.rootY;
+ /* do motion compression */
+ if (tail &&
+ (tail->event->u.u.type == MotionNotify) &&
+ (tail->pScreen == sprite.hotPhys.pScreen))
+ {
+ tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+ tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+ tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+ tail->months = currentTime.months;
+ return;
+ }
+ }
+ qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+ if (!qe)
+ return;
+ qe->next = (QdEventPtr)NULL;
+ qe->device = device;
+ qe->pScreen = sprite.hotPhys.pScreen;
+ qe->months = currentTime.months;
+ qe->event = (xEvent *)(qe + 1);
+ qe->evcount = count;
+ for (qxE = qe->event; --count >= 0; qxE++, xE++)
+ *qxE = *xE;
+ if (tail)
+ syncEvents.pendtail = &tail->next;
+ *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+ register QdEventPtr *prev, qe;
+ register DeviceIntPtr dev;
+
+ prev = &syncEvents.pending;
+ while ( (qe = *prev) )
+ {
+ if (!qe->device->sync.frozen)
+ {
+ *prev = qe->next;
+ if (*syncEvents.pendtail == *prev)
+ syncEvents.pendtail = prev;
+ if (qe->event->u.u.type == MotionNotify)
+ CheckVirtualMotion(qe, NullWindow);
+ syncEvents.time.months = qe->months;
+ syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ qe->event->u.keyButtonPointer.rootX +=
+ panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x;
+ qe->event->u.keyButtonPointer.rootY +=
+ panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ (*qe->device->public.processInputProc)(qe->event, qe->device,
+ qe->evcount);
+ xfree(qe);
+ for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+ ;
+ if (!dev)
+ break;
+ /* Playing the event may have unfrozen another device. */
+ /* So to play it safe, restart at the head of the queue */
+ prev = &syncEvents.pending;
+ }
+ else
+ prev = &qe->next;
+ }
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+ dev->sync.frozen = frozen;
+ if (frozen)
+ dev->public.processInputProc = dev->public.enqueueInputProc;
+ else
+ dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+ register DeviceIntPtr replayDev = syncEvents.replayDev;
+ register int i;
+ WindowPtr w;
+ register xEvent *xE;
+ int count;
+ GrabPtr grab;
+ register DeviceIntPtr dev;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+ if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+ return;
+ syncEvents.playingEvents = TRUE;
+ if (replayDev)
+ {
+ xE = replayDev->sync.event;
+ count = replayDev->sync.evcount;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+ w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+ for (i = 0; i < spriteTraceGood; i++)
+ {
+ if (syncEvents.replayWin == spriteTrace[i])
+ {
+ if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+ replayDev, count);
+ }
+ goto playmore;
+ }
+ }
+ /* must not still be in the same stack */
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+ }
+playmore:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!dev->sync.frozen)
+ {
+ PlayReleasedEvents();
+ break;
+ }
+ }
+ syncEvents.playingEvents = FALSE;
+ /* the following may have been skipped during replay, so do it now */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+ PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+ GrabPtr grab;
+
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+ register GrabPtr grab = thisDev->grab;
+ register DeviceIntPtr dev;
+
+ if (thisMode == GrabModeSync)
+ thisDev->sync.state = FROZEN_NO_EVENT;
+ else
+ { /* free both if same client owns both */
+ thisDev->sync.state = THAWED;
+ if (thisDev->sync.other &&
+ (CLIENT_BITS(thisDev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ thisDev->sync.other = NullGrab;
+ }
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev != thisDev)
+ {
+ if (otherMode == GrabModeSync)
+ dev->sync.other = grab;
+ else
+ { /* free both if same client owns both */
+ if (dev->sync.other &&
+ (CLIENT_BITS(dev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ dev->sync.other = NullGrab;
+ }
+ }
+ }
+ ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
+ TimeStamp time, Bool autoGrab)
+{
+ WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+ : sprite.win;
+
+ if (grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+ }
+ DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (syncEvents.playingEvents)
+ mouse->grabTime = syncEvents.time;
+ else
+ mouse->grabTime = time;
+ if (grab->cursor)
+ grab->cursor->refcnt++;
+ mouse->activeGrab = *grab;
+ mouse->grab = &mouse->activeGrab;
+ mouse->fromPassiveGrab = autoGrab;
+ PostNewCursor();
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+ register GrabPtr grab = mouse->grab;
+ register DeviceIntPtr dev;
+
+ mouse->valuator->motionHintWindow = NullWindow;
+ mouse->grab = NullGrab;
+ mouse->sync.state = NOT_GRABBED;
+ mouse->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+ if (grab->confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ PostNewCursor();
+ if (grab->cursor)
+ FreeCursor(grab->cursor, (Cursor)0);
+ ComputeFreezes();
+}
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+ WindowPtr oldWin;
+
+ if (keybd->grab)
+ oldWin = keybd->grab->window;
+ else if (keybd->focus)
+ oldWin = keybd->focus->win;
+ else
+ oldWin = sprite.win;
+ if (oldWin == FollowKeyboardWin)
+ oldWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+ if (syncEvents.playingEvents)
+ keybd->grabTime = syncEvents.time;
+ else
+ keybd->grabTime = time;
+ keybd->activeGrab = *grab;
+ keybd->grab = &keybd->activeGrab;
+ keybd->fromPassiveGrab = passive;
+ CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+ register GrabPtr grab = keybd->grab;
+ register DeviceIntPtr dev;
+ register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+ : sprite.win;
+
+ if (focusWin == FollowKeyboardWin)
+ focusWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ keybd->grab = NullGrab;
+ keybd->sync.state = NOT_GRABBED;
+ keybd->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+ ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+ Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+ TimeStamp grabTime;
+ register DeviceIntPtr dev;
+
+ thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+ thisSynced = FALSE;
+ otherGrabbed = FALSE;
+ othersFrozen = TRUE;
+ grabTime = thisDev->grabTime;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ if (!(thisGrabbed || otherGrabbed) ||
+ (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+ grabTime = dev->grabTime;
+ otherGrabbed = TRUE;
+ if (thisDev->sync.other == dev->grab)
+ thisSynced = TRUE;
+ if (dev->sync.state < FROZEN)
+ othersFrozen = FALSE;
+ }
+ else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+ othersFrozen = FALSE;
+ }
+ if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+ return;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, grabTime) == EARLIER))
+ return;
+ switch (newState)
+ {
+ case THAWED: /* Async */
+ if (thisGrabbed)
+ thisDev->sync.state = THAWED;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ break;
+ case FREEZE_NEXT_EVENT: /* Sync */
+ if (thisGrabbed)
+ {
+ thisDev->sync.state = FREEZE_NEXT_EVENT;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ }
+ break;
+ case THAWED_BOTH: /* AsyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case NOT_GRABBED: /* Replay */
+ if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+ {
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ syncEvents.replayDev = thisDev;
+ syncEvents.replayWin = thisDev->grab->window;
+ (*thisDev->DeactivateGrab)(thisDev);
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ }
+ break;
+ case THAW_OTHERS: /* AsyncOthers */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+ TimeStamp time;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ REQUEST(xAllowEventsReq);
+
+ REQUEST_SIZE_MATCH(xAllowEventsReq);
+ time = ClientTimeToServerTime(stuff->time);
+ switch (stuff->mode)
+ {
+ case ReplayPointer:
+ AllowSome(client, time, mouse, NOT_GRABBED);
+ break;
+ case SyncPointer:
+ AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncPointer:
+ AllowSome(client, time, mouse, THAWED);
+ break;
+ case ReplayKeyboard:
+ AllowSome(client, time, keybd, NOT_GRABBED);
+ break;
+ case SyncKeyboard:
+ AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncKeyboard:
+ AllowSome(client, time, keybd, THAWED);
+ break;
+ case SyncBoth:
+ AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case AsyncBoth:
+ AllowSome(client, time, keybd, THAWED_BOTH);
+ break;
+ default:
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+ register DeviceIntPtr dev;
+ Bool done;
+
+ /* XXX CloseDownClient should remove passive grabs before
+ * releasing active grabs.
+ */
+ do {
+ done = TRUE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ (*dev->DeactivateGrab)(dev);
+ done = FALSE;
+ }
+ }
+ } while (!done);
+}
+
+/**************************************************************************
+ * The following procedures deal with delivering events *
+ **************************************************************************/
+
+_X_EXPORT int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
+ Mask filter, GrabPtr grab)
+{
+ int i;
+ int type;
+
+#ifdef DEBUG
+ if (debug_events) ErrorF(
+ "Event([%d, %d], mask=0x%x), client=%d",
+ pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client))
+ return -1; /* don't send, but notify caller */
+ type = pEvents->u.u.type;
+ if (type == MotionNotify)
+ {
+ if (mask & PointerMotionHintMask)
+ {
+ if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+ pEvents->u.keyButtonPointer.event)
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+ fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->u.u.detail = NotifyHint;
+ }
+ else
+ {
+ pEvents->u.u.detail = NotifyNormal;
+ }
+ }
+#ifdef XINPUT
+ else
+ {
+ if ((type == DeviceMotionNotify) &&
+ MaybeSendDeviceMotionNotifyHint
+ ((deviceKeyButtonPointer*)pEvents, mask) != 0)
+ return 1;
+ }
+#endif
+ type &= 0177;
+ if (type != KeymapNotify)
+ {
+ /* all extension events must have a sequence number */
+ for (i = 0; i < count; i++)
+ pEvents[i].u.u.sequenceNumber = client->sequence;
+ }
+
+ if (BitIsOn(criticalEvents, type))
+ {
+#ifdef SMART_SCHEDULE
+ if (client->smart_priority < SMART_MAX_PRIORITY)
+ client->smart_priority++;
+#endif
+ SetCriticalOutputPending();
+ }
+
+ WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+ if (debug_events) ErrorF( " delivered\n");
+#endif
+ return 1;
+ }
+ else
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+#endif
+ return 0;
+ }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
+ Mask filter, GrabPtr grab, int mskidx)
+{
+ int deliveries = 0, nondeliveries = 0;
+ int attempt;
+ register InputClients *other;
+ ClientPtr client = NullClient;
+ Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+ this mask is the mask of the grab. */
+ int type = pEvents->u.u.type;
+
+ /* CantBeFiltered means only window owner gets the event */
+ if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+ {
+ /* if nobody ever wants to see this event, skip some work */
+ if (filter != CantBeFiltered &&
+ !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+ return 0;
+ if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = wClient(pWin);
+ deliveryMask = pWin->eventMask;
+ } else
+ nondeliveries--;
+ }
+ }
+ if (filter != CantBeFiltered)
+ {
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ OtherInputMasks *inputMasks;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[mskidx] & filter))
+ return 0;
+ other = inputMasks->inputClients;
+ }
+ else
+ other = (InputClients *)wOtherClients(pWin);
+ for (; other; other = other->next)
+ {
+ if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+ other->mask[mskidx], filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = rClient(other);
+ deliveryMask = other->mask[mskidx];
+ } else
+ nondeliveries--;
+ }
+ }
+ }
+ if ((type == ButtonPress) && deliveries && (!grab))
+ {
+ GrabRec tempGrab;
+
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+ currentTime, TRUE);
+ }
+ else if ((type == MotionNotify) && deliveries)
+ inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+ else
+ {
+ if (((type == DeviceMotionNotify)
+#ifdef XKB
+ || (type == DeviceButtonPress)
+#endif
+ ) && deliveries)
+ CheckDeviceGrabAndHintWindow (pWin, type,
+ (deviceKeyButtonPointer*) pEvents,
+ grab, client, deliveryMask);
+ }
+#endif
+ if (deliveries)
+ return deliveries;
+ return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0. if
+ send works, return 1 or if send didn't work, return 2.
+ Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int
+XineramaTryClientEventsResult(
+ ClientPtr client,
+ GrabPtr grab,
+ Mask mask,
+ Mask filter
+){
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client)) return -1;
+ else return 1;
+ }
+ return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents,
+ int count, Mask filter, ClientPtr dontClient)
+{
+ register OtherClients *other;
+
+
+ if (pWin->eventMask & filter)
+ {
+ if (wClient(pWin) == dontClient)
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+ return TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, NullGrab);
+ }
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & filter)
+ {
+ if (SameClient(other, dontClient))
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ rClient(other), NullGrab, other->mask, filter);
+#endif
+ return TryClientEvents(rClient(other), pEvents, count,
+ other->mask, filter, NullGrab);
+ }
+ }
+ return 2;
+}
+
+static void
+FixUpEventFromWindow(
+ xEvent *xE,
+ WindowPtr pWin,
+ Window child,
+ Bool calcChild)
+{
+ if (calcChild)
+ {
+ WindowPtr w=spriteTrace[spriteTraceGood-1];
+ /* If the search ends up past the root should the child field be
+ set to none or should the value in the argument be passed
+ through. It probably doesn't matter since everyone calls
+ this function with child == None anyway. */
+
+ while (w)
+ {
+ /* If the source window is same as event window, child should be
+ none. Don't bother going all all the way back to the root. */
+
+ if (w == pWin)
+ {
+ child = None;
+ break;
+ }
+
+ if (w->parent == pWin)
+ {
+ child = w->drawable.id;
+ break;
+ }
+ w = w->parent;
+ }
+ }
+ XE_KBPTR.root = ROOT->drawable.id;
+ XE_KBPTR.event = pWin->drawable.id;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ XE_KBPTR.sameScreen = xTrue;
+ XE_KBPTR.child = child;
+ XE_KBPTR.eventX =
+ XE_KBPTR.rootX - pWin->drawable.x;
+ XE_KBPTR.eventY =
+ XE_KBPTR.rootY - pWin->drawable.y;
+ }
+ else
+ {
+ XE_KBPTR.sameScreen = xFalse;
+ XE_KBPTR.child = None;
+ XE_KBPTR.eventX = 0;
+ XE_KBPTR.eventY = 0;
+ }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab,
+ register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+ Window child = None;
+ int type = xE->u.u.type;
+ Mask filter = filters[type];
+ int deliveries = 0;
+
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ register OtherInputMasks *inputMasks;
+ int mskidx = dev->id;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+ return 0;
+ while (pWin)
+ {
+ if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, mskidx);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (inputMasks &&
+ (filter & inputMasks->dontPropagateMask[mskidx])))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ if (pWin)
+ inputMasks = wOtherInputMasks(pWin);
+ }
+ }
+ else
+ {
+ if (!(filter & pWin->deliverableEvents))
+ return 0;
+ while (pWin)
+ {
+ if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, 0);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (filter & wDontPropagateMask(pWin)))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ }
+ }
+ return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+_X_EXPORT int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count,
+ register WindowPtr otherParent)
+{
+ Mask filter;
+ int deliveries;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return count;
+#endif
+
+ if (!count)
+ return 0;
+ filter = filters[xE->u.u.type];
+ if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+ xE->u.destroyNotify.event = pWin->drawable.id;
+ if (filter != StructureAndSubMask)
+ return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+ NullGrab, 0);
+ if (pWin->parent)
+ {
+ xE->u.destroyNotify.event = pWin->parent->drawable.id;
+ deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+ SubstructureNotifyMask, NullGrab,
+ 0);
+ if (xE->u.u.type == ReparentNotify)
+ {
+ xE->u.destroyNotify.event = otherParent->drawable.id;
+ deliveries += DeliverEventsToWindow(otherParent, xE, count,
+ SubstructureNotifyMask,
+ NullGrab, 0);
+ }
+ }
+ return deliveries;
+}
+
+
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(POINT_IN_REGION(sprite.screen,
+ &sprite.windows[i]->borderSize,
+ x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
+ y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
+ &box))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+static WindowPtr
+XYToWindow(int x, int y)
+{
+ register WindowPtr pWin;
+ BoxRec box;
+
+ spriteTraceGood = 1; /* root window still there */
+ pWin = ROOT->firstChild;
+ while (pWin)
+ {
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth(pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ if (spriteTraceGood >= spriteTraceSize)
+ {
+ spriteTraceSize += 10;
+ Must_have_memory = TRUE; /* XXX */
+ spriteTrace = (WindowPtr *)xrealloc(
+ spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ spriteTrace[spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaCheckMotion(xE);
+#endif
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+ {
+ sprite.hot.pScreen = sprite.hotPhys.pScreen;
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+ }
+ sprite.hot.x = XE_KBPTR.rootX;
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+#ifdef XEVIE
+ xeviehot.x = sprite.hot.x;
+ xeviehot.y = sprite.hot.y;
+#endif
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ (*sprite.hotPhys.pScreen->SetCursorPosition)(
+ sprite.hotPhys.pScreen,
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+ if (!(sprite.win->deliverableEvents &
+ Motion_Filter(inputInfo.pointer->button))
+ !syncEvents.playingEvents)
+ {
+ /* XXX Do PointerNonInterestBox here */
+ }
+#endif
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+_X_EXPORT void
+WindowsRestructured()
+{
+ (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx. The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+ GrabPtr grab;
+
+ if (noPanoramiXExtension) return;
+
+ sprite.hot.x -= xoff;
+ sprite.hot.y -= yoff;
+
+ sprite.hotPhys.x -= xoff;
+ sprite.hotPhys.y -= yoff;
+
+ sprite.hotLimits.x1 -= xoff;
+ sprite.hotLimits.y1 -= yoff;
+ sprite.hotLimits.x2 -= xoff;
+ sprite.hotLimits.y2 -= yoff;
+
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, xoff, yoff);
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, xoff, yoff);
+
+ /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ } else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+ register ScreenPtr pScreen = win->drawable.pScreen;
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hotPhys.x = pScreen->width / 2;
+ sprite.hotPhys.y = pScreen->height / 2;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (
+ pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.confineWin = NullWindow;
+#ifdef SHAPE
+ sprite.hotShape = NullRegion;
+#endif
+ sprite.screen = pScreen;
+ /* gotta UNINIT these someplace */
+ REGION_NULL(pScreen, &sprite.Reg1);
+ REGION_NULL(pScreen, &sprite.Reg2);
+ }
+#endif
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+ PostNewCursor();
+}
+
+_X_EXPORT void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+ sprite.hotPhys.x = x;
+ sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
+ panoramiXdataPtr[0].x;
+ sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
+ panoramiXdataPtr[0].y;
+ if (newScreen != sprite.screen) {
+ sprite.screen = newScreen;
+ /* Make sure we tell the DDX to update its copy of the screen */
+ if(sprite.confineWin)
+ XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+ else
+ XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+ /* if the pointer wasn't confined, the DDX won't get
+ told of the pointer warp so we reposition it here */
+ if(!syncEvents.playingEvents)
+ (*sprite.screen->SetCursorPosition)(sprite.screen,
+ sprite.hotPhys.x + panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x,
+ sprite.hotPhys.y + panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+ }
+ } else
+#endif
+ if (newScreen != sprite.hotPhys.pScreen)
+ ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+ WindowPtr pWin,
+ int x,
+ int y
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+ int i, xoff, yoff;
+
+ if (!pWin->realized) return FALSE;
+
+ if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+ return TRUE;
+
+ if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+ xoff = x + panoramiXdataPtr[0].x;
+ yoff = y + panoramiXdataPtr[0].y;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ pWin = sprite.windows[i];
+ pScreen = pWin->drawable.pScreen;
+ x = xoff - panoramiXdataPtr[i].x;
+ y = yoff - panoramiXdataPtr[i].y;
+
+ if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+
+ REQUEST(xWarpPointerReq);
+
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if(source == WindowTable[0]) {
+ winX -= panoramiXdataPtr[0].x;
+ winY -= panoramiXdataPtr[0].y;
+ }
+ if (x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !XineramaPointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest) {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ if(dest == WindowTable[0]) {
+ x -= panoramiXdataPtr[0].x;
+ y -= panoramiXdataPtr[0].y;
+ }
+ }
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+
+ XineramaSetCursorPosition(x, y, TRUE);
+
+ return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+ ScreenPtr newScreen;
+
+ REQUEST(xWarpPointerReq);
+
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaWarpPointer(client);
+#endif
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+ x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !PointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest)
+ {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ newScreen = dest->drawable.pScreen;
+ } else
+ newScreen = sprite.hotPhys.pScreen;
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= newScreen->width)
+ x = newScreen->width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= newScreen->height)
+ y = newScreen->height - 1;
+
+ if (newScreen == sprite.hotPhys.pScreen)
+ {
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+ (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+ }
+ else if (!PointerConfinedToScreen())
+ {
+ NewCurrentScreen(newScreen, x, y);
+ }
+ return Success;
+}
+
+static Bool
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+ if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+ WindowPtr pWin,
+ register DeviceIntPtr device,
+ register xEvent *xE,
+ int count)
+{
+ register GrabPtr grab = wPassiveGrabs(pWin);
+ GrabRec tempGrab;
+ register xEvent *dxE;
+
+ if (!grab)
+ return FALSE;
+ tempGrab.window = pWin;
+ tempGrab.device = device;
+ tempGrab.type = xE->u.u.type;
+ tempGrab.detail.exact = xE->u.u.detail;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.modifiersDetail.pMask = NULL;
+ for (; grab; grab = grab->next)
+ {
+#ifdef XKB
+ DeviceIntPtr gdev;
+ XkbSrvInfoPtr xkbi;
+
+ gdev= grab->modifierDevice;
+ xkbi= gdev->key->xkbInfo;
+#endif
+ tempGrab.modifierDevice = grab->modifierDevice;
+ if ((device == grab->modifierDevice) &&
+ ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceKeyPress)
+#endif
+ ))
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->prev_state;
+#endif
+ else
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->state;
+#endif
+ if (GrabMatchesSecond(&tempGrab, grab) &&
+ (!grab->confineTo ||
+ (grab->confineTo->realized &&
+ BorderSizeNotEmpty(grab->confineTo))))
+ {
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, wClient(pWin), device, FALSE))
+ return FALSE;
+#endif
+#ifdef XKB
+ if (!noXkbExtension) {
+ XE_KBPTR.state &= 0x1f00;
+ XE_KBPTR.state |=
+ tempGrab.modifiersDetail.exact&(~0x1f00);
+ }
+#endif
+ (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+ (void) TryClientEvents(rClient(grab), xE, count,
+ filters[xE->u.u.type],
+ filters[xE->u.u.type], grab);
+
+ if (device->sync.state == FROZEN_NO_EVENT)
+ {
+ if (device->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ device->sync.event = (xEvent *)xrealloc(device->sync.event,
+ count*
+ sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ device->sync.evcount = count;
+ for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ device->sync.state = FROZEN_WITH_EVENT;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated. If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated. If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated. If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE,
+ int checkFirst, int count)
+{
+ register int i;
+ register WindowPtr pWin = NULL;
+ register FocusClassPtr focus = device->focus;
+
+ if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceButtonPress)
+#endif
+ ) && (device->button->buttonsDown != 1))
+ return FALSE;
+
+ i = checkFirst;
+
+ if (focus)
+ {
+ for (; i < focus->traceGood; i++)
+ {
+ pWin = focus->trace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ if ((focus->win == NoneWin) ||
+ (i >= spriteTraceGood) ||
+ ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+ return FALSE;
+ }
+
+ for (; i < spriteTraceGood; i++)
+ {
+ pWin = spriteTrace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+ WindowPtr focus = keybd->focus->win;
+ int mskidx = 0;
+
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ if (!focus)
+ return;
+ if (focus == PointerRootWin)
+ {
+ DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+ return;
+ }
+ if ((focus == window) || IsParent(focus, window))
+ {
+ if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+ return;
+ }
+ /* just deliver it to the focus window */
+ FixUpEventFromWindow(xE, focus, None, FALSE);
+ if (xE->u.u.type & EXTENSION_EVENT_BASE)
+ mskidx = keybd->id;
+ (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+ NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev,
+ Bool deactivateGrab, int count)
+{
+ register GrabPtr grab = thisDev->grab;
+ int deliveries = 0;
+ register DeviceIntPtr dev;
+ register xEvent *dxE;
+
+ if (grab->ownerEvents)
+ {
+ WindowPtr focus;
+
+ if (thisDev->focus)
+ {
+ focus = thisDev->focus->win;
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ }
+ else
+ focus = PointerRootWin;
+ if (focus == PointerRootWin)
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+ thisDev, count);
+ else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+ thisDev, count);
+ else if (focus)
+ deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+ thisDev, count);
+ }
+ if (!deliveries)
+ {
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+ deliveries = TryClientEvents(rClient(grab), xE, count,
+ (Mask)grab->eventMask,
+ filters[xE->u.u.type], grab);
+ if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+ || xE->u.u.type == DeviceMotionNotify
+#endif
+ ))
+ thisDev->valuator->motionHintWindow = grab->window;
+ }
+ if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+ && xE->u.u.type != DeviceMotionNotify
+#endif
+ ))
+ switch (thisDev->sync.state)
+ {
+ case FREEZE_BOTH_NEXT_EVENT:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ FreezeThaw(dev, TRUE);
+ if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+ (CLIENT_BITS(dev->grab->resource) ==
+ CLIENT_BITS(thisDev->grab->resource)))
+ dev->sync.state = FROZEN_NO_EVENT;
+ else
+ dev->sync.other = thisDev->grab;
+ }
+ /* fall through */
+ case FREEZE_NEXT_EVENT:
+ thisDev->sync.state = FROZEN_WITH_EVENT;
+ FreezeThaw(thisDev, TRUE);
+ if (thisDev->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+ count*sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ thisDev->sync.evcount = count;
+ for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ break;
+ }
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+ int key, bit;
+ register BYTE *kptr;
+ register int i;
+ register CARD8 modifiers;
+ register CARD16 mask;
+ GrabPtr grab = keybd->grab;
+ Bool deactivateGrab = FALSE;
+ register KeyClassPtr keyc = keybd->key;
+#ifdef XEVIE
+ static Window rootWin = 0;
+
+ if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ if((xE->u.u.type == KeyPress && (*kptr & bit)) ||
+ (xE->u.u.type == KeyRelease && !(*kptr & bit)))
+ {} else {
+#ifdef XKB
+ if(!noXkbExtension)
+ xevieKBEventSent = 1;
+#endif
+ if(!xevieKBEventSent)
+ {
+ xeviekb = keybd;
+ if(!rootWin) {
+ rootWin = GetCurrentRootWindow()->drawable.id;
+ }
+ xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+ xE->u.keyButtonPointer.root = rootWin;
+ xE->u.keyButtonPointer.child = (xeviewin->firstChild) ? xeviewin->firstChild->
+drawable.id:0;
+ xE->u.keyButtonPointer.rootX = xeviehot.x;
+ xE->u.keyButtonPointer.rootY = xeviehot.y;
+ xE->u.keyButtonPointer.state = keyc->state;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+#ifdef XKB
+ if(noXkbExtension)
+#endif
+ return;
+ } else {
+ xevieKBEventSent = 0;
+ }
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+#ifdef XEVIE
+ /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+ if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+ && !noXkbExtension
+#endif
+ )))
+#endif
+ XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ modifiers = keyc->modifierMap[key];
+#if defined(XKB) && defined(XEVIE)
+ if(!noXkbExtension && !xeviegrabState &&
+ xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ switch(xE->u.u.type) {
+ case KeyPress: *kptr &= ~bit; break;
+ case KeyRelease: *kptr |= bit; break;
+ }
+ }
+#endif
+
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ if (*kptr & bit) /* allow ddx to generate multiple downs */
+ {
+ if (!modifiers)
+ {
+ xE->u.u.type = KeyRelease;
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ xE->u.u.type = KeyPress;
+ /* release can have side effects, don't fall through */
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ }
+ return;
+ }
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr |= bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers)
+ {
+ /* This key affects modifier "i" */
+ keyc->modifierKeyCount[i]++;
+ keyc->state |= mask;
+ modifiers &= ~mask;
+ }
+ }
+ if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+ {
+ keybd->activatingKey = key;
+ return;
+ }
+ break;
+ case KeyRelease:
+ if (!(*kptr & bit)) /* guard against duplicates */
+ return;
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr &= ~bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers) {
+ /* This key affects modifier "i" */
+ if (--keyc->modifierKeyCount[i] <= 0) {
+ keyc->state &= ~mask;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ modifiers &= ~mask;
+ }
+ }
+ if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+ if (grab)
+ DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+ else
+ DeliverFocusedEvent(keybd, xE, sprite.win, count);
+ if (deactivateGrab)
+ (*keybd->DeactivateGrab)(keybd);
+
+#ifdef XACE
+ XaceHook(XACE_KEY_AVAIL, xE, keybd, count);
+#endif
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+ this is only used when the pressing of keys does not cause
+ CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+ int key, bit;
+ register BYTE *kptr;
+ register KeyClassPtr keyc = keybd->key;
+
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("FixKeyState: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ *kptr |= bit;
+ break;
+ case KeyRelease:
+ *kptr &= ~bit;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+ register GrabPtr grab = mouse->grab;
+ Bool deactivateGrab = FALSE;
+ register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+ XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
+#endif
+#ifdef XEVIE
+ if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ if(xevieEventSent)
+ xevieEventSent = 0;
+ else {
+ xeviemouse = mouse;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+ return;
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE)
+ XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+ (noXkbExtension ?
+ inputInfo.keyboard->key->state :
+ xkbi->state.grab_mods)
+#else
+ inputInfo.keyboard->key->state
+#endif
+ ));
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* see comment in EnqueueEvents regarding the next three lines */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+ if (xE->u.u.type != MotionNotify)
+ {
+ register int key;
+ register BYTE *kptr;
+ int bit;
+
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+
+ key = xE->u.u.detail;
+ kptr = &butc->down[key >> 3];
+ bit = 1 << (key & 7);
+ switch (xE->u.u.type)
+ {
+ case ButtonPress:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (!(*kptr & bit))
+ butc->buttonsDown++;
+ butc->motionMask = ButtonMotionMask;
+ *kptr |= bit;
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!grab)
+ if (CheckDeviceGrabs(mouse, xE, 0, count))
+ return;
+ break;
+ case ButtonRelease:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (*kptr & bit)
+ --butc->buttonsDown;
+ if (!butc->buttonsDown)
+ butc->motionMask = 0;
+ *kptr &= ~bit;
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!butc->state && mouse->fromPassiveGrab)
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("bogus pointer event from ddx");
+ }
+ }
+ else if (!CheckMotion(xE))
+ return;
+ if (grab)
+ DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+ else
+ DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+ mouse, count);
+ if (deactivateGrab)
+ (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+ register WindowPtr pWin;
+{
+ register OtherClients *others;
+ register WindowPtr pChild;
+
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->optional)
+ {
+ pChild->optional->otherEventMasks = 0;
+ for (others = wOtherClients(pChild); others; others = others->next)
+ {
+ pChild->optional->otherEventMasks |= others->mask;
+ }
+ }
+ pChild->deliverableEvents = pChild->eventMask|
+ wOtherEventMasks(pChild);
+ if (pChild->parent)
+ pChild->deliverableEvents |=
+ (pChild->parent->deliverableEvents &
+ ~wDontPropagateMask(pChild) & PropagateMask);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+ register OtherClientsPtr other, prev;
+ register WindowPtr pWin = (WindowPtr)value;
+
+ prev = 0;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ prev->next = other->next;
+ else
+ {
+ if (!(pWin->optional->otherClients = other->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ xfree(other);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on event list");
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+ Mask check;
+ OtherClients * others;
+
+ if (mask & ~AllEventMasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ check = (mask & AtMostOneClient);
+ if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+ { /* It is illegal for two different
+ clients to select on any of the
+ events for AtMostOneClient. However,
+ it is OK, for some client to
+ continue selecting on one of those
+ events. */
+ if ((wClient(pWin) != client) && (check & pWin->eventMask))
+ return BadAccess;
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (!SameClient(others, client) && (check & others->mask))
+ return BadAccess;
+ }
+ }
+ if (wClient (pWin) == client)
+ {
+ check = pWin->eventMask;
+#ifdef SGIMISC
+ pWin->eventMask =
+ (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+ pWin->eventMask = mask;
+#endif
+ }
+ else
+ {
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (SameClient(others, client))
+ {
+ check = others->mask;
+#ifdef SGIMISC
+ mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+ if (mask == 0)
+ {
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ else
+ others->mask = mask;
+ goto maskSet;
+ }
+ }
+ check = 0;
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return BadAlloc;
+ others = (OtherClients *) xalloc(sizeof(OtherClients));
+ if (!others)
+ return BadAlloc;
+ others->mask = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->otherClients;
+ pWin->optional->otherClients = others;
+ if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+ return BadAlloc;
+ }
+maskSet:
+ if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+ (mask & PointerMotionHintMask) &&
+ !(check & PointerMotionHintMask) &&
+ !inputInfo.pointer->grab)
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client,
+ Mask mask, Bool *checkOptional)
+{
+ register int i, free;
+
+ if (mask & ~PropagateMask)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ if (!mask)
+ i = 0;
+ else
+ {
+ for (i = DNPMCOUNT, free = 0; --i > 0; )
+ {
+ if (!DontPropagateRefCnts[i])
+ free = i;
+ else if (mask == DontPropagateMasks[i])
+ break;
+ }
+ if (!i && free)
+ {
+ i = free;
+ DontPropagateMasks[i] = mask;
+ }
+ }
+ if (i || !mask)
+ {
+ pWin->dontPropagate = i;
+ if (i)
+ DontPropagateRefCnts[i]++;
+ if (pWin->optional)
+ {
+ pWin->optional->dontPropagateMask = mask;
+ *checkOptional = TRUE;
+ }
+ }
+ else
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]++;
+ return BadAlloc;
+ }
+ pWin->dontPropagate = 0;
+ pWin->optional->dontPropagateMask = mask;
+ }
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+static WindowPtr
+CommonAncestor(
+ register WindowPtr a,
+ register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (IsParent(b, a)) return b;
+ return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+ int type,
+ int mode,
+ int detail,
+ register WindowPtr pWin,
+ Window child)
+{
+ xEvent event;
+ register DeviceIntPtr keybd = inputInfo.keyboard;
+ WindowPtr focus;
+ register DeviceIntPtr mouse = inputInfo.pointer;
+ register GrabPtr grab = mouse->grab;
+ Mask mask;
+
+ if ((pWin == mouse->valuator->motionHintWindow) &&
+ (detail != NotifyInferior))
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (grab)
+ {
+ mask = (pWin == grab->window) ? grab->eventMask : 0;
+ if (grab->ownerEvents)
+ mask |= EventMaskForClient(pWin, rClient(grab));
+ }
+ else
+ {
+ mask = pWin->eventMask | wOtherEventMasks(pWin);
+ }
+ if (mask & filters[type])
+ {
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.enterLeave.time = currentTime.milliseconds;
+ event.u.enterLeave.rootX = sprite.hot.x;
+ event.u.enterLeave.rootY = sprite.hot.y;
+ /* Counts on the same initial structure of crossing & button events! */
+ FixUpEventFromWindow(&event, pWin, None, FALSE);
+ /* Enter/Leave events always set child */
+ event.u.enterLeave.child = child;
+ event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+ ELFlagSameScreen : 0;
+#ifdef XKB
+ if (!noXkbExtension) {
+ event.u.enterLeave.state = mouse->button->state & 0x1f00;
+ event.u.enterLeave.state |=
+ XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+ } else
+#endif
+ event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+ event.u.enterLeave.mode = mode;
+ focus = keybd->focus->win;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) ||
+ IsParent(focus, pWin)))
+ event.u.enterLeave.flags |= ELFlagFocus;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), &event, 1, mask,
+ filters[type], grab);
+ else
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+ NullGrab, 0);
+ }
+ if ((type == EnterNotify) && (mask & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+
+#ifdef XACE
+ ClientPtr client = grab ? rClient(grab)
+ : clients[CLIENT_ID(pWin->drawable.id)];
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, keybd, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+ ke.type = KeymapNotify;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+ KeymapStateMask, grab);
+ else
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+ WindowPtr parent = child->parent;
+
+ if (ancestor == parent)
+ return;
+ EnterNotifies(ancestor, parent, mode, detail);
+ EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+ register WindowPtr pWin;
+
+ if (ancestor == child)
+ return;
+ for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+ {
+ EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+ child = pWin;
+ }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ if (fromWin == toWin)
+ return;
+ if (IsParent(fromWin, toWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+ EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+ }
+ else if (IsParent(toWin, fromWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+ LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+ }
+ else
+ { /* neither fromWin nor toWin is descendent of the other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+ LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+ EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+ }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+ xEvent event;
+
+#ifdef XINPUT
+ if (dev != inputInfo.keyboard)
+ {
+ DeviceFocusEvent(dev, type, mode, detail, pWin);
+ return;
+ }
+#endif
+ event.u.focus.mode = mode;
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.focus.window = pWin->drawable.id;
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+ 0);
+ if ((type == FocusIn) &&
+ ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+#ifdef XACE
+ ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, dev, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+ ke.type = KeymapNotify;
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+ /*
+ * recursive because it is easier
+ * no-op if child not descended from ancestor
+ */
+static Bool
+FocusInEvents(
+ DeviceIntPtr dev,
+ WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ if (child == NullWindow)
+ return ancestor == NullWindow;
+ if (ancestor == child)
+ {
+ if (doAncestor)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+ doAncestor))
+ {
+ if (child != skipChild)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+ DeviceIntPtr dev,
+ WindowPtr child, WindowPtr ancestor,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ register WindowPtr pWin;
+
+ for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+ FocusEvent(dev, FocusOut, mode, detail, pWin);
+ if (doAncestor)
+ FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ int out, in; /* for holding details for to/from
+ PointerRoot/None */
+ int i;
+
+ if (fromWin == toWin)
+ return;
+ out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+ if ((toWin == NullWindow) || (toWin == PointerRootWin))
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ }
+ else
+ {
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+ FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ /* next call catches the root too, if the screen changed */
+ FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+ NotifyNonlinearVirtual, FALSE);
+ }
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+ if (toWin == PointerRootWin)
+ (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+ NotifyPointer, TRUE);
+ }
+ else
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+ NotifyNonlinearVirtual, TRUE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+ NotifyPointer, FALSE);
+ }
+ else
+ {
+ if (IsParent(toWin, fromWin))
+ {
+ FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+ FocusOutEvents(dev, fromWin->parent, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+ if ((IsParent(toWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(fromWin, sprite.win)) &&
+ (!IsParent(sprite.win, fromWin)))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ else
+ if (IsParent(fromWin, toWin))
+ {
+ if ((IsParent(fromWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(toWin, sprite.win)) &&
+ (!IsParent(sprite.win, toWin)))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+ (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+ }
+ else
+ {
+ /* neither fromWin or toWin is child of other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ if (fromWin->parent != NullWindow)
+ FocusOutEvents(dev, fromWin->parent, common, mode,
+ NotifyNonlinearVirtual, FALSE);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, common, toWin, toWin, mode,
+ NotifyNonlinearVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ }
+ }
+}
+
+int
+SetInputFocus(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ Window focusID,
+ CARD8 revertTo,
+ Time ctime,
+ Bool followOK)
+{
+ register FocusClassPtr focus;
+ register WindowPtr focusWin;
+ int mode;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((revertTo != RevertToParent) &&
+ (revertTo != RevertToPointerRoot) &&
+ (revertTo != RevertToNone) &&
+ ((revertTo != RevertToFollowKeyboard) || !followOK))
+ {
+ client->errorValue = revertTo;
+ return BadValue;
+ }
+ time = ClientTimeToServerTime(ctime);
+ if ((focusID == None) || (focusID == PointerRoot))
+ focusWin = (WindowPtr)(long)focusID;
+ else if ((focusID == FollowKeyboard) && followOK)
+ focusWin = inputInfo.keyboard->focus->win;
+ else if (!(focusWin = SecurityLookupWindow(focusID, client,
+ SecurityReadAccess)))
+ return BadWindow;
+ else
+ {
+ /* It is a match error to try to set the input focus to an
+ unviewable window. */
+
+ if(!focusWin->realized)
+ return(BadMatch);
+ }
+ focus = dev->focus;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, focus->time) == EARLIER))
+ return Success;
+ mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+ if (focus->win == FollowKeyboardWin)
+ DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+ else
+ DoFocusEvents(dev, focus->win, focusWin, mode);
+ focus->time = time;
+ focus->revert = revertTo;
+ if (focusID == FollowKeyboard)
+ focus->win = FollowKeyboardWin;
+ else
+ focus->win = focusWin;
+ if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+ focus->traceGood = 0;
+ else
+ {
+ int depth = 0;
+ register WindowPtr pWin;
+
+ for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+ if (depth > focus->traceSize)
+ {
+ focus->traceSize = depth+1;
+ Must_have_memory = TRUE; /* XXX */
+ focus->trace = (WindowPtr *)xrealloc(focus->trace,
+ focus->traceSize *
+ sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ focus->traceGood = depth;
+ for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
+ focus->trace[depth] = pWin;
+ }
+ return Success;
+}
+
+int
+ProcSetInputFocus(client)
+ ClientPtr client;
+{
+ REQUEST(xSetInputFocusReq);
+
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
+ return Success;
+#endif
+ return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+ stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+ xGetInputFocusReply rep;
+ /* REQUEST(xReq); */
+ FocusClassPtr focus = inputInfo.keyboard->focus;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (focus->win == NoneWin)
+ rep.focus = None;
+ else if (focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else rep.focus = focus->win->drawable.id;
+ rep.revertTo = focus->revert;
+ WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+ return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+ xGrabPointerReply rep;
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor, oldCursor;
+ REQUEST(xGrabPointerReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ UpdateCurrentTime();
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else
+ {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ /* at this point, some sort of reply is guaranteed. */
+ time = ClientTimeToServerTime(stuff->time);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ grab = device->grab;
+ if ((grab) && !SameClient(grab, client))
+ rep.status = AlreadyGrabbed;
+ else if ((!pWin->realized) ||
+ (confineTo &&
+ !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+ rep.status = GrabNotViewable;
+ else if (device->sync.frozen &&
+ device->sync.other && !SameClient(device->sync.other, client))
+ rep.status = GrabFrozen;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ rep.status = GrabInvalidTime;
+ else
+ {
+ GrabRec tempGrab;
+
+ oldCursor = NullCursor;
+ if (grab)
+ {
+ if (grab->confineTo && !confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ oldCursor = grab->cursor;
+ }
+ tempGrab.cursor = cursor;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = stuff->ownerEvents;
+ tempGrab.eventMask = stuff->eventMask;
+ tempGrab.confineTo = confineTo;
+ tempGrab.window = pWin;
+ tempGrab.keyboardMode = stuff->keyboardMode;
+ tempGrab.pointerMode = stuff->pointerMode;
+ tempGrab.device = device;
+ (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+ if (oldCursor)
+ FreeCursor (oldCursor, (Cursor)0);
+ rep.status = GrabSuccess;
+ }
+ WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+ return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ register GrabPtr grab = device->grab;
+ CursorPtr newCursor, oldCursor;
+ REQUEST(xChangeActivePointerGrabReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ if (stuff->cursor == None)
+ newCursor = NullCursor;
+ else
+ {
+ newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!newCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ if (!grab)
+ return Success;
+ if (!SameClient(grab, client))
+ return Success;
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ return Success;
+ oldCursor = grab->cursor;
+ grab->cursor = newCursor;
+ if (newCursor)
+ newCursor->refcnt++;
+ PostNewCursor();
+ if (oldCursor)
+ FreeCursor(oldCursor, (Cursor)0);
+ grab->eventMask = stuff->eventMask;
+ return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
+ unsigned this_mode, unsigned other_mode, Window grabWindow,
+ unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+ register WindowPtr pWin;
+ register GrabPtr grab;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+ {
+ client->errorValue = this_mode;
+ return BadValue;
+ }
+ if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+ {
+ client->errorValue = other_mode;
+ return BadValue;
+ }
+ if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ time = ClientTimeToServerTime(ctime);
+ grab = dev->grab;
+ if (grab && !SameClient(grab, client))
+ *status = AlreadyGrabbed;
+ else if (!pWin->realized)
+ *status = GrabNotViewable;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+ *status = GrabInvalidTime;
+ else if (dev->sync.frozen &&
+ dev->sync.other && !SameClient(dev->sync.other, client))
+ *status = GrabFrozen;
+ else
+ {
+ GrabRec tempGrab;
+
+ tempGrab.window = pWin;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = ownerEvents;
+ tempGrab.keyboardMode = this_mode;
+ tempGrab.pointerMode = other_mode;
+ tempGrab.eventMask = mask;
+ tempGrab.device = dev;
+ (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ *status = GrabSuccess;
+ }
+ return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+ xGrabKeyboardReply rep;
+ REQUEST(xGrabKeyboardReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
+ {
+ result = Success;
+ rep.status = AlreadyGrabbed;
+ }
+ else
+#endif
+ result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+ stuff->pointerMode, stuff->grabWindow,
+ stuff->ownerEvents, stuff->time,
+ KeyPressMask | KeyReleaseMask, &rep.status);
+ if (result != Success)
+ return result;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+ return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.keyboard;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+ xQueryPointerReply rep;
+ WindowPtr pWin, t;
+ REQUEST(xResourceReq);
+ DeviceIntPtr mouse = inputInfo.pointer;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+ rep.length = 0;
+ rep.root = (ROOT)->drawable.id;
+ rep.rootX = sprite.hot.x;
+ rep.rootY = sprite.hot.y;
+ rep.child = None;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ rep.sameScreen = xTrue;
+ rep.winX = sprite.hot.x - pWin->drawable.x;
+ rep.winY = sprite.hot.y - pWin->drawable.y;
+ for (t = sprite.win; t; t = t->parent)
+ if (t->parent == pWin)
+ {
+ rep.child = t->drawable.id;
+ break;
+ }
+ }
+ else
+ {
+ rep.sameScreen = xFalse;
+ rep.winX = 0;
+ rep.winY = 0;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ rep.rootX += panoramiXdataPtr[0].x;
+ rep.rootY += panoramiXdataPtr[0].y;
+ if(stuff->id == rep.root) {
+ rep.winX += panoramiXdataPtr[0].x;
+ rep.winY += panoramiXdataPtr[0].y;
+ }
+ }
+#endif
+
+ WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+ return(Success);
+}
+
+void
+InitEvents()
+{
+ int i;
+
+ sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+ inputInfo.numDevices = 0;
+ inputInfo.devices = (DeviceIntPtr)NULL;
+ inputInfo.off_devices = (DeviceIntPtr)NULL;
+ inputInfo.keyboard = (DeviceIntPtr)NULL;
+ inputInfo.pointer = (DeviceIntPtr)NULL;
+ if (spriteTraceSize == 0)
+ {
+ spriteTraceSize = 32;
+ spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+ if (!spriteTrace)
+ FatalError("failed to allocate spriteTrace");
+ }
+ spriteTraceGood = 0;
+ lastEventMask = OwnerGrabButtonMask;
+ filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = NullWindow;
+ sprite.current = NullCursor;
+ sprite.hotLimits.x1 = 0;
+ sprite.hotLimits.y1 = 0;
+ sprite.hotLimits.x2 = 0;
+ sprite.hotLimits.y2 = 0;
+ sprite.confined = FALSE;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ syncEvents.replayWin = NullWindow;
+ while (syncEvents.pending)
+ {
+ QdEventPtr next = syncEvents.pending->next;
+ xfree(syncEvents.pending);
+ syncEvents.pending = next;
+ }
+ syncEvents.pendtail = &syncEvents.pending;
+ syncEvents.playingEvents = FALSE;
+ syncEvents.time.months = 0;
+ syncEvents.time.milliseconds = 0; /* hardly matters */
+ currentTime.months = 0;
+ currentTime.milliseconds = GetTimeInMillis();
+ lastDeviceEventTime = currentTime;
+ for (i = 0; i < DNPMCOUNT; i++)
+ {
+ DontPropagateMasks[i] = 0;
+ DontPropagateRefCnts[i] = 0;
+ }
+}
+
+void
+CloseDownEvents(void)
+{
+ xfree(spriteTrace);
+ spriteTrace = NULL;
+ spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ REQUEST(xSendEventReq);
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+
+ /* The client's event type must be a core event type or one defined by an
+ extension. */
+
+ if ( ! ((stuff->event.u.u.type > X_Reply &&
+ stuff->event.u.u.type < LASTEvent) ||
+ (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+ stuff->event.u.u.type < (unsigned)lastEvent)))
+ {
+ client->errorValue = stuff->event.u.u.type;
+ return BadValue;
+ }
+ if (stuff->event.u.u.type == ClientMessage &&
+ stuff->event.u.u.detail != 8 &&
+ stuff->event.u.u.detail != 16 &&
+ stuff->event.u.u.detail != 32)
+ {
+ client->errorValue = stuff->event.u.u.detail;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~AllEventMasks)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->destination == PointerWindow)
+ pWin = sprite.win;
+ else if (stuff->destination == InputFocus)
+ {
+ WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = ROOT;
+
+ if (IsParent(inputFocus, sprite.win))
+ {
+ effectiveFocus = inputFocus;
+ pWin = sprite.win;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ pWin = SecurityLookupWindow(stuff->destination, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+ {
+ client->errorValue = stuff->propagate;
+ return BadValue;
+ }
+ stuff->event.u.u.type |= 0x80;
+ if (stuff->propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ stuff->eventMask &= ~wDontPropagateMask(pWin);
+ if (!stuff->eventMask)
+ break;
+ }
+ }
+ else
+ (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0);
+ return Success;
+}
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+ REQUEST(xUngrabKeyReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = keybd;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = KeyPress;
+ tempGrab.detail.exact = stuff->key;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xGrabKeyReq);
+ GrabPtr grab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+ if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return(BadValue);
+ }
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ grab = CreateGrab(client->index, keybd, pWin,
+ (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+ (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+ keybd, stuff->modifiers, KeyPress, stuff->key,
+ NullWindow, NullCursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+ WindowPtr pWin, confineTo;
+ REQUEST(xGrabButtonReq);
+ CursorPtr cursor;
+ GrabPtr grab;
+
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+
+
+ grab = CreateGrab(client->index, inputInfo.pointer, pWin,
+ (Mask)stuff->eventMask, (Bool)stuff->ownerEvents,
+ (Bool) stuff->keyboardMode, (Bool)stuff->pointerMode,
+ inputInfo.keyboard, stuff->modifiers, ButtonPress,
+ stuff->button, confineTo, cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+ REQUEST(xUngrabButtonReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = ButtonPress;
+ tempGrab.detail.exact = stuff->button;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+ WindowPtr parent;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ FocusClassPtr focus = keybd->focus;
+ OtherClientsPtr oc;
+ GrabPtr passive;
+
+
+ /* Deactivate any grabs performed on this window, before making any
+ input focus changes. */
+
+ if (mouse->grab &&
+ ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+ (*mouse->DeactivateGrab)(mouse);
+
+ /* Deactivating a keyboard grab should cause focus events. */
+
+ if (keybd->grab && (keybd->grab->window == pWin))
+ (*keybd->DeactivateGrab)(keybd);
+
+ /* If the focus window is a root window (ie. has no parent) then don't
+ delete the focus from it. */
+
+ if ((pWin == focus->win) && (pWin->parent != NullWindow))
+ {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (keybd->grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (focus->revert)
+ {
+ case RevertToNone:
+ DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+ focus->win = NoneWin;
+ focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do
+ {
+ parent = parent->parent;
+ focus->traceGood--;
+ } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+ during SaveSet processing would cause the focus to revert to the
+ nearest enclosing window which will survive the death of the exiting
+ client, instead of ending up reverting to a dying window and thence
+ to None
+ */
+#ifdef NOTDEF
+ || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+ );
+ DoFocusEvents(keybd, pWin, parent, focusEventMode);
+ focus->win = parent;
+ focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+ focus->win = PointerRootWin;
+ focus->traceGood = 0;
+ break;
+ }
+ }
+
+ if (mouse->valuator->motionHintWindow == pWin)
+ mouse->valuator->motionHintWindow = NullWindow;
+
+ if (freeResources)
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ while ( (oc = wOtherClients(pWin)) )
+ FreeResource(oc->resource, RT_NONE);
+ while ( (passive = wPassiveGrabs(pWin)) )
+ FreeResource(passive->resource, RT_NONE);
+ }
+#ifdef XINPUT
+ DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry
+ */
+_X_EXPORT void
+CheckCursorConfinement(WindowPtr pWin)
+{
+ GrabPtr grab = inputInfo.pointer->grab;
+ WindowPtr confineTo;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+ if (grab && (confineTo = grab->confineTo))
+ {
+ if (!BorderSizeNotEmpty(confineTo))
+ (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+ else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+ ConfineCursorToWindow(confineTo, TRUE, TRUE);
+ }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+ register OtherClientsPtr other;
+
+ if (wClient (pWin) == client)
+ return pWin->eventMask;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (SameClient(other, client))
+ return other->mask;
+ }
+ return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+ CursorPtr pCursor;
+ int nscr;
+ ScreenPtr pscr;
+ Bool displayed;
+ REQUEST(xRecolorCursorReq);
+
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityWriteAccess);
+ if ( !pCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return (BadCursor);
+ }
+
+ pCursor->foreRed = stuff->foreRed;
+ pCursor->foreGreen = stuff->foreGreen;
+ pCursor->foreBlue = stuff->foreBlue;
+
+ pCursor->backRed = stuff->backRed;
+ pCursor->backGreen = stuff->backGreen;
+ pCursor->backBlue = stuff->backBlue;
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ displayed = (pscr == sprite.screen);
+ else
+#endif
+ displayed = (pscr == sprite.hotPhys.pScreen);
+ ( *pscr->RecolorCursor)(pscr, pCursor,
+ (pCursor == sprite.current) && displayed);
+ }
+ return (Success);
+}
+
+_X_EXPORT void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+ xEvent eventCopy;
+#endif
+ xEvent eventTo, *eventFrom;
+ int i;
+
+#ifdef XKB
+ if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+ return;
+#endif
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension &&
+ (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
+ {
+ switch(events->u.u.type) {
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ /*
+ When multiple clients want the same event DeliverEventsToWindow
+ passes the same event structure multiple times so we can't
+ modify the one passed to us
+ */
+ count = 1; /* should always be 1 */
+ memcpy(&eventCopy, events, sizeof(xEvent));
+ eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+ if(eventCopy.u.keyButtonPointer.event ==
+ eventCopy.u.keyButtonPointer.root)
+ {
+ eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+ }
+ events = &eventCopy;
+ break;
+ default: break;
+ }
+ }
+#endif
+
+ if (EventCallback)
+ {
+ EventInfoRec eventinfo;
+ eventinfo.client = pClient;
+ eventinfo.events = events;
+ eventinfo.count = count;
+ CallCallbacks(&EventCallback, (pointer)&eventinfo);
+ }
+ if(pClient->swapped)
+ {
+ for(i = 0; i < count; i++)
+ {
+ eventFrom = &events[i];
+ /* Remember to strip off the leading bit of type in case
+ this event was sent with "SendEvent." */
+ (*EventSwapVector[eventFrom->u.u.type & 0177])
+ (eventFrom, &eventTo);
+ (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+ }
+ }
+ else
+ {
+ (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+ }
+}
diff --git a/xserver/dix/extension.c b/xserver/dix/extension.c
new file mode 100644
index 000000000..f58c73138
--- /dev/null
+++ b/xserver/dix/extension.c
@@ -0,0 +1,484 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "dispatch.h"
+#ifdef XACE
+#include "xace.h"
+#endif
+
+#define EXTENSION_BASE 128
+#define EXTENSION_EVENT_BASE 64
+#define LAST_EVENT 128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+extern int extensionPrivateLen;
+extern unsigned *extensionPrivateSizes;
+extern unsigned totalExtensionSize;
+
+static void
+InitExtensionPrivates(ExtensionEntry *ext)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalExtensionSize == sizeof(ExtensionEntry))
+ ppriv = (DevUnion *)NULL;
+ else
+ ppriv = (DevUnion *)(ext + 1);
+
+ ext->devPrivates = ppriv;
+ sizes = extensionPrivateSizes;
+ ptr = (char *)(ppriv + extensionPrivateLen);
+ for (i = extensionPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+}
+
+_X_EXPORT ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors,
+ int (*MainProc)(ClientPtr c1),
+ int (*SwappedMainProc)(ClientPtr c2),
+ void (*CloseDownProc)(ExtensionEntry *e),
+ unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+ int i;
+ register ExtensionEntry *ext, **newexts;
+
+ if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+ return((ExtensionEntry *) NULL);
+ if ((lastEvent + NumEvents > LAST_EVENT) ||
+ (unsigned)(lastError + NumErrors > LAST_ERROR))
+ return((ExtensionEntry *) NULL);
+
+ ext = (ExtensionEntry *) xalloc(totalExtensionSize);
+ if (!ext)
+ return((ExtensionEntry *) NULL);
+ bzero(ext, totalExtensionSize);
+ InitExtensionPrivates(ext);
+ ext->name = (char *)xalloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **)NULL;
+ if (!ext->name)
+ {
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ strcpy(ext->name, name);
+ i = NumExtensions;
+ newexts = (ExtensionEntry **) xrealloc(extensions,
+ (i + 1) * sizeof(ExtensionEntry *));
+ if (!newexts)
+ {
+ xfree(ext->name);
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ NumExtensions++;
+ extensions = newexts;
+ extensions[i] = ext;
+ ext->index = i;
+ ext->base = i + EXTENSION_BASE;
+ ext->CloseDown = CloseDownProc;
+ ext->MinorOpcode = MinorOpcodeProc;
+ ProcVector[i + EXTENSION_BASE] = MainProc;
+ SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+ if (NumEvents)
+ {
+ ext->eventBase = lastEvent;
+ ext->eventLast = lastEvent + NumEvents;
+ lastEvent += NumEvents;
+ }
+ else
+ {
+ ext->eventBase = 0;
+ ext->eventLast = 0;
+ }
+ if (NumErrors)
+ {
+ ext->errorBase = lastError;
+ ext->errorLast = lastError + NumErrors;
+ lastError += NumErrors;
+ }
+ else
+ {
+ ext->errorBase = 0;
+ ext->errorLast = 0;
+ }
+
+ return(ext);
+}
+
+_X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+ char *name;
+ char **aliases;
+
+ aliases = (char **)xrealloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *)xalloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases] = name;
+ ext->num_aliases++;
+ return TRUE;
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+ int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+ if ((strlen(extensions[i]->name) == len) &&
+ !strncmp(extname, extensions[i]->name, len))
+ break;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ if ((strlen(extensions[i]->aliases[j]) == len) &&
+ !strncmp(extname, extensions[i]->aliases[j], len))
+ break;
+ }
+ if (j >= 0) break;
+ }
+ return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name. Maybe this could just return a Bool instead?
+ */
+_X_EXPORT ExtensionEntry *
+CheckExtension(const char *extname)
+{
+ int n;
+
+ n = FindExtension((char*)extname, strlen(extname));
+ if (n != -1)
+ return extensions[n];
+ else
+ return NULL;
+}
+
+/*
+ * Added as part of Xace.
+ */
+ExtensionEntry *
+GetExtensionEntry(int major)
+{
+ if (major < EXTENSION_BASE)
+ return NULL;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return NULL;
+ return extensions[major];
+}
+
+_X_EXPORT void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XACE
+ int i = FindExtension(extname, strlen(extname));
+ if (i >= 0)
+ XaceHook(XACE_DECLARE_EXT_SECURE, extensions[i], secure);
+#endif
+}
+
+_X_EXPORT unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+ return ((xReq *)client->requestBuffer)->data;
+}
+
+_X_EXPORT unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+ unsigned char major;
+
+ major = ((xReq *)client->requestBuffer)->reqType;
+ if (major < EXTENSION_BASE)
+ return 0;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return 0;
+ return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+ register int i,j;
+
+ for (i = NumExtensions - 1; i >= 0; i--)
+ {
+ (* extensions[i]->CloseDown)(extensions[i]);
+ NumExtensions = i;
+ xfree(extensions[i]->name);
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ xfree(extensions[i]->aliases[j]);
+ xfree(extensions[i]->aliases);
+ xfree(extensions[i]);
+ }
+ xfree(extensions);
+ extensions = (ExtensionEntry **)NULL;
+ lastEvent = EXTENSION_EVENT_BASE;
+ lastError = FirstExtensionError;
+ for (i=0; i<MAXSCREENS; i++)
+ {
+ register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+ while (spentry->num)
+ {
+ spentry->num--;
+ xfree(spentry->procList[spentry->num].name);
+ }
+ xfree(spentry->procList);
+ spentry->procList = (ProcEntryPtr)NULL;
+ }
+}
+
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+ xQueryExtensionReply reply;
+ int i;
+ REQUEST(xQueryExtensionReq);
+
+ REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.major_opcode = 0;
+ reply.sequenceNumber = client->sequence;
+
+ if ( ! NumExtensions )
+ reply.present = xFalse;
+ else
+ {
+ i = FindExtension((char *)&stuff[1], stuff->nbytes);
+ if (i < 0
+#ifdef XACE
+ /* call callbacks to find out whether to show extension */
+ || !XaceHook(XACE_EXT_ACCESS, client, extensions[i])
+#endif
+ )
+ reply.present = xFalse;
+ else
+ {
+ reply.present = xTrue;
+ reply.major_opcode = extensions[i]->base;
+ reply.first_event = extensions[i]->eventBase;
+ reply.first_error = extensions[i]->errorBase;
+ }
+ }
+ WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+ xListExtensionsReply reply;
+ char *bufptr, *buffer;
+ int total_length = 0;
+
+ REQUEST_SIZE_MATCH(xReq);
+
+ reply.type = X_Reply;
+ reply.nExtensions = 0;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ buffer = NULL;
+
+ if ( NumExtensions )
+ {
+ register int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+#ifdef XACE
+ /* call callbacks to find out whether to show extension */
+ if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
+ continue;
+#endif
+ total_length += strlen(extensions[i]->name) + 1;
+ reply.nExtensions += 1 + extensions[i]->num_aliases;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ total_length += strlen(extensions[i]->aliases[j]) + 1;
+ }
+ reply.length = (total_length + 3) >> 2;
+ buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+ if (!buffer)
+ return(BadAlloc);
+ for (i=0; i<NumExtensions; i++)
+ {
+ int len;
+#ifdef XACE
+ if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
+ continue;
+#endif
+ *bufptr++ = len = strlen(extensions[i]->name);
+ memmove(bufptr, extensions[i]->name, len);
+ bufptr += len;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ *bufptr++ = len = strlen(extensions[i]->aliases[j]);
+ memmove(bufptr, extensions[i]->aliases[j], len);
+ bufptr += len;
+ }
+ }
+ }
+ WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+ if (reply.length)
+ {
+ WriteToClient(client, total_length, buffer);
+ DEALLOCATE_LOCAL(buffer);
+ }
+ return(client->noClientException);
+}
+
+
+ExtensionLookupProc
+LookupProc(char *name, GCPtr pGC)
+{
+ register int i;
+ register ScreenProcEntry *spentry;
+ spentry = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ return(spentry->procList[i].proc);
+ }
+ return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+ return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+ register ScreenProcEntry *spentry;
+ register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+ char *newname;
+ int i;
+
+ spentry = &AuxillaryScreenProcs[pScreen->myNum];
+ /* first replace duplicates */
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ {
+ procEntry = &spentry->procList[i];
+ break;
+ }
+ }
+ if (procEntry)
+ procEntry->proc = proc;
+ else
+ {
+ newname = (char *)xalloc(strlen(name)+1);
+ if (!newname)
+ return FALSE;
+ procEntry = (ProcEntryPtr)
+ xrealloc(spentry->procList,
+ sizeof(ProcEntryRec) * (spentry->num+1));
+ if (!procEntry)
+ {
+ xfree(newname);
+ return FALSE;
+ }
+ spentry->procList = procEntry;
+ procEntry += spentry->num;
+ procEntry->name = newname;
+ strcpy(newname, name);
+ procEntry->proc = proc;
+ spentry->num++;
+ }
+ return TRUE;
+}
diff --git a/xserver/dix/ffs.c b/xserver/dix/ffs.c
new file mode 100644
index 000000000..e25d715dd
--- /dev/null
+++ b/xserver/dix/ffs.c
@@ -0,0 +1,36 @@
+/*
+
+Copyright 1996, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, 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 The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+int
+ffs(int i)
+{
+ int j;
+ for (j = 1; (i & 1) == 0; j++)
+ i >>= 1;
+ return j;
+}
diff --git a/xserver/dix/gc.c b/xserver/dix/gc.c
new file mode 100644
index 000000000..ed6bf26db
--- /dev/null
+++ b/xserver/dix/gc.c
@@ -0,0 +1,1286 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "dix.h"
+#include <assert.h>
+
+extern XID clientErrorValue;
+extern FontPtr defaultFont;
+
+static Bool CreateDefaultTile(GCPtr pGC);
+
+unsigned char DefaultDash[2] = {4, 4};
+
+_X_EXPORT void
+ValidateGC(DrawablePtr pDraw, GC *pGC)
+{
+ (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
+ pGC->stateChanges = 0;
+ pGC->serialNumber = pDraw->serialNumber;
+}
+
+
+/* dixChangeGC(client, pGC, mask, pC32, pUnion)
+ *
+ * This function was created as part of the Security extension
+ * implementation. The client performing the gc change must be passed so
+ * that access checks can be performed on any tiles, stipples, or fonts
+ * that are specified. ddxen can call this too; they should normally
+ * pass NullClient for the client since any access checking should have
+ * already been done at a higher level.
+ *
+ * Since we had to create a new function anyway, we decided to change the
+ * way the list of gc values is passed to eliminate the compiler warnings
+ * caused by the DoChangeGC interface. You can pass the values via pC32
+ * or pUnion, but not both; one of them must be NULL. If you don't need
+ * to pass any pointers, you can use either one:
+ *
+ * example calling dixChangeGC using pC32 parameter
+ *
+ * CARD32 v[2];
+ * v[0] = foreground;
+ * v[1] = background;
+ * dixChangeGC(client, pGC, GCForeground|GCBackground, v, NULL);
+ *
+ * example calling dixChangeGC using pUnion parameter;
+ * same effect as above
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = foreground;
+ * v[1].val = background;
+ * dixChangeGC(client, pGC, GCForeground|GCBackground, NULL, v);
+ *
+ * However, if you need to pass a pointer to a pixmap or font, you MUST
+ * use the pUnion parameter.
+ *
+ * example calling dixChangeGC passing pointers in the value list
+ * v[1].ptr is a pointer to a pixmap
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = FillTiled;
+ * v[1].ptr = pPixmap;
+ * dixChangeGC(client, pGC, GCFillStyle|GCTile, NULL, v);
+ *
+ * Note: we could have gotten by with just the pUnion parameter, but on
+ * 64 bit machines that would have forced us to copy the value list that
+ * comes in the ChangeGC request.
+ *
+ * Ideally, we'd change all the DoChangeGC calls to dixChangeGC, but this
+ * is far too many changes to consider at this time, so we've only
+ * changed the ones that caused compiler warnings. New code should use
+ * dixChangeGC.
+ *
+ * dpw
+ */
+
+#define NEXTVAL(_type, _var) { \
+ if (pC32) _var = (_type)*pC32++; \
+ else { \
+ _var = (_type)(pUnion->val); pUnion++; \
+ } \
+ }
+
+#define NEXT_PTR(_type, _var) { \
+ assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; }
+
+_X_EXPORT int
+dixChangeGC(ClientPtr client, register GC *pGC, register BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion)
+{
+ register BITS32 index2;
+ register int error = 0;
+ PixmapPtr pPixmap;
+ BITS32 maskQ;
+
+ assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ maskQ = mask; /* save these for when we walk the GCque */
+ while (mask && !error)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ pGC->stateChanges |= index2;
+ switch (index2)
+ {
+ case GCFunction:
+ {
+ CARD8 newalu;
+ NEXTVAL(CARD8, newalu);
+ if (newalu <= GXset)
+ pGC->alu = newalu;
+ else
+ {
+ clientErrorValue = newalu;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCPlaneMask:
+ NEXTVAL(unsigned long, pGC->planemask);
+ break;
+ case GCForeground:
+ NEXTVAL(unsigned long, pGC->fgPixel);
+ /*
+ * this is for CreateGC
+ */
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ {
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = pGC->fgPixel;
+ }
+ break;
+ case GCBackground:
+ NEXTVAL(unsigned long, pGC->bgPixel);
+ break;
+ case GCLineWidth: /* ??? line width is a CARD16 */
+ NEXTVAL(CARD16, pGC->lineWidth);
+ break;
+ case GCLineStyle:
+ {
+ unsigned int newlinestyle;
+ NEXTVAL(unsigned int, newlinestyle);
+ if (newlinestyle <= LineDoubleDash)
+ pGC->lineStyle = newlinestyle;
+ else
+ {
+ clientErrorValue = newlinestyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCCapStyle:
+ {
+ unsigned int newcapstyle;
+ NEXTVAL(unsigned int, newcapstyle);
+ if (newcapstyle <= CapProjecting)
+ pGC->capStyle = newcapstyle;
+ else
+ {
+ clientErrorValue = newcapstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCJoinStyle:
+ {
+ unsigned int newjoinstyle;
+ NEXTVAL(unsigned int, newjoinstyle);
+ if (newjoinstyle <= JoinBevel)
+ pGC->joinStyle = newjoinstyle;
+ else
+ {
+ clientErrorValue = newjoinstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillStyle:
+ {
+ unsigned int newfillstyle;
+ NEXTVAL(unsigned int, newfillstyle);
+ if (newfillstyle <= FillOpaqueStippled)
+ pGC->fillStyle = newfillstyle;
+ else
+ {
+ clientErrorValue = newfillstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillRule:
+ {
+ unsigned int newfillrule;
+ NEXTVAL(unsigned int, newfillrule);
+ if (newfillrule <= WindingRule)
+ pGC->fillRule = newfillrule;
+ else
+ {
+ clientErrorValue = newfillrule;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCTile:
+ {
+ XID newpix = 0;
+ if (pUnion)
+ {
+ NEXT_PTR(PixmapPtr, pPixmap);
+ }
+ else
+ {
+ NEXTVAL(XID, newpix);
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ newpix, RT_PIXMAP, SecurityReadAccess);
+ }
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != pGC->depth) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pPixmap;
+ }
+ }
+ else
+ {
+ clientErrorValue = newpix;
+ error = BadPixmap;
+ }
+ break;
+ }
+ case GCStipple:
+ {
+ XID newstipple = 0;
+ if (pUnion)
+ {
+ NEXT_PTR(PixmapPtr, pPixmap);
+ }
+ else
+ {
+ NEXTVAL(XID, newstipple)
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ newstipple, RT_PIXMAP, SecurityReadAccess);
+ }
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+ pGC->stipple = pPixmap;
+ }
+ }
+ else
+ {
+ clientErrorValue = newstipple;
+ error = BadPixmap;
+ }
+ break;
+ }
+ case GCTileStipXOrigin:
+ NEXTVAL(INT16, pGC->patOrg.x);
+ break;
+ case GCTileStipYOrigin:
+ NEXTVAL(INT16, pGC->patOrg.y);
+ break;
+ case GCFont:
+ {
+ FontPtr pFont;
+ XID newfont = 0;
+ if (pUnion)
+ {
+ NEXT_PTR(FontPtr, pFont);
+ }
+ else
+ {
+ NEXTVAL(XID, newfont)
+ pFont = (FontPtr)SecurityLookupIDByType(client, newfont,
+ RT_FONT, SecurityReadAccess);
+ }
+ if (pFont)
+ {
+ pFont->refcnt++;
+ if (pGC->font)
+ CloseFont(pGC->font, (Font)0);
+ pGC->font = pFont;
+ }
+ else
+ {
+ clientErrorValue = newfont;
+ error = BadFont;
+ }
+ break;
+ }
+ case GCSubwindowMode:
+ {
+ unsigned int newclipmode;
+ NEXTVAL(unsigned int, newclipmode);
+ if (newclipmode <= IncludeInferiors)
+ pGC->subWindowMode = newclipmode;
+ else
+ {
+ clientErrorValue = newclipmode;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCGraphicsExposures:
+ {
+ unsigned int newge;
+ NEXTVAL(unsigned int, newge);
+ if (newge <= xTrue)
+ pGC->graphicsExposures = newge;
+ else
+ {
+ clientErrorValue = newge;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCClipXOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.x);
+ break;
+ case GCClipYOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.y);
+ break;
+ case GCClipMask:
+ {
+ Pixmap pid = 0;
+ int clipType = 0;
+
+ if (pUnion)
+ {
+ NEXT_PTR(PixmapPtr, pPixmap);
+ }
+ else
+ {
+ NEXTVAL(Pixmap, pid)
+ if (pid == None)
+ {
+ clipType = CT_NONE;
+ pPixmap = NullPixmap;
+ }
+ else
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ pid, RT_PIXMAP, SecurityReadAccess);
+ }
+
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap->refcnt++;
+ }
+ }
+ else if (!pUnion && (pid != None))
+ {
+ clientErrorValue = pid;
+ error = BadPixmap;
+ }
+ if(error == Success)
+ {
+ (*pGC->funcs->ChangeClip)(pGC, clipType,
+ (pointer)pPixmap, 0);
+ }
+ break;
+ }
+ case GCDashOffset:
+ NEXTVAL(INT16, pGC->dashOffset);
+ break;
+ case GCDashList:
+ {
+ CARD8 newdash;
+ NEXTVAL(CARD8, newdash);
+ if (newdash == 4)
+ {
+ if (pGC->dash != DefaultDash)
+ {
+ xfree(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ }
+ }
+ else if (newdash != 0)
+ {
+ unsigned char *dash;
+
+ dash = (unsigned char *)xalloc(2 * sizeof(unsigned char));
+ if (dash)
+ {
+ if (pGC->dash != DefaultDash)
+ xfree(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = dash;
+ dash[0] = newdash;
+ dash[1] = newdash;
+ }
+ else
+ error = BadAlloc;
+ }
+ else
+ {
+ clientErrorValue = newdash;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCArcMode:
+ {
+ unsigned int newarcmode;
+ NEXTVAL(unsigned int, newarcmode);
+ if (newarcmode <= ArcPieSlice)
+ pGC->arcMode = newarcmode;
+ else
+ {
+ clientErrorValue = newarcmode;
+ error = BadValue;
+ }
+ break;
+ }
+ default:
+ clientErrorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ } /* end while mask && !error */
+
+ if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pGC))
+ {
+ pGC->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pGC->funcs->ChangeGC)(pGC, maskQ);
+ return error;
+}
+
+#undef NEXTVAL
+#undef NEXT_PTR
+
+/* Publically defined entry to ChangeGC. Just calls dixChangeGC and tells
+ * it that all of the entries are constants or IDs */
+_X_EXPORT int
+ChangeGC(register GC *pGC, register BITS32 mask, XID *pval)
+{
+ return (dixChangeGC(NullClient, pGC, mask, pval, NULL));
+}
+
+/* DoChangeGC(pGC, mask, pval, fPointer)
+ mask is a set of bits indicating which values to change.
+ pval contains an appropriate value for each mask.
+ fPointer is true if the values for tiles, stipples, fonts or clipmasks
+ are pointers instead of IDs. Note: if you are passing pointers you
+ MUST declare the array of values as type pointer! Other data types
+ may not be large enough to hold pointers on some machines. Yes,
+ this means you have to cast to (XID *) when you pass the array to
+ DoChangeGC. Similarly, if you are not passing pointers (fPointer = 0) you
+ MUST declare the array as type XID (not unsigned long!), or again the wrong
+ size data type may be used. To avoid this cruftiness, use dixChangeGC
+ above.
+
+ if there is an error, the value is marked as changed
+ anyway, which is probably wrong, but infrequent.
+
+NOTE:
+ all values sent over the protocol for ChangeGC requests are
+32 bits long
+*/
+_X_EXPORT int
+DoChangeGC(register GC *pGC, register BITS32 mask, XID *pval, int fPointer)
+{
+ if (fPointer)
+ /* XXX might be a problem on 64 bit big-endian servers */
+ return dixChangeGC(NullClient, pGC, mask, NULL, (ChangeGCValPtr)pval);
+ else
+ return dixChangeGC(NullClient, pGC, mask, pval, NULL);
+}
+
+
+/* CreateGC(pDrawable, mask, pval, pStatus)
+ creates a default GC for the given drawable, using mask to fill
+ in any non-default values.
+ Returns a pointer to the new GC on success, NULL otherwise.
+ returns status of non-default fields in pStatus
+BUG:
+ should check for failure to create default tile
+
+*/
+
+static GCPtr
+AllocateGC(ScreenPtr pScreen)
+{
+ GCPtr pGC;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ pGC = (GCPtr)xalloc(pScreen->totalGCSize);
+ if (pGC)
+ {
+ ppriv = (DevUnion *)(pGC + 1);
+ pGC->devPrivates = ppriv;
+ sizes = pScreen->GCPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->GCPrivateLen);
+ for (i = pScreen->GCPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ }
+ return pGC;
+}
+
+_X_EXPORT GCPtr
+CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus)
+{
+ register GCPtr pGC;
+
+ pGC = AllocateGC(pDrawable->pScreen);
+ if (!pGC)
+ {
+ *pStatus = BadAlloc;
+ return (GCPtr)NULL;
+ }
+
+ pGC->pScreen = pDrawable->pScreen;
+ pGC->depth = pDrawable->depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pGC->funcs = 0;
+
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ if (mask & GCForeground)
+ {
+ /*
+ * magic special case -- ChangeGC checks for this condition
+ * and snags the Foreground value to create a pseudo default-tile
+ */
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = NullPixmap;
+ }
+ else
+ {
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ }
+
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = (pointer)NULL;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->dashOffset = 0;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ /* use the default font and stipple */
+ pGC->font = defaultFont;
+ defaultFont->refcnt++;
+ pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
+ pGC->stipple->refcnt++;
+
+ pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
+ if (!(*pGC->pScreen->CreateGC)(pGC))
+ *pStatus = BadAlloc;
+ else if (mask)
+ *pStatus = ChangeGC(pGC, mask, pval);
+ else
+ *pStatus = Success;
+ if (*pStatus != Success)
+ {
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ pGC->tileIsPixel = TRUE; /* undo special case */
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+
+ return (pGC);
+}
+
+static Bool
+CreateDefaultTile (GCPtr pGC)
+{
+ XID tmpval[3];
+ PixmapPtr pTile;
+ GCPtr pgcScratch;
+ xRectangle rect;
+ CARD16 w, h;
+
+ w = 1;
+ h = 1;
+ (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
+ pTile = (PixmapPtr)
+ (*pGC->pScreen->CreatePixmap)(pGC->pScreen,
+ w, h, pGC->depth);
+ pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
+ if (!pTile || !pgcScratch)
+ {
+ if (pTile)
+ (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
+ if (pgcScratch)
+ FreeScratchGC(pgcScratch);
+ return FALSE;
+ }
+ tmpval[0] = GXcopy;
+ tmpval[1] = pGC->tile.pixel;
+ tmpval[2] = FillSolid;
+ (void)ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle,
+ tmpval);
+ ValidateGC((DrawablePtr)pTile, pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
+ /* Always remember to free the scratch graphics context after use. */
+ FreeScratchGC(pgcScratch);
+
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pTile;
+ return TRUE;
+}
+
+_X_EXPORT int
+CopyGC(register GC *pgcSrc, register GC *pgcDst, register BITS32 mask)
+{
+ register BITS32 index2;
+ BITS32 maskQ;
+ int error = 0;
+
+ if (pgcSrc == pgcDst)
+ return Success;
+ pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgcDst->stateChanges |= mask;
+ maskQ = mask;
+ while (mask)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ switch (index2)
+ {
+ case GCFunction:
+ pgcDst->alu = pgcSrc->alu;
+ break;
+ case GCPlaneMask:
+ pgcDst->planemask = pgcSrc->planemask;
+ break;
+ case GCForeground:
+ pgcDst->fgPixel = pgcSrc->fgPixel;
+ break;
+ case GCBackground:
+ pgcDst->bgPixel = pgcSrc->bgPixel;
+ break;
+ case GCLineWidth:
+ pgcDst->lineWidth = pgcSrc->lineWidth;
+ break;
+ case GCLineStyle:
+ pgcDst->lineStyle = pgcSrc->lineStyle;
+ break;
+ case GCCapStyle:
+ pgcDst->capStyle = pgcSrc->capStyle;
+ break;
+ case GCJoinStyle:
+ pgcDst->joinStyle = pgcSrc->joinStyle;
+ break;
+ case GCFillStyle:
+ pgcDst->fillStyle = pgcSrc->fillStyle;
+ break;
+ case GCFillRule:
+ pgcDst->fillRule = pgcSrc->fillRule;
+ break;
+ case GCTile:
+ {
+ if (EqualPixUnion(pgcDst->tileIsPixel,
+ pgcDst->tile,
+ pgcSrc->tileIsPixel,
+ pgcSrc->tile))
+ {
+ break;
+ }
+ if (!pgcDst->tileIsPixel)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
+ pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
+ pgcDst->tile = pgcSrc->tile;
+ if (!pgcDst->tileIsPixel)
+ pgcDst->tile.pixmap->refcnt++;
+ break;
+ }
+ case GCStipple:
+ {
+ if (pgcDst->stipple == pgcSrc->stipple)
+ break;
+ if (pgcDst->stipple)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
+ pgcDst->stipple = pgcSrc->stipple;
+ if (pgcDst->stipple)
+ pgcDst->stipple->refcnt ++;
+ break;
+ }
+ case GCTileStipXOrigin:
+ pgcDst->patOrg.x = pgcSrc->patOrg.x;
+ break;
+ case GCTileStipYOrigin:
+ pgcDst->patOrg.y = pgcSrc->patOrg.y;
+ break;
+ case GCFont:
+ if (pgcDst->font == pgcSrc->font)
+ break;
+ if (pgcDst->font)
+ CloseFont(pgcDst->font, (Font)0);
+ if ((pgcDst->font = pgcSrc->font) != NullFont)
+ (pgcDst->font)->refcnt++;
+ break;
+ case GCSubwindowMode:
+ pgcDst->subWindowMode = pgcSrc->subWindowMode;
+ break;
+ case GCGraphicsExposures:
+ pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
+ break;
+ case GCClipXOrigin:
+ pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
+ break;
+ case GCClipYOrigin:
+ pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
+ break;
+ case GCClipMask:
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ break;
+ case GCDashOffset:
+ pgcDst->dashOffset = pgcSrc->dashOffset;
+ break;
+ case GCDashList:
+ if (pgcSrc->dash == DefaultDash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ {
+ xfree(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = pgcSrc->dash;
+ }
+ }
+ else
+ {
+ unsigned char *dash;
+ unsigned int i;
+
+ dash = (unsigned char *)xalloc(pgcSrc->numInDashList *
+ sizeof(unsigned char));
+ if (dash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ xfree(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = dash;
+ for (i=0; i<pgcSrc->numInDashList; i++)
+ dash[i] = pgcSrc->dash[i];
+ }
+ else
+ error = BadAlloc;
+ }
+ break;
+ case GCArcMode:
+ pgcDst->arcMode = pgcSrc->arcMode;
+ break;
+ default:
+ clientErrorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ }
+ if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pgcDst))
+ {
+ pgcDst->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
+ return error;
+}
+
+/**
+ * does the diX part of freeing the characteristics in the GC.
+ *
+ * \param value must conform to DeleteType
+ */
+_X_EXPORT int
+FreeGC(pointer value, XID gid)
+{
+ GCPtr pGC = (GCPtr)value;
+
+ CloseFont(pGC->font, (Font)0);
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+ if (pGC->dash != DefaultDash)
+ xfree(pGC->dash);
+ xfree(pGC);
+ return(Success);
+}
+
+void
+SetGCMask(GCPtr pGC, Mask selectMask, Mask newDataMask)
+{
+ pGC->stateChanges = (~selectMask & pGC->stateChanges) |
+ (selectMask & newDataMask);
+ if (selectMask & newDataMask)
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+}
+
+
+
+/* CreateScratchGC(pScreen, depth)
+ like CreateGC, but doesn't do the default tile or stipple,
+since we can't create them without already having a GC. any code
+using the tile or stipple has to set them explicitly anyway,
+since the state of the scratch gc is unknown. This is OK
+because ChangeGC() has to be able to deal with NULL tiles and
+stipples anyway (in case the CreateGC() call has provided a
+value for them -- we can't set the default tile until the
+client-supplied attributes are installed, since the fgPixel
+is what fills the default tile. (maybe this comment should
+go with CreateGC() or ChangeGC().)
+*/
+
+_X_EXPORT GCPtr
+CreateScratchGC(ScreenPtr pScreen, unsigned depth)
+{
+ register GCPtr pGC;
+
+ pGC = AllocateGC(pScreen);
+ if (!pGC)
+ return (GCPtr)NULL;
+
+ pGC->pScreen = pScreen;
+ pGC->depth = depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ pGC->font = defaultFont;
+ if ( pGC->font) /* necessary, because open of default font could fail */
+ pGC->font->refcnt++;
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->dashOffset = 0;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
+ if (!(*pScreen->CreateGC)(pGC))
+ {
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+ return pGC;
+}
+
+void
+FreeGCperDepth(int screenNum)
+{
+ register int i;
+ register ScreenPtr pScreen;
+ GCPtr *ppGC;
+
+ pScreen = screenInfo.screens[screenNum];
+ ppGC = pScreen->GCperDepth;
+
+ for (i = 0; i <= pScreen->numDepths; i++)
+ (void)FreeGC(ppGC[i], (XID)0);
+ pScreen->rgf = ~0L;
+}
+
+
+Bool
+CreateGCperDepth(int screenNum)
+{
+ register int i;
+ register ScreenPtr pScreen;
+ DepthPtr pDepth;
+ GCPtr *ppGC;
+
+ pScreen = screenInfo.screens[screenNum];
+ pScreen->rgf = 0;
+ ppGC = pScreen->GCperDepth;
+ /* do depth 1 separately because it's not included in list */
+ if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
+ return FALSE;
+ ppGC[0]->graphicsExposures = FALSE;
+ /* Make sure we don't overflow GCperDepth[] */
+ if( pScreen->numDepths > MAXFORMATS )
+ return FALSE;
+
+ pDepth = pScreen->allowedDepths;
+ for (i=0; i<pScreen->numDepths; i++, pDepth++)
+ {
+ if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
+ {
+ for (; i >= 0; i--)
+ (void)FreeGC(ppGC[i], (XID)0);
+ return FALSE;
+ }
+ ppGC[i+1]->graphicsExposures = FALSE;
+ }
+ return TRUE;
+}
+
+Bool
+CreateDefaultStipple(int screenNum)
+{
+ register ScreenPtr pScreen;
+ XID tmpval[3];
+ xRectangle rect;
+ CARD16 w, h;
+ GCPtr pgcScratch;
+
+ pScreen = screenInfo.screens[screenNum];
+
+ w = 16;
+ h = 16;
+ (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
+ if (!(pScreen->PixmapPerDepth[0] =
+ (*pScreen->CreatePixmap)(pScreen, w, h, 1)))
+ return FALSE;
+ /* fill stipple with 1 */
+ tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
+ pgcScratch = GetScratchGC(1, pScreen);
+ if (!pgcScratch)
+ {
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+ return FALSE;
+ }
+ (void)ChangeGC(pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
+ ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
+ pgcScratch, 1, &rect);
+ FreeScratchGC(pgcScratch);
+ return TRUE;
+}
+
+void
+FreeDefaultStipple(int screenNum)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+}
+
+_X_EXPORT int
+SetDashes(register GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
+{
+ register long i;
+ register unsigned char *p, *indash;
+ BITS32 maskQ = 0;
+
+ i = ndash;
+ p = pdash;
+ while (i--)
+ {
+ if (!*p++)
+ {
+ /* dash segment must be > 0 */
+ clientErrorValue = 0;
+ return BadValue;
+ }
+ }
+
+ if (ndash & 1)
+ p = (unsigned char *)xalloc(2 * ndash * sizeof(unsigned char));
+ else
+ p = (unsigned char *)xalloc(ndash * sizeof(unsigned char));
+ if (!p)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ if (offset != pGC->dashOffset)
+ {
+ pGC->dashOffset = offset;
+ pGC->stateChanges |= GCDashOffset;
+ maskQ |= GCDashOffset;
+ }
+
+ if (pGC->dash != DefaultDash)
+ xfree(pGC->dash);
+ pGC->numInDashList = ndash;
+ pGC->dash = p;
+ if (ndash & 1)
+ {
+ pGC->numInDashList += ndash;
+ indash = pdash;
+ i = ndash;
+ while (i--)
+ *p++ = *indash++;
+ }
+ while(ndash--)
+ *p++ = *pdash++;
+ pGC->stateChanges |= GCDashList;
+ maskQ |= GCDashList;
+
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, maskQ);
+ return Success;
+}
+
+_X_EXPORT int
+VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
+{
+ register xRectangle *prectP, *prectN;
+ register int i;
+
+ switch(ordering)
+ {
+ case Unsorted:
+ return CT_UNSORTED;
+ case YSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if(prectN->y < prectP->y)
+ return -1;
+ }
+ return CT_YSORTED;
+ case YXSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y < prectP->y) ||
+ ( (prectN->y == prectP->y) &&
+ (prectN->x < prectP->x) ) )
+ return -1;
+ }
+ return CT_YXSORTED;
+ case YXBanded:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y != prectP->y &&
+ prectN->y < prectP->y + (int) prectP->height) ||
+ ((prectN->y == prectP->y) &&
+ (prectN->height != prectP->height ||
+ prectN->x < prectP->x + (int) prectP->width)))
+ return -1;
+ }
+ return CT_YXBANDED;
+ }
+ return -1;
+}
+
+_X_EXPORT int
+SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
+ xRectangle *prects, int ordering)
+{
+ int newct, size;
+ xRectangle *prectsNew;
+
+ newct = VerifyRectOrder(nrects, prects, ordering);
+ if (newct < 0)
+ return(BadMatch);
+ size = nrects * sizeof(xRectangle);
+ prectsNew = (xRectangle *) xalloc(size);
+ if (!prectsNew && size)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->clipOrg.x = xOrigin;
+ pGC->stateChanges |= GCClipXOrigin;
+
+ pGC->clipOrg.y = yOrigin;
+ pGC->stateChanges |= GCClipYOrigin;
+
+ if (size)
+ memmove((char *)prectsNew, (char *)prects, size);
+ (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects);
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
+ return Success;
+}
+
+
+/*
+ sets reasonable defaults
+ if we can get a pre-allocated one, use it and mark it as used.
+ if we can't, create one out of whole cloth (The Velveteen GC -- if
+ you use it often enough it will become real.)
+*/
+_X_EXPORT GCPtr
+GetScratchGC(register unsigned depth, register ScreenPtr pScreen)
+{
+ register int i;
+ register GCPtr pGC;
+
+ for (i=0; i<=pScreen->numDepths; i++)
+ if ( pScreen->GCperDepth[i]->depth == depth &&
+ !(pScreen->rgf & (1L << (i+1)))
+ )
+ {
+ pScreen->rgf |= (1L << (i+1));
+ pGC = (pScreen->GCperDepth[i]);
+
+ pGC->alu = GXcopy;
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcChord;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = FALSE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ if (pGC->clientClipType != CT_NONE)
+ (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
+ pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
+ return pGC;
+ }
+ /* if we make it this far, need to roll our own */
+ pGC = CreateScratchGC(pScreen, depth);
+ if (pGC)
+ pGC->graphicsExposures = FALSE;
+ return pGC;
+}
+
+/*
+ if the gc to free is in the table of pre-existing ones,
+mark it as available.
+ if not, free it for real
+*/
+_X_EXPORT void
+FreeScratchGC(register GCPtr pGC)
+{
+ register ScreenPtr pScreen = pGC->pScreen;
+ register int i;
+
+ for (i=0; i<=pScreen->numDepths; i++)
+ {
+ if ( pScreen->GCperDepth[i] == pGC)
+ {
+ pScreen->rgf &= ~(1L << (i+1));
+ return;
+ }
+ }
+ (void)FreeGC(pGC, (GContext)0);
+}
diff --git a/xserver/dix/globals.c b/xserver/dix/globals.c
new file mode 100644
index 000000000..f86c6026d
--- /dev/null
+++ b/xserver/dix/globals.c
@@ -0,0 +1,161 @@
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "misc.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "input.h"
+#include "dixfont.h"
+#include "site.h"
+#include "dixstruct.h"
+#include "os.h"
+
+_X_EXPORT ScreenInfo screenInfo;
+KeybdCtrl defaultKeyboardControl = {
+ DEFAULT_KEYBOARD_CLICK,
+ DEFAULT_BELL,
+ DEFAULT_BELL_PITCH,
+ DEFAULT_BELL_DURATION,
+ DEFAULT_AUTOREPEAT,
+ DEFAULT_AUTOREPEATS,
+ DEFAULT_LEDS,
+ 0};
+
+PtrCtrl defaultPointerControl = {
+ DEFAULT_PTR_NUMERATOR,
+ DEFAULT_PTR_DENOMINATOR,
+ DEFAULT_PTR_THRESHOLD,
+ 0};
+
+_X_EXPORT ClientPtr *clients;
+_X_EXPORT ClientPtr serverClient;
+_X_EXPORT int currentMaxClients; /* current size of clients array */
+_X_EXPORT long maxBigRequestSize = MAX_BIG_REQUEST_SIZE;
+
+_X_EXPORT WindowPtr *WindowTable;
+
+_X_EXPORT unsigned long globalSerialNumber = 0;
+_X_EXPORT unsigned long serverGeneration = 0;
+
+/* these next four are initialized in main.c */
+_X_EXPORT CARD32 ScreenSaverTime;
+CARD32 ScreenSaverInterval;
+_X_EXPORT int ScreenSaverBlanking;
+int ScreenSaverAllowExposures;
+
+#ifdef DPMSExtension
+# ifndef DEFAULT_STANDBY_TIME
+# define DEFAULT_STANDBY_TIME DEFAULT_SCREEN_SAVER_TIME * 2
+# endif
+# ifndef DEFAULT_SUSPEND_TIME
+# define DEFAULT_SUSPEND_TIME DEFAULT_SCREEN_SAVER_TIME * 3
+# endif
+# ifndef DEFAULT_OFF_TIME
+# define DEFAULT_OFF_TIME DEFAULT_SCREEN_SAVER_TIME * 4
+# endif
+# ifndef DEFAULT_DPMS_ENABLED
+# define DEFAULT_DPMS_ENABLED TRUE
+# endif
+CARD32 defaultDPMSStandbyTime = DEFAULT_STANDBY_TIME;
+CARD32 defaultDPMSSuspendTime = DEFAULT_SUSPEND_TIME;
+CARD32 defaultDPMSOffTime = DEFAULT_OFF_TIME;
+_X_EXPORT CARD16 DPMSPowerLevel = 0;
+_X_EXPORT Bool defaultDPMSEnabled = DEFAULT_DPMS_ENABLED;
+_X_EXPORT Bool DPMSEnabledSwitch = FALSE; /* these denote the DPMS command */
+_X_EXPORT Bool DPMSDisabledSwitch = FALSE; /* lind switch states */
+_X_EXPORT Bool DPMSCapableFlag = FALSE;
+_X_EXPORT CARD32 DPMSStandbyTime;
+_X_EXPORT CARD32 DPMSSuspendTime;
+_X_EXPORT CARD32 DPMSOffTime;
+_X_EXPORT Bool DPMSEnabled;
+#endif
+
+CARD32 defaultScreenSaverTime = DEFAULT_SCREEN_SAVER_TIME;
+CARD32 defaultScreenSaverInterval = DEFAULT_SCREEN_SAVER_INTERVAL;
+int defaultScreenSaverBlanking = DEFAULT_SCREEN_SAVER_BLANKING;
+int defaultScreenSaverAllowExposures = DEFAULT_SCREEN_SAVER_EXPOSURES;
+#ifndef NOLOGOHACK
+int logoScreenSaver = DEFAULT_LOGO_SCREEN_SAVER;
+#endif
+
+#ifdef SCREENSAVER
+Bool screenSaverSuspended = FALSE;
+#endif
+
+char *defaultFontPath = COMPILEDDEFAULTFONTPATH;
+char *defaultTextFont = COMPILEDDEFAULTFONT;
+char *defaultCursorFont = COMPILEDCURSORFONT;
+char *rgbPath = RGB_DB;
+char *defaultDisplayClass = COMPILEDDISPLAYCLASS;
+FontPtr defaultFont; /* not declared in dix.h to avoid including font.h in
+ every compilation of dix code */
+Bool loadableFonts = FALSE;
+CursorPtr rootCursor;
+Bool blackRoot=FALSE;
+Bool whiteRoot=FALSE;
+ClientPtr requestingClient; /* XXX this should be obsolete now, remove? */
+
+_X_EXPORT TimeStamp currentTime;
+_X_EXPORT TimeStamp lastDeviceEventTime;
+
+_X_EXPORT int defaultColorVisualClass = -1;
+_X_EXPORT int monitorResolution = 0;
+
+_X_EXPORT char *display;
+
+CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
+int argcGlobal;
+char **argvGlobal;
+
+DDXPointRec dixScreenOrigins[MAXSCREENS];
diff --git a/xserver/dix/glyphcurs.c b/xserver/dix/glyphcurs.c
new file mode 100644
index 000000000..c1c545fa9
--- /dev/null
+++ b/xserver/dix/glyphcurs.c
@@ -0,0 +1,193 @@
+/************************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+
+/*
+ get the bits out of the font in a portable way. to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+ since all screens return the same bitmap format, we'll just use
+the first one we find.
+ the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+ register ScreenPtr pScreen;
+ register GCPtr pGC;
+ xRectangle rect;
+ PixmapPtr ppix;
+ long nby;
+ char *pbits;
+ ChangeGCVal gcval[3];
+ unsigned char char2b[2];
+
+ /* turn glyph index into a protocol-format char2b */
+ char2b[0] = (unsigned char)(ch >> 8);
+ char2b[1] = (unsigned char)(ch & 0xff);
+
+ pScreen = screenInfo.screens[0];
+ nby = BitmapBytePad(cm->width) * (long)cm->height;
+ pbits = (char *)xalloc(nby);
+ if (!pbits)
+ return BadAlloc;
+ /* zeroing the (pad) bits seems to help some ddx cursor handling */
+ bzero(pbits, nby);
+
+ ppix = (PixmapPtr)(*pScreen->CreatePixmap)(pScreen, cm->width,
+ cm->height, 1);
+ pGC = GetScratchGC(1, pScreen);
+ if (!ppix || !pGC)
+ {
+ if (ppix)
+ (*pScreen->DestroyPixmap)(ppix);
+ if (pGC)
+ FreeScratchGC(pGC);
+ xfree(pbits);
+ return BadAlloc;
+ }
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = cm->width;
+ rect.height = cm->height;
+
+ /* fill the pixmap with 0 */
+ gcval[0].val = GXcopy;
+ gcval[1].val = 0;
+ gcval[2].ptr = (pointer)pfont;
+ dixChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont,
+ NULL, gcval);
+ ValidateGC((DrawablePtr)ppix, pGC);
+ (*pGC->ops->PolyFillRect)((DrawablePtr)ppix, pGC, 1, &rect);
+
+ /* draw the glyph */
+ gcval[0].val = 1;
+ dixChangeGC(NullClient, pGC, GCForeground, NULL, gcval);
+ ValidateGC((DrawablePtr)ppix, pGC);
+ (*pGC->ops->PolyText16)((DrawablePtr)ppix, pGC, cm->xhot, cm->yhot,
+ 1, (unsigned short *)char2b);
+ (*pScreen->GetImage)((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+ XYPixmap, 1, pbits);
+ *ppbits = (unsigned char *)pbits;
+ FreeScratchGC(pGC);
+ (*pScreen->DestroyPixmap)(ppix);
+ return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+ CharInfoPtr pci;
+ unsigned long nglyphs;
+ CARD8 chs[2];
+ FontEncoding encoding;
+
+ chs[0] = ch >> 8;
+ chs[1] = ch;
+ encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+ if (encoding == Linear16Bit)
+ {
+ if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+ return FALSE;
+ }
+ else
+ {
+ if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+ return FALSE;
+ if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+ return FALSE;
+ }
+ (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+ if (nglyphs == 0)
+ return FALSE;
+ cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ cm->height = pci->metrics.descent + pci->metrics.ascent;
+ if (pci->metrics.leftSideBearing > 0)
+ {
+ cm->width += pci->metrics.leftSideBearing;
+ cm->xhot = 0;
+ }
+ else
+ {
+ cm->xhot = -pci->metrics.leftSideBearing;
+ if (pci->metrics.rightSideBearing < 0)
+ cm->width -= pci->metrics.rightSideBearing;
+ }
+ if (pci->metrics.ascent < 0)
+ {
+ cm->height -= pci->metrics.ascent;
+ cm->yhot = 0;
+ }
+ else
+ {
+ cm->yhot = pci->metrics.ascent;
+ if (pci->metrics.descent < 0)
+ cm->height -= pci->metrics.descent;
+ }
+ return TRUE;
+}
diff --git a/xserver/dix/grabs.c b/xserver/dix/grabs.c
new file mode 100644
index 000000000..0c2b05e89
--- /dev/null
+++ b/xserver/dix/grabs.c
@@ -0,0 +1,436 @@
+/*
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE OPEN GROUP 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 The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "cursorstr.h"
+#include "dixgrabs.h"
+
+#define BITMASK(i) (((Mask)1) << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+GrabPtr
+CreateGrab(
+ int client,
+ DeviceIntPtr device,
+ WindowPtr window,
+ Mask eventMask,
+ Bool ownerEvents, Bool keyboardMode, Bool pointerMode,
+ DeviceIntPtr modDevice,
+ unsigned short modifiers,
+ int type,
+ KeyCode keybut, /* key or button */
+ WindowPtr confineTo,
+ CursorPtr cursor)
+{
+ GrabPtr grab;
+
+ grab = (GrabPtr)xalloc(sizeof(GrabRec));
+ if (!grab)
+ return (GrabPtr)NULL;
+ grab->resource = FakeClientID(client);
+ grab->device = device;
+ grab->coreGrab = ((device == inputInfo.keyboard) ||
+ (device == inputInfo.pointer));
+ grab->window = window;
+ grab->eventMask = eventMask;
+ grab->ownerEvents = ownerEvents;
+ grab->keyboardMode = keyboardMode;
+ grab->pointerMode = pointerMode;
+ grab->modifiersDetail.exact = modifiers;
+ grab->modifiersDetail.pMask = NULL;
+ grab->modifierDevice = modDevice;
+ grab->coreMods = ((modDevice == inputInfo.keyboard) ||
+ (modDevice == inputInfo.pointer));
+ grab->type = type;
+ grab->detail.exact = keybut;
+ grab->detail.pMask = NULL;
+ grab->confineTo = confineTo;
+ grab->cursor = cursor;
+ if (cursor)
+ cursor->refcnt++;
+ return grab;
+
+}
+
+static void
+FreeGrab(GrabPtr pGrab)
+{
+ if (pGrab->modifiersDetail.pMask != NULL)
+ xfree(pGrab->modifiersDetail.pMask);
+
+ if (pGrab->detail.pMask != NULL)
+ xfree(pGrab->detail.pMask);
+
+ if (pGrab->cursor)
+ FreeCursor(pGrab->cursor, (Cursor)0);
+
+ xfree(pGrab);
+}
+
+int
+DeletePassiveGrab(pointer value, XID id)
+{
+ register GrabPtr g, prev;
+ GrabPtr pGrab = (GrabPtr)value;
+
+ /* it is OK if the grab isn't found */
+ prev = 0;
+ for (g = (wPassiveGrabs (pGrab->window)); g; g = g->next)
+ {
+ if (pGrab == g)
+ {
+ if (prev)
+ prev->next = g->next;
+ else
+ if (!(pGrab->window->optional->passiveGrabs = g->next))
+ CheckWindowOptionalNeed (pGrab->window);
+ break;
+ }
+ prev = g;
+ }
+ FreeGrab(pGrab);
+ return Success;
+}
+
+static Mask *
+DeleteDetailFromMask(Mask *pDetailMask, unsigned short detail)
+{
+ register Mask *mask;
+ register int i;
+
+ mask = (Mask *)xalloc(sizeof(Mask) * MasksPerDetailMask);
+ if (mask)
+ {
+ if (pDetailMask)
+ for (i = 0; i < MasksPerDetailMask; i++)
+ mask[i]= pDetailMask[i];
+ else
+ for (i = 0; i < MasksPerDetailMask; i++)
+ mask[i]= ~0L;
+ BITCLEAR(mask, detail);
+ }
+ return mask;
+}
+
+static Bool
+IsInGrabMask(
+ DetailRec firstDetail,
+ DetailRec secondDetail,
+ unsigned short exception)
+{
+ if (firstDetail.exact == exception)
+ {
+ if (firstDetail.pMask == NULL)
+ return TRUE;
+
+ /* (at present) never called with two non-null pMasks */
+ if (secondDetail.exact == exception)
+ return FALSE;
+
+ if (GETBIT(firstDetail.pMask, secondDetail.exact))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Bool
+IdenticalExactDetails(
+ unsigned short firstExact,
+ unsigned short secondExact,
+ unsigned short exception)
+{
+ if ((firstExact == exception) || (secondExact == exception))
+ return FALSE;
+
+ if (firstExact == secondExact)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
+DetailSupersedesSecond(
+ DetailRec firstDetail,
+ DetailRec secondDetail,
+ unsigned short exception)
+{
+ if (IsInGrabMask(firstDetail, secondDetail, exception))
+ return TRUE;
+
+ if (IdenticalExactDetails(firstDetail.exact, secondDetail.exact,
+ exception))
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
+GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
+{
+ if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail,
+ pSecondGrab->modifiersDetail,
+ (unsigned short)AnyModifier))
+ return FALSE;
+
+ if (DetailSupersedesSecond(pFirstGrab->detail,
+ pSecondGrab->detail, (unsigned short)AnyKey))
+ return TRUE;
+
+ return FALSE;
+}
+
+Bool
+GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
+{
+ if ((pFirstGrab->device != pSecondGrab->device) ||
+ (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
+ (pFirstGrab->type != pSecondGrab->type))
+ return FALSE;
+
+ if (GrabSupersedesSecond(pFirstGrab, pSecondGrab) ||
+ GrabSupersedesSecond(pSecondGrab, pFirstGrab))
+ return TRUE;
+
+ if (DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail,
+ (unsigned short)AnyKey)
+ &&
+ DetailSupersedesSecond(pFirstGrab->modifiersDetail,
+ pSecondGrab->modifiersDetail,
+ (unsigned short)AnyModifier))
+ return TRUE;
+
+ if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail,
+ (unsigned short)AnyKey)
+ &&
+ DetailSupersedesSecond(pSecondGrab->modifiersDetail,
+ pFirstGrab->modifiersDetail,
+ (unsigned short)AnyModifier))
+ return TRUE;
+
+ return FALSE;
+}
+
+int
+AddPassiveGrabToList(GrabPtr pGrab)
+{
+ GrabPtr grab;
+
+ for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next)
+ {
+ if (GrabMatchesSecond(pGrab, grab))
+ {
+ if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource))
+ {
+ FreeGrab(pGrab);
+ return BadAccess;
+ }
+ }
+ }
+
+ if (!pGrab->window->optional && !MakeWindowOptional (pGrab->window))
+ {
+ FreeGrab(pGrab);
+ return BadAlloc;
+ }
+ pGrab->next = pGrab->window->optional->passiveGrabs;
+ pGrab->window->optional->passiveGrabs = pGrab;
+ if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (pointer)pGrab))
+ return Success;
+ return BadAlloc;
+}
+
+/* the following is kinda complicated, because we need to be able to back out
+ * if any allocation fails
+ */
+
+Bool
+DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
+{
+ register GrabPtr grab;
+ GrabPtr *deletes, *adds;
+ Mask ***updates, **details;
+ int i, ndels, nadds, nups;
+ Bool ok;
+
+#define UPDATE(mask,exact) \
+ if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \
+ ok = FALSE; \
+ else \
+ updates[nups++] = &(mask)
+
+ i = 0;
+ for (grab = wPassiveGrabs(pMinuendGrab->window); grab; grab = grab->next)
+ i++;
+ if (!i)
+ return TRUE;
+ deletes = (GrabPtr *)ALLOCATE_LOCAL(i * sizeof(GrabPtr));
+ adds = (GrabPtr *)ALLOCATE_LOCAL(i * sizeof(GrabPtr));
+ updates = (Mask ***)ALLOCATE_LOCAL(i * sizeof(Mask **));
+ details = (Mask **)ALLOCATE_LOCAL(i * sizeof(Mask *));
+ if (!deletes || !adds || !updates || !details)
+ {
+ if (details) DEALLOCATE_LOCAL(details);
+ if (updates) DEALLOCATE_LOCAL(updates);
+ if (adds) DEALLOCATE_LOCAL(adds);
+ if (deletes) DEALLOCATE_LOCAL(deletes);
+ return FALSE;
+ }
+ ndels = nadds = nups = 0;
+ ok = TRUE;
+ for (grab = wPassiveGrabs(pMinuendGrab->window);
+ grab && ok;
+ grab = grab->next)
+ {
+ if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) ||
+ !GrabMatchesSecond(grab, pMinuendGrab))
+ continue;
+ if (GrabSupersedesSecond(pMinuendGrab, grab))
+ {
+ deletes[ndels++] = grab;
+ }
+ else if ((grab->detail.exact == AnyKey)
+ && (grab->modifiersDetail.exact != AnyModifier))
+ {
+ UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
+ }
+ else if ((grab->modifiersDetail.exact == AnyModifier)
+ && (grab->detail.exact != AnyKey))
+ {
+ UPDATE(grab->modifiersDetail.pMask,
+ pMinuendGrab->modifiersDetail.exact);
+ }
+ else if ((pMinuendGrab->detail.exact != AnyKey)
+ && (pMinuendGrab->modifiersDetail.exact != AnyModifier))
+ {
+ GrabPtr pNewGrab;
+
+ UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
+
+ pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device,
+ grab->window, (Mask)grab->eventMask,
+ (Bool)grab->ownerEvents,
+ (Bool)grab->keyboardMode,
+ (Bool)grab->pointerMode,
+ grab->modifierDevice,
+ AnyModifier, (int)grab->type,
+ pMinuendGrab->detail.exact,
+ grab->confineTo, grab->cursor);
+ if (!pNewGrab)
+ ok = FALSE;
+ else if (!(pNewGrab->modifiersDetail.pMask =
+ DeleteDetailFromMask(grab->modifiersDetail.pMask,
+ pMinuendGrab->modifiersDetail.exact))
+ ||
+ (!pNewGrab->window->optional &&
+ !MakeWindowOptional(pNewGrab->window)))
+ {
+ FreeGrab(pNewGrab);
+ ok = FALSE;
+ }
+ else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB,
+ (pointer)pNewGrab))
+ ok = FALSE;
+ else
+ adds[nadds++] = pNewGrab;
+ }
+ else if (pMinuendGrab->detail.exact == AnyKey)
+ {
+ UPDATE(grab->modifiersDetail.pMask,
+ pMinuendGrab->modifiersDetail.exact);
+ }
+ else
+ {
+ UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
+ }
+ }
+
+ if (!ok)
+ {
+ for (i = 0; i < nadds; i++)
+ FreeResource(adds[i]->resource, RT_NONE);
+ for (i = 0; i < nups; i++)
+ xfree(details[i]);
+ }
+ else
+ {
+ for (i = 0; i < ndels; i++)
+ FreeResource(deletes[i]->resource, RT_NONE);
+ for (i = 0; i < nadds; i++)
+ {
+ grab = adds[i];
+ grab->next = grab->window->optional->passiveGrabs;
+ grab->window->optional->passiveGrabs = grab;
+ }
+ for (i = 0; i < nups; i++)
+ {
+ xfree(*updates[i]);
+ *updates[i] = details[i];
+ }
+ }
+ DEALLOCATE_LOCAL(details);
+ DEALLOCATE_LOCAL(updates);
+ DEALLOCATE_LOCAL(adds);
+ DEALLOCATE_LOCAL(deletes);
+ return ok;
+
+#undef UPDATE
+}
diff --git a/xserver/dix/initatoms.c b/xserver/dix/initatoms.c
new file mode 100644
index 000000000..a5972afd6
--- /dev/null
+++ b/xserver/dix/initatoms.c
@@ -0,0 +1,84 @@
+/* THIS IS A GENERATED FILE
+ *
+ * Do not change! Changing this file implies a protocol change!
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include "misc.h"
+#include "dix.h"
+void MakePredeclaredAtoms()
+{
+ if (MakeAtom("PRIMARY", 7, 1) != XA_PRIMARY) AtomError();
+ if (MakeAtom("SECONDARY", 9, 1) != XA_SECONDARY) AtomError();
+ if (MakeAtom("ARC", 3, 1) != XA_ARC) AtomError();
+ if (MakeAtom("ATOM", 4, 1) != XA_ATOM) AtomError();
+ if (MakeAtom("BITMAP", 6, 1) != XA_BITMAP) AtomError();
+ if (MakeAtom("CARDINAL", 8, 1) != XA_CARDINAL) AtomError();
+ if (MakeAtom("COLORMAP", 8, 1) != XA_COLORMAP) AtomError();
+ if (MakeAtom("CURSOR", 6, 1) != XA_CURSOR) AtomError();
+ if (MakeAtom("CUT_BUFFER0", 11, 1) != XA_CUT_BUFFER0) AtomError();
+ if (MakeAtom("CUT_BUFFER1", 11, 1) != XA_CUT_BUFFER1) AtomError();
+ if (MakeAtom("CUT_BUFFER2", 11, 1) != XA_CUT_BUFFER2) AtomError();
+ if (MakeAtom("CUT_BUFFER3", 11, 1) != XA_CUT_BUFFER3) AtomError();
+ if (MakeAtom("CUT_BUFFER4", 11, 1) != XA_CUT_BUFFER4) AtomError();
+ if (MakeAtom("CUT_BUFFER5", 11, 1) != XA_CUT_BUFFER5) AtomError();
+ if (MakeAtom("CUT_BUFFER6", 11, 1) != XA_CUT_BUFFER6) AtomError();
+ if (MakeAtom("CUT_BUFFER7", 11, 1) != XA_CUT_BUFFER7) AtomError();
+ if (MakeAtom("DRAWABLE", 8, 1) != XA_DRAWABLE) AtomError();
+ if (MakeAtom("FONT", 4, 1) != XA_FONT) AtomError();
+ if (MakeAtom("INTEGER", 7, 1) != XA_INTEGER) AtomError();
+ if (MakeAtom("PIXMAP", 6, 1) != XA_PIXMAP) AtomError();
+ if (MakeAtom("POINT", 5, 1) != XA_POINT) AtomError();
+ if (MakeAtom("RECTANGLE", 9, 1) != XA_RECTANGLE) AtomError();
+ if (MakeAtom("RESOURCE_MANAGER", 16, 1) != XA_RESOURCE_MANAGER) AtomError();
+ if (MakeAtom("RGB_COLOR_MAP", 13, 1) != XA_RGB_COLOR_MAP) AtomError();
+ if (MakeAtom("RGB_BEST_MAP", 12, 1) != XA_RGB_BEST_MAP) AtomError();
+ if (MakeAtom("RGB_BLUE_MAP", 12, 1) != XA_RGB_BLUE_MAP) AtomError();
+ if (MakeAtom("RGB_DEFAULT_MAP", 15, 1) != XA_RGB_DEFAULT_MAP) AtomError();
+ if (MakeAtom("RGB_GRAY_MAP", 12, 1) != XA_RGB_GRAY_MAP) AtomError();
+ if (MakeAtom("RGB_GREEN_MAP", 13, 1) != XA_RGB_GREEN_MAP) AtomError();
+ if (MakeAtom("RGB_RED_MAP", 11, 1) != XA_RGB_RED_MAP) AtomError();
+ if (MakeAtom("STRING", 6, 1) != XA_STRING) AtomError();
+ if (MakeAtom("VISUALID", 8, 1) != XA_VISUALID) AtomError();
+ if (MakeAtom("WINDOW", 6, 1) != XA_WINDOW) AtomError();
+ if (MakeAtom("WM_COMMAND", 10, 1) != XA_WM_COMMAND) AtomError();
+ if (MakeAtom("WM_HINTS", 8, 1) != XA_WM_HINTS) AtomError();
+ if (MakeAtom("WM_CLIENT_MACHINE", 17, 1) != XA_WM_CLIENT_MACHINE) AtomError();
+ if (MakeAtom("WM_ICON_NAME", 12, 1) != XA_WM_ICON_NAME) AtomError();
+ if (MakeAtom("WM_ICON_SIZE", 12, 1) != XA_WM_ICON_SIZE) AtomError();
+ if (MakeAtom("WM_NAME", 7, 1) != XA_WM_NAME) AtomError();
+ if (MakeAtom("WM_NORMAL_HINTS", 15, 1) != XA_WM_NORMAL_HINTS) AtomError();
+ if (MakeAtom("WM_SIZE_HINTS", 13, 1) != XA_WM_SIZE_HINTS) AtomError();
+ if (MakeAtom("WM_ZOOM_HINTS", 13, 1) != XA_WM_ZOOM_HINTS) AtomError();
+ if (MakeAtom("MIN_SPACE", 9, 1) != XA_MIN_SPACE) AtomError();
+ if (MakeAtom("NORM_SPACE", 10, 1) != XA_NORM_SPACE) AtomError();
+ if (MakeAtom("MAX_SPACE", 9, 1) != XA_MAX_SPACE) AtomError();
+ if (MakeAtom("END_SPACE", 9, 1) != XA_END_SPACE) AtomError();
+ if (MakeAtom("SUPERSCRIPT_X", 13, 1) != XA_SUPERSCRIPT_X) AtomError();
+ if (MakeAtom("SUPERSCRIPT_Y", 13, 1) != XA_SUPERSCRIPT_Y) AtomError();
+ if (MakeAtom("SUBSCRIPT_X", 11, 1) != XA_SUBSCRIPT_X) AtomError();
+ if (MakeAtom("SUBSCRIPT_Y", 11, 1) != XA_SUBSCRIPT_Y) AtomError();
+ if (MakeAtom("UNDERLINE_POSITION", 18, 1) != XA_UNDERLINE_POSITION) AtomError();
+ if (MakeAtom("UNDERLINE_THICKNESS", 19, 1) != XA_UNDERLINE_THICKNESS) AtomError();
+ if (MakeAtom("STRIKEOUT_ASCENT", 16, 1) != XA_STRIKEOUT_ASCENT) AtomError();
+ if (MakeAtom("STRIKEOUT_DESCENT", 17, 1) != XA_STRIKEOUT_DESCENT) AtomError();
+ if (MakeAtom("ITALIC_ANGLE", 12, 1) != XA_ITALIC_ANGLE) AtomError();
+ if (MakeAtom("X_HEIGHT", 8, 1) != XA_X_HEIGHT) AtomError();
+ if (MakeAtom("QUAD_WIDTH", 10, 1) != XA_QUAD_WIDTH) AtomError();
+ if (MakeAtom("WEIGHT", 6, 1) != XA_WEIGHT) AtomError();
+ if (MakeAtom("POINT_SIZE", 10, 1) != XA_POINT_SIZE) AtomError();
+ if (MakeAtom("RESOLUTION", 10, 1) != XA_RESOLUTION) AtomError();
+ if (MakeAtom("COPYRIGHT", 9, 1) != XA_COPYRIGHT) AtomError();
+ if (MakeAtom("NOTICE", 6, 1) != XA_NOTICE) AtomError();
+ if (MakeAtom("FONT_NAME", 9, 1) != XA_FONT_NAME) AtomError();
+ if (MakeAtom("FAMILY_NAME", 11, 1) != XA_FAMILY_NAME) AtomError();
+ if (MakeAtom("FULL_NAME", 9, 1) != XA_FULL_NAME) AtomError();
+ if (MakeAtom("CAP_HEIGHT", 10, 1) != XA_CAP_HEIGHT) AtomError();
+ if (MakeAtom("WM_CLASS", 8, 1) != XA_WM_CLASS) AtomError();
+ if (MakeAtom("WM_TRANSIENT_FOR", 16, 1) != XA_WM_TRANSIENT_FOR) AtomError();
+}
diff --git a/xserver/dix/main.c b/xserver/dix/main.c
new file mode 100644
index 000000000..f3cde189c
--- /dev/null
+++ b/xserver/dix/main.c
@@ -0,0 +1,792 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+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.
+
+The above copyright notice and this permission notice 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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $TOG: main.c /main/86 1998/02/09 14:20:03 kaleb $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xos.h> /* for unistd.h */
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "extension.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include <X11/fonts/font.h>
+#include "opaque.h"
+#include "servermd.h"
+#include "site.h"
+#include "dixfont.h"
+#include "extnsionst.h"
+#ifdef XPRINT
+#include "DiPrint.h"
+#endif
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#else
+#include "dixevents.h" /* InitEvents() */
+#include "dispatch.h" /* InitProcVectors() */
+#endif
+
+#ifdef DPMSExtension
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+#include "dpmsproc.h"
+#endif
+
+extern int InitClientPrivates(ClientPtr client);
+
+extern void Dispatch(void);
+
+char *ConnectionInfo;
+xConnSetupPrefix connSetupPrefix;
+
+extern FontPtr defaultFont;
+extern int screenPrivateCount;
+
+extern void InitProcVectors(void);
+extern Bool CreateGCperDepthArray(void);
+
+#ifndef PANORAMIX
+static
+#endif
+Bool CreateConnectionBlock(void);
+
+static void FreeScreen(ScreenPtr);
+
+_X_EXPORT PaddingInfo PixmapWidthPaddingInfo[33];
+
+int connBlockScreenStart;
+
+static int restart = 0;
+
+_X_EXPORT void
+NotImplemented(xEvent *from, xEvent *to)
+{
+ FatalError("Not implemented");
+}
+
+/*
+ * Dummy entry for ReplySwapVector[]
+ */
+
+void
+ReplyNotSwappd(
+ ClientPtr pClient ,
+ int size ,
+ void * pbuf
+ )
+{
+ FatalError("Not implemented");
+}
+
+/*
+ * This array encodes the answer to the question "what is the log base 2
+ * of the number of pixels that fit in a scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int answer[6][4] = {
+ /* pad pad pad pad*/
+ /* 8 16 32 64 */
+
+ { 3, 4, 5 , 6 }, /* 1 bit per pixel */
+ { 1, 2, 3 , 4 }, /* 4 bits per pixel */
+ { 0, 1, 2 , 3 }, /* 8 bits per pixel */
+ { ~0, 0, 1 , 2 }, /* 16 bits per pixel */
+ { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */
+ { ~0, ~0, 0 , 1 } /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the first index for
+ * the answer array above given the number of bits per pixel?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForBitsPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 1, ~0, ~0, ~0, /* 4 bits per pixel */
+ 2, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 4, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 5 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the bytesperPixel value for cases where the number
+ * of bits per pixel is a multiple of 8 but not a power of 2.
+ */
+static int answerBytesPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 0, ~0, ~0, ~0, /* 4 bits per pixel */
+ 0, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the second index for
+ * the answer array above given the number of bits per scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForScanlinePad[ 65 ] = {
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 3 /* 64 bits per scanline pad unit */
+};
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+int
+main(int argc, char *argv[], char *envp[])
+{
+ int i, j, k, error;
+ char *xauthfile;
+ HWEventQueueType alwaysCheckForInput[2];
+
+ display = "0";
+
+ InitGlobals();
+#ifdef XPRINT
+ PrinterInitGlobals();
+#endif
+
+ /* Quartz support on Mac OS X requires that the Cocoa event loop be in
+ * the main thread. This allows the X server main to be called again
+ * from another thread. */
+#if defined(__DARWIN__) && defined(DARWIN_WITH_QUARTZ)
+ DarwinHandleGUI(argc, argv, envp);
+#endif
+
+ /* Notice if we're restarted. Probably this is because we jumped through
+ * an uninitialized pointer */
+ if (restart)
+ FatalError("server restarted. Jumped through uninitialized pointer?\n");
+ else
+ restart = 1;
+
+ CheckUserParameters(argc, argv, envp);
+
+ CheckUserAuthorization();
+
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+ ExpandCommandLine(&argc, &argv);
+#endif
+
+ InitConnectionLimits();
+
+ /* These are needed by some routines which are called from interrupt
+ * handlers, thus have no direct calling path back to main and thus
+ * can't be passed argc, argv as parameters */
+ argcGlobal = argc;
+ argvGlobal = argv;
+ /* prep X authority file from environment; this can be overriden by a
+ * command line option */
+ xauthfile = getenv("XAUTHORITY");
+ if (xauthfile) InitAuthorization (xauthfile);
+ ProcessCommandLine(argc, argv);
+
+ alwaysCheckForInput[0] = 0;
+ alwaysCheckForInput[1] = 1;
+ while(1)
+ {
+ serverGeneration++;
+ ScreenSaverTime = defaultScreenSaverTime;
+ ScreenSaverInterval = defaultScreenSaverInterval;
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+#ifdef DPMSExtension
+ DPMSStandbyTime = defaultDPMSStandbyTime;
+ DPMSSuspendTime = defaultDPMSSuspendTime;
+ DPMSOffTime = defaultDPMSOffTime;
+ DPMSEnabled = defaultDPMSEnabled;
+ DPMSPowerLevel = 0;
+#endif
+ InitBlockAndWakeupHandlers();
+ /* Perform any operating system dependent initializations you'd like */
+ OsInit();
+ if(serverGeneration == 1)
+ {
+ CreateWellKnownSockets();
+ InitProcVectors();
+ clients = (ClientPtr *)xalloc(MAXCLIENTS * sizeof(ClientPtr));
+ if (!clients)
+ FatalError("couldn't create client array");
+ for (i=1; i<MAXCLIENTS; i++)
+ clients[i] = NullClient;
+ serverClient = (ClientPtr)xalloc(sizeof(ClientRec));
+ if (!serverClient)
+ FatalError("couldn't create server client");
+ InitClient(serverClient, 0, (pointer)NULL);
+ }
+ else
+ ResetWellKnownSockets ();
+ clients[0] = serverClient;
+ currentMaxClients = 1;
+
+ if (!InitClientResources(serverClient)) /* for root resources */
+ FatalError("couldn't init server resources");
+
+ SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
+ screenInfo.arraySize = MAXSCREENS;
+ screenInfo.numScreens = 0;
+ screenInfo.numVideoScreens = -1;
+ WindowTable = (WindowPtr *)xalloc(MAXSCREENS * sizeof(WindowPtr));
+ if (!WindowTable)
+ FatalError("couldn't create root window table");
+
+ /*
+ * Just in case the ddx doesnt supply a format for depth 1 (like qvss).
+ */
+ j = indexForBitsPerPixel[ 1 ];
+ k = indexForScanlinePad[ BITMAP_SCANLINE_PAD ];
+ PixmapWidthPaddingInfo[1].padRoundUp = BITMAP_SCANLINE_PAD-1;
+ PixmapWidthPaddingInfo[1].padPixelsLog2 = answer[j][k];
+ j = indexForBitsPerPixel[8]; /* bits per byte */
+ PixmapWidthPaddingInfo[1].padBytesLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[1].bitsPerPixel = 1;
+
+ InitAtoms();
+ InitEvents();
+ InitGlyphCaching();
+ ResetExtensionPrivates();
+ ResetClientPrivates();
+ ResetScreenPrivates();
+ ResetWindowPrivates();
+ ResetGCPrivates();
+#ifdef PIXPRIV
+ ResetPixmapPrivates();
+#endif
+ ResetColormapPrivates();
+ ResetFontPrivateIndex();
+ ResetDevicePrivateIndex();
+ InitCallbackManager();
+ InitVisualWrap();
+ InitOutput(&screenInfo, argc, argv);
+#ifdef XPRINT
+ PrinterInitOutput(&screenInfo, argc, argv);
+#endif
+
+ if (screenInfo.numScreens < 1)
+ FatalError("no screens found");
+ if (screenInfo.numVideoScreens < 0)
+ screenInfo.numVideoScreens = screenInfo.numScreens;
+ InitExtensions(argc, argv);
+ if (!InitClientPrivates(serverClient))
+ FatalError("failed to allocate serverClient devprivates");
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ if (!CreateScratchPixmapsForScreen(i))
+ FatalError("failed to create scratch pixmaps");
+ if (pScreen->CreateScreenResources &&
+ !(*pScreen->CreateScreenResources)(pScreen))
+ FatalError("failed to create screen resources");
+ if (!CreateGCperDepth(i))
+ FatalError("failed to create scratch GCs");
+ if (!CreateDefaultStipple(i))
+ FatalError("failed to create default stipple");
+ if (!CreateRootWindow(pScreen))
+ FatalError("failed to create root window");
+ }
+ InitInput(argc, argv);
+ if (InitAndStartDevices() != Success)
+ FatalError("failed to initialize core devices");
+
+ InitFonts();
+ if (loadableFonts) {
+ SetFontPath(0, 0, (unsigned char *)defaultFontPath, &error);
+ } else {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ ErrorF("failed to set default font path '%s'",
+ defaultFontPath);
+ }
+ if (!SetDefaultFont(defaultTextFont))
+ FatalError("could not open default font '%s'", defaultTextFont);
+ if (!(rootCursor = CreateRootCursor(defaultCursorFont, 0)))
+ FatalError("could not open default cursor font '%s'",
+ defaultCursorFont);
+#ifdef DPMSExtension
+ /* check all screens, looking for DPMS Capabilities */
+ DPMSCapableFlag = DPMSSupported();
+ if (!DPMSCapableFlag)
+ DPMSEnabled = FALSE;
+#endif
+
+#ifdef PANORAMIX
+ /*
+ * Consolidate window and colourmap information for each screen
+ */
+ if (!noPanoramiXExtension)
+ PanoramiXConsolidate();
+#endif
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ InitRootWindow(WindowTable[i]);
+ DefineInitialRootWindow(WindowTable[0]);
+ SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ if (!PanoramiXCreateConnectionBlock())
+ FatalError("could not create connection block info");
+ } else
+#endif
+ {
+ if (!CreateConnectionBlock())
+ FatalError("could not create connection block info");
+ }
+
+ Dispatch();
+
+ /* Now free up whatever must be freed */
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
+ FreeScreenSaverTimer();
+ CloseDownExtensions();
+
+#ifdef PANORAMIX
+ {
+ Bool remember_it = noPanoramiXExtension;
+ noPanoramiXExtension = TRUE;
+ FreeAllResources();
+ noPanoramiXExtension = remember_it;
+ }
+#else
+ FreeAllResources();
+#endif
+
+ CloseDownDevices();
+ for (i = screenInfo.numScreens - 1; i >= 0; i--)
+ {
+ FreeScratchPixmapsForScreen(i);
+ FreeGCperDepth(i);
+ FreeDefaultStipple(i);
+ (* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]);
+ FreeScreen(screenInfo.screens[i]);
+ screenInfo.numScreens = i;
+ }
+ CloseDownEvents();
+ xfree(WindowTable);
+ WindowTable = NULL;
+ FreeFonts();
+
+ FreeAuditTimer();
+
+ xfree(serverClient->devPrivates);
+ serverClient->devPrivates = NULL;
+
+ if (dispatchException & DE_TERMINATE)
+ {
+ CloseWellKnownConnections();
+ }
+
+ OsCleanup((dispatchException & DE_TERMINATE) != 0);
+
+ if (dispatchException & DE_TERMINATE)
+ {
+ ddxGiveUp();
+ break;
+ }
+
+ xfree(ConnectionInfo);
+ ConnectionInfo = NULL;
+ }
+ return(0);
+}
+
+static int VendorRelease = VENDOR_RELEASE;
+static char *VendorString = VENDOR_STRING;
+
+void
+SetVendorRelease(int release)
+{
+ VendorRelease = release;
+}
+
+void
+SetVendorString(char *string)
+{
+ VendorString = string;
+}
+
+static int padlength[4] = {0, 3, 2, 1};
+
+#ifndef PANORAMIX
+static
+#endif
+Bool
+CreateConnectionBlock()
+{
+ xConnSetup setup;
+ xWindowRoot root;
+ xDepth depth;
+ xVisualType visual;
+ xPixmapFormat format;
+ unsigned long vid;
+ int i, j, k,
+ lenofblock,
+ sizesofar = 0;
+ char *pBuf;
+
+
+ /* Leave off the ridBase and ridMask, these must be sent with
+ connection */
+
+ setup.release = VendorRelease;
+ /*
+ * per-server image and bitmap parameters are defined in Xmd.h
+ */
+ setup.imageByteOrder = screenInfo.imageByteOrder;
+
+ setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
+ setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
+
+ setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
+ setup.motionBufferSize = NumMotionEvents();
+ setup.numRoots = screenInfo.numScreens;
+ setup.nbytesVendor = strlen(VendorString);
+ setup.numFormats = screenInfo.numPixmapFormats;
+ setup.maxRequestSize = MAX_REQUEST_SIZE;
+ QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
+
+ lenofblock = sizeof(xConnSetup) +
+ ((setup.nbytesVendor + 3) & ~3) +
+ (setup.numFormats * sizeof(xPixmapFormat)) +
+ (setup.numRoots * sizeof(xWindowRoot));
+ ConnectionInfo = (char *) xalloc(lenofblock);
+ if (!ConnectionInfo)
+ return FALSE;
+
+ memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
+ sizesofar = sizeof(xConnSetup);
+ pBuf = ConnectionInfo + sizeof(xConnSetup);
+
+ memmove(pBuf, VendorString, (int)setup.nbytesVendor);
+ sizesofar += setup.nbytesVendor;
+ pBuf += setup.nbytesVendor;
+ i = padlength[setup.nbytesVendor & 3];
+ sizesofar += i;
+ while (--i >= 0)
+ *pBuf++ = 0;
+
+ for (i=0; i<screenInfo.numPixmapFormats; i++)
+ {
+ format.depth = screenInfo.formats[i].depth;
+ format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
+ format.scanLinePad = screenInfo.formats[i].scanlinePad;
+ memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
+ pBuf += sizeof(xPixmapFormat);
+ sizesofar += sizeof(xPixmapFormat);
+ }
+
+ connBlockScreenStart = sizesofar;
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ pScreen = screenInfo.screens[i];
+ root.windowId = WindowTable[i]->drawable.id;
+ root.defaultColormap = pScreen->defColormap;
+ root.whitePixel = pScreen->whitePixel;
+ root.blackPixel = pScreen->blackPixel;
+ root.currentInputMask = 0; /* filled in when sent */
+ root.pixWidth = pScreen->width;
+ root.pixHeight = pScreen->height;
+ root.mmWidth = pScreen->mmWidth;
+ root.mmHeight = pScreen->mmHeight;
+ root.minInstalledMaps = pScreen->minInstalledCmaps;
+ root.maxInstalledMaps = pScreen->maxInstalledCmaps;
+ root.rootVisualID = pScreen->rootVisual;
+ root.backingStore = pScreen->backingStoreSupport;
+ root.saveUnders = pScreen->saveUnderSupport != NotUseful;
+ root.rootDepth = pScreen->rootDepth;
+ root.nDepths = pScreen->numDepths;
+ memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
+ sizesofar += sizeof(xWindowRoot);
+ pBuf += sizeof(xWindowRoot);
+
+ pDepth = pScreen->allowedDepths;
+ for(j = 0; j < pScreen->numDepths; j++, pDepth++)
+ {
+ lenofblock += sizeof(xDepth) +
+ (pDepth->numVids * sizeof(xVisualType));
+ pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
+ if (!pBuf)
+ {
+ xfree(ConnectionInfo);
+ return FALSE;
+ }
+ ConnectionInfo = pBuf;
+ pBuf += sizesofar;
+ depth.depth = pDepth->depth;
+ depth.nVisuals = pDepth->numVids;
+ memmove(pBuf, (char *)&depth, sizeof(xDepth));
+ pBuf += sizeof(xDepth);
+ sizesofar += sizeof(xDepth);
+ for(k = 0; k < pDepth->numVids; k++)
+ {
+ vid = pDepth->vids[k];
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != vid;
+ pVisual++)
+ ;
+ visual.visualID = vid;
+ visual.class = pVisual->class;
+ visual.bitsPerRGB = pVisual->bitsPerRGBValue;
+ visual.colormapEntries = pVisual->ColormapEntries;
+ visual.redMask = pVisual->redMask;
+ visual.greenMask = pVisual->greenMask;
+ visual.blueMask = pVisual->blueMask;
+ memmove(pBuf, (char *)&visual, sizeof(xVisualType));
+ pBuf += sizeof(xVisualType);
+ sizesofar += sizeof(xVisualType);
+ }
+ }
+ }
+ connSetupPrefix.success = xTrue;
+ connSetupPrefix.length = lenofblock/4;
+ connSetupPrefix.majorVersion = X_PROTOCOL;
+ connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
+ return TRUE;
+}
+
+/*
+ grow the array of screenRecs if necessary.
+ call the device-supplied initialization procedure
+with its screen number, a pointer to its ScreenRec, argc, and argv.
+ return the number of successfully installed screens.
+
+*/
+
+int
+AddScreen(
+ Bool (* pfnInit)(
+ int /*index*/,
+ ScreenPtr /*pScreen*/,
+ int /*argc*/,
+ char ** /*argv*/
+ ),
+ int argc,
+ char **argv)
+{
+
+ int i;
+ int scanlinepad, format, depth, bitsPerPixel, j, k;
+ ScreenPtr pScreen;
+#ifdef DEBUG
+ void (**jNI) ();
+#endif /* DEBUG */
+
+ i = screenInfo.numScreens;
+ if (i == MAXSCREENS)
+ return -1;
+
+ pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
+ if (!pScreen)
+ return -1;
+
+ pScreen->devPrivates = (DevUnion *)xcalloc(sizeof(DevUnion),
+ screenPrivateCount);
+ if (!pScreen->devPrivates && screenPrivateCount)
+ {
+ xfree(pScreen);
+ return -1;
+ }
+ pScreen->myNum = i;
+ pScreen->WindowPrivateLen = 0;
+ pScreen->WindowPrivateSizes = (unsigned *)NULL;
+ pScreen->totalWindowSize =
+ ((sizeof(WindowRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+ pScreen->GCPrivateLen = 0;
+ pScreen->GCPrivateSizes = (unsigned *)NULL;
+ pScreen->totalGCSize =
+ ((sizeof(GC) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+#ifdef PIXPRIV
+ pScreen->PixmapPrivateLen = 0;
+ pScreen->PixmapPrivateSizes = (unsigned *)NULL;
+ pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
+#endif
+ pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
+ pScreen->CreateScreenResources = 0;
+
+#ifdef DEBUG
+ for (jNI = &pScreen->QueryBestSize;
+ jNI < (void (**) ()) &pScreen->SendGraphicsExpose;
+ jNI++)
+ *jNI = NotImplemented;
+#endif /* DEBUG */
+
+ /*
+ * This loop gets run once for every Screen that gets added,
+ * but thats ok. If the ddx layer initializes the formats
+ * one at a time calling AddScreen() after each, then each
+ * iteration will make it a little more accurate. Worst case
+ * we do this loop N * numPixmapFormats where N is # of screens.
+ * Anyway, this must be called after InitOutput and before the
+ * screen init routine is called.
+ */
+ for (format=0; format<screenInfo.numPixmapFormats; format++)
+ {
+ depth = screenInfo.formats[format].depth;
+ bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
+ scanlinepad = screenInfo.formats[format].scanlinePad;
+ j = indexForBitsPerPixel[ bitsPerPixel ];
+ k = indexForScanlinePad[ scanlinepad ];
+ PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].padRoundUp =
+ (scanlinepad/bitsPerPixel) - 1;
+ j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
+ PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
+ if (answerBytesPerPixel[bitsPerPixel])
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
+ PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
+ answerBytesPerPixel[bitsPerPixel];
+ }
+ else
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
+ }
+ }
+
+ /* This is where screen specific stuff gets initialized. Load the
+ screen structure, call the hardware, whatever.
+ This is also where the default colormap should be allocated and
+ also pixel values for blackPixel, whitePixel, and the cursor
+ Note that InitScreen is NOT allowed to modify argc, argv, or
+ any of the strings pointed to by argv. They may be passed to
+ multiple screens.
+ */
+ pScreen->rgf = ~0L; /* there are no scratch GCs yet*/
+ WindowTable[i] = NullWindow;
+ screenInfo.screens[i] = pScreen;
+ screenInfo.numScreens++;
+ if (!(*pfnInit)(i, pScreen, argc, argv))
+ {
+ FreeScreen(pScreen);
+ screenInfo.numScreens--;
+ return -1;
+ }
+ return i;
+}
+
+static void
+FreeScreen(ScreenPtr pScreen)
+{
+ xfree(pScreen->WindowPrivateSizes);
+ xfree(pScreen->GCPrivateSizes);
+#ifdef PIXPRIV
+ xfree(pScreen->PixmapPrivateSizes);
+#endif
+ xfree(pScreen->devPrivates);
+ xfree(pScreen);
+}
diff --git a/xserver/dix/pixmap.c b/xserver/dix/pixmap.c
new file mode 100644
index 000000000..a5b7b064d
--- /dev/null
+++ b/xserver/dix/pixmap.c
@@ -0,0 +1,151 @@
+/*
+
+Copyright 1993, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE OPEN GROUP 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 The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "site.h"
+
+
+/*
+ * Scratch pixmap management and device independent pixmap allocation
+ * function.
+ */
+
+
+/* callable by ddx */
+_X_EXPORT PixmapPtr
+GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData)
+{
+ PixmapPtr pPixmap = pScreen->pScratchPixmap;
+
+ if (pPixmap)
+ pScreen->pScratchPixmap = NULL;
+ else
+ /* width and height of 0 means don't allocate any pixmap data */
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth);
+
+ if (pPixmap) {
+ if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ bitsPerPixel, devKind, pPixData))
+ return pPixmap;
+ (*pScreen->DestroyPixmap)(pPixmap);
+ }
+ return NullPixmap;
+}
+
+
+/* callable by ddx */
+_X_EXPORT void
+FreeScratchPixmapHeader(PixmapPtr pPixmap)
+{
+ if (pPixmap)
+ {
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
+ pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
+ if (pScreen->pScratchPixmap)
+ (*pScreen->DestroyPixmap)(pPixmap);
+ else
+ pScreen->pScratchPixmap = pPixmap;
+ }
+}
+
+
+Bool
+CreateScratchPixmapsForScreen(int scrnum)
+{
+ /* let it be created on first use */
+ screenInfo.screens[scrnum]->pScratchPixmap = NULL;
+ return TRUE;
+}
+
+
+void
+FreeScratchPixmapsForScreen(int scrnum)
+{
+ FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap);
+}
+
+
+/* callable by ddx */
+_X_EXPORT PixmapPtr
+AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
+{
+ PixmapPtr pPixmap;
+#ifdef PIXPRIV
+ char *ptr;
+ DevUnion *ppriv;
+ unsigned *sizes;
+ unsigned size;
+ int i;
+
+ if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize)
+ return NullPixmap;
+
+ pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize);
+ if (!pPixmap)
+ return NullPixmap;
+ ppriv = (DevUnion *)(pPixmap + 1);
+ pPixmap->devPrivates = ppriv;
+ sizes = pScreen->PixmapPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->PixmapPrivateLen);
+ for (i = pScreen->PixmapPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ((size = *sizes) != 0)
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+#else
+ pPixmap = (PixmapPtr)xalloc(sizeof(PixmapRec) + pixDataSize);
+#endif
+
+#ifdef _XSERVER64
+ if (pPixmap) {
+ pPixmap->drawable.pad0 = 0;
+ pPixmap->drawable.pad1 = 0;
+ }
+#endif
+
+ return pPixmap;
+}
diff --git a/xserver/dix/privates.c b/xserver/dix/privates.c
new file mode 100644
index 000000000..b20a1dbf0
--- /dev/null
+++ b/xserver/dix/privates.c
@@ -0,0 +1,456 @@
+/*
+
+Copyright 1993, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE OPEN GROUP 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 The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "colormapst.h"
+#include "servermd.h"
+#include "site.h"
+#include "inputstr.h"
+#include "extnsionst.h"
+
+/*
+ * See the Wrappers and devPrivates section in "Definition of the
+ * Porting Layer for the X v11 Sample Server" (doc/Server/ddx.tbl.ms)
+ * for information on how to use devPrivates.
+ */
+
+/*
+ * extension private machinery
+ */
+
+static int extensionPrivateCount;
+int extensionPrivateLen;
+unsigned *extensionPrivateSizes;
+unsigned totalExtensionSize;
+
+void
+ResetExtensionPrivates()
+{
+ extensionPrivateCount = 0;
+ extensionPrivateLen = 0;
+ xfree(extensionPrivateSizes);
+ extensionPrivateSizes = (unsigned *)NULL;
+ totalExtensionSize =
+ ((sizeof(ExtensionEntry) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+}
+
+_X_EXPORT int
+AllocateExtensionPrivateIndex()
+{
+ return extensionPrivateCount++;
+}
+
+_X_EXPORT Bool
+AllocateExtensionPrivate(int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= extensionPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)xrealloc(extensionPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (extensionPrivateLen <= index2)
+ {
+ nsizes[extensionPrivateLen++] = 0;
+ totalExtensionSize += sizeof(DevUnion);
+ }
+ extensionPrivateSizes = nsizes;
+ }
+ oldamount = extensionPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ extensionPrivateSizes[index2] = amount;
+ totalExtensionSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+/*
+ * client private machinery
+ */
+
+static int clientPrivateCount;
+int clientPrivateLen;
+unsigned *clientPrivateSizes;
+unsigned totalClientSize;
+
+void
+ResetClientPrivates()
+{
+ clientPrivateCount = 0;
+ clientPrivateLen = 0;
+ xfree(clientPrivateSizes);
+ clientPrivateSizes = (unsigned *)NULL;
+ totalClientSize =
+ ((sizeof(ClientRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+}
+
+_X_EXPORT int
+AllocateClientPrivateIndex()
+{
+ return clientPrivateCount++;
+}
+
+_X_EXPORT Bool
+AllocateClientPrivate(int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= clientPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)xrealloc(clientPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (clientPrivateLen <= index2)
+ {
+ nsizes[clientPrivateLen++] = 0;
+ totalClientSize += sizeof(DevUnion);
+ }
+ clientPrivateSizes = nsizes;
+ }
+ oldamount = clientPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ clientPrivateSizes[index2] = amount;
+ totalClientSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+/*
+ * screen private machinery
+ */
+
+int screenPrivateCount;
+
+void
+ResetScreenPrivates()
+{
+ screenPrivateCount = 0;
+}
+
+/* this can be called after some screens have been created,
+ * so we have to worry about resizing existing devPrivates
+ */
+_X_EXPORT int
+AllocateScreenPrivateIndex()
+{
+ int idx;
+ int i;
+ ScreenPtr pScreen;
+ DevUnion *nprivs;
+
+ idx = screenPrivateCount++;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ nprivs = (DevUnion *)xrealloc(pScreen->devPrivates,
+ screenPrivateCount * sizeof(DevUnion));
+ if (!nprivs)
+ {
+ screenPrivateCount--;
+ return -1;
+ }
+ /* Zero the new private */
+ bzero(&nprivs[idx], sizeof(DevUnion));
+ pScreen->devPrivates = nprivs;
+ }
+ return idx;
+}
+
+
+/*
+ * window private machinery
+ */
+
+static int windowPrivateCount;
+
+void
+ResetWindowPrivates()
+{
+ windowPrivateCount = 0;
+}
+
+_X_EXPORT int
+AllocateWindowPrivateIndex()
+{
+ return windowPrivateCount++;
+}
+
+_X_EXPORT Bool
+AllocateWindowPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= pScreen->WindowPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)xrealloc(pScreen->WindowPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (pScreen->WindowPrivateLen <= index2)
+ {
+ nsizes[pScreen->WindowPrivateLen++] = 0;
+ pScreen->totalWindowSize += sizeof(DevUnion);
+ }
+ pScreen->WindowPrivateSizes = nsizes;
+ }
+ oldamount = pScreen->WindowPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ pScreen->WindowPrivateSizes[index2] = amount;
+ pScreen->totalWindowSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+
+/*
+ * gc private machinery
+ */
+
+static int gcPrivateCount;
+
+void
+ResetGCPrivates()
+{
+ gcPrivateCount = 0;
+}
+
+_X_EXPORT int
+AllocateGCPrivateIndex()
+{
+ return gcPrivateCount++;
+}
+
+_X_EXPORT Bool
+AllocateGCPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= pScreen->GCPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)xrealloc(pScreen->GCPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (pScreen->GCPrivateLen <= index2)
+ {
+ nsizes[pScreen->GCPrivateLen++] = 0;
+ pScreen->totalGCSize += sizeof(DevUnion);
+ }
+ pScreen->GCPrivateSizes = nsizes;
+ }
+ oldamount = pScreen->GCPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ pScreen->GCPrivateSizes[index2] = amount;
+ pScreen->totalGCSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+
+/*
+ * pixmap private machinery
+ */
+#ifdef PIXPRIV
+static int pixmapPrivateCount;
+
+void
+ResetPixmapPrivates()
+{
+ pixmapPrivateCount = 0;
+}
+
+_X_EXPORT int
+AllocatePixmapPrivateIndex()
+{
+ return pixmapPrivateCount++;
+}
+
+_X_EXPORT Bool
+AllocatePixmapPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= pScreen->PixmapPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)xrealloc(pScreen->PixmapPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (pScreen->PixmapPrivateLen <= index2)
+ {
+ nsizes[pScreen->PixmapPrivateLen++] = 0;
+ pScreen->totalPixmapSize += sizeof(DevUnion);
+ }
+ pScreen->PixmapPrivateSizes = nsizes;
+ }
+ oldamount = pScreen->PixmapPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ pScreen->PixmapPrivateSizes[index2] = amount;
+ pScreen->totalPixmapSize += (amount - oldamount);
+ }
+ pScreen->totalPixmapSize = BitmapBytePad(pScreen->totalPixmapSize * 8);
+ return TRUE;
+}
+#endif
+
+
+/*
+ * colormap private machinery
+ */
+
+int colormapPrivateCount;
+
+void
+ResetColormapPrivates()
+{
+ colormapPrivateCount = 0;
+}
+
+
+_X_EXPORT int
+AllocateColormapPrivateIndex (InitCmapPrivFunc initPrivFunc)
+{
+ int index;
+ int i;
+ ColormapPtr pColormap;
+ DevUnion *privs;
+
+ index = colormapPrivateCount++;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ /*
+ * AllocateColormapPrivateIndex may be called after the
+ * default colormap has been created on each screen!
+ *
+ * We must resize the devPrivates array for the default
+ * colormap on each screen, making room for this new private.
+ * We also call the initialization function 'initPrivFunc' on
+ * the new private allocated for each default colormap.
+ */
+
+ ScreenPtr pScreen = screenInfo.screens[i];
+
+ pColormap = (ColormapPtr) LookupIDByType (
+ pScreen->defColormap, RT_COLORMAP);
+
+ if (pColormap)
+ {
+ privs = (DevUnion *) xrealloc (pColormap->devPrivates,
+ colormapPrivateCount * sizeof(DevUnion));
+ if (!privs) {
+ colormapPrivateCount--;
+ return -1;
+ }
+ bzero(&privs[index], sizeof(DevUnion));
+ pColormap->devPrivates = privs;
+ if (!(*initPrivFunc)(pColormap,index))
+ {
+ colormapPrivateCount--;
+ return -1;
+ }
+ }
+ }
+
+ return index;
+}
+
+/*
+ * device private machinery
+ */
+
+static int devicePrivateIndex = 0;
+
+_X_EXPORT int
+AllocateDevicePrivateIndex()
+{
+ return devicePrivateIndex++;
+}
+
+_X_EXPORT Bool
+AllocateDevicePrivate(DeviceIntPtr device, int index)
+{
+ if (device->nPrivates < ++index) {
+ DevUnion *nprivs = (DevUnion *) xrealloc(device->devPrivates,
+ index * sizeof(DevUnion));
+ if (!nprivs)
+ return FALSE;
+ device->devPrivates = nprivs;
+ bzero(&nprivs[device->nPrivates], sizeof(DevUnion)
+ * (index - device->nPrivates));
+ device->nPrivates = index;
+ return TRUE;
+ } else {
+ return TRUE;
+ }
+}
+
+void
+ResetDevicePrivateIndex(void)
+{
+ devicePrivateIndex = 0;
+}
diff --git a/xserver/dix/property.c b/xserver/dix/property.c
new file mode 100644
index 000000000..da983838f
--- /dev/null
+++ b/xserver/dix/property.c
@@ -0,0 +1,683 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#ifdef XACE
+#include "xace.h"
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ * ChangeProperty, DeleteProperty, GetProperties,
+ * ListProperties
+ *
+ * Properties below to windows. A allocate slots each time
+ * a property is added. No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+ PropertyPtr pProp;
+ register int j;
+
+ pProp = pWin->userProps;
+ while (pProp)
+ {
+ ErrorF( "%x %x\n", pProp->propertyName, pProp->type);
+ ErrorF("property format: %d\n", pProp->format);
+ ErrorF("property data: \n");
+ for (j=0; j<(pProp->format/8)*pProp->size; j++)
+ ErrorF("%c\n", pProp->data[j]);
+ pProp = pProp->next;
+ }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+ int i, j, delta;
+ REQUEST(xRotatePropertiesReq);
+ WindowPtr pWin;
+ register Atom * atoms;
+ PropertyPtr * props; /* array of pointer */
+ PropertyPtr pProp;
+ xEvent event;
+
+ REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+ UpdateCurrentTime();
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!stuff->nAtoms)
+ return(Success);
+ atoms = (Atom *) & stuff[1];
+ props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+ if (!props)
+ return(BadAlloc);
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+#ifdef XACE
+ char action = XaceHook(XACE_PROPERTY_ACCESS, client, pWin, atoms[i],
+ SecurityReadAccess|SecurityWriteAccess);
+#endif
+ if (!ValidAtom(atoms[i])
+#ifdef XACE
+ || (SecurityErrorOperation == action)
+#endif
+ )
+ {
+ DEALLOCATE_LOCAL(props);
+ client->errorValue = atoms[i];
+ return BadAtom;
+ }
+#ifdef XACE
+ if (SecurityIgnoreOperation == action)
+ {
+ DEALLOCATE_LOCAL(props);
+ return Success;
+ }
+#endif
+ for (j = i + 1; j < stuff->nAtoms; j++)
+ if (atoms[j] == atoms[i])
+ {
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+ }
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == atoms[i])
+ goto found;
+ pProp = pProp->next;
+ }
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+found:
+ props[i] = pProp;
+ }
+ delta = stuff->nPositions;
+
+ /* If the rotation is a complete 360 degrees, then moving the properties
+ around and generating PropertyNotify events should be skipped. */
+
+ if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 )
+ {
+ while (delta < 0) /* faster if abs value is small */
+ delta += stuff->nAtoms;
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+ /* Generate a PropertyNotify event for each property whose value
+ is changed in the order in which they appear in the request. */
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = props[i]->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+
+ props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+ }
+ }
+ DEALLOCATE_LOCAL(props);
+ return Success;
+}
+
+int
+ProcChangeProperty(ClientPtr client)
+{
+ WindowPtr pWin;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+ REQUEST(xChangePropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend))
+ {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32))
+ {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
+
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if (!ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+#ifdef XACE
+ switch (XaceHook(XACE_PROPERTY_ACCESS, client, pWin, stuff->property,
+ SecurityWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+ err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+ (int)mode, len, (pointer)&stuff[1], TRUE);
+ if (err != Success)
+ return err;
+ else
+ return client->noClientException;
+}
+
+_X_EXPORT int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
+ int mode, unsigned long len, pointer value,
+ Bool sendevent)
+{
+ PropertyPtr pProp;
+ xEvent event;
+ int sizeInBytes;
+ int totalSize;
+ pointer data;
+
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+
+ /* first see if property already exists */
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) /* just add to list */
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return(BadAlloc);
+ pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+ if (!pProp)
+ return(BadAlloc);
+ data = (pointer)xalloc(totalSize);
+ if (!data && len)
+ {
+ xfree(pProp);
+ return(BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (len)
+ memmove((char *)data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ }
+ else
+ {
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return(BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return(BadMatch);
+ if (mode == PropModeReplace)
+ {
+ if (totalSize != pProp->size * (pProp->format >> 3))
+ {
+ data = (pointer)xrealloc(pProp->data, totalSize);
+ if (!data && len)
+ return(BadAlloc);
+ pProp->data = data;
+ }
+ if (len)
+ memmove((char *)pProp->data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ }
+ else if (len == 0)
+ {
+ /* do nothing */
+ }
+ else if (mode == PropModeAppend)
+ {
+ data = (pointer)xrealloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ pProp->data = data;
+ memmove(&((char *)data)[pProp->size * sizeInBytes],
+ (char *)value,
+ totalSize);
+ pProp->size += len;
+ }
+ else if (mode == PropModePrepend)
+ {
+ data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ memmove(&((char *)data)[totalSize], (char *)pProp->data,
+ (int)(pProp->size * sizeInBytes));
+ memmove((char *)data, (char *)value, totalSize);
+ xfree(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent)
+ {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+ return(Success);
+}
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+ PropertyPtr pProp, prevProp;
+ xEvent event;
+
+ if (!(pProp = wUserProps (pWin)))
+ return(Success);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == propName)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+ if (pProp)
+ {
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ {
+ prevProp->next = pProp->next;
+ }
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+ PropertyPtr pProp, pNextProp;
+ xEvent event;
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ pNextProp = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ pProp = pNextProp;
+ }
+}
+
+static int
+NullPropertyReply(
+ ClientPtr client,
+ ATOM propertyType,
+ int format,
+ xGetPropertyReply *reply)
+{
+ reply->nItems = 0;
+ reply->length = 0;
+ reply->bytesAfter = 0;
+ reply->propertyType = propertyType;
+ reply->format = format;
+ WriteReplyToClient(client, sizeof(xGenericReply), reply);
+ return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ * If type Any is specified, returns the property from the specified
+ * window regardless of its type. If a type is specified, returns the
+ * property only if its type equals the specified type.
+ * If delete is True and a property is returned, the property is also
+ * deleted from the window and a PropertyNotify event is generated on the
+ * window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+ WindowPtr pWin;
+ xGetPropertyReply reply;
+ REQUEST(xGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
+ {
+ client->errorValue = stuff->delete;
+ return(BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ if (!pProp)
+ return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XACE
+ {
+ Mask access_mode = SecurityReadAccess;
+
+ if (stuff->delete)
+ access_mode |= SecurityDestroyAccess;
+ switch(XaceHook(XACE_PROPERTY_ACCESS, client, pWin, stuff->property,
+ access_mode))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return NullPropertyReply(client, pProp->type, pProp->format,
+ &reply);
+ }
+ }
+#endif
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType))
+ )
+ {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ return(Success);
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.length = (len + 3) >> 2;
+ reply.nItems = len / (pProp->format / 8 );
+ reply.propertyType = pProp->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ if (len)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *)pProp->data + ind);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* delete the Property */
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcListProperties(ClientPtr client)
+{
+ Atom *pAtoms = NULL, *temppAtoms;
+ xListPropertiesReply xlpr;
+ int numProps = 0;
+ WindowPtr pWin;
+ PropertyPtr pProp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ pProp = pProp->next;
+ numProps++;
+ }
+ if (numProps)
+ if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+ return(BadAlloc);
+
+ xlpr.type = X_Reply;
+ xlpr.nProperties = numProps;
+ xlpr.length = (numProps * sizeof(Atom)) >> 2;
+ xlpr.sequenceNumber = client->sequence;
+ pProp = wUserProps (pWin);
+ temppAtoms = pAtoms;
+ while (pProp)
+ {
+ *temppAtoms++ = pProp->propertyName;
+ pProp = pProp->next;
+ }
+ WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+ if (numProps)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ DEALLOCATE_LOCAL(pAtoms);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcDeleteProperty(register ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xDeletePropertyReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+
+#ifdef XACE
+ switch(XaceHook(XACE_PROPERTY_ACCESS, client, pWin, stuff->property,
+ SecurityDestroyAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+ result = DeleteProperty(pWin, stuff->property);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
diff --git a/xserver/dix/resource.c b/xserver/dix/resource.c
new file mode 100644
index 000000000..b2d01c8f3
--- /dev/null
+++ b/xserver/dix/resource.c
@@ -0,0 +1,903 @@
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+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.
+
+The above copyright notice and this permission notice 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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/* Routines to manage various kinds of resources:
+ *
+ * CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ * FakeClientID, AddResource, FreeResource, FreeClientResources,
+ * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/*
+ * A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ * off-limits for client-visible resources. The next 8 bits are
+ * used as client ID, and the low 22 bits come from the client.
+ * A resource ID is "hashed" by extracting and xoring subfields
+ * (varying with the size of the hash table).
+ *
+ * It is sometimes necessary for the server to create an ID that looks
+ * like it belongs to a client. This ID, however, must not be one
+ * the client actually can create, or we have the potential for conflict.
+ * The 31st bit of the ID is reserved for the server's use for this
+ * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ * resource "owned" by the client.
+ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XACE
+#include "xace.h"
+#endif
+#include <assert.h>
+
+static void RebuildTable(
+ int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+ struct _Resource *next;
+ XID id;
+ RESTYPE type;
+ pointer value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+ ResourcePtr *resources;
+ int elements;
+ int buckets;
+ int hashsize; /* log(2)(buckets) */
+ XID fakeID;
+ XID endFakeID;
+ XID expectID;
+} ClientResourceRec;
+
+_X_EXPORT RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+_X_EXPORT RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+_X_EXPORT Atom * ResourceNames = NULL;
+
+_X_EXPORT void RegisterResourceName (RESTYPE type, char *name)
+{
+ ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+_X_EXPORT RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+ RESTYPE next = lastResourceType + 1;
+ DeleteType *funcs;
+
+ if (next & lastResourceClass)
+ return 0;
+ funcs = (DeleteType *)xrealloc(DeleteFuncs,
+ (next + 1) * sizeof(DeleteType));
+ if (!funcs)
+ return 0;
+
+#ifdef XResExtension
+ {
+ Atom *newnames;
+ newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+ if(!newnames)
+ return 0;
+ ResourceNames = newnames;
+ ResourceNames[next] = 0;
+ }
+#endif
+
+ lastResourceType = next;
+ DeleteFuncs = funcs;
+ DeleteFuncs[next] = deleteFunc;
+ return next;
+}
+
+_X_EXPORT RESTYPE
+CreateNewResourceClass()
+{
+ RESTYPE next = lastResourceClass >> 1;
+
+ if (next & lastResourceType)
+ return 0;
+ lastResourceClass = next;
+ TypeMask = next - 1;
+ return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ * When a new client is created, call this to allocate space
+ * in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+ register int i, j;
+
+ if (client == serverClient)
+ {
+ lastResourceType = RT_LASTPREDEF;
+ lastResourceClass = RC_LASTPREDEF;
+ TypeMask = RC_LASTPREDEF - 1;
+ if (DeleteFuncs)
+ xfree(DeleteFuncs);
+ DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+ sizeof(DeleteType));
+ if (!DeleteFuncs)
+ return FALSE;
+ DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+ DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+ DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+ DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+ DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+ DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+ DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+ DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+ DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+ DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+ if(ResourceNames)
+ xfree(ResourceNames);
+ ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+ if(!ResourceNames)
+ return FALSE;
+#endif
+ }
+ clientTable[i = client->index].resources =
+ (ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+ if (!clientTable[i].resources)
+ return FALSE;
+ clientTable[i].buckets = INITBUCKETS;
+ clientTable[i].elements = 0;
+ clientTable[i].hashsize = INITHASHSIZE;
+ /* Many IDs allocated from the server client are visible to clients,
+ * so we don't use the SERVER_BIT for them, but we have to start
+ * past the magic value constants used in the protocol. For normal
+ * clients, we can start from zero, with SERVER_BIT set.
+ */
+ clientTable[i].fakeID = client->clientAsMask |
+ (client->index ? SERVER_BIT : SERVER_MINID);
+ clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+ clientTable[i].expectID = client->clientAsMask;
+ for (j=0; j<INITBUCKETS; j++)
+ {
+ clientTable[i].resources[j] = NullResource;
+ }
+ return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+ id &= RESOURCE_ID_MASK;
+ switch (clientTable[client].hashsize)
+ {
+ case 6:
+ return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+ case 7:
+ return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+ case 8:
+ return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+ case 9:
+ return ((int)(0x1FF & (id ^ (id>>9))));
+ case 10:
+ return ((int)(0x3FF & (id ^ (id>>10))));
+ case 11:
+ return ((int)(0x7FF & (id ^ (id>>11))));
+ }
+ return -1;
+}
+
+static XID
+AvailableID(
+ register int client,
+ register XID id,
+ register XID maxid,
+ register XID goodid)
+{
+ register ResourcePtr res;
+
+ if ((goodid >= id) && (goodid <= maxid))
+ return goodid;
+ for (; id <= maxid; id++)
+ {
+ res = clientTable[client].resources[Hash(client, id)];
+ while (res && (res->id != id))
+ res = res->next;
+ if (!res)
+ return id;
+ }
+ return 0;
+}
+
+_X_EXPORT void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+ register XID id, maxid;
+ register ResourcePtr *resp;
+ register ResourcePtr res;
+ register int i;
+ XID goodid;
+
+ id = (Mask)client << CLIENTOFFSET;
+ if (server)
+ id |= client ? SERVER_BIT : SERVER_MINID;
+ maxid = id | RESOURCE_ID_MASK;
+ goodid = 0;
+ for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+ --i >= 0;)
+ {
+ for (res = *resp++; res; res = res->next)
+ {
+ if ((res->id < id) || (res->id > maxid))
+ continue;
+ if (((res->id - id) >= (maxid - res->id)) ?
+ (goodid = AvailableID(client, id, res->id - 1, goodid)) :
+ !(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+ maxid = res->id - 1;
+ else
+ id = res->id + 1;
+ }
+ }
+ if (id > maxid)
+ id = maxid = 0;
+ *minp = id;
+ *maxp = maxid;
+}
+
+/**
+ * GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ * This function tries to find count unused XIDs for the given client. It
+ * puts the IDs in the array pids and returns the number found, which should
+ * almost always be the number requested.
+ *
+ * The circumstances that lead to a call to this function are very rare.
+ * Xlib must run out of IDs while trying to generate a request that wants
+ * multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ * No rocket science in the implementation; just iterate over all
+ * possible IDs for the given client and pick the first count IDs
+ * that aren't in use. A more efficient algorithm could probably be
+ * invented, but this will be used so rarely that this should suffice.
+ */
+
+_X_EXPORT unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+ unsigned int found = 0;
+ XID id = pClient->clientAsMask;
+ XID maxid;
+
+ maxid = id | RESOURCE_ID_MASK;
+ while ( (found < count) && (id <= maxid) )
+ {
+ if (!LookupIDByClass(id, RC_ANY))
+ {
+ pids[found++] = id;
+ }
+ id++;
+ }
+ return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+_X_EXPORT XID
+FakeClientID(register int client)
+{
+ XID id, maxid;
+
+ id = clientTable[client].fakeID++;
+ if (id != clientTable[client].endFakeID)
+ return id;
+ GetXIDRange(client, TRUE, &id, &maxid);
+ if (!id) {
+ if (!client)
+ FatalError("FakeClientID: server internal ids exhausted\n");
+ MarkClientException(clients[client]);
+ id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+ maxid = id | RESOURCE_ID_MASK;
+ }
+ clientTable[client].fakeID = id + 1;
+ clientTable[client].endFakeID = maxid + 1;
+ return id;
+}
+
+_X_EXPORT Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+ int client;
+ register ClientResourceRec *rrec;
+ register ResourcePtr res, *head;
+
+ client = CLIENT_ID(id);
+ rrec = &clientTable[client];
+ if (!rrec->buckets)
+ {
+ ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+ (unsigned long)id, type, (unsigned long)value, client);
+ FatalError("client not in use\n");
+ }
+ if ((rrec->elements >= 4*rrec->buckets) &&
+ (rrec->hashsize < MAXHASHSIZE))
+ RebuildTable(client);
+ head = &rrec->resources[Hash(client, id)];
+ res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+ if (!res)
+ {
+ (*DeleteFuncs[type & TypeMask])(value, id);
+ return FALSE;
+ }
+ res->next = *head;
+ res->id = id;
+ res->type = type;
+ res->value = value;
+ *head = res;
+ rrec->elements++;
+ if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ rrec->expectID = id + 1;
+ return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+ register int j;
+ register ResourcePtr res, next;
+ ResourcePtr **tails, *resources;
+ register ResourcePtr **tptr, *rptr;
+
+ /*
+ * For now, preserve insertion order, since some ddx layers depend
+ * on resources being free in the opposite order they are added.
+ */
+
+ j = 2 * clientTable[client].buckets;
+ tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+ if (!tails)
+ return;
+ resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+ if (!resources)
+ {
+ DEALLOCATE_LOCAL(tails);
+ return;
+ }
+ for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+ {
+ *rptr = NullResource;
+ *tptr = rptr;
+ }
+ clientTable[client].hashsize++;
+ for (j = clientTable[client].buckets,
+ rptr = clientTable[client].resources;
+ --j >= 0;
+ rptr++)
+ {
+ for (res = *rptr; res; res = next)
+ {
+ next = res->next;
+ res->next = NullResource;
+ tptr = &tails[Hash(client, res->id)];
+ **tptr = res;
+ *tptr = &res->next;
+ }
+ }
+ DEALLOCATE_LOCAL(tails);
+ clientTable[client].buckets *= 2;
+ xfree(clientTable[client].resources);
+ clientTable[client].resources = resources;
+}
+
+_X_EXPORT void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ register int *eltptr;
+ int elements;
+ Bool gotOne = FALSE;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+ eltptr = &clientTable[cid].elements;
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id)
+ {
+ RESTYPE rtype = res->type;
+ *prev = res->next;
+ elements = --*eltptr;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (rtype != skipDeleteFuncType)
+ (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+ xfree(res);
+ if (*eltptr != elements)
+ prev = head; /* prev may no longer be valid */
+ gotOne = TRUE;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+ if (!gotOne)
+ ErrorF("Freeing resource id=%lX which isn't there.\n",
+ (unsigned long)id);
+}
+
+
+_X_EXPORT void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id && res->type == type)
+ {
+ *prev = res->next;
+ if (type & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (!skipFree)
+ (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+ xfree(res);
+ break;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+}
+
+/*
+ * Change the value associated with a resource id. Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+_X_EXPORT Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ res->value = value;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources. If func adds new resources,
+ * func might or might not get called for them. func cannot both
+ * add and delete an equal number of resources!
+ */
+
+_X_EXPORT void
+FindClientResourcesByType(
+ ClientPtr client,
+ RESTYPE type,
+ FindResType func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ if (!type || this->type == type) {
+ elements = *eltptr;
+ (*func)(this->value, this->id, cdata);
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+ }
+}
+
+_X_EXPORT void
+FindAllClientResources(
+ ClientPtr client,
+ FindAllRes func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ elements = *eltptr;
+ (*func)(this->value, this->id, this->type, cdata);
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+}
+
+
+pointer
+LookupClientResourceComplex(
+ ClientPtr client,
+ RESTYPE type,
+ FindComplexResType func,
+ pointer cdata
+){
+ ResourcePtr *resources;
+ ResourcePtr this;
+ int i;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ for (i = 0; i < clientTable[client->index].buckets; i++) {
+ for (this = resources[i]; this; this = this->next) {
+ if (!type || this->type == type) {
+ if((*func)(this->value, this->id, cdata))
+ return this->value;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+ ResourcePtr *resources;
+ ResourcePtr this;
+ ResourcePtr *prev;
+ int j;
+
+ if (!client)
+ return;
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ prev = &resources[j];
+ while ( (this = *prev) )
+ {
+ RESTYPE rtype = this->type;
+ if (rtype & RC_NEVERRETAIN)
+ {
+ *prev = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ else
+ prev = &this->next;
+ }
+ }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+ register ResourcePtr *resources;
+ register ResourcePtr this;
+ int j;
+
+ /* This routine shouldn't be called with a null client, but just in
+ case ... */
+
+ if (!client)
+ return;
+
+ HandleSaveSet(client);
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ /* It may seem silly to update the head of this resource list as
+ we delete the members, since the entire list will be deleted any way,
+ but there are some resource deletion functions "FreeClientPixels" for
+ one which do a LookupID on another resource id (a Colormap id in this
+ case), so the resource list must be kept valid up to the point that
+ it is deleted, so every time we delete a resource, we must update the
+ head, just like in FreeResource. I hope that this doesn't slow down
+ mass deletion appreciably. PRH */
+
+ ResourcePtr *head;
+
+ head = &resources[j];
+
+ for (this = *head; this; this = *head)
+ {
+ RESTYPE rtype = this->type;
+ *head = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ }
+ xfree(clientTable[client->index].resources);
+ clientTable[client->index].resources = NULL;
+ clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+ int i;
+
+ for (i = currentMaxClients; --i >= 0; )
+ {
+ if (clientTable[i].buckets)
+ FreeClientResources(clients[i]);
+ }
+}
+
+_X_EXPORT Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+ XID minid, maxid;
+
+ if (!noPanoramiXExtension) {
+ minid = client->clientAsMask | (client->index ?
+ SERVER_BIT : SERVER_MINID);
+ maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+ if ((id >= minid) && (id <= maxid))
+ return TRUE;
+ }
+#endif /* PANORAMIX */
+ return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+ ((clientTable[client->index].expectID <= id) ||
+ !LookupIDByClass(id, RC_ANY)));
+}
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system. They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+_X_EXPORT pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+ int cid;
+ register ResourcePtr res;
+ pointer retval = NULL;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+#ifdef XACE
+ if (retval && client &&
+ !XaceHook(XACE_RESOURCE_ACCESS, client, id, rtype, mode, retval))
+ retval = NULL;
+#endif
+ return retval;
+}
+
+
+_X_EXPORT pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+ int cid;
+ register ResourcePtr res = NULL;
+ pointer retval = NULL;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+#ifdef XACE
+ if (retval && client &&
+ !XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type, mode, retval))
+ retval = NULL;
+#endif
+ return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+_X_EXPORT pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ return SecurityLookupIDByType(NullClient, id, rtype,
+ SecurityUnknownAccess);
+}
+
+_X_EXPORT pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ return SecurityLookupIDByClass(NullClient, id, classes,
+ SecurityUnknownAccess);
+}
diff --git a/xserver/dix/strcasecmp.c b/xserver/dix/strcasecmp.c
new file mode 100644
index 000000000..58f0961e6
--- /dev/null
+++ b/xserver/dix/strcasecmp.c
@@ -0,0 +1,48 @@
+/************************************************************
+ Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, 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 Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <ctype.h>
+#include "dix.h"
+
+#ifdef NEED_STRCASECMP
+int
+xstrcasecmp(char *str1,char *str2)
+{
+ const u_char *us1 = (const u_char *)str1, *us2 = (const u_char *)str2;
+
+ while (tolower(*us1) == tolower(*us2)) {
+ if (*us1++ == '\0')
+ return (0);
+ us2++;
+ }
+
+ return (tolower(*us1) - tolower(*us2));
+}
+#endif
diff --git a/xserver/dix/swaprep.c b/xserver/dix/swaprep.c
new file mode 100644
index 000000000..08ae6eb1a
--- /dev/null
+++ b/xserver/dix/swaprep.c
@@ -0,0 +1,1299 @@
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include <X11/fonts/fontstruct.h>
+#include "scrnintstr.h"
+#include "swaprep.h"
+#include "globals.h"
+
+static void SwapFontInfo(xQueryFontReply *pr);
+
+static void SwapCharInfo(xCharInfo *pInfo);
+
+static void SwapFont(xQueryFontReply *pr, Bool hasGlyphs);
+
+/**
+ * Thanks to Jack Palevich for testing and subsequently rewriting all this
+ *
+ * \param size size in bytes
+ */
+_X_EXPORT void
+Swap32Write(ClientPtr pClient, int size, register CARD32 *pbuf)
+{
+ register int i;
+ register char n;
+
+ size >>= 2;
+ for(i = 0; i < size; i++)
+ /* brackets are mandatory here, because "swapl" macro expands
+ to several statements */
+ {
+ swapl(&pbuf[i], n);
+ }
+ (void)WriteToClient(pClient, size << 2, (char *) pbuf);
+}
+
+/**
+ *
+ * \param size size in bytes
+ */
+_X_EXPORT void
+CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf)
+{
+ int bufsize = size;
+ CARD32 *pbufT;
+ register CARD32 *from, *to, *fromLast, *toLast;
+ CARD32 tmpbuf[1];
+
+ /* Allocate as big a buffer as we can... */
+ while (!(pbufT = (CARD32 *) ALLOCATE_LOCAL(bufsize)))
+ {
+ bufsize >>= 1;
+ if (bufsize == 4)
+ {
+ pbufT = tmpbuf;
+ break;
+ }
+ }
+
+ /* convert lengths from # of bytes to # of longs */
+ size >>= 2;
+ bufsize >>= 2;
+
+ from = pbuf;
+ fromLast = from + size;
+ while (from < fromLast) {
+ int nbytes;
+ to = pbufT;
+ toLast = to + min (bufsize, fromLast - from);
+ nbytes = (toLast - to) << 2;
+ while (to < toLast) {
+ /* can't write "cpswapl(*from++, *to++)" because cpswapl is a macro
+ that evaulates its args more than once */
+ cpswapl(*from, *to);
+ from++;
+ to++;
+ }
+ (void)WriteToClient (pClient, nbytes, (char *) pbufT);
+ }
+
+ if (pbufT != tmpbuf)
+ DEALLOCATE_LOCAL ((char *) pbufT);
+}
+
+/**
+ *
+ * \param size size in bytes
+ */
+void
+CopySwap16Write(ClientPtr pClient, int size, short *pbuf)
+{
+ int bufsize = size;
+ short *pbufT;
+ register short *from, *to, *fromLast, *toLast;
+ short tmpbuf[2];
+
+ /* Allocate as big a buffer as we can... */
+ while (!(pbufT = (short *) ALLOCATE_LOCAL(bufsize)))
+ {
+ bufsize >>= 1;
+ if (bufsize == 4)
+ {
+ pbufT = tmpbuf;
+ break;
+ }
+ }
+
+ /* convert lengths from # of bytes to # of shorts */
+ size >>= 1;
+ bufsize >>= 1;
+
+ from = pbuf;
+ fromLast = from + size;
+ while (from < fromLast) {
+ int nbytes;
+ to = pbufT;
+ toLast = to + min (bufsize, fromLast - from);
+ nbytes = (toLast - to) << 1;
+ while (to < toLast) {
+ /* can't write "cpswaps(*from++, *to++)" because cpswaps is a macro
+ that evaulates its args more than once */
+ cpswaps(*from, *to);
+ from++;
+ to++;
+ }
+ (void)WriteToClient (pClient, nbytes, (char *) pbufT);
+ }
+
+ if (pbufT != tmpbuf)
+ DEALLOCATE_LOCAL ((char *) pbufT);
+}
+
+
+/* Extra-small reply */
+void
+SGenericReply(ClientPtr pClient, int size, xGenericReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+/* Extra-large reply */
+void
+SGetWindowAttributesReply(ClientPtr pClient, int size,
+ xGetWindowAttributesReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swapl(&pRep->visualID, n);
+ swaps(&pRep->class, n);
+ swapl(&pRep->backingBitPlanes, n);
+ swapl(&pRep->backingPixel, n);
+ swapl(&pRep->colormap, n);
+ swapl(&pRep->allEventMasks, n);
+ swapl(&pRep->yourEventMask, n);
+ swaps(&pRep->doNotPropagateMask, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetGeometryReply(ClientPtr pClient, int size, xGetGeometryReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->root, n);
+ swaps(&pRep->x, n);
+ swaps(&pRep->y, n);
+ swaps(&pRep->width, n);
+ swaps(&pRep->height, n);
+ swaps(&pRep->borderWidth, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SQueryTreeReply(ClientPtr pClient, int size, xQueryTreeReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swapl(&pRep->root, n);
+ swapl(&pRep->parent, n);
+ swaps(&pRep->nChildren, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SInternAtomReply(ClientPtr pClient, int size, xInternAtomReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->atom, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetAtomNameReply(ClientPtr pClient, int size, xGetAtomNameReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nameLength, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+
+void
+SGetPropertyReply(ClientPtr pClient, int size, xGetPropertyReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swapl(&pRep->propertyType, n);
+ swapl(&pRep->bytesAfter, n);
+ swapl(&pRep->nItems, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SListPropertiesReply(ClientPtr pClient, int size, xListPropertiesReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nProperties, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetSelectionOwnerReply(ClientPtr pClient, int size,
+ xGetSelectionOwnerReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->owner, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+
+void
+SQueryPointerReply(ClientPtr pClient, int size, xQueryPointerReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->root, n);
+ swapl(&pRep->child, n);
+ swaps(&pRep->rootX, n);
+ swaps(&pRep->rootY, n);
+ swaps(&pRep->winX, n);
+ swaps(&pRep->winY, n);
+ swaps(&pRep->mask, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SwapTimecoord(xTimecoord* pCoord)
+{
+ register char n;
+
+ swapl(&pCoord->time, n);
+ swaps(&pCoord->x, n);
+ swaps(&pCoord->y, n);
+}
+
+void
+SwapTimeCoordWrite(ClientPtr pClient, int size, xTimecoord *pRep)
+{
+ int i, n;
+ xTimecoord *pRepT;
+
+ n = size / sizeof(xTimecoord);
+ pRepT = pRep;
+ for(i = 0; i < n; i++)
+ {
+ SwapTimecoord(pRepT);
+ pRepT++;
+ }
+ (void)WriteToClient(pClient, size, (char *) pRep);
+
+}
+void
+SGetMotionEventsReply(ClientPtr pClient, int size, xGetMotionEventsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swapl(&pRep->nEvents, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+STranslateCoordsReply(ClientPtr pClient, int size, xTranslateCoordsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->child, n);
+ swaps(&pRep->dstX, n);
+ swaps(&pRep->dstY, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetInputFocusReply(ClientPtr pClient, int size, xGetInputFocusReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->focus, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+/* extra long reply */
+void
+SQueryKeymapReply(ClientPtr pClient, int size, xQueryKeymapReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+static void
+SwapCharInfo(xCharInfo *pInfo)
+{
+ register char n;
+
+ swaps(&pInfo->leftSideBearing, n);
+ swaps(&pInfo->rightSideBearing, n);
+ swaps(&pInfo->characterWidth, n);
+ swaps(&pInfo->ascent, n);
+ swaps(&pInfo->descent, n);
+ swaps(&pInfo->attributes, n);
+}
+
+static void
+SwapFontInfo(xQueryFontReply *pr)
+{
+ register char n;
+
+ swaps(&pr->minCharOrByte2, n);
+ swaps(&pr->maxCharOrByte2, n);
+ swaps(&pr->defaultChar, n);
+ swaps(&pr->nFontProps, n);
+ swaps(&pr->fontAscent, n);
+ swaps(&pr->fontDescent, n);
+ SwapCharInfo( &pr->minBounds);
+ SwapCharInfo( &pr->maxBounds);
+ swapl(&pr->nCharInfos, n);
+}
+
+static void
+SwapFont(xQueryFontReply *pr, Bool hasGlyphs)
+{
+ unsigned i;
+ xCharInfo * pxci;
+ unsigned nchars, nprops;
+ char *pby;
+ register char n;
+
+ swaps(&pr->sequenceNumber, n);
+ swapl(&pr->length, n);
+ nchars = pr->nCharInfos;
+ nprops = pr->nFontProps;
+ SwapFontInfo(pr);
+ pby = (char *) &pr[1];
+ /* Font properties are an atom and either an int32 or a CARD32, so
+ * they are always 2 4 byte values */
+ for(i = 0; i < nprops; i++)
+ {
+ swapl(pby, n);
+ pby += 4;
+ swapl(pby, n);
+ pby += 4;
+ }
+ if (hasGlyphs)
+ {
+ pxci = (xCharInfo *)pby;
+ for(i = 0; i< nchars; i++, pxci++)
+ SwapCharInfo(pxci);
+ }
+}
+
+void
+SQueryFontReply(ClientPtr pClient, int size, xQueryFontReply *pRep)
+{
+ SwapFont(pRep, TRUE);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SQueryTextExtentsReply(ClientPtr pClient, int size, xQueryTextExtentsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swaps(&pRep->fontAscent, n);
+ swaps(&pRep->fontDescent, n);
+ swaps(&pRep->overallAscent, n);
+ swaps(&pRep->overallDescent, n);
+ swapl(&pRep->overallWidth, n);
+ swapl(&pRep->overallLeft, n);
+ swapl(&pRep->overallRight, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SListFontsReply(ClientPtr pClient, int size, xListFontsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nFonts, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SListFontsWithInfoReply(ClientPtr pClient, int size,
+ xListFontsWithInfoReply *pRep)
+{
+ SwapFont((xQueryFontReply *)pRep, FALSE);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetFontPathReply(ClientPtr pClient, int size, xGetFontPathReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nPaths, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetImageReply(ClientPtr pClient, int size, xGetImageReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swapl(&pRep->visual, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+ /* Fortunately, image doesn't need swapping */
+}
+
+void
+SListInstalledColormapsReply(ClientPtr pClient, int size,
+ xListInstalledColormapsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nColormaps, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SAllocColorReply(pClient, size, pRep)
+ ClientPtr pClient;
+ int size;
+ xAllocColorReply *pRep;
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swaps(&pRep->red, n);
+ swaps(&pRep->green, n);
+ swaps(&pRep->blue, n);
+ swapl(&pRep->pixel, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SAllocNamedColorReply(ClientPtr pClient, int size, xAllocNamedColorReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->pixel, n);
+ swaps(&pRep->exactRed, n);
+ swaps(&pRep->exactGreen, n);
+ swaps(&pRep->exactBlue, n);
+ swaps(&pRep->screenRed, n);
+ swaps(&pRep->screenGreen, n);
+ swaps(&pRep->screenBlue, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SAllocColorCellsReply(ClientPtr pClient, int size, xAllocColorCellsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nPixels, n);
+ swaps(&pRep->nMasks, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+
+void
+SAllocColorPlanesReply(ClientPtr pClient, int size, xAllocColorPlanesReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nPixels, n);
+ swapl(&pRep->redMask, n);
+ swapl(&pRep->greenMask, n);
+ swapl(&pRep->blueMask, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SwapRGB(xrgb *prgb)
+{
+ register char n;
+
+ swaps(&prgb->red, n);
+ swaps(&prgb->green, n);
+ swaps(&prgb->blue, n);
+}
+
+void
+SQColorsExtend(ClientPtr pClient, int size, xrgb *prgb)
+{
+ int i, n;
+ xrgb *prgbT;
+
+ n = size / sizeof(xrgb);
+ prgbT = prgb;
+ for(i = 0; i < n; i++)
+ {
+ SwapRGB(prgbT);
+ prgbT++;
+ }
+ (void)WriteToClient(pClient, size, (char *) prgb);
+}
+
+void
+SQueryColorsReply(ClientPtr pClient, int size, xQueryColorsReply* pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nColors, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SLookupColorReply(ClientPtr pClient, int size, xLookupColorReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swaps(&pRep->exactRed, n);
+ swaps(&pRep->exactGreen, n);
+ swaps(&pRep->exactBlue, n);
+ swaps(&pRep->screenRed, n);
+ swaps(&pRep->screenGreen, n);
+ swaps(&pRep->screenBlue, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SQueryBestSizeReply(ClientPtr pClient, int size, xQueryBestSizeReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swaps(&pRep->width, n);
+ swaps(&pRep->height, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SListExtensionsReply(ClientPtr pClient, int size, xListExtensionsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetKeyboardMappingReply(ClientPtr pClient, int size,
+ xGetKeyboardMappingReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetPointerMappingReply(ClientPtr pClient, int size,
+ xGetPointerMappingReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetModifierMappingReply(ClientPtr pClient, int size,
+ xGetModifierMappingReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetKeyboardControlReply(ClientPtr pClient, int size, xGetKeyboardControlReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swapl(&pRep->ledMask, n);
+ swaps(&pRep->bellPitch, n);
+ swaps(&pRep->bellDuration, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetPointerControlReply(ClientPtr pClient, int size, xGetPointerControlReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swaps(&pRep->accelNumerator, n);
+ swaps(&pRep->accelDenominator, n);
+ swaps(&pRep->threshold, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SGetScreenSaverReply(ClientPtr pClient, int size, xGetScreenSaverReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swaps(&pRep->timeout, n);
+ swaps(&pRep->interval, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+void
+SLHostsExtend(ClientPtr pClient, int size, char *buf)
+{
+ char *bufT = buf;
+ char *endbuf = buf + size;
+ while (bufT < endbuf) {
+ xHostEntry *host = (xHostEntry *) bufT;
+ int len = host->length;
+ register char n;
+ swaps (&host->length, n);
+ bufT += sizeof (xHostEntry) + (((len + 3) >> 2) << 2);
+ }
+ (void)WriteToClient (pClient, size, buf);
+}
+
+void
+SListHostsReply(ClientPtr pClient, int size, xListHostsReply *pRep)
+{
+ register char n;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swaps(&pRep->nHosts, n);
+ (void)WriteToClient(pClient, size, (char *) pRep);
+}
+
+
+
+void
+SErrorEvent(xError *from, xError *to)
+{
+ to->type = X_Error;
+ to->errorCode = from->errorCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->resourceID, to->resourceID);
+ cpswaps(from->minorCode, to->minorCode);
+ to->majorCode = from->majorCode;
+}
+
+void
+SKeyButtonPtrEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.keyButtonPointer.time,
+ to->u.keyButtonPointer.time);
+ cpswapl(from->u.keyButtonPointer.root,
+ to->u.keyButtonPointer.root);
+ cpswapl(from->u.keyButtonPointer.event,
+ to->u.keyButtonPointer.event);
+ cpswapl(from->u.keyButtonPointer.child,
+ to->u.keyButtonPointer.child);
+ cpswaps(from->u.keyButtonPointer.rootX,
+ to->u.keyButtonPointer.rootX);
+ cpswaps(from->u.keyButtonPointer.rootY,
+ to->u.keyButtonPointer.rootY);
+ cpswaps(from->u.keyButtonPointer.eventX,
+ to->u.keyButtonPointer.eventX);
+ cpswaps(from->u.keyButtonPointer.eventY,
+ to->u.keyButtonPointer.eventY);
+ cpswaps(from->u.keyButtonPointer.state,
+ to->u.keyButtonPointer.state);
+ to->u.keyButtonPointer.sameScreen =
+ from->u.keyButtonPointer.sameScreen;
+}
+
+void
+SEnterLeaveEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.enterLeave.time, to->u.enterLeave.time);
+ cpswapl(from->u.enterLeave.root, to->u.enterLeave.root);
+ cpswapl(from->u.enterLeave.event, to->u.enterLeave.event);
+ cpswapl(from->u.enterLeave.child, to->u.enterLeave.child);
+ cpswaps(from->u.enterLeave.rootX, to->u.enterLeave.rootX);
+ cpswaps(from->u.enterLeave.rootY, to->u.enterLeave.rootY);
+ cpswaps(from->u.enterLeave.eventX, to->u.enterLeave.eventX);
+ cpswaps(from->u.enterLeave.eventY, to->u.enterLeave.eventY);
+ cpswaps(from->u.enterLeave.state, to->u.enterLeave.state);
+ to->u.enterLeave.mode = from->u.enterLeave.mode;
+ to->u.enterLeave.flags = from->u.enterLeave.flags;
+}
+
+void
+SFocusEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.focus.window, to->u.focus.window);
+ to->u.focus.mode = from->u.focus.mode;
+}
+
+void
+SExposeEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.expose.window, to->u.expose.window);
+ cpswaps(from->u.expose.x, to->u.expose.x);
+ cpswaps(from->u.expose.y, to->u.expose.y);
+ cpswaps(from->u.expose.width, to->u.expose.width);
+ cpswaps(from->u.expose.height, to->u.expose.height);
+ cpswaps(from->u.expose.count, to->u.expose.count);
+}
+
+void
+SGraphicsExposureEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.graphicsExposure.drawable,
+ to->u.graphicsExposure.drawable);
+ cpswaps(from->u.graphicsExposure.x,
+ to->u.graphicsExposure.x);
+ cpswaps(from->u.graphicsExposure.y,
+ to->u.graphicsExposure.y);
+ cpswaps(from->u.graphicsExposure.width,
+ to->u.graphicsExposure.width);
+ cpswaps(from->u.graphicsExposure.height,
+ to->u.graphicsExposure.height);
+ cpswaps(from->u.graphicsExposure.minorEvent,
+ to->u.graphicsExposure.minorEvent);
+ cpswaps(from->u.graphicsExposure.count,
+ to->u.graphicsExposure.count);
+ to->u.graphicsExposure.majorEvent =
+ from->u.graphicsExposure.majorEvent;
+}
+
+void
+SNoExposureEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.noExposure.drawable, to->u.noExposure.drawable);
+ cpswaps(from->u.noExposure.minorEvent, to->u.noExposure.minorEvent);
+ to->u.noExposure.majorEvent = from->u.noExposure.majorEvent;
+}
+
+void
+SVisibilityEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.visibility.window, to->u.visibility.window);
+ to->u.visibility.state = from->u.visibility.state;
+}
+
+void
+SCreateNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.createNotify.window, to->u.createNotify.window);
+ cpswapl(from->u.createNotify.parent, to->u.createNotify.parent);
+ cpswaps(from->u.createNotify.x, to->u.createNotify.x);
+ cpswaps(from->u.createNotify.y, to->u.createNotify.y);
+ cpswaps(from->u.createNotify.width, to->u.createNotify.width);
+ cpswaps(from->u.createNotify.height, to->u.createNotify.height);
+ cpswaps(from->u.createNotify.borderWidth,
+ to->u.createNotify.borderWidth);
+ to->u.createNotify.override = from->u.createNotify.override;
+}
+
+void
+SDestroyNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.destroyNotify.event, to->u.destroyNotify.event);
+ cpswapl(from->u.destroyNotify.window, to->u.destroyNotify.window);
+}
+
+void
+SUnmapNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.unmapNotify.event, to->u.unmapNotify.event);
+ cpswapl(from->u.unmapNotify.window, to->u.unmapNotify.window);
+ to->u.unmapNotify.fromConfigure = from->u.unmapNotify.fromConfigure;
+}
+
+void
+SMapNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.mapNotify.event, to->u.mapNotify.event);
+ cpswapl(from->u.mapNotify.window, to->u.mapNotify.window);
+ to->u.mapNotify.override = from->u.mapNotify.override;
+}
+
+void
+SMapRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.mapRequest.parent, to->u.mapRequest.parent);
+ cpswapl(from->u.mapRequest.window, to->u.mapRequest.window);
+}
+
+void
+SReparentEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.reparent.event, to->u.reparent.event);
+ cpswapl(from->u.reparent.window, to->u.reparent.window);
+ cpswapl(from->u.reparent.parent, to->u.reparent.parent);
+ cpswaps(from->u.reparent.x, to->u.reparent.x);
+ cpswaps(from->u.reparent.y, to->u.reparent.y);
+ to->u.reparent.override = from->u.reparent.override;
+}
+
+void
+SConfigureNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.configureNotify.event,
+ to->u.configureNotify.event);
+ cpswapl(from->u.configureNotify.window,
+ to->u.configureNotify.window);
+ cpswapl(from->u.configureNotify.aboveSibling,
+ to->u.configureNotify.aboveSibling);
+ cpswaps(from->u.configureNotify.x, to->u.configureNotify.x);
+ cpswaps(from->u.configureNotify.y, to->u.configureNotify.y);
+ cpswaps(from->u.configureNotify.width, to->u.configureNotify.width);
+ cpswaps(from->u.configureNotify.height,
+ to->u.configureNotify.height);
+ cpswaps(from->u.configureNotify.borderWidth,
+ to->u.configureNotify.borderWidth);
+ to->u.configureNotify.override = from->u.configureNotify.override;
+}
+
+void
+SConfigureRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail; /* actually stack-mode */
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.configureRequest.parent,
+ to->u.configureRequest.parent);
+ cpswapl(from->u.configureRequest.window,
+ to->u.configureRequest.window);
+ cpswapl(from->u.configureRequest.sibling,
+ to->u.configureRequest.sibling);
+ cpswaps(from->u.configureRequest.x, to->u.configureRequest.x);
+ cpswaps(from->u.configureRequest.y, to->u.configureRequest.y);
+ cpswaps(from->u.configureRequest.width,
+ to->u.configureRequest.width);
+ cpswaps(from->u.configureRequest.height,
+ to->u.configureRequest.height);
+ cpswaps(from->u.configureRequest.borderWidth,
+ to->u.configureRequest.borderWidth);
+ cpswaps(from->u.configureRequest.valueMask,
+ to->u.configureRequest.valueMask);
+}
+
+
+void
+SGravityEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.gravity.event, to->u.gravity.event);
+ cpswapl(from->u.gravity.window, to->u.gravity.window);
+ cpswaps(from->u.gravity.x, to->u.gravity.x);
+ cpswaps(from->u.gravity.y, to->u.gravity.y);
+}
+
+void
+SResizeRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.resizeRequest.window, to->u.resizeRequest.window);
+ cpswaps(from->u.resizeRequest.width, to->u.resizeRequest.width);
+ cpswaps(from->u.resizeRequest.height, to->u.resizeRequest.height);
+}
+
+void
+SCirculateEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.circulate.event, to->u.circulate.event);
+ cpswapl(from->u.circulate.window, to->u.circulate.window);
+ cpswapl(from->u.circulate.parent, to->u.circulate.parent);
+ to->u.circulate.place = from->u.circulate.place;
+}
+
+void
+SPropertyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.property.window, to->u.property.window);
+ cpswapl(from->u.property.atom, to->u.property.atom);
+ cpswapl(from->u.property.time, to->u.property.time);
+ to->u.property.state = from->u.property.state;
+}
+
+void
+SSelectionClearEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.selectionClear.time, to->u.selectionClear.time);
+ cpswapl(from->u.selectionClear.window, to->u.selectionClear.window);
+ cpswapl(from->u.selectionClear.atom, to->u.selectionClear.atom);
+}
+
+void
+SSelectionRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.selectionRequest.time, to->u.selectionRequest.time);
+ cpswapl(from->u.selectionRequest.owner,
+ to->u.selectionRequest.owner);
+ cpswapl(from->u.selectionRequest.requestor,
+ to->u.selectionRequest.requestor);
+ cpswapl(from->u.selectionRequest.selection,
+ to->u.selectionRequest.selection);
+ cpswapl(from->u.selectionRequest.target,
+ to->u.selectionRequest.target);
+ cpswapl(from->u.selectionRequest.property,
+ to->u.selectionRequest.property);
+}
+
+void
+SSelectionNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.selectionNotify.time, to->u.selectionNotify.time);
+ cpswapl(from->u.selectionNotify.requestor,
+ to->u.selectionNotify.requestor);
+ cpswapl(from->u.selectionNotify.selection,
+ to->u.selectionNotify.selection);
+ cpswapl(from->u.selectionNotify.target,
+ to->u.selectionNotify.target);
+ cpswapl(from->u.selectionNotify.property,
+ to->u.selectionNotify.property);
+}
+
+void
+SColormapEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.colormap.window, to->u.colormap.window);
+ cpswapl(from->u.colormap.colormap, to->u.colormap.colormap);
+ to->u.colormap.new = from->u.colormap.new;
+ to->u.colormap.state = from->u.colormap.state;
+}
+
+void
+SMappingEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ to->u.mappingNotify.request = from->u.mappingNotify.request;
+ to->u.mappingNotify.firstKeyCode =
+ from->u.mappingNotify.firstKeyCode;
+ to->u.mappingNotify.count = from->u.mappingNotify.count;
+}
+
+void
+SClientMessageEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail; /* actually format */
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.clientMessage.window, to->u.clientMessage.window);
+ cpswapl(from->u.clientMessage.u.l.type,
+ to->u.clientMessage.u.l.type);
+ switch (from->u.u.detail) {
+ case 8:
+ memmove(to->u.clientMessage.u.b.bytes,
+ from->u.clientMessage.u.b.bytes,20);
+ break;
+ case 16:
+ cpswaps(from->u.clientMessage.u.s.shorts0,
+ to->u.clientMessage.u.s.shorts0);
+ cpswaps(from->u.clientMessage.u.s.shorts1,
+ to->u.clientMessage.u.s.shorts1);
+ cpswaps(from->u.clientMessage.u.s.shorts2,
+ to->u.clientMessage.u.s.shorts2);
+ cpswaps(from->u.clientMessage.u.s.shorts3,
+ to->u.clientMessage.u.s.shorts3);
+ cpswaps(from->u.clientMessage.u.s.shorts4,
+ to->u.clientMessage.u.s.shorts4);
+ cpswaps(from->u.clientMessage.u.s.shorts5,
+ to->u.clientMessage.u.s.shorts5);
+ cpswaps(from->u.clientMessage.u.s.shorts6,
+ to->u.clientMessage.u.s.shorts6);
+ cpswaps(from->u.clientMessage.u.s.shorts7,
+ to->u.clientMessage.u.s.shorts7);
+ cpswaps(from->u.clientMessage.u.s.shorts8,
+ to->u.clientMessage.u.s.shorts8);
+ cpswaps(from->u.clientMessage.u.s.shorts9,
+ to->u.clientMessage.u.s.shorts9);
+ break;
+ case 32:
+ cpswapl(from->u.clientMessage.u.l.longs0,
+ to->u.clientMessage.u.l.longs0);
+ cpswapl(from->u.clientMessage.u.l.longs1,
+ to->u.clientMessage.u.l.longs1);
+ cpswapl(from->u.clientMessage.u.l.longs2,
+ to->u.clientMessage.u.l.longs2);
+ cpswapl(from->u.clientMessage.u.l.longs3,
+ to->u.clientMessage.u.l.longs3);
+ cpswapl(from->u.clientMessage.u.l.longs4,
+ to->u.clientMessage.u.l.longs4);
+ break;
+ }
+}
+
+void
+SKeymapNotifyEvent(xEvent *from, xEvent *to)
+{
+ /* Keymap notify events are special; they have no
+ sequence number field, and contain entirely 8-bit data */
+ *to = *from;
+}
+
+_X_EXPORT void
+SwapConnSetupInfo(
+ char *pInfo,
+ char *pInfoT
+)
+{
+ int i, j, k;
+ xConnSetup *pConnSetup = (xConnSetup *)pInfo;
+ xDepth *depth;
+ xWindowRoot *root;
+
+ SwapConnSetup(pConnSetup, (xConnSetup *)pInfoT);
+ pInfo += sizeof(xConnSetup);
+ pInfoT += sizeof(xConnSetup);
+
+ /* Copy the vendor string */
+ i = (pConnSetup->nbytesVendor + 3) & ~3;
+ memcpy(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ /* The Pixmap formats don't need to be swapped, just copied. */
+ i = sizeof(xPixmapFormat) * pConnSetup->numFormats;
+ memcpy(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ for(i = 0; i < pConnSetup->numRoots; i++)
+ {
+ root = (xWindowRoot*)pInfo;
+ SwapWinRoot(root, (xWindowRoot *)pInfoT);
+ pInfo += sizeof(xWindowRoot);
+ pInfoT += sizeof(xWindowRoot);
+
+ for(j = 0; j < root->nDepths; j++)
+ {
+ depth = (xDepth*)pInfo;
+ ((xDepth *)pInfoT)->depth = depth->depth;
+ cpswaps(depth->nVisuals, ((xDepth *)pInfoT)->nVisuals);
+ pInfo += sizeof(xDepth);
+ pInfoT += sizeof(xDepth);
+ for(k = 0; k < depth->nVisuals; k++)
+ {
+ SwapVisual((xVisualType *)pInfo, (xVisualType *)pInfoT);
+ pInfo += sizeof(xVisualType);
+ pInfoT += sizeof(xVisualType);
+ }
+ }
+ }
+}
+
+
+void
+WriteSConnectionInfo(ClientPtr pClient, unsigned long size, char *pInfo)
+{
+ char *pInfoTBase;
+
+ pInfoTBase = (char *) ALLOCATE_LOCAL(size);
+ if (!pInfoTBase)
+ {
+ pClient->noClientException = -1;
+ return;
+ }
+ SwapConnSetupInfo(pInfo, pInfoTBase);
+ (void)WriteToClient(pClient, (int)size, (char *) pInfoTBase);
+ DEALLOCATE_LOCAL(pInfoTBase);
+}
+
+void
+SwapConnSetup(xConnSetup *pConnSetup, xConnSetup *pConnSetupT)
+{
+ cpswapl(pConnSetup->release, pConnSetupT->release);
+ cpswapl(pConnSetup->ridBase, pConnSetupT->ridBase);
+ cpswapl(pConnSetup->ridMask, pConnSetupT->ridMask);
+ cpswapl(pConnSetup->motionBufferSize, pConnSetupT->motionBufferSize);
+ cpswaps(pConnSetup->nbytesVendor, pConnSetupT->nbytesVendor);
+ cpswaps(pConnSetup->maxRequestSize, pConnSetupT->maxRequestSize);
+ pConnSetupT->minKeyCode = pConnSetup->minKeyCode;
+ pConnSetupT->maxKeyCode = pConnSetup->maxKeyCode;
+ pConnSetupT->numRoots = pConnSetup->numRoots;
+ pConnSetupT->numFormats = pConnSetup->numFormats;
+ pConnSetupT->imageByteOrder = pConnSetup->imageByteOrder;
+ pConnSetupT->bitmapBitOrder = pConnSetup->bitmapBitOrder;
+ pConnSetupT->bitmapScanlineUnit = pConnSetup->bitmapScanlineUnit;
+ pConnSetupT->bitmapScanlinePad = pConnSetup->bitmapScanlinePad;
+}
+
+void
+SwapWinRoot(xWindowRoot *pRoot, xWindowRoot *pRootT)
+{
+ cpswapl(pRoot->windowId, pRootT->windowId);
+ cpswapl(pRoot->defaultColormap, pRootT->defaultColormap);
+ cpswapl(pRoot->whitePixel, pRootT->whitePixel);
+ cpswapl(pRoot->blackPixel, pRootT->blackPixel);
+ cpswapl(pRoot->currentInputMask, pRootT->currentInputMask);
+ cpswaps(pRoot->pixWidth, pRootT->pixWidth);
+ cpswaps(pRoot->pixHeight, pRootT->pixHeight);
+ cpswaps(pRoot->mmWidth, pRootT->mmWidth);
+ cpswaps(pRoot->mmHeight, pRootT->mmHeight);
+ cpswaps(pRoot->minInstalledMaps, pRootT->minInstalledMaps);
+ cpswaps(pRoot->maxInstalledMaps, pRootT->maxInstalledMaps);
+ cpswapl(pRoot->rootVisualID, pRootT->rootVisualID);
+ pRootT->backingStore = pRoot->backingStore;
+ pRootT->saveUnders = pRoot->saveUnders;
+ pRootT->rootDepth = pRoot->rootDepth;
+ pRootT->nDepths = pRoot->nDepths;
+}
+
+void
+SwapVisual(xVisualType *pVis, xVisualType *pVisT)
+{
+ cpswapl(pVis->visualID, pVisT->visualID);
+ pVisT->class = pVis->class;
+ pVisT->bitsPerRGB = pVis->bitsPerRGB;
+ cpswaps(pVis->colormapEntries, pVisT->colormapEntries);
+ cpswapl(pVis->redMask, pVisT->redMask);
+ cpswapl(pVis->greenMask, pVisT->greenMask);
+ cpswapl(pVis->blueMask, pVisT->blueMask);
+}
+
+_X_EXPORT void
+SwapConnSetupPrefix(xConnSetupPrefix *pcspFrom, xConnSetupPrefix *pcspTo)
+{
+ pcspTo->success = pcspFrom->success;
+ pcspTo->lengthReason = pcspFrom->lengthReason;
+ cpswaps(pcspFrom->majorVersion, pcspTo->majorVersion);
+ cpswaps(pcspFrom->minorVersion, pcspTo->minorVersion);
+ cpswaps(pcspFrom->length, pcspTo->length);
+}
+
+void
+WriteSConnSetupPrefix(ClientPtr pClient, xConnSetupPrefix *pcsp)
+{
+ xConnSetupPrefix cspT;
+
+ SwapConnSetupPrefix(pcsp, &cspT);
+ (void)WriteToClient(pClient, sizeof(cspT), (char *) &cspT);
+}
diff --git a/xserver/dix/swapreq.c b/xserver/dix/swapreq.c
new file mode 100644
index 000000000..a6a211515
--- /dev/null
+++ b/xserver/dix/swapreq.c
@@ -0,0 +1,1100 @@
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <X11/Xprotostr.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h" /* for SendEvent */
+#include "swapreq.h"
+
+/* Thanks to Jack Palevich for testing and subsequently rewriting all this */
+
+/* Byte swap a list of longs */
+_X_EXPORT void
+SwapLongs (register CARD32 *list, register unsigned long count)
+{
+ register char n;
+
+ while (count >= 8) {
+ swapl(list+0, n);
+ swapl(list+1, n);
+ swapl(list+2, n);
+ swapl(list+3, n);
+ swapl(list+4, n);
+ swapl(list+5, n);
+ swapl(list+6, n);
+ swapl(list+7, n);
+ list += 8;
+ count -= 8;
+ }
+ if (count != 0) {
+ do {
+ swapl(list, n);
+ list++;
+ } while (--count != 0);
+ }
+}
+
+/* Byte swap a list of shorts */
+_X_EXPORT void
+SwapShorts (register short *list, register unsigned long count)
+{
+ register char n;
+
+ while (count >= 16) {
+ swaps(list+0, n);
+ swaps(list+1, n);
+ swaps(list+2, n);
+ swaps(list+3, n);
+ swaps(list+4, n);
+ swaps(list+5, n);
+ swaps(list+6, n);
+ swaps(list+7, n);
+ swaps(list+8, n);
+ swaps(list+9, n);
+ swaps(list+10, n);
+ swaps(list+11, n);
+ swaps(list+12, n);
+ swaps(list+13, n);
+ swaps(list+14, n);
+ swaps(list+15, n);
+ list += 16;
+ count -= 16;
+ }
+ if (count != 0) {
+ do {
+ swaps(list, n);
+ list++;
+ } while (--count != 0);
+ }
+}
+
+/* The following is used for all requests that have
+ no fields to be swapped (except "length") */
+int
+SProcSimpleReq(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xReq);
+ swaps(&stuff->length, n);
+ return(*ProcVector[stuff->reqType])(client);
+}
+
+/* The following is used for all requests that have
+ only a single 32-bit field to be swapped, coming
+ right after the "length" field */
+int
+SProcResourceReq(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xResourceReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xResourceReq); /* not EXACT */
+ swapl(&stuff->id, n);
+ return(*ProcVector[stuff->reqType])(client);
+}
+
+int
+SProcCreateWindow(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xCreateWindowReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+ swapl(&stuff->wid, n);
+ swapl(&stuff->parent, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swaps(&stuff->borderWidth, n);
+ swaps(&stuff->class, n);
+ swapl(&stuff->visual, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_CreateWindow])(client));
+}
+
+int
+SProcChangeWindowAttributes(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xChangeWindowAttributesReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->valueMask, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeWindowAttributes])(client));
+}
+
+int
+SProcReparentWindow(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xReparentWindowReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->parent, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ return((* ProcVector[X_ReparentWindow])(client));
+}
+
+int
+SProcConfigureWindow(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xConfigureWindowReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ swapl(&stuff->window, n);
+ swaps(&stuff->mask, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ConfigureWindow])(client));
+
+}
+
+
+int
+SProcInternAtom(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xInternAtomReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xInternAtomReq);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_InternAtom])(client));
+}
+
+int
+SProcChangeProperty(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xChangePropertyReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ switch ( stuff->format ) {
+ case 8 :
+ break;
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ return((* ProcVector[X_ChangeProperty])(client));
+}
+
+int
+SProcDeleteProperty(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xDeletePropertyReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ return((* ProcVector[X_DeleteProperty])(client));
+
+}
+
+int
+SProcGetProperty(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xGetPropertyReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ return((* ProcVector[X_GetProperty])(client));
+}
+
+int
+SProcSetSelectionOwner(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xSetSelectionOwnerReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->selection, n);
+ swapl(&stuff->time, n);
+ return((* ProcVector[X_SetSelectionOwner])(client));
+}
+
+int
+SProcConvertSelection(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xConvertSelectionReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ swapl(&stuff->requestor, n);
+ swapl(&stuff->selection, n);
+ swapl(&stuff->target, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->time, n);
+ return((* ProcVector[X_ConvertSelection])(client));
+}
+
+int
+SProcSendEvent(register ClientPtr client)
+{
+ register char n;
+ xEvent eventT;
+ EventSwapPtr proc;
+ REQUEST(xSendEventReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSendEventReq);
+ swapl(&stuff->destination, n);
+ swapl(&stuff->eventMask, n);
+
+ /* Swap event */
+ proc = EventSwapVector[stuff->event.u.u.type & 0177];
+ if (!proc || proc == NotImplemented) /* no swapping proc; invalid event type? */
+ return (BadValue);
+ (*proc)(&stuff->event, &eventT);
+ stuff->event = eventT;
+
+ return((* ProcVector[X_SendEvent])(client));
+}
+
+int
+SProcGrabPointer(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xGrabPointerReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ swapl(&stuff->grabWindow, n);
+ swaps(&stuff->eventMask, n);
+ swapl(&stuff->confineTo, n);
+ swapl(&stuff->cursor, n);
+ swapl(&stuff->time, n);
+ return((* ProcVector[X_GrabPointer])(client));
+}
+
+int
+SProcGrabButton(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xGrabButtonReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ swapl(&stuff->grabWindow, n);
+ swaps(&stuff->eventMask, n);
+ swapl(&stuff->confineTo, n);
+ swapl(&stuff->cursor, n);
+ swaps(&stuff->modifiers, n);
+ return((* ProcVector[X_GrabButton])(client));
+}
+
+int
+SProcUngrabButton(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xUngrabButtonReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ swapl(&stuff->grabWindow, n);
+ swaps(&stuff->modifiers, n);
+ return((* ProcVector[X_UngrabButton])(client));
+}
+
+int
+SProcChangeActivePointerGrab(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xChangeActivePointerGrabReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ swapl(&stuff->cursor, n);
+ swapl(&stuff->time, n);
+ swaps(&stuff->eventMask, n);
+ return((* ProcVector[X_ChangeActivePointerGrab])(client));
+}
+
+int
+SProcGrabKeyboard(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xGrabKeyboardReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+ swapl(&stuff->grabWindow, n);
+ swapl(&stuff->time, n);
+ return((* ProcVector[X_GrabKeyboard])(client));
+}
+
+int
+SProcGrabKey(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xGrabKeyReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+ swapl(&stuff->grabWindow, n);
+ swaps(&stuff->modifiers, n);
+ return((* ProcVector[X_GrabKey])(client));
+}
+
+int
+SProcUngrabKey(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xUngrabKeyReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ swapl(&stuff->grabWindow, n);
+ swaps(&stuff->modifiers, n);
+ return((* ProcVector[X_UngrabKey])(client));
+}
+
+int
+SProcGetMotionEvents(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xGetMotionEventsReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGetMotionEventsReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->start, n);
+ swapl(&stuff->stop, n);
+ return((* ProcVector[X_GetMotionEvents])(client));
+}
+
+int
+SProcTranslateCoords(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xTranslateCoordsReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ swapl(&stuff->srcWid, n);
+ swapl(&stuff->dstWid, n);
+ swaps(&stuff->srcX, n);
+ swaps(&stuff->srcY, n);
+ return((* ProcVector[X_TranslateCoords])(client));
+}
+
+int
+SProcWarpPointer(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xWarpPointerReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+ swapl(&stuff->srcWid, n);
+ swapl(&stuff->dstWid, n);
+ swaps(&stuff->srcX, n);
+ swaps(&stuff->srcY, n);
+ swaps(&stuff->srcWidth, n);
+ swaps(&stuff->srcHeight, n);
+ swaps(&stuff->dstX, n);
+ swaps(&stuff->dstY, n);
+ return((* ProcVector[X_WarpPointer])(client));
+}
+
+int
+SProcSetInputFocus(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xSetInputFocusReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+ swapl(&stuff->focus, n);
+ swapl(&stuff->time, n);
+ return((* ProcVector[X_SetInputFocus])(client));
+}
+
+int
+SProcOpenFont(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xOpenFontReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xOpenFontReq);
+ swapl(&stuff->fid, n);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_OpenFont])(client));
+}
+
+int
+SProcListFonts(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xListFontsReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xListFontsReq);
+ swaps(&stuff->maxNames, n);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_ListFonts])(client));
+}
+
+int
+SProcListFontsWithInfo(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xListFontsWithInfoReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xListFontsWithInfoReq);
+ swaps(&stuff->maxNames, n);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_ListFontsWithInfo])(client));
+}
+
+int
+SProcSetFontPath(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xSetFontPathReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+ swaps(&stuff->nFonts, n);
+ return((* ProcVector[X_SetFontPath])(client));
+}
+
+int
+SProcCreatePixmap(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCreatePixmapReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return((* ProcVector[X_CreatePixmap])(client));
+}
+
+int
+SProcCreateGC(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCreateGCReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ swapl(&stuff->gc, n);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_CreateGC])(client));
+}
+
+int
+SProcChangeGC(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xChangeGCReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ swapl(&stuff->gc, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeGC])(client));
+}
+
+int
+SProcCopyGC(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCopyGCReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ swapl(&stuff->srcGC, n);
+ swapl(&stuff->dstGC, n);
+ swapl(&stuff->mask, n);
+ return((* ProcVector[X_CopyGC])(client));
+}
+
+int
+SProcSetDashes(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xSetDashesReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xSetDashesReq);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->dashOffset, n);
+ swaps(&stuff->nDashes, n);
+ return((* ProcVector[X_SetDashes])(client));
+
+}
+
+int
+SProcSetClipRectangles(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xSetClipRectanglesReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->xOrigin, n);
+ swaps(&stuff->yOrigin, n);
+ SwapRestS(stuff);
+ return((* ProcVector[X_SetClipRectangles])(client));
+}
+
+int
+SProcClearToBackground(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xClearAreaReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ swapl(&stuff->window, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return((* ProcVector[X_ClearArea])(client));
+}
+
+int
+SProcCopyArea(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCopyAreaReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+ swapl(&stuff->srcDrawable, n);
+ swapl(&stuff->dstDrawable, n);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->srcX, n);
+ swaps(&stuff->srcY, n);
+ swaps(&stuff->dstX, n);
+ swaps(&stuff->dstY, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return((* ProcVector[X_CopyArea])(client));
+}
+
+int
+SProcCopyPlane(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCopyPlaneReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+ swapl(&stuff->srcDrawable, n);
+ swapl(&stuff->dstDrawable, n);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->srcX, n);
+ swaps(&stuff->srcY, n);
+ swaps(&stuff->dstX, n);
+ swaps(&stuff->dstY, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swapl(&stuff->bitPlane, n);
+ return((* ProcVector[X_CopyPlane])(client));
+}
+
+/* The following routine is used for all Poly drawing requests
+ (except FillPoly, which uses a different request format) */
+int
+SProcPoly(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xPolyPointReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->gc, n);
+ SwapRestS(stuff);
+ return((* ProcVector[stuff->reqType])(client));
+}
+
+/* cannot use SProcPoly for this one, because xFillPolyReq
+ is longer than xPolyPointReq, and we don't want to swap
+ the difference as shorts! */
+int
+SProcFillPoly(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xFillPolyReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->gc, n);
+ SwapRestS(stuff);
+ return((* ProcVector[X_FillPoly])(client));
+}
+
+int
+SProcPutImage(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xPutImageReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swaps(&stuff->dstX, n);
+ swaps(&stuff->dstY, n);
+ /* Image should already be swapped */
+ return((* ProcVector[X_PutImage])(client));
+
+}
+
+int
+SProcGetImage(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xGetImageReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGetImageReq);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swapl(&stuff->planeMask, n);
+ return((* ProcVector[X_GetImage])(client));
+}
+
+/* ProcPolyText used for both PolyText8 and PolyText16 */
+
+int
+SProcPolyText(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xPolyTextReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ return((* ProcVector[stuff->reqType])(client));
+}
+
+/* ProcImageText used for both ImageText8 and ImageText16 */
+
+int
+SProcImageText(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xImageTextReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xImageTextReq);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ return((* ProcVector[stuff->reqType])(client));
+}
+
+int
+SProcCreateColormap(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCreateColormapReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+ swapl(&stuff->mid, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->visual, n);
+ return((* ProcVector[X_CreateColormap])(client));
+}
+
+
+int
+SProcCopyColormapAndFree(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCopyColormapAndFreeReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ swapl(&stuff->mid, n);
+ swapl(&stuff->srcCmap, n);
+ return((* ProcVector[X_CopyColormapAndFree])(client));
+
+}
+
+int
+SProcAllocColor(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xAllocColorReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+ return((* ProcVector[X_AllocColor])(client));
+}
+
+int
+SProcAllocNamedColor(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xAllocNamedColorReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xAllocNamedColorReq);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_AllocNamedColor])(client));
+}
+
+int
+SProcAllocColorCells(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xAllocColorCellsReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->colors, n);
+ swaps(&stuff->planes, n);
+ return((* ProcVector[X_AllocColorCells])(client));
+}
+
+int
+SProcAllocColorPlanes(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xAllocColorPlanesReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->colors, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+ return((* ProcVector[X_AllocColorPlanes])(client));
+}
+
+int
+SProcFreeColors(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xFreeColorsReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ swapl(&stuff->cmap, n);
+ swapl(&stuff->planeMask, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_FreeColors])(client));
+
+}
+
+_X_EXPORT void
+SwapColorItem(xColorItem *pItem)
+{
+ register char n;
+
+ swapl(&pItem->pixel, n);
+ swaps(&pItem->red, n);
+ swaps(&pItem->green, n);
+ swaps(&pItem->blue, n);
+}
+
+int
+SProcStoreColors(register ClientPtr client)
+{
+ register char n;
+ long count;
+ xColorItem *pItem;
+
+ REQUEST(xStoreColorsReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ swapl(&stuff->cmap, n);
+ pItem = (xColorItem *) &stuff[1];
+ for(count = LengthRestB(stuff)/sizeof(xColorItem); --count >= 0; )
+ SwapColorItem(pItem++);
+ return((* ProcVector[X_StoreColors])(client));
+}
+
+int
+SProcStoreNamedColor (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xStoreNamedColorReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xStoreNamedColorReq);
+ swapl(&stuff->cmap, n);
+ swapl(&stuff->pixel, n);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_StoreNamedColor])(client));
+}
+
+int
+SProcQueryColors (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xQueryColorsReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ swapl(&stuff->cmap, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_QueryColors])(client));
+}
+
+int
+SProcLookupColor (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xLookupColorReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xLookupColorReq);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_LookupColor])(client));
+}
+
+int
+SProcCreateCursor (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCreateCursorReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ swapl(&stuff->cid, n);
+ swapl(&stuff->source, n);
+ swapl(&stuff->mask, n);
+ swaps(&stuff->foreRed, n);
+ swaps(&stuff->foreGreen, n);
+ swaps(&stuff->foreBlue, n);
+ swaps(&stuff->backRed, n);
+ swaps(&stuff->backGreen, n);
+ swaps(&stuff->backBlue, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ return((* ProcVector[X_CreateCursor])(client));
+}
+
+int
+SProcCreateGlyphCursor (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xCreateGlyphCursorReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ swapl(&stuff->cid, n);
+ swapl(&stuff->source, n);
+ swapl(&stuff->mask, n);
+ swaps(&stuff->sourceChar, n);
+ swaps(&stuff->maskChar, n);
+ swaps(&stuff->foreRed, n);
+ swaps(&stuff->foreGreen, n);
+ swaps(&stuff->foreBlue, n);
+ swaps(&stuff->backRed, n);
+ swaps(&stuff->backGreen, n);
+ swaps(&stuff->backBlue, n);
+ return((* ProcVector[X_CreateGlyphCursor])(client));
+}
+
+
+int
+SProcRecolorCursor (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xRecolorCursorReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ swapl(&stuff->cursor, n);
+ swaps(&stuff->foreRed, n);
+ swaps(&stuff->foreGreen, n);
+ swaps(&stuff->foreBlue, n);
+ swaps(&stuff->backRed, n);
+ swaps(&stuff->backGreen, n);
+ swaps(&stuff->backBlue, n);
+ return((* ProcVector[X_RecolorCursor])(client));
+}
+
+int
+SProcQueryBestSize (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xQueryBestSizeReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return((* ProcVector[X_QueryBestSize])(client));
+
+}
+
+int
+SProcQueryExtension (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xQueryExtensionReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xQueryExtensionReq);
+ swaps(&stuff->nbytes, n);
+ return((* ProcVector[X_QueryExtension])(client));
+}
+
+int
+SProcChangeKeyboardMapping (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xChangeKeyboardMappingReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeKeyboardMapping])(client));
+}
+
+
+int
+SProcChangeKeyboardControl (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xChangeKeyboardControlReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeKeyboardControl])(client));
+}
+
+int
+SProcChangePointerControl (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xChangePointerControlReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xChangePointerControlReq);
+ swaps(&stuff->accelNum, n);
+ swaps(&stuff->accelDenum, n);
+ swaps(&stuff->threshold, n);
+ return((* ProcVector[X_ChangePointerControl])(client));
+}
+
+
+int
+SProcSetScreenSaver (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xSetScreenSaverReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ swaps(&stuff->timeout, n);
+ swaps(&stuff->interval, n);
+ return((* ProcVector[X_SetScreenSaver])(client));
+}
+
+int
+SProcChangeHosts (register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(xChangeHostsReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xChangeHostsReq);
+ swaps(&stuff->hostLength, n);
+ return((* ProcVector[X_ChangeHosts])(client));
+
+}
+
+int SProcRotateProperties (register ClientPtr client)
+{
+ register char n;
+ REQUEST(xRotatePropertiesReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xRotatePropertiesReq);
+ swapl(&stuff->window, n);
+ swaps(&stuff->nAtoms, n);
+ swaps(&stuff->nPositions, n);
+ SwapRestL(stuff);
+ return ((* ProcVector[X_RotateProperties])(client));
+}
+
+int
+SProcNoOperation(register ClientPtr client)
+{
+ register char n;
+ REQUEST(xReq);
+ swaps(&stuff->length, n);
+ return ((* ProcVector[X_NoOperation])(client));
+}
+
+void
+SwapConnClientPrefix(xConnClientPrefix *pCCP)
+{
+ register char n;
+
+ swaps(&pCCP->majorVersion, n);
+ swaps(&pCCP->minorVersion, n);
+ swaps(&pCCP->nbytesAuthProto, n);
+ swaps(&pCCP->nbytesAuthString, n);
+}
diff --git a/xserver/dix/tables.c b/xserver/dix/tables.c
new file mode 100644
index 000000000..258ac0370
--- /dev/null
+++ b/xserver/dix/tables.c
@@ -0,0 +1,527 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE
+OPEN GROUP 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 The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "dixevents.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+
+#ifdef K5AUTH
+extern int
+ k5_stage1(), k5_stage2(), k5_stage3(), k5_bad();
+#endif
+
+int (* InitialVector[3]) (
+ ClientPtr /* client */
+ ) =
+{
+ 0,
+ ProcInitialConnection,
+ ProcEstablishConnection
+};
+
+_X_EXPORT int (* ProcVector[256]) (
+ ClientPtr /* client */
+ ) =
+{
+ ProcBadRequest,
+ ProcCreateWindow,
+ ProcChangeWindowAttributes,
+ ProcGetWindowAttributes,
+ ProcDestroyWindow,
+ ProcDestroySubwindows, /* 5 */
+ ProcChangeSaveSet,
+ ProcReparentWindow,
+ ProcMapWindow,
+ ProcMapSubwindows,
+ ProcUnmapWindow, /* 10 */
+ ProcUnmapSubwindows,
+ ProcConfigureWindow,
+ ProcCirculateWindow,
+ ProcGetGeometry,
+ ProcQueryTree, /* 15 */
+ ProcInternAtom,
+ ProcGetAtomName,
+ ProcChangeProperty,
+ ProcDeleteProperty,
+ ProcGetProperty, /* 20 */
+ ProcListProperties,
+ ProcSetSelectionOwner,
+ ProcGetSelectionOwner,
+ ProcConvertSelection,
+ ProcSendEvent, /* 25 */
+ ProcGrabPointer,
+ ProcUngrabPointer,
+ ProcGrabButton,
+ ProcUngrabButton,
+ ProcChangeActivePointerGrab, /* 30 */
+ ProcGrabKeyboard,
+ ProcUngrabKeyboard,
+ ProcGrabKey,
+ ProcUngrabKey,
+ ProcAllowEvents, /* 35 */
+ ProcGrabServer,
+ ProcUngrabServer,
+ ProcQueryPointer,
+ ProcGetMotionEvents,
+ ProcTranslateCoords, /* 40 */
+ ProcWarpPointer,
+ ProcSetInputFocus,
+ ProcGetInputFocus,
+ ProcQueryKeymap,
+ ProcOpenFont, /* 45 */
+ ProcCloseFont,
+ ProcQueryFont,
+ ProcQueryTextExtents,
+ ProcListFonts,
+ ProcListFontsWithInfo, /* 50 */
+ ProcSetFontPath,
+ ProcGetFontPath,
+ ProcCreatePixmap,
+ ProcFreePixmap,
+ ProcCreateGC, /* 55 */
+ ProcChangeGC,
+ ProcCopyGC,
+ ProcSetDashes,
+ ProcSetClipRectangles,
+ ProcFreeGC, /* 60 */
+ ProcClearToBackground,
+ ProcCopyArea,
+ ProcCopyPlane,
+ ProcPolyPoint,
+ ProcPolyLine, /* 65 */
+ ProcPolySegment,
+ ProcPolyRectangle,
+ ProcPolyArc,
+ ProcFillPoly,
+ ProcPolyFillRectangle, /* 70 */
+ ProcPolyFillArc,
+ ProcPutImage,
+ ProcGetImage,
+ ProcPolyText,
+ ProcPolyText, /* 75 */
+ ProcImageText8,
+ ProcImageText16,
+ ProcCreateColormap,
+ ProcFreeColormap,
+ ProcCopyColormapAndFree, /* 80 */
+ ProcInstallColormap,
+ ProcUninstallColormap,
+ ProcListInstalledColormaps,
+ ProcAllocColor,
+ ProcAllocNamedColor, /* 85 */
+ ProcAllocColorCells,
+ ProcAllocColorPlanes,
+ ProcFreeColors,
+ ProcStoreColors,
+ ProcStoreNamedColor, /* 90 */
+ ProcQueryColors,
+ ProcLookupColor,
+ ProcCreateCursor,
+ ProcCreateGlyphCursor,
+ ProcFreeCursor, /* 95 */
+ ProcRecolorCursor,
+ ProcQueryBestSize,
+ ProcQueryExtension,
+ ProcListExtensions,
+ ProcChangeKeyboardMapping, /* 100 */
+ ProcGetKeyboardMapping,
+ ProcChangeKeyboardControl,
+ ProcGetKeyboardControl,
+ ProcBell,
+ ProcChangePointerControl, /* 105 */
+ ProcGetPointerControl,
+ ProcSetScreenSaver,
+ ProcGetScreenSaver,
+ ProcChangeHosts,
+ ProcListHosts, /* 110 */
+ ProcChangeAccessControl,
+ ProcChangeCloseDownMode,
+ ProcKillClient,
+ ProcRotateProperties,
+ ProcForceScreenSaver, /* 115 */
+ ProcSetPointerMapping,
+ ProcGetPointerMapping,
+ ProcSetModifierMapping,
+ ProcGetModifierMapping,
+ 0, /* 120 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 125 */
+ 0,
+ ProcNoOperation
+};
+
+int (* SwappedProcVector[256]) (
+ ClientPtr /* client */
+ ) =
+{
+ ProcBadRequest,
+ SProcCreateWindow,
+ SProcChangeWindowAttributes,
+ SProcResourceReq, /* GetWindowAttributes */
+ SProcResourceReq, /* DestroyWindow */
+ SProcResourceReq, /* 5 DestroySubwindows */
+ SProcResourceReq, /* SProcChangeSaveSet, */
+ SProcReparentWindow,
+ SProcResourceReq, /* MapWindow */
+ SProcResourceReq, /* MapSubwindows */
+ SProcResourceReq, /* 10 UnmapWindow */
+ SProcResourceReq, /* UnmapSubwindows */
+ SProcConfigureWindow,
+ SProcResourceReq, /* SProcCirculateWindow, */
+ SProcResourceReq, /* GetGeometry */
+ SProcResourceReq, /* 15 QueryTree */
+ SProcInternAtom,
+ SProcResourceReq, /* SProcGetAtomName, */
+ SProcChangeProperty,
+ SProcDeleteProperty,
+ SProcGetProperty, /* 20 */
+ SProcResourceReq, /* SProcListProperties, */
+ SProcSetSelectionOwner,
+ SProcResourceReq, /* SProcGetSelectionOwner, */
+ SProcConvertSelection,
+ SProcSendEvent, /* 25 */
+ SProcGrabPointer,
+ SProcResourceReq, /* SProcUngrabPointer, */
+ SProcGrabButton,
+ SProcUngrabButton,
+ SProcChangeActivePointerGrab, /* 30 */
+ SProcGrabKeyboard,
+ SProcResourceReq, /* SProcUngrabKeyboard, */
+ SProcGrabKey,
+ SProcUngrabKey,
+ SProcResourceReq, /* 35 SProcAllowEvents, */
+ SProcSimpleReq, /* SProcGrabServer, */
+ SProcSimpleReq, /* SProcUngrabServer, */
+ SProcResourceReq, /* SProcQueryPointer, */
+ SProcGetMotionEvents,
+ SProcTranslateCoords, /*40 */
+ SProcWarpPointer,
+ SProcSetInputFocus,
+ SProcSimpleReq, /* SProcGetInputFocus, */
+ SProcSimpleReq, /* QueryKeymap, */
+ SProcOpenFont, /* 45 */
+ SProcResourceReq, /* SProcCloseFont, */
+ SProcResourceReq, /* SProcQueryFont, */
+ SProcResourceReq, /* SProcQueryTextExtents, */
+ SProcListFonts,
+ SProcListFontsWithInfo, /* 50 */
+ SProcSetFontPath,
+ SProcSimpleReq, /* GetFontPath, */
+ SProcCreatePixmap,
+ SProcResourceReq, /* SProcFreePixmap, */
+ SProcCreateGC, /* 55 */
+ SProcChangeGC,
+ SProcCopyGC,
+ SProcSetDashes,
+ SProcSetClipRectangles,
+ SProcResourceReq, /* 60 SProcFreeGC, */
+ SProcClearToBackground,
+ SProcCopyArea,
+ SProcCopyPlane,
+ SProcPoly, /* PolyPoint, */
+ SProcPoly, /* 65 PolyLine */
+ SProcPoly, /* PolySegment, */
+ SProcPoly, /* PolyRectangle, */
+ SProcPoly, /* PolyArc, */
+ SProcFillPoly,
+ SProcPoly, /* 70 PolyFillRectangle */
+ SProcPoly, /* PolyFillArc, */
+ SProcPutImage,
+ SProcGetImage,
+ SProcPolyText,
+ SProcPolyText, /* 75 */
+ SProcImageText,
+ SProcImageText,
+ SProcCreateColormap,
+ SProcResourceReq, /* SProcFreeColormap, */
+ SProcCopyColormapAndFree, /* 80 */
+ SProcResourceReq, /* SProcInstallColormap, */
+ SProcResourceReq, /* SProcUninstallColormap, */
+ SProcResourceReq, /* SProcListInstalledColormaps, */
+ SProcAllocColor,
+ SProcAllocNamedColor, /* 85 */
+ SProcAllocColorCells,
+ SProcAllocColorPlanes,
+ SProcFreeColors,
+ SProcStoreColors,
+ SProcStoreNamedColor, /* 90 */
+ SProcQueryColors,
+ SProcLookupColor,
+ SProcCreateCursor,
+ SProcCreateGlyphCursor,
+ SProcResourceReq, /* 95 SProcFreeCursor, */
+ SProcRecolorCursor,
+ SProcQueryBestSize,
+ SProcQueryExtension,
+ SProcSimpleReq, /* ListExtensions, */
+ SProcChangeKeyboardMapping, /* 100 */
+ SProcSimpleReq, /* GetKeyboardMapping, */
+ SProcChangeKeyboardControl,
+ SProcSimpleReq, /* GetKeyboardControl, */
+ SProcSimpleReq, /* Bell, */
+ SProcChangePointerControl, /* 105 */
+ SProcSimpleReq, /* GetPointerControl, */
+ SProcSetScreenSaver,
+ SProcSimpleReq, /* GetScreenSaver, */
+ SProcChangeHosts,
+ SProcSimpleReq, /* 110 ListHosts, */
+ SProcSimpleReq, /* SProcChangeAccessControl, */
+ SProcSimpleReq, /* SProcChangeCloseDownMode, */
+ SProcResourceReq, /* SProcKillClient, */
+ SProcRotateProperties,
+ SProcSimpleReq, /* 115 ForceScreenSaver */
+ SProcSimpleReq, /* SetPointerMapping, */
+ SProcSimpleReq, /* GetPointerMapping, */
+ SProcSimpleReq, /* SetModifierMapping, */
+ SProcSimpleReq, /* GetModifierMapping, */
+ 0, /* 120 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 125 */
+ 0,
+ SProcNoOperation
+};
+
+_X_EXPORT EventSwapPtr EventSwapVector[128] =
+{
+ (EventSwapPtr)SErrorEvent,
+ NotImplemented,
+ SKeyButtonPtrEvent,
+ SKeyButtonPtrEvent,
+ SKeyButtonPtrEvent,
+ SKeyButtonPtrEvent, /* 5 */
+ SKeyButtonPtrEvent,
+ SEnterLeaveEvent,
+ SEnterLeaveEvent,
+ SFocusEvent,
+ SFocusEvent, /* 10 */
+ SKeymapNotifyEvent,
+ SExposeEvent,
+ SGraphicsExposureEvent,
+ SNoExposureEvent,
+ SVisibilityEvent, /* 15 */
+ SCreateNotifyEvent,
+ SDestroyNotifyEvent,
+ SUnmapNotifyEvent,
+ SMapNotifyEvent,
+ SMapRequestEvent, /* 20 */
+ SReparentEvent,
+ SConfigureNotifyEvent,
+ SConfigureRequestEvent,
+ SGravityEvent,
+ SResizeRequestEvent, /* 25 */
+ SCirculateEvent,
+ SCirculateEvent,
+ SPropertyEvent,
+ SSelectionClearEvent,
+ SSelectionRequestEvent, /* 30 */
+ SSelectionNotifyEvent,
+ SColormapEvent,
+ SClientMessageEvent,
+ SMappingEvent,
+};
+
+
+_X_EXPORT ReplySwapPtr ReplySwapVector[256] =
+{
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetWindowAttributesReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 5 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 10 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetGeometryReply,
+ (ReplySwapPtr)SQueryTreeReply, /* 15 */
+ (ReplySwapPtr)SInternAtomReply,
+ (ReplySwapPtr)SGetAtomNameReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetPropertyReply, /* 20 */
+ (ReplySwapPtr)SListPropertiesReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetSelectionOwnerReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 25 */
+ (ReplySwapPtr)SGenericReply, /* SGrabPointerReply, */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 30 */
+ (ReplySwapPtr)SGenericReply, /* SGrabKeyboardReply, */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 35 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SQueryPointerReply,
+ (ReplySwapPtr)SGetMotionEventsReply,
+ (ReplySwapPtr)STranslateCoordsReply, /* 40 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetInputFocusReply,
+ (ReplySwapPtr)SQueryKeymapReply,
+ ReplyNotSwappd, /* 45 */
+ ReplyNotSwappd,
+ (ReplySwapPtr)SQueryFontReply,
+ (ReplySwapPtr)SQueryTextExtentsReply,
+ (ReplySwapPtr)SListFontsReply,
+ (ReplySwapPtr)SListFontsWithInfoReply, /* 50 */
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetFontPathReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 55 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 60 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 65 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 70 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetImageReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 75 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 80 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SListInstalledColormapsReply,
+ (ReplySwapPtr)SAllocColorReply,
+ (ReplySwapPtr)SAllocNamedColorReply, /* 85 */
+ (ReplySwapPtr)SAllocColorCellsReply,
+ (ReplySwapPtr)SAllocColorPlanesReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 90 */
+ (ReplySwapPtr)SQueryColorsReply,
+ (ReplySwapPtr)SLookupColorReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 95 */
+ ReplyNotSwappd,
+ (ReplySwapPtr)SQueryBestSizeReply,
+ (ReplySwapPtr)SGenericReply, /* SQueryExtensionReply, */
+ (ReplySwapPtr)SListExtensionsReply,
+ ReplyNotSwappd, /* 100 */
+ (ReplySwapPtr)SGetKeyboardMappingReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetKeyboardControlReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 105 */
+ (ReplySwapPtr)SGetPointerControlReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetScreenSaverReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SListHostsReply, /* 110 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 115 */
+ (ReplySwapPtr)SGenericReply, /* SetPointerMapping */
+ (ReplySwapPtr)SGetPointerMappingReply,
+ (ReplySwapPtr)SGenericReply, /* SetModifierMapping */
+ (ReplySwapPtr)SGetModifierMappingReply, /* 119 */
+ ReplyNotSwappd, /* 120 */
+ ReplyNotSwappd, /* 121 */
+ ReplyNotSwappd, /* 122 */
+ ReplyNotSwappd, /* 123 */
+ ReplyNotSwappd, /* 124 */
+ ReplyNotSwappd, /* 125 */
+ ReplyNotSwappd, /* 126 */
+ ReplyNotSwappd, /* NoOperation */
+ ReplyNotSwappd
+};
+
+#ifdef K5AUTH
+int (*k5_Vector[256])() =
+{
+ k5_bad,
+ k5_stage1,
+ k5_bad,
+ k5_stage3
+};
+#endif
diff --git a/xserver/dix/window.c b/xserver/dix/window.c
new file mode 100644
index 000000000..3dfeda36e
--- /dev/null
+++ b/xserver/dix/window.c
@@ -0,0 +1,3924 @@
+/*
+
+Copyright (c) 2006, 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.
+
+The above copyright notice and this permission notice 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
+RED HAT 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 Red Hat shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from Red Hat.
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE OPEN GROUP 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 The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+*/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+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.
+
+The above copyright notice and this permission notice 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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include "appgroup.h"
+#endif
+#ifdef XACE
+#include "xace.h"
+#endif
+
+/******
+ * Window stuff for server
+ *
+ * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ * GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
+static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+
+_X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
+
+_X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+ CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+ (!( ((b1)->x2 <= (b2)->x1) || \
+ ( ((b1)->x1 >= (b2)->x2)) || \
+ ( ((b1)->y2 <= (b2)->y1)) || \
+ ( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+_X_EXPORT int numSaveUndersViewable = 0;
+_X_EXPORT int deltaSaveUndersViewable = 0;
+
+#ifdef DEBUG
+/******
+ * PrintWindowTree
+ * For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+ WindowPtr p2;
+ int i;
+
+ while (p1)
+ {
+ p2 = p1->firstChild;
+ for (i=0; i<indent; i++) ErrorF( " ");
+ ErrorF( "%x\n", p1->drawable.id);
+ miPrintRegion(&p1->clipList);
+ PrintChildren(p2, indent+4);
+ p1 = p1->nextSib;
+ }
+}
+
+PrintWindowTree()
+{
+ int i;
+ WindowPtr pWin, p1;
+
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ErrorF( "WINDOW %d\n", i);
+ pWin = WindowTable[i];
+ miPrintRegion(&pWin->clipList);
+ p1 = pWin->firstChild;
+ PrintChildren(p1, 4);
+ }
+}
+#endif
+
+_X_EXPORT int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+{
+ register int result;
+ register WindowPtr pChild;
+
+ if (!(pChild = pWin))
+ return(WT_NOMATCH);
+ while (1)
+ {
+ result = (* func)(pChild, data);
+ if (result == WT_STOPWALKING)
+ return(WT_STOPWALKING);
+ if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
+ * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
+ * exit WalkTree. Does depth-first traverse.
+ *****/
+
+_X_EXPORT int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+{
+ return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool disableBackingStore = FALSE;
+Bool enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+ pWin->prevSib = NullWindow;
+ pWin->firstChild = NullWindow;
+ pWin->lastChild = NullWindow;
+
+ pWin->valdata = (ValidatePtr)NULL;
+ pWin->optional = (WindowOptPtr)NULL;
+ pWin->cursorIsNone = TRUE;
+
+ pWin->backingStore = NotUseful;
+ pWin->DIXsaveUnder = FALSE;
+ pWin->backStorage = (pointer) NULL;
+
+ pWin->mapped = FALSE; /* off */
+ pWin->realized = FALSE; /* off */
+ pWin->viewable = FALSE;
+ pWin->visibility = VisibilityNotViewable;
+ pWin->overrideRedirect = FALSE;
+ pWin->saveUnder = FALSE;
+
+ pWin->bitGravity = ForgetGravity;
+ pWin->winGravity = NorthWestGravity;
+
+ pWin->eventMask = 0;
+ pWin->deliverableEvents = 0;
+ pWin->dontPropagate = 0;
+ pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+ pWin->srcBuffer = DBE_FRONT_BUFFER;
+ pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+ pWin->redirectDraw = 0;
+#endif
+}
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ GCPtr pGC;
+ unsigned char back[128];
+ int len = BitmapBytePad(sizeof(long));
+ register unsigned char *from, *to;
+ register int i, j;
+
+ pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+ pScreen->rootDepth);
+
+ pWin->backgroundState = BackgroundPixmap;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pWin->background.pixmap || !pGC)
+ FatalError("could not create root tile");
+
+ {
+ CARD32 attributes[2];
+
+ attributes[0] = pScreen->whitePixel;
+ attributes[1] = pScreen->blackPixel;
+
+ (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+ }
+
+ ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+ from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+ to = back;
+
+ for (i = 4; i > 0; i--, from++)
+ for (j = len; j > 0; j--)
+ *to++ = *from;
+
+ (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+ 0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+ FreeScratchGC(pGC);
+
+}
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+ if (pWin)
+ {
+ ppriv = (DevUnion *)(pWin + 1);
+ pWin->devPrivates = ppriv;
+ sizes = pScreen->WindowPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+ for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+#if _XSERVER64
+ pWin->drawable.pad0 = 0;
+ pWin->drawable.pad1 = 0;
+#endif
+ }
+ return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ * Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ BoxRec box;
+ PixmapFormatRec *format;
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ return FALSE;
+
+ savedScreenInfo[pScreen->myNum].pWindow = NULL;
+ savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+ screenIsSaved = SCREEN_SAVER_OFF;
+
+ WindowTable[pScreen->myNum] = pWin;
+
+ pWin->drawable.pScreen = pScreen;
+ pWin->drawable.type = DRAWABLE_WINDOW;
+
+ pWin->drawable.depth = pScreen->rootDepth;
+ for (format = screenInfo.formats;
+ format->depth != pScreen->rootDepth;
+ format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->parent = NullWindow;
+ SetWindowToDefaults(pWin);
+
+ pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+ if (!pWin->optional)
+ return FALSE;
+
+ pWin->optional->dontPropagateMask = 0;
+ pWin->optional->otherEventMasks = 0;
+ pWin->optional->otherClients = NULL;
+ pWin->optional->passiveGrabs = NULL;
+ pWin->optional->userProps = NULL;
+ pWin->optional->backingBitPlanes = ~0L;
+ pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+ pWin->optional->boundingShape = NULL;
+ pWin->optional->clipShape = NULL;
+ pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ pWin->optional->inputMasks = NULL;
+#endif
+ pWin->optional->colormap = pScreen->defColormap;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->nextSib = NullWindow;
+
+ pWin->drawable.id = FakeClientID(0);
+
+ pWin->origin.x = pWin->origin.y = 0;
+ pWin->drawable.height = pScreen->height;
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.x = pWin->drawable.y = 0;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+ pWin->drawable.class = InputOutput;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = pScreen->whitePixel;
+
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = pScreen->blackPixel;
+ pWin->borderWidth = 0;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+ return FALSE;
+
+ if (disableBackingStore)
+ pScreen->backingStoreSupport = NotUseful;
+ if (enableBackingStore)
+ pScreen->backingStoreSupport = Always;
+
+#ifdef DO_SAVE_UNDERS
+ if ((pScreen->backingStoreSupport != NotUseful) &&
+ (pScreen->saveUnderSupport == NotUseful))
+ {
+ /*
+ * If the screen has backing-store but no save-unders, let the
+ * clients know we can support save-unders using backing-store.
+ */
+ pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (disableSaveUnders)
+ pScreen->saveUnderSupport = NotUseful;
+
+ return TRUE;
+}
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ int backFlag = CWBorderPixel | CWCursor | CWBackingStore;
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+
+ if (!blackRoot && !whiteRoot) {
+ MakeRootTile(pWin);
+ backFlag |= CWBackPixmap;
+ }
+ else {
+ if (blackRoot)
+ pWin->background.pixel = pScreen->blackPixel;
+ else
+ pWin->background.pixel = pScreen->whitePixel;
+ backFlag |= CWBackPixel;
+ }
+
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin, backFlag);
+
+#ifdef XACE
+ XaceHook(XACE_WINDOW_INIT, serverClient, pWin);
+#endif
+
+ MapWindow(pWin, serverClient);
+}
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize. The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+ register int x, register int y,
+ register int w, register int h)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+
+ box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+ /* we do these calculations to avoid overflows */
+ if (x > box.x1)
+ box.x1 = x;
+ if (y > box.y1)
+ box.y1 = y;
+ x += w;
+ if (x < box.x2)
+ box.x2 = x;
+ y += h;
+ if (y < box.y2)
+ box.y2 = y;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ REGION_RESET(pScreen, Rgn, &box);
+ REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+static RealChildHeadProc realChildHeadProc = NULL;
+
+void
+RegisterRealChildHeadProc (RealChildHeadProc proc)
+{
+ realChildHeadProc = proc;
+}
+
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+ if (realChildHeadProc) {
+ return realChildHeadProc (pWin);
+ }
+
+ if (!pWin->parent &&
+ (screenIsSaved == SCREEN_SAVER_ON) &&
+ (HasSaverWindow (pWin->drawable.pScreen->myNum)))
+ return (pWin->firstChild);
+ else
+ return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ * Makes a window in response to client request
+ *****/
+
+_X_EXPORT WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+ unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+ int depth, ClientPtr client, VisualID visual, int *error)
+{
+ register WindowPtr pWin;
+ WindowPtr pHead;
+ register ScreenPtr pScreen;
+ xEvent event;
+ int idepth, ivisual;
+ Bool fOK;
+ DepthPtr pDepth;
+ PixmapFormatRec *format;
+ register WindowOptPtr ancwopt;
+
+ if (class == CopyFromParent)
+ class = pParent->drawable.class;
+
+ if ((class != InputOutput) && (class != InputOnly))
+ {
+ *error = BadValue;
+ client->errorValue = class;
+ return NullWindow;
+ }
+
+ if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pScreen = pParent->drawable.pScreen;
+ if ((class == InputOutput) && (depth == 0))
+ depth = pParent->drawable.depth;
+ ancwopt = pParent->optional;
+ if (!ancwopt)
+ ancwopt = FindWindowWithOptional(pParent)->optional;
+ if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+ VisualID ag_visual;
+
+ if (client->appgroup && !pParent->parent &&
+ (ag_visual = XagRootVisual (client)))
+ visual = ag_visual;
+ else
+#endif
+ visual = ancwopt->visual;
+ }
+
+ /* Find out if the depth and visual are acceptable for this Screen */
+ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+ {
+ fOK = FALSE;
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+ {
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+ if ((depth == pDepth->depth) || (depth == 0))
+ {
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+ {
+ if (visual == pDepth->vids[ivisual])
+ {
+ fOK = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (fOK == FALSE)
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+ }
+
+ if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) &&
+ (depth != pParent->drawable.depth))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if (((vmask & CWColormap) == 0) &&
+ (class != InputOnly) &&
+ ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ {
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->drawable = pParent->drawable;
+ pWin->drawable.depth = depth;
+ if (depth == pParent->drawable.depth)
+ pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+ else
+ {
+ for (format = screenInfo.formats; format->depth != depth; format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+ }
+ if (class == InputOnly)
+ pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->drawable.id = wid;
+ pWin->drawable.class = class;
+
+ pWin->parent = pParent;
+ SetWindowToDefaults(pWin);
+
+ if (visual != ancwopt->visual)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ xfree (pWin);
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->optional->visual = visual;
+ pWin->optional->colormap = None;
+ }
+
+ pWin->borderWidth = bw;
+#ifdef XACE
+ /* can't let untrusted clients have background None windows;
+ * they make it too easy to steal window contents
+ */
+ if (!XaceHook(XACE_BACKGRND_ACCESS, client, pWin))
+ {
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = 0;
+ }
+ else
+#endif
+ pWin->backgroundState = None;
+
+ pWin->borderIsPixel = pParent->borderIsPixel;
+ pWin->border = pParent->border;
+ if (pWin->borderIsPixel == FALSE)
+ pWin->border.pixmap->refcnt++;
+
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ pWin->drawable.width = w;
+ pWin->drawable.height = h;
+ pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ /* set up clip list correctly for unobscured WindowPtr */
+ REGION_NULL(pScreen, &pWin->clipList);
+ REGION_NULL(pScreen, &pWin->borderClip);
+ REGION_NULL(pScreen, &pWin->winSize);
+ REGION_NULL(pScreen, &pWin->borderSize);
+
+#ifdef XACE
+ XaceHook(XACE_WINDOW_INIT, client, pWin);
+#endif
+
+ pHead = RealChildHead(pParent);
+ if (pHead)
+ {
+ pWin->nextSib = pHead->nextSib;
+ if (pHead->nextSib)
+ pHead->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pHead->nextSib = pWin;
+ pWin->prevSib = pHead;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ if (!(*pScreen->CreateWindow)(pWin))
+ {
+ *error = BadAlloc;
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ if (!(vmask & CWEventMask))
+ RecalculateDeliverableEvents(pWin);
+
+ if (vmask)
+ *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+ else
+ *error = Success;
+
+ if (*error != Success)
+ {
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+ {
+ XID value = defaultBackingStore;
+ (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+ pWin->forcedBS = TRUE;
+ }
+
+ if (SubSend(pParent))
+ {
+ event.u.u.type = CreateNotify;
+ event.u.createNotify.window = wid;
+ event.u.createNotify.parent = pParent->drawable.id;
+ event.u.createNotify.x = x;
+ event.u.createNotify.y = y;
+ event.u.createNotify.width = w;
+ event.u.createNotify.height = h;
+ event.u.createNotify.borderWidth = bw;
+ event.u.createNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pParent, &event, 1, NullWindow);
+ }
+ return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DeleteWindowFromAnySaveSet(pWin);
+ DeleteWindowFromAnySelections(pWin);
+ DeleteWindowFromAnyEvents(pWin, TRUE);
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ REGION_UNINIT(pScreen, &pWin->winSize);
+ REGION_UNINIT(pScreen, &pWin->borderClip);
+ REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ REGION_DESTROY(pScreen, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_DESTROY(pScreen, wClipShape (pWin));
+ if (wInputShape (pWin))
+ REGION_DESTROY(pScreen, wInputShape (pWin));
+#endif
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+ DeleteAllWindowProperties(pWin);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->DestroyWindow)(pWin);
+ DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+ register WindowPtr pChild, pSib, pParent;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ xEvent event;
+
+ if (!(pChild = pWin->firstChild))
+ return;
+ UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+ while (1)
+ {
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (1)
+ {
+ pParent = pChild->parent;
+ if (SubStrSend(pChild, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pChild->drawable.id;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ FreeResource(pChild->drawable.id, RT_WINDOW);
+ pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder && pChild->viewable)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ (*UnrealizeWindow)(pChild);
+ }
+ FreeWindowResources(pChild);
+ xfree(pChild);
+ if ( (pChild = pSib) )
+ break;
+ pChild = pParent;
+ pChild->firstChild = NullWindow;
+ pChild->lastChild = NullWindow;
+ if (pChild == pWin)
+ return;
+ }
+ }
+}
+
+/*****
+ * DeleteWindow
+ * Deletes child of window then window itself
+ * If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(pointer value, XID wid)
+ {
+ register WindowPtr pParent;
+ register WindowPtr pWin = (WindowPtr)value;
+ xEvent event;
+
+ UnmapWindow(pWin, FALSE);
+
+ CrushTree(pWin);
+
+ pParent = pWin->parent;
+ if (wid && pParent && SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pWin->drawable.id;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ FreeWindowResources(pWin);
+ if (pParent)
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ }
+ xfree(pWin);
+ return Success;
+}
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+ /* XXX
+ * The protocol is quite clear that each window should be
+ * destroyed in turn, however, unmapping all of the first
+ * eliminates most of the calls to ValidateTree. So,
+ * this implementation is incorrect in that all of the
+ * UnmapNotifies occur before all of the DestroyNotifies.
+ * If you care, simply delete the call to UnmapSubwindows.
+ */
+ UnmapSubwindows(pWin);
+ while (pWin->lastChild)
+ FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+ ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ * ChangeWindowAttributes
+ *
+ * The value-mask specifies which attributes are to be changed; the
+ * value-list contains one value for each one bit in the mask, from least
+ * to most significant bit in the mask.
+ *****/
+
+_X_EXPORT int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+ register Mask index2;
+ register XID *pVlist;
+ PixmapPtr pPixmap;
+ Pixmap pixID;
+ CursorPtr pCursor, pOldCursor;
+ Cursor cursorID;
+ WindowPtr pChild;
+ Colormap cmap;
+ ColormapPtr pCmap;
+ xEvent xE;
+ int result;
+ register ScreenPtr pScreen;
+ Mask vmaskCopy = 0;
+ register Mask tmask;
+ unsigned int val;
+ int error;
+ Bool checkOptional = FALSE;
+ Bool borderRelative = FALSE;
+ WindowPtr pLayerWin;
+
+ if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+ return BadMatch;
+
+ error = Success;
+ pScreen = pWin->drawable.pScreen;
+ pVlist = vlist;
+ tmask = vmask;
+ while (tmask)
+ {
+ index2 = (Mask) lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBackPixmap:
+ pixID = (Pixmap )*pVlist;
+ pVlist++;
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pixID == None)
+ {
+#ifdef XACE
+ /* can't let untrusted clients have background None windows */
+ if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin))
+ {
+#endif
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = None;
+#ifdef XACE
+ }
+ else
+ { /* didn't change the background to None, so don't tell ddx */
+ index2 = 0;
+ }
+#endif
+ }
+ else if (pixID == ParentRelative)
+ {
+ if (pWin->parent &&
+ pWin->drawable.depth != pWin->parent->drawable.depth)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = ParentRelative;
+ borderRelative = TRUE;
+ /* Note that the parent's backgroundTile's refcnt is NOT
+ * incremented. */
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap != (PixmapPtr) NULL)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixmap;
+ pWin->background.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBackPixel:
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = (CARD32 ) *pVlist;
+ /* background pixel overrides background pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBackPixmap;
+ pVlist++;
+ break;
+ case CWBorderPixmap:
+ pixID = (Pixmap ) *pVlist;
+ pVlist++;
+ if (pixID == CopyFromParent)
+ {
+ if (!pWin->parent ||
+ (pWin->drawable.depth != pWin->parent->drawable.depth))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->border = pWin->parent->border;
+ if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+ {
+ index2 = CWBorderPixel;
+ }
+ else
+ {
+ pWin->parent->border.pixmap->refcnt++;
+ }
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = FALSE;
+ pWin->border.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBorderPixel:
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = (CARD32) *pVlist;
+ /* border pixel overrides border pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBorderPixmap;
+ pVlist++;
+ break;
+ case CWBitGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->bitGravity = val;
+ break;
+ case CWWinGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->winGravity = val;
+ break;
+ case CWBackingStore:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->backingStore = val;
+ pWin->forcedBS = FALSE;
+ break;
+ case CWBackingPlanes:
+ if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+ if ((CARD32)*pVlist == (CARD32)~0L)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWBackingPixel:
+ if (pWin->optional || (CARD32) *pVlist) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingPixel = (CARD32) *pVlist;
+ if (!*pVlist)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWSaveUnder:
+ val = (BOOL) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+#ifdef DO_SAVE_UNDERS
+ if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+ DO_SAVE_UNDERS(pWin))
+ {
+ /*
+ * Re-check all siblings and inferiors for obscurity or
+ * exposition (hee hee).
+ */
+ if (pWin->saveUnder)
+ deltaSaveUndersViewable--;
+ else
+ deltaSaveUndersViewable++;
+ pWin->saveUnder = val;
+
+ if (pWin->firstChild)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+ if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+ pWin->nextSib);
+ }
+ else
+ {
+ if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ }
+ }
+ else
+ {
+ /* If we're changing the saveUnder attribute of the root
+ * window, all we do is set pWin->saveUnder so that
+ * GetWindowAttributes returns the right value. We don't
+ * do the "normal" save-under processing (as above).
+ * Hope that doesn't cause any problems.
+ */
+ pWin->saveUnder = val;
+ }
+#else
+ pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+ break;
+ case CWEventMask:
+ result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWDontPropagate:
+ result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+ &checkOptional);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWOverrideRedirect:
+ val = (BOOL ) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->overrideRedirect = val;
+ break;
+ case CWColormap:
+ cmap = (Colormap) *pVlist;
+ pVlist++;
+ if (cmap == CopyFromParent)
+ {
+#ifdef XAPPGROUP
+ Colormap ag_colormap;
+ ClientPtr win_owner;
+
+ /*
+ * win_owner == client for CreateWindow, other clients
+ * can ChangeWindowAttributes
+ */
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+ if ( win_owner && win_owner->appgroup &&
+ !pWin->parent->parent &&
+ (ag_colormap = XagDefaultColormap (win_owner)))
+ cmap = ag_colormap;
+ else
+#endif
+ if (pWin->parent &&
+ (!pWin->optional ||
+ pWin->optional->visual == wVisual (pWin->parent)))
+ {
+ cmap = wColormap (pWin->parent);
+ }
+ else
+ cmap = None;
+ }
+ if (cmap == None)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (!pCmap)
+ {
+ error = BadColor;
+ client->errorValue = cmap;
+ goto PatchUp;
+ }
+ if (pCmap->pVisual->vid != wVisual (pWin) ||
+ pCmap->pScreen != pScreen)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (cmap != wColormap (pWin))
+ {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && cmap == wColormap (pWin->parent))
+ checkOptional = TRUE;
+
+ /*
+ * propagate the original colormap to any children
+ * inheriting it
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pWin->optional->colormap = cmap;
+
+ /*
+ * check on any children now matching the new colormap
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional->colormap == cmap)
+ CheckWindowOptionalNeed (pChild);
+ }
+
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pWin->drawable.id;
+ xE.u.colormap.colormap = cmap;
+ xE.u.colormap.new = xTrue;
+ xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+ DeliverEvents(pWin, &xE, 1, NullWindow);
+ }
+ break;
+ case CWCursor:
+ cursorID = (Cursor ) *pVlist;
+ pVlist++;
+ /*
+ * install the new
+ */
+ if ( cursorID == None)
+ {
+ if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+ pCursor = rootCursor;
+ else
+ pCursor = (CursorPtr) None;
+ }
+ else
+ {
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+ RT_CURSOR, SecurityReadAccess);
+ if (!pCursor)
+ {
+ error = BadCursor;
+ client->errorValue = cursorID;
+ goto PatchUp;
+ }
+ }
+
+ if (pCursor != wCursor (pWin))
+ {
+ /*
+ * patch up child windows so they don't lose cursors.
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !pChild->cursorIsNone &&
+ !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pOldCursor = 0;
+ if (pCursor == (CursorPtr) None)
+ {
+ pWin->cursorIsNone = TRUE;
+ if (pWin->optional)
+ {
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = (CursorPtr) None;
+ checkOptional = TRUE;
+ }
+ } else {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && pCursor == wCursor (pWin->parent))
+ checkOptional = TRUE;
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = pCursor;
+ pCursor->refcnt++;
+ pWin->cursorIsNone = FALSE;
+ /*
+ * check on any children now matching the new cursor
+ */
+
+ for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional &&
+ (pChild->optional->cursor == pCursor))
+ CheckWindowOptionalNeed (pChild);
+ }
+ }
+
+ if (pWin->realized)
+ WindowHasNewCursor( pWin);
+
+ /* Can't free cursor until here - old cursor
+ * is needed in WindowHasNewCursor
+ */
+ if (pOldCursor)
+ FreeCursor (pOldCursor, (Cursor)0);
+ }
+ break;
+ default:
+ error = BadValue;
+ client->errorValue = vmask;
+ goto PatchUp;
+ }
+ vmaskCopy |= index2;
+ }
+PatchUp:
+ if (checkOptional)
+ CheckWindowOptionalNeed (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+ /*
+ If the border contents have changed, redraw the border.
+ Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+ for the tile to be rotated, and the correct function selected.
+ */
+ if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+ && pWin->viewable && HasBorder (pWin))
+ {
+ RegionRec exposed;
+
+ REGION_NULL(pScreen, &exposed);
+ REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+ (*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+ REGION_UNINIT(pScreen, &exposed);
+ }
+ return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ * Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+ wa->type = X_Reply;
+ wa->bitGravity = pWin->bitGravity;
+ wa->winGravity = pWin->winGravity;
+ if (pWin->forcedBS && pWin->backingStore != Always)
+ wa->backingStore = NotUseful;
+ else
+ wa->backingStore = pWin->backingStore;
+ wa->length = (sizeof(xGetWindowAttributesReply) -
+ sizeof(xGenericReply)) >> 2;
+ wa->sequenceNumber = client->sequence;
+ wa->backingBitPlanes = wBackingBitPlanes (pWin);
+ wa->backingPixel = wBackingPixel (pWin);
+ wa->saveUnder = (BOOL)pWin->saveUnder;
+ wa->override = pWin->overrideRedirect;
+ if (!pWin->mapped)
+ wa->mapState = IsUnmapped;
+ else if (pWin->realized)
+ wa->mapState = IsViewable;
+ else
+ wa->mapState = IsUnviewable;
+
+ wa->colormap = wColormap (pWin);
+ wa->mapInstalled = (wa->colormap == None) ? xFalse
+ : IsMapInstalled(wa->colormap, pWin);
+
+ wa->yourEventMask = EventMaskForClient(pWin, client);
+ wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+ wa->doNotPropagateMask = wDontPropagateMask (pWin);
+ wa->class = pWin->drawable.class;
+ wa->visualID = wVisual (pWin);
+}
+
+
+_X_EXPORT WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+ register WindowPtr pParent = pWin->parent;
+ WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+ if (pWin->nextSib != pNextSib)
+ {
+ WindowPtr pOldNextSib = pWin->nextSib;
+
+ if (!pNextSib) /* move to bottom */
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
+ * and pWin->nextSib != pNextSib
+ * therefore pWin->nextSib != NULL */
+ pFirstChange = pWin->nextSib;
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pParent->lastChild->nextSib = pWin;
+ pWin->prevSib = pParent->lastChild;
+ pWin->nextSib = NullWindow;
+ pParent->lastChild = pWin;
+ }
+ else if (pParent->firstChild == pNextSib) /* move to top */
+ {
+ pFirstChange = pWin;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = (WindowPtr ) NULL;
+ pNextSib->prevSib = pWin;
+ pParent->firstChild = pWin;
+ }
+ else /* move in middle of list */
+ {
+ WindowPtr pOldNext = pWin->nextSib;
+
+ pFirstChange = NullWindow;
+ if (pParent->firstChild == pWin)
+ pFirstChange = pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin) {
+ pFirstChange = pWin;
+ pParent->lastChild = pWin->prevSib;
+ }
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pNextSib;
+ pWin->prevSib = pNextSib->prevSib;
+ if (pNextSib->prevSib)
+ pNextSib->prevSib->nextSib = pWin;
+ pNextSib->prevSib = pWin;
+ if (!pFirstChange) { /* do we know it yet? */
+ pFirstChange = pParent->firstChild; /* no, search from top */
+ while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+ pFirstChange = pFirstChange->nextSib;
+ }
+ }
+ if(pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+ }
+
+#ifdef ROOTLESS
+ /*
+ * In rootless mode we can't optimize away window restacks.
+ * There may be non-X windows around, so even if the window
+ * is in the correct position from X's point of view,
+ * the underlying window system may want to reorder it.
+ */
+ else if (pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+ return( pFirstChange );
+}
+
+_X_EXPORT RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+ RegionPtr pRgn;
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+ box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+ pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+ }
+#endif
+ return pRgn;
+}
+
+_X_EXPORT void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + pWin->drawable.width;
+ box.y2 = pWin->drawable.y + pWin->drawable.height;
+ REGION_RESET (pScreen, &pWin->winSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+ pWin->drawable.x, pWin->drawable.y,
+ (int)pWin->drawable.width,
+ (int)pWin->drawable.height);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+ pWin->drawable.y);
+ }
+#endif
+}
+
+_X_EXPORT void
+SetBorderSize (register WindowPtr pWin)
+{
+ int bw;
+
+ if (HasBorder (pWin)) {
+ bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x - bw;
+ box.y1 = pWin->drawable.y - bw;
+ box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+ box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+ REGION_RESET (pScreen, &pWin->borderSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+ pWin->drawable.x - bw, pWin->drawable.y - bw,
+ (int)(pWin->drawable.width + (bw<<1)),
+ (int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+ if (wBoundingShape (pWin)) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+ wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+ pWin->drawable.y);
+ REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+ &pWin->winSize);
+ }
+#endif
+ } else {
+ REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+ &pWin->winSize);
+ }
+}
+
+/**
+ *
+ * \param x,y new window position
+ * \param oldx,oldy old window position
+ * \param destx,desty position relative to gravity
+ */
+
+_X_EXPORT void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+ int dw, int dh, unsigned gravity,
+ register int *destx, register int *desty)
+{
+ switch (gravity) {
+ case NorthGravity:
+ *destx = x + dw / 2;
+ *desty = y;
+ break;
+ case NorthEastGravity:
+ *destx = x + dw;
+ *desty = y;
+ break;
+ case WestGravity:
+ *destx = x;
+ *desty = y + dh / 2;
+ break;
+ case CenterGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh / 2;
+ break;
+ case EastGravity:
+ *destx = x + dw;
+ *desty = y + dh / 2;
+ break;
+ case SouthWestGravity:
+ *destx = x;
+ *desty = y + dh;
+ break;
+ case SouthGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh;
+ break;
+ case SouthEastGravity:
+ *destx = x + dw;
+ *desty = y + dh;
+ break;
+ case StaticGravity:
+ *destx = oldx;
+ *desty = oldy;
+ break;
+ default:
+ *destx = x;
+ *desty = y;
+ break;
+ }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+_X_EXPORT void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+ register ScreenPtr pScreen;
+ register WindowPtr pSib, pChild;
+ Bool resized = (dw || dh);
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+ {
+ if (resized && (pSib->winGravity > NorthWestGravity))
+ {
+ int cwsx, cwsy;
+
+ cwsx = pSib->origin.x;
+ cwsy = pSib->origin.y;
+ GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+ pSib->winGravity, &cwsx, &cwsy);
+ if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+ {
+ xEvent event;
+
+ event.u.u.type = GravityNotify;
+ event.u.gravity.window = pSib->drawable.id;
+ event.u.gravity.x = cwsx - wBorderWidth (pSib);
+ event.u.gravity.y = cwsy - wBorderWidth (pSib);
+ DeliverEvents (pSib, &event, 1, NullWindow);
+ pSib->origin.x = cwsx;
+ pSib->origin.y = cwsy;
+ }
+ }
+ pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+ pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+ SetWinSize (pSib);
+ SetBorderSize (pSib);
+ (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+
+ if ( (pChild = pSib->firstChild) )
+ {
+ while (1)
+ {
+ pChild->drawable.x = pChild->parent->drawable.x +
+ pChild->origin.x;
+ pChild->drawable.y = pChild->parent->drawable.y +
+ pChild->origin.y;
+ SetWinSize (pChild);
+ SetBorderSize (pChild);
+ (*pScreen->PositionWindow)(pChild,
+ pChild->drawable.x, pChild->drawable.y);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pSib))
+ pChild = pChild->parent;
+ if (pChild == pSib)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ }
+}
+
+#define GET_INT16(m, f) \
+ if (m & mask) \
+ { \
+ f = (INT16) *pVlist;\
+ pVlist++; \
+ }
+#define GET_CARD16(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD16) *pVlist;\
+ pVlist++;\
+ }
+
+#define GET_CARD8(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD8) *pVlist;\
+ pVlist++;\
+ }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ * returns Above if pSib above pMe in stack or Below otherwise
+ */
+
+static int
+IsSiblingAboveMe(
+ register WindowPtr pMe,
+ register WindowPtr pSib)
+{
+ register WindowPtr pWin;
+
+ pWin = pMe->parent->firstChild;
+ while (pWin)
+ {
+ if (pWin == pSib)
+ return(Above);
+ else if (pWin == pMe)
+ return(Below);
+ pWin = pWin->nextSib;
+ }
+ return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+ register WindowPtr pWin,
+ register BoxPtr pBox)
+{
+ pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+ pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+ pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+ + wBorderWidth (pWin);
+ pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+ + wBorderWidth (pWin);
+ return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+ register WindowPtr pWin,
+ BoxPtr pBox)
+{
+ RegionPtr pRgn;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ pRgn = REGION_CREATE(pScreen, pBox, 1);
+ if (wBoundingShape (pWin)) {
+ REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+ -pWin->origin.y);
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+ pWin->origin.y);
+ }
+ return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+ WindowPtr pWin,
+ BoxPtr pWinBox,
+ WindowPtr pSib,
+ BoxPtr pSibBox)
+{
+ RegionPtr pWinRgn, pSibRgn;
+ register ScreenPtr pScreen;
+ Bool ret;
+
+ if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+ return TRUE;
+ pScreen = pWin->drawable.pScreen;
+ pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+ pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+ REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+ ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pSibRgn);
+ return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+ WindowPtr pWin,
+ WindowPtr pHead,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+ WindowPtr pWin,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+/*
+ * WhereDoIGoInTheStack()
+ * Given pWin and pSib and the relationshipe smode, return
+ * the window that pWin should go ABOVE.
+ * If a pSib is specified:
+ * Above: pWin is placed just above pSib
+ * Below: pWin is placed just below pSib
+ * TopIf: if pSib occludes pWin, then pWin is placed
+ * at the top of the stack
+ * BottomIf: if pWin occludes pSib, then pWin is
+ * placed at the bottom of the stack
+ * Opposite: if pSib occludes pWin, then pWin is placed at the
+ * top of the stack, else if pWin occludes pSib, then
+ * pWin is placed at the bottom of the stack
+ *
+ * If pSib is NULL:
+ * Above: pWin is placed at the top of the stack
+ * Below: pWin is placed at the bottom of the stack
+ * TopIf: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack
+ * BottomIf: if pWin occludes any sibline, then pWin is placed at
+ * the bottom of the stack
+ * Opposite: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack, else if pWin occludes any
+ * sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ short x,
+ short y,
+ unsigned short w,
+ unsigned short h,
+ int smode)
+{
+ BoxRec box;
+ register ScreenPtr pScreen;
+ WindowPtr pHead, pFirst;
+
+ if ((pWin == pWin->parent->firstChild) &&
+ (pWin == pWin->parent->lastChild))
+ return((WindowPtr ) NULL);
+ pHead = RealChildHead(pWin->parent);
+ pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+ pScreen = pWin->drawable.pScreen;
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + (int)w;
+ box.y2 = y + (int)h;
+ switch (smode)
+ {
+ case Above:
+ if (pSib)
+ return(pSib);
+ else if (pWin == pFirst)
+ return(pWin->nextSib);
+ else
+ return(pFirst);
+ case Below:
+ if (pSib)
+ if (pSib->nextSib != pWin)
+ return(pSib->nextSib);
+ else
+ return(pWin->nextSib);
+ else
+ return NullWindow;
+ case TopIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)))
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ case BottomIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)))
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ case Opposite:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)))
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+ {
+ if (IsSiblingAboveMe(pWin, pSib) == Above)
+ return(pFirst);
+ else
+ return NullWindow;
+ }
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ {
+ /* If I'm occluded, I can't possibly be the first child
+ * if (pWin == pWin->parent->firstChild)
+ * return pWin->nextSib;
+ */
+ return(pFirst);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return pWin->nextSib;
+ default:
+ {
+ ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+ return pWin->nextSib;
+ }
+ }
+}
+
+static void
+ReflectStackChange(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ VTKind kind)
+{
+/* Note that pSib might be NULL */
+
+ Bool WasViewable = (Bool)pWin->viewable;
+ Bool anyMarked;
+ WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ /* if this is a root window, can't be restacked */
+ if (!pWin->parent)
+ return;
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ &pLayerWin);
+ if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN 0
+#define MOVE_WIN 1
+#define RESIZE_WIN 2
+#define REBORDER_WIN 3
+ register WindowPtr pSib = NullWindow;
+ register WindowPtr pParent = pWin->parent;
+ Window sibwid = 0;
+ Mask index2, tmask;
+ register XID *pVlist;
+ short x, y, beforeX, beforeY;
+ unsigned short w = pWin->drawable.width,
+ h = pWin->drawable.height,
+ bw = pWin->borderWidth;
+ int action, smode = Above;
+#ifdef XAPPGROUP
+ ClientPtr win_owner;
+ ClientPtr ag_leader = NULL;
+#endif
+ xEvent event;
+
+ if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+ return(BadMatch);
+
+ if ((mask & CWSibling) && !(mask & CWStackMode))
+ return(BadMatch);
+
+ pVlist = vlist;
+
+ if (pParent)
+ {
+ x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+ y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+ }
+ else
+ {
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ }
+ beforeX = x;
+ beforeY = y;
+ action = RESTACK_WIN;
+ if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ action = MOVE_WIN;
+ }
+ /* or should be resized */
+ else if (mask & (CWX | CWY | CWWidth | CWHeight))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ GET_CARD16(CWWidth, w);
+ GET_CARD16 (CWHeight, h);
+ if (!w || !h)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ action = RESIZE_WIN;
+ }
+ tmask = mask & ~ChangeMask;
+ while (tmask)
+ {
+ index2 = (Mask)lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBorderWidth:
+ GET_CARD16(CWBorderWidth, bw);
+ break;
+ case CWSibling:
+ sibwid = (Window ) *pVlist;
+ pVlist++;
+ pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+ RT_WINDOW, SecurityReadAccess);
+ if (!pSib)
+ {
+ client->errorValue = sibwid;
+ return(BadWindow);
+ }
+ if (pSib->parent != pParent)
+ return(BadMatch);
+ if (pSib == pWin)
+ return(BadMatch);
+ break;
+ case CWStackMode:
+ GET_CARD8(CWStackMode, smode);
+ if ((smode != TopIf) && (smode != BottomIf) &&
+ (smode != Opposite) && (smode != Above) && (smode != Below))
+ {
+ client->errorValue = smode;
+ return(BadValue);
+ }
+ break;
+ default:
+ client->errorValue = mask;
+ return(BadValue);
+ }
+ }
+ /* root really can't be reconfigured, so just return */
+ if (!pParent)
+ return Success;
+
+ /* Figure out if the window should be moved. Doesnt
+ make the changes to the window if event sent */
+
+ if (mask & CWStackMode)
+ pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+ pParent->drawable.y + y,
+ w + (bw << 1), h + (bw << 1), smode);
+ else
+ pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = ConfigureRequest;
+ event.u.configureRequest.window = pWin->drawable.id;
+ if (mask & CWSibling)
+ event.u.configureRequest.sibling = sibwid;
+ else
+ event.u.configureRequest.sibling = None;
+ if (mask & CWStackMode)
+ event.u.u.detail = smode;
+ else
+ event.u.u.detail = Above;
+ event.u.configureRequest.x = x;
+ event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureRequest.x += panoramiXdataPtr[0].x;
+ event.u.configureRequest.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureRequest.width = w;
+ event.u.configureRequest.height = h;
+ event.u.configureRequest.borderWidth = bw;
+ event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.configureRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.configureRequest.parent = pParent->drawable.id;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+ if (action == RESIZE_WIN)
+ {
+ Bool size_change = (w != pWin->drawable.width)
+ || (h != pWin->drawable.height);
+ if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+ {
+ xEvent eventT;
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = w;
+ eventT.u.resizeRequest.height = h;
+ if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+ ResizeRedirectMask, client) == 1)
+ {
+ /* if event is delivered, leave the actual size alone. */
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ size_change = FALSE;
+ }
+ }
+ if (!size_change)
+ {
+ if (mask & (CWX | CWY))
+ action = MOVE_WIN;
+ else if (mask & (CWStackMode | CWBorderWidth))
+ action = RESTACK_WIN;
+ else /* really nothing to do */
+ return(Success) ;
+ }
+ }
+
+ if (action == RESIZE_WIN)
+ /* we've already checked whether there's really a size change */
+ goto ActuallyDoSomething;
+ if ((mask & CWX) && (x != beforeX))
+ goto ActuallyDoSomething;
+ if ((mask & CWY) && (y != beforeY))
+ goto ActuallyDoSomething;
+ if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+ goto ActuallyDoSomething;
+ if (mask & CWStackMode)
+ {
+#ifndef ROOTLESS
+ /* See above for why we always reorder in rootless mode. */
+ if (pWin->nextSib != pSib)
+#endif
+ goto ActuallyDoSomething;
+ }
+ return(Success);
+
+ActuallyDoSomething:
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ if (pSib)
+ event.u.configureNotify.aboveSibling = pSib->drawable.id;
+ else
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = x;
+ event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureNotify.x += panoramiXdataPtr[0].x;
+ event.u.configureNotify.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureNotify.width = w;
+ event.u.configureNotify.height = h;
+ event.u.configureNotify.borderWidth = bw;
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (mask & CWBorderWidth)
+ {
+ if (action == RESTACK_WIN)
+ {
+ action = MOVE_WIN;
+ pWin->borderWidth = bw;
+ }
+ else if ((action == MOVE_WIN) &&
+ (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+ (beforeY + wBorderWidth (pWin) == y + (int)bw))
+ {
+ action = REBORDER_WIN;
+ (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+ }
+ else
+ pWin->borderWidth = bw;
+ }
+ if (action == MOVE_WIN)
+ (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+ (mask & CWBorderWidth) ? VTOther : VTMove);
+ else if (action == RESIZE_WIN)
+ (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ else if (mask & CWStackMode)
+ ReflectStackChange(pWin, pSib, VTOther);
+
+ if (action != RESTACK_WIN)
+ CheckCursorConfinement(pWin);
+ return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ * For RaiseLowest, raises the lowest mapped child (if any) that is
+ * obscured by another child to the top of the stack. For LowerHighest,
+ * lowers the highest mapped child (if any) that is obscuring another
+ * child to the bottom of the stack. Exposure processing is performed
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+ register WindowPtr pWin, pHead, pFirst;
+ xEvent event;
+ BoxRec box;
+
+ pHead = RealChildHead(pParent);
+ pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+ if (direction == RaiseLowest)
+ {
+ for (pWin = pParent->lastChild;
+ (pWin != pHead) &&
+ !(pWin->mapped &&
+ AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+ pWin = pWin->prevSib) ;
+ if (pWin == pHead)
+ return Success;
+ }
+ else
+ {
+ for (pWin = pFirst;
+ pWin &&
+ !(pWin->mapped &&
+ IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+ pWin = pWin->nextSib) ;
+ if (!pWin)
+ return Success;
+ }
+
+ event.u.circulate.window = pWin->drawable.id;
+ event.u.circulate.parent = pParent->drawable.id;
+ event.u.circulate.event = pParent->drawable.id;
+ if (direction == RaiseLowest)
+ event.u.circulate.place = PlaceOnTop;
+ else
+ event.u.circulate.place = PlaceOnBottom;
+
+ if (RedirectSend(pParent))
+ {
+ event.u.u.type = CirculateRequest;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ event.u.u.type = CirculateNotify;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ ReflectStackChange(pWin,
+ (direction == RaiseLowest) ? pFirst : NullWindow,
+ VTStack);
+
+ return(Success);
+}
+
+static int
+CompareWIDs(
+ WindowPtr pWin,
+ pointer value) /* must conform to VisitWindowProcPtr */
+{
+ Window *wid = (Window *)value;
+
+ if (pWin->drawable.id == *wid)
+ return(WT_STOPWALKING);
+ else
+ return(WT_WALKCHILDREN);
+}
+
+/*****
+ * ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+ int x, int y, ClientPtr client)
+{
+ WindowPtr pPrev, pPriorParent;
+ Bool WasMapped = (Bool)(pWin->mapped);
+ xEvent event;
+ int bw = wBorderWidth (pWin);
+ register ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+ return(BadMatch);
+ if (!MakeWindowOptional(pWin))
+ return(BadAlloc);
+
+ if (WasMapped)
+ UnmapWindow(pWin, FALSE);
+
+ event.u.u.type = ReparentNotify;
+ event.u.reparent.window = pWin->drawable.id;
+ event.u.reparent.parent = pParent->drawable.id;
+ event.u.reparent.x = x;
+ event.u.reparent.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pParent->parent) {
+ event.u.reparent.x += panoramiXdataPtr[0].x;
+ event.u.reparent.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.reparent.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, pParent);
+
+ /* take out of sibling chain */
+
+ pPriorParent = pPrev = pWin->parent;
+ if (pPrev->firstChild == pWin)
+ pPrev->firstChild = pWin->nextSib;
+ if (pPrev->lastChild == pWin)
+ pPrev->lastChild = pWin->prevSib;
+
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+
+ /* insert at begining of pParent */
+ pWin->parent = pParent;
+ pPrev = RealChildHead(pParent);
+ if (pPrev)
+ {
+ pWin->nextSib = pPrev->nextSib;
+ if (pPrev->nextSib)
+ pPrev->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pPrev->nextSib = pWin;
+ pWin->prevSib = pPrev;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = NullWindow;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.x = x + bw + pParent->drawable.x;
+ pWin->drawable.y = y + bw + pParent->drawable.y;
+
+ /* clip to parent */
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow)(pWin, pPriorParent);
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ CheckWindowOptionalNeed(pWin);
+
+ if (WasMapped)
+ MapWindow(pWin, client);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+}
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+ register WindowPtr pChild;
+ RealizeWindowProcPtr Realize;
+
+ Realize = pWin->drawable.pScreen->RealizeWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->mapped)
+ {
+ pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable++;
+#endif
+ pChild->viewable = (pChild->drawable.class == InputOutput);
+ (* Realize)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * MapWindow
+ * If some other client has selected SubStructureReDirect on the parent
+ * and override-redirect is xFalse, then a MapRequest event is generated,
+ * but the window remains unmapped. Otherwise, the window is mapped and a
+ * MapNotify event is generated.
+ *****/
+
+_X_EXPORT int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+ register ScreenPtr pScreen;
+
+ register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (pWin->mapped)
+ return(Success);
+
+#ifdef XACE
+ /* general check for permission to map window */
+ if (!XaceHook(XACE_MAP_ACCESS, client, pWin))
+ return Success;
+#endif
+
+ pScreen = pWin->drawable.pScreen;
+ if ( (pParent = pWin->parent) )
+ {
+ xEvent event;
+ Bool anyMarked;
+#ifdef XAPPGROUP
+ ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.mapRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ pWin->mapped = TRUE;
+ if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pParent->realized)
+ return(Success);
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ }
+ WindowsRestructured ();
+ }
+ else
+ {
+ RegionRec temp;
+
+ pWin->mapped = TRUE;
+ pWin->realized = TRUE; /* for roots */
+ pWin->viewable = pWin->drawable.class == InputOutput;
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->RealizeWindow)(pWin);
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pWin, 0, 0);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+ REGION_NULL(pScreen, &temp);
+ REGION_COPY(pScreen, &temp, &pWin->clipList);
+ (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+ REGION_UNINIT(pScreen, &temp);
+ }
+
+ return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ * Performs a MapWindow all unmapped children of the window, in top
+ * to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+ register WindowPtr pWin;
+ WindowPtr pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+ WindowPtr pFirstSaveUndered = NullWindow;
+#endif
+ register ScreenPtr pScreen;
+ register Mask parentRedirect;
+ register Mask parentNotify;
+ xEvent event;
+ Bool anyMarked;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ pScreen = pParent->drawable.pScreen;
+ parentRedirect = RedirectSend(pParent);
+ parentNotify = SubSend(pParent);
+ anyMarked = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (!pWin->mapped)
+ {
+ if (parentRedirect && !pWin->overrideRedirect)
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ continue;
+ }
+
+ pWin->mapped = TRUE;
+ if (parentNotify || StrSend(pWin))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pFirstMapped)
+ pFirstMapped = pWin;
+ if (pParent->realized)
+ {
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = TRUE;
+ }
+#endif /* DO_SAVE_UNDERS */
+ }
+ }
+ }
+ }
+
+ if (pFirstMapped)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+ if (pLayerWin->parent != pParent) {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+ pLayerWin,
+ (WindowPtr *)NULL);
+ pFirstMapped = pLayerWin;
+ }
+ if (anyMarked)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pLayerWin->parent != pParent)
+ {
+ if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+ pLayerWin);
+ }
+ }
+ else if (dosave)
+ {
+ dosave = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ if (dosave && !pFirstSaveUndered)
+ pFirstSaveUndered = pWin;
+ }
+ }
+ }
+#endif /* DO_SAVE_UNDERS */
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin,
+ pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+ VTMap);
+ WindowsRestructured ();
+ }
+}
+
+static void
+UnrealizeTree(
+ WindowPtr pWin,
+ Bool fromConfigure)
+{
+ register WindowPtr pChild;
+ UnrealizeWindowProcPtr Unrealize;
+ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+ Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+ MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+ PanoramiXRes *win;
+ win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+ XRT_WINDOW);
+ if(win)
+ win->u.win.visibility = VisibilityNotViewable;
+ }
+#endif
+ (* Unrealize)(pChild);
+ DeleteWindowFromAnyEvents(pChild, FALSE);
+ if (pChild->viewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->backStorage)
+ (*pChild->drawable.pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * UnmapWindow
+ * If the window is already unmapped, this request has no effect.
+ * Otherwise, the window is unmapped and an UnMapNotify event is
+ * generated. Cannot unmap a root window.
+ *****/
+
+_X_EXPORT int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+ register WindowPtr pParent;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+ return(Success);
+ if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pWin->drawable.id;
+ event.u.unmapNotify.fromConfigure = fromConfigure;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (wasViewable && !fromConfigure)
+ {
+ pWin->valdata = UnmapValData;
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+ }
+ pWin->mapped = FALSE;
+ if (wasRealized)
+ UnrealizeTree(pWin, fromConfigure);
+ if (wasViewable)
+ {
+ if (!fromConfigure)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+ }
+ pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (!fromConfigure && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ }
+ if (wasRealized && !fromConfigure)
+ WindowsRestructured ();
+ return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ * Performs an UnmapWindow request with the specified mode on all mapped
+ * children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+ register WindowPtr pChild, pHead;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ Bool anyMarked = FALSE;
+ Mask parentNotify;
+ WindowPtr pLayerWin = NULL;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!pWin->firstChild)
+ return;
+ parentNotify = SubSend(pWin);
+ pHead = RealChildHead(pWin);
+
+ if (wasViewable)
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (pChild->mapped)
+ {
+ if (parentNotify || StrSend(pChild))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pChild->drawable.id;
+ event.u.unmapNotify.fromConfigure = xFalse;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ if (pChild->viewable)
+ {
+ pChild->valdata = UnmapValData;
+ anyMarked = TRUE;
+ }
+ pChild->mapped = FALSE;
+ if (pChild->realized)
+ UnrealizeTree(pChild, FALSE);
+ if (wasViewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (pChild->backStorage)
+ (*pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ }
+ }
+ }
+ if (wasViewable)
+ {
+ if (anyMarked)
+ {
+ if (pLayerWin->parent == pWin)
+ (*pScreen->MarkWindow)(pWin);
+ else
+ {
+ WindowPtr ptmp;
+ (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+
+ /* Windows between pWin and pLayerWin may not have been marked */
+ ptmp = pWin;
+
+ while (ptmp != pLayerWin->parent)
+ {
+ (*pScreen->MarkWindow)(ptmp);
+ ptmp = ptmp->parent;
+ }
+ pHead = pWin->firstChild;
+ }
+ (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ }
+ if (wasRealized)
+ WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ register int j;
+
+ for (j=0; j<client->numSaved; j++)
+ {
+ pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+ if (SaveSetToRoot(client->saveSet[j]))
+ pParent = WindowTable[pWin->drawable.pScreen->myNum];
+ else
+#endif
+ {
+ pParent = pWin->parent;
+ while (pParent && (wClient (pParent) == client))
+ pParent = pParent->parent;
+ }
+ if (pParent)
+ {
+ if (pParent != pWin->parent)
+ {
+ ReparentWindow(pWin, pParent,
+ pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+ pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+ client);
+ if(!pWin->realized && pWin->mapped)
+ pWin->mapped = FALSE;
+ }
+#ifdef XFIXES
+ if (SaveSetRemap (client->saveSet[j]))
+#endif
+ MapWindow(pWin, client);
+ }
+ }
+ xfree(client->saveSet);
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ * \param x,y in root
+ * \param box "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+ return(TRUE);
+ return(FALSE);
+}
+
+/**
+ *
+ * \param x,y in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+ x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return(TRUE);
+ return(FALSE);
+}
+
+
+_X_EXPORT RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen;
+ RegionPtr pReg;
+
+ pScreen = pWin->drawable.pScreen;
+ pReg = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->parent ||
+ screenIsSaved != SCREEN_SAVER_ON ||
+ !HasSaverWindow (pWin->drawable.pScreen->myNum))
+ {
+ REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+ }
+ return(pReg);
+}
+
+_X_EXPORT void
+SendVisibilityNotify(WindowPtr pWin)
+{
+ xEvent event;
+#ifndef NO_XINERAMA_PORT
+ unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+ /* This is not quite correct yet, but it's close */
+ if(!noPanoramiXExtension) {
+ PanoramiXRes *win;
+ WindowPtr pWin2;
+ int i, Scrnum;
+
+ Scrnum = pWin->drawable.pScreen->myNum;
+
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+ if(!win || (win->u.win.visibility == visibility))
+ return;
+
+ switch(visibility) {
+ case VisibilityUnobscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility == VisibilityPartiallyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ case VisibilityPartiallyObscured:
+ if(Scrnum) {
+ pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+ if (pWin2) pWin = pWin2;
+ }
+ break;
+ case VisibilityFullyObscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility != VisibilityFullyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ }
+
+ win->u.win.visibility = visibility;
+ }
+#endif
+
+ event.u.u.type = VisibilityNotify;
+ event.u.visibility.window = pWin->drawable.id;
+ event.u.visibility.state = visibility;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+static WindowPtr windowDisableMapUnmapEvents;
+
+void
+DisableMapUnmapEvents(WindowPtr pWin)
+{
+ assert (windowDisableMapUnmapEvents == NULL);
+
+ windowDisableMapUnmapEvents = pWin;
+}
+
+void
+EnableMapUnmapEvents(WindowPtr pWin)
+{
+ assert (windowDisableMapUnmapEvents != NULL);
+
+ windowDisableMapUnmapEvents = NULL;
+}
+
+Bool
+MapUnmapEventsEnabled(WindowPtr pWin)
+{
+ return pWin != windowDisableMapUnmapEvents;
+}
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+ WindowPtr pWin
+);
+#endif
+
+_X_EXPORT void
+SaveScreens(int on, int mode)
+{
+ int i;
+ int what;
+ int type;
+
+ if (on == SCREEN_SAVER_FORCER)
+ {
+ UpdateCurrentTimeIf();
+ lastDeviceEventTime = currentTime;
+ if (mode == ScreenSaverReset)
+ what = SCREEN_SAVER_OFF;
+ else
+ what = SCREEN_SAVER_ON;
+ type = what;
+ }
+ else
+ {
+ what = on;
+ type = what;
+ if (what == screenIsSaved)
+ type = SCREEN_SAVER_CYCLE;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (on == SCREEN_SAVER_FORCER)
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+ if (savedScreenInfo[i].ExternalScreenSaver)
+ {
+ if ((*savedScreenInfo[i].ExternalScreenSaver)
+ (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+ continue;
+ }
+ if (type == screenIsSaved)
+ continue;
+ switch (type) {
+ case SCREEN_SAVER_OFF:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ what);
+ }
+ else if (HasSaverWindow (i))
+ {
+ savedScreenInfo[i].pWindow = NullWindow;
+ FreeResource(savedScreenInfo[i].wid, RT_NONE);
+ }
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+ {
+ WindowPtr pWin = savedScreenInfo[i].pWindow;
+ /* make it look like screen saver is off, so that
+ * NotClippedByChildren will compute a clip list
+ * for the root window, so miPaintWindow works
+ */
+ screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+ (*pWin->drawable.pScreen->MoveWindow)(pWin,
+ (short)(-(rand() % RANDOM_WIDTH)),
+ (short)(-(rand() % RANDOM_WIDTH)),
+ pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ screenIsSaved = SCREEN_SAVER_ON;
+ }
+ /*
+ * Call the DDX saver in case it wants to do something
+ * at cycle time
+ */
+ else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ type);
+ }
+ break;
+ case SCREEN_SAVER_ON:
+ if (ScreenSaverBlanking != DontPreferBlanking)
+ {
+ if ((* screenInfo.screens[i]->SaveScreen)
+ (screenInfo.screens[i], what))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+ continue;
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_BLACK))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+ continue;
+ }
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_TILED))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+ }
+ else
+ savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+ break;
+ }
+ }
+ screenIsSaved = what;
+ if (mode == ScreenSaverReset)
+ SetScreenSaverTimer();
+}
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+ int j;
+ int result;
+ XID attributes[3];
+ Mask mask;
+ WindowPtr pWin;
+ CursorMetricRec cm;
+ unsigned char *srcbits, *mskbits;
+ CursorPtr cursor;
+ XID cursorID = 0;
+ int attri;
+
+ mask = 0;
+ attri = 0;
+ switch (kind) {
+ case SCREEN_IS_TILED:
+ switch (WindowTable[i]->backgroundState) {
+ case BackgroundPixel:
+ attributes[attri++] = WindowTable[i]->background.pixel;
+ mask |= CWBackPixel;
+ break;
+ case BackgroundPixmap:
+ attributes[attri++] = None;
+ mask |= CWBackPixmap;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SCREEN_IS_BLACK:
+ attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+ mask |= CWBackPixel;
+ break;
+ }
+ mask |= CWOverrideRedirect;
+ attributes[attri++] = xTrue;
+
+ /*
+ * create a blank cursor
+ */
+
+ cm.width=16;
+ cm.height=16;
+ cm.xhot=8;
+ cm.yhot=8;
+ srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ if (!srcbits || !mskbits)
+ {
+ xfree(srcbits);
+ xfree(mskbits);
+ cursor = 0;
+ }
+ else
+ {
+ for (j=0; j<BitmapBytePad(32)*16; j++)
+ srcbits[j] = mskbits[j] = 0x0;
+ cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+ if (cursor)
+ {
+ cursorID = FakeClientID(0);
+ if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+ {
+ attributes[attri] = cursorID;
+ mask |= CWCursor;
+ }
+ else
+ cursor = 0;
+ }
+ else
+ {
+ xfree (srcbits);
+ xfree (mskbits);
+ }
+ }
+
+ pWin = savedScreenInfo[i].pWindow =
+ CreateWindow(savedScreenInfo[i].wid,
+ WindowTable[i],
+ -RANDOM_WIDTH, -RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+ 0, InputOutput, mask, attributes, 0, serverClient,
+ wVisual (WindowTable[i]), &result);
+
+ if (cursor)
+ FreeResource (cursorID, RT_NONE);
+
+ if (!pWin)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW,
+ (pointer)savedScreenInfo[i].pWindow))
+ return FALSE;
+
+ if (mask & CWBackPixmap)
+ {
+ MakeRootTile (pWin);
+ (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+ }
+ MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+ if (kind == SCREEN_IS_TILED && logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure. Assumptions: some parent will
+ * contain the structure.
+ */
+
+_X_EXPORT WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+ do
+ w = w->parent;
+ while (!w->optional);
+ return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules. If so,
+ * release the optional record
+ */
+
+_X_EXPORT void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (!w->parent)
+ return;
+ optional = w->optional;
+ if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+ return;
+ if (optional->otherEventMasks != 0)
+ return;
+ if (optional->otherClients != NULL)
+ return;
+ if (optional->passiveGrabs != NULL)
+ return;
+ if (optional->userProps != NULL)
+ return;
+ if (optional->backingBitPlanes != ~0L)
+ return;
+ if (optional->backingPixel != 0)
+ return;
+#ifdef SHAPE
+ if (optional->boundingShape != NULL)
+ return;
+ if (optional->clipShape != NULL)
+ return;
+ if (optional->inputShape != NULL)
+ return;
+#endif
+#ifdef XINPUT
+ if (optional->inputMasks != NULL)
+ return;
+#endif
+ parentOptional = FindWindowWithOptional(w)->optional;
+ if (optional->visual != parentOptional->visual)
+ return;
+ if (optional->cursor != None &&
+ (optional->cursor != parentOptional->cursor ||
+ w->parent->cursorIsNone))
+ return;
+ if (optional->colormap != parentOptional->colormap)
+ return;
+ DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+_X_EXPORT Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (pWin->optional)
+ return TRUE;
+ optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+ if (!optional)
+ return FALSE;
+ optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+ optional->otherEventMasks = 0;
+ optional->otherClients = NULL;
+ optional->passiveGrabs = NULL;
+ optional->userProps = NULL;
+ optional->backingBitPlanes = ~0L;
+ optional->backingPixel = 0;
+#ifdef SHAPE
+ optional->boundingShape = NULL;
+ optional->clipShape = NULL;
+ optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ optional->inputMasks = NULL;
+#endif
+ parentOptional = FindWindowWithOptional(pWin)->optional;
+ optional->visual = parentOptional->visual;
+ if (!pWin->cursorIsNone)
+ {
+ optional->cursor = parentOptional->cursor;
+ optional->cursor->refcnt++;
+ }
+ else
+ {
+ optional->cursor = None;
+ }
+ optional->colormap = parentOptional->colormap;
+ pWin->optional = optional;
+ return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+ if (!pWin->optional)
+ return;
+ /*
+ * everything is peachy. Delete the optional record
+ * and clean up
+ */
+ /*
+ * TOG changed this code to:
+ *
+ * if (pWin->cursorIsNone == FALSE)
+ * FreeCursor (pWin->optional->cursor, (Cursor)0);
+ * pWin->cursorIsNone = TRUE;
+ *
+ * This is blatently wrong; windows without optionals can have
+ * two different cursor values, either None or sharing their
+ * parents cursor. This difference is controlled by the
+ * cursorIsNone value; when TRUE, the window has no cursor,
+ * when false, it shares its cursor with its parent; TOG
+ * made it impossible for a window to have a cursor without
+ * an optional record.
+ */
+ if (pWin->optional->cursor)
+ {
+ FreeCursor (pWin->optional->cursor, (Cursor)0);
+ pWin->cursorIsNone = FALSE;
+ }
+ else
+ pWin->cursorIsNone = TRUE;
+ xfree (pWin->optional);
+ pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ int x, y;
+ unsigned int width, height, size;
+ GC *pGC;
+ int thin, gap, d31;
+ DDXPointRec poly[4];
+ ChangeGCVal fore[2], back[2];
+ xrgb rgb[2];
+ BITS32 fmask, bmask;
+ ColormapPtr cmap;
+
+ pDraw = (DrawablePtr)pWin;
+ pScreen = pDraw->pScreen;
+ x = -pWin->origin.x;
+ y = -pWin->origin.y;
+ width = pScreen->width;
+ height = pScreen->height;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pGC)
+ return;
+
+ if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ if ((pWin->backgroundState == BackgroundPixel) &&
+ (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+ Pixel querypixels[2];
+
+ querypixels[0] = fore[0].val;
+ querypixels[1] = pWin->background.pixel;
+ QueryColors(cmap, 2, querypixels, rgb);
+ if ((rgb[0].red == rgb[1].red) &&
+ (rgb[0].green == rgb[1].green) &&
+ (rgb[0].blue == rgb[1].blue)) {
+ if (fore[0].val == pScreen->blackPixel)
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ }
+ }
+ fore[1].val = FillSolid;
+ fmask = GCForeground|GCFillStyle;
+ if (pWin->backgroundState == BackgroundPixel) {
+ back[0].val = pWin->background.pixel;
+ back[1].val = FillSolid;
+ bmask = GCForeground|GCFillStyle;
+ } else {
+ back[0].val = 0;
+ back[1].val = 0;
+ dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+ NULL, back);
+ back[0].val = FillTiled;
+ back[1].ptr = pWin->background.pixmap;
+ bmask = GCFillStyle|GCTile;
+ }
+
+ /* should be the same as the reference function XmuDrawLogo() */
+
+ size = width;
+ if (height < width)
+ size = height;
+ size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+ size &= ~1;
+ x += rand() % (width - size);
+ y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ * -----
+ * / /
+ * / /
+ * / /
+ * / /
+ * /____/
+ * d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+ thin = (size / 11);
+ if (thin < 1) thin = 1;
+ gap = (thin+3) / 4;
+ d31 = thin + thin + gap;
+ poly[0].x = x + size; poly[0].y = y;
+ poly[1].x = x + size-d31; poly[1].y = y;
+ poly[2].x = x + 0; poly[2].y = y + size;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ * ------
+ * / /
+ * / __ /
+ * / / /
+ * / / /
+ * /__/__/
+ */
+
+ poly[0].x = x + d31/2; poly[0].y = y + size;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)+(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ * ------
+ * / / /
+ * /--/ /
+ * / /
+ * / /
+ * /_____/
+ */
+
+ poly[0].x = x + size - d31/2; poly[0].y = y;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)-(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + size - d31; poly[3].y = y;
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ * b
+ * -----
+ * \ \
+ * \ \
+ * \ \
+ * \ \
+ * \____\
+ */
+
+ poly[0].x = x; poly[0].y = y;
+ poly[1].x = x + size/4; poly[1].y = y;
+ poly[2].x = x + size; poly[2].y = y + size;
+ poly[3].x = x + size - size/4; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ * /
+ * /
+ * /
+ * /
+ * /
+ */
+
+ poly[0].x = x + size- thin; poly[0].y = y;
+ poly[1].x = x + size-( thin+gap); poly[1].y = y;
+ poly[2].x = x + thin; poly[2].y = y + size;
+ poly[3].x = x + thin + gap; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+ FreeScratchGC(pGC);
+}
+
+#endif
diff --git a/xserver/dix/xpstubs.c b/xserver/dix/xpstubs.c
new file mode 100644
index 000000000..3276d9dfe
--- /dev/null
+++ b/xserver/dix/xpstubs.c
@@ -0,0 +1,79 @@
+/* $XFree86$ */
+/*
+Copyright 1996, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 THE OPEN GROUP 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 The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/font.h>
+#ifdef XPRINT
+#include "DiPrint.h"
+#else
+extern Bool XpClientIsBitmapClient(ClientPtr client);
+extern Bool XpClientIsPrintClient(ClientPtr client, FontPathElementPtr fpe);
+#endif
+
+Bool
+XpClientIsBitmapClient(
+ ClientPtr client)
+{
+ return TRUE;
+}
+
+Bool
+XpClientIsPrintClient(
+ ClientPtr client,
+ FontPathElementPtr fpe)
+{
+ return FALSE;
+}
+#ifdef XPRINT
+int
+PrinterOptions(
+ int argc,
+ char **argv,
+ int i)
+{
+ return i;
+}
+void
+PrinterInitOutput(
+ ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv)
+{
+}
+void PrinterUseMsg(void)
+{
+}
+void PrinterInitGlobals(void)
+{
+}
+#endif /* XPRINT */
+