1 /***************************************************************************
3 * Copyright 2010, 2011 BMW Car IT GmbH
4 * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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.
28 ****************************************************************************/
32 #include <linux/input.h>
41 #include "InputManager.h"
42 #include "WindowSystems/WaylandEvdevInputEvent.h"
44 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
46 #define WL_UNUSED(A) (A)=(A)
47 static const char default_seat[] = "seat0";
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)
59 #define MAX_VELOCITY_DIFF 1.0
60 #define MOTION_TIMEOUT 300 // (ms)
61 #define NUM_POINTER_TRACKERS 16
63 struct evdev_dispatch_interface touchpad_interface = {
64 WaylandEvdevInputEvent::touchpadProcess,
65 WaylandEvdevInputEvent::touchpadDestroy,
68 struct evdev_dispatch_interface fallback_interface = {
69 WaylandEvdevInputEvent::fallbackProcess,
70 WaylandEvdevInputEvent::fallbackDestroy,
73 // Function prototypes
74 void acceleratorFilter(struct motion_filter *, struct motion_params *, void *, uint32_t);
75 void acceleratorDestroy(struct motion_filter *);
77 struct motion_filter_interface accelerator_interface = {
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}
90 ////////////////////////////////////////////////////////////////////////////
93 isMotionEvent(struct input_event *e)
110 case ABS_MT_POSITION_X:
111 case ABS_MT_POSITION_Y:
119 static enum touchpad_model
120 getTouchpadModel(struct evdev_input_device *device)
125 if (ioctl(device->fd, EVIOCGID, &id) < 0)
126 return TOUCHPAD_MODEL_UNKNOWN;
128 for (i = 0; i < sizeof(touchpad_spec_table); ++i)
130 if (touchpad_spec_table[i].vendor == id.vendor &&
131 (!touchpad_spec_table[i].product ||
132 touchpad_spec_table[i].product == id.product))
134 return touchpad_spec_table[i].model;
138 return TOUCHPAD_MODEL_UNKNOWN;
142 configureTouchpadPressure(struct touchpad_dispatch *touchpad,
143 int32_t pressure_min, int32_t pressure_max)
145 int32_t range = pressure_max - pressure_min + 1;
146 touchpad->has_pressure = 1;
148 // Magic numbers from xf86-input-synaptics
149 switch (touchpad->model)
151 case TOUCHPAD_MODEL_ELANTECH:
152 touchpad->pressure.touch_low = pressure_min + 1;
153 touchpad->pressure.touch_high = pressure_min + 1;
156 touchpad->pressure.touch_low = pressure_min + range * (25.0 / 256.0);
157 touchpad->pressure.touch_high = pressure_min + range * (30.0 / 256.0);
161 touchpad->pressure.press = pressure_min + range;
165 touchpadProfile(struct motion_filter *filter, void *data,
166 double velocity, uint32_t time)
170 struct touchpad_dispatch *touchpad = (struct touchpad_dispatch*)data;
173 accel_factor = velocity * touchpad->constant_accel_factor;
175 if (accel_factor > touchpad->max_accel_factor)
176 accel_factor = touchpad->max_accel_factor;
177 else if (accel_factor < touchpad->min_accel_factor)
178 accel_factor = touchpad->min_accel_factor;
183 static motion_filter*
184 createPointerAccelatorFilter(accel_profile_func_t profile)
186 struct pointer_accelerator *filter;
188 filter = (struct pointer_accelerator*)malloc(sizeof(*filter));
192 filter->base.interface = &accelerator_interface;
193 wl_list_init(&filter->base.link);
195 filter->profile = profile;
196 filter->last_velocity = 0.0;
200 filter->trackers = (struct pointer_tracker*)
201 calloc(NUM_POINTER_TRACKERS, sizeof(*filter->trackers));
202 filter->cur_tracker = 0;
204 return &filter->base;
207 static evdev_dispatch*
208 createFallbackDispatch()
210 struct evdev_dispatch *dispatch =
211 (struct evdev_dispatch*)malloc(sizeof(*dispatch));
212 if (dispatch == NULL)
215 dispatch->interface = &fallback_interface;
220 ////////////////////////////////////////////////////////////////////////
223 processTouch(struct evdev_input_device *device, struct input_event *e,
224 int screen_width, int screen_height)
229 device->mt.slot = e->value;
231 case ABS_MT_TRACKING_ID:
233 device->pending_events |= EVDEV_ABSOLUTE_MT_DOWN;
235 device->pending_events |= EVDEV_ABSOLUTE_MT_UP;
237 case ABS_MT_POSITION_X:
238 device->mt.x[device->mt.slot] =
239 (e->value - device->abs.min_x) * screen_width /
240 (device->abs.max_x - device->abs.min_x) +
241 0; //device->output->x;
242 device->pending_events |= EVDEV_ABSOLUTE_MT_MOTION;
244 case ABS_MT_POSITION_Y:
245 device->mt.y[device->mt.slot] =
246 (e->value - device->abs.min_y) * screen_height /
247 (device->abs.max_y - device->abs.min_y) +
248 0; //device->output->y;
249 device->pending_events |= EVDEV_ABSOLUTE_MT_MOTION;
255 processAbsoluteMotion(struct evdev_input_device *device, struct input_event *e,
256 int screen_width, int screen_height)
262 (e->value - device->abs.min_x) * screen_width /
263 (device->abs.max_x - device->abs.min_x) +
264 0; //device->output->x;
265 device->pending_events |= EVDEV_ABSOLUTE_MOTION;
269 (e->value - device->abs.min_y) * screen_height /
270 (device->abs.max_y - device->abs.min_y) +
271 0; //device->output->y;
272 device->abs.x = screen_width - device->abs.x;
273 device->pending_events |= EVDEV_ABSOLUTE_MOTION;
275 // The following is the effective code only from a specific model
278 device->abs.y = (e->value - device->abs.min_x) * screen_height /
279 (device->abs.max_x - device->abs.min_x);
280 device->pending_events |= EVDEV_ABSOLUTE_MOTION;
283 device->abs.x = (e->value - device->abs.min_y) * screen_width /
284 (device->abs.max_y - device->abs.min_y);
285 device->abs.x = screen_width - device->abs.x;
286 device->pending_events |= EVDEV_ABSOLUTE_MOTION;
292 ////////////////////////////////////////////////////////////////////////
295 hysteresis(int in, int center, int margin)
297 int diff = in - center;
298 if (abs(diff) <= margin)
302 return center + diff - margin;
303 else if (diff < -margin)
304 return center + diff + margin;
305 return center + diff;
308 static inline struct touchpad_motion*
309 motionHistoryOffset(struct touchpad_dispatch *touchpad, int offset)
312 (touchpad->motion_index - offset + TOUCHPAD_HISTORY_LENGTH) %
313 TOUCHPAD_HISTORY_LENGTH;
315 return &touchpad->motion_history[offsetIndex];
319 estimateDelta(int x0, int x1, int x2, int x3)
321 return (x0 + x1 - x2 - x3) / 4;
325 touchpadGetDelta(struct touchpad_dispatch *touchpad, double *dx, double *dy)
327 *dx = estimateDelta(motionHistoryOffset(touchpad, 0)->x,
328 motionHistoryOffset(touchpad, 1)->x,
329 motionHistoryOffset(touchpad, 2)->x,
330 motionHistoryOffset(touchpad, 3)->x);
331 *dy = estimateDelta(motionHistoryOffset(touchpad, 0)->y,
332 motionHistoryOffset(touchpad, 1)->y,
333 motionHistoryOffset(touchpad, 2)->y,
334 motionHistoryOffset(touchpad, 3)->y);
338 filterDispatch(struct motion_filter *filter, struct motion_params *motion,
339 void *data, uint32_t time)
341 filter->interface->filter(filter, motion, data, time);
345 filterMotion(struct touchpad_dispatch *touchpad,
346 double *dx, double *dy, uint32_t time)
348 struct motion_filter *filter;
349 struct motion_params motion;
354 wl_list_for_each(filter, &touchpad->motion_filters, link)
356 filterDispatch(filter, &motion, touchpad, time);
364 getDirection(int dx, int dy)
366 int dir = UNDEFINED_DIRECTION;
371 if (abs(dx) < 2 && abs(dy) < 2)
373 if (dx > 0 && dy > 0)
375 else if (dx > 0 && dy < 0)
377 else if (dx < 0 && dy > 0)
379 else if (dx < 0 && dy < 0)
392 // Calculate r within the interval [0 to 8)
394 // r = [0 .. 2Ï€] where 0 is North
395 // d_f = r / 2Ï€ ([0 .. 1))
399 r = fmod(r + 2.5*M_PI, 2*M_PI);
402 // Mark one or two close enough octants
403 d1 = (int)(r + 0.9) % 8;
404 d2 = (int)(r + 0.1) % 8;
406 dir = (1 << d1) | (1 << d2);
413 feedTrackers(struct pointer_accelerator *accel,
414 double dx, double dy, uint32_t time)
418 struct pointer_tracker *trackers = accel->trackers;
420 for (i = 0; i < NUM_POINTER_TRACKERS; ++i)
422 trackers[i].dx += dx;
423 trackers[i].dy += dy;
426 current = (accel->cur_tracker + 1) % NUM_POINTER_TRACKERS;
427 accel->cur_tracker = current;
429 trackers[current].dx = 0.0;
430 trackers[current].dy = 0.0;
431 trackers[current].time = time;
432 trackers[current].dir = getDirection(dx, dy);
435 static struct pointer_tracker*
436 trackerByOffset(struct pointer_accelerator *accel, unsigned int offset)
439 (accel->cur_tracker + NUM_POINTER_TRACKERS - offset)
440 % NUM_POINTER_TRACKERS;
441 return &accel->trackers[index];
445 calculateTrackerVelocity(struct pointer_tracker *tracker, uint32_t time)
453 distance = sqrt(dx*dx + dy*dy);
454 return distance / (double)(time - tracker->time);
458 calculateVelocity(struct pointer_accelerator *accel, uint32_t time)
460 struct pointer_tracker *tracker;
463 double initial_velocity;
464 double velocity_diff;
467 unsigned int dir = trackerByOffset(accel, 0)->dir;
469 // Find first velocity
470 for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++)
472 tracker = trackerByOffset(accel, offset);
474 if (time <= tracker->time)
477 result = initial_velocity =
478 calculateTrackerVelocity(tracker, time);
479 if (initial_velocity > 0.0)
483 // Find least recent vector within a timelimit, maximum velocity diff
484 // and direction threshold.
485 for (; offset < NUM_POINTER_TRACKERS; offset++)
487 tracker = trackerByOffset(accel, offset);
489 // Stop if too far away in time
490 if (time - tracker->time > MOTION_TIMEOUT ||
491 tracker->time > time)
494 // Stop if direction changed
499 velocity = calculateTrackerVelocity(tracker, time);
501 // Stop if velocity differs too much from initial
502 velocity_diff = fabs(initial_velocity - velocity);
503 if (velocity_diff > MAX_VELOCITY_DIFF)
513 accelerationProfile(struct pointer_accelerator *accel,
514 void *data, double velocity, uint32_t time)
516 return accel->profile(&accel->base, data, velocity, time);
520 calculateAcceleration(struct pointer_accelerator *accel,
521 void *data, double velocity, uint32_t time)
525 factor = accelerationProfile(accel, data, velocity, time);
526 factor += accelerationProfile(accel, data, accel->last_velocity, time);
528 accelerationProfile(accel, data,
529 (accel->last_velocity + velocity) / 2,
531 factor = factor / 6.0;
536 softenDelta(double lastDelta, double delta)
538 if (delta < -1.0 || delta > 1.0)
540 if (delta > lastDelta)
542 else if (delta < lastDelta)
549 applySoftening(struct pointer_accelerator *accel,
550 struct motion_params *motion)
552 motion->dx = softenDelta(accel->last_dx, motion->dx);
553 motion->dy = softenDelta(accel->last_dy, motion->dy);
557 acceleratorFilter(struct motion_filter *filter, struct motion_params *motion,
558 void *data, uint32_t time)
560 struct pointer_accelerator *accel = (struct pointer_accelerator*)filter;
564 feedTrackers(accel, motion->dx, motion->dy, time);
565 velocity = calculateVelocity(accel, time);
566 accel_value = calculateAcceleration(accel, data, velocity, time);
568 motion->dx = accel_value * motion->dx;
569 motion->dy = accel_value * motion->dy;
571 applySoftening(accel, motion);
573 accel->last_dx = motion->dx;
574 accel->last_dy = motion->dy;
576 accel->last_velocity = velocity;
580 acceleratorDestroy(struct motion_filter *filter)
582 struct pointer_accelerator *accel = (struct pointer_accelerator*)filter;
584 free(accel->trackers);
588 /// WaylandEvdevInputEvent /////////////////////////////////////////////////
590 WaylandEvdevInputEvent::WaylandEvdevInputEvent(WaylandBaseWindowSystem* windowSystem)
591 : WaylandInputEvent(windowSystem)
596 wl_list_init(&m_deviceList);
599 WaylandEvdevInputEvent::~WaylandEvdevInputEvent()
606 struct evdev_input_device *device, *next;
608 wl_list_for_each_safe(device, next, &m_deviceList, link)
610 removeDevice(device);
615 WaylandEvdevInputEvent::removeDevice(struct evdev_input_device *device)
617 struct evdev_dispatch *dispatch = device->dispatch;
620 dispatch->interface->destroy(dispatch);
622 wl_event_source_remove(device->source);
623 wl_list_remove(&device->link);
625 mtdev_close_delete(device->mtdev);
627 free(device->devnode);
632 WaylandEvdevInputEvent::setupInputEvent()
634 LOG_INFO("WaylandEvdevInputEvent", "setupInputEvent IN");
636 WaylandInputEvent::setupInputEvent();
638 m_screenWidth = m_windowSystem->getWindowWidth();
639 m_screenHeight = m_windowSystem->getWindowHeight();
642 bool bRet = addDevices();
649 LOG_INFO("WaylandEvdevInputEvent", "setupInputEvent OUT");
653 WaylandEvdevInputEvent::addDevices()
659 LOG_ERROR("WaylandEvdevInputEvent", "Failed to initialize udev context");
663 struct udev_enumerate *e = udev_enumerate_new(m_udev);
664 udev_enumerate_add_match_subsystem(e, "input");
665 udev_enumerate_scan_devices(e);
667 struct udev_list_entry *entry;
668 const char *path, *sysname;
669 struct udev_device *device;
670 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e))
672 path = udev_list_entry_get_name(entry);
673 device = udev_device_new_from_syspath(m_udev, path);
675 sysname = udev_device_get_sysname(device);
676 if (strncmp("event", sysname, 5) != 0)
678 udev_device_unref(device);
683 udev_device_unref(device);
685 udev_enumerate_unref(e);
687 notifyKeyboardFocus();
689 if (wl_list_empty(&m_deviceList))
691 LOG_WARNING("WaylandEvdevInputEvent", "No input devices on entering service");
698 WaylandEvdevInputEvent::addDevice(struct udev_device *udevDevice)
701 const char *device_seat;
703 device_seat = udev_device_get_property_value(udevDevice, "ID_SEAT");
705 device_seat = default_seat;
707 devnode = udev_device_get_devnode(udevDevice);
708 createInputDevice(m_windowSystem->getNativeDisplayHandle(), devnode);
712 WaylandEvdevInputEvent::createInputDevice(struct wl_display *display, const char *path)
714 struct evdev_input_device *device;
715 struct wl_event_loop *eventLoop;
717 device = (struct evdev_input_device*)malloc(sizeof(*device));
723 device->master = this;
725 device->mtdev = NULL;
726 device->devnode = strdup(path);
727 device->mt.slot = -1;
730 device->dispatch = NULL;
732 device->fd = open(path, O_RDWR | O_NONBLOCK);
738 if (configureDevice(device) < 0)
743 // If the dispatch was not set up use the fallback
744 if (device->dispatch == NULL)
745 device->dispatch = createFallbackDispatch();
746 if (device->dispatch == NULL)
751 device->mtdev = mtdev_new_open(device->fd);
754 LOG_WARNING("WaylandEvdevInputEvent", "mtdev failed to open for " << path);
758 eventLoop = wl_display_get_event_loop(display);
759 device->source = wl_event_loop_add_fd(eventLoop, device->fd, WL_EVENT_READABLE,
760 WaylandEvdevInputEvent::handleInputEvent,
762 if (device->source == NULL)
767 wl_list_insert(m_deviceList.prev, &(device->link));
772 device->dispatch->interface->destroy(device->dispatch);
776 free(device->devnode);
782 WaylandEvdevInputEvent::configureDevice(struct evdev_input_device *device)
784 struct input_absinfo absinfo;
785 unsigned long ev_bits[NBITS(EV_MAX)];
786 unsigned long abs_bits[NBITS(ABS_MAX)];
787 unsigned long rel_bits[NBITS(ABS_MAX)];
788 unsigned long key_bits[NBITS(KEY_MAX)];
795 ioctl(device->fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits);
796 if (TEST_BIT(ev_bits, EV_ABS))
800 ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
801 if (TEST_BIT(abs_bits, ABS_X))
803 ioctl(device->fd, EVIOCGABS(ABS_X), &absinfo);
804 device->abs.min_x = absinfo.minimum;
805 device->abs.max_x = absinfo.maximum;
806 device->caps |= EVDEV_MOTION_ABS;
808 if (TEST_BIT(abs_bits, ABS_Y))
810 ioctl(device->fd, EVIOCGABS(ABS_Y), &absinfo);
811 device->abs.min_y = absinfo.minimum;
812 device->abs.max_y = absinfo.maximum;
813 device->caps |= EVDEV_MOTION_ABS;
815 if (TEST_BIT(abs_bits, ABS_MT_SLOT))
819 device->caps |= EVDEV_TOUCH;
822 if (TEST_BIT(ev_bits, EV_REL))
824 ioctl(device->fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), rel_bits);
825 if (TEST_BIT(rel_bits, REL_X) || TEST_BIT(rel_bits, REL_Y))
827 device->caps |= EVDEV_MOTION_REL;
830 if (TEST_BIT(ev_bits, EV_KEY))
833 ioctl(device->fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits);
834 if (TEST_BIT(key_bits, BTN_TOOL_FINGER) &&
835 !TEST_BIT(key_bits, BTN_TOOL_PEN) && hasAbs)
837 device->dispatch = createTouchpad(device);
840 for (i = KEY_ESC; i < KEY_MAX; ++i)
842 if (i >= BTN_MISC && i < KEY_OK)
844 if (TEST_BIT(key_bits, i))
846 device->caps |= EVDEV_KEYBOARD;
850 for (i = BTN_MISC; i < KEY_OK; ++i)
852 if (TEST_BIT(key_bits, i))
854 device->caps |= EVDEV_BUTTON;
859 if (TEST_BIT(ev_bits, EV_LED))
861 device->caps |= EVDEV_KEYBOARD;
864 // This rule tries to catch accelerometer devices and opt out. We may
865 // want to adjust the protocol later adding a proper event for dealing
866 // with accelerometers and implement here accordingly
867 if (hasAbs && !hasKey && !device->isMt)
871 fprintf(stdout, "DEVICE: [%s] information\n", device->devnode);
872 fprintf(stdout, " capabilities: EVDEV_KEYBOARD %s\n"
874 " EVDEV_MOTION_ABS %s\n"
875 " EVDEV_MOTION_REL %s\n"
877 (device->caps & EVDEV_KEYBOARD) ? "TRUE" : "FALSE",
878 (device->caps & EVDEV_BUTTON) ? "TRUE" : "FALSE",
879 (device->caps & EVDEV_MOTION_ABS) ? "TRUE" : "FALSE",
880 (device->caps & EVDEV_MOTION_REL) ? "TRUE" : "FALSE",
881 (device->caps & EVDEV_TOUCH) ? "TRUE" : "FALSE");
882 if (device->caps & EVDEV_MOTION_ABS)
884 fprintf(stdout, " abs: min_x(%4d), min_y(%4d)\n", device->abs.min_x, device->abs.min_y);
885 fprintf(stdout, " max_x(%4d), max_y(%4d)\n", device->abs.max_x, device->abs.max_y);
886 fprintf(stdout, " x(%4d), y(%4d)\n", device->abs.x, device->abs.y);
888 fprintf(stdout, "\n");
891 if ((device->caps & (EVDEV_MOTION_ABS | EVDEV_MOTION_REL | EVDEV_BUTTON)))
895 if ((device->caps & (EVDEV_KEYBOARD)))
897 initKeyboardDevice(NULL);
899 if ((device->caps & (EVDEV_TOUCH)))
908 WaylandEvdevInputEvent::notifyKeyboardFocus()
910 struct evdev_input_device *device;
911 struct wl_array keys;
912 char evdev_keys[(KEY_CNT + 7) / 8];
913 char all_keys[(KEY_CNT + 7) / 8];
918 memset(all_keys, 0, sizeof(all_keys));
919 wl_list_for_each(device, &m_deviceList, link)
921 memset(evdev_keys, 0, sizeof(evdev_keys));
922 ret = ioctl(device->fd, EVIOCGKEY(sizeof(evdev_keys)), evdev_keys);
925 LOG_WARNING("WaylandEvdevInputEvent", "Failed to get keys for device: " <<
929 for (i = 0; i < ARRAY_LENGTH(evdev_keys); ++i)
931 all_keys[i] |= evdev_keys[i];
935 wl_array_init(&keys);
936 for (i = 0; i < KEY_CNT; ++i)
938 set = all_keys[i >> 3] & (1 << (i & 7));
941 k = (uint32_t*)wl_array_add(&keys, sizeof(*k));
946 notifyKeyboardFocusIn(&keys, STATE_UPDATE_AUTOMATIC);
948 wl_array_release(&keys);
952 WaylandEvdevInputEvent::notifyKeyboardFocusIn(struct wl_array *keys,
953 enum key_state_update updateState)
955 struct wl_seat *wlSeat;
959 if ((wlSeat = m_inputDevice->seat()) == NULL)
963 if (!wlSeat->keyboard)
967 serial = wl_display_next_serial(m_inputDevice->display());
968 wl_array_init(&wlSeat->keyboard->keys);
969 wl_array_copy(&wlSeat->keyboard->keys, keys);
971 struct wl_array *array = &wlSeat->keyboard->keys;
972 for (k = (uint32_t*)array->data;
973 (const char*)k < (const char*)array->data + array->size;
976 if (updateState == STATE_UPDATE_AUTOMATIC)
978 updateModifierState(wlSeat, serial, *k, WL_KEYBOARD_KEY_STATE_PRESSED);
984 WaylandEvdevInputEvent::updateModifierState(struct wl_seat *wlSeat, uint32_t serial,
985 uint32_t key, enum wl_keyboard_key_state state)
987 enum xkb_key_direction direction;
989 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
990 direction = XKB_KEY_DOWN;
992 direction = XKB_KEY_UP;
994 // Offset the keycode by 8, as the evdev XKB rules reflect X's
995 // broken keycode system, which starts at 8.
996 xkb_state_update_key(m_xkbState.state, key + 8, direction);
998 notifyModifiers(wlSeat, serial);
1001 struct evdev_dispatch*
1002 WaylandEvdevInputEvent::createTouchpad(struct evdev_input_device *device)
1004 struct touchpad_dispatch *touchpad;
1006 touchpad = (struct touchpad_dispatch*)malloc(sizeof(*touchpad));
1007 if (touchpad == NULL)
1010 touchpad->base.interface = &touchpad_interface;
1012 touchpad->device = device;
1013 wl_list_init(&touchpad->motion_filters);
1015 configureTouchpad(touchpad, device);
1017 return &touchpad->base;
1021 WaylandEvdevInputEvent::configureTouchpad(struct touchpad_dispatch *touchpad,
1022 struct evdev_input_device *device)
1024 struct motion_filter *accel;
1026 struct input_absinfo absinfo;
1027 unsigned long abs_bits[NBITS(ABS_MAX)];
1034 touchpad->model = getTouchpadModel(device);
1036 // Configure pressure
1037 ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
1038 if (TEST_BIT(abs_bits, ABS_PRESSURE))
1040 ioctl(device->fd, EVIOCGABS(ABS_PRESSURE), &absinfo);
1041 configureTouchpadPressure(touchpad,
1046 // Configure acceleration factor
1047 width = abs(device->abs.max_x - device->abs.min_x);
1048 height = abs(device->abs.max_y - device->abs.min_y);
1049 diagonal = sqrt(width*width + height*height);
1051 touchpad->constant_accel_factor =
1052 DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
1054 touchpad->min_accel_factor = DEFAULT_MIN_ACCEL_FACTOR;
1055 touchpad->max_accel_factor = DEFAULT_MAX_ACCEL_FACTOR;
1057 touchpad->hysteresis.margin_x = diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
1058 touchpad->hysteresis.margin_y = diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
1059 touchpad->hysteresis.center_x = 0;
1060 touchpad->hysteresis.center_y = 0;
1062 // Configure acceleration profile
1063 accel = createPointerAccelatorFilter(touchpadProfile);
1064 wl_list_insert(&touchpad->motion_filters, &accel->link);
1066 // Setup initial state
1067 touchpad->reset = 1;
1069 memset(touchpad->motion_history, 0, sizeof touchpad->motion_history);
1070 touchpad->motion_index = 0;
1071 touchpad->motion_count = 0;
1073 touchpad->state = TOUCHPAD_STATE_NONE;
1074 touchpad->last_finger_state = 0;
1075 touchpad->finger_state = 0;
1079 WaylandEvdevInputEvent::handleInputEvent(int fd, uint32_t mask, void *data)
1083 struct evdev_input_device *device = (evdev_input_device*)data;
1084 struct input_event ev[32];
1089 len = mtdev_get(device->mtdev, fd, ev,
1090 ARRAY_LENGTH(ev)) * sizeof(struct input_event);
1094 len = read(fd, &ev, sizeof(ev));
1097 if (len < 0 || len % sizeof(ev[0]) != 0)
1102 WaylandEvdevInputEvent::processEvents(device, ev, len / sizeof(ev[0]));
1109 WaylandEvdevInputEvent::processEvents(struct evdev_input_device *device,
1110 struct input_event *ev,
1113 struct evdev_dispatch *dispatch = device->dispatch;
1114 struct input_event *e, *end;
1117 device->pending_events = 0;
1121 for (; e < end; ++e)
1123 time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
1125 if (!isMotionEvent(e))
1127 WaylandEvdevInputEvent::flushMotion(device, time);
1130 dispatch->interface->process(dispatch, device, e, time);
1133 WaylandEvdevInputEvent::flushMotion(device, time);
1137 WaylandEvdevInputEvent::flushMotion(struct evdev_input_device *device,
1140 if (!device->pending_events)
1143 WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1147 if (device->pending_events & EVDEV_RELATIVE_MOTION)
1149 struct wl_seat *wlSeat = inputEvent->inputDevice().seat();
1153 notifyMotion(device, time,
1154 wlSeat->pointer->x + device->rel.dx,
1155 wlSeat->pointer->y + device->rel.dy);
1157 device->pending_events &= ~EVDEV_RELATIVE_MOTION;
1161 if (device->pending_events & EVDEV_ABSOLUTE_MT_DOWN)
1164 notifyTouch(device);
1165 device->pending_events &= ~EVDEV_ABSOLUTE_MT_DOWN;
1166 device->pending_events &= ~EVDEV_ABSOLUTE_MT_MOTION;
1168 if (device->pending_events & EVDEV_ABSOLUTE_MT_MOTION)
1171 notifyTouch(device);
1172 device->pending_events &= ~EVDEV_ABSOLUTE_MT_DOWN;
1173 device->pending_events &= ~EVDEV_ABSOLUTE_MT_MOTION;
1175 if (device->pending_events & EVDEV_ABSOLUTE_MT_UP)
1178 notifyTouch(device);
1179 device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP;
1181 if (device->pending_events & EVDEV_ABSOLUTE_MOTION)
1184 notifyMotion(device, time,
1185 wl_fixed_from_int(device->abs.x),
1186 wl_fixed_from_int(device->abs.y));
1187 device->pending_events &= ~EVDEV_ABSOLUTE_MOTION;
1191 /// Default event handler //////////////////////////////////////////////////
1194 WaylandEvdevInputEvent::fallbackProcess(struct evdev_dispatch *dispatch,
1195 struct evdev_input_device *device,
1196 struct input_event *e,
1199 WL_UNUSED(dispatch);
1204 evdevProcessRelative(device, time, e);
1207 evdevProcessAbsolute(device, e);
1210 evdevProcessKey(device, time, e);
1216 WaylandEvdevInputEvent::fallbackDestroy(struct evdev_dispatch *dispatch)
1218 if (dispatch) free(dispatch);
1222 WaylandEvdevInputEvent::evdevProcessRelative(struct evdev_input_device *device,
1223 uint32_t /*time*/, struct input_event *e)
1228 device->rel.dx += wl_fixed_from_int(e->value);
1229 device->pending_events |= EVDEV_RELATIVE_MOTION;
1232 device->rel.dy += wl_fixed_from_int(e->value);
1233 device->pending_events |= EVDEV_RELATIVE_MOTION;
1243 WaylandEvdevInputEvent::evdevProcessAbsolute(struct evdev_input_device *device,
1244 struct input_event *e)
1246 WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1250 int w = inputEvent->m_screenWidth;
1251 int h = inputEvent->m_screenHeight;
1255 processTouch(device, e, w, h);
1259 processAbsoluteMotion(device, e, w, h);
1264 WaylandEvdevInputEvent::evdevProcessKey(struct evdev_input_device *device,
1265 uint32_t time, struct input_event *e)
1282 notifyButton(device, time, e->code,
1283 e->value ? WL_POINTER_BUTTON_STATE_PRESSED
1284 : WL_POINTER_BUTTON_STATE_RELEASED);
1288 notifyKey(device, time, e->code,
1289 e->value ? WL_KEYBOARD_KEY_STATE_PRESSED
1290 : WL_KEYBOARD_KEY_STATE_RELEASED,
1296 /// Multi-touch event handler //////////////////////////////////////////////
1299 WaylandEvdevInputEvent::touchpadProcess(struct evdev_dispatch *dispatch,
1300 struct evdev_input_device *device,
1301 struct input_event *e,
1304 struct touchpad_dispatch *touchpad = (struct touchpad_dispatch*)dispatch;
1309 if (e->code == SYN_REPORT)
1310 touchpad->event_mask |= TOUCHPAD_EVENT_REPORT;
1313 touchpadProcessAbsolute(touchpad, device, e);
1316 touchpadProcessKey(touchpad, device, e, time);
1320 touchpadUpdateState(touchpad, time);
1324 WaylandEvdevInputEvent::touchpadDestroy(struct evdev_dispatch *dispatch)
1326 struct touchpad_dispatch *touchpad = (struct touchpad_dispatch*)dispatch;
1327 struct motion_filter *filter;
1328 struct motion_filter *next;
1330 wl_list_for_each_safe(filter, next, &touchpad->motion_filters, link)
1332 filter->interface->destroy(filter);
1335 if (dispatch) free(dispatch);
1339 WaylandEvdevInputEvent::touchpadProcessAbsolute(struct touchpad_dispatch *touchpad,
1340 struct evdev_input_device *device,
1341 struct input_event *e)
1348 if (e->value > touchpad->pressure.press)
1349 touchpad->state = TOUCHPAD_STATE_PRESS;
1350 else if (e->value > touchpad->pressure.touch_high)
1351 touchpad->state = TOUCHPAD_STATE_TOUCH;
1352 else if (e->value < touchpad->pressure.touch_low)
1354 if (touchpad->state > TOUCHPAD_STATE_NONE)
1355 touchpad->reset = 1;
1356 touchpad->state = TOUCHPAD_STATE_NONE;
1360 if (touchpad->state >= TOUCHPAD_STATE_TOUCH)
1362 touchpad->hw_abs.x = e->value;
1363 touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
1364 touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_X;
1368 if (touchpad->state >= TOUCHPAD_STATE_TOUCH)
1370 touchpad->hw_abs.y = e->value;
1371 touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
1372 touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_Y;
1379 WaylandEvdevInputEvent::touchpadProcessKey(struct touchpad_dispatch *touchpad,
1380 struct evdev_input_device * device,
1381 struct input_event *e,
1387 if (!touchpad->has_pressure)
1391 touchpad->state = TOUCHPAD_STATE_NONE;
1392 touchpad->reset = 1;
1396 touchpad->state = e->value ? TOUCHPAD_STATE_TOUCH
1397 : TOUCHPAD_STATE_NONE;
1410 notifyButton(device, time, e->code,
1411 e->value ? WL_POINTER_BUTTON_STATE_PRESSED
1412 : WL_POINTER_BUTTON_STATE_RELEASED);
1415 case BTN_TOOL_RUBBER:
1416 case BTN_TOOL_BRUSH:
1417 case BTN_TOOL_PENCIL:
1418 case BTN_TOOL_AIRBRUSH:
1419 case BTN_TOOL_MOUSE:
1421 touchpad->reset = 1;
1423 case BTN_TOOL_FINGER:
1424 touchpad->finger_state =
1425 ~TOUCHPAD_FINGERS_ONE | e->value ? TOUCHPAD_FINGERS_ONE : 0;
1427 case BTN_TOOL_DOUBLETAP:
1428 touchpad->finger_state =
1429 ~TOUCHPAD_FINGERS_TWO | e->value ? TOUCHPAD_FINGERS_TWO : 0;
1431 case BTN_TOOL_TRIPLETAP:
1432 touchpad->finger_state =
1433 ~TOUCHPAD_FINGERS_THREE | e->value ? TOUCHPAD_FINGERS_THREE : 0;
1439 WaylandEvdevInputEvent::touchpadUpdateState(struct touchpad_dispatch *touchpad,
1448 if (touchpad->reset ||
1449 touchpad->last_finger_state != touchpad->finger_state)
1451 touchpad->reset = 0;
1452 touchpad->motion_count = 0;
1453 touchpad->event_mask = TOUCHPAD_EVENT_NONE;
1454 touchpad->event_mask_filter =
1455 TOUCHPAD_EVENT_ABSOLUTE_X | TOUCHPAD_EVENT_ABSOLUTE_Y;
1457 touchpad->last_finger_state = touchpad->finger_state;
1461 touchpad->last_finger_state = touchpad->finger_state;
1463 if (!(touchpad->event_mask & TOUCHPAD_EVENT_REPORT))
1466 touchpad->event_mask &= ~TOUCHPAD_EVENT_REPORT;
1468 if ((touchpad->event_mask & touchpad->event_mask_filter) !=
1469 touchpad->event_mask_filter)
1472 touchpad->event_mask_filter = TOUCHPAD_EVENT_ABSOLUTE_ANY;
1473 touchpad->event_mask = 0;
1475 // Avoid noice by moving center only when delta reaches a threshold
1476 // distance from the old center
1477 if (touchpad->motion_count > 0)
1479 center_x = hysteresis(touchpad->hw_abs.x,
1480 touchpad->hysteresis.center_x,
1481 touchpad->hysteresis.margin_x);
1482 center_y = hysteresis(touchpad->hw_abs.y,
1483 touchpad->hysteresis.center_y,
1484 touchpad->hysteresis.margin_y);
1488 center_x = touchpad->hw_abs.x;
1489 center_y = touchpad->hw_abs.y;
1491 touchpad->hysteresis.center_x = center_x;
1492 touchpad->hysteresis.center_y = center_y;
1493 touchpad->hw_abs.x = center_x;
1494 touchpad->hw_abs.y = center_y;
1496 // Update motion history tracker
1497 motion_index = (touchpad->motion_index + 1) % TOUCHPAD_HISTORY_LENGTH;
1498 touchpad->motion_index = motion_index;
1499 touchpad->motion_history[motion_index].x = touchpad->hw_abs.x;
1500 touchpad->motion_history[motion_index].y = touchpad->hw_abs.y;
1501 if (touchpad->motion_count < 4)
1502 touchpad->motion_count++;
1504 if (touchpad->motion_count >= 4)
1506 touchpadGetDelta(touchpad, &dx, &dy);
1508 filterMotion(touchpad, &dx, &dy, time);
1510 touchpad->device->rel.dx = wl_fixed_from_double(dx);
1511 touchpad->device->rel.dy = wl_fixed_from_double(dy);
1512 touchpad->device->pending_events |= EVDEV_RELATIVE_MOTION;
1516 /// Notifier ///////////////////////////////////////////////////////////////
1519 WaylandEvdevInputEvent::notifyButton(struct evdev_input_device *device,
1520 uint32_t time, int32_t button,
1521 enum wl_pointer_button_state state)
1524 struct wl_seat *wlSeat = NULL;
1527 WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1531 wlSeat = inputEvent->inputDevice().seat();
1532 serial = wl_display_next_serial(inputEvent->inputDevice().display());
1534 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
1536 if (wlSeat->pointer->button_count == 0)
1538 wlSeat->pointer->grab_button = button;
1539 wlSeat->pointer->grab_time = time;
1540 wlSeat->pointer->grab_x = wlSeat->pointer->x;
1541 wlSeat->pointer->grab_y = wlSeat->pointer->y;
1543 ++wlSeat->pointer->button_count;
1547 --wlSeat->pointer->button_count;
1549 wlEvent.x = wl_fixed_to_int(wlSeat->pointer->x);
1550 wlEvent.y = wl_fixed_to_int(wlSeat->pointer->y);
1551 wlEvent.buttonState = state;
1552 wlEvent.serial = serial;
1554 inputEvent->windowSystem().manageWLInputEvent(INPUT_DEVICE_POINTER,
1555 state == WL_POINTER_BUTTON_STATE_PRESSED ? INPUT_STATE_PRESSED :
1556 INPUT_STATE_RELEASED, &wlEvent);
1558 if (wlSeat->pointer->button_count == 1)
1560 wlSeat->pointer->grab_serial =
1561 wl_display_get_serial(inputEvent->inputDevice().display());
1566 WaylandEvdevInputEvent::notifyMotion(struct evdev_input_device *device,
1568 wl_fixed_t fx, wl_fixed_t fy)
1573 struct wl_seat *wlSeat = NULL;
1580 WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1584 wlSeat = inputEvent->inputDevice().seat();
1585 w = inputEvent->m_screenWidth;
1586 h = inputEvent->m_screenHeight;
1588 x = wl_fixed_to_int(fx);
1589 y = wl_fixed_to_int(fy);
1590 //old_x = wl_fixed_to_int(wlSeat->pointer->x);
1591 //old_y = wl_fixed_to_int(wlSeat->pointer->y);
1597 wlSeat->pointer->x = wl_fixed_from_int(x);
1598 wlSeat->pointer->y = wl_fixed_from_int(y);
1603 inputEvent->windowSystem().manageWLInputEvent(
1604 INPUT_DEVICE_POINTER, INPUT_STATE_MOTION, &wlEvent);
1608 WaylandEvdevInputEvent::notifyKey(struct evdev_input_device *device,
1609 uint32_t time, uint32_t key,
1610 enum wl_keyboard_key_state state,
1611 bool bUpdateAutomatic)
1613 WL_UNUSED(bUpdateAutomatic);
1616 struct wl_seat *wlSeat = NULL;
1620 WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1624 wlSeat = inputEvent->inputDevice().seat();
1625 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1627 wlSeat->keyboard->grab_key = key;
1628 wlSeat->keyboard->grab_time = time;
1631 end = (uint32_t*)(((unsigned char*)wlSeat->keyboard->keys.data) + wlSeat->keyboard->keys.size);
1632 for (k = (uint32_t*)wlSeat->keyboard->keys.data; k < end; ++k)
1636 // Ignore server-generated repeats
1637 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1642 wlSeat->keyboard->keys.size = end - (uint32_t*)wlSeat->keyboard->keys.data;
1643 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1645 k = (uint32_t*)wl_array_add(&wlSeat->keyboard->keys, sizeof(*k));
1649 wlEvent.keyCode = key;
1650 wlEvent.keyState = state;
1652 inputEvent->windowSystem().manageWLInputEvent(INPUT_DEVICE_KEYBOARD,
1653 state == WL_KEYBOARD_KEY_STATE_PRESSED ? INPUT_STATE_PRESSED
1654 : INPUT_STATE_RELEASED, &wlEvent);
1658 WaylandEvdevInputEvent::notifyTouch(struct evdev_input_device *device)
1661 InputEventState eventState = INPUT_STATE_OTHER;
1663 WaylandEvdevInputEvent *inputEvent = static_cast<WaylandEvdevInputEvent*>(device->master);
1667 if (device->pending_events & EVDEV_ABSOLUTE_MT_DOWN)
1669 wlEvent.x = (int)wl_fixed_from_int(device->mt.x[device->mt.slot]);
1670 wlEvent.y = (int)wl_fixed_from_int(device->mt.y[device->mt.slot]);
1671 wlEvent.touchId = device->mt.slot;
1672 wlEvent.touchType = WL_TOUCH_DOWN;
1673 eventState = INPUT_STATE_PRESSED;
1675 else if (device->pending_events & EVDEV_ABSOLUTE_MT_MOTION)
1677 wlEvent.x = (int)wl_fixed_from_int(device->mt.x[device->mt.slot]);
1678 wlEvent.y = (int)wl_fixed_from_int(device->mt.y[device->mt.slot]);
1679 wlEvent.touchId = device->mt.slot;
1680 wlEvent.touchType = WL_TOUCH_MOTION;
1681 eventState = INPUT_STATE_MOTION;
1683 else if (device->pending_events & EVDEV_ABSOLUTE_MT_UP)
1687 wlEvent.touchId = device->mt.slot;
1688 wlEvent.touchType = WL_TOUCH_UP;
1689 eventState = INPUT_STATE_RELEASED;
1696 inputEvent->windowSystem().manageWLInputEvent(INPUT_DEVICE_TOUCH, eventState, &wlEvent);
1700 WaylandEvdevInputEvent::notifyModifiers(struct wl_seat *wlSeat, uint32_t serial)
1702 uint32_t mods_depressed;
1703 uint32_t mods_latched;
1704 uint32_t mods_locked;
1706 uint32_t mods_lookup;
1709 mods_depressed = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_DEPRESSED);
1710 mods_latched = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_LATCHED);
1711 mods_locked = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_LOCKED);
1712 group = xkb_state_serialize_mods(m_xkbState.state, (xkb_state_component)XKB_STATE_EFFECTIVE);
1714 if (mods_depressed != wlSeat->keyboard->modifiers.mods_depressed ||
1715 mods_latched != wlSeat->keyboard->modifiers.mods_latched ||
1716 mods_locked != wlSeat->keyboard->modifiers.mods_locked ||
1717 group != wlSeat->keyboard->modifiers.group)
1722 wlSeat->keyboard->modifiers.mods_depressed = mods_depressed;
1723 wlSeat->keyboard->modifiers.mods_latched = mods_latched;
1724 wlSeat->keyboard->modifiers.mods_locked = mods_locked;
1725 wlSeat->keyboard->modifiers.group = group;
1727 // And update the modifier_state for bindings
1728 mods_lookup = mods_depressed | mods_latched;
1729 m_modifierState = 0;
1730 if (mods_lookup & (1 << m_xkbInfo.ctrl_mod)) m_modifierState |= MODIFIER_CTRL;
1731 if (mods_lookup & (1 << m_xkbInfo.alt_mod)) m_modifierState |= MODIFIER_ALT;
1732 if (mods_lookup & (1 << m_xkbInfo.super_mod)) m_modifierState |= MODIFIER_SUPER;
1733 if (mods_lookup & (1 << m_xkbInfo.shift_mod)) m_modifierState |= MODIFIER_SHIFT;
1737 m_inputDevice->sendModifiers(serial);