The install window doesn't need to be wider than the other ones.
[Rockbox.git] / uisimulator / sdl / button.c
bloba435fd2c4e92453520fddff3c2b85fa717d6ab73
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Felix Arends
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "uisdl.h"
21 #include "lcd-charcells.h"
22 #include "lcd-remote.h"
23 #include "config.h"
24 #include "button.h"
25 #include "kernel.h"
26 #include "backlight.h"
27 #include "misc.h"
29 #include "debug.h"
31 static intptr_t button_data; /* data value from last message dequeued */
33 /* how long until repeat kicks in */
34 #define REPEAT_START 6
36 /* the speed repeat starts at */
37 #define REPEAT_INTERVAL_START 4
39 /* speed repeat finishes at */
40 #define REPEAT_INTERVAL_FINISH 2
42 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
43 int _remote_type=REMOTETYPE_H100_LCD;
45 int remote_type(void)
47 return _remote_type;
49 #endif
51 struct event_queue button_queue;
53 static int btn = 0; /* Hopefully keeps track of currently pressed keys... */
55 #ifdef HAVE_BACKLIGHT
56 static bool filter_first_keypress;
58 void set_backlight_filter_keypress(bool value)
60 filter_first_keypress = value;
62 #ifdef HAVE_REMOTE_LCD
63 static bool remote_filter_first_keypress;
65 void set_remote_backlight_filter_keypress(bool value)
67 remote_filter_first_keypress = value;
69 #endif
70 #endif
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
86 void button_event(int key, bool pressed)
88 int new_btn = 0;
89 int diff = 0;
90 static int count = 0;
91 static int lastbtn;
92 static int repeat_speed = REPEAT_INTERVAL_START;
93 static int repeat_count = 0;
94 static bool repeat = false;
95 static bool post = false;
96 #ifdef HAVE_BACKLIGHT
97 static bool skip_release = false;
98 #ifdef HAVE_REMOTE_LCD
99 static bool skip_remote_release = false;
100 #endif
101 #endif
102 static bool usb_connected = false;
103 if (usb_connected && key != SDLK_u)
104 return;
105 switch (key)
108 case SDLK_u:
109 if (!pressed)
111 usb_connected = !usb_connected;
112 if (usb_connected)
113 queue_post(&button_queue, SYS_USB_CONNECTED, 0);
114 else
115 queue_post(&button_queue, SYS_USB_DISCONNECTED, 0);
117 return;
119 #ifdef HAS_BUTTON_HOLD
120 case SDLK_h:
121 if(pressed)
123 hold_button_state = !hold_button_state;
124 DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF");
126 return;
127 #endif
129 #ifdef HAS_REMOTE_BUTTON_HOLD
130 case SDLK_j:
131 if(pressed)
133 remote_hold_button_state = !remote_hold_button_state;
134 DEBUGF("Remote hold button is %s\n",
135 remote_hold_button_state?"ON":"OFF");
137 return;
138 #endif
140 #if CONFIG_KEYPAD == GIGABEAT_PAD
141 case SDLK_KP4:
142 case SDLK_LEFT:
143 new_btn = BUTTON_LEFT;
144 break;
145 case SDLK_KP6:
146 case SDLK_RIGHT:
147 new_btn = BUTTON_RIGHT;
148 break;
149 case SDLK_KP8:
150 case SDLK_UP:
151 new_btn = BUTTON_UP;
152 break;
153 case SDLK_KP2:
154 case SDLK_DOWN:
155 new_btn = BUTTON_DOWN;
156 break;
157 case SDLK_KP_PLUS:
158 case SDLK_F8:
159 new_btn = BUTTON_POWER;
160 break;
161 case SDLK_ESCAPE:
162 new_btn = BUTTON_POWER;
163 break;
164 case SDLK_KP_ENTER:
165 case SDLK_RETURN:
166 case SDLK_a:
167 new_btn = BUTTON_A;
168 break;
169 case SDLK_KP5:
170 case SDLK_SPACE:
171 new_btn = BUTTON_SELECT;
172 break;
173 case SDLK_KP_PERIOD:
174 case SDLK_INSERT:
175 new_btn = BUTTON_MENU;
176 break;
178 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
179 case SDLK_KP4:
180 case SDLK_LEFT:
181 new_btn = BUTTON_LEFT;
182 break;
183 case SDLK_KP6:
184 case SDLK_RIGHT:
185 new_btn = BUTTON_RIGHT;
186 break;
187 case SDLK_KP8:
188 case SDLK_UP:
189 new_btn = BUTTON_UP;
190 break;
191 case SDLK_KP2:
192 case SDLK_DOWN:
193 new_btn = BUTTON_DOWN;
194 break;
195 case SDLK_KP_PLUS:
196 case SDLK_F8:
197 new_btn = BUTTON_PLAY;
198 break;
199 case SDLK_ESCAPE:
200 new_btn = BUTTON_POWER;
201 break;
202 case SDLK_KP_ENTER:
203 case SDLK_RETURN:
204 case SDLK_a:
205 new_btn = BUTTON_POWER;
206 break;
207 case SDLK_KP_DIVIDE:
208 case SDLK_F1:
209 new_btn = BUTTON_REC;
210 break;
211 case SDLK_KP5:
212 case SDLK_SPACE:
213 new_btn = BUTTON_SELECT;
214 break;
216 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) \
217 || (CONFIG_KEYPAD == IPOD_4G_PAD)
218 case SDLK_KP4:
219 case SDLK_LEFT:
220 new_btn = BUTTON_LEFT;
221 break;
222 case SDLK_KP6:
223 case SDLK_RIGHT:
224 new_btn = BUTTON_RIGHT;
225 break;
226 case SDLK_KP8:
227 case SDLK_UP:
228 new_btn = BUTTON_SCROLL_BACK;
229 break;
230 case SDLK_KP2:
231 case SDLK_DOWN:
232 new_btn = BUTTON_SCROLL_FWD;
233 break;
234 case SDLK_KP_PLUS:
235 case SDLK_F8:
236 new_btn = BUTTON_PLAY;
237 break;
238 case SDLK_KP5:
239 case SDLK_SPACE:
240 new_btn = BUTTON_SELECT;
241 break;
242 case SDLK_KP_PERIOD:
243 case SDLK_INSERT:
244 new_btn = BUTTON_MENU;
245 break;
247 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
248 case SDLK_KP4:
249 case SDLK_LEFT:
250 new_btn = BUTTON_LEFT;
251 break;
252 case SDLK_KP6:
253 case SDLK_RIGHT:
254 new_btn = BUTTON_RIGHT;
255 break;
256 case SDLK_KP8:
257 case SDLK_UP:
258 new_btn = BUTTON_SCROLL_UP;
259 break;
260 case SDLK_KP2:
261 case SDLK_DOWN:
262 new_btn = BUTTON_SCROLL_DOWN;
263 break;
264 case SDLK_KP_PLUS:
265 case SDLK_F8:
266 new_btn = BUTTON_POWER;
267 break;
268 case SDLK_ESCAPE:
269 new_btn = BUTTON_POWER;
270 break;
271 case SDLK_KP_DIVIDE:
272 case SDLK_F1:
273 new_btn = BUTTON_REW;
274 break;
275 case SDLK_KP_MULTIPLY:
276 case SDLK_F2:
277 new_btn = BUTTON_FF;
278 break;
279 case SDLK_KP5:
280 case SDLK_SPACE:
281 new_btn = BUTTON_PLAY;
282 break;
284 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
285 case SDLK_t:
286 if(pressed)
287 switch(_remote_type)
289 case REMOTETYPE_UNPLUGGED:
290 _remote_type=REMOTETYPE_H100_LCD;
291 DEBUGF("Changed remote type to H100\n");
292 break;
293 case REMOTETYPE_H100_LCD:
294 _remote_type=REMOTETYPE_H300_LCD;
295 DEBUGF("Changed remote type to H300\n");
296 break;
297 case REMOTETYPE_H300_LCD:
298 _remote_type=REMOTETYPE_H300_NONLCD;
299 DEBUGF("Changed remote type to H300 NON-LCD\n");
300 break;
301 case REMOTETYPE_H300_NONLCD:
302 _remote_type=REMOTETYPE_UNPLUGGED;
303 DEBUGF("Changed remote type to none\n");
304 break;
306 break;
307 case SDLK_KP4:
308 case SDLK_LEFT:
309 new_btn = BUTTON_LEFT;
310 break;
311 case SDLK_KP6:
312 case SDLK_RIGHT:
313 new_btn = BUTTON_RIGHT;
314 break;
315 case SDLK_KP8:
316 case SDLK_UP:
317 new_btn = BUTTON_UP;
318 break;
319 case SDLK_KP2:
320 case SDLK_DOWN:
321 new_btn = BUTTON_DOWN;
322 break;
323 case SDLK_KP_PLUS:
324 case SDLK_F8:
325 new_btn = BUTTON_ON;
326 break;
327 case SDLK_KP_ENTER:
328 case SDLK_RETURN:
329 case SDLK_a:
330 new_btn = BUTTON_OFF;
331 break;
332 case SDLK_KP_DIVIDE:
333 case SDLK_F1:
334 new_btn = BUTTON_REC;
335 break;
336 case SDLK_KP5:
337 case SDLK_SPACE:
338 new_btn = BUTTON_SELECT;
339 break;
340 case SDLK_KP_PERIOD:
341 case SDLK_INSERT:
342 new_btn = BUTTON_MODE;
343 break;
345 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
346 case SDLK_KP4:
347 case SDLK_LEFT:
348 new_btn = BUTTON_LEFT;
349 break;
350 case SDLK_KP6:
351 case SDLK_RIGHT:
352 new_btn = BUTTON_RIGHT;
353 break;
354 case SDLK_KP8:
355 case SDLK_UP:
356 new_btn = BUTTON_UP;
357 break;
358 case SDLK_KP2:
359 case SDLK_DOWN:
360 new_btn = BUTTON_DOWN;
361 break;
362 case SDLK_KP_PLUS:
363 case SDLK_F8:
364 new_btn = BUTTON_PLAY;
365 break;
366 case SDLK_KP_ENTER:
367 case SDLK_RETURN:
368 case SDLK_a:
369 new_btn = BUTTON_EQ;
370 break;
371 case SDLK_KP5:
372 case SDLK_SPACE:
373 new_btn = BUTTON_SELECT;
374 break;
375 case SDLK_KP_PERIOD:
376 case SDLK_INSERT:
377 new_btn = BUTTON_MODE;
378 break;
380 #elif CONFIG_KEYPAD == ONDIO_PAD
381 case SDLK_KP4:
382 case SDLK_LEFT:
383 new_btn = BUTTON_LEFT;
384 break;
385 case SDLK_KP6:
386 case SDLK_RIGHT:
387 new_btn = BUTTON_RIGHT;
388 break;
389 case SDLK_KP8:
390 case SDLK_UP:
391 new_btn = BUTTON_UP;
392 break;
393 case SDLK_KP2:
394 case SDLK_DOWN:
395 new_btn = BUTTON_DOWN;
396 break;
397 case SDLK_KP_ENTER:
398 case SDLK_RETURN:
399 case SDLK_a:
400 new_btn = BUTTON_OFF;
401 break;
402 case SDLK_KP_PERIOD:
403 case SDLK_INSERT:
404 new_btn = BUTTON_MENU;
405 break;
407 #elif CONFIG_KEYPAD == PLAYER_PAD
408 case SDLK_KP4:
409 case SDLK_LEFT:
410 new_btn = BUTTON_LEFT;
411 break;
412 case SDLK_KP6:
413 case SDLK_RIGHT:
414 new_btn = BUTTON_RIGHT;
415 break;
416 case SDLK_KP8:
417 case SDLK_UP:
418 new_btn = BUTTON_PLAY;
419 break;
420 case SDLK_KP2:
421 case SDLK_DOWN:
422 new_btn = BUTTON_STOP;
423 break;
424 case SDLK_KP_PLUS:
425 case SDLK_F8:
426 new_btn = BUTTON_ON;
427 break;
428 case SDLK_KP_PERIOD:
429 case SDLK_INSERT:
430 new_btn = BUTTON_MENU;
431 break;
433 #elif CONFIG_KEYPAD == RECORDER_PAD
434 case SDLK_KP4:
435 case SDLK_LEFT:
436 new_btn = BUTTON_LEFT;
437 break;
438 case SDLK_KP6:
439 case SDLK_RIGHT:
440 new_btn = BUTTON_RIGHT;
441 break;
442 case SDLK_KP8:
443 case SDLK_UP:
444 new_btn = BUTTON_UP;
445 break;
446 case SDLK_KP2:
447 case SDLK_DOWN:
448 new_btn = BUTTON_DOWN;
449 break;
450 case SDLK_KP_PLUS:
451 case SDLK_F8:
452 new_btn = BUTTON_ON;
453 break;
454 case SDLK_KP_ENTER:
455 case SDLK_RETURN:
456 case SDLK_a:
457 new_btn = BUTTON_OFF;
458 break;
459 case SDLK_KP_DIVIDE:
460 case SDLK_F1:
461 new_btn = BUTTON_F1;
462 break;
463 case SDLK_KP_MULTIPLY:
464 case SDLK_F2:
465 new_btn = BUTTON_F2;
466 break;
467 case SDLK_KP_MINUS:
468 case SDLK_F3:
469 new_btn = BUTTON_F3;
470 break;
471 case SDLK_KP5:
472 case SDLK_SPACE:
473 new_btn = BUTTON_PLAY;
474 break;
476 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
477 case SDLK_KP4:
478 case SDLK_LEFT:
479 new_btn = BUTTON_LEFT;
480 break;
481 case SDLK_KP6:
482 case SDLK_RIGHT:
483 new_btn = BUTTON_RIGHT;
484 break;
485 case SDLK_KP8:
486 case SDLK_UP:
487 new_btn = BUTTON_UP;
488 break;
489 case SDLK_KP2:
490 case SDLK_DOWN:
491 new_btn = BUTTON_DOWN;
492 break;
493 case SDLK_KP_PLUS:
494 case SDLK_F8:
495 new_btn = BUTTON_ON;
496 break;
497 case SDLK_KP_ENTER:
498 case SDLK_RETURN:
499 case SDLK_a:
500 new_btn = BUTTON_OFF;
501 break;
502 case SDLK_KP_DIVIDE:
503 case SDLK_F1:
504 new_btn = BUTTON_F1;
505 break;
506 case SDLK_KP_MULTIPLY:
507 case SDLK_F2:
508 new_btn = BUTTON_F2;
509 break;
510 case SDLK_KP_MINUS:
511 case SDLK_F3:
512 new_btn = BUTTON_F3;
513 break;
514 case SDLK_KP5:
515 case SDLK_SPACE:
516 new_btn = BUTTON_SELECT;
517 break;
519 #elif CONFIG_KEYPAD == SANSA_E200_PAD
520 case SDLK_KP4:
521 case SDLK_LEFT:
522 new_btn = BUTTON_LEFT;
523 break;
524 case SDLK_KP6:
525 case SDLK_RIGHT:
526 new_btn = BUTTON_RIGHT;
527 break;
528 case SDLK_KP8:
529 case SDLK_UP:
530 new_btn = BUTTON_SCROLL_UP;
531 break;
532 case SDLK_KP2:
533 case SDLK_DOWN:
534 new_btn = BUTTON_SCROLL_DOWN;
535 break;
536 case SDLK_KP9:
537 new_btn = BUTTON_UP;
538 break;
539 case SDLK_KP3:
540 new_btn = BUTTON_DOWN;
541 break;
542 case SDLK_KP1:
543 new_btn = BUTTON_POWER;
544 break;
545 case SDLK_KP7:
546 new_btn = BUTTON_REC;
547 break;
548 case SDLK_KP5:
549 case SDLK_SPACE:
550 new_btn = BUTTON_SELECT;
551 break;
553 #endif /* CONFIG_KEYPAD */
554 case SDLK_KP0:
555 case SDLK_F5:
556 if(pressed)
558 screen_dump();
559 return;
561 break;
564 if (pressed)
565 btn |= new_btn;
566 else
567 btn &= ~new_btn;
569 /* Lots of stuff copied from real button.c. Not good, I think... */
571 /* Find out if a key has been released */
572 diff = btn ^ lastbtn;
573 if(diff && (btn & diff) == 0)
575 #ifdef HAVE_BACKLIGHT
576 #ifdef HAVE_REMOTE_LCD
577 if(diff & BUTTON_REMOTE)
578 if(!skip_remote_release)
579 queue_post(&button_queue, BUTTON_REL | diff, 0);
580 else
581 skip_remote_release = false;
582 else
583 #endif
584 if(!skip_release)
585 queue_post(&button_queue, BUTTON_REL | diff, 0);
586 else
587 skip_release = false;
588 #else
589 queue_post(&button_queue, BUTTON_REL | diff, 0);
590 #endif
593 else
595 if ( btn )
597 /* normal keypress */
598 if ( btn != lastbtn )
600 post = true;
601 repeat = false;
602 repeat_speed = REPEAT_INTERVAL_START;
605 else /* repeat? */
607 if ( repeat )
609 if (!post)
610 count--;
611 if (count == 0)
613 post = true;
614 /* yes we have repeat */
615 repeat_speed--;
616 if (repeat_speed < REPEAT_INTERVAL_FINISH)
617 repeat_speed = REPEAT_INTERVAL_FINISH;
618 count = repeat_speed;
620 repeat_count++;
623 else
625 if (count++ > REPEAT_START)
627 post = true;
628 repeat = true;
629 repeat_count = 0;
630 /* initial repeat */
631 count = REPEAT_INTERVAL_START;
635 if ( post )
637 if(repeat)
639 if (queue_empty(&button_queue))
641 queue_post(&button_queue, BUTTON_REPEAT | btn, 0);
642 #ifdef HAVE_BACKLIGHT
643 #ifdef HAVE_REMOTE_LCD
644 if(btn & BUTTON_REMOTE)
646 if(skip_remote_release)
647 skip_remote_release = false;
649 else
650 #endif
651 if(skip_release)
652 skip_release = false;
653 #endif
654 post = false;
657 else
659 #ifdef HAVE_BACKLIGHT
660 #ifdef HAVE_REMOTE_LCD
661 if (btn & BUTTON_REMOTE) {
662 if (!remote_filter_first_keypress || is_remote_backlight_on())
663 queue_post(&button_queue, btn, 0);
664 else
665 skip_remote_release = true;
667 else
668 #endif
669 if (!filter_first_keypress || is_backlight_on())
670 queue_post(&button_queue, btn, 0);
671 else
672 skip_release = true;
673 #else /* no backlight, nothing to skip */
674 queue_post(&button_queue, btn, 0);
675 #endif
676 post = false;
679 #ifdef HAVE_REMOTE_LCD
680 if(btn & BUTTON_REMOTE)
681 remote_backlight_on();
682 else
683 #endif
684 backlight_on();
688 else
690 repeat = false;
691 count = 0;
694 lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
697 /* Again copied from real button.c... */
699 long button_get(bool block)
701 struct event ev;
703 if ( block || !queue_empty(&button_queue) ) {
704 queue_wait(&button_queue, &ev);
705 button_data = ev.data;
706 return ev.id;
708 return BUTTON_NONE;
711 long button_get_w_tmo(int ticks)
713 struct event ev;
714 queue_wait_w_tmo(&button_queue, &ev, ticks);
715 if (ev.id == SYS_TIMEOUT)
716 ev.id = BUTTON_NONE;
717 else
718 button_data = ev.data;
720 return ev.id;
723 intptr_t button_get_data(void)
725 /* Needed by the accelerating wheel driver for Sansa e200 */
726 return 1 << 24;
729 void button_init(void)
733 int button_status(void)
735 return btn;
738 void button_clear_queue(void)
740 queue_clear(&button_queue);