Skip to content

Commit

Permalink
working mac mouse woot
Browse files Browse the repository at this point in the history
  • Loading branch information
rdp committed May 20, 2014
1 parent 1ccca66 commit 54270ea
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 82 deletions.
95 changes: 13 additions & 82 deletions lib/simple_gui_creator/mouse_control.rb
Expand Up @@ -18,44 +18,10 @@
require 'rubygems'
require 'ffi'
require 'java'
require 'os'

module MouseControl
extend FFI::Library
MouseInfo = java.awt.MouseInfo

ffi_lib 'user32'
ffi_convention :stdcall

MOUSEEVENTF_MOVE = 1
INPUT_MOUSE = 0
MOUSEEVENTF_ABSOLUTE = 0x8000
MOUSEEVENTF_LEFTDOWN = 0x0002
MOUSEEVENTF_LEFTUP = 0x0004


class MouseInput < FFI::Struct
layout :dx, :long,
:dy, :long,
:mouse_data, :ulong,
:flags, :ulong,
:time, :ulong,
:extra, :ulong
end

class InputEvent < FFI::Union
layout :mi, MouseInput
end

class Input < FFI::Struct
layout :type, :ulong,
:evt, InputEvent
end

# UINT SendInput(UINT nInputs, LPINPUT pInputs, int cbSize);
attach_function :SendInput, [ :uint, :pointer, :int ], :uint

# poller...
attach_function :GetAsyncKeyState, [:int], :uint
module MouseControl # base
MouseInfo = java.awt.MouseInfo

class << self
@keep_going = true
Expand Down Expand Up @@ -86,21 +52,8 @@ def jitter_forever_in_own_thread
sleep 3
end
end
puts 'mouse control, shutting down thread'
}

end

def move_mouse_relative dx, dy
myinput = MouseControl::Input.new
myinput[:type] = MouseControl::INPUT_MOUSE
in_evt = myinput[:evt][:mi]
in_evt[:mouse_data] = 0 # null it out
in_evt[:flags] = MouseControl::MOUSEEVENTF_MOVE
in_evt[:time] = 0
in_evt[:extra] = 0
in_evt[:dx] = dx
in_evt[:dy] = dy
SendInput(1, myinput, MouseControl::Input.size)
end

def single_click_left_mouse_button
Expand All @@ -109,25 +62,6 @@ def single_click_left_mouse_button
p "CLICKED LEFT MOUSE BUTTON"
end

def left_mouse_down!
send_left_mouse_button MOUSEEVENTF_LEFTDOWN
end

def left_mouse_up!
send_left_mouse_button MOUSEEVENTF_LEFTUP
end

VK_LBUTTON = 0x01 # mouse left button for GetAsyncKeyState (seeing if mouse down currently or not)

def left_mouse_button_state
GetAsyncKeyState(VK_LBUTTON) # ignore a first response, which also tells us if it has changed at all since last call
if GetAsyncKeyState(VK_LBUTTON) == 0 # zero means up
:up
else
:down
end
end

# [x, y]
def get_mouse_location
loc = MouseInfo.getPointerInfo.getLocation # pure java!
Expand All @@ -136,19 +70,16 @@ def get_mouse_location

attr_accessor :total_movements

private

def send_left_mouse_button action_type
myinput = MouseControl::Input.new
myinput[:type] = MouseControl::INPUT_MOUSE
in_evt = myinput[:evt][:mi]
in_evt[:flags] = action_type
SendInput(1, myinput, MouseControl::Input.size)
end


end

end

MouseControl.total_movements=0 # ruby is a bit freaky with these...
MouseControl.total_movements=0 # ruby is a bit freaky with these...

if OS.windows?
require_relative 'mouse_control_windows'
elsif OS.mac?
require_relative 'mouse_control_mac'
else
raise 'unsupported os for mouse yet'
end
104 changes: 104 additions & 0 deletions lib/simple_gui_creator/mouse_control_windows.rb
@@ -0,0 +1,104 @@
=begin
Copyright 2010, Roger Pack
This file is part of Sensible Cinema.
Sensible Cinema is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Sensible Cinema is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
=end
require 'rubygems'
require 'ffi'
require 'java'

module MouseControl # add some more stuff to it :)
extend FFI::Library
MouseInfo = java.awt.MouseInfo

ffi_lib 'user32'
ffi_convention :stdcall

MOUSEEVENTF_MOVE = 1
INPUT_MOUSE = 0
MOUSEEVENTF_ABSOLUTE = 0x8000
MOUSEEVENTF_LEFTDOWN = 0x0002
MOUSEEVENTF_LEFTUP = 0x0004


class MouseInput < FFI::Struct
layout :dx, :long,
:dy, :long,
:mouse_data, :ulong,
:flags, :ulong,
:time, :ulong,
:extra, :ulong
end

class InputEvent < FFI::Union
layout :mi, MouseInput
end

class Input < FFI::Struct
layout :type, :ulong,
:evt, InputEvent
end

# UINT SendInput(UINT nInputs, LPINPUT pInputs, int cbSize);
attach_function :SendInput, [ :uint, :pointer, :int ], :uint

# poller...
attach_function :GetAsyncKeyState, [:int], :uint
class << self
def move_mouse_relative dx, dy
myinput = MouseControl::Input.new
myinput[:type] = MouseControl::INPUT_MOUSE
in_evt = myinput[:evt][:mi]
in_evt[:mouse_data] = 0 # null it out
in_evt[:flags] = MouseControl::MOUSEEVENTF_MOVE
in_evt[:time] = 0
in_evt[:extra] = 0
in_evt[:dx] = dx
in_evt[:dy] = dy
SendInput(1, myinput, MouseControl::Input.size)
end

def left_mouse_down!
send_left_mouse_button MOUSEEVENTF_LEFTDOWN
end

def left_mouse_up!
send_left_mouse_button MOUSEEVENTF_LEFTUP
end

VK_LBUTTON = 0x01 # mouse left button for GetAsyncKeyState (seeing if mouse down currently or not)

def left_mouse_button_state
GetAsyncKeyState(VK_LBUTTON) # ignore a first response, which also tells us if it has changed at all since last call
if GetAsyncKeyState(VK_LBUTTON) == 0 # zero means up
:up
else
:down
end
end

private

def send_left_mouse_button action_type
myinput = MouseControl::Input.new
myinput[:type] = MouseControl::INPUT_MOUSE
in_evt = myinput[:evt][:mi]
in_evt[:flags] = action_type
SendInput(1, myinput, MouseControl::Input.size)
end

end

end

0 comments on commit 54270ea

Please sign in to comment.