#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
#include <X11/Xlibint.h>
#include <X11/Xlib.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/extutil.h>
#include "XIint.h"
XDeviceControl *
XGetDeviceControl(dpy, dev, control)
register Display *dpy;
XDevice *dev;
int control;
{
int size = 0;
int nbytes, i;
XDeviceControl *Device = NULL;
XDeviceControl *Sav = NULL;
xDeviceState *d = NULL;
xDeviceState *sav = NULL;
xGetDeviceControlReq *req;
xGetDeviceControlReply rep;
XExtDisplayInfo *info = XInput_find_display(dpy);
LockDisplay(dpy);
if (_XiCheckExtInit(dpy, XInput_Add_XChangeDeviceControl, info) == -1)
return ((XDeviceControl *) NoSuchExtension);
GetReq(GetDeviceControl, req);
req->reqType = info->codes->major_opcode;
req->ReqType = X_GetDeviceControl;
req->deviceid = dev->device_id;
req->control = control;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return (XDeviceControl *) NULL;
}
if (rep.length > 0) {
nbytes = (long)rep.length << 2;
d = (xDeviceState *) Xmalloc((unsigned)nbytes);
if (!d) {
_XEatData(dpy, (unsigned long)nbytes);
UnlockDisplay(dpy);
SyncHandle();
return (XDeviceControl *) NULL;
}
sav = d;
_XRead(dpy, (char *)d, nbytes);
switch (d->control) {
case DEVICE_RESOLUTION:
{
xDeviceResolutionState *r;
r = (xDeviceResolutionState *) d;
size += sizeof(XDeviceResolutionState) +
(3 * sizeof(int) * r->num_valuators);
break;
}
case DEVICE_ABS_CALIB:
{
size += sizeof(XDeviceAbsCalibState);
break;
}
case DEVICE_ABS_AREA:
{
size += sizeof(XDeviceAbsAreaState);
break;
}
case DEVICE_CORE:
{
size += sizeof(XDeviceCoreState);
break;
}
default:
size += d->length;
break;
}
Device = (XDeviceControl *) Xmalloc((unsigned)size);
if (!Device) {
UnlockDisplay(dpy);
SyncHandle();
return (XDeviceControl *) NULL;
}
Sav = Device;
d = sav;
switch (control) {
case DEVICE_RESOLUTION:
{
int *iptr, *iptr2;
xDeviceResolutionState *r;
XDeviceResolutionState *R;
r = (xDeviceResolutionState *) d;
R = (XDeviceResolutionState *) Device;
R->control = DEVICE_RESOLUTION;
R->length = sizeof(XDeviceResolutionState);
R->num_valuators = r->num_valuators;
iptr = (int *)(R + 1);
iptr2 = (int *)(r + 1);
R->resolutions = iptr;
R->min_resolutions = iptr + R->num_valuators;
R->max_resolutions = iptr + (2 * R->num_valuators);
for (i = 0; i < (3 * R->num_valuators); i++)
*iptr++ = *iptr2++;
break;
}
case DEVICE_ABS_CALIB:
{
xDeviceAbsCalibState *c = (xDeviceAbsCalibState *) d;
XDeviceAbsCalibState *C = (XDeviceAbsCalibState *) Device;
C->control = DEVICE_ABS_CALIB;
C->length = sizeof(XDeviceAbsCalibState);
C->min_x = c->min_x;
C->max_x = c->max_x;
C->min_y = c->min_y;
C->max_y = c->max_y;
C->flip_x = c->flip_x;
C->flip_y = c->flip_y;
C->rotation = c->rotation;
C->button_threshold = c->button_threshold;
break;
}
case DEVICE_ABS_AREA:
{
xDeviceAbsAreaState *a = (xDeviceAbsAreaState *) d;
XDeviceAbsAreaState *A = (XDeviceAbsAreaState *) Device;
A->control = DEVICE_ABS_AREA;
A->length = sizeof(XDeviceAbsAreaState);
A->offset_x = a->offset_x;
A->offset_y = a->offset_y;
A->width = a->width;
A->height = a->height;
A->screen = a->screen;
A->following = a->following;
break;
}
case DEVICE_CORE:
{
xDeviceCoreState *c = (xDeviceCoreState *) d;
XDeviceCoreState *C = (XDeviceCoreState *) Device;
C->control = DEVICE_CORE;
C->length = sizeof(XDeviceCoreState);
C->status = c->status;
C->iscore = c->iscore;
break;
}
case DEVICE_ENABLE:
{
xDeviceEnableState *e = (xDeviceEnableState *) d;
XDeviceEnableState *E = (XDeviceEnableState *) Device;
E->control = DEVICE_ENABLE;
E->length = sizeof(E);
E->enable = e->enable;
break;
}
default:
break;
}
XFree(sav);
}
UnlockDisplay(dpy);
SyncHandle();
return (Sav);
}
void
XFreeDeviceControl(control)
XDeviceControl *control;
{
XFree(control);
}