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]> --- dix/getevents.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 104 insertions(+), 4 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index c1ebbb2..f8be73c 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 OS Authors * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -60,11 +61,13 @@ #include <X11/extensions/XI.h> #include <X11/extensions/XI2.h> #include <X11/extensions/XIproto.h> +#include <X11/extensions/XI2.h> #include <pixman.h> #include "exglobals.h" #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 @@ -622,8 +625,10 @@ GetMaximumEventsNum(void) { /* One raw event * One device event * One possible device changed event + * Lots of possible separate scroll events (horiz + vert) + * Lots of possible separate raw scroll event (horiz + vert) */ - return 3; + return 51; } @@ -1199,7 +1204,12 @@ 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 i; + ValuatorMask mask; + Atom h_scroll_label = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); + Atom v_scroll_label = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); + int h_scroll_axis = -1, v_scroll_axis = -1; /* refuse events from disabled devices */ if (!pDev->enabled) @@ -1210,8 +1220,98 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - num_events += _GetPointerEvents(events, pDev, type, buttons, ms, flags, - mask_in); + + valuator_mask_copy(&mask, mask_in); + + /* Find the vertical and horizontal scroll axes, if any. */ + for (i = 0; i < pDev->valuator->numAxes; i++) + { + if (h_scroll_label && pDev->valuator->axes[i].label == h_scroll_label) + h_scroll_axis = i; + else if (v_scroll_label && + pDev->valuator->axes[i].label == v_scroll_label) + v_scroll_axis = i; + } + + /* Turn a scroll button press into a smooth-scrolling event. */ + if (type == ButtonPress && + ((v_scroll_axis != -1 && (buttons == 4 || buttons == 5)) || + (h_scroll_axis != -1 && (buttons == 6 || buttons == 7)))) + { + double val; + + type = MotionNotify; + buttons = 0; + if (buttons == 4) + { + val = valuator_mask_get_double(&mask, v_scroll_axis) + 1.0; + valuator_mask_set_double(&mask, v_scroll_axis, val); + } + else if (buttons == 5) + { + val = valuator_mask_get_double(&mask, v_scroll_axis) - 1.0; + valuator_mask_set_double(&mask, v_scroll_axis, val); + } + else if (buttons == 6) + { + val = valuator_mask_get_double(&mask, v_scroll_axis) + 1.0; + valuator_mask_set_double(&mask, h_scroll_axis, val); + } + else if (buttons == 7) + { + val = valuator_mask_get_double(&mask, v_scroll_axis) - 1.0; + valuator_mask_set_double(&mask, h_scroll_axis, val); + } + } + + /* Return the original event set, plus potential legacy scrolling events. */ + nev_tmp = _GetPointerEvents(events, pDev, type, buttons, ms, flags, + &mask); + events += nev_tmp; + num_events += nev_tmp; + + 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)) && + (num_events + 4) < GetMaximumEventsNum()) + { + int b = 0; + + 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 = _GetPointerEvents(events, pDev, ButtonPress, b, ms, + POINTER_EMULATED, NULL); + events += nev_tmp; + num_events += nev_tmp; + nev_tmp = _GetPointerEvents(events, pDev, ButtonRelease, b, ms, + POINTER_EMULATED, NULL); + events += nev_tmp; + num_events += nev_tmp; + } + return num_events; } -- 1.7.5.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
