int ProcXIPassiveGrabDevice(ClientPtr client) { DeviceIntPtr dev, mod_dev; xXIPassiveGrabDeviceReply rep = { .repType = X_Reply, .RepType = X_XIPassiveGrabDevice, .sequenceNumber = client->sequence, .length = 0, .num_modifiers = 0 }; int i, ret = Success; uint32_t *modifiers; xXIGrabModifierInfo *modifiers_failed; GrabMask mask = { 0 }; GrabParameters param; void *tmp; int mask_len; REQUEST(xXIPassiveGrabDeviceReq); REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4); if (stuff->deviceid == XIAllDevices) dev = inputInfo.all_devices; else if (stuff->deviceid == XIAllMasterDevices) dev = inputInfo.all_master_devices; else { ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); if (ret != Success) { client->errorValue = stuff->deviceid; return ret; } } if (stuff->grab_type != XIGrabtypeButton && stuff->grab_type != XIGrabtypeKeycode && stuff->grab_type != XIGrabtypeEnter && stuff->grab_type != XIGrabtypeFocusIn && stuff->grab_type != XIGrabtypeTouchBegin) { client->errorValue = stuff->grab_type; return BadValue; } if ((stuff->grab_type == XIGrabtypeEnter || stuff->grab_type == XIGrabtypeFocusIn || stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) { client->errorValue = stuff->detail; return BadValue; } if (stuff->grab_type == XIGrabtypeTouchBegin && (stuff->grab_mode != XIGrabModeTouch || stuff->paired_device_mode != GrabModeAsync)) { client->errorValue = stuff->grab_mode; return BadValue; } if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1], stuff->mask_len * 4) != Success) return BadValue; mask.xi2mask = xi2mask_new(); if (!mask.xi2mask) return BadAlloc; mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4); xi2mask_set_one_mask(mask.xi2mask, stuff->deviceid, (unsigned char *) &stuff[1], mask_len * 4); memset(¶m, 0, sizeof(param)); param.grabtype = XI2; param.ownerEvents = stuff->owner_events; param.grabWindow = stuff->grab_window; param.cursor = stuff->cursor; if (IsKeyboardDevice(dev)) { param.this_device_mode = stuff->grab_mode; param.other_devices_mode = stuff->paired_device_mode; } else { param.this_device_mode = stuff->paired_device_mode; param.other_devices_mode = stuff->grab_mode; } if (stuff->cursor != None) { ret = dixLookupResourceByType(&tmp, stuff->cursor, RT_CURSOR, client, DixUseAccess); if (ret != Success) { client->errorValue = stuff->cursor; goto out; } } ret = dixLookupWindow((WindowPtr *) &tmp, stuff->grab_window, client, DixSetAttrAccess); if (ret != Success) goto out; ret = CheckGrabValues(client, ¶m); if (ret != Success) goto out; modifiers = (uint32_t *) &stuff[1] + stuff->mask_len; modifiers_failed = calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo)); if (!modifiers_failed) { ret = BadAlloc; goto out; } mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD); for (i = 0; i < stuff->num_modifiers; i++, modifiers++) { uint8_t status = Success; param.modifiers = *modifiers; ret = CheckGrabValues(client, ¶m); if (ret != Success) goto out; switch (stuff->grab_type) { case XIGrabtypeButton: status = GrabButton(client, dev, mod_dev, stuff->detail, ¶m, XI2, &mask); break; case XIGrabtypeKeycode: status = GrabKey(client, dev, mod_dev, stuff->detail, ¶m, XI2, &mask); break; case XIGrabtypeEnter: case XIGrabtypeFocusIn: status = GrabWindow(client, dev, stuff->grab_type, ¶m, &mask); break; case XIGrabtypeTouchBegin: status = GrabTouch(client, dev, mod_dev, ¶m, &mask); break; } if (status != GrabSuccess) { xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers; info->status = status; info->modifiers = *modifiers; if (client->swapped) swapl(&info->modifiers); rep.num_modifiers++; rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo)); } } WriteReplyToClient(client, sizeof(rep), &rep); if (rep.num_modifiers) WriteToClient(client, rep.length * 4, modifiers_failed); free(modifiers_failed); out: xi2mask_free(&mask.xi2mask); return ret; } void _X_COLD SRepXIPassiveGrabDevice(ClientPtr client, int size, xXIPassiveGrabDeviceReply * rep) { swaps(&rep->sequenceNumber); swapl(&rep->length); swaps(&rep->num_modifiers); WriteToClient(client, size, rep); }
void PrintDeviceGrabInfo(DeviceIntPtr dev) { ClientPtr client; LocalClientCredRec *lcc; int i, j; GrabInfoPtr devGrab = &dev->deviceGrab; GrabPtr grab = devGrab->grab; Bool clientIdPrinted = FALSE; ErrorF("Active grab 0x%lx (%s) on device '%s' (%d):\n", (unsigned long) grab->resource, (grab->grabtype == XI2) ? "xi2" : ((grab->grabtype == CORE) ? "core" : "xi1"), dev->name, dev->id); client = clients[CLIENT_ID(grab->resource)]; if (client) { pid_t clientpid = GetClientPid(client); const char *cmdname = GetClientCmdName(client); const char *cmdargs = GetClientCmdArgs(client); if ((clientpid > 0) && (cmdname != NULL)) { ErrorF(" client pid %ld %s %s\n", (long) clientpid, cmdname, cmdargs ? cmdargs : ""); clientIdPrinted = TRUE; } else if (GetLocalClientCreds(client, &lcc) != -1) { ErrorF(" client pid %ld uid %ld gid %ld\n", (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0, (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0, (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0); FreeLocalClientCreds(lcc); clientIdPrinted = TRUE; } } if (!clientIdPrinted) { ErrorF(" (no client information available for client %d)\n", CLIENT_ID(grab->resource)); } /* XXX is this even correct? */ if (devGrab->sync.other) ErrorF(" grab ID 0x%lx from paired device\n", (unsigned long) devGrab->sync.other->resource); ErrorF(" at %ld (from %s grab)%s (device %s, state %d)\n", (unsigned long) devGrab->grabTime.milliseconds, devGrab->fromPassiveGrab ? "passive" : "active", devGrab->implicitGrab ? " (implicit)" : "", devGrab->sync.frozen ? "frozen" : "thawed", devGrab->sync.state); if (grab->grabtype == CORE) { ErrorF(" core event mask 0x%lx\n", (unsigned long) grab->eventMask); } else if (grab->grabtype == XI) { ErrorF(" xi1 event mask 0x%lx\n", devGrab->implicitGrab ? (unsigned long) grab->deviceMask : (unsigned long) grab->eventMask); } else if (grab->grabtype == XI2) { for (i = 0; i < xi2mask_num_masks(grab->xi2mask); i++) { const unsigned char *mask; int print; print = 0; for (j = 0; j < XI2MASKSIZE; j++) { mask = xi2mask_get_one_mask(grab->xi2mask, i); if (mask[j]) { print = 1; break; } } if (!print) continue; ErrorF(" xi2 event mask for device %d: 0x", dev->id); for (j = 0; j < xi2mask_mask_size(grab->xi2mask); j++) ErrorF("%x", mask[j]); ErrorF("\n"); } } if (devGrab->fromPassiveGrab) { ErrorF(" passive grab type %d, detail 0x%x, " "activating key %d\n", grab->type, grab->detail.exact, devGrab->activatingKey); } ErrorF(" owner-events %s, kb %d ptr %d, confine %lx, cursor 0x%lx\n", grab->ownerEvents ? "true" : "false", grab->keyboardMode, grab->pointerMode, grab->confineTo ? (unsigned long) grab->confineTo->drawable.id : 0, grab->cursor ? (unsigned long) grab->cursor->id : 0); }
int ProcXIGrabDevice(ClientPtr client) { DeviceIntPtr dev; xXIGrabDeviceReply rep; int ret = Success; uint8_t status; GrabMask mask = { 0 }; int mask_len; REQUEST(xXIGrabDeviceReq); REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); if (ret != Success) return ret; if (!IsMaster(dev)) stuff->paired_device_mode = GrabModeAsync; if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1], stuff->mask_len * 4) != Success) return BadValue; mask.xi2mask = xi2mask_new(); if (!mask.xi2mask) return BadAlloc; mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4); /* FIXME: I think the old code was broken here */ xi2mask_set_one_mask(mask.xi2mask, dev->id, (unsigned char *) &stuff[1], mask_len); ret = GrabDevice(client, dev, stuff->grab_mode, stuff->paired_device_mode, stuff->grab_window, stuff->owner_events, stuff->time, &mask, XI2, stuff->cursor, None /* confineTo */ , &status); xi2mask_free(&mask.xi2mask); if (ret != Success) return ret; rep = (xXIGrabDeviceReply) { .repType = X_Reply, .RepType = X_XIGrabDevice, .sequenceNumber = client->sequence, .length = 0, .status = status }; WriteReplyToClient(client, sizeof(rep), &rep); return ret; } int SProcXIUngrabDevice(ClientPtr client) { REQUEST(xXIUngrabDeviceReq); swaps(&stuff->length); swaps(&stuff->deviceid); swapl(&stuff->time); return ProcXIUngrabDevice(client); }