vigilem-x11 0.0.3

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.
@@ -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