1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 * Copyright (C) 2009 by Karl Kurbjun
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
25 #include "pluginlib_touchscreen.h"
26 #include "pluginlib_exit.h"
28 /*******************************************************************************
29 * Touchbutton functions: These functions allow the plugin to specify a button
30 * location that, in turn gets mapped to a button press return value.
31 ******************************************************************************/
33 /* touchbutton_check_button:
34 * This function checks the touchbutton structure passed to it for hits. When
35 * one is found it returns action. It doesn't block because it doesn't actually
36 * call button_get. You need to call it before and pass its result.
38 * struct touchbutton *data: This is intended to be an array of
39 * touchbuttons of size num_buttons. Each element in the array defines
41 * int button: This is the button return value from a button_get() call.
42 * It is used to determine REPEAT/RELEASE events. This way
43 * this function can be mixed with other buttons
44 * int num_buttons: This tells touchbutton_get how many elements are in
47 * If a touch occured over one of the defined buttons, return action, else
50 int touchbutton_check_button(int button
, struct touchbutton
*data
, int num_buttons
) {
53 /* Get the x/y location of the button press, this is set by button_get when
54 * a button is pulled from the queue.
56 x
= rb
->button_get_data() >> 16;
57 y
= (short) rb
->button_get_data();
62 /* Loop over the data array to check if any of the buttons were pressed */
63 for (i
=0; i
<num_buttons
; i
++) {
65 /* See if the point is inside the button viewport */
66 if( x
>= v
->x
&& x
< (v
->x
+ v
->width
) &&
67 y
>= v
->y
&& y
< (v
->y
+ v
->height
) ) {
68 if( ((button
& BUTTON_REPEAT
) && data
[i
].repeat
) ||
69 ((button
& BUTTON_REL
) && !data
[i
].repeat
) ) {
70 return data
[i
].action
;
77 /* touchbutton_get_w_tmo:
78 * This function checks the touchbutton structure passed to it for hits. When
79 * one is found it returns the corresponding action.
81 * struct touchbutton *data: This is intended to be an array of
82 * touchbuttons of size num_buttons. Each element in the array defines
84 * int tmo: Timeout when waiting for input.
85 * int num_buttons: This tells touchbutton_get how many elements are in
88 * If a touch occured over one of the defined buttons, return action, else
91 int touchbutton_get_w_tmo(int tmo
, struct touchbutton
*data
, int num_buttons
)
93 int btn
= rb
->button_get_w_tmo(tmo
);
94 int result
= touchbutton_check_button(btn
, data
, num_buttons
);
100 * This function checks the touchbutton structure passed to it for hits. When
101 * one is found it returns the corresponding action.
103 * struct touchbutton *data: This is intended to be an array of
104 * touchbuttons of size num_buttons. Each element in the array defines
106 * int num_buttons: This tells touchbutton_get how many elements are in
109 * If a touch occured over one of the defined buttons, return action, else
112 int touchbutton_get(struct touchbutton
*data
, int num_buttons
)
114 return touchbutton_get_w_tmo(TIMEOUT_BLOCK
, data
, num_buttons
);
118 * This function draws the button with the associated text as long as the
119 * invisible flag is not set. Support for pixmaps needs to be added.
121 * struct touchbutton *data: This is intended to be an array of
122 * touchbuttons of size num_buttons. Each element in the array defines
124 * int num_buttons: This tells touchbutton_get how many elements are in
127 * If a touch occured over one of the defined buttons, return action, else
130 void touchbutton_draw(struct touchbutton
*data
, int num_buttons
) {
132 struct screen
*lcd
= rb
->screens
[SCREEN_MAIN
];
134 /* Loop over all the elements in data */
135 for(i
=0; i
<num_buttons
; i
++) {
136 /* Is this a visible button? */
137 if(!data
[i
].invisible
) {
138 /* Set the current viewport to the button so that all drawing
139 * operations are within the button location.
141 lcd
->set_viewport(&data
[i
].vp
);
143 /* Set line_height to height, then it'll center for us */
144 data
[i
].vp
.line_height
= data
[i
].vp
.height
;
145 data
[i
].vp
.flags
|= VP_FLAG_ALIGN_CENTER
;
147 /* If the width offset was 0, use a scrolling puts, else center and
150 lcd
->puts_scroll_style(0, 0, data
[i
].title
, STYLE_DEFAULT
);
151 /* Draw bounding box around the button location. */
152 lcd
->draw_border_viewport();
155 lcd
->set_viewport(NULL
); /* Go back to the default viewport */
158 /*******************************************************************************
159 * Touchmap functions: Not sure how exactly these functions are used, comments
161 ******************************************************************************/
162 unsigned int touchscreen_map(struct ts_mappings
*map
, int x
, int y
)
165 for(i
=0; i
< map
->amount
; i
++)
167 #define _MAP(x) (map->mappings[x])
168 if(x
> _MAP(i
).tl_x
&& x
< (_MAP(i
).tl_x
+_MAP(i
).width
)
169 && y
> _MAP(i
).tl_y
&& y
< (_MAP(i
).tl_y
+_MAP(i
).height
))
176 unsigned int touchscreen_map_raster(struct ts_raster
*map
, int x
, int y
, struct ts_raster_result
*result
)
178 int res1_x
, res2_x
, res1_y
, res2_y
;
180 if((x
- map
->tl_x
) < 0 ||
181 (x
- map
->tl_x
) > map
->width
)
183 res1_x
= (x
- map
->tl_x
)/(map
->raster_width
);
184 res2_x
= (x
- map
->tl_x
)%(map
->raster_width
);
186 if((y
- map
->tl_y
) < 0 ||
187 (y
- map
->tl_y
) > map
->height
)
189 res1_y
= (y
- map
->tl_y
)/(map
->raster_height
);
190 res2_y
= (y
- map
->tl_y
)%(map
->raster_height
);
192 if(res2_x
== 0 || res2_y
== 0) /* pen hit a raster boundary */
196 (*result
).x
= res1_x
;
197 (*result
).y
= res1_y
;
202 struct ts_raster_button_result
touchscreen_raster_map_button(struct ts_raster_button_mapping
*map
, int x
, int y
, int button
)
204 struct ts_raster_button_result ret
= {0, {0, 0}, {0, 0}};
205 struct ts_raster_result tmp
;
207 ret
.action
= TS_ACTION_NONE
;
208 if(touchscreen_map_raster(map
->raster
, x
, y
, &tmp
) != 1)
211 #define NOT_HANDLED (ret.action == TS_ACTION_NONE)
212 if((button
== BUTTON_REPEAT
) && (map
->_prev_btn_state
!= BUTTON_REPEAT
) && map
->drag_drop_enable
)
214 map
->_prev_x
= tmp
.x
;
215 map
->_prev_y
= tmp
.y
;
217 if((button
== BUTTON_REL
) && (map
->_prev_btn_state
== BUTTON_REPEAT
) && map
->drag_drop_enable
)
219 ret
.action
= TS_ACTION_DRAG_DROP
;
220 ret
.from
.x
= map
->_prev_x
;
221 ret
.from
.y
= map
->_prev_y
;
225 if((button
== BUTTON_REL
) && map
->double_click_enable
&& NOT_HANDLED
)
227 if(map
->_prev_x
== tmp
.x
&& map
->_prev_y
== tmp
.y
)
229 ret
.action
= TS_ACTION_DOUBLE_CLICK
;
230 ret
.from
.x
= ret
.to
.x
= tmp
.x
;
231 ret
.from
.y
= ret
.to
.y
= tmp
.y
;
235 map
->_prev_x
= tmp
.x
;
236 map
->_prev_y
= tmp
.y
;
239 if((button
& BUTTON_REL
|| button
& BUTTON_REPEAT
) && map
->two_d_movement_enable
&& NOT_HANDLED
)
241 if((map
->two_d_from
.x
== tmp
.x
) ^ (map
->two_d_from
.y
== tmp
.y
))
243 ret
.action
= TS_ACTION_TWO_D_MOVEMENT
;
244 ret
.from
.x
= map
->two_d_from
.x
;
245 ret
.from
.y
= map
->two_d_from
.y
;
246 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));
247 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));
250 ret
.action
= TS_ACTION_NONE
;
252 if(map
->click_enable
&& (button
& BUTTON_REL
) && NOT_HANDLED
)
254 ret
.action
= TS_ACTION_CLICK
;
255 ret
.from
.x
= ret
.to
.x
= tmp
.x
;
256 ret
.from
.y
= ret
.to
.y
= tmp
.y
;
258 if(map
->move_progress_enable
&& NOT_HANDLED
)
260 ret
.action
= TS_ACTION_MOVE
;
261 ret
.from
.x
= ret
.to
.x
= tmp
.x
;
262 ret
.from
.y
= ret
.to
.y
= tmp
.y
;
265 map
->_prev_btn_state
= button
;