SDL target: remove mouse polling and replace it with an event-based mechanism, this...
[kugel-rb.git] / firmware / target / hosted / sdl / button-sdl.c
blob8b236c19f1533c157686e542d62baf3a6ae49ea8
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 #ifdef SIMULATOR
35 #include "sim_tasks.h"
36 #include "buttonmap.h"
37 #endif
38 #include "debug.h"
40 #ifdef HAVE_TOUCHSCREEN
41 #include "touchscreen.h"
42 static int mouse_coords = 0;
43 #endif
44 /* how long until repeat kicks in */
45 #define REPEAT_START 6
47 /* the speed repeat starts at */
48 #define REPEAT_INTERVAL_START 4
50 /* speed repeat finishes at */
51 #define REPEAT_INTERVAL_FINISH 2
53 #ifdef HAVE_TOUCHSCREEN
54 #define USB_KEY SDLK_c /* SDLK_u is taken by BUTTON_MIDLEFT */
55 #else
56 #define USB_KEY SDLK_u
57 #endif
59 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
60 int _remote_type=REMOTETYPE_H100_LCD;
62 int remote_type(void)
64 return _remote_type;
66 #endif
68 struct event_queue button_queue;
70 static int btn = 0; /* Hopefully keeps track of currently pressed keys... */
72 #ifdef HAS_BUTTON_HOLD
73 bool hold_button_state = false;
74 bool button_hold(void) {
75 return hold_button_state;
77 #endif
79 #ifdef HAS_REMOTE_BUTTON_HOLD
80 bool remote_hold_button_state = false;
81 bool remote_button_hold(void) {
82 return remote_hold_button_state;
84 #endif
85 static void button_event(int key, bool pressed);
86 extern bool debug_wps;
87 extern bool mapping;
89 #ifdef HAVE_TOUCHSCREEN
90 static void touchscreen_event(int x, int y)
92 if(background) {
93 x -= UI_LCD_POSX;
94 y -= UI_LCD_POSY;
97 if(x >= 0 && y >= 0 && x < SIM_LCD_WIDTH && y < SIM_LCD_HEIGHT) {
98 mouse_coords = (x << 16) | y;
99 button_event(BUTTON_TOUCHSCREEN, true);
100 if (debug_wps)
101 printf("Mouse at: (%d, %d)\n", x, y);
104 #endif
106 bool gui_message_loop(void)
108 SDL_Event event;
109 static int x,y,xybutton = 0;
111 while (SDL_WaitEvent(&event))
113 sim_enter_irq_handler();
114 switch(event.type)
116 case SDL_KEYDOWN:
117 case SDL_KEYUP:
118 button_event(event.key.keysym.sym, event.type == SDL_KEYDOWN);
119 break;
120 #ifdef HAVE_TOUCHSCREEN
121 case SDL_MOUSEMOTION:
122 if (event.motion.state & SDL_BUTTON(1))
123 touchscreen_event(event.motion.x, event.motion.y);
124 break;
125 #endif
126 case SDL_MOUSEBUTTONDOWN:
127 switch ( event.button.button ) {
128 #ifdef HAVE_SCROLLWHEEL
129 case SDL_BUTTON_WHEELUP:
130 button_event( SDLK_UP, true );
131 break;
132 case SDL_BUTTON_WHEELDOWN:
133 button_event( SDLK_DOWN, true );
134 break;
135 #endif
136 case SDL_BUTTON_LEFT:
137 case SDL_BUTTON_MIDDLE:
138 if ( mapping && background ) {
139 x = event.button.x;
140 y = event.button.y;
142 if ( background ) {
143 xybutton = xy2button( event.button.x, event.button.y );
144 if( xybutton ) {
145 button_event( xybutton, true );
146 break;
149 #ifdef HAVE_TOUCHSCREEN
150 touchscreen_event(event.button.x, event.button.y);
151 #endif
152 break;
154 default:
155 break;
158 if (debug_wps && event.button.button == 1)
160 if ( background )
161 #ifdef HAVE_REMOTE
162 if ( event.button.y < UI_REMOTE_POSY ) /* Main Screen */
163 printf("Mouse at: (%d, %d)\n", event.button.x - UI_LCD_POSX -1 , event.button.y - UI_LCD_POSY - 1 );
164 else
165 printf("Mouse at: (%d, %d)\n", event.button.x - UI_REMOTE_POSX -1 , event.button.y - UI_REMOTE_POSY - 1 );
166 #else
167 printf("Mouse at: (%d, %d)\n", event.button.x - UI_LCD_POSX -1 , event.button.y - UI_LCD_POSY - 1 );
168 #endif
169 else
170 if ( event.button.y/display_zoom < LCD_HEIGHT ) /* Main Screen */
171 printf("Mouse at: (%d, %d)\n", event.button.x/display_zoom, event.button.y/display_zoom );
172 #ifdef HAVE_REMOTE
173 else
174 printf("Mouse at: (%d, %d)\n", event.button.x/display_zoom, event.button.y/display_zoom - LCD_HEIGHT );
175 #endif
177 break;
178 case SDL_MOUSEBUTTONUP:
179 switch ( event.button.button ) {
180 /* The scrollwheel button up events are ignored as they are queued immediately */
181 case SDL_BUTTON_LEFT:
182 case SDL_BUTTON_MIDDLE:
183 if ( mapping && background ) {
184 printf(" { SDLK_, %d, %d, %d, \"\" },\n", x,
185 #define SQUARE(x) ((x)*(x))
186 y, (int)sqrt( SQUARE(x-(int)event.button.x)
187 + SQUARE(y-(int)event.button.y)) );
189 if ( background && xybutton ) {
190 button_event( xybutton, false );
191 xybutton = 0;
193 #ifdef HAVE_TOUCHSCREEN
194 else
195 button_event(BUTTON_TOUCHSCREEN, false);
196 #endif
197 break;
198 default:
199 break;
201 break;
204 case SDL_QUIT:
206 sim_exit_irq_handler();
207 return false;
209 default:
210 /*printf("Unhandled event\n"); */
211 break;
213 sim_exit_irq_handler();
216 return true;
219 static void button_event(int key, bool pressed)
221 int new_btn = 0;
222 static bool usb_connected = false;
223 if (usb_connected && key != USB_KEY)
224 return;
225 switch (key)
227 case USB_KEY:
228 if (!pressed)
230 usb_connected = !usb_connected;
231 if (usb_connected)
232 queue_post(&button_queue, SYS_USB_CONNECTED, 0);
233 else
234 queue_post(&button_queue, SYS_USB_DISCONNECTED, 0);
236 return;
238 #ifdef HAS_BUTTON_HOLD
239 case SDLK_h:
240 if(pressed)
242 hold_button_state = !hold_button_state;
243 DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF");
245 return;
246 #endif
248 #ifdef HAS_REMOTE_BUTTON_HOLD
249 case SDLK_j:
250 if(pressed)
252 remote_hold_button_state = !remote_hold_button_state;
253 DEBUGF("Remote hold button is %s\n",
254 remote_hold_button_state?"ON":"OFF");
256 return;
257 #endif
259 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
260 case SDLK_t:
261 if(pressed)
262 switch(_remote_type)
264 case REMOTETYPE_UNPLUGGED:
265 _remote_type=REMOTETYPE_H100_LCD;
266 DEBUGF("Changed remote type to H100\n");
267 break;
268 case REMOTETYPE_H100_LCD:
269 _remote_type=REMOTETYPE_H300_LCD;
270 DEBUGF("Changed remote type to H300\n");
271 break;
272 case REMOTETYPE_H300_LCD:
273 _remote_type=REMOTETYPE_H300_NONLCD;
274 DEBUGF("Changed remote type to H300 NON-LCD\n");
275 break;
276 case REMOTETYPE_H300_NONLCD:
277 _remote_type=REMOTETYPE_UNPLUGGED;
278 DEBUGF("Changed remote type to none\n");
279 break;
281 break;
282 #endif
283 case SDLK_KP0:
284 case SDLK_F5:
285 if(pressed)
287 sim_trigger_screendump();
288 return;
290 break;
291 #ifdef HAVE_TOUCHSCREEN
292 case SDLK_F4:
293 if(pressed)
295 touchscreen_set_mode(touchscreen_get_mode() == TOUCHSCREEN_POINT ? TOUCHSCREEN_BUTTON : TOUCHSCREEN_POINT);
296 printf("Touchscreen mode: %s\n", touchscreen_get_mode() == TOUCHSCREEN_POINT ? "TOUCHSCREEN_POINT" : "TOUCHSCREEN_BUTTON");
298 #endif
299 default:
300 #ifdef HAVE_TOUCHSCREEN
301 new_btn = key_to_touch(key, mouse_coords);
302 if (!new_btn)
303 #endif
304 new_btn = key_to_button(key);
305 break;
307 /* Call to make up for scrollwheel target implementation. This is
308 * not handled in the main button.c driver, but on the target
309 * implementation (look at button-e200.c for example if you are trying to
310 * figure out why using button_get_data needed a hack before).
312 #if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK)
313 if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) &&
314 pressed)
316 /* Clear these buttons from the data - adding them to the queue is
317 * handled in the scrollwheel drivers for the targets. They do not
318 * store the scroll forward/back buttons in their button data for
319 * the button_read call.
321 #ifdef HAVE_BACKLIGHT
322 backlight_on();
323 #endif
324 #ifdef HAVE_BUTTON_LIGHT
325 buttonlight_on();
326 #endif
327 queue_post(&button_queue, new_btn, 1<<24);
328 new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK);
330 #endif
332 if (pressed)
333 btn |= new_btn;
334 else
335 btn &= ~new_btn;
337 #if defined(HAVE_BUTTON_DATA) && defined(HAVE_TOUCHSCREEN)
338 int button_read_device(int* data)
340 *data = mouse_coords;
341 #else
342 int button_read_device(void)
344 #endif
345 #ifdef HAS_BUTTON_HOLD
346 int hold_button = button_hold();
348 #ifdef HAVE_BACKLIGHT
349 /* light handling */
350 static int hold_button_old = false;
351 if (hold_button != hold_button_old)
353 hold_button_old = hold_button;
354 backlight_hold_changed(hold_button);
356 #endif
358 if (hold_button)
359 return BUTTON_NONE;
360 else
361 #endif
363 return btn;
366 void button_init_device(void)
368 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);