Fix newly introduced race condition in SD driver. Make sure to force remount in case...
[kugel-rb.git] / uisimulator / sdl / button.c
blob967f41baf76c286f29ab2c8eeb83f02c04b42b9c
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 #ifdef HAVE_TOUCHPAD
34 static int mouse_coords = 0;
35 #endif
36 /* how long until repeat kicks in */
37 #define REPEAT_START 6
39 /* the speed repeat starts at */
40 #define REPEAT_INTERVAL_START 4
42 /* speed repeat finishes at */
43 #define REPEAT_INTERVAL_FINISH 2
45 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
46 int _remote_type=REMOTETYPE_H100_LCD;
48 int remote_type(void)
50 return _remote_type;
52 #endif
54 struct event_queue button_queue;
56 static int btn = 0; /* Hopefully keeps track of currently pressed keys... */
58 #ifdef HAVE_BACKLIGHT
59 static bool filter_first_keypress;
61 void set_backlight_filter_keypress(bool value)
63 filter_first_keypress = value;
65 #ifdef HAVE_REMOTE_LCD
66 static bool remote_filter_first_keypress;
68 void set_remote_backlight_filter_keypress(bool value)
70 remote_filter_first_keypress = value;
72 #endif
73 #endif
75 #ifdef HAS_BUTTON_HOLD
76 bool hold_button_state = false;
77 bool button_hold(void) {
78 return hold_button_state;
80 #endif
82 #ifdef HAS_REMOTE_BUTTON_HOLD
83 bool remote_hold_button_state = false;
84 bool remote_button_hold(void) {
85 return remote_hold_button_state;
87 #endif
89 static int lastbtn;
90 void button_event(int key, bool pressed)
92 int new_btn = 0;
93 int diff = 0;
94 int data = 0;
95 static int count = 0;
96 static int repeat_speed = REPEAT_INTERVAL_START;
97 static int repeat_count = 0;
98 static bool repeat = false;
99 static bool post = false;
100 #ifdef HAVE_BACKLIGHT
101 static bool skip_release = false;
102 #ifdef HAVE_REMOTE_LCD
103 static bool skip_remote_release = false;
104 #endif
105 #endif
106 static bool usb_connected = false;
107 if (usb_connected && key != SDLK_u)
108 return;
109 switch (key)
112 #ifdef HAVE_TOUCHPAD
113 case BUTTON_TOUCHPAD:
114 new_btn = BUTTON_TOUCHPAD;
115 data = mouse_coords;
116 break;
117 #endif
118 case SDLK_u:
119 if (!pressed)
121 usb_connected = !usb_connected;
122 if (usb_connected)
123 queue_post(&button_queue, SYS_USB_CONNECTED, 0);
124 else
125 queue_post(&button_queue, SYS_USB_DISCONNECTED, 0);
127 return;
129 #ifdef HAS_BUTTON_HOLD
130 case SDLK_h:
131 if(pressed)
133 hold_button_state = !hold_button_state;
134 DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF");
136 return;
137 #endif
139 #ifdef HAS_REMOTE_BUTTON_HOLD
140 case SDLK_j:
141 if(pressed)
143 remote_hold_button_state = !remote_hold_button_state;
144 DEBUGF("Remote hold button is %s\n",
145 remote_hold_button_state?"ON":"OFF");
147 return;
148 #endif
150 #if CONFIG_KEYPAD == GIGABEAT_PAD
151 case SDLK_KP4:
152 case SDLK_LEFT:
153 new_btn = BUTTON_LEFT;
154 break;
155 case SDLK_KP6:
156 case SDLK_RIGHT:
157 new_btn = BUTTON_RIGHT;
158 break;
159 case SDLK_KP8:
160 case SDLK_UP:
161 new_btn = BUTTON_UP;
162 break;
163 case SDLK_KP2:
164 case SDLK_DOWN:
165 new_btn = BUTTON_DOWN;
166 break;
167 case SDLK_KP_PLUS:
168 case SDLK_F8:
169 new_btn = BUTTON_POWER;
170 break;
171 case SDLK_ESCAPE:
172 new_btn = BUTTON_POWER;
173 break;
174 case SDLK_KP_ENTER:
175 case SDLK_RETURN:
176 case SDLK_a:
177 new_btn = BUTTON_A;
178 break;
179 case SDLK_KP5:
180 case SDLK_SPACE:
181 new_btn = BUTTON_SELECT;
182 break;
183 case SDLK_KP_PERIOD:
184 case SDLK_INSERT:
185 new_btn = BUTTON_MENU;
186 break;
188 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
189 case SDLK_KP4:
190 case SDLK_LEFT:
191 new_btn = BUTTON_LEFT;
192 break;
193 case SDLK_KP6:
194 case SDLK_RIGHT:
195 new_btn = BUTTON_RIGHT;
196 break;
197 case SDLK_KP8:
198 case SDLK_UP:
199 new_btn = BUTTON_UP;
200 break;
201 case SDLK_KP2:
202 case SDLK_DOWN:
203 new_btn = BUTTON_DOWN;
204 break;
205 case SDLK_F8:
206 case SDLK_ESCAPE:
207 new_btn = BUTTON_POWER;
208 break;
209 case SDLK_KP_PLUS:
210 case SDLK_KP_ENTER:
211 case SDLK_RETURN:
212 new_btn = BUTTON_PLAY;
213 break;
214 case SDLK_KP7:
215 new_btn = BUTTON_BACK;
216 break;
217 case SDLK_KP5:
218 case SDLK_SPACE:
219 new_btn = BUTTON_SELECT;
220 break;
221 case SDLK_KP9:
222 case SDLK_KP_PERIOD:
223 case SDLK_INSERT:
224 new_btn = BUTTON_MENU;
225 break;
227 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
228 case SDLK_KP4:
229 case SDLK_LEFT:
230 new_btn = BUTTON_LEFT;
231 break;
232 case SDLK_KP6:
233 case SDLK_RIGHT:
234 new_btn = BUTTON_RIGHT;
235 break;
236 case SDLK_KP8:
237 case SDLK_UP:
238 new_btn = BUTTON_UP;
239 break;
240 case SDLK_KP2:
241 case SDLK_DOWN:
242 new_btn = BUTTON_DOWN;
243 break;
244 case SDLK_KP_PLUS:
245 case SDLK_F8:
246 new_btn = BUTTON_PLAY;
247 break;
248 case SDLK_ESCAPE:
249 new_btn = BUTTON_POWER;
250 break;
251 case SDLK_KP_ENTER:
252 case SDLK_RETURN:
253 case SDLK_a:
254 new_btn = BUTTON_POWER;
255 break;
256 case SDLK_KP_DIVIDE:
257 case SDLK_F1:
258 new_btn = BUTTON_REC;
259 break;
260 case SDLK_KP5:
261 case SDLK_SPACE:
262 new_btn = BUTTON_SELECT;
263 break;
265 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) \
266 || (CONFIG_KEYPAD == IPOD_4G_PAD)
267 case SDLK_KP4:
268 case SDLK_LEFT:
269 new_btn = BUTTON_LEFT;
270 break;
271 case SDLK_KP6:
272 case SDLK_RIGHT:
273 new_btn = BUTTON_RIGHT;
274 break;
275 case SDLK_KP8:
276 case SDLK_UP:
277 new_btn = BUTTON_SCROLL_BACK;
278 break;
279 case SDLK_KP2:
280 case SDLK_DOWN:
281 new_btn = BUTTON_SCROLL_FWD;
282 break;
283 case SDLK_KP_PLUS:
284 case SDLK_F8:
285 new_btn = BUTTON_PLAY;
286 break;
287 case SDLK_KP5:
288 case SDLK_SPACE:
289 new_btn = BUTTON_SELECT;
290 break;
291 case SDLK_KP_PERIOD:
292 case SDLK_INSERT:
293 new_btn = BUTTON_MENU;
294 break;
296 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
297 case SDLK_KP4:
298 case SDLK_LEFT:
299 new_btn = BUTTON_LEFT;
300 break;
301 case SDLK_KP6:
302 case SDLK_RIGHT:
303 new_btn = BUTTON_RIGHT;
304 break;
305 case SDLK_KP8:
306 case SDLK_UP:
307 new_btn = BUTTON_SCROLL_UP;
308 break;
309 case SDLK_KP2:
310 case SDLK_DOWN:
311 new_btn = BUTTON_SCROLL_DOWN;
312 break;
313 case SDLK_KP_PLUS:
314 case SDLK_F8:
315 new_btn = BUTTON_POWER;
316 break;
317 case SDLK_ESCAPE:
318 new_btn = BUTTON_POWER;
319 break;
320 case SDLK_KP_DIVIDE:
321 case SDLK_F1:
322 new_btn = BUTTON_REW;
323 break;
324 case SDLK_KP_MULTIPLY:
325 case SDLK_F2:
326 new_btn = BUTTON_FF;
327 break;
328 case SDLK_KP5:
329 case SDLK_SPACE:
330 new_btn = BUTTON_PLAY;
331 break;
333 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
334 case SDLK_t:
335 if(pressed)
336 switch(_remote_type)
338 case REMOTETYPE_UNPLUGGED:
339 _remote_type=REMOTETYPE_H100_LCD;
340 DEBUGF("Changed remote type to H100\n");
341 break;
342 case REMOTETYPE_H100_LCD:
343 _remote_type=REMOTETYPE_H300_LCD;
344 DEBUGF("Changed remote type to H300\n");
345 break;
346 case REMOTETYPE_H300_LCD:
347 _remote_type=REMOTETYPE_H300_NONLCD;
348 DEBUGF("Changed remote type to H300 NON-LCD\n");
349 break;
350 case REMOTETYPE_H300_NONLCD:
351 _remote_type=REMOTETYPE_UNPLUGGED;
352 DEBUGF("Changed remote type to none\n");
353 break;
355 break;
356 case SDLK_KP4:
357 case SDLK_LEFT:
358 new_btn = BUTTON_LEFT;
359 break;
360 case SDLK_KP6:
361 case SDLK_RIGHT:
362 new_btn = BUTTON_RIGHT;
363 break;
364 case SDLK_KP8:
365 case SDLK_UP:
366 new_btn = BUTTON_UP;
367 break;
368 case SDLK_KP2:
369 case SDLK_DOWN:
370 new_btn = BUTTON_DOWN;
371 break;
372 case SDLK_KP_PLUS:
373 case SDLK_F8:
374 new_btn = BUTTON_ON;
375 break;
376 case SDLK_KP_ENTER:
377 case SDLK_RETURN:
378 case SDLK_a:
379 new_btn = BUTTON_OFF;
380 break;
381 case SDLK_KP_DIVIDE:
382 case SDLK_F1:
383 new_btn = BUTTON_REC;
384 break;
385 case SDLK_KP5:
386 case SDLK_SPACE:
387 new_btn = BUTTON_SELECT;
388 break;
389 case SDLK_KP_PERIOD:
390 case SDLK_INSERT:
391 new_btn = BUTTON_MODE;
392 break;
394 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
395 case SDLK_KP4:
396 case SDLK_LEFT:
397 new_btn = BUTTON_LEFT;
398 break;
399 case SDLK_KP6:
400 case SDLK_RIGHT:
401 new_btn = BUTTON_RIGHT;
402 break;
403 case SDLK_KP8:
404 case SDLK_UP:
405 new_btn = BUTTON_UP;
406 break;
407 case SDLK_KP2:
408 case SDLK_DOWN:
409 new_btn = BUTTON_DOWN;
410 break;
411 case SDLK_KP_PLUS:
412 case SDLK_F8:
413 new_btn = BUTTON_PLAY;
414 break;
415 case SDLK_KP_ENTER:
416 case SDLK_RETURN:
417 case SDLK_a:
418 new_btn = BUTTON_EQ;
419 break;
420 case SDLK_KP5:
421 case SDLK_SPACE:
422 new_btn = BUTTON_SELECT;
423 break;
424 case SDLK_KP_PERIOD:
425 case SDLK_INSERT:
426 new_btn = BUTTON_MODE;
427 break;
429 #elif CONFIG_KEYPAD == ONDIO_PAD
430 case SDLK_KP4:
431 case SDLK_LEFT:
432 new_btn = BUTTON_LEFT;
433 break;
434 case SDLK_KP6:
435 case SDLK_RIGHT:
436 new_btn = BUTTON_RIGHT;
437 break;
438 case SDLK_KP8:
439 case SDLK_UP:
440 new_btn = BUTTON_UP;
441 break;
442 case SDLK_KP2:
443 case SDLK_DOWN:
444 new_btn = BUTTON_DOWN;
445 break;
446 case SDLK_KP_ENTER:
447 case SDLK_RETURN:
448 case SDLK_a:
449 new_btn = BUTTON_OFF;
450 break;
451 case SDLK_KP_PERIOD:
452 case SDLK_INSERT:
453 new_btn = BUTTON_MENU;
454 break;
456 #elif CONFIG_KEYPAD == PLAYER_PAD
457 case SDLK_KP4:
458 case SDLK_LEFT:
459 new_btn = BUTTON_LEFT;
460 break;
461 case SDLK_KP6:
462 case SDLK_RIGHT:
463 new_btn = BUTTON_RIGHT;
464 break;
465 case SDLK_KP8:
466 case SDLK_UP:
467 new_btn = BUTTON_PLAY;
468 break;
469 case SDLK_KP2:
470 case SDLK_DOWN:
471 new_btn = BUTTON_STOP;
472 break;
473 case SDLK_KP_PLUS:
474 case SDLK_F8:
475 new_btn = BUTTON_ON;
476 break;
477 case SDLK_KP_PERIOD:
478 case SDLK_INSERT:
479 new_btn = BUTTON_MENU;
480 break;
482 #elif CONFIG_KEYPAD == RECORDER_PAD
483 case SDLK_KP4:
484 case SDLK_LEFT:
485 new_btn = BUTTON_LEFT;
486 break;
487 case SDLK_KP6:
488 case SDLK_RIGHT:
489 new_btn = BUTTON_RIGHT;
490 break;
491 case SDLK_KP8:
492 case SDLK_UP:
493 new_btn = BUTTON_UP;
494 break;
495 case SDLK_KP2:
496 case SDLK_DOWN:
497 new_btn = BUTTON_DOWN;
498 break;
499 case SDLK_KP_PLUS:
500 case SDLK_F8:
501 new_btn = BUTTON_ON;
502 break;
503 case SDLK_KP_ENTER:
504 case SDLK_RETURN:
505 case SDLK_a:
506 new_btn = BUTTON_OFF;
507 break;
508 case SDLK_KP_DIVIDE:
509 case SDLK_F1:
510 new_btn = BUTTON_F1;
511 break;
512 case SDLK_KP_MULTIPLY:
513 case SDLK_F2:
514 new_btn = BUTTON_F2;
515 break;
516 case SDLK_KP_MINUS:
517 case SDLK_F3:
518 new_btn = BUTTON_F3;
519 break;
520 case SDLK_KP5:
521 case SDLK_SPACE:
522 new_btn = BUTTON_PLAY;
523 break;
525 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
526 case SDLK_KP4:
527 case SDLK_LEFT:
528 new_btn = BUTTON_LEFT;
529 break;
530 case SDLK_KP6:
531 case SDLK_RIGHT:
532 new_btn = BUTTON_RIGHT;
533 break;
534 case SDLK_KP8:
535 case SDLK_UP:
536 new_btn = BUTTON_UP;
537 break;
538 case SDLK_KP2:
539 case SDLK_DOWN:
540 new_btn = BUTTON_DOWN;
541 break;
542 case SDLK_KP_PLUS:
543 case SDLK_F8:
544 new_btn = BUTTON_ON;
545 break;
546 case SDLK_KP_ENTER:
547 case SDLK_RETURN:
548 case SDLK_a:
549 new_btn = BUTTON_OFF;
550 break;
551 case SDLK_KP_DIVIDE:
552 case SDLK_F1:
553 new_btn = BUTTON_F1;
554 break;
555 case SDLK_KP_MULTIPLY:
556 case SDLK_F2:
557 new_btn = BUTTON_F2;
558 break;
559 case SDLK_KP_MINUS:
560 case SDLK_F3:
561 new_btn = BUTTON_F3;
562 break;
563 case SDLK_KP5:
564 case SDLK_SPACE:
565 new_btn = BUTTON_SELECT;
566 break;
568 #elif CONFIG_KEYPAD == SANSA_E200_PAD
569 case SDLK_KP4:
570 case SDLK_LEFT:
571 new_btn = BUTTON_LEFT;
572 break;
573 case SDLK_KP6:
574 case SDLK_RIGHT:
575 new_btn = BUTTON_RIGHT;
576 break;
577 case SDLK_KP8:
578 case SDLK_UP:
579 new_btn = BUTTON_SCROLL_BACK;
580 break;
581 case SDLK_KP2:
582 case SDLK_DOWN:
583 new_btn = BUTTON_SCROLL_FWD;
584 break;
585 case SDLK_KP9:
586 new_btn = BUTTON_UP;
587 break;
588 case SDLK_KP3:
589 new_btn = BUTTON_DOWN;
590 break;
591 case SDLK_KP1:
592 new_btn = BUTTON_POWER;
593 break;
594 case SDLK_KP7:
595 new_btn = BUTTON_REC;
596 break;
597 case SDLK_KP5:
598 case SDLK_SPACE:
599 new_btn = BUTTON_SELECT;
600 break;
602 #elif CONFIG_KEYPAD == SANSA_C200_PAD
603 case SDLK_KP4:
604 case SDLK_LEFT:
605 new_btn = BUTTON_LEFT;
606 break;
607 case SDLK_KP6:
608 case SDLK_RIGHT:
609 new_btn = BUTTON_RIGHT;
610 break;
611 case SDLK_KP8:
612 case SDLK_UP:
613 new_btn = BUTTON_UP;
614 break;
615 case SDLK_KP2:
616 case SDLK_DOWN:
617 new_btn = BUTTON_DOWN;
618 break;
619 case SDLK_KP3:
620 new_btn = BUTTON_POWER;
621 break;
622 case SDLK_KP1:
623 new_btn = BUTTON_REC;
624 break;
625 case SDLK_KP5:
626 case SDLK_KP_ENTER:
627 case SDLK_RETURN:
628 new_btn = BUTTON_SELECT;
629 break;
630 case SDLK_KP7:
631 new_btn = BUTTON_VOL_DOWN;
632 break;
633 case SDLK_KP9:
634 new_btn = BUTTON_VOL_UP;
635 break;
637 #elif CONFIG_KEYPAD == MROBE500_PAD
638 case SDLK_KP4:
639 case SDLK_LEFT:
640 new_btn = BUTTON_LEFT;
641 break;
642 case SDLK_KP6:
643 case SDLK_RIGHT:
644 new_btn = BUTTON_RIGHT;
645 break;
646 case SDLK_KP8:
647 case SDLK_UP:
648 new_btn = BUTTON_RC_PLAY;
649 break;
650 case SDLK_KP2:
651 case SDLK_DOWN:
652 new_btn = BUTTON_RC_DOWN;
653 break;
654 case SDLK_KP_PLUS:
655 case SDLK_F8:
656 new_btn = BUTTON_POWER;
657 break;
658 case SDLK_ESCAPE:
659 new_btn = BUTTON_POWER;
660 break;
661 case SDLK_KP_ENTER:
662 case SDLK_RETURN:
663 case SDLK_a:
664 new_btn = BUTTON_RC_VOL_UP;
665 break;
666 case SDLK_KP5:
667 case SDLK_SPACE:
668 new_btn = BUTTON_RC_HEART;
669 break;
670 case SDLK_KP_PERIOD:
671 case SDLK_INSERT:
672 new_btn = BUTTON_RC_MODE;
673 break;
675 #elif CONFIG_KEYPAD == MROBE100_PAD
676 case SDLK_KP1:
677 new_btn = BUTTON_DISPLAY;
678 break;
679 case SDLK_KP7:
680 new_btn = BUTTON_MENU;
681 break;
682 case SDLK_KP9:
683 new_btn = BUTTON_PLAY;
684 break;
685 case SDLK_KP4:
686 case SDLK_LEFT:
687 new_btn = BUTTON_LEFT;
688 break;
689 case SDLK_KP6:
690 case SDLK_RIGHT:
691 new_btn = BUTTON_RIGHT;
692 break;
693 case SDLK_KP8:
694 case SDLK_UP:
695 new_btn = BUTTON_UP;
696 break;
697 case SDLK_KP2:
698 case SDLK_DOWN:
699 new_btn = BUTTON_DOWN;
700 break;
701 case SDLK_KP5:
702 case SDLK_SPACE:
703 new_btn = BUTTON_SELECT;
704 break;
705 case SDLK_KP_MULTIPLY:
706 case SDLK_F8:
707 case SDLK_ESCAPE:
708 new_btn = BUTTON_POWER;
709 break;
711 #elif CONFIG_KEYPAD == COWOND2_PAD
712 case SDLK_KP4:
713 case SDLK_LEFT:
714 new_btn = BUTTON_LEFT;
715 break;
716 case SDLK_KP6:
717 case SDLK_RIGHT:
718 new_btn = BUTTON_RIGHT;
719 break;
720 case SDLK_KP8:
721 case SDLK_UP:
722 new_btn = BUTTON_UP;
723 break;
724 case SDLK_KP2:
725 case SDLK_DOWN:
726 new_btn = BUTTON_DOWN;
727 break;
728 case SDLK_KP3:
729 new_btn = BUTTON_POWER;
730 break;
731 case SDLK_KP5:
732 case SDLK_KP_ENTER:
733 case SDLK_RETURN:
734 new_btn = BUTTON_SELECT;
735 break;
736 case SDLK_KP_PLUS:
737 new_btn = BUTTON_PLUS;
738 break;
739 case SDLK_KP_MINUS:
740 new_btn = BUTTON_MINUS;
741 break;
742 case SDLK_KP9:
743 new_btn = BUTTON_MENU;
744 break;
745 #else
746 #error No keymap defined!
747 #endif /* CONFIG_KEYPAD */
748 case SDLK_KP0:
749 case SDLK_F5:
750 if(pressed)
752 queue_broadcast(SYS_SCREENDUMP, 0);
753 return;
755 break;
758 if (pressed)
759 btn |= new_btn;
760 else
761 btn &= ~new_btn;
763 /* Lots of stuff copied from real button.c. Not good, I think... */
765 /* Find out if a key has been released */
766 diff = btn ^ lastbtn;
767 if(diff && (btn & diff) == 0)
769 #ifdef HAVE_BACKLIGHT
770 #ifdef HAVE_REMOTE_LCD
771 if(diff & BUTTON_REMOTE)
772 if(!skip_remote_release)
773 queue_post(&button_queue, BUTTON_REL | diff, data);
774 else
775 skip_remote_release = false;
776 else
777 #endif
778 if(!skip_release)
779 queue_post(&button_queue, BUTTON_REL | diff, data);
780 else
781 skip_release = false;
782 #else
783 queue_post(&button_queue, BUTTON_REL | diff, data);
784 #endif
787 else
789 if ( btn )
791 /* normal keypress */
792 if ( btn != lastbtn )
794 post = true;
795 repeat = false;
796 repeat_speed = REPEAT_INTERVAL_START;
799 else /* repeat? */
801 if ( repeat )
803 if (!post)
804 count--;
805 if (count == 0)
807 post = true;
808 /* yes we have repeat */
809 repeat_speed--;
810 if (repeat_speed < REPEAT_INTERVAL_FINISH)
811 repeat_speed = REPEAT_INTERVAL_FINISH;
812 count = repeat_speed;
814 repeat_count++;
817 else
819 if (count++ > REPEAT_START)
821 post = true;
822 repeat = true;
823 repeat_count = 0;
824 /* initial repeat */
825 count = REPEAT_INTERVAL_START;
829 if ( post )
831 if(repeat)
833 if (queue_empty(&button_queue))
835 queue_post(&button_queue, BUTTON_REPEAT | btn, data);
836 #ifdef HAVE_BACKLIGHT
837 #ifdef HAVE_REMOTE_LCD
838 if(btn & BUTTON_REMOTE)
840 if(skip_remote_release)
841 skip_remote_release = false;
843 else
844 #endif
845 if(skip_release)
846 skip_release = false;
847 #endif
848 post = false;
851 else
853 #ifdef HAVE_BACKLIGHT
854 #ifdef HAVE_REMOTE_LCD
855 if (btn & BUTTON_REMOTE) {
856 if (!remote_filter_first_keypress || is_remote_backlight_on())
857 queue_post(&button_queue, btn, data);
858 else
859 skip_remote_release = true;
861 else
862 #endif
863 if (!filter_first_keypress || is_backlight_on())
864 queue_post(&button_queue, btn, data);
865 else
866 skip_release = true;
867 #else /* no backlight, nothing to skip */
868 queue_post(&button_queue, btn, data);
869 #endif
870 post = false;
873 #ifdef HAVE_REMOTE_LCD
874 if(btn & BUTTON_REMOTE)
875 remote_backlight_on();
876 else
877 #endif
878 backlight_on();
882 else
884 repeat = false;
885 count = 0;
888 lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
891 /* Again copied from real button.c... */
893 int button_queue_count( void )
895 return queue_count(&button_queue);
898 long button_get(bool block)
900 struct queue_event ev;
902 if ( block || !queue_empty(&button_queue) ) {
903 queue_wait(&button_queue, &ev);
904 button_data = ev.data;
905 return ev.id;
907 return BUTTON_NONE;
910 long button_get_w_tmo(int ticks)
912 struct queue_event ev;
913 queue_wait_w_tmo(&button_queue, &ev, ticks);
914 if (ev.id == SYS_TIMEOUT)
915 ev.id = BUTTON_NONE;
916 else
917 button_data = ev.data;
919 return ev.id;
922 intptr_t button_get_data(void)
924 #ifdef HAVE_TOUCHPAD
925 return button_data;
926 #else
927 /* Needed by the accelerating wheel driver for Sansa e200 */
928 return 1 << 24;
929 #endif
932 #ifdef HAVE_TOUCHPAD
933 extern bool debug_wps;
934 void mouse_tick_task(void)
936 static int last_check = 0;
937 int x,y;
938 if (TIME_BEFORE(current_tick, last_check+(HZ/10)))
939 return;
940 last_check = current_tick;
941 if (SDL_GetMouseState(&x, &y) & SDL_BUTTON(SDL_BUTTON_LEFT))
943 mouse_coords = (x<<16)|y;
944 button_event(BUTTON_TOUCHPAD, true);
945 if (debug_wps)
946 printf("Mouse at: (%d, %d)\n", x, y);
948 else if (lastbtn == BUTTON_TOUCHPAD)
950 button_event(BUTTON_TOUCHPAD, false);
951 mouse_coords = 0;
954 #endif
955 void button_init(void)
957 #ifdef HAVE_TOUCHPAD
958 tick_add_task(mouse_tick_task);
959 #endif
962 int button_status(void)
964 return btn;
967 void button_clear_queue(void)
969 queue_clear(&button_queue);