aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-07-25 20:12:58 +0000
committermarha <marha@users.sourceforge.net>2009-07-25 20:12:58 +0000
commit2553bdd7c359cd87525d367761c86932cec5adff (patch)
treeae71245933c98474a699d3e392de5820879b2018 /xorg-server/dix
parente2c51f2ee7b0a3ea1a052fc49324057b4a4bbc78 (diff)
parent4a3dbb926ae3f5410198d7cc4f4ebe4f62eebf05 (diff)
downloadvcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.tar.gz
vcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.tar.bz2
vcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.zip
svn merge file:///D:/svnrepos/vcxsrv/branches/released .
Diffstat (limited to 'xorg-server/dix')
-rw-r--r--xorg-server/dix/CHANGES17
-rw-r--r--xorg-server/dix/Makefile.am26
-rw-r--r--xorg-server/dix/Makefile.in397
-rw-r--r--xorg-server/dix/cursor.c136
-rw-r--r--xorg-server/dix/devices.c1255
-rw-r--r--xorg-server/dix/dispatch.c48
-rw-r--r--xorg-server/dix/dixfonts.c106
-rw-r--r--xorg-server/dix/dixutils.c7
-rw-r--r--xorg-server/dix/enterleave.c1377
-rw-r--r--xorg-server/dix/enterleave.h95
-rw-r--r--xorg-server/dix/events.c3976
-rw-r--r--xorg-server/dix/extension.c7
-rw-r--r--xorg-server/dix/ffs.c4
-rw-r--r--xorg-server/dix/gc.c4
-rw-r--r--xorg-server/dix/getevents.c1144
-rw-r--r--xorg-server/dix/globals.c20
-rw-r--r--xorg-server/dix/glyphcurs.c4
-rw-r--r--xorg-server/dix/grabs.c34
-rw-r--r--xorg-server/dix/main.c110
-rw-r--r--xorg-server/dix/privates.c209
-rw-r--r--xorg-server/dix/property.c8
-rw-r--r--xorg-server/dix/protocol.txt17
-rw-r--r--xorg-server/dix/ptrveloc.c939
-rw-r--r--xorg-server/dix/resource.c6
-rw-r--r--xorg-server/dix/selection.c6
-rw-r--r--xorg-server/dix/strcasecmp.c70
-rw-r--r--xorg-server/dix/strcasestr.c64
-rw-r--r--xorg-server/dix/tables.c4
-rw-r--r--xorg-server/dix/window.c613
-rw-r--r--xorg-server/dix/xpstubs.c78
30 files changed, 7038 insertions, 3743 deletions
diff --git a/xorg-server/dix/CHANGES b/xorg-server/dix/CHANGES
deleted file mode 100644
index d8fb7c31a..000000000
--- a/xorg-server/dix/CHANGES
+++ /dev/null
@@ -1,17 +0,0 @@
-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/xorg-server/dix/Makefile.am b/xorg-server/dix/Makefile.am
index eb5e77946..4c2395d82 100644
--- a/xorg-server/dix/Makefile.am
+++ b/xorg-server/dix/Makefile.am
@@ -1,10 +1,4 @@
-standard_dix_libs = libdix.la libxpstubs.la
-
-if XPRINT
-noinst_LTLIBRARIES = $(standard_dix_libs) libXpdix.la
-else
-noinst_LTLIBRARIES = $(standard_dix_libs)
-endif
+noinst_LTLIBRARIES = libdix.la
AM_CFLAGS = $(DIX_CFLAGS) \
-DVENDOR_NAME=\""@VENDOR_NAME@"\" \
@@ -20,6 +14,8 @@ libdix_la_SOURCES = \
dispatch.h \
dixfonts.c \
dixutils.c \
+ enterleave.c \
+ enterleave.h \
events.c \
extension.c \
ffs.c \
@@ -33,26 +29,16 @@ libdix_la_SOURCES = \
pixmap.c \
privates.c \
property.c \
+ ptrveloc.c \
registry.c \
resource.c \
selection.c \
swaprep.c \
swapreq.c \
tables.c \
- window.c \
- strcasecmp.c \
- strcasestr.c
-
-libxpstubs_la_SOURCES = \
- xpstubs.c
-
-if XPRINT
-libXpdix_la_SOURCES = $(libdix_la_SOURCES)
-libXpdix_la_CPPFLAGS = -I$(top_srcdir)/hw/xprint
-libXpdix_la_CFLAGS = $(AM_CFLAGS) $(XPRINT_CFLAGS)
-endif
+ window.c
-EXTRA_DIST = buildatoms BuiltInAtoms CHANGES Xserver.d Xserver-dtrace.h.in
+EXTRA_DIST = buildatoms BuiltInAtoms Xserver.d Xserver-dtrace.h.in
# Install list of protocol names
miscconfigdir = $(SERVER_MISC_CONFIG_PATH)
diff --git a/xorg-server/dix/Makefile.in b/xorg-server/dix/Makefile.in
index c1a07a163..28de940f1 100644
--- a/xorg-server/dix/Makefile.in
+++ b/xorg-server/dix/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -47,56 +47,20 @@ 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)
-libXpdix_la_LIBADD =
-am__libXpdix_la_SOURCES_DIST = atom.c colormap.c cursor.c deprecated.c \
- devices.c dispatch.c dispatch.h dixfonts.c dixutils.c events.c \
- extension.c ffs.c gc.c getevents.c globals.c glyphcurs.c \
- grabs.c initatoms.c main.c pixmap.c privates.c property.c \
- registry.c resource.c selection.c swaprep.c swapreq.c tables.c \
- window.c strcasecmp.c strcasestr.c
-am__objects_1 = libXpdix_la-atom.lo libXpdix_la-colormap.lo \
- libXpdix_la-cursor.lo libXpdix_la-deprecated.lo \
- libXpdix_la-devices.lo libXpdix_la-dispatch.lo \
- libXpdix_la-dixfonts.lo libXpdix_la-dixutils.lo \
- libXpdix_la-events.lo libXpdix_la-extension.lo \
- libXpdix_la-ffs.lo libXpdix_la-gc.lo libXpdix_la-getevents.lo \
- libXpdix_la-globals.lo libXpdix_la-glyphcurs.lo \
- libXpdix_la-grabs.lo libXpdix_la-initatoms.lo \
- libXpdix_la-main.lo libXpdix_la-pixmap.lo \
- libXpdix_la-privates.lo libXpdix_la-property.lo \
- libXpdix_la-registry.lo libXpdix_la-resource.lo \
- libXpdix_la-selection.lo libXpdix_la-swaprep.lo \
- libXpdix_la-swapreq.lo libXpdix_la-tables.lo \
- libXpdix_la-window.lo libXpdix_la-strcasecmp.lo \
- libXpdix_la-strcasestr.lo
-@XPRINT_TRUE@am_libXpdix_la_OBJECTS = $(am__objects_1)
-libXpdix_la_OBJECTS = $(am_libXpdix_la_OBJECTS)
-libXpdix_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libXpdix_la_CFLAGS) \
- $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-@XPRINT_TRUE@am_libXpdix_la_rpath =
libdix_la_LIBADD =
am_libdix_la_OBJECTS = atom.lo colormap.lo cursor.lo deprecated.lo \
- devices.lo dispatch.lo dixfonts.lo dixutils.lo events.lo \
- extension.lo ffs.lo gc.lo getevents.lo globals.lo glyphcurs.lo \
- grabs.lo initatoms.lo main.lo pixmap.lo privates.lo \
- property.lo registry.lo resource.lo selection.lo swaprep.lo \
- swapreq.lo tables.lo window.lo strcasecmp.lo strcasestr.lo
+ devices.lo dispatch.lo dixfonts.lo dixutils.lo enterleave.lo \
+ events.lo extension.lo ffs.lo gc.lo getevents.lo globals.lo \
+ glyphcurs.lo grabs.lo initatoms.lo main.lo pixmap.lo \
+ privates.lo property.lo ptrveloc.lo registry.lo resource.lo \
+ selection.lo swaprep.lo swapreq.lo tables.lo window.lo
libdix_la_OBJECTS = $(am_libdix_la_OBJECTS)
-@XPRINT_FALSE@am_libdix_la_rpath =
-@XPRINT_TRUE@am_libdix_la_rpath =
-libxpstubs_la_LIBADD =
-am_libxpstubs_la_OBJECTS = xpstubs.lo
-libxpstubs_la_OBJECTS = $(am_libxpstubs_la_OBJECTS)
-@XPRINT_FALSE@am_libxpstubs_la_rpath =
-@XPRINT_TRUE@am_libxpstubs_la_rpath =
PROGRAMS = $(noinst_PROGRAMS)
dix_O_SOURCES = dix.c
dix_O_OBJECTS = dix.$(OBJEXT)
@@ -106,17 +70,12 @@ 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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libXpdix_la_SOURCES) $(libdix_la_SOURCES) \
- $(libxpstubs_la_SOURCES) dix.c
-DIST_SOURCES = $(am__libXpdix_la_SOURCES_DIST) $(libdix_la_SOURCES) \
- $(libxpstubs_la_SOURCES) dix.c
+SOURCES = $(libdix_la_SOURCES) dix.c
+DIST_SOURCES = $(libdix_la_SOURCES) dix.c
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -134,8 +93,9 @@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
-APPDEFAULTDIR = @APPDEFAULTDIR@
APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@
+APPLE_APPLICATION_ID = @APPLE_APPLICATION_ID@
+APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
@@ -156,10 +116,6 @@ CFLAGS = @CFLAGS@
COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DARWIN_LIBS = @DARWIN_LIBS@
DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -181,6 +137,7 @@ DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@
DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@
DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@
DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@
+DOLT_BASH = @DOLT_BASH@
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@
@@ -190,18 +147,15 @@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DRI_DRIVER_PATH = @DRI_DRIVER_PATH@
DSYMUTIL = @DSYMUTIL@
DTRACE = @DTRACE@
-ECHO = @ECHO@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
+FGREP = @FGREP@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
-FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
-FREETYPE_LIBS = @FREETYPE_LIBS@
GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@
GLX_DEFINES = @GLX_DEFINES@
GL_CFLAGS = @GL_CFLAGS@
@@ -220,7 +174,7 @@ KDRIVE_LIBS = @KDRIVE_LIBS@
KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@
KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@
KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@
-LAUNCHD = @LAUNCHD@
+LD = @LD@
LDFLAGS = @LDFLAGS@
LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@
LEX = @LEX@
@@ -234,7 +188,10 @@ LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LINUXDOC = @LINUXDOC@
+LIPO = @LIPO@
LN_S = @LN_S@
+LTCOMPILE = @LTCOMPILE@
+LTCXXCOMPILE = @LTCXXCOMPILE@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -246,8 +203,7 @@ MESA_SOURCE = @MESA_SOURCE@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
-MKFONTDIR = @MKFONTDIR@
-MKFONTSCALE = @MKFONTSCALE@
+NM = @NM@
NMEDIT = @NMEDIT@
OBJC = @OBJC@
OBJCCLD = @OBJCCLD@
@@ -256,8 +212,8 @@ OBJCFLAGS = @OBJCFLAGS@
OBJCLINK = @OBJCLINK@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
-OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
@@ -290,7 +246,6 @@ VENDOR_NAME = @VENDOR_NAME@
VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
VENDOR_RELEASE = @VENDOR_RELEASE@
VERSION = @VERSION@
-X11APP_ARCHS = @X11APP_ARCHS@
X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
XDMCP_CFLAGS = @XDMCP_CFLAGS@
@@ -300,27 +255,12 @@ XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@
XDMX_CFLAGS = @XDMX_CFLAGS@
XDMX_LIBS = @XDMX_LIBS@
XDMX_SYS_LIBS = @XDMX_SYS_LIBS@
-XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@
-XEGL_LIBS = @XEGL_LIBS@
-XEGL_SYS_LIBS = @XEGL_SYS_LIBS@
XEPHYR_CFLAGS = @XEPHYR_CFLAGS@
-XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@
XEPHYR_INCS = @XEPHYR_INCS@
XEPHYR_LIBS = @XEPHYR_LIBS@
XF86CONFIGFILE = @XF86CONFIGFILE@
-XF86MISC_CFLAGS = @XF86MISC_CFLAGS@
-XF86MISC_LIBS = @XF86MISC_LIBS@
XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
-XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@
-XGLMODULES_LIBS = @XGLMODULES_LIBS@
-XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@
-XGLXMODULES_LIBS = @XGLXMODULES_LIBS@
-XGLX_LIBS = @XGLX_LIBS@
-XGLX_SYS_LIBS = @XGLX_SYS_LIBS@
-XGL_LIBS = @XGL_LIBS@
-XGL_MODULE_PATH = @XGL_MODULE_PATH@
-XGL_SYS_LIBS = @XGL_SYS_LIBS@
XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@
XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@
XKB_COMPILED_DIR = @XKB_COMPILED_DIR@
@@ -331,10 +271,6 @@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@
XNESTMODULES_LIBS = @XNESTMODULES_LIBS@
XNEST_LIBS = @XNEST_LIBS@
XNEST_SYS_LIBS = @XNEST_SYS_LIBS@
-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_CFLAGS = @XORG_CFLAGS@
XORG_INCS = @XORG_INCS@
XORG_LIBS = @XORG_LIBS@
@@ -343,13 +279,8 @@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@
XORG_OS = @XORG_OS@
XORG_OS_SUBDIR = @XORG_OS_SUBDIR@
XORG_SYS_LIBS = @XORG_SYS_LIBS@
-XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@
-XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@
-XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@
-XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@
-XPRINT_CFLAGS = @XPRINT_CFLAGS@
-XPRINT_LIBS = @XPRINT_LIBS@
-XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@
+XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@
+XPBPROXY_LIBS = @XPBPROXY_LIBS@
XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@
XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@
XSDL_INCS = @XSDL_INCS@
@@ -382,8 +313,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -403,7 +333,6 @@ driverdir = @driverdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
extdir = @extdir@
-ft_config = @ft_config@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -413,12 +342,12 @@ htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
-launchagentsdir = @launchagentsdir@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
logdir = @logdir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
moduledir = @moduledir@
@@ -436,11 +365,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-xglmoduledir = @xglmoduledir@
-xpconfigdir = @xpconfigdir@
-standard_dix_libs = libdix.la libxpstubs.la
-@XPRINT_FALSE@noinst_LTLIBRARIES = $(standard_dix_libs)
-@XPRINT_TRUE@noinst_LTLIBRARIES = $(standard_dix_libs) libXpdix.la
+noinst_LTLIBRARIES = libdix.la
AM_CFLAGS = $(DIX_CFLAGS) \
-DVENDOR_NAME=\""@VENDOR_NAME@"\" \
-DVENDOR_RELEASE="@VENDOR_RELEASE@"
@@ -455,6 +380,8 @@ libdix_la_SOURCES = \
dispatch.h \
dixfonts.c \
dixutils.c \
+ enterleave.c \
+ enterleave.h \
events.c \
extension.c \
ffs.c \
@@ -468,23 +395,16 @@ libdix_la_SOURCES = \
pixmap.c \
privates.c \
property.c \
+ ptrveloc.c \
registry.c \
resource.c \
selection.c \
swaprep.c \
swapreq.c \
tables.c \
- window.c \
- strcasecmp.c \
- strcasestr.c
+ window.c
-libxpstubs_la_SOURCES = \
- xpstubs.c
-
-@XPRINT_TRUE@libXpdix_la_SOURCES = $(libdix_la_SOURCES)
-@XPRINT_TRUE@libXpdix_la_CPPFLAGS = -I$(top_srcdir)/hw/xprint
-@XPRINT_TRUE@libXpdix_la_CFLAGS = $(AM_CFLAGS) $(XPRINT_CFLAGS)
-EXTRA_DIST = buildatoms BuiltInAtoms CHANGES Xserver.d Xserver-dtrace.h.in
+EXTRA_DIST = buildatoms BuiltInAtoms Xserver.d Xserver-dtrace.h.in
# Install list of protocol names
miscconfigdir = $(SERVER_MISC_CONFIG_PATH)
@@ -502,8 +422,8 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -536,12 +456,8 @@ clean-noinstLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libXpdix.la: $(libXpdix_la_OBJECTS) $(libXpdix_la_DEPENDENCIES)
- $(libXpdix_la_LINK) $(am_libXpdix_la_rpath) $(libXpdix_la_OBJECTS) $(libXpdix_la_LIBADD) $(LIBS)
libdix.la: $(libdix_la_OBJECTS) $(libdix_la_DEPENDENCIES)
- $(LINK) $(am_libdix_la_rpath) $(libdix_la_OBJECTS) $(libdix_la_LIBADD) $(LIBS)
-libxpstubs.la: $(libxpstubs_la_OBJECTS) $(libxpstubs_la_DEPENDENCIES)
- $(LINK) $(am_libxpstubs_la_rpath) $(libxpstubs_la_OBJECTS) $(libxpstubs_la_LIBADD) $(LIBS)
+ $(LINK) $(libdix_la_OBJECTS) $(libdix_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; for p in $$list; do \
@@ -568,6 +484,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dix.Po@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)/enterleave.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@
@@ -577,50 +494,18 @@ distclean-compile:
@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)/libXpdix_la-atom.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-colormap.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-cursor.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-deprecated.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-devices.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-dispatch.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-dixfonts.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-dixutils.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-events.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-extension.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-ffs.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-gc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-getevents.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-globals.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-glyphcurs.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-grabs.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-initatoms.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-main.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-pixmap.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-privates.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-property.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-registry.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-resource.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-selection.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-strcasecmp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-strcasestr.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-swaprep.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-swapreq.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-tables.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXpdix_la-window.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)/ptrveloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/registry.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resource.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selection.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcasecmp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcasestr.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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -643,216 +528,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-libXpdix_la-atom.lo: atom.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-atom.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-atom.Tpo -c -o libXpdix_la-atom.lo `test -f 'atom.c' || echo '$(srcdir)/'`atom.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-atom.Tpo $(DEPDIR)/libXpdix_la-atom.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='atom.c' object='libXpdix_la-atom.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-atom.lo `test -f 'atom.c' || echo '$(srcdir)/'`atom.c
-
-libXpdix_la-colormap.lo: colormap.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-colormap.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-colormap.Tpo -c -o libXpdix_la-colormap.lo `test -f 'colormap.c' || echo '$(srcdir)/'`colormap.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-colormap.Tpo $(DEPDIR)/libXpdix_la-colormap.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='colormap.c' object='libXpdix_la-colormap.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-colormap.lo `test -f 'colormap.c' || echo '$(srcdir)/'`colormap.c
-
-libXpdix_la-cursor.lo: cursor.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-cursor.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-cursor.Tpo -c -o libXpdix_la-cursor.lo `test -f 'cursor.c' || echo '$(srcdir)/'`cursor.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-cursor.Tpo $(DEPDIR)/libXpdix_la-cursor.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cursor.c' object='libXpdix_la-cursor.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-cursor.lo `test -f 'cursor.c' || echo '$(srcdir)/'`cursor.c
-
-libXpdix_la-deprecated.lo: deprecated.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-deprecated.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-deprecated.Tpo -c -o libXpdix_la-deprecated.lo `test -f 'deprecated.c' || echo '$(srcdir)/'`deprecated.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-deprecated.Tpo $(DEPDIR)/libXpdix_la-deprecated.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='deprecated.c' object='libXpdix_la-deprecated.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-deprecated.lo `test -f 'deprecated.c' || echo '$(srcdir)/'`deprecated.c
-
-libXpdix_la-devices.lo: devices.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-devices.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-devices.Tpo -c -o libXpdix_la-devices.lo `test -f 'devices.c' || echo '$(srcdir)/'`devices.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-devices.Tpo $(DEPDIR)/libXpdix_la-devices.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='devices.c' object='libXpdix_la-devices.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-devices.lo `test -f 'devices.c' || echo '$(srcdir)/'`devices.c
-
-libXpdix_la-dispatch.lo: dispatch.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-dispatch.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-dispatch.Tpo -c -o libXpdix_la-dispatch.lo `test -f 'dispatch.c' || echo '$(srcdir)/'`dispatch.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-dispatch.Tpo $(DEPDIR)/libXpdix_la-dispatch.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dispatch.c' object='libXpdix_la-dispatch.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-dispatch.lo `test -f 'dispatch.c' || echo '$(srcdir)/'`dispatch.c
-
-libXpdix_la-dixfonts.lo: dixfonts.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-dixfonts.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-dixfonts.Tpo -c -o libXpdix_la-dixfonts.lo `test -f 'dixfonts.c' || echo '$(srcdir)/'`dixfonts.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-dixfonts.Tpo $(DEPDIR)/libXpdix_la-dixfonts.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dixfonts.c' object='libXpdix_la-dixfonts.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-dixfonts.lo `test -f 'dixfonts.c' || echo '$(srcdir)/'`dixfonts.c
-
-libXpdix_la-dixutils.lo: dixutils.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-dixutils.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-dixutils.Tpo -c -o libXpdix_la-dixutils.lo `test -f 'dixutils.c' || echo '$(srcdir)/'`dixutils.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-dixutils.Tpo $(DEPDIR)/libXpdix_la-dixutils.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dixutils.c' object='libXpdix_la-dixutils.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-dixutils.lo `test -f 'dixutils.c' || echo '$(srcdir)/'`dixutils.c
-
-libXpdix_la-events.lo: events.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-events.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-events.Tpo -c -o libXpdix_la-events.lo `test -f 'events.c' || echo '$(srcdir)/'`events.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-events.Tpo $(DEPDIR)/libXpdix_la-events.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='events.c' object='libXpdix_la-events.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-events.lo `test -f 'events.c' || echo '$(srcdir)/'`events.c
-
-libXpdix_la-extension.lo: extension.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-extension.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-extension.Tpo -c -o libXpdix_la-extension.lo `test -f 'extension.c' || echo '$(srcdir)/'`extension.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-extension.Tpo $(DEPDIR)/libXpdix_la-extension.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='extension.c' object='libXpdix_la-extension.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-extension.lo `test -f 'extension.c' || echo '$(srcdir)/'`extension.c
-
-libXpdix_la-ffs.lo: ffs.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-ffs.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-ffs.Tpo -c -o libXpdix_la-ffs.lo `test -f 'ffs.c' || echo '$(srcdir)/'`ffs.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-ffs.Tpo $(DEPDIR)/libXpdix_la-ffs.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ffs.c' object='libXpdix_la-ffs.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-ffs.lo `test -f 'ffs.c' || echo '$(srcdir)/'`ffs.c
-
-libXpdix_la-gc.lo: gc.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-gc.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-gc.Tpo -c -o libXpdix_la-gc.lo `test -f 'gc.c' || echo '$(srcdir)/'`gc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-gc.Tpo $(DEPDIR)/libXpdix_la-gc.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gc.c' object='libXpdix_la-gc.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-gc.lo `test -f 'gc.c' || echo '$(srcdir)/'`gc.c
-
-libXpdix_la-getevents.lo: getevents.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-getevents.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-getevents.Tpo -c -o libXpdix_la-getevents.lo `test -f 'getevents.c' || echo '$(srcdir)/'`getevents.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-getevents.Tpo $(DEPDIR)/libXpdix_la-getevents.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='getevents.c' object='libXpdix_la-getevents.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-getevents.lo `test -f 'getevents.c' || echo '$(srcdir)/'`getevents.c
-
-libXpdix_la-globals.lo: globals.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-globals.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-globals.Tpo -c -o libXpdix_la-globals.lo `test -f 'globals.c' || echo '$(srcdir)/'`globals.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-globals.Tpo $(DEPDIR)/libXpdix_la-globals.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='globals.c' object='libXpdix_la-globals.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-globals.lo `test -f 'globals.c' || echo '$(srcdir)/'`globals.c
-
-libXpdix_la-glyphcurs.lo: glyphcurs.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-glyphcurs.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-glyphcurs.Tpo -c -o libXpdix_la-glyphcurs.lo `test -f 'glyphcurs.c' || echo '$(srcdir)/'`glyphcurs.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-glyphcurs.Tpo $(DEPDIR)/libXpdix_la-glyphcurs.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glyphcurs.c' object='libXpdix_la-glyphcurs.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-glyphcurs.lo `test -f 'glyphcurs.c' || echo '$(srcdir)/'`glyphcurs.c
-
-libXpdix_la-grabs.lo: grabs.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-grabs.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-grabs.Tpo -c -o libXpdix_la-grabs.lo `test -f 'grabs.c' || echo '$(srcdir)/'`grabs.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-grabs.Tpo $(DEPDIR)/libXpdix_la-grabs.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='grabs.c' object='libXpdix_la-grabs.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-grabs.lo `test -f 'grabs.c' || echo '$(srcdir)/'`grabs.c
-
-libXpdix_la-initatoms.lo: initatoms.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-initatoms.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-initatoms.Tpo -c -o libXpdix_la-initatoms.lo `test -f 'initatoms.c' || echo '$(srcdir)/'`initatoms.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-initatoms.Tpo $(DEPDIR)/libXpdix_la-initatoms.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='initatoms.c' object='libXpdix_la-initatoms.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-initatoms.lo `test -f 'initatoms.c' || echo '$(srcdir)/'`initatoms.c
-
-libXpdix_la-main.lo: main.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-main.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-main.Tpo -c -o libXpdix_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-main.Tpo $(DEPDIR)/libXpdix_la-main.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='libXpdix_la-main.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c
-
-libXpdix_la-pixmap.lo: pixmap.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-pixmap.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-pixmap.Tpo -c -o libXpdix_la-pixmap.lo `test -f 'pixmap.c' || echo '$(srcdir)/'`pixmap.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-pixmap.Tpo $(DEPDIR)/libXpdix_la-pixmap.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pixmap.c' object='libXpdix_la-pixmap.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-pixmap.lo `test -f 'pixmap.c' || echo '$(srcdir)/'`pixmap.c
-
-libXpdix_la-privates.lo: privates.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-privates.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-privates.Tpo -c -o libXpdix_la-privates.lo `test -f 'privates.c' || echo '$(srcdir)/'`privates.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-privates.Tpo $(DEPDIR)/libXpdix_la-privates.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='privates.c' object='libXpdix_la-privates.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-privates.lo `test -f 'privates.c' || echo '$(srcdir)/'`privates.c
-
-libXpdix_la-property.lo: property.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-property.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-property.Tpo -c -o libXpdix_la-property.lo `test -f 'property.c' || echo '$(srcdir)/'`property.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-property.Tpo $(DEPDIR)/libXpdix_la-property.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='property.c' object='libXpdix_la-property.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-property.lo `test -f 'property.c' || echo '$(srcdir)/'`property.c
-
-libXpdix_la-registry.lo: registry.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-registry.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-registry.Tpo -c -o libXpdix_la-registry.lo `test -f 'registry.c' || echo '$(srcdir)/'`registry.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-registry.Tpo $(DEPDIR)/libXpdix_la-registry.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='registry.c' object='libXpdix_la-registry.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-registry.lo `test -f 'registry.c' || echo '$(srcdir)/'`registry.c
-
-libXpdix_la-resource.lo: resource.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-resource.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-resource.Tpo -c -o libXpdix_la-resource.lo `test -f 'resource.c' || echo '$(srcdir)/'`resource.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-resource.Tpo $(DEPDIR)/libXpdix_la-resource.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='resource.c' object='libXpdix_la-resource.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-resource.lo `test -f 'resource.c' || echo '$(srcdir)/'`resource.c
-
-libXpdix_la-selection.lo: selection.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-selection.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-selection.Tpo -c -o libXpdix_la-selection.lo `test -f 'selection.c' || echo '$(srcdir)/'`selection.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-selection.Tpo $(DEPDIR)/libXpdix_la-selection.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='selection.c' object='libXpdix_la-selection.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-selection.lo `test -f 'selection.c' || echo '$(srcdir)/'`selection.c
-
-libXpdix_la-swaprep.lo: swaprep.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-swaprep.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-swaprep.Tpo -c -o libXpdix_la-swaprep.lo `test -f 'swaprep.c' || echo '$(srcdir)/'`swaprep.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-swaprep.Tpo $(DEPDIR)/libXpdix_la-swaprep.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='swaprep.c' object='libXpdix_la-swaprep.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-swaprep.lo `test -f 'swaprep.c' || echo '$(srcdir)/'`swaprep.c
-
-libXpdix_la-swapreq.lo: swapreq.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-swapreq.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-swapreq.Tpo -c -o libXpdix_la-swapreq.lo `test -f 'swapreq.c' || echo '$(srcdir)/'`swapreq.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-swapreq.Tpo $(DEPDIR)/libXpdix_la-swapreq.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='swapreq.c' object='libXpdix_la-swapreq.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-swapreq.lo `test -f 'swapreq.c' || echo '$(srcdir)/'`swapreq.c
-
-libXpdix_la-tables.lo: tables.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-tables.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-tables.Tpo -c -o libXpdix_la-tables.lo `test -f 'tables.c' || echo '$(srcdir)/'`tables.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-tables.Tpo $(DEPDIR)/libXpdix_la-tables.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tables.c' object='libXpdix_la-tables.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-tables.lo `test -f 'tables.c' || echo '$(srcdir)/'`tables.c
-
-libXpdix_la-window.lo: window.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-window.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-window.Tpo -c -o libXpdix_la-window.lo `test -f 'window.c' || echo '$(srcdir)/'`window.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-window.Tpo $(DEPDIR)/libXpdix_la-window.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='window.c' object='libXpdix_la-window.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-window.lo `test -f 'window.c' || echo '$(srcdir)/'`window.c
-
-libXpdix_la-strcasecmp.lo: strcasecmp.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-strcasecmp.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-strcasecmp.Tpo -c -o libXpdix_la-strcasecmp.lo `test -f 'strcasecmp.c' || echo '$(srcdir)/'`strcasecmp.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-strcasecmp.Tpo $(DEPDIR)/libXpdix_la-strcasecmp.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='strcasecmp.c' object='libXpdix_la-strcasecmp.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-strcasecmp.lo `test -f 'strcasecmp.c' || echo '$(srcdir)/'`strcasecmp.c
-
-libXpdix_la-strcasestr.lo: strcasestr.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -MT libXpdix_la-strcasestr.lo -MD -MP -MF $(DEPDIR)/libXpdix_la-strcasestr.Tpo -c -o libXpdix_la-strcasestr.lo `test -f 'strcasestr.c' || echo '$(srcdir)/'`strcasestr.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libXpdix_la-strcasestr.Tpo $(DEPDIR)/libXpdix_la-strcasestr.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='strcasestr.c' object='libXpdix_la-strcasestr.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXpdix_la_CPPFLAGS) $(CPPFLAGS) $(libXpdix_la_CFLAGS) $(CFLAGS) -c -o libXpdix_la-strcasestr.lo `test -f 'strcasestr.c' || echo '$(srcdir)/'`strcasestr.c
-
mostlyclean-libtool:
-rm -f *.lo
@@ -881,7 +556,7 @@ ID: $(HEADERS) $(SOURCES) $(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; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/xorg-server/dix/cursor.c b/xorg-server/dix/cursor.c
index 0ddf9d791..81540fd89 100644
--- a/xorg-server/dix/cursor.c
+++ b/xorg-server/dix/cursor.c
@@ -59,6 +59,7 @@ SOFTWARE.
#include "cursorstr.h"
#include "dixfontstr.h"
#include "opaque.h"
+#include "inputstr.h"
#include "xace.h"
typedef struct _GlyphShare {
@@ -116,14 +117,15 @@ FreeCursor(pointer value, XID cid)
CursorPtr pCurs = (CursorPtr)value;
ScreenPtr pscr;
+ DeviceIntPtr pDev = NULL; /* unused anyway */
- if ( --pCurs->refcnt > 0)
+ if ( --pCurs->refcnt != 0)
return(Success);
for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
{
pscr = screenInfo.screens[nscr];
- (void)( *pscr->UnrealizeCursor)( pscr, pCurs);
+ (void)( *pscr->UnrealizeCursor)(pDev, pscr, pCurs);
}
dixFreePrivates(pCurs->devPrivates);
FreeCursorBits(pCurs->bits);
@@ -175,9 +177,10 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
CursorPtr pCurs;
int rc, nscr;
ScreenPtr pscr;
+ DeviceIntPtr pDev;
*ppCurs = NULL;
- pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits));
+ pCurs = (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1);
if (!pCurs)
{
xfree(psrcbits);
@@ -194,11 +197,11 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
bits->height = cm->height;
bits->xhot = cm->xhot;
bits->yhot = cm->yhot;
+ pCurs->refcnt = 1;
bits->devPrivates = NULL;
bits->refcnt = -1;
CheckForEmptyMask(bits);
pCurs->bits = bits;
- pCurs->refcnt = 1;
#ifdef XFIXES
pCurs->serialNumber = ++cursorSerial;
pCurs->name = None;
@@ -227,22 +230,51 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
/*
* realize the cursor for every screen
+ * Do not change the refcnt, this will be changed when ChangeToCursor
+ * actually changes the sprite.
*/
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);
- }
- dixFreePrivates(pCurs->devPrivates);
- FreeCursorBits(bits);
- xfree(pCurs);
- return BadAlloc;
- }
+ pscr = screenInfo.screens[nscr];
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ {
+ if (DevHasCursor(pDev))
+ {
+ if (!( *pscr->RealizeCursor)(pDev, pscr, pCurs))
+ {
+ /* Realize failed for device pDev on screen pscr.
+ * We have to assume that for all devices before, realize
+ * worked. We need to rollback all devices so far on the
+ * current screen and then all devices on previous
+ * screens.
+ */
+ DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator*/
+ while(pDevIt && pDevIt != pDev)
+ {
+ if (DevHasCursor(pDevIt))
+ ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs);
+ pDevIt = pDevIt->next;
+ }
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ /* now unrealize all devices on previous screens */
+ pDevIt = inputInfo.devices;
+ while (pDevIt)
+ {
+ if (DevHasCursor(pDevIt))
+ ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs);
+ pDevIt = pDevIt->next;
+ }
+ ( *pscr->UnrealizeCursor)(pDev, pscr, pCurs);
+ }
+ dixFreePrivates(pCurs->devPrivates);
+ FreeCursorBits(bits);
+ xfree(pCurs);
+ return BadAlloc;
+ }
+ }
+ }
}
*ppCurs = pCurs;
return rc;
@@ -264,6 +296,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
int nscr;
ScreenPtr pscr;
GlyphSharePtr pShare;
+ DeviceIntPtr pDev;
rc = dixLookupResource((pointer *)&sourcefont, source, RT_FONT, client,
DixUseAccess);
@@ -293,7 +326,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
}
if (pShare)
{
- pCurs = (CursorPtr)xalloc(sizeof(CursorRec));
+ pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1);
if (!pCurs)
return BadAlloc;
bits = pShare->bits;
@@ -335,7 +368,8 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
}
if (sourcefont != maskfont)
{
- pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits));
+ pCurs =
+ (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1);
if (pCurs)
bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
else
@@ -343,9 +377,9 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
}
else
{
- pCurs = (CursorPtr)xalloc(sizeof(CursorRec));
+ pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1);
if (pCurs)
- bits = (CursorBitsPtr)xalloc(sizeof(CursorBits));
+ bits = (CursorBitsPtr)xcalloc(sizeof(CursorBits), 1);
else
bits = (CursorBitsPtr)NULL;
}
@@ -386,6 +420,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
sharedGlyphs = pShare;
}
}
+
CheckForEmptyMask(bits);
pCurs->bits = bits;
pCurs->refcnt = 1;
@@ -420,19 +455,52 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
*/
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);
- }
- dixFreePrivates(pCurs->devPrivates);
- FreeCursorBits(pCurs->bits);
- xfree(pCurs);
- return BadAlloc;
- }
+ pscr = screenInfo.screens[nscr];
+
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ {
+ if (DevHasCursor(pDev))
+ {
+ if (!( *pscr->RealizeCursor)(pDev, pscr, pCurs))
+ {
+ /* Realize failed for device pDev on screen pscr.
+ * We have to assume that for all devices before, realize
+ * worked. We need to rollback all devices so far on the
+ * current screen and then all devices on previous
+ * screens.
+ */
+ DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator*/
+ while(pDevIt && pDevIt != pDev)
+ {
+ if (DevHasCursor(pDevIt))
+ ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs);
+ pDevIt = pDevIt->next;
+ }
+
+ (*pscr->UnrealizeCursor)(inputInfo.pointer, pscr, pCurs);
+
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ /* now unrealize all devices on previous screens */
+ ( *pscr->UnrealizeCursor)(inputInfo.pointer, pscr, pCurs);
+
+ pDevIt = inputInfo.devices;
+ while (pDevIt)
+ {
+ if (DevHasCursor(pDevIt))
+ ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs);
+ pDevIt = pDevIt->next;
+ }
+ ( *pscr->UnrealizeCursor)(pDev, pscr, pCurs);
+ }
+ dixFreePrivates(pCurs->devPrivates);
+ FreeCursorBits(bits);
+ xfree(pCurs);
+ return BadAlloc;
+ }
+ }
+ }
}
*ppCurs = pCurs;
return Success;
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index 5a726afe8..3b8d544da 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -27,13 +27,13 @@ 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,
+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
+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.
+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
@@ -57,11 +57,13 @@ SOFTWARE.
#define NEED_EVENTS
#define NEED_REPLIES
#include <X11/Xproto.h>
+#include <X11/Xatom.h>
#include "windowstr.h"
#include "inputstr.h"
#include "scrnintstr.h"
#include "cursorstr.h"
#include "dixstruct.h"
+#include "ptrveloc.h"
#include "site.h"
#ifndef XKB_IN_SERVER
#define XKB_IN_SERVER
@@ -71,21 +73,109 @@ SOFTWARE.
#endif
#include "privates.h"
#include "xace.h"
+#include "mi.h"
#include "dispatch.h"
#include "swaprep.h"
#include "dixevents.h"
+#include "mipointer.h"
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
#include "exglobals.h"
#include "exevents.h"
+#include "listdev.h" /* for CopySwapXXXClass */
+#include "xiproperty.h"
+#include "enterleave.h" /* for EnterWindow() */
+#include "xserver-properties.h"
/** @file
* This file handles input device-related stuff.
*/
-DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKey;
+static int CoreDevicePrivateKeyIndex;
+DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKeyIndex;
+/* Used to sture classes currently not in use by an MD */
+static int UnusedClassesPrivateKeyIndex;
+DevPrivateKey UnusedClassesPrivateKey = &UnusedClassesPrivateKeyIndex;
+
+
+/**
+ * DIX property handler.
+ */
+static int
+DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
+ BOOL checkonly)
+{
+ if (property == XIGetKnownProperty(XI_PROP_ENABLED))
+ {
+ if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
+ return BadValue;
+
+ /* Don't allow disabling of VCP/VCK */
+ if ((dev == inputInfo.pointer || dev == inputInfo.keyboard) &&
+ !(*(CARD8*)prop->data))
+ return BadAccess;
+
+ if (!checkonly)
+ {
+ if ((*((CARD8*)prop->data)) && !dev->enabled)
+ EnableDevice(dev);
+ else if (!(*((CARD8*)prop->data)) && dev->enabled)
+ DisableDevice(dev);
+ }
+ }
+
+ return Success;
+}
+
+/* Pair the keyboard to the pointer device. Keyboard events will follow the
+ * pointer sprite. Only applicable for master devices.
+ * If the client is set, the request to pair comes from some client. In this
+ * case, we need to check for access. If the client is NULL, it's from an
+ * internal automatic pairing, we must always permit this.
+ */
+static int
+PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
+{
+ if (!ptr)
+ return BadDevice;
+
+ /* Don't allow pairing for slave devices */
+ if (!ptr->isMaster || !kbd->isMaster)
+ return BadDevice;
+
+ if (ptr->spriteInfo->paired)
+ return BadDevice;
+
+ if (kbd->spriteInfo->spriteOwner)
+ {
+ xfree(kbd->spriteInfo->sprite);
+ kbd->spriteInfo->sprite = NULL;
+ kbd->spriteInfo->spriteOwner = FALSE;
+ }
+
+ kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
+ kbd->spriteInfo->paired = ptr;
+ ptr->spriteInfo->paired = kbd;
+ return Success;
+}
+
+
+/**
+ * Find and return the next unpaired MD pointer device.
+ */
+static DeviceIntPtr
+NextFreePointerDevice(void)
+{
+ DeviceIntPtr dev;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ if (dev->isMaster &&
+ dev->spriteInfo->spriteOwner &&
+ !dev->spriteInfo->paired)
+ return dev;
+ return NULL;
+}
/**
* Create a new input device and init it to sane values. The device is added
@@ -95,69 +185,48 @@ DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKey;
* @return The newly created device.
*/
DeviceIntPtr
-AddInputDevice(DeviceProc deviceProc, Bool autoStart)
+AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
{
DeviceIntPtr dev, *prev; /* not a typo */
DeviceIntPtr devtmp;
int devid;
- char devind[MAX_DEVICES];
+ char devind[MAXDEVICES];
+ BOOL enabled;
/* Find next available id */
- memset(devind, 0, sizeof(char)*MAX_DEVICES);
+ memset(devind, 0, sizeof(char)*MAXDEVICES);
for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
devind[devtmp->id]++;
for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
devind[devtmp->id]++;
- for (devid = 0; devid < MAX_DEVICES && devind[devid]; devid++)
+ for (devid = 0; devid < MAXDEVICES && devind[devid]; devid++)
;
- if (devid >= MAX_DEVICES)
+ if (devid >= MAXDEVICES)
return (DeviceIntPtr)NULL;
- dev = (DeviceIntPtr) xcalloc(sizeof(DeviceIntRec), 1);
+ dev = xcalloc(sizeof(DeviceIntRec) + sizeof(SpriteInfoRec), 1);
if (!dev)
return (DeviceIntPtr)NULL;
- dev->name = (char *)NULL;
- dev->type = 0;
dev->id = devid;
- 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->absolute = (AbsoluteClassPtr)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;
-#ifdef XKB
- dev->xkb_interest = NULL;
-#endif
- dev->config_info = NULL;
- dev->devPrivates = NULL;
- dev->unwrapProc = NULL;
+
+ /* device grab defaults */
+ dev->deviceGrab.grabTime = currentTime;
+ dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+
dev->coreEvents = TRUE;
- dev->inited = FALSE;
- dev->enabled = FALSE;
+
+ /* sprite defaults */
+ dev->spriteInfo = (SpriteInfoPtr)&dev[1];
/* security creation/labeling check
*/
- if (XaceHook(XACE_DEVICE_ACCESS, serverClient, dev, DixCreateAccess)) {
+ if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
xfree(dev);
return NULL;
}
@@ -169,14 +238,24 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart)
*prev = dev;
dev->next = NULL;
+ enabled = FALSE;
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+ XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+ FALSE);
+ XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE);
+ XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
+
return dev;
}
/**
+ * Enable the device through the driver, add the device to the device list.
* Switch device ON through the driver and push it onto the global device
- * list. All clients are notified about the device being enabled.
+ * list. Initialize the DIX sprite or pair the device. All clients are
+ * notified about the device being enabled.
*
- * A device will send events once enabled.
+ * A master pointer device needs to be enabled before a master keyboard
+ * device.
*
* @param The device to be enabled.
* @return TRUE on success or FALSE otherwise.
@@ -187,15 +266,62 @@ EnableDevice(DeviceIntPtr dev)
DeviceIntPtr *prev;
int ret;
DeviceIntRec dummyDev;
+ DeviceIntPtr other;
devicePresenceNotify ev;
+ int namelen = 0; /* dummy */
+ int evsize = sizeof(xEvent);
+ int listlen;
+ EventListPtr evlist;
+ BOOL enabled;
for (prev = &inputInfo.off_devices;
*prev && (*prev != dev);
prev = &(*prev)->next)
;
+
+ if (!dev->spriteInfo->sprite)
+ {
+ if (dev->isMaster)
+ {
+ /* Sprites appear on first root window, so we can hardcode it */
+ if (dev->spriteInfo->spriteOwner)
+ {
+ InitializeSprite(dev, WindowTable[0]);
+ /* mode doesn't matter */
+ EnterWindow(dev, WindowTable[0], NotifyAncestor);
+ }
+ else if ((other = NextFreePointerDevice()) == NULL)
+ {
+ ErrorF("[dix] cannot find pointer to pair with. "
+ "This is a bug.\n");
+ return FALSE;
+ } else
+ PairDevices(NULL, other, dev);
+ } else
+ {
+ other = (IsPointerDevice(dev)) ? inputInfo.pointer :
+ inputInfo.keyboard;
+ AttachDevice(NULL, dev, other);
+ }
+ }
+
+ /* Before actually enabling the device, we need to make sure the event
+ * list's events have enough memory for a ClassesChangedEvent from the
+ * device
+ */
+
+ SizeDeviceInfo(dev, &namelen, &evsize);
+
+ listlen = GetEventList(&evlist);
+ OsBlockSignals();
+ SetMinimumEventSize(evlist, listlen, evsize);
+ mieqResizeEvents(evsize);
+ OsReleaseSignals();
+
+
if ((*prev != dev) || !dev->inited ||
((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
- ErrorF("couldn't enable device %d\n", dev->id);
+ ErrorF("[dix] couldn't enable device %d\n", dev->id);
return FALSE;
}
dev->enabled = TRUE;
@@ -206,11 +332,16 @@ EnableDevice(DeviceIntPtr dev)
*prev = dev;
dev->next = NULL;
+ enabled = TRUE;
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+ XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+ TRUE);
+
ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds;
ev.devchange = DeviceEnabled;
ev.deviceid = dev->id;
- dummyDev.id = 0;
+ dummyDev.id = MAXDEVICES;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1);
@@ -222,14 +353,18 @@ EnableDevice(DeviceIntPtr dev)
* list. A device will not send events while disabled. All clients are
* notified about the device being disabled.
*
+ * Master keyboard devices have to be disabled before master pointer devices
+ * otherwise things turn bad.
+ *
* @return TRUE on success or FALSE otherwise.
*/
Bool
DisableDevice(DeviceIntPtr dev)
{
- DeviceIntPtr *prev;
+ DeviceIntPtr *prev, other;
DeviceIntRec dummyDev;
devicePresenceNotify ev;
+ BOOL enabled;
for (prev = &inputInfo.devices;
*prev && (*prev != dev);
@@ -237,17 +372,54 @@ DisableDevice(DeviceIntPtr dev)
;
if (*prev != dev)
return FALSE;
+
+ /* float attached devices */
+ if (dev->isMaster)
+ {
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (other->u.master == dev)
+ AttachDevice(NULL, other, NULL);
+ }
+ }
+ else
+ {
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (other->isMaster && other->u.lastSlave == dev)
+ other->u.lastSlave = NULL;
+ }
+ }
+
+ if (dev->isMaster && dev->spriteInfo->sprite)
+ {
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (other->spriteInfo->paired == dev)
+ {
+ ErrorF("[dix] cannot disable device, still paired. "
+ "This is a bug. \n");
+ return FALSE;
+ }
+ }
+ }
+
(void)(*dev->deviceProc)(dev, DEVICE_OFF);
dev->enabled = FALSE;
*prev = dev->next;
dev->next = inputInfo.off_devices;
inputInfo.off_devices = dev;
+ enabled = FALSE;
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+ XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+ TRUE);
+
ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds;
ev.devchange = DeviceDisabled;
ev.deviceid = dev->id;
- dummyDev.id = 0;
+ dummyDev.id = MAXDEVICES;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1);
@@ -257,7 +429,8 @@ DisableDevice(DeviceIntPtr dev)
/**
* Initialise a new device through the driver and tell all clients about the
* new device.
- *
+ *
+ * Must be called before EnableDevice.
* The device will NOT send events until it is enabled!
*
* @return Success or an error code on failure.
@@ -268,18 +441,27 @@ ActivateDevice(DeviceIntPtr dev)
int ret = Success;
devicePresenceNotify ev;
DeviceIntRec dummyDev;
+ ScreenPtr pScreen = screenInfo.screens[0];
if (!dev || !dev->deviceProc)
return BadImplementation;
ret = (*dev->deviceProc) (dev, DEVICE_INIT);
dev->inited = (ret == Success);
-
+ if (!dev->inited)
+ return ret;
+
+ /* Initialize memory for sprites. */
+ if (dev->isMaster && dev->spriteInfo->spriteOwner)
+ pScreen->DeviceCursorInitialize(dev, pScreen);
+
ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds;
ev.devchange = DeviceAdded;
ev.deviceid = dev->id;
- dummyDev.id = 0;
+
+ memset(&dummyDev, 0, sizeof(DeviceIntRec));
+ dummyDev.id = MAXDEVICES;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1);
@@ -305,7 +487,7 @@ CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
}
/**
- * Device control function for the Virtual Core Keyboard.
+ * Device control function for the Virtual Core Keyboard.
*/
static int
CoreKeyboardProc(DeviceIntPtr pDev, int what)
@@ -315,9 +497,16 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
#ifdef XKB
XkbComponentNamesRec names;
#endif
+ ClassesPtr classes;
switch (what) {
case DEVICE_INIT:
+ if (!(classes = xcalloc(1, sizeof(ClassesRec))))
+ {
+ ErrorF("[dix] Could not allocate device classes.\n");
+ return BadAlloc;
+ }
+
keySyms.minKeyCode = 8;
keySyms.maxKeyCode = 255;
keySyms.mapWidth = 4;
@@ -326,21 +515,21 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
keySyms.minKeyCode + 1) *
keySyms.mapWidth);
if (!keySyms.map) {
- ErrorF("Couldn't allocate core keymap\n");
+ ErrorF("[dix] Couldn't allocate core keymap\n");
+ xfree(classes);
return BadAlloc;
}
- modMap = (CARD8 *)xalloc(MAP_LENGTH);
+ modMap = xcalloc(1, MAP_LENGTH);
if (!modMap) {
- ErrorF("Couldn't allocate core modifier map\n");
+ ErrorF("[dix] Couldn't allocate core modifier map\n");
+ xfree(classes);
return BadAlloc;
}
- bzero((char *)modMap, MAP_LENGTH);
#ifdef XKB
if (!noXkbExtension) {
bzero(&names, sizeof(names));
- XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modMap,
CoreKeyboardBell, CoreKeyboardCtl);
}
@@ -354,11 +543,9 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
xfree(keySyms.map);
xfree(modMap);
-
break;
case DEVICE_CLOSE:
- dixSetPrivate(&pDev->devPrivates, CoreDevicePrivateKey, NULL);
break;
default:
@@ -369,28 +556,34 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
/**
* Device control function for the Virtual Core Pointer.
+ *
+ * Aside from initialisation, it backs up the original device classes into the
+ * devicePrivates. This only needs to be done for master devices.
*/
static int
CorePointerProc(DeviceIntPtr pDev, int what)
{
BYTE map[33];
int i = 0;
+ ClassesPtr classes;
switch (what) {
case DEVICE_INIT:
+ if (!(classes = xcalloc(1, sizeof(ClassesRec))))
+ return BadAlloc;
+
for (i = 1; i <= 32; i++)
map[i] = i;
InitPointerDeviceStruct((DevicePtr)pDev, map, 32,
- GetMotionHistory, (PtrCtrlProcPtr)NoopDDA,
+ (PtrCtrlProcPtr)NoopDDA,
GetMotionHistorySize(), 2);
pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
- pDev->valuator->lastx = pDev->valuator->axisVal[0];
+ pDev->last.valuators[0] = pDev->valuator->axisVal[0];
pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
- pDev->valuator->lasty = pDev->valuator->axisVal[1];
+ pDev->last.valuators[1] = pDev->valuator->axisVal[1];
break;
case DEVICE_CLOSE:
- dixSetPrivate(&pDev->devPrivates, CoreDevicePrivateKey, NULL);
break;
default:
@@ -402,68 +595,41 @@ CorePointerProc(DeviceIntPtr pDev, int what)
/**
* Initialise the two core devices, VCP and VCK (see events.c).
- * The devices are activated but not enabled.
+ * Both devices are not tied to physical devices, but guarantee that there is
+ * always a keyboard and a pointer present and keep the protocol semantics.
+ *
* Note that the server MUST have two core devices at all times, even if there
* is no physical device connected.
*/
void
InitCoreDevices(void)
{
- DeviceIntPtr dev;
+ if (AllocMasterDevice(serverClient, "Virtual core",
+ &inputInfo.pointer,
+ &inputInfo.keyboard) != Success)
+ FatalError("Failed to allocate core devices");
+
+ ActivateDevice(inputInfo.pointer);
+ ActivateDevice(inputInfo.keyboard);
+ EnableDevice(inputInfo.pointer);
+ EnableDevice(inputInfo.keyboard);
- if (!inputInfo.keyboard) {
- dev = AddInputDevice(CoreKeyboardProc, TRUE);
- if (!dev)
- FatalError("Failed to allocate core keyboard");
- dev->name = strdup("Virtual core keyboard");
-#ifdef XKB
- dev->public.processInputProc = CoreProcessKeyboardEvent;
- dev->public.realInputProc = CoreProcessKeyboardEvent;
- if (!noXkbExtension)
- XkbSetExtension(dev, ProcessKeyboardEvent);
-#else
- dev->public.processInputProc = ProcessKeyboardEvent;
- dev->public.realInputProc = ProcessKeyboardEvent;
-#endif
- dev->ActivateGrab = ActivateKeyboardGrab;
- dev->DeactivateGrab = DeactivateKeyboardGrab;
- dev->coreEvents = FALSE;
- (void)ActivateDevice(dev);
- inputInfo.keyboard = dev;
- }
-
- if (!inputInfo.pointer) {
- dev = AddInputDevice(CorePointerProc, TRUE);
- if (!dev)
- FatalError("Failed to allocate core pointer");
- dev->name = strdup("Virtual core pointer");
-#ifdef XKB
- dev->public.processInputProc = CoreProcessPointerEvent;
- dev->public.realInputProc = CoreProcessPointerEvent;
- if (!noXkbExtension)
- XkbSetExtension(dev, ProcessPointerEvent);
-#else
- dev->public.processInputProc = ProcessPointerEvent;
- dev->public.realInputProc = ProcessPointerEvent;
-#endif
- dev->ActivateGrab = ActivatePointerGrab;
- dev->DeactivateGrab = DeactivatePointerGrab;
- dev->coreEvents = FALSE;
- (void)ActivateDevice(dev);
- inputInfo.pointer = dev;
- }
}
/**
* Activate all switched-off devices and then enable all those devices.
- *
+ *
* Will return an error if no core keyboard or core pointer is present.
* In theory this should never happen if you call InitCoreDevices() first.
- *
+ *
+ * InitAndStartDevices needs to be called AFTER the windows are initialized.
+ * Devices will start sending events after InitAndStartDevices() has
+ * completed.
+ *
* @return Success or error code on failure.
*/
int
-InitAndStartDevices(void)
+InitAndStartDevices()
{
DeviceIntPtr dev, next;
@@ -472,6 +638,8 @@ InitAndStartDevices(void)
if (!dev->inited)
ActivateDevice(dev);
}
+
+ /* enable real devices */
for (dev = inputInfo.off_devices; dev; dev = next)
{
DebugF("(dix) enabling device %d\n", dev->id);
@@ -479,27 +647,183 @@ InitAndStartDevices(void)
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;
+
+ return Success;
+}
+
+/**
+ * Free the given device class and reset the pointer to NULL.
+ */
+static void
+FreeDeviceClass(int type, pointer *class)
+{
+ if (!(*class))
+ return;
+
+ switch(type)
+ {
+ case KeyClass:
+ {
+ KeyClassPtr* k = (KeyClassPtr*)class;
+#ifdef XKB
+ if ((*k)->xkbInfo)
+ {
+ XkbFreeInfo((*k)->xkbInfo);
+ (*k)->xkbInfo = NULL;
+ }
+#endif
+ xfree((*k)->curKeySyms.map);
+ xfree((*k)->modifierKeyMap);
+ xfree((*k));
+ break;
+ }
+ case ButtonClass:
+ {
+ ButtonClassPtr *b = (ButtonClassPtr*)class;
+#ifdef XKB
+ if ((*b)->xkb_acts)
+ xfree((*b)->xkb_acts);
+#endif
+ xfree((*b));
+ break;
+ }
+ case ValuatorClass:
+ {
+ ValuatorClassPtr *v = (ValuatorClassPtr*)class;
+
+ /* Counterpart to 'biggest hack ever' in init. */
+ if ((*v)->motion)
+ xfree((*v)->motion);
+ xfree((*v));
+ break;
+ }
+ case FocusClass:
+ {
+ FocusClassPtr *f = (FocusClassPtr*)class;
+ xfree((*f)->trace);
+ xfree((*f));
+ break;
+ }
+ case ProximityClass:
+ {
+ ProximityClassPtr *p = (ProximityClassPtr*)class;
+ xfree((*p));
+ break;
+ }
}
- for (dev = inputInfo.devices;
- dev && (dev != inputInfo.pointer);
- dev = dev->next)
- ;
- if (!dev || (dev != inputInfo.pointer)) {
- ErrorF("No core pointer\n");
- return BadImplementation;
+ *class = NULL;
+}
+
+static void
+FreeFeedbackClass(int type, pointer *class)
+{
+ if (!(*class))
+ return;
+
+ switch(type)
+ {
+ case KbdFeedbackClass:
+ {
+ KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class;
+ KbdFeedbackPtr k, knext;
+ for (k = (*kbdfeed); k; k = knext) {
+ knext = k->next;
+#ifdef XKB
+ if (k->xkb_sli)
+ XkbFreeSrvLedInfo(k->xkb_sli);
+#endif
+ xfree(k);
+ }
+ break;
+ }
+ case PtrFeedbackClass:
+ {
+ PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class;
+ PtrFeedbackPtr p, pnext;
+
+ for (p = (*ptrfeed); p; p = pnext) {
+ pnext = p->next;
+ xfree(p);
+ }
+ break;
+ }
+ case IntegerFeedbackClass:
+ {
+ IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class;
+ IntegerFeedbackPtr i, inext;
+
+ for (i = (*intfeed); i; i = inext) {
+ inext = i->next;
+ xfree(i);
+ }
+ break;
+ }
+ case StringFeedbackClass:
+ {
+ StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class;
+ StringFeedbackPtr s, snext;
+
+ for (s = (*stringfeed); s; s = snext) {
+ snext = s->next;
+ xfree(s->ctrl.symbols_supported);
+ xfree(s->ctrl.symbols_displayed);
+ xfree(s);
+ }
+ break;
+ }
+ case BellFeedbackClass:
+ {
+ BellFeedbackPtr *bell = (BellFeedbackPtr*)class;
+ BellFeedbackPtr b, bnext;
+
+ for (b = (*bell); b; b = bnext) {
+ bnext = b->next;
+ xfree(b);
+ }
+ break;
+ }
+ case LedFeedbackClass:
+ {
+ LedFeedbackPtr *leds = (LedFeedbackPtr*)class;
+ LedFeedbackPtr l, lnext;
+
+ for (l = (*leds); l; l = lnext) {
+ lnext = l->next;
+#ifdef XKB
+ if (l->xkb_sli)
+ XkbFreeSrvLedInfo(l->xkb_sli);
+#endif
+ xfree(l);
+ }
+ break;
+ }
}
- return Success;
+ *class = NULL;
+}
+
+static void
+FreeAllDeviceClasses(ClassesPtr classes)
+{
+ if (!classes)
+ return;
+
+ FreeDeviceClass(KeyClass, (pointer)&classes->key);
+ FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator);
+ FreeDeviceClass(ButtonClass, (pointer)&classes->button);
+ FreeDeviceClass(FocusClass, (pointer)&classes->focus);
+ FreeDeviceClass(ProximityClass, (pointer)&classes->proximity);
+
+ FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed);
+ FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed);
+ FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed);
+ FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed);
+ FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell);
+ FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds);
+
}
/**
- * Close down a device and free all resources.
+ * Close down a device and free all resources.
* Once closed down, the driver will probably not expect you that you'll ever
* enable it again and free associated structs. If you want the device to just
* be disabled, DisableDevice().
@@ -508,106 +832,65 @@ InitAndStartDevices(void)
static void
CloseDevice(DeviceIntPtr dev)
{
- KbdFeedbackPtr k, knext;
- PtrFeedbackPtr p, pnext;
- IntegerFeedbackPtr i, inext;
- StringFeedbackPtr s, snext;
- BellFeedbackPtr b, bnext;
- LedFeedbackPtr l, lnext;
+ ScreenPtr screen = screenInfo.screens[0];
+ ClassesPtr classes;
+ int j;
+
+ if (!dev)
+ return;
+
+ XIDeleteAllDeviceProperties(dev);
if (dev->inited)
(void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
- xfree(dev->name);
+ /* free sprite memory */
+ if (dev->isMaster && dev->spriteInfo->sprite)
+ screen->DeviceCursorCleanup(dev, screen);
- if (dev->key) {
-#ifdef XKB
- if (dev->key->xkbInfo)
- XkbFreeInfo(dev->key->xkbInfo);
-#endif
- dev->key->xkbInfo = NULL;
- xfree(dev->key->curKeySyms.map);
- xfree(dev->key->modifierKeyMap);
- xfree(dev->key);
- dev->key = NULL;
- }
+ /* free acceleration info */
+ if(dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
+ dev->valuator->accelScheme.AccelCleanupProc(dev);
- if (dev->valuator) {
- /* Counterpart to 'biggest hack ever' in init. */
- if (dev->valuator->motion &&
- dev->valuator->GetMotionProc == GetMotionHistory)
- xfree(dev->valuator->motion);
- xfree(dev->valuator);
- }
+ xfree(dev->name);
- if (dev->button) {
-#ifdef XKB
- if (dev->button->xkb_acts)
- xfree(dev->button->xkb_acts);
-#endif
- xfree(dev->button);
- }
+ classes = (ClassesPtr)&dev->key;
+ FreeAllDeviceClasses(classes);
- if (dev->focus) {
- xfree(dev->focus->trace);
- xfree(dev->focus);
+ if (dev->isMaster)
+ {
+ classes = dixLookupPrivate(&dev->devPrivates, UnusedClassesPrivateKey);
+ FreeAllDeviceClasses(classes);
}
- if (dev->proximity)
- xfree(dev->proximity);
- for (k = dev->kbdfeed; k; k = knext) {
- knext = k->next;
#ifdef XKB
- if (k->xkb_sli)
- XkbFreeSrvLedInfo(k->xkb_sli);
+ while (dev->xkb_interest)
+ XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
#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);
+ if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
+ xfree(dev->spriteInfo->sprite->spriteTrace);
+ xfree(dev->spriteInfo->sprite);
}
- 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);
+ /* a client may have the device set as client pointer */
+ for (j = 0; j < currentMaxClients; j++)
+ {
+ if (clients[j] && clients[j]->clientPtr == dev)
+ {
+ clients[j]->clientPtr = NULL;
+ clients[j]->clientPtr = PickPointer(clients[j]);
+ }
}
-#ifdef XKB
- while (dev->xkb_interest)
- XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
-#endif
-
- xfree(dev->sync.event);
+ xfree(dev->deviceGrab.sync.event);
dixFreePrivates(dev->devPrivates);
xfree(dev);
}
/**
- * Shut down all devices, free all resources, etc.
+ * Shut down all devices, free all resources, etc.
* Only useful if you're shutting down the server!
*/
void
@@ -615,6 +898,17 @@ CloseDownDevices(void)
{
DeviceIntPtr dev, next;
+ /* Float all SDs before closing them. Note that at this point resources
+ * (e.g. cursors) have been freed already, so we can't just call
+ * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
+ * to NULL and pretend nothing happened.
+ */
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!dev->isMaster && dev->u.master)
+ dev->u.master = NULL;
+ }
+
for (dev = inputInfo.devices; dev; dev = next)
{
next = dev->next;
@@ -625,17 +919,40 @@ CloseDownDevices(void)
next = dev->next;
DeleteInputDeviceRequest(dev);
}
+
inputInfo.devices = NULL;
inputInfo.off_devices = NULL;
inputInfo.keyboard = NULL;
inputInfo.pointer = NULL;
+#ifdef XKB
+ XkbDeleteRulesDflts();
+#endif
+}
+
+/**
+ * Remove the cursor sprite for all devices. This needs to be done before any
+ * resources are freed or any device is deleted.
+ */
+void
+UndisplayDevices()
+{
+ DeviceIntPtr dev;
+ ScreenPtr screen = screenInfo.screens[0];
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ screen->DisplayCursor(dev, screen, NullCursor);
}
/**
* Remove a device from the device list, closes it and thus frees all
- * resources.
+ * resources.
* Removes both enabled and disabled devices and notifies all devices about
* the removal of the device.
+ *
+ * No PresenceNotify is sent for device that the client never saw. This can
+ * happen if a malloc fails during the addition of master devices. If
+ * dev->init is FALSE it means the client never received a DeviceAdded event,
+ * so let's not send a DeviceRemoved event either.
*/
int
RemoveDevice(DeviceIntPtr dev)
@@ -644,13 +961,19 @@ RemoveDevice(DeviceIntPtr dev)
int ret = BadMatch;
devicePresenceNotify ev;
DeviceIntRec dummyDev;
+ ScreenPtr screen = screenInfo.screens[0];
int deviceid;
+ int initialized;
DebugF("(dix) removing device %d\n", dev->id);
if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
return BadImplementation;
+ initialized = dev->inited;
+ if (DevHasCursor(dev))
+ screen->DisplayCursor(dev, screen, NullCursor);
+
deviceid = dev->id;
DisableDevice(dev);
@@ -658,13 +981,13 @@ RemoveDevice(DeviceIntPtr dev)
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;
+ CloseDevice(tmp);
ret = Success;
}
}
@@ -683,14 +1006,14 @@ RemoveDevice(DeviceIntPtr dev)
ret = Success;
}
}
-
- if (ret == Success) {
+
+ if (ret == Success && initialized) {
inputInfo.numDevices--;
ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds;
ev.devchange = DeviceRemoved;
ev.deviceid = deviceid;
- dummyDev.id = 0;
+ dummyDev.id = MAXDEVICES;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1);
}
@@ -701,6 +1024,8 @@ RemoveDevice(DeviceIntPtr dev)
int
NumMotionEvents(void)
{
+ /* only called to fill data in initial connection reply.
+ * VCP is ok here, it is the only fixed device we have. */
return inputInfo.pointer->valuator->numMotionEvents;
}
@@ -776,10 +1101,9 @@ SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
KeySym *map;
int bytes = sizeof(KeySym) * src->mapWidth *
(dst->maxKeyCode - dst->minKeyCode + 1);
- map = (KeySym *)xalloc(bytes);
+ map = (KeySym *)xcalloc(1, bytes);
if (!map)
return FALSE;
- bzero((char *)map, bytes);
if (dst->map)
{
for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
@@ -790,6 +1114,16 @@ SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
}
dst->mapWidth = src->mapWidth;
dst->map = map;
+ } else if (!dst->map)
+ {
+ KeySym *map;
+ int bytes = sizeof(KeySym) * src->mapWidth *
+ (dst->maxKeyCode - dst->minKeyCode + 1);
+ map = (KeySym *)xcalloc(1, bytes);
+ if (!map)
+ return FALSE;
+ dst->map = map;
+ dst->mapWidth = src->mapWidth;
}
memmove((char *)&dst->map[rowDif * dst->mapWidth],
(char *)src->map,
@@ -819,10 +1153,9 @@ InitModMap(KeyClassPtr keyc)
}
}
}
- keyc->modifierKeyMap = (KeyCode *)xalloc(8*keyc->maxKeysPerModifier);
+ keyc->modifierKeyMap = xcalloc(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++)
@@ -843,27 +1176,15 @@ InitModMap(KeyClassPtr keyc)
_X_EXPORT Bool
InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[])
{
- int i;
KeyClassPtr keyc;
-
- keyc = (KeyClassPtr)xalloc(sizeof(KeyClassRec));
+
+ keyc = xcalloc(1, 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);
- bzero((char *)keyc->postdown, DOWN_LENGTH);
- for (i = 0; i < 8; i++)
- keyc->modifierKeyCount[i] = 0;
if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
{
xfree(keyc->curKeySyms.map);
@@ -880,32 +1201,24 @@ InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers
}
_X_EXPORT Bool
-InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons,
+InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons,
CARD8 *map)
{
ButtonClassPtr butc;
int i;
- butc = (ButtonClassPtr)xalloc(sizeof(ButtonClassRec));
+ butc = xcalloc(1, 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,
+InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
int numMotionEvents, int mode)
{
int i;
@@ -914,7 +1227,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
if (!dev)
return FALSE;
- valc = (ValuatorClassPtr)xalloc(sizeof(ValuatorClassRec) +
+ valc = (ValuatorClassPtr)xcalloc(1, sizeof(ValuatorClassRec) +
numAxes * sizeof(AxisInfo) +
numAxes * sizeof(unsigned int));
if (!valc)
@@ -923,7 +1236,6 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
valc->motion = NULL;
valc->first_motion = 0;
valc->last_motion = 0;
- valc->GetMotionProc = motionProc;
valc->numMotionEvents = numMotionEvents;
valc->motionHintWindow = NullWindow;
@@ -931,20 +1243,82 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
valc->mode = mode;
valc->axes = (AxisInfoPtr)(valc + 1);
valc->axisVal = (int *)(valc->axes + numAxes);
- valc->lastx = 0;
- valc->lasty = 0;
- valc->dxremaind = 0;
- valc->dyremaind = 0;
dev->valuator = valc;
- /* biggest hack ever. */
- if (motionProc == GetMotionHistory)
- AllocateMotionHistory(dev);
+ AllocateMotionHistory(dev);
for (i=0; i<numAxes; i++) {
- InitValuatorAxisStruct(dev, i, 0, -1, 0, 0, 0);
+ InitValuatorAxisStruct(dev, i, NO_AXIS_LIMITS, NO_AXIS_LIMITS,
+ 0, 0, 0);
valc->axisVal[i]=0;
}
+
+ dev->last.numValuators = numAxes;
+ if(dev->isMaster) /* master devs do not accelerate */
+ InitPointerAccelerationScheme(dev, PtrAccelNoOp);
+ else
+ InitPointerAccelerationScheme(dev, PtrAccelDefault);
+ return TRUE;
+}
+
+/* global list of acceleration schemes */
+ValuatorAccelerationRec pointerAccelerationScheme[] = {
+ {PtrAccelNoOp, NULL, NULL, NULL},
+ {PtrAccelPredictable, acceleratePointerPredictable, NULL, AccelerationDefaultCleanup},
+ {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL},
+ {-1, NULL, NULL, NULL} /* terminator */
+};
+
+/**
+ * install an acceleration scheme. returns TRUE on success, and should not
+ * change anything if unsuccessful.
+ */
+_X_EXPORT Bool
+InitPointerAccelerationScheme(DeviceIntPtr dev,
+ int scheme)
+{
+ int x, i = -1;
+ void* data = NULL;
+ ValuatorClassPtr val;
+
+ val = dev->valuator;
+
+ if(!val)
+ return FALSE;
+
+ if(dev->isMaster && (scheme != PtrAccelNoOp))
+ scheme = PtrAccelNoOp; /* no accel for master devices */
+
+ for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
+ if(pointerAccelerationScheme[x].number == scheme){
+ i = x;
+ break;
+ }
+ }
+
+ if(-1 == i)
+ return FALSE;
+
+
+ /* init scheme-specific data */
+ switch(scheme){
+ case PtrAccelPredictable:
+ {
+ DeviceVelocityPtr s;
+ s = (DeviceVelocityPtr)xalloc(sizeof(DeviceVelocityRec));
+ if(!s)
+ return FALSE;
+ InitVelocityData(s);
+ data = s;
+ break;
+ }
+ default:
+ break;
+ }
+
+ val->accelScheme = pointerAccelerationScheme[i];
+ val->accelScheme.accelData = data;
+
return TRUE;
}
@@ -958,10 +1332,10 @@ InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
return FALSE;
/* we don't do anything sensible with these, but should */
- abs->min_x = -1;
- abs->min_y = -1;
- abs->max_x = -1;
- abs->max_y = -1;
+ abs->min_x = NO_AXIS_LIMITS;
+ abs->min_y = NO_AXIS_LIMITS;
+ abs->max_x = NO_AXIS_LIMITS;
+ abs->max_y = NO_AXIS_LIMITS;
abs->flip_x = 0;
abs->flip_y = 0;
abs->rotation = 0;
@@ -969,8 +1343,8 @@ InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
abs->offset_x = 0;
abs->offset_y = 0;
- abs->width = -1;
- abs->height = -1;
+ abs->width = NO_AXIS_LIMITS;
+ abs->height = NO_AXIS_LIMITS;
abs->following = 0;
abs->screen = 0;
@@ -998,7 +1372,7 @@ InitFocusClassDeviceStruct(DeviceIntPtr dev)
}
_X_EXPORT Bool
-InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
+InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
KbdCtrlProcPtr controlProc)
{
KbdFeedbackPtr feedc;
@@ -1062,7 +1436,7 @@ static IntegerCtrl defaultIntegerControl = {
_X_EXPORT Bool
InitStringFeedbackClassDeviceStruct (
- DeviceIntPtr dev, StringCtrlProcPtr controlProc,
+ DeviceIntPtr dev, StringCtrlProcPtr controlProc,
int max_symbols, int num_symbols_supported, KeySym *symbols)
{
int i;
@@ -1075,9 +1449,9 @@ InitStringFeedbackClassDeviceStruct (
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 *)
+ feedc->ctrl.symbols_supported = (KeySym *)
xalloc (sizeof (KeySym) * num_symbols_supported);
- feedc->ctrl.symbols_displayed = (KeySym *)
+ feedc->ctrl.symbols_displayed = (KeySym *)
xalloc (sizeof (KeySym) * max_symbols);
if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
{
@@ -1101,7 +1475,7 @@ InitStringFeedbackClassDeviceStruct (
}
_X_EXPORT Bool
-InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
+InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
BellCtrlProcPtr controlProc)
{
BellFeedbackPtr feedc;
@@ -1160,23 +1534,22 @@ InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr contr
}
_X_EXPORT Bool
-InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
- ValuatorMotionProcPtr motionProc,
+InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
PtrCtrlProcPtr controlProc, int numMotionEvents,
int numAxes)
{
DeviceIntPtr dev = (DeviceIntPtr)device;
return(InitButtonClassDeviceStruct(dev, numButtons, map) &&
- InitValuatorClassDeviceStruct(dev, numAxes, motionProc,
+ InitValuatorClassDeviceStruct(dev, numAxes,
numMotionEvents, 0) &&
InitPtrFeedbackClassDeviceStruct(dev, controlProc));
}
_X_EXPORT Bool
-InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
- CARD8 pModifiers[], BellProcPtr bellProc,
- KbdCtrlProcPtr controlProc)
+InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
+ CARD8 pModifiers[], BellProcPtr bellProc,
+ KbdCtrlProcPtr controlProc)
{
DeviceIntPtr dev = (DeviceIntPtr)device;
@@ -1186,8 +1559,8 @@ InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
}
_X_EXPORT void
-SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
- ClientPtr client)
+SendMappingNotify(DeviceIntPtr pDev, unsigned request, unsigned firstKeyCode,
+ unsigned count, ClientPtr client)
{
int i;
xEvent event;
@@ -1201,9 +1574,9 @@ SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
}
#ifdef XKB
if (!noXkbExtension &&
- ((request == MappingKeyboard) || (request == MappingModifier)))
- XkbApplyMappingChange(inputInfo.keyboard, request, firstKeyCode, count,
- client);
+ ((request == MappingKeyboard) || (request == MappingModifier))) {
+ XkbApplyMappingChange(pDev,request,firstKeyCode,count, client);
+ }
#endif
/* 0 is the server client */
@@ -1225,13 +1598,15 @@ SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
}
/*
- * 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?
+ * Check if the given buffer contains elements between low (inclusive) and
+ * high (inclusive) only.
+ *
+ * @return TRUE if the device map is invalid, FALSE otherwise.
*/
Bool
BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
{
- int i, j;
+ int i;
for (i = 0; i < length; i++)
if (buff[i]) /* only check non-zero elements */
@@ -1241,12 +1616,6 @@ BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
*errval = buff[i];
return TRUE;
}
- for (j = i + 1; j < length; j++)
- if (buff[i] == buff[j])
- {
- *errval = buff[i];
- return TRUE;
- }
}
return FALSE;
}
@@ -1281,10 +1650,11 @@ DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
int numKeyPerModifier, xSetModifierMappingReply *rep)
{
DeviceIntPtr pDev = NULL;
+ DeviceIntPtr cp = PickKeyboard(client); /* ClientPointer keyboard */
int rc, i = 0, inputMapLen = numKeyPerModifier * 8;
for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
- if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
+ if (pDev == cp || (!pDev->isMaster && (pDev->u.master == cp) && pDev->key)) {
for (i = 0; i < inputMapLen; i++) {
/* Check that all the new modifiers fall within the advertised
* keycode range, and are okay with the DDX. */
@@ -1350,7 +1720,7 @@ DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
return Success;
}
-int
+int
ProcSetModifierMapping(ClientPtr client)
{
xSetModifierMappingReply rep;
@@ -1372,7 +1742,6 @@ ProcSetModifierMapping(ClientPtr client)
if (rc != Success)
return rc;
- SendMappingNotify(MappingModifier, 0, 0, client);
for (dev = inputInfo.devices; dev; dev = dev->next)
if (dev->key && dev->coreEvents)
SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
@@ -1384,12 +1753,12 @@ int
ProcGetModifierMapping(ClientPtr client)
{
xGetModifierMappingReply rep;
- KeyClassPtr keyc = inputInfo.keyboard->key;
+ DeviceIntPtr dev = PickKeyboard(client);
+ KeyClassPtr keyc = dev->key;
int rc;
REQUEST_SIZE_MATCH(xReq);
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard,
- DixGetAttrAccess);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess);
if (rc != Success)
return rc;
@@ -1413,12 +1782,12 @@ ProcChangeKeyboardMapping(ClientPtr client)
REQUEST(xChangeKeyboardMappingReq);
unsigned len;
KeySymsRec keysyms;
- KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+ KeySymsPtr curKeySyms = &PickKeyboard(client)->key->curKeySyms;
DeviceIntPtr pDev = NULL;
int rc;
REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
- len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);
+ len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);
if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
return BadLength;
@@ -1451,8 +1820,6 @@ ProcChangeKeyboardMapping(ClientPtr client)
if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms))
return BadAlloc;
- SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
- client);
for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
if (pDev->key && pDev->coreEvents)
SendDeviceMappingNotify(client, MappingKeyboard,
@@ -1466,36 +1833,23 @@ static int
DoSetPointerMapping(ClientPtr client, DeviceIntPtr device, BYTE *map, int n)
{
int rc, i = 0;
- DeviceIntPtr dev = NULL;
if (!device || !device->button)
return BadDevice;
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
- if (rc != Success)
- return rc;
- }
- }
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixManageAccess);
+ if (rc != Success)
+ return rc;
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
- for (i = 0; i < n; i++) {
- if ((device->button->map[i + 1] != map[i]) &&
- BitIsOn(device->button->down, i + 1)) {
- return MappingBusy;
- }
- }
+ for (i = 0; i < n; i++) {
+ if ((device->button->map[i + 1] != map[i]) &&
+ BitIsOn(device->button->down, i + 1)) {
+ return MappingBusy;
}
}
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
- for (i = 0; i < n; i++)
- dev->button->map[i + 1] = map[i];
- }
- }
+ for (i = 0; i < n; i++)
+ device->button->map[i + 1] = map[i];
return Success;
}
@@ -1505,6 +1859,8 @@ ProcSetPointerMapping(ClientPtr client)
{
BYTE *map;
int ret;
+ int i, j;
+ DeviceIntPtr ptr = PickPointer(client);
xSetPointerMappingReply rep;
REQUEST(xSetPointerMappingReq);
REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
@@ -1516,25 +1872,41 @@ ProcSetPointerMapping(ClientPtr client)
rep.sequenceNumber = client->sequence;
rep.success = MappingSuccess;
map = (BYTE *)&stuff[1];
-
+
/* So we're bounded here by the number of core buttons. This check
* probably wants disabling through XFixes. */
- if (stuff->nElts != inputInfo.pointer->button->numButtons) {
+ /* MPX: With ClientPointer, we can return the right number of buttons.
+ * Let's just hope nobody changed ClientPointer between GetPointerMapping
+ * and SetPointerMapping
+ */
+ if (stuff->nElts != ptr->button->numButtons) {
client->errorValue = stuff->nElts;
return BadValue;
}
if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
return BadValue;
- ret = DoSetPointerMapping(client, inputInfo.pointer, map, stuff->nElts);
+ /* core protocol specs don't allow for duplicate mappings. */
+ for (i = 0; i < stuff->nElts; i++)
+ {
+ for (j = i + 1; j < stuff->nElts; j++)
+ {
+ if (map[i] && map[i] == map[j])
+ {
+ client->errorValue = map[i];
+ return BadValue;
+ }
+ }
+ }
+
+ ret = DoSetPointerMapping(client, ptr, map, stuff->nElts);
if (ret != Success) {
rep.success = ret;
WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
return Success;
}
- /* FIXME: Send mapping notifies for all the extended devices as well. */
- SendMappingNotify(MappingPointer, 0, 0, client);
+ SendMappingNotify(ptr, MappingPointer, 0, 0, client);
WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
return Success;
}
@@ -1543,13 +1915,13 @@ int
ProcGetKeyboardMapping(ClientPtr client)
{
xGetKeyboardMappingReply rep;
- KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+ DeviceIntPtr kbd = PickKeyboard(client);
+ KeySymsPtr curKeySyms = &kbd->key->curKeySyms;
int rc;
REQUEST(xGetKeyboardMappingReq);
REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard,
- DixGetAttrAccess);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
if (rc != Success)
return rc;
@@ -1584,12 +1956,14 @@ int
ProcGetPointerMapping(ClientPtr client)
{
xGetPointerMappingReply rep;
- ButtonClassPtr butc = inputInfo.pointer->button;
+ /* Apps may get different values each time they call GetPointerMapping as
+ * the ClientPointer could change. */
+ DeviceIntPtr ptr = PickPointer(client);
+ ButtonClassPtr butc = ptr->button;
int rc;
REQUEST_SIZE_MATCH(xReq);
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.pointer,
- DixGetAttrAccess);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
if (rc != Success)
return rc;
@@ -1599,7 +1973,7 @@ ProcGetPointerMapping(ClientPtr client)
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;
+ return Success;
}
void
@@ -1639,7 +2013,7 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
index2 = (BITS32) lowbit (vmask);
vmask &= ~index2;
switch (index2) {
- case KBKeyClickPercent:
+ case KBKeyClickPercent:
t = (INT8)*vlist;
vlist++;
if (t == -1) {
@@ -1728,8 +2102,8 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
case KBKey:
key = (KeyCode)*vlist;
vlist++;
- if ((KeyCode)key < inputInfo.keyboard->key->curKeySyms.minKeyCode ||
- (KeyCode)key > inputInfo.keyboard->key->curKeySyms.maxKeyCode) {
+ if ((KeyCode)key < keybd->key->curKeySyms.minKeyCode ||
+ (KeyCode)key > keybd->key->curKeySyms.maxKeyCode) {
client->errorValue = key;
return BadValue;
}
@@ -1789,7 +2163,7 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
return Success;
#undef DO_ALL
-}
+}
int
ProcChangeKeyboardControl (ClientPtr client)
@@ -1833,12 +2207,12 @@ int
ProcGetKeyboardControl (ClientPtr client)
{
int rc, i;
- KeybdCtrl *ctrl = &inputInfo.keyboard->kbdfeed->ctrl;
+ DeviceIntPtr kbd = PickKeyboard(client);
+ KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
xGetKeyboardControlReply rep;
REQUEST_SIZE_MATCH(xReq);
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard,
- DixGetAttrAccess);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
if (rc != Success)
return rc;
@@ -1855,21 +2229,26 @@ ProcGetKeyboardControl (ClientPtr client)
rep.map[i] = ctrl->autoRepeats[i];
WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
return Success;
-}
+}
int
ProcBell(ClientPtr client)
{
- DeviceIntPtr keybd = inputInfo.keyboard;
+ DeviceIntPtr keybd = PickKeyboard(client);
int base = keybd->kbdfeed->ctrl.bell;
int newpercent;
int rc;
REQUEST(xBellReq);
REQUEST_SIZE_MATCH(xBellReq);
+ /* Seems like no keyboard actually has the BellProc set. Returning
+ * BadDevice (previous code) will make apps crash badly. The man pages
+ * doesn't say anything about a BadDevice being returned either.
+ * So just quietly do nothing and pretend everything has worked.
+ */
if (!keybd->kbdfeed->BellProc)
- return BadDevice;
-
+ return Success;
+
if (stuff->percent < -100 || stuff->percent > 100) {
client->errorValue = stuff->percent;
return BadValue;
@@ -1879,7 +2258,7 @@ ProcBell(ClientPtr client)
if (stuff->percent < 0)
newpercent = base + newpercent;
else
- newpercent = base - newpercent + stuff->percent;
+ newpercent = base - newpercent + stuff->percent;
for (keybd = inputInfo.devices; keybd; keybd = keybd->next) {
if ((keybd->coreEvents || keybd == inputInfo.keyboard) &&
@@ -1900,20 +2279,20 @@ ProcBell(ClientPtr client)
}
return Success;
-}
+}
int
ProcChangePointerControl(ClientPtr client)
{
- DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr mouse = PickPointer(client);
PtrCtrl ctrl; /* might get BadValue part way through */
int rc;
REQUEST(xChangePointerControlReq);
REQUEST_SIZE_MATCH(xChangePointerControlReq);
-
+
if (!mouse->ptrfeed->CtrlProc)
return BadDevice;
-
+
ctrl = mouse->ptrfeed->ctrl;
if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
client->errorValue = stuff->doAccel;
@@ -1969,7 +2348,7 @@ ProcChangePointerControl(ClientPtr client)
}
for (mouse = inputInfo.devices; mouse; mouse = mouse->next) {
- if ((mouse->coreEvents || mouse == inputInfo.pointer) &&
+ if ((mouse->coreEvents || mouse == PickPointer(client)) &&
mouse->ptrfeed && mouse->ptrfeed->CtrlProc) {
mouse->ptrfeed->ctrl = ctrl;
(*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl);
@@ -1977,18 +2356,18 @@ ProcChangePointerControl(ClientPtr client)
}
return Success;
-}
+}
int
ProcGetPointerControl(ClientPtr client)
{
- PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl;
+ DeviceIntPtr ptr = PickPointer(client);
+ PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
xGetPointerControlReply rep;
int rc;
REQUEST_SIZE_MATCH(xReq);
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.pointer,
- DixGetAttrAccess);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
if (rc != Success)
return rc;
@@ -2005,7 +2384,7 @@ ProcGetPointerControl(ClientPtr client)
void
MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
{
- GrabPtr grab = dev->grab;
+ GrabPtr grab = dev->deviceGrab.grab;
if ((grab && SameClient(grab, client) &&
((grab->eventMask & PointerMotionHintMask) ||
@@ -2026,7 +2405,7 @@ ProcGetMotionEvents(ClientPtr client)
xGetMotionEventsReply rep;
int i, count, xmin, xmax, ymin, ymax, rc;
unsigned long nEvents;
- DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr mouse = PickPointer(client);
TimeStamp start, stop;
REQUEST(xGetMotionEventsReq);
REQUEST_SIZE_MATCH(xGetMotionEventsReq);
@@ -2051,14 +2430,9 @@ ProcGetMotionEvents(ClientPtr client)
{
if (CompareTimeStamps(stop, currentTime) == LATER)
stop = currentTime;
- coords = (xTimecoord *)xalloc(mouse->valuator->numMotionEvents
- * sizeof(xTimecoord));
- if (!coords)
- return BadAlloc;
- count = (*mouse->valuator->GetMotionProc) (mouse, coords,
- start.milliseconds,
- stop.milliseconds,
- pWin->drawable.pScreen);
+ count = GetMotionHistory(mouse, &coords, start.milliseconds,
+ stop.milliseconds, pWin->drawable.pScreen,
+ TRUE);
xmin = pWin->drawable.x - wBorderWidth (pWin);
xmax = pWin->drawable.x + (int)pWin->drawable.width +
wBorderWidth (pWin);
@@ -2094,15 +2468,15 @@ ProcQueryKeymap(ClientPtr client)
{
xQueryKeymapReply rep;
int rc, i;
- CARD8 *down = inputInfo.keyboard->key->down;
+ DeviceIntPtr keybd = PickKeyboard(client);
+ CARD8 *down = keybd->key->down;
REQUEST_SIZE_MATCH(xReq);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 2;
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard,
- DixReadAccess);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
if (rc != Success)
return rc;
@@ -2110,5 +2484,174 @@ ProcQueryKeymap(ClientPtr client)
rep.map[i] = down[i];
WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
+
+ return Success;
+}
+
+/**
+ * Attach device 'dev' to device 'master'.
+ * Client is set to the client that issued the request, or NULL if it comes
+ * from some internal automatic pairing.
+ *
+ * Master may be NULL to set the device floating.
+ *
+ * We don't allow multi-layer hierarchies right now. You can't attach a slave
+ * to another slave.
+ */
+int
+AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
+{
+ ScreenPtr screen;
+ DeviceIntPtr oldmaster;
+ if (!dev || dev->isMaster)
+ return BadDevice;
+
+ if (master && !master->isMaster) /* can't attach to slaves */
+ return BadDevice;
+
+ /* set from floating to floating? */
+ if (!dev->u.master && !master)
+ return Success;
+
+ /* free the existing sprite. */
+ if (!dev->u.master && dev->spriteInfo->paired == dev)
+ {
+ screen = miPointerGetScreen(dev);
+ screen->DeviceCursorCleanup(dev, screen);
+ xfree(dev->spriteInfo->sprite);
+ }
+
+ oldmaster = dev->u.master;
+ dev->u.master = master;
+
+ /* If device is set to floating, we need to create a sprite for it,
+ * otherwise things go bad. However, we don't want to render the cursor,
+ * so we reset spriteOwner.
+ * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
+ * alloc new memory but overwrite the previous one.
+ */
+ if (!master)
+ {
+ WindowPtr currentRoot = dev->spriteInfo->sprite->spriteTrace[0];
+ /* we need to init a fake sprite */
+ screen = currentRoot->drawable.pScreen;
+ screen->DeviceCursorInitialize(dev, screen);
+ dev->spriteInfo->sprite = NULL;
+ InitializeSprite(dev, currentRoot);
+ dev->spriteInfo->spriteOwner = FALSE;
+ dev->spriteInfo->paired = dev;
+
+ } else
+ {
+ dev->spriteInfo->sprite = master->spriteInfo->sprite;
+ dev->spriteInfo->paired = master;
+ dev->spriteInfo->spriteOwner = FALSE;
+ }
+
+ /* If we were connected to master device before, this MD may need to
+ * change back to it's original classes.
+ */
+ if (oldmaster)
+ {
+ DeviceIntPtr it;
+ for (it = inputInfo.devices; it; it = it->next)
+ if (!it->isMaster && it->u.master == oldmaster)
+ break;
+ }
+
+ return Success;
+}
+
+/**
+ * Return the device paired with the given device or NULL.
+ * Returns the device paired with the parent master if the given device is a
+ * slave device.
+ */
+_X_EXPORT DeviceIntPtr
+GetPairedDevice(DeviceIntPtr dev)
+{
+ if (!dev->isMaster && dev->u.master)
+ dev = dev->u.master;
+
+ return dev->spriteInfo->paired;
+}
+
+
+/**
+ * Create a new master device (== one pointer, one keyboard device).
+ * Only allocates the devices, you will need to call ActivateDevice() and
+ * EnableDevice() manually.
+ */
+int
+AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* keybd)
+{
+ DeviceIntPtr pointer;
+ DeviceIntPtr keyboard;
+ ClassesPtr classes;
+ *ptr = *keybd = NULL;
+
+ pointer = AddInputDevice(client, CorePointerProc, TRUE);
+ if (!pointer)
+ return BadAlloc;
+
+ pointer->name = xcalloc(strlen(name) + strlen(" pointer") + 1, sizeof(char));
+ strcpy(pointer->name, name);
+ strcat(pointer->name, " pointer");
+
+#ifdef XKB
+ pointer->public.processInputProc = ProcessOtherEvent;
+ pointer->public.realInputProc = ProcessOtherEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(pointer, ProcessPointerEvent);
+#else
+ pointer->public.processInputProc = ProcessPointerEvent;
+ pointer->public.realInputProc = ProcessPointerEvent;
+#endif
+ pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
+ pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
+ pointer->coreEvents = TRUE;
+ pointer->spriteInfo->spriteOwner = TRUE;
+
+ pointer->u.lastSlave = NULL;
+ pointer->isMaster = TRUE;
+
+ keyboard = AddInputDevice(client, CoreKeyboardProc, TRUE);
+ if (!keyboard)
+ {
+ RemoveDevice(pointer);
+ return BadAlloc;
+ }
+
+ keyboard->name = xcalloc(strlen(name) + strlen(" keyboard") + 1, sizeof(char));
+ strcpy(keyboard->name, name);
+ strcat(keyboard->name, " keyboard");
+
+#ifdef XKB
+ keyboard->public.processInputProc = ProcessOtherEvent;
+ keyboard->public.realInputProc = ProcessOtherEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(keyboard, ProcessKeyboardEvent);
+#else
+ keyboard->public.processInputProc = ProcessKeyboardEvent;
+ keyboard->public.realInputProc = ProcessKeyboardEvent;
+#endif
+ keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+ keyboard->coreEvents = TRUE;
+ keyboard->spriteInfo->spriteOwner = FALSE;
+
+ keyboard->u.lastSlave = NULL;
+ keyboard->isMaster = TRUE;
+
+
+ /* The ClassesRec stores the device classes currently not used. */
+ classes = xcalloc(1, sizeof(ClassesRec));
+ dixSetPrivate(&pointer->devPrivates, UnusedClassesPrivateKey, classes);
+ classes = xcalloc(1, sizeof(ClassesRec));
+ dixSetPrivate(&keyboard->devPrivates, UnusedClassesPrivateKey, classes);
+
+ *ptr = pointer;
+ *keybd = keyboard;
+
return Success;
}
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c
index b91385596..66f8f79ff 100644
--- a/xorg-server/dix/dispatch.c
+++ b/xorg-server/dix/dispatch.c
@@ -136,9 +136,6 @@ int ProcInitialConnection();
#endif
#include "privates.h"
#include "xace.h"
-#ifdef XAPPGROUP
-#include "appgroup.h"
-#endif
#ifdef XKB
#ifndef XKB_IN_SERVER
#define XKB_IN_SERVER
@@ -163,7 +160,6 @@ typedef const char *string;
#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
extern xConnSetupPrefix connSetupPrefix;
-extern char *ConnectionInfo;
static ClientPtr grabClient;
#define GrabNone 0
@@ -201,7 +197,7 @@ XID clientErrorValue; /* XXX this is a kludge */
#define SAME_SCREENS(a, b) (\
(a.pScreen == b.pScreen))
-_X_EXPORT void
+void
SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
{
checkForInput[0] = c0;
@@ -240,7 +236,6 @@ UpdateCurrentTimeIf(void)
currentTime = systime;
}
-#ifdef SMART_SCHEDULE
#undef SMART_DEBUG
@@ -341,7 +336,6 @@ SmartScheduleClient (int *clientReady, int nready)
}
return best;
}
-#endif
#define MAJOROP ((xReq *)client->requestBuffer)->reqType
@@ -353,9 +347,7 @@ Dispatch(void)
ClientPtr client;
int nready;
HWEventQueuePtr* icheck = checkForInput;
-#ifdef SMART_SCHEDULE
long start_tick;
-#endif
nextFreeClientID = 1;
nClients = 0;
@@ -374,13 +366,11 @@ Dispatch(void)
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
@@ -402,19 +392,13 @@ Dispatch(void)
}
isItTimeToYield = FALSE;
-#ifdef XPRINT
- requestingClient = client;
-#endif
-#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)
{
@@ -423,7 +407,6 @@ Dispatch(void)
client->smart_priority--;
break;
}
-#endif
/* now, finally, deal with client requests */
result = ReadRequestFromClient(client);
@@ -471,14 +454,9 @@ Dispatch(void)
}
}
FlushAllOutput();
-#ifdef SMART_SCHEDULE
client = clients[clientReady[nready]];
if (client)
client->smart_stop_tick = SmartScheduleTime;
-#endif
-#ifdef XPRINT
- requestingClient = NULL;
-#endif
}
dispatchException &= ~DE_PRIORITYCHANGE;
}
@@ -1053,9 +1031,7 @@ ProcTranslateCoords(ClientPtr client)
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 +
@@ -1063,7 +1039,6 @@ ProcTranslateCoords(ClientPtr client)
(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
@@ -1077,7 +1052,6 @@ ProcTranslateCoords(ClientPtr client)
wInputShape(pWin),
x - pWin->drawable.x,
y - pWin->drawable.y, &box))
-#endif
)
{
rep.child = pWin->drawable.id;
@@ -2901,18 +2875,16 @@ ProcCreateCursor (ClientPtr client)
return (BadMatch);
n = BitmapBytePad(width)*height;
- srcbits = (unsigned char *)xalloc(n);
+ srcbits = xcalloc(1, n);
if (!srcbits)
return (BadAlloc);
- mskbits = (unsigned char *)xalloc(n);
+ mskbits = 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)
@@ -3465,9 +3437,7 @@ CloseDownClient(ClientPtr client)
if (client->index < nextFreeClientID)
nextFreeClientID = client->index;
clients[client->index] = NullClient;
-#ifdef SMART_SCHEDULE
SmartLastClient = NullClient;
-#endif
dixFreePrivates(client->devPrivates);
xfree(client);
@@ -3512,20 +3482,19 @@ void InitClient(ClientPtr client, int i, pointer ospriv)
if (!noXkbExtension) {
client->xkbClientFlags = 0;
client->mapNotifyMask = 0;
+ client->newKeyboardNotifyMask = 0;
+ client->vMinor = client->vMajor = 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
+
+ client->clientPtr = NULL;
}
/************************
@@ -3643,9 +3612,6 @@ SendConnSetup(ClientPtr client, char *reason)
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
diff --git a/xorg-server/dix/dixfonts.c b/xorg-server/dix/dixfonts.c
index 8ed494c09..02f9d6de8 100644
--- a/xorg-server/dix/dixfonts.c
+++ b/xorg-server/dix/dixfonts.c
@@ -87,7 +87,7 @@ extern FontPtr defaultFont;
static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
static int num_fpes = 0;
-_X_EXPORT FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static FPEFunctions *fpe_functions = (FPEFunctions *) 0;
static int num_fpe_types = 0;
static unsigned char *font_path_string;
@@ -97,9 +97,8 @@ static int size_slept_fpes = 0;
static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
static FontPatternCachePtr patternCache;
-_X_EXPORT int
-FontToXError(err)
- int err;
+static int
+FontToXError(int err)
{
switch (err) {
case Successful:
@@ -117,6 +116,16 @@ FontToXError(err)
}
}
+static 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;
+}
/*
* adding RT_FONT prevents conflict with default cursor font
@@ -304,8 +313,14 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
c->fontname = newname;
c->fnamelen = newlen;
c->current_fpe = 0;
- if (--aliascount <= 0)
+ if (--aliascount <= 0) {
+ /* We've tried resolving this alias 20 times, we're
+ * probably stuck in an infinite loop of aliases pointing
+ * to each other - time to take emergency exit!
+ */
+ err = BadImplementation;
break;
+ }
continue;
}
if (err == BadFontName) {
@@ -388,7 +403,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna
f = (char *)xalloc(lenfname + 1);
memmove(f, pfontname, lenfname);
f[lenfname] = '\0';
- ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ ErrorF("[dix] OpenFont: fontname is \"%s\"\n", f);
xfree(f);
#endif
if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
@@ -466,7 +481,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna
*
* \param value must conform to DeleteType
*/
-_X_EXPORT int
+int
CloseFont(pointer value, XID fid)
{
int nscr;
@@ -1695,7 +1710,7 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
if (len == 0)
{
if (persist)
- ErrorF ("Removing empty element from the valid list of fontpaths\n");
+ ErrorF("[dix] Removing empty element from the valid list of fontpaths\n");
err = BadValue;
}
else
@@ -1747,7 +1762,7 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
{
if (persist)
{
- ErrorF("Could not init font path element %s, removing from list!\n",
+ ErrorF("[dix] Could not init font path element %s, removing from list!\n",
fpe->name);
}
xfree (fpe->name);
@@ -1875,16 +1890,6 @@ GetFontPath(ClientPtr client, int *count, int *length, unsigned char **result)
return Success;
}
-_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)
{
@@ -1904,16 +1909,9 @@ InitFonts (void)
{
patternCache = MakeFontPatternCache();
- if (screenInfo.numScreens > screenInfo.numVideoScreens) {
- PrinterFontRegisterFpeFunctions();
- FontFileCheckRegisterFpeFunctions();
- check_fs_register_fpe_functions();
- } else
- {
- BuiltinRegisterFpeFunctions();
- FontFileRegisterFpeFunctions();
- fs_register_fpe_functions();
- }
+ BuiltinRegisterFpeFunctions();
+ FontFileRegisterFpeFunctions();
+ fs_register_fpe_functions();
}
int
@@ -1926,37 +1924,27 @@ GetDefaultPointSize ()
FontResolutionPtr
GetClientResolutions (int *num)
{
-#ifdef XPRINT
- if (requestingClient && requestingClient->fontResFunc != NULL &&
- !requestingClient->clientGone)
- {
- return (*requestingClient->fontResFunc)(requestingClient, num);
- }
- else
-#endif
- {
- static struct _FontResolution res;
- ScreenPtr pScreen;
+ 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;
- }
+ 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;
}
/*
diff --git a/xorg-server/dix/dixutils.c b/xorg-server/dix/dixutils.c
index aaf510623..340564ecd 100644
--- a/xorg-server/dix/dixutils.c
+++ b/xorg-server/dix/dixutils.c
@@ -270,14 +270,15 @@ dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access)
*pClient = clients[clientIndex];
return Success;
bad:
- client->errorValue = rid;
+ if(client)
+ client->errorValue = rid;
*pClient = NULL;
return rc;
}
int
AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode,
- Bool toRoot, Bool remap)
+ Bool toRoot, Bool map)
{
int numnow;
SaveSetElt *pTmp = NULL;
@@ -303,7 +304,7 @@ AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode,
client->numSaved = numnow;
SaveSetAssignWindow(client->saveSet[numnow - 1], pWin);
SaveSetAssignToRoot(client->saveSet[numnow - 1], toRoot);
- SaveSetAssignRemap(client->saveSet[numnow - 1], remap);
+ SaveSetAssignMap(client->saveSet[numnow - 1], map);
return(Success);
}
else if ((mode == SetModeDelete) && (j < numnow))
diff --git a/xorg-server/dix/enterleave.c b/xorg-server/dix/enterleave.c
new file mode 100644
index 000000000..8511dea6f
--- /dev/null
+++ b/xorg-server/dix/enterleave.c
@@ -0,0 +1,1377 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Peter Hutterer
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "exglobals.h"
+#include "enterleave.h"
+
+/* @file This file describes the model for sending core enter/leave events and
+ * focus in/out in the case of multiple pointers/keyboard foci
+ * Since we can't send more than one Enter or Leave/Focus in or out event per
+ * window to a core client without confusing it, this is a rather complicated
+ * approach.
+ *
+ * For a full description of the enter/leave model from a window's
+ * perspective, see
+ * http://lists.freedesktop.org/archives/xorg/2008-August/037606.html
+ *
+ * For a full description of the focus in/out model from a window's
+ * perspective, see
+ * http://lists.freedesktop.org/archives/xorg/2008-December/041740.html
+ *
+ * Additional notes:
+ * -) The core protocol spec says that "In a LeaveNotify event, if a child of the
+ * event window contains the initial position of the pointer, then the child
+ * component is set to that child. Otherwise, it is None. For an EnterNotify
+ * event, if a child of the event window contains the final pointer position,
+ * then the child component is set to that child. Otherwise, it is None."
+ *
+ * By inference, this means that only NotifyVirtual or NotifyNonlinearVirtual
+ * events may have a subwindow set to other than None.
+ *
+ * -) NotifyPointer events may be sent if the focus changes from window A to
+ * B. The assumption used in this model is that NotifyPointer events are only
+ * sent for the pointer paired with the keyboard that is involved in the focus
+ * events. For example, if F(W) changes because of keyboard 2, then
+ * NotifyPointer events are only sent for pointer 2.
+ */
+
+static WindowPtr PointerWindows[MAXDEVICES];
+static WindowPtr FocusWindows[MAXDEVICES];
+
+/**
+ * Return TRUE if @win has a pointer within its boundaries, excluding child
+ * window.
+ */
+static BOOL
+HasPointer(WindowPtr win)
+{
+ int i;
+
+ for (i = 0; i < MAXDEVICES; i++)
+ if (PointerWindows[i] == win)
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * Return TRUE if at least one keyboard focus is set to @win (excluding
+ * descendants of win).
+ */
+static BOOL
+HasFocus(WindowPtr win)
+{
+ int i;
+ for (i = 0; i < MAXDEVICES; i++)
+ if (FocusWindows[i] == win)
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * Return the window the device @dev is currently on.
+ */
+static WindowPtr
+PointerWin(DeviceIntPtr dev)
+{
+ return PointerWindows[dev->id];
+}
+
+/**
+ * Search for the first window below @win that has a pointer directly within
+ * it's boundaries (excluding boundaries of its own descendants).
+ *
+ * @return The child window that has the pointer within its boundaries or
+ * NULL.
+ */
+static WindowPtr
+FirstPointerChild(WindowPtr win)
+{
+ int i;
+ for (i = 0; i < MAXDEVICES; i++)
+ {
+ if (PointerWindows[i] && IsParent(win, PointerWindows[i]))
+ return PointerWindows[i];
+ }
+
+ return NULL;
+}
+
+/**
+ * Search for the first window below @win that has a focus directly within
+ * it's boundaries (excluding boundaries of its own descendants).
+ *
+ * @return The child window that has the pointer within its boundaries or
+ * NULL.
+ */
+static WindowPtr
+FirstFocusChild(WindowPtr win)
+{
+ int i;
+ for (i = 0; i < MAXDEVICES; i++)
+ {
+ if (FocusWindows[i] && FocusWindows[i] != PointerRootWin &&
+ IsParent(win, FocusWindows[i]))
+ return FocusWindows[i];
+ }
+
+ return NULL;
+}
+
+/**
+ * Set the presence flag for @dev to mark that it is now in @win.
+ */
+void
+EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode)
+{
+ PointerWindows[dev->id] = win;
+}
+
+/**
+ * Unset the presence flag for @dev to mark that it is not in @win anymore.
+ */
+static void
+LeaveWindow(DeviceIntPtr dev, WindowPtr win, int mode)
+{
+ PointerWindows[dev->id] = NULL;
+}
+
+/**
+ * Set the presence flag for @dev to mark that it is now in @win.
+ */
+void
+SetFocusIn(DeviceIntPtr dev, WindowPtr win)
+{
+ FocusWindows[dev->id] = win;
+}
+
+/**
+ * Unset the presence flag for @dev to mark that it is not in @win anymore.
+ */
+void
+SetFocusOut(DeviceIntPtr dev, WindowPtr win)
+{
+ FocusWindows[dev->id] = NULL;
+}
+
+
+
+
+/**
+ * @return The window that is the first ancestor of both a and b.
+ */
+WindowPtr
+CommonAncestor(
+ WindowPtr a,
+ WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (IsParent(b, a)) return b;
+ return NullWindow;
+}
+
+
+#if 0
+/**
+ * Send enter notifies to all windows between @ancestor and @child (excluding
+ * both). Events are sent running up the window hierarchy. This function
+ * recurses.
+ * If @core is TRUE, core events are sent, otherwise XI events will be sent.
+ */
+static void
+DeviceEnterNotifies(DeviceIntPtr dev,
+ WindowPtr ancestor,
+ WindowPtr child,
+ int mode,
+ int detail)
+{
+ WindowPtr parent = child->parent;
+
+ if (ancestor == parent)
+ return;
+ DeviceEnterNotifies(dev, ancestor, parent, mode, detail);
+ DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, detail, parent,
+ child->drawable.id);
+}
+#endif
+
+/**
+ * Send enter notifies to all windows between @ancestor and @child (excluding
+ * both). Events are sent running down the window hierarchy. This function
+ * recurses.
+ */
+static void
+CoreEnterNotifies(DeviceIntPtr dev,
+ WindowPtr ancestor,
+ WindowPtr child,
+ int mode,
+ int detail)
+{
+ WindowPtr parent = child->parent;
+ if (ancestor == parent)
+ return;
+ CoreEnterNotifies(dev, ancestor, parent, mode, detail);
+
+
+ /* Case 3:
+ A is above W, B is a descendant
+
+ Classically: The move generates an EnterNotify on W with a detail of
+ Virtual or NonlinearVirtual
+
+ MPX:
+ Case 3A: There is at least one other pointer on W itself
+ P(W) doesn't change, so the event should be suppressed
+ Case 3B: Otherwise, if there is at least one other pointer in a
+ descendant
+ P(W) stays on the same descendant, or changes to a different
+ descendant. The event should be suppressed.
+ Case 3C: Otherwise:
+ P(W) moves from a window above W to a descendant. The subwindow
+ field is set to the child containing the descendant. The detail
+ may need to be changed from Virtual to NonlinearVirtual depending
+ on the previous P(W). */
+
+ if (!HasPointer(parent) && !FirstPointerChild(parent))
+ CoreEnterLeaveEvent(dev, EnterNotify, mode, detail, parent,
+ child->drawable.id);
+}
+
+static void
+CoreLeaveNotifies(DeviceIntPtr dev,
+ WindowPtr child,
+ WindowPtr ancestor,
+ int mode,
+ int detail)
+{
+ WindowPtr win;
+
+ if (ancestor == child)
+ return;
+
+ for (win = child->parent; win != ancestor; win = win->parent)
+ {
+ /*Case 7:
+ A is a descendant of W, B is above W
+
+ Classically: A LeaveNotify is generated on W with a detail of Virtual
+ or NonlinearVirtual.
+
+ MPX:
+ Case 3A: There is at least one other pointer on W itself
+ P(W) doesn't change, the event should be suppressed.
+ Case 3B: Otherwise, if there is at least one other pointer in a
+ descendant
+ P(W) stays on the same descendant, or changes to a different
+ descendant. The event should be suppressed.
+ Case 3C: Otherwise:
+ P(W) changes from the descendant of W to a window above W.
+ The detail may need to be changed from Virtual to NonlinearVirtual
+ or vice-versa depending on the new P(W).*/
+
+ /* If one window has a pointer or a child with a pointer, skip some
+ * work and exit. */
+ if (HasPointer(win) || FirstPointerChild(win))
+ return;
+
+ CoreEnterLeaveEvent(dev, LeaveNotify, mode, detail, win, child->drawable.id);
+
+ child = win;
+ }
+}
+
+#if 0
+/**
+ * Send leave notifies to all windows between @child and @ancestor.
+ * Events are sent running up the hierarchy.
+ */
+static void
+DeviceLeaveNotifies(DeviceIntPtr dev,
+ WindowPtr child,
+ WindowPtr ancestor,
+ int mode,
+ int detail)
+{
+ WindowPtr win;
+
+ if (ancestor == child)
+ return;
+ for (win = child->parent; win != ancestor; win = win->parent)
+ {
+ DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, detail, win,
+ child->drawable.id);
+ child = win;
+ }
+}
+#endif
+
+/**
+ * Pointer @dev moves from @A to @B and @A neither a descendant of @B nor is
+ * @B a descendant of @A.
+ */
+static void
+CoreEnterLeaveNonLinear(DeviceIntPtr dev,
+ WindowPtr A,
+ WindowPtr B,
+ int mode)
+{
+ WindowPtr X = CommonAncestor(A, B);
+ /* Case 4:
+ A is W, B is above W
+
+ Classically: The move generates a LeaveNotify on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 3A: There is at least one other pointer on W itself
+ P(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise, if there is at least one other pointer in a
+ descendant of W
+ P(W) changes from W to a descendant of W. The subwindow field
+ is set to the child containing the new P(W), the detail field
+ is set to Inferior
+ Case 3C: Otherwise:
+ The pointer window moves from W to a window above W.
+ The detail may need to be changed from Ancestor to Nonlinear or
+ vice versa depending on the the new P(W)
+ */
+
+ if (!HasPointer(A))
+ {
+ WindowPtr child = FirstPointerChild(A);
+ if (child)
+ CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyInferior, A, None);
+ else
+ CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyNonlinear, A, None);
+ }
+
+
+ CoreLeaveNotifies(dev, A, X, mode, NotifyNonlinearVirtual);
+
+ /*
+ Case 9:
+ A is a descendant of W, B is a descendant of W
+
+ Classically: No events are generated on W
+ MPX: The pointer window stays the same or moves to a different
+ descendant of W. No events should be generated on W.
+
+
+ Therefore, no event to X.
+ */
+
+ CoreEnterNotifies(dev, X, B, mode, NotifyNonlinearVirtual);
+
+ /* Case 2:
+ A is above W, B=W
+
+ Classically: The move generates an EnterNotify on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 2A: There is at least one other pointer on W itself
+ P(W) doesn't change, so the event should be suppressed
+ Case 2B: Otherwise, if there is at least one other pointer in a
+ descendant
+ P(W) moves from a descendant to W. detail is changed to Inferior,
+ subwindow is set to the child containing the previous P(W)
+ Case 2C: Otherwise:
+ P(W) changes from a window above W to W itself.
+ The detail may need to be changed from Ancestor to Nonlinear
+ or vice-versa depending on the previous P(W). */
+
+ if (!HasPointer(B))
+ {
+ WindowPtr child = FirstPointerChild(B);
+ if (child)
+ CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyInferior, B, None);
+ else
+ CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyNonlinear, B, None);
+ }
+}
+
+/**
+ * Pointer @dev moves from @A to @B and @A is a descendant of @B.
+ */
+static void
+CoreEnterLeaveToAncestor(DeviceIntPtr dev,
+ WindowPtr A,
+ WindowPtr B,
+ int mode)
+{
+ /* Case 4:
+ A is W, B is above W
+
+ Classically: The move generates a LeaveNotify on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 3A: There is at least one other pointer on W itself
+ P(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise, if there is at least one other pointer in a
+ descendant of W
+ P(W) changes from W to a descendant of W. The subwindow field
+ is set to the child containing the new P(W), the detail field
+ is set to Inferior
+ Case 3C: Otherwise:
+ The pointer window moves from W to a window above W.
+ The detail may need to be changed from Ancestor to Nonlinear or
+ vice versa depending on the the new P(W)
+ */
+ if (!HasPointer(A))
+ {
+ WindowPtr child = FirstPointerChild(A);
+ if (child)
+ CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyInferior, A, None);
+ else
+ CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyAncestor, A, None);
+ }
+
+ CoreLeaveNotifies(dev, A, B, mode, NotifyVirtual);
+
+ /* Case 8:
+ A is a descendant of W, B is W
+
+ Classically: A EnterNotify is generated on W with a detail of
+ NotifyInferior
+
+ MPX:
+ Case 3A: There is at least one other pointer on W itself
+ P(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise:
+ P(W) changes from a descendant to W itself. The subwindow
+ field should be set to the child containing the old P(W) <<< WRONG */
+
+ if (!HasPointer(B))
+ CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyInferior, B, None);
+
+}
+
+
+/**
+ * Pointer @dev moves from @A to @B and @B is a descendant of @A.
+ */
+static void
+CoreEnterLeaveToDescendant(DeviceIntPtr dev,
+ WindowPtr A,
+ WindowPtr B,
+ int mode)
+{
+ /* Case 6:
+ A is W, B is a descendant of W
+
+ Classically: A LeaveNotify is generated on W with a detail of
+ NotifyInferior
+
+ MPX:
+ Case 3A: There is at least one other pointer on W itself
+ P(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise:
+ P(W) changes from W to a descendant of W. The subwindow field
+ is set to the child containing the new P(W) <<< THIS IS WRONG */
+
+ if (!HasPointer(A))
+ CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyInferior, A, None);
+
+
+ CoreEnterNotifies(dev, A, B, mode, NotifyVirtual);
+
+ /* Case 2:
+ A is above W, B=W
+
+ Classically: The move generates an EnterNotify on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 2A: There is at least one other pointer on W itself
+ P(W) doesn't change, so the event should be suppressed
+ Case 2B: Otherwise, if there is at least one other pointer in a
+ descendant
+ P(W) moves from a descendant to W. detail is changed to Inferior,
+ subwindow is set to the child containing the previous P(W)
+ Case 2C: Otherwise:
+ P(W) changes from a window above W to W itself.
+ The detail may need to be changed from Ancestor to Nonlinear
+ or vice-versa depending on the previous P(W). */
+
+ if (!HasPointer(B))
+ {
+ WindowPtr child = FirstPointerChild(B);
+ if (child)
+ CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyInferior, B, None);
+ else
+ CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyAncestor, B, None);
+ }
+}
+
+static void
+CoreEnterLeaveEvents(DeviceIntPtr dev,
+ WindowPtr from,
+ WindowPtr to,
+ int mode)
+{
+ if (!dev->isMaster)
+ return;
+
+ LeaveWindow(dev, from, mode);
+
+ if (IsParent(from, to))
+ CoreEnterLeaveToDescendant(dev, from, to, mode);
+ else if (IsParent(to, from))
+ CoreEnterLeaveToAncestor(dev, from, to, mode);
+ else
+ CoreEnterLeaveNonLinear(dev, from, to, mode);
+
+ EnterWindow(dev, to, mode);
+}
+
+#if 0
+static void
+DeviceEnterLeaveEvents(DeviceIntPtr dev,
+ WindowPtr from,
+ WindowPtr to,
+ int mode)
+{
+ if (IsParent(from, to))
+ {
+ DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyInferior, from, None);
+ DeviceEnterNotifies(dev, from, to, mode, NotifyVirtual);
+ DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyAncestor, to, None);
+ }
+ else if (IsParent(to, from))
+ {
+ DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyAncestor, from, None);
+ DeviceLeaveNotifies(dev, from, to, mode, NotifyVirtual);
+ DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyInferior, to, None);
+ }
+ else
+ { /* neither from nor to is descendent of the other */
+ WindowPtr common = CommonAncestor(to, from);
+ /* common == NullWindow ==> different screens */
+ DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyNonlinear, from, None);
+ DeviceLeaveNotifies(dev, from, common, mode, NotifyNonlinearVirtual);
+ DeviceEnterNotifies(dev, common, to, mode, NotifyNonlinearVirtual);
+ DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyNonlinear, to, None);
+ }
+}
+#endif
+
+/**
+ * Figure out if enter/leave events are necessary and send them to the
+ * appropriate windows.
+ *
+ * @param fromWin Window the sprite moved out of.
+ * @param toWin Window the sprite moved into.
+ */
+void
+DoEnterLeaveEvents(DeviceIntPtr pDev,
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode)
+{
+ if (!IsPointerDevice(pDev))
+ return;
+
+ if (fromWin == toWin)
+ return;
+
+ CoreEnterLeaveEvents(pDev, fromWin, toWin, mode);
+#if 0
+ DeviceEnterLeaveEvents(pDev, fromWin, toWin, mode);
+#endif
+}
+
+/**
+ * Send focus out events to all windows between @child and @ancestor.
+ * Events are sent running up the hierarchy.
+ */
+static void
+DeviceFocusOutEvents(DeviceIntPtr dev,
+ WindowPtr child,
+ WindowPtr ancestor,
+ int mode,
+ int detail)
+{
+ WindowPtr win;
+
+ if (ancestor == child)
+ return;
+ for (win = child->parent; win != ancestor; win = win->parent)
+ DeviceFocusEvent(dev, DeviceFocusOut, mode, detail, win);
+}
+
+
+/**
+ * Send enter notifies to all windows between @ancestor and @child (excluding
+ * both). Events are sent running up the window hierarchy. This function
+ * recurses.
+ */
+static void
+DeviceFocusInEvents(DeviceIntPtr dev,
+ WindowPtr ancestor,
+ WindowPtr child,
+ int mode,
+ int detail)
+{
+ WindowPtr parent = child->parent;
+
+ if (ancestor == parent || !parent)
+ return;
+ DeviceFocusInEvents(dev, ancestor, parent, mode, detail);
+ DeviceFocusEvent(dev, DeviceFocusIn, mode, detail, parent);
+}
+
+/**
+ * Send FocusIn events to all windows between @ancestor and @child (excluding
+ * both). Events are sent running down the window hierarchy. This function
+ * recurses.
+ */
+static void
+CoreFocusInEvents(DeviceIntPtr dev,
+ WindowPtr ancestor,
+ WindowPtr child,
+ int mode,
+ int detail)
+{
+ WindowPtr parent = child->parent;
+ if (ancestor == parent)
+ return;
+ CoreFocusInEvents(dev, ancestor, parent, mode, detail);
+
+
+ /* Case 3:
+ A is above W, B is a descendant
+
+ Classically: The move generates an FocusIn on W with a detail of
+ Virtual or NonlinearVirtual
+
+ MPX:
+ Case 3A: There is at least one other focus on W itself
+ F(W) doesn't change, so the event should be suppressed
+ Case 3B: Otherwise, if there is at least one other focus in a
+ descendant
+ F(W) stays on the same descendant, or changes to a different
+ descendant. The event should be suppressed.
+ Case 3C: Otherwise:
+ F(W) moves from a window above W to a descendant. The detail may
+ need to be changed from Virtual to NonlinearVirtual depending
+ on the previous F(W). */
+
+ if (!HasFocus(parent) && !FirstFocusChild(parent))
+ CoreFocusEvent(dev, FocusIn, mode, detail, parent);
+}
+
+static void
+CoreFocusOutEvents(DeviceIntPtr dev,
+ WindowPtr child,
+ WindowPtr ancestor,
+ int mode,
+ int detail)
+{
+ WindowPtr win;
+
+ if (ancestor == child)
+ return;
+
+ for (win = child->parent; win != ancestor; win = win->parent)
+ {
+ /*Case 7:
+ A is a descendant of W, B is above W
+
+ Classically: A FocusOut is generated on W with a detail of Virtual
+ or NonlinearVirtual.
+
+ MPX:
+ Case 3A: There is at least one other focus on W itself
+ F(W) doesn't change, the event should be suppressed.
+ Case 3B: Otherwise, if there is at least one other focus in a
+ descendant
+ F(W) stays on the same descendant, or changes to a different
+ descendant. The event should be suppressed.
+ Case 3C: Otherwise:
+ F(W) changes from the descendant of W to a window above W.
+ The detail may need to be changed from Virtual to NonlinearVirtual
+ or vice-versa depending on the new P(W).*/
+
+ /* If one window has a focus or a child with a focuspointer, skip some
+ * work and exit. */
+ if (HasFocus(win) || FirstFocusChild(win))
+ return;
+
+ CoreFocusEvent(dev, FocusOut, mode, detail, win);
+ }
+}
+
+/**
+ * Send FocusOut(NotifyPointer) events from the current pointer window (which
+ * is a descendant of @pwin_parent) up to (excluding) @pwin_parent.
+ *
+ * NotifyPointer events are only sent for the device paired with @dev.
+ *
+ * If the current pointer window is a descendat of @exclude or an ancestor of
+ * @exclude, no events are sent. Note: If the current pointer IS @exclude,
+ * events are sent!
+ */
+static void
+CoreFocusOutNotifyPointerEvents(DeviceIntPtr dev,
+ WindowPtr pwin_parent,
+ WindowPtr exclude,
+ int mode,
+ int inclusive)
+{
+ WindowPtr P, stopAt;
+
+ P = PointerWin(GetPairedDevice(dev));
+
+ if (!P)
+ return;
+ if (!IsParent(pwin_parent, P))
+ if (!(pwin_parent == P && inclusive))
+ return;
+
+ if (exclude != None && exclude != PointerRootWin &&
+ (IsParent(exclude, P) || IsParent(P, exclude)))
+ return;
+
+ stopAt = (inclusive) ? pwin_parent->parent : pwin_parent;
+
+ for (; P && P != stopAt; P = P->parent)
+ CoreFocusEvent(dev, FocusOut, mode, NotifyPointer, P);
+}
+
+/**
+ * DO NOT CALL DIRECTLY.
+ * Recursion helper for CoreFocusInNotifyPointerEvents.
+ */
+static void
+CoreFocusInRecurse(DeviceIntPtr dev,
+ WindowPtr win,
+ WindowPtr stopAt,
+ int mode,
+ int inclusive)
+{
+ if ((!inclusive && win == stopAt) || !win)
+ return;
+
+ CoreFocusInRecurse(dev, win->parent, stopAt, mode, inclusive);
+ CoreFocusEvent(dev, FocusIn, mode, NotifyPointer, win);
+}
+
+
+/**
+ * Send FocusIn(NotifyPointer) events from @pwin_parent down to
+ * including the current pointer window (which is a descendant of @pwin_parent).
+ * If @inclusive is TRUE, @pwin_parent will receive the event too.
+ *
+ * @pwin is the pointer window.
+ *
+ * If the current pointer window is a child of @exclude, no events are sent.
+ */
+static void
+CoreFocusInNotifyPointerEvents(DeviceIntPtr dev,
+ WindowPtr pwin_parent,
+ WindowPtr exclude,
+ int mode,
+ int inclusive)
+{
+ WindowPtr P;
+
+ P = PointerWin(GetPairedDevice(dev));
+
+ if (!P || P == exclude || (pwin_parent != P && !IsParent(pwin_parent, P)))
+ return;
+
+ if (exclude != None && (IsParent(exclude, P) || IsParent(P, exclude)))
+ return;
+
+ CoreFocusInRecurse(dev, P, pwin_parent, mode, inclusive);
+}
+
+
+/**
+ * Focus of @dev moves from @A to @B and @A neither a descendant of @B nor is
+ * @B a descendant of @A.
+ */
+static void
+CoreFocusNonLinear(DeviceIntPtr dev,
+ WindowPtr A,
+ WindowPtr B,
+ int mode)
+{
+ WindowPtr X = CommonAncestor(A, B);
+
+ /* Case 4:
+ A is W, B is above W
+
+ Classically: The change generates a FocusOut on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 3A: There is at least one other focus on W itself
+ F(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise, if there is at least one other focus in a
+ descendant of W
+ F(W) changes from W to a descendant of W. The detail field
+ is set to Inferior
+ Case 3C: Otherwise:
+ The focus window moves from W to a window above W.
+ The detail may need to be changed from Ancestor to Nonlinear or
+ vice versa depending on the the new F(W)
+ */
+
+ if (!HasFocus(A))
+ {
+ WindowPtr child = FirstFocusChild(A);
+ if (child)
+ {
+ /* NotifyPointer P-A unless P is child or below*/
+ CoreFocusOutNotifyPointerEvents(dev, A, child, mode, FALSE);
+ CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A);
+ } else
+ {
+ /* NotifyPointer P-A */
+ CoreFocusOutNotifyPointerEvents(dev, A, None, mode, FALSE);
+ CoreFocusEvent(dev, FocusOut, mode, NotifyNonlinear, A);
+ }
+ }
+
+
+ CoreFocusOutEvents(dev, A, X, mode, NotifyNonlinearVirtual);
+
+ /*
+ Case 9:
+ A is a descendant of W, B is a descendant of W
+
+ Classically: No events are generated on W
+ MPX: The focus window stays the same or moves to a different
+ descendant of W. No events should be generated on W.
+
+
+ Therefore, no event to X.
+ */
+
+ CoreFocusInEvents(dev, X, B, mode, NotifyNonlinearVirtual);
+
+ /* Case 2:
+ A is above W, B=W
+
+ Classically: The move generates an EnterNotify on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 2A: There is at least one other focus on W itself
+ F(W) doesn't change, so the event should be suppressed
+ Case 2B: Otherwise, if there is at least one other focus in a
+ descendant
+ F(W) moves from a descendant to W. detail is changed to Inferior.
+ Case 2C: Otherwise:
+ F(W) changes from a window above W to W itself.
+ The detail may need to be changed from Ancestor to Nonlinear
+ or vice-versa depending on the previous F(W). */
+
+ if (!HasFocus(B))
+ {
+ WindowPtr child = FirstFocusChild(B);
+ if (child)
+ {
+ CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B);
+ /* NotifyPointer B-P unless P is child or below. */
+ CoreFocusInNotifyPointerEvents(dev, B, child, mode, FALSE);
+ } else {
+ CoreFocusEvent(dev, FocusIn, mode, NotifyNonlinear, B);
+ /* NotifyPointer B-P unless P is child or below. */
+ CoreFocusInNotifyPointerEvents(dev, B, None, mode, FALSE);
+ }
+ }
+}
+
+
+/**
+ * Focus of @dev moves from @A to @B and @A is a descendant of @B.
+ */
+static void
+CoreFocusToAncestor(DeviceIntPtr dev,
+ WindowPtr A,
+ WindowPtr B,
+ int mode)
+{
+ /* Case 4:
+ A is W, B is above W
+
+ Classically: The change generates a FocusOut on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 3A: There is at least one other focus on W itself
+ F(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise, if there is at least one other focus in a
+ descendant of W
+ F(W) changes from W to a descendant of W. The detail field
+ is set to Inferior
+ Case 3C: Otherwise:
+ The focus window moves from W to a window above W.
+ The detail may need to be changed from Ancestor to Nonlinear or
+ vice versa depending on the the new F(W)
+ */
+ if (!HasFocus(A))
+ {
+ WindowPtr child = FirstFocusChild(A);
+ if (child)
+ {
+ /* NotifyPointer P-A unless P is child or below*/
+ CoreFocusOutNotifyPointerEvents(dev, A, child, mode, FALSE);
+ CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A);
+ } else
+ CoreFocusEvent(dev, FocusOut, mode, NotifyAncestor, A);
+ }
+
+ CoreFocusOutEvents(dev, A, B, mode, NotifyVirtual);
+
+ /* Case 8:
+ A is a descendant of W, B is W
+
+ Classically: A FocusOut is generated on W with a detail of
+ NotifyInferior
+
+ MPX:
+ Case 3A: There is at least one other focus on W itself
+ F(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise:
+ F(W) changes from a descendant to W itself. */
+
+ if (!HasFocus(B))
+ {
+ CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B);
+ /* NotifyPointer B-P unless P is A or below. */
+ CoreFocusInNotifyPointerEvents(dev, B, A, mode, FALSE);
+ }
+}
+
+/**
+ * Focus of @dev moves from @A to @B and @B is a descendant of @A.
+ */
+static void
+CoreFocusToDescendant(DeviceIntPtr dev,
+ WindowPtr A,
+ WindowPtr B,
+ int mode)
+{
+ /* Case 6:
+ A is W, B is a descendant of W
+
+ Classically: A FocusOut is generated on W with a detail of
+ NotifyInferior
+
+ MPX:
+ Case 3A: There is at least one other focus on W itself
+ F(W) doesn't change, the event should be suppressed
+ Case 3B: Otherwise:
+ F(W) changes from W to a descendant of W. */
+
+ if (!HasFocus(A))
+ {
+ /* NotifyPointer P-A unless P is B or below*/
+ CoreFocusOutNotifyPointerEvents(dev, A, B, mode, FALSE);
+ CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A);
+ }
+
+
+ CoreFocusInEvents(dev, A, B, mode, NotifyVirtual);
+
+ /* Case 2:
+ A is above W, B=W
+
+ Classically: The move generates an FocusIn on W with a detail of
+ Ancestor or Nonlinear
+
+ MPX:
+ Case 2A: There is at least one other focus on W itself
+ F(W) doesn't change, so the event should be suppressed
+ Case 2B: Otherwise, if there is at least one other focus in a
+ descendant
+ F(W) moves from a descendant to W. detail is changed to Inferior.
+ Case 2C: Otherwise:
+ F(W) changes from a window above W to W itself.
+ The detail may need to be changed from Ancestor to Nonlinear
+ or vice-versa depending on the previous F(W). */
+
+ if (!HasFocus(B))
+ {
+ WindowPtr child = FirstFocusChild(B);
+ if (child)
+ {
+ CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B);
+ /* NotifyPointer B-P unless P is child or below. */
+ CoreFocusInNotifyPointerEvents(dev, B, child, mode, FALSE);
+ } else
+ CoreFocusEvent(dev, FocusIn, mode, NotifyAncestor, B);
+ }
+}
+
+static BOOL
+HasOtherPointer(WindowPtr win, DeviceIntPtr exclude)
+{
+ int i;
+
+ for (i = 0; i < MAXDEVICES; i++)
+ if (i != exclude->id && PointerWindows[i] == win)
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * Focus moves from PointerRoot to None or from None to PointerRoot.
+ * Assumption: Neither A nor B are valid windows.
+ */
+static void
+CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev,
+ WindowPtr A, /* PointerRootWin or NoneWin */
+ WindowPtr B, /* NoneWin or PointerRootWin */
+ int mode)
+{
+ WindowPtr root;
+ int i;
+ int nscreens = screenInfo.numScreens;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ nscreens = 1;
+#endif
+
+ for (i = 0; i < nscreens; i++)
+ {
+ root = WindowTable[i];
+ if (!HasOtherPointer(root, GetPairedDevice(dev)) && !FirstFocusChild(root))
+ {
+ /* If pointer was on PointerRootWin and changes to NoneWin, and
+ * the pointer paired with @dev is below the current root window,
+ * do a NotifyPointer run. */
+ if (dev->focus && dev->focus->win == PointerRootWin &&
+ B != PointerRootWin)
+ {
+ WindowPtr ptrwin = PointerWin(GetPairedDevice(dev));
+ if (ptrwin && IsParent(root, ptrwin))
+ CoreFocusOutNotifyPointerEvents(dev, root, None, mode, TRUE);
+ }
+ CoreFocusEvent(dev, FocusOut, mode, ((int)A) ? NotifyPointerRoot : NotifyDetailNone, root);
+ CoreFocusEvent(dev, FocusIn, mode, ((int)B) ? NotifyPointerRoot : NotifyDetailNone, root);
+ if (B == PointerRootWin)
+ CoreFocusInNotifyPointerEvents(dev, root, None, mode, TRUE);
+ }
+
+ }
+}
+
+/**
+ * Focus moves from window @A to PointerRoot or to None.
+ * Assumption: @A is a valid window and not PointerRoot or None.
+ */
+static void
+CoreFocusToPointerRootOrNone(DeviceIntPtr dev,
+ WindowPtr A,
+ WindowPtr B, /* PointerRootWin or NoneWin */
+ int mode)
+{
+ WindowPtr root;
+ int i;
+ int nscreens = screenInfo.numScreens;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ nscreens = 1;
+#endif
+
+ if (!HasFocus(A))
+ {
+ WindowPtr child = FirstFocusChild(A);
+ if (child)
+ {
+ /* NotifyPointer P-A unless P is B or below*/
+ CoreFocusOutNotifyPointerEvents(dev, A, B, mode, FALSE);
+ CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A);
+ } else {
+ /* NotifyPointer P-A */
+ CoreFocusOutNotifyPointerEvents(dev, A, None, mode, FALSE);
+ CoreFocusEvent(dev, FocusOut, mode, NotifyNonlinear, A);
+ }
+ }
+
+ /* NullWindow means we include the root window */
+ CoreFocusOutEvents(dev, A, NullWindow, mode, NotifyNonlinearVirtual);
+
+ for (i = 0; i < nscreens; i++)
+ {
+ root = WindowTable[i];
+ if (!HasFocus(root) && !FirstFocusChild(root))
+ {
+ CoreFocusEvent(dev, FocusIn, mode, ((int)B) ? NotifyPointerRoot : NotifyDetailNone, root);
+ if (B == PointerRootWin)
+ CoreFocusInNotifyPointerEvents(dev, root, None, mode, TRUE);
+ }
+ }
+}
+
+/**
+ * Focus moves from PointerRoot or None to a window @to.
+ * Assumption: @to is a valid window and not PointerRoot or None.
+ */
+static void
+CoreFocusFromPointerRootOrNone(DeviceIntPtr dev,
+ WindowPtr A, /* PointerRootWin or NoneWin */
+ WindowPtr B,
+ int mode)
+{
+ WindowPtr root;
+ int i;
+ int nscreens = screenInfo.numScreens;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ nscreens = 1;
+#endif
+
+ for (i = 0; i < nscreens; i++)
+ {
+ root = WindowTable[i];
+ if (!HasFocus(root) && !FirstFocusChild(root))
+ {
+ /* If pointer was on PointerRootWin and changes to NoneWin, and
+ * the pointer paired with @dev is below the current root window,
+ * do a NotifyPointer run. */
+ if (dev->focus && dev->focus->win == PointerRootWin &&
+ B != PointerRootWin)
+ {
+ WindowPtr ptrwin = PointerWin(GetPairedDevice(dev));
+ if (ptrwin)
+ CoreFocusOutNotifyPointerEvents(dev, root, None, mode, TRUE);
+ }
+ CoreFocusEvent(dev, FocusOut, mode, ((int)A) ? NotifyPointerRoot : NotifyDetailNone, root);
+ }
+ }
+
+ root = B; /* get B's root window */
+ while(root->parent)
+ root = root->parent;
+
+ if (B != root)
+ {
+ CoreFocusEvent(dev, FocusIn, mode, NotifyNonlinearVirtual, root);
+ CoreFocusInEvents(dev, root, B, mode, NotifyNonlinearVirtual);
+ }
+
+
+ if (!HasFocus(B))
+ {
+ WindowPtr child = FirstFocusChild(B);
+ if (child)
+ {
+ CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B);
+ /* NotifyPointer B-P unless P is child or below. */
+ CoreFocusInNotifyPointerEvents(dev, B, child, mode, FALSE);
+ } else {
+ CoreFocusEvent(dev, FocusIn, mode, NotifyNonlinear, B);
+ /* NotifyPointer B-P unless P is child or below. */
+ CoreFocusInNotifyPointerEvents(dev, B, None, mode, FALSE);
+ }
+ }
+
+}
+
+static void
+CoreFocusEvents(DeviceIntPtr dev,
+ WindowPtr from,
+ WindowPtr to,
+ int mode)
+{
+ if (!dev->isMaster)
+ return;
+
+ SetFocusOut(dev, from);
+
+ if (((to == NullWindow) || (to == PointerRootWin)) &&
+ ((from == NullWindow) || (from == PointerRootWin)))
+ CoreFocusPointerRootNoneSwitch(dev, from, to, mode);
+ else if ((to == NullWindow) || (to == PointerRootWin))
+ CoreFocusToPointerRootOrNone(dev, from, to, mode);
+ else if ((from == NullWindow) || (from == PointerRootWin))
+ CoreFocusFromPointerRootOrNone(dev, from, to, mode);
+ else if (IsParent(from, to))
+ CoreFocusToDescendant(dev, from, to, mode);
+ else if (IsParent(to, from))
+ CoreFocusToAncestor(dev, from, to, mode);
+ else
+ CoreFocusNonLinear(dev, from, to, mode);
+
+ SetFocusIn(dev, to);
+}
+
+#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
+
+static void
+DeviceFocusEvents(DeviceIntPtr dev,
+ WindowPtr from,
+ WindowPtr to,
+ int mode)
+{
+ int out, in; /* for holding details for to/from
+ PointerRoot/None */
+ int i;
+ int nscreens = screenInfo.numScreens;
+ SpritePtr sprite = dev->spriteInfo->sprite;
+
+ if (from == to)
+ return;
+ out = (from == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ in = (to == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ nscreens = 1;
+#endif
+
+ if ((to == NullWindow) || (to == PointerRootWin))
+ {
+ if ((from == NullWindow) || (from == PointerRootWin))
+ {
+ if (from == PointerRootWin)
+ DeviceFocusOutEvents(dev, sprite->win, RootWindow(dev), mode,
+ NotifyPointer);
+ /* Notify all the roots */
+ for (i = 0; i < nscreens; i++)
+ DeviceFocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ }
+ else
+ {
+ if (IsParent(from, sprite->win))
+ DeviceFocusOutEvents(dev, sprite->win, from, mode,
+ NotifyPointer);
+ DeviceFocusEvent(dev, FocusOut, mode, NotifyNonlinear, from);
+ /* next call catches the root too, if the screen changed */
+ DeviceFocusOutEvents(dev, from->parent, NullWindow, mode,
+ NotifyNonlinearVirtual);
+ }
+ /* Notify all the roots */
+ for (i = 0; i < nscreens; i++)
+ DeviceFocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+ if (to == PointerRootWin)
+ DeviceFocusInEvents(dev, RootWindow(dev), sprite->win, mode, NotifyPointer);
+ }
+ else
+ {
+ if ((from == NullWindow) || (from == PointerRootWin))
+ {
+ if (from == PointerRootWin)
+ DeviceFocusOutEvents(dev, sprite->win, RootWindow(dev), mode,
+ NotifyPointer);
+ for (i = 0; i < nscreens; i++)
+ DeviceFocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ if (to->parent != NullWindow)
+ DeviceFocusInEvents(dev, RootWindow(dev), to, mode, NotifyNonlinearVirtual);
+ DeviceFocusEvent(dev, FocusIn, mode, NotifyNonlinear, to);
+ if (IsParent(to, sprite->win))
+ DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer);
+ }
+ else
+ {
+ if (IsParent(to, from))
+ {
+ DeviceFocusEvent(dev, FocusOut, mode, NotifyAncestor, from);
+ DeviceFocusOutEvents(dev, from->parent, to, mode,
+ NotifyVirtual);
+ DeviceFocusEvent(dev, FocusIn, mode, NotifyInferior, to);
+ if ((IsParent(to, sprite->win)) &&
+ (sprite->win != from) &&
+ (!IsParent(from, sprite->win)) &&
+ (!IsParent(sprite->win, from)))
+ DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer);
+ }
+ else
+ if (IsParent(from, to))
+ {
+ if ((IsParent(from, sprite->win)) &&
+ (sprite->win != from) &&
+ (!IsParent(to, sprite->win)) &&
+ (!IsParent(sprite->win, to)))
+ DeviceFocusOutEvents(dev, sprite->win, from, mode,
+ NotifyPointer);
+ DeviceFocusEvent(dev, FocusOut, mode, NotifyInferior, from);
+ DeviceFocusInEvents(dev, from, to, mode, NotifyVirtual);
+ DeviceFocusEvent(dev, FocusIn, mode, NotifyAncestor, to);
+ }
+ else
+ {
+ /* neither from or to is child of other */
+ WindowPtr common = CommonAncestor(to, from);
+ /* common == NullWindow ==> different screens */
+ if (IsParent(from, sprite->win))
+ DeviceFocusOutEvents(dev, sprite->win, from, mode,
+ NotifyPointer);
+ DeviceFocusEvent(dev, FocusOut, mode, NotifyNonlinear, from);
+ if (from->parent != NullWindow)
+ DeviceFocusOutEvents(dev, from->parent, common, mode,
+ NotifyNonlinearVirtual);
+ if (to->parent != NullWindow)
+ DeviceFocusInEvents(dev, common, to, mode, NotifyNonlinearVirtual);
+ DeviceFocusEvent(dev, FocusIn, mode, NotifyNonlinear, to);
+ if (IsParent(to, sprite->win))
+ DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer);
+ }
+ }
+ }
+}
+
+/**
+ * Figure out if focus events are necessary and send them to the
+ * appropriate windows.
+ *
+ * @param from Window the focus moved out of.
+ * @param to Window the focus moved into.
+ */
+void
+DoFocusEvents(DeviceIntPtr pDev,
+ WindowPtr from,
+ WindowPtr to,
+ int mode)
+{
+ if (!IsKeyboardDevice(pDev))
+ return;
+
+ if (from == to)
+ return;
+
+ CoreFocusEvents(pDev, from, to, mode);
+ DeviceFocusEvents(pDev, from, to, mode);
+}
diff --git a/xorg-server/dix/enterleave.h b/xorg-server/dix/enterleave.h
new file mode 100644
index 000000000..edca38664
--- /dev/null
+++ b/xorg-server/dix/enterleave.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Peter Hutterer
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef ENTERLEAVE_H
+#define ENTERLEAVE_H
+
+extern void DoEnterLeaveEvents(
+ DeviceIntPtr pDev,
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode
+);
+
+extern void DoFocusEvents(
+ DeviceIntPtr pDev,
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode
+);
+
+extern void EnterLeaveEvent(
+ DeviceIntPtr mouse,
+ int type,
+ int mode,
+ int detail,
+ WindowPtr pWin,
+ Window child);
+
+extern WindowPtr CommonAncestor(
+ WindowPtr a,
+ WindowPtr b);
+
+extern void CoreEnterLeaveEvent(DeviceIntPtr mouse,
+ int type,
+ int mode,
+ int detail,
+ WindowPtr pWin,
+ Window child);
+extern void DeviceEnterLeaveEvent(DeviceIntPtr mouse,
+ int type,
+ int mode,
+ int detail,
+ WindowPtr pWin,
+ Window child);
+
+extern void EnterWindow(DeviceIntPtr dev,
+ WindowPtr win,
+ int mode);
+
+
+extern void CoreFocusEvent(DeviceIntPtr kbd,
+ int type,
+ int mode,
+ int detail,
+ WindowPtr pWin);
+
+extern void DeviceFocusEvent(DeviceIntPtr kbd,
+ int type,
+ int mode,
+ int detail,
+ WindowPtr pWin);
+
+extern void SetFocusIn(DeviceIntPtr kbd,
+ WindowPtr win);
+
+extern void SetFocusOut(DeviceIntPtr dev,
+ WindowPtr win);
+#endif /* _ENTERLEAVE_H_ */
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c
index 4a8e480c8..f15c46090 100644
--- a/xorg-server/dix/events.c
+++ b/xorg-server/dix/events.c
@@ -27,13 +27,13 @@ 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,
+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
+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.
+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
@@ -149,20 +149,8 @@ typedef const char *string;
#include "Xserver-dtrace.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;
-#endif
-
#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI.h>
#include "exglobals.h"
#include "exevents.h"
#include "exglobals.h"
@@ -171,11 +159,16 @@ int xeviegrabState = 0;
#include "dixevents.h"
#include "dixgrabs.h"
#include "dispatch.h"
+
+#include <X11/extensions/ge.h>
+#include "geext.h"
+#include "geint.h"
+
+#include "enterleave.h"
+
/**
* Extension events type numbering starts at EXTENSION_EVENT_BASE.
*/
-#define EXTENSION_EVENT_BASE 64
-
#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
#define AllButtonsMask ( \
@@ -196,6 +189,12 @@ int xeviegrabState = 0;
ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
Mod3Mask | Mod4Mask | Mod5Mask )
#define AllEventMasks (lastEventMask|(lastEventMask-1))
+
+/**
+ * Used to indicate a implicit passive grab created by a ButtonPress event.
+ * See DeliverEventsToWindow().
+ */
+#define ImplicitGrabMask (1 << 7)
/*
* 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.
@@ -219,21 +218,21 @@ _X_EXPORT CallbackListPtr DeviceEventCallback;
Mask DontPropagateMasks[DNPMCOUNT];
static int DontPropagateRefCnts[DNPMCOUNT];
+
/**
- * Main input device struct.
- * inputInfo.pointer
+ * Main input device struct.
+ * inputInfo.pointer
* is the core pointer. Referred to as "virtual core pointer", "VCP",
* "core pointer" or inputInfo.pointer. There is exactly one core pointer,
- * but multiple devices may send core events. If a device generates core
- * events, those events will appear to originate from the core pointer.
- *
+ * but multiple devices may send core events. The VCP is the first master
+ * pointer device and cannot be deleted.
+ *
* inputInfo.keyboard
* is the core keyboard ("virtual core keyboard", "VCK", "core keyboard").
* See inputInfo.pointer.
- *
+ *
* inputInfo.devices
- * linked list containing all devices including VCK and VCP. The VCK will
- * always be the first entry, the VCP the second entry in the device list.
+ * linked list containing all devices including VCP and VCK.
*
* inputInfo.off_devices
* Devices that have not been initialized and are thus turned off.
@@ -243,6 +242,24 @@ static int DontPropagateRefCnts[DNPMCOUNT];
*/
_X_EXPORT InputInfo inputInfo;
+/**
+ * syncEvents is the global structure for queued events.
+ * Devices can be frozen through GrabModeSync pointer grabs. If this is the
+ * case, events from these devices are added to "pending" instead of being
+ * processed normally. When the device is unfrozen, events in "pending" are
+ * replayed and processed as if they would come from the device directly.
+ *
+ * pending ... list of queued events
+ * pendtail ... last event in list
+ * replayDev ... The device to replay events for. Only set in AllowEvents, in
+ * which case it is set to the device specified in the request.
+ * replayWin ... the window the events are supposed to be replayed on. This
+ * window may be set to the grab's window (but only when
+ * Replay{Pointer|Keyboard} is given in the XAllowEvents
+ * request.
+ * playingEvents ... flag to indicate whether we're in the process of
+ * replaying events. Only set in ComputeFreezes().
+ */
static struct {
QdEventPtr pending, *pendtail;
DeviceIntPtr replayDev; /* kludgy rock to put flag for */
@@ -251,55 +268,68 @@ static struct {
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.
- *
- * @see XYToWindow() for a documentation on how the array is set up.
+#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
+
+static xEvent* swapEvent = NULL;
+static int swapEventLen = 0;
+
+/**
+ * Convert the given event type from an XI event to a core event.
+ * @return The matching core event type or 0 if there is none.
*/
-static WindowPtr *spriteTrace = (WindowPtr *)NULL;
-#define ROOT spriteTrace[0]
-static int spriteTraceSize = 0;
-static int spriteTraceGood;
+_X_EXPORT int
+XItoCoreType(int xitype)
+{
+ int coretype = 0;
+ if (xitype == DeviceMotionNotify)
+ coretype = MotionNotify;
+ else if (xitype == DeviceButtonPress)
+ coretype = ButtonPress;
+ else if (xitype == DeviceButtonRelease)
+ coretype = ButtonRelease;
+ else if (xitype == DeviceKeyPress)
+ coretype = KeyPress;
+ else if (xitype == DeviceKeyRelease)
+ coretype = KeyRelease;
+
+ return coretype;
+}
/**
- * DIX sprite information. This is the sprite as seen from the DIX. It does
- * not represent the actual sprite rendered to the screen.
- *
+ * True if device owns a cursor, false if device shares a cursor sprite with
+ * another device.
*/
-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 */
+_X_EXPORT Bool
+DevHasCursor(DeviceIntPtr pDev)
+{
+ return pDev->spriteInfo->spriteOwner;
+}
-#ifdef XEVIE
-_X_EXPORT WindowPtr xeviewin;
-_X_EXPORT HotSpot xeviehot;
-#endif
+/*
+ * Return true if a device is a pointer, check is the same as used by XI to
+ * fill the 'use' field.
+ */
+_X_EXPORT Bool
+IsPointerDevice(DeviceIntPtr dev)
+{
+ return (dev->valuator && dev->button);
+}
-static void DoEnterLeaveEvents(
- WindowPtr fromWin,
- WindowPtr toWin,
- int mode
-);
+/*
+ * Return true if a device is a keyboard, check is the same as used by XI to
+ * fill the 'use' field.
+ *
+ * Some pointer devices have keys as well (e.g. multimedia keys). Try to not
+ * count them as keyboard devices.
+ */
+_X_EXPORT Bool
+IsKeyboardDevice(DeviceIntPtr dev)
+{
+ return (dev->key && dev->kbdfeed) && !IsPointerDevice(dev);
+}
static WindowPtr XYToWindow(
+ DeviceIntPtr pDev,
int x,
int y
);
@@ -311,12 +341,14 @@ extern int lastEvent;
static Mask lastEventMask;
-#ifdef XINPUT
extern int DeviceMotionNotify;
-#endif
+/**
+ * Event filters. One set of filters for each device, but only the first layer
+ * is initialized. The rest is memcpy'd in InitEvents.
+ */
#define CantBeFiltered NoEventMask
-static Mask filters[128] =
+static Mask filters[MAXDEVICES][128] = {
{
NoSuchEvent, /* 0 */
NoSuchEvent, /* 1 */
@@ -353,48 +385,57 @@ static Mask filters[128] =
ColormapChangeMask, /* ColormapNotify */
CantBeFiltered, /* ClientMessage */
CantBeFiltered /* MappingNotify */
-};
+}};
+
+
+/**
+ * same principle as filters, but one set of filters for each extension.
+ * The extension is responsible for setting the filters by calling
+ * SetGenericFilter().
+ */
+static Mask* generic_filters[MAXEXTENSIONS];
static CARD8 criticalEvents[32] =
{
- 0x7c /* key and button events */
+ 0x7c, 0x30, 0x40 /* key, button, expose, and configure events */
};
#ifdef PANORAMIX
-static void ConfineToShape(RegionPtr shape, int *px, int *py);
-static void PostNewCursor(void);
+static void PostNewCursor(DeviceIntPtr pDev);
-#define SyntheticMotion(x, y) \
- PostSyntheticMotion(x, y, noPanoramiXExtension ? 0 : \
- sprite.screen->myNum, \
+#define SyntheticMotion(dev, x, y) \
+ PostSyntheticMotion(dev, x, y, noPanoramiXExtension ? 0 : \
+ dev->spriteInfo->sprite->screen->myNum, \
syncEvents.playingEvents ? \
syncEvents.time.milliseconds : \
currentTime.milliseconds);
static Bool
XineramaSetCursorPosition(
- int x,
- int y,
+ DeviceIntPtr pDev,
+ int x,
+ int y,
Bool generateEvent
){
ScreenPtr pScreen;
BoxRec box;
int i;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
/* x,y are in Screen 0 coordinates. We need to decide what Screen
- to send the message too and what the coordinates relative to
+ to send the message too and what the coordinates relative to
that screen are. */
- pScreen = sprite.screen;
+ pScreen = pSprite->screen;
x += panoramiXdataPtr[0].x;
y += panoramiXdataPtr[0].y;
if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
- x, y, &box))
+ x, y, &box))
{
- FOR_NSCREENS(i)
+ FOR_NSCREENS(i)
{
- if(i == pScreen->myNum)
+ if(i == pScreen->myNum)
continue;
if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
{
@@ -404,21 +445,25 @@ XineramaSetCursorPosition(
}
}
- sprite.screen = pScreen;
- sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
- sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+ pSprite->screen = pScreen;
+ pSprite->hotPhys.x = x - panoramiXdataPtr[0].x;
+ pSprite->hotPhys.y = y - panoramiXdataPtr[0].y;
x -= panoramiXdataPtr[pScreen->myNum].x;
y -= panoramiXdataPtr[pScreen->myNum].y;
- return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+ return (*pScreen->SetCursorPosition)(pDev, pScreen, x, y, generateEvent);
}
static void
-XineramaConstrainCursor(void)
+XineramaConstrainCursor(DeviceIntPtr pDev)
{
- ScreenPtr pScreen = sprite.screen;
- BoxRec newBox = sprite.physLimits;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ ScreenPtr pScreen;
+ BoxRec newBox;
+
+ pScreen = pSprite->screen;
+ newBox = pSprite->physLimits;
/* Translate the constraining box to the screen
the sprite is actually on */
@@ -427,56 +472,60 @@ XineramaConstrainCursor(void)
newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
- (* pScreen->ConstrainCursor)(pScreen, &newBox);
+ (* pScreen->ConstrainCursor)(pDev, pScreen, &newBox);
}
static void
XineramaCheckPhysLimits(
+ DeviceIntPtr pDev,
CursorPtr cursor,
Bool generateEvents
){
HotSpot new;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
if (!cursor)
return;
-
- new = sprite.hotPhys;
+
+ new = pSprite->hotPhys;
/* I don't care what the DDX has to say about it */
- sprite.physLimits = sprite.hotLimits;
+ pSprite->physLimits = pSprite->hotLimits;
/* constrain the pointer to those limits */
- if (new.x < sprite.physLimits.x1)
- new.x = sprite.physLimits.x1;
+ if (new.x < pSprite->physLimits.x1)
+ new.x = pSprite->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;
+ if (new.x >= pSprite->physLimits.x2)
+ new.x = pSprite->physLimits.x2 - 1;
+ if (new.y < pSprite->physLimits.y1)
+ new.y = pSprite->physLimits.y1;
else
- if (new.y >= sprite.physLimits.y2)
- new.y = sprite.physLimits.y2 - 1;
+ if (new.y >= pSprite->physLimits.y2)
+ new.y = pSprite->physLimits.y2 - 1;
- if (sprite.hotShape) /* more work if the shape is a mess */
- ConfineToShape(sprite.hotShape, &new.x, &new.y);
+ if (pSprite->hotShape) /* more work if the shape is a mess */
+ ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y);
- if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ if((new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y))
{
- XineramaSetCursorPosition (new.x, new.y, generateEvents);
+ XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents);
if (!generateEvents)
- SyntheticMotion(new.x, new.y);
+ SyntheticMotion(pDev, new.x, new.y);
}
/* Tell DDX what the limits are */
- XineramaConstrainCursor();
+ XineramaConstrainCursor(pDev);
}
static Bool
-XineramaSetWindowPntrs(WindowPtr pWin)
+XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin)
{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
if(pWin == WindowTable[0]) {
- memcpy(sprite.windows, WindowTable,
+ memcpy(pSprite->windows, WindowTable,
PanoramiXNumScreens*sizeof(WindowPtr));
} else {
PanoramiXRes *win;
@@ -488,8 +537,8 @@ XineramaSetWindowPntrs(WindowPtr pWin)
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 */
+ pSprite->windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+ if(!pSprite->windows[i]) /* window is being unmapped */
return FALSE;
}
}
@@ -498,16 +547,18 @@ XineramaSetWindowPntrs(WindowPtr pWin)
static void
XineramaCheckVirtualMotion(
+ DeviceIntPtr pDev,
QdEventPtr qe,
- WindowPtr pWin
-){
+ WindowPtr pWin)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
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 :
+ pSprite->hot.pScreen = qe->pScreen; /* should always be Screen 0 */
+ pSprite->hot.x = qe->event->u.keyButtonPointer.rootX;
+ pSprite->hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo :
NullWindow;
}
if (pWin)
@@ -515,13 +566,13 @@ XineramaCheckVirtualMotion(
int x, y, off_x, off_y, i;
BoxRec lims;
- if(!XineramaSetWindowPntrs(pWin))
+ if(!XineramaSetWindowPntrs(pDev, pWin))
return;
i = PanoramiXNumScreens - 1;
-
- REGION_COPY(sprite.screen, &sprite.Reg2,
- &sprite.windows[i]->borderSize);
+
+ REGION_COPY(pSprite->screen, &pSprite->Reg2,
+ &pSprite->windows[i]->borderSize);
off_x = panoramiXdataPtr[i].x;
off_y = panoramiXdataPtr[i].y;
@@ -530,97 +581,110 @@ XineramaCheckVirtualMotion(
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);
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, x, y);
+
+ REGION_UNION(pSprite->screen, &pSprite->Reg2, &pSprite->Reg2,
+ &pSprite->windows[i]->borderSize);
off_x = panoramiXdataPtr[i].x;
off_y = panoramiXdataPtr[i].y;
}
- lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+ lims = *REGION_EXTENTS(pSprite->screen, &pSprite->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 (pSprite->hot.x < lims.x1)
+ pSprite->hot.x = lims.x1;
+ else if (pSprite->hot.x >= lims.x2)
+ pSprite->hot.x = lims.x2 - 1;
+ if (pSprite->hot.y < lims.y1)
+ pSprite->hot.y = lims.y1;
+ else if (pSprite->hot.y >= lims.y2)
+ pSprite->hot.y = lims.y2 - 1;
- if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
- ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+ if (REGION_NUM_RECTS(&pSprite->Reg2) > 1)
+ ConfineToShape(pDev, &pSprite->Reg2,
+ &pSprite->hot.x, &pSprite->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;
+ qe->pScreen = pSprite->hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = pSprite->hot.x;
+ qe->event->u.keyButtonPointer.rootY = pSprite->hot.y;
}
}
-#ifdef XEVIE
- xeviehot.x = sprite.hot.x;
- xeviehot.y = sprite.hot.y;
-#endif
}
static Bool
-XineramaCheckMotion(xEvent *xE)
+XineramaCheckMotion(xEvent *xE, DeviceIntPtr pDev)
{
- WindowPtr prevSpriteWin = sprite.win;
+ WindowPtr prevSpriteWin;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ prevSpriteWin = pSprite->win;
if (xE && !syncEvents.playingEvents)
{
+ /* GetPointerEvents() guarantees that pointer events have the correct
+ rootX/Y set already. */
+ switch(xE->u.u.type)
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ break;
+ default:
+ if (xE->u.u.type == DeviceButtonPress ||
+ xE->u.u.type == DeviceButtonRelease ||
+ xE->u.u.type == DeviceMotionNotify)
+ break;
+ /* all other events return FALSE */
+ return FALSE;
+ }
+
/* Motion events entering DIX get translated to Screen 0
- coordinates. Replayed events have already been
+ coordinates. Replayed events have already been
translated since they've entered DIX before */
- XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ XE_KBPTR.rootX += panoramiXdataPtr[pSprite->screen->myNum].x -
panoramiXdataPtr[0].x;
- XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ XE_KBPTR.rootY += panoramiXdataPtr[pSprite->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))
+ pSprite->hot.x = XE_KBPTR.rootX;
+ pSprite->hot.y = XE_KBPTR.rootY;
+ if (pSprite->hot.x < pSprite->physLimits.x1)
+ pSprite->hot.x = pSprite->physLimits.x1;
+ else if (pSprite->hot.x >= pSprite->physLimits.x2)
+ pSprite->hot.x = pSprite->physLimits.x2 - 1;
+ if (pSprite->hot.y < pSprite->physLimits.y1)
+ pSprite->hot.y = pSprite->physLimits.y1;
+ else if (pSprite->hot.y >= pSprite->physLimits.y2)
+ pSprite->hot.y = pSprite->physLimits.y2 - 1;
+
+ if (pSprite->hotShape)
+ ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y);
+
+ pSprite->hotPhys = pSprite->hot;
+ if ((pSprite->hotPhys.x != XE_KBPTR.rootX) ||
+ (pSprite->hotPhys.y != XE_KBPTR.rootY))
{
XineramaSetCursorPosition(
- sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ pDev, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE);
}
- XE_KBPTR.rootX = sprite.hot.x;
- XE_KBPTR.rootY = sprite.hot.y;
+ XE_KBPTR.rootX = pSprite->hot.x;
+ XE_KBPTR.rootY = pSprite->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);
+ pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
- if (sprite.win != prevSpriteWin)
+ if (pSprite->win != prevSpriteWin)
{
if (prevSpriteWin != NullWindow) {
if (!xE)
UpdateCurrentTimeIf();
- DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
- }
- PostNewCursor();
+ DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win,
+ NotifyNormal);
+ }
+ PostNewCursor(pDev);
return FALSE;
}
return TRUE;
@@ -628,25 +692,28 @@ XineramaCheckMotion(xEvent *xE)
static void
-XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+XineramaConfineCursorToWindow(DeviceIntPtr pDev,
+ WindowPtr pWin,
+ Bool generateEvents)
{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
if (syncEvents.playingEvents)
{
- XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
- SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ XineramaCheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin);
+ SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y);
}
else
{
int x, y, off_x, off_y, i;
- if(!XineramaSetWindowPntrs(pWin))
+ if(!XineramaSetWindowPntrs(pDev, pWin))
return;
i = PanoramiXNumScreens - 1;
-
- REGION_COPY(sprite.screen, &sprite.Reg1,
- &sprite.windows[i]->borderSize);
+
+ REGION_COPY(pSprite->screen, &pSprite->Reg1,
+ &pSprite->windows[i]->borderSize);
off_x = panoramiXdataPtr[i].x;
off_y = panoramiXdataPtr[i].y;
@@ -655,48 +722,51 @@ XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
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);
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y);
+
+ REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1,
+ &pSprite->windows[i]->borderSize);
off_x = panoramiXdataPtr[i].x;
off_y = panoramiXdataPtr[i].y;
}
- sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+ pSprite->hotLimits = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg1);
- if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
- sprite.hotShape = &sprite.Reg1;
+ if(REGION_NUM_RECTS(&pSprite->Reg1) > 1)
+ pSprite->hotShape = &pSprite->Reg1;
else
- sprite.hotShape = NullRegion;
-
- sprite.confined = FALSE;
- sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+ pSprite->hotShape = NullRegion;
+
+ pSprite->confined = FALSE;
+ pSprite->confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
- XineramaCheckPhysLimits(sprite.current, generateEvents);
+ XineramaCheckPhysLimits(pDev, pSprite->current,
+ generateEvents);
}
}
static void
-XineramaChangeToCursor(CursorPtr cursor)
+XineramaChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
{
- if (cursor != sprite.current)
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ if (cursor != pSprite->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++;
+ if ((pSprite->current->bits->xhot != cursor->bits->xhot) ||
+ (pSprite->current->bits->yhot != cursor->bits->yhot))
+ XineramaCheckPhysLimits(pDev, cursor, FALSE);
+ (*pSprite->screen->DisplayCursor)(pDev, pSprite->screen, cursor);
+ FreeCursor(pSprite->current, (Cursor)0);
+ pSprite->current = cursor;
+ pSprite->current->refcnt++;
}
}
#else
-#define SyntheticMotion(x, y) \
- PostSyntheticMotion(x, y, \
+#define SyntheticMotion(dev, x, y) \
+ PostSyntheticMotion(dev, x, y, \
0, \
syncEvents.playingEvents ? \
syncEvents.time.milliseconds : \
@@ -705,11 +775,19 @@ XineramaChangeToCursor(CursorPtr cursor)
#endif /* PANORAMIX */
void
-SetMaskForEvent(Mask mask, int event)
+SetMaskForEvent(int deviceid, Mask mask, int event)
{
+ int coretype;
+ if (deviceid < 0 || deviceid >= MAXDEVICES)
+ FatalError("SetMaskForEvent: bogus device id");
if ((event < LASTEvent) || (event >= 128))
FatalError("SetMaskForEvent: bogus event number");
- filters[event] = mask;
+ filters[deviceid][event] = mask;
+
+ /* Need to change the mask for the core events too */
+ coretype = XItoCoreType(event);
+ if (coretype)
+ filters[deviceid][coretype] = mask;
}
_X_EXPORT void
@@ -720,17 +798,18 @@ SetCriticalEvent(int event)
criticalEvents[event >> 3] |= 1 << (event & 7);
}
-#ifdef SHAPE
-static void
-ConfineToShape(RegionPtr shape, int *px, int *py)
+void
+ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py)
{
BoxRec box;
int x = *px, y = *py;
int incx = 1, incy = 1;
+ SpritePtr pSprite;
- if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+ pSprite = pDev->spriteInfo->sprite;
+ if (POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box))
return;
- box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+ box = *REGION_EXTENTS(pSprite->hot.pScreen, shape);
/* this is rather crude */
do {
x += incx;
@@ -752,145 +831,141 @@ ConfineToShape(RegionPtr shape, int *px, int *py)
else if (y < box.y1)
return; /* should never get here! */
}
- } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+ } while (!POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box));
*px = x;
*py = y;
}
-#endif
static void
CheckPhysLimits(
+ DeviceIntPtr pDev,
CursorPtr cursor,
Bool generateEvents,
Bool confineToScreen,
ScreenPtr pScreen)
{
HotSpot new;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
if (!cursor)
return;
- new = sprite.hotPhys;
+ new = pSprite->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;
+ (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits,
+ &pSprite->physLimits);
+ pSprite->confined = confineToScreen;
+ (* pScreen->ConstrainCursor)(pDev, pScreen, &pSprite->physLimits);
+ if (new.x < pSprite->physLimits.x1)
+ new.x = pSprite->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;
+ if (new.x >= pSprite->physLimits.x2)
+ new.x = pSprite->physLimits.x2 - 1;
+ if (new.y < pSprite->physLimits.y1)
+ new.y = pSprite->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);
+ if (new.y >= pSprite->physLimits.y2)
+ new.y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y);
+ if ((pScreen != pSprite->hotPhys.pScreen) ||
+ (new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y))
+ {
+ if (pScreen != pSprite->hotPhys.pScreen)
+ pSprite->hotPhys = new;
+ (*pScreen->SetCursorPosition)
+ (pDev, pScreen, new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(pDev, new.x, new.y);
}
}
static void
CheckVirtualMotion(
+ DeviceIntPtr pDev,
QdEventPtr qe,
WindowPtr pWin)
{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
#ifdef PANORAMIX
if(!noPanoramiXExtension) {
- XineramaCheckVirtualMotion(qe, pWin);
+ XineramaCheckVirtualMotion(pDev, 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;
+ pSprite->hot.pScreen = qe->pScreen;
+ pSprite->hot.x = qe->event->u.keyButtonPointer.rootX;
+ pSprite->hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : NullWindow;
}
if (pWin)
{
BoxRec lims;
- if (sprite.hot.pScreen != pWin->drawable.pScreen)
+ if (pSprite->hot.pScreen != pWin->drawable.pScreen)
{
- sprite.hot.pScreen = pWin->drawable.pScreen;
- sprite.hot.x = sprite.hot.y = 0;
+ pSprite->hot.pScreen = pWin->drawable.pScreen;
+ pSprite->hot.x = pSprite->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 (pSprite->hot.x < lims.x1)
+ pSprite->hot.x = lims.x1;
+ else if (pSprite->hot.x >= lims.x2)
+ pSprite->hot.x = lims.x2 - 1;
+ if (pSprite->hot.y < lims.y1)
+ pSprite->hot.y = lims.y1;
+ else if (pSprite->hot.y >= lims.y2)
+ pSprite->hot.y = lims.y2 - 1;
if (wBoundingShape(pWin))
- ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
-#endif
+ ConfineToShape(pDev, &pWin->borderSize,
+ &pSprite->hot.x, &pSprite->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;
+ qe->pScreen = pSprite->hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = pSprite->hot.x;
+ qe->event->u.keyButtonPointer.rootY = pSprite->hot.y;
}
}
-#ifdef XEVIE
- xeviehot.x = sprite.hot.x;
- xeviehot.y = sprite.hot.y;
-#endif
- ROOT = WindowTable[sprite.hot.pScreen->myNum];
+ RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum];
}
static void
-ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
#ifdef PANORAMIX
if(!noPanoramiXExtension) {
- XineramaConfineCursorToWindow(pWin, generateEvents);
+ XineramaConfineCursorToWindow(pDev, pWin, generateEvents);
return;
- }
+ }
#endif
if (syncEvents.playingEvents)
{
- CheckVirtualMotion((QdEventPtr)NULL, pWin);
- SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ CheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin);
+ SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y);
}
else
{
- sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
-#ifdef SHAPE
- sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+ pSprite->hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+ pSprite->hotShape = wBoundingShape(pWin) ? &pWin->borderSize
: NullRegion;
-#endif
- CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
- pScreen);
+ CheckPhysLimits(pDev, pSprite->current, generateEvents,
+ confineToScreen, pScreen);
}
}
_X_EXPORT Bool
-PointerConfinedToScreen(void)
+PointerConfinedToScreen(DeviceIntPtr pDev)
{
- return sprite.confined;
+ return pDev->spriteInfo->sprite->confined;
}
/**
@@ -901,31 +976,34 @@ PointerConfinedToScreen(void)
* happens.
*/
static void
-ChangeToCursor(CursorPtr cursor)
+ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
#ifdef PANORAMIX
if(!noPanoramiXExtension) {
- XineramaChangeToCursor(cursor);
+ XineramaChangeToCursor(pDev, cursor);
return;
}
#endif
- if (cursor != sprite.current)
+ if (cursor != pSprite->current)
{
- if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
- (sprite.current->bits->yhot != cursor->bits->yhot))
- CheckPhysLimits(cursor, FALSE, sprite.confined,
+ if ((pSprite->current->bits->xhot != cursor->bits->xhot) ||
+ (pSprite->current->bits->yhot != cursor->bits->yhot))
+ CheckPhysLimits(pDev, cursor, FALSE, pSprite->confined,
(ScreenPtr)NULL);
- (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
- cursor);
- FreeCursor(sprite.current, (Cursor)0);
- sprite.current = cursor;
- sprite.current->refcnt++;
+ (*pSprite->hotPhys.pScreen->DisplayCursor) (pDev,
+ pSprite->hotPhys.pScreen,
+ cursor);
+ FreeCursor(pSprite->current, (Cursor)0);
+ pSprite->current = cursor;
+ pSprite->current->refcnt++;
}
}
/**
- * @returns true if b is a descendent of a
+ * @returns true if b is a descendent of a
*/
Bool
IsParent(WindowPtr a, WindowPtr b)
@@ -938,13 +1016,15 @@ IsParent(WindowPtr a, WindowPtr b)
/**
* Update the cursor displayed on the screen.
*
- * Called whenever a cursor may have changed shape or position.
+ * Called whenever a cursor may have changed shape or position.
*/
static void
-PostNewCursor(void)
+PostNewCursor(DeviceIntPtr pDev)
{
WindowPtr win;
- GrabPtr grab = inputInfo.pointer->grab;
+ GrabPtr grab = pDev->deviceGrab.grab;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ CursorPtr pCursor;
if (syncEvents.playingEvents)
return;
@@ -952,67 +1032,78 @@ PostNewCursor(void)
{
if (grab->cursor)
{
- ChangeToCursor(grab->cursor);
+ ChangeToCursor(pDev, grab->cursor);
return;
}
- if (IsParent(grab->window, sprite.win))
- win = sprite.win;
+ if (IsParent(grab->window, pSprite->win))
+ win = pSprite->win;
else
win = grab->window;
}
else
- win = sprite.win;
+ win = pSprite->win;
for (; win; win = win->parent)
- if (win->optional && win->optional->cursor != NullCursor)
- {
- ChangeToCursor(win->optional->cursor);
- return;
+ {
+ if (win->optional)
+ {
+ pCursor = WindowGetDeviceCursor(win, pDev);
+ if (!pCursor && win->optional->cursor != NullCursor)
+ pCursor = win->optional->cursor;
+ if (pCursor)
+ {
+ ChangeToCursor(pDev, pCursor);
+ return;
+ }
}
+ }
}
+
/**
- * @return root window of current active screen.
+ * @param dev device which you want to know its current root window
+ * @return root window where dev's sprite is located
*/
_X_EXPORT WindowPtr
-GetCurrentRootWindow(void)
+GetCurrentRootWindow(DeviceIntPtr dev)
{
- return ROOT;
+ return RootWindow(dev);
}
/**
* @return window underneath the cursor sprite.
*/
_X_EXPORT WindowPtr
-GetSpriteWindow(void)
+GetSpriteWindow(DeviceIntPtr pDev)
{
- return sprite.win;
+ return pDev->spriteInfo->sprite->win;
}
/**
* @return current sprite cursor.
*/
_X_EXPORT CursorPtr
-GetSpriteCursor(void)
+GetSpriteCursor(DeviceIntPtr pDev)
{
- return sprite.current;
+ return pDev->spriteInfo->sprite->current;
}
/**
* Set x/y current sprite position in screen coordinates.
*/
_X_EXPORT void
-GetSpritePosition(int *px, int *py)
+GetSpritePosition(DeviceIntPtr pDev, int *px, int *py)
{
- *px = sprite.hotPhys.x;
- *py = sprite.hotPhys.y;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ *px = pSprite->hotPhys.x;
+ *py = pSprite->hotPhys.y;
}
#ifdef PANORAMIX
_X_EXPORT int
-XineramaGetCursorScreen(void)
+XineramaGetCursorScreen(DeviceIntPtr pDev)
{
if(!noPanoramiXExtension) {
- return sprite.screen->myNum;
+ return pDev->spriteInfo->sprite->screen->myNum;
} else {
return 0;
}
@@ -1051,18 +1142,25 @@ NoticeEventTime(xEvent *xE)
* The following procedures deal with synchronous events *
**************************************************************************/
+/**
+ * EnqueueEvent is a device's processInputProc if a device is frozen.
+ * Instead of delivering the events to the client, the event is tacked onto a
+ * linked list for later delivery.
+ */
void
EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
{
- QdEventPtr tail = *syncEvents.pendtail;
- QdEventPtr qe;
- xEvent *qxE;
+ QdEventPtr tail = *syncEvents.pendtail;
+ QdEventPtr qe;
+ SpritePtr pSprite = device->spriteInfo->sprite;
+ int eventlen;
+
NoticeTime(xE);
#ifdef XKB
/* Fix for key repeating bug. */
- if (device->key != NULL && device->key->xkbInfo != NULL &&
+ if (device->key != NULL && device->key->xkbInfo != NULL &&
xE->u.u.type == KeyRelease)
AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
#endif
@@ -1079,89 +1177,126 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
* the data that GetCurrentRootWindow relies on hasn't been
* updated yet.
*/
- if (xE->u.u.type == MotionNotify)
+ if (xE->u.u.type == DeviceMotionNotify)
XE_KBPTR.root =
- WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id;
eventinfo.events = xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
}
- if (xE->u.u.type == MotionNotify)
+ if (xE->u.u.type == DeviceMotionNotify)
{
#ifdef PANORAMIX
if(!noPanoramiXExtension) {
- XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ XE_KBPTR.rootX += panoramiXdataPtr[pSprite->screen->myNum].x -
panoramiXdataPtr[0].x;
- XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ XE_KBPTR.rootY += panoramiXdataPtr[pSprite->screen->myNum].y -
panoramiXdataPtr[0].y;
}
#endif
- sprite.hotPhys.x = XE_KBPTR.rootX;
- sprite.hotPhys.y = XE_KBPTR.rootY;
+ pSprite->hotPhys.x = XE_KBPTR.rootX;
+ pSprite->hotPhys.y = XE_KBPTR.rootY;
/* do motion compression, but not if from different devices */
if (tail &&
- (tail->event->u.u.type == MotionNotify) &&
+ (tail->event->u.u.type == DeviceMotionNotify) &&
(tail->device == device) &&
- (tail->pScreen == sprite.hotPhys.pScreen))
+ (tail->pScreen == pSprite->hotPhys.pScreen))
{
- tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
- tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+ tail->event->u.keyButtonPointer.rootX = pSprite->hotPhys.x;
+ tail->event->u.keyButtonPointer.rootY = pSprite->hotPhys.y;
tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
tail->months = currentTime.months;
return;
}
}
- qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+
+ eventlen = count * sizeof(xEvent);
+ if (xE->u.u.type == GenericEvent) /* count is 1 for GenericEvents */
+ eventlen += ((xGenericEvent*)xE)->length * 4;
+
+ qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + eventlen);
if (!qe)
return;
qe->next = (QdEventPtr)NULL;
qe->device = device;
- qe->pScreen = sprite.hotPhys.pScreen;
+ qe->pScreen = pSprite->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 (xE->u.u.type == GenericEvent)
+ {
+ memcpy(qe->event, xE, eventlen);
+ } else
+ {
+ xEvent *qxE;
+ for (qxE = qe->event; --count >= 0; qxE++, xE++)
+ {
+ *qxE = *xE;
+ }
+ }
if (tail)
syncEvents.pendtail = &tail->next;
*syncEvents.pendtail = qe;
}
+/**
+ * Run through the list of events queued up in syncEvents.
+ * For each event do:
+ * If the device for this event is not frozen anymore, take it and process it
+ * as usually.
+ * After that, check if there's any devices in the list that are not frozen.
+ * If there is none, we're done. If there is at least one device that is not
+ * frozen, then re-run from the beginning of the event queue.
+ */
static void
PlayReleasedEvents(void)
{
QdEventPtr *prev, qe;
DeviceIntPtr dev;
+ DeviceIntPtr pDev;
+ static CARD32 lastKnownMillis = 0; /* Hack, see comment below */
prev = &syncEvents.pending;
while ( (qe = *prev) )
{
- if (!qe->device->sync.frozen)
+ if (!qe->device->deviceGrab.sync.frozen)
{
*prev = qe->next;
+ pDev = qe->device;
if (*syncEvents.pendtail == *prev)
syncEvents.pendtail = prev;
- if (qe->event->u.u.type == MotionNotify)
- CheckVirtualMotion(qe, NullWindow);
+ if (qe->event->u.u.type == DeviceMotionNotify)
+ CheckVirtualMotion(pDev, qe, NullWindow);
syncEvents.time.months = qe->months;
- syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+ /* XXX: Hack! We can't reliably get the time from GenericEvents,
+ since we don't know which struct it may be. So we store the time
+ when we know it, and re-use it when we can't get it. */
+ if (qe->event->u.u.type == GenericEvent)
+ {
+ syncEvents.time.milliseconds = lastKnownMillis;
+ } else
+ {
+ syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+ lastKnownMillis = syncEvents.time.milliseconds;
+ }
#ifdef PANORAMIX
/* Translate back to the sprite screen since processInputProc
will translate from sprite screen to screen 0 upon reentry
to the DIX layer */
+ /* XXX: we can't do that for generic events */
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;
+ qe->event->u.keyButtonPointer.rootX +=
+ panoramiXdataPtr[0].x -
+ panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x;
+ qe->event->u.keyButtonPointer.rootY +=
+ panoramiXdataPtr[0].y -
+ panoramiXdataPtr[pDev->spriteInfo->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)
+ for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen; dev = dev->next)
;
if (!dev)
break;
@@ -1171,19 +1306,38 @@ PlayReleasedEvents(void)
}
else
prev = &qe->next;
- }
+ }
}
+/**
+ * Freeze or thaw the given devices. The device's processing proc is
+ * switched to either the real processing proc (in case of thawing) or an
+ * enqueuing processing proc (usually EnqueueEvent()).
+ *
+ * @param dev The device to freeze/thaw
+ * @param frozen True to freeze or false to thaw.
+ */
static void
FreezeThaw(DeviceIntPtr dev, Bool frozen)
{
- dev->sync.frozen = frozen;
+ dev->deviceGrab.sync.frozen = frozen;
if (frozen)
dev->public.processInputProc = dev->public.enqueueInputProc;
else
dev->public.processInputProc = dev->public.realInputProc;
}
+/**
+ * Unfreeze devices and replay all events to the respective clients.
+ *
+ * ComputeFreezes takes the first event in the device's frozen event queue. It
+ * runs up the sprite tree (spriteTrace) and searches for the window to replay
+ * the events from. If it is found, it checks for passive grabs one down from
+ * the window or delivers the events.
+ *
+ * Since the events in the EQ are always XI events, we need to emulate core
+ * events here.
+ */
static void
ComputeFreezes(void)
{
@@ -1196,23 +1350,25 @@ ComputeFreezes(void)
DeviceIntPtr dev;
for (dev = inputInfo.devices; dev; dev = dev->next)
- FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+ FreezeThaw(dev, dev->deviceGrab.sync.other ||
+ (dev->deviceGrab.sync.state >= FROZEN));
if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
return;
syncEvents.playingEvents = TRUE;
if (replayDev)
{
- xE = replayDev->sync.event;
- count = replayDev->sync.evcount;
+ xE = replayDev->deviceGrab.sync.event;
+ count = replayDev->deviceGrab.sync.evcount;
syncEvents.replayDev = (DeviceIntPtr)NULL;
- w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
- for (i = 0; i < spriteTraceGood; i++)
+ w = XYToWindow(replayDev, XE_KBPTR.rootX, XE_KBPTR.rootY);
+ for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++)
{
- if (syncEvents.replayWin == spriteTrace[i])
+ if (syncEvents.replayWin ==
+ replayDev->spriteInfo->sprite->spriteTrace[i])
{
if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
- if (replayDev->focus)
+ if (replayDev->focus && !IsPointerEvent(xE))
DeliverFocusedEvent(replayDev, xE, w, count);
else
DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
@@ -1222,7 +1378,7 @@ ComputeFreezes(void)
}
}
/* must not still be in the same stack */
- if (replayDev->focus)
+ if (replayDev->focus && !IsPointerEvent(xE))
DeliverFocusedEvent(replayDev, xE, w, count);
else
DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
@@ -1230,24 +1386,34 @@ ComputeFreezes(void)
playmore:
for (dev = inputInfo.devices; dev; dev = dev->next)
{
- if (!dev->sync.frozen)
+ if (!dev->deviceGrab.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)
+ for (dev = inputInfo.devices; dev; dev = dev->next)
{
- if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
- sprite.hotPhys.x = sprite.hotPhys.y = 0;
- ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ if (DevHasCursor(dev))
+ {
+ /* the following may have been skipped during replay,
+ so do it now */
+ if ((grab = dev->deviceGrab.grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen !=
+ dev->spriteInfo->sprite->hotPhys.pScreen)
+ dev->spriteInfo->sprite->hotPhys.x =
+ dev->spriteInfo->sprite->hotPhys.y = 0;
+ ConfineCursorToWindow(dev, grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(dev,
+ WindowTable[dev->spriteInfo->sprite->hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+ PostNewCursor(dev);
+ }
}
- else
- ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
- TRUE, FALSE);
- PostNewCursor();
}
#ifdef RANDR
@@ -1255,232 +1421,280 @@ void
ScreenRestructured (ScreenPtr pScreen)
{
GrabPtr grab;
+ DeviceIntPtr pDev;
- if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
{
- if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
- sprite.hotPhys.x = sprite.hotPhys.y = 0;
- ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ if (!DevHasCursor(pDev))
+ continue;
+
+ /* GrabDevice doesn't have a confineTo field, so we don't need to
+ * worry about it. */
+ if ((grab = pDev->deviceGrab.grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen
+ != pDev->spriteInfo->sprite->hotPhys.pScreen)
+ pDev->spriteInfo->sprite->hotPhys.x = pDev->spriteInfo->sprite->hotPhys.y = 0;
+ ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(pDev,
+ WindowTable[pDev->spriteInfo->sprite->hotPhys.pScreen->myNum],
+ TRUE, FALSE);
}
- else
- ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
- TRUE, FALSE);
}
#endif
static void
CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
{
- GrabPtr grab = thisDev->grab;
+ GrabPtr grab = thisDev->deviceGrab.grab;
DeviceIntPtr dev;
if (thisMode == GrabModeSync)
- thisDev->sync.state = FROZEN_NO_EVENT;
+ thisDev->deviceGrab.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) ==
+ thisDev->deviceGrab.sync.state = THAWED;
+ if (thisDev->deviceGrab.sync.other &&
+ (CLIENT_BITS(thisDev->deviceGrab.sync.other->resource) ==
CLIENT_BITS(grab->resource)))
- thisDev->sync.other = NullGrab;
+ thisDev->deviceGrab.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;
- }
- }
+
+ /*
+ XXX: Direct slave grab won't freeze the paired master device.
+ The correct thing to do would be to freeze all SDs attached to the
+ paired master device.
+ */
+ if (thisDev->isMaster)
+ {
+ dev = GetPairedDevice(thisDev);
+ if (otherMode == GrabModeSync)
+ dev->deviceGrab.sync.other = grab;
+ else
+ { /* free both if same client owns both */
+ if (dev->deviceGrab.sync.other &&
+ (CLIENT_BITS(dev->deviceGrab.sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ dev->deviceGrab.sync.other = NullGrab;
+ }
}
ComputeFreezes();
}
/**
* Activate a pointer grab on the given device. A pointer grab will cause all
- * core pointer events to be delivered to the grabbing client only. Can cause
- * the cursor to change if a grab cursor is set.
- *
- * As a pointer grab can only be issued on the core devices, mouse is always
- * inputInfo.pointer. Extension devices are set up for ActivateKeyboardGrab().
- *
+ * core pointer events of this device to be delivered to the grabbing client only.
+ * No other device will send core events to the grab client while the grab is
+ * on, but core events will be sent to other clients.
+ * Can cause the cursor to change if a grab cursor is set.
+ *
+ * Note that parameter autoGrab may be (True & ImplicitGrabMask) if the grab
+ * is an implicit grab caused by a ButtonPress event.
+ *
* @param mouse The device to grab.
* @param grab The grab structure, needs to be setup.
* @param autoGrab True if the grab was caused by a button down event and not
- * explicitely by a client.
+ * explicitely by a client.
*/
void
-ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
+ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
TimeStamp time, Bool autoGrab)
{
- WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
- : sprite.win;
+ GrabInfoPtr grabinfo = &mouse->deviceGrab;
+ WindowPtr oldWin = (grabinfo->grab) ?
+ grabinfo->grab->window
+ : mouse->spriteInfo->sprite->win;
+ Bool isPassive = autoGrab & ~ImplicitGrabMask;
if (grab->confineTo)
{
- if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
- sprite.hotPhys.x = sprite.hotPhys.y = 0;
- ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+ if (grab->confineTo->drawable.pScreen
+ != mouse->spriteInfo->sprite->hotPhys.pScreen)
+ mouse->spriteInfo->sprite->hotPhys.x =
+ mouse->spriteInfo->sprite->hotPhys.y = 0;
+ ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE);
}
- DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+ DoEnterLeaveEvents(mouse, oldWin, grab->window, NotifyGrab);
mouse->valuator->motionHintWindow = NullWindow;
if (syncEvents.playingEvents)
- mouse->grabTime = syncEvents.time;
+ grabinfo->grabTime = syncEvents.time;
else
- mouse->grabTime = time;
+ grabinfo->grabTime = time;
if (grab->cursor)
grab->cursor->refcnt++;
- mouse->activeGrab = *grab;
- mouse->grab = &mouse->activeGrab;
- mouse->fromPassiveGrab = autoGrab;
- PostNewCursor();
+ grabinfo->activeGrab = *grab;
+ grabinfo->grab = &grabinfo->activeGrab;
+ grabinfo->fromPassiveGrab = isPassive;
+ grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
+ PostNewCursor(mouse);
CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
}
/**
* Delete grab on given device, update the sprite.
*
- * As a pointer grab can only be issued on the core devices, mouse is always
- * inputInfo.pointer. Extension devices are set up for ActivateKeyboardGrab().
+ * Extension devices are set up for ActivateKeyboardGrab().
*/
void
DeactivatePointerGrab(DeviceIntPtr mouse)
{
- GrabPtr grab = mouse->grab;
+ GrabPtr grab = mouse->deviceGrab.grab;
DeviceIntPtr dev;
mouse->valuator->motionHintWindow = NullWindow;
- mouse->grab = NullGrab;
- mouse->sync.state = NOT_GRABBED;
- mouse->fromPassiveGrab = FALSE;
+ mouse->deviceGrab.grab = NullGrab;
+ mouse->deviceGrab.sync.state = NOT_GRABBED;
+ mouse->deviceGrab.fromPassiveGrab = FALSE;
+
+ /* make sure the potential XGE event mask is freed too*/
+ if (grab->genericMasks)
+ {
+ xfree(grab->genericMasks);
+ grab->genericMasks = NULL;
+ }
+
for (dev = inputInfo.devices; dev; dev = dev->next)
{
- if (dev->sync.other == grab)
- dev->sync.other = NullGrab;
+ if (dev->deviceGrab.sync.other == grab)
+ dev->deviceGrab.sync.other = NullGrab;
}
- DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+ DoEnterLeaveEvents(mouse, grab->window,
+ mouse->spriteInfo->sprite->win, NotifyUngrab);
if (grab->confineTo)
- ConfineCursorToWindow(ROOT, FALSE, FALSE);
- PostNewCursor();
+ ConfineCursorToWindow(mouse, RootWindow(mouse), FALSE, FALSE);
+ PostNewCursor(mouse);
if (grab->cursor)
FreeCursor(grab->cursor, (Cursor)0);
+
ComputeFreezes();
}
/**
- * Activate a keyboard grab on the given device.
+ * Activate a keyboard grab on the given device.
*
* Extension devices have ActivateKeyboardGrab() set as their grabbing proc.
*/
void
ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
{
+ GrabInfoPtr grabinfo = &keybd->deviceGrab;
WindowPtr oldWin;
- if (keybd->grab)
- oldWin = keybd->grab->window;
+ if (grabinfo->grab)
+ oldWin = grabinfo->grab->window;
else if (keybd->focus)
oldWin = keybd->focus->win;
else
- oldWin = sprite.win;
+ oldWin = keybd->spriteInfo->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;
+ grabinfo->grabTime = syncEvents.time;
else
- keybd->grabTime = time;
- keybd->activeGrab = *grab;
- keybd->grab = &keybd->activeGrab;
- keybd->fromPassiveGrab = passive;
+ grabinfo->grabTime = time;
+ grabinfo->activeGrab = *grab;
+ grabinfo->grab = &grabinfo->activeGrab;
+ grabinfo->fromPassiveGrab = passive;
CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
}
/**
- * Delete keyboard grab for the given device.
+ * Delete keyboard grab for the given device.
*/
void
DeactivateKeyboardGrab(DeviceIntPtr keybd)
{
- GrabPtr grab = keybd->grab;
+ GrabPtr grab = keybd->deviceGrab.grab;
DeviceIntPtr dev;
WindowPtr focusWin = keybd->focus ? keybd->focus->win
- : sprite.win;
+ : keybd->spriteInfo->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;
+ keybd->deviceGrab.grab = NullGrab;
+ keybd->deviceGrab.sync.state = NOT_GRABBED;
+ keybd->deviceGrab.fromPassiveGrab = FALSE;
+ if (grab->genericMasks)
+ {
+ xfree(grab->genericMasks);
+ grab->genericMasks = NULL;
+ }
+
for (dev = inputInfo.devices; dev; dev = dev->next)
{
- if (dev->sync.other == grab)
- dev->sync.other = NullGrab;
+ if (dev->deviceGrab.sync.other == grab)
+ dev->deviceGrab.sync.other = NullGrab;
}
DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+
ComputeFreezes();
}
void
-AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+AllowSome(ClientPtr client,
+ TimeStamp time,
+ DeviceIntPtr thisDev,
+ int newState,
+ Bool core)
{
Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
TimeStamp grabTime;
DeviceIntPtr dev;
+ GrabInfoPtr devgrabinfo,
+ grabinfo = &thisDev->deviceGrab;
- thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+ thisGrabbed = grabinfo->grab && SameClient(grabinfo->grab, client);
thisSynced = FALSE;
otherGrabbed = FALSE;
othersFrozen = TRUE;
- grabTime = thisDev->grabTime;
+ grabTime = grabinfo->grabTime;
for (dev = inputInfo.devices; dev; dev = dev->next)
{
+ devgrabinfo = &dev->deviceGrab;
+
if (dev == thisDev)
continue;
- if (dev->grab && SameClient(dev->grab, client))
+ if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client))
{
if (!(thisGrabbed || otherGrabbed) ||
- (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
- grabTime = dev->grabTime;
+ (CompareTimeStamps(devgrabinfo->grabTime, grabTime) == LATER))
+ grabTime = devgrabinfo->grabTime;
otherGrabbed = TRUE;
- if (thisDev->sync.other == dev->grab)
+ if (grabinfo->sync.other == devgrabinfo->grab)
thisSynced = TRUE;
- if (dev->sync.state < FROZEN)
+ if (devgrabinfo->sync.state < FROZEN)
othersFrozen = FALSE;
}
- else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+ else if (!devgrabinfo->sync.other || !SameClient(devgrabinfo->sync.other, client))
othersFrozen = FALSE;
}
- if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+ if (!((thisGrabbed && grabinfo->sync.state >= FROZEN) || thisSynced))
return;
if ((CompareTimeStamps(time, currentTime) == LATER) ||
(CompareTimeStamps(time, grabTime) == EARLIER))
return;
switch (newState)
{
- case THAWED: /* Async */
+ case THAWED: /* Async */
if (thisGrabbed)
- thisDev->sync.state = THAWED;
+ grabinfo->sync.state = THAWED;
if (thisSynced)
- thisDev->sync.other = NullGrab;
+ grabinfo->sync.other = NullGrab;
ComputeFreezes();
break;
case FREEZE_NEXT_EVENT: /* Sync */
if (thisGrabbed)
{
- thisDev->sync.state = FREEZE_NEXT_EVENT;
+ grabinfo->sync.state = FREEZE_NEXT_EVENT;
if (thisSynced)
- thisDev->sync.other = NullGrab;
+ grabinfo->sync.other = NullGrab;
ComputeFreezes();
}
break;
@@ -1489,10 +1703,13 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
{
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;
+ devgrabinfo = &dev->deviceGrab;
+ if (devgrabinfo->grab
+ && SameClient(devgrabinfo->grab, client))
+ devgrabinfo->sync.state = THAWED;
+ if (devgrabinfo->sync.other &&
+ SameClient(devgrabinfo->sync.other, client))
+ devgrabinfo->sync.other = NullGrab;
}
ComputeFreezes();
}
@@ -1502,22 +1719,25 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
{
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;
+ devgrabinfo = &dev->deviceGrab;
+ if (devgrabinfo->grab
+ && SameClient(devgrabinfo->grab, client))
+ devgrabinfo->sync.state = FREEZE_BOTH_NEXT_EVENT;
+ if (devgrabinfo->sync.other
+ && SameClient(devgrabinfo->sync.other, client))
+ devgrabinfo->sync.other = NullGrab;
}
ComputeFreezes();
}
break;
case NOT_GRABBED: /* Replay */
- if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+ if (thisGrabbed && grabinfo->sync.state == FROZEN_WITH_EVENT)
{
if (thisSynced)
- thisDev->sync.other = NullGrab;
+ grabinfo->sync.other = NullGrab;
syncEvents.replayDev = thisDev;
- syncEvents.replayWin = thisDev->grab->window;
- (*thisDev->DeactivateGrab)(thisDev);
+ syncEvents.replayWin = grabinfo->grab->window;
+ (*grabinfo->DeactivateGrab)(thisDev);
syncEvents.replayDev = (DeviceIntPtr)NULL;
}
break;
@@ -1528,10 +1748,13 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
{
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;
+ devgrabinfo = (core) ? &dev->deviceGrab : &dev->deviceGrab;
+ if (devgrabinfo->grab
+ && SameClient(devgrabinfo->grab, client))
+ devgrabinfo->sync.state = THAWED;
+ if (devgrabinfo->sync.other
+ && SameClient(devgrabinfo->sync.other, client))
+ devgrabinfo->sync.other = NullGrab;
}
ComputeFreezes();
}
@@ -1542,45 +1765,49 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
/**
* Server-side protocol handling for AllowEvents request.
*
- * Release some events from a frozen device. Only applicable for core devices.
+ * Release some events from a frozen device.
*/
int
ProcAllowEvents(ClientPtr client)
{
TimeStamp time;
- DeviceIntPtr mouse = inputInfo.pointer;
- DeviceIntPtr keybd = inputInfo.keyboard;
+ DeviceIntPtr mouse = NULL;
+ DeviceIntPtr keybd = NULL;
REQUEST(xAllowEventsReq);
REQUEST_SIZE_MATCH(xAllowEventsReq);
time = ClientTimeToServerTime(stuff->time);
+
+ mouse = PickPointer(client);
+ keybd = PickKeyboard(client);
+
switch (stuff->mode)
{
case ReplayPointer:
- AllowSome(client, time, mouse, NOT_GRABBED);
+ AllowSome(client, time, mouse, NOT_GRABBED, True);
break;
- case SyncPointer:
- AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+ case SyncPointer:
+ AllowSome(client, time, mouse, FREEZE_NEXT_EVENT, True);
break;
- case AsyncPointer:
- AllowSome(client, time, mouse, THAWED);
+ case AsyncPointer:
+ AllowSome(client, time, mouse, THAWED, True);
break;
- case ReplayKeyboard:
- AllowSome(client, time, keybd, NOT_GRABBED);
+ case ReplayKeyboard:
+ AllowSome(client, time, keybd, NOT_GRABBED, True);
break;
- case SyncKeyboard:
- AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+ case SyncKeyboard:
+ AllowSome(client, time, keybd, FREEZE_NEXT_EVENT, True);
break;
- case AsyncKeyboard:
- AllowSome(client, time, keybd, THAWED);
+ case AsyncKeyboard:
+ AllowSome(client, time, keybd, THAWED, True);
break;
case SyncBoth:
- AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+ AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT, True);
break;
case AsyncBoth:
- AllowSome(client, time, keybd, THAWED_BOTH);
+ AllowSome(client, time, keybd, THAWED_BOTH, True);
break;
- default:
+ default:
client->errorValue = stuff->mode;
return BadValue;
}
@@ -1600,15 +1827,15 @@ ReleaseActiveGrabs(ClientPtr client)
* releasing active grabs.
*/
do {
- done = TRUE;
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (dev->grab && SameClient(dev->grab, client))
+ done = TRUE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client))
{
- (*dev->DeactivateGrab)(dev);
- done = FALSE;
+ (*dev->deviceGrab.DeactivateGrab)(dev);
+ done = FALSE;
}
- }
+ }
} while (!done);
}
@@ -1624,31 +1851,32 @@ ReleaseActiveGrabs(ClientPtr client)
*
* TryClientEvents() is the last station before actually writing the events to
* the socket. Anything that is not filtered here, will get delivered to the
- * client.
- * An event is only delivered if
+ * client.
+ * An event is only delivered if
* - mask and filter match up.
* - no other client has a grab on the device that caused the event.
- *
+ *
*
* @param client The target client to deliver to.
+ * @param dev The device the event came from. May be NULL.
* @param pEvents The events to be delivered.
* @param count Number of elements in pEvents.
* @param mask Event mask as set by the window.
* @param filter Mask based on event type.
- * @param grab Possible grab on the device that caused the event.
+ * @param grab Possible grab on the device that caused the event.
*
* @return 1 if event was delivered, 0 if not or -1 if grab was not set by the
* client.
*/
_X_EXPORT int
-TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
- Mask filter, GrabPtr grab)
+TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
+ int count, Mask mask, Mask filter, GrabPtr grab)
{
int i;
int type;
#ifdef DEBUG_EVENTS
- ErrorF("Event([%d, %d], mask=0x%x), client=%d",
+ ErrorF("[dix] 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) &&
@@ -1661,12 +1889,12 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
{
if (mask & PointerMotionHintMask)
{
- if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+ if (WID(dev->valuator->motionHintWindow) ==
pEvents->u.keyButtonPointer.event)
{
#ifdef DEBUG_EVENTS
- ErrorF("\n");
- ErrorF("motionHintWindow == keyButtonPointer.event\n");
+ ErrorF("[dix] \n");
+ ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n");
#endif
return 1; /* don't send, but pretend we did */
}
@@ -1677,7 +1905,6 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
pEvents->u.u.detail = NotifyNormal;
}
}
-#ifdef XINPUT
else
{
if ((type == DeviceMotionNotify) &&
@@ -1685,7 +1912,6 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
((deviceKeyButtonPointer*)pEvents, mask) != 0)
return 1;
}
-#endif
type &= 0177;
if (type != KeymapNotify)
{
@@ -1696,23 +1922,21 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
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_EVENTS
- ErrorF( " delivered\n");
+ ErrorF("[dix] delivered\n");
#endif
return 1;
}
else
{
#ifdef DEBUG_EVENTS
- ErrorF("\n");
+ ErrorF("[dix] \n");
#endif
return 0;
}
@@ -1723,21 +1947,25 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
* actually needs to be delivered. May activate a grab if the event is a
* button press.
*
+ * Core events are always delivered to the window owner. If the filter is
+ * something other than CantBeFiltered, the event is also delivered to other
+ * clients with the matching mask on the window.
+ *
* More than one event may be delivered at a time. This is the case with
* DeviceMotionNotifies which may be followed by DeviceValuator events.
- *
+ *
* @param pWin The window that would get the event.
* @param pEvents The events to be delivered.
* @param count Number of elements in pEvents.
* @param filter Mask based on event type.
- * @param grab Possible grab on the device that caused the event.
+ * @param grab Possible grab on the device that caused the event.
* @param mskidx Mask index, depending on device that caused event.
*
* @return Number of events delivered to various clients.
*/
int
-DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
- Mask filter, GrabPtr grab, int mskidx)
+DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
+ *pEvents, int count, Mask filter, GrabPtr grab, int mskidx)
{
int deliveries = 0, nondeliveries = 0;
int attempt;
@@ -1748,16 +1976,23 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
int type = pEvents->u.u.type;
/* CantBeFiltered means only window owner gets the event */
- if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+ if ((filter == CantBeFiltered) ||
+ (!(type & EXTENSION_EVENT_BASE) && type != GenericEvent))
{
/* if nobody ever wants to see this event, skip some work */
if (filter != CantBeFiltered &&
!((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
return 0;
+
+ if (!(type & EXTENSION_EVENT_BASE) &&
+ IsInterferingGrab(wClient(pWin), pDev, pEvents))
+ return 0;
+
if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
/* do nothing */;
- else if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
- pWin->eventMask, filter, grab)) )
+ else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents,
+ count, pWin->eventMask,
+ filter, grab)) )
{
if (attempt > 0)
{
@@ -1770,41 +2005,94 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
}
if (filter != CantBeFiltered)
{
- if (type & EXTENSION_EVENT_BASE)
- {
- OtherInputMasks *inputMasks;
+ /* Handle generic events */
+ if (type == GenericEvent)
+ {
+ GenericMaskPtr gmask;
+ /* We don't do more than one GenericEvent at a time. */
+ if (count > 1)
+ {
+ ErrorF("[dix] Do not send more than one GenericEvent at a time!\n");
+ return 0;
+ }
- 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 (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents,
- count))
- /* do nothing */;
- else 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 we get here, filter should be set to the GE specific mask.
+ check if any client wants it */
+ if (!GEDeviceMaskIsSet(pWin, pDev, GEEXT(pEvents), filter))
+ return 0;
+
+ /* run through all clients, deliver event */
+ for (gmask = GECLIENT(pWin); gmask; gmask = gmask->next)
+ {
+ if (gmask->eventMask[GEEXTIDX(pEvents)] & filter)
+ {
+ if (XaceHook(XACE_RECEIVE_ACCESS, rClient(gmask), pWin,
+ pEvents, count))
+ /* do nothing */;
+ else if (TryClientEvents(rClient(gmask), pDev,
+ pEvents, count,
+ gmask->eventMask[GEEXTIDX(pEvents)],
+ filter, grab) > 0)
+ {
+ deliveries++;
+ } else
+ nondeliveries--;
+ }
+ }
+ }
+ else {
+ /* Traditional event */
+ 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)
+ {
+ /* core event? check for grab interference */
+ if (!(type & EXTENSION_EVENT_BASE) &&
+ IsInterferingGrab(rClient(other), pDev, pEvents))
+ continue;
+
+ if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
+ pEvents, count))
+ /* do nothing */;
+ else if ( (attempt = TryClientEvents(rClient(other), pDev,
+ 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))
+ /*
+ * Note that since core events are delivered first, an implicit grab may
+ * be activated on a core grab, stopping the XI events.
+ */
+ if ((type == DeviceButtonPress || type == ButtonPress)
+ && deliveries
+ && (!grab))
{
GrabRec tempGrab;
+ OtherInputMasks *inputMasks;
- tempGrab.device = inputInfo.pointer;
+ tempGrab.next = NULL;
+ tempGrab.device = pDev;
tempGrab.resource = client->clientAsMask;
tempGrab.window = pWin;
tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
@@ -1813,12 +2101,32 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
tempGrab.pointerMode = GrabModeAsync;
tempGrab.confineTo = NullWindow;
tempGrab.cursor = NullCursor;
- (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
- currentTime, TRUE);
+ tempGrab.coreGrab = (type == ButtonPress);
+
+ /* get the XI device mask */
+ inputMasks = wOtherInputMasks(pWin);
+ tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0;
+
+ /* get the XGE event mask. */
+ tempGrab.genericMasks = NULL;
+ if (pWin->optional && pWin->optional->geMasks)
+ {
+ GenericClientMasksPtr gemasks = pWin->optional->geMasks;
+ GenericMaskPtr geclient = gemasks->geClients;
+ while(geclient && rClient(geclient) != client)
+ geclient = geclient->next;
+ if (geclient)
+ {
+ tempGrab.genericMasks = xcalloc(1, sizeof(GenericMaskRec));
+ *tempGrab.genericMasks = *geclient;
+ tempGrab.genericMasks->next = NULL;
+ }
+ }
+ (*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab,
+ currentTime, TRUE | ImplicitGrabMask);
}
else if ((type == MotionNotify) && deliveries)
- inputInfo.pointer->valuator->motionHintWindow = pWin;
-#ifdef XINPUT
+ pDev->valuator->motionHintWindow = pWin;
else
{
if (((type == DeviceMotionNotify)
@@ -1830,7 +2138,6 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
(deviceKeyButtonPointer*) pEvents,
grab, client, deliveryMask);
}
-#endif
if (deliveries)
return deliveries;
return nondeliveries;
@@ -1842,11 +2149,11 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
*/
#ifdef PANORAMIX
-static int
+static int
XineramaTryClientEventsResult(
ClientPtr client,
GrabPtr grab,
- Mask mask,
+ Mask mask,
Mask filter
){
if ((client) && (client != serverClient) && (!client->clientGone) &&
@@ -1869,7 +2176,7 @@ XineramaTryClientEventsResult(
* @param dontClient Don't deliver to the dontClient.
*/
int
-MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
+MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
int count, Mask filter, ClientPtr dontClient)
{
OtherClients *other;
@@ -1880,13 +2187,13 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
if (wClient(pWin) == dontClient)
return 0;
#ifdef PANORAMIX
- if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
return XineramaTryClientEventsResult(
wClient(pWin), NullGrab, pWin->eventMask, filter);
#endif
if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
return 1; /* don't send, but pretend we did */
- return TryClientEvents(wClient(pWin), pEvents, count,
+ return TryClientEvents(wClient(pWin), NULL, pEvents, count,
pWin->eventMask, filter, NullGrab);
}
for (other = wOtherClients(pWin); other; other = other->next)
@@ -1896,14 +2203,14 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
if (SameClient(other, dontClient))
return 0;
#ifdef PANORAMIX
- if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
return XineramaTryClientEventsResult(
rClient(other), NullGrab, other->mask, filter);
#endif
if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents,
count))
return 1; /* don't send, but pretend we did */
- return TryClientEvents(rClient(other), pEvents, count,
+ return TryClientEvents(rClient(other), NULL, pEvents, count,
other->mask, filter, NullGrab);
}
}
@@ -1920,41 +2227,47 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
*/
static void
FixUpEventFromWindow(
+ DeviceIntPtr pDev,
xEvent *xE,
WindowPtr pWin,
Window child,
Bool calcChild)
{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ if (xE->u.u.type == GenericEvent) /* just a safety barrier */
+ return;
+
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
+ WindowPtr w= pSprite->spriteTrace[pSprite->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)
+ 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 == pWin)
+ {
+ child = None;
+ break;
}
-
+
if (w->parent == pWin)
{
child = w->drawable.id;
break;
}
- w = w->parent;
- }
+ w = w->parent;
+ }
}
- XE_KBPTR.root = ROOT->drawable.id;
+ XE_KBPTR.root = RootWindow(pDev)->drawable.id;
XE_KBPTR.event = pWin->drawable.id;
- if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ if (pSprite->hot.pScreen == pWin->drawable.pScreen)
{
XE_KBPTR.sameScreen = xTrue;
XE_KBPTR.child = child;
@@ -1973,12 +2286,14 @@ FixUpEventFromWindow(
}
/**
- * Deliver events caused by input devices. Called for all core input events
- * and XI events. No filtering of events happens before DeliverDeviceEvents(),
- * it will be called for any event that comes out of the event queue.
- *
- * For all core events, dev is either inputInfo.pointer or inputInfo.keyboard.
- * For all extension events, dev is the device that caused the event.
+ * Deliver events caused by input devices. Called for both core input events
+ * and XI events.
+ * For events from a non-grabbed, non-focus device, DeliverDeviceEvents is
+ * called directly from the processInputProc.
+ * For grabbed devices, DeliverGrabbedEvent is called first, and _may_ call
+ * DeliverDeviceEvents.
+ * For focused events, DeliverFocusedEvent is called first, and _may_ call
+ * DeliverDeviceEvents.
*
* @param pWin Window to deliver event to.
* @param xE Events to deliver.
@@ -1987,77 +2302,110 @@ FixUpEventFromWindow(
* @param dev The device that is responsible for the event.
* @param count number of events in xE.
*
+ * @see DeliverGrabbedEvent
+ * @see DeliverFocusedEvent
*/
int
-DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
+DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
WindowPtr stopAt, DeviceIntPtr dev, int count)
{
Window child = None;
int type = xE->u.u.type;
- Mask filter = filters[type];
+ Mask filter = filters[dev->id][type];
int deliveries = 0;
+ OtherInputMasks *inputMasks;
+ int mskidx = dev->id;
+ xEvent core;
if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
return 0;
- if (type & EXTENSION_EVENT_BASE)
+ /* handle generic events */
+ /* XXX: Generic events aren't quite handled correctly yet. They should
+ * eventually fit in with the rest of the stuff
+ */
+ if (type == GenericEvent)
{
- OtherInputMasks *inputMasks;
- int mskidx = dev->id;
+ WindowPtr win = pWin;
+ xGenericEvent* ge = (xGenericEvent*)xE;
- 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);
- }
+ if (count > 1)
+ {
+ ErrorF("[dix] Do not send more than one GenericEvent at a time!\n");
+ return 0;
+ }
+ filter = generic_filters[GEEXTIDX(xE)][ge->evtype];
+
+ while(win)
+ {
+ if (GEDeviceMaskIsSet(win, dev, GEEXT(xE), filter))
+ {
+ if (GEExtensions[GEEXTIDX(xE)].evfill)
+ GEExtensions[GEEXTIDX(xE)].evfill(ge, dev, win, grab);
+ deliveries = DeliverEventsToWindow(dev, win, xE, count,
+ filter, grab, 0);
+ if (deliveries > 0)
+ return deliveries;
+ }
+
+ win = win->parent;
+ }
}
- else
+
+ while (pWin && type != GenericEvent)
{
- 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;
- }
+ if (!dev->isMaster)
+ {
+ inputMasks = wOtherInputMasks(pWin);
+ if (inputMasks && (filter & inputMasks->deliverableEvents[mskidx]))
+ {
+
+ if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+ {
+ FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
+ filter, grab, mskidx);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ }
+
+ if ((deliveries < 0) || (pWin == stopAt) ||
+ (inputMasks && (filter & inputMasks->dontPropagateMask[mskidx])))
+ return 0;
+ } else
+ {
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+
+ if (core.u.u.type && filter & pWin->deliverableEvents)
+ {
+ if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+ {
+ FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
+ 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;
}
/**
* Deliver event to a window and it's immediate parent. Used for most window
* events (CreateNotify, ConfigureNotify, etc.). Not useful for events that
- * propagate up the tree or extension events
+ * propagate up the tree or extension events
*
* In case of a ReparentNotify event, the event will be delivered to the
* otherParent as well.
@@ -2068,7 +2416,7 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
* @param otherParent Used for ReparentNotify events.
*/
_X_EXPORT int
-DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
+DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
WindowPtr otherParent)
{
Mask filter;
@@ -2081,24 +2429,26 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
if (!count)
return 0;
- filter = filters[xE->u.u.type];
+ /* We don't know a device here. However, this should only ever be called
+ for a non-device event so we are safe to use 0*/
+ filter = filters[0][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,
+ return DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, filter, NullGrab, 0);
+ deliveries = DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, StructureNotifyMask,
NullGrab, 0);
if (pWin->parent)
{
xE->u.destroyNotify.event = pWin->parent->drawable.id;
- deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+ deliveries += DeliverEventsToWindow(inputInfo.pointer, 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,
+ deliveries += DeliverEventsToWindow(inputInfo.pointer,
+ otherParent, xE, count, SubstructureNotifyMask,
NullGrab, 0);
}
}
@@ -2106,23 +2456,25 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
}
-static Bool
+static Bool
PointInBorderSize(WindowPtr pWin, int x, int y)
{
BoxRec box;
+ SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite;
if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
return TRUE;
#ifdef PANORAMIX
- if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ if(!noPanoramiXExtension &&
+ XineramaSetWindowPntrs(inputInfo.pointer, 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,
+ if(POINT_IN_REGION(pSprite->screen,
+ &pSprite->windows[i]->borderSize,
+ x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
+ y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
&box))
return TRUE;
}
@@ -2142,14 +2494,16 @@ PointInBorderSize(WindowPtr pWin, int x, int y)
*
* @returns the window at the given coordinates.
*/
-static WindowPtr
-XYToWindow(int x, int y)
+static WindowPtr
+XYToWindow(DeviceIntPtr pDev, int x, int y)
{
WindowPtr pWin;
BoxRec box;
+ SpritePtr pSprite;
- spriteTraceGood = 1; /* root window still there */
- pWin = ROOT->firstChild;
+ pSprite = pDev->spriteInfo->sprite;
+ pSprite->spriteTraceGood = 1; /* root window still there */
+ pWin = RootWindow(pDev)->firstChild;
while (pWin)
{
if ((pWin->mapped) &&
@@ -2159,7 +2513,6 @@ XYToWindow(int x, int y)
(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
@@ -2170,24 +2523,28 @@ XYToWindow(int x, int y)
wInputShape(pWin),
x - pWin->drawable.x,
y - pWin->drawable.y, &box))
+#ifdef ROOTLESS
+ /* In rootless mode windows may be offscreen, even when
+ * they're in X's stack. (E.g. if the native window system
+ * implements some form of virtual desktop system).
+ */
+ && !pWin->rootlessUnhittable
#endif
)
{
- if (spriteTraceGood >= spriteTraceSize)
+ if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
{
- spriteTraceSize += 10;
- Must_have_memory = TRUE; /* XXX */
- spriteTrace = (WindowPtr *)xrealloc(
- spriteTrace, spriteTraceSize*sizeof(WindowPtr));
- Must_have_memory = FALSE; /* XXX */
+ pSprite->spriteTraceSize += 10;
+ pSprite->spriteTrace = xrealloc(pSprite->spriteTrace,
+ pSprite->spriteTraceSize*sizeof(WindowPtr));
}
- spriteTrace[spriteTraceGood++] = pWin;
+ pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
pWin = pWin->firstChild;
}
else
pWin = pWin->nextSib;
}
- return spriteTrace[spriteTraceGood-1];
+ return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
}
/**
@@ -2195,74 +2552,100 @@ XYToWindow(int x, int y)
* position, then update the event with the new coordinates that may have been
* changed. If the window underneath the sprite has changed, change to new
* cursor and send enter/leave events.
+ *
+ * CheckMotion() will not do anything and return FALSE if the event is not a
+ * pointer event.
+ *
+ * @return TRUE if the sprite has moved or FALSE otherwise.
*/
-static Bool
-CheckMotion(xEvent *xE)
+Bool
+CheckMotion(xEvent *xE, DeviceIntPtr pDev)
{
- WindowPtr prevSpriteWin = sprite.win;
+ INT16 *rootX, *rootY;
+ WindowPtr prevSpriteWin;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ prevSpriteWin = pSprite->win;
#ifdef PANORAMIX
if(!noPanoramiXExtension)
- return XineramaCheckMotion(xE);
+ return XineramaCheckMotion(xE, pDev);
#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))
+ /* GetPointerEvents() guarantees that pointer events have the correct
+ rootX/Y set already. */
+ switch(xE->u.u.type)
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ rootX = &XE_KBPTR.rootX;
+ rootY = &XE_KBPTR.rootY;
+ break;
+ default:
+ if (xE->u.u.type == DeviceButtonPress ||
+ xE->u.u.type == DeviceButtonRelease ||
+ xE->u.u.type == DeviceMotionNotify)
+ {
+ rootX = &((deviceKeyButtonPointer*)xE)->root_x;
+ rootY = &((deviceKeyButtonPointer*)xE)->root_y;
+ break;
+ }
+ /* all other events return FALSE */
+ return FALSE;
+ }
+
+ if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen)
+ {
+ pSprite->hot.pScreen = pSprite->hotPhys.pScreen;
+ RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum];
+ }
+ pSprite->hot.x = *rootX;
+ pSprite->hot.y = *rootY;
+ if (pSprite->hot.x < pSprite->physLimits.x1)
+ pSprite->hot.x = pSprite->physLimits.x1;
+ else if (pSprite->hot.x >= pSprite->physLimits.x2)
+ pSprite->hot.x = pSprite->physLimits.x2 - 1;
+ if (pSprite->hot.y < pSprite->physLimits.y1)
+ pSprite->hot.y = pSprite->physLimits.y1;
+ else if (pSprite->hot.y >= pSprite->physLimits.y2)
+ pSprite->hot.y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y);
+ pSprite->hotPhys = pSprite->hot;
+
+ if ((pSprite->hotPhys.x != *rootX) ||
+ (pSprite->hotPhys.y != *rootY))
{
- (*sprite.hotPhys.pScreen->SetCursorPosition)(
- sprite.hotPhys.pScreen,
- sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ (*pSprite->hotPhys.pScreen->SetCursorPosition)(
+ pDev, pSprite->hotPhys.pScreen,
+ pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE);
}
- XE_KBPTR.rootX = sprite.hot.x;
- XE_KBPTR.rootY = sprite.hot.y;
+
+ *rootX = pSprite->hot.x;
+ *rootY = pSprite->hot.y;
}
-#ifdef XEVIE
- xeviewin =
-#endif
- sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+ pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
#ifdef notyet
- if (!(sprite.win->deliverableEvents &
- Motion_Filter(inputInfo.pointer->button))
+ if (!(pSprite->win->deliverableEvents &
+ Motion_Filter(pDev->button))
!syncEvents.playingEvents)
{
/* XXX Do PointerNonInterestBox here */
}
#endif
- if (sprite.win != prevSpriteWin)
+ if (pSprite->win != prevSpriteWin)
{
if (prevSpriteWin != NullWindow) {
if (!xE)
UpdateCurrentTimeIf();
- DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
- }
- PostNewCursor();
+ DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win,
+ NotifyNormal);
+ }
+ PostNewCursor(pDev);
return FALSE;
}
return TRUE;
@@ -2272,10 +2655,16 @@ CheckMotion(xEvent *xE)
* Windows have restructured, we need to update the sprite position and the
* sprite's cursor.
*/
-_X_EXPORT void
+void
WindowsRestructured(void)
{
- (void) CheckMotion((xEvent *)NULL);
+ DeviceIntPtr pDev = inputInfo.devices;
+ while(pDev)
+ {
+ if (DevHasCursor(pDev))
+ CheckMotion((xEvent *)NULL, pDev);
+ pDev = pDev->next;
+ }
}
#ifdef PANORAMIX
@@ -2287,81 +2676,174 @@ WindowsRestructured(void)
void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
{
GrabPtr grab;
+ DeviceIntPtr pDev;
+ SpritePtr pSprite;
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);
+
+ pDev = inputInfo.devices;
+ while(pDev)
+ {
+ if (DevHasCursor(pDev))
+ {
+ pSprite = pDev->spriteInfo->sprite;
+ pSprite->hot.x -= xoff;
+ pSprite->hot.y -= yoff;
+
+ pSprite->hotPhys.x -= xoff;
+ pSprite->hotPhys.y -= yoff;
+
+ pSprite->hotLimits.x1 -= xoff;
+ pSprite->hotLimits.y1 -= yoff;
+ pSprite->hotLimits.x2 -= xoff;
+ pSprite->hotLimits.y2 -= yoff;
+
+ if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg1))
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, xoff, yoff);
+ if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg2))
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, xoff, yoff);
+
+ /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+ if ((grab = pDev->deviceGrab.grab) && grab->confineTo) {
+ if (grab->confineTo->drawable.pScreen
+ != pSprite->hotPhys.pScreen)
+ pSprite->hotPhys.x = pSprite->hotPhys.y = 0;
+ ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE);
+ } else
+ ConfineCursorToWindow(
+ pDev,
+ WindowTable[pSprite->hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+
+ }
+ pDev = pDev->next;
+ }
}
#endif
/**
- * Set the given window to sane values, display the cursor in the center of
- * the screen. Called from main() with the root window on the first screen.
+ * Called from main() with the root window on the first screen. Used to do a
+ * lot more when MPX wasn't around yet. Things change.
+ *
+ * Should delete this now? -ds
*/
void
DefineInitialRootWindow(WindowPtr win)
{
- 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);
+}
+
+/**
+ * Initialize a sprite for the given device and set it to some sane values. If
+ * the device already has a sprite alloc'd, don't realloc but just reset to
+ * default values.
+ * If a window is supplied, the sprite will be initialized with the window's
+ * cursor and positioned in the center of the window's screen. The root window
+ * is a good choice to pass in here.
+ *
+ * It's a good idea to call it only for pointer devices, unless you have a
+ * really talented keyboard.
+ *
+ * @param pDev The device to initialize.
+ * @param pWin The window where to generate the sprite in.
+ *
+ */
+void
+InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
+{
+ SpritePtr pSprite;
+ ScreenPtr pScreen;
+
+ if (!pDev->spriteInfo->sprite)
+ {
+ DeviceIntPtr it;
+
+ pDev->spriteInfo->sprite = (SpritePtr)xcalloc(1, sizeof(SpriteRec));
+ if (!pDev->spriteInfo->sprite)
+ FatalError("InitializeSprite: failed to allocate sprite struct");
+
+ /* We may have paired another device with this device before our
+ * device had a actual sprite. We need to check for this and reset the
+ * sprite field for all paired devices.
+ *
+ * The VCK is always paired with the VCP before the VCP has a sprite.
+ */
+ for (it = inputInfo.devices; it; it = it->next)
+ {
+ if (it->spriteInfo->paired == pDev)
+ it->spriteInfo->sprite = pDev->spriteInfo->sprite;
+ }
+ if (inputInfo.keyboard->spriteInfo->paired == pDev)
+ inputInfo.keyboard->spriteInfo->sprite = pDev->spriteInfo->sprite;
+ }
+
+ pSprite = pDev->spriteInfo->sprite;
+ pDev->spriteInfo->spriteOwner = TRUE;
+
+ pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr)NULL;
+ pSprite->hot.pScreen = pScreen;
+ pSprite->hotPhys.pScreen = pScreen;
+ if (pScreen)
+ {
+ pSprite->hotPhys.x = pScreen->width / 2;
+ pSprite->hotPhys.y = pScreen->height / 2;
+ pSprite->hotLimits.x2 = pScreen->width;
+ pSprite->hotLimits.y2 = pScreen->height;
+ }
+ pSprite->hot = pSprite->hotPhys;
+ pSprite->win = pWin;
+
+ if (pWin)
+ {
+ pSprite->current = wCursor(pWin);
+ pSprite->current->refcnt++;
+ pSprite->spriteTrace = (WindowPtr *)xcalloc(1, 32*sizeof(WindowPtr));
+ if (!pSprite->spriteTrace)
+ FatalError("Failed to allocate spriteTrace");
+ pSprite->spriteTraceSize = 32;
+
+ RootWindow(pDev) = pWin;
+ pSprite->spriteTraceGood = 1;
+
+ pSprite->pEnqueueScreen = pScreen;
+ pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
+
+ } else {
+ pSprite->current = NullCursor;
+ pSprite->spriteTrace = NULL;
+ pSprite->spriteTraceSize = 0;
+ pSprite->spriteTraceGood = 0;
+ pSprite->pEnqueueScreen = screenInfo.screens[0];
+ pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
+ }
+
+ if (pScreen)
+ {
+ (*pScreen->RealizeCursor) ( pDev, pScreen, pSprite->current);
+ (*pScreen->CursorLimits) ( pDev, pScreen, pSprite->current,
+ &pSprite->hotLimits, &pSprite->physLimits);
+ pSprite->confined = FALSE;
+
+ (*pScreen->ConstrainCursor) (pDev, pScreen,
+ &pSprite->physLimits);
+ (*pScreen->SetCursorPosition) (pDev, pScreen, pSprite->hot.x,
+ pSprite->hot.y,
+ FALSE);
+ (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->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);
+ pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y1 = -panoramiXdataPtr[0].y;
+ pSprite->hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ pSprite->physLimits = pSprite->hotLimits;
+ pSprite->confineWin = NullWindow;
+ pSprite->hotShape = NullRegion;
+ pSprite->screen = pScreen;
+ /* gotta UNINIT these someplace */
+ REGION_NULL(pScreen, &pSprite->Reg1);
+ REGION_NULL(pScreen, &pSprite->Reg2);
}
#endif
}
@@ -2382,41 +2864,46 @@ DefineInitialRootWindow(WindowPtr win)
* @param win must be the new pScreen we are switching to.
*/
void
-UpdateSpriteForScreen(ScreenPtr pScreen)
+UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
{
+ SpritePtr pSprite = NULL;
WindowPtr win = NULL;
if (!pScreen)
return ;
+
+ if (!pDev->spriteInfo->sprite)
+ return;
+
+ pSprite = pDev->spriteInfo->sprite;
+
win = WindowTable[pScreen->myNum];
- sprite.hotPhys.pScreen = pScreen;
- 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->DisplayCursor) (pScreen, sprite.current);
+ pSprite->hotPhys.pScreen = pScreen;
+ pSprite->hot = pSprite->hotPhys;
+ pSprite->hotLimits.x2 = pScreen->width;
+ pSprite->hotLimits.y2 = pScreen->height;
+ pSprite->win = win;
+ pSprite->current = wCursor (win);
+ pSprite->current->refcnt++;
+ pSprite->spriteTraceGood = 1;
+ pSprite->spriteTrace[0] = win;
+ (*pScreen->CursorLimits) (pDev,
+ pScreen,
+ pSprite->current,
+ &pSprite->hotLimits,
+ &pSprite->physLimits);
+ pSprite->confined = FALSE;
+ (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits);
+ (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->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.screen = pScreen;
+ pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y1 = -panoramiXdataPtr[0].y;
+ pSprite->hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ pSprite->physLimits = pSprite->hotLimits;
+ pSprite->screen = pScreen;
}
#endif
}
@@ -2431,40 +2918,50 @@ UpdateSpriteForScreen(ScreenPtr pScreen)
void
WindowHasNewCursor(WindowPtr pWin)
{
- PostNewCursor();
+ DeviceIntPtr pDev;
+
+ for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ if (DevHasCursor(pDev))
+ PostNewCursor(pDev);
}
_X_EXPORT void
-NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y)
{
- sprite.hotPhys.x = x;
- sprite.hotPhys.y = y;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ pSprite->hotPhys.x = x;
+ pSprite->hotPhys.y = y;
#ifdef PANORAMIX
if(!noPanoramiXExtension) {
- sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
+ pSprite->hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
panoramiXdataPtr[0].x;
- sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
+ pSprite->hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
panoramiXdataPtr[0].y;
- if (newScreen != sprite.screen) {
- sprite.screen = newScreen;
+ if (newScreen != pSprite->screen) {
+ pSprite->screen = newScreen;
/* Make sure we tell the DDX to update its copy of the screen */
- if(sprite.confineWin)
- XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+ if(pSprite->confineWin)
+ XineramaConfineCursorToWindow(pDev,
+ pSprite->confineWin, TRUE);
else
- XineramaConfineCursorToWindow(WindowTable[0], TRUE);
- /* if the pointer wasn't confined, the DDX won't get
+ XineramaConfineCursorToWindow(pDev, 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);
+ (*pSprite->screen->SetCursorPosition)(
+ pDev,
+ pSprite->screen,
+ pSprite->hotPhys.x + panoramiXdataPtr[0].x -
+ panoramiXdataPtr[pSprite->screen->myNum].x,
+ pSprite->hotPhys.y + panoramiXdataPtr[0].y -
+ panoramiXdataPtr[pSprite->screen->myNum].y, FALSE);
}
- } else
+ } else
#endif
- if (newScreen != sprite.hotPhys.pScreen)
- ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+ if (newScreen != pSprite->hotPhys.pScreen)
+ ConfineCursorToWindow(pDev, WindowTable[newScreen->myNum],
+ TRUE, FALSE);
}
#ifdef PANORAMIX
@@ -2484,14 +2981,14 @@ XineramaPointInWindowIsVisible(
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;
+ if(!XineramaSetWindowPntrs(inputInfo.pointer, pWin)) return FALSE;
+
+ xoff = x + panoramiXdataPtr[0].x;
+ yoff = y + panoramiXdataPtr[0].y;
for(i = 1; i < PanoramiXNumScreens; i++) {
- pWin = sprite.windows[i];
+ pWin = inputInfo.pointer->spriteInfo->sprite->windows[i];
pScreen = pWin->drawable.pScreen;
x = xoff - panoramiXdataPtr[i].x;
y = yoff - panoramiXdataPtr[i].y;
@@ -2500,7 +2997,7 @@ XineramaPointInWindowIsVisible(
&& (!wInputShape(pWin) ||
POINT_IN_REGION(pWin->drawable.pScreen,
wInputShape(pWin),
- x - pWin->drawable.x,
+ x - pWin->drawable.x,
y - pWin->drawable.y, &box)))
return TRUE;
@@ -2514,6 +3011,7 @@ XineramaWarpPointer(ClientPtr client)
{
WindowPtr dest = NULL;
int x, y, rc;
+ SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite;
REQUEST(xWarpPointerReq);
@@ -2523,15 +3021,15 @@ XineramaWarpPointer(ClientPtr client)
if (rc != Success)
return rc;
}
- x = sprite.hotPhys.x;
- y = sprite.hotPhys.y;
+ x = pSprite->hotPhys.x;
+ y = pSprite->hotPhys.y;
if (stuff->srcWid != None)
{
int winX, winY;
- XID winID = stuff->srcWid;
+ XID winID = stuff->srcWid;
WindowPtr source;
-
+
rc = dixLookupWindow(&source, winID, client, DixReadAccess);
if (rc != Success)
return rc;
@@ -2558,23 +3056,23 @@ XineramaWarpPointer(ClientPtr client)
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);
+ if (x < pSprite->physLimits.x1)
+ x = pSprite->physLimits.x1;
+ else if (x >= pSprite->physLimits.x2)
+ x = pSprite->physLimits.x2 - 1;
+ if (y < pSprite->physLimits.y1)
+ y = pSprite->physLimits.y1;
+ else if (y >= pSprite->physLimits.y2)
+ y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y);
- XineramaSetCursorPosition(x, y, TRUE);
+ XineramaSetCursorPosition(PickPointer(client), x, y, TRUE);
return Success;
}
@@ -2593,9 +3091,12 @@ ProcWarpPointer(ClientPtr client)
int x, y, rc;
ScreenPtr newScreen;
DeviceIntPtr dev;
+ SpritePtr pSprite;
+
REQUEST(xWarpPointerReq);
REQUEST_SIZE_MATCH(xWarpPointerReq);
+ /* XXX XACE ??*/
for (dev = inputInfo.devices; dev; dev = dev->next) {
if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess);
@@ -2603,6 +3104,12 @@ ProcWarpPointer(ClientPtr client)
return rc;
}
}
+
+ dev = PickPointer(client);
+ if (dev->u.lastSlave)
+ dev = dev->u.lastSlave;
+ pSprite = dev->spriteInfo->sprite;
+
#ifdef PANORAMIX
if(!noPanoramiXExtension)
return XineramaWarpPointer(client);
@@ -2613,22 +3120,22 @@ ProcWarpPointer(ClientPtr client)
if (rc != Success)
return rc;
}
- x = sprite.hotPhys.x;
- y = sprite.hotPhys.y;
+ x = pSprite->hotPhys.x;
+ y = pSprite->hotPhys.y;
if (stuff->srcWid != None)
{
int winX, winY;
- XID winID = stuff->srcWid;
+ XID winID = stuff->srcWid;
WindowPtr source;
-
+
rc = dixLookupWindow(&source, winID, client, DixGetAttrAccess);
if (rc != Success)
return rc;
winX = source->drawable.x;
winY = source->drawable.y;
- if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+ if (source->drawable.pScreen != pSprite->hotPhys.pScreen ||
x < winX + stuff->srcX ||
y < winY + stuff->srcY ||
(stuff->srcWidth != 0 &&
@@ -2638,13 +3145,13 @@ ProcWarpPointer(ClientPtr client)
!PointInWindowIsVisible(source, x, y))
return Success;
}
- if (dest)
+ if (dest)
{
x = dest->drawable.x;
y = dest->drawable.y;
newScreen = dest->drawable.pScreen;
- } else
- newScreen = sprite.hotPhys.pScreen;
+ } else
+ newScreen = pSprite->hotPhys.pScreen;
x += stuff->dstX;
y += stuff->dstY;
@@ -2658,41 +3165,40 @@ ProcWarpPointer(ClientPtr client)
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);
+ if (newScreen == pSprite->hotPhys.pScreen)
+ {
+ if (x < pSprite->physLimits.x1)
+ x = pSprite->physLimits.x1;
+ else if (x >= pSprite->physLimits.x2)
+ x = pSprite->physLimits.x2 - 1;
+ if (y < pSprite->physLimits.y1)
+ y = pSprite->physLimits.y1;
+ else if (y >= pSprite->physLimits.y2)
+ y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(dev, pSprite->hotShape, &x, &y);
+ (*newScreen->SetCursorPosition)(dev, newScreen, x, y, TRUE);
}
- else if (!PointerConfinedToScreen())
+ else if (!PointerConfinedToScreen(dev))
{
- NewCurrentScreen(newScreen, x, y);
+ NewCurrentScreen(dev, newScreen, x, y);
}
return Success;
}
-static Bool
-BorderSizeNotEmpty(WindowPtr pWin)
+static Bool
+BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
{
- if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+ if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->hotPhys.pScreen, &pWin->borderSize))
return TRUE;
#ifdef PANORAMIX
- if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pDev, pWin)) {
int i;
for(i = 1; i < PanoramiXNumScreens; i++) {
- if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+ if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->screen,
+ &pDev->spriteInfo->sprite->windows[i]->borderSize))
return TRUE;
}
}
@@ -2700,15 +3206,17 @@ BorderSizeNotEmpty(WindowPtr pWin)
return FALSE;
}
-/**
+/**
* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
- * passive grab set on the window to be activated.
+ * passive grab set on the window to be activated.
* If a passive grab is activated, the event will be delivered to the client.
- *
+ *
* @param pWin The window that may be subject to a passive grab.
* @param device Device that caused the event.
* @param xE List of events (multiple ones for DeviceMotionNotify)
- * @count number of elements in xE.
+ * @param count number of elements in xE.
+ * @param store The event that will be stored on the device (always XI)
+ * @param scount number of elements in store.
*/
static Bool
@@ -2716,10 +3224,13 @@ CheckPassiveGrabsOnWindow(
WindowPtr pWin,
DeviceIntPtr device,
xEvent *xE,
- int count)
+ int count,
+ xEvent *store,
+ int scount)
{
GrabPtr grab = wPassiveGrabs(pWin);
GrabRec tempGrab;
+ GrabInfoPtr grabinfo;
xEvent *dxE;
if (!grab)
@@ -2730,39 +3241,49 @@ CheckPassiveGrabsOnWindow(
tempGrab.detail.exact = xE->u.u.detail;
tempGrab.detail.pMask = NULL;
tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.next = NULL;
for (; grab; grab = grab->next)
{
#ifdef XKB
DeviceIntPtr gdev;
- XkbSrvInfoPtr xkbi;
+ XkbSrvInfoPtr xkbi = NULL;
gdev= grab->modifierDevice;
- xkbi= gdev->key->xkbInfo;
+ if (grab->coreGrab)
+ {
+ if (IsPointerDevice(device))
+ gdev = GetPairedDevice(device);
+ else
+ gdev = device;
+ }
+ if (gdev && gdev->key)
+ 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
- ))
+ ((xE->u.u.type == KeyPress) || (xE->u.u.type == DeviceKeyPress)))
tempGrab.modifiersDetail.exact =
#ifdef XKB
- (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+ (noXkbExtension) ?
+ ((gdev) ? gdev->key->prev_state : 0) :
+ ((xkbi) ? xkbi->state.grab_mods : 0);
#else
- grab->modifierDevice->key->prev_state;
+ (gdev) ? gdev->key->prev_state : 0;
#endif
else
tempGrab.modifiersDetail.exact =
#ifdef XKB
- (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+ (noXkbExtension) ?
+ ((gdev) ? gdev->key->state : 0) :
+ ((xkbi) ? xkbi->state.grab_mods : 0);
#else
- grab->modifierDevice->key->state;
+ (gdev) ? gdev->key->state : 0;
#endif
- if (GrabMatchesSecond(&tempGrab, grab) &&
+ /* ignore the device for core events when comparing grabs */
+ if (GrabMatchesSecond(&tempGrab, grab, (xE->u.u.type < LASTEvent)) &&
(!grab->confineTo ||
- (grab->confineTo->realized &&
- BorderSizeNotEmpty(grab->confineTo))))
+ (grab->confineTo->realized &&
+ BorderSizeNotEmpty(device, grab->confineTo))))
{
#ifdef XKB
if (!noXkbExtension) {
@@ -2771,29 +3292,70 @@ CheckPassiveGrabsOnWindow(
tempGrab.modifiersDetail.exact&(~0x1f00);
}
#endif
- (*device->ActivateGrab)(device, grab, currentTime, TRUE);
-
- FixUpEventFromWindow(xE, grab->window, None, TRUE);
+ grabinfo = &device->deviceGrab;
+ /* A passive grab may have been created for a different device
+ than it is assigned to at this point in time.
+ Update the grab's device and modifier device to reflect the
+ current state.
+ Since XGrabDeviceButton requires to specify the
+ modifierDevice explicitly, we don't override this choice.
+ */
+ if (xE->u.u.type < LASTEvent)
+ {
+ grab->device = device;
+ grab->modifierDevice = GetPairedDevice(device);
+ }
+
+ /* In some cases a passive core grab may exist, but the client
+ * already has a core grab on some other device. In this case we
+ * must not get the grab, otherwise we may never ungrab the
+ * device.
+ */
+
+ if (grab->coreGrab)
+ {
+ DeviceIntPtr other;
+ BOOL interfering = FALSE;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ GrabPtr othergrab = other->deviceGrab.grab;
+ if (othergrab && othergrab->coreGrab &&
+ SameClient(grab, rClient(othergrab)) &&
+ ((IsPointerDevice(grab->device) &&
+ IsPointerDevice(othergrab->device)) ||
+ (IsKeyboardDevice(grab->device) &&
+ IsKeyboardDevice(othergrab->device))))
+ {
+ interfering = TRUE;
+ break;
+ }
+ }
+ if (interfering)
+ continue;
+ }
+
- (void) TryClientEvents(rClient(grab), xE, count,
- filters[xE->u.u.type],
- filters[xE->u.u.type], grab);
+ (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
- if (device->sync.state == FROZEN_NO_EVENT)
+ FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
+
+ (void) TryClientEvents(rClient(grab), device, xE, count,
+ filters[device->id][xE->u.u.type],
+ filters[device->id][xE->u.u.type], grab);
+
+ if (grabinfo->sync.state == FROZEN_NO_EVENT)
{
- if (device->sync.evcount < count)
+ if (grabinfo->sync.evcount < scount)
{
- Must_have_memory = TRUE; /* XXX */
- device->sync.event = (xEvent *)xrealloc(device->sync.event,
- count*
- sizeof(xEvent));
- Must_have_memory = FALSE; /* XXX */
+ grabinfo->sync.event = xrealloc(grabinfo->sync.event,
+ scount * sizeof(xEvent));
}
- device->sync.evcount = count;
- for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
- *dxE = *xE;
- device->sync.state = FROZEN_WITH_EVENT;
- }
+ grabinfo->sync.evcount = scount;
+ /* we always store the XI event, never the core event */
+ for (dxE = grabinfo->sync.event; --scount >= 0; dxE++, store++)
+ *dxE = *store;
+ grabinfo->sync.state = FROZEN_WITH_EVENT;
+ }
return TRUE;
}
}
@@ -2802,14 +3364,14 @@ CheckPassiveGrabsOnWindow(
/**
* CheckDeviceGrabs handles both keyboard and pointer events that may cause
- * a passive grab to be activated.
+ * 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 the 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.
+ * 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
@@ -2817,27 +3379,44 @@ CheckPassiveGrabsOnWindow(
*
* If a grab is activated, the event has been sent to the client already!
*
+ * The event we pass in must always be an XI event. From this, we then emulate
+ * the core event and then check for grabs.
+ *
* @param device The device that caused the event.
- * @param xE The event to handle (most likely {Device}ButtonPress).
+ * @param xE The event to handle (Device{Button|Key}Press).
* @param count Number of events in list.
* @return TRUE if a grab has been activated or false otherwise.
*/
Bool
-CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
+CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
int checkFirst, int count)
{
int i;
WindowPtr pWin = NULL;
- FocusClassPtr focus = device->focus;
+ FocusClassPtr focus = IsPointerEvent(xE) ? NULL : device->focus;
+ xEvent core;
+ BOOL sendCore = (device->isMaster && device->coreEvents);
- if (((xE->u.u.type == ButtonPress)
-#if defined(XINPUT) && defined(XKB)
- || (xE->u.u.type == DeviceButtonPress)
-#endif
- ) && (device->button->buttonsDown != 1))
+ if ((xE->u.u.type == DeviceButtonPress)
+ && (device->button->buttonsDown != 1))
return FALSE;
+ if (xE->u.u.type < EXTENSION_EVENT_BASE)
+ {
+ ErrorF("[dix] Core event passed into CheckDeviceGrabs.\n");
+ return FALSE;
+ }
+
+
+ if (sendCore)
+ {
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+ if(!core.u.u.type) /* probably a Proximity event, can't grab for those */
+ return FALSE;
+ }
+
i = checkFirst;
if (focus)
@@ -2845,22 +3424,28 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
for (; i < focus->traceGood; i++)
{
pWin = focus->trace[i];
+ /* XI grabs have precendence */
if (pWin->optional &&
- CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count)
+ || (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core,
+ 1, xE, count))))
return TRUE;
}
-
+
if ((focus->win == NoneWin) ||
- (i >= spriteTraceGood) ||
- ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+ (i >= device->spriteInfo->sprite->spriteTraceGood) ||
+ ((i > checkFirst) &&
+ (pWin != device->spriteInfo->sprite->spriteTrace[i-1])))
return FALSE;
}
- for (; i < spriteTraceGood; i++)
+ for (; i < device->spriteInfo->sprite->spriteTraceGood; i++)
{
- pWin = spriteTrace[i];
+ pWin = device->spriteInfo->sprite->spriteTrace[i];
if (pWin->optional &&
- CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) ||
+ (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core, 1,
+ xE, count))))
return TRUE;
}
@@ -2880,8 +3465,11 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
void
DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
{
+ DeviceIntPtr pointer;
WindowPtr focus = keybd->focus->win;
- int mskidx = 0;
+ BOOL sendCore = (keybd->isMaster && keybd->coreEvents);
+ xEvent core;
+ int deliveries = 0;
if (focus == FollowKeyboardWin)
focus = inputInfo.keyboard->focus->win;
@@ -2897,14 +3485,32 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
return;
}
+ pointer = GetPairedDevice(keybd);
if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
return;
+
+ if (sendCore)
+ {
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+ }
+
/* 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);
+ FixUpEventFromWindow(pointer, xE, focus, None, FALSE);
+ deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
+ filters[keybd->id][xE->u.u.type],
+ NullGrab, keybd->id);
+
+ if (deliveries > 0)
+ return;
+
+ if (sendCore && core.u.u.type)
+ {
+ FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
+ deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
+ filters[keybd->id][xE->u.u.type],
+ NullGrab, 0);
+ }
}
/**
@@ -2915,19 +3521,36 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
* @param deactivateGrab True if the device's grab should be deactivated.
*/
void
-DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
+DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
Bool deactivateGrab, int count)
{
- GrabPtr grab = thisDev->grab;
+ GrabPtr grab;
+ GrabInfoPtr grabinfo;
int deliveries = 0;
DeviceIntPtr dev;
- xEvent *dxE;
+ xEvent *dxE, core;
+ SpritePtr pSprite = thisDev->spriteInfo->sprite;
+ BOOL sendCore = FALSE;
+
+ grabinfo = &thisDev->deviceGrab;
+ grab = grabinfo->grab;
if (grab->ownerEvents)
{
WindowPtr focus;
- if (thisDev->focus)
+ /* Hack: Some pointer device have a focus class. So we need to check
+ * for the type of event, to see if we really want to deliver it to
+ * the focus window. For pointer events, the answer is no.
+ */
+ if (xE->u.u.type == DeviceButtonPress ||
+ xE->u.u.type == DeviceButtonRelease ||
+ xE->u.u.type == DeviceMotionNotify ||
+ xE->u.u.type == ProximityIn ||
+ xE->u.u.type == ProximityOut)
+ {
+ focus = PointerRootWin;
+ } else if (thisDev->focus)
{
focus = thisDev->focus->win;
if (focus == FollowKeyboardWin)
@@ -2936,10 +3559,11 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
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,
+ deliveries = DeliverDeviceEvents(pSprite->win, xE, grab,
+ NullWindow, thisDev, count);
+ else if (focus && (focus == pSprite->win ||
+ IsParent(focus, pSprite->win)))
+ deliveries = DeliverDeviceEvents(pSprite->win, xE, grab, focus,
thisDev, count);
else if (focus)
deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
@@ -2947,28 +3571,65 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
}
if (!deliveries)
{
- FixUpEventFromWindow(xE, grab->window, None, TRUE);
- if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, grab->window, xE, count) ||
- XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), grab->window, xE,
- count))
- deliveries = 1; /* don't send, but pretend we did */
- else
- 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;
+ {
+ Mask mask = grab->eventMask;
+
+ if (thisDev->isMaster)
+ {
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+ if(core.u.u.type) {
+ FixUpEventFromWindow(thisDev, &core, grab->window,
+ None, TRUE);
+ if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+ grab->window, &core, 1) ||
+ XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+ grab->window, &core, 1))
+ deliveries = 1; /* don't send, but pretend we did */
+ else if (!IsInterferingGrab(rClient(grab), thisDev,
+ &core))
+ {
+ deliveries = TryClientEvents(rClient(grab), thisDev,
+ &core, 1, mask,
+ filters[thisDev->id][core.u.u.type],
+ grab);
+ }
+ }
+ } else
+ {
+ /* try XI event */
+ if (grabinfo->fromPassiveGrab &&
+ grabinfo->implicitGrab &&
+ (xE->u.u.type & EXTENSION_EVENT_BASE))
+ mask = grab->deviceMask;
+ FixUpEventFromWindow(thisDev, xE, grab->window,
+ None, TRUE);
+
+ if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+ grab->window, xE, count) ||
+ XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+ grab->window, xE, count))
+ deliveries = 1; /* don't send, but pretend we did */
+ else
+ {
+ deliveries =
+ TryClientEvents(rClient(grab), thisDev,
+ xE, count,
+ mask,
+ filters[thisDev->id][xE->u.u.type],
+ grab);
+ }
+
+ }
+ }
+ if (deliveries && (xE->u.u.type == MotionNotify
+ || xE->u.u.type == DeviceMotionNotify))
+ 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)
+ if (deliveries && !deactivateGrab &&
+ (xE->u.u.type != MotionNotify && xE->u.u.type != DeviceMotionNotify))
+ {
+ switch (grabinfo->sync.state)
{
case FREEZE_BOTH_NEXT_EVENT:
for (dev = inputInfo.devices; dev; dev = dev->next)
@@ -2976,33 +3637,32 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
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;
+ if ((grabinfo->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+ (CLIENT_BITS(grab->resource) ==
+ CLIENT_BITS(grab->resource)))
+ grabinfo->sync.state = FROZEN_NO_EVENT;
else
- dev->sync.other = thisDev->grab;
+ grabinfo->sync.other = grab;
}
/* fall through */
case FREEZE_NEXT_EVENT:
- thisDev->sync.state = FROZEN_WITH_EVENT;
+ grabinfo->sync.state = FROZEN_WITH_EVENT;
FreezeThaw(thisDev, TRUE);
- if (thisDev->sync.evcount < count)
+ if (grabinfo->sync.evcount < count)
{
- Must_have_memory = TRUE; /* XXX */
- thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
- count*sizeof(xEvent));
- Must_have_memory = FALSE; /* XXX */
+ grabinfo->sync.event = xrealloc(grabinfo->sync.event,
+ count * sizeof(xEvent));
}
- thisDev->sync.evcount = count;
- for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+ grabinfo->sync.evcount = count;
+ for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++)
*dxE = *xE;
break;
}
+ }
}
/**
- * Main keyboard event processing function for core keyboard events.
+ * Main keyboard event processing function for core keyboard events.
* Updates the events fields from the current pointer state and delivers the
* event.
*
@@ -3020,52 +3680,15 @@ ProcessKeyboardEvent (xEvent *xE, DeviceIntPtr keybd, int count)
#endif
{
int key, bit;
- BYTE *kptr;
- int i;
- CARD8 modifiers;
- CARD16 mask;
- GrabPtr grab = keybd->grab;
+ BYTE *kptr;
+ CARD8 modifiers;
+ GrabPtr grab;
+ GrabInfoPtr grabinfo;
Bool deactivateGrab = FALSE;
- 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
+ KeyClassPtr keyc = keybd->key;
+
+ grabinfo = &keybd->deviceGrab;
+ grab = grabinfo->grab;
if (!syncEvents.playingEvents)
{
@@ -3078,103 +3701,56 @@ drawable.id:0;
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;
+ /* ProcessOtherEvent already updated the keyboard's state, so we need to
+ * access prev_state here! */
+ XE_KBPTR.state = (keyc->prev_state | GetPairedDevice(keybd)->button->state);
+ XE_KBPTR.rootX = keybd->spriteInfo->sprite->hot.x;
+ XE_KBPTR.rootY = keybd->spriteInfo->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
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;
- }
- }
+ case KeyPress:
+ /* We MUST NOT change the device itself here. All device state
+ * changes must be performed in ProcessOtherEvents. We're dealing
+ * with the same device struct, so if we change it in POE and
+ * here, we've just screwed up the state by setting it twice.
+ *
+ * Devices may not send core events but always send XI events, so
+ * the state must be changed in POE, not here.
+ */
if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
{
- keybd->activatingKey = key;
+ grabinfo->activatingKey = key;
return;
}
break;
- case KeyRelease:
+ 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))
+ /* No device state changes, see comment for KeyPress */
+ if (grabinfo->fromPassiveGrab && (key == grabinfo->activatingKey))
deactivateGrab = TRUE;
break;
- default:
+ default:
FatalError("Impossible keyboard event");
}
if (grab)
DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
else
- DeliverFocusedEvent(keybd, xE, sprite.win, count);
+ DeliverFocusedEvent(keybd, xE, keybd->spriteInfo->sprite->win, count);
if (deactivateGrab)
- (*keybd->DeactivateGrab)(keybd);
+ (*grabinfo->DeactivateGrab)(keybd);
XaceHook(XACE_KEY_AVAIL, xE, keybd, count);
}
#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
+ this is only used when the pressing of keys does not cause
the device's processInputProc to be called, as in for example Mouse Keys.
*/
void
@@ -3204,8 +3780,8 @@ FixKeyState (xEvent *xE, DeviceIntPtr keybd)
}
#endif
-/**
- * Main pointer event processing function for core pointer events.
+/**
+ * Main pointer event processing function for core pointer events.
* For motion events: update the sprite.
* For all other events: Update the event fields based on the current sprite
* state.
@@ -3223,23 +3799,13 @@ CoreProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
#endif
{
- GrabPtr grab = mouse->grab;
+ GrabPtr grab = mouse->deviceGrab.grab;
Bool deactivateGrab = FALSE;
- ButtonClassPtr butc = mouse->button;
+ ButtonClassPtr butc = mouse->button;
+ SpritePtr pSprite = mouse->spriteInfo->sprite;
+
#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;
- }
- }
+ XkbSrvInfoPtr xkbi= GetPairedDevice(mouse)->key->xkbInfo;
#endif
if (!syncEvents.playingEvents)
@@ -3261,69 +3827,59 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
/* 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;
+ WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id;
eventinfo.events = xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
}
}
+ /* We need to call CheckMotion for each event. It doesn't really give us
+ any benefit for relative devices, but absolute devices may not send
+ button events to the right position otherwise. */
+ if (!CheckMotion(xE, mouse) && xE->u.u.type == MotionNotify)
+ return;
if (xE->u.u.type != MotionNotify)
{
int key;
- BYTE *kptr;
- int bit;
- XE_KBPTR.rootX = sprite.hot.x;
- XE_KBPTR.rootY = sprite.hot.y;
+ XE_KBPTR.rootX = pSprite->hot.x;
+ XE_KBPTR.rootY = pSprite->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;
+ case ButtonPress:
+ /*
+ * We rely on the fact that ButtonMotionMask is the same as
+ * DeviceButtonMotionMask, so setting the motionMask
+ * to this value ensures correctness for both XI and core events.
+ */
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);
+ filters[mouse->id][Motion_Filter(butc)] = MotionNotify;
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;
+ case ButtonRelease:
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)
+ filters[mouse->id][Motion_Filter(butc)] = MotionNotify;
+ if (!butc->buttonsDown && mouse->deviceGrab.fromPassiveGrab)
deactivateGrab = TRUE;
break;
- default:
- FatalError("bogus pointer event from ddx: %d", xE->u.u.type);
+ default:
+ FatalError("bogus pointer event from ddx. Type %d\n", xE->u.u.type);
}
}
- else if (!CheckMotion(xE))
- return;
+
if (grab)
DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
else
- DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+ DeliverDeviceEvents(pSprite->win, xE, NullGrab, NullWindow,
mouse, count);
if (deactivateGrab)
- (*mouse->DeactivateGrab)(mouse);
+ (*mouse->deviceGrab.DeactivateGrab)(mouse);
}
#define AtMostOneClient \
@@ -3418,6 +3974,7 @@ EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask)
{
Mask check;
OtherClients * others;
+ DeviceIntPtr dev;
int rc;
if (mask & ~AllEventMasks)
@@ -3483,18 +4040,21 @@ EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask)
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;
+maskSet:
+ if ((mask & PointerMotionHintMask) && !(check & PointerMotionHintMask))
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->valuator && dev->valuator->motionHintWindow == pWin)
+ dev->valuator->motionHintWindow = NullWindow;
+ }
+ }
RecalculateDeliverableEvents(pWin);
return Success;
}
int
-EventSuppressForWindow(WindowPtr pWin, ClientPtr client,
+EventSuppressForWindow(WindowPtr pWin, ClientPtr client,
Mask mask, Bool *checkOptional)
{
int i, free;
@@ -3550,37 +4110,26 @@ EventSuppressForWindow(WindowPtr pWin, ClientPtr client,
}
/**
- * @return The window that is the first ancestor of both a and b.
+ * Assembles an EnterNotify or LeaveNotify and sends it event to the client.
+ * Uses the paired keyboard to get some additional information.
*/
-static WindowPtr
-CommonAncestor(
- WindowPtr a,
- WindowPtr b)
-{
- for (b = b->parent; b; b = b->parent)
- if (IsParent(b, a)) return b;
- return NullWindow;
-}
-
-/**
- * Assembles an EnterNotify or LeaveNotify and sends it event to the client.
- * The core devices are used to fill in the event fields.
- */
-static void
-EnterLeaveEvent(
+void
+CoreEnterLeaveEvent(
+ DeviceIntPtr mouse,
int type,
int mode,
int detail,
WindowPtr pWin,
Window child)
{
- xEvent event;
- DeviceIntPtr keybd = inputInfo.keyboard;
+ xEvent event;
WindowPtr focus;
- DeviceIntPtr mouse = inputInfo.pointer;
- GrabPtr grab = mouse->grab;
+ DeviceIntPtr keybd;
+ GrabPtr grab = mouse->deviceGrab.grab;
Mask mask;
+ keybd = GetPairedDevice(mouse);
+
if ((pWin == mouse->valuator->motionHintWindow) &&
(detail != NotifyInferior))
mouse->valuator->motionHintWindow = NullWindow;
@@ -3594,345 +4143,105 @@ EnterLeaveEvent(
{
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;
+
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.enterLeave.time = currentTime.milliseconds;
+ event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x;
+ event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y;
+ /* Counts on the same initial structure of crossing & button events! */
+ FixUpEventFromWindow(mouse, &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
+ if (!noXkbExtension) {
+ event.u.enterLeave.state = mouse->button->state & 0x1f00;
+ if (keybd)
+ 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;
- ClientPtr client = grab ? rClient(grab)
- : clients[CLIENT_ID(pWin->drawable.id)];
- if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess))
- bzero((char *)&ke.map[0], 31);
- else
- 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);
+ event.u.enterLeave.state = (keybd) ? keybd->key->state : 0;
+ event.u.enterLeave.state |= mouse->button->state;
}
-}
-
-/**
- * Send enter notifies to all parent windows up to ancestor.
- * This function recurses.
- */
-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);
-}
-
+ event.u.enterLeave.mode = mode;
+ focus = (keybd) ? keybd->focus->win : None;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) ||
+ IsParent(focus, pWin)))
+ event.u.enterLeave.flags |= ELFlagFocus;
-/**
- * Send leave notifies to all parent windows up to ancestor.
- * This function recurses.
- */
-static void
-LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
-{
- WindowPtr pWin;
-
- if (ancestor == child)
- return;
- for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+ if ((mask & filters[mouse->id][type]))
{
- EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
- child = pWin;
+ if (grab)
+ TryClientEvents(rClient(grab), mouse, &event, 1, mask,
+ filters[mouse->id][type], grab);
+ else
+ DeliverEventsToWindow(mouse, pWin, &event, 1,
+ filters[mouse->id][type], NullGrab, 0);
}
-}
-/**
- * Figure out if enter/leave events are necessary and send them to the
- * appropriate windows.
- *
- * @param fromWin Window the sprite moved out of.
- * @param toWin Window the sprite moved into.
- */
-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))
+ if ((type == EnterNotify) && (mask & KeymapStateMask))
{
- 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);
+ xKeymapEvent ke;
+ ClientPtr client = grab ? rClient(grab)
+ : clients[CLIENT_ID(pWin->drawable.id)];
+ if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess))
+ bzero((char *)&ke.map[0], 31);
+ else
+ memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+
+ ke.type = KeymapNotify;
+ if (grab)
+ TryClientEvents(rClient(grab), keybd, (xEvent *)&ke, 1,
+ mask, KeymapStateMask, grab);
+ else
+ DeliverEventsToWindow(mouse, pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
}
}
-static void
-FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
+void
+CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 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);
+ (void)DeliverEventsToWindow(dev, pWin, &event, 1,
+ filters[dev->id][type], NullGrab, 0);
if ((type == FocusIn) &&
- ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+ ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
{
- xKeymapEvent ke;
- ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
- if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess))
- bzero((char *)&ke.map[0], 31);
- else
- memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+ xKeymapEvent ke;
+ ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+ if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess))
+ bzero((char *)&ke.map[0], 31);
+ else
+ 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)
-{
- 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);
- }
- }
+ ke.type = KeymapNotify;
+ (void)DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
}
}
/**
* Set the input focus to the given window. Subsequent keyboard events will be
* delivered to the given window.
- *
+ *
* Usually called from ProcSetInputFocus as result of a client request. If so,
* the device is the inputInfo.keyboard.
* If called from ProcXSetInputFocus as result of a client xinput request, the
* device is set to the device specified by the client.
*
* @param client Client that requested input focus change.
- * @param dev Focus device.
+ * @param dev Focus device.
* @param focusID The window to obtain the focus. Can be PointerRoot or None.
* @param revertTo Specifies where the focus reverts to when window becomes
* unviewable.
@@ -3952,6 +4261,8 @@ SetInputFocus(
WindowPtr focusWin;
int mode, rc;
TimeStamp time;
+ DeviceIntPtr keybd; /* used for FollowKeyboard or FollowKeyboardWin */
+
UpdateCurrentTime();
if ((revertTo != RevertToParent) &&
@@ -3963,15 +4274,23 @@ SetInputFocus(
return BadValue;
}
time = ClientTimeToServerTime(ctime);
+
+ if (IsKeyboardDevice(dev))
+ keybd = dev;
+ else
+ keybd = GetPairedDevice(dev);
+
if ((focusID == None) || (focusID == PointerRoot))
focusWin = (WindowPtr)(long)focusID;
else if ((focusID == FollowKeyboard) && followOK)
- focusWin = inputInfo.keyboard->focus->win;
+ {
+ focusWin = keybd->focus->win;
+ }
else {
rc = dixLookupWindow(&focusWin, focusID, client, DixSetAttrAccess);
if (rc != Success)
return rc;
- /* It is a match error to try to set the input focus to an
+ /* It is a match error to try to set the input focus to an
unviewable window. */
if(!focusWin->realized)
return(BadMatch);
@@ -3984,9 +4303,9 @@ SetInputFocus(
if ((CompareTimeStamps(time, currentTime) == LATER) ||
(CompareTimeStamps(time, focus->time) == EARLIER))
return Success;
- mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+ mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal;
if (focus->win == FollowKeyboardWin)
- DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+ DoFocusEvents(dev, keybd->focus->win, focusWin, mode);
else
DoFocusEvents(dev, focus->win, focusWin, mode);
focus->time = time;
@@ -4006,14 +4325,11 @@ SetInputFocus(
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->trace = xrealloc(focus->trace,
+ focus->traceSize * sizeof(WindowPtr));
}
focus->traceGood = depth;
- for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
+ for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
focus->trace[depth] = pWin;
}
return Success;
@@ -4028,31 +4344,32 @@ int
ProcSetInputFocus(client)
ClientPtr client;
{
+ DeviceIntPtr kbd = PickKeyboard(client);
REQUEST(xSetInputFocusReq);
REQUEST_SIZE_MATCH(xSetInputFocusReq);
- return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+ return SetInputFocus(client, kbd, stuff->focus,
stuff->revertTo, stuff->time, FALSE);
}
/**
* Server-side protocol handling for GetInputFocus request.
- *
- * Sends the current input focus for the virtual core keyboard back to the
+ *
+ * Sends the current input focus for the client's keyboard back to the
* client.
*/
int
ProcGetInputFocus(ClientPtr client)
{
+ DeviceIntPtr kbd = PickKeyboard(client);
xGetInputFocusReply rep;
- FocusClassPtr focus = inputInfo.keyboard->focus;
+ FocusClassPtr focus = kbd->focus;
int rc;
/* REQUEST(xReq); */
REQUEST_SIZE_MATCH(xReq);
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard,
- DixGetFocusAccess);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetFocusAccess);
if (rc != Success)
return rc;
@@ -4070,16 +4387,16 @@ ProcGetInputFocus(ClientPtr client)
}
/**
- * Server-side protocol handling for Grabpointer request.
+ * Server-side protocol handling for GrabPointer request.
*
- * Sets an active grab on the inputInfo.pointer and returns success status to
- * client.
+ * Sets an active grab on the client's ClientPointer and returns success
+ * status to client.
*/
int
ProcGrabPointer(ClientPtr client)
{
xGrabPointerReply rep;
- DeviceIntPtr device = inputInfo.pointer;
+ DeviceIntPtr device = PickPointer(client);
GrabPtr grab;
WindowPtr pWin, confineTo;
CursorPtr cursor, oldCursor;
@@ -4117,7 +4434,7 @@ ProcGrabPointer(ClientPtr client)
return rc;
if (stuff->confineTo == None)
confineTo = NullWindow;
- else
+ else
{
rc = dixLookupWindow(&confineTo, stuff->confineTo, client,
DixSetAttrAccess);
@@ -4149,18 +4466,27 @@ ProcGrabPointer(ClientPtr client)
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
- grab = device->grab;
+
+ grab = device->deviceGrab.grab;
+ /* check for
+ 1. other client has a grab on the device already.
+ 2. window is viewable
+ 3. other client has this device as frozen "other" device
+ 4. times are screwed.
+ */
if ((grab) && !SameClient(grab, client))
rep.status = AlreadyGrabbed;
else if ((!pWin->realized) ||
(confineTo &&
- !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+ !(confineTo->realized
+ && BorderSizeNotEmpty(device, confineTo))))
rep.status = GrabNotViewable;
- else if (device->sync.frozen &&
- device->sync.other && !SameClient(device->sync.other, client))
+ else if (device->deviceGrab.sync.frozen &&
+ device->deviceGrab.sync.other &&
+ !SameClient(device->deviceGrab.sync.other, client))
rep.status = GrabFrozen;
else if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
rep.status = GrabInvalidTime;
else
{
@@ -4168,11 +4494,12 @@ ProcGrabPointer(ClientPtr client)
oldCursor = NullCursor;
if (grab)
- {
+ {
if (grab->confineTo && !confineTo)
- ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE);
oldCursor = grab->cursor;
}
+ tempGrab.next = NULL;
tempGrab.cursor = cursor;
tempGrab.resource = client->clientAsMask;
tempGrab.ownerEvents = stuff->ownerEvents;
@@ -4182,7 +4509,9 @@ ProcGrabPointer(ClientPtr client)
tempGrab.keyboardMode = stuff->keyboardMode;
tempGrab.pointerMode = stuff->pointerMode;
tempGrab.device = device;
- (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+ tempGrab.coreGrab = True;
+ tempGrab.genericMasks = NULL;
+ (*device->deviceGrab.ActivateGrab)(device, &tempGrab, time, FALSE);
if (oldCursor)
FreeCursor (oldCursor, (Cursor)0);
rep.status = GrabSuccess;
@@ -4195,15 +4524,13 @@ ProcGrabPointer(ClientPtr client)
* Server-side protocol handling for ChangeActivePointerGrab request.
*
* Changes properties of the grab hold by the client. If the client does not
- * hold an active grab on the device, nothing happens.
- *
- * Works on the core pointer only.
+ * hold an active grab on the device, nothing happens.
*/
int
ProcChangeActivePointerGrab(ClientPtr client)
{
- DeviceIntPtr device = inputInfo.pointer;
- GrabPtr grab = device->grab;
+ DeviceIntPtr device;
+ GrabPtr grab;
CursorPtr newCursor, oldCursor;
REQUEST(xChangeActivePointerGrabReq);
TimeStamp time;
@@ -4226,19 +4553,23 @@ ProcChangeActivePointerGrab(ClientPtr client)
return (rc == BadValue) ? BadCursor : rc;
}
}
+
+ device = PickPointer(client);
+ grab = device->deviceGrab.grab;
+
if (!grab)
return Success;
if (!SameClient(grab, client))
return Success;
time = ClientTimeToServerTime(stuff->time);
if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
return Success;
oldCursor = grab->cursor;
grab->cursor = newCursor;
if (newCursor)
newCursor->refcnt++;
- PostNewCursor();
+ PostNewCursor(device);
if (oldCursor)
FreeCursor(oldCursor, (Cursor)0);
grab->eventMask = stuff->eventMask;
@@ -4248,55 +4579,58 @@ ProcChangeActivePointerGrab(ClientPtr client)
/**
* Server-side protocol handling for UngrabPointer request.
*
- * Deletes the pointer grab on the core pointer device.
+ * Deletes a pointer grab on a device the client has grabbed.
*/
int
ProcUngrabPointer(ClientPtr client)
{
- DeviceIntPtr device = inputInfo.pointer;
+ DeviceIntPtr device = PickPointer(client);
GrabPtr grab;
TimeStamp time;
REQUEST(xResourceReq);
REQUEST_SIZE_MATCH(xResourceReq);
UpdateCurrentTime();
- grab = device->grab;
+ grab = device->deviceGrab.grab;
+
time = ClientTimeToServerTime(stuff->id);
if ((CompareTimeStamps(time, currentTime) != LATER) &&
- (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
(grab) && SameClient(grab, client))
- (*device->DeactivateGrab)(device);
+ (*device->deviceGrab.DeactivateGrab)(device);
return Success;
}
/**
* Sets a grab on the given device.
- *
- * Called from ProcGrabKeyboard to work on the inputInfo.keyboard.
+ *
+ * Called from ProcGrabKeyboard to work on the client's keyboard.
* Called from ProcXGrabDevice to work on the device specified by the client.
- *
+ *
* The parameters this_mode and other_mode represent the keyboard_mode and
- * pointer_mode parameters of XGrabKeyboard().
+ * pointer_mode parameters of XGrabKeyboard().
* See man page for details on all the parameters
- *
+ *
* @param client Client that owns the grab.
- * @param dev The device to grab.
+ * @param dev The device to grab.
* @param this_mode GrabModeSync or GrabModeAsync
* @param other_mode GrabModeSync or GrabModeAsync
* @param status Return code to be returned to the caller.
- *
+ *
* @returns Success or BadValue.
*/
int
-GrabDevice(ClientPtr client, DeviceIntPtr dev,
- unsigned this_mode, unsigned other_mode, Window grabWindow,
- unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+GrabDevice(ClientPtr client, DeviceIntPtr dev,
+ unsigned this_mode, unsigned other_mode, Window grabWindow,
+ unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status,
+ Bool coreGrab)
{
WindowPtr pWin;
GrabPtr grab;
TimeStamp time;
Mask access_mode = DixGrabAccess;
int rc;
+ GrabInfoPtr grabInfo = &dev->deviceGrab;
UpdateCurrentTime();
if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
@@ -4325,21 +4659,25 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
return rc;
time = ClientTimeToServerTime(ctime);
- grab = dev->grab;
+ grab = grabInfo->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))
+ (CompareTimeStamps(time, grabInfo->grabTime) == EARLIER))
*status = GrabInvalidTime;
- else if (dev->sync.frozen &&
- dev->sync.other && !SameClient(dev->sync.other, client))
+ else if (grabInfo->sync.frozen &&
+ grabInfo->sync.other && !SameClient(grabInfo->sync.other, client))
*status = GrabFrozen;
else
{
GrabRec tempGrab;
+ /* Otherwise segfaults happen on grabbed MPX devices */
+ memset(&tempGrab, 0, sizeof(GrabRec));
+
+ tempGrab.next = NULL;
tempGrab.window = pWin;
tempGrab.resource = client->clientAsMask;
tempGrab.ownerEvents = ownerEvents;
@@ -4347,7 +4685,11 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
tempGrab.pointerMode = other_mode;
tempGrab.eventMask = mask;
tempGrab.device = dev;
- (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ tempGrab.cursor = NULL;
+ tempGrab.coreGrab = coreGrab;
+ tempGrab.genericMasks = NULL;
+
+ (*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
*status = GrabSuccess;
}
return Success;
@@ -4356,7 +4698,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
/**
* Server-side protocol handling for GrabKeyboard request.
*
- * Grabs the inputInfo.keyboad and returns success status to client.
+ * Grabs the client's keyboard and returns success status to client.
*/
int
ProcGrabKeyboard(ClientPtr client)
@@ -4364,13 +4706,14 @@ ProcGrabKeyboard(ClientPtr client)
xGrabKeyboardReply rep;
REQUEST(xGrabKeyboardReq);
int result;
+ DeviceIntPtr keyboard = PickKeyboard(client);
REQUEST_SIZE_MATCH(xGrabKeyboardReq);
- result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
- stuff->pointerMode, stuff->grabWindow,
- stuff->ownerEvents, stuff->time,
- KeyPressMask | KeyReleaseMask, &rep.status);
+ result = GrabDevice(client, keyboard, stuff->keyboardMode,
+ stuff->pointerMode, stuff->grabWindow,
+ stuff->ownerEvents, stuff->time,
+ KeyPressMask | KeyReleaseMask, &rep.status, TRUE);
if (result != Success)
return result;
@@ -4384,38 +4727,42 @@ ProcGrabKeyboard(ClientPtr client)
/**
* Server-side protocol handling for UngrabKeyboard request.
*
- * Deletes a possible grab on the inputInfo.keyboard.
+ * Deletes a possible grab on the client's keyboard.
*/
int
ProcUngrabKeyboard(ClientPtr client)
{
- DeviceIntPtr device = inputInfo.keyboard;
+ DeviceIntPtr device = PickKeyboard(client);
GrabPtr grab;
TimeStamp time;
REQUEST(xResourceReq);
REQUEST_SIZE_MATCH(xResourceReq);
UpdateCurrentTime();
- grab = device->grab;
+
+ grab = device->deviceGrab.grab;
+
time = ClientTimeToServerTime(stuff->id);
if ((CompareTimeStamps(time, currentTime) != LATER) &&
- (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
- (grab) && SameClient(grab, client))
- (*device->DeactivateGrab)(device);
+ (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client) && grab->coreGrab)
+ (*device->deviceGrab.DeactivateGrab)(device);
return Success;
}
/**
* Server-side protocol handling for QueryPointer request.
*
- * Returns the current state and position of the core pointer to the client.
+ * Returns the current state and position of the client's ClientPointer to the
+ * client.
*/
int
ProcQueryPointer(ClientPtr client)
{
xQueryPointerReply rep;
WindowPtr pWin, t;
- DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr mouse = PickPointer(client);
+ SpritePtr pSprite;
int rc;
REQUEST(xResourceReq);
REQUEST_SIZE_MATCH(xResourceReq);
@@ -4427,22 +4774,23 @@ ProcQueryPointer(ClientPtr client)
if (rc != Success)
return rc;
+ pSprite = mouse->spriteInfo->sprite;
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.root = (RootWindow(mouse))->drawable.id;
+ rep.rootX = pSprite->hot.x;
+ rep.rootY = pSprite->hot.y;
rep.child = None;
- if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ if (pSprite->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)
+ rep.winX = pSprite->hot.x - pWin->drawable.x;
+ rep.winY = pSprite->hot.y - pWin->drawable.y;
+ for (t = pSprite->win; t; t = t->parent)
if (t->parent == pWin)
{
rep.child = t->drawable.id;
@@ -4469,7 +4817,7 @@ ProcQueryPointer(ClientPtr client)
WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
- return(Success);
+ return(Success);
}
/**
@@ -4481,32 +4829,18 @@ InitEvents(void)
{
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)
+ lastEventMask = OwnerGrabButtonMask;
+ filters[0][PointerMotionMask] = MotionNotify;
+ for (i = 1; i < MAXDEVICES; i++)
{
- spriteTraceSize = 32;
- spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
- if (!spriteTrace)
- FatalError("failed to allocate spriteTrace");
+ memcpy(&filters[i], filters[0], sizeof(filters[0]));
}
- 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)
@@ -4527,26 +4861,35 @@ InitEvents(void)
DontPropagateMasks[i] = 0;
DontPropagateRefCnts[i] = 0;
}
+
+ InputEventListLen = GetMaximumEventsNum();
+ InputEventList = InitEventList(InputEventListLen);
+ if (!InputEventList)
+ FatalError("[dix] Failed to allocate input event list.\n");
}
void
CloseDownEvents(void)
{
- xfree(spriteTrace);
- spriteTrace = NULL;
- spriteTraceSize = 0;
+ int len;
+ EventListPtr list;
+
+ len = GetEventList(&list);
+ while(len--)
+ xfree(list[len].event);
}
/**
* Server-side protocol handling for SendEvent request.
*
- * Locates the window to send the event to and forwards the event.
+ * Locates the window to send the event to and forwards the event.
*/
int
ProcSendEvent(ClientPtr client)
{
WindowPtr pWin;
WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite;
REQUEST(xSendEventReq);
REQUEST_SIZE_MATCH(xSendEventReq);
@@ -4555,7 +4898,7 @@ ProcSendEvent(ClientPtr client)
extension. */
if ( ! ((stuff->event.u.u.type > X_Reply &&
- stuff->event.u.u.type < LASTEvent) ||
+ stuff->event.u.u.type < LASTEvent) ||
(stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
stuff->event.u.u.type < (unsigned)lastEvent)))
{
@@ -4577,7 +4920,7 @@ ProcSendEvent(ClientPtr client)
}
if (stuff->destination == PointerWindow)
- pWin = sprite.win;
+ pWin = pSprite->win;
else if (stuff->destination == InputFocus)
{
WindowPtr inputFocus = inputInfo.keyboard->focus->win;
@@ -4587,13 +4930,13 @@ ProcSendEvent(ClientPtr client)
/* 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 (inputFocus == PointerRootWin)
+ inputFocus = pSprite->spriteTrace[0]; /* Root window! */
- if (IsParent(inputFocus, sprite.win))
+ if (IsParent(inputFocus, pSprite->win))
{
effectiveFocus = inputFocus;
- pWin = sprite.win;
+ pWin = pSprite->win;
}
else
effectiveFocus = pWin = inputFocus;
@@ -4616,8 +4959,8 @@ ProcSendEvent(ClientPtr client)
if (XaceHook(XACE_SEND_ACCESS, client, NULL, pWin,
&stuff->event, 1))
return Success;
- if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
- NullGrab, 0))
+ if (DeliverEventsToWindow(PickPointer(client), pWin,
+ &stuff->event, 1, stuff->eventMask, NullGrab, 0))
return Success;
if (pWin == effectiveFocus)
return Success;
@@ -4627,16 +4970,16 @@ ProcSendEvent(ClientPtr client)
}
}
else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1))
- (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
- NullGrab, 0);
+ (void)DeliverEventsToWindow(PickPointer(client), pWin, &stuff->event,
+ 1, stuff->eventMask, NullGrab, 0);
return Success;
}
/**
* Server-side protocol handling for UngrabKey request.
*
- * Deletes a passive grab for the given key. Only works on the
- * inputInfo.keyboard.
+ * Deletes a passive grab for the given key. Works on the
+ * client's keyboard.
*/
int
ProcUngrabKey(ClientPtr client)
@@ -4644,7 +4987,7 @@ ProcUngrabKey(ClientPtr client)
REQUEST(xUngrabKeyReq);
WindowPtr pWin;
GrabRec tempGrab;
- DeviceIntPtr keybd = inputInfo.keyboard;
+ DeviceIntPtr keybd = PickKeyboard(client);
int rc;
REQUEST_SIZE_MATCH(xUngrabKeyReq);
@@ -4674,6 +5017,7 @@ ProcUngrabKey(ClientPtr client)
tempGrab.type = KeyPress;
tempGrab.detail.exact = stuff->key;
tempGrab.detail.pMask = NULL;
+ tempGrab.next = NULL;
if (!DeletePassiveGrabFromList(&tempGrab))
return(BadAlloc);
@@ -4683,8 +5027,8 @@ ProcUngrabKey(ClientPtr client)
/**
* Server-side protocol handling for GrabKey request.
*
- * Creates a grab for the inputInfo.keyboard and adds it to the list of
- * passive grabs.
+ * Creates a grab for the client's keyboard and adds it to the list of passive
+ * grabs.
*/
int
ProcGrabKey(ClientPtr client)
@@ -4692,7 +5036,7 @@ ProcGrabKey(ClientPtr client)
WindowPtr pWin;
REQUEST(xGrabKeyReq);
GrabPtr grab;
- DeviceIntPtr keybd = inputInfo.keyboard;
+ DeviceIntPtr keybd = PickKeyboard(client);
int rc;
REQUEST_SIZE_MATCH(xGrabKeyReq);
@@ -4730,10 +5074,10 @@ ProcGrabKey(ClientPtr client)
if (rc != Success)
return rc;
- grab = CreateGrab(client->index, keybd, pWin,
+ grab = CreateGrab(client->index, keybd, pWin,
(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
- keybd, stuff->modifiers, KeyPress, stuff->key,
+ keybd, stuff->modifiers, KeyPress, stuff->key,
NullWindow, NullCursor);
if (!grab)
return BadAlloc;
@@ -4744,8 +5088,8 @@ ProcGrabKey(ClientPtr client)
/**
* Server-side protocol handling for GrabButton request.
*
- * Creates a grab for the inputInfo.pointer and adds it as a passive grab to
- * the list.
+ * Creates a grab for the client's ClientPointer and adds it as a passive grab
+ * to the list.
*/
int
ProcGrabButton(ClientPtr client)
@@ -4754,6 +5098,7 @@ ProcGrabButton(ClientPtr client)
REQUEST(xGrabButtonReq);
CursorPtr cursor;
GrabPtr grab;
+ DeviceIntPtr ptr, modifierDevice;
Mask access_mode = DixGrabAccess;
int rc;
@@ -4811,17 +5156,20 @@ ProcGrabButton(ClientPtr client)
}
access_mode |= DixForceAccess;
}
+
+ ptr = PickPointer(client);
+ modifierDevice = GetPairedDevice(ptr);
if (stuff->pointerMode == GrabModeSync ||
stuff->keyboardMode == GrabModeSync)
access_mode |= DixFreezeAccess;
- rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.pointer, access_mode);
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, access_mode);
if (rc != Success)
return rc;
- grab = CreateGrab(client->index, inputInfo.pointer, pWin,
+ grab = CreateGrab(client->index, ptr, pWin,
(Mask)stuff->eventMask, (Bool)stuff->ownerEvents,
(Bool) stuff->keyboardMode, (Bool)stuff->pointerMode,
- inputInfo.keyboard, stuff->modifiers, ButtonPress,
+ modifierDevice, stuff->modifiers, ButtonPress,
stuff->button, confineTo, cursor);
if (!grab)
return BadAlloc;
@@ -4831,7 +5179,7 @@ ProcGrabButton(ClientPtr client)
/**
* Server-side protocol handling for UngrabButton request.
*
- * Deletes a passive grab on the inputInfo.pointer from the list.
+ * Deletes a passive grab on the client's ClientPointer from the list.
*/
int
ProcUngrabButton(ClientPtr client)
@@ -4852,7 +5200,7 @@ ProcUngrabButton(ClientPtr client)
if (rc != Success)
return rc;
tempGrab.resource = client->clientAsMask;
- tempGrab.device = inputInfo.pointer;
+ tempGrab.device = PickPointer(client);
tempGrab.window = pWin;
tempGrab.modifiersDetail.exact = stuff->modifiers;
tempGrab.modifiersDetail.pMask = NULL;
@@ -4860,6 +5208,7 @@ ProcUngrabButton(ClientPtr client)
tempGrab.type = ButtonPress;
tempGrab.detail.exact = stuff->button;
tempGrab.detail.pMask = NULL;
+ tempGrab.next = NULL;
if (!DeletePassiveGrabFromList(&tempGrab))
return(BadAlloc);
@@ -4883,73 +5232,95 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
WindowPtr parent;
DeviceIntPtr mouse = inputInfo.pointer;
DeviceIntPtr keybd = inputInfo.keyboard;
- FocusClassPtr focus = keybd->focus;
+ FocusClassPtr focus;
OtherClientsPtr oc;
GrabPtr passive;
+ GrabPtr grab;
/* Deactivate any grabs performed on this window, before making any
input focus changes. */
+ grab = mouse->deviceGrab.grab;
+ if (grab &&
+ ((grab->window == pWin) || (grab->confineTo == pWin)))
+ (*mouse->deviceGrab.DeactivateGrab)(mouse);
- if (mouse->grab &&
- ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
- (*mouse->DeactivateGrab)(mouse);
/* Deactivating a keyboard grab should cause focus events. */
+ grab = keybd->deviceGrab.grab;
+ if (grab && (grab->window == pWin))
+ (*keybd->deviceGrab.DeactivateGrab)(keybd);
- 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))
+ /* And now the real devices */
+ for (mouse = inputInfo.devices; mouse; mouse = mouse->next)
{
- int focusEventMode = NotifyNormal;
-
- /* If a grab is in progress, then alter the mode of focus events. */
+ grab = mouse->deviceGrab.grab;
+ if (grab && ((grab->window == pWin) || (grab->confineTo == pWin)))
+ (*mouse->deviceGrab.DeactivateGrab)(mouse);
+ }
- 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
- */
+ for (keybd = inputInfo.devices; keybd; keybd = keybd->next)
+ {
+ if (IsKeyboardDevice(keybd))
+ {
+ focus = keybd->focus;
+
+ /* 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->deviceGrab.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
+ || 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;
- }
- }
+ );
+ 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 (IsPointerDevice(keybd))
+ {
+ if (keybd->valuator->motionHintWindow == pWin)
+ keybd->valuator->motionHintWindow = NullWindow;
+ }
+ }
if (freeResources)
{
@@ -4960,9 +5331,8 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
while ( (passive = wPassiveGrabs(pWin)) )
FreeResource(passive->resource, RT_NONE);
}
-#ifdef XINPUT
+
DeleteWindowFromAnyExtEvents(pWin, freeResources);
-#endif
}
/**
@@ -4973,19 +5343,27 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
_X_EXPORT void
CheckCursorConfinement(WindowPtr pWin)
{
- GrabPtr grab = inputInfo.pointer->grab;
+ GrabPtr grab;
WindowPtr confineTo;
+ DeviceIntPtr pDev;
#ifdef PANORAMIX
if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
#endif
- if (grab && (confineTo = grab->confineTo))
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
{
- if (!BorderSizeNotEmpty(confineTo))
- (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
- else if ((pWin == confineTo) || IsParent(pWin, confineTo))
- ConfineCursorToWindow(confineTo, TRUE, TRUE);
+ if (DevHasCursor(pDev))
+ {
+ grab = pDev->deviceGrab.grab;
+ if (grab && (confineTo = grab->confineTo))
+ {
+ if (!BorderSizeNotEmpty(pDev, confineTo))
+ (*inputInfo.pointer->deviceGrab.DeactivateGrab)(pDev);
+ else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+ ConfineCursorToWindow(pDev, confineTo, TRUE, TRUE);
+ }
+ }
}
}
@@ -5013,7 +5391,8 @@ ProcRecolorCursor(ClientPtr client)
CursorPtr pCursor;
int rc, nscr;
ScreenPtr pscr;
- Bool displayed;
+ Bool displayed;
+ SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite;
REQUEST(xRecolorCursorReq);
REQUEST_SIZE_MATCH(xRecolorCursorReq);
@@ -5038,12 +5417,12 @@ ProcRecolorCursor(ClientPtr client)
pscr = screenInfo.screens[nscr];
#ifdef PANORAMIX
if(!noPanoramiXExtension)
- displayed = (pscr == sprite.screen);
+ displayed = (pscr == pSprite->screen);
else
#endif
- displayed = (pscr == sprite.hotPhys.pScreen);
- ( *pscr->RecolorCursor)(pscr, pCursor,
- (pCursor == sprite.current) && displayed);
+ displayed = (pscr == pSprite->hotPhys.pScreen);
+ ( *pscr->RecolorCursor)(PickPointer(client), pscr, pCursor,
+ (pCursor == pSprite->current) && displayed);
}
return (Success);
}
@@ -5054,10 +5433,10 @@ ProcRecolorCursor(ClientPtr client)
* the given event type.
*
* In the case of DeviceMotionNotify trailed by DeviceValuators, the events
- * can be more than one. Usually it's just one event.
+ * can be more than one. Usually it's just one event.
*
* Do not modify the event structure passed in. See comment below.
- *
+ *
* @param pClient Client to send events to.
* @param count Number of events.
* @param events The event list.
@@ -5068,8 +5447,9 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
#ifdef PANORAMIX
xEvent eventCopy;
#endif
- xEvent eventTo, *eventFrom;
- int i;
+ xEvent *eventTo, *eventFrom;
+ int i,
+ eventlength = sizeof(xEvent);
#ifdef XKB
if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
@@ -5077,8 +5457,8 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
#endif
#ifdef PANORAMIX
- if(!noPanoramiXExtension &&
- (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
+ if(!noPanoramiXExtension &&
+ (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
{
switch(events->u.u.type) {
case MotionNotify:
@@ -5088,17 +5468,17 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
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
+ 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)
+ if(eventCopy.u.keyButtonPointer.event ==
+ eventCopy.u.keyButtonPointer.root)
{
eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
@@ -5125,21 +5505,273 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
XSERVER_SEND_EVENT(pClient->index, events[i].u.u.type, &events[i]);
}
}
-#endif
+#endif
+ /* Just a safety check to make sure we only have one GenericEvent, it just
+ * makes things easier for me right now. (whot) */
+ for (i = 1; i < count; i++)
+ {
+ if (events[i].u.u.type == GenericEvent)
+ {
+ ErrorF("[dix] TryClientEvents: Only one GenericEvent at a time.\n");
+ return;
+ }
+ }
+
+ if (events->u.u.type == GenericEvent)
+ {
+ eventlength += ((xGenericEvent*)events)->length * 4;
+ }
+
if(pClient->swapped)
{
+ if (eventlength > swapEventLen)
+ {
+ swapEventLen = eventlength;
+ swapEvent = Xrealloc(swapEvent, swapEventLen);
+ if (!swapEvent)
+ {
+ FatalError("WriteEventsToClient: Out of memory.\n");
+ return;
+ }
+ }
+
for(i = 0; i < count; i++)
{
eventFrom = &events[i];
+ eventTo = swapEvent;
+
/* 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);
+ (eventFrom, eventTo);
+
+ (void)WriteToClient(pClient, eventlength, (char *)eventTo);
}
}
else
{
- (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+ /* only one GenericEvent, remember? that means either count is 1 and
+ * eventlength is arbitrary or eventlength is 32 and count doesn't
+ * matter. And we're all set. Woohoo. */
+ (void)WriteToClient(pClient, count * eventlength, (char *) events);
+ }
+}
+
+/*
+ * Set the client pointer for the given client. Second parameter setter could
+ * be used in the future to determine access rights. Unused for now.
+ *
+ * A client can have exactly one ClientPointer. Each time a
+ * request/reply/event is processed and the choice of devices is ambiguous
+ * (e.g. QueryPointer request), the server will pick the ClientPointer (see
+ * PickPointer()).
+ * If a keyboard is needed, the first keyboard paired with the CP is used.
+ */
+_X_EXPORT Bool
+SetClientPointer(ClientPtr client, ClientPtr setter, DeviceIntPtr device)
+{
+ if (!device->isMaster)
+ {
+ ErrorF("[dix] Need master device for ClientPointer. This is a bug.\n");
+ return FALSE;
+ } else if (!device->spriteInfo->spriteOwner)
+ {
+ ErrorF("[dix] Device %d does not have a sprite. "
+ "Cannot be ClientPointer\n", device->id);
+ return FALSE;
}
+ client->clientPtr = device;
+ return TRUE;
}
+
+/* PickPointer will pick an appropriate pointer for the given client.
+ *
+ * An "appropriate device" is (in order of priority):
+ * 1) A device the given client has a core grab on.
+ * 2) A device set as ClientPointer for the given client.
+ * 3) The first master device.
+ */
+_X_EXPORT DeviceIntPtr
+PickPointer(ClientPtr client)
+{
+ DeviceIntPtr it = inputInfo.devices;
+
+ /* First, check if the client currently has a grab on a device. Even
+ * keyboards count. */
+ for(it = inputInfo.devices; it; it = it->next)
+ {
+ GrabPtr grab = it->deviceGrab.grab;
+ if (grab && grab->coreGrab && SameClient(grab, client))
+ {
+ if (!IsPointerDevice(it))
+ it = GetPairedDevice(it);
+ return it; /* Always return a core grabbed device */
+ }
+ }
+
+ if (!client->clientPtr)
+ {
+ DeviceIntPtr it = inputInfo.devices;
+ while (it)
+ {
+ if (it->isMaster && it->spriteInfo->spriteOwner)
+ {
+ client->clientPtr = it;
+ break;
+ }
+ it = it->next;
+ }
+ }
+ return client->clientPtr;
+}
+
+/* PickKeyboard will pick an appropriate keyboard for the given client by
+ * searching the list of devices for the keyboard device that is paired with
+ * the client's pointer.
+ */
+_X_EXPORT DeviceIntPtr
+PickKeyboard(ClientPtr client)
+{
+ DeviceIntPtr ptr = PickPointer(client);
+ DeviceIntPtr kbd = ptr->spriteInfo->paired;
+
+ if (!kbd)
+ {
+ ErrorF("[dix] ClientPointer not paired with a keyboard. This "
+ "is a bug.\n");
+ }
+
+ return kbd;
+}
+
+/* A client that has one or more core grabs does not get core events from
+ * devices it does not have a grab on. Legacy applications behave bad
+ * otherwise because they are not used to it and the events interfere.
+ * Only applies for core events.
+ *
+ * Return true if a core event from the device would interfere and should not
+ * be delivered.
+ */
+Bool
+IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event)
+{
+ DeviceIntPtr it = inputInfo.devices;
+
+ if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client))
+ return FALSE;
+
+ switch(event->u.u.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case EnterNotify:
+ case LeaveNotify:
+ break;
+ default:
+ return FALSE;
+ }
+
+ while(it)
+ {
+ if (it != dev)
+ {
+ if (it->deviceGrab.grab && SameClient(it->deviceGrab.grab, client)
+ && !it->deviceGrab.fromPassiveGrab)
+ {
+ if ((IsPointerDevice(it) && IsPointerDevice(dev)) ||
+ (IsKeyboardDevice(it) && IsKeyboardDevice(dev)))
+ return TRUE;
+ }
+ }
+ it = it->next;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Set the filters for a extension.
+ * The filters array needs to contain the Masks that are applicable for each
+ * event type for the given extension.
+ * e.g. if generic event type 2 should be let through for windows with
+ * MyExampleMask set, make sure that filters[2] == MyExampleMask.
+ */
+_X_EXPORT void
+SetGenericFilter(int extension, Mask* filters)
+{
+ generic_filters[extension & 0x7f] = filters;
+}
+
+
+/**
+ * Grab a device for XI events and XGE events.
+ * grabmode is used to ungrab a device.
+ */
+_X_EXPORT int
+ExtGrabDevice(ClientPtr client,
+ DeviceIntPtr dev,
+ int device_mode,
+ WindowPtr grabWindow,
+ WindowPtr confineTo,
+ TimeStamp ctime,
+ Bool ownerEvents,
+ CursorPtr cursor,
+ Mask xi_mask,
+ GenericMaskPtr ge_masks)
+{
+ GrabInfoPtr grabinfo;
+ GrabRec newGrab;
+
+ UpdateCurrentTime();
+
+ grabinfo = &dev->deviceGrab;
+
+ if (grabinfo->grab && !SameClient(grabinfo->grab, client))
+ return AlreadyGrabbed;
+
+ if (!grabWindow->realized)
+ return GrabNotViewable;
+
+ if ((CompareTimeStamps(ctime, currentTime) == LATER) ||
+ (CompareTimeStamps(ctime, grabinfo->grabTime) == EARLIER))
+ return GrabInvalidTime;
+
+ if (grabinfo->sync.frozen && grabinfo->sync.other &&
+ !SameClient(grabinfo->sync.other, client))
+ return GrabFrozen;
+
+ memset(&newGrab, 0, sizeof(GrabRec));
+ newGrab.window = grabWindow;
+ newGrab.resource = client->clientAsMask;
+ newGrab.ownerEvents = ownerEvents;
+ newGrab.device = dev;
+ newGrab.cursor = cursor;
+ newGrab.confineTo = confineTo;
+ newGrab.eventMask = xi_mask;
+ newGrab.genericMasks = NULL;
+ newGrab.next = NULL;
+
+ if (ge_masks)
+ {
+ newGrab.genericMasks = xcalloc(1, sizeof(GenericMaskRec));
+ *newGrab.genericMasks = *ge_masks;
+ newGrab.genericMasks->next = NULL;
+ }
+
+ if (IsPointerDevice(dev))
+ {
+ newGrab.keyboardMode = GrabModeAsync;
+ newGrab.pointerMode = device_mode;
+ } else
+ {
+ newGrab.keyboardMode = device_mode;
+ newGrab.pointerMode = GrabModeAsync;
+ }
+
+ (*grabinfo->ActivateGrab)(dev, &newGrab, ctime, FALSE);
+ return GrabSuccess;
+}
+
diff --git a/xorg-server/dix/extension.c b/xorg-server/dix/extension.c
index 9740c1b50..3070f4da1 100644
--- a/xorg-server/dix/extension.c
+++ b/xorg-server/dix/extension.c
@@ -63,8 +63,6 @@ SOFTWARE.
#include "registry.h"
#include "xace.h"
-#define EXTENSION_BASE 128
-#define EXTENSION_EVENT_BASE 64
#define LAST_EVENT 128
#define LAST_ERROR 255
@@ -84,7 +82,7 @@ AddExtension(char *name, int NumEvents, int NumErrors,
int i;
ExtensionEntry *ext, **newexts;
- if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+ if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
return((ExtensionEntry *) NULL);
if ((lastEvent + NumEvents > LAST_EVENT) ||
(unsigned)(lastError + NumErrors > LAST_ERROR))
@@ -247,7 +245,8 @@ CloseDownExtensions(void)
for (i = NumExtensions - 1; i >= 0; i--)
{
- (* extensions[i]->CloseDown)(extensions[i]);
+ if (extensions[i]->CloseDown)
+ extensions[i]->CloseDown(extensions[i]);
NumExtensions = i;
xfree(extensions[i]->name);
for (j = extensions[i]->num_aliases; --j >= 0;)
diff --git a/xorg-server/dix/ffs.c b/xorg-server/dix/ffs.c
index b75657d29..d0bd3e507 100644
--- a/xorg-server/dix/ffs.c
+++ b/xorg-server/dix/ffs.c
@@ -30,6 +30,8 @@ The Open Group.
#include <dix-config.h>
#endif
+#ifndef HAVE_FFS
+
#include "dix.h"
int
@@ -42,3 +44,5 @@ ffs(int i)
i >>= 1;
return j;
}
+
+#endif
diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c
index 83f48d4e3..b9256940d 100644
--- a/xorg-server/dix/gc.c
+++ b/xorg-server/dix/gc.c
@@ -1049,7 +1049,7 @@ FreeDefaultStipple(int screenNum)
(*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
}
-_X_EXPORT int
+int
SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
{
long i;
@@ -1155,7 +1155,7 @@ VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
return -1;
}
-_X_EXPORT int
+int
SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
xRectangle *prects, int ordering)
{
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index 1e0edbf00..9747b35a6 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -47,7 +47,6 @@
#ifdef XKB
#include <X11/extensions/XKBproto.h>
#include <xkbsrv.h>
-extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
#endif
#ifdef PANORAMIX
@@ -62,14 +61,22 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
#include "exglobals.h"
#include "extnsionst.h"
-
-/* Maximum number of valuators, divided by six, rounded up, to get number
- * of events. */
-#define MAX_VALUATOR_EVENTS 6
-
/* Number of motion history events to store. */
#define MOTION_HISTORY_SIZE 256
+/* InputEventList is the container list for all input events generated by the
+ * DDX. The DDX is expected to call GetEventList() and then pass the list into
+ * Get{Pointer|Keyboard}Events.
+ */
+EventListPtr InputEventList = NULL;
+int InputEventListLen = 0;
+
+_X_EXPORT int
+GetEventList(EventListPtr* list)
+{
+ *list = InputEventList;
+ return InputEventListLen;
+}
/**
* Pick some arbitrary size for Xi motion history.
@@ -106,43 +113,151 @@ key_autorepeats(DeviceIntPtr pDev, int key_code)
}
/**
+ * Rescale the coord between the two axis ranges.
+ */
+static int
+rescaleValuatorAxis(int coord, AxisInfoPtr from, AxisInfoPtr to,
+ int defmax)
+{
+ int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax;
+
+ if(from && from->min_value < from->max_value) {
+ fmin = from->min_value;
+ fmax = from->max_value;
+ }
+ if(to && to->min_value < to->max_value) {
+ tmin = to->min_value;
+ tmax = to->max_value;
+ }
+
+ if(fmin == tmin && fmax == tmax)
+ return coord;
+
+ if(fmax == fmin) /* avoid division by 0 */
+ return 0;
+
+ return roundf(((float)(coord - fmin)) * (tmax - tmin) /
+ (fmax - fmin)) + tmin;
+}
+
+/**
+ * Update all coordinates when changing to a different SD
+ * to ensure that relative reporting will work as expected
+ * without loss of precision.
+ *
+ * pDev->last.valuators will be in absolute device coordinates after this
+ * function.
+ */
+static void
+updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
+{
+ ScreenPtr scr = miPointerGetScreen(pDev);
+ int i;
+ DeviceIntPtr lastSlave;
+
+ /* master->last.valuators[0]/[1] is in screen coords and the actual
+ * position of the pointer */
+ pDev->last.valuators[0] = master->last.valuators[0];
+ pDev->last.valuators[1] = master->last.valuators[1];
+
+ if (!pDev->valuator)
+ return;
+
+ /* scale back to device coordinates */
+ if(pDev->valuator->numAxes > 0)
+ pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL, pDev->valuator->axes + 0, scr->width);
+ if(pDev->valuator->numAxes > 1)
+ pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL, pDev->valuator->axes + 1, scr->height);
+
+ /* calculate the other axis as well based on info from the old
+ * slave-device. If the old slave had less axes than this one,
+ * last.valuators is reset to 0.
+ */
+ if ((lastSlave = master->u.lastSlave) && lastSlave->valuator) {
+ for (i = 2; i < pDev->valuator->numAxes; i++) {
+ if (i >= lastSlave->valuator->numAxes)
+ pDev->last.valuators[i] = 0;
+ else
+ pDev->last.valuators[i] =
+ rescaleValuatorAxis(pDev->last.valuators[i],
+ lastSlave->valuator->axes + i,
+ pDev->valuator->axes + i, 0);
+ }
+ }
+
+}
+
+/**
* Allocate the motion history buffer.
*/
_X_EXPORT void
AllocateMotionHistory(DeviceIntPtr pDev)
{
+ int size;
if (pDev->valuator->motion)
xfree(pDev->valuator->motion);
if (pDev->valuator->numMotionEvents < 1)
return;
- pDev->valuator->motion = xalloc(((sizeof(INT32) * pDev->valuator->numAxes) +
- sizeof(Time)) *
- pDev->valuator->numMotionEvents);
+ /* An MD must have a motion history size large enough to keep all
+ * potential valuators, plus the respective range of the valuators.
+ * 3 * INT32 for (min_val, max_val, curr_val))
+ */
+ if (pDev->isMaster)
+ size = sizeof(INT32) * 3 * MAX_VALUATORS;
+ else
+ size = sizeof(INT32) * pDev->valuator->numAxes;
+
+ size += sizeof(Time);
+
+ pDev->valuator->motion = xcalloc(pDev->valuator->numMotionEvents, size);
pDev->valuator->first_motion = 0;
pDev->valuator->last_motion = 0;
+ if (!pDev->valuator->motion)
+ ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
+ pDev->name, size * pDev->valuator->numMotionEvents);
}
-
/**
* Dump the motion history between start and stop into the supplied buffer.
* Only records the event for a given screen in theory, but in practice, we
* sort of ignore this.
+ *
+ * If core is set, we only generate x/y, in INT16, scaled to screen coords.
*/
_X_EXPORT int
-GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start,
- unsigned long stop, ScreenPtr pScreen)
+GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
+ unsigned long stop, ScreenPtr pScreen, BOOL core)
{
- char *ibuff = NULL, *obuff = (char *) buff;
+ char *ibuff = NULL, *obuff;
int i = 0, ret = 0;
+ int j, coord;
Time current;
/* The size of a single motion event. */
- int size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+ int size;
+ int dflt;
+ AxisInfo from, *to; /* for scaling */
+ INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */
+ INT16 *corebuf;
+ AxisInfo core_axis = {0};
if (!pDev->valuator || !pDev->valuator->numMotionEvents)
return 0;
+ if (core && !pScreen)
+ return 0;
+
+ if (pDev->isMaster)
+ size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
+ else
+ size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+
+ *buff = xalloc(size * pDev->valuator->numMotionEvents);
+ if (!(*buff))
+ return 0;
+ obuff = (char *)*buff;
+
for (i = pDev->valuator->first_motion;
i != pDev->valuator->last_motion;
i = (i + 1) % pDev->valuator->numMotionEvents) {
@@ -156,8 +271,80 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start,
return ret;
}
else if (current >= start) {
- memcpy(obuff, ibuff, size);
- obuff += size;
+ if (core)
+ {
+ memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+ icbuf = (INT32*)(ibuff + sizeof(Time));
+ corebuf = (INT16*)(obuff + sizeof(Time));
+
+ /* fetch x coordinate + range */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ /* scale to screen coords */
+ to = &core_axis;
+ to->max_value = pScreen->width;
+ coord = rescaleValuatorAxis(coord, &from, to, pScreen->width);
+
+ memcpy(corebuf, &coord, sizeof(INT16));
+ corebuf++;
+
+ /* fetch y coordinate + range */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ to->max_value = pScreen->height;
+ coord = rescaleValuatorAxis(coord, &from, to, pScreen->height);
+ memcpy(corebuf, &coord, sizeof(INT16));
+
+ } else if (pDev->isMaster)
+ {
+ memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+ ocbuf = (INT32*)(obuff + sizeof(Time));
+ icbuf = (INT32*)(ibuff + sizeof(Time));
+ for (j = 0; j < MAX_VALUATORS; j++)
+ {
+ if (j >= pDev->valuator->numAxes)
+ break;
+
+ /* fetch min/max/coordinate */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL;
+
+ /* x/y scaled to screen if no range is present */
+ if (j == 0 && (from.max_value < from.min_value))
+ from.max_value = pScreen->width;
+ else if (j == 1 && (from.max_value < from.min_value))
+ from.max_value = pScreen->height;
+
+ if (j == 0 && (to->max_value < to->min_value))
+ dflt = pScreen->width;
+ else if (j == 1 && (to->max_value < to->min_value))
+ dflt = pScreen->height;
+ else
+ dflt = 0;
+
+ /* scale from stored range into current range */
+ coord = rescaleValuatorAxis(coord, &from, to, 0);
+ memcpy(ocbuf, &coord, sizeof(INT32));
+ ocbuf++;
+ }
+ } else
+ memcpy(obuff, ibuff, size);
+
+ /* don't advance by size here. size may be different to the
+ * actually written size if the MD has less valuators than MAX */
+ if (core)
+ obuff += sizeof(INT32) + sizeof(Time);
+ else
+ obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
ret++;
}
}
@@ -169,29 +356,65 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start,
/**
* Update the motion history for a specific device, with the list of
* valuators.
+ *
+ * Layout of the history buffer:
+ * for SDs: [time] [val0] [val1] ... [valn]
+ * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
+ *
+ * For events that have some valuators unset (first_valuator > 0):
+ * min_val == max_val == val == 0.
*/
static void
updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
int num_valuators, int *valuators)
{
char *buff = (char *) pDev->valuator->motion;
+ ValuatorClassPtr v;
+ int i;
if (!pDev->valuator->numMotionEvents)
return;
- buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
+ v = pDev->valuator;
+ if (pDev->isMaster)
+ {
+ buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
+ v->last_motion;
+
+ memcpy(buff, &ms, sizeof(Time));
+ buff += sizeof(Time);
+
+ memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
+ buff += 3 * sizeof(INT32) * first_valuator;
+
+ for (i = first_valuator; i < first_valuator + num_valuators; i++)
+ {
+ if (i >= v->numAxes)
+ break;
+ memcpy(buff, &v->axes[i].min_value, sizeof(INT32));
+ buff += sizeof(INT32);
+ memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
+ buff += sizeof(INT32);
+ memcpy(buff, &valuators[i - first_valuator], sizeof(INT32));
+ buff += sizeof(INT32);
+ }
+ } else
+ {
+
+ buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
pDev->valuator->last_motion;
- memcpy(buff, &ms, sizeof(Time));
- buff += sizeof(Time);
- bzero(buff, sizeof(INT32) * pDev->valuator->numAxes);
+ memcpy(buff, &ms, sizeof(Time));
+ buff += sizeof(Time);
- buff += sizeof(INT32) * first_valuator;
- memcpy(buff, valuators, sizeof(INT32) * num_valuators);
+ memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
+ buff += sizeof(INT32) * first_valuator;
- pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
- pDev->valuator->numMotionEvents;
+ memcpy(buff, valuators, sizeof(INT32) * num_valuators);
+ }
+ pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
+ pDev->valuator->numMotionEvents;
/* If we're wrapping around, just keep the circular buffer going. */
if (pDev->valuator->first_motion == pDev->valuator->last_motion)
pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
@@ -212,9 +435,9 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
*/
_X_EXPORT int
GetMaximumEventsNum(void) {
- /* Two base events -- core and device, plus valuator events. Multiply
- * by two if we're doing non-XKB key repeats. */
- int ret = 2 + MAX_VALUATOR_EVENTS;
+ /* One base event -- device, plus valuator events.
+ * Multiply by two if we're doing non-XKB key repeats. */
+ int ret = 1 + MAX_VALUATOR_EVENTS;
#ifdef XKB
if (noXkbExtension)
@@ -225,80 +448,6 @@ GetMaximumEventsNum(void) {
}
-/* Originally a part of xf86PostMotionEvent; modifies valuators
- * in-place. */
-static void
-acceleratePointer(DeviceIntPtr pDev, int first_valuator, int num_valuators,
- int *valuators)
-{
- float mult = 0.0;
- int dx = 0, dy = 0;
- int *px = NULL, *py = NULL;
-
- if (!num_valuators || !valuators)
- return;
-
- if (first_valuator == 0) {
- dx = valuators[0];
- px = &valuators[0];
- }
- if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
- dy = valuators[1 - first_valuator];
- py = &valuators[1 - first_valuator];
- }
-
- if (!dx && !dy)
- return;
-
- if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
- /* modeled from xf86Events.c */
- if (pDev->ptrfeed->ctrl.threshold) {
- if ((abs(dx) + abs(dy)) >= pDev->ptrfeed->ctrl.threshold) {
- pDev->valuator->dxremaind = ((float)dx *
- (float)(pDev->ptrfeed->ctrl.num)) /
- (float)(pDev->ptrfeed->ctrl.den) +
- pDev->valuator->dxremaind;
- if (px) {
- *px = (int)pDev->valuator->dxremaind;
- pDev->valuator->dxremaind = pDev->valuator->dxremaind -
- (float)(*px);
- }
-
- pDev->valuator->dyremaind = ((float)dy *
- (float)(pDev->ptrfeed->ctrl.num)) /
- (float)(pDev->ptrfeed->ctrl.den) +
- pDev->valuator->dyremaind;
- if (py) {
- *py = (int)pDev->valuator->dyremaind;
- pDev->valuator->dyremaind = pDev->valuator->dyremaind -
- (float)(*py);
- }
- }
- }
- else {
- mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
- ((float)(pDev->ptrfeed->ctrl.num) /
- (float)(pDev->ptrfeed->ctrl.den) - 1.0) /
- 2.0) / 2.0;
- if (dx) {
- pDev->valuator->dxremaind = mult * (float)dx +
- pDev->valuator->dxremaind;
- *px = (int)pDev->valuator->dxremaind;
- pDev->valuator->dxremaind = pDev->valuator->dxremaind -
- (float)(*px);
- }
- if (dy) {
- pDev->valuator->dyremaind = mult * (float)dy +
- pDev->valuator->dyremaind;
- *py = (int)pDev->valuator->dyremaind;
- pDev->valuator->dyremaind = pDev->valuator->dyremaind -
- (float)(*py);
- }
- }
- }
-}
-
-
/**
* Clip an axis to its bounds, which are declared in the call to
* InitValuatorAxisClassStruct.
@@ -306,15 +455,17 @@ acceleratePointer(DeviceIntPtr pDev, int first_valuator, int num_valuators,
static void
clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
{
- AxisInfoPtr axes = pDev->valuator->axes + axisNum;
-
- /* No clipping if the value-range <= 0 */
- if(axes->min_value < axes->min_value) {
- if (*val < axes->min_value)
- *val = axes->min_value;
- if (*val > axes->max_value)
- *val = axes->max_value;
- }
+ AxisInfoPtr axis = pDev->valuator->axes + axisNum;
+ /* InitValuatoraAxisStruct ensures that (min < max). */
+
+ /* If a value range is defined, clip. If not, do nothing */
+ if (axis->max_value <= axis->min_value)
+ return;
+
+ if (*val < axis->min_value)
+ *val = axis->min_value;
+ if (*val > axis->max_value)
+ *val = axis->max_value;
}
/**
@@ -335,23 +486,20 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
/**
* Fills events with valuator events for pDev, as given by the other
* parameters.
- *
- * FIXME: Need to fix ValuatorClassRec to store all the valuators as
- * last posted, not just x and y; otherwise relative non-x/y
- * valuators, though a very narrow use case, will be broken.
*/
-static xEvent *
-getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator,
- int num_valuators, int *valuators) {
- deviceValuator *xv = (deviceValuator *) events;
- int i = 0, final_valuator = first_valuator + num_valuators;
+static EventList *
+getValuatorEvents(EventList *events, DeviceIntPtr pDev,
+ int first_valuator, int num_valuators, int *valuators) {
+ deviceValuator *xv;
+ int i;
- for (i = first_valuator; i < final_valuator; i += 6, xv++, events++) {
+ for (i = 0; i < num_valuators; i += 6, events++) {
+ xv = (deviceValuator*)events->event;
xv->type = DeviceValuator;
- xv->first_valuator = i;
- xv->num_valuators = ((final_valuator - i) > 6) ? 6 : (final_valuator - i);
+ xv->first_valuator = first_valuator + i;
+ xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
xv->deviceid = pDev->id;
- switch (final_valuator - i) {
+ switch (num_valuators - i) {
case 6:
xv->valuator5 = valuators[i + 5];
case 5:
@@ -363,23 +511,235 @@ getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator,
case 2:
xv->valuator1 = valuators[i + 1];
case 1:
- xv->valuator0 = valuators[i];
+ xv->valuator0 = valuators[i + 0];
}
- if (i + 6 < final_valuator)
+ if (i + 6 < num_valuators)
xv->deviceid |= MORE_EVENTS;
}
return events;
}
+/**
+ * Create the DCCE event (does not update the master's device state yet, this
+ * is done in the event processing).
+ * Pull in the coordinates from the MD if necessary.
+ *
+ * @param events Pointer to a pre-allocated event list.
+ * @param dev The slave device that generated an event.
+ * @param num_events The current number of events, returns the number of
+ * events if a DCCE was generated.
+ * @return The updated @events pointer.
+ */
+static EventListPtr
+updateFromMaster(EventListPtr events, DeviceIntPtr dev, int *num_events)
+{
+ DeviceIntPtr master = dev->u.master;
+ if (master && master->u.lastSlave != dev)
+ {
+ updateSlaveDeviceCoords(master, dev);
+ master->u.lastSlave = dev;
+ master->last.numValuators = dev->last.numValuators;
+ }
+ return events;
+}
+
+/**
+ * Move the device's pointer to the position given in the valuators.
+ *
+ * @param dev The device which's pointer is to be moved.
+ * @param x Returns the x position of the pointer after the move.
+ * @param y Returns the y position of the pointer after the move.
+ * @param first The first valuator in @valuators
+ * @param num Total number of valuators in @valuators.
+ * @param valuators Valuator data for each axis between @first and
+ * @first+@num.
+ */
+static void
+moveAbsolute(DeviceIntPtr dev, int *x, int *y,
+ int first, int num, int *valuators)
+{
+ int i;
+
+
+ if (num >= 1 && first == 0)
+ *x = *(valuators + 0);
+ else
+ *x = dev->last.valuators[0];
+
+ if (first <= 1 && num >= (2 - first))
+ *y = *(valuators + 1 - first);
+ else
+ *y = dev->last.valuators[1];
+
+ clipAxis(dev, 0, x);
+ clipAxis(dev, 1, y);
+
+ i = (first > 2) ? 0 : 2;
+ for (; i < num; i++)
+ {
+ dev->last.valuators[i + first] = valuators[i];
+ clipAxis(dev, i, &dev->last.valuators[i + first]);
+ }
+}
+
+/**
+ * Move the device's pointer by the values given in @valuators.
+ *
+ * @param dev The device which's pointer is to be moved.
+ * @param x Returns the x position of the pointer after the move.
+ * @param y Returns the y position of the pointer after the move.
+ * @param first The first valuator in @valuators
+ * @param num Total number of valuators in @valuators.
+ * @param valuators Valuator data for each axis between @first and
+ * @first+@num.
+ */
+static void
+moveRelative(DeviceIntPtr dev, int *x, int *y,
+ int first, int num, int *valuators)
+{
+ int i;
+
+ *x = dev->last.valuators[0];
+ *y = dev->last.valuators[1];
+
+ if (num >= 1 && first == 0)
+ *x += *(valuators +0);
+
+ if (first <= 1 && num >= (2 - first))
+ *y += *(valuators + 1 - first);
+
+ /* if attached, clip both x and y to the defined limits (usually
+ * co-ord space limit). If it is attached, we need x/y to go over the
+ * limits to be able to change screens. */
+ if(dev->u.master) {
+ clipAxis(dev, 0, x);
+ clipAxis(dev, 1, y);
+ }
+
+ /* calc other axes, clip, drop back into valuators */
+ i = (first > 2) ? 0 : 2;
+ for (; i < num; i++)
+ {
+ dev->last.valuators[i + first] += valuators[i];
+ clipAxis(dev, i, &dev->last.valuators[i + first]);
+ valuators[i] = dev->last.valuators[i + first];
+ }
+}
+
+/**
+ * Accelerate the data in valuators based on the device's acceleration scheme.
+ *
+ * @param dev The device which's pointer is to be moved.
+ * @param first The first valuator in @valuators
+ * @param num Total number of valuators in @valuators.
+ * @param valuators Valuator data for each axis between @first and
+ * @first+@num.
+ * @param ms Current time.
+ */
+static void
+accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms)
+{
+ if (dev->valuator->accelScheme.AccelSchemeProc)
+ dev->valuator->accelScheme.AccelSchemeProc(dev, first, num, valuators, ms);
+}
+
+/**
+ * If we have HW cursors, this actually moves the visible sprite. If not, we
+ * just do all the screen crossing, etc.
+ *
+ * We scale from device to screen coordinates here, call
+ * miPointerSetPosition() and then scale back into device coordinates (if
+ * needed). miPSP will change x/y if the screen was crossed.
+ *
+ * @param dev The device to be moved.
+ * @param x Pointer to current x-axis value, may be modified.
+ * @param y Pointer to current y-axis value, may be modified.
+ * @param scr Screen the device's sprite is currently on.
+ * @param screenx Screen x coordinate the sprite is on after the update.
+ * @param screeny Screen y coordinate the sprite is on after the update.
+ */
+static void
+positionSprite(DeviceIntPtr dev, int *x, int *y,
+ ScreenPtr scr, int *screenx, int *screeny)
+{
+ /* scale x&y to screen */
+ *screenx = rescaleValuatorAxis(*x, dev->valuator->axes + 0, NULL, scr->width);
+ *screeny = rescaleValuatorAxis(*y, dev->valuator->axes + 1, NULL, scr->height);
+ dev->last.valuators[0] = *screenx;
+ dev->last.valuators[1] = *screeny;
+
+ /* This takes care of crossing screens for us, as well as clipping
+ * to the current screen. */
+ miPointerSetPosition(dev, &dev->last.valuators[0], &dev->last.valuators[1]);
+
+ if (dev->u.master) {
+ dev->u.master->last.valuators[0] = dev->last.valuators[0];
+ dev->u.master->last.valuators[1] = dev->last.valuators[1];
+ }
+
+ /* Crossed screen? Scale back to device coordiantes */
+ if(*screenx != dev->last.valuators[0])
+ {
+ scr = miPointerGetScreen(dev);
+ *x = rescaleValuatorAxis(dev->last.valuators[0], NULL,
+ dev->valuator->axes + 0, scr->width);
+ *screenx = dev->last.valuators[0];
+ }
+ if(*screeny != dev->last.valuators[1])
+ {
+ scr = miPointerGetScreen(dev);
+ *screeny = dev->last.valuators[1];
+ *y = rescaleValuatorAxis(dev->last.valuators[1], NULL,
+ dev->valuator->axes + 1, scr->height);
+ }
+
+ /* dropy x/y (device coordinates) back into valuators for next event */
+ dev->last.valuators[0] = *x;
+ dev->last.valuators[1] = *y;
+}
+
+/**
+ * Update the motion history for the device and (if appropriate) for its
+ * master device.
+ * @param dev Slave device to update.
+ * @param first First valuator to append to history.
+ * @param num Total number of valuators to append to history.
+ * @param ms Current time
+ */
+static void
+updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
+{
+ updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]);
+ if (dev->u.master)
+ updateMotionHistory(dev->u.master, ms, first, num,
+ &dev->last.valuators[first]);
+}
+
+/**
+ * Calculate how many DeviceValuator events are needed given a number of
+ * valuators.
+ * @param num_valuators Number of valuators to attach to event.
+ * @return the number of DeviceValuator events needed.
+ */
+static int
+countValuatorEvents(int num_valuators)
+{
+ if (num_valuators) {
+ if (((num_valuators - 1) / 6) + 1 > MAX_VALUATOR_EVENTS)
+ num_valuators = MAX_VALUATOR_EVENTS * 6;
+ return ((num_valuators - 1)/ 6) + 1;
+ } else
+ return 0;
+}
/**
* Convenience wrapper around GetKeyboardValuatorEvents, that takes no
* valuators.
*/
_X_EXPORT int
-GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) {
+GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL);
}
@@ -388,6 +748,9 @@ GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) {
* Returns a set of keyboard events for KeyPress/KeyRelease, optionally
* also with valuator events. Handles Xi and XKB.
*
+ * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
+ * event (ProcessOtherEvent).
+ *
* events is not NULL-terminated; the return value is the number of events.
* The DDX is responsible for allocating the event structure in the first
* place via GetMaximumEventsNum(), and for freeing it.
@@ -402,42 +765,29 @@ GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) {
* KeyPresses.
*/
_X_EXPORT int
-GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
+GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
int key_code, int first_valuator,
int num_valuators, int *valuators) {
int numEvents = 0;
CARD32 ms = 0;
- KeySym *map = pDev->key->curKeySyms.map;
+ KeySym *map;
KeySym sym;
deviceKeyButtonPointer *kbp = NULL;
- if (!events)
- return 0;
-
- /* DO NOT WANT */
- if (type != KeyPress && type != KeyRelease)
+ if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
+ (type != KeyPress && type != KeyRelease) ||
+ (key_code < 8 || key_code > 255))
return 0;
- if (!pDev->key || !pDev->focus || !pDev->kbdfeed ||
- (pDev->coreEvents && !inputInfo.keyboard->key))
- return 0;
-
- if (key_code < 8 || key_code > 255)
- return 0;
+ numEvents = 1;
+ map = pDev->key->curKeySyms.map;
sym = map[(key_code - pDev->key->curKeySyms.minKeyCode)
* pDev->key->curKeySyms.mapWidth];
- if (pDev->coreEvents)
- numEvents = 2;
- else
- numEvents = 1;
+ events = updateFromMaster(events, pDev, &numEvents);
- if (num_valuators) {
- if ((num_valuators / 6) + 1 > MAX_VALUATOR_EVENTS)
- num_valuators = MAX_VALUATOR_EVENTS;
- numEvents += (num_valuators / 6) + 1;
- }
+ numEvents += countValuatorEvents(num_valuators);
#ifdef XKB
if (noXkbExtension)
@@ -470,28 +820,21 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
if (noXkbExtension)
#endif
{
- numEvents += GetKeyboardValuatorEvents(events, pDev,
- KeyRelease, key_code,
- first_valuator, num_valuators,
- valuators);
- events += numEvents;
+ int numReleaseEvents;
+
+ numReleaseEvents = GetKeyboardValuatorEvents(events, pDev,
+ KeyRelease, key_code,
+ first_valuator,
+ num_valuators,
+ valuators);
+ numEvents += numReleaseEvents;
+ events += numReleaseEvents;
}
}
ms = GetTimeInMillis();
- if (pDev->coreEvents) {
- events->u.keyButtonPointer.time = ms;
- events->u.u.type = type;
- events->u.u.detail = key_code;
- if (type == KeyPress)
- set_key_down(inputInfo.keyboard, key_code);
- else if (type == KeyRelease)
- set_key_up(inputInfo.keyboard, key_code);
- events++;
- }
-
- kbp = (deviceKeyButtonPointer *) events;
+ kbp = (deviceKeyButtonPointer *) events->event;
kbp->time = ms;
kbp->deviceid = pDev->id;
kbp->detail = key_code;
@@ -515,261 +858,179 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
return numEvents;
}
+/**
+ * Initialize an event list and fill with 32 byte sized events.
+ * This event list is to be passed into GetPointerEvents() and
+ * GetKeyboardEvents().
+ *
+ * @param num_events Number of elements in list.
+ */
+EventListPtr
+InitEventList(int num_events)
+{
+ EventListPtr events;
+ int i;
+
+ events = (EventListPtr)xcalloc(num_events, sizeof(EventList));
+ if (!events)
+ return NULL;
+
+ for (i = 0; i < num_events; i++)
+ {
+ events[i].evlen = sizeof(xEvent);
+ events[i].event = xcalloc(1, sizeof(xEvent));
+ if (!events[i].event)
+ {
+ /* rollback */
+ while(i--)
+ xfree(events[i].event);
+ xfree(events);
+ events = NULL;
+ break;
+ }
+ }
+
+ return events;
+}
+
+/**
+ * Allocs min_size memory for each event in the list.
+ */
+_X_EXPORT void
+SetMinimumEventSize(EventListPtr list, int num_events, int min_size)
+{
+ if (!list)
+ return;
+
+ while(num_events--)
+ {
+ if (list[num_events].evlen < min_size)
+ {
+ list[num_events].evlen = min_size;
+ list[num_events].event = realloc(list[num_events].event, min_size);
+ if (!list[num_events].event)
+ {
+ FatalError("[dix] Failed to set event list's "
+ "min_size to %d.\n", min_size);
+ }
+ }
+ }
+}
+
+/**
+ * Free an event list.
+ *
+ * @param list The list to be freed.
+ * @param num_events Number of elements in list.
+ */
+_X_EXPORT void
+FreeEventList(EventListPtr list, int num_events)
+{
+ if (!list)
+ return;
+ while(num_events--)
+ xfree(list[num_events].event);
+ xfree(list);
+}
/**
- * Generate a series of xEvents (returned in xE) representing pointer
- * motion, or button presses. Xi and XKB-aware.
+ * Generate a series of xEvents (filled into the EventList) representing
+ * pointer motion, or button presses. Xi and XKB-aware.
+ *
+ * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
+ * event (ProcessOtherEvent).
*
* events is not NULL-terminated; the return value is the number of events.
* The DDX is responsible for allocating the event structure in the first
- * place via GetMaximumEventsNum(), and for freeing it.
+ * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
+ *
+ * In the generated events rootX/Y will be in absolute screen coords and
+ * the valuator information in the absolute or relative device coords.
+ *
+ * last.valuators[x] of the device is always in absolute device coords.
+ * last.valuators[x] of the master device is in absolute screen coords.
+ *
+ * master->last.valuators[x] for x > 2 is undefined.
*/
_X_EXPORT int
-GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
+GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
int flags, int first_valuator, int num_valuators,
int *valuators) {
- int num_events = 0, final_valuator = 0;
- CARD32 ms = 0;
+ int num_events = 1;
+ CARD32 ms;
deviceKeyButtonPointer *kbp = NULL;
- DeviceIntPtr cp = inputInfo.pointer;
- int x = 0, y = 0;
- Bool coreOnly = (pDev == inputInfo.pointer);
+ int x, y, /* switches between device and screen coords */
+ cx, cy; /* only screen coordinates */
ScreenPtr scr = miPointerGetScreen(pDev);
- /* Sanity checks. */
- if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
- return 0;
-
- if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
- return 0;
-
- /* FIXME: I guess it should, in theory, be possible to post button events
- * from devices without valuators. */
- if (!pDev->valuator)
- return 0;
-
- if (!coreOnly && pDev->coreEvents)
- num_events = 2;
- else
- num_events = 1;
+ ms = GetTimeInMillis(); /* before pointer update to help precision */
- if (type == MotionNotify && num_valuators <= 0)
+ if (!scr || !pDev->valuator || first_valuator < 0 ||
+ ((num_valuators + first_valuator) > pDev->valuator->numAxes) ||
+ (type != MotionNotify && type != ButtonPress && type != ButtonRelease) ||
+ (type != MotionNotify && !pDev->button) ||
+ (type == MotionNotify && num_valuators <= 0))
return 0;
- /* Do we need to send a DeviceValuator event? */
- if (!coreOnly && num_valuators) {
- if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
- num_valuators = MAX_VALUATOR_EVENTS * 6;
- num_events += ((num_valuators - 1) / 6) + 1;
- }
-
- final_valuator = num_valuators + first_valuator;
-
- /* You fail. */
- if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes)
- return 0;
+ num_events += countValuatorEvents(num_valuators);
- ms = GetTimeInMillis();
+ events = updateFromMaster(events, pDev, &num_events);
- /* Set x and y based on whether this is absolute or relative, and
- * accelerate if we need to. */
- if (flags & POINTER_ABSOLUTE) {
- if (num_valuators >= 1 && first_valuator == 0) {
- x = valuators[0];
- }
- else {
- /* If we're sending core events but didn't provide a value,
- * translate the core value (but use the device coord if
- * it translates to the same coord to preserve sub-pixel
- * coord information). If we're not sending core events use
- * whatever value we have */
- x = pDev->valuator->lastx;
- if(pDev->coreEvents) {
- int min = pDev->valuator->axes[0].min_value;
- int max = pDev->valuator->axes[0].max_value;
- if(min < max) {
- if((int)((float)(x-min)*scr->width/(max-min+1)) != cp->valuator->lastx)
- x = (int)((float)(cp->valuator->lastx)*(max-min+1)/scr->width)+min;
- }
- else
- x = cp->valuator->lastx;
- }
- }
+ if (flags & POINTER_ABSOLUTE)
+ {
+ if (flags & POINTER_SCREEN) /* valuators are in screen coords */
+ {
- if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
- y = valuators[1 - first_valuator];
- }
- else {
- y = pDev->valuator->lasty;
- if(pDev->coreEvents) {
- int min = pDev->valuator->axes[1].min_value;
- int max = pDev->valuator->axes[1].max_value;
- if(min < max) {
- if((int)((float)(y-min)*scr->height/(max-min+1)) != cp->valuator->lasty)
- y = (int)((float)(cp->valuator->lasty)*(max-min+1)/scr->height)+min;
- }
- else
- y = cp->valuator->lasty;
- }
+ valuators[0] = rescaleValuatorAxis(valuators[0], NULL,
+ pDev->valuator->axes + 0,
+ scr->width);
+ valuators[1] = rescaleValuatorAxis(valuators[1], NULL,
+ pDev->valuator->axes + 1,
+ scr->height);
}
- /* Clip both x and y to the defined limits (usually co-ord space limit). */
- clipAxis(pDev, 0, &x);
- clipAxis(pDev, 1, &y);
- }
- else {
+ moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
+ } else {
if (flags & POINTER_ACCELERATE)
- acceleratePointer(pDev, first_valuator, num_valuators,
- valuators);
-
- if (pDev->coreEvents) {
- /* Get and convert the core pointer coordinate space into
- * device coordinates. Use the device coords if it translates
- * into the same position as the core to preserve relative sub-
- * pixel movements from the device. */
- int min = pDev->valuator->axes[0].min_value;
- int max = pDev->valuator->axes[0].max_value;
- if(min < max) {
- x = pDev->valuator->lastx;
- if((int)((float)(x-min)*scr->width/(max-min+1)) != cp->valuator->lastx)
- x = (int)((float)(cp->valuator->lastx)*(max-min+1)/scr->width)+min;
- }
- else
- x = cp->valuator->lastx;
-
- min = pDev->valuator->axes[1].min_value;
- max = pDev->valuator->axes[1].max_value;
- if(min < max) {
- y = pDev->valuator->lasty;
- if((int)((float)(y-min)*scr->height/(max-min+1)) != cp->valuator->lasty)
- y = (int)((float)(cp->valuator->lasty)*(max-min+1)/scr->height)+min;
- }
- else
- y = cp->valuator->lasty;
-
- /* Add relative movement */
- if (first_valuator == 0 && num_valuators >= 1)
- x += valuators[0];
- if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
- y += valuators[1 - first_valuator];
- }
- else {
- x = pDev->valuator->lastx;
- y = pDev->valuator->lasty;
- if (first_valuator == 0 && num_valuators >= 1)
- x += valuators[0];
- if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
- y += valuators[1 - first_valuator];
-
- if(!coreOnly) {
- /* Since we're not sending core-events we must clip both x and y
- * to the defined limits so we don't run outside the box. */
- clipAxis(pDev, 0, &x);
- clipAxis(pDev, 1, &y);
- }
- }
+ accelPointer(pDev, first_valuator, num_valuators, valuators, ms);
+ moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
}
- pDev->valuator->lastx = x;
- pDev->valuator->lasty = y;
- /* Convert the dev coord back to screen coord if we're
- * sending core events */
- if (pDev->coreEvents) {
- int min = pDev->valuator->axes[0].min_value;
- int max = pDev->valuator->axes[0].max_value;
- if(min < max)
- x = (int)((float)(x-min)*scr->width/(max-min+1));
- cp->valuator->lastx = x;
- min = pDev->valuator->axes[1].min_value;
- max = pDev->valuator->axes[1].max_value;
- if(min < max)
- y = (int)((float)(y-min)*scr->height/(max-min+1));
- cp->valuator->lasty = y;
- }
+ positionSprite(pDev, &x, &y, scr, &cx, &cy);
+ updateHistory(pDev, first_valuator, num_valuators, ms);
- /* This takes care of crossing screens for us, as well as clipping
- * to the current screen. Right now, we only have one history buffer,
- * so we don't set this for both the device and core.*/
- miPointerSetPosition(pDev, &x, &y, ms);
-
- if (pDev->coreEvents) {
- /* miPointerSetPosition may have changed screen */
- scr = miPointerGetScreen(pDev);
- if(x != cp->valuator->lastx) {
- int min = pDev->valuator->axes[0].min_value;
- int max = pDev->valuator->axes[0].max_value;
- cp->valuator->lastx = pDev->valuator->lastx = x;
- if(min < max)
- pDev->valuator->lastx = (int)((float)(x)*(max-min+1)/scr->width)+min;
- }
- if(y != cp->valuator->lasty) {
- int min = pDev->valuator->axes[1].min_value;
- int max = pDev->valuator->axes[1].max_value;
- cp->valuator->lasty = pDev->valuator->lasty = y;
- if(min < max)
- pDev->valuator->lasty = (int)((float)(y)*(max-min+1)/scr->height)+min;
- }
- }
- else if (coreOnly) {
- cp->valuator->lastx = x;
- cp->valuator->lasty = y;
- }
- /* Drop x and y back into the valuators list, if they were originally
- * present. */
- if (first_valuator == 0 && num_valuators >= 1)
- valuators[0] = pDev->valuator->lastx;
+ /* Update the valuators with the true value sent to the client*/
+ if (num_valuators >= 1 && first_valuator == 0)
+ valuators[0] = x;
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
- valuators[1 - first_valuator] = pDev->valuator->lasty;
-
- updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
-
- /* for some reason inputInfo.pointer does not have coreEvents set */
- if (coreOnly || pDev->coreEvents) {
- events->u.u.type = type;
- events->u.keyButtonPointer.time = ms;
- events->u.keyButtonPointer.rootX = x;
- events->u.keyButtonPointer.rootY = y;
-
- if (type == ButtonPress || type == ButtonRelease) {
- /* We hijack SetPointerMapping to work on all core-sending
- * devices, so we use the device-specific map here instead of
- * the core one. */
- events->u.u.detail = pDev->button->map[buttons];
- }
- else {
- events->u.u.detail = 0;
- }
+ valuators[1 - first_valuator] = y;
- events++;
- }
-
- if (!coreOnly) {
- kbp = (deviceKeyButtonPointer *) events;
- kbp->time = ms;
- kbp->deviceid = pDev->id;
+ kbp = (deviceKeyButtonPointer *) events->event;
+ kbp->time = ms;
+ kbp->deviceid = pDev->id;
- if (type == MotionNotify) {
- kbp->type = DeviceMotionNotify;
- }
- else {
- if (type == ButtonPress)
- kbp->type = DeviceButtonPress;
- else if (type == ButtonRelease)
- kbp->type = DeviceButtonRelease;
- kbp->detail = pDev->button->map[buttons];
- }
+ if (type == MotionNotify) {
+ kbp->type = DeviceMotionNotify;
+ }
+ else {
+ if (type == ButtonPress)
+ kbp->type = DeviceButtonPress;
+ else if (type == ButtonRelease)
+ kbp->type = DeviceButtonRelease;
+ kbp->detail = buttons;
+ }
- kbp->root_x = pDev->valuator->lastx;
- kbp->root_y = pDev->valuator->lasty;
+ kbp->root_x = cx; /* root_x/y always in screen coords */
+ kbp->root_y = cy;
- events++;
- if (num_valuators) {
- kbp->deviceid |= MORE_EVENTS;
+ events++;
+ if (num_valuators) {
+ kbp->deviceid |= MORE_EVENTS;
+ if (flags & POINTER_ABSOLUTE)
clipValuators(pDev, first_valuator, num_valuators, valuators);
- events = getValuatorEvents(events, pDev, first_valuator,
- num_valuators, valuators);
- }
+ events = getValuatorEvents(events, pDev, first_valuator,
+ num_valuators, valuators);
}
return num_events;
@@ -784,19 +1045,18 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
* place via GetMaximumEventsNum(), and for freeing it.
*/
_X_EXPORT int
-GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type,
+GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
int first_valuator, int num_valuators, int *valuators)
{
int num_events = 1;
- deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events;
+ deviceKeyButtonPointer *kbp;
+ DeviceIntPtr master;
/* Sanity checks. */
if (type != ProximityIn && type != ProximityOut)
return 0;
-
if (!pDev->valuator)
return 0;
-
/* Do we need to send a DeviceValuator event? */
if ((pDev->valuator->mode & 1) == Relative)
num_valuators = 0;
@@ -812,6 +1072,15 @@ GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type,
(num_valuators + first_valuator) > pDev->valuator->numAxes)
return 0;
+ master = pDev->u.master;
+ if (master && master->u.lastSlave != pDev)
+ {
+ updateSlaveDeviceCoords(master, pDev);
+ master->u.lastSlave = pDev;
+ master->last.numValuators = pDev->last.numValuators;
+ }
+
+ kbp = (deviceKeyButtonPointer *) events->event;
kbp->type = type;
kbp->deviceid = pDev->id;
kbp->detail = 0;
@@ -828,87 +1097,6 @@ GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type,
return num_events;
}
-
-/**
- * Note that pDev was the last device to send a core event. This function
- * copies the complete keymap from the originating device to the core
- * device, and makes sure the appropriate notifications are generated.
- *
- * Call this just before processInputProc.
- */
-_X_EXPORT void
-SwitchCoreKeyboard(DeviceIntPtr pDev)
-{
- KeyClassPtr ckeyc = inputInfo.keyboard->key;
- int i = 0;
-
- if (pDev != dixLookupPrivate(&inputInfo.keyboard->devPrivates,
- CoreDevicePrivateKey)) {
- memcpy(ckeyc->modifierMap, pDev->key->modifierMap, MAP_LENGTH);
- if (ckeyc->modifierKeyMap)
- xfree(ckeyc->modifierKeyMap);
- ckeyc->modifierKeyMap = xalloc(8 * pDev->key->maxKeysPerModifier);
- memcpy(ckeyc->modifierKeyMap, pDev->key->modifierKeyMap,
- (8 * pDev->key->maxKeysPerModifier));
-
- ckeyc->maxKeysPerModifier = pDev->key->maxKeysPerModifier;
- ckeyc->curKeySyms.minKeyCode = pDev->key->curKeySyms.minKeyCode;
- ckeyc->curKeySyms.maxKeyCode = pDev->key->curKeySyms.maxKeyCode;
- SetKeySymsMap(&ckeyc->curKeySyms, &pDev->key->curKeySyms);
-
- /*
- * Copy state from the extended keyboard to core. If you omit this,
- * holding Ctrl on keyboard one, and pressing Q on keyboard two, will
- * cause your app to quit. This feels wrong to me, hence the below
- * code.
- *
- * XXX: If you synthesise core modifier events, the state will get
- * clobbered here. You'll have to work out something sensible
- * to fix that. Good luck.
- */
-
-#define KEYBOARD_MASK (ShiftMask | LockMask | ControlMask | Mod1Mask | \
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)
- ckeyc->state &= ~(KEYBOARD_MASK);
- ckeyc->state |= (pDev->key->state & KEYBOARD_MASK);
-#undef KEYBOARD_MASK
- for (i = 0; i < 8; i++)
- ckeyc->modifierKeyCount[i] = pDev->key->modifierKeyCount[i];
-
-#ifdef XKB
- if (!noXkbExtension && pDev->key->xkbInfo && pDev->key->xkbInfo->desc) {
- if (!XkbCopyKeymap(pDev->key->xkbInfo->desc, ckeyc->xkbInfo->desc,
- True))
- FatalError("Couldn't pivot keymap from device to core!\n");
- }
-#endif
-
- SendMappingNotify(MappingKeyboard, ckeyc->curKeySyms.minKeyCode,
- (ckeyc->curKeySyms.maxKeyCode -
- ckeyc->curKeySyms.minKeyCode),
- serverClient);
- dixSetPrivate(&inputInfo.keyboard->devPrivates, CoreDevicePrivateKey,
- pDev);
- }
-}
-
-
-/**
- * Note that pDev was the last function to send a core pointer event.
- * Currently a no-op.
- *
- * Call this just before processInputProc.
- */
-_X_EXPORT void
-SwitchCorePointer(DeviceIntPtr pDev)
-{
- if (pDev != dixLookupPrivate(&inputInfo.pointer->devPrivates,
- CoreDevicePrivateKey))
- dixSetPrivate(&inputInfo.pointer->devPrivates,
- CoreDevicePrivateKey, pDev);
-}
-
-
/**
* Synthesize a single motion event for the core pointer.
*
@@ -916,7 +1104,11 @@ SwitchCorePointer(DeviceIntPtr pDev)
* to shift the pointer to get it inside the new bounds.
*/
void
-PostSyntheticMotion(int x, int y, int screen, unsigned long time)
+PostSyntheticMotion(DeviceIntPtr pDev,
+ int x,
+ int y,
+ int screen,
+ unsigned long time)
{
xEvent xE;
@@ -936,5 +1128,5 @@ PostSyntheticMotion(int x, int y, int screen, unsigned long time)
xE.u.keyButtonPointer.rootY = y;
xE.u.keyButtonPointer.time = time;
- (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+ (*pDev->public.processInputProc)(&xE, pDev, 1);
}
diff --git a/xorg-server/dix/globals.c b/xorg-server/dix/globals.c
index 7f95eabd5..973dc43c3 100644
--- a/xorg-server/dix/globals.c
+++ b/xorg-server/dix/globals.c
@@ -78,12 +78,12 @@ PtrCtrl defaultPointerControl = {
DEFAULT_PTR_THRESHOLD,
0};
-_X_EXPORT ClientPtr *clients;
+_X_EXPORT ClientPtr clients[MAXCLIENTS];
_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 WindowPtr WindowTable[MAXSCREENS];
_X_EXPORT unsigned long globalSerialNumber = 0;
_X_EXPORT unsigned long serverGeneration = 0;
@@ -111,7 +111,7 @@ 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;
+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;
@@ -136,16 +136,13 @@ Bool screenSaverSuspended = FALSE;
char *defaultFontPath = COMPILEDDEFAULTFONTPATH;
char *defaultTextFont = COMPILEDDEFAULTFONT;
char *defaultCursorFont = COMPILEDCURSORFONT;
-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;
-#ifdef XPRINT
-ClientPtr requestingClient; /* XXX this should be obsolete now, remove? */
-#endif
+Bool party_like_its_1989 = FALSE;
+Bool whiteRoot = FALSE;
+
+int cursorScreenDevPriv[MAXSCREENS];
_X_EXPORT TimeStamp currentTime;
_X_EXPORT TimeStamp lastDeviceEventTime;
@@ -154,9 +151,8 @@ _X_EXPORT int defaultColorVisualClass = -1;
_X_EXPORT int monitorResolution = 0;
_X_EXPORT char *display;
+char *ConnectionInfo;
CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
-int argcGlobal;
-char **argvGlobal;
DDXPointRec dixScreenOrigins[MAXSCREENS];
diff --git a/xorg-server/dix/glyphcurs.c b/xorg-server/dix/glyphcurs.c
index 905b5fb13..f74b13730 100644
--- a/xorg-server/dix/glyphcurs.c
+++ b/xorg-server/dix/glyphcurs.c
@@ -91,11 +91,9 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm, unsigned cha
pScreen = screenInfo.screens[0];
nby = BitmapBytePad(cm->width) * (long)cm->height;
- pbits = (char *)xalloc(nby);
+ pbits = xcalloc(1, 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,
diff --git a/xorg-server/dix/grabs.c b/xorg-server/dix/grabs.c
index 85e101c6a..b372d8f1b 100644
--- a/xorg-server/dix/grabs.c
+++ b/xorg-server/dix/grabs.c
@@ -88,10 +88,10 @@ CreateGrab(
return (GrabPtr)NULL;
grab->resource = FakeClientID(client);
grab->device = device;
- grab->coreGrab = ((device == inputInfo.keyboard) ||
- (device == inputInfo.pointer));
+ grab->coreGrab = (type < LASTEvent);
grab->window = window;
grab->eventMask = eventMask;
+ grab->deviceMask = 0;
grab->ownerEvents = ownerEvents;
grab->keyboardMode = keyboardMode;
grab->pointerMode = pointerMode;
@@ -105,6 +105,8 @@ CreateGrab(
grab->detail.pMask = NULL;
grab->confineTo = confineTo;
grab->cursor = cursor;
+ grab->genericMasks = NULL;
+ grab->next = NULL;
if (cursor)
cursor->refcnt++;
return grab;
@@ -239,12 +241,28 @@ GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
return FALSE;
}
+/**
+ * Compares two grabs and returns TRUE if the first grab matches the second
+ * grab.
+ *
+ * A match is when
+ * - the devices set for the grab are equal (this is optional).
+ * - the event types for both grabs are equal.
+ * - XXX
+ *
+ * @param ignoreDevice TRUE if the device settings on the grabs are to be
+ * ignored.
+ * @return TRUE if the grabs match or FALSE otherwise.
+ */
Bool
-GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
+GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
{
- if ((pFirstGrab->device != pSecondGrab->device) ||
- (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
- (pFirstGrab->type != pSecondGrab->type))
+ if (!ignoreDevice &&
+ ((pFirstGrab->device != pSecondGrab->device) ||
+ (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice)))
+ return FALSE;
+
+ if (pFirstGrab->type != pSecondGrab->type)
return FALSE;
if (GrabSupersedesSecond(pFirstGrab, pSecondGrab) ||
@@ -315,7 +333,7 @@ AddPassiveGrabToList(ClientPtr client, GrabPtr pGrab)
for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next)
{
- if (GrabMatchesSecond(pGrab, grab))
+ if (GrabMatchesSecond(pGrab, grab, FALSE))
{
if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource))
{
@@ -397,7 +415,7 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
grab = grab->next)
{
if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) ||
- !GrabMatchesSecond(grab, pMinuendGrab))
+ !GrabMatchesSecond(grab, pMinuendGrab, (grab->coreGrab)))
continue;
if (GrabSupersedesSecond(pMinuendGrab, grab))
{
diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c
index fa1a934a3..90ddb6dd4 100644
--- a/xorg-server/dix/main.c
+++ b/xorg-server/dix/main.c
@@ -103,9 +103,6 @@ Equipment Corporation.
#include "extnsionst.h"
#include "privates.h"
#include "registry.h"
-#ifdef XPRINT
-#include "DiPrint.h"
-#endif
#ifdef PANORAMIX
#include "panoramiXsrv.h"
#else
@@ -121,7 +118,6 @@ Equipment Corporation.
extern void Dispatch(void);
-char *ConnectionInfo;
xConnSetupPrefix connSetupPrefix;
extern FontPtr defaultFont;
@@ -237,52 +233,32 @@ static int indexForScanlinePad[ 65 ] = {
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
-#ifdef __APPLE__
-void DarwinHandleGUI(int argc, char **argv, char **envp);
-#endif
+#ifdef XQUARTZ
+#include <pthread.h>
-int
-main(int argc, char *argv[], char *envp[])
+BOOL serverInitComplete = FALSE;
+pthread_mutex_t serverInitCompleteMutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t serverInitCompleteCond = PTHREAD_COND_INITIALIZER;
+
+int dix_main(int argc, char *argv[], char *envp[])
+#else
+int main(int argc, char *argv[], char *envp[])
+#endif
{
- int i, j, k, error;
- char *xauthfile;
+ int i;
HWEventQueueType alwaysCheckForInput[2];
ptw32_processInitialize();
display = "0";
- InitGlobals();
InitRegions();
-#ifdef XPRINT
- PrinterInitGlobals();
-#endif
-
-#ifdef XQUARTZ
- /* 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. */
- DarwinHandleGUI(argc, argv, envp);
-#endif
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;
@@ -309,10 +285,7 @@ main(int argc, char *argv[], char *envp[])
{
CreateWellKnownSockets();
InitProcVectors();
- clients = (ClientPtr *)xalloc(MAXCLIENTS * sizeof(ClientPtr));
- if (!clients)
- FatalError("couldn't create client array");
- for (i=1; i<MAXCLIENTS; i++)
+ for (i=1; i<MAXCLIENTS; i++)
clients[i] = NullClient;
serverClient = (ClientPtr)xalloc(sizeof(ClientRec));
if (!serverClient)
@@ -330,21 +303,6 @@ main(int argc, char *argv[], char *envp[])
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();
@@ -355,16 +313,10 @@ main(int argc, char *argv[], char *envp[])
dixResetRegistry();
ResetFontPrivateIndex();
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);
for (i = 0; i < screenInfo.numScreens; i++)
{
@@ -381,19 +333,10 @@ main(int argc, char *argv[], char *envp[])
if (!CreateRootWindow(pScreen))
FatalError("failed to create root window");
}
- InitCoreDevices();
- InitInput(argc, argv);
- if (InitAndStartDevices() != Success)
- FatalError("failed to initialize core devices");
InitFonts();
- if (loadableFonts)
- SetFontPath(serverClient, 0, (unsigned char *)defaultFontPath,
- &error);
- else {
- if (SetDefaultFontPath(defaultFontPath) != Success)
- ErrorF("failed to set default font path '%s'",
- defaultFontPath);
+ if (SetDefaultFontPath(defaultFontPath) != Success) {
+ ErrorF("[dix] failed to set default font path '%s'", defaultFontPath);
}
if (!SetDefaultFont(defaultTextFont)) {
FatalError("could not open default font '%s'", defaultTextFont);
@@ -422,6 +365,11 @@ main(int argc, char *argv[], char *envp[])
for (i = 0; i < screenInfo.numScreens; i++)
InitRootWindow(WindowTable[i]);
DefineInitialRootWindow(WindowTable[0]);
+
+ InitCoreDevices();
+ InitInput(argc, argv);
+ InitAndStartDevices();
+
dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
#ifdef PANORAMIX
@@ -437,10 +385,20 @@ main(int argc, char *argv[], char *envp[])
}
}
+#ifdef XQUARTZ
+ /* Let the other threads know the server is done with its init */
+ pthread_mutex_lock(&serverInitCompleteMutex);
+ serverInitComplete = TRUE;
+ pthread_cond_broadcast(&serverInitCompleteCond);
+ pthread_mutex_unlock(&serverInitCompleteMutex);
+#endif
+
NotifyParentProcess();
Dispatch();
+ UndisplayDevices();
+
/* Now free up whatever must be freed */
if (screenIsSaved == SCREEN_SAVER_ON)
dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
@@ -460,8 +418,9 @@ main(int argc, char *argv[], char *envp[])
config_fini();
- memset(WindowTable, 0, MAXSCREENS * sizeof(WindowPtr));
+ memset(WindowTable, 0, sizeof(WindowTable));
CloseDownDevices();
+ CloseDownEvents();
for (i = screenInfo.numScreens - 1; i >= 0; i--)
{
@@ -473,9 +432,6 @@ main(int argc, char *argv[], char *envp[])
xfree(screenInfo.screens[i]);
screenInfo.numScreens = i;
}
- CloseDownEvents();
- xfree(WindowTable);
- WindowTable = NULL;
FreeFonts();
FreeAuditTimer();
@@ -517,7 +473,7 @@ SetVendorString(char *string)
VendorString = string;
}
-static int padlength[4] = {0, 3, 2, 1};
+static const int padlength[4] = {0, 3, 2, 1};
#ifndef PANORAMIX
static
@@ -608,7 +564,7 @@ CreateConnectionBlock(void)
root.maxInstalledMaps = pScreen->maxInstalledCmaps;
root.rootVisualID = pScreen->rootVisual;
root.backingStore = pScreen->backingStoreSupport;
- root.saveUnders = pScreen->saveUnderSupport != NotUseful;
+ root.saveUnders = FALSE;
root.rootDepth = pScreen->rootDepth;
root.nDepths = pScreen->numDepths;
memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
diff --git a/xorg-server/dix/privates.c b/xorg-server/dix/privates.c
index efb320463..ca03317bf 100644
--- a/xorg-server/dix/privates.c
+++ b/xorg-server/dix/privates.c
@@ -40,9 +40,8 @@ from The Open Group.
#include "inputstr.h"
struct _Private {
- DevPrivateKey key;
- pointer value;
- struct _Private *next;
+ int state;
+ pointer value;
};
typedef struct _PrivateDesc {
@@ -50,22 +49,36 @@ typedef struct _PrivateDesc {
unsigned size;
CallbackListPtr initfuncs;
CallbackListPtr deletefuncs;
- struct _PrivateDesc *next;
} PrivateDescRec;
+#define PRIV_MAX 256
+#define PRIV_STEP 16
+
/* list of all allocated privates */
-static PrivateDescRec *items = NULL;
+static PrivateDescRec items[PRIV_MAX];
+static int nextPriv;
-static _X_INLINE PrivateDescRec *
+static PrivateDescRec *
findItem(const DevPrivateKey key)
{
- PrivateDescRec *item = items;
- while (item) {
- if (item->key == key)
- return item;
- item = item->next;
+ if (!*key) {
+ if (nextPriv >= PRIV_MAX)
+ return NULL;
+
+ items[nextPriv].key = key;
+ *key = nextPriv;
+ nextPriv++;
}
- return NULL;
+
+ return items + *key;
+}
+
+static _X_INLINE int
+privateExists(PrivateRec **privates, const DevPrivateKey key)
+{
+ return *key && *privates &&
+ (*privates)[0].state > *key &&
+ (*privates)[*key].state;
}
/*
@@ -75,21 +88,10 @@ _X_EXPORT int
dixRequestPrivate(const DevPrivateKey key, unsigned size)
{
PrivateDescRec *item = findItem(key);
- if (item) {
- if (size > item->size)
- item->size = size;
- } else {
- item = (PrivateDescRec *)xalloc(sizeof(PrivateDescRec));
- if (!item)
- return FALSE;
- memset(item, 0, sizeof(PrivateDescRec));
-
- /* add privates descriptor */
- item->key = key;
+ if (!item)
+ return FALSE;
+ if (size > item->size)
item->size = size;
- item->next = items;
- items = item;
- }
return TRUE;
}
@@ -100,25 +102,52 @@ _X_EXPORT pointer *
dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
{
PrivateDescRec *item = findItem(key);
+ PrivateCallbackRec calldata;
PrivateRec *ptr;
- unsigned size = sizeof(PrivateRec);
-
- if (item)
- size += item->size;
+ pointer value;
+ int oldsize, newsize;
+
+ newsize = (*key / PRIV_STEP + 1) * PRIV_STEP;
- ptr = (PrivateRec *)xcalloc(size, 1);
- if (!ptr)
+ /* resize or init privates array */
+ if (!item)
return NULL;
- ptr->key = key;
- ptr->value = (size > sizeof(PrivateRec)) ? (ptr + 1) : NULL;
- ptr->next = *privates;
- *privates = ptr;
-
- /* call any init funcs and return */
- if (item) {
- PrivateCallbackRec calldata = { key, &ptr->value };
- CallCallbacks(&item->initfuncs, &calldata);
+
+ /* initialize privates array if necessary */
+ if (!*privates) {
+ ptr = xcalloc(newsize, sizeof(*ptr));
+ if (!ptr)
+ return NULL;
+ *privates = ptr;
+ (*privates)[0].state = newsize;
+ }
+
+ oldsize = (*privates)[0].state;
+
+ /* resize privates array if necessary */
+ if (*key >= oldsize) {
+ ptr = xrealloc(*privates, newsize * sizeof(*ptr));
+ if (!ptr)
+ return NULL;
+ memset(ptr + oldsize, 0, (newsize - oldsize) * sizeof(*ptr));
+ *privates = ptr;
+ (*privates)[0].state = newsize;
+ }
+
+ /* initialize slot */
+ ptr = *privates + *key;
+ ptr->state = 1;
+ if (item->size) {
+ value = xcalloc(item->size, 1);
+ if (!value)
+ return NULL;
+ ptr->value = value;
}
+
+ calldata.key = key;
+ calldata.value = &ptr->value;
+ CallCallbacks(&item->initfuncs, &calldata);
+
return &ptr->value;
}
@@ -128,14 +157,10 @@ dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
_X_EXPORT pointer
dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
{
- PrivateRec *rec = *privates;
pointer *ptr;
- while (rec) {
- if (rec->key == key)
- return rec->value;
- rec = rec->next;
- }
+ if (privateExists(privates, key))
+ return (*privates)[*key].value;
ptr = dixAllocatePrivate(privates, key);
return ptr ? *ptr : NULL;
@@ -147,13 +172,8 @@ dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
_X_EXPORT pointer *
dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
{
- PrivateRec *rec = *privates;
-
- while (rec) {
- if (rec->key == key)
- return &rec->value;
- rec = rec->next;
- }
+ if (privateExists(privates, key))
+ return &(*privates)[*key].value;
return dixAllocatePrivate(privates, key);
}
@@ -164,16 +184,10 @@ dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
_X_EXPORT int
dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
{
- PrivateRec *rec;
-
top:
- rec = *privates;
- while (rec) {
- if (rec->key == key) {
- rec->value = val;
- return TRUE;
- }
- rec = rec->next;
+ if (privateExists(privates, key)) {
+ (*privates)[*key].value = val;
+ return TRUE;
}
if (!dixAllocatePrivate(privates, key))
@@ -187,27 +201,23 @@ dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
_X_EXPORT void
dixFreePrivates(PrivateRec *privates)
{
- PrivateRec *ptr, *next;
- PrivateDescRec *item;
+ int i;
PrivateCallbackRec calldata;
- /* first pass calls the delete callbacks */
- for (ptr = privates; ptr; ptr = ptr->next) {
- item = findItem(ptr->key);
- if (item) {
- calldata.key = ptr->key;
- calldata.value = &ptr->value;
- CallCallbacks(&item->deletefuncs, &calldata);
- }
- }
-
- /* second pass frees the memory */
- ptr = privates;
- while (ptr) {
- next = ptr->next;
- xfree(ptr);
- ptr = next;
- }
+ if (privates)
+ for (i = 1; i < privates->state; i++)
+ if (privates[i].state) {
+ /* call the delete callbacks */
+ calldata.key = items[i].key;
+ calldata.value = &privates[i].value;
+ CallCallbacks(&items[i].deletefuncs, &calldata);
+
+ /* free pre-allocated memory */
+ if (items[i].size)
+ xfree(privates[i].value);
+ }
+
+ xfree(privates);
}
/*
@@ -218,11 +228,9 @@ dixRegisterPrivateInitFunc(const DevPrivateKey key,
CallbackProcPtr callback, pointer data)
{
PrivateDescRec *item = findItem(key);
- if (!item) {
- if (!dixRequestPrivate(key, 0))
- return FALSE;
- item = findItem(key);
- }
+ if (!item)
+ return FALSE;
+
return AddCallback(&item->initfuncs, callback, data);
}
@@ -231,11 +239,9 @@ dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
CallbackProcPtr callback, pointer data)
{
PrivateDescRec *item = findItem(key);
- if (!item) {
- if (!dixRequestPrivate(key, 0))
- return FALSE;
- item = findItem(key);
- }
+ if (!item)
+ return FALSE;
+
return AddCallback(&item->deletefuncs, callback, data);
}
@@ -292,16 +298,17 @@ dixLookupPrivateOffset(RESTYPE type)
int
dixResetPrivates(void)
{
- PrivateDescRec *next;
-
- /* reset internal structures */
- while (items) {
- next = items->next;
- DeleteCallbackList(&items->initfuncs);
- DeleteCallbackList(&items->deletefuncs);
- xfree(items);
- items = next;
+ int i;
+
+ /* reset private descriptors */
+ for (i = 1; i < nextPriv; i++) {
+ *items[i].key = 0;
+ DeleteCallbackList(&items[i].initfuncs);
+ DeleteCallbackList(&items[i].deletefuncs);
}
+ nextPriv = 1;
+
+ /* reset offsets */
if (offsets)
xfree(offsets);
offsetsSize = sizeof(offsetDefaults);
diff --git a/xorg-server/dix/property.c b/xorg-server/dix/property.c
index 8b66ad6a2..7149f7c8c 100644
--- a/xorg-server/dix/property.c
+++ b/xorg-server/dix/property.c
@@ -80,11 +80,11 @@ PrintPropertys(WindowPtr pWin)
pProp = pWin->userProps;
while (pProp)
{
- ErrorF( "%x %x\n", pProp->propertyName, pProp->type);
- ErrorF("property format: %d\n", pProp->format);
- ErrorF("property data: \n");
+ ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type);
+ ErrorF("[dix] property format: %d\n", pProp->format);
+ ErrorF("[dix] property data: \n");
for (j=0; j<(pProp->format/8)*pProp->size; j++)
- ErrorF("%c\n", pProp->data[j]);
+ ErrorF("[dix] %c\n", pProp->data[j]);
pProp = pProp->next;
}
}
diff --git a/xorg-server/dix/protocol.txt b/xorg-server/dix/protocol.txt
index 0a85ca872..364f13e31 100644
--- a/xorg-server/dix/protocol.txt
+++ b/xorg-server/dix/protocol.txt
@@ -296,6 +296,13 @@ R021 RANDR:SetCrtcConfig
R022 RANDR:GetCrtcGammaSize
R023 RANDR:GetCrtcGamma
R024 RANDR:SetCrtcGamma
+R025 RANDR:GetScreenResourcesCurrent
+R026 RANDR:SetCrtcTransform
+R027 RANDR:GetCrtcTransform
+R028 RANDR:GetPanning
+R029 RANDR:SetPanning
+R030 RANDR:SetOutputPrimary
+R031 RANDR:GetOutputPrimary
V000 RANDR:ScreenChangeNotify
V001 RANDR:Notify
E000 RANDR:BadRROutput
@@ -731,11 +738,6 @@ E000 XC-APPGROUP:BadAppGroup
R000 XC-MISC:GetVersion
R001 XC-MISC:GetXIDRange
R002 XC-MISC:GetXIDList
-R000 XEVIE:QueryVersion
-R001 XEVIE:Start
-R002 XEVIE:End
-R003 XEVIE:Send
-R004 XEVIE:SelectInput
R000 XFIXES:QueryVersion
R001 XFIXES:ChangeSaveSet
R002 XFIXES:SelectSelectionInput
@@ -942,6 +944,10 @@ R032 XInputExtension:DeviceBell
R033 XInputExtension:SetDeviceValuators
R034 XInputExtension:GetDeviceControl
R035 XInputExtension:ChangeDeviceControl
+R036 XInputExtension:ListDeviceProperties
+R037 XInputExtension:ChangeDeviceProperty
+R038 XInputExtension:DeleteDeviceProperty
+R039 XInputExtension:GetDeviceProperty
V000 XInputExtension:DeviceValuator
V001 XInputExtension:DeviceKeyPress
V002 XInputExtension:DeviceKeyRelease
@@ -958,6 +964,7 @@ V012 XInputExtension:ChangeDeviceNotify
V013 XInputExtension:DeviceKeystateNotify
V014 XInputExtension:DeviceButtonstateNotify
V015 XInputExtension:DevicePresenceNotify
+V016 XInputExtension:DevicePropertyNotify
E000 XInputExtension:BadDevice
E001 XInputExtension:BadEvent
E002 XInputExtension:BadMode
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c
new file mode 100644
index 000000000..e9d4e882f
--- /dev/null
+++ b/xorg-server/dix/ptrveloc.c
@@ -0,0 +1,939 @@
+/*
+ *
+ * Copyright © 2006-2008 Simon Thum simon dot thum at gmx dot de
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <math.h>
+#include <ptrveloc.h>
+#include <inputstr.h>
+#include <assert.h>
+#include <os.h>
+
+/*****************************************************************************
+ * Predictable pointer acceleration
+ *
+ * 2006-2008 by Simon Thum (simon [dot] thum [at] gmx de)
+ *
+ * Serves 3 complementary functions:
+ * 1) provide a sophisticated ballistic velocity estimate to improve
+ * the relation between velocity (of the device) and acceleration
+ * 2) make arbitrary acceleration profiles possible
+ * 3) decelerate by two means (constant and adaptive) if enabled
+ *
+ * Important concepts are the
+ *
+ * - Scheme
+ * which selects the basic algorithm
+ * (see devices.c/InitPointerAccelerationScheme)
+ * - Profile
+ * which returns an acceleration
+ * for a given velocity
+ *
+ * The profile can be selected by the user (potentially at runtime).
+ * the classic profile is intended to cleanly perform old-style
+ * function selection (threshold =/!= 0)
+ *
+ ****************************************************************************/
+
+/* fwds */
+static inline void
+FeedFilterStage(FilterStagePtr s, float value, int tdiff);
+extern void
+InitFilterStage(FilterStagePtr s, float rdecay, int lutsize);
+void
+CleanupFilterChain(DeviceVelocityPtr s);
+int
+SetAccelerationProfile(DeviceVelocityPtr s, int profile_num);
+void
+InitFilterChain(DeviceVelocityPtr s, float rdecay, float degression,
+ int stages, int lutsize);
+void
+CleanupFilterChain(DeviceVelocityPtr s);
+static float
+SimpleSmoothProfile(DeviceVelocityPtr pVel, float velocity,
+ float threshold, float acc);
+
+
+
+/*#define PTRACCEL_DEBUGGING*/
+
+#ifdef PTRACCEL_DEBUGGING
+#define DebugAccelF ErrorF
+#else
+#define DebugAccelF(...) /* */
+#endif
+
+/********************************
+ * Init/Uninit etc
+ *******************************/
+
+/**
+ * Init struct so it should match the average case
+ */
+void
+InitVelocityData(DeviceVelocityPtr s)
+{
+ memset(s, 0, sizeof(DeviceVelocityRec));
+
+ s->corr_mul = 10.0; /* dots per 10 milisecond should be usable */
+ s->const_acceleration = 1.0; /* no acceleration/deceleration */
+ s->reset_time = 300;
+ s->use_softening = 1;
+ s->min_acceleration = 1.0; /* don't decelerate */
+ s->coupling = 0.25;
+ s->average_accel = TRUE;
+ SetAccelerationProfile(s, AccelProfileClassic);
+ InitFilterChain(s, (float)1.0/20.0, 1, 1, 40);
+}
+
+
+/**
+ * Clean up
+ */
+static void
+FreeVelocityData(DeviceVelocityPtr s){
+ CleanupFilterChain(s);
+ SetAccelerationProfile(s, -1);
+}
+
+
+/*
+ * dix uninit helper, called through scheme
+ */
+void
+AccelerationDefaultCleanup(DeviceIntPtr pDev)
+{
+ /*sanity check*/
+ if( pDev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable
+ && pDev->valuator->accelScheme.accelData != NULL){
+ pDev->valuator->accelScheme.AccelSchemeProc = NULL;
+ FreeVelocityData(pDev->valuator->accelScheme.accelData);
+ xfree(pDev->valuator->accelScheme.accelData);
+ pDev->valuator->accelScheme.accelData = NULL;
+ }
+}
+
+/*********************
+ * Filtering logic
+ ********************/
+
+/**
+Initialize a filter chain.
+Expected result is a series of filters, each progressively more integrating.
+
+This allows for two strategies: Either you have one filter which is reasonable
+and is being coupled to account for fast-changing input, or you have 'one for
+every situation'. You might want to have tighter coupling then, e.g. 0.1.
+In the filter stats, you can see if a reasonable filter useage emerges.
+*/
+void
+InitFilterChain(DeviceVelocityPtr s, float rdecay, float progression, int stages, int lutsize)
+{
+ int fn;
+ if((stages > 1 && progression < 1.0f) || 0 == progression){
+ ErrorF("(dix ptracc) invalid filter chain progression specified\n");
+ return;
+ }
+ /* Block here to support runtime filter adjustment */
+ OsBlockSignals();
+ for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){
+ if(fn < stages){
+ InitFilterStage(&s->filters[fn], rdecay, lutsize);
+ }else{
+ InitFilterStage(&s->filters[fn], 0, 0);
+ }
+ rdecay /= progression;
+ }
+ /* release again. Should the input loop be threaded, we also need
+ * memory release here (in principle).
+ */
+ OsReleaseSignals();
+}
+
+
+void
+CleanupFilterChain(DeviceVelocityPtr s)
+{
+ int fn;
+
+ for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++)
+ InitFilterStage(&s->filters[fn], 0, 0);
+}
+
+static inline void
+StuffFilterChain(DeviceVelocityPtr s, float value)
+{
+ int fn;
+
+ for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){
+ if(s->filters[fn].rdecay != 0)
+ s->filters[fn].current = value;
+ else break;
+ }
+}
+
+
+/**
+ * Adjust weighting decay and lut for a stage
+ * The weight fn is designed so its integral 0->inf is unity, so we end
+ * up with a stable (basically IIR) filter. It always draws
+ * towards its more current input values, which have more weight the older
+ * the last input value is.
+ */
+void
+InitFilterStage(FilterStagePtr s, float rdecay, int lutsize)
+{
+ int x;
+ float *newlut;
+ float *oldlut;
+
+ s->fading_lut_size = 0; /* prevent access */
+
+ if(lutsize > 0){
+ newlut = xalloc (sizeof(float)* lutsize);
+ if(!newlut)
+ return;
+ for(x = 0; x < lutsize; x++)
+ newlut[x] = pow(0.5, ((float)x) * rdecay);
+ }else{
+ newlut = NULL;
+ }
+ oldlut = s->fading_lut;
+ s->fading_lut = newlut;
+ s->rdecay = rdecay;
+ s->fading_lut_size = lutsize;
+ s->current = 0;
+ if(oldlut != NULL)
+ xfree(oldlut);
+}
+
+
+static inline void
+FeedFilterChain(DeviceVelocityPtr s, float value, int tdiff)
+{
+ int fn;
+
+ for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){
+ if(s->filters[fn].rdecay != 0)
+ FeedFilterStage(&s->filters[fn], value, tdiff);
+ else break;
+ }
+}
+
+
+static inline void
+FeedFilterStage(FilterStagePtr s, float value, int tdiff){
+ float fade;
+ if(tdiff < s->fading_lut_size)
+ fade = s->fading_lut[tdiff];
+ else
+ fade = pow(0.5, ((float)tdiff) * s->rdecay);
+ s->current *= fade; /* fade out old velocity */
+ s->current += value * (1.0f - fade); /* and add up current */
+}
+
+/**
+ * Select the most filtered matching result. Also, the first
+ * mismatching filter may be set to value (coupling).
+ */
+static inline float
+QueryFilterChain(
+ DeviceVelocityPtr s,
+ float value)
+{
+ int fn, rfn = 0, cfn = -1;
+ float cur, result = value;
+
+ /* try to retrieve most integrated result 'within range'
+ * Assumption: filter are in order least to most integrating */
+ for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){
+ if(0.0f == s->filters[fn].rdecay)
+ break;
+ cur = s->filters[fn].current;
+
+ if (fabs(value - cur) <= (s->coupling * (value + cur))){
+ result = cur;
+ rfn = fn + 1; /*remember result determining filter */
+ } else if(cfn == -1){
+ cfn = fn; /* remember first mismatching filter */
+ }
+ }
+
+ s->statistics.filter_usecount[rfn]++;
+ DebugAccelF("(dix ptracc) result from stage %i, input %.2f, output %.2f\n",
+ rfn, value, result);
+
+ /* override first mismatching current (coupling) so the filter
+ * catches up quickly. */
+ if(cfn != -1)
+ s->filters[cfn].current = result;
+
+ return result;
+}
+
+/********************************
+ * velocity computation
+ *******************************/
+
+/**
+ * return the axis if mickey is insignificant and axis-aligned,
+ * -1 otherwise
+ * 1 for x-axis
+ * 2 for y-axis
+ */
+static inline short
+GetAxis(int dx, int dy){
+ if(dx == 0 || dy == 0){
+ if(dx == 1 || dx == -1)
+ return 1;
+ if(dy == 1 || dy == -1)
+ return 2;
+ return -1;
+ }else{
+ return -1;
+ }
+}
+
+
+/**
+ * Perform velocity approximation
+ * return true if non-visible state reset is suggested
+ */
+static short
+ProcessVelocityData(
+ DeviceVelocityPtr s,
+ int dx,
+ int dy,
+ int time)
+{
+ float cvelocity;
+
+ int diff = time - s->lrm_time;
+ int cur_ax, last_ax;
+ short reset = (diff >= s->reset_time);
+
+ /* remember last round's result */
+ s->last_velocity = s->velocity;
+ cur_ax = GetAxis(dx, dy);
+ last_ax = GetAxis(s->last_dx, s->last_dy);
+
+ if(cur_ax != last_ax && cur_ax != -1 && last_ax != -1 && !reset){
+ /* correct for the error induced when diagonal movements are
+ reported as alternating axis mickeys */
+ dx += s->last_dx;
+ dy += s->last_dy;
+ diff += s->last_diff;
+ s->last_diff = time - s->lrm_time; /* prevent repeating add-up */
+ DebugAccelF("(dix ptracc) axial correction\n");
+ }else{
+ s->last_diff = diff;
+ }
+
+ /*
+ * cvelocity is not a real velocity yet, more a motion delta. constant
+ * acceleration is multiplied here to make the velocity an on-screen
+ * velocity (pix/t as opposed to [insert unit]/t). This is intended to
+ * make multiple devices with widely varying ConstantDecelerations respond
+ * similar to acceleration controls.
+ */
+ cvelocity = (float)sqrt(dx*dx + dy*dy) * s->const_acceleration;
+
+ s->lrm_time = time;
+
+ if (s->reset_time < 0 || diff < 0) { /* reset disabled or timer overrun? */
+ /* simply set velocity from current movement, no reset. */
+ s->velocity = cvelocity;
+ return FALSE;
+ }
+
+ if (diff == 0)
+ diff = 1; /* prevent div-by-zero, though it shouldn't happen anyway*/
+
+ /* translate velocity to dots/ms (somewhat intractable in integers,
+ so we multiply by some per-device adjustable factor) */
+ cvelocity = cvelocity * s->corr_mul / (float)diff;
+
+ /* short-circuit: when nv-reset the rest can be skipped */
+ if(reset == TRUE){
+ /*
+ * we don't really have a velocity here, since diff includes inactive
+ * time. This is dealt with in ComputeAcceleration.
+ */
+ StuffFilterChain(s, cvelocity);
+ s->velocity = s->last_velocity = cvelocity;
+ s->last_reset = TRUE;
+ DebugAccelF("(dix ptracc) non-visible state reset\n");
+ return TRUE;
+ }
+
+ if(s->last_reset == TRUE){
+ /*
+ * when here, we're probably processing the second mickey of a starting
+ * stroke. This happens to be the first time we can reasonably pretend
+ * that cvelocity is an actual velocity. Thus, to opt precision, we
+ * stuff that into the filter chain.
+ */
+ s->last_reset = FALSE;
+ DebugAccelF("(dix ptracc) after-reset vel:%.3f\n", cvelocity);
+ StuffFilterChain(s, cvelocity);
+ s->velocity = cvelocity;
+ return FALSE;
+ }
+
+ /* feed into filter chain */
+ FeedFilterChain(s, cvelocity, diff);
+
+ /* perform coupling and decide final value */
+ s->velocity = QueryFilterChain(s, cvelocity);
+
+ DebugAccelF("(dix ptracc) guess: vel=%.3f diff=%d %i|%i|%i|%i|%i|%i|%i|%i|%i\n",
+ s->velocity, diff,
+ s->statistics.filter_usecount[0], s->statistics.filter_usecount[1],
+ s->statistics.filter_usecount[2], s->statistics.filter_usecount[3],
+ s->statistics.filter_usecount[4], s->statistics.filter_usecount[5],
+ s->statistics.filter_usecount[6], s->statistics.filter_usecount[7],
+ s->statistics.filter_usecount[8]);
+ return FALSE;
+}
+
+
+/**
+ * this flattens significant ( > 1) mickeys a little bit for more steady
+ * constant-velocity response
+ */
+static inline float
+ApplySimpleSoftening(int od, int d)
+{
+ float res = d;
+ if (d <= 1 && d >= -1)
+ return res;
+ if (d > od)
+ res -= 0.5;
+ else if (d < od)
+ res += 0.5;
+ return res;
+}
+
+
+static void
+ApplySofteningAndConstantDeceleration(
+ DeviceVelocityPtr s,
+ int dx,
+ int dy,
+ float* fdx,
+ float* fdy,
+ short do_soften)
+{
+ if (do_soften && s->use_softening) {
+ *fdx = ApplySimpleSoftening(s->last_dx, dx);
+ *fdy = ApplySimpleSoftening(s->last_dy, dy);
+ } else {
+ *fdx = dx;
+ *fdy = dy;
+ }
+
+ *fdx *= s->const_acceleration;
+ *fdy *= s->const_acceleration;
+}
+
+/*
+ * compute the acceleration for given velocity and enforce min_acceleartion
+ */
+static float
+BasicComputeAcceleration(
+ DeviceVelocityPtr pVel,
+ float velocity,
+ float threshold,
+ float acc){
+
+ float result;
+ result = pVel->Profile(pVel, velocity, threshold, acc);
+
+ /* enforce min_acceleration */
+ if (result < pVel->min_acceleration)
+ result = pVel->min_acceleration;
+ return result;
+}
+
+/**
+ * Compute acceleration. Takes into account averaging, nv-reset, etc.
+ */
+static float
+ComputeAcceleration(
+ DeviceVelocityPtr vel,
+ float threshold,
+ float acc){
+ float res;
+
+ if(vel->last_reset){
+ DebugAccelF("(dix ptracc) profile skipped\n");
+ /*
+ * This is intended to override the first estimate of a stroke,
+ * which is too low (see ProcessVelocityData). 1 should make sure
+ * the mickey is seen on screen.
+ */
+ return 1;
+ }
+
+ if(vel->average_accel && vel->velocity != vel->last_velocity){
+ /* use simpson's rule to average acceleration between
+ * current and previous velocity.
+ * Though being the more natural choice, it causes a minor delay
+ * in comparison, so it can be disabled. */
+ res = BasicComputeAcceleration(vel, vel->velocity, threshold, acc);
+ res += BasicComputeAcceleration(vel, vel->last_velocity, threshold, acc);
+ res += 4.0f * BasicComputeAcceleration(vel,
+ (vel->last_velocity + vel->velocity) / 2,
+ threshold, acc);
+ res /= 6.0f;
+ DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+ vel->velocity, vel->last_velocity, res);
+ return res;
+ }else{
+ res = BasicComputeAcceleration(vel, vel->velocity, threshold, acc);
+ DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
+ vel->velocity, res);
+ return res;
+ }
+}
+
+
+/*****************************************
+ * Acceleration functions and profiles
+ ****************************************/
+
+/**
+ * Polynomial function similar previous one, but with f(1) = 1
+ */
+static float
+PolynomialAccelerationProfile(
+ DeviceVelocityPtr pVel,
+ float velocity,
+ float ignored,
+ float acc)
+{
+ return pow(velocity, (acc - 1.0) * 0.5);
+}
+
+
+/**
+ * returns acceleration for velocity.
+ * This profile selects the two functions like the old scheme did
+ */
+static float
+ClassicProfile(
+ DeviceVelocityPtr pVel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ if (threshold) {
+ return SimpleSmoothProfile (pVel,
+ velocity,
+ threshold,
+ acc);
+ } else {
+ return PolynomialAccelerationProfile (pVel,
+ velocity,
+ 0,
+ acc);
+ }
+}
+
+
+/**
+ * Power profile
+ * This has a completely smooth transition curve, i.e. no jumps in the
+ * derivatives.
+ *
+ * This has the expense of overall response dependency on min-acceleration.
+ * In effect, min_acceleration mimics const_acceleration in this profile.
+ */
+static float
+PowerProfile(
+ DeviceVelocityPtr pVel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ float vel_dist;
+
+ acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
+
+ if (velocity <= threshold)
+ return pVel->min_acceleration;
+ vel_dist = velocity - threshold;
+ return (pow(acc, vel_dist)) * pVel->min_acceleration;
+}
+
+
+/**
+ * just a smooth function in [0..1] -> [0..1]
+ * - point symmetry at 0.5
+ * - f'(0) = f'(1) = 0
+ * - starts faster than a sinoid
+ * - smoothness C1 (Cinf if you dare to ignore endpoints)
+ */
+static inline float
+CalcPenumbralGradient(float x){
+ x *= 2.0f;
+ x -= 1.0f;
+ return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI;
+}
+
+
+/**
+ * acceleration function similar to classic accelerated/unaccelerated,
+ * but with smooth transition in between (and towards zero for adaptive dec.).
+ */
+static float
+SimpleSmoothProfile(
+ DeviceVelocityPtr pVel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ if(velocity < 1.0f)
+ return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
+ if(threshold < 1.0f)
+ threshold = 1.0f;
+ if (velocity <= threshold)
+ return 1;
+ velocity /= threshold;
+ if (velocity >= acc)
+ return acc;
+ else
+ return 1.0f + (CalcPenumbralGradient(velocity/acc) * (acc - 1.0f));
+}
+
+
+/**
+ * This profile uses the first half of the penumbral gradient as a start
+ * and then scales linearly.
+ */
+static float
+SmoothLinearProfile(
+ DeviceVelocityPtr pVel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ float res, nv;
+
+ if(acc > 1.0f)
+ acc -= 1.0f; /*this is so acc = 1 is no acceleration */
+ else
+ return 1.0f;
+
+ nv = (velocity - threshold) * acc * 0.5f;
+
+ if(nv < 0){
+ res = 0;
+ }else if(nv < 2){
+ res = CalcPenumbralGradient(nv*0.25f)*2.0f;
+ }else{
+ nv -= 2.0f;
+ res = nv * 2.0f / M_PI /* steepness of gradient at 0.5 */
+ + 1.0f; /* gradient crosses 2|1 */
+ }
+ res += pVel->min_acceleration;
+ return res;
+}
+
+
+static float
+LinearProfile(
+ DeviceVelocityPtr pVel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ return acc * velocity;
+}
+
+
+/**
+ * Set the profile by number.
+ * Intended to make profiles exchangeable at runtime.
+ * If you created a profile, give it a number here and in the header to
+ * make it selectable. In case some profile-specific init is needed, here
+ * would be a good place, since FreeVelocityData() also calls this with -1.
+ * returns FALSE (0) if profile number is unavailable.
+ */
+_X_EXPORT int
+SetAccelerationProfile(
+ DeviceVelocityPtr s,
+ int profile_num)
+{
+ PointerAccelerationProfileFunc profile;
+ switch(profile_num){
+ case -1:
+ profile = NULL; /* Special case to uninit properly */
+ break;
+ case AccelProfileClassic:
+ profile = ClassicProfile;
+ break;
+ case AccelProfileDeviceSpecific:
+ if(NULL == s->deviceSpecificProfile)
+ return FALSE;
+ profile = s->deviceSpecificProfile;
+ break;
+ case AccelProfilePolynomial:
+ profile = PolynomialAccelerationProfile;
+ break;
+ case AccelProfileSmoothLinear:
+ profile = SmoothLinearProfile;
+ break;
+ case AccelProfileSimple:
+ profile = SimpleSmoothProfile;
+ break;
+ case AccelProfilePower:
+ profile = PowerProfile;
+ break;
+ case AccelProfileLinear:
+ profile = LinearProfile;
+ break;
+ case AccelProfileReserved:
+ /* reserved for future use, e.g. a user-defined profile */
+ default:
+ return FALSE;
+ }
+ if(s->profile_private != NULL){
+ /* Here one could free old profile-private data */
+ xfree(s->profile_private);
+ s->profile_private = NULL;
+ }
+ /* Here one could init profile-private data */
+ s->Profile = profile;
+ s->statistics.profile_number = profile_num;
+ return TRUE;
+}
+
+/**********************************************
+ * driver interaction
+ **********************************************/
+
+
+/**
+ * device-specific profile
+ *
+ * The device-specific profile is intended as a hook for a driver
+ * which may want to provide an own acceleration profile.
+ * It should not rely on profile-private data, instead
+ * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends).
+ * Users may override or choose it.
+ */
+_X_EXPORT void
+SetDeviceSpecificAccelerationProfile(
+ DeviceVelocityPtr s,
+ PointerAccelerationProfileFunc profile)
+{
+ if(s)
+ s->deviceSpecificProfile = profile;
+}
+
+/**
+ * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if
+ * the predictable acceleration scheme is not in effect.
+ */
+_X_EXPORT DeviceVelocityPtr
+GetDevicePredictableAccelData(
+ DeviceIntPtr pDev)
+{
+ /*sanity check*/
+ if(!pDev){
+ ErrorF("[dix] accel: DeviceIntPtr was NULL");
+ return NULL;
+ }
+ if( pDev->valuator &&
+ pDev->valuator->accelScheme.AccelSchemeProc ==
+ acceleratePointerPredictable &&
+ pDev->valuator->accelScheme.accelData != NULL){
+
+ return (DeviceVelocityPtr)pDev->valuator->accelScheme.accelData;
+ }
+ return NULL;
+}
+
+/********************************
+ * acceleration schemes
+ *******************************/
+
+/**
+ * Modifies valuators in-place.
+ * This version employs a velocity approximation algorithm to
+ * enable fine-grained predictable acceleration profiles.
+ */
+void
+acceleratePointerPredictable(
+ DeviceIntPtr pDev,
+ int first_valuator,
+ int num_valuators,
+ int *valuators,
+ int evtime)
+{
+ float mult = 0.0;
+ int dx = 0, dy = 0;
+ int *px = NULL, *py = NULL;
+ DeviceVelocityPtr velocitydata =
+ (DeviceVelocityPtr) pDev->valuator->accelScheme.accelData;
+ float fdx, fdy; /* no need to init */
+
+ if (!num_valuators || !valuators || !velocitydata)
+ return;
+
+ if (first_valuator == 0) {
+ dx = valuators[0];
+ px = &valuators[0];
+ }
+ if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
+ dy = valuators[1 - first_valuator];
+ py = &valuators[1 - first_valuator];
+ }
+
+ if (dx || dy){
+ /* reset nonvisible state? */
+ if (ProcessVelocityData(velocitydata, dx , dy, evtime)) {
+ /* set to center of pixel. makes sense as long as there are no
+ * means of passing on sub-pixel values.
+ */
+ pDev->last.remainder[0] = pDev->last.remainder[1] = 0.5f;
+ /* prevent softening (somewhat quirky solution,
+ as it depends on the algorithm) */
+ velocitydata->last_dx = dx;
+ velocitydata->last_dy = dy;
+ }
+
+ if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
+ /* invoke acceleration profile to determine acceleration */
+ mult = ComputeAcceleration (velocitydata,
+ pDev->ptrfeed->ctrl.threshold,
+ (float)pDev->ptrfeed->ctrl.num /
+ (float)pDev->ptrfeed->ctrl.den);
+
+ if(mult != 1.0 || velocitydata->const_acceleration != 1.0) {
+ ApplySofteningAndConstantDeceleration( velocitydata,
+ dx, dy,
+ &fdx, &fdy,
+ mult > 1.0);
+ if (dx) {
+ pDev->last.remainder[0] = mult * fdx + pDev->last.remainder[0];
+ *px = (int)pDev->last.remainder[0];
+ pDev->last.remainder[0] = pDev->last.remainder[0] - (float)*px;
+ }
+ if (dy) {
+ pDev->last.remainder[1] = mult * fdy + pDev->last.remainder[1];
+ *py = (int)pDev->last.remainder[1];
+ pDev->last.remainder[1] = pDev->last.remainder[1] - (float)*py;
+ }
+ }
+ }
+ }
+ /* remember last motion delta (for softening/slow movement treatment) */
+ velocitydata->last_dx = dx;
+ velocitydata->last_dy = dy;
+}
+
+
+
+/**
+ * Originally a part of xf86PostMotionEvent; modifies valuators
+ * in-place. Retained mostly for embedded scenarios.
+ */
+void
+acceleratePointerLightweight(
+ DeviceIntPtr pDev,
+ int first_valuator,
+ int num_valuators,
+ int *valuators,
+ int ignored)
+{
+ float mult = 0.0;
+ int dx = 0, dy = 0;
+ int *px = NULL, *py = NULL;
+
+ if (!num_valuators || !valuators)
+ return;
+
+ if (first_valuator == 0) {
+ dx = valuators[0];
+ px = &valuators[0];
+ }
+ if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
+ dy = valuators[1 - first_valuator];
+ py = &valuators[1 - first_valuator];
+ }
+
+ if (!dx && !dy)
+ return;
+
+ if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
+ /* modeled from xf86Events.c */
+ if (pDev->ptrfeed->ctrl.threshold) {
+ if ((abs(dx) + abs(dy)) >= pDev->ptrfeed->ctrl.threshold) {
+ pDev->last.remainder[0] = ((float)dx *
+ (float)(pDev->ptrfeed->ctrl.num)) /
+ (float)(pDev->ptrfeed->ctrl.den) +
+ pDev->last.remainder[0];
+ if (px) {
+ *px = (int)pDev->last.remainder[0];
+ pDev->last.remainder[0] = pDev->last.remainder[0] -
+ (float)(*px);
+ }
+
+ pDev->last.remainder[1] = ((float)dy *
+ (float)(pDev->ptrfeed->ctrl.num)) /
+ (float)(pDev->ptrfeed->ctrl.den) +
+ pDev->last.remainder[1];
+ if (py) {
+ *py = (int)pDev->last.remainder[1];
+ pDev->last.remainder[1] = pDev->last.remainder[1] -
+ (float)(*py);
+ }
+ }
+ }
+ else {
+ mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
+ ((float)(pDev->ptrfeed->ctrl.num) /
+ (float)(pDev->ptrfeed->ctrl.den) - 1.0) /
+ 2.0) / 2.0;
+ if (dx) {
+ pDev->last.remainder[0] = mult * (float)dx +
+ pDev->last.remainder[0];
+ *px = (int)pDev->last.remainder[0];
+ pDev->last.remainder[0] = pDev->last.remainder[0] -
+ (float)(*px);
+ }
+ if (dy) {
+ pDev->last.remainder[1] = mult * (float)dy +
+ pDev->last.remainder[1];
+ *py = (int)pDev->last.remainder[1];
+ pDev->last.remainder[1] = pDev->last.remainder[1] -
+ (float)(*py);
+ }
+ }
+ }
+}
diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c
index f318de3c0..7b0441ee9 100644
--- a/xorg-server/dix/resource.c
+++ b/xorg-server/dix/resource.c
@@ -339,7 +339,7 @@ AvailableID(
return 0;
}
-_X_EXPORT void
+void
GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
{
XID id, maxid;
@@ -390,7 +390,7 @@ GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
* invented, but this will be used so rarely that this should suffice.
*/
-_X_EXPORT unsigned int
+unsigned int
GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
{
unsigned int found = 0;
@@ -452,7 +452,7 @@ AddResource(XID id, RESTYPE type, pointer value)
rrec = &clientTable[client];
if (!rrec->buckets)
{
- ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+ ErrorF("[dix] AddResource(%lx, %lx, %lx), client=%d \n",
(unsigned long)id, type, (unsigned long)value, client);
FatalError("client not in use\n");
}
diff --git a/xorg-server/dix/selection.c b/xorg-server/dix/selection.c
index 6a9198e96..c5427e004 100644
--- a/xorg-server/dix/selection.c
+++ b/xorg-server/dix/selection.c
@@ -189,7 +189,7 @@ ProcSetSelectionOwner(ClientPtr client)
event.u.selectionClear.time = time.milliseconds;
event.u.selectionClear.window = pSel->window;
event.u.selectionClear.atom = pSel->selection;
- TryClientEvents(pSel->client, &event, 1, NoEventMask,
+ TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask,
NoEventMask /* CantBeFiltered */, NullGrab);
}
}
@@ -294,7 +294,7 @@ ProcConvertSelection(ClientPtr client)
event.u.selectionRequest.selection = stuff->selection;
event.u.selectionRequest.target = stuff->target;
event.u.selectionRequest.property = stuff->property;
- if (TryClientEvents(pSel->client, &event, 1, NoEventMask,
+ if (TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask,
NoEventMask /* CantBeFiltered */, NullGrab))
return client->noClientException;
}
@@ -305,7 +305,7 @@ ProcConvertSelection(ClientPtr client)
event.u.selectionNotify.selection = stuff->selection;
event.u.selectionNotify.target = stuff->target;
event.u.selectionNotify.property = None;
- TryClientEvents(client, &event, 1, NoEventMask,
+ TryClientEvents(client, NULL, &event, 1, NoEventMask,
NoEventMask /* CantBeFiltered */, NullGrab);
return client->noClientException;
}
diff --git a/xorg-server/dix/strcasecmp.c b/xorg-server/dix/strcasecmp.c
deleted file mode 100644
index ca1051dc1..000000000
--- a/xorg-server/dix/strcasecmp.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <ctype.h>
-#include "dix.h"
-
-#ifdef NEED_STRCASECMP
-int
-xstrcasecmp(const char *str1, const 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
-
-#ifdef NEED_STRNCASECMP
-int
-xstrncasecmp(const char *s1, const char *s2, size_t n)
-{
- if (n != 0) {
- const u_char *us1 = (const u_char *)s1, *us2 = (const u_char *)s2;
-
- do {
- if (tolower(*us1) != tolower(*us2++))
- return (tolower(*us1) - tolower(*--us2));
- if (*us1++ == '\0')
- break;
- } while (--n != 0);
- }
-
- return 0;
-}
-#endif
diff --git a/xorg-server/dix/strcasestr.c b/xorg-server/dix/strcasestr.c
deleted file mode 100644
index b3d45495c..000000000
--- a/xorg-server/dix/strcasestr.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <ctype.h>
-#include <string.h>
-#include "dix.h"
-
-/*
- * Find the first occurrence of find in s, ignore case.
- */
-#ifdef NEED_STRCASESTR
-char *
-xstrcasestr(const char *s, const char *find)
-{
- char c, sc;
- size_t len;
-
- if ((c = *find++) != 0) {
- c = tolower((unsigned char)c);
- len = strlen(find);
- do {
- do {
- if ((sc = *s++) == 0)
- return (NULL);
- } while ((char)tolower((unsigned char)sc) != c);
- } while (strncasecmp(s, find, len) != 0);
- s--;
- }
- return ((char *)s);
-}
-#endif
diff --git a/xorg-server/dix/tables.c b/xorg-server/dix/tables.c
index 2200e3ceb..e4f93661c 100644
--- a/xorg-server/dix/tables.c
+++ b/xorg-server/dix/tables.c
@@ -70,7 +70,7 @@ int (* InitialVector[3]) (
ProcEstablishConnection
};
-_X_EXPORT int (* ProcVector[256]) (
+int (* ProcVector[256]) (
ClientPtr /* client */
) =
{
@@ -378,7 +378,7 @@ _X_EXPORT EventSwapPtr EventSwapVector[128] =
};
-_X_EXPORT ReplySwapPtr ReplySwapVector[256] =
+ReplySwapPtr ReplySwapVector[256] =
{
ReplyNotSwappd,
ReplyNotSwappd,
diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c
index 834c26b12..c19990ac1 100644
--- a/xorg-server/dix/window.c
+++ b/xorg-server/dix/window.c
@@ -110,6 +110,7 @@ Equipment Corporation.
#include "validate.h"
#include "windowstr.h"
#include "input.h"
+#include "inputstr.h"
#include "resource.h"
#include "colormapst.h"
#include "cursorstr.h"
@@ -122,10 +123,8 @@ Equipment Corporation.
#endif
#include "dixevents.h"
#include "globals.h"
+#include "mi.h" /* miPaintWindow */
-#ifdef XAPPGROUP
-#include "appgroup.h"
-#endif
#include "privates.h"
#include "xace.h"
@@ -136,16 +135,28 @@ Equipment Corporation.
* GetWindowAttributes, DeleteWindow, DestroySubWindows,
* HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
* UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
- *
+ * ChangeWindowDeviceCursor
******/
static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+static Bool WindowParentHasDeviceCursor(WindowPtr pWin,
+ DeviceIntPtr pDev,
+ CursorPtr pCurs);
+static Bool
+WindowSeekDeviceCursor(WindowPtr pWin,
+ DeviceIntPtr pDev,
+ DevCursNodePtr* pNode,
+ DevCursNodePtr* pPrev);
+
_X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
_X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+static int FocusPrivatesKeyIndex;
+_X_EXPORT DevPrivateKey FocusPrivatesKey = &FocusPrivatesKeyIndex;
+
static Bool TileScreenSaver(int i, int kind);
@@ -169,9 +180,6 @@ static Bool TileScreenSaver(int i, int kind);
#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
-_X_EXPORT int numSaveUndersViewable = 0;
-_X_EXPORT int deltaSaveUndersViewable = 0;
-
#ifdef DEBUG
/******
* PrintWindowTree
@@ -187,8 +195,9 @@ PrintChildren(WindowPtr p1, int indent)
while (p1)
{
p2 = p1->firstChild;
- for (i=0; i<indent; i++) ErrorF( " ");
- ErrorF( "%lx\n", p1->drawable.id);
+ ErrorF("[dix] ");
+ for (i=0; i<indent; i++) ErrorF(" ");
+ ErrorF("%lx\n", p1->drawable.id);
miPrintRegion(&p1->clipList);
PrintChildren(p2, indent+4);
p1 = p1->nextSib;
@@ -203,7 +212,7 @@ PrintWindowTree(void)
for (i=0; i<screenInfo.numScreens; i++)
{
- ErrorF( "WINDOW %d\n", i);
+ ErrorF("[dix] WINDOW %d\n", i);
pWin = WindowTable[i];
miPrintRegion(&pWin->clipList);
p1 = pWin->firstChild;
@@ -258,8 +267,6 @@ 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(WindowPtr pWin)
@@ -292,6 +299,10 @@ SetWindowToDefaults(WindowPtr pWin)
pWin->forcedBS = FALSE;
pWin->redirectDraw = RedirectDrawNone;
pWin->forcedBG = FALSE;
+
+#ifdef ROOTLESS
+ pWin->rootlessUnhittable = FALSE;
+#endif
}
static void
@@ -387,14 +398,24 @@ CreateRootWindow(ScreenPtr pScreen)
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->deviceCursors = NULL;
+ pWin->optional->geMasks = (GenericClientMasksPtr)xcalloc(1, sizeof(GenericClientMasksRec));
+ if (!pWin->optional->geMasks)
+ {
+ xfree(pWin->optional);
+ return FALSE;
+ }
+
+ pWin->optional->access.perm = NULL;
+ pWin->optional->access.deny = NULL;
+ pWin->optional->access.nperm = 0;
+ pWin->optional->access.ndeny = 0;
+ pWin->optional->access.defaultRule = 0;
+
pWin->optional->colormap = pScreen->defColormap;
pWin->optional->visual = pScreen->rootVisual;
@@ -440,20 +461,7 @@ CreateRootWindow(ScreenPtr pScreen)
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;
+ pScreen->saveUnderSupport = NotUseful;
return TRUE;
}
@@ -472,15 +480,15 @@ InitRootWindow(WindowPtr pWin)
pWin->optional->cursor = rootCursor;
rootCursor->refcnt++;
- if (!blackRoot && !whiteRoot) {
+
+ if (party_like_its_1989) {
MakeRootTile(pWin);
backFlag |= CWBackPixmap;
- }
- else {
- if (blackRoot)
- pWin->background.pixel = pScreen->blackPixel;
- else
+ } else {
+ if (whiteRoot)
pWin->background.pixel = pScreen->whitePixel;
+ else
+ pWin->background.pixel = pScreen->blackPixel;
backFlag |= CWBackPixel;
}
@@ -600,14 +608,6 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
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;
}
@@ -797,6 +797,8 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
static void
DisposeWindowOptional (WindowPtr pWin)
{
+ GenericMaskPtr gmask = NULL, next = NULL;
+
if (!pWin->optional)
return;
/*
@@ -810,6 +812,37 @@ DisposeWindowOptional (WindowPtr pWin)
}
else
pWin->cursorIsNone = TRUE;
+
+ if (pWin->optional->deviceCursors)
+ {
+ DevCursorList pList;
+ DevCursorList pPrev;
+ pList = pWin->optional->deviceCursors;
+ while(pList)
+ {
+ if (pList->cursor)
+ FreeCursor(pList->cursor, (XID)0);
+ pPrev = pList;
+ pList = pList->next;
+ xfree(pPrev);
+ }
+ pWin->optional->deviceCursors = NULL;
+ }
+
+ xfree(pWin->optional->access.perm);
+ xfree(pWin->optional->access.deny);
+
+ /* Remove generic event mask allocations */
+ if (pWin->optional->geMasks)
+ gmask = pWin->optional->geMasks->geClients;
+ while(gmask)
+ {
+ next = gmask->next;
+ xfree(gmask);
+ gmask = next;
+ }
+ xfree (pWin->optional->geMasks);
+
xfree (pWin->optional);
pWin->optional = NULL;
}
@@ -826,14 +859,12 @@ FreeWindowResources(WindowPtr pWin)
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)
@@ -873,10 +904,6 @@ CrushTree(WindowPtr pWin)
}
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)
{
@@ -934,6 +961,7 @@ DeleteWindow(pointer value, XID wid)
if (pWin->prevSib)
pWin->prevSib->nextSib = pWin->nextSib;
}
+ xfree(dixLookupPrivate(&pWin->devPrivates, FocusPrivatesKey));
dixFreePrivates(pWin->devPrivates);
xfree(pWin);
return Success;
@@ -981,7 +1009,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
Pixmap pixID;
CursorPtr pCursor, pOldCursor;
Cursor cursorID;
- WindowPtr pChild, pLayerWin;
+ WindowPtr pChild;
Colormap cmap;
ColormapPtr pCmap;
xEvent xE;
@@ -1202,47 +1230,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
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:
rc = EventSelectForWindow(pWin, client, (Mask )*pVlist);
@@ -1288,22 +1276,6 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
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)))
@@ -1541,7 +1513,7 @@ GetWindowAttributes(WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply
}
-_X_EXPORT WindowPtr
+WindowPtr
MoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib)
{
WindowPtr pParent = pWin->parent;
@@ -1636,7 +1608,6 @@ CreateUnclippedWinSize (WindowPtr pWin)
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;
pScreen = pWin->drawable.pScreen;
@@ -1649,11 +1620,10 @@ CreateUnclippedWinSize (WindowPtr pWin)
REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
}
-#endif
return pRgn;
}
-_X_EXPORT void
+void
SetWinSize (WindowPtr pWin)
{
#ifdef COMPOSITE
@@ -1677,7 +1647,6 @@ SetWinSize (WindowPtr pWin)
pWin->drawable.x, pWin->drawable.y,
(int)pWin->drawable.width,
(int)pWin->drawable.height);
-#ifdef SHAPE
if (wBoundingShape (pWin) || wClipShape (pWin)) {
ScreenPtr pScreen;
pScreen = pWin->drawable.pScreen;
@@ -1693,10 +1662,9 @@ SetWinSize (WindowPtr pWin)
REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
pWin->drawable.y);
}
-#endif
}
-_X_EXPORT void
+void
SetBorderSize (WindowPtr pWin)
{
int bw;
@@ -1724,7 +1692,6 @@ SetBorderSize (WindowPtr pWin)
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;
pScreen = pWin->drawable.pScreen;
@@ -1738,7 +1705,6 @@ SetBorderSize (WindowPtr pWin)
REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
&pWin->winSize);
}
-#endif
} else {
REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
&pWin->winSize);
@@ -1802,7 +1768,7 @@ GravityTranslate (int x, int y, int oldx, int oldy,
}
/* XXX need to retile border on each window with ParentRelative origin */
-_X_EXPORT void
+void
ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh)
{
ScreenPtr pScreen;
@@ -1929,7 +1895,6 @@ WindowExtents(
return(pBox);
}
-#ifdef SHAPE
#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
static RegionPtr
@@ -1974,7 +1939,6 @@ ShapeOverlap (
REGION_DESTROY(pScreen, pSibRgn);
return ret;
}
-#endif
static Bool
AnyWindowOverlapsMe(
@@ -1992,9 +1956,7 @@ AnyWindowOverlapsMe(
{
sbox = WindowExtents(pSib, &sboxrec);
if (BOXES_OVERLAP(sbox, box)
-#ifdef SHAPE
&& ShapeOverlap (pWin, box, pSib, sbox)
-#endif
)
return(TRUE);
}
@@ -2017,9 +1979,7 @@ IOverlapAnyWindow(
{
sbox = WindowExtents(pSib, &sboxrec);
if (BOXES_OVERLAP(sbox, box)
-#ifdef SHAPE
&& ShapeOverlap (pWin, box, pSib, sbox)
-#endif
)
return(TRUE);
}
@@ -2172,9 +2132,6 @@ ReflectStackChange(
Bool WasViewable = (Bool)pWin->viewable;
Bool anyMarked;
WindowPtr pFirstChange;
-#ifdef DO_SAVE_UNDERS
- Bool dosave = FALSE;
-#endif
WindowPtr pLayerWin;
ScreenPtr pScreen = pWin->drawable.pScreen;
@@ -2189,21 +2146,11 @@ ReflectStackChange(
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);
}
@@ -2232,10 +2179,6 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
h = pWin->drawable.height,
bw = pWin->borderWidth;
int rc, action, smode = Above;
-#ifdef XAPPGROUP
- ClientPtr win_owner;
- ClientPtr ag_leader = NULL;
-#endif
xEvent event;
if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
@@ -2331,17 +2274,9 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
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;
@@ -2366,16 +2301,6 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
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)
@@ -2676,10 +2601,6 @@ RealizeTree(WindowPtr pWin)
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)
@@ -2734,9 +2655,6 @@ MapWindow(WindowPtr pWin, ClientPtr client)
ScreenPtr pScreen;
WindowPtr pParent;
-#ifdef DO_SAVE_UNDERS
- Bool dosave = FALSE;
-#endif
WindowPtr pLayerWin;
if (pWin->mapped)
@@ -2752,31 +2670,13 @@ MapWindow(WindowPtr pWin, ClientPtr client)
{
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,
@@ -2800,21 +2700,11 @@ MapWindow(WindowPtr pWin, ClientPtr client)
{
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);
}
@@ -2854,17 +2744,11 @@ MapSubwindows(WindowPtr pParent, ClientPtr client)
{
WindowPtr pWin;
WindowPtr pFirstMapped = NullWindow;
-#ifdef DO_SAVE_UNDERS
- WindowPtr pFirstSaveUndered = NullWindow;
-#endif
ScreenPtr pScreen;
Mask parentRedirect;
Mask parentNotify;
xEvent event;
Bool anyMarked;
-#ifdef DO_SAVE_UNDERS
- Bool dosave = FALSE;
-#endif
WindowPtr pLayerWin;
pScreen = pParent->drawable.pScreen;
@@ -2904,12 +2788,6 @@ MapSubwindows(WindowPtr pParent, ClientPtr client)
{
anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
(WindowPtr *)NULL);
-#ifdef DO_SAVE_UNDERS
- if (DO_SAVE_UNDERS(pWin))
- {
- dosave = TRUE;
- }
-#endif /* DO_SAVE_UNDERS */
}
}
}
@@ -2926,38 +2804,9 @@ MapSubwindows(WindowPtr pParent, ClientPtr client)
}
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);
@@ -2997,10 +2846,6 @@ UnrealizeTree(
DeleteWindowFromAnyEvents(pChild, FALSE);
if (pChild->viewable)
{
-#ifdef DO_SAVE_UNDERS
- if (pChild->saveUnder)
- deltaSaveUndersViewable--;
-#endif
pChild->viewable = FALSE;
(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
@@ -3061,16 +2906,6 @@ UnmapWindow(WindowPtr pWin, Bool 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);
}
@@ -3126,9 +2961,6 @@ UnmapSubwindows(WindowPtr pWin)
UnrealizeTree(pChild, FALSE);
if (wasViewable)
{
-#ifdef DO_SAVE_UNDERS
- pChild->DIXsaveUnder = FALSE;
-#endif /* DO_SAVE_UNDERS */
}
}
}
@@ -3158,13 +2990,6 @@ UnmapSubwindows(WindowPtr pWin)
(*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);
}
@@ -3196,6 +3021,11 @@ HandleSaveSet(ClientPtr client)
{
if (pParent != pWin->parent)
{
+#ifdef XFIXES
+ /* unmap first so that ReparentWindow doesn't remap */
+ if (!SaveSetShouldMap (client->saveSet[j]))
+ UnmapWindow(pWin, FALSE);
+#endif
ReparentWindow(pWin, pParent,
pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
@@ -3204,7 +3034,7 @@ HandleSaveSet(ClientPtr client)
pWin->mapped = FALSE;
}
#ifdef XFIXES
- if (SaveSetRemap (client->saveSet[j]))
+ if (SaveSetShouldMap (client->saveSet[j]))
#endif
MapWindow(pWin, client);
}
@@ -3254,10 +3084,12 @@ NotClippedByChildren(WindowPtr pWin)
return(pReg);
}
-_X_EXPORT void
+void
SendVisibilityNotify(WindowPtr pWin)
{
xEvent event;
+ if (!MapUnmapEventsEnabled(pWin))
+ return;
#ifndef NO_XINERAMA_PORT
unsigned int visibility = pWin->visibility;
#endif
@@ -3614,18 +3446,31 @@ CheckWindowOptionalNeed (WindowPtr w)
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
+ if (optional->deviceCursors != NULL)
+ {
+ DevCursNodePtr pNode = optional->deviceCursors;
+ while(pNode)
+ {
+ if (pNode->cursor != None)
+ return;
+ pNode = pNode->next;
+ }
+ }
+ if (optional->access.nperm != 0 ||
+ optional->access.ndeny != 0)
+ return;
+
+ if (optional->geMasks != NULL)
+ return;
+
parentOptional = FindWindowWithOptional(w)->optional;
if (optional->visual != parentOptional->visual)
return;
@@ -3663,14 +3508,30 @@ MakeWindowOptional (WindowPtr pWin)
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
+ optional->deviceCursors = NULL;
+
+ optional->geMasks =
+ (GenericClientMasksPtr)xalloc(sizeof(GenericClientMasksRec));
+ if (!optional->geMasks)
+ {
+ xfree(optional);
+ return FALSE;
+ } else {
+ int i;
+ optional->geMasks->geClients = 0;
+ for (i = 0; i < MAXEXTENSIONS; i++)
+ optional->geMasks->eventMasks[i] = 0;
+ }
+
+ optional->access.nperm = 0;
+ optional->access.ndeny = 0;
+ optional->access.perm = NULL;
+ optional->access.deny = NULL;
+ optional->access.defaultRule = 0;
parentOptional = FindWindowWithOptional(pWin)->optional;
optional->visual = parentOptional->visual;
if (!pWin->cursorIsNone)
@@ -3687,6 +3548,222 @@ MakeWindowOptional (WindowPtr pWin)
return TRUE;
}
+/*
+ * Changes the cursor struct for the given device and the given window.
+ * A cursor that does not have a device cursor set will use whatever the
+ * standard cursor is for the window. If all devices have a cursor set,
+ * changing the window cursor (e.g. using XDefineCursor()) will not have any
+ * visible effect. Only when one of the device cursors is set to None again,
+ * this device's cursor will display the changed standard cursor.
+ *
+ * CursorIsNone of the window struct is NOT modified if you set a device
+ * cursor.
+ *
+ * Assumption: If there is a node for a device in the list, the device has a
+ * cursor. If the cursor is set to None, it is inherited by the parent.
+ */
+_X_EXPORT int
+ChangeWindowDeviceCursor(WindowPtr pWin,
+ DeviceIntPtr pDev,
+ CursorPtr pCursor)
+{
+ DevCursNodePtr pNode, pPrev;
+ CursorPtr pOldCursor = NULL;
+ ScreenPtr pScreen;
+ WindowPtr pChild;
+
+ if (!pWin->optional && !MakeWindowOptional(pWin))
+ return BadAlloc;
+
+ /* 1) Check if window has device cursor set
+ * Yes: 1.1) swap cursor with given cursor if parent does not have same
+ * cursor, free old cursor
+ * 1.2) free old cursor, use parent cursor
+ * No: 1.1) add node to beginning of list.
+ * 1.2) add cursor to node if parent does not have same cursor
+ * 1.3) use parent cursor if parent does not have same cursor
+ * 2) Patch up children if child has a devcursor
+ * 2.1) if child has cursor None, it inherited from parent, set to old
+ * cursor
+ * 2.2) if child has same cursor as new cursor, remove and set to None
+ */
+
+ pScreen = pWin->drawable.pScreen;
+
+ if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev))
+ {
+ /* has device cursor */
+
+ if (pNode->cursor == pCursor)
+ return Success;
+
+ pOldCursor = pNode->cursor;
+
+ if (!pCursor) /* remove from list */
+ {
+ if(pPrev)
+ pPrev->next = pNode->next;
+ else
+ /* first item in list */
+ pWin->optional->deviceCursors = pNode->next;
+
+ xfree(pNode);
+ return Success;
+ }
+
+ } else
+ {
+ /* no device cursor yet */
+ DevCursNodePtr pNewNode;
+
+ if (!pCursor)
+ return Success;
+
+ pNewNode = (DevCursNodePtr)xalloc(sizeof(DevCursNodeRec));
+ pNewNode->dev = pDev;
+ pNewNode->next = pWin->optional->deviceCursors;
+ pWin->optional->deviceCursors = pNewNode;
+ pNode = pNewNode;
+
+ }
+
+ if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
+ pNode->cursor = None;
+ else
+ {
+ pNode->cursor = pCursor;
+ pCursor->refcnt++;
+ }
+
+ pNode = pPrev = NULL;
+ /* fix up children */
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev))
+ {
+ if (pNode->cursor == None) /* inherited from parent */
+ {
+ pNode->cursor = pOldCursor;
+ pOldCursor->refcnt++;
+ } else if (pNode->cursor == pCursor)
+ {
+ pNode->cursor = None;
+ FreeCursor(pCursor, (Cursor)0); /* fix up refcnt */
+ }
+ }
+ }
+
+ if (pWin->realized)
+ WindowHasNewCursor(pWin);
+
+ if (pOldCursor)
+ FreeCursor(pOldCursor, (Cursor)0);
+
+ /* FIXME: We SHOULD check for an error value here XXX
+ (comment taken from ChangeWindowAttributes) */
+ (*pScreen->ChangeWindowAttributes)(pWin, CWCursor);
+
+ return Success;
+}
+
+/* Get device cursor for given device or None if none is set */
+_X_EXPORT CursorPtr
+WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev)
+{
+ DevCursorList pList;
+
+ if (!pWin->optional || !pWin->optional->deviceCursors)
+ return NULL;
+
+ pList = pWin->optional->deviceCursors;
+
+ while(pList)
+ {
+ if (pList->dev == pDev)
+ {
+ if (pList->cursor == None) /* inherited from parent */
+ return WindowGetDeviceCursor(pWin->parent, pDev);
+ else
+ return pList->cursor;
+ }
+ pList = pList->next;
+ }
+ return NULL;
+}
+
+/* Searches for a DevCursorNode for the given window and device. If one is
+ * found, return True and set pNode and pPrev to the node and to the node
+ * before the node respectively. Otherwise return False.
+ * If the device is the first in list, pPrev is set to NULL.
+ */
+static Bool
+WindowSeekDeviceCursor(WindowPtr pWin,
+ DeviceIntPtr pDev,
+ DevCursNodePtr* pNode,
+ DevCursNodePtr* pPrev)
+{
+ DevCursorList pList;
+
+ if (!pWin->optional)
+ return FALSE;
+
+ pList = pWin->optional->deviceCursors;
+
+ if (pList && pList->dev == pDev)
+ {
+ *pNode = pList;
+ *pPrev = NULL;
+ return TRUE;
+ }
+
+ while(pList)
+ {
+ if (pList->next)
+ {
+ if (pList->next->dev == pDev)
+ {
+ *pNode = pList->next;
+ *pPrev = pList;
+ return TRUE;
+ }
+ }
+ pList = pList->next;
+ }
+ return FALSE;
+}
+
+/* Return True if a parent has the same device cursor set or False if
+ * otherwise
+ */
+static Bool
+WindowParentHasDeviceCursor(WindowPtr pWin,
+ DeviceIntPtr pDev,
+ CursorPtr pCursor)
+{
+ WindowPtr pParent;
+ DevCursNodePtr pParentNode, pParentPrev;
+
+ pParent = pWin->parent;
+ while(pParent)
+ {
+ if (WindowSeekDeviceCursor(pParent, pDev,
+ &pParentNode, &pParentPrev))
+ {
+ /* if there is a node in the list, the win has a dev cursor */
+ if (!pParentNode->cursor) /* inherited. loop needs to cont. */
+ {
+ } else if (pParentNode->cursor == pCursor) /* inherit */
+ return TRUE;
+ else /* different cursor */
+ return FALSE;
+ }
+ else
+ /* parent does not have a device cursor for our device */
+ return FALSE;
+ }
+ return FALSE;
+}
+
#ifndef NOLOGOHACK
static void
DrawLogo(WindowPtr pWin)
diff --git a/xorg-server/dix/xpstubs.c b/xorg-server/dix/xpstubs.c
deleted file mode 100644
index 59340ad21..000000000
--- a/xorg-server/dix/xpstubs.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-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 */
-