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 }