pure-x11 0.0.4 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51d974fee51d60b334a5e5f26bb5e0d90f8628e09930da7bb6c97145b3718ed9
4
- data.tar.gz: 2312f1c9f7e0d2b5391bb15aab15805e802635d53d6fe1d90cf22f0c2112b117
3
+ metadata.gz: 0ecd289a7ec4a0a7f44bba1d05a437774ca6ed3d4c403b572b28a8691ef2a950
4
+ data.tar.gz: ac9460f0c0db0635e33358550176802119db88c9bb4dee097807f21c970f68ba
5
5
  SHA512:
6
- metadata.gz: 226fbfc35ff75f2fa95fabf09a7d0e4c72cd99f1678cd607e8421ed26750118e40291686a582c01b0ae296dfcefc5e7038bd3d3025f9b678e5a1fa35c2465135
7
- data.tar.gz: 69363b78df087ea43799f06c8477d008d15b721bcd604a52e1eb3b33411a102fcf4d33f3262ac0c0de5fa76de9262d489eaaca85e043f5251bb41563959970fd
6
+ metadata.gz: db23062260daabe75bfe5a9f419772be329023777c405ae7bb3a08125b9942f63ec8d635c1c11869648272d2c3ecad16a432fbca2d4d584d80ad2dbf15250d5a
7
+ data.tar.gz: f303d01e2c4b43fa2c5d44af4e469288684887c3efe71ee644275f233d584b9e342f9ebd80374632afe1199ad0d4182cebb515a95a7408b79aa36d239c9c9ffb
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
- 0,
23
- X11::Form::InputOutput,
24
- X11::Form::CopyFromParent,
25
- X11::Form::CWBackPixel |
26
- X11::Form::CWEventMask,
27
- [0x0, # RGB background
28
- X11::Form::SubstructureNotifyMask |
29
- X11::Form::StructureNotifyMask | ## Move
30
- X11::Form::ExposureMask |
31
- X11::Form::KeyPressMask |
32
- X11::Form::ButtonPressMask
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
- X11::Form::Replace,
39
- wid, dpy.atom(:_NET_WM_WINDOW_OPACITY),
40
- X11::Form::CardinalAtom, 32,
41
- [(0xffffffff * opacity).to_i].pack("N").split(//).map(&:ord)
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")
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
- when 2
85
- return Form::KeyPress.from_packet(StringIO.new(data))
86
- when 3
87
- return Form::KeyRelease.from_packet(StringIO.new(data))
88
- when 4
89
- return Form::ButtonPress.from_packet(StringIO.new(data))
90
- when 5
91
- return Form::ButtonRelease.from_packet(StringIO.new(data))
92
- when 6
93
- return Form::MotionNotify.from_packet(StringIO.new(data))
94
- when 12
95
- return Form::Expose.from_packet(StringIO.new(data))
96
- when 14
97
- return Form::NoExposure.from_packet(StringIO.new(data))
98
- when 19
99
- return Form::MapNotify.from_packet(StringIO.new(data))
100
- when 22
101
- return Form::ConfigureNotify.from_packet(StringIO.new(data))
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(StringIO.new(data))
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,19 +142,28 @@ module X11
122
142
  data = read_full_packet(32)
123
143
  return nil if data.nil?
124
144
 
125
- type = data.unpack("C").first
145
+ # FIXME: What is bit 8 for? Synthentic?
146
+ type = data.unpack("C").first & 0x7f
126
147
  case type
127
- when 0
128
- read_error(data)
129
- when 1
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
168
  #p data
140
169
  #p [:write_request, @requestseq, ob.class]
@@ -142,14 +171,16 @@ module X11
142
171
  #p [:AddGlyph,data] if ob.is_a?(X11::Form::XRenderAddGlyphs)
143
172
  #p [ob.request_length.to_i*4, data.size]
144
173
  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
- @requestseq += 1
146
- @socket.write(data)
174
+ write_raw_packet(data)
147
175
  end
148
176
 
149
177
  def write_sync(data, reply=nil)
178
+ seq = @requestseq
150
179
  write_request(data)
151
- pkt = next_reply
180
+ pkt = next_reply(seq)
152
181
  return nil if !pkt
182
+ return pkt if pkt.is_a?(X11::Form::Error)
183
+ pp reply
153
184
  reply ? reply.from_packet(StringIO.new(pkt)) : pkt
154
185
  end
155
186
 
@@ -161,17 +192,19 @@ module X11
161
192
  @queue.shift || read_packet
162
193
  end
163
194
 
164
- def next_reply
195
+ def next_reply(errseq)
165
196
  # FIXME: This is totally broken
166
197
  while pkt = read_packet
167
198
  if pkt.is_a?(String)
168
199
  return pkt
200
+ elsif pkt.is_a?(X11::Form::Error) && pkt.sequence_number == errseq
201
+ return pkt
169
202
  else
170
203
  @queue.push(pkt)
171
204
  end
172
205
  end
173
206
  end
174
-
207
+
175
208
  def run
176
209
  loop do
177
210
  pkt = read_packet
@@ -193,12 +226,10 @@ module X11
193
226
  wid = new_id
194
227
  parent ||= screens.first.root
195
228
 
196
-
197
229
  if visual.nil?
198
230
  visual = find_visual(0, depth).visual_id
199
231
  end
200
232
 
201
-
202
233
  values[X11::Form::CWColorMap] ||= create_colormap(0, parent, visual)
203
234
 
204
235
  values = values.sort_by{_1[0]}
@@ -212,6 +243,10 @@ module X11
212
243
  return wid
213
244
  end
214
245
 
246
+ def get_window_attributes(wid)
247
+ write_sync( Form::GetWindowAttributes.new(wid), Form::WindowAttributes )
248
+ end
249
+
215
250
  def change_window_attributes(wid,
216
251
  values: {})
217
252
  values = values.sort_by{_1[0]}
@@ -222,7 +257,10 @@ module X11
222
257
  )
223
258
  end
224
259
 
260
+ def select_input(w, events) = change_window_attributes(w, values: {Form::CWEventMask => events})
261
+
225
262
  def atom(name)
263
+ name = name.to_sym
226
264
  intern_atom(false, name) if !@atoms[name]
227
265
  @atoms[name]
228
266
  end
@@ -251,13 +289,13 @@ module X11
251
289
  end
252
290
  end
253
291
 
254
- def destroy_window(window)
255
- write_request(X11::Form::DestroyWindow.new(window))
256
- end
257
-
258
- def get_geometry(drawable)
259
- write_sync(X11::Form::GetGeometry.new(drawable), X11::Form::Geometry)
292
+ def get_atom_name(atom)
293
+ reply = write_sync(X11::Form::GetAtomName.new(atom), X11::Form::AtomName)
294
+ reply&.name
260
295
  end
296
+
297
+ def destroy_window(window) = write_request(X11::Form::DestroyWindow.new(window))
298
+ def get_geometry(drawable) = write_sync(X11::Form::GetGeometry.new(drawable), X11::Form::Geometry)
261
299
 
262
300
  def get_keyboard_mapping(min_keycode=display_info.min_keycode, count= display_info.max_keycode - min_keycode)
263
301
  write_sync(X11::Form::GetKeyboardMapping.new(min_keycode, count), X11::Form::GetKeyboardMappingReply)
@@ -269,8 +307,35 @@ module X11
269
307
  mid
270
308
  end
271
309
 
272
- def change_property(*args)
273
- write_request(X11::Form::ChangeProperty.new(*args))
310
+ def get_property(window, property, type, offset: 0, length: 4, delete: false)
311
+ property = atom(property) if !property.is_a?(Integer)
312
+ type = atom_enum(type)
313
+
314
+ result = write_sync(X11::Form::GetProperty.new(
315
+ delete, window, property, type, offset, length
316
+ ), X11::Form::Property)
317
+
318
+ if result && result.format != 0
319
+ case result.format
320
+ when 16
321
+ result.value = result.value.unpack("v")
322
+ result.value = result.value.first if length == 2
323
+ when 32
324
+ result.value = result.value.unpack("V")
325
+ result.value = result.value.first if length == 4
326
+ end
327
+ elsif result
328
+ result.value = nil
329
+ end
330
+ result
331
+ end
332
+
333
+ def change_property(mode, window, property, type, format, data)
334
+ property = atom(property.to_sym) if property.is_a?(Symbol) || property.is_a?(String)
335
+
336
+ mode = open_enum(mode, {replace: 0, prepend: 1, append: 2})
337
+ type = atom_enum(type)
338
+ write_request(X11::Form::ChangeProperty.new(mode, window, property, type, format, data))
274
339
  end
275
340
 
276
341
  def list_fonts(*args)
@@ -278,25 +343,46 @@ module X11
278
343
  X11::Form::ListFontsReply)
279
344
  end
280
345
 
281
- def open_font(*args)
282
- write_request(X11::Form::OpenFont.new(*args))
346
+ def open_font(*args) = write_request(X11::Form::OpenFont.new(*args))
347
+ def change_gc(*args) = write_request(X11::Form::ChangeGC.new(*args))
348
+ def change_save_set(...)= write_request(X11::Form::ChangeSaveSet.new(...))
349
+ def reparent_window(window, parent, x, y, save: true)
350
+ # You so almost always want this that it should've been a single request
351
+ change_save_set(0, window) if save
352
+ write_request(X11::Form::ReparentWindow.new(window, parent, x,y))
283
353
  end
354
+
355
+ def map_window(*args) = write_request(X11::Form::MapWindow.new(*args))
356
+ def unmap_window(*args) = write_request(X11::Form::UnmapWindow.new(*args))
284
357
 
285
- def change_gc(*args)
286
- write_request(X11::Form::ChangeGC.new(*args))
358
+ def u8(*args) = args.pack("c*")
359
+ def u16(*args) = args.pack("v*")
360
+ def u32(*args) = args.pack("V*")
361
+ def atom_enum(val) = open_enum(val, {cardinal: Form::CardinalAtom, atom: Form::AtomAtom, window: Form::WindowAtom})
362
+ def window(*args)
363
+ args.each {|a| raise "Window expected" if a.nil? }
364
+ u32(*args)
287
365
  end
288
366
 
289
- def map_window(*args)
290
- write_request(X11::Form::MapWindow.new(*args))
367
+ def open_enum(val, map) = (map[val].nil? ? val : map[val])
368
+
369
+ def set_input_focus(revert_to, focus, time=:now)
370
+ # FIXME: This is an experiment.
371
+ # Upside: Simpler. Downside: Doesn't work server-side.
372
+ #
373
+ revert_to = open_enum(revert_to, {none: 0, pointer_root: 1, parent: 2})
374
+ focus = open_enum(focus, {none: 0, pointer_root: 1 })
375
+ time = open_enum(time, {current_time: 0, now: 0})
376
+ write_packet(u8(42,revert_to), u16(3), window(focus), u32(time))
291
377
  end
292
-
378
+
293
379
  def grab_key(owner_events, grab_window, modifiers, keycode, pointer_mode, keyboard_mode)
294
380
  write_request(X11::Form::GrabKey.new(
295
381
  owner_events,
296
382
  grab_window,
297
383
  modifiers,
298
384
  keycode,
299
- pointer_mode == :async ? 1 : 0,
385
+ pointer_mode == :async ? 1 : 0,
300
386
  keyboard_mode == :async ? 1 : 0
301
387
  ))
302
388
  end
@@ -354,7 +440,7 @@ module X11
354
440
  when :below then 1
355
441
  when :top_if then 2
356
442
  when :bottom_if then 3
357
- when :opposite then 4
443
+ when :opposite then 4
358
444
  else raise "Unknown stack_mode #{stack_mode.inspect}"
359
445
  end
360
446
  end
@@ -384,29 +470,12 @@ module X11
384
470
  gc
385
471
  end
386
472
 
387
- def put_image(*args)
388
- write_request(X11::Form::PutImage.new(*args))
389
- end
390
-
391
- def clear_area(*args)
392
- write_request(X11::Form::ClearArea.new(*args))
393
- end
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))
409
- end
473
+ def put_image(*args) = write_request(X11::Form::PutImage.new(*args))
474
+ def clear_area(*args) = write_request(X11::Form::ClearArea.new(*args))
475
+ def copy_area(*args) = write_request(X11::Form::CopyArea.new(*args))
476
+ def image_text8(*args) = write_request(X11::Form::ImageText8.new(*args))
477
+ def image_text16(*args)= write_request(X11::Form::ImageText16.new(*args))
478
+ def poly_fill_rectangle(*args) = write_request(X11::Form::PolyFillRectangle.new(*args))
410
479
 
411
480
  def create_pixmap(depth, drawable, w,h)
412
481
  pid = new_id
data/lib/X11/form.rb CHANGED
@@ -81,14 +81,14 @@ module X11
81
81
  when :unused
82
82
  sz = s.size.respond_to?(:call) ? s.size.call(self) : s.size
83
83
  "\x00" * sz
84
- when :length
84
+ when :length, :format_length
85
85
  #p [s,value]
86
86
  #p [value.size]
87
87
  s.type_klass.pack(value.size)
88
88
  when :string
89
89
  s.type_klass.pack(value)
90
90
  when :list
91
- value.collect do |obj|
91
+ Array(value).collect do |obj|
92
92
  if obj.is_a?(BaseForm)
93
93
  obj.to_packet
94
94
  else
@@ -127,8 +127,17 @@ module X11
127
127
  when :length
128
128
  size = s.type_klass.unpack( socket.read(s.type_klass.size) )
129
129
  lengths[s.name] = size
130
+ when :format_length
131
+ size = s.type_klass.unpack( socket.read(s.type_klass.size) )
132
+ lengths[s.name] = case form.format
133
+ when 8 then size
134
+ when 16 then size*2
135
+ when 32 then size*4
136
+ else 0
137
+ end
130
138
  when :string
131
- val = s.type_klass.unpack(socket, lengths[s.name])
139
+ len = lengths[s.name]
140
+ val = s.type_klass.unpack(socket, len)
132
141
  form.instance_variable_set("@#{s.name}", val)
133
142
  when :list
134
143
  len = lengths[s.name]
@@ -177,12 +186,14 @@ module X11
177
186
  end
178
187
 
179
188
  def fields
180
- super+Array(@structs).dup.delete_if{|s| s.type == :unused or s.type == :length }
189
+ super+Array(@structs).dup.delete_if{|s| s.type == :unused or s.type == :length or s.type == :format_length}
181
190
  end
182
191
  end
183
192
  end
184
193
 
194
+ AtomAtom=4
185
195
  CardinalAtom=6
196
+ WindowAtom=33
186
197
 
187
198
  ##
188
199
  ## X11 Packet Defintions
@@ -247,9 +258,9 @@ module X11
247
258
  end
248
259
 
249
260
  class DisplayInfo < BaseForm
250
- field :release_number, Uint32
251
- field :resource_id_base, Uint32
252
- field :resource_id_mask, Uint32
261
+ field :release_number, Uint32
262
+ field :resource_id_base, Uint32
263
+ field :resource_id_mask, Uint32
253
264
  field :motion_buffer_size, Uint32
254
265
  field :vendor, Uint16, :length
255
266
  field :maximum_request_length, Uint16
@@ -258,11 +269,11 @@ module X11
258
269
  field :image_byte_order, Signifigance
259
270
  field :bitmap_bit_order, Signifigance
260
271
  field :bitmap_format_scanline_unit, Uint8
261
- field :bitmap_format_scanline_pad, Uint8
272
+ field :bitmap_format_scanline_pad, Uint8
262
273
  field :min_keycode, KeyCode
263
274
  field :max_keycode, KeyCode
264
275
  unused 4
265
- field :vendor, String8, :string
276
+ field :vendor, String8, :string
266
277
  field :formats, FormatInfo, :list
267
278
  field :screens, ScreenInfo, :list
268
279
  end
@@ -287,13 +298,13 @@ module X11
287
298
  # XRender structures
288
299
 
289
300
  class DirectFormat < BaseForm
290
- field :red, Uint16
291
- field :red_mask, Uint16
292
- field :green, Uint16
301
+ field :red, Uint16
302
+ field :red_mask, Uint16
303
+ field :green, Uint16
293
304
  field :green_mask, Uint16
294
- field :blue, Uint16
295
- field :blue_mask, Uint16
296
- field :alpha, Uint16
305
+ field :blue, Uint16
306
+ field :blue_mask, Uint16
307
+ field :alpha, Uint16
297
308
  field :alpha_mask, Uint16
298
309
  end
299
310
 
@@ -328,8 +339,8 @@ module X11
328
339
  # Requests
329
340
 
330
341
  CopyFromParent = 0
331
- InputOutput = 1
332
- InputOnly = 2
342
+ InputOutput = 1
343
+ InputOnly = 2
333
344
 
334
345
  CWBackPixmap = 0x0001
335
346
  CWBackPixel = 0x0002
@@ -337,23 +348,29 @@ module X11
337
348
  CWBorderPixel = 0x0008
338
349
  CWBitGravity = 0x0010
339
350
  CWWinGravity = 0x0020
340
- CWBackingStore= 0x0040
341
- CWSaveUnder = 0x0400
342
- CWEventMask = 0x0800
343
- CWColorMap = 0x2000
344
-
345
- KeyPressMask = 0x00001
346
- KeyReleaseMask = 0x00002
347
- ButtonPressMask = 0x00004
348
- ButtonReleaseMask = 0x00008
349
- EnterWindowMask = 0x00010
350
- LeaveWindowMask = 0x00020
351
- PointerMotionMask = 0x00040
352
- PointerMotionHintMask = 0x00080
353
- Button1MotionMask = 0x00100
354
- ExposureMask = 0x08000
355
- StructureNotifyMask = 0x20000
356
- SubstructureNotifyMask = 0x80000
351
+ CWBackingStore = 0x0040
352
+ CWBackingPlanes = 0x0080
353
+ CWBackingPixel = 0x0100
354
+ CWOverrideRedirect = 0x0200
355
+ CWSaveUnder = 0x0400
356
+ CWEventMask = 0x0800
357
+ CWColorMap = 0x2000
358
+
359
+ KeyPressMask = 0x000001
360
+ KeyReleaseMask = 0x000002
361
+ ButtonPressMask = 0x000004
362
+ ButtonReleaseMask = 0x000008
363
+ EnterWindowMask = 0x000010
364
+ LeaveWindowMask = 0x000020
365
+ PointerMotionMask = 0x000040
366
+ PointerMotionHintMask = 0x000080
367
+ Button1MotionMask = 0x000100
368
+ ExposureMask = 0x008000
369
+ StructureNotifyMask = 0x020000
370
+ SubstructureNotifyMask = 0x080000
371
+ SubstructureRedirectMask=0x100000
372
+ FocusChangeMask = 0x200000
373
+ PropertyChangeMask = 0x400000
357
374
 
358
375
  class CreateWindow < BaseForm
359
376
  field :opcode, Uint8, value: 1
@@ -394,14 +411,14 @@ module X11
394
411
  field :sequence_number, Uint16
395
412
  field :reply_length, Uint32
396
413
  field :visual, VisualID
397
- field :class, Uint16
414
+ field :wclass, Uint16
398
415
  field :bit_gravity, Uint8
399
416
  field :win_gravity, Uint8
400
417
  field :backing_planes, Uint32
401
418
  field :backing_pixel, Uint32
402
419
  field :save_under, Bool
403
420
  field :map_is_installed, Bool
404
- field :map_state, Bool
421
+ field :map_state, Uint8
405
422
  field :override_redirect, Bool
406
423
  field :colormap, Colormap
407
424
  field :all_event_masks, Uint32
@@ -417,6 +434,23 @@ module X11
417
434
  field :window, Window
418
435
  end
419
436
 
437
+ class ChangeSaveSet < BaseForm
438
+ field :opcode, Uint8, value: 6
439
+ field :mode, Uint8
440
+ field :request_length, Uint16, value: 2
441
+ field :window, Window
442
+ end
443
+
444
+ class ReparentWindow < BaseForm
445
+ field :opcode, Uint8, value: 7
446
+ unused 1
447
+ field :request_length, Uint16, value: 4
448
+ field :window, Window
449
+ field :parent, Window
450
+ field :x, Int16
451
+ field :y, Int16
452
+ end
453
+
420
454
  class MapWindow < BaseForm
421
455
  field :opcode, Uint8, value: 8
422
456
  unused 1
@@ -424,6 +458,13 @@ module X11
424
458
  field :window, Window
425
459
  end
426
460
 
461
+ class UnmapWindow < BaseForm
462
+ field :opcode, Uint8, value: 10
463
+ unused 1
464
+ field :request_length, Uint16, value: 2
465
+ field :window, Window
466
+ end
467
+
427
468
  class ConfigureWindow < BaseForm
428
469
  field :opcode, Uint8, value: 12
429
470
  unused 1
@@ -455,6 +496,25 @@ module X11
455
496
  unused 10
456
497
  end
457
498
 
499
+ class QueryTree < BaseForm
500
+ field :opcode, Uint8, value: 15
501
+ unused 1
502
+ field :request_length, Uint16, value: 2
503
+ field :window, Window
504
+ end
505
+
506
+ class QueryTreeReply < BaseForm
507
+ field :reply, Uint8, value: 1
508
+ unused 1
509
+ field :sequence_number, Uint16
510
+ field :reply_length, Uint32
511
+ field :root, Window
512
+ field :parent, Window
513
+ field :children, Uint16, :length
514
+ unused 14
515
+ field :children, Window, :list
516
+ end
517
+
458
518
  class InternAtom < BaseForm
459
519
  field :opcode, Uint8, value: 16
460
520
  field :only_if_exists, Bool
@@ -480,6 +540,22 @@ module X11
480
540
  unused 20
481
541
  end
482
542
 
543
+ class GetAtomName < BaseForm
544
+ field :opcode, Uint8, value: 17
545
+ unused 1
546
+ field :request_length, Uint16, value: 2
547
+ field :atom, Atom
548
+ end
549
+
550
+ class AtomName < Reply
551
+ unused 1
552
+ field :sequence_number, Uint16
553
+ field :reply_length, Uint32
554
+ field :name, Uint16, :length
555
+ unused 22
556
+ field :name, String8, :string
557
+ end
558
+
483
559
  Replace = 0
484
560
  Prepend = 1
485
561
  Append = 2
@@ -496,12 +572,33 @@ module X11
496
572
  field :type, Atom
497
573
  field :format, Uint8
498
574
  unused 3
499
- field :data, Uint32, value: ->(cp) {
500
- cp.data.length / 4
501
- }
575
+ field :data, Uint32, value: ->(cp) { cp.data.length / (cp.format/8) }
502
576
  field :data, Uint8, :list
503
577
  end
504
578
 
579
+ class GetProperty < BaseForm
580
+ field :opcode, Uint8, value: 20
581
+ field :delete, Bool
582
+ field :request_length, Uint16, value: 6
583
+ field :window, Window
584
+ field :property, Atom
585
+ field :type, Atom
586
+ field :long_offset, Uint32
587
+ field :long_length, Uint32
588
+ end
589
+
590
+ class Property < BaseForm
591
+ field :reply, Uint8, value: 1
592
+ field :format, Uint8
593
+ field :sequence_number, Uint16
594
+ field :reply_length, Uint32
595
+ field :type, Atom
596
+ field :bytes_after, Uint32
597
+ field :value, Uint32, :format_length
598
+ unused 12
599
+ field :value, String8, :string
600
+ end
601
+
505
602
  class GrabButton < BaseForm
506
603
  field :opcode, Uint8, value: 28
507
604
  field :owner_events, Bool
@@ -528,6 +625,18 @@ module X11
528
625
  field :keyboard_mode, Uint8
529
626
  unused 3
530
627
  end
628
+
629
+ class OpenFont < BaseForm
630
+ field :opcode, Uint8, value: 45
631
+ unused 1
632
+ field :request_length, Uint16, value: ->(of) {
633
+ 3+(of.name.length+3)/4
634
+ }
635
+ field :fid, Font
636
+ field :name, Uint16, :length
637
+ unused 2
638
+ field :name, String8, :string
639
+ end
531
640
 
532
641
  class ListFonts < BaseForm
533
642
  field :opcode, Uint8, value: 49
@@ -618,11 +727,11 @@ module X11
618
727
  field :src_drawable, Drawable
619
728
  field :dst_drawable, Drawable
620
729
  field :gc, Gcontext
621
- field :src_x, Uint16
622
- field :src_y, Uint16
623
- field :dst_x, Uint16
624
- field :dst_y, Uint16
625
- field :width, Uint16
730
+ field :src_x, Uint16
731
+ field :src_y, Uint16
732
+ field :dst_x, Uint16
733
+ field :dst_y, Uint16
734
+ field :width, Uint16
626
735
  field :height, Uint16
627
736
  end
628
737
 
@@ -754,7 +863,7 @@ module X11
754
863
  field :sequence_number, Uint16
755
864
  end
756
865
 
757
- class PressEvent < SimpleEvent
866
+ class InputEvent < SimpleEvent
758
867
  field :time, Uint32
759
868
  field :root, Window
760
869
  field :event, Window
@@ -764,6 +873,32 @@ module X11
764
873
  field :event_x, Int16
765
874
  field :event_y, Int16
766
875
  field :state, Uint16
876
+ end
877
+
878
+ class EnterLeaveNotify < InputEvent
879
+ field :mode, Uint8
880
+ field :same_screen_or_focus, Uint8
881
+
882
+ def same_screen = same_screen_or_focus.anybit?(0x02)
883
+ def focus = same_screen_or_focus.anybit?(0x01)
884
+ end
885
+
886
+ class EnterNotify < EnterLeaveNotify
887
+ end
888
+
889
+ class LeaveNotify < EnterLeaveNotify
890
+ end
891
+
892
+ class FocusIn < SimpleEvent
893
+ field :event, Window
894
+ field :mode, Uint8
895
+ unused 23
896
+ end
897
+
898
+ class FocusOut < FocusIn
899
+ end
900
+
901
+ class PressEvent < InputEvent
767
902
  field :same_screen, Bool
768
903
  unused 1
769
904
  end
@@ -782,6 +917,31 @@ module X11
782
917
 
783
918
  class ButtonRelease < PressEvent
784
919
  end
920
+
921
+ class ReparentNotify < SimpleEvent
922
+ field :event, Window
923
+ field :window, Window
924
+ field :parent, Window
925
+ field :x, Int16
926
+ field :y, Int16
927
+ field :override_redirect, Bool
928
+ unused 11
929
+ end
930
+
931
+ class ConfigureRequest < Event # 23
932
+ field :stack_mode, Uint8
933
+ field :sequence_number, Uint16
934
+ field :parent, Window
935
+ field :window, Window
936
+ field :sibling, Window
937
+ field :x, Int16
938
+ field :y, Int16
939
+ field :width, Uint16
940
+ field :height, Uint16
941
+ field :border_width, Uint16
942
+ field :value_mask, Uint16
943
+ unused 4
944
+ end
785
945
 
786
946
  class Expose < SimpleEvent
787
947
  field :window, Window
@@ -800,14 +960,51 @@ module X11
800
960
  unused 21
801
961
  end
802
962
 
963
+ class CreateNotify < SimpleEvent # 16
964
+ field :parent, Window
965
+ field :window, Window
966
+ field :x, Int16
967
+ field :y, Int16
968
+ field :width, Uint16
969
+ field :height, Uint16
970
+ field :border_width, Uint16
971
+ field :override_redirect, Bool
972
+ end
973
+
974
+ class DestroyNotify < Event
975
+ unused 1
976
+ field :sequence_number, Uint16
977
+ field :event, Window
978
+ field :window, Window
979
+ unused 20
980
+ end
981
+
982
+ class UnmapNotify < Event
983
+ unused 1
984
+ field :sequence_number, Uint16
985
+ field :event, Window
986
+ field :window, Window
987
+ field :from_configure, Bool
988
+ unused 19
989
+ end
990
+
803
991
  class MapNotify < Event
804
992
  unused 1
805
993
  field :sequence_number, Uint16
806
994
  field :event, Window
995
+ field :window, Window
807
996
  field :override_redirect, Bool
808
997
  unused 19
809
998
  end
810
999
 
1000
+ class MapRequest < Event
1001
+ unused 1
1002
+ field :sequence_number, Uint16
1003
+ field :parent, Window
1004
+ field :window, Window
1005
+ unused 20
1006
+ end
1007
+
811
1008
  class ConfigureNotify < Event
812
1009
  unused 1
813
1010
  field :sequence_number, Uint16
@@ -822,6 +1019,24 @@ module X11
822
1019
  unused 5
823
1020
  end
824
1021
 
1022
+ class ClientMessage < Event
1023
+ field :format, Uint8
1024
+ field :sequence_number, Uint16
1025
+ field :window, Window
1026
+ field :type, Atom
1027
+ field :data, X11::Type::Message
1028
+ end
1029
+
1030
+ class PropertyNotify < Event # 28
1031
+ unused 1
1032
+ field :sequence_number, Uint16
1033
+ field :window, Window
1034
+ field :atom, Atom
1035
+ field :time, Uint32
1036
+ field :state, Uint8
1037
+ unused 15
1038
+ end
1039
+
825
1040
 
826
1041
  # XRender extension
827
1042
  # From https://cgit.freedesktop.org/xorg/proto/renderproto/tree/renderproto.h
data/lib/X11/type.rb CHANGED
@@ -36,16 +36,23 @@ module X11
36
36
  define "Uint8", "C", 1
37
37
  define "Uint16", "S", 2
38
38
  define "Uint32", "L", 4
39
+
40
+ define "Message", "c*", 20
41
+
42
+ class Message
43
+ def self.pack(x) = x.b
44
+ def self.unpack(x) = x.b
45
+ def self.size = 20
46
+ def self.from_packet(sock) = sock.read(2).b
47
+ end
39
48
 
40
49
  class String8
41
50
  def self.pack(x)
42
51
  x.force_encoding("ASCII-8BIT") + "\x00"*(-x.length & 3)
43
52
  end
44
53
 
45
-
46
-
47
-
48
54
  def self.unpack(socket, size)
55
+ raise "Expected size for String8" if size.nil?
49
56
  val = socket.read(size)
50
57
  unused_padding = (4 - (size % 4)) % 4
51
58
  socket.read(unused_padding)
data/lib/X11/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module X11
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
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
4
+ version: 0.0.5
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-11-21 00:00:00.000000000 Z
12
+ date: 2023-12-16 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Pure Ruby X11 bindings
15
15
  email: