SDL enhancements:
[maemo-rb.git] / firmware / target / hosted / sdl / button-sdl.c
blob6890aae0ec9cc5960d3366c94d0647282b4cb0b1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Felix Arends
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <math.h>
23 #include <stdlib.h> /* EXIT_SUCCESS */
24 #include "sim-ui-defines.h"
25 #include "lcd-charcells.h"
26 #include "lcd-remote.h"
27 #include "config.h"
28 #include "button.h"
29 #include "kernel.h"
30 #include "backlight.h"
31 #include "misc.h"
32 #include "button-sdl.h"
33 #include "backlight.h"
34 #include "sim_tasks.h"
35 #include "buttonmap.h"
36 #include "debug.h"
38 #ifdef HAVE_TOUCHSCREEN
39 #include "touchscreen.h"
40 static int mouse_coords = 0;
41 #endif
42 /* how long until repeat kicks in */
43 #define REPEAT_START 6
45 /* the speed repeat starts at */
46 #define REPEAT_INTERVAL_START 4
48 /* speed repeat finishes at */
49 #define REPEAT_INTERVAL_FINISH 2
51 #ifdef HAVE_TOUCHSCREEN
52 #define USB_KEY SDLK_c /* SDLK_u is taken by BUTTON_MIDLEFT */
53 #else
54 #define USB_KEY SDLK_u
55 #endif
57 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
58 int _remote_type=REMOTETYPE_H100_LCD;
60 int remote_type(void)
62 return _remote_type;
64 #endif
66 struct event_queue button_queue;
68 static int btn = 0; /* Hopefully keeps track of currently pressed keys... */
70 #ifdef HAS_BUTTON_HOLD
71 bool hold_button_state = false;
72 bool button_hold(void) {
73 return hold_button_state;
75 #endif
77 #ifdef HAS_REMOTE_BUTTON_HOLD
78 bool remote_hold_button_state = false;
79 bool remote_button_hold(void) {
80 return remote_hold_button_state;
82 #endif
83 static void button_event(int key, bool pressed);
84 extern bool debug_wps;
85 extern bool mapping;
87 #ifdef HAVE_TOUCHSCREEN
88 static void touchscreen_event(int x, int y)
90 if(background) {
91 x -= UI_LCD_POSX;
92 y -= UI_LCD_POSY;
95 if(x >= 0 && y >= 0 && x < SIM_LCD_WIDTH && y < SIM_LCD_HEIGHT) {
96 mouse_coords = (x << 16) | y;
97 button_event(BUTTON_TOUCHSCREEN, true);
98 if (debug_wps)
99 printf("Mouse at: (%d, %d)\n", x, y);
102 #endif
104 static void mouse_event(SDL_MouseButtonEvent *event, bool button_up)
106 #define SQUARE(x) ((x)*(x))
107 static int x,y;
108 #ifdef SIMULATOR
109 static int xybutton = 0;
110 #endif
112 if(button_up) {
113 switch ( event->button )
115 /* The scrollwheel button up events are ignored as they are queued immediately */
116 case SDL_BUTTON_LEFT:
117 case SDL_BUTTON_MIDDLE:
118 if ( mapping && background ) {
119 printf(" { SDLK_, %d, %d, %d, \"\" },\n", x, y,
120 (int)sqrt( SQUARE(x-(int)event->x) + SQUARE(y-(int)event->y))
123 #ifdef SIMULATOR
124 if ( background && xybutton ) {
125 button_event( xybutton, false );
126 xybutton = 0;
128 #endif
129 #ifdef HAVE_TOUCHSCREEN
130 else
131 button_event(BUTTON_TOUCHSCREEN, false);
132 #endif
133 break;
135 } else { /* button down */
136 switch ( event->button )
138 #ifdef HAVE_SCROLLWHEEL
139 case SDL_BUTTON_WHEELUP:
140 button_event( SDLK_UP, true );
141 break;
142 case SDL_BUTTON_WHEELDOWN:
143 button_event( SDLK_DOWN, true );
144 break;
145 #endif
146 case SDL_BUTTON_LEFT:
147 case SDL_BUTTON_MIDDLE:
148 if ( mapping && background ) {
149 x = event->x;
150 y = event->y;
152 #ifdef SIMULATOR
153 if ( background ) {
154 xybutton = xy2button( event->x, event->y );
155 if( xybutton ) {
156 button_event( xybutton, true );
157 break;
159 #endif
161 #ifdef HAVE_TOUCHSCREEN
162 touchscreen_event(event->x, event->y);
163 #endif
164 break;
167 if (debug_wps && event->button == BUTTON_LEFT)
169 int m_x, m_y;
171 if ( background )
173 m_x = event->x - 1;
174 m_y = event->y - 1;
175 #ifdef HAVE_REMOTE
176 if ( event->y >= UI_REMOTE_POSY ) /* Remote Screen */
178 m_x -= UI_REMOTE_POSX;
179 m_y -= UI_REMOTE_POSY;
181 else
182 #endif
184 m_x -= UI_LCD_POSX;
185 m_y -= UI_LCD_POSY;
188 else
190 m_x = event->x / display_zoom;
191 m_y = event->y / display_zoom;
192 #ifdef HAVE_REMOTE
193 if ( m_y >= LCD_HEIGHT ) /* Remote Screen */
194 m_y -= LCD_HEIGHT;
195 #endif
198 printf("Mouse at: (%d, %d)\n", m_x, m_y);
201 #undef SQUARE
204 static bool event_handler(SDL_Event *event)
206 switch(event->type)
208 case SDL_KEYDOWN:
209 case SDL_KEYUP:
210 button_event(event->key.keysym.sym, event->type == SDL_KEYDOWN);
211 break;
212 #ifdef HAVE_TOUCHSCREEN
213 case SDL_MOUSEMOTION:
214 if (event->motion.state & SDL_BUTTON(1))
215 touchscreen_event(event->motion.x, event->motion.y);
216 break;
217 #endif
219 case SDL_MOUSEBUTTONUP:
220 case SDL_MOUSEBUTTONDOWN:
221 mouse_event(&event->button, event->type == SDL_MOUSEBUTTONUP);
222 break;
224 case SDL_QUIT:
225 return true;
228 return false;
231 void gui_message_loop(void)
233 SDL_Event event;
234 bool quit;
236 do {
237 /* wait for the next event */
238 while(SDL_WaitEvent(&event) == 0)
239 printf("SDL_WaitEvent() error\n");
241 sim_enter_irq_handler();
242 quit = event_handler(&event);
243 sim_exit_irq_handler();
245 } while(!quit);
248 static void button_event(int key, bool pressed)
250 int new_btn = 0;
251 static bool usb_connected = false;
252 if (usb_connected && key != USB_KEY)
253 return;
254 switch (key)
256 case USB_KEY:
257 if (!pressed)
259 usb_connected = !usb_connected;
260 if (usb_connected)
261 queue_post(&button_queue, SYS_USB_CONNECTED, 0);
262 else
263 queue_post(&button_queue, SYS_USB_DISCONNECTED, 0);
265 return;
267 #ifdef HAS_BUTTON_HOLD
268 case SDLK_h:
269 if(pressed)
271 hold_button_state = !hold_button_state;
272 DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF");
274 return;
275 #endif
277 #ifdef HAS_REMOTE_BUTTON_HOLD
278 case SDLK_j:
279 if(pressed)
281 remote_hold_button_state = !remote_hold_button_state;
282 DEBUGF("Remote hold button is %s\n",
283 remote_hold_button_state?"ON":"OFF");
285 return;
286 #endif
288 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
289 case SDLK_t:
290 if(pressed)
291 switch(_remote_type)
293 case REMOTETYPE_UNPLUGGED:
294 _remote_type=REMOTETYPE_H100_LCD;
295 DEBUGF("Changed remote type to H100\n");
296 break;
297 case REMOTETYPE_H100_LCD:
298 _remote_type=REMOTETYPE_H300_LCD;
299 DEBUGF("Changed remote type to H300\n");
300 break;
301 case REMOTETYPE_H300_LCD:
302 _remote_type=REMOTETYPE_H300_NONLCD;
303 DEBUGF("Changed remote type to H300 NON-LCD\n");
304 break;
305 case REMOTETYPE_H300_NONLCD:
306 _remote_type=REMOTETYPE_UNPLUGGED;
307 DEBUGF("Changed remote type to none\n");
308 break;
310 break;
311 #endif
312 case SDLK_KP0:
313 case SDLK_F5:
314 if(pressed)
316 sim_trigger_screendump();
317 return;
319 break;
320 #ifdef HAVE_TOUCHSCREEN
321 case SDLK_F4:
322 if(pressed)
324 touchscreen_set_mode(touchscreen_get_mode() == TOUCHSCREEN_POINT ? TOUCHSCREEN_BUTTON : TOUCHSCREEN_POINT);
325 printf("Touchscreen mode: %s\n", touchscreen_get_mode() == TOUCHSCREEN_POINT ? "TOUCHSCREEN_POINT" : "TOUCHSCREEN_BUTTON");
327 #endif
328 default:
329 #ifdef HAVE_TOUCHSCREEN
330 new_btn = key_to_touch(key, mouse_coords);
331 if (!new_btn)
332 #endif
333 new_btn = key_to_button(key);
334 break;
336 /* Call to make up for scrollwheel target implementation. This is
337 * not handled in the main button.c driver, but on the target
338 * implementation (look at button-e200.c for example if you are trying to
339 * figure out why using button_get_data needed a hack before).
341 #if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK)
342 if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) &&
343 pressed)
345 /* Clear these buttons from the data - adding them to the queue is
346 * handled in the scrollwheel drivers for the targets. They do not
347 * store the scroll forward/back buttons in their button data for
348 * the button_read call.
350 #ifdef HAVE_BACKLIGHT
351 backlight_on();
352 #endif
353 #ifdef HAVE_BUTTON_LIGHT
354 buttonlight_on();
355 #endif
356 queue_post(&button_queue, new_btn, 1<<24);
357 new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK);
359 #endif
361 if (pressed)
362 btn |= new_btn;
363 else
364 btn &= ~new_btn;
366 #if defined(HAVE_BUTTON_DATA) && defined(HAVE_TOUCHSCREEN)
367 int button_read_device(int* data)
369 *data = mouse_coords;
370 #else
371 int button_read_device(void)
373 #endif
374 #ifdef HAS_BUTTON_HOLD
375 int hold_button = button_hold();
377 #ifdef HAVE_BACKLIGHT
378 /* light handling */
379 static int hold_button_old = false;
380 if (hold_button != hold_button_old)
382 hold_button_old = hold_button;
383 backlight_hold_changed(hold_button);
385 #endif
387 if (hold_button)
388 return BUTTON_NONE;
389 else
390 #endif
392 return btn;
395 void button_init_device(void)
397 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);