diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-02-15 18:49:58 +0000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-09-30 09:24:18 +1000 |
commit | 3304bbff9b4ed63f1a47410a5320a136420ba2c6 (patch) | |
tree | 8f0c9e5d1cd32476287cb426bc82fa7eda5e48a6 /test | |
parent | 635a1f50bc65512ec491fe71b9dfa8cf9118e2c2 (diff) |
Input: Add smooth-scrolling support to GetPointerEvents
For scroll wheel support, we used to send buttons 4/5 and 6/7 for
horizontal/vertical positive/negative scroll events. For touchpads, we
really want more fine-grained scroll values. GetPointerEvents now
accepts both old-school scroll button presses, and new-style scroll axis
events, while emitting both types of events to support both old and new
clients.
This works with the new XIScrollClass to mark axes as scrolling axes.
Drivers mark any valuators that send scroll events with SetScrollValuator.
(Currently missing: the XIDeviceChangeEvent being sent when a driver changes
a scroll axis at run-time. This can be added later.)
Note: the SCROLL_TYPE enums are intentionally different values to the XI2
proto values to avoid copy/overlapping range bugs.
Co-authored-by: Daniel Stone <daniel@fooishbar.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
Diffstat (limited to 'test')
-rw-r--r-- | test/input.c | 57 | ||||
-rw-r--r-- | test/xi2/protocol-common.c | 63 | ||||
-rw-r--r-- | test/xi2/protocol-xiquerydevice.c | 49 |
3 files changed, 163 insertions, 6 deletions
diff --git a/test/input.c b/test/input.c index 2501d59b7..afc4d4d99 100644 --- a/test/input.c +++ b/test/input.c @@ -52,6 +52,7 @@ static void dix_init_valuators(void) { DeviceIntRec dev; ValuatorClassPtr val; + AxisInfoPtr axis; const int num_axes = 2; int i; Atom atoms[MAX_VALUATORS] = { 0 }; @@ -78,6 +79,62 @@ static void dix_init_valuators(void) } assert(dev.last.numValuators == num_axes); + + /* invalid increment */ + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 0.0, SCROLL_FLAG_NONE) == FALSE); + /* invalid type */ + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL - 1, 1.0, SCROLL_FLAG_NONE) == FALSE); + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_HORIZONTAL + 1, 1.0, SCROLL_FLAG_NONE) == FALSE); + /* invalid axisnum */ + assert(SetScrollValuator(&dev, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE) == FALSE); + + /* valid */ + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 3.0, SCROLL_FLAG_NONE) == TRUE); + axis = &dev.valuator->axes[0]; + assert(axis->scroll.increment == 3.0); + assert(axis->scroll.type == SCROLL_TYPE_VERTICAL); + assert(axis->scroll.flags == 0); + + /* valid */ + assert(SetScrollValuator(&dev, 1, SCROLL_TYPE_HORIZONTAL, 2.0, SCROLL_FLAG_NONE) == TRUE); + axis = &dev.valuator->axes[1]; + assert(axis->scroll.increment == 2.0); + assert(axis->scroll.type == SCROLL_TYPE_HORIZONTAL); + assert(axis->scroll.flags == 0); + + /* can add another non-preffered axis */ + assert(SetScrollValuator(&dev, 1, SCROLL_TYPE_VERTICAL, 5.0, SCROLL_FLAG_NONE) == TRUE); + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_HORIZONTAL, 5.0, SCROLL_FLAG_NONE) == TRUE); + + /* can overwrite with Preferred */ + assert(SetScrollValuator(&dev, 1, SCROLL_TYPE_VERTICAL, 5.5, SCROLL_FLAG_PREFERRED) == TRUE); + axis = &dev.valuator->axes[1]; + assert(axis->scroll.increment == 5.5); + assert(axis->scroll.type == SCROLL_TYPE_VERTICAL); + assert(axis->scroll.flags == SCROLL_FLAG_PREFERRED); + + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_HORIZONTAL, 8.8, SCROLL_FLAG_PREFERRED) == TRUE); + axis = &dev.valuator->axes[0]; + assert(axis->scroll.increment == 8.8); + assert(axis->scroll.type == SCROLL_TYPE_HORIZONTAL); + assert(axis->scroll.flags == SCROLL_FLAG_PREFERRED); + + /* can overwrite as none */ + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_NONE, 5.0, + SCROLL_FLAG_NONE) == TRUE); + axis = &dev.valuator->axes[0]; + assert(axis->scroll.type == SCROLL_TYPE_NONE); + + /* can overwrite axis with new settings */ + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 5.0, SCROLL_FLAG_NONE) == TRUE); + axis = &dev.valuator->axes[0]; + assert(axis->scroll.type == SCROLL_TYPE_VERTICAL); + assert(axis->scroll.increment == 5.0); + assert(axis->scroll.flags == SCROLL_FLAG_NONE); + assert(SetScrollValuator(&dev, 0, SCROLL_TYPE_VERTICAL, 3.0, SCROLL_FLAG_NONE) == TRUE); + assert(axis->scroll.type == SCROLL_TYPE_VERTICAL); + assert(axis->scroll.increment == 3.0); + assert(axis->scroll.flags == SCROLL_FLAG_NONE); } /* just check the known success cases, and that error cases set the client's diff --git a/test/xi2/protocol-common.c b/test/xi2/protocol-common.c index 423453358..56d6bd268 100644 --- a/test/xi2/protocol-common.c +++ b/test/xi2/protocol-common.c @@ -29,6 +29,8 @@ #include "extinit.h" /* for XInputExtensionInit */ #include "exglobals.h" #include "xkbsrv.h" /* for XkbInitPrivates */ +#include "xserver-properties.h" +#include <X11/extensions/XI2.h> #include "protocol-common.h" @@ -63,6 +65,65 @@ static void fake_init_sprite(DeviceIntPtr dev) sprite->physLimits.y2 = screen.height; } +/* This is essentially CorePointerProc with ScrollAxes added */ +static int +TestPointerProc(DeviceIntPtr pDev, int what) +{ +#define NBUTTONS 10 +#define NAXES 4 + BYTE map[NBUTTONS + 1]; + int i = 0; + Atom btn_labels[NBUTTONS] = {0}; + Atom axes_labels[NAXES] = {0}; + + switch (what) { + case DEVICE_INIT: + for (i = 1; i <= NBUTTONS; i++) + map[i] = i; + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); + btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + /* don't know about the rest */ + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); + + if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels, + (PtrCtrlProcPtr)NoopDDA, + GetMotionHistorySize(), NAXES, axes_labels)) + { + ErrorF("Could not initialize device '%s'. Out of memory.\n", + pDev->name); + return BadAlloc; + } + pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; + pDev->last.valuators[0] = pDev->valuator->axisVal[0]; + pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; + pDev->last.valuators[1] = pDev->valuator->axisVal[1]; + + SetScrollValuator(pDev, 2, SCROLL_TYPE_VERTICAL, 2.4, SCROLL_FLAG_NONE); + SetScrollValuator(pDev, 3, SCROLL_TYPE_HORIZONTAL, 3.5, SCROLL_FLAG_PREFERRED); + break; + + case DEVICE_CLOSE: + break; + + default: + break; + } + + return Success; + +#undef NBUTTONS +#undef NAXES +} /** * Create and init 2 master devices (VCP + VCK) and two slave devices, one * default mouse, one default keyboard. @@ -84,7 +145,7 @@ struct devices init_devices(void) EnableDevice(devices.vck, FALSE); AllocDevicePair(&client, "", &devices.mouse, &devices.kbd, - CorePointerProc, CoreKeyboardProc, FALSE); + TestPointerProc, CoreKeyboardProc, FALSE); ActivateDevice(devices.mouse, FALSE); ActivateDevice(devices.kbd, FALSE); EnableDevice(devices.mouse, FALSE); diff --git a/test/xi2/protocol-xiquerydevice.c b/test/xi2/protocol-xiquerydevice.c index 47eb5b14c..63d725f28 100644 --- a/test/xi2/protocol-xiquerydevice.c +++ b/test/xi2/protocol-xiquerydevice.c @@ -127,7 +127,7 @@ static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void dev = devices.mouse; assert(info->use == XISlavePointer); assert(info->attachment == devices.vcp->id); - assert(info->num_classes == 3); /* 2 axes + button */ + assert(info->num_classes == 7); /* 4 axes + button + 2 scroll*/ break; case 5: /* keyboard */ dev = devices.kbd; @@ -183,11 +183,48 @@ static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void } break; } - case 2: /* VCP and mouse have the same properties */ case 4: { assert(any->type == XIButtonClass || - any->type == XIValuatorClass); + any->type == XIValuatorClass || + any->type == XIScrollClass); + + if (any->type == XIScrollClass) + { + xXIScrollInfo *si = (xXIScrollInfo*)any; + + if (client->swapped) + { + swaps(&si->number); + swaps(&si->scroll_type); + swapl(&si->increment.integral); + swapl(&si->increment.frac); + } + assert(si->length == 6); + assert(si->number == 2 || si->number == 3); + if (si->number == 2) { + assert(si->scroll_type == XIScrollTypeVertical); + assert(!si->flags); + } + if (si->number == 3) { + assert(si->scroll_type == XIScrollTypeHorizontal); + assert(si->flags & XIScrollFlagPreferred); + assert(!(si->flags & ~XIScrollFlagPreferred)); + } + + assert(si->increment.integral == si->number); + /* FIXME: frac testing with float/FP issues? */ + assert(si->increment.frac > 0.3 * (1UL << 32)); + assert(si->increment.frac < 0.6 * (1UL << 32)); + } + + } + /* fall through */ + case 2: /* VCP and mouse have the same properties except for scroll */ + { + if (info->deviceid == 2 ) /* VCP */ + assert(any->type == XIButtonClass || + any->type == XIValuatorClass); if (any->type == XIButtonClass) { @@ -217,8 +254,10 @@ static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void } assert(vi->length == 11); - assert(vi->number == 0 || - vi->number == 1); + assert(vi->number >= 0 && vi->number < 4); + if (info->deviceid == 2) /* VCP */ + assert(vi->number < 2); + assert(vi->mode == XIModeRelative); /* device was set up as relative, so standard * values here. */ |