summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2009-08-02 07:05:30 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2009-08-02 07:05:30 +0000
commit0131a3873e0cb05bd357326b441f2cbc1884c657 (patch)
treebf224f3e36c3b052f3583d5692eae12d9c922f55
parente9b061a7174298c61dd1f935a38654e07f573197 (diff)
downloadrockbox-0131a3873e0cb05bd357326b441f2cbc1884c657.tar.gz
rockbox-0131a3873e0cb05bd357326b441f2cbc1884c657.zip
Pluginlib: Add support for general buttons. Add menu and quit buttons to Reversi. MRobe 500: Modify touch handler to return the previous data always rather than 0 when there is no touch.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22110 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c2
-rw-r--r--apps/plugin.h2
-rw-r--r--apps/plugins/calculator.c2
-rw-r--r--apps/plugins/lib/SOURCES2
-rw-r--r--apps/plugins/lib/pluginlib_touchscreen.c249
-rw-r--r--apps/plugins/lib/pluginlib_touchscreen.h (renamed from apps/plugins/lib/touchscreen.h)23
-rw-r--r--apps/plugins/lib/touchscreen.c135
-rw-r--r--apps/plugins/minesweeper.c2
-rw-r--r--apps/plugins/pegbox.c2
-rw-r--r--apps/plugins/reversi/reversi-gui.c218
-rw-r--r--apps/plugins/reversi/reversi-gui.h15
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c5
12 files changed, 438 insertions, 219 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 35b4179949..52565b82cc 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -668,6 +668,8 @@ static const struct plugin_api rockbox_api = {
668#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID) 668#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
669 usb_hid_send, 669 usb_hid_send,
670#endif 670#endif
671
672 lcd_set_viewport,
671}; 673};
672 674
673int plugin_load(const char* plugin, const void* parameter) 675int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 3809486d0a..d2130f48df 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -836,6 +836,8 @@ struct plugin_api {
836#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID) 836#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
837 void (*usb_hid_send)(usage_page_t usage_page, int id); 837 void (*usb_hid_send)(usage_page_t usage_page, int id);
838#endif 838#endif
839
840 void (*lcd_set_viewport)(struct viewport* vp);
839}; 841};
840 842
841/* plugin header */ 843/* plugin header */
diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c
index 2c16e03c9c..079a6e500c 100644
--- a/apps/plugins/calculator.c
+++ b/apps/plugins/calculator.c
@@ -365,7 +365,7 @@ PLUGIN_HEADER
365#define CALCULATOR_CLEAR BUTTON_TOPRIGHT 365#define CALCULATOR_CLEAR BUTTON_TOPRIGHT
366#endif 366#endif
367 367
368#include "lib/touchscreen.h" 368#include "lib/pluginlib_touchscreen.h"
369static struct ts_raster calc_raster = { X_0_POS, Y_1_POS, 369static struct ts_raster calc_raster = { X_0_POS, Y_1_POS,
370 BUTTON_COLS*REC_WIDTH, BUTTON_ROWS*REC_HEIGHT, REC_WIDTH, REC_HEIGHT }; 370 BUTTON_COLS*REC_WIDTH, BUTTON_ROWS*REC_HEIGHT, REC_WIDTH, REC_HEIGHT };
371#endif 371#endif
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 72538fc2a0..00d3ac7c56 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -54,7 +54,7 @@ pluginlib_albumart.c
54pluginlib_actions.c 54pluginlib_actions.c
55helper.c 55helper.c
56#ifdef HAVE_TOUCHSCREEN 56#ifdef HAVE_TOUCHSCREEN
57touchscreen.c 57pluginlib_touchscreen.c
58#endif 58#endif
59md5.c 59md5.c
60 60
diff --git a/apps/plugins/lib/pluginlib_touchscreen.c b/apps/plugins/lib/pluginlib_touchscreen.c
new file mode 100644
index 0000000000..eb023b064c
--- /dev/null
+++ b/apps/plugins/lib/pluginlib_touchscreen.c
@@ -0,0 +1,249 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2008 by Maurus Cuelenaere
11* Copyright (C) 2009 by Karl Kurbjun
12*
13* This program is free software; you can redistribute it and/or
14* modify it under the terms of the GNU General Public License
15* as published by the Free Software Foundation; either version 2
16* of the License, or (at your option) any later version.
17*
18* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19* KIND, either express or implied.
20*
21****************************************************************************/
22
23#include "plugin.h"
24
25#ifdef HAVE_TOUCHSCREEN
26
27#include "pluginlib_touchscreen.h"
28
29/*******************************************************************************
30 * Touchbutton functions: These functions allow the plugin to specify a button
31 * location that, in turn gets mapped to a button press return value.
32 ******************************************************************************/
33
34/* touchbutton_get:
35 * This function checks the touchbutton structure passed to it for hits. When
36 * one is found it returns action.
37 * inputs:
38 * struct touchbutton *data: This is intended to be an array of
39 * touchbuttons of size num_buttons. Each element in the array defines
40 * one button.
41 * int button: This is the button return value from a button_get() call.
42 * It is used to determine REPEAT/RELEASE events.
43 * int num_buttons: This tells touchbutton_get how many elements are in
44 * data.
45 * return:
46 * If a touch occured over one of the defined buttons, return action, else
47 * return 0.
48 */
49int touchbutton_get(struct touchbutton *data, int button, int num_buttons) {
50 short x,y;
51
52 /* Get the x/y location of the button press, this is set by button_get when
53 * a button is pulled from the queue.
54 */
55 x = rb->button_get_data() >> 16;
56 y = (short) rb->button_get_data();
57 struct viewport *v;
58
59 int i;
60
61 /* Loop over the data array to check if any of the buttons were pressed */
62 for (i=0; i<num_buttons; i++) {
63 v=&data[i].vp;
64 /* See if the point is inside the button viewport */
65 if( x >= v->x && x < (v->x + v->width) &&
66 y >= v->y && y < (v->y + v->height) ) {
67 if( ((button & BUTTON_REPEAT) && data[i].repeat) ||
68 ((button & BUTTON_REL) && !data[i].repeat) ) {
69 return data[i].action;
70 }
71 }
72 }
73 return 0;
74}
75
76/* touchbutton_draw:
77 * This function draws the button with the associated text as long as the
78 * invisible flag is not set. Support for pixmaps needs to be added.
79 * inputs:
80 * struct touchbutton *data: This is intended to be an array of
81 * touchbuttons of size num_buttons. Each element in the array defines
82 * one button.
83 * int num_buttons: This tells touchbutton_get how many elements are in
84 * data.
85 * return:
86 * If a touch occured over one of the defined buttons, return action, else
87 * return 0.
88 */
89void touchbutton_draw(struct touchbutton *data, int num_buttons) {
90 int i;
91 /* These store the width and height of the title offset */
92 int title_width, title_height;
93
94 /* Loop over all the elements in data */
95 for(i=0; i<num_buttons; i++) {
96 /* Is this a visible button? */
97 if(!data[i].invisible) {
98 /* Set the current viewport to the button so that all drawing
99 * operations are within the button location.
100 */
101 rb->lcd_set_viewport(&data[i].vp);
102
103 /* Get the string size so that the title can be centered. */
104 rb->lcd_getstringsize(data[i].title, &title_width, &title_height);
105
106 /* Center the title vertically */
107 title_height=(data[i].vp.height-title_height)/2;
108
109 /* If the above calculation was negative, reset to 0 */
110 if(title_height<0) {
111 title_height=0;
112 }
113
114 /* Center the title horizontally */
115 title_width=(data[i].vp.width-title_width)/2;
116
117 /* If the above calculation was negative, reset to 0 */
118 if(title_width<0) {
119 title_width=0;
120 }
121
122 /* If the width offset was 0, use a scrolling puts, else center and
123 * print the title.
124 */
125 if(title_width==0) {
126 rb->lcd_puts_scroll(0, 0, data[i].title);
127 } else {
128 rb->lcd_putsxy(title_width, title_height, data[i].title);
129 }
130
131 /* Draw bounding box around the button location. */
132 rb->lcd_drawrect( 0, 0, data[i].vp.width, data[i].vp.height);
133 }
134 }
135 rb->lcd_set_viewport(NULL); /* Go back to the default viewport */
136}
137
138/*******************************************************************************
139 * Touchmap functions: Not sure how exactly these functions are used, comments
140 * needed!!!
141 ******************************************************************************/
142unsigned int touchscreen_map(struct ts_mappings *map, int x, int y)
143{
144 int i;
145 for(i=0; i < map->amount; i++)
146 {
147 #define _MAP(x) (map->mappings[x])
148 if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width)
149 && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height))
150 return i;
151 }
152
153 return -1;
154}
155
156unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result)
157{
158 int res1_x, res2_x, res1_y, res2_y;
159
160 if((x - map->tl_x) < 0 ||
161 (x - map->tl_x) > map->width)
162 return -1;
163 res1_x = (x - map->tl_x)/(map->raster_width);
164 res2_x = (x - map->tl_x)%(map->raster_width);
165
166 if((y - map->tl_y) < 0 ||
167 (y - map->tl_y) > map->height)
168 return -1;
169 res1_y = (y - map->tl_y)/(map->raster_height);
170 res2_y = (y - map->tl_y)%(map->raster_height);
171
172 if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */
173 return -2;
174 else
175 {
176 (*result).x = res1_x;
177 (*result).y = res1_y;
178 return 1;
179 }
180}
181
182struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button)
183{
184 struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}};
185 struct ts_raster_result tmp;
186
187 ret.action = TS_ACTION_NONE;
188 if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1)
189 return ret;
190
191 #define NOT_HANDLED (ret.action == TS_ACTION_NONE)
192 if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable)
193 {
194 map->_prev_x = tmp.x;
195 map->_prev_y = tmp.y;
196 }
197 if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable)
198 {
199 ret.action = TS_ACTION_DRAG_DROP;
200 ret.from.x = map->_prev_x;
201 ret.from.y = map->_prev_y;
202 ret.to.x = tmp.x;
203 ret.to.y = tmp.y;
204 }
205 if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED)
206 {
207 if(map->_prev_x == tmp.x && map->_prev_y == tmp.y)
208 {
209 ret.action = TS_ACTION_DOUBLE_CLICK;
210 ret.from.x = ret.to.x = tmp.x;
211 ret.from.y = ret.to.y = tmp.y;
212 }
213 else
214 {
215 map->_prev_x = tmp.x;
216 map->_prev_y = tmp.y;
217 }
218 }
219 if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED)
220 {
221 if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y))
222 {
223 ret.action = TS_ACTION_TWO_D_MOVEMENT;
224 ret.from.x = map->two_d_from.x;
225 ret.from.y = map->two_d_from.y;
226 ret.to.x = map->two_d_from.x + (map->two_d_from.x == tmp.x ? 0 : (tmp.x > map->two_d_from.x ? 1 : -1));
227 ret.to.y = map->two_d_from.y + (map->two_d_from.y == tmp.y ? 0 : (tmp.y > map->two_d_from.y ? 1 : -1));
228 }
229 else
230 ret.action = TS_ACTION_NONE;
231 }
232 if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED)
233 {
234 ret.action = TS_ACTION_CLICK;
235 ret.from.x = ret.to.x = tmp.x;
236 ret.from.y = ret.to.y = tmp.y;
237 }
238 if(map->move_progress_enable && NOT_HANDLED)
239 {
240 ret.action = TS_ACTION_MOVE;
241 ret.from.x = ret.to.x = tmp.x;
242 ret.from.y = ret.to.y = tmp.y;
243 }
244
245 map->_prev_btn_state = button;
246 return ret;
247}
248
249#endif /* HAVE_TOUCHSCREEN */
diff --git a/apps/plugins/lib/touchscreen.h b/apps/plugins/lib/pluginlib_touchscreen.h
index cd5251e46f..f2787655ee 100644
--- a/apps/plugins/lib/touchscreen.h
+++ b/apps/plugins/lib/pluginlib_touchscreen.h
@@ -8,6 +8,7 @@
8* $Id$ 8* $Id$
9* 9*
10* Copyright (C) 2008 by Maurus Cuelenaere 10* Copyright (C) 2008 by Maurus Cuelenaere
11* Copyright (C) 2009 by Karl Kurbjun
11* 12*
12* This program is free software; you can redistribute it and/or 13* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License 14* modify it under the terms of the GNU General Public License
@@ -26,6 +27,28 @@
26 27
27#ifdef HAVE_TOUCHSCREEN 28#ifdef HAVE_TOUCHSCREEN
28 29
30/*******************************************************************************
31 * Touchbutton
32 ******************************************************************************/
33struct touchbutton {
34 /* Each button has it's own viewport to define colors, drawstyle, location*/
35 struct viewport vp;
36 bool repeat; /* requires the area be held for the action */
37 int action; /* action this button will return */
38 bool invisible; /* Is this an invisible button? */
39 char *title; /* Specify a title */
40 fb_data *pixmap; /* Currently unused, but will allow for a graphic */
41};
42
43/* Get: tests for a button press and returns action. */
44int touchbutton_get(struct touchbutton *data, int button, int num_buttons);
45/* Draw: Draws all visible buttons */
46void touchbutton_draw(struct touchbutton *data, int num_buttons);
47
48
49/*******************************************************************************
50 * Touch mapping
51 ******************************************************************************/
29struct ts_mapping 52struct ts_mapping
30{ 53{
31 int tl_x; /* top left */ 54 int tl_x; /* top left */
diff --git a/apps/plugins/lib/touchscreen.c b/apps/plugins/lib/touchscreen.c
deleted file mode 100644
index 5b7517349a..0000000000
--- a/apps/plugins/lib/touchscreen.c
+++ /dev/null
@@ -1,135 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2008 by Maurus Cuelenaere
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version 2
15* of the License, or (at your option) any later version.
16*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
21
22#include "plugin.h"
23
24#ifdef HAVE_TOUCHSCREEN
25
26#include "touchscreen.h"
27
28unsigned int touchscreen_map(struct ts_mappings *map, int x, int y)
29{
30 int i;
31 for(i=0; i < map->amount; i++)
32 {
33 #define _MAP(x) (map->mappings[x])
34 if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width)
35 && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height))
36 return i;
37 }
38
39 return -1;
40}
41
42unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result)
43{
44 int res1_x, res2_x, res1_y, res2_y;
45
46 if((x - map->tl_x) < 0 ||
47 (x - map->tl_x) > map->width)
48 return -1;
49 res1_x = (x - map->tl_x)/(map->raster_width);
50 res2_x = (x - map->tl_x)%(map->raster_width);
51
52 if((y - map->tl_y) < 0 ||
53 (y - map->tl_y) > map->height)
54 return -1;
55 res1_y = (y - map->tl_y)/(map->raster_height);
56 res2_y = (y - map->tl_y)%(map->raster_height);
57
58 if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */
59 return -2;
60 else
61 {
62 (*result).x = res1_x;
63 (*result).y = res1_y;
64 return 1;
65 }
66}
67
68struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button)
69{
70 struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}};
71 struct ts_raster_result tmp;
72
73 ret.action = TS_ACTION_NONE;
74 if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1)
75 return ret;
76
77 #define NOT_HANDLED (ret.action == TS_ACTION_NONE)
78 if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable)
79 {
80 map->_prev_x = tmp.x;
81 map->_prev_y = tmp.y;
82 }
83 if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable)
84 {
85 ret.action = TS_ACTION_DRAG_DROP;
86 ret.from.x = map->_prev_x;
87 ret.from.y = map->_prev_y;
88 ret.to.x = tmp.x;
89 ret.to.y = tmp.y;
90 }
91 if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED)
92 {
93 if(map->_prev_x == tmp.x && map->_prev_y == tmp.y)
94 {
95 ret.action = TS_ACTION_DOUBLE_CLICK;
96 ret.from.x = ret.to.x = tmp.x;
97 ret.from.y = ret.to.y = tmp.y;
98 }
99 else
100 {
101 map->_prev_x = tmp.x;
102 map->_prev_y = tmp.y;
103 }
104 }
105 if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED)
106 {
107 if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y))
108 {
109 ret.action = TS_ACTION_TWO_D_MOVEMENT;
110 ret.from.x = map->two_d_from.x;
111 ret.from.y = map->two_d_from.y;
112 ret.to.x = map->two_d_from.x + (map->two_d_from.x == tmp.x ? 0 : (tmp.x > map->two_d_from.x ? 1 : -1));
113 ret.to.y = map->two_d_from.y + (map->two_d_from.y == tmp.y ? 0 : (tmp.y > map->two_d_from.y ? 1 : -1));
114 }
115 else
116 ret.action = TS_ACTION_NONE;
117 }
118 if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED)
119 {
120 ret.action = TS_ACTION_CLICK;
121 ret.from.x = ret.to.x = tmp.x;
122 ret.from.y = ret.to.y = tmp.y;
123 }
124 if(map->move_progress_enable && NOT_HANDLED)
125 {
126 ret.action = TS_ACTION_MOVE;
127 ret.from.x = ret.to.x = tmp.x;
128 ret.from.y = ret.to.y = tmp.y;
129 }
130
131 map->_prev_btn_state = button;
132 return ret;
133}
134
135#endif /* HAVE_TOUCHSCREEN */
diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c
index 5bd38dc244..47be0ea309 100644
--- a/apps/plugins/minesweeper.c
+++ b/apps/plugins/minesweeper.c
@@ -340,7 +340,7 @@ char str[30];
340 340
341#ifdef HAVE_TOUCHSCREEN 341#ifdef HAVE_TOUCHSCREEN
342 342
343#include "lib/touchscreen.h" 343#include "lib/pluginlib_touchscreen.h"
344static struct ts_raster mine_raster = { 0, 0, MAX_WIDTH, MAX_HEIGHT, TileSize, TileSize }; 344static struct ts_raster mine_raster = { 0, 0, MAX_WIDTH, MAX_HEIGHT, TileSize, TileSize };
345#endif 345#endif
346 346
diff --git a/apps/plugins/pegbox.c b/apps/plugins/pegbox.c
index 67714fee9d..cd90de49c6 100644
--- a/apps/plugins/pegbox.c
+++ b/apps/plugins/pegbox.c
@@ -520,7 +520,7 @@ PLUGIN_HEADER
520 520
521 521
522#ifdef HAVE_TOUCHSCREEN 522#ifdef HAVE_TOUCHSCREEN
523#include "lib/touchscreen.h" 523#include "lib/pluginlib_touchscreen.h"
524static struct ts_raster pegbox_raster = 524static struct ts_raster pegbox_raster =
525 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT, 525 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
526 PIECE_WIDTH, PIECE_HEIGHT }; 526 PIECE_WIDTH, PIECE_HEIGHT };
diff --git a/apps/plugins/reversi/reversi-gui.c b/apps/plugins/reversi/reversi-gui.c
index 2ad27caf01..fa20e46bb6 100644
--- a/apps/plugins/reversi/reversi-gui.c
+++ b/apps/plugins/reversi/reversi-gui.c
@@ -32,11 +32,9 @@ Use the arrow keys to move cursor, and press TOGGLE to place a stone.
32 32
33At any time during the game, press MENU to bring up the game menu with 33At any time during the game, press MENU to bring up the game menu with
34further options: 34further options:
35
36 - Save 35 - Save
37 - Reload 36 - Reload
38 - Clear 37 - Clear
39
40*/ 38*/
41 39
42#include "plugin.h" 40#include "plugin.h"
@@ -139,6 +137,75 @@ static cursor_wrap_mode_t cursor_wrap_mode;
139static bool quit_plugin; 137static bool quit_plugin;
140static bool game_finished; 138static bool game_finished;
141 139
140#ifdef HAVE_TOUCHSCREEN
141#include "lib/pluginlib_touchscreen.h"
142/* This uses the touchscreen library functions/structures. */
143
144/* This defines the number of buttons used; only used in this C file. */
145#define TOUCHBUTTON_COUNT 3
146
147/* Define the button locations, widths and heights */
148
149#if LCD_HEIGHT < LCD_WIDTH
150/* Define Menu button x, y, width, height */
151#define B_MENU_X LEGEND_X(0)
152#define B_MENU_Y (LCD_HEIGHT/4)
153#define B_MENU_W (LCD_WIDTH-LEGEND_X(0))
154#define B_MENU_H (LCD_HEIGHT/4)
155/* Define Quit Button x, y, width, height */
156#define B_QUIT_X LEGEND_X(0)
157#define B_QUIT_Y (LCD_HEIGHT/2)
158#define B_QUIT_W (LCD_WIDTH-LEGEND_X(0))
159#define B_QUIT_H (LCD_HEIGHT/4)
160#else
161/* Define Menu button x, y, width, height */
162#define B_MENU_X (LCD_WIDTH/2)
163#define B_MENU_Y LEGEND_Y(0)
164#define B_MENU_W (LCD_WIDTH/4)
165#define B_MENU_H (2*CELL_HEIGHT)
166/* Define Quit Button x, y, width, height */
167#define B_QUIT_X (LCD_WIDTH-LCD_WIDTH/4)
168#define B_QUIT_Y LEGEND_Y(0)
169#define B_QUIT_W (LCD_WIDTH/4)
170#define B_QUIT_H (2*CELL_HEIGHT)
171#endif
172
173/* This is the button initialization/definition. The first element is the
174 * Viewport. This is defined in lcd.h, but the elements are:
175 * int x - X location of button/viewport
176 * int y - Y location of button/viewport
177 * int width - Width of button/viewport
178 * int height - Height of button/viewport
179 * int font - Font to be used on button/viewport
180 * int drawmode- Modes defined in lcd.h
181 * unsigned fg_pattern - foreground color
182 * unsigned bg_pattern - backbround color
183 * unsigned lss_pattern - Selector colors (currently unused)
184 * unsigned lse_pattern - |
185 * unsigned lst_pattern - \/
186 *
187 * The rest of the touch button elements are:
188 * bool repeat - requires the area be held for the action
189 * int action - action this button will return
190 * bool invisible - Is this an invisible button?
191 * char *title - Specify a title
192 * fb_data *pixmap- Currently unused, but will allow for a graphic
193 */
194struct touchbutton reversi_buttons[TOUCHBUTTON_COUNT] =
195 {
196 { {B_MENU_X, B_MENU_Y, B_MENU_W, B_MENU_H, FONT_UI,
197 STYLE_DEFAULT, 0, 0xFFFF, 0, 0, 0},
198 false, REVERSI_BUTTON_MENU, false, "Menu", NULL },
199
200 { {B_QUIT_X, B_QUIT_Y, B_QUIT_W, B_QUIT_H, FONT_UI,
201 STYLE_DEFAULT, 0, 0xFFFF, 0, 0, 0},
202 false, REVERSI_BUTTON_QUIT, false, "Quit", NULL },
203
204 { {0, 0, XOFS+BOARD_WIDTH, YOFS+BOARD_HEIGHT, 0,
205 STYLE_DEFAULT, 0, 0xFFFF, 0, 0, 0},
206 false, REVERSI_BUTTON_MAKE_MOVE, true, NULL, NULL }
207};
208#endif
142 209
143/* Initialises the state of the game (starts a new game) */ 210/* Initialises the state of the game (starts a new game) */
144static void reversi_gui_init(void) { 211static void reversi_gui_init(void) {
@@ -184,8 +251,12 @@ static void reversi_gui_draw_cell(int x, int y, int color) {
184 int i; 251 int i;
185 if (color == WHITE) { 252 if (color == WHITE) {
186 for (i = 0; i < CELL_LINE_THICKNESS; i++) { 253 for (i = 0; i < CELL_LINE_THICKNESS; i++) {
187 rb->lcd_drawrect(x+STONE_MARGIN+i, y+STONE_MARGIN+i, 254 rb->lcd_drawrect(
188 CELL_WIDTH+1-2*(STONE_MARGIN+i), CELL_HEIGHT+1-2*(STONE_MARGIN+i)); 255 x+STONE_MARGIN+i,
256 y+STONE_MARGIN+i,
257 CELL_WIDTH+1-2*(STONE_MARGIN+i),
258 CELL_HEIGHT+1-2*(STONE_MARGIN+i)
259 );
189 } 260 }
190 } else if (color == BLACK) { 261 } else if (color == BLACK) {
191 rb->lcd_fillrect(x+STONE_MARGIN, y+STONE_MARGIN, 262 rb->lcd_fillrect(x+STONE_MARGIN, y+STONE_MARGIN,
@@ -249,6 +320,10 @@ static void reversi_gui_display_board(void) {
249 y = LEGEND_Y(r); 320 y = LEGEND_Y(r);
250 rb->lcd_drawrect(x, y, CELL_WIDTH+1, CELL_HEIGHT+1); 321 rb->lcd_drawrect(x, y, CELL_WIDTH+1, CELL_HEIGHT+1);
251 322
323#if defined(HAVE_TOUCHSCREEN)
324 touchbutton_draw(reversi_buttons, TOUCHBUTTON_COUNT);
325#endif
326
252 /* Update the screen */ 327 /* Update the screen */
253 rb->lcd_update(); 328 rb->lcd_update();
254} 329}
@@ -299,7 +374,10 @@ static bool reversi_gui_choose_strategy(
299 break; 374 break;
300 } 375 }
301 } 376 }
302 result = rb->set_option(prompt, &index, INT, strategy_settings, num_items, NULL); 377
378 result =
379 rb->set_option(prompt, &index, INT, strategy_settings, num_items, NULL);
380
303 (*player) = strategy_values[index]; 381 (*player) = strategy_values[index];
304 382
305 if((*player)->init_func) 383 if((*player)->init_func)
@@ -339,7 +417,8 @@ static bool reversi_gui_menu(void) {
339 break; 417 break;
340 418
341 case 4: /* Cursor wrap mode */ 419 case 4: /* Cursor wrap mode */
342 num_items = sizeof(cursor_wrap_mode_values)/sizeof(cursor_wrap_mode_values[0]); 420 num_items = sizeof(cursor_wrap_mode_values) /
421 sizeof(cursor_wrap_mode_values[0]);
343 index = 0; 422 index = 0;
344 for (i = 0; i < num_items; i++) { 423 for (i = 0; i < num_items; i++) {
345 if (cursor_wrap_mode == cursor_wrap_mode_values[i]) { 424 if (cursor_wrap_mode == cursor_wrap_mode_values[i]) {
@@ -372,7 +451,8 @@ static bool reversi_gui_menu(void) {
372 * Returns true iff the cursor would be really moved. In any case, the 451 * Returns true iff the cursor would be really moved. In any case, the
373 * new cursor position is stored in (new_row, new_col). 452 * new cursor position is stored in (new_row, new_col).
374 */ 453 */
375static bool reversi_gui_cursor_pos_vmove(int row_delta, int *new_row, int *new_col) { 454static bool
455reversi_gui_cursor_pos_vmove(int row_delta, int *new_row, int *new_col) {
376 *new_row = cur_row + row_delta; 456 *new_row = cur_row + row_delta;
377 *new_col = cur_col; 457 *new_col = cur_col;
378 458
@@ -421,7 +501,8 @@ static bool reversi_gui_cursor_pos_vmove(int row_delta, int *new_row, int *new_c
421 * Returns true iff the cursor would be really moved. In any case, the 501 * Returns true iff the cursor would be really moved. In any case, the
422 * new cursor position is stored in (new_row, new_col). 502 * new cursor position is stored in (new_row, new_col).
423 */ 503 */
424static bool reversi_gui_cursor_pos_hmove(int col_delta, int *new_row, int *new_col) { 504static bool
505reversi_gui_cursor_pos_hmove(int col_delta, int *new_row, int *new_col) {
425 *new_row = cur_row; 506 *new_row = cur_row;
426 *new_col = cur_col + col_delta; 507 *new_col = cur_col + col_delta;
427 508
@@ -554,39 +635,62 @@ enum plugin_status plugin_start(const void *parameter) {
554 continue; 635 continue;
555 } 636 }
556 637
638 /***********************************************************************
639 * Button handling code happens below here
640 **********************************************************************/
557 button = rb->button_get(true); 641 button = rb->button_get(true);
642
643 /* The touchscreen buttons can act as true buttons so OR them in */
644#ifdef HAVE_TOUCHSCREEN
645 button |= touchbutton_get(reversi_buttons, button, TOUCHBUTTON_COUNT);
646#endif
558 647
559 switch (button) { 648 /* All of these button presses wait for the release event */
649 if(button&BUTTON_REL) {
560#ifdef REVERSI_BUTTON_QUIT 650#ifdef REVERSI_BUTTON_QUIT
561 /* Exit game */ 651 if(button&REVERSI_BUTTON_QUIT) {
562 case REVERSI_BUTTON_QUIT:
563 exit = true; 652 exit = true;
564 break; 653 }
565#endif 654#endif
566 655
567#ifdef HAVE_TOUCHSCREEN 656#ifdef HAVE_TOUCHSCREEN
568 case BUTTON_TOUCHSCREEN: 657 if(button&BUTTON_TOUCHSCREEN) {
569 button_x = rb->button_get_data() >> 16; 658 button_x = rb->button_get_data();
570 button_y = rb->button_get_data() & 0xffff; 659 button_y = button_x & 0xffff;
571 if( (CELL_R(button_y)>(BOARD_SIZE-1)) || 660 button_x >>= 16;
572 (CELL_C(button_x)>(BOARD_SIZE-1)) ) 661
662 /* Check if the click was in the gameboard, if so move cursor.
663 * This has to happen before MAKE_MOVE is processed.
664 */
665 if( (CELL_R(button_y)<BOARD_SIZE) &&
666 (CELL_C(button_x)<BOARD_SIZE) )
573 { 667 {
574 break;
575 } else {
576 reversi_gui_move_cursor(CELL_R(button_y), CELL_C(button_x)); 668 reversi_gui_move_cursor(CELL_R(button_y), CELL_C(button_x));
577 } 669 }
670 }
578#endif 671#endif
579 672
580#ifdef REVERSI_BUTTON_ALT_MAKE_MOVE 673 if( (button&REVERSI_BUTTON_MENU)
581 case REVERSI_BUTTON_ALT_MAKE_MOVE: 674#if defined(REVERSI_BUTTON_MENU_LONGPRESS)
675 && (lastbutton&BUTTON_REPEAT)
582#endif 676#endif
583 case REVERSI_BUTTON_MAKE_MOVE: 677 ) {
584#ifdef REVERSI_BUTTON_MAKE_MOVE_PRE 678 if (reversi_gui_menu()) {
585 if ((button == REVERSI_BUTTON_MAKE_MOVE) 679 return PLUGIN_USB_CONNECTED;
586 && (lastbutton != REVERSI_BUTTON_MAKE_MOVE_PRE)) 680 }
587 break; 681 draw_screen = true;
682 }
683
684 if(button&REVERSI_BUTTON_MAKE_MOVE
685#if defined(REVERSI_BUTTON_MAKE_MOVE_SHORTPRESS)
686 && !(lastbutton&BUTTON_REPEAT)
588#endif 687#endif
589 if (game_finished) break; 688 ) {
689 /* If you touch the game board instead of hitting menu after it
690 * has completed the game will exit out.
691 */
692 if (game_finished)
693 break;
590 if (reversi_make_move(&game, cur_row, cur_col, cur_player) > 0) { 694 if (reversi_make_move(&game, cur_row, cur_col, cur_player) > 0) {
591 /* Move was made. Global changes on the board are possible */ 695 /* Move was made. Global changes on the board are possible */
592 draw_screen = true; /* Redraw the screen next time */ 696 draw_screen = true; /* Redraw the screen next time */
@@ -607,66 +711,42 @@ enum plugin_status plugin_start(const void *parameter) {
607 /* Ignore any button presses during the splash */ 711 /* Ignore any button presses during the splash */
608 rb->button_clear_queue(); 712 rb->button_clear_queue();
609 } 713 }
610 break; 714 }
715 }
716
717 /* These button presses will run on a release or a repeat event */
718 if(button&BUTTON_REL || button&BUTTON_REPEAT) {
611 /* Move cursor left */ 719 /* Move cursor left */
612#ifdef REVERSI_BUTTON_ALT_LEFT 720 if(button&REVERSI_BUTTON_LEFT) {
613 case REVERSI_BUTTON_ALT_LEFT:
614 case (REVERSI_BUTTON_ALT_LEFT | BUTTON_REPEAT):
615#endif
616 case REVERSI_BUTTON_LEFT:
617 case (REVERSI_BUTTON_LEFT | BUTTON_REPEAT):
618 if (reversi_gui_cursor_pos_hmove(-1, &row, &col)) { 721 if (reversi_gui_cursor_pos_hmove(-1, &row, &col)) {
619 reversi_gui_move_cursor(row, col); 722 reversi_gui_move_cursor(row, col);
620 } 723 }
621 break; 724 }
622
623 /* Move cursor right */ 725 /* Move cursor right */
624#ifdef REVERSI_BUTTON_ALT_RIGHT 726 if(button&REVERSI_BUTTON_RIGHT) {
625 case REVERSI_BUTTON_ALT_RIGHT:
626 case (REVERSI_BUTTON_ALT_RIGHT | BUTTON_REPEAT):
627#endif
628 case REVERSI_BUTTON_RIGHT:
629 case (REVERSI_BUTTON_RIGHT | BUTTON_REPEAT):
630 if (reversi_gui_cursor_pos_hmove(1, &row, &col)) { 727 if (reversi_gui_cursor_pos_hmove(1, &row, &col)) {
631 reversi_gui_move_cursor(row, col); 728 reversi_gui_move_cursor(row, col);
632 } 729 }
633 break; 730 }
634
635 /* Move cursor up */ 731 /* Move cursor up */
636 case REVERSI_BUTTON_UP: 732 if(button&REVERSI_BUTTON_UP) {
637 case (REVERSI_BUTTON_UP | BUTTON_REPEAT):
638 if (reversi_gui_cursor_pos_vmove(-1, &row, &col)) { 733 if (reversi_gui_cursor_pos_vmove(-1, &row, &col)) {
639 reversi_gui_move_cursor(row, col); 734 reversi_gui_move_cursor(row, col);
640 } 735 }
641 break; 736 }
642
643 /* Move cursor down */ 737 /* Move cursor down */
644 case REVERSI_BUTTON_DOWN: 738 if(button&REVERSI_BUTTON_DOWN) {
645 case (REVERSI_BUTTON_DOWN | BUTTON_REPEAT):
646 if (reversi_gui_cursor_pos_vmove(1, &row, &col)) { 739 if (reversi_gui_cursor_pos_vmove(1, &row, &col)) {
647 reversi_gui_move_cursor(row, col); 740 reversi_gui_move_cursor(row, col);
648 } 741 }
649 break; 742 }
650 743 }
651 case REVERSI_BUTTON_MENU:
652#ifdef REVERSI_BUTTON_MENU_PRE
653 if (lastbutton != REVERSI_BUTTON_MENU_PRE) {
654 break;
655 }
656#endif
657 if (reversi_gui_menu()) {
658 return PLUGIN_USB_CONNECTED;
659 }
660 draw_screen = true;
661 break;
662 744
663 default: 745 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) {
664 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { 746 /* Quit if USB has been connected */
665 /* Quit if USB has been connected */ 747 return PLUGIN_USB_CONNECTED;
666 return PLUGIN_USB_CONNECTED;
667 }
668 break;
669 } 748 }
749
670 if (button != BUTTON_NONE) { 750 if (button != BUTTON_NONE) {
671 lastbutton = button; 751 lastbutton = button;
672 } 752 }
diff --git a/apps/plugins/reversi/reversi-gui.h b/apps/plugins/reversi/reversi-gui.h
index 8c409e9a75..a93fa344e4 100644
--- a/apps/plugins/reversi/reversi-gui.h
+++ b/apps/plugins/reversi/reversi-gui.h
@@ -42,11 +42,10 @@
42#define REVERSI_BUTTON_DOWN BUTTON_DOWN 42#define REVERSI_BUTTON_DOWN BUTTON_DOWN
43#define REVERSI_BUTTON_LEFT BUTTON_LEFT 43#define REVERSI_BUTTON_LEFT BUTTON_LEFT
44#define REVERSI_BUTTON_RIGHT BUTTON_RIGHT 44#define REVERSI_BUTTON_RIGHT BUTTON_RIGHT
45#define REVERSI_BUTTON_MAKE_MOVE_PRE BUTTON_MENU 45#define REVERSI_BUTTON_MAKE_MOVE BUTTON_MENU
46#define REVERSI_BUTTON_MAKE_MOVE (BUTTON_MENU | BUTTON_REL) 46#define REVERSI_BUTTON_MAKE_MOVE_SHORTPRESS
47#define REVERSI_BUTTON_ALT_MAKE_MOVE (BUTTON_MENU | BUTTON_DOWN) 47#define REVERSI_BUTTON_MENU_LONGPRESS
48#define REVERSI_BUTTON_MENU_PRE BUTTON_MENU 48#define REVERSI_BUTTON_MENU BUTTON_MENU
49#define REVERSI_BUTTON_MENU (BUTTON_MENU | BUTTON_REPEAT)
50 49
51#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ 50#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
52 (CONFIG_KEYPAD == IRIVER_H300_PAD) 51 (CONFIG_KEYPAD == IRIVER_H300_PAD)
@@ -63,10 +62,8 @@
63 (CONFIG_KEYPAD == IPOD_1G2G_PAD) 62 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
64#define REVERSI_BUTTON_UP BUTTON_MENU 63#define REVERSI_BUTTON_UP BUTTON_MENU
65#define REVERSI_BUTTON_DOWN BUTTON_PLAY 64#define REVERSI_BUTTON_DOWN BUTTON_PLAY
66#define REVERSI_BUTTON_LEFT BUTTON_LEFT 65#define REVERSI_BUTTON_LEFT (BUTTON_LEFT | BUTTON_SCROLL_BACK)
67#define REVERSI_BUTTON_RIGHT BUTTON_RIGHT 66#define REVERSI_BUTTON_RIGHT (BUTTON_RIGHT | BUTTON_SCROLL_FWD)
68#define REVERSI_BUTTON_ALT_LEFT BUTTON_SCROLL_BACK
69#define REVERSI_BUTTON_ALT_RIGHT BUTTON_SCROLL_FWD
70#define REVERSI_BUTTON_MAKE_MOVE (BUTTON_SELECT | BUTTON_REL) 67#define REVERSI_BUTTON_MAKE_MOVE (BUTTON_SELECT | BUTTON_REL)
71#define REVERSI_BUTTON_MENU (BUTTON_MENU | BUTTON_SELECT) 68#define REVERSI_BUTTON_MENU (BUTTON_MENU | BUTTON_SELECT)
72 69
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c
index 4def88c4f8..04acb71e45 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c
@@ -110,16 +110,17 @@ inline bool button_hold(void)
110 110
111int button_read_device(int *data) 111int button_read_device(int *data)
112{ 112{
113 static int old_data;
113 int button_read = BUTTON_NONE; 114 int button_read = BUTTON_NONE;
114 short touch_x, touch_y, touch_z1, touch_z2; 115 short touch_x, touch_y, touch_z1, touch_z2;
115 static bool hold_button_old = false; 116 static bool hold_button_old = false;
116 117
117 *data = 0; 118 *data = old_data;
118 119
119 /* Handle touchscreen */ 120 /* Handle touchscreen */
120 if (tsc2100_read_touch(&touch_x, &touch_y, &touch_z1, &touch_z2)) 121 if (tsc2100_read_touch(&touch_x, &touch_y, &touch_z1, &touch_z2))
121 { 122 {
122 *data = touch_to_pixels(&touch_x, &touch_y); 123 old_data = *data = touch_to_pixels(&touch_x, &touch_y);
123 button_read |= touchscreen_to_pixels(touch_x, touch_y, data); 124 button_read |= touchscreen_to_pixels(touch_x, touch_y, data);
124 } 125 }
125 126