/src/backend/x11-emu/ftk_source_x11.c

http://ftk.googlecode.com/ · C · 285 lines · 226 code · 27 blank · 32 comment · 16 complexity · 4321b841b40a6b6bbddadc430fbd8270 MD5 · raw file

  1. /*
  2. * File: ftk_source_x11.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: x11 event handler
  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-06 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "ftk.h"
  31. #include "ftk_typedef.h"
  32. #include "ftk_key.h"
  33. #include "ftk_log.h"
  34. #include <X11/Xlib.h>
  35. #include <X11/keysym.h>
  36. #include "ftk_source_x11.h"
  37. #include "ftk_display_x11.h"
  38. typedef struct _PrivInfo
  39. {
  40. int fd;
  41. Window win;
  42. FtkEvent event;
  43. FtkDisplay* display;
  44. FtkOnEvent on_event;
  45. void* ctx;
  46. }PrivInfo;
  47. static int ftk_source_x11_get_fd(FtkSource* thiz)
  48. {
  49. DECL_PRIV(thiz, priv);
  50. return priv->fd;
  51. }
  52. static int ftk_source_x11_check(FtkSource* thiz)
  53. {
  54. return -1;
  55. }
  56. static const int s_key_map[] =
  57. {
  58. [0x0a] = FTK_KEY_1,
  59. [0x0b] = FTK_KEY_2,
  60. [0x0c] = FTK_KEY_3,
  61. [0x0d] = FTK_KEY_4,
  62. [0x0e] = FTK_KEY_5,
  63. [0x0f] = FTK_KEY_6,
  64. [0x10] = FTK_KEY_7,
  65. [0x11] = FTK_KEY_8,
  66. [0x12] = FTK_KEY_9,
  67. [0x13] = FTK_KEY_0,
  68. [0x14] = FTK_KEY_MINUS,
  69. [0x15] = FTK_KEY_EQUAL,
  70. [0x16] = FTK_KEY_BACKSPACE,
  71. [0x17] = FTK_KEY_TAB,
  72. [0x18] = FTK_KEY_q,
  73. [0x19] = FTK_KEY_w,
  74. [0x1a] = FTK_KEY_e,
  75. [0x1b] = FTK_KEY_r,
  76. [0x1c] = FTK_KEY_t,
  77. [0x1d] = FTK_KEY_y,
  78. [0x1e] = FTK_KEY_u,
  79. [0x1f] = FTK_KEY_i,
  80. [0x20] = FTK_KEY_o,
  81. [0x21] = FTK_KEY_p,
  82. [0x22] = FTK_KEY_BRACKETLEFT,
  83. [0x23] = FTK_KEY_BRACKETRIGHT,
  84. [0x24] = FTK_KEY_ENTER,
  85. [0x26] = FTK_KEY_a,
  86. [0x27] = FTK_KEY_s,
  87. [0x28] = FTK_KEY_d,
  88. [0x29] = FTK_KEY_f,
  89. [0x2a] = FTK_KEY_g,
  90. [0x2b] = FTK_KEY_h,
  91. [0x2c] = FTK_KEY_j,
  92. [0x2d] = FTK_KEY_k,
  93. [0x2e] = FTK_KEY_l,
  94. [0x2f] = FTK_KEY_SEMICOLON,
  95. [0x30] = FTK_KEY_QUOTERIGHT,
  96. [0x31] = FTK_KEY_GRAVE,
  97. [0x32] = FTK_KEY_LEFTSHIFT,
  98. [0x33] = FTK_KEY_BACKSLASH,
  99. [0x34] = FTK_KEY_z,
  100. [0x35] = FTK_KEY_x,
  101. [0x36] = FTK_KEY_c,
  102. [0x37] = FTK_KEY_v,
  103. [0x38] = FTK_KEY_b,
  104. [0x39] = FTK_KEY_n,
  105. [0x3a] = FTK_KEY_m,
  106. [0x3b] = FTK_KEY_COMMA,
  107. [0x3c] = FTK_KEY_DOT,
  108. [0x3d] = FTK_KEY_SLASH,
  109. [0x3e] = FTK_KEY_RIGHTSHIFT,
  110. [0x40] = FTK_KEY_LEFTALT,
  111. [0x41] = FTK_KEY_SPACE,
  112. [0x42] = FTK_KEY_CAPSLOCK,
  113. [0x43] = FTK_KEY_F1,
  114. [0x44] = FTK_KEY_F2,
  115. [0x45] = FTK_KEY_F3,
  116. [0x46] = FTK_KEY_F4,
  117. [0x47] = FTK_KEY_F5,
  118. [0x48] = FTK_KEY_F6,
  119. [0x49] = FTK_KEY_F7,
  120. [0x4a] = FTK_KEY_F8,
  121. [0x61] = FTK_KEY_HOME,
  122. [0x62] = FTK_KEY_UP,
  123. [0x63] = FTK_KEY_PAGEUP,
  124. [0x64] = FTK_KEY_LEFT,
  125. [0x66] = FTK_KEY_RIGHT,
  126. [0x67] = FTK_KEY_END,
  127. [0x68] = FTK_KEY_DOWN,
  128. [0x69] = FTK_KEY_PAGEDOWN,
  129. [0x6a] = FTK_KEY_INSERT,
  130. [0x6b] = FTK_KEY_DELETE,
  131. [0x6f] = FTK_KEY_UP,
  132. [0x71] = FTK_KEY_LEFT,
  133. [0x72] = FTK_KEY_RIGHT,
  134. [0x74] = FTK_KEY_DOWN,
  135. [0x77] = FTK_KEY_DELETE,
  136. // [0x71] = FTK_KEY_RIGHTALT,
  137. };
  138. static int ftk_source_x11_keymap(FtkSource* thiz, Display* display, int keycode)
  139. {
  140. ftk_logd("0x%03x --> 0x%03x %c\n", keycode, s_key_map[0xff&keycode], (char)s_key_map[0xff&keycode]);
  141. return s_key_map[0xff&keycode] ? s_key_map[0xff&keycode] : keycode;
  142. }
  143. static int on_x11_error (Display* display, XErrorEvent* event)
  144. {
  145. ftk_loge("%s\n", __func__);
  146. exit(0);
  147. return 0;
  148. }
  149. static Ret ftk_source_x11_dispatch(FtkSource* thiz)
  150. {
  151. XEvent event = {0};
  152. DECL_PRIV(thiz, priv);
  153. Display* display = (Display*)ftk_display_x11_get_xdisplay(priv->display);
  154. Atom* win_del_atom = (Atom*)ftk_display_x11_get_win_del_atom(priv->display);
  155. return_val_if_fail(priv->fd > 0, RET_FAIL);
  156. while(XPending (display))
  157. {
  158. XNextEvent(display, &event);
  159. switch(event.type)
  160. {
  161. case ConfigureNotify:
  162. {
  163. priv->event.type = FTK_EVT_DISPLAY_CHANGED;
  164. priv->event.u.display.width = event.xconfigure.width;
  165. priv->event.u.display.height = event.xconfigure.height;
  166. priv->event.u.display.display = thiz;
  167. ftk_display_x11_on_resize(priv->display, event.xconfigure.width, event.xconfigure.height);
  168. break;
  169. }
  170. case Expose:
  171. {
  172. ftk_display_update(priv->display, NULL, NULL, 0, 0);
  173. break;
  174. }
  175. case KeyPress:
  176. case KeyRelease:
  177. {
  178. priv->event.u.key.code = ftk_source_x11_keymap(thiz, display, event.xkey.keycode);
  179. priv->event.type = event.type == KeyPress ? FTK_EVT_KEY_DOWN : FTK_EVT_KEY_UP;
  180. break;
  181. }
  182. case ButtonPress:
  183. {
  184. //ftk_logd("%s: ButtonPress: %d %d\n", __func__, event.xbutton.x, event.xbutton.y);
  185. priv->event.type = FTK_EVT_MOUSE_DOWN;
  186. priv->event.u.mouse.x = event.xbutton.x;
  187. priv->event.u.mouse.y = event.xbutton.y;
  188. break;
  189. }
  190. case ButtonRelease:
  191. {
  192. //ftk_logd("%s: ButtonRelease: %d %d\n", __func__, event.xbutton.x, event.xbutton.y);
  193. priv->event.type = FTK_EVT_MOUSE_UP;
  194. priv->event.u.mouse.x = event.xbutton.x;
  195. priv->event.u.mouse.y = event.xbutton.y;
  196. break;
  197. }
  198. case MotionNotify:
  199. {
  200. priv->event.u.mouse.x = event.xbutton.x;
  201. priv->event.u.mouse.y = event.xbutton.y;
  202. priv->event.type = FTK_EVT_MOUSE_MOVE;
  203. break;
  204. }
  205. case DestroyNotify:
  206. {
  207. ftk_logd("%s: window destroied\n", __func__);
  208. break;
  209. }
  210. case ClientMessage:
  211. {
  212. if ((Atom)event.xclient.data.l[0] == *win_del_atom) {
  213. FTK_QUIT();
  214. }
  215. break;
  216. }
  217. default:break;
  218. }
  219. if(priv->on_event != NULL && priv->event.type != FTK_EVT_NOP)
  220. {
  221. priv->on_event(priv->ctx, &priv->event);
  222. priv->event.type = FTK_EVT_NOP;
  223. }
  224. }
  225. return RET_OK;
  226. }
  227. static void ftk_source_x11_destroy(FtkSource* thiz)
  228. {
  229. if(thiz != NULL)
  230. {
  231. DECL_PRIV(thiz, priv);
  232. close(priv->fd);
  233. FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
  234. }
  235. return;
  236. }
  237. FtkSource* ftk_source_x11_create(FtkDisplay* display, FtkOnEvent on_event, void* ctx)
  238. {
  239. FtkSource* thiz = NULL;
  240. return_val_if_fail(display != NULL && on_event != NULL, NULL);
  241. thiz = (FtkSource*)FTK_ZALLOC(sizeof(FtkSource) + sizeof(PrivInfo));
  242. if(thiz != NULL)
  243. {
  244. DECL_PRIV(thiz, priv);
  245. thiz->get_fd = ftk_source_x11_get_fd;
  246. thiz->check = ftk_source_x11_check;
  247. thiz->dispatch = ftk_source_x11_dispatch;
  248. thiz->destroy = ftk_source_x11_destroy;
  249. thiz->ref = 1;
  250. priv->ctx = ctx;
  251. priv->on_event = on_event;
  252. priv->display = display;
  253. priv->fd = ConnectionNumber(ftk_display_x11_get_xdisplay(display));
  254. priv->win = (Window)ftk_display_x11_get_xwindow(display);
  255. XSetErrorHandler(on_x11_error);
  256. }
  257. return thiz;
  258. }