uh 2.0.0.pre3 → 2.0.0.pre4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/uh/color.c +34 -0
- data/ext/uh/display.c +222 -0
- data/ext/uh/event.c +168 -0
- data/ext/uh/font.c +31 -0
- data/ext/uh/pixmap.c +110 -0
- data/ext/uh/screen.c +12 -0
- data/ext/uh/uh.c +147 -0
- data/ext/uh/uh.h +110 -0
- data/ext/uh/window.c +278 -0
- data/lib/uh/version.rb +1 -1
- metadata +10 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 654b2920bafd23793a74fa558b93bdc7e4852af3
|
4
|
+
data.tar.gz: 7407b260cc14024807da1ea16824754d4f87223a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f85b085cda9091602508ee84a1c9fdc5d4e4faed56a17091a2aa2a6d9846758dc6ad66a034ab78c526f105c4985fdd25530cec281e8cd141c12ade03321b7df
|
7
|
+
data.tar.gz: 7989dc2e520cb7e38a89b1e7c9742ced939d165723e3b60e14501321ea503414546cc95f05ea69afcc184e612e58dd7a86c30356d617f9a618bb43ced302e339
|
data/ext/uh/color.c
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
VALUE color_make(Display *dpy, char *color_name);
|
5
|
+
|
6
|
+
|
7
|
+
VALUE color_s_new(VALUE klass, VALUE rdisplay, VALUE rcolor_name) {
|
8
|
+
VALUE rcolor;
|
9
|
+
SET_DISPLAY(rdisplay);
|
10
|
+
|
11
|
+
rb_funcall(rdisplay, rb_intern("check!"), 0);
|
12
|
+
StringValue(rcolor_name);
|
13
|
+
|
14
|
+
rcolor = color_make(display->dpy, RSTRING_PTR(rcolor_name));
|
15
|
+
rb_ivar_set(rcolor, rb_intern("@name"), rcolor_name);
|
16
|
+
|
17
|
+
return rcolor;
|
18
|
+
}
|
19
|
+
|
20
|
+
|
21
|
+
VALUE color_make(Display *dpy, char *color_name) {
|
22
|
+
Colormap map;
|
23
|
+
XColor color;
|
24
|
+
VALUE rcolor;
|
25
|
+
VALUE args[0];
|
26
|
+
|
27
|
+
map = DefaultColormap(dpy, DefaultScreen(dpy));
|
28
|
+
if (!XAllocNamedColor(dpy, map, color_name, &color, &color))
|
29
|
+
rb_raise(eArgumentError, "invalid color name `%s'", color_name);
|
30
|
+
rcolor = rb_class_new_instance(0, args, cColor);
|
31
|
+
rb_ivar_set(rcolor, rb_intern("@pixel"), LONG2NUM(color.pixel));
|
32
|
+
|
33
|
+
return rcolor;
|
34
|
+
}
|
data/ext/uh/display.c
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
#define SET_DISPLAY(x) \
|
5
|
+
UhDisplay *display;\
|
6
|
+
Data_Get_Struct(x, UhDisplay, display);
|
7
|
+
|
8
|
+
#define DPY display->dpy
|
9
|
+
|
10
|
+
|
11
|
+
VALUE rdisplay_error_handler = Qnil;
|
12
|
+
|
13
|
+
int display_x_error_handler(Display *dpy, XErrorEvent *e);
|
14
|
+
|
15
|
+
|
16
|
+
VALUE display_s_on_error(VALUE klass) {
|
17
|
+
if (!rb_block_given_p()) {
|
18
|
+
rb_raise(rb_eArgError, "no block given");
|
19
|
+
}
|
20
|
+
|
21
|
+
rdisplay_error_handler = rb_block_proc();
|
22
|
+
rb_global_variable(&rdisplay_error_handler);
|
23
|
+
|
24
|
+
return Qnil;
|
25
|
+
}
|
26
|
+
|
27
|
+
|
28
|
+
VALUE display_alloc(VALUE klass) {
|
29
|
+
UhDisplay *display;
|
30
|
+
|
31
|
+
return Data_Make_Struct(klass, UhDisplay, 0, free, display);
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
VALUE display_close(VALUE self) {
|
36
|
+
SET_DISPLAY(self);
|
37
|
+
|
38
|
+
if (DPY) {
|
39
|
+
XCloseDisplay(DPY);
|
40
|
+
DPY = NULL;
|
41
|
+
}
|
42
|
+
else {
|
43
|
+
rb_raise(eDisplayError, "cannot close display");
|
44
|
+
}
|
45
|
+
|
46
|
+
return self;
|
47
|
+
}
|
48
|
+
|
49
|
+
VALUE display_each_event(VALUE self) {
|
50
|
+
XEvent xev;
|
51
|
+
SET_DISPLAY(self);
|
52
|
+
|
53
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
54
|
+
while (1) {
|
55
|
+
XNextEvent(DPY, &xev);
|
56
|
+
rb_yield(event_make(&xev));
|
57
|
+
}
|
58
|
+
|
59
|
+
return Qnil;
|
60
|
+
}
|
61
|
+
|
62
|
+
VALUE display_fileno(VALUE self) {
|
63
|
+
SET_DISPLAY(self);
|
64
|
+
|
65
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
66
|
+
|
67
|
+
return INT2FIX(XConnectionNumber(DPY));
|
68
|
+
}
|
69
|
+
|
70
|
+
VALUE display_flush(VALUE self) {
|
71
|
+
SET_DISPLAY(self);
|
72
|
+
|
73
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
74
|
+
|
75
|
+
return INT2FIX(XFlush(DPY));
|
76
|
+
}
|
77
|
+
|
78
|
+
VALUE display_grab_key(VALUE self, VALUE rkey, VALUE rmodifier) {
|
79
|
+
KeySym ks;
|
80
|
+
KeyCode kc;
|
81
|
+
SET_DISPLAY(self);
|
82
|
+
|
83
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
84
|
+
StringValue(rkey);
|
85
|
+
ks = XStringToKeysym(RSTRING_PTR(rkey));
|
86
|
+
if (ks == NoSymbol)
|
87
|
+
rb_raise(eArgumentError, "invalid KeySym %s", RSTRING_PTR(rkey));
|
88
|
+
|
89
|
+
kc = XKeysymToKeycode(DPY, ks);
|
90
|
+
if (kc == 0)
|
91
|
+
rb_raise(eArgumentError, "keysym XK_%s has no keycode", RSTRING_PTR(rkey));
|
92
|
+
|
93
|
+
XGrabKey(DPY, kc, FIX2INT(rmodifier), ROOT_DEFAULT, True,
|
94
|
+
GrabModeAsync, GrabModeAsync);
|
95
|
+
|
96
|
+
return Qnil;
|
97
|
+
}
|
98
|
+
|
99
|
+
VALUE display_listen_events(int argc, VALUE *argv, VALUE self) {
|
100
|
+
VALUE arg1;
|
101
|
+
VALUE arg2;
|
102
|
+
Window window;
|
103
|
+
long mask;
|
104
|
+
SET_DISPLAY(self);
|
105
|
+
|
106
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
107
|
+
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
|
108
|
+
window = window_id(arg1);
|
109
|
+
mask = FIX2LONG(arg2);
|
110
|
+
}
|
111
|
+
else {
|
112
|
+
window = ROOT_DEFAULT;
|
113
|
+
mask = FIX2LONG(arg1);
|
114
|
+
}
|
115
|
+
|
116
|
+
XSelectInput(DPY, window, mask);
|
117
|
+
|
118
|
+
return Qnil;
|
119
|
+
}
|
120
|
+
|
121
|
+
VALUE display_next_event(VALUE self) {
|
122
|
+
XEvent xev;
|
123
|
+
SET_DISPLAY(self);
|
124
|
+
|
125
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
126
|
+
XNextEvent(DPY, &xev);
|
127
|
+
|
128
|
+
return event_make(&xev);
|
129
|
+
}
|
130
|
+
|
131
|
+
VALUE display_open(VALUE self) {
|
132
|
+
SET_DISPLAY(self);
|
133
|
+
|
134
|
+
if (!(DPY = XOpenDisplay(NULL))) {
|
135
|
+
rb_raise(eDisplayError, "cannot open display");
|
136
|
+
}
|
137
|
+
|
138
|
+
XSetErrorHandler(display_x_error_handler);
|
139
|
+
|
140
|
+
return self;
|
141
|
+
}
|
142
|
+
|
143
|
+
VALUE display_opened_p(VALUE self) {
|
144
|
+
SET_DISPLAY(self);
|
145
|
+
|
146
|
+
return DPY ? Qtrue : Qfalse;
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE display_pending_p(VALUE self) {
|
150
|
+
SET_DISPLAY(self);
|
151
|
+
|
152
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
153
|
+
|
154
|
+
return INT2FIX(XPending(DPY));
|
155
|
+
}
|
156
|
+
|
157
|
+
VALUE display_root(VALUE self) {
|
158
|
+
SET_DISPLAY(self);
|
159
|
+
|
160
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
161
|
+
|
162
|
+
return window_make(DPY, ROOT_DEFAULT);
|
163
|
+
}
|
164
|
+
|
165
|
+
VALUE display_screens(VALUE self) {
|
166
|
+
XineramaScreenInfo *xsi;
|
167
|
+
int n;
|
168
|
+
VALUE screens = rb_ary_new();
|
169
|
+
VALUE args[5];
|
170
|
+
SET_DISPLAY(self);
|
171
|
+
|
172
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
173
|
+
if (XineramaIsActive(DPY)) {
|
174
|
+
xsi = XineramaQueryScreens(DPY, &n);
|
175
|
+
for (int i = 0; i < n; i++) {
|
176
|
+
args[0] = INT2FIX(i);
|
177
|
+
args[1] = INT2FIX(xsi[i].x_org);
|
178
|
+
args[2] = INT2FIX(xsi[i].y_org);
|
179
|
+
args[3] = INT2FIX(xsi[i].width);
|
180
|
+
args[4] = INT2FIX(xsi[i].height);
|
181
|
+
rb_ary_push(screens, rb_class_new_instance(5, args, cScreen));
|
182
|
+
}
|
183
|
+
}
|
184
|
+
else {
|
185
|
+
args[0] = INT2FIX(SCREEN_DEFAULT);
|
186
|
+
args[1] = INT2FIX(0);
|
187
|
+
args[2] = INT2FIX(0);
|
188
|
+
args[3] = INT2FIX(XDisplayWidth(DPY, SCREEN_DEFAULT));
|
189
|
+
args[4] = INT2FIX(XDisplayHeight(DPY, SCREEN_DEFAULT));
|
190
|
+
rb_ary_push(screens, rb_class_new_instance(5, args, cScreen));
|
191
|
+
}
|
192
|
+
|
193
|
+
return screens;
|
194
|
+
}
|
195
|
+
|
196
|
+
VALUE display_sync(VALUE self, VALUE rdiscard) {
|
197
|
+
SET_DISPLAY(self);
|
198
|
+
|
199
|
+
rb_funcall(self, rb_intern("check!"), 0);
|
200
|
+
XSync(display->dpy, RTEST(rdiscard));
|
201
|
+
|
202
|
+
return Qnil;
|
203
|
+
}
|
204
|
+
|
205
|
+
|
206
|
+
int display_x_error_handler(Display *dpy, XErrorEvent *e) {
|
207
|
+
char msg[80];
|
208
|
+
char req[80];
|
209
|
+
char nb[80];
|
210
|
+
|
211
|
+
XGetErrorText(dpy, e->error_code, msg, sizeof msg);
|
212
|
+
sprintf(nb, "%d", e->request_code);
|
213
|
+
XGetErrorDatabaseText(dpy, "XRequest", nb, "<unknown>", req, sizeof req);
|
214
|
+
|
215
|
+
rb_funcall(rdisplay_error_handler, rb_intern("call"), 3,
|
216
|
+
rb_str_new_cstr(req),
|
217
|
+
LONG2NUM(e->resourceid),
|
218
|
+
rb_str_new_cstr(msg)
|
219
|
+
);
|
220
|
+
|
221
|
+
return 0;
|
222
|
+
}
|
data/ext/uh/event.c
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
#define SET_XEV(x) \
|
5
|
+
XEvent *xev;\
|
6
|
+
Data_Get_Struct(x, XEvent, xev);
|
7
|
+
|
8
|
+
|
9
|
+
VALUE event_make_event(VALUE klass, XEvent *xev);
|
10
|
+
void event_make_configure_request(VALUE self);
|
11
|
+
void event_make_key_any(VALUE self);
|
12
|
+
void event_make_win_any(VALUE self);
|
13
|
+
|
14
|
+
|
15
|
+
VALUE event_make(XEvent *xev) {
|
16
|
+
typedef struct {
|
17
|
+
int type;
|
18
|
+
VALUE klass;
|
19
|
+
void (*function)(VALUE self);
|
20
|
+
} EvClass;
|
21
|
+
EvClass ev_classes[] = {
|
22
|
+
{ConfigureRequest, cConfigureRequest, event_make_configure_request},
|
23
|
+
{DestroyNotify, cDestroyNotify, NULL},
|
24
|
+
{Expose, cExpose, NULL},
|
25
|
+
{KeyPress, cKeyPress, event_make_key_any},
|
26
|
+
{KeyRelease, cKeyRelease, event_make_key_any},
|
27
|
+
{MapRequest, cMapRequest, NULL},
|
28
|
+
{PropertyNotify, cPropertyNotify, NULL},
|
29
|
+
{UnmapNotify, cUnmapNotify, NULL}
|
30
|
+
};
|
31
|
+
unsigned int i;
|
32
|
+
VALUE event;
|
33
|
+
|
34
|
+
for (i = 0; i < (sizeof ev_classes / sizeof ev_classes[0]); i++) {
|
35
|
+
if (ev_classes[i].type == xev->type) {
|
36
|
+
event = event_make_event(ev_classes[i].klass, xev);
|
37
|
+
event_make_win_any(event);
|
38
|
+
if (ev_classes[i].function)
|
39
|
+
ev_classes[i].function(event);
|
40
|
+
|
41
|
+
return event;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
return event_make_event(cEvent, xev);
|
46
|
+
}
|
47
|
+
|
48
|
+
VALUE event_make_event(VALUE klass, XEvent *xev) {
|
49
|
+
const char *type_descs[LASTEvent];
|
50
|
+
VALUE event;
|
51
|
+
|
52
|
+
type_descs[KeyPress] = "key_press";
|
53
|
+
type_descs[KeyRelease] = "key_release";
|
54
|
+
type_descs[ButtonPress] = "button_press";
|
55
|
+
type_descs[ButtonRelease] = "button_release";
|
56
|
+
type_descs[MotionNotify] = "motion_notify";
|
57
|
+
type_descs[EnterNotify] = "enter_notify";
|
58
|
+
type_descs[LeaveNotify] = "leave_notify";
|
59
|
+
type_descs[FocusIn] = "focus_in";
|
60
|
+
type_descs[FocusOut] = "focus_out";
|
61
|
+
type_descs[KeymapNotify] = "keymap_notify";
|
62
|
+
type_descs[Expose] = "expose";
|
63
|
+
type_descs[GraphicsExpose] = "graphics_expose";
|
64
|
+
type_descs[NoExpose] = "no_expose";
|
65
|
+
type_descs[VisibilityNotify] = "visibility_notify";
|
66
|
+
type_descs[CreateNotify] = "create_notify";
|
67
|
+
type_descs[DestroyNotify] = "destroy_notify";
|
68
|
+
type_descs[UnmapNotify] = "unmap_notify";
|
69
|
+
type_descs[MapNotify] = "map_notify";
|
70
|
+
type_descs[MapRequest] = "map_request";
|
71
|
+
type_descs[ReparentNotify] = "reparent_notify";
|
72
|
+
type_descs[ConfigureNotify] = "configure_notify";
|
73
|
+
type_descs[ConfigureRequest] = "configure_request";
|
74
|
+
type_descs[GravityNotify] = "gravity_notify";
|
75
|
+
type_descs[ResizeRequest] = "resize_request";
|
76
|
+
type_descs[CirculateNotify] = "circulate_notify";
|
77
|
+
type_descs[CirculateRequest] = "circulate_request";
|
78
|
+
type_descs[PropertyNotify] = "property_notify";
|
79
|
+
type_descs[SelectionClear] = "selection_clear";
|
80
|
+
type_descs[SelectionRequest] = "selection_request";
|
81
|
+
type_descs[SelectionNotify] = "selection_notify";
|
82
|
+
type_descs[ColormapNotify] = "colormap_notify";
|
83
|
+
type_descs[ClientMessage] = "client_message";
|
84
|
+
type_descs[MappingNotify] = "mapping_notify";
|
85
|
+
type_descs[GenericEvent] = "generic";
|
86
|
+
|
87
|
+
event = Data_Wrap_Struct(klass, 0, 0, xev);
|
88
|
+
rb_ivar_set(event, rb_intern("@type"),
|
89
|
+
ID2SYM(rb_intern(type_descs[xev->type])));
|
90
|
+
rb_ivar_set(event, rb_intern("@send_event"),
|
91
|
+
xev->xany.send_event ? Qtrue : Qfalse);
|
92
|
+
|
93
|
+
return event;
|
94
|
+
}
|
95
|
+
|
96
|
+
void event_make_configure_request(VALUE self) {
|
97
|
+
SET_XEV(self);
|
98
|
+
|
99
|
+
if (xev->xconfigurerequest.value_mask & CWX)
|
100
|
+
rb_ivar_set(self, rb_intern("@x"), INT2FIX(xev->xconfigurerequest.x));
|
101
|
+
|
102
|
+
if (xev->xconfigurerequest.value_mask & CWY)
|
103
|
+
rb_ivar_set(self, rb_intern("@y"), INT2FIX(xev->xconfigurerequest.y));
|
104
|
+
|
105
|
+
if (xev->xconfigurerequest.value_mask & CWWidth)
|
106
|
+
rb_ivar_set(self, rb_intern("@width"),
|
107
|
+
INT2FIX(xev->xconfigurerequest.width));
|
108
|
+
|
109
|
+
if (xev->xconfigurerequest.value_mask & CWHeight)
|
110
|
+
rb_ivar_set(self, rb_intern("@height"),
|
111
|
+
INT2FIX(xev->xconfigurerequest.height));
|
112
|
+
|
113
|
+
rb_ivar_set(self, rb_intern("@above_window_id"),
|
114
|
+
LONG2NUM(xev->xconfigurerequest.above));
|
115
|
+
rb_ivar_set(self, rb_intern("@detail"),
|
116
|
+
INT2FIX(xev->xconfigurerequest.detail));
|
117
|
+
rb_ivar_set(self, rb_intern("@value_mask"),
|
118
|
+
LONG2NUM(xev->xconfigurerequest.detail));
|
119
|
+
}
|
120
|
+
|
121
|
+
void event_make_key_any(VALUE self) {
|
122
|
+
KeySym ks;
|
123
|
+
SET_XEV(self);
|
124
|
+
|
125
|
+
ks = XkbKeycodeToKeysym(xev->xany.display, xev->xkey.keycode, 0, 0);
|
126
|
+
if (ks == NoSymbol)
|
127
|
+
return;
|
128
|
+
|
129
|
+
rb_ivar_set(self, rb_intern("@key"), rb_str_new_cstr(XKeysymToString(ks)));
|
130
|
+
rb_ivar_set(self, rb_intern("@modifier_mask"), INT2FIX(xev->xkey.state));
|
131
|
+
}
|
132
|
+
|
133
|
+
void event_make_win_any(VALUE self) {
|
134
|
+
Window window;
|
135
|
+
SET_XEV(self);
|
136
|
+
|
137
|
+
switch (xev->type) {
|
138
|
+
case ConfigureRequest:
|
139
|
+
window = xev->xconfigurerequest.window;
|
140
|
+
break;
|
141
|
+
case DestroyNotify:
|
142
|
+
window = xev->xdestroywindow.window;
|
143
|
+
break;
|
144
|
+
case Expose:
|
145
|
+
window = xev->xexpose.window;
|
146
|
+
break;
|
147
|
+
case KeyPress:
|
148
|
+
window = xev->xkey.window;
|
149
|
+
break;
|
150
|
+
case MapRequest:
|
151
|
+
window = xev->xmaprequest.window;
|
152
|
+
break;
|
153
|
+
case PropertyNotify:
|
154
|
+
window = xev->xproperty.window;
|
155
|
+
break;
|
156
|
+
case UnmapNotify:
|
157
|
+
rb_ivar_set(self, rb_intern("@event_window"),
|
158
|
+
window_make(xev->xany.display, xev->xunmap.event));
|
159
|
+
window = xev->xunmap.window;
|
160
|
+
break;
|
161
|
+
default:
|
162
|
+
window = xev->xany.window;
|
163
|
+
break;
|
164
|
+
}
|
165
|
+
|
166
|
+
rb_ivar_set(self, rb_intern("@window"),
|
167
|
+
window_make(xev->xany.display, window));
|
168
|
+
}
|
data/ext/uh/font.c
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
VALUE font_make(Display *dpy);
|
5
|
+
|
6
|
+
|
7
|
+
VALUE font_s_new(VALUE klass, VALUE rdisplay) {
|
8
|
+
SET_DISPLAY(rdisplay);
|
9
|
+
|
10
|
+
rb_funcall(rdisplay, rb_intern("check!"), 0);
|
11
|
+
|
12
|
+
return font_make(display->dpy);
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
VALUE font_make(Display *dpy) {
|
17
|
+
XFontStruct *xfs;
|
18
|
+
VALUE rfont;
|
19
|
+
VALUE args[0];
|
20
|
+
|
21
|
+
if (!(xfs = XQueryFont(dpy,
|
22
|
+
XGContextFromGC(DefaultGC(dpy, DefaultScreen(dpy))))))
|
23
|
+
rb_raise(eDisplayError, "cannot query font");
|
24
|
+
rfont = rb_class_new_instance(0, args, cFont);
|
25
|
+
rb_ivar_set(rfont, rb_intern("@width"), INT2FIX(xfs->max_bounds.width));
|
26
|
+
rb_ivar_set(rfont, rb_intern("@ascent"), INT2FIX(xfs->ascent));
|
27
|
+
rb_ivar_set(rfont, rb_intern("@descent"), INT2FIX(xfs->descent));
|
28
|
+
XFreeFontInfo(NULL, xfs, 1);
|
29
|
+
|
30
|
+
return rfont;
|
31
|
+
}
|
data/ext/uh/pixmap.c
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
#define SET_PIXMAP(x) \
|
5
|
+
UhPixmap *pixmap;\
|
6
|
+
Data_Get_Struct(x, UhPixmap, pixmap);
|
7
|
+
|
8
|
+
#define DPY pixmap->dpy
|
9
|
+
#define PIXMAP pixmap->pixmap
|
10
|
+
#define GC pixmap->gc
|
11
|
+
#define DEPTH_DEFAULT DefaultDepth(DPY, SCREEN_DEFAULT)
|
12
|
+
|
13
|
+
|
14
|
+
void pixmap_deallocate(UhPixmap *p);
|
15
|
+
|
16
|
+
|
17
|
+
VALUE pixmap_s_new(VALUE klass, VALUE rdisplay, VALUE rwidth, VALUE rheight) {
|
18
|
+
VALUE rpixmap;
|
19
|
+
SET_DISPLAY(rdisplay);
|
20
|
+
|
21
|
+
rb_funcall(rdisplay, rb_intern("check!"), 0);
|
22
|
+
|
23
|
+
rpixmap = pixmap_make(display->dpy, FIX2INT(rwidth), FIX2INT(rheight));
|
24
|
+
rb_ivar_set(rpixmap, rb_intern("@width"), rwidth);
|
25
|
+
rb_ivar_set(rpixmap, rb_intern("@height"), rheight);
|
26
|
+
|
27
|
+
return rpixmap;
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
VALUE pixmap_draw_rect(VALUE self, VALUE rx, VALUE ry, VALUE rw, VALUE rh) {
|
32
|
+
SET_PIXMAP(self)
|
33
|
+
|
34
|
+
XFillRectangle(DPY, PIXMAP, GC,
|
35
|
+
FIX2INT(rx), FIX2INT(ry), FIX2INT(rw), FIX2INT(rh)
|
36
|
+
);
|
37
|
+
|
38
|
+
return Qnil;
|
39
|
+
}
|
40
|
+
|
41
|
+
VALUE pixmap_draw_string(VALUE self, VALUE rx, VALUE ry, VALUE rstr) {
|
42
|
+
SET_PIXMAP(self)
|
43
|
+
|
44
|
+
StringValue(rstr);
|
45
|
+
XDrawString(DPY, PIXMAP, GC,
|
46
|
+
FIX2INT(rx), FIX2INT(ry), RSTRING_PTR(rstr), RSTRING_LEN(rstr)
|
47
|
+
);
|
48
|
+
|
49
|
+
return Qnil;
|
50
|
+
}
|
51
|
+
|
52
|
+
VALUE pixmap_gc_black(VALUE self) {
|
53
|
+
SET_PIXMAP(self)
|
54
|
+
|
55
|
+
XSetForeground(DPY, GC, BlackPixel(DPY, SCREEN_DEFAULT));
|
56
|
+
|
57
|
+
return Qnil;
|
58
|
+
}
|
59
|
+
|
60
|
+
VALUE pixmap_gc_color(VALUE self, VALUE rcolor) {
|
61
|
+
SET_PIXMAP(self)
|
62
|
+
|
63
|
+
XSetForeground(DPY, GC, NUM2LONG(rb_funcall(rcolor, rb_intern("pixel"), 0)));
|
64
|
+
|
65
|
+
return Qnil;
|
66
|
+
}
|
67
|
+
|
68
|
+
VALUE pixmap_gc_white(VALUE self) {
|
69
|
+
SET_PIXMAP(self)
|
70
|
+
|
71
|
+
XSetForeground(DPY, GC, WhitePixel(DPY, SCREEN_DEFAULT));
|
72
|
+
|
73
|
+
return Qnil;
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
VALUE pixmap_copy(VALUE self, VALUE rwindow) {
|
78
|
+
SET_PIXMAP(self)
|
79
|
+
|
80
|
+
XCopyArea(DPY, PIXMAP,
|
81
|
+
FIX2INT(rb_funcall(rwindow, rb_intern("id"), 0)),
|
82
|
+
GC,
|
83
|
+
0, 0,
|
84
|
+
FIX2INT(rb_ivar_get(self, rb_intern("@width"))),
|
85
|
+
FIX2INT(rb_ivar_get(self, rb_intern("@height"))),
|
86
|
+
0, 0
|
87
|
+
);
|
88
|
+
|
89
|
+
return Qnil;
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
VALUE pixmap_make(Display *dpy, int w, int h) {
|
94
|
+
UhPixmap *pixmap;
|
95
|
+
VALUE rpixmap;
|
96
|
+
|
97
|
+
rpixmap = Data_Make_Struct(cPixmap, UhPixmap, 0, pixmap_deallocate, pixmap);
|
98
|
+
pixmap->dpy = dpy;
|
99
|
+
pixmap->pixmap = XCreatePixmap(dpy, ROOT_DEFAULT, w, h, DEPTH_DEFAULT);
|
100
|
+
pixmap->gc = XCreateGC(dpy, ROOT_DEFAULT, 0, NULL);
|
101
|
+
|
102
|
+
return rpixmap;
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
void pixmap_deallocate(UhPixmap *pixmap) {
|
107
|
+
XFreePixmap(DPY, PIXMAP);
|
108
|
+
XFreeGC(DPY, GC);
|
109
|
+
free(pixmap);
|
110
|
+
}
|
data/ext/uh/screen.c
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
VALUE screen_init(VALUE self, VALUE rid, VALUE rx, VALUE ry, VALUE rw, VALUE rh) {
|
5
|
+
rb_ivar_set(self, rb_intern("@id"), rid);
|
6
|
+
rb_ivar_set(self, rb_intern("@x"), rx);
|
7
|
+
rb_ivar_set(self, rb_intern("@y"), ry);
|
8
|
+
rb_ivar_set(self, rb_intern("@width"), rw);
|
9
|
+
rb_ivar_set(self, rb_intern("@height"), rh);
|
10
|
+
|
11
|
+
return self;
|
12
|
+
}
|
data/ext/uh/uh.c
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
void uh_color();
|
5
|
+
void uh_display();
|
6
|
+
void uh_events();
|
7
|
+
void uh_font();
|
8
|
+
void uh_pixmap();
|
9
|
+
void uh_screen();
|
10
|
+
void uh_window();
|
11
|
+
|
12
|
+
|
13
|
+
void Init_uh(void) {
|
14
|
+
mUh = rb_define_module("Uh");
|
15
|
+
|
16
|
+
eError = rb_define_class_under(mUh, "Error", rb_eStandardError);
|
17
|
+
eRuntimeError = rb_define_class_under(mUh, "RuntimeError", rb_eRuntimeError);
|
18
|
+
eArgumentError = rb_define_class_under(mUh, "ArgumentError", eError);
|
19
|
+
eDisplayError = rb_define_class_under(mUh, "DisplayError", eRuntimeError);
|
20
|
+
|
21
|
+
uh_color();
|
22
|
+
uh_display();
|
23
|
+
uh_events();
|
24
|
+
uh_font();
|
25
|
+
uh_pixmap();
|
26
|
+
uh_screen();
|
27
|
+
uh_window();
|
28
|
+
}
|
29
|
+
|
30
|
+
void uh_color() {
|
31
|
+
cColor = rb_define_class_under(mUh, "Color", rb_cObject);
|
32
|
+
rb_define_singleton_method(cColor, "new", color_s_new, 2);
|
33
|
+
rb_define_attr(cColor, "name", 1, 0);
|
34
|
+
rb_define_attr(cColor, "pixel", 1, 0);
|
35
|
+
}
|
36
|
+
|
37
|
+
void uh_display() {
|
38
|
+
cDisplay = rb_define_class_under(mUh, "Display", rb_cObject);
|
39
|
+
rb_define_singleton_method(cDisplay, "on_error", display_s_on_error, 0);
|
40
|
+
rb_define_alloc_func(cDisplay, display_alloc);
|
41
|
+
rb_define_attr(cDisplay, "name", 1, 0);
|
42
|
+
rb_define_method(cDisplay, "close", display_close, 0);
|
43
|
+
rb_define_method(cDisplay, "fileno", display_fileno, 0);
|
44
|
+
rb_define_method(cDisplay, "flush", display_flush, 0);
|
45
|
+
rb_define_method(cDisplay, "grab_key", display_grab_key, 2);
|
46
|
+
rb_define_method(cDisplay, "listen_events", display_listen_events, -1);
|
47
|
+
rb_define_method(cDisplay, "each_event", display_each_event, 0);
|
48
|
+
rb_define_method(cDisplay, "next_event", display_next_event, 0);
|
49
|
+
rb_define_method(cDisplay, "open", display_open, 0);
|
50
|
+
rb_define_method(cDisplay, "opened?", display_opened_p, 0);
|
51
|
+
rb_define_method(cDisplay, "pending", display_pending_p, 0);
|
52
|
+
rb_define_method(cDisplay, "root", display_root, 0);
|
53
|
+
rb_define_method(cDisplay, "screens", display_screens, 0);
|
54
|
+
rb_define_method(cDisplay, "sync", display_sync, 1);
|
55
|
+
}
|
56
|
+
|
57
|
+
void uh_events() {
|
58
|
+
mEvents = rb_define_module_under(mUh, "Events");
|
59
|
+
|
60
|
+
cEvent = rb_define_class_under(mEvents, "Event", rb_cObject);
|
61
|
+
rb_define_attr(cEvent, "type", 1, 0);
|
62
|
+
rb_define_attr(cEvent, "window", 1, 0);
|
63
|
+
|
64
|
+
cConfigureRequest = rb_define_class_under(mEvents, "ConfigureRequest", cEvent);
|
65
|
+
rb_define_attr(cConfigureRequest, "x", 1, 0);
|
66
|
+
rb_define_attr(cConfigureRequest, "y", 1, 0);
|
67
|
+
rb_define_attr(cConfigureRequest, "width", 1, 0);
|
68
|
+
rb_define_attr(cConfigureRequest, "height", 1, 0);
|
69
|
+
rb_define_attr(cConfigureRequest, "above_window_id", 1, 0);
|
70
|
+
rb_define_attr(cConfigureRequest, "detail", 1, 0);
|
71
|
+
rb_define_attr(cConfigureRequest, "value_mask", 1, 0);
|
72
|
+
|
73
|
+
cDestroyNotify = rb_define_class_under(mEvents, "DestroyNotify", cEvent);
|
74
|
+
|
75
|
+
cExpose = rb_define_class_under(mEvents, "Expose", cEvent);
|
76
|
+
|
77
|
+
cKeyPress = rb_define_class_under(mEvents, "KeyPress", cEvent);
|
78
|
+
rb_define_attr(cKeyPress, "key", 1, 0);
|
79
|
+
rb_define_attr(cKeyPress, "modifier_mask", 1, 0);
|
80
|
+
|
81
|
+
cKeyRelease = rb_define_class_under(mEvents, "KeyRelease", cEvent);
|
82
|
+
rb_define_attr(cKeyRelease, "key", 1, 0);
|
83
|
+
rb_define_attr(cKeyRelease, "modifier_mask", 1, 0);
|
84
|
+
|
85
|
+
cMapRequest = rb_define_class_under(mEvents, "MapRequest", cEvent);
|
86
|
+
|
87
|
+
cPropertyNotify = rb_define_class_under(mEvents, "PropertyNotify", cEvent);
|
88
|
+
|
89
|
+
cUnmapNotify = rb_define_class_under(mEvents, "UnmapNotify", cEvent);
|
90
|
+
}
|
91
|
+
|
92
|
+
void uh_font() {
|
93
|
+
cFont = rb_define_class_under(mUh, "Font", rb_cObject);
|
94
|
+
rb_define_singleton_method(cFont, "new", font_s_new, 1);
|
95
|
+
rb_define_attr(cFont, "width", 1, 0);
|
96
|
+
rb_define_attr(cFont, "ascent", 1, 0);
|
97
|
+
rb_define_attr(cFont, "descent", 1, 0);
|
98
|
+
}
|
99
|
+
|
100
|
+
void uh_pixmap() {
|
101
|
+
cPixmap = rb_define_class_under(mUh, "Pixmap", rb_cObject);
|
102
|
+
rb_define_singleton_method(cPixmap, "new", pixmap_s_new, 3);
|
103
|
+
rb_define_attr(cPixmap, "width", 1, 0);
|
104
|
+
rb_define_attr(cPixmap, "height", 1, 0);
|
105
|
+
rb_define_method(cPixmap, "copy", pixmap_copy, 1);
|
106
|
+
rb_define_method(cPixmap, "draw_rect", pixmap_draw_rect, 4);
|
107
|
+
rb_define_method(cPixmap, "draw_string", pixmap_draw_string, 3);
|
108
|
+
rb_define_method(cPixmap, "gc_black", pixmap_gc_black, 0);
|
109
|
+
rb_define_method(cPixmap, "gc_color", pixmap_gc_color, 1);
|
110
|
+
rb_define_method(cPixmap, "gc_white", pixmap_gc_white, 0);
|
111
|
+
}
|
112
|
+
|
113
|
+
void uh_screen() {
|
114
|
+
cScreen = rb_define_class_under(mUh, "Screen", rb_cObject);
|
115
|
+
rb_define_method(cScreen, "initialize", screen_init, 5);
|
116
|
+
rb_define_attr(cScreen, "id", 1, 0);
|
117
|
+
rb_define_attr(cScreen, "x", 1, 0);
|
118
|
+
rb_define_attr(cScreen, "y", 1, 0);
|
119
|
+
rb_define_attr(cScreen, "width", 1, 0);
|
120
|
+
rb_define_attr(cScreen, "height", 1, 0);
|
121
|
+
}
|
122
|
+
|
123
|
+
void uh_window() {
|
124
|
+
cWindow = rb_define_class_under(mUh, "Window", rb_cObject);
|
125
|
+
rb_define_singleton_method(cWindow, "new", window_s_new, 2);
|
126
|
+
rb_define_attr(cWindow, "id", 1, 0);
|
127
|
+
rb_define_method(cWindow, "configure", window_configure, 1);
|
128
|
+
rb_define_method(cWindow, "configure_event", window_configure_event, 1);
|
129
|
+
rb_define_method(cWindow, "create", window_create, 1);
|
130
|
+
rb_define_method(cWindow, "create_sub", window_create_sub, 1);
|
131
|
+
rb_define_method(cWindow, "destroy", window_destroy, 0);
|
132
|
+
rb_define_method(cWindow, "focus", window_focus, 0);
|
133
|
+
rb_define_method(cWindow, "icccm_wm_delete", window_icccm_wm_delete, 0);
|
134
|
+
rb_define_method(cWindow, "icccm_wm_protocols", window_icccm_wm_protocols, 0);
|
135
|
+
rb_define_method(cWindow, "kill", window_kill, 0);
|
136
|
+
rb_define_method(cWindow, "map", window_map, 0);
|
137
|
+
rb_define_alias(cWindow, "show", "map");
|
138
|
+
rb_define_method(cWindow, "mask", window_mask, 0);
|
139
|
+
rb_define_method(cWindow, "mask=", window_mask_set, 1);
|
140
|
+
rb_define_method(cWindow, "moveresize", window_moveresize, 1);
|
141
|
+
rb_define_method(cWindow, "name", window_name, 0);
|
142
|
+
rb_define_method(cWindow, "name=", window_name_set, 1);
|
143
|
+
rb_define_method(cWindow, "override_redirect?", window_override_redirect, 0);
|
144
|
+
rb_define_method(cWindow, "raise", window_raise, 0);
|
145
|
+
rb_define_method(cWindow, "unmap", window_unmap, 0);
|
146
|
+
rb_define_method(cWindow, "wclass", window_wclass, 0);
|
147
|
+
}
|
data/ext/uh/uh.h
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
#ifndef RUBY_UH
|
2
|
+
#define RUBY_UH
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
|
6
|
+
#include <X11/Xlib.h>
|
7
|
+
#include <X11/XKBlib.h>
|
8
|
+
#include <X11/Xutil.h>
|
9
|
+
#include <X11/extensions/Xinerama.h>
|
10
|
+
|
11
|
+
|
12
|
+
#define SET_DISPLAY(x) \
|
13
|
+
UhDisplay *display;\
|
14
|
+
Data_Get_Struct(x, UhDisplay, display);
|
15
|
+
|
16
|
+
#define ROOT_DEFAULT DefaultRootWindow(DPY)
|
17
|
+
#define SCREEN_DEFAULT DefaultScreen(DPY)
|
18
|
+
|
19
|
+
|
20
|
+
typedef struct s_display UhDisplay;
|
21
|
+
typedef struct s_pixmap UhPixmap;
|
22
|
+
typedef struct s_window UhWindow;
|
23
|
+
|
24
|
+
struct s_display {
|
25
|
+
Display *dpy;
|
26
|
+
};
|
27
|
+
|
28
|
+
struct s_pixmap {
|
29
|
+
Display *dpy;
|
30
|
+
Pixmap pixmap;
|
31
|
+
GC gc;
|
32
|
+
};
|
33
|
+
|
34
|
+
struct s_window {
|
35
|
+
Display *dpy;
|
36
|
+
Window id;
|
37
|
+
};
|
38
|
+
|
39
|
+
|
40
|
+
VALUE mUh, mEvents,
|
41
|
+
cColor,
|
42
|
+
cDisplay,
|
43
|
+
cEvent, cConfigureRequest, cDestroyNotify, cExpose, cKeyPress, cKeyRelease,
|
44
|
+
cMapRequest, cPropertyNotify, cUnmapNotify,
|
45
|
+
cFont,
|
46
|
+
cPixmap,
|
47
|
+
cScreen,
|
48
|
+
cWindow,
|
49
|
+
eError, eRuntimeError, eArgumentError, eDisplayError;
|
50
|
+
|
51
|
+
|
52
|
+
VALUE color_s_new(VALUE klass, VALUE display, VALUE color_name);
|
53
|
+
|
54
|
+
VALUE display_s_on_error(VALUE klass);
|
55
|
+
VALUE display_alloc(VALUE klass);
|
56
|
+
VALUE display_close(VALUE self);
|
57
|
+
VALUE display_each_event(VALUE self);
|
58
|
+
VALUE display_fileno(VALUE self);
|
59
|
+
VALUE display_flush(VALUE self);
|
60
|
+
VALUE display_grab_key(VALUE self, VALUE key, VALUE modifier);
|
61
|
+
VALUE display_listen_events(int argc, VALUE *argv, VALUE self);
|
62
|
+
VALUE display_next_event(VALUE self);
|
63
|
+
VALUE display_open(VALUE self);
|
64
|
+
VALUE display_opened_p(VALUE self);
|
65
|
+
VALUE display_pending_p(VALUE self);
|
66
|
+
VALUE display_root(VALUE self);
|
67
|
+
VALUE display_root_change_attributes(VALUE self, VALUE mask);
|
68
|
+
VALUE display_screens(VALUE self);
|
69
|
+
VALUE display_sync(VALUE self, VALUE discard);
|
70
|
+
|
71
|
+
VALUE event_make(XEvent *xev);
|
72
|
+
|
73
|
+
VALUE font_s_new(VALUE klass, VALUE rdisplay);
|
74
|
+
|
75
|
+
VALUE pixmap_s_new(VALUE klass, VALUE rdisplay, VALUE rwidth, VALUE rheight);
|
76
|
+
VALUE pixmap_copy(VALUE self, VALUE rwindow);
|
77
|
+
VALUE pixmap_draw_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h);
|
78
|
+
VALUE pixmap_draw_string(VALUE self, VALUE x, VALUE y, VALUE str);
|
79
|
+
VALUE pixmap_gc_black(VALUE self);
|
80
|
+
VALUE pixmap_gc_color(VALUE self, VALUE rcolor);
|
81
|
+
VALUE pixmap_gc_white(VALUE self);
|
82
|
+
VALUE pixmap_make(Display *dpy, int w, int h);
|
83
|
+
|
84
|
+
VALUE screen_init(VALUE self, VALUE id, VALUE x, VALUE y, VALUE w, VALUE h);
|
85
|
+
|
86
|
+
VALUE window_s_new(VALUE klass, VALUE rdisplay, VALUE rwindow_id);
|
87
|
+
VALUE window_configure(VALUE self, VALUE rgeo);
|
88
|
+
VALUE window_configure_event(VALUE self, VALUE rgeo);
|
89
|
+
VALUE window_create(VALUE self, VALUE rgeo);
|
90
|
+
VALUE window_create_sub(VALUE self, VALUE rgeo);
|
91
|
+
VALUE window_destroy(VALUE self);
|
92
|
+
VALUE window_focus(VALUE self);
|
93
|
+
VALUE window_icccm_wm_delete(VALUE self);
|
94
|
+
VALUE window_icccm_wm_protocols(VALUE self);
|
95
|
+
VALUE window_kill(VALUE self);
|
96
|
+
VALUE window_map(VALUE self);
|
97
|
+
VALUE window_mask(VALUE self);
|
98
|
+
VALUE window_mask_set(VALUE self, VALUE mask);
|
99
|
+
VALUE window_moveresize(VALUE self, VALUE rgeo);
|
100
|
+
VALUE window_name(VALUE self);
|
101
|
+
VALUE window_name_set(VALUE self, VALUE name);
|
102
|
+
VALUE window_override_redirect(VALUE self);
|
103
|
+
VALUE window_raise(VALUE self);
|
104
|
+
VALUE window_unmap(VALUE self);
|
105
|
+
VALUE window_wclass(VALUE self);
|
106
|
+
int window_id(VALUE window);
|
107
|
+
VALUE window_make(Display *display, Window window_id);
|
108
|
+
|
109
|
+
|
110
|
+
#endif
|
data/ext/uh/window.c
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
#include "uh.h"
|
2
|
+
|
3
|
+
|
4
|
+
#define SET_WINDOW(x) \
|
5
|
+
UhWindow *window;\
|
6
|
+
Data_Get_Struct(x, UhWindow, window);
|
7
|
+
|
8
|
+
#define DPY window->dpy
|
9
|
+
#define WINDOW window->id
|
10
|
+
|
11
|
+
|
12
|
+
VALUE window_s_new(VALUE klass, VALUE rdisplay, VALUE rwindow_id) {
|
13
|
+
VALUE rwindow;
|
14
|
+
SET_DISPLAY(rdisplay);
|
15
|
+
|
16
|
+
rwindow = window_make(display->dpy, NUM2LONG(rwindow_id));
|
17
|
+
|
18
|
+
return rwindow;
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
VALUE window_configure(VALUE self, VALUE rgeo) {
|
23
|
+
XWindowChanges wc;
|
24
|
+
unsigned int mask;
|
25
|
+
SET_WINDOW(self);
|
26
|
+
|
27
|
+
mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWStackMode;
|
28
|
+
wc.x = FIX2INT(rb_funcall(rgeo, rb_intern("x"), 0));
|
29
|
+
wc.y = FIX2INT(rb_funcall(rgeo, rb_intern("y"), 0));
|
30
|
+
wc.width = FIX2INT(rb_funcall(rgeo, rb_intern("width"), 0));
|
31
|
+
wc.height = FIX2INT(rb_funcall(rgeo, rb_intern("height"), 0));
|
32
|
+
wc.border_width = 0;
|
33
|
+
wc.stack_mode = Above;
|
34
|
+
XConfigureWindow(DPY, WINDOW, mask, &wc);
|
35
|
+
|
36
|
+
return self;
|
37
|
+
}
|
38
|
+
|
39
|
+
VALUE window_configure_event(VALUE self, VALUE rgeo) {
|
40
|
+
XConfigureEvent ev;
|
41
|
+
SET_WINDOW(self);
|
42
|
+
|
43
|
+
ev.type = ConfigureNotify;
|
44
|
+
ev.display = DPY;
|
45
|
+
ev.event = WINDOW;
|
46
|
+
ev.window = WINDOW;
|
47
|
+
ev.x = FIX2INT(rb_funcall(rgeo, rb_intern("x"), 0));
|
48
|
+
ev.y = FIX2INT(rb_funcall(rgeo, rb_intern("y"), 0));
|
49
|
+
ev.width = FIX2INT(rb_funcall(rgeo, rb_intern("width"), 0));
|
50
|
+
ev.height = FIX2INT(rb_funcall(rgeo, rb_intern("height"), 0));
|
51
|
+
ev.border_width = 0;
|
52
|
+
ev.above = None;
|
53
|
+
ev.override_redirect = False;
|
54
|
+
XSendEvent(DPY, WINDOW, False, StructureNotifyMask, (XEvent *)&ev);
|
55
|
+
|
56
|
+
return self;
|
57
|
+
}
|
58
|
+
|
59
|
+
VALUE window_create(VALUE self, VALUE rgeo) {
|
60
|
+
Window win;
|
61
|
+
SET_WINDOW(self);
|
62
|
+
|
63
|
+
win = XCreateSimpleWindow(DPY, WINDOW,
|
64
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("x"), 0)),
|
65
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("y"), 0)),
|
66
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("width"), 0)),
|
67
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("height"), 0)),
|
68
|
+
0, BlackPixel(DPY, SCREEN_DEFAULT), BlackPixel(DPY, SCREEN_DEFAULT)
|
69
|
+
);
|
70
|
+
|
71
|
+
return window_make(DPY, win);
|
72
|
+
}
|
73
|
+
|
74
|
+
VALUE window_create_sub(VALUE self, VALUE rgeo) {
|
75
|
+
XSetWindowAttributes wa;
|
76
|
+
Window sub_win;
|
77
|
+
SET_WINDOW(self);
|
78
|
+
|
79
|
+
wa.override_redirect = True;
|
80
|
+
wa.background_pixmap = ParentRelative;
|
81
|
+
wa.event_mask = ExposureMask;
|
82
|
+
|
83
|
+
sub_win = XCreateWindow(DPY, WINDOW,
|
84
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("x"), 0)),
|
85
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("y"), 0)),
|
86
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("width"), 0)),
|
87
|
+
FIX2INT(rb_funcall(rgeo, rb_intern("height"), 0)),
|
88
|
+
0, CopyFromParent, CopyFromParent, CopyFromParent,
|
89
|
+
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa
|
90
|
+
);
|
91
|
+
|
92
|
+
return window_make(DPY, sub_win);
|
93
|
+
}
|
94
|
+
|
95
|
+
VALUE window_destroy(VALUE self) {
|
96
|
+
SET_WINDOW(self);
|
97
|
+
|
98
|
+
XDestroyWindow(DPY, WINDOW);
|
99
|
+
|
100
|
+
return Qnil;
|
101
|
+
}
|
102
|
+
|
103
|
+
VALUE window_focus(VALUE self) {
|
104
|
+
SET_WINDOW(self);
|
105
|
+
|
106
|
+
XSetInputFocus(DPY, WINDOW, RevertToPointerRoot, CurrentTime);
|
107
|
+
|
108
|
+
return self;
|
109
|
+
}
|
110
|
+
|
111
|
+
VALUE window_icccm_wm_delete(VALUE self) {
|
112
|
+
XEvent xev;
|
113
|
+
SET_WINDOW(self);
|
114
|
+
|
115
|
+
xev.type = ClientMessage;
|
116
|
+
xev.xclient.window = WINDOW;
|
117
|
+
xev.xclient.message_type = XInternAtom(DPY, "WM_PROTOCOLS", False);
|
118
|
+
xev.xclient.format = 32;
|
119
|
+
xev.xclient.data.l[0] = XInternAtom(DPY, "WM_DELETE_WINDOW", False);
|
120
|
+
xev.xclient.data.l[1] = CurrentTime;
|
121
|
+
XSendEvent(DPY, WINDOW, False, NoEventMask, &xev);
|
122
|
+
|
123
|
+
return Qnil;
|
124
|
+
}
|
125
|
+
|
126
|
+
VALUE window_icccm_wm_protocols(VALUE self) {
|
127
|
+
Atom *win_protocols;
|
128
|
+
int count;
|
129
|
+
int i;
|
130
|
+
char *atom_name;
|
131
|
+
VALUE protocols;
|
132
|
+
SET_WINDOW(self);
|
133
|
+
protocols = rb_ary_new();
|
134
|
+
|
135
|
+
if (XGetWMProtocols(DPY, WINDOW, &win_protocols, &count)) {
|
136
|
+
for (i = 0; i < count; i++) {
|
137
|
+
atom_name = XGetAtomName(DPY, win_protocols[i]);
|
138
|
+
rb_ary_push(protocols, ID2SYM(rb_intern(atom_name)));
|
139
|
+
XFree(atom_name);
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
return protocols;
|
144
|
+
}
|
145
|
+
|
146
|
+
VALUE window_kill(VALUE self) {
|
147
|
+
SET_WINDOW(self);
|
148
|
+
|
149
|
+
XKillClient(DPY, WINDOW);
|
150
|
+
|
151
|
+
return Qnil;
|
152
|
+
}
|
153
|
+
|
154
|
+
VALUE window_map(VALUE self) {
|
155
|
+
SET_WINDOW(self);
|
156
|
+
|
157
|
+
XMapWindow(DPY, WINDOW);
|
158
|
+
|
159
|
+
return self;
|
160
|
+
}
|
161
|
+
|
162
|
+
VALUE window_mask(VALUE self) {
|
163
|
+
XWindowAttributes wa;
|
164
|
+
SET_WINDOW(self);
|
165
|
+
|
166
|
+
if (!XGetWindowAttributes(DPY, WINDOW, &wa)) {
|
167
|
+
rb_raise(rb_eArgError, "cannot get window attributes for `0x%08lx'", WINDOW);
|
168
|
+
}
|
169
|
+
|
170
|
+
return LONG2FIX(wa.your_event_mask);
|
171
|
+
}
|
172
|
+
|
173
|
+
VALUE window_mask_set(VALUE self, VALUE mask) {
|
174
|
+
XSetWindowAttributes attrs;
|
175
|
+
SET_WINDOW(self);
|
176
|
+
|
177
|
+
attrs.event_mask = FIX2LONG(mask);
|
178
|
+
XChangeWindowAttributes(DPY, WINDOW, CWEventMask, &attrs);
|
179
|
+
|
180
|
+
return Qnil;
|
181
|
+
}
|
182
|
+
|
183
|
+
VALUE window_moveresize(VALUE self, VALUE rgeo) {
|
184
|
+
XWindowChanges wc;
|
185
|
+
SET_WINDOW(self);
|
186
|
+
|
187
|
+
wc.x = FIX2INT(rb_funcall(rgeo, rb_intern("x"), 0));
|
188
|
+
wc.y = FIX2INT(rb_funcall(rgeo, rb_intern("y"), 0));
|
189
|
+
wc.width = FIX2INT(rb_funcall(rgeo, rb_intern("width"), 0));
|
190
|
+
wc.height = FIX2INT(rb_funcall(rgeo, rb_intern("height"), 0));
|
191
|
+
XConfigureWindow(DPY, WINDOW, CWX | CWY | CWWidth | CWHeight, &wc);
|
192
|
+
|
193
|
+
return self;
|
194
|
+
}
|
195
|
+
|
196
|
+
VALUE window_name(VALUE self) {
|
197
|
+
char *wxname;
|
198
|
+
VALUE wname;
|
199
|
+
SET_WINDOW(self);
|
200
|
+
|
201
|
+
if (!XFetchName(DPY, WINDOW, &wxname))
|
202
|
+
return Qnil;
|
203
|
+
|
204
|
+
wname = rb_str_new_cstr(wxname);
|
205
|
+
XFree(wxname);
|
206
|
+
|
207
|
+
return wname;
|
208
|
+
}
|
209
|
+
|
210
|
+
VALUE window_name_set(VALUE self, VALUE rname) {
|
211
|
+
SET_WINDOW(self);
|
212
|
+
|
213
|
+
StringValue(rname);
|
214
|
+
XStoreName(DPY, WINDOW, RSTRING_PTR(rname));
|
215
|
+
|
216
|
+
return Qnil;
|
217
|
+
}
|
218
|
+
|
219
|
+
VALUE window_override_redirect(VALUE self) {
|
220
|
+
XWindowAttributes wa;
|
221
|
+
SET_WINDOW(self);
|
222
|
+
|
223
|
+
if (!XGetWindowAttributes(DPY, WINDOW, &wa))
|
224
|
+
return Qnil;
|
225
|
+
|
226
|
+
return wa.override_redirect ? Qtrue : Qfalse;
|
227
|
+
}
|
228
|
+
|
229
|
+
VALUE window_raise(VALUE self) {
|
230
|
+
SET_WINDOW(self);
|
231
|
+
|
232
|
+
XRaiseWindow(DPY, WINDOW);
|
233
|
+
|
234
|
+
return self;
|
235
|
+
}
|
236
|
+
|
237
|
+
VALUE window_unmap(VALUE self) {
|
238
|
+
SET_WINDOW(self);
|
239
|
+
|
240
|
+
XUnmapWindow(DPY, WINDOW);
|
241
|
+
|
242
|
+
return self;
|
243
|
+
}
|
244
|
+
|
245
|
+
VALUE window_wclass(VALUE self) {
|
246
|
+
XClassHint ch;
|
247
|
+
VALUE wclass;
|
248
|
+
SET_WINDOW(self);
|
249
|
+
|
250
|
+
if (!XGetClassHint(DPY, WINDOW, &ch))
|
251
|
+
return Qnil;
|
252
|
+
|
253
|
+
wclass = rb_str_new_cstr(ch.res_class);
|
254
|
+
XFree(ch.res_name);
|
255
|
+
XFree(ch.res_class);
|
256
|
+
|
257
|
+
return wclass;
|
258
|
+
}
|
259
|
+
|
260
|
+
|
261
|
+
int window_id(VALUE self) {
|
262
|
+
SET_WINDOW(self);
|
263
|
+
|
264
|
+
return WINDOW;
|
265
|
+
}
|
266
|
+
|
267
|
+
VALUE window_make(Display *display, Window window_id) {
|
268
|
+
UhWindow *window;
|
269
|
+
VALUE obj;
|
270
|
+
|
271
|
+
obj = Data_Make_Struct(cWindow, UhWindow, 0, free, window);
|
272
|
+
window->dpy = display;
|
273
|
+
window->id = window_id;
|
274
|
+
|
275
|
+
rb_ivar_set(obj, rb_intern("@id"), LONG2NUM(window_id));
|
276
|
+
|
277
|
+
return obj;
|
278
|
+
}
|
data/lib/uh/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.pre4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibault Jouan
|
@@ -89,7 +89,16 @@ extra_rdoc_files:
|
|
89
89
|
- README.md
|
90
90
|
files:
|
91
91
|
- README.md
|
92
|
+
- ext/uh/color.c
|
93
|
+
- ext/uh/display.c
|
94
|
+
- ext/uh/event.c
|
92
95
|
- ext/uh/extconf.rb
|
96
|
+
- ext/uh/font.c
|
97
|
+
- ext/uh/pixmap.c
|
98
|
+
- ext/uh/screen.c
|
99
|
+
- ext/uh/uh.c
|
100
|
+
- ext/uh/uh.h
|
101
|
+
- ext/uh/window.c
|
93
102
|
- lib/uh.rb
|
94
103
|
- lib/uh/display.rb
|
95
104
|
- lib/uh/events.rb
|