aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/dix')
-rw-r--r--xorg-server/dix/Makefile.am12
-rw-r--r--xorg-server/dix/Makefile.in66
-rw-r--r--xorg-server/dix/atom.c23
-rw-r--r--xorg-server/dix/colormap.c77
-rw-r--r--xorg-server/dix/cursor.c13
-rw-r--r--xorg-server/dix/deprecated.c27
-rw-r--r--xorg-server/dix/devices.c1185
-rw-r--r--xorg-server/dix/dispatch.c579
-rw-r--r--xorg-server/dix/dixfonts.c130
-rw-r--r--xorg-server/dix/dixutils.c55
-rw-r--r--xorg-server/dix/enterleave.c194
-rw-r--r--xorg-server/dix/enterleave.h6
-rw-r--r--xorg-server/dix/eventconvert.c718
-rw-r--r--xorg-server/dix/events.c3179
-rw-r--r--xorg-server/dix/extension.c28
-rw-r--r--xorg-server/dix/gc.c42
-rw-r--r--xorg-server/dix/getevents.c614
-rw-r--r--xorg-server/dix/globals.c61
-rw-r--r--xorg-server/dix/grabs.c152
-rw-r--r--xorg-server/dix/inpututils.c334
-rw-r--r--xorg-server/dix/main.c383
-rw-r--r--xorg-server/dix/pixmap.c8
-rw-r--r--xorg-server/dix/privates.c22
-rw-r--r--xorg-server/dix/property.c84
-rw-r--r--xorg-server/dix/protocol.txt30
-rw-r--r--xorg-server/dix/ptrveloc.c995
-rw-r--r--xorg-server/dix/registry.c2
-rw-r--r--xorg-server/dix/resource.c76
-rw-r--r--xorg-server/dix/selection.c6
-rw-r--r--xorg-server/dix/swaprep.c44
-rw-r--r--xorg-server/dix/swapreq.c11
-rw-r--r--xorg-server/dix/tables.c4
-rw-r--r--xorg-server/dix/window.c249
33 files changed, 5386 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 8b1bad8a3..a5a006e60 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>
@@ -253,7 +252,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)
{
@@ -275,7 +274,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)
@@ -311,7 +310,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);
@@ -357,7 +356,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]);
@@ -373,7 +372,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]);
@@ -502,7 +501,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;
@@ -527,7 +526,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;
@@ -744,7 +743,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;
@@ -800,7 +799,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)
@@ -894,9 +893,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,
@@ -911,9 +910,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)
{
@@ -963,7 +962,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);
@@ -985,7 +984,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;
@@ -1052,7 +1051,7 @@ FakeAllocColor (ColormapPtr pmap, xColorItem *item)
}
/* free a pixel value obtained from FakeAllocColor */
-_X_EXPORT void
+void
FakeFreeColor(ColormapPtr pmap, Pixel pixel)
{
VisualPtr pVisual;
@@ -1415,7 +1414,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;
@@ -1551,12 +1550,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;
}
@@ -1579,7 +1580,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);
}
@@ -1654,7 +1655,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);
}
@@ -1746,9 +1747,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);
@@ -1853,7 +1854,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);
@@ -2083,14 +2084,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]);
@@ -2206,7 +2206,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;
@@ -2400,7 +2400,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;
@@ -2673,8 +2673,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 7e16589da..414bd0404 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 PANORAMIX_DEBUG
@@ -130,19 +131,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"
@@ -159,7 +152,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
@@ -167,9 +162,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);
@@ -177,15 +172,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.
@@ -204,7 +199,7 @@ SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
checkForInput[1] = c1;
}
-_X_EXPORT void
+void
UpdateCurrentTime(void)
{
TimeStamp systime;
@@ -223,7 +218,7 @@ UpdateCurrentTime(void)
}
/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
-_X_EXPORT void
+void
UpdateCurrentTimeIf(void)
{
TimeStamp systime;
@@ -242,12 +237,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];
@@ -370,7 +365,7 @@ Dispatch(void)
nextFreeClientID = 1;
nClients = 0;
- clientReady = (int *) xalloc(sizeof(int) * MaxClients);
+ clientReady = xalloc(sizeof(int) * MaxClients);
if (!clientReady)
return;
@@ -437,12 +432,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,
@@ -490,7 +479,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);
@@ -509,7 +658,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)
@@ -552,7 +701,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,
@@ -577,6 +726,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);
@@ -755,7 +905,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],
@@ -838,6 +988,7 @@ ProcGetGeometry(ClientPtr client)
xGetGeometryReply rep;
int status;
+ memset(&rep, 0, sizeof(xGetGeometryReply));
if ((status = GetGeometry(client, &rep)) != Success)
return status;
@@ -859,6 +1010,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;
@@ -873,7 +1025,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)
@@ -881,7 +1033,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)
@@ -912,6 +1064,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;
@@ -926,7 +1079,7 @@ ProcInternAtom(ClientPtr client)
int
ProcGetAtomName(ClientPtr client)
{
- char *str;
+ const char *str;
xGetAtomNameReply reply;
int len;
REQUEST(xResourceReq);
@@ -935,8 +1088,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);
@@ -1031,6 +1185,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;
@@ -1111,12 +1266,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);
@@ -1124,7 +1280,7 @@ ProcCloseFont(ClientPtr client)
else
{
client->errorValue = stuff->id;
- return (BadFont);
+ return (rc == BadValue) ? BadFont : rc;
}
}
@@ -1167,14 +1323,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);
@@ -1208,7 +1364,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)
{
@@ -1376,7 +1532,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,
@@ -1401,7 +1557,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;
@@ -1651,7 +1807,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]);
@@ -1674,7 +1830,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]);
@@ -1762,7 +1918,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,
@@ -1906,8 +2062,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,
@@ -1926,9 +2082,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;
@@ -1944,35 +2102,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;
@@ -1995,7 +2178,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)
@@ -2006,7 +2189,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)
@@ -2033,7 +2216,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);
}
@@ -2405,8 +2588,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)
@@ -2550,7 +2732,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;
@@ -2569,7 +2751,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;
@@ -2619,7 +2801,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,
@@ -2633,7 +2815,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
@@ -2668,7 +2850,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)
@@ -2771,8 +2953,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)) )
@@ -2786,8 +2968,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);
@@ -3013,6 +3196,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;
@@ -3156,7 +3340,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)
{
@@ -3289,7 +3473,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);
@@ -3480,41 +3664,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;
}
/************************
@@ -3533,7 +3692,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);
@@ -3543,7 +3702,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);
@@ -3583,8 +3742,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);
@@ -3608,7 +3767,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)
@@ -3699,7 +3858,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";
@@ -3724,12 +3883,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;
@@ -3745,3 +3905,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 719bca469..7d7ae71de 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>
@@ -142,8 +137,9 @@ SetDefaultFont(char *defaultfontname)
(unsigned) strlen(defaultfontname), defaultfontname);
if (err != Success)
return FALSE;
- pf = (FontPtr) LookupIDByType(fid, RT_FONT);
- if (pf == (FontPtr) NULL)
+ err = dixLookupResourceByType((pointer *)&pf, fid, RT_FONT, serverClient,
+ DixReadAccess);
+ if (err != Success)
return FALSE;
defaultFont = pf;
return TRUE;
@@ -398,7 +394,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);
@@ -435,10 +431,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) {
@@ -449,8 +445,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);
@@ -684,7 +679,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);
}
@@ -739,7 +734,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;
@@ -795,12 +790,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);
@@ -821,7 +817,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);
@@ -860,10 +856,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;
@@ -1002,7 +997,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;
@@ -1051,6 +1046,7 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
err = AllocError;
break;
}
+ memset(reply + c->length, 0, length - c->length);
c->reply = reply;
c->length = length;
}
@@ -1061,9 +1057,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;
@@ -1101,8 +1097,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)
@@ -1136,10 +1132,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);
@@ -1207,17 +1202,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;
@@ -1239,12 +1235,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;
@@ -1326,7 +1321,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;
@@ -1336,7 +1331,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);
@@ -1492,17 +1487,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);
@@ -1518,7 +1514,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;
@@ -1527,7 +1523,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);
@@ -1664,7 +1660,7 @@ FreeFontPath(FontPathElementPtr *list, int n, Bool force)
}
FreeFPE(list[i]);
}
- xfree((char *) list);
+ xfree(list);
}
static FontPathElementPtr
@@ -1691,8 +1687,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;
@@ -1733,13 +1728,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);
@@ -1827,7 +1822,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;
@@ -1913,7 +1908,7 @@ InitFonts (void)
}
int
-GetDefaultPointSize ()
+GetDefaultPointSize (void)
{
return 120;
}
@@ -2020,12 +2015,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..90a2675c4 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;
-
- win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+ int rc, i;
- 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;
+ if(!XineramaSetWindowPntrs(pDev, pWin))
+ return;
- while(i--) {
- x = off_x - panoramiXdataPtr[i].x;
- y = off_y - panoramiXdataPtr[i].y;
+ i = PanoramiXNumScreens - 1;
- if(x || y)
- REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y);
+ REGION_COPY(pSprite->screen, &pSprite->Reg1,
+ &pSprite->windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
- REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1,
- &pSprite->windows[i]->borderSize);
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
- off_x = panoramiXdataPtr[i].x;
- off_y = panoramiXdataPtr[i].y;
- }
+ if(x || y)
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y);
- pSprite->hotLimits = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg1);
+ REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1,
+ &pSprite->windows[i]->borderSize);
- if(REGION_NUM_RECTS(&pSprite->Reg1) > 1)
- pSprite->hotShape = &pSprite->Reg1;
- else
- pSprite->hotShape = NullRegion;
-
- 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;
+
+ /* 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(&param, 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, &param);
+ 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,
+ &param, 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(&param, 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, &param, 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 9747b35a6..2912c1e85 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,7 @@
#include "exevents.h"
#include "exglobals.h"
#include "extnsionst.h"
+#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */
/* Number of motion history events to store. */
#define MOTION_HISTORY_SIZE 256
@@ -71,7 +72,7 @@
EventListPtr InputEventList = NULL;
int InputEventListLen = 0;
-_X_EXPORT int
+int
GetEventList(EventListPtr* list)
{
*list = InputEventList;
@@ -81,28 +82,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
@@ -112,14 +126,118 @@ key_autorepeats(DeviceIntPtr pDev, int key_code)
(1 << (key_code & 7)));
}
+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;
@@ -130,14 +248,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;
}
/**
@@ -165,21 +292,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);
}
@@ -190,7 +321,7 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
/**
* Allocate the motion history buffer.
*/
-_X_EXPORT void
+void
AllocateMotionHistory(DeviceIntPtr pDev)
{
int size;
@@ -204,7 +335,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;
@@ -226,7 +357,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)
{
@@ -248,7 +379,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);
@@ -286,7 +417,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++;
@@ -297,10 +428,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 */
@@ -332,7 +463,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++;
}
@@ -376,7 +507,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;
@@ -428,23 +559,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;
}
@@ -458,6 +581,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;
@@ -475,52 +601,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).
@@ -528,19 +614,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;
}
@@ -656,48 +749,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;
}
/**
@@ -713,32 +827,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);
}
@@ -764,98 +863,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];
-
- events = updateFromMaster(events, pDev, &numEvents);
+ num_events = 1;
- numEvents += countValuatorEvents(num_valuators);
+ events = updateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
-#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;
}
/**
@@ -877,8 +951,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 */
@@ -896,7 +970,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)
@@ -923,7 +997,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)
@@ -952,53 +1026,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)
@@ -1006,32 +1102,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;
}
@@ -1044,13 +1142,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)
@@ -1061,38 +1162,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;
}
@@ -1110,7 +1194,7 @@ PostSyntheticMotion(DeviceIntPtr pDev,
int screen,
unsigned long time)
{
- xEvent xE;
+ DeviceEvent ev;
#ifdef PANORAMIX
/* Translate back to the sprite screen since processInputProc
@@ -1122,11 +1206,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(&param, 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,
+ &param, (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 0527621e7..f96245a4b 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>
@@ -252,6 +139,8 @@ int main(int argc, char *argv[], char *envp[])
InitRegions();
+ pixman_disable_out_of_bounds_workaround();
+
CheckUserParameters(argc, argv, envp);
CheckUserAuthorization();
@@ -270,10 +159,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();
@@ -286,7 +175,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);
@@ -363,7 +252,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);
@@ -457,254 +345,3 @@ int main(int argc, char *argv[], char *envp[])
return(0);
}
-static int VendorRelease = VENDOR_RELEASE;
-static char *VendorString = VENDOR_NAME;
-
-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/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 e9d4e882f..37c8e5178 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"),
@@ -28,14 +28,15 @@
#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
@@ -52,31 +53,20 @@
* 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)
*
****************************************************************************/
/* 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*/
@@ -87,36 +77,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);
}
@@ -124,302 +119,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
@@ -440,41 +594,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;
}
@@ -483,17 +638,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;
}
@@ -503,9 +657,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;
@@ -513,7 +669,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;
@@ -530,7 +687,8 @@ ComputeAcceleration(
*/
static float
PolynomialAccelerationProfile(
- DeviceVelocityPtr pVel,
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
float velocity,
float ignored,
float acc)
@@ -545,18 +703,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);
@@ -574,7 +735,8 @@ ClassicProfile(
*/
static float
PowerProfile(
- DeviceVelocityPtr pVel,
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
float velocity,
float threshold,
float acc)
@@ -584,9 +746,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;
}
@@ -611,7 +773,8 @@ CalcPenumbralGradient(float x){
*/
static float
SimpleSmoothProfile(
- DeviceVelocityPtr pVel,
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
float velocity,
float threshold,
float acc)
@@ -636,7 +799,8 @@ SimpleSmoothProfile(
*/
static float
SmoothLinearProfile(
- DeviceVelocityPtr pVel,
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
float velocity,
float threshold,
float acc)
@@ -659,14 +823,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)
@@ -675,60 +840,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;
}
@@ -746,34 +924,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;
}
@@ -789,7 +967,7 @@ GetDevicePredictableAccelData(
*/
void
acceleratePointerPredictable(
- DeviceIntPtr pDev,
+ DeviceIntPtr dev,
int first_valuator,
int num_valuators,
int *valuators,
@@ -799,12 +977,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];
@@ -815,40 +999,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);
}
}
}
@@ -865,7 +1050,7 @@ acceleratePointerPredictable(
*/
void
acceleratePointerLightweight(
- DeviceIntPtr pDev,
+ DeviceIntPtr dev,
int first_valuator,
int num_valuators,
int *valuators,
@@ -890,48 +1075,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 e0b0decce..caff1cbff 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;
@@ -3088,17 +3043,17 @@ void
SendVisibilityNotify(WindowPtr pWin)
{
xEvent event;
- if (!MapUnmapEventsEnabled(pWin))
- return;
#ifndef NO_XINERAMA_PORT
unsigned int 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;
@@ -3112,9 +3067,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;
@@ -3124,17 +3080,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;
@@ -3148,6 +3106,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;
@@ -3162,7 +3121,7 @@ static void DrawLogo(
);
#endif
-_X_EXPORT int
+int
dixSaveScreens(ClientPtr client, int on, int mode)
{
int rc, i, what, type;
@@ -3279,7 +3238,7 @@ dixSaveScreens(ClientPtr client, int on, int mode)
return Success;
}
-_X_EXPORT int
+int
SaveScreens(int on, int mode)
{
return dixSaveScreens(serverClient, on, mode);
@@ -3332,8 +3291,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);
@@ -3404,7 +3363,7 @@ TileScreenSaver(int i, int kind)
* contain the structure.
*/
-_X_EXPORT WindowPtr
+WindowPtr
FindWindowWithOptional (WindowPtr w)
{
do
@@ -3421,13 +3380,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])
@@ -3462,12 +3421,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)
@@ -3488,7 +3441,7 @@ CheckWindowOptionalNeed (WindowPtr w)
* values.
*/
-_X_EXPORT Bool
+Bool
MakeWindowOptional (WindowPtr pWin)
{
WindowOptPtr optional;
@@ -3496,7 +3449,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];
@@ -3512,24 +3465,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)
@@ -3560,7 +3495,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)
@@ -3606,7 +3541,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin,
pWin->optional->deviceCursors = pNode->next;
xfree(pNode);
- return Success;
+ goto out;
}
} else
@@ -3617,7 +3552,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;
@@ -3651,6 +3586,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin,
}
}
+out:
if (pWin->realized)
WindowHasNewCursor(pWin);
@@ -3665,7 +3601,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;
@@ -3771,7 +3707,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];
@@ -3792,20 +3728,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;