Remove the full url path from links to the wiki and display the wiki name only instea...
[Rockbox.git] / uisimulator / sdl / button.c
blob4869dd06b1d53c673e8dfc1f645e0d3e1b1e6d18
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 /* Special thread-synced queue_post for button driver or any other preemptive sim thread */
34 extern void queue_syncpost(struct event_queue *q, long id, intptr_t data);
35 /* Special thread-synced queue_broadcast for button driver or any other preemptive sim thread */
36 extern int queue_syncbroadcast(long id, intptr_t data);
38 /* how long until repeat kicks in */
39 #define REPEAT_START 6
41 /* the speed repeat starts at */
42 #define REPEAT_INTERVAL_START 4
44 /* speed repeat finishes at */
45 #define REPEAT_INTERVAL_FINISH 2
47 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
48 int _remote_type=REMOTETYPE_H100_LCD;
50 int remote_type(void)
52 return _remote_type;
54 #endif
56 struct event_queue button_queue;
58 static int btn = 0; /* Hopefully keeps track of currently pressed keys... */
60 #ifdef HAVE_BACKLIGHT
61 static bool filter_first_keypress;
63 void set_backlight_filter_keypress(bool value)
65 filter_first_keypress = value;
67 #ifdef HAVE_REMOTE_LCD
68 static bool remote_filter_first_keypress;
70 void set_remote_backlight_filter_keypress(bool value)
72 remote_filter_first_keypress = value;
74 #endif
75 #endif
77 #ifdef HAS_BUTTON_HOLD
78 bool hold_button_state = false;
79 bool button_hold(void) {
80 return hold_button_state;
82 #endif
84 #ifdef HAS_REMOTE_BUTTON_HOLD
85 bool remote_hold_button_state = false;
86 bool remote_button_hold(void) {
87 return remote_hold_button_state;
89 #endif
91 void button_event(int key, bool pressed)
93 int new_btn = 0;
94 int diff = 0;
95 static int count = 0;
96 static int lastbtn;
97 static int repeat_speed = REPEAT_INTERVAL_START;
98 static int repeat_count = 0;
99 static bool repeat = false;
100 static bool post = false;
101 #ifdef HAVE_BACKLIGHT
102 static bool skip_release = false;
103 #ifdef HAVE_REMOTE_LCD
104 static bool skip_remote_release = false;
105 #endif
106 #endif
107 static bool usb_connected = false;
108 if (usb_connected && key != SDLK_u)
109 return;
110 switch (key)
113 case SDLK_u:
114 if (!pressed)
116 usb_connected = !usb_connected;
117 if (usb_connected)
118 queue_syncpost(&button_queue, SYS_USB_CONNECTED, 0);
119 else
120 queue_syncpost(&button_queue, SYS_USB_DISCONNECTED, 0);
122 return;
124 #ifdef HAS_BUTTON_HOLD
125 case SDLK_h:
126 if(pressed)
128 hold_button_state = !hold_button_state;
129 DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF");
131 return;
132 #endif
134 #ifdef HAS_REMOTE_BUTTON_HOLD
135 case SDLK_j:
136 if(pressed)
138 remote_hold_button_state = !remote_hold_button_state;
139 DEBUGF("Remote hold button is %s\n",
140 remote_hold_button_state?"ON":"OFF");
142 return;
143 #endif
145 #if CONFIG_KEYPAD == GIGABEAT_PAD
146 case SDLK_KP4:
147 case SDLK_LEFT:
148 new_btn = BUTTON_LEFT;
149 break;
150 case SDLK_KP6:
151 case SDLK_RIGHT:
152 new_btn = BUTTON_RIGHT;
153 break;
154 case SDLK_KP8:
155 case SDLK_UP:
156 new_btn = BUTTON_UP;
157 break;
158 case SDLK_KP2:
159 case SDLK_DOWN:
160 new_btn = BUTTON_DOWN;
161 break;
162 case SDLK_KP_PLUS:
163 case SDLK_F8:
164 new_btn = BUTTON_POWER;
165 break;
166 case SDLK_ESCAPE:
167 new_btn = BUTTON_POWER;
168 break;
169 case SDLK_KP_ENTER:
170 case SDLK_RETURN:
171 case SDLK_a:
172 new_btn = BUTTON_A;
173 break;
174 case SDLK_KP5:
175 case SDLK_SPACE:
176 new_btn = BUTTON_SELECT;
177 break;
178 case SDLK_KP_PERIOD:
179 case SDLK_INSERT:
180 new_btn = BUTTON_MENU;
181 break;
183 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
184 case SDLK_KP4:
185 case SDLK_LEFT:
186 new_btn = BUTTON_LEFT;
187 break;
188 case SDLK_KP6:
189 case SDLK_RIGHT:
190 new_btn = BUTTON_RIGHT;
191 break;
192 case SDLK_KP8:
193 case SDLK_UP:
194 new_btn = BUTTON_UP;
195 break;
196 case SDLK_KP2:
197 case SDLK_DOWN:
198 new_btn = BUTTON_DOWN;
199 break;
200 case SDLK_KP_PLUS:
201 case SDLK_F8:
202 new_btn = BUTTON_PLAY;
203 break;
204 case SDLK_ESCAPE:
205 new_btn = BUTTON_POWER;
206 break;
207 case SDLK_KP_ENTER:
208 case SDLK_RETURN:
209 case SDLK_a:
210 new_btn = BUTTON_POWER;
211 break;
212 case SDLK_KP_DIVIDE:
213 case SDLK_F1:
214 new_btn = BUTTON_REC;
215 break;
216 case SDLK_KP5:
217 case SDLK_SPACE:
218 new_btn = BUTTON_SELECT;
219 break;
221 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) \
222 || (CONFIG_KEYPAD == IPOD_4G_PAD)
223 case SDLK_KP4:
224 case SDLK_LEFT:
225 new_btn = BUTTON_LEFT;
226 break;
227 case SDLK_KP6:
228 case SDLK_RIGHT:
229 new_btn = BUTTON_RIGHT;
230 break;
231 case SDLK_KP8:
232 case SDLK_UP:
233 new_btn = BUTTON_SCROLL_BACK;
234 break;
235 case SDLK_KP2:
236 case SDLK_DOWN:
237 new_btn = BUTTON_SCROLL_FWD;
238 break;
239 case SDLK_KP_PLUS:
240 case SDLK_F8:
241 new_btn = BUTTON_PLAY;
242 break;
243 case SDLK_KP5:
244 case SDLK_SPACE:
245 new_btn = BUTTON_SELECT;
246 break;
247 case SDLK_KP_PERIOD:
248 case SDLK_INSERT:
249 new_btn = BUTTON_MENU;
250 break;
252 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
253 case SDLK_KP4:
254 case SDLK_LEFT:
255 new_btn = BUTTON_LEFT;
256 break;
257 case SDLK_KP6:
258 case SDLK_RIGHT:
259 new_btn = BUTTON_RIGHT;
260 break;
261 case SDLK_KP8:
262 case SDLK_UP:
263 new_btn = BUTTON_SCROLL_UP;
264 break;
265 case SDLK_KP2:
266 case SDLK_DOWN:
267 new_btn = BUTTON_SCROLL_DOWN;
268 break;
269 case SDLK_KP_PLUS:
270 case SDLK_F8:
271 new_btn = BUTTON_POWER;
272 break;
273 case SDLK_ESCAPE:
274 new_btn = BUTTON_POWER;
275 break;
276 case SDLK_KP_DIVIDE:
277 case SDLK_F1:
278 new_btn = BUTTON_REW;
279 break;
280 case SDLK_KP_MULTIPLY:
281 case SDLK_F2:
282 new_btn = BUTTON_FF;
283 break;
284 case SDLK_KP5:
285 case SDLK_SPACE:
286 new_btn = BUTTON_PLAY;
287 break;
289 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
290 case SDLK_t:
291 if(pressed)
292 switch(_remote_type)
294 case REMOTETYPE_UNPLUGGED:
295 _remote_type=REMOTETYPE_H100_LCD;
296 DEBUGF("Changed remote type to H100\n");
297 break;
298 case REMOTETYPE_H100_LCD:
299 _remote_type=REMOTETYPE_H300_LCD;
300 DEBUGF("Changed remote type to H300\n");
301 break;
302 case REMOTETYPE_H300_LCD:
303 _remote_type=REMOTETYPE_H300_NONLCD;
304 DEBUGF("Changed remote type to H300 NON-LCD\n");
305 break;
306 case REMOTETYPE_H300_NONLCD:
307 _remote_type=REMOTETYPE_UNPLUGGED;
308 DEBUGF("Changed remote type to none\n");
309 break;
311 break;
312 case SDLK_KP4:
313 case SDLK_LEFT:
314 new_btn = BUTTON_LEFT;
315 break;
316 case SDLK_KP6:
317 case SDLK_RIGHT:
318 new_btn = BUTTON_RIGHT;
319 break;
320 case SDLK_KP8:
321 case SDLK_UP:
322 new_btn = BUTTON_UP;
323 break;
324 case SDLK_KP2:
325 case SDLK_DOWN:
326 new_btn = BUTTON_DOWN;
327 break;
328 case SDLK_KP_PLUS:
329 case SDLK_F8:
330 new_btn = BUTTON_ON;
331 break;
332 case SDLK_KP_ENTER:
333 case SDLK_RETURN:
334 case SDLK_a:
335 new_btn = BUTTON_OFF;
336 break;
337 case SDLK_KP_DIVIDE:
338 case SDLK_F1:
339 new_btn = BUTTON_REC;
340 break;
341 case SDLK_KP5:
342 case SDLK_SPACE:
343 new_btn = BUTTON_SELECT;
344 break;
345 case SDLK_KP_PERIOD:
346 case SDLK_INSERT:
347 new_btn = BUTTON_MODE;
348 break;
350 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
351 case SDLK_KP4:
352 case SDLK_LEFT:
353 new_btn = BUTTON_LEFT;
354 break;
355 case SDLK_KP6:
356 case SDLK_RIGHT:
357 new_btn = BUTTON_RIGHT;
358 break;
359 case SDLK_KP8:
360 case SDLK_UP:
361 new_btn = BUTTON_UP;
362 break;
363 case SDLK_KP2:
364 case SDLK_DOWN:
365 new_btn = BUTTON_DOWN;
366 break;
367 case SDLK_KP_PLUS:
368 case SDLK_F8:
369 new_btn = BUTTON_PLAY;
370 break;
371 case SDLK_KP_ENTER:
372 case SDLK_RETURN:
373 case SDLK_a:
374 new_btn = BUTTON_EQ;
375 break;
376 case SDLK_KP5:
377 case SDLK_SPACE:
378 new_btn = BUTTON_SELECT;
379 break;
380 case SDLK_KP_PERIOD:
381 case SDLK_INSERT:
382 new_btn = BUTTON_MODE;
383 break;
385 #elif CONFIG_KEYPAD == ONDIO_PAD
386 case SDLK_KP4:
387 case SDLK_LEFT:
388 new_btn = BUTTON_LEFT;
389 break;
390 case SDLK_KP6:
391 case SDLK_RIGHT:
392 new_btn = BUTTON_RIGHT;
393 break;
394 case SDLK_KP8:
395 case SDLK_UP:
396 new_btn = BUTTON_UP;
397 break;
398 case SDLK_KP2:
399 case SDLK_DOWN:
400 new_btn = BUTTON_DOWN;
401 break;
402 case SDLK_KP_ENTER:
403 case SDLK_RETURN:
404 case SDLK_a:
405 new_btn = BUTTON_OFF;
406 break;
407 case SDLK_KP_PERIOD:
408 case SDLK_INSERT:
409 new_btn = BUTTON_MENU;
410 break;
412 #elif CONFIG_KEYPAD == PLAYER_PAD
413 case SDLK_KP4:
414 case SDLK_LEFT:
415 new_btn = BUTTON_LEFT;
416 break;
417 case SDLK_KP6:
418 case SDLK_RIGHT:
419 new_btn = BUTTON_RIGHT;
420 break;
421 case SDLK_KP8:
422 case SDLK_UP:
423 new_btn = BUTTON_PLAY;
424 break;
425 case SDLK_KP2:
426 case SDLK_DOWN:
427 new_btn = BUTTON_STOP;
428 break;
429 case SDLK_KP_PLUS:
430 case SDLK_F8:
431 new_btn = BUTTON_ON;
432 break;
433 case SDLK_KP_PERIOD:
434 case SDLK_INSERT:
435 new_btn = BUTTON_MENU;
436 break;
438 #elif CONFIG_KEYPAD == RECORDER_PAD
439 case SDLK_KP4:
440 case SDLK_LEFT:
441 new_btn = BUTTON_LEFT;
442 break;
443 case SDLK_KP6:
444 case SDLK_RIGHT:
445 new_btn = BUTTON_RIGHT;
446 break;
447 case SDLK_KP8:
448 case SDLK_UP:
449 new_btn = BUTTON_UP;
450 break;
451 case SDLK_KP2:
452 case SDLK_DOWN:
453 new_btn = BUTTON_DOWN;
454 break;
455 case SDLK_KP_PLUS:
456 case SDLK_F8:
457 new_btn = BUTTON_ON;
458 break;
459 case SDLK_KP_ENTER:
460 case SDLK_RETURN:
461 case SDLK_a:
462 new_btn = BUTTON_OFF;
463 break;
464 case SDLK_KP_DIVIDE:
465 case SDLK_F1:
466 new_btn = BUTTON_F1;
467 break;
468 case SDLK_KP_MULTIPLY:
469 case SDLK_F2:
470 new_btn = BUTTON_F2;
471 break;
472 case SDLK_KP_MINUS:
473 case SDLK_F3:
474 new_btn = BUTTON_F3;
475 break;
476 case SDLK_KP5:
477 case SDLK_SPACE:
478 new_btn = BUTTON_PLAY;
479 break;
481 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
482 case SDLK_KP4:
483 case SDLK_LEFT:
484 new_btn = BUTTON_LEFT;
485 break;
486 case SDLK_KP6:
487 case SDLK_RIGHT:
488 new_btn = BUTTON_RIGHT;
489 break;
490 case SDLK_KP8:
491 case SDLK_UP:
492 new_btn = BUTTON_UP;
493 break;
494 case SDLK_KP2:
495 case SDLK_DOWN:
496 new_btn = BUTTON_DOWN;
497 break;
498 case SDLK_KP_PLUS:
499 case SDLK_F8:
500 new_btn = BUTTON_ON;
501 break;
502 case SDLK_KP_ENTER:
503 case SDLK_RETURN:
504 case SDLK_a:
505 new_btn = BUTTON_OFF;
506 break;
507 case SDLK_KP_DIVIDE:
508 case SDLK_F1:
509 new_btn = BUTTON_F1;
510 break;
511 case SDLK_KP_MULTIPLY:
512 case SDLK_F2:
513 new_btn = BUTTON_F2;
514 break;
515 case SDLK_KP_MINUS:
516 case SDLK_F3:
517 new_btn = BUTTON_F3;
518 break;
519 case SDLK_KP5:
520 case SDLK_SPACE:
521 new_btn = BUTTON_SELECT;
522 break;
524 #elif CONFIG_KEYPAD == SANSA_E200_PAD
525 case SDLK_KP4:
526 case SDLK_LEFT:
527 new_btn = BUTTON_LEFT;
528 break;
529 case SDLK_KP6:
530 case SDLK_RIGHT:
531 new_btn = BUTTON_RIGHT;
532 break;
533 case SDLK_KP8:
534 case SDLK_UP:
535 new_btn = BUTTON_SCROLL_UP;
536 break;
537 case SDLK_KP2:
538 case SDLK_DOWN:
539 new_btn = BUTTON_SCROLL_DOWN;
540 break;
541 case SDLK_KP9:
542 new_btn = BUTTON_UP;
543 break;
544 case SDLK_KP3:
545 new_btn = BUTTON_DOWN;
546 break;
547 case SDLK_KP1:
548 new_btn = BUTTON_POWER;
549 break;
550 case SDLK_KP7:
551 new_btn = BUTTON_REC;
552 break;
553 case SDLK_KP5:
554 case SDLK_SPACE:
555 new_btn = BUTTON_SELECT;
556 break;
558 #elif CONFIG_KEYPAD == SANSA_C200_PAD
559 case SDLK_KP4:
560 case SDLK_LEFT:
561 new_btn = BUTTON_LEFT;
562 break;
563 case SDLK_KP6:
564 case SDLK_RIGHT:
565 new_btn = BUTTON_RIGHT;
566 break;
567 case SDLK_KP8:
568 case SDLK_UP:
569 new_btn = BUTTON_UP;
570 break;
571 case SDLK_KP2:
572 case SDLK_DOWN:
573 new_btn = BUTTON_DOWN;
574 break;
575 case SDLK_KP3:
576 new_btn = BUTTON_POWER;
577 break;
578 case SDLK_KP1:
579 new_btn = BUTTON_REC;
580 break;
581 case SDLK_KP5:
582 case SDLK_KP_ENTER:
583 case SDLK_RETURN:
584 new_btn = BUTTON_SELECT;
585 break;
586 case SDLK_KP7:
587 new_btn = BUTTON_VOL_DOWN;
588 break;
589 case SDLK_KP9:
590 new_btn = BUTTON_VOL_UP;
591 break;
593 #endif /* CONFIG_KEYPAD */
594 case SDLK_KP0:
595 case SDLK_F5:
596 if(pressed)
598 queue_syncbroadcast(SYS_SCREENDUMP, 0);
599 return;
601 break;
604 if (pressed)
605 btn |= new_btn;
606 else
607 btn &= ~new_btn;
609 /* Lots of stuff copied from real button.c. Not good, I think... */
611 /* Find out if a key has been released */
612 diff = btn ^ lastbtn;
613 if(diff && (btn & diff) == 0)
615 #ifdef HAVE_BACKLIGHT
616 #ifdef HAVE_REMOTE_LCD
617 if(diff & BUTTON_REMOTE)
618 if(!skip_remote_release)
619 queue_syncpost(&button_queue, BUTTON_REL | diff, 0);
620 else
621 skip_remote_release = false;
622 else
623 #endif
624 if(!skip_release)
625 queue_syncpost(&button_queue, BUTTON_REL | diff, 0);
626 else
627 skip_release = false;
628 #else
629 queue_syncpost(&button_queue, BUTTON_REL | diff, 0);
630 #endif
633 else
635 if ( btn )
637 /* normal keypress */
638 if ( btn != lastbtn )
640 post = true;
641 repeat = false;
642 repeat_speed = REPEAT_INTERVAL_START;
645 else /* repeat? */
647 if ( repeat )
649 if (!post)
650 count--;
651 if (count == 0)
653 post = true;
654 /* yes we have repeat */
655 repeat_speed--;
656 if (repeat_speed < REPEAT_INTERVAL_FINISH)
657 repeat_speed = REPEAT_INTERVAL_FINISH;
658 count = repeat_speed;
660 repeat_count++;
663 else
665 if (count++ > REPEAT_START)
667 post = true;
668 repeat = true;
669 repeat_count = 0;
670 /* initial repeat */
671 count = REPEAT_INTERVAL_START;
675 if ( post )
677 if(repeat)
679 if (queue_empty(&button_queue))
681 queue_syncpost(&button_queue, BUTTON_REPEAT | btn, 0);
682 #ifdef HAVE_BACKLIGHT
683 #ifdef HAVE_REMOTE_LCD
684 if(btn & BUTTON_REMOTE)
686 if(skip_remote_release)
687 skip_remote_release = false;
689 else
690 #endif
691 if(skip_release)
692 skip_release = false;
693 #endif
694 post = false;
697 else
699 #ifdef HAVE_BACKLIGHT
700 #ifdef HAVE_REMOTE_LCD
701 if (btn & BUTTON_REMOTE) {
702 if (!remote_filter_first_keypress || is_remote_backlight_on())
703 queue_syncpost(&button_queue, btn, 0);
704 else
705 skip_remote_release = true;
707 else
708 #endif
709 if (!filter_first_keypress || is_backlight_on())
710 queue_syncpost(&button_queue, btn, 0);
711 else
712 skip_release = true;
713 #else /* no backlight, nothing to skip */
714 queue_syncpost(&button_queue, btn, 0);
715 #endif
716 post = false;
719 #ifdef HAVE_REMOTE_LCD
720 if(btn & BUTTON_REMOTE)
721 remote_backlight_on();
722 else
723 #endif
724 backlight_on();
728 else
730 repeat = false;
731 count = 0;
734 lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
737 /* Again copied from real button.c... */
739 long button_get(bool block)
741 struct event ev;
743 if ( block || !queue_empty(&button_queue) ) {
744 queue_wait(&button_queue, &ev);
745 button_data = ev.data;
746 return ev.id;
748 return BUTTON_NONE;
751 long button_get_w_tmo(int ticks)
753 struct event ev;
754 queue_wait_w_tmo(&button_queue, &ev, ticks);
755 if (ev.id == SYS_TIMEOUT)
756 ev.id = BUTTON_NONE;
757 else
758 button_data = ev.data;
760 return ev.id;
763 intptr_t button_get_data(void)
765 /* Needed by the accelerating wheel driver for Sansa e200 */
766 return 1 << 24;
769 void button_init(void)
773 int button_status(void)
775 return btn;
778 void button_clear_queue(void)
780 queue_clear(&button_queue);