A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 218 lines 6.2 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 * 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 "config.h" 23#include "button.h" 24#include "button-target.h" 25#include "touchscreen.h" 26#include "string.h" 27#include "logf.h" 28#include "lcd.h" 29 30/* Size of the 'dead zone' around each 3x3 button */ 31#define BUTTON_MARGIN_X (int)(LCD_WIDTH * 0.03) 32#define BUTTON_MARGIN_Y (int)(LCD_HEIGHT * 0.03) 33 34static bool touch_enabled = true; 35static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; 36static const int touchscreen_buttons[3][3] = 37{ 38 {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, 39 {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, 40 {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT} 41}; 42 43#ifndef DEFAULT_TOUCHSCREEN_CALIBRATION 44#define DEFAULT_TOUCHSCREEN_CALIBRATION { .A=1, .B=0, .C=0, \ 45 .D=0, .E=1, .F=0, \ 46 .divider=1 } 47#endif 48 49struct touchscreen_parameter calibration_parameters 50 = DEFAULT_TOUCHSCREEN_CALIBRATION; 51const struct touchscreen_parameter default_calibration_parameters 52 = DEFAULT_TOUCHSCREEN_CALIBRATION; 53 54void touchscreen_disable_mapping(void) 55{ 56#define C(x) calibration_parameters.x 57 C(A) = C(E) = 1; 58 C(B) = C(C) = C(D) = C(F) = 0; 59 C(divider) = 1; 60#undef C 61} 62 63void touchscreen_reset_mapping(void) 64{ 65 memcpy(&calibration_parameters, &default_calibration_parameters, 66 sizeof(struct touchscreen_parameter)); 67} 68 69int touchscreen_calibrate(struct touchscreen_calibration *cal) 70{ 71#define C(x) calibration_parameters.x /* Calibration */ 72#define S(i,j) cal->i[j][0] /* Screen */ 73#define D(i,j) cal->i[j][1] /* Display */ 74 long divider = (S(x,0) - S(x,2)) * (S(y,1) - S(y,2)) - 75 (S(x,1) - S(x,2)) * (S(y,0) - S(y,2)); 76 77 if(divider == 0) 78 return -1; 79 else 80 C(divider) = divider; 81 82 C(A) = (D(x,0) - D(x,2)) * (S(y,1) - S(y,2)) - 83 (D(x,1) - D(x,2)) * (S(y,0) - S(y,2)); 84 85 C(B) = (S(x,0) - S(x,2)) * (D(x,1) - D(x,2)) - 86 (D(x,0) - D(x,2)) * (S(x,1) - S(x,2)); 87 88 C(C) = S(y,0) * (S(x,2) * D(x,1) - S(x,1) * D(x,2)) + 89 S(y,1) * (S(x,0) * D(x,2) - S(x,2) * D(x,0)) + 90 S(y,2) * (S(x,1) * D(x,0) - S(x,0) * D(x,1)); 91 92 C(D) = (D(y,0) - D(y,2)) * (S(y,1) - S(y,2)) - 93 (D(y,1) - D(y,2)) * (S(y,0) - S(y,2)); 94 95 C(E) = (S(x,0) - S(x,2)) * (D(y,1) - D(y,2)) - 96 (D(y,0) - D(y,2)) * (S(x,1) - S(x,2)); 97 98 C(F) = S(y,0) * (S(x,2) * D(y,1) - S(x,1) * D(y,2)) + 99 S(y,1) * (S(x,0) * D(y,2) - S(x,2) * D(y,0)) + 100 S(y,2) * (S(x,1) * D(y,0) - S(x,0) * D(y,1)); 101 102 logf("A: %lX B: %lX C: %lX", C(A), C(B), C(C)); 103 logf("D: %lX E: %lX F: %lX", C(D), C(E), C(F)); 104 logf("divider: %lX", C(divider)); 105 106 return 0; 107#undef C 108#undef S 109#undef D 110} 111 112static void map_pixels(int *x, int *y) 113{ 114#define C(x) calibration_parameters.x 115 int _x = *x, _y = *y; 116 117 *x = (C(A) * _x + C(B) * _y + C(C)) / C(divider); 118 *y = (C(D) * _x + C(E) * _y + C(F)) / C(divider); 119#undef C 120} 121 122/* TODO: add jitter (and others) filter */ 123int touchscreen_to_pixels(int x, int y, int *data) 124{ 125 if(!touch_enabled) 126 return 0; 127 x &= 0xFFFF; 128 y &= 0xFFFF; 129 130 map_pixels(&x, &y); 131 132 if (current_mode == TOUCHSCREEN_BUTTON) 133 { 134 int column = 0, row = 0; 135 136 if (x < LCD_WIDTH/3 - BUTTON_MARGIN_X) 137 column = 0; 138 else if (x > LCD_WIDTH/3 + BUTTON_MARGIN_X && 139 x < 2*LCD_WIDTH/3 - BUTTON_MARGIN_X) 140 column = 1; 141 else if (x > 2*LCD_WIDTH/3 + BUTTON_MARGIN_X) 142 column = 2; 143 else 144 return BUTTON_NONE; 145 146 if (y < LCD_HEIGHT/3 - BUTTON_MARGIN_Y) 147 row = 0; 148 else if (y > LCD_HEIGHT/3 + BUTTON_MARGIN_Y && 149 y < 2*LCD_HEIGHT/3 - BUTTON_MARGIN_Y) 150 row = 1; 151 else if (y > 2*LCD_HEIGHT/3 + BUTTON_MARGIN_Y) 152 row = 2; 153 else 154 return BUTTON_NONE; 155 156 return touchscreen_buttons[row][column]; 157 } 158 else 159 { 160 *data = (x << 16 | y); 161 return BUTTON_TOUCHSCREEN; 162 } 163} 164 165void touchscreen_set_mode(enum touchscreen_mode mode) 166{ 167 current_mode = mode; 168} 169 170enum touchscreen_mode touchscreen_get_mode(void) 171{ 172 return current_mode; 173} 174 175#ifndef HAS_BUTTON_HOLD 176void touchscreen_enable(bool en) 177{ 178 if(en != touch_enabled) 179 { 180 touch_enabled = en; 181 touchscreen_enable_device(en); 182 } 183} 184 185bool touchscreen_is_enabled(void) 186{ 187 return touch_enabled; 188} 189#endif 190 191#if ((CONFIG_PLATFORM & PLATFORM_ANDROID) == 0) || defined(DX50) || defined(DX90) 192/* android has an API for this */ 193 194#define TOUCH_SLOP 16u 195#define REFERENCE_DPI 160 196 197int touchscreen_get_scroll_threshold(void) 198{ 199#ifdef LCD_DPI 200 const int dpi = LCD_DPI; 201#else 202 const int dpi = lcd_get_dpi(); 203#endif 204 205 /* Inspired by Android calculation 206 * 207 * float density = real dpi / reference dpi (=160) 208 * int threshold = (int) (density * TOUCH_SLOP + 0.5f);(original calculation) 209 * 210 * + 0.5f is for rounding, we use fixed point math to achieve that 211 */ 212 213 int result = dpi * (TOUCH_SLOP<<1) / REFERENCE_DPI; 214 result += result & 1; /* round up if needed */ 215 return result>>1; 216} 217 218#endif