diff options
Diffstat (limited to 'xorg-server/Xi')
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(¶m, 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, ¶m, + 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(¶m, 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, ¶m, 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(¶m, 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, ¶m); + + 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, + ¶m, GRABTYPE_XI2, &mask); + break; + case XIGrabtypeKeycode: + status = GrabKey(client, dev, mod_dev, stuff->detail, + ¶m, GRABTYPE_XI2, &mask); + break; + case XIGrabtypeEnter: + case XIGrabtypeFocusIn: + status = GrabWindow(client, dev, stuff->grab_type, + ¶m, &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 */ |