1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
23 #include "lcd-charcells.h"
24 #include "lcd-remote.h"
28 #include "backlight.h"
33 static intptr_t button_data
; /* data value from last message dequeued */
36 static int mouse_coords
= 0;
37 static enum touchpad_mode touchpad_mode
= TOUCHPAD_POINT
;
38 void touchpad_set_mode(enum touchpad_mode mode
)
42 enum touchpad_mode
touchpad_get_mode(void)
47 /* how long until repeat kicks in */
48 #define REPEAT_START 6
50 /* the speed repeat starts at */
51 #define REPEAT_INTERVAL_START 4
53 /* speed repeat finishes at */
54 #define REPEAT_INTERVAL_FINISH 2
56 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
57 int _remote_type
=REMOTETYPE_H100_LCD
;
65 struct event_queue button_queue
;
67 static int btn
= 0; /* Hopefully keeps track of currently pressed keys... */
70 static bool filter_first_keypress
;
72 void set_backlight_filter_keypress(bool value
)
74 filter_first_keypress
= value
;
76 #ifdef HAVE_REMOTE_LCD
77 static bool remote_filter_first_keypress
;
79 void set_remote_backlight_filter_keypress(bool value
)
81 remote_filter_first_keypress
= value
;
86 #ifdef HAS_BUTTON_HOLD
87 bool hold_button_state
= false;
88 bool button_hold(void) {
89 return hold_button_state
;
93 #ifdef HAS_REMOTE_BUTTON_HOLD
94 bool remote_hold_button_state
= false;
95 bool remote_button_hold(void) {
96 return remote_hold_button_state
;
101 void button_event(int key
, bool pressed
)
106 static int count
= 0;
107 static int repeat_speed
= REPEAT_INTERVAL_START
;
108 static int repeat_count
= 0;
109 static bool repeat
= false;
110 static bool post
= false;
111 #ifdef HAVE_BACKLIGHT
112 static bool skip_release
= false;
113 #ifdef HAVE_REMOTE_LCD
114 static bool skip_remote_release
= false;
117 static bool usb_connected
= false;
118 if (usb_connected
&& key
!= SDLK_u
)
124 case BUTTON_TOUCHPAD
:
126 switch (touchpad_mode
)
129 new_btn
= BUTTON_TOUCHPAD
;
131 case TOUCHPAD_BUTTON
:
133 static int touchpad_buttons
[3][3] = {
134 {BUTTON_TOPLEFT
, BUTTON_TOPMIDDLE
, BUTTON_TOPRIGHT
},
135 {BUTTON_MIDLEFT
, BUTTON_CENTER
, BUTTON_MIDRIGHT
},
136 {BUTTON_BOTTOMLEFT
, BUTTON_BOTTOMMIDDLE
, BUTTON_BOTTOMRIGHT
},
138 int px_x
= ((data
&0xffff0000)>>16), px_y
= ((data
&0x0000ffff));
139 new_btn
= touchpad_buttons
[px_y
/(LCD_HEIGHT
/3)][px_x
/(LCD_WIDTH
/3)];
145 new_btn
= BUTTON_TOPLEFT
;
148 new_btn
= BUTTON_TOPMIDDLE
;
151 new_btn
= BUTTON_TOPRIGHT
;
154 new_btn
= BUTTON_MIDLEFT
;
157 new_btn
= BUTTON_CENTER
;
160 new_btn
= BUTTON_MIDRIGHT
;
163 new_btn
= BUTTON_BOTTOMLEFT
;
166 new_btn
= BUTTON_BOTTOMMIDDLE
;
169 new_btn
= BUTTON_BOTTOMRIGHT
;
174 touchpad_mode
= (touchpad_mode
== TOUCHPAD_POINT
? TOUCHPAD_BUTTON
: TOUCHPAD_POINT
);
175 printf("Touchpad mode: %s\n", touchpad_mode
== TOUCHPAD_POINT
? "TOUCHPAD_POINT" : "TOUCHPAD_BUTTON");
183 usb_connected
= !usb_connected
;
185 queue_post(&button_queue
, SYS_USB_CONNECTED
, 0);
187 queue_post(&button_queue
, SYS_USB_DISCONNECTED
, 0);
191 #ifdef HAS_BUTTON_HOLD
195 hold_button_state
= !hold_button_state
;
196 DEBUGF("Hold button is %s\n", hold_button_state
?"ON":"OFF");
201 #ifdef HAS_REMOTE_BUTTON_HOLD
205 remote_hold_button_state
= !remote_hold_button_state
;
206 DEBUGF("Remote hold button is %s\n",
207 remote_hold_button_state
?"ON":"OFF");
212 #if CONFIG_KEYPAD == GIGABEAT_PAD
215 new_btn
= BUTTON_LEFT
;
219 new_btn
= BUTTON_RIGHT
;
227 new_btn
= BUTTON_DOWN
;
231 new_btn
= BUTTON_POWER
;
234 new_btn
= BUTTON_POWER
;
243 new_btn
= BUTTON_SELECT
;
247 new_btn
= BUTTON_MENU
;
250 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
253 new_btn
= BUTTON_LEFT
;
257 new_btn
= BUTTON_RIGHT
;
265 new_btn
= BUTTON_DOWN
;
269 new_btn
= BUTTON_POWER
;
274 new_btn
= BUTTON_PLAY
;
277 new_btn
= BUTTON_BACK
;
281 new_btn
= BUTTON_SELECT
;
286 new_btn
= BUTTON_MENU
;
289 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
292 new_btn
= BUTTON_LEFT
;
296 new_btn
= BUTTON_RIGHT
;
304 new_btn
= BUTTON_DOWN
;
308 new_btn
= BUTTON_PLAY
;
311 new_btn
= BUTTON_POWER
;
316 new_btn
= BUTTON_POWER
;
320 new_btn
= BUTTON_REC
;
324 new_btn
= BUTTON_SELECT
;
327 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
330 new_btn
= BUTTON_LEFT
;
334 new_btn
= BUTTON_RIGHT
;
338 new_btn
= BUTTON_VOL_UP
;
342 new_btn
= BUTTON_VOL_DOWN
;
346 new_btn
= BUTTON_MODE
;
350 new_btn
= BUTTON_REC
;
354 new_btn
= BUTTON_PLAY
;
357 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) \
358 || (CONFIG_KEYPAD == IPOD_4G_PAD)
361 new_btn
= BUTTON_LEFT
;
365 new_btn
= BUTTON_RIGHT
;
369 new_btn
= BUTTON_SCROLL_BACK
;
373 new_btn
= BUTTON_SCROLL_FWD
;
377 new_btn
= BUTTON_PLAY
;
381 new_btn
= BUTTON_SELECT
;
385 new_btn
= BUTTON_MENU
;
388 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
391 new_btn
= BUTTON_LEFT
;
395 new_btn
= BUTTON_RIGHT
;
399 new_btn
= BUTTON_SCROLL_UP
;
403 new_btn
= BUTTON_SCROLL_DOWN
;
407 new_btn
= BUTTON_POWER
;
410 new_btn
= BUTTON_POWER
;
414 new_btn
= BUTTON_REW
;
416 case SDLK_KP_MULTIPLY
:
422 new_btn
= BUTTON_PLAY
;
425 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
430 case REMOTETYPE_UNPLUGGED
:
431 _remote_type
=REMOTETYPE_H100_LCD
;
432 DEBUGF("Changed remote type to H100\n");
434 case REMOTETYPE_H100_LCD
:
435 _remote_type
=REMOTETYPE_H300_LCD
;
436 DEBUGF("Changed remote type to H300\n");
438 case REMOTETYPE_H300_LCD
:
439 _remote_type
=REMOTETYPE_H300_NONLCD
;
440 DEBUGF("Changed remote type to H300 NON-LCD\n");
442 case REMOTETYPE_H300_NONLCD
:
443 _remote_type
=REMOTETYPE_UNPLUGGED
;
444 DEBUGF("Changed remote type to none\n");
450 new_btn
= BUTTON_LEFT
;
454 new_btn
= BUTTON_RIGHT
;
462 new_btn
= BUTTON_DOWN
;
471 new_btn
= BUTTON_OFF
;
475 new_btn
= BUTTON_REC
;
479 new_btn
= BUTTON_SELECT
;
483 new_btn
= BUTTON_MODE
;
486 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
489 new_btn
= BUTTON_LEFT
;
493 new_btn
= BUTTON_RIGHT
;
501 new_btn
= BUTTON_DOWN
;
505 new_btn
= BUTTON_PLAY
;
514 new_btn
= BUTTON_SELECT
;
518 new_btn
= BUTTON_MODE
;
521 #elif CONFIG_KEYPAD == ONDIO_PAD
524 new_btn
= BUTTON_LEFT
;
528 new_btn
= BUTTON_RIGHT
;
536 new_btn
= BUTTON_DOWN
;
541 new_btn
= BUTTON_OFF
;
545 new_btn
= BUTTON_MENU
;
548 #elif CONFIG_KEYPAD == PLAYER_PAD
551 new_btn
= BUTTON_LEFT
;
555 new_btn
= BUTTON_RIGHT
;
559 new_btn
= BUTTON_PLAY
;
563 new_btn
= BUTTON_STOP
;
571 new_btn
= BUTTON_MENU
;
574 #elif CONFIG_KEYPAD == RECORDER_PAD
577 new_btn
= BUTTON_LEFT
;
581 new_btn
= BUTTON_RIGHT
;
589 new_btn
= BUTTON_DOWN
;
598 new_btn
= BUTTON_OFF
;
604 case SDLK_KP_MULTIPLY
:
614 new_btn
= BUTTON_PLAY
;
617 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
620 new_btn
= BUTTON_LEFT
;
624 new_btn
= BUTTON_RIGHT
;
632 new_btn
= BUTTON_DOWN
;
641 new_btn
= BUTTON_OFF
;
647 case SDLK_KP_MULTIPLY
:
657 new_btn
= BUTTON_SELECT
;
660 #elif CONFIG_KEYPAD == SANSA_E200_PAD
663 new_btn
= BUTTON_LEFT
;
667 new_btn
= BUTTON_RIGHT
;
671 new_btn
= BUTTON_SCROLL_BACK
;
675 new_btn
= BUTTON_SCROLL_FWD
;
681 new_btn
= BUTTON_DOWN
;
684 new_btn
= BUTTON_POWER
;
687 new_btn
= BUTTON_REC
;
691 new_btn
= BUTTON_SELECT
;
694 #elif CONFIG_KEYPAD == SANSA_C200_PAD
697 new_btn
= BUTTON_LEFT
;
701 new_btn
= BUTTON_RIGHT
;
709 new_btn
= BUTTON_DOWN
;
712 new_btn
= BUTTON_POWER
;
715 new_btn
= BUTTON_REC
;
720 new_btn
= BUTTON_SELECT
;
723 new_btn
= BUTTON_VOL_DOWN
;
726 new_btn
= BUTTON_VOL_UP
;
729 #elif CONFIG_KEYPAD == MROBE500_PAD
731 new_btn
= BUTTON_RC_HEART
;
734 new_btn
= BUTTON_RC_MODE
;
737 new_btn
= BUTTON_RC_VOL_DOWN
;
740 new_btn
= BUTTON_RC_VOL_UP
;
743 new_btn
= BUTTON_LEFT
;
746 new_btn
= BUTTON_RIGHT
;
749 new_btn
= BUTTON_RC_PLAY
;
752 new_btn
= BUTTON_RC_DOWN
;
756 new_btn
= BUTTON_POWER
;
758 #elif CONFIG_KEYPAD == MROBE100_PAD
760 new_btn
= BUTTON_DISPLAY
;
763 new_btn
= BUTTON_MENU
;
766 new_btn
= BUTTON_PLAY
;
770 new_btn
= BUTTON_LEFT
;
774 new_btn
= BUTTON_RIGHT
;
782 new_btn
= BUTTON_DOWN
;
786 new_btn
= BUTTON_SELECT
;
788 case SDLK_KP_MULTIPLY
:
791 new_btn
= BUTTON_POWER
;
794 #elif CONFIG_KEYPAD == COWOND2_PAD
796 new_btn
= BUTTON_POWER
;
799 new_btn
= BUTTON_PLUS
;
802 new_btn
= BUTTON_MINUS
;
805 new_btn
= BUTTON_MENU
;
808 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
810 new_btn
= BUTTON_BACK
;
813 new_btn
= BUTTON_MENU
;
816 new_btn
= BUTTON_CUSTOM
;
819 new_btn
= BUTTON_PLAY
;
823 new_btn
= BUTTON_LEFT
;
827 new_btn
= BUTTON_RIGHT
;
835 new_btn
= BUTTON_DOWN
;
839 new_btn
= BUTTON_SELECT
;
841 case SDLK_KP_MULTIPLY
:
844 new_btn
= BUTTON_POWER
;
846 #elif CONFIG_KEYPAD == CREATIVEZV_PAD
848 new_btn
= BUTTON_PREV
;
851 new_btn
= BUTTON_NEXT
;
854 new_btn
= BUTTON_BACK
;
857 new_btn
= BUTTON_PLAY
;
860 new_btn
= BUTTON_MENU
;
864 new_btn
= BUTTON_LEFT
;
868 new_btn
= BUTTON_RIGHT
;
876 new_btn
= BUTTON_DOWN
;
880 new_btn
= BUTTON_SELECT
;
882 case SDLK_KP_MULTIPLY
:
885 new_btn
= BUTTON_POWER
;
888 new_btn
= BUTTON_VOL_DOWN
;
891 new_btn
= BUTTON_VOL_UP
;
893 #elif CONFIG_KEYPAD == MEIZU_M6SL_PAD
895 new_btn
= BUTTON_PREV
;
898 new_btn
= BUTTON_NEXT
;
903 new_btn
= BUTTON_PLAY
;
907 new_btn
= BUTTON_MENU
;
915 new_btn
= BUTTON_DOWN
;
919 new_btn
= BUTTON_SELECT
;
922 #error No keymap defined!
923 #endif /* CONFIG_KEYPAD */
928 queue_broadcast(SYS_SCREENDUMP
, 0);
939 /* Lots of stuff copied from real button.c. Not good, I think... */
941 /* Find out if a key has been released */
942 diff
= btn
^ lastbtn
;
943 if(diff
&& (btn
& diff
) == 0)
945 #ifdef HAVE_BACKLIGHT
946 #ifdef HAVE_REMOTE_LCD
947 if(diff
& BUTTON_REMOTE
)
948 if(!skip_remote_release
)
949 queue_post(&button_queue
, BUTTON_REL
| diff
, data
);
951 skip_remote_release
= false;
955 queue_post(&button_queue
, BUTTON_REL
| diff
, data
);
957 skip_release
= false;
959 queue_post(&button_queue
, BUTTON_REL
| diff
, data
);
967 /* normal keypress */
968 if ( btn
!= lastbtn
)
972 repeat_speed
= REPEAT_INTERVAL_START
;
984 /* yes we have repeat */
986 if (repeat_speed
< REPEAT_INTERVAL_FINISH
)
987 repeat_speed
= REPEAT_INTERVAL_FINISH
;
988 count
= repeat_speed
;
995 if (count
++ > REPEAT_START
)
1000 /* initial repeat */
1001 count
= REPEAT_INTERVAL_START
;
1009 if (queue_empty(&button_queue
))
1011 queue_post(&button_queue
, BUTTON_REPEAT
| btn
, data
);
1012 #ifdef HAVE_BACKLIGHT
1013 #ifdef HAVE_REMOTE_LCD
1014 if(btn
& BUTTON_REMOTE
)
1016 if(skip_remote_release
)
1017 skip_remote_release
= false;
1022 skip_release
= false;
1029 #ifdef HAVE_BACKLIGHT
1030 #ifdef HAVE_REMOTE_LCD
1031 if (btn
& BUTTON_REMOTE
) {
1032 if (!remote_filter_first_keypress
1033 || is_remote_backlight_on(false))
1034 queue_post(&button_queue
, btn
, data
);
1036 skip_remote_release
= true;
1040 if (!filter_first_keypress
1041 || is_backlight_on(false))
1042 queue_post(&button_queue
, btn
, data
);
1044 skip_release
= true;
1045 #else /* no backlight, nothing to skip */
1046 queue_post(&button_queue
, btn
, data
);
1051 #ifdef HAVE_REMOTE_LCD
1052 if(btn
& BUTTON_REMOTE
)
1053 remote_backlight_on();
1066 lastbtn
= btn
& ~(BUTTON_REL
| BUTTON_REPEAT
);
1069 /* Again copied from real button.c... */
1071 int button_queue_count( void )
1073 return queue_count(&button_queue
);
1076 long button_get(bool block
)
1078 struct queue_event ev
;
1080 if ( block
|| !queue_empty(&button_queue
) ) {
1081 queue_wait(&button_queue
, &ev
);
1082 button_data
= ev
.data
;
1088 long button_get_w_tmo(int ticks
)
1090 struct queue_event ev
;
1091 queue_wait_w_tmo(&button_queue
, &ev
, ticks
);
1092 if (ev
.id
== SYS_TIMEOUT
)
1093 ev
.id
= BUTTON_NONE
;
1095 button_data
= ev
.data
;
1100 intptr_t button_get_data(void)
1102 #ifdef HAVE_TOUCHPAD
1105 /* Needed by the accelerating wheel driver for Sansa e200 */
1110 #ifdef HAVE_TOUCHPAD
1111 extern bool debug_wps
;
1112 void mouse_tick_task(void)
1114 static int last_check
= 0;
1116 if (TIME_BEFORE(current_tick
, last_check
+(HZ
/10)))
1118 last_check
= current_tick
;
1119 if (SDL_GetMouseState(&x
, &y
) & SDL_BUTTON(SDL_BUTTON_LEFT
))
1126 if(x
<0 || y
<0 || x
>UI_LCD_WIDTH
|| y
>UI_LCD_HEIGHT
)
1130 mouse_coords
= (x
<<16)|y
;
1131 button_event(BUTTON_TOUCHPAD
, true);
1133 printf("Mouse at: (%d, %d)\n", x
, y
);
1137 void button_init(void)
1139 #ifdef HAVE_TOUCHPAD
1140 tick_add_task(mouse_tick_task
);
1144 int button_status(void)
1149 void button_clear_queue(void)
1151 queue_clear(&button_queue
);