宮川さんがすでにPlaggerを使ってやっていますが、ちょっと前に話題になった MacBook などの衝撃を感知してなにかをする SmackBook のようなことが ThinkPad でもできるということで、自分もためしてみました。

やったのは ThinkPad を傾けると Firefox のウィンドウをがそちらに動くというもの。(Firefoxのウィンドウ限定です…)

http://www.youtube.com/watch?v=sbh_JGbPoJU


そして、これを動作させているのは Perl で、、はなくて Ruby です。なんとなくRubyで書いてみました。
Rubyのレベルがしょぼいのは気にしないでください…。

作成にあたり、こちらにあるプログラムを参考にさせて頂きました。
プログラムは3つのファイルに分れてて、1つは前述のページのプログラムに添付されているdevice.rb。あとは以下の2つです。

本体(これを実行する)
require 'device'
require 'Win32API'
require 'firefox'

command = 0x733fc
result_size = 0x24

device = Device.new '\\\\.\\ShockMgr'

firefox = FirefoxWindow.new

begin
	device.open
	values = device.io(command, result_size).unpack("x4s*")
	cx = values[3]
	cy = values[2]

	loop do
		values = device.io(command, result_size).unpack("x4s*")
		ax = (values[1] - cx) / 30
		ay = (values[0] - cy) / 30
		firefox.move(ax, ay)
	end
ensure
	device.close
end
firefox.rb(FirefoxWindowクラス)
require 'Win32API'

class FirefoxWindow
	def initialize
		@win_handle = self.get_win_handle
		@left, @top, @right, @bottom = self.get_pos
		@width, @height = self.get_screen
	end

	def get_screen
		sm = Win32API.new('user32', 'GetSystemMetrics', 'i', 'i')
		cx_screen = 0
		cy_screen = 1
		return sm.call(cx_screen), sm.call(cy_screen)
	end
	
	def get_win_handle
		fw = Win32API.new('user32', 'FindWindow', 'pp', 'i')
		return fw.call('MozillaUIWindowClass', 0)
	end
	
	def get_pos
		gwr = Win32API.new('user32', 'GetWindowRect', 'pp', 'l')
		rect = " " * 16
		pos = gwr.call(@win_handle, rect)
		return rect.unpack('LLLL')
	end
	
	def set_pos(x, y, w, h)
		moveWindow = Win32API.new('user32', 'MoveWindow', 'piiiii', 'i')
		moveWindow.Call(@win_handle, x, y, w, h, 1);
	end
	
	def move(x, y)
		left   = @left   + x
		top    = @top    + y
		right  = @right  + x
		bottom = @bottom + y
		if left >= 0 && top >= 0 && right <= @width && bottom < @height
			@left   = left
			@top    = top
			@right  = right
			@bottom = bottom
			self.set_pos(left, top, right - left, bottom - top)
		end
	end
end