From 3a5ea080e77dd6b77d18eff51121e48ee97d09b3 Mon Sep 17 00:00:00 2001 From: Taegil Bae Date: Thu, 12 Dec 2013 20:52:48 +0900 Subject: [PATCH 1/6] implement trackpoint wheel emulation --- src/evdev.c | 33 ++++++++++++++++++++++++++- src/evdev.h | 2 ++ src/synaptics.c | 66 ++++++++++++++++++++++++++++++++++++------------------ src/synapticsstr.h | 1 + src/synproto.c | 2 +- src/synproto.h | 4 ++++ 6 files changed, 84 insertions(+), 24 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 30f809b..d860836 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -115,6 +115,9 @@ static int proximity_bits[] = { BTN_TOOL_LENS, }; +int SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); +void SynapticsUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); + static int EvdevOn(DeviceIntPtr); static int EvdevCache(InputInfoPtr pInfo); static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl); @@ -141,6 +144,8 @@ static Atom prop_device; static Atom prop_virtual; static Atom prop_scroll_dist; +InputInfoPtr trackpoint = NULL; + static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode) { InputInfoPtr pInfo; @@ -969,7 +974,7 @@ static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int num_v, int first_v, * Take the synchronization input event and process it accordingly; the motion * notify events are sent first, then any button/key press/release events. */ -static void +void EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev) { int i; @@ -2510,6 +2515,11 @@ static void EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { EvdevPtr pEvdev = pInfo ? pInfo->private : NULL; + + /* Synaptics */ + if (pEvdev->isSynaptics) + return SynapticsUnInit(drv, pInfo, flags); + if (pEvdev) { /* Release string allocated in EvdevOpenDevice. */ @@ -2521,6 +2531,12 @@ EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) libevdev_free(pEvdev->dev); } + + /* TrackPoint */ + if (strstr(pInfo->name, "TrackPoint")) { + trackpoint = NULL; + } + xf86DeleteInput(pInfo, flags); } @@ -2559,6 +2575,9 @@ EvdevAlloc(InputInfoPtr pInfo) pEvdev->rel_axis_map[1] = 1; pEvdev->type_name = NULL; + + /* Synaptics */ + pEvdev->isSynaptics = 0; return pEvdev; } @@ -2577,6 +2596,11 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) pInfo->device_control = EvdevProc; pInfo->read_input = EvdevReadInput; pInfo->switch_mode = EvdevSwitchMode; + + /* TrackPoint */ + if (strstr(pInfo->name, "TrackPoint")) { + trackpoint = pInfo; + } rc = EvdevOpenDevice(pInfo); if (rc != Success) @@ -2604,6 +2628,13 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) rc = BadMatch; goto error; } + + /* Synaptics */ + if (pEvdev->flags & EVDEV_TOUCHPAD) { + free(pInfo->private); + pInfo->private = NULL; + return SynapticsPreInit(drv, pInfo, flags); + } /* Overwrite type_name with custom-defined one (#62831). Note: pInfo->type_name isn't freed so we need to manually do this diff --git a/src/evdev.h b/src/evdev.h index 520d017..341fd91 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -152,6 +152,8 @@ typedef struct { } EventQueueRec, *EventQueuePtr; typedef struct { + int isSynaptics; + struct libevdev *dev; char *device; diff --git a/src/synaptics.c b/src/synaptics.c index b25c902..aa7725d 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -1,20 +1,20 @@ /* - * Copyright © 1999 Henry Davies - * Copyright © 2001 Stefan Gmeiner - * Copyright © 2002 S. Lehner - * Copyright © 2002 Peter Osterlund - * Copyright © 2002 Linuxcare Inc. David Kennedy - * Copyright © 2003 Hartwig Felger - * Copyright © 2003 Jörg Bösner - * Copyright © 2003 Fred Hucht - * Copyright © 2004 Alexei Gilchrist - * Copyright © 2004 Matthias Ihmig - * Copyright © 2006 Stefan Bethge - * Copyright © 2006 Christian Thaeter - * Copyright © 2007 Joseph P. Skudlarek - * Copyright © 2008 Fedor P. Goncharov - * Copyright © 2008-2012 Red Hat, Inc. - * Copyright © 2011 The Chromium OS Authors + * Copyright © 1999 Henry Davies + * Copyright © 2001 Stefan Gmeiner + * Copyright © 2002 S. Lehner + * Copyright © 2002 Peter Osterlund + * Copyright © 2002 Linuxcare Inc. David Kennedy + * Copyright © 2003 Hartwig Felger + * Copyright © 2003 Jörg Bösner + * Copyright © 2003 Fred Hucht + * Copyright © 2004 Alexei Gilchrist + * Copyright © 2004 Matthias Ihmig + * Copyright © 2006 Stefan Bethge + * Copyright © 2006 Christian Thaeter + * Copyright © 2007 Joseph P. Skudlarek + * Copyright © 2008 Fedor P. Goncharov + * Copyright © 2008-2012 Red Hat, Inc. + * Copyright © 2011 The Chromium OS Authors * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without @@ -41,7 +41,7 @@ * Stefan Bethge * Matthias Ihmig * Alexei Gilchrist - * Jörg Bösner + * Jörg Bösner * Hartwig Felger * Peter Osterlund * S. Lehner @@ -59,6 +59,8 @@ #include "config.h" #endif +#define BUILD_EVENTCOMM 1 + #include #include #include @@ -77,6 +79,12 @@ #include "synapticsstr.h" #include "synaptics-properties.h" +extern InputInfoPtr trackpoint; +extern BOOL +EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value); +void +EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev); + enum EdgeType { NO_EDGE = 0, BOTTOM_EDGE = 1, @@ -119,8 +127,8 @@ enum EdgeType { /***************************************************************************** * Forward declaration ****************************************************************************/ -static int SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); -static void SynapticsUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); +int SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); +void SynapticsUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); static Bool DeviceControl(DeviceIntPtr, int); static void ReadInput(InputInfoPtr); static int HandleState(InputInfoPtr, struct SynapticsHwState *, CARD32 now, @@ -834,7 +842,7 @@ SynapticsAccelerationProfile(DeviceIntPtr dev, return accelfct; } -static int +int SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { SynapticsPrivate *priv; @@ -850,6 +858,8 @@ SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) pInfo->control_proc = ControlProc; pInfo->switch_mode = SwitchMode; pInfo->private = priv; + + priv->isSynaptics = 1; /* allocate now so we don't allocate in the signal handler */ priv->timer = TimerSet(NULL, 0, 0, NULL, NULL); @@ -929,7 +939,7 @@ SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) /* * Uninitialize the device. */ -static void +void SynapticsUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { SynapticsPrivate *priv = ((SynapticsPrivate *) pInfo->private); @@ -2787,7 +2797,9 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw, * the soft button instead. */ if (para->clickpad) { /* hw->left is down, but no other buttons were already down */ - if (!(priv->lastButtons & 7) && hw->left && !hw->right && !hw->middle) { + if (!(priv->lastButtons & 7) && + hw->left && !hw->right && !hw->middle && + !hw->trackpoint_middle) { /* If the finger down event is delayed, the x and y * coordinates are stale so we delay processing the click */ if (hw->z < para->finger_low) { @@ -2805,6 +2817,11 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw, else if (is_inside_middlebutton_area(para, hw->x, hw->y)) { hw->left = 0; hw->middle = 1; + if (trackpoint) { + hw->middle = 0; + hw->trackpoint_middle = 1; + EvdevWheelEmuFilterButton(trackpoint, 2, 1); + } } else if (is_inside_sec_middlebutton_area(para, hw->x, hw->y)) { hw->left = 0; @@ -2817,6 +2834,11 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw, hw->middle = (priv->lastButtons & 2) ? 1 : 0; hw->right = (priv->lastButtons & 4) ? 1 : 0; } + else if (hw->trackpoint_middle) { + hw->trackpoint_middle = 0; + EvdevWheelEmuFilterButton(trackpoint, 2, 0); + EvdevProcessSyncEvent(trackpoint, NULL); + } } /* Fingers emulate other buttons. ClickFinger can only be diff --git a/src/synapticsstr.h b/src/synapticsstr.h index 4bd32ac..1ca02ac 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -229,6 +229,7 @@ typedef struct _SynapticsParameters { } SynapticsParameters; struct _SynapticsPrivateRec { + int isSynaptics; SynapticsParameters synpara; /* Default parameter settings, read from the X config file */ struct SynapticsProtocolOperations *proto_ops; diff --git a/src/synproto.c b/src/synproto.c index 91e20e6..143160c 100644 --- a/src/synproto.c +++ b/src/synproto.c @@ -1,5 +1,5 @@ /* - * Copyright © 2012 Canonical, Ltd. + * Copyright © 2012 Canonical, Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), diff --git a/src/synproto.h b/src/synproto.h index c52838c..3ba3617 100644 --- a/src/synproto.h +++ b/src/synproto.h @@ -31,6 +31,8 @@ #include "config.h" #endif +#define BUILD_EVENTCOMM 1 + #include #include #include @@ -74,6 +76,8 @@ struct SynapticsHwState { Bool multi[8]; Bool middle; /* Some ALPS touchpads have a middle button */ + + Bool trackpoint_middle; int num_mt_mask; ValuatorMask **mt_mask; -- 1.9.3