blob: 673f71ea7b9affaad9dd97bef1756c59564a12c7 [file] [log] [blame]
Björn Stenbergc7dd78e2002-04-19 14:12:31 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
Jens Arnold74b731e2005-03-18 23:51:52 +000019#include <stdlib.h>
Björn Stenberg8b695042004-09-16 14:36:08 +000020#include "config.h"
Björn Stenbergc7dd78e2002-04-19 14:12:31 +000021#include "button.h"
Daniel Stenberg132a09b2002-05-28 15:05:16 +000022#include "kernel.h"
Daniel Stenbergeae51102003-04-23 18:49:57 +000023#include "debug.h"
Jens Arnoldb51f7df2005-11-21 23:55:39 +000024#include "backlight.h"
Linus Nielsen Feltzinga8dab4c2004-06-30 13:31:14 +000025#include "misc.h"
Björn Stenbergc7dd78e2002-04-19 14:12:31 +000026
27#include "X11/keysym.h"
28
Jens Arnold74b731e2005-03-18 23:51:52 +000029extern int screenhack_handle_events(bool *release);
30
31struct event_queue button_queue;
32
33static int button_state = 0; /* keeps track of pressed keys */
34static long lastbtn; /* Last valid button status */
35
36/* how often we check to see if a button is pressed */
37#define POLL_FREQUENCY HZ/25
38
39/* how long until repeat kicks in */
40#define REPEAT_START 8
41
42/* the speed repeat starts at */
43#define REPEAT_INTERVAL_START 4
44
45/* speed repeat finishes at */
46#define REPEAT_INTERVAL_FINISH 2
47
48/* mostly copied from real button.c */
49void button_read (void);
50
Jens Arnoldb51f7df2005-11-21 23:55:39 +000051static void button_tick(void)
Björn Stenbergc7dd78e2002-04-19 14:12:31 +000052{
Jens Arnold74b731e2005-03-18 23:51:52 +000053 static int tick = 0;
54 static int count = 0;
55 static int repeat_speed = REPEAT_INTERVAL_START;
56 static int repeat_count = 0;
57 static bool repeat = false;
Jens Arnold237d3c42006-02-19 13:34:12 +000058 static bool post = false;
Jens Arnold74b731e2005-03-18 23:51:52 +000059 int diff;
60 int btn;
61
62 /* only poll every X ticks */
63 if ( ++tick >= POLL_FREQUENCY )
64 {
Jens Arnold74b731e2005-03-18 23:51:52 +000065 button_read();
66 btn = button_state;
67
68 /* Find out if a key has been released */
69 diff = btn ^ lastbtn;
70 if(diff && (btn & diff) == 0)
71 {
72 queue_post(&button_queue, BUTTON_REL | diff, NULL);
73 }
74 else
75 {
76 if ( btn )
77 {
78 /* normal keypress */
79 if ( btn != lastbtn )
80 {
81 post = true;
82 repeat = false;
83 repeat_speed = REPEAT_INTERVAL_START;
84
85 }
86 else /* repeat? */
87 {
88 if ( repeat )
89 {
90 count--;
91 if (count == 0) {
92 post = true;
93 /* yes we have repeat */
94 repeat_speed--;
95 if (repeat_speed < REPEAT_INTERVAL_FINISH)
96 repeat_speed = REPEAT_INTERVAL_FINISH;
97 count = repeat_speed;
98
99 repeat_count++;
100
101 }
102 }
103 else
104 {
105 if (count++ > REPEAT_START)
106 {
107 post = true;
108 repeat = true;
109 repeat_count = 0;
110 /* initial repeat */
111 count = REPEAT_INTERVAL_START;
112 }
113 }
114 }
115 if ( post )
116 {
117 if (repeat)
Jens Arnold237d3c42006-02-19 13:34:12 +0000118 {
119 if (queue_empty(&button_queue))
120 {
121 queue_post(&button_queue, BUTTON_REPEAT | btn, NULL);
122 post = false;
123 }
124 }
Jens Arnold74b731e2005-03-18 23:51:52 +0000125 else
Jens Arnold237d3c42006-02-19 13:34:12 +0000126 {
Jens Arnold74b731e2005-03-18 23:51:52 +0000127 queue_post(&button_queue, btn, NULL);
Jens Arnold237d3c42006-02-19 13:34:12 +0000128 post = false;
129 }
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000130#ifdef HAVE_REMOTE_LCD
131 if(btn & BUTTON_REMOTE)
132 remote_backlight_on();
133 else
134#endif
135 backlight_on();
136
Jens Arnold74b731e2005-03-18 23:51:52 +0000137 }
138 }
139 else
140 {
141 repeat = false;
142 count = 0;
143 }
144 }
145 lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
146 tick = 0;
147 }
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000148}
149
150/*
Jens Arnold74b731e2005-03-18 23:51:52 +0000151 * Read X keys and translate to rockbox buttons
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000152 */
Daniel Stenberged6c7e42002-06-14 11:00:13 +0000153
Jens Arnold74b731e2005-03-18 23:51:52 +0000154void button_read (void)
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000155{
Björn Stenberg9af59722002-08-21 14:13:53 +0000156 int k;
Jens Arnold74b731e2005-03-18 23:51:52 +0000157 bool release = false; /* is this a release event */
158 int ev = screenhack_handle_events(&release);
159
160 switch (ev)
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000161 {
Jens Arnold31b28f52005-03-18 00:03:22 +0000162 case XK_KP_Left:
163 case XK_Left:
164 case XK_KP_4:
165 k = BUTTON_LEFT;
Björn Stenberg9af59722002-08-21 14:13:53 +0000166 break;
Björn Stenberg45e94942002-04-19 14:38:28 +0000167
Jens Arnold31b28f52005-03-18 00:03:22 +0000168 case XK_KP_Right:
169 case XK_Right:
170 case XK_KP_6:
171 k = BUTTON_RIGHT;
Björn Stenberg9af59722002-08-21 14:13:53 +0000172 break;
Björn Stenberg45e94942002-04-19 14:38:28 +0000173
Jens Arnold31b28f52005-03-18 00:03:22 +0000174 case XK_KP_Up:
175 case XK_Up:
176 case XK_KP_8:
Björn Stenberg6c33c512004-09-19 21:58:37 +0000177#ifdef BUTTON_UP
Jens Arnold31b28f52005-03-18 00:03:22 +0000178 k = BUTTON_UP;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000179#elif defined BUTTON_PLAY
Jens Arnold31b28f52005-03-18 00:03:22 +0000180 k = BUTTON_PLAY;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000181#endif
Björn Stenberg9af59722002-08-21 14:13:53 +0000182 break;
Björn Stenberg45e94942002-04-19 14:38:28 +0000183
Jens Arnold31b28f52005-03-18 00:03:22 +0000184 case XK_KP_Down:
185 case XK_Down:
186 case XK_KP_2:
Björn Stenberg6c33c512004-09-19 21:58:37 +0000187#ifdef BUTTON_DOWN
Jens Arnold31b28f52005-03-18 00:03:22 +0000188 k = BUTTON_DOWN;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000189#elif defined BUTTON_STOP
Jens Arnold31b28f52005-03-18 00:03:22 +0000190 k = BUTTON_STOP;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000191#endif
Björn Stenberg9af59722002-08-21 14:13:53 +0000192 break;
Björn Stenberg45e94942002-04-19 14:38:28 +0000193
Jens Arnolde6f403f2005-01-17 21:14:34 +0000194#ifdef BUTTON_ON
Jens Arnold31b28f52005-03-18 00:03:22 +0000195 case XK_KP_Add:
196 case XK_Q:
197 case XK_q:
198 k = BUTTON_ON;
Björn Stenberg9af59722002-08-21 14:13:53 +0000199 break;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000200#endif
Björn Stenberg45e94942002-04-19 14:38:28 +0000201
Björn Stenberg6c33c512004-09-19 21:58:37 +0000202#ifdef BUTTON_OFF
Jens Arnold31b28f52005-03-18 00:03:22 +0000203 case XK_KP_Enter:
204 case XK_A:
205 case XK_a:
206 k = BUTTON_OFF;
Björn Stenberg9af59722002-08-21 14:13:53 +0000207 break;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000208#endif
Björn Stenberg45e94942002-04-19 14:38:28 +0000209
Björn Stenberg6c33c512004-09-19 21:58:37 +0000210#ifdef BUTTON_F1
Jens Arnold31b28f52005-03-18 00:03:22 +0000211 case XK_KP_Divide:
212 case XK_1:
213 k = BUTTON_F1;
Björn Stenberg9af59722002-08-21 14:13:53 +0000214 break;
Björn Stenberg45e94942002-04-19 14:38:28 +0000215
Jens Arnold31b28f52005-03-18 00:03:22 +0000216 case XK_KP_Multiply:
217 case XK_2:
218 k = BUTTON_F2;
Björn Stenberg9af59722002-08-21 14:13:53 +0000219 break;
Björn Stenberg45e94942002-04-19 14:38:28 +0000220
Jens Arnold31b28f52005-03-18 00:03:22 +0000221 case XK_KP_Subtract:
222 case XK_3:
223 k = BUTTON_F3;
Björn Stenberg9af59722002-08-21 14:13:53 +0000224 break;
Jens Arnolde6f403f2005-01-17 21:14:34 +0000225#elif defined(BUTTON_REC)
Jens Arnold31b28f52005-03-18 00:03:22 +0000226 case XK_KP_Divide:
227 case XK_1:
228 k = BUTTON_REC;
229 break;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000230#endif
Linus Nielsen Feltzinga8dab4c2004-06-30 13:31:14 +0000231
Jens Arnold31b28f52005-03-18 00:03:22 +0000232 case XK_KP_Space:
233 case XK_KP_5:
234 case XK_KP_Begin:
235 case XK_space:
Jens Arnolde6f403f2005-01-17 21:14:34 +0000236#ifdef BUTTON_PLAY
Jens Arnold31b28f52005-03-18 00:03:22 +0000237 k = BUTTON_PLAY;
Jens Arnolde6f403f2005-01-17 21:14:34 +0000238#elif defined(BUTTON_SELECT)
Jens Arnold31b28f52005-03-18 00:03:22 +0000239 k = BUTTON_SELECT;
Jens Arnolde6f403f2005-01-17 21:14:34 +0000240#endif
241 break;
242
Björn Stenberg6c33c512004-09-19 21:58:37 +0000243#ifdef HAVE_LCD_BITMAP
Jens Arnold31b28f52005-03-18 00:03:22 +0000244 case XK_5:
245 if(!release)
Jens Arnold31b28f52005-03-18 00:03:22 +0000246 screen_dump();
Jens Arnold31b28f52005-03-18 00:03:22 +0000247 break;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000248#endif
Linus Nielsen Feltzinga8dab4c2004-06-30 13:31:14 +0000249
Jens Arnold31b28f52005-03-18 00:03:22 +0000250 case XK_KP_Separator:
251 case XK_KP_Insert:
252 case XK_Insert:
Björn Stenberg6c33c512004-09-19 21:58:37 +0000253#ifdef BUTTON_MENU
Jens Arnold31b28f52005-03-18 00:03:22 +0000254 k = BUTTON_MENU;
Jens Arnolde6f403f2005-01-17 21:14:34 +0000255#elif defined(BUTTON_MODE)
Jens Arnold31b28f52005-03-18 00:03:22 +0000256 k = BUTTON_MODE;
Björn Stenberg6c33c512004-09-19 21:58:37 +0000257#endif
Björn Stenberg9af59722002-08-21 14:13:53 +0000258 break;
Björn Stenberg45e94942002-04-19 14:38:28 +0000259
Jens Arnold31b28f52005-03-18 00:03:22 +0000260 default:
261 k = 0;
Daniel Stenbergeae51102003-04-23 18:49:57 +0000262 if(ev)
263 DEBUGF("received ev %d\n", ev);
Björn Stenberg9af59722002-08-21 14:13:53 +0000264 break;
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000265 }
Björn Stenberg9af59722002-08-21 14:13:53 +0000266
Jens Arnold74b731e2005-03-18 23:51:52 +0000267 if (release)
Linus Nielsen Feltzing15d04fd2004-07-23 21:38:43 +0000268 button_state &= ~k;
Jens Arnold74b731e2005-03-18 23:51:52 +0000269 else
270 button_state |= k;
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000271}
272
Jens Arnold74b731e2005-03-18 23:51:52 +0000273/* Again copied from real button.c... */
Daniel Stenberga398aa42002-08-07 08:43:55 +0000274
Jean-Philippe Bernardy58046642005-02-07 23:11:20 +0000275long button_get(bool block)
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000276{
Jens Arnold74b731e2005-03-18 23:51:52 +0000277 struct event ev;
Daniel Stenberg132a09b2002-05-28 15:05:16 +0000278
Jens Arnold74b731e2005-03-18 23:51:52 +0000279 if ( block || !queue_empty(&button_queue) )
280 {
281 queue_wait(&button_queue, &ev);
282 return ev.id;
283 }
284 return BUTTON_NONE;
285}
Daniel Stenbergea604362002-10-13 14:16:44 +0000286
Jens Arnold74b731e2005-03-18 23:51:52 +0000287long button_get_w_tmo(int ticks)
288{
289 struct event ev;
290 queue_wait_w_tmo(&button_queue, &ev, ticks);
291 return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
292}
293
294void button_init(void)
295{
Jens Arnoldb51f7df2005-11-21 23:55:39 +0000296 tick_add_task(button_tick);
Björn Stenbergc7dd78e2002-04-19 14:12:31 +0000297}
Linus Nielsen Feltzinga754dd82004-07-21 08:02:23 +0000298
299int button_status(void)
300{
Jens Arnold74b731e2005-03-18 23:51:52 +0000301 return lastbtn;
Linus Nielsen Feltzinga754dd82004-07-21 08:02:23 +0000302}
303
304void button_clear_queue(void)
305{
Jens Arnold74b731e2005-03-18 23:51:52 +0000306 queue_clear(&button_queue);
Linus Nielsen Feltzinga754dd82004-07-21 08:02:23 +0000307}
Michiel Van Der Kolkabacb232005-03-03 15:55:11 +0000308
Kevin Ferrarea3766bf2005-11-22 22:52:05 +0000309#ifdef HAS_BUTTON_HOLD
Michiel Van Der Kolkabacb232005-03-03 15:55:11 +0000310bool button_hold(void) {
311 /* temp fix for hold button on irivers */
Linus Nielsen Feltzinga81f4c32005-08-21 19:56:49 +0000312 return false;
313}
Kevin Ferrarea3766bf2005-11-22 22:52:05 +0000314#endif
315
316#ifdef HAS_REMOTE_BUTTON_HOLD
Linus Nielsen Feltzinga81f4c32005-08-21 19:56:49 +0000317bool remote_button_hold(void) {
318 /* temp fix for hold button on irivers */
319 return false;
Michiel Van Der Kolkabacb232005-03-03 15:55:11 +0000320}
321#endif