pure-x11 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile.lock +1 -1
- data/example/test.rb +22 -22
- data/lib/X11/display.rb +178 -144
- data/lib/X11/form.rb +260 -52
- data/lib/X11/type.rb +41 -52
- data/lib/X11/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 927c52f35913e7d8bc466563bb5d238919c4a43d6a9f9fb1be8a6df4735cc5fb
|
4
|
+
data.tar.gz: 3b92ed556881c32486ed189c9de27fdd373988379118fefdbd6f40ff6268c0e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 580ab719f597acaecfa467389f26526dc50c1d25cacb14dbda9d63f61e3cb63f3665fd010408fc093501893a229a4b6a6f314734f6cf35786c58d965d0ec51cd
|
7
|
+
data.tar.gz: 211b56d642b773c29769e9620c746a657596b6314e1d5a89487ace79bf29c6f01f4675ec2456a8668b8723912b2c81f2c95309dcdaf9eac459682150b884f726
|
data/Gemfile.lock
CHANGED
data/example/test.rb
CHANGED
@@ -13,37 +13,37 @@ require 'X11'
|
|
13
13
|
dpy = display = X11::Display.new
|
14
14
|
screen = dpy.screens.first
|
15
15
|
root = screen.root
|
16
|
-
wid = display.new_id
|
17
16
|
|
18
|
-
dpy.create_window(
|
19
|
-
screen.root_depth, wid, root,
|
17
|
+
wid = dpy.create_window(
|
20
18
|
0, 0, # x,y
|
21
19
|
1000, 600, # w,h
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
X11::Form::CWEventMask
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
]
|
20
|
+
# FIXME: WTH isn't depth: 32 working here?
|
21
|
+
depth: 24,
|
22
|
+
values: {
|
23
|
+
X11::Form::CWBackPixel => 0x0,
|
24
|
+
X11::Form::CWEventMask =>
|
25
|
+
(X11::Form::SubstructureNotifyMask |
|
26
|
+
X11::Form::StructureNotifyMask | ## Move
|
27
|
+
X11::Form::ExposureMask |
|
28
|
+
X11::Form::KeyPressMask |
|
29
|
+
X11::Form::ButtonPressMask)
|
30
|
+
}
|
34
31
|
)
|
32
|
+
#dpy.next_packet
|
33
|
+
#exit(0)
|
35
34
|
|
36
35
|
def set_window_opacity(dpy, wid, opacity)
|
37
36
|
dpy.change_property(
|
38
|
-
|
39
|
-
wid,
|
40
|
-
|
41
|
-
[(0xffffffff * opacity).to_i].pack("
|
37
|
+
:replace,
|
38
|
+
wid, "_NET_WM_WINDOW_OPACITY",
|
39
|
+
:cardinal, 32,
|
40
|
+
[(0xffffffff * opacity).to_i].pack("V").unpack("C*")
|
42
41
|
)
|
43
42
|
end
|
44
43
|
|
45
44
|
|
46
45
|
set_window_opacity(dpy, wid, 0.8)
|
46
|
+
|
47
47
|
#p dpy.display_info
|
48
48
|
|
49
49
|
#reply = dpy.query_extension("XKEYBOARD")
|
@@ -143,7 +143,7 @@ def render_glyph(display, wid, x,y, ch)
|
|
143
143
|
#p img
|
144
144
|
# p ch
|
145
145
|
display.put_image(
|
146
|
-
|
146
|
+
:ZPixmap, wid, $gc2,
|
147
147
|
mtx.min_width,mtx.min_height,
|
148
148
|
x, y - mtx.y_offset, 0, depth, data
|
149
149
|
)
|
@@ -158,12 +158,12 @@ def render_str(display, wid, x,y, str)
|
|
158
158
|
end
|
159
159
|
|
160
160
|
def redraw(dpy, wid, gc)
|
161
|
-
dpy.poly_fill_rectangle(wid, gc, [
|
161
|
+
dpy.poly_fill_rectangle(wid, gc, [20,20, 60, 80])
|
162
162
|
dpy.clear_area(false, wid, 30, 30, 5, 5)
|
163
163
|
dpy.image_text16(wid, $gc2, 30, 70, "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ")
|
164
164
|
#"\u25f0\u25ef Hello World")
|
165
165
|
dpy.put_image(
|
166
|
-
|
166
|
+
:ZPixmap, wid, $gc2,
|
167
167
|
$png.width, $png.height, 80, 120, 0, 24, $data
|
168
168
|
)
|
169
169
|
render_str(dpy, wid, 30,90, 'HelloWorld')
|
data/lib/X11/display.rb
CHANGED
@@ -68,6 +68,7 @@ module X11
|
|
68
68
|
def read_error data
|
69
69
|
error = Form::Error.from_packet(StringIO.new(data))
|
70
70
|
STDERR.puts "ERROR: #{error.inspect}"
|
71
|
+
raise error.inspect
|
71
72
|
error
|
72
73
|
end
|
73
74
|
|
@@ -80,28 +81,47 @@ module X11
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def read_event type, data, event_class
|
84
|
+
io = StringIO.new(data)
|
83
85
|
case type
|
84
|
-
|
85
|
-
|
86
|
-
when
|
87
|
-
|
88
|
-
when 4
|
89
|
-
|
90
|
-
when
|
91
|
-
|
92
|
-
when
|
93
|
-
|
94
|
-
when
|
95
|
-
|
96
|
-
when
|
97
|
-
|
98
|
-
when
|
99
|
-
|
100
|
-
when
|
101
|
-
|
86
|
+
# 0 is error, not handled here
|
87
|
+
# 1 is reply, not handled here
|
88
|
+
when 2 then return Form::KeyPress.from_packet(io)
|
89
|
+
when 3 then return Form::KeyRelease.from_packet(io)
|
90
|
+
when 4 then return Form::ButtonPress.from_packet(io)
|
91
|
+
when 5 then return Form::ButtonRelease.from_packet(io)
|
92
|
+
when 6 then return Form::MotionNotify.from_packet(io)
|
93
|
+
when 7 then return Form::EnterNotify.from_packet(io)
|
94
|
+
when 8 then return Form::LeaveNotify.from_packet(io)
|
95
|
+
when 9 then return Form::FocusIn.from_packet(io)
|
96
|
+
when 10 then return Form::FocusOut.from_packet(io)
|
97
|
+
# FIXME 11: KeymapNotify
|
98
|
+
when 12 then return Form::Expose.from_packet(io)
|
99
|
+
# FIXME 13: GraphicsExposure
|
100
|
+
when 14 then return Form::NoExposure.from_packet(io)
|
101
|
+
# FIXME: 15: VisibilityNotify
|
102
|
+
when 16 then return Form::CreateNotify.from_packet(io)
|
103
|
+
when 17 then return Form::DestroyNotify.from_packet(io)
|
104
|
+
when 18 then return Form::UnmapNotify.from_packet(io)
|
105
|
+
when 19 then return Form::MapNotify.from_packet(io)
|
106
|
+
when 20 then return Form::MapRequest.from_packet(io)
|
107
|
+
when 21 then return Form::ReparentNotify.from_packet(io)
|
108
|
+
when 22 then return Form::ConfigureNotify.from_packet(io)
|
109
|
+
when 23 then return Form::ConfigureRequest.from_packet(io)
|
110
|
+
# FIXME: 24: GravityNotify
|
111
|
+
# FIXME: 25: ResizeRequest
|
112
|
+
# FIXME: 26: CirculateNotify
|
113
|
+
# FIXME: 27: CirculateRequest
|
114
|
+
when 28 then return Form::PropertyNotify.from_packet(io)
|
115
|
+
# FIXME: 29: SelectionClear
|
116
|
+
# FIXME: 30: SelectionRequest
|
117
|
+
# FIXME: 31: SelectionNotify
|
118
|
+
# FIXME: 32: ColormapNotify
|
119
|
+
when 33 then return Form::ClientMessage.from_packet(io)
|
120
|
+
# FIXME: 34: MappingNotify
|
102
121
|
else
|
103
122
|
STDERR.puts "FIXME: Event: #{type}"
|
104
123
|
STDERR.puts "EVENT: #{data.inspect}"
|
124
|
+
data
|
105
125
|
end
|
106
126
|
end
|
107
127
|
|
@@ -122,34 +142,41 @@ module X11
|
|
122
142
|
data = read_full_packet(32)
|
123
143
|
return nil if data.nil?
|
124
144
|
|
125
|
-
|
145
|
+
# FIXME: What is bit 8 for? Synthentic?
|
146
|
+
type = data.unpack("C").first & 0x7f
|
126
147
|
case type
|
127
|
-
when 0
|
128
|
-
|
129
|
-
when
|
130
|
-
read_reply(data)
|
131
|
-
when 2..34
|
132
|
-
read_event(type, data, nil)
|
148
|
+
when 0 then read_error(data)
|
149
|
+
when 1 then read_reply(data)
|
150
|
+
when 2..34 then read_event(type, data, nil)
|
133
151
|
else
|
134
|
-
raise ProtocolError, "Unsupported reply type: #{type}"
|
152
|
+
raise ProtocolError, "Unsupported reply type: #{type} #{data.inspect}"
|
135
153
|
end
|
136
154
|
end
|
137
155
|
|
156
|
+
def write_raw_packet(pkt)
|
157
|
+
@requestseq += 1
|
158
|
+
@socket.write(pkt)
|
159
|
+
end
|
160
|
+
|
161
|
+
def write_packet(*args)
|
162
|
+
pkt = args.join
|
163
|
+
pkt[2..3] = u16(pkt.length/4)
|
164
|
+
write_raw_packet(pkt)
|
165
|
+
end
|
166
|
+
|
138
167
|
def write_request ob
|
139
|
-
#p data
|
140
|
-
#p [:write_request, @requestseq, ob.class]
|
141
168
|
data = ob.to_packet if ob.respond_to?(:to_packet)
|
142
|
-
#p [:AddGlyph,data] if ob.is_a?(X11::Form::XRenderAddGlyphs)
|
143
|
-
#p [ob.request_length.to_i*4, data.size]
|
144
169
|
raise "BAD LENGTH for #{ob.inspect} (#{ob.request_length.to_i*4} ! #{data.size} " if ob.request_length && ob.request_length.to_i*4 != data.size
|
145
|
-
|
146
|
-
@socket.write(data)
|
170
|
+
write_raw_packet(data)
|
147
171
|
end
|
148
172
|
|
149
173
|
def write_sync(data, reply=nil)
|
174
|
+
seq = @requestseq
|
150
175
|
write_request(data)
|
151
|
-
pkt = next_reply
|
176
|
+
pkt = next_reply(seq)
|
152
177
|
return nil if !pkt
|
178
|
+
return pkt if pkt.is_a?(X11::Form::Error)
|
179
|
+
pp reply
|
153
180
|
reply ? reply.from_packet(StringIO.new(pkt)) : pkt
|
154
181
|
end
|
155
182
|
|
@@ -161,17 +188,19 @@ module X11
|
|
161
188
|
@queue.shift || read_packet
|
162
189
|
end
|
163
190
|
|
164
|
-
def next_reply
|
191
|
+
def next_reply(errseq)
|
165
192
|
# FIXME: This is totally broken
|
166
193
|
while pkt = read_packet
|
167
194
|
if pkt.is_a?(String)
|
168
195
|
return pkt
|
196
|
+
elsif pkt.is_a?(X11::Form::Error) && pkt.sequence_number == errseq
|
197
|
+
return pkt
|
169
198
|
else
|
170
199
|
@queue.push(pkt)
|
171
200
|
end
|
172
201
|
end
|
173
202
|
end
|
174
|
-
|
203
|
+
|
175
204
|
def run
|
176
205
|
loop do
|
177
206
|
pkt = read_packet
|
@@ -193,12 +222,10 @@ module X11
|
|
193
222
|
wid = new_id
|
194
223
|
parent ||= screens.first.root
|
195
224
|
|
196
|
-
|
197
225
|
if visual.nil?
|
198
226
|
visual = find_visual(0, depth).visual_id
|
199
227
|
end
|
200
228
|
|
201
|
-
|
202
229
|
values[X11::Form::CWColorMap] ||= create_colormap(0, parent, visual)
|
203
230
|
|
204
231
|
values = values.sort_by{_1[0]}
|
@@ -212,26 +239,30 @@ module X11
|
|
212
239
|
return wid
|
213
240
|
end
|
214
241
|
|
242
|
+
def get_window_attributes(wid)
|
243
|
+
write_sync( Form::GetWindowAttributes.new(wid), Form::WindowAttributes )
|
244
|
+
end
|
245
|
+
|
215
246
|
def change_window_attributes(wid,
|
216
247
|
values: {})
|
217
248
|
values = values.sort_by{_1[0]}
|
218
249
|
mask = values.inject(0) {|acc,v| (acc | v[0]) }
|
219
250
|
values = values.map{_1[1]}
|
220
|
-
write_request(
|
221
|
-
X11::Form::ChangeWindowAttributes.new(wid, mask, values)
|
222
|
-
)
|
251
|
+
write_request(Form::ChangeWindowAttributes.new(wid, mask, values))
|
223
252
|
end
|
224
253
|
|
254
|
+
def select_input(w, events) = change_window_attributes(w, values: {Form::CWEventMask => events})
|
255
|
+
|
225
256
|
def atom(name)
|
257
|
+
return name if name.is_a?(Integer) # Allow atom(atom_integer_or_symbol)
|
258
|
+
name = name.to_sym
|
226
259
|
intern_atom(false, name) if !@atoms[name]
|
227
260
|
@atoms[name]
|
228
261
|
end
|
229
262
|
|
230
263
|
def query_extension(name)
|
231
|
-
r = write_sync(
|
232
|
-
@extensions[name] = {
|
233
|
-
major: r.major_opcode
|
234
|
-
}
|
264
|
+
r = write_sync(Form::QueryExtension.new(name), Form::QueryExtensionReply)
|
265
|
+
@extensions[name] = { major: r.major_opcode }
|
235
266
|
r
|
236
267
|
end
|
237
268
|
|
@@ -244,66 +275,106 @@ module X11
|
|
244
275
|
end
|
245
276
|
|
246
277
|
def intern_atom(flag, name)
|
247
|
-
reply = write_sync(
|
248
|
-
X11::Form::InternAtomReply)
|
278
|
+
reply = write_sync(Form::InternAtom.new(flag, name.to_s),Form::InternAtomReply)
|
249
279
|
if reply
|
250
280
|
@atoms[name.to_sym] = reply.atom
|
251
281
|
end
|
252
282
|
end
|
253
283
|
|
254
|
-
def
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
def get_geometry(drawable)
|
259
|
-
write_sync(X11::Form::GetGeometry.new(drawable), X11::Form::Geometry)
|
260
|
-
end
|
284
|
+
def get_atom_name(atom) = write_sync(Form::GetAtomName.new(atom), Form::AtomName)&.name
|
285
|
+
def destroy_window(window) = write_request(Form::DestroyWindow.new(window))
|
286
|
+
def get_geometry(drawable) = write_sync(Form::GetGeometry.new(drawable), Form::Geometry)
|
261
287
|
|
262
288
|
def get_keyboard_mapping(min_keycode=display_info.min_keycode, count= display_info.max_keycode - min_keycode)
|
263
|
-
write_sync(
|
289
|
+
write_sync(Form::GetKeyboardMapping.new(min_keycode, count), Form::GetKeyboardMappingReply)
|
264
290
|
end
|
265
291
|
|
266
292
|
def create_colormap(alloc, window, visual)
|
267
293
|
mid = new_id
|
268
|
-
write_request(
|
294
|
+
write_request(Form::CreateColormap.new(alloc, mid, window, visual))
|
269
295
|
mid
|
270
296
|
end
|
271
297
|
|
272
|
-
def
|
273
|
-
|
298
|
+
def get_property(window, property, type, offset: 0, length: 4, delete: false)
|
299
|
+
property = atom(property)
|
300
|
+
type = atom_enum(type)
|
301
|
+
|
302
|
+
result = write_sync(Form::GetProperty.new(
|
303
|
+
delete, window, property, type, offset, length
|
304
|
+
), Form::Property)
|
305
|
+
|
306
|
+
if result && result.format != 0
|
307
|
+
case result.format
|
308
|
+
when 16
|
309
|
+
result.value = result.value.unpack("v")
|
310
|
+
result.value = result.value.first if length == 2
|
311
|
+
when 32
|
312
|
+
result.value = result.value.unpack("V")
|
313
|
+
result.value = result.value.first if length == 4
|
314
|
+
end
|
315
|
+
elsif result
|
316
|
+
result.value = nil
|
317
|
+
end
|
318
|
+
result
|
274
319
|
end
|
320
|
+
|
321
|
+
def change_property(mode, window, property, type, format, data)
|
322
|
+
property = atom(property.to_sym) if property.is_a?(Symbol) || property.is_a?(String)
|
275
323
|
|
276
|
-
|
277
|
-
|
278
|
-
|
324
|
+
mode = open_enum(mode, {replace: 0, prepend: 1, append: 2})
|
325
|
+
type = atom_enum(type)
|
326
|
+
write_request(Form::ChangeProperty.new(mode, window, property, type, format, data))
|
279
327
|
end
|
280
328
|
|
281
|
-
def
|
282
|
-
write_request(
|
329
|
+
def list_fonts(...) = write_sync(Form::ListFonts.new(...), Form::ListFontsReply)
|
330
|
+
def open_font(...) = write_request(Form::OpenFont.new(...))
|
331
|
+
def change_gc(...) = write_request(Form::ChangeGC.new(...))
|
332
|
+
def change_save_set(...)= write_request(Form::ChangeSaveSet.new(...))
|
333
|
+
|
334
|
+
def reparent_window(window, parent, x, y, save: true)
|
335
|
+
# You so almost always want this that it should've been a single request
|
336
|
+
change_save_set(0, window) if save
|
337
|
+
write_request(Form::ReparentWindow.new(window, parent, x,y))
|
283
338
|
end
|
339
|
+
|
340
|
+
def map_window(...) = write_request(Form::MapWindow.new(...))
|
341
|
+
def unmap_window(...) = write_request(Form::UnmapWindow.new(...))
|
284
342
|
|
285
|
-
def
|
286
|
-
|
343
|
+
def u8(*args) = args.pack("c*")
|
344
|
+
def u16(*args) = args.pack("v*")
|
345
|
+
def u32(*args) = args.pack("V*")
|
346
|
+
def atom_enum(val) = open_enum(val, {cardinal: Form::CardinalAtom, atom: Form::AtomAtom, window: Form::WindowAtom})
|
347
|
+
def window(*args)
|
348
|
+
args.each {|a| raise "Window expected" if a.nil? }
|
349
|
+
u32(*args)
|
287
350
|
end
|
288
351
|
|
289
|
-
def
|
290
|
-
|
352
|
+
def open_enum(val, map) = (map[val].nil? ? val : map[val])
|
353
|
+
|
354
|
+
def set_input_focus(revert_to, focus, time=:now)
|
355
|
+
# FIXME: This is an experiment.
|
356
|
+
# Upside: Simpler. Downside: Doesn't work server-side.
|
357
|
+
#
|
358
|
+
revert_to = open_enum(revert_to, {none: 0, pointer_root: 1, parent: 2})
|
359
|
+
focus = open_enum(focus, {none: 0, pointer_root: 1 })
|
360
|
+
time = open_enum(time, {current_time: 0, now: 0})
|
361
|
+
write_packet(u8(42,revert_to), u16(3), window(focus), u32(time))
|
291
362
|
end
|
292
363
|
|
293
364
|
def grab_key(owner_events, grab_window, modifiers, keycode, pointer_mode, keyboard_mode)
|
294
|
-
write_request(
|
365
|
+
write_request(Form::GrabKey.new(
|
295
366
|
owner_events,
|
296
367
|
grab_window,
|
297
368
|
modifiers,
|
298
369
|
keycode,
|
299
|
-
pointer_mode
|
370
|
+
pointer_mode == :async ? 1 : 0,
|
300
371
|
keyboard_mode == :async ? 1 : 0
|
301
372
|
))
|
302
373
|
end
|
303
374
|
|
304
375
|
def grab_button(owner_events, grab_window, event_mask, pointer_mode,
|
305
376
|
keyboard_mode, confine_to, cursor, button, modifiers)
|
306
|
-
write_request(
|
377
|
+
write_request(Form::GrabButton.new(
|
307
378
|
owner_events, grab_window, event_mask,
|
308
379
|
pointer_mode == :async ? 1 : 0,
|
309
380
|
keyboard_mode == :async ? 1 : 0,
|
@@ -311,41 +382,27 @@ module X11
|
|
311
382
|
)
|
312
383
|
end
|
313
384
|
|
385
|
+
def set_value(values, mask, x)
|
386
|
+
if x
|
387
|
+
values << x
|
388
|
+
mask
|
389
|
+
else
|
390
|
+
0
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
314
394
|
def configure_window(window, x: nil, y: nil, width: nil, height: nil,
|
315
395
|
border_width: nil, sibling: nil, stack_mode: nil)
|
316
396
|
|
317
397
|
mask = 0
|
318
398
|
values = []
|
319
399
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
mask |= 0x002
|
327
|
-
values << y
|
328
|
-
end
|
329
|
-
|
330
|
-
if width
|
331
|
-
mask |= 0x004
|
332
|
-
values << width
|
333
|
-
end
|
334
|
-
|
335
|
-
if height
|
336
|
-
mask |= 0x008
|
337
|
-
values << height
|
338
|
-
end
|
339
|
-
|
340
|
-
if border_width
|
341
|
-
mask |= 0x010
|
342
|
-
values << border_width
|
343
|
-
end
|
344
|
-
|
345
|
-
if sibling
|
346
|
-
mask |= 0x020
|
347
|
-
values << sibling
|
348
|
-
end
|
400
|
+
mask |= set_value(values, 0x001, x)
|
401
|
+
mask |= set_value(values, 0x002, y)
|
402
|
+
mask |= set_value(values, 0x004, width)
|
403
|
+
mask |= set_value(values, 0x008, height)
|
404
|
+
mask |= set_value(values, 0x010, border_width)
|
405
|
+
mask |= set_value(values, 0x020, sibling)
|
349
406
|
|
350
407
|
if stack_mode
|
351
408
|
mask |= 0x040
|
@@ -354,7 +411,7 @@ module X11
|
|
354
411
|
when :below then 1
|
355
412
|
when :top_if then 2
|
356
413
|
when :bottom_if then 3
|
357
|
-
when
|
414
|
+
when :opposite then 4
|
358
415
|
else raise "Unknown stack_mode #{stack_mode.inspect}"
|
359
416
|
end
|
360
417
|
end
|
@@ -369,49 +426,26 @@ module X11
|
|
369
426
|
# FIXME:
|
370
427
|
# The rest can be found here:
|
371
428
|
# https://tronche.com/gui/x/xlib/GC/manipulating.html#XGCValues
|
372
|
-
|
373
|
-
|
374
|
-
args << foreground
|
375
|
-
end
|
376
|
-
if background
|
377
|
-
mask |= 0x08
|
378
|
-
args << background
|
379
|
-
end
|
380
|
-
|
429
|
+
mask |= set_value(args, 0x04, foreground)
|
430
|
+
mask |= set_value(args, 0x08, background)
|
381
431
|
|
382
432
|
gc = new_id
|
383
433
|
write_request(X11::Form::CreateGC.new(gc, window, mask, args))
|
384
434
|
gc
|
385
435
|
end
|
386
436
|
|
387
|
-
def put_image(*args)
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
def
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
def copy_area(*args)
|
396
|
-
write_request(X11::Form::CopyArea.new(*args))
|
397
|
-
end
|
398
|
-
|
399
|
-
def image_text8(*args)
|
400
|
-
write_request(X11::Form::ImageText8.new(*args))
|
401
|
-
end
|
402
|
-
|
403
|
-
def image_text16(*args)
|
404
|
-
write_request(X11::Form::ImageText16.new(*args))
|
405
|
-
end
|
406
|
-
|
407
|
-
def poly_fill_rectangle(*args)
|
408
|
-
write_request(X11::Form::PolyFillRectangle.new(*args))
|
437
|
+
def put_image(*args) = write_request(X11::Form::PutImage.new(*args))
|
438
|
+
def clear_area(*args) = write_request(X11::Form::ClearArea.new(*args))
|
439
|
+
def copy_area(*args) = write_request(X11::Form::CopyArea.new(*args))
|
440
|
+
def image_text8(*args) = write_request(X11::Form::ImageText8.new(*args))
|
441
|
+
def image_text16(*args)= write_request(X11::Form::ImageText16.new(*args))
|
442
|
+
def poly_fill_rectangle(wid, gc, *rects)
|
443
|
+
rects = rects.map{|r| r.is_a?(Array) ? Form::Rectangle.new(*r) : r}
|
444
|
+
write_request(X11::Form::PolyFillRectangle.new(wid, gc, rects))
|
409
445
|
end
|
410
446
|
|
411
447
|
def create_pixmap(depth, drawable, w,h)
|
412
|
-
pid
|
413
|
-
write_request(X11::Form::CreatePixmap.new(depth, pid, drawable, w,h))
|
414
|
-
pid
|
448
|
+
new_id.tap{|pid| write_request(Form::CreatePixmap.new(depth, pid, drawable, w,h)) }
|
415
449
|
end
|
416
450
|
|
417
451
|
# XRender
|
@@ -437,8 +471,8 @@ module X11
|
|
437
471
|
|
438
472
|
def render_query_pict_formats
|
439
473
|
@render_formats ||= write_sync(
|
440
|
-
|
441
|
-
|
474
|
+
Form::XRenderQueryPictFormats.new(render_opcode),
|
475
|
+
Form::XRenderQueryPictFormatsReply
|
442
476
|
)
|
443
477
|
end
|
444
478
|
|
@@ -459,26 +493,26 @@ module X11
|
|
459
493
|
case sym
|
460
494
|
when :a8
|
461
495
|
@a8 ||= formats.formats.find do |f|
|
462
|
-
f.type
|
496
|
+
f.type == 1 &&
|
463
497
|
f.depth == 8 &&
|
464
498
|
f.direct.alpha_mask == 255
|
465
499
|
end
|
466
500
|
when :rgb24
|
467
501
|
@rgb24 ||= formats.formats.find do |f|
|
468
|
-
f.type
|
469
|
-
f.depth
|
470
|
-
f.direct.red
|
502
|
+
f.type == 1 &&
|
503
|
+
f.depth == 24 &&
|
504
|
+
f.direct.red == 16 &&
|
471
505
|
f.direct.green == 8 &&
|
472
|
-
f.direct.blue
|
506
|
+
f.direct.blue == 0
|
473
507
|
end
|
474
508
|
when :argb24
|
475
509
|
@argb24 ||= formats.formats.find do |f|
|
476
|
-
f.type
|
477
|
-
f.depth
|
510
|
+
f.type == 1 &&
|
511
|
+
f.depth == 32 &&
|
478
512
|
f.direct.alpha == 24 &&
|
479
|
-
f.direct.red
|
513
|
+
f.direct.red == 16 &&
|
480
514
|
f.direct.green == 8 &&
|
481
|
-
f.direct.blue
|
515
|
+
f.direct.blue == 0
|
482
516
|
end
|
483
517
|
else
|
484
518
|
raise "Unsupported format (a4/a1 by omission)"
|
data/lib/X11/form.rb
CHANGED
@@ -65,13 +65,6 @@ module X11
|
|
65
65
|
|
66
66
|
if value.is_a?(BaseForm)
|
67
67
|
v = value.to_packet
|
68
|
-
elsif value.is_a?(Symbol)
|
69
|
-
#if !@atoms[value]
|
70
|
-
# reply = write_sync(X11::Forms::InternAtom.new(false, value.to_s), X11::Forms::InternAtomReply)
|
71
|
-
# @
|
72
|
-
#end
|
73
|
-
#value = @atoms[value]
|
74
|
-
raise "FIXME"
|
75
68
|
else
|
76
69
|
#p [s,value]
|
77
70
|
v = s.type_klass.pack(value)
|
@@ -81,14 +74,14 @@ module X11
|
|
81
74
|
when :unused
|
82
75
|
sz = s.size.respond_to?(:call) ? s.size.call(self) : s.size
|
83
76
|
"\x00" * sz
|
84
|
-
when :length
|
77
|
+
when :length, :format_length
|
85
78
|
#p [s,value]
|
86
79
|
#p [value.size]
|
87
80
|
s.type_klass.pack(value.size)
|
88
81
|
when :string
|
89
82
|
s.type_klass.pack(value)
|
90
83
|
when :list
|
91
|
-
value.collect do |obj|
|
84
|
+
Array(value).collect do |obj|
|
92
85
|
if obj.is_a?(BaseForm)
|
93
86
|
obj.to_packet
|
94
87
|
else
|
@@ -127,8 +120,17 @@ module X11
|
|
127
120
|
when :length
|
128
121
|
size = s.type_klass.unpack( socket.read(s.type_klass.size) )
|
129
122
|
lengths[s.name] = size
|
123
|
+
when :format_length
|
124
|
+
size = s.type_klass.unpack( socket.read(s.type_klass.size) )
|
125
|
+
lengths[s.name] = case form.format
|
126
|
+
when 8 then size
|
127
|
+
when 16 then size*2
|
128
|
+
when 32 then size*4
|
129
|
+
else 0
|
130
|
+
end
|
130
131
|
when :string
|
131
|
-
|
132
|
+
len = lengths[s.name]
|
133
|
+
val = s.type_klass.unpack(socket, len)
|
132
134
|
form.instance_variable_set("@#{s.name}", val)
|
133
135
|
when :list
|
134
136
|
len = lengths[s.name]
|
@@ -177,12 +179,14 @@ module X11
|
|
177
179
|
end
|
178
180
|
|
179
181
|
def fields
|
180
|
-
super+Array(@structs).dup.delete_if{|s| s.type == :unused or s.type == :length }
|
182
|
+
super+Array(@structs).dup.delete_if{|s| s.type == :unused or s.type == :length or s.type == :format_length}
|
181
183
|
end
|
182
184
|
end
|
183
185
|
end
|
184
186
|
|
187
|
+
AtomAtom=4
|
185
188
|
CardinalAtom=6
|
189
|
+
WindowAtom=33
|
186
190
|
|
187
191
|
##
|
188
192
|
## X11 Packet Defintions
|
@@ -247,9 +251,9 @@ module X11
|
|
247
251
|
end
|
248
252
|
|
249
253
|
class DisplayInfo < BaseForm
|
250
|
-
field :release_number,
|
251
|
-
field :resource_id_base,
|
252
|
-
field :resource_id_mask,
|
254
|
+
field :release_number, Uint32
|
255
|
+
field :resource_id_base, Uint32
|
256
|
+
field :resource_id_mask, Uint32
|
253
257
|
field :motion_buffer_size, Uint32
|
254
258
|
field :vendor, Uint16, :length
|
255
259
|
field :maximum_request_length, Uint16
|
@@ -258,11 +262,11 @@ module X11
|
|
258
262
|
field :image_byte_order, Signifigance
|
259
263
|
field :bitmap_bit_order, Signifigance
|
260
264
|
field :bitmap_format_scanline_unit, Uint8
|
261
|
-
field :bitmap_format_scanline_pad,
|
265
|
+
field :bitmap_format_scanline_pad, Uint8
|
262
266
|
field :min_keycode, KeyCode
|
263
267
|
field :max_keycode, KeyCode
|
264
268
|
unused 4
|
265
|
-
field :vendor,
|
269
|
+
field :vendor, String8, :string
|
266
270
|
field :formats, FormatInfo, :list
|
267
271
|
field :screens, ScreenInfo, :list
|
268
272
|
end
|
@@ -287,13 +291,13 @@ module X11
|
|
287
291
|
# XRender structures
|
288
292
|
|
289
293
|
class DirectFormat < BaseForm
|
290
|
-
field :red,
|
291
|
-
field :red_mask,
|
292
|
-
field :green,
|
294
|
+
field :red, Uint16
|
295
|
+
field :red_mask, Uint16
|
296
|
+
field :green, Uint16
|
293
297
|
field :green_mask, Uint16
|
294
|
-
field :blue,
|
295
|
-
field :blue_mask,
|
296
|
-
field :alpha,
|
298
|
+
field :blue, Uint16
|
299
|
+
field :blue_mask, Uint16
|
300
|
+
field :alpha, Uint16
|
297
301
|
field :alpha_mask, Uint16
|
298
302
|
end
|
299
303
|
|
@@ -328,8 +332,8 @@ module X11
|
|
328
332
|
# Requests
|
329
333
|
|
330
334
|
CopyFromParent = 0
|
331
|
-
InputOutput
|
332
|
-
InputOnly
|
335
|
+
InputOutput = 1
|
336
|
+
InputOnly = 2
|
333
337
|
|
334
338
|
CWBackPixmap = 0x0001
|
335
339
|
CWBackPixel = 0x0002
|
@@ -337,23 +341,29 @@ module X11
|
|
337
341
|
CWBorderPixel = 0x0008
|
338
342
|
CWBitGravity = 0x0010
|
339
343
|
CWWinGravity = 0x0020
|
340
|
-
CWBackingStore= 0x0040
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
344
|
+
CWBackingStore = 0x0040
|
345
|
+
CWBackingPlanes = 0x0080
|
346
|
+
CWBackingPixel = 0x0100
|
347
|
+
CWOverrideRedirect = 0x0200
|
348
|
+
CWSaveUnder = 0x0400
|
349
|
+
CWEventMask = 0x0800
|
350
|
+
CWColorMap = 0x2000
|
351
|
+
|
352
|
+
KeyPressMask = 0x000001
|
353
|
+
KeyReleaseMask = 0x000002
|
354
|
+
ButtonPressMask = 0x000004
|
355
|
+
ButtonReleaseMask = 0x000008
|
356
|
+
EnterWindowMask = 0x000010
|
357
|
+
LeaveWindowMask = 0x000020
|
358
|
+
PointerMotionMask = 0x000040
|
359
|
+
PointerMotionHintMask = 0x000080
|
360
|
+
Button1MotionMask = 0x000100
|
361
|
+
ExposureMask = 0x008000
|
362
|
+
StructureNotifyMask = 0x020000
|
363
|
+
SubstructureNotifyMask = 0x080000
|
364
|
+
SubstructureRedirectMask=0x100000
|
365
|
+
FocusChangeMask = 0x200000
|
366
|
+
PropertyChangeMask = 0x400000
|
357
367
|
|
358
368
|
class CreateWindow < BaseForm
|
359
369
|
field :opcode, Uint8, value: 1
|
@@ -394,14 +404,14 @@ module X11
|
|
394
404
|
field :sequence_number, Uint16
|
395
405
|
field :reply_length, Uint32
|
396
406
|
field :visual, VisualID
|
397
|
-
field :
|
407
|
+
field :wclass, Uint16
|
398
408
|
field :bit_gravity, Uint8
|
399
409
|
field :win_gravity, Uint8
|
400
410
|
field :backing_planes, Uint32
|
401
411
|
field :backing_pixel, Uint32
|
402
412
|
field :save_under, Bool
|
403
413
|
field :map_is_installed, Bool
|
404
|
-
field :map_state,
|
414
|
+
field :map_state, Uint8
|
405
415
|
field :override_redirect, Bool
|
406
416
|
field :colormap, Colormap
|
407
417
|
field :all_event_masks, Uint32
|
@@ -417,6 +427,23 @@ module X11
|
|
417
427
|
field :window, Window
|
418
428
|
end
|
419
429
|
|
430
|
+
class ChangeSaveSet < BaseForm
|
431
|
+
field :opcode, Uint8, value: 6
|
432
|
+
field :mode, Uint8
|
433
|
+
field :request_length, Uint16, value: 2
|
434
|
+
field :window, Window
|
435
|
+
end
|
436
|
+
|
437
|
+
class ReparentWindow < BaseForm
|
438
|
+
field :opcode, Uint8, value: 7
|
439
|
+
unused 1
|
440
|
+
field :request_length, Uint16, value: 4
|
441
|
+
field :window, Window
|
442
|
+
field :parent, Window
|
443
|
+
field :x, Int16
|
444
|
+
field :y, Int16
|
445
|
+
end
|
446
|
+
|
420
447
|
class MapWindow < BaseForm
|
421
448
|
field :opcode, Uint8, value: 8
|
422
449
|
unused 1
|
@@ -424,6 +451,13 @@ module X11
|
|
424
451
|
field :window, Window
|
425
452
|
end
|
426
453
|
|
454
|
+
class UnmapWindow < BaseForm
|
455
|
+
field :opcode, Uint8, value: 10
|
456
|
+
unused 1
|
457
|
+
field :request_length, Uint16, value: 2
|
458
|
+
field :window, Window
|
459
|
+
end
|
460
|
+
|
427
461
|
class ConfigureWindow < BaseForm
|
428
462
|
field :opcode, Uint8, value: 12
|
429
463
|
unused 1
|
@@ -455,6 +489,25 @@ module X11
|
|
455
489
|
unused 10
|
456
490
|
end
|
457
491
|
|
492
|
+
class QueryTree < BaseForm
|
493
|
+
field :opcode, Uint8, value: 15
|
494
|
+
unused 1
|
495
|
+
field :request_length, Uint16, value: 2
|
496
|
+
field :window, Window
|
497
|
+
end
|
498
|
+
|
499
|
+
class QueryTreeReply < BaseForm
|
500
|
+
field :reply, Uint8, value: 1
|
501
|
+
unused 1
|
502
|
+
field :sequence_number, Uint16
|
503
|
+
field :reply_length, Uint32
|
504
|
+
field :root, Window
|
505
|
+
field :parent, Window
|
506
|
+
field :children, Uint16, :length
|
507
|
+
unused 14
|
508
|
+
field :children, Window, :list
|
509
|
+
end
|
510
|
+
|
458
511
|
class InternAtom < BaseForm
|
459
512
|
field :opcode, Uint8, value: 16
|
460
513
|
field :only_if_exists, Bool
|
@@ -480,6 +533,22 @@ module X11
|
|
480
533
|
unused 20
|
481
534
|
end
|
482
535
|
|
536
|
+
class GetAtomName < BaseForm
|
537
|
+
field :opcode, Uint8, value: 17
|
538
|
+
unused 1
|
539
|
+
field :request_length, Uint16, value: 2
|
540
|
+
field :atom, Atom
|
541
|
+
end
|
542
|
+
|
543
|
+
class AtomName < Reply
|
544
|
+
unused 1
|
545
|
+
field :sequence_number, Uint16
|
546
|
+
field :reply_length, Uint32
|
547
|
+
field :name, Uint16, :length
|
548
|
+
unused 22
|
549
|
+
field :name, String8, :string
|
550
|
+
end
|
551
|
+
|
483
552
|
Replace = 0
|
484
553
|
Prepend = 1
|
485
554
|
Append = 2
|
@@ -496,12 +565,33 @@ module X11
|
|
496
565
|
field :type, Atom
|
497
566
|
field :format, Uint8
|
498
567
|
unused 3
|
499
|
-
field :data, Uint32, value: ->(cp) {
|
500
|
-
cp.data.length / 4
|
501
|
-
}
|
568
|
+
field :data, Uint32, value: ->(cp) { cp.data.length / (cp.format/8) }
|
502
569
|
field :data, Uint8, :list
|
503
570
|
end
|
504
571
|
|
572
|
+
class GetProperty < BaseForm
|
573
|
+
field :opcode, Uint8, value: 20
|
574
|
+
field :delete, Bool
|
575
|
+
field :request_length, Uint16, value: 6
|
576
|
+
field :window, Window
|
577
|
+
field :property, Atom
|
578
|
+
field :type, Atom
|
579
|
+
field :long_offset, Uint32
|
580
|
+
field :long_length, Uint32
|
581
|
+
end
|
582
|
+
|
583
|
+
class Property < BaseForm
|
584
|
+
field :reply, Uint8, value: 1
|
585
|
+
field :format, Uint8
|
586
|
+
field :sequence_number, Uint16
|
587
|
+
field :reply_length, Uint32
|
588
|
+
field :type, Atom
|
589
|
+
field :bytes_after, Uint32
|
590
|
+
field :value, Uint32, :format_length
|
591
|
+
unused 12
|
592
|
+
field :value, String8, :string
|
593
|
+
end
|
594
|
+
|
505
595
|
class GrabButton < BaseForm
|
506
596
|
field :opcode, Uint8, value: 28
|
507
597
|
field :owner_events, Bool
|
@@ -528,6 +618,18 @@ module X11
|
|
528
618
|
field :keyboard_mode, Uint8
|
529
619
|
unused 3
|
530
620
|
end
|
621
|
+
|
622
|
+
class OpenFont < BaseForm
|
623
|
+
field :opcode, Uint8, value: 45
|
624
|
+
unused 1
|
625
|
+
field :request_length, Uint16, value: ->(of) {
|
626
|
+
3+(of.name.length+3)/4
|
627
|
+
}
|
628
|
+
field :fid, Font
|
629
|
+
field :name, Uint16, :length
|
630
|
+
unused 2
|
631
|
+
field :name, String8, :string
|
632
|
+
end
|
531
633
|
|
532
634
|
class ListFonts < BaseForm
|
533
635
|
field :opcode, Uint8, value: 49
|
@@ -618,11 +720,11 @@ module X11
|
|
618
720
|
field :src_drawable, Drawable
|
619
721
|
field :dst_drawable, Drawable
|
620
722
|
field :gc, Gcontext
|
621
|
-
field :src_x,
|
622
|
-
field :src_y,
|
623
|
-
field :dst_x,
|
624
|
-
field :dst_y,
|
625
|
-
field :width,
|
723
|
+
field :src_x, Uint16
|
724
|
+
field :src_y, Uint16
|
725
|
+
field :dst_x, Uint16
|
726
|
+
field :dst_y, Uint16
|
727
|
+
field :width, Uint16
|
626
728
|
field :height, Uint16
|
627
729
|
end
|
628
730
|
|
@@ -754,7 +856,7 @@ module X11
|
|
754
856
|
field :sequence_number, Uint16
|
755
857
|
end
|
756
858
|
|
757
|
-
class
|
859
|
+
class InputEvent < SimpleEvent
|
758
860
|
field :time, Uint32
|
759
861
|
field :root, Window
|
760
862
|
field :event, Window
|
@@ -764,6 +866,32 @@ module X11
|
|
764
866
|
field :event_x, Int16
|
765
867
|
field :event_y, Int16
|
766
868
|
field :state, Uint16
|
869
|
+
end
|
870
|
+
|
871
|
+
class EnterLeaveNotify < InputEvent
|
872
|
+
field :mode, Uint8
|
873
|
+
field :same_screen_or_focus, Uint8
|
874
|
+
|
875
|
+
def same_screen = same_screen_or_focus.anybit?(0x02)
|
876
|
+
def focus = same_screen_or_focus.anybit?(0x01)
|
877
|
+
end
|
878
|
+
|
879
|
+
class EnterNotify < EnterLeaveNotify
|
880
|
+
end
|
881
|
+
|
882
|
+
class LeaveNotify < EnterLeaveNotify
|
883
|
+
end
|
884
|
+
|
885
|
+
class FocusIn < SimpleEvent
|
886
|
+
field :event, Window
|
887
|
+
field :mode, Uint8
|
888
|
+
unused 23
|
889
|
+
end
|
890
|
+
|
891
|
+
class FocusOut < FocusIn
|
892
|
+
end
|
893
|
+
|
894
|
+
class PressEvent < InputEvent
|
767
895
|
field :same_screen, Bool
|
768
896
|
unused 1
|
769
897
|
end
|
@@ -782,6 +910,31 @@ module X11
|
|
782
910
|
|
783
911
|
class ButtonRelease < PressEvent
|
784
912
|
end
|
913
|
+
|
914
|
+
class ReparentNotify < SimpleEvent
|
915
|
+
field :event, Window
|
916
|
+
field :window, Window
|
917
|
+
field :parent, Window
|
918
|
+
field :x, Int16
|
919
|
+
field :y, Int16
|
920
|
+
field :override_redirect, Bool
|
921
|
+
unused 11
|
922
|
+
end
|
923
|
+
|
924
|
+
class ConfigureRequest < Event # 23
|
925
|
+
field :stack_mode, Uint8
|
926
|
+
field :sequence_number, Uint16
|
927
|
+
field :parent, Window
|
928
|
+
field :window, Window
|
929
|
+
field :sibling, Window
|
930
|
+
field :x, Int16
|
931
|
+
field :y, Int16
|
932
|
+
field :width, Uint16
|
933
|
+
field :height, Uint16
|
934
|
+
field :border_width, Uint16
|
935
|
+
field :value_mask, Uint16
|
936
|
+
unused 4
|
937
|
+
end
|
785
938
|
|
786
939
|
class Expose < SimpleEvent
|
787
940
|
field :window, Window
|
@@ -800,14 +953,51 @@ module X11
|
|
800
953
|
unused 21
|
801
954
|
end
|
802
955
|
|
956
|
+
class CreateNotify < SimpleEvent # 16
|
957
|
+
field :parent, Window
|
958
|
+
field :window, Window
|
959
|
+
field :x, Int16
|
960
|
+
field :y, Int16
|
961
|
+
field :width, Uint16
|
962
|
+
field :height, Uint16
|
963
|
+
field :border_width, Uint16
|
964
|
+
field :override_redirect, Bool
|
965
|
+
end
|
966
|
+
|
967
|
+
class DestroyNotify < Event
|
968
|
+
unused 1
|
969
|
+
field :sequence_number, Uint16
|
970
|
+
field :event, Window
|
971
|
+
field :window, Window
|
972
|
+
unused 20
|
973
|
+
end
|
974
|
+
|
975
|
+
class UnmapNotify < Event
|
976
|
+
unused 1
|
977
|
+
field :sequence_number, Uint16
|
978
|
+
field :event, Window
|
979
|
+
field :window, Window
|
980
|
+
field :from_configure, Bool
|
981
|
+
unused 19
|
982
|
+
end
|
983
|
+
|
803
984
|
class MapNotify < Event
|
804
985
|
unused 1
|
805
986
|
field :sequence_number, Uint16
|
806
987
|
field :event, Window
|
988
|
+
field :window, Window
|
807
989
|
field :override_redirect, Bool
|
808
990
|
unused 19
|
809
991
|
end
|
810
992
|
|
993
|
+
class MapRequest < Event
|
994
|
+
unused 1
|
995
|
+
field :sequence_number, Uint16
|
996
|
+
field :parent, Window
|
997
|
+
field :window, Window
|
998
|
+
unused 20
|
999
|
+
end
|
1000
|
+
|
811
1001
|
class ConfigureNotify < Event
|
812
1002
|
unused 1
|
813
1003
|
field :sequence_number, Uint16
|
@@ -822,6 +1012,24 @@ module X11
|
|
822
1012
|
unused 5
|
823
1013
|
end
|
824
1014
|
|
1015
|
+
class ClientMessage < Event
|
1016
|
+
field :format, Uint8
|
1017
|
+
field :sequence_number, Uint16
|
1018
|
+
field :window, Window
|
1019
|
+
field :type, Atom
|
1020
|
+
field :data, X11::Type::Message
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
class PropertyNotify < Event # 28
|
1024
|
+
unused 1
|
1025
|
+
field :sequence_number, Uint16
|
1026
|
+
field :window, Window
|
1027
|
+
field :atom, Atom
|
1028
|
+
field :time, Uint32
|
1029
|
+
field :state, Uint8
|
1030
|
+
unused 15
|
1031
|
+
end
|
1032
|
+
|
825
1033
|
|
826
1034
|
# XRender extension
|
827
1035
|
# From https://cgit.freedesktop.org/xorg/proto/renderproto/tree/renderproto.h
|
data/lib/X11/type.rb
CHANGED
@@ -1,51 +1,54 @@
|
|
1
1
|
# This module is used for encoding Ruby Objects to binary
|
2
2
|
# data. The types Int8, Int16, etc. are data-types defined
|
3
|
-
# in the X11 protocol.
|
4
|
-
# which gets evaluated when a packet is created.
|
3
|
+
# in the X11 protocol.
|
5
4
|
|
6
5
|
module X11
|
7
6
|
module Type
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def self.pack(x)
|
13
|
-
[x].pack(\"#{directive}\")
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.unpack(x)
|
17
|
-
x.unpack(\"#{directive}\").first
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.size
|
21
|
-
#{bytesize}
|
22
|
-
end
|
8
|
+
class BaseType
|
9
|
+
@directive = nil
|
10
|
+
@bytesize = nil
|
23
11
|
|
24
|
-
|
25
|
-
|
26
|
-
|
12
|
+
def self.config(d,b) = (@directive, @bytesize = d,b)
|
13
|
+
|
14
|
+
def self.pack(x)
|
15
|
+
if x.is_a?(Symbol)
|
16
|
+
if (t = X11::Form.const_get(x)) && t.is_a?(Numeric)
|
17
|
+
x = t
|
27
18
|
end
|
28
19
|
end
|
29
|
-
|
30
|
-
|
20
|
+
[x].pack(@directive)
|
21
|
+
rescue TypeError => e
|
22
|
+
raise "Expected #{self.name}, got #{x.class} (value: #{x})"
|
23
|
+
end
|
31
24
|
|
25
|
+
def self.unpack(x) = x.nil? ? nil : x.unpack1(@directive)
|
26
|
+
def self.size = @bytesize
|
27
|
+
def self.from_packet(sock) = unpack(sock.read(size))
|
28
|
+
end
|
29
|
+
|
32
30
|
# Primitive Types
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
class Int8 < BaseType; config("c",1); end
|
32
|
+
class Int16 < BaseType; config("s",2); end
|
33
|
+
class Int32 < BaseType; config("l",4); end
|
34
|
+
class Uint8 < BaseType; config("C",1); end
|
35
|
+
class Uint16 < BaseType; config("S",2); end
|
36
|
+
class Uint32 < BaseType; config("L",4); end
|
37
|
+
|
38
|
+
class Message
|
39
|
+
def self.pack(x) = x.b
|
40
|
+
def self.unpack(x) = x.b
|
41
|
+
def self.size = 20
|
42
|
+
def self.from_packet(sock) = sock.read(2).b
|
43
|
+
end
|
39
44
|
|
40
45
|
class String8
|
41
46
|
def self.pack(x)
|
42
|
-
x.
|
47
|
+
x.b + "\x00"*(-x.length & 3)
|
43
48
|
end
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
50
|
def self.unpack(socket, size)
|
51
|
+
raise "Expected size for String8" if size.nil?
|
49
52
|
val = socket.read(size)
|
50
53
|
unused_padding = (4 - (size % 4)) % 4
|
51
54
|
socket.read(unused_padding)
|
@@ -55,7 +58,7 @@ module X11
|
|
55
58
|
|
56
59
|
class String16
|
57
60
|
def self.pack(x)
|
58
|
-
x.encode("UTF-16BE").
|
61
|
+
x.encode("UTF-16BE").b + "\x00\x00"*(-x.length & 1)
|
59
62
|
end
|
60
63
|
|
61
64
|
def self.unpack(socket, size)
|
@@ -68,28 +71,14 @@ module X11
|
|
68
71
|
|
69
72
|
|
70
73
|
class String8Unpadded
|
71
|
-
def self.pack(x)
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
def self.unpack(socket, size)
|
77
|
-
val = socket.read(size)
|
78
|
-
end
|
74
|
+
def self.pack(x) = x
|
75
|
+
def self.unpack(socket, size) = socket.read(size)
|
79
76
|
end
|
80
|
-
|
77
|
+
|
81
78
|
class Bool
|
82
|
-
def self.pack(x)
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
def self.unpack(str)
|
87
|
-
str[0] == "\x01"
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.size
|
91
|
-
1
|
92
|
-
end
|
79
|
+
def self.pack(x) = (x ? "\x01" : "\x00")
|
80
|
+
def self.unpack(str) = (str[0] == "\x01")
|
81
|
+
def self.size = 1
|
93
82
|
end
|
94
83
|
|
95
84
|
KeyCode = Uint8
|
data/lib/X11/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pure-x11
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vidar Hokstad
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Pure Ruby X11 bindings
|
15
15
|
email:
|