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"
30 #include "sim_tasks.h"
34 static intptr_t button_data
; /* data value from last message dequeued */
36 #ifdef HAVE_TOUCHSCREEN
37 #include "touchscreen.h"
38 static int mouse_coords
= 0;
39 static int last_touchscreen_touch
= 0xffff;
41 /* how long until repeat kicks in */
42 #define REPEAT_START 6
44 /* the speed repeat starts at */
45 #define REPEAT_INTERVAL_START 4
47 /* speed repeat finishes at */
48 #define REPEAT_INTERVAL_FINISH 2
50 #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
51 int _remote_type
=REMOTETYPE_H100_LCD
;
59 struct event_queue button_queue
;
61 static int btn
= 0; /* Hopefully keeps track of currently pressed keys... */
64 static bool filter_first_keypress
;
66 void set_backlight_filter_keypress(bool value
)
68 filter_first_keypress
= value
;
70 #ifdef HAVE_REMOTE_LCD
71 static bool remote_filter_first_keypress
;
73 void set_remote_backlight_filter_keypress(bool value
)
75 remote_filter_first_keypress
= value
;
80 #ifdef HAS_BUTTON_HOLD
81 bool hold_button_state
= false;
82 bool button_hold(void) {
83 return hold_button_state
;
87 #ifdef HAS_REMOTE_BUTTON_HOLD
88 bool remote_hold_button_state
= false;
89 bool remote_button_hold(void) {
90 return remote_hold_button_state
;
95 void button_event(int key
, bool pressed
)
100 static int count
= 0;
101 static int repeat_speed
= REPEAT_INTERVAL_START
;
102 static int repeat_count
= 0;
103 static bool repeat
= false;
104 static bool post
= false;
105 #ifdef HAVE_BACKLIGHT
106 static bool skip_release
= false;
107 #ifdef HAVE_REMOTE_LCD
108 static bool skip_remote_release
= false;
111 static bool usb_connected
= false;
112 if (usb_connected
&& key
!= SDLK_u
)
117 #ifdef HAVE_TOUCHSCREEN
118 case BUTTON_TOUCHSCREEN
:
120 switch (touchscreen_get_mode())
122 case TOUCHSCREEN_POINT
:
123 new_btn
= BUTTON_TOUCHSCREEN
;
125 case TOUCHSCREEN_BUTTON
:
127 static int touchscreen_buttons
[3][3] = {
128 {BUTTON_TOPLEFT
, BUTTON_TOPMIDDLE
, BUTTON_TOPRIGHT
},
129 {BUTTON_MIDLEFT
, BUTTON_CENTER
, BUTTON_MIDRIGHT
},
130 {BUTTON_BOTTOMLEFT
, BUTTON_BOTTOMMIDDLE
, BUTTON_BOTTOMRIGHT
},
132 int px_x
= ((data
&0xffff0000)>>16), px_y
= ((data
&0x0000ffff));
133 new_btn
= touchscreen_buttons
[px_y
/(LCD_HEIGHT
/3)][px_x
/(LCD_WIDTH
/3)];
139 new_btn
= BUTTON_TOPLEFT
;
142 new_btn
= BUTTON_TOPMIDDLE
;
145 new_btn
= BUTTON_TOPRIGHT
;
148 new_btn
= BUTTON_MIDLEFT
;
151 new_btn
= BUTTON_CENTER
;
154 new_btn
= BUTTON_MIDRIGHT
;
157 new_btn
= BUTTON_BOTTOMLEFT
;
160 new_btn
= BUTTON_BOTTOMMIDDLE
;
163 new_btn
= BUTTON_BOTTOMRIGHT
;
168 touchscreen_set_mode(touchscreen_get_mode() == TOUCHSCREEN_POINT
? TOUCHSCREEN_BUTTON
: TOUCHSCREEN_POINT
);
169 printf("Touchscreen mode: %s\n", touchscreen_get_mode() == TOUCHSCREEN_POINT
? "TOUCHSCREEN_POINT" : "TOUCHSCREEN_BUTTON");
177 usb_connected
= !usb_connected
;
179 queue_post(&button_queue
, SYS_USB_CONNECTED
, 0);
181 queue_post(&button_queue
, SYS_USB_DISCONNECTED
, 0);
185 #ifdef HAS_BUTTON_HOLD
189 hold_button_state
= !hold_button_state
;
190 DEBUGF("Hold button is %s\n", hold_button_state
?"ON":"OFF");
195 #ifdef HAS_REMOTE_BUTTON_HOLD
199 remote_hold_button_state
= !remote_hold_button_state
;
200 DEBUGF("Remote hold button is %s\n",
201 remote_hold_button_state
?"ON":"OFF");
206 #if CONFIG_KEYPAD == GIGABEAT_PAD
209 new_btn
= BUTTON_LEFT
;
213 new_btn
= BUTTON_RIGHT
;
221 new_btn
= BUTTON_DOWN
;
225 new_btn
= BUTTON_POWER
;
228 new_btn
= BUTTON_POWER
;
237 new_btn
= BUTTON_SELECT
;
241 new_btn
= BUTTON_MENU
;
244 new_btn
= BUTTON_VOL_UP
;
247 new_btn
= BUTTON_VOL_DOWN
;
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
;
683 new_btn
= BUTTON_DOWN
;
687 new_btn
= BUTTON_POWER
;
691 new_btn
= BUTTON_REC
;
695 new_btn
= BUTTON_SELECT
;
698 #elif CONFIG_KEYPAD == SANSA_C200_PAD
701 new_btn
= BUTTON_LEFT
;
705 new_btn
= BUTTON_RIGHT
;
713 new_btn
= BUTTON_DOWN
;
716 new_btn
= BUTTON_POWER
;
719 new_btn
= BUTTON_REC
;
724 new_btn
= BUTTON_SELECT
;
727 new_btn
= BUTTON_VOL_DOWN
;
730 new_btn
= BUTTON_VOL_UP
;
733 #elif CONFIG_KEYPAD == MROBE500_PAD
735 new_btn
= BUTTON_RC_HEART
;
738 new_btn
= BUTTON_RC_MODE
;
741 new_btn
= BUTTON_RC_VOL_DOWN
;
744 new_btn
= BUTTON_RC_VOL_UP
;
747 new_btn
= BUTTON_LEFT
;
750 new_btn
= BUTTON_RIGHT
;
753 new_btn
= BUTTON_RC_PLAY
;
756 new_btn
= BUTTON_RC_DOWN
;
760 new_btn
= BUTTON_POWER
;
762 #elif CONFIG_KEYPAD == MROBE100_PAD
764 new_btn
= BUTTON_DISPLAY
;
767 new_btn
= BUTTON_MENU
;
770 new_btn
= BUTTON_PLAY
;
774 new_btn
= BUTTON_LEFT
;
778 new_btn
= BUTTON_RIGHT
;
786 new_btn
= BUTTON_DOWN
;
790 new_btn
= BUTTON_SELECT
;
792 case SDLK_KP_MULTIPLY
:
795 new_btn
= BUTTON_POWER
;
798 #elif CONFIG_KEYPAD == COWOND2_PAD
800 new_btn
= BUTTON_POWER
;
803 new_btn
= BUTTON_PLUS
;
806 new_btn
= BUTTON_MINUS
;
809 new_btn
= BUTTON_MENU
;
811 #elif CONFIG_KEYPAD == IAUDIO67_PAD
813 new_btn
= BUTTON_RIGHT
;
816 new_btn
= BUTTON_LEFT
;
819 new_btn
= BUTTON_STOP
;
824 new_btn
= BUTTON_PLAY
;
827 new_btn
= BUTTON_VOLUP
;
830 new_btn
= BUTTON_VOLDOWN
;
833 new_btn
= BUTTON_MENU
;
836 new_btn
= BUTTON_POWER
;
838 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
840 new_btn
= BUTTON_BACK
;
843 new_btn
= BUTTON_MENU
;
846 new_btn
= BUTTON_CUSTOM
;
849 new_btn
= BUTTON_PLAY
;
853 new_btn
= BUTTON_LEFT
;
857 new_btn
= BUTTON_RIGHT
;
865 new_btn
= BUTTON_DOWN
;
869 new_btn
= BUTTON_SELECT
;
871 case SDLK_KP_MULTIPLY
:
874 new_btn
= BUTTON_POWER
;
876 #elif CONFIG_KEYPAD == CREATIVEZV_PAD
878 new_btn
= BUTTON_PREV
;
881 new_btn
= BUTTON_NEXT
;
884 new_btn
= BUTTON_BACK
;
887 new_btn
= BUTTON_PLAY
;
890 new_btn
= BUTTON_MENU
;
894 new_btn
= BUTTON_LEFT
;
898 new_btn
= BUTTON_RIGHT
;
906 new_btn
= BUTTON_DOWN
;
910 new_btn
= BUTTON_SELECT
;
912 case SDLK_KP_MULTIPLY
:
915 new_btn
= BUTTON_POWER
;
918 new_btn
= BUTTON_VOL_DOWN
;
921 new_btn
= BUTTON_VOL_UP
;
923 #elif CONFIG_KEYPAD == MEIZU_M6SL_PAD
925 new_btn
= BUTTON_PREV
;
928 new_btn
= BUTTON_NEXT
;
933 new_btn
= BUTTON_PLAY
;
937 new_btn
= BUTTON_MENU
;
945 new_btn
= BUTTON_DOWN
;
949 new_btn
= BUTTON_SELECT
;
951 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
954 new_btn
= BUTTON_LEFT
;
958 new_btn
= BUTTON_RIGHT
;
962 new_btn
= BUTTON_SCROLL_BACK
;
966 new_btn
= BUTTON_SCROLL_FWD
;
974 new_btn
= BUTTON_DOWN
;
977 new_btn
= BUTTON_POWER
;
979 case SDLK_KP_MULTIPLY
:
980 new_btn
= BUTTON_HOME
;
986 new_btn
= BUTTON_SELECT
;
988 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
991 new_btn
= BUTTON_LEFT
;
995 new_btn
= BUTTON_RIGHT
;
1003 new_btn
= BUTTON_DOWN
;
1006 new_btn
= BUTTON_HOME
;
1009 new_btn
= BUTTON_SELECT
;
1012 new_btn
= BUTTON_VOL_DOWN
;
1015 new_btn
= BUTTON_VOL_UP
;
1019 new_btn
= BUTTON_POWER
;
1021 #elif CONFIG_KEYPAD == SANSA_M200_PAD
1024 new_btn
= BUTTON_LEFT
;
1028 new_btn
= BUTTON_RIGHT
;
1032 new_btn
= BUTTON_UP
;
1036 new_btn
= BUTTON_DOWN
;
1039 new_btn
= BUTTON_POWER
;
1042 new_btn
= BUTTON_SELECT
;
1045 new_btn
= BUTTON_VOL_DOWN
;
1048 new_btn
= BUTTON_VOL_UP
;
1051 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
1054 new_btn
= BUTTON_LEFT
;
1058 new_btn
= BUTTON_RIGHT
;
1062 new_btn
= BUTTON_UP
;
1066 new_btn
= BUTTON_DOWN
;
1070 new_btn
= BUTTON_SELECT
;
1074 new_btn
= BUTTON_POWER
;
1077 new_btn
= BUTTON_PLAYLIST
;
1080 new_btn
= BUTTON_VOL_UP
;
1083 new_btn
= BUTTON_VOL_DOWN
;
1086 new_btn
= BUTTON_MENU
;
1089 new_btn
= BUTTON_VIEW
;
1091 #elif CONFIG_KEYPAD == ONDAVX747_PAD
1093 new_btn
= BUTTON_POWER
;
1096 new_btn
= BUTTON_VOL_UP
;
1099 new_btn
= BUTTON_VOL_DOWN
;
1102 new_btn
= BUTTON_MENU
;
1105 #error No keymap defined!
1106 #endif /* CONFIG_KEYPAD */
1111 sim_trigger_screendump();
1122 /* Lots of stuff copied from real button.c. Not good, I think... */
1124 /* Find out if a key has been released */
1125 diff
= btn
^ lastbtn
;
1126 if(diff
&& (btn
& diff
) == 0)
1128 #ifdef HAVE_BACKLIGHT
1129 #ifdef HAVE_REMOTE_LCD
1130 if(diff
& BUTTON_REMOTE
)
1131 if(!skip_remote_release
)
1132 queue_post(&button_queue
, BUTTON_REL
| diff
, data
);
1134 skip_remote_release
= false;
1138 queue_post(&button_queue
, BUTTON_REL
| diff
, data
);
1140 skip_release
= false;
1142 queue_post(&button_queue
, BUTTON_REL
| diff
, data
);
1150 /* normal keypress */
1151 if ( btn
!= lastbtn
)
1155 repeat_speed
= REPEAT_INTERVAL_START
;
1167 /* yes we have repeat */
1169 if (repeat_speed
< REPEAT_INTERVAL_FINISH
)
1170 repeat_speed
= REPEAT_INTERVAL_FINISH
;
1171 count
= repeat_speed
;
1178 if (count
++ > REPEAT_START
)
1183 /* initial repeat */
1184 count
= REPEAT_INTERVAL_START
;
1192 if (queue_empty(&button_queue
))
1194 queue_post(&button_queue
, BUTTON_REPEAT
| btn
, data
);
1195 #ifdef HAVE_BACKLIGHT
1196 #ifdef HAVE_REMOTE_LCD
1197 if(btn
& BUTTON_REMOTE
)
1199 if(skip_remote_release
)
1200 skip_remote_release
= false;
1205 skip_release
= false;
1212 #ifdef HAVE_BACKLIGHT
1213 #ifdef HAVE_REMOTE_LCD
1214 if (btn
& BUTTON_REMOTE
) {
1215 if (!remote_filter_first_keypress
1216 || is_remote_backlight_on(false))
1217 queue_post(&button_queue
, btn
, data
);
1219 skip_remote_release
= true;
1223 if (!filter_first_keypress
1224 || is_backlight_on(false))
1225 queue_post(&button_queue
, btn
, data
);
1227 skip_release
= true;
1228 #else /* no backlight, nothing to skip */
1229 queue_post(&button_queue
, btn
, data
);
1234 #ifdef HAVE_REMOTE_LCD
1235 if(btn
& BUTTON_REMOTE
)
1236 remote_backlight_on();
1249 lastbtn
= btn
& ~(BUTTON_REL
| BUTTON_REPEAT
);
1252 /* Again copied from real button.c... */
1254 int button_queue_count( void )
1256 return queue_count(&button_queue
);
1259 long button_get(bool block
)
1261 struct queue_event ev
;
1263 if ( block
|| !queue_empty(&button_queue
) ) {
1264 queue_wait(&button_queue
, &ev
);
1265 button_data
= ev
.data
;
1271 long button_get_w_tmo(int ticks
)
1273 struct queue_event ev
;
1274 queue_wait_w_tmo(&button_queue
, &ev
, ticks
);
1275 if (ev
.id
== SYS_TIMEOUT
)
1276 ev
.id
= BUTTON_NONE
;
1278 button_data
= ev
.data
;
1283 intptr_t button_get_data(void)
1285 #ifdef HAVE_TOUCHSCREEN
1288 /* Needed by the accelerating wheel driver for Sansa e200 */
1293 #ifdef HAVE_TOUCHSCREEN
1294 extern bool debug_wps
;
1295 void mouse_tick_task(void)
1297 static int last_check
= 0;
1299 if (TIME_BEFORE(current_tick
, last_check
+(HZ
/10)))
1301 last_check
= current_tick
;
1302 if (SDL_GetMouseState(&x
, &y
) & SDL_BUTTON(SDL_BUTTON_LEFT
))
1309 if(x
<0 || y
<0 || x
>SIM_LCD_WIDTH
|| y
>SIM_LCD_HEIGHT
)
1313 mouse_coords
= (x
<<16)|y
;
1314 last_touchscreen_touch
= current_tick
;
1315 button_event(BUTTON_TOUCHSCREEN
, true);
1317 printf("Mouse at: (%d, %d)\n", x
, y
);
1320 int touchscreen_last_touch(void)
1322 return last_touchscreen_touch
;
1325 void button_init(void)
1327 #ifdef HAVE_TOUCHSCREEN
1328 tick_add_task(mouse_tick_task
);
1332 int button_status(void)
1337 void button_clear_queue(void)
1339 queue_clear(&button_queue
);