vigilem-x11 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 162ca2f1112eea4acea8fefef0cc1e0bb228d114
4
+ data.tar.gz: f6082f66f84e01897b736694b311a1e9e47b2e81
5
+ SHA512:
6
+ metadata.gz: 37d103aab9dafff1e6e9340249521504047fc37895ac5393ae5f46cc859a35f5f45a7b9f24fc3396591dcb18e935363945a6897cf155c851732f9e2d82e1e6a5
7
+ data.tar.gz: 6e1a02234056c12c0ed2e521d903d054360b902c7556a0c2fe65ab4b08594727bf09aa517e199930c82a81e8003d679705791630b651da7a363ba6011064ebca
@@ -0,0 +1,69 @@
1
+ require 'xlib'
2
+
3
+ require 'vigilem/x11/display'
4
+
5
+ module Vigilem
6
+ module X11
7
+
8
+ module_function
9
+
10
+ # XQueryTree(Display *display, Window w, Window *root_return,
11
+ # Window *parent_return, Window **children_return,
12
+ # unsigned int *nchildren_return);
13
+ # @see man xquerytree
14
+ # @param [#to_ptr] display
15
+ # @param [Integer] w
16
+ # @param [Hash]
17
+ # @option :root_return [::FFI::Pointer<:ulong>]
18
+ # @option :parent_return [::FFI::Pointer<:ulong>]
19
+ # @option :children_return [::FFI::Pointer]
20
+ # @option :nchildren_return [::FFI::Pointer<:uint> || Integer]
21
+ # @return [Fixnum] status
22
+ def query_tree(display, w, opts={})
23
+ opts[:root_return] ||= ::FFI::MemoryPointer.new(:ulong, 1)
24
+ opts[:parent_return] ||= ::FFI::MemoryPointer.new(:ulong, 1)
25
+ opts[:children_return] ||= ::FFI::MemoryPointer.new(:ulong)
26
+ opts[:nchildren_return] ||= ::FFI::MemoryPointer.new(:uint, 1)
27
+
28
+ raise_nil_arg_error('display', display)
29
+ raise_nil_arg_error('w', w)
30
+
31
+ Xlib::XQueryTree(display, w, opts[:root_return], opts[:parent_return],
32
+ opts[:children_return], opts[:nchildren_return])
33
+ opts[:nchildren_return] = opts[:nchildren_return].read_uint
34
+ opts.each do |k,v|
35
+ opts[k] = v.read_ulong if opts[k].respond_to? :read_ulong
36
+ end
37
+ end
38
+
39
+ #
40
+ # @param [#to_ptr] display
41
+ # @param [Integer || ::FFI::Pointer] focus_return
42
+ # @param [Integer || ::FFI::Pointer] revert_to_return
43
+ # @return [Array<Fixnum, Integer, Fixnum>] exit_code, xwindow id, revert_to_return
44
+ def get_input_focus(display, focus_return, revert_to_return=nil)
45
+ display = Vigilem::X11::Display.wrap(display)
46
+ if not focus_return.is_a? ::FFI::MemoryPointer
47
+ fr = focus_return
48
+ focus_return = ::FFI::MemoryPointer.new(:int)
49
+ focus_return.write_int(fr)
50
+ end
51
+ if not revert_to_return.is_a? ::FFI::MemoryPointer
52
+ rtr = revert_to_return
53
+ revert_to_return = ::FFI::MemoryPointer.new(:int)
54
+ revert_to_return.write_int(rtr || 0)
55
+ end
56
+ raise_nil_arg_error('display', display)
57
+ raise_nil_arg_error('focus_return', focus_return)
58
+ [Xlib.XGetInputFocus(display, focus_return, revert_to_return),
59
+ focus_return.read_int, revert_to_return.read_int]
60
+ end
61
+
62
+ def raise_nil_arg_error(name, val)
63
+ raise ArgumentError, "#{name} is #{val.inspect}" if val.nil?
64
+ end
65
+ end
66
+ end
67
+
68
+
69
+ require 'vigilem/x11/input_system_handler'
@@ -0,0 +1,5 @@
1
+ module Vigilem
2
+ module X11
3
+ NotifyNonlinearVirtual = 4
4
+ end
5
+ end
@@ -0,0 +1,53 @@
1
+ require 'xlib'
2
+
3
+ module Vigilem
4
+ module X11
5
+ #
6
+ #
7
+ class Display < Xlib::Display
8
+
9
+ @layout = superclass.layout
10
+
11
+ #
12
+ # @param [Display || FFI::Pointer || String]
13
+ # display_pointer_or_name
14
+ def initialize(display_pointer_or_name)
15
+ if display_pointer_or_name.is_a? ::FFI::Pointer
16
+ super(display_pointer_or_name)
17
+ else
18
+ super(Xlib.XOpenDisplay(display_pointer_or_name))
19
+ end
20
+ end
21
+
22
+ #
23
+ # @return [Fixnum]
24
+ def fileno
25
+ @fileno ||= self[:fd]
26
+ end
27
+
28
+ #
29
+ # @return [UNIXSocket]
30
+ def to_io
31
+ @io ||= UNIXSocket.for_fd(fileno)
32
+ end
33
+
34
+ class << self
35
+ alias_method :open, :new
36
+
37
+ #
38
+ # @param [Display || FFI::Pointer || String]
39
+ # display_obj_pointer_or_name
40
+ # @return [Display]
41
+ def wrap(display_obj_pointer_or_name)
42
+ if display_obj_pointer_or_name.is_a? self
43
+ display_obj_pointer_or_name
44
+ else
45
+ Display.open(display_obj_pointer_or_name)
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,152 @@
1
+ require 'xlib'
2
+
3
+ require 'vigilem/support/obj_space'
4
+
5
+ require 'vigilem/core/buffer'
6
+
7
+ require 'vigilem/core/eventable'
8
+
9
+ require 'vigilem/x11/display'
10
+
11
+ module Vigilem
12
+ module X11
13
+ #
14
+ #
15
+ class EventQueue
16
+
17
+ include Core::Buffer
18
+
19
+ attr_reader :display
20
+
21
+ extend Support::ObjSpace
22
+
23
+ class << self
24
+ #
25
+ # @param [String || Display || ::FFI::Pointer]
26
+ # display_pointer_or_name
27
+ def new(display_obj_pointer_or_name)
28
+ ret = obj_register(super(display_obj_pointer_or_name))
29
+ same_display_check!
30
+ ret
31
+ end
32
+
33
+ #
34
+ # finds an existing EventQueue with the given display or
35
+ # returns a new one based on the items passed in
36
+ # @param [Display || FFI::Pointer || String]
37
+ # display_obj_pointer_or_name
38
+ # @return [EventQueue]
39
+ def acquire(display_obj_pointer_or_name)
40
+ dip = Display.wrap(display_obj_pointer_or_name)
41
+ eventq = all.find {|evq| evq.fileno == dip.fileno }
42
+
43
+ eventq || new(dip)
44
+ end
45
+
46
+ #
47
+ # @return [Array]
48
+ def same_display_check
49
+ all.group_by {|ev| ev.display.fileno }.select {|k, v| v.size > 1 }
50
+ end
51
+
52
+ #
53
+ # @param [StandardError] err_type, defaults to ArgumentError
54
+ # @raise "EventQueues should not have the same display `#{array of event queues with same display}'"
55
+ # @return [NilClass]
56
+ def same_display_check!(err_type=ArgumentError)
57
+ unless (dups = same_display_check).empty?
58
+ raise err_type, "EventQueues should not have the same display `#{dups}'"
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ #
65
+ # @param [String || Display || ::FFI::Pointer]
66
+ # display_pointer_or_name
67
+ def initialize(display_obj_pointer_or_name)
68
+ @display = Display.wrap(display_obj_pointer_or_name)
69
+ end
70
+
71
+ # the XPending and items pulled from the queue that
72
+ # haven't propagated
73
+ # @return [Fixnum]
74
+ def pending
75
+ pending! + _internal_buffer.size
76
+ end
77
+
78
+ # only the number of events returned by XPending
79
+ # @return [Fixnum]
80
+ def pending!
81
+ Xlib.XPending(display!)
82
+ end
83
+
84
+ #
85
+ # @return [Xlib::XEvent]
86
+ def next_event
87
+ x_event = Xlib::XEvent.new
88
+ Xlib.XNextEvent(display!, x_event)
89
+ x_event
90
+ end
91
+
92
+ #
93
+ # @return [Fixnum]
94
+ def fileno
95
+ @fileno ||= display.fileno
96
+ end
97
+
98
+ #
99
+ # @raise [ArgumentError]
100
+ # @return
101
+ def display!
102
+ # a way to validate the pointer to prevent segfault?
103
+ if display.is_a?(::FFI::Pointer) or display.respond_to?(:to_ptr)
104
+ display
105
+ else
106
+ raise ArgumentError, "Display is a `#{display.inspect}'" +
107
+ "and doesn't respond to :to_ptr"
108
+ end
109
+ end
110
+
111
+ #
112
+ # @param [Integer || Range] start_idx_range
113
+ # @param [Integer] len
114
+ # @return [Array]
115
+ def slice!(start_idx_range, len=nil)
116
+ # this isn;t the most efficient way, but is the
117
+ # most straight forward
118
+ pending!.times.map do
119
+ next_event
120
+ end.compact.slice!(start_idx_range, *len)
121
+ end
122
+
123
+ #
124
+ # @raise [NotImplemented]
125
+ def concat(*args)
126
+ raise NotImplementedError
127
+ end
128
+
129
+ #
130
+ # @raise [NotImplemented]
131
+ def peek
132
+ raise NotImplementedError
133
+ # @todo
134
+ #if _internal_buffer.size > 0
135
+ # _internal_buffer[0]
136
+ #else
137
+ # if pending! > 0
138
+ # next_event
139
+ # end
140
+ #end
141
+ end
142
+
143
+ private
144
+ #
145
+ # @return [Array]
146
+ def _internal_buffer
147
+ @internal_buffer ||= []
148
+ end
149
+
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,75 @@
1
+ require 'vigilem/x11'
2
+
3
+ require 'vigilem/core/input_system_handler'
4
+
5
+ require 'vigilem/x11/constants'
6
+
7
+ require 'vigilem/x11/display'
8
+
9
+ require 'vigilem/x11/event_queue'
10
+
11
+ module Vigilem
12
+ module X11
13
+ #
14
+ #
15
+ class InputSystemHandler
16
+ include Core::InputSystemHandler
17
+
18
+ attr_reader :window_xid, :demultiplexer
19
+
20
+ #
21
+ # @param [Integer] win_xid
22
+ # @param [String || Display || ::FFI::Pointer] display_pointer_or_name
23
+ # @param [Integer] event_mask
24
+ def initialize(win_xid, display_obj_pointer_or_name, event_mask=nil)
25
+
26
+ initialize_input_system_handler
27
+
28
+ display = Display.open(display_obj_pointer_or_name)
29
+
30
+ @demultiplexer = Core::Demultiplexer.acquire(EventQueue.new(display), [[self.buffer, {:func => :concat}]]) do |dem|
31
+ dem.input.respond.fileno == display.fileno
32
+ end
33
+
34
+ @window_xid = win_xid
35
+
36
+ self.select_input(event_mask) if event_mask
37
+
38
+ end
39
+
40
+ include Core::Eventable
41
+
42
+ #
43
+ # @param [Fixnum] num
44
+ # @return [Array]
45
+ def read_many_nonblock(num=1)
46
+ synchronize {
47
+ demultiplexer.demux(num)
48
+ buffer.slice!(0, num)
49
+ }
50
+ end
51
+
52
+ # @todo handle `X Error of failed request: BadWindow (invalid Window parameter)'
53
+ # @param [Fixnum]
54
+ # @return [Fixnum]
55
+ def select_input(event_mask)
56
+ Xlib.XSelectInput(demultiplexer.input.display, window_xid, event_mask)
57
+ end
58
+
59
+ def_delegators :'demultiplexer.input', :pending, :display
60
+
61
+ # @see http://www.unix.com/man-page/All/3x/XGetInputFocus/
62
+ # @return [Array<Integer, Fixnum>] [xwindow_id, revert_to_return]
63
+ def get_input_focus
64
+ X11.get_input_focus(display, window_xid, 0)[1..-1]
65
+ end
66
+
67
+ # @see ::query_tree
68
+ # @return [Hash]
69
+ def query_tree(opts={})
70
+ X11.query_tree(display, window_xid, opts)
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,37 @@
1
+ module Vigilem
2
+ module X11
3
+ module System
4
+ # gets the
5
+ # @param [Integer] pid
6
+ # @return [Integer || NilClass]
7
+ def ppid_of(pid)
8
+ to_i!(`ps -p #{pid} -o ppid= 2>&1`.strip)
9
+ end
10
+
11
+ #
12
+ # @param [Intger] pid
13
+ # @return [File]
14
+ def environ_file(pid='self')
15
+ file_path = "#{File::SEPARATOR}#{File.join('proc', pid.to_s, 'environ')}"
16
+ if test ?e, file_path
17
+ @environ = File.open(file_path)
18
+ end
19
+ end
20
+
21
+ # like #to_i but returns nil if not convertable
22
+ # @todo move to support/core_ext
23
+ # @param [String] str
24
+ # @return [Integer || NilClass]
25
+ def to_i!(str)
26
+ if str =~ /^\s*(0+|(0*\.0+))\s*$/
27
+ 0
28
+ else
29
+ [str.to_i].find {|i| i != 0 }
30
+ end
31
+ end
32
+
33
+ extend self
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ require 'vigilem/x11/system'
2
+
3
+ module Vigilem
4
+ module X11
5
+ #
6
+ #
7
+ module TerminalWindowUtils
8
+
9
+ extend System
10
+
11
+ module_function
12
+
13
+ # gets the id of the window that spawned this
14
+ # ruby process
15
+ # @return [Integer]
16
+ def window_id
17
+ return (env = to_i!(ENV['WINDOWID'])) if env
18
+
19
+ curr_pid = Process.pid
20
+ until curr_pid.to_i < 2
21
+ file = environ_file(curr_pid)
22
+ if file and (xid = to_i!(file.read.scan(/(?<=WINDOWID=)\d+/)[0]))
23
+ return xid
24
+ else
25
+ curr_pid = ppid_of(curr_pid)
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Vigilem
2
+ module X11
3
+ VERSION = '0.0.3'
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'xlib'
2
+
3
+ require 'vigilem/support/core_ext/debug_puts'
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ require 'vigilem/x11/display'
4
+
5
+ describe Vigilem::X11::Display do
6
+
7
+ after(:each) do
8
+ [described_class].each do |klass|
9
+ (klass.instance_variables - [:@layout]).each do |ivar|
10
+ klass.send(:remove_instance_variable, ivar)
11
+ end
12
+ end
13
+ end
14
+
15
+ it 'is a subclass of Xlib::Display' do
16
+ expect(described_class).to be < Xlib::Display
17
+ end
18
+
19
+ it 'has the same structure as Xlib::Display' do
20
+ expect(described_class.layout).to eql(Xlib::Display.layout)
21
+ end
22
+
23
+ describe '#initialize' do
24
+ it 'takes a pointer and creates a display from it' do
25
+ expect do
26
+ described_class.new(Xlib.XOpenDisplay(ENV['DISPLAY']))
27
+ end.not_to raise_error and be_a described_class
28
+ end
29
+
30
+ it 'takes a display name and creates a Display' do
31
+ expect do
32
+ described_class.new(ENV['DISPLAY'])
33
+ end.not_to raise_error and be_a described_class
34
+ end
35
+ end
36
+
37
+ context 'post_init' do
38
+ subject { described_class.new(ENV['DISPLAY']) }
39
+
40
+ describe '#fileno' do
41
+ it 'returns the fileno of the associated IO' do
42
+ expect(subject.fileno).to be_an Integer
43
+ end
44
+ end
45
+
46
+ describe '#to_io' do
47
+ it 'returns the display as IO' do
48
+ expect(subject.to_io).to be_a IO
49
+ end
50
+ end
51
+ end
52
+
53
+ describe '::wrap' do
54
+ it 'returns a new display object' do
55
+ expect { described_class.wrap(ENV['DISPLAY']) }.not_to raise_error and be_a Display
56
+ end
57
+
58
+ it 'takes a pointer and creates a display from it' do
59
+ expect { described_class.wrap(Xlib.XOpenDisplay(ENV['DISPLAY'])) }.not_to raise_error and be_a Display
60
+ end
61
+
62
+ it 'takes a Display object and returns the same Display object' do
63
+ dpy = described_class.wrap(ENV['DISPLAY'])
64
+ expect { described_class.wrap(dpy) }.not_to raise_error and eql(dpy)
65
+ end
66
+ end
67
+
68
+ #describe '::open' do
69
+ #
70
+ #end
71
+
72
+ end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ require 'vigilem/x11/event_queue'
4
+
5
+ describe Vigilem::X11::EventQueue do
6
+
7
+ let(:dpy) { Vigilem::X11::Display.new(ENV['DISPLAY']) }
8
+
9
+ after(:each) do
10
+ [described_class, Vigilem::X11::Display].each do |klass|
11
+ (klass.instance_variables - [:@layout]).each do |ivar|
12
+ klass.send(:remove_instance_variable, ivar)
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '::same_display_check' do
18
+
19
+ it %q<checks the ::all for EventQueue's that have the same fileno> do
20
+ ary = [double("EventQueue1", :display => dpy), double("EventQueue2", :display => dpy)]
21
+ described_class.all.concat(ary)
22
+ expect(described_class.same_display_check).to eql({ dpy.fileno => ary })
23
+ end
24
+
25
+ end
26
+
27
+ describe '::same_display_check!' do
28
+
29
+ it %q<checks the ::all for EventQueue's that have the same fileno and raises an Error if some exist> do
30
+ ary = [double("EventQueue1", :display => dpy), double("EventQueue2", :display => dpy)]
31
+ described_class.all.concat(ary)
32
+ expect { described_class.same_display_check! }.to raise_error(ArgumentError)
33
+ end
34
+
35
+ end
36
+
37
+ describe '#initialize' do
38
+ it 'accepts a display obj' do
39
+ expect do
40
+ described_class.new(dpy)
41
+ end.to_not raise_error and be_a described_class
42
+ end
43
+
44
+ it 'accepts a display pointer' do
45
+ expect do
46
+ described_class.new(Xlib.XOpenDisplay(ENV['DISPLAY']))
47
+ end.to_not raise_error and be_a described_class
48
+ end
49
+
50
+ it 'accepts a display_name' do
51
+ expect do
52
+ described_class.new(ENV['DISPLAY'])
53
+ end.to_not raise_error and be_a described_class
54
+ end
55
+
56
+ end
57
+
58
+ describe '::new' do
59
+ it 'adds the instance to ' do
60
+ dpy = described_class.new(ENV['DISPLAY'])
61
+ expect(described_class.all).to include(dpy)
62
+ end
63
+
64
+ it 'calls #same_display_check!' do
65
+ ary = [double("EventQueue1", :display => dpy), double("EventQueue2", :display => dpy)]
66
+ described_class.all.concat(ary)
67
+ expect { described_class.new(dpy) }.to raise_error(ArgumentError)
68
+ end
69
+ end
70
+
71
+ describe '::acquire' do
72
+ it 'returns a new instance if none is found' do
73
+ described_class.all.replace([])
74
+ dspy = Vigilem::X11::Display.new(ENV['DISPLAY'])
75
+ expect(described_class.acquire(dspy)).to be_a described_class
76
+ end
77
+
78
+ it 'returns the instance that has the same display#fileno' do
79
+ evq = described_class.new(dpy)
80
+ expect(described_class.acquire(dpy)).to eql(evq)
81
+ end
82
+ end
83
+
84
+ describe '#pending!' do
85
+ it 'gets the XPending value' do
86
+ evq = described_class.new(dpy)
87
+ num = 1
88
+ allow(Xlib).to receive(:XPending) { num }
89
+ expect(evq.pending!).to eql(num)
90
+ end
91
+ end
92
+
93
+ describe '#pending' do
94
+ it 'gets the XPending value and the size of the array not yet propagated' do
95
+ evq = described_class.new(dpy)
96
+ internal_buf = [Xlib::XEvent.new, Xlib::XEvent.new]
97
+ evq.send(:_internal_buffer).concat(internal_buf)
98
+ xpend_ret = 1
99
+ allow(Xlib).to receive(:XPending) { xpend_ret }
100
+ expect(evq.pending).to eql(xpend_ret + internal_buf.size)
101
+ end
102
+ end
103
+
104
+ describe '#next_event' do
105
+ it 'gets the next event from the xwindow event queue' do
106
+ allow(Xlib).to receive(:XNextEvent)
107
+ evq = described_class.new(dpy)
108
+ expect(evq.next_event).to be_a Xlib::XEvent
109
+ end
110
+ end
111
+
112
+ describe '#fileno' do
113
+ it 'gets the fileno of the display' do
114
+ evq = described_class.new(dpy)
115
+ expect(evq.fileno).to eql(evq.fileno)
116
+ end
117
+ end
118
+
119
+ describe '#slice!' do
120
+ it 'will get the ' do
121
+ evq = described_class.new(dpy)
122
+ allow(evq).to receive(:pending!) { 1 }
123
+ empty_event = Xlib::XEvent.new
124
+ allow(evq).to receive(:next_event) { empty_event }
125
+ expect(evq.slice!(0)).to eql(empty_event)
126
+ end
127
+ end
128
+
129
+ describe '#concat' do
130
+ it 'will error, not implemented' do
131
+ evq = described_class.new(dpy)
132
+ expect { evq.concat }.to raise_error(NotImplementedError)
133
+ end
134
+ end
135
+
136
+ describe '#peek' do
137
+ it 'will error, no implemented' do
138
+ evq = described_class.new(dpy)
139
+ expect { evq.concat }.to raise_error(NotImplementedError)
140
+ end
141
+ end
142
+
143
+ context 'private' do
144
+ describe '#_internal_buffer' do
145
+ it 'defaults to an empty array' do
146
+ evq = described_class.new(dpy)
147
+ expect(evq.send(:_internal_buffer)).to eql([])
148
+ end
149
+ end
150
+ end
151
+
152
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ require 'vigilem/x11/input_system_handler'
4
+
5
+ describe Vigilem::X11::InputSystemHandler do
6
+
7
+ subject { described_class.new(0x12123, (ENV['DISPLAY'] || ::FFI::MemoryPointer.new(:long, 296))) }
8
+
9
+ after(:each) do
10
+ [described_class, Vigilem::X11::EventQueue, Vigilem::Core::Demultiplexer, Vigilem::X11::Display].each do |klass|
11
+ (klass.instance_variables - [:@layout]).each do |ivar|
12
+ klass.send(:remove_instance_variable, ivar)
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '#select_input' do
18
+ it 'calls XSelectInput' do
19
+ mask = Xlib::KeyPressMask | Xlib::FocusChangeMask
20
+ allow(Xlib).to receive(:XSelectInput).with(mask)
21
+ expect(Xlib).to receive(:XSelectInput).with(subject.demultiplexer.input.display, subject.window_xid, mask)
22
+ subject.select_input(mask)
23
+ end
24
+ end
25
+
26
+ describe '#initialize' do
27
+
28
+ it 'sets up the window if the window_xid was given' do
29
+ expect(subject.window_xid).to be_an Integer
30
+ end
31
+
32
+ it 'calls XSelectInput if passed in' do
33
+ mask = Xlib::KeyPressMask | Xlib::FocusChangeMask
34
+ allow(Xlib).to receive(:XSelectInput).with(mask)
35
+ expect(Xlib).to receive(:XSelectInput)
36
+ Vigilem::X11::EventQueue.all.replace([])
37
+ described_class.new(0x1111, ::FFI::MemoryPointer.new(:long, 296), mask)
38
+ end
39
+ end
40
+
41
+ describe '#read_many_nonblock' do
42
+ it 'reads a max number of events from the event_queue' do
43
+ allow(subject.demultiplexer.input).to receive(:shift) { [1,2,3] }
44
+ expect(subject.read_many_nonblock(3)).to eql([1,2,3])
45
+ end
46
+
47
+ it 'calls #synchronize' do
48
+ allow(subject.demultiplexer.input).to receive(:shift) { [1,2,3] }
49
+ expect(subject).to receive(:synchronize)
50
+ subject.read_many_nonblock(3)
51
+ end
52
+
53
+ it 'sets up the other eventable methods' do
54
+ allow(subject.demultiplexer.input).to receive(:shift) { [1] }
55
+ expect { subject.read_one_nonblock }.not_to raise_error and eql([1])
56
+ end
57
+ end
58
+
59
+ describe '#get_input_focus' do
60
+ it 'calls ::get_input_focus' do
61
+ allow(Vigilem::X11).to receive(:get_input_focus)
62
+ expect(Vigilem::X11).to receive(:get_input_focus).with(subject.display, subject.window_xid, 0) { [1,2,3] }
63
+ subject.get_input_focus
64
+ end
65
+
66
+ if Xlib.available?
67
+ it 'returns a Fixnum, and Integer' do
68
+ allow(described_class).to receive(:get_input_focus).and_call_original
69
+ expect(subject.get_input_focus).to match [a_kind_of(Fixnum), a_kind_of(Integer)]
70
+ end
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ require 'vigilem/x11/system'
4
+
5
+ describe Vigilem::X11::System do
6
+
7
+ describe '::to_i!' do
8
+ it 'returns an Integer if convertable' do
9
+ expect(described_class.to_i!("1234.1234")).to eql(1234)
10
+ end
11
+
12
+ it 'returns an nil if not convertable' do
13
+ expect(described_class.to_i!("Sjaldan er ein baran stok")).to be_nil
14
+ end
15
+
16
+ it 'returns 0 when the value is zero' do
17
+ expect(described_class.to_i!("0")).to eql(0)
18
+ end
19
+
20
+ it 'returns 0 when the value is zero equivilant' do
21
+ expect(described_class.to_i!(".00")).to eql(0)
22
+ end
23
+
24
+ it %q<doesn't return 0 if it contains zero> do
25
+ expect(described_class.to_i!('83886092')).to eql(83886092)
26
+ end
27
+ end
28
+
29
+ describe '::environ_file' do
30
+ it 'defaults to the /proc/self/environ' do
31
+ expect(described_class.environ_file.path).to eql("/proc/self/environ")
32
+ end
33
+
34
+ it 'gets the environ file of the pid passed in' do
35
+ expect(described_class.environ_file(Process.pid).path).to eql("/proc/#{Process.pid}/environ")
36
+ end
37
+ end
38
+
39
+ describe '::ppid_of' do
40
+ it 'gets the ppid of the passed in pid' do
41
+ expect(described_class.ppid_of(Process.pid)).to eql(Process.ppid)
42
+ end
43
+
44
+ it 'returns nil if ppid cannot be found' do
45
+ expect(described_class.ppid_of(`cat /proc/sys/kernel/pid_max`.to_i + 1)).to be_nil
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ require 'tempfile'
4
+
5
+ require 'vigilem/x11/terminal_window_utils'
6
+
7
+ describe Vigilem::X11::TerminalWindowUtils do
8
+
9
+ describe '::window_id' do
10
+ it 'returns the id of the window if it exists' do
11
+ expect(described_class.window_id).to be > 0
12
+ end
13
+
14
+ it 'checks the environ_file if the ENV is empty' do
15
+
16
+ ENV['WINDOWID'] = ''
17
+ allow(described_class).to receive(:environ_file) { Tempfile.new('asdf') }
18
+ expect(described_class).to receive(:environ_file)
19
+ described_class.window_id
20
+ end
21
+
22
+ it 'returns traverses the pid tree to find an WINDOWID in the environ_file' do
23
+ ENV['WINDOWID'] = ''
24
+ allow(described_class).to receive(:environ_file) { Tempfile.new('asdf') }
25
+ expect(described_class.window_id).to be_nil
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ require 'vigilem/x11'
2
+
3
+ describe Vigilem::X11 do
4
+ if Xlib.available?
5
+
6
+ describe '::get_input_focus' do
7
+
8
+ let(:display) { Vigilem::X11::Display.new(ENV['DISPLAY'] || ::FFI::MemoryPointer.new(:long, 296)) }
9
+
10
+ let(:win_id) { 0x12123 }
11
+
12
+ =begin
13
+ # this should work, but allow strips out the arguments (or something) and
14
+ # then ArgumentError: "Invalid Memory object" is raised
15
+ it 'calls XGetInputFocus' do
16
+ allow(Xlib).to receive(:XGetInputFocus).with(a_kind_of(::FFI::Struct), a_kind_of(Fixnum), a_kind_of(Fixnum))
17
+ expect(Xlib).to receive(:XGetInputFocus).with(a_kind_of(::FFI::Struct), a_kind_of(Fixnum), a_kind_of(Fixnum))
18
+
19
+ subject.get_input_focus
20
+ end
21
+ =end
22
+ it 'accepts [String],[Fixnum],[Fixnum] returns [Fixnum, Integer, Fixnum]' do
23
+ expect(described_class.get_input_focus(display, win_id)).to match [
24
+ a_kind_of(Fixnum), a_kind_of(Integer), a_kind_of(Fixnum)
25
+ ]
26
+ end
27
+
28
+ it 'updates window ptr' do
29
+ window = FFI::MemoryPointer.new(:ulong)
30
+ window.write_ulong(win_id)
31
+ described_class.get_input_focus(display, window)
32
+ expect(window.read_int).not_to eql(win_id)
33
+ end
34
+
35
+ it 'updates revert_to_return ptr' do
36
+ revert_to_return = FFI::MemoryPointer.new(:int)
37
+ revert_to_return.write_int(0)
38
+ described_class.get_input_focus(display, win_id)
39
+ expect(revert_to_return.read_int).to be_a Fixnum
40
+ end
41
+ end
42
+
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vigilem-x11
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - jtzero
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xlib
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: vigilem-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '3.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '3.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-given
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: turnip
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: guard-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: X11 bindings for Vigilem, currently used internally only
140
+ email:
141
+ - jtzero511@gmail
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - lib/vigilem/x11.rb
147
+ - lib/vigilem/x11/constants.rb
148
+ - lib/vigilem/x11/display.rb
149
+ - lib/vigilem/x11/event_queue.rb
150
+ - lib/vigilem/x11/input_system_handler.rb
151
+ - lib/vigilem/x11/system.rb
152
+ - lib/vigilem/x11/terminal_window_utils.rb
153
+ - lib/vigilem/x11/version.rb
154
+ - spec/spec_helper.rb
155
+ - spec/vigilem/x11/display_spec.rb
156
+ - spec/vigilem/x11/event_queue_spec.rb
157
+ - spec/vigilem/x11/input_system_handler_spec.rb
158
+ - spec/vigilem/x11/system_spec.rb
159
+ - spec/vigilem/x11/terminal_window_utils_spec.rb
160
+ - spec/vigilem/x11_spec.rb
161
+ homepage: http://rubygems.org/gems/vigilem-x11
162
+ licenses:
163
+ - MIT
164
+ metadata: {}
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 2.4.6
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: X11 bindings for Vigilem
185
+ test_files:
186
+ - spec/spec_helper.rb
187
+ - spec/vigilem/x11/display_spec.rb
188
+ - spec/vigilem/x11/event_queue_spec.rb
189
+ - spec/vigilem/x11/input_system_handler_spec.rb
190
+ - spec/vigilem/x11/system_spec.rb
191
+ - spec/vigilem/x11/terminal_window_utils_spec.rb
192
+ - spec/vigilem/x11_spec.rb