qt: playlist: use item title if available
[vlc.git] / modules / control / unimotion.c
blob59044bb22e3472a473b5928852a9ed956e223d66
1 /*
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
21 * HISTORY of Motion
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.
30 /* motion.c
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
37 * ---===---
38 * *** teenage mutant ninja hero coders ***
39 * ---===---
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
47 * are met:
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
67 * SUCH DAMAGE.
71 #ifdef __APPLE__
72 #include "TargetConditionals.h"
73 #if !TARGET_OS_IPHONE
74 #define HAVE_MACOS_UNIMOTION
75 #endif
76 #endif
78 #ifdef HAVE_MACOS_UNIMOTION
80 #include "unimotion.h"
81 #include <IOKit/IOKitLib.h>
82 #include <CoreFoundation/CoreFoundation.h>
83 #include <stdint.h>
85 enum data_type {
86 PB_IB,
87 MBP
90 struct pb_ib_data {
91 int8_t x;
92 int8_t y;
93 int8_t z;
94 int8_t pad[57];
97 struct mbp_data {
98 int16_t x;
99 int16_t y;
100 int16_t z;
101 int8_t pad[34];
104 union motion_data {
105 struct pb_ib_data pb_ib;
106 struct mbp_data mbp;
110 static int set_values(int type, int *kernFunc, const char **servMatch, int *dataType)
112 switch ( type ) {
113 case powerbook:
114 *kernFunc = 21;
115 *servMatch = "IOI2CMotionSensor";
116 *dataType = PB_IB;
117 break;
118 case ibook:
119 *kernFunc = 21;
120 *servMatch = "IOI2CMotionSensor";
121 *dataType = PB_IB;
122 break;
123 case highrespb:
124 *kernFunc = 21;
125 *servMatch = "PMUMotionSensor";
126 *dataType = PB_IB;
127 break;
128 case macbookpro:
129 *kernFunc = 5;
130 *servMatch = "SMCMotionSensor";
131 *dataType = MBP;
132 break;
133 default:
134 return 0;
137 return 1;
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;
145 io_object_t aDevice;
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);
164 return 0;
167 aDevice = IOIteratorNext(iterator);
168 IOObjectRelease(iterator);
170 if (aDevice == 0) {
171 //fputs("No motion sensor available\n", stderr);
172 return 0;
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);
180 return 0;
183 switch ( dataType ) {
184 case PB_IB:
185 structureInputSize = sizeof(struct pb_ib_data);
186 structureOutputSize = sizeof(struct pb_ib_data);
187 break;
188 case MBP:
189 structureInputSize = sizeof(struct mbp_data);
190 structureOutputSize = sizeof(struct mbp_data);
191 break;
192 default:
193 return 0;
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) {
205 //puts("no coords");
206 return 0;
208 return 1;
211 int detect_sms()
213 int kernFunc;
214 const char *servMatch;
215 int dataType;
216 union motion_data data;
217 int i;
219 for ( i = 1; ; i++ ) {
220 if ( !set_values(i, &kernFunc, &servMatch, &dataType) )
221 break;
222 if ( probe_sms(kernFunc, servMatch, dataType, &data) )
223 return i;
226 return unknown;
229 int read_sms_raw(int type, int *x, int *y, int *z)
231 int kernFunc;
232 const char *servMatch;
233 int dataType;
234 union motion_data data;
236 if ( !set_values(type, &kernFunc, &servMatch, &dataType) )
237 return 0;
238 if ( probe_sms(kernFunc, servMatch, dataType, &data) ) {
239 switch ( dataType ) {
240 case PB_IB:
241 if ( x ) *x = data.pb_ib.x;
242 if ( y ) *y = data.pb_ib.y;
243 if ( z ) *z = data.pb_ib.z;
244 break;
245 case MBP:
246 if ( x ) *x = data.mbp.x;
247 if ( y ) *y = data.mbp.y;
248 if ( z ) *z = data.mbp.z;
249 break;
250 default:
251 return 0;
253 return 1;
255 return 0;
258 int read_sms(int type, int *x, int *y, int *z)
260 int _x, _y, _z;
261 int xoff, yoff, zoff;
262 Boolean ok;
263 int ret;
265 ret = read_sms_raw(type, &_x, &_y, &_z);
266 if ( !ret )
267 return 0;
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;
280 *x = _x;
281 *y = _y;
282 *z = _z;
284 return ret;
287 int read_sms_real(int type, double *x, double *y, double *z)
289 int _x, _y, _z;
290 int xscale, yscale, zscale;
291 int ret;
292 Boolean ok;
294 ret = read_sms_raw(type, &_x, &_y, &_z);
295 if ( !ret )
296 return 0;
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);
303 if ( !ok ) return 0;
304 yscale = CFPreferencesGetAppIntegerValue(yscalestr, app, &ok);
305 if ( !ok ) return 0;
306 zscale = CFPreferencesGetAppIntegerValue(zscalestr, app, &ok);
307 if ( !ok ) return 0;
309 *x = _x / (double)xscale;
310 *y = _y / (double)yscale;
311 *z = _z / (double)zscale;
313 return 1;
316 #endif