mirror of
https://github.com/vidarh/ruby-x11
synced 2024-11-16 07:48:12 +01:00
Extensive increase in number of requests and events supported.
This commit is contained in:
parent
370ac3e367
commit
e5b672673c
3 changed files with 413 additions and 122 deletions
|
@ -68,6 +68,7 @@ module X11
|
|||
def read_error data
|
||||
error = Form::Error.from_packet(StringIO.new(data))
|
||||
STDERR.puts "ERROR: #{error.inspect}"
|
||||
raise error.inspect
|
||||
error
|
||||
end
|
||||
|
||||
|
@ -80,28 +81,47 @@ module X11
|
|||
end
|
||||
|
||||
def read_event type, data, event_class
|
||||
io = StringIO.new(data)
|
||||
case type
|
||||
when 2
|
||||
return Form::KeyPress.from_packet(StringIO.new(data))
|
||||
when 3
|
||||
return Form::KeyRelease.from_packet(StringIO.new(data))
|
||||
when 4
|
||||
return Form::ButtonPress.from_packet(StringIO.new(data))
|
||||
when 5
|
||||
return Form::ButtonRelease.from_packet(StringIO.new(data))
|
||||
when 6
|
||||
return Form::MotionNotify.from_packet(StringIO.new(data))
|
||||
when 12
|
||||
return Form::Expose.from_packet(StringIO.new(data))
|
||||
when 14
|
||||
return Form::NoExposure.from_packet(StringIO.new(data))
|
||||
when 19
|
||||
return Form::MapNotify.from_packet(StringIO.new(data))
|
||||
when 22
|
||||
return Form::ConfigureNotify.from_packet(StringIO.new(data))
|
||||
# 0 is error, not handled here
|
||||
# 1 is reply, not handled here
|
||||
when 2 then return Form::KeyPress.from_packet(io)
|
||||
when 3 then return Form::KeyRelease.from_packet(io)
|
||||
when 4 then return Form::ButtonPress.from_packet(io)
|
||||
when 5 then return Form::ButtonRelease.from_packet(io)
|
||||
when 6 then return Form::MotionNotify.from_packet(io)
|
||||
when 7 then return Form::EnterNotify.from_packet(io)
|
||||
when 8 then return Form::LeaveNotify.from_packet(io)
|
||||
when 9 then return Form::FocusIn.from_packet(io)
|
||||
when 10 then return Form::FocusOut.from_packet(io)
|
||||
# FIXME 11: KeymapNotify
|
||||
when 12 then return Form::Expose.from_packet(io)
|
||||
# FIXME 13: GraphicsExposure
|
||||
when 14 then return Form::NoExposure.from_packet(io)
|
||||
# FIXME: 15: VisibilityNotify
|
||||
when 16 then return Form::CreateNotify.from_packet(io)
|
||||
when 17 then return Form::DestroyNotify.from_packet(io)
|
||||
when 18 then return Form::UnmapNotify.from_packet(io)
|
||||
when 19 then return Form::MapNotify.from_packet(io)
|
||||
when 20 then return Form::MapRequest.from_packet(io)
|
||||
when 21 then return Form::ReparentNotify.from_packet(io)
|
||||
when 22 then return Form::ConfigureNotify.from_packet(io)
|
||||
when 23 then return Form::ConfigureRequest.from_packet(io)
|
||||
# FIXME: 24: GravityNotify
|
||||
# FIXME: 25: ResizeRequest
|
||||
# FIXME: 26: CirculateNotify
|
||||
# FIXME: 27: CirculateRequest
|
||||
when 28 then return Form::PropertyNotify.from_packet(io)
|
||||
# FIXME: 29: SelectionClear
|
||||
# FIXME: 30: SelectionRequest
|
||||
# FIXME: 31: SelectionNotify
|
||||
# FIXME: 32: ColormapNotify
|
||||
when 33 then return Form::ClientMessage.from_packet(StringIO.new(data))
|
||||
# FIXME: 34: MappingNotify
|
||||
else
|
||||
STDERR.puts "FIXME: Event: #{type}"
|
||||
STDERR.puts "EVENT: #{data.inspect}"
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -122,19 +142,28 @@ module X11
|
|||
data = read_full_packet(32)
|
||||
return nil if data.nil?
|
||||
|
||||
type = data.unpack("C").first
|
||||
# FIXME: What is bit 8 for? Synthentic?
|
||||
type = data.unpack("C").first & 0x7f
|
||||
case type
|
||||
when 0
|
||||
read_error(data)
|
||||
when 1
|
||||
read_reply(data)
|
||||
when 2..34
|
||||
read_event(type, data, nil)
|
||||
when 0 then read_error(data)
|
||||
when 1 then read_reply(data)
|
||||
when 2..34 then read_event(type, data, nil)
|
||||
else
|
||||
raise ProtocolError, "Unsupported reply type: #{type}"
|
||||
raise ProtocolError, "Unsupported reply type: #{type} #{data.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
def write_raw_packet(pkt)
|
||||
@requestseq += 1
|
||||
@socket.write(pkt)
|
||||
end
|
||||
|
||||
def write_packet(*args)
|
||||
pkt = args.join
|
||||
pkt[2..3] = u16(pkt.length/4)
|
||||
write_raw_packet(pkt)
|
||||
end
|
||||
|
||||
def write_request ob
|
||||
#p data
|
||||
#p [:write_request, @requestseq, ob.class]
|
||||
|
@ -142,14 +171,16 @@ module X11
|
|||
#p [:AddGlyph,data] if ob.is_a?(X11::Form::XRenderAddGlyphs)
|
||||
#p [ob.request_length.to_i*4, data.size]
|
||||
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
|
||||
@requestseq += 1
|
||||
@socket.write(data)
|
||||
write_raw_packet(data)
|
||||
end
|
||||
|
||||
def write_sync(data, reply=nil)
|
||||
seq = @requestseq
|
||||
write_request(data)
|
||||
pkt = next_reply
|
||||
pkt = next_reply(seq)
|
||||
return nil if !pkt
|
||||
return pkt if pkt.is_a?(X11::Form::Error)
|
||||
pp reply
|
||||
reply ? reply.from_packet(StringIO.new(pkt)) : pkt
|
||||
end
|
||||
|
||||
|
@ -161,17 +192,19 @@ module X11
|
|||
@queue.shift || read_packet
|
||||
end
|
||||
|
||||
def next_reply
|
||||
def next_reply(errseq)
|
||||
# FIXME: This is totally broken
|
||||
while pkt = read_packet
|
||||
if pkt.is_a?(String)
|
||||
return pkt
|
||||
elsif pkt.is_a?(X11::Form::Error) && pkt.sequence_number == errseq
|
||||
return pkt
|
||||
else
|
||||
@queue.push(pkt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
loop do
|
||||
pkt = read_packet
|
||||
|
@ -193,12 +226,10 @@ module X11
|
|||
wid = new_id
|
||||
parent ||= screens.first.root
|
||||
|
||||
|
||||
if visual.nil?
|
||||
visual = find_visual(0, depth).visual_id
|
||||
end
|
||||
|
||||
|
||||
values[X11::Form::CWColorMap] ||= create_colormap(0, parent, visual)
|
||||
|
||||
values = values.sort_by{_1[0]}
|
||||
|
@ -212,6 +243,10 @@ module X11
|
|||
return wid
|
||||
end
|
||||
|
||||
def get_window_attributes(wid)
|
||||
write_sync( Form::GetWindowAttributes.new(wid), Form::WindowAttributes )
|
||||
end
|
||||
|
||||
def change_window_attributes(wid,
|
||||
values: {})
|
||||
values = values.sort_by{_1[0]}
|
||||
|
@ -222,7 +257,10 @@ module X11
|
|||
)
|
||||
end
|
||||
|
||||
def select_input(w, events) = change_window_attributes(w, values: {Form::CWEventMask => events})
|
||||
|
||||
def atom(name)
|
||||
name = name.to_sym
|
||||
intern_atom(false, name) if !@atoms[name]
|
||||
@atoms[name]
|
||||
end
|
||||
|
@ -251,13 +289,13 @@ module X11
|
|||
end
|
||||
end
|
||||
|
||||
def destroy_window(window)
|
||||
write_request(X11::Form::DestroyWindow.new(window))
|
||||
end
|
||||
|
||||
def get_geometry(drawable)
|
||||
write_sync(X11::Form::GetGeometry.new(drawable), X11::Form::Geometry)
|
||||
def get_atom_name(atom)
|
||||
reply = write_sync(X11::Form::GetAtomName.new(atom), X11::Form::AtomName)
|
||||
reply&.name
|
||||
end
|
||||
|
||||
def destroy_window(window) = write_request(X11::Form::DestroyWindow.new(window))
|
||||
def get_geometry(drawable) = write_sync(X11::Form::GetGeometry.new(drawable), X11::Form::Geometry)
|
||||
|
||||
def get_keyboard_mapping(min_keycode=display_info.min_keycode, count= display_info.max_keycode - min_keycode)
|
||||
write_sync(X11::Form::GetKeyboardMapping.new(min_keycode, count), X11::Form::GetKeyboardMappingReply)
|
||||
|
@ -269,8 +307,35 @@ module X11
|
|||
mid
|
||||
end
|
||||
|
||||
def change_property(*args)
|
||||
write_request(X11::Form::ChangeProperty.new(*args))
|
||||
def get_property(window, property, type, offset: 0, length: 4, delete: false)
|
||||
property = atom(property) if !property.is_a?(Integer)
|
||||
type = atom_enum(type)
|
||||
|
||||
result = write_sync(X11::Form::GetProperty.new(
|
||||
delete, window, property, type, offset, length
|
||||
), X11::Form::Property)
|
||||
|
||||
if result && result.format != 0
|
||||
case result.format
|
||||
when 16
|
||||
result.value = result.value.unpack("v")
|
||||
result.value = result.value.first if length == 2
|
||||
when 32
|
||||
result.value = result.value.unpack("V")
|
||||
result.value = result.value.first if length == 4
|
||||
end
|
||||
elsif result
|
||||
result.value = nil
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def change_property(mode, window, property, type, format, data)
|
||||
property = atom(property.to_sym) if property.is_a?(Symbol) || property.is_a?(String)
|
||||
|
||||
mode = open_enum(mode, {replace: 0, prepend: 1, append: 2})
|
||||
type = atom_enum(type)
|
||||
write_request(X11::Form::ChangeProperty.new(mode, window, property, type, format, data))
|
||||
end
|
||||
|
||||
def list_fonts(*args)
|
||||
|
@ -278,25 +343,46 @@ module X11
|
|||
X11::Form::ListFontsReply)
|
||||
end
|
||||
|
||||
def open_font(*args)
|
||||
write_request(X11::Form::OpenFont.new(*args))
|
||||
def open_font(*args) = write_request(X11::Form::OpenFont.new(*args))
|
||||
def change_gc(*args) = write_request(X11::Form::ChangeGC.new(*args))
|
||||
def change_save_set(...)= write_request(X11::Form::ChangeSaveSet.new(...))
|
||||
def reparent_window(window, parent, x, y, save: true)
|
||||
# You so almost always want this that it should've been a single request
|
||||
change_save_set(0, window) if save
|
||||
write_request(X11::Form::ReparentWindow.new(window, parent, x,y))
|
||||
end
|
||||
|
||||
def map_window(*args) = write_request(X11::Form::MapWindow.new(*args))
|
||||
def unmap_window(*args) = write_request(X11::Form::UnmapWindow.new(*args))
|
||||
|
||||
def u8(*args) = args.pack("c*")
|
||||
def u16(*args) = args.pack("v*")
|
||||
def u32(*args) = args.pack("V*")
|
||||
def atom_enum(val) = open_enum(val, {cardinal: Form::CardinalAtom, atom: Form::AtomAtom, window: Form::WindowAtom})
|
||||
def window(*args)
|
||||
args.each {|a| raise "Window expected" if a.nil? }
|
||||
u32(*args)
|
||||
end
|
||||
|
||||
def change_gc(*args)
|
||||
write_request(X11::Form::ChangeGC.new(*args))
|
||||
def open_enum(val, map) = (map[val].nil? ? val : map[val])
|
||||
|
||||
def set_input_focus(revert_to, focus, time=:now)
|
||||
# FIXME: This is an experiment.
|
||||
# Upside: Simpler. Downside: Doesn't work server-side.
|
||||
#
|
||||
revert_to = open_enum(revert_to, {none: 0, pointer_root: 1, parent: 2})
|
||||
focus = open_enum(focus, {none: 0, pointer_root: 1 })
|
||||
time = open_enum(time, {current_time: 0, now: 0})
|
||||
write_packet(u8(42,revert_to), u16(3), window(focus), u32(time))
|
||||
end
|
||||
|
||||
def map_window(*args)
|
||||
write_request(X11::Form::MapWindow.new(*args))
|
||||
end
|
||||
|
||||
|
||||
def grab_key(owner_events, grab_window, modifiers, keycode, pointer_mode, keyboard_mode)
|
||||
write_request(X11::Form::GrabKey.new(
|
||||
owner_events,
|
||||
grab_window,
|
||||
modifiers,
|
||||
keycode,
|
||||
pointer_mode == :async ? 1 : 0,
|
||||
pointer_mode == :async ? 1 : 0,
|
||||
keyboard_mode == :async ? 1 : 0
|
||||
))
|
||||
end
|
||||
|
@ -354,7 +440,7 @@ module X11
|
|||
when :below then 1
|
||||
when :top_if then 2
|
||||
when :bottom_if then 3
|
||||
when :opposite then 4
|
||||
when :opposite then 4
|
||||
else raise "Unknown stack_mode #{stack_mode.inspect}"
|
||||
end
|
||||
end
|
||||
|
@ -384,29 +470,12 @@ module X11
|
|||
gc
|
||||
end
|
||||
|
||||
def put_image(*args)
|
||||
write_request(X11::Form::PutImage.new(*args))
|
||||
end
|
||||
|
||||
def clear_area(*args)
|
||||
write_request(X11::Form::ClearArea.new(*args))
|
||||
end
|
||||
|
||||
def copy_area(*args)
|
||||
write_request(X11::Form::CopyArea.new(*args))
|
||||
end
|
||||
|
||||
def image_text8(*args)
|
||||
write_request(X11::Form::ImageText8.new(*args))
|
||||
end
|
||||
|
||||
def image_text16(*args)
|
||||
write_request(X11::Form::ImageText16.new(*args))
|
||||
end
|
||||
|
||||
def poly_fill_rectangle(*args)
|
||||
write_request(X11::Form::PolyFillRectangle.new(*args))
|
||||
end
|
||||
def put_image(*args) = write_request(X11::Form::PutImage.new(*args))
|
||||
def clear_area(*args) = write_request(X11::Form::ClearArea.new(*args))
|
||||
def copy_area(*args) = write_request(X11::Form::CopyArea.new(*args))
|
||||
def image_text8(*args) = write_request(X11::Form::ImageText8.new(*args))
|
||||
def image_text16(*args)= write_request(X11::Form::ImageText16.new(*args))
|
||||
def poly_fill_rectangle(*args) = write_request(X11::Form::PolyFillRectangle.new(*args))
|
||||
|
||||
def create_pixmap(depth, drawable, w,h)
|
||||
pid = new_id
|
||||
|
|
303
lib/X11/form.rb
303
lib/X11/form.rb
|
@ -81,14 +81,14 @@ module X11
|
|||
when :unused
|
||||
sz = s.size.respond_to?(:call) ? s.size.call(self) : s.size
|
||||
"\x00" * sz
|
||||
when :length
|
||||
when :length, :format_length
|
||||
#p [s,value]
|
||||
#p [value.size]
|
||||
s.type_klass.pack(value.size)
|
||||
when :string
|
||||
s.type_klass.pack(value)
|
||||
when :list
|
||||
value.collect do |obj|
|
||||
Array(value).collect do |obj|
|
||||
if obj.is_a?(BaseForm)
|
||||
obj.to_packet
|
||||
else
|
||||
|
@ -127,8 +127,17 @@ module X11
|
|||
when :length
|
||||
size = s.type_klass.unpack( socket.read(s.type_klass.size) )
|
||||
lengths[s.name] = size
|
||||
when :format_length
|
||||
size = s.type_klass.unpack( socket.read(s.type_klass.size) )
|
||||
lengths[s.name] = case form.format
|
||||
when 8 then size
|
||||
when 16 then size*2
|
||||
when 32 then size*4
|
||||
else 0
|
||||
end
|
||||
when :string
|
||||
val = s.type_klass.unpack(socket, lengths[s.name])
|
||||
len = lengths[s.name]
|
||||
val = s.type_klass.unpack(socket, len)
|
||||
form.instance_variable_set("@#{s.name}", val)
|
||||
when :list
|
||||
len = lengths[s.name]
|
||||
|
@ -177,12 +186,14 @@ module X11
|
|||
end
|
||||
|
||||
def fields
|
||||
super+Array(@structs).dup.delete_if{|s| s.type == :unused or s.type == :length }
|
||||
super+Array(@structs).dup.delete_if{|s| s.type == :unused or s.type == :length or s.type == :format_length}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AtomAtom=4
|
||||
CardinalAtom=6
|
||||
WindowAtom=33
|
||||
|
||||
##
|
||||
## X11 Packet Defintions
|
||||
|
@ -247,9 +258,9 @@ module X11
|
|||
end
|
||||
|
||||
class DisplayInfo < BaseForm
|
||||
field :release_number, Uint32
|
||||
field :resource_id_base, Uint32
|
||||
field :resource_id_mask, Uint32
|
||||
field :release_number, Uint32
|
||||
field :resource_id_base, Uint32
|
||||
field :resource_id_mask, Uint32
|
||||
field :motion_buffer_size, Uint32
|
||||
field :vendor, Uint16, :length
|
||||
field :maximum_request_length, Uint16
|
||||
|
@ -258,11 +269,11 @@ module X11
|
|||
field :image_byte_order, Signifigance
|
||||
field :bitmap_bit_order, Signifigance
|
||||
field :bitmap_format_scanline_unit, Uint8
|
||||
field :bitmap_format_scanline_pad, Uint8
|
||||
field :bitmap_format_scanline_pad, Uint8
|
||||
field :min_keycode, KeyCode
|
||||
field :max_keycode, KeyCode
|
||||
unused 4
|
||||
field :vendor, String8, :string
|
||||
field :vendor, String8, :string
|
||||
field :formats, FormatInfo, :list
|
||||
field :screens, ScreenInfo, :list
|
||||
end
|
||||
|
@ -287,13 +298,13 @@ module X11
|
|||
# XRender structures
|
||||
|
||||
class DirectFormat < BaseForm
|
||||
field :red, Uint16
|
||||
field :red_mask, Uint16
|
||||
field :green, Uint16
|
||||
field :red, Uint16
|
||||
field :red_mask, Uint16
|
||||
field :green, Uint16
|
||||
field :green_mask, Uint16
|
||||
field :blue, Uint16
|
||||
field :blue_mask, Uint16
|
||||
field :alpha, Uint16
|
||||
field :blue, Uint16
|
||||
field :blue_mask, Uint16
|
||||
field :alpha, Uint16
|
||||
field :alpha_mask, Uint16
|
||||
end
|
||||
|
||||
|
@ -328,8 +339,8 @@ module X11
|
|||
# Requests
|
||||
|
||||
CopyFromParent = 0
|
||||
InputOutput = 1
|
||||
InputOnly = 2
|
||||
InputOutput = 1
|
||||
InputOnly = 2
|
||||
|
||||
CWBackPixmap = 0x0001
|
||||
CWBackPixel = 0x0002
|
||||
|
@ -337,23 +348,29 @@ module X11
|
|||
CWBorderPixel = 0x0008
|
||||
CWBitGravity = 0x0010
|
||||
CWWinGravity = 0x0020
|
||||
CWBackingStore= 0x0040
|
||||
CWSaveUnder = 0x0400
|
||||
CWEventMask = 0x0800
|
||||
CWColorMap = 0x2000
|
||||
CWBackingStore = 0x0040
|
||||
CWBackingPlanes = 0x0080
|
||||
CWBackingPixel = 0x0100
|
||||
CWOverrideRedirect = 0x0200
|
||||
CWSaveUnder = 0x0400
|
||||
CWEventMask = 0x0800
|
||||
CWColorMap = 0x2000
|
||||
|
||||
KeyPressMask = 0x00001
|
||||
KeyReleaseMask = 0x00002
|
||||
ButtonPressMask = 0x00004
|
||||
ButtonReleaseMask = 0x00008
|
||||
EnterWindowMask = 0x00010
|
||||
LeaveWindowMask = 0x00020
|
||||
PointerMotionMask = 0x00040
|
||||
PointerMotionHintMask = 0x00080
|
||||
Button1MotionMask = 0x00100
|
||||
ExposureMask = 0x08000
|
||||
StructureNotifyMask = 0x20000
|
||||
SubstructureNotifyMask = 0x80000
|
||||
KeyPressMask = 0x000001
|
||||
KeyReleaseMask = 0x000002
|
||||
ButtonPressMask = 0x000004
|
||||
ButtonReleaseMask = 0x000008
|
||||
EnterWindowMask = 0x000010
|
||||
LeaveWindowMask = 0x000020
|
||||
PointerMotionMask = 0x000040
|
||||
PointerMotionHintMask = 0x000080
|
||||
Button1MotionMask = 0x000100
|
||||
ExposureMask = 0x008000
|
||||
StructureNotifyMask = 0x020000
|
||||
SubstructureNotifyMask = 0x080000
|
||||
SubstructureRedirectMask=0x100000
|
||||
FocusChangeMask = 0x200000
|
||||
PropertyChangeMask = 0x400000
|
||||
|
||||
class CreateWindow < BaseForm
|
||||
field :opcode, Uint8, value: 1
|
||||
|
@ -394,14 +411,14 @@ module X11
|
|||
field :sequence_number, Uint16
|
||||
field :reply_length, Uint32
|
||||
field :visual, VisualID
|
||||
field :class, Uint16
|
||||
field :wclass, Uint16
|
||||
field :bit_gravity, Uint8
|
||||
field :win_gravity, Uint8
|
||||
field :backing_planes, Uint32
|
||||
field :backing_pixel, Uint32
|
||||
field :save_under, Bool
|
||||
field :map_is_installed, Bool
|
||||
field :map_state, Bool
|
||||
field :map_state, Uint8
|
||||
field :override_redirect, Bool
|
||||
field :colormap, Colormap
|
||||
field :all_event_masks, Uint32
|
||||
|
@ -417,6 +434,23 @@ module X11
|
|||
field :window, Window
|
||||
end
|
||||
|
||||
class ChangeSaveSet < BaseForm
|
||||
field :opcode, Uint8, value: 6
|
||||
field :mode, Uint8
|
||||
field :request_length, Uint16, value: 2
|
||||
field :window, Window
|
||||
end
|
||||
|
||||
class ReparentWindow < BaseForm
|
||||
field :opcode, Uint8, value: 7
|
||||
unused 1
|
||||
field :request_length, Uint16, value: 4
|
||||
field :window, Window
|
||||
field :parent, Window
|
||||
field :x, Int16
|
||||
field :y, Int16
|
||||
end
|
||||
|
||||
class MapWindow < BaseForm
|
||||
field :opcode, Uint8, value: 8
|
||||
unused 1
|
||||
|
@ -424,6 +458,13 @@ module X11
|
|||
field :window, Window
|
||||
end
|
||||
|
||||
class UnmapWindow < BaseForm
|
||||
field :opcode, Uint8, value: 10
|
||||
unused 1
|
||||
field :request_length, Uint16, value: 2
|
||||
field :window, Window
|
||||
end
|
||||
|
||||
class ConfigureWindow < BaseForm
|
||||
field :opcode, Uint8, value: 12
|
||||
unused 1
|
||||
|
@ -455,6 +496,25 @@ module X11
|
|||
unused 10
|
||||
end
|
||||
|
||||
class QueryTree < BaseForm
|
||||
field :opcode, Uint8, value: 15
|
||||
unused 1
|
||||
field :request_length, Uint16, value: 2
|
||||
field :window, Window
|
||||
end
|
||||
|
||||
class QueryTreeReply < BaseForm
|
||||
field :reply, Uint8, value: 1
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :reply_length, Uint32
|
||||
field :root, Window
|
||||
field :parent, Window
|
||||
field :children, Uint16, :length
|
||||
unused 14
|
||||
field :children, Window, :list
|
||||
end
|
||||
|
||||
class InternAtom < BaseForm
|
||||
field :opcode, Uint8, value: 16
|
||||
field :only_if_exists, Bool
|
||||
|
@ -480,6 +540,22 @@ module X11
|
|||
unused 20
|
||||
end
|
||||
|
||||
class GetAtomName < BaseForm
|
||||
field :opcode, Uint8, value: 17
|
||||
unused 1
|
||||
field :request_length, Uint16, value: 2
|
||||
field :atom, Atom
|
||||
end
|
||||
|
||||
class AtomName < Reply
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :reply_length, Uint32
|
||||
field :name, Uint16, :length
|
||||
unused 22
|
||||
field :name, String8, :string
|
||||
end
|
||||
|
||||
Replace = 0
|
||||
Prepend = 1
|
||||
Append = 2
|
||||
|
@ -496,12 +572,33 @@ module X11
|
|||
field :type, Atom
|
||||
field :format, Uint8
|
||||
unused 3
|
||||
field :data, Uint32, value: ->(cp) {
|
||||
cp.data.length / 4
|
||||
}
|
||||
field :data, Uint32, value: ->(cp) { cp.data.length / (cp.format/8) }
|
||||
field :data, Uint8, :list
|
||||
end
|
||||
|
||||
class GetProperty < BaseForm
|
||||
field :opcode, Uint8, value: 20
|
||||
field :delete, Bool
|
||||
field :request_length, Uint16, value: 6
|
||||
field :window, Window
|
||||
field :property, Atom
|
||||
field :type, Atom
|
||||
field :long_offset, Uint32
|
||||
field :long_length, Uint32
|
||||
end
|
||||
|
||||
class Property < BaseForm
|
||||
field :reply, Uint8, value: 1
|
||||
field :format, Uint8
|
||||
field :sequence_number, Uint16
|
||||
field :reply_length, Uint32
|
||||
field :type, Atom
|
||||
field :bytes_after, Uint32
|
||||
field :value, Uint32, :format_length
|
||||
unused 12
|
||||
field :value, String8, :string
|
||||
end
|
||||
|
||||
class GrabButton < BaseForm
|
||||
field :opcode, Uint8, value: 28
|
||||
field :owner_events, Bool
|
||||
|
@ -528,6 +625,18 @@ module X11
|
|||
field :keyboard_mode, Uint8
|
||||
unused 3
|
||||
end
|
||||
|
||||
class OpenFont < BaseForm
|
||||
field :opcode, Uint8, value: 45
|
||||
unused 1
|
||||
field :request_length, Uint16, value: ->(of) {
|
||||
3+(of.name.length+3)/4
|
||||
}
|
||||
field :fid, Font
|
||||
field :name, Uint16, :length
|
||||
unused 2
|
||||
field :name, String8, :string
|
||||
end
|
||||
|
||||
class ListFonts < BaseForm
|
||||
field :opcode, Uint8, value: 49
|
||||
|
@ -618,11 +727,11 @@ module X11
|
|||
field :src_drawable, Drawable
|
||||
field :dst_drawable, Drawable
|
||||
field :gc, Gcontext
|
||||
field :src_x, Uint16
|
||||
field :src_y, Uint16
|
||||
field :dst_x, Uint16
|
||||
field :dst_y, Uint16
|
||||
field :width, Uint16
|
||||
field :src_x, Uint16
|
||||
field :src_y, Uint16
|
||||
field :dst_x, Uint16
|
||||
field :dst_y, Uint16
|
||||
field :width, Uint16
|
||||
field :height, Uint16
|
||||
end
|
||||
|
||||
|
@ -754,7 +863,7 @@ module X11
|
|||
field :sequence_number, Uint16
|
||||
end
|
||||
|
||||
class PressEvent < SimpleEvent
|
||||
class InputEvent < SimpleEvent
|
||||
field :time, Uint32
|
||||
field :root, Window
|
||||
field :event, Window
|
||||
|
@ -764,6 +873,32 @@ module X11
|
|||
field :event_x, Int16
|
||||
field :event_y, Int16
|
||||
field :state, Uint16
|
||||
end
|
||||
|
||||
class EnterLeaveNotify < InputEvent
|
||||
field :mode, Uint8
|
||||
field :same_screen_or_focus, Uint8
|
||||
|
||||
def same_screen = same_screen_or_focus.anybit?(0x02)
|
||||
def focus = same_screen_or_focus.anybit?(0x01)
|
||||
end
|
||||
|
||||
class EnterNotify < EnterLeaveNotify
|
||||
end
|
||||
|
||||
class LeaveNotify < EnterLeaveNotify
|
||||
end
|
||||
|
||||
class FocusIn < SimpleEvent
|
||||
field :event, Window
|
||||
field :mode, Uint8
|
||||
unused 23
|
||||
end
|
||||
|
||||
class FocusOut < FocusIn
|
||||
end
|
||||
|
||||
class PressEvent < InputEvent
|
||||
field :same_screen, Bool
|
||||
unused 1
|
||||
end
|
||||
|
@ -782,6 +917,31 @@ module X11
|
|||
|
||||
class ButtonRelease < PressEvent
|
||||
end
|
||||
|
||||
class ReparentNotify < SimpleEvent
|
||||
field :event, Window
|
||||
field :window, Window
|
||||
field :parent, Window
|
||||
field :x, Int16
|
||||
field :y, Int16
|
||||
field :override_redirect, Bool
|
||||
unused 11
|
||||
end
|
||||
|
||||
class ConfigureRequest < Event # 23
|
||||
field :stack_mode, Uint8
|
||||
field :sequence_number, Uint16
|
||||
field :parent, Window
|
||||
field :window, Window
|
||||
field :sibling, Window
|
||||
field :x, Int16
|
||||
field :y, Int16
|
||||
field :width, Uint16
|
||||
field :height, Uint16
|
||||
field :border_width, Uint16
|
||||
field :value_mask, Uint16
|
||||
unused 4
|
||||
end
|
||||
|
||||
class Expose < SimpleEvent
|
||||
field :window, Window
|
||||
|
@ -800,14 +960,51 @@ module X11
|
|||
unused 21
|
||||
end
|
||||
|
||||
class CreateNotify < SimpleEvent # 16
|
||||
field :parent, Window
|
||||
field :window, Window
|
||||
field :x, Int16
|
||||
field :y, Int16
|
||||
field :width, Uint16
|
||||
field :height, Uint16
|
||||
field :border_width, Uint16
|
||||
field :override_redirect, Bool
|
||||
end
|
||||
|
||||
class DestroyNotify < Event
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :event, Window
|
||||
field :window, Window
|
||||
unused 20
|
||||
end
|
||||
|
||||
class UnmapNotify < Event
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :event, Window
|
||||
field :window, Window
|
||||
field :from_configure, Bool
|
||||
unused 19
|
||||
end
|
||||
|
||||
class MapNotify < Event
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :event, Window
|
||||
field :window, Window
|
||||
field :override_redirect, Bool
|
||||
unused 19
|
||||
end
|
||||
|
||||
class MapRequest < Event
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :parent, Window
|
||||
field :window, Window
|
||||
unused 20
|
||||
end
|
||||
|
||||
class ConfigureNotify < Event
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
|
@ -822,6 +1019,24 @@ module X11
|
|||
unused 5
|
||||
end
|
||||
|
||||
class ClientMessage < Event
|
||||
field :format, Uint8
|
||||
field :sequence_number, Uint16
|
||||
field :window, Window
|
||||
field :type, Atom
|
||||
field :data, X11::Type::Message
|
||||
end
|
||||
|
||||
class PropertyNotify < Event # 28
|
||||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :window, Window
|
||||
field :atom, Atom
|
||||
field :time, Uint32
|
||||
field :state, Uint8
|
||||
unused 15
|
||||
end
|
||||
|
||||
|
||||
# XRender extension
|
||||
# From https://cgit.freedesktop.org/xorg/proto/renderproto/tree/renderproto.h
|
||||
|
|
|
@ -36,16 +36,23 @@ module X11
|
|||
define "Uint8", "C", 1
|
||||
define "Uint16", "S", 2
|
||||
define "Uint32", "L", 4
|
||||
|
||||
define "Message", "c*", 20
|
||||
|
||||
class Message
|
||||
def self.pack(x) = x.b
|
||||
def self.unpack(x) = x.b
|
||||
def self.size = 20
|
||||
def self.from_packet(sock) = sock.read(2).b
|
||||
end
|
||||
|
||||
class String8
|
||||
def self.pack(x)
|
||||
x.force_encoding("ASCII-8BIT") + "\x00"*(-x.length & 3)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
def self.unpack(socket, size)
|
||||
raise "Expected size for String8" if size.nil?
|
||||
val = socket.read(size)
|
||||
unused_padding = (4 - (size % 4)) % 4
|
||||
socket.read(unused_padding)
|
||||
|
|
Loading…
Reference in a new issue