diff options
-rw-r--r-- | xserver/Xi/exevents.c | 1 | ||||
-rw-r--r-- | xserver/Xi/xichangehierarchy.c | 31 | ||||
-rw-r--r-- | xserver/Xi/xiquerypointer.c | 3 | ||||
-rw-r--r-- | xserver/dix/devices.c | 27 | ||||
-rw-r--r-- | xserver/dix/enterleave.c | 126 | ||||
-rw-r--r-- | xserver/glx/glxcmds.c | 8 | ||||
-rw-r--r-- | xserver/hw/kdrive/ephyr/ephyrcursor.c | 2 |
7 files changed, 114 insertions, 84 deletions
diff --git a/xserver/Xi/exevents.c b/xserver/Xi/exevents.c index 54ea11a93..e16171468 100644 --- a/xserver/Xi/exevents.c +++ b/xserver/Xi/exevents.c @@ -605,6 +605,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) to->button = calloc(1, sizeof(ButtonClassRec)); if (!to->button) FatalError("[Xi] no memory for class shift.\n"); + to->button->numButtons = from->button->numButtons; } else classes->button = NULL; diff --git a/xserver/Xi/xichangehierarchy.c b/xserver/Xi/xichangehierarchy.c index 504defe56..72d00451e 100644 --- a/xserver/Xi/xichangehierarchy.c +++ b/xserver/Xi/xichangehierarchy.c @@ -270,7 +270,7 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES]) if (rc != Success) goto unwind; - if (!IsMaster(newptr)) { + if (!IsMaster(newptr) || !IsPointerDevice(newptr)) { client->errorValue = r->return_pointer; rc = BadDevice; goto unwind; @@ -281,7 +281,7 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES]) if (rc != Success) goto unwind; - if (!IsMaster(newkeybd)) { + if (!IsMaster(newkeybd) || !IsKeyboardDevice(newkeybd)) { client->errorValue = r->return_keyboard; rc = BadDevice; goto unwind; @@ -416,6 +416,11 @@ ProcXIChangeHierarchy(ClientPtr client) size_t len; /* length of data remaining in request */ int rc = Success; int flags[MAXDEVICES] = { 0 }; + enum { + NO_CHANGE, + FLUSH, + CHANGED, + } changes = NO_CHANGE; REQUEST(xXIChangeHierarchyReq); REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq); @@ -465,8 +470,9 @@ ProcXIChangeHierarchy(ClientPtr client) rc = add_master(client, c, flags); if (rc != Success) goto unwind; - } + changes = FLUSH; break; + } case XIRemoveMaster: { xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any; @@ -475,8 +481,9 @@ ProcXIChangeHierarchy(ClientPtr client) rc = remove_master(client, r, flags); if (rc != Success) goto unwind; - } + changes = FLUSH; break; + } case XIDetachSlave: { xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any; @@ -485,8 +492,9 @@ ProcXIChangeHierarchy(ClientPtr client) rc = detach_slave(client, c, flags); if (rc != Success) goto unwind; - } + changes = CHANGED; break; + } case XIAttachSlave: { xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any; @@ -495,16 +503,25 @@ ProcXIChangeHierarchy(ClientPtr client) rc = attach_slave(client, c, flags); if (rc != Success) goto unwind; + changes = CHANGED; + break; } + default: break; } + if (changes == FLUSH) { + XISendDeviceHierarchyEvent(flags); + memset(flags, 0, sizeof(flags)); + changes = NO_CHANGE; + } + len -= any->length * 4; any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4); } unwind: - - XISendDeviceHierarchyEvent(flags); + if (changes != NO_CHANGE) + XISendDeviceHierarchyEvent(flags); return rc; } diff --git a/xserver/Xi/xiquerypointer.c b/xserver/Xi/xiquerypointer.c index 5b77b1a44..2b05ac5f3 100644 --- a/xserver/Xi/xiquerypointer.c +++ b/xserver/Xi/xiquerypointer.c @@ -149,8 +149,7 @@ ProcXIQueryPointer(ClientPtr client) if (pDev->button) { int i; - rep.buttons_len = - bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); + rep.buttons_len = bytes_to_int32(bits_to_bytes(256)); /* button map up to 255 */ rep.length += rep.buttons_len; buttons = calloc(rep.buttons_len, 4); if (!buttons) diff --git a/xserver/dix/devices.c b/xserver/dix/devices.c index ed8c5aee7..660c01f97 100644 --- a/xserver/dix/devices.c +++ b/xserver/dix/devices.c @@ -447,14 +447,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr *prev, other; BOOL enabled; + BOOL dev_in_devices_list = FALSE; int flags[MAXDEVICES] = { 0 }; if (!dev->enabled) return TRUE; - for (prev = &inputInfo.devices; - *prev && (*prev != dev); prev = &(*prev)->next); - if (*prev != dev) + for (other = inputInfo.devices; other; other = other->next) { + if (other == dev) { + dev_in_devices_list = TRUE; + break; + } + } + + if (!dev_in_devices_list) return FALSE; TouchEndPhysicallyActiveTouches(dev); @@ -471,6 +477,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) flags[other->id] |= XISlaveDetached; } } + + for (other = inputInfo.off_devices; other; other = other->next) { + if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) { + AttachDevice(NULL, other, NULL); + flags[other->id] |= XISlaveDetached; + } + } } else { for (other = inputInfo.devices; other; other = other->next) { @@ -505,6 +518,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) LeaveWindow(dev); SetFocusOut(dev); + for (prev = &inputInfo.devices; + *prev && (*prev != dev); prev = &(*prev)->next); + *prev = dev->next; dev->next = inputInfo.off_devices; inputInfo.off_devices = dev; @@ -1064,6 +1080,11 @@ CloseDownDevices(void) dev->master = NULL; } + for (dev = inputInfo.off_devices; dev; dev = dev->next) { + if (!IsMaster(dev) && !IsFloating(dev)) + dev->master = NULL; + } + CloseDeviceList(&inputInfo.devices); CloseDeviceList(&inputInfo.off_devices); diff --git a/xserver/dix/enterleave.c b/xserver/dix/enterleave.c index 033ddc212..81348148d 100644 --- a/xserver/dix/enterleave.c +++ b/xserver/dix/enterleave.c @@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, ev->type = DeviceValuator; ev->deviceid = dev->id; - ev->num_valuators = nval < 3 ? nval : 3; + ev->num_valuators = nval < 6 ? nval : 6; ev->first_valuator = first; switch (ev->num_valuators) { + case 6: + ev->valuator2 = v->axisVal[first + 5]; + case 5: + ev->valuator2 = v->axisVal[first + 4]; + case 4: + ev->valuator2 = v->axisVal[first + 3]; case 3: ev->valuator2 = v->axisVal[first + 2]; case 2: @@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, ev->valuator0 = v->axisVal[first]; break; } - first += ev->num_valuators; } static void @@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, ev->num_buttons = b->numButtons; memcpy((char *) ev->buttons, (char *) b->down, 4); } - else if (k) { + if (k) { ev->classes_reported |= (1 << KeyClass); ev->num_keys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; @@ -670,14 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, } } - +/** + * The device state notify event is split across multiple 32-byte events. + * The first one contains the first 32 button state bits, the first 32 + * key state bits, and the first 3 valuator values. + * + * If a device has more than that, the server sends out: + * - one deviceButtonStateNotify for buttons 32 and above + * - one deviceKeyStateNotify for keys 32 and above + * - one deviceValuator event per 6 valuators above valuator 4 + * + * All events but the last one have the deviceid binary ORed with MORE_EVENTS, + */ static void DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) { + /* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify + * and one deviceValuator for each 6 valuators */ + deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6]; int evcount = 1; - deviceStateNotify *ev, *sev; - deviceKeyStateNotify *kev; - deviceButtonStateNotify *bev; + deviceStateNotify *ev = sev; KeyClassPtr k; ButtonClassPtr b; @@ -690,87 +707,53 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) if ((b = dev->button) != NULL) { nbuttons = b->numButtons; - if (nbuttons > 32) + if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */ evcount++; } if ((k = dev->key) != NULL) { nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; - if (nkeys > 32) + if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */ 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); - } + /* first three are encoded in deviceStateNotify, then + * it's 6 per deviceValuator event */ + evcount += ((nval - 3) + 6)/6; } - sev = ev = xallocarray(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; - } + BUG_RETURN(evcount <= ARRAY_SIZE(sev)); + + FixDeviceStateNotify(dev, ev, k, b, v, first); + + if (b != NULL && nbuttons > 32) { + deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev; + (ev - 1)->deviceid |= MORE_EVENTS; + bev->type = DeviceButtonStateNotify; + bev->deviceid = dev->id; + memcpy((char *) &bev->buttons[4], (char *) &b->down[4], + DOWN_LENGTH - 4); } - 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; - } + if (k != NULL && nkeys > 32) { + deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev; + (ev - 1)->deviceid |= MORE_EVENTS; + kev->type = DeviceKeyStateNotify; + kev->deviceid = dev->id; + memmove((char *) &kev->keys[0], (char *) &k->down[4], 28); } + 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; - } + ev->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first); + first += 6; + nval -= 6; } DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, DeviceStateNotifyMask, NullGrab); - free(sev); } void @@ -784,8 +767,9 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); - /* XI 2 event */ - btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; + /* XI 2 event contains the logical button map - maps are CARD8 + * so we need 256 bits for the possibly maximum mapping */ + btlen = (mouse->button) ? bits_to_bytes(256) : 0; btlen = bytes_to_int32(btlen); len = sizeof(xXIFocusInEvent) + btlen * 4; diff --git a/xserver/glx/glxcmds.c b/xserver/glx/glxcmds.c index fc26a2e34..1e46d0c72 100644 --- a/xserver/glx/glxcmds.c +++ b/xserver/glx/glxcmds.c @@ -48,6 +48,7 @@ #include "indirect_util.h" #include "protocol-versions.h" #include "glxvndabi.h" +#include "xace.h" static char GLXServerVendorName[] = "SGI"; @@ -1392,6 +1393,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, if (!pPixmap) return BadAlloc; + err = XaceHook(XACE_RESOURCE_ACCESS, client, glxDrawableId, RT_PIXMAP, + pPixmap, RT_NONE, NULL, DixCreateAccess); + if (err != Success) { + (*pGlxScreen->pScreen->DestroyPixmap) (pPixmap); + return err; + } + /* Assign the pixmap the same id as the pbuffer and add it as a * resource so it and the DRI2 drawable will be reclaimed when the * pbuffer is destroyed. */ diff --git a/xserver/hw/kdrive/ephyr/ephyrcursor.c b/xserver/hw/kdrive/ephyr/ephyrcursor.c index f991899c5..3f192d034 100644 --- a/xserver/hw/kdrive/ephyr/ephyrcursor.c +++ b/xserver/hw/kdrive/ephyr/ephyrcursor.c @@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = { Bool ephyrCursorInit(ScreenPtr screen) { - if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR_BITS, + if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR, sizeof(ephyrCursorRec))) return FALSE; |