2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
10 #include "ecore_fb_private.h"
12 #define CLICK_THRESHOLD_DEFAULT 0.25
14 static Eina_List *_ecore_fb_li_devices = NULL;
16 static const char *_ecore_fb_li_kbd_syms[128 * 6] =
18 #include "ecore_fb_keytable.h"
21 /* Initial Copyright (C) Brad Hards (1999-2002),
22 * this function is used to tell if "bit" is set in "array"
23 * it selects a byte from the array, and does a boolean AND
24 * operation with a byte that only has the relevant bit set.
25 * eg. to check for the 12th bit, we do (array[1] & 1<<4).
26 * Moved to static inline in order to force compiler to otimized
27 * the unsued part away or force a link error if long has an unexpected
31 extern int long_has_neither_32_nor_64_bits(void);
32 static inline int test_bit(int bit, unsigned long *array)
34 if (sizeof(long) == 4)
35 return array[bit / 32] & (1 << (bit % 32));
37 else if (sizeof(long) == 8)
38 return array[bit / 64] & (1 << (bit % 64));
40 else long_has_neither_32_nor_64_bits();
44 _ecore_fb_li_event_free_key_down(void *data, void *ev)
47 Ecore_Fb_Event_Key_Up *e;
51 if (e->keysymbol) free(e->keysymbol);
52 if (e->key_compose) free(e->key_compose);
57 _ecore_fb_li_event_free_key_up(void *data, void *ev)
60 Ecore_Fb_Event_Key_Up *e;
64 if (e->keysymbol) free(e->keysymbol);
65 if (e->key_compose) free(e->key_compose);
70 _ecore_fb_li_device_event_key(Ecore_Fb_Input_Device *dev, struct input_event *iev)
75 /* check for basic keyboard keys */
76 if(iev->code >= KEY_ESC && iev->code <= KEY_COMPOSE)
78 /* check the key table */
82 Ecore_Fb_Event_Key_Down *ev;
84 ev = calloc(1, sizeof(Ecore_Fb_Event_Key_Down));
85 if(dev->keyboard.shift) offset = 1;
86 else if(dev->keyboard.lock) offset = 2;
87 ev->keyname = strdup(_ecore_fb_li_kbd_syms[iev->code * 6]);
89 ev->keysymbol = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + offset]);
90 ev->key_compose = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + 3 + offset]);
92 ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, ev, _ecore_fb_li_event_free_key_down, NULL);
93 /* its a repeated key, dont increment */
96 if (!strcmp(ev->keyname, "Control_L"))
98 else if (!strcmp(ev->keyname, "Control_R"))
100 else if (!strcmp(ev->keyname, "Alt_L"))
102 else if (!strcmp(ev->keyname, "Alt_R"))
104 else if (!strcmp(ev->keyname, "Shift_L"))
105 dev->keyboard.shift++;
106 else if (!strcmp(ev->keyname, "Shift_R"))
107 dev->keyboard.shift++;
108 else if (!strcmp(ev->keyname, "Caps_Lock"))
109 dev->keyboard.lock++;
110 if (dev->keyboard.ctrl > 2) dev->keyboard.ctrl = 2;
111 if (dev->keyboard.alt > 2) dev->keyboard.alt = 2;
112 if (dev->keyboard.shift > 2) dev->keyboard.shift = 2;
113 if (dev->keyboard.lock > 1) dev->keyboard.lock = 1;
118 Ecore_Fb_Event_Key_Up *ev;
120 ev = calloc(1, sizeof(Ecore_Fb_Event_Key_Up));
121 if(dev->keyboard.shift) offset = 1;
122 else if(dev->keyboard.lock) offset = 2;
123 ev->keyname = strdup(_ecore_fb_li_kbd_syms[iev->code * 6]);
125 ev->keysymbol = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + offset]);
126 ev->key_compose = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + 3 + offset]);
128 ecore_event_add(ECORE_FB_EVENT_KEY_UP, ev, _ecore_fb_li_event_free_key_up, NULL);
129 if (!strcmp(ev->keyname, "Control_L"))
130 dev->keyboard.ctrl--;
131 else if (!strcmp(ev->keyname, "Control_R"))
132 dev->keyboard.ctrl--;
133 else if (!strcmp(ev->keyname, "Alt_L"))
135 else if (!strcmp(ev->keyname, "Alt_R"))
137 else if (!strcmp(ev->keyname, "Shift_L"))
138 dev->keyboard.shift--;
139 else if (!strcmp(ev->keyname, "Shift_R"))
140 dev->keyboard.shift--;
141 else if (!strcmp(ev->keyname, "Caps_Lock"))
142 dev->keyboard.lock--;
143 if (dev->keyboard.ctrl < 0) dev->keyboard.ctrl = 0;
144 if (dev->keyboard.alt < 0) dev->keyboard.alt = 0;
145 if (dev->keyboard.shift < 0) dev->keyboard.shift = 0;
146 if (dev->keyboard.lock < 0) dev->keyboard.lock = 0;
149 /* check for mouse button events */
150 else if(iev->code >= BTN_MOUSE && iev->code < BTN_JOYSTICK)
154 button = ((iev->code & 0x00F) + 1);
157 Ecore_Fb_Event_Mouse_Button_Down *ev;
160 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
163 ev->x = dev->mouse.x;
164 ev->y = dev->mouse.y;
166 current = ecore_time_get();
167 if((current - dev->mouse.prev) <= dev->mouse.threshold)
169 ev->double_click = 1;
171 if((current - dev->mouse.last) <= (2 * dev->mouse.threshold))
173 ev->triple_click = 1;
182 dev->mouse.last = dev->mouse.prev;
183 dev->mouse.prev = current;
185 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, ev, NULL ,NULL);
189 Ecore_Fb_Event_Mouse_Button_Up *ev;
191 ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Button_Up));
194 ev->x = dev->mouse.x;
195 ev->y = dev->mouse.y;
197 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, ev, NULL ,NULL);
203 _ecore_fb_li_device_event_rel(Ecore_Fb_Input_Device *dev, struct input_event *iev)
207 /* dispatch the button events if they are queued */
213 Ecore_Fb_Event_Mouse_Move *ev;
214 if(iev->code == REL_X)
216 dev->mouse.x += iev->value;
217 if(dev->mouse.x > dev->mouse.w - 1)
218 dev->mouse.x = dev->mouse.w;
219 else if(dev->mouse.x < 0)
224 dev->mouse.y += iev->value;
225 if(dev->mouse.y > dev->mouse.h - 1)
226 dev->mouse.y = dev->mouse.h;
227 else if(dev->mouse.y < 0)
230 ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Move));
231 ev->x = dev->mouse.x;
232 ev->y = dev->mouse.y;
235 ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE,ev,NULL,NULL);
241 Ecore_Fb_Event_Mouse_Wheel *ev;
242 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Wheel));
244 ev->x = dev->mouse.x;
245 ev->y = dev->mouse.y;
246 if(iev->code == REL_HWHEEL)
248 ev->wheel = iev->value;
250 ecore_event_add(ECORE_FB_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
259 _ecore_fb_li_device_event_abs(Ecore_Fb_Input_Device *dev, struct input_event *iev)
261 static int prev_pressure = 0;
269 if(dev->mouse.w != 0)
273 tmp = (int)((double)(iev->value - dev->mouse.min_w) / dev->mouse.rel_w);
276 else if(tmp > dev->mouse.w)
277 dev->mouse.x = dev->mouse.w;
280 dev->mouse.event = ECORE_FB_EVENT_MOUSE_MOVE;
285 if(dev->mouse.h != 0)
289 tmp = (int)((double)(iev->value - dev->mouse.min_h) / dev->mouse.rel_h);
292 else if(tmp > dev->mouse.h)
293 dev->mouse.y = dev->mouse.h;
296 dev->mouse.event = ECORE_FB_EVENT_MOUSE_MOVE;
301 pressure = iev->value;
302 if ((pressure) && (!prev_pressure))
304 /* DOWN: mouse is down, but was not now */
305 dev->mouse.event = ECORE_FB_EVENT_MOUSE_BUTTON_DOWN;
307 else if ((!pressure) && (prev_pressure))
309 /* UP: mouse was down, but is not now */
310 dev->mouse.event = ECORE_FB_EVENT_MOUSE_BUTTON_UP;
312 prev_pressure = pressure;
318 _ecore_fb_li_device_event_syn(Ecore_Fb_Input_Device *dev, struct input_event *iev)
323 if(dev->mouse.event == ECORE_FB_EVENT_MOUSE_MOVE)
325 Ecore_Fb_Event_Mouse_Move *ev;
326 ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Move));
327 ev->x = dev->mouse.x;
328 ev->y = dev->mouse.y;
330 ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, ev, NULL, NULL);
332 else if(dev->mouse.event == ECORE_FB_EVENT_MOUSE_BUTTON_DOWN)
334 Ecore_Fb_Event_Mouse_Button_Down *ev;
335 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
336 ev->x = dev->mouse.x;
337 ev->y = dev->mouse.y;
339 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
341 else if(dev->mouse.event == ECORE_FB_EVENT_MOUSE_BUTTON_UP)
343 Ecore_Fb_Event_Mouse_Button_Up *ev;
344 ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
345 ev->x = dev->mouse.x;
346 ev->y = dev->mouse.y;
348 ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
353 _ecore_fb_li_device_fd_callback(void *data, Ecore_Fd_Handler *fdh)
355 Ecore_Fb_Input_Device *dev;
356 struct input_event ev[64];
360 dev = (Ecore_Fb_Input_Device*)data;
361 /* read up to 64 events at once */
362 len = read(dev->fd, &ev, sizeof(ev));
363 // printf("[ecore_fb_li_device:fd_callback] received %d data\n", len);
364 for(i = 0; i < len/sizeof(ev[0]); i++)
369 _ecore_fb_li_device_event_syn(dev, &ev[i]);
372 _ecore_fb_li_device_event_abs(dev, &ev[i]);
375 _ecore_fb_li_device_event_rel(dev, &ev[i]);
378 _ecore_fb_li_device_event_key(dev, &ev[i]);
388 * Starts getting events from the input device
392 ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, int listen)
395 if((listen && dev->listen) || (!listen && !dev->listen)) return;
398 /* if the device already had a handler */
400 dev->handler = ecore_main_fd_handler_add(dev->fd, ECORE_FD_READ, _ecore_fb_li_device_fd_callback, dev, NULL, NULL);
403 dev->listen = listen;
407 #define EV_CNT (EV_MAX+1)
411 * Opens an input device
413 EAPI Ecore_Fb_Input_Device *
414 ecore_fb_input_device_open(const char *dev)
416 Ecore_Fb_Input_Device *device;
417 unsigned long event_type_bitmask[EV_CNT / 32 + 1];
421 if(!dev) return NULL;
422 device = calloc(1, sizeof(Ecore_Fb_Input_Device));
423 if(!device) return NULL;
425 if((fd = open(dev, O_RDONLY, O_NONBLOCK)) < 0)
427 fprintf(stderr, "[ecore_fb_li:device_open] %s %s", dev, strerror(errno));
430 /* query capabilities */
431 if(ioctl(fd, EVIOCGBIT(0, EV_MAX), event_type_bitmask) < 0)
433 fprintf(stderr,"[ecore_fb_li:device_open] query capabilities %s %s", dev, strerror(errno));
437 device->info.name = calloc(256, sizeof(char));
438 if(ioctl(fd, EVIOCGNAME(sizeof(char) * 256), device->info.name) < 0)
440 fprintf(stderr, "[ecore_fb_li:device_open] get name %s %s", dev, strerror(errno));
441 strcpy(device->info.name, "Unknown");
444 device->info.dev = strdup(dev);
446 device->mouse.threshold = CLICK_THRESHOLD_DEFAULT;
449 for(event_type = 0; event_type < EV_MAX; event_type++)
451 if(!test_bit(event_type, event_type_bitmask))
459 device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS;
463 device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_RELATIVE;
467 device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE;
481 _ecore_fb_li_devices = eina_list_append(_ecore_fb_li_devices, device);
493 ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev)
497 /* remove the element from the list */
498 _ecore_fb_li_devices = eina_list_remove(_ecore_fb_li_devices, dev);
504 * If the device is a relative input device,
505 * we must set a width and height for it. If its
506 * absolute set the ioctl correctly, if not, unsupported
510 ecore_fb_input_device_axis_size_set(Ecore_Fb_Input_Device *dev, int w, int h)
517 * this code is for a touchscreen device,
518 * make it configurable (ABSOLUTE | RELATIVE)
520 if(dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE)
522 /* FIXME looks like some kernels dont include this struct */
523 struct input_absinfo abs_features;
525 ioctl(dev->fd, EVIOCGABS(ABS_X), &abs_features);
526 dev->mouse.min_w = abs_features.minimum;
527 dev->mouse.rel_w = (double)(abs_features.maximum - abs_features.minimum)/(double)(w);
529 ioctl(dev->fd, EVIOCGABS(ABS_Y), &abs_features);
530 dev->mouse.min_h = abs_features.minimum;
531 dev->mouse.rel_h = (double)(abs_features.maximum - abs_features.minimum)/(double)(h);
533 else if(!(dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE))
536 /* update the local values */
537 if(dev->mouse.x > w - 1)
539 if(dev->mouse.y > h - 1)
547 ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev)
551 return dev->info.name;
553 EAPI Ecore_Fb_Input_Device_Cap
554 ecore_fb_input_device_cap_get(Ecore_Fb_Input_Device *dev)
557 return ECORE_FB_INPUT_DEVICE_CAP_NONE;
558 return dev->info.cap;
561 ecore_fb_input_device_threshold_click_set(Ecore_Fb_Input_Device *dev, double threshold)
564 if(threshold == dev->mouse.threshold || threshold == 0) return;
565 dev->mouse.threshold = threshold;
568 ecore_fb_input_device_threshold_click_get(Ecore_Fb_Input_Device *dev)
571 return dev->mouse.threshold;