summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2009-04-20 01:41:56 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2009-04-20 01:41:56 +0000
commit0eb5dc649f34ca136d0160bf5d43961a2c3cea05 (patch)
tree5082fcd0d0479979a51891e082e742e2cf769266
parent88b509b7d258c820f2eeda513524acbf76dcaaf5 (diff)
downloadrockbox-0eb5dc649f34ca136d0160bf5d43961a2c3cea05.tar.gz
rockbox-0eb5dc649f34ca136d0160bf5d43961a2c3cea05.zip
beginings of a working touchscreen interface for the WPS. 2 new tags:
%T|x|y|width|height|action| <- setup a region (relative to the current viewport) where if pressed the "action" will be done (currently play/stop/prev/next/menu/browse work, suggestions for others to add and better names welcome) %Tl<timeout> <- used as a conditional to say if the touchscreen was touched in the last <timeout>, use this to enable/disable button viewports or something... same syntax as other timeout tags cabbiev2 for the mr500 has been modified to demonstrate the new tags. press the pause/play button to pause playback. press the rockbox logo to get back to the menu. pretty icons needed to make this more usable :) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20753 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/gwps-common.c7
-rw-r--r--apps/gui/gwps.c37
-rw-r--r--apps/gui/gwps.h19
-rw-r--r--apps/gui/wps_parser.c86
-rw-r--r--firmware/drivers/button.c19
-rw-r--r--firmware/export/button.h2
-rw-r--r--uisimulator/sdl/button.c6
-rw-r--r--wps/cabbiev2.320x240x16.mrobe500.wps47
8 files changed, 215 insertions, 8 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index 5ab0097b2c..1fef9e02cb 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -1292,6 +1292,13 @@ static const char *get_token_value(struct gui_wps *gwps,
1292 token->value.i * TIMEOUT_UNIT)) 1292 token->value.i * TIMEOUT_UNIT))
1293 return "v"; 1293 return "v";
1294 return NULL; 1294 return NULL;
1295 case WPS_TOKEN_LASTTOUCH:
1296#ifdef HAVE_TOUCHSCREEN
1297 if (TIME_BEFORE(current_tick, token->value.i * TIMEOUT_UNIT +
1298 touchscreen_last_touch()))
1299 return "t";
1300#endif
1301 return NULL;
1295 1302
1296 case WPS_TOKEN_SETTING: 1303 case WPS_TOKEN_SETTING:
1297 { 1304 {
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 0c8a3aa2b1..26b531e332 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -293,7 +293,38 @@ void gwps_draw_statusbars(void)
293{ 293{
294 viewportmanager_set_statusbar(wpsbars); 294 viewportmanager_set_statusbar(wpsbars);
295} 295}
296 296#ifdef HAVE_TOUCHSCREEN
297static int wps_get_touchaction(struct wps_data *data)
298{
299 short x,y;
300 short vx, vy;
301 int type = action_get_touchscreen_press(&x, &y);
302 int i;
303 struct touchregion *r;
304 if (type != BUTTON_REL)
305 return ACTION_TOUCHSCREEN;
306 for (i=0; i<data->touchregion_count; i++)
307 {
308 r = &data->touchregion[i];
309 /* make sure this region's viewport is visible */
310 if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
311 continue;
312 /* reposition the touch inside the viewport */
313 vx = x - r->wvp->vp.x;
314 vy = y - r->wvp->vp.y;
315 /* check if its inside this viewport */
316 if (vx >= 0 && vx < r->wvp->vp.x + r->wvp->vp.width &&
317 vy >= 0 && vy < r->wvp->vp.y + r->wvp->vp.height)
318 {
319 /* now see if the point is inside this region */
320 if (vx >= r->x && vx < r->x+r->width &&
321 vy >= r->y && vy < r->y+r->height)
322 return r->action;
323 }
324 }
325 return ACTION_TOUCHSCREEN;
326}
327#endif
297/* The WPS can be left in two ways: 328/* The WPS can be left in two ways:
298 * a) call a function, which draws over the wps. In this case, the wps 329 * a) call a function, which draws over the wps. In this case, the wps
299 * will be still active (i.e. the below function didn't return) 330 * will be still active (i.e. the below function didn't return)
@@ -393,6 +424,10 @@ long gui_wps_show(void)
393 playlist or if using the sleep timer. */ 424 playlist or if using the sleep timer. */
394 if (!(audio_status() & AUDIO_STATUS_PLAY)) 425 if (!(audio_status() & AUDIO_STATUS_PLAY))
395 exit = true; 426 exit = true;
427#ifdef HAVE_TOUCHSCREEN
428 if (button == ACTION_TOUCHSCREEN)
429 button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data);
430#endif
396/* The iPods/X5/M5 use a single button for the A-B mode markers, 431/* The iPods/X5/M5 use a single button for the A-B mode markers,
397 defined as ACTION_WPSAB_SINGLE in their config files. */ 432 defined as ACTION_WPSAB_SINGLE in their config files. */
398#ifdef ACTION_WPSAB_SINGLE 433#ifdef ACTION_WPSAB_SINGLE
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 1042e1a795..935e015c93 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -88,6 +88,8 @@ struct progressbar {
88}; 88};
89#endif 89#endif
90 90
91
92
91struct align_pos { 93struct align_pos {
92 char* left; 94 char* left;
93 char* center; 95 char* center;
@@ -297,6 +299,7 @@ enum wps_token_type {
297 299
298 /* buttons */ 300 /* buttons */
299 WPS_TOKEN_BUTTON_VOLUME, 301 WPS_TOKEN_BUTTON_VOLUME,
302 WPS_TOKEN_LASTTOUCH,
300 303
301 /* Setting option */ 304 /* Setting option */
302 WPS_TOKEN_SETTING, 305 WPS_TOKEN_SETTING,
@@ -363,6 +366,17 @@ struct wps_viewport {
363 char label; 366 char label;
364}; 367};
365 368
369#ifdef HAVE_TOUCHSCREEN
370struct touchregion {
371 struct wps_viewport* wvp;/* The viewport this region is in */
372 short int x; /* x-pos */
373 short int y; /* y-pos */
374 short int width; /* width */
375 short int height; /* height */
376 int action; /* action this button will return */
377};
378#define MAX_TOUCHREGIONS 12
379#endif
366/* wps_data 380/* wps_data
367 this struct holds all necessary data which describes the 381 this struct holds all necessary data which describes the
368 viewable content of a wps */ 382 viewable content of a wps */
@@ -399,6 +413,11 @@ struct wps_data
399 bool full_line_progressbar; 413 bool full_line_progressbar;
400#endif 414#endif
401 415
416#ifdef HAVE_TOUCHSCREEN
417 struct touchregion touchregion[MAX_TOUCHREGIONS];
418 short touchregion_count;
419#endif
420
402#ifdef HAVE_REMOTE_LCD 421#ifdef HAVE_REMOTE_LCD
403 bool remote_wps; 422 bool remote_wps;
404#endif 423#endif
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 390df56cbb..290f370fe7 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -121,7 +121,7 @@ struct wps_tag {
121 unsigned char refresh_type; 121 unsigned char refresh_type;
122 const wps_tag_parse_func parse_func; 122 const wps_tag_parse_func parse_func;
123}; 123};
124 124static int skip_end_of_line(const char *wps_bufptr);
125/* prototypes of all special parse functions : */ 125/* prototypes of all special parse functions : */
126static int parse_timeout(const char *wps_bufptr, 126static int parse_timeout(const char *wps_bufptr,
127 struct wps_token *token, struct wps_data *wps_data); 127 struct wps_token *token, struct wps_data *wps_data);
@@ -131,7 +131,7 @@ static int parse_dir_level(const char *wps_bufptr,
131 struct wps_token *token, struct wps_data *wps_data); 131 struct wps_token *token, struct wps_data *wps_data);
132static int parse_setting(const char *wps_bufptr, 132static int parse_setting(const char *wps_bufptr,
133 struct wps_token *token, struct wps_data *wps_data); 133 struct wps_token *token, struct wps_data *wps_data);
134 134
135#ifdef HAVE_LCD_BITMAP 135#ifdef HAVE_LCD_BITMAP
136static int parse_viewport_display(const char *wps_bufptr, 136static int parse_viewport_display(const char *wps_bufptr,
137 struct wps_token *token, struct wps_data *wps_data); 137 struct wps_token *token, struct wps_data *wps_data);
@@ -156,7 +156,18 @@ static int parse_albumart_load(const char *wps_bufptr,
156static int parse_albumart_conditional(const char *wps_bufptr, 156static int parse_albumart_conditional(const char *wps_bufptr,
157 struct wps_token *token, struct wps_data *wps_data); 157 struct wps_token *token, struct wps_data *wps_data);
158#endif /* HAVE_ALBUMART */ 158#endif /* HAVE_ALBUMART */
159 159#ifdef HAVE_TOUCHSCREEN
160static int parse_touchregion(const char *wps_bufptr,
161 struct wps_token *token, struct wps_data *wps_data);
162#else
163static int fulline_tag_not_supported(const char *wps_bufptr,
164 struct wps_token *token, struct wps_data *wps_data)
165{
166 (void)token; (void)wps_data;
167 return skip_end_of_line(wps_bufptr);
168}
169#define parse_touchregion fulline_tag_not_supported
170#endif
160#ifdef CONFIG_RTC 171#ifdef CONFIG_RTC
161#define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC 172#define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC
162#else 173#else
@@ -337,7 +348,10 @@ static const struct wps_tag all_tags[] = {
337#endif 348#endif
338 349
339 { WPS_TOKEN_SETTING, "St", WPS_REFRESH_DYNAMIC, parse_setting }, 350 { WPS_TOKEN_SETTING, "St", WPS_REFRESH_DYNAMIC, parse_setting },
340 351
352 { WPS_TOKEN_LASTTOUCH, "Tl", WPS_REFRESH_DYNAMIC, parse_timeout },
353 { WPS_NO_TOKEN, "T", 0, parse_touchregion },
354
341 { WPS_TOKEN_UNKNOWN, "", 0, NULL } 355 { WPS_TOKEN_UNKNOWN, "", 0, NULL }
342 /* the array MUST end with an empty string (first char is \0) */ 356 /* the array MUST end with an empty string (first char is \0) */
343}; 357};
@@ -1142,6 +1156,70 @@ static int parse_albumart_conditional(const char *wps_bufptr,
1142}; 1156};
1143#endif /* HAVE_ALBUMART */ 1157#endif /* HAVE_ALBUMART */
1144 1158
1159#ifdef HAVE_TOUCHSCREEN
1160
1161struct touchaction {char* s; int action;};
1162static struct touchaction touchactions[] = {
1163 {"play", ACTION_WPS_PLAY }, {"stop", ACTION_WPS_STOP },
1164 {"prev", ACTION_WPS_SKIPPREV }, {"next", ACTION_WPS_SKIPNEXT },
1165 {"menu", ACTION_WPS_MENU }, {"browse", ACTION_WPS_BROWSE }
1166};
1167static int parse_touchregion(const char *wps_bufptr,
1168 struct wps_token *token, struct wps_data *wps_data)
1169{
1170 (void)token;
1171 unsigned i;
1172 struct touchregion *region;
1173 const char *ptr = wps_bufptr;
1174 const char *action;
1175 int x,y,w,h;
1176
1177 /* format: %T|x|y|width|height|action|
1178 * action is one of:
1179 * play - play/pause playback
1180 * stop - stop playback, exit the wps
1181 * prev - prev track
1182 * next - next track
1183 * ffwd
1184 * rwd
1185 * menu - go back to the main menu
1186 * browse - go back to the file/db browser
1187 */
1188
1189 if ((wps_data->touchregion_count +1 >= MAX_TOUCHREGIONS) || (*ptr != '|'))
1190 return WPS_ERROR_INVALID_PARAM;
1191 ptr++;
1192
1193 if (!(ptr = parse_list("dddds", NULL, '|', ptr, &x, &y, &w, &h, &action)))
1194 return WPS_ERROR_INVALID_PARAM;
1195
1196 /* Check there is a terminating | */
1197 if (*ptr != '|')
1198 return WPS_ERROR_INVALID_PARAM;
1199
1200 /* should probably do some bounds checking here with the viewport... but later */
1201 region = &wps_data->touchregion[wps_data->touchregion_count];
1202 region->action = ACTION_NONE;
1203 region->x = x;
1204 region->y = y;
1205 region->width = w;
1206 region->height = h;
1207 region->wvp = &wps_data->viewports[wps_data->num_viewports];
1208 i = 0;
1209 while ((region->action == ACTION_NONE) &&
1210 (i < sizeof(touchactions)/sizeof(*touchactions)))
1211 {
1212 if (!strncmp(touchactions[i].s, action, strlen(touchactions[i].s)))
1213 region->action = touchactions[i].action;
1214 i++;
1215 }
1216 if (region->action == ACTION_NONE)
1217 return WPS_ERROR_INVALID_PARAM;
1218 wps_data->touchregion_count++;
1219 return skip_end_of_line(wps_bufptr);
1220}
1221#endif
1222
1145/* Parse a generic token from the given string. Return the length read */ 1223/* Parse a generic token from the given string. Return the length read */
1146static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) 1224static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
1147{ 1225{
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 7d4daafdc2..6fbe5de229 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -81,6 +81,9 @@ static int button_read(int *data);
81static int button_read(void); 81static int button_read(void);
82#endif 82#endif
83 83
84#ifdef HAVE_TOUCHSCREEN
85 int last_touchscreen_touch;
86#endif
84#if defined(HAVE_HEADPHONE_DETECTION) 87#if defined(HAVE_HEADPHONE_DETECTION)
85static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */ 88static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */
86/* This callback can be used for many different functions if needed - 89/* This callback can be used for many different functions if needed -
@@ -406,7 +409,9 @@ void button_init(void)
406 remote_filter_first_keypress = false; 409 remote_filter_first_keypress = false;
407#endif 410#endif
408#endif 411#endif
409 412#ifdef HAVE_TOUCHSCREEN
413 last_touchscreen_touch = 0xffff;
414#endif
410 /* Start polling last */ 415 /* Start polling last */
411 tick_add_task(button_tick); 416 tick_add_task(button_tick);
412} 417}
@@ -522,7 +527,10 @@ static int button_read(void)
522 if (btn && flipped) 527 if (btn && flipped)
523 btn = button_flip(btn); /* swap upside down */ 528 btn = button_flip(btn); /* swap upside down */
524#endif 529#endif
525 530#ifdef HAVE_TOUCHSCREEN
531 if (btn & BUTTON_TOUCHSCREEN)
532 last_touchscreen_touch = current_tick;
533#endif
526 /* Filter the button status. It is only accepted if we get the same 534 /* Filter the button status. It is only accepted if we get the same
527 status twice in a row. */ 535 status twice in a row. */
528#ifndef HAVE_TOUCHSCREEN 536#ifndef HAVE_TOUCHSCREEN
@@ -536,7 +544,6 @@ static int button_read(void)
536 return retval; 544 return retval;
537} 545}
538 546
539
540int button_status(void) 547int button_status(void)
541{ 548{
542 return lastbtn; 549 return lastbtn;
@@ -547,6 +554,12 @@ void button_clear_queue(void)
547 queue_clear(&button_queue); 554 queue_clear(&button_queue);
548} 555}
549 556
557#ifdef HAVE_TOUCHSCREEN
558int touchscreen_last_touch(void)
559{
560 return last_touchscreen_touch;
561}
562#endif
550#endif /* SIMULATOR */ 563#endif /* SIMULATOR */
551 564
552#ifdef HAVE_WHEEL_ACCELERATION 565#ifdef HAVE_WHEEL_ACCELERATION
diff --git a/firmware/export/button.h b/firmware/export/button.h
index d5a8001fb7..3947f07207 100644
--- a/firmware/export/button.h
+++ b/firmware/export/button.h
@@ -68,6 +68,8 @@ int button_apply_acceleration(const unsigned int data);
68#define BUTTON_TOUCHSCREEN 0x08000000 68#define BUTTON_TOUCHSCREEN 0x08000000
69 69
70#ifdef HAVE_TOUCHSCREEN 70#ifdef HAVE_TOUCHSCREEN
71int touchscreen_last_touch(void);
72
71#if (!defined(BUTTON_TOPLEFT) || !defined(BUTTON_TOPMIDDLE) \ 73#if (!defined(BUTTON_TOPLEFT) || !defined(BUTTON_TOPMIDDLE) \
72 || !defined(BUTTON_TOPRIGHT) || !defined(BUTTON_MIDLEFT) \ 74 || !defined(BUTTON_TOPRIGHT) || !defined(BUTTON_MIDLEFT) \
73 || !defined(BUTTON_CENTER) || !defined(BUTTON_MIDRIGHT) \ 75 || !defined(BUTTON_CENTER) || !defined(BUTTON_MIDRIGHT) \
diff --git a/uisimulator/sdl/button.c b/uisimulator/sdl/button.c
index e9fa03cbef..9c8f334b43 100644
--- a/uisimulator/sdl/button.c
+++ b/uisimulator/sdl/button.c
@@ -36,6 +36,7 @@ static intptr_t button_data; /* data value from last message dequeued */
36#ifdef HAVE_TOUCHSCREEN 36#ifdef HAVE_TOUCHSCREEN
37#include "touchscreen.h" 37#include "touchscreen.h"
38static int mouse_coords = 0; 38static int mouse_coords = 0;
39static int last_touchscreen_touch = 0xffff;
39#endif 40#endif
40/* how long until repeat kicks in */ 41/* how long until repeat kicks in */
41#define REPEAT_START 6 42#define REPEAT_START 6
@@ -1310,11 +1311,16 @@ void mouse_tick_task(void)
1310 } 1311 }
1311 1312
1312 mouse_coords = (x<<16)|y; 1313 mouse_coords = (x<<16)|y;
1314 last_touchscreen_touch = current_tick;
1313 button_event(BUTTON_TOUCHSCREEN, true); 1315 button_event(BUTTON_TOUCHSCREEN, true);
1314 if (debug_wps) 1316 if (debug_wps)
1315 printf("Mouse at: (%d, %d)\n", x, y); 1317 printf("Mouse at: (%d, %d)\n", x, y);
1316 } 1318 }
1317} 1319}
1320int touchscreen_last_touch(void)
1321{
1322 return last_touchscreen_touch;
1323}
1318#endif 1324#endif
1319void button_init(void) 1325void button_init(void)
1320{ 1326{
diff --git a/wps/cabbiev2.320x240x16.mrobe500.wps b/wps/cabbiev2.320x240x16.mrobe500.wps
new file mode 100644
index 0000000000..222f51bc41
--- /dev/null
+++ b/wps/cabbiev2.320x240x16.mrobe500.wps
@@ -0,0 +1,47 @@
1# cabbie 2.0 default
2# (C) 2007, Johannes Voggenthaler (Zinc Alloy)
3#derived from "cabbie" (C) Yohann Misquitta
4%wd
5%T|286|207|24|24|play|
6%T|0|207|84|24|menu|
7%X|wpsbackdrop-320x240x16.bmp|
8%xl|A|lock-320x240x16.bmp|91|207|2|
9%xl|B|battery-320x240x16.bmp|126|207|10|
10%xl|C|volume-320x240x16.bmp|177|207|10|
11%xl|D|shuffle-320x240x16.bmp|218|211|
12%xl|E|repeat-320x240x16.bmp|261|207|4|
13%xl|F|playmode-320x240x16.bmp|286|207|5|
14%Cl|16|32|s120|s120|
15%pb|pb-320x240x16.bmp|10|162|300|15|
16%?mh<%xdAa|%xdAb>
17%?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
18%?pv<%xdCa|%xdCb|%xdCc|%xdCd|%xdCe|%xdCf|%xdCg|%xdCh|%xdCi|%xdCj>
19%?ps<%xdD>
20%?mm<|%xdEa|%xdEb|%xdEc|%xdEd>
21%?mp<%xdFa|%xdFc|%xdFb|%xdFd|%xdFe>
22%?C<%Vda%C|%Vdb>
23#NowPlaying
24
25%Vl|a|153|30|-|130|1|-|-|
26%s%al%?it<%it|%fn>
27%s%al%?ia<%ia|%?d2<%d2|(root)>>
28%s%al%?id<%id|%?d1<%d1|(root)>>
29#%s%al%iy
30
31%s%alNext Track:
32%s%al%?It<%It|%Fn>
33%s%al%Ia
34
35%Vl|b|0|30|-|130|1|-|-|
36%s%ac%?it<%it|%fn>
37%s%ac%?ia<%ia|%?d2<%d2|(root)>>
38%s%ac%?id<%id|%?d1<%d1|(root)>>
39%s%ac%iy
40
41%acNext Track:
42%s%ac%?It<%It|%Fn>
43%s%ac%Ia
44
45%V|0|180|-|20|1|-|-|
46%al %pc%ac%pp of %pe%ar%pr
47