/src/backend/native/ftk_source_input.c

http://ftk.googlecode.com/ · C · 346 lines · 279 code · 32 blank · 35 comment · 37 complexity · 838819008c858a987a384aa24e1ce83a MD5 · raw file

  1. /*
  2. * File: ftk_source_input.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: source to handle /dev/input/xx
  5. *
  6. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  7. *
  8. * Licensed under the Academic Free License version 2.1
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. /*
  25. * History:
  26. * ================================================================
  27. * 2009-10-03 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "ftk_log.h"
  31. #include "ftk_globals.h"
  32. #include "ftk_key.h"
  33. #include "ftk_display.h"
  34. #include <linux/input.h>
  35. #include "ftk_source_input.h"
  36. #ifndef EV_SYN
  37. #define EV_SYN 0x00
  38. #endif
  39. typedef struct _PrivInfo
  40. {
  41. int fd;
  42. int x;
  43. int y;
  44. FtkEvent event;
  45. FtkOnEvent on_event;
  46. void* user_data;
  47. char filename[64];
  48. }PrivInfo;
  49. #include <linux/input.h>
  50. /*FIXME: complete the keymap table.*/
  51. static unsigned short s_key_map[0x100] =
  52. {
  53. [KEY_1] = FTK_KEY_1,
  54. [KEY_2] = FTK_KEY_2,
  55. [KEY_3] = FTK_KEY_3,
  56. [KEY_4] = FTK_KEY_4,
  57. [KEY_5] = FTK_KEY_5,
  58. [KEY_6] = FTK_KEY_6,
  59. [KEY_7] = FTK_KEY_7,
  60. [KEY_8] = FTK_KEY_8,
  61. [KEY_9] = FTK_KEY_9,
  62. [KEY_0] = FTK_KEY_0,
  63. [KEY_A] = FTK_KEY_a,
  64. [KEY_B] = FTK_KEY_b,
  65. [KEY_C] = FTK_KEY_c,
  66. [KEY_D] = FTK_KEY_d,
  67. [KEY_E] = FTK_KEY_e,
  68. [KEY_F] = FTK_KEY_f,
  69. [KEY_G] = FTK_KEY_g,
  70. [KEY_H] = FTK_KEY_h,
  71. [KEY_I] = FTK_KEY_i,
  72. [KEY_J] = FTK_KEY_j,
  73. [KEY_K] = FTK_KEY_k,
  74. [KEY_L] = FTK_KEY_l,
  75. [KEY_M] = FTK_KEY_m,
  76. [KEY_N] = FTK_KEY_n,
  77. [KEY_O] = FTK_KEY_o,
  78. [KEY_P] = FTK_KEY_p,
  79. [KEY_Q] = FTK_KEY_q,
  80. [KEY_R] = FTK_KEY_r,
  81. [KEY_S] = FTK_KEY_s,
  82. [KEY_T] = FTK_KEY_t,
  83. [KEY_U] = FTK_KEY_u,
  84. [KEY_V] = FTK_KEY_v,
  85. [KEY_W] = FTK_KEY_w,
  86. [KEY_X] = FTK_KEY_x,
  87. [KEY_Y] = FTK_KEY_y,
  88. [KEY_Z] = FTK_KEY_z,
  89. [KEY_RIGHTCTRL] = FTK_KEY_RIGHTCTRL,
  90. [KEY_RIGHTALT] = FTK_KEY_RIGHTALT,
  91. [KEY_HOME] = FTK_KEY_HOME,
  92. [KEY_UP] = FTK_KEY_UP,
  93. [KEY_PAGEUP] = FTK_KEY_PAGEUP,
  94. [KEY_LEFT] = FTK_KEY_LEFT,
  95. [KEY_RIGHT] = FTK_KEY_RIGHT,
  96. [KEY_END] = FTK_KEY_END,
  97. [KEY_DOWN] = FTK_KEY_DOWN,
  98. [KEY_PAGEDOWN] = FTK_KEY_PAGEDOWN,
  99. [KEY_INSERT] = FTK_KEY_INSERT,
  100. [KEY_DELETE] = FTK_KEY_DELETE,
  101. [KEY_F1] = FTK_KEY_F1,
  102. [KEY_F2] = FTK_KEY_F2,
  103. [KEY_F3] = FTK_KEY_F3,
  104. [KEY_F4] = FTK_KEY_F4,
  105. [KEY_F5] = FTK_KEY_F5,
  106. [KEY_F6] = FTK_KEY_F6,
  107. [KEY_F7] = FTK_KEY_F7,
  108. [KEY_F8] = FTK_KEY_F8,
  109. [KEY_F9] = FTK_KEY_F9,
  110. [KEY_F10] = FTK_KEY_F10,
  111. [KEY_COMMA] = FTK_KEY_COMMA,
  112. [KEY_DOT] = FTK_KEY_DOT,
  113. [KEY_SLASH] = FTK_KEY_SLASH,
  114. [KEY_RIGHTSHIFT] = FTK_KEY_RIGHTSHIFT,
  115. [KEY_LEFTALT] = FTK_KEY_LEFTALT,
  116. [KEY_SPACE] = FTK_KEY_SPACE,
  117. [KEY_CAPSLOCK] = FTK_KEY_CAPSLOCK,
  118. [KEY_SEMICOLON] = FTK_KEY_SEMICOLON,
  119. [KEY_LEFTSHIFT] = FTK_KEY_LEFTSHIFT,
  120. [KEY_BACKSLASH] = FTK_KEY_BACKSLASH,
  121. [KEY_LEFTBRACE] = FTK_KEY_LEFTBRACE,
  122. [KEY_RIGHTBRACE] = FTK_KEY_RIGHTBRACE,
  123. [KEY_ENTER] = FTK_KEY_ENTER,
  124. [KEY_LEFTCTRL] = FTK_KEY_LEFTCTRL,
  125. [KEY_MINUS] = FTK_KEY_MINUS,
  126. [KEY_EQUAL] = FTK_KEY_EQUAL,
  127. [KEY_BACKSPACE] = FTK_KEY_BACKSPACE,
  128. [KEY_TAB] = FTK_KEY_TAB,
  129. [KEY_ESC] = FTK_KEY_ESC,
  130. [139] = FTK_KEY_F2, /*map menu to f2*/
  131. // [KEY_SEND] = FTK_KEY_SEND,
  132. // [KEY_REPLY] = FTK_KEY_REPLY,
  133. // [KEY_SAVE] = FTK_KEY_SAVE,
  134. [KEY_POWER] = FTK_KEY_POWER
  135. };
  136. static int ftk_source_input_get_fd(FtkSource* thiz)
  137. {
  138. DECL_PRIV(thiz, priv);
  139. return priv->fd;
  140. }
  141. static int ftk_key_map(FtkSource* thiz, int key)
  142. {
  143. return s_key_map[key] != 0 ? s_key_map[key] : key;
  144. }
  145. static int ftk_source_input_check(FtkSource* thiz)
  146. {
  147. return -1;
  148. }
  149. static Ret ftk_source_input_dispatch(FtkSource* thiz)
  150. {
  151. int ret = 0;
  152. DECL_PRIV(thiz, priv);
  153. struct input_event ievent;
  154. return_val_if_fail(priv->fd > 0, RET_FAIL);
  155. ret = read(priv->fd, &ievent, sizeof(ievent));
  156. if(ret != sizeof(ievent))
  157. {
  158. ftk_logd("%s:%d read from %s failed(ret=%d, errno=%d)\n", __func__, __LINE__, priv->filename, ret, errno);
  159. }
  160. return_val_if_fail(ret == sizeof(ievent), RET_FAIL);
  161. switch(ievent.type)
  162. {
  163. case EV_KEY:
  164. {
  165. if(ievent.code == BTN_LEFT || ievent.code == BTN_RIGHT
  166. || ievent.code == BTN_MIDDLE || ievent.code == BTN_TOUCH)
  167. {
  168. priv->event.type = ievent.value ? FTK_EVT_MOUSE_DOWN : FTK_EVT_MOUSE_UP;
  169. }
  170. else
  171. {
  172. priv->event.type = ievent.value ? FTK_EVT_KEY_DOWN : FTK_EVT_KEY_UP;
  173. priv->event.u.key.code = ftk_key_map(thiz, ievent.code);
  174. if(priv->on_event != NULL && priv->event.type != FTK_EVT_NOP)
  175. {
  176. priv->on_event(priv->user_data, &priv->event);
  177. priv->event.type = FTK_EVT_NOP;
  178. }
  179. ftk_logd("%s: %02x --> %02x\n", __func__, ievent.code, priv->event.u.key.code);
  180. }
  181. break;
  182. }
  183. case EV_ABS:
  184. {
  185. switch(ievent.code)
  186. {
  187. case ABS_X:
  188. {
  189. priv->x = ievent.value;
  190. break;
  191. }
  192. case ABS_Y:
  193. {
  194. priv->y = ievent.value;
  195. break;
  196. }
  197. default:break;
  198. }
  199. if(priv->event.type == FTK_EVT_NOP)
  200. {
  201. priv->event.type = FTK_EVT_MOUSE_MOVE;
  202. }
  203. break;
  204. }
  205. case EV_REL:
  206. {
  207. switch(ievent.code)
  208. {
  209. case REL_X:
  210. {
  211. priv->x += ievent.value;
  212. break;
  213. }
  214. case REL_Y:
  215. {
  216. priv->y += ievent.value;
  217. break;
  218. }
  219. default:break;
  220. }
  221. if(priv->event.type == FTK_EVT_NOP)
  222. {
  223. priv->event.type = FTK_EVT_MOUSE_MOVE;
  224. }
  225. break;
  226. }
  227. case EV_SYN:
  228. {
  229. switch(priv->event.type)
  230. {
  231. case FTK_EVT_MOUSE_DOWN:
  232. case FTK_EVT_MOUSE_UP:
  233. case FTK_EVT_MOUSE_MOVE:
  234. {
  235. int max_x = ftk_display_width(ftk_default_display());
  236. int max_y = ftk_display_height(ftk_default_display());
  237. priv->x = priv->x > 0 ? priv->x : 0;
  238. priv->y = priv->y > 0 ? priv->y : 0;
  239. priv->x = priv->x < max_x ? priv->x : max_x;
  240. priv->y = priv->y < max_y ? priv->y : max_y;
  241. priv->event.u.mouse.x = priv->x;
  242. priv->event.u.mouse.y = priv->y;
  243. break;
  244. }
  245. default:break;
  246. }
  247. if(priv->on_event != NULL && priv->event.type != FTK_EVT_NOP)
  248. {
  249. priv->on_event(priv->user_data, &priv->event);
  250. priv->event.type = FTK_EVT_NOP;
  251. }
  252. break;
  253. }
  254. default:break;
  255. }
  256. return RET_OK;
  257. }
  258. static void ftk_source_input_destroy(FtkSource* thiz)
  259. {
  260. if(thiz != NULL)
  261. {
  262. DECL_PRIV(thiz, priv);
  263. close(priv->fd);
  264. FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
  265. }
  266. return;
  267. }
  268. FtkSource* ftk_source_input_create(const char* filename, FtkOnEvent on_event, void* user_data)
  269. {
  270. FtkSource* thiz = (FtkSource*)FTK_ZALLOC(sizeof(FtkSource) + sizeof(PrivInfo));
  271. if(thiz != NULL)
  272. {
  273. int grab = 0;
  274. char name[100] = {0};
  275. DECL_PRIV(thiz, priv);
  276. thiz->get_fd = ftk_source_input_get_fd;
  277. thiz->check = ftk_source_input_check;
  278. thiz->dispatch = ftk_source_input_dispatch;
  279. thiz->destroy = ftk_source_input_destroy;
  280. thiz->ref = 1;
  281. priv->fd = open(filename, O_RDONLY);
  282. ftk_strncpy(priv->filename, filename, sizeof(priv->filename));
  283. if(priv->fd < 0)
  284. {
  285. FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
  286. return NULL;
  287. }
  288. #ifdef PC_EMU
  289. /*use uinput only.*/
  290. if(ioctl(priv->fd, EVIOCGNAME(sizeof(name) - 1), &name) < 0 || name[0] != 'v')
  291. {
  292. close(priv->fd);
  293. priv->fd = -1;
  294. FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
  295. return NULL;
  296. }
  297. /*grab uinput to prevent event broadcasting*/
  298. if(ioctl(priv->fd, EVIOCGRAB, &grab) < 0)
  299. {
  300. close(priv->fd);
  301. priv->fd = -1;
  302. FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
  303. return NULL;
  304. }
  305. #else
  306. (void)name;
  307. (void)grab;
  308. #endif
  309. priv->on_event = on_event;
  310. priv->user_data = user_data;
  311. printf("%s: %d=%s priv->user_data=%p\n", __func__, priv->fd, filename, priv->user_data);
  312. }
  313. return thiz;
  314. }