aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-3m-pct.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-3m-pct.c')
-rw-r--r--drivers/hid/hid-3m-pct.c41
1 files changed, 5 insertions, 36 deletions
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index 3c380e1c5b60..39628e02a428 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -37,7 +37,6 @@ MODULE_LICENSE("GPL");
37struct mmm_finger { 37struct mmm_finger {
38 __s32 x, y, w, h; 38 __s32 x, y, w, h;
39 __u16 id; 39 __u16 id;
40 __u8 rank;
41 bool prev_touch; 40 bool prev_touch;
42 bool touch, valid; 41 bool touch, valid;
43}; 42};
@@ -45,7 +44,7 @@ struct mmm_finger {
45struct mmm_data { 44struct mmm_data {
46 struct mmm_finger f[MAX_SLOTS]; 45 struct mmm_finger f[MAX_SLOTS];
47 __u16 id; 46 __u16 id;
48 __u8 curid, num; 47 __u8 curid;
49 __u8 nexp, nreal; 48 __u8 nexp, nreal;
50 bool touch, valid; 49 bool touch, valid;
51}; 50};
@@ -156,13 +155,7 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
156static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) 155static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
157{ 156{
158 struct mmm_finger *oldest = 0; 157 struct mmm_finger *oldest = 0;
159 bool pressed = false, released = false;
160 int i; 158 int i;
161
162 /*
163 * we need to iterate on all fingers to decide if we have a press
164 * or a release event in our touchscreen emulation.
165 */
166 for (i = 0; i < MAX_SLOTS; ++i) { 159 for (i = 0; i < MAX_SLOTS; ++i) {
167 struct mmm_finger *f = &md->f[i]; 160 struct mmm_finger *f = &md->f[i];
168 if (!f->valid) { 161 if (!f->valid) {
@@ -183,34 +176,11 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
183 wide ? f->w : f->h); 176 wide ? f->w : f->h);
184 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, 177 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR,
185 wide ? f->h : f->w); 178 wide ? f->h : f->w);
186 /* 179 /* touchscreen emulation: pick the oldest contact */
187 * touchscreen emulation: maintain the age rank 180 if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
188 * of this finger, decide if we have a press
189 */
190 if (f->rank == 0) {
191 f->rank = ++(md->num);
192 if (f->rank == 1)
193 pressed = true;
194 }
195 if (f->rank == 1)
196 oldest = f; 181 oldest = f;
197 } else { 182 } else {
198 /* this finger took off the screen */ 183 /* this finger took off the screen */
199 /* touchscreen emulation: maintain age rank of others */
200 int j;
201
202 for (j = 0; j < 10; ++j) {
203 struct mmm_finger *g = &md->f[j];
204 if (g->rank > f->rank) {
205 g->rank--;
206 if (g->rank == 1)
207 oldest = g;
208 }
209 }
210 f->rank = 0;
211 --(md->num);
212 if (md->num == 0)
213 released = true;
214 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1); 184 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
215 } 185 }
216 f->prev_touch = f->touch; 186 f->prev_touch = f->touch;
@@ -219,11 +189,10 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
219 189
220 /* touchscreen emulation */ 190 /* touchscreen emulation */
221 if (oldest) { 191 if (oldest) {
222 if (pressed) 192 input_event(input, EV_KEY, BTN_TOUCH, 1);
223 input_event(input, EV_KEY, BTN_TOUCH, 1);
224 input_event(input, EV_ABS, ABS_X, oldest->x); 193 input_event(input, EV_ABS, ABS_X, oldest->x);
225 input_event(input, EV_ABS, ABS_Y, oldest->y); 194 input_event(input, EV_ABS, ABS_Y, oldest->y);
226 } else if (released) { 195 } else {
227 input_event(input, EV_KEY, BTN_TOUCH, 0); 196 input_event(input, EV_KEY, BTN_TOUCH, 0);
228 } 197 }
229 input_sync(input); 198 input_sync(input);