A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 266 lines 9.8 kB view raw
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#include "pluginlib_touchscreen.h" 26#include "pluginlib_exit.h" 27 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 ******************************************************************************/ 32 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. 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. This way 43 * this function can be mixed with other buttons 44 * int num_buttons: This tells touchbutton_get how many elements are in 45 * data. 46 * return: 47 * If a touch occured over one of the defined buttons, return action, else 48 * return 0. 49 */ 50int touchbutton_check_button(int button, struct touchbutton *data, int num_buttons) { 51 short x,y; 52 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. 55 */ 56 x = rb->button_get_data() >> 16; 57 y = (short) rb->button_get_data(); 58 struct viewport *v; 59 60 int i; 61 62 /* Loop over the data array to check if any of the buttons were pressed */ 63 for (i=0; i<num_buttons; i++) { 64 v=&data[i].vp; 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; 71 } 72 } 73 } 74 return 0; 75} 76 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. 80 * inputs: 81 * struct touchbutton *data: This is intended to be an array of 82 * touchbuttons of size num_buttons. Each element in the array defines 83 * one button. 84 * int tmo: Timeout when waiting for input. 85 * int num_buttons: This tells touchbutton_get how many elements are in 86 * data. 87 * return: 88 * If a touch occured over one of the defined buttons, return action, else 89 * return 0. 90 */ 91int touchbutton_get_w_tmo(int tmo, struct touchbutton *data, int num_buttons) 92{ 93 int btn = rb->button_get_w_tmo(tmo); 94 int result = touchbutton_check_button(btn, data, num_buttons); 95 exit_on_usb(result); 96 return result; 97} 98 99/* touchbutton_get: 100 * This function checks the touchbutton structure passed to it for hits. When 101 * one is found it returns the corresponding action. 102 * inputs: 103 * struct touchbutton *data: This is intended to be an array of 104 * touchbuttons of size num_buttons. Each element in the array defines 105 * one button. 106 * int num_buttons: This tells touchbutton_get how many elements are in 107 * data. 108 * return: 109 * If a touch occured over one of the defined buttons, return action, else 110 * return 0. 111 */ 112int touchbutton_get(struct touchbutton *data, int num_buttons) 113{ 114 return touchbutton_get_w_tmo(TIMEOUT_BLOCK, data, num_buttons); 115} 116 117/* touchbutton_draw: 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. 120 * inputs: 121 * struct touchbutton *data: This is intended to be an array of 122 * touchbuttons of size num_buttons. Each element in the array defines 123 * one button. 124 * int num_buttons: This tells touchbutton_get how many elements are in 125 * data. 126 * return: 127 * If a touch occured over one of the defined buttons, return action, else 128 * return 0. 129 */ 130void touchbutton_draw(struct touchbutton *data, int num_buttons) { 131 int i; 132 struct screen *lcd = rb->screens[SCREEN_MAIN]; 133 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. 140 */ 141 lcd->set_viewport(&data[i].vp); 142 143 /* TODO: Center text vert*/ 144 data[i].vp.flags |= VP_FLAG_ALIGN_CENTER; 145 146 /* If the width offset was 0, use a scrolling puts, else center and 147 * print the title. 148 */ 149 lcd->puts_scroll(0, 0, data[i].title); 150 /* Draw bounding box around the button location. */ 151 lcd->draw_border_viewport(); 152 } 153 } 154 lcd->set_viewport(NULL); /* Go back to the default viewport */ 155} 156 157/******************************************************************************* 158 * Touchmap functions: Not sure how exactly these functions are used, comments 159 * needed!!! 160 ******************************************************************************/ 161unsigned int touchscreen_map(struct ts_mappings *map, int x, int y) 162{ 163 int i; 164 for(i=0; i < map->amount; i++) 165 { 166 #define _MAP(x) (map->mappings[x]) 167 if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width) 168 && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height)) 169 return i; 170 } 171 172 return -1; 173} 174 175unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result) 176{ 177 int res1_x, res2_x, res1_y, res2_y; 178 179 if((x - map->tl_x) < 0 || 180 (x - map->tl_x) > map->width) 181 return -1; 182 res1_x = (x - map->tl_x)/(map->raster_width); 183 res2_x = (x - map->tl_x)%(map->raster_width); 184 185 if((y - map->tl_y) < 0 || 186 (y - map->tl_y) > map->height) 187 return -1; 188 res1_y = (y - map->tl_y)/(map->raster_height); 189 res2_y = (y - map->tl_y)%(map->raster_height); 190 191 if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */ 192 return -2; 193 else 194 { 195 (*result).x = res1_x; 196 (*result).y = res1_y; 197 return 1; 198 } 199} 200 201struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button) 202{ 203 struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}}; 204 struct ts_raster_result tmp; 205 206 ret.action = TS_ACTION_NONE; 207 if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1) 208 return ret; 209 210 #define NOT_HANDLED (ret.action == TS_ACTION_NONE) 211 if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable) 212 { 213 map->_prev_x = tmp.x; 214 map->_prev_y = tmp.y; 215 } 216 if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable) 217 { 218 ret.action = TS_ACTION_DRAG_DROP; 219 ret.from.x = map->_prev_x; 220 ret.from.y = map->_prev_y; 221 ret.to.x = tmp.x; 222 ret.to.y = tmp.y; 223 } 224 if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED) 225 { 226 if(map->_prev_x == tmp.x && map->_prev_y == tmp.y) 227 { 228 ret.action = TS_ACTION_DOUBLE_CLICK; 229 ret.from.x = ret.to.x = tmp.x; 230 ret.from.y = ret.to.y = tmp.y; 231 } 232 else 233 { 234 map->_prev_x = tmp.x; 235 map->_prev_y = tmp.y; 236 } 237 } 238 if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED) 239 { 240 if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y)) 241 { 242 ret.action = TS_ACTION_TWO_D_MOVEMENT; 243 ret.from.x = map->two_d_from.x; 244 ret.from.y = map->two_d_from.y; 245 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)); 246 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)); 247 } 248 else 249 ret.action = TS_ACTION_NONE; 250 } 251 if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED) 252 { 253 ret.action = TS_ACTION_CLICK; 254 ret.from.x = ret.to.x = tmp.x; 255 ret.from.y = ret.to.y = tmp.y; 256 } 257 if(map->move_progress_enable && NOT_HANDLED) 258 { 259 ret.action = TS_ACTION_MOVE; 260 ret.from.x = ret.to.x = tmp.x; 261 ret.from.y = ret.to.y = tmp.y; 262 } 263 264 map->_prev_btn_state = button; 265 return ret; 266}