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
72 #include "TargetConditionals.h"
74 #define HAVE_MACOS_UNIMOTION
78 #ifdef HAVE_MACOS_UNIMOTION
80 #include "unimotion.h"
81 #include <IOKit/IOKitLib.h>
82 #include <CoreFoundation/CoreFoundation.h>
105 struct pb_ib_data pb_ib
;
110 static int set_values(int type
, int *kernFunc
, const char **servMatch
, int *dataType
)
115 *servMatch
= "IOI2CMotionSensor";
120 *servMatch
= "IOI2CMotionSensor";
125 *servMatch
= "PMUMotionSensor";
130 *servMatch
= "SMCMotionSensor";
140 static int probe_sms(int kernFunc
, const char *servMatch
, int dataType
, void *data
)
142 kern_return_t result
;
143 mach_port_t masterPort
;
144 io_iterator_t iterator
;
146 io_connect_t dataPort
;
148 size_t structureInputSize
;
149 size_t structureOutputSize
;
151 union motion_data inputStructure
;
152 union motion_data
*outputStructure
;
154 outputStructure
= (union motion_data
*)data
;
156 result
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
158 CFMutableDictionaryRef matchingDictionary
= IOServiceMatching(servMatch
);
160 result
= IOServiceGetMatchingServices(masterPort
, matchingDictionary
, &iterator
);
162 if (result
!= KERN_SUCCESS
) {
163 //fputs("IOServiceGetMatchingServices returned error.\n", stderr);
167 aDevice
= IOIteratorNext(iterator
);
168 IOObjectRelease(iterator
);
171 //fputs("No motion sensor available\n", stderr);
175 result
= IOServiceOpen(aDevice
, mach_task_self(), 0, &dataPort
);
176 IOObjectRelease(aDevice
);
178 if (result
!= KERN_SUCCESS
) {
179 //fputs("Could not open motion sensor device\n", stderr);
183 switch ( dataType
) {
185 structureInputSize
= sizeof(struct pb_ib_data
);
186 structureOutputSize
= sizeof(struct pb_ib_data
);
189 structureInputSize
= sizeof(struct mbp_data
);
190 structureOutputSize
= sizeof(struct mbp_data
);
196 memset(&inputStructure
, 0, sizeof(union motion_data
));
197 memset(outputStructure
, 0, sizeof(union motion_data
));
199 result
= IOConnectCallStructMethod(dataPort
, kernFunc
, &inputStructure
,
200 structureInputSize
, outputStructure
, &structureOutputSize
);
202 IOServiceClose(dataPort
);
204 if (result
!= KERN_SUCCESS
) {
214 const char *servMatch
;
216 union motion_data data
;
219 for ( i
= 1; ; i
++ ) {
220 if ( !set_values(i
, &kernFunc
, &servMatch
, &dataType
) )
222 if ( probe_sms(kernFunc
, servMatch
, dataType
, &data
) )
229 int read_sms_raw(int type
, int *x
, int *y
, int *z
)
232 const char *servMatch
;
234 union motion_data data
;
236 if ( !set_values(type
, &kernFunc
, &servMatch
, &dataType
) )
238 if ( probe_sms(kernFunc
, servMatch
, dataType
, &data
) ) {
239 switch ( dataType
) {
241 if ( x
) *x
= data
.pb_ib
.x
;
242 if ( y
) *y
= data
.pb_ib
.y
;
243 if ( z
) *z
= data
.pb_ib
.z
;
246 if ( x
) *x
= data
.mbp
.x
;
247 if ( y
) *y
= data
.mbp
.y
;
248 if ( z
) *z
= data
.mbp
.z
;
258 int read_sms(int type
, int *x
, int *y
, int *z
)
261 int xoff
, yoff
, zoff
;
265 ret
= read_sms_raw(type
, &_x
, &_y
, &_z
);
269 static CFStringRef app
= CFSTR("com.ramsayl.UniMotion");
270 static CFStringRef xoffstr
= CFSTR("x_offset");
271 static CFStringRef yoffstr
= CFSTR("y_offset");
272 static CFStringRef zoffstr
= CFSTR("z_offset");
273 xoff
= CFPreferencesGetAppIntegerValue(xoffstr
, app
, &ok
);
274 if ( ok
) _x
+= xoff
;
275 yoff
= CFPreferencesGetAppIntegerValue(yoffstr
, app
, &ok
);
276 if ( ok
) _y
+= yoff
;
277 zoff
= CFPreferencesGetAppIntegerValue(zoffstr
, app
, &ok
);
278 if ( ok
) _z
+= zoff
;
287 int read_sms_real(int type
, double *x
, double *y
, double *z
)
290 int xscale
, yscale
, zscale
;
294 ret
= read_sms_raw(type
, &_x
, &_y
, &_z
);
298 static CFStringRef app
= CFSTR("com.ramsayl.UniMotion");
299 static CFStringRef xscalestr
= CFSTR("x_scale");
300 static CFStringRef yscalestr
= CFSTR("y_scale");
301 static CFStringRef zscalestr
= CFSTR("z_scale");
302 xscale
= CFPreferencesGetAppIntegerValue(xscalestr
, app
, &ok
);
304 yscale
= CFPreferencesGetAppIntegerValue(yscalestr
, app
, &ok
);
306 zscale
= CFPreferencesGetAppIntegerValue(zscalestr
, app
, &ok
);
309 *x
= _x
/ (double)xscale
;
310 *y
= _y
/ (double)yscale
;
311 *z
= _z
/ (double)zscale
;