#!/usr/bin/env ruby # # sms.rb # # Copyright (c) 2007 Naoki Hiroshima # You can redistribute it and/or modify it under the same terms as GPL2. # # Author:: Naoki Hiroshima # # Also see UniMotion # http://members.optusnet.com.au/lbramsay/programs/unimotion.html # require 'ioservice.rb' class SuddenMotionSensor < IOService Sensors = { :mbp => {:cmd=>5, :size=>40, :parser=>:mbp, :service=>"SMCMotionSensor"}, :pb => {:cmd=>21, :size=>60, :parser=>:pb, :service=>"IOI2CMotionSensor"}, :hires => {:cmd=>21, :size=>60, :parser=>:pb, :service=>"PMUMotionSensor"}, } def initialize super @key = detect end def open(service=nil, &block) super service || Sensors[@key][:service] end def get v = Sensors[@key] i = alloc_structure v[:size] o = alloc_structure v[:size] sizeO = OSX::ObjcPtr.allocate_as_int32 sizeO.assign v[:size] if 0 == structure_io(v[:cmd], v[:size], sizeO, i, o) bytes = o.bytestr return send(v[:parser], bytes) end [nil, nil, nil] end private def detect Sensors.each do |k,v| open(v[:service]) do i = alloc_structure v[:size] o = alloc_structure v[:size] sizeO = OSX::ObjcPtr.allocate_as_int32 sizeO.assign v[:size] if 0 == structure_io(v[:cmd], v[:size], sizeO, i, o) return k end end end raise Exception.new("It's time to get MacBook Pro!") end def mbp(bytes) x = bytes[1] * 256 + bytes[0] y = bytes[3] * 256 + bytes[2] z = bytes[5] * 256 + bytes[4] x -= 65536 if x > 32767 y -= 65536 if y > 32767 z -= 65536 if z > 32767 return [x, y, z] end def pb(bytes) x = bytes[0] y = bytes[1] z = bytes[2] return [x, y, z] end end if $0 == __FILE__ trap(:INT) {raise Exception('SIGINT')} SuddenMotionSensor.new.open do |sms| begin while true v = sms.get print "X:%4d Y:%4d Z:%4d" % [v[0], v[1], v[2]] STDOUT.flush print "\033[80D" sleep 1 end rescue Exception end end end