Mercurial > MadButterfly
comparison src/X_supp.c @ 122:17e97e92b76e
Encapsulate X_MB_runtime_t and support X keyboard events.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Mon, 15 Sep 2008 20:33:06 +0800 |
parents | 5df7403b6fbc |
children | 6a8588df68af |
comparison
equal
deleted
inserted
replaced
121:76ba6fd61c7d | 122:17e97e92b76e |
---|---|
7 #include <cairo-xlib.h> | 7 #include <cairo-xlib.h> |
8 #include "redraw_man.h" | 8 #include "redraw_man.h" |
9 #include "mb_timer.h" | 9 #include "mb_timer.h" |
10 #include "X_supp.h" | 10 #include "X_supp.h" |
11 | 11 |
12 #define ERR -1 | |
13 #define OK 0 | |
14 | |
15 /*! \ingroup xkb | |
16 * @{ | |
17 */ | |
18 struct _X_kb_info { | |
19 int keycode_min, keycode_max; | |
20 int ksym_per_code; | |
21 KeySym *syms; | |
22 subject_t *kbevents; | |
23 ob_factory_t *ob_factory; | |
24 }; | |
25 | |
26 /* @} */ | |
27 | |
28 struct _X_MB_runtime { | |
29 Display *display; | |
30 Window win; | |
31 Visual *visual; | |
32 cairo_surface_t *surface, *backend_surface; | |
33 cairo_t *cr, *backend_cr; | |
34 redraw_man_t *rdman; | |
35 mb_tman_t *tman; | |
36 int w, h; | |
37 | |
38 X_kb_info_t kbinfo; | |
39 | |
40 /* States */ | |
41 shape_t *last; | |
42 }; | |
43 | |
44 /*! \defgroup xkb X Keyboard Handling | |
45 * | |
46 * Accept keyboard events from X server and delivery it to | |
47 * application through observer pattern. There is a subject, | |
48 * per X-connection, for that. | |
49 * @{ | |
50 */ | |
51 static int keycode2sym(X_kb_info_t *kbinfo, unsigned int keycode) { | |
52 int sym_idx; | |
53 int sym; | |
54 | |
55 sym_idx = kbinfo->ksym_per_code * (keycode - kbinfo->keycode_min); | |
56 sym = kbinfo->syms[sym_idx]; | |
57 return sym; | |
58 } | |
59 | |
60 static int X_kb_init(X_kb_info_t *kbinfo, Display *display, | |
61 redraw_man_t *rdman) { | |
62 int n_syms; | |
63 ob_factory_t *factory; | |
64 int r; | |
65 | |
66 r = XDisplayKeycodes(display, | |
67 &kbinfo->keycode_min, | |
68 &kbinfo->keycode_max); | |
69 if(r == 0) | |
70 return ERR; | |
71 | |
72 n_syms = kbinfo->keycode_max - kbinfo->keycode_min + 1; | |
73 kbinfo->syms = XGetKeyboardMapping(display, kbinfo->keycode_min, | |
74 n_syms, | |
75 &kbinfo->ksym_per_code); | |
76 if(kbinfo->syms == NULL) | |
77 return ERR; | |
78 | |
79 factory = rdman_get_ob_factory(rdman); | |
80 kbinfo->kbevents = subject_new(factory, kbinfo, OBJT_KB); | |
81 if(kbinfo->kbevents == NULL) | |
82 return ERR; | |
83 kbinfo->ob_factory = factory; | |
84 | |
85 return OK; | |
86 } | |
87 | |
88 static void X_kb_destroy(X_kb_info_t *kbinfo) { | |
89 subject_free(kbinfo->ob_factory, kbinfo->kbevents); | |
90 XFree(kbinfo->syms); | |
91 } | |
92 | |
93 /*! \brief Accept X keyboard events from handle_x_event() and dispatch it. | |
94 */ | |
95 static void X_kb_handle_event(X_kb_info_t *kbinfo, XKeyEvent *xkey) { | |
96 unsigned int code; | |
97 int sym; | |
98 X_kb_event_t event; | |
99 | |
100 code = xkey->keycode; | |
101 sym = keycode2sym(kbinfo, code); | |
102 if(xkey->type == KeyPress) | |
103 event.event.type = EVT_KB_PRESS; | |
104 else if(xkey->type == KeyRelease) | |
105 event.event.type = EVT_KB_RELEASE; | |
106 event.event.tgt = event.event.cur_tgt = kbinfo->kbevents; | |
107 event.keycode = code; | |
108 event.sym = sym; | |
109 | |
110 subject_notify(kbinfo->ob_factory, kbinfo->kbevents, &event.event); | |
111 } | |
112 | |
113 /* @} */ | |
12 | 114 |
13 static unsigned int get_button_state(unsigned int state) { | 115 static unsigned int get_button_state(unsigned int state) { |
14 unsigned int but = 0; | 116 unsigned int but = 0; |
15 | 117 |
16 if(state & Button1Mask) | 118 if(state & Button1Mask) |
70 redraw_man_t *rdman = rt->rdman; | 172 redraw_man_t *rdman = rt->rdman; |
71 XEvent evt; | 173 XEvent evt; |
72 XMotionEvent *mevt; | 174 XMotionEvent *mevt; |
73 XButtonEvent *bevt; | 175 XButtonEvent *bevt; |
74 XExposeEvent *eevt; | 176 XExposeEvent *eevt; |
177 XKeyEvent *xkey; | |
75 co_aix x, y, w, h; | 178 co_aix x, y, w, h; |
76 | 179 |
77 int eflag = 0; | 180 int eflag = 0; |
78 int ex1=0, ey1=0, ex2=0, ey2=0; | 181 int ex1=0, ey1=0, ex2=0, ey2=0; |
79 | 182 |
143 rt->last = NULL; | 246 rt->last = NULL; |
144 } | 247 } |
145 } | 248 } |
146 break; | 249 break; |
147 | 250 |
251 case KeyPress: | |
252 case KeyRelease: | |
253 xkey = &evt.xkey; | |
254 X_kb_handle_event(&rt->kbinfo, xkey); | |
255 break; | |
256 | |
148 case Expose: | 257 case Expose: |
149 eevt = &evt.xexpose; | 258 eevt = &evt.xexpose; |
150 x = eevt->x; | 259 x = eevt->x; |
151 y = eevt->y; | 260 y = eevt->y; |
152 w = eevt->width; | 261 w = eevt->width; |
271 XCloseDisplay(display); | 380 XCloseDisplay(display); |
272 return ERR; | 381 return ERR; |
273 } | 382 } |
274 | 383 |
275 XSelectInput(display, win, PointerMotionMask | ExposureMask | | 384 XSelectInput(display, win, PointerMotionMask | ExposureMask | |
276 ButtonPressMask | ButtonReleaseMask); | 385 ButtonPressMask | ButtonReleaseMask | |
386 KeyPressMask | KeyReleaseMask); | |
277 XFlush(display); | 387 XFlush(display); |
278 | 388 |
279 *displayp = display; | 389 *displayp = display; |
280 *visualp = visual; | 390 *visualp = visual; |
281 *winp = win; | 391 *winp = win; |
286 /*! \brief Initialize a MadButterfy runtime for Xlib. | 396 /*! \brief Initialize a MadButterfy runtime for Xlib. |
287 * | 397 * |
288 * It setups a runtime environment to run MadButterfly with Xlib. | 398 * It setups a runtime environment to run MadButterfly with Xlib. |
289 * Users should specify width and height of the opening window. | 399 * Users should specify width and height of the opening window. |
290 */ | 400 */ |
291 int X_MB_init(const char *display_name, | 401 static int X_MB_init(const char *display_name, |
292 int w, int h, X_MB_runtime_t *xmb_rt) { | 402 int w, int h, X_MB_runtime_t *xmb_rt) { |
293 memset(xmb_rt, 0, sizeof(X_MB_runtime_t)); | 403 memset(xmb_rt, 0, sizeof(X_MB_runtime_t)); |
294 | 404 |
295 xmb_rt->w = w; | 405 xmb_rt->w = w; |
296 xmb_rt->h = h; | 406 xmb_rt->h = h; |
316 | 426 |
317 xmb_rt->tman = mb_tman_new(); | 427 xmb_rt->tman = mb_tman_new(); |
318 | 428 |
319 xmb_rt->last = NULL; | 429 xmb_rt->last = NULL; |
320 | 430 |
431 X_kb_init(&xmb_rt->kbinfo, xmb_rt->display, xmb_rt->rdman); | |
432 | |
321 return OK; | 433 return OK; |
322 } | 434 } |
323 | 435 |
324 void X_MB_destroy(X_MB_runtime_t *xmb_rt) { | 436 static void X_MB_destroy(X_MB_runtime_t *xmb_rt) { |
325 if(xmb_rt->rdman) { | 437 if(xmb_rt->rdman) { |
326 redraw_man_destroy(xmb_rt->rdman); | 438 redraw_man_destroy(xmb_rt->rdman); |
327 free(xmb_rt->rdman); | 439 free(xmb_rt->rdman); |
328 } | 440 } |
329 | 441 |
340 if(xmb_rt->backend_surface) | 452 if(xmb_rt->backend_surface) |
341 cairo_surface_destroy(xmb_rt->backend_surface); | 453 cairo_surface_destroy(xmb_rt->backend_surface); |
342 | 454 |
343 if(xmb_rt->display) | 455 if(xmb_rt->display) |
344 XCloseDisplay(xmb_rt->display); | 456 XCloseDisplay(xmb_rt->display); |
345 } | 457 |
346 | 458 X_kb_destroy(&xmb_rt->kbinfo); |
459 } | |
460 | |
461 X_MB_runtime_t *X_MB_new(const char *display_name, int w, int h) { | |
462 X_MB_runtime_t *rt; | |
463 int r; | |
464 | |
465 rt = O_ALLOC(X_MB_runtime_t); | |
466 if(rt == NULL) | |
467 return NULL; | |
468 | |
469 r = X_MB_init(display_name, w, h, rt); | |
470 if(r != OK) | |
471 return NULL; | |
472 | |
473 return rt; | |
474 } | |
475 | |
476 void X_MB_free(X_MB_runtime_t *rt) { | |
477 X_MB_destroy(rt); | |
478 free(rt); | |
479 } | |
480 | |
481 subject_t *X_MB_kbevents(X_MB_runtime_t *xmb_rt) { | |
482 return xmb_rt->kbinfo.kbevents; | |
483 } | |
484 | |
485 redraw_man_t *X_MB_rdman(X_MB_runtime_t *xmb_rt) { | |
486 return xmb_rt->rdman; | |
487 } | |
488 | |
489 mb_tman_t *X_MB_tman(X_MB_runtime_t *xmb_rt) { | |
490 return xmb_rt->tman; | |
491 } |