aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xi
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xi')
-rw-r--r--xorg-server/Xi/Makefile.am28
-rw-r--r--xorg-server/Xi/Makefile.in82
-rw-r--r--xorg-server/Xi/allowev.c14
-rw-r--r--xorg-server/Xi/chgdctl.c12
-rw-r--r--xorg-server/Xi/chgfctl.c16
-rw-r--r--xorg-server/Xi/chgkbd.c2
-rw-r--r--xorg-server/Xi/chgkmap.c4
-rw-r--r--xorg-server/Xi/chgprop.c4
-rw-r--r--xorg-server/Xi/chgptr.c2
-rw-r--r--xorg-server/Xi/closedev.c2
-rw-r--r--xorg-server/Xi/devbell.c2
-rw-r--r--xorg-server/Xi/exevents.c1403
-rw-r--r--xorg-server/Xi/exglobals.h27
-rw-r--r--xorg-server/Xi/extinit.c534
-rw-r--r--xorg-server/Xi/getbmap.c4
-rw-r--r--xorg-server/Xi/getdctl.c4
-rw-r--r--xorg-server/Xi/getfctl.c4
-rw-r--r--xorg-server/Xi/getfocus.c2
-rw-r--r--xorg-server/Xi/getkmap.c31
-rw-r--r--xorg-server/Xi/getmmap.c30
-rw-r--r--xorg-server/Xi/getprop.c4
-rw-r--r--xorg-server/Xi/getselev.c4
-rw-r--r--xorg-server/Xi/getvers.c16
-rw-r--r--xorg-server/Xi/grabdev.c20
-rw-r--r--xorg-server/Xi/grabdevb.c26
-rw-r--r--xorg-server/Xi/grabdevk.c25
-rw-r--r--xorg-server/Xi/gtmotion.c4
-rw-r--r--xorg-server/Xi/listdev.c121
-rw-r--r--xorg-server/Xi/listdev.h11
-rw-r--r--xorg-server/Xi/opendev.c9
-rw-r--r--xorg-server/Xi/queryst.c11
-rw-r--r--xorg-server/Xi/selectev.c18
-rw-r--r--xorg-server/Xi/sendexev.c10
-rw-r--r--xorg-server/Xi/setbmap.c34
-rw-r--r--xorg-server/Xi/setdval.c4
-rw-r--r--xorg-server/Xi/setfocus.c2
-rw-r--r--xorg-server/Xi/setmmap.c33
-rw-r--r--xorg-server/Xi/setmode.c2
-rw-r--r--xorg-server/Xi/stubs.c3
-rw-r--r--xorg-server/Xi/ungrdev.c4
-rw-r--r--xorg-server/Xi/ungrdevb.c3
-rw-r--r--xorg-server/Xi/ungrdevk.c9
-rw-r--r--xorg-server/Xi/xiallowev.c103
-rw-r--r--xorg-server/Xi/xiallowev.h36
-rw-r--r--xorg-server/Xi/xichangecursor.c113
-rw-r--r--xorg-server/Xi/xichangecursor.h36
-rw-r--r--xorg-server/Xi/xichangehierarchy.c454
-rw-r--r--xorg-server/Xi/xichangehierarchy.h44
-rw-r--r--xorg-server/Xi/xigetclientpointer.c106
-rw-r--r--xorg-server/Xi/xigetclientpointer.h38
-rw-r--r--xorg-server/Xi/xigrabdev.c161
-rw-r--r--xorg-server/Xi/xigrabdev.h41
-rw-r--r--xorg-server/Xi/xipassivegrab.c313
-rw-r--r--xorg-server/Xi/xipassivegrab.h39
-rw-r--r--xorg-server/Xi/xiproperty.c836
-rw-r--r--xorg-server/Xi/xiproperty.h25
-rw-r--r--xorg-server/Xi/xiquerydevice.c487
-rw-r--r--xorg-server/Xi/xiquerydevice.h45
-rw-r--r--xorg-server/Xi/xiquerypointer.c228
-rw-r--r--xorg-server/Xi/xiquerypointer.h39
-rw-r--r--xorg-server/Xi/xiqueryversion.c128
-rw-r--r--xorg-server/Xi/xiqueryversion.h40
-rw-r--r--xorg-server/Xi/xiselectev.c299
-rw-r--r--xorg-server/Xi/xiselectev.h40
-rw-r--r--xorg-server/Xi/xisetclientpointer.c109
-rw-r--r--xorg-server/Xi/xisetclientpointer.h36
-rw-r--r--xorg-server/Xi/xisetdevfocus.c130
-rw-r--r--xorg-server/Xi/xisetdevfocus.h40
-rw-r--r--xorg-server/Xi/xiwarppointer.c201
-rw-r--r--xorg-server/Xi/xiwarppointer.h36
70 files changed, 5505 insertions, 1278 deletions
diff --git a/xorg-server/Xi/Makefile.am b/xorg-server/Xi/Makefile.am
index 557e20728..69c7886b9 100644
--- a/xorg-server/Xi/Makefile.am
+++ b/xorg-server/Xi/Makefile.am
@@ -76,7 +76,33 @@ libXi_la_SOURCES = \
ungrdevb.h \
ungrdevk.c \
ungrdevk.h \
+ xiallowev.c \
+ xiallowev.h \
+ xichangecursor.c \
+ xichangecursor.h \
+ xichangehierarchy.c \
+ xichangehierarchy.h \
+ xigetclientpointer.c \
+ xigetclientpointer.h \
+ xigrabdev.c \
+ xigrabdev.h \
+ xipassivegrab.h \
+ xipassivegrab.c \
xiproperty.c \
- xiproperty.h
+ xiproperty.h \
+ xiquerydevice.c \
+ xiquerydevice.h \
+ xiquerypointer.c \
+ xiquerypointer.h \
+ xiqueryversion.c \
+ xiqueryversion.h \
+ xiselectev.c \
+ xiselectev.h \
+ xisetclientpointer.c \
+ xisetclientpointer.h \
+ xisetdevfocus.c \
+ xisetdevfocus.h \
+ xiwarppointer.c \
+ xiwarppointer.h
EXTRA_DIST = stubs.c
diff --git a/xorg-server/Xi/Makefile.in b/xorg-server/Xi/Makefile.in
index 9da131ad2..10cb1c7b4 100644
--- a/xorg-server/Xi/Makefile.in
+++ b/xorg-server/Xi/Makefile.in
@@ -37,8 +37,11 @@ host_triplet = @host@
subdir = Xi
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \
+ $(top_srcdir)/m4/dolt.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/shave.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -48,7 +51,8 @@ CONFIG_HEADER = $(top_builddir)/include/do-not-use-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
+ $(top_builddir)/include/kdrive-config.h \
+ $(top_builddir)/include/version-config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
@@ -60,7 +64,11 @@ am_libXi_la_OBJECTS = allowev.lo chgdctl.lo chgfctl.lo chgkbd.lo \
getvers.lo grabdev.lo grabdevb.lo grabdevk.lo gtmotion.lo \
listdev.lo opendev.lo queryst.lo selectev.lo sendexev.lo \
setbmap.lo setdval.lo setfocus.lo setmmap.lo setmode.lo \
- ungrdev.lo ungrdevb.lo ungrdevk.lo xiproperty.lo
+ ungrdev.lo ungrdevb.lo ungrdevk.lo xiallowev.lo \
+ xichangecursor.lo xichangehierarchy.lo xigetclientpointer.lo \
+ xigrabdev.lo xipassivegrab.lo xiproperty.lo xiquerydevice.lo \
+ xiquerypointer.lo xiqueryversion.lo xiselectev.lo \
+ xisetclientpointer.lo xisetdevfocus.lo xiwarppointer.lo
libXi_la_OBJECTS = $(am_libXi_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -82,6 +90,7 @@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
+AM_MAKEFLAGS = @AM_MAKEFLAGS@
APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@
APPLE_APPLICATION_ID = @APPLE_APPLICATION_ID@
APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@
@@ -102,9 +111,12 @@ CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
CYGPATH_W = @CYGPATH_W@
DARWIN_LIBS = @DARWIN_LIBS@
DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -133,7 +145,9 @@ DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@
DRIPROTO_LIBS = @DRIPROTO_LIBS@
DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DRI_CFLAGS = @DRI_CFLAGS@
DRI_DRIVER_PATH = @DRI_DRIVER_PATH@
+DRI_LIBS = @DRI_LIBS@
DSYMUTIL = @DSYMUTIL@
DTRACE = @DTRACE@
DUMPBIN = @DUMPBIN@
@@ -142,9 +156,13 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+F77 = @F77@
+FC = @FC@
FGREP = @FGREP@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@
GLX_DEFINES = @GLX_DEFINES@
GL_CFLAGS = @GL_CFLAGS@
@@ -183,12 +201,13 @@ LTCOMPILE = @LTCOMPILE@
LTCXXCOMPILE = @LTCXXCOMPILE@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
+MAIN_LIB = @MAIN_LIB@
+MAKEFLAGS = @MAKEFLAGS@
MAKEINFO = @MAKEINFO@
MAKE_HTML = @MAKE_HTML@
MAKE_PDF = @MAKE_PDF@
MAKE_PS = @MAKE_PS@
MAKE_TEXT = @MAKE_TEXT@
-MESA_SOURCE = @MESA_SOURCE@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
@@ -208,7 +227,6 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
@@ -218,6 +236,7 @@ PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
PROJECTROOT = @PROJECTROOT@
PS2PDF = @PS2PDF@
+Q = @Q@
RANLIB = @RANLIB@
RAWCPP = @RAWCPP@
RAWCPPFLAGS = @RAWCPPFLAGS@
@@ -231,11 +250,10 @@ STRIP = @STRIP@
TSLIB_CFLAGS = @TSLIB_CFLAGS@
TSLIB_LIBS = @TSLIB_LIBS@
UTILS_SYS_LIBS = @UTILS_SYS_LIBS@
-VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@
-VENDOR_NAME = @VENDOR_NAME@
+V = @V@
VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
-VENDOR_RELEASE = @VENDOR_RELEASE@
VERSION = @VERSION@
+WINDRES = @WINDRES@
X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
XDMCP_CFLAGS = @XDMCP_CFLAGS@
@@ -271,6 +289,7 @@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@
XORG_SYS_LIBS = @XORG_SYS_LIBS@
XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@
XPBPROXY_LIBS = @XPBPROXY_LIBS@
+XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@
XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@
XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@
XSDL_INCS = @XSDL_INCS@
@@ -295,7 +314,6 @@ YFLAGS = @YFLAGS@
__XCONFIGFILE__ = @__XCONFIGFILE__@
abi_ansic = @abi_ansic@
abi_extension = @abi_extension@
-abi_font = @abi_font@
abi_videodrv = @abi_videodrv@
abi_xinput = @abi_xinput@
abs_builddir = @abs_builddir@
@@ -318,6 +336,7 @@ build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
docdir = @docdir@
driverdir = @driverdir@
dvidir = @dvidir@
@@ -349,7 +368,9 @@ psdir = @psdir@
sbindir = @sbindir@
sdkdir = @sdkdir@
sharedstatedir = @sharedstatedir@
+shavedir = @shavedir@
srcdir = @srcdir@
+symbol_visibility = @symbol_visibility@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
@@ -431,8 +452,34 @@ libXi_la_SOURCES = \
ungrdevb.h \
ungrdevk.c \
ungrdevk.h \
+ xiallowev.c \
+ xiallowev.h \
+ xichangecursor.c \
+ xichangecursor.h \
+ xichangehierarchy.c \
+ xichangehierarchy.h \
+ xigetclientpointer.c \
+ xigetclientpointer.h \
+ xigrabdev.c \
+ xigrabdev.h \
+ xipassivegrab.h \
+ xipassivegrab.c \
xiproperty.c \
- xiproperty.h
+ xiproperty.h \
+ xiquerydevice.c \
+ xiquerydevice.h \
+ xiquerypointer.c \
+ xiquerypointer.h \
+ xiqueryversion.c \
+ xiqueryversion.h \
+ xiselectev.c \
+ xiselectev.h \
+ xisetclientpointer.c \
+ xisetclientpointer.h \
+ xisetdevfocus.c \
+ xisetdevfocus.h \
+ xiwarppointer.c \
+ xiwarppointer.h
EXTRA_DIST = stubs.c
all: all-am
@@ -524,7 +571,20 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ungrdev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ungrdevb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ungrdevk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiallowev.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xichangecursor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xichangehierarchy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xigetclientpointer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xigrabdev.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xipassivegrab.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiproperty.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiquerydevice.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiquerypointer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiqueryversion.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiselectev.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xisetclientpointer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xisetdevfocus.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiwarppointer.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/xorg-server/Xi/allowev.c b/xorg-server/Xi/allowev.c
index 36b6caad5..96f3b543c 100644
--- a/xorg-server/Xi/allowev.c
+++ b/xorg-server/Xi/allowev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -106,22 +104,22 @@ ProcXAllowDeviceEvents(ClientPtr client)
switch (stuff->mode) {
case ReplayThisDevice:
- AllowSome(client, time, thisdev, NOT_GRABBED, FALSE);
+ AllowSome(client, time, thisdev, NOT_GRABBED);
break;
case SyncThisDevice:
- AllowSome(client, time, thisdev, FREEZE_NEXT_EVENT, FALSE);
+ AllowSome(client, time, thisdev, FREEZE_NEXT_EVENT);
break;
case AsyncThisDevice:
- AllowSome(client, time, thisdev, THAWED, FALSE);
+ AllowSome(client, time, thisdev, THAWED);
break;
case AsyncOtherDevices:
- AllowSome(client, time, thisdev, THAW_OTHERS, FALSE);
+ AllowSome(client, time, thisdev, THAW_OTHERS);
break;
case SyncAll:
- AllowSome(client, time, thisdev, FREEZE_BOTH_NEXT_EVENT, FALSE);
+ AllowSome(client, time, thisdev, FREEZE_BOTH_NEXT_EVENT);
break;
case AsyncAll:
- AllowSome(client, time, thisdev, THAWED_BOTH, FALSE);
+ AllowSome(client, time, thisdev, THAWED_BOTH);
break;
default:
client->errorValue = stuff->mode;
diff --git a/xorg-server/Xi/chgdctl.c b/xorg-server/Xi/chgdctl.c
index 6044f6cd6..901a0e419 100644
--- a/xorg-server/Xi/chgdctl.c
+++ b/xorg-server/Xi/chgdctl.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -144,7 +142,7 @@ ProcXChangeDeviceControl(ClientPtr client)
REQUEST(xChangeDeviceControlReq);
REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
- len = stuff->length - (sizeof(xChangeDeviceControlReq) >> 2);
+ len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq));
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
if (ret != Success)
goto out;
@@ -157,8 +155,8 @@ ProcXChangeDeviceControl(ClientPtr client)
switch (stuff->control) {
case DEVICE_RESOLUTION:
r = (xDeviceResolutionCtl *) & stuff[1];
- if ((len < (sizeof(xDeviceResolutionCtl) >> 2)) ||
- (len != (sizeof(xDeviceResolutionCtl) >> 2) + r->num_valuators)) {
+ if ((len < bytes_to_int32(sizeof(xDeviceResolutionCtl))) ||
+ (len != bytes_to_int32(sizeof(xDeviceResolutionCtl)) + r->num_valuators)) {
ret = BadLength;
goto out;
}
@@ -255,9 +253,9 @@ ProcXChangeDeviceControl(ClientPtr client)
if (status == Success) {
if (e->enable)
- EnableDevice(dev);
+ EnableDevice(dev, TRUE);
else
- DisableDevice(dev);
+ DisableDevice(dev, TRUE);
ret = Success;
} else if (status == DeviceBusy) {
rep.status = DeviceBusy;
diff --git a/xorg-server/Xi/chgfctl.c b/xorg-server/Xi/chgfctl.c
index 3155e87c2..9189702c1 100644
--- a/xorg-server/Xi/chgfctl.c
+++ b/xorg-server/Xi/chgfctl.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -443,14 +441,14 @@ ProcXChangeFeedbackControl(ClientPtr client)
REQUEST(xChangeFeedbackControlReq);
REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
- len = stuff->length - (sizeof(xChangeFeedbackControlReq) >> 2);
+ len = stuff->length - bytes_to_int32(sizeof(xChangeFeedbackControlReq));
rc = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
if (rc != Success)
return rc;
switch (stuff->feedbackid) {
case KbdFeedbackClass:
- if (len != (sizeof(xKbdFeedbackCtl) >> 2))
+ if (len != bytes_to_int32(sizeof(xKbdFeedbackCtl)))
return BadLength;
for (k = dev->kbdfeed; k; k = k->next)
@@ -459,7 +457,7 @@ ProcXChangeFeedbackControl(ClientPtr client)
(xKbdFeedbackCtl *) & stuff[1]);
break;
case PtrFeedbackClass:
- if (len != (sizeof(xPtrFeedbackCtl) >> 2))
+ if (len != bytes_to_int32(sizeof(xPtrFeedbackCtl)))
return BadLength;
for (p = dev->ptrfeed; p; p = p->next)
@@ -475,7 +473,7 @@ ProcXChangeFeedbackControl(ClientPtr client)
if (client->swapped) {
swaps(&f->num_keysyms, n);
}
- if (len != ((sizeof(xStringFeedbackCtl) >> 2) + f->num_keysyms))
+ if (len != (bytes_to_int32(sizeof(xStringFeedbackCtl)) + f->num_keysyms))
return BadLength;
for (s = dev->stringfeed; s; s = s->next)
@@ -485,7 +483,7 @@ ProcXChangeFeedbackControl(ClientPtr client)
break;
}
case IntegerFeedbackClass:
- if (len != (sizeof(xIntegerFeedbackCtl) >> 2))
+ if (len != bytes_to_int32(sizeof(xIntegerFeedbackCtl)))
return BadLength;
for (i = dev->intfeed; i; i = i->next)
@@ -494,7 +492,7 @@ ProcXChangeFeedbackControl(ClientPtr client)
(xIntegerFeedbackCtl *)&stuff[1]);
break;
case LedFeedbackClass:
- if (len != (sizeof(xLedFeedbackCtl) >> 2))
+ if (len != bytes_to_int32(sizeof(xLedFeedbackCtl)))
return BadLength;
for (l = dev->leds; l; l = l->next)
@@ -503,7 +501,7 @@ ProcXChangeFeedbackControl(ClientPtr client)
(xLedFeedbackCtl *) & stuff[1]);
break;
case BellFeedbackClass:
- if (len != (sizeof(xBellFeedbackCtl) >> 2))
+ if (len != bytes_to_int32(sizeof(xBellFeedbackCtl)))
return BadLength;
for (b = dev->bell; b; b = b->next)
diff --git a/xorg-server/Xi/chgkbd.c b/xorg-server/Xi/chgkbd.c
index 83de646f1..f9fd09902 100644
--- a/xorg-server/Xi/chgkbd.c
+++ b/xorg-server/Xi/chgkbd.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/Xi/chgkmap.c b/xorg-server/Xi/chgkmap.c
index 3f51648e1..e4b9e154c 100644
--- a/xorg-server/Xi/chgkmap.c
+++ b/xorg-server/Xi/chgkmap.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -109,7 +107,7 @@ ProcXChangeDeviceKeyMapping(ClientPtr client)
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
if (ret != Success)
return ret;
- len = stuff->length - (sizeof(xChangeDeviceKeyMappingReq) >> 2);
+ len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceKeyMappingReq));
ret = ChangeKeyMapping(client, dev, len, DeviceMappingNotify,
stuff->firstKeyCode, stuff->keyCodes,
diff --git a/xorg-server/Xi/chgprop.c b/xorg-server/Xi/chgprop.c
index 3fb33e129..d24a24638 100644
--- a/xorg-server/Xi/chgprop.c
+++ b/xorg-server/Xi/chgprop.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -106,7 +104,7 @@ ProcXChangeDeviceDontPropagateList(ClientPtr client)
REQUEST(xChangeDeviceDontPropagateListReq);
REQUEST_AT_LEAST_SIZE(xChangeDeviceDontPropagateListReq);
- if (stuff->length != (sizeof(xChangeDeviceDontPropagateListReq) >> 2) +
+ if (stuff->length != bytes_to_int32(sizeof(xChangeDeviceDontPropagateListReq)) +
stuff->count)
return BadLength;
diff --git a/xorg-server/Xi/chgptr.c b/xorg-server/Xi/chgptr.c
index 28950918f..6a4fbc342 100644
--- a/xorg-server/Xi/chgptr.c
+++ b/xorg-server/Xi/chgptr.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/Xi/closedev.c b/xorg-server/Xi/closedev.c
index 2be908c4a..159ead55c 100644
--- a/xorg-server/Xi/closedev.c
+++ b/xorg-server/Xi/closedev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/Xi/devbell.c b/xorg-server/Xi/devbell.c
index 264f64800..539da1814 100644
--- a/xorg-server/Xi/devbell.c
+++ b/xorg-server/Xi/devbell.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index 0bb84f86c..0211e72b7 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -52,17 +52,17 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
+#include "inputstr.h"
#include <X11/X.h>
#include <X11/Xproto.h>
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
#include <X11/extensions/geproto.h>
-#include "inputstr.h"
#include "windowstr.h"
#include "miscstruct.h"
#include "region.h"
@@ -74,12 +74,12 @@ SOFTWARE.
#include "scrnintstr.h"
#include "listdev.h" /* for CopySwapXXXClass */
#include "xace.h"
+#include "xiquerydevice.h" /* For List*Info */
+#include "eventconvert.h"
+#include "eventstr.h"
-#ifdef XKB
#include <X11/extensions/XKBproto.h>
#include "xkbsrv.h"
-extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
-#endif
#define WID(w) ((w) ? ((w)->drawable.id) : 0)
#define AllModifiersMask ( \
@@ -87,8 +87,6 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
Mod3Mask | Mod4Mask | Mod5Mask )
#define AllButtonsMask ( \
Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
-#define Motion_Filter(class) (DevicePointerMotionMask | \
- (class)->state | (class)->motionMask)
Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
Bool /* ignoreSelectedEvents */
@@ -99,6 +97,22 @@ static Bool MakeInputMasks(WindowPtr /* pWin */
/* Used to sture classes currently not in use by an MD */
extern DevPrivateKey UnusedClassesPrivateKey;
+/*
+ * Only let the given client know of core events which will affect its
+ * interpretation of input events, if the client's ClientPointer (or the
+ * paired keyboard) is the current device.
+ */
+int
+XIShouldNotify(ClientPtr client, DeviceIntPtr dev)
+{
+ DeviceIntPtr current_ptr = PickPointer(client);
+ DeviceIntPtr current_kbd = GetPairedDevice(current_ptr);
+
+ if (dev == current_kbd || dev == current_ptr)
+ return 1;
+
+ return 0;
+}
void
RegisterOtherDevice(DeviceIntPtr device)
@@ -108,25 +122,17 @@ RegisterOtherDevice(DeviceIntPtr device)
}
Bool
-IsPointerEvent(xEvent* xE)
+IsPointerEvent(InternalEvent* event)
{
- switch(xE->u.u.type)
+ switch(event->any.type)
{
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case EnterNotify:
- case LeaveNotify:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_Motion:
+ /* XXX: enter/leave ?? */
return TRUE;
default:
- 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)
- {
- return TRUE;
- }
+ break;
}
return FALSE;
}
@@ -186,88 +192,23 @@ XIGetDevice(xEvent* xE)
* This code is basically the old SwitchCoreKeyboard.
*/
-void
+static void
CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
{
- static DeviceIntPtr lastMapNotifyDevice = NULL;
- KeyClassPtr mk, dk; /* master, device */
- BOOL sendNotify = FALSE;
+ KeyClassPtr mk = master->key;
+ KeyClassPtr dk = device->key;
int i;
if (device == master)
return;
- dk = device->key;
- mk = master->key;
+ mk->sourceid = device->id;
- if (device != dixLookupPrivate(&master->devPrivates,
- CoreDevicePrivateKey)) {
- memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH);
+ for (i = 0; i < 8; i++)
+ mk->modifierKeyCount[i] = dk->modifierKeyCount[i];
- if (dk->maxKeysPerModifier)
- {
- mk->modifierKeyMap = xrealloc(mk->modifierKeyMap,
- 8 * dk->maxKeysPerModifier);
- if (!mk->modifierKeyMap)
- FatalError("[Xi] no memory for class shift.\n");
- memcpy(mk->modifierKeyMap, dk->modifierKeyMap,
- (8 * dk->maxKeysPerModifier));
- } else
- {
- xfree(mk->modifierKeyMap);
- mk->modifierKeyMap = NULL;
- }
-
- mk->maxKeysPerModifier = dk->maxKeysPerModifier;
- mk->curKeySyms.minKeyCode = dk->curKeySyms.minKeyCode;
- mk->curKeySyms.maxKeyCode = dk->curKeySyms.maxKeyCode;
- SetKeySymsMap(&mk->curKeySyms, &dk->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)
- mk->state &= ~(KEYBOARD_MASK);
- mk->state |= (dk->state & KEYBOARD_MASK);
-#undef KEYBOARD_MASK
- for (i = 0; i < 8; i++)
- mk->modifierKeyCount[i] = dk->modifierKeyCount[i];
-
-#ifdef XKB
- if (!noXkbExtension && dk->xkbInfo && dk->xkbInfo->desc) {
- if (!mk->xkbInfo || !mk->xkbInfo->desc)
- {
- XkbInitDevice(master);
- XkbFinishDeviceInit(master);
- }
- if (!XkbCopyKeymap(dk->xkbInfo->desc, mk->xkbInfo->desc, True))
- FatalError("Couldn't pivot keymap from device to core!\n");
- }
-#endif
-
- dixSetPrivate(&master->devPrivates, CoreDevicePrivateKey, device);
- sendNotify = TRUE;
- } else if (lastMapNotifyDevice != master)
- sendNotify = TRUE;
-
- if (sendNotify)
- {
- SendMappingNotify(master, MappingKeyboard,
- mk->curKeySyms.minKeyCode,
- (mk->curKeySyms.maxKeyCode -
- mk->curKeySyms.minKeyCode),
- serverClient);
- lastMapNotifyDevice = master;
- }
+ if (!XkbCopyDeviceKeymap(master, device))
+ FatalError("Couldn't pivot keymap from device to core!\n");
}
/**
@@ -280,82 +221,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
{
ClassesPtr classes;
- if (from->kbdfeed)
- {
- KbdFeedbackPtr *k, it;
-
- if (!to->kbdfeed)
- {
- classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
- to->kbdfeed = classes->kbdfeed;
- }
-
- k = &to->kbdfeed;
- for(it = from->kbdfeed; it; it = it->next)
- {
- if (!(*k))
- {
- *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
- if (!*k)
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*k)->BellProc = it->BellProc;
- (*k)->CtrlProc = it->CtrlProc;
- (*k)->ctrl = it->ctrl;
-#ifdef XKB
- if ((*k)->xkb_sli)
- XkbFreeSrvLedInfo((*k)->xkb_sli);
- (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
-#endif
-
- k = &(*k)->next;
- }
- } else if (to->kbdfeed && !from->kbdfeed)
- {
- ClassesPtr classes;
- classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->kbdfeed = to->kbdfeed;
- to->kbdfeed = NULL;
- }
-
- if (from->ptrfeed)
- {
- PtrFeedbackPtr *p, it;
- if (!to->ptrfeed)
- {
- classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
- to->ptrfeed = classes->ptrfeed;
- }
-
- p = &to->ptrfeed;
- for (it = from->ptrfeed; it; it = it->next)
- {
- if (!(*p))
- {
- *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
- if (!*p)
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*p)->CtrlProc = it->CtrlProc;
- (*p)->ctrl = it->ctrl;
-
- p = &(*p)->next;
- }
- } else if (to->ptrfeed && !from->ptrfeed)
- {
- ClassesPtr classes;
- classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->ptrfeed = to->ptrfeed;
- to->ptrfeed = NULL;
- }
if (from->intfeed)
{
@@ -491,11 +356,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
}
(*l)->CtrlProc = it->CtrlProc;
(*l)->ctrl = it->ctrl;
-#ifdef XKB
if ((*l)->xkb_sli)
XkbFreeSrvLedInfo((*l)->xkb_sli);
(*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l);
-#endif
l = &(*l)->next;
}
@@ -508,74 +371,161 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
}
}
-/**
- * Copies the CONTENT of the classes of device from into the classes in device
- * to. From and to are identical after finishing.
- *
- * If to does not have classes from currenly has, the classes are stored in
- * to's devPrivates system. Later, we recover it again from there if needed.
- * Saves a few memory allocations.
- */
-
-void
-DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
+static void
+DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
{
ClassesPtr classes;
/* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
* kbdfeed to be set up properly, so let's do the feedback classes first.
*/
- DeepCopyFeedbackClasses(from, to);
+ if (from->kbdfeed)
+ {
+ KbdFeedbackPtr *k, it;
+
+ if (!to->kbdfeed)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+
+ to->kbdfeed = classes->kbdfeed;
+ if (!to->kbdfeed)
+ InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+ }
+
+ k = &to->kbdfeed;
+ for(it = from->kbdfeed; it; it = it->next)
+ {
+ if (!(*k))
+ {
+ *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
+ if (!*k)
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*k)->BellProc = it->BellProc;
+ (*k)->CtrlProc = it->CtrlProc;
+ (*k)->ctrl = it->ctrl;
+ if ((*k)->xkb_sli)
+ XkbFreeSrvLedInfo((*k)->xkb_sli);
+ (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
+
+ k = &(*k)->next;
+ }
+ } else if (to->kbdfeed && !from->kbdfeed)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->kbdfeed = to->kbdfeed;
+ to->kbdfeed = NULL;
+ }
if (from->key)
{
- KeyCode *oldModKeyMap;
- KeySym *oldMap;
-#ifdef XKB
- struct _XkbSrvInfo *oldXkbInfo;
-#endif
if (!to->key)
{
classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
+ UnusedClassesPrivateKey);
to->key = classes->key;
if (!to->key)
+ InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+ else
+ classes->key = NULL;
+ }
+
+ CopyKeyClass(from, to);
+ } else if (to->key && !from->key)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->key = to->key;
+ to->key = NULL;
+ }
+
+ /* We can't just copy over the focus class. When an app sets the focus,
+ * it'll do so on the master device. Copying the SDs focus means losing
+ * the focus.
+ * So we only copy the focus class if the device didn't have one,
+ * otherwise we leave it as it is.
+ */
+ if (from->focus)
+ {
+ if (!to->focus)
+ {
+ WindowPtr *oldTrace;
+
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->focus = classes->focus;
+ if (!to->focus)
{
- to->key = xcalloc(1, sizeof(KeyClassRec));
- if (!to->key)
+ to->focus = xcalloc(1, sizeof(FocusClassRec));
+ if (!to->focus)
FatalError("[Xi] no memory for class shift.\n");
} else
- classes->key = NULL;
+ classes->focus = NULL;
+
+ oldTrace = to->focus->trace;
+ memcpy(to->focus, from->focus, sizeof(FocusClassRec));
+ to->focus->trace = xrealloc(oldTrace,
+ to->focus->traceSize * sizeof(WindowPtr));
+ if (!to->focus->trace && to->focus->traceSize)
+ FatalError("[Xi] no memory for trace.\n");
+ memcpy(to->focus->trace, from->focus->trace,
+ from->focus->traceSize * sizeof(WindowPtr));
+ to->focus->sourceid = from->id;
}
+ } else if (to->focus)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->focus = to->focus;
+ to->focus = NULL;
+ }
- oldModKeyMap = to->key->modifierKeyMap;
- oldMap = to->key->curKeySyms.map;
-#ifdef XKB
- oldXkbInfo = to->key->xkbInfo;
-#endif
+}
- if (!oldMap) /* newly created key struct */
+static void
+DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
+{
+ ClassesPtr classes;
+
+ /* Feedback classes must be copied first */
+ if (from->ptrfeed)
+ {
+ PtrFeedbackPtr *p, it;
+ if (!to->ptrfeed)
{
- int bytes = (to->key->curKeySyms.maxKeyCode -
- to->key->curKeySyms.minKeyCode + 1) *
- to->key->curKeySyms.mapWidth;
- oldMap = (KeySym *)xcalloc(sizeof(KeySym), bytes);
- memcpy(oldMap, from->key->curKeySyms.map, bytes);
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->ptrfeed = classes->ptrfeed;
}
- to->key->modifierKeyMap = oldModKeyMap;
- to->key->curKeySyms.map = oldMap;
-#ifdef XKB
- to->key->xkbInfo = oldXkbInfo;
-#endif
+ p = &to->ptrfeed;
+ for (it = from->ptrfeed; it; it = it->next)
+ {
+ if (!(*p))
+ {
+ *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
+ if (!*p)
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*p)->CtrlProc = it->CtrlProc;
+ (*p)->ctrl = it->ctrl;
- CopyKeyClass(from, to);
- } else if (to->key && !from->key)
+ p = &(*p)->next;
+ }
+ } else if (to->ptrfeed && !from->ptrfeed)
{
ClassesPtr classes;
classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->key = to->key;
- to->key = NULL;
+ classes->ptrfeed = to->ptrfeed;
+ to->ptrfeed = NULL;
}
if (from->valuator)
@@ -592,7 +542,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) +
from->valuator->numAxes * sizeof(AxisInfo) +
- from->valuator->numAxes * sizeof(unsigned int));
+ from->valuator->numAxes * sizeof(double));
v = to->valuator;
if (!v)
FatalError("[Xi] no memory for class shift.\n");
@@ -601,7 +551,9 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
v->axes = (AxisInfoPtr)&v[1];
memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo));
- v->axisVal = (int*)(v->axes + from->valuator->numAxes);
+ v->axisVal = (double*)(v->axes + from->valuator->numAxes);
+ v->sourceid = from->id;
+ v->mode = from->valuator->mode;
} else if (to->valuator && !from->valuator)
{
ClassesPtr classes;
@@ -626,7 +578,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->button = NULL;
}
-#ifdef XKB
if (from->button->xkb_acts)
{
if (!to->button->xkb_acts)
@@ -639,7 +590,10 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
sizeof(XkbAction));
} else
xfree(to->button->xkb_acts);
-#endif
+
+ memcpy(to->button->labels, from->button->labels,
+ from->button->numButtons * sizeof(Atom));
+ to->button->sourceid = from->id;
} else if (to->button && !from->button)
{
ClassesPtr classes;
@@ -648,47 +602,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
to->button = NULL;
}
-
- /* We can't just copy over the focus class. When an app sets the focus,
- * it'll do so on the master device. Copying the SDs focus means losing
- * the focus.
- * So we only copy the focus class if the device didn't have one,
- * otherwise we leave it as it is.
- */
- if (from->focus)
- {
- if (!to->focus)
- {
- WindowPtr *oldTrace;
-
- classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
- to->focus = classes->focus;
- if (!to->focus)
- {
- to->focus = xcalloc(1, sizeof(FocusClassRec));
- if (!to->focus)
- FatalError("[Xi] no memory for class shift.\n");
- } else
- classes->focus = NULL;
-
- oldTrace = to->focus->trace;
- memcpy(to->focus, from->focus, sizeof(FocusClassRec));
- to->focus->trace = xrealloc(oldTrace,
- to->focus->traceSize * sizeof(WindowPtr));
- if (!to->focus->trace && to->focus->traceSize)
- FatalError("[Xi] no memory for trace.\n");
- memcpy(to->focus->trace, from->focus->trace,
- from->focus->traceSize * sizeof(WindowPtr));
- }
- } else if (to->focus)
- {
- ClassesPtr classes;
- classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->focus = to->focus;
- to->focus = NULL;
- }
-
if (from->proximity)
{
if (!to->proximity)
@@ -705,6 +618,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->proximity = NULL;
}
memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec));
+ to->proximity->sourceid = from->id;
} else if (to->proximity)
{
ClassesPtr classes;
@@ -729,6 +643,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->absolute = NULL;
}
memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec));
+ to->absolute->sourceid = from->id;
} else if (to->absolute)
{
ClassesPtr classes;
@@ -738,6 +653,78 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
}
}
+/**
+ * Copies the CONTENT of the classes of device from into the classes in device
+ * to. From and to are identical after finishing.
+ *
+ * If to does not have classes from currenly has, the classes are stored in
+ * to's devPrivates system. Later, we recover it again from there if needed.
+ * Saves a few memory allocations.
+ */
+void
+DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce)
+{
+ /* generic feedback classes, not tied to pointer and/or keyboard */
+ DeepCopyFeedbackClasses(from, to);
+
+ if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT))
+ DeepCopyKeyboardClasses(from, to);
+ if ((dce->flags & DEVCHANGE_POINTER_EVENT))
+ DeepCopyPointerClasses(from, to);
+}
+
+
+/**
+ * Send an XI2 DeviceChangedEvent to all interested clients.
+ */
+void
+XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
+{
+ xXIDeviceChangedEvent *dcce;
+ int rc;
+
+ rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce);
+ if (rc != Success)
+ {
+ ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc);
+ return;
+ }
+
+ /* we don't actually swap if there's a NullClient, swapping is done
+ * later when event is delivered. */
+ SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1);
+ xfree(dcce);
+}
+
+static void
+ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
+{
+ DeviceIntPtr slave;
+ int rc;
+
+ /* For now, we don't have devices that change physically. */
+ if (!IsMaster(device))
+ return;
+
+ rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess);
+
+ if (rc != Success)
+ return; /* Device has disappeared */
+
+ if (!slave->u.master)
+ return; /* set floating since the event */
+
+ if (slave->u.master->id != dce->masterid)
+ return; /* not our slave anymore, don't care */
+
+ /* FIXME: we probably need to send a DCE for the new slave now */
+
+ device->public.devicePrivate = slave->public.devicePrivate;
+
+ /* FIXME: the classes may have changed since we generated the event. */
+ DeepCopyDeviceClasses(slave, device, dce);
+ XISendDeviceChangedEvent(slave, device, dce);
+}
/**
* Update the device state according to the data in the event.
@@ -745,147 +732,106 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
* return values are
* DEFAULT ... process as normal
* DONT_PROCESS ... return immediately from caller
- * IS_REPEAT .. event is a repeat event.
*/
#define DEFAULT 0
#define DONT_PROCESS 1
-#define IS_REPEAT 2
int
-UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
+UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
{
int i;
int key = 0,
- bit = 0;
+ bit = 0,
+ last_valuator;
KeyClassPtr k = NULL;
ButtonClassPtr b = NULL;
ValuatorClassPtr v = NULL;
- deviceValuator *xV = (deviceValuator *) xE;
BYTE *kptr = NULL;
- CARD16 modifiers = 0,
- mask = 0;
- /* currently no other generic event modifies the device */
- if (xE->u.u.type == GenericEvent)
- return DEFAULT;
+ /* This event is always the first we get, before the actual events with
+ * the data. However, the way how the DDX is set up, "device" will
+ * actually be the slave device that caused the event.
+ */
+ switch(event->type)
+ {
+ case ET_DeviceChanged:
+ ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event);
+ return DONT_PROCESS; /* event has been sent already */
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ break;
+ default:
+ /* other events don't update the device */
+ return DEFAULT;
+ }
k = device->key;
v = device->valuator;
b = device->button;
+ key = event->detail.key;
+ bit = 1 << (key & 7);
- if (xE->u.u.type != DeviceValuator)
+ /* Update device axis */
+ /* Check valuators first */
+ last_valuator = -1;
+ for (i = 0; i < MAX_VALUATORS; i++)
{
- key = xE->u.u.detail;
- bit = 1 << (key & 7);
+ if (BitIsOn(&event->valuators.mask, i))
+ {
+ if (!v)
+ {
+ ErrorF("[Xi] Valuators reported for non-valuator device '%s'. "
+ "Ignoring event.\n", device->name);
+ return DONT_PROCESS;
+ } else if (v->numAxes < i)
+ {
+ ErrorF("[Xi] Too many valuators reported for device '%s'. "
+ "Ignoring event.\n", device->name);
+ return DONT_PROCESS;
+ }
+ last_valuator = i;
+ }
}
- /* Update device axis */
- /* Don't update valuators for the VCP, it never sends XI events anyway */
- for (i = 1; !device->isMaster && i < count; i++) {
- if ((++xV)->type == DeviceValuator) {
- int *axisvals;
- int first = xV->first_valuator;
- BOOL change = FALSE;
-
-
- if (xV->num_valuators &&
- (!v || (xV->num_valuators &&
- (first + xV->num_valuators > v->numAxes))))
- FatalError("Bad valuators reported for device %s\n",
- device->name);
- if (v && v->axisVal) {
- /* v->axisVal is always in absolute coordinates. Only the
- * delivery mode changes.
- * If device is mode Absolute
- * dev = event
- * If device is mode Relative
- * swap = (event - device)
- * dev = event
- * event = delta
- */
- int delta;
- axisvals = v->axisVal;
- if (v->mode == Relative) /* device reports relative */
- change = TRUE;
-
- switch (xV->num_valuators) {
- case 6:
- if (change) delta = xV->valuator5 - *(axisvals + first + 5);
- *(axisvals + first + 5) = xV->valuator5;
- if (change) xV->valuator5 = delta;
- case 5:
- if (change) delta = xV->valuator4 - *(axisvals + first + 4);
- *(axisvals + first + 4) = xV->valuator4;
- if (change) xV->valuator4 = delta;
- case 4:
- if (change) delta = xV->valuator3 - *(axisvals + first + 3);
- *(axisvals + first + 3) = xV->valuator3;
- if (change) xV->valuator3 = delta;
- case 3:
- if (change) delta = xV->valuator2 - *(axisvals + first + 2);
- *(axisvals + first + 2) = xV->valuator2;
- if (change) xV->valuator2 = delta;
- case 2:
- if (change) delta = xV->valuator1 - *(axisvals + first + 1);
- *(axisvals + first + 1) = xV->valuator1;
- if (change) xV->valuator1 = delta;
- case 1:
- if (change) delta = xV->valuator0 - *(axisvals + first);
- *(axisvals + first) = xV->valuator0;
- if (change) xV->valuator0 = delta;
- case 0:
- default:
- break;
- }
- }
- }
+ for (i = 0; i <= last_valuator && i < v->numAxes; i++)
+ {
+ if (BitIsOn(&event->valuators.mask, i))
+ {
+ /* XXX: Relative/Absolute mode */
+ v->axisVal[i] = event->valuators.data[i];
+ v->axisVal[i] += event->valuators.data_frac[i];
+ }
}
- if (xE->u.u.type == DeviceKeyPress) {
+ if (event->type == ET_KeyPress) {
if (!k)
return DONT_PROCESS;
- modifiers = k->modifierMap[key];
kptr = &k->down[key >> 3];
- if (*kptr & bit) { /* allow ddx to generate multiple downs */
- return IS_REPEAT;
- }
+ /* don't allow ddx to generate multiple downs, but repeats are okay */
+ if ((*kptr & bit) && !event->key_repeat)
+ return DONT_PROCESS;
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
*kptr |= bit;
- k->prev_state = k->state;
- for (i = 0, mask = 1; modifiers; i++, mask <<= 1) {
- if (mask & modifiers) {
- /* This key affects modifier "i" */
- k->modifierKeyCount[i]++;
- k->state |= mask;
- modifiers &= ~mask;
- }
- }
- } else if (xE->u.u.type == DeviceKeyRelease) {
+ } else if (event->type == ET_KeyRelease) {
if (!k)
return DONT_PROCESS;
kptr = &k->down[key >> 3];
if (!(*kptr & bit)) /* guard against duplicates */
return DONT_PROCESS;
- modifiers = k->modifierMap[key];
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
*kptr &= ~bit;
- k->prev_state = k->state;
- for (i = 0, mask = 1; modifiers; i++, mask <<= 1) {
- if (mask & modifiers) {
- /* This key affects modifier "i" */
- if (--k->modifierKeyCount[i] <= 0) {
- k->modifierKeyCount[i] = 0;
- k->state &= ~mask;
- }
- modifiers &= ~mask;
- }
- }
- } else if (xE->u.u.type == DeviceButtonPress) {
+ } else if (event->type == ET_ButtonPress) {
+ Mask mask;
if (!b)
return DONT_PROCESS;
@@ -901,15 +847,21 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
b->motionMask = DeviceButtonMotionMask;
if (b->map[key] <= 5)
b->state |= (Button1Mask >> 1) << b->map[key];
- SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
- } else if (xE->u.u.type == DeviceButtonRelease) {
+
+ /* Add state and motionMask to the filter for this event */
+ mask = DevicePointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, DeviceMotionNotify);
+ mask = PointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, MotionNotify);
+ } else if (event->type == ET_ButtonRelease) {
+ Mask mask;
if (!b)
return DONT_PROCESS;
kptr = &b->down[key>>3];
if (!(*kptr & bit))
return DONT_PROCESS;
- if (device->isMaster) {
+ if (IsMaster(device)) {
DeviceIntPtr sd;
/*
@@ -918,7 +870,9 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
* event being delivered through the slave first
*/
for (sd = inputInfo.devices; sd; sd = sd->next) {
- if (sd->isMaster || sd->u.master != device)
+ if (IsMaster(sd) || sd->u.master != device)
+ continue;
+ if (!sd->button)
continue;
if ((sd->button->down[key>>3] & bit) != 0)
return DONT_PROCESS;
@@ -933,35 +887,76 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
b->motionMask = 0;
if (b->map[key] <= 5)
b->state &= ~((Button1Mask >> 1) << b->map[key]);
- SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
- } else if (xE->u.u.type == ProximityIn)
+
+ /* Add state and motionMask to the filter for this event */
+ mask = DevicePointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, DeviceMotionNotify);
+ mask = PointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, MotionNotify);
+ } else if (event->type == ET_ProximityIn)
device->valuator->mode &= ~OutOfProximity;
- else if (xE->u.u.type == ProximityOut)
+ else if (event->type == ET_ProximityOut)
device->valuator->mode |= OutOfProximity;
return DEFAULT;
}
+static void
+ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
+{
+ GrabPtr grab = device->deviceGrab.grab;
+
+ if (grab)
+ DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE);
+ else { /* deliver to all root windows */
+ xEvent *xi;
+ int i;
+
+ i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
+ if (i != Success)
+ {
+ ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n",
+ device->name, i);
+ return;
+ }
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ DeliverEventsToWindow(device, WindowTable[i], xi, 1,
+ GetEventFilter(device, xi), NULL);
+ xfree(xi);
+ }
+}
+
/**
* Main device event processing function.
* Called from when processing the events from the event queue.
*
*/
void
-ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
+ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
{
- int i;
- CARD16 modifiers;
- GrabPtr grab = device->deviceGrab.grab;
+ GrabPtr grab;
Bool deactivateDeviceGrab = FALSE;
int key = 0, rootX, rootY;
ButtonClassPtr b;
KeyClassPtr k;
ValuatorClassPtr v;
- deviceValuator *xV = (deviceValuator *) xE;
int ret = 0;
- int state;
+ int state, i;
DeviceIntPtr mouse = NULL, kbd = NULL;
+ DeviceEvent *event = (DeviceEvent*)ev;
+
+ CHECKEVENT(ev);
+
+ if (ev->any.type == ET_RawKeyPress ||
+ ev->any.type == ET_RawKeyRelease ||
+ ev->any.type == ET_RawButtonPress ||
+ ev->any.type == ET_RawButtonRelease ||
+ ev->any.type == ET_RawMotion)
+ {
+ ProcessRawEvent((RawDeviceEvent*)ev, device);
+ return;
+ }
if (IsPointerDevice(device))
{
@@ -978,10 +973,34 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
}
/* State needs to be assembled BEFORE the device is updated. */
- state = (kbd) ? kbd->key->state : 0;
- state |= (mouse) ? (mouse->button->state) : 0;
+ state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
+ state |= (mouse && mouse->button) ? (mouse->button->state) : 0;
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(event->buttons, i);
- ret = UpdateDeviceState(device, xE, count);
+ if (kbd && kbd->key)
+ {
+ XkbStatePtr state;
+ /* we need the state before the event happens */
+ if (event->type == ET_KeyPress || event->type == ET_KeyRelease)
+ state = &kbd->key->xkbInfo->prev_state;
+ else
+ state = &kbd->key->xkbInfo->state;
+
+ event->mods.base = state->base_mods;
+ event->mods.latched = state->latched_mods;
+ event->mods.locked = state->locked_mods;
+ event->mods.effective = state->mods;
+
+ event->group.base = state->base_group;
+ event->group.latched = state->latched_group;
+ event->group.locked = state->locked_group;
+ event->group.effective = state->group;
+ }
+
+ ret = UpdateDeviceState(device, event);
if (ret == DONT_PROCESS)
return;
@@ -989,19 +1008,31 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
b = device->button;
k = device->key;
- if (device->isMaster)
- CheckMotion(xE, device);
-
- if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
- GetSpritePosition(device, &rootX, &rootY);
- xE->u.keyButtonPointer.rootX = rootX;
- xE->u.keyButtonPointer.rootY = rootY;
- NoticeEventTime(xE);
+ if (IsMaster(device) || !device->u.master)
+ CheckMotion(event, device);
- xE->u.keyButtonPointer.state = state;
-
- key = xE->u.u.detail;
+ switch (event->type)
+ {
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ GetSpritePosition(device, &rootX, &rootY);
+ event->root_x = rootX;
+ event->root_y = rootY;
+ NoticeEventTime((InternalEvent*)event);
+ event->corestate = state;
+ key = event->detail.key;
+ break;
+ default:
+ break;
}
+
+#if 0
+ /* FIXME: I'm broken. Please fix me. Thanks */
if (DeviceEventCallback) {
DeviceEventInfoRec eventinfo;
@@ -1009,84 +1040,70 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
}
+#endif
+ grab = device->deviceGrab.grab;
- /* Valuator event handling */
- /* Don't care about valuators for the VCP, it never sends XI events */
-
- for (i = 1; !device->isMaster && i < count; i++) {
- if ((++xV)->type == DeviceValuator) {
- int first = xV->first_valuator;
- if (xV->num_valuators
- && (!v
- || (xV->num_valuators
- && (first + xV->num_valuators > v->numAxes))))
- FatalError("Bad valuators reported for device %s\n",
- device->name);
- xV->device_state = 0;
- if (k)
- xV->device_state |= k->state;
- if (b)
- xV->device_state |= b->state;
- }
+ switch(event->type)
+ {
+ case ET_KeyPress:
+ if (!grab && CheckDeviceGrabs(device, event, 0)) {
+ device->deviceGrab.activatingKey = key;
+ return;
+ }
+ break;
+ case ET_KeyRelease:
+ if (grab && device->deviceGrab.fromPassiveGrab &&
+ (key == device->deviceGrab.activatingKey) &&
+ (device->deviceGrab.grab->type == KeyPress ||
+ device->deviceGrab.grab->type == DeviceKeyPress ||
+ device->deviceGrab.grab->type == XI_KeyPress))
+ deactivateDeviceGrab = TRUE;
+ break;
+ case ET_ButtonPress:
+ event->detail.button = b->map[key];
+ if (!event->detail.button) { /* there's no button 0 */
+ event->detail.button = key;
+ return;
+ }
+ if (!grab && CheckDeviceGrabs(device, event, 0))
+ {
+ /* if a passive grab was activated, the event has been sent
+ * already */
+ return;
+ }
+ break;
+ case ET_ButtonRelease:
+ event->detail.button = b->map[key];
+ if (!event->detail.button) { /* there's no button 0 */
+ event->detail.button = key;
+ return;
+ }
+ if (grab && !b->buttonsDown &&
+ device->deviceGrab.fromPassiveGrab &&
+ (device->deviceGrab.grab->type == ButtonPress ||
+ device->deviceGrab.grab->type == DeviceButtonPress ||
+ device->deviceGrab.grab->type == XI_ButtonPress))
+ deactivateDeviceGrab = TRUE;
+ default:
+ break;
}
- if (xE->u.u.type == DeviceKeyPress) {
- if (ret == IS_REPEAT) { /* allow ddx to generate multiple downs */
- modifiers = k->modifierMap[key];
- if (!modifiers) {
- xE->u.u.type = DeviceKeyRelease;
- ProcessOtherEvent(xE, device, count);
- xE->u.u.type = DeviceKeyPress;
- /* release can have side effects, don't fall through */
- ProcessOtherEvent(xE, device, count);
- }
- return;
- }
- if (!grab && CheckDeviceGrabs(device, xE, 0, count)) {
- device->deviceGrab.activatingKey = key;
- return;
- }
- } else if (xE->u.u.type == DeviceKeyRelease) {
- if (device->deviceGrab.fromPassiveGrab &&
- (key == device->deviceGrab.activatingKey))
- deactivateDeviceGrab = TRUE;
- } else if (xE->u.u.type == DeviceButtonPress) {
- xE->u.u.detail = b->map[key];
- if (xE->u.u.detail == 0) {
- xE->u.u.detail = key;
- return;
- }
- if (!grab && CheckDeviceGrabs(device, xE, 0, count))
- {
- /* if a passive grab was activated, the event has been sent
- * already */
- return;
- }
-
- } else if (xE->u.u.type == DeviceButtonRelease) {
- xE->u.u.detail = b->map[key];
- if (xE->u.u.detail == 0) {
- xE->u.u.detail = key;
- return;
- }
- if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab)
- deactivateDeviceGrab = TRUE;
- }
if (grab)
- DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count);
- else if (device->focus && !IsPointerEvent(xE))
- DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count);
+ DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab);
+ else if (device->focus && !IsPointerEvent((InternalEvent*)ev))
+ DeliverFocusedEvent(device, (InternalEvent*)event,
+ GetSpriteWindow(device));
else
- DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow,
- device, count);
+ DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event,
+ NullGrab, NullWindow, device);
if (deactivateDeviceGrab == TRUE)
(*device->deviceGrab.DeactivateGrab) (device);
- xE->u.u.detail = key;
+ event->detail.key = key;
}
-_X_EXPORT int
+int
InitProximityClassDeviceStruct(DeviceIntPtr dev)
{
ProximityClassPtr proxc;
@@ -1094,6 +1111,7 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec));
if (!proxc)
return FALSE;
+ proxc->sourceid = dev->id;
dev->proximity = proxc;
return TRUE;
}
@@ -1107,14 +1125,16 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
*
* @see InitValuatorClassDeviceStruct
*/
-_X_EXPORT void
-InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval,
+void
+InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
int resolution, int min_res, int max_res)
{
AxisInfoPtr ax;
if (!dev || !dev->valuator || minval > maxval)
return;
+ if (axnum >= dev->valuator->numAxes)
+ return;
ax = dev->valuator->axes + axnum;
@@ -1123,6 +1143,7 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval,
ax->resolution = resolution;
ax->min_resolution = min_res;
ax->max_resolution = max_res;
+ ax->label = label;
}
static void
@@ -1143,7 +1164,8 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
memcpy((char*)ev->buttons, (char*)b->down, 4);
} else if (k) {
ev->classes_reported |= (1 << KeyClass);
- ev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
+ ev->num_keys = k->xkbInfo->desc->max_key_code -
+ k->xkbInfo->desc->min_key_code;
memmove((char *)&ev->keys[0], (char *)k->down, 4);
}
if (v) {
@@ -1191,21 +1213,65 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
WindowPtr pWin)
{
deviceFocus event;
+ xXIFocusInEvent *xi2event;
+ DeviceIntPtr mouse;
+ int btlen, len, i;
+
+ mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev;
+
+ /* XI 2 event */
+ btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
+ btlen = bytes_to_int32(btlen);
+ len = sizeof(xXIFocusInEvent) + btlen * 4;
+
+ xi2event = xcalloc(1, len);
+ xi2event->type = GenericEvent;
+ xi2event->extension = IReqCode;
+ xi2event->evtype = type;
+ xi2event->length = bytes_to_int32(len - sizeof(xEvent));
+ xi2event->buttons_len = btlen;
+ xi2event->detail = detail;
+ xi2event->time = currentTime.milliseconds;
+ xi2event->deviceid = dev->id;
+ xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */
+ xi2event->mode = mode;
+ xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0);
+ xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0);
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(&xi2event[1], i);
+
+ if (dev->key)
+ {
+ xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods;
+ xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods;
+ xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods;
+ xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods;
+
+ xi2event->group.base_group = dev->key->xkbInfo->state.base_group;
+ xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group;
+ xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group;
+ xi2event->group.effective_group = dev->key->xkbInfo->state.group;
+ }
- if (type == FocusIn)
- type = DeviceFocusIn;
- else
- type = DeviceFocusOut;
+ FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE);
+
+ DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1,
+ GetEventFilter(dev, (xEvent*)xi2event), NullGrab);
+ xfree(xi2event);
+
+ /* XI 1.x event */
event.deviceid = dev->id;
event.mode = mode;
- event.type = type;
+ event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut;
event.detail = detail;
event.window = pWin->drawable.id;
event.time = currentTime.milliseconds;
- (void)DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
- DeviceFocusChangeMask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
+ DeviceFocusChangeMask, NullGrab);
if ((type == DeviceFocusIn) &&
(wOtherInputMasks(pWin)) &&
@@ -1227,7 +1293,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
evcount++;
}
if ((k = dev->key) != NULL) {
- nkeys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
+ nkeys = k->xkbInfo->desc->max_key_code -
+ k->xkbInfo->desc->min_key_code;
if (nkeys > 32)
evcount++;
if (nbuttons > 0) {
@@ -1300,147 +1367,203 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
}
}
- (void)DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
- DeviceStateNotifyMask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
+ DeviceStateNotifyMask, NullGrab);
xfree(sev);
}
}
int
-GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
- BYTE other_devices_mode, CARD16 modifiers,
- DeviceIntPtr modifier_device, CARD8 button, Window grabWindow,
- BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask)
+CheckGrabValues(ClientPtr client, GrabParameters* param)
{
- WindowPtr pWin, confineTo;
- CursorPtr cursor;
- GrabPtr grab;
- Mask access_mode = DixGrabAccess;
- int rc;
+ if (param->grabtype != GRABTYPE_CORE &&
+ param->grabtype != GRABTYPE_XI &&
+ param->grabtype != GRABTYPE_XI2)
+ {
+ ErrorF("[Xi] grabtype is invalid. This is a bug.\n");
+ return BadImplementation;
+ }
- if ((this_device_mode != GrabModeSync) &&
- (this_device_mode != GrabModeAsync)) {
- client->errorValue = this_device_mode;
+ if ((param->this_device_mode != GrabModeSync) &&
+ (param->this_device_mode != GrabModeAsync)) {
+ client->errorValue = param->this_device_mode;
return BadValue;
}
- if ((other_devices_mode != GrabModeSync) &&
- (other_devices_mode != GrabModeAsync)) {
- client->errorValue = other_devices_mode;
+ if ((param->other_devices_mode != GrabModeSync) &&
+ (param->other_devices_mode != GrabModeAsync)) {
+ client->errorValue = param->other_devices_mode;
return BadValue;
}
- if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) {
- client->errorValue = modifiers;
+
+ if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) &&
+ (param->modifiers & ~AllModifiersMask)) {
+ client->errorValue = param->modifiers;
return BadValue;
}
- if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) {
- client->errorValue = ownerEvents;
+
+ if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) {
+ client->errorValue = param->ownerEvents;
return BadValue;
}
- rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+ return Success;
+}
+
+int
+GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+ int button, GrabParameters *param, GrabType grabtype,
+ GrabMask *mask)
+{
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor;
+ GrabPtr grab;
+ int rc, type = -1;
+ Mask access_mode = DixGrabAccess;
+
+ rc = CheckGrabValues(client, param);
if (rc != Success)
return rc;
- if (rconfineTo == None)
+ if (param->confineTo == None)
confineTo = NullWindow;
else {
- rc = dixLookupWindow(&confineTo, rconfineTo, client, DixSetAttrAccess);
+ rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess);
if (rc != Success)
return rc;
}
- if (rcursor == None)
+ if (param->cursor == None)
cursor = NullCursor;
else {
- rc = dixLookupResourceByType((pointer *)&cursor, rcursor, RT_CURSOR,
- client, DixUseAccess);
+ rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+ RT_CURSOR, client, DixUseAccess);
if (rc != Success)
{
- client->errorValue = rcursor;
+ client->errorValue = param->cursor;
return (rc == BadValue) ? BadCursor : rc;
}
access_mode |= DixForceAccess;
}
- if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync)
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
access_mode |= DixFreezeAccess;
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
if (rc != Success)
return rc;
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
- grab = CreateGrab(client->index, dev, pWin, eventMask,
- (Bool) ownerEvents, (Bool) this_device_mode,
- (Bool) other_devices_mode, modifier_device, modifiers,
- DeviceButtonPress, button, confineTo, cursor);
+ if (grabtype == GRABTYPE_XI)
+ type = DeviceButtonPress;
+ else if (grabtype == GRABTYPE_XI2)
+ type = XI_ButtonPress;
+
+ grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+ mask, param, type, button, confineTo, cursor);
if (!grab)
return BadAlloc;
return AddPassiveGrabToList(client, grab);
}
+/**
+ * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If
+ * grabtype is GRABTYPE_XI2, the key is a keysym.
+ */
int
-GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
- BYTE other_devices_mode, CARD16 modifiers,
- DeviceIntPtr modifier_device, CARD8 key, Window grabWindow,
- BOOL ownerEvents, Mask mask)
+GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+ int key, GrabParameters *param, GrabType grabtype, GrabMask *mask)
{
WindowPtr pWin;
GrabPtr grab;
KeyClassPtr k = dev->key;
Mask access_mode = DixGrabAccess;
- int rc;
+ int rc, type = -1;
+ rc = CheckGrabValues(client, param);
+ if (rc != Success)
+ return rc;
if (k == NULL)
return BadMatch;
- if ((other_devices_mode != GrabModeSync) &&
- (other_devices_mode != GrabModeAsync)) {
- client->errorValue = other_devices_mode;
- return BadValue;
- }
- if ((this_device_mode != GrabModeSync) &&
- (this_device_mode != GrabModeAsync)) {
- client->errorValue = this_device_mode;
- return BadValue;
- }
- if (((key > k->curKeySyms.maxKeyCode) || (key < k->curKeySyms.minKeyCode))
- && (key != AnyKey)) {
- client->errorValue = key;
- return BadValue;
- }
- if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) {
- client->errorValue = modifiers;
- return BadValue;
- }
- if ((ownerEvents != xTrue) && (ownerEvents != xFalse)) {
- client->errorValue = ownerEvents;
- return BadValue;
- }
- rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+ if (grabtype == GRABTYPE_XI)
+ {
+ if ((key > k->xkbInfo->desc->max_key_code ||
+ key < k->xkbInfo->desc->min_key_code)
+ && (key != AnyKey)) {
+ client->errorValue = key;
+ return BadValue;
+ }
+ type = DeviceKeyPress;
+ } else if (grabtype == GRABTYPE_XI2)
+ type = XI_KeyPress;
+
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
if (rc != Success)
return rc;
- if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync)
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
access_mode |= DixFreezeAccess;
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
if (rc != Success)
return rc;
- grab = CreateGrab(client->index, dev, pWin,
- mask, ownerEvents, this_device_mode, other_devices_mode,
- modifier_device, modifiers, DeviceKeyPress, key,
- NullWindow, NullCursor);
+ grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+ mask, param, type, key, NULL, NULL);
if (!grab)
return BadAlloc;
return AddPassiveGrabToList(client, grab);
}
+/* Enter/FocusIn grab */
+int
+GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
+ GrabParameters *param, GrabMask *mask)
+{
+ WindowPtr pWin;
+ CursorPtr cursor;
+ GrabPtr grab;
+ Mask access_mode = DixGrabAccess;
+ int rc;
+
+ rc = CheckGrabValues(client, param);
+ if (rc != Success)
+ return rc;
+
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (param->cursor == None)
+ cursor = NullCursor;
+ else {
+ rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+ RT_CURSOR, client, DixUseAccess);
+ if (rc != Success)
+ {
+ client->errorValue = param->cursor;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+ access_mode |= DixForceAccess;
+ }
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
+ access_mode |= DixFreezeAccess;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+ if (rc != Success)
+ return rc;
+
+ grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2,
+ mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn,
+ 0, NULL, cursor);
+
+ if (!grab)
+ return BadAlloc;
+
+ return AddPassiveGrabToList(client, grab);
+}
+
int
SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client,
- Mask mask, Mask exclusivemasks, Mask validmasks)
+ Mask mask, Mask exclusivemasks)
{
int mskidx = dev->id;
int i, ret;
Mask check;
InputClientsPtr others;
- if (mask & ~validmasks) {
- client->errorValue = mask;
- return BadValue;
- }
check = (mask & exclusivemasks);
if (wOtherInputMasks(pWin)) {
if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different
@@ -1528,15 +1651,20 @@ RecalculateDeviceDeliverableEvents(WindowPtr pWin)
InputClientsPtr others;
struct _OtherInputMasks *inputMasks; /* default: NULL */
WindowPtr pChild, tmp;
- int i;
+ int i, j;
pChild = pWin;
while (1) {
if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
+ for (i = 0; i < EMASKSIZE; i++)
+ memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i]));
for (others = inputMasks->inputClients; others;
others = others->next) {
for (i = 0; i < EMASKSIZE; i++)
inputMasks->inputEvents[i] |= others->mask[i];
+ for (i = 0; i < EMASKSIZE; i++)
+ for (j = 0; j < XI2MASKSIZE; j++)
+ inputMasks->xi2mask[i][j] |= others->xi2mask[i][j];
}
for (i = 0; i < EMASKSIZE; i++)
inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
@@ -1644,7 +1772,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
ev->u.u.type |= 0x80;
if (propagate) {
for (; pWin; pWin = pWin->parent) {
- if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id))
+ if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab))
return Success;
if (pWin == effectiveFocus)
return Success;
@@ -1654,7 +1782,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
break;
}
} else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count))
- (void)(DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id));
+ DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab);
return Success;
}
@@ -1682,111 +1810,6 @@ SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
}
int
-SetModifierMapping(ClientPtr client, DeviceIntPtr dev, int len, int rlen,
- int numKeyPerModifier, KeyCode * inputMap, KeyClassPtr * k)
-{
- KeyCode *map = NULL;
- int inputMapLen;
- int i;
-
- *k = dev->key;
- if (*k == NULL)
- return BadMatch;
- if (len != ((numKeyPerModifier << 1) + rlen))
- return BadLength;
-
- inputMapLen = 8 * numKeyPerModifier;
-
- /*
- * Now enforce the restriction that "all of the non-zero keycodes must be
- * in the range specified by min-keycode and max-keycode in the
- * connection setup (else a Value error)"
- */
- i = inputMapLen;
- while (i--) {
- if (inputMap[i]
- && (inputMap[i] < (*k)->curKeySyms.minKeyCode
- || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) {
- client->errorValue = inputMap[i];
- return -1; /* BadValue collides with MappingFailed */
- }
- }
-
- /*
- * Now enforce the restriction that none of the old or new
- * modifier keys may be down while we change the mapping, and
- * that the DDX layer likes the choice.
- */
- if (!AllModifierKeysAreUp(dev, (*k)->modifierKeyMap,
- (int)(*k)->maxKeysPerModifier, inputMap,
- (int)numKeyPerModifier)
- || !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier,
- (*k)->modifierKeyMap,
- (int)(*k)->maxKeysPerModifier)) {
- return MappingBusy;
- } else {
- for (i = 0; i < inputMapLen; i++) {
- if (inputMap[i] && !LegalModifier(inputMap[i], dev)) {
- return MappingFailed;
- }
- }
- }
-
- /*
- * Now build the keyboard's modifier bitmap from the
- * list of keycodes.
- */
- if (inputMapLen) {
- map = (KeyCode *) xalloc(inputMapLen);
- if (!map)
- return BadAlloc;
- }
- if ((*k)->modifierKeyMap)
- xfree((*k)->modifierKeyMap);
- if (inputMapLen) {
- (*k)->modifierKeyMap = map;
- memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen);
- } else
- (*k)->modifierKeyMap = NULL;
-
- (*k)->maxKeysPerModifier = numKeyPerModifier;
- for (i = 0; i < MAP_LENGTH; i++)
- (*k)->modifierMap[i] = 0;
- for (i = 0; i < inputMapLen; i++)
- if (inputMap[i]) {
- (*k)->modifierMap[inputMap[i]]
- |= (1 << (i / (*k)->maxKeysPerModifier));
- }
-
- return (MappingSuccess);
-}
-
-void
-SendDeviceMappingNotify(ClientPtr client, CARD8 request,
- KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev)
-{
- xEvent event;
- deviceMappingNotify *ev = (deviceMappingNotify *) & event;
-
- ev->type = DeviceMappingNotify;
- ev->request = request;
- ev->deviceid = dev->id;
- ev->time = currentTime.milliseconds;
- if (request == MappingKeyboard) {
- ev->firstKeyCode = firstKeyCode;
- ev->count = count;
- }
-
-#ifdef XKB
- if (!noXkbExtension && (request == MappingKeyboard ||
- request == MappingModifier))
- XkbApplyMappingChange(dev, request, firstKeyCode, count, client);
-#endif
-
- SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) ev, 1);
-}
-
-int
ChangeKeyMapping(ClientPtr client,
DeviceIntPtr dev,
unsigned len,
@@ -1803,8 +1826,8 @@ ChangeKeyMapping(ClientPtr client,
if (len != (keyCodes * keySymsPerKeyCode))
return BadLength;
- if ((firstKeyCode < k->curKeySyms.minKeyCode) ||
- (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode)) {
+ if ((firstKeyCode < k->xkbInfo->desc->min_key_code) ||
+ (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) {
client->errorValue = firstKeyCode;
return BadValue;
}
@@ -1816,9 +1839,10 @@ ChangeKeyMapping(ClientPtr client,
keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
keysyms.mapWidth = keySymsPerKeyCode;
keysyms.map = map;
- if (!SetKeySymsMap(&k->curKeySyms, &keysyms))
- return BadAlloc;
- SendDeviceMappingNotify(client, MappingKeyboard, firstKeyCode, keyCodes, dev);
+
+ XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL,
+ serverClient);
+
return client->noClientException;
}
@@ -1847,7 +1871,8 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
switch (dev->focus->revert) {
case RevertToNone:
- DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, NoneWin))
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
dev->focus->win = NoneWin;
dev->focus->traceGood = 0;
break;
@@ -1858,26 +1883,34 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
dev->focus->traceGood--;
}
while (!parent->realized);
- DoFocusEvents(dev, pWin, parent, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, parent))
+ DoFocusEvents(dev, pWin, parent, focusEventMode);
dev->focus->win = parent;
dev->focus->revert = RevertToNone;
break;
case RevertToPointerRoot:
- DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, PointerRootWin))
+ DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
dev->focus->win = PointerRootWin;
dev->focus->traceGood = 0;
break;
case RevertToFollowKeyboard:
- if (inputInfo.keyboard->focus->win) {
- DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win,
- focusEventMode);
+ {
+ DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD);
+ if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
+ kbd = inputInfo.keyboard;
+ if (kbd->focus->win) {
+ if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win))
+ DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
dev->focus->win = FollowKeyboardWin;
dev->focus->traceGood = 0;
} else {
- DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, NoneWin))
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
dev->focus->win = NoneWin;
dev->focus->traceGood = 0;
}
+ }
break;
}
}
@@ -1896,8 +1929,6 @@ DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources)
struct _OtherInputMasks *inputMasks;
for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev == inputInfo.pointer || dev == inputInfo.keyboard)
- continue;
DeleteDeviceFromAnyExtEvents(pWin, dev);
}
@@ -1944,7 +1975,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
DeviceIntPtr dev;
dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient,
- DixReadAccess);
+ DixGrabAccess);
if (!dev)
return;
@@ -1964,7 +1995,6 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
tempGrab.pointerMode = GrabModeAsync;
tempGrab.confineTo = NullWindow;
tempGrab.cursor = NullCursor;
- tempGrab.genericMasks = NULL;
tempGrab.next = NULL;
(*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE);
}
@@ -2063,7 +2093,7 @@ FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask,
while (p1) {
p2 = p1->firstChild;
- (void)DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab);
FindInterestedChildren(dev, p2, mask, ev, count);
p1 = p1->nextSib;
}
@@ -2085,9 +2115,56 @@ SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count)
pWin = WindowTable[i];
if (!pWin)
continue;
- (void)DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab);
p1 = pWin->firstChild;
FindInterestedChildren(dev, p1, mask, ev, count);
}
}
+/**
+ * Set the XI2 mask for the given client on the given window.
+ * @param dev The device to set the mask for.
+ * @param win The window to set the mask on.
+ * @param client The client setting the mask.
+ * @param len Number of bytes in mask.
+ * @param mask Event mask in the form of (1 << eventtype)
+ */
+int
+XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
+ unsigned int len, unsigned char* mask)
+{
+ OtherInputMasks *masks;
+ InputClientsPtr others = NULL;
+
+ masks = wOtherInputMasks(win);
+ if (masks)
+ {
+ for (others = wOtherInputMasks(win)->inputClients; others;
+ others = others->next) {
+ if (SameClient(others, client)) {
+ memset(others->xi2mask[dev->id], 0,
+ sizeof(others->xi2mask[dev->id]));
+ break;
+ }
+ }
+ }
+
+ len = min(len, sizeof(others->xi2mask[dev->id]));
+
+ if (len && !others)
+ {
+ if (AddExtensionClient(win, client, 0, 0) != Success)
+ return BadAlloc;
+ others= wOtherInputMasks(win)->inputClients;
+ }
+
+ if (others)
+ memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id]));
+
+ if (len)
+ memcpy(others->xi2mask[dev->id], mask, len);
+
+ RecalculateDeviceDeliverableEvents(win);
+
+ return Success;
+}
diff --git a/xorg-server/Xi/exglobals.h b/xorg-server/Xi/exglobals.h
index 42a695356..2d2d25c0b 100644
--- a/xorg-server/Xi/exglobals.h
+++ b/xorg-server/Xi/exglobals.h
@@ -43,18 +43,19 @@ extern int BadMode;
extern int DeviceBusy;
extern int BadClass;
-extern Mask DevicePointerMotionMask;
-extern Mask DevicePointerMotionHintMask;
-extern Mask DeviceFocusChangeMask;
-extern Mask DeviceStateNotifyMask;
-extern Mask DeviceMappingNotifyMask;
-extern Mask DeviceOwnerGrabButtonMask;
-extern Mask DeviceButtonGrabMask;
-extern Mask DeviceButtonMotionMask;
-extern Mask DevicePresenceNotifyMask;
-extern Mask DevicePropertyNotifyMask;
-extern Mask DeviceEnterWindowMask;
-extern Mask DeviceLeaveWindowMask;
+/* Note: only the ones needed in files other than extinit.c are declared */
+extern const Mask DevicePointerMotionMask;
+extern const Mask DevicePointerMotionHintMask;
+extern const Mask DeviceFocusChangeMask;
+extern const Mask DeviceStateNotifyMask;
+extern const Mask DeviceMappingNotifyMask;
+extern const Mask DeviceOwnerGrabButtonMask;
+extern const Mask DeviceButtonGrabMask;
+extern const Mask DeviceButtonMotionMask;
+extern const Mask DevicePresenceNotifyMask;
+extern const Mask DevicePropertyNotifyMask;
+extern const Mask XIAllMasks;
+
extern Mask PropagateMask[];
extern int DeviceValuator;
@@ -74,8 +75,6 @@ extern int DeviceMappingNotify;
extern int ChangeDeviceNotify;
extern int DevicePresenceNotify;
extern int DevicePropertyNotify;
-extern int DeviceEnterNotify;
-extern int DeviceLeaveNotify;
extern int RT_INPUTCLIENT;
diff --git a/xorg-server/Xi/extinit.c b/xorg-server/Xi/extinit.c
index 14eb3cbe1..84b999c0c 100644
--- a/xorg-server/Xi/extinit.c
+++ b/xorg-server/Xi/extinit.c
@@ -52,8 +52,6 @@ SOFTWARE.
#define NUMTYPES 15
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -63,6 +61,7 @@ SOFTWARE.
#include "extnsionst.h" /* extension entry */
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
#include <X11/extensions/geproto.h>
#include "geext.h" /* extension interfaces for ge */
@@ -112,12 +111,53 @@ SOFTWARE.
#include "ungrdev.h"
#include "ungrdevb.h"
#include "ungrdevk.h"
+#include "xiallowev.h"
+#include "xiselectev.h"
+#include "xigrabdev.h"
+#include "xipassivegrab.h"
+#include "xisetdevfocus.h"
#include "xiproperty.h"
+#include "xichangecursor.h"
+#include "xichangehierarchy.h"
+#include "xigetclientpointer.h"
+#include "xiquerydevice.h"
+#include "xiquerypointer.h"
+#include "xiqueryversion.h"
+#include "xisetclientpointer.h"
+#include "xiwarppointer.h"
+
+
+/* Masks for XI events have to be aligned with core event (partially anyway).
+ * If DeviceButtonMotionMask is != ButtonMotionMask, event delivery
+ * breaks down. The device needs the dev->button->motionMask. If DBMM is
+ * the same as BMM, we can ensure that both core and device events can be
+ * delivered, without the need for extra structures in the DeviceIntRec. */
+const Mask DeviceKeyPressMask = KeyPressMask;
+const Mask DeviceKeyReleaseMask = KeyReleaseMask;
+const Mask DeviceButtonPressMask = ButtonPressMask;
+const Mask DeviceButtonReleaseMask = ButtonReleaseMask;
+const Mask DeviceProximityMask = (1L << 4);
+const Mask DeviceStateNotifyMask = (1L << 5);
+const Mask DevicePointerMotionMask = PointerMotionMask;
+const Mask DevicePointerMotionHintMask = PointerMotionHintMask;
+const Mask DeviceButton1MotionMask = Button1MotionMask;
+const Mask DeviceButton2MotionMask = Button2MotionMask;
+const Mask DeviceButton3MotionMask = Button3MotionMask;
+const Mask DeviceButton4MotionMask = Button4MotionMask;
+const Mask DeviceButton5MotionMask = Button5MotionMask;
+const Mask DeviceButtonMotionMask = ButtonMotionMask;
+const Mask DeviceFocusChangeMask = (1L << 14);
+const Mask DeviceMappingNotifyMask = (1L << 15);
+const Mask ChangeDeviceNotifyMask = (1L << 16);
+const Mask DeviceButtonGrabMask = (1L << 17);
+const Mask DeviceOwnerGrabButtonMask = (1L << 17);
+const Mask DevicePresenceNotifyMask = (1L << 18);
+const Mask DeviceEnterWindowMask = (1L << 18);
+const Mask DeviceLeaveWindowMask = (1L << 19);
+const Mask DevicePropertyNotifyMask = (1L << 20);
+const Mask XIAllMasks = (1L << 21) - 1;
-
-static Mask lastExtEventMask = 1;
int ExtEventIndex;
-Mask ExtValidMasks[EMASKSIZE];
Mask ExtExclusiveMasks[EMASKSIZE];
static struct dev_type
@@ -148,6 +188,9 @@ static struct dev_type
CARD8 event_base[numInputClasses];
XExtEventInfo EventInfo[32];
+static DeviceIntRec xi_all_devices;
+static DeviceIntRec xi_all_master_devices;
+
/**
* Dispatch vector. Functions defined in here will be called when the matching
* request arrives.
@@ -193,7 +236,29 @@ static int (*ProcIVector[])(ClientPtr) = {
ProcXListDeviceProperties, /* 36 */
ProcXChangeDeviceProperty, /* 37 */
ProcXDeleteDeviceProperty, /* 38 */
- ProcXGetDeviceProperty /* 39 */
+ ProcXGetDeviceProperty, /* 39 */
+ /* XI 2 */
+ ProcXIQueryPointer, /* 40 */
+ ProcXIWarpPointer, /* 41 */
+ ProcXIChangeCursor, /* 42 */
+ ProcXIChangeHierarchy, /* 43 */
+ ProcXISetClientPointer, /* 44 */
+ ProcXIGetClientPointer, /* 45 */
+ ProcXISelectEvents, /* 46 */
+ ProcXIQueryVersion, /* 47 */
+ ProcXIQueryDevice, /* 48 */
+ ProcXISetFocus, /* 49 */
+ ProcXIGetFocus, /* 50 */
+ ProcXIGrabDevice, /* 51 */
+ ProcXIUngrabDevice, /* 52 */
+ ProcXIAllowEvents, /* 53 */
+ ProcXIPassiveGrabDevice, /* 54 */
+ ProcXIPassiveUngrabDevice, /* 55 */
+ ProcXIListProperties, /* 56 */
+ ProcXIChangeProperty, /* 57 */
+ ProcXIDeleteProperty, /* 58 */
+ ProcXIGetProperty, /* 59 */
+ ProcXIGetSelectedEvents /* 60 */
};
/* For swapped clients */
@@ -237,7 +302,28 @@ static int (*SProcIVector[])(ClientPtr) = {
SProcXListDeviceProperties, /* 36 */
SProcXChangeDeviceProperty, /* 37 */
SProcXDeleteDeviceProperty, /* 38 */
- SProcXGetDeviceProperty /* 39 */
+ SProcXGetDeviceProperty, /* 39 */
+ SProcXIQueryPointer, /* 40 */
+ SProcXIWarpPointer, /* 41 */
+ SProcXIChangeCursor, /* 42 */
+ SProcXIChangeHierarchy, /* 43 */
+ SProcXISetClientPointer, /* 44 */
+ SProcXIGetClientPointer, /* 45 */
+ SProcXISelectEvents, /* 46 */
+ SProcXIQueryVersion, /* 47 */
+ SProcXIQueryDevice, /* 48 */
+ SProcXISetFocus, /* 49 */
+ SProcXIGetFocus, /* 50 */
+ SProcXIGrabDevice, /* 51 */
+ SProcXIUngrabDevice, /* 52 */
+ SProcXIAllowEvents, /* 53 */
+ SProcXIPassiveGrabDevice, /* 54 */
+ SProcXIPassiveUngrabDevice, /* 55 */
+ SProcXIListProperties, /* 56 */
+ SProcXIChangeProperty, /* 57 */
+ SProcXIDeleteProperty, /* 58 */
+ SProcXIGetProperty, /* 59 */
+ SProcXIGetSelectedEvents /* 60 */
};
/*****************************************************************
@@ -254,18 +340,6 @@ int BadMode = 2;
int DeviceBusy = 3;
int BadClass = 4;
-Mask DevicePointerMotionMask;
-Mask DevicePointerMotionHintMask;
-Mask DeviceFocusChangeMask;
-Mask DeviceStateNotifyMask;
-static Mask ChangeDeviceNotifyMask;
-Mask DeviceMappingNotifyMask;
-Mask DeviceOwnerGrabButtonMask;
-Mask DeviceButtonGrabMask;
-Mask DeviceButtonMotionMask;
-Mask DevicePresenceNotifyMask;
-Mask DevicePropertyNotifyMask;
-
int DeviceValuator;
int DeviceKeyPress;
int DeviceKeyRelease;
@@ -292,7 +366,7 @@ int RT_INPUTCLIENT;
*
*/
-extern XExtensionVersion AllExtensionVersions[];
+extern XExtensionVersion XIVersion;
Mask PropagateMask[MAXDEVICES];
@@ -307,8 +381,8 @@ static int XIClientPrivateKeyIndex;
DevPrivateKey XIClientPrivateKey = &XIClientPrivateKeyIndex;
static XExtensionVersion thisversion = { XI_Present,
- XI_Add_DeviceProperties_Major,
- XI_Add_DeviceProperties_Minor
+ XI_2_Major,
+ XI_2_Minor
};
@@ -343,7 +417,7 @@ static int
ProcIDispatch(ClientPtr client)
{
REQUEST(xReq);
- if (stuff->data > IREQUESTS || !ProcIVector[stuff->data])
+ if (stuff->data > (IREQUESTS + XI2REQUESTS) || !ProcIVector[stuff->data])
return BadRequest;
return (*ProcIVector[stuff->data])(client);
@@ -433,6 +507,26 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
SRepXListDeviceProperties(client, len, (xListDevicePropertiesReply*)rep);
else if (rep->RepType == X_GetDeviceProperty)
SRepXGetDeviceProperty(client, len, (xGetDevicePropertyReply *) rep);
+ else if (rep->RepType == X_XIQueryPointer)
+ SRepXIQueryPointer(client, len, (xXIQueryPointerReply *) rep);
+ else if (rep->RepType == X_XIGetClientPointer)
+ SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply*) rep);
+ else if (rep->RepType == X_XIQueryVersion)
+ SRepXIQueryVersion(client, len, (xXIQueryVersionReply*)rep);
+ else if (rep->RepType == X_XIQueryDevice)
+ SRepXIQueryDevice(client, len, (xXIQueryDeviceReply*)rep);
+ else if (rep->RepType == X_XIGrabDevice)
+ SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
+ else if (rep->RepType == X_XIGrabDevice)
+ SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep);
+ else if (rep->RepType == X_XIListProperties)
+ SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep);
+ else if (rep->RepType == X_XIGetProperty)
+ SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep);
+ else if (rep->RepType == X_XIGetSelectedEvents)
+ SRepXIGetSelectedEvents(client, len, (xXIGetSelectedEventsReply *) rep);
+ else if (rep->RepType == X_XIGetFocus)
+ SRepXIGetFocus(client, len, (xXIGetFocusReply *) rep);
else {
FatalError("XINPUT confused sending swapped reply");
}
@@ -549,42 +643,279 @@ SDevicePropertyNotifyEvent (devicePropertyNotify *from, devicePropertyNotify *to
swapl(&to->atom, n);
}
-/**************************************************************************
- *
- * Allow the specified event to have its propagation suppressed.
- * The default is to not allow suppression of propagation.
- *
- */
+static void
+SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber,n);
+ swapl(&to->length, n);
+ swaps(&to->evtype, n);
+ swaps(&to->deviceid, n);
+ swapl(&to->time, n);
+ swapl(&to->root, n);
+ swapl(&to->event, n);
+ swapl(&to->child, n);
+ swapl(&to->root_x, n);
+ swapl(&to->root_y, n);
+ swapl(&to->event_x, n);
+ swapl(&to->event_y, n);
+ swaps(&to->sourceid, n);
+ swaps(&to->buttons_len, n);
+ swapl(&to->mods.base_mods, n);
+ swapl(&to->mods.latched_mods, n);
+ swapl(&to->mods.locked_mods, n);
+}
static void
-AllowPropagateSuppress(Mask mask)
+SDeviceChangedEvent(xXIDeviceChangedEvent* from, xXIDeviceChangedEvent* to)
+{
+ char n;
+ int i, j;
+ xXIAnyInfo *any;
+
+ *to = *from;
+ memcpy(&to[1], &from[1], from->length * 4);
+
+ any = (xXIAnyInfo*)&to[1];
+ for (i = 0; i < to->num_classes; i++)
+ {
+ int length = any->length;
+
+ switch(any->type)
+ {
+ case KeyClass:
+ {
+ xXIKeyInfo *ki = (xXIKeyInfo*)any;
+ uint32_t *key = (uint32_t*)&ki[1];
+ for (j = 0; j < ki->num_keycodes; j++, key++)
+ swapl(key, n);
+ swaps(&ki->num_keycodes, n);
+ }
+ break;
+ case ButtonClass:
+ {
+ xXIButtonInfo *bi = (xXIButtonInfo*)any;
+ Atom *labels = (Atom*)((char*)bi + sizeof(xXIButtonInfo) +
+ pad_to_int32(bits_to_bytes(bi->num_buttons)));
+ for (j = 0; j < bi->num_buttons; j++)
+ swapl(&labels[j], n);
+ swaps(&bi->num_buttons, n);
+ }
+ break;
+ case ValuatorClass:
+ {
+ xXIValuatorInfo* ai = (xXIValuatorInfo*)any;
+ swapl(&ai->label, n);
+ swapl(&ai->min.integral, n);
+ swapl(&ai->min.frac, n);
+ swapl(&ai->max.integral, n);
+ swapl(&ai->max.frac, n);
+ swapl(&ai->resolution, n);
+ swaps(&ai->number, n);
+ }
+ break;
+ }
+
+ swaps(&any->type, n);
+ swaps(&any->length, n);
+ swaps(&any->sourceid, n);
+
+ any = (xXIAnyInfo*)((char*)any + length * 4);
+ }
+
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->length, n);
+ swaps(&to->evtype, n);
+ swaps(&to->deviceid, n);
+ swapl(&to->time, n);
+ swaps(&to->num_classes, n);
+ swaps(&to->sourceid, n);
+
+}
+
+static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to)
{
int i;
+ char n;
+ char *ptr;
+ char *vmask;
- for (i = 0; i < MAXDEVICES; i++)
- PropagateMask[i] |= mask;
+ memcpy(to, from, sizeof(xEvent) + from->length * 4);
+
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->length, n);
+ swaps(&to->evtype, n);
+ swaps(&to->deviceid, n);
+ swapl(&to->time, n);
+ swapl(&to->detail, n);
+ swapl(&to->root, n);
+ swapl(&to->event, n);
+ swapl(&to->child, n);
+ swapl(&to->root_x, n);
+ swapl(&to->root_y, n);
+ swapl(&to->event_x, n);
+ swapl(&to->event_y, n);
+ swaps(&to->buttons_len, n);
+ swaps(&to->valuators_len, n);
+ swaps(&to->sourceid, n);
+ swapl(&to->mods.base_mods, n);
+ swapl(&to->mods.latched_mods, n);
+ swapl(&to->mods.locked_mods, n);
+ swapl(&to->mods.effective_mods, n);
+
+ ptr = (char*)(&to[1]);
+ ptr += from->buttons_len * 4;
+ vmask = ptr; /* valuator mask */
+ ptr += from->valuators_len * 4;
+ for (i = 0; i < from->valuators_len * 32; i++)
+ {
+ if (BitIsOn(vmask, i))
+ {
+ swapl(((uint32_t*)ptr), n);
+ ptr += 4;
+ swapl(((uint32_t*)ptr), n);
+ ptr += 4;
+ }
+ }
+}
+
+static void SDeviceHierarchyEvent(xXIHierarchyEvent *from,
+ xXIHierarchyEvent *to)
+{
+ int i;
+ char n;
+ xXIHierarchyInfo *info;
+
+ *to = *from;
+ memcpy(&to[1], &from[1], from->length * 4);
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->length, n);
+ swaps(&to->evtype, n);
+ swaps(&to->deviceid, n);
+ swapl(&to->time, n);
+ swapl(&to->flags, n);
+ swaps(&to->num_info, n);
+
+ info = (xXIHierarchyInfo*)&to[1];
+ for (i = 0; i< from->num_info; i++)
+ {
+ swaps(&info->deviceid, n);
+ swaps(&info->attachment, n);
+ info++;
+ }
+}
+
+static void SXIPropertyEvent(xXIPropertyEvent *from, xXIPropertyEvent *to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->length, n);
+ swaps(&to->evtype, n);
+ swaps(&to->deviceid, n);
+ swapl(&to->property, n);
+}
+
+static void SRawEvent(xXIRawEvent *from, xXIRawEvent *to)
+{
+ char n;
+ int i;
+ FP3232 *values;
+ unsigned char *mask;
+
+ memcpy(to, from, sizeof(xEvent) + from->length * 4);
+
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->length, n);
+ swaps(&to->evtype, n);
+ swaps(&to->deviceid, n);
+ swapl(&to->time, n);
+ swapl(&to->detail, n);
+
+
+ mask = (unsigned char*)&to[1];
+ values = (FP3232*)(mask + from->valuators_len * 4);
+
+ for (i = 0; i < from->valuators_len * 4 * 8; i++)
+ {
+ if (BitIsOn(mask, i))
+ {
+ /* for each bit set there are two FP3232 values on the wire, in
+ * the order abcABC for data and data_raw. Here we swap as if
+ * they were in aAbBcC order because it's easier and really
+ * doesn't matter.
+ */
+ swapl(&values->integral, n);
+ swapl(&values->frac, n);
+ values++;
+ swapl(&values->integral, n);
+ swapl(&values->frac, n);
+ values++;
+ }
+ }
+
+ swaps(&to->valuators_len, n);
+}
+
+
+/** Event swapping function for XI2 events. */
+void
+XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
+{
+ switch(from->evtype)
+ {
+ case XI_Enter:
+ case XI_Leave:
+ SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to);
+ break;
+ case XI_DeviceChanged:
+ SDeviceChangedEvent((xXIDeviceChangedEvent*)from,
+ (xXIDeviceChangedEvent*)to);
+ break;
+ case XI_HierarchyChanged:
+ SDeviceHierarchyEvent((xXIHierarchyEvent*)from, (xXIHierarchyEvent*)to);
+ break;
+ case XI_PropertyEvent:
+ SXIPropertyEvent((xXIPropertyEvent*)from,
+ (xXIPropertyEvent*)to);
+ break;
+ case XI_Motion:
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
+ break;
+ case XI_RawMotion:
+ case XI_RawKeyPress:
+ case XI_RawKeyRelease:
+ case XI_RawButtonPress:
+ case XI_RawButtonRelease:
+ SRawEvent((xXIRawEvent*)from, (xXIRawEvent*)to);
+ break;
+ default:
+ ErrorF("[Xi] Unknown event type to swap. This is a bug.\n");
+ break;
+ }
}
/**************************************************************************
*
- * Return the next available extension event mask.
+ * Allow the specified event to have its propagation suppressed.
+ * The default is to not allow suppression of propagation.
*
*/
-static Mask
-GetNextExtEventMask(void)
+static void
+AllowPropagateSuppress(Mask mask)
{
int i;
- Mask mask = lastExtEventMask;
-
- if (lastExtEventMask == 0) {
- FatalError("GetNextExtEventMask: no more events are available.");
- }
- lastExtEventMask <<= 1;
for (i = 0; i < MAXDEVICES; i++)
- ExtValidMasks[i] |= mask;
- return mask;
+ PropagateMask[i] |= mask;
}
/**************************************************************************
@@ -654,8 +985,6 @@ SetMaskForExtEvent(Mask mask, int event)
static void
FixExtensionEvents(ExtensionEntry * extEntry)
{
- Mask mask;
-
DeviceValuator = extEntry->eventBase;
DeviceKeyPress = DeviceValuator + 1;
DeviceKeyRelease = DeviceKeyPress + 1;
@@ -687,81 +1016,50 @@ FixExtensionEvents(ExtensionEntry * extEntry)
DeviceBusy += extEntry->errorBase;
BadClass += extEntry->errorBase;
- mask = GetNextExtEventMask();
- SetMaskForExtEvent(mask, DeviceKeyPress);
- AllowPropagateSuppress(mask);
+ SetMaskForExtEvent(DeviceKeyPressMask, DeviceKeyPress);
+ AllowPropagateSuppress(DeviceKeyPressMask);
+ SetCriticalEvent(DeviceKeyPress);
- mask = GetNextExtEventMask();
- SetMaskForExtEvent(mask, DeviceKeyRelease);
- AllowPropagateSuppress(mask);
+ SetMaskForExtEvent(DeviceKeyReleaseMask, DeviceKeyRelease);
+ AllowPropagateSuppress(DeviceKeyReleaseMask);
+ SetCriticalEvent(DeviceKeyRelease);
- mask = GetNextExtEventMask();
- SetMaskForExtEvent(mask, DeviceButtonPress);
- AllowPropagateSuppress(mask);
+ SetMaskForExtEvent(DeviceButtonPressMask, DeviceButtonPress);
+ AllowPropagateSuppress(DeviceButtonPressMask);
+ SetCriticalEvent(DeviceButtonPress);
- mask = GetNextExtEventMask();
- SetMaskForExtEvent(mask, DeviceButtonRelease);
- AllowPropagateSuppress(mask);
+ SetMaskForExtEvent(DeviceButtonReleaseMask, DeviceButtonRelease);
+ AllowPropagateSuppress(DeviceButtonReleaseMask);
+ SetCriticalEvent(DeviceButtonRelease);
- mask = GetNextExtEventMask();
- SetMaskForExtEvent(mask, ProximityIn);
- SetMaskForExtEvent(mask, ProximityOut);
- AllowPropagateSuppress(mask);
+ SetMaskForExtEvent(DeviceProximityMask, ProximityIn);
+ SetMaskForExtEvent(DeviceProximityMask, ProximityOut);
- mask = GetNextExtEventMask();
- DeviceStateNotifyMask = mask;
- SetMaskForExtEvent(mask, DeviceStateNotify);
+ SetMaskForExtEvent(DeviceStateNotifyMask, DeviceStateNotify);
- mask = GetNextExtEventMask();
- DevicePointerMotionMask = mask;
- SetMaskForExtEvent(mask, DeviceMotionNotify);
- AllowPropagateSuppress(mask);
+ SetMaskForExtEvent(DevicePointerMotionMask, DeviceMotionNotify);
+ AllowPropagateSuppress(DevicePointerMotionMask);
+ SetCriticalEvent(DeviceMotionNotify);
- DevicePointerMotionHintMask = GetNextExtEventMask();
SetEventInfo(DevicePointerMotionHintMask, _devicePointerMotionHint);
- SetEventInfo(GetNextExtEventMask(), _deviceButton1Motion);
- SetEventInfo(GetNextExtEventMask(), _deviceButton2Motion);
- SetEventInfo(GetNextExtEventMask(), _deviceButton3Motion);
- SetEventInfo(GetNextExtEventMask(), _deviceButton4Motion);
- SetEventInfo(GetNextExtEventMask(), _deviceButton5Motion);
-
- /* If DeviceButtonMotionMask is != ButtonMotionMask, event delivery
- * breaks down. The device needs the dev->button->motionMask. If DBMM is
- * the same as BMM, we can ensure that both core and device events can be
- * delivered, without the need for extra structures in the DeviceIntRec.
- */
- DeviceButtonMotionMask = GetNextExtEventMask();
+ SetEventInfo(DeviceButton1MotionMask, _deviceButton1Motion);
+ SetEventInfo(DeviceButton2MotionMask, _deviceButton2Motion);
+ SetEventInfo(DeviceButton3MotionMask, _deviceButton3Motion);
+ SetEventInfo(DeviceButton4MotionMask, _deviceButton4Motion);
+ SetEventInfo(DeviceButton5MotionMask, _deviceButton5Motion);
SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion);
- if (DeviceButtonMotionMask != ButtonMotionMask)
- {
- /* This should never happen, but if it does, hide under the
- * bed and cry for help. */
- ErrorF("[Xi] DeviceButtonMotionMask != ButtonMotionMask. Trouble!\n");
- }
- DeviceFocusChangeMask = GetNextExtEventMask();
SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn);
SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusOut);
- mask = GetNextExtEventMask();
- SetMaskForExtEvent(mask, DeviceMappingNotify);
- DeviceMappingNotifyMask = mask;
-
- mask = GetNextExtEventMask();
- SetMaskForExtEvent(mask, ChangeDeviceNotify);
- ChangeDeviceNotifyMask = mask;
+ SetMaskForExtEvent(DeviceMappingNotifyMask, DeviceMappingNotify);
+ SetMaskForExtEvent(ChangeDeviceNotifyMask, ChangeDeviceNotify);
- DeviceButtonGrabMask = GetNextExtEventMask();
SetEventInfo(DeviceButtonGrabMask, _deviceButtonGrab);
SetExclusiveAccess(DeviceButtonGrabMask);
- DeviceOwnerGrabButtonMask = GetNextExtEventMask();
SetEventInfo(DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton);
-
- DevicePresenceNotifyMask = GetNextExtEventMask();
SetEventInfo(DevicePresenceNotifyMask, _devicePresence);
-
- DevicePropertyNotifyMask = GetNextExtEventMask();
SetMaskForExtEvent(DevicePropertyNotifyMask, DevicePropertyNotify);
SetEventInfo(0, _noExtensionEvent);
@@ -792,7 +1090,6 @@ RestoreExtensionEvents(void)
EventInfo[i].type = 0;
}
ExtEventIndex = 0;
- lastExtEventMask = 1;
DeviceValuator = 0;
DeviceKeyPress = 1;
DeviceKeyRelease = 2;
@@ -852,21 +1149,6 @@ IResetProc(ExtensionEntry * unused)
RestoreExtensionEvents();
}
-/*****************************************************************
- *
- * Returns TRUE if the device has some sort of pointer type.
- *
- */
-
-Bool
-DeviceIsPointerType(DeviceIntPtr dev)
-{
- if (dev_type[1].type == dev->type)
- return TRUE;
-
- return FALSE;
-}
-
/***********************************************************************
*
@@ -877,7 +1159,7 @@ DeviceIsPointerType(DeviceIntPtr dev)
void
AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name)
{
- dev->type = type;
+ dev->xinput_type = type;
dev->name = (char *)xalloc(strlen(name) + 1);
strcpy(dev->name, name);
}
@@ -985,9 +1267,8 @@ XInputExtensionInit(void)
if (extEntry) {
IReqCode = extEntry->base;
IEventBase = extEntry->eventBase;
- AllExtensionVersions[IReqCode - 128] = thisversion;
+ XIVersion = thisversion;
MakeDeviceTypeAtoms();
- XIInitKnownProperties();
RT_INPUTCLIENT = CreateNewResourceType((DeleteType) InputClientGone);
RegisterResourceName(RT_INPUTCLIENT, "INPUTCLIENT");
FixExtensionEvents(extEntry);
@@ -1009,7 +1290,20 @@ XInputExtensionInit(void)
EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
+ GERegisterExtension(IReqCode, XI2EventSwap);
+
+
+ memset(&xi_all_devices, 0, sizeof(xi_all_devices));
+ memset(&xi_all_master_devices, 0, sizeof(xi_all_master_devices));
+ xi_all_devices.id = XIAllDevices;
+ xi_all_devices.name = "XIAllDevices";
+ xi_all_master_devices.id = XIAllMasterDevices;
+ xi_all_master_devices.name = "XIAllMasterDevices";
+
+ inputInfo.all_devices = &xi_all_devices;
+ inputInfo.all_master_devices = &xi_all_master_devices;
} else {
FatalError("IExtensionInit: AddExtensions failed\n");
}
}
+
diff --git a/xorg-server/Xi/getbmap.c b/xorg-server/Xi/getbmap.c
index 9f93b06ef..e2d58972a 100644
--- a/xorg-server/Xi/getbmap.c
+++ b/xorg-server/Xi/getbmap.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -111,7 +109,7 @@ ProcXGetDeviceButtonMapping(ClientPtr client)
return BadMatch;
rep.nElts = b->numButtons;
- rep.length = (rep.nElts + (4 - 1)) / 4;
+ rep.length = bytes_to_int32(rep.nElts);
WriteReplyToClient(client, sizeof(xGetDeviceButtonMappingReply), &rep);
(void)WriteToClient(client, rep.nElts, (char *)&b->map[1]);
return Success;
diff --git a/xorg-server/Xi/getdctl.c b/xorg-server/Xi/getdctl.c
index c979959e2..68181fa61 100644
--- a/xorg-server/Xi/getdctl.c
+++ b/xorg-server/Xi/getdctl.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -308,7 +306,7 @@ ProcXGetDeviceControl(ClientPtr client)
break;
}
- rep.length = (total_length + 3) >> 2;
+ rep.length = bytes_to_int32(total_length);
WriteReplyToClient(client, sizeof(xGetDeviceControlReply), &rep);
WriteToClient(client, total_length, savbuf);
xfree(savbuf);
diff --git a/xorg-server/Xi/getfctl.c b/xorg-server/Xi/getfctl.c
index 1b1e594a2..607765e98 100644
--- a/xorg-server/Xi/getfctl.c
+++ b/xorg-server/Xi/getfctl.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -360,7 +358,7 @@ ProcXGetFeedbackControl(ClientPtr client)
for (b = dev->bell; b; b = b->next)
CopySwapBellFeedback(client, b, &buf);
- rep.length = (total_length + 3) >> 2;
+ rep.length = bytes_to_int32(total_length);
WriteReplyToClient(client, sizeof(xGetFeedbackControlReply), &rep);
WriteToClient(client, total_length, savbuf);
xfree(savbuf);
diff --git a/xorg-server/Xi/getfocus.c b/xorg-server/Xi/getfocus.c
index dfef22fb7..69eadde87 100644
--- a/xorg-server/Xi/getfocus.c
+++ b/xorg-server/Xi/getfocus.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/Xi/getkmap.c b/xorg-server/Xi/getkmap.c
index 0eec1d8df..78449e212 100644
--- a/xorg-server/Xi/getkmap.c
+++ b/xorg-server/Xi/getkmap.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -61,6 +59,8 @@ SOFTWARE.
#include <X11/extensions/XIproto.h>
#include "exglobals.h"
#include "swaprep.h"
+#include "xkbsrv.h"
+#include "xkbstr.h"
#include "getkmap.h"
@@ -92,7 +92,8 @@ ProcXGetDeviceKeyMapping(ClientPtr client)
{
xGetDeviceKeyMappingReply rep;
DeviceIntPtr dev;
- KeySymsPtr k;
+ XkbDescPtr xkb;
+ KeySymsPtr syms;
int rc;
REQUEST(xGetDeviceKeyMappingReq);
@@ -103,31 +104,37 @@ ProcXGetDeviceKeyMapping(ClientPtr client)
return rc;
if (dev->key == NULL)
return BadMatch;
- k = &dev->key->curKeySyms;
+ xkb = dev->key->xkbInfo->desc;
- if ((stuff->firstKeyCode < k->minKeyCode) ||
- (stuff->firstKeyCode > k->maxKeyCode)) {
+ if (stuff->firstKeyCode < xkb->min_key_code ||
+ stuff->firstKeyCode > xkb->max_key_code) {
client->errorValue = stuff->firstKeyCode;
return BadValue;
}
- if (stuff->firstKeyCode + stuff->count > k->maxKeyCode + 1) {
+ if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) {
client->errorValue = stuff->count;
return BadValue;
}
+ syms = XkbGetCoreMap(dev);
+ if (!syms)
+ return BadAlloc;
+
rep.repType = X_Reply;
rep.RepType = X_GetDeviceKeyMapping;
rep.sequenceNumber = client->sequence;
- rep.keySymsPerKeyCode = k->mapWidth;
- rep.length = (k->mapWidth * stuff->count); /* KeySyms are 4 bytes */
+ rep.keySymsPerKeyCode = syms->mapWidth;
+ rep.length = (syms->mapWidth * stuff->count); /* KeySyms are 4 bytes */
WriteReplyToClient(client, sizeof(xGetDeviceKeyMappingReply), &rep);
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
WriteSwappedDataToClient(client,
- k->mapWidth * stuff->count * sizeof(KeySym),
- &k->map[(stuff->firstKeyCode - k->minKeyCode) *
- k->mapWidth]);
+ syms->mapWidth * stuff->count * sizeof(KeySym),
+ &syms->map[syms->mapWidth * (stuff->firstKeyCode -
+ syms->minKeyCode)]);
+ xfree(syms->map);
+ xfree(syms);
return Success;
}
diff --git a/xorg-server/Xi/getmmap.c b/xorg-server/Xi/getmmap.c
index c6c9c3362..ddf27a5f0 100644
--- a/xorg-server/Xi/getmmap.c
+++ b/xorg-server/Xi/getmmap.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -89,36 +87,34 @@ SProcXGetDeviceModifierMapping(ClientPtr client)
int
ProcXGetDeviceModifierMapping(ClientPtr client)
{
- CARD8 maxkeys;
DeviceIntPtr dev;
xGetDeviceModifierMappingReply rep;
- KeyClassPtr kp;
- int rc;
+ KeyCode *modkeymap = NULL;
+ int ret, max_keys_per_mod;
REQUEST(xGetDeviceModifierMappingReq);
REQUEST_SIZE_MATCH(xGetDeviceModifierMappingReq);
- rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
+ if (ret != Success)
+ return ret;
- kp = dev->key;
- if (kp == NULL)
- return BadMatch;
-
- maxkeys = kp->maxKeysPerModifier;
+ ret = generate_modkeymap(client, dev, &modkeymap, &max_keys_per_mod);
+ if (ret != Success)
+ return ret;
rep.repType = X_Reply;
rep.RepType = X_GetDeviceModifierMapping;
- rep.numKeyPerModifier = maxkeys;
+ rep.numKeyPerModifier = max_keys_per_mod;
rep.sequenceNumber = client->sequence;
/* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
- rep.length = 2 * maxkeys;
+ rep.length = max_keys_per_mod << 1;
WriteReplyToClient(client, sizeof(xGetDeviceModifierMappingReply), &rep);
+ WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap);
+
+ xfree(modkeymap);
- /* Reply with the (modified by DDX) map that SetModifierMapping passed in */
- WriteToClient(client, 8 * maxkeys, (char *)kp->modifierKeyMap);
return Success;
}
diff --git a/xorg-server/Xi/getprop.c b/xorg-server/Xi/getprop.c
index 188f549e5..1f28a8a40 100644
--- a/xorg-server/Xi/getprop.c
+++ b/xorg-server/Xi/getprop.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -122,7 +120,7 @@ ProcXGetDeviceDontPropagateList(ClientPtr client)
if (count) {
rep.count = count;
buf = (XEventClass *) xalloc(rep.count * sizeof(XEventClass));
- rep.length = (rep.count * sizeof(XEventClass) + 3) >> 2;
+ rep.length = bytes_to_int32(rep.count * sizeof(XEventClass));
tbuf = buf;
for (i = 0; i < EMASKSIZE; i++)
diff --git a/xorg-server/Xi/getselev.c b/xorg-server/Xi/getselev.c
index caa376fcb..90f6284e5 100644
--- a/xorg-server/Xi/getselev.c
+++ b/xorg-server/Xi/getselev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -133,7 +131,7 @@ ProcXGetSelectedExtensionEvents(ClientPtr client)
total_length = (rep.all_clients_count + rep.this_client_count) *
sizeof(XEventClass);
- rep.length = (total_length + 3) >> 2;
+ rep.length = bytes_to_int32(total_length);
buf = (XEventClass *) xalloc(total_length);
tclient = buf;
diff --git a/xorg-server/Xi/getvers.c b/xorg-server/Xi/getvers.c
index 88ff1991a..c8e9ebca6 100644
--- a/xorg-server/Xi/getvers.c
+++ b/xorg-server/Xi/getvers.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -64,7 +62,7 @@ SOFTWARE.
#include "getvers.h"
-XExtensionVersion AllExtensionVersions[128];
+XExtensionVersion XIVersion;
/***********************************************************************
*
@@ -94,24 +92,22 @@ int
ProcXGetExtensionVersion(ClientPtr client)
{
xGetExtensionVersionReply rep;
- XIClientPtr pXIClient;
REQUEST(xGetExtensionVersionReq);
REQUEST_AT_LEAST_SIZE(xGetExtensionVersionReq);
- if (stuff->length != (sizeof(xGetExtensionVersionReq) +
- stuff->nbytes + 3) >> 2)
+ if (stuff->length != bytes_to_int32(sizeof(xGetExtensionVersionReq) +
+ stuff->nbytes))
return BadLength;
- pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
-
+ memset(&rep, 0, sizeof(xGetExtensionVersionReply));
rep.repType = X_Reply;
rep.RepType = X_GetExtensionVersion;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.present = TRUE;
- rep.major_version = AllExtensionVersions[IReqCode - 128].major_version;
- rep.minor_version = AllExtensionVersions[IReqCode - 128].minor_version;
+ rep.major_version = XIVersion.major_version;
+ rep.minor_version = XIVersion.minor_version;
WriteReplyToClient(client, sizeof(xGetExtensionVersionReply), &rep);
diff --git a/xorg-server/Xi/grabdev.c b/xorg-server/Xi/grabdev.c
index 8217a9928..925c9a6d2 100644
--- a/xorg-server/Xi/grabdev.c
+++ b/xorg-server/Xi/grabdev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -86,7 +84,7 @@ SProcXGrabDevice(ClientPtr client)
swapl(&stuff->time, n);
swaps(&stuff->event_count, n);
- if (stuff->length != (sizeof(xGrabDeviceReq) >> 2) + stuff->event_count)
+ if (stuff->length != bytes_to_int32(sizeof(xGrabDeviceReq)) + stuff->event_count)
return BadLength;
SwapLongs((CARD32 *) (&stuff[1]), stuff->event_count);
@@ -106,12 +104,13 @@ ProcXGrabDevice(ClientPtr client)
int rc;
xGrabDeviceReply rep;
DeviceIntPtr dev;
+ GrabMask mask;
struct tmask tmp[EMASKSIZE];
REQUEST(xGrabDeviceReq);
REQUEST_AT_LEAST_SIZE(xGrabDeviceReq);
- if (stuff->length != (sizeof(xGrabDeviceReq) >> 2) + stuff->event_count)
+ if (stuff->length != bytes_to_int32(sizeof(xGrabDeviceReq)) + stuff->event_count)
return BadLength;
rep.repType = X_Reply;
@@ -128,10 +127,13 @@ ProcXGrabDevice(ClientPtr client)
X_GrabDevice)) != Success)
return rc;
- rc = GrabDevice(client, dev, stuff->this_device_mode,
- stuff->other_devices_mode, stuff->grabWindow,
+ mask.xi = tmp[stuff->deviceid].mask;
+
+ rc = GrabDevice(client, dev, stuff->other_devices_mode,
+ stuff->this_device_mode, stuff->grabWindow,
stuff->ownerEvents, stuff->time,
- tmp[stuff->deviceid].mask, &rep.status, FALSE);
+ &mask, GRABTYPE_XI, None, None,
+ &rep.status);
if (rc != Success)
return rc;
@@ -179,10 +181,10 @@ CreateMaskFromList(ClientPtr client, XEventClass * list, int count,
for (i = 0; i < count; i++, list++) {
device = *list >> 8;
- if (device > 255) /* FIXME: we only use 7 bit for devices? */
+ if (device > 255)
return BadClass;
- rc = dixLookupDevice(&tdev, device, client, DixReadAccess);
+ rc = dixLookupDevice(&tdev, device, client, DixUseAccess);
if (rc != BadDevice && rc != Success)
return rc;
if (rc == BadDevice || (dev != NULL && tdev != dev))
diff --git a/xorg-server/Xi/grabdevb.c b/xorg-server/Xi/grabdevb.c
index 98f7e117d..e235f5313 100644
--- a/xorg-server/Xi/grabdevb.c
+++ b/xorg-server/Xi/grabdevb.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -105,12 +103,14 @@ ProcXGrabDeviceButton(ClientPtr client)
DeviceIntPtr mdev;
XEventClass *class;
struct tmask tmp[EMASKSIZE];
+ GrabParameters param;
+ GrabMask mask;
REQUEST(xGrabDeviceButtonReq);
REQUEST_AT_LEAST_SIZE(xGrabDeviceButtonReq);
if (stuff->length !=
- (sizeof(xGrabDeviceButtonReq) >> 2) + stuff->event_count)
+ bytes_to_int32(sizeof(xGrabDeviceButtonReq)) + stuff->event_count)
return BadLength;
ret = dixLookupDevice(&dev, stuff->grabbed_device, client, DixGrabAccess);
@@ -119,14 +119,14 @@ ProcXGrabDeviceButton(ClientPtr client)
if (stuff->modifier_device != UseXKeyboard) {
ret = dixLookupDevice(&mdev, stuff->modifier_device, client,
- DixReadAccess);
+ DixUseAccess);
if (ret != Success)
return ret;
if (mdev->key == NULL)
return BadMatch;
} else {
mdev = PickKeyboard(client);
- ret = XaceHook(XACE_DEVICE_ACCESS, client, mdev, DixReadAccess);
+ ret = XaceHook(XACE_DEVICE_ACCESS, client, mdev, DixUseAccess);
if (ret != Success)
return ret;
}
@@ -137,10 +137,18 @@ ProcXGrabDeviceButton(ClientPtr client)
stuff->event_count, tmp, dev,
X_GrabDeviceButton)) != Success)
return ret;
- ret = GrabButton(client, dev, stuff->this_device_mode,
- stuff->other_devices_mode, stuff->modifiers, mdev,
- stuff->button, stuff->grabWindow, stuff->ownerEvents,
- (Cursor) 0, (Window) 0, tmp[stuff->grabbed_device].mask);
+
+ memset(&param, 0, sizeof(param));
+ param.grabtype = GRABTYPE_XI;
+ param.ownerEvents = stuff->ownerEvents;
+ param.this_device_mode = stuff->this_device_mode;
+ param.other_devices_mode = stuff->other_devices_mode;
+ param.grabWindow = stuff->grabWindow;
+ param.modifiers = stuff->modifiers;
+ mask.xi = tmp[stuff->grabbed_device].mask;
+
+ ret = GrabButton(client, dev, mdev, stuff->button, &param,
+ GRABTYPE_XI, &mask);
return ret;
}
diff --git a/xorg-server/Xi/grabdevk.c b/xorg-server/Xi/grabdevk.c
index 6a245f25a..b34867b5f 100644
--- a/xorg-server/Xi/grabdevk.c
+++ b/xorg-server/Xi/grabdevk.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -103,11 +101,13 @@ ProcXGrabDeviceKey(ClientPtr client)
DeviceIntPtr mdev;
XEventClass *class;
struct tmask tmp[EMASKSIZE];
+ GrabParameters param;
+ GrabMask mask;
REQUEST(xGrabDeviceKeyReq);
REQUEST_AT_LEAST_SIZE(xGrabDeviceKeyReq);
- if (stuff->length != (sizeof(xGrabDeviceKeyReq) >> 2) + stuff->event_count)
+ if (stuff->length != bytes_to_int32(sizeof(xGrabDeviceKeyReq)) + stuff->event_count)
return BadLength;
ret = dixLookupDevice(&dev, stuff->grabbed_device, client, DixGrabAccess);
@@ -116,14 +116,14 @@ ProcXGrabDeviceKey(ClientPtr client)
if (stuff->modifier_device != UseXKeyboard) {
ret = dixLookupDevice(&mdev, stuff->modifier_device, client,
- DixReadAccess);
+ DixUseAccess);
if (ret != Success)
return ret;
if (mdev->key == NULL)
return BadMatch;
} else {
mdev = PickKeyboard(client);
- ret = XaceHook(XACE_DEVICE_ACCESS, client, mdev, DixReadAccess);
+ ret = XaceHook(XACE_DEVICE_ACCESS, client, mdev, DixUseAccess);
if (ret != Success)
return ret;
}
@@ -135,10 +135,17 @@ ProcXGrabDeviceKey(ClientPtr client)
X_GrabDeviceKey)) != Success)
return ret;
- ret = GrabKey(client, dev, stuff->this_device_mode,
- stuff->other_devices_mode, stuff->modifiers, mdev,
- stuff->key, stuff->grabWindow, stuff->ownerEvents,
- tmp[stuff->grabbed_device].mask);
+
+ memset(&param, 0, sizeof(param));
+ param.grabtype = GRABTYPE_XI;
+ param.ownerEvents = stuff->ownerEvents;
+ param.this_device_mode = stuff->this_device_mode;
+ param.other_devices_mode = stuff->other_devices_mode;
+ param.grabWindow = stuff->grabWindow;
+ param.modifiers = stuff->modifiers;
+ mask.xi = tmp[stuff->grabbed_device].mask;
+
+ ret = GrabKey(client, dev, mdev, stuff->key, &param, GRABTYPE_XI, &mask);
return ret;
}
diff --git a/xorg-server/Xi/gtmotion.c b/xorg-server/Xi/gtmotion.c
index 8fa0cca29..8e91c5a47 100644
--- a/xorg-server/Xi/gtmotion.c
+++ b/xorg-server/Xi/gtmotion.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -138,7 +136,7 @@ ProcXGetDeviceMotionEvents(ClientPtr client)
(ScreenPtr) NULL, FALSE);
}
if (rep.nEvents > 0) {
- length = (rep.nEvents * size + 3) >> 2;
+ length = bytes_to_int32(rep.nEvents * size);
rep.length = length;
}
nEvents = rep.nEvents;
diff --git a/xorg-server/Xi/listdev.c b/xorg-server/Xi/listdev.c
index 56ba2f6eb..98ef7aa43 100644
--- a/xorg-server/Xi/listdev.c
+++ b/xorg-server/Xi/listdev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -63,9 +61,10 @@ SOFTWARE.
#include <X11/extensions/XIproto.h>
#include "XIstubs.h"
#include "extnsionst.h"
-#include "exglobals.h" /* FIXME */
#include "exevents.h"
#include "xace.h"
+#include "xkbsrv.h"
+#include "xkbstr.h"
#include "listdev.h"
@@ -93,7 +92,7 @@ SProcXListInputDevices(ClientPtr client)
*
*/
-void
+static void
SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size)
{
int chunks;
@@ -175,11 +174,11 @@ CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes,
dev = (xDeviceInfoPtr) * buf;
dev->id = d->id;
- dev->type = d->type;
+ dev->type = d->xinput_type;
dev->num_classes = num_classes;
- if (d->isMaster && IsKeyboardDevice(d))
+ if (IsMaster(d) && IsKeyboardDevice(d))
dev->use = IsXKeyboard;
- else if (d->isMaster && IsPointerDevice(d))
+ else if (IsMaster(d) && IsPointerDevice(d))
dev->use = IsXPointer;
else if (d->key && d->kbdfeed)
dev->use = IsXExtensionKeyboard;
@@ -209,8 +208,8 @@ CopySwapKeyClass(ClientPtr client, KeyClassPtr k, char **buf)
k2 = (xKeyInfoPtr) * buf;
k2->class = KeyClass;
k2->length = sizeof(xKeyInfo);
- k2->min_keycode = k->curKeySyms.minKeyCode;
- k2->max_keycode = k->curKeySyms.maxKeyCode;
+ k2->min_keycode = k->xkbInfo->desc->min_key_code;
+ k2->max_keycode = k->xkbInfo->desc->max_key_code;
k2->num_keys = k2->max_keycode - k2->min_keycode + 1;
if (client && client->swapped) {
swaps(&k2->num_keys, n);
@@ -273,6 +272,24 @@ CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf)
return (i);
}
+static void
+CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
+ char** classbuf)
+{
+ if (dev->key != NULL) {
+ CopySwapKeyClass(client, dev->key, classbuf);
+ (*num_classes)++;
+ }
+ if (dev->button != NULL) {
+ CopySwapButtonClass(client, dev->button, classbuf);
+ (*num_classes)++;
+ }
+ if (dev->valuator != NULL) {
+ (*num_classes) +=
+ CopySwapValuatorClass(client, dev->valuator, classbuf);
+ }
+}
+
/***********************************************************************
*
* This procedure lists information to be returned for an input device.
@@ -288,24 +305,26 @@ ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev,
CopySwapClasses(client, d, &dev->num_classes, classbuf);
}
-void
-CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
- char** classbuf)
+/***********************************************************************
+ *
+ * This procedure checks if a device should be left off the list.
+ *
+ */
+
+static Bool
+ShouldSkipDevice(ClientPtr client, DeviceIntPtr d)
{
- if (dev->key != NULL) {
- CopySwapKeyClass(client, dev->key, classbuf);
- (*num_classes)++;
- }
- if (dev->button != NULL) {
- CopySwapButtonClass(client, dev->button, classbuf);
- (*num_classes)++;
- }
- if (dev->valuator != NULL) {
- (*num_classes) +=
- CopySwapValuatorClass(client, dev->valuator, classbuf);
+ /* don't send master devices other than VCP/VCK */
+ if (!IsMaster(d) || d == inputInfo.pointer || d == inputInfo.keyboard)
+ {
+ int rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess);
+ if (rc == Success)
+ return FALSE;
}
+ return TRUE;
}
+
/***********************************************************************
*
* This procedure lists the input devices available to the server.
@@ -320,66 +339,80 @@ int
ProcXListInputDevices(ClientPtr client)
{
xListInputDevicesReply rep;
- XIClientPtr pXIClient;
int numdevs = 0;
int namesize = 1; /* need 1 extra byte for strcpy */
- int rc, size = 0;
+ int i = 0, size = 0;
int total_length;
- char *devbuf;
- char *classbuf;
- char *namebuf;
- char *savbuf;
+ char *devbuf, *classbuf, *namebuf, *savbuf;
+ Bool *skip;
xDeviceInfo *dev;
DeviceIntPtr d;
REQUEST_SIZE_MATCH(xListInputDevicesReq);
+ memset(&rep, 0, sizeof(xListInputDevicesReply));
rep.repType = X_Reply;
rep.RepType = X_ListInputDevices;
rep.length = 0;
rep.sequenceNumber = client->sequence;
- pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
AddOtherInputDevices();
- for (d = inputInfo.devices; d; d = d->next) {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess);
- if (rc != Success)
- return rc;
+ /* allocate space for saving skip value */
+ skip = xcalloc(sizeof(Bool), inputInfo.numDevices);
+ if (!skip)
+ return BadAlloc;
+
+ /* figure out which devices to skip */
+ numdevs = 0;
+ for (d = inputInfo.devices; d; d = d->next, i++) {
+ skip[i] = ShouldSkipDevice(client, d);
+ if (skip[i])
+ continue;
+
SizeDeviceInfo(d, &namesize, &size);
numdevs++;
}
- for (d = inputInfo.off_devices; d; d = d->next) {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess);
- if (rc != Success)
- return rc;
+ for (d = inputInfo.off_devices; d; d = d->next, i++) {
+ skip[i] = ShouldSkipDevice(client, d);
+ if (skip[i])
+ continue;
+
SizeDeviceInfo(d, &namesize, &size);
numdevs++;
}
+ /* allocate space for reply */
total_length = numdevs * sizeof(xDeviceInfo) + size + namesize;
- devbuf = (char *)xalloc(total_length);
+ devbuf = (char *)xcalloc(1, total_length);
classbuf = devbuf + (numdevs * sizeof(xDeviceInfo));
namebuf = classbuf + size;
savbuf = devbuf;
+ /* fill in and send reply */
+ i = 0;
dev = (xDeviceInfoPtr) devbuf;
- for (d = inputInfo.devices; d; d = d->next)
- {
+ for (d = inputInfo.devices; d; d = d->next, i++) {
+ if (skip[i])
+ continue;
+
ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf);
}
- for (d = inputInfo.off_devices; d; d = d->next)
- {
+ for (d = inputInfo.off_devices; d; d = d->next, i++) {
+ if (skip[i])
+ continue;
+
ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf);
}
rep.ndevices = numdevs;
- rep.length = (total_length + 3) >> 2;
+ rep.length = bytes_to_int32(total_length);
WriteReplyToClient(client, sizeof(xListInputDevicesReply), &rep);
WriteToClient(client, total_length, savbuf);
xfree(savbuf);
+ xfree(skip);
return Success;
}
diff --git a/xorg-server/Xi/listdev.h b/xorg-server/Xi/listdev.h
index 39ea2d635..b0d2dd5e2 100644
--- a/xorg-server/Xi/listdev.h
+++ b/xorg-server/Xi/listdev.h
@@ -43,15 +43,4 @@ void SRepXListInputDevices(ClientPtr /* client */ ,
xListInputDevicesReply * /* rep */
);
-void
-CopySwapClasses(ClientPtr /* client */,
- DeviceIntPtr /* dev */,
- CARD8* /* num_classes */,
- char** /* classbuf */);
-
-void
-SizeDeviceInfo(DeviceIntPtr /* dev */,
- int* /* namesize */,
- int* /* size */);
-
#endif /* LISTDEV_H */
diff --git a/xorg-server/Xi/opendev.c b/xorg-server/Xi/opendev.c
index 8d249278d..3844d25a2 100644
--- a/xorg-server/Xi/opendev.c
+++ b/xorg-server/Xi/opendev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -114,13 +112,14 @@ ProcXOpenDevice(ClientPtr client)
} else if (status != Success)
return status;
- if (dev->isMaster)
- return BadDevice;
+ if (IsMaster(dev))
+ return BadDevice;
OpenInputDevice(dev, client, &status);
if (status != Success)
return status;
+ memset(&rep, 0, sizeof(xOpenDeviceReply));
rep.repType = X_Reply;
rep.RepType = X_OpenDevice;
rep.sequenceNumber = client->sequence;
@@ -151,7 +150,7 @@ ProcXOpenDevice(ClientPtr client)
}
evbase[j].class = OtherClass;
evbase[j++].event_type_base = event_base[OtherClass];
- rep.length = (j * sizeof(xInputClassInfo) + 3) >> 2;
+ rep.length = bytes_to_int32(j * sizeof(xInputClassInfo));
rep.num_classes = j;
WriteReplyToClient(client, sizeof(xOpenDeviceReply), &rep);
WriteToClient(client, j * sizeof(xInputClassInfo), (char *)evbase);
diff --git a/xorg-server/Xi/queryst.c b/xorg-server/Xi/queryst.c
index 21de843f3..60ec32ec9 100644
--- a/xorg-server/Xi/queryst.c
+++ b/xorg-server/Xi/queryst.c
@@ -32,8 +32,6 @@ from The Open Group.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -44,6 +42,8 @@ from The Open Group.
#include <X11/extensions/XIproto.h>
#include "exevents.h"
#include "exglobals.h"
+#include "xkbsrv.h"
+#include "xkbstr.h"
#include "queryst.h"
@@ -85,7 +85,7 @@ ProcXQueryDeviceState(ClientPtr client)
xValuatorState *tv;
xQueryDeviceStateReply rep;
DeviceIntPtr dev;
- int *values;
+ double *values;
REQUEST(xQueryDeviceStateReq);
REQUEST_SIZE_MATCH(xQueryDeviceStateReq);
@@ -128,7 +128,8 @@ ProcXQueryDeviceState(ClientPtr client)
tk = (xKeyState *) buf;
tk->class = KeyClass;
tk->length = sizeof(xKeyState);
- tk->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode + 1;
+ tk->num_keys = k->xkbInfo->desc->max_key_code -
+ k->xkbInfo->desc->min_key_code + 1;
for (i = 0; i < 32; i++)
tk->keys[i] = k->down[i];
buf += sizeof(xKeyState);
@@ -160,7 +161,7 @@ ProcXQueryDeviceState(ClientPtr client)
}
rep.num_classes = num_classes;
- rep.length = (total_length + 3) >> 2;
+ rep.length = bytes_to_int32(total_length);
WriteReplyToClient(client, sizeof(xQueryDeviceStateReply), &rep);
if (total_length > 0)
WriteToClient(client, total_length, savbuf);
diff --git a/xorg-server/Xi/selectev.c b/xorg-server/Xi/selectev.c
index 9c336fce5..031e602ad 100644
--- a/xorg-server/Xi/selectev.c
+++ b/xorg-server/Xi/selectev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
@@ -60,6 +58,7 @@ SOFTWARE.
#include "inputstr.h" /* DeviceIntPtr */
#include "windowstr.h" /* window structure */
#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
#include <X11/extensions/XIproto.h>
#include "exevents.h"
#include "exglobals.h"
@@ -68,7 +67,6 @@ SOFTWARE.
#include "selectev.h"
extern Mask ExtExclusiveMasks[];
-extern Mask ExtValidMasks[];
static int
HandleDevicePresenceMask(ClientPtr client, WindowPtr win,
@@ -106,10 +104,9 @@ HandleDevicePresenceMask(ClientPtr client, WindowPtr win,
if (mask == 0)
return Success;
- /* We always only use mksidx = MAXDEVICES for events not bound to
+ /* We always only use mksidx = AllDevices for events not bound to
* devices */
-
- if (AddExtensionClient (win, client, mask, MAXDEVICES) != Success)
+ if (AddExtensionClient (win, client, mask, XIAllDevices) != Success)
return BadAlloc;
RecalculateDeviceDeliverableEvents(win);
@@ -157,7 +154,7 @@ ProcXSelectExtensionEvent(ClientPtr client)
REQUEST(xSelectExtensionEventReq);
REQUEST_AT_LEAST_SIZE(xSelectExtensionEventReq);
- if (stuff->length != (sizeof(xSelectExtensionEventReq) >> 2) + stuff->count)
+ if (stuff->length != bytes_to_int32(sizeof(xSelectExtensionEventReq)) + stuff->count)
return BadLength;
ret = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
@@ -175,10 +172,13 @@ ProcXSelectExtensionEvent(ClientPtr client)
for (i = 0; i < EMASKSIZE; i++)
if (tmp[i].dev != NULL) {
+ if (tmp[i].mask & ~XIAllMasks) {
+ client->errorValue = tmp[i].mask;
+ return BadValue;
+ }
if ((ret =
SelectForWindow((DeviceIntPtr) tmp[i].dev, pWin, client,
- tmp[i].mask, ExtExclusiveMasks[i],
- ExtValidMasks[i])) != Success)
+ tmp[i].mask, ExtExclusiveMasks[i]))!= Success)
return ret;
}
diff --git a/xorg-server/Xi/sendexev.c b/xorg-server/Xi/sendexev.c
index 9b37de307..8629dd202 100644
--- a/xorg-server/Xi/sendexev.c
+++ b/xorg-server/Xi/sendexev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -91,8 +89,8 @@ SProcXSendExtensionEvent(ClientPtr client)
swapl(&stuff->destination, n);
swaps(&stuff->count, n);
- if (stuff->length != (sizeof(xSendExtensionEventReq) >> 2) + stuff->count +
- (stuff->num_events * (sizeof(xEvent) >> 2)))
+ if (stuff->length != bytes_to_int32(sizeof(xSendExtensionEventReq)) + stuff->count +
+ bytes_to_int32(stuff->num_events * sizeof(xEvent)))
return BadLength;
eventP = (xEvent *) & stuff[1];
@@ -128,8 +126,8 @@ ProcXSendExtensionEvent(ClientPtr client)
REQUEST(xSendExtensionEventReq);
REQUEST_AT_LEAST_SIZE(xSendExtensionEventReq);
- if (stuff->length != (sizeof(xSendExtensionEventReq) >> 2) + stuff->count +
- (stuff->num_events * (sizeof(xEvent) >> 2)))
+ if (stuff->length != bytes_to_int32(sizeof(xSendExtensionEventReq)) + stuff->count +
+ (stuff->num_events * bytes_to_int32(sizeof(xEvent))))
return BadLength;
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixWriteAccess);
diff --git a/xorg-server/Xi/setbmap.c b/xorg-server/Xi/setbmap.c
index f05225531..37c40e408 100644
--- a/xorg-server/Xi/setbmap.c
+++ b/xorg-server/Xi/setbmap.c
@@ -50,11 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
-#define IsOn(ptr, bit) \
- (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
-
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -99,31 +94,30 @@ ProcXSetDeviceButtonMapping(ClientPtr client)
REQUEST(xSetDeviceButtonMappingReq);
REQUEST_AT_LEAST_SIZE(xSetDeviceButtonMappingReq);
- if (stuff->length != (sizeof(xSetDeviceButtonMappingReq) +
- stuff->map_length + 3) >> 2)
+ if (stuff->length !=
+ bytes_to_int32(sizeof(xSetDeviceButtonMappingReq) + stuff->map_length))
return BadLength;
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
+ if (ret != Success)
+ return ret;
+
rep.repType = X_Reply;
rep.RepType = X_SetDeviceButtonMapping;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.status = MappingSuccess;
- ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
- if (ret != Success)
- return ret;
-
- ret = SetButtonMapping(client, dev, stuff->map_length, (BYTE *) & stuff[1]);
+ ret = ApplyPointerMapping(dev, (CARD8 *) &stuff[1], stuff->map_length, client);
+ if (ret == -1)
+ return BadValue;
+ else if (ret == MappingBusy)
+ rep.status = ret;
+ else if (ret != Success)
+ return ret;
- if (ret == BadValue || ret == BadMatch)
- return ret;
- else {
- rep.status = ret;
- WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep);
- }
+ WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep);
- if (ret != MappingBusy)
- SendDeviceMappingNotify(client, MappingPointer, 0, 0, dev);
return Success;
}
diff --git a/xorg-server/Xi/setdval.c b/xorg-server/Xi/setdval.c
index 20584629a..b384f0d3c 100644
--- a/xorg-server/Xi/setdval.c
+++ b/xorg-server/Xi/setdval.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -102,7 +100,7 @@ ProcXSetDeviceValuators(ClientPtr client)
rep.status = Success;
rep.sequenceNumber = client->sequence;
- if (stuff->length != (sizeof(xSetDeviceValuatorsReq) >> 2) +
+ if (stuff->length != bytes_to_int32(sizeof(xSetDeviceValuatorsReq)) +
stuff->num_valuators)
return BadLength;
diff --git a/xorg-server/Xi/setfocus.c b/xorg-server/Xi/setfocus.c
index c6edbc2e5..03bc37acb 100644
--- a/xorg-server/Xi/setfocus.c
+++ b/xorg-server/Xi/setfocus.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/Xi/setmmap.c b/xorg-server/Xi/setmmap.c
index 34efde595..cbe5dc8c5 100644
--- a/xorg-server/Xi/setmmap.c
+++ b/xorg-server/Xi/setmmap.c
@@ -50,14 +50,13 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS /* for inputstr.h */
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "inputstr.h" /* DeviceIntPtr */
#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
#include <X11/extensions/XIproto.h>
#include "exevents.h"
#include "exglobals.h"
@@ -93,33 +92,39 @@ ProcXSetDeviceModifierMapping(ClientPtr client)
int ret;
xSetDeviceModifierMappingReply rep;
DeviceIntPtr dev;
- KeyClassPtr kp;
REQUEST(xSetDeviceModifierMappingReq);
REQUEST_AT_LEAST_SIZE(xSetDeviceModifierMappingReq);
- ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
- if (ret != Success)
- return ret;
+ if (stuff->length != bytes_to_int32(sizeof(xSetDeviceModifierMappingReq)) +
+ (stuff->numKeyPerModifier << 1))
+ return BadLength;
rep.repType = X_Reply;
rep.RepType = X_SetDeviceModifierMapping;
rep.length = 0;
rep.sequenceNumber = client->sequence;
- ret = SetModifierMapping(client, dev, stuff->length,
- (sizeof(xSetDeviceModifierMappingReq) >> 2),
- stuff->numKeyPerModifier, (BYTE *) & stuff[1],
- &kp);
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
+ if (ret != Success)
+ return ret;
+
+ ret = change_modmap(client, dev, (KeyCode *) &stuff[1],
+ stuff->numKeyPerModifier);
+ if (ret == Success)
+ ret = MappingSuccess;
if (ret == MappingSuccess || ret == MappingBusy || ret == MappingFailed) {
rep.success = ret;
- if (ret == MappingSuccess)
- SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
WriteReplyToClient(client, sizeof(xSetDeviceModifierMappingReply),
&rep);
- } else if (ret == -1)
- return BadValue;
+ }
+ else if (ret == -1) {
+ return BadValue;
+ }
+ else {
+ return ret;
+ }
return Success;
}
diff --git a/xorg-server/Xi/setmode.c b/xorg-server/Xi/setmode.c
index 2badb5161..51e57675f 100644
--- a/xorg-server/Xi/setmode.c
+++ b/xorg-server/Xi/setmode.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
diff --git a/xorg-server/Xi/stubs.c b/xorg-server/Xi/stubs.c
index d01927c73..400e937d1 100644
--- a/xorg-server/Xi/stubs.c
+++ b/xorg-server/Xi/stubs.c
@@ -54,7 +54,6 @@ SOFTWARE.
* Xnest could do the same thing.
*/
-#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -154,7 +153,7 @@ AddOtherInputDevices(void)
void
OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status)
{
- *status = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess);
+ *status = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixUseAccess);
}
/****************************************************************************
diff --git a/xorg-server/Xi/ungrdev.c b/xorg-server/Xi/ungrdev.c
index f6525a287..a09c3d024 100644
--- a/xorg-server/Xi/ungrdev.c
+++ b/xorg-server/Xi/ungrdev.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -106,7 +104,7 @@ ProcXUngrabDevice(ClientPtr client)
time = ClientTimeToServerTime(stuff->time);
if ((CompareTimeStamps(time, currentTime) != LATER) &&
(CompareTimeStamps(time, dev->deviceGrab.grabTime) != EARLIER) &&
- (grab) && SameClient(grab, client) && !grab->coreGrab)
+ (grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_XI)
(*dev->deviceGrab.DeactivateGrab) (dev);
return Success;
}
diff --git a/xorg-server/Xi/ungrdevb.c b/xorg-server/Xi/ungrdevb.c
index d1aef5f13..4e93f1ae3 100644
--- a/xorg-server/Xi/ungrdevb.c
+++ b/xorg-server/Xi/ungrdevb.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -134,6 +132,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
temporaryGrab.device = dev;
temporaryGrab.window = pWin;
temporaryGrab.type = DeviceButtonPress;
+ temporaryGrab.grabtype = GRABTYPE_XI;
temporaryGrab.modifierDevice = mdev;
temporaryGrab.modifiersDetail.exact = stuff->modifiers;
temporaryGrab.modifiersDetail.pMask = NULL;
diff --git a/xorg-server/Xi/ungrdevk.c b/xorg-server/Xi/ungrdevk.c
index bc3ada987..3b4d6260e 100644
--- a/xorg-server/Xi/ungrdevk.c
+++ b/xorg-server/Xi/ungrdevk.c
@@ -50,8 +50,6 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
-#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -62,6 +60,8 @@ SOFTWARE.
#include <X11/extensions/XIproto.h>
#include "exglobals.h"
#include "dixgrabs.h"
+#include "xkbsrv.h"
+#include "xkbstr.h"
#include "ungrdevk.h"
@@ -126,8 +126,8 @@ ProcXUngrabDeviceKey(ClientPtr client)
if (rc != Success)
return rc;
- if (((stuff->key > dev->key->curKeySyms.maxKeyCode) ||
- (stuff->key < dev->key->curKeySyms.minKeyCode))
+ if (((stuff->key > dev->key->xkbInfo->desc->max_key_code) ||
+ (stuff->key < dev->key->xkbInfo->desc->min_key_code))
&& (stuff->key != AnyKey))
return BadValue;
@@ -139,6 +139,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
temporaryGrab.device = dev;
temporaryGrab.window = pWin;
temporaryGrab.type = DeviceKeyPress;
+ temporaryGrab.grabtype = GRABTYPE_XI;
temporaryGrab.modifierDevice = mdev;
temporaryGrab.modifiersDetail.exact = stuff->modifiers;
temporaryGrab.modifiersDetail.pMask = NULL;
diff --git a/xorg-server/Xi/xiallowev.c b/xorg-server/Xi/xiallowev.c
new file mode 100644
index 000000000..3077e1a44
--- /dev/null
+++ b/xorg-server/Xi/xiallowev.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+/***********************************************************************
+ *
+ * Request to allow some device events.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h" /* BadDevice */
+#include "xiallowev.h"
+
+int
+SProcXIAllowEvents(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIAllowEventsReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->time, n);
+
+ return ProcXIAllowEvents(client);
+}
+
+int
+ProcXIAllowEvents(ClientPtr client)
+{
+ TimeStamp time;
+ DeviceIntPtr dev;
+ int ret = Success;
+
+ REQUEST(xXIAllowEventsReq);
+ REQUEST_SIZE_MATCH(xXIAllowEventsReq);
+
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
+ if (ret != Success)
+ return ret;
+
+ time = ClientTimeToServerTime(stuff->time);
+
+ switch (stuff->mode) {
+ case XIReplayDevice:
+ AllowSome(client, time, dev, NOT_GRABBED);
+ break;
+ case XISyncDevice:
+ AllowSome(client, time, dev, FREEZE_NEXT_EVENT);
+ break;
+ case XIAsyncDevice:
+ AllowSome(client, time, dev, THAWED);
+ break;
+ case XIAsyncPairedDevice:
+ if (IsMaster(dev))
+ AllowSome(client, time, dev, THAW_OTHERS);
+ break;
+ case XISyncPair:
+ if (IsMaster(dev))
+ AllowSome(client, time, dev, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case XIAsyncPair:
+ if (IsMaster(dev))
+ AllowSome(client, time, dev, THAWED_BOTH);
+ break;
+ default:
+ client->errorValue = stuff->mode;
+ ret = BadValue;
+ }
+
+ return ret;
+}
+
diff --git a/xorg-server/Xi/xiallowev.h b/xorg-server/Xi/xiallowev.h
new file mode 100644
index 000000000..3a417b9b1
--- /dev/null
+++ b/xorg-server/Xi/xiallowev.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef XIALLOWEV_H
+#define XIALLOWEV_H 1
+
+int ProcXIAllowEvents(ClientPtr client);
+int SProcXIAllowEvents(ClientPtr client);
+
+#endif /* XIALLOWEV_H */
diff --git a/xorg-server/Xi/xichangecursor.c b/xorg-server/Xi/xichangecursor.c
new file mode 100644
index 000000000..f071e8406
--- /dev/null
+++ b/xorg-server/Xi/xichangecursor.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+/***********************************************************************
+ *
+ * Request to change a given device pointer's cursor.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include "scrnintstr.h" /* screen structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2proto.h>
+#include "extnsionst.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "input.h"
+
+#include "xichangecursor.h"
+
+/***********************************************************************
+ *
+ * This procedure allows a client to set one pointer's cursor.
+ *
+ */
+
+int
+SProcXIChangeCursor(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIChangeCursorReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->win, n);
+ swapl(&stuff->cursor, n);
+ swaps(&stuff->deviceid, n);
+ REQUEST_SIZE_MATCH(xXIChangeCursorReq);
+ return (ProcXIChangeCursor(client));
+}
+
+int ProcXIChangeCursor(ClientPtr client)
+{
+ int rc;
+ WindowPtr pWin = NULL;
+ DeviceIntPtr pDev = NULL;
+ CursorPtr pCursor = NULL;
+
+ REQUEST(xXIChangeCursorReq);
+ REQUEST_SIZE_MATCH(xXIChangeCursorReq);
+
+ rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!IsMaster(pDev) || !IsPointerDevice(pDev))
+ return BadDevice;
+
+ if (stuff->win != None)
+ {
+ rc = dixLookupWindow(&pWin, stuff->win, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+
+ if (stuff->cursor == None)
+ {
+ if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+ pCursor = rootCursor;
+ else
+ pCursor = (CursorPtr)None;
+ }
+ else
+ {
+ rc = dixLookupResourceByType((pointer *)&pCursor, stuff->cursor,
+ RT_CURSOR, client, DixUseAccess);
+ if (rc != Success)
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+
+ ChangeWindowDeviceCursor(pWin, pDev, pCursor);
+
+ return Success;
+}
+
diff --git a/xorg-server/Xi/xichangecursor.h b/xorg-server/Xi/xichangecursor.h
new file mode 100644
index 000000000..dc6ccb1af
--- /dev/null
+++ b/xorg-server/Xi/xichangecursor.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHDEVCUR_H
+#define CHDEVCUR_H 1
+
+int SProcXIChangeCursor(ClientPtr /* client */);
+int ProcXIChangeCursor(ClientPtr /* client */);
+
+#endif /* CHDEVCUR_H */
diff --git a/xorg-server/Xi/xichangehierarchy.c b/xorg-server/Xi/xichangehierarchy.c
new file mode 100644
index 000000000..1a06e4555
--- /dev/null
+++ b/xorg-server/Xi/xichangehierarchy.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ * Copyright 2009 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+/***********************************************************************
+ *
+ * Request change in the device hierarchy.
+ *
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include "scrnintstr.h" /* screen structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2proto.h>
+#include <X11/extensions/geproto.h>
+#include "extnsionst.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "geext.h"
+#include "xace.h"
+#include "xiquerydevice.h" /* for GetDeviceUse */
+
+#include "xkbsrv.h"
+
+#include "xichangehierarchy.h"
+
+/**
+ * Send the current state of the device hierarchy to all clients.
+ */
+void XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
+{
+ xXIHierarchyEvent *ev;
+ xXIHierarchyInfo *info;
+ DeviceIntRec dummyDev;
+ DeviceIntPtr dev;
+ int i;
+
+ if (!flags)
+ return;
+
+ ev = xcalloc(1, sizeof(xXIHierarchyEvent) +
+ MAXDEVICES * sizeof(xXIHierarchyInfo));
+ ev->type = GenericEvent;
+ ev->extension = IReqCode;
+ ev->evtype = XI_HierarchyChanged;
+ ev->time = GetTimeInMillis();
+ ev->flags = 0;
+ ev->num_info = inputInfo.numDevices;
+
+ info = (xXIHierarchyInfo*)&ev[1];
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ info->deviceid = dev->id;
+ info->enabled = dev->enabled;
+ info->use = GetDeviceUse(dev, &info->attachment);
+ info->flags = flags[dev->id];
+ ev->flags |= info->flags;
+ info++;
+ }
+ for (dev = inputInfo.off_devices; dev; dev = dev->next)
+ {
+ info->deviceid = dev->id;
+ info->enabled = dev->enabled;
+ info->use = GetDeviceUse(dev, &info->attachment);
+ info->flags = flags[dev->id];
+ ev->flags |= info->flags;
+ info++;
+ }
+
+
+ for (i = 0; i < MAXDEVICES; i++)
+ {
+ if (flags[i] & (XIMasterRemoved | XISlaveRemoved))
+ {
+ info->deviceid = i;
+ info->enabled = FALSE;
+ info->flags = flags[i];
+ info->use = 0;
+ ev->flags |= info->flags;
+ ev->num_info++;
+ info++;
+ }
+ }
+
+ ev->length = bytes_to_int32(ev->num_info * sizeof(xXIHierarchyInfo));
+
+ dummyDev.id = XIAllDevices;
+ SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1);
+ xfree(ev);
+}
+
+
+/***********************************************************************
+ *
+ * This procedure allows a client to change the device hierarchy through
+ * adding new master devices, removing them, etc.
+ *
+ */
+
+int SProcXIChangeHierarchy(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIChangeHierarchyReq);
+ swaps(&stuff->length, n);
+ return (ProcXIChangeHierarchy(client));
+}
+
+#define SWAPIF(cmd) if (client->swapped) { cmd; }
+
+int
+ProcXIChangeHierarchy(ClientPtr client)
+{
+ DeviceIntPtr ptr, keybd, XTestptr, XTestkeybd;
+ xXIAnyHierarchyChangeInfo *any;
+ int required_len = sizeof(xXIChangeHierarchyReq);
+ char n;
+ int rc = Success;
+ int flags[MAXDEVICES] = {0};
+
+ REQUEST(xXIChangeHierarchyReq);
+ REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
+
+ if (!stuff->num_changes)
+ return rc;
+
+ any = (xXIAnyHierarchyChangeInfo*)&stuff[1];
+ while(stuff->num_changes--)
+ {
+ SWAPIF(swapl(&any->type, n));
+ SWAPIF(swaps(&any->length, n));
+
+ required_len += any->length;
+ if ((stuff->length * 4) < required_len)
+ return BadLength;
+
+ switch(any->type)
+ {
+ case XIAddMaster:
+ {
+ xXIAddMasterInfo* c = (xXIAddMasterInfo*)any;
+ char* name;
+
+ SWAPIF(swaps(&c->name_len, n));
+ name = xcalloc(c->name_len + 1, sizeof(char));
+ strncpy(name, (char*)&c[1], c->name_len);
+
+
+ rc = AllocDevicePair(client, name, &ptr, &keybd,
+ CorePointerProc, CoreKeyboardProc,
+ TRUE);
+ if (rc != Success)
+ {
+ xfree(name);
+ goto unwind;
+ }
+
+ if (!c->send_core)
+ ptr->coreEvents = keybd->coreEvents = FALSE;
+
+ /* Allocate virtual slave devices for xtest events */
+ rc = AllocXTestDevice(client, name, &XTestptr, &XTestkeybd,
+ ptr, keybd);
+ if (rc != Success)
+ {
+
+ xfree(name);
+ goto unwind;
+ }
+
+ ActivateDevice(ptr, FALSE);
+ ActivateDevice(keybd, FALSE);
+ flags[ptr->id] |= XIMasterAdded;
+ flags[keybd->id] |= XIMasterAdded;
+
+ ActivateDevice(XTestptr, FALSE);
+ ActivateDevice(XTestkeybd, FALSE);
+ flags[XTestptr->id] |= XISlaveAdded;
+ flags[XTestkeybd->id] |= XISlaveAdded;
+
+ if (c->enable)
+ {
+ EnableDevice(ptr, FALSE);
+ EnableDevice(keybd, FALSE);
+ flags[ptr->id] |= XIDeviceEnabled;
+ flags[keybd->id] |= XIDeviceEnabled;
+
+ EnableDevice(XTestptr, FALSE);
+ EnableDevice(XTestkeybd, FALSE);
+ flags[XTestptr->id] |= XIDeviceEnabled;
+ flags[XTestkeybd->id] |= XIDeviceEnabled;
+ }
+
+ /* Attach the XTest virtual devices to the newly
+ created master device */
+ AttachDevice(NULL, XTestptr, ptr);
+ AttachDevice(NULL, XTestkeybd, keybd);
+ flags[XTestptr->id] |= XISlaveAttached;
+ flags[XTestkeybd->id] |= XISlaveAttached;
+
+ xfree(name);
+ }
+ break;
+ case XIRemoveMaster:
+ {
+ xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any;
+
+ if (r->return_mode != XIAttachToMaster &&
+ r->return_mode != XIFloating)
+ return BadValue;
+
+ rc = dixLookupDevice(&ptr, r->deviceid, client,
+ DixDestroyAccess);
+ if (rc != Success)
+ goto unwind;
+
+ if (!IsMaster(ptr))
+ {
+ client->errorValue = r->deviceid;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ /* XXX: For now, don't allow removal of VCP, VCK */
+ if (ptr == inputInfo.pointer ||
+ ptr == inputInfo.keyboard)
+ {
+ rc = BadDevice;
+ goto unwind;
+ }
+
+
+ ptr = GetMaster(ptr, MASTER_POINTER);
+ rc = dixLookupDevice(&ptr,
+ ptr->id,
+ client,
+ DixDestroyAccess);
+ if (rc != Success)
+ goto unwind;
+ keybd = GetMaster(ptr, MASTER_KEYBOARD);
+ rc = dixLookupDevice(&keybd,
+ keybd->id,
+ client,
+ DixDestroyAccess);
+ if (rc != Success)
+ goto unwind;
+
+ XTestptr = GetXTestDevice(ptr);
+ rc = dixLookupDevice(&XTestptr, XTestptr->id, client,
+ DixDestroyAccess);
+ if (rc != Success)
+ goto unwind;
+
+ XTestkeybd = GetXTestDevice(keybd);
+ rc = dixLookupDevice(&XTestkeybd, XTestkeybd->id, client,
+ DixDestroyAccess);
+ if (rc != Success)
+ goto unwind;
+
+ /* Disabling sends the devices floating, reattach them if
+ * desired. */
+ if (r->return_mode == XIAttachToMaster)
+ {
+ DeviceIntPtr attached,
+ newptr,
+ newkeybd;
+
+ rc = dixLookupDevice(&newptr, r->return_pointer,
+ client, DixAddAccess);
+ if (rc != Success)
+ goto unwind;
+
+ if (!IsMaster(newptr))
+ {
+ client->errorValue = r->return_pointer;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ rc = dixLookupDevice(&newkeybd, r->return_keyboard,
+ client, DixAddAccess);
+ if (rc != Success)
+ goto unwind;
+
+ if (!IsMaster(newkeybd))
+ {
+ client->errorValue = r->return_keyboard;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ for (attached = inputInfo.devices;
+ attached;
+ attached = attached->next)
+ {
+ if (!IsMaster(attached)) {
+ if (attached->u.master == ptr)
+ {
+ AttachDevice(client, attached, newptr);
+ flags[attached->id] |= XISlaveAttached;
+ }
+ if (attached->u.master == keybd)
+ {
+ AttachDevice(client, attached, newkeybd);
+ flags[attached->id] |= XISlaveAttached;
+ }
+ }
+ }
+ }
+
+ /* can't disable until we removed pairing */
+ keybd->spriteInfo->paired = NULL;
+ ptr->spriteInfo->paired = NULL;
+ XTestptr->spriteInfo->paired = NULL;
+ XTestkeybd->spriteInfo->paired = NULL;
+
+ /* disable the remove the devices, XTest devices must be done first
+ else the sprites they rely on will be destroyed */
+ DisableDevice(XTestptr, FALSE);
+ DisableDevice(XTestkeybd, FALSE);
+ DisableDevice(keybd, FALSE);
+ DisableDevice(ptr, FALSE);
+ flags[XTestptr->id] |= XIDeviceDisabled | XISlaveDetached;
+ flags[XTestkeybd->id] |= XIDeviceDisabled | XISlaveDetached;
+ flags[keybd->id] |= XIDeviceDisabled;
+ flags[ptr->id] |= XIDeviceDisabled;
+
+ RemoveDevice(XTestptr, FALSE);
+ RemoveDevice(XTestkeybd, FALSE);
+ RemoveDevice(keybd, FALSE);
+ RemoveDevice(ptr, FALSE);
+ flags[XTestptr->id] |= XISlaveRemoved;
+ flags[XTestkeybd->id] |= XISlaveRemoved;
+ flags[keybd->id] |= XIMasterRemoved;
+ flags[ptr->id] |= XIMasterRemoved;
+ }
+ break;
+ case XIDetachSlave:
+ {
+ xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any;
+
+ rc = dixLookupDevice(&ptr, c->deviceid, client,
+ DixManageAccess);
+ if (rc != Success)
+ goto unwind;
+
+ if (IsMaster(ptr))
+ {
+ client->errorValue = c->deviceid;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ /* Don't allow changes to XTest Devices, these are fixed */
+ if (IsXTestDevice(ptr, NULL))
+ {
+ client->errorValue = c->deviceid;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ AttachDevice(client, ptr, NULL);
+ flags[ptr->id] |= XISlaveDetached;
+ }
+ break;
+ case XIAttachSlave:
+ {
+ xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any;
+ DeviceIntPtr newmaster;
+
+ rc = dixLookupDevice(&ptr, c->deviceid, client,
+ DixManageAccess);
+ if (rc != Success)
+ goto unwind;
+
+ if (IsMaster(ptr))
+ {
+ client->errorValue = c->deviceid;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ /* Don't allow changes to XTest Devices, these are fixed */
+ if (IsXTestDevice(ptr, NULL))
+ {
+ client->errorValue = c->deviceid;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ rc = dixLookupDevice(&newmaster, c->new_master,
+ client, DixAddAccess);
+ if (rc != Success)
+ goto unwind;
+ if (!IsMaster(newmaster))
+ {
+ client->errorValue = c->new_master;
+ rc = BadDevice;
+ goto unwind;
+ }
+
+ if (!((IsPointerDevice(newmaster) &&
+ IsPointerDevice(ptr)) ||
+ (IsKeyboardDevice(newmaster) &&
+ IsKeyboardDevice(ptr))))
+ {
+ rc = BadDevice;
+ goto unwind;
+ }
+ AttachDevice(client, ptr, newmaster);
+ flags[ptr->id] |= XISlaveAttached;
+ }
+ break;
+ }
+
+ any = (xXIAnyHierarchyChangeInfo*)((char*)any + any->length * 4);
+ }
+
+unwind:
+
+ XISendDeviceHierarchyEvent(flags);
+ return rc;
+}
+
diff --git a/xorg-server/Xi/xichangehierarchy.h b/xorg-server/Xi/xichangehierarchy.h
new file mode 100644
index 000000000..483c6cd72
--- /dev/null
+++ b/xorg-server/Xi/xichangehierarchy.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+/***********************************************************************
+ *
+ * Request change in the device hierarchy.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHDEVHIER_H
+#define CHDEVHIER_H 1
+
+int SProcXIChangeHierarchy(ClientPtr /* client */);
+int ProcXIChangeHierarchy(ClientPtr /* client */);
+
+void XISendDeviceHierarchyEvent(int flags[]);
+
+#endif /* CHDEVHIER_H */
diff --git a/xorg-server/Xi/xigetclientpointer.c b/xorg-server/Xi/xigetclientpointer.c
new file mode 100644
index 000000000..401e89fb4
--- /dev/null
+++ b/xorg-server/Xi/xigetclientpointer.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include "scrnintstr.h" /* screen structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2proto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "xigetclientpointer.h"
+
+/***********************************************************************
+ * This procedure allows a client to query another client's client pointer
+ * setting.
+ */
+
+int
+SProcXIGetClientPointer(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIGetClientPointerReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->win, n);
+ return ProcXIGetClientPointer(client);
+}
+
+int ProcXIGetClientPointer(ClientPtr client)
+{
+ int rc;
+ ClientPtr winclient;
+ xXIGetClientPointerReply rep;
+ REQUEST(xXIGetClientPointerReq);
+ REQUEST_SIZE_MATCH(xXIGetClientPointerReq);
+
+ if (stuff->win != None)
+ {
+ rc = dixLookupClient(&winclient, stuff->win, client,
+ DixGetAttrAccess);
+
+ if (rc != Success)
+ return BadWindow;
+ } else
+ winclient = client;
+
+ rep.repType = X_Reply;
+ rep.RepType = X_XIGetClientPointer;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.set = (winclient->clientPtr != NULL);
+ rep.deviceid = (winclient->clientPtr) ? winclient->clientPtr->id : 0;
+
+ WriteReplyToClient(client, sizeof(xXIGetClientPointerReply), &rep);
+ return Success;
+}
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetClientPointer function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXIGetClientPointer(ClientPtr client, int size,
+ xXIGetClientPointerReply* rep)
+{
+ char n;
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swaps(&rep->deviceid, n);
+ WriteToClient(client, size, (char *)rep);
+}
+
diff --git a/xorg-server/Xi/xigetclientpointer.h b/xorg-server/Xi/xigetclientpointer.h
new file mode 100644
index 000000000..1539aa8a9
--- /dev/null
+++ b/xorg-server/Xi/xigetclientpointer.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETCPTR_H
+#define GETCPTR_H 1
+int SProcXIGetClientPointer(ClientPtr /* client */);
+int ProcXIGetClientPointer(ClientPtr /* client */);
+void SRepXIGetClientPointer(ClientPtr /* client */,
+ int /* size */,
+ xXIGetClientPointerReply* /* rep */);
+
+#endif /* GETCPTR_H */
diff --git a/xorg-server/Xi/xigrabdev.c b/xorg-server/Xi/xigrabdev.c
new file mode 100644
index 000000000..24ededcb1
--- /dev/null
+++ b/xorg-server/Xi/xigrabdev.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+/***********************************************************************
+ *
+ * Request to grab or ungrab input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h" /* BadDevice */
+#include "exevents.h"
+#include "xigrabdev.h"
+
+int
+SProcXIGrabDevice(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIGrabDeviceReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->grab_window, n);
+ swapl(&stuff->cursor, n);
+ swapl(&stuff->time, n);
+ swaps(&stuff->mask_len, n);
+
+ return ProcXIGrabDevice(client);
+}
+
+int
+ProcXIGrabDevice(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xXIGrabDeviceReply rep;
+ int ret = Success;
+ uint8_t status;
+ GrabMask mask;
+ int mask_len;
+
+ REQUEST(xXIGrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
+
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+ if (ret != Success)
+ return ret;
+
+ if (!IsMaster(dev))
+ stuff->paired_device_mode = GrabModeAsync;
+
+ if (XICheckInvalidMaskBits((unsigned char*)&stuff[1],
+ stuff->mask_len * 4) != Success)
+ return BadValue;
+
+ mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
+ memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
+ memcpy(mask.xi2mask, (char*)&stuff[1], mask_len);
+
+ ret = GrabDevice(client, dev, stuff->grab_mode,
+ stuff->paired_device_mode,
+ stuff->grab_window,
+ stuff->owner_events,
+ stuff->time,
+ &mask,
+ GRABTYPE_XI2,
+ stuff->cursor,
+ None /* confineTo */,
+ &status);
+
+ if (ret != Success)
+ return ret;
+
+ rep.repType = X_Reply;
+ rep.RepType = X_XIGrabDevice;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.status = status;
+
+
+ WriteReplyToClient(client, sizeof(rep), &rep);
+ return ret;
+}
+
+int
+SProcXIUngrabDevice(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIUngrabDeviceReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->time, n);
+
+ return ProcXIUngrabDevice(client);
+}
+
+int
+ProcXIUngrabDevice(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ GrabPtr grab;
+ int ret = Success;
+ TimeStamp time;
+
+ REQUEST(xXIUngrabDeviceReq);
+
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
+ if (ret != Success)
+ return ret;
+
+ grab = dev->deviceGrab.grab;
+
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, dev->deviceGrab.grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_XI2)
+ (*dev->deviceGrab.DeactivateGrab) (dev);
+
+ return Success;
+}
+
+void SRepXIGrabDevice(ClientPtr client, int size, xXIGrabDeviceReply * rep)
+{
+ char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ WriteToClient(client, size, (char *)rep);
+}
diff --git a/xorg-server/Xi/xigrabdev.h b/xorg-server/Xi/xigrabdev.h
new file mode 100644
index 000000000..08309c932
--- /dev/null
+++ b/xorg-server/Xi/xigrabdev.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef XIGRABDEV_H
+#define XIGRABDEV_H 1
+
+int ProcXIGrabDevice(ClientPtr client);
+int SProcXIGrabDevice(ClientPtr client);
+
+int ProcXIUngrabDevice(ClientPtr client);
+int SProcXIUngrabDevice(ClientPtr client);
+
+void SRepXIGrabDevice(ClientPtr client, int size, xXIGrabDeviceReply * rep);
+
+#endif /* XIGRABDEV_H */
diff --git a/xorg-server/Xi/xipassivegrab.c b/xorg-server/Xi/xipassivegrab.c
new file mode 100644
index 000000000..41a56b14e
--- /dev/null
+++ b/xorg-server/Xi/xipassivegrab.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+/***********************************************************************
+ *
+ * Request to grab or ungrab input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+#include "swaprep.h"
+
+#include "exglobals.h" /* BadDevice */
+#include "exevents.h"
+#include "xipassivegrab.h"
+#include "dixgrabs.h"
+
+int
+SProcXIPassiveGrabDevice(ClientPtr client)
+{
+ int i;
+ char n;
+ xXIModifierInfo *mods;
+
+ REQUEST(xXIPassiveGrabDeviceReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->grab_window, n);
+ swapl(&stuff->cursor, n);
+ swapl(&stuff->time, n);
+ swapl(&stuff->detail, n);
+ swaps(&stuff->mask_len, n);
+ swaps(&stuff->num_modifiers, n);
+
+ mods = (xXIModifierInfo*)&stuff[1];
+
+ for (i = 0; i < stuff->num_modifiers; i++, mods++)
+ {
+ swapl(&mods->base_mods, n);
+ swapl(&mods->latched_mods, n);
+ swapl(&mods->locked_mods, n);
+ }
+
+ return ProcXIPassiveGrabDevice(client);
+}
+
+int
+ProcXIPassiveGrabDevice(ClientPtr client)
+{
+ DeviceIntPtr dev, mod_dev;
+ xXIPassiveGrabDeviceReply rep;
+ int i, ret = Success;
+ uint8_t status;
+ uint32_t *modifiers;
+ xXIGrabModifierInfo *modifiers_failed;
+ GrabMask mask;
+ GrabParameters param;
+ void *tmp;
+ int mask_len;
+
+ REQUEST(xXIPassiveGrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
+
+ if (stuff->deviceid == XIAllDevices)
+ dev = inputInfo.all_devices;
+ else if (stuff->deviceid == XIAllMasterDevices)
+ dev = inputInfo.all_master_devices;
+ else
+ {
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+ if (ret != Success)
+ return ret;
+ }
+
+ if (stuff->grab_type != XIGrabtypeButton &&
+ stuff->grab_type != XIGrabtypeKeycode &&
+ stuff->grab_type != XIGrabtypeEnter &&
+ stuff->grab_type != XIGrabtypeFocusIn)
+ {
+ client->errorValue = stuff->grab_type;
+ return BadValue;
+ }
+
+ if ((stuff->grab_type == XIGrabtypeEnter ||
+ stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
+ {
+ client->errorValue = stuff->detail;
+ return BadValue;
+ }
+
+ if (XICheckInvalidMaskBits((unsigned char*)&stuff[1],
+ stuff->mask_len * 4) != Success)
+ return BadValue;
+
+ mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
+ memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
+ memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_XIPassiveGrabDevice;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.num_modifiers = 0;
+
+ memset(&param, 0, sizeof(param));
+ param.grabtype = GRABTYPE_XI2;
+ param.ownerEvents = stuff->owner_events;
+ param.this_device_mode = stuff->grab_mode;
+ param.other_devices_mode = stuff->paired_device_mode;
+ param.grabWindow = stuff->grab_window;
+ param.cursor = stuff->cursor;
+
+ if (stuff->cursor != None)
+ {
+ status = dixLookupResourceByType(&tmp, stuff->cursor,
+ RT_CURSOR, client, DixUseAccess);
+ if (status != Success)
+ {
+ client->errorValue = stuff->cursor;
+ return (status == BadValue) ? BadCursor : status;
+ }
+ }
+
+ status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess);
+ if (status != Success)
+ return status;
+
+ status = CheckGrabValues(client, &param);
+
+ modifiers = (uint32_t*)&stuff[1] + stuff->mask_len;
+ modifiers_failed = xcalloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
+ if (!modifiers_failed)
+ return BadAlloc;
+
+ if (!IsMaster(dev) && dev->u.master)
+ mod_dev = GetMaster(dev, MASTER_KEYBOARD);
+ else
+ mod_dev = dev;
+
+ for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+ {
+ param.modifiers = *modifiers;
+ switch(stuff->grab_type)
+ {
+ case XIGrabtypeButton:
+ status = GrabButton(client, dev, mod_dev, stuff->detail,
+ &param, GRABTYPE_XI2, &mask);
+ break;
+ case XIGrabtypeKeycode:
+ status = GrabKey(client, dev, mod_dev, stuff->detail,
+ &param, GRABTYPE_XI2, &mask);
+ break;
+ case XIGrabtypeEnter:
+ case XIGrabtypeFocusIn:
+ status = GrabWindow(client, dev, stuff->grab_type,
+ &param, &mask);
+ break;
+ }
+
+ if (status != GrabSuccess)
+ {
+ xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
+
+ info->status = status;
+ info->modifiers = *modifiers;
+ rep.num_modifiers++;
+ rep.length++;
+ }
+ }
+
+ WriteReplyToClient(client, sizeof(rep), &rep);
+ if (rep.num_modifiers)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, rep.num_modifiers * 4, (char*)modifiers_failed);
+ }
+ xfree(modifiers_failed);
+ return ret;
+}
+
+void
+SRepXIPassiveGrabDevice(ClientPtr client, int size,
+ xXIPassiveGrabDeviceReply * rep)
+{
+ char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swaps(&rep->num_modifiers, n);
+
+ WriteToClient(client, size, (char *)rep);
+}
+
+int
+SProcXIPassiveUngrabDevice(ClientPtr client)
+{
+ char n;
+ int i;
+ uint32_t *modifiers;
+
+ REQUEST(xXIPassiveUngrabDeviceReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->grab_window, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->detail, n);
+ swaps(&stuff->num_modifiers, n);
+
+ modifiers = (uint32_t*)&stuff[1];
+
+ for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+ swapl(modifiers, n);
+
+ return ProcXIPassiveUngrabDevice(client);
+}
+
+int
+ProcXIPassiveUngrabDevice(ClientPtr client)
+{
+ DeviceIntPtr dev, mod_dev;
+ WindowPtr win;
+ GrabRec tempGrab;
+ uint32_t* modifiers;
+ int i, rc;
+
+ REQUEST(xXIPassiveUngrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
+
+ rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->grab_type != XIGrabtypeButton &&
+ stuff->grab_type != XIGrabtypeKeycode &&
+ stuff->grab_type != XIGrabtypeEnter &&
+ stuff->grab_type != XIGrabtypeFocusIn)
+ {
+ client->errorValue = stuff->grab_type;
+ return BadValue;
+ }
+
+ if ((stuff->grab_type == XIGrabtypeEnter ||
+ stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
+ {
+ client->errorValue = stuff->detail;
+ return BadValue;
+ }
+
+ rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!IsMaster(dev) && dev->u.master)
+ mod_dev = GetMaster(dev, MASTER_KEYBOARD);
+ else
+ mod_dev = dev;
+
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = dev;
+ tempGrab.window = win;
+ switch(stuff->grab_type)
+ {
+ case XIGrabtypeButton: tempGrab.type = XI_ButtonPress; break;
+ case XIGrabtypeKeycode: tempGrab.type = XI_KeyPress; break;
+ case XIGrabtypeEnter: tempGrab.type = XI_Enter; break;
+ case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn; break;
+ }
+ tempGrab.grabtype = GRABTYPE_XI2;
+ tempGrab.modifierDevice = mod_dev;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.detail.exact = stuff->detail;
+ tempGrab.detail.pMask = NULL;
+
+ modifiers = (uint32_t*)&stuff[1];
+
+ for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+ {
+ tempGrab.modifiersDetail.exact = *modifiers;
+ DeletePassiveGrabFromList(&tempGrab);
+ }
+
+ return Success;
+}
diff --git a/xorg-server/Xi/xipassivegrab.h b/xorg-server/Xi/xipassivegrab.h
new file mode 100644
index 000000000..079e7c61b
--- /dev/null
+++ b/xorg-server/Xi/xipassivegrab.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef XIPASSIVEGRAB_H
+#define XIPASSIVEGRAB_H 1
+
+int SProcXIPassiveUngrabDevice(ClientPtr client);
+int ProcXIPassiveUngrabDevice(ClientPtr client);
+void SRepXIPassiveGrabDevice(ClientPtr client, int size, xXIPassiveGrabDeviceReply * rep);
+int ProcXIPassiveGrabDevice(ClientPtr client);
+int SProcXIPassiveGrabDevice(ClientPtr client);
+
+#endif /* XIPASSIVEGRAB_H */
diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c
index b04ee9433..024dc444b 100644
--- a/xorg-server/Xi/xiproperty.c
+++ b/xorg-server/Xi/xiproperty.c
@@ -34,6 +34,7 @@
#include <X11/extensions/XI.h>
#include <X11/Xatom.h>
#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
#include "exglobals.h"
#include "exevents.h"
#include "swaprep.h"
@@ -50,18 +51,323 @@ static struct dev_properties
char *name;
} dev_properties[] = {
{0, XI_PROP_ENABLED},
- {0, XATOM_FLOAT}
+ {0, XI_PROP_XTEST_DEVICE},
+ {0, XATOM_FLOAT},
+ {0, ACCEL_PROP_PROFILE_NUMBER},
+ {0, ACCEL_PROP_CONSTANT_DECELERATION},
+ {0, ACCEL_PROP_ADAPTIVE_DECELERATION},
+ {0, ACCEL_PROP_VELOCITY_SCALING},
+ {0, AXIS_LABEL_PROP},
+ {0, AXIS_LABEL_PROP_REL_X},
+ {0, AXIS_LABEL_PROP_REL_Y},
+ {0, AXIS_LABEL_PROP_REL_Z},
+ {0, AXIS_LABEL_PROP_REL_RX},
+ {0, AXIS_LABEL_PROP_REL_RY},
+ {0, AXIS_LABEL_PROP_REL_RZ},
+ {0, AXIS_LABEL_PROP_REL_HWHEEL},
+ {0, AXIS_LABEL_PROP_REL_DIAL},
+ {0, AXIS_LABEL_PROP_REL_WHEEL},
+ {0, AXIS_LABEL_PROP_REL_MISC},
+ {0, AXIS_LABEL_PROP_ABS_X},
+ {0, AXIS_LABEL_PROP_ABS_Y},
+ {0, AXIS_LABEL_PROP_ABS_Z},
+ {0, AXIS_LABEL_PROP_ABS_RX},
+ {0, AXIS_LABEL_PROP_ABS_RY},
+ {0, AXIS_LABEL_PROP_ABS_RZ},
+ {0, AXIS_LABEL_PROP_ABS_THROTTLE},
+ {0, AXIS_LABEL_PROP_ABS_RUDDER},
+ {0, AXIS_LABEL_PROP_ABS_WHEEL},
+ {0, AXIS_LABEL_PROP_ABS_GAS},
+ {0, AXIS_LABEL_PROP_ABS_BRAKE},
+ {0, AXIS_LABEL_PROP_ABS_HAT0X},
+ {0, AXIS_LABEL_PROP_ABS_HAT0Y},
+ {0, AXIS_LABEL_PROP_ABS_HAT1X},
+ {0, AXIS_LABEL_PROP_ABS_HAT1Y},
+ {0, AXIS_LABEL_PROP_ABS_HAT2X},
+ {0, AXIS_LABEL_PROP_ABS_HAT2Y},
+ {0, AXIS_LABEL_PROP_ABS_HAT3X},
+ {0, AXIS_LABEL_PROP_ABS_HAT3Y},
+ {0, AXIS_LABEL_PROP_ABS_PRESSURE},
+ {0, AXIS_LABEL_PROP_ABS_DISTANCE},
+ {0, AXIS_LABEL_PROP_ABS_TILT_X},
+ {0, AXIS_LABEL_PROP_ABS_TILT_Y},
+ {0, AXIS_LABEL_PROP_ABS_TOOL_WIDTH},
+ {0, AXIS_LABEL_PROP_ABS_VOLUME},
+ {0, AXIS_LABEL_PROP_ABS_MISC},
+
+ {0, BTN_LABEL_PROP},
+ {0, BTN_LABEL_PROP_BTN_UNKNOWN},
+ {0, BTN_LABEL_PROP_BTN_WHEEL_UP},
+ {0, BTN_LABEL_PROP_BTN_WHEEL_DOWN},
+ {0, BTN_LABEL_PROP_BTN_HWHEEL_LEFT},
+ {0, BTN_LABEL_PROP_BTN_HWHEEL_RIGHT},
+ {0, BTN_LABEL_PROP_BTN_0},
+ {0, BTN_LABEL_PROP_BTN_1},
+ {0, BTN_LABEL_PROP_BTN_2},
+ {0, BTN_LABEL_PROP_BTN_3},
+ {0, BTN_LABEL_PROP_BTN_4},
+ {0, BTN_LABEL_PROP_BTN_5},
+ {0, BTN_LABEL_PROP_BTN_6},
+ {0, BTN_LABEL_PROP_BTN_7},
+ {0, BTN_LABEL_PROP_BTN_8},
+ {0, BTN_LABEL_PROP_BTN_9},
+
+ {0, BTN_LABEL_PROP_BTN_LEFT},
+ {0, BTN_LABEL_PROP_BTN_RIGHT},
+ {0, BTN_LABEL_PROP_BTN_MIDDLE},
+ {0, BTN_LABEL_PROP_BTN_SIDE},
+ {0, BTN_LABEL_PROP_BTN_EXTRA},
+ {0, BTN_LABEL_PROP_BTN_FORWARD},
+ {0, BTN_LABEL_PROP_BTN_BACK},
+ {0, BTN_LABEL_PROP_BTN_TASK},
+
+ {0, BTN_LABEL_PROP_BTN_TRIGGER},
+ {0, BTN_LABEL_PROP_BTN_THUMB},
+ {0, BTN_LABEL_PROP_BTN_THUMB2},
+ {0, BTN_LABEL_PROP_BTN_TOP},
+ {0, BTN_LABEL_PROP_BTN_TOP2},
+ {0, BTN_LABEL_PROP_BTN_PINKIE},
+ {0, BTN_LABEL_PROP_BTN_BASE},
+ {0, BTN_LABEL_PROP_BTN_BASE2},
+ {0, BTN_LABEL_PROP_BTN_BASE3},
+ {0, BTN_LABEL_PROP_BTN_BASE4},
+ {0, BTN_LABEL_PROP_BTN_BASE5},
+ {0, BTN_LABEL_PROP_BTN_BASE6},
+ {0, BTN_LABEL_PROP_BTN_DEAD},
+
+ {0, BTN_LABEL_PROP_BTN_A},
+ {0, BTN_LABEL_PROP_BTN_B},
+ {0, BTN_LABEL_PROP_BTN_C},
+ {0, BTN_LABEL_PROP_BTN_X},
+ {0, BTN_LABEL_PROP_BTN_Y},
+ {0, BTN_LABEL_PROP_BTN_Z},
+ {0, BTN_LABEL_PROP_BTN_TL},
+ {0, BTN_LABEL_PROP_BTN_TR},
+ {0, BTN_LABEL_PROP_BTN_TL2},
+ {0, BTN_LABEL_PROP_BTN_TR2},
+ {0, BTN_LABEL_PROP_BTN_SELECT},
+ {0, BTN_LABEL_PROP_BTN_START},
+ {0, BTN_LABEL_PROP_BTN_MODE},
+ {0, BTN_LABEL_PROP_BTN_THUMBL},
+ {0, BTN_LABEL_PROP_BTN_THUMBR},
+
+ {0, BTN_LABEL_PROP_BTN_TOOL_PEN},
+ {0, BTN_LABEL_PROP_BTN_TOOL_RUBBER},
+ {0, BTN_LABEL_PROP_BTN_TOOL_BRUSH},
+ {0, BTN_LABEL_PROP_BTN_TOOL_PENCIL},
+ {0, BTN_LABEL_PROP_BTN_TOOL_AIRBRUSH},
+ {0, BTN_LABEL_PROP_BTN_TOOL_FINGER},
+ {0, BTN_LABEL_PROP_BTN_TOOL_MOUSE},
+ {0, BTN_LABEL_PROP_BTN_TOOL_LENS},
+ {0, BTN_LABEL_PROP_BTN_TOUCH},
+ {0, BTN_LABEL_PROP_BTN_STYLUS},
+ {0, BTN_LABEL_PROP_BTN_STYLUS2},
+ {0, BTN_LABEL_PROP_BTN_TOOL_DOUBLETAP},
+ {0, BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP},
+
+ {0, BTN_LABEL_PROP_BTN_GEAR_DOWN},
+ {0, BTN_LABEL_PROP_BTN_GEAR_UP}
};
static long XIPropHandlerID = 1;
+static void send_property_event(DeviceIntPtr dev, Atom property, int what)
+{
+ devicePropertyNotify event;
+ xXIPropertyEvent xi2;
+ int state;
+
+ if (what == XIPropertyDeleted)
+ state = PropertyDelete;
+ else
+ state = PropertyNewValue;
+
+ event.type = DevicePropertyNotify;
+ event.deviceid = dev->id;
+ event.state = state;
+ event.atom = property;
+ event.time = currentTime.milliseconds;
+ SendEventToAllWindows(dev, DevicePropertyNotifyMask,
+ (xEvent*)&event, 1);
+
+ xi2.type = GenericEvent;
+ xi2.extension = IReqCode;
+ xi2.length = 0;
+ xi2.evtype = XI_PropertyEvent;
+ xi2.deviceid = dev->id;
+ xi2.time = currentTime.milliseconds;
+ xi2.property = property;
+ xi2.what = what;
+ SendEventToAllWindows(dev, GetEventFilter(dev, (xEvent*)&xi2),
+ (xEvent*)&xi2, 1);
+}
+
+static int list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return)
+{
+ XIPropertyPtr prop;
+ Atom *atoms = NULL;
+ int nprops = 0;
+
+ for (prop = dev->properties.properties; prop; prop = prop->next)
+ nprops++;
+ if (nprops)
+ {
+ Atom *a;
+
+ atoms = xalloc(nprops * sizeof(Atom));
+ if(!atoms)
+ return BadAlloc;
+ a = atoms;
+ for (prop = dev->properties.properties; prop; prop = prop->next, a++)
+ *a = prop->propertyName;
+ }
+
+ *natoms = nprops;
+ *atoms_return = atoms;
+ return Success;
+}
+
+static int
+get_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
+ BOOL delete, int offset, int length,
+ int *bytes_after, Atom *type_return, int *format, int *nitems,
+ int *length_return, char **data)
+{
+ unsigned long n, len, ind;
+ int rc;
+ XIPropertyPtr prop;
+ XIPropertyValuePtr prop_value;
+
+ if (!ValidAtom(property))
+ {
+ client->errorValue = property;
+ return(BadAtom);
+ }
+ if ((delete != xTrue) && (delete != xFalse))
+ {
+ client->errorValue = delete;
+ return(BadValue);
+ }
+
+ if ((type != AnyPropertyType) && !ValidAtom(type))
+ {
+ client->errorValue = type;
+ return(BadAtom);
+ }
+
+ for (prop = dev->properties.properties; prop; prop = prop->next)
+ if (prop->propertyName == property)
+ break;
+
+ if (!prop)
+ {
+ *bytes_after = 0;
+ *type_return = None;
+ *format = 0;
+ *nitems = 0;
+ *length_return = 0;
+ return Success;
+ }
+
+ rc = XIGetDeviceProperty(dev, property, &prop_value);
+ if (rc != Success)
+ {
+ client->errorValue = property;
+ return rc;
+ }
+
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((type != prop_value->type) && (type != AnyPropertyType)))
+ {
+ *bytes_after = prop_value->size;
+ *format = prop_value->format;
+ *length_return = 0;
+ *nitems = 0;
+ *type_return = prop_value->type;
+ return Success;
+ }
+
+ /* Return type, format, value to client */
+ n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */
+ ind = offset << 2;
+
+ /* If offset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ client->errorValue = offset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * length);
+
+ *bytes_after = n - (ind + len);
+ *format = prop_value->format;
+ *length_return = len;
+ if (prop_value->format)
+ *nitems = len / (prop_value->format / 8);
+ else
+ *nitems = 0;
+ *type_return = prop_value->type;
+
+ *data = (char*)prop_value->data + ind;
+
+ return Success;
+}
+
+static int
+check_change_property(ClientPtr client, Atom property, Atom type, int format,
+ int mode, int nitems)
+{
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend))
+ {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32))
+ {
+ client->errorValue = format;
+ return BadValue;
+ }
+
+ if (!ValidAtom(property))
+ {
+ client->errorValue = property;
+ return(BadAtom);
+ }
+ if (!ValidAtom(type))
+ {
+ client->errorValue = type;
+ return(BadAtom);
+ }
+
+ return Success;
+}
+
+static int
+change_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
+ int format, int mode, int len, void *data)
+{
+ int rc = Success;
+
+ rc = XIChangeDeviceProperty(dev, property, type, format, mode, len, data, TRUE);
+ if (rc != Success)
+ client->errorValue = property;
+
+ return rc;
+}
+
/**
- * Return the type assigned to the specified atom or 0 if the atom isn't known
+ * Return the atom assigned to the specified string or 0 if the atom isn't known
* to the DIX.
*
* If name is NULL, None is returned.
*/
-_X_EXPORT Atom
+Atom
XIGetKnownProperty(char *name)
{
int i;
@@ -71,8 +377,16 @@ XIGetKnownProperty(char *name)
for (i = 0; i < (sizeof(dev_properties)/sizeof(struct dev_properties)); i++)
{
- if (strcmp(name, dev_properties[i].name) == 0)
+ if (strcmp(name, dev_properties[i].name) == 0){
+ if (dev_properties[i].type == None){
+ dev_properties[i].type =
+ MakeAtom(dev_properties[i].name,
+ strlen(dev_properties[i].name),
+ TRUE);
+ }
+
return dev_properties[i].type;
+ }
}
return 0;
@@ -197,24 +511,6 @@ XIPropToFloat(XIPropertyValuePtr val, int *nelem_return, float **buf_return)
return Success;
}
-/**
- * Init those properties that are allocated by the server and most likely used
- * by the DIX or the DDX.
- */
-void
-XIInitKnownProperties(void)
-{
- int i;
- for (i = 0; i < (sizeof(dev_properties)/sizeof(struct dev_properties)); i++)
- {
- dev_properties[i].type =
- MakeAtom(dev_properties[i].name,
- strlen(dev_properties[i].name),
- TRUE);
- }
-}
-
-
/* Registers a new property handler on the given device and returns a unique
* identifier for this handler. This identifier is required to unregister the
* property handler again.
@@ -318,20 +614,11 @@ XIDeleteAllDeviceProperties (DeviceIntPtr device)
{
XIPropertyPtr prop, next;
XIPropertyHandlerPtr curr_handler, next_handler;
- devicePropertyNotify event;
for (prop = device->properties.properties; prop; prop = next)
{
next = prop->next;
-
- event.type = DevicePropertyNotify;
- event.deviceid = device->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(device, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
-
+ send_property_event(device, prop->propertyName, XIPropertyDeleted);
XIDestroyDeviceProperty(prop);
}
@@ -350,7 +637,6 @@ int
XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient)
{
XIPropertyPtr prop, *prev;
- devicePropertyNotify event;
int rc = Success;
for (prev = &device->properties.properties; (prop = *prev); prev = &(prop->next))
@@ -377,13 +663,7 @@ XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient)
if (prop)
{
*prev = prop->next;
- event.type = DevicePropertyNotify;
- event.deviceid = device->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(device, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
+ send_property_event(device, prop->propertyName, XIPropertyDeleted);
XIDestroyDeviceProperty (prop);
}
@@ -396,7 +676,6 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
pointer value, Bool sendevent)
{
XIPropertyPtr prop;
- devicePropertyNotify event;
int size_in_bytes;
int total_size;
unsigned long total_len;
@@ -515,15 +794,9 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
}
if (sendevent)
- {
- event.type = DevicePropertyNotify;
- event.deviceid = dev->id;
- event.state = PropertyNewValue;
- event.atom = prop->propertyName;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(dev, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
- }
+ send_property_event(dev, prop->propertyName,
+ (add) ? XIPropertyCreated : XIPropertyModified);
+
return(Success);
}
@@ -577,41 +850,35 @@ XISetDevicePropertyDeletable(DeviceIntPtr dev, Atom property, Bool deletable)
int
ProcXListDeviceProperties (ClientPtr client)
{
- Atom *pAtoms = NULL, *temppAtoms;
+ Atom *atoms;
xListDevicePropertiesReply rep;
- int numProps = 0;
+ int natoms;
DeviceIntPtr dev;
- XIPropertyPtr prop;
int rc = Success;
REQUEST(xListDevicePropertiesReq);
REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
- rc = dixLookupDevice (&dev, stuff->deviceid, client, DixReadAccess);
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixListPropAccess);
if (rc != Success)
return rc;
- for (prop = dev->properties.properties; prop; prop = prop->next)
- numProps++;
- if (numProps)
- if(!(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom))))
- return(BadAlloc);
+ rc = list_atoms(dev, &natoms, &atoms);
+ if (rc != Success)
+ return rc;
rep.repType = X_Reply;
rep.RepType = X_ListDeviceProperties;
- rep.length = (numProps * sizeof(Atom)) >> 2;
+ rep.length = natoms;
rep.sequenceNumber = client->sequence;
- rep.nAtoms = numProps;
- temppAtoms = pAtoms;
- for (prop = dev->properties.properties; prop; prop = prop->next)
- *temppAtoms++ = prop->propertyName;
+ rep.nAtoms = natoms;
WriteReplyToClient(client, sizeof(xListDevicePropertiesReply), &rep);
- if (numProps)
+ if (natoms)
{
client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
- WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
- xfree(pAtoms);
+ WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms);
+ xfree(atoms);
}
return rc;
}
@@ -621,55 +888,29 @@ ProcXChangeDeviceProperty (ClientPtr client)
{
REQUEST(xChangeDevicePropertyReq);
DeviceIntPtr dev;
- char format, mode;
unsigned long len;
- int sizeInBytes;
int totalSize;
int rc;
REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq);
UpdateCurrentTime();
- format = stuff->format;
- mode = stuff->mode;
- if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
- (mode != PropModePrepend))
- {
- client->errorValue = mode;
- return BadValue;
- }
- if ((format != 8) && (format != 16) && (format != 32))
- {
- client->errorValue = format;
- return BadValue;
- }
- len = stuff->nUnits;
- if (len > ((0xffffffff - sizeof(xChangeDevicePropertyReq)) >> 2))
- return BadLength;
- sizeInBytes = format>>3;
- totalSize = len * sizeInBytes;
- REQUEST_FIXED_SIZE(xChangeDevicePropertyReq, totalSize);
- rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess);
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixSetPropAccess);
if (rc != Success)
return rc;
- if (!ValidAtom(stuff->property))
- {
- client->errorValue = stuff->property;
- return(BadAtom);
- }
- if (!ValidAtom(stuff->type))
- {
- client->errorValue = stuff->type;
- return(BadAtom);
- }
+ rc = check_change_property(client, stuff->property, stuff->type,
+ stuff->format, stuff->mode, stuff->nUnits);
- rc = XIChangeDeviceProperty(dev, stuff->property,
- stuff->type, (int)format,
- (int)mode, len, (pointer)&stuff[1], TRUE);
+ len = stuff->nUnits;
+ if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq))))
+ return BadLength;
- if (rc != Success)
- client->errorValue = stuff->property;
+ totalSize = len * (stuff->format/8);
+ REQUEST_FIXED_SIZE(xChangeDevicePropertyReq, totalSize);
+
+ rc = change_property(client, dev, stuff->property, stuff->type,
+ stuff->format, stuff->mode, len, (void*)&stuff[1]);
return rc;
}
@@ -682,7 +923,7 @@ ProcXDeleteDeviceProperty (ClientPtr client)
REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
UpdateCurrentTime();
- rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess);
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixSetPropAccess);
if (rc != Success)
return rc;
@@ -700,137 +941,69 @@ int
ProcXGetDeviceProperty (ClientPtr client)
{
REQUEST(xGetDevicePropertyReq);
- XIPropertyPtr prop, *prev;
- XIPropertyValuePtr prop_value;
- unsigned long n, len, ind;
DeviceIntPtr dev;
+ int length;
+ int rc, format, nitems, bytes_after;
+ char *data;
+ Atom type;
xGetDevicePropertyReply reply;
- int rc;
REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
if (stuff->delete)
UpdateCurrentTime();
rc = dixLookupDevice (&dev, stuff->deviceid, client,
- stuff->delete ? DixWriteAccess :
- DixReadAccess);
+ stuff->delete ? DixSetPropAccess :
+ DixGetPropAccess);
if (rc != Success)
return rc;
- if (!ValidAtom(stuff->property))
- {
- client->errorValue = stuff->property;
- return(BadAtom);
- }
- if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
- {
- client->errorValue = stuff->delete;
- return(BadValue);
- }
- if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
- {
- client->errorValue = stuff->type;
- return(BadAtom);
- }
+ rc = get_property(client, dev, stuff->property, stuff->type,
+ stuff->delete, stuff->longOffset, stuff->longLength,
+ &bytes_after, &type, &format, &nitems, &length, &data);
- for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next)
- if (prop->propertyName == stuff->property)
- break;
+ if (rc != Success)
+ return rc;
reply.repType = X_Reply;
reply.RepType = X_GetDeviceProperty;
reply.sequenceNumber = client->sequence;
reply.deviceid = dev->id;
- if (!prop)
- {
- reply.nItems = 0;
- reply.length = 0;
- reply.bytesAfter = 0;
- reply.propertyType = None;
- reply.format = 0;
- WriteReplyToClient(client, sizeof(xGetDevicePropertyReply), &reply);
- return(client->noClientException);
- }
-
- rc = XIGetDeviceProperty(dev, stuff->property, &prop_value);
- if (rc != Success)
- {
- client->errorValue = stuff->property;
- return rc;
- }
-
- /* If the request type and actual type don't match. Return the
- property information, but not the data. */
-
- if (((stuff->type != prop_value->type) &&
- (stuff->type != AnyPropertyType))
- )
- {
- reply.bytesAfter = prop_value->size;
- reply.format = prop_value->format;
- reply.length = 0;
- reply.nItems = 0;
- reply.propertyType = prop_value->type;
- WriteReplyToClient(client, sizeof(xGetDevicePropertyReply), &reply);
- return(client->noClientException);
- }
-
-/*
- * Return type, format, value to client
- */
- n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */
- ind = stuff->longOffset << 2;
-
- /* If longOffset is invalid such that it causes "len" to
- be negative, it's a value error. */
-
- if (n < ind)
- {
- client->errorValue = stuff->longOffset;
- return BadValue;
- }
-
- len = min(n - ind, 4 * stuff->longLength);
-
- reply.bytesAfter = n - (ind + len);
- reply.format = prop_value->format;
- reply.length = (len + 3) >> 2;
- if (prop_value->format)
- reply.nItems = len / (prop_value->format / 8);
- else
- reply.nItems = 0;
- reply.propertyType = prop_value->type;
+ reply.nItems = nitems;
+ reply.format = format;
+ reply.bytesAfter = bytes_after;
+ reply.propertyType = type;
+ reply.length = bytes_to_int32(length);
if (stuff->delete && (reply.bytesAfter == 0))
- {
- devicePropertyNotify event;
-
- event.type = DevicePropertyNotify;
- event.deviceid = dev->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(dev, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
- }
+ send_property_event(dev, stuff->property, XIPropertyDeleted);
WriteReplyToClient(client, sizeof(xGenericReply), &reply);
- if (len)
+
+ if (length)
{
switch (reply.format) {
- case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
- case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
- default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
}
- WriteSwappedDataToClient(client, len,
- (char *)prop_value->data + ind);
+ WriteSwappedDataToClient(client, length, data);
}
+ /* delete the Property */
if (stuff->delete && (reply.bytesAfter == 0))
- { /* delete the Property */
- *prev = prop->next;
- XIDestroyDeviceProperty (prop);
+ {
+ XIPropertyPtr prop, *prev;
+ for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next)
+ {
+ if (prop->propertyName == stuff->property)
+ {
+ *prev = prop->next;
+ XIDestroyDeviceProperty(prop);
+ break;
+ }
+ }
}
- return(client->noClientException);
+ return Success;
}
@@ -916,3 +1089,248 @@ SRepXGetDeviceProperty(ClientPtr client, int size,
/* data will be swapped, see ProcXGetDeviceProperty */
WriteToClient(client, size, (char*)rep);
}
+
+/* XI2 Request/reply handling */
+int
+ProcXIListProperties(ClientPtr client)
+{
+ Atom *atoms;
+ xXIListPropertiesReply rep;
+ int natoms;
+ DeviceIntPtr dev;
+ int rc = Success;
+
+ REQUEST(xXIListPropertiesReq);
+ REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixListPropAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = list_atoms(dev, &natoms, &atoms);
+ if (rc != Success)
+ return rc;
+
+ rep.repType = X_Reply;
+ rep.RepType = X_XIListProperties;
+ rep.length = natoms;
+ rep.sequenceNumber = client->sequence;
+ rep.num_properties = natoms;
+
+ WriteReplyToClient(client, sizeof(xXIListPropertiesReply), &rep);
+ if (natoms)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms);
+ xfree(atoms);
+ }
+ return rc;
+}
+
+int
+ProcXIChangeProperty(ClientPtr client)
+{
+ int rc;
+ DeviceIntPtr dev;
+ int totalSize;
+ unsigned long len;
+
+ REQUEST(xXIChangePropertyReq);
+ REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq);
+ UpdateCurrentTime();
+
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixSetPropAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = check_change_property(client, stuff->property, stuff->type,
+ stuff->format, stuff->mode, stuff->num_items);
+ len = stuff->num_items;
+ if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq)))
+ return BadLength;
+
+ totalSize = len * (stuff->format/8);
+ REQUEST_FIXED_SIZE(xXIChangePropertyReq, totalSize);
+
+ rc = change_property(client, dev, stuff->property, stuff->type,
+ stuff->format, stuff->mode, len, (void*)&stuff[1]);
+ return rc;
+}
+
+int
+ProcXIDeleteProperty(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ int rc;
+ REQUEST(xXIDeletePropertyReq);
+
+ REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
+ UpdateCurrentTime();
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixSetPropAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+
+ rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE);
+ return rc;
+}
+
+
+int
+ProcXIGetProperty(ClientPtr client)
+{
+ REQUEST(xXIGetPropertyReq);
+ DeviceIntPtr dev;
+ xXIGetPropertyReply reply;
+ int length;
+ int rc, format, nitems, bytes_after;
+ char *data;
+ Atom type;
+
+ REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ rc = dixLookupDevice (&dev, stuff->deviceid, client,
+ stuff->delete ? DixSetPropAccess :
+ DixGetPropAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = get_property(client, dev, stuff->property, stuff->type,
+ stuff->delete, stuff->offset, stuff->len,
+ &bytes_after, &type, &format, &nitems, &length, &data);
+
+ if (rc != Success)
+ return rc;
+
+ reply.repType = X_Reply;
+ reply.RepType = X_XIGetProperty;
+ reply.sequenceNumber = client->sequence;
+ reply.num_items = nitems;
+ reply.format = format;
+ reply.bytes_after = bytes_after;
+ reply.type = type;
+ reply.length = bytes_to_int32(length);
+
+ if (length && stuff->delete && (reply.bytes_after == 0))
+ send_property_event(dev, stuff->property, XIPropertyDeleted);
+
+ WriteReplyToClient(client, sizeof(xXIGetPropertyReply), &reply);
+
+ if (length)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, length, data);
+ }
+
+ /* delete the Property */
+ if (stuff->delete && (reply.bytes_after == 0))
+ {
+ XIPropertyPtr prop, *prev;
+ for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next)
+ {
+ if (prop->propertyName == stuff->property)
+ {
+ *prev = prop->next;
+ XIDestroyDeviceProperty(prop);
+ break;
+ }
+ }
+ }
+
+ return Success;
+}
+
+int
+SProcXIListProperties(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIListPropertiesReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+
+ REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+ return (ProcXIListProperties(client));
+}
+
+int
+SProcXIChangeProperty(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIChangePropertyReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->num_items, n);
+ REQUEST_SIZE_MATCH(xXIChangePropertyReq);
+ return (ProcXIChangeProperty(client));
+}
+
+int
+SProcXIDeleteProperty(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIDeletePropertyReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->property, n);
+ REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
+ return (ProcXIDeleteProperty(client));
+}
+
+int
+SProcXIGetProperty(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIGetPropertyReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->offset, n);
+ swapl(&stuff->len, n);
+ REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+ return (ProcXIGetProperty(client));
+}
+
+
+void
+SRepXIListProperties(ClientPtr client, int size,
+ xXIListPropertiesReply *rep)
+{
+ char n;
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swaps(&rep->num_properties, n);
+ /* properties will be swapped later, see ProcXIListProperties */
+ WriteToClient(client, size, (char*)rep);
+}
+
+void
+SRepXIGetProperty(ClientPtr client, int size,
+ xXIGetPropertyReply *rep)
+{
+ char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->type, n);
+ swapl(&rep->bytes_after, n);
+ swapl(&rep->num_items, n);
+ /* data will be swapped, see ProcXIGetProperty */
+ WriteToClient(client, size, (char*)rep);
+}
diff --git a/xorg-server/Xi/xiproperty.h b/xorg-server/Xi/xiproperty.h
index 12026e9e8..69b41fafd 100644
--- a/xorg-server/Xi/xiproperty.h
+++ b/xorg-server/Xi/xiproperty.h
@@ -23,8 +23,12 @@
* Author: Peter Hutterer
*/
-#ifndef XIPROPERTY_C
-#define XIPROPERTY_C
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef XIPROPERTY_H
+#define XIPROPERTY_H 1
int ProcXListDeviceProperties (ClientPtr client);
int ProcXChangeDeviceProperty (ClientPtr client);
@@ -43,6 +47,19 @@ void SRepXListDeviceProperties(ClientPtr client, int size,
void SRepXGetDeviceProperty(ClientPtr client, int size,
xGetDevicePropertyReply *rep);
-void XIInitKnownProperties(void);
+/* XI2 request/reply handling */
+int ProcXIListProperties (ClientPtr client);
+int ProcXIChangeProperty (ClientPtr client);
+int ProcXIDeleteProperty (ClientPtr client);
+int ProcXIGetProperty (ClientPtr client);
+
+int SProcXIListProperties (ClientPtr client);
+int SProcXIChangeProperty (ClientPtr client);
+int SProcXIDeleteProperty (ClientPtr client);
+int SProcXIGetProperty (ClientPtr client);
-#endif /* XIPROPERTY_C */
+void SRepXIListProperties(ClientPtr client, int size,
+ xXIListPropertiesReply *rep);
+void SRepXIGetProperty(ClientPtr client, int size,
+ xXIGetPropertyReply *rep);
+#endif /* XIPROPERTY_H */
diff --git a/xorg-server/Xi/xiquerydevice.c b/xorg-server/Xi/xiquerydevice.c
new file mode 100644
index 000000000..68d91fa87
--- /dev/null
+++ b/xorg-server/Xi/xiquerydevice.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright © 2009 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
+ *
+ */
+
+/**
+ * @file Protocol handling for the XIQueryDevice request/reply.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/XI2proto.h>
+#include "xkbstr.h"
+#include "xkbsrv.h"
+#include "xserver-properties.h"
+#include "exevents.h"
+#include "xace.h"
+
+#include "xiquerydevice.h"
+
+static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d);
+static int ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
+static int SizeDeviceInfo(DeviceIntPtr dev);
+static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
+int
+SProcXIQueryDevice(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIQueryDeviceReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+
+ return ProcXIQueryDevice(client);
+}
+
+int
+ProcXIQueryDevice(ClientPtr client)
+{
+ xXIQueryDeviceReply rep;
+ DeviceIntPtr dev = NULL;
+ int rc = Success;
+ int i = 0, len = 0;
+ char *info, *ptr;
+ Bool *skip = NULL;
+
+ REQUEST(xXIQueryDeviceReq);
+ REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
+
+ if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices)
+ {
+ rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->deviceid;
+ return rc;
+ }
+ len += SizeDeviceInfo(dev);
+ }
+ else
+ {
+ skip = xcalloc(sizeof(Bool), inputInfo.numDevices);
+ if (!skip)
+ return BadAlloc;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next, i++)
+ {
+ skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
+ if (!skip[i])
+ len += SizeDeviceInfo(dev);
+ }
+
+ for (dev = inputInfo.off_devices; dev; dev = dev->next, i++)
+ {
+ skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
+ if (!skip[i])
+ len += SizeDeviceInfo(dev);
+ }
+ }
+
+ info = xcalloc(1, len);
+ if (!info)
+ return BadAlloc;
+
+ memset(&rep, 0, sizeof(xXIQueryDeviceReply));
+ rep.repType = X_Reply;
+ rep.RepType = X_XIQueryDevice;
+ rep.sequenceNumber = client->sequence;
+ rep.length = len/4;
+ rep.num_devices = 0;
+
+ ptr = info;
+ if (dev)
+ {
+ len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+ if (client->swapped)
+ SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
+ info += len;
+ rep.num_devices = 1;
+ } else
+ {
+ i = 0;
+ for (dev = inputInfo.devices; dev; dev = dev->next, i++)
+ {
+ if (!skip[i])
+ {
+ len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+ if (client->swapped)
+ SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
+ info += len;
+ rep.num_devices++;
+ }
+ }
+
+ for (dev = inputInfo.off_devices; dev; dev = dev->next, i++)
+ {
+ if (!skip[i])
+ {
+ len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+ if (client->swapped)
+ SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
+ info += len;
+ rep.num_devices++;
+ }
+ }
+ }
+
+ WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep);
+ WriteToClient(client, rep.length * 4, ptr);
+ xfree(ptr);
+ xfree(skip);
+ return rc;
+}
+
+void
+SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep)
+{
+ char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swaps(&rep->num_devices, n);
+
+ /* Device info is already swapped, see ProcXIQueryDevice */
+
+ WriteToClient(client, size, (char *)rep);
+}
+
+
+/**
+ * @return Whether the device should be included in the returned list.
+ */
+static Bool
+ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev)
+{
+ /* if all devices are not being queried, only master devices are */
+ if (deviceid == XIAllDevices || IsMaster(dev))
+ {
+ int rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess);
+ if (rc == Success)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * @return The number of bytes needed to store this device's xXIDeviceInfo
+ * (and its classes).
+ */
+static int
+SizeDeviceInfo(DeviceIntPtr dev)
+{
+ int len = sizeof(xXIDeviceInfo);
+
+ /* 4-padded name */
+ len += pad_to_int32(strlen(dev->name));
+
+ return len + SizeDeviceClasses(dev);
+
+}
+
+/*
+ * @return The number of bytes needed to store this device's classes.
+ */
+int
+SizeDeviceClasses(DeviceIntPtr dev)
+{
+ int len = 0;
+
+ if (dev->button)
+ {
+ len += sizeof(xXIButtonInfo);
+ len += dev->button->numButtons * sizeof(Atom);
+ len += pad_to_int32(bits_to_bytes(dev->button->numButtons));
+ }
+
+ if (dev->key)
+ {
+ XkbDescPtr xkb = dev->key->xkbInfo->desc;
+ len += sizeof(xXIKeyInfo);
+ len += (xkb->max_key_code - xkb->min_key_code + 1) * sizeof(uint32_t);
+ }
+
+ if (dev->valuator)
+ len += sizeof(xXIValuatorInfo) * dev->valuator->numAxes;
+
+ return len;
+}
+
+
+/**
+ * Write button information into info.
+ * @return Number of bytes written into info.
+ */
+int
+ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
+{
+ unsigned char *bits;
+ int mask_len;
+ int i;
+
+ mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons));
+
+ info->type = ButtonClass;
+ info->num_buttons = dev->button->numButtons;
+ info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
+ info->num_buttons + mask_len;
+ info->sourceid = dev->button->sourceid;
+
+ bits = (unsigned char*)&info[1];
+ memset(bits, 0, mask_len * 4);
+
+ for (i = 0; dev && dev->button && i < dev->button->numButtons; i++)
+ if (BitIsOn(dev->button->down, i))
+ SetBit(bits, i);
+ bits += mask_len * 4;
+ memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom));
+
+ return info->length * 4;
+}
+
+static void
+SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
+{
+ char n;
+ Atom *btn;
+ int i;
+ swaps(&info->type, n);
+ swaps(&info->length, n);
+ swaps(&info->sourceid, n);
+
+ for (i = 0, btn = (Atom*)&info[1]; i < info->num_buttons; i++, btn++)
+ swaps(btn, n);
+
+ swaps(&info->num_buttons, n);
+}
+
+/**
+ * Write key information into info.
+ * @return Number of bytes written into info.
+ */
+int
+ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
+{
+ int i;
+ XkbDescPtr xkb = dev->key->xkbInfo->desc;
+ uint32_t *kc;
+
+ info->type = KeyClass;
+ info->num_keycodes = xkb->max_key_code - xkb->min_key_code + 1;
+ info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
+ info->sourceid = dev->key->sourceid;
+
+ kc = (uint32_t*)&info[1];
+ for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++)
+ *kc = i;
+
+ return info->length * 4;
+}
+
+static void
+SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
+{
+ char n;
+ uint32_t *key;
+ int i;
+ swaps(&info->type, n);
+ swaps(&info->length, n);
+ swaps(&info->sourceid, n);
+
+ for (i = 0, key = (uint32_t*)&info[1]; i < info->num_keycodes; i++, key++)
+ swapl(key, n);
+
+ swaps(&info->num_keycodes, n);
+}
+
+/**
+ * List axis information for the given axis.
+ *
+ * @return The number of bytes written into info.
+ */
+int
+ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber)
+{
+ ValuatorClassPtr v = dev->valuator;
+
+ info->type = ValuatorClass;
+ info->length = sizeof(xXIValuatorInfo)/4;
+ info->label = v->axes[axisnumber].label;
+ info->min.integral = v->axes[axisnumber].min_value;
+ info->min.frac = 0;
+ info->max.integral = v->axes[axisnumber].max_value;
+ info->max.frac = 0;
+ info->value.integral = (int)v->axisVal[axisnumber];
+ info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16));
+ info->resolution = v->axes[axisnumber].resolution;
+ info->number = axisnumber;
+ info->mode = v->mode; /* Server doesn't have per-axis mode yet */
+ info->sourceid = v->sourceid;
+
+ return info->length * 4;
+}
+
+static void
+SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info)
+{
+ char n;
+ swaps(&info->type, n);
+ swaps(&info->length, n);
+ swapl(&info->label, n);
+ swapl(&info->min.integral, n);
+ swapl(&info->min.frac, n);
+ swapl(&info->max.integral, n);
+ swapl(&info->max.frac, n);
+ swaps(&info->number, n);
+ swaps(&info->sourceid, n);
+}
+
+int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
+{
+ DeviceIntPtr master = dev->u.master;
+ int use;
+
+ if (IsMaster(dev))
+ {
+ DeviceIntPtr paired = GetPairedDevice(dev);
+ use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard;
+ *attachment = (paired ? paired->id : 0);
+ } else if (master)
+ {
+ use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard;
+ *attachment = master->id;
+ } else
+ use = XIFloatingSlave;
+
+ return use;
+}
+
+/**
+ * Write the info for device dev into the buffer pointed to by info.
+ *
+ * @return The number of bytes used.
+ */
+static int
+ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
+{
+ char *any = (char*)&info[1];
+ int len = 0, total_len = 0;
+
+ info->deviceid = dev->id;
+ info->use = GetDeviceUse(dev, &info->attachment);
+ info->num_classes = 0;
+ info->name_len = strlen(dev->name);
+ info->enabled = dev->enabled;
+ total_len = sizeof(xXIDeviceInfo);
+
+ len = pad_to_int32(info->name_len);
+ memset(any, 0, len);
+ strncpy(any, dev->name, info->name_len);
+ any += len;
+ total_len += len;
+
+ return total_len + ListDeviceClasses(dev, any, &info->num_classes);
+}
+
+/**
+ * Write the class info of the device into the memory pointed to by any, set
+ * nclasses to the number of classes in total and return the number of bytes
+ * written.
+ */
+int
+ListDeviceClasses(DeviceIntPtr dev, char *any, uint16_t *nclasses)
+{
+ int total_len = 0;
+ int len;
+ int i;
+
+ if (dev->button)
+ {
+ (*nclasses)++;
+ len = ListButtonInfo(dev, (xXIButtonInfo*)any);
+ any += len;
+ total_len += len;
+ }
+
+ if (dev->key)
+ {
+ (*nclasses)++;
+ len = ListKeyInfo(dev, (xXIKeyInfo*)any);
+ any += len;
+ total_len += len;
+ }
+
+ for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++)
+ {
+ (*nclasses)++;
+ len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i);
+ any += len;
+ total_len += len;
+ }
+
+ return total_len;
+}
+
+static void
+SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
+{
+ char n;
+ char *any = (char*)&info[1];
+ int i;
+
+ /* Skip over name */
+ any += pad_to_int32(info->name_len);
+
+ for (i = 0; i < info->num_classes; i++)
+ {
+ int len = ((xXIAnyInfo*)any)->length;
+ switch(((xXIAnyInfo*)any)->type)
+ {
+ case XIButtonClass:
+ SwapButtonInfo(dev, (xXIButtonInfo*)any);
+ break;
+ case XIKeyClass:
+ SwapKeyInfo(dev, (xXIKeyInfo*)any);
+ break;
+ case XIValuatorClass:
+ SwapValuatorInfo(dev, (xXIValuatorInfo*)any);
+ break;
+ }
+
+ any += len * 4;
+ }
+
+ swaps(&info->deviceid, n);
+ swaps(&info->use, n);
+ swaps(&info->attachment, n);
+ swaps(&info->num_classes, n);
+ swaps(&info->name_len, n);
+
+}
diff --git a/xorg-server/Xi/xiquerydevice.h b/xorg-server/Xi/xiquerydevice.h
new file mode 100644
index 000000000..34e87bdde
--- /dev/null
+++ b/xorg-server/Xi/xiquerydevice.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2009 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 QUERYDEV_H
+#define QUERYDEV_H 1
+
+#include <X11/extensions/XI2proto.h>
+
+int SProcXIQueryDevice(ClientPtr client);
+int ProcXIQueryDevice(ClientPtr client);
+void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep);
+int SizeDeviceClasses(DeviceIntPtr dev);
+int ListDeviceClasses(DeviceIntPtr dev, char* any, uint16_t* nclasses);
+int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment);
+int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info);
+int ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info);
+int ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber);
+#endif /* QUERYDEV_H */
diff --git a/xorg-server/Xi/xiquerypointer.c b/xorg-server/Xi/xiquerypointer.c
new file mode 100644
index 000000000..93ceba4c3
--- /dev/null
+++ b/xorg-server/Xi/xiquerypointer.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+/***********************************************************************
+ *
+ * Request to query the pointer location of an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2proto.h>
+#include "extnsionst.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "eventconvert.h"
+#include "xkbsrv.h"
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+#include "xiquerypointer.h"
+
+/***********************************************************************
+ *
+ * This procedure allows a client to query the pointer of a device.
+ *
+ */
+
+int
+SProcXIQueryPointer(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIQueryPointerReq);
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->win, n);
+ return (ProcXIQueryPointer(client));
+}
+
+int
+ProcXIQueryPointer(ClientPtr client)
+{
+ int rc;
+ xXIQueryPointerReply rep;
+ DeviceIntPtr pDev, kbd;
+ WindowPtr pWin, t;
+ SpritePtr pSprite;
+ XkbStatePtr state;
+ char *buttons = NULL;
+ int buttons_size = 0; /* size of buttons array */
+
+ REQUEST(xXIQueryPointerReq);
+ REQUEST_SIZE_MATCH(xXIQueryPointerReq);
+
+ rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->deviceid;
+ return rc;
+ }
+
+ if (pDev->valuator == NULL || IsKeyboardDevice(pDev) ||
+ (!IsMaster(pDev) && pDev->u.master)) /* no attached devices */
+ {
+ client->errorValue = stuff->deviceid;
+ return BadDevice;
+ }
+
+ rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_XIQueryPointer,
+ stuff->win, rc);
+ return Success;
+ }
+
+ if (pDev->valuator->motionHintWindow)
+ MaybeStopHint(pDev, client);
+
+ if (IsMaster(pDev))
+ kbd = GetPairedDevice(pDev);
+ else
+ kbd = (pDev->key) ? pDev : NULL;
+
+ pSprite = pDev->spriteInfo->sprite;
+
+ memset(&rep, 0, sizeof(rep));
+ rep.repType = X_Reply;
+ rep.RepType = X_XIQueryPointer;
+ rep.length = 6;
+ rep.sequenceNumber = client->sequence;
+ rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
+ rep.root_x = FP1616(pSprite->hot.x, 0);
+ rep.root_y = FP1616(pSprite->hot.y, 0);
+ rep.child = None;
+
+ if (kbd)
+ {
+ state = &kbd->key->xkbInfo->prev_state;
+ rep.mods.base_mods = state->base_mods;
+ rep.mods.latched_mods = state->latched_mods;
+ rep.mods.locked_mods = state->locked_mods;
+
+ rep.group.base_group = state->base_group;
+ rep.group.latched_group = state->latched_group;
+ rep.group.locked_group = state->locked_group;
+ }
+
+ if (pDev->button)
+ {
+ int i, down;
+ rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
+ rep.length += rep.buttons_len;
+ buttons_size = rep.buttons_len * 4;
+ buttons = xcalloc(1, buttons_size);
+ if (!buttons)
+ return BadAlloc;
+
+ down = pDev->button->buttonsDown;
+
+ for (i = 0; i < pDev->button->numButtons && down; i++)
+ {
+ if (BitIsOn(pDev->button->down, i))
+ {
+ SetBit(buttons, i);
+ down--;
+ }
+ }
+ } else
+ rep.buttons_len = 0;
+
+ if (pSprite->hot.pScreen == pWin->drawable.pScreen)
+ {
+ rep.same_screen = xTrue;
+ rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0);
+ rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0);
+ for (t = pSprite->win; t; t = t->parent)
+ if (t->parent == pWin)
+ {
+ rep.child = t->drawable.id;
+ break;
+ }
+ } else
+ {
+ rep.same_screen = xFalse;
+ rep.win_x = 0;
+ rep.win_y = 0;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ rep.root_x += FP1616(panoramiXdataPtr[0].x, 0);
+ rep.root_y += FP1616(panoramiXdataPtr[0].y, 0);
+ if (stuff->win == rep.root)
+ {
+ rep.win_x += FP1616(panoramiXdataPtr[0].x, 0);
+ rep.win_y += FP1616(panoramiXdataPtr[0].y, 0);
+ }
+ }
+#endif
+
+ WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep);
+ if (buttons)
+ WriteToClient(client, buttons_size, buttons);
+
+ xfree(buttons);
+
+ return Success;
+}
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XIQueryPointer function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXIQueryPointer(ClientPtr client, int size,
+ xXIQueryPointerReply * rep)
+{
+ char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->root, n);
+ swapl(&rep->child, n);
+ swapl(&rep->root_x, n);
+ swapl(&rep->root_y, n);
+ swapl(&rep->win_x, n);
+ swapl(&rep->win_y, n);
+ swaps(&rep->buttons_len, n);
+
+ WriteToClient(client, size, (char *)rep);
+}
+
diff --git a/xorg-server/Xi/xiquerypointer.h b/xorg-server/Xi/xiquerypointer.h
new file mode 100644
index 000000000..ea22376a6
--- /dev/null
+++ b/xorg-server/Xi/xiquerypointer.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef QUERYDP_H
+#define QUERYDP_H 1
+
+int SProcXIQueryPointer(ClientPtr /* client */);
+int ProcXIQueryPointer(ClientPtr /* client */);
+void SRepXIQueryPointer(ClientPtr /* client */ ,
+ int /* size */ ,
+ xXIQueryPointerReply * /* rep */);
+
+#endif /* QUERYDP_H */
diff --git a/xorg-server/Xi/xiqueryversion.c b/xorg-server/Xi/xiqueryversion.c
new file mode 100644
index 000000000..ae63297da
--- /dev/null
+++ b/xorg-server/Xi/xiqueryversion.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2009 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
+ *
+ */
+
+/**
+ * @file xiqueryversion.c
+ * Protocol handling for the XIQueryVersion request/reply.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include "inputstr.h"
+
+#include <X11/Xmd.h>
+#include <X11/X.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h"
+#include "exevents.h"
+#include "xiqueryversion.h"
+#include "misc.h"
+
+extern XExtensionVersion XIVersion; /* defined in getvers.c */
+/**
+ * Return the supported XI version.
+ *
+ * Saves the version the client claims to support as well, for future
+ * reference.
+ */
+int
+ProcXIQueryVersion(ClientPtr client)
+{
+ xXIQueryVersionReply rep;
+ XIClientPtr pXIClient;
+ int major, minor;
+ unsigned int sversion, cversion;
+
+ REQUEST(xXIQueryVersionReq);
+ REQUEST_SIZE_MATCH(xXIQueryVersionReq);
+
+ /* This request only exists after XI2 */
+ if (stuff->major_version < 2)
+ {
+ client->errorValue = stuff->major_version;
+ return BadValue;
+ }
+
+ pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
+
+ sversion = XIVersion.major_version * 1000 + XIVersion.minor_version;
+ cversion = stuff->major_version * 1000 + stuff->minor_version;
+
+ if (sversion > cversion)
+ {
+ major = stuff->major_version;
+ minor = stuff->minor_version;
+ } else
+ {
+ major = XIVersion.major_version;
+ minor = XIVersion.minor_version;
+ }
+
+ pXIClient->major_version = major;
+ pXIClient->minor_version = minor;
+
+ memset(&rep, 0, sizeof(xXIQueryVersionReply));
+ rep.repType = X_Reply;
+ rep.RepType = X_XIQueryVersion;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.major_version = major;
+ rep.minor_version = minor;
+
+ WriteReplyToClient(client, sizeof(xXIQueryVersionReply), &rep);
+
+ return Success;
+}
+
+/* Swapping routines */
+
+int
+SProcXIQueryVersion(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIQueryVersionReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXIQueryVersionReq);
+ swaps(&stuff->major_version, n);
+ swaps(&stuff->minor_version, n);
+ return (ProcXIQueryVersion(client));
+}
+
+void
+SRepXIQueryVersion(ClientPtr client, int size, xXIQueryVersionReply *rep)
+{
+ char n;
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swaps(&rep->major_version, n);
+ swaps(&rep->minor_version, n);
+ WriteToClient(client, size, (char *)rep);
+}
diff --git a/xorg-server/Xi/xiqueryversion.h b/xorg-server/Xi/xiqueryversion.h
new file mode 100644
index 000000000..06bb7291a
--- /dev/null
+++ b/xorg-server/Xi/xiqueryversion.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2009 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/extensions/XI2proto.h>
+
+#ifndef QUERYVERSION_H
+#define QUERYVERSION_H 1
+
+int SProcXIQueryVersion(ClientPtr client);
+int ProcXIQueryVersion(ClientPtr client);
+void SRepXIQueryVersion(ClientPtr client, int size, xXIQueryVersionReply* rep);
+
+#endif /* QUERYVERSION_H */
diff --git a/xorg-server/Xi/xiselectev.c b/xorg-server/Xi/xiselectev.c
new file mode 100644
index 000000000..672edab3b
--- /dev/null
+++ b/xorg-server/Xi/xiselectev.c
@@ -0,0 +1,299 @@
+/*
+ * 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include "dixstruct.h"
+#include "windowstr.h"
+#include "exglobals.h"
+#include "exevents.h"
+#include <X11/extensions/XI2proto.h>
+
+#include "xiselectev.h"
+
+/**
+ * Check the given mask (in len bytes) for invalid mask bits.
+ * Invalid mask bits are any bits above XI2LastEvent.
+ *
+ * @return BadValue if at least one invalid bit is set or Success otherwise.
+ */
+int XICheckInvalidMaskBits(unsigned char *mask, int len)
+{
+ if (len >= XIMaskLen(XI2LASTEVENT))
+ {
+ int i;
+ for (i = XI2LASTEVENT + 1; i < len * 8; i++)
+ if (BitIsOn(mask, i))
+ return BadValue;
+ }
+
+ return Success;
+}
+
+int
+SProcXISelectEvents(ClientPtr client)
+{
+ char n;
+ int i;
+ xXIEventMask* evmask;
+
+ REQUEST(xXISelectEventsReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXISelectEventsReq);
+ swapl(&stuff->win, n);
+ swaps(&stuff->num_masks, n);
+
+ evmask = (xXIEventMask*)&stuff[1];
+ for (i = 0; i < stuff->num_masks; i++)
+ {
+ swaps(&evmask->deviceid, n);
+ swaps(&evmask->mask_len, n);
+ evmask = (xXIEventMask*)(((char*)&evmask[1]) + evmask->mask_len * 4);
+ }
+
+ return (ProcXISelectEvents(client));
+}
+
+int
+ProcXISelectEvents(ClientPtr client)
+{
+ int rc, num_masks;
+ WindowPtr win;
+ DeviceIntPtr dev;
+ DeviceIntRec dummy;
+ xXIEventMask *evmask;
+ int *types = NULL;
+ int len;
+
+ REQUEST(xXISelectEventsReq);
+ REQUEST_AT_LEAST_SIZE(xXISelectEventsReq);
+
+ if (stuff->num_masks == 0)
+ return BadValue;
+
+ rc = dixLookupWindow(&win, stuff->win, client, DixReceiveAccess);
+ if (rc != Success)
+ return rc;
+
+ len = sz_xXISelectEventsReq;
+
+ /* check request validity */
+ evmask = (xXIEventMask*)&stuff[1];
+ num_masks = stuff->num_masks;
+ while(num_masks--)
+ {
+ len += sizeof(xXIEventMask) + evmask->mask_len * 4;
+
+ if (bytes_to_int32(len) > stuff->length)
+ return BadLength;
+
+ if (evmask->deviceid != XIAllDevices &&
+ evmask->deviceid != XIAllMasterDevices)
+ rc = dixLookupDevice(&dev, evmask->deviceid, client, DixUseAccess);
+ else {
+ /* XXX: XACE here? */
+ }
+ if (rc != Success)
+ return rc;
+
+ /* hierarchy event mask is not allowed on devices */
+ if (evmask->deviceid != XIAllDevices && evmask->mask_len >= 1)
+ {
+ unsigned char *bits = (unsigned char*)&evmask[1];
+ if (BitIsOn(bits, XI_HierarchyChanged))
+ return BadValue;
+ }
+
+ /* Raw events may only be selected on root windows */
+ if (win->parent && evmask->mask_len >= 1)
+ {
+ unsigned char *bits = (unsigned char*)&evmask[1];
+ if (BitIsOn(bits, XI_RawKeyPress) ||
+ BitIsOn(bits, XI_RawKeyRelease) ||
+ BitIsOn(bits, XI_RawButtonPress) ||
+ BitIsOn(bits, XI_RawButtonRelease) ||
+ BitIsOn(bits, XI_RawMotion))
+ return BadValue;
+ }
+
+ if (XICheckInvalidMaskBits((unsigned char*)&evmask[1],
+ evmask->mask_len * 4) != Success)
+ return BadValue;
+
+ evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+ evmask++;
+ }
+
+ if (bytes_to_int32(len) != stuff->length)
+ return BadLength;
+
+ /* Set masks on window */
+ evmask = (xXIEventMask*)&stuff[1];
+ num_masks = stuff->num_masks;
+ while(num_masks--)
+ {
+ if (evmask->deviceid == XIAllDevices ||
+ evmask->deviceid == XIAllMasterDevices)
+ {
+ dummy.id = evmask->deviceid;
+ dev = &dummy;
+ } else
+ dixLookupDevice(&dev, evmask->deviceid, client, DixUseAccess);
+ if (XISetEventMask(dev, win, client, evmask->mask_len * 4,
+ (unsigned char*)&evmask[1]) != Success)
+ return BadAlloc;
+ evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+ evmask++;
+ }
+
+ RecalculateDeliverableEvents(win);
+
+ xfree(types);
+ return Success;
+}
+
+
+int
+SProcXIGetSelectedEvents(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIGetSelectedEventsReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
+ swapl(&stuff->win, n);
+
+ return (ProcXIGetSelectedEvents(client));
+}
+
+int
+ProcXIGetSelectedEvents(ClientPtr client)
+{
+ int rc, i;
+ WindowPtr win;
+ char n;
+ char *buffer = NULL;
+ xXIGetSelectedEventsReply reply;
+ OtherInputMasks *masks;
+ InputClientsPtr others = NULL;
+ xXIEventMask *evmask = NULL;
+ DeviceIntPtr dev;
+
+ REQUEST(xXIGetSelectedEventsReq);
+ REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
+
+ rc = dixLookupWindow(&win, stuff->win, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ reply.repType = X_Reply;
+ reply.RepType = X_XIGetSelectedEvents;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.num_masks = 0;
+
+ masks = wOtherInputMasks(win);
+ if (masks)
+ {
+ for (others = wOtherInputMasks(win)->inputClients; others;
+ others = others->next) {
+ if (SameClient(others, client)) {
+ break;
+ }
+ }
+ }
+
+ if (!others)
+ {
+ WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
+ return Success;
+ }
+
+ buffer = xcalloc(MAXDEVICES, sizeof(xXIEventMask) + pad_to_int32(XI2MASKSIZE));
+ if (!buffer)
+ return BadAlloc;
+
+ evmask = (xXIEventMask*)buffer;
+ for (i = 0; i < MAXDEVICES; i++)
+ {
+ int j;
+ unsigned char *devmask = others->xi2mask[i];
+
+ if (i > 2)
+ {
+ rc = dixLookupDevice(&dev, i, client, DixGetAttrAccess);
+ if (rc != Success)
+ continue;
+ }
+
+
+ for (j = XI2MASKSIZE - 1; j >= 0; j--)
+ {
+ if (devmask[j] != 0)
+ {
+ int mask_len = (j + 4)/4; /* j is an index, hence + 4, not + 3 */
+ evmask->deviceid = i;
+ evmask->mask_len = mask_len;
+ reply.num_masks++;
+ reply.length += sizeof(xXIEventMask)/4 + evmask->mask_len;
+
+ if (client->swapped)
+ {
+ swaps(&evmask->deviceid, n);
+ swaps(&evmask->mask_len, n);
+ }
+
+ memcpy(&evmask[1], devmask, j + 1);
+ evmask = (xXIEventMask*)((char*)evmask +
+ sizeof(xXIEventMask) + mask_len * 4);
+ break;
+ }
+ }
+ }
+
+ WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
+
+ if (reply.num_masks)
+ WriteToClient(client, reply.length * 4, buffer);
+
+ xfree(buffer);
+ return Success;
+}
+
+void SRepXIGetSelectedEvents(ClientPtr client,
+ int len, xXIGetSelectedEventsReply *rep)
+{
+ char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swaps(&rep->num_masks, n);
+ WriteToClient(client, len, (char *)rep);
+}
+
+
diff --git a/xorg-server/Xi/xiselectev.h b/xorg-server/Xi/xiselectev.h
new file mode 100644
index 000000000..21ec9371b
--- /dev/null
+++ b/xorg-server/Xi/xiselectev.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef XISELECTEVENTS_H
+#define XISELECTEVENTS_H 1
+
+int SProcXISelectEvents(ClientPtr client);
+int ProcXISelectEvents(ClientPtr client);
+int SProcXIGetSelectedEvents(ClientPtr client);
+int ProcXIGetSelectedEvents(ClientPtr client);
+void SRepXIGetSelectedEvents(ClientPtr client,
+ int len, xXIGetSelectedEventsReply *rep);
+
+#endif /* _XISELECTEVENTS_H_ */
diff --git a/xorg-server/Xi/xisetclientpointer.c b/xorg-server/Xi/xisetclientpointer.c
new file mode 100644
index 000000000..09db8ff75
--- /dev/null
+++ b/xorg-server/Xi/xisetclientpointer.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+/***********************************************************************
+ *
+ * Request to set the client pointer for the owner of the given window.
+ * All subsequent calls that are ambiguous will choose the client pointer as
+ * default value.
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include "scrnintstr.h" /* screen structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2proto.h>
+#include "extnsionst.h"
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "xisetclientpointer.h"
+
+int
+SProcXISetClientPointer(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXISetClientPointerReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->win, n);
+ swaps(&stuff->deviceid, n);
+ REQUEST_SIZE_MATCH(xXISetClientPointerReq);
+ return (ProcXISetClientPointer(client));
+}
+
+int
+ProcXISetClientPointer(ClientPtr client)
+{
+ DeviceIntPtr pDev;
+ ClientPtr targetClient;
+ int rc;
+
+ REQUEST(xXISetClientPointerReq);
+ REQUEST_SIZE_MATCH(xXISetClientPointerReq);
+
+
+ rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixManageAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->deviceid;
+ return rc;
+ }
+
+ if (!IsMaster(pDev))
+ {
+ client->errorValue = stuff->deviceid;
+ return BadDevice;
+ }
+
+ pDev = GetMaster(pDev, MASTER_POINTER);
+
+ if (stuff->win != None)
+ {
+ rc = dixLookupClient(&targetClient, stuff->win, client,
+ DixManageAccess);
+
+ if (rc != Success)
+ return BadWindow;
+
+ } else
+ targetClient = client;
+
+ rc = SetClientPointer(targetClient, pDev);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->deviceid;
+ return rc;
+ }
+
+ return Success;
+}
diff --git a/xorg-server/Xi/xisetclientpointer.h b/xorg-server/Xi/xisetclientpointer.h
new file mode 100644
index 000000000..5968d98da
--- /dev/null
+++ b/xorg-server/Xi/xisetclientpointer.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SETCPTR_H
+#define SETCPTR_H 1
+
+int SProcXISetClientPointer(ClientPtr /* client */);
+int ProcXISetClientPointer(ClientPtr /* client */);
+
+#endif /* SETCPTR_H */
diff --git a/xorg-server/Xi/xisetdevfocus.c b/xorg-server/Xi/xisetdevfocus.c
new file mode 100644
index 000000000..059424e41
--- /dev/null
+++ b/xorg-server/Xi/xisetdevfocus.c
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ *
+ * Author: Peter Hutterer
+ */
+/***********************************************************************
+ *
+ * Request to set and get an input device's focus.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h" /* BadDevice */
+#include "xisetdevfocus.h"
+
+int
+SProcXISetFocus(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXISetFocusReq);
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->focus, n);
+ swapl(&stuff->time, n);
+
+ return ProcXISetFocus(client);
+}
+
+int
+SProcXIGetFocus(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIGetFocusReq);
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+
+ return ProcXIGetFocus(client);
+}
+
+int
+ProcXISetFocus(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ int ret;
+
+ REQUEST(xXISetFocusReq);
+ REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
+
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+ if (ret != Success)
+ return ret;
+ if (!dev->focus)
+ return BadDevice;
+
+ return SetInputFocus(client, dev, stuff->focus, RevertToParent,
+ stuff->time, TRUE);
+}
+
+int
+ProcXIGetFocus(ClientPtr client)
+{
+ xXIGetFocusReply rep;
+ DeviceIntPtr dev;
+ int ret;
+
+ REQUEST(xXIGetFocusReq);
+ REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
+
+ ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetFocusAccess);
+ if (ret != Success)
+ return ret;
+ if (!dev->focus)
+ return BadDevice;
+
+ rep.repType = X_Reply;
+ rep.RepType = X_XIGetFocus;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (dev->focus->win == NoneWin)
+ rep.focus = None;
+ else if (dev->focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else if (dev->focus->win == FollowKeyboardWin)
+ rep.focus = FollowKeyboard;
+ else
+ rep.focus = dev->focus->win->drawable.id;
+
+ WriteReplyToClient(client, sizeof(xXIGetFocusReply), &rep);
+ return Success;
+}
+
+void
+SRepXIGetFocus(ClientPtr client, int len, xXIGetFocusReply *rep)
+{
+ char n;
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->focus, n);
+ WriteToClient(client, len, (char *)rep);
+}
diff --git a/xorg-server/Xi/xisetdevfocus.h b/xorg-server/Xi/xisetdevfocus.h
new file mode 100644
index 000000000..2c3243d86
--- /dev/null
+++ b/xorg-server/Xi/xisetdevfocus.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef XISETDEVFOCUS_H
+#define XISETDEVFOCUS_H 1
+
+int SProcXISetFocus(ClientPtr client);
+int ProcXISetFocus(ClientPtr client);
+
+int SProcXIGetFocus(ClientPtr client);
+int ProcXIGetFocus(ClientPtr client);
+
+void SRepXIGetFocus(ClientPtr client, int len, xXIGetFocusReply* rep);
+#endif /* XISETDEVFOCUS_H */
diff --git a/xorg-server/Xi/xiwarppointer.c b/xorg-server/Xi/xiwarppointer.c
new file mode 100644
index 000000000..7276e6faf
--- /dev/null
+++ b/xorg-server/Xi/xiwarppointer.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+/***********************************************************************
+ *
+ * Request to Warp the pointer location of an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include "scrnintstr.h" /* screen structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2proto.h>
+#include "extnsionst.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "mipointer.h" /* for miPointerUpdateSprite */
+
+
+#include "xiwarppointer.h"
+/***********************************************************************
+ *
+ * This procedure allows a client to warp the pointer of a device.
+ *
+ */
+
+int
+SProcXIWarpPointer(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIWarpPointerReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->src_win, n);
+ swapl(&stuff->dst_win, n);
+ swapl(&stuff->src_x, n);
+ swapl(&stuff->src_y, n);
+ swaps(&stuff->src_width, n);
+ swaps(&stuff->src_height, n);
+ swapl(&stuff->dst_x, n);
+ swapl(&stuff->dst_y, n);
+ swaps(&stuff->deviceid, n);
+ return (ProcXIWarpPointer(client));
+}
+
+int
+ProcXIWarpPointer(ClientPtr client)
+{
+ int rc;
+ int x, y;
+ WindowPtr dest = NULL;
+ DeviceIntPtr pDev;
+ SpritePtr pSprite;
+ ScreenPtr newScreen;
+ int src_x, src_y;
+ int dst_x, dst_y;
+
+ REQUEST(xXIWarpPointerReq);
+ REQUEST_SIZE_MATCH(xXIWarpPointerReq);
+
+ /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */
+
+ rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixWriteAccess);
+
+ if (rc != Success)
+ {
+ client->errorValue = stuff->deviceid;
+ return rc;
+ }
+
+ if ((!IsMaster(pDev) && pDev->u.master) ||
+ (IsMaster(pDev) && !IsPointerDevice(pDev)))
+ {
+ client->errorValue = stuff->deviceid;
+ return BadDevice;
+ }
+
+ if (stuff->dst_win != None)
+ {
+ rc = dixLookupWindow(&dest, stuff->dst_win, client, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->dst_win;
+ return rc;
+ }
+ }
+
+ pSprite = pDev->spriteInfo->sprite;
+ x = pSprite->hotPhys.x;
+ y = pSprite->hotPhys.y;
+
+ src_x = stuff->src_x / (double)(1 << 16);
+ src_y = stuff->src_y / (double)(1 << 16);
+ dst_x = stuff->dst_x / (double)(1 << 16);
+ dst_y = stuff->dst_y / (double)(1 << 16);
+
+ if (stuff->src_win != None)
+ {
+ int winX, winY;
+ WindowPtr src;
+
+ rc = dixLookupWindow(&src, stuff->src_win, client, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->src_win;
+ return rc;
+ }
+
+ winX = src->drawable.x;
+ winY = src->drawable.y;
+ if (src->drawable.pScreen != pSprite->hotPhys.pScreen ||
+ x < winX + src_x ||
+ y < winY + src_y ||
+ (stuff->src_width != 0 &&
+ winX + src_x + (int)stuff->src_width < 0) ||
+ (stuff->src_height != 0 &&
+ winY + src_y + (int)stuff->src_height < y) ||
+ !PointInWindowIsVisible(src, x, y))
+ return Success;
+ }
+
+ if (dest)
+ {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ newScreen = dest->drawable.pScreen;
+ } else
+ newScreen = pSprite->hotPhys.pScreen;
+
+ x += dst_x;
+ y += dst_y;
+
+ if (x < 0)
+ x = 0;
+ else if (x > newScreen->width)
+ x = newScreen->width - 1;
+
+ if (y < 0)
+ y = 0;
+ else if (y > newScreen->height)
+ y = newScreen->height - 1;
+
+ if (newScreen == 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(pDev, pSprite->hotShape, &x, &y);
+ (*newScreen->SetCursorPosition)(pDev, newScreen, x, y, TRUE);
+ } else if (!PointerConfinedToScreen(pDev))
+ {
+ NewCurrentScreen(pDev, newScreen, x, y);
+ }
+
+ /* if we don't update the device, we get a jump next time it moves */
+ pDev->last.valuators[0] = x;
+ pDev->last.valuators[1] = y;
+ miPointerUpdateSprite(pDev);
+
+ /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it
+ here though. */
+ return Success;
+}
+
diff --git a/xorg-server/Xi/xiwarppointer.h b/xorg-server/Xi/xiwarppointer.h
new file mode 100644
index 000000000..aafc73904
--- /dev/null
+++ b/xorg-server/Xi/xiwarppointer.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef WARPDEVP_H
+#define WARPDEVP_H 1
+
+int SProcXIWarpPointer(ClientPtr /* client */);
+int ProcXIWarpPointer(ClientPtr /* client */);
+
+#endif /* WARPDEVP_H */