fingerpoken 0.2.20101208032306

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+