xlib_ruby 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/x11.h ADDED
@@ -0,0 +1,76 @@
1
+ #ifndef X11_RUBY_H
2
+ #define X11_RUBY_H
3
+
4
+ #include <stdlib.h>
5
+ #include <stdio.h>
6
+ #include <unistd.h>
7
+ #include <string.h>
8
+ #include <X11/keysym.h>
9
+ #include <X11/Xatom.h>
10
+ #include <X11/Xlib.h>
11
+ #include <X11/Xproto.h>
12
+ #include <X11/Xutil.h>
13
+ #include <locale.h>
14
+
15
+ enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
16
+ enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
17
+
18
+ typedef struct Client_t Client;
19
+ typedef struct WM_t WM;
20
+
21
+ struct Client_t {
22
+ char name[256];
23
+ char class[256];
24
+ int x,y,w,h;
25
+ int rx,ry,rw,rh; //revert geo
26
+ int basew,baseh,incw,inch,maxw,maxh,minw,minh;
27
+ int minax,maxax,minay,maxay;
28
+ long flags;
29
+ unsigned int border, oldborder;
30
+ Bool isbanned, isfixed, ismax, isfloating, wasfloating;
31
+ WM *manager;
32
+ Window win;
33
+ };
34
+
35
+ typedef struct Key_t {
36
+ unsigned long mod;
37
+ KeySym keysym;
38
+ const char *arg;
39
+ void (*func)(const char *arg);
40
+ } Key;
41
+
42
+ struct WM_t {
43
+ int screen, sx, sy, sw, sh, wax, way, waw, wah;
44
+ Client *selected;
45
+ Client* order;
46
+ Display *dpy;
47
+ Window root;
48
+ Bool running;
49
+ Bool otherwm;
50
+ Bool manage_override_redirect_windows;
51
+ int (*xerrorxlib)(Display *, XErrorEvent *);
52
+ Atom wmatom[WMLast];
53
+ Atom netatom[NetLast];
54
+ unsigned int clients_num;
55
+ Client* clients;
56
+ };
57
+
58
+ int manageable_p(WM* wm, Window w);
59
+ void init_client(WM* wm, Window w, Client* c);
60
+ void manage_client(WM* wm, XWindowAttributes *wa, Client* c);
61
+ void resize(WM* winman, Client *c, int x, int y, int w, int h, int sizehints);
62
+ Client* query_clients(WM* winman);
63
+ void raise_client(Client* c);
64
+ void ban_client(Client* c);
65
+ void unban_client(Client* c);
66
+ void unborder_client(Client* c);
67
+ void border_client(Client* c, int w);
68
+ WM* Init_WM();
69
+ int event_pending(WM* winman);
70
+ int event_next_source(WM* winman);
71
+ char* event_next_type(WM* winman);
72
+ void event_pop(WM* winman);
73
+ void Destroy_WM(WM* winman);
74
+ Client* client_ftw(WM* wm, Window w);
75
+
76
+ #endif
data/ext/x11_wrap.c ADDED
@@ -0,0 +1,712 @@
1
+ #include <ruby.h>
2
+ #include <x11.h>
3
+
4
+ // Main module
5
+ VALUE mX11,
6
+
7
+ // Classes
8
+ cClient, cWM,
9
+ cEvent, cKeyEvent, cButtonEvent, cMotionEvent, cCrossingEvent, cFocusEvent,
10
+ cFocusChangeEvent, cCreateWindowEvent, cDestroyWindowEvent, cUnmapEvent, cMapRequestEvent,
11
+ cResizeRequestEvent, cConfigureRequestEvent;
12
+
13
+ #define numKeyMasks 13
14
+
15
+ // Symbols
16
+ static ID id_client, id_x, id_y, id_button, id_keycode, id_keysym, id_state, id_mods,
17
+ id_keymasks[numKeyMasks];
18
+ // id_Button1,id_Button2,id_Button3,id_Button4,id_Button5,
19
+ // id_Shift,id_Lock,id_Control,
20
+ // id_Mod1,id_Mod2,id_Mod3,id_Mod4,id_Mod5;
21
+
22
+ static VALUE client_make(VALUE klass, Client* c); // I need this alot
23
+ static VALUE event_wrap(VALUE klass, XEvent* ev);
24
+
25
+
26
+ static VALUE x11_error_handler(VALUE self) {
27
+ return rb_iv_get(mX11,"error_handler");
28
+ }
29
+
30
+ static VALUE x11_error_handler_set(VALUE self, VALUE proc) {
31
+ if (!(NIL_P(proc) || RTEST(rb_respond_to(proc,rb_intern("call"))))) {
32
+ rb_raise(rb_eArgError,"Error handler must be a Proc or nil");
33
+ return Qnil;
34
+ }
35
+ rb_iv_set(mX11,"error_handler",proc);
36
+ return proc;
37
+ }
38
+
39
+ static int x11_internal_error_handler(Display* dpy, XErrorEvent* err) {
40
+ char message[255];
41
+ VALUE handler = rb_iv_get(mX11,"error_handler");
42
+
43
+ XGetErrorText(err->display, err->error_code, message, 254);
44
+ if (NIL_P(handler) || !RTEST(rb_respond_to(handler,rb_intern("call")))) {
45
+ fprintf(stderr,"X11 Error: %s\n", message);
46
+ } else {
47
+ rb_funcall(handler, rb_intern("call"), 2, INT2NUM(err->error_code), rb_str_new2(message));
48
+ }
49
+ return 0; // ignored
50
+ }
51
+
52
+
53
+ // Allocate a new WindowManager object
54
+ // using the supplied Init_WM
55
+ // Also do a first query
56
+ static VALUE wm_alloc(VALUE klass) {
57
+ WM* newwm;
58
+ VALUE obj;
59
+ newwm = Init_WM();
60
+ newwm->clients = query_clients(newwm);
61
+ obj = Data_Wrap_Struct(klass, 0, Destroy_WM, newwm);
62
+ return obj;
63
+ }
64
+
65
+ static VALUE wm_query(VALUE self) {
66
+ WM *newwm;
67
+ Data_Get_Struct(self, WM, newwm);
68
+ newwm->clients = query_clients(newwm);
69
+ return Qnil;
70
+ }
71
+
72
+ static VALUE wm_sx(VALUE self) {
73
+ WM *newwm;
74
+ Data_Get_Struct(self, WM, newwm);
75
+ return INT2NUM(newwm->sx);
76
+ }
77
+
78
+ static VALUE wm_sy(VALUE self) {
79
+ WM *newwm;
80
+ Data_Get_Struct(self, WM, newwm);
81
+ return INT2NUM(newwm->sy);
82
+ }
83
+
84
+ static VALUE wm_sw(VALUE self) {
85
+ WM *newwm;
86
+ Data_Get_Struct(self, WM, newwm);
87
+ return INT2NUM(newwm->sw);
88
+ }
89
+
90
+ static VALUE wm_sh(VALUE self) {
91
+ WM *newwm;
92
+ Data_Get_Struct(self, WM, newwm);
93
+ return INT2NUM(newwm->sh);
94
+ }
95
+
96
+ static VALUE wm_wax(VALUE self) {
97
+ WM *newwm;
98
+ Data_Get_Struct(self, WM, newwm);
99
+ return INT2NUM(newwm->wax);
100
+ }
101
+
102
+ static VALUE wm_wax_set(VALUE self, VALUE newval) {
103
+ WM *newwm;
104
+ Data_Get_Struct(self, WM, newwm);
105
+ newwm->wax = NUM2INT(newval);
106
+ return Qnil;
107
+ }
108
+
109
+ static VALUE wm_manage_override_redirect_windows(VALUE self) {
110
+ WM *newwm;
111
+ Data_Get_Struct(self, WM, newwm);
112
+ return newwm->manage_override_redirect_windows ? Qtrue : Qfalse;
113
+ }
114
+
115
+ static VALUE wm_manage_override_redirect_windows_set(VALUE self, VALUE flag) {
116
+ WM *newwm;
117
+ Data_Get_Struct(self, WM, newwm);
118
+ newwm->manage_override_redirect_windows = (flag == Qtrue ? 1 : 0);
119
+ return newwm->manage_override_redirect_windows ? Qtrue : Qfalse;
120
+ }
121
+
122
+ static VALUE wm_way(VALUE self) {
123
+ WM *newwm;
124
+ Data_Get_Struct(self, WM, newwm);
125
+ return INT2NUM(newwm->way);
126
+ }
127
+
128
+ static VALUE wm_way_set(VALUE self, VALUE newval) {
129
+ WM *newwm;
130
+ Data_Get_Struct(self, WM, newwm);
131
+ newwm->way = NUM2INT(newval);
132
+ return Qnil;
133
+ }
134
+
135
+ static VALUE wm_waw(VALUE self) {
136
+ WM *newwm;
137
+ Data_Get_Struct(self, WM, newwm);
138
+ return INT2NUM(newwm->waw);
139
+ }
140
+
141
+ static VALUE wm_waw_set(VALUE self, VALUE newval) {
142
+ WM *newwm;
143
+ Data_Get_Struct(self, WM, newwm);
144
+ newwm->waw = NUM2INT(newval);
145
+ return Qnil;
146
+ }
147
+
148
+ static VALUE wm_wah(VALUE self) {
149
+ WM *newwm;
150
+ Data_Get_Struct(self, WM, newwm);
151
+ return INT2NUM(newwm->wah);
152
+ }
153
+
154
+ static VALUE wm_wah_set(VALUE self, VALUE newval) {
155
+ WM *newwm;
156
+ Data_Get_Struct(self, WM, newwm);
157
+ newwm->wah = NUM2INT(newval);
158
+ return Qnil;
159
+ }
160
+
161
+ static VALUE wm_num_clients(VALUE self) {
162
+ WM *newwm;
163
+ Data_Get_Struct(self, WM, newwm);
164
+ return INT2NUM(newwm->clients_num);
165
+ }
166
+
167
+ static VALUE wm_selected(VALUE self) {
168
+ WM *newwm;
169
+ XEvent event_return, event_saviour;
170
+ int i;
171
+
172
+ Data_Get_Struct(self, WM, newwm);
173
+
174
+ // Cycle through focus events and get the most recent
175
+ XCheckTypedEvent(newwm->dpy, FocusIn, &event_return);
176
+ /*
177
+ while (XCheckTypedEvent(newwm->dpy, FocusIn, &event_return))
178
+ */
179
+ event_saviour = event_return;
180
+ for (i=0; i<newwm->clients_num; i++)
181
+ if (&newwm->clients[i].win == &event_saviour.xany.window)
182
+ newwm->selected = &newwm->clients[i];
183
+ return client_make(cClient, newwm->selected);
184
+ }
185
+
186
+ static VALUE wm_clients(VALUE self) {
187
+ WM *newwm;
188
+ //Client *c;
189
+ VALUE obj;
190
+ VALUE arr;
191
+ int i;
192
+
193
+ arr = rb_ary_new();
194
+ Data_Get_Struct(self, WM, newwm);
195
+ for (i=0; i<newwm->clients_num; i++) {
196
+ obj = client_make(cClient, &newwm->clients[i]);
197
+ rb_ary_push(arr, obj);
198
+ }
199
+ return arr;
200
+ }
201
+
202
+ static VALUE wm_pending_event_count(VALUE self) {
203
+ WM *newwm;
204
+ Data_Get_Struct(self, WM, newwm);
205
+ return INT2NUM(XPending(newwm->dpy));
206
+ }
207
+
208
+ static VALUE wm_event_next_source(VALUE self) {
209
+ WM *newwm;
210
+ int c;
211
+
212
+ Data_Get_Struct(self, WM, newwm);
213
+ c = event_next_source(newwm);
214
+ if (c > 0)
215
+ return client_make(cClient, &newwm->clients[c]);
216
+ else
217
+ return Qnil;
218
+ }
219
+
220
+ static VALUE wm_event_next_type(VALUE self) {
221
+ WM *newwm;
222
+
223
+ Data_Get_Struct(self, WM, newwm);
224
+ if (event_next_type(newwm) != NULL)
225
+ return rb_str_new2(event_next_type(newwm));
226
+ else {
227
+ return Qnil;
228
+ }
229
+ }
230
+
231
+ static VALUE wm_event_pop(VALUE self) {
232
+ WM *newwm;
233
+
234
+ Data_Get_Struct(self, WM, newwm);
235
+ event_pop(newwm);
236
+ return Qnil;
237
+ }
238
+
239
+ static KeySym keysym_to_c(VALUE r_keysym) {
240
+ return XStringToKeysym(StringValueCStr(r_keysym));
241
+ }
242
+
243
+ static int keymask_to_c(VALUE r_mods) {
244
+ int mods = 0, i;
245
+ for (i = 0; i < numKeyMasks; i++) {
246
+ if (RTEST(rb_funcall(r_mods,rb_intern("key?"),1,ID2SYM(id_keymasks[i])))) {
247
+ mods = mods | (1 << i);
248
+ }
249
+ }
250
+ return mods;
251
+ }
252
+
253
+ static Client* client_to_c(VALUE r_client) {
254
+ Client* c;
255
+ Data_Get_Struct(r_client,Client,c);
256
+ return c;
257
+ }
258
+
259
+ static WM* wm_to_c(VALUE r_wm) {
260
+ WM* wm;
261
+ Data_Get_Struct(r_wm,WM,wm);
262
+ return wm;
263
+ }
264
+
265
+ static VALUE wm_manage(VALUE self, VALUE r_client, VALUE x, VALUE y, VALUE w, VALUE h) {
266
+ WM* wm = wm_to_c(self);
267
+ Client* c = client_to_c(r_client);
268
+ XWindowAttributes wa;
269
+ wa.x = NUM2INT(x);
270
+ wa.y = NUM2INT(y);
271
+ wa.width = NUM2INT(w);
272
+ wa.height = NUM2INT(h);
273
+ manage_client(wm,&wa,c);
274
+ return Qtrue;
275
+ }
276
+
277
+ VALUE r_client_for_window(WM* wm, Window w) {
278
+ Client* c;
279
+ c = client_ftw(wm,w);
280
+ if (!c && manageable_p(wm,w)) {
281
+ c = (Client*) calloc(1,sizeof(Client));
282
+ init_client(wm,w,c);
283
+ }
284
+ return c ? client_make(cClient,c) : Qnil;
285
+ }
286
+
287
+ static VALUE wm_get_event(VALUE self) {
288
+ WM* wm;
289
+ XEvent* pev;
290
+ VALUE r_ev,r_mods,r_keysym;
291
+ int i;
292
+
293
+ Data_Get_Struct(self,WM,wm);
294
+ pev = (XEvent*) calloc(1,sizeof(XEvent));
295
+ XNextEvent(wm->dpy,pev);
296
+ r_ev = event_wrap(cEvent,pev);
297
+
298
+
299
+ switch(pev->type) {
300
+
301
+ case ButtonPress:
302
+ case ButtonRelease:
303
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xbutton.window));
304
+ rb_ivar_set(r_ev,id_x,INT2NUM(pev->xbutton.x));
305
+ rb_ivar_set(r_ev,id_y,INT2NUM(pev->xbutton.y));
306
+ break;
307
+
308
+ case KeyPress:
309
+ case KeyRelease:
310
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xkey.window));
311
+ rb_ivar_set(r_ev,id_keycode,INT2NUM(pev->xkey.keycode));
312
+ rb_ivar_set(r_ev,id_state,INT2NUM(pev->xkey.state));
313
+
314
+ r_keysym = rb_str_new2(XKeysymToString(XLookupKeysym((XKeyEvent*)pev,0)));
315
+ r_mods = rb_hash_new();
316
+ for (i = 0; i < numKeyMasks; i++) {
317
+ if (pev->xkey.state & (1 << i))
318
+ rb_hash_aset(r_mods,ID2SYM(id_keymasks[i]),Qtrue);
319
+ }
320
+
321
+ rb_ivar_set(r_ev,id_keysym,r_keysym);
322
+ rb_ivar_set(r_ev,id_mods,r_mods);
323
+ break;
324
+
325
+ case ConfigureNotify:
326
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xconfigure.window));
327
+ break;
328
+
329
+ case FocusIn:
330
+ case FocusOut:
331
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xfocus.window));
332
+ break;
333
+
334
+ case EnterNotify:
335
+ case LeaveNotify:
336
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xcrossing.window));
337
+ break;
338
+
339
+ case CreateNotify:
340
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xcreatewindow.window));
341
+ break;
342
+
343
+ case DestroyNotify:
344
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xdestroywindow.window));
345
+ break;
346
+
347
+ case MapRequest:
348
+ rb_ivar_set(r_ev, id_client, r_client_for_window(wm,pev->xmaprequest.window));
349
+ break;
350
+ }
351
+ return r_ev;
352
+ }
353
+
354
+ static VALUE wm_grab_key(VALUE self, VALUE r_keysym, VALUE r_mods) {
355
+ KeySym keysym = keysym_to_c(r_keysym);
356
+ KeyCode keycode;
357
+ int mods = keymask_to_c(r_mods);
358
+ WM* wm;
359
+
360
+ Data_Get_Struct(self,WM,wm);
361
+ keycode = XKeysymToKeycode(wm->dpy, keysym);
362
+ XGrabKey(wm->dpy, keycode, mods, wm->root, True, GrabModeAsync, GrabModeAsync);
363
+ return Qnil;
364
+ }
365
+
366
+ static VALUE wm_ungrab_key(VALUE self, VALUE r_keysym, VALUE r_mods) {
367
+ KeySym keysym = keysym_to_c(r_keysym);
368
+ KeyCode keycode;
369
+ int mods = keymask_to_c(r_mods);
370
+ WM* wm;
371
+
372
+ Data_Get_Struct(self,WM,wm);
373
+ keycode = XKeysymToKeycode(wm->dpy, keysym);
374
+ XUngrabKey(wm->dpy, keycode, mods, wm->root);
375
+ return Qnil;
376
+ }
377
+
378
+ static void client_free(void *p) {
379
+ //free(p);
380
+ }
381
+
382
+ static VALUE client_alloc(VALUE klass) {
383
+ Client *c;
384
+ VALUE obj;
385
+ c = (Client*)calloc(1, sizeof(Client));
386
+ obj = Data_Wrap_Struct(klass, 0, client_free, c);
387
+ return obj;
388
+ }
389
+
390
+ static VALUE client_make(VALUE klass, Client* c) {
391
+ VALUE obj;
392
+ obj = Data_Wrap_Struct(klass, 0, client_free, c);
393
+ return obj;
394
+ }
395
+
396
+ static VALUE client_wid(VALUE self) {
397
+ Client *c;
398
+ Data_Get_Struct(self, Client, c);
399
+ return INT2NUM(c->win);
400
+ }
401
+
402
+ static VALUE client_name(VALUE self) {
403
+ Client *c;
404
+ Data_Get_Struct(self, Client, c);
405
+ return rb_str_new2(c->name);
406
+ }
407
+
408
+ static VALUE client_class(VALUE self) {
409
+ Client *c;
410
+ Data_Get_Struct(self, Client, c);
411
+ return rb_str_new2(c->class);
412
+ }
413
+
414
+ static VALUE client_border(VALUE self) {
415
+ Client* c;
416
+ Data_Get_Struct(self, Client, c);
417
+ return INT2NUM(c->border);
418
+ }
419
+
420
+ static VALUE client_border_set(VALUE self, VALUE width) {
421
+ Client* c;
422
+ Data_Get_Struct(self, Client, c);
423
+ border_client(c, NUM2INT(width));
424
+ return Qnil;
425
+ }
426
+
427
+ static VALUE client_border_dset(VALUE self) {
428
+ Client* c;
429
+ Data_Get_Struct(self, Client, c);
430
+ unborder_client(c);
431
+ return Qnil;
432
+ }
433
+
434
+ static VALUE client_x(VALUE self) {
435
+ Client *c;
436
+ Data_Get_Struct(self, Client, c);
437
+ return INT2NUM(c->x);
438
+ }
439
+
440
+ static VALUE client_x_set(VALUE self, VALUE nv) {
441
+ Client *c;
442
+ Data_Get_Struct(self, Client, c);
443
+ resize(c->manager, c, NUM2INT(nv), c->y, c->w, c->h, False);
444
+
445
+ return Qnil;
446
+ }
447
+
448
+ static VALUE client_y(VALUE self) {
449
+ Client *c;
450
+ Data_Get_Struct(self, Client, c);
451
+ return INT2NUM(c->y);
452
+ }
453
+
454
+ static VALUE client_y_set(VALUE self, VALUE nv) {
455
+ Client *c;
456
+ Data_Get_Struct(self, Client, c);
457
+ resize(c->manager, c, c->x, NUM2INT(nv), c->w, c->h, False);
458
+
459
+ return Qnil;
460
+ }
461
+
462
+ static VALUE client_w(VALUE self) {
463
+ Client *c;
464
+ Data_Get_Struct(self, Client, c);
465
+ return INT2NUM(c->w);
466
+ }
467
+
468
+ static VALUE client_w_set(VALUE self, VALUE nv) {
469
+ Client *c;
470
+ Data_Get_Struct(self, Client, c);
471
+ resize(c->manager, c, c->x, c->y, NUM2INT(nv), c->h, False);
472
+
473
+ return Qnil;
474
+ }
475
+
476
+ static VALUE client_h(VALUE self) {
477
+ Client *c;
478
+ Data_Get_Struct(self, Client, c);
479
+ return INT2NUM(c->h);
480
+ }
481
+
482
+ static VALUE client_h_set(VALUE self, VALUE nv) {
483
+ Client *c;
484
+ Data_Get_Struct(self, Client, c);
485
+ resize(c->manager, c, c->x, c->y, c->w, NUM2INT(nv), False);
486
+
487
+ return Qnil;
488
+ }
489
+
490
+ static VALUE client_size(VALUE self) {
491
+ Client *c;
492
+ int sizes[4];
493
+
494
+ Data_Get_Struct(self, Client, c);
495
+ sizes[0] = c->x;
496
+ sizes[1] = c->y;
497
+ sizes[2] = c->w;
498
+ sizes[3] = c->h;
499
+ return rb_ary_new3(4, INT2NUM(sizes[0]), INT2NUM(sizes[1]), INT2NUM(sizes[2]), INT2NUM(sizes[3]));
500
+ }
501
+
502
+ static VALUE client_raise(VALUE self) {
503
+ Client *c;
504
+ Data_Get_Struct(self, Client, c);
505
+ raise_client(c);
506
+ return client_make(cClient, c);
507
+ }
508
+
509
+ static VALUE client_ban(VALUE self) {
510
+ Client* c;
511
+ Data_Get_Struct(self, Client, c);
512
+ ban_client(c);
513
+ return Qnil;
514
+ }
515
+
516
+ static VALUE client_unban(VALUE self) {
517
+ Client* c;
518
+ Data_Get_Struct(self, Client, c);
519
+ unban_client(c);
520
+ return client_make(cClient, c);
521
+ }
522
+
523
+ static VALUE client_size_set(VALUE self, VALUE valarray) {
524
+ Client *c;
525
+ Data_Get_Struct(self, Client, c);
526
+ int x,y,w,h;
527
+
528
+ if (RARRAY_LEN(valarray) >= 4) {
529
+ x = RARRAY_PTR(valarray)[0];
530
+ y = RARRAY_PTR(valarray)[1];
531
+ w = RARRAY_PTR(valarray)[2];
532
+ h = RARRAY_PTR(valarray)[3];
533
+ resize(c->manager, c, x, y, w, h, False);
534
+ }
535
+ else
536
+ rb_raise(rb_eArgError, "wrong number of arguments [x,y,w,h]");
537
+ return Qnil;
538
+ }
539
+
540
+ static VALUE event_alloc(VALUE klass) {
541
+ XEvent *ev = (XEvent*) calloc(1,sizeof(XEvent));
542
+ return Data_Wrap_Struct(klass, 0, free, ev);
543
+ }
544
+
545
+ static VALUE event_wrap(VALUE klass, XEvent* ev) {
546
+ return Data_Wrap_Struct(klass, 0, free, ev);
547
+ }
548
+
549
+ static VALUE event_type(VALUE self) {
550
+ XEvent* ev;
551
+ Data_Get_Struct(self,XEvent,ev);
552
+ //if (ev->type < LASTEvent && !NIL_P(id_events[ev->type])) {
553
+ // return id_events[ev->type];
554
+ //} else {
555
+ return INT2NUM(ev->type);
556
+ //}
557
+ }
558
+
559
+ static VALUE event_serial(VALUE self) {
560
+ XEvent* ev;
561
+ Data_Get_Struct(self,XEvent,ev);
562
+ return INT2NUM(ev->xany.serial);
563
+ }
564
+
565
+ static VALUE event_wid(VALUE self) {
566
+ XEvent* ev;
567
+ Data_Get_Struct(self,XEvent,ev);
568
+ return INT2NUM(ev->xany.window);
569
+ }
570
+
571
+ static VALUE event_client(VALUE self) {
572
+ return rb_ivar_get(self,id_client);
573
+ }
574
+
575
+ static VALUE event_button(VALUE self) {
576
+ return rb_ivar_get(self,id_button);
577
+ }
578
+
579
+ static VALUE event_x(VALUE self) {
580
+ return rb_ivar_get(self,id_x);
581
+ }
582
+
583
+ static VALUE event_y(VALUE self) {
584
+ return rb_ivar_get(self,id_y);
585
+ }
586
+
587
+ static VALUE event_keycode(VALUE self) {
588
+ return rb_ivar_get(self,id_keycode);
589
+ }
590
+
591
+ static VALUE event_keysym(VALUE self) {
592
+ return rb_ivar_get(self,id_keysym);
593
+ }
594
+
595
+ static VALUE event_state(VALUE self) {
596
+ return rb_ivar_get(self,id_state);
597
+ }
598
+
599
+ static VALUE event_mods(VALUE self) {
600
+ return rb_ivar_get(self,id_mods);
601
+ }
602
+
603
+ void Init_x11() {
604
+
605
+ // Main module
606
+ mX11 = rb_define_module("X11");
607
+
608
+ rb_define_singleton_method(mX11, "error_handler", x11_error_handler, 0);
609
+ rb_define_singleton_method(mX11, "error_handler=", x11_error_handler_set, 1);
610
+
611
+ XSetErrorHandler(x11_internal_error_handler);
612
+
613
+ // WindowManager
614
+
615
+ cWM = rb_define_class_under(mX11, "WindowManager", rb_cObject);
616
+ rb_define_alloc_func(cWM, wm_alloc);
617
+
618
+ rb_define_method(cWM, "query", wm_query, 0);
619
+ rb_define_method(cWM, "selected", wm_selected, 0);
620
+ rb_define_method(cWM, "screenxpos", wm_sx, 0);
621
+ rb_define_method(cWM, "screenypos", wm_sy, 0);
622
+ rb_define_method(cWM, "screenwidth", wm_sw, 0);
623
+ rb_define_method(cWM, "screenheight", wm_sh, 0);
624
+ rb_define_method(cWM, "windowareaxpos", wm_wax, 0);
625
+ rb_define_method(cWM, "windowareaypos", wm_way, 0);
626
+ rb_define_method(cWM, "windowareawidth", wm_waw, 0);
627
+ rb_define_method(cWM, "windowareaheight", wm_wah, 0);
628
+ rb_define_method(cWM, "windowareaxpos=", wm_wax_set, 1);
629
+ rb_define_method(cWM, "windowareaypos=", wm_way_set, 1);
630
+ rb_define_method(cWM, "windowareawidth=", wm_waw_set, 1);
631
+ rb_define_method(cWM, "windowareaheight=", wm_wah_set, 1);
632
+ rb_define_method(cWM, "number_of_clients", wm_num_clients, 0);
633
+ rb_define_method(cWM, "clients", wm_clients, 0);
634
+ rb_define_method(cWM, "pending_event_count", wm_pending_event_count, 0);
635
+ rb_define_method(cWM, "next_event", wm_event_next_type, 0);
636
+ rb_define_method(cWM, "next_event_source", wm_event_next_source, 0);
637
+ rb_define_method(cWM, "event_pop", wm_event_pop, 0);
638
+ rb_define_method(cWM, "get_event", wm_get_event, 0);
639
+ rb_define_method(cWM, "get_grab_key", wm_grab_key, 2);
640
+ rb_define_method(cWM, "get_ungrab_key", wm_ungrab_key, 2);
641
+ rb_define_method(cWM, "manage", wm_manage, 5);
642
+ rb_define_method(cWM, "manage_override_redirect_windows", wm_manage_override_redirect_windows, 0);
643
+ rb_define_method(cWM, "manage_override_redirect_windows=", wm_manage_override_redirect_windows_set, 1);
644
+
645
+ // Client
646
+
647
+ cClient = rb_define_class_under(cWM, "Client", rb_cObject);
648
+ rb_define_alloc_func(cClient, client_alloc);
649
+
650
+ rb_define_method(cClient, "size=", client_size_set, 1);
651
+ rb_define_method(cClient, "size", client_size, 0);
652
+ rb_define_method(cClient, "name", client_name, 0);
653
+ rb_define_method(cClient, "window_class", client_class, 0);
654
+ rb_define_method(cClient, "wid", client_wid, 0);
655
+
656
+ rb_define_method(cClient, "xpos", client_x, 0);
657
+ rb_define_method(cClient, "ypos", client_y, 0);
658
+ rb_define_method(cClient, "width", client_w, 0);
659
+ rb_define_method(cClient, "height", client_h, 0);
660
+ rb_define_method(cClient, "xpos=", client_x_set, 1);
661
+ rb_define_method(cClient, "ypos=", client_y_set, 1);
662
+ rb_define_method(cClient, "width=", client_w_set, 1);
663
+ rb_define_method(cClient, "height=", client_h_set, 1);
664
+ rb_define_method(cClient, "raise", client_raise, 0);
665
+ rb_define_method(cClient, "ban", client_ban, 0);
666
+ rb_define_method(cClient, "unban", client_unban, 0);
667
+ rb_define_method(cClient, "border", client_border, 0);
668
+ rb_define_method(cClient, "border=", client_border_set, 1);
669
+ rb_define_method(cClient, "border_reset", client_border_dset, 0);
670
+
671
+
672
+ // Event
673
+
674
+ id_keymasks[0] = rb_intern("Shift");
675
+ id_keymasks[1] = rb_intern("Lock");
676
+ id_keymasks[2] = rb_intern("Control");
677
+ id_keymasks[3] = rb_intern("Mod1");
678
+ id_keymasks[4] = rb_intern("Mod2");
679
+ id_keymasks[5] = rb_intern("Mod3");
680
+ id_keymasks[6] = rb_intern("Mod4");
681
+ id_keymasks[7] = rb_intern("Mod5");
682
+ id_keymasks[8] = rb_intern("Button1");
683
+ id_keymasks[9] = rb_intern("Button2");
684
+ id_keymasks[10] = rb_intern("Button3");
685
+ id_keymasks[11] = rb_intern("Button4");
686
+ id_keymasks[12] = rb_intern("Button5");
687
+
688
+ id_client = rb_intern("client");
689
+ id_x = rb_intern("x");
690
+ id_y = rb_intern("y");
691
+ id_button = rb_intern("button");
692
+ id_keycode = rb_intern("keycode");
693
+ id_keysym = rb_intern("keysym");
694
+ id_state = rb_intern("state");
695
+ id_mods = rb_intern("mods");
696
+
697
+ cEvent = rb_define_class_under(mX11,"Event",rb_cObject);
698
+ rb_define_alloc_func(cEvent, event_alloc);
699
+
700
+ rb_define_method(cEvent,"type",event_type,0);
701
+ rb_define_method(cEvent,"serial",event_serial,0);
702
+ rb_define_method(cEvent,"wid",event_wid,0);
703
+ rb_define_method(cEvent,"client",event_client,0);
704
+ rb_define_method(cEvent,"button",event_button,0);
705
+ rb_define_method(cEvent,"x",event_x,0);
706
+ rb_define_method(cEvent,"y",event_y,0);
707
+ rb_define_method(cEvent,"keycode",event_keycode,0);
708
+ rb_define_method(cEvent,"keysym",event_keysym,0);
709
+ rb_define_method(cEvent,"state",event_state,0);
710
+ rb_define_method(cEvent,"mods",event_mods,0);
711
+ }
712
+