mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 08:38:20 +00:00
[client] x11: Find and use the correct valuators for mouse axes
Using the first two valuators present in the event is incorrect. Events with only one valuator set, such as those sent by the Xorg evdev driver when the mouse moved along one axis only, were being discarded. On the other hand, mice with multiple scroll wheels may be able to emit events with two scroll wheel valuators set. The XInput2 specification is light on details, but "Rel X" and "Rel Y" appear to be the de facto standard names for the motion valuators. If valuators with those labels are not found, fall back to using valuators with numbers 0 and 1.
This commit is contained in:
parent
d74307223f
commit
358515f4a8
@ -96,6 +96,8 @@ static bool x11Init(const LG_DSInitParams params)
|
|||||||
int event, error;
|
int event, error;
|
||||||
|
|
||||||
memset(&x11, 0, sizeof(x11));
|
memset(&x11, 0, sizeof(x11));
|
||||||
|
x11.xValuator = -1;
|
||||||
|
x11.yValuator = -1;
|
||||||
x11.display = XOpenDisplay(NULL);
|
x11.display = XOpenDisplay(NULL);
|
||||||
|
|
||||||
XSetWindowAttributes swa =
|
XSetWindowAttributes swa =
|
||||||
@ -289,24 +291,39 @@ static bool x11Init(const LG_DSInitParams params)
|
|||||||
goto fail_window;
|
goto fail_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Atom rel_x = XInternAtom(x11.display, "Rel X", True);
|
||||||
|
Atom rel_y = XInternAtom(x11.display, "Rel Y", True);
|
||||||
|
|
||||||
bool havePointer = false;
|
bool havePointer = false;
|
||||||
bool haveKeyboard = false;
|
bool haveKeyboard = false;
|
||||||
for(int i = 0; i < count; ++i)
|
for(int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
/* look for the master pointing device */
|
/* look for the master pointing device */
|
||||||
if (!havePointer && devinfo[i].use == XIMasterPointer)
|
if (!havePointer && devinfo[i].use == XIMasterPointer)
|
||||||
|
{
|
||||||
for(int j = 0; j < devinfo[i].num_classes; ++j)
|
for(int j = 0; j < devinfo[i].num_classes; ++j)
|
||||||
{
|
{
|
||||||
XIAnyClassInfo *cdevinfo =
|
XIAnyClassInfo *cdevinfo =
|
||||||
(XIAnyClassInfo *)(devinfo[i].classes[j]);
|
(XIAnyClassInfo *)(devinfo[i].classes[j]);
|
||||||
if (cdevinfo->type == XIValuatorClass)
|
if (cdevinfo->type == XIValuatorClass)
|
||||||
{
|
{
|
||||||
havePointer = true;
|
XIValuatorClassInfo *vdevinfo = (XIValuatorClassInfo *)cdevinfo;
|
||||||
x11.pointerDev = devinfo[i].deviceid;
|
if (vdevinfo->label == rel_x || (!vdevinfo->label &&
|
||||||
break;
|
vdevinfo->number == 0 && vdevinfo->mode == XIModeRelative))
|
||||||
|
x11.xValuator = vdevinfo->number;
|
||||||
|
else if (vdevinfo->label == rel_y || (!vdevinfo->label &&
|
||||||
|
vdevinfo->number == 1 && vdevinfo->mode == XIModeRelative))
|
||||||
|
x11.yValuator = vdevinfo->number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x11.xValuator >= 0 && x11.yValuator >= 0)
|
||||||
|
{
|
||||||
|
havePointer = true;
|
||||||
|
x11.pointerDev = devinfo[i].deviceid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* look for the master keyboard device */
|
/* look for the master keyboard device */
|
||||||
if (!haveKeyboard && devinfo[i].use == XIMasterKeyboard)
|
if (!haveKeyboard && devinfo[i].use == XIMasterKeyboard)
|
||||||
for(int j = 0; j < devinfo[i].num_classes; ++j)
|
for(int j = 0; j < devinfo[i].num_classes; ++j)
|
||||||
@ -817,31 +834,37 @@ static void x11GenericEvent(XGenericEventCookie *cookie)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
XIRawEvent *raw = cookie->data;
|
XIRawEvent *raw = cookie->data;
|
||||||
double raw_axis[2];
|
double raw_axis[2] = { 0 };
|
||||||
double axis[2];
|
double axis[2] = { 0 };
|
||||||
|
|
||||||
/* select the active validators for the X & Y axis */
|
/* select the active validators for the X & Y axis */
|
||||||
double *valuator = raw->valuators.values;
|
double *valuator = raw->valuators.values;
|
||||||
double *r_value = raw->raw_values;
|
double *r_value = raw->raw_values;
|
||||||
int count = 0;
|
bool has_axes = false;
|
||||||
for(int i = 0; i < raw->valuators.mask_len * 8; ++i)
|
for(int i = 0; i < raw->valuators.mask_len * 8; ++i)
|
||||||
{
|
{
|
||||||
if (XIMaskIsSet(raw->valuators.mask, i))
|
if (XIMaskIsSet(raw->valuators.mask, i))
|
||||||
{
|
{
|
||||||
raw_axis[count] = *r_value;
|
if (i == x11.xValuator)
|
||||||
axis [count] = *valuator;
|
{
|
||||||
++count;
|
raw_axis[0] = *r_value;
|
||||||
|
axis [0] = *valuator;
|
||||||
if (count == 2)
|
has_axes = true;
|
||||||
break;
|
}
|
||||||
|
else if (i == x11.yValuator)
|
||||||
|
{
|
||||||
|
raw_axis[1] = *r_value;
|
||||||
|
axis [1] = *valuator;
|
||||||
|
has_axes = true;
|
||||||
|
}
|
||||||
|
|
||||||
++valuator;
|
++valuator;
|
||||||
++r_value;
|
++r_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* filter out scroll wheel and other events */
|
/* filter out events with no axis data */
|
||||||
if (count < 2)
|
if (!has_axes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* filter out duplicate events */
|
/* filter out duplicate events */
|
||||||
|
@ -38,6 +38,8 @@ struct X11DSState
|
|||||||
|
|
||||||
int pointerDev;
|
int pointerDev;
|
||||||
int keyboardDev;
|
int keyboardDev;
|
||||||
|
int xValuator;
|
||||||
|
int yValuator;
|
||||||
|
|
||||||
bool pointerGrabbed;
|
bool pointerGrabbed;
|
||||||
bool keyboardGrabbed;
|
bool keyboardGrabbed;
|
||||||
|
Loading…
Reference in New Issue
Block a user