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
71 #include "unimotion.h"
72 #include <IOKit/IOKitLib.h>
73 #include <CoreFoundation/CoreFoundation.h>
97 struct pb_ib_data pb_ib
;
102 static int set_values(int type
, int *kernFunc
, char **servMatch
, int *dataType
)
107 *servMatch
= "IOI2CMotionSensor";
112 *servMatch
= "IOI2CMotionSensor";
117 *servMatch
= "PMUMotionSensor";
122 *servMatch
= "SMCMotionSensor";
132 static int probe_sms(int kernFunc
, char *servMatch
, int dataType
, void *data
)
134 kern_return_t result
;
135 mach_port_t masterPort
;
136 io_iterator_t iterator
;
138 io_connect_t dataPort
;
140 IOItemCount structureInputSize
;
141 IOByteCount structureOutputSize
;
143 union motion_data inputStructure
;
144 union motion_data
*outputStructure
;
146 outputStructure
= (union motion_data
*)data
;
148 result
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
150 CFMutableDictionaryRef matchingDictionary
= IOServiceMatching(servMatch
);
152 result
= IOServiceGetMatchingServices(masterPort
, matchingDictionary
, &iterator
);
154 if (result
!= KERN_SUCCESS
) {
155 //fputs("IOServiceGetMatchingServices returned error.\n", stderr);
159 aDevice
= IOIteratorNext(iterator
);
160 IOObjectRelease(iterator
);
163 //fputs("No motion sensor available\n", stderr);
167 result
= IOServiceOpen(aDevice
, mach_task_self(), 0, &dataPort
);
168 IOObjectRelease(aDevice
);
170 if (result
!= KERN_SUCCESS
) {
171 //fputs("Could not open motion sensor device\n", stderr);
175 switch ( dataType
) {
177 structureInputSize
= sizeof(struct pb_ib_data
);
178 structureOutputSize
= sizeof(struct pb_ib_data
);
181 structureInputSize
= sizeof(struct mbp_data
);
182 structureOutputSize
= sizeof(struct mbp_data
);
188 memset(&inputStructure
, 0, sizeof(union motion_data
));
189 memset(outputStructure
, 0, sizeof(union motion_data
));
191 result
= IOConnectMethodStructureIStructureO(dataPort
, kernFunc
, structureInputSize
,
192 &structureOutputSize
, &inputStructure
, outputStructure
);
194 IOServiceClose(dataPort
);
196 if (result
!= KERN_SUCCESS
) {
208 union motion_data data
;
211 for ( i
= 1; ; i
++ ) {
212 if ( !set_values(i
, &kernFunc
, &servMatch
, &dataType
) )
214 if ( probe_sms(kernFunc
, servMatch
, dataType
, &data
) )
221 int read_sms_raw(int type
, int *x
, int *y
, int *z
)
226 union motion_data data
;
228 if ( !set_values(type
, &kernFunc
, &servMatch
, &dataType
) )
230 if ( probe_sms(kernFunc
, servMatch
, dataType
, &data
) ) {
231 switch ( dataType
) {
233 if ( x
) *x
= data
.pb_ib
.x
;
234 if ( y
) *y
= data
.pb_ib
.y
;
235 if ( z
) *z
= data
.pb_ib
.z
;
238 if ( x
) *x
= data
.mbp
.x
;
239 if ( y
) *y
= data
.mbp
.y
;
240 if ( z
) *z
= data
.mbp
.z
;
250 int read_sms(int type
, int *x
, int *y
, int *z
)
253 int xoff
, yoff
, zoff
;
257 ret
= read_sms_raw(type
, &_x
, &_y
, &_z
);
261 CFStringRef app
= CFSTR("com.ramsayl.UniMotion");
262 CFStringRef xoffstr
= CFSTR("x_offset");
263 CFStringRef yoffstr
= CFSTR("y_offset");
264 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 CFStringRef app
= CFSTR("com.ramsayl.UniMotion");
292 CFStringRef xscalestr
= CFSTR("x_scale");
293 CFStringRef yscalestr
= CFSTR("y_scale");
294 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
;