diff options
author | marha <marha@users.sourceforge.net> | 2009-09-09 05:23:48 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-09-09 05:23:48 +0000 |
commit | 81f91c615982e50bb62708201569c33a3cd3d973 (patch) | |
tree | 4f32ecc48a3b7b5e76642f3792338263c53879bd /xorg-server/dix | |
parent | b571a562410f565af2bdde52d9f7f9a23ffae04f (diff) | |
parent | a915739887477b28d924ecc8417ee107d125bd6c (diff) | |
download | vcxsrv-81f91c615982e50bb62708201569c33a3cd3d973.tar.gz vcxsrv-81f91c615982e50bb62708201569c33a3cd3d973.tar.bz2 vcxsrv-81f91c615982e50bb62708201569c33a3cd3d973.zip |
svn merge https://vcxsrv.svn.sourceforge.net/svnroot/vcxsrv/branches/released .
Diffstat (limited to 'xorg-server/dix')
34 files changed, 5393 insertions, 4023 deletions
diff --git a/xorg-server/dix/Makefile.am b/xorg-server/dix/Makefile.am index 4c2395d82..13e5dedd7 100644 --- a/xorg-server/dix/Makefile.am +++ b/xorg-server/dix/Makefile.am @@ -1,8 +1,9 @@ -noinst_LTLIBRARIES = libdix.la +noinst_LTLIBRARIES = libdix.la libmain.la -AM_CFLAGS = $(DIX_CFLAGS) \ - -DVENDOR_NAME=\""@VENDOR_NAME@"\" \ - -DVENDOR_RELEASE="@VENDOR_RELEASE@" +AM_CFLAGS = $(DIX_CFLAGS) + +libmain_la_SOURCES = \ + main.c libdix_la_SOURCES = \ atom.c \ @@ -17,6 +18,7 @@ libdix_la_SOURCES = \ enterleave.c \ enterleave.h \ events.c \ + eventconvert.c \ extension.c \ ffs.c \ gc.c \ @@ -25,7 +27,7 @@ libdix_la_SOURCES = \ glyphcurs.c \ grabs.c \ initatoms.c \ - main.c \ + inpututils.c \ pixmap.c \ privates.c \ property.c \ diff --git a/xorg-server/dix/Makefile.in b/xorg-server/dix/Makefile.in index 3d10eb3c0..caa244120 100644 --- a/xorg-server/dix/Makefile.in +++ b/xorg-server/dix/Makefile.in @@ -41,8 +41,11 @@ subdir = dix DIST_COMMON = $(dist_miscconfig_DATA) $(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 @@ -52,18 +55,23 @@ 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) libdix_la_LIBADD = am_libdix_la_OBJECTS = atom.lo colormap.lo cursor.lo deprecated.lo \ devices.lo dispatch.lo dixfonts.lo dixutils.lo enterleave.lo \ - events.lo extension.lo ffs.lo gc.lo getevents.lo globals.lo \ - glyphcurs.lo grabs.lo initatoms.lo main.lo pixmap.lo \ - privates.lo property.lo ptrveloc.lo registry.lo resource.lo \ - selection.lo swaprep.lo swapreq.lo tables.lo window.lo + events.lo eventconvert.lo extension.lo ffs.lo gc.lo \ + getevents.lo globals.lo glyphcurs.lo grabs.lo initatoms.lo \ + inpututils.lo pixmap.lo privates.lo property.lo ptrveloc.lo \ + registry.lo resource.lo selection.lo swaprep.lo swapreq.lo \ + tables.lo window.lo libdix_la_OBJECTS = $(am_libdix_la_OBJECTS) +libmain_la_LIBADD = +am_libmain_la_OBJECTS = main.lo +libmain_la_OBJECTS = $(am_libmain_la_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) dix_O_SOURCES = dix.c dix_O_OBJECTS = dix.$(OBJEXT) @@ -78,8 +86,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libdix_la_SOURCES) dix.c -DIST_SOURCES = $(libdix_la_SOURCES) dix.c +SOURCES = $(libdix_la_SOURCES) $(libmain_la_SOURCES) dix.c +DIST_SOURCES = $(libdix_la_SOURCES) $(libmain_la_SOURCES) dix.c am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -111,6 +119,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@ @@ -131,9 +140,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@ @@ -162,7 +174,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@ @@ -171,9 +185,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@ @@ -212,12 +230,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@ @@ -237,7 +256,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@ @@ -247,6 +265,7 @@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PROJECTROOT = @PROJECTROOT@ PS2PDF = @PS2PDF@ +Q = @Q@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ @@ -260,11 +279,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@ @@ -300,6 +318,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@ @@ -324,7 +343,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@ @@ -347,6 +365,7 @@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +distcleancheck_listfiles = @distcleancheck_listfiles@ docdir = @docdir@ driverdir = @driverdir@ dvidir = @dvidir@ @@ -378,16 +397,18 @@ 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@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = libdix.la -AM_CFLAGS = $(DIX_CFLAGS) \ - -DVENDOR_NAME=\""@VENDOR_NAME@"\" \ - -DVENDOR_RELEASE="@VENDOR_RELEASE@" +noinst_LTLIBRARIES = libdix.la libmain.la +AM_CFLAGS = $(DIX_CFLAGS) +libmain_la_SOURCES = \ + main.c libdix_la_SOURCES = \ atom.c \ @@ -402,6 +423,7 @@ libdix_la_SOURCES = \ enterleave.c \ enterleave.h \ events.c \ + eventconvert.c \ extension.c \ ffs.c \ gc.c \ @@ -410,7 +432,7 @@ libdix_la_SOURCES = \ glyphcurs.c \ grabs.c \ initatoms.c \ - main.c \ + inpututils.c \ pixmap.c \ privates.c \ property.c \ @@ -478,6 +500,8 @@ clean-noinstLTLIBRARIES: done libdix.la: $(libdix_la_OBJECTS) $(libdix_la_DEPENDENCIES) $(LINK) $(libdix_la_OBJECTS) $(libdix_la_LIBADD) $(LIBS) +libmain.la: $(libmain_la_OBJECTS) $(libmain_la_DEPENDENCIES) + $(LINK) $(libmain_la_OBJECTS) $(libmain_la_LIBADD) $(LIBS) clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ @@ -507,6 +531,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dixfonts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dixutils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enterleave.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventconvert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs.Plo@am__quote@ @@ -516,6 +541,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyphcurs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grabs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initatoms.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inpututils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/privates.Plo@am__quote@ diff --git a/xorg-server/dix/atom.c b/xorg-server/dix/atom.c index c968c1e5a..f5bf8ad7e 100644 --- a/xorg-server/dix/atom.c +++ b/xorg-server/dix/atom.c @@ -64,7 +64,7 @@ typedef struct _Node { struct _Node *left, *right; Atom a; unsigned int fingerPrint; - char *string; + const char *string; } NodeRec, *NodePtr; static Atom lastAtom = None; @@ -74,8 +74,8 @@ static NodePtr *nodeTable; void FreeAtom(NodePtr patom); -_X_EXPORT Atom -MakeAtom(char *string, unsigned len, Bool makeit) +Atom +MakeAtom(const char *string, unsigned len, Bool makeit) { NodePtr * np; unsigned i; @@ -109,7 +109,7 @@ MakeAtom(char *string, unsigned len, Bool makeit) { NodePtr nd; - nd = (NodePtr) xalloc(sizeof(NodeRec)); + nd = xalloc(sizeof(NodeRec)); if (!nd) return BAD_RESOURCE; if (lastAtom < XA_LAST_PREDEFINED) @@ -118,13 +118,14 @@ MakeAtom(char *string, unsigned len, Bool makeit) } else { - nd->string = (char *) xalloc(len + 1); - if (!nd->string) { + char *newstring = xalloc(len + 1); + if (!newstring) { xfree(nd); return BAD_RESOURCE; } - strncpy(nd->string, string, (int)len); - nd->string[len] = 0; + strncpy(newstring, string, (int)len); + newstring[len] = 0; + nd->string = newstring; } if ((lastAtom + 1) >= tableLength) { NodePtr *table; @@ -151,13 +152,13 @@ MakeAtom(char *string, unsigned len, Bool makeit) return None; } -_X_EXPORT Bool +Bool ValidAtom(Atom atom) { return (atom != None) && (atom <= lastAtom); } -_X_EXPORT char * +const char * NameForAtom(Atom atom) { NodePtr node; @@ -201,7 +202,7 @@ InitAtoms(void) { FreeAllAtoms(); tableLength = InitialTableSize; - nodeTable = (NodePtr *)xalloc(InitialTableSize*sizeof(NodePtr)); + nodeTable = xalloc(InitialTableSize*sizeof(NodePtr)); if (!nodeTable) AtomError(); nodeTable[None] = (NodePtr)NULL; diff --git a/xorg-server/dix/colormap.c b/xorg-server/dix/colormap.c index f54615111..6fbf26c3b 100644 --- a/xorg-server/dix/colormap.c +++ b/xorg-server/dix/colormap.c @@ -51,7 +51,6 @@ SOFTWARE. #endif #include <X11/X.h> -#define NEED_EVENTS #include <X11/Xproto.h> #include <stdio.h> #include <string.h> @@ -257,7 +256,7 @@ typedef struct _colorResource * \param mid resource to use for this colormap * \param alloc 1 iff all entries are allocated writable */ -_X_EXPORT int +int CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, ColormapPtr *ppcmap, int alloc, int client) { @@ -279,7 +278,7 @@ CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, if ((class | DynamicClass) == DirectColor) sizebytes *= 3; sizebytes += sizeof(ColormapRec); - pmap = (ColormapPtr) xalloc(sizebytes); + pmap = xalloc(sizebytes); if (!pmap) return (BadAlloc); #if defined(_XSERVER64) @@ -315,7 +314,7 @@ CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--) pent->refcnt = AllocPrivate; pmap->freeRed = 0; - ppix = (Pixel *)xalloc(size * sizeof(Pixel)); + ppix = xalloc(size * sizeof(Pixel)); if (!ppix) { xfree(pmap); @@ -361,7 +360,7 @@ CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--) pent->refcnt = AllocPrivate; pmap->freeGreen = 0; - ppix = (Pixel *) xalloc(size * sizeof(Pixel)); + ppix = xalloc(size * sizeof(Pixel)); if (!ppix) { xfree(pmap->clientPixelsRed[client]); @@ -377,7 +376,7 @@ CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--) pent->refcnt = AllocPrivate; pmap->freeBlue = 0; - ppix = (Pixel *) xalloc(size * sizeof(Pixel)); + ppix = xalloc(size * sizeof(Pixel)); if (!ppix) { xfree(pmap->clientPixelsGreen[client]); @@ -506,7 +505,7 @@ TellNoMap (WindowPtr pwin, Colormap *pmid) } /* Tell window that pmid got uninstalled */ -_X_EXPORT int +int TellLostMap (WindowPtr pwin, pointer value) { Colormap *pmid = (Colormap *)value; @@ -531,7 +530,7 @@ TellLostMap (WindowPtr pwin, pointer value) } /* Tell window that pmid got installed */ -_X_EXPORT int +int TellGainedMap (WindowPtr pwin, pointer value) { Colormap *pmid = (Colormap *)value; @@ -748,7 +747,7 @@ UpdateColors (ColormapPtr pmap) pVisual = pmap->pVisual; size = pVisual->ColormapEntries; - defs = (xColorItem *)xalloc(size * sizeof(xColorItem)); + defs = xalloc(size * sizeof(xColorItem)); if (!defs) return; n = 0; @@ -804,7 +803,7 @@ UpdateColors (ColormapPtr pmap) /* Get a read-only color from a ColorMap (probably slow for large maps) * Returns by changing the value in pred, pgreen, pblue and pPix */ -_X_EXPORT int +int AllocColor (ColormapPtr pmap, unsigned short *pred, unsigned short *pgreen, unsigned short *pblue, Pixel *pPix, int client) @@ -898,9 +897,9 @@ AllocColor (ColormapPtr pmap, if (pmap->mid != pmap->pScreen->defColormap && pmap->pVisual->vid == pmap->pScreen->rootVisual) { - ColormapPtr prootmap = (ColormapPtr) - SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap, - RT_COLORMAP, DixReadAccess); + ColormapPtr prootmap; + dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap, + RT_COLORMAP, clients[client], DixReadAccess); if (pmap->class == prootmap->class) FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb, @@ -915,9 +914,9 @@ AllocColor (ColormapPtr pmap, if (pmap->mid != pmap->pScreen->defColormap && pmap->pVisual->vid == pmap->pScreen->rootVisual) { - ColormapPtr prootmap = (ColormapPtr) - SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap, - RT_COLORMAP, DixReadAccess); + ColormapPtr prootmap; + dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap, + RT_COLORMAP, clients[client], DixReadAccess); if (pmap->class == prootmap->class) { @@ -967,7 +966,7 @@ AllocColor (ColormapPtr pmap, { colorResource *pcr; - pcr = (colorResource *) xalloc(sizeof(colorResource)); + pcr = xalloc(sizeof(colorResource)); if (!pcr) { (void)FreeColors(pmap, client, 1, pPix, (Pixel)0); @@ -989,7 +988,7 @@ AllocColor (ColormapPtr pmap, * is that this routine will never return failure. */ -_X_EXPORT void +void FakeAllocColor (ColormapPtr pmap, xColorItem *item) { Pixel pixR, pixG, pixB; @@ -1056,7 +1055,7 @@ FakeAllocColor (ColormapPtr pmap, xColorItem *item) } /* free a pixel value obtained from FakeAllocColor */ -_X_EXPORT void +void FakeFreeColor(ColormapPtr pmap, Pixel pixel) { VisualPtr pVisual; @@ -1419,7 +1418,7 @@ BlueComp (EntryPtr pent, xrgb *prgb) /* Read the color value of a cell */ -_X_EXPORT int +int QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList) { Pixel *ppix, pixel; @@ -1555,12 +1554,14 @@ FreePixels(ColormapPtr pmap, int client) int FreeClientPixels (pointer value, XID fakeid) { - ColormapPtr pmap; - colorResource *pcr = (colorResource *)value; - - pmap = (ColormapPtr) LookupIDByType(pcr->mid, RT_COLORMAP); - if (pmap) - FreePixels(pmap, pcr->client); + pointer pmap; + colorResource *pcr = value; + int rc; + + rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient, + DixRemoveAccess); + if (rc == Success) + FreePixels((ColormapPtr)pmap, pcr->client); xfree(pcr); return Success; } @@ -1583,7 +1584,7 @@ AllocColorCells (int client, ColormapPtr pmap, int colors, int planes, oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; if (!oldcount && (CLIENT_ID(pmap->mid) != client)) { - pcr = (colorResource *) xalloc(sizeof(colorResource)); + pcr = xalloc(sizeof(colorResource)); if (!pcr) return (BadAlloc); } @@ -1658,7 +1659,7 @@ AllocColorPlanes (int client, ColormapPtr pmap, int colors, oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; if (!oldcount && (CLIENT_ID(pmap->mid) != client)) { - pcr = (colorResource *) xalloc(sizeof(colorResource)); + pcr = xalloc(sizeof(colorResource)); if (!pcr) return (BadAlloc); } @@ -1750,9 +1751,9 @@ AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool cont for(p = pixels; p < pixels + c; p++) *p = 0; - ppixRed = (Pixel *)xalloc(npixR * sizeof(Pixel)); - ppixGreen = (Pixel *)xalloc(npixG * sizeof(Pixel)); - ppixBlue = (Pixel *)xalloc(npixB * sizeof(Pixel)); + ppixRed = xalloc(npixR * sizeof(Pixel)); + ppixGreen = xalloc(npixG * sizeof(Pixel)); + ppixBlue = xalloc(npixB * sizeof(Pixel)); if (!ppixRed || !ppixGreen || !ppixBlue) { if (ppixBlue) xfree(ppixBlue); @@ -1857,7 +1858,7 @@ AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig, npix = c << r; if ((r >= 32) || (npix > pmap->freeRed) || (npix < c)) return(BadAlloc); - if(!(ppixTemp = (Pixel *)xalloc(npix * sizeof(Pixel)))) + if(!(ppixTemp = xalloc(npix * sizeof(Pixel)))) return(BadAlloc); ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask); @@ -2087,14 +2088,13 @@ AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b, npixClientNew = c << (r + g + b); npixShared = (c << r) + (c << g) + (c << b); - psharedList = (SHAREDCOLOR **)xalloc(npixShared * - sizeof(SHAREDCOLOR *)); + psharedList = xalloc(npixShared * sizeof(SHAREDCOLOR *)); if (!psharedList) return FALSE; ppshared = psharedList; for (z = npixShared; --z >= 0; ) { - if (!(ppshared[z] = (SHAREDCOLOR *)xalloc(sizeof(SHAREDCOLOR)))) + if (!(ppshared[z] = xalloc(sizeof(SHAREDCOLOR)))) { for (z++ ; z < npixShared; z++) xfree(ppshared[z]); @@ -2210,7 +2210,7 @@ AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b, /** FreeColors * Free colors and/or cells (probably slow for large numbers) */ -_X_EXPORT int +int FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask) { int rval, result, class; @@ -2404,7 +2404,7 @@ FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixe /* Redefine color values */ -_X_EXPORT int +int StoreColors (ColormapPtr pmap, int count, xColorItem *defs) { Pixel pix; @@ -2677,8 +2677,7 @@ IsMapInstalled(Colormap map, WindowPtr pWin) Colormap *pmaps; int imap, nummaps, found; - pmaps = (Colormap *) xalloc( - pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap)); + pmaps = xalloc(pWin->drawable.pScreen->maxInstalledCmaps*sizeof(Colormap)); if(!pmaps) return(FALSE); nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) diff --git a/xorg-server/dix/cursor.c b/xorg-server/dix/cursor.c index 0017c661d..086d008e0 100644 --- a/xorg-server/dix/cursor.c +++ b/xorg-server/dix/cursor.c @@ -110,7 +110,7 @@ FreeCursorBits(CursorBitsPtr bits) * * \param value must conform to DeleteType */ -_X_EXPORT int +int FreeCursor(pointer value, XID cid) { int nscr; @@ -345,7 +345,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, unsigned char *mskptr; n = BitmapBytePad(cm.width)*(long)cm.height; - mskptr = mskbits = (unsigned char *)xalloc(n); + mskptr = mskbits = xalloc(n); if (!mskptr) return BadAlloc; while (--n >= 0) @@ -405,7 +405,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, else { bits->refcnt = 1; - pShare = (GlyphSharePtr)xalloc(sizeof(GlyphShare)); + pShare = xalloc(sizeof(GlyphShare)); if (!pShare) { FreeCursorBits(bits); @@ -515,7 +515,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, * add the cursor to the resource table *************************************************************/ -CursorPtr +CursorPtr CreateRootCursor(char *unused1, unsigned int unused2) { CursorPtr curs; @@ -545,8 +545,9 @@ CreateRootCursor(char *unused1, unsigned int unused2) if (err != Success) return NullCursor; - cursorfont = (FontPtr)LookupIDByType(fontID, RT_FONT); - if (!cursorfont) + err = dixLookupResourceByType((pointer *)&cursorfont, fontID, RT_FONT, + serverClient, DixReadAccess); + if (err != Success) return NullCursor; if (AllocGlyphCursor(fontID, 0, fontID, 1, 0, 0, 0, ~0, ~0, ~0, &curs, serverClient, (XID)0) != Success) diff --git a/xorg-server/dix/deprecated.c b/xorg-server/dix/deprecated.c index 4e20d6082..8123886ca 100644 --- a/xorg-server/dix/deprecated.c +++ b/xorg-server/dix/deprecated.c @@ -61,7 +61,7 @@ SOFTWARE. */ /* replaced by dixLookupWindow */ -_X_EXPORT WindowPtr +WindowPtr SecurityLookupWindow(XID id, ClientPtr client, Mask access_mode) { WindowPtr pWin; @@ -75,14 +75,14 @@ SecurityLookupWindow(XID id, ClientPtr client, Mask access_mode) } /* replaced by dixLookupWindow */ -_X_EXPORT WindowPtr +WindowPtr LookupWindow(XID id, ClientPtr client) { return SecurityLookupWindow(id, client, DixUnknownAccess); } /* replaced by dixLookupDrawable */ -_X_EXPORT pointer +pointer SecurityLookupDrawable(XID id, ClientPtr client, Mask access_mode) { DrawablePtr pDraw; @@ -96,14 +96,14 @@ SecurityLookupDrawable(XID id, ClientPtr client, Mask access_mode) } /* replaced by dixLookupDrawable */ -_X_EXPORT pointer +pointer LookupDrawable(XID id, ClientPtr client) { return SecurityLookupDrawable(id, client, DixUnknownAccess); } /* replaced by dixLookupClient */ -_X_EXPORT ClientPtr +ClientPtr LookupClient(XID id, ClientPtr client) { ClientPtr pClient; @@ -116,7 +116,7 @@ LookupClient(XID id, ClientPtr client) } /* replaced by dixLookupResourceByType */ -_X_EXPORT pointer +pointer SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask access_mode) { @@ -130,8 +130,7 @@ SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, return (i == Success) ? retval : NULL; } -/* replaced by dixLookupResourceByClass */ -_X_EXPORT pointer +pointer SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask access_mode) { @@ -146,17 +145,21 @@ SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, } /* replaced by dixLookupResourceByType */ -_X_EXPORT pointer +pointer LookupIDByType(XID id, RESTYPE rtype) { - return SecurityLookupIDByType(NullClient, id, rtype, DixUnknownAccess); + pointer val; + dixLookupResourceByType(&val, id, rtype, NullClient, DixUnknownAccess); + return val; } /* replaced by dixLookupResourceByClass */ -_X_EXPORT pointer +pointer LookupIDByClass(XID id, RESTYPE classes) { - return SecurityLookupIDByClass(NullClient, id, classes, DixUnknownAccess); + pointer val; + dixLookupResourceByClass(&val, id, classes, NullClient, DixUnknownAccess); + return val; } /* replaced by dixLookupResourceBy{Type,Class} */ diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index 3b8d544da..0be3d58ab 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -54,8 +54,6 @@ SOFTWARE. #include <X11/X.h> #include "misc.h" #include "resource.h" -#define NEED_EVENTS -#define NEED_REPLIES #include <X11/Xproto.h> #include <X11/Xatom.h> #include "windowstr.h" @@ -65,12 +63,7 @@ SOFTWARE. #include "dixstruct.h" #include "ptrveloc.h" #include "site.h" -#ifndef XKB_IN_SERVER -#define XKB_IN_SERVER -#endif -#ifdef XKB -#include <xkbsrv.h> -#endif +#include "xkbsrv.h" #include "privates.h" #include "xace.h" #include "mi.h" @@ -79,15 +72,18 @@ SOFTWARE. #include "swaprep.h" #include "dixevents.h" #include "mipointer.h" +#include "eventstr.h" #include <X11/extensions/XI.h> +#include <X11/extensions/XI2.h> #include <X11/extensions/XIproto.h> #include "exglobals.h" #include "exevents.h" -#include "listdev.h" /* for CopySwapXXXClass */ +#include "xiquerydevice.h" /* for SizeDeviceClasses */ #include "xiproperty.h" #include "enterleave.h" /* for EnterWindow() */ #include "xserver-properties.h" +#include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ /** @file * This file handles input device-related stuff. @@ -95,11 +91,13 @@ SOFTWARE. static int CoreDevicePrivateKeyIndex; DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKeyIndex; -/* Used to sture classes currently not in use by an MD */ +/* Used to store classes currently not in use by an MD */ static int UnusedClassesPrivateKeyIndex; DevPrivateKey UnusedClassesPrivateKey = &UnusedClassesPrivateKeyIndex; +static void RecalculateMasterButtons(DeviceIntPtr slave); + /** * DIX property handler. */ @@ -120,9 +118,9 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, if (!checkonly) { if ((*((CARD8*)prop->data)) && !dev->enabled) - EnableDevice(dev); + EnableDevice(dev, TRUE); else if (!(*((CARD8*)prop->data)) && dev->enabled) - DisableDevice(dev); + DisableDevice(dev, TRUE); } } @@ -142,7 +140,7 @@ PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) return BadDevice; /* Don't allow pairing for slave devices */ - if (!ptr->isMaster || !kbd->isMaster) + if (!IsMaster(ptr) || !IsMaster(kbd)) return BadDevice; if (ptr->spriteInfo->paired) @@ -170,7 +168,7 @@ NextFreePointerDevice(void) { DeviceIntPtr dev; for (dev = inputInfo.devices; dev; dev = dev->next) - if (dev->isMaster && + if (IsMaster(dev) && dev->spriteInfo->spriteOwner && !dev->spriteInfo->paired) return dev; @@ -193,13 +191,13 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) char devind[MAXDEVICES]; BOOL enabled; - /* Find next available id */ + /* Find next available id, 0 and 1 are reserved */ memset(devind, 0, sizeof(char)*MAXDEVICES); for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next) devind[devtmp->id]++; for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next) devind[devtmp->id]++; - for (devid = 0; devid < MAXDEVICES && devind[devid]; devid++) + for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++) ; if (devid >= MAXDEVICES) @@ -248,6 +246,22 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) return dev; } +static void +SendDevicePresenceEvent(int deviceid, int type) +{ + DeviceIntRec dummyDev; + devicePresenceNotify ev; + + memset(&dummyDev, 0, sizeof(DeviceIntRec)); + ev.type = DevicePresenceNotify; + ev.time = currentTime.milliseconds; + ev.devchange = type; + ev.deviceid = deviceid; + dummyDev.id = XIAllDevices; + SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, + (xEvent*)&ev, 1); +} + /** * Enable the device through the driver, add the device to the device list. * Switch device ON through the driver and push it onto the global device @@ -258,21 +272,20 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) * device. * * @param The device to be enabled. + * @param sendevent True if an XI2 event should be sent. * @return TRUE on success or FALSE otherwise. */ Bool -EnableDevice(DeviceIntPtr dev) +EnableDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr *prev; int ret; - DeviceIntRec dummyDev; DeviceIntPtr other; - devicePresenceNotify ev; - int namelen = 0; /* dummy */ int evsize = sizeof(xEvent); int listlen; EventListPtr evlist; BOOL enabled; + int flags[MAXDEVICES] = {0}; for (prev = &inputInfo.off_devices; *prev && (*prev != dev); @@ -281,7 +294,7 @@ EnableDevice(DeviceIntPtr dev) if (!dev->spriteInfo->sprite) { - if (dev->isMaster) + if (IsMaster(dev)) { /* Sprites appear on first root window, so we can hardcode it */ if (dev->spriteInfo->spriteOwner) @@ -310,7 +323,7 @@ EnableDevice(DeviceIntPtr dev) * device */ - SizeDeviceInfo(dev, &namelen, &evsize); + evsize += SizeDeviceClasses(dev); listlen = GetEventList(&evlist); OsBlockSignals(); @@ -337,13 +350,14 @@ EnableDevice(DeviceIntPtr dev) XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceEnabled; - ev.deviceid = dev->id; - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); + SendDevicePresenceEvent(dev->id, DeviceEnabled); + if (sendevent) + { + flags[dev->id] |= XIDeviceEnabled; + XISendDeviceHierarchyEvent(flags); + } + + RecalculateMasterButtons(dev); return TRUE; } @@ -356,15 +370,15 @@ EnableDevice(DeviceIntPtr dev) * Master keyboard devices have to be disabled before master pointer devices * otherwise things turn bad. * + * @param sendevent True if an XI2 event should be sent. * @return TRUE on success or FALSE otherwise. */ Bool -DisableDevice(DeviceIntPtr dev) +DisableDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr *prev, other; - DeviceIntRec dummyDev; - devicePresenceNotify ev; BOOL enabled; + int flags[MAXDEVICES] = {0}; for (prev = &inputInfo.devices; *prev && (*prev != dev); @@ -374,24 +388,27 @@ DisableDevice(DeviceIntPtr dev) return FALSE; /* float attached devices */ - if (dev->isMaster) + if (IsMaster(dev)) { for (other = inputInfo.devices; other; other = other->next) { if (other->u.master == dev) + { AttachDevice(NULL, other, NULL); + flags[other->id] |= XISlaveDetached; + } } } else { for (other = inputInfo.devices; other; other = other->next) { - if (other->isMaster && other->u.lastSlave == dev) + if (IsMaster(other) && other->u.lastSlave == dev) other->u.lastSlave = NULL; } } - if (dev->isMaster && dev->spriteInfo->sprite) + if (IsMaster(dev) && dev->spriteInfo->sprite) { for (other = inputInfo.devices; other; other = other->next) { @@ -406,6 +423,20 @@ DisableDevice(DeviceIntPtr dev) (void)(*dev->deviceProc)(dev, DEVICE_OFF); dev->enabled = FALSE; + + /* now that the device is disabled, we can reset the signal handler's + * last.slave */ + OsBlockSignals(); + for (other = inputInfo.devices; other; other = other->next) + { + if (other->last.slave == dev) + other->last.slave = NULL; + } + OsReleaseSignals(); + + LeaveWindow(dev); + SetFocusOut(dev); + *prev = dev->next; dev->next = inputInfo.off_devices; inputInfo.off_devices = dev; @@ -415,13 +446,14 @@ DisableDevice(DeviceIntPtr dev) XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceDisabled; - ev.deviceid = dev->id; - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); + SendDevicePresenceEvent(dev->id, DeviceDisabled); + if (sendevent) + { + flags[dev->id] = XIDeviceDisabled; + XISendDeviceHierarchyEvent(flags); + } + + RecalculateMasterButtons(dev); return TRUE; } @@ -433,14 +465,13 @@ DisableDevice(DeviceIntPtr dev) * Must be called before EnableDevice. * The device will NOT send events until it is enabled! * + * @param sendevent True if an XI2 event should be sent. * @return Success or an error code on failure. */ int -ActivateDevice(DeviceIntPtr dev) +ActivateDevice(DeviceIntPtr dev, BOOL sendevent) { int ret = Success; - devicePresenceNotify ev; - DeviceIntRec dummyDev; ScreenPtr pScreen = screenInfo.screens[0]; if (!dev || !dev->deviceProc) @@ -452,19 +483,16 @@ ActivateDevice(DeviceIntPtr dev) return ret; /* Initialize memory for sprites. */ - if (dev->isMaster && dev->spriteInfo->spriteOwner) + if (IsMaster(dev) && dev->spriteInfo->spriteOwner) pScreen->DeviceCursorInitialize(dev, pScreen); - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceAdded; - ev.deviceid = dev->id; - - memset(&dummyDev, 0, sizeof(DeviceIntRec)); - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); - + SendDevicePresenceEvent(dev->id, DeviceAdded); + if (sendevent) + { + int flags[MAXDEVICES] = {0}; + flags[dev->id] = XISlaveAdded; + XISendDeviceHierarchyEvent(flags); + } return ret; } @@ -489,94 +517,70 @@ CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl) /** * Device control function for the Virtual Core Keyboard. */ -static int +int CoreKeyboardProc(DeviceIntPtr pDev, int what) { - CARD8 *modMap; - KeySymsRec keySyms; -#ifdef XKB - XkbComponentNamesRec names; -#endif - ClassesPtr classes; switch (what) { case DEVICE_INIT: - if (!(classes = xcalloc(1, sizeof(ClassesRec)))) + if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell, + CoreKeyboardCtl)) { - ErrorF("[dix] Could not allocate device classes.\n"); - return BadAlloc; - } - - keySyms.minKeyCode = 8; - keySyms.maxKeyCode = 255; - keySyms.mapWidth = 4; - keySyms.map = (KeySym *)xcalloc(sizeof(KeySym), - (keySyms.maxKeyCode - - keySyms.minKeyCode + 1) * - keySyms.mapWidth); - if (!keySyms.map) { - ErrorF("[dix] Couldn't allocate core keymap\n"); - xfree(classes); - return BadAlloc; - } - - modMap = xcalloc(1, MAP_LENGTH); - if (!modMap) { - ErrorF("[dix] Couldn't allocate core modifier map\n"); - xfree(classes); - return BadAlloc; - } - -#ifdef XKB - if (!noXkbExtension) { - bzero(&names, sizeof(names)); - XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modMap, - CoreKeyboardBell, CoreKeyboardCtl); - } - else -#endif - { - /* FIXME Our keymap here isn't exactly useful. */ - InitKeyboardDeviceStruct((DevicePtr)pDev, &keySyms, modMap, - CoreKeyboardBell, CoreKeyboardCtl); + ErrorF("Keyboard initialization failed. This could be a missing " + "or incorrect setup of xkeyboard-config.\n"); + return BadValue; } + return Success; - xfree(keySyms.map); - xfree(modMap); - break; + case DEVICE_ON: + case DEVICE_OFF: + return Success; case DEVICE_CLOSE: - break; - - default: - break; + return Success; } - return Success; + + return BadMatch; } /** * Device control function for the Virtual Core Pointer. - * - * Aside from initialisation, it backs up the original device classes into the - * devicePrivates. This only needs to be done for master devices. */ -static int +int CorePointerProc(DeviceIntPtr pDev, int what) { - BYTE map[33]; +#define NBUTTONS 7 +#define NAXES 2 + BYTE map[NBUTTONS + 1]; int i = 0; - ClassesPtr classes; + Atom btn_labels[NBUTTONS] = {0}; + Atom axes_labels[NAXES] = {0}; switch (what) { case DEVICE_INIT: - if (!(classes = xcalloc(1, sizeof(ClassesRec)))) - return BadAlloc; - - for (i = 1; i <= 32; i++) + for (i = 1; i <= NBUTTONS; i++) map[i] = i; - InitPointerDeviceStruct((DevicePtr)pDev, map, 32, + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); + btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + /* don't know about the rest */ + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + + if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels, (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), 2); + GetMotionHistorySize(), NAXES, axes_labels)) + { + ErrorF("Could not initialize device '%s'. Out of memory.\n", + pDev->name); + return BadAlloc; /* IPDS only fails on allocs */ + } pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; pDev->last.valuators[0] = pDev->valuator->axisVal[0]; pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; @@ -591,6 +595,9 @@ CorePointerProc(DeviceIntPtr pDev, int what) } return Success; + +#undef NBUTTONS +#undef NAXES } /** @@ -604,16 +611,20 @@ CorePointerProc(DeviceIntPtr pDev, int what) void InitCoreDevices(void) { - if (AllocMasterDevice(serverClient, "Virtual core", - &inputInfo.pointer, - &inputInfo.keyboard) != Success) + if (AllocDevicePair(serverClient, "Virtual core", + &inputInfo.pointer, &inputInfo.keyboard, + CorePointerProc, CoreKeyboardProc, + TRUE) != Success) FatalError("Failed to allocate core devices"); - ActivateDevice(inputInfo.pointer); - ActivateDevice(inputInfo.keyboard); - EnableDevice(inputInfo.pointer); - EnableDevice(inputInfo.keyboard); + if (ActivateDevice(inputInfo.pointer, TRUE) != Success || + ActivateDevice(inputInfo.keyboard, TRUE) != Success) + FatalError("Failed to activate core devices."); + if (!EnableDevice(inputInfo.pointer, TRUE) || + !EnableDevice(inputInfo.keyboard, TRUE)) + FatalError("Failed to enable core devices."); + InitXTestDevices(); } /** @@ -629,14 +640,14 @@ InitCoreDevices(void) * @return Success or error code on failure. */ int -InitAndStartDevices() +InitAndStartDevices(void) { DeviceIntPtr dev, next; for (dev = inputInfo.off_devices; dev; dev = dev->next) { DebugF("(dix) initialising device %d\n", dev->id); if (!dev->inited) - ActivateDevice(dev); + ActivateDevice(dev, TRUE); } /* enable real devices */ @@ -645,7 +656,7 @@ InitAndStartDevices() DebugF("(dix) enabling device %d\n", dev->id); next = dev->next; if (dev->inited && dev->startup) - (void)EnableDevice(dev); + EnableDevice(dev, TRUE); } return Success; @@ -665,25 +676,19 @@ FreeDeviceClass(int type, pointer *class) case KeyClass: { KeyClassPtr* k = (KeyClassPtr*)class; -#ifdef XKB if ((*k)->xkbInfo) { XkbFreeInfo((*k)->xkbInfo); (*k)->xkbInfo = NULL; } -#endif - xfree((*k)->curKeySyms.map); - xfree((*k)->modifierKeyMap); xfree((*k)); break; } case ButtonClass: { ButtonClassPtr *b = (ButtonClassPtr*)class; -#ifdef XKB if ((*b)->xkb_acts) xfree((*b)->xkb_acts); -#endif xfree((*b)); break; } @@ -728,10 +733,8 @@ FreeFeedbackClass(int type, pointer *class) KbdFeedbackPtr k, knext; for (k = (*kbdfeed); k; k = knext) { knext = k->next; -#ifdef XKB if (k->xkb_sli) XkbFreeSrvLedInfo(k->xkb_sli); -#endif xfree(k); } break; @@ -789,10 +792,8 @@ FreeFeedbackClass(int type, pointer *class) for (l = (*leds); l; l = lnext) { lnext = l->next; -#ifdef XKB if (l->xkb_sli) XkbFreeSrvLedInfo(l->xkb_sli); -#endif xfree(l); } break; @@ -845,7 +846,7 @@ CloseDevice(DeviceIntPtr dev) (void)(*dev->deviceProc)(dev, DEVICE_CLOSE); /* free sprite memory */ - if (dev->isMaster && dev->spriteInfo->sprite) + if (IsMaster(dev) && dev->spriteInfo->sprite) screen->DeviceCursorCleanup(dev, screen); /* free acceleration info */ @@ -857,17 +858,14 @@ CloseDevice(DeviceIntPtr dev) classes = (ClassesPtr)&dev->key; FreeAllDeviceClasses(classes); - if (dev->isMaster) + if (IsMaster(dev)) { classes = dixLookupPrivate(&dev->devPrivates, UnusedClassesPrivateKey); FreeAllDeviceClasses(classes); } - -#ifdef XKB while (dev->xkb_interest) XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource); -#endif if (DevHasCursor(dev) && dev->spriteInfo->sprite) { xfree(dev->spriteInfo->sprite->spriteTrace); @@ -905,7 +903,7 @@ CloseDownDevices(void) */ for (dev = inputInfo.devices; dev; dev = dev->next) { - if (!dev->isMaster && dev->u.master) + if (!IsMaster(dev) && dev->u.master) dev->u.master = NULL; } @@ -924,9 +922,7 @@ CloseDownDevices(void) inputInfo.off_devices = NULL; inputInfo.keyboard = NULL; inputInfo.pointer = NULL; -#ifdef XKB XkbDeleteRulesDflts(); -#endif } /** @@ -934,7 +930,7 @@ CloseDownDevices(void) * resources are freed or any device is deleted. */ void -UndisplayDevices() +UndisplayDevices(void) { DeviceIntPtr dev; ScreenPtr screen = screenInfo.screens[0]; @@ -953,17 +949,18 @@ UndisplayDevices() * happen if a malloc fails during the addition of master devices. If * dev->init is FALSE it means the client never received a DeviceAdded event, * so let's not send a DeviceRemoved event either. + * + * @param sendevent True if an XI2 event should be sent. */ int -RemoveDevice(DeviceIntPtr dev) +RemoveDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr prev,tmp,next; int ret = BadMatch; - devicePresenceNotify ev; - DeviceIntRec dummyDev; ScreenPtr screen = screenInfo.screens[0]; int deviceid; int initialized; + int flags[MAXDEVICES] = {0}; DebugF("(dix) removing device %d\n", dev->id); @@ -971,11 +968,16 @@ RemoveDevice(DeviceIntPtr dev) return BadImplementation; initialized = dev->inited; - if (DevHasCursor(dev)) - screen->DisplayCursor(dev, screen, NullCursor); - deviceid = dev->id; - DisableDevice(dev); + + if (initialized) + { + if (DevHasCursor(dev)) + screen->DisplayCursor(dev, screen, NullCursor); + + DisableDevice(dev, sendevent); + flags[dev->id] = XIDeviceDisabled; + } prev = NULL; for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { @@ -987,6 +989,7 @@ RemoveDevice(DeviceIntPtr dev) else prev->next = next; + flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); ret = Success; } @@ -996,6 +999,7 @@ RemoveDevice(DeviceIntPtr dev) for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { next = tmp->next; if (tmp == dev) { + flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); if (prev == NULL) @@ -1009,13 +1013,9 @@ RemoveDevice(DeviceIntPtr dev) if (ret == Success && initialized) { inputInfo.numDevices--; - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceRemoved; - ev.deviceid = deviceid; - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); + SendDevicePresenceEvent(deviceid, DeviceRemoved); + if (sendevent) + XISendDeviceHierarchyEvent(flags); } return ret; @@ -1049,11 +1049,11 @@ dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode) *pDev = NULL; for (dev=inputInfo.devices; dev; dev=dev->next) { - if (dev->id == (CARD8)id) + if (dev->id == id) goto found; } for (dev=inputInfo.off_devices; dev; dev=dev->next) { - if (dev->id == (CARD8)id) + if (dev->id == id) goto found; } return BadDevice; @@ -1069,24 +1069,25 @@ void QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) { if (inputInfo.keyboard) { - *minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode; - *maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode; + *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code; + *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code; } } +/* Notably, this function does not expand the destination's keycode range, or + * notify clients. */ Bool SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) { int i, j; + KeySym *tmp; int rowDif = src->minKeyCode - dst->minKeyCode; /* if keysym map size changes, grow map first */ - if (src->mapWidth < dst->mapWidth) - { - for (i = src->minKeyCode; i <= src->maxKeyCode; i++) - { -#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c)) -#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c)) + if (src->mapWidth < dst->mapWidth) { + for (i = src->minKeyCode; i <= src->maxKeyCode; i++) { +#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c)) +#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c)) for (j = 0; j < src->mapWidth; j++) dst->map[DI(i, j)] = src->map[SI(i, j)]; for (j = src->mapWidth; j < dst->mapWidth; j++) @@ -1096,112 +1097,42 @@ SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) } return TRUE; } - else if (src->mapWidth > dst->mapWidth) - { - KeySym *map; - int bytes = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - map = (KeySym *)xcalloc(1, bytes); - if (!map) - return FALSE; - if (dst->map) - { - for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) - memmove((char *)&map[i*src->mapWidth], - (char *)&dst->map[i*dst->mapWidth], - dst->mapWidth * sizeof(KeySym)); - xfree(dst->map); - } - dst->mapWidth = src->mapWidth; - dst->map = map; - } else if (!dst->map) - { - KeySym *map; - int bytes = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - map = (KeySym *)xcalloc(1, bytes); - if (!map) + else if (src->mapWidth > dst->mapWidth) { + i = sizeof(KeySym) * src->mapWidth * + (dst->maxKeyCode - dst->minKeyCode + 1); + tmp = xcalloc(sizeof(KeySym), i); + if (!tmp) return FALSE; - dst->map = map; + + if (dst->map) { + for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) + memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth], + dst->mapWidth * sizeof(KeySym)); + xfree(dst->map); + } dst->mapWidth = src->mapWidth; + dst->map = tmp; } - memmove((char *)&dst->map[rowDif * dst->mapWidth], - (char *)src->map, - (int)(src->maxKeyCode - src->minKeyCode + 1) * - dst->mapWidth * sizeof(KeySym)); - return TRUE; -} - -static Bool -InitModMap(KeyClassPtr keyc) -{ - int i, j; - CARD8 keysPerModifier[8]; - CARD8 mask; + else if (!dst->map) { + i = sizeof(KeySym) * src->mapWidth * + (dst->maxKeyCode - dst->minKeyCode + 1); + tmp = xcalloc(sizeof(KeySym), i); + if (!tmp) + return FALSE; - keyc->maxKeysPerModifier = 0; - for (i = 0; i < 8; i++) - keysPerModifier[i] = 0; - for (i = 8; i < MAP_LENGTH; i++) - { - for (j = 0, mask = 1; j < 8; j++, mask <<= 1) - { - if (mask & keyc->modifierMap[i]) - { - if (++keysPerModifier[j] > keyc->maxKeysPerModifier) - keyc->maxKeysPerModifier = keysPerModifier[j]; - } - } - } - keyc->modifierKeyMap = xcalloc(8, keyc->maxKeysPerModifier); - if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier) - return (FALSE); - for (i = 0; i < 8; i++) - keysPerModifier[i] = 0; - for (i = 8; i < MAP_LENGTH; i++) - { - for (j = 0, mask = 1; j < 8; j++, mask <<= 1) - { - if (mask & keyc->modifierMap[i]) - { - keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) + - keysPerModifier[j]] = i; - keysPerModifier[j]++; - } - } + dst->map = tmp; + dst->mapWidth = src->mapWidth; } - return TRUE; -} -_X_EXPORT Bool -InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[]) -{ - KeyClassPtr keyc; + memmove(&dst->map[rowDif * dst->mapWidth], src->map, + (src->maxKeyCode - src->minKeyCode + 1) * + dst->mapWidth * sizeof(KeySym)); - keyc = xcalloc(1, sizeof(KeyClassRec)); - if (!keyc) - return FALSE; - keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode; - keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode; - if (pModifiers) - memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH); - if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc)) - { - xfree(keyc->curKeySyms.map); - xfree(keyc->modifierKeyMap); - xfree(keyc); - return FALSE; - } - dev->key = keyc; -#ifdef XKB - dev->key->xkbInfo= NULL; - if (!noXkbExtension) XkbInitDevice(dev); -#endif return TRUE; } _X_EXPORT Bool -InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, +InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels, CARD8 *map) { ButtonClassPtr butc; @@ -1211,14 +1142,18 @@ InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, if (!butc) return FALSE; butc->numButtons = numButtons; + butc->sourceid = dev->id; for (i = 1; i <= numButtons; i++) butc->map[i] = map[i]; + for (i = numButtons + 1; i < MAP_LENGTH; i++) + butc->map[i] = i; + memcpy(butc->labels, labels, numButtons * sizeof(Atom)); dev->button = butc; return TRUE; } -_X_EXPORT Bool -InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, +Bool +InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, int numMotionEvents, int mode) { int i; @@ -1227,12 +1162,21 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, if (!dev) return FALSE; + if (numAxes >= MAX_VALUATORS) + { + LogMessage(X_WARNING, + "Device '%s' has %d axes, only using first %d.\n", + dev->name, numAxes, MAX_VALUATORS); + numAxes = MAX_VALUATORS; + } + valc = (ValuatorClassPtr)xcalloc(1, sizeof(ValuatorClassRec) + numAxes * sizeof(AxisInfo) + - numAxes * sizeof(unsigned int)); + numAxes * sizeof(double)); if (!valc) return FALSE; + valc->sourceid = dev->id; valc->motion = NULL; valc->first_motion = 0; valc->last_motion = 0; @@ -1242,19 +1186,21 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, valc->numAxes = numAxes; valc->mode = mode; valc->axes = (AxisInfoPtr)(valc + 1); - valc->axisVal = (int *)(valc->axes + numAxes); + valc->axisVal = (double *)(valc->axes + numAxes); dev->valuator = valc; AllocateMotionHistory(dev); for (i=0; i<numAxes; i++) { - InitValuatorAxisStruct(dev, i, NO_AXIS_LIMITS, NO_AXIS_LIMITS, + InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0); valc->axisVal[i]=0; } dev->last.numValuators = numAxes; - if(dev->isMaster) /* master devs do not accelerate */ + + if (IsMaster(dev) || /* do not accelerate master or xtest devices */ + IsXTestDevice(dev, NULL)) InitPointerAccelerationScheme(dev, PtrAccelNoOp); else InitPointerAccelerationScheme(dev, PtrAccelDefault); @@ -1273,7 +1219,7 @@ ValuatorAccelerationRec pointerAccelerationScheme[] = { * install an acceleration scheme. returns TRUE on success, and should not * change anything if unsuccessful. */ -_X_EXPORT Bool +Bool InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme) { @@ -1286,8 +1232,8 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, if(!val) return FALSE; - if(dev->isMaster && (scheme != PtrAccelNoOp)) - scheme = PtrAccelNoOp; /* no accel for master devices */ + if(IsMaster(dev) && scheme != PtrAccelNoOp) + return FALSE; for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) { if(pointerAccelerationScheme[x].number == scheme){ @@ -1305,7 +1251,7 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, case PtrAccelPredictable: { DeviceVelocityPtr s; - s = (DeviceVelocityPtr)xalloc(sizeof(DeviceVelocityRec)); + s = xalloc(sizeof(DeviceVelocityRec)); if(!s) return FALSE; InitVelocityData(s); @@ -1319,15 +1265,25 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, val->accelScheme = pointerAccelerationScheme[i]; val->accelScheme.accelData = data; + /* post-init scheme */ + switch(scheme){ + case PtrAccelPredictable: + InitializePredictableAccelerationProperties(dev); + break; + + default: + break; + } + return TRUE; } -_X_EXPORT Bool +Bool InitAbsoluteClassDeviceStruct(DeviceIntPtr dev) { AbsoluteClassPtr abs; - abs = (AbsoluteClassPtr)xalloc(sizeof(AbsoluteClassRec)); + abs = xalloc(sizeof(AbsoluteClassRec)); if (!abs) return FALSE; @@ -1348,17 +1304,19 @@ InitAbsoluteClassDeviceStruct(DeviceIntPtr dev) abs->following = 0; abs->screen = 0; + abs->sourceid = dev->id; + dev->absolute = abs; return TRUE; } -_X_EXPORT Bool +Bool InitFocusClassDeviceStruct(DeviceIntPtr dev) { FocusClassPtr focc; - focc = (FocusClassPtr)xalloc(sizeof(FocusClassRec)); + focc = xalloc(sizeof(FocusClassRec)); if (!focc) return FALSE; focc->win = PointerRootWin; @@ -1367,44 +1325,17 @@ InitFocusClassDeviceStruct(DeviceIntPtr dev) focc->trace = (WindowPtr *)NULL; focc->traceSize = 0; focc->traceGood = 0; + focc->sourceid = dev->id; dev->focus = focc; return TRUE; } _X_EXPORT Bool -InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc, - KbdCtrlProcPtr controlProc) -{ - KbdFeedbackPtr feedc; - - feedc = (KbdFeedbackPtr)xalloc(sizeof(KbdFeedbackClassRec)); - if (!feedc) - return FALSE; - feedc->BellProc = bellProc; - feedc->CtrlProc = controlProc; -#ifdef XKB - defaultKeyboardControl.autoRepeat = TRUE; -#endif - feedc->ctrl = defaultKeyboardControl; - feedc->ctrl.id = 0; - if ((feedc->next = dev->kbdfeed) != 0) - feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1; - dev->kbdfeed = feedc; -#ifdef XKB - feedc->xkb_sli= NULL; - if (!noXkbExtension) - XkbFinishDeviceInit(dev); -#endif - (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl); - return TRUE; -} - -_X_EXPORT Bool InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc) { PtrFeedbackPtr feedc; - feedc = (PtrFeedbackPtr)xalloc(sizeof(PtrFeedbackClassRec)); + feedc = xalloc(sizeof(PtrFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1434,7 +1365,7 @@ static IntegerCtrl defaultIntegerControl = { DEFAULT_INT_DISPLAYED, 0}; -_X_EXPORT Bool +Bool InitStringFeedbackClassDeviceStruct ( DeviceIntPtr dev, StringCtrlProcPtr controlProc, int max_symbols, int num_symbols_supported, KeySym *symbols) @@ -1442,17 +1373,15 @@ InitStringFeedbackClassDeviceStruct ( int i; StringFeedbackPtr feedc; - feedc = (StringFeedbackPtr)xalloc(sizeof(StringFeedbackClassRec)); + feedc = xalloc(sizeof(StringFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; feedc->ctrl.num_symbols_supported = num_symbols_supported; feedc->ctrl.num_symbols_displayed = 0; feedc->ctrl.max_symbols = max_symbols; - feedc->ctrl.symbols_supported = (KeySym *) - xalloc (sizeof (KeySym) * num_symbols_supported); - feedc->ctrl.symbols_displayed = (KeySym *) - xalloc (sizeof (KeySym) * max_symbols); + feedc->ctrl.symbols_supported = xalloc (sizeof (KeySym) * num_symbols_supported); + feedc->ctrl.symbols_displayed = xalloc (sizeof (KeySym) * max_symbols); if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) { if (feedc->ctrl.symbols_supported) @@ -1465,7 +1394,7 @@ InitStringFeedbackClassDeviceStruct ( for (i=0; i<num_symbols_supported; i++) *(feedc->ctrl.symbols_supported+i) = *symbols++; for (i=0; i<max_symbols; i++) - *(feedc->ctrl.symbols_displayed+i) = (KeySym) NULL; + *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0; feedc->ctrl.id = 0; if ( (feedc->next = dev->stringfeed) ) feedc->ctrl.id = dev->stringfeed->ctrl.id + 1; @@ -1474,13 +1403,13 @@ InitStringFeedbackClassDeviceStruct ( return TRUE; } -_X_EXPORT Bool +Bool InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc, BellCtrlProcPtr controlProc) { BellFeedbackPtr feedc; - feedc = (BellFeedbackPtr)xalloc(sizeof(BellFeedbackClassRec)); + feedc = xalloc(sizeof(BellFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1494,12 +1423,12 @@ InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc, return TRUE; } -_X_EXPORT Bool +Bool InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc) { LedFeedbackPtr feedc; - feedc = (LedFeedbackPtr)xalloc(sizeof(LedFeedbackClassRec)); + feedc = xalloc(sizeof(LedFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1507,20 +1436,18 @@ InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc) feedc->ctrl.id = 0; if ( (feedc->next = dev->leds) ) feedc->ctrl.id = dev->leds->ctrl.id + 1; -#ifdef XKB feedc->xkb_sli= NULL; -#endif dev->leds = feedc; (*controlProc)(dev, &feedc->ctrl); return TRUE; } -_X_EXPORT Bool +Bool InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc) { IntegerFeedbackPtr feedc; - feedc = (IntegerFeedbackPtr)xalloc(sizeof(IntegerFeedbackClassRec)); + feedc = xalloc(sizeof(IntegerFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1533,70 +1460,19 @@ InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr contr return TRUE; } -_X_EXPORT Bool -InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, +Bool +InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels, PtrCtrlProcPtr controlProc, int numMotionEvents, - int numAxes) + int numAxes, Atom *axes_labels) { DeviceIntPtr dev = (DeviceIntPtr)device; - return(InitButtonClassDeviceStruct(dev, numButtons, map) && - InitValuatorClassDeviceStruct(dev, numAxes, + return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) && + InitValuatorClassDeviceStruct(dev, numAxes, axes_labels, numMotionEvents, 0) && InitPtrFeedbackClassDeviceStruct(dev, controlProc)); } -_X_EXPORT Bool -InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms, - CARD8 pModifiers[], BellProcPtr bellProc, - KbdCtrlProcPtr controlProc) -{ - DeviceIntPtr dev = (DeviceIntPtr)device; - - return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) && - InitFocusClassDeviceStruct(dev) && - InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc)); -} - -_X_EXPORT void -SendMappingNotify(DeviceIntPtr pDev, unsigned request, unsigned firstKeyCode, - unsigned count, ClientPtr client) -{ - int i; - xEvent event; - - event.u.u.type = MappingNotify; - event.u.mappingNotify.request = request; - if (request == MappingKeyboard) - { - event.u.mappingNotify.firstKeyCode = firstKeyCode; - event.u.mappingNotify.count = count; - } -#ifdef XKB - if (!noXkbExtension && - ((request == MappingKeyboard) || (request == MappingModifier))) { - XkbApplyMappingChange(pDev,request,firstKeyCode,count, client); - } -#endif - - /* 0 is the server client */ - for (i=1; i<currentMaxClients; i++) - { - if (clients[i] && clients[i]->clientState == ClientStateRunning) - { -#ifdef XKB - if (!noXkbExtension && - (request == MappingKeyboard) && - (clients[i]->xkbClientFlags != 0) && - (clients[i]->mapNotifyMask&XkbKeySymsMask)) - continue; -#endif - event.u.u.sequenceNumber = clients[i]->sequence; - WriteEventsToClient(clients[i], 1, &event); - } - } -} - /* * Check if the given buffer contains elements between low (inclusive) and * high (inclusive) only. @@ -1620,131 +1496,32 @@ BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval) return FALSE; } -Bool -AllModifierKeysAreUp(dev, map1, per1, map2, per2) - DeviceIntPtr dev; - CARD8 *map1, *map2; - int per1, per2; -{ - int i, j, k; - CARD8 *down = dev->key->down; - - for (i = 8; --i >= 0; map2 += per2) - { - for (j = per1; --j >= 0; map1++) - { - if (*map1 && BitIsOn(down, *map1)) - { - for (k = per2; (--k >= 0) && (*map1 != map2[k]);) - ; - if (k < 0) - return FALSE; - } - } - } - return TRUE; -} - -static int -DoSetModifierMapping(ClientPtr client, KeyCode *inputMap, - int numKeyPerModifier, xSetModifierMappingReply *rep) -{ - DeviceIntPtr pDev = NULL; - DeviceIntPtr cp = PickKeyboard(client); /* ClientPointer keyboard */ - int rc, i = 0, inputMapLen = numKeyPerModifier * 8; - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if (pDev == cp || (!pDev->isMaster && (pDev->u.master == cp) && pDev->key)) { - for (i = 0; i < inputMapLen; i++) { - /* Check that all the new modifiers fall within the advertised - * keycode range, and are okay with the DDX. */ - if (inputMap[i] && ((inputMap[i] < pDev->key->curKeySyms.minKeyCode || - inputMap[i] > pDev->key->curKeySyms.maxKeyCode) || - !LegalModifier(inputMap[i], pDev))) { - client->errorValue = inputMap[i]; - return BadValue; - } - } - - rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (rc != Success) - return rc; - - /* None of the modifiers (old or new) may be down while we change - * the map. */ - if (!AllModifierKeysAreUp(pDev, pDev->key->modifierKeyMap, - pDev->key->maxKeysPerModifier, - inputMap, numKeyPerModifier) || - !AllModifierKeysAreUp(pDev, inputMap, numKeyPerModifier, - pDev->key->modifierKeyMap, - pDev->key->maxKeysPerModifier)) { - rep->success = MappingBusy; - return Success; - } - } - } - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) { - bzero(pDev->key->modifierMap, MAP_LENGTH); - - /* Annoyingly, we lack a modifierKeyMap size, so we have to just free - * and re-alloc it every time. */ - if (pDev->key->modifierKeyMap) - xfree(pDev->key->modifierKeyMap); - - if (inputMapLen) { - pDev->key->modifierKeyMap = (KeyCode *) xalloc(inputMapLen); - if (!pDev->key->modifierKeyMap) - return BadAlloc; - - memcpy(pDev->key->modifierKeyMap, inputMap, inputMapLen); - pDev->key->maxKeysPerModifier = numKeyPerModifier; - - for (i = 0; i < inputMapLen; i++) { - if (inputMap[i]) { - pDev->key->modifierMap[inputMap[i]] |= - (1 << (((unsigned int)i) / numKeyPerModifier)); - } - } - } - else { - pDev->key->modifierKeyMap = NULL; - pDev->key->maxKeysPerModifier = 0; - } - } - } - - rep->success = Success; - return Success; -} - int ProcSetModifierMapping(ClientPtr client) { xSetModifierMappingReply rep; - DeviceIntPtr dev; int rc; REQUEST(xSetModifierMappingReq); REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); if (client->req_len != ((stuff->numKeyPerModifier << 1) + - (sizeof (xSetModifierMappingReq) >> 2))) + bytes_to_int32(sizeof(xSetModifierMappingReq)))) return BadLength; rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; - rc = DoSetModifierMapping(client, (KeyCode *)&stuff[1], - stuff->numKeyPerModifier, &rep); - if (rc != Success) + rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1], + stuff->numKeyPerModifier); + if (rc == MappingFailed || rc == -1) + return BadValue; + if (rc != Success && rc != MappingSuccess && rc != MappingFailed && + rc != MappingBusy) return rc; - for (dev = inputInfo.devices; dev; dev = dev->next) - if (dev->key && dev->coreEvents) - SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev); + rep.success = rc; + WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); return client->noClientException; } @@ -1753,26 +1530,27 @@ int ProcGetModifierMapping(ClientPtr client) { xGetModifierMappingReply rep; - DeviceIntPtr dev = PickKeyboard(client); - KeyClassPtr keyc = dev->key; - int rc; + int ret, max_keys_per_mod = 0; + KeyCode *modkeymap = NULL; REQUEST_SIZE_MATCH(xReq); - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); - if (rc != Success) - return rc; + ret = generate_modkeymap(client, PickKeyboard(client), &modkeymap, + &max_keys_per_mod); + if (ret != Success) + return ret; + memset(&rep, 0, sizeof(xGetModifierMappingReply)); rep.type = X_Reply; - rep.numKeyPerModifier = keyc->maxKeysPerModifier; + rep.numKeyPerModifier = max_keys_per_mod; rep.sequenceNumber = client->sequence; /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ - rep.length = keyc->maxKeysPerModifier << 1; + rep.length = max_keys_per_mod << 1; WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); + (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); + + xfree(modkeymap); - /* Use the (modified by DDX) map that SetModifierMapping passed in */ - (void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3), - (char *)keyc->modifierKeyMap); return client->noClientException; } @@ -1782,76 +1560,56 @@ ProcChangeKeyboardMapping(ClientPtr client) REQUEST(xChangeKeyboardMappingReq); unsigned len; KeySymsRec keysyms; - KeySymsPtr curKeySyms = &PickKeyboard(client)->key->curKeySyms; - DeviceIntPtr pDev = NULL; + DeviceIntPtr pDev, tmp; int rc; REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); - len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq)); if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) return BadLength; - if ((stuff->firstKeyCode < curKeySyms->minKeyCode) || - (stuff->firstKeyCode > curKeySyms->maxKeyCode)) { + pDev = PickKeyboard(client); + + if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) || + (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) { client->errorValue = stuff->firstKeyCode; return BadValue; } if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) > - curKeySyms->maxKeyCode) || (stuff->keySymsPerKeyCode == 0)) { + pDev->key->xkbInfo->desc->max_key_code) || + (stuff->keySymsPerKeyCode == 0)) { client->errorValue = stuff->keySymsPerKeyCode; return BadValue; } - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (rc != Success) - return rc; - } - } - keysyms.minKeyCode = stuff->firstKeyCode; keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; keysyms.mapWidth = stuff->keySymsPerKeyCode; - keysyms.map = (KeySym *)&stuff[1]; - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) - if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms)) - return BadAlloc; - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - if (pDev->key && pDev->coreEvents) - SendDeviceMappingNotify(client, MappingKeyboard, - stuff->firstKeyCode, stuff->keyCodes, - pDev); + keysyms.map = (KeySym *) &stuff[1]; - return client->noClientException; -} + rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); + if (rc != Success) + return rc; -static int -DoSetPointerMapping(ClientPtr client, DeviceIntPtr device, BYTE *map, int n) -{ - int rc, i = 0; + XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, + stuff->keyCodes, NULL, client); - if (!device || !device->button) - return BadDevice; + for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { + if (IsMaster(tmp) || tmp->u.master != pDev) + continue; + if (!tmp->key) + continue; - rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixManageAccess); - if (rc != Success) - return rc; + rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); + if (rc != Success) + continue; - for (i = 0; i < n; i++) { - if ((device->button->map[i + 1] != map[i]) && - BitIsOn(device->button->down, i + 1)) { - return MappingBusy; - } + XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, + stuff->keyCodes, NULL, client); } - for (i = 0; i < n; i++) - device->button->map[i + 1] = map[i]; - - return Success; + return client->noClientException; } int @@ -1865,7 +1623,8 @@ ProcSetPointerMapping(ClientPtr client) REQUEST(xSetPointerMappingReq); REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); - if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2) + if (client->req_len != + bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) return BadLength; rep.type = X_Reply; rep.length = 0; @@ -1883,30 +1642,26 @@ ProcSetPointerMapping(ClientPtr client) client->errorValue = stuff->nElts; return BadValue; } - if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue)) - return BadValue; - /* core protocol specs don't allow for duplicate mappings. */ - for (i = 0; i < stuff->nElts; i++) - { - for (j = i + 1; j < stuff->nElts; j++) - { - if (map[i] && map[i] == map[j]) - { + /* Core protocol specs don't allow for duplicate mappings; this check + * almost certainly wants disabling through XFixes too. */ + for (i = 0; i < stuff->nElts; i++) { + for (j = i + 1; j < stuff->nElts; j++) { + if (map[i] && map[i] == map[j]) { client->errorValue = map[i]; return BadValue; } } } - ret = DoSetPointerMapping(client, ptr, map, stuff->nElts); - if (ret != Success) { + ret = ApplyPointerMapping(ptr, map, stuff->nElts, client); + if (ret == MappingBusy) rep.success = ret; - WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); - return Success; - } + else if (ret == -1) + return BadValue; + else if (ret != Success) + return ret; - SendMappingNotify(ptr, MappingPointer, 0, 0, client); WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); return Success; } @@ -1916,7 +1671,8 @@ ProcGetKeyboardMapping(ClientPtr client) { xGetKeyboardMappingReply rep; DeviceIntPtr kbd = PickKeyboard(client); - KeySymsPtr curKeySyms = &kbd->key->curKeySyms; + XkbDescPtr xkb; + KeySymsPtr syms; int rc; REQUEST(xGetKeyboardMappingReq); REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); @@ -1925,29 +1681,36 @@ ProcGetKeyboardMapping(ClientPtr client) if (rc != Success) return rc; - if ((stuff->firstKeyCode < curKeySyms->minKeyCode) || - (stuff->firstKeyCode > curKeySyms->maxKeyCode)) { + xkb = kbd->key->xkbInfo->desc; + + if ((stuff->firstKeyCode < xkb->min_key_code) || + (stuff->firstKeyCode > xkb->max_key_code)) { client->errorValue = stuff->firstKeyCode; return BadValue; } - if (stuff->firstKeyCode + stuff->count > - (unsigned)(curKeySyms->maxKeyCode + 1)) { + if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { client->errorValue = stuff->count; return BadValue; } + syms = XkbGetCoreMap(kbd); + if (!syms) + return BadAlloc; + + memset(&rep, 0, sizeof(xGetKeyboardMappingReply)); rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.keySymsPerKeyCode = curKeySyms->mapWidth; + rep.keySymsPerKeyCode = syms->mapWidth; /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ - rep.length = (curKeySyms->mapWidth * stuff->count); + rep.length = syms->mapWidth * stuff->count; WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; - WriteSwappedDataToClient( - client, - curKeySyms->mapWidth * stuff->count * sizeof(KeySym), - &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) * - curKeySyms->mapWidth]); + WriteSwappedDataToClient(client, + syms->mapWidth * stuff->count * sizeof(KeySym), + &syms->map[syms->mapWidth * (stuff->firstKeyCode - + syms->minKeyCode)]); + xfree(syms->map); + xfree(syms); return client->noClientException; } @@ -1969,10 +1732,11 @@ ProcGetPointerMapping(ClientPtr client) rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.nElts = butc->numButtons; + rep.nElts = (butc) ? butc->numButtons : 0; rep.length = ((unsigned)rep.nElts + (4-1))/4; WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); - (void)WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]); + if (butc) + WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]); return Success; } @@ -1986,7 +1750,7 @@ NoteLedState(DeviceIntPtr keybd, int led, Bool on) ctrl->leds &= ~((Leds)1 << (led - 1)); } -_X_EXPORT int +int Ones(unsigned long mask) /* HACKMEM 169 */ { unsigned long y; @@ -2007,6 +1771,7 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, int key = DO_ALL; BITS32 index2; int mask = vmask, i; + XkbEventCauseRec cause; ctrl = keybd->kbdfeed->ctrl; while (vmask) { @@ -2089,21 +1854,18 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, client->errorValue = t; return BadValue; } -#ifdef XKB - if (!noXkbExtension) { - XkbEventCauseRec cause; - XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client); - XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))), - ctrl.leds, &cause); - ctrl.leds = keybd->kbdfeed->ctrl.leds; - } -#endif + + XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client); + XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))), + ctrl.leds, &cause); + ctrl.leds = keybd->kbdfeed->ctrl.leds; + break; case KBKey: key = (KeyCode)*vlist; vlist++; - if ((KeyCode)key < keybd->key->curKeySyms.minKeyCode || - (KeyCode)key > keybd->key->curKeySyms.maxKeyCode) { + if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code || + (KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) { client->errorValue = key; return BadValue; } @@ -2115,10 +1877,8 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, mask = (1 << (key & 7)); t = (CARD8)*vlist; vlist++; -#ifdef XKB - if (!noXkbExtension && key != DO_ALL) + if (key != DO_ALL) XkbDisableComputedAutoRepeats(keybd,key); -#endif if (t == AutoRepeatModeOff) { if (key == DO_ALL) ctrl.autoRepeat = FALSE; @@ -2151,27 +1911,25 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, } keybd->kbdfeed->ctrl = ctrl; -#ifdef XKB /* The XKB RepeatKeys control and core protocol global autorepeat */ /* value are linked */ - if (!noXkbExtension) - XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); - else -#endif - (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl); + XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); return Success; #undef DO_ALL } +/** + * Changes kbd control on the ClientPointer and all attached SDs. + */ int ProcChangeKeyboardControl (ClientPtr client) { XID *vlist; BITS32 vmask; int ret = Success, error = Success; - DeviceIntPtr pDev = NULL; + DeviceIntPtr pDev = NULL, keyboard; REQUEST(xChangeKeyboardControlReq); REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); @@ -2182,8 +1940,10 @@ ProcChangeKeyboardControl (ClientPtr client) if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask)) return BadLength; + keyboard = PickKeyboard(client); + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && + if ((pDev == keyboard || (!IsMaster(keyboard) && pDev->u.master == keyboard)) && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); if (ret != Success) @@ -2192,7 +1952,7 @@ ProcChangeKeyboardControl (ClientPtr client) } for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && + if ((pDev == keyboard || (!IsMaster(keyboard) && pDev->u.master == keyboard)) && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { ret = DoChangeKeyboardControl(client, pDev, vlist, vmask); if (ret != Success) @@ -2234,13 +1994,18 @@ ProcGetKeyboardControl (ClientPtr client) int ProcBell(ClientPtr client) { - DeviceIntPtr keybd = PickKeyboard(client); + DeviceIntPtr dev, keybd = PickKeyboard(client); int base = keybd->kbdfeed->ctrl.bell; int newpercent; int rc; REQUEST(xBellReq); REQUEST_SIZE_MATCH(xBellReq); + if (stuff->percent < -100 || stuff->percent > 100) { + client->errorValue = stuff->percent; + return BadValue; + } + /* Seems like no keyboard actually has the BellProc set. Returning * BadDevice (previous code) will make apps crash badly. The man pages * doesn't say anything about a BadDevice being returned either. @@ -2249,32 +2014,21 @@ ProcBell(ClientPtr client) if (!keybd->kbdfeed->BellProc) return Success; - if (stuff->percent < -100 || stuff->percent > 100) { - client->errorValue = stuff->percent; - return BadValue; - } - newpercent = (base * stuff->percent) / 100; if (stuff->percent < 0) newpercent = base + newpercent; else newpercent = base - newpercent + stuff->percent; - for (keybd = inputInfo.devices; keybd; keybd = keybd->next) { - if ((keybd->coreEvents || keybd == inputInfo.keyboard) && - keybd->kbdfeed && keybd->kbdfeed->BellProc) { + for (dev = inputInfo.devices; dev; dev = dev->next) { + if ((dev == keybd || (!IsMaster(dev) && dev->u.master == keybd)) && + dev->kbdfeed && dev->kbdfeed->BellProc) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixBellAccess); + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess); if (rc != Success) return rc; -#ifdef XKB - if (!noXkbExtension) - XkbHandleBell(FALSE, FALSE, keybd, newpercent, - &keybd->kbdfeed->ctrl, 0, None, NULL, client); - else -#endif - (*keybd->kbdfeed->BellProc)(newpercent, keybd, - &keybd->kbdfeed->ctrl, 0); + XkbHandleBell(FALSE, FALSE, dev, newpercent, + &dev->kbdfeed->ctrl, 0, None, NULL, client); } } @@ -2284,7 +2038,7 @@ ProcBell(ClientPtr client) int ProcChangePointerControl(ClientPtr client) { - DeviceIntPtr mouse = PickPointer(client); + DeviceIntPtr dev, mouse = PickPointer(client); PtrCtrl ctrl; /* might get BadValue part way through */ int rc; REQUEST(xChangePointerControlReq); @@ -2338,20 +2092,20 @@ ProcChangePointerControl(ClientPtr client) } } - for (mouse = inputInfo.devices; mouse; mouse = mouse->next) { - if ((mouse->coreEvents || mouse == inputInfo.pointer) && - mouse->ptrfeed && mouse->ptrfeed->CtrlProc) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixManageAccess); + for (dev = inputInfo.devices; dev; dev = dev->next) { + if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) && + dev->ptrfeed && dev->ptrfeed->CtrlProc) { + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); if (rc != Success) return rc; } } - for (mouse = inputInfo.devices; mouse; mouse = mouse->next) { - if ((mouse->coreEvents || mouse == PickPointer(client)) && - mouse->ptrfeed && mouse->ptrfeed->CtrlProc) { - mouse->ptrfeed->ctrl = ctrl; - (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl); + for (dev = inputInfo.devices; dev; dev = dev->next) { + if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) && + dev->ptrfeed && dev->ptrfeed->CtrlProc) { + dev->ptrfeed->ctrl = ctrl; + (*dev->ptrfeed->CtrlProc)(dev, &mouse->ptrfeed->ctrl); } } @@ -2449,7 +2203,7 @@ ProcGetMotionEvents(ClientPtr client) nEvents++; } } - rep.length = nEvents * (sizeof(xTimecoord) >> 2); + rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord)); rep.nEvents = nEvents; WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); if (nEvents) @@ -2488,6 +2242,77 @@ ProcQueryKeymap(ClientPtr client) return Success; } + +/** + * Recalculate the number of buttons for the master device. The number of + * buttons on the master device is equal to the number of buttons on the + * slave device with the highest number of buttons. + */ +static void +RecalculateMasterButtons(DeviceIntPtr slave) +{ + DeviceIntPtr dev, master; + int maxbuttons = 0; + + if (!slave->button || IsMaster(slave)) + return; + + master = GetMaster(slave, MASTER_POINTER); + if (!master) + return; + + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsMaster(dev) || + dev->u.master != master || + !dev->button) + continue; + + maxbuttons = max(maxbuttons, dev->button->numButtons); + } + + if (master->button->numButtons != maxbuttons) + { + int i; + DeviceChangedEvent event; + + memset(&event, 0, sizeof(event)); + + master->button->numButtons = maxbuttons; + + event.header = ET_Internal; + event.type = ET_DeviceChanged; + event.time = CurrentTime; + event.deviceid = master->id; + event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE; + event.buttons.num_buttons = maxbuttons; + memcpy(&event.buttons.names, master->button->labels, maxbuttons * + sizeof(Atom)); + + if (master->valuator) + { + event.num_valuators = master->valuator->numAxes; + for (i = 0; i < event.num_valuators; i++) + { + event.valuators[i].min = master->valuator->axes[i].min_value; + event.valuators[i].max = master->valuator->axes[i].max_value; + event.valuators[i].resolution = master->valuator->axes[i].resolution; + /* This should, eventually, be a per-axis mode */ + event.valuators[i].mode = master->valuator->mode; + event.valuators[i].name = master->valuator->axes[i].label; + } + } + + if (master->key) + { + event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; + event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; + } + + XISendDeviceChangedEvent(master, master, &event); + } +} + /** * Attach device 'dev' to device 'master'. * Client is set to the client that issued the request, or NULL if it comes @@ -2503,10 +2328,10 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) { ScreenPtr screen; DeviceIntPtr oldmaster; - if (!dev || dev->isMaster) + if (!dev || IsMaster(dev)) return BadDevice; - if (master && !master->isMaster) /* can't attach to slaves */ + if (master && !IsMaster(master)) /* can't attach to slaves */ return BadDevice; /* set from floating to floating? */ @@ -2540,12 +2365,13 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) InitializeSprite(dev, currentRoot); dev->spriteInfo->spriteOwner = FALSE; dev->spriteInfo->paired = dev; - } else { dev->spriteInfo->sprite = master->spriteInfo->sprite; dev->spriteInfo->paired = master; dev->spriteInfo->spriteOwner = FALSE; + + RecalculateMasterButtons(master); } /* If we were connected to master device before, this MD may need to @@ -2555,8 +2381,22 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) { DeviceIntPtr it; for (it = inputInfo.devices; it; it = it->next) - if (!it->isMaster && it->u.master == oldmaster) + if (!IsMaster(it) && it->u.master == oldmaster) break; + + if (!it) /* no dev is paired with old master */ + { + EventListPtr event = NULL; + + /* XXX: reset master back to defaults */ + event = InitEventList(1); + SetMinimumEventSize(event, 1, sizeof(DeviceChangedEvent)); + CreateClassesChangedEvent(event, oldmaster, oldmaster, + DEVCHANGE_POINTER_EVENT | DEVCHANGE_KEYBOARD_EVENT); + XISendDeviceChangedEvent(oldmaster, oldmaster, + (DeviceChangedEvent*)event->event); + FreeEventList(event, 1); + } } return Success; @@ -2567,10 +2407,10 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) * Returns the device paired with the parent master if the given device is a * slave device. */ -_X_EXPORT DeviceIntPtr +DeviceIntPtr GetPairedDevice(DeviceIntPtr dev) { - if (!dev->isMaster && dev->u.master) + if (!IsMaster(dev) && dev->u.master) dev = dev->u.master; return dev->spriteInfo->paired; @@ -2578,19 +2418,61 @@ GetPairedDevice(DeviceIntPtr dev) /** - * Create a new master device (== one pointer, one keyboard device). + * Returns the right master for the type of event needed. If the event is a + * keyboard event. + * This function may be called with a master device as argument. If so, the + * returned master is either the device itself or the paired master device. + * If dev is a floating slave device, NULL is returned. + * + * @type ::MASTER_KEYBOARD or ::MASTER_POINTER + */ +DeviceIntPtr +GetMaster(DeviceIntPtr dev, int which) +{ + DeviceIntPtr master; + + if (IsMaster(dev)) + master = dev; + else + master = dev->u.master; + + if (master) + { + if (which == MASTER_KEYBOARD) + { + if (master->type != MASTER_KEYBOARD) + master = GetPairedDevice(master); + } else + { + if (master->type != MASTER_POINTER) + master = GetPairedDevice(master); + } + } + + return master; +} + +/** + * Create a new device pair (== one pointer, one keyboard device). * Only allocates the devices, you will need to call ActivateDevice() and * EnableDevice() manually. + * Either a master or a slave device can be created depending on + * the value for master. */ int -AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* keybd) +AllocDevicePair (ClientPtr client, char* name, + DeviceIntPtr* ptr, + DeviceIntPtr* keybd, + DeviceProc ptr_proc, + DeviceProc keybd_proc, + Bool master) { DeviceIntPtr pointer; DeviceIntPtr keyboard; ClassesPtr classes; *ptr = *keybd = NULL; - pointer = AddInputDevice(client, CorePointerProc, TRUE); + pointer = AddInputDevice(client, ptr_proc, TRUE); if (!pointer) return BadAlloc; @@ -2598,27 +2480,22 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* strcpy(pointer->name, name); strcat(pointer->name, " pointer"); -#ifdef XKB pointer->public.processInputProc = ProcessOtherEvent; pointer->public.realInputProc = ProcessOtherEvent; - if (!noXkbExtension) - XkbSetExtension(pointer, ProcessPointerEvent); -#else - pointer->public.processInputProc = ProcessPointerEvent; - pointer->public.realInputProc = ProcessPointerEvent; -#endif + XkbSetExtension(pointer, ProcessPointerEvent); pointer->deviceGrab.ActivateGrab = ActivatePointerGrab; pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab; pointer->coreEvents = TRUE; pointer->spriteInfo->spriteOwner = TRUE; pointer->u.lastSlave = NULL; - pointer->isMaster = TRUE; + pointer->last.slave = NULL; + pointer->type = (master) ? MASTER_POINTER : SLAVE; - keyboard = AddInputDevice(client, CoreKeyboardProc, TRUE); + keyboard = AddInputDevice(client, keybd_proc, TRUE); if (!keyboard) { - RemoveDevice(pointer); + RemoveDevice(pointer, FALSE); return BadAlloc; } @@ -2626,22 +2503,17 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* strcpy(keyboard->name, name); strcat(keyboard->name, " keyboard"); -#ifdef XKB keyboard->public.processInputProc = ProcessOtherEvent; keyboard->public.realInputProc = ProcessOtherEvent; - if (!noXkbExtension) - XkbSetExtension(keyboard, ProcessKeyboardEvent); -#else - keyboard->public.processInputProc = ProcessKeyboardEvent; - keyboard->public.realInputProc = ProcessKeyboardEvent; -#endif + XkbSetExtension(keyboard, ProcessKeyboardEvent); keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab; keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; keyboard->coreEvents = TRUE; keyboard->spriteInfo->spriteOwner = FALSE; keyboard->u.lastSlave = NULL; - keyboard->isMaster = TRUE; + keyboard->last.slave = NULL; + keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; /* The ClassesRec stores the device classes currently not used. */ @@ -2655,3 +2527,4 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* return Success; } + diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index b4f5f437f..76ed70f66 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -107,6 +107,7 @@ Equipment Corporation. #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#include <version-config.h> #endif #ifdef CreateWindow @@ -134,19 +135,11 @@ int ProcInitialConnection(); #include "dispatch.h" #include "swaprep.h" #include "swapreq.h" -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif #include "privates.h" #include "xace.h" -#ifdef XKB -#ifndef XKB_IN_SERVER -#define XKB_IN_SERVER -#endif #include "inputstr.h" -#include <xkbsrv.h> -#endif +#include "xkbsrv.h" +#include "site.h" #ifdef XSERVER_DTRACE #include "registry.h" @@ -163,7 +156,9 @@ typedef const char *string; #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) -extern xConnSetupPrefix connSetupPrefix; +xConnSetupPrefix connSetupPrefix; + +PaddingInfo PixmapWidthPaddingInfo[33]; static ClientPtr grabClient; #define GrabNone 0 @@ -171,9 +166,9 @@ static ClientPtr grabClient; #define GrabKickout 2 static int grabState = GrabNone; static long grabWaiters[mskcnt]; -_X_EXPORT CallbackListPtr ServerGrabCallback = NULL; +CallbackListPtr ServerGrabCallback = NULL; HWEventQueuePtr checkForInput[2]; -extern int connBlockScreenStart; +int connBlockScreenStart; static void KillAllClients(void); @@ -181,15 +176,15 @@ static int nextFreeClientID; /* always MIN free client ID */ static int nClients; /* number of authorized clients */ -_X_EXPORT CallbackListPtr ClientStateCallback; +CallbackListPtr ClientStateCallback; /* dispatchException & isItTimeToYield must be declared volatile since they * are modified by signal handlers - otherwise optimizer may assume it doesn't * need to actually check value in memory when used and may miss changes from * signal handlers. */ -_X_EXPORT volatile char dispatchException = 0; -_X_EXPORT volatile char isItTimeToYield; +volatile char dispatchException = 0; +volatile char isItTimeToYield; /* Various of the DIX function interfaces were not designed to allow * the client->errorValue to be set on BadValue and other errors. @@ -208,7 +203,7 @@ SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) checkForInput[1] = c1; } -_X_EXPORT void +void UpdateCurrentTime(void) { TimeStamp systime; @@ -227,7 +222,7 @@ UpdateCurrentTime(void) } /* Like UpdateCurrentTime, but can't call ProcessInputEvents */ -_X_EXPORT void +void UpdateCurrentTimeIf(void) { TimeStamp systime; @@ -246,12 +241,12 @@ UpdateCurrentTimeIf(void) #define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ #define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ -Bool SmartScheduleDisable = FALSE; -long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; -long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; -long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; -long SmartScheduleTime; -int SmartScheduleLatencyLimited = 0; +Bool SmartScheduleDisable = FALSE; +long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; +long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; +long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; +long SmartScheduleTime; +int SmartScheduleLatencyLimited = 0; static ClientPtr SmartLastClient; static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; @@ -374,7 +369,7 @@ Dispatch(void) nextFreeClientID = 1; nClients = 0; - clientReady = (int *) xalloc(sizeof(int) * MaxClients); + clientReady = xalloc(sizeof(int) * MaxClients); if (!clientReady) return; @@ -441,12 +436,6 @@ Dispatch(void) } client->sequence++; -#ifdef DEBUG - if (client->requestLogIndex == MAX_REQUEST_LOG) - client->requestLogIndex = 0; - client->requestLog[client->requestLogIndex] = MAJOROP; - client->requestLogIndex++; -#endif #ifdef XSERVER_DTRACE XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP, ((xReq *)client->requestBuffer)->length, @@ -494,7 +483,167 @@ Dispatch(void) #undef MAJOROP -_X_EXPORT int +static int VendorRelease = VENDOR_RELEASE; +static char *VendorString = VENDOR_NAME; + +static const int padlength[4] = {0, 3, 2, 1}; + +void +SetVendorRelease(int release) +{ + VendorRelease = release; +} + +void +SetVendorString(char *string) +{ + VendorString = string; +} + +Bool +CreateConnectionBlock(void) +{ + xConnSetup setup; + xWindowRoot root; + xDepth depth; + xVisualType visual; + xPixmapFormat format; + unsigned long vid; + int i, j, k, + lenofblock, + sizesofar = 0; + char *pBuf; + + + memset(&setup, 0, sizeof(xConnSetup)); + /* Leave off the ridBase and ridMask, these must be sent with + connection */ + + setup.release = VendorRelease; + /* + * per-server image and bitmap parameters are defined in Xmd.h + */ + setup.imageByteOrder = screenInfo.imageByteOrder; + + setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; + setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; + + setup.bitmapBitOrder = screenInfo.bitmapBitOrder; + setup.motionBufferSize = NumMotionEvents(); + setup.numRoots = screenInfo.numScreens; + setup.nbytesVendor = strlen(VendorString); + setup.numFormats = screenInfo.numPixmapFormats; + setup.maxRequestSize = MAX_REQUEST_SIZE; + QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); + + lenofblock = sizeof(xConnSetup) + + pad_to_int32(setup.nbytesVendor) + + (setup.numFormats * sizeof(xPixmapFormat)) + + (setup.numRoots * sizeof(xWindowRoot)); + ConnectionInfo = xalloc(lenofblock); + if (!ConnectionInfo) + return FALSE; + + memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup)); + sizesofar = sizeof(xConnSetup); + pBuf = ConnectionInfo + sizeof(xConnSetup); + + memmove(pBuf, VendorString, (int)setup.nbytesVendor); + sizesofar += setup.nbytesVendor; + pBuf += setup.nbytesVendor; + i = padlength[setup.nbytesVendor & 3]; + sizesofar += i; + while (--i >= 0) + *pBuf++ = 0; + + memset(&format, 0, sizeof(xPixmapFormat)); + for (i=0; i<screenInfo.numPixmapFormats; i++) + { + format.depth = screenInfo.formats[i].depth; + format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; + format.scanLinePad = screenInfo.formats[i].scanlinePad; + memmove(pBuf, (char *)&format, sizeof(xPixmapFormat)); + pBuf += sizeof(xPixmapFormat); + sizesofar += sizeof(xPixmapFormat); + } + + connBlockScreenStart = sizesofar; + memset(&depth, 0, sizeof(xDepth)); + memset(&visual, 0, sizeof(xVisualType)); + for (i=0; i<screenInfo.numScreens; i++) + { + ScreenPtr pScreen; + DepthPtr pDepth; + VisualPtr pVisual; + + pScreen = screenInfo.screens[i]; + root.windowId = WindowTable[i]->drawable.id; + root.defaultColormap = pScreen->defColormap; + root.whitePixel = pScreen->whitePixel; + root.blackPixel = pScreen->blackPixel; + root.currentInputMask = 0; /* filled in when sent */ + root.pixWidth = pScreen->width; + root.pixHeight = pScreen->height; + root.mmWidth = pScreen->mmWidth; + root.mmHeight = pScreen->mmHeight; + root.minInstalledMaps = pScreen->minInstalledCmaps; + root.maxInstalledMaps = pScreen->maxInstalledCmaps; + root.rootVisualID = pScreen->rootVisual; + root.backingStore = pScreen->backingStoreSupport; + root.saveUnders = FALSE; + root.rootDepth = pScreen->rootDepth; + root.nDepths = pScreen->numDepths; + memmove(pBuf, (char *)&root, sizeof(xWindowRoot)); + sizesofar += sizeof(xWindowRoot); + pBuf += sizeof(xWindowRoot); + + pDepth = pScreen->allowedDepths; + for(j = 0; j < pScreen->numDepths; j++, pDepth++) + { + lenofblock += sizeof(xDepth) + + (pDepth->numVids * sizeof(xVisualType)); + pBuf = (char *)xrealloc(ConnectionInfo, lenofblock); + if (!pBuf) + { + xfree(ConnectionInfo); + return FALSE; + } + ConnectionInfo = pBuf; + pBuf += sizesofar; + depth.depth = pDepth->depth; + depth.nVisuals = pDepth->numVids; + memmove(pBuf, (char *)&depth, sizeof(xDepth)); + pBuf += sizeof(xDepth); + sizesofar += sizeof(xDepth); + for(k = 0; k < pDepth->numVids; k++) + { + vid = pDepth->vids[k]; + for (pVisual = pScreen->visuals; + pVisual->vid != vid; + pVisual++) + ; + visual.visualID = vid; + visual.class = pVisual->class; + visual.bitsPerRGB = pVisual->bitsPerRGBValue; + visual.colormapEntries = pVisual->ColormapEntries; + visual.redMask = pVisual->redMask; + visual.greenMask = pVisual->greenMask; + visual.blueMask = pVisual->blueMask; + memmove(pBuf, (char *)&visual, sizeof(xVisualType)); + pBuf += sizeof(xVisualType); + sizesofar += sizeof(xVisualType); + } + } + } + connSetupPrefix.success = xTrue; + connSetupPrefix.length = lenofblock/4; + connSetupPrefix.majorVersion = X_PROTOCOL; + connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; + return TRUE; +} + + +int ProcBadRequest(ClientPtr client) { return (BadRequest); @@ -513,7 +662,7 @@ ProcCreateWindow(ClientPtr client) rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); if (rc != Success) return rc; - len = client->req_len - (sizeof(xCreateWindowReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); if (Ones(stuff->mask) != len) return BadLength; if (!stuff->width || !stuff->height) @@ -556,7 +705,7 @@ ProcChangeWindowAttributes(ClientPtr client) rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); if (rc != Success) return rc; - len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); if (len != Ones(stuff->valueMask)) return BadLength; result = ChangeWindowAttributes(pWin, @@ -581,6 +730,7 @@ ProcGetWindowAttributes(ClientPtr client) rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); if (rc != Success) return rc; + memset(&wa, 0, sizeof(xGetWindowAttributesReply)); GetWindowAttributes(pWin, client, &wa); WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); return(client->noClientException); @@ -759,7 +909,7 @@ ProcConfigureWindow(ClientPtr client) DixManageAccess|DixSetAttrAccess); if (rc != Success) return rc; - len = client->req_len - (sizeof(xConfigureWindowReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); if (Ones((Mask)stuff->mask) != len) return BadLength; result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], @@ -842,6 +992,7 @@ ProcGetGeometry(ClientPtr client) xGetGeometryReply rep; int status; + memset(&rep, 0, sizeof(xGetGeometryReply)); if ((status = GetGeometry(client, &rep)) != Success) return status; @@ -863,6 +1014,7 @@ ProcQueryTree(ClientPtr client) rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); if (rc != Success) return rc; + memset(&reply, 0, sizeof(xQueryTreeReply)); reply.type = X_Reply; reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; reply.sequenceNumber = client->sequence; @@ -877,7 +1029,7 @@ ProcQueryTree(ClientPtr client) { int curChild = 0; - childIDs = (Window *) xalloc(numChildren * sizeof(Window)); + childIDs = xalloc(numChildren * sizeof(Window)); if (!childIDs) return BadAlloc; for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) @@ -885,7 +1037,7 @@ ProcQueryTree(ClientPtr client) } reply.nChildren = numChildren; - reply.length = (numChildren * sizeof(Window)) >> 2; + reply.length = bytes_to_int32(numChildren * sizeof(Window)); WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); if (numChildren) @@ -916,6 +1068,7 @@ ProcInternAtom(ClientPtr client) if (atom != BAD_RESOURCE) { xInternAtomReply reply; + memset(&reply, 0, sizeof(xInternAtomReply)); reply.type = X_Reply; reply.length = 0; reply.sequenceNumber = client->sequence; @@ -930,7 +1083,7 @@ ProcInternAtom(ClientPtr client) int ProcGetAtomName(ClientPtr client) { - char *str; + const char *str; xGetAtomNameReply reply; int len; REQUEST(xResourceReq); @@ -939,8 +1092,9 @@ ProcGetAtomName(ClientPtr client) if ( (str = NameForAtom(stuff->id)) ) { len = strlen(str); + memset(&reply, 0, sizeof(xGetAtomNameReply)); reply.type = X_Reply; - reply.length = (len + 3) >> 2; + reply.length = bytes_to_int32(len); reply.sequenceNumber = client->sequence; reply.nameLength = len; WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); @@ -1035,6 +1189,7 @@ ProcTranslateCoords(ClientPtr client) rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); if (rc != Success) return rc; + memset(&rep, 0, sizeof(xTranslateCoordsReply)); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1115,12 +1270,13 @@ int ProcCloseFont(ClientPtr client) { FontPtr pFont; + int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); - pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT, - DixDestroyAccess); - if ( pFont != (FontPtr)NULL) /* id was valid */ + rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, + client, DixDestroyAccess); + if (rc == Success) { FreeResource(stuff->id, RT_NONE); return(client->noClientException); @@ -1128,7 +1284,7 @@ ProcCloseFont(ClientPtr client) else { client->errorValue = stuff->id; - return (BadFont); + return (rc == BadValue) ? BadFont : rc; } } @@ -1171,14 +1327,14 @@ ProcQueryFont(ClientPtr client) rlength = sizeof(xQueryFontReply) + FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + nprotoxcistructs * sizeof(xCharInfo); - reply = (xQueryFontReply *)xalloc(rlength); + reply = xcalloc(1, rlength); if(!reply) { return(BadAlloc); } reply->type = X_Reply; - reply->length = (rlength - sizeof(xGenericReply)) >> 2; + reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); reply->sequenceNumber = client->sequence; QueryFont( pFont, reply, nprotoxcistructs); @@ -1212,7 +1368,7 @@ ProcQueryTextExtents(ClientPtr client) if (rc != Success) return (rc == BadValue) ? BadFont: rc; - length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2); + length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq)); length = length << 1; if (stuff->oddLength) { @@ -1380,7 +1536,7 @@ ProcCreateGC(ClientPtr client) if (rc != Success) return rc; - len = client->req_len - (sizeof(xCreateGCReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); if (len != Ones(stuff->mask)) return BadLength; pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, @@ -1405,7 +1561,7 @@ ProcChangeGC(ClientPtr client) if (result != Success) return result; - len = client->req_len - (sizeof(xChangeGCReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); if (len != Ones(stuff->mask)) return BadLength; @@ -1655,7 +1811,7 @@ ProcPolyPoint(ClientPtr client) return BadValue; } VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2; + npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); if (npoint) (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint, (xPoint *) &stuff[1]); @@ -1678,7 +1834,7 @@ ProcPolyLine(ClientPtr client) return BadValue; } VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2; + npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); if (npoint > 1) (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, (DDXPointPtr) &stuff[1]); @@ -1766,7 +1922,7 @@ ProcFillPoly(ClientPtr client) } VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2; + things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); if (things) (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, stuff->coordMode, things, @@ -1910,8 +2066,8 @@ ProcPutImage(ClientPtr client) tmpImage = (char *)&stuff[1]; lengthProto = length; - if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + - (sizeof(xPutImageReq) >> 2)) != client->req_len) + if ((bytes_to_int32(lengthProto * stuff->height) + + bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) return BadLength; ReformatImage (tmpImage, lengthProto * stuff->height, @@ -1930,9 +2086,11 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, int x, int y, int width, int height, Mask planemask, xGetImageReply **im_return) { - DrawablePtr pDraw; + DrawablePtr pDraw, pBoundingDraw; int nlines, linesPerBuf, rc; - int linesDone; + int linesDone; + /* coordinates relative to the bounding drawable */ + int relx, rely; long widthBytesLine, length; Mask plane = 0; char *pBuf; @@ -1948,35 +2106,60 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, if (rc != Success) return rc; + memset(&xgi, 0, sizeof(xGetImageReply)); + + relx = x; + rely = y; + if(pDraw->type == DRAWABLE_WINDOW) { - if( /* check for being viewable */ - !((WindowPtr) pDraw)->realized || - /* check for being on screen */ - pDraw->x + x < 0 || - pDraw->x + x + width > pDraw->pScreen->width || - pDraw->y + y < 0 || - pDraw->y + y + height > pDraw->pScreen->height || - /* check for being inside of border */ - x < - wBorderWidth((WindowPtr)pDraw) || - x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || - y < -wBorderWidth((WindowPtr)pDraw) || - y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height - ) - return(BadMatch); - xgi.visual = wVisual (((WindowPtr) pDraw)); + WindowPtr pWin = (WindowPtr)pDraw; + + /* "If the drawable is a window, the window must be viewable ... or a + * BadMatch error results" */ + if (!pWin->viewable) + return BadMatch; + + relx += pDraw->x; + rely += pDraw->y; + + if (pDraw->pScreen->GetWindowPixmap) { + PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); + + pBoundingDraw = &pPix->drawable; +#ifdef COMPOSITE + relx -= pPix->screen_x; + rely -= pPix->screen_y; +#endif + } + else + { + pBoundingDraw = (DrawablePtr)WindowTable[pDraw->pScreen->myNum]; + } + + xgi.visual = wVisual (pWin); } else { - if(x < 0 || - x+width > (int)pDraw->width || - y < 0 || - y+height > (int)pDraw->height - ) - return(BadMatch); + pBoundingDraw = pDraw; xgi.visual = None; } + /* "If the drawable is a pixmap, the given rectangle must be wholly + * contained within the pixmap, or a BadMatch error results. If the + * drawable is a window [...] it must be the case that if there were no + * inferiors or overlapping windows, the specified rectangle of the window + * would be fully visible on the screen and wholly contained within the + * outside edges of the window, or a BadMatch error results." + * + * We relax the window case slightly to mean that the rectangle must exist + * within the bounds of the window's backing pixmap. In particular, this + * means that a GetImage request may succeed or fail with BadMatch depending + * on whether any of its ancestor windows are redirected. */ + if(relx < 0 || relx + width > (int)pBoundingDraw->width || + rely < 0 || rely + height > (int)pBoundingDraw->height) + return BadMatch; + xgi.type = X_Reply; xgi.sequenceNumber = client->sequence; xgi.depth = pDraw->depth; @@ -1999,7 +2182,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, xgi.length = length; if (im_return) { - pBuf = (char *)xalloc(sz_xGetImageReply + length); + pBuf = xcalloc(1, sz_xGetImageReply + length); if (!pBuf) return (BadAlloc); if (widthBytesLine == 0) @@ -2010,7 +2193,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, *(xGetImageReply *)pBuf = xgi; pBuf += sz_xGetImageReply; } else { - xgi.length = (xgi.length + 3) >> 2; + xgi.length = bytes_to_int32(xgi.length); if (widthBytesLine == 0 || height == 0) linesPerBuf = 0; else if (widthBytesLine >= IMAGE_BUFSIZE) @@ -2037,7 +2220,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, length += widthBytesLine; } } - if(!(pBuf = (char *) xalloc(length))) + if(!(pBuf = xcalloc(1, length))) return (BadAlloc); WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); } @@ -2409,8 +2592,7 @@ ProcListInstalledColormaps(ClientPtr client) if (rc != Success) goto out; - preply = (xListInstalledColormapsReply *) - xalloc(sizeof(xListInstalledColormapsReply) + + preply = xalloc(sizeof(xListInstalledColormapsReply) + pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap)); if(!preply) @@ -2554,7 +2736,7 @@ ProcAllocColorCells (ClientPtr client) } nmasks = stuff->planes; length = ((long)npixels + (long)nmasks) * sizeof(Pixel); - ppixels = (Pixel *)xalloc(length); + ppixels = xalloc(length); if(!ppixels) return(BadAlloc); pmasks = ppixels + npixels; @@ -2573,7 +2755,7 @@ ProcAllocColorCells (ClientPtr client) #endif { accr.type = X_Reply; - accr.length = length >> 2; + accr.length = bytes_to_int32(length); accr.sequenceNumber = client->sequence; accr.nPixels = npixels; accr.nMasks = nmasks; @@ -2623,7 +2805,7 @@ ProcAllocColorPlanes(ClientPtr client) acpr.sequenceNumber = client->sequence; acpr.nPixels = npixels; length = (long)npixels * sizeof(Pixel); - ppixels = (Pixel *)xalloc(length); + ppixels = xalloc(length); if(!ppixels) return(BadAlloc); if( (rc = AllocColorPlanes(client->index, pcmp, npixels, @@ -2637,7 +2819,7 @@ ProcAllocColorPlanes(ClientPtr client) else return rc; } - acpr.length = length >> 2; + acpr.length = bytes_to_int32(length); #ifdef PANORAMIX if (noPanoramiXExtension || !pcmp->pScreen->myNum) #endif @@ -2672,7 +2854,7 @@ ProcFreeColors(ClientPtr client) if(pcmp->flags & AllAllocated) return(BadAccess); - count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2; + count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); rc = FreeColors(pcmp, client->index, count, (Pixel *)&stuff[1], (Pixel)stuff->planeMask); if (client->noClientException != Success) @@ -2775,8 +2957,8 @@ ProcQueryColors(ClientPtr client) xrgb *prgbs; xQueryColorsReply qcr; - count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2; - prgbs = (xrgb *)xalloc(count * sizeof(xrgb)); + count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); + prgbs = xcalloc(1, count * sizeof(xrgb)); if(!prgbs && count) return(BadAlloc); if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) ) @@ -2790,8 +2972,9 @@ ProcQueryColors(ClientPtr client) return rc; } } + memset(&qcr, 0, sizeof(xQueryColorsReply)); qcr.type = X_Reply; - qcr.length = (count * sizeof(xrgb)) >> 2; + qcr.length = bytes_to_int32(count * sizeof(xrgb)); qcr.sequenceNumber = client->sequence; qcr.nColors = count; WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); @@ -3017,6 +3200,7 @@ ProcQueryBestSize (ClientPtr client) return rc; (* pScreen->QueryBestSize)(stuff->class, &stuff->width, &stuff->height, pScreen); + memset(&reply, 0, sizeof(xQueryBestSizeReply)); reply.type = X_Reply; reply.length = 0; reply.sequenceNumber = client->sequence; @@ -3160,7 +3344,7 @@ ProcListHosts(ClientPtr client) reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.nHosts = nHosts; - reply.length = len >> 2; + reply.length = bytes_to_int32(len); WriteReplyToClient(client, sizeof(xListHostsReply), &reply); if (nHosts) { @@ -3293,7 +3477,7 @@ ProcGetFontPath(ClientPtr client) reply.type = X_Reply; reply.sequenceNumber = client->sequence; - reply.length = (stringLens + numpaths + 3) >> 2; + reply.length = bytes_to_int32(stringLens + numpaths); reply.nPaths = numpaths; WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); @@ -3484,41 +3668,16 @@ KillAllClients(void) void InitClient(ClientPtr client, int i, pointer ospriv) { + memset(client, 0, sizeof(*client)); client->index = i; - client->sequence = 0; client->clientAsMask = ((Mask)i) << CLIENTOFFSET; - client->clientGone = FALSE; client->closeDownMode = i ? DestroyAll : RetainPermanent; - client->numSaved = 0; - client->saveSet = (SaveSetElt *)NULL; - client->noClientException = Success; -#ifdef DEBUG - client->requestLogIndex = 0; -#endif client->requestVector = InitialVector; client->osPrivate = ospriv; - client->swapped = FALSE; - client->big_requests = FALSE; - client->priority = 0; - client->clientState = ClientStateInitial; - client->devPrivates = NULL; -#ifdef XKB - if (!noXkbExtension) { - client->xkbClientFlags = 0; - client->mapNotifyMask = 0; - client->newKeyboardNotifyMask = 0; - client->vMinor = client->vMajor = 0; - QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); - } -#endif - client->replyBytesRemaining = 0; - client->fontResFunc = NULL; - client->smart_priority = 0; + QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); client->smart_start_tick = SmartScheduleTime; client->smart_stop_tick = SmartScheduleTime; client->smart_check_tick = SmartScheduleTime; - - client->clientPtr = NULL; } /************************ @@ -3537,7 +3696,7 @@ ClientPtr NextAvailableClient(pointer ospriv) i = nextFreeClientID; if (i == MAXCLIENTS) return (ClientPtr)NULL; - clients[i] = client = (ClientPtr)xalloc(sizeof(ClientRec)); + clients[i] = client = xalloc(sizeof(ClientRec)); if (!client) return (ClientPtr)NULL; InitClient(client, i, ospriv); @@ -3547,7 +3706,7 @@ ClientPtr NextAvailableClient(pointer ospriv) return (ClientPtr)NULL; } data.reqType = 1; - data.length = (sz_xReq + sz_xConnClientPrefix) >> 2; + data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); if (!InsertFakeRequest(client, (char *)&data, sz_xReq)) { FreeClientResources(client); @@ -3587,8 +3746,8 @@ ProcInitialConnection(ClientPtr client) SwapConnClientPrefix(prefix); } stuff->reqType = 2; - stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) + - ((prefix->nbytesAuthString + (unsigned)3) >> 2); + stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + + bytes_to_int32(prefix->nbytesAuthString); if (client->swapped) { swaps(&stuff->length, whichbyte); @@ -3612,7 +3771,7 @@ SendConnSetup(ClientPtr client, char *reason) csp.success = xFalse; csp.lengthReason = strlen(reason); - csp.length = (csp.lengthReason + (unsigned)3) >> 2; + csp.length = bytes_to_int32(csp.lengthReason); csp.majorVersion = X_PROTOCOL; csp.minorVersion = X_PROTOCOL_REVISION; if (client->swapped) @@ -3703,7 +3862,7 @@ ProcEstablishConnection(ClientPtr client) prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); auth_proto = (char *)prefix + sz_xConnClientPrefix; - auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3); + auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); if ((prefix->majorVersion != X_PROTOCOL) || (prefix->minorVersion != X_PROTOCOL_REVISION)) reason = "Protocol version mismatch"; @@ -3728,12 +3887,13 @@ ProcEstablishConnection(ClientPtr client) return(client->noClientException); } -_X_EXPORT void +void SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, XID resId, int errorCode) { xError rep; + memset(&rep, 0, sizeof(xError)); rep.type = X_Error; rep.sequenceNumber = client->sequence; rep.errorCode = errorCode; @@ -3749,3 +3909,172 @@ MarkClientException(ClientPtr client) { client->noClientException = -1; } + +/* + * This array encodes the answer to the question "what is the log base 2 + * of the number of pixels that fit in a scanline pad unit?" + * Note that ~0 is an invalid entry (mostly for the benefit of the reader). + */ +static int answer[6][4] = { + /* pad pad pad pad*/ + /* 8 16 32 64 */ + + { 3, 4, 5 , 6 }, /* 1 bit per pixel */ + { 1, 2, 3 , 4 }, /* 4 bits per pixel */ + { 0, 1, 2 , 3 }, /* 8 bits per pixel */ + { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ + { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ + { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ +}; + +/* + * This array gives the answer to the question "what is the first index for + * the answer array above given the number of bits per pixel?" + * Note that ~0 is an invalid entry (mostly for the benefit of the reader). + */ +static int indexForBitsPerPixel[ 33 ] = { + ~0, 0, ~0, ~0, /* 1 bit per pixel */ + 1, ~0, ~0, ~0, /* 4 bits per pixel */ + 2, ~0, ~0, ~0, /* 8 bits per pixel */ + ~0,~0, ~0, ~0, + 3, ~0, ~0, ~0, /* 16 bits per pixel */ + ~0,~0, ~0, ~0, + 4, ~0, ~0, ~0, /* 24 bits per pixel */ + ~0,~0, ~0, ~0, + 5 /* 32 bits per pixel */ +}; + +/* + * This array gives the bytesperPixel value for cases where the number + * of bits per pixel is a multiple of 8 but not a power of 2. + */ +static int answerBytesPerPixel[ 33 ] = { + ~0, 0, ~0, ~0, /* 1 bit per pixel */ + 0, ~0, ~0, ~0, /* 4 bits per pixel */ + 0, ~0, ~0, ~0, /* 8 bits per pixel */ + ~0,~0, ~0, ~0, + 0, ~0, ~0, ~0, /* 16 bits per pixel */ + ~0,~0, ~0, ~0, + 3, ~0, ~0, ~0, /* 24 bits per pixel */ + ~0,~0, ~0, ~0, + 0 /* 32 bits per pixel */ +}; + +/* + * This array gives the answer to the question "what is the second index for + * the answer array above given the number of bits per scanline pad unit?" + * Note that ~0 is an invalid entry (mostly for the benefit of the reader). + */ +static int indexForScanlinePad[ 65 ] = { + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ + ~0, ~0, ~0, ~0, + 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + 3 /* 64 bits per scanline pad unit */ +}; + +/* + grow the array of screenRecs if necessary. + call the device-supplied initialization procedure +with its screen number, a pointer to its ScreenRec, argc, and argv. + return the number of successfully installed screens. + +*/ + +int +AddScreen( + Bool (* pfnInit)( + int /*index*/, + ScreenPtr /*pScreen*/, + int /*argc*/, + char ** /*argv*/ + ), + int argc, + char **argv) +{ + + int i; + int scanlinepad, format, depth, bitsPerPixel, j, k; + ScreenPtr pScreen; + + i = screenInfo.numScreens; + if (i == MAXSCREENS) + return -1; + + pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec)); + if (!pScreen) + return -1; + + pScreen->devPrivates = NULL; + pScreen->myNum = i; + pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8); + pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ + pScreen->CreateScreenResources = 0; + + /* + * This loop gets run once for every Screen that gets added, + * but thats ok. If the ddx layer initializes the formats + * one at a time calling AddScreen() after each, then each + * iteration will make it a little more accurate. Worst case + * we do this loop N * numPixmapFormats where N is # of screens. + * Anyway, this must be called after InitOutput and before the + * screen init routine is called. + */ + for (format=0; format<screenInfo.numPixmapFormats; format++) + { + depth = screenInfo.formats[format].depth; + bitsPerPixel = screenInfo.formats[format].bitsPerPixel; + scanlinepad = screenInfo.formats[format].scanlinePad; + j = indexForBitsPerPixel[ bitsPerPixel ]; + k = indexForScanlinePad[ scanlinepad ]; + PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k]; + PixmapWidthPaddingInfo[ depth ].padRoundUp = + (scanlinepad/bitsPerPixel) - 1; + j = indexForBitsPerPixel[ 8 ]; /* bits per byte */ + PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k]; + PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel; + if (answerBytesPerPixel[bitsPerPixel]) + { + PixmapWidthPaddingInfo[ depth ].notPower2 = 1; + PixmapWidthPaddingInfo[ depth ].bytesPerPixel = + answerBytesPerPixel[bitsPerPixel]; + } + else + { + PixmapWidthPaddingInfo[ depth ].notPower2 = 0; + } + } + + /* This is where screen specific stuff gets initialized. Load the + screen structure, call the hardware, whatever. + This is also where the default colormap should be allocated and + also pixel values for blackPixel, whitePixel, and the cursor + Note that InitScreen is NOT allowed to modify argc, argv, or + any of the strings pointed to by argv. They may be passed to + multiple screens. + */ + pScreen->rgf = ~0L; /* there are no scratch GCs yet*/ + WindowTable[i] = NullWindow; + screenInfo.screens[i] = pScreen; + screenInfo.numScreens++; + if (!(*pfnInit)(i, pScreen, argc, argv)) + { + dixFreePrivates(pScreen->devPrivates); + xfree(pScreen); + screenInfo.numScreens--; + return -1; + } + return i; +} diff --git a/xorg-server/dix/dixfonts.c b/xorg-server/dix/dixfonts.c index 02f9d6de8..527060486 100644 --- a/xorg-server/dix/dixfonts.c +++ b/xorg-server/dix/dixfonts.c @@ -48,7 +48,6 @@ Equipment Corporation. ******************************************************************/ -#define NEED_REPLIES #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -71,10 +70,6 @@ Equipment Corporation. #include <stdio.h> #endif -#ifdef PANORAMIX -#include "panoramiX.h" -#endif - #ifdef XF86BIGFONT #define _XF86BIGFONT_SERVER_ #include <X11/extensions/xf86bigfont.h> @@ -143,8 +138,9 @@ SetDefaultFont(char *defaultfontname) (unsigned) strlen(defaultfontname), defaultfontname); if (err != Success) return FALSE; - pf = (FontPtr) LookupIDByType(fid, RT_FONT); - if (pf != (FontPtr) NULL) last_pf = pf; + err = dixLookupResourceByType((pointer *)&pf, fid, RT_FONT, serverClient, + DixReadAccess); + if (err == Success) last_pf = pf; if (last_pf == (FontPtr) NULL) return FALSE; defaultFont = last_pf; @@ -400,7 +396,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna #ifdef FONTDEBUG char *f; - f = (char *)xalloc(lenfname + 1); + f = xalloc(lenfname + 1); memmove(f, pfontname, lenfname); f[lenfname] = '\0'; ErrorF("[dix] OpenFont: fontname is \"%s\"\n", f); @@ -437,10 +433,10 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna return Success; } } - c = (OFclosurePtr) xalloc(sizeof(OFclosureRec)); + c = xalloc(sizeof(OFclosureRec)); if (!c) return BadAlloc; - c->fontname = (char *) xalloc(lenfname); + c->fontname = xalloc(lenfname); c->origFontName = pfontname; c->origFontNameLen = lenfname; if (!c->fontname) { @@ -451,8 +447,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna * copy the current FPE list, so that if it gets changed by another client * while we're blocking, the request still appears atomic */ - c->fpe_list = (FontPathElementPtr *) - xalloc(sizeof(FontPathElementPtr) * num_fpes); + c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes); if (!c->fpe_list) { xfree(c->fontname); xfree(c); @@ -686,7 +681,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c) } if (err == FontNameAlias) { if (resolved) xfree(resolved); - resolved = (char *) xalloc(resolvedlen + 1); + resolved = xalloc(resolvedlen + 1); if (resolved) memmove(resolved, tmpname, resolvedlen + 1); } @@ -741,7 +736,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c) c->haveSaved = TRUE; if (c->savedName) xfree(c->savedName); - c->savedName = (char *)xalloc(namelen + 1); + c->savedName = xalloc(namelen + 1); if (c->savedName) memmove(c->savedName, name, namelen + 1); c->savedNameLen = namelen; @@ -797,12 +792,13 @@ finish: for (i = 0; i < nnames; i++) stringLens += (names->length[i] <= 255) ? names->length[i] : 0; + memset(&reply, 0, sizeof(xListFontsReply)); reply.type = X_Reply; - reply.length = (stringLens + nnames + 3) >> 2; + reply.length = bytes_to_int32(stringLens + nnames); reply.nFonts = nnames; reply.sequenceNumber = client->sequence; - bufptr = bufferStart = (char *) xalloc(reply.length << 2); + bufptr = bufferStart = xalloc(reply.length << 2); if (!bufptr && reply.length) { SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc); @@ -823,7 +819,7 @@ finish: } } nnames = reply.nFonts; - reply.length = (stringLens + nnames + 3) >> 2; + reply.length = bytes_to_int32(stringLens + nnames); client->pSwapReplyFunc = ReplySwapVector[X_ListFonts]; WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply); (void) WriteToClient(client, stringLens + nnames, bufferStart); @@ -862,10 +858,9 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, if (i != Success) return i; - if (!(c = (LFclosurePtr) xalloc(sizeof *c))) + if (!(c = xalloc(sizeof *c))) return BadAlloc; - c->fpe_list = (FontPathElementPtr *) - xalloc(sizeof(FontPathElementPtr) * num_fpes); + c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes); if (!c->fpe_list) { xfree(c); return BadAlloc; @@ -1004,7 +999,7 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) c->savedNumFonts = numFonts; if (c->savedName) xfree(c->savedName); - c->savedName = (char *)xalloc(namelen + 1); + c->savedName = xalloc(namelen + 1); if (c->savedName) memmove(c->savedName, name, namelen + 1); aliascount = 20; @@ -1053,6 +1048,7 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) err = AllocError; break; } + memset(reply + c->length, 0, length - c->length); c->reply = reply; c->length = length; } @@ -1063,9 +1059,9 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) namelen = strlen(name); } reply->type = X_Reply; - reply->length = (sizeof *reply - sizeof(xGenericReply) + + reply->length = bytes_to_int32(sizeof *reply - sizeof(xGenericReply) + pFontInfo->nprops * sizeof(xFontProp) + - namelen + 3) >> 2; + namelen); reply->sequenceNumber = client->sequence; reply->nameLength = namelen; reply->minBounds = pFontInfo->ink_minbounds; @@ -1103,8 +1099,8 @@ finish: bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply)); finalReply.type = X_Reply; finalReply.sequenceNumber = client->sequence; - finalReply.length = (sizeof(xListFontsWithInfoReply) - - sizeof(xGenericReply)) >> 2; + finalReply.length = bytes_to_int32(sizeof(xListFontsWithInfoReply) + - sizeof(xGenericReply)); WriteSwappedDataToClient(client, length, &finalReply); bail: if (c->slept) @@ -1138,10 +1134,9 @@ StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, if (i != Success) return i; - if (!(c = (LFWIclosurePtr) xalloc(sizeof *c))) + if (!(c = xalloc(sizeof *c))) goto badAlloc; - c->fpe_list = (FontPathElementPtr *) - xalloc(sizeof(FontPathElementPtr) * num_fpes); + c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes); if (!c->fpe_list) { xfree(c); @@ -1209,17 +1204,18 @@ doPolyText(ClientPtr client, PTclosurePtr c) } /* Make sure our drawable hasn't disappeared while we slept. */ - if (c->slept && - c->pDraw && - c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did, - RC_DRAWABLE, DixWriteAccess)) + if (c->slept && c->pDraw) { - /* Our drawable has disappeared. Treat like client died... ask - the FPE code to clean up after client and avoid further - rendering while we clean up after ourself. */ - fpe = c->pGC->font->fpe; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - c->pDraw = (DrawablePtr)0; + DrawablePtr pDraw; + dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess); + if (c->pDraw != pDraw) { + /* Our drawable has disappeared. Treat like client died... ask + the FPE code to clean up after client and avoid further + rendering while we clean up after ourself. */ + fpe = c->pGC->font->fpe; + (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); + c->pDraw = (DrawablePtr)0; + } } client_state = c->slept ? SLEEPING : NEVER_SLEPT; @@ -1241,12 +1237,11 @@ doPolyText(ClientPtr client, PTclosurePtr c) | ((Font)*(c->pElt+3)) << 8 | ((Font)*(c->pElt+2)) << 16 | ((Font)*(c->pElt+1)) << 24; - pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT, - DixReadAccess); - if (!pFont) + err = dixLookupResourceByType((pointer *)&pFont, fid, RT_FONT, + client, DixReadAccess); + if (err != Success) { - client->errorValue = fid; - err = BadFont; + err = (err == BadValue) ? BadFont : err; /* restore pFont and fid for step 4 (described below) */ pFont = oldpFont; fid = oldfid; @@ -1328,7 +1323,7 @@ doPolyText(ClientPtr client, PTclosurePtr c) /* Step 1 */ /* Allocate a malloc'd closure structure to replace the local one we were passed */ - new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec)); + new_closure = xalloc(sizeof(PTclosureRec)); if (!new_closure) { err = BadAlloc; @@ -1338,7 +1333,7 @@ doPolyText(ClientPtr client, PTclosurePtr c) c = new_closure; len = c->endReq - c->pElt; - c->data = (unsigned char *)xalloc(len); + c->data = xalloc(len); if (!c->data) { xfree(c); @@ -1494,17 +1489,18 @@ doImageText(ClientPtr client, ITclosurePtr c) } /* Make sure our drawable hasn't disappeared while we slept. */ - if (c->slept && - c->pDraw && - c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did, - RC_DRAWABLE, DixWriteAccess)) + if (c->slept && c->pDraw) { - /* Our drawable has disappeared. Treat like client died... ask - the FPE code to clean up after client. */ - fpe = c->pGC->font->fpe; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - err = Success; - goto bail; + DrawablePtr pDraw; + dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess); + if (c->pDraw != pDraw) { + /* Our drawable has disappeared. Treat like client died... ask + the FPE code to clean up after client. */ + fpe = c->pGC->font->fpe; + (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); + err = Success; + goto bail; + } } lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data); @@ -1520,7 +1516,7 @@ doImageText(ClientPtr client, ITclosurePtr c) in doPolyText, but much simpler because the request structure is much simpler. */ - new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec)); + new_closure = xalloc(sizeof(ITclosureRec)); if (!new_closure) { err = BadAlloc; @@ -1529,7 +1525,7 @@ doImageText(ClientPtr client, ITclosurePtr c) *new_closure = *c; c = new_closure; - data = (unsigned char *)xalloc(c->nChars * c->itemSize); + data = xalloc(c->nChars * c->itemSize); if (!data) { xfree(c); @@ -1666,7 +1662,7 @@ FreeFontPath(FontPathElementPtr *list, int n, Bool force) } FreeFPE(list[i]); } - xfree((char *) list); + xfree(list); } static FontPathElementPtr @@ -1693,8 +1689,7 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist) unsigned char *cp = paths; FontPathElementPtr fpe = NULL, *fplist; - fplist = (FontPathElementPtr *) - xalloc(sizeof(FontPathElementPtr) * npaths); + fplist = xalloc(sizeof(FontPathElementPtr) * npaths); if (!fplist) { *bad = 0; return BadAlloc; @@ -1735,13 +1730,13 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist) /* if error or can't do it, act like it's a new one */ if (!fpe) { - fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec)); + fpe = xalloc(sizeof(FontPathElementRec)); if (!fpe) { err = BadAlloc; goto bail; } - fpe->name = (char *) xalloc(len + 1); + fpe->name = xalloc(len + 1); if (!fpe->name) { xfree(fpe); @@ -1829,7 +1824,7 @@ SetDefaultFontPath(char *path) /* get enough for string, plus values -- use up commas */ len = strlen(path) + 1; - nump = cp = newpath = (unsigned char *) xalloc(len); + nump = cp = newpath = xalloc(len); if (!newpath) return BadAlloc; pp = (unsigned char *) path; @@ -1915,7 +1910,7 @@ InitFonts (void) } int -GetDefaultPointSize () +GetDefaultPointSize (void) { return 120; } @@ -2022,12 +2017,13 @@ FreeFonts(void) FontPtr find_old_font(XID id) { - return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE, - DixUnknownAccess); + pointer pFont; + dixLookupResourceByType(&pFont, id, RT_NONE, serverClient, DixReadAccess); + return (FontPtr)pFont; } Font -GetNewFontClientID() +GetNewFontClientID(void) { return FakeClientID(0); } diff --git a/xorg-server/dix/dixutils.c b/xorg-server/dix/dixutils.c index 66e5bc51b..5cede5f43 100644 --- a/xorg-server/dix/dixutils.c +++ b/xorg-server/dix/dixutils.c @@ -102,7 +102,7 @@ Author: Adobe Systems Incorporated * argument is less than, equal to or greater than the second argument. */ -_X_EXPORT int +int CompareTimeStamps(TimeStamp a, TimeStamp b) { if (a.months < b.months) @@ -121,7 +121,7 @@ CompareTimeStamps(TimeStamp a, TimeStamp b) */ #define HALFMONTH ((unsigned long) 1<<31) -_X_EXPORT TimeStamp +TimeStamp ClientTimeToServerTime(CARD32 c) { TimeStamp ts; @@ -165,7 +165,7 @@ ISOLatin1ToLower (unsigned char source) } -_X_EXPORT void +void CopyISOLatin1Lowered(unsigned char *dest, unsigned char *source, int length) { int i; @@ -203,7 +203,7 @@ CompareISOLatin1Lowered(unsigned char *s1, int s1len, * access mask values are defined in resource.h. The type mask values are * defined in pixmap.h, with zero equivalent to M_DRAWABLE. */ -_X_EXPORT int +int dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client, Mask type, Mask access) { @@ -229,7 +229,7 @@ dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client, return Success; } -_X_EXPORT int +int dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access) { int rc; @@ -237,20 +237,15 @@ dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access) return (rc == BadDrawable) ? BadWindow : rc; } -_X_EXPORT int +int dixLookupGC(GCPtr *pGC, XID id, ClientPtr client, Mask access) { - GCPtr pTmp = (GCPtr)SecurityLookupIDByType(client, id, RT_GC, access); - if (pTmp) { - *pGC = pTmp; - return Success; - } - client->errorValue = id; - *pGC = NULL; - return BadGC; + int rc; + rc = dixLookupResourceByType((pointer *)pGC, id, RT_GC, client, access); + return (rc == BadValue) ? BadGC : rc; } -_X_EXPORT int +int dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access) { pointer pRes; @@ -351,7 +346,7 @@ DeleteWindowFromAnySaveSet(WindowPtr pWin) * colormaps, if someone calls install colormap, it's easier to have a dummy * procedure to call than to check if there's a procedure */ -_X_EXPORT void +void NoopDDA(void) { } @@ -441,7 +436,7 @@ WakeupHandler(int result, pointer pReadmask) * Reentrant with BlockHandler and WakeupHandler, except wakeup won't * get called until next time */ -_X_EXPORT Bool +Bool RegisterBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler, WakeupHandlerProcPtr wakeupHandler, pointer blockData) @@ -465,7 +460,7 @@ RegisterBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler, return TRUE; } -_X_EXPORT void +void RemoveBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler, WakeupHandlerProcPtr wakeupHandler, pointer blockData) @@ -560,14 +555,14 @@ ProcessWorkQueueZombies(void) workQueueLast = p; } -_X_EXPORT Bool +Bool QueueWorkProc ( Bool (*function)(ClientPtr /* pClient */, pointer /* closure */), ClientPtr client, pointer closure) { WorkQueuePtr q; - q = (WorkQueuePtr) xalloc (sizeof *q); + q = xalloc (sizeof *q); if (!q) return FALSE; q->function = function; @@ -596,12 +591,12 @@ typedef struct _SleepQueue { static SleepQueuePtr sleepQueue = NULL; -_X_EXPORT Bool +Bool ClientSleep (ClientPtr client, ClientSleepProcPtr function, pointer closure) { SleepQueuePtr q; - q = (SleepQueuePtr) xalloc (sizeof *q); + q = xalloc (sizeof *q); if (!q) return FALSE; @@ -627,7 +622,7 @@ ClientSignal (ClientPtr client) return FALSE; } -_X_EXPORT void +void ClientWakeup (ClientPtr client) { SleepQueuePtr q, *prev; @@ -673,7 +668,7 @@ ClientIsAsleep (ClientPtr client) static int numCallbackListsToCleanup = 0; static CallbackListPtr **listsToCleanup = NULL; -static Bool +static Bool _AddCallback( CallbackListPtr *pcbl, CallbackProcPtr callback, @@ -681,7 +676,7 @@ _AddCallback( { CallbackPtr cbr; - cbr = (CallbackPtr) xalloc(sizeof(CallbackRec)); + cbr = xalloc(sizeof(CallbackRec)); if (!cbr) return FALSE; cbr->proc = callback; @@ -824,7 +819,7 @@ CreateCallbackList(CallbackListPtr *pcbl) int i; if (!pcbl) return FALSE; - cbl = (CallbackListPtr) xalloc(sizeof(CallbackListRec)); + cbl = xalloc(sizeof(CallbackListRec)); if (!cbl) return FALSE; cbl->inCallback = 0; cbl->deleted = FALSE; @@ -850,7 +845,7 @@ CreateCallbackList(CallbackListPtr *pcbl) /* ===== Public Procedures ===== */ -_X_EXPORT Bool +Bool AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data) { if (!pcbl) return FALSE; @@ -862,14 +857,14 @@ AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data) return _AddCallback(pcbl, callback, data); } -_X_EXPORT Bool +Bool DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data) { if (!pcbl || !*pcbl) return FALSE; return _DeleteCallback(pcbl, callback, data); } -void +void CallCallbacks(CallbackListPtr *pcbl, pointer call_data) { if (!pcbl || !*pcbl) return; @@ -883,7 +878,7 @@ DeleteCallbackList(CallbackListPtr *pcbl) _DeleteCallbackList(pcbl); } -void +void InitCallbackManager(void) { int i; diff --git a/xorg-server/dix/enterleave.c b/xorg-server/dix/enterleave.c index 8511dea6f..c08cc3100 100644 --- a/xorg-server/dix/enterleave.c +++ b/xorg-server/dix/enterleave.c @@ -29,13 +29,18 @@ #endif #include <X11/X.h> +#include <X11/extensions/XI2.h> +#include "inputstr.h" #include "windowstr.h" #include "scrnintstr.h" #include "exglobals.h" #include "enterleave.h" -/* @file This file describes the model for sending core enter/leave events and - * focus in/out in the case of multiple pointers/keyboard foci +/** + * @file + * This file describes the model for sending core enter/leave events and + * focus in/out in the case of multiple pointers/keyboard foci. + * * Since we can't send more than one Enter or Leave/Focus in or out event per * window to a core client without confusing it, this is a rather complicated * approach. @@ -49,7 +54,7 @@ * http://lists.freedesktop.org/archives/xorg/2008-December/041740.html * * Additional notes: - * -) The core protocol spec says that "In a LeaveNotify event, if a child of the + * - The core protocol spec says that "In a LeaveNotify event, if a child of the * event window contains the initial position of the pointer, then the child * component is set to that child. Otherwise, it is None. For an EnterNotify * event, if a child of the event window contains the final pointer position, @@ -58,7 +63,7 @@ * By inference, this means that only NotifyVirtual or NotifyNonlinearVirtual * events may have a subwindow set to other than None. * - * -) NotifyPointer events may be sent if the focus changes from window A to + * - NotifyPointer events may be sent if the focus changes from window A to * B. The assumption used in this model is that NotifyPointer events are only * sent for the pointer paired with the keyboard that is involved in the focus * events. For example, if F(W) changes because of keyboard 2, then @@ -69,7 +74,7 @@ static WindowPtr PointerWindows[MAXDEVICES]; static WindowPtr FocusWindows[MAXDEVICES]; /** - * Return TRUE if @win has a pointer within its boundaries, excluding child + * Return TRUE if 'win' has a pointer within its boundaries, excluding child * window. */ static BOOL @@ -85,7 +90,7 @@ HasPointer(WindowPtr win) } /** - * Return TRUE if at least one keyboard focus is set to @win (excluding + * Return TRUE if at least one keyboard focus is set to 'win' (excluding * descendants of win). */ static BOOL @@ -100,7 +105,7 @@ HasFocus(WindowPtr win) } /** - * Return the window the device @dev is currently on. + * Return the window the device dev is currently on. */ static WindowPtr PointerWin(DeviceIntPtr dev) @@ -109,7 +114,7 @@ PointerWin(DeviceIntPtr dev) } /** - * Search for the first window below @win that has a pointer directly within + * Search for the first window below 'win' that has a pointer directly within * it's boundaries (excluding boundaries of its own descendants). * * @return The child window that has the pointer within its boundaries or @@ -129,7 +134,7 @@ FirstPointerChild(WindowPtr win) } /** - * Search for the first window below @win that has a focus directly within + * Search for the first window below 'win' that has a focus directly within * it's boundaries (excluding boundaries of its own descendants). * * @return The child window that has the pointer within its boundaries or @@ -150,7 +155,7 @@ FirstFocusChild(WindowPtr win) } /** - * Set the presence flag for @dev to mark that it is now in @win. + * Set the presence flag for dev to mark that it is now in 'win'. */ void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode) @@ -159,16 +164,16 @@ EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode) } /** - * Unset the presence flag for @dev to mark that it is not in @win anymore. + * Unset the presence flag for dev to mark that it is not in 'win' anymore. */ -static void -LeaveWindow(DeviceIntPtr dev, WindowPtr win, int mode) +void +LeaveWindow(DeviceIntPtr dev) { PointerWindows[dev->id] = NULL; } /** - * Set the presence flag for @dev to mark that it is now in @win. + * Set the presence flag for dev to mark that it is now in 'win'. */ void SetFocusIn(DeviceIntPtr dev, WindowPtr win) @@ -177,10 +182,10 @@ SetFocusIn(DeviceIntPtr dev, WindowPtr win) } /** - * Unset the presence flag for @dev to mark that it is not in @win anymore. + * Unset the presence flag for dev to mark that it is not in 'win' anymore. */ void -SetFocusOut(DeviceIntPtr dev, WindowPtr win) +SetFocusOut(DeviceIntPtr dev) { FocusWindows[dev->id] = NULL; } @@ -189,7 +194,11 @@ SetFocusOut(DeviceIntPtr dev, WindowPtr win) /** - * @return The window that is the first ancestor of both a and b. + * Return the common ancestor of 'a' and 'b' (if one exists). + * @param a A window with the same ancestor as b. + * @param b A window with the same ancestor as a. + * @return The window that is the first ancestor of both 'a' and 'b', or the + * NullWindow if they do not have a common ancestor. */ WindowPtr CommonAncestor( @@ -202,15 +211,14 @@ CommonAncestor( } -#if 0 /** - * Send enter notifies to all windows between @ancestor and @child (excluding + * Send enter notifies to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running up the window hierarchy. This function * recurses. - * If @core is TRUE, core events are sent, otherwise XI events will be sent. */ static void DeviceEnterNotifies(DeviceIntPtr dev, + int sourceid, WindowPtr ancestor, WindowPtr child, int mode, @@ -220,14 +228,13 @@ DeviceEnterNotifies(DeviceIntPtr dev, if (ancestor == parent) return; - DeviceEnterNotifies(dev, ancestor, parent, mode, detail); - DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, detail, parent, + DeviceEnterNotifies(dev, sourceid, ancestor, parent, mode, detail); + DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, detail, parent, child->drawable.id); } -#endif /** - * Send enter notifies to all windows between @ancestor and @child (excluding + * Send enter notifies to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running down the window hierarchy. This function * recurses. */ @@ -311,13 +318,13 @@ CoreLeaveNotifies(DeviceIntPtr dev, } } -#if 0 /** - * Send leave notifies to all windows between @child and @ancestor. + * Send leave notifies to all windows between 'child' and 'ancestor'. * Events are sent running up the hierarchy. */ static void DeviceLeaveNotifies(DeviceIntPtr dev, + int sourceid, WindowPtr child, WindowPtr ancestor, int mode, @@ -329,16 +336,15 @@ DeviceLeaveNotifies(DeviceIntPtr dev, return; for (win = child->parent; win != ancestor; win = win->parent) { - DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, detail, win, + DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, detail, win, child->drawable.id); child = win; } } -#endif /** - * Pointer @dev moves from @A to @B and @A neither a descendant of @B nor is - * @B a descendant of @A. + * Pointer dev moves from A to B and A neither a descendant of B nor is + * B a descendant of A. */ static void CoreEnterLeaveNonLinear(DeviceIntPtr dev, @@ -422,7 +428,7 @@ CoreEnterLeaveNonLinear(DeviceIntPtr dev, } /** - * Pointer @dev moves from @A to @B and @A is a descendant of @B. + * Pointer dev moves from A to B and A is a descendant of B. */ static void CoreEnterLeaveToAncestor(DeviceIntPtr dev, @@ -480,7 +486,7 @@ CoreEnterLeaveToAncestor(DeviceIntPtr dev, /** - * Pointer @dev moves from @A to @B and @B is a descendant of @A. + * Pointer dev moves from A to B and B is a descendant of A. */ static void CoreEnterLeaveToDescendant(DeviceIntPtr dev, @@ -541,10 +547,10 @@ CoreEnterLeaveEvents(DeviceIntPtr dev, WindowPtr to, int mode) { - if (!dev->isMaster) + if (!IsMaster(dev)) return; - LeaveWindow(dev, from, mode); + LeaveWindow(dev); if (IsParent(from, to)) CoreEnterLeaveToDescendant(dev, from, to, mode); @@ -556,36 +562,35 @@ CoreEnterLeaveEvents(DeviceIntPtr dev, EnterWindow(dev, to, mode); } -#if 0 static void DeviceEnterLeaveEvents(DeviceIntPtr dev, + int sourceid, WindowPtr from, WindowPtr to, int mode) { if (IsParent(from, to)) { - DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyInferior, from, None); - DeviceEnterNotifies(dev, from, to, mode, NotifyVirtual); - DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyAncestor, to, None); + DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, NotifyInferior, from, None); + DeviceEnterNotifies(dev, sourceid, from, to, mode, NotifyVirtual); + DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, NotifyAncestor, to, None); } else if (IsParent(to, from)) { - DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyAncestor, from, None); - DeviceLeaveNotifies(dev, from, to, mode, NotifyVirtual); - DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyInferior, to, None); + DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, NotifyAncestor, from, None); + DeviceLeaveNotifies(dev, sourceid, from, to, mode, NotifyVirtual); + DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, NotifyInferior, to, None); } else { /* neither from nor to is descendent of the other */ WindowPtr common = CommonAncestor(to, from); /* common == NullWindow ==> different screens */ - DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyNonlinear, from, None); - DeviceLeaveNotifies(dev, from, common, mode, NotifyNonlinearVirtual); - DeviceEnterNotifies(dev, common, to, mode, NotifyNonlinearVirtual); - DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyNonlinear, to, None); + DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, NotifyNonlinear, from, None); + DeviceLeaveNotifies(dev, sourceid, from, common, mode, NotifyNonlinearVirtual); + DeviceEnterNotifies(dev, sourceid, common, to, mode, NotifyNonlinearVirtual); + DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, NotifyNonlinear, to, None); } } -#endif /** * Figure out if enter/leave events are necessary and send them to the @@ -596,6 +601,7 @@ DeviceEnterLeaveEvents(DeviceIntPtr dev, */ void DoEnterLeaveEvents(DeviceIntPtr pDev, + int sourceid, WindowPtr fromWin, WindowPtr toWin, int mode) @@ -606,14 +612,13 @@ DoEnterLeaveEvents(DeviceIntPtr pDev, if (fromWin == toWin) return; - CoreEnterLeaveEvents(pDev, fromWin, toWin, mode); -#if 0 - DeviceEnterLeaveEvents(pDev, fromWin, toWin, mode); -#endif + if (mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab) + CoreEnterLeaveEvents(pDev, fromWin, toWin, mode); + DeviceEnterLeaveEvents(pDev, sourceid, fromWin, toWin, mode); } /** - * Send focus out events to all windows between @child and @ancestor. + * Send focus out events to all windows between 'child' and 'ancestor'. * Events are sent running up the hierarchy. */ static void @@ -628,12 +633,12 @@ DeviceFocusOutEvents(DeviceIntPtr dev, if (ancestor == child) return; for (win = child->parent; win != ancestor; win = win->parent) - DeviceFocusEvent(dev, DeviceFocusOut, mode, detail, win); + DeviceFocusEvent(dev, XI_FocusOut, mode, detail, win); } /** - * Send enter notifies to all windows between @ancestor and @child (excluding + * Send enter notifies to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running up the window hierarchy. This function * recurses. */ @@ -649,11 +654,11 @@ DeviceFocusInEvents(DeviceIntPtr dev, if (ancestor == parent || !parent) return; DeviceFocusInEvents(dev, ancestor, parent, mode, detail); - DeviceFocusEvent(dev, DeviceFocusIn, mode, detail, parent); + DeviceFocusEvent(dev, XI_FocusIn, mode, detail, parent); } /** - * Send FocusIn events to all windows between @ancestor and @child (excluding + * Send FocusIn events to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running down the window hierarchy. This function * recurses. */ @@ -735,13 +740,13 @@ CoreFocusOutEvents(DeviceIntPtr dev, /** * Send FocusOut(NotifyPointer) events from the current pointer window (which - * is a descendant of @pwin_parent) up to (excluding) @pwin_parent. + * is a descendant of pwin_parent) up to (excluding) pwin_parent. * - * NotifyPointer events are only sent for the device paired with @dev. + * NotifyPointer events are only sent for the device paired with dev. * - * If the current pointer window is a descendat of @exclude or an ancestor of - * @exclude, no events are sent. Note: If the current pointer IS @exclude, - * events are sent! + * If the current pointer window is a descendant of 'exclude' or an ancestor of + * 'exclude', no events are sent. If the current pointer IS 'exclude', events + * are sent! */ static void CoreFocusOutNotifyPointerEvents(DeviceIntPtr dev, @@ -790,13 +795,13 @@ CoreFocusInRecurse(DeviceIntPtr dev, /** - * Send FocusIn(NotifyPointer) events from @pwin_parent down to - * including the current pointer window (which is a descendant of @pwin_parent). - * If @inclusive is TRUE, @pwin_parent will receive the event too. - * - * @pwin is the pointer window. + * Send FocusIn(NotifyPointer) events from pwin_parent down to + * including the current pointer window (which is a descendant of pwin_parent). * - * If the current pointer window is a child of @exclude, no events are sent. + * @param pwin The pointer window. + * @param exclude If the pointer window is a child of 'exclude', no events are + * sent. + * @param inclusive If TRUE, pwin_parent will receive the event too. */ static void CoreFocusInNotifyPointerEvents(DeviceIntPtr dev, @@ -820,8 +825,8 @@ CoreFocusInNotifyPointerEvents(DeviceIntPtr dev, /** - * Focus of @dev moves from @A to @B and @A neither a descendant of @B nor is - * @B a descendant of @A. + * Focus of dev moves from A to B and A neither a descendant of B nor is + * B a descendant of A. */ static void CoreFocusNonLinear(DeviceIntPtr dev, @@ -918,7 +923,7 @@ CoreFocusNonLinear(DeviceIntPtr dev, /** - * Focus of @dev moves from @A to @B and @A is a descendant of @B. + * Focus of dev moves from A to B and A is a descendant of B. */ static void CoreFocusToAncestor(DeviceIntPtr dev, @@ -979,7 +984,7 @@ CoreFocusToAncestor(DeviceIntPtr dev, } /** - * Focus of @dev moves from @A to @B and @B is a descendant of @A. + * Focus of dev moves from A to B and B is a descendant of A. */ static void CoreFocusToDescendant(DeviceIntPtr dev, @@ -1076,7 +1081,7 @@ CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev, if (!HasOtherPointer(root, GetPairedDevice(dev)) && !FirstFocusChild(root)) { /* If pointer was on PointerRootWin and changes to NoneWin, and - * the pointer paired with @dev is below the current root window, + * the pointer paired with dev is below the current root window, * do a NotifyPointer run. */ if (dev->focus && dev->focus->win == PointerRootWin && B != PointerRootWin) @@ -1085,8 +1090,8 @@ CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev, if (ptrwin && IsParent(root, ptrwin)) CoreFocusOutNotifyPointerEvents(dev, root, None, mode, TRUE); } - CoreFocusEvent(dev, FocusOut, mode, ((int)A) ? NotifyPointerRoot : NotifyDetailNone, root); - CoreFocusEvent(dev, FocusIn, mode, ((int)B) ? NotifyPointerRoot : NotifyDetailNone, root); + CoreFocusEvent(dev, FocusOut, mode, A ? NotifyPointerRoot : NotifyDetailNone, root); + CoreFocusEvent(dev, FocusIn, mode, B ? NotifyPointerRoot : NotifyDetailNone, root); if (B == PointerRootWin) CoreFocusInNotifyPointerEvents(dev, root, None, mode, TRUE); } @@ -1095,8 +1100,8 @@ CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev, } /** - * Focus moves from window @A to PointerRoot or to None. - * Assumption: @A is a valid window and not PointerRoot or None. + * Focus moves from window A to PointerRoot or to None. + * Assumption: A is a valid window and not PointerRoot or None. */ static void CoreFocusToPointerRootOrNone(DeviceIntPtr dev, @@ -1136,7 +1141,7 @@ CoreFocusToPointerRootOrNone(DeviceIntPtr dev, root = WindowTable[i]; if (!HasFocus(root) && !FirstFocusChild(root)) { - CoreFocusEvent(dev, FocusIn, mode, ((int)B) ? NotifyPointerRoot : NotifyDetailNone, root); + CoreFocusEvent(dev, FocusIn, mode, B ? NotifyPointerRoot : NotifyDetailNone, root); if (B == PointerRootWin) CoreFocusInNotifyPointerEvents(dev, root, None, mode, TRUE); } @@ -1144,8 +1149,8 @@ CoreFocusToPointerRootOrNone(DeviceIntPtr dev, } /** - * Focus moves from PointerRoot or None to a window @to. - * Assumption: @to is a valid window and not PointerRoot or None. + * Focus moves from PointerRoot or None to a window B. + * Assumption: B is a valid window and not PointerRoot or None. */ static void CoreFocusFromPointerRootOrNone(DeviceIntPtr dev, @@ -1168,7 +1173,7 @@ CoreFocusFromPointerRootOrNone(DeviceIntPtr dev, if (!HasFocus(root) && !FirstFocusChild(root)) { /* If pointer was on PointerRootWin and changes to NoneWin, and - * the pointer paired with @dev is below the current root window, + * the pointer paired with dev is below the current root window, * do a NotifyPointer run. */ if (dev->focus && dev->focus->win == PointerRootWin && B != PointerRootWin) @@ -1177,7 +1182,7 @@ CoreFocusFromPointerRootOrNone(DeviceIntPtr dev, if (ptrwin) CoreFocusOutNotifyPointerEvents(dev, root, None, mode, TRUE); } - CoreFocusEvent(dev, FocusOut, mode, ((int)A) ? NotifyPointerRoot : NotifyDetailNone, root); + CoreFocusEvent(dev, FocusOut, mode, A ? NotifyPointerRoot : NotifyDetailNone, root); } } @@ -1215,10 +1220,10 @@ CoreFocusEvents(DeviceIntPtr dev, WindowPtr to, int mode) { - if (!dev->isMaster) + if (!IsMaster(dev)) return; - SetFocusOut(dev, from); + SetFocusOut(dev); if (((to == NullWindow) || (to == PointerRootWin)) && ((from == NullWindow) || (from == PointerRootWin))) @@ -1237,6 +1242,9 @@ CoreFocusEvents(DeviceIntPtr dev, SetFocusIn(dev, to); } +/** + * The root window the given device is currently on. + */ #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0] static void @@ -1271,21 +1279,21 @@ DeviceFocusEvents(DeviceIntPtr dev, NotifyPointer); /* Notify all the roots */ for (i = 0; i < nscreens; i++) - DeviceFocusEvent(dev, FocusOut, mode, out, WindowTable[i]); + DeviceFocusEvent(dev, XI_FocusOut, mode, out, WindowTable[i]); } else { if (IsParent(from, sprite->win)) DeviceFocusOutEvents(dev, sprite->win, from, mode, NotifyPointer); - DeviceFocusEvent(dev, FocusOut, mode, NotifyNonlinear, from); + DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); /* next call catches the root too, if the screen changed */ DeviceFocusOutEvents(dev, from->parent, NullWindow, mode, NotifyNonlinearVirtual); } /* Notify all the roots */ for (i = 0; i < nscreens; i++) - DeviceFocusEvent(dev, FocusIn, mode, in, WindowTable[i]); + DeviceFocusEvent(dev, XI_FocusIn, mode, in, WindowTable[i]); if (to == PointerRootWin) DeviceFocusInEvents(dev, RootWindow(dev), sprite->win, mode, NotifyPointer); } @@ -1297,10 +1305,10 @@ DeviceFocusEvents(DeviceIntPtr dev, DeviceFocusOutEvents(dev, sprite->win, RootWindow(dev), mode, NotifyPointer); for (i = 0; i < nscreens; i++) - DeviceFocusEvent(dev, FocusOut, mode, out, WindowTable[i]); + DeviceFocusEvent(dev, XI_FocusOut, mode, out, WindowTable[i]); if (to->parent != NullWindow) DeviceFocusInEvents(dev, RootWindow(dev), to, mode, NotifyNonlinearVirtual); - DeviceFocusEvent(dev, FocusIn, mode, NotifyNonlinear, to); + DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyNonlinear, to); if (IsParent(to, sprite->win)) DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer); } @@ -1308,10 +1316,10 @@ DeviceFocusEvents(DeviceIntPtr dev, { if (IsParent(to, from)) { - DeviceFocusEvent(dev, FocusOut, mode, NotifyAncestor, from); + DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyAncestor, from); DeviceFocusOutEvents(dev, from->parent, to, mode, NotifyVirtual); - DeviceFocusEvent(dev, FocusIn, mode, NotifyInferior, to); + DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyInferior, to); if ((IsParent(to, sprite->win)) && (sprite->win != from) && (!IsParent(from, sprite->win)) && @@ -1327,9 +1335,9 @@ DeviceFocusEvents(DeviceIntPtr dev, (!IsParent(sprite->win, to))) DeviceFocusOutEvents(dev, sprite->win, from, mode, NotifyPointer); - DeviceFocusEvent(dev, FocusOut, mode, NotifyInferior, from); + DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyInferior, from); DeviceFocusInEvents(dev, from, to, mode, NotifyVirtual); - DeviceFocusEvent(dev, FocusIn, mode, NotifyAncestor, to); + DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyAncestor, to); } else { @@ -1339,13 +1347,13 @@ DeviceFocusEvents(DeviceIntPtr dev, if (IsParent(from, sprite->win)) DeviceFocusOutEvents(dev, sprite->win, from, mode, NotifyPointer); - DeviceFocusEvent(dev, FocusOut, mode, NotifyNonlinear, from); + DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); if (from->parent != NullWindow) DeviceFocusOutEvents(dev, from->parent, common, mode, NotifyNonlinearVirtual); if (to->parent != NullWindow) DeviceFocusInEvents(dev, common, to, mode, NotifyNonlinearVirtual); - DeviceFocusEvent(dev, FocusIn, mode, NotifyNonlinear, to); + DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyNonlinear, to); if (IsParent(to, sprite->win)) DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer); } diff --git a/xorg-server/dix/enterleave.h b/xorg-server/dix/enterleave.h index edca38664..471f4efaa 100644 --- a/xorg-server/dix/enterleave.h +++ b/xorg-server/dix/enterleave.h @@ -33,6 +33,7 @@ extern void DoEnterLeaveEvents( DeviceIntPtr pDev, + int sourceid, WindowPtr fromWin, WindowPtr toWin, int mode @@ -64,6 +65,7 @@ extern void CoreEnterLeaveEvent(DeviceIntPtr mouse, WindowPtr pWin, Window child); extern void DeviceEnterLeaveEvent(DeviceIntPtr mouse, + int sourceid, int type, int mode, int detail, @@ -74,6 +76,7 @@ extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode); +extern void LeaveWindow(DeviceIntPtr dev); extern void CoreFocusEvent(DeviceIntPtr kbd, int type, @@ -90,6 +93,5 @@ extern void DeviceFocusEvent(DeviceIntPtr kbd, extern void SetFocusIn(DeviceIntPtr kbd, WindowPtr win); -extern void SetFocusOut(DeviceIntPtr dev, - WindowPtr win); +extern void SetFocusOut(DeviceIntPtr dev); #endif /* _ENTERLEAVE_H_ */ diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c new file mode 100644 index 000000000..21eed40e1 --- /dev/null +++ b/xorg-server/dix/eventconvert.c @@ -0,0 +1,718 @@ +/* + * 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. + * + */ + +/** + * @file eventconvert.c + * This file contains event conversion routines from InternalEvent to the + * matching protocol events. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdint.h> +#include <X11/X.h> +#include <X11/extensions/XIproto.h> +#include <X11/extensions/XI2proto.h> +#include <X11/extensions/XI.h> +#include <X11/extensions/XI2.h> + +#include "dix.h" +#include "inputstr.h" +#include "misc.h" +#include "eventstr.h" +#include "exglobals.h" +#include "eventconvert.h" +#include "xiquerydevice.h" +#include "xkbsrv.h" + + +static int countValuators(DeviceEvent *ev, int *first); +static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv); +static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count); +static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce); +static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi); +static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi); + +/* Do not use, read comments below */ +BOOL EventIsKeyRepeat(xEvent *event); + +/** + * Hack to allow detectable autorepeat for core and XI1 events. + * The sequence number is unused until we send to the client and can be + * misused to store data. More or less, anyway. + * + * Do not use this. It may change any time without warning, eat your babies + * and piss on your cat. + */ +static void +EventSetKeyRepeatFlag(xEvent *event, BOOL on) +{ + event->u.u.sequenceNumber = on; +} + +/** + * Check if the event was marked as a repeat event before. + * NOTE: This is a nasty hack and should NOT be used by anyone else but + * TryClientEvents. + */ +BOOL +EventIsKeyRepeat(xEvent *event) +{ + return !!event->u.u.sequenceNumber; +} + +/** + * Convert the given event to the respective core event. + * + * Return values: + * Success ... core contains the matching core event. + * BadValue .. One or more values in the internal event are invalid. + * BadMatch .. The event has no core equivalent. + * + * @param[in] event The event to convert into a core event. + * @param[in] core The memory location to store the core event at. + * @return Success or the matching error code. + */ +int +EventToCore(InternalEvent *event, xEvent *core) +{ + switch(event->any.type) + { + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + { + DeviceEvent *e = (DeviceEvent*)event; + + if (e->detail.key > 0xFF) + return BadMatch; + + memset(core, 0, sizeof(xEvent)); + core->u.u.type = e->type - ET_KeyPress + KeyPress; + core->u.u.detail = e->detail.key & 0xFF; + core->u.keyButtonPointer.time = e->time; + core->u.keyButtonPointer.rootX = e->root_x; + core->u.keyButtonPointer.rootY = e->root_y; + core->u.keyButtonPointer.state = e->corestate; + EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); + } + break; + case ET_ProximityIn: + case ET_ProximityOut: + case ET_RawKeyPress: + case ET_RawKeyRelease: + case ET_RawButtonPress: + case ET_RawButtonRelease: + case ET_RawMotion: + return BadMatch; + default: + /* XXX: */ + ErrorF("[dix] EventToCore: Not implemented yet \n"); + return BadImplementation; + } + return Success; +} + +/** + * Convert the given event to the respective XI 1.x event and store it in + * xi. xi is allocated on demand and must be freed by the caller. + * count returns the number of events in xi. If count is 1, and the type of + * xi is GenericEvent, then xi may be larger than 32 bytes. + * + * Return values: + * Success ... core contains the matching core event. + * BadValue .. One or more values in the internal event are invalid. + * BadMatch .. The event has no XI equivalent. + * + * @param[in] ev The event to convert into an XI 1 event. + * @param[out] xi Future memory location for the XI event. + * @param[out] count Number of elements in xi. + * + * @return Success or the error code. + */ +int +EventToXI(InternalEvent *ev, xEvent **xi, int *count) +{ + switch (ev->any.type) + { + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ProximityIn: + case ET_ProximityOut: + return eventToKeyButtonPointer((DeviceEvent*)ev, xi, count); + case ET_DeviceChanged: + case ET_RawKeyPress: + case ET_RawKeyRelease: + case ET_RawButtonPress: + case ET_RawButtonRelease: + case ET_RawMotion: + *count = 0; + *xi = NULL; + return BadMatch; + default: + break; + } + + ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type); + return BadImplementation; +} + +/** + * Convert the given event to the respective XI 2.x event and store it in xi. + * xi is allocated on demand and must be freed by the caller. + * + * Return values: + * Success ... core contains the matching core event. + * BadValue .. One or more values in the internal event are invalid. + * BadMatch .. The event has no XI2 equivalent. + * + * @param[in] ev The event to convert into an XI2 event + * @param[out] xi Future memory location for the XI2 event. + * + * @return Success or the error code. + */ +int +EventToXI2(InternalEvent *ev, xEvent **xi) +{ + switch (ev->any.type) + { + /* Enter/FocusIn are for grabs. We don't need an actual event, since + * the real events delivered are triggered elsewhere */ + case ET_Enter: + case ET_FocusIn: + *xi = NULL; + return Success; + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + return eventToDeviceEvent((DeviceEvent*)ev, xi); + case ET_ProximityIn: + case ET_ProximityOut: + *xi = NULL; + return BadMatch; + case ET_DeviceChanged: + return eventToDeviceChanged((DeviceChangedEvent*)ev, xi); + case ET_RawKeyPress: + case ET_RawKeyRelease: + case ET_RawButtonPress: + case ET_RawButtonRelease: + case ET_RawMotion: + return eventToRawEvent((RawDeviceEvent*)ev, xi); + default: + break; + } + + ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type); + return BadImplementation; +} + +static int +eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count) +{ + int num_events; + int first; /* dummy */ + deviceKeyButtonPointer *kbp; + + /* Sorry, XI 1.x protocol restrictions. */ + if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) + { + *count = 0; + return Success; + } + + num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */ + num_events++; /* the actual event event */ + + *xi = xcalloc(num_events, sizeof(xEvent)); + if (!(*xi)) + { + return BadAlloc; + } + + kbp = (deviceKeyButtonPointer*)(*xi); + kbp->detail = ev->detail.button; + kbp->time = ev->time; + kbp->root = ev->root; + kbp->root_x = ev->root_x; + kbp->root_y = ev->root_y; + kbp->deviceid = ev->deviceid; + kbp->state = ev->corestate; + EventSetKeyRepeatFlag((xEvent*)kbp, + (ev->type == ET_KeyPress && ev->key_repeat)); + + if (num_events > 1) + kbp->deviceid |= MORE_EVENTS; + + switch(ev->type) + { + case ET_Motion: kbp->type = DeviceMotionNotify; break; + case ET_ButtonPress: kbp->type = DeviceButtonPress; break; + case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break; + case ET_KeyPress: kbp->type = DeviceKeyPress; break; + case ET_KeyRelease: kbp->type = DeviceKeyRelease; break; + case ET_ProximityIn: kbp->type = ProximityIn; break; + case ET_ProximityOut: kbp->type = ProximityOut; break; + default: + break; + } + + if (num_events > 1) + { + getValuatorEvents(ev, (deviceValuator*)(kbp + 1)); + } + + *count = num_events; + return Success; +} + + +/** + * Set first to the first valuator in the event ev and return the number of + * valuators from first to the last set valuator. + */ +static int +countValuators(DeviceEvent *ev, int *first) +{ + int first_valuator = -1, last_valuator = -1, num_valuators = 0; + int i; + + for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) + { + if (BitIsOn(ev->valuators.mask, i)) + { + if (first_valuator == -1) + first_valuator = i; + last_valuator = i; + } + } + + if (first_valuator != -1) + { + num_valuators = last_valuator - first_valuator + 1; + *first = first_valuator; + } + + return num_valuators; +} + +static int +getValuatorEvents(DeviceEvent *ev, deviceValuator *xv) +{ + int i; + int state = 0; + int first_valuator, num_valuators; + + + num_valuators = countValuators(ev, &first_valuator); + if (num_valuators > 0) + { + DeviceIntPtr dev = NULL; + dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess); + /* State needs to be assembled BEFORE the device is updated. */ + state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0; + state |= (dev && dev->button) ? (dev->button->state) : 0; + } + + /* FIXME: non-continuous valuator data in internal events*/ + for (i = 0; i < num_valuators; i += 6, xv++) { + xv->type = DeviceValuator; + xv->first_valuator = first_valuator + i; + xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); + xv->deviceid = ev->deviceid; + xv->device_state = state; + switch (xv->num_valuators) { + case 6: + xv->valuator5 = ev->valuators.data[i + 5]; + case 5: + xv->valuator4 = ev->valuators.data[i + 4]; + case 4: + xv->valuator3 = ev->valuators.data[i + 3]; + case 3: + xv->valuator2 = ev->valuators.data[i + 2]; + case 2: + xv->valuator1 = ev->valuators.data[i + 1]; + case 1: + xv->valuator0 = ev->valuators.data[i + 0]; + } + + if (i + 6 < num_valuators) + xv->deviceid |= MORE_EVENTS; + } + + return (num_valuators + 5) / 6; +} + + +static int +appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info) +{ + uint32_t *kc; + int i; + + info->type = XIKeyClass; + info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1; + info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes; + info->sourceid = dce->sourceid; + + kc = (uint32_t*)&info[1]; + for (i = 0; i < info->num_keycodes; i++) + *kc++ = i + dce->keys.min_keycode; + + return info->length * 4; +} + +static int +appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info) +{ + unsigned char *bits; + int mask_len; + + mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons)); + + info->type = XIButtonClass; + info->num_buttons = dce->buttons.num_buttons; + info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + + info->num_buttons + mask_len; + info->sourceid = dce->sourceid; + + bits = (unsigned char*)&info[1]; + memset(bits, 0, mask_len * 4); + /* FIXME: is_down? */ + + bits += mask_len * 4; + memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom)); + + return info->length * 4; +} + +static int +appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber) +{ + info->type = XIValuatorClass; + info->length = sizeof(xXIValuatorInfo)/4; + info->label = dce->valuators[axisnumber].name; + info->min.integral = dce->valuators[axisnumber].min; + info->min.frac = 0; + info->max.integral = dce->valuators[axisnumber].max; + info->max.frac = 0; + /* FIXME: value */ + info->value.integral = 0; + info->value.frac = 0; + info->resolution = dce->valuators[axisnumber].resolution; + info->number = axisnumber; + info->mode = dce->valuators[axisnumber].mode; /* Server doesn't have per-axis mode yet */ + info->sourceid = dce->sourceid; + + return info->length * 4; +} + +static int +eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi) +{ + xXIDeviceChangedEvent *dcce; + int len = sizeof(xXIDeviceChangedEvent); + int nkeys; + char *ptr; + + if (dce->buttons.num_buttons) + { + len += sizeof(xXIButtonInfo); + len += dce->buttons.num_buttons * sizeof(Atom); /* button names */ + len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons)); + } + if (dce->num_valuators) + len += sizeof(xXIValuatorInfo) * dce->num_valuators; + + nkeys = (dce->keys.max_keycode > 0) ? + dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0; + if (nkeys > 0) + { + len += sizeof(xXIKeyInfo); + len += sizeof(CARD32) * nkeys; /* keycodes */ + } + + dcce = xcalloc(1, len); + if (!dcce) + { + ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n"); + return BadAlloc; + } + + dcce->type = GenericEvent; + dcce->extension = IReqCode; + dcce->evtype = XI_DeviceChanged; + dcce->time = dce->time; + dcce->deviceid = dce->deviceid; + dcce->sourceid = dce->sourceid; + dcce->reason = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch; + dcce->num_classes = 0; + dcce->length = bytes_to_int32(len - sizeof(xEvent)); + + ptr = (char*)&dcce[1]; + if (dce->buttons.num_buttons) + { + dcce->num_classes++; + ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr); + } + + if (nkeys) + { + dcce->num_classes++; + ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr); + } + + if (dce->num_valuators) + { + int i; + + dcce->num_classes += dce->num_valuators; + for (i = 0; i < dce->num_valuators; i++) + ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i); + } + + *xi = (xEvent*)dcce; + + return Success; +} + +static int count_bits(unsigned char* ptr, int len) +{ + int bits = 0; + unsigned int i; + unsigned char x; + + for (i = 0; i < len; i++) + { + x = ptr[i]; + while(x > 0) + { + bits += (x & 0x1); + x >>= 1; + } + } + return bits; +} + +static int +eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) +{ + int len = sizeof(xXIDeviceEvent); + xXIDeviceEvent *xde; + int i, btlen, vallen; + char *ptr; + FP3232 *axisval; + + /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same + * with MAX_VALUATORS below */ + /* btlen is in 4 byte units */ + btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS)); + len += btlen * 4; /* buttonmask len */ + + + vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0])); + len += vallen * 2 * sizeof(uint32_t); /* axisvalues */ + vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); + len += vallen * 4; /* valuators mask */ + + *xi = xcalloc(1, len); + xde = (xXIDeviceEvent*)*xi; + xde->type = GenericEvent; + xde->extension = IReqCode; + xde->evtype = GetXI2Type((InternalEvent*)ev); + xde->time = ev->time; + xde->length = bytes_to_int32(len - sizeof(xEvent)); + xde->detail = ev->detail.button; + xde->root = ev->root; + xde->buttons_len = btlen; + xde->valuators_len = vallen; + xde->deviceid = ev->deviceid; + xde->sourceid = ev->sourceid; + xde->root_x = FP1616(ev->root_x, ev->root_x_frac); + xde->root_y = FP1616(ev->root_y, ev->root_y_frac); + + if (ev->key_repeat) + xde->flags |= XIKeyRepeat; + + xde->mods.base_mods = ev->mods.base; + xde->mods.latched_mods = ev->mods.latched; + xde->mods.locked_mods = ev->mods.locked; + xde->mods.effective_mods = ev->mods.effective; + + xde->group.base_group = ev->group.base; + xde->group.latched_group = ev->group.latched; + xde->group.locked_group = ev->group.locked; + xde->group.effective_group = ev->group.effective; + + ptr = (char*)&xde[1]; + for (i = 0; i < sizeof(ev->buttons) * 8; i++) + { + if (BitIsOn(ev->buttons, i)) + SetBit(ptr, i); + } + + ptr += xde->buttons_len * 4; + axisval = (FP3232*)(ptr + xde->valuators_len * 4); + for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) + { + if (BitIsOn(ev->valuators.mask, i)) + { + SetBit(ptr, i); + axisval->integral = ev->valuators.data[i]; + axisval->frac = ev->valuators.data_frac[i]; + axisval++; + } + } + + return Success; +} + +static int +eventToRawEvent(RawDeviceEvent *ev, xEvent **xi) +{ + xXIRawEvent* raw; + int vallen, nvals; + int i, len = sizeof(xXIRawEvent); + char *ptr; + FP3232 *axisval; + + nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)); + len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once + raw, once processed */ + vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); + len += vallen * 4; /* valuators mask */ + + *xi = xcalloc(1, len); + raw = (xXIRawEvent*)*xi; + raw->type = GenericEvent; + raw->extension = IReqCode; + raw->evtype = GetXI2Type((InternalEvent*)ev); + raw->time = ev->time; + raw->length = bytes_to_int32(len - sizeof(xEvent)); + raw->detail = ev->detail.button; + raw->deviceid = ev->deviceid; + raw->valuators_len = vallen; + + ptr = (char*)&raw[1]; + axisval = (FP3232*)(ptr + raw->valuators_len * 4); + for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) + { + if (BitIsOn(ev->valuators.mask, i)) + { + SetBit(ptr, i); + axisval->integral = ev->valuators.data[i]; + axisval->frac = ev->valuators.data_frac[i]; + (axisval + nvals)->integral = ev->valuators.data_raw[i]; + (axisval + nvals)->frac = ev->valuators.data_raw_frac[i]; + axisval++; + } + } + + return Success; +} + +/** + * Return the corresponding core type for the given event or 0 if no core + * equivalent exists. + */ +int +GetCoreType(InternalEvent *event) +{ + int coretype = 0; + switch(event->any.type) + { + case ET_Motion: coretype = MotionNotify; break; + case ET_ButtonPress: coretype = ButtonPress; break; + case ET_ButtonRelease: coretype = ButtonRelease; break; + case ET_KeyPress: coretype = KeyPress; break; + case ET_KeyRelease: coretype = KeyRelease; break; + default: + break; + } + return coretype; +} + +/** + * Return the corresponding XI 1.x type for the given event or 0 if no + * equivalent exists. + */ +int +GetXIType(InternalEvent *event) +{ + int xitype = 0; + switch(event->any.type) + { + case ET_Motion: xitype = DeviceMotionNotify; break; + case ET_ButtonPress: xitype = DeviceButtonPress; break; + case ET_ButtonRelease: xitype = DeviceButtonRelease; break; + case ET_KeyPress: xitype = DeviceKeyPress; break; + case ET_KeyRelease: xitype = DeviceKeyRelease; break; + case ET_ProximityIn: xitype = ProximityIn; break; + case ET_ProximityOut: xitype = ProximityOut; break; + default: + break; + } + return xitype; +} + +/** + * Return the corresponding XI 2.x type for the given event or 0 if no + * equivalent exists. + */ +int +GetXI2Type(InternalEvent *event) +{ + int xi2type = 0; + + switch(event->any.type) + { + case ET_Motion: xi2type = XI_Motion; break; + case ET_ButtonPress: xi2type = XI_ButtonPress; break; + case ET_ButtonRelease: xi2type = XI_ButtonRelease; break; + case ET_KeyPress: xi2type = XI_KeyPress; break; + case ET_KeyRelease: xi2type = XI_KeyRelease; break; + case ET_Enter: xi2type = XI_Enter; break; + case ET_Leave: xi2type = XI_Leave; break; + case ET_Hierarchy: xi2type = XI_HierarchyChanged; break; + case ET_DeviceChanged: xi2type = XI_DeviceChanged; break; + case ET_RawKeyPress: xi2type = XI_RawKeyPress; break; + case ET_RawKeyRelease: xi2type = XI_RawKeyRelease; break; + case ET_RawButtonPress: xi2type = XI_RawButtonPress; break; + case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break; + case ET_RawMotion: xi2type = XI_RawMotion; break; + case ET_FocusIn: xi2type = XI_FocusIn; break; + case ET_FocusOut: xi2type = XI_FocusOut; break; + default: + break; + } + return xi2type; +} diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index f9448ba76..0d01df512 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -107,7 +107,7 @@ of the copyright holder. ******************************************************************/ -/** @file +/** @file events.c * This file handles event delivery and a big part of the server-side protocol * handling (the parts for input devices). */ @@ -117,11 +117,8 @@ of the copyright holder. #endif #include <X11/X.h> -#include <X11/keysym.h> #include "misc.h" #include "resource.h" -#define NEED_EVENTS -#define NEED_REPLIES #include <X11/Xproto.h> #include "windowstr.h" #include "inputstr.h" @@ -135,12 +132,8 @@ of the copyright holder. #endif #include "globals.h" -#ifdef XKB #include <X11/extensions/XKBproto.h> -#include <xkbsrv.h> -extern Bool XkbFilterEvents(ClientPtr, int, xEvent *); -#endif - +#include "xkbsrv.h" #include "xace.h" #ifdef XSERVER_DTRACE @@ -150,7 +143,9 @@ typedef const char *string; #endif #include <X11/extensions/XIproto.h> +#include <X11/extensions/XI2proto.h> #include <X11/extensions/XI.h> +#include <X11/extensions/XI2.h> #include "exglobals.h" #include "exevents.h" #include "exglobals.h" @@ -164,11 +159,11 @@ typedef const char *string; #include "geext.h" #include "geint.h" +#include "eventstr.h" #include "enterleave.h" +#include "eventconvert.h" -/** - * Extension events type numbering starts at EXTENSION_EVENT_BASE. - */ +/* Extension events type numbering starts at EXTENSION_EVENT_BASE. */ #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask ) #define AllButtonsMask ( \ @@ -188,20 +183,22 @@ typedef const char *string; #define AllModifiersMask ( \ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ Mod3Mask | Mod4Mask | Mod5Mask ) -#define AllEventMasks (lastEventMask|(lastEventMask-1)) +#define LastEventMask OwnerGrabButtonMask +#define AllEventMasks (LastEventMask|(LastEventMask-1)) + + +#define CORE_EVENT(event) \ + (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \ + (event)->u.u.type != GenericEvent) +#define XI2_EVENT(event) \ + (((event)->u.u.type == GenericEvent) && \ + ((xGenericEvent*)(event))->extension == IReqCode) /** * Used to indicate a implicit passive grab created by a ButtonPress event. * See DeliverEventsToWindow(). */ #define ImplicitGrabMask (1 << 7) -/* - * The following relies on the fact that the Button<n>MotionMasks are equal - * to the corresponding Button<n>Masks from the current modifier/button state. - */ -#define Motion_Filter(class) (PointerMotionMask | \ - (class)->state | (class)->motionMask) - #define WID(w) ((w) ? ((w)->drawable.id) : 0) @@ -210,21 +207,33 @@ typedef const char *string; #define rClient(obj) (clients[CLIENT_ID((obj)->resource)]) -_X_EXPORT CallbackListPtr EventCallback; -_X_EXPORT CallbackListPtr DeviceEventCallback; +CallbackListPtr EventCallback; +CallbackListPtr DeviceEventCallback; #define DNPMCOUNT 8 Mask DontPropagateMasks[DNPMCOUNT]; static int DontPropagateRefCnts[DNPMCOUNT]; +static void CheckVirtualMotion( DeviceIntPtr pDev, QdEventPtr qe, WindowPtr pWin); +static void CheckPhysLimits(DeviceIntPtr pDev, + CursorPtr cursor, + Bool generateEvents, + Bool confineToScreen, + ScreenPtr pScreen); +static Bool CheckPassiveGrabsOnWindow(WindowPtr pWin, + DeviceIntPtr device, + DeviceEvent *event, + BOOL checkCore); + +/** Key repeat hack. Do not use but in TryClientEvents */ +extern BOOL EventIsKeyRepeat(xEvent *event); /** * Main input device struct. * inputInfo.pointer * is the core pointer. Referred to as "virtual core pointer", "VCP", - * "core pointer" or inputInfo.pointer. There is exactly one core pointer, - * but multiple devices may send core events. The VCP is the first master + * "core pointer" or inputInfo.pointer. The VCP is the first master * pointer device and cannot be deleted. * * inputInfo.keyboard @@ -239,45 +248,69 @@ static int DontPropagateRefCnts[DNPMCOUNT]; * * inputInfo.numDevices * Total number of devices. + * + * inputInfo.all_devices + * Virtual device used for XIAllDevices passive grabs. This device is + * not part of the inputInfo.devices list and mostly unset except for + * the deviceid. It exists because passivegrabs need a valid device + * reference. + * + * inputInfo.all_master_devices + * Virtual device used for XIAllMasterDevices passive grabs. This device + * is not part of the inputInfo.devices list and mostly unset except for + * the deviceid. It exists because passivegrabs need a valid device + * reference. */ -_X_EXPORT InputInfo inputInfo; +InputInfo inputInfo; /** * syncEvents is the global structure for queued events. + * * Devices can be frozen through GrabModeSync pointer grabs. If this is the * case, events from these devices are added to "pending" instead of being * processed normally. When the device is unfrozen, events in "pending" are * replayed and processed as if they would come from the device directly. - * - * pending ... list of queued events - * pendtail ... last event in list - * replayDev ... The device to replay events for. Only set in AllowEvents, in - * which case it is set to the device specified in the request. - * replayWin ... the window the events are supposed to be replayed on. This - * window may be set to the grab's window (but only when - * Replay{Pointer|Keyboard} is given in the XAllowEvents - * request. - * playingEvents ... flag to indicate whether we're in the process of - * replaying events. Only set in ComputeFreezes(). */ static struct { - QdEventPtr pending, *pendtail; + QdEventPtr pending, /**< list of queued events */ + *pendtail; /**< last event in list */ + /** The device to replay events for. Only set in AllowEvents(), in which + * case it is set to the device specified in the request. */ DeviceIntPtr replayDev; /* kludgy rock to put flag for */ + + /** + * The window the events are supposed to be replayed on. + * This window may be set to the grab's window (but only when + * Replay{Pointer|Keyboard} is given in the XAllowEvents() + * request. */ WindowPtr replayWin; /* ComputeFreezes */ + /** + * Flag to indicate whether we're in the process of + * replaying events. Only set in ComputeFreezes(). */ Bool playingEvents; TimeStamp time; } syncEvents; +/** + * The root window the given device is currently on. + */ #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0] static xEvent* swapEvent = NULL; static int swapEventLen = 0; +void +NotImplemented(xEvent *from, xEvent *to) +{ + FatalError("Not implemented"); +} + /** * Convert the given event type from an XI event to a core event. + * @param[in] The XI 1.x event type. * @return The matching core event type or 0 if there is none. */ -_X_EXPORT int +int XItoCoreType(int xitype) { int coretype = 0; @@ -296,36 +329,43 @@ XItoCoreType(int xitype) } /** - * True if device owns a cursor, false if device shares a cursor sprite with - * another device. + * @return true if the device owns a cursor, false if device shares a cursor + * sprite with another device. */ -_X_EXPORT Bool +Bool DevHasCursor(DeviceIntPtr pDev) { return pDev->spriteInfo->spriteOwner; } /* - * Return true if a device is a pointer, check is the same as used by XI to + * @return true if a device is a pointer, check is the same as used by XI to * fill the 'use' field. */ -_X_EXPORT Bool +Bool IsPointerDevice(DeviceIntPtr dev) { - return (dev->valuator && dev->button); + return (dev->type == MASTER_POINTER) || (dev->valuator && dev->button); } /* - * Return true if a device is a keyboard, check is the same as used by XI to + * @return true if a device is a keyboard, check is the same as used by XI to * fill the 'use' field. * * Some pointer devices have keys as well (e.g. multimedia keys). Try to not * count them as keyboard devices. */ -_X_EXPORT Bool +Bool IsKeyboardDevice(DeviceIntPtr dev) { - return (dev->key && dev->kbdfeed) && !IsPointerDevice(dev); + return (dev->type == MASTER_KEYBOARD) || + ((dev->key && dev->kbdfeed) && !IsPointerDevice(dev)); +} + +Bool +IsMaster(DeviceIntPtr dev) +{ + return (dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD); } static WindowPtr XYToWindow( @@ -339,15 +379,22 @@ static WindowPtr XYToWindow( */ extern int lastEvent; -static Mask lastEventMask; - extern int DeviceMotionNotify; +#define CantBeFiltered NoEventMask /** - * Event filters. One set of filters for each device, but only the first layer + * Event masks for each event type. + * + * One set of filters for each device, but only the first layer * is initialized. The rest is memcpy'd in InitEvents. + * + * Filters are used whether a given event may be delivered to a client, + * usually in the form of if (window-event-mask & filter); then deliver event. + * + * One notable filter is for PointerMotion/DevicePointerMotion events. Each + * time a button is pressed, the filter is modified to also contain the + * matching ButtonXMotion mask. */ -#define CantBeFiltered NoEventMask static Mask filters[MAXDEVICES][128] = { { NoSuchEvent, /* 0 */ @@ -387,28 +434,90 @@ static Mask filters[MAXDEVICES][128] = { CantBeFiltered /* MappingNotify */ }}; +/** + * For the given event, return the matching event filter. This filter may then + * be AND'ed with the selected event mask. + * + * For XI2 events, the returned filter is simply the byte containing the event + * mask we're interested in. E.g. for a mask of (1 << 13), this would be + * byte[1]. + * + * @param[in] dev The device the event belongs to, may be NULL. + * @param[in] event The event to get the filter for. Only the type of the + * event matters, or the extension + evtype for GenericEvents. + * @return The filter mask for the given event. + * + * @see GetEventMask + */ +Mask +GetEventFilter(DeviceIntPtr dev, xEvent *event) +{ + if (event->u.u.type != GenericEvent) + return filters[dev ? dev->id : 0][event->u.u.type]; + else if (XI2_EVENT(event)) + return (1 << (((xXIDeviceEvent*)event)->evtype % 8)); + ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type); + return 0; +} /** - * same principle as filters, but one set of filters for each extension. - * The extension is responsible for setting the filters by calling - * SetGenericFilter(). + * Return the windows complete XI2 mask for the given XI2 event type. */ -static Mask* generic_filters[MAXEXTENSIONS]; +Mask +GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) +{ + OtherInputMasks *inputMasks = wOtherInputMasks(win); + int filter; + int evtype; + + if (!inputMasks || !XI2_EVENT(ev)) + return 0; + + evtype = ((xGenericEvent*)ev)->evtype; + filter = GetEventFilter(dev, ev); + + return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) || + inputMasks->xi2mask[XIAllDevices][evtype/8] || + (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && IsMaster(dev))); +} + +static Mask +GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other) +{ + /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ + if (XI2_EVENT(event)) + { + int byte = ((xGenericEvent*)event)->evtype / 8; + return (other->xi2mask[dev->id][byte] | + other->xi2mask[XIAllDevices][byte] | + (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0)); + } else if (CORE_EVENT(event)) + return other->mask[XIAllDevices]; + else + return other->mask[dev->id]; +} + static CARD8 criticalEvents[32] = { 0x7c, 0x30, 0x40 /* key, button, expose, and configure events */ }; +static void +SyntheticMotion(DeviceIntPtr dev, int x, int y) { + int screenno = 0; + #ifdef PANORAMIX -static void PostNewCursor(DeviceIntPtr pDev); + if (!noPanoramiXExtension) + screenno = dev->spriteInfo->sprite->screen->myNum; +#endif + PostSyntheticMotion(dev, x, y, screenno, + (syncEvents.playingEvents) ? syncEvents.time.milliseconds : currentTime.milliseconds); -#define SyntheticMotion(dev, x, y) \ - PostSyntheticMotion(dev, x, y, noPanoramiXExtension ? 0 : \ - dev->spriteInfo->sprite->screen->myNum, \ - syncEvents.playingEvents ? \ - syncEvents.time.milliseconds : \ - currentTime.milliseconds); +} + +#ifdef PANORAMIX +static void PostNewCursor(DeviceIntPtr pDev); static Bool XineramaSetCursorPosition( @@ -475,49 +584,6 @@ XineramaConstrainCursor(DeviceIntPtr pDev) (* pScreen->ConstrainCursor)(pDev, pScreen, &newBox); } -static void -XineramaCheckPhysLimits( - DeviceIntPtr pDev, - CursorPtr cursor, - Bool generateEvents -){ - HotSpot new; - SpritePtr pSprite = pDev->spriteInfo->sprite; - - if (!cursor) - return; - - new = pSprite->hotPhys; - - /* I don't care what the DDX has to say about it */ - pSprite->physLimits = pSprite->hotLimits; - - /* constrain the pointer to those limits */ - if (new.x < pSprite->physLimits.x1) - new.x = pSprite->physLimits.x1; - else - if (new.x >= pSprite->physLimits.x2) - new.x = pSprite->physLimits.x2 - 1; - if (new.y < pSprite->physLimits.y1) - new.y = pSprite->physLimits.y1; - else - if (new.y >= pSprite->physLimits.y2) - new.y = pSprite->physLimits.y2 - 1; - - if (pSprite->hotShape) /* more work if the shape is a mess */ - ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y); - - if((new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)) - { - XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents); - if (!generateEvents) - SyntheticMotion(pDev, new.x, new.y); - } - - /* Tell DDX what the limits are */ - XineramaConstrainCursor(pDev); -} - static Bool XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) @@ -529,16 +595,17 @@ XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) PanoramiXNumScreens*sizeof(WindowPtr)); } else { PanoramiXRes *win; - int i; + int rc, i; - win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW); - - if(!win) + rc = dixLookupResourceByType((pointer *)&win, pWin->drawable.id, + XRT_WINDOW, serverClient, DixReadAccess); + if (rc != Success) return FALSE; for(i = 0; i < PanoramiXNumScreens; i++) { - pSprite->windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW); - if(!pSprite->windows[i]) /* window is being unmapped */ + rc = dixLookupWindow(pSprite->windows + i, win->info[i].id, + serverClient, DixReadAccess); + if (rc != Success) /* window is being unmapped */ return FALSE; } } @@ -546,251 +613,76 @@ XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) } static void -XineramaCheckVirtualMotion( - DeviceIntPtr pDev, - QdEventPtr qe, - WindowPtr pWin) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - - if (qe) - { - pSprite->hot.pScreen = qe->pScreen; /* should always be Screen 0 */ - pSprite->hot.x = qe->event->u.keyButtonPointer.rootX; - pSprite->hot.y = qe->event->u.keyButtonPointer.rootY; - pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : - NullWindow; - } - if (pWin) - { - int x, y, off_x, off_y, i; - BoxRec lims; - - if(!XineramaSetWindowPntrs(pDev, pWin)) - return; - - i = PanoramiXNumScreens - 1; - - REGION_COPY(pSprite->screen, &pSprite->Reg2, - &pSprite->windows[i]->borderSize); - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - - while(i--) { - x = off_x - panoramiXdataPtr[i].x; - y = off_y - panoramiXdataPtr[i].y; - - if(x || y) - REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, x, y); - - REGION_UNION(pSprite->screen, &pSprite->Reg2, &pSprite->Reg2, - &pSprite->windows[i]->borderSize); - - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - } - - lims = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg2); - - if (pSprite->hot.x < lims.x1) - pSprite->hot.x = lims.x1; - else if (pSprite->hot.x >= lims.x2) - pSprite->hot.x = lims.x2 - 1; - if (pSprite->hot.y < lims.y1) - pSprite->hot.y = lims.y1; - else if (pSprite->hot.y >= lims.y2) - pSprite->hot.y = lims.y2 - 1; - - if (REGION_NUM_RECTS(&pSprite->Reg2) > 1) - ConfineToShape(pDev, &pSprite->Reg2, - &pSprite->hot.x, &pSprite->hot.y); - - if (qe) - { - qe->pScreen = pSprite->hot.pScreen; - qe->event->u.keyButtonPointer.rootX = pSprite->hot.x; - qe->event->u.keyButtonPointer.rootY = pSprite->hot.y; - } - } -} - - -static Bool -XineramaCheckMotion(xEvent *xE, DeviceIntPtr pDev) -{ - WindowPtr prevSpriteWin; - SpritePtr pSprite = pDev->spriteInfo->sprite; - - prevSpriteWin = pSprite->win; - - if (xE && !syncEvents.playingEvents) - { - /* GetPointerEvents() guarantees that pointer events have the correct - rootX/Y set already. */ - switch(xE->u.u.type) - { - case ButtonPress: - case ButtonRelease: - case MotionNotify: - break; - default: - if (xE->u.u.type == DeviceButtonPress || - xE->u.u.type == DeviceButtonRelease || - xE->u.u.type == DeviceMotionNotify) - break; - /* all other events return FALSE */ - return FALSE; - } - - /* Motion events entering DIX get translated to Screen 0 - coordinates. Replayed events have already been - translated since they've entered DIX before */ - XE_KBPTR.rootX += panoramiXdataPtr[pSprite->screen->myNum].x - - panoramiXdataPtr[0].x; - XE_KBPTR.rootY += panoramiXdataPtr[pSprite->screen->myNum].y - - panoramiXdataPtr[0].y; - pSprite->hot.x = XE_KBPTR.rootX; - pSprite->hot.y = XE_KBPTR.rootY; - if (pSprite->hot.x < pSprite->physLimits.x1) - pSprite->hot.x = pSprite->physLimits.x1; - else if (pSprite->hot.x >= pSprite->physLimits.x2) - pSprite->hot.x = pSprite->physLimits.x2 - 1; - if (pSprite->hot.y < pSprite->physLimits.y1) - pSprite->hot.y = pSprite->physLimits.y1; - else if (pSprite->hot.y >= pSprite->physLimits.y2) - pSprite->hot.y = pSprite->physLimits.y2 - 1; - - if (pSprite->hotShape) - ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); - - pSprite->hotPhys = pSprite->hot; - if ((pSprite->hotPhys.x != XE_KBPTR.rootX) || - (pSprite->hotPhys.y != XE_KBPTR.rootY)) - { - XineramaSetCursorPosition( - pDev, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); - } - XE_KBPTR.rootX = pSprite->hot.x; - XE_KBPTR.rootY = pSprite->hot.y; - } - - pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y); - - if (pSprite->win != prevSpriteWin) - { - if (prevSpriteWin != NullWindow) { - if (!xE) - UpdateCurrentTimeIf(); - DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win, - NotifyNormal); - } - PostNewCursor(pDev); - return FALSE; - } - return TRUE; -} - - -static void XineramaConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents) { SpritePtr pSprite = pDev->spriteInfo->sprite; - if (syncEvents.playingEvents) - { - XineramaCheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin); - SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y); - } - else - { - int x, y, off_x, off_y, i; - - if(!XineramaSetWindowPntrs(pDev, pWin)) - return; - - i = PanoramiXNumScreens - 1; + int x, y, off_x, off_y, i; - REGION_COPY(pSprite->screen, &pSprite->Reg1, - &pSprite->windows[i]->borderSize); - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - - while(i--) { - x = off_x - panoramiXdataPtr[i].x; - y = off_y - panoramiXdataPtr[i].y; + if(!XineramaSetWindowPntrs(pDev, pWin)) + return; - if(x || y) - REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y); + i = PanoramiXNumScreens - 1; - REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1, - &pSprite->windows[i]->borderSize); + REGION_COPY(pSprite->screen, &pSprite->Reg1, + &pSprite->windows[i]->borderSize); + off_x = panoramiXdataPtr[i].x; + off_y = panoramiXdataPtr[i].y; - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - } + while(i--) { + x = off_x - panoramiXdataPtr[i].x; + y = off_y - panoramiXdataPtr[i].y; - pSprite->hotLimits = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg1); + if(x || y) + REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y); - if(REGION_NUM_RECTS(&pSprite->Reg1) > 1) - pSprite->hotShape = &pSprite->Reg1; - else - pSprite->hotShape = NullRegion; + REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1, + &pSprite->windows[i]->borderSize); - pSprite->confined = FALSE; - pSprite->confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin; - - XineramaCheckPhysLimits(pDev, pSprite->current, - generateEvents); + off_x = panoramiXdataPtr[i].x; + off_y = panoramiXdataPtr[i].y; } -} + pSprite->hotLimits = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg1); -static void -XineramaChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; + if(REGION_NUM_RECTS(&pSprite->Reg1) > 1) + pSprite->hotShape = &pSprite->Reg1; + else + pSprite->hotShape = NullRegion; - if (cursor != pSprite->current) - { - if ((pSprite->current->bits->xhot != cursor->bits->xhot) || - (pSprite->current->bits->yhot != cursor->bits->yhot)) - XineramaCheckPhysLimits(pDev, cursor, FALSE); - (*pSprite->screen->DisplayCursor)(pDev, pSprite->screen, cursor); - FreeCursor(pSprite->current, (Cursor)0); - pSprite->current = cursor; - pSprite->current->refcnt++; - } -} + pSprite->confined = FALSE; + pSprite->confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin; -#else -#define SyntheticMotion(dev, x, y) \ - PostSyntheticMotion(dev, x, y, \ - 0, \ - syncEvents.playingEvents ? \ - syncEvents.time.milliseconds : \ - currentTime.milliseconds); + CheckPhysLimits(pDev, pSprite->current, generateEvents, FALSE, NULL); +} #endif /* PANORAMIX */ +/** + * Modifies the filter for the given protocol event type to the given masks. + * + * There's only two callers: UpdateDeviceState() and XI's SetMaskForExtEvent(). + * The latter initialises masks for the matching XI events, it's a once-off + * setting. + * UDS however changes the mask for MotionNotify and DeviceMotionNotify each + * time a button is pressed to include the matching ButtonXMotion mask in the + * filter. + * + * @param[in] deviceid The device to modify the filter for. + * @param[in] mask The new filter mask. + * @param[in] event Protocol event type. + */ void SetMaskForEvent(int deviceid, Mask mask, int event) { - int coretype; if (deviceid < 0 || deviceid >= MAXDEVICES) FatalError("SetMaskForEvent: bogus device id"); - if ((event < LASTEvent) || (event >= 128)) - FatalError("SetMaskForEvent: bogus event number"); filters[deviceid][event] = mask; - - /* Need to change the mask for the core events too */ - coretype = XItoCoreType(event); - if (coretype) - filters[deviceid][coretype] = mask; } -_X_EXPORT void +void SetCriticalEvent(int event) { if (event >= 128) @@ -841,8 +733,8 @@ CheckPhysLimits( DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents, - Bool confineToScreen, - ScreenPtr pScreen) + Bool confineToScreen, /* unused if PanoramiX on */ + ScreenPtr pScreen) /* unused if PanoramiX on */ { HotSpot new; SpritePtr pSprite = pDev->spriteInfo->sprite; @@ -850,14 +742,24 @@ CheckPhysLimits( if (!cursor) return; new = pSprite->hotPhys; - if (pScreen) - new.pScreen = pScreen; +#ifdef PANORAMIX + if (!noPanoramiXExtension) + /* I don't care what the DDX has to say about it */ + pSprite->physLimits = pSprite->hotLimits; else - pScreen = new.pScreen; - (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits, - &pSprite->physLimits); - pSprite->confined = confineToScreen; - (* pScreen->ConstrainCursor)(pDev, pScreen, &pSprite->physLimits); +#endif + { + if (pScreen) + new.pScreen = pScreen; + else + pScreen = new.pScreen; + (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits, + &pSprite->physLimits); + pSprite->confined = confineToScreen; + (* pScreen->ConstrainCursor)(pDev, pScreen, &pSprite->physLimits); + } + + /* constrain the pointer to those limits */ if (new.x < pSprite->physLimits.x1) new.x = pSprite->physLimits.x1; else @@ -873,13 +775,26 @@ CheckPhysLimits( if ((pScreen != pSprite->hotPhys.pScreen) || (new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)) { - if (pScreen != pSprite->hotPhys.pScreen) - pSprite->hotPhys = new; - (*pScreen->SetCursorPosition) - (pDev, pScreen, new.x, new.y, generateEvents); +#ifdef PANORAMIX + if (!noPanoramiXExtension) + XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents); + else +#endif + { + if (pScreen != pSprite->hotPhys.pScreen) + pSprite->hotPhys = new; + (*pScreen->SetCursorPosition) + (pDev, pScreen, new.x, new.y, generateEvents); + } if (!generateEvents) - SyntheticMotion(pDev, new.x, new.y); + SyntheticMotion(pDev, new.x, new.y); } + +#ifdef PANORAMIX + /* Tell DDX what the limits are */ + if (!noPanoramiXExtension) + XineramaConstrainCursor(pDev); +#endif } static void @@ -889,29 +804,71 @@ CheckVirtualMotion( WindowPtr pWin) { SpritePtr pSprite = pDev->spriteInfo->sprite; + RegionPtr reg = NULL; + DeviceEvent *ev = NULL; -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XineramaCheckVirtualMotion(pDev, qe, pWin); - return; - } -#endif if (qe) { - pSprite->hot.pScreen = qe->pScreen; - pSprite->hot.x = qe->event->u.keyButtonPointer.rootX; - pSprite->hot.y = qe->event->u.keyButtonPointer.rootY; - pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : NullWindow; + ev = (DeviceEvent*)qe->event; + switch(ev->type) + { + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ProximityIn: + case ET_ProximityOut: + pSprite->hot.pScreen = qe->pScreen; + pSprite->hot.x = ev->root_x; + pSprite->hot.y = ev->root_y; + pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : NullWindow; + break; + default: + break; + } } if (pWin) { BoxRec lims; - if (pSprite->hot.pScreen != pWin->drawable.pScreen) - { - pSprite->hot.pScreen = pWin->drawable.pScreen; - pSprite->hot.x = pSprite->hot.y = 0; - } +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + int x, y, off_x, off_y, i; + + if(!XineramaSetWindowPntrs(pDev, pWin)) + return; + + i = PanoramiXNumScreens - 1; + + REGION_COPY(pSprite->screen, &pSprite->Reg2, + &pSprite->windows[i]->borderSize); + off_x = panoramiXdataPtr[i].x; + off_y = panoramiXdataPtr[i].y; + + while(i--) { + x = off_x - panoramiXdataPtr[i].x; + y = off_y - panoramiXdataPtr[i].y; + + if(x || y) + REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, x, y); + + REGION_UNION(pSprite->screen, &pSprite->Reg2, &pSprite->Reg2, + &pSprite->windows[i]->borderSize); + + off_x = panoramiXdataPtr[i].x; + off_y = panoramiXdataPtr[i].y; + } + } else +#endif + { + if (pSprite->hot.pScreen != pWin->drawable.pScreen) + { + pSprite->hot.pScreen = pWin->drawable.pScreen; + pSprite->hot.x = pSprite->hot.y = 0; + } + } + lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize); if (pSprite->hot.x < lims.x1) pSprite->hot.x = lims.x1; @@ -921,17 +878,34 @@ CheckVirtualMotion( pSprite->hot.y = lims.y1; else if (pSprite->hot.y >= lims.y2) pSprite->hot.y = lims.y2 - 1; - if (wBoundingShape(pWin)) - ConfineToShape(pDev, &pWin->borderSize, - &pSprite->hot.x, &pSprite->hot.y); - if (qe) + +#ifdef PANORAMIX + if (!noPanoramiXExtension) + { + if (REGION_NUM_RECTS(&pSprite->Reg2) > 1) + reg = &pSprite->Reg2; + + } else +#endif + { + if (wBoundingShape(pWin)) + reg = &pWin->borderSize; + } + + if (reg) + ConfineToShape(pDev, reg, &pSprite->hot.x, &pSprite->hot.y); + + if (qe && ev) { qe->pScreen = pSprite->hot.pScreen; - qe->event->u.keyButtonPointer.rootX = pSprite->hot.x; - qe->event->u.keyButtonPointer.rootY = pSprite->hot.y; + ev->root_x = pSprite->hot.x; + ev->root_y = pSprite->hot.y; } } - RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; +#ifdef PANORAMIX + if (noPanoramiXExtension) /* No typo. Only set the root win if disabled */ +#endif + RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; } static void @@ -940,13 +914,6 @@ ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bo ScreenPtr pScreen = pWin->drawable.pScreen; SpritePtr pSprite = pDev->spriteInfo->sprite; -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XineramaConfineCursorToWindow(pDev, pWin, generateEvents); - return; - } -#endif - if (syncEvents.playingEvents) { CheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin); @@ -954,6 +921,12 @@ ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bo } else { +#ifdef PANORAMIX + if(!noPanoramiXExtension) { + XineramaConfineCursorToWindow(pDev, pWin, generateEvents); + return; + } +#endif pSprite->hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize); pSprite->hotShape = wBoundingShape(pWin) ? &pWin->borderSize : NullRegion; @@ -962,7 +935,7 @@ ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bo } } -_X_EXPORT Bool +Bool PointerConfinedToScreen(DeviceIntPtr pDev) { return pDev->spriteInfo->sprite->confined; @@ -979,13 +952,7 @@ static void ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor) { SpritePtr pSprite = pDev->spriteInfo->sprite; - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XineramaChangeToCursor(pDev, cursor); - return; - } -#endif + ScreenPtr pScreen; if (cursor != pSprite->current) { @@ -993,9 +960,15 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor) (pSprite->current->bits->yhot != cursor->bits->yhot)) CheckPhysLimits(pDev, cursor, FALSE, pSprite->confined, (ScreenPtr)NULL); - (*pSprite->hotPhys.pScreen->DisplayCursor) (pDev, - pSprite->hotPhys.pScreen, - cursor); +#ifdef PANORAMIX + /* XXX: is this really necessary?? (whot) */ + if (!noPanoramiXExtension) + pScreen = pSprite->screen; + else +#endif + pScreen = pSprite->hotPhys.pScreen; + + (*pScreen->DisplayCursor)(pDev, pScreen, cursor); FreeCursor(pSprite->current, (Cursor)0); pSprite->current = cursor; pSprite->current->refcnt++; @@ -1063,7 +1036,7 @@ PostNewCursor(DeviceIntPtr pDev) * @param dev device which you want to know its current root window * @return root window where dev's sprite is located */ -_X_EXPORT WindowPtr +WindowPtr GetCurrentRootWindow(DeviceIntPtr dev) { return RootWindow(dev); @@ -1072,7 +1045,7 @@ GetCurrentRootWindow(DeviceIntPtr dev) /** * @return window underneath the cursor sprite. */ -_X_EXPORT WindowPtr +WindowPtr GetSpriteWindow(DeviceIntPtr pDev) { return pDev->spriteInfo->sprite->win; @@ -1081,7 +1054,7 @@ GetSpriteWindow(DeviceIntPtr pDev) /** * @return current sprite cursor. */ -_X_EXPORT CursorPtr +CursorPtr GetSpriteCursor(DeviceIntPtr pDev) { return pDev->spriteInfo->sprite->current; @@ -1090,7 +1063,7 @@ GetSpriteCursor(DeviceIntPtr pDev) /** * Set x/y current sprite position in screen coordinates. */ -_X_EXPORT void +void GetSpritePosition(DeviceIntPtr pDev, int *px, int *py) { SpritePtr pSprite = pDev->spriteInfo->sprite; @@ -1099,7 +1072,7 @@ GetSpritePosition(DeviceIntPtr pDev, int *px, int *py) } #ifdef PANORAMIX -_X_EXPORT int +int XineramaGetCursorScreen(DeviceIntPtr pDev) { if(!noPanoramiXExtension) { @@ -1113,29 +1086,32 @@ XineramaGetCursorScreen(DeviceIntPtr pDev) #define TIMESLOP (5 * 60 * 1000) /* 5 minutes */ static void -MonthChangedOrBadTime(xEvent *xE) +MonthChangedOrBadTime(InternalEvent *ev) { /* If the ddx/OS is careless about not processing timestamped events from * different sources in sorted order, then it's possible for time to go * backwards when it should not. Here we ensure a decent time. */ - if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP) + if ((currentTime.milliseconds - ev->any.time) > TIMESLOP) currentTime.months++; else - XE_KBPTR.time = currentTime.milliseconds; + ev->any.time = currentTime.milliseconds; } -#define NoticeTime(xE) { \ - if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \ - MonthChangedOrBadTime(xE); \ - currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \ - lastDeviceEventTime = currentTime; } +static void +NoticeTime(InternalEvent *ev) +{ + if (ev->any.time < currentTime.milliseconds) + MonthChangedOrBadTime(ev); + currentTime.milliseconds = ev->any.time; + lastDeviceEventTime = currentTime; +} void -NoticeEventTime(xEvent *xE) +NoticeEventTime(InternalEvent *ev) { if (!syncEvents.playingEvents) - NoticeTime(xE); + NoticeTime(ev); } /************************************************************************** @@ -1148,23 +1124,23 @@ NoticeEventTime(xEvent *xE) * linked list for later delivery. */ void -EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) +EnqueueEvent(InternalEvent *ev, DeviceIntPtr device) { QdEventPtr tail = *syncEvents.pendtail; QdEventPtr qe; SpritePtr pSprite = device->spriteInfo->sprite; int eventlen; + DeviceEvent *event = (DeviceEvent*)ev; + NoticeTime((InternalEvent*)event); - NoticeTime(xE); - -#ifdef XKB /* Fix for key repeating bug. */ if (device->key != NULL && device->key->xkbInfo != NULL && - (xE->u.u.type == KeyRelease || xE->u.u.type == DeviceKeyRelease)) - AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail); -#endif + event->type == ET_KeyRelease) + AccessXCancelRepeatKey(device->key->xkbInfo, event->detail.key); +#if 0 + /* FIXME: I'm broken now. Please fix me. */ if (DeviceEventCallback) { DeviceEventInfoRec eventinfo; @@ -1181,59 +1157,48 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) XE_KBPTR.root = WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; eventinfo.events = xE; - eventinfo.count = count; + eventinfo.count = nevents; CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); } - if (xE->u.u.type == DeviceMotionNotify) +#endif + if (event->type == ET_Motion) { #ifdef PANORAMIX if(!noPanoramiXExtension) { - XE_KBPTR.rootX += panoramiXdataPtr[pSprite->screen->myNum].x - + event->root_x += panoramiXdataPtr[pSprite->screen->myNum].x - panoramiXdataPtr[0].x; - XE_KBPTR.rootY += panoramiXdataPtr[pSprite->screen->myNum].y - + event->root_y += panoramiXdataPtr[pSprite->screen->myNum].y - panoramiXdataPtr[0].y; } #endif - pSprite->hotPhys.x = XE_KBPTR.rootX; - pSprite->hotPhys.y = XE_KBPTR.rootY; + pSprite->hotPhys.x = event->root_x; + pSprite->hotPhys.y = event->root_y; /* do motion compression, but not if from different devices */ if (tail && - (tail->event->u.u.type == DeviceMotionNotify) && + (tail->event->any.type == ET_Motion) && (tail->device == device) && (tail->pScreen == pSprite->hotPhys.pScreen)) { - tail->event->u.keyButtonPointer.rootX = pSprite->hotPhys.x; - tail->event->u.keyButtonPointer.rootY = pSprite->hotPhys.y; - tail->event->u.keyButtonPointer.time = XE_KBPTR.time; + DeviceEvent *tailev = (DeviceEvent*)tail->event; + tailev->root_x = pSprite->hotPhys.x; + tailev->root_y = pSprite->hotPhys.y; + tailev->time = event->time; tail->months = currentTime.months; return; } } - eventlen = count * sizeof(xEvent); - if (xE->u.u.type == GenericEvent) /* count is 1 for GenericEvents */ - eventlen += ((xGenericEvent*)xE)->length * 4; + eventlen = event->length; - qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + eventlen); + qe = xalloc(sizeof(QdEventRec) + eventlen); if (!qe) return; qe->next = (QdEventPtr)NULL; qe->device = device; qe->pScreen = pSprite->hotPhys.pScreen; qe->months = currentTime.months; - qe->event = (xEvent *)(qe + 1); - qe->evcount = count; - if (xE->u.u.type == GenericEvent) - { - memcpy(qe->event, xE, eventlen); - } else - { - xEvent *qxE; - for (qxE = qe->event; --count >= 0; qxE++, xE++) - { - *qxE = *xE; - } - } + qe->event = (InternalEvent *)(qe + 1); + memcpy(qe->event, event, eventlen); if (tail) syncEvents.pendtail = &tail->next; *syncEvents.pendtail = qe; @@ -1254,7 +1219,6 @@ PlayReleasedEvents(void) QdEventPtr *prev, qe; DeviceIntPtr dev; DeviceIntPtr pDev; - static CARD32 lastKnownMillis = 0; /* Hack, see comment below */ prev = &syncEvents.pending; while ( (qe = *prev) ) @@ -1265,36 +1229,37 @@ PlayReleasedEvents(void) pDev = qe->device; if (*syncEvents.pendtail == *prev) syncEvents.pendtail = prev; - if (qe->event->u.u.type == DeviceMotionNotify) + if (qe->event->any.type == ET_Motion) CheckVirtualMotion(pDev, qe, NullWindow); syncEvents.time.months = qe->months; - /* XXX: Hack! We can't reliably get the time from GenericEvents, - since we don't know which struct it may be. So we store the time - when we know it, and re-use it when we can't get it. */ - if (qe->event->u.u.type == GenericEvent) - { - syncEvents.time.milliseconds = lastKnownMillis; - } else - { - syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time; - lastKnownMillis = syncEvents.time.milliseconds; - } + syncEvents.time.milliseconds = qe->event->any.time; #ifdef PANORAMIX /* Translate back to the sprite screen since processInputProc will translate from sprite screen to screen 0 upon reentry to the DIX layer */ - /* XXX: we can't do that for generic events */ if(!noPanoramiXExtension) { - qe->event->u.keyButtonPointer.rootX += - panoramiXdataPtr[0].x - - panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x; - qe->event->u.keyButtonPointer.rootY += - panoramiXdataPtr[0].y - - panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].y; + DeviceEvent *ev = (DeviceEvent*)(qe->event); + switch(ev->type) + { + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ProximityIn: + case ET_ProximityOut: + ev->root_x += panoramiXdataPtr[0].x - + panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x; + ev->root_y += panoramiXdataPtr[0].y - + panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].y; + break; + default: + break; + } + } #endif - (*qe->device->public.processInputProc)(qe->event, qe->device, - qe->evcount); + (*qe->device->public.processInputProc)(qe->event, qe->device); xfree(qe); for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen; dev = dev->next) ; @@ -1334,9 +1299,6 @@ FreezeThaw(DeviceIntPtr dev, Bool frozen) * runs up the sprite tree (spriteTrace) and searches for the window to replay * the events from. If it is found, it checks for passive grabs one down from * the window or delivers the events. - * - * Since the events in the EQ are always XI events, we need to emulate core - * events here. */ static void ComputeFreezes(void) @@ -1344,8 +1306,6 @@ ComputeFreezes(void) DeviceIntPtr replayDev = syncEvents.replayDev; int i; WindowPtr w; - xEvent *xE; - int count; GrabPtr grab; DeviceIntPtr dev; @@ -1357,31 +1317,32 @@ ComputeFreezes(void) syncEvents.playingEvents = TRUE; if (replayDev) { - xE = replayDev->deviceGrab.sync.event; - count = replayDev->deviceGrab.sync.evcount; + DeviceEvent* event = replayDev->deviceGrab.sync.event; + syncEvents.replayDev = (DeviceIntPtr)NULL; - w = XYToWindow(replayDev, XE_KBPTR.rootX, XE_KBPTR.rootY); + w = XYToWindow(replayDev, event->root_x, event->root_y); for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++) { if (syncEvents.replayWin == replayDev->spriteInfo->sprite->spriteTrace[i]) { - if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) { - if (replayDev->focus && !IsPointerEvent(xE)) - DeliverFocusedEvent(replayDev, xE, w, count); + if (!CheckDeviceGrabs(replayDev, event, i+1)) { + if (replayDev->focus && !IsPointerEvent((InternalEvent*)event)) + DeliverFocusedEvent(replayDev, (InternalEvent*)event, w); else - DeliverDeviceEvents(w, xE, NullGrab, NullWindow, - replayDev, count); + DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab, + NullWindow, replayDev); } goto playmore; } } /* must not still be in the same stack */ - if (replayDev->focus && !IsPointerEvent(xE)) - DeliverFocusedEvent(replayDev, xE, w, count); + if (replayDev->focus && !IsPointerEvent((InternalEvent*)event)) + DeliverFocusedEvent(replayDev, (InternalEvent*)event, w); else - DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count); + DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab, + NullWindow, replayDev); } playmore: for (dev = inputInfo.devices; dev; dev = dev->next) @@ -1467,7 +1428,7 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode) The correct thing to do would be to freeze all SDs attached to the paired master device. */ - if (thisDev->isMaster) + if (IsMaster(thisDev)) { dev = GetPairedDevice(thisDev); if (otherMode == GrabModeSync) @@ -1483,6 +1444,54 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode) ComputeFreezes(); } +/* Only ever used if a grab is called on an attached slave device. */ +static int GrabPrivateKeyIndex; +static DevPrivateKey GrabPrivateKey = &GrabPrivateKeyIndex; + +/** + * Save the device's master device in the devPrivates. This needs to be done + * if a client directly grabs a slave device that is attached to a master. For + * the duration of the grab, the device is detached, ungrabbing re-attaches it + * though. + * + * We store the ID of the master device only in case the master disappears + * while the device has a grab. + */ +static void +DetachFromMaster(DeviceIntPtr dev) +{ + int id; + if (!dev->u.master) + return; + + id = dev->u.master->id; + + dixSetPrivate(&dev->devPrivates, GrabPrivateKey, (void *)id); + AttachDevice(NULL, dev, NULL); +} + +static void +ReattachToOldMaster(DeviceIntPtr dev) +{ + int id; + void *p; + DeviceIntPtr master = NULL; + + if (IsMaster(dev)) + return; + + + p = dixLookupPrivate(&dev->devPrivates, GrabPrivateKey); + id = (int)p; /* silence gcc warnings */ + dixLookupDevice(&master, id, serverClient, DixUseAccess); + + if (master) + { + AttachDevice(serverClient, dev, master); + dixSetPrivate(&dev->devPrivates, GrabPrivateKey, NULL); + } +} + /** * Activate a pointer grab on the given device. A pointer grab will cause all * core pointer events of this device to be delivered to the grabbing client only. @@ -1508,6 +1517,11 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, : mouse->spriteInfo->sprite->win; Bool isPassive = autoGrab & ~ImplicitGrabMask; + /* slave devices need to float for the duration of the grab. */ + if (grab->grabtype == GRABTYPE_XI2 && + !(autoGrab & ImplicitGrabMask) && !IsMaster(mouse)) + DetachFromMaster(mouse); + if (grab->confineTo) { if (grab->confineTo->drawable.pScreen @@ -1516,7 +1530,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, mouse->spriteInfo->sprite->hotPhys.y = 0; ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE); } - DoEnterLeaveEvents(mouse, oldWin, grab->window, NotifyGrab); + DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab); mouse->valuator->motionHintWindow = NullWindow; if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time; @@ -1542,25 +1556,20 @@ DeactivatePointerGrab(DeviceIntPtr mouse) { GrabPtr grab = mouse->deviceGrab.grab; DeviceIntPtr dev; + Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab && + mouse->deviceGrab.implicitGrab); mouse->valuator->motionHintWindow = NullWindow; mouse->deviceGrab.grab = NullGrab; mouse->deviceGrab.sync.state = NOT_GRABBED; mouse->deviceGrab.fromPassiveGrab = FALSE; - /* make sure the potential XGE event mask is freed too*/ - if (grab->genericMasks) - { - xfree(grab->genericMasks); - grab->genericMasks = NULL; - } - for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev->deviceGrab.sync.other == grab) dev->deviceGrab.sync.other = NullGrab; } - DoEnterLeaveEvents(mouse, grab->window, + DoEnterLeaveEvents(mouse, mouse->id, grab->window, mouse->spriteInfo->sprite->win, NotifyUngrab); if (grab->confineTo) ConfineCursorToWindow(mouse, RootWindow(mouse), FALSE, FALSE); @@ -1568,6 +1577,9 @@ DeactivatePointerGrab(DeviceIntPtr mouse) if (grab->cursor) FreeCursor(grab->cursor, (Cursor)0); + if (!wasImplicit && grab->grabtype == GRABTYPE_XI2) + ReattachToOldMaster(mouse); + ComputeFreezes(); } @@ -1582,6 +1594,12 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass GrabInfoPtr grabinfo = &keybd->deviceGrab; WindowPtr oldWin; + /* slave devices need to float for the duration of the grab. */ + if (grab->grabtype == GRABTYPE_XI2 && + !(passive & ImplicitGrabMask) && + !IsMaster(keybd)) + DetachFromMaster(keybd); + if (grabinfo->grab) oldWin = grabinfo->grab->window; else if (keybd->focus) @@ -1589,7 +1607,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass else oldWin = keybd->spriteInfo->sprite->win; if (oldWin == FollowKeyboardWin) - oldWin = inputInfo.keyboard->focus->win; + oldWin = keybd->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); @@ -1600,6 +1618,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass grabinfo->activeGrab = *grab; grabinfo->grab = &grabinfo->activeGrab; grabinfo->fromPassiveGrab = passive; + grabinfo->implicitGrab = passive & ImplicitGrabMask; CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode); } @@ -1613,6 +1632,8 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd) DeviceIntPtr dev; WindowPtr focusWin = keybd->focus ? keybd->focus->win : keybd->spriteInfo->sprite->win; + Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab && + keybd->deviceGrab.implicitGrab); if (focusWin == FollowKeyboardWin) focusWin = inputInfo.keyboard->focus->win; @@ -1621,11 +1642,6 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd) keybd->deviceGrab.grab = NullGrab; keybd->deviceGrab.sync.state = NOT_GRABBED; keybd->deviceGrab.fromPassiveGrab = FALSE; - if (grab->genericMasks) - { - xfree(grab->genericMasks); - grab->genericMasks = NULL; - } for (dev = inputInfo.devices; dev; dev = dev->next) { @@ -1634,6 +1650,9 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd) } DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab); + if (!wasImplicit && grab->grabtype == GRABTYPE_XI2) + ReattachToOldMaster(keybd); + ComputeFreezes(); } @@ -1641,8 +1660,7 @@ void AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, - int newState, - Bool core) + int newState) { Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced; TimeStamp grabTime; @@ -1748,7 +1766,7 @@ AllowSome(ClientPtr client, { if (dev == thisDev) continue; - devgrabinfo = (core) ? &dev->deviceGrab : &dev->deviceGrab; + devgrabinfo = &dev->deviceGrab; if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client)) devgrabinfo->sync.state = THAWED; @@ -1784,28 +1802,28 @@ ProcAllowEvents(ClientPtr client) switch (stuff->mode) { case ReplayPointer: - AllowSome(client, time, mouse, NOT_GRABBED, True); + AllowSome(client, time, mouse, NOT_GRABBED); break; case SyncPointer: - AllowSome(client, time, mouse, FREEZE_NEXT_EVENT, True); + AllowSome(client, time, mouse, FREEZE_NEXT_EVENT); break; case AsyncPointer: - AllowSome(client, time, mouse, THAWED, True); + AllowSome(client, time, mouse, THAWED); break; case ReplayKeyboard: - AllowSome(client, time, keybd, NOT_GRABBED, True); + AllowSome(client, time, keybd, NOT_GRABBED); break; case SyncKeyboard: - AllowSome(client, time, keybd, FREEZE_NEXT_EVENT, True); + AllowSome(client, time, keybd, FREEZE_NEXT_EVENT); break; case AsyncKeyboard: - AllowSome(client, time, keybd, THAWED, True); + AllowSome(client, time, keybd, THAWED); break; case SyncBoth: - AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT, True); + AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT); break; case AsyncBoth: - AllowSome(client, time, keybd, THAWED_BOTH, True); + AllowSome(client, time, keybd, THAWED_BOTH); break; default: client->errorValue = stuff->mode; @@ -1868,7 +1886,7 @@ ReleaseActiveGrabs(ClientPtr client) * @return 1 if event was delivered, 0 if not or -1 if grab was not set by the * client. */ -_X_EXPORT int +int TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, int count, Mask mask, Mask filter, GrabPtr grab) { @@ -1876,70 +1894,124 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, int type; #ifdef DEBUG_EVENTS - ErrorF("[dix] Event([%d, %d], mask=0x%x), client=%d", - pEvents->u.u.type, pEvents->u.u.detail, mask, client->index); + ErrorF("[dix] Event([%d, %d], mask=0x%lx), client=%d%s", + pEvents->u.u.type, pEvents->u.u.detail, mask, + client ? client->index : -1, + (client && client->clientGone) ? " (gone)" : ""); #endif - if ((client) && (client != serverClient) && (!client->clientGone) && - ((filter == CantBeFiltered) || (mask & filter))) - { - if (grab && !SameClient(grab, client)) - return -1; /* don't send, but notify caller */ - type = pEvents->u.u.type; - if (type == MotionNotify) - { - if (mask & PointerMotionHintMask) - { - if (WID(dev->valuator->motionHintWindow) == - pEvents->u.keyButtonPointer.event) - { + + if (!client || client == serverClient || client->clientGone) { #ifdef DEBUG_EVENTS - ErrorF("[dix] \n"); - ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n"); + ErrorF(" not delivered to fake/dead client\n"); #endif - return 1; /* don't send, but pretend we did */ - } - pEvents->u.u.detail = NotifyHint; - } - else - { - pEvents->u.u.detail = NotifyNormal; - } - } - else - { - if ((type == DeviceMotionNotify) && - MaybeSendDeviceMotionNotifyHint - ((deviceKeyButtonPointer*)pEvents, mask) != 0) - return 1; - } - type &= 0177; - if (type != KeymapNotify) - { - /* all extension events must have a sequence number */ - for (i = 0; i < count; i++) - pEvents[i].u.u.sequenceNumber = client->sequence; - } + return 0; + } - if (BitIsOn(criticalEvents, type)) - { - if (client->smart_priority < SMART_MAX_PRIORITY) - client->smart_priority++; - SetCriticalOutputPending(); - } + if (filter != CantBeFiltered && !(mask & filter)) + { + #ifdef DEBUG_EVENTS + ErrorF(" filtered\n"); + #endif + return 0; + } + + if (grab && !SameClient(grab, client)) + { +#ifdef DEBUG_EVENTS + ErrorF(" not delivered due to grab\n"); +#endif + return -1; /* don't send, but notify caller */ + } - WriteEventsToClient(client, count, pEvents); + type = pEvents->u.u.type; + if (type == MotionNotify) + { + if (mask & PointerMotionHintMask) + { + if (WID(dev->valuator->motionHintWindow) == + pEvents->u.keyButtonPointer.event) + { #ifdef DEBUG_EVENTS - ErrorF("[dix] delivered\n"); + ErrorF("[dix] \n"); + ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n"); #endif - return 1; + return 1; /* don't send, but pretend we did */ + } + pEvents->u.u.detail = NotifyHint; + } + else + { + pEvents->u.u.detail = NotifyNormal; + } } - else + else if (type == DeviceMotionNotify) + { + if (MaybeSendDeviceMotionNotifyHint((deviceKeyButtonPointer*)pEvents, + mask) != 0) + return 1; + } else if (type == KeyPress) { + if (EventIsKeyRepeat(pEvents)) + { + if (!_XkbWantsDetectableAutoRepeat(client)) + { + xEvent release = *pEvents; + release.u.u.type = KeyRelease; + release.u.u.sequenceNumber = client->sequence; + WriteEventsToClient(client, 1, &release); #ifdef DEBUG_EVENTS - ErrorF("[dix] \n"); + ErrorF(" (plus fake core release for repeat)"); #endif - return 0; + } else + { +#ifdef DEBUG_EVENTS + ErrorF(" (detectable autorepeat for core)"); +#endif + } + } + + } else if (type == DeviceKeyPress) + { + if (EventIsKeyRepeat(pEvents)) + { + if (!_XkbWantsDetectableAutoRepeat(client)) + { + deviceKeyButtonPointer release = *(deviceKeyButtonPointer *)pEvents; + release.type = DeviceKeyRelease; + release.sequenceNumber = client->sequence; +#ifdef DEBUG_EVENTS + ErrorF(" (plus fake xi1 release for repeat)"); +#endif + WriteEventsToClient(client, 1, (xEvent *) &release); + } + else { +#ifdef DEBUG_EVENTS + ErrorF(" (detectable autorepeat for core)"); +#endif + } + } + } + + type &= 0177; + if (type != KeymapNotify) + { + /* all extension events must have a sequence number */ + for (i = 0; i < count; i++) + pEvents[i].u.u.sequenceNumber = client->sequence; } + + if (BitIsOn(criticalEvents, type)) + { + if (client->smart_priority < SMART_MAX_PRIORITY) + client->smart_priority++; + SetCriticalOutputPending(); + } + + WriteEventsToClient(client, count, pEvents); +#ifdef DEBUG_EVENTS + ErrorF("[dix] delivered\n"); +#endif + return 1; } /** @@ -1959,13 +2031,12 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, * @param count Number of elements in pEvents. * @param filter Mask based on event type. * @param grab Possible grab on the device that caused the event. - * @param mskidx Mask index, depending on device that caused event. * * @return Number of events delivered to various clients. */ int DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent - *pEvents, int count, Mask filter, GrabPtr grab, int mskidx) + *pEvents, int count, Mask filter, GrabPtr grab) { int deliveries = 0, nondeliveries = 0; int attempt; @@ -1975,17 +2046,16 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent this mask is the mask of the grab. */ int type = pEvents->u.u.type; - /* CantBeFiltered means only window owner gets the event */ - if ((filter == CantBeFiltered) || - (!(type & EXTENSION_EVENT_BASE) && type != GenericEvent)) + + /* Deliver to window owner */ + if ((filter == CantBeFiltered) || CORE_EVENT(pEvents)) { /* if nobody ever wants to see this event, skip some work */ if (filter != CantBeFiltered && !((wOtherEventMasks(pWin)|pWin->eventMask) & filter)) return 0; - if (!(type & EXTENSION_EVENT_BASE) && - IsInterferingGrab(wClient(pWin), pDev, pEvents)) + if (IsInterferingGrab(wClient(pWin), pDev, pEvents)) return 0; if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count)) @@ -2003,80 +2073,51 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent nondeliveries--; } } + + /* CantBeFiltered means only window owner gets the event */ if (filter != CantBeFiltered) { - /* Handle generic events */ - if (type == GenericEvent) + if (CORE_EVENT(pEvents)) + other = (InputClients *)wOtherClients(pWin); + else if (XI2_EVENT(pEvents)) { - GenericMaskPtr gmask; - /* We don't do more than one GenericEvent at a time. */ - if (count > 1) - { - ErrorF("[dix] Do not send more than one GenericEvent at a time!\n"); + OtherInputMasks *inputMasks = wOtherInputMasks(pWin); + /* Has any client selected for the event? */ + if (!GetWindowXI2Mask(pDev, pWin, pEvents)) return 0; - } - - /* if we get here, filter should be set to the GE specific mask. - check if any client wants it */ - if (!GEDeviceMaskIsSet(pWin, pDev, GEEXT(pEvents), filter)) + other = inputMasks->inputClients; + } else { + OtherInputMasks *inputMasks = wOtherInputMasks(pWin); + /* Has any client selected for the event? */ + if (!inputMasks || + !(inputMasks->inputEvents[pDev->id] & filter)) return 0; - /* run through all clients, deliver event */ - for (gmask = GECLIENT(pWin); gmask; gmask = gmask->next) - { - if (gmask->eventMask[GEEXTIDX(pEvents)] & filter) - { - if (XaceHook(XACE_RECEIVE_ACCESS, rClient(gmask), pWin, - pEvents, count)) - /* do nothing */; - else if (TryClientEvents(rClient(gmask), pDev, - pEvents, count, - gmask->eventMask[GEEXTIDX(pEvents)], - filter, grab) > 0) - { - deliveries++; - } else - nondeliveries--; - } - } + other = inputMasks->inputClients; } - else { - /* Traditional event */ - if (type & EXTENSION_EVENT_BASE) - { - OtherInputMasks *inputMasks; - inputMasks = wOtherInputMasks(pWin); - if (!inputMasks || - !(inputMasks->inputEvents[mskidx] & filter)) - return 0; - other = inputMasks->inputClients; - } - else - other = (InputClients *)wOtherClients(pWin); - for (; other; other = other->next) + for (; other; other = other->next) + { + Mask mask; + if (IsInterferingGrab(rClient(other), pDev, pEvents)) + continue; + + mask = GetEventMask(pDev, pEvents, other); + + if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, + pEvents, count)) + /* do nothing */; + else if ( (attempt = TryClientEvents(rClient(other), pDev, + pEvents, count, + mask, filter, grab)) ) { - /* core event? check for grab interference */ - if (!(type & EXTENSION_EVENT_BASE) && - IsInterferingGrab(rClient(other), pDev, pEvents)) - continue; - - if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, - pEvents, count)) - /* do nothing */; - else if ( (attempt = TryClientEvents(rClient(other), pDev, - pEvents, count, - other->mask[mskidx], - filter, grab)) ) + if (attempt > 0) { - if (attempt > 0) - { - deliveries++; - client = rClient(other); - deliveryMask = other->mask[mskidx]; - } else - nondeliveries--; - } + deliveries++; + client = rClient(other); + deliveryMask = mask; + } else + nondeliveries--; } } } @@ -2084,13 +2125,15 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent * Note that since core events are delivered first, an implicit grab may * be activated on a core grab, stopping the XI events. */ - if ((type == DeviceButtonPress || type == ButtonPress) + if ((type == DeviceButtonPress || type == ButtonPress || + ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress))) && deliveries && (!grab)) { GrabRec tempGrab; OtherInputMasks *inputMasks; + memset(&tempGrab, 0, sizeof(GrabRec)); tempGrab.next = NULL; tempGrab.device = pDev; tempGrab.resource = client->clientAsMask; @@ -2101,27 +2144,25 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent tempGrab.pointerMode = GrabModeAsync; tempGrab.confineTo = NullWindow; tempGrab.cursor = NullCursor; - tempGrab.coreGrab = (type == ButtonPress); + tempGrab.type = type; + if (type == ButtonPress) + tempGrab.grabtype = GRABTYPE_CORE; + else if (type == DeviceButtonPress) + tempGrab.grabtype = GRABTYPE_XI; + else + { + tempGrab.type = ((xGenericEvent*)pEvents)->evtype; + tempGrab.grabtype = GRABTYPE_XI2; + } - /* get the XI device mask */ + /* get the XI and XI2 device mask */ inputMasks = wOtherInputMasks(pWin); tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0; - /* get the XGE event mask. */ - tempGrab.genericMasks = NULL; - if (pWin->optional && pWin->optional->geMasks) - { - GenericClientMasksPtr gemasks = pWin->optional->geMasks; - GenericMaskPtr geclient = gemasks->geClients; - while(geclient && rClient(geclient) != client) - geclient = geclient->next; - if (geclient) - { - tempGrab.genericMasks = xcalloc(1, sizeof(GenericMaskRec)); - *tempGrab.genericMasks = *geclient; - tempGrab.genericMasks->next = NULL; - } - } + if (inputMasks) + memcpy(tempGrab.xi2mask, inputMasks->xi2mask, + sizeof(tempGrab.xi2mask)); + (*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab, currentTime, TRUE | ImplicitGrabMask); } @@ -2129,11 +2170,8 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent pDev->valuator->motionHintWindow = pWin; else { - if (((type == DeviceMotionNotify) -#ifdef XKB - || (type == DeviceButtonPress) -#endif - ) && deliveries) + if ((type == DeviceMotionNotify || type == DeviceButtonPress) && + deliveries) CheckDeviceGrabAndHintWindow (pWin, type, (deviceKeyButtonPointer*) pEvents, grab, client, deliveryMask); @@ -2217,6 +2255,37 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, return 2; } +static Window FindChildForEvent(DeviceIntPtr dev, WindowPtr event) +{ + SpritePtr pSprite = dev->spriteInfo->sprite; + WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1]; + Window child = None; + + /* If the search ends up past the root should the child field be + set to none or should the value in the argument be passed + through. It probably doesn't matter since everyone calls + this function with child == None anyway. */ + while (w) + { + /* If the source window is same as event window, child should be + none. Don't bother going all all the way back to the root. */ + + if (w == event) + { + child = None; + break; + } + + if (w->parent == event) + { + child = w->drawable.id; + break; + } + w = w->parent; + } + return child; +} + /** * Adjust event fields to comply with the window properties. * @@ -2225,7 +2294,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, * @param child Child window setting for event (if applicable) * @param calcChild If True, calculate the child window. */ -static void +void FixUpEventFromWindow( DeviceIntPtr pDev, xEvent *xE, @@ -2235,59 +2304,141 @@ FixUpEventFromWindow( { SpritePtr pSprite = pDev->spriteInfo->sprite; - if (xE->u.u.type == GenericEvent) /* just a safety barrier */ - return; - if (calcChild) + child = FindChildForEvent(pDev, pWin); + + if (XI2_EVENT(xE)) { - WindowPtr w= pSprite->spriteTrace[pSprite->spriteTraceGood-1]; - /* If the search ends up past the root should the child field be - set to none or should the value in the argument be passed - through. It probably doesn't matter since everyone calls - this function with child == None anyway. */ + xXIDeviceEvent* event = (xXIDeviceEvent*)xE; + + if (event->evtype == XI_RawKeyPress || + event->evtype == XI_RawKeyRelease || + event->evtype == XI_RawButtonPress || + event->evtype == XI_RawButtonRelease || + event->evtype == XI_RawMotion || + event->evtype == XI_DeviceChanged || + event->evtype == XI_HierarchyChanged || + event->evtype == XI_PropertyEvent) + return; - while (w) + event->root = RootWindow(pDev)->drawable.id; + event->event = pWin->drawable.id; + if (pSprite->hot.pScreen == pWin->drawable.pScreen) + { + event->event_x = event->root_x - FP1616(pWin->drawable.x, 0); + event->event_y = event->root_y - FP1616(pWin->drawable.y, 0); + event->child = child; + } else { - /* If the source window is same as event window, child should be - none. Don't bother going all all the way back to the root. */ + event->event_x = 0; + event->event_y = 0; + event->child = None; + } - if (w == pWin) - { - child = None; - break; - } + if (event->evtype == XI_Enter || event->evtype == XI_Leave || + event->evtype == XI_FocusIn || event->evtype == XI_FocusOut) + ((xXIEnterEvent*)event)->same_screen = + (pSprite->hot.pScreen == pWin->drawable.pScreen); - if (w->parent == pWin) - { - child = w->drawable.id; - break; - } - w = w->parent; - } - } - XE_KBPTR.root = RootWindow(pDev)->drawable.id; - XE_KBPTR.event = pWin->drawable.id; - if (pSprite->hot.pScreen == pWin->drawable.pScreen) - { - XE_KBPTR.sameScreen = xTrue; - XE_KBPTR.child = child; - XE_KBPTR.eventX = - XE_KBPTR.rootX - pWin->drawable.x; - XE_KBPTR.eventY = - XE_KBPTR.rootY - pWin->drawable.y; - } - else + } else { - XE_KBPTR.sameScreen = xFalse; - XE_KBPTR.child = None; - XE_KBPTR.eventX = 0; - XE_KBPTR.eventY = 0; + XE_KBPTR.root = RootWindow(pDev)->drawable.id; + XE_KBPTR.event = pWin->drawable.id; + if (pSprite->hot.pScreen == pWin->drawable.pScreen) + { + XE_KBPTR.sameScreen = xTrue; + XE_KBPTR.child = child; + XE_KBPTR.eventX = + XE_KBPTR.rootX - pWin->drawable.x; + XE_KBPTR.eventY = + XE_KBPTR.rootY - pWin->drawable.y; + } + else + { + XE_KBPTR.sameScreen = xFalse; + XE_KBPTR.child = None; + XE_KBPTR.eventX = 0; + XE_KBPTR.eventY = 0; + } } } /** - * Deliver events caused by input devices. Called for both core input events - * and XI events. + * Return masks for EventIsDeliverable. + * @defgroup EventIsDeliverable return flags + * @{ + */ +#define XI_MASK (1 << 0) /**< XI mask set on window */ +#define CORE_MASK (1 << 1) /**< Core mask set on window */ +#define DONT_PROPAGATE_MASK (1 << 2) /**< DontPropagate mask set on window */ +#define XI2_MASK (1 << 3) /**< XI2 mask set on window */ +/* @} */ + +/** + * Check if a given event is deliverable at all on a given window. + * + * This function only checks if any client wants it, not for a specific + * client. + * + * @param[in] dev The device this event is being sent for. + * @param[in] event The event that is to be sent. + * @param[in] win The current event window. + * + * @return Bitmask of ::XI2_MASK, ::XI_MASK, ::CORE_MASK, and + * ::DONT_PROPAGATE_MASK. + */ +static int +EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win) +{ + int rc = 0; + int filter = 0; + int type; + OtherInputMasks *inputMasks = wOtherInputMasks(win); + xEvent ev; + + /* XXX: this makes me gag */ + type = GetXI2Type(event); + ev.u.u.type = GenericEvent; /* GetEventFilter only cares about type and evtype*/ + ((xGenericEvent*)&ev)->extension = IReqCode; + ((xGenericEvent*)&ev)->evtype = type; + filter = GetEventFilter(dev, &ev); + if (type && inputMasks && + ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) || + ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) || + (inputMasks->xi2mask[dev->id][type/8] & filter))) + rc |= XI2_MASK; + + type = GetXIType(event); + ev.u.u.type = type; + filter = GetEventFilter(dev, &ev); + + /* Check for XI mask */ + if (type && inputMasks && + (inputMasks->deliverableEvents[dev->id] & filter) && + (inputMasks->inputEvents[dev->id] & filter)) + rc |= XI_MASK; + + /* Check for XI DontPropagate mask */ + if (type && inputMasks && + (inputMasks->dontPropagateMask[dev->id] & filter)) + rc |= DONT_PROPAGATE_MASK; + + /* Check for core mask */ + type = GetCoreType(event); + if (type && (win->deliverableEvents & filter) && + ((wOtherEventMasks(win) | win->eventMask) & filter)) + rc |= CORE_MASK; + + /* Check for core DontPropagate mask */ + if (type && (filter & wDontPropagateMask(win))) + rc |= DONT_PROPAGATE_MASK; + + return rc; +} + +/** + * Deliver events caused by input devices. + * * For events from a non-grabbed, non-focus device, DeliverDeviceEvents is * called directly from the processInputProc. * For grabbed devices, DeliverGrabbedEvent is called first, and _may_ call @@ -2296,112 +2447,108 @@ FixUpEventFromWindow( * DeliverDeviceEvents. * * @param pWin Window to deliver event to. - * @param xE Events to deliver. + * @param event The events to deliver, not yet in wire format. * @param grab Possible grab on a device. * @param stopAt Don't recurse up to the root window. * @param dev The device that is responsible for the event. - * @param count number of events in xE. * * @see DeliverGrabbedEvent * @see DeliverFocusedEvent */ int -DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab, - WindowPtr stopAt, DeviceIntPtr dev, int count) +DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, + WindowPtr stopAt, DeviceIntPtr dev) { Window child = None; - int type = xE->u.u.type; - Mask filter = filters[dev->id][type]; + Mask filter; int deliveries = 0; - OtherInputMasks *inputMasks; - int mskidx = dev->id; xEvent core; + xEvent *xE = NULL; + int rc, mask, count = 0; - if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count)) - return 0; + CHECKEVENT(event); - /* handle generic events */ - /* XXX: Generic events aren't quite handled correctly yet. They should - * eventually fit in with the rest of the stuff - */ - if (type == GenericEvent) + while (pWin) { - WindowPtr win = pWin; - xGenericEvent* ge = (xGenericEvent*)xE; - - if (count > 1) + if ((mask = EventIsDeliverable(dev, event, pWin))) { - ErrorF("[dix] Do not send more than one GenericEvent at a time!\n"); - return 0; - } - filter = generic_filters[GEEXTIDX(xE)][ge->evtype]; - - while(win) - { - if (GEDeviceMaskIsSet(win, dev, GEEXT(xE), filter)) + /* XI2 events first */ + if (mask & XI2_MASK) { - if (GEExtensions[GEEXTIDX(xE)].evfill) - GEExtensions[GEEXTIDX(xE)].evfill(ge, dev, win, grab); - deliveries = DeliverEventsToWindow(dev, win, xE, count, - filter, grab, 0); - if (deliveries > 0) - return deliveries; + xEvent *xi2 = NULL; + rc = EventToXI2(event, &xi2); + if (rc == Success) + { + /* XXX: XACE */ + filter = GetEventFilter(dev, xi2); + FixUpEventFromWindow(dev, xi2, pWin, child, FALSE); + deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1, + filter, grab); + xfree(xi2); + if (deliveries > 0) + goto unwind; + } else if (rc != BadMatch) + ErrorF("[dix] %s: XI2 conversion failed in DDE (%d).\n", + dev->name, rc); } - win = win->parent; - } - } - - while (pWin && type != GenericEvent) - { - if (!dev->isMaster) - { - inputMasks = wOtherInputMasks(pWin); - if (inputMasks && (filter & inputMasks->deliverableEvents[mskidx])) + /* XI events */ + if (mask & XI_MASK) { - - if (inputMasks && (inputMasks->inputEvents[mskidx] & filter)) + rc = EventToXI(event, &xE, &count); + if (rc == Success && + XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success) { + filter = GetEventFilter(dev, xE); FixUpEventFromWindow(dev, xE, pWin, child, FALSE); deliveries = DeliverEventsToWindow(dev, pWin, xE, count, - filter, grab, mskidx); + filter, grab); if (deliveries > 0) - return deliveries; - } + goto unwind; + } else if (rc != BadMatch) + ErrorF("[dix] %s: XI conversion failed in DDE (%d, %d). Skipping delivery.\n", + dev->name, event->any.type, rc); } - if ((deliveries < 0) || (pWin == stopAt) || - (inputMasks && (filter & inputMasks->dontPropagateMask[mskidx]))) - return 0; - } else - { - core = *xE; - core.u.u.type = XItoCoreType(xE->u.u.type); - - if (core.u.u.type && filter & pWin->deliverableEvents) + /* Core event */ + if ((mask & CORE_MASK) && IsMaster(dev) && dev->coreEvents) { - if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter) + rc = EventToCore(event, &core); + if (rc == Success && + XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success) { + filter = GetEventFilter(dev, &core); FixUpEventFromWindow(dev, &core, pWin, child, FALSE); deliveries = DeliverEventsToWindow(dev, pWin, &core, 1, - filter, grab, 0); + filter, grab); if (deliveries > 0) - return deliveries; - } + goto unwind; + } else if (rc != BadMatch) + ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n", + dev->name, event->any.type, rc); } if ((deliveries < 0) || (pWin == stopAt) || - (filter & wDontPropagateMask(pWin))) - return 0; + (mask & DONT_PROPAGATE_MASK)) + { + deliveries = 0; + goto unwind; + } } child = pWin->drawable.id; pWin = pWin->parent; } - return 0; +unwind: + xfree(xE); + return deliveries; } +#undef XI_MASK +#undef CORE_MASK +#undef DONT_PROPAGATE_MASK + /** * Deliver event to a window and it's immediate parent. Used for most window * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that @@ -2415,12 +2562,13 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab, * @param count number of events in xE. * @param otherParent Used for ReparentNotify events. */ -_X_EXPORT int +int DeliverEvents(WindowPtr pWin, xEvent *xE, int count, WindowPtr otherParent) { Mask filter; int deliveries; + DeviceIntRec dummy; #ifdef PANORAMIX if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) @@ -2429,27 +2577,26 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count, if (!count) return 0; - /* We don't know a device here. However, this should only ever be called - for a non-device event so we are safe to use 0*/ - filter = filters[0][xE->u.u.type]; + + dummy.id = XIAllDevices; + filter = GetEventFilter(&dummy, xE); if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify)) xE->u.destroyNotify.event = pWin->drawable.id; if (filter != StructureAndSubMask) - return DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, filter, NullGrab, 0); - deliveries = DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, StructureNotifyMask, - NullGrab, 0); + return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab); + deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count, + StructureNotifyMask, NullGrab); if (pWin->parent) { xE->u.destroyNotify.event = pWin->parent->drawable.id; - deliveries += DeliverEventsToWindow(inputInfo.pointer, pWin->parent, xE, count, - SubstructureNotifyMask, NullGrab, - 0); + deliveries += DeliverEventsToWindow(&dummy, pWin->parent, xE, count, + SubstructureNotifyMask, NullGrab); if (xE->u.u.type == ReparentNotify) { xE->u.destroyNotify.event = otherParent->drawable.id; - deliveries += DeliverEventsToWindow(inputInfo.pointer, + deliveries += DeliverEventsToWindow(&dummy, otherParent, xE, count, SubstructureNotifyMask, - NullGrab, 0); + NullGrab); } } return deliveries; @@ -2548,6 +2695,85 @@ XYToWindow(DeviceIntPtr pDev, int x, int y) } /** + * Ungrab a currently FocusIn grabbed device and grab the device on the + * given window. If the win given is the NoneWin, the device is ungrabbed if + * applicable and FALSE is returned. + * + * @returns TRUE if the device has been grabbed, or FALSE otherwise. + */ +BOOL +ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) +{ + BOOL rc = FALSE; + DeviceEvent event; + + if (dev->deviceGrab.grab && + dev->deviceGrab.fromPassiveGrab && + dev->deviceGrab.grab->type == XI_Enter) + { + if (dev->deviceGrab.grab->window == win || + IsParent(dev->deviceGrab.grab->window, win)) + return FALSE; + DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); + (*dev->deviceGrab.DeactivateGrab)(dev); + } + + if (win == NoneWin || win == PointerRootWin) + return FALSE; + + memset(&event, 0, sizeof(DeviceEvent)); + event.header = ET_Internal; + event.type = ET_FocusIn; + event.length = sizeof(DeviceEvent); + event.time = GetTimeInMillis(); + event.deviceid = dev->id; + event.sourceid = dev->id; + event.detail.button = 0; + rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); + if (rc) + DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); + return rc; +} + +/** + * Ungrab a currently Enter grabbed device and grab the device for the given + * window. + * + * @returns TRUE if the device has been grabbed, or FALSE otherwise. + */ +static BOOL +ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) +{ + BOOL rc = FALSE; + DeviceEvent event; + + if (dev->deviceGrab.grab && + dev->deviceGrab.fromPassiveGrab && + dev->deviceGrab.grab->type == XI_Enter) + { + if (dev->deviceGrab.grab->window == win || + IsParent(dev->deviceGrab.grab->window, win)) + return FALSE; + DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); + (*dev->deviceGrab.DeactivateGrab)(dev); + } + + memset(&event, 0, sizeof(DeviceEvent)); + event.header = ET_Internal; + event.type = ET_Enter; + event.length = sizeof(DeviceEvent); + event.time = GetTimeInMillis(); + event.deviceid = dev->id; + event.sourceid = dev->id; + event.detail.button = 0; + rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); + if (rc) + DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab); + + return rc; +} + +/** * Update the sprite coordinates based on the event. Update the cursor * position, then update the event with the new coordinates that may have been * changed. If the window underneath the sprite has changed, change to new @@ -2559,51 +2785,53 @@ XYToWindow(DeviceIntPtr pDev, int x, int y) * @return TRUE if the sprite has moved or FALSE otherwise. */ Bool -CheckMotion(xEvent *xE, DeviceIntPtr pDev) +CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) { - INT16 *rootX, *rootY; - WindowPtr prevSpriteWin; + WindowPtr prevSpriteWin, newSpriteWin; SpritePtr pSprite = pDev->spriteInfo->sprite; - prevSpriteWin = pSprite->win; + CHECKEVENT(ev); -#ifdef PANORAMIX - if(!noPanoramiXExtension) - return XineramaCheckMotion(xE, pDev); -#endif + prevSpriteWin = pSprite->win; - if (xE && !syncEvents.playingEvents) + if (ev && !syncEvents.playingEvents) { /* GetPointerEvents() guarantees that pointer events have the correct rootX/Y set already. */ - switch(xE->u.u.type) + switch (ev->type) { - case ButtonPress: - case ButtonRelease: - case MotionNotify: - rootX = &XE_KBPTR.rootX; - rootY = &XE_KBPTR.rootY; + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_Motion: break; default: - if (xE->u.u.type == DeviceButtonPress || - xE->u.u.type == DeviceButtonRelease || - xE->u.u.type == DeviceMotionNotify) - { - rootX = &((deviceKeyButtonPointer*)xE)->root_x; - rootY = &((deviceKeyButtonPointer*)xE)->root_y; - break; - } /* all other events return FALSE */ return FALSE; } - if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) + +#ifdef PANORAMIX + if (!noPanoramiXExtension) + { + /* Motion events entering DIX get translated to Screen 0 + coordinates. Replayed events have already been + translated since they've entered DIX before */ + ev->root_x += panoramiXdataPtr[pSprite->screen->myNum].x - + panoramiXdataPtr[0].x; + ev->root_y += panoramiXdataPtr[pSprite->screen->myNum].y - + panoramiXdataPtr[0].y; + } else +#endif { - pSprite->hot.pScreen = pSprite->hotPhys.pScreen; - RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; + if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) + { + pSprite->hot.pScreen = pSprite->hotPhys.pScreen; + RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; + } } - pSprite->hot.x = *rootX; - pSprite->hot.y = *rootY; + + pSprite->hot.x = ev->root_x; + pSprite->hot.y = ev->root_y; if (pSprite->hot.x < pSprite->physLimits.x1) pSprite->hot.x = pSprite->physLimits.x1; else if (pSprite->hot.x >= pSprite->physLimits.x2) @@ -2616,36 +2844,48 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev) ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); pSprite->hotPhys = pSprite->hot; - if ((pSprite->hotPhys.x != *rootX) || - (pSprite->hotPhys.y != *rootY)) + if ((pSprite->hotPhys.x != ev->root_x) || + (pSprite->hotPhys.y != ev->root_y)) { - (*pSprite->hotPhys.pScreen->SetCursorPosition)( - pDev, pSprite->hotPhys.pScreen, - pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); +#ifdef PANORAMIX + if (!noPanoramiXExtension) + { + XineramaSetCursorPosition( + pDev, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); + } else +#endif + { + (*pSprite->hotPhys.pScreen->SetCursorPosition)( + pDev, pSprite->hotPhys.pScreen, + pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); + } } - *rootX = pSprite->hot.x; - *rootY = pSprite->hot.y; + ev->root_x = pSprite->hot.x; + ev->root_y = pSprite->hot.y; } - pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y); -#ifdef notyet - if (!(pSprite->win->deliverableEvents & - Motion_Filter(pDev->button)) - !syncEvents.playingEvents) - { - /* XXX Do PointerNonInterestBox here */ - } -#endif - if (pSprite->win != prevSpriteWin) + newSpriteWin = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y); + + if (newSpriteWin != prevSpriteWin) { + int sourceid; + if (!ev) { + UpdateCurrentTimeIf(); + sourceid = pDev->id; /* when from WindowsRestructured */ + } else + sourceid = ev->sourceid; + if (prevSpriteWin != NullWindow) { - if (!xE) - UpdateCurrentTimeIf(); - DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win, - NotifyNormal); + if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin)) + DoEnterLeaveEvents(pDev, sourceid, prevSpriteWin, + newSpriteWin, NotifyNormal); } - PostNewCursor(pDev); + /* set pSprite->win after ActivateEnterGrab, otherwise + sprite window == grab_window and no enter/leave events are + sent. */ + pSprite->win = newSpriteWin; + PostNewCursor(pDev); return FALSE; } return TRUE; @@ -2661,7 +2901,7 @@ WindowsRestructured(void) DeviceIntPtr pDev = inputInfo.devices; while(pDev) { - if (pDev->isMaster || !pDev->u.master) + if (IsMaster(pDev) || !pDev->u.master) CheckMotion(NULL, pDev); pDev = pDev->next; } @@ -2722,17 +2962,6 @@ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) #endif /** - * Called from main() with the root window on the first screen. Used to do a - * lot more when MPX wasn't around yet. Things change. - * - * Should delete this now? -ds - */ -void -DefineInitialRootWindow(WindowPtr win) -{ -} - -/** * Initialize a sprite for the given device and set it to some sane values. If * the device already has a sprite alloc'd, don't realloc but just reset to * default values. @@ -2925,7 +3154,7 @@ WindowHasNewCursor(WindowPtr pWin) PostNewCursor(pDev); } -_X_EXPORT void +void NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y) { SpritePtr pSprite = pDev->spriteInfo->sprite; @@ -3090,22 +3319,22 @@ ProcWarpPointer(ClientPtr client) WindowPtr dest = NULL; int x, y, rc; ScreenPtr newScreen; - DeviceIntPtr dev; + DeviceIntPtr dev, tmp; SpritePtr pSprite; REQUEST(xWarpPointerReq); REQUEST_SIZE_MATCH(xWarpPointerReq); - /* XXX XACE ??*/ - for (dev = inputInfo.devices; dev; dev = dev->next) { - if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) { + dev = PickPointer(client); + + for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { + if ((tmp == dev) || (!IsMaster(tmp) && tmp->u.master == dev)) { rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess); if (rc != Success) return rc; } } - dev = PickPointer(client); if (dev->u.lastSlave) dev = dev->u.lastSlave; pSprite = dev->spriteInfo->sprite; @@ -3213,113 +3442,130 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin) * * @param pWin The window that may be subject to a passive grab. * @param device Device that caused the event. - * @param xE List of events (multiple ones for DeviceMotionNotify) - * @param count number of elements in xE. - * @param store The event that will be stored on the device (always XI) - * @param scount number of elements in store. + * @param event The current device event. + * @param checkCore Check for core grabs too. */ static Bool CheckPassiveGrabsOnWindow( WindowPtr pWin, DeviceIntPtr device, - xEvent *xE, - int count, - xEvent *store, - int scount) + DeviceEvent *event, + BOOL checkCore) { GrabPtr grab = wPassiveGrabs(pWin); GrabRec tempGrab; GrabInfoPtr grabinfo; - xEvent *dxE; +#define CORE_MATCH 0x1 +#define XI_MATCH 0x2 +#define XI2_MATCH 0x4 + int match = 0; + + if (device->deviceGrab.grab) + return FALSE; if (!grab) return FALSE; + /* Fill out the grab details, but leave the type for later before + * comparing */ tempGrab.window = pWin; tempGrab.device = device; - tempGrab.type = xE->u.u.type; - tempGrab.detail.exact = xE->u.u.detail; + tempGrab.detail.exact = event->detail.key; tempGrab.detail.pMask = NULL; tempGrab.modifiersDetail.pMask = NULL; tempGrab.next = NULL; for (; grab; grab = grab->next) { -#ifdef XKB DeviceIntPtr gdev; XkbSrvInfoPtr xkbi = NULL; + Mask mask = 0; gdev= grab->modifierDevice; - if (grab->coreGrab) + if (grab->grabtype == GRABTYPE_CORE) { if (IsPointerDevice(device)) gdev = GetPairedDevice(device); else gdev = device; + } else if (grab->grabtype == GRABTYPE_XI2) + { + /* if the device is an attached slave device, gdev must be the + * attached master keyboard. Since the slave may have been + * reattached after the grab, the modifier device may not be the + * same. */ + if (!IsMaster(grab->device) && device->u.master) + gdev = GetMaster(device, MASTER_KEYBOARD); } + + if (gdev && gdev->key) xkbi= gdev->key->xkbInfo; -#endif tempGrab.modifierDevice = grab->modifierDevice; - if ((device == grab->modifierDevice) && - ((xE->u.u.type == KeyPress) || (xE->u.u.type == DeviceKeyPress))) - tempGrab.modifiersDetail.exact = -#ifdef XKB - (noXkbExtension) ? - ((gdev) ? gdev->key->prev_state : 0) : - ((xkbi) ? xkbi->state.grab_mods : 0); -#else - (gdev) ? gdev->key->prev_state : 0; -#endif - else - tempGrab.modifiersDetail.exact = -#ifdef XKB - (noXkbExtension) ? - ((gdev) ? gdev->key->state : 0) : - ((xkbi) ? xkbi->state.grab_mods : 0); -#else - (gdev) ? gdev->key->state : 0; -#endif - /* ignore the device for core events when comparing grabs */ - if (GrabMatchesSecond(&tempGrab, grab, (xE->u.u.type < LASTEvent)) && - (!grab->confineTo || + tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0; + + /* Check for XI2 and XI grabs first */ + tempGrab.type = GetXI2Type((InternalEvent*)event); + tempGrab.grabtype = GRABTYPE_XI2; + if (GrabMatchesSecond(&tempGrab, grab, FALSE)) + match = XI2_MATCH; + + tempGrab.detail.exact = event->detail.key; + if (!match) + { + tempGrab.type = GetXIType((InternalEvent*)event); + tempGrab.grabtype = GRABTYPE_XI; + if (GrabMatchesSecond(&tempGrab, grab, FALSE)) + match = XI_MATCH; + } + + /* Check for a core grab (ignore the device when comparing) */ + if (!match && checkCore) + { + tempGrab.grabtype = GRABTYPE_CORE; + if ((tempGrab.type = GetCoreType((InternalEvent*)event)) && + (GrabMatchesSecond(&tempGrab, grab, TRUE))) + match = CORE_MATCH; + } + + if (match && (!grab->confineTo || (grab->confineTo->realized && BorderSizeNotEmpty(device, grab->confineTo)))) { -#ifdef XKB - if (!noXkbExtension) { - XE_KBPTR.state &= 0x1f00; - XE_KBPTR.state |= - tempGrab.modifiersDetail.exact&(~0x1f00); - } -#endif - grabinfo = &device->deviceGrab; - /* A passive grab may have been created for a different device - than it is assigned to at this point in time. - Update the grab's device and modifier device to reflect the - current state. - Since XGrabDeviceButton requires to specify the - modifierDevice explicitly, we don't override this choice. - */ - if (xE->u.u.type < LASTEvent) - { - grab->device = device; - grab->modifierDevice = GetPairedDevice(device); - } + int rc, count = 0; + xEvent *xE = NULL; + xEvent core; + event->corestate &= 0x1f00; + event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00); + grabinfo = &device->deviceGrab; /* In some cases a passive core grab may exist, but the client * already has a core grab on some other device. In this case we * must not get the grab, otherwise we may never ungrab the * device. */ - if (grab->coreGrab) + if (grab->grabtype == GRABTYPE_CORE) { DeviceIntPtr other; BOOL interfering = FALSE; + + /* A passive grab may have been created for a different device + than it is assigned to at this point in time. + Update the grab's device and modifier device to reflect the + current state. + Since XGrabDeviceButton requires to specify the + modifierDevice explicitly, we don't override this choice. + */ + if (tempGrab.type < GenericEvent) + { + grab->device = device; + grab->modifierDevice = GetPairedDevice(device); + } + for (other = inputInfo.devices; other; other = other->next) { GrabPtr othergrab = other->deviceGrab.grab; - if (othergrab && othergrab->coreGrab && + if (othergrab && othergrab->grabtype == GRABTYPE_CORE && SameClient(grab, rClient(othergrab)) && ((IsPointerDevice(grab->device) && IsPointerDevice(othergrab->device)) || @@ -3335,31 +3581,80 @@ CheckPassiveGrabsOnWindow( } + if (match & CORE_MATCH) + { + rc = EventToCore((InternalEvent*)event, &core); + if (rc != Success) + { + if (rc != BadMatch) + ErrorF("[dix] %s: core conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->type, rc); + continue; + } + xE = &core; + count = 1; + mask = grab->eventMask; + } else if (match & XI2_MATCH) + { + rc = EventToXI2((InternalEvent*)event, &xE); + if (rc != Success) + { + if (rc != BadMatch) + ErrorF("[dix] %s: XI2 conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->type, rc); + continue; + } + count = 1; + + /* FIXME: EventToXI2 returns NULL for enter events, so + * dereferencing the event is bad. Internal event types are + * aligned with core events, so the else clause is valid. + * long-term we should use internal events for enter/focus + * as well */ + if (xE) + mask = grab->xi2mask[device->id][((xGenericEvent*)xE)->evtype/8]; + else if (event->type == XI_Enter || event->type == XI_FocusIn) + mask = grab->xi2mask[device->id][event->type/8]; + } else + { + rc = EventToXI((InternalEvent*)event, &xE, &count); + if (rc != Success) + { + if (rc != BadMatch) + ErrorF("[dix] %s: XI conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->type, rc); + continue; + } + mask = grab->eventMask; + } + (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); - FixUpEventFromWindow(device, xE, grab->window, None, TRUE); + if (xE) + { + FixUpEventFromWindow(device, xE, grab->window, None, TRUE); - (void) TryClientEvents(rClient(grab), device, xE, count, - filters[device->id][xE->u.u.type], - filters[device->id][xE->u.u.type], grab); + TryClientEvents(rClient(grab), device, xE, count, mask, + GetEventFilter(device, xE), grab); + } if (grabinfo->sync.state == FROZEN_NO_EVENT) { - if (grabinfo->sync.evcount < scount) - { - grabinfo->sync.event = xrealloc(grabinfo->sync.event, - scount * sizeof(xEvent)); - } - grabinfo->sync.evcount = scount; - /* we always store the XI event, never the core event */ - for (dxE = grabinfo->sync.event; --scount >= 0; dxE++, store++) - *dxE = *store; + if (!grabinfo->sync.event) + grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent)); + *grabinfo->sync.event = *event; grabinfo->sync.state = FROZEN_WITH_EVENT; } + + if (match & (XI_MATCH | XI2_MATCH)) + xfree(xE); /* on core match xE == &core */ return TRUE; } } return FALSE; +#undef CORE_MATCH +#undef XI_MATCH +#undef XI2_MATCH } /** @@ -3389,33 +3684,20 @@ CheckPassiveGrabsOnWindow( */ Bool -CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE, - int checkFirst, int count) +CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst) { int i; WindowPtr pWin = NULL; - FocusClassPtr focus = IsPointerEvent(xE) ? NULL : device->focus; - xEvent core; - BOOL sendCore = (device->isMaster && device->coreEvents); - - if ((xE->u.u.type == DeviceButtonPress) - && (device->button->buttonsDown != 1)) - return FALSE; + FocusClassPtr focus = IsPointerEvent((InternalEvent*)event) ? NULL : device->focus; + BOOL sendCore = (IsMaster(device) && device->coreEvents); - if (xE->u.u.type < EXTENSION_EVENT_BASE) - { - ErrorF("[dix] Core event passed into CheckDeviceGrabs.\n"); + if (event->type != ET_ButtonPress && + event->type != ET_KeyPress) return FALSE; - } - - if (sendCore) - { - core = *xE; - core.u.u.type = XItoCoreType(xE->u.u.type); - if(!core.u.u.type) /* probably a Proximity event, can't grab for those */ - return FALSE; - } + if (event->type == ET_ButtonPress + && (device->button->buttonsDown != 1)) + return FALSE; i = checkFirst; @@ -3424,11 +3706,8 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE, for (; i < focus->traceGood; i++) { pWin = focus->trace[i]; - /* XI grabs have precendence */ if (pWin->optional && - (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) - || (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core, - 1, xE, count)))) + CheckPassiveGrabsOnWindow(pWin, device, event, sendCore)) return TRUE; } @@ -3443,9 +3722,7 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE, { pWin = device->spriteInfo->sprite->spriteTrace[i]; if (pWin->optional && - (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) || - (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core, 1, - xE, count)))) + CheckPassiveGrabsOnWindow(pWin, device, event, sendCore)) return TRUE; } @@ -3454,21 +3731,24 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE, /** * Called for keyboard events to deliver event to whatever client owns the - * focus. Event is delivered to the keyboard's focus window, the root window - * or to the window owning the input focus. + * focus. + * + * The event is delivered to the keyboard's focus window, the root window or + * to the window owning the input focus. * * @param keybd The keyboard originating the event. - * @param xE The event list. + * @param event The event, not yet in wire format. * @param window Window underneath the sprite. - * @param count number of events in xE. */ void -DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count) +DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) { - DeviceIntPtr pointer; + DeviceIntPtr ptr; WindowPtr focus = keybd->focus->win; - BOOL sendCore = (keybd->isMaster && keybd->coreEvents); + BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents); xEvent core; + xEvent *xE = NULL, *xi2 = NULL; + int count, rc; int deliveries = 0; if (focus == FollowKeyboardWin) @@ -3477,40 +3757,69 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count) return; if (focus == PointerRootWin) { - DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count); + DeliverDeviceEvents(window, event, NullGrab, NullWindow, keybd); return; } if ((focus == window) || IsParent(focus, window)) { - if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count)) + if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd)) return; } - pointer = GetPairedDevice(keybd); - if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count)) - return; - - if (sendCore) - { - core = *xE; - core.u.u.type = XItoCoreType(xE->u.u.type); - } /* just deliver it to the focus window */ - FixUpEventFromWindow(pointer, xE, focus, None, FALSE); - deliveries = DeliverEventsToWindow(keybd, focus, xE, count, - filters[keybd->id][xE->u.u.type], - NullGrab, keybd->id); - - if (deliveries > 0) - return; + ptr = GetPairedDevice(keybd); + + + rc = EventToXI2(event, &xi2); + if (rc == Success) + { + /* XXX: XACE */ + int filter = GetEventFilter(keybd, xi2); + FixUpEventFromWindow(ptr, xi2, focus, None, FALSE); + deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1, + filter, NullGrab); + if (deliveries > 0) + goto unwind; + } else if (rc != BadMatch) + ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n", + keybd->name, event->any.type, rc); + + rc = EventToXI(event, &xE, &count); + if (rc == Success && + XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count) == Success) + { + FixUpEventFromWindow(ptr, xE, focus, None, FALSE); + deliveries = DeliverEventsToWindow(keybd, focus, xE, count, + GetEventFilter(keybd, xE), + NullGrab); + + if (deliveries > 0) + goto unwind; + } else if (rc != BadMatch) + ErrorF("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n", + keybd->name, event->any.type, rc); - if (sendCore && core.u.u.type) + if (sendCore) { - FixUpEventFromWindow(keybd, &core, focus, None, FALSE); - deliveries = DeliverEventsToWindow(keybd, focus, &core, 1, - filters[keybd->id][xE->u.u.type], - NullGrab, 0); - } + rc = EventToCore(event, &core); + if (rc == Success && + XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success) + { + FixUpEventFromWindow(keybd, &core, focus, None, FALSE); + deliveries = DeliverEventsToWindow(keybd, focus, &core, 1, + GetEventFilter(keybd, &core), + NullGrab); + } else if (rc != BadMatch) + ErrorF("[dix] %s: core conversion failed DFE (%d, %d). Skipping delivery.\n", + keybd->name, event->any.type, rc); + } + +unwind: + if (xE) + xfree(xE); + if (xi2) + xfree(xi2); + return; } /** @@ -3521,16 +3830,18 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count) * @param deactivateGrab True if the device's grab should be deactivated. */ void -DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, - Bool deactivateGrab, int count) +DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, + Bool deactivateGrab) { GrabPtr grab; GrabInfoPtr grabinfo; int deliveries = 0; DeviceIntPtr dev; - xEvent *dxE, core; SpritePtr pSprite = thisDev->spriteInfo->sprite; BOOL sendCore = FALSE; + int rc, count = 0; + xEvent *xi = NULL; + xEvent *xi2 = NULL; grabinfo = &thisDev->deviceGrab; grab = grabinfo->grab; @@ -3543,14 +3854,9 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, * for the type of event, to see if we really want to deliver it to * the focus window. For pointer events, the answer is no. */ - if (xE->u.u.type == DeviceButtonPress || - xE->u.u.type == DeviceButtonRelease || - xE->u.u.type == DeviceMotionNotify || - xE->u.u.type == ProximityIn || - xE->u.u.type == ProximityOut) - { + if (IsPointerEvent(event)) focus = PointerRootWin; - } else if (thisDev->focus) + else if (thisDev->focus) { focus = thisDev->focus->win; if (focus == FollowKeyboardWin) @@ -3559,75 +3865,112 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, else focus = PointerRootWin; if (focus == PointerRootWin) - deliveries = DeliverDeviceEvents(pSprite->win, xE, grab, - NullWindow, thisDev, count); + deliveries = DeliverDeviceEvents(pSprite->win, event, grab, + NullWindow, thisDev); else if (focus && (focus == pSprite->win || IsParent(focus, pSprite->win))) - deliveries = DeliverDeviceEvents(pSprite->win, xE, grab, focus, - thisDev, count); + deliveries = DeliverDeviceEvents(pSprite->win, event, grab, focus, + thisDev); else if (focus) - deliveries = DeliverDeviceEvents(focus, xE, grab, focus, - thisDev, count); + deliveries = DeliverDeviceEvents(focus, event, grab, focus, + thisDev); } if (!deliveries) { + Mask mask; + + /* XXX: In theory, we could pass the internal events through to + * everything and only convert just before hitting the wire. We can't + * do that yet, so DGE is the last stop for internal events. From here + * onwards, we deal with core/XI events. + */ + + mask = grab->eventMask; + + sendCore = (IsMaster(thisDev) && thisDev->coreEvents); + /* try core event */ + if (sendCore && grab->grabtype == GRABTYPE_CORE) { - Mask mask = grab->eventMask; + xEvent core; - if (thisDev->isMaster) + rc = EventToCore(event, &core); + if (rc == Success) { - core = *xE; - core.u.u.type = XItoCoreType(xE->u.u.type); - if(core.u.u.type) { - FixUpEventFromWindow(thisDev, &core, grab->window, - None, TRUE); - if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, - grab->window, &core, 1) || - XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), - grab->window, &core, 1)) - deliveries = 1; /* don't send, but pretend we did */ - else if (!IsInterferingGrab(rClient(grab), thisDev, - &core)) - { - deliveries = TryClientEvents(rClient(grab), thisDev, - &core, 1, mask, - filters[thisDev->id][core.u.u.type], - grab); - } + FixUpEventFromWindow(thisDev, &core, grab->window, + None, TRUE); + if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, + grab->window, &core, 1) || + XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), + grab->window, &core, 1)) + deliveries = 1; /* don't send, but pretend we did */ + else if (!IsInterferingGrab(rClient(grab), thisDev, &core)) + { + deliveries = TryClientEvents(rClient(grab), thisDev, + &core, 1, mask, + GetEventFilter(thisDev, &core), + grab); } - } else + } else if (rc != BadMatch) + ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n"); + } + + if (!deliveries) + { + rc = EventToXI2(event, &xi2); + if (rc == Success) + { + int evtype = ((xGenericEvent*)xi2)->evtype; + mask = grab->xi2mask[XIAllDevices][evtype/8] | + grab->xi2mask[XIAllMasterDevices][evtype/8] | + grab->xi2mask[thisDev->id][evtype/8]; + /* try XI2 event */ + FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE); + /* XXX: XACE */ + deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask, + GetEventFilter(thisDev, xi2), grab); + } else if (rc != BadMatch) + ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n", + thisDev->name, event->any.type, rc); + } + + if (!deliveries) + { + rc = EventToXI(event, &xi, &count); + if (rc == Success) { /* try XI event */ if (grabinfo->fromPassiveGrab && - grabinfo->implicitGrab && - (xE->u.u.type & EXTENSION_EVENT_BASE)) + grabinfo->implicitGrab) mask = grab->deviceMask; - FixUpEventFromWindow(thisDev, xE, grab->window, + else + mask = grab->eventMask; + + FixUpEventFromWindow(thisDev, xi, grab->window, None, TRUE); if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, - grab->window, xE, count) || + grab->window, xi, count) || XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), - grab->window, xE, count)) + grab->window, xi, count)) deliveries = 1; /* don't send, but pretend we did */ else { deliveries = TryClientEvents(rClient(grab), thisDev, - xE, count, + xi, count, mask, - filters[thisDev->id][xE->u.u.type], + GetEventFilter(thisDev, xi), grab); } - - } + } else if (rc != BadMatch) + ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n", + thisDev->name, event->any.type, rc); } - if (deliveries && (xE->u.u.type == MotionNotify - || xE->u.u.type == DeviceMotionNotify)) + + if (deliveries && (event->any.type == ET_Motion)) thisDev->valuator->motionHintWindow = grab->window; } - if (deliveries && !deactivateGrab && - (xE->u.u.type != MotionNotify && xE->u.u.type != DeviceMotionNotify)) + if (deliveries && !deactivateGrab && event->any.type != ET_Motion) { switch (grabinfo->sync.state) { @@ -3637,250 +3980,57 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, if (dev == thisDev) continue; FreezeThaw(dev, TRUE); - if ((grabinfo->sync.state == FREEZE_BOTH_NEXT_EVENT) && + if ((dev->deviceGrab.sync.state == FREEZE_BOTH_NEXT_EVENT) && (CLIENT_BITS(grab->resource) == - CLIENT_BITS(grab->resource))) - grabinfo->sync.state = FROZEN_NO_EVENT; + CLIENT_BITS(dev->deviceGrab.sync.other->resource))) + dev->deviceGrab.sync.state = FROZEN_NO_EVENT; else - grabinfo->sync.other = grab; + dev->deviceGrab.sync.other = grab; } /* fall through */ case FREEZE_NEXT_EVENT: grabinfo->sync.state = FROZEN_WITH_EVENT; FreezeThaw(thisDev, TRUE); - if (grabinfo->sync.evcount < count) - { - grabinfo->sync.event = xrealloc(grabinfo->sync.event, - count * sizeof(xEvent)); - } - grabinfo->sync.evcount = count; - for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++) - *dxE = *xE; + if (!grabinfo->sync.event) + grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent)); + *grabinfo->sync.event = *(DeviceEvent*)event; break; } } -} -/** - * Main keyboard event processing function for core keyboard events. - * Updates the events fields from the current pointer state and delivers the - * event. - * - * For key events, xE will always be a single event. - * - * @param xE Event list - * @param keybd The device that caused an event. - * @param count Number of elements in xE. - */ -void -#ifdef XKB -CoreProcessKeyboardEvent (xEvent *xE, DeviceIntPtr keybd, int count) -#else -ProcessKeyboardEvent (xEvent *xE, DeviceIntPtr keybd, int count) -#endif -{ - int key, bit; - BYTE *kptr; - CARD8 modifiers; - GrabPtr grab; - GrabInfoPtr grabinfo; - Bool deactivateGrab = FALSE; - KeyClassPtr keyc = keybd->key; - - grabinfo = &keybd->deviceGrab; - grab = grabinfo->grab; - - if (!syncEvents.playingEvents) - { - NoticeTime(xE); - if (DeviceEventCallback) - { - DeviceEventInfoRec eventinfo; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); - } - } - /* ProcessOtherEvent already updated the keyboard's state, so we need to - * access prev_state here! */ - XE_KBPTR.state = (keyc->prev_state | GetPairedDevice(keybd)->button->state); - XE_KBPTR.rootX = keybd->spriteInfo->sprite->hot.x; - XE_KBPTR.rootY = keybd->spriteInfo->sprite->hot.y; - key = xE->u.u.detail; - kptr = &keyc->down[key >> 3]; - bit = 1 << (key & 7); - modifiers = keyc->modifierMap[key]; - - switch (xE->u.u.type) - { - case KeyPress: - /* We MUST NOT change the device itself here. All device state - * changes must be performed in ProcessOtherEvents. We're dealing - * with the same device struct, so if we change it in POE and - * here, we've just screwed up the state by setting it twice. - * - * Devices may not send core events but always send XI events, so - * the state must be changed in POE, not here. - */ - if (!grab && CheckDeviceGrabs(keybd, xE, 0, count)) - { - grabinfo->activatingKey = key; - return; - } - break; - case KeyRelease: - if (!(*kptr & bit)) /* guard against duplicates */ - return; - /* No device state changes, see comment for KeyPress */ - if (grabinfo->fromPassiveGrab && (key == grabinfo->activatingKey)) - deactivateGrab = TRUE; - break; - default: - FatalError("Impossible keyboard event"); - } - if (grab) - DeliverGrabbedEvent(xE, keybd, deactivateGrab, count); - else - DeliverFocusedEvent(keybd, xE, keybd->spriteInfo->sprite->win, count); - if (deactivateGrab) - (*grabinfo->DeactivateGrab)(keybd); - - XaceHook(XACE_KEY_AVAIL, xE, keybd, count); + if (xi) + xfree(xi); + if (xi2) + xfree(xi2); } -#ifdef XKB /* This function is used to set the key pressed or key released state - this is only used when the pressing of keys does not cause the device's processInputProc to be called, as in for example Mouse Keys. */ void -FixKeyState (xEvent *xE, DeviceIntPtr keybd) +FixKeyState (DeviceEvent *event, DeviceIntPtr keybd) { int key, bit; BYTE *kptr; KeyClassPtr keyc = keybd->key; - key = xE->u.u.detail; + key = event->detail.key; kptr = &keyc->down[key >> 3]; bit = 1 << (key & 7); - if (((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease)|| - (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)) - ) { + if (event->type == ET_KeyPress) { DebugF("FixKeyState: Key %d %s\n",key, - (((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress))?"down":"up")); + ((event->type == ET_KeyPress) ? "down" : "up")); } - if (xE->u.u.type == KeyPress || xE->u.u.type == DeviceKeyPress) + if (event->type == ET_KeyPress) *kptr |= bit; - else if (xE->u.u.type == KeyRelease || xE->u.u.type == DeviceKeyRelease) + else if (event->type == ET_KeyRelease) *kptr &= ~bit; else FatalError("Impossible keyboard event"); } -#endif - -/** - * Main pointer event processing function for core pointer events. - * For motion events: update the sprite. - * For all other events: Update the event fields based on the current sprite - * state. - * - * For core pointer events, xE will always be a single event. - * - * @param xE Event list - * @param mouse The device that caused an event. - * @param count Number of elements in xE. - */ -void -#ifdef XKB -CoreProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) -#else -ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) -#endif -{ - GrabPtr grab = mouse->deviceGrab.grab; - Bool deactivateGrab = FALSE; - ButtonClassPtr butc = mouse->button; - SpritePtr pSprite = mouse->spriteInfo->sprite; - -#ifdef XKB - XkbSrvInfoPtr xkbi= GetPairedDevice(mouse)->key->xkbInfo; -#endif - - if (!syncEvents.playingEvents) - NoticeTime(xE) - XE_KBPTR.state = (butc->state | ( -#ifdef XKB - (noXkbExtension ? - inputInfo.keyboard->key->state : - xkbi->state.grab_mods) -#else - inputInfo.keyboard->key->state -#endif - )); - { - NoticeTime(xE); - if (DeviceEventCallback) - { - DeviceEventInfoRec eventinfo; - /* see comment in EnqueueEvents regarding the next three lines */ - if (xE->u.u.type == MotionNotify) - XE_KBPTR.root = - WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); - } - } - /* We need to call CheckMotion for each event. It doesn't really give us - any benefit for relative devices, but absolute devices may not send - button events to the right position otherwise. */ - if (!CheckMotion(xE, mouse) && xE->u.u.type == MotionNotify) - return; - if (xE->u.u.type != MotionNotify) - { - int key; - - XE_KBPTR.rootX = pSprite->hot.x; - XE_KBPTR.rootY = pSprite->hot.y; - - key = xE->u.u.detail; - switch (xE->u.u.type) - { - case ButtonPress: - /* - * We rely on the fact that ButtonMotionMask is the same as - * DeviceButtonMotionMask, so setting the motionMask - * to this value ensures correctness for both XI and core events. - */ - if (xE->u.u.detail == 0) - return; - filters[mouse->id][Motion_Filter(butc)] = MotionNotify; - if (!grab) - if (CheckDeviceGrabs(mouse, xE, 0, count)) - return; - break; - case ButtonRelease: - if (xE->u.u.detail == 0) - return; - filters[mouse->id][Motion_Filter(butc)] = MotionNotify; - if (!butc->buttonsDown && mouse->deviceGrab.fromPassiveGrab) - deactivateGrab = TRUE; - break; - default: - FatalError("bogus pointer event from ddx. Type %d\n", xE->u.u.type); - } - } - - if (grab) - DeliverGrabbedEvent(xE, mouse, deactivateGrab, count); - else - DeliverDeviceEvents(pSprite->win, xE, NullGrab, NullWindow, - mouse, count); - if (deactivateGrab) - (*mouse->deviceGrab.DeactivateGrab)(mouse); -} #define AtMostOneClient \ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask) @@ -3895,13 +4045,12 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) * The otherEventMasks on a WindowOptional is the combination of all event * masks set by all clients on the window. * deliverableEventMask is the combination of the eventMask and the - * otherEventMask. + * otherEventMask plus the events that may be propagated to the parent. * * Traverses to siblings and parents of the window. */ void -RecalculateDeliverableEvents(pWin) - WindowPtr pWin; +RecalculateDeliverableEvents(WindowPtr pWin) { OtherClients *others; WindowPtr pChild; @@ -4030,7 +4179,7 @@ EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask) check = 0; if (!pWin->optional && !MakeWindowOptional (pWin)) return BadAlloc; - others = (OtherClients *) xalloc(sizeof(OtherClients)); + others = xalloc(sizeof(OtherClients)); if (!others) return BadAlloc; others->mask = mask; @@ -4144,6 +4293,7 @@ CoreEnterLeaveEvent( mask = pWin->eventMask | wOtherEventMasks(pWin); } + memset(&event, 0, sizeof(xEvent)); event.u.u.type = type; event.u.u.detail = detail; event.u.enterLeave.time = currentTime.milliseconds; @@ -4155,18 +4305,10 @@ CoreEnterLeaveEvent( event.u.enterLeave.child = child; event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ? ELFlagSameScreen : 0; -#ifdef XKB - if (!noXkbExtension) { - event.u.enterLeave.state = mouse->button->state & 0x1f00; - if (keybd) - event.u.enterLeave.state |= + event.u.enterLeave.state = mouse->button ? (mouse->button->state & 0x1f00) : 0; + if (keybd) + event.u.enterLeave.state |= XkbGrabStateFromRec(&keybd->key->xkbInfo->state); - } else -#endif - { - event.u.enterLeave.state = (keybd) ? keybd->key->state : 0; - event.u.enterLeave.state |= mouse->button->state; - } event.u.enterLeave.mode = mode; focus = (keybd) ? keybd->focus->win : None; if ((focus != NoneWin) && @@ -4174,21 +4316,21 @@ CoreEnterLeaveEvent( IsParent(focus, pWin))) event.u.enterLeave.flags |= ELFlagFocus; - if ((mask & filters[mouse->id][type])) + if ((mask & GetEventFilter(mouse, &event))) { if (grab) TryClientEvents(rClient(grab), mouse, &event, 1, mask, - filters[mouse->id][type], grab); + GetEventFilter(mouse, &event), grab); else DeliverEventsToWindow(mouse, pWin, &event, 1, - filters[mouse->id][type], NullGrab, 0); + GetEventFilter(mouse, &event), + NullGrab); } if ((type == EnterNotify) && (mask & KeymapStateMask)) { xKeymapEvent ke; - ClientPtr client = grab ? rClient(grab) - : clients[CLIENT_ID(pWin->drawable.id)]; + ClientPtr client = grab ? rClient(grab) : wClient(pWin); if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess)) bzero((char *)&ke.map[0], 31); else @@ -4200,8 +4342,83 @@ CoreEnterLeaveEvent( mask, KeymapStateMask, grab); else DeliverEventsToWindow(mouse, pWin, (xEvent *)&ke, 1, - KeymapStateMask, NullGrab, 0); + KeymapStateMask, NullGrab); + } +} + +void +DeviceEnterLeaveEvent( + DeviceIntPtr mouse, + int sourceid, + int type, + int mode, + int detail, + WindowPtr pWin, + Window child) +{ + GrabPtr grab = mouse->deviceGrab.grab; + xXIEnterEvent *event; + int filter; + int btlen, len, i; + DeviceIntPtr kbd; + + if ((mode == XINotifyPassiveGrab && type == XI_Leave) || + (mode == XINotifyPassiveUngrab && type == XI_Enter)) + return; + + btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; + btlen = bytes_to_int32(btlen); + len = sizeof(xXIEnterEvent) + btlen * 4; + + event = xcalloc(1, len); + event->type = GenericEvent; + event->extension = IReqCode; + event->evtype = type; + event->length = (len - sizeof(xEvent))/4; + event->buttons_len = btlen; + event->detail = detail; + event->time = currentTime.milliseconds; + event->deviceid = mouse->id; + event->sourceid = sourceid; + event->mode = mode; + event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); + event->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(&event[1], i); + + kbd = (IsMaster(mouse) || mouse->u.master) ? GetPairedDevice(mouse) : NULL; + if (kbd && kbd->key) + { + event->mods.base_mods = kbd->key->xkbInfo->state.base_mods; + event->mods.latched_mods = kbd->key->xkbInfo->state.latched_mods; + event->mods.locked_mods = kbd->key->xkbInfo->state.locked_mods; + + event->group.base_group = kbd->key->xkbInfo->state.base_group; + event->group.latched_group = kbd->key->xkbInfo->state.latched_group; + event->group.locked_group = kbd->key->xkbInfo->state.locked_group; } + + FixUpEventFromWindow(mouse, (xEvent*)event, pWin, None, FALSE); + + filter = GetEventFilter(mouse, (xEvent*)event); + + if (grab) + { + Mask mask; + mask = grab->xi2mask[XIAllDevices][type/8] | + grab->xi2mask[XIAllMasterDevices][type/8] | + grab->xi2mask[mouse->id][type/8]; + TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask, + filter, grab); + } else { + if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event)) + return; + DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter, + NullGrab); + } + xfree(event); } void @@ -4209,25 +4426,27 @@ CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) { xEvent event; + memset(&event, 0, sizeof(xEvent)); event.u.focus.mode = mode; event.u.u.type = type; event.u.u.detail = detail; event.u.focus.window = pWin->drawable.id; - (void)DeliverEventsToWindow(dev, pWin, &event, 1, - filters[dev->id][type], NullGrab, 0); + + DeliverEventsToWindow(dev, pWin, &event, 1, + GetEventFilter(dev, &event), NullGrab); if ((type == FocusIn) && ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask)) { xKeymapEvent ke; - ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)]; + ClientPtr client = wClient(pWin); if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess)) bzero((char *)&ke.map[0], 31); else memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31); ke.type = KeymapNotify; - (void)DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1, - KeymapStateMask, NullGrab, 0); + DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1, + KeymapStateMask, NullGrab); } } @@ -4305,9 +4524,14 @@ SetInputFocus( return Success; mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal; if (focus->win == FollowKeyboardWin) - DoFocusEvents(dev, keybd->focus->win, focusWin, mode); - else - DoFocusEvents(dev, focus->win, focusWin, mode); + { + if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin)) + DoFocusEvents(dev, keybd->focus->win, focusWin, mode); + } else + { + if (!ActivateFocusInGrab(dev, focus->win, focusWin)) + DoFocusEvents(dev, focus->win, focusWin, mode); + } focus->time = time; focus->revert = revertTo; if (focusID == FollowKeyboard) @@ -4341,8 +4565,7 @@ SetInputFocus( * Sets the input focus for the virtual core keyboard. */ int -ProcSetInputFocus(client) - ClientPtr client; +ProcSetInputFocus(ClientPtr client) { DeviceIntPtr kbd = PickKeyboard(client); REQUEST(xSetInputFocusReq); @@ -4373,6 +4596,7 @@ ProcGetInputFocus(ClientPtr client) if (rc != Success) return rc; + memset(&rep, 0, sizeof(xGetInputFocusReply)); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -4398,40 +4622,22 @@ ProcGrabPointer(ClientPtr client) xGrabPointerReply rep; DeviceIntPtr device = PickPointer(client); GrabPtr grab; - WindowPtr pWin, confineTo; - CursorPtr cursor, oldCursor; + GrabMask mask; + WindowPtr confineTo; + CursorPtr oldCursor; REQUEST(xGrabPointerReq); TimeStamp time; - Mask access_mode = DixGrabAccess; int rc; REQUEST_SIZE_MATCH(xGrabPointerReq); UpdateCurrentTime(); - if ((stuff->pointerMode != GrabModeSync) && - (stuff->pointerMode != GrabModeAsync)) - { - client->errorValue = stuff->pointerMode; - return BadValue; - } - if ((stuff->keyboardMode != GrabModeSync) && - (stuff->keyboardMode != GrabModeAsync)) - { - client->errorValue = stuff->keyboardMode; - return BadValue; - } - if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) - { - client->errorValue = stuff->ownerEvents; - return BadValue; - } + if (stuff->eventMask & ~PointerGrabMask) { client->errorValue = stuff->eventMask; return BadValue; } - rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; + if (stuff->confineTo == None) confineTo = NullWindow; else @@ -4441,81 +4647,34 @@ ProcGrabPointer(ClientPtr client) if (rc != Success) return rc; } - if (stuff->cursor == None) - cursor = NullCursor; - else + + memset(&rep, 0, sizeof(xGrabPointerReply)); + oldCursor = NullCursor; + grab = device->deviceGrab.grab; + + if (grab) { - rc = dixLookupResourceByType((pointer *)&cursor, stuff->cursor, RT_CURSOR, - client, DixUseAccess); - if (rc != Success) - { - client->errorValue = stuff->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - access_mode |= DixForceAccess; + if (grab->confineTo && !confineTo) + ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE); + oldCursor = grab->cursor; } - if (stuff->pointerMode == GrabModeSync || - stuff->keyboardMode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, device, access_mode); + + mask.core = stuff->eventMask; + + rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode, + stuff->grabWindow, stuff->ownerEvents, stuff->time, + &mask, GRABTYPE_CORE, stuff->cursor, + stuff->confineTo, &rep.status); if (rc != Success) - return rc; + return rc; + + if (oldCursor && rep.status == GrabSuccess) + FreeCursor (oldCursor, (Cursor)0); - /* at this point, some sort of reply is guaranteed. */ time = ClientTimeToServerTime(stuff->time); rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; - - grab = device->deviceGrab.grab; - /* check for - 1. other client has a grab on the device already. - 2. window is viewable - 3. other client has this device as frozen "other" device - 4. times are screwed. - */ - if ((grab) && !SameClient(grab, client)) - rep.status = AlreadyGrabbed; - else if ((!pWin->realized) || - (confineTo && - !(confineTo->realized - && BorderSizeNotEmpty(device, confineTo)))) - rep.status = GrabNotViewable; - else if (device->deviceGrab.sync.frozen && - device->deviceGrab.sync.other && - !SameClient(device->deviceGrab.sync.other, client)) - rep.status = GrabFrozen; - else if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER)) - rep.status = GrabInvalidTime; - else - { - GrabRec tempGrab; - - oldCursor = NullCursor; - if (grab) - { - if (grab->confineTo && !confineTo) - ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE); - oldCursor = grab->cursor; - } - tempGrab.next = NULL; - tempGrab.cursor = cursor; - tempGrab.resource = client->clientAsMask; - tempGrab.ownerEvents = stuff->ownerEvents; - tempGrab.eventMask = stuff->eventMask; - tempGrab.confineTo = confineTo; - tempGrab.window = pWin; - tempGrab.keyboardMode = stuff->keyboardMode; - tempGrab.pointerMode = stuff->pointerMode; - tempGrab.device = device; - tempGrab.coreGrab = True; - tempGrab.genericMasks = NULL; - (*device->deviceGrab.ActivateGrab)(device, &tempGrab, time, FALSE); - if (oldCursor) - FreeCursor (oldCursor, (Cursor)0); - rep.status = GrabSuccess; - } WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep); return Success; } @@ -4621,26 +4780,27 @@ ProcUngrabPointer(ClientPtr client) */ int GrabDevice(ClientPtr client, DeviceIntPtr dev, - unsigned this_mode, unsigned other_mode, Window grabWindow, - unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status, - Bool coreGrab) + unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow, + unsigned ownerEvents, Time ctime, GrabMask *mask, + int grabtype, Cursor curs, Window confineToWin, CARD8 *status) { - WindowPtr pWin; + WindowPtr pWin, confineTo; GrabPtr grab; TimeStamp time; Mask access_mode = DixGrabAccess; int rc; GrabInfoPtr grabInfo = &dev->deviceGrab; + CursorPtr cursor; UpdateCurrentTime(); - if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync)) + if ((keyboard_mode != GrabModeSync) && (keyboard_mode != GrabModeAsync)) { - client->errorValue = this_mode; + client->errorValue = keyboard_mode; return BadValue; } - if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync)) + if ((pointer_mode != GrabModeSync) && (pointer_mode != GrabModeAsync)) { - client->errorValue = other_mode; + client->errorValue = pointer_mode; return BadValue; } if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) @@ -4652,7 +4812,32 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess); if (rc != Success) return rc; - if (this_mode == GrabModeSync || other_mode == GrabModeSync) + + if (confineToWin == None) + confineTo = NullWindow; + else + { + rc = dixLookupWindow(&confineTo, confineToWin, client, + DixSetAttrAccess); + if (rc != Success) + return rc; + } + + if (curs == None) + cursor = NullCursor; + else + { + rc = dixLookupResourceByType((pointer *)&cursor, curs, RT_CURSOR, + client, DixUseAccess); + if (rc != Success) + { + client->errorValue = curs; + return (rc == BadValue) ? BadCursor : rc; + } + access_mode |= DixForceAccess; + } + + if (keyboard_mode == GrabModeSync || pointer_mode == GrabModeSync) access_mode |= DixFreezeAccess; rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); if (rc != Success) @@ -4660,9 +4845,14 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, time = ClientTimeToServerTime(ctime); grab = grabInfo->grab; + if (grab && grab->grabtype != grabtype) + *status = AlreadyGrabbed; if (grab && !SameClient(grab, client)) *status = AlreadyGrabbed; - else if (!pWin->realized) + else if ((!pWin->realized) || + (confineTo && + !(confineTo->realized + && BorderSizeNotEmpty(dev, confineTo)))) *status = GrabNotViewable; else if ((CompareTimeStamps(time, currentTime) == LATER) || (CompareTimeStamps(time, grabInfo->grabTime) == EARLIER)) @@ -4681,14 +4871,18 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, tempGrab.window = pWin; tempGrab.resource = client->clientAsMask; tempGrab.ownerEvents = ownerEvents; - tempGrab.keyboardMode = this_mode; - tempGrab.pointerMode = other_mode; - tempGrab.eventMask = mask; + tempGrab.keyboardMode = keyboard_mode; + tempGrab.pointerMode = pointer_mode; + if (grabtype == GRABTYPE_CORE) + tempGrab.eventMask = mask->core; + else if (grabtype == GRABTYPE_XI) + tempGrab.eventMask = mask->xi; + else + memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask)); tempGrab.device = dev; - tempGrab.cursor = NULL; - tempGrab.coreGrab = coreGrab; - tempGrab.genericMasks = NULL; - + tempGrab.cursor = cursor; + tempGrab.confineTo = confineTo; + tempGrab.grabtype = grabtype; (*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE); *status = GrabSuccess; } @@ -4707,13 +4901,17 @@ ProcGrabKeyboard(ClientPtr client) REQUEST(xGrabKeyboardReq); int result; DeviceIntPtr keyboard = PickKeyboard(client); + GrabMask mask; REQUEST_SIZE_MATCH(xGrabKeyboardReq); - result = GrabDevice(client, keyboard, stuff->keyboardMode, - stuff->pointerMode, stuff->grabWindow, - stuff->ownerEvents, stuff->time, - KeyPressMask | KeyReleaseMask, &rep.status, TRUE); + memset(&rep, 0, sizeof(xGrabKeyboardReply)); + mask.core = KeyPressMask | KeyReleaseMask; + + result = GrabDevice(client, keyboard, stuff->pointerMode, + stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents, + stuff->time, &mask, GRABTYPE_CORE, None, None, + &rep.status); if (result != Success) return result; @@ -4745,7 +4943,7 @@ ProcUngrabKeyboard(ClientPtr client) time = ClientTimeToServerTime(stuff->id); if ((CompareTimeStamps(time, currentTime) != LATER) && (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) && - (grab) && SameClient(grab, client) && grab->coreGrab) + (grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_CORE) (*device->deviceGrab.DeactivateGrab)(device); return Success; } @@ -4762,6 +4960,7 @@ ProcQueryPointer(ClientPtr client) xQueryPointerReply rep; WindowPtr pWin, t; DeviceIntPtr mouse = PickPointer(client); + DeviceIntPtr keyboard; SpritePtr pSprite; int rc; REQUEST(xResourceReq); @@ -4774,12 +4973,16 @@ ProcQueryPointer(ClientPtr client) if (rc != Success) return rc; + keyboard = GetPairedDevice(mouse); + pSprite = mouse->spriteInfo->sprite; if (mouse->valuator->motionHintWindow) MaybeStopHint(mouse, client); + memset(&rep, 0, sizeof(xQueryPointerReply)); rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.mask = mouse->button->state | inputInfo.keyboard->key->state; + rep.mask = mouse->button ? (mouse->button->state) : 0; + rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state); rep.length = 0; rep.root = (RootWindow(mouse))->drawable.id; rep.rootX = pSprite->hot.x; @@ -4834,7 +5037,8 @@ InitEvents(void) inputInfo.off_devices = (DeviceIntPtr)NULL; inputInfo.keyboard = (DeviceIntPtr)NULL; inputInfo.pointer = (DeviceIntPtr)NULL; - lastEventMask = OwnerGrabButtonMask; + /* The mask for pointer motion events may have changed in the last server + * generation. See comment above definition of filters. */ filters[0][PointerMotionMask] = MotionNotify; for (i = 1; i < MAXDEVICES; i++) { @@ -4889,7 +5093,9 @@ ProcSendEvent(ClientPtr client) { WindowPtr pWin; WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ - SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; + DeviceIntPtr dev = PickPointer(client); + DeviceIntPtr keybd = GetPairedDevice(dev); + SpritePtr pSprite = dev->spriteInfo->sprite; REQUEST(xSendEventReq); REQUEST_SIZE_MATCH(xSendEventReq); @@ -4923,7 +5129,7 @@ ProcSendEvent(ClientPtr client) pWin = pSprite->win; else if (stuff->destination == InputFocus) { - WindowPtr inputFocus = inputInfo.keyboard->focus->win; + WindowPtr inputFocus = (keybd) ? keybd->focus->win : NoneWin; if (inputFocus == NoneWin) return Success; @@ -4959,8 +5165,8 @@ ProcSendEvent(ClientPtr client) if (XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1)) return Success; - if (DeliverEventsToWindow(PickPointer(client), pWin, - &stuff->event, 1, stuff->eventMask, NullGrab, 0)) + if (DeliverEventsToWindow(dev, pWin, + &stuff->event, 1, stuff->eventMask, NullGrab)) return Success; if (pWin == effectiveFocus) return Success; @@ -4970,8 +5176,8 @@ ProcSendEvent(ClientPtr client) } } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1)) - (void)DeliverEventsToWindow(PickPointer(client), pWin, &stuff->event, - 1, stuff->eventMask, NullGrab, 0); + DeliverEventsToWindow(dev, pWin, &stuff->event, + 1, stuff->eventMask, NullGrab); return Success; } @@ -4991,12 +5197,12 @@ ProcUngrabKey(ClientPtr client) int rc; REQUEST_SIZE_MATCH(xUngrabKeyReq); - rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixReadAccess); + rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixGetAttrAccess); if (rc != Success) return rc; - if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) || - (stuff->key < keybd->key->curKeySyms.minKeyCode)) + if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) || + (stuff->key < keybd->key->xkbInfo->desc->min_key_code)) && (stuff->key != AnyKey)) { client->errorValue = stuff->key; @@ -5013,8 +5219,9 @@ ProcUngrabKey(ClientPtr client) tempGrab.window = pWin; tempGrab.modifiersDetail.exact = stuff->modifiers; tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = inputInfo.keyboard; + tempGrab.modifierDevice = GetPairedDevice(keybd); tempGrab.type = KeyPress; + tempGrab.grabtype = GRABTYPE_CORE; tempGrab.detail.exact = stuff->key; tempGrab.detail.pMask = NULL; tempGrab.next = NULL; @@ -5038,47 +5245,38 @@ ProcGrabKey(ClientPtr client) GrabPtr grab; DeviceIntPtr keybd = PickKeyboard(client); int rc; + GrabParameters param; + GrabMask mask; REQUEST_SIZE_MATCH(xGrabKeyReq); - if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse)) - { - client->errorValue = stuff->ownerEvents; - return(BadValue); - } - if ((stuff->pointerMode != GrabModeSync) && - (stuff->pointerMode != GrabModeAsync)) - { - client->errorValue = stuff->pointerMode; - return BadValue; - } - if ((stuff->keyboardMode != GrabModeSync) && - (stuff->keyboardMode != GrabModeAsync)) - { - client->errorValue = stuff->keyboardMode; - return BadValue; - } - if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) || - (stuff->key < keybd->key->curKeySyms.minKeyCode)) + + memset(¶m, 0, sizeof(param)); + param.grabtype = GRABTYPE_CORE; + param.ownerEvents = stuff->ownerEvents; + param.this_device_mode = stuff->keyboardMode; + param.other_devices_mode = stuff->pointerMode; + param.modifiers = stuff->modifiers; + + rc = CheckGrabValues(client, ¶m); + if (rc != Success) + return rc; + + if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) || + (stuff->key < keybd->key->xkbInfo->desc->min_key_code)) && (stuff->key != AnyKey)) { client->errorValue = stuff->key; return BadValue; } - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess); if (rc != Success) return rc; - grab = CreateGrab(client->index, keybd, pWin, - (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents, - (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode, - keybd, stuff->modifiers, KeyPress, stuff->key, - NullWindow, NullCursor); + + mask.core = (KeyPressMask | KeyReleaseMask); + + grab = CreateGrab(client->index, keybd, keybd, pWin, GRABTYPE_CORE, &mask, + ¶m, KeyPress, stuff->key, NullWindow, NullCursor); if (!grab) return BadAlloc; return AddPassiveGrabToList(client, grab); @@ -5100,6 +5298,8 @@ ProcGrabButton(ClientPtr client) GrabPtr grab; DeviceIntPtr ptr, modifierDevice; Mask access_mode = DixGrabAccess; + GrabMask mask; + GrabParameters param; int rc; REQUEST_SIZE_MATCH(xGrabButtonReq); @@ -5166,11 +5366,18 @@ ProcGrabButton(ClientPtr client) if (rc != Success) return rc; - grab = CreateGrab(client->index, ptr, pWin, - (Mask)stuff->eventMask, (Bool)stuff->ownerEvents, - (Bool) stuff->keyboardMode, (Bool)stuff->pointerMode, - modifierDevice, stuff->modifiers, ButtonPress, - stuff->button, confineTo, cursor); + memset(¶m, 0, sizeof(param)); + param.grabtype = GRABTYPE_CORE; + param.ownerEvents = stuff->ownerEvents; + param.this_device_mode = stuff->keyboardMode; + param.other_devices_mode = stuff->pointerMode; + param.modifiers = stuff->modifiers; + + mask.core = stuff->eventMask; + + grab = CreateGrab(client->index, ptr, modifierDevice, pWin, + GRABTYPE_CORE, &mask, ¶m, ButtonPress, + stuff->button, confineTo, cursor); if (!grab) return BadAlloc; return AddPassiveGrabToList(client, grab); @@ -5188,6 +5395,7 @@ ProcUngrabButton(ClientPtr client) WindowPtr pWin; GrabRec tempGrab; int rc; + DeviceIntPtr ptr; REQUEST_SIZE_MATCH(xUngrabButtonReq); if ((stuff->modifiers != AnyModifier) && @@ -5199,14 +5407,18 @@ ProcUngrabButton(ClientPtr client) rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixReadAccess); if (rc != Success) return rc; + + ptr = PickPointer(client); + tempGrab.resource = client->clientAsMask; - tempGrab.device = PickPointer(client); + tempGrab.device = ptr; tempGrab.window = pWin; tempGrab.modifiersDetail.exact = stuff->modifiers; tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = inputInfo.keyboard; + tempGrab.modifierDevice = GetPairedDevice(ptr); tempGrab.type = ButtonPress; tempGrab.detail.exact = stuff->button; + tempGrab.grabtype = GRABTYPE_CORE; tempGrab.detail.pMask = NULL; tempGrab.next = NULL; @@ -5299,15 +5511,17 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) to None */ #ifdef NOTDEF - || clients[CLIENT_ID(parent->drawable.id)]->clientGone + || wClient(parent)->clientGone #endif ); - DoFocusEvents(keybd, pWin, parent, focusEventMode); + if (!ActivateFocusInGrab(keybd, pWin, parent)) + DoFocusEvents(keybd, pWin, parent, focusEventMode); focus->win = parent; focus->revert = RevertToNone; break; case RevertToPointerRoot: - DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode); + if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin)) + DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode); focus->win = PointerRootWin; focus->traceGood = 0; break; @@ -5340,7 +5554,7 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) * there is a grab on the window, the cursor will be re-confined into the * window. */ -_X_EXPORT void +void CheckCursorConfinement(WindowPtr pWin) { GrabPtr grab; @@ -5359,7 +5573,7 @@ CheckCursorConfinement(WindowPtr pWin) if (grab && (confineTo = grab->confineTo)) { if (!BorderSizeNotEmpty(pDev, confineTo)) - (*inputInfo.pointer->deviceGrab.DeactivateGrab)(pDev); + (*pDev->deviceGrab.DeactivateGrab)(pDev); else if ((pWin == confineTo) || IsParent(pWin, confineTo)) ConfineCursorToWindow(pDev, confineTo, TRUE, TRUE); } @@ -5441,7 +5655,7 @@ ProcRecolorCursor(ClientPtr client) * @param count Number of events. * @param events The event list. */ -_X_EXPORT void +void WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) { #ifdef PANORAMIX @@ -5451,10 +5665,8 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) int i, eventlength = sizeof(xEvent); -#ifdef XKB - if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events))) - return; -#endif + /* Let XKB rewrite the state, as it depends on client preferences. */ + XkbFilterEvents(pClient, count, events); #ifdef PANORAMIX if(!noPanoramiXExtension && @@ -5545,7 +5757,7 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) (*EventSwapVector[eventFrom->u.u.type & 0177]) (eventFrom, eventTo); - (void)WriteToClient(pClient, eventlength, (char *)eventTo); + WriteToClient(pClient, eventlength, (char *)eventTo); } } else @@ -5553,13 +5765,12 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) /* only one GenericEvent, remember? that means either count is 1 and * eventlength is arbitrary or eventlength is 32 and count doesn't * matter. And we're all set. Woohoo. */ - (void)WriteToClient(pClient, count * eventlength, (char *) events); + WriteToClient(pClient, count * eventlength, (char *) events); } } /* - * Set the client pointer for the given client. Second parameter setter could - * be used in the future to determine access rights. Unused for now. + * Set the client pointer for the given client. * * A client can have exactly one ClientPointer. Each time a * request/reply/event is processed and the choice of devices is ambiguous @@ -5567,21 +5778,25 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) * PickPointer()). * If a keyboard is needed, the first keyboard paired with the CP is used. */ -_X_EXPORT Bool -SetClientPointer(ClientPtr client, ClientPtr setter, DeviceIntPtr device) +int +SetClientPointer(ClientPtr client, DeviceIntPtr device) { - if (!device->isMaster) + int rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixUseAccess); + if (rc != Success) + return rc; + + if (!IsMaster(device)) { ErrorF("[dix] Need master device for ClientPointer. This is a bug.\n"); - return FALSE; + return BadDevice; } else if (!device->spriteInfo->spriteOwner) { ErrorF("[dix] Device %d does not have a sprite. " "Cannot be ClientPointer\n", device->id); - return FALSE; + return BadDevice; } client->clientPtr = device; - return TRUE; + return Success; } /* PickPointer will pick an appropriate pointer for the given client. @@ -5591,7 +5806,7 @@ SetClientPointer(ClientPtr client, ClientPtr setter, DeviceIntPtr device) * 2) A device set as ClientPointer for the given client. * 3) The first master device. */ -_X_EXPORT DeviceIntPtr +DeviceIntPtr PickPointer(ClientPtr client) { DeviceIntPtr it = inputInfo.devices; @@ -5601,10 +5816,9 @@ PickPointer(ClientPtr client) for(it = inputInfo.devices; it; it = it->next) { GrabPtr grab = it->deviceGrab.grab; - if (grab && grab->coreGrab && SameClient(grab, client)) + if (grab && grab->grabtype == GRABTYPE_CORE && SameClient(grab, client)) { - if (!IsPointerDevice(it)) - it = GetPairedDevice(it); + it = GetMaster(it, MASTER_POINTER); return it; /* Always return a core grabbed device */ } } @@ -5614,7 +5828,7 @@ PickPointer(ClientPtr client) DeviceIntPtr it = inputInfo.devices; while (it) { - if (it->isMaster && it->spriteInfo->spriteOwner) + if (IsMaster(it) && it->spriteInfo->spriteOwner) { client->clientPtr = it; break; @@ -5629,11 +5843,11 @@ PickPointer(ClientPtr client) * searching the list of devices for the keyboard device that is paired with * the client's pointer. */ -_X_EXPORT DeviceIntPtr +DeviceIntPtr PickKeyboard(ClientPtr client) { DeviceIntPtr ptr = PickPointer(client); - DeviceIntPtr kbd = ptr->spriteInfo->paired; + DeviceIntPtr kbd = GetMaster(ptr, MASTER_KEYBOARD); if (!kbd) { @@ -5657,9 +5871,6 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event) { DeviceIntPtr it = inputInfo.devices; - if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client)) - return FALSE; - switch(event->u.u.type) { case KeyPress: @@ -5674,6 +5885,9 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event) return FALSE; } + if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client)) + return FALSE; + while(it) { if (it != dev) @@ -5692,86 +5906,3 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event) return FALSE; } -/** - * Set the filters for a extension. - * The filters array needs to contain the Masks that are applicable for each - * event type for the given extension. - * e.g. if generic event type 2 should be let through for windows with - * MyExampleMask set, make sure that filters[2] == MyExampleMask. - */ -_X_EXPORT void -SetGenericFilter(int extension, Mask* filters) -{ - generic_filters[extension & 0x7f] = filters; -} - - -/** - * Grab a device for XI events and XGE events. - * grabmode is used to ungrab a device. - */ -_X_EXPORT int -ExtGrabDevice(ClientPtr client, - DeviceIntPtr dev, - int device_mode, - WindowPtr grabWindow, - WindowPtr confineTo, - TimeStamp ctime, - Bool ownerEvents, - CursorPtr cursor, - Mask xi_mask, - GenericMaskPtr ge_masks) -{ - GrabInfoPtr grabinfo; - GrabRec newGrab; - - UpdateCurrentTime(); - - grabinfo = &dev->deviceGrab; - - if (grabinfo->grab && !SameClient(grabinfo->grab, client)) - return AlreadyGrabbed; - - if (!grabWindow->realized) - return GrabNotViewable; - - if ((CompareTimeStamps(ctime, currentTime) == LATER) || - (CompareTimeStamps(ctime, grabinfo->grabTime) == EARLIER)) - return GrabInvalidTime; - - if (grabinfo->sync.frozen && grabinfo->sync.other && - !SameClient(grabinfo->sync.other, client)) - return GrabFrozen; - - memset(&newGrab, 0, sizeof(GrabRec)); - newGrab.window = grabWindow; - newGrab.resource = client->clientAsMask; - newGrab.ownerEvents = ownerEvents; - newGrab.device = dev; - newGrab.cursor = cursor; - newGrab.confineTo = confineTo; - newGrab.eventMask = xi_mask; - newGrab.genericMasks = NULL; - newGrab.next = NULL; - - if (ge_masks) - { - newGrab.genericMasks = xcalloc(1, sizeof(GenericMaskRec)); - *newGrab.genericMasks = *ge_masks; - newGrab.genericMasks->next = NULL; - } - - if (IsPointerDevice(dev)) - { - newGrab.keyboardMode = GrabModeAsync; - newGrab.pointerMode = device_mode; - } else - { - newGrab.keyboardMode = device_mode; - newGrab.pointerMode = GrabModeAsync; - } - - (*grabinfo->ActivateGrab)(dev, &newGrab, ctime, FALSE); - return GrabSuccess; -} - diff --git a/xorg-server/dix/extension.c b/xorg-server/dix/extension.c index 3070f4da1..fb83af148 100644 --- a/xorg-server/dix/extension.c +++ b/xorg-server/dix/extension.c @@ -50,8 +50,6 @@ SOFTWARE. #endif #include <X11/X.h> -#define NEED_EVENTS -#define NEED_REPLIES #include <X11/Xproto.h> #include "misc.h" #include "dixstruct.h" @@ -72,7 +70,7 @@ int lastEvent = EXTENSION_EVENT_BASE; static int lastError = FirstExtensionError; static unsigned int NumExtensions = 0; -_X_EXPORT ExtensionEntry * +ExtensionEntry * AddExtension(char *name, int NumEvents, int NumErrors, int (*MainProc)(ClientPtr c1), int (*SwappedMainProc)(ClientPtr c2), @@ -88,10 +86,10 @@ AddExtension(char *name, int NumEvents, int NumErrors, (unsigned)(lastError + NumErrors > LAST_ERROR)) return((ExtensionEntry *) NULL); - ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry)); + ext = xalloc(sizeof(ExtensionEntry)); if (!ext) - return((ExtensionEntry *) NULL); - ext->name = (char *)xalloc(strlen(name) + 1); + return(NULL); + ext->name = xalloc(strlen(name) + 1); ext->num_aliases = 0; ext->aliases = (char **)NULL; ext->devPrivates = NULL; @@ -146,7 +144,7 @@ AddExtension(char *name, int NumEvents, int NumErrors, return(ext); } -_X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext) +Bool AddExtensionAlias(char *alias, ExtensionEntry *ext) { char *name; char **aliases; @@ -158,7 +156,7 @@ _X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext) if (!aliases) return FALSE; ext->aliases = aliases; - name = (char *)xalloc(strlen(alias) + 1); + name = xalloc(strlen(alias) + 1); if (!name) return FALSE; strcpy(name, alias); @@ -192,7 +190,7 @@ FindExtension(char *extname, int len) * CheckExtension returns the extensions[] entry for the requested * extension name. Maybe this could just return a Bool instead? */ -_X_EXPORT ExtensionEntry * +ExtensionEntry * CheckExtension(const char *extname) { int n; @@ -218,13 +216,13 @@ GetExtensionEntry(int major) return extensions[major]; } -_X_EXPORT unsigned short +unsigned short StandardMinorOpcode(ClientPtr client) { return ((xReq *)client->requestBuffer)->data; } -_X_EXPORT unsigned short +unsigned short MinorOpcodeOfRequest(ClientPtr client) { unsigned char major; @@ -269,7 +267,8 @@ ProcQueryExtension(ClientPtr client) REQUEST(xQueryExtensionReq); REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes); - + + memset(&reply, 0, sizeof(xQueryExtensionReply)); reply.type = X_Reply; reply.length = 0; reply.major_opcode = 0; @@ -303,6 +302,7 @@ ProcListExtensions(ClientPtr client) REQUEST_SIZE_MATCH(xReq); + memset(&reply, 0, sizeof(xListExtensionsReply)); reply.type = X_Reply; reply.nExtensions = 0; reply.length = 0; @@ -324,8 +324,8 @@ ProcListExtensions(ClientPtr client) for (j = extensions[i]->num_aliases; --j >= 0;) total_length += strlen(extensions[i]->aliases[j]) + 1; } - reply.length = (total_length + 3) >> 2; - buffer = bufptr = (char *)xalloc(total_length); + reply.length = bytes_to_int32(total_length); + buffer = bufptr = xalloc(total_length); if (!buffer) return(BadAlloc); for (i=0; i<NumExtensions; i++) diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c index 44bfe8b65..649016595 100644 --- a/xorg-server/dix/gc.c +++ b/xorg-server/dix/gc.c @@ -73,7 +73,7 @@ static Bool CreateDefaultTile(GCPtr pGC); static unsigned char DefaultDash[2] = {4, 4}; -_X_EXPORT void +void ValidateGC(DrawablePtr pDraw, GC *pGC) { (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw); @@ -145,7 +145,7 @@ ValidateGC(DrawablePtr pDraw, GC *pGC) #define NEXT_PTR(_type, _var) { \ assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; } -_X_EXPORT int +int dixChangeGC(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion) { BITS32 index2; @@ -470,7 +470,7 @@ dixChangeGC(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32, ChangeGCValPtr { unsigned char *dash; - dash = (unsigned char *)xalloc(2 * sizeof(unsigned char)); + dash = xalloc(2 * sizeof(unsigned char)); if (dash) { if (pGC->dash != DefaultDash) @@ -527,7 +527,7 @@ dixChangeGC(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32, ChangeGCValPtr /* Publically defined entry to ChangeGC. Just calls dixChangeGC and tells * it that all of the entries are constants or IDs */ -_X_EXPORT int +int ChangeGC(GC *pGC, BITS32 mask, XID *pval) { return (dixChangeGC(NullClient, pGC, mask, pval, NULL)); @@ -553,7 +553,7 @@ NOTE: all values sent over the protocol for ChangeGC requests are 32 bits long */ -_X_EXPORT int +int DoChangeGC(GC *pGC, BITS32 mask, XID *pval, int fPointer) { if (fPointer) @@ -573,13 +573,13 @@ BUG: should check for failure to create default tile */ -_X_EXPORT GCPtr +GCPtr CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, XID gcid, ClientPtr client) { GCPtr pGC; - pGC = (GCPtr)xalloc(sizeof(GC)); + pGC = xalloc(sizeof(GC)); if (!pGC) { *pStatus = BadAlloc; @@ -602,6 +602,8 @@ CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, pGC->fillStyle = FillSolid; pGC->fillRule = EvenOddRule; pGC->arcMode = ArcPieSlice; + pGC->tile.pixel = 0; + pGC->tile.pixmap = NullPixmap; if (mask & GCForeground) { /* @@ -609,12 +611,10 @@ CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, * and snags the Foreground value to create a pseudo default-tile */ pGC->tileIsPixel = FALSE; - pGC->tile.pixmap = NullPixmap; } else { pGC->tileIsPixel = TRUE; - pGC->tile.pixel = 0; } pGC->patOrg.x = 0; @@ -706,7 +706,7 @@ CreateDefaultTile (GCPtr pGC) return TRUE; } -_X_EXPORT int +int CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask) { BITS32 index2; @@ -829,8 +829,7 @@ CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask) unsigned char *dash; unsigned int i; - dash = (unsigned char *)xalloc(pgcSrc->numInDashList * - sizeof(unsigned char)); + dash = xalloc(pgcSrc->numInDashList * sizeof(unsigned char)); if (dash) { if (pgcDst->dash != DefaultDash) @@ -870,7 +869,7 @@ CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask) * * \param value must conform to DeleteType */ -_X_EXPORT int +int FreeGC(pointer value, XID gid) { GCPtr pGC = (GCPtr)value; @@ -904,12 +903,12 @@ is what fills the default tile. (maybe this comment should go with CreateGC() or ChangeGC().) */ -_X_EXPORT GCPtr +GCPtr CreateScratchGC(ScreenPtr pScreen, unsigned depth) { GCPtr pGC; - pGC = (GCPtr)xalloc(sizeof(GC)); + pGC = xalloc(sizeof(GC)); if (!pGC) return (GCPtr)NULL; @@ -933,6 +932,7 @@ CreateScratchGC(ScreenPtr pScreen, unsigned depth) pGC->font->refcnt++; pGC->tileIsPixel = TRUE; pGC->tile.pixel = 0; + pGC->tile.pixmap = NullPixmap; pGC->stipple = NullPixmap; pGC->patOrg.x = 0; pGC->patOrg.y = 0; @@ -1069,9 +1069,9 @@ SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash) } if (ndash & 1) - p = (unsigned char *)xalloc(2 * ndash * sizeof(unsigned char)); + p = xalloc(2 * ndash * sizeof(unsigned char)); else - p = (unsigned char *)xalloc(ndash * sizeof(unsigned char)); + p = xalloc(ndash * sizeof(unsigned char)); if (!p) return BadAlloc; @@ -1105,7 +1105,7 @@ SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash) return Success; } -_X_EXPORT int +int VerifyRectOrder(int nrects, xRectangle *prects, int ordering) { xRectangle *prectP, *prectN; @@ -1166,7 +1166,7 @@ SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects, if (newct < 0) return(BadMatch); size = nrects * sizeof(xRectangle); - prectsNew = (xRectangle *) xalloc(size); + prectsNew = xalloc(size); if (!prectsNew && size) return BadAlloc; @@ -1192,7 +1192,7 @@ SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects, if we can't, create one out of whole cloth (The Velveteen GC -- if you use it often enough it will become real.) */ -_X_EXPORT GCPtr +GCPtr GetScratchGC(unsigned depth, ScreenPtr pScreen) { int i; @@ -1241,7 +1241,7 @@ GetScratchGC(unsigned depth, ScreenPtr pScreen) mark it as available. if not, free it for real */ -_X_EXPORT void +void FreeScratchGC(GCPtr pGC) { ScreenPtr pScreen = pGC->pScreen; diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index 50a8f5690..e19d0ce11 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -1,6 +1,7 @@ /* * Copyright © 2006 Nokia Corporation * Copyright © 2006-2007 Daniel Stone + * 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"), @@ -21,7 +22,8 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * - * Author: Daniel Stone <daniel@fooishbar.org> + * Authors: Daniel Stone <daniel@fooishbar.org> + * Peter Hutterer <peter.hutterer@who-t.net> */ #ifdef HAVE_DIX_CONFIG_H @@ -30,8 +32,6 @@ #include <X11/X.h> #include <X11/keysym.h> -#define NEED_EVENTS -#define NEED_REPLIES #include <X11/Xproto.h> #include "misc.h" @@ -43,11 +43,11 @@ #include "globals.h" #include "dixevents.h" #include "mipointer.h" +#include "eventstr.h" +#include "eventconvert.h" -#ifdef XKB #include <X11/extensions/XKBproto.h> -#include <xkbsrv.h> -#endif +#include "xkbsrv.h" #ifdef PANORAMIX #include "panoramiX.h" @@ -60,6 +60,11 @@ #include "exevents.h" #include "exglobals.h" #include "extnsionst.h" +#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ + +#ifdef _MSC_VER +#define lroundf(val) ((int)(val<0.0f)?val-.5f:val+.5f) +#endif /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 @@ -71,7 +76,7 @@ EventListPtr InputEventList = NULL; int InputEventListLen = 0; -_X_EXPORT int +int GetEventList(EventListPtr* list) { *list = InputEventList; @@ -81,28 +86,41 @@ GetEventList(EventListPtr* list) /** * Pick some arbitrary size for Xi motion history. */ -_X_EXPORT int +int GetMotionHistorySize(void) { return MOTION_HISTORY_SIZE; } -static void -set_key_down(DeviceIntPtr pDev, int key_code) +void +set_key_down(DeviceIntPtr pDev, int key_code, int type) { - pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7)); + if (type == KEY_PROCESSED) + pDev->key->down[key_code >> 3] |= (1 << (key_code & 7)); + else + pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7)); } -static void -set_key_up(DeviceIntPtr pDev, int key_code) +void +set_key_up(DeviceIntPtr pDev, int key_code, int type) { - pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7)); + if (type == KEY_PROCESSED) + pDev->key->down[key_code >> 3] &= ~(1 << (key_code & 7)); + else + pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7)); } -static Bool -key_is_down(DeviceIntPtr pDev, int key_code) +Bool +key_is_down(DeviceIntPtr pDev, int key_code, int type) { - return !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7))); + int ret = 0; + + if (type & KEY_PROCESSED) + ret |= !!(pDev->key->down[key_code >> 3] & (1 << (key_code & 7))); + else if (type & KEY_POSTED) + ret |= !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7))); + + return ret; } static Bool @@ -119,14 +137,118 @@ float roundf(float f) } #endif +static void +init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms) +{ + memset(event, 0, sizeof(DeviceEvent)); + event->header = ET_Internal; + event->length = sizeof(DeviceEvent); + event->time = ms; + event->deviceid = dev->id; + event->sourceid = dev->id; +} + +static void +init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail) +{ + memset(event, 0, sizeof(RawDeviceEvent)); + event->header = ET_Internal; + event->length = sizeof(RawDeviceEvent); + event->type = ET_RawKeyPress - ET_KeyPress + type; + event->time = ms; + event->deviceid = dev->id; + event->sourceid = dev->id; + event->detail.button = detail; +} + +static void +set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data) +{ + int i; + for (i = first; i < first + num; i++) + SetBit(event->valuators.mask, i); + + memcpy(&data[first], valuators, num * sizeof(uint32_t)); +} + + +static void +set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator, + int num_valuators, int *valuators) +{ + int i; + + for (i = first_valuator; i < first_valuator + num_valuators; i++) + { + SetBit(event->valuators.mask, i); + if (dev->valuator->mode == Absolute) + SetBit(event->valuators.mode, i); + event->valuators.data_frac[i] = + dev->last.remainder[i] * (1 << 16) * (1 << 16); + } + + memcpy(&event->valuators.data[first_valuator], + valuators, num_valuators * sizeof(uint32_t)); + +} + +void +CreateClassesChangedEvent(EventList* event, + DeviceIntPtr master, + DeviceIntPtr slave, + int type) +{ + int i; + DeviceChangedEvent *dce; + CARD32 ms = GetTimeInMillis(); + + dce = (DeviceChangedEvent*)event->event; + memset(dce, 0, sizeof(DeviceChangedEvent)); + dce->deviceid = slave->id; + dce->masterid = master->id; + dce->header = ET_Internal; + dce->length = sizeof(DeviceChangedEvent); + dce->type = ET_DeviceChanged; + dce->time = ms; + dce->flags = type; + dce->flags |= DEVCHANGE_SLAVE_SWITCH; + dce->sourceid = slave->id; + + if (slave->button) + { + dce->buttons.num_buttons = slave->button->numButtons; + for (i = 0; i < dce->buttons.num_buttons; i++) + dce->buttons.names[i] = slave->button->labels[i]; + } + if (slave->valuator) + { + dce->num_valuators = slave->valuator->numAxes; + for (i = 0; i < dce->num_valuators; i++) + { + dce->valuators[i].min = slave->valuator->axes[i].min_value; + dce->valuators[i].max = slave->valuator->axes[i].max_value; + dce->valuators[i].resolution = slave->valuator->axes[i].resolution; + /* This should, eventually, be a per-axis mode */ + dce->valuators[i].mode = slave->valuator->mode; + dce->valuators[i].name = slave->valuator->axes[i].label; + } + } + if (slave->key) + { + dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code; + dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code; + } +} + /** * Rescale the coord between the two axis ranges. */ static int -rescaleValuatorAxis(int coord, AxisInfoPtr from, AxisInfoPtr to, +rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to, int defmax) { - int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax; + int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return; + float value; if(from && from->min_value < from->max_value) { fmin = from->min_value; @@ -137,14 +259,23 @@ rescaleValuatorAxis(int coord, AxisInfoPtr from, AxisInfoPtr to, tmax = to->max_value; } - if(fmin == tmin && fmax == tmax) + if(fmin == tmin && fmax == tmax) { + if (remainder_return) + *remainder_return = remainder; return coord; + } - if(fmax == fmin) /* avoid division by 0 */ + if(fmax == fmin) { /* avoid division by 0 */ + if (remainder_return) + *remainder_return = 0.0; return 0; + } - return roundf(((float)(coord - fmin)) * (tmax - tmin) / - (fmax - fmin)) + tmin; + value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin; + coord_return = lroundf(value); + if (remainder_return) + *remainder_return = value - coord_return; + return coord_return; } /** @@ -172,21 +303,25 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) /* scale back to device coordinates */ if(pDev->valuator->numAxes > 0) - pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL, pDev->valuator->axes + 0, scr->width); + pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0], + &pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width); if(pDev->valuator->numAxes > 1) - pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL, pDev->valuator->axes + 1, scr->height); + pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1], + &pDev->last.remainder[0], NULL, pDev->valuator->axes + 1, scr->height); /* calculate the other axis as well based on info from the old * slave-device. If the old slave had less axes than this one, * last.valuators is reset to 0. */ - if ((lastSlave = master->u.lastSlave) && lastSlave->valuator) { + if ((lastSlave = master->last.slave) && lastSlave->valuator) { for (i = 2; i < pDev->valuator->numAxes; i++) { if (i >= lastSlave->valuator->numAxes) pDev->last.valuators[i] = 0; else pDev->last.valuators[i] = rescaleValuatorAxis(pDev->last.valuators[i], + pDev->last.remainder[i], + &pDev->last.remainder[i], lastSlave->valuator->axes + i, pDev->valuator->axes + i, 0); } @@ -197,7 +332,7 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) /** * Allocate the motion history buffer. */ -_X_EXPORT void +void AllocateMotionHistory(DeviceIntPtr pDev) { int size; @@ -211,7 +346,7 @@ AllocateMotionHistory(DeviceIntPtr pDev) * potential valuators, plus the respective range of the valuators. * 3 * INT32 for (min_val, max_val, curr_val)) */ - if (pDev->isMaster) + if (IsMaster(pDev)) size = sizeof(INT32) * 3 * MAX_VALUATORS; else size = sizeof(INT32) * pDev->valuator->numAxes; @@ -233,7 +368,7 @@ AllocateMotionHistory(DeviceIntPtr pDev) * * If core is set, we only generate x/y, in INT16, scaled to screen coords. */ -_X_EXPORT int +int GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, unsigned long stop, ScreenPtr pScreen, BOOL core) { @@ -255,7 +390,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, if (core && !pScreen) return 0; - if (pDev->isMaster) + if (IsMaster(pDev)) size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time); else size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); @@ -293,7 +428,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, /* scale to screen coords */ to = &core_axis; to->max_value = pScreen->width; - coord = rescaleValuatorAxis(coord, &from, to, pScreen->width); + coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width); memcpy(corebuf, &coord, sizeof(INT16)); corebuf++; @@ -304,10 +439,10 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, memcpy(&coord, icbuf++, sizeof(INT32)); to->max_value = pScreen->height; - coord = rescaleValuatorAxis(coord, &from, to, pScreen->height); + coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height); memcpy(corebuf, &coord, sizeof(INT16)); - } else if (pDev->isMaster) + } else if (IsMaster(pDev)) { memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ @@ -339,7 +474,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, dflt = 0; /* scale from stored range into current range */ - coord = rescaleValuatorAxis(coord, &from, to, 0); + coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0); memcpy(ocbuf, &coord, sizeof(INT32)); ocbuf++; } @@ -383,7 +518,7 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator, return; v = pDev->valuator; - if (pDev->isMaster) + if (IsMaster(pDev)) { buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) * v->last_motion; @@ -435,23 +570,15 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator, * Returns the maximum number of events GetKeyboardEvents, * GetKeyboardValuatorEvents, and GetPointerEvents will ever return. * - * Should be used in DIX as: - * xEvent *events = xcalloc(sizeof(xEvent), GetMaximumEventsNum()); - * * This MUST be absolutely constant, from init until exit. */ -_X_EXPORT int +int GetMaximumEventsNum(void) { - /* One base event -- device, plus valuator events. - * Multiply by two if we're doing non-XKB key repeats. */ - int ret = 1 + MAX_VALUATOR_EVENTS; - -#ifdef XKB - if (noXkbExtension) -#endif - ret *= 2; - - return ret; + /* One raw event + * One device event + * One possible device changed event + */ + return 3; } @@ -465,6 +592,9 @@ clipAxis(DeviceIntPtr pDev, int axisNum, int *val) AxisInfoPtr axis = pDev->valuator->axes + axisNum; /* InitValuatoraAxisStruct ensures that (min < max). */ + if (axisNum >= pDev->valuator->numAxes) + return; + /* If a value range is defined, clip. If not, do nothing */ if (axis->max_value <= axis->min_value) return; @@ -482,52 +612,12 @@ static void clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators, int *valuators) { - AxisInfoPtr axes = pDev->valuator->axes + first_valuator; int i; - for (i = 0; i < num_valuators; i++, axes++) + for (i = 0; i < num_valuators; i++) clipAxis(pDev, i + first_valuator, &(valuators[i])); } - -/** - * Fills events with valuator events for pDev, as given by the other - * parameters. - */ -static EventList * -getValuatorEvents(EventList *events, DeviceIntPtr pDev, - int first_valuator, int num_valuators, int *valuators) { - deviceValuator *xv; - int i; - - for (i = 0; i < num_valuators; i += 6, events++) { - xv = (deviceValuator*)events->event; - xv->type = DeviceValuator; - xv->first_valuator = first_valuator + i; - xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); - xv->deviceid = pDev->id; - switch (num_valuators - i) { - case 6: - xv->valuator5 = valuators[i + 5]; - case 5: - xv->valuator4 = valuators[i + 4]; - case 4: - xv->valuator3 = valuators[i + 3]; - case 3: - xv->valuator2 = valuators[i + 2]; - case 2: - xv->valuator1 = valuators[i + 1]; - case 1: - xv->valuator0 = valuators[i + 0]; - } - - if (i + 6 < num_valuators) - xv->deviceid |= MORE_EVENTS; - } - - return events; -} - /** * Create the DCCE event (does not update the master's device state yet, this * is done in the event processing). @@ -535,19 +625,26 @@ getValuatorEvents(EventList *events, DeviceIntPtr pDev, * * @param events Pointer to a pre-allocated event list. * @param dev The slave device that generated an event. + * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT * @param num_events The current number of events, returns the number of * events if a DCCE was generated. * @return The updated @events pointer. */ static EventListPtr -updateFromMaster(EventListPtr events, DeviceIntPtr dev, int *num_events) +updateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events) { - DeviceIntPtr master = dev->u.master; - if (master && master->u.lastSlave != dev) + DeviceIntPtr master; + + master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : MASTER_KEYBOARD); + + if (master && master->last.slave != dev) { + CreateClassesChangedEvent(events, master, dev, type); updateSlaveDeviceCoords(master, dev); - master->u.lastSlave = dev; + master->last.slave = dev; master->last.numValuators = dev->last.numValuators; + (*num_events)++; + events++; } return events; } @@ -663,48 +760,69 @@ accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms) * @param dev The device to be moved. * @param x Pointer to current x-axis value, may be modified. * @param y Pointer to current y-axis value, may be modified. + * @param x_frac Fractional part of current x-axis value, may be modified. + * @param y_frac Fractional part of current y-axis value, may be modified. * @param scr Screen the device's sprite is currently on. * @param screenx Screen x coordinate the sprite is on after the update. * @param screeny Screen y coordinate the sprite is on after the update. + * @param screenx_frac Fractional part of screen x coordinate, as above. + * @param screeny_frac Fractional part of screen y coordinate, as above. */ static void -positionSprite(DeviceIntPtr dev, int *x, int *y, - ScreenPtr scr, int *screenx, int *screeny) +positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac, + ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac) { + int old_screenx, old_screeny; + /* scale x&y to screen */ - *screenx = rescaleValuatorAxis(*x, dev->valuator->axes + 0, NULL, scr->width); - *screeny = rescaleValuatorAxis(*y, dev->valuator->axes + 1, NULL, scr->height); - dev->last.valuators[0] = *screenx; - dev->last.valuators[1] = *screeny; + if (dev->valuator->numAxes > 0) { + *screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac, + dev->valuator->axes + 0, NULL, scr->width); + } else { + *screenx = dev->last.valuators[0]; + *screenx_frac = dev->last.remainder[0]; + } + if (dev->valuator->numAxes > 1) { + *screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac, + dev->valuator->axes + 1, NULL, scr->height); + } else { + *screeny = dev->last.valuators[1]; + *screeny_frac = dev->last.remainder[1]; + } + + old_screenx = *screenx; + old_screeny = *screeny; /* This takes care of crossing screens for us, as well as clipping * to the current screen. */ - miPointerSetPosition(dev, &dev->last.valuators[0], &dev->last.valuators[1]); + miPointerSetPosition(dev, screenx, screeny); if (dev->u.master) { - dev->u.master->last.valuators[0] = dev->last.valuators[0]; - dev->u.master->last.valuators[1] = dev->last.valuators[1]; + dev->u.master->last.valuators[0] = *screenx; + dev->u.master->last.valuators[1] = *screeny; + dev->u.master->last.remainder[0] = *screenx_frac; + dev->u.master->last.remainder[1] = *screeny_frac; } /* Crossed screen? Scale back to device coordiantes */ - if(*screenx != dev->last.valuators[0]) + if(*screenx != old_screenx) { scr = miPointerGetScreen(dev); - *x = rescaleValuatorAxis(dev->last.valuators[0], NULL, + *x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL, dev->valuator->axes + 0, scr->width); - *screenx = dev->last.valuators[0]; } - if(*screeny != dev->last.valuators[1]) + if(*screeny != old_screeny) { scr = miPointerGetScreen(dev); - *screeny = dev->last.valuators[1]; - *y = rescaleValuatorAxis(dev->last.valuators[1], NULL, + *y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL, dev->valuator->axes + 1, scr->height); } /* dropy x/y (device coordinates) back into valuators for next event */ dev->last.valuators[0] = *x; dev->last.valuators[1] = *y; + dev->last.remainder[0] = x_frac; + dev->last.remainder[1] = y_frac; } /** @@ -720,32 +838,17 @@ updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms) { updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]); if (dev->u.master) - updateMotionHistory(dev->u.master, ms, first, num, - &dev->last.valuators[first]); -} - -/** - * Calculate how many DeviceValuator events are needed given a number of - * valuators. - * @param num_valuators Number of valuators to attach to event. - * @return the number of DeviceValuator events needed. - */ -static int -countValuatorEvents(int num_valuators) -{ - if (num_valuators) { - if (((num_valuators - 1) / 6) + 1 > MAX_VALUATOR_EVENTS) - num_valuators = MAX_VALUATOR_EVENTS * 6; - return ((num_valuators - 1)/ 6) + 1; - } else - return 0; + { + DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); + updateMotionHistory(master, ms, first, num, &dev->last.valuators[first]); + } } /** * Convenience wrapper around GetKeyboardValuatorEvents, that takes no * valuators. */ -_X_EXPORT int +int GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) { return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL); } @@ -771,98 +874,73 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) * key press will trigger a matching KeyRelease, as well as the * KeyPresses. */ -_X_EXPORT int +int GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code, int first_valuator, int num_valuators, int *valuators) { - int numEvents = 0; + int num_events = 0; CARD32 ms = 0; - KeySym *map; - KeySym sym; - deviceKeyButtonPointer *kbp = NULL; + DeviceEvent *event; + RawDeviceEvent *raw; + + /* refuse events from disabled devices */ + if (!pDev->enabled) + return 0; if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed || (type != KeyPress && type != KeyRelease) || (key_code < 8 || key_code > 255)) return 0; - numEvents = 1; - - map = pDev->key->curKeySyms.map; - sym = map[(key_code - pDev->key->curKeySyms.minKeyCode) - * pDev->key->curKeySyms.mapWidth]; + num_events = 1; - events = updateFromMaster(events, pDev, &numEvents); + events = updateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events); - numEvents += countValuatorEvents(num_valuators); - -#ifdef XKB - if (noXkbExtension) -#endif - { - switch (sym) { - case XK_Num_Lock: - case XK_Caps_Lock: - case XK_Scroll_Lock: - case XK_Shift_Lock: - if (type == KeyRelease) - return 0; - else if (type == KeyPress && key_is_down(pDev, key_code)) - type = KeyRelease; - } - } - - /* Handle core repeating, via press/release/press/release. - * FIXME: In theory, if you're repeating with two keyboards in non-XKB, - * you could get unbalanced events here. */ - if (type == KeyPress && key_is_down(pDev, key_code)) { + /* Handle core repeating, via press/release/press/release. */ + if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) { /* If autorepeating is disabled either globally or just for that key, * or we have a modifier, don't generate a repeat event. */ if (!pDev->kbdfeed->ctrl.autoRepeat || !key_autorepeats(pDev, key_code) || - pDev->key->modifierMap[key_code]) + pDev->key->xkbInfo->desc->map->modmap[key_code]) return 0; - -#ifdef XKB - if (noXkbExtension) -#endif - { - int numReleaseEvents; - - numReleaseEvents = GetKeyboardValuatorEvents(events, pDev, - KeyRelease, key_code, - first_valuator, - num_valuators, - valuators); - numEvents += numReleaseEvents; - events += numReleaseEvents; - } } ms = GetTimeInMillis(); - kbp = (deviceKeyButtonPointer *) events->event; - kbp->time = ms; - kbp->deviceid = pDev->id; - kbp->detail = key_code; + raw = (RawDeviceEvent*)events->event; + events++; + num_events++; + + init_raw(pDev, raw, ms, type, key_code); + set_raw_valuators(raw, first_valuator, num_valuators, valuators, + raw->valuators.data_raw); + + if (num_valuators) + clipValuators(pDev, first_valuator, num_valuators, valuators); + + set_raw_valuators(raw, first_valuator, num_valuators, valuators, + raw->valuators.data); + + event = (DeviceEvent*) events->event; + init_event(pDev, event, ms); + event->detail.key = key_code; + if (type == KeyPress) { - kbp->type = DeviceKeyPress; - set_key_down(pDev, key_code); + event->type = ET_KeyPress; + set_key_down(pDev, key_code, KEY_POSTED); } else if (type == KeyRelease) { - kbp->type = DeviceKeyRelease; - set_key_up(pDev, key_code); + event->type = ET_KeyRelease; + set_key_up(pDev, key_code, KEY_POSTED); } - events++; - if (num_valuators) { - kbp->deviceid |= MORE_EVENTS; + if (num_valuators) clipValuators(pDev, first_valuator, num_valuators, valuators); - events = getValuatorEvents(events, pDev, first_valuator, - num_valuators, valuators); - } - return numEvents; + set_valuators(pDev, event, first_valuator, num_valuators, valuators); + + return num_events; } /** @@ -884,8 +962,8 @@ InitEventList(int num_events) for (i = 0; i < num_events; i++) { - events[i].evlen = sizeof(xEvent); - events[i].event = xcalloc(1, sizeof(xEvent)); + events[i].evlen = sizeof(InternalEvent); + events[i].event = xcalloc(1, sizeof(InternalEvent)); if (!events[i].event) { /* rollback */ @@ -903,7 +981,7 @@ InitEventList(int num_events) /** * Allocs min_size memory for each event in the list. */ -_X_EXPORT void +void SetMinimumEventSize(EventListPtr list, int num_events, int min_size) { if (!list) @@ -930,7 +1008,7 @@ SetMinimumEventSize(EventListPtr list, int num_events, int min_size) * @param list The list to be freed. * @param num_events Number of elements in list. */ -_X_EXPORT void +void FreeEventList(EventListPtr list, int num_events) { if (!list) @@ -959,53 +1037,75 @@ FreeEventList(EventListPtr list, int num_events) * * master->last.valuators[x] for x > 2 is undefined. */ -_X_EXPORT int +int GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, int flags, int first_valuator, int num_valuators, int *valuators) { int num_events = 1; CARD32 ms; - deviceKeyButtonPointer *kbp = NULL; - int x, y, /* switches between device and screen coords */ + DeviceEvent *event; + RawDeviceEvent *raw; + int x = 0, y = 0, /* device coords */ cx, cy; /* only screen coordinates */ + float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac; ScreenPtr scr = miPointerGetScreen(pDev); + /* refuse events from disabled devices */ + if (!pDev->enabled) + return 0; + ms = GetTimeInMillis(); /* before pointer update to help precision */ if (!scr || !pDev->valuator || first_valuator < 0 || ((num_valuators + first_valuator) > pDev->valuator->numAxes) || (type != MotionNotify && type != ButtonPress && type != ButtonRelease) || (type != MotionNotify && !pDev->button) || + ((type == ButtonPress || type == ButtonRelease) && !buttons) || (type == MotionNotify && num_valuators <= 0)) return 0; - num_events += countValuatorEvents(num_valuators); + events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); + + raw = (RawDeviceEvent*)events->event; + events++; + num_events++; - events = updateFromMaster(events, pDev, &num_events); + init_raw(pDev, raw, ms, type, buttons); + set_raw_valuators(raw, first_valuator, num_valuators, valuators, + raw->valuators.data_raw); if (flags & POINTER_ABSOLUTE) { if (flags & POINTER_SCREEN) /* valuators are in screen coords */ { - valuators[0] = rescaleValuatorAxis(valuators[0], NULL, - pDev->valuator->axes + 0, - scr->width); - valuators[1] = rescaleValuatorAxis(valuators[1], NULL, - pDev->valuator->axes + 1, - scr->height); + if (num_valuators >= 1 && first_valuator == 0) + valuators[0] = rescaleValuatorAxis(valuators[0], 0.0, &x_frac, NULL, + pDev->valuator->axes + 0, + scr->width); + if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) + valuators[1 - first_valuator] = rescaleValuatorAxis(valuators[1 - first_valuator], 0.0, &y_frac, NULL, + pDev->valuator->axes + 1, + scr->height); } moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators); } else { - if (flags & POINTER_ACCELERATE) + if (flags & POINTER_ACCELERATE) { accelPointer(pDev, first_valuator, num_valuators, valuators, ms); + /* The pointer acceleration code modifies the fractional part + * in-place, so we need to extract this information first */ + x_frac = pDev->last.remainder[0]; + y_frac = pDev->last.remainder[1]; + } moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators); } - positionSprite(pDev, &x, &y, scr, &cx, &cy); - updateHistory(pDev, first_valuator, num_valuators, ms); + set_raw_valuators(raw, first_valuator, num_valuators, valuators, + raw->valuators.data); + positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac); + updateHistory(pDev, first_valuator, num_valuators, ms); /* Update the valuators with the true value sent to the client*/ if (num_valuators >= 1 && first_valuator == 0) @@ -1013,32 +1113,34 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) valuators[1 - first_valuator] = y; - kbp = (deviceKeyButtonPointer *) events->event; - kbp->time = ms; - kbp->deviceid = pDev->id; + if (num_valuators) + clipValuators(pDev, first_valuator, num_valuators, valuators); + + event = (DeviceEvent*) events->event; + init_event(pDev, event, ms); if (type == MotionNotify) { - kbp->type = DeviceMotionNotify; + event->type = ET_Motion; + event->detail.button = 0; } else { - if (type == ButtonPress) - kbp->type = DeviceButtonPress; - else if (type == ButtonRelease) - kbp->type = DeviceButtonRelease; - kbp->detail = buttons; + if (type == ButtonPress) { + event->type = ET_ButtonPress; + pDev->button->postdown[buttons >> 3] |= (1 << (buttons & 7)); + } + else if (type == ButtonRelease) { + event->type = ET_ButtonRelease; + pDev->button->postdown[buttons >> 3] &= ~(1 << (buttons & 7)); + } + event->detail.button = buttons; } - kbp->root_x = cx; /* root_x/y always in screen coords */ - kbp->root_y = cy; + event->root_x = cx; /* root_x/y always in screen coords */ + event->root_y = cy; + event->root_x_frac = cx_frac; + event->root_y_frac = cy_frac; - events++; - if (num_valuators) { - kbp->deviceid |= MORE_EVENTS; - if (flags & POINTER_ABSOLUTE) - clipValuators(pDev, first_valuator, num_valuators, valuators); - events = getValuatorEvents(events, pDev, first_valuator, - num_valuators, valuators); - } + set_valuators(pDev, event, first_valuator, num_valuators, valuators); return num_events; } @@ -1051,13 +1153,16 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, * The DDX is responsible for allocating the event structure in the first * place via GetMaximumEventsNum(), and for freeing it. */ -_X_EXPORT int +int GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, int first_valuator, int num_valuators, int *valuators) { int num_events = 1; - deviceKeyButtonPointer *kbp; - DeviceIntPtr master; + DeviceEvent *event; + + /* refuse events from disabled devices */ + if (!pDev->enabled) + return 0; /* Sanity checks. */ if (type != ProximityIn && type != ProximityOut) @@ -1068,38 +1173,21 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, if ((pDev->valuator->mode & 1) == Relative) num_valuators = 0; - if (num_valuators) { - if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS) - num_valuators = MAX_VALUATOR_EVENTS * 6; - num_events += ((num_valuators - 1) / 6) + 1; - } - /* You fail. */ if (first_valuator < 0 || (num_valuators + first_valuator) > pDev->valuator->numAxes) return 0; - master = pDev->u.master; - if (master && master->u.lastSlave != pDev) - { - updateSlaveDeviceCoords(master, pDev); - master->u.lastSlave = pDev; - master->last.numValuators = pDev->last.numValuators; - } + events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - kbp = (deviceKeyButtonPointer *) events->event; - kbp->type = type; - kbp->deviceid = pDev->id; - kbp->detail = 0; - kbp->time = GetTimeInMillis(); + event = (DeviceEvent *) events->event; + init_event(pDev, event, GetTimeInMillis()); + event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; - if (num_valuators) { - kbp->deviceid |= MORE_EVENTS; - events++; + if (num_valuators) clipValuators(pDev, first_valuator, num_valuators, valuators); - events = getValuatorEvents(events, pDev, first_valuator, - num_valuators, valuators); - } + + set_valuators(pDev, event, first_valuator, num_valuators, valuators); return num_events; } @@ -1117,7 +1205,7 @@ PostSyntheticMotion(DeviceIntPtr pDev, int screen, unsigned long time) { - xEvent xE; + DeviceEvent ev; #ifdef PANORAMIX /* Translate back to the sprite screen since processInputProc @@ -1129,11 +1217,13 @@ PostSyntheticMotion(DeviceIntPtr pDev, } #endif - memset(&xE, 0, sizeof(xEvent)); - xE.u.u.type = MotionNotify; - xE.u.keyButtonPointer.rootX = x; - xE.u.keyButtonPointer.rootY = y; - xE.u.keyButtonPointer.time = time; + memset(&ev, 0, sizeof(DeviceEvent)); + init_event(pDev, &ev, time); + ev.root_x = x; + ev.root_y = y; + ev.type = ET_Motion; + ev.time = time; - (*pDev->public.processInputProc)(&xE, pDev, 1); + /* FIXME: MD/SD considerations? */ + (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev); } diff --git a/xorg-server/dix/globals.c b/xorg-server/dix/globals.c index 973dc43c3..c24a94fbe 100644 --- a/xorg-server/dix/globals.c +++ b/xorg-server/dix/globals.c @@ -61,7 +61,7 @@ SOFTWARE. #include "dixstruct.h" #include "os.h" -_X_EXPORT ScreenInfo screenInfo; +ScreenInfo screenInfo; KeybdCtrl defaultKeyboardControl = { DEFAULT_KEYBOARD_CLICK, DEFAULT_BELL, @@ -78,47 +78,30 @@ PtrCtrl defaultPointerControl = { DEFAULT_PTR_THRESHOLD, 0}; -_X_EXPORT ClientPtr clients[MAXCLIENTS]; -_X_EXPORT ClientPtr serverClient; -_X_EXPORT int currentMaxClients; /* current size of clients array */ -_X_EXPORT long maxBigRequestSize = MAX_BIG_REQUEST_SIZE; +ClientPtr clients[MAXCLIENTS]; +ClientPtr serverClient; +int currentMaxClients; /* current size of clients array */ +long maxBigRequestSize = MAX_BIG_REQUEST_SIZE; -_X_EXPORT WindowPtr WindowTable[MAXSCREENS]; +WindowPtr WindowTable[MAXSCREENS]; -_X_EXPORT unsigned long globalSerialNumber = 0; -_X_EXPORT unsigned long serverGeneration = 0; +unsigned long globalSerialNumber = 0; +unsigned long serverGeneration = 0; /* these next four are initialized in main.c */ -_X_EXPORT CARD32 ScreenSaverTime; +CARD32 ScreenSaverTime; CARD32 ScreenSaverInterval; -_X_EXPORT int ScreenSaverBlanking; +int ScreenSaverBlanking; int ScreenSaverAllowExposures; #ifdef DPMSExtension -# ifndef DEFAULT_STANDBY_TIME -# define DEFAULT_STANDBY_TIME DEFAULT_SCREEN_SAVER_TIME * 2 -# endif -# ifndef DEFAULT_SUSPEND_TIME -# define DEFAULT_SUSPEND_TIME DEFAULT_SCREEN_SAVER_TIME * 3 -# endif -# ifndef DEFAULT_OFF_TIME -# define DEFAULT_OFF_TIME DEFAULT_SCREEN_SAVER_TIME * 4 -# endif -# ifndef DEFAULT_DPMS_ENABLED -# define DEFAULT_DPMS_ENABLED TRUE -# endif -CARD32 defaultDPMSStandbyTime = DEFAULT_STANDBY_TIME; -CARD32 defaultDPMSSuspendTime = DEFAULT_SUSPEND_TIME; -CARD32 defaultDPMSOffTime = DEFAULT_OFF_TIME; -_X_EXPORT CARD16 DPMSPowerLevel = 0; -Bool defaultDPMSEnabled = DEFAULT_DPMS_ENABLED; -_X_EXPORT Bool DPMSEnabledSwitch = FALSE; /* these denote the DPMS command */ -_X_EXPORT Bool DPMSDisabledSwitch = FALSE; /* lind switch states */ -_X_EXPORT Bool DPMSCapableFlag = FALSE; -_X_EXPORT CARD32 DPMSStandbyTime; -_X_EXPORT CARD32 DPMSSuspendTime; -_X_EXPORT CARD32 DPMSOffTime; -_X_EXPORT Bool DPMSEnabled; +CARD16 DPMSPowerLevel = 0; +Bool DPMSDisabledSwitch = FALSE; +Bool DPMSCapableFlag = FALSE; +CARD32 DPMSStandbyTime; +CARD32 DPMSSuspendTime; +CARD32 DPMSOffTime; +Bool DPMSEnabled; #endif CARD32 defaultScreenSaverTime = DEFAULT_SCREEN_SAVER_TIME; @@ -144,13 +127,13 @@ Bool whiteRoot = FALSE; int cursorScreenDevPriv[MAXSCREENS]; -_X_EXPORT TimeStamp currentTime; -_X_EXPORT TimeStamp lastDeviceEventTime; +TimeStamp currentTime; +TimeStamp lastDeviceEventTime; -_X_EXPORT int defaultColorVisualClass = -1; -_X_EXPORT int monitorResolution = 0; +int defaultColorVisualClass = -1; +int monitorResolution = 0; -_X_EXPORT char *display; +char *display; char *ConnectionInfo; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; diff --git a/xorg-server/dix/grabs.c b/xorg-server/dix/grabs.c index b372d8f1b..4a351d647 100644 --- a/xorg-server/dix/grabs.c +++ b/xorg-server/dix/grabs.c @@ -52,13 +52,14 @@ SOFTWARE. #include <X11/X.h> #include "misc.h" -#define NEED_EVENTS #include <X11/Xproto.h> +#include <X11/extensions/XI2.h> #include "windowstr.h" #include "inputstr.h" #include "cursorstr.h" #include "dixgrabs.h" #include "xace.h" +#include "exevents.h" #define BITMASK(i) (((Mask)1) << ((i) & 31)) #define MASKIDX(i) ((i) >> 5) @@ -71,11 +72,11 @@ GrabPtr CreateGrab( int client, DeviceIntPtr device, - WindowPtr window, - Mask eventMask, - Bool ownerEvents, Bool keyboardMode, Bool pointerMode, DeviceIntPtr modDevice, - unsigned short modifiers, + WindowPtr window, + GrabType grabtype, + GrabMask *mask, + GrabParameters *param, int type, KeyCode keybut, /* key or button */ WindowPtr confineTo, @@ -83,30 +84,30 @@ CreateGrab( { GrabPtr grab; - grab = (GrabPtr)xalloc(sizeof(GrabRec)); + grab = xcalloc(1, sizeof(GrabRec)); if (!grab) return (GrabPtr)NULL; grab->resource = FakeClientID(client); grab->device = device; - grab->coreGrab = (type < LASTEvent); grab->window = window; - grab->eventMask = eventMask; + grab->eventMask = mask->core; /* same for XI */ grab->deviceMask = 0; - grab->ownerEvents = ownerEvents; - grab->keyboardMode = keyboardMode; - grab->pointerMode = pointerMode; - grab->modifiersDetail.exact = modifiers; + grab->ownerEvents = param->ownerEvents; + grab->keyboardMode = param->this_device_mode; + grab->pointerMode = param->other_devices_mode; + grab->modifiersDetail.exact = param->modifiers; grab->modifiersDetail.pMask = NULL; grab->modifierDevice = modDevice; - grab->coreMods = ((modDevice == inputInfo.keyboard) || - (modDevice == inputInfo.pointer)); grab->type = type; + grab->grabtype = grabtype; grab->detail.exact = keybut; grab->detail.pMask = NULL; grab->confineTo = confineTo; grab->cursor = cursor; - grab->genericMasks = NULL; grab->next = NULL; + + if (grabtype == GRABTYPE_XI2) + memcpy(grab->xi2mask, mask->xi2mask, sizeof(mask->xi2mask)); if (cursor) cursor->refcnt++; return grab; @@ -154,12 +155,12 @@ DeletePassiveGrab(pointer value, XID id) } static Mask * -DeleteDetailFromMask(Mask *pDetailMask, unsigned short detail) +DeleteDetailFromMask(Mask *pDetailMask, unsigned int detail) { Mask *mask; int i; - mask = (Mask *)xalloc(sizeof(Mask) * MasksPerDetailMask); + mask = xalloc(sizeof(Mask) * MasksPerDetailMask); if (mask) { if (pDetailMask) @@ -177,7 +178,7 @@ static Bool IsInGrabMask( DetailRec firstDetail, DetailRec secondDetail, - unsigned short exception) + unsigned int exception) { if (firstDetail.exact == exception) { @@ -197,9 +198,9 @@ IsInGrabMask( static Bool IdenticalExactDetails( - unsigned short firstExact, - unsigned short secondExact, - unsigned short exception) + unsigned int firstExact, + unsigned int secondExact, + unsigned int exception) { if ((firstExact == exception) || (secondExact == exception)) return FALSE; @@ -214,7 +215,7 @@ static Bool DetailSupersedesSecond( DetailRec firstDetail, DetailRec secondDetail, - unsigned short exception) + unsigned int exception) { if (IsInGrabMask(firstDetail, secondDetail, exception)) return TRUE; @@ -229,13 +230,16 @@ DetailSupersedesSecond( static Bool GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab) { + unsigned int any_modifier = (pFirstGrab->grabtype == GRABTYPE_XI2) ? + (unsigned int)XIAnyModifier : + (unsigned int)AnyModifier; if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail, pSecondGrab->modifiersDetail, - (unsigned short)AnyModifier)) + any_modifier)) return FALSE; if (DetailSupersedesSecond(pFirstGrab->detail, - pSecondGrab->detail, (unsigned short)AnyKey)) + pSecondGrab->detail, (unsigned int)AnyKey)) return TRUE; return FALSE; @@ -257,7 +261,32 @@ GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab) Bool GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice) { - if (!ignoreDevice && + unsigned int any_modifier = (pFirstGrab->grabtype == GRABTYPE_XI2) ? + (unsigned int)XIAnyModifier : + (unsigned int)AnyModifier; + + if (pFirstGrab->grabtype != pSecondGrab->grabtype) + return FALSE; + + if (pFirstGrab->grabtype == GRABTYPE_XI2) + { + if (pFirstGrab->device == inputInfo.all_devices || + pSecondGrab->device == inputInfo.all_devices) + { + /* do nothing */ + } else if (pFirstGrab->device == inputInfo.all_master_devices) + { + if (pSecondGrab->device != inputInfo.all_master_devices && + !IsMaster(pSecondGrab->device)) + return FALSE; + } else if (pSecondGrab->device == inputInfo.all_master_devices) + { + if (pFirstGrab->device != inputInfo.all_master_devices && + !IsMaster(pFirstGrab->device)) + return FALSE; + } else if (pSecondGrab->device != pFirstGrab->device) + return FALSE; + } else if (!ignoreDevice && ((pFirstGrab->device != pSecondGrab->device) || (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice))) return FALSE; @@ -270,19 +299,19 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice) return TRUE; if (DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail, - (unsigned short)AnyKey) + (unsigned int)AnyKey) && DetailSupersedesSecond(pFirstGrab->modifiersDetail, pSecondGrab->modifiersDetail, - (unsigned short)AnyModifier)) + any_modifier)) return TRUE; if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail, - (unsigned short)AnyKey) + (unsigned int)AnyKey) && DetailSupersedesSecond(pSecondGrab->modifiersDetail, pFirstGrab->modifiersDetail, - (unsigned short)AnyModifier)) + any_modifier)) return TRUE; return FALSE; @@ -291,6 +320,13 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice) static Bool GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab) { + unsigned int any_modifier = (pFirstGrab->grabtype == GRABTYPE_XI2) ? + (unsigned int)XIAnyModifier : + (unsigned int)AnyModifier; + + if (pFirstGrab->grabtype != pSecondGrab->grabtype) + return FALSE; + if (pFirstGrab->device != pSecondGrab->device || (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) || (pFirstGrab->type != pSecondGrab->type)) @@ -298,18 +334,19 @@ GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab) if (!(DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail, - (unsigned short)AnyKey) && + (unsigned int)AnyKey) && DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail, - (unsigned short)AnyKey))) + (unsigned int)AnyKey))) return FALSE; + if (!(DetailSupersedesSecond(pFirstGrab->modifiersDetail, pSecondGrab->modifiersDetail, - (unsigned short)AnyModifier) && + any_modifier) && DetailSupersedesSecond(pSecondGrab->modifiersDetail, pFirstGrab->modifiersDetail, - (unsigned short)AnyModifier))) + any_modifier))) return FALSE; return TRUE; @@ -384,6 +421,8 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab) Mask ***updates, **details; int i, ndels, nadds, nups; Bool ok; + unsigned int any_modifier; + unsigned int any_key; #define UPDATE(mask,exact) \ if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \ @@ -396,10 +435,10 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab) i++; if (!i) return TRUE; - deletes = (GrabPtr *)xalloc(i * sizeof(GrabPtr)); - adds = (GrabPtr *)xalloc(i * sizeof(GrabPtr)); - updates = (Mask ***)xalloc(i * sizeof(Mask **)); - details = (Mask **)xalloc(i * sizeof(Mask *)); + deletes = xalloc(i * sizeof(GrabPtr)); + adds = xalloc(i * sizeof(GrabPtr)); + updates = xalloc(i * sizeof(Mask **)); + details = xalloc(i * sizeof(Mask *)); if (!deletes || !adds || !updates || !details) { if (details) xfree(details); @@ -408,6 +447,11 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab) if (deletes) xfree(deletes); return FALSE; } + + any_modifier = (pMinuendGrab->grabtype == GRABTYPE_XI2) ? + (unsigned int)XIAnyModifier : (unsigned int)AnyModifier; + any_key = (pMinuendGrab->grabtype == GRABTYPE_XI2) ? + (unsigned int)XIAnyKeycode : (unsigned int)AnyKey; ndels = nadds = nups = 0; ok = TRUE; for (grab = wPassiveGrabs(pMinuendGrab->window); @@ -415,37 +459,43 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab) grab = grab->next) { if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) || - !GrabMatchesSecond(grab, pMinuendGrab, (grab->coreGrab))) + !GrabMatchesSecond(grab, pMinuendGrab, + (grab->grabtype == GRABTYPE_CORE))) continue; if (GrabSupersedesSecond(pMinuendGrab, grab)) { deletes[ndels++] = grab; } - else if ((grab->detail.exact == AnyKey) - && (grab->modifiersDetail.exact != AnyModifier)) + else if ((grab->detail.exact == any_key) + && (grab->modifiersDetail.exact != any_modifier)) { UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); } - else if ((grab->modifiersDetail.exact == AnyModifier) - && (grab->detail.exact != AnyKey)) + else if ((grab->modifiersDetail.exact == any_modifier) + && (grab->detail.exact != any_key)) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); } - else if ((pMinuendGrab->detail.exact != AnyKey) - && (pMinuendGrab->modifiersDetail.exact != AnyModifier)) + else if ((pMinuendGrab->detail.exact != any_key) + && (pMinuendGrab->modifiersDetail.exact != any_modifier)) { GrabPtr pNewGrab; + GrabParameters param; UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); + memset(¶m, 0, sizeof(param)); + param.ownerEvents = grab->ownerEvents; + param.this_device_mode = grab->keyboardMode; + param.other_devices_mode = grab->pointerMode; + param.modifiers = any_modifier; + pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device, - grab->window, (Mask)grab->eventMask, - (Bool)grab->ownerEvents, - (Bool)grab->keyboardMode, - (Bool)grab->pointerMode, - grab->modifierDevice, - AnyModifier, (int)grab->type, + grab->modifierDevice, grab->window, + grab->grabtype, + (GrabMask*)&grab->eventMask, + ¶m, (int)grab->type, pMinuendGrab->detail.exact, grab->confineTo, grab->cursor); if (!pNewGrab) @@ -466,7 +516,7 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab) else adds[nadds++] = pNewGrab; } - else if (pMinuendGrab->detail.exact == AnyKey) + else if (pMinuendGrab->detail.exact == any_key) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); diff --git a/xorg-server/dix/inpututils.c b/xorg-server/dix/inpututils.c new file mode 100644 index 000000000..4848c1bc2 --- /dev/null +++ b/xorg-server/dix/inpututils.c @@ -0,0 +1,334 @@ +/* + * Copyright © 2008 Daniel Stone + * + * 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: Daniel Stone <daniel@fooishbar.org> + */ + +#ifdef HAVE_DIX_CONFIG_H +#include "dix-config.h" +#endif + +#include "exevents.h" +#include "exglobals.h" +#include "misc.h" +#include "input.h" +#include "inputstr.h" +#include "xace.h" +#include "xkbsrv.h" +#include "xkbstr.h" + +/* Check if a button map change is okay with the device. + * Returns -1 for BadValue, as it collides with MappingBusy. */ +static int +check_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, CARD32 *errval_out, + ClientPtr client) +{ + int i, ret; + + if (!dev || !dev->button) + { + client->errorValue = (dev) ? dev->id : 0; + return BadDevice; + } + + ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); + if (ret != Success) + { + client->errorValue = dev->id; + return ret; + } + + for (i = 0; i < len; i++) { + if (dev->button->map[i + 1] != map[i] && dev->button->down[i + 1]) + return MappingBusy; + } + + return Success; +} + +static void +do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) +{ + int i; + xEvent core_mn; + deviceMappingNotify xi_mn; + + /* The map in ButtonClassRec refers to button numbers, whereas the + * protocol is zero-indexed. Sigh. */ + memcpy(&(dev->button->map[1]), map, len); + + core_mn.u.u.type = MappingNotify; + core_mn.u.mappingNotify.request = MappingPointer; + + /* 0 is the server client. */ + for (i = 1; i < currentMaxClients; i++) { + /* Don't send irrelevant events to naïve clients. */ + if (!clients[i] || clients[i]->clientState != ClientStateRunning) + continue; + + if (!XIShouldNotify(clients[i], dev)) + continue; + + core_mn.u.u.sequenceNumber = clients[i]->sequence; + WriteEventsToClient(clients[i], 1, &core_mn); + } + + xi_mn.type = DeviceMappingNotify; + xi_mn.request = MappingPointer; + xi_mn.deviceid = dev->id; + xi_mn.time = GetTimeInMillis(); + + SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1); +} + +/* + * Does what it says on the box, both for core and Xi. + * + * Faithfully reports any errors encountered while trying to apply the map + * to the requested device, faithfully ignores any errors encountered while + * trying to apply the map to its master/slaves. + */ +int +ApplyPointerMapping(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) +{ + int ret; + + /* If we can't perform the change on the requested device, bail out. */ + ret = check_butmap_change(dev, map, len, &client->errorValue, client); + if (ret != Success) + return ret; + do_butmap_change(dev, map, len, client); + + return Success; +} + +/* Check if a modifier map change is okay with the device. + * Returns -1 for BadValue, as it collides with MappingBusy; this particular + * caveat can be removed with LegalModifier, as we have no other reason to + * set MappingFailed. Sigh. */ +static int +check_modmap_change(ClientPtr client, DeviceIntPtr dev, KeyCode *modmap) +{ + int ret, i; + XkbDescPtr xkb; + + ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); + if (ret != Success) + return ret; + + if (!dev->key) + return BadMatch; + xkb = dev->key->xkbInfo->desc; + + for (i = 0; i < MAP_LENGTH; i++) { + if (!modmap[i]) + continue; + + /* Check that all the new modifiers fall within the advertised + * keycode range. */ + if (i < xkb->min_key_code || i > xkb->max_key_code) { + client->errorValue = i; + return -1; + } + + /* Make sure the mapping is okay with the DDX. */ + if (!LegalModifier(i, dev)) { + client->errorValue = i; + return MappingFailed; + } + + /* None of the new modifiers may be down while we change the + * map. */ + if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) { + client->errorValue = i; + return MappingBusy; + } + } + + /* None of the old modifiers may be down while we change the map, + * either. */ + for (i = xkb->min_key_code; i < xkb->max_key_code; i++) { + if (!xkb->map->modmap[i]) + continue; + if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) { + client->errorValue = i; + return MappingBusy; + } + } + + return Success; +} + +static int +check_modmap_change_slave(ClientPtr client, DeviceIntPtr master, + DeviceIntPtr slave, CARD8 *modmap) +{ + XkbDescPtr master_xkb, slave_xkb; + int i, j; + + if (!slave->key || !master->key) + return 0; + + master_xkb = master->key->xkbInfo->desc; + slave_xkb = slave->key->xkbInfo->desc; + + /* Ignore devices with a clearly different keymap. */ + if (slave_xkb->min_key_code != master_xkb->min_key_code || + slave_xkb->max_key_code != master_xkb->max_key_code) + return 0; + + for (i = 0; i < MAP_LENGTH; i++) { + if (!modmap[i]) + continue; + + /* If we have different symbols for any modifier on an + * extended keyboard, ignore the whole remap request. */ + for (j = 0; + j < XkbKeyNumSyms(slave_xkb, i) && + j < XkbKeyNumSyms(master_xkb, i); + j++) + if (XkbKeySymsPtr(slave_xkb, i)[j] != XkbKeySymsPtr(master_xkb, i)[j]) + return 0; + } + + if (check_modmap_change(client, slave, modmap) != Success) + return 0; + + return 1; +} + +/* Actually change the modifier map, and send notifications. Cannot fail. */ +static void +do_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap) +{ + XkbApplyMappingChange(dev, NULL, 0, 0, modmap, serverClient); +} + +/* Rebuild modmap (key -> mod) from map (mod -> key). */ +static int build_modmap_from_modkeymap(CARD8 *modmap, KeyCode *modkeymap, + int max_keys_per_mod) +{ + int i, len = max_keys_per_mod * 8; + + memset(modmap, 0, MAP_LENGTH); + + for (i = 0; i < len; i++) { + if (!modkeymap[i]) + continue; + + if (modkeymap[i] >= MAP_LENGTH) + return BadValue; + + if (modmap[modkeymap[i]]) + return BadValue; + + modmap[modkeymap[i]] = 1 << (i / max_keys_per_mod); + } + + return Success; +} + +int +change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, + int max_keys_per_mod) +{ + int ret; + CARD8 modmap[MAP_LENGTH]; + DeviceIntPtr tmp; + + ret = build_modmap_from_modkeymap(modmap, modkeymap, max_keys_per_mod); + if (ret != Success) + return ret; + + /* If we can't perform the change on the requested device, bail out. */ + ret = check_modmap_change(client, dev, modmap); + if (ret != Success) + return ret; + do_modmap_change(client, dev, modmap); + + /* Change any attached masters/slaves. */ + if (IsMaster(dev)) { + for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { + if (!IsMaster(tmp) && tmp->u.master == dev) + if (check_modmap_change_slave(client, dev, tmp, modmap)) + do_modmap_change(client, tmp, modmap); + } + } + else if (dev->u.master && dev->u.master->u.lastSlave == dev) { + /* If this fails, expect the results to be weird. */ + if (check_modmap_change(client, dev->u.master, modmap)) + do_modmap_change(client, dev->u.master, modmap); + } + + return Success; +} + +int generate_modkeymap(ClientPtr client, DeviceIntPtr dev, + KeyCode **modkeymap_out, int *max_keys_per_mod_out) +{ + CARD8 keys_per_mod[8]; + int max_keys_per_mod; + KeyCode *modkeymap; + int i, j, ret; + + ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); + if (ret != Success) + return ret; + + if (!dev->key) + return BadMatch; + + /* Count the number of keys per modifier to determine how wide we + * should make the map. */ + max_keys_per_mod = 0; + for (i = 0; i < 8; i++) + keys_per_mod[i] = 0; + for (i = 8; i < MAP_LENGTH; i++) { + for (j = 0; j < 8; j++) { + if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) { + if (++keys_per_mod[j] > max_keys_per_mod) + max_keys_per_mod = keys_per_mod[j]; + } + } + } + + modkeymap = xcalloc(max_keys_per_mod * 8, sizeof(KeyCode)); + if (!modkeymap) + return BadAlloc; + + for (i = 0; i < 8; i++) + keys_per_mod[i] = 0; + + for (i = 8; i < MAP_LENGTH; i++) { + for (j = 0; j < 8; j++) { + if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) { + modkeymap[(j * max_keys_per_mod) + keys_per_mod[j]] = i; + keys_per_mod[j]++; + } + } + } + + *max_keys_per_mod_out = max_keys_per_mod; + *modkeymap_out = modkeymap; + + return Success; +} diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c index c4d362a36..e49d6cd11 100644 --- a/xorg-server/dix/main.c +++ b/xorg-server/dix/main.c @@ -74,14 +74,15 @@ Equipment Corporation. ******************************************************************/ -#define NEED_EVENTS #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#include <version-config.h> #endif #include <X11/X.h> #include <X11/Xos.h> /* for unistd.h */ #include <X11/Xproto.h> +#include <pixman.h> #include "scrnintstr.h" #include "misc.h" #include "os.h" @@ -111,127 +112,13 @@ Equipment Corporation. #endif #ifdef DPMSExtension -#define DPMS_SERVER -#include <X11/extensions/dpms.h> +#include <X11/extensions/dpmsconst.h> #include "dpmsproc.h" #endif extern void Dispatch(void); -xConnSetupPrefix connSetupPrefix; - -extern FontPtr defaultFont; - extern void InitProcVectors(void); -extern Bool CreateGCperDepthArray(void); - -#ifndef PANORAMIX -static -#endif -Bool CreateConnectionBlock(void); - -_X_EXPORT PaddingInfo PixmapWidthPaddingInfo[33]; - -int connBlockScreenStart; - -_X_EXPORT void -NotImplemented(xEvent *from, xEvent *to) -{ - FatalError("Not implemented"); -} - -/* - * Dummy entry for ReplySwapVector[] - */ - -void -ReplyNotSwappd( - ClientPtr pClient , - int size , - void * pbuf - ) -{ - FatalError("Not implemented"); -} - -/* - * This array encodes the answer to the question "what is the log base 2 - * of the number of pixels that fit in a scanline pad unit?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int answer[6][4] = { - /* pad pad pad pad*/ - /* 8 16 32 64 */ - - { 3, 4, 5 , 6 }, /* 1 bit per pixel */ - { 1, 2, 3 , 4 }, /* 4 bits per pixel */ - { 0, 1, 2 , 3 }, /* 8 bits per pixel */ - { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ - { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ - { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ -}; - -/* - * This array gives the answer to the question "what is the first index for - * the answer array above given the number of bits per pixel?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int indexForBitsPerPixel[ 33 ] = { - ~0, 0, ~0, ~0, /* 1 bit per pixel */ - 1, ~0, ~0, ~0, /* 4 bits per pixel */ - 2, ~0, ~0, ~0, /* 8 bits per pixel */ - ~0,~0, ~0, ~0, - 3, ~0, ~0, ~0, /* 16 bits per pixel */ - ~0,~0, ~0, ~0, - 4, ~0, ~0, ~0, /* 24 bits per pixel */ - ~0,~0, ~0, ~0, - 5 /* 32 bits per pixel */ -}; - -/* - * This array gives the bytesperPixel value for cases where the number - * of bits per pixel is a multiple of 8 but not a power of 2. - */ -static int answerBytesPerPixel[ 33 ] = { - ~0, 0, ~0, ~0, /* 1 bit per pixel */ - 0, ~0, ~0, ~0, /* 4 bits per pixel */ - 0, ~0, ~0, ~0, /* 8 bits per pixel */ - ~0,~0, ~0, ~0, - 0, ~0, ~0, ~0, /* 16 bits per pixel */ - ~0,~0, ~0, ~0, - 3, ~0, ~0, ~0, /* 24 bits per pixel */ - ~0,~0, ~0, ~0, - 0 /* 32 bits per pixel */ -}; - -/* - * This array gives the answer to the question "what is the second index for - * the answer array above given the number of bits per scanline pad unit?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int indexForScanlinePad[ 65 ] = { - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 3 /* 64 bits per scanline pad unit */ -}; - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif #ifdef XQUARTZ #include <pthread.h> @@ -253,6 +140,8 @@ int main(int argc, char *argv[], char *envp[]) InitRegions(); + pixman_disable_out_of_bounds_workaround(); + CheckUserParameters(argc, argv, envp); CheckUserAuthorization(); @@ -271,10 +160,10 @@ int main(int argc, char *argv[], char *envp[]) ScreenSaverBlanking = defaultScreenSaverBlanking; ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; #ifdef DPMSExtension - DPMSStandbyTime = defaultDPMSStandbyTime; - DPMSSuspendTime = defaultDPMSSuspendTime; - DPMSOffTime = defaultDPMSOffTime; - DPMSEnabled = defaultDPMSEnabled; + DPMSStandbyTime = DEFAULT_SCREEN_SAVER_TIME; + DPMSSuspendTime = DEFAULT_SCREEN_SAVER_TIME; + DPMSOffTime = DEFAULT_SCREEN_SAVER_TIME; + DPMSEnabled = TRUE; DPMSPowerLevel = 0; #endif InitBlockAndWakeupHandlers(); @@ -287,7 +176,7 @@ int main(int argc, char *argv[], char *envp[]) InitProcVectors(); for (i=1; i<MAXCLIENTS; i++) clients[i] = NullClient; - serverClient = (ClientPtr)xalloc(sizeof(ClientRec)); + serverClient = xalloc(sizeof(ClientRec)); if (!serverClient) FatalError("couldn't create server client"); InitClient(serverClient, 0, (pointer)NULL); @@ -364,7 +253,6 @@ int main(int argc, char *argv[], char *envp[]) for (i = 0; i < screenInfo.numScreens; i++) InitRootWindow(WindowTable[i]); - DefineInitialRootWindow(WindowTable[0]); InitCoreDevices(); InitInput(argc, argv); @@ -458,254 +346,3 @@ int main(int argc, char *argv[], char *envp[]) return(0); } -static int VendorRelease = XORG_VERSION_CURRENT; -static char *VendorString = "HMCA" ; - -void -SetVendorRelease(int release) -{ - VendorRelease = release; -} - -void -SetVendorString(char *string) -{ - VendorString = string; -} - -static const int padlength[4] = {0, 3, 2, 1}; - -#ifndef PANORAMIX -static -#endif -Bool -CreateConnectionBlock(void) -{ - xConnSetup setup; - xWindowRoot root; - xDepth depth; - xVisualType visual; - xPixmapFormat format; - unsigned long vid; - int i, j, k, - lenofblock, - sizesofar = 0; - char *pBuf; - - - /* Leave off the ridBase and ridMask, these must be sent with - connection */ - - setup.release = VendorRelease; - /* - * per-server image and bitmap parameters are defined in Xmd.h - */ - setup.imageByteOrder = screenInfo.imageByteOrder; - - setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; - setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; - - setup.bitmapBitOrder = screenInfo.bitmapBitOrder; - setup.motionBufferSize = NumMotionEvents(); - setup.numRoots = screenInfo.numScreens; - setup.nbytesVendor = strlen(VendorString); - setup.numFormats = screenInfo.numPixmapFormats; - setup.maxRequestSize = MAX_REQUEST_SIZE; - QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); - - lenofblock = sizeof(xConnSetup) + - ((setup.nbytesVendor + 3) & ~3) + - (setup.numFormats * sizeof(xPixmapFormat)) + - (setup.numRoots * sizeof(xWindowRoot)); - ConnectionInfo = (char *) xalloc(lenofblock); - if (!ConnectionInfo) - return FALSE; - - memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup)); - sizesofar = sizeof(xConnSetup); - pBuf = ConnectionInfo + sizeof(xConnSetup); - - memmove(pBuf, VendorString, (int)setup.nbytesVendor); - sizesofar += setup.nbytesVendor; - pBuf += setup.nbytesVendor; - i = padlength[setup.nbytesVendor & 3]; - sizesofar += i; - while (--i >= 0) - *pBuf++ = 0; - - for (i=0; i<screenInfo.numPixmapFormats; i++) - { - format.depth = screenInfo.formats[i].depth; - format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; - format.scanLinePad = screenInfo.formats[i].scanlinePad; - memmove(pBuf, (char *)&format, sizeof(xPixmapFormat)); - pBuf += sizeof(xPixmapFormat); - sizesofar += sizeof(xPixmapFormat); - } - - connBlockScreenStart = sizesofar; - for (i=0; i<screenInfo.numScreens; i++) - { - ScreenPtr pScreen; - DepthPtr pDepth; - VisualPtr pVisual; - - pScreen = screenInfo.screens[i]; - root.windowId = WindowTable[i]->drawable.id; - root.defaultColormap = pScreen->defColormap; - root.whitePixel = pScreen->whitePixel; - root.blackPixel = pScreen->blackPixel; - root.currentInputMask = 0; /* filled in when sent */ - root.pixWidth = pScreen->width; - root.pixHeight = pScreen->height; - root.mmWidth = pScreen->mmWidth; - root.mmHeight = pScreen->mmHeight; - root.minInstalledMaps = pScreen->minInstalledCmaps; - root.maxInstalledMaps = pScreen->maxInstalledCmaps; - root.rootVisualID = pScreen->rootVisual; - root.backingStore = pScreen->backingStoreSupport; - root.saveUnders = FALSE; - root.rootDepth = pScreen->rootDepth; - root.nDepths = pScreen->numDepths; - memmove(pBuf, (char *)&root, sizeof(xWindowRoot)); - sizesofar += sizeof(xWindowRoot); - pBuf += sizeof(xWindowRoot); - - pDepth = pScreen->allowedDepths; - for(j = 0; j < pScreen->numDepths; j++, pDepth++) - { - lenofblock += sizeof(xDepth) + - (pDepth->numVids * sizeof(xVisualType)); - pBuf = (char *)xrealloc(ConnectionInfo, lenofblock); - if (!pBuf) - { - xfree(ConnectionInfo); - return FALSE; - } - ConnectionInfo = pBuf; - pBuf += sizesofar; - depth.depth = pDepth->depth; - depth.nVisuals = pDepth->numVids; - memmove(pBuf, (char *)&depth, sizeof(xDepth)); - pBuf += sizeof(xDepth); - sizesofar += sizeof(xDepth); - for(k = 0; k < pDepth->numVids; k++) - { - vid = pDepth->vids[k]; - for (pVisual = pScreen->visuals; - pVisual->vid != vid; - pVisual++) - ; - visual.visualID = vid; - visual.class = pVisual->class; - visual.bitsPerRGB = pVisual->bitsPerRGBValue; - visual.colormapEntries = pVisual->ColormapEntries; - visual.redMask = pVisual->redMask; - visual.greenMask = pVisual->greenMask; - visual.blueMask = pVisual->blueMask; - memmove(pBuf, (char *)&visual, sizeof(xVisualType)); - pBuf += sizeof(xVisualType); - sizesofar += sizeof(xVisualType); - } - } - } - connSetupPrefix.success = xTrue; - connSetupPrefix.length = lenofblock/4; - connSetupPrefix.majorVersion = X_PROTOCOL; - connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; - return TRUE; -} - -/* - grow the array of screenRecs if necessary. - call the device-supplied initialization procedure -with its screen number, a pointer to its ScreenRec, argc, and argv. - return the number of successfully installed screens. - -*/ - -int -AddScreen( - Bool (* pfnInit)( - int /*index*/, - ScreenPtr /*pScreen*/, - int /*argc*/, - char ** /*argv*/ - ), - int argc, - char **argv) -{ - - int i; - int scanlinepad, format, depth, bitsPerPixel, j, k; - ScreenPtr pScreen; - - i = screenInfo.numScreens; - if (i == MAXSCREENS) - return -1; - - pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec)); - if (!pScreen) - return -1; - - pScreen->devPrivates = NULL; - pScreen->myNum = i; - pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8); - pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ - pScreen->CreateScreenResources = 0; - - /* - * This loop gets run once for every Screen that gets added, - * but thats ok. If the ddx layer initializes the formats - * one at a time calling AddScreen() after each, then each - * iteration will make it a little more accurate. Worst case - * we do this loop N * numPixmapFormats where N is # of screens. - * Anyway, this must be called after InitOutput and before the - * screen init routine is called. - */ - for (format=0; format<screenInfo.numPixmapFormats; format++) - { - depth = screenInfo.formats[format].depth; - bitsPerPixel = screenInfo.formats[format].bitsPerPixel; - scanlinepad = screenInfo.formats[format].scanlinePad; - j = indexForBitsPerPixel[ bitsPerPixel ]; - k = indexForScanlinePad[ scanlinepad ]; - PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k]; - PixmapWidthPaddingInfo[ depth ].padRoundUp = - (scanlinepad/bitsPerPixel) - 1; - j = indexForBitsPerPixel[ 8 ]; /* bits per byte */ - PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k]; - PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel; - if (answerBytesPerPixel[bitsPerPixel]) - { - PixmapWidthPaddingInfo[ depth ].notPower2 = 1; - PixmapWidthPaddingInfo[ depth ].bytesPerPixel = - answerBytesPerPixel[bitsPerPixel]; - } - else - { - PixmapWidthPaddingInfo[ depth ].notPower2 = 0; - } - } - - /* This is where screen specific stuff gets initialized. Load the - screen structure, call the hardware, whatever. - This is also where the default colormap should be allocated and - also pixel values for blackPixel, whitePixel, and the cursor - Note that InitScreen is NOT allowed to modify argc, argv, or - any of the strings pointed to by argv. They may be passed to - multiple screens. - */ - pScreen->rgf = ~0L; /* there are no scratch GCs yet*/ - WindowTable[i] = NullWindow; - screenInfo.screens[i] = pScreen; - screenInfo.numScreens++; - if (!(*pfnInit)(i, pScreen, argc, argv)) - { - dixFreePrivates(pScreen->devPrivates); - xfree(pScreen); - screenInfo.numScreens--; - return -1; - } - return i; -} diff --git a/xorg-server/dix/makefile b/xorg-server/dix/makefile index f15ccd91a..4abd48a32 100644 --- a/xorg-server/dix/makefile +++ b/xorg-server/dix/makefile @@ -13,6 +13,7 @@ CSRCS=\ dixutils.c \
enterleave.c \
events.c \
+ eventconvert.c \
extension.c \
ffs.c \
gc.c \
@@ -21,6 +22,7 @@ CSRCS=\ glyphcurs.c \
grabs.c \
initatoms.c \
+ inpututils.c \
main.c \
pixmap.c \
privates.c \
diff --git a/xorg-server/dix/pixmap.c b/xorg-server/dix/pixmap.c index 82e388cf3..10ec02a78 100644 --- a/xorg-server/dix/pixmap.c +++ b/xorg-server/dix/pixmap.c @@ -49,7 +49,7 @@ from The Open Group. /* callable by ddx */ -_X_EXPORT PixmapPtr +PixmapPtr GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) { @@ -72,7 +72,7 @@ GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth, /* callable by ddx */ -_X_EXPORT void +void FreeScratchPixmapHeader(PixmapPtr pPixmap) { if (pPixmap) @@ -105,7 +105,7 @@ FreeScratchPixmapsForScreen(int scrnum) /* callable by ddx */ -_X_EXPORT PixmapPtr +PixmapPtr AllocatePixmap(ScreenPtr pScreen, int pixDataSize) { PixmapPtr pPixmap; @@ -113,7 +113,7 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize) if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize) return NullPixmap; - pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize); + pPixmap = xalloc(pScreen->totalPixmapSize + pixDataSize); if (!pPixmap) return NullPixmap; diff --git a/xorg-server/dix/privates.c b/xorg-server/dix/privates.c index ca03317bf..3a2deb85c 100644 --- a/xorg-server/dix/privates.c +++ b/xorg-server/dix/privates.c @@ -84,7 +84,7 @@ privateExists(PrivateRec **privates, const DevPrivateKey key) /* * Request pre-allocated space. */ -_X_EXPORT int +int dixRequestPrivate(const DevPrivateKey key, unsigned size) { PrivateDescRec *item = findItem(key); @@ -98,7 +98,7 @@ dixRequestPrivate(const DevPrivateKey key, unsigned size) /* * Allocate a private and attach it to an existing object. */ -_X_EXPORT pointer * +pointer * dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key) { PrivateDescRec *item = findItem(key); @@ -154,7 +154,7 @@ dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key) /* * Look up a private pointer. */ -_X_EXPORT pointer +pointer dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key) { pointer *ptr; @@ -169,7 +169,7 @@ dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key) /* * Look up the address of a private pointer. */ -_X_EXPORT pointer * +pointer * dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key) { if (privateExists(privates, key)) @@ -181,7 +181,7 @@ dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key) /* * Set a private pointer. */ -_X_EXPORT int +int dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val) { top: @@ -198,7 +198,7 @@ dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val) /* * Called to free privates at object deletion time. */ -_X_EXPORT void +void dixFreePrivates(PrivateRec *privates) { int i; @@ -223,7 +223,7 @@ dixFreePrivates(PrivateRec *privates) /* * Callback registration */ -_X_EXPORT int +int dixRegisterPrivateInitFunc(const DevPrivateKey key, CallbackProcPtr callback, pointer data) { @@ -234,7 +234,7 @@ dixRegisterPrivateInitFunc(const DevPrivateKey key, return AddCallback(&item->initfuncs, callback, data); } -_X_EXPORT int +int dixRegisterPrivateDeleteFunc(const DevPrivateKey key, CallbackProcPtr callback, pointer data) { @@ -265,7 +265,7 @@ static int offsetsSize = 0; /* * Specify where the devPrivates field is located in a structure type */ -_X_EXPORT int +int dixRegisterPrivateOffset(RESTYPE type, int offset) { type = type & TypeMask; @@ -287,7 +287,7 @@ dixRegisterPrivateOffset(RESTYPE type, int offset) return TRUE; } -_X_EXPORT int +int dixLookupPrivateOffset(RESTYPE type) { type = type & TypeMask; @@ -312,7 +312,7 @@ dixResetPrivates(void) if (offsets) xfree(offsets); offsetsSize = sizeof(offsetDefaults); - offsets = (int *)xalloc(offsetsSize); + offsets = xalloc(offsetsSize); offsetsSize /= sizeof(int); if (!offsets) return FALSE; diff --git a/xorg-server/dix/property.c b/xorg-server/dix/property.c index 7149f7c8c..9ec5dc6ae 100644 --- a/xorg-server/dix/property.c +++ b/xorg-server/dix/property.c @@ -50,8 +50,6 @@ SOFTWARE. #endif #include <X11/X.h> -#define NEED_REPLIES -#define NEED_EVENTS #include <X11/Xproto.h> #include "windowstr.h" #include "propertyst.h" @@ -90,7 +88,7 @@ PrintPropertys(WindowPtr pWin) } #endif -_X_EXPORT int +int dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, ClientPtr client, Mask access_mode) { @@ -113,6 +111,7 @@ deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom) { xEvent event; + memset(&event, 0, sizeof(xEvent)); event.u.u.type = PropertyNotify; event.u.property.window = pWin->drawable.id; event.u.property.state = state; @@ -138,8 +137,8 @@ ProcRotateProperties(ClientPtr client) return rc; atoms = (Atom *) & stuff[1]; - props = (PropertyPtr *)xalloc(stuff->nAtoms * sizeof(PropertyPtr)); - saved = (PropertyPtr)xalloc(stuff->nAtoms * sizeof(PropertyRec)); + props = xalloc(stuff->nAtoms * sizeof(PropertyPtr)); + saved = xalloc(stuff->nAtoms * sizeof(PropertyRec)); if (!props || !saved) { rc = BadAlloc; goto out; @@ -219,7 +218,7 @@ ProcChangeProperty(ClientPtr client) return BadValue; } len = stuff->nUnits; - if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2)) + if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) return BadLength; sizeInBytes = format>>3; totalSize = len * sizeInBytes; @@ -248,14 +247,15 @@ ProcChangeProperty(ClientPtr client) return client->noClientException; } -_X_EXPORT int +int dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, Atom type, int format, int mode, unsigned long len, pointer value, Bool sendevent) { PropertyPtr pProp; + PropertyRec savedProp; int sizeInBytes, totalSize, rc; - pointer data; + unsigned char *data; Mask access_mode; sizeInBytes = format>>3; @@ -269,21 +269,20 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, { if (!pWin->optional && !MakeWindowOptional (pWin)) return(BadAlloc); - pProp = (PropertyPtr)xalloc(sizeof(PropertyRec)); + pProp = xalloc(sizeof(PropertyRec)); if (!pProp) return(BadAlloc); - data = (pointer)xalloc(totalSize); + data = xalloc(totalSize); if (!data && len) { xfree(pProp); return(BadAlloc); } + memcpy(data, value, totalSize); pProp->propertyName = property; pProp->type = type; pProp->format = format; pProp->data = data; - if (len) - memmove((char *)data, (char *)value, totalSize); pProp->size = len; pProp->devPrivates = NULL; rc = XaceHookPropertyAccess(pClient, pWin, &pProp, @@ -308,17 +307,17 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, return(BadMatch); if ((pProp->type != type) && (mode != PropModeReplace)) return(BadMatch); + + /* save the old values for later */ + savedProp = *pProp; + if (mode == PropModeReplace) { - if (totalSize != pProp->size * (pProp->format >> 3)) - { - data = (pointer)xrealloc(pProp->data, totalSize); - if (!data && len) - return(BadAlloc); - pProp->data = data; - } - if (len) - memmove((char *)pProp->data, (char *)value, totalSize); + data = xalloc(totalSize); + if (!data && len) + return(BadAlloc); + memcpy(data, value, totalSize); + pProp->data = data; pProp->size = len; pProp->type = type; pProp->format = format; @@ -329,28 +328,40 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, } else if (mode == PropModeAppend) { - data = (pointer)xrealloc(pProp->data, - sizeInBytes * (len + pProp->size)); + data = xalloc((pProp->size + len) * sizeInBytes); if (!data) return(BadAlloc); + memcpy(data, pProp->data, pProp->size * sizeInBytes); + memcpy(data + pProp->size * sizeInBytes, value, totalSize); pProp->data = data; - memmove(&((char *)data)[pProp->size * sizeInBytes], - (char *)value, - totalSize); pProp->size += len; } else if (mode == PropModePrepend) { - data = (pointer)xalloc(sizeInBytes * (len + pProp->size)); + data = xalloc(sizeInBytes * (len + pProp->size)); if (!data) return(BadAlloc); - memmove(&((char *)data)[totalSize], (char *)pProp->data, - (int)(pProp->size * sizeInBytes)); - memmove((char *)data, (char *)value, totalSize); - xfree(pProp->data); + memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); + memcpy(data, value, totalSize); pProp->data = data; pProp->size += len; } + + /* Allow security modules to check the new content */ + access_mode |= DixPostAccess; + rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); + if (rc == Success) + { + if (savedProp.data != pProp->data) + xfree(savedProp.data); + } + else + { + if (savedProp.data != pProp->data) + xfree(pProp->data); + *pProp = savedProp; + return rc; + } } else return rc; @@ -361,7 +372,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, return(Success); } -_X_EXPORT int +int ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, int mode, unsigned long len, pointer value, Bool sendevent) @@ -463,7 +474,7 @@ ProcGetProperty(ClientPtr client) } rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); if (rc != Success) - return rc; + return (rc == BadMatch) ? BadWindow : rc; if (!ValidAtom(stuff->property)) { @@ -481,6 +492,7 @@ ProcGetProperty(ClientPtr client) return(BadAtom); } + memset(&reply, 0, sizeof(xGetPropertyReply)); reply.type = X_Reply; reply.sequenceNumber = client->sequence; @@ -525,7 +537,7 @@ ProcGetProperty(ClientPtr client) reply.bytesAfter = n - (ind + len); reply.format = pProp->format; - reply.length = (len + 3) >> 2; + reply.length = bytes_to_int32(len); reply.nItems = len / (pProp->format / 8 ); reply.propertyType = pProp->type; @@ -583,7 +595,7 @@ ProcListProperties(ClientPtr client) for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) numProps++; - if (numProps && !(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom)))) + if (numProps && !(pAtoms = xalloc(numProps * sizeof(Atom)))) return BadAlloc; numProps = 0; @@ -599,7 +611,7 @@ ProcListProperties(ClientPtr client) xlpr.type = X_Reply; xlpr.nProperties = numProps; - xlpr.length = (numProps * sizeof(Atom)) >> 2; + xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); xlpr.sequenceNumber = client->sequence; WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); if (numProps) diff --git a/xorg-server/dix/protocol.txt b/xorg-server/dix/protocol.txt index 364f13e31..8e152edaa 100644 --- a/xorg-server/dix/protocol.txt +++ b/xorg-server/dix/protocol.txt @@ -116,6 +116,14 @@ R004 DPMS:Enable R005 DPMS:Disable R006 DPMS:ForceLevel R007 DPMS:Info +R000 DRI2:QueryVersion +R001 DRI2:Connect +R002 DRI2:Authenticate +R003 DRI2:CreateDrawable +R004 DRI2:DestroyDrawable +R005 DRI2:GetBuffers +R006 DRI2:CopyRegion +R007 DRI2:GetBuffersWithFormat R000 Extended-Visual-Information:QueryVersion R001 Extended-Visual-Information:GetVisualInfo R000 FontCache:QueryVersion @@ -590,6 +598,7 @@ V031 X11:SelectionNotify V032 X11:ColormapNotify V033 X11:ClientMessage V034 X11:MappingNotify +V035 X11:GenericEvent E000 X11:Success E001 X11:BadRequest E002 X11:BadValue @@ -948,6 +957,27 @@ R036 XInputExtension:ListDeviceProperties R037 XInputExtension:ChangeDeviceProperty R038 XInputExtension:DeleteDeviceProperty R039 XInputExtension:GetDeviceProperty +R040 XInputExtension:QueryPointer +R041 XInputExtension:WarpPointer +R042 XInputExtension:ChangeCursor +R043 XInputExtension:ChangeHierarchy +R044 XInputExtension:SetClientPointer +R045 XInputExtension:GetClientPointer +R046 XInputExtension:SelectEvents +R047 XInputExtension:QueryVersion +R048 XInputExtension:QueryDevice +R049 XInputExtension:SetFocus +R050 XInputExtension:GetFocus +R051 XInputExtension:GrabDevice +R052 XInputExtension:UngrabDevice +R053 XInputExtension:AllowEvents +R054 XInputExtension:PassiveGrabDevice +R055 XInputExtension:PassiveUngrabDevice +R056 XInputExtension:ListProperties +R057 XInputExtension:ChangeProperty +R058 XInputExtension:DeleteProperty +R059 XInputExtension:GetProperty +R060 XInputExtension:GetSelectedEvents V000 XInputExtension:DeviceValuator V001 XInputExtension:DeviceKeyPress V002 XInputExtension:DeviceKeyRelease diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c index 58b6a81da..684f2a851 100644 --- a/xorg-server/dix/ptrveloc.c +++ b/xorg-server/dix/ptrveloc.c @@ -1,6 +1,6 @@ /* * - * Copyright © 2006-2008 Simon Thum simon dot thum at gmx dot de + * Copyright © 2006-2009 Simon Thum simon dot thum at gmx dot de * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -32,15 +32,16 @@ #include <math.h> #include <ptrveloc.h> -#include <inputstr.h> -#include <assert.h> -#include <os.h> +#include <exevents.h> +#include <X11/Xatom.h> + +#include <xserver-properties.h> /***************************************************************************** * Predictable pointer acceleration * - * 2006-2008 by Simon Thum (simon [dot] thum [at] gmx de) + * 2006-2009 by Simon Thum (simon [dot] thum [at] gmx de) * * Serves 3 complementary functions: * 1) provide a sophisticated ballistic velocity estimate to improve @@ -57,35 +58,25 @@ * which returns an acceleration * for a given velocity * - * The profile can be selected by the user (potentially at runtime). - * the classic profile is intended to cleanly perform old-style + * The profile can be selected by the user at runtime. + * The classic profile is intended to cleanly perform old-style * function selection (threshold =/!= 0) * ****************************************************************************/ #ifdef _MSC_VER #define inline __inline +#define lrintf(val) ((int)val) #endif /* fwds */ -static inline void -FeedFilterStage(FilterStagePtr s, float value, int tdiff); -extern void -InitFilterStage(FilterStagePtr s, float rdecay, int lutsize); -void -CleanupFilterChain(DeviceVelocityPtr s); int -SetAccelerationProfile(DeviceVelocityPtr s, int profile_num); -void -InitFilterChain(DeviceVelocityPtr s, float rdecay, float degression, - int stages, int lutsize); -void -CleanupFilterChain(DeviceVelocityPtr s); +SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); static float -SimpleSmoothProfile(DeviceVelocityPtr pVel, float velocity, +SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity, float threshold, float acc); - - +static PointerAccelerationProfileFunc +GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); /*#define PTRACCEL_DEBUGGING*/ @@ -96,36 +87,41 @@ SimpleSmoothProfile(DeviceVelocityPtr pVel, float velocity, #endif /******************************** - * Init/Uninit etc + * Init/Uninit *******************************/ +/* some int which is not a profile number */ +#define PROFILE_UNINITIALIZE (-100) + /** * Init struct so it should match the average case */ void -InitVelocityData(DeviceVelocityPtr s) +InitVelocityData(DeviceVelocityPtr vel) { - memset(s, 0, sizeof(DeviceVelocityRec)); - - s->corr_mul = 10.0; /* dots per 10 milisecond should be usable */ - s->const_acceleration = 1.0; /* no acceleration/deceleration */ - s->reset_time = 300; - s->use_softening = 1; - s->min_acceleration = 1.0; /* don't decelerate */ - s->coupling = 0.25; - s->average_accel = TRUE; - SetAccelerationProfile(s, AccelProfileClassic); - InitFilterChain(s, (float)1.0/20.0, 1, 1, 40); + memset(vel, 0, sizeof(DeviceVelocityRec)); + + vel->corr_mul = 10.0; /* dots per 10 milisecond should be usable */ + vel->const_acceleration = 1.0; /* no acceleration/deceleration */ + vel->reset_time = 300; + vel->use_softening = 1; + vel->min_acceleration = 1.0; /* don't decelerate */ + vel->max_rel_diff = 0.2; + vel->max_diff = 1.0; + vel->initial_range = 2; + vel->average_accel = TRUE; + SetAccelerationProfile(vel, AccelProfileClassic); + InitTrackers(vel, 16); } /** * Clean up */ -static void -FreeVelocityData(DeviceVelocityPtr s){ - CleanupFilterChain(s); - SetAccelerationProfile(s, -1); +void +FreeVelocityData(DeviceVelocityPtr vel){ + xfree(vel->tracker); + SetAccelerationProfile(vel, PROFILE_UNINITIALIZE); } @@ -133,302 +129,461 @@ FreeVelocityData(DeviceVelocityPtr s){ * dix uninit helper, called through scheme */ void -AccelerationDefaultCleanup(DeviceIntPtr pDev) +AccelerationDefaultCleanup(DeviceIntPtr dev) { /*sanity check*/ - if( pDev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable - && pDev->valuator->accelScheme.accelData != NULL){ - pDev->valuator->accelScheme.AccelSchemeProc = NULL; - FreeVelocityData(pDev->valuator->accelScheme.accelData); - xfree(pDev->valuator->accelScheme.accelData); - pDev->valuator->accelScheme.accelData = NULL; + if( dev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable + && dev->valuator->accelScheme.accelData != NULL){ + dev->valuator->accelScheme.AccelSchemeProc = NULL; + FreeVelocityData(dev->valuator->accelScheme.accelData); + xfree(dev->valuator->accelScheme.accelData); + dev->valuator->accelScheme.accelData = NULL; } } -/********************* - * Filtering logic - ********************/ + +/************************* + * Input property support + ************************/ /** -Initialize a filter chain. -Expected result is a series of filters, each progressively more integrating. - -This allows for two strategies: Either you have one filter which is reasonable -and is being coupled to account for fast-changing input, or you have 'one for -every situation'. You might want to have tighter coupling then, e.g. 0.1. -In the filter stats, you can see if a reasonable filter useage emerges. -*/ -void -InitFilterChain(DeviceVelocityPtr s, float rdecay, float progression, int stages, int lutsize) + * choose profile + */ +static int +AccelSetProfileProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) { - int fn; - if((stages > 1 && progression < 1.0f) || 0 == progression){ - ErrorF("(dix ptracc) invalid filter chain progression specified\n"); - return; - } - /* Block here to support runtime filter adjustment */ - OsBlockSignals(); - for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){ - if(fn < stages){ - InitFilterStage(&s->filters[fn], rdecay, lutsize); - }else{ - InitFilterStage(&s->filters[fn], 0, 0); - } - rdecay /= progression; - } - /* release again. Should the input loop be threaded, we also need - * memory release here (in principle). - */ - OsReleaseSignals(); + DeviceVelocityPtr vel; + int profile, *ptr = &profile; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER)) + return Success; + + vel = GetDevicePredictableAccelData(dev); + if (!vel) + return BadValue; + rc = XIPropToInt(val, &nelem, &ptr); + + if(checkOnly) + { + if (rc) + return rc; + + if (GetAccelerationProfile(vel, profile) == NULL) + return BadValue; + } else + SetAccelerationProfile(vel, profile); + + return Success; } +static void +AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) +{ + int profile = vel->statistics.profile_number; + Atom prop_profile_number = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); -void -CleanupFilterChain(DeviceVelocityPtr s) + XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32, + PropModeReplace, 1, &profile, FALSE); + XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE); + XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL); +} + +/** + * constant deceleration + */ +static int +AccelSetDecelProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) { - int fn; + DeviceVelocityPtr vel; + float v, *ptr = &v; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION)) + return Success; + + vel = GetDevicePredictableAccelData(dev); + if (!vel) + return BadValue; + rc = XIPropToFloat(val, &nelem, &ptr); + + if(checkOnly) + { + if (rc) + return rc; + return (v >= 1.0f) ? Success : BadValue; + } + + if(v >= 1.0f) + vel->const_acceleration = 1/v; - for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++) - InitFilterStage(&s->filters[fn], 0, 0); + return Success; } -static inline void -StuffFilterChain(DeviceVelocityPtr s, float value) +static void +AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) { - int fn; + float fval = 1.0/vel->const_acceleration; + Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); + XIChangeDeviceProperty(dev, prop_const_decel, + XIGetKnownProperty(XATOM_FLOAT), 32, + PropModeReplace, 1, &fval, FALSE); + XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE); + XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL); +} - for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){ - if(s->filters[fn].rdecay != 0) - s->filters[fn].current = value; - else break; + +/** + * adaptive deceleration + */ +static int +AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) +{ + DeviceVelocityPtr veloc; + float v, *ptr = &v; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION)) + return Success; + + veloc = GetDevicePredictableAccelData(dev); + if (!veloc) + return BadValue; + rc = XIPropToFloat(val, &nelem, &ptr); + + if(checkOnly) + { + if (rc) + return rc; + return (v >= 1.0f) ? Success : BadValue; } + + if(v >= 1.0f) + veloc->min_acceleration = 1/v; + + return Success; +} + +static void +AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) +{ + float fval = 1.0/vel->min_acceleration; + Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); + + XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32, + PropModeReplace, 1, &fval, FALSE); + XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE); + XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL); } /** - * Adjust weighting decay and lut for a stage - * The weight fn is designed so its integral 0->inf is unity, so we end - * up with a stable (basically IIR) filter. It always draws - * towards its more current input values, which have more weight the older - * the last input value is. + * velocity scaling */ -void -InitFilterStage(FilterStagePtr s, float rdecay, int lutsize) +static int +AccelSetScaleProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) { - int x; - float *newlut; - float *oldlut; - - s->fading_lut_size = 0; /* prevent access */ - - if(lutsize > 0){ - newlut = xalloc (sizeof(float)* lutsize); - if(!newlut) - return; - for(x = 0; x < lutsize; x++) - newlut[x] = pow(0.5, ((float)x) * rdecay); - }else{ - newlut = NULL; + DeviceVelocityPtr vel; + float v, *ptr = &v; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING)) + return Success; + + vel = GetDevicePredictableAccelData(dev); + if (!vel) + return BadValue; + rc = XIPropToFloat(val, &nelem, &ptr); + + if (checkOnly) + { + if (rc) + return rc; + + return (v > 0) ? Success : BadValue; } - oldlut = s->fading_lut; - s->fading_lut = newlut; - s->rdecay = rdecay; - s->fading_lut_size = lutsize; - s->current = 0; - if(oldlut != NULL) - xfree(oldlut); + + if(v > 0) + vel->corr_mul = v; + + return Success; } +static void +AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) +{ + float fval = vel->corr_mul; + Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); + + XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32, + PropModeReplace, 1, &fval, FALSE); + XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE); + XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL); +} -static inline void -FeedFilterChain(DeviceVelocityPtr s, float value, int tdiff) +BOOL +InitializePredictableAccelerationProperties(DeviceIntPtr dev) { - int fn; + DeviceVelocityPtr vel = GetDevicePredictableAccelData(dev); - for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){ - if(s->filters[fn].rdecay != 0) - FeedFilterStage(&s->filters[fn], value, tdiff); - else break; - } + if(!vel) + return FALSE; + + AccelInitProfileProperty(dev, vel); + AccelInitDecelProperty(dev, vel); + AccelInitAdaptDecelProperty(dev, vel); + AccelInitScaleProperty(dev, vel); + return TRUE; } +/********************* + * Tracking logic + ********************/ -static inline void -FeedFilterStage(FilterStagePtr s, float value, int tdiff){ - float fade; - if(tdiff < s->fading_lut_size) - fade = s->fading_lut[tdiff]; - else - fade = pow(0.5, ((float)tdiff) * s->rdecay); - s->current *= fade; /* fade out old velocity */ - s->current += value * (1.0f - fade); /* and add up current */ +void +InitTrackers(DeviceVelocityPtr vel, int ntracker) +{ + if(ntracker < 1){ + ErrorF("(dix ptracc) invalid number of trackers\n"); + return; + } + xfree(vel->tracker); + vel->tracker = (MotionTrackerPtr)xalloc(ntracker * sizeof(MotionTracker)); + memset(vel->tracker, 0, ntracker * sizeof(MotionTracker)); + vel->num_tracker = ntracker; } /** - * Select the most filtered matching result. Also, the first - * mismatching filter may be set to value (coupling). + * return a bit field of possible directions. + * 0 = N, 2 = E, 4 = S, 6 = W, in-between is as you guess. + * There's no reason against widening to more precise directions (<45 degrees), + * should it not perform well. All this is needed for is sort out non-linear + * motion, so precision isn't paramount. However, one should not flag direction + * too narrow, since it would then cut the linear segment to zero size way too + * often. */ -static inline float -QueryFilterChain( - DeviceVelocityPtr s, - float value) -{ - int fn, rfn = 0, cfn = -1; - float cur, result = value; - - /* try to retrieve most integrated result 'within range' - * Assumption: filter are in order least to most integrating */ - for(fn = 0; fn < MAX_VELOCITY_FILTERS; fn++){ - if(0.0f == s->filters[fn].rdecay) - break; - cur = s->filters[fn].current; +static int +DoGetDirection(int dx, int dy){ + float r; + int i1, i2; + /* on insignificant mickeys, flag 135 degrees */ + if(abs(dx) < 2 && abs(dy < 2)){ + /* first check diagonal cases */ + if(dx > 0 && dy > 0) + return 4+8+16; + if(dx > 0 && dy < 0) + return 1+2+4; + if(dx < 0 && dy < 0) + return 1+128+64; + if(dx < 0 && dy > 0) + return 16+32+64; + /* check axis-aligned directions */ + if(dx > 0) + return 2+4+8; /*E*/ + if(dx < 0) + return 128+64+32; /*W*/ + if(dy > 0) + return 32+16+8; /*S*/ + if(dy < 0) + return 128+1+2; /*N*/ + return 255; /* shouldn't happen */ + } + /* else, compute angle and set appropriate flags */ +#ifdef _ISOC99_SOURCE + r = atan2f(dy, dx); +#else + r = atan2(dy, dx); +#endif + /* find direction. We avoid r to become negative, + * since C has no well-defined modulo for such cases. */ + r = (r+(M_PI*2.5))/(M_PI/4); + /* this intends to flag 2 directions (90 degrees), + * except on very well-aligned mickeys. */ + i1 = (int)(r+0.1) % 8; + i2 = (int)(r+0.9) % 8; + if(i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7) + return 255; /* shouldn't happen */ + return 1 << i1 | 1 << i2; +} - if (fabs(value - cur) <= (s->coupling * (value + cur))){ - result = cur; - rfn = fn + 1; /*remember result determining filter */ - } else if(cfn == -1){ - cfn = fn; /* remember first mismatching filter */ +#define DIRECTION_CACHE_RANGE 5 +#define DIRECTION_CACHE_SIZE (DIRECTION_CACHE_RANGE*2+1) + +/* cache DoGetDirection(). */ +static int +GetDirection(int dx, int dy){ + static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE]; + int i; + if (abs(dx) <= DIRECTION_CACHE_RANGE && + abs(dy) <= DIRECTION_CACHE_RANGE) { + /* cacheable */ + i = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy]; + if(i != 0){ + return i; + }else{ + i = DoGetDirection(dx, dy); + cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy] = i; + return i; } + }else{ + /* non-cacheable */ + return DoGetDirection(dx, dy); } +} - s->statistics.filter_usecount[rfn]++; - DebugAccelF("(dix ptracc) result from stage %i, input %.2f, output %.2f\n", - rfn, value, result); +#undef DIRECTION_CACHE_RANGE +#undef DIRECTION_CACHE_SIZE - /* override first mismatching current (coupling) so the filter - * catches up quickly. */ - if(cfn != -1) - s->filters[cfn].current = result; - return result; -} +/* convert offset (age) to array index */ +#define TRACKER_INDEX(s, d) (((s)->num_tracker + (s)->cur_tracker - (d)) % (s)->num_tracker) -/******************************** - * velocity computation - *******************************/ +static inline void +FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t) +{ + int n; + for(n = 0; n < vel->num_tracker; n++){ + vel->tracker[n].dx += dx; + vel->tracker[n].dy += dy; + } + n = (vel->cur_tracker + 1) % vel->num_tracker; + vel->tracker[n].dx = 0; + vel->tracker[n].dy = 0; + vel->tracker[n].time = cur_t; + vel->tracker[n].dir = GetDirection(dx, dy); + DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n", + dx, dy, vel->tracker[n].dir, + cur_t - vel->tracker[vel->cur_tracker].time); + vel->cur_tracker = n; +} /** - * return the axis if mickey is insignificant and axis-aligned, - * -1 otherwise - * 1 for x-axis - * 2 for y-axis + * calc velocity for given tracker, with + * velocity scaling. + * This assumes linear motion. */ -static inline short -GetAxis(int dx, int dy){ - if(dx == 0 || dy == 0){ - if(dx == 1 || dx == -1) - return 1; - if(dy == 1 || dy == -1) - return 2; - return -1; - }else{ - return -1; +static float +CalcTracker(DeviceVelocityPtr vel, int offset, int cur_t){ + int index = TRACKER_INDEX(vel, offset); + float dist = sqrt( vel->tracker[index].dx * vel->tracker[index].dx + + vel->tracker[index].dy * vel->tracker[index].dy); + int dtime = cur_t - vel->tracker[index].time; + if(dtime > 0) + return (dist / dtime); + else + return 0;/* synonymous for NaN, since we're not C99 */ +} + +/* find the most plausible velocity. That is, the most distant + * (in time) tracker which isn't too old, beyond a linear partition, + * or simply too much off initial velocity. + * + * May return 0. + */ +static float +QueryTrackers(DeviceVelocityPtr vel, int cur_t){ + int n, offset, dir = 255, i = -1, age_ms; + /* initial velocity: a low-offset, valid velocity */ + float iveloc = 0, res = 0, tmp, vdiff; + float vfac = vel->corr_mul * vel->const_acceleration; /* premultiply */ + /* loop from current to older data */ + for(offset = 1; offset < vel->num_tracker; offset++){ + n = TRACKER_INDEX(vel, offset); + + age_ms = cur_t - vel->tracker[n].time; + + /* bail out if data is too old and protect from overrun */ + if (age_ms >= vel->reset_time || age_ms < 0) { + DebugAccelF("(dix prtacc) query: tracker too old\n"); + break; + } + + /* + * this heuristic avoids using the linear-motion velocity formula + * in CalcTracker() on motion that isn't exactly linear. So to get + * even more precision we could subdivide as a final step, so possible + * non-linearities are accounted for. + */ + dir &= vel->tracker[n].dir; + if(dir == 0){ + DebugAccelF("(dix prtacc) query: no longer linear\n"); + /* instead of breaking it we might also inspect the partition after, + * but actual improvement with this is probably rare. */ + break; + } + + tmp = CalcTracker(vel, offset, cur_t) * vfac; + + if ((iveloc == 0 || offset <= vel->initial_range) && tmp != 0) { + /* set initial velocity and result */ + res = iveloc = tmp; + i = offset; + } else if (iveloc != 0 && tmp != 0) { + vdiff = fabs(iveloc - tmp); + if (vdiff <= vel->max_diff || + vdiff/(iveloc + tmp) < vel->max_rel_diff) { + /* we're in range with the initial velocity, + * so this result is likely better + * (it contains more information). */ + res = tmp; + i = offset; + }else{ + /* we're not in range, quit - it won't get better. */ + DebugAccelF("(dix prtacc) query: tracker too different:" + " old %2.2f initial %2.2f diff: %2.2f\n", + tmp, iveloc, vdiff); + break; + } + } + } + if(offset == vel->num_tracker){ + DebugAccelF("(dix prtacc) query: last tracker in effect\n"); + i = vel->num_tracker-1; } + if(i>=0){ + n = TRACKER_INDEX(vel, i); + DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n", + i, + vel->tracker[n].dx, + vel->tracker[n].dy, + cur_t - vel->tracker[n].time); + } + return res; } +#undef TRACKER_INDEX /** - * Perform velocity approximation + * Perform velocity approximation based on 2D 'mickeys' (mouse motion delta). * return true if non-visible state reset is suggested */ -static short -ProcessVelocityData( - DeviceVelocityPtr s, +short +ProcessVelocityData2D( + DeviceVelocityPtr vel, int dx, int dy, int time) { - float cvelocity; - - int diff = time - s->lrm_time; - int cur_ax, last_ax; - short reset = (diff >= s->reset_time); - - /* remember last round's result */ - s->last_velocity = s->velocity; - cur_ax = GetAxis(dx, dy); - last_ax = GetAxis(s->last_dx, s->last_dy); - - if(cur_ax != last_ax && cur_ax != -1 && last_ax != -1 && !reset){ - /* correct for the error induced when diagonal movements are - reported as alternating axis mickeys */ - dx += s->last_dx; - dy += s->last_dy; - diff += s->last_diff; - s->last_diff = time - s->lrm_time; /* prevent repeating add-up */ - DebugAccelF("(dix ptracc) axial correction\n"); - }else{ - s->last_diff = diff; - } + float velocity; - /* - * cvelocity is not a real velocity yet, more a motion delta. constant - * acceleration is multiplied here to make the velocity an on-screen - * velocity (pix/t as opposed to [insert unit]/t). This is intended to - * make multiple devices with widely varying ConstantDecelerations respond - * similar to acceleration controls. - */ - cvelocity = (float)sqrt(dx*dx + dy*dy) * s->const_acceleration; - - s->lrm_time = time; - - if (s->reset_time < 0 || diff < 0) { /* reset disabled or timer overrun? */ - /* simply set velocity from current movement, no reset. */ - s->velocity = cvelocity; - return FALSE; - } + vel->last_velocity = vel->velocity; - if (diff == 0) - diff = 1; /* prevent div-by-zero, though it shouldn't happen anyway*/ + FeedTrackers(vel, dx, dy, time); - /* translate velocity to dots/ms (somewhat intractable in integers, - so we multiply by some per-device adjustable factor) */ - cvelocity = cvelocity * s->corr_mul / (float)diff; + velocity = QueryTrackers(vel, time); - /* short-circuit: when nv-reset the rest can be skipped */ - if(reset == TRUE){ - /* - * we don't really have a velocity here, since diff includes inactive - * time. This is dealt with in ComputeAcceleration. - */ - StuffFilterChain(s, cvelocity); - s->velocity = s->last_velocity = cvelocity; - s->last_reset = TRUE; - DebugAccelF("(dix ptracc) non-visible state reset\n"); - return TRUE; - } - - if(s->last_reset == TRUE){ - /* - * when here, we're probably processing the second mickey of a starting - * stroke. This happens to be the first time we can reasonably pretend - * that cvelocity is an actual velocity. Thus, to opt precision, we - * stuff that into the filter chain. - */ - s->last_reset = FALSE; - DebugAccelF("(dix ptracc) after-reset vel:%.3f\n", cvelocity); - StuffFilterChain(s, cvelocity); - s->velocity = cvelocity; - return FALSE; - } - - /* feed into filter chain */ - FeedFilterChain(s, cvelocity, diff); - - /* perform coupling and decide final value */ - s->velocity = QueryFilterChain(s, cvelocity); - - DebugAccelF("(dix ptracc) guess: vel=%.3f diff=%d %i|%i|%i|%i|%i|%i|%i|%i|%i\n", - s->velocity, diff, - s->statistics.filter_usecount[0], s->statistics.filter_usecount[1], - s->statistics.filter_usecount[2], s->statistics.filter_usecount[3], - s->statistics.filter_usecount[4], s->statistics.filter_usecount[5], - s->statistics.filter_usecount[6], s->statistics.filter_usecount[7], - s->statistics.filter_usecount[8]); - return FALSE; + vel->velocity = velocity; + return velocity == 0; } - /** * this flattens significant ( > 1) mickeys a little bit for more steady * constant-velocity response @@ -449,41 +604,42 @@ ApplySimpleSoftening(int od, int d) static void ApplySofteningAndConstantDeceleration( - DeviceVelocityPtr s, + DeviceVelocityPtr vel, int dx, int dy, float* fdx, float* fdy, short do_soften) { - if (do_soften && s->use_softening) { - *fdx = ApplySimpleSoftening(s->last_dx, dx); - *fdy = ApplySimpleSoftening(s->last_dy, dy); + if (do_soften && vel->use_softening) { + *fdx = ApplySimpleSoftening(vel->last_dx, dx); + *fdy = ApplySimpleSoftening(vel->last_dy, dy); } else { *fdx = dx; *fdy = dy; } - *fdx *= s->const_acceleration; - *fdy *= s->const_acceleration; + *fdx *= vel->const_acceleration; + *fdy *= vel->const_acceleration; } /* * compute the acceleration for given velocity and enforce min_acceleartion */ -static float +float BasicComputeAcceleration( - DeviceVelocityPtr pVel, + DeviceIntPtr dev, + DeviceVelocityPtr vel, float velocity, float threshold, float acc){ float result; - result = pVel->Profile(pVel, velocity, threshold, acc); + result = vel->Profile(dev, vel, velocity, threshold, acc); /* enforce min_acceleration */ - if (result < pVel->min_acceleration) - result = pVel->min_acceleration; + if (result < vel->min_acceleration) + result = vel->min_acceleration; return result; } @@ -492,17 +648,16 @@ BasicComputeAcceleration( */ static float ComputeAcceleration( + DeviceIntPtr dev, DeviceVelocityPtr vel, float threshold, float acc){ float res; - if(vel->last_reset){ + if(vel->velocity <= 0){ DebugAccelF("(dix ptracc) profile skipped\n"); /* - * This is intended to override the first estimate of a stroke, - * which is too low (see ProcessVelocityData). 1 should make sure - * the mickey is seen on screen. + * If we have no idea about device velocity, don't pretend it. */ return 1; } @@ -512,9 +667,11 @@ ComputeAcceleration( * current and previous velocity. * Though being the more natural choice, it causes a minor delay * in comparison, so it can be disabled. */ - res = BasicComputeAcceleration(vel, vel->velocity, threshold, acc); - res += BasicComputeAcceleration(vel, vel->last_velocity, threshold, acc); - res += 4.0f * BasicComputeAcceleration(vel, + res = BasicComputeAcceleration( + dev, vel, vel->velocity, threshold, acc); + res += BasicComputeAcceleration( + dev, vel, vel->last_velocity, threshold, acc); + res += 4.0f * BasicComputeAcceleration(dev, vel, (vel->last_velocity + vel->velocity) / 2, threshold, acc); res /= 6.0f; @@ -522,7 +679,8 @@ ComputeAcceleration( vel->velocity, vel->last_velocity, res); return res; }else{ - res = BasicComputeAcceleration(vel, vel->velocity, threshold, acc); + res = BasicComputeAcceleration(dev, vel, + vel->velocity, threshold, acc); DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n", vel->velocity, res); return res; @@ -539,7 +697,8 @@ ComputeAcceleration( */ static float PolynomialAccelerationProfile( - DeviceVelocityPtr pVel, + DeviceIntPtr dev, + DeviceVelocityPtr vel, float velocity, float ignored, float acc) @@ -554,18 +713,21 @@ PolynomialAccelerationProfile( */ static float ClassicProfile( - DeviceVelocityPtr pVel, + DeviceIntPtr dev, + DeviceVelocityPtr vel, float velocity, float threshold, float acc) { - if (threshold) { - return SimpleSmoothProfile (pVel, + if (threshold > 0) { + return SimpleSmoothProfile (dev, + vel, velocity, threshold, acc); } else { - return PolynomialAccelerationProfile (pVel, + return PolynomialAccelerationProfile (dev, + vel, velocity, 0, acc); @@ -583,7 +745,8 @@ ClassicProfile( */ static float PowerProfile( - DeviceVelocityPtr pVel, + DeviceIntPtr dev, + DeviceVelocityPtr vel, float velocity, float threshold, float acc) @@ -593,9 +756,9 @@ PowerProfile( acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */ if (velocity <= threshold) - return pVel->min_acceleration; + return vel->min_acceleration; vel_dist = velocity - threshold; - return (pow(acc, vel_dist)) * pVel->min_acceleration; + return (pow(acc, vel_dist)) * vel->min_acceleration; } @@ -620,7 +783,8 @@ CalcPenumbralGradient(float x){ */ static float SimpleSmoothProfile( - DeviceVelocityPtr pVel, + DeviceIntPtr dev, + DeviceVelocityPtr vel, float velocity, float threshold, float acc) @@ -645,7 +809,8 @@ SimpleSmoothProfile( */ static float SmoothLinearProfile( - DeviceVelocityPtr pVel, + DeviceIntPtr dev, + DeviceVelocityPtr vel, float velocity, float threshold, float acc) @@ -668,14 +833,15 @@ SmoothLinearProfile( res = nv * 2.0f / M_PI /* steepness of gradient at 0.5 */ + 1.0f; /* gradient crosses 2|1 */ } - res += pVel->min_acceleration; + res += vel->min_acceleration; return res; } static float LinearProfile( - DeviceVelocityPtr pVel, + DeviceIntPtr dev, + DeviceVelocityPtr vel, float velocity, float threshold, float acc) @@ -684,60 +850,73 @@ LinearProfile( } -/** - * Set the profile by number. - * Intended to make profiles exchangeable at runtime. - * If you created a profile, give it a number here and in the header to - * make it selectable. In case some profile-specific init is needed, here - * would be a good place, since FreeVelocityData() also calls this with -1. - * returns FALSE (0) if profile number is unavailable. - */ -_X_EXPORT int -SetAccelerationProfile( - DeviceVelocityPtr s, +static float +NoProfile( + DeviceIntPtr dev, + DeviceVelocityPtr vel, + float velocity, + float threshold, + float acc) +{ + return 1.0f; +} + +static PointerAccelerationProfileFunc +GetAccelerationProfile( + DeviceVelocityPtr vel, int profile_num) { - PointerAccelerationProfileFunc profile; switch(profile_num){ - case -1: - profile = NULL; /* Special case to uninit properly */ - break; case AccelProfileClassic: - profile = ClassicProfile; - break; + return ClassicProfile; case AccelProfileDeviceSpecific: - if(NULL == s->deviceSpecificProfile) - return FALSE; - profile = s->deviceSpecificProfile; - break; + return vel->deviceSpecificProfile; case AccelProfilePolynomial: - profile = PolynomialAccelerationProfile; - break; + return PolynomialAccelerationProfile; case AccelProfileSmoothLinear: - profile = SmoothLinearProfile; - break; + return SmoothLinearProfile; case AccelProfileSimple: - profile = SimpleSmoothProfile; - break; + return SimpleSmoothProfile; case AccelProfilePower: - profile = PowerProfile; - break; + return PowerProfile; case AccelProfileLinear: - profile = LinearProfile; - break; - case AccelProfileReserved: - /* reserved for future use, e.g. a user-defined profile */ + return LinearProfile; + case AccelProfileNone: + return NoProfile; default: - return FALSE; + return NULL; } - if(s->profile_private != NULL){ +} + +/** + * Set the profile by number. + * Intended to make profiles exchangeable at runtime. + * If you created a profile, give it a number here and in the header to + * make it selectable. In case some profile-specific init is needed, here + * would be a good place, since FreeVelocityData() also calls this with + * PROFILE_UNINITIALIZE. + * + * returns FALSE if profile number is unavailable, TRUE otherwise. + */ +int +SetAccelerationProfile( + DeviceVelocityPtr vel, + int profile_num) +{ + PointerAccelerationProfileFunc profile; + profile = GetAccelerationProfile(vel, profile_num); + + if(profile == NULL && profile_num != PROFILE_UNINITIALIZE) + return FALSE; + + if(vel->profile_private != NULL){ /* Here one could free old profile-private data */ - xfree(s->profile_private); - s->profile_private = NULL; + xfree(vel->profile_private); + vel->profile_private = NULL; } /* Here one could init profile-private data */ - s->Profile = profile; - s->statistics.profile_number = profile_num; + vel->Profile = profile; + vel->statistics.profile_number = profile_num; return TRUE; } @@ -755,34 +934,34 @@ SetAccelerationProfile( * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends). * Users may override or choose it. */ -_X_EXPORT void +void SetDeviceSpecificAccelerationProfile( - DeviceVelocityPtr s, + DeviceVelocityPtr vel, PointerAccelerationProfileFunc profile) { - if(s) - s->deviceSpecificProfile = profile; + if(vel) + vel->deviceSpecificProfile = profile; } /** * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if * the predictable acceleration scheme is not in effect. */ -_X_EXPORT DeviceVelocityPtr +DeviceVelocityPtr GetDevicePredictableAccelData( - DeviceIntPtr pDev) + DeviceIntPtr dev) { /*sanity check*/ - if(!pDev){ + if(!dev){ ErrorF("[dix] accel: DeviceIntPtr was NULL"); return NULL; } - if( pDev->valuator && - pDev->valuator->accelScheme.AccelSchemeProc == + if( dev->valuator && + dev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable && - pDev->valuator->accelScheme.accelData != NULL){ + dev->valuator->accelScheme.accelData != NULL){ - return (DeviceVelocityPtr)pDev->valuator->accelScheme.accelData; + return (DeviceVelocityPtr)dev->valuator->accelScheme.accelData; } return NULL; } @@ -798,7 +977,7 @@ GetDevicePredictableAccelData( */ void acceleratePointerPredictable( - DeviceIntPtr pDev, + DeviceIntPtr dev, int first_valuator, int num_valuators, int *valuators, @@ -808,12 +987,18 @@ acceleratePointerPredictable( int dx = 0, dy = 0; int *px = NULL, *py = NULL; DeviceVelocityPtr velocitydata = - (DeviceVelocityPtr) pDev->valuator->accelScheme.accelData; - float fdx, fdy; /* no need to init */ + (DeviceVelocityPtr) dev->valuator->accelScheme.accelData; + float fdx, fdy, tmp; /* no need to init */ + Bool soften = TRUE; if (!num_valuators || !valuators || !velocitydata) return; + if (velocitydata->statistics.profile_number == AccelProfileNone && + velocitydata->const_acceleration == 1.0f) { + return; /*we're inactive anyway, so skip the whole thing.*/ + } + if (first_valuator == 0) { dx = valuators[0]; px = &valuators[0]; @@ -824,40 +1009,41 @@ acceleratePointerPredictable( } if (dx || dy){ - /* reset nonvisible state? */ - if (ProcessVelocityData(velocitydata, dx , dy, evtime)) { - /* set to center of pixel. makes sense as long as there are no - * means of passing on sub-pixel values. - */ - pDev->last.remainder[0] = pDev->last.remainder[1] = 0.5f; - /* prevent softening (somewhat quirky solution, - as it depends on the algorithm) */ - velocitydata->last_dx = dx; - velocitydata->last_dy = dy; + /* reset non-visible state? */ + if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) { + soften = FALSE; } - if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) { + if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { /* invoke acceleration profile to determine acceleration */ - mult = ComputeAcceleration (velocitydata, - pDev->ptrfeed->ctrl.threshold, - (float)pDev->ptrfeed->ctrl.num / - (float)pDev->ptrfeed->ctrl.den); + mult = ComputeAcceleration (dev, velocitydata, + dev->ptrfeed->ctrl.threshold, + (float)dev->ptrfeed->ctrl.num / + (float)dev->ptrfeed->ctrl.den); if(mult != 1.0 || velocitydata->const_acceleration != 1.0) { ApplySofteningAndConstantDeceleration( velocitydata, - dx, dy, - &fdx, &fdy, - mult > 1.0); + dx, dy, + &fdx, &fdy, + (mult > 1.0) && soften); + if (dx) { - pDev->last.remainder[0] = mult * fdx + pDev->last.remainder[0]; - *px = (int)pDev->last.remainder[0]; - pDev->last.remainder[0] = pDev->last.remainder[0] - (float)*px; + tmp = mult * fdx + dev->last.remainder[0]; + /* Since it may not be apparent: lrintf() does not offer + * strong statements about rounding; however because we + * process each axis conditionally, there's no danger + * of a toggling remainder. Its lack of guarantees likely + * makes it faster on the average target. */ + *px = lrintf(tmp); + dev->last.remainder[0] = tmp - (float)*px; } if (dy) { - pDev->last.remainder[1] = mult * fdy + pDev->last.remainder[1]; - *py = (int)pDev->last.remainder[1]; - pDev->last.remainder[1] = pDev->last.remainder[1] - (float)*py; + tmp = mult * fdy + dev->last.remainder[1]; + *py = lrintf(tmp); + dev->last.remainder[1] = tmp - (float)*py; } + DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n", + *px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy); } } } @@ -874,7 +1060,7 @@ acceleratePointerPredictable( */ void acceleratePointerLightweight( - DeviceIntPtr pDev, + DeviceIntPtr dev, int first_valuator, int num_valuators, int *valuators, @@ -899,48 +1085,48 @@ acceleratePointerLightweight( if (!dx && !dy) return; - if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) { + if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { /* modeled from xf86Events.c */ - if (pDev->ptrfeed->ctrl.threshold) { - if ((abs(dx) + abs(dy)) >= pDev->ptrfeed->ctrl.threshold) { - pDev->last.remainder[0] = ((float)dx * - (float)(pDev->ptrfeed->ctrl.num)) / - (float)(pDev->ptrfeed->ctrl.den) + - pDev->last.remainder[0]; + if (dev->ptrfeed->ctrl.threshold) { + if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) { + dev->last.remainder[0] = ((float)dx * + (float)(dev->ptrfeed->ctrl.num)) / + (float)(dev->ptrfeed->ctrl.den) + + dev->last.remainder[0]; if (px) { - *px = (int)pDev->last.remainder[0]; - pDev->last.remainder[0] = pDev->last.remainder[0] - + *px = (int)dev->last.remainder[0]; + dev->last.remainder[0] = dev->last.remainder[0] - (float)(*px); } - pDev->last.remainder[1] = ((float)dy * - (float)(pDev->ptrfeed->ctrl.num)) / - (float)(pDev->ptrfeed->ctrl.den) + - pDev->last.remainder[1]; + dev->last.remainder[1] = ((float)dy * + (float)(dev->ptrfeed->ctrl.num)) / + (float)(dev->ptrfeed->ctrl.den) + + dev->last.remainder[1]; if (py) { - *py = (int)pDev->last.remainder[1]; - pDev->last.remainder[1] = pDev->last.remainder[1] - + *py = (int)dev->last.remainder[1]; + dev->last.remainder[1] = dev->last.remainder[1] - (float)(*py); } } } else { mult = pow((float)dx * (float)dx + (float)dy * (float)dy, - ((float)(pDev->ptrfeed->ctrl.num) / - (float)(pDev->ptrfeed->ctrl.den) - 1.0) / + ((float)(dev->ptrfeed->ctrl.num) / + (float)(dev->ptrfeed->ctrl.den) - 1.0) / 2.0) / 2.0; if (dx) { - pDev->last.remainder[0] = mult * (float)dx + - pDev->last.remainder[0]; - *px = (int)pDev->last.remainder[0]; - pDev->last.remainder[0] = pDev->last.remainder[0] - + dev->last.remainder[0] = mult * (float)dx + + dev->last.remainder[0]; + *px = (int)dev->last.remainder[0]; + dev->last.remainder[0] = dev->last.remainder[0] - (float)(*px); } if (dy) { - pDev->last.remainder[1] = mult * (float)dy + - pDev->last.remainder[1]; - *py = (int)pDev->last.remainder[1]; - pDev->last.remainder[1] = pDev->last.remainder[1] - + dev->last.remainder[1] = mult * (float)dy + + dev->last.remainder[1]; + *py = (int)dev->last.remainder[1]; + dev->last.remainder[1] = dev->last.remainder[1] - (float)(*py); } } diff --git a/xorg-server/dix/registry.c b/xorg-server/dix/registry.c index a519cff6b..ec853b37f 100644 --- a/xorg-server/dix/registry.c +++ b/xorg-server/dix/registry.c @@ -1,6 +1,6 @@ /************************************************************ -Author: Eamon Walsh <ewalsh@epoch.ncsc.mil> +Author: Eamon Walsh <ewalsh@tycho.nsa.gov> Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c index 7b133cae4..d3641df8d 100644 --- a/xorg-server/dix/resource.c +++ b/xorg-server/dix/resource.c @@ -124,7 +124,6 @@ Equipment Corporation. * resource "owned" by the client. */ -#define NEED_EVENTS #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -186,13 +185,13 @@ typedef struct _ClientResource { XID expectID; } ClientResourceRec; -_X_EXPORT RESTYPE lastResourceType; +RESTYPE lastResourceType; static RESTYPE lastResourceClass; -_X_EXPORT RESTYPE TypeMask; +RESTYPE TypeMask; static DeleteType *DeleteFuncs = (DeleteType *)NULL; -_X_EXPORT CallbackListPtr ResourceStateCallback; +CallbackListPtr ResourceStateCallback; static _X_INLINE void CallResourceStateCallback(ResourceState state, ResourceRec *res) @@ -203,7 +202,7 @@ CallResourceStateCallback(ResourceState state, ResourceRec *res) } } -_X_EXPORT RESTYPE +RESTYPE CreateNewResourceType(DeleteType deleteFunc) { RESTYPE next = lastResourceType + 1; @@ -224,7 +223,7 @@ CreateNewResourceType(DeleteType deleteFunc) return next; } -_X_EXPORT RESTYPE +RESTYPE CreateNewResourceClass(void) { RESTYPE next = lastResourceClass >> 1; @@ -256,8 +255,7 @@ InitClientResources(ClientPtr client) TypeMask = RC_LASTPREDEF - 1; if (DeleteFuncs) xfree(DeleteFuncs); - DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) * - sizeof(DeleteType)); + DeleteFuncs = xalloc((lastResourceType + 1) * sizeof(DeleteType)); if (!DeleteFuncs) return FALSE; DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA; @@ -272,7 +270,7 @@ InitClientResources(ClientPtr client) DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab; } clientTable[i = client->index].resources = - (ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr)); + xalloc(INITBUCKETS*sizeof(ResourcePtr)); if (!clientTable[i].resources) return FALSE; clientTable[i].buckets = INITBUCKETS; @@ -394,13 +392,16 @@ unsigned int GetXIDList(ClientPtr pClient, unsigned count, XID *pids) { unsigned int found = 0; - XID id = pClient->clientAsMask; + XID rc, id = pClient->clientAsMask; XID maxid; + pointer val; maxid = id | RESOURCE_ID_MASK; while ( (found < count) && (id <= maxid) ) { - if (!LookupIDByClass(id, RC_ANY)) + rc = dixLookupResourceByClass(&val, id, RC_ANY, serverClient, + DixGetAttrAccess); + if (rc == BadValue) { pids[found++] = id; } @@ -417,7 +418,7 @@ GetXIDList(ClientPtr pClient, unsigned count, XID *pids) * over-running another client. */ -_X_EXPORT XID +XID FakeClientID(int client) { XID id, maxid; @@ -438,7 +439,7 @@ FakeClientID(int client) return id; } -_X_EXPORT Bool +Bool AddResource(XID id, RESTYPE type, pointer value) { int client; @@ -460,7 +461,7 @@ AddResource(XID id, RESTYPE type, pointer value) (rrec->hashsize < MAXHASHSIZE)) RebuildTable(client); head = &rrec->resources[Hash(client, id)]; - res = (ResourcePtr)xalloc(sizeof(ResourceRec)); + res = xalloc(sizeof(ResourceRec)); if (!res) { (*DeleteFuncs[type & TypeMask])(value, id); @@ -492,10 +493,10 @@ RebuildTable(int client) */ j = 2 * clientTable[client].buckets; - tails = (ResourcePtr **)xalloc(j * sizeof(ResourcePtr *)); + tails = xalloc(j * sizeof(ResourcePtr *)); if (!tails) return; - resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr)); + resources = xalloc(j * sizeof(ResourcePtr)); if (!resources) { xfree(tails); @@ -527,7 +528,7 @@ RebuildTable(int client) clientTable[client].resources = resources; } -_X_EXPORT void +void FreeResource(XID id, RESTYPE skipDeleteFuncType) { int cid; @@ -570,7 +571,7 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) } -_X_EXPORT void +void FreeResourceByType(XID id, RESTYPE type, Bool skipFree) { int cid; @@ -610,7 +611,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) * data */ -_X_EXPORT Bool +Bool ChangeResourceValue (XID id, RESTYPE rtype, pointer value) { int cid; @@ -636,7 +637,7 @@ ChangeResourceValue (XID id, RESTYPE rtype, pointer value) * add and delete an equal number of resources! */ -_X_EXPORT void +void FindClientResourcesByType( ClientPtr client, RESTYPE type, @@ -668,7 +669,7 @@ FindClientResourcesByType( } } -_X_EXPORT void +void FindAllClientResources( ClientPtr client, FindAllRes func, @@ -706,7 +707,8 @@ LookupClientResourceComplex( pointer cdata ){ ResourcePtr *resources; - ResourcePtr this; + ResourcePtr this, next; + pointer value; int i; if (!client) @@ -714,10 +716,13 @@ LookupClientResourceComplex( resources = clientTable[client->index].resources; for (i = 0; i < clientTable[client->index].buckets; i++) { - for (this = resources[i]; this; this = this->next) { + for (this = resources[i]; this; this = next) { + next = this->next; if (!type || this->type == type) { - if((*func)(this->value, this->id, cdata)) - return this->value; + /* workaround func freeing the type as DRI1 does */ + value = this->value; + if((*func)(value, this->id, cdata)) + return value; } } } @@ -825,9 +830,11 @@ FreeAllResources(void) } } -_X_EXPORT Bool +Bool LegalNewID(XID id, ClientPtr client) { + pointer val; + int rc; #ifdef PANORAMIX XID minid, maxid; @@ -840,12 +847,19 @@ LegalNewID(XID id, ClientPtr client) return TRUE; } #endif /* PANORAMIX */ - return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) && - ((clientTable[client->index].expectID <= id) || - !LookupIDByClass(id, RC_ANY))); + if (client->clientAsMask == (id & ~RESOURCE_ID_MASK)) + { + if (clientTable[client->index].expectID <= id) + return TRUE; + + rc = dixLookupResourceByClass(&val, id, RC_ANY, serverClient, + DixGetAttrAccess); + return (rc == BadValue); + } + return FALSE; } -_X_EXPORT int +int dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype, ClientPtr client, Mask mode) { @@ -876,7 +890,7 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype, return Success; } -_X_EXPORT int +int dixLookupResourceByClass(pointer *result, XID id, RESTYPE rclass, ClientPtr client, Mask mode) { diff --git a/xorg-server/dix/selection.c b/xorg-server/dix/selection.c index c5427e004..d72f381ca 100644 --- a/xorg-server/dix/selection.c +++ b/xorg-server/dix/selection.c @@ -65,10 +65,10 @@ SOFTWARE. * *****************************************************************/ -_X_EXPORT Selection *CurrentSelections; +Selection *CurrentSelections; CallbackListPtr SelectionCallback; -_X_EXPORT int +int dixLookupSelection(Selection **result, Atom selectionName, ClientPtr client, Mask access_mode) { @@ -243,6 +243,7 @@ ProcGetSelectionOwner(ClientPtr client) return BadAtom; } + memset(&reply, 0, sizeof(xGetSelectionOwnerReply)); reply.type = X_Reply; reply.length = 0; reply.sequenceNumber = client->sequence; @@ -284,6 +285,7 @@ ProcConvertSelection(ClientPtr client) rc = dixLookupSelection(&pSel, stuff->selection, client, DixReadAccess); + memset(&event, 0, sizeof(xEvent)); if (rc != Success && rc != BadMatch) return rc; else if (rc == Success && pSel->window != None) { diff --git a/xorg-server/dix/swaprep.c b/xorg-server/dix/swaprep.c index 91469e17b..12c6dbd26 100644 --- a/xorg-server/dix/swaprep.c +++ b/xorg-server/dix/swaprep.c @@ -51,8 +51,6 @@ SOFTWARE. #endif #include <X11/X.h> -#define NEED_REPLIES -#define NEED_EVENTS #include <X11/Xproto.h> #include "misc.h" #include "dixstruct.h" @@ -72,7 +70,7 @@ static void SwapFont(xQueryFontReply *pr, Bool hasGlyphs); * * \param size size in bytes */ -_X_EXPORT void +void Swap32Write(ClientPtr pClient, int size, CARD32 *pbuf) { int i; @@ -92,7 +90,7 @@ Swap32Write(ClientPtr pClient, int size, CARD32 *pbuf) * * \param size size in bytes */ -_X_EXPORT void +void CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf) { int bufsize = size; @@ -101,7 +99,7 @@ CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf) CARD32 tmpbuf[1]; /* Allocate as big a buffer as we can... */ - while (!(pbufT = (CARD32 *) xalloc(bufsize))) + while (!(pbufT = xalloc(bufsize))) { bufsize >>= 1; if (bufsize == 4) @@ -133,7 +131,7 @@ CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf) } if (pbufT != tmpbuf) - xfree ((char *) pbufT); + xfree (pbufT); } /** @@ -149,7 +147,7 @@ CopySwap16Write(ClientPtr pClient, int size, short *pbuf) short tmpbuf[2]; /* Allocate as big a buffer as we can... */ - while (!(pbufT = (short *) xalloc(bufsize))) + while (!(pbufT = xalloc(bufsize))) { bufsize >>= 1; if (bufsize == 4) @@ -181,7 +179,7 @@ CopySwap16Write(ClientPtr pClient, int size, short *pbuf) } if (pbufT != tmpbuf) - xfree ((char *) pbufT); + xfree (pbufT); } @@ -526,10 +524,7 @@ SListInstalledColormapsReply(ClientPtr pClient, int size, } void -SAllocColorReply(pClient, size, pRep) - ClientPtr pClient; - int size; - xAllocColorReply *pRep; +SAllocColorReply(ClientPtr pClient, int size, xAllocColorReply *pRep) { char n; @@ -736,7 +731,7 @@ SLHostsExtend(ClientPtr pClient, int size, char *buf) int len = host->length; char n; swaps (&host->length, n); - bufT += sizeof (xHostEntry) + (((len + 3) >> 2) << 2); + bufT += sizeof (xHostEntry) + pad_to_int32(len); } (void)WriteToClient (pClient, size, buf); } @@ -1211,7 +1206,7 @@ SwapVisual(xVisualType *pVis, xVisualType *pVisT) cpswapl(pVis->blueMask, pVisT->blueMask); } -_X_EXPORT void +void SwapConnSetupInfo( char *pInfo, char *pInfoT @@ -1227,7 +1222,7 @@ SwapConnSetupInfo( pInfoT += sizeof(xConnSetup); /* Copy the vendor string */ - i = (pConnSetup->nbytesVendor + 3) & ~3; + i = pad_to_int32(pConnSetup->nbytesVendor); memcpy(pInfoT, pInfo, i); pInfo += i; pInfoT += i; @@ -1267,7 +1262,7 @@ WriteSConnectionInfo(ClientPtr pClient, unsigned long size, char *pInfo) { char *pInfoTBase; - pInfoTBase = (char *) xalloc(size); + pInfoTBase = xalloc(size); if (!pInfoTBase) { pClient->noClientException = -1; @@ -1278,7 +1273,7 @@ WriteSConnectionInfo(ClientPtr pClient, unsigned long size, char *pInfo) xfree(pInfoTBase); } -_X_EXPORT void +void SwapConnSetupPrefix(xConnSetupPrefix *pcspFrom, xConnSetupPrefix *pcspTo) { pcspTo->success = pcspFrom->success; @@ -1296,3 +1291,18 @@ WriteSConnSetupPrefix(ClientPtr pClient, xConnSetupPrefix *pcsp) SwapConnSetupPrefix(pcsp, &cspT); (void)WriteToClient(pClient, sizeof(cspT), (char *) &cspT); } + +/* + * Dummy entry for ReplySwapVector[] + */ + +void +ReplyNotSwappd( + ClientPtr pClient , + int size , + void * pbuf + ) +{ + FatalError("Not implemented"); +} + diff --git a/xorg-server/dix/swapreq.c b/xorg-server/dix/swapreq.c index ad60d17da..5d7d71c8f 100644 --- a/xorg-server/dix/swapreq.c +++ b/xorg-server/dix/swapreq.c @@ -51,7 +51,6 @@ SOFTWARE. #endif #include <X11/X.h> -#define NEED_EVENTS #include <X11/Xproto.h> #include <X11/Xprotostr.h> #include "misc.h" @@ -62,7 +61,7 @@ SOFTWARE. /* Thanks to Jack Palevich for testing and subsequently rewriting all this */ /* Byte swap a list of longs */ -_X_EXPORT void +void SwapLongs (CARD32 *list, unsigned long count) { char n; @@ -88,7 +87,7 @@ SwapLongs (CARD32 *list, unsigned long count) } /* Byte swap a list of shorts */ -_X_EXPORT void +void SwapShorts (short *list, unsigned long count) { char n; @@ -248,7 +247,7 @@ SProcChangeProperty(ClientPtr client) return((* ProcVector[X_ChangeProperty])(client)); } -int +int SProcDeleteProperty(ClientPtr client) { char n; @@ -261,7 +260,7 @@ SProcDeleteProperty(ClientPtr client) } -int +int SProcGetProperty(ClientPtr client) { char n; @@ -853,7 +852,7 @@ SProcFreeColors(ClientPtr client) } -_X_EXPORT void +void SwapColorItem(xColorItem *pItem) { char n; diff --git a/xorg-server/dix/tables.c b/xorg-server/dix/tables.c index e4f93661c..5aafb8b0f 100644 --- a/xorg-server/dix/tables.c +++ b/xorg-server/dix/tables.c @@ -50,8 +50,6 @@ SOFTWARE. #endif #include <X11/X.h> -#define NEED_EVENTS -#define NEED_REPLIES #include <X11/Xproto.h> #include "windowstr.h" #include "extnsionst.h" @@ -338,7 +336,7 @@ int (* SwappedProcVector[256]) ( SProcNoOperation }; -_X_EXPORT EventSwapPtr EventSwapVector[128] = +EventSwapPtr EventSwapVector[128] = { (EventSwapPtr)SErrorEvent, NotImplemented, diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c index 7b1af49cb..e9d90aba4 100644 --- a/xorg-server/dix/window.c +++ b/xorg-server/dix/window.c @@ -2,25 +2,24 @@ Copyright (c) 2006, Red Hat, Inc. -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. +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 shall be included in -all copies or substantial portions of the Software. +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 -RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Red Hat shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from Red Hat. +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. Copyright 1987, 1998 The Open Group @@ -150,12 +149,12 @@ WindowSeekDeviceCursor(WindowPtr pWin, DevCursNodePtr* pNode, DevCursNodePtr* pPrev); -_X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF; +int screenIsSaved = SCREEN_SAVER_OFF; -_X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS]; +ScreenSaverStuffRec savedScreenInfo[MAXSCREENS]; static int FocusPrivatesKeyIndex; -_X_EXPORT DevPrivateKey FocusPrivatesKey = &FocusPrivatesKeyIndex; +DevPrivateKey FocusPrivatesKey = &FocusPrivatesKeyIndex; static Bool TileScreenSaver(int i, int kind); @@ -221,7 +220,7 @@ PrintWindowTree(void) } #endif -_X_EXPORT int +int TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data) { int result; @@ -256,7 +255,7 @@ TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data) * exit WalkTree. Does depth-first traverse. *****/ -_X_EXPORT int +int WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data) { return(TraverseTree(WindowTable[pScreen->myNum], func, data)); @@ -360,7 +359,7 @@ CreateRootWindow(ScreenPtr pScreen) BoxRec box; PixmapFormatRec *format; - pWin = (WindowPtr)xalloc(sizeof(WindowRec)); + pWin = xalloc(sizeof(WindowRec)); if (!pWin) return FALSE; @@ -387,7 +386,7 @@ CreateRootWindow(ScreenPtr pScreen) pWin->parent = NullWindow; SetWindowToDefaults(pWin); - pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec)); + pWin->optional = xalloc (sizeof (WindowOptRec)); if (!pWin->optional) return FALSE; @@ -403,19 +402,6 @@ CreateRootWindow(ScreenPtr pScreen) pWin->optional->inputShape = NULL; pWin->optional->inputMasks = NULL; pWin->optional->deviceCursors = NULL; - pWin->optional->geMasks = (GenericClientMasksPtr)xcalloc(1, sizeof(GenericClientMasksRec)); - if (!pWin->optional->geMasks) - { - xfree(pWin->optional); - return FALSE; - } - - pWin->optional->access.perm = NULL; - pWin->optional->access.deny = NULL; - pWin->optional->access.nperm = 0; - pWin->optional->access.ndeny = 0; - pWin->optional->access.defaultRule = 0; - pWin->optional->colormap = pScreen->defColormap; pWin->optional->visual = pScreen->rootVisual; @@ -564,7 +550,7 @@ RealChildHead(WindowPtr pWin) * Makes a window in response to client request *****/ -_X_EXPORT WindowPtr +WindowPtr CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist, int depth, ClientPtr client, VisualID visual, int *error) @@ -653,7 +639,7 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, return NullWindow; } - pWin = (WindowPtr)xalloc(sizeof(WindowRec)); + pWin = xalloc(sizeof(WindowRec)); if (!pWin) { *error = BadAlloc; @@ -780,6 +766,7 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, if (SubSend(pParent)) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = CreateNotify; event.u.createNotify.window = wid; event.u.createNotify.parent = pParent->drawable.id; @@ -797,8 +784,6 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, static void DisposeWindowOptional (WindowPtr pWin) { - GenericMaskPtr gmask = NULL, next = NULL; - if (!pWin->optional) return; /* @@ -829,20 +814,6 @@ DisposeWindowOptional (WindowPtr pWin) pWin->optional->deviceCursors = NULL; } - xfree(pWin->optional->access.perm); - xfree(pWin->optional->access.deny); - - /* Remove generic event mask allocations */ - if (pWin->optional->geMasks) - gmask = pWin->optional->geMasks->geClients; - while(gmask) - { - next = gmask->next; - xfree(gmask); - gmask = next; - } - xfree (pWin->optional->geMasks); - xfree (pWin->optional); pWin->optional = NULL; } @@ -898,9 +869,10 @@ CrushTree(WindowPtr pWin) pParent = pChild->parent; if (SubStrSend(pChild, pParent)) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = DestroyNotify; event.u.destroyNotify.window = pChild->drawable.id; - DeliverEvents(pChild, &event, 1, NullWindow); + DeliverEvents(pChild, &event, 1, NullWindow); } FreeResource(pChild->drawable.id, RT_WINDOW); pSib = pChild->nextSib; @@ -944,9 +916,10 @@ DeleteWindow(pointer value, XID wid) pParent = pWin->parent; if (wid && pParent && SubStrSend(pWin, pParent)) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = DestroyNotify; event.u.destroyNotify.window = pWin->drawable.id; - DeliverEvents(pWin, &event, 1, NullWindow); + DeliverEvents(pWin, &event, 1, NullWindow); } FreeWindowResources(pWin); @@ -990,9 +963,6 @@ DestroySubwindows(WindowPtr pWin, ClientPtr client) return Success; } -#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \ - ButtonReleaseMask | PointerMotionMask) - /***** * ChangeWindowAttributes * @@ -1001,7 +971,7 @@ DestroySubwindows(WindowPtr pWin, ClientPtr client) * to most significant bit in the mask. *****/ -_X_EXPORT int +int ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) { XID *pVlist; @@ -1487,8 +1457,8 @@ GetWindowAttributes(WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply wa->backingStore = NotUseful; else wa->backingStore = pWin->backingStore; - wa->length = (sizeof(xGetWindowAttributesReply) - - sizeof(xGenericReply)) >> 2; + wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) - + sizeof(xGenericReply)); wa->sequenceNumber = client->sequence; wa->backingBitPlanes = wBackingBitPlanes (pWin); wa->backingPixel = wBackingPixel (pWin); @@ -1597,32 +1567,6 @@ MoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib) return( pFirstChange ); } -_X_EXPORT RegionPtr -CreateUnclippedWinSize (WindowPtr pWin) -{ - RegionPtr pRgn; - BoxRec box; - - box.x1 = pWin->drawable.x; - box.y1 = pWin->drawable.y; - box.x2 = pWin->drawable.x + (int) pWin->drawable.width; - box.y2 = pWin->drawable.y + (int) pWin->drawable.height; - pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1); - if (wBoundingShape (pWin) || wClipShape (pWin)) { - ScreenPtr pScreen; - pScreen = pWin->drawable.pScreen; - - REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x, - - pWin->drawable.y); - if (wBoundingShape (pWin)) - REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin)); - if (wClipShape (pWin)) - REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin)); - REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y); - } - return pRgn; -} - void SetWinSize (WindowPtr pWin) { @@ -1718,7 +1662,7 @@ SetBorderSize (WindowPtr pWin) * \param destx,desty position relative to gravity */ -_X_EXPORT void +void GravityTranslate (int x, int y, int oldx, int oldy, int dw, int dh, unsigned gravity, int *destx, int *desty) @@ -2279,6 +2223,7 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) (RedirectSend(pParent) )) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = ConfigureRequest; event.u.configureRequest.window = pWin->drawable.id; if (mask & CWSibling) @@ -2313,6 +2258,7 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask)) { xEvent eventT; + memset(&eventT, 0, sizeof(xEvent)); eventT.u.u.type = ResizeRequest; eventT.u.resizeRequest.window = pWin->drawable.id; eventT.u.resizeRequest.width = w; @@ -2359,6 +2305,7 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) ActuallyDoSomething: if (SubStrSend(pWin, pParent)) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = ConfigureNotify; event.u.configureNotify.window = pWin->drawable.id; if (pSib) @@ -2515,6 +2462,7 @@ ReparentWindow(WindowPtr pWin, WindowPtr pParent, if (WasMapped) UnmapWindow(pWin, FALSE); + memset(&event, 0, sizeof(xEvent)); event.u.u.type = ReparentNotify; event.u.reparent.window = pWin->drawable.id; event.u.reparent.parent = pParent->drawable.id; @@ -2649,7 +2597,7 @@ MapUnmapEventsEnabled(WindowPtr pWin) * MapNotify event is generated. *****/ -_X_EXPORT int +int MapWindow(WindowPtr pWin, ClientPtr client) { ScreenPtr pScreen; @@ -2675,6 +2623,7 @@ MapWindow(WindowPtr pWin, ClientPtr client) (RedirectSend(pParent) )) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = MapRequest; event.u.mapRequest.window = pWin->drawable.id; event.u.mapRequest.parent = pParent->drawable.id; @@ -2687,6 +2636,7 @@ MapWindow(WindowPtr pWin, ClientPtr client) pWin->mapped = TRUE; if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = MapNotify; event.u.mapNotify.window = pWin->drawable.id; event.u.mapNotify.override = pWin->overrideRedirect; @@ -2761,6 +2711,7 @@ MapSubwindows(WindowPtr pParent, ClientPtr client) { if (parentRedirect && !pWin->overrideRedirect) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = MapRequest; event.u.mapRequest.window = pWin->drawable.id; event.u.mapRequest.parent = pParent->drawable.id; @@ -2773,6 +2724,7 @@ MapSubwindows(WindowPtr pParent, ClientPtr client) pWin->mapped = TRUE; if (parentNotify || StrSend(pWin)) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = MapNotify; event.u.mapNotify.window = pWin->drawable.id; event.u.mapNotify.override = pWin->overrideRedirect; @@ -2822,6 +2774,7 @@ UnrealizeTree( WindowPtr pChild; UnrealizeWindowProcPtr Unrealize; MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; + int rc; Unrealize = pWin->drawable.pScreen->UnrealizeWindow; MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow; @@ -2835,9 +2788,10 @@ UnrealizeTree( #ifdef PANORAMIX if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { PanoramiXRes *win; - win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id, - XRT_WINDOW); - if(win) + rc = dixLookupResourceByType((pointer *)&win, + pChild->drawable.id, XRT_WINDOW, + serverClient, DixWriteAccess); + if (rc == Success) win->u.win.visibility = VisibilityNotViewable; } #endif @@ -2871,7 +2825,7 @@ UnrealizeTree( * generated. Cannot unmap a root window. *****/ -_X_EXPORT int +int UnmapWindow(WindowPtr pWin, Bool fromConfigure) { WindowPtr pParent; @@ -2885,6 +2839,7 @@ UnmapWindow(WindowPtr pWin, Bool fromConfigure) return(Success); if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) { + memset(&event, 0, sizeof(xEvent)); event.u.u.type = UnmapNotify; event.u.unmapNotify.window = pWin->drawable.id; event.u.unmapNotify.fromConfigure = fromConfigure; @@ -3067,7 +3022,7 @@ PointInWindowIsVisible(WindowPtr pWin, int x, int y) } -_X_EXPORT RegionPtr +RegionPtr NotClippedByChildren(WindowPtr pWin) { ScreenPtr pScreen; @@ -3091,17 +3046,17 @@ SendVisibilityNotify(WindowPtr pWin) unsigned int visibility; #endif xEvent event; - if (!MapUnmapEventsEnabled(pWin)) - return; #ifndef NO_XINERAMA_PORT visibility = pWin->visibility; #endif + if (!MapUnmapEventsEnabled(pWin)) + return; #ifdef PANORAMIX /* This is not quite correct yet, but it's close */ if(!noPanoramiXExtension) { PanoramiXRes *win; WindowPtr pWin2; - int i, Scrnum; + int rc, i, Scrnum; Scrnum = pWin->drawable.pScreen->myNum; @@ -3115,9 +3070,10 @@ SendVisibilityNotify(WindowPtr pWin) for(i = 0; i < PanoramiXNumScreens; i++) { if(i == Scrnum) continue; - pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW); + rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, + DixWriteAccess); - if (pWin2) { + if (rc == Success) { if(pWin2->visibility == VisibilityPartiallyObscured) return; @@ -3127,17 +3083,19 @@ SendVisibilityNotify(WindowPtr pWin) break; case VisibilityPartiallyObscured: if(Scrnum) { - pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW); - if (pWin2) pWin = pWin2; + rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient, + DixWriteAccess); + if (rc == Success) pWin = pWin2; } break; case VisibilityFullyObscured: for(i = 0; i < PanoramiXNumScreens; i++) { if(i == Scrnum) continue; - pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW); + rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, + DixWriteAccess); - if (pWin2) { + if (rc == Success) { if(pWin2->visibility != VisibilityFullyObscured) return; @@ -3151,6 +3109,7 @@ SendVisibilityNotify(WindowPtr pWin) } #endif + memset(&event, 0, sizeof(xEvent)); event.u.u.type = VisibilityNotify; event.u.visibility.window = pWin->drawable.id; event.u.visibility.state = visibility; @@ -3165,7 +3124,7 @@ static void DrawLogo( ); #endif -_X_EXPORT int +int dixSaveScreens(ClientPtr client, int on, int mode) { int rc, i, what, type; @@ -3282,7 +3241,7 @@ dixSaveScreens(ClientPtr client, int on, int mode) return Success; } -_X_EXPORT int +int SaveScreens(int on, int mode) { return dixSaveScreens(serverClient, on, mode); @@ -3335,8 +3294,8 @@ TileScreenSaver(int i, int kind) cm.height=16; cm.xhot=8; cm.yhot=8; - srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16); - mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16); + srcbits = xalloc( BitmapBytePad(32)*16); + mskbits = xalloc( BitmapBytePad(32)*16); if (!srcbits || !mskbits) { xfree(srcbits); @@ -3407,7 +3366,7 @@ TileScreenSaver(int i, int kind) * contain the structure. */ -_X_EXPORT WindowPtr +WindowPtr FindWindowWithOptional (WindowPtr w) { do @@ -3424,13 +3383,13 @@ FindWindowWithOptional (WindowPtr w) * release the optional record */ -_X_EXPORT void +void CheckWindowOptionalNeed (WindowPtr w) { WindowOptPtr optional; WindowOptPtr parentOptional; - if (!w->parent) + if (!w->parent || !w->optional) return; optional = w->optional; if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate]) @@ -3465,12 +3424,6 @@ CheckWindowOptionalNeed (WindowPtr w) pNode = pNode->next; } } - if (optional->access.nperm != 0 || - optional->access.ndeny != 0) - return; - - if (optional->geMasks != NULL) - return; parentOptional = FindWindowWithOptional(w)->optional; if (optional->visual != parentOptional->visual) @@ -3491,7 +3444,7 @@ CheckWindowOptionalNeed (WindowPtr w) * values. */ -_X_EXPORT Bool +Bool MakeWindowOptional (WindowPtr pWin) { WindowOptPtr optional; @@ -3499,7 +3452,7 @@ MakeWindowOptional (WindowPtr pWin) if (pWin->optional) return TRUE; - optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec)); + optional = xalloc (sizeof (WindowOptRec)); if (!optional) return FALSE; optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate]; @@ -3515,24 +3468,6 @@ MakeWindowOptional (WindowPtr pWin) optional->inputMasks = NULL; optional->deviceCursors = NULL; - optional->geMasks = - (GenericClientMasksPtr)xalloc(sizeof(GenericClientMasksRec)); - if (!optional->geMasks) - { - xfree(optional); - return FALSE; - } else { - int i; - optional->geMasks->geClients = 0; - for (i = 0; i < MAXEXTENSIONS; i++) - optional->geMasks->eventMasks[i] = 0; - } - - optional->access.nperm = 0; - optional->access.ndeny = 0; - optional->access.perm = NULL; - optional->access.deny = NULL; - optional->access.defaultRule = 0; parentOptional = FindWindowWithOptional(pWin)->optional; optional->visual = parentOptional->visual; if (!pWin->cursorIsNone) @@ -3563,7 +3498,7 @@ MakeWindowOptional (WindowPtr pWin) * Assumption: If there is a node for a device in the list, the device has a * cursor. If the cursor is set to None, it is inherited by the parent. */ -_X_EXPORT int +int ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor) @@ -3609,7 +3544,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, pWin->optional->deviceCursors = pNode->next; xfree(pNode); - return Success; + goto out; } } else @@ -3620,7 +3555,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, if (!pCursor) return Success; - pNewNode = (DevCursNodePtr)xalloc(sizeof(DevCursNodeRec)); + pNewNode = xalloc(sizeof(DevCursNodeRec)); pNewNode->dev = pDev; pNewNode->next = pWin->optional->deviceCursors; pWin->optional->deviceCursors = pNewNode; @@ -3654,6 +3589,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, } } +out: if (pWin->realized) WindowHasNewCursor(pWin); @@ -3668,7 +3604,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, } /* Get device cursor for given device or None if none is set */ -_X_EXPORT CursorPtr +CursorPtr WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) { DevCursorList pList; @@ -3774,7 +3710,7 @@ DrawLogo(WindowPtr pWin) int x, y; unsigned int width, height, size; GC *pGC; - int thin, gap, d31; + int rc, thin, gap, d31; DDXPointRec poly[4]; ChangeGCVal fore[2], back[2]; xrgb rgb[2]; @@ -3795,20 +3731,23 @@ DrawLogo(WindowPtr pWin) fore[0].val = pScreen->whitePixel; else fore[0].val = pScreen->blackPixel; - if ((pWin->backgroundState == BackgroundPixel) && - (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) { - Pixel querypixels[2]; - - querypixels[0] = fore[0].val; - querypixels[1] = pWin->background.pixel; - QueryColors(cmap, 2, querypixels, rgb); - if ((rgb[0].red == rgb[1].red) && - (rgb[0].green == rgb[1].green) && - (rgb[0].blue == rgb[1].blue)) { - if (fore[0].val == pScreen->blackPixel) - fore[0].val = pScreen->whitePixel; - else - fore[0].val = pScreen->blackPixel; + if (pWin->backgroundState == BackgroundPixel) { + rc = dixLookupResourceByType((pointer *)&cmap, wColormap(pWin), + RT_COLORMAP, serverClient, DixReadAccess); + if (rc == Success) { + Pixel querypixels[2]; + + querypixels[0] = fore[0].val; + querypixels[1] = pWin->background.pixel; + QueryColors(cmap, 2, querypixels, rgb); + if ((rgb[0].red == rgb[1].red) && + (rgb[0].green == rgb[1].green) && + (rgb[0].blue == rgb[1].blue)) { + if (fore[0].val == pScreen->blackPixel) + fore[0].val = pScreen->whitePixel; + else + fore[0].val = pScreen->blackPixel; + } } } fore[1].val = FillSolid; |