Move the PCM/audio playback part of SDL into the target tree.
[kugel-rb.git] / apps / plugins / lib / pluginlib_touchscreen.c
blob3168b46ac84968bb5c9579091cdfe421a23cb500
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
23 #include "plugin.h"
25 #ifdef HAVE_TOUCHSCREEN
27 #include "pluginlib_touchscreen.h"
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 ******************************************************************************/
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.
49 int touchbutton_get(struct touchbutton *data, int button, int num_buttons) {
50 short x,y;
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.
55 x = rb->button_get_data() >> 16;
56 y = (short) rb->button_get_data();
57 struct viewport *v;
59 int i;
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;
73 return 0;
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.
89 void 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;
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.
101 rb->screens[SCREEN_MAIN]->set_viewport(&data[i].vp);
103 /* Get the string size so that the title can be centered. */
104 rb->lcd_getstringsize(data[i].title, &title_width, &title_height);
106 /* Center the title vertically */
107 title_height=(data[i].vp.height-title_height)/2;
109 /* If the above calculation was negative, reset to 0 */
110 if(title_height<0) {
111 title_height=0;
114 /* Center the title horizontally */
115 title_width=(data[i].vp.width-title_width)/2;
117 /* If the above calculation was negative, reset to 0 */
118 if(title_width<0) {
119 title_width=0;
122 /* If the width offset was 0, use a scrolling puts, else center and
123 * print the title.
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);
131 /* Draw bounding box around the button location. */
132 rb->lcd_drawrect( 0, 0, data[i].vp.width, data[i].vp.height);
135 rb->screens[SCREEN_MAIN]->set_viewport(NULL); /* Go back to the default viewport */
138 /*******************************************************************************
139 * Touchmap functions: Not sure how exactly these functions are used, comments
140 * needed!!!
141 ******************************************************************************/
142 unsigned int touchscreen_map(struct ts_mappings *map, int x, int y)
144 int i;
145 for(i=0; i < map->amount; i++)
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;
153 return -1;
156 unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result)
158 int res1_x, res2_x, res1_y, res2_y;
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);
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);
172 if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */
173 return -2;
174 else
176 (*result).x = res1_x;
177 (*result).y = res1_y;
178 return 1;
182 struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button)
184 struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}};
185 struct ts_raster_result tmp;
187 ret.action = TS_ACTION_NONE;
188 if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1)
189 return ret;
191 #define NOT_HANDLED (ret.action == TS_ACTION_NONE)
192 if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable)
194 map->_prev_x = tmp.x;
195 map->_prev_y = tmp.y;
197 if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable)
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;
205 if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED)
207 if(map->_prev_x == tmp.x && map->_prev_y == tmp.y)
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;
213 else
215 map->_prev_x = tmp.x;
216 map->_prev_y = tmp.y;
219 if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED)
221 if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y))
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));
229 else
230 ret.action = TS_ACTION_NONE;
232 if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED)
234 ret.action = TS_ACTION_CLICK;
235 ret.from.x = ret.to.x = tmp.x;
236 ret.from.y = ret.to.y = tmp.y;
238 if(map->move_progress_enable && NOT_HANDLED)
240 ret.action = TS_ACTION_MOVE;
241 ret.from.x = ret.to.x = tmp.x;
242 ret.from.y = ret.to.y = tmp.y;
245 map->_prev_btn_state = button;
246 return ret;
249 #endif /* HAVE_TOUCHSCREEN */