6 #include "ecore_fb_private.h"
8 #define CLICK_THRESHOLD_DEFAULT 0.25
10 static Eina_List *_ecore_fb_li_devices = NULL;
12 static const char *_ecore_fb_li_kbd_syms[128 * 6] =
14 #include "ecore_fb_keytable.h"
17 /* Initial Copyright (C) Brad Hards (1999-2002),
18 * this function is used to tell if "bit" is set in "array"
19 * it selects a byte from the array, and does a boolean AND
20 * operation with a byte that only has the relevant bit set.
21 * eg. to check for the 12th bit, we do (array[1] & 1<<4).
22 * Moved to static inline in order to force compiler to otimized
23 * the unsued part away or force a link error if long has an unexpected
27 extern int long_has_neither_32_nor_64_bits(void);
29 test_bit(int bit, unsigned long *array)
31 if (sizeof(long) == 4)
32 return array[bit / 32] & (1 << (bit % 32));
33 else if (sizeof(long) == 8)
34 return array[bit / 64] & (1 << (bit % 64));
35 else long_has_neither_32_nor_64_bits();
39 _ecore_fb_li_event_free_key_down(void *data __UNUSED__, void *ev)
41 Ecore_Fb_Event_Key_Up *e;
45 if (e->keysymbol) free(e->keysymbol);
46 if (e->key_compose) free(e->key_compose);
51 _ecore_fb_li_event_free_key_up(void *data __UNUSED__, void *ev)
53 Ecore_Fb_Event_Key_Up *e;
57 if (e->keysymbol) free(e->keysymbol);
58 if (e->key_compose) free(e->key_compose);
63 _ecore_fb_li_device_event_key(Ecore_Fb_Input_Device *dev, struct input_event *iev)
65 if (!dev->listen) return;
67 /* check for basic keyboard keys */
68 if ((iev->code >= KEY_ESC) && (iev->code <= KEY_COMPOSE))
70 /* check the key table */
74 Ecore_Fb_Event_Key_Down *ev;
76 ev = calloc(1, sizeof(Ecore_Fb_Event_Key_Down));
77 if (dev->keyboard.shift) offset = 1;
78 else if (dev->keyboard.lock) offset = 2;
79 ev->keyname = strdup(_ecore_fb_li_kbd_syms[iev->code * 6]);
81 ev->keysymbol = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + offset]);
82 ev->key_compose = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + 3 + offset]);
84 ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, ev, _ecore_fb_li_event_free_key_down, NULL);
85 /* its a repeated key, dont increment */
88 if (!strcmp(ev->keyname, "Control_L"))
90 else if (!strcmp(ev->keyname, "Control_R"))
92 else if (!strcmp(ev->keyname, "Alt_L"))
94 else if (!strcmp(ev->keyname, "Alt_R"))
96 else if (!strcmp(ev->keyname, "Shift_L"))
97 dev->keyboard.shift++;
98 else if (!strcmp(ev->keyname, "Shift_R"))
99 dev->keyboard.shift++;
100 else if (!strcmp(ev->keyname, "Caps_Lock"))
101 dev->keyboard.lock++;
102 if (dev->keyboard.ctrl > 2) dev->keyboard.ctrl = 2;
103 if (dev->keyboard.alt > 2) dev->keyboard.alt = 2;
104 if (dev->keyboard.shift > 2) dev->keyboard.shift = 2;
105 if (dev->keyboard.lock > 1) dev->keyboard.lock = 1;
110 Ecore_Fb_Event_Key_Up *ev;
112 ev = calloc(1, sizeof(Ecore_Fb_Event_Key_Up));
113 if (dev->keyboard.shift) offset = 1;
114 else if (dev->keyboard.lock) offset = 2;
115 ev->keyname = strdup(_ecore_fb_li_kbd_syms[iev->code * 6]);
117 ev->keysymbol = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + offset]);
118 ev->key_compose = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + 3 + offset]);
120 ecore_event_add(ECORE_FB_EVENT_KEY_UP, ev, _ecore_fb_li_event_free_key_up, NULL);
121 if (!strcmp(ev->keyname, "Control_L"))
122 dev->keyboard.ctrl--;
123 else if (!strcmp(ev->keyname, "Control_R"))
124 dev->keyboard.ctrl--;
125 else if (!strcmp(ev->keyname, "Alt_L"))
127 else if (!strcmp(ev->keyname, "Alt_R"))
129 else if (!strcmp(ev->keyname, "Shift_L"))
130 dev->keyboard.shift--;
131 else if (!strcmp(ev->keyname, "Shift_R"))
132 dev->keyboard.shift--;
133 else if (!strcmp(ev->keyname, "Caps_Lock"))
134 dev->keyboard.lock--;
135 if (dev->keyboard.ctrl < 0) dev->keyboard.ctrl = 0;
136 if (dev->keyboard.alt < 0) dev->keyboard.alt = 0;
137 if (dev->keyboard.shift < 0) dev->keyboard.shift = 0;
138 if (dev->keyboard.lock < 0) dev->keyboard.lock = 0;
141 /* check for mouse button events */
142 else if ((iev->code >= BTN_MOUSE) && (iev->code < BTN_JOYSTICK))
146 button = ((iev->code & 0x00F) + 1);
149 Ecore_Fb_Event_Mouse_Button_Down *ev;
152 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
155 ev->x = dev->mouse.x;
156 ev->y = dev->mouse.y;
158 current = ecore_time_get();
159 if ((current - dev->mouse.prev) <= dev->mouse.threshold)
160 ev->double_click = 1;
161 if ((current - dev->mouse.last) <= (2 * dev->mouse.threshold))
163 ev->triple_click = 1;
172 dev->mouse.last = dev->mouse.prev;
173 dev->mouse.prev = current;
175 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, ev, NULL ,NULL);
179 Ecore_Fb_Event_Mouse_Button_Up *ev;
181 ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Button_Up));
184 ev->x = dev->mouse.x;
185 ev->y = dev->mouse.y;
186 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, ev, NULL ,NULL);
192 _ecore_fb_li_device_event_rel(Ecore_Fb_Input_Device *dev, struct input_event *iev)
194 if (!dev->listen) return;
195 /* dispatch the button events if they are queued */
201 Ecore_Fb_Event_Mouse_Move *ev;
202 if(iev->code == REL_X)
204 dev->mouse.x += iev->value;
205 if(dev->mouse.x > dev->mouse.w - 1)
206 dev->mouse.x = dev->mouse.w;
207 else if(dev->mouse.x < 0)
212 dev->mouse.y += iev->value;
213 if(dev->mouse.y > dev->mouse.h - 1)
214 dev->mouse.y = dev->mouse.h;
215 else if(dev->mouse.y < 0)
218 ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Move));
219 ev->x = dev->mouse.x;
220 ev->y = dev->mouse.y;
223 ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE,ev,NULL,NULL);
229 Ecore_Fb_Event_Mouse_Wheel *ev;
230 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Wheel));
232 ev->x = dev->mouse.x;
233 ev->y = dev->mouse.y;
234 if (iev->code == REL_HWHEEL) ev->direction = 1;
235 ev->wheel = iev->value;
237 ecore_event_add(ECORE_FB_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
246 _ecore_fb_li_device_event_abs(Ecore_Fb_Input_Device *dev, struct input_event *iev)
248 static int prev_pressure = 0;
251 if (!dev->listen) return;
255 if (dev->mouse.w != 0)
259 tmp = (int)((double)(iev->value - dev->mouse.min_w) / dev->mouse.rel_w);
260 if (tmp < 0) dev->mouse.x = 0;
261 else if (tmp > dev->mouse.w) dev->mouse.x = dev->mouse.w;
262 else dev->mouse.x = tmp;
263 dev->mouse.event = ECORE_FB_EVENT_MOUSE_MOVE;
268 if(dev->mouse.h != 0)
272 tmp = (int)((double)(iev->value - dev->mouse.min_h) / dev->mouse.rel_h);
273 if (tmp < 0) dev->mouse.y = 0;
274 else if (tmp > dev->mouse.h) dev->mouse.y = dev->mouse.h;
275 else dev->mouse.y = tmp;
276 dev->mouse.event = ECORE_FB_EVENT_MOUSE_MOVE;
281 pressure = iev->value;
282 if ((pressure) && (!prev_pressure))
284 /* DOWN: mouse is down, but was not now */
285 dev->mouse.event = ECORE_FB_EVENT_MOUSE_BUTTON_DOWN;
287 else if ((!pressure) && (prev_pressure))
289 /* UP: mouse was down, but is not now */
290 dev->mouse.event = ECORE_FB_EVENT_MOUSE_BUTTON_UP;
292 prev_pressure = pressure;
298 _ecore_fb_li_device_event_syn(Ecore_Fb_Input_Device *dev, struct input_event *iev __UNUSED__)
300 if (!dev->listen) return;
302 if (dev->mouse.event == ECORE_FB_EVENT_MOUSE_MOVE)
304 Ecore_Fb_Event_Mouse_Move *ev;
305 ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Move));
306 ev->x = dev->mouse.x;
307 ev->y = dev->mouse.y;
309 ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, ev, NULL, NULL);
311 else if (dev->mouse.event == ECORE_FB_EVENT_MOUSE_BUTTON_DOWN)
313 Ecore_Fb_Event_Mouse_Button_Down *ev;
314 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
315 ev->x = dev->mouse.x;
316 ev->y = dev->mouse.y;
318 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
320 else if (dev->mouse.event == ECORE_FB_EVENT_MOUSE_BUTTON_UP)
322 Ecore_Fb_Event_Mouse_Button_Up *ev;
323 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
324 ev->x = dev->mouse.x;
325 ev->y = dev->mouse.y;
327 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
332 _ecore_fb_li_device_fd_callback(void *data, Ecore_Fd_Handler *fdh __UNUSED__)
334 Ecore_Fb_Input_Device *dev;
335 struct input_event ev[64];
339 dev = (Ecore_Fb_Input_Device*)data;
340 /* read up to 64 events at once */
341 len = read(dev->fd, &ev, sizeof(ev));
342 // printf("[ecore_fb_li_device:fd_callback] received %d data\n", len);
343 for(i = 0; i < (int)(len / sizeof(ev[0])); i++)
348 _ecore_fb_li_device_event_syn(dev, &ev[i]);
351 _ecore_fb_li_device_event_abs(dev, &ev[i]);
354 _ecore_fb_li_device_event_rel(dev, &ev[i]);
357 _ecore_fb_li_device_event_key(dev, &ev[i]);
367 * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions.
373 * @brief Set the listen mode for an input device .
375 * @param dev The device to set the mode of.
376 * @param listen EINA_FALSE to disable listening mode, EINA_TRUE to enable it.
378 * This function enables or disables listening on the input device @p
379 * dev. If @p listen is #EINA_FALSE, listening mode is disabled, if it
380 * is #EINA_TRUE, it is enabled.
383 ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, Eina_Bool listen)
386 if ((listen && dev->listen) || (!listen && !dev->listen)) return;
389 /* if the device already had a handler */
391 dev->handler = ecore_main_fd_handler_add(dev->fd, ECORE_FD_READ, _ecore_fb_li_device_fd_callback, dev, NULL, NULL);
394 dev->listen = listen;
398 # define EV_CNT (EV_MAX+1)
402 * @brief Open an input device.
404 * @param dev The device to open.
405 * @return The @ref Ecore_Fb_Input_Device object that has been opened.
407 * This function opens the input device named @p dev and returns the
408 * object for it, or returns @c NULL on failure.
410 EAPI Ecore_Fb_Input_Device *
411 ecore_fb_input_device_open(const char *dev)
413 Ecore_Fb_Input_Device *device;
414 unsigned long event_type_bitmask[EV_CNT / 32 + 1];
418 if (!dev) return NULL;
419 device = calloc(1, sizeof(Ecore_Fb_Input_Device));
420 if (!device) return NULL;
422 if ((fd = open(dev, O_RDONLY, O_NONBLOCK)) < 0)
424 fprintf(stderr, "[ecore_fb_li:device_open] %s %s", dev, strerror(errno));
427 /* query capabilities */
428 if (ioctl(fd, EVIOCGBIT(0, EV_MAX), event_type_bitmask) < 0)
430 fprintf(stderr,"[ecore_fb_li:device_open] query capabilities %s %s", dev, strerror(errno));
434 device->info.name = calloc(256, sizeof(char));
435 if (ioctl(fd, EVIOCGNAME(sizeof(char) * 256), device->info.name) < 0)
437 fprintf(stderr, "[ecore_fb_li:device_open] get name %s %s", dev, strerror(errno));
438 strcpy(device->info.name, "Unknown");
441 device->info.dev = strdup(dev);
443 device->mouse.threshold = CLICK_THRESHOLD_DEFAULT;
446 for (event_type = 0; event_type < EV_MAX; event_type++)
448 if(!test_bit(event_type, event_type_bitmask))
455 device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS;
458 device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_RELATIVE;
461 device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE;
474 _ecore_fb_li_devices = eina_list_append(_ecore_fb_li_devices, device);
485 * @brief Close the given device.
487 * @param dev The device to close
489 * This function closes the device @p dev. If @p dev is @c NULL, this
490 * function does nothing.
493 ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev)
495 if (!dev || dev->fd < 0) return;
498 /* remove the element from the list */
499 _ecore_fb_li_devices = eina_list_remove(_ecore_fb_li_devices, dev);
505 * @brief Set the axis size of the given device.
507 * @param dev The device to set the axis size to.
508 * @param w The width of the axis.
509 * @param h The height of the axis.
511 * This function sets set the width @p w and height @p h of the axis
512 * of device @p dev. If @p dev is a relative input device, a width and
513 * height must set for it. If its absolute set the ioctl correctly, if
514 * not, unsupported device.
517 ecore_fb_input_device_axis_size_set(Ecore_Fb_Input_Device *dev, int w, int h)
520 if ((w < 0) || (h < 0)) return;
522 * this code is for a touchscreen device,
523 * make it configurable (ABSOLUTE | RELATIVE)
525 if (dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE)
527 /* FIXME looks like some kernels dont include this struct */
528 struct input_absinfo abs_features;
530 ioctl(dev->fd, EVIOCGABS(ABS_X), &abs_features);
531 dev->mouse.min_w = abs_features.minimum;
532 dev->mouse.rel_w = (double)(abs_features.maximum - abs_features.minimum)/(double)(w);
534 ioctl(dev->fd, EVIOCGABS(ABS_Y), &abs_features);
535 dev->mouse.min_h = abs_features.minimum;
536 dev->mouse.rel_h = (double)(abs_features.maximum - abs_features.minimum)/(double)(h);
538 else if (!(dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE))
541 /* update the local values */
542 if (dev->mouse.x > w - 1) dev->mouse.x = w -1;
543 if (dev->mouse.y > h - 1) dev->mouse.y = h -1;
549 * @brief Retrieve the name of the given device.
551 * @param dev The device to get the name from.
552 * @return The name of the device.
554 * This function returns the name of the device @p dev. If @p dev is
555 * @c NULL, this function returns @c NULL.
558 ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev)
560 if (!dev) return NULL;
561 return dev->info.name;
565 * @brief Retrieve the capability of the given device.
567 * @param dev The device to get the name from.
568 * @return The capability of the device.
570 * This function returns the capability of the device @p dev. If @p dev is
571 * @c NULL, this function returns #ECORE_FB_INPUT_DEVICE_CAP_NONE.
573 EAPI Ecore_Fb_Input_Device_Cap
574 ecore_fb_input_device_cap_get(Ecore_Fb_Input_Device *dev)
576 if (!dev) return ECORE_FB_INPUT_DEVICE_CAP_NONE;
577 return dev->info.cap;
581 * @brief Set the threshold of mouse clicks of the given device.
583 * @param dev The device to set the threshodl mouse click to.
584 * @param threshold The threshold value.
586 * This function sets the threshold of mouse clicks of the device
587 * @p dev to @p threshold. If @p dev is @c NULL, this function does
591 ecore_fb_input_device_threshold_click_set(Ecore_Fb_Input_Device *dev, double threshold)
594 if ((threshold == dev->mouse.threshold) || (threshold == 0)) return;
595 dev->mouse.threshold = threshold;
599 * @brief Get the threshold of mouse clicks of the given device.
601 * @param dev The device to set the threshodl mouse click from.
602 * @return The threshold value.
604 * This function returns the threshold of mouse clicks of the device
605 * @p dev. If @p dev is @c NULL, this function returns 0.0.
608 ecore_fb_input_device_threshold_click_get(Ecore_Fb_Input_Device *dev)
611 return dev->mouse.threshold;