diff options
author | Thomas Martitz <kugel@rockbox.org> | 2010-09-22 23:01:51 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2010-09-22 23:01:51 +0000 |
commit | 54a81076bcca1da13673526b57e9c2fc3e807ae7 (patch) | |
tree | bf92493a055937f661f58d230afed5db906b0381 /firmware/drivers | |
parent | 7f9e76556d2e21d36d7ba906ebd4adc6915fccee (diff) | |
download | rockbox-54a81076bcca1da13673526b57e9c2fc3e807ae7.tar.gz rockbox-54a81076bcca1da13673526b57e9c2fc3e807ae7.zip |
Touchscreen: button driver improvements
* Until BUTTON_REPEAT was started, coordinate changes were not exposed. Change
that (post on every coordinate change) so that wiping over the screen does actually
something between the first touch and BUTTON_REPEAT
* Once BUTTON_REPEAT is active, further repeats are posted in an acceleration
fashion (slow at the begginning), which smoothes list scrolling. But this has
the contrary effect on touchscreen, as it makes swiping appear very laggy. So,
remove that acceleration for touchscreen and make it equally fast at all times
so the scrollbar is better usable.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28143 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-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 | } |