1 /*
2 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
4
5 All rights reserved.
6
7 Written by Denis Oliver Kropp <dok@directfb.org>,
8 Andreas Hundt <andi@fischlustig.de>,
9 Sven Neumann <neo@directfb.org>,
10 Ville Syrjälä <syrjala@sci.fi> and
11 Claudio Ciccani <klan@users.sf.net>.
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27 */
28
29 #include <config.h>
30
31 #include <string.h>
32 #include <unistd.h>
33 #include <errno.h>
34
35 #include <directfb.h>
36
37
38 #include <core/coredefs.h>
39 #include <core/coretypes.h>
40 #include <core/input.h>
41 #include <core/system.h>
42
43 #include <direct/mem.h>
44 #include <direct/thread.h>
45
46 #include <Carbon/Carbon.h>
47
48 #include "osx.h"
49
50 #include <core/input_driver.h>
51
52
53 DFB_INPUT_DRIVER( osxinput )
54
55 /*
56 * declaration of private data
57 */
58 typedef struct {
59 CoreInputDevice *device;
60 DirectThread *thread;
61 DFBOSX *dfb_osx;
62 int stop;
63 } OSXInputData;
64
65 static DFBInputEvent motionX = {
66 .type = DIET_UNKNOWN,
67 .axisabs = 0,
68 };
69
70 static DFBInputEvent motionY = {
71 .type = DIET_UNKNOWN,
72 .axisabs = 0,
73 };
74
75 static void
motion_compress(int x,int y)76 motion_compress( int x, int y )
77 {
78 if (motionX.axisabs != x) {
79 motionX.type = DIET_AXISMOTION;
80 motionX.flags = DIEF_AXISABS;
81 motionX.axis = DIAI_X;
82 motionX.axisabs = x;
83 }
84
85 if (motionY.axisabs != y) {
86 motionY.type = DIET_AXISMOTION;
87 motionY.flags = DIEF_AXISABS;
88 motionY.axis = DIAI_Y;
89 motionY.axisabs = y;
90 }
91 }
92
93 static void
motion_realize(OSXInputData * data)94 motion_realize( OSXInputData *data )
95 {
96 if (motionX.type != DIET_UNKNOWN) {
97 dfb_input_dispatch( data->device, &motionX );
98
99 motionX.type = DIET_UNKNOWN;
100 }
101
102 if (motionY.type != DIET_UNKNOWN) {
103 dfb_input_dispatch( data->device, &motionY );
104
105 motionY.type = DIET_UNKNOWN;
106 }
107 }
108
109
110 static bool
translate_key(unsigned short key,DFBInputEvent * evt)111 translate_key( unsigned short key, DFBInputEvent *evt )
112 {
113 unsigned char charcode = (unsigned char)key;
114 unsigned char keycode = (unsigned char)(key>>8);
115
116 printf("keycode: %d char: %d\n",keycode,charcode);
117
118 if (charcode) {
119 evt->flags = DIEF_KEYSYMBOL;
120 switch (charcode) {
121 case 28: evt->key_symbol = DIKS_CURSOR_LEFT; break;
122 case 29: evt->key_symbol = DIKS_CURSOR_RIGHT; break;
123 case 30: evt->key_symbol = DIKS_CURSOR_UP; break;
124 case 31: evt->key_symbol = DIKS_CURSOR_DOWN; break;
125 default:
126 evt->key_symbol = charcode;
127 break;
128 }
129 return true;
130 }
131 else if (keycode) {
132 evt->flags = DIEF_KEYID;
133 evt->key_id = keycode;
134 return true;
135 }
136
137 return false;
138 }
139
140 /*
141 * Input thread reading from device.
142 * Generates events on incoming data.
143 */
144 static void*
osxEventThread(DirectThread * thread,void * driver_data)145 osxEventThread( DirectThread *thread, void *driver_data )
146 {
147 OSXInputData *data = (OSXInputData*) driver_data;
148 DFBOSX *dfb_osx = data->dfb_osx;
149
150 while (!data->stop) {
151 DFBInputEvent evt;
152 EventRecord event;
153
154 fusion_skirmish_prevail( &dfb_osx->lock );
155
156 /* Check for events */
157 while ( WaitNextEvent( everyEvent, &event, 0, nil) ) {
158 fusion_skirmish_dismiss( &dfb_osx->lock );
159
160 switch (event.what) {
161 case keyDown:
162 case keyUp:
163 case autoKey:
164 if (event.what == keyUp)
165 evt.type = DIET_KEYRELEASE;
166 else
167 evt.type = DIET_KEYPRESS;
168
169 if (translate_key( event.message & (charCodeMask | keyCodeMask), &evt )) {
170 dfb_input_dispatch( data->device, &evt );
171 }
172
173 break;
174 case mouseDown:
175 evt.type = DIET_BUTTONPRESS;
176 evt.button = DIBI_LEFT;
177 dfb_input_dispatch( data->device, &evt );
178 break;
179 case mouseUp:
180 evt.type = DIET_BUTTONRELEASE;
181 evt.button = DIBI_LEFT;
182 dfb_input_dispatch( data->device, &evt );
183 break;
184 default:
185 printf("%d\n",event.what);
186 break;
187 }
188
189 fusion_skirmish_prevail( &dfb_osx->lock );
190 }
191
192 fusion_skirmish_dismiss( &dfb_osx->lock );
193
194 usleep(10000);
195
196 direct_thread_testcancel( thread );
197 }
198
199 return NULL;
200 }
201
202 /* exported symbols */
203
204 /*
205 * Return the number of available devices.
206 * Called once during initialization of DirectFB.
207 */
208 static int
driver_get_available(void)209 driver_get_available( void )
210 {
211 if (dfb_system_type() == CORE_OSX)
212 return 1;
213
214 return 0;
215 }
216
217 /*
218 * Fill out general information about this driver.
219 * Called once during initialization of DirectFB.
220 */
221 static void
driver_get_info(InputDriverInfo * info)222 driver_get_info( InputDriverInfo *info )
223 {
224 /* fill driver info structure */
225 snprintf ( info->name,
226 DFB_INPUT_DRIVER_INFO_NAME_LENGTH, "OSX Input Driver" );
227 snprintf ( info->vendor,
228 DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH, "Andreas Hundt" );
229
230 info->version.major = 0;
231 info->version.minor = 1;
232 }
233
234 /*
235 * Open the device, fill out information about it,
236 * allocate and fill private data, start input thread.
237 * Called during initialization, resuming or taking over mastership.
238 */
239 static DFBResult
driver_open_device(CoreInputDevice * device,unsigned int number,InputDeviceInfo * info,void ** driver_data)240 driver_open_device( CoreInputDevice *device,
241 unsigned int number,
242 InputDeviceInfo *info,
243 void **driver_data )
244 {
245 OSXInputData *data;
246 DFBOSX *dfb_osx = dfb_system_data();
247
248 fusion_skirmish_prevail( &dfb_osx->lock );
249
250 fusion_skirmish_dismiss( &dfb_osx->lock );
251
252 /* set device name */
253 snprintf( info->desc.name,
254 DFB_INPUT_DEVICE_DESC_NAME_LENGTH, "OSX Input" );
255
256 /* set device vendor */
257 snprintf( info->desc.vendor,
258 DFB_INPUT_DEVICE_DESC_VENDOR_LENGTH, "OSX" );
259
260 /* set one of the primary input device IDs */
261 info->prefered_id = DIDID_KEYBOARD;
262
263 /* set type flags */
264 info->desc.type = DIDTF_KEYBOARD | DIDTF_MOUSE;
265
266 /* set capabilities */
267 info->desc.caps = DICAPS_ALL;
268
269 /* allocate and fill private data */
270 data = D_CALLOC( 1, sizeof(OSXInputData) );
271
272 data->device = device;
273 data->dfb_osx = dfb_osx;
274
275 /* start input thread */
276 data->thread = direct_thread_create( DTT_INPUT, osxEventThread, data, "OSX Input" );
277
278 /* set private data pointer */
279 *driver_data = data;
280
281 return DFB_OK;
282 }
283
284 /*
285 * Fetch one entry from the device's keymap if supported.
286 */
287 static DFBResult
driver_get_keymap_entry(CoreInputDevice * device,void * driver_data,DFBInputDeviceKeymapEntry * entry)288 driver_get_keymap_entry( CoreInputDevice *device,
289 void *driver_data,
290 DFBInputDeviceKeymapEntry *entry )
291 {
292 return DFB_UNSUPPORTED;
293 }
294
295 /*
296 * End thread, close device and free private data.
297 */
298 static void
driver_close_device(void * driver_data)299 driver_close_device( void *driver_data )
300 {
301 OSXInputData *data = (OSXInputData*) driver_data;
302
303 /* stop input thread */
304 data->stop = 1;
305
306 direct_thread_join( data->thread );
307 direct_thread_destroy( data->thread );
308
309 /* free private data */
310 D_FREE ( data );
311 }
312