diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/button.c | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 0d0d1cd7ad..f87128adf8 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c | |||
@@ -38,19 +38,10 @@ | |||
38 | #else | 38 | #else |
39 | #include "button-target.h" | 39 | #include "button-target.h" |
40 | #endif | 40 | #endif |
41 | |||
42 | #ifdef HAVE_REMOTE_LCD | 41 | #ifdef HAVE_REMOTE_LCD |
43 | #include "lcd-remote.h" | 42 | #include "lcd-remote.h" |
44 | #endif | 43 | #endif |
45 | 44 | ||
46 | #if 0 | ||
47 | /* Older than MAX_EVENT_AGE button events are going to be ignored. | ||
48 | * Used to prevent for example volume going up uncontrollable when events | ||
49 | * are getting queued and UI is lagging too much. | ||
50 | */ | ||
51 | #define MAX_EVENT_AGE HZ | ||
52 | #endif | ||
53 | |||
54 | struct event_queue button_queue; | 45 | struct event_queue button_queue; |
55 | 46 | ||
56 | static long lastbtn; /* Last valid button status */ | 47 | static long lastbtn; /* Last valid button status */ |
@@ -72,11 +63,27 @@ static bool phones_present = false; | |||
72 | /* how long until repeat kicks in, in centiseconds */ | 63 | /* how long until repeat kicks in, in centiseconds */ |
73 | #define REPEAT_START (30*HZ/100) | 64 | #define REPEAT_START (30*HZ/100) |
74 | 65 | ||
66 | #ifndef HAVE_TOUCHSCREEN | ||
67 | /* the next two make repeat "accelerate", which is nice for lists | ||
68 | * which begin to scroll a bit faster when holding until the | ||
69 | * real list accerelation kicks in (this smoothes acceleration) | ||
70 | */ | ||
71 | |||
75 | /* the speed repeat starts at, in centiseconds */ | 72 | /* the speed repeat starts at, in centiseconds */ |
76 | #define REPEAT_INTERVAL_START (16*HZ/100) | 73 | #define REPEAT_INTERVAL_START (16*HZ/100) |
77 | |||
78 | /* speed repeat finishes at, in centiseconds */ | 74 | /* speed repeat finishes at, in centiseconds */ |
79 | #define REPEAT_INTERVAL_FINISH (5*HZ/100) | 75 | #define REPEAT_INTERVAL_FINISH (5*HZ/100) |
76 | #else | ||
77 | /* | ||
78 | * on touchscreen it's different, scrolling is done by swiping over the | ||
79 | * screen (potentially very quickly) and is completely different from button | ||
80 | * targets | ||
81 | * So, on touchscreen we don't want to artifically slow down early repeats, | ||
82 | * it'd have the contrary effect of making rockbox appear lagging | ||
83 | */ | ||
84 | #define REPEAT_INTERVAL_START (3*HZ/100) | ||
85 | #define REPEAT_INTERVAL_FINISH (3*HZ/100) | ||
86 | #endif | ||
80 | 87 | ||
81 | #ifdef HAVE_BUTTON_DATA | 88 | #ifdef HAVE_BUTTON_DATA |
82 | static int button_read(int *data); | 89 | static int button_read(int *data); |
@@ -102,6 +109,35 @@ static int btn_detect_callback(struct timeout *tmo) | |||
102 | } | 109 | } |
103 | #endif | 110 | #endif |
104 | 111 | ||
112 | static bool button_try_post(int button, int data) | ||
113 | { | ||
114 | #ifdef HAVE_TOUCHSCREEN | ||
115 | /* one can swipe over the scren very quickly, | ||
116 | * for this to work we want to forget about old presses and | ||
117 | * only respect the very latest ones */ | ||
118 | const int force_post = true; | ||
119 | #else | ||
120 | /* Only post events if the queue is empty, | ||
121 | * to avoid afterscroll effects. | ||
122 | * i.e. don't post new buttons if previous ones haven't been | ||
123 | * processed yet */ | ||
124 | const int force_post = false; | ||
125 | #endif | ||
126 | |||
127 | bool ret = queue_empty(&button_queue); | ||
128 | if (!ret && force_post) | ||
129 | { | ||
130 | queue_remove_from_head(&button_queue, button); | ||
131 | ret = true; | ||
132 | } | ||
133 | |||
134 | if (ret) | ||
135 | queue_post(&button_queue, button, data); | ||
136 | |||
137 | /* on touchscreen we posted unconditionally */ | ||
138 | return ret; | ||
139 | } | ||
140 | |||
105 | static void button_tick(void) | 141 | static void button_tick(void) |
106 | { | 142 | { |
107 | static int count = 0; | 143 | static int count = 0; |
@@ -127,9 +163,7 @@ static void button_tick(void) | |||
127 | /* Post events for the remote control */ | 163 | /* Post events for the remote control */ |
128 | btn = remote_control_rx(); | 164 | btn = remote_control_rx(); |
129 | if(btn) | 165 | if(btn) |
130 | { | 166 | button_try_post(btn, 0); |
131 | queue_post(&button_queue, btn, 0); | ||
132 | } | ||
133 | #endif | 167 | #endif |
134 | 168 | ||
135 | #ifdef HAVE_BUTTON_DATA | 169 | #ifdef HAVE_BUTTON_DATA |
@@ -137,7 +171,6 @@ static void button_tick(void) | |||
137 | #else | 171 | #else |
138 | btn = button_read(); | 172 | btn = button_read(); |
139 | #endif | 173 | #endif |
140 | |||
141 | #if defined(HAVE_HEADPHONE_DETECTION) | 174 | #if defined(HAVE_HEADPHONE_DETECTION) |
142 | if (headphones_inserted() != phones_present) | 175 | if (headphones_inserted() != phones_present) |
143 | { | 176 | { |
@@ -156,17 +189,17 @@ static void button_tick(void) | |||
156 | #ifdef HAVE_REMOTE_LCD | 189 | #ifdef HAVE_REMOTE_LCD |
157 | if(diff & BUTTON_REMOTE) | 190 | if(diff & BUTTON_REMOTE) |
158 | if(!skip_remote_release) | 191 | if(!skip_remote_release) |
159 | queue_post(&button_queue, BUTTON_REL | diff, data); | 192 | button_try_post(BUTTON_REL | diff, data); |
160 | else | 193 | else |
161 | skip_remote_release = false; | 194 | skip_remote_release = false; |
162 | else | 195 | else |
163 | #endif | 196 | #endif |
164 | if(!skip_release) | 197 | if(!skip_release) |
165 | queue_post(&button_queue, BUTTON_REL | diff, data); | 198 | button_try_post(BUTTON_REL | diff, data); |
166 | else | 199 | else |
167 | skip_release = false; | 200 | skip_release = false; |
168 | #else | 201 | #else |
169 | queue_post(&button_queue, BUTTON_REL | diff, data); | 202 | button_try_post(BUTTON_REL | diff, data); |
170 | #endif | 203 | #endif |
171 | } | 204 | } |
172 | else | 205 | else |
@@ -233,6 +266,13 @@ static void button_tick(void) | |||
233 | /* initial repeat */ | 266 | /* initial repeat */ |
234 | count = REPEAT_INTERVAL_START; | 267 | count = REPEAT_INTERVAL_START; |
235 | } | 268 | } |
269 | #ifdef HAVE_TOUCHSCREEN | ||
270 | else if (lastdata != data && btn == lastbtn) | ||
271 | { /* only coordinates changed, post anyway */ | ||
272 | if (touchscreen_get_mode() == TOUCHSCREEN_POINT) | ||
273 | post = true; | ||
274 | } | ||
275 | #endif | ||
236 | } | 276 | } |
237 | } | 277 | } |
238 | if ( post ) | 278 | if ( post ) |
@@ -241,9 +281,8 @@ static void button_tick(void) | |||
241 | { | 281 | { |
242 | /* Only post repeat events if the queue is empty, | 282 | /* Only post repeat events if the queue is empty, |
243 | * to avoid afterscroll effects. */ | 283 | * to avoid afterscroll effects. */ |
244 | if (queue_empty(&button_queue)) | 284 | if (button_try_post(BUTTON_REPEAT | btn, data)) |
245 | { | 285 | { |
246 | queue_post(&button_queue, BUTTON_REPEAT | btn, data); | ||
247 | #ifdef HAVE_BACKLIGHT | 286 | #ifdef HAVE_BACKLIGHT |
248 | #ifdef HAVE_REMOTE_LCD | 287 | #ifdef HAVE_REMOTE_LCD |
249 | skip_remote_release = false; | 288 | skip_remote_release = false; |
@@ -264,7 +303,7 @@ static void button_tick(void) | |||
264 | || (remote_type()==REMOTETYPE_H300_NONLCD) | 303 | || (remote_type()==REMOTETYPE_H300_NONLCD) |
265 | #endif | 304 | #endif |
266 | ) | 305 | ) |
267 | queue_post(&button_queue, btn, data); | 306 | button_try_post(btn, data); |
268 | else | 307 | else |
269 | skip_remote_release = true; | 308 | skip_remote_release = true; |
270 | } | 309 | } |
@@ -275,11 +314,11 @@ static void button_tick(void) | |||
275 | || (btn & BUTTON_REMOTE) | 314 | || (btn & BUTTON_REMOTE) |
276 | #endif | 315 | #endif |
277 | ) | 316 | ) |
278 | queue_post(&button_queue, btn, data); | 317 | button_try_post(btn, data); |
279 | else | 318 | else |
280 | skip_release = true; | 319 | skip_release = true; |
281 | #else /* no backlight, nothing to skip */ | 320 | #else /* no backlight, nothing to skip */ |
282 | queue_post(&button_queue, btn, data); | 321 | button_try_post(btn, data); |
283 | #endif | 322 | #endif |
284 | post = false; | 323 | post = false; |
285 | } | 324 | } |
@@ -350,12 +389,6 @@ long button_get(bool block) | |||
350 | { | 389 | { |
351 | queue_wait(&button_queue, &ev); | 390 | queue_wait(&button_queue, &ev); |
352 | 391 | ||
353 | #if 0 | ||
354 | /* Ignore if the event was too old and for simplicity, just | ||
355 | * wait for a new button_get() request. */ | ||
356 | if (current_tick - ev.tick > MAX_EVENT_AGE) | ||
357 | return BUTTON_NONE; | ||
358 | #endif | ||
359 | button_data = ev.data; | 392 | button_data = ev.data; |
360 | return ev.id; | 393 | return ev.id; |
361 | } | 394 | } |