Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: e5a97f9f2b
Fetching contributors…

Cannot retrieve contributors at this time

file 148 lines (119 sloc) 4.132 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
=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 Mouse
  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 jitter_forever_in_own_thread
  
      old_x, old_y = get_mouse_location
      Thread.new {
        loop {
          move_y = 8 # just enough for VLC when full screened...
          cur_x, cur_y = get_mouse_location
          if(cur_x == old_x && cur_y == old_y)
            @total_movements += 1
            # blit it up
            move_mouse_relative(0, move_y)
            move_mouse_relative(0, move_y * -1)
            # let it move it back
            sleep 0.05
            old_x, old_y = get_mouse_location
            sleep 0.75
          else
            # user has been moving the mouse around, so we don't need to, to not annoy them
            old_x, old_y = get_mouse_location
            sleep 3
          end
        }
      }
      
    end
    
    def move_mouse_relative dx, dy
      myinput = Mouse::Input.new
      myinput[:type] = Mouse::INPUT_MOUSE
      in_evt = myinput[:evt][:mi]
      in_evt[:mouse_data] = 0 # null it out
      in_evt[:flags] = Mouse::MOUSEEVENTF_MOVE
      in_evt[:time] = 0
      in_evt[:extra] = 0
      in_evt[:dx] = dx
      in_evt[:dy] = dy
      SendInput(1, myinput, Mouse::Input.size)
    end
    
    def single_click_left_mouse_button
      left_mouse_down!
      left_mouse_up!
      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!
      [loc.x, loc.y]
    end
    
    attr_accessor :total_movements
    
    private
    
    def send_left_mouse_button action_type
      myinput = Mouse::Input.new
      myinput[:type] = Mouse::INPUT_MOUSE
      in_evt = myinput[:evt][:mi]
      in_evt[:flags] = action_type
      SendInput(1, myinput, Mouse::Input.size)
    end

    
  end
    
end
Mouse.total_movements=0 # ruby is a bit freaky with these...
Something went wrong with that request. Please try again.