diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2013-06-07 17:28:57 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2013-06-07 17:28:57 +0000 |
commit | c0190187060808fe0ad2a09b31f4244757572ff9 (patch) | |
tree | b028697436476ae3ff34218b0b233a233d8a7818 /xserver/dix | |
parent | 33eda071f5846d332b428de759c5b1649e9cf1ba (diff) |
Update to X server 1.14.1. Tested by many during t2k13. Thanks.
Diffstat (limited to 'xserver/dix')
31 files changed, 3198 insertions, 1534 deletions
diff --git a/xserver/dix/Makefile.in b/xserver/dix/Makefile.in index 09f1e2231..580e662e9 100644 --- a/xserver/dix/Makefile.in +++ b/xserver/dix/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.12.3 from Makefile.am. +# Makefile.in generated by automake 1.12.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. @@ -227,13 +227,9 @@ DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ -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@ @@ -255,6 +251,7 @@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ +GLX_SYS_LIBS = @GLX_SYS_LIBS@ GLX_TLS = @GLX_TLS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ @@ -279,6 +276,7 @@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ +LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ @@ -294,7 +292,6 @@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -393,6 +390,7 @@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ +XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ @@ -549,7 +547,7 @@ all: $(BUILT_SOURCES) .SUFFIXES: .SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -574,9 +572,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) +$(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): diff --git a/xserver/dix/Xserver-dtrace.h.in b/xserver/dix/Xserver-dtrace.h.in index daf3faf1d..60ebbcdd9 100644 --- a/xserver/dix/Xserver-dtrace.h.in +++ b/xserver/dix/Xserver-dtrace.h.in @@ -54,7 +54,8 @@ extern "C" { __dtrace_Xserver___resource__free(arg0, arg1, arg2, arg3) #define XSERVER_SEND_EVENT(arg0, arg1, arg2) \ __dtrace_Xserver___send__event(arg0, arg1, arg2) - +#define XSERVER_INPUT_EVENT(arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + __dtrace_Xserver___input__event(arg0, arg1, arg2, arg3, arg4, arg5, arg6) extern void __dtrace_Xserver___client__auth(int, string, pid_t, zoneid_t); extern void __dtrace_Xserver___client__connect(int, int); @@ -64,6 +65,8 @@ extern void __dtrace_Xserver___request__start(string, uint8_t, uint16_t, int, vo extern void __dtrace_Xserver___resource__alloc(uint32_t, uint32_t, void *, string); extern void __dtrace_Xserver___resource__free(uint32_t, uint32_t, void *, string); extern void __dtrace_Xserver___send__event(int, uint8_t, void *); +extern void __dtrace_Xserver___input__event(int, uint16_t, uint32_t, uint32_t, int8_t, uint8_t *, double *); + #else @@ -75,6 +78,7 @@ extern void __dtrace_Xserver___send__event(int, uint8_t, void *); #define XSERVER_RESOURCE_ALLOC(arg0, arg1, arg2, arg3) #define XSERVER_RESOURCE_FREE(arg0, arg1, arg2, arg3) #define XSERVER_SEND_EVENT(arg0, arg1, arg2) +#define XSERVER_INPUT_EVENT(arg0, arg1, arg2, arg3, arg4, arg5, arg6) #endif @@ -86,6 +90,7 @@ extern void __dtrace_Xserver___send__event(int, uint8_t, void *); #define XSERVER_RESOURCE_ALLOC_ENABLED() (1) #define XSERVER_RESOURCE_FREE_ENABLED() (1) #define XSERVER_SEND_EVENT_ENABLED() (1) +#define XSERVER_INPUT_EVENT_ENABLED() (1) #ifdef __cplusplus } diff --git a/xserver/dix/Xserver.d b/xserver/dix/Xserver.d index 2ad337351..248d48e24 100644 --- a/xserver/dix/Xserver.d +++ b/xserver/dix/Xserver.d @@ -48,6 +48,8 @@ provider Xserver { probe resource__free(uint32_t, uint32_t, void *, string); /* client id, event type, event* */ probe send__event(int, uint8_t, void *); + /* deviceid, type, button/keycode/touchid, flags, nvalues, mask, values */ + probe input__event(int, int, uint32_t, uint32_t, int8_t, uint8_t*, double*); }; #pragma D attributes Unstable/Unstable/Common provider Xserver provider diff --git a/xserver/dix/colormap.c b/xserver/dix/colormap.c index 10306285e..39fddc9b1 100644 --- a/xserver/dix/colormap.c +++ b/xserver/dix/colormap.c @@ -450,15 +450,15 @@ FreeColormap(pointer value, XID mid) static int TellNoMap(WindowPtr pwin, Colormap * pmid) { - xEvent xE; - if (wColormap(pwin) == *pmid) { /* This should be call to DeliverEvent */ + xEvent xE = { + .u.colormap.window = pwin->drawable.id, + .u.colormap.colormap = None, + .u.colormap.new = TRUE, + .u.colormap.state = ColormapUninstalled + }; xE.u.u.type = ColormapNotify; - xE.u.colormap.window = pwin->drawable.id; - xE.u.colormap.colormap = None; - xE.u.colormap.new = TRUE; - xE.u.colormap.state = ColormapUninstalled; #ifdef PANORAMIX if (noPanoramiXExtension || !pwin->drawable.pScreen->myNum) #endif @@ -477,7 +477,6 @@ int TellLostMap(WindowPtr pwin, pointer value) { Colormap *pmid = (Colormap *) value; - xEvent xE; #ifdef PANORAMIX if (!noPanoramiXExtension && pwin->drawable.pScreen->myNum) @@ -485,11 +484,13 @@ TellLostMap(WindowPtr pwin, pointer value) #endif if (wColormap(pwin) == *pmid) { /* This should be call to DeliverEvent */ + xEvent xE = { + .u.colormap.window = pwin->drawable.id, + .u.colormap.colormap = *pmid, + .u.colormap.new = FALSE, + .u.colormap.state = ColormapUninstalled + }; xE.u.u.type = ColormapNotify; - xE.u.colormap.window = pwin->drawable.id; - xE.u.colormap.colormap = *pmid; - xE.u.colormap.new = FALSE; - xE.u.colormap.state = ColormapUninstalled; DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); } @@ -501,7 +502,6 @@ int TellGainedMap(WindowPtr pwin, pointer value) { Colormap *pmid = (Colormap *) value; - xEvent xE; #ifdef PANORAMIX if (!noPanoramiXExtension && pwin->drawable.pScreen->myNum) @@ -509,11 +509,13 @@ TellGainedMap(WindowPtr pwin, pointer value) #endif if (wColormap(pwin) == *pmid) { /* This should be call to DeliverEvent */ + xEvent xE = { + .u.colormap.window = pwin->drawable.id, + .u.colormap.colormap = *pmid, + .u.colormap.new = FALSE, + .u.colormap.state = ColormapInstalled + }; xE.u.u.type = ColormapNotify; - xE.u.colormap.window = pwin->drawable.id; - xE.u.colormap.colormap = *pmid; - xE.u.colormap.new = FALSE; - xE.u.colormap.state = ColormapInstalled; DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); } @@ -576,7 +578,7 @@ CopyFree(int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst) int nalloc; switch (channel) { - default: /* so compiler can see that everything gets initialized */ + default: /* so compiler can see that everything gets initialized */ case REDMAP: ppix = (pmapSrc->clientPixelsRed)[client]; npix = (pmapSrc->numPixelsRed)[client]; @@ -653,18 +655,18 @@ FreeCell(ColormapPtr pmap, Pixel i, int channel) int *pCount; switch (channel) { - default: /* so compiler can see that everything gets initialized */ + default: /* so compiler can see that everything gets initialized */ case PSEUDOMAP: case REDMAP: - pent = (EntryPtr) & pmap->red[i]; + pent = (EntryPtr) &pmap->red[i]; pCount = &pmap->freeRed; break; case GREENMAP: - pent = (EntryPtr) & pmap->green[i]; + pent = (EntryPtr) &pmap->green[i]; pCount = &pmap->freeGreen; break; case BLUEMAP: - pent = (EntryPtr) & pmap->blue[i]; + pent = (EntryPtr) &pmap->blue[i]; pCount = &pmap->freeBlue; break; } @@ -1398,7 +1400,7 @@ QueryColors(ColormapPtr pmap, int count, Pixel * ppixIn, xrgb * prgbList, errVal = BadValue; } else { - pent = (EntryPtr) & pmap->red[pixel]; + pent = (EntryPtr) &pmap->red[pixel]; if (pent->fShared) { prgb->red = pent->co.shco.red->color; prgb->green = pent->co.shco.green->color; @@ -2146,7 +2148,7 @@ FreeCo(ColormapPtr pmap, int client, int color, int npixIn, Pixel * ppixIn, ppixClient = pmap->clientPixelsBlue[client]; npixClient = pmap->numPixelsBlue[client]; break; - default: /* so compiler can see that everything gets initialized */ + default: /* so compiler can see that everything gets initialized */ case PSEUDOMAP: cmask = ~((Pixel) 0); rgbbad = 0; diff --git a/xserver/dix/devices.c b/xserver/dix/devices.c index 012550443..be236dd70 100644 --- a/xserver/dix/devices.c +++ b/xserver/dix/devices.c @@ -84,6 +84,7 @@ SOFTWARE. #include "enterleave.h" /* for EnterWindow() */ #include "xserver-properties.h" #include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ +#include "syncsrv.h" /** @file * This file handles input device-related stuff. @@ -92,9 +93,10 @@ SOFTWARE. static void RecalculateMasterButtons(DeviceIntPtr slave); static void -DeviceSetTransform(DeviceIntPtr dev, float *transform) +DeviceSetTransform(DeviceIntPtr dev, float *transform_data) { struct pixman_f_transform scale; + struct pixman_f_transform transform; double sx, sy; int x, y; @@ -121,16 +123,21 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform) /* transform */ for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - dev->transform.m[y][x] = *transform++; + transform.m[y][x] = *transform_data++; - pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform); + pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform); /* scale */ pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy); scale.m[0][2] = -dev->valuator->axes[0].min_value / sx; scale.m[1][2] = -dev->valuator->axes[1].min_value / sy; - pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale); + pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale); + + /* remove translation component for relative movements */ + dev->relative_transform = transform; + dev->relative_transform.m[0][2] = 0; + dev->relative_transform.m[1][2] = 0; } /** @@ -144,9 +151,11 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1) return BadValue; - /* Don't allow disabling of VCP/VCK */ - if ((dev == inputInfo.pointer ||dev == - inputInfo.keyboard) &&!(*(CARD8 *) prop->data)) + /* Don't allow disabling of VCP/VCK or XTest devices */ + if ((dev == inputInfo.pointer || + dev == inputInfo.keyboard || + IsXTestDevice(dev, NULL)) + &&!(*(CARD8 *) prop->data)) return BadAccess; if (!checkonly) { @@ -177,12 +186,9 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, /* Pair the keyboard to the pointer device. Keyboard events will follow the * pointer sprite. Only applicable for master devices. - * If the client is set, the request to pair comes from some client. In this - * case, we need to check for access. If the client is NULL, it's from an - * internal automatic pairing, we must always permit this. */ static int -PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) +PairDevices(DeviceIntPtr ptr, DeviceIntPtr kbd) { if (!ptr) return BadDevice; @@ -248,13 +254,17 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) if (devid >= MAXDEVICES) return (DeviceIntPtr) NULL; - dev = - _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) + - sizeof(SpriteInfoRec), - sizeof(DeviceIntRec) + - sizeof(SpriteInfoRec), - offsetof(DeviceIntRec, devPrivates), - PRIVATE_DEVICE); + dev = calloc(1, + sizeof(DeviceIntRec) + + sizeof(SpriteInfoRec)); + if (!dev) + return (DeviceIntPtr) NULL; + + if (!dixAllocatePrivates(&dev->devPrivates, PRIVATE_DEVICE)) { + free(dev); + return NULL; + } + if (!dev) return (DeviceIntPtr) NULL; @@ -279,11 +289,12 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) dev->coreEvents = TRUE; /* sprite defaults */ - dev->spriteInfo = (SpriteInfoPtr) & dev[1]; + dev->spriteInfo = (SpriteInfoPtr) &dev[1]; /* security creation/labeling check */ if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) { + dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); free(dev); return NULL; } @@ -303,6 +314,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) /* unity matrix */ memset(transform, 0, sizeof(transform)); transform[0] = transform[4] = transform[8] = 1.0f; + dev->relative_transform.m[0][0] = 1.0; + dev->relative_transform.m[1][1] = 1.0; + dev->relative_transform.m[2][2] = 1.0; + dev->scale_and_transform = dev->relative_transform; XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), XIGetKnownProperty(XATOM_FLOAT), 32, @@ -318,15 +333,14 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) void SendDevicePresenceEvent(int deviceid, int type) { - DeviceIntRec dummyDev; - devicePresenceNotify ev; + DeviceIntRec dummyDev = { .id = XIAllDevices }; + devicePresenceNotify ev = { + .type = DevicePresenceNotify, + .time = currentTime.milliseconds, + .devchange = type, + .deviceid = deviceid + }; - 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); } @@ -364,13 +378,12 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) /* mode doesn't matter */ EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor); } - else if ((other = NextFreePointerDevice()) == NULL) { - ErrorF("[dix] cannot find pointer to pair with. " - "This is a bug.\n"); - return FALSE; + else { + other = NextFreePointerDevice(); + BUG_RETURN_VAL_MSG(other == NULL, FALSE, + "[dix] cannot find pointer to pair with.\n"); + PairDevices(other, dev); } - else - PairDevices(NULL, other, dev); } else { if (dev->coreEvents) @@ -406,9 +419,13 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) RecalculateMasterButtons(dev); + /* initialise an idle timer for this device*/ + dev->idle_counter = SyncInitDeviceIdleTime(dev); + return TRUE; } + /** * Switch a device off through the driver and push it onto the off_devices * list. A device will not send events while disabled. All clients are @@ -427,11 +444,19 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) BOOL enabled; int flags[MAXDEVICES] = { 0 }; + if (!dev->enabled) + return TRUE; + for (prev = &inputInfo.devices; *prev && (*prev != dev); prev = &(*prev)->next); if (*prev != dev) return FALSE; + TouchEndPhysicallyActiveTouches(dev); + ReleaseButtonsAndKeys(dev); + SyncRemoveDeviceIdleTime(dev->idle_counter); + dev->idle_counter = NULL; + /* float attached devices */ if (IsMaster(dev)) { for (other = inputInfo.devices; other; other = other->next) { @@ -449,18 +474,19 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) } if (IsMaster(dev) && dev->spriteInfo->sprite) { - for (other = inputInfo.devices; other; other = other->next) { - if (other->spriteInfo->paired == dev) { - ErrorF("[dix] cannot disable device, still paired. " - "This is a bug. \n"); - return FALSE; - } - } + for (other = inputInfo.devices; other; other = other->next) + if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner) + DisableDevice(other, sendevent); } + if (dev->spriteInfo->paired) + dev->spriteInfo->paired = NULL; + (void) (*dev->deviceProc) (dev, DEVICE_OFF); dev->enabled = FALSE; + FreeSprite(dev); + /* now that the device is disabled, we can reset the signal handler's * last.slave */ OsBlockSignals(); @@ -492,6 +518,32 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) return TRUE; } +void +DisableAllDevices(void) +{ + DeviceIntPtr dev, tmp; + + /* Disable slave devices first, excluding XTest devices */ + nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { + if (!IsXTestDevice(dev, NULL) && !IsMaster(dev)) + DisableDevice(dev, FALSE); + } + /* Disable XTest devices */ + nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { + if (!IsMaster(dev)) + DisableDevice(dev, FALSE); + } + /* master keyboards need to be disabled first */ + nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { + if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev)) + DisableDevice(dev, FALSE); + } + nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { + if (dev->enabled) + DisableDevice(dev, FALSE); + } +} + /** * Initialise a new device through the driver and tell all clients about the * new device. @@ -905,7 +957,7 @@ CloseDevice(DeviceIntPtr dev) free(dev->name); - classes = (ClassesPtr) & dev->key; + classes = (ClassesPtr) &dev->key; FreeAllDeviceClasses(classes); if (IsMaster(dev)) { @@ -914,12 +966,7 @@ CloseDevice(DeviceIntPtr dev) free(classes); } - if (DevHasCursor(dev) && dev->spriteInfo->sprite) { - if (dev->spriteInfo->sprite->current) - FreeCursor(dev->spriteInfo->sprite->current, None); - free(dev->spriteInfo->sprite->spriteTrace); - free(dev->spriteInfo->sprite); - } + FreeSprite(dev); /* a client may have the device set as client pointer */ for (j = 0; j < currentMaxClients; j++) { @@ -937,7 +984,8 @@ CloseDevice(DeviceIntPtr dev) free(dev->last.touches[j].valuators); free(dev->last.touches); dev->config_info = NULL; - dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE); + dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); + free(dev); } /** @@ -1008,6 +1056,25 @@ CloseDownDevices(void) } /** + * Signal all devices that we're in the process of aborting. + * This function is called from a signal handler. + */ +void +AbortDevices(void) +{ + DeviceIntPtr dev; + nt_list_for_each_entry(dev, inputInfo.devices, next) { + if (!IsMaster(dev)) + (*dev->deviceProc) (dev, DEVICE_ABORT); + } + + nt_list_for_each_entry(dev, inputInfo.off_devices, next) { + if (!IsMaster(dev)) + (*dev->deviceProc) (dev, DEVICE_ABORT); + } +} + +/** * Remove the cursor sprite for all devices. This needs to be done before any * resources are freed or any device is deleted. */ @@ -1323,13 +1390,10 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, /* global list of acceleration schemes */ ValuatorAccelerationRec pointerAccelerationScheme[] = { - {PtrAccelNoOp, NULL, NULL, NULL, NULL} - , + {PtrAccelNoOp, NULL, NULL, NULL, NULL}, {PtrAccelPredictable, acceleratePointerPredictable, NULL, - InitPredictableAccelerationScheme, AccelerationDefaultCleanup} - , - {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL} - , + InitPredictableAccelerationScheme, AccelerationDefaultCleanup}, + {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL}, {-1, NULL, NULL, NULL, NULL} /* terminator */ }; @@ -1366,8 +1430,7 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme) if (pointerAccelerationScheme[i].AccelInitProc) { if (!pointerAccelerationScheme[i].AccelInitProc(dev, - &pointerAccelerationScheme - [i])) { + &pointerAccelerationScheme[i])) { return FALSE; } } @@ -1640,9 +1703,11 @@ ProcSetModifierMapping(ClientPtr client) bytes_to_int32(sizeof(xSetModifierMappingReq)))) return BadLength; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; + rep = (xSetModifierMappingReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0 + }; rc = change_modmap(client, PickKeyboard(client), (KeyCode *) &stuff[1], stuff->numKeyPerModifier); @@ -1670,15 +1735,16 @@ ProcGetModifierMapping(ClientPtr client) generate_modkeymap(client, PickKeyboard(client), &modkeymap, &max_keys_per_mod); - memset(&rep, 0, sizeof(xGetModifierMappingReply)); - rep.type = X_Reply; - rep.numKeyPerModifier = max_keys_per_mod; - rep.sequenceNumber = client->sequence; + rep = (xGetModifierMappingReply) { + .type = X_Reply, + .numKeyPerModifier = max_keys_per_mod, + .sequenceNumber = client->sequence, /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ - rep.length = max_keys_per_mod << 1; + .length = max_keys_per_mod << 1 + }; WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); - (void) WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); + WriteToClient(client, max_keys_per_mod * 8, modkeymap); free(modkeymap); @@ -1759,10 +1825,13 @@ ProcSetPointerMapping(ClientPtr client) if (client->req_len != bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) return BadLength; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.success = MappingSuccess; + + rep = (xSetPointerMappingReply) { + .type = X_Reply, + .success = MappingSuccess, + .sequenceNumber = client->sequence, + .length = 0 + }; map = (BYTE *) &stuff[1]; /* So we're bounded here by the number of core buttons. This check @@ -1831,12 +1900,13 @@ ProcGetKeyboardMapping(ClientPtr client) if (!syms) return BadAlloc; - memset(&rep, 0, sizeof(xGetKeyboardMappingReply)); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.keySymsPerKeyCode = syms->mapWidth; - /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ - rep.length = syms->mapWidth * stuff->count; + rep = (xGetKeyboardMappingReply) { + .type = X_Reply, + .keySymsPerKeyCode = syms->mapWidth, + .sequenceNumber = client->sequence, + /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ + .length = syms->mapWidth * stuff->count + }; WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; WriteSwappedDataToClient(client, @@ -1858,6 +1928,7 @@ ProcGetPointerMapping(ClientPtr client) * the ClientPointer could change. */ DeviceIntPtr ptr = PickPointer(client); ButtonClassPtr butc = ptr->button; + int nElts; int rc; REQUEST_SIZE_MATCH(xReq); @@ -1866,13 +1937,16 @@ ProcGetPointerMapping(ClientPtr client) if (rc != Success) return rc; - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.nElts = (butc) ? butc->numButtons : 0; - rep.length = ((unsigned) rep.nElts + (4 - 1)) / 4; + nElts = (butc) ? butc->numButtons : 0; + rep = (xGetPointerMappingReply) { + .type = X_Reply, + .nElts = nElts, + .sequenceNumber = client->sequence, + .length = ((unsigned) nElts + (4 - 1)) / 4 + }; WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); if (butc) - WriteToClient(client, (int) rep.nElts, (char *) &butc->map[1]); + WriteToClient(client, nElts, &butc->map[1]); return Success; } @@ -2118,15 +2192,17 @@ ProcGetKeyboardControl(ClientPtr client) if (rc != Success) return rc; - rep.type = X_Reply; - rep.length = 5; - rep.sequenceNumber = client->sequence; - rep.globalAutoRepeat = ctrl->autoRepeat; - rep.keyClickPercent = ctrl->click; - rep.bellPercent = ctrl->bell; - rep.bellPitch = ctrl->bell_pitch; - rep.bellDuration = ctrl->bell_duration; - rep.ledMask = ctrl->leds; + rep = (xGetKeyboardControlReply) { + .type = X_Reply, + .globalAutoRepeat = ctrl->autoRepeat, + .sequenceNumber = client->sequence, + .length = 5, + .ledMask = ctrl->leds, + .keyClickPercent = ctrl->click, + .bellPercent = ctrl->bell, + .bellPitch = ctrl->bell_pitch, + .bellDuration = ctrl->bell_duration + }; for (i = 0; i < 32; i++) rep.map[i] = ctrl->autoRepeats[i]; WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep); @@ -2261,12 +2337,14 @@ ProcGetPointerControl(ClientPtr client) if (rc != Success) return rc; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.threshold = ctrl->threshold; - rep.accelNumerator = ctrl->num; - rep.accelDenominator = ctrl->den; + rep = (xGetPointerControlReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .accelNumerator = ctrl->num, + .accelDenominator = ctrl->den, + .threshold = ctrl->threshold + }; WriteReplyToClient(client, sizeof(xGenericReply), &rep); return Success; } @@ -2310,8 +2388,10 @@ ProcGetMotionEvents(ClientPtr client) if (mouse->valuator->motionHintWindow) MaybeStopHint(mouse, client); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; + rep = (xGetMotionEventsReply) { + .type = X_Reply, + .sequenceNumber = client->sequence + }; nEvents = 0; start = ClientTimeToServerTime(stuff->start); stop = ClientTimeToServerTime(stuff->stop); @@ -2359,20 +2439,23 @@ ProcQueryKeymap(ClientPtr client) CARD8 *down = keybd->key->down; REQUEST_SIZE_MATCH(xReq); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 2; + rep = (xQueryKeymapReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 2 + }; rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); - if (rc != Success && rc != BadAccess) + /* If rc is Success, we're allowed to copy out the keymap. + * If it's BadAccess, we leave it empty & lie to the client. + */ + if (rc == Success) { + for (i = 0; i < 32; i++) + rep.map[i] = down[i]; + } + else if (rc != BadAccess) return rc; - for (i = 0; i < 32; i++) - rep.map[i] = down[i]; - - if (rc == BadAccess) - memset(rep.map, 0, 32); - WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); return Success; @@ -2406,18 +2489,17 @@ RecalculateMasterButtons(DeviceIntPtr slave) if (master->button && master->button->numButtons != maxbuttons) { int i; - DeviceChangedEvent event; - - memset(&event, 0, sizeof(event)); + DeviceChangedEvent event = { + .header = ET_Internal, + .type = ET_DeviceChanged, + .time = GetTimeInMillis(), + .deviceid = master->id, + .flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE, + .buttons.num_buttons = maxbuttons + }; master->button->numButtons = maxbuttons; - event.header = ET_Internal; - event.type = ET_DeviceChanged; - event.time = GetTimeInMillis(); - 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)); @@ -2630,6 +2712,8 @@ AllocDevicePair(ClientPtr client, const char *name, *ptr = *keybd = NULL; + XkbInitPrivates(); + pointer = AddInputDevice(client, ptr_proc, TRUE); if (!pointer) diff --git a/xserver/dix/dispatch.c b/xserver/dix/dispatch.c index d97180548..8d6173525 100644 --- a/xserver/dix/dispatch.c +++ b/xserver/dix/dispatch.c @@ -223,7 +223,11 @@ UpdateCurrentTimeIf(void) #define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ #define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ +#if defined(WIN32) && !defined(__CYGWIN__) +Bool SmartScheduleDisable = TRUE; +#else Bool SmartScheduleDisable = FALSE; +#endif long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; @@ -466,8 +470,6 @@ Dispatch(void) static int VendorRelease = VENDOR_RELEASE; static char *VendorString = VENDOR_NAME; -static const int padlength[4] = { 0, 3, 2, 1 }; - void SetVendorRelease(int release) { @@ -528,7 +530,7 @@ CreateConnectionBlock(void) memmove(pBuf, VendorString, (int) setup.nbytesVendor); sizesofar += setup.nbytesVendor; pBuf += setup.nbytesVendor; - i = padlength[setup.nbytesVendor & 3]; + i = padding_for_int32(setup.nbytesVendor); sizesofar += i; while (--i >= 0) *pBuf++ = 0; @@ -926,10 +928,9 @@ GetGeometry(ClientPtr client, xGetGeometryReply * rep) int ProcGetGeometry(ClientPtr client) { - xGetGeometryReply rep; + xGetGeometryReply rep = { .type = X_Reply }; int status; - memset(&rep, 0, sizeof(xGetGeometryReply)); if ((status = GetGeometry(client, &rep)) != Success) return status; @@ -951,14 +952,13 @@ 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 = pWin->drawable.pScreen->root->drawable.id; - reply.sequenceNumber = client->sequence; - if (pWin->parent) - reply.parent = pWin->parent->drawable.id; - else - reply.parent = (Window) None; + + reply = (xQueryTreeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .root = pWin->drawable.pScreen->root->drawable.id, + .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None + }; pHead = RealChildHead(pWin); for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) numChildren++; @@ -1003,13 +1003,12 @@ ProcInternAtom(ClientPtr client) tchar = (char *) &stuff[1]; atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); if (atom != BAD_RESOURCE) { - xInternAtomReply reply; - - memset(&reply, 0, sizeof(xInternAtomReply)); - reply.type = X_Reply; - reply.length = 0; - reply.sequenceNumber = client->sequence; - reply.atom = atom; + xInternAtomReply reply = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .atom = atom + }; WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); return Success; } @@ -1021,21 +1020,21 @@ int ProcGetAtomName(ClientPtr client) { const char *str; - xGetAtomNameReply reply; - int len; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); if ((str = NameForAtom(stuff->id))) { - len = strlen(str); - memset(&reply, 0, sizeof(xGetAtomNameReply)); - reply.type = X_Reply; - reply.length = bytes_to_int32(len); - reply.sequenceNumber = client->sequence; - reply.nameLength = len; + int len = strlen(str); + xGetAtomNameReply reply = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(len), + .nameLength = len + }; + WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); - (void) WriteToClient(client, len, str); + WriteToClient(client, len, str); return Success; } else { @@ -1123,10 +1122,12 @@ 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; + + rep = (xTranslateCoordsReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0 + }; if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) { rep.sameScreen = xFalse; rep.child = None; @@ -1288,17 +1289,19 @@ ProcQueryTextExtents(ClientPtr client) } if (!QueryTextExtents(pFont, length, (unsigned char *) &stuff[1], &info)) return BadAlloc; - reply.type = X_Reply; - reply.length = 0; - reply.sequenceNumber = client->sequence; - reply.drawDirection = info.drawDirection; - reply.fontAscent = info.fontAscent; - reply.fontDescent = info.fontDescent; - reply.overallAscent = info.overallAscent; - reply.overallDescent = info.overallDescent; - reply.overallWidth = info.overallWidth; - reply.overallLeft = info.overallLeft; - reply.overallRight = info.overallRight; + reply = (xQueryTextExtentsReply) { + .type = X_Reply, + .drawDirection = info.drawDirection, + .sequenceNumber = client->sequence, + .length = 0, + .fontAscent = info.fontAscent, + .fontDescent = info.fontDescent, + .overallAscent = info.overallAscent, + .overallDescent = info.overallDescent, + .overallWidth = info.overallWidth, + .overallLeft = info.overallLeft, + .overallRight = info.overallRight + }; WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); return Success; } @@ -2143,8 +2146,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, BitsPerPixel(pDraw->depth), ClientOrder(client)); /* Don't split me, gcc pukes when you do */ - (void) WriteToClient(client, - (int) (nlines * widthBytesLine), pBuf); + WriteToClient(client, (int) (nlines * widthBytesLine), pBuf); } linesDone += nlines; } @@ -2179,9 +2181,8 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, 1, ClientOrder(client)); /* Don't split me, gcc pukes when you do */ - (void) WriteToClient(client, - (int) (nlines * widthBytesLine), - pBuf); + WriteToClient(client, (int) (nlines * widthBytesLine), + pBuf); } linesDone += nlines; } @@ -2453,7 +2454,7 @@ ProcListInstalledColormaps(ClientPtr client) preply->type = X_Reply; preply->sequenceNumber = client->sequence; nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) - (pWin->drawable.pScreen, (Colormap *) & preply[1]); + (pWin->drawable.pScreen, (Colormap *) &preply[1]); preply->nColormaps = nummaps; preply->length = nummaps; WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply); @@ -2468,7 +2469,6 @@ ProcAllocColor(ClientPtr client) { ColormapPtr pmap; int rc; - xAllocColorReply acr; REQUEST(xAllocColorReq); @@ -2476,13 +2476,15 @@ ProcAllocColor(ClientPtr client) rc = dixLookupResourceByType((pointer *) &pmap, stuff->cmap, RT_COLORMAP, client, DixAddAccess); if (rc == Success) { - acr.type = X_Reply; - acr.length = 0; - acr.sequenceNumber = client->sequence; - acr.red = stuff->red; - acr.green = stuff->green; - acr.blue = stuff->blue; - acr.pixel = 0; + xAllocColorReply acr = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .red = stuff->red, + .green = stuff->green, + .blue = stuff->blue, + .pixel = 0 + }; if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, &acr.pixel, client->index))) return rc; @@ -2511,12 +2513,11 @@ ProcAllocNamedColor(ClientPtr client) rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP, client, DixAddAccess); if (rc == Success) { - xAllocNamedColorReply ancr; - - ancr.type = X_Reply; - ancr.length = 0; - ancr.sequenceNumber = client->sequence; - + xAllocNamedColorReply ancr = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0 + }; if (OsLookupColor (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) { @@ -2557,7 +2558,6 @@ ProcAllocColorCells(ClientPtr client) rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP, client, DixAddAccess); if (rc == Success) { - xAllocColorCellsReply accr; int npixels, nmasks; long length; Pixel *ppixels, *pmasks; @@ -2587,11 +2587,13 @@ ProcAllocColorCells(ClientPtr client) if (noPanoramiXExtension || !pcmp->pScreen->myNum) #endif { - accr.type = X_Reply; - accr.length = bytes_to_int32(length); - accr.sequenceNumber = client->sequence; - accr.nPixels = npixels; - accr.nMasks = nmasks; + xAllocColorCellsReply accr = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(length), + .nPixels = npixels, + .nMasks = nmasks + }; WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr); client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; WriteSwappedDataToClient(client, length, ppixels); @@ -2631,9 +2633,11 @@ ProcAllocColorPlanes(ClientPtr client) client->errorValue = stuff->contiguous; return BadValue; } - acpr.type = X_Reply; - acpr.sequenceNumber = client->sequence; - acpr.nPixels = npixels; + acpr = (xAllocColorPlanesReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .nPixels = npixels + }; length = (long) npixels *sizeof(Pixel); ppixels = malloc(length); @@ -2771,11 +2775,12 @@ ProcQueryColors(ClientPtr client) free(prgbs); return rc; } - memset(&qcr, 0, sizeof(xQueryColorsReply)); - qcr.type = X_Reply; - qcr.length = bytes_to_int32(count * sizeof(xrgb)); - qcr.sequenceNumber = client->sequence; - qcr.nColors = count; + qcr = (xQueryColorsReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(count * sizeof(xrgb)), + .nColors = count + }; WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); if (count) { client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; @@ -2803,17 +2808,22 @@ ProcLookupColor(ClientPtr client) rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP, client, DixReadAccess); if (rc == Success) { - xLookupColorReply lcr; + CARD16 exactRed, exactGreen, exactBlue; if (OsLookupColor (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, - &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) { - lcr.type = X_Reply; - lcr.length = 0; - lcr.sequenceNumber = client->sequence; - lcr.screenRed = lcr.exactRed; - lcr.screenGreen = lcr.exactGreen; - lcr.screenBlue = lcr.exactBlue; + &exactRed, &exactGreen, &exactBlue)) { + xLookupColorReply lcr = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .exactRed = exactRed, + .exactGreen = exactGreen, + .exactBlue = exactBlue, + .screenRed = exactRed, + .screenGreen = exactGreen, + .screenBlue = exactBlue + }; (*pcmp->pScreen->ResolveColor) (&lcr.screenRed, &lcr.screenGreen, &lcr.screenBlue, pcmp->pVisual); @@ -2993,12 +3003,13 @@ 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; - reply.width = stuff->width; - reply.height = stuff->height; + reply = (xQueryBestSizeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .width = stuff->width, + .height = stuff->height + }; WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); return Success; } @@ -3078,13 +3089,15 @@ ProcGetScreenSaver(ClientPtr client) return rc; } - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.timeout = ScreenSaverTime / MILLI_PER_SECOND; - rep.interval = ScreenSaverInterval / MILLI_PER_SECOND; - rep.preferBlanking = ScreenSaverBlanking; - rep.allowExposures = ScreenSaverAllowExposures; + rep = (xGetScreenSaverReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .timeout = ScreenSaverTime / MILLI_PER_SECOND, + .interval = ScreenSaverInterval / MILLI_PER_SECOND, + .preferBlanking = ScreenSaverBlanking, + .allowExposures = ScreenSaverAllowExposures + }; WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); return Success; } @@ -3111,6 +3124,7 @@ ProcListHosts(ClientPtr client) { xListHostsReply reply; int len, nHosts, result; + BOOL enabled; pointer pdata; /* REQUEST(xListHostsReq); */ @@ -3122,13 +3136,17 @@ ProcListHosts(ClientPtr client) if (result != Success) return result; - result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); + result = GetHosts(&pdata, &nHosts, &len, &enabled); if (result != Success) return result; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.nHosts = nHosts; - reply.length = bytes_to_int32(len); + + reply = (xListHostsReply) { + .type = X_Reply, + .enabled = enabled, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(len), + .nHosts = nHosts + }; WriteReplyToClient(client, sizeof(xListHostsReply), &reply); if (nHosts) { client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; @@ -3243,15 +3261,16 @@ ProcGetFontPath(ClientPtr client) if (rc != Success) return rc; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = bytes_to_int32(stringLens + numpaths); - reply.nPaths = numpaths; + reply = (xGetFontPathReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(stringLens + numpaths), + .nPaths = numpaths + }; WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); if (stringLens || numpaths) - (void) WriteToClient(client, stringLens + numpaths, - (char *) bufferStart); + WriteToClient(client, stringLens + numpaths, bufferStart); return Success; } @@ -3484,14 +3503,16 @@ ProcInitialConnection(ClientPtr client) REQUEST(xReq); xConnClientPrefix *prefix; int whichbyte = 1; + char order; - prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq); - if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) - return client->noClientException = -1; - if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || - (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) { - client->swapped = TRUE; - SwapConnClientPrefix(prefix); + prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq); + order = prefix->byteOrder; + if (order != 'l' && order != 'B' && order != 'r' && order != 'R') + return client->noClientException = -1; + if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || + (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { + client->swapped = TRUE; + SwapConnClientPrefix(prefix); } stuff->reqType = 2; stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + @@ -3499,6 +3520,9 @@ ProcInitialConnection(ClientPtr client) if (client->swapped) { swaps(&stuff->length); } + if (order == 'r' || order == 'R') { + client->local = FALSE; + } ResetCurrentRequest(client); return Success; } @@ -3523,8 +3547,8 @@ SendConnSetup(ClientPtr client, const char *reason) if (client->swapped) WriteSConnSetupPrefix(client, &csp); else - (void) WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp); - (void) WriteToClient(client, (int) csp.lengthReason, reason); + WriteToClient(client, sz_xConnSetupPrefix, &csp); + WriteToClient(client, (int) csp.lengthReason, reason); return client->noClientException = -1; } @@ -3577,10 +3601,9 @@ SendConnSetup(ClientPtr client, const char *reason) lConnectionInfo); } else { - (void) WriteToClient(client, sizeof(xConnSetupPrefix), - (char *) lconnSetupPrefix); - (void) WriteToClient(client, (int) (lconnSetupPrefix->length << 2), - lConnectionInfo); + WriteToClient(client, sizeof(xConnSetupPrefix), lconnSetupPrefix); + WriteToClient(client, (int) (lconnSetupPrefix->length << 2), + lConnectionInfo); } client->clientState = ClientStateRunning; if (ClientStateCallback) { @@ -3623,14 +3646,13 @@ void SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, XID resId, int errorCode) { - xError rep; - - memset(&rep, 0, sizeof(xError)); - rep.type = X_Error; - rep.errorCode = errorCode; - rep.majorCode = majorCode; - rep.minorCode = minorCode; - rep.resourceID = resId; + xError rep = { + .type = X_Error, + .errorCode = errorCode, + .resourceID = resId, + .minorCode = minorCode, + .majorCode = majorCode + }; WriteEventsToClient(client, 1, (xEvent *) &rep); } @@ -3724,35 +3746,29 @@ with its screen number, a pointer to its ScreenRec, argc, and argv. */ -int -AddScreen(Bool (*pfnInit) (int /*index */ , - ScreenPtr /*pScreen */ , - int /*argc */ , - char ** /*argv */ - ), int argc, char **argv) +static int init_screen(ScreenPtr pScreen, int i, Bool gpu) { - - int i; int scanlinepad, format, depth, bitsPerPixel, j, k; - ScreenPtr pScreen; - i = screenInfo.numScreens; - if (i == MAXSCREENS) - return -1; - - pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); - if (!pScreen) - return -1; + dixInitScreenSpecificPrivates(pScreen); if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) { - free(pScreen); return -1; } pScreen->myNum = i; + if (gpu) { + pScreen->myNum += GPU_SCREEN_OFFSET; + pScreen->isGPU = TRUE; + } pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */ pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ pScreen->CreateScreenResources = 0; + xorg_list_init(&pScreen->pixmap_dirty_list); + xorg_list_init(&pScreen->unattached_list); + xorg_list_init(&pScreen->output_slave_list); + xorg_list_init(&pScreen->offload_slave_list); + /* * This loop gets run once for every Screen that gets added, * but thats ok. If the ddx layer initializes the formats @@ -3783,7 +3799,33 @@ AddScreen(Bool (*pfnInit) (int /*index */ , PixmapWidthPaddingInfo[depth].notPower2 = 0; } } + return 0; +} + +int +AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , + int /*argc */ , + char ** /*argv */ + ), int argc, char **argv) +{ + + int i; + ScreenPtr pScreen; + Bool ret; + + i = screenInfo.numScreens; + if (i == MAXSCREENS) + return -1; + + pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); + if (!pScreen) + return -1; + ret = init_screen(pScreen, i, FALSE); + if (ret != 0) { + free(pScreen); + return ret; + } /* 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 @@ -3794,7 +3836,8 @@ AddScreen(Bool (*pfnInit) (int /*index */ , */ screenInfo.screens[i] = pScreen; screenInfo.numScreens++; - if (!(*pfnInit) (i, pScreen, argc, argv)) { + if (!(*pfnInit) (pScreen, argc, argv)) { + dixFreeScreenSpecificPrivates(pScreen); dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); free(pScreen); screenInfo.numScreens--; @@ -3808,3 +3851,124 @@ AddScreen(Bool (*pfnInit) (int /*index */ , return i; } + +int +AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , + int /*argc */ , + char ** /*argv */ + ), + int argc, char **argv) +{ + int i; + ScreenPtr pScreen; + Bool ret; + + i = screenInfo.numGPUScreens; + if (i == MAXGPUSCREENS) + return -1; + + pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); + if (!pScreen) + return -1; + + ret = init_screen(pScreen, i, TRUE); + if (ret != 0) { + free(pScreen); + return ret; + } + + /* 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. + */ + screenInfo.gpuscreens[i] = pScreen; + screenInfo.numGPUScreens++; + if (!(*pfnInit) (pScreen, argc, argv)) { + dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); + free(pScreen); + screenInfo.numGPUScreens--; + return -1; + } + + update_desktop_dimensions(); + + return i; +} + +void +RemoveGPUScreen(ScreenPtr pScreen) +{ + int idx, j; + if (!pScreen->isGPU) + return; + + idx = pScreen->myNum - GPU_SCREEN_OFFSET; + for (j = idx; j < screenInfo.numGPUScreens - 1; j++) { + screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1]; + screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET; + } + screenInfo.numGPUScreens--; + + /* this gets freed later in the resource list, but without + * the screen existing it causes crashes - so remove it here */ + if (pScreen->defColormap) + FreeResource(pScreen->defColormap, RT_COLORMAP); + free(pScreen); + +} + +void +AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new) +{ + assert(new->isGPU); + assert(!new->current_master); + xorg_list_add(&new->unattached_head, &pScreen->unattached_list); + new->current_master = pScreen; +} + +void +DetachUnboundGPU(ScreenPtr slave) +{ + assert(slave->isGPU); + xorg_list_del(&slave->unattached_head); + slave->current_master = NULL; +} + +void +AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new) +{ + assert(new->isGPU); + assert(!new->current_master); + xorg_list_add(&new->output_head, &pScreen->output_slave_list); + new->current_master = pScreen; +} + +void +DetachOutputGPU(ScreenPtr slave) +{ + assert(slave->isGPU); + xorg_list_del(&slave->output_head); + slave->current_master = NULL; +} + +void +AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new) +{ + assert(new->isGPU); + assert(!new->current_master); + xorg_list_add(&new->offload_head, &pScreen->offload_slave_list); + new->current_master = pScreen; +} + +void +DetachOffloadGPU(ScreenPtr slave) +{ + assert(slave->isGPU); + xorg_list_del(&slave->offload_head); + slave->current_master = NULL; +} + diff --git a/xserver/dix/dixfonts.c b/xserver/dix/dixfonts.c index 19fd31e3e..feb765d1c 100644 --- a/xserver/dix/dixfonts.c +++ b/xserver/dix/dixfonts.c @@ -115,6 +115,15 @@ LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, return Successful; } +void +dixGetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, + FontEncoding fontEncoding, + unsigned long *glyphcount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs); +} + /* * adding RT_FONT prevents conflict with default cursor font */ @@ -744,11 +753,12 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c) 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 = bytes_to_int32(stringLens + nnames); - reply.nFonts = nnames; - reply.sequenceNumber = client->sequence; + reply = (xListFontsReply) { + .type = X_Reply, + .length = bytes_to_int32(stringLens + nnames), + .nFonts = nnames, + .sequenceNumber = client->sequence + }; bufptr = bufferStart = malloc(reply.length << 2); @@ -773,7 +783,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c) reply.length = bytes_to_int32(stringLens + nnames); client->pSwapReplyFunc = ReplySwapVector[X_ListFonts]; WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply); - (void) WriteToClient(client, stringLens + nnames, bufferStart); + WriteToClient(client, stringLens + nnames, bufferStart); free(bufferStart); bail: @@ -1011,7 +1021,7 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) pFP++; } WriteSwappedDataToClient(client, length, reply); - (void) WriteToClient(client, namelen, name); + WriteToClient(client, namelen, name); if (pFontInfo == &fontInfo) { free(fontInfo.props); free(fontInfo.isStringProp); @@ -1021,11 +1031,12 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) } finish: length = sizeof(xListFontsWithInfoReply); - memset((char *) &finalReply, 0, sizeof(xListFontsWithInfoReply)); - finalReply.type = X_Reply; - finalReply.sequenceNumber = client->sequence; - finalReply.length = bytes_to_int32(sizeof(xListFontsWithInfoReply) - - sizeof(xGenericReply)); + finalReply = (xListFontsWithInfoReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(sizeof(xListFontsWithInfoReply) + - sizeof(xGenericReply)) + }; WriteSwappedDataToClient(client, length, &finalReply); bail: ClientWakeup(client); @@ -1812,12 +1823,14 @@ InitFonts(void) register_fpe_functions(); } +_X_EXPORT int GetDefaultPointSize(void) { return 120; } +_X_EXPORT FontResolutionPtr GetClientResolutions(int *num) { @@ -1850,6 +1863,7 @@ GetClientResolutions(int *num) * should be called (only once!) by each type of fpe when initialized */ +_X_EXPORT int RegisterFPEFunctions(NameCheckFunc name_func, InitFpeFunc init_func, @@ -1921,24 +1935,28 @@ find_old_font(XID id) return (FontPtr) pFont; } +_X_EXPORT Font GetNewFontClientID(void) { return FakeClientID(0); } +_X_EXPORT int StoreFontClientFont(FontPtr pfont, Font id) { return AddResource(id, RT_NONE, (pointer) pfont); } +_X_EXPORT void DeleteFontClientID(Font id) { FreeResource(id, RT_NONE); } +_X_EXPORT int client_auth_generation(ClientPtr client) { @@ -1948,6 +1966,7 @@ client_auth_generation(ClientPtr client) static int fs_handlers_installed = 0; static unsigned int last_server_gen; +_X_EXPORT int init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler) { @@ -1966,6 +1985,7 @@ init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler) return Successful; } +_X_EXPORT void remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all) diff --git a/xserver/dix/dixutils.c b/xserver/dix/dixutils.c index 9eb54893a..3f24629b4 100644 --- a/xserver/dix/dixutils.c +++ b/xserver/dix/dixutils.c @@ -384,9 +384,11 @@ BlockHandler(pointer pTimeout, pointer pReadmask) ++inHandler; for (i = 0; i < screenInfo.numScreens; i++) - (*screenInfo.screens[i]->BlockHandler) (i, - screenInfo.screens[i]-> - blockData, pTimeout, pReadmask); + (*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], + pTimeout, pReadmask); + for (i = 0; i < screenInfo.numGPUScreens; i++) + (*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], + pTimeout, pReadmask); for (i = 0; i < numHandlers; i++) if (!handlers[i].deleted) (*handlers[i].BlockHandler) (handlers[i].blockData, @@ -421,9 +423,11 @@ WakeupHandler(int result, pointer pReadmask) (*handlers[i].WakeupHandler) (handlers[i].blockData, result, pReadmask); for (i = 0; i < screenInfo.numScreens; i++) - (*screenInfo.screens[i]->WakeupHandler) (i, - screenInfo.screens[i]-> - wakeupData, result, pReadmask); + (*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], + result, pReadmask); + for (i = 0; i < screenInfo.numGPUScreens; i++) + (*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], + result, pReadmask); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { diff --git a/xserver/dix/enterleave.c b/xserver/dix/enterleave.c index 725080a4c..54f4b8554 100644 --- a/xserver/dix/enterleave.c +++ b/xserver/dix/enterleave.c @@ -30,11 +30,16 @@ #include <X11/X.h> #include <X11/extensions/XI2.h> +#include <X11/extensions/XIproto.h> +#include <X11/extensions/XI2proto.h> #include "inputstr.h" #include "windowstr.h" #include "scrnintstr.h" #include "exglobals.h" #include "enterleave.h" +#include "eventconvert.h" +#include "xkbsrv.h" +#include "inpututils.h" /** * @file @@ -602,6 +607,243 @@ DoEnterLeaveEvents(DeviceIntPtr pDev, DeviceEnterLeaveEvents(pDev, sourceid, fromWin, toWin, mode); } +static void +FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, + int first) +{ + int nval = v->numAxes - first; + + ev->type = DeviceValuator; + ev->deviceid = dev->id; + ev->num_valuators = nval < 3 ? nval : 3; + ev->first_valuator = first; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + first += ev->num_valuators; +} + +static void +FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, + ButtonClassPtr b, ValuatorClassPtr v, int first) +{ + ev->type = DeviceStateNotify; + ev->deviceid = dev->id; + ev->time = currentTime.milliseconds; + ev->classes_reported = 0; + ev->num_keys = 0; + ev->num_buttons = 0; + ev->num_valuators = 0; + + if (b) { + ev->classes_reported |= (1 << ButtonClass); + ev->num_buttons = b->numButtons; + memcpy((char *) ev->buttons, (char *) b->down, 4); + } + else if (k) { + ev->classes_reported |= (1 << KeyClass); + ev->num_keys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + memmove((char *) &ev->keys[0], (char *) k->down, 4); + } + if (v) { + int nval = v->numAxes - first; + + ev->classes_reported |= (1 << ValuatorClass); + ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift; + ev->num_valuators = nval < 3 ? nval : 3; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + } +} + + +static void +DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) +{ + int evcount = 1; + deviceStateNotify *ev, *sev; + deviceKeyStateNotify *kev; + deviceButtonStateNotify *bev; + + KeyClassPtr k; + ButtonClassPtr b; + ValuatorClassPtr v; + int nval = 0, nkeys = 0, nbuttons = 0, first = 0; + + if (!(wOtherInputMasks(win)) || + !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask)) + return; + + if ((b = dev->button) != NULL) { + nbuttons = b->numButtons; + if (nbuttons > 32) + evcount++; + } + if ((k = dev->key) != NULL) { + nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; + if (nkeys > 32) + evcount++; + if (nbuttons > 0) { + evcount++; + } + } + if ((v = dev->valuator) != NULL) { + nval = v->numAxes; + + if (nval > 3) + evcount++; + if (nval > 6) { + if (!(k && b)) + evcount++; + if (nval > 9) + evcount += ((nval - 7) / 3); + } + } + + sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); + FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); + + if (b != NULL) { + FixDeviceStateNotify(dev, ev++, NULL, b, v, first); + first += 3; + nval -= 3; + if (nbuttons > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + bev = (deviceButtonStateNotify *) ev++; + bev->type = DeviceButtonStateNotify; + bev->deviceid = dev->id; + memcpy((char *) &bev->buttons[4], (char *) &b->down[4], + DOWN_LENGTH - 4); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + if (k != NULL) { + FixDeviceStateNotify(dev, ev++, k, NULL, v, first); + first += 3; + nval -= 3; + if (nkeys > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + kev = (deviceKeyStateNotify *) ev++; + kev->type = DeviceKeyStateNotify; + kev->deviceid = dev->id; + memmove((char *) &kev->keys[0], (char *) &k->down[4], 28); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + while (nval > 0) { + FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); + first += 3; + nval -= 3; + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, + DeviceStateNotifyMask, NullGrab); + free(sev); +} + +void +DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, + WindowPtr pWin) +{ + deviceFocus event; + xXIFocusInEvent *xi2event; + DeviceIntPtr mouse; + int btlen, len, i; + + mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); + + /* XI 2 event */ + btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; + btlen = bytes_to_int32(btlen); + len = sizeof(xXIFocusInEvent) + btlen * 4; + + xi2event = calloc(1, len); + xi2event->type = GenericEvent; + xi2event->extension = IReqCode; + xi2event->evtype = type; + xi2event->length = bytes_to_int32(len - sizeof(xEvent)); + xi2event->buttons_len = btlen; + xi2event->detail = detail; + xi2event->time = currentTime.milliseconds; + xi2event->deviceid = dev->id; + xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ + xi2event->mode = mode; + xi2event->root_x = double_to_fp1616(mouse->spriteInfo->sprite->hot.x); + xi2event->root_y = double_to_fp1616(mouse->spriteInfo->sprite->hot.y); + + for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) + if (BitIsOn(mouse->button->down, i)) + SetBit(&xi2event[1], mouse->button->map[i]); + + if (dev->key) { + xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; + xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; + xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; + xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; + + xi2event->group.base_group = dev->key->xkbInfo->state.base_group; + xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; + xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; + xi2event->group.effective_group = dev->key->xkbInfo->state.group; + } + + FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent *) xi2event, pWin, + None, FALSE); + + DeliverEventsToWindow(dev, pWin, (xEvent *) xi2event, 1, + GetEventFilter(dev, (xEvent *) xi2event), NullGrab); + + free(xi2event); + + /* XI 1.x event */ + event = (deviceFocus) { + .deviceid = dev->id, + .mode = mode, + .type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut, + .detail = detail, + .window = pWin->drawable.id, + .time = currentTime.milliseconds + }; + + DeliverEventsToWindow(dev, pWin, (xEvent *) &event, 1, + DeviceFocusChangeMask, NullGrab); + + if (event.type == DeviceFocusIn) + DeliverStateNotifyEvent(dev, pWin); +} + /** * Send focus out events to all windows between 'child' and 'ancestor'. * Events are sent running up the hierarchy. @@ -1007,7 +1249,8 @@ HasOtherPointer(WindowPtr win, DeviceIntPtr exclude) * Assumption: Neither A nor B are valid windows. */ static void -CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev, WindowPtr A, /* PointerRootWin or NoneWin */ +CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev, + WindowPtr A, /* PointerRootWin or NoneWin */ WindowPtr B, /* NoneWin or PointerRootWin */ int mode) { @@ -1051,7 +1294,8 @@ CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev, WindowPtr A, /* PointerRootWi * Assumption: A is a valid window and not PointerRoot or None. */ static void -CoreFocusToPointerRootOrNone(DeviceIntPtr dev, WindowPtr A, WindowPtr B, /* PointerRootWin or NoneWin */ +CoreFocusToPointerRootOrNone(DeviceIntPtr dev, WindowPtr A, + WindowPtr B, /* PointerRootWin or NoneWin */ int mode) { WindowPtr root; @@ -1097,7 +1341,8 @@ CoreFocusToPointerRootOrNone(DeviceIntPtr dev, WindowPtr A, WindowPtr B, * Assumption: B is a valid window and not PointerRoot or None. */ static void -CoreFocusFromPointerRootOrNone(DeviceIntPtr dev, WindowPtr A, /* PointerRootWin or NoneWin */ +CoreFocusFromPointerRootOrNone(DeviceIntPtr dev, + WindowPtr A, /* PointerRootWin or NoneWin */ WindowPtr B, int mode) { WindowPtr root; diff --git a/xserver/dix/enterleave.h b/xserver/dix/enterleave.h index c1729f8da..a59d05799 100644 --- a/xserver/dix/enterleave.h +++ b/xserver/dix/enterleave.h @@ -31,13 +31,12 @@ #ifndef ENTERLEAVE_H #define ENTERLEAVE_H +#include <dix.h> /* DoFocusEvents() */ + extern void DoEnterLeaveEvents(DeviceIntPtr pDev, int sourceid, WindowPtr fromWin, WindowPtr toWin, int mode); -extern void DoFocusEvents(DeviceIntPtr pDev, - WindowPtr fromWin, WindowPtr toWin, int mode); - extern void EnterLeaveEvent(DeviceIntPtr mouse, int type, int mode, int detail, WindowPtr pWin, Window child); @@ -53,6 +52,11 @@ extern void DeviceEnterLeaveEvent(DeviceIntPtr mouse, int type, int mode, int detail, WindowPtr pWin, Window child); +extern void DeviceFocusEvent(DeviceIntPtr dev, + int type, + int mode, + int detail , + WindowPtr pWin); extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode); @@ -61,9 +65,6 @@ extern void LeaveWindow(DeviceIntPtr dev); extern void CoreFocusEvent(DeviceIntPtr kbd, int type, int mode, int detail, WindowPtr pWin); -extern void DeviceFocusEvent(DeviceIntPtr kbd, - int type, int mode, int detail, WindowPtr pWin); - extern void SetFocusIn(DeviceIntPtr kbd, WindowPtr win); extern void SetFocusOut(DeviceIntPtr dev); diff --git a/xserver/dix/eventconvert.c b/xserver/dix/eventconvert.c index 41a3174a6..2c411cf40 100644 --- a/xserver/dix/eventconvert.c +++ b/xserver/dix/eventconvert.c @@ -57,6 +57,7 @@ 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); +static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi); static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi); /* Do not use, read comments below */ @@ -160,6 +161,8 @@ EventToCore(InternalEvent *event, xEvent **core_out, int *count_out) case ET_TouchUpdate: case ET_TouchEnd: case ET_TouchOwnership: + case ET_BarrierHit: + case ET_BarrierLeave: ret = BadMatch; break; default: @@ -216,6 +219,8 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count) case ET_TouchUpdate: case ET_TouchEnd: case ET_TouchOwnership: + case ET_BarrierHit: + case ET_BarrierLeave: *count = 0; *xi = NULL; return BadMatch; @@ -277,6 +282,9 @@ EventToXI2(InternalEvent *ev, xEvent **xi) case ET_RawTouchUpdate: case ET_RawTouchEnd: return eventToRawEvent(&ev->raw_event, xi); + case ET_BarrierHit: + case ET_BarrierLeave: + return eventToBarrierEvent(&ev->barrier_event, xi); default: break; } @@ -451,7 +459,7 @@ appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info) info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes; info->sourceid = dce->sourceid; - kc = (uint32_t *) & info[1]; + kc = (uint32_t *) &info[1]; for (i = 0; i < info->num_keycodes; i++) *kc++ = i + dce->keys.min_keycode; @@ -673,8 +681,8 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) 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); + xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac); + xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac); if (ev->type == ET_TouchUpdate) xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0; @@ -782,6 +790,35 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi) return Success; } +static int +eventToBarrierEvent(BarrierEvent *ev, xEvent **xi) +{ + xXIBarrierEvent *barrier; + int len = sizeof(xXIBarrierEvent); + + *xi = calloc(1, len); + barrier = (xXIBarrierEvent*) *xi; + barrier->type = GenericEvent; + barrier->extension = IReqCode; + barrier->evtype = GetXI2Type(ev->type); + barrier->length = bytes_to_int32(len - sizeof(xEvent)); + barrier->deviceid = ev->deviceid; + barrier->sourceid = ev->sourceid; + barrier->time = ev->time; + barrier->event = ev->window; + barrier->root = ev->root; + barrier->dx = double_to_fp3232(ev->dx); + barrier->dy = double_to_fp3232(ev->dy); + barrier->dtime = ev->dt; + barrier->flags = ev->flags; + barrier->eventid = ev->event_id; + barrier->barrier = ev->barrierid; + barrier->root_x = double_to_fp1616(ev->root_x); + barrier->root_y = double_to_fp1616(ev->root_y); + + return Success; +} + /** * Return the corresponding core type for the given event or 0 if no core * equivalent exists. @@ -929,6 +966,12 @@ GetXI2Type(enum EventType type) case ET_TouchOwnership: xi2type = XI_TouchOwnership; break; + case ET_BarrierHit: + xi2type = XI_BarrierHit; + break; + case ET_BarrierLeave: + xi2type = XI_BarrierLeave; + break; default: break; } diff --git a/xserver/dix/events.c b/xserver/dix/events.c index 86336fef6..2682ecd46 100644 --- a/xserver/dix/events.c +++ b/xserver/dix/events.c @@ -219,6 +219,9 @@ static void CheckVirtualMotion(DeviceIntPtr pDev, QdEventPtr qe, static void CheckPhysLimits(DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents, Bool confineToScreen, ScreenPtr pScreen); +static Bool IsWrongPointerBarrierClient(ClientPtr client, + DeviceIntPtr dev, + xEvent *event); /** Key repeat hack. Do not use but in TryClientEvents */ extern BOOL EventIsKeyRepeat(xEvent *event); @@ -349,8 +352,6 @@ IsFloating(DeviceIntPtr dev) */ extern int lastEvent; -extern int DeviceMotionNotify; - #define CantBeFiltered NoEventMask /** * Event masks for each event type. @@ -700,9 +701,10 @@ ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py) } static void -CheckPhysLimits(DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents, Bool confineToScreen, /* unused if PanoramiX on */ - ScreenPtr pScreen) -{ /* unused if PanoramiX on */ +CheckPhysLimits(DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents, + Bool confineToScreen, /* unused if PanoramiX on */ + ScreenPtr pScreen) /* unused if PanoramiX on */ +{ HotSpot new; SpritePtr pSprite = pDev->spriteInfo->sprite; @@ -1055,19 +1057,20 @@ MonthChangedOrBadTime(InternalEvent *ev) } static void -NoticeTime(InternalEvent *ev) +NoticeTime(InternalEvent *ev, DeviceIntPtr dev) { if (ev->any.time < currentTime.milliseconds) MonthChangedOrBadTime(ev); currentTime.milliseconds = ev->any.time; - lastDeviceEventTime = currentTime; + lastDeviceEventTime[XIAllDevices] = currentTime; + lastDeviceEventTime[dev->id] = currentTime; } void -NoticeEventTime(InternalEvent *ev) +NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev) { if (!syncEvents.playingEvents) - NoticeTime(ev); + NoticeTime(ev, dev); } /************************************************************************** @@ -1091,7 +1094,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device) if (!xorg_list_is_empty(&syncEvents.pending)) tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next); - NoticeTime((InternalEvent *) event); + NoticeTime((InternalEvent *)event, device); /* Fix for key repeating bug. */ if (device->key != NULL && device->key->xkbInfo != NULL && @@ -1435,6 +1438,7 @@ UpdateTouchesForGrab(DeviceIntPtr mouse) ti->listeners[0].type = LISTENER_POINTER_GRAB; else ti->listeners[0].type = LISTENER_GRAB; + ti->listeners[0].grab = grab; } } } @@ -1503,11 +1507,27 @@ DeactivatePointerGrab(DeviceIntPtr mouse) { GrabPtr grab = mouse->deviceGrab.grab; DeviceIntPtr dev; + Bool wasPassive = mouse->deviceGrab.fromPassiveGrab; Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab && mouse->deviceGrab.implicitGrab); XID grab_resource = grab->resource; int i; + /* If an explicit grab was deactivated, we must remove it from the head of + * all the touches' listener lists. */ + for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) { + TouchPointInfoPtr ti = mouse->touch->touches + i; + if (ti->active && TouchResourceIsOwner(ti, grab_resource)) { + /* Rejecting will generate a TouchEnd, but we must not + emulate a ButtonRelease here. So pretend the listener + already has the end event */ + if (grab->grabtype == CORE || grab->grabtype == XI || + !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin)) + ti->listeners[0].state = LISTENER_HAS_END; + TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); + } + } + TouchRemovePointerGrab(mouse); mouse->valuator->motionHintWindow = NullWindow; @@ -1531,15 +1551,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse) ReattachToOldMaster(mouse); ComputeFreezes(); - - /* If an explicit grab was deactivated, we must remove it from the head of - * all the touches' listener lists. */ - for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) { - TouchPointInfoPtr ti = mouse->touch->touches + i; - - if (ti->active && TouchResourceIsOwner(ti, grab_resource)) - TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); - } } /** @@ -1555,11 +1566,13 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, WindowPtr oldWin; /* slave devices need to float for the duration of the grab. */ - if (grab->grabtype == XI2 && + if (grab->grabtype == XI2 && keybd->enabled && !(passive & ImplicitGrabMask) && !IsMaster(keybd)) DetachFromMaster(keybd); - if (grabinfo->grab) + if (!keybd->enabled) + oldWin = NULL; + else if (grabinfo->grab) oldWin = grabinfo->grab->window; else if (keybd->focus) oldWin = keybd->focus->win; @@ -1569,7 +1582,8 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, oldWin = keybd->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; - DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); + if (oldWin) + DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time; else @@ -1590,13 +1604,10 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd) { GrabPtr grab = keybd->deviceGrab.grab; DeviceIntPtr dev; - WindowPtr focusWin = keybd->focus ? keybd->focus->win - : keybd->spriteInfo->sprite->win; + WindowPtr focusWin; Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab && keybd->deviceGrab.implicitGrab); - if (focusWin == FollowKeyboardWin) - focusWin = inputInfo.keyboard->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; keybd->deviceGrab.grab = NullGrab; @@ -1607,6 +1618,17 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd) if (dev->deviceGrab.sync.other == grab) dev->deviceGrab.sync.other = NullGrab; } + + if (keybd->focus) + focusWin = keybd->focus->win; + else if (keybd->spriteInfo->sprite) + focusWin = keybd->spriteInfo->sprite->win; + else + focusWin = NullWindow; + + if (focusWin == FollowKeyboardWin) + focusWin = inputInfo.keyboard->focus->win; + DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab); if (!wasImplicit && grab->grabtype == XI2) @@ -2016,19 +2038,19 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win, */ static Bool GetClientsForDelivery(DeviceIntPtr dev, WindowPtr win, - xEvent *events, Mask filter, InputClients ** clients) + xEvent *events, Mask filter, InputClients ** iclients) { int rc = 0; if (core_get_type(events) != 0) - *clients = (InputClients *) wOtherClients(win); + *iclients = (InputClients *) wOtherClients(win); else if (xi2_get_type(events) != 0) { OtherInputMasks *inputMasks = wOtherInputMasks(win); /* Has any client selected for the event? */ if (!WindowXI2MaskIsset(dev, win, events)) goto out; - *clients = inputMasks->inputClients; + *iclients = inputMasks->inputClients; } else { OtherInputMasks *inputMasks = wOtherInputMasks(win); @@ -2037,7 +2059,7 @@ GetClientsForDelivery(DeviceIntPtr dev, WindowPtr win, if (!inputMasks || !(inputMasks->inputEvents[dev->id] & filter)) goto out; - *clients = inputMasks->inputClients; + *iclients = inputMasks->inputClients; } rc = 1; @@ -2065,6 +2087,9 @@ DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients, if (IsInterferingGrab(client, dev, events)) continue; + if (IsWrongPointerBarrierClient(client, dev, events)) + continue; + mask = GetEventMask(dev, events, inputclients); if (XaceHook(XACE_RECEIVE_ACCESS, client, win, events, count)) @@ -2099,12 +2124,12 @@ DeliverEventToWindowMask(DeviceIntPtr dev, WindowPtr win, xEvent *events, int count, Mask filter, GrabPtr grab, ClientPtr *client_return, Mask *mask_return) { - InputClients *clients; + InputClients *iclients; - if (!GetClientsForDelivery(dev, win, events, filter, &clients)) + if (!GetClientsForDelivery(dev, win, events, filter, &iclients)) return EVENT_SKIP; - return DeliverEventToInputClients(dev, clients, win, events, count, filter, + return DeliverEventToInputClients(dev, iclients, win, events, count, filter, grab, client_return, mask_return); } @@ -2213,7 +2238,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent * @return TRUE if the event should be discarded, FALSE otherwise. */ static BOOL -FilterRawEvents(const ClientPtr client, const GrabPtr grab) +FilterRawEvents(const ClientPtr client, const GrabPtr grab, WindowPtr root) { XIClientPtr client_xi_version; int cmp; @@ -2229,7 +2254,10 @@ FilterRawEvents(const ClientPtr client, const GrabPtr grab) client_xi_version->minor_version, 2, 0); /* XI 2.0: if device is grabbed, skip XI 2.1: if device is grabbed by us, skip, we've already delivered */ - return (cmp == 0) ? TRUE : SameClient(grab, client); + if (cmp == 0) + return TRUE; + + return (grab->window != root) ? FALSE : SameClient(grab, client); } /** @@ -2282,7 +2310,7 @@ DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) */ ic.next = NULL; - if (!FilterRawEvents(rClient(&ic), grab)) + if (!FilterRawEvents(rClient(&ic), grab, root)) DeliverEventToInputClients(device, &ic, root, xi, 1, filter, NULL, &c, &m); } @@ -2419,6 +2447,8 @@ FixUpEventFromWindow(SpritePtr pSprite, case XI_DeviceChanged: case XI_HierarchyChanged: case XI_PropertyEvent: + case XI_BarrierHit: + case XI_BarrierLeave: return; default: break; @@ -2433,8 +2463,8 @@ FixUpEventFromWindow(SpritePtr pSprite, } 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->event_x = event->root_x - double_to_fp1616(pWin->drawable.x); + event->event_y = event->root_y - double_to_fp1616(pWin->drawable.y); event->child = child; } else { @@ -2834,14 +2864,15 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) 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; + event = (DeviceEvent) { + .header = ET_Internal, + .type = ET_FocusIn, + .length = sizeof(DeviceEvent), + .time = GetTimeInMillis(), + .deviceid = dev->id, + .sourceid = dev->id, + .detail.button = 0 + }; rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, TRUE) != NULL); if (rc) @@ -2871,14 +2902,15 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) (*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; + event = (DeviceEvent) { + .header = ET_Internal, + .type = ET_Enter, + .length = sizeof(DeviceEvent), + .time = GetTimeInMillis(), + .deviceid = dev->id, + .sourceid = dev->id, + .detail.button = 0 + }; rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, TRUE) != NULL); if (rc) @@ -3193,6 +3225,18 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) #endif } +void FreeSprite(DeviceIntPtr dev) +{ + if (DevHasCursor(dev) && dev->spriteInfo->sprite) { + if (dev->spriteInfo->sprite->current) + FreeCursor(dev->spriteInfo->sprite->current, None); + free(dev->spriteInfo->sprite->spriteTrace); + free(dev->spriteInfo->sprite); + } + dev->spriteInfo->sprite = NULL; +} + + /** * Update the mouse sprite info when the server switches from a pScreen to another. * Otherwise, the pScreen of the mouse sprite is never updated when we switch @@ -4314,7 +4358,6 @@ OtherClientGone(pointer value, XID id) prev = other; } FatalError("client not on event list"); - /*NOTREACHED*/ return -1; /* make compiler happy */ } int @@ -4337,12 +4380,10 @@ EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask) return rc; } check = (mask & AtMostOneClient); - if (check & (pWin->eventMask | wOtherEventMasks(pWin))) { /* It is illegal for two different - clients to select on any of the - events for AtMostOneClient. However, - it is OK, for some client to - continue selecting on one of those - events. */ + if (check & (pWin->eventMask | wOtherEventMasks(pWin))) { + /* It is illegal for two different clients to select on any of the + events for AtMostOneClient. However, it is OK, for some client to + continue selecting on one of those events. */ if ((wClient(pWin) != client) && (check & pWin->eventMask)) return BadAccess; for (others = wOtherClients(pWin); others; others = others->next) { @@ -4395,7 +4436,7 @@ int EventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, Bool *checkOptional) { - int i, free; + int i, freed; if (mask & ~PropagateMask) { client->errorValue = mask; @@ -4406,14 +4447,14 @@ EventSuppressForWindow(WindowPtr pWin, ClientPtr client, if (!mask) i = 0; else { - for (i = DNPMCOUNT, free = 0; --i > 0;) { + for (i = DNPMCOUNT, freed = 0; --i > 0;) { if (!DontPropagateRefCnts[i]) - free = i; + freed = i; else if (mask == DontPropagateMasks[i]) break; } - if (!i && free) { - i = free; + if (!i && freed) { + i = freed; DontPropagateMasks[i] = mask; } } @@ -4448,7 +4489,10 @@ CoreEnterLeaveEvent(DeviceIntPtr mouse, int type, int mode, int detail, WindowPtr pWin, Window child) { - xEvent event; + xEvent event = { + .u.u.type = type, + .u.u.detail = detail + }; WindowPtr focus; DeviceIntPtr keybd; GrabPtr grab = mouse->deviceGrab.grab; @@ -4468,9 +4512,6 @@ CoreEnterLeaveEvent(DeviceIntPtr mouse, 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; event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x; event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y; @@ -4501,15 +4542,16 @@ CoreEnterLeaveEvent(DeviceIntPtr mouse, } if ((type == EnterNotify) && (mask & KeymapStateMask)) { - xKeymapEvent ke; + xKeymapEvent ke = { + .type = KeymapNotify + }; ClientPtr client = grab ? rClient(grab) : wClient(pWin); + int rc; - if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess)) - memset((char *) &ke.map[0], 0, 31); - else - memmove((char *) &ke.map[0], (char *) &keybd->key->down[1], 31); + rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); + if (rc == Success) + memcpy((char *) &ke.map[0], (char *) &keybd->key->down[1], 31); - ke.type = KeymapNotify; if (grab) TryClientEvents(rClient(grab), keybd, (xEvent *) &ke, 1, mask, KeymapStateMask, grab); @@ -4527,6 +4569,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse, { GrabPtr grab = mouse->deviceGrab.grab; xXIEnterEvent *event; + WindowPtr focus; int filter; int btlen, len, i; DeviceIntPtr kbd; @@ -4550,8 +4593,8 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse, 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); + event->root_x = double_to_fp1616(mouse->spriteInfo->sprite->hot.x); + event->root_y = double_to_fp1616(mouse->spriteInfo->sprite->hot.y); for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) if (BitIsOn(mouse->button->down, i)) @@ -4568,6 +4611,11 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse, event->group.locked_group = kbd->key->xkbInfo->state.locked_group; } + focus = (kbd) ? kbd->focus->win : None; + if ((focus != NoneWin) && + ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin))) + event->focus = TRUE; + FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin, None, FALSE); @@ -4594,27 +4642,27 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse, void CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) { - xEvent event; - - memset(&event, 0, sizeof(xEvent)); + xEvent event = { + .u.u.type = type, + .u.u.detail = detail + }; event.u.focus.mode = mode; - event.u.u.type = type; - event.u.u.detail = detail; event.u.focus.window = pWin->drawable.id; DeliverEventsToWindow(dev, pWin, &event, 1, GetEventFilter(dev, &event), NullGrab); if ((type == FocusIn) && ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask)) { - xKeymapEvent ke; + xKeymapEvent ke = { + .type = KeymapNotify + }; ClientPtr client = wClient(pWin); + int rc; - if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess)) - memset((char *) &ke.map[0], 0, 31); - else - memmove((char *) &ke.map[0], (char *) &dev->key->down[1], 31); + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess); + if (rc == Success) + memcpy((char *) &ke.map[0], (char *) &dev->key->down[1], 31); - ke.type = KeymapNotify; DeliverEventsToWindow(dev, pWin, (xEvent *) &ke, 1, KeymapStateMask, NullGrab); } @@ -4756,17 +4804,20 @@ ProcGetInputFocus(ClientPtr client) if (rc != Success) return rc; - memset(&rep, 0, sizeof(xGetInputFocusReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; + rep = (xGetInputFocusReply) { + .type = X_Reply, + .length = 0, + .sequenceNumber = client->sequence, + .revertTo = focus->revert + }; + if (focus->win == NoneWin) rep.focus = None; else if (focus->win == PointerRootWin) rep.focus = PointerRoot; else rep.focus = focus->win->drawable.id; - rep.revertTo = focus->revert; + WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep); return Success; } @@ -4786,6 +4837,7 @@ ProcGrabPointer(ClientPtr client) GrabMask mask; WindowPtr confineTo; CursorPtr oldCursor; + BYTE status; REQUEST(xGrabPointerReq); int rc; @@ -4807,7 +4859,6 @@ ProcGrabPointer(ClientPtr client) return rc; } - memset(&rep, 0, sizeof(xGrabPointerReply)); oldCursor = NullCursor; grab = device->deviceGrab.grab; @@ -4822,16 +4873,19 @@ ProcGrabPointer(ClientPtr client) rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents, stuff->time, - &mask, CORE, stuff->cursor, stuff->confineTo, &rep.status); + &mask, CORE, stuff->cursor, stuff->confineTo, &status); if (rc != Success) return rc; - if (oldCursor && rep.status == GrabSuccess) + if (oldCursor && status == GrabSuccess) FreeCursor(oldCursor, (Cursor) 0); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; + rep = (xGrabPointerReply) { + .type = X_Reply, + .status = status, + .sequenceNumber = client->sequence, + .length = 0 + }; WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep); return Success; } @@ -4998,7 +5052,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, grab = grabInfo->grab; if (grab && grab->grabtype != grabtype) *status = AlreadyGrabbed; - if (grab && !SameClient(grab, client)) + else if (grab && !SameClient(grab, client)) *status = AlreadyGrabbed; else if ((!pWin->realized) || (confineTo && @@ -5048,6 +5102,7 @@ int ProcGrabKeyboard(ClientPtr client) { xGrabKeyboardReply rep; + BYTE status; REQUEST(xGrabKeyboardReq); int result; @@ -5056,19 +5111,22 @@ ProcGrabKeyboard(ClientPtr client) REQUEST_SIZE_MATCH(xGrabKeyboardReq); - memset(&rep, 0, sizeof(xGrabKeyboardReply)); mask.core = KeyPressMask | KeyReleaseMask; result = GrabDevice(client, keyboard, stuff->pointerMode, stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents, stuff->time, &mask, CORE, None, - None, &rep.status); + None, &status); if (result != Success) return result; - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; + + rep = (xGrabKeyboardReply) { + .type = X_Reply, + .status = status, + .sequenceNumber = client->sequence, + .length = 0 + }; WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep); return Success; } @@ -5131,15 +5189,16 @@ ProcQueryPointer(ClientPtr client) 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 = event_get_corestate(mouse, keyboard); - rep.length = 0; - rep.root = (GetCurrentRootWindow(mouse))->drawable.id; - rep.rootX = pSprite->hot.x; - rep.rootY = pSprite->hot.y; - rep.child = None; + rep = (xQueryPointerReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .mask = event_get_corestate(mouse, keyboard), + .root = (GetCurrentRootWindow(mouse))->drawable.id, + .rootX = pSprite->hot.x, + .rootY = pSprite->hot.y, + .child = None + }; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { rep.sameScreen = xTrue; rep.winX = pSprite->hot.x - pWin->drawable.x; @@ -5199,6 +5258,7 @@ InitEvents(void) for (i = 0; i < MAXDEVICES; i++) { memcpy(&event_filters[i], default_filter, sizeof(default_filter)); + lastDeviceEventTime[i] = currentTime; } syncEvents.replayDev = (DeviceIntPtr) NULL; @@ -5212,7 +5272,6 @@ InitEvents(void) syncEvents.time.milliseconds = 0; /* hardly matters */ currentTime.months = 0; currentTime.milliseconds = GetTimeInMillis(); - lastDeviceEventTime = currentTime; for (i = 0; i < DNPMCOUNT; i++) { DontPropagateMasks[i] = 0; DontPropagateRefCnts[i] = 0; @@ -5407,12 +5466,13 @@ ProcGrabKey(ClientPtr client) REQUEST_SIZE_MATCH(xGrabKeyReq); - memset(¶m, 0, sizeof(param)); - param.grabtype = CORE; - param.ownerEvents = stuff->ownerEvents; - param.this_device_mode = stuff->keyboardMode; - param.other_devices_mode = stuff->pointerMode; - param.modifiers = stuff->modifiers; + param = (GrabParameters) { + .grabtype = CORE, + .ownerEvents = stuff->ownerEvents, + .this_device_mode = stuff->keyboardMode, + .other_devices_mode = stuff->pointerMode, + .modifiers = stuff->modifiers + }; rc = CheckGrabValues(client, ¶m); if (rc != Success) @@ -5513,12 +5573,13 @@ ProcGrabButton(ClientPtr client) if (rc != Success) return rc; - memset(¶m, 0, sizeof(param)); - param.grabtype = CORE; - param.ownerEvents = stuff->ownerEvents; - param.this_device_mode = stuff->keyboardMode; - param.other_devices_mode = stuff->pointerMode; - param.modifiers = stuff->modifiers; + param = (GrabParameters) { + .grabtype = CORE, + .ownerEvents = stuff->ownerEvents, + .this_device_mode = stuff->keyboardMode, + .other_devices_mode = stuff->pointerMode, + .modifiers = stuff->modifiers + }; mask.core = stuff->eventMask; @@ -5622,8 +5683,8 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) if (IsKeyboardDevice(keybd)) { focus = keybd->focus; - /* If the focus window is a root window (ie. has no parent) then don't - delete the focus from it. */ + /* If the focus window is a root window (ie. has no parent) + then don't delete the focus from it. */ if ((pWin == focus->win) && (pWin->parent != NullWindow)) { int focusEventMode = NotifyNormal; @@ -5645,12 +5706,12 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) parent = parent->parent; focus->traceGood--; } while (!parent->realized - /* This would be a good protocol change -- windows being reparented - during SaveSet processing would cause the focus to revert to the - nearest enclosing window which will survive the death of the exiting - client, instead of ending up reverting to a dying window and thence - to None - */ + /* This would be a good protocol change -- windows being + reparented during SaveSet processing would cause the + focus to revert to the nearest enclosing window which + will survive the death of the exiting client, instead + of ending up reverting to a dying window and thence + to None */ #ifdef NOTDEF || wClient(parent)->clientGone #endif @@ -5890,14 +5951,14 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) (*EventSwapVector[eventFrom->u.u.type & 0177]) (eventFrom, eventTo); - WriteToClient(pClient, eventlength, (char *) eventTo); + WriteToClient(pClient, eventlength, eventTo); } } else { /* 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. */ - WriteToClient(pClient, count * eventlength, (char *) events); + WriteToClient(pClient, count * eventlength, events); } } @@ -6028,3 +6089,19 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent *event) return FALSE; } + +/* PointerBarrier events are only delivered to the client that created that + * barrier */ +static Bool +IsWrongPointerBarrierClient(ClientPtr client, DeviceIntPtr dev, xEvent *event) +{ + xXIBarrierEvent *ev = (xXIBarrierEvent*)event; + + if (ev->type != GenericEvent || ev->extension != IReqCode) + return FALSE; + + if (ev->evtype != XI_BarrierHit && ev->evtype != XI_BarrierLeave) + return FALSE; + + return client->index != CLIENT_ID(ev->barrier); +} diff --git a/xserver/dix/extension.c b/xserver/dix/extension.c index b46b36874..24e9cb43a 100644 --- a/xserver/dix/extension.c +++ b/xserver/dix/extension.c @@ -254,11 +254,12 @@ ProcQueryExtension(ClientPtr client) REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes); - memset(&reply, 0, sizeof(xQueryExtensionReply)); - reply.type = X_Reply; - reply.length = 0; - reply.major_opcode = 0; - reply.sequenceNumber = client->sequence; + reply = (xQueryExtensionReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .major_opcode = 0 + }; if (!NumExtensions) reply.present = xFalse; @@ -286,11 +287,12 @@ ProcListExtensions(ClientPtr client) REQUEST_SIZE_MATCH(xReq); - memset(&reply, 0, sizeof(xListExtensionsReply)); - reply.type = X_Reply; - reply.nExtensions = 0; - reply.length = 0; - reply.sequenceNumber = client->sequence; + reply = (xListExtensionsReply) { + .type = X_Reply, + .nExtensions = 0, + .sequenceNumber = client->sequence, + .length = 0 + }; buffer = NULL; if (NumExtensions) { diff --git a/xserver/dix/gc.c b/xserver/dix/gc.c index 7be050221..f46e0ddc4 100644 --- a/xserver/dix/gc.c +++ b/xserver/dix/gc.c @@ -419,11 +419,11 @@ static const struct { RESTYPE type; Mask access_mode; } xidfields[] = { - { - GCTile, RT_PIXMAP, DixReadAccess}, { - GCStipple, RT_PIXMAP, DixReadAccess}, { - GCFont, RT_FONT, DixUseAccess}, { -GCClipMask, RT_PIXMAP, DixReadAccess},}; + {GCTile, RT_PIXMAP, DixReadAccess}, + {GCStipple, RT_PIXMAP, DixReadAccess}, + {GCFont, RT_FONT, DixUseAccess}, + {GCClipMask, RT_PIXMAP, DixReadAccess}, +}; int ChangeGCXIDs(ClientPtr client, GC * pGC, BITS32 mask, CARD32 *pC32) @@ -458,32 +458,21 @@ ChangeGCXIDs(ClientPtr client, GC * pGC, BITS32 mask, CARD32 *pC32) return ChangeGC(client, pGC, mask, vals); } -/* CreateGC(pDrawable, mask, pval, pStatus) - creates a default GC for the given drawable, using mask to fill - in any non-default values. - Returns a pointer to the new GC on success, NULL otherwise. - returns status of non-default fields in pStatus -BUG: - should check for failure to create default tile - -*/ -GCPtr -CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, - XID gcid, ClientPtr client) +static GCPtr +NewGCObject(ScreenPtr pScreen, int depth) { GCPtr pGC; - pGC = dixAllocateObjectWithPrivates(GC, PRIVATE_GC); + pGC = dixAllocateScreenObjectWithPrivates(pScreen, GC, PRIVATE_GC); if (!pGC) { - *pStatus = BadAlloc; return (GCPtr) NULL; } - pGC->pScreen = pDrawable->pScreen; - pGC->depth = pDrawable->depth; + pGC->pScreen = pScreen; + pGC->depth = depth; pGC->alu = GXcopy; /* dst <- src */ pGC->planemask = ~0; - pGC->serialNumber = GC_CHANGE_SERIAL_BIT; + pGC->serialNumber = 0; pGC->funcs = 0; pGC->fgPixel = 0; pGC->bgPixel = 1; @@ -496,17 +485,8 @@ CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, pGC->arcMode = ArcPieSlice; pGC->tile.pixel = 0; pGC->tile.pixmap = NullPixmap; - if (mask & GCForeground) { - /* - * magic special case -- ChangeGC checks for this condition - * and snags the Foreground value to create a pseudo default-tile - */ - pGC->tileIsPixel = FALSE; - } - else { - pGC->tileIsPixel = TRUE; - } + pGC->tileIsPixel = TRUE; pGC->patOrg.x = 0; pGC->patOrg.y = 0; pGC->subWindowMode = ClipByChildren; @@ -521,12 +501,49 @@ CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, /* use the default font and stipple */ pGC->font = defaultFont; - defaultFont->refcnt++; + if (pGC->font) /* necessary, because open of default font could fail */ + pGC->font->refcnt++; pGC->stipple = pGC->pScreen->PixmapPerDepth[0]; - pGC->stipple->refcnt++; + if (pGC->stipple) + pGC->stipple->refcnt++; /* this is not a scratch GC */ pGC->scratch_inuse = FALSE; + return pGC; +} + +/* CreateGC(pDrawable, mask, pval, pStatus) + creates a default GC for the given drawable, using mask to fill + in any non-default values. + Returns a pointer to the new GC on success, NULL otherwise. + returns status of non-default fields in pStatus +BUG: + should check for failure to create default tile + +*/ +GCPtr +CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, + XID gcid, ClientPtr client) +{ + GCPtr pGC; + + pGC = NewGCObject(pDrawable->pScreen, pDrawable->depth); + if (!pGC) { + *pStatus = BadAlloc; + return (GCPtr) NULL; + } + + pGC->serialNumber = GC_CHANGE_SERIAL_BIT; + if (mask & GCForeground) { + /* + * magic special case -- ChangeGC checks for this condition + * and snags the Foreground value to create a pseudo default-tile + */ + pGC->tileIsPixel = FALSE; + } + else { + pGC->tileIsPixel = TRUE; + } /* security creation/labeling check */ *pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC, @@ -784,45 +801,10 @@ CreateScratchGC(ScreenPtr pScreen, unsigned depth) { GCPtr pGC; - pGC = dixAllocateObjectWithPrivates(GC, PRIVATE_GC); + pGC = NewGCObject(pScreen, depth); if (!pGC) return (GCPtr) NULL; - pGC->pScreen = pScreen; - pGC->depth = depth; - pGC->alu = GXcopy; /* dst <- src */ - pGC->planemask = ~0; - pGC->serialNumber = 0; - pGC->fgPixel = 0; - pGC->bgPixel = 1; - pGC->lineWidth = 0; - pGC->lineStyle = LineSolid; - pGC->capStyle = CapButt; - pGC->joinStyle = JoinMiter; - pGC->fillStyle = FillSolid; - pGC->fillRule = EvenOddRule; - pGC->arcMode = ArcPieSlice; - pGC->font = defaultFont; - if (pGC->font) /* necessary, because open of default font could fail */ - 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; - pGC->subWindowMode = ClipByChildren; - pGC->graphicsExposures = TRUE; - pGC->clipOrg.x = 0; - pGC->clipOrg.y = 0; - pGC->clientClipType = CT_NONE; - pGC->dashOffset = 0; - pGC->numInDashList = 2; - pGC->dash = DefaultDash; - - /* scratch GCs in the GCperDepth pool start off unused */ - pGC->scratch_inuse = FALSE; - pGC->stateChanges = GCAllBits; if (!(*pScreen->CreateGC) (pGC)) { FreeGC(pGC, (XID) 0); diff --git a/xserver/dix/getevents.c b/xserver/dix/getevents.c index b78d5cec0..a4f192cf0 100644 --- a/xserver/dix/getevents.c +++ b/xserver/dix/getevents.c @@ -69,6 +69,12 @@ #include "extnsionst.h" #include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ +#if XSERVER_DTRACE +#include <sys/types.h> +typedef const char *string; +#include <Xserver-dtrace.h> +#endif + /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 @@ -158,17 +164,6 @@ key_autorepeats(DeviceIntPtr pDev, int key_code) } 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_touch_ownership(DeviceIntPtr dev, TouchOwnershipEvent *event, Time ms) { memset(event, 0, sizeof(TouchOwnershipEvent)); @@ -781,11 +776,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl * @param[in,out] mask Valuator data for this event, modified in-place. */ static void -moveRelative(DeviceIntPtr dev, ValuatorMask *mask) +moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask) { int i; Bool clip_xy = IsMaster(dev) || !IsFloating(dev); + /* for abs devices in relative mode, we've just scaled wrong, since we + mapped the device's shape into the screen shape. Undo this. */ + if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator && + dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) { + + double ratio = 1.0 * screenInfo.width/screenInfo.height; + + if (ratio > 1.0) { + double y; + if (valuator_mask_fetch_double(mask, 1, &y)) { + y *= ratio; + valuator_mask_set_double(mask, 1, y); + } + } else { + double x; + if (valuator_mask_fetch_double(mask, 0, &x)) { + x *= ratio; + valuator_mask_set_double(mask, 0, x); + } + } + } + /* calc other axes, clip, drop back into valuators */ for (i = 0; i < valuator_mask_size(mask); i++) { double val = dev->last.valuators[i]; @@ -825,27 +842,33 @@ accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms) * device's coordinate range. * * @param dev The device to scale for. - * @param[in, out] mask The mask in desktop coordinates, modified in place + * @param[in, out] mask The mask in desktop/screen coordinates, modified in place * to contain device coordinate range. + * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates. + * Otherwise, mask is in desktop coords. */ static void -scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask) +scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags) { double scaled; ScreenPtr scr = miPointerGetScreen(dev); if (valuator_mask_isset(mask, 0)) { - scaled = valuator_mask_get_double(mask, 0) + scr->x; + scaled = valuator_mask_get_double(mask, 0); + if (flags & POINTER_SCREEN) + scaled += scr->x; scaled = rescaleValuatorAxis(scaled, NULL, dev->valuator->axes + 0, - 0, scr->width); + screenInfo.x, screenInfo.width); valuator_mask_set_double(mask, 0, scaled); } if (valuator_mask_isset(mask, 1)) { - scaled = valuator_mask_get_double(mask, 1) + scr->y; + scaled = valuator_mask_get_double(mask, 1); + if (flags & POINTER_SCREEN) + scaled += scr->y; scaled = rescaleValuatorAxis(scaled, NULL, dev->valuator->axes + 1, - 0, scr->height); + screenInfo.y, screenInfo.height); valuator_mask_set_double(mask, 1, scaled); } } @@ -890,9 +913,9 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask, /* scale x&y to desktop coordinates */ *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL, - screenInfo.x, screenInfo.width); + screenInfo.x, screenInfo.width - 1); *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL, - screenInfo.y, screenInfo.height); + screenInfo.y, screenInfo.height - 1); *devx = x; *devy = y; @@ -921,10 +944,13 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask, * @param[in,out] devy y desktop-wide coordinate in device coordinate system * @param[in,out] screenx x coordinate in desktop coordinate system * @param[in,out] screeny y coordinate in desktop coordinate system + * @param[out] nevents Number of barrier events added to events + * @param[in,out] events List of events barrier events are added to */ static ScreenPtr positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask, - double *devx, double *devy, double *screenx, double *screeny) + double *devx, double *devy, double *screenx, double *screeny, + int *nevents, InternalEvent* events) { ScreenPtr scr = miPointerGetScreen(dev); double tmpx, tmpy; @@ -938,7 +964,7 @@ positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask, /* miPointerSetPosition takes care of crossing screens for us, as well as * clipping to the current screen. Coordinates returned are in desktop * coord system */ - scr = miPointerSetPosition(dev, mode, screenx, screeny); + scr = miPointerSetPosition(dev, mode, screenx, screeny, nevents, events); /* If we were constrained, rescale x/y from the screen coordinates so * the device valuators reflect the correct position. For screen @@ -1054,6 +1080,15 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type, RawDeviceEvent *raw; ValuatorMask mask; +#if XSERVER_DTRACE + if (XSERVER_INPUT_EVENT_ENABLED()) { + XSERVER_INPUT_EVENT(pDev->id, type, key_code, 0, + mask_in ? mask_in->last_bit + 1 : 0, + mask_in ? mask_in->mask : NULL, + mask_in ? mask_in->valuators : NULL); + } +#endif + /* refuse events from disabled devices */ if (!pDev->enabled) return 0; @@ -1167,6 +1202,27 @@ transform(struct pixman_f_transform *m, double *x, double *y) *y = p.v[1]; } +static void +transformRelative(DeviceIntPtr dev, ValuatorMask *mask) +{ + double x = 0, y = 0; + + valuator_mask_fetch_double(mask, 0, &x); + valuator_mask_fetch_double(mask, 1, &y); + + transform(&dev->relative_transform, &x, &y); + + if (x) + valuator_mask_set_double(mask, 0, x); + else + valuator_mask_unset(mask, 0); + + if (y) + valuator_mask_set_double(mask, 1, y); + else + valuator_mask_unset(mask, 1); +} + /** * Apply the device's transformation matrix to the valuator mask and replace * the scaled values in mask. This transformation only applies to valuators @@ -1194,7 +1250,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) ox = dev->last.valuators[0]; oy = dev->last.valuators[1]; - pixman_f_transform_invert(&invert, &dev->transform); + pixman_f_transform_invert(&invert, &dev->scale_and_transform); transform(&invert, &ox, &oy); x = ox; @@ -1207,7 +1263,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) if (valuator_mask_isset(mask, 1)) oy = y = valuator_mask_get_double(mask, 1); - transform(&dev->transform, &x, &y); + transform(&dev->scale_and_transform, &x, &y); if (valuator_mask_isset(mask, 0) || ox != x) valuator_mask_set_double(mask, 0, x); @@ -1312,8 +1368,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, RawDeviceEvent *raw; double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */ + int sx, sy; /* for POINTER_SCREEN */ ValuatorMask mask; ScreenPtr scr; + int num_barrier_events = 0; switch (type) { case MotionNotify: @@ -1354,8 +1412,11 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, /* valuators are in driver-native format (rel or abs) */ if (flags & POINTER_ABSOLUTE) { - if (flags & POINTER_SCREEN) /* valuators are in screen coords */ - scale_from_screen(pDev, &mask); + if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) { /* valuators are in screen/desktop coords */ + sx = valuator_mask_get(&mask, 0); + sy = valuator_mask_get(&mask, 1); + scale_from_screen(pDev, &mask, flags); + } transformAbsolute(pDev, &mask); clipAbsolute(pDev, &mask); @@ -1363,18 +1424,36 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, set_raw_valuators(raw, &mask, raw->valuators.data); } else { + transformRelative(pDev, &mask); + if (flags & POINTER_ACCELERATE) accelPointer(pDev, &mask, ms); if ((flags & POINTER_NORAW) == 0) set_raw_valuators(raw, &mask, raw->valuators.data); - moveRelative(pDev, &mask); + moveRelative(pDev, flags, &mask); } /* valuators are in device coordinate system in absolute coordinates */ scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny); + + /* #53037 XWarpPointer's scaling back and forth between screen and + device may leave us with rounding errors. End result is that the + pointer doesn't end up on the pixel it should. + Avoid this by forcing screenx/screeny back to what the input + coordinates were. + */ + if (flags & POINTER_SCREEN) { + scr = miPointerGetScreen(pDev); + screenx = sx + scr->x; + screeny = sy + scr->y; + } + scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, - &mask, &devx, &devy, &screenx, &screeny); + &mask, &devx, &devy, &screenx, &screeny, + &num_barrier_events, events); + num_events += num_barrier_events; + events += num_barrier_events; /* screenx, screeny are in desktop coordinates, mask is in device coordinates per-screen (the event data) @@ -1549,6 +1628,15 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int i; int realtype = type; +#if XSERVER_DTRACE + if (XSERVER_INPUT_EVENT_ENABLED()) { + XSERVER_INPUT_EVENT(pDev->id, type, buttons, flags, + mask_in ? mask_in->last_bit + 1 : 0, + mask_in ? mask_in->mask : NULL, + mask_in ? mask_in->valuators : NULL); + } +#endif + /* refuse events from disabled devices */ if (!pDev->enabled) return 0; @@ -1601,6 +1689,8 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, if (adj != 0.0 && axis != -1) { adj *= pDev->valuator->axes[axis].scroll.increment; + if (!valuator_mask_isset(&mask, axis)) + valuator_mask_set(&mask, axis, 0); add_to_scroll_valuator(pDev, &mask, axis, adj); type = MotionNotify; buttons = 0; @@ -1676,6 +1766,15 @@ GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, DeviceEvent *event; ValuatorMask mask; +#if XSERVER_DTRACE + if (XSERVER_INPUT_EVENT_ENABLED()) { + XSERVER_INPUT_EVENT(pDev->id, type, 0, 0, + mask_in ? mask_in->last_bit + 1 : 0, + mask_in ? mask_in->mask : NULL, + mask_in ? mask_in->valuators : NULL); + } +#endif + /* refuse events from disabled devices */ if (!pDev->enabled) return 0; @@ -1792,53 +1891,34 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, int i; int num_events = 0; RawDeviceEvent *raw; - union touch { - TouchPointInfoPtr dix_ti; - DDXTouchPointInfoPtr ti; - } touchpoint; + DDXTouchPointInfoPtr ti; int need_rawevent = TRUE; Bool emulate_pointer = FALSE; int client_id = 0; +#if XSERVER_DTRACE + if (XSERVER_INPUT_EVENT_ENABLED()) { + XSERVER_INPUT_EVENT(dev->id, type, ddx_touchid, flags, + mask_in ? mask_in->last_bit + 1 : 0, + mask_in ? mask_in->mask : NULL, + mask_in ? mask_in->valuators : NULL); + } +#endif + if (!dev->enabled || !t || !v) return 0; /* Find and/or create the DDX touch info */ - if (flags & TOUCH_CLIENT_ID) { /* A DIX-submitted TouchEnd */ - touchpoint.dix_ti = TouchFindByClientID(dev, ddx_touchid); - BUG_WARN(!touchpoint.dix_ti); - - if (!touchpoint.dix_ti) - return 0; - - if (!mask_in || - !valuator_mask_isset(mask_in, 0) || - !valuator_mask_isset(mask_in, 1)) { - ErrorF - ("[dix] dix-submitted events must have x/y valuator information.\n"); - return 0; - } - - need_rawevent = FALSE; - client_id = touchpoint.dix_ti->client_id; - } - else { /* a DDX-submitted touch */ - - touchpoint.ti = - TouchFindByDDXID(dev, ddx_touchid, (type == XI_TouchBegin)); - if (!touchpoint.ti) { - ErrorF("[dix] %s: unable to %s touch point %x\n", dev->name, - type == XI_TouchBegin ? "begin" : "find", ddx_touchid); - return 0; - } - client_id = touchpoint.ti->client_id; + ti = TouchFindByDDXID(dev, ddx_touchid, (type == XI_TouchBegin)); + if (!ti) { + ErrorFSigSafe("[dix] %s: unable to %s touch point %u\n", dev->name, + type == XI_TouchBegin ? "begin" : "find", ddx_touchid); + return 0; } + client_id = ti->client_id; - if (!(flags & TOUCH_CLIENT_ID)) - emulate_pointer = touchpoint.ti->emulate_pointer; - else - emulate_pointer = ! !(flags & TOUCH_POINTER_EMULATED); + emulate_pointer = ti->emulate_pointer; if (!IsMaster(dev)) events = @@ -1857,12 +1937,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, event = &events->device_event; num_events++; - init_event(dev, event, ms); - /* if submitted for master device, get the sourceid from there */ - if (flags & TOUCH_CLIENT_ID) { - event->sourceid = touchpoint.dix_ti->sourceid; - /* TOUCH_CLIENT_ID implies norawevent */ - } + init_device_event(event, dev, ms); switch (type) { case XI_TouchBegin: @@ -1871,54 +1946,46 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, if (!mask_in || !valuator_mask_isset(mask_in, 0) || !valuator_mask_isset(mask_in, 1)) { - ErrorF("%s: Attempted to start touch without x/y (driver bug)\n", - dev->name); + ErrorFSigSafe("%s: Attempted to start touch without x/y " + "(driver bug)\n", dev->name); return 0; } break; case XI_TouchUpdate: event->type = ET_TouchUpdate; if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) { - ErrorF("%s: TouchUpdate with no valuators? Driver bug\n", - dev->name); + ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n", + dev->name); } break; case XI_TouchEnd: event->type = ET_TouchEnd; /* We can end the DDX touch here, since we don't use the active * field below */ - if (!(flags & TOUCH_CLIENT_ID)) - TouchEndDDXTouch(dev, touchpoint.ti); + TouchEndDDXTouch(dev, ti); break; default: return 0; } - if (t->mode == XIDirectTouch && !(flags & TOUCH_CLIENT_ID)) { - if (!valuator_mask_isset(&mask, 0)) - valuator_mask_set_double(&mask, 0, - valuator_mask_get_double(touchpoint.ti-> - valuators, 0)); - if (!valuator_mask_isset(&mask, 1)) - valuator_mask_set_double(&mask, 1, - valuator_mask_get_double(touchpoint.ti-> - valuators, 1)); - } /* Get our screen event co-ordinates (root_x/root_y/event_x/event_y): * these come from the touchpoint in Absolute mode, or the sprite in * Relative. */ if (t->mode == XIDirectTouch) { - transformAbsolute(dev, &mask); - - if (!(flags & TOUCH_CLIENT_ID)) { - for (i = 0; i < valuator_mask_size(&mask); i++) { - double val; - - if (valuator_mask_fetch_double(&mask, i, &val)) - valuator_mask_set_double(touchpoint.ti->valuators, i, val); - } + for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) { + double val; + + if (valuator_mask_fetch_double(&mask, i, &val)) + valuator_mask_set_double(ti->valuators, i, val); + /* If the device doesn't post new X and Y axis values, + * use the last values posted. + */ + else if (i < 2 && + valuator_mask_fetch_double(ti->valuators, i, &val)) + valuator_mask_set_double(&mask, i, val); } + transformAbsolute(dev, &mask); clipAbsolute(dev, &mask); } else { @@ -1936,7 +2003,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, scr = scale_to_desktop(dev, &mask, &devx, &devy, &screenx, &screeny); if (emulate_pointer) scr = positionSprite(dev, Absolute, &mask, - &devx, &devy, &screenx, &screeny); + &devx, &devy, &screenx, &screeny, NULL, NULL); /* see fill_pointer_events for coordinate systems */ if (emulate_pointer) @@ -1947,6 +2014,14 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, if (emulate_pointer) storeLastValuators(dev, &mask, 0, 1, devx, devy); + /* Update the MD's co-ordinates, which are always in desktop space. */ + if (emulate_pointer && !IsMaster(dev) && !IsFloating(dev)) { + DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); + + master->last.valuators[0] = screenx; + master->last.valuators[1] = screeny; + } + event->root = scr->root->drawable.id; event_set_root_coordinates(event, screenx, screeny); @@ -1967,6 +2042,37 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, return num_events; } +void +GetDixTouchEnd(InternalEvent *ievent, DeviceIntPtr dev, TouchPointInfoPtr ti, + uint32_t flags) +{ + ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen; + DeviceEvent *event = &ievent->device_event; + CARD32 ms = GetTimeInMillis(); + + BUG_WARN(!dev->enabled); + + init_device_event(event, dev, ms); + + event->sourceid = ti->sourceid; + event->type = ET_TouchEnd; + + event->root = scr->root->drawable.id; + + /* Get screen event coordinates from the sprite. Is this really the best + * we can do? */ + event_set_root_coordinates(event, + dev->last.valuators[0], + dev->last.valuators[1]); + event->touchid = ti->client_id; + event->flags = flags; + + if (flags & TOUCH_POINTER_EMULATED) { + event->flags |= TOUCH_POINTER_EMULATED; + event->detail.button = 1; + } +} + /** * Synthesize a single motion event for the core pointer. * diff --git a/xserver/dix/globals.c b/xserver/dix/globals.c index db38ffd0a..ee7379226 100644 --- a/xserver/dix/globals.c +++ b/xserver/dix/globals.c @@ -126,12 +126,13 @@ Bool party_like_its_1989 = TRUE; Bool whiteRoot = FALSE; TimeStamp currentTime; -TimeStamp lastDeviceEventTime; +TimeStamp lastDeviceEventTime[MAXDEVICES]; int defaultColorVisualClass = -1; int monitorResolution = 0; char *display; +int displayfd; char *ConnectionInfo; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; diff --git a/xserver/dix/grabs.c b/xserver/dix/grabs.c index 2f05f5733..3b02352df 100644 --- a/xserver/dix/grabs.c +++ b/xserver/dix/grabs.c @@ -179,7 +179,7 @@ UngrabAllDevices(Bool kill_client) continue; PrintDeviceGrabInfo(dev); client = clients[CLIENT_ID(dev->deviceGrab.grab->resource)]; - if (!client || client->clientGone) + if (!kill_client || !client || client->clientGone) dev->deviceGrab.DeactivateGrab(dev); if (kill_client) CloseDownClient(client); @@ -205,7 +205,10 @@ AllocGrab(void) } GrabPtr -CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice, WindowPtr window, enum InputLevel grabtype, GrabMask *mask, GrabParameters *param, int type, KeyCode keybut, /* key or button */ +CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice, + WindowPtr window, enum InputLevel grabtype, GrabMask *mask, + GrabParameters *param, int type, + KeyCode keybut, /* key or button */ WindowPtr confineTo, CursorPtr cursor) { GrabPtr grab; @@ -216,7 +219,10 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice, WindowPtr wi grab->resource = FakeClientID(client); grab->device = device; grab->window = window; - grab->eventMask = mask->core; /* same for XI */ + if (grabtype == CORE || grabtype == XI) + grab->eventMask = mask->core; /* same for XI */ + else + grab->eventMask = 0; grab->deviceMask = 0; grab->ownerEvents = param->ownerEvents; grab->keyboardMode = param->this_device_mode; diff --git a/xserver/dix/inpututils.c b/xserver/dix/inpututils.c index 223d547c5..9e38e1742 100644 --- a/xserver/dix/inpututils.c +++ b/xserver/dix/inpututils.c @@ -71,14 +71,13 @@ static void do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) { int i; - xEvent core_mn; + xEvent core_mn = { .u.u.type = MappingNotify }; 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. */ @@ -93,10 +92,12 @@ do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) WriteEventsToClient(clients[i], 1, &core_mn); } - xi_mn.type = DeviceMappingNotify; - xi_mn.request = MappingPointer; - xi_mn.deviceid = dev->id; - xi_mn.time = GetTimeInMillis(); + xi_mn = (deviceMappingNotify) { + .type = DeviceMappingNotify, + .request = MappingPointer, + .deviceid = dev->id, + .time = GetTimeInMillis() + }; SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1); } @@ -909,11 +910,7 @@ input_option_set_value(InputOption *opt, const char *value) double fp1616_to_double(FP1616 in) { - double ret; - - ret = (double) (in >> 16); - ret += (double) (in & 0xffff) * (1.0 / (1UL << 16)); /* Optimized: ldexp((double)(in & 0xffff), -16); */ - return ret; + return pixman_fixed_to_double(in); } double @@ -929,20 +926,7 @@ fp3232_to_double(FP3232 in) FP1616 double_to_fp1616(double in) { - FP1616 ret; - int32_t integral; - double tmp; - uint32_t frac_d; - - tmp = floor(in); - integral = (int32_t) tmp; - - tmp = (in - integral) * (1UL << 16); /* Optimized: ldexp(in - integral, 16) */ - frac_d = (uint16_t) tmp; - - ret = integral << 16; - ret |= frac_d & 0xffff; - return ret; + return pixman_double_to_fixed(in); } FP3232 @@ -1032,6 +1016,21 @@ xi2mask_free(XI2Mask **mask) } /** + * Test if the bit for event type is set for this device only. + * + * @return TRUE if the bit is set, FALSE otherwise + */ +Bool +xi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type) +{ + BUG_WARN(dev->id < 0); + BUG_WARN(dev->id >= mask->nmasks); + BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size); + + return BitIsOn(mask->masks[dev->id], event_type); +} + +/** * Test if the bit for event type is set for this device, or the * XIAllDevices/XIAllMasterDevices (if applicable) is set. * @@ -1042,15 +1041,12 @@ xi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type) { int set = 0; - BUG_WARN(dev->id < 0); - BUG_WARN(dev->id >= mask->nmasks); - BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size); - - set = ! !BitIsOn(mask->masks[XIAllDevices], event_type); - if (!set) - set = ! !BitIsOn(mask->masks[dev->id], event_type); - if (!set && IsMaster(dev)) - set = ! !BitIsOn(mask->masks[XIAllMasterDevices], event_type); + if (xi2mask_isset_for_device(mask, inputInfo.all_devices, event_type)) + set = 1; + else if (xi2mask_isset_for_device(mask, dev, event_type)) + set = 1; + else if (IsMaster(dev) && xi2mask_isset_for_device(mask, inputInfo.all_master_devices, event_type)) + set = 1; return set; } diff --git a/xserver/dix/main.c b/xserver/dix/main.c index 70dcc946e..fb935c969 100644 --- a/xserver/dix/main.c +++ b/xserver/dix/main.c @@ -104,6 +104,7 @@ Equipment Corporation. #include "privates.h" #include "registry.h" #include "client.h" +#include "exevents.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #else @@ -206,10 +207,16 @@ main(int argc, char *argv[], char *envp[]) FatalError("no screens found"); InitExtensions(argc, argv); + for (i = 0; i < screenInfo.numGPUScreens; i++) { + ScreenPtr pScreen = screenInfo.gpuscreens[i]; + if (!CreateScratchPixmapsForScreen(pScreen)) + FatalError("failed to create scratch pixmaps"); + } + for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; - if (!CreateScratchPixmapsForScreen(i)) + if (!CreateScratchPixmapsForScreen(pScreen)) FatalError("failed to create scratch pixmaps"); if (pScreen->CreateScreenResources && !(*pScreen->CreateScreenResources) (pScreen)) @@ -295,6 +302,7 @@ main(int argc, char *argv[], char *envp[]) #endif UndisplayDevices(); + DisableAllDevices(); /* Now free up whatever must be freed */ if (screenIsSaved == SCREEN_SAVER_ON) @@ -318,14 +326,26 @@ main(int argc, char *argv[], char *envp[]) for (i = 0; i < screenInfo.numScreens; i++) screenInfo.screens[i]->root = NullWindow; + CloseDownDevices(); + CloseDownEvents(); + for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) { + ScreenPtr pScreen = screenInfo.gpuscreens[i]; + FreeScratchPixmapsForScreen(pScreen); + (*pScreen->CloseScreen) (pScreen); + dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); + free(pScreen); + screenInfo.numGPUScreens = i; + } + for (i = screenInfo.numScreens - 1; i >= 0; i--) { - FreeScratchPixmapsForScreen(i); + FreeScratchPixmapsForScreen(screenInfo.screens[i]); FreeGCperDepth(i); FreeDefaultStipple(i); - (*screenInfo.screens[i]->CloseScreen) (i, screenInfo.screens[i]); + dixFreeScreenSpecificPrivates(screenInfo.screens[i]); + (*screenInfo.screens[i]->CloseScreen) (screenInfo.screens[i]); dixFreePrivates(screenInfo.screens[i]->devPrivates, PRIVATE_SCREEN); free(screenInfo.screens[i]); screenInfo.numScreens = i; diff --git a/xserver/dix/pixmap.c b/xserver/dix/pixmap.c index 47b220b58..241881262 100644 --- a/xserver/dix/pixmap.c +++ b/xserver/dix/pixmap.c @@ -84,23 +84,23 @@ FreeScratchPixmapHeader(PixmapPtr pPixmap) } Bool -CreateScratchPixmapsForScreen(int scrnum) +CreateScratchPixmapsForScreen(ScreenPtr pScreen) { unsigned int pixmap_size; - pixmap_size = sizeof(PixmapRec) + dixPrivatesSize(PRIVATE_PIXMAP); - screenInfo.screens[scrnum]->totalPixmapSize = + pixmap_size = sizeof(PixmapRec) + dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP); + pScreen->totalPixmapSize = BitmapBytePad(pixmap_size * 8); /* let it be created on first use */ - screenInfo.screens[scrnum]->pScratchPixmap = NULL; + pScreen->pScratchPixmap = NULL; return TRUE; } void -FreeScratchPixmapsForScreen(int scrnum) +FreeScratchPixmapsForScreen(ScreenPtr pScreen) { - FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap); + FreeScratchPixmapHeader(pScreen->pScratchPixmap); } /* callable by ddx */ @@ -118,7 +118,7 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize) if (!pPixmap) return NullPixmap; - dixInitPrivates(pPixmap, pPixmap + 1, PRIVATE_PIXMAP); + dixInitScreenPrivates(pScreen, pPixmap, pPixmap + 1, PRIVATE_PIXMAP); return pPixmap; } @@ -129,3 +129,142 @@ FreePixmap(PixmapPtr pPixmap) dixFiniPrivates(pPixmap, PRIVATE_PIXMAP); free(pPixmap); } + +PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave) +{ + PixmapPtr spix; + int ret; + void *handle; + ScreenPtr master = pixmap->drawable.pScreen; + int depth = pixmap->drawable.depth; + + ret = master->SharePixmapBacking(pixmap, slave, &handle); + if (ret == FALSE) + return NULL; + + spix = slave->CreatePixmap(slave, 0, 0, depth, + CREATE_PIXMAP_USAGE_SHARED); + slave->ModifyPixmapHeader(spix, pixmap->drawable.width, + pixmap->drawable.height, depth, 0, + pixmap->devKind, NULL); + + /* have the slave pixmap take a reference on the master pixmap + later we destroy them both at the same time */ + pixmap->refcnt++; + + spix->master_pixmap = pixmap; + + ret = slave->SetSharedPixmapBacking(spix, handle); + if (ret == FALSE) { + slave->DestroyPixmap(spix); + return NULL; + } + + return spix; +} + +Bool +PixmapStartDirtyTracking(PixmapPtr src, + PixmapPtr slave_dst, + int x, int y) +{ + ScreenPtr screen = src->drawable.pScreen; + PixmapDirtyUpdatePtr dirty_update; + + dirty_update = calloc(1, sizeof(PixmapDirtyUpdateRec)); + if (!dirty_update) + return FALSE; + + dirty_update->src = src; + dirty_update->slave_dst = slave_dst; + dirty_update->x = x; + dirty_update->y = y; + + dirty_update->damage = DamageCreate(NULL, NULL, + DamageReportNone, + TRUE, src->drawable.pScreen, + src->drawable.pScreen); + if (!dirty_update->damage) { + free(dirty_update); + return FALSE; + } + + DamageRegister(&src->drawable, dirty_update->damage); + xorg_list_add(&dirty_update->ent, &screen->pixmap_dirty_list); + return TRUE; +} + +Bool +PixmapStopDirtyTracking(PixmapPtr src, PixmapPtr slave_dst) +{ + ScreenPtr screen = src->drawable.pScreen; + PixmapDirtyUpdatePtr ent, safe; + + xorg_list_for_each_entry_safe(ent, safe, &screen->pixmap_dirty_list, ent) { + if (ent->src == src && ent->slave_dst == slave_dst) { + DamageUnregister(&src->drawable, ent->damage); + DamageDestroy(ent->damage); + xorg_list_del(&ent->ent); + free(ent); + } + } + return TRUE; +} + +/* + * this function can possibly be improved and optimised, by clipping + * instead of iterating + */ +Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region) +{ + ScreenPtr pScreen = dirty->src->drawable.pScreen; + int n; + BoxPtr b; + RegionPtr region = DamageRegion(dirty->damage); + GCPtr pGC; + PixmapPtr dst; + SourceValidateProcPtr SourceValidate; + + /* + * SourceValidate is used by the software cursor code + * to pull the cursor off of the screen when reading + * bits from the frame buffer. Bypassing this function + * leaves the software cursor in place + */ + SourceValidate = pScreen->SourceValidate; + pScreen->SourceValidate = NULL; + + RegionTranslate(dirty_region, dirty->x, dirty->y); + RegionIntersect(dirty_region, dirty_region, region); + + if (RegionNil(dirty_region)) { + RegionUninit(dirty_region); + return FALSE; + } + + dst = dirty->slave_dst->master_pixmap; + + RegionTranslate(dirty_region, -dirty->x, -dirty->y); + n = RegionNumRects(dirty_region); + b = RegionRects(dirty_region); + + pGC = GetScratchGC(dirty->src->drawable.depth, pScreen); + ValidateGC(&dst->drawable, pGC); + + while (n--) { + BoxRec dst_box; + int w, h; + + dst_box = *b; + w = dst_box.x2 - dst_box.x1; + h = dst_box.y2 - dst_box.y1; + + pGC->ops->CopyArea(&dirty->src->drawable, &dst->drawable, pGC, + dirty->x + dst_box.x1, dirty->y + dst_box.y1, w, h, dst_box.x1, dst_box.y1); + b++; + } + FreeScratchGC(pGC); + + pScreen->SourceValidate = SourceValidate; + return TRUE; +} diff --git a/xserver/dix/privates.c b/xserver/dix/privates.c index 15fbf7590..55b9345a7 100644 --- a/xserver/dix/privates.c +++ b/xserver/dix/privates.c @@ -62,13 +62,9 @@ from The Open Group. #include "inputstr.h" #include "scrnintstr.h" #include "extnsionst.h" +#include "inputstr.h" -static struct { - DevPrivateKey key; - unsigned offset; - int created; - int allocated; -} keys[PRIVATE_LAST]; +static DevPrivateSetRec global_keys[PRIVATE_LAST]; static const Bool xselinux_private[PRIVATE_LAST] = { [PRIVATE_SCREEN] = TRUE, @@ -86,8 +82,57 @@ static const Bool xselinux_private[PRIVATE_LAST] = { [PRIVATE_GLYPHSET] = TRUE, }; +static const char *key_names[PRIVATE_LAST] = { + /* XSELinux uses the same private keys for numerous objects */ + [PRIVATE_XSELINUX] = "XSELINUX", + + /* Otherwise, you get a private in just the requested structure + */ + /* These can have objects created before all of the keys are registered */ + [PRIVATE_SCREEN] = "SCREEN", + [PRIVATE_EXTENSION] = "EXTENSION", + [PRIVATE_COLORMAP] = "COLORMAP", + [PRIVATE_DEVICE] = "DEVICE", + + /* These cannot have any objects before all relevant keys are registered */ + [PRIVATE_CLIENT] = "CLIENT", + [PRIVATE_PROPERTY] = "PROPERTY", + [PRIVATE_SELECTION] = "SELECTION", + [PRIVATE_WINDOW] = "WINDOW", + [PRIVATE_PIXMAP] = "PIXMAP", + [PRIVATE_GC] = "GC", + [PRIVATE_CURSOR] = "CURSOR", + [PRIVATE_CURSOR_BITS] = "CURSOR_BITS", + + /* extension privates */ + [PRIVATE_DBE_WINDOW] = "DBE_WINDOW", + [PRIVATE_DAMAGE] = "DAMAGE", + [PRIVATE_GLYPH] = "GLYPH", + [PRIVATE_GLYPHSET] = "GLYPHSET", + [PRIVATE_PICTURE] = "PICTURE", + [PRIVATE_SYNC_FENCE] = "SYNC_FENCE", +}; + +static const Bool screen_specific_private[PRIVATE_LAST] = { + [PRIVATE_SCREEN] = FALSE, + [PRIVATE_CLIENT] = FALSE, + [PRIVATE_WINDOW] = TRUE, + [PRIVATE_PIXMAP] = TRUE, + [PRIVATE_GC] = TRUE, + [PRIVATE_CURSOR] = FALSE, + [PRIVATE_COLORMAP] = FALSE, + [PRIVATE_DEVICE] = FALSE, + [PRIVATE_EXTENSION] = FALSE, + [PRIVATE_SELECTION] = FALSE, + [PRIVATE_PROPERTY] = FALSE, + [PRIVATE_PICTURE] = TRUE, + [PRIVATE_GLYPHSET] = FALSE, +}; + typedef Bool (*FixupFunc) (PrivatePtr *privates, int offset, unsigned bytes); +typedef enum { FixupMove, FixupRealloc } FixupType; + static Bool dixReallocPrivates(PrivatePtr *privates, int old_offset, unsigned bytes) { @@ -110,14 +155,76 @@ dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes) } static Bool +fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes) +{ + intptr_t dist; + char *old; + char *new; + DevPrivateKey *keyp, key; + DevPrivateType type; + int size; + + old = (char *) pScreen->devPrivates; + size = global_keys[PRIVATE_SCREEN].offset; + if (!fixup (&pScreen->devPrivates, size, bytes)) + return FALSE; + + /* Screen privates can contain screen-specific private keys + * for other types. When they move, the linked list we use to + * track them gets scrambled. Fix that by computing the change + * in the location of each private adjusting our linked list + * pointers to match + */ + + new = (char *) pScreen->devPrivates; + + /* Moving means everyone shifts up in the privates by 'bytes' amount, + * realloc means the base pointer moves + */ + if (fixup == dixMovePrivates) + new += bytes; + + dist = new - old; + + if (dist) { + for (type = PRIVATE_XSELINUX; type < PRIVATE_LAST; type++) + + /* Walk the privates list, being careful as the + * pointers are scrambled before we patch them. + */ + for (keyp = &pScreen->screenSpecificPrivates[type].key; + (key = *keyp) != NULL; + keyp = &key->next) + { + + /* Only mangle things if the private structure + * is contained within the allocation. Privates + * stored elsewhere will be left alone + */ + if (old <= (char *) key && (char *) key < old + size) + { + /* Compute new location of key */ + key = (DevPrivateKey) ((char *) key + dist); + + /* Patch the list */ + *keyp = key; + } + } + } + return TRUE; +} + +static Bool fixupScreens(FixupFunc fixup, unsigned bytes) { int s; for (s = 0; s < screenInfo.numScreens; s++) - if (!fixup - (&screenInfo.screens[s]->devPrivates, keys[PRIVATE_SCREEN].offset, - bytes)) + if (!fixupOneScreen (screenInfo.screens[s], fixup, bytes)) + return FALSE; + + for (s = 0; s < screenInfo.numGPUScreens; s++) + if (!fixupOneScreen (screenInfo.gpuscreens[s], fixup, bytes)) return FALSE; return TRUE; } @@ -126,7 +233,7 @@ static Bool fixupServerClient(FixupFunc fixup, unsigned bytes) { if (serverClient) - return fixup(&serverClient->devPrivates, keys[PRIVATE_CLIENT].offset, + return fixup(&serverClient->devPrivates, global_keys[PRIVATE_CLIENT].offset, bytes); return TRUE; } @@ -140,7 +247,7 @@ fixupExtensions(FixupFunc fixup, unsigned bytes) for (major = EXTENSION_BASE; (extension = GetExtensionEntry(major)); major++) if (!fixup - (&extension->devPrivates, keys[PRIVATE_EXTENSION].offset, bytes)) + (&extension->devPrivates, global_keys[PRIVATE_EXTENSION].offset, bytes)) return FALSE; return TRUE; } @@ -157,17 +264,65 @@ fixupDefaultColormaps(FixupFunc fixup, unsigned bytes) screenInfo.screens[s]->defColormap, RT_COLORMAP, serverClient, DixCreateAccess); if (cmap && - !fixup(&cmap->devPrivates, keys[PRIVATE_COLORMAP].offset, bytes)) + !fixup(&cmap->devPrivates, screenInfo.screens[s]->screenSpecificPrivates[PRIVATE_COLORMAP].offset, bytes)) + return FALSE; + } + return TRUE; +} + +static Bool +fixupDeviceList(DeviceIntPtr device, FixupFunc fixup, unsigned bytes) +{ + while (device) { + if (!fixup(&device->devPrivates, global_keys[PRIVATE_DEVICE].offset, bytes)) return FALSE; + device = device->next; } return TRUE; } +static Bool +fixupDevices(FixupFunc fixup, unsigned bytes) +{ + return (fixupDeviceList(inputInfo.devices, fixup, bytes) && + fixupDeviceList(inputInfo.off_devices, fixup, bytes)); +} + static Bool (*const allocated_early[PRIVATE_LAST]) (FixupFunc, unsigned) = { -[PRIVATE_SCREEN] = fixupScreens, - [PRIVATE_CLIENT] = fixupServerClient, - [PRIVATE_EXTENSION] = fixupExtensions, - [PRIVATE_COLORMAP] = fixupDefaultColormaps,}; + [PRIVATE_SCREEN] = fixupScreens, + [PRIVATE_CLIENT] = fixupServerClient, + [PRIVATE_EXTENSION] = fixupExtensions, + [PRIVATE_COLORMAP] = fixupDefaultColormaps, + [PRIVATE_DEVICE] = fixupDevices, +}; + +static void +grow_private_set(DevPrivateSetPtr set, unsigned bytes) +{ + DevPrivateKey k; + + for (k = set->key; k; k = k->next) + k->offset += bytes; + set->offset += bytes; +} + +static void +grow_screen_specific_set(DevPrivateType type, unsigned bytes) +{ + int s; + + /* Update offsets for all screen-specific keys */ + for (s = 0; s < screenInfo.numScreens; s++) { + ScreenPtr pScreen = screenInfo.screens[s]; + + grow_private_set(&pScreen->screenSpecificPrivates[type], bytes); + } + for (s = 0; s < screenInfo.numGPUScreens; s++) { + ScreenPtr pScreen = screenInfo.gpuscreens[s]; + + grow_private_set(&pScreen->screenSpecificPrivates[type], bytes); + } +} /* * Register a private key. This takes the type of object the key will @@ -199,14 +354,13 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size) /* Update offsets for all affected keys */ if (type == PRIVATE_XSELINUX) { - DevPrivateKey k; /* Resize if we can, or make sure nothing's allocated if we can't */ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) if (xselinux_private[t]) { if (!allocated_early[t]) - assert(!keys[t].created); + assert(!global_keys[t].created); else if (!allocated_early[t] (dixReallocPrivates, bytes)) return FALSE; } @@ -216,12 +370,12 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size) */ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { if (xselinux_private[t]) { - for (k = keys[t].key; k; k = k->next) - k->offset += bytes; - keys[t].offset += bytes; + grow_private_set(&global_keys[t], bytes); + grow_screen_specific_set(t, bytes); if (allocated_early[t]) allocated_early[t] (dixMovePrivates, bytes); } + } offset = 0; @@ -229,11 +383,12 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size) else { /* Resize if we can, or make sure nothing's allocated if we can't */ if (!allocated_early[type]) - assert(!keys[type].created); + assert(!global_keys[type].created); else if (!allocated_early[type] (dixReallocPrivates, bytes)) return FALSE; - offset = keys[type].offset; - keys[type].offset += bytes; + offset = global_keys[type].offset; + global_keys[type].offset += bytes; + grow_screen_specific_set(type, bytes); } /* Setup this key */ @@ -242,8 +397,8 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size) key->initialized = TRUE; key->type = type; key->allocated = FALSE; - key->next = keys[type].key; - keys[type].key = key; + key->next = global_keys[type].key; + global_keys[type].key = key; return TRUE; } @@ -286,13 +441,15 @@ _dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen) void _dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type) { - keys[type].created++; + assert (!screen_specific_private[type]); + + global_keys[type].created++; if (xselinux_private[type]) - keys[PRIVATE_XSELINUX].created++; - if (keys[type].offset == 0) + global_keys[PRIVATE_XSELINUX].created++; + if (global_keys[type].offset == 0) addr = 0; *privates = addr; - memset(addr, '\0', keys[type].offset); + memset(addr, '\0', global_keys[type].offset); } /* @@ -301,9 +458,9 @@ _dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type) void _dixFiniPrivates(PrivatePtr privates, DevPrivateType type) { - keys[type].created--; + global_keys[type].created--; if (xselinux_private[type]) - keys[PRIVATE_XSELINUX].created--; + global_keys[PRIVATE_XSELINUX].created--; } /* @@ -322,10 +479,11 @@ _dixAllocateObjectWithPrivates(unsigned baseSize, unsigned clear, PrivatePtr *devPrivates; assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST); + assert(!screen_specific_private[type]); /* round up so that void * is aligned */ baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1); - totalSize = baseSize + keys[type].offset; + totalSize = baseSize + global_keys[type].offset; object = malloc(totalSize); if (!object) return NULL; @@ -350,8 +508,9 @@ dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type) PrivatePtr p; assert(type > PRIVATE_XSELINUX && type < PRIVATE_LAST); + assert(!screen_specific_private[type]); - size = keys[type].offset; + size = global_keys[type].offset; if (!size) { p = NULL; } @@ -361,7 +520,7 @@ dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type) } _dixInitPrivates(privates, p, type); - ++keys[type].allocated; + ++global_keys[type].allocated; return TRUE; } @@ -387,7 +546,7 @@ void dixFreePrivates(PrivatePtr privates, DevPrivateType type) { _dixFiniPrivates(privates, type); - --keys[type].allocated; + --global_keys[type].allocated; free(privates); } @@ -398,8 +557,9 @@ extern _X_EXPORT int dixPrivatesSize(DevPrivateType type) { assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST); + assert (!screen_specific_private[type]); - return keys[type].offset; + return global_keys[type].offset; } /* Table of devPrivates offsets */ @@ -434,36 +594,136 @@ dixLookupPrivateOffset(RESTYPE type) return -1; } -static const char *key_names[PRIVATE_LAST] = { - /* XSELinux uses the same private keys for numerous objects */ - [PRIVATE_XSELINUX] = "XSELINUX", +/* + * Screen-specific privates + */ - /* Otherwise, you get a private in just the requested structure - */ - /* These can have objects created before all of the keys are registered */ - [PRIVATE_SCREEN] = "SCREEN", - [PRIVATE_EXTENSION] = "EXTENSION", - [PRIVATE_COLORMAP] = "COLORMAP", +extern _X_EXPORT Bool +dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, + DevPrivateType type, unsigned size) +{ + int offset; + unsigned bytes; - /* These cannot have any objects before all relevant keys are registered */ - [PRIVATE_DEVICE] = "DEVICE", - [PRIVATE_CLIENT] = "CLIENT", - [PRIVATE_PROPERTY] = "PROPERTY", - [PRIVATE_SELECTION] = "SELECTION", - [PRIVATE_WINDOW] = "WINDOW", - [PRIVATE_PIXMAP] = "PIXMAP", - [PRIVATE_GC] = "GC", - [PRIVATE_CURSOR] = "CURSOR", - [PRIVATE_CURSOR_BITS] = "CURSOR_BITS", + if (!screen_specific_private[type]) + FatalError("Attempt to allocate screen-specific private storage for type %s\n", + key_names[type]); - /* extension privates */ - [PRIVATE_DBE_WINDOW] = "DBE_WINDOW", - [PRIVATE_DAMAGE] = "DAMAGE", - [PRIVATE_GLYPH] = "GLYPH", - [PRIVATE_GLYPHSET] = "GLYPHSET", - [PRIVATE_PICTURE] = "PICTURE", - [PRIVATE_SYNC_FENCE] = "SYNC_FENCE", -}; + if (key->initialized) { + assert(size == key->size); + return TRUE; + } + + /* Compute required space */ + bytes = size; + if (size == 0) + bytes = sizeof(void *); + + /* align to void * size */ + bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1); + + assert (!allocated_early[type]); + assert (!pScreen->screenSpecificPrivates[type].created); + offset = pScreen->screenSpecificPrivates[type].offset; + pScreen->screenSpecificPrivates[type].offset += bytes; + + /* Setup this key */ + key->offset = offset; + key->size = size; + key->initialized = TRUE; + key->type = type; + key->allocated = FALSE; + key->next = pScreen->screenSpecificPrivates[type].key; + pScreen->screenSpecificPrivates[type].key = key; + + return TRUE; +} + +/* Clean up screen-specific privates before CloseScreen */ +void +dixFreeScreenSpecificPrivates(ScreenPtr pScreen) +{ +} + +/* Initialize screen-specific privates in AddScreen */ +void +dixInitScreenSpecificPrivates(ScreenPtr pScreen) +{ + DevPrivateType t; + + for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) + pScreen->screenSpecificPrivates[t].offset = global_keys[t].offset; +} + +/* Initialize screen-specific privates in AddScreen */ +void +_dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type) +{ + int privates_size; + assert (screen_specific_private[type]); + + if (pScreen) { + privates_size = pScreen->screenSpecificPrivates[type].offset; + pScreen->screenSpecificPrivates[type].created++; + } + else + privates_size = global_keys[type].offset; + + global_keys[type].created++; + if (xselinux_private[type]) + global_keys[PRIVATE_XSELINUX].created++; + if (privates_size == 0) + addr = 0; + *privates = addr; + memset(addr, '\0', privates_size); +} + +void * +_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen, + unsigned baseSize, + unsigned clear, + unsigned offset, + DevPrivateType type) +{ + unsigned totalSize; + void *object; + PrivatePtr privates; + PrivatePtr *devPrivates; + int privates_size; + + assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST); + assert (screen_specific_private[type]); + + if (pScreen) + privates_size = pScreen->screenSpecificPrivates[type].offset; + else + privates_size = global_keys[type].offset; + /* round up so that void * is aligned */ + baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1); + totalSize = baseSize + privates_size; + object = malloc(totalSize); + if (!object) + return NULL; + + memset(object, '\0', clear); + privates = (PrivatePtr) (((char *) object) + baseSize); + devPrivates = (PrivatePtr *) ((char *) object + offset); + + _dixInitScreenPrivates(pScreen, devPrivates, privates, type); + + return object; +} + +int +dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type) +{ + assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST); + + if (screen_specific_private[type]) + return pScreen->screenSpecificPrivates[type].offset; + else + return global_keys[type].offset; +} void dixPrivateUsage(void) @@ -474,14 +734,14 @@ dixPrivateUsage(void) DevPrivateType t; for (t = PRIVATE_XSELINUX + 1; t < PRIVATE_LAST; t++) { - if (keys[t].offset) { + if (global_keys[t].offset) { ErrorF ("%s: %d objects of %d bytes = %d total bytes %d private allocs\n", - key_names[t], keys[t].created, keys[t].offset, - keys[t].created * keys[t].offset, keys[t].allocated); - bytes += keys[t].created * keys[t].offset; - objects += keys[t].created; - alloc += keys[t].allocated; + key_names[t], global_keys[t].created, global_keys[t].offset, + global_keys[t].created * global_keys[t].offset, global_keys[t].allocated); + bytes += global_keys[t].created * global_keys[t].offset; + objects += global_keys[t].created; + alloc += global_keys[t].allocated; } } ErrorF("TOTAL: %d objects, %d bytes, %d allocs\n", objects, bytes, alloc); @@ -495,7 +755,7 @@ dixResetPrivates(void) for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { DevPrivateKey key, next; - for (key = keys[t].key; key; key = next) { + for (key = global_keys[t].key; key; key = next) { next = key->next; key->offset = 0; key->initialized = FALSE; @@ -504,14 +764,14 @@ dixResetPrivates(void) if (key->allocated) free(key); } - if (keys[t].created) { + if (global_keys[t].created) { ErrorF("%d %ss still allocated at reset\n", - keys[t].created, key_names[t]); + global_keys[t].created, key_names[t]); dixPrivateUsage(); } - keys[t].key = NULL; - keys[t].offset = 0; - keys[t].created = 0; - keys[t].allocated = 0; + global_keys[t].key = NULL; + global_keys[t].offset = 0; + global_keys[t].created = 0; + global_keys[t].allocated = 0; } } diff --git a/xserver/dix/property.c b/xserver/dix/property.c index b1b83124f..dec409024 100644 --- a/xserver/dix/property.c +++ b/xserver/dix/property.c @@ -108,14 +108,13 @@ dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, static void deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom) { - xEvent event; - - memset(&event, 0, sizeof(xEvent)); + xEvent event = { + .u.property.window = pWin->drawable.id, + .u.property.state = state, + .u.property.atom = atom, + .u.property.time = currentTime.milliseconds + }; event.u.u.type = PropertyNotify; - event.u.property.window = pWin->drawable.id; - event.u.property.state = state; - event.u.property.atom = atom; - event.u.property.time = currentTime.milliseconds; DeliverEvents(pWin, &event, 1, (WindowPtr) NULL); } @@ -413,15 +412,18 @@ DeleteAllWindowProperties(WindowPtr pWin) } static int -NullPropertyReply(ClientPtr client, - ATOM propertyType, int format, xGetPropertyReply * reply) +NullPropertyReply(ClientPtr client, ATOM propertyType, int format) { - reply->nItems = 0; - reply->length = 0; - reply->bytesAfter = 0; - reply->propertyType = propertyType; - reply->format = format; - WriteReplyToClient(client, sizeof(xGenericReply), reply); + xGetPropertyReply reply = { + .type = X_Reply, + .format = format, + .sequenceNumber = client->sequence, + .length = 0, + .propertyType = propertyType, + .bytesAfter = 0, + .nItems = 0 + }; + WriteReplyToClient(client, sizeof(xGenericReply), &reply); return Success; } @@ -470,13 +472,9 @@ ProcGetProperty(ClientPtr client) return BadAtom; } - memset(&reply, 0, sizeof(xGetPropertyReply)); - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); if (rc == BadMatch) - return NullPropertyReply(client, None, 0, &reply); + return NullPropertyReply(client, None, 0); else if (rc != Success) return rc; @@ -485,11 +483,15 @@ ProcGetProperty(ClientPtr client) if (((stuff->type != pProp->type) && (stuff->type != AnyPropertyType)) ) { - reply.bytesAfter = pProp->size; - reply.format = pProp->format; - reply.length = 0; - reply.nItems = 0; - reply.propertyType = pProp->type; + reply = (xGetPropertyReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .bytesAfter = pProp->size, + .format = pProp->format, + .length = 0, + .nItems = 0, + .propertyType = pProp->type + }; WriteReplyToClient(client, sizeof(xGenericReply), &reply); return Success; } @@ -510,11 +512,15 @@ ProcGetProperty(ClientPtr client) len = min(n - ind, 4 * stuff->longLength); - reply.bytesAfter = n - (ind + len); - reply.format = pProp->format; - reply.length = bytes_to_int32(len); - reply.nItems = len / (pProp->format / 8); - reply.propertyType = pProp->type; + reply = (xGetPropertyReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .bytesAfter = n - (ind + len), + .format = pProp->format, + .length = bytes_to_int32(len), + .nItems = len / (pProp->format / 8), + .propertyType = pProp->type + }; if (stuff->delete && (reply.bytesAfter == 0)) deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); @@ -589,10 +595,12 @@ ProcListProperties(ClientPtr client) } } - xlpr.type = X_Reply; - xlpr.nProperties = numProps; - xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); - xlpr.sequenceNumber = client->sequence; + xlpr = (xListPropertiesReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(numProps * sizeof(Atom)), + .nProperties = numProps + }; WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); if (numProps) { client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; diff --git a/xserver/dix/ptrveloc.c b/xserver/dix/ptrveloc.c index acbb479c1..d6fef9cf3 100644 --- a/xserver/dix/ptrveloc.c +++ b/xserver/dix/ptrveloc.c @@ -61,10 +61,7 @@ ****************************************************************************/ /* fwds */ -int - SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); static double - SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc); static PointerAccelerationProfileFunc @@ -80,7 +77,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr, /*#define PTRACCEL_DEBUGGING*/ #ifdef PTRACCEL_DEBUGGING -#define DebugAccelF ErrorF +#define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__) #else #define DebugAccelF(...) /* */ #endif @@ -424,7 +421,7 @@ void InitTrackers(DeviceVelocityPtr vel, int ntracker) { if (ntracker < 1) { - ErrorF("(dix ptracc) invalid number of trackers\n"); + ErrorF("invalid number of trackers\n"); return; } free(vel->tracker); @@ -569,7 +566,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t) vel->tracker[n].dy = 0.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", + DebugAccelF("motion [dx: %f dy: %f dir:%d diff: %d]\n", dx, dy, vel->tracker[n].dir, cur_t - vel->tracker[vel->cur_tracker].time); vel->cur_tracker = n; @@ -617,7 +614,8 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t) /* 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"); + DebugAccelF("query: tracker too old (reset after %d, age is %d)\n", + vel->reset_time, age_ms); break; } @@ -629,7 +627,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t) */ dir &= tracker->dir; if (dir == 0) { /* we've changed octant of movement (e.g. NE → NW) */ - DebugAccelF("(dix prtacc) query: no longer linear\n"); + DebugAccelF("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; @@ -650,7 +648,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t) velocity_diff / (initial_velocity + tracker_velocity) >= vel->max_rel_diff) { /* we're not in range, quit - it won't get better. */ - DebugAccelF("(dix prtacc) query: tracker too different:" + DebugAccelF("query: tracker too different:" " old %2.2f initial %2.2f diff: %2.2f\n", tracker_velocity, initial_velocity, velocity_diff); break; @@ -663,14 +661,14 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t) } } if (offset == vel->num_tracker) { - DebugAccelF("(dix prtacc) query: last tracker in effect\n"); + DebugAccelF("query: last tracker in effect\n"); used_offset = vel->num_tracker - 1; } if (used_offset >= 0) { #ifdef PTRACCEL_DEBUGGING MotionTracker *tracker = TRACKER(vel, used_offset); - DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n", + DebugAccelF("result: offset %i [dx: %f dy: %f diff: %i]\n", used_offset, tracker->dx, tracker->dy, cur_t - tracker->time); #endif @@ -696,6 +694,8 @@ ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time) velocity = QueryTrackers(vel, time); + DebugAccelF("velocity is %f\n", velocity); + vel->velocity = velocity; return velocity == 0; } @@ -741,7 +741,7 @@ ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy) } /* - * compute the acceleration for given velocity and enforce min_acceleartion + * compute the acceleration for given velocity and enforce min_acceleration */ double BasicComputeAcceleration(DeviceIntPtr dev, @@ -771,7 +771,7 @@ ComputeAcceleration(DeviceIntPtr dev, double result; if (vel->velocity <= 0) { - DebugAccelF("(dix ptracc) profile skipped\n"); + DebugAccelF("profile skipped\n"); /* * If we have no idea about device velocity, don't pretend it. */ @@ -791,17 +791,18 @@ ComputeAcceleration(DeviceIntPtr dev, result += 4.0f * BasicComputeAcceleration(dev, vel, (vel->last_velocity + - vel->velocity) / 2, threshold, + vel->velocity) / 2, + threshold, acc); result /= 6.0f; - DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n", + DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n", vel->velocity, vel->last_velocity, result); } else { result = BasicComputeAcceleration(dev, vel, vel->velocity, threshold, acc); - DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n", - vel->velocity, res); + DebugAccelF("profile sample [%.2f] is %.3f\n", + vel->velocity, result); } return result; @@ -1052,11 +1053,8 @@ SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel, DeviceVelocityPtr GetDevicePredictableAccelData(DeviceIntPtr dev) { - /*sanity check */ - if (!dev) { - ErrorF("[dix] accel: DeviceIntPtr was NULL"); - return NULL; - } + BUG_RETURN_VAL(!dev, NULL); + if (dev->valuator && dev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable && @@ -1115,6 +1113,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime) (double) dev->ptrfeed->ctrl.num / (double) dev->ptrfeed->ctrl.den); + DebugAccelF("mult is %f\n", mult); if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) { if (mult > 1.0f && soften) ApplySoftening(velocitydata, &dx, &dy); @@ -1124,8 +1123,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime) valuator_mask_set_double(val, 0, mult * dx); if (dy != 0.0) valuator_mask_set_double(val, 1, mult * dy); - DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx, - mult * dy); + DebugAccelF("delta x:%.3f y:%.3f\n", mult * dx, mult * dy); } } } diff --git a/xserver/dix/registry.c b/xserver/dix/registry.c index e9c19b092..5bad0fdd4 100644 --- a/xserver/dix/registry.c +++ b/xserver/dix/registry.c @@ -286,7 +286,7 @@ LookupResourceName(RESTYPE resource) void dixResetRegistry(void) { - ExtensionEntry extEntry; + ExtensionEntry extEntry = { .name = CORE }; /* Free all memory */ while (nmajor--) { @@ -336,8 +336,6 @@ dixResetRegistry(void) RegisterResourceName(RT_PASSIVEGRAB, "PASSIVE GRAB"); /* Add the core protocol */ - memset(&extEntry, 0, sizeof(extEntry)); - extEntry.name = CORE; RegisterExtensionNames(&extEntry); } diff --git a/xserver/dix/resource.c b/xserver/dix/resource.c index 89d077642..2aafa343c 100644 --- a/xserver/dix/resource.c +++ b/xserver/dix/resource.c @@ -141,6 +141,7 @@ Equipment Corporation. #include "xace.h" #include <assert.h> #include "registry.h" +#include "gcstruct.h" #ifdef XSERVER_DTRACE #include <sys/types.h> @@ -182,50 +183,313 @@ RESTYPE TypeMask; struct ResourceType { DeleteType deleteFunc; + SizeType sizeFunc; + FindTypeSubResources findSubResFunc; int errorValue; }; +/** + * Used by all resources that don't specify a function to calculate + * resource size. Currently this is used for all resources with + * insignificant memory usage. + * + * @see GetResourceTypeSizeFunc, SetResourceTypeSizeFunc + * + * @param[in] value Pointer to resource object. + * + * @param[in] id Resource ID for the object. + * + * @param[out] size Fill all fields to zero to indicate that size of + * resource can't be determined. + */ +static void +GetDefaultBytes(pointer value, XID id, ResourceSizePtr size) +{ + size->resourceSize = 0; + size->pixmapRefSize = 0; + size->refCnt = 1; +} + +/** + * Used by all resources that don't specify a function to iterate + * through subresources. Currently this is used for all resources with + * insignificant memory usage. + * + * @see FindSubResources, SetResourceTypeFindSubResFunc + * + * @param[in] value Pointer to resource object. + * + * @param[in] func Function to call for each subresource. + + * @param[out] cdata Pointer to opaque data. + */ +static void +DefaultFindSubRes(pointer value, FindAllRes func, pointer cdata) +{ + /* do nothing */ +} + +/** + * Calculate drawable size in bytes. Reference counting is not taken + * into account. + * + * @param[in] drawable Pointer to a drawable. + * + * @return Estimate of total memory usage for the drawable. + */ +static unsigned long +GetDrawableBytes(DrawablePtr drawable) +{ + int bytes = 0; + + if (drawable) + { + int bytesPerPixel = drawable->bitsPerPixel >> 3; + int numberOfPixels = drawable->width * drawable->height; + bytes = numberOfPixels * bytesPerPixel; + } + + return bytes; +} + +/** + * Calculate pixmap size in bytes. Reference counting is taken into + * account. Any extra data attached by extensions and drivers is not + * taken into account. The purpose of this function is to estimate + * memory usage that can be attributed to single reference of the + * pixmap. + * + * @param[in] value Pointer to a pixmap. + * + * @param[in] id Resource ID of pixmap. If the pixmap hasn't been + * added as resource, just pass value->drawable.id. + * + * @param[out] size Estimate of memory usage attributed to a single + * pixmap reference. + */ +static void +GetPixmapBytes(pointer value, XID id, ResourceSizePtr size) +{ + PixmapPtr pixmap = value; + + size->resourceSize = 0; + size->pixmapRefSize = 0; + size->refCnt = pixmap->refcnt; + + if (pixmap && pixmap->refcnt) + { + DrawablePtr drawable = &pixmap->drawable; + size->resourceSize = GetDrawableBytes(drawable); + size->pixmapRefSize = size->resourceSize / pixmap->refcnt; + } +} + +/** + * Calculate window size in bytes. The purpose of this function is to + * estimate memory usage that can be attributed to all pixmap + * references of the window. + * + * @param[in] value Pointer to a window. + * + * @param[in] id Resource ID of window. + * + * @param[out] size Estimate of memory usage attributed to a all + * pixmap references of a window. + */ +static void +GetWindowBytes(pointer value, XID id, ResourceSizePtr size) +{ + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + WindowPtr window = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + + size->refCnt = 1; + + if (window->backgroundState == BackgroundPixmap) + { + PixmapPtr pixmap = window->background.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } + if (window->border.pixmap && !window->borderIsPixel) + { + PixmapPtr pixmap = window->border.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + +/** + * Iterate through subresources of a window. The purpose of this + * function is to gather accurate information on what resources + * a resource uses. + * + * @note Currently only sub-pixmaps are iterated + * + * @param[in] value Pointer to a window + * + * @param[in] func Function to call with each subresource + * + * @param[out] cdata Pointer to opaque data + */ +static void +FindWindowSubRes(pointer value, FindAllRes func, pointer cdata) +{ + WindowPtr window = value; + + /* Currently only pixmap subresources are reported to clients. */ + + if (window->backgroundState == BackgroundPixmap) + { + PixmapPtr pixmap = window->background.pixmap; + func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } + if (window->border.pixmap && !window->borderIsPixel) + { + PixmapPtr pixmap = window->border.pixmap; + func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } +} + +/** + * Calculate graphics context size in bytes. The purpose of this + * function is to estimate memory usage that can be attributed to all + * pixmap references of the graphics context. + * + * @param[in] value Pointer to a graphics context. + * + * @param[in] id Resource ID of graphics context. + * + * @param[out] size Estimate of memory usage attributed to a all + * pixmap references of a graphics context. + */ +static void +GetGcBytes(pointer value, XID id, ResourceSizePtr size) +{ + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + GCPtr gc = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + + size->refCnt = 1; + if (gc->stipple) + { + PixmapPtr pixmap = gc->stipple; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } + if (gc->tile.pixmap && !gc->tileIsPixel) + { + PixmapPtr pixmap = gc->tile.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + +/** + * Iterate through subresources of a graphics context. The purpose of + * this function is to gather accurate information on what resources a + * resource uses. + * + * @note Currently only sub-pixmaps are iterated + * + * @param[in] value Pointer to a window + * + * @param[in] func Function to call with each subresource + * + * @param[out] cdata Pointer to opaque data + */ +static void +FindGCSubRes(pointer value, FindAllRes func, pointer cdata) +{ + GCPtr gc = value; + + /* Currently only pixmap subresources are reported to clients. */ + + if (gc->stipple) + { + PixmapPtr pixmap = gc->stipple; + func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } + if (gc->tile.pixmap && !gc->tileIsPixel) + { + PixmapPtr pixmap = gc->tile.pixmap; + func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } +} + static struct ResourceType *resourceTypes; static const struct ResourceType predefTypes[] = { [RT_NONE & (RC_LASTPREDEF - 1)] = { .deleteFunc = (DeleteType) NoopDDA, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, [RT_WINDOW & (RC_LASTPREDEF - 1)] = { .deleteFunc = DeleteWindow, + .sizeFunc = GetWindowBytes, + .findSubResFunc = FindWindowSubRes, .errorValue = BadWindow, }, [RT_PIXMAP & (RC_LASTPREDEF - 1)] = { .deleteFunc = dixDestroyPixmap, + .sizeFunc = GetPixmapBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadPixmap, }, [RT_GC & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeGC, + .sizeFunc = GetGcBytes, + .findSubResFunc = FindGCSubRes, .errorValue = BadGC, }, [RT_FONT & (RC_LASTPREDEF - 1)] = { .deleteFunc = CloseFont, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadFont, }, [RT_CURSOR & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeCursor, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadCursor, }, [RT_COLORMAP & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeColormap, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadColor, }, [RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeClientPixels, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadColor, }, [RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = { .deleteFunc = OtherClientGone, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, [RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = { .deleteFunc = DeletePassiveGrab, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, }; @@ -256,6 +520,8 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name) lastResourceType = next; resourceTypes = types; resourceTypes[next].deleteFunc = deleteFunc; + resourceTypes[next].sizeFunc = GetDefaultBytes; + resourceTypes[next].findSubResFunc = DefaultFindSubRes; resourceTypes[next].errorValue = BadValue; /* Called even if name is NULL, to remove any previous entry */ @@ -264,6 +530,57 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name) return next; } +/** + * Get the function used to calculate resource size. Extensions and + * drivers need to be able to determine the current size calculation + * function if they want to wrap or override it. + * + * @param[in] type Resource type used in size calculations. + * + * @return Function to calculate the size of a single + * resource. + */ +SizeType +GetResourceTypeSizeFunc(RESTYPE type) +{ + return resourceTypes[type & TypeMask].sizeFunc; +} + +/** + * Override the default function that calculates resource size. For + * example, video driver knows better how to calculate pixmap memory + * usage and can therefore wrap or override size calculation for + * RT_PIXMAP. + * + * @param[in] type Resource type used in size calculations. + * + * @param[in] sizeFunc Function to calculate the size of a single + * resource. + */ +void +SetResourceTypeSizeFunc(RESTYPE type, SizeType sizeFunc) +{ + resourceTypes[type & TypeMask].sizeFunc = sizeFunc; +} + +/** + * Provide a function for iterating the subresources of a resource. + * This allows for example more accurate accounting of the (memory) + * resources consumed by a resource. + * + * @see FindSubResources + * + * @param[in] type Resource type used in size calculations. + * + * @param[in] sizeFunc Function to calculate the size of a single + * resource. + */ +void +SetResourceTypeFindSubResFunc(RESTYPE type, FindTypeSubResources findFunc) +{ + resourceTypes[type & TypeMask].findSubResFunc = findFunc; +} + void SetResourceTypeErrorValue(RESTYPE type, int errorValue) { @@ -326,25 +643,32 @@ InitClientResources(ClientPtr client) return TRUE; } -static int -Hash(int client, XID id) +int +HashResourceID(XID id, int numBits) { id &= RESOURCE_ID_MASK; - switch (clientTable[client].hashsize) { - case 6: - return ((int) (0x03F & (id ^ (id >> 6) ^ (id >> 12)))); - case 7: - return ((int) (0x07F & (id ^ (id >> 7) ^ (id >> 13)))); - case 8: - return ((int) (0x0FF & (id ^ (id >> 8) ^ (id >> 16)))); - case 9: - return ((int) (0x1FF & (id ^ (id >> 9)))); - case 10: - return ((int) (0x3FF & (id ^ (id >> 10)))); - case 11: - return ((int) (0x7FF & (id ^ (id >> 11)))); - } - return -1; + switch (numBits) + { + case 6: + return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12)))); + case 7: + return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13)))); + case 8: + return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16)))); + case 9: + return ((int)(0x1FF & (id ^ (id>>9)))); + case 10: + return ((int)(0x3FF & (id ^ (id>>10)))); + case 11: + return ((int)(0x7FF & (id ^ (id>>11)))); + } + if (numBits >= 11) + return ((int)(0x7FF & (id ^ (id>>11)))); + else + { + assert(numBits >= 0); + return id & ~((~0) << numBits); + } } static XID @@ -355,7 +679,7 @@ AvailableID(int client, XID id, XID maxid, XID goodid) if ((goodid >= id) && (goodid <= maxid)) return goodid; for (; id <= maxid; id++) { - res = clientTable[client].resources[Hash(client, id)]; + res = clientTable[client].resources[HashResourceID(id, clientTable[client].hashsize)]; while (res && (res->id != id)) res = res->next; if (!res) @@ -481,7 +805,7 @@ AddResource(XID id, RESTYPE type, pointer value) } if ((rrec->elements >= 4 * rrec->buckets) && (rrec->hashsize < MAXHASHSIZE)) RebuildTable(client); - head = &rrec->resources[Hash(client, id)]; + head = &rrec->resources[HashResourceID(id, clientTable[client].hashsize)]; res = malloc(sizeof(ResourceRec)); if (!res) { (*resourceTypes[type & TypeMask].deleteFunc) (value, id); @@ -529,7 +853,7 @@ RebuildTable(int client) for (res = *rptr; res; res = next) { next = res->next; res->next = NULL; - tptr = &tails[Hash(client, res->id)]; + tptr = &tails[HashResourceID(res->id, clientTable[client].hashsize)]; **tptr = res; *tptr = &res->next; } @@ -561,7 +885,7 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) int elements; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - head = &clientTable[cid].resources[Hash(cid, id)]; + head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; eltptr = &clientTable[cid].elements; prev = head; @@ -595,7 +919,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) ResourcePtr *prev, *head; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - head = &clientTable[cid].resources[Hash(cid, id)]; + head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; prev = head; while ((res = *prev)) { @@ -630,7 +954,7 @@ ChangeResourceValue(XID id, RESTYPE rtype, pointer value) ResourcePtr res; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if ((res->id == id) && (res->type == rtype)) { @@ -674,6 +998,15 @@ FindClientResourcesByType(ClientPtr client, } } +void FindSubResources(pointer resource, + RESTYPE type, + FindAllRes func, + pointer cdata) +{ + struct ResourceType rtype = resourceTypes[type & TypeMask]; + rtype.findSubResFunc(resource, func, cdata); +} + void FindAllClientResources(ClientPtr client, FindAllRes func, pointer cdata) { @@ -859,7 +1192,7 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype, return BadImplementation; if ((cid < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && res->type == rtype) @@ -892,7 +1225,7 @@ dixLookupResourceByClass(pointer *result, XID id, RESTYPE rclass, *result = NULL; if ((cid < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && (res->type & rclass)) diff --git a/xserver/dix/selection.c b/xserver/dix/selection.c index dfdcfdc64..e905b1ec2 100644 --- a/xserver/dix/selection.c +++ b/xserver/dix/selection.c @@ -174,8 +174,6 @@ ProcSetSelectionOwner(ClientPtr client) rc = dixLookupSelection(&pSel, stuff->selection, client, DixSetAttrAccess); if (rc == Success) { - xEvent event; - /* If the timestamp in client's request is in the past relative to the time stamp indicating the last time the owner of the selection was set, do not set the selection, just return @@ -183,10 +181,12 @@ ProcSetSelectionOwner(ClientPtr client) if (CompareTimeStamps(time, pSel->lastTimeChanged) == EARLIER) return Success; if (pSel->client && (!pWin || (pSel->client != client))) { + xEvent event = { + .u.selectionClear.time = time.milliseconds, + .u.selectionClear.window = pSel->window, + .u.selectionClear.atom = pSel->selection + }; event.u.u.type = SelectionClear; - event.u.selectionClear.time = time.milliseconds; - event.u.selectionClear.window = pSel->window; - event.u.selectionClear.atom = pSel->selection; WriteEventsToClient(pSel->client, 1, &event); } } @@ -238,10 +238,11 @@ ProcGetSelectionOwner(ClientPtr client) return BadAtom; } - memset(&reply, 0, sizeof(xGetSelectionOwnerReply)); - reply.type = X_Reply; - reply.length = 0; - reply.sequenceNumber = client->sequence; + reply = (xGetSelectionOwnerReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + }; rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess); if (rc == Success) diff --git a/xserver/dix/swaprep.c b/xserver/dix/swaprep.c index 9440c4ee3..559fe271e 100644 --- a/xserver/dix/swaprep.c +++ b/xserver/dix/swaprep.c @@ -80,7 +80,7 @@ Swap32Write(ClientPtr pClient, int size, CARD32 *pbuf) { swapl(&pbuf[i]); } - (void) WriteToClient(pClient, size << 2, (char *) pbuf); + WriteToClient(pClient, size << 2, pbuf); } /** @@ -123,7 +123,7 @@ CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf) from++; to++; } - (void) WriteToClient(pClient, nbytes, (char *) pbufT); + WriteToClient(pClient, nbytes, pbufT); } if (pbufT != tmpbuf) @@ -170,7 +170,7 @@ CopySwap16Write(ClientPtr pClient, int size, short *pbuf) from++; to++; } - (void) WriteToClient(pClient, nbytes, (char *) pbufT); + WriteToClient(pClient, nbytes, pbufT); } if (pbufT != tmpbuf) @@ -182,7 +182,7 @@ void SGenericReply(ClientPtr pClient, int size, xGenericReply * pRep) { swaps(&pRep->sequenceNumber); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } /* Extra-large reply */ @@ -200,7 +200,7 @@ SGetWindowAttributesReply(ClientPtr pClient, int size, swapl(&pRep->allEventMasks); swapl(&pRep->yourEventMask); swaps(&pRep->doNotPropagateMask); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -213,7 +213,7 @@ SGetGeometryReply(ClientPtr pClient, int size, xGetGeometryReply * pRep) swaps(&pRep->width); swaps(&pRep->height); swaps(&pRep->borderWidth); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -224,7 +224,7 @@ SQueryTreeReply(ClientPtr pClient, int size, xQueryTreeReply * pRep) swapl(&pRep->root); swapl(&pRep->parent); swaps(&pRep->nChildren); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -232,7 +232,7 @@ SInternAtomReply(ClientPtr pClient, int size, xInternAtomReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->atom); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -241,7 +241,7 @@ SGetAtomNameReply(ClientPtr pClient, int size, xGetAtomNameReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nameLength); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -252,7 +252,7 @@ SGetPropertyReply(ClientPtr pClient, int size, xGetPropertyReply * pRep) swapl(&pRep->propertyType); swapl(&pRep->bytesAfter); swapl(&pRep->nItems); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -261,7 +261,7 @@ SListPropertiesReply(ClientPtr pClient, int size, xListPropertiesReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nProperties); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -270,7 +270,7 @@ SGetSelectionOwnerReply(ClientPtr pClient, int size, { swaps(&pRep->sequenceNumber); swapl(&pRep->owner); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -284,7 +284,7 @@ SQueryPointerReply(ClientPtr pClient, int size, xQueryPointerReply * pRep) swaps(&pRep->winX); swaps(&pRep->winY); swaps(&pRep->mask); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } static void @@ -307,7 +307,7 @@ SwapTimeCoordWrite(ClientPtr pClient, int size, xTimecoord * pRep) SwapTimecoord(pRepT); pRepT++; } - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } @@ -317,7 +317,7 @@ SGetMotionEventsReply(ClientPtr pClient, int size, xGetMotionEventsReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->nEvents); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -327,7 +327,7 @@ STranslateCoordsReply(ClientPtr pClient, int size, xTranslateCoordsReply * pRep) swapl(&pRep->child); swaps(&pRep->dstX); swaps(&pRep->dstY); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -335,7 +335,7 @@ SGetInputFocusReply(ClientPtr pClient, int size, xGetInputFocusReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->focus); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } /* extra long reply */ @@ -344,7 +344,7 @@ SQueryKeymapReply(ClientPtr pClient, int size, xQueryKeymapReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } static void @@ -405,7 +405,7 @@ void SQueryFontReply(ClientPtr pClient, int size, xQueryFontReply * pRep) { SwapFont(pRep, TRUE); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -420,7 +420,7 @@ SQueryTextExtentsReply(ClientPtr pClient, int size, swapl(&pRep->overallWidth); swapl(&pRep->overallLeft); swapl(&pRep->overallRight); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -429,7 +429,7 @@ SListFontsReply(ClientPtr pClient, int size, xListFontsReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nFonts); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -437,7 +437,7 @@ SListFontsWithInfoReply(ClientPtr pClient, int size, xListFontsWithInfoReply * pRep) { SwapFont((xQueryFontReply *) pRep, FALSE); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -446,7 +446,7 @@ SGetFontPathReply(ClientPtr pClient, int size, xGetFontPathReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nPaths); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -455,7 +455,7 @@ SGetImageReply(ClientPtr pClient, int size, xGetImageReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->visual); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); /* Fortunately, image doesn't need swapping */ } @@ -466,7 +466,7 @@ SListInstalledColormapsReply(ClientPtr pClient, int size, swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nColormaps); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -477,7 +477,7 @@ SAllocColorReply(ClientPtr pClient, int size, xAllocColorReply * pRep) swaps(&pRep->green); swaps(&pRep->blue); swapl(&pRep->pixel); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -491,7 +491,7 @@ SAllocNamedColorReply(ClientPtr pClient, int size, xAllocNamedColorReply * pRep) swaps(&pRep->screenRed); swaps(&pRep->screenGreen); swaps(&pRep->screenBlue); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -501,7 +501,7 @@ SAllocColorCellsReply(ClientPtr pClient, int size, xAllocColorCellsReply * pRep) swapl(&pRep->length); swaps(&pRep->nPixels); swaps(&pRep->nMasks); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -514,7 +514,7 @@ SAllocColorPlanesReply(ClientPtr pClient, int size, swapl(&pRep->redMask); swapl(&pRep->greenMask); swapl(&pRep->blueMask); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } static void @@ -537,7 +537,7 @@ SQColorsExtend(ClientPtr pClient, int size, xrgb * prgb) SwapRGB(prgbT); prgbT++; } - (void) WriteToClient(pClient, size, (char *) prgb); + WriteToClient(pClient, size, prgb); } void @@ -546,7 +546,7 @@ SQueryColorsReply(ClientPtr pClient, int size, xQueryColorsReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nColors); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -559,7 +559,7 @@ SLookupColorReply(ClientPtr pClient, int size, xLookupColorReply * pRep) swaps(&pRep->screenRed); swaps(&pRep->screenGreen); swaps(&pRep->screenBlue); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -568,7 +568,7 @@ SQueryBestSizeReply(ClientPtr pClient, int size, xQueryBestSizeReply * pRep) swaps(&pRep->sequenceNumber); swaps(&pRep->width); swaps(&pRep->height); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -576,7 +576,7 @@ SListExtensionsReply(ClientPtr pClient, int size, xListExtensionsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -585,7 +585,7 @@ SGetKeyboardMappingReply(ClientPtr pClient, int size, { swaps(&pRep->sequenceNumber); swapl(&pRep->length); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -594,7 +594,7 @@ SGetPointerMappingReply(ClientPtr pClient, int size, { swaps(&pRep->sequenceNumber); swapl(&pRep->length); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -603,7 +603,7 @@ SGetModifierMappingReply(ClientPtr pClient, int size, { swaps(&pRep->sequenceNumber); swapl(&pRep->length); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -615,7 +615,7 @@ SGetKeyboardControlReply(ClientPtr pClient, int size, swapl(&pRep->ledMask); swaps(&pRep->bellPitch); swaps(&pRep->bellDuration); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -626,7 +626,7 @@ SGetPointerControlReply(ClientPtr pClient, int size, swaps(&pRep->accelNumerator); swaps(&pRep->accelDenominator); swaps(&pRep->threshold); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -635,7 +635,7 @@ SGetScreenSaverReply(ClientPtr pClient, int size, xGetScreenSaverReply * pRep) swaps(&pRep->sequenceNumber); swaps(&pRep->timeout); swaps(&pRep->interval); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -651,7 +651,7 @@ SLHostsExtend(ClientPtr pClient, int size, char *buf) swaps(&host->length); bufT += sizeof(xHostEntry) + pad_to_int32(len); } - (void) WriteToClient(pClient, size, buf); + WriteToClient(pClient, size, buf); } void @@ -660,7 +660,7 @@ SListHostsReply(ClientPtr pClient, int size, xListHostsReply * pRep) swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nHosts); - (void) WriteToClient(pClient, size, (char *) pRep); + WriteToClient(pClient, size, pRep); } void @@ -1140,7 +1140,7 @@ WriteSConnectionInfo(ClientPtr pClient, unsigned long size, char *pInfo) return; } SwapConnSetupInfo(pInfo, pInfoTBase); - (void) WriteToClient(pClient, (int) size, (char *) pInfoTBase); + WriteToClient(pClient, (int) size, pInfoTBase); free(pInfoTBase); } @@ -1160,7 +1160,7 @@ WriteSConnSetupPrefix(ClientPtr pClient, xConnSetupPrefix * pcsp) xConnSetupPrefix cspT; SwapConnSetupPrefix(pcsp, &cspT); - (void) WriteToClient(pClient, sizeof(cspT), (char *) &cspT); + WriteToClient(pClient, sizeof(cspT), &cspT); } /* diff --git a/xserver/dix/swapreq.c b/xserver/dix/swapreq.c index a896b4b29..0f6d49ef0 100644 --- a/xserver/dix/swapreq.c +++ b/xserver/dix/swapreq.c @@ -283,7 +283,7 @@ SProcConvertSelection(ClientPtr client) int SProcSendEvent(ClientPtr client) { - xEvent eventT; + xEvent eventT = { .u.u.type = 0 }; EventSwapPtr proc; REQUEST(xSendEventReq); diff --git a/xserver/dix/tables.c b/xserver/dix/tables.c index 705ef0d4d..686cddd7d 100644 --- a/xserver/dix/tables.c +++ b/xserver/dix/tables.c @@ -58,364 +58,529 @@ SOFTWARE. #include "swaprep.h" #include "swapreq.h" -int (*InitialVector[3]) (ClientPtr /* client */ - ) = { -0, ProcInitialConnection, ProcEstablishConnection}; +int (*InitialVector[3]) (ClientPtr /* client */) = { + 0, + ProcInitialConnection, + ProcEstablishConnection +}; -int (*ProcVector[256]) (ClientPtr /* client */ - ) = { - ProcBadRequest, ProcCreateWindow, ProcChangeWindowAttributes, ProcGetWindowAttributes, ProcDestroyWindow, ProcDestroySubwindows, /* 5 */ - ProcChangeSaveSet, ProcReparentWindow, ProcMapWindow, ProcMapSubwindows, ProcUnmapWindow, /* 10 */ - ProcUnmapSubwindows, ProcConfigureWindow, ProcCirculateWindow, ProcGetGeometry, ProcQueryTree, /* 15 */ - ProcInternAtom, ProcGetAtomName, ProcChangeProperty, ProcDeleteProperty, ProcGetProperty, /* 20 */ - ProcListProperties, ProcSetSelectionOwner, ProcGetSelectionOwner, ProcConvertSelection, ProcSendEvent, /* 25 */ - ProcGrabPointer, ProcUngrabPointer, ProcGrabButton, ProcUngrabButton, ProcChangeActivePointerGrab, /* 30 */ - ProcGrabKeyboard, ProcUngrabKeyboard, ProcGrabKey, ProcUngrabKey, ProcAllowEvents, /* 35 */ - ProcGrabServer, ProcUngrabServer, ProcQueryPointer, ProcGetMotionEvents, ProcTranslateCoords, /* 40 */ - ProcWarpPointer, ProcSetInputFocus, ProcGetInputFocus, ProcQueryKeymap, ProcOpenFont, /* 45 */ - ProcCloseFont, ProcQueryFont, ProcQueryTextExtents, ProcListFonts, ProcListFontsWithInfo, /* 50 */ - ProcSetFontPath, ProcGetFontPath, ProcCreatePixmap, ProcFreePixmap, ProcCreateGC, /* 55 */ - ProcChangeGC, ProcCopyGC, ProcSetDashes, ProcSetClipRectangles, ProcFreeGC, /* 60 */ - ProcClearToBackground, ProcCopyArea, ProcCopyPlane, ProcPolyPoint, ProcPolyLine, /* 65 */ - ProcPolySegment, ProcPolyRectangle, ProcPolyArc, ProcFillPoly, ProcPolyFillRectangle, /* 70 */ - ProcPolyFillArc, ProcPutImage, ProcGetImage, ProcPolyText, ProcPolyText, /* 75 */ - ProcImageText8, ProcImageText16, ProcCreateColormap, ProcFreeColormap, ProcCopyColormapAndFree, /* 80 */ - ProcInstallColormap, ProcUninstallColormap, ProcListInstalledColormaps, ProcAllocColor, ProcAllocNamedColor, /* 85 */ - ProcAllocColorCells, ProcAllocColorPlanes, ProcFreeColors, ProcStoreColors, ProcStoreNamedColor, /* 90 */ - ProcQueryColors, ProcLookupColor, ProcCreateCursor, ProcCreateGlyphCursor, ProcFreeCursor, /* 95 */ - ProcRecolorCursor, ProcQueryBestSize, ProcQueryExtension, ProcListExtensions, ProcChangeKeyboardMapping, /* 100 */ - ProcGetKeyboardMapping, ProcChangeKeyboardControl, ProcGetKeyboardControl, ProcBell, ProcChangePointerControl, /* 105 */ - ProcGetPointerControl, ProcSetScreenSaver, ProcGetScreenSaver, ProcChangeHosts, ProcListHosts, /* 110 */ - ProcChangeAccessControl, ProcChangeCloseDownMode, ProcKillClient, ProcRotateProperties, ProcForceScreenSaver, /* 115 */ - ProcSetPointerMapping, ProcGetPointerMapping, ProcSetModifierMapping, ProcGetModifierMapping, ProcBadRequest, /* 120 */ - ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, /* 125 */ -ProcBadRequest, - ProcNoOperation, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest}; +int (*ProcVector[256]) (ClientPtr /* client */) = { + ProcBadRequest, + ProcCreateWindow, + ProcChangeWindowAttributes, + ProcGetWindowAttributes, + ProcDestroyWindow, + ProcDestroySubwindows, /* 5 */ + ProcChangeSaveSet, + ProcReparentWindow, + ProcMapWindow, + ProcMapSubwindows, + ProcUnmapWindow, /* 10 */ + ProcUnmapSubwindows, + ProcConfigureWindow, + ProcCirculateWindow, + ProcGetGeometry, + ProcQueryTree, /* 15 */ + ProcInternAtom, + ProcGetAtomName, + ProcChangeProperty, + ProcDeleteProperty, + ProcGetProperty, /* 20 */ + ProcListProperties, + ProcSetSelectionOwner, + ProcGetSelectionOwner, + ProcConvertSelection, + ProcSendEvent, /* 25 */ + ProcGrabPointer, + ProcUngrabPointer, + ProcGrabButton, + ProcUngrabButton, + ProcChangeActivePointerGrab, /* 30 */ + ProcGrabKeyboard, + ProcUngrabKeyboard, + ProcGrabKey, + ProcUngrabKey, + ProcAllowEvents, /* 35 */ + ProcGrabServer, + ProcUngrabServer, + ProcQueryPointer, + ProcGetMotionEvents, + ProcTranslateCoords, /* 40 */ + ProcWarpPointer, + ProcSetInputFocus, + ProcGetInputFocus, + ProcQueryKeymap, + ProcOpenFont, /* 45 */ + ProcCloseFont, + ProcQueryFont, + ProcQueryTextExtents, + ProcListFonts, + ProcListFontsWithInfo, /* 50 */ + ProcSetFontPath, + ProcGetFontPath, + ProcCreatePixmap, + ProcFreePixmap, + ProcCreateGC, /* 55 */ + ProcChangeGC, + ProcCopyGC, + ProcSetDashes, + ProcSetClipRectangles, + ProcFreeGC, /* 60 */ + ProcClearToBackground, + ProcCopyArea, + ProcCopyPlane, + ProcPolyPoint, + ProcPolyLine, /* 65 */ + ProcPolySegment, + ProcPolyRectangle, + ProcPolyArc, + ProcFillPoly, + ProcPolyFillRectangle, /* 70 */ + ProcPolyFillArc, + ProcPutImage, + ProcGetImage, + ProcPolyText, + ProcPolyText, /* 75 */ + ProcImageText8, + ProcImageText16, + ProcCreateColormap, + ProcFreeColormap, + ProcCopyColormapAndFree, /* 80 */ + ProcInstallColormap, + ProcUninstallColormap, + ProcListInstalledColormaps, + ProcAllocColor, + ProcAllocNamedColor, /* 85 */ + ProcAllocColorCells, + ProcAllocColorPlanes, + ProcFreeColors, + ProcStoreColors, + ProcStoreNamedColor, /* 90 */ + ProcQueryColors, + ProcLookupColor, + ProcCreateCursor, + ProcCreateGlyphCursor, + ProcFreeCursor, /* 95 */ + ProcRecolorCursor, + ProcQueryBestSize, + ProcQueryExtension, + ProcListExtensions, + ProcChangeKeyboardMapping, /* 100 */ + ProcGetKeyboardMapping, + ProcChangeKeyboardControl, + ProcGetKeyboardControl, + ProcBell, + ProcChangePointerControl, /* 105 */ + ProcGetPointerControl, + ProcSetScreenSaver, + ProcGetScreenSaver, + ProcChangeHosts, + ProcListHosts, /* 110 */ + ProcChangeAccessControl, + ProcChangeCloseDownMode, + ProcKillClient, + ProcRotateProperties, + ProcForceScreenSaver, /* 115 */ + ProcSetPointerMapping, + ProcGetPointerMapping, + ProcSetModifierMapping, + ProcGetModifierMapping, + ProcBadRequest, /* 120 */ + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, /* 125 */ + ProcBadRequest, + ProcNoOperation, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest +}; -int (*SwappedProcVector[256]) (ClientPtr /* client */ - ) = { - ProcBadRequest, SProcCreateWindow, SProcChangeWindowAttributes, SProcResourceReq, /* GetWindowAttributes */ - SProcResourceReq, /* DestroyWindow */ - SProcResourceReq, /* 5 DestroySubwindows */ - SProcResourceReq, /* SProcChangeSaveSet, */ - SProcReparentWindow, SProcResourceReq, /* MapWindow */ - SProcResourceReq, /* MapSubwindows */ - SProcResourceReq, /* 10 UnmapWindow */ - SProcResourceReq, /* UnmapSubwindows */ - SProcConfigureWindow, SProcResourceReq, /* SProcCirculateWindow, */ - SProcResourceReq, /* GetGeometry */ - SProcResourceReq, /* 15 QueryTree */ - SProcInternAtom, SProcResourceReq, /* SProcGetAtomName, */ - SProcChangeProperty, SProcDeleteProperty, SProcGetProperty, /* 20 */ - SProcResourceReq, /* SProcListProperties, */ - SProcSetSelectionOwner, SProcResourceReq, /* SProcGetSelectionOwner, */ - SProcConvertSelection, SProcSendEvent, /* 25 */ - SProcGrabPointer, SProcResourceReq, /* SProcUngrabPointer, */ - SProcGrabButton, SProcUngrabButton, SProcChangeActivePointerGrab, /* 30 */ - SProcGrabKeyboard, SProcResourceReq, /* SProcUngrabKeyboard, */ - SProcGrabKey, SProcUngrabKey, SProcResourceReq, /* 35 SProcAllowEvents, */ - SProcSimpleReq, /* SProcGrabServer, */ - SProcSimpleReq, /* SProcUngrabServer, */ - SProcResourceReq, /* SProcQueryPointer, */ - SProcGetMotionEvents, SProcTranslateCoords, /*40 */ - SProcWarpPointer, SProcSetInputFocus, SProcSimpleReq, /* SProcGetInputFocus, */ - SProcSimpleReq, /* QueryKeymap, */ - SProcOpenFont, /* 45 */ - SProcResourceReq, /* SProcCloseFont, */ - SProcResourceReq, /* SProcQueryFont, */ - SProcResourceReq, /* SProcQueryTextExtents, */ - SProcListFonts, SProcListFontsWithInfo, /* 50 */ - SProcSetFontPath, SProcSimpleReq, /* GetFontPath, */ - SProcCreatePixmap, SProcResourceReq, /* SProcFreePixmap, */ - SProcCreateGC, /* 55 */ - SProcChangeGC, SProcCopyGC, SProcSetDashes, SProcSetClipRectangles, SProcResourceReq, /* 60 SProcFreeGC, */ - SProcClearToBackground, SProcCopyArea, SProcCopyPlane, SProcPoly, /* PolyPoint, */ - SProcPoly, /* 65 PolyLine */ - SProcPoly, /* PolySegment, */ - SProcPoly, /* PolyRectangle, */ - SProcPoly, /* PolyArc, */ - SProcFillPoly, SProcPoly, /* 70 PolyFillRectangle */ - SProcPoly, /* PolyFillArc, */ - SProcPutImage, SProcGetImage, SProcPolyText, SProcPolyText, /* 75 */ - SProcImageText, SProcImageText, SProcCreateColormap, SProcResourceReq, /* SProcFreeColormap, */ - SProcCopyColormapAndFree, /* 80 */ - SProcResourceReq, /* SProcInstallColormap, */ - SProcResourceReq, /* SProcUninstallColormap, */ - SProcResourceReq, /* SProcListInstalledColormaps, */ - SProcAllocColor, SProcAllocNamedColor, /* 85 */ - SProcAllocColorCells, SProcAllocColorPlanes, SProcFreeColors, SProcStoreColors, SProcStoreNamedColor, /* 90 */ - SProcQueryColors, SProcLookupColor, SProcCreateCursor, SProcCreateGlyphCursor, SProcResourceReq, /* 95 SProcFreeCursor, */ - SProcRecolorCursor, SProcQueryBestSize, SProcQueryExtension, SProcSimpleReq, /* ListExtensions, */ - SProcChangeKeyboardMapping, /* 100 */ - SProcSimpleReq, /* GetKeyboardMapping, */ - SProcChangeKeyboardControl, SProcSimpleReq, /* GetKeyboardControl, */ - SProcSimpleReq, /* Bell, */ - SProcChangePointerControl, /* 105 */ - SProcSimpleReq, /* GetPointerControl, */ - SProcSetScreenSaver, SProcSimpleReq, /* GetScreenSaver, */ - SProcChangeHosts, SProcSimpleReq, /* 110 ListHosts, */ - SProcSimpleReq, /* SProcChangeAccessControl, */ - SProcSimpleReq, /* SProcChangeCloseDownMode, */ - SProcResourceReq, /* SProcKillClient, */ - SProcRotateProperties, SProcSimpleReq, /* 115 ForceScreenSaver */ - SProcSimpleReq, /* SetPointerMapping, */ - SProcSimpleReq, /* GetPointerMapping, */ - SProcSimpleReq, /* SetModifierMapping, */ - SProcSimpleReq, /* GetModifierMapping, */ - ProcBadRequest, /* 120 */ - ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, /* 125 */ -ProcBadRequest, - SProcNoOperation, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, - ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest}; +int (*SwappedProcVector[256]) (ClientPtr /* client */) = { + ProcBadRequest, + SProcCreateWindow, + SProcChangeWindowAttributes, + SProcResourceReq, /* GetWindowAttributes */ + SProcResourceReq, /* DestroyWindow */ + SProcResourceReq, /* 5 DestroySubwindows */ + SProcResourceReq, /* SProcChangeSaveSet, */ + SProcReparentWindow, + SProcResourceReq, /* MapWindow */ + SProcResourceReq, /* MapSubwindows */ + SProcResourceReq, /* 10 UnmapWindow */ + SProcResourceReq, /* UnmapSubwindows */ + SProcConfigureWindow, + SProcResourceReq, /* SProcCirculateWindow, */ + SProcResourceReq, /* GetGeometry */ + SProcResourceReq, /* 15 QueryTree */ + SProcInternAtom, + SProcResourceReq, /* SProcGetAtomName, */ + SProcChangeProperty, + SProcDeleteProperty, + SProcGetProperty, /* 20 */ + SProcResourceReq, /* SProcListProperties, */ + SProcSetSelectionOwner, + SProcResourceReq, /* SProcGetSelectionOwner, */ + SProcConvertSelection, + SProcSendEvent, /* 25 */ + SProcGrabPointer, + SProcResourceReq, /* SProcUngrabPointer, */ + SProcGrabButton, + SProcUngrabButton, + SProcChangeActivePointerGrab, /* 30 */ + SProcGrabKeyboard, + SProcResourceReq, /* SProcUngrabKeyboard, */ + SProcGrabKey, + SProcUngrabKey, + SProcResourceReq, /* 35 SProcAllowEvents, */ + SProcSimpleReq, /* SProcGrabServer, */ + SProcSimpleReq, /* SProcUngrabServer, */ + SProcResourceReq, /* SProcQueryPointer, */ + SProcGetMotionEvents, + SProcTranslateCoords, /*40 */ + SProcWarpPointer, + SProcSetInputFocus, + SProcSimpleReq, /* SProcGetInputFocus, */ + SProcSimpleReq, /* QueryKeymap, */ + SProcOpenFont, /* 45 */ + SProcResourceReq, /* SProcCloseFont, */ + SProcResourceReq, /* SProcQueryFont, */ + SProcResourceReq, /* SProcQueryTextExtents, */ + SProcListFonts, + SProcListFontsWithInfo, /* 50 */ + SProcSetFontPath, + SProcSimpleReq, /* GetFontPath, */ + SProcCreatePixmap, + SProcResourceReq, /* SProcFreePixmap, */ + SProcCreateGC, /* 55 */ + SProcChangeGC, + SProcCopyGC, + SProcSetDashes, + SProcSetClipRectangles, + SProcResourceReq, /* 60 SProcFreeGC, */ + SProcClearToBackground, + SProcCopyArea, + SProcCopyPlane, + SProcPoly, /* PolyPoint, */ + SProcPoly, /* 65 PolyLine */ + SProcPoly, /* PolySegment, */ + SProcPoly, /* PolyRectangle, */ + SProcPoly, /* PolyArc, */ + SProcFillPoly, + SProcPoly, /* 70 PolyFillRectangle */ + SProcPoly, /* PolyFillArc, */ + SProcPutImage, + SProcGetImage, + SProcPolyText, + SProcPolyText, /* 75 */ + SProcImageText, + SProcImageText, + SProcCreateColormap, + SProcResourceReq, /* SProcFreeColormap, */ + SProcCopyColormapAndFree, /* 80 */ + SProcResourceReq, /* SProcInstallColormap, */ + SProcResourceReq, /* SProcUninstallColormap, */ + SProcResourceReq, /* SProcListInstalledColormaps, */ + SProcAllocColor, + SProcAllocNamedColor, /* 85 */ + SProcAllocColorCells, + SProcAllocColorPlanes, + SProcFreeColors, + SProcStoreColors, + SProcStoreNamedColor, /* 90 */ + SProcQueryColors, + SProcLookupColor, + SProcCreateCursor, + SProcCreateGlyphCursor, + SProcResourceReq, /* 95 SProcFreeCursor, */ + SProcRecolorCursor, + SProcQueryBestSize, + SProcQueryExtension, + SProcSimpleReq, /* ListExtensions, */ + SProcChangeKeyboardMapping, /* 100 */ + SProcSimpleReq, /* GetKeyboardMapping, */ + SProcChangeKeyboardControl, + SProcSimpleReq, /* GetKeyboardControl, */ + SProcSimpleReq, /* Bell, */ + SProcChangePointerControl, /* 105 */ + SProcSimpleReq, /* GetPointerControl, */ + SProcSetScreenSaver, + SProcSimpleReq, /* GetScreenSaver, */ + SProcChangeHosts, + SProcSimpleReq, /* 110 ListHosts, */ + SProcSimpleReq, /* SProcChangeAccessControl, */ + SProcSimpleReq, /* SProcChangeCloseDownMode, */ + SProcResourceReq, /* SProcKillClient, */ + SProcRotateProperties, + SProcSimpleReq, /* 115 ForceScreenSaver */ + SProcSimpleReq, /* SetPointerMapping, */ + SProcSimpleReq, /* GetPointerMapping, */ + SProcSimpleReq, /* SetModifierMapping, */ + SProcSimpleReq, /* GetModifierMapping, */ + ProcBadRequest, /* 120 */ + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, /* 125 */ + ProcBadRequest, + SProcNoOperation, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest, + ProcBadRequest +}; EventSwapPtr EventSwapVector[MAXEVENTS] = { (EventSwapPtr) SErrorEvent, @@ -423,32 +588,32 @@ EventSwapPtr EventSwapVector[MAXEVENTS] = { SKeyButtonPtrEvent, SKeyButtonPtrEvent, SKeyButtonPtrEvent, - SKeyButtonPtrEvent, /* 5 */ + SKeyButtonPtrEvent, /* 5 */ SKeyButtonPtrEvent, SEnterLeaveEvent, SEnterLeaveEvent, SFocusEvent, - SFocusEvent, /* 10 */ + SFocusEvent, /* 10 */ SKeymapNotifyEvent, SExposeEvent, SGraphicsExposureEvent, SNoExposureEvent, - SVisibilityEvent, /* 15 */ + SVisibilityEvent, /* 15 */ SCreateNotifyEvent, SDestroyNotifyEvent, SUnmapNotifyEvent, SMapNotifyEvent, - SMapRequestEvent, /* 20 */ + SMapRequestEvent, /* 20 */ SReparentEvent, SConfigureNotifyEvent, SConfigureRequestEvent, SGravityEvent, - SResizeRequestEvent, /* 25 */ + SResizeRequestEvent, /* 25 */ SCirculateEvent, SCirculateEvent, SPropertyEvent, SSelectionClearEvent, - SSelectionRequestEvent, /* 30 */ + SSelectionRequestEvent, /* 30 */ SSelectionNotifyEvent, SColormapEvent, SClientMessageEvent, @@ -554,37 +719,37 @@ ReplySwapPtr ReplySwapVector[256] = { ReplyNotSwappd, (ReplySwapPtr) SGetWindowAttributesReply, ReplyNotSwappd, - ReplyNotSwappd, /* 5 */ + ReplyNotSwappd, /* 5 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 10 */ + ReplyNotSwappd, /* 10 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SGetGeometryReply, - (ReplySwapPtr) SQueryTreeReply, /* 15 */ + (ReplySwapPtr) SQueryTreeReply, /* 15 */ (ReplySwapPtr) SInternAtomReply, (ReplySwapPtr) SGetAtomNameReply, ReplyNotSwappd, ReplyNotSwappd, - (ReplySwapPtr) SGetPropertyReply, /* 20 */ + (ReplySwapPtr) SGetPropertyReply, /* 20 */ (ReplySwapPtr) SListPropertiesReply, ReplyNotSwappd, (ReplySwapPtr) SGetSelectionOwnerReply, ReplyNotSwappd, - ReplyNotSwappd, /* 25 */ - (ReplySwapPtr) SGenericReply, /* SGrabPointerReply, */ + ReplyNotSwappd, /* 25 */ + (ReplySwapPtr) SGenericReply, /* SGrabPointerReply, */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 30 */ - (ReplySwapPtr) SGenericReply, /* SGrabKeyboardReply, */ + ReplyNotSwappd, /* 30 */ + (ReplySwapPtr) SGenericReply, /* SGrabKeyboardReply, */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 35 */ + ReplyNotSwappd, /* 35 */ ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SQueryPointerReply, @@ -594,7 +759,7 @@ ReplySwapPtr ReplySwapVector[256] = { ReplyNotSwappd, (ReplySwapPtr) SGetInputFocusReply, (ReplySwapPtr) SQueryKeymapReply, - ReplyNotSwappd, /* 45 */ + ReplyNotSwappd, /* 45 */ ReplyNotSwappd, (ReplySwapPtr) SQueryFontReply, (ReplySwapPtr) SQueryTextExtentsReply, @@ -604,32 +769,32 @@ ReplySwapPtr ReplySwapVector[256] = { (ReplySwapPtr) SGetFontPathReply, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 55 */ + ReplyNotSwappd, /* 55 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 60 */ + ReplyNotSwappd, /* 60 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 65 */ + ReplyNotSwappd, /* 65 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 70 */ + ReplyNotSwappd, /* 70 */ ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SGetImageReply, ReplyNotSwappd, - ReplyNotSwappd, /* 75 */ + ReplyNotSwappd, /* 75 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 80 */ + ReplyNotSwappd, /* 80 */ ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SListInstalledColormapsReply, @@ -639,44 +804,44 @@ ReplySwapPtr ReplySwapVector[256] = { (ReplySwapPtr) SAllocColorPlanesReply, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 90 */ + ReplyNotSwappd, /* 90 */ (ReplySwapPtr) SQueryColorsReply, (ReplySwapPtr) SLookupColorReply, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 95 */ + ReplyNotSwappd, /* 95 */ ReplyNotSwappd, (ReplySwapPtr) SQueryBestSizeReply, - (ReplySwapPtr) SGenericReply, /* SQueryExtensionReply, */ + (ReplySwapPtr) SGenericReply, /* SQueryExtensionReply, */ (ReplySwapPtr) SListExtensionsReply, - ReplyNotSwappd, /* 100 */ + ReplyNotSwappd, /* 100 */ (ReplySwapPtr) SGetKeyboardMappingReply, ReplyNotSwappd, (ReplySwapPtr) SGetKeyboardControlReply, ReplyNotSwappd, - ReplyNotSwappd, /* 105 */ + ReplyNotSwappd, /* 105 */ (ReplySwapPtr) SGetPointerControlReply, ReplyNotSwappd, (ReplySwapPtr) SGetScreenSaverReply, ReplyNotSwappd, - (ReplySwapPtr) SListHostsReply, /* 110 */ + (ReplySwapPtr) SListHostsReply, /* 110 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, - ReplyNotSwappd, /* 115 */ - (ReplySwapPtr) SGenericReply, /* SetPointerMapping */ + ReplyNotSwappd, /* 115 */ + (ReplySwapPtr) SGenericReply, /* SetPointerMapping */ (ReplySwapPtr) SGetPointerMappingReply, - (ReplySwapPtr) SGenericReply, /* SetModifierMapping */ + (ReplySwapPtr) SGenericReply, /* SetModifierMapping */ (ReplySwapPtr) SGetModifierMappingReply, /* 119 */ - ReplyNotSwappd, /* 120 */ - ReplyNotSwappd, /* 121 */ - ReplyNotSwappd, /* 122 */ - ReplyNotSwappd, /* 123 */ - ReplyNotSwappd, /* 124 */ - ReplyNotSwappd, /* 125 */ - ReplyNotSwappd, /* 126 */ - ReplyNotSwappd, /* NoOperation */ + ReplyNotSwappd, /* 120 */ + ReplyNotSwappd, /* 121 */ + ReplyNotSwappd, /* 122 */ + ReplyNotSwappd, /* 123 */ + ReplyNotSwappd, /* 124 */ + ReplyNotSwappd, /* 125 */ + ReplyNotSwappd, /* 126 */ + ReplyNotSwappd, /* NoOperation */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, diff --git a/xserver/dix/touch.c b/xserver/dix/touch.c index 04733ab35..891cc7803 100644 --- a/xserver/dix/touch.c +++ b/xserver/dix/touch.c @@ -103,11 +103,11 @@ TouchResizeQueue(ClientPtr client, pointer closure) tmp = realloc(dev->last.touches, size * sizeof(*dev->last.touches)); if (tmp) { - int i; + int j; dev->last.touches = tmp; - for (i = dev->last.num_touches; i < size; i++) - TouchInitDDXTouchPoint(dev, &dev->last.touches[i]); + for (j = dev->last.num_touches; j < size; j++) + TouchInitDDXTouchPoint(dev, &dev->last.touches[j]); dev->last.num_touches = size; } @@ -160,11 +160,13 @@ TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id) int i; TouchClassPtr t = dev->touch; DDXTouchPointInfoPtr ti = NULL; - Bool emulate_pointer = (t->mode == XIDirectTouch); + Bool emulate_pointer; if (!t) return NULL; + emulate_pointer = (t->mode == XIDirectTouch); + /* Look for another active touchpoint with the same DDX ID. DDX * touchpoints must be unique. */ if (TouchFindByDDXID(dev, ddx_id, FALSE)) @@ -198,8 +200,9 @@ TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id) /* If we get here, then we've run out of touches and we need to drop the * event (we're inside the SIGIO handler here) schedule a WorkProc to * grow the queue for us for next time. */ - ErrorF("%s: not enough space for touch events (max %d touchpoints). " - "Dropping this event.\n", dev->name, dev->last.num_touches); + ErrorFSigSafe("%s: not enough space for touch events (max %u touchpoints). " + "Dropping this event.\n", dev->name, dev->last.num_touches); + if (!BitIsOn(resize_waiting, dev->id)) { SetBit(resize_waiting, dev->id); QueueWorkProc(TouchResizeQueue, serverClient, NULL); @@ -460,45 +463,14 @@ TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev) void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource) { - InternalEvent *tel; - ValuatorMask *mask; - int i, nev; - int flags; + int i; if (!ti->history) return; - tel = InitEventList(GetMaximumEventsNum()); - mask = valuator_mask_new(0); - - valuator_mask_set_double(mask, 0, ti->history[0].valuators.data[0]); - valuator_mask_set_double(mask, 1, ti->history[0].valuators.data[1]); - - flags = TOUCH_CLIENT_ID | TOUCH_REPLAYING; - if (ti->emulate_pointer) - flags |= TOUCH_POINTER_EMULATED; - /* Generate events based on a fake touch begin event to get DCCE events if - * needed */ - /* FIXME: This needs to be cleaned up */ - nev = GetTouchEvents(tel, dev, ti->client_id, XI_TouchBegin, flags, mask); - for (i = 0; i < nev; i++) { - /* Send saved touch begin event */ - if (tel[i].any.type == ET_TouchBegin) { - DeviceEvent *ev = &ti->history[0]; - ev->flags |= TOUCH_REPLAYING; - DeliverTouchEvents(dev, ti, (InternalEvent*)ev, resource); - } - else {/* Send DCCE event */ - tel[i].any.time = ti->history[0].time; - DeliverTouchEvents(dev, ti, tel + i, resource); - } - } - - valuator_mask_free(&mask); - FreeEventList(tel, GetMaximumEventsNum()); + TouchDeliverDeviceClassesChangedEvent(ti, ti->history[0].time, resource); - /* First event was TouchBegin, already replayed that one */ - for (i = 1; i < ti->history_elements; i++) { + for (i = 0; i < ti->history_elements; i++) { DeviceEvent *ev = &ti->history[i]; ev->flags |= TOUCH_REPLAYING; @@ -506,6 +478,30 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource) } } +void +TouchDeliverDeviceClassesChangedEvent(TouchPointInfoPtr ti, Time time, + XID resource) +{ + DeviceIntPtr dev; + int num_events = 0; + InternalEvent dcce; + + dixLookupDevice(&dev, ti->sourceid, serverClient, DixWriteAccess); + + if (!dev) + return; + + /* UpdateFromMaster generates at most one event */ + UpdateFromMaster(&dcce, dev, DEVCHANGE_POINTER_EVENT, &num_events); + BUG_WARN(num_events > 1); + + if (num_events) { + dcce.any.time = time; + /* FIXME: This doesn't do anything */ + dev->public.processInputProc(&dcce, dev); + } +} + Bool TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite) { @@ -569,8 +565,8 @@ TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, return FALSE; /* Mark which grabs/event selections we're delivering to: max one grab per - * window plus the bottom-most event selection. */ - ti->listeners = calloc(sprite->spriteTraceGood + 1, sizeof(*ti->listeners)); + * window plus the bottom-most event selection, plus any active grab. */ + ti->listeners = calloc(sprite->spriteTraceGood + 2, sizeof(*ti->listeners)); if (!ti->listeners) { sprite->spriteTraceGood = 0; return FALSE; @@ -601,8 +597,8 @@ TouchConvertToPointerEvent(const InternalEvent *event, int ptrtype; int nevents = 0; - BUG_WARN(!event); - BUG_WARN(!motion_event); + BUG_RETURN_VAL(!event, 0); + BUG_RETURN_VAL(!motion_event, 0); switch (event->any.type) { case ET_TouchUpdate: @@ -630,7 +626,7 @@ TouchConvertToPointerEvent(const InternalEvent *event, motion_event->device_event.flags = XIPointerEmulated; if (nevents > 1) { - BUG_WARN(!button_event); + BUG_RETURN_VAL(!button_event, 0); *button_event = *event; button_event->any.type = ptrtype; button_event->device_event.flags = XIPointerEmulated; @@ -679,15 +675,20 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource) * Add the resource to this touch's listeners. */ void -TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level, - enum TouchListenerType type, enum TouchListenerState state, - WindowPtr window) +TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type, + enum InputLevel level, enum TouchListenerType type, + enum TouchListenerState state, WindowPtr window, + GrabPtr grab) { ti->listeners[ti->num_listeners].listener = resource; + ti->listeners[ti->num_listeners].resource_type = resource_type; ti->listeners[ti->num_listeners].level = level; ti->listeners[ti->num_listeners].state = state; ti->listeners[ti->num_listeners].type = type; ti->listeners[ti->num_listeners].window = window; + ti->listeners[ti->num_listeners].grab = grab; + if (grab) + ti->num_grabs++; ti->num_listeners++; } @@ -706,6 +707,11 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource) if (ti->listeners[i].listener == resource) { int j; + if (ti->listeners[i].grab) { + ti->listeners[i].grab = NULL; + ti->num_grabs--; + } + for (j = i; j < ti->num_listeners - 1; j++) ti->listeners[j] = ti->listeners[j + 1]; ti->num_listeners--; @@ -736,9 +742,9 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti, type = LISTENER_POINTER_GRAB; } - TouchAddListener(ti, grab->resource, grab->grabtype, - type, LISTENER_AWAITING_BEGIN, grab->window); - ti->num_grabs++; + /* grab listeners are always RT_NONE since we keep the grab pointer */ + TouchAddListener(ti, grab->resource, RT_NONE, grab->grabtype, + type, LISTENER_AWAITING_BEGIN, grab->window, grab); } /** @@ -793,8 +799,8 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, if (!xi2mask_isset(iclients->xi2mask, dev, XI_TouchOwnership)) TouchEventHistoryAllocate(ti); - TouchAddListener(ti, iclients->resource, XI2, - type, LISTENER_AWAITING_BEGIN, win); + TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI2, + type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } } @@ -808,9 +814,9 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, continue; TouchEventHistoryAllocate(ti); - TouchAddListener(ti, iclients->resource, XI, + TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, - win); + win, NULL); return TRUE; } } @@ -823,9 +829,9 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, /* window owner */ if (IsMaster(dev) && (win->eventMask & core_filter)) { TouchEventHistoryAllocate(ti); - TouchAddListener(ti, win->drawable.id, CORE, + TouchAddListener(ti, win->drawable.id, RT_WINDOW, CORE, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, - win); + win, NULL); return TRUE; } @@ -835,8 +841,8 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, continue; TouchEventHistoryAllocate(ti); - TouchAddListener(ti, oclients->resource, CORE, - type, LISTENER_AWAITING_BEGIN, win); + TouchAddListener(ti, oclients->resource, RT_OTHERCLIENT, CORE, + type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } } @@ -896,7 +902,8 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev) } /** - * Remove the touch pointer grab from the device. Called from AllowSome() + * Remove the touch pointer grab from the device. Called from + * DeactivatePointerGrab() */ void TouchRemovePointerGrab(DeviceIntPtr dev) @@ -919,6 +926,8 @@ TouchRemovePointerGrab(DeviceIntPtr dev) ti = TouchFindByClientID(dev, ev->touchid); if (!ti) return; + + /* FIXME: missing a bit of code here... */ } /* As touch grabs don't turn into active grabs with their own resources, we @@ -969,10 +978,8 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, int nev; int i; - BUG_WARN(listener < 0); - BUG_WARN(listener >= ti->num_listeners); - if (listener < 0 || listener >= ti->num_listeners) - return BadMatch; + BUG_RETURN_VAL(listener < 0, BadMatch); + BUG_RETURN_VAL(listener >= ti->num_listeners, BadMatch); if (listener > 0) { if (mode == XIRejectTouch) @@ -984,10 +991,7 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, } events = InitEventList(GetMaximumEventsNum()); - if (!events) { - BUG_WARN_MSG(TRUE, "Failed to allocate touch ownership events\n"); - return BadAlloc; - } + BUG_RETURN_VAL_MSG(!events, BadAlloc, "Failed to allocate touch ownership events\n"); nev = GetTouchOwnershipEvents(events, dev, ti, mode, ti->listeners[0].listener, 0); @@ -996,8 +1000,6 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, for (i = 0; i < nev; i++) mieqProcessDeviceEvent(dev, events + i, NULL); - ProcessInputEvents(); - FreeEventList(events, GetMaximumEventsNum()); return nev ? Success : BadMatch; @@ -1031,3 +1033,31 @@ TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, return TouchListenerAcceptReject(dev, ti, i, mode); } + +/** + * End physically active touches for a device. + */ +void +TouchEndPhysicallyActiveTouches(DeviceIntPtr dev) +{ + InternalEvent *eventlist = InitEventList(GetMaximumEventsNum()); + int i; + + OsBlockSignals(); + mieqProcessInputEvents(); + for (i = 0; i < dev->last.num_touches; i++) { + DDXTouchPointInfoPtr ddxti = dev->last.touches + i; + + if (ddxti->active) { + int j; + int nevents = GetTouchEvents(eventlist, dev, ddxti->ddx_id, + XI_TouchEnd, 0, NULL); + + for (j = 0; j < nevents; j++) + mieqProcessDeviceEvent(dev, eventlist + j, NULL); + } + } + OsReleaseSignals(); + + FreeEventList(eventlist, GetMaximumEventsNum()); +} diff --git a/xserver/dix/window.c b/xserver/dix/window.c index a31e78fad..a5b28a630 100644 --- a/xserver/dix/window.c +++ b/xserver/dix/window.c @@ -446,7 +446,7 @@ CreateRootWindow(ScreenPtr pScreen) BoxRec box; PixmapFormatRec *format; - pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW); + pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); if (!pWin) return FALSE; @@ -641,7 +641,6 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, WindowPtr pWin; WindowPtr pHead; ScreenPtr pScreen; - xEvent event; int idepth, ivisual; Bool fOK; DepthPtr pDepth; @@ -681,7 +680,7 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) { fOK = FALSE; for (idepth = 0; idepth < pScreen->numDepths; idepth++) { - pDepth = (DepthPtr) & pScreen->allowedDepths[idepth]; + pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; if ((depth == pDepth->depth) || (depth == 0)) { for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) { if (visual == pDepth->vids[ivisual]) { @@ -710,7 +709,7 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, return NullWindow; } - pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW); + pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); if (!pWin) { *error = BadAlloc; return NullWindow; @@ -828,16 +827,17 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, } if (SubSend(pParent)) { - memset(&event, 0, sizeof(xEvent)); + xEvent event = { + .u.createNotify.window = wid, + .u.createNotify.parent = pParent->drawable.id, + .u.createNotify.x = x, + .u.createNotify.y = y, + .u.createNotify.width = w, + .u.createNotify.height = h, + .u.createNotify.borderWidth = bw, + .u.createNotify.override = pWin->overrideRedirect + }; event.u.u.type = CreateNotify; - event.u.createNotify.window = wid; - event.u.createNotify.parent = pParent->drawable.id; - event.u.createNotify.x = x; - event.u.createNotify.y = y; - event.u.createNotify.width = w; - event.u.createNotify.height = h; - event.u.createNotify.borderWidth = bw; - event.u.createNotify.override = pWin->overrideRedirect; DeliverEvents(pParent, &event, 1, NullWindow); } return pWin; @@ -912,7 +912,6 @@ CrushTree(WindowPtr pWin) { WindowPtr pChild, pSib, pParent; UnrealizeWindowProcPtr UnrealizeWindow; - xEvent event; if (!(pChild = pWin->firstChild)) return; @@ -925,8 +924,7 @@ CrushTree(WindowPtr pWin) while (1) { pParent = pChild->parent; if (SubStrSend(pChild, pParent)) { - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = DestroyNotify; + xEvent event = { .u.u.type = DestroyNotify }; event.u.destroyNotify.window = pChild->drawable.id; DeliverEvents(pChild, &event, 1, NullWindow); } @@ -961,7 +959,6 @@ DeleteWindow(pointer value, XID wid) { WindowPtr pParent; WindowPtr pWin = (WindowPtr) value; - xEvent event; UnmapWindow(pWin, FALSE); @@ -969,8 +966,7 @@ DeleteWindow(pointer value, XID wid) pParent = pWin->parent; if (wid && pParent && SubStrSend(pWin, pParent)) { - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = DestroyNotify; + xEvent event = { .u.u.type = DestroyNotify }; event.u.destroyNotify.window = pWin->drawable.id; DeliverEvents(pWin, &event, 1, NullWindow); } @@ -1355,11 +1351,13 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) CheckWindowOptionalNeed(pChild); } + xE = (xEvent) { + .u.colormap.window = pWin->drawable.id, + .u.colormap.colormap = cmap, + .u.colormap.new = xTrue, + .u.colormap.state = IsMapInstalled(cmap, pWin) + }; xE.u.u.type = ColormapNotify; - xE.u.colormap.window = pWin->drawable.id; - xE.u.colormap.colormap = cmap; - xE.u.colormap.new = xTrue; - xE.u.colormap.state = IsMapInstalled(cmap, pWin); DeliverEvents(pWin, &xE, 1, NullWindow); } break; @@ -1746,12 +1744,12 @@ ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh) GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh, pSib->winGravity, &cwsx, &cwsy); if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) { - xEvent event; - + xEvent event = { + .u.gravity.window = pSib->drawable.id, + .u.gravity.x = cwsx - wBorderWidth(pSib), + .u.gravity.y = cwsy - wBorderWidth(pSib) + }; event.u.u.type = GravityNotify; - event.u.gravity.window = pSib->drawable.id; - event.u.gravity.x = cwsx - wBorderWidth(pSib); - event.u.gravity.y = cwsy - wBorderWidth(pSib); DeliverEvents(pSib, &event, 1, NullWindow); pSib->origin.x = cwsx; pSib->origin.y = cwsy; @@ -1888,8 +1886,7 @@ AnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, BoxPtr box) if (pSib->mapped) { sbox = WindowExtents(pSib, &sboxrec); if (BOXES_OVERLAP(sbox, box) - && ShapeOverlap(pWin, box, pSib, sbox) - ) + && ShapeOverlap(pWin, box, pSib, sbox)) return TRUE; } } @@ -1907,8 +1904,7 @@ IOverlapAnyWindow(WindowPtr pWin, BoxPtr box) if (pSib->mapped) { sbox = WindowExtents(pSib, &sboxrec); if (BOXES_OVERLAP(sbox, box) - && ShapeOverlap(pWin, box, pSib, sbox) - ) + && ShapeOverlap(pWin, box, pSib, sbox)) return TRUE; } } @@ -2090,7 +2086,6 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) unsigned short w = pWin->drawable.width, h = pWin->drawable.height, bw = pWin->borderWidth; int rc, action, smode = Above; - xEvent event; if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask)) @@ -2177,32 +2172,26 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) else pSib = pWin->nextSib; - if ((!pWin->overrideRedirect) && (RedirectSend(pParent) - )) { - memset(&event, 0, sizeof(xEvent)); + if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) { + xEvent event = { + .u.configureRequest.window = pWin->drawable.id, + .u.configureRequest.sibling = (mask & CWSibling) ? sibwid : None, + .u.configureRequest.x = x, + .u.configureRequest.y = y, + .u.configureRequest.width = w, + .u.configureRequest.height = h, + .u.configureRequest.borderWidth = bw, + .u.configureRequest.valueMask = mask, + .u.configureRequest.parent = pParent->drawable.id + }; event.u.u.type = ConfigureRequest; - event.u.configureRequest.window = pWin->drawable.id; - if (mask & CWSibling) - event.u.configureRequest.sibling = sibwid; - else - event.u.configureRequest.sibling = None; - if (mask & CWStackMode) - event.u.u.detail = smode; - else - event.u.u.detail = Above; - event.u.configureRequest.x = x; - event.u.configureRequest.y = y; + event.u.u.detail = (mask & CWStackMode) ? smode : Above; #ifdef PANORAMIX if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { event.u.configureRequest.x += screenInfo.screens[0]->x; event.u.configureRequest.y += screenInfo.screens[0]->y; } #endif - event.u.configureRequest.width = w; - event.u.configureRequest.height = h; - event.u.configureRequest.borderWidth = bw; - event.u.configureRequest.valueMask = mask; - event.u.configureRequest.parent = pParent->drawable.id; if (MaybeDeliverEventsToClient(pParent, &event, 1, SubstructureRedirectMask, client) == 1) return Success; @@ -2213,13 +2202,12 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) if (size_change && ((pWin->eventMask | wOtherEventMasks(pWin)) & ResizeRedirectMask)) { - xEvent eventT; - - memset(&eventT, 0, sizeof(xEvent)); + xEvent eventT = { + .u.resizeRequest.window = pWin->drawable.id, + .u.resizeRequest.width = w, + .u.resizeRequest.height = h + }; eventT.u.u.type = ResizeRequest; - eventT.u.resizeRequest.window = pWin->drawable.id; - eventT.u.resizeRequest.width = w; - eventT.u.resizeRequest.height = h; if (MaybeDeliverEventsToClient(pWin, &eventT, 1, ResizeRedirectMask, client) == 1) { /* if event is delivered, leave the actual size alone. */ @@ -2270,25 +2258,23 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) } if (SubStrSend(pWin, pParent)) { - memset(&event, 0, sizeof(xEvent)); + xEvent event = { + .u.configureNotify.window = pWin->drawable.id, + .u.configureNotify.aboveSibling = pSib ? pSib->drawable.id : None, + .u.configureNotify.x = x, + .u.configureNotify.y = y, + .u.configureNotify.width = w, + .u.configureNotify.height = h, + .u.configureNotify.borderWidth = bw, + .u.configureNotify.override = pWin->overrideRedirect + }; event.u.u.type = ConfigureNotify; - event.u.configureNotify.window = pWin->drawable.id; - if (pSib) - event.u.configureNotify.aboveSibling = pSib->drawable.id; - else - event.u.configureNotify.aboveSibling = None; - event.u.configureNotify.x = x; - event.u.configureNotify.y = y; #ifdef PANORAMIX if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { event.u.configureNotify.x += screenInfo.screens[0]->x; event.u.configureNotify.y += screenInfo.screens[0]->y; } #endif - event.u.configureNotify.width = w; - event.u.configureNotify.height = h; - event.u.configureNotify.borderWidth = bw; - event.u.configureNotify.override = pWin->overrideRedirect; DeliverEvents(pWin, &event, 1, NullWindow); } if (mask & CWBorderWidth) { @@ -2361,13 +2347,13 @@ CirculateWindow(WindowPtr pParent, int direction, ClientPtr client) return Success; } - event.u.circulate.window = pWin->drawable.id; - event.u.circulate.parent = pParent->drawable.id; - event.u.circulate.event = pParent->drawable.id; - if (direction == RaiseLowest) - event.u.circulate.place = PlaceOnTop; - else - event.u.circulate.place = PlaceOnBottom; + event = (xEvent) { + .u.circulate.window = pWin->drawable.id, + .u.circulate.parent = pParent->drawable.id, + .u.circulate.event = pParent->drawable.id, + .u.circulate.place = (direction == RaiseLowest) ? + PlaceOnTop : PlaceOnBottom, + }; if (RedirectSend(pParent)) { event.u.u.type = CirculateRequest; @@ -2420,19 +2406,20 @@ ReparentWindow(WindowPtr pWin, WindowPtr pParent, if (WasMapped) UnmapWindow(pWin, FALSE); - memset(&event, 0, sizeof(xEvent)); + event = (xEvent) { + .u.reparent.window = pWin->drawable.id, + .u.reparent.parent = pParent->drawable.id, + .u.reparent.x = x, + .u.reparent.y = y, + .u.reparent.override = pWin->overrideRedirect + }; event.u.u.type = ReparentNotify; - event.u.reparent.window = pWin->drawable.id; - event.u.reparent.parent = pParent->drawable.id; - event.u.reparent.x = x; - event.u.reparent.y = y; #ifdef PANORAMIX if (!noPanoramiXExtension && !pParent->parent) { event.u.reparent.x += screenInfo.screens[0]->x; event.u.reparent.y += screenInfo.screens[0]->y; } #endif - event.u.reparent.override = pWin->overrideRedirect; DeliverEvents(pWin, &event, 1, pParent); /* take out of sibling chain */ @@ -2518,28 +2505,29 @@ RealizeTree(WindowPtr pWin) } } -static WindowPtr windowDisableMapUnmapEvents; - -void -DisableMapUnmapEvents(WindowPtr pWin) -{ - assert(windowDisableMapUnmapEvents == NULL); - - windowDisableMapUnmapEvents = pWin; -} - -void -EnableMapUnmapEvents(WindowPtr pWin) +static Bool +MaybeDeliverMapRequest(WindowPtr pWin, WindowPtr pParent, ClientPtr client) { - assert(windowDisableMapUnmapEvents != NULL); - - windowDisableMapUnmapEvents = NULL; + xEvent event = { + .u.mapRequest.window = pWin->drawable.id, + .u.mapRequest.parent = pParent->drawable.id + }; + event.u.u.type = MapRequest; + + return MaybeDeliverEventsToClient(pParent, &event, 1, + SubstructureRedirectMask, + client) == 1; } -static Bool -MapUnmapEventsEnabled(WindowPtr pWin) +static void +DeliverMapNotify(WindowPtr pWin) { - return pWin != windowDisableMapUnmapEvents; + xEvent event = { + .u.mapNotify.window = pWin->drawable.id, + .u.mapNotify.override = pWin->overrideRedirect, + }; + event.u.u.type = MapNotify; + DeliverEvents(pWin, &event, 1, NullWindow); } /***** @@ -2561,37 +2549,22 @@ MapWindow(WindowPtr pWin, ClientPtr client) if (pWin->mapped) return Success; - /* general check for permission to map window */ + /* general check for permission to map window */ if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, pWin, RT_NONE, NULL, DixShowAccess) != Success) return Success; pScreen = pWin->drawable.pScreen; if ((pParent = pWin->parent)) { - xEvent event; Bool anyMarked; - if ((!pWin->overrideRedirect) && (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; - - if (MaybeDeliverEventsToClient(pParent, &event, 1, - SubstructureRedirectMask, - client) == 1) + if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) + if (MaybeDeliverMapRequest(pWin, pParent, client)) return Success; - } 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; - DeliverEvents(pWin, &event, 1, NullWindow); - } + if (SubStrSend(pWin, pParent)) + DeliverMapNotify(pWin); if (!pParent->realized) return Success; @@ -2644,7 +2617,6 @@ MapSubwindows(WindowPtr pParent, ClientPtr client) ScreenPtr pScreen; Mask parentRedirect; Mask parentNotify; - xEvent event; Bool anyMarked; WindowPtr pLayerWin; @@ -2654,26 +2626,13 @@ MapSubwindows(WindowPtr pParent, ClientPtr client) anyMarked = FALSE; for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) { if (!pWin->mapped) { - 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; - - if (MaybeDeliverEventsToClient(pParent, &event, 1, - SubstructureRedirectMask, - client) == 1) + if (parentRedirect && !pWin->overrideRedirect) + if (MaybeDeliverMapRequest(pWin, pParent, client)) continue; - } 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; - DeliverEvents(pWin, &event, 1, NullWindow); - } + if (parentNotify || StrSend(pWin)) + DeliverMapNotify(pWin); if (!pFirstMapped) pFirstMapped = pWin; @@ -2734,8 +2693,7 @@ UnrealizeTree(WindowPtr pWin, Bool fromConfigure) } #endif (*Unrealize) (pChild); - if (MapUnmapEventsEnabled(pWin)) - DeleteWindowFromAnyEvents(pChild, FALSE); + DeleteWindowFromAnyEvents(pChild, FALSE); if (pChild->viewable) { pChild->viewable = FALSE; (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure); @@ -2754,6 +2712,17 @@ UnrealizeTree(WindowPtr pWin, Bool fromConfigure) } } +static void +DeliverUnmapNotify(WindowPtr pWin, Bool fromConfigure) +{ + xEvent event = { + .u.unmapNotify.window = pWin->drawable.id, + .u.unmapNotify.fromConfigure = fromConfigure + }; + event.u.u.type = UnmapNotify; + DeliverEvents(pWin, &event, 1, NullWindow); +} + /***** * UnmapWindow * If the window is already unmapped, this request has no effect. @@ -2765,7 +2734,6 @@ int UnmapWindow(WindowPtr pWin, Bool fromConfigure) { WindowPtr pParent; - xEvent event; Bool wasRealized = (Bool) pWin->realized; Bool wasViewable = (Bool) pWin->viewable; ScreenPtr pScreen = pWin->drawable.pScreen; @@ -2773,13 +2741,8 @@ UnmapWindow(WindowPtr pWin, Bool fromConfigure) if ((!pWin->mapped) || (!(pParent = pWin->parent))) 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; - DeliverEvents(pWin, &event, 1, NullWindow); - } + if (SubStrSend(pWin, pParent)) + DeliverUnmapNotify(pWin, fromConfigure); if (wasViewable && !fromConfigure) { pWin->valdata = UnmapValData; (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin); @@ -2813,7 +2776,6 @@ void UnmapSubwindows(WindowPtr pWin) { WindowPtr pChild, pHead; - xEvent event; Bool wasRealized = (Bool) pWin->realized; Bool wasViewable = (Bool) pWin->viewable; Bool anyMarked = FALSE; @@ -2831,12 +2793,8 @@ UnmapSubwindows(WindowPtr pWin) for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) { if (pChild->mapped) { - if (parentNotify || StrSend(pChild)) { - event.u.u.type = UnmapNotify; - event.u.unmapNotify.window = pChild->drawable.id; - event.u.unmapNotify.fromConfigure = xFalse; - DeliverEvents(pChild, &event, 1, NullWindow); - } + if (parentNotify || StrSend(pChild)) + DeliverUnmapNotify(pChild, xFalse); if (pChild->viewable) { pChild->valdata = UnmapValData; anyMarked = TRUE; @@ -2963,8 +2921,6 @@ SendVisibilityNotify(WindowPtr pWin) xEvent event; unsigned int visibility = pWin->visibility; - if (!MapUnmapEventsEnabled(pWin)) - return; #ifdef PANORAMIX /* This is not quite correct yet, but it's close */ if (!noPanoramiXExtension) { @@ -3028,10 +2984,11 @@ SendVisibilityNotify(WindowPtr pWin) } #endif - memset(&event, 0, sizeof(xEvent)); + event = (xEvent) { + .u.visibility.window = pWin->drawable.id, + .u.visibility.state = visibility + }; event.u.u.type = VisibilityNotify; - event.u.visibility.window = pWin->drawable.id; - event.u.visibility.state = visibility; DeliverEvents(pWin, &event, 1, NullWindow); } @@ -3134,8 +3091,12 @@ dixSaveScreens(ClientPtr client, int on, int mode) screenIsSaved = what; if (mode == ScreenSaverReset) { if (on == SCREEN_SAVER_FORCER) { + DeviceIntPtr dev; UpdateCurrentTimeIf(); - lastDeviceEventTime = currentTime; + nt_list_for_each_entry(dev, inputInfo.devices, next) + lastDeviceEventTime[dev->id] = currentTime; + lastDeviceEventTime[XIAllDevices] = currentTime; + lastDeviceEventTime[XIAllMasterDevices] = currentTime; } SetScreenSaverTimer(); } @@ -3658,3 +3619,16 @@ SetRootClip(ScreenPtr pScreen, Bool enable) WindowsRestructured(); FlushAllOutput(); } + +VisualPtr +WindowGetVisual(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + VisualID vid = wVisual(pWin); + int i; + + for (i = 0; i < pScreen->numVisuals; i++) + if (pScreen->visuals[i].vid == vid) + return &pScreen->visuals[i]; + return 0; +} |