topherfangio-lcdproc-ruby 0.1.1

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.
Files changed (50) hide show
  1. data/.document +5 -0
  2. data/.gitignore +6 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +9 -0
  5. data/Rakefile +70 -0
  6. data/TODO +18 -0
  7. data/VERSION +1 -0
  8. data/devices/crystalfontz/packet.rb +108 -0
  9. data/devices/devices.rb +41 -0
  10. data/examples/basic.rb +39 -0
  11. data/examples/clock.rb +78 -0
  12. data/examples/lights.rb +67 -0
  13. data/lcdproc.rb +43 -0
  14. data/lib/console.rb +39 -0
  15. data/lib/core_extensions/array.rb +37 -0
  16. data/lib/core_extensions/string.rb +37 -0
  17. data/lib/includes/lcdproc.rb +27 -0
  18. data/lib/lcdproc-ruby.rb +0 -0
  19. data/lib/lcdproc/client.rb +458 -0
  20. data/lib/lcdproc/command.rb +54 -0
  21. data/lib/lcdproc/errors.rb +41 -0
  22. data/lib/lcdproc/key_event.rb +59 -0
  23. data/lib/lcdproc/menu.rb +188 -0
  24. data/lib/lcdproc/menu_event.rb +49 -0
  25. data/lib/lcdproc/menu_item.rb +108 -0
  26. data/lib/lcdproc/menu_items/action.rb +72 -0
  27. data/lib/lcdproc/menu_items/alpha.rb +85 -0
  28. data/lib/lcdproc/menu_items/checkbox.rb +76 -0
  29. data/lib/lcdproc/menu_items/ip.rb +75 -0
  30. data/lib/lcdproc/menu_items/numeric.rb +75 -0
  31. data/lib/lcdproc/menu_items/ring.rb +75 -0
  32. data/lib/lcdproc/menu_items/slider.rb +83 -0
  33. data/lib/lcdproc/menu_items/submenu.rb +77 -0
  34. data/lib/lcdproc/response.rb +65 -0
  35. data/lib/lcdproc/screen.rb +283 -0
  36. data/lib/lcdproc/widget.rb +142 -0
  37. data/lib/lcdproc/widgets/graph.rb +185 -0
  38. data/lib/lcdproc/widgets/hbar.rb +101 -0
  39. data/lib/lcdproc/widgets/icon.rb +94 -0
  40. data/lib/lcdproc/widgets/num.rb +92 -0
  41. data/lib/lcdproc/widgets/scroller.rb +110 -0
  42. data/lib/lcdproc/widgets/string.rb +94 -0
  43. data/lib/lcdproc/widgets/title.rb +90 -0
  44. data/lib/lcdproc/widgets/vbar.rb +111 -0
  45. data/script/console.rb +28 -0
  46. data/script/telnet.rb +90 -0
  47. data/tasks/test/basic.rake +82 -0
  48. data/tasks/test/keys.rake +66 -0
  49. data/tasks/test/menus.rake +74 -0
  50. metadata +104 -0
data/lcdproc.rb ADDED
@@ -0,0 +1,43 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ require "socket"
28
+ require "find"
29
+
30
+ fileList = []
31
+ directories = [ "lib/lcdproc", "lib/core_extensions", "devices" ]
32
+
33
+ directories.each do |directory|
34
+ Find.find( directory ) do |file|
35
+ if File.basename( file ) =~ /.rb$/
36
+ fileList << file
37
+ end
38
+ end
39
+
40
+ fileList.sort { |a,b| a.scan(/\//).size <=> b.scan(/\//).size }.each do |file|
41
+ require file
42
+ end
43
+ end
data/lib/console.rb ADDED
@@ -0,0 +1,39 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ require 'optparse'
28
+
29
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
30
+
31
+ options = { :irb => irb }
32
+
33
+ libs = " -r irb/completion"
34
+ libs << " -r lcdproc"
35
+ libs << " -r lib/includes/lcdproc"
36
+
37
+ puts "Loading LCDProc Console Environment"
38
+
39
+ exec "#{options[:irb]} #{libs} --simple-prompt"
@@ -0,0 +1,37 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ class Array
28
+
29
+ def sum
30
+ inject( nil ) { |sum,x| sum ? sum + x : x }
31
+ end
32
+
33
+ def mean
34
+ sum.to_f / size
35
+ end
36
+
37
+ end
@@ -0,0 +1,37 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ class String
28
+
29
+ def quotify
30
+ "\"#{self}\""
31
+ end
32
+
33
+ def quotify!
34
+ self.replace self.quotify
35
+ end
36
+
37
+ end
@@ -0,0 +1,27 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ include LCDProc
File without changes
@@ -0,0 +1,458 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2008 Topher Fangio
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation
6
+ # files (the "Software"), to deal in the Software without
7
+ # restriction, including without limitation the rights to use,
8
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following
11
+ # conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ # OTHER DEALINGS IN THE SOFTWARE.
24
+ #-------------------------------------------------------------------------------
25
+
26
+
27
+ module LCDProc
28
+
29
+ class Client
30
+ # The maximum number of messages allowed to stay in memory. This works much like a circular array with the
31
+ # oldest messages being overwritten.
32
+ MAX_MESSAGES = 512
33
+
34
+ # The number of milliseconds to wait before processing new responses.
35
+ RESPONSE_PROCESS_TIME = 25
36
+
37
+ # Whether or not debugging output should be displayed.
38
+ DEBUG = false
39
+
40
+ # The number of LCDProc-Ruby clients currently connected to the server.
41
+ @@client_count = 0
42
+
43
+ attr_reader :key_events, :commands, :name, :menu_events, :messages, :response_queue, :screens, :width, :height, :cell_width, :cell_height
44
+ attr_accessor :menu
45
+
46
+ # Create a new client.
47
+ #
48
+ # If <tt>:host</tt> is left blank, it will attempt to connect to "_localhost_" on port <i>13666</i>. You may also
49
+ # specify another port through <tt>:port</tt>.
50
+ #
51
+ # * <tt>:host</tt> - The host to which the client should attempt to connect. Defaults to "localhost".
52
+ # * <tt>:port</tt> - The port on which the client should attempt to connect. Defaults to 13666.
53
+ # * <tt>:name</tt> - The name that should be associated with this client. Defaults to "Client_" + a sequence number.
54
+ #
55
+ # Example:
56
+ #
57
+ # my_client = Client.new
58
+ #
59
+ # or
60
+ #
61
+ # my_client = Client.new( :host => "my.remote-host.com", :port => 13667, :name => 'MyGamingRig' )
62
+ def initialize( user_options = {} )
63
+ if self.respond_to?( :before_initialize ) then self.send( :before_initialize, user_options ) end
64
+
65
+ @messages = []
66
+ @commands = []
67
+ @response_queue = []
68
+ @screens = []
69
+ @menu_events = []
70
+ @global_key_events = []
71
+ @current_screen = nil
72
+
73
+ options = {}
74
+
75
+ options[:host] = "localhost"
76
+ options[:port] = 13666
77
+ options[:name] = "Client_#{@@client_count}"
78
+
79
+ # Update our defaults with anything that they passed in
80
+ options.update( user_options )
81
+
82
+ @daemon_socket = connect( options[:host], options[:port] )
83
+
84
+ if @daemon_socket.nil?
85
+ raise messages[0]
86
+ end
87
+
88
+ @thread = Thread.new do
89
+ while true do
90
+ sleep( RESPONSE_PROCESS_TIME.to_f / 1000.0 )
91
+ process_responses
92
+ end
93
+ end
94
+
95
+ response = send_command( Command.new( "hello" ) )
96
+ response = response.message.split(' ')
97
+
98
+ @version = response[2]
99
+ @protocol = response[4]
100
+ @width = response[7]
101
+ @height = response[9]
102
+ @cell_width = response[11]
103
+ @cell_height = response[13]
104
+
105
+ @menu = Menu.new( self )
106
+
107
+ response = send_command( Command.new( "info" ) )
108
+ driver_info = response.message
109
+
110
+ LCDProc::Devices.find_all_that_drive( driver_info ).each do |device|
111
+ LCDProc::Client.send( :include, device )
112
+ end
113
+
114
+ @name = options[:name]
115
+
116
+ response = send_command( Command.new( "client_set -name #{@name}" ) )
117
+
118
+ @@client_count += 1
119
+
120
+ if self.respond_to?( :after_initialize ) then self.send( :after_initialize, options ) end
121
+ end
122
+
123
+
124
+ # Adds a message to the client's message list. Used seperately from the responses returned by
125
+ # the LCDd server. If there are more than MAX_MESSAGES, the oldest message will be removed from
126
+ # the stack.
127
+ #
128
+ # * msg - The message to be added.
129
+ #
130
+ # Example:
131
+ #
132
+ # client.add_message( "Woah Man!!! Something is wrong!!!" )
133
+ def add_message( msg )
134
+ @messages.unshift( msg )
135
+
136
+ if @messages.length > MAX_MESSAGES
137
+ @messages.pop
138
+ end
139
+ end
140
+
141
+
142
+ # Attaches a screen to this client.
143
+ #
144
+ # * screen - Any screen which contains any number of widgets.
145
+ #
146
+ # Example:
147
+ #
148
+ # s = Screen.new( 'MyTestScreen' )
149
+ # client.attach( s )
150
+ #
151
+ # or
152
+ #
153
+ # client.attach( Screen.new( 'MyTestScreen' ) )
154
+ def attach( screen )
155
+
156
+ if @screens.select{ |s| s.id == screen.id }.empty?
157
+ if screen.attach_to( self )
158
+ @screens << screen
159
+ screen.update
160
+ return true
161
+ else
162
+ return false
163
+ end
164
+ else
165
+ return false
166
+ end
167
+
168
+ end
169
+
170
+
171
+ # Detaches a screen from the client but leaves it in memory so that it may later be attached to another
172
+ # client or re-attached to this client.
173
+ #
174
+ # * <tt>screen</tt> - Any screen currently attached to this client.
175
+ #
176
+ # Example:
177
+ #
178
+ # client.detach( 'TestScreen' )
179
+ def detach( screen )
180
+ if @screens.include? screen
181
+
182
+ if screen.detach
183
+ @screens.delete( screen )
184
+ return true
185
+ else
186
+ return false
187
+ end
188
+
189
+ else
190
+ add_message "Error: Screen '#{screen.id}' is not attached to client '#{self.name}'"
191
+ return false
192
+ end
193
+ end
194
+
195
+
196
+ # Returns the last received message from the @messages array (internally more like a circular array).
197
+ #
198
+ # Example:
199
+ #
200
+ # puts client.message
201
+ def message
202
+ @messages.first
203
+ end
204
+
205
+
206
+ # Sets the name of the client
207
+ #
208
+ # * <tt>name</tt> - The new name of the client
209
+ #
210
+ # Example:
211
+ #
212
+ # client.name = 'MyGreatClient'
213
+ def name= name
214
+ response = send_command( Command.new( "client_set -name #{name}" ) )
215
+
216
+ if response.successful?
217
+ @name = name
218
+
219
+ return @name
220
+ else
221
+ error = "Error: Failed to set client's name to '#{name}'\n\n#{response.message}".gsub( /\n/, "\n " )
222
+ add_message error
223
+
224
+ raise InvalidCommand, error
225
+ end
226
+ end
227
+
228
+
229
+ # Register a new button event for the client to process and reserves the key.
230
+ def register_key_event( key_event )
231
+
232
+ if key_event and valid_keys.include? key_event.key
233
+ response = send_command( Command.new( "client_add_key -exclusively #{key_event.key}" ) )
234
+
235
+ if response.successful?
236
+ @global_key_events << key_event
237
+ return key_event
238
+ end
239
+ end
240
+
241
+ return nil
242
+ end
243
+
244
+
245
+ # Register a new menu event for the client to process
246
+ def register_menu_event( menu_event )
247
+
248
+ if menu_event
249
+ @menu_events << menu_event
250
+ return menu_event
251
+ else
252
+ return nil
253
+ end
254
+
255
+ end
256
+
257
+
258
+ # Sends a command to the server and returns a Response object. This is generally used for internal
259
+ # purposes, but has been opened to the public API in case LCDProc changes it's behaviour or adds new
260
+ # features. You should *NOT* use this to bypass the default behaviour such as setting a client's name.
261
+ #
262
+ # * <tt>command</tt> - The Command object that you wish to send to the server.
263
+ #
264
+ # Example:
265
+ #
266
+ # client.send_command( Command.new( 'info' ) )
267
+ def send_command( command )
268
+
269
+ puts "Command: " + command.message unless not DEBUG
270
+ if command.message.kind_of? String
271
+
272
+ @daemon_socket.write( command.message )
273
+ @commands << command
274
+
275
+ # NOTE: This extra get_response is here because LCDd will get confused if sent two messages very
276
+ # quickly when trying to add menu items to a menu. Hopefully it will be removed when they have their
277
+ # commands queued properly.
278
+ if command.message =~ /^menu_add_item/
279
+ r1 = get_response
280
+
281
+ if r1.message =~ /^success/
282
+ get_response
283
+ end
284
+
285
+ return r1
286
+ else
287
+ return get_response
288
+ end
289
+
290
+ elsif command.message.kind_of? Array
291
+
292
+ @daemon_socket.write( command.message.join("\n") )
293
+ @commands << command
294
+ return get_response( command.message.length )
295
+
296
+ end
297
+ end
298
+
299
+
300
+ # Unregisters a button event from the client
301
+ def unregister_key_event( key_event )
302
+ if @global_key_events.include? key_event
303
+ @global_key_events.delete key_event
304
+ return key_event
305
+ else
306
+ return nil
307
+ end
308
+ end
309
+
310
+
311
+ # Register a new menu event for the client to process
312
+ def unregister_menu_event( menu_event )
313
+
314
+ if @menu_events.include? menu_event
315
+ @menu_events.delete( menu_event )
316
+ return menu_event
317
+ else
318
+ return nil
319
+ end
320
+ end
321
+
322
+
323
+ # Returns the keys that may be registered for the client
324
+ def valid_keys
325
+ if VALID_KEYS
326
+ VALID_KEYS
327
+ else
328
+ []
329
+ end
330
+ end
331
+
332
+
333
+ private
334
+ # Connects this client to a remote (or local) LCDd server.
335
+ #
336
+ # * <tt>:host</tt> - The remote host to which you wish to connect. Defaults to <i>"localhost"</i>.
337
+ # * <tt>:port</tt> - The port on which the TCP socket should be opened. Defaults to <i>13666</i>.
338
+ def connect( host, port )
339
+ daemon_socket = nil
340
+
341
+ begin
342
+ daemon_socket = TCPSocket.new( host, port )
343
+ rescue Errno::ECONNREFUSED
344
+ add_message "Connection to '#{host}':#{port} was refused"
345
+ end
346
+
347
+ return daemon_socket
348
+ end
349
+
350
+
351
+ # Blocks until a message is entered into the response queue, creates a new Response object
352
+ # and returns it to the requester.
353
+ def get_response( number_of_responses = 1 )
354
+
355
+ responses = []
356
+
357
+ 1.upto( number_of_responses ) do |i|
358
+ response = @response_queue.pop
359
+
360
+ while response.nil?
361
+ Thread.pass
362
+
363
+ response = @response_queue.pop
364
+ end
365
+
366
+ puts "Q: #{@response_queue}, #{response}" unless not DEBUG
367
+
368
+ responses << response
369
+ end
370
+
371
+ if responses.length == 1
372
+ puts "returning one response" unless not DEBUG
373
+
374
+ return Response.new( responses[0] )
375
+ else
376
+ puts "returning multiple response: #{responses.length}" unless not DEBUG
377
+
378
+ return Response.new( responses )
379
+ end
380
+ end
381
+
382
+
383
+ # Controls processing the responses received from the LCDd server. This includes
384
+ # <tt>listen</tt> and <tt>ignore</tt> messages as well as button presses and responses to
385
+ # commands. Takes no arguments.
386
+ #
387
+ # This should be called via a thread in the client at least twice every second (currently
388
+ # set to fifty (50) times a second).
389
+ def process_responses
390
+ data = @daemon_socket.recv( 1024 )
391
+
392
+ puts "Data: " + data unless not DEBUG
393
+ array = data.split( "\n" )
394
+
395
+ puts "Array: #{array.inspect}" unless not DEBUG
396
+
397
+ array.each do |response|
398
+ puts "response: #{response} about to be processed" unless not DEBUG
399
+
400
+ # Process the listen event
401
+ if response =~ /^listen .*$/
402
+
403
+ @current_screen = @screens.find{ |s| s.id == response.split(' ').last }
404
+ puts " ! processing listen..." unless not DEBUG
405
+
406
+
407
+
408
+ # Process the ignore event
409
+ elsif response =~ /^ignore .*$/
410
+
411
+ puts " ! processing ignore..." unless not DEBUG
412
+
413
+
414
+
415
+ # Process menu events
416
+ elsif response =~ /^menuevent .*$/
417
+
418
+ puts " ! processing a menu event: #{response}" unless not DEBUG
419
+
420
+ @menu_events.each do |me|
421
+ if response =~ /^menuevent #{me.menu_item.lcdproc_event_type} #{me.menu_item.id}/
422
+ if me.block
423
+ me.block.call( response )
424
+ end
425
+ end
426
+ end
427
+
428
+
429
+
430
+ # Process key events
431
+ elsif response =~ /^key .*$/
432
+ key = response.split(' ').last
433
+
434
+ puts "Processing key #{key} in Client" unless not DEBUG
435
+
436
+ @global_key_events.each do |gbe|
437
+ if ( key == gbe.key ) and ( gbe.block )
438
+ gbe.block.call
439
+ end
440
+ end
441
+
442
+ @current_screen.process_key( key )
443
+
444
+
445
+
446
+ # Otherwise stick it in the queue
447
+ else
448
+ # If we don't know how to process it, assume that it is a response to a command
449
+ @response_queue << response
450
+ puts "response: #{response} added to queue" unless not DEBUG
451
+ end
452
+ end
453
+
454
+ end
455
+
456
+ end
457
+
458
+ end