From: Daniel Stone <[email protected]> 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.
Signed-off-by: Daniel Stone <[email protected]> Reviewed-by: Peter Hutterer <[email protected]> --- dix/devices.c | 8 ++++ dix/getevents.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++-- include/inputstr.h | 2 + 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index ab8a648..0310119 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -1261,6 +1261,8 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, { int i; ValuatorClassPtr valc; + Atom h_scroll_label = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); + Atom v_scroll_label = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); if (!dev) return FALSE; @@ -1281,6 +1283,8 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, valc->motion = NULL; valc->first_motion = 0; valc->last_motion = 0; + valc->h_scroll_axis = -1; + valc->v_scroll_axis = -1; valc->numMotionEvents = numMotionEvents; valc->motionHintWindow = NullWindow; @@ -1295,6 +1299,10 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, for (i=0; i<numAxes; i++) { InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, mode); + if (labels[i] == h_scroll_label) + valc->h_scroll_axis = i; + else if (labels[i] == v_scroll_label) + valc->v_scroll_axis = i; valc->axisVal[i]=0; } diff --git a/dix/getevents.c b/dix/getevents.c index a1d5e52..2890b6f 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -2,6 +2,7 @@ * Copyright © 2006 Nokia Corporation * Copyright © 2006-2007 Daniel Stone * Copyright © 2008 Red Hat, Inc. + * Copyright © 2011 The Chromium Authors * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -65,6 +66,7 @@ #include "exevents.h" #include "extnsionst.h" #include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ +#include "xserver-properties.h" /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 @@ -603,8 +605,10 @@ GetMaximumEventsNum(void) { /* One raw event * One device event * One possible device changed event + * Lots of possible separate button scroll events (horiz + vert) + * Lots of possible separate raw button scroll events (horiz + vert) */ - return 3; + return 51; } @@ -1193,7 +1197,10 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, int flags, const ValuatorMask *mask_in) { CARD32 ms = GetTimeInMillis(); - int num_events = 0; + int num_events = 0, nev_tmp; + int h_scroll_axis = pDev->valuator->h_scroll_axis; + int v_scroll_axis = pDev->valuator->v_scroll_axis; + ValuatorMask mask; /* refuse events from disabled devices */ if (!pDev->enabled) @@ -1204,8 +1211,101 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - num_events += fill_pointer_events(events, pDev, type, buttons, ms, flags, - mask_in); + + valuator_mask_copy(&mask, mask_in); + + /* Turn a scroll button press into a smooth-scrolling event if necessary. */ + if (type == ButtonPress) + { + double val, adj; + int axis; + + switch (buttons) { + case 4: + adj = 1.0; + axis = v_scroll_axis; + break; + case 5: + adj = -1.0; + axis = v_scroll_axis; + break; + case 6: + adj = 1.0; + axis = h_scroll_axis; + break; + case 7: + adj = -1.0; + axis = h_scroll_axis; + break; + default: + adj = 0.0; + axis = -1; + break; + } + + if (adj != 0.0 && axis != -1) + { + val = valuator_mask_get_double(&mask, axis) + adj; + valuator_mask_set_double(&mask, axis, val); + type = MotionNotify; + buttons = 0; + } + } + + /* First fill out the original event set, with smooth-scrolling axes. */ + nev_tmp = fill_pointer_events(events, pDev, type, buttons, ms, flags, + &mask); + events += nev_tmp; + num_events += nev_tmp; + + /* Now turn the smooth-scrolling axes back into emulated button presses + * for legacy clients. */ + while ((v_scroll_axis != -1 && + fabs(pDev->last.valuators[v_scroll_axis]) >= 1.0) || + (h_scroll_axis != -1 && + fabs(pDev->last.valuators[h_scroll_axis]) >= 1.0)) + { + int b = 0; + + /* fill_pointer_events() generates four events: one normal and one raw + * event each for the emulated button press and release both. */ + if (num_events + 4 >= GetMaximumEventsNum()) + break; + + if (v_scroll_axis != -1 && pDev->last.valuators[v_scroll_axis] <= -1.0) + { + pDev->last.valuators[v_scroll_axis] += 1.0; + b = 4; + } + else if (v_scroll_axis != -1 && + pDev->last.valuators[v_scroll_axis] >= 1.0) + { + pDev->last.valuators[v_scroll_axis] -= 1.0; + b = 5; + } + else if (h_scroll_axis != -1 && + pDev->last.valuators[h_scroll_axis] <= -1.0) + { + pDev->last.valuators[h_scroll_axis] += 1.0; + b = 6; + } + else if (h_scroll_axis != -1 && + pDev->last.valuators[h_scroll_axis] >= 1.0) + { + pDev->last.valuators[h_scroll_axis] -= 1.0; + b = 7; + } + + nev_tmp = fill_pointer_events(events, pDev, ButtonPress, b, ms, + POINTER_EMULATED, NULL); + events += nev_tmp; + num_events += nev_tmp; + nev_tmp = fill_pointer_events(events, pDev, ButtonRelease, b, ms, + POINTER_EMULATED, NULL); + events += nev_tmp; + num_events += nev_tmp; + } + return num_events; } diff --git a/include/inputstr.h b/include/inputstr.h index c25f5c6..26327cd 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -283,6 +283,8 @@ typedef struct _ValuatorClassRec { unsigned short numAxes; double *axisVal; /* always absolute, but device-coord system */ ValuatorAccelerationRec accelScheme; + int h_scroll_axis; /* horiz smooth-scrolling axis */ + int v_scroll_axis; /* vert smooth-scrolling axis */ } ValuatorClassRec; typedef struct _ButtonClassRec { -- 1.7.6 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
