WaylandEvdevInputEvent: Fix segfault
[profile/ivi/layer-management.git] / LayerManagerPlugins / Renderers / Graphic / src / WindowSystems / WaylandEvdevInputEvent.cpp
1 /***************************************************************************
2 *
3 * Copyright 2010, 2011 BMW Car IT GmbH
4 * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *        http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *
20 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
21 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
24 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
25 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
26 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 *
28 ****************************************************************************/
29 #include <time.h>
30 #include <sys/time.h>
31 #include <sys/wait.h>
32 #include <linux/input.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <libudev.h>
39 #include <mtdev.h>
40 #include <math.h>
41 #include "InputManager.h"
42 #include "WindowSystems/WaylandEvdevInputEvent.h"
43
44 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
45
46 #define WL_UNUSED(A) (A)=(A)
47 static const char default_seat[] = "seat0";
48
49 // copied from udev/extras/input_id/input_id.c
50 // we must use this kernel-compatible implementation
51 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
52 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
53 #define OFF(x)  ((x)%BITS_PER_LONG)
54 #define BIT(x)  (1UL<<OFF(x))
55 #define LONG(x) ((x)/BITS_PER_LONG)
56 #define TEST_BIT(array, bit)    ((array[LONG(bit)] >> OFF(bit)) & 1)
57 // end copied
58
59 #define MAX_VELOCITY_DIFF    1.0
60 #define MOTION_TIMEOUT       300 // (ms)
61 #define NUM_POINTER_TRACKERS 16
62
63 struct evdev_dispatch_interface touchpad_interface = {
64     WaylandEvdevInputEvent::touchpadProcess,
65     WaylandEvdevInputEvent::touchpadDestroy,
66 };
67
68 struct evdev_dispatch_interface fallback_interface = {
69     WaylandEvdevInputEvent::fallbackProcess,
70     WaylandEvdevInputEvent::fallbackDestroy,
71 };
72
73 // Function prototypes
74 void acceleratorFilter (struct motion_filter *, struct motion_params *, void *, uint32_t);
75 void acceleratorDestroy(struct motion_filter *);
76
77 struct motion_filter_interface accelerator_interface = {
78     acceleratorFilter,
79     acceleratorDestroy,
80 };
81
82 static struct touchpad_model_spec touchpad_spec_table[] = {
83     {0x0002, 0x0007, TOUCHPAD_MODEL_SYNAPTICS},
84     {0x0002, 0x0008, TOUCHPAD_MODEL_ALPS},
85     {0x05ac, 0x0000, TOUCHPAD_MODEL_APPLETOUCH},
86     {0x0002, 0x000e, TOUCHPAD_MODEL_ELANTECH},
87     {0x0000, 0x0000, TOUCHPAD_MODEL_UNKNOWN}
88 };
89
90 ////////////////////////////////////////////////////////////////////////////
91
92 static int
93 isMotionEvent(struct input_event *e)
94 {
95     switch (e->type){
96     case EV_REL:
97         switch (e->code){
98         case REL_X:
99         case REL_Y:
100             return 1;
101         }
102         break;
103     case EV_ABS:
104         switch (e->code){
105         case ABS_X:
106         case ABS_Y:
107         case ABS_MT_POSITION_X:
108         case ABS_MT_POSITION_Y:
109             return 1;
110         }
111         break;
112     }
113     return 0;
114 }
115
116 static enum touchpad_model
117 getTouchpadModel(struct evdev_input_device *device)
118 {
119     struct input_id id;
120     unsigned int i;
121
122     if (ioctl(device->fd, EVIOCGID, &id) < 0)
123         return TOUCHPAD_MODEL_UNKNOWN;
124
125     for (i = 0; i < sizeof(touchpad_spec_table); ++i){
126         if (touchpad_spec_table[i].vendor == id.vendor &&
127             (!touchpad_spec_table[i].product ||
128             touchpad_spec_table[i].product == id.product)){
129             return touchpad_spec_table[i].model;
130         }
131     }
132
133     return TOUCHPAD_MODEL_UNKNOWN;
134 }
135
136 static void
137 configureTouchpadPressure(struct touchpad_dispatch *touchpad,
138                           int32_t pressure_min, int32_t pressure_max)
139 {
140     int32_t range = pressure_max - pressure_min + 1;
141     touchpad->has_pressure = 1;
142
143     // Magic numbers from xf86-input-synaptics
144     switch (touchpad->model){
145     case TOUCHPAD_MODEL_ELANTECH:
146         touchpad->pressure.touch_low  = pressure_min + 1;
147         touchpad->pressure.touch_high = pressure_min + 1;
148         break;
149     default:
150         touchpad->pressure.touch_low  = pressure_min + range * (25.0/256.0);
151         touchpad->pressure.touch_high = pressure_min + range * (30.0/256.0);
152         break;
153     }
154
155     touchpad->pressure.press = pressure_min + range;
156 }
157
158 static double
159 touchpadProfile(struct motion_filter *filter, void *data,
160                 double velocity, uint32_t time)
161 {
162     WL_UNUSED(filter);
163     WL_UNUSED(time);
164     struct touchpad_dispatch *touchpad = (struct touchpad_dispatch*)data;
165     double accel_factor;
166
167     accel_factor = velocity * touchpad->constant_accel_factor;
168
169     if (accel_factor > touchpad->max_accel_factor)
170         accel_factor = touchpad->max_accel_factor;
171     else if (accel_factor < touchpad->min_accel_factor)
172         accel_factor = touchpad->min_accel_factor;
173
174     return accel_factor;
175 }
176
177 static motion_filter*
178 createPointerAccelatorFilter(accel_profile_func_t profile)
179 {
180     struct pointer_accelerator *filter;
181
182     filter = (struct pointer_accelerator*)malloc(sizeof(*filter));
183     if (filter == NULL)
184         return NULL;
185
186     filter->base.interface = &accelerator_interface;
187     wl_list_init(&filter->base.link);
188
189     filter->profile = profile;
190     filter->last_velocity = 0.0;
191     filter->last_dx = 0;
192     filter->last_dy = 0;
193
194     filter->trackers = (struct pointer_tracker*)
195         calloc(NUM_POINTER_TRACKERS, sizeof(*filter->trackers));
196     filter->cur_tracker = 0;
197
198     return &filter->base;
199 }
200
201 static evdev_dispatch*
202 createFallbackDispatch()
203 {
204     struct evdev_dispatch *dispatch =
205         (struct evdev_dispatch*)malloc(sizeof(*dispatch));
206     if (dispatch ==   NULL)
207         return NULL;
208
209     dispatch->interface = &fallback_interface;
210
211     return dispatch;
212 }
213
214 ////////////////////////////////////////////////////////////////////////
215
216 static void
217 processTouch(struct evdev_input_device *device, struct input_event *e,
218              int screen_width, int screen_height)
219 {
220     switch (e->code) {
221     case ABS_MT_SLOT:
222         device->mt.slot = e->value;
223         break;
224     case ABS_MT_TRACKING_ID:
225         if (e->value >= 0)
226             device->pending_events |= EVDEV_ABSOLUTE_MT_DOWN;
227         else
228             device->pending_events |= EVDEV_ABSOLUTE_MT_UP;
229         break;
230     case ABS_MT_POSITION_X:
231         device->mt.x[device->mt.slot] =
232             (e->value - device->abs.min_x) * screen_width /
233             (device->abs.max_x - device->abs.min_x) +
234             0; //device->output->x;
235         device->pending_events |= EVDEV_ABSOLUTE_MT_MOTION;
236         break;
237     case ABS_MT_POSITION_Y:
238         device->mt.y[device->mt.slot] =
239             (e->value - device->abs.min_y) * screen_height /
240             (device->abs.max_y - device->abs.min_y) +
241             0; //device->output->y;
242         device->pending_events |= EVDEV_ABSOLUTE_MT_MOTION;
243         break;
244     }
245 }
246
247 static void
248 processAbsoluteMotion(struct evdev_input_device *device, struct input_event *e,
249                       int screen_width, int screen_height)
250 {
251     switch (e->code) {
252     case ABS_X:
253         device->abs.x =
254             (e->value - device->abs.min_x) * screen_width /
255             (device->abs.max_x - device->abs.min_x) +
256             0; //device->output->x;
257         device->pending_events |= EVDEV_ABSOLUTE_MOTION;
258         break;
259     case ABS_Y:
260         device->abs.y =
261             (e->value - device->abs.min_y) * screen_height /
262             (device->abs.max_y - device->abs.min_y) +
263             0; //device->output->y;
264         device->abs.x = screen_width - device->abs.x;
265         device->pending_events |= EVDEV_ABSOLUTE_MOTION;
266         break;
267     // The following is the effective code only from a specific model
268     /****
269     case ABS_X:
270         device->abs.y = (e->value - device->abs.min_x) * screen_height /
271                         (device->abs.max_x - device->abs.min_x);
272         device->pending_events |= EVDEV_ABSOLUTE_MOTION;
273         break;
274     case ABS_Y:
275         device->abs.x = (e->value - device->abs.min_y) * screen_width /
276                         (device->abs.max_y - device->abs.min_y);
277         device->abs.x = screen_width - device->abs.x;
278         device->pending_events |= EVDEV_ABSOLUTE_MOTION;
279         break;
280      ****/
281     }
282 }
283
284 ////////////////////////////////////////////////////////////////////////
285
286 static int
287 hysteresis(int in, int center, int margin)
288 {
289     int diff = in - center;
290     if (abs(diff) <= margin)
291         return center;
292
293     if (diff > margin)
294         return center + diff - margin;
295     else if (diff < -margin)
296         return center + diff + margin;
297     return center + diff;
298 }
299
300 static inline struct touchpad_motion*
301 motionHistoryOffset(struct touchpad_dispatch *touchpad, int offset)
302 {
303     int offsetIndex =
304         (touchpad->motion_index - offset + TOUCHPAD_HISTORY_LENGTH) %
305         TOUCHPAD_HISTORY_LENGTH;
306
307     return &touchpad->motion_history[offsetIndex];
308 }
309
310 static double
311 estimateDelta(int x0, int x1, int x2, int x3)
312 {
313     return (x0 + x1 - x2 - x3) / 4;
314 }
315
316 static void
317 touchpadGetDelta(struct touchpad_dispatch *touchpad, double *dx, double *dy)
318 {
319     *dx = estimateDelta(motionHistoryOffset(touchpad, 0)->x,
320                         motionHistoryOffset(touchpad, 1)->x,
321                         motionHistoryOffset(touchpad, 2)->x,
322                         motionHistoryOffset(touchpad, 3)->x);
323     *dy = estimateDelta(motionHistoryOffset(touchpad, 0)->y,
324                         motionHistoryOffset(touchpad, 1)->y,
325                         motionHistoryOffset(touchpad, 2)->y,
326                         motionHistoryOffset(touchpad, 3)->y);
327 }
328
329 static void
330 filterDispatch(struct motion_filter *filter, struct motion_params *motion,
331                void *data, uint32_t time)
332 {
333     filter->interface->filter(filter, motion, data, time);
334 }
335
336 static void
337 filterMotion(struct touchpad_dispatch *touchpad,
338              double *dx, double *dy, uint32_t time)
339 {
340     struct motion_filter *filter;
341     struct motion_params  motion;
342
343     motion.dx = *dx;
344     motion.dy = *dy;
345
346     wl_list_for_each(filter, &touchpad->motion_filters, link){
347         filterDispatch(filter, &motion, touchpad, time);
348     }
349
350     *dx = motion.dx;
351     *dy = motion.dy;
352 }
353
354 static int
355 getDirection(int dx, int dy)
356 {
357     int dir = UNDEFINED_DIRECTION;
358     int d1, d2;
359     double r;
360
361     if (abs(dx) < 2 && abs(dy) < 2) {
362         if (dx > 0 && dy > 0)
363             dir = S | SE | E;
364         else if (dx > 0 && dy < 0)
365             dir = N | NE | E;
366         else if (dx < 0 && dy > 0)
367             dir = S | SW | W;
368         else if (dx < 0 && dy < 0)
369             dir = N | NW | W;
370         else if (dx > 0)
371             dir = NW | W | SW;
372         else if (dx < 0)
373             dir = NE | E | SE;
374         else if (dy > 0)
375             dir = SE | S | SW;
376         else if (dy < 0)
377             dir = NE | N | NW;
378     }
379     else {
380         // Calculate r within the interval  [0 to 8)
381         //
382         // r = [0 .. 2Ï€] where 0 is North
383         // d_f = r / 2Ï€  ([0 .. 1))
384         // d_8 = 8 * d_f
385         //
386         r = atan2(dy, dx);
387         r = fmod(r + 2.5*M_PI, 2*M_PI);
388         r *= 4*M_1_PI;
389
390         // Mark one or two close enough octants
391         d1 = (int)(r + 0.9) % 8;
392         d2 = (int)(r + 0.1) % 8;
393
394         dir = (1 << d1) | (1 << d2);
395     }
396
397     return dir;
398 }
399
400 static void
401 feedTrackers(struct pointer_accelerator *accel,
402              double dx, double dy, uint32_t time)
403 {
404     int i, current;
405     struct pointer_tracker *trackers = accel->trackers;
406
407     for (i = 0; i < NUM_POINTER_TRACKERS; ++i){
408         trackers[i].dx += dx;
409         trackers[i].dy += dy;
410     }
411
412     current = (accel->cur_tracker + 1) % NUM_POINTER_TRACKERS;
413     accel->cur_tracker = current;
414
415     trackers[current].dx = 0.0;
416     trackers[current].dy = 0.0;
417     trackers[current].time = time;
418     trackers[current].dir  = getDirection(dx, dy);
419 }
420
421 static struct pointer_tracker*
422 trackerByOffset(struct pointer_accelerator *accel, unsigned int offset)
423 {
424     unsigned int index =
425         (accel->cur_tracker + NUM_POINTER_TRACKERS - offset)
426         % NUM_POINTER_TRACKERS;
427     return &accel->trackers[index];
428 }
429
430 static double
431 calculateTrackerVelocity(struct pointer_tracker *tracker, uint32_t time)
432 {
433     int dx;
434     int dy;
435     double distance;
436
437     dx = tracker->dx;
438     dy = tracker->dy;
439     distance = sqrt(dx*dx + dy*dy);
440     return distance / (double)(time - tracker->time);
441 }
442
443 static double
444 calculateVelocity(struct pointer_accelerator *accel, uint32_t time)
445 {
446     struct pointer_tracker *tracker;
447     double velocity;
448     double result = 0.0;
449     double initial_velocity;
450     double velocity_diff;
451     unsigned int offset;
452
453     unsigned int dir = trackerByOffset(accel, 0)->dir;
454
455     // Find first velocity
456     for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) {
457         tracker = trackerByOffset(accel, offset);
458
459         if (time <= tracker->time)
460             continue;
461
462         result = initial_velocity =
463             calculateTrackerVelocity(tracker, time);
464         if (initial_velocity > 0.0)
465             break;
466     }
467
468     // Find least recent vector within a timelimit, maximum velocity diff
469     // and direction threshold.
470     for (; offset < NUM_POINTER_TRACKERS; offset++) {
471         tracker = trackerByOffset(accel, offset);
472
473         // Stop if too far away in time
474         if (time - tracker->time > MOTION_TIMEOUT ||
475             tracker->time > time)
476             break;
477
478         // Stop if direction changed
479         dir &= tracker->dir;
480         if (dir == 0)
481             break;
482
483         velocity = calculateTrackerVelocity(tracker, time);
484
485         // Stop if velocity differs too much from initial
486         velocity_diff = fabs(initial_velocity - velocity);
487         if (velocity_diff > MAX_VELOCITY_DIFF)
488             break;
489
490         result = velocity;
491     }
492
493     return result;
494 }
495
496 static double
497 accelerationProfile(struct pointer_accelerator *accel,
498                     void *data, double velocity, uint32_t time)
499 {
500     return accel->profile(&accel->base, data, velocity, time);
501 }
502
503 static double
504 calculateAcceleration(struct pointer_accelerator *accel,
505                       void *data, double velocity, uint32_t time)
506 {
507     double factor;
508
509     factor  = accelerationProfile(accel, data, velocity, time);
510     factor += accelerationProfile(accel, data, accel->last_velocity, time);
511     factor += 4.0 *
512               accelerationProfile(accel, data,
513                                  (accel->last_velocity + velocity) / 2,
514                                   time);
515     factor = factor / 6.0;
516     return factor;
517 }
518
519 static double
520 softenDelta(double lastDelta, double delta)
521 {
522     if (delta < -1.0 || delta > 1.0){
523         if (delta > lastDelta)
524             return delta - 0.5;
525         else if (delta < lastDelta)
526             return delta + 0.5;
527     }
528     return delta;
529 }
530
531 static void
532 applySoftening(struct pointer_accelerator *accel,
533                struct motion_params *motion)
534 {
535     motion->dx = softenDelta(accel->last_dx, motion->dx);
536     motion->dy = softenDelta(accel->last_dy, motion->dy);
537 }
538
539 void
540 acceleratorFilter(struct motion_filter *filter, struct motion_params *motion,
541                   void *data, uint32_t time)
542 {
543     struct pointer_accelerator *accel = (struct pointer_accelerator*)filter;
544     double velocity;
545     double accel_value;
546
547     feedTrackers(accel, motion->dx, motion->dy, time);
548     velocity = calculateVelocity(accel, time);
549     accel_value = calculateAcceleration(accel, data, velocity, time);
550
551     motion->dx = accel_value * motion->dx;
552     motion->dy = accel_value * motion->dy;
553
554     applySoftening(accel, motion);
555
556     accel->last_dx = motion->dx;
557     accel->last_dy = motion->dy;
558
559     accel->last_velocity = velocity;
560 }
561
562 void
563 acceleratorDestroy(struct motion_filter *filter)
564 {
565     struct pointer_accelerator *accel = (struct pointer_accelerator*)filter;
566
567     free(accel->trackers);
568     free(accel);
569 }
570
571 /// WaylandEvdevInputEvent /////////////////////////////////////////////////
572
573 WaylandEvdevInputEvent::WaylandEvdevInputEvent(WaylandBaseWindowSystem* windowSystem)
574 : WaylandInputEvent(windowSystem)
575 , m_udev(NULL)
576 , m_screenWidth(0)
577 , m_screenHeight(0)
578 {
579     wl_list_init(&m_deviceList);
580 }
581
582 WaylandEvdevInputEvent::~WaylandEvdevInputEvent()
583 {
584     if (m_udev){
585         udev_unref(m_udev);
586     }
587
588     struct evdev_input_device *device, *next;
589
590     wl_list_for_each_safe(device, next, &m_deviceList, link){
591         removeDevice(device);
592     }
593 }
594
595 void
596 WaylandEvdevInputEvent::removeDevice(struct evdev_input_device *device)
597 {
598     struct evdev_dispatch *dispatch = device->dispatch;
599
600     if (dispatch)
601         dispatch->interface->destroy(dispatch);
602
603     wl_event_source_remove(device->source);
604     wl_list_remove(&device->link);
605     if (device->mtdev)
606         mtdev_close_delete(device->mtdev);
607     close(device->fd);
608     free(device->devnode);
609     free(device);
610 }
611
612 void
613 WaylandEvdevInputEvent::setupInputEvent()
614 {
615     LOG_INFO("WaylandEvdevInputEvent", "setupInputEvent IN");
616
617     WaylandInputEvent::setupInputEvent();
618
619     m_screenWidth  = m_windowSystem->getWindowWidth();
620     m_screenHeight = m_windowSystem->getWindowHeight();
621
622     do {
623         bool bRet = addDevices();
624         if (!bRet){
625             break;
626         }
627     } while (0);
628
629     LOG_INFO("WaylandEvdevInputEvent", "setupInputEvent OUT");
630 }
631
632 bool
633 WaylandEvdevInputEvent::addDevices()
634 {
635     if (!m_udev)
636         m_udev = udev_new();
637     if (!m_udev){
638         LOG_ERROR("WaylandEvdevInputEvent", "Failed to initialize udev context");
639         return false;
640     }
641
642     struct udev_enumerate *e = udev_enumerate_new(m_udev);
643     udev_enumerate_add_match_subsystem(e, "input");
644     udev_enumerate_scan_devices(e);
645
646     struct udev_list_entry *entry;
647     const char *path, *sysname;
648     struct udev_device *device;
649     udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)){
650         path = udev_list_entry_get_name(entry);
651         device = udev_device_new_from_syspath(m_udev, path);
652
653         sysname = udev_device_get_sysname(device);
654         if (strncmp("event", sysname, 5) != 0){
655             udev_device_unref(device);
656             continue;
657         }
658
659         addDevice(device);
660         udev_device_unref(device);
661     }
662     udev_enumerate_unref(e);
663
664     notifyKeyboardFocus();
665
666     if (wl_list_empty(&m_deviceList)){
667         LOG_WARNING("WaylandEvdevInputEvent", "No input devices on entering service");
668     }
669
670     return true;
671 }
672
673 void
674 WaylandEvdevInputEvent::addDevice(struct udev_device *udevDevice)
675 {
676     const char *devnode;
677     const char *device_seat;
678
679     device_seat = udev_device_get_property_value(udevDevice, "ID_SEAT");
680     if (!device_seat)
681         device_seat = default_seat;
682
683     devnode = udev_device_get_devnode(udevDevice);
684     createInputDevice(m_windowSystem->getNativeDisplayHandle(), devnode);
685 }
686
687 void
688 WaylandEvdevInputEvent::createInputDevice(struct wl_display *display, const char *path)
689 {
690     struct evdev_input_device *device;
691     struct wl_event_loop      *eventLoop;
692
693     device = (struct evdev_input_device*)malloc(sizeof(*device));
694     if (device == NULL){
695         return;
696     }
697
698     device->master   = this;
699     device->isMt     = 0;
700     device->mtdev    = NULL;
701     device->devnode  = strdup(path);
702     device->mt.slot  = -1;
703     device->rel.dx   = 0;
704     device->rel.dy   = 0;
705     device->dispatch = NULL;
706
707     device->fd = open(path, O_RDWR | O_NONBLOCK);
708     if (device->fd < 0){
709         goto err0;
710     }
711
712     if (configureDevice(device) < 0){
713         goto err1;
714     }
715
716     // If the dispatch was not set up use the fallback
717     if (device->dispatch == NULL)
718         device->dispatch = createFallbackDispatch();
719     if (device->dispatch == NULL)
720         goto err1;
721
722     if (device->isMt){
723         device->mtdev = mtdev_new_open(device->fd);
724         if  (!device->mtdev){
725             LOG_WARNING("WaylandEvdevInputEvent", "mtdev failed to open for " << path);
726         }
727     }
728
729     eventLoop = wl_display_get_event_loop(display);
730     device->source = wl_event_loop_add_fd(eventLoop, device->fd, WL_EVENT_READABLE,
731                                           WaylandEvdevInputEvent::handleInputEvent,
732                                           device);
733     if (device->source == NULL){
734         goto err2;
735     }
736
737     wl_list_insert(m_deviceList.prev, &(device->link));
738
739     return;
740
741 err2:
742     device->dispatch->interface->destroy(device->dispatch);
743 err1:
744     close(device->fd);
745 err0:
746     free(device->devnode);
747     free(device);
748     return;
749 }
750
751 int
752 WaylandEvdevInputEvent::configureDevice(struct evdev_input_device *device)
753 {
754     struct input_absinfo absinfo;
755     unsigned long ev_bits[NBITS(EV_MAX)];
756     unsigned long abs_bits[NBITS(ABS_MAX)];
757     unsigned long rel_bits[NBITS(ABS_MAX)];
758     unsigned long key_bits[NBITS(KEY_MAX)];
759
760     int hasKey = 0;
761     int hasAbs = 0;
762     int i;
763     device->caps = 0;
764
765     ioctl(device->fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits);
766     if (TEST_BIT(ev_bits, EV_ABS)){
767         hasAbs = 1;
768
769         ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
770         if (TEST_BIT(abs_bits, ABS_X)){
771             ioctl(device->fd, EVIOCGABS(ABS_X), &absinfo);
772             device->abs.min_x = absinfo.minimum;
773             device->abs.max_x = absinfo.maximum;
774             device->caps |= EVDEV_MOTION_ABS;
775         }
776         if (TEST_BIT(abs_bits, ABS_Y)){
777             ioctl(device->fd, EVIOCGABS(ABS_Y), &absinfo);
778             device->abs.min_y = absinfo.minimum;
779             device->abs.max_y = absinfo.maximum;
780             device->caps |= EVDEV_MOTION_ABS;
781         }
782         if (TEST_BIT(abs_bits, ABS_MT_SLOT)){
783             device->isMt = 1;
784             device->mt.slot = 0;
785             device->caps |= EVDEV_TOUCH;
786         }
787     }
788     if (TEST_BIT(ev_bits, EV_REL)){
789         ioctl(device->fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), rel_bits);
790         if (TEST_BIT(rel_bits, REL_X) || TEST_BIT(rel_bits, REL_Y)){
791             device->caps |= EVDEV_MOTION_REL;
792         }
793     }
794     if (TEST_BIT(ev_bits, EV_KEY)){
795         hasKey = 1;
796         ioctl(device->fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits);
797         if (TEST_BIT(key_bits, BTN_TOOL_FINGER) &&
798             !TEST_BIT(key_bits, BTN_TOOL_PEN) && hasAbs){
799             device->dispatch = createTouchpad(device);
800         }
801
802         for (i = KEY_ESC; i < KEY_MAX; ++i){
803             if (i >= BTN_MISC && i < KEY_OK)
804                 continue;
805             if (TEST_BIT(key_bits, i)){
806                 device->caps |= EVDEV_KEYBOARD;
807                 break;
808             }
809         }
810         for (i = BTN_MISC; i < KEY_OK; ++i){
811             if (TEST_BIT(key_bits, i)){
812                 device->caps |= EVDEV_BUTTON;
813                 break;
814             }
815         }
816     }
817     if (TEST_BIT(ev_bits, EV_LED)){
818         device->caps |= EVDEV_KEYBOARD;
819     }
820
821     // This rule tries to catch accelerometer devices and opt out. We may
822     // want to adjust the protocol later adding a proper event for dealing
823     // with accelerometers and implement here accordingly
824     if (hasAbs && !hasKey && !device->isMt)
825         return -1;
826
827 #if 0
828     fprintf(stdout, "DEVICE: [%s] information\n", device->devnode);
829     fprintf(stdout, "        capabilities: EVDEV_KEYBOARD   %s\n"
830                     "                      EVDEV_BUTTON     %s\n"
831                     "                      EVDEV_MOTION_ABS %s\n"
832                     "                      EVDEV_MOTION_REL %s\n"
833                     "                      EVDEV_TOUCH      %s\n",
834             (device->caps & EVDEV_KEYBOARD)   ? "TRUE" : "FALSE",
835             (device->caps & EVDEV_BUTTON)     ? "TRUE" : "FALSE",
836             (device->caps & EVDEV_MOTION_ABS) ? "TRUE" : "FALSE",
837             (device->caps & EVDEV_MOTION_REL) ? "TRUE" : "FALSE",
838             (device->caps & EVDEV_TOUCH)      ? "TRUE" : "FALSE");
839     if (device->caps & EVDEV_MOTION_ABS){
840         fprintf(stdout, "        abs: min_x(%4d), min_y(%4d)\n", device->abs.min_x, device->abs.min_y);
841         fprintf(stdout, "             max_x(%4d), max_y(%4d)\n", device->abs.max_x, device->abs.max_y);
842         fprintf(stdout, "                 x(%4d),     y(%4d)\n", device->abs.x, device->abs.y);
843     }
844     fprintf(stdout, "\n");
845 #endif
846
847     if ((device->caps & (EVDEV_MOTION_ABS | EVDEV_MOTION_REL | EVDEV_BUTTON))){
848         initPointerDevice();
849     }
850     if ((device->caps & (EVDEV_KEYBOARD))){
851         initKeyboardDevice(NULL);
852     }
853     if ((device->caps & (EVDEV_TOUCH))){
854         initTouchDevice();
855     }
856
857     return 0;
858 }
859
860 void
861 WaylandEvdevInputEvent::notifyKeyboardFocus()
862 {
863     struct evdev_input_device *device;
864     struct wl_array keys;
865     char evdev_keys[(KEY_CNT + 7) / 8], all_keys[(KEY_CNT + 7) / 8];
866     uint32_t *k;
867     unsigned int i, set;
868     int ret;
869
870     memset(all_keys, 0, sizeof(all_keys));
871     wl_list_for_each(device, &m_deviceList, link){
872         memset(evdev_keys, 0, sizeof(evdev_keys));
873         ret = ioctl(device->fd, EVIOCGKEY(sizeof(evdev_keys)), evdev_keys);
874         if (ret < 0){
875             LOG_WARNING("WaylandEvdevInputEvent", "Failed to get keys for device: " <<
876                         device->devnode);
877             continue;
878         }
879         for (i = 0; i < ARRAY_LENGTH(evdev_keys); ++i){
880             all_keys[i] |= evdev_keys[i];
881         }
882     }
883
884     wl_array_init(&keys);
885     for (i = 0; i < KEY_CNT; ++i){
886         set = all_keys[i >> 3] & (1 << (i & 7));
887         if (set){
888             k = (uint32_t*)wl_array_add(&keys, sizeof(*k));
889             *k = i;
890         }
891     }
892
893     notifyKeyboardFocusIn(&keys, STATE_UPDATE_AUTOMATIC);
894
895     wl_array_release(&keys);
896 }
897
898 void
899 WaylandEvdevInputEvent::notifyKeyboardFocusIn(struct wl_array *keys,
900                                               enum key_state_update updateState)
901 {
902     struct wl_seat *wlSeat;
903     uint32_t *k, serial;
904
905     if ((wlSeat = m_inputDevice->seat()) == NULL){
906         return;
907     }
908     if (!wlSeat->keyboard){
909         return;
910     }
911     serial = wl_display_next_serial(m_inputDevice->display());
912     wl_array_init(&wlSeat->keyboard->keys);
913     wl_array_copy(&wlSeat->keyboard->keys, keys);
914
915     struct wl_array *array = &wlSeat->keyboard->keys;
916     for (k = (uint32_t*)array->data;
917         (const char*)k < (const char*)array->data + array->size;
918         ++k){
919         if (updateState == STATE_UPDATE_AUTOMATIC){
920             updateModifierState(wlSeat, serial, *k, WL_KEYBOARD_KEY_STATE_PRESSED);
921         }
922     }
923 }
924
925 void
926 WaylandEvdevInputEvent::updateModifierState(struct wl_seat *wlSeat, uint32_t serial,
927                                             uint32_t key, enum wl_keyboard_key_state state)
928 {
929     enum xkb_key_direction direction;
930
931     if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
932         direction = XKB_KEY_DOWN;
933     else
934         direction = XKB_KEY_UP;
935
936     // Offset the keycode by 8, as the evdev XKB rules reflect X's
937     // broken keycode system, which starts at 8.
938     xkb_state_update_key(m_xkbState.state, key + 8, direction);
939
940     notifyModifiers(wlSeat, serial);
941 }
942
943 struct evdev_dispatch*
944 WaylandEvdevInputEvent::createTouchpad(struct evdev_input_device *device)
945 {
946     struct touchpad_dispatch *touchpad;
947
948     touchpad = (struct touchpad_dispatch*)malloc(sizeof(*touchpad));
949     if (touchpad == NULL)
950         return NULL;
951
952     touchpad->base.interface = &touchpad_interface;
953
954     touchpad->device = device;
955     wl_list_init(&touchpad->motion_filters);
956
957     configureTouchpad(touchpad, device);
958
959     return &touchpad->base;
960 }
961
962 void
963 WaylandEvdevInputEvent::configureTouchpad(struct touchpad_dispatch *touchpad,
964                                           struct evdev_input_device *device)
965 {
966     struct motion_filter *accel;
967
968     struct input_absinfo absinfo;
969     unsigned long abs_bits[NBITS(ABS_MAX)];
970
971     double width;
972     double height;
973     double diagonal;
974
975     // Detect model
976     touchpad->model = getTouchpadModel(device);
977
978     // Configure pressure
979     ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
980     if (TEST_BIT(abs_bits, ABS_PRESSURE)) {
981         ioctl(device->fd, EVIOCGABS(ABS_PRESSURE), &absinfo);
982         configureTouchpadPressure(touchpad,
983                                   absinfo.minimum,
984                                   absinfo.maximum);
985     }
986
987     // Configure acceleration factor
988     width = abs(device->abs.max_x - device->abs.min_x);
989     height = abs(device->abs.max_y - device->abs.min_y);
990     diagonal = sqrt(width*width + height*height);
991
992     touchpad->constant_accel_factor =
993         DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
994
995     touchpad->min_accel_factor = DEFAULT_MIN_ACCEL_FACTOR;
996     touchpad->max_accel_factor = DEFAULT_MAX_ACCEL_FACTOR;
997
998     touchpad->hysteresis.margin_x = diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
999     touchpad->hysteresis.margin_y = diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
1000     touchpad->hysteresis.center_x = 0;
1001     touchpad->hysteresis.center_y = 0;
1002
1003     // Configure acceleration profile
1004     accel = createPointerAccelatorFilter(touchpadProfile);
1005     wl_list_insert(&touchpad->motion_filters, &accel->link);
1006
1007     // Setup initial state
1008     touchpad->reset = 1;
1009
1010     memset(touchpad->motion_history, 0, sizeof touchpad->motion_history);
1011     touchpad->motion_index = 0;
1012     touchpad->motion_count = 0;
1013
1014     touchpad->state = TOUCHPAD_STATE_NONE;
1015     touchpad->last_finger_state = 0;
1016     touchpad->finger_state = 0;
1017 }
1018
1019 int
1020 WaylandEvdevInputEvent::handleInputEvent(int fd, uint32_t mask, void *data)
1021 {
1022     WL_UNUSED(mask);
1023
1024     struct evdev_input_device *device = (evdev_input_device*)data;
1025     struct input_event ev[32];
1026     int len;
1027     do {
1028         if (device->mtdev){
1029             len = mtdev_get(device->mtdev, fd, ev,
1030                 ARRAY_LENGTH(ev)) * sizeof(struct input_event);
1031         }
1032         else {
1033             len = read(fd, &ev, sizeof(ev));
1034         }
1035
1036         if (len < 0 || len % sizeof(ev[0]) != 0){
1037             return 1;
1038         }
1039
1040         WaylandEvdevInputEvent::processEvents(device, ev, len / sizeof(ev[0]));
1041
1042     } while (len > 0);
1043
1044     return 1;
1045 }
1046
1047 void
1048 WaylandEvdevInputEvent::processEvents(struct evdev_input_device *device,
1049                                       struct input_event *ev,
1050                                       int count)
1051 {
1052     struct evdev_dispatch *dispatch = device->dispatch;
1053     struct input_event *e, *end;
1054     uint32_t time = 0;
1055
1056     device->pending_events = 0;
1057
1058     e = ev;
1059     end = e + count;
1060     for (; e < end; ++e){
1061         time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
1062
1063         if (!isMotionEvent(e)){
1064             WaylandEvdevInputEvent::flushMotion(device, time);
1065         }
1066
1067         dispatch->interface->process(dispatch, device, e, time);
1068     }
1069
1070     WaylandEvdevInputEvent::flushMotion(device, time);
1071 }
1072
1073 void
1074 WaylandEvdevInputEvent::flushMotion(struct evdev_input_device *device,
1075                                     uint32_t time)
1076 {
1077     if (!device->pending_events)
1078         return;
1079
1080     WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1081     if (!inputEvent)
1082         return;
1083
1084     if (device->pending_events & EVDEV_RELATIVE_MOTION){
1085         struct wl_seat *wlSeat = inputEvent->inputDevice().seat();
1086         if (wlSeat){
1087             // notify_motion
1088             notifyMotion(device, time,
1089                          wlSeat->pointer->x + device->rel.dx,
1090                          wlSeat->pointer->y + device->rel.dy);
1091         }
1092         device->pending_events &= ~EVDEV_RELATIVE_MOTION;
1093         device->rel.dx = 0;
1094         device->rel.dy = 0;
1095     }
1096     if (device->pending_events & EVDEV_ABSOLUTE_MT_DOWN){
1097         // notify_touch
1098         notifyTouch(device);
1099         device->pending_events &= ~EVDEV_ABSOLUTE_MT_DOWN;
1100         device->pending_events &= ~EVDEV_ABSOLUTE_MT_MOTION;
1101     }
1102     if (device->pending_events & EVDEV_ABSOLUTE_MT_MOTION){
1103         // notify_touch
1104         notifyTouch(device);
1105         device->pending_events &= ~EVDEV_ABSOLUTE_MT_DOWN;
1106         device->pending_events &= ~EVDEV_ABSOLUTE_MT_MOTION;
1107     }
1108     if (device->pending_events & EVDEV_ABSOLUTE_MT_UP){
1109         // notify_touch
1110         notifyTouch(device);
1111         device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP;
1112     }
1113     if (device->pending_events & EVDEV_ABSOLUTE_MOTION){
1114         // notify_motion
1115         notifyMotion(device, time,
1116                      wl_fixed_from_int(device->abs.x),
1117                      wl_fixed_from_int(device->abs.y));
1118         device->pending_events &= ~EVDEV_ABSOLUTE_MOTION;
1119     }
1120 }
1121
1122 /// Default event handler //////////////////////////////////////////////////
1123
1124 void
1125 WaylandEvdevInputEvent::fallbackProcess(struct evdev_dispatch *dispatch,
1126                                         struct evdev_input_device *device,
1127                                         struct input_event *e,
1128                                         uint32_t time)
1129 {
1130     WL_UNUSED(dispatch);
1131
1132     switch (e->type){
1133     case EV_REL:
1134         evdevProcessRelative(device, time, e);
1135         break;
1136     case EV_ABS:
1137         evdevProcessAbsolute(device, e);
1138         break;
1139     case EV_KEY:
1140         evdevProcessKey(device, time, e);
1141         break;
1142     }
1143 }
1144
1145 void
1146 WaylandEvdevInputEvent::fallbackDestroy(struct evdev_dispatch *dispatch)
1147 {
1148     if (dispatch) free(dispatch);
1149 }
1150
1151 void
1152 WaylandEvdevInputEvent::evdevProcessRelative(struct evdev_input_device *device,
1153                                              uint32_t /*time*/, struct input_event *e)
1154 {
1155     switch (e->code){
1156     case REL_X:
1157         device->rel.dx += wl_fixed_from_int(e->value);
1158         device->pending_events |= EVDEV_RELATIVE_MOTION;
1159         break;
1160     case REL_Y:
1161         device->rel.dy += wl_fixed_from_int(e->value);
1162         device->pending_events |= EVDEV_RELATIVE_MOTION;
1163         break;
1164     case REL_WHEEL:
1165     case REL_HWHEEL:
1166         // not supported
1167         break;
1168     }
1169 }
1170
1171 void
1172 WaylandEvdevInputEvent::evdevProcessAbsolute(struct evdev_input_device *device,
1173                                              struct input_event *e)
1174 {
1175     WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1176     if (!inputEvent)
1177         return;
1178
1179     int w = inputEvent->m_screenWidth;
1180     int h = inputEvent->m_screenHeight;
1181
1182     if (device->isMt){
1183         processTouch(device, e, w, h);
1184     } else {
1185         processAbsoluteMotion(device, e, w, h);
1186     }
1187 }
1188
1189 void
1190 WaylandEvdevInputEvent::evdevProcessKey(struct evdev_input_device *device,
1191                                         uint32_t time, struct input_event *e)
1192 {
1193     if (e->value == 2)
1194         return;
1195
1196     switch (e->code){
1197     case BTN_LEFT:
1198     case BTN_RIGHT:
1199     case BTN_MIDDLE:
1200     case BTN_SIDE:
1201     case BTN_EXTRA:
1202     case BTN_FORWARD:
1203     case BTN_BACK:
1204     case BTN_TASK:
1205     case BTN_TOUCH:
1206         // notify_button
1207         notifyButton(device, time, e->code,
1208                      e->value ? WL_POINTER_BUTTON_STATE_PRESSED
1209                               : WL_POINTER_BUTTON_STATE_RELEASED);
1210         break;
1211     default:
1212         // notify_key
1213         notifyKey(device, time, e->code,
1214                   e->value ? WL_KEYBOARD_KEY_STATE_PRESSED
1215                            : WL_KEYBOARD_KEY_STATE_RELEASED,
1216                   true);
1217         break;
1218     }
1219 }
1220
1221 /// Multi-touch event handler //////////////////////////////////////////////
1222
1223 void
1224 WaylandEvdevInputEvent::touchpadProcess(struct evdev_dispatch *dispatch,
1225                                         struct evdev_input_device *device,
1226                                         struct input_event *e,
1227                                         uint32_t time)
1228 {
1229     struct touchpad_dispatch *touchpad = (struct touchpad_dispatch*)dispatch;
1230
1231     switch (e->type){
1232     case EV_SYN:
1233         if (e->code == SYN_REPORT)
1234             touchpad->event_mask |= TOUCHPAD_EVENT_REPORT;
1235         break;
1236     case EV_ABS:
1237         touchpadProcessAbsolute(touchpad, device, e);
1238         break;
1239     case EV_KEY:
1240         touchpadProcessKey(touchpad, device, e, time);
1241         break;
1242     }
1243
1244     touchpadUpdateState(touchpad, time);
1245 }
1246
1247 void
1248 WaylandEvdevInputEvent::touchpadDestroy(struct evdev_dispatch *dispatch)
1249 {
1250     struct touchpad_dispatch *touchpad = (struct touchpad_dispatch*)dispatch;
1251     struct motion_filter *filter;
1252     struct motion_filter *next;
1253
1254     wl_list_for_each_safe(filter, next, &touchpad->motion_filters, link){
1255         filter->interface->destroy(filter);
1256     }
1257
1258     if (dispatch) free(dispatch);
1259 }
1260
1261 void
1262 WaylandEvdevInputEvent::touchpadProcessAbsolute(struct touchpad_dispatch *touchpad,
1263                                                 struct evdev_input_device *device,
1264                                                 struct input_event *e)
1265 {
1266     WL_UNUSED(device);
1267
1268     switch (e->code){
1269     case ABS_PRESSURE:
1270         if (e->value > touchpad->pressure.press)
1271             touchpad->state = TOUCHPAD_STATE_PRESS;
1272         else if (e->value > touchpad->pressure.touch_high)
1273             touchpad->state = TOUCHPAD_STATE_TOUCH;
1274         else if (e->value < touchpad->pressure.touch_low){
1275             if (touchpad->state > TOUCHPAD_STATE_NONE)
1276                 touchpad->reset = 1;
1277             touchpad->state = TOUCHPAD_STATE_NONE;
1278         }
1279         break;
1280     case ABS_X:
1281         if (touchpad->state >= TOUCHPAD_STATE_TOUCH){
1282             touchpad->hw_abs.x = e->value;
1283             touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
1284             touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_X;
1285         }
1286         break;
1287     case ABS_Y:
1288         if (touchpad->state >= TOUCHPAD_STATE_TOUCH){
1289             touchpad->hw_abs.y = e->value;
1290             touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
1291             touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_Y;
1292         }
1293         break;
1294     }
1295 }
1296
1297 void
1298 WaylandEvdevInputEvent::touchpadProcessKey(struct touchpad_dispatch *touchpad,
1299                                            struct evdev_input_device * device,
1300                                            struct input_event *e,
1301                                            uint32_t time)
1302 {
1303     switch (e->code){
1304     case BTN_TOUCH:
1305         if (!touchpad->has_pressure){
1306             if (!e->value){
1307                 touchpad->state = TOUCHPAD_STATE_NONE;
1308                 touchpad->reset = 1;
1309             }
1310             else {
1311                 touchpad->state = e->value ? TOUCHPAD_STATE_TOUCH
1312                                            : TOUCHPAD_STATE_NONE;
1313             }
1314         }
1315         break;
1316     case BTN_LEFT:
1317     case BTN_RIGHT:
1318     case BTN_MIDDLE:
1319     case BTN_SIDE:
1320     case BTN_EXTRA:
1321     case BTN_FORWARD:
1322     case BTN_BACK:
1323     case BTN_TASK:
1324         // notify_button
1325         notifyButton(device, time, e->code,
1326                      e->value ? WL_POINTER_BUTTON_STATE_PRESSED
1327                               : WL_POINTER_BUTTON_STATE_RELEASED);
1328         break;
1329     case BTN_TOOL_PEN:
1330     case BTN_TOOL_RUBBER:
1331     case BTN_TOOL_BRUSH:
1332     case BTN_TOOL_PENCIL:
1333     case BTN_TOOL_AIRBRUSH:
1334     case BTN_TOOL_MOUSE:
1335     case BTN_TOOL_LENS:
1336         touchpad->reset = 1;
1337         break;
1338     case BTN_TOOL_FINGER:
1339         touchpad->finger_state =
1340             ~TOUCHPAD_FINGERS_ONE | e->value ? TOUCHPAD_FINGERS_ONE : 0;
1341         break;
1342     case BTN_TOOL_DOUBLETAP:
1343         touchpad->finger_state =
1344             ~TOUCHPAD_FINGERS_TWO | e->value ? TOUCHPAD_FINGERS_TWO : 0;
1345         break;
1346     case BTN_TOOL_TRIPLETAP:
1347         touchpad->finger_state =
1348             ~TOUCHPAD_FINGERS_THREE | e->value ? TOUCHPAD_FINGERS_THREE : 0;
1349         break;
1350     }
1351 }
1352
1353 void
1354 WaylandEvdevInputEvent::touchpadUpdateState(struct touchpad_dispatch *touchpad,
1355                                             uint32_t time)
1356 {
1357     int motion_index;
1358     int center_x, center_y;
1359     double dx, dy;
1360
1361     if (touchpad->reset ||
1362         touchpad->last_finger_state != touchpad->finger_state) {
1363         touchpad->reset = 0;
1364         touchpad->motion_count = 0;
1365         touchpad->event_mask = TOUCHPAD_EVENT_NONE;
1366         touchpad->event_mask_filter =
1367             TOUCHPAD_EVENT_ABSOLUTE_X | TOUCHPAD_EVENT_ABSOLUTE_Y;
1368
1369         touchpad->last_finger_state = touchpad->finger_state;
1370
1371         return;
1372     }
1373     touchpad->last_finger_state = touchpad->finger_state;
1374
1375     if (!(touchpad->event_mask & TOUCHPAD_EVENT_REPORT))
1376         return;
1377     else
1378         touchpad->event_mask &= ~TOUCHPAD_EVENT_REPORT;
1379
1380     if ((touchpad->event_mask & touchpad->event_mask_filter) !=
1381         touchpad->event_mask_filter)
1382         return;
1383
1384     touchpad->event_mask_filter = TOUCHPAD_EVENT_ABSOLUTE_ANY;
1385     touchpad->event_mask = 0;
1386
1387     // Avoid noice by moving center only when delta reaches a threshold
1388     // distance from the old center
1389     if (touchpad->motion_count > 0) {
1390         center_x = hysteresis(touchpad->hw_abs.x,
1391                       touchpad->hysteresis.center_x,
1392                       touchpad->hysteresis.margin_x);
1393         center_y = hysteresis(touchpad->hw_abs.y,
1394                       touchpad->hysteresis.center_y,
1395                       touchpad->hysteresis.margin_y);
1396     }
1397     else {
1398         center_x = touchpad->hw_abs.x;
1399         center_y = touchpad->hw_abs.y;
1400     }
1401     touchpad->hysteresis.center_x = center_x;
1402     touchpad->hysteresis.center_y = center_y;
1403     touchpad->hw_abs.x = center_x;
1404     touchpad->hw_abs.y = center_y;
1405
1406     // Update motion history tracker
1407     motion_index = (touchpad->motion_index + 1) % TOUCHPAD_HISTORY_LENGTH;
1408     touchpad->motion_index = motion_index;
1409     touchpad->motion_history[motion_index].x = touchpad->hw_abs.x;
1410     touchpad->motion_history[motion_index].y = touchpad->hw_abs.y;
1411     if (touchpad->motion_count < 4)
1412         touchpad->motion_count++;
1413
1414     if (touchpad->motion_count >= 4) {
1415         touchpadGetDelta(touchpad, &dx, &dy);
1416
1417         filterMotion(touchpad, &dx, &dy, time);
1418
1419         touchpad->device->rel.dx = wl_fixed_from_double(dx);
1420         touchpad->device->rel.dy = wl_fixed_from_double(dy);
1421         touchpad->device->pending_events |= EVDEV_RELATIVE_MOTION;
1422     }
1423 }
1424
1425 /// Notifier ///////////////////////////////////////////////////////////////
1426
1427 void
1428 WaylandEvdevInputEvent::notifyButton(struct evdev_input_device *device,
1429                                      uint32_t time, int32_t button,
1430                                      enum wl_pointer_button_state state)
1431 {
1432     WLEvent         wlEvent;
1433     struct wl_seat *wlSeat = NULL;
1434     uint32_t        serial;
1435
1436     WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1437     if (!inputEvent)
1438         return;
1439
1440     wlSeat = inputEvent->inputDevice().seat();
1441     serial = wl_display_next_serial(inputEvent->inputDevice().display());
1442
1443     if (state == WL_POINTER_BUTTON_STATE_PRESSED){
1444         if (wlSeat->pointer->button_count == 0){
1445             wlSeat->pointer->grab_button = button;
1446             wlSeat->pointer->grab_time = time;
1447             wlSeat->pointer->grab_x = wlSeat->pointer->x;
1448             wlSeat->pointer->grab_y = wlSeat->pointer->y;
1449         }
1450         ++wlSeat->pointer->button_count;
1451     }
1452     else {
1453         --wlSeat->pointer->button_count;
1454     }
1455     wlEvent.x = wl_fixed_to_int(wlSeat->pointer->x);
1456     wlEvent.y = wl_fixed_to_int(wlSeat->pointer->y);
1457     wlEvent.buttonState = state;
1458     wlEvent.serial = serial;
1459
1460     inputEvent->windowSystem().manageWLInputEvent(INPUT_DEVICE_POINTER,
1461         state == WL_POINTER_BUTTON_STATE_PRESSED ? INPUT_STATE_PRESSED :
1462         INPUT_STATE_RELEASED, &wlEvent);
1463
1464     if (wlSeat->pointer->button_count == 1){
1465         wlSeat->pointer->grab_serial =
1466             wl_display_get_serial(inputEvent->inputDevice().display());
1467     }
1468 }
1469
1470 void
1471 WaylandEvdevInputEvent::notifyMotion(struct evdev_input_device *device,
1472                                      uint32_t time,
1473                                      wl_fixed_t fx, wl_fixed_t fy)
1474 {
1475     WL_UNUSED(time);
1476
1477     WLEvent         wlEvent;
1478     struct wl_seat *wlSeat = NULL;
1479     int             x, y;
1480     //int             old_x, old_y;
1481     int             w, h;
1482
1483     WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1484     if (!inputEvent)
1485         return;
1486
1487     wlSeat = inputEvent->inputDevice().seat();
1488     w = inputEvent->m_screenWidth;
1489     h = inputEvent->m_screenHeight;
1490
1491     x = wl_fixed_to_int(fx);
1492     y = wl_fixed_to_int(fy);
1493     //old_x = wl_fixed_to_int(wlSeat->pointer->x);
1494     //old_y = wl_fixed_to_int(wlSeat->pointer->y);
1495     if (x < 0) x = 0;
1496     if (x > w) x = w;
1497     if (y < 0) y = 0;
1498     if (y > h) y = h;
1499
1500     wlSeat->pointer->x = wl_fixed_from_int(x);
1501     wlSeat->pointer->y = wl_fixed_from_int(y);
1502
1503     wlEvent.x = x;
1504     wlEvent.y = y;
1505
1506     inputEvent->windowSystem().manageWLInputEvent(
1507         INPUT_DEVICE_POINTER, INPUT_STATE_MOTION, &wlEvent);
1508 }
1509
1510 void
1511 WaylandEvdevInputEvent::notifyKey(struct evdev_input_device *device,
1512                                   uint32_t time, uint32_t key,
1513                                   enum wl_keyboard_key_state state,
1514                                   bool bUpdateAutomatic)
1515 {
1516     WL_UNUSED(bUpdateAutomatic);
1517
1518     WLEvent wlEvent;
1519     struct wl_seat *wlSeat = NULL;
1520     uint32_t *k, *end;
1521
1522     WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1523     if (!inputEvent)
1524         return;
1525
1526     wlSeat = inputEvent->inputDevice().seat();
1527     if (state == WL_KEYBOARD_KEY_STATE_PRESSED){
1528         wlSeat->keyboard->grab_key = key;
1529         wlSeat->keyboard->grab_time = time;
1530     }
1531
1532     end = (uint32_t*)(((unsigned char*)wlSeat->keyboard->keys.data) + wlSeat->keyboard->keys.size);
1533     for (k = (uint32_t*)wlSeat->keyboard->keys.data; k < end; ++k){
1534         if (*k == key){
1535             // Ignore server-generated repeats
1536             if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1537                 return;
1538             *k = *--end;
1539         }
1540     }
1541     wlSeat->keyboard->keys.size = end - (uint32_t*)wlSeat->keyboard->keys.data;
1542     if (state == WL_KEYBOARD_KEY_STATE_PRESSED){
1543         k = (uint32_t*)wl_array_add(&wlSeat->keyboard->keys, sizeof(*k));
1544         *k = key;
1545     }
1546
1547     wlEvent.keyCode = key;
1548     wlEvent.keyState = state;
1549
1550     inputEvent->windowSystem().manageWLInputEvent(INPUT_DEVICE_KEYBOARD,
1551         state == WL_KEYBOARD_KEY_STATE_PRESSED ? INPUT_STATE_PRESSED
1552                                                : INPUT_STATE_RELEASED, &wlEvent);
1553 }
1554
1555 void
1556 WaylandEvdevInputEvent::notifyTouch(struct evdev_input_device *device)
1557 {
1558     WLEvent         wlEvent;
1559     InputEventState eventState = INPUT_STATE_OTHER;
1560
1561     WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1562     if (!inputEvent)
1563         return;
1564
1565     if (device->pending_events & EVDEV_ABSOLUTE_MT_DOWN){
1566         wlEvent.x = (int)wl_fixed_from_int(device->mt.x[device->mt.slot]);
1567         wlEvent.y = (int)wl_fixed_from_int(device->mt.y[device->mt.slot]);
1568         wlEvent.touchId = device->mt.slot;
1569         wlEvent.touchType = WL_TOUCH_DOWN;
1570         eventState = INPUT_STATE_PRESSED;
1571     } else
1572     if (device->pending_events & EVDEV_ABSOLUTE_MT_MOTION){
1573         wlEvent.x = (int)wl_fixed_from_int(device->mt.x[device->mt.slot]);
1574         wlEvent.y = (int)wl_fixed_from_int(device->mt.y[device->mt.slot]);
1575         wlEvent.touchId = device->mt.slot;
1576         wlEvent.touchType = WL_TOUCH_MOTION;
1577         eventState = INPUT_STATE_MOTION;
1578     } else
1579     if (device->pending_events & EVDEV_ABSOLUTE_MT_UP){
1580         wlEvent.x = 0;
1581         wlEvent.y = 0;
1582         wlEvent.touchId = device->mt.slot;
1583         wlEvent.touchType = WL_TOUCH_UP;
1584         eventState = INPUT_STATE_RELEASED;
1585     }
1586     else {
1587         return;
1588     }
1589
1590     inputEvent->windowSystem().manageWLInputEvent(INPUT_DEVICE_TOUCH, eventState, &wlEvent);
1591 }
1592
1593 void
1594 WaylandEvdevInputEvent::notifyModifiers(struct wl_seat *wlSeat, uint32_t serial)
1595 {
1596     uint32_t mods_depressed, mods_latched, mods_locked, group;
1597     uint32_t mods_lookup;
1598     int changed = 0;
1599
1600     mods_depressed = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_DEPRESSED);
1601     mods_latched   = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_LATCHED);
1602     mods_locked    = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_LOCKED);
1603     group          = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_EFFECTIVE);
1604
1605     if (mods_depressed != wlSeat->keyboard->modifiers.mods_depressed ||
1606         mods_latched   != wlSeat->keyboard->modifiers.mods_latched   ||
1607         mods_locked    != wlSeat->keyboard->modifiers.mods_locked    ||
1608         group          != wlSeat->keyboard->modifiers.group){
1609         changed = 1;
1610     }
1611
1612     wlSeat->keyboard->modifiers.mods_depressed = mods_depressed;
1613     wlSeat->keyboard->modifiers.mods_latched   = mods_latched;
1614     wlSeat->keyboard->modifiers.mods_locked    = mods_locked;
1615     wlSeat->keyboard->modifiers.group          = group;
1616
1617     // And update the modifier_state for bindings
1618     mods_lookup = mods_depressed | mods_latched;
1619     m_modifierState = 0;
1620     if (mods_lookup & (1 << m_xkbInfo.ctrl_mod))  m_modifierState |= MODIFIER_CTRL;
1621     if (mods_lookup & (1 << m_xkbInfo.alt_mod))   m_modifierState |= MODIFIER_ALT;
1622     if (mods_lookup & (1 << m_xkbInfo.super_mod)) m_modifierState |= MODIFIER_SUPER;
1623     if (mods_lookup & (1 << m_xkbInfo.shift_mod)) m_modifierState |= MODIFIER_SHIFT;
1624
1625     if (changed){
1626         m_inputDevice->sendModifiers(serial);
1627     }
1628 }