fingerpoken 0.2.20101208032306

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,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "em-websocket"
5
+ require "json"
6
+ require "rack"
7
+ require "sinatra/async"
8
+
9
+ class FingerPoken < Sinatra::Base
10
+ register Sinatra::Async
11
+ set :haml, :format => :html5
12
+ set :logging, true
13
+ set :public, "#{File.dirname(__FILE__)}/../public"
14
+ set :views, "#{File.dirname(__FILE__)}/../views"
15
+
16
+ aget '/' do
17
+ headers "Content-Type" => "text/html"
18
+ body haml :index
19
+ end # GET /
20
+
21
+ aget '/style.css' do
22
+ headers "Content-Type" => "text/css; charset=utf8"
23
+ body sass :style
24
+ end # GET /style.css
25
+ end
26
+
27
+ EventMachine::run do
28
+ $:.unshift(File.dirname(__FILE__) + "/lib")
29
+ channel = EventMachine::Channel.new
30
+
31
+ # TODO(sissel): Pick up here and make command flags to choose the
32
+ # target (vnc, xdo, etc)
33
+ require "fingerpoken/xdo"
34
+ target = FingerPoken::Target::Xdo.new :channel => channel
35
+
36
+ #require "fingerpoken/vnc"
37
+ #target = FingerPoken::Target::VNC.new :channel => channel
38
+
39
+ EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 5001) do |ws|
40
+ ws.onmessage do |message|
41
+ request = JSON.parse(message)
42
+ p request
43
+ channel.push(request)
44
+ end # ws.onmessage
45
+ end # WebSocket
46
+
47
+ Rack::Handler::Thin.run(
48
+ Rack::CommonLogger.new( \
49
+ Rack::ShowExceptions.new( \
50
+ FingerPoken.new)), :Port => 5000)
51
+ end # EventMachine::run
@@ -0,0 +1,59 @@
1
+ require "logger"
2
+
3
+ class FingerPoken::Target
4
+ def initialize(config)
5
+ @channel = config[:channel]
6
+ @logger = Logger.new(STDERR)
7
+ end
8
+
9
+ def register
10
+ @channel.subscribe do |request|
11
+ case request["action"]
12
+ when "mousemove_relative"
13
+ mousemove_relative(request["rel_x"], request["rel_y"])
14
+ when "click"
15
+ click(request["button"])
16
+ when "mousedown"
17
+ mousedown(request["button"])
18
+ when "mouseup"
19
+ mouseup(request["button"])
20
+ when "type"
21
+ type(request["string"])
22
+ end
23
+ end
24
+ end
25
+
26
+ # Subclasses should implement this.
27
+ def mousemove_relative(x, y)
28
+ @logger.info("mousemove not supported")
29
+ end
30
+
31
+ def mousedown(button)
32
+ @logger.info("mousedown not supported")
33
+ end
34
+
35
+ def mouseup(button)
36
+ @logger.info("mouseup not supported")
37
+ end
38
+
39
+ def click(button)
40
+ mousedown(button)
41
+ mouseup(button)
42
+ end
43
+
44
+ def type(string)
45
+ @logger.info("typing not supported")
46
+ end
47
+
48
+ def keypress(key)
49
+ @logger.info("keypress not supported")
50
+ end
51
+
52
+ def keydown(key)
53
+ @logger.info("keydown not supported")
54
+ end
55
+
56
+ def keyup(key)
57
+ @logger.info("keyup not supported")
58
+ end
59
+ end # class FingerPoken::Target
@@ -0,0 +1,69 @@
1
+ require "rubygems"
2
+ require "eventmachine-vnc"
3
+ require "fingerpoken/target"
4
+
5
+ class FingerPoken::Target::VNC < FingerPoken::Target
6
+ attr_accessor :x
7
+ attr_accessor :y
8
+ attr_accessor :buttonmask
9
+
10
+ def initialize(config)
11
+ super(config)
12
+ # TODO(sissel): Make this configurable
13
+ @password = ENV["VNCPASS"]
14
+ @host = "sadness"
15
+ @port = 5900
16
+
17
+ @vnc = EventMachine::connect(@host, @port, VNCClient, self)
18
+ @x = 0
19
+ @y = 0
20
+ @buttonmask = 0
21
+ end
22
+
23
+ def update
24
+ p [@x, @y, @buttonmask]
25
+ @vnc.pointerevent(@x, @y, @buttonmask)
26
+
27
+ # TODO(sissel): Hack to make it work in TF2.
28
+ # Mouse movement is always "from center"
29
+ # So after each move, center the cursor.
30
+ #@x = (@vnc.screen_width / 2).to_i
31
+ #@y = (@vnc.screen_height / 2).to_i
32
+ end
33
+
34
+
35
+ def mousemove_relative(x, y)
36
+ @x += x
37
+ @y += y
38
+ update
39
+ end
40
+
41
+ def mousedown(button)
42
+ button = (1 << (button - 1))
43
+ return if @buttonmask & button != 0
44
+ @buttonmask |= button
45
+ update
46
+ end
47
+
48
+ def mouseup(button)
49
+ button = (1 << (button - 1))
50
+ return if @buttonmask & button == 0
51
+ @buttonmask &= (~button)
52
+ update
53
+ end
54
+
55
+ class VNCClient < EventMachine::Connection
56
+ include EventMachine::Protocols::VNC::Client
57
+
58
+ def initialize(target)
59
+ @target = target
60
+ end
61
+
62
+ def ready
63
+ @target.register
64
+ @target.x = (@screen_width / 2).to_i
65
+ @target.y = (@screen_height / 2).to_i
66
+ @target.buttonmask = 0
67
+ end
68
+ end # class VNCClient
69
+ end
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "ffi"
5
+ require "fingerpoken/target"
6
+
7
+ class FingerPoken::Target::Xdo < FingerPoken::Target
8
+ module LibXdo
9
+ extend FFI::Library
10
+ ffi_lib "libxdo.so"
11
+
12
+ attach_function :xdo_new, [:string], :pointer
13
+ attach_function :xdo_mousemove, [:pointer, :int, :int, :int], :int
14
+ attach_function :xdo_mousemove_relative, [:pointer, :int, :int], :int
15
+ attach_function :xdo_click, [:pointer, :long, :int], :int
16
+ attach_function :xdo_mousedown, [:pointer, :long, :int], :int
17
+ attach_function :xdo_mouseup, [:pointer, :long, :int], :int
18
+ attach_function :xdo_type, [:pointer, :long, :string, :long], :int
19
+ attach_function :xdo_keysequence, [:pointer, :long, :string, :long], :int
20
+ end
21
+
22
+ def initialize(config)
23
+ super(config)
24
+ @xdo = LibXdo::xdo_new(nil)
25
+ if @xdo.null?
26
+ raise "xdo_new failed"
27
+ end
28
+ register
29
+ end
30
+
31
+ def mousemove_relative(x, y)
32
+ @logger.info("move #{x},#{y}")
33
+ return LibXdo::xdo_mousemove_relative(@xdo, x, y)
34
+ end
35
+
36
+ def click(button)
37
+ LibXdo::xdo_click(@xdo, 0, button)
38
+ end
39
+
40
+ def mousedown(button)
41
+ LibXdo::xdo_mousedown(@xdo, 0, button)
42
+ end
43
+
44
+ def mouseup(button)
45
+ LibXdo::xdo_mouseup(@xdo, 0, button)
46
+ end
47
+
48
+ def type(string)
49
+ LibXdo::xdo_type(@xdo, 0, string, 12000)
50
+ end
51
+
52
+ def keypress(key)
53
+ key = request["key"]
54
+ if key.is_a?(String)
55
+ if key.length == 1
56
+ # Assume letter
57
+ LibXdo::xdo_type(@xdo, 0, key, 12000)
58
+ else
59
+ # Assume keysym
60
+ LibXdo::xdo_keysequence(@xdo, 0, key, 12000)
61
+ end
62
+ else
63
+ # type printables, key others.
64
+ if 32.upto(127).include?(key)
65
+ LibXdo::xdo_type(@xdo, 0, request["key"].chr, 12000)
66
+ else
67
+ case key
68
+ when 8
69
+ LibXdo::xdo_keysequence(@xdo, 0, "BackSpace", 12000)
70
+ when 13
71
+ LibXdo::xdo_keysequence(@xdo, 0, "Return", 12000)
72
+ else
73
+ puts "I don't know how to type web keycode '#{key}'"
74
+ end # case key
75
+ end # if 32.upto(127).include?(key)
76
+ end # if key.is_a?String
77
+ end # def keypress
78
+ end # class FingerPoken::Target::Xdo
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fingerpoken
3
+ version: !ruby/object:Gem::Version
4
+ hash: 40202416064627
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 20101208032306
10
+ version: 0.2.20101208032306
11
+ platform: ruby
12
+ authors:
13
+ - Jordan Sissel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-08 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: eventmachine-vnc
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: ffi
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: eventmachine
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ description: fingerpoken - turns your ipad/itouch/iphone into a remote touchpad, keyboard, etc
64
+ email: jls@semicomplete.com
65
+ executables:
66
+ - fingerpoken.rb
67
+ extensions: []
68
+
69
+ extra_rdoc_files: []
70
+
71
+ files:
72
+ - lib/fingerpoken/xdo.rb
73
+ - lib/fingerpoken/target.rb
74
+ - lib/fingerpoken/vnc.rb
75
+ - bin/fingerpoken.rb
76
+ has_rdoc: true
77
+ homepage: https://github.com/jordansissel/eventmachine-vnc
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options: []
82
+
83
+ require_paths:
84
+ - lib
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.3.7
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: fingerpoken - turns your ipad/itouch/iphone into a remote touchpad, keyboard, etc
111
+ test_files: []
112
+