mirror of
https://github.com/vidarh/ruby-x11
synced 2024-11-16 07:48:12 +01:00
Cleanups, more automated lookups of atoms to avoid needing to dereference constants.
More constants and requestsm including SendEvent, and a helper for ClientMessage, w/example
This commit is contained in:
parent
5f3aca393e
commit
da2fe51596
5 changed files with 100 additions and 35 deletions
13
example/client_message.rb
Normal file
13
example/client_message.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
||||
|
||||
require 'X11'
|
||||
|
||||
display = X11::Display.new
|
||||
|
||||
display.client_message(
|
||||
mask: X11::Form::SubstructureNotifyMask | X11::Form::SubstructureRedirectMask,
|
||||
type: :_NET_CURRENT_DESKTOP,
|
||||
data: ARGV.shift.to_i
|
||||
)
|
||||
|
|
@ -316,6 +316,12 @@ module X11
|
|||
|
||||
def atom(name)
|
||||
return name if name.is_a?(Integer) # Allow atom(atom_integer_or_symbol)
|
||||
begin
|
||||
return Form::Atoms.const_get(name.to_sym) if Form::Atoms.const_defined?(name.to_sym)
|
||||
rescue
|
||||
# const_defined? will throw if name isn't a valid constant name, but
|
||||
# that's fine
|
||||
end
|
||||
name = name.to_sym
|
||||
intern_atom(false, name) if !@atoms[name]
|
||||
@atoms[name]
|
||||
|
@ -404,7 +410,10 @@ module X11
|
|||
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 atom_enum(val)
|
||||
open_enum(val, {cardinal: Form::CardinalAtom, atom: Form::AtomAtom, window: Form::WindowAtom}) || atom(val)
|
||||
end
|
||||
|
||||
def window(*args)
|
||||
args.each {|a| raise "Window expected" if a.nil? }
|
||||
u32(*args)
|
||||
|
@ -415,7 +424,7 @@ module X11
|
|||
def set_input_focus(revert_to, focus, time=:now)
|
||||
# FIXME: This is an experiment.
|
||||
# Upside: Simpler. Downside: Doesn't work server-side.
|
||||
#
|
||||
# Probably a bad idea.
|
||||
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})
|
||||
|
@ -455,9 +464,8 @@ module X11
|
|||
def configure_window(window, x: nil, y: nil, width: nil, height: nil,
|
||||
border_width: nil, sibling: nil, stack_mode: nil)
|
||||
|
||||
mask = 0
|
||||
values = []
|
||||
|
||||
mask = 0
|
||||
mask |= set_value(values, 0x001, x)
|
||||
mask |= set_value(values, 0x002, y)
|
||||
mask |= set_value(values, 0x004, width)
|
||||
|
@ -480,7 +488,9 @@ module X11
|
|||
end
|
||||
|
||||
|
||||
def create_gc(window, foreground: nil, background: nil)
|
||||
def create_gc(window, foreground: nil, background: nil,
|
||||
graphics_exposures: nil
|
||||
)
|
||||
mask = 0
|
||||
args = []
|
||||
|
||||
|
@ -489,12 +499,27 @@ module X11
|
|||
# https://tronche.com/gui/x/xlib/GC/manipulating.html#XGCValues
|
||||
mask |= set_value(args, 0x04, foreground)
|
||||
mask |= set_value(args, 0x08, background)
|
||||
mask |= set_value(args, 0x10000, graphics_exposures)
|
||||
|
||||
gc = new_id
|
||||
write_request(X11::Form::CreateGC.new(gc, window, mask, args))
|
||||
gc
|
||||
end
|
||||
|
||||
def send_event(...) = write_request(Form::SendEvent.new(...))
|
||||
def client_message(window: default_root, type: :ClientMessage, format: 32, destination: default_root, mask: 0, data: [], propagate: true)
|
||||
f = {8 => "C20", 16 => "S10", 32 => "L5"}[format]
|
||||
p f
|
||||
data = (Array(data).map{|item|atom(item)} +[0]*20).pack(f)
|
||||
event = Form::ClientMessage.new(
|
||||
format, 0, window, atom(type), data
|
||||
)
|
||||
event.code =33
|
||||
pp event
|
||||
|
||||
send_event(propagate, destination, mask, event)
|
||||
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))
|
||||
|
@ -560,19 +585,19 @@ module X11
|
|||
end
|
||||
when :rgb24
|
||||
@rgb24 ||= formats.formats.find do |f|
|
||||
f.type == 1 &&
|
||||
f.type == 1 &&
|
||||
f.depth == 24 &&
|
||||
f.direct.red == 16 &&
|
||||
f.direct.green == 8 &&
|
||||
f.direct.green == 8 &&
|
||||
f.direct.blue == 0
|
||||
end
|
||||
when :argb24
|
||||
@argb24 ||= formats.formats.find do |f|
|
||||
f.type == 1 &&
|
||||
f.type == 1 &&
|
||||
f.depth == 32 &&
|
||||
f.direct.alpha == 24 &&
|
||||
f.direct.red == 16 &&
|
||||
f.direct.green == 8 &&
|
||||
f.direct.green == 8 &&
|
||||
f.direct.blue == 0
|
||||
end
|
||||
else
|
||||
|
|
|
@ -184,6 +184,29 @@ module X11
|
|||
end
|
||||
end
|
||||
|
||||
# # Predefined constants, that can be used in the form of symbols
|
||||
|
||||
module Atoms
|
||||
PRIMARY = 1
|
||||
SECONDARY = 2
|
||||
ARC = 3
|
||||
ATOM = 4
|
||||
BITMAP = 5
|
||||
CARDINAL = 6
|
||||
COLORMAP = 7
|
||||
CURSOR = 8
|
||||
#...
|
||||
STRING = 31
|
||||
VISUALID = 32
|
||||
WINDOW = 33
|
||||
WM_COMMAND = 34
|
||||
WM_HINTS = 35
|
||||
end
|
||||
|
||||
PointerWindow = 0
|
||||
InputFocus = 1
|
||||
|
||||
# FIXME: Deprecated in favour of the Constants module
|
||||
AtomAtom=4
|
||||
CardinalAtom=6
|
||||
WindowAtom=33
|
||||
|
@ -286,6 +309,9 @@ module X11
|
|||
field :minor_opcode, Uint16
|
||||
field :major_opcode, Uint8
|
||||
unused 21
|
||||
|
||||
# The original request
|
||||
attr_accessor :request
|
||||
end
|
||||
|
||||
# XRender structures
|
||||
|
@ -329,8 +355,9 @@ module X11
|
|||
field :colormap, Colormap
|
||||
end
|
||||
|
||||
# Requests
|
||||
# # Requests
|
||||
|
||||
# Constants, p112 onwards
|
||||
CopyFromParent = 0
|
||||
InputOutput = 1
|
||||
InputOnly = 2
|
||||
|
@ -358,12 +385,17 @@ module X11
|
|||
PointerMotionMask = 0x000040
|
||||
PointerMotionHintMask = 0x000080
|
||||
Button1MotionMask = 0x000100
|
||||
# 0x200 .. 0x40000; page 113
|
||||
ExposureMask = 0x008000
|
||||
VisibilityChangeMask = 0x010000
|
||||
StructureNotifyMask = 0x020000
|
||||
ResizeRedirectMask = 0x040000
|
||||
SubstructureNotifyMask = 0x080000
|
||||
SubstructureRedirectMask=0x100000
|
||||
FocusChangeMask = 0x200000
|
||||
PropertyChangeMask = 0x400000
|
||||
ColormapChangeMask = 0x800000
|
||||
OwnerGrabButtonMask = 0x100000
|
||||
|
||||
class CreateWindow < BaseForm
|
||||
field :opcode, Uint8, value: 1
|
||||
|
@ -592,6 +624,15 @@ module X11
|
|||
field :value, String8, :string
|
||||
end
|
||||
|
||||
class SendEvent < BaseForm
|
||||
field :opcode, Uint8, value: 25
|
||||
field :propagate, Bool
|
||||
field :request_length, Uint16, value: 11
|
||||
field :destination, Window
|
||||
field :event_mask, Uint32
|
||||
field :event, Uint32 # FIXME: This is wrong, and will break on parsing.
|
||||
end
|
||||
|
||||
class GrabButton < BaseForm
|
||||
field :opcode, Uint8, value: 28
|
||||
field :owner_events, Bool
|
||||
|
@ -678,6 +719,7 @@ module X11
|
|||
ForegroundMask = 0x04
|
||||
BackgroundMask = 0x08
|
||||
FontMask = 0x4000
|
||||
GraphicsExposures = 0x10000
|
||||
|
||||
class CreateGC < BaseForm
|
||||
field :opcode, Uint8, value: 55
|
||||
|
@ -1002,6 +1044,7 @@ module X11
|
|||
unused 1
|
||||
field :sequence_number, Uint16
|
||||
field :event, Window
|
||||
field :window, Window
|
||||
field :above_sibling, Window
|
||||
field :x, Int16
|
||||
field :y, Int16
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
module X11
|
||||
module Protocol
|
||||
# endiness of your machine
|
||||
# endianess of your machine
|
||||
BYTE_ORDER = case [1].pack("L")
|
||||
when "\0\0\0\1"
|
||||
"B".ord
|
||||
when "\1\0\0\0"
|
||||
"l".ord
|
||||
when "\0\0\0\1" then "B".ord
|
||||
when "\1\0\0\0" then "l".ord
|
||||
else
|
||||
raise ByteOrderError.new "Cannot determine byte order"
|
||||
end
|
||||
end
|
||||
|
||||
MAJOR = 11
|
||||
MINOR = 0
|
||||
|
|
|
@ -7,25 +7,11 @@ module X11
|
|||
@internal = data
|
||||
end
|
||||
|
||||
def root
|
||||
@internal.root
|
||||
end
|
||||
|
||||
def root_depth
|
||||
@internal.root_depth
|
||||
end
|
||||
|
||||
def root_visual
|
||||
@internal.root_visual
|
||||
end
|
||||
|
||||
def width
|
||||
@internal.width_in_pixels
|
||||
end
|
||||
|
||||
def height
|
||||
@internal.height_in_pixels
|
||||
end
|
||||
def root = @internal.root
|
||||
def root_depth = @internal.root_depth
|
||||
def root_visual = @internal.root_visual
|
||||
def width = @internal.width_in_pixels
|
||||
def height = @internal.height_in_pixels
|
||||
|
||||
def to_s
|
||||
"#<X11::Screen(#{id}) width=#{width} height=#{height}>"
|
||||
|
|
Loading…
Reference in a new issue