uh 2.0.0.pre3 → 2.0.0.pre4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|