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