summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 5ab0097..1fef9e0 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,
token->value.i * TIMEOUT_UNIT))
return "v";
return NULL;
+ case WPS_TOKEN_LASTTOUCH:
+#ifdef HAVE_TOUCHSCREEN
+ if (TIME_BEFORE(current_tick, token->value.i * TIMEOUT_UNIT +
+ touchscreen_last_touch()))
+ return "t";
+#endif
+ return NULL;
case WPS_TOKEN_SETTING:
{
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 0c8a3aa..26b531e 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -293,7 +293,38 @@ void gwps_draw_statusbars(void)
{
viewportmanager_set_statusbar(wpsbars);
}
-
+#ifdef HAVE_TOUCHSCREEN
+static int wps_get_touchaction(struct wps_data *data)
+{
+ short x,y;
+ short vx, vy;
+ int type = action_get_touchscreen_press(&x, &y);
+ int i;
+ struct touchregion *r;
+ if (type != BUTTON_REL)
+ return ACTION_TOUCHSCREEN;
+ for (i=0; i<data->touchregion_count; i++)
+ {
+ r = &data->touchregion[i];
+ /* make sure this region's viewport is visible */
+ if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
+ continue;
+ /* reposition the touch inside the viewport */
+ vx = x - r->wvp->vp.x;
+ vy = y - r->wvp->vp.y;
+ /* check if its inside this viewport */
+ if (vx >= 0 && vx < r->wvp->vp.x + r->wvp->vp.width &&
+ vy >= 0 && vy < r->wvp->vp.y + r->wvp->vp.height)
+ {
+ /* now see if the point is inside this region */
+ if (vx >= r->x && vx < r->x+r->width &&
+ vy >= r->y && vy < r->y+r->height)
+ return r->action;
+ }
+ }
+ return ACTION_TOUCHSCREEN;
+}
+#endif
/* The WPS can be left in two ways:
* a) call a function, which draws over the wps. In this case, the wps
* will be still active (i.e. the below function didn't return)
@@ -393,6 +424,10 @@ long gui_wps_show(void)
playlist or if using the sleep timer. */
if (!(audio_status() & AUDIO_STATUS_PLAY))
exit = true;
+#ifdef HAVE_TOUCHSCREEN
+ if (button == ACTION_TOUCHSCREEN)
+ button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data);
+#endif
/* The iPods/X5/M5 use a single button for the A-B mode markers,
defined as ACTION_WPSAB_SINGLE in their config files. */
#ifdef ACTION_WPSAB_SINGLE
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 1042e1a..935e015 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -88,6 +88,8 @@ struct progressbar {
};
#endif
+
+
struct align_pos {
char* left;
char* center;
@@ -297,6 +299,7 @@ enum wps_token_type {
/* buttons */
WPS_TOKEN_BUTTON_VOLUME,
+ WPS_TOKEN_LASTTOUCH,
/* Setting option */
WPS_TOKEN_SETTING,
@@ -363,6 +366,17 @@ struct wps_viewport {
char label;
};
+#ifdef HAVE_TOUCHSCREEN
+struct touchregion {
+ struct wps_viewport* wvp;/* The viewport this region is in */
+ short int x; /* x-pos */
+ short int y; /* y-pos */
+ short int width; /* width */
+ short int height; /* height */
+ int action; /* action this button will return */
+};
+#define MAX_TOUCHREGIONS 12
+#endif
/* wps_data
this struct holds all necessary data which describes the
viewable content of a wps */
@@ -399,6 +413,11 @@ struct wps_data
bool full_line_progressbar;
#endif
+#ifdef HAVE_TOUCHSCREEN
+ struct touchregion touchregion[MAX_TOUCHREGIONS];
+ short touchregion_count;
+#endif
+
#ifdef HAVE_REMOTE_LCD
bool remote_wps;
#endif
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 390df56..290f370 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -121,7 +121,7 @@ struct wps_tag {
unsigned char refresh_type;
const wps_tag_parse_func parse_func;
};
-
+static int skip_end_of_line(const char *wps_bufptr);
/* prototypes of all special parse functions : */
static int parse_timeout(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
@@ -131,7 +131,7 @@ static int parse_dir_level(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
static int parse_setting(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
-
+
#ifdef HAVE_LCD_BITMAP
static int parse_viewport_display(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
@@ -156,7 +156,18 @@ static int parse_albumart_load(const char *wps_bufptr,
static int parse_albumart_conditional(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
#endif /* HAVE_ALBUMART */
-
+#ifdef HAVE_TOUCHSCREEN
+static int parse_touchregion(const char *wps_bufptr,
+ struct wps_token *token, struct wps_data *wps_data);
+#else
+static int fulline_tag_not_supported(const char *wps_bufptr,
+ struct wps_token *token, struct wps_data *wps_data)
+{
+ (void)token; (void)wps_data;
+ return skip_end_of_line(wps_bufptr);
+}
+#define parse_touchregion fulline_tag_not_supported
+#endif
#ifdef CONFIG_RTC
#define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC
#else
@@ -337,7 +348,10 @@ static const struct wps_tag all_tags[] = {
#endif
{ WPS_TOKEN_SETTING, "St", WPS_REFRESH_DYNAMIC, parse_setting },
-
+
+ { WPS_TOKEN_LASTTOUCH, "Tl", WPS_REFRESH_DYNAMIC, parse_timeout },
+ { WPS_NO_TOKEN, "T", 0, parse_touchregion },
+
{ WPS_TOKEN_UNKNOWN, "", 0, NULL }
/* the array MUST end with an empty string (first char is \0) */
};
@@ -1142,6 +1156,70 @@ static int parse_albumart_conditional(const char *wps_bufptr,
};
#endif /* HAVE_ALBUMART */
+#ifdef HAVE_TOUCHSCREEN
+
+struct touchaction {char* s; int action;};
+static struct touchaction touchactions[] = {
+ {"play", ACTION_WPS_PLAY }, {"stop", ACTION_WPS_STOP },
+ {"prev", ACTION_WPS_SKIPPREV }, {"next", ACTION_WPS_SKIPNEXT },
+ {"menu", ACTION_WPS_MENU }, {"browse", ACTION_WPS_BROWSE }
+};
+static int parse_touchregion(const char *wps_bufptr,
+ struct wps_token *token, struct wps_data *wps_data)
+{
+ (void)token;
+ unsigned i;
+ struct touchregion *region;
+ const char *ptr = wps_bufptr;
+ const char *action;
+ int x,y,w,h;
+
+ /* format: %T|x|y|width|height|action|
+ * action is one of:
+ * play - play/pause playback
+ * stop - stop playback, exit the wps
+ * prev - prev track
+ * next - next track
+ * ffwd
+ * rwd
+ * menu - go back to the main menu
+ * browse - go back to the file/db browser
+ */
+
+ if ((wps_data->touchregion_count +1 >= MAX_TOUCHREGIONS) || (*ptr != '|'))
+ return WPS_ERROR_INVALID_PARAM;
+ ptr++;
+
+ if (!(ptr = parse_list("dddds", NULL, '|', ptr, &x, &y, &w, &h, &action)))
+ return WPS_ERROR_INVALID_PARAM;
+
+ /* Check there is a terminating | */
+ if (*ptr != '|')
+ return WPS_ERROR_INVALID_PARAM;
+
+ /* should probably do some bounds checking here with the viewport... but later */
+ region = &wps_data->touchregion[wps_data->touchregion_count];
+ region->action = ACTION_NONE;
+ region->x = x;
+ region->y = y;
+ region->width = w;
+ region->height = h;
+ region->wvp = &wps_data->viewports[wps_data->num_viewports];
+ i = 0;
+ while ((region->action == ACTION_NONE) &&
+ (i < sizeof(touchactions)/sizeof(*touchactions)))
+ {
+ if (!strncmp(touchactions[i].s, action, strlen(touchactions[i].s)))
+ region->action = touchactions[i].action;
+ i++;
+ }
+ if (region->action == ACTION_NONE)
+ return WPS_ERROR_INVALID_PARAM;
+ wps_data->touchregion_count++;
+ return skip_end_of_line(wps_bufptr);
+}
+#endif
+
/* Parse a generic token from the given string. Return the length read */
static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
{
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 7d4daaf..6fbe5de 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -81,6 +81,9 @@ static int button_read(int *data);
static int button_read(void);
#endif
+#ifdef HAVE_TOUCHSCREEN
+ int last_touchscreen_touch;
+#endif
#if defined(HAVE_HEADPHONE_DETECTION)
static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */
/* This callback can be used for many different functions if needed -
@@ -406,7 +409,9 @@ void button_init(void)
remote_filter_first_keypress = false;
#endif
#endif
-
+#ifdef HAVE_TOUCHSCREEN
+ last_touchscreen_touch = 0xffff;
+#endif
/* Start polling last */
tick_add_task(button_tick);
}
@@ -522,7 +527,10 @@ static int button_read(void)
if (btn && flipped)
btn = button_flip(btn); /* swap upside down */
#endif
-
+#ifdef HAVE_TOUCHSCREEN
+ if (btn & BUTTON_TOUCHSCREEN)
+ last_touchscreen_touch = current_tick;
+#endif
/* Filter the button status. It is only accepted if we get the same
status twice in a row. */
#ifndef HAVE_TOUCHSCREEN
@@ -536,7 +544,6 @@ static int button_read(void)
return retval;
}
-
int button_status(void)
{
return lastbtn;
@@ -547,6 +554,12 @@ void button_clear_queue(void)
queue_clear(&button_queue);
}
+#ifdef HAVE_TOUCHSCREEN
+int touchscreen_last_touch(void)
+{
+ return last_touchscreen_touch;
+}
+#endif
#endif /* SIMULATOR */
#ifdef HAVE_WHEEL_ACCELERATION
diff --git a/firmware/export/button.h b/firmware/export/button.h
index d5a8001..3947f07 100644
--- a/firmware/export/button.h
+++ b/firmware/export/button.h
@@ -68,6 +68,8 @@ int button_apply_acceleration(const unsigned int data);
#define BUTTON_TOUCHSCREEN 0x08000000
#ifdef HAVE_TOUCHSCREEN
+int touchscreen_last_touch(void);
+
#if (!defined(BUTTON_TOPLEFT) || !defined(BUTTON_TOPMIDDLE) \
|| !defined(BUTTON_TOPRIGHT) || !defined(BUTTON_MIDLEFT) \
|| !defined(BUTTON_CENTER) || !defined(BUTTON_MIDRIGHT) \
diff --git a/uisimulator/sdl/button.c b/uisimulator/sdl/button.c
index e9fa03c..9c8f334 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 */
#ifdef HAVE_TOUCHSCREEN
#include "touchscreen.h"
static int mouse_coords = 0;
+static int last_touchscreen_touch = 0xffff;
#endif
/* how long until repeat kicks in */
#define REPEAT_START 6
@@ -1310,11 +1311,16 @@ void mouse_tick_task(void)
}
mouse_coords = (x<<16)|y;
+ last_touchscreen_touch = current_tick;
button_event(BUTTON_TOUCHSCREEN, true);
if (debug_wps)
printf("Mouse at: (%d, %d)\n", x, y);
}
}
+int touchscreen_last_touch(void)
+{
+ return last_touchscreen_touch;
+}
#endif
void button_init(void)
{
diff --git a/wps/cabbiev2.320x240x16.mrobe500.wps b/wps/cabbiev2.320x240x16.mrobe500.wps
new file mode 100644
index 0000000..222f51b
--- /dev/null
+++ b/wps/cabbiev2.320x240x16.mrobe500.wps
@@ -0,0 +1,47 @@
+# cabbie 2.0 default
+# (C) 2007, Johannes Voggenthaler (Zinc Alloy)
+#derived from "cabbie" (C) Yohann Misquitta
+%wd
+%T|286|207|24|24|play|
+%T|0|207|84|24|menu|
+%X|wpsbackdrop-320x240x16.bmp|
+%xl|A|lock-320x240x16.bmp|91|207|2|
+%xl|B|battery-320x240x16.bmp|126|207|10|
+%xl|C|volume-320x240x16.bmp|177|207|10|
+%xl|D|shuffle-320x240x16.bmp|218|211|
+%xl|E|repeat-320x240x16.bmp|261|207|4|
+%xl|F|playmode-320x240x16.bmp|286|207|5|
+%Cl|16|32|s120|s120|
+%pb|pb-320x240x16.bmp|10|162|300|15|
+%?mh<%xdAa|%xdAb>
+%?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
+%?pv<%xdCa|%xdCb|%xdCc|%xdCd|%xdCe|%xdCf|%xdCg|%xdCh|%xdCi|%xdCj>
+%?ps<%xdD>
+%?mm<|%xdEa|%xdEb|%xdEc|%xdEd>
+%?mp<%xdFa|%xdFc|%xdFb|%xdFd|%xdFe>
+%?C<%Vda%C|%Vdb>
+#NowPlaying
+
+%Vl|a|153|30|-|130|1|-|-|
+%s%al%?it<%it|%fn>
+%s%al%?ia<%ia|%?d2<%d2|(root)>>
+%s%al%?id<%id|%?d1<%d1|(root)>>
+#%s%al%iy
+
+%s%alNext Track:
+%s%al%?It<%It|%Fn>
+%s%al%Ia
+
+%Vl|b|0|30|-|130|1|-|-|
+%s%ac%?it<%it|%fn>
+%s%ac%?ia<%ia|%?d2<%d2|(root)>>
+%s%ac%?id<%id|%?d1<%d1|(root)>>
+%s%ac%iy
+
+%acNext Track:
+%s%ac%?It<%It|%Fn>
+%s%ac%Ia
+
+%V|0|180|-|20|1|-|-|
+%al %pc%ac%pp of %pe%ar%pr
+