summarylogtreecommitdiffstats
path: root/0001-implement-trackpoint-wheel-emulation.patch
blob: da1795d502684509fe51b0b7843a668f965a54ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
From 3a5ea080e77dd6b77d18eff51121e48ee97d09b3 Mon Sep 17 00:00:00 2001
From: Taegil Bae <esrevinu@gmail.com>
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 <stefan.bethge@web.de>
  *      Matthias Ihmig <m.ihmig@gmx.net>
  *      Alexei Gilchrist <alexei@physics.uq.edu.au>
- *      Jörg Bösner <ich@joerg-boesner.de>
+ *      Jörg Bösner <ich@joerg-boesner.de>
  *      Hartwig Felger <hgfelger@hgfelger.de>
  *      Peter Osterlund <petero2@telia.com>
  *      S. Lehner <sam_x@bluemail.ch>
@@ -59,6 +59,8 @@
 #include "config.h"
 #endif
 
+#define BUILD_EVENTCOMM 1
+
 #include <xorg-server.h>
 #include <unistd.h>
 #include <misc.h>
@@ -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 <unistd.h>
 #include <sys/ioctl.h>
 #include <xf86Xinput.h>
@@ -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