xlib-objects 0.6.3 → 0.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a7de1f655c5f8f27b0741b9f991bfe08a162e5a
4
- data.tar.gz: 8d0d1d94558f9093b12a0595bf1f43a1ab1917f9
3
+ metadata.gz: 5a7725013756732b19e1d6cad4a23e39db1db597
4
+ data.tar.gz: fd41104e5db94a5f0e9e162e7addfb73cae71c66
5
5
  SHA512:
6
- metadata.gz: bf40a03630e0bb7e5754f57ac3486804fcf80b2a0c8c4f76288f321962200de83b2961a3b421894cf6f064aff6e841812a79db39264ce9cdd8005e9323f1a4fb
7
- data.tar.gz: 5c2cf3f1bbb0ab353ead915c34068e78ef52c52dc352ee300a8e4b9a481fb99d6ca6bc9a58cd29df4516330e4e9499c62c46117d5d50f485a00bd04bfe4d44d3
6
+ metadata.gz: 2192da1bfc5495095d66616f9800c63723df3a3041fa04dc2557583887469d3cb383de1242f55a90edd6db8f887b38f503dcd6bb6c57cffd35c72773381d3d1e
7
+ data.tar.gz: 44300b382803c33c2cd5c3cfe2a51b5ec6c6b4eed1ac6a2eb4cddfe0755e88ca634c98ea32e106377bbc31999bb635169289d9ed1e40f098fda4d8d61801b5ea
data/lib/display.rb CHANGED
@@ -20,9 +20,7 @@ module XlibObj
20
20
  end
21
21
 
22
22
  def initialize(name)
23
- display_pointer = Xlib.XOpenDisplay(name)
24
- raise ArgumentError, "Unknown display #{name}" if display_pointer.null?
25
- @struct = Xlib::Display.new(display_pointer)
23
+ @struct = Xlib::X.open_display(name)
26
24
  end
27
25
 
28
26
  def to_native
@@ -41,12 +39,38 @@ module XlibObj
41
39
  (0..@struct[:nscreens]-1).map{ |number| screen(number) }
42
40
  end
43
41
 
42
+ def extensions
43
+ @extensions ||= ['CORE', *Xlib::X.list_extensions(self)].map do |name|
44
+ Extension.for(self, name)
45
+ end
46
+ end
47
+
48
+ def input_devices
49
+ device_infos = Xlib::XI.query_device(self, Xlib::XIAllDevices)
50
+ device_ids = device_infos.map{ |dev| dev[:deviceid] }
51
+ Xlib::XI.free_device_info(device_infos.first)
52
+ device_ids.map do |device_id|
53
+ InputDevice.new(self, device_id)
54
+ end
55
+ end
56
+
57
+ def keyboards
58
+ input_devices.select(&:keyboard?)
59
+ end
60
+
61
+ def pointers
62
+ input_devices.select(&:pointer?)
63
+ end
64
+
44
65
  def focused_window
45
66
  screens.reduce(nil){ |focused_window, s| focused_window or s.focused_window }
46
67
  end
47
68
 
48
69
  def handle_events
49
- handle_event(next_event) while pending_events > 0
70
+ while Xlib::X.pending(self) > 0
71
+ xevent = Xlib::X.next_event(self)
72
+ Event.new(self, xevent).extension_event.handle
73
+ end
50
74
  end
51
75
 
52
76
  def selection(*args, &on_receive)
@@ -61,7 +85,7 @@ module XlibObj
61
85
 
62
86
  def on_error(&callback)
63
87
  @error_handler = if callback
64
- FFI::Function.new(:pointer, [:pointer, :pointer]) do |display_ptr, error_ptr|
88
+ FFI::Function.new(:int, [:pointer, :pointer]) do |display_ptr, error_ptr|
65
89
  next if display_ptr != to_native
66
90
  x_error = Xlib::XErrorEvent.new(error_ptr)
67
91
  callback.call Error.new(self, x_error)
@@ -87,8 +111,11 @@ module XlibObj
87
111
  end
88
112
 
89
113
  def flush
90
- Xlib.XFlush(to_native)
91
- handle_events
114
+ handle_events # XPending flushes the output buffer: http://tronche.com/gui/x/xlib/event-handling/XFlush.html
115
+ end
116
+
117
+ def close
118
+ Xlib::X.close_display(self)
92
119
  end
93
120
 
94
121
  private
@@ -97,22 +124,6 @@ module XlibObj
97
124
  @internal_window ||= screen.root_window.create_window
98
125
  end
99
126
 
100
- def pending_events
101
- Xlib.XPending(to_native)
102
- end
103
-
104
- def next_event
105
- x_event = Xlib::XEvent.new
106
- Xlib.XNextEvent(to_native, x_event) # blocks
107
- Event.new(x_event)
108
- end
109
-
110
- def handle_event(event)
111
- handling_window_id = event.event || event.parent || event.window || event.owner || event.requestor
112
- handling_window = Window.new(self, handling_window_id)
113
- handling_window.handle(event)
114
- end
115
-
116
127
  def screen_pointer(number)
117
128
  @struct[:screens] + number*Xlib::Screen.size
118
129
  end
data/lib/error.rb CHANGED
@@ -10,78 +10,50 @@ module XlibObj
10
10
  class Error < StandardError
11
11
  def initialize(display, error)
12
12
  @display = display
13
- @error = error
14
- end
15
-
16
- def code
17
- @error[:error_code]
18
- end
19
-
20
- def minor_code
21
- @error[:minor_code]
22
- end
23
-
24
- def request
25
- @error[:request_code]
26
- end
27
-
28
- def resource
29
- @error[:resourceid]
13
+ @error_code = error[:error_code]
14
+ @request_code = error[:request_code]
15
+ @minor_code = error[:minor_code]
16
+ @resource = error[:resourceid]
30
17
  end
31
18
 
32
19
  def description
33
- "#{general_description}\n" <<
34
- " #{code_description}\n" <<
35
- ((code >= 128) ? " #{minor_code_description}\n" : "") <<
36
- " #{resource_description}"
20
+ "#{request_description}\n" <<
21
+ "Error: #{error_description}\n" <<
22
+ "Resource: #{resource_description}"
37
23
  end
24
+ alias_method :message, :description
38
25
 
39
- def general_description
40
- type_size = 2**16
41
- type = FFI::MemoryPointer.new(:char, type_size)
42
- Xlib.XGetErrorDatabaseText(@display.to_native, @display.name, 'XError', 'X Error', type,
43
- type_size)
44
-
45
- details_size = 2**16
46
- details = FFI::MemoryPointer.new(:char, details_size)
47
- Xlib.XGetErrorText(@display.to_native, code, details, details_size)
48
-
49
- "#{type.read_string}: #{details.read_string}"
26
+ def request_description
27
+ @request_code < 128 ? major_request_description : minor_request_description
50
28
  end
51
29
 
52
- def code_description
53
- message_size = 2**16
30
+ def major_request_description
31
+ message_size = 256
54
32
  message = FFI::MemoryPointer.new(:char, message_size)
55
- Xlib.XGetErrorDatabaseText(@display.to_native, @display.name, 'MajorCode',
56
- 'Request Major code %d', message, message_size)
57
- message.read_string.gsub('%d', code.to_s)
33
+ Xlib.XGetErrorDatabaseText(@display.to_native, 'XRequest', "#{@request_code}",
34
+ "Major code #{@request_code}", message, message_size)
35
+ message.read_string
58
36
  end
59
37
 
60
- def minor_code_description
61
- message_size = 2**16
38
+ def minor_request_description
39
+ message_size = 256
62
40
  message = FFI::MemoryPointer.new(:char, message_size)
63
- Xlib.XGetErrorDatabaseText(@display.to_native, @display.name, 'MinorCode',
64
- 'Request Minor code %d', message, message_size)
65
- message.read_string.gsub('%d', minor_code.to_s)
41
+ extension = @display.extensions.find{ |ext| ext.opcode == @request_code }
42
+ Xlib.XGetErrorDatabaseText(@display.to_native, "XRequest.#{extension.name}", "#{@minor_code}",
43
+ "Minor code #{@minor_code}", message, message_size)
44
+ "#{extension.name} #{message.read_string}"
66
45
  end
67
46
 
68
- def resource_description
69
- message_size = 2**16
47
+ def error_description
48
+ message_size = 256
70
49
  message = FFI::MemoryPointer.new(:char, message_size)
50
+ Xlib.XGetErrorDatabaseText(@display.to_native, 'XProtoError', "#{@error_code}",
51
+ "Error code #{@error_code}", message, message_size)
52
+ message.read_string
53
+ end
71
54
 
72
- if [Xlib::BadWindow, Xlib::BadPixmap, Xlib::BadCursor, Xlib::BadFont, Xlib::BadDrawable,
73
- Xlib::BadColor, Xlib::BadGC, Xlib::BadIDChoice].include?(code)
74
- Xlib.XGetErrorDatabaseText(@display.to_native, @display.name, "ResourceID",
75
- "ResourceID %x", message, message_size)
76
- elsif code == Xlib::BadValue
77
- Xlib.XGetErrorDatabaseText(@display.to_native, @display.name, "Value", "Value 0x%x",
78
- message, message_size)
79
- elsif code == Xlib::BadAtom
80
- Xlib.XGetErrorDatabaseText(@display.to_native, @display.name, "AtomID", "AtomID 0x%x",
81
- message, message_size)
82
- end
83
-
84
- message.read_string.gsub('%x', resource.to_s)
55
+ def resource_description
56
+ @resource
85
57
  end
86
58
  end
87
59
  end
data/lib/event.rb CHANGED
@@ -1,248 +1,40 @@
1
- #
2
- # Copyright (c) 2014 Christopher Aue <mail@christopheraue.net>
3
- #
4
- # This file is part of the ruby xlib-objects gem. It is subject to the license
5
- # terms in the LICENSE file found in the top-level directory of this
6
- # distribution and at http://github.com/christopheraue/ruby-xlib-objects.
7
- #
8
-
9
1
  module XlibObj
10
2
  class Event
11
- def initialize(event)
12
- @event = event
13
- struct && (struct.members-[:type]).each do |key|
14
- define_singleton_method(key) { struct[key] }
15
- end
16
- end
17
-
18
- def name
19
- @name ||= (x_name || xrr_name)
3
+ def initialize(display, xevent)
4
+ @display = display
5
+ @xevent = xevent
20
6
  end
21
7
 
22
- def method_missing(name)
23
- nil
24
- end
8
+ attr_reader :xevent
25
9
 
26
- private
27
10
  def type
28
- @event[:type]
29
- end
30
-
31
- def struct
32
- @struct ||= (xrr_struct || x_struct)
33
- end
34
-
35
- def union_member
36
- self.class::TYPE_TO_UNION_MEMBER[type]
11
+ @xevent[:type]
37
12
  end
38
13
 
39
- def x_struct
40
- @event[union_member]
14
+ def generic?
15
+ type == Xlib::GenericEvent
41
16
  end
42
17
 
43
- def xrr_type
44
- type-self.class.xrr_type_offset(@event[:xany][:display])
18
+ def data?
19
+ @is_cookie ||= generic? && Xlib::X.get_event_data(@display, cookie)
45
20
  end
46
21
 
47
- def xrr_struct
48
- xrr_subtype_struct || xrr_type_struct
22
+ def cookie
23
+ @xevent[:xcookie]
49
24
  end
50
25
 
51
- def xrr_type_struct
52
- struct = self.class::RR_TYPE_TO_STRUCT[xrr_type]
53
- struct.new(@event.pointer) if struct
26
+ def opcode
27
+ (data? and cookie[:extension])
54
28
  end
55
29
 
56
- def xrr_subtype_struct
57
- if xrr_type == Xlib::RRNotify
58
- struct = self.class::RR_SUBTYPE_TO_STRUCT[xrr_type_struct[:subtype]]
59
- struct.new(@event.pointer) if struct
30
+ def extension
31
+ @extension ||= @display.extensions.find do |ext|
32
+ data? ? opcode == ext.opcode : ext.event_range.include?(type)
60
33
  end
61
34
  end
62
35
 
63
- def x_name
64
- self.class::TYPE.key(type)
65
- end
66
-
67
- def xrr_name
68
- xrr_subtype_name || xrr_type_name
69
- end
70
-
71
- def xrr_type_name
72
- self.class::RR_TYPE.key(xrr_type)
73
- end
74
-
75
- def xrr_subtype_name
76
- if xrr_type == Xlib::RRNotify
77
- self.class::RR_SUBTYPE.key(xrr_type_struct[:subtype])
78
- end
36
+ def extension_event
37
+ extension.event(data? ? cookie : xevent)
79
38
  end
80
39
  end
81
-
82
- class Event
83
- class << self
84
- def xrr_type_offset(display)
85
- @xrr_type_offset ||= {}
86
- @xrr_type_offset[display] ||= (
87
- rr_event_offset = FFI::MemoryPointer.new :int
88
- rr_error_offset = FFI::MemoryPointer.new :int
89
- Xlib.XRRQueryExtension(display, rr_event_offset, rr_error_offset)
90
- rr_event_offset.read_int
91
- )
92
- end
93
-
94
- def valid_name?(name)
95
- TYPE[name] || RR_SUBTYPE[name] || RR_TYPE[name]
96
- end
97
- end
98
-
99
- MASK = {
100
- no_event: Xlib::NoEventMask,
101
- key_press: Xlib::KeyPressMask,
102
- key_release: Xlib::KeyReleaseMask,
103
- button_press: Xlib::ButtonPressMask,
104
- button_release: Xlib::ButtonReleaseMask,
105
- enter_window: Xlib::EnterWindowMask,
106
- leave_window: Xlib::LeaveWindowMask,
107
- pointer_motion: Xlib::PointerMotionMask,
108
- pointer_motion_hint: Xlib::PointerMotionHintMask,
109
- button1_motion: Xlib::Button1MotionMask,
110
- button2_motion: Xlib::Button2MotionMask,
111
- button3_motion: Xlib::Button3MotionMask,
112
- button4_motion: Xlib::Button4MotionMask,
113
- button5_motion: Xlib::Button5MotionMask,
114
- button_motion: Xlib::ButtonMotionMask,
115
- keymap_state: Xlib::KeymapStateMask,
116
- exposure: Xlib::ExposureMask,
117
- visibility_change: Xlib::VisibilityChangeMask,
118
- structure_notify: Xlib::StructureNotifyMask,
119
- resize_redirect: Xlib::ResizeRedirectMask,
120
- substructure_notify: Xlib::SubstructureNotifyMask,
121
- substructure_redirect: Xlib::SubstructureRedirectMask,
122
- focus_change: Xlib::FocusChangeMask,
123
- property_change: Xlib::PropertyChangeMask,
124
- colormap_change: Xlib::ColormapChangeMask,
125
- owner_grab_button: Xlib::OwnerGrabButtonMask,
126
- screen_change_notify: Xlib::RRScreenChangeNotifyMask,
127
- crtc_change_notify: Xlib::RRCrtcChangeNotifyMask,
128
- output_change_notify: Xlib::RROutputChangeNotifyMask,
129
- output_property_notify: Xlib::RROutputPropertyNotifyMask,
130
- provider_change_notify: Xlib::RRProviderChangeNotifyMask,
131
- provider_property_notify: Xlib::RRProviderPropertyNotifyMask,
132
- resource_change_notify: Xlib::RRResourceChangeNotifyMask
133
- }
134
-
135
- RR_MASK = {
136
- screen_change_notify: Xlib::RRScreenChangeNotifyMask,
137
- crtc_change_notify: Xlib::RRCrtcChangeNotifyMask,
138
- output_change_notify: Xlib::RROutputChangeNotifyMask,
139
- output_property_notify: Xlib::RROutputPropertyNotifyMask,
140
- provider_change_notify: Xlib::RRProviderChangeNotifyMask,
141
- provider_property_notify: Xlib::RRProviderPropertyNotifyMask,
142
- resource_change_notify: Xlib::RRResourceChangeNotifyMask
143
- }
144
-
145
- TYPE = {
146
- key_press: Xlib::KeyPress,
147
- key_release: Xlib::KeyRelease,
148
- button_press: Xlib::ButtonPress,
149
- button_release: Xlib::ButtonRelease,
150
- motion_notify: Xlib::MotionNotify,
151
- enter_notify: Xlib::EnterNotify,
152
- leave_notify: Xlib::LeaveNotify,
153
- focus_in: Xlib::FocusIn,
154
- focus_out: Xlib::FocusOut,
155
- keymap_notify: Xlib::KeymapNotify,
156
- expose: Xlib::Expose,
157
- graphics_expose: Xlib::GraphicsExpose,
158
- no_expose: Xlib::NoExpose,
159
- visibility_notify: Xlib::VisibilityNotify,
160
- create_notify: Xlib::CreateNotify,
161
- destroy_notify: Xlib::DestroyNotify,
162
- unmap_notify: Xlib::UnmapNotify,
163
- map_notify: Xlib::MapNotify,
164
- map_request: Xlib::MapRequest,
165
- reparent_notify: Xlib::ReparentNotify,
166
- configure_notify: Xlib::ConfigureNotify,
167
- configure_request: Xlib::ConfigureRequest,
168
- gravity_notify: Xlib::GravityNotify,
169
- resize_request: Xlib::ResizeRequest,
170
- circulate_notify: Xlib::CirculateNotify,
171
- circulate_request: Xlib::CirculateRequest,
172
- property_notify: Xlib::PropertyNotify,
173
- selection_clear: Xlib::SelectionClear,
174
- selection_request: Xlib::SelectionRequest,
175
- selection_notify: Xlib::SelectionNotify,
176
- colormap_notify: Xlib::ColormapNotify,
177
- client_message: Xlib::ClientMessage,
178
- mapping_notify: Xlib::MappingNotify,
179
- generic_event: Xlib::GenericEvent,
180
- last_event: Xlib::LASTEvent
181
- }
182
-
183
- RR_TYPE = {
184
- screen_change_notify: Xlib::RRScreenChangeNotify,
185
- notify: Xlib::RRNotify
186
- }
187
-
188
- RR_SUBTYPE = {
189
- crtc_change_notify: Xlib::RRNotify_CrtcChange,
190
- output_change_notify: Xlib::RRNotify_OutputChange,
191
- output_property_notify: Xlib::RRNotify_OutputProperty,
192
- provider_change_notify: Xlib::RRNotify_ProviderChange,
193
- provider_property_notify: Xlib::RRNotify_ProviderProperty,
194
- resource_change_notify: Xlib::RRNotify_ResourceChange
195
- }
196
-
197
- TYPE_TO_UNION_MEMBER = {
198
- Xlib::KeyPress => :xkey,
199
- Xlib::KeyRelease => :xkey,
200
- Xlib::ButtonPress => :xbutton,
201
- Xlib::ButtonRelease => :xbutton,
202
- Xlib::MotionNotify => :xmotion,
203
- Xlib::EnterNotify => :xcrossing,
204
- Xlib::LeaveNotify => :xcrossing,
205
- Xlib::FocusIn => :xfocus,
206
- Xlib::FocusOut => :xfocus,
207
- Xlib::KeymapNotify => :xkeymap,
208
- Xlib::Expose => :xexpose,
209
- Xlib::GraphicsExpose => :xgraphicsexpose,
210
- Xlib::NoExpose => :xnoexpose,
211
- Xlib::VisibilityNotify => :xvisibility,
212
- Xlib::CreateNotify => :xcreatewindow,
213
- Xlib::DestroyNotify => :xdestroywindow,
214
- Xlib::UnmapNotify => :xunmap,
215
- Xlib::MapNotify => :xmap,
216
- Xlib::MapRequest => :xmaprequest,
217
- Xlib::ReparentNotify => :xreparent,
218
- Xlib::ConfigureNotify => :xconfigure,
219
- Xlib::ConfigureRequest => :xconfigurerequest,
220
- Xlib::GravityNotify => :xgravity,
221
- Xlib::ResizeRequest => :xresizerequest,
222
- Xlib::CirculateNotify => :xcirculate,
223
- Xlib::CirculateRequest => :xcirculaterequest,
224
- Xlib::PropertyNotify => :xproperty,
225
- Xlib::SelectionClear => :xselectionclear,
226
- Xlib::SelectionRequest => :xselectionrequest,
227
- Xlib::SelectionNotify => :xselection,
228
- Xlib::ColormapNotify => :xcolormap,
229
- Xlib::ClientMessage => :xclient,
230
- Xlib::MappingNotify => :xmapping,
231
- Xlib::GenericEvent => :xgeneric
232
- }
233
-
234
- RR_TYPE_TO_STRUCT = {
235
- Xlib::RRScreenChangeNotify => Xlib::XRRScreenChangeNotifyEvent,
236
- Xlib::RRNotify => Xlib::XRRNotifyEvent
237
- }
238
-
239
- RR_SUBTYPE_TO_STRUCT = {
240
- Xlib::RRNotify_CrtcChange => Xlib::XRRCrtcChangeNotifyEvent,
241
- Xlib::RRNotify_OutputChange => Xlib::XRROutputChangeNotifyEvent,
242
- Xlib::RRNotify_OutputProperty => Xlib::XRROutputPropertyNotifyEvent,
243
- Xlib::RRNotify_ProviderChange => Xlib::XRRProviderChangeNotifyEvent,
244
- Xlib::RRNotify_ProviderProperty => Xlib::XRRProviderPropertyNotifyEvent,
245
- Xlib::RRNotify_ResourceChange => Xlib::XRRResourceChangeNotifyEvent
246
- }
247
- end
248
40
  end