lib/firewatir/x11.rb in firewatir-1.6.5 vs lib/firewatir/x11.rb in firewatir-1.6.6.rc1
- old
+ new
@@ -1,192 +1,192 @@
-require 'dl/import'
-require 'dl/struct'
-
-require 'singleton'
-
-module X11
- class << self
- include X11 # Do this so we can call imported libraries directly on X11
- end
-
- # Load the X11 library
- extend DL::Importable
- dlload "libX11.so"
-
- # Import necessary functions from X11 here.
- import("XOpenDisplay", "unsigned long", ["char*"])
- import("XScreenCount", "int", ["unsigned long"])
- import("XRootWindow", "unsigned long", ["unsigned long","int"])
-
- import("XFree", "int", ["void*"])
-
- import("XFetchName", "int", ["unsigned long","unsigned long","char**"])
- import("XGetClassHint", "int", ["unsigned long","unsigned long","void*"])
- import("XQueryTree", "int", ["unsigned long","unsigned long","unsigned long*","unsigned long*","unsigned long**","unsigned int*"])
-
- import("XSetInputFocus", "int", ["unsigned long","unsigned long","int","long"])
- import("XSendEvent", "int", ["unsigned long","unsigned long","int","long","void*"])
- import("XFlush", "int", ["unsigned long"])
-
- # Structs we will use in API calls.
- # Pointer structs are necessary when the API uses a pointer parameter for a return value.
- ULPPointer = struct [
- "long* value"
- ]
- ULPointer = struct [
- "long value"
- ]
- CPPointer = struct [
- "char* value"
- ]
- UIPointer = struct [
- "int value"
- ]
- # Info about window class
- XClassHint = struct [
- "char* res_name",
- "char* res_class"
- ]
- # Event struct for key presses
- XKeyEvent = struct [
- "int type",
- "long serial",
- "int send_event",
- "long display",
- "long window",
- "long root",
- "long subwindow",
- "long time",
- "int x",
- "int y",
- "int x_root",
- "int y_root",
- "int state",
- "int keycode",
- "int same_screen"
- ]
-
- # End of library imports.
-
- # X11 Display. Singleton -- assumes single display.
- # Assumes the current display is the same as the one running FireFox.
- # Represented by memory pointer (which we treat in-code as an unsigned long).
- class Display
- include Singleton
-
- def initialize
- @xdisplay = X11.xOpenDisplay("");
- end
-
- # Array of screens associated with this display.
- def screens
- nScreens = X11.xScreenCount(@xdisplay);
- (0...nScreens).collect{|n| Screen.new(n,@xdisplay)}
- end
- end
-
- # A display screen, for multi-monitor displays like mine ;-)
- # Represented by display pointer and screen number.
- class Screen
- def initialize(screen_num,xdisplay)
- @screen_num = screen_num
- @xdisplay = xdisplay
- end
-
- # Root window containing all other windows in this screen.
- def root_window
- Window.new(X11.xRootWindow(@xdisplay,@screen_num),@screen_num,@xdisplay)
- end
- end
-
- # An X11 Window (toplevel window, widget, applet, etc.)
- # Represented by its XID, an unsigned long.
- class Window
- attr_reader :xid, :name, :class, :hint, :parent
-
- def initialize(xid,screen_num,xdisplay,parent=nil)
- @xid = xid
- @screen_num = screen_num
- @xdisplay = xdisplay
- @parent = parent
- load_standard
- end
-
- # Child windows
- def children
- tree[:children].collect{|c| Window.new(c,@screen_num,@xdisplay,self)}
- end
-
- # XID of parent window
- def parent_xid
- parent ? parent.xid : nil
- end
-
- # Send a key press to this window
- def send_key(key=:enter,sleep=nil)
- # TODO expand this list out, add support for shift, etc.
- @@keys = {:enter => 36, :tab => 23} unless defined?@@keys
- keycode = @@keys[key]
- X11.xSetInputFocus(@xdisplay, @xid, 1, 0)
- sleep(sleep) if sleep
- e = create_key_event
- e.keycode = keycode
- e.type = 2 # press
- X11.xSendEvent(@xdisplay,@xid,1,1,e)
- e.type = 3 # release
- X11.xSendEvent(@xdisplay,@xid,1,2,e)
- X11.xFlush(@xdisplay)
- end
-
- private
-
- # Retrieve this window's portion of the window tree
- # Includes display root, parent, and children
- def tree
- tree = {:children => [], :parent => 0, :root => 0}
- children = ULPPointer.malloc
- root = ULPointer.malloc
- parent = ULPointer.malloc
- n = UIPointer.malloc
- r=X11.xQueryTree(@xdisplay,@xid,root,parent,children,n)
- tree[:parent] = parent.value
- tree[:root] = root.value
- tree[:children] = children.value.to_s(4*n.value).unpack("L*") if children.value
- tree
- end
-
- # Load some standard attributes (name and class)
- def load_standard
- name = CPPointer.malloc
- if X11.xFetchName(@xdisplay,@xid,name) != 0
- @name = name.value.to_s
- X11.xFree name.value
- end
- classHint = XClassHint.malloc
- res = X11.xGetClassHint(@xdisplay,@xid,classHint)
- if res != 0 then
- @class = classHint.res_name.to_s
- @hint = classHint.res_class.to_s
- X11.xFree classHint.res_name
- X11.xFree classHint.res_class
- end
- end
-
- # Create an X11 Key Event for this window and set defaults
- def create_key_event
- ke = XKeyEvent.malloc
- ke.serial = 0
- ke.send_event = 1
- ke.display = @xdisplay
- ke.window = @xid
- ke.subwindow = 0
- ke.root = tree[:root]
- ke.time = Time.now.sec
- ke.state = 0
- ke.same_screen = 0
- return ke
- end
-
- end
-
-end
-
+require 'dl/import'
+require 'dl/struct'
+
+require 'singleton'
+
+module X11
+ class << self
+ include X11 # Do this so we can call imported libraries directly on X11
+ end
+
+ # Load the X11 library
+ extend DL::Importable
+ dlload "libX11.so"
+
+ # Import necessary functions from X11 here.
+ import("XOpenDisplay", "unsigned long", ["char*"])
+ import("XScreenCount", "int", ["unsigned long"])
+ import("XRootWindow", "unsigned long", ["unsigned long","int"])
+
+ import("XFree", "int", ["void*"])
+
+ import("XFetchName", "int", ["unsigned long","unsigned long","char**"])
+ import("XGetClassHint", "int", ["unsigned long","unsigned long","void*"])
+ import("XQueryTree", "int", ["unsigned long","unsigned long","unsigned long*","unsigned long*","unsigned long**","unsigned int*"])
+
+ import("XSetInputFocus", "int", ["unsigned long","unsigned long","int","long"])
+ import("XSendEvent", "int", ["unsigned long","unsigned long","int","long","void*"])
+ import("XFlush", "int", ["unsigned long"])
+
+ # Structs we will use in API calls.
+ # Pointer structs are necessary when the API uses a pointer parameter for a return value.
+ ULPPointer = struct [
+ "long* value"
+ ]
+ ULPointer = struct [
+ "long value"
+ ]
+ CPPointer = struct [
+ "char* value"
+ ]
+ UIPointer = struct [
+ "int value"
+ ]
+ # Info about window class
+ XClassHint = struct [
+ "char* res_name",
+ "char* res_class"
+ ]
+ # Event struct for key presses
+ XKeyEvent = struct [
+ "int type",
+ "long serial",
+ "int send_event",
+ "long display",
+ "long window",
+ "long root",
+ "long subwindow",
+ "long time",
+ "int x",
+ "int y",
+ "int x_root",
+ "int y_root",
+ "int state",
+ "int keycode",
+ "int same_screen"
+ ]
+
+ # End of library imports.
+
+ # X11 Display. Singleton -- assumes single display.
+ # Assumes the current display is the same as the one running FireFox.
+ # Represented by memory pointer (which we treat in-code as an unsigned long).
+ class Display
+ include Singleton
+
+ def initialize
+ @xdisplay = X11.xOpenDisplay("");
+ end
+
+ # Array of screens associated with this display.
+ def screens
+ nScreens = X11.xScreenCount(@xdisplay);
+ (0...nScreens).collect{|n| Screen.new(n,@xdisplay)}
+ end
+ end
+
+ # A display screen, for multi-monitor displays like mine ;-)
+ # Represented by display pointer and screen number.
+ class Screen
+ def initialize(screen_num,xdisplay)
+ @screen_num = screen_num
+ @xdisplay = xdisplay
+ end
+
+ # Root window containing all other windows in this screen.
+ def root_window
+ Window.new(X11.xRootWindow(@xdisplay,@screen_num),@screen_num,@xdisplay)
+ end
+ end
+
+ # An X11 Window (toplevel window, widget, applet, etc.)
+ # Represented by its XID, an unsigned long.
+ class Window
+ attr_reader :xid, :name, :class, :hint, :parent
+
+ def initialize(xid,screen_num,xdisplay,parent=nil)
+ @xid = xid
+ @screen_num = screen_num
+ @xdisplay = xdisplay
+ @parent = parent
+ load_standard
+ end
+
+ # Child windows
+ def children
+ tree[:children].collect{|c| Window.new(c,@screen_num,@xdisplay,self)}
+ end
+
+ # XID of parent window
+ def parent_xid
+ parent ? parent.xid : nil
+ end
+
+ # Send a key press to this window
+ def send_key(key=:enter,sleep=nil)
+ # TODO expand this list out, add support for shift, etc.
+ @@keys = {:enter => 36, :tab => 23} unless defined?@@keys
+ keycode = @@keys[key]
+ X11.xSetInputFocus(@xdisplay, @xid, 1, 0)
+ sleep(sleep) if sleep
+ e = create_key_event
+ e.keycode = keycode
+ e.type = 2 # press
+ X11.xSendEvent(@xdisplay,@xid,1,1,e)
+ e.type = 3 # release
+ X11.xSendEvent(@xdisplay,@xid,1,2,e)
+ X11.xFlush(@xdisplay)
+ end
+
+ private
+
+ # Retrieve this window's portion of the window tree
+ # Includes display root, parent, and children
+ def tree
+ tree = {:children => [], :parent => 0, :root => 0}
+ children = ULPPointer.malloc
+ root = ULPointer.malloc
+ parent = ULPointer.malloc
+ n = UIPointer.malloc
+ r=X11.xQueryTree(@xdisplay,@xid,root,parent,children,n)
+ tree[:parent] = parent.value
+ tree[:root] = root.value
+ tree[:children] = children.value.to_s(4*n.value).unpack("L*") if children.value
+ tree
+ end
+
+ # Load some standard attributes (name and class)
+ def load_standard
+ name = CPPointer.malloc
+ if X11.xFetchName(@xdisplay,@xid,name) != 0
+ @name = name.value.to_s
+ X11.xFree name.value
+ end
+ classHint = XClassHint.malloc
+ res = X11.xGetClassHint(@xdisplay,@xid,classHint)
+ if res != 0 then
+ @class = classHint.res_name.to_s
+ @hint = classHint.res_class.to_s
+ X11.xFree classHint.res_name
+ X11.xFree classHint.res_class
+ end
+ end
+
+ # Create an X11 Key Event for this window and set defaults
+ def create_key_event
+ ke = XKeyEvent.malloc
+ ke.serial = 0
+ ke.send_event = 1
+ ke.display = @xdisplay
+ ke.window = @xid
+ ke.subwindow = 0
+ ke.root = tree[:root]
+ ke.time = Time.now.sec
+ ke.state = 0
+ ke.same_screen = 0
+ return ke
+ end
+
+ end
+
+end
+