2 * UniMotion - Unified Motion detection for Apple portables.
4 * Copyright (c) 2006 Lincoln Ramsay. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation Inc. 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
22 * Written by Christian Klein
23 * Modified for iBook compatibility by Pall Thayer
24 * Modified for Hi Res Powerbook compatibility by Pall Thayer
25 * Modified for MacBook Pro compatibility by Randy Green
26 * Disparate forks unified into UniMotion by Lincoln Ramsay
29 // This license applies to the portions created by Cristian Klein.
32 * a little program to display the coords returned by
33 * the powerbook motion sensor
35 * A fine piece of c0de, brought to you by
38 * *** teenage mutant ninja hero coders ***
41 * All of the software included is copyrighted by Christian Klein <chris@5711.org>.
43 * Copyright 2005 Christian Klein. All rights reserved.
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. The name of the author must not be used to endorse or promote
54 * products derived from this software
55 * without specific prior written permission.
57 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 #include "unimotion.h"
74 #include <IOKit/IOKitLib.h>
75 #include <CoreFoundation/CoreFoundation.h>
98 struct pb_ib_data pb_ib
;
103 static int set_values(int type
, int *kernFunc
, char **servMatch
, int *dataType
)
108 *servMatch
= "IOI2CMotionSensor";
113 *servMatch
= "IOI2CMotionSensor";
118 *servMatch
= "PMUMotionSensor";
123 *servMatch
= "SMCMotionSensor";
133 static int probe_sms(int kernFunc
, char *servMatch
, int dataType
, void *data
)
135 kern_return_t result
;
136 mach_port_t masterPort
;
137 io_iterator_t iterator
;
139 io_connect_t dataPort
;
141 size_t structureInputSize
;
142 size_t structureOutputSize
;
144 union motion_data inputStructure
;
145 union motion_data
*outputStructure
;
147 outputStructure
= (union motion_data
*)data
;
149 result
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
151 CFMutableDictionaryRef matchingDictionary
= IOServiceMatching(servMatch
);
153 result
= IOServiceGetMatchingServices(masterPort
, matchingDictionary
, &iterator
);
155 if (result
!= KERN_SUCCESS
) {
156 //fputs("IOServiceGetMatchingServices returned error.\n", stderr);
160 aDevice
= IOIteratorNext(iterator
);
161 IOObjectRelease(iterator
);
164 //fputs("No motion sensor available\n", stderr);
168 result
= IOServiceOpen(aDevice
, mach_task_self(), 0, &dataPort
);
169 IOObjectRelease(aDevice
);
171 if (result
!= KERN_SUCCESS
) {
172 //fputs("Could not open motion sensor device\n", stderr);
176 switch ( dataType
) {
178 structureInputSize
= sizeof(struct pb_ib_data
);
179 structureOutputSize
= sizeof(struct pb_ib_data
);
182 structureInputSize
= sizeof(struct mbp_data
);
183 structureOutputSize
= sizeof(struct mbp_data
);
189 memset(&inputStructure
, 0, sizeof(union motion_data
));
190 memset(outputStructure
, 0, sizeof(union motion_data
));
192 result
= IOConnectCallStructMethod(dataPort
, kernFunc
, &inputStructure
,
193 structureInputSize
, outputStructure
, &structureOutputSize
);
195 IOServiceClose(dataPort
);
197 if (result
!= KERN_SUCCESS
) {
209 union motion_data data
;
212 for ( i
= 1; ; i
++ ) {
213 if ( !set_values(i
, &kernFunc
, &servMatch
, &dataType
) )
215 if ( probe_sms(kernFunc
, servMatch
, dataType
, &data
) )
222 int read_sms_raw(int type
, int *x
, int *y
, int *z
)
227 union motion_data data
;
229 if ( !set_values(type
, &kernFunc
, &servMatch
, &dataType
) )
231 if ( probe_sms(kernFunc
, servMatch
, dataType
, &data
) ) {
232 switch ( dataType
) {
234 if ( x
) *x
= data
.pb_ib
.x
;
235 if ( y
) *y
= data
.pb_ib
.y
;
236 if ( z
) *z
= data
.pb_ib
.z
;
239 if ( x
) *x
= data
.mbp
.x
;
240 if ( y
) *y
= data
.mbp
.y
;
241 if ( z
) *z
= data
.mbp
.z
;
251 int read_sms(int type
, int *x
, int *y
, int *z
)
254 int xoff
, yoff
, zoff
;
258 ret
= read_sms_raw(type
, &_x
, &_y
, &_z
);
262 static CFStringRef app
= CFSTR("com.ramsayl.UniMotion");
263 static CFStringRef xoffstr
= CFSTR("x_offset");
264 static CFStringRef yoffstr
= CFSTR("y_offset");
265 static CFStringRef zoffstr
= CFSTR("z_offset");
266 xoff
= CFPreferencesGetAppIntegerValue(xoffstr
, app
, &ok
);
267 if ( ok
) _x
+= xoff
;
268 yoff
= CFPreferencesGetAppIntegerValue(yoffstr
, app
, &ok
);
269 if ( ok
) _y
+= yoff
;
270 zoff
= CFPreferencesGetAppIntegerValue(zoffstr
, app
, &ok
);
271 if ( ok
) _z
+= zoff
;
280 int read_sms_real(int type
, double *x
, double *y
, double *z
)
283 int xscale
, yscale
, zscale
;
287 ret
= read_sms_raw(type
, &_x
, &_y
, &_z
);
291 static CFStringRef app
= CFSTR("com.ramsayl.UniMotion");
292 static CFStringRef xscalestr
= CFSTR("x_scale");
293 static CFStringRef yscalestr
= CFSTR("y_scale");
294 static CFStringRef zscalestr
= CFSTR("z_scale");
295 xscale
= CFPreferencesGetAppIntegerValue(xscalestr
, app
, &ok
);
297 yscale
= CFPreferencesGetAppIntegerValue(yscalestr
, app
, &ok
);
299 zscale
= CFPreferencesGetAppIntegerValue(zscalestr
, app
, &ok
);
302 *x
= _x
/ (double)xscale
;
303 *y
= _y
/ (double)yscale
;
304 *z
= _z
/ (double)zscale
;