int XChangeDeviceKeyMapping( register Display *dpy, XDevice *dev, int first, int syms_per_code, KeySym *keysyms, int count) { register long nbytes; xChangeDeviceKeyMappingReq *req; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return (NoSuchExtension); GetReq(ChangeDeviceKeyMapping, req); req->reqType = info->codes->major_opcode; req->ReqType = X_ChangeDeviceKeyMapping; req->deviceid = dev->device_id; req->firstKeyCode = first; req->keyCodes = count; req->keySymsPerKeyCode = syms_per_code; req->length += count * syms_per_code; nbytes = syms_per_code * count * sizeof(CARD32); Data(dpy, (char *)keysyms, nbytes); UnlockDisplay(dpy); SyncHandle(); return (Success); }
Status XIGetFocus(Display *dpy, int deviceid, Window *focus_return) { xXIGetFocusReq *req; xXIGetFocusReply reply; XExtDisplayInfo *extinfo = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) return (NoSuchExtension); GetReq(XIGetFocus, req); req->reqType = extinfo->codes->major_opcode; req->ReqType = X_XIGetFocus; req->deviceid = deviceid; if (!_XReply(dpy, (xReply*) &reply, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } *focus_return = reply.focus; UnlockDisplay(dpy); SyncHandle(); return Success; }
int XUngrabDeviceKey( register Display *dpy, XDevice *dev, unsigned int key, /* CARD8 */ unsigned int modifiers, /* CARD16 */ XDevice *modifier_dev, Window grab_window) { register xUngrabDeviceKeyReq *req; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return (NoSuchExtension); GetReq(UngrabDeviceKey, req); req->reqType = info->codes->major_opcode; req->ReqType = X_UngrabDeviceKey; req->grabbed_device = dev->device_id; req->key = key; req->modifiers = modifiers; if (modifier_dev) req->modifier_device = modifier_dev->device_id; else req->modifier_device = UseXKeyboard; req->grabWindow = grab_window; UnlockDisplay(dpy); SyncHandle(); return (Success); }
Status XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time, Cursor cursor, int grab_mode, int paired_device_mode, Bool owner_events, XIEventMask *mask) { xXIGrabDeviceReq *req; xXIGrabDeviceReply reply; char* buff; int len; XExtDisplayInfo *extinfo = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) return (NoSuchExtension); if (mask->mask_len > INT_MAX - 3 || (mask->mask_len + 3)/4 >= 0xffff) { reply.status = BadValue; goto out; } /* mask->mask_len is in bytes, but we need 4-byte units on the wire, * and they need to be padded with 0 */ len = (mask->mask_len + 3)/4; buff = calloc(4, len); if (!buff) { reply.status = BadAlloc; goto out; } GetReq(XIGrabDevice, req); req->reqType = extinfo->codes->major_opcode; req->ReqType = X_XIGrabDevice; req->deviceid = deviceid; req->grab_window = grab_window; req->time = time; req->grab_mode = grab_mode; req->paired_device_mode = paired_device_mode; req->owner_events = owner_events; req->mask_len = len; req->cursor = cursor; memcpy(buff, mask->mask, mask->mask_len); SetReqLen(req, len, len); Data(dpy, buff, len * 4); free(buff); if (_XReply(dpy, (xReply *)&reply, 0, xTrue) == 0) reply.status = GrabSuccess; out: UnlockDisplay(dpy); SyncHandle(); return reply.status; }
int XSelectExtensionEvent( register Display *dpy, Window w, XEventClass *event_list, int count) { register xSelectExtensionEventReq *req; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return (NoSuchExtension); GetReq(SelectExtensionEvent, req); req->reqType = info->codes->major_opcode; req->ReqType = X_SelectExtensionEvent; req->window = w; req->count = count; req->length += count; /* note: Data is a macro that uses its arguments multiple * times, so "nvalues" is changed in a separate assignment * statement */ count <<= 2; Data32(dpy, (long *)event_list, count); UnlockDisplay(dpy); SyncHandle(); return (Success); }
Status XSendExtensionEvent( register Display *dpy, XDevice *dev, Window dest, Bool prop, int count, XEventClass *list, XEvent *event) { int num_events; int ev_size; xSendExtensionEventReq *req; xEvent *ev; ext_event_to_wire *fp; Status status; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return (NoSuchExtension); /* call through display to find proper conversion routine */ fp = (ext_event_to_wire*)&dpy->wire_vec[event->type & 0177]; if (*fp == NULL) *fp = _XiEventToWire; status = (*fp) (dpy, event, &ev, &num_events); if (status) { GetReq(SendExtensionEvent, req); req->reqType = info->codes->major_opcode; req->ReqType = X_SendExtensionEvent; req->deviceid = dev->device_id; req->destination = dest; req->propagate = prop; req->count = count; req->num_events = num_events; ev_size = num_events * sizeof(xEvent); req->length += (count + (ev_size >> 2)); /* note: Data is a macro that uses its arguments multiple * times, so "count" is changed in a separate assignment * statement. Any extra events must be sent before the event * list, in order to ensure quad alignment. */ Data(dpy, (char *)ev, ev_size); count <<= 2; Data32(dpy, (long *)list, count); XFree((char *)ev); } UnlockDisplay(dpy); SyncHandle(); return (status); }
int XISelectEvents(Display* dpy, Window win, XIEventMask* masks, int num_masks) { XIEventMask *current; xXISelectEventsReq *req; xXIEventMask mask; int i; int len = 0; int r = Success; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) { r = NoSuchExtension; goto out; } GetReq(XISelectEvents, req); req->reqType = info->codes->major_opcode; req->ReqType = X_XISelectEvents; req->win = win; req->num_masks = num_masks; /* get the right length */ for (i = 0; i < num_masks; i++) { len++; current = &masks[i]; len += (current->mask_len + 3)/4; } SetReqLen(req, len, len); for (i = 0; i < num_masks; i++) { char *buff; current = &masks[i]; mask.deviceid = current->deviceid; mask.mask_len = (current->mask_len + 3)/4; /* masks.mask_len is in bytes, but we need 4-byte units on the wire, * and they need to be padded with 0 */ buff = calloc(1, mask.mask_len * 4); memcpy(buff, current->mask, current->mask_len); Data32(dpy, &mask, sizeof(xXIEventMask)); Data(dpy, buff, mask.mask_len * 4); free(buff); } out: UnlockDisplay(dpy); SyncHandle(); return r; }
Status XIAllowTouchEvents(Display *dpy, int deviceid, unsigned int touchid, Window grab_window, int event_mode) { XExtDisplayInfo *extinfo = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1) return (NoSuchExtension); UnlockDisplay(dpy); return _XIAllowEvents(dpy, deviceid, event_mode, CurrentTime, touchid, grab_window); }
static Status _XIAllowEvents(Display *dpy, int deviceid, int event_mode, Time time, unsigned int touchid, Window grab_window) { Bool have_XI22 = True; xXIAllowEventsReq *req; xXI2_2AllowEventsReq *req_XI22; XExtDisplayInfo *extinfo = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) return (NoSuchExtension); if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == 0) have_XI22 = True; if (have_XI22) { GetReq(XI2_2AllowEvents, req_XI22); req = (xXIAllowEventsReq*)req_XI22; } else GetReq(XIAllowEvents, req); req->reqType = extinfo->codes->major_opcode; req->ReqType = X_XIAllowEvents; req->deviceid = deviceid; req->mode = event_mode; req->time = time; if (have_XI22) { req_XI22->touchid = touchid; req_XI22->grab_window = grab_window; } UnlockDisplay(dpy); SyncHandle(); return Success; }
XDevice * XOpenDevice( register Display *dpy, register XID id) { register long rlen; /* raw length */ xOpenDeviceReq *req; xOpenDeviceReply rep; XDevice *dev; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return ((XDevice *) NoSuchExtension); GetReq(OpenDevice, req); req->reqType = info->codes->major_opcode; req->ReqType = X_OpenDevice; req->deviceid = id; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return (XDevice *) NULL; } rlen = rep.length << 2; dev = (XDevice *) Xmalloc(sizeof(XDevice) + rep.num_classes * sizeof(XInputClassInfo)); if (dev) { int dlen; /* data length */ dev->device_id = req->deviceid; dev->num_classes = rep.num_classes; dev->classes = (XInputClassInfo *) ((char *)dev + sizeof(XDevice)); dlen = rep.num_classes * sizeof(xInputClassInfo); _XRead(dpy, (char *)dev->classes, dlen); /* could be padding that we still need to eat (yummy!) */ if (rlen - dlen > 0) _XEatData(dpy, (unsigned long)rlen - dlen); } else _XEatData(dpy, (unsigned long)rlen); UnlockDisplay(dpy); SyncHandle(); return (dev); }
_X_HIDDEN Status _xiQueryVersion(Display * dpy, int *major, int *minor, XExtDisplayInfo *info) { xXIQueryVersionReq *req; xXIQueryVersionReply rep; LockDisplay(dpy); /* This could mean either a malloc problem, or supported version < XInput_2_0 */ if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) { XExtensionVersion *ext; XExtDisplayInfo *extinfo = XInput_find_display(dpy); if (!extinfo || !extinfo->data) { *major = 0; *minor = 0; return BadRequest; } ext = ((XInputData*)extinfo->data)->vers; *major = ext->major_version; *minor = ext->minor_version; return BadRequest; } GetReq(XIQueryVersion, req); req->reqType = info->codes->major_opcode; req->ReqType = X_XIQueryVersion; req->major_version = *major; req->minor_version = *minor; if (!_XReply(dpy, (xReply*)&rep, 0, xTrue)) { UnlockDisplay(dpy); return BadImplementation; } *major = rep.major_version; *minor = rep.minor_version; UnlockDisplay(dpy); return Success; }
XModifierKeymap * XGetDeviceModifierMapping( register Display *dpy, XDevice *dev) { unsigned long nbytes; XModifierKeymap *res; xGetDeviceModifierMappingReq *req; xGetDeviceModifierMappingReply rep; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return ((XModifierKeymap *) NoSuchExtension); GetReq(GetDeviceModifierMapping, req); req->reqType = info->codes->major_opcode; req->ReqType = X_GetDeviceModifierMapping; req->deviceid = dev->device_id; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return (XModifierKeymap *) NULL; } nbytes = (unsigned long)rep.length << 2; res = (XModifierKeymap *) Xmalloc(sizeof(XModifierKeymap)); if (res) { res->modifiermap = (KeyCode *) Xmalloc(nbytes); if (res->modifiermap) _XReadPad(dpy, (char *)res->modifiermap, nbytes); else _XEatData(dpy, (unsigned long)nbytes); res->max_keypermod = rep.numKeyPerModifier; } UnlockDisplay(dpy); SyncHandle(); return (res); }
int XCloseDevice( register Display *dpy, register XDevice *dev) { xCloseDeviceReq *req; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return (NoSuchExtension); GetReq(CloseDevice, req); req->reqType = info->codes->major_opcode; req->ReqType = X_CloseDevice; req->deviceid = dev->device_id; XFree((char *)dev); UnlockDisplay(dpy); SyncHandle(); return (Success); }
Status XIUngrabDevice(Display* dpy, int deviceid, Time time) { xXIUngrabDeviceReq *req; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) return (NoSuchExtension); GetReq(XIUngrabDevice, req); req->reqType = info->codes->major_opcode; req->ReqType = X_XIUngrabDevice; req->deviceid = deviceid; req->time = time; UnlockDisplay(dpy); SyncHandle(); return (Success); }
XExtensionVersion * _XiGetExtensionVersion ( register Display *dpy, _Xconst char *name) { xGetExtensionVersionReq *req; xGetExtensionVersionReply rep; XExtensionVersion *ext; XExtDisplayInfo *info = XInput_find_display (dpy); if (_XiCheckExtInit(dpy, Dont_Check) == -1) return ((XExtensionVersion *) NoSuchExtension); GetReq(GetExtensionVersion,req); req->reqType = info->codes->major_opcode; req->ReqType = X_GetExtensionVersion; req->nbytes = name ? strlen(name) : 0; req->length += (unsigned)(req->nbytes+3)>>2; _XSend(dpy, name, (long)req->nbytes); if (! _XReply (dpy, (xReply *) &rep, 0, xTrue)) { return (XExtensionVersion *) NULL; } ext = (XExtensionVersion *) Xmalloc (sizeof (XExtensionVersion)); if (ext) { ext->present = rep.present; if (ext->present) { ext->major_version = rep.major_version; ext->minor_version = rep.minor_version; } } return (ext); }
int XIChangeHierarchy(Display* dpy, XIAnyHierarchyChangeInfo* changes, int num_changes) { XIAnyHierarchyChangeInfo* any; xXIChangeHierarchyReq *req; XExtDisplayInfo *info = XInput_find_display(dpy); char *data = NULL, *dptr; int dlen = 0, i; LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) return (NoSuchExtension); if (num_changes <= 0) return Success; GetReq(XIChangeHierarchy, req); req->reqType = info->codes->major_opcode; req->ReqType = X_XIChangeHierarchy; req->num_changes = num_changes; /* alloc required memory */ for (i = 0, any = changes; i < num_changes; i++, any++) { switch(any->type) { case XIAddMaster: { int slen = (strlen(any->add.name)); dlen += sizeof(xXIAddMasterInfo) + slen + (4 - (slen % 4)); } break; case XIRemoveMaster: dlen += sizeof(xXIRemoveMasterInfo); break; case XIAttachSlave: dlen += sizeof(xXIAttachSlaveInfo); break; case XIDetachSlave: dlen += sizeof(xXIDetachSlaveInfo); break; default: return BadValue; } } req->length += dlen / 4; /* dlen is 4-byte aligned */ data = Xmalloc(dlen); if (!data) return BadAlloc; dptr = data; for (i = 0, any = changes; i < num_changes; i++, any++) { switch(any->type) { case XIAddMaster: { XIAddMasterInfo* C = &any->add; xXIAddMasterInfo* c = (xXIAddMasterInfo*)dptr; c->type = C->type; c->send_core = C->send_core; c->enable = C->enable; c->name_len = strlen(C->name); c->length = (sizeof(xXIAddMasterInfo) + c->name_len + 3)/4; strncpy((char*)&c[1], C->name, c->name_len); dptr += c->length; } break; case XIRemoveMaster: { XIRemoveMasterInfo* R = &any->remove; xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)dptr; r->type = R->type; r->return_mode = R->return_mode; r->deviceid = R->deviceid; r->length = sizeof(xXIRemoveMasterInfo)/4; if (r->return_mode == XIAttachToMaster) { r->return_pointer = R->return_pointer; r->return_keyboard = R->return_keyboard; } dptr += sizeof(xXIRemoveMasterInfo); } break; case XIAttachSlave: { XIAttachSlaveInfo* C = &any->attach; xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)dptr; c->type = C->type; c->deviceid = C->deviceid; c->length = sizeof(xXIAttachSlaveInfo)/4; c->new_master = C->new_master; dptr += sizeof(xXIAttachSlaveInfo); } break; case XIDetachSlave: { XIDetachSlaveInfo *D = &any->detach; xXIDetachSlaveInfo *d = (xXIDetachSlaveInfo*)dptr; d->type = D->type; d->deviceid = D->deviceid; d->length = sizeof(xXIDetachSlaveInfo)/4; dptr += sizeof(xXIDetachSlaveInfo); } } } Data(dpy, data, dlen); Xfree(data); UnlockDisplay(dpy); SyncHandle(); return Success; }
void XChangeDeviceProperty(Display* dpy, XDevice* dev, Atom property, Atom type, int format, int mode, _Xconst unsigned char *data, int nelements) { xChangeDevicePropertyReq *req; int len; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return; GetReq(ChangeDeviceProperty, req); req->reqType = info->codes->major_opcode; req->ReqType = X_ChangeDeviceProperty; req->deviceid = dev->device_id; req->property = property; req->type = type; req->mode = mode; if (nelements < 0) { req->nUnits = 0; req->format = 0; /* ask for garbage, get garbage */ } else { req->nUnits = nelements; req->format = format; } switch (req->format) { case 8: len = ((long)nelements + 3) >> 2; if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) { SetReqLen(req, len, len); Data (dpy, (_Xconst char *)data, nelements); } /* else force BadLength */ break; case 16: len = ((long)nelements + 1) >> 1; if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) { SetReqLen(req, len, len); len = (long)nelements << 1; Data16 (dpy, (_Xconst short *) data, len); } /* else force BadLength */ break; case 32: len = nelements; if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) { SetReqLen(req, len, len); len = (long)nelements << 2; Data32 (dpy, (_Xconst long *) data, len); } /* else force BadLength */ break; default: /* BadValue will be generated */ ; } UnlockDisplay(dpy); SyncHandle(); }
XIDeviceInfo* XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return) { XIDeviceInfo *info = NULL; xXIQueryDeviceReq *req; xXIQueryDeviceReply reply; char *ptr; char *end; int i; char *buf; XExtDisplayInfo *extinfo = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) goto error_unlocked; GetReq(XIQueryDevice, req); req->reqType = extinfo->codes->major_opcode; req->ReqType = X_XIQueryDevice; req->deviceid = deviceid; if (!_XReply(dpy, (xReply*) &reply, 0, xFalse)) goto error; if (reply.length < INT_MAX / 4) { *ndevices_return = reply.num_devices; info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo)); } else { *ndevices_return = 0; info = NULL; } if (!info) goto error; buf = Xmalloc(reply.length * 4); _XRead(dpy, buf, reply.length * 4); ptr = buf; end = buf + reply.length * 4; /* info is a null-terminated array */ info[reply.num_devices].name = NULL; for (i = 0; i < reply.num_devices; i++) { int nclasses; size_t sz; XIDeviceInfo *lib = &info[i]; xXIDeviceInfo *wire = (xXIDeviceInfo*)ptr; if (ptr + sizeof(xXIDeviceInfo) > end) goto error_loop; lib->deviceid = wire->deviceid; lib->use = wire->use; lib->attachment = wire->attachment; lib->enabled = wire->enabled; nclasses = wire->num_classes; ptr += sizeof(xXIDeviceInfo); if (ptr + wire->name_len > end) goto error_loop; lib->name = Xcalloc(wire->name_len + 1, 1); if (lib->name == NULL) goto error_loop; strncpy(lib->name, ptr, wire->name_len); lib->name[wire->name_len] = '\0'; ptr += ((wire->name_len + 3)/4) * 4; sz = size_classes((xXIAnyInfo*)ptr, nclasses); lib->classes = Xmalloc(sz); if (lib->classes == NULL) { Xfree(lib->name); goto error_loop; } ptr += copy_classes(lib, (xXIAnyInfo*)ptr, &nclasses); /* We skip over unused classes */ lib->num_classes = nclasses; } Xfree(buf); UnlockDisplay(dpy); SyncHandle(); return info; error_loop: while (--i >= 0) { Xfree(info[i].name); Xfree(info[i].classes); } error: UnlockDisplay(dpy); error_unlocked: SyncHandle(); *ndevices_return = -1; Xfree(buf); return NULL; }
XIEventMask* XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return) { int i, len = 0; unsigned char *mask; XIEventMask *mask_out = NULL; xXIEventMask *mask_in = NULL, *mi; xXIGetSelectedEventsReq *req; xXIGetSelectedEventsReply reply; XExtDisplayInfo *info = XInput_find_display(dpy); *num_masks_return = -1; LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) goto out; GetReq(XIGetSelectedEvents, req); req->reqType = info->codes->major_opcode; req->ReqType = X_XIGetSelectedEvents; req->win = win; if (!_XReply(dpy, (xReply *) &reply, 0, xFalse)) goto out; if (reply.num_masks == 0) { *num_masks_return = 0; goto out; } mask_in = Xmalloc(reply.length * 4); if (!mask_in) goto out; _XRead(dpy, (char*)mask_in, reply.length * 4); /* Memory layout of the XIEventMask for a 3 mask reply: * [struct a][struct b][struct c][masks a][masks b][masks c] */ len = reply.num_masks * sizeof(XIEventMask); for (i = 0, mi = mask_in; i < reply.num_masks; i++) { len += mi->mask_len * 4; mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4); mi++; } mask_out = Xmalloc(len); if (!mask_out) goto out; mi = mask_in; mask = (unsigned char*)&mask_out[reply.num_masks]; for (i = 0; i < reply.num_masks; i++) { mask_out[i].deviceid = mi->deviceid; mask_out[i].mask_len = mi->mask_len * 4; mask_out[i].mask = mask; memcpy(mask_out[i].mask, &mi[1], mask_out[i].mask_len); mask += mask_out[i].mask_len; mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4); mi++; } *num_masks_return = reply.num_masks; out: Xfree(mask_in); UnlockDisplay(dpy); SyncHandle(); return mask_out; }
XIDeviceInfo* XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return) { XIDeviceInfo *info = NULL; xXIQueryDeviceReq *req; xXIQueryDeviceReply reply; char *ptr; int i; char *buf; XExtDisplayInfo *extinfo = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) goto error; GetReq(XIQueryDevice, req); req->reqType = extinfo->codes->major_opcode; req->ReqType = X_XIQueryDevice; req->deviceid = deviceid; if (!_XReply(dpy, (xReply*) &reply, 0, xFalse)) goto error; *ndevices_return = reply.num_devices; info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo)); if (!info) goto error; buf = Xmalloc(reply.length * 4); _XRead(dpy, buf, reply.length * 4); ptr = buf; /* info is a null-terminated array */ info[reply.num_devices].name = NULL; for (i = 0; i < reply.num_devices; i++) { XIDeviceInfo *lib = &info[i]; xXIDeviceInfo *wire = (xXIDeviceInfo*)ptr; lib->deviceid = wire->deviceid; lib->use = wire->use; lib->attachment = wire->attachment; lib->enabled = wire->enabled; lib->num_classes = wire->num_classes; lib->classes = (XIAnyClassInfo**)&lib[1]; ptr += sizeof(xXIDeviceInfo); lib->name = Xcalloc(wire->name_len + 1, 1); strncpy(lib->name, ptr, wire->name_len); ptr += ((wire->name_len + 3)/4) * 4; lib->classes = Xmalloc(size_classes((xXIAnyInfo*)ptr, lib->num_classes)); ptr += copy_classes(lib, (xXIAnyInfo*)ptr, lib->num_classes); } Xfree(buf); UnlockDisplay(dpy); SyncHandle(); return info; error: UnlockDisplay(dpy); SyncHandle(); *ndevices_return = -1; return NULL; }
XDeviceTimeCoord * XGetDeviceMotionEvents( register Display *dpy, XDevice *dev, Time start, Time stop, int *nEvents, int *mode, int *axis_count) { xGetDeviceMotionEventsReq *req; xGetDeviceMotionEventsReply rep; XDeviceTimeCoord *tc; int *data, *bufp, *readp, *savp; long size, size2; int i, j; XExtDisplayInfo *info = XInput_find_display(dpy); LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) return ((XDeviceTimeCoord *) NoSuchExtension); GetReq(GetDeviceMotionEvents, req); req->reqType = info->codes->major_opcode; req->ReqType = X_GetDeviceMotionEvents; req->start = start; req->stop = stop; req->deviceid = dev->device_id; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); *nEvents = 0; return (NULL); } *mode = rep.mode; *axis_count = rep.axes; *nEvents = rep.nEvents; if (!rep.nEvents) { UnlockDisplay(dpy); SyncHandle(); return (NULL); } size = rep.length << 2; size2 = rep.nEvents * (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int))); savp = readp = (int *)Xmalloc(size); bufp = (int *)Xmalloc(size2); if (!bufp || !savp) { Xfree(bufp); Xfree(savp); *nEvents = 0; _XEatData(dpy, (unsigned long)size); UnlockDisplay(dpy); SyncHandle(); return (NULL); } _XRead(dpy, (char *)readp, size); tc = (XDeviceTimeCoord *) bufp; data = (int *)(tc + rep.nEvents); for (i = 0; i < *nEvents; i++, tc++) { tc->time = *readp++; tc->data = data; for (j = 0; j < *axis_count; j++) *data++ = *readp++; } XFree((char *)savp); UnlockDisplay(dpy); SyncHandle(); return ((XDeviceTimeCoord *) bufp); }