rockbox/firmware/drivers/touchscreen.c

219 lines
6.1 KiB
C
Raw Permalink Normal View History

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Maurus Cuelenaere
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "button.h"
#include "button-target.h"
#include "touchscreen.h"
#include "string.h"
#include "logf.h"
#include "lcd.h"
/* Size of the 'dead zone' around each 3x3 button */
#define BUTTON_MARGIN_X (int)(LCD_WIDTH * 0.03)
#define BUTTON_MARGIN_Y (int)(LCD_HEIGHT * 0.03)
static bool touch_enabled = true;
static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT;
static const int touchscreen_buttons[3][3] =
{
{BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT},
{BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT},
{BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT}
};
#ifndef DEFAULT_TOUCHSCREEN_CALIBRATION
#define DEFAULT_TOUCHSCREEN_CALIBRATION { .A=1, .B=0, .C=0, \
.D=0, .E=1, .F=0, \
.divider=1 }
#endif
struct touchscreen_parameter calibration_parameters
= DEFAULT_TOUCHSCREEN_CALIBRATION;
const struct touchscreen_parameter default_calibration_parameters
= DEFAULT_TOUCHSCREEN_CALIBRATION;
void touchscreen_disable_mapping(void)
{
#define C(x) calibration_parameters.x
C(A) = C(E) = 1;
C(B) = C(C) = C(D) = C(F) = 0;
C(divider) = 1;
#undef C
}
void touchscreen_reset_mapping(void)
{
memcpy(&calibration_parameters, &default_calibration_parameters,
sizeof(struct touchscreen_parameter));
}
int touchscreen_calibrate(struct touchscreen_calibration *cal)
{
#define C(x) calibration_parameters.x /* Calibration */
#define S(i,j) cal->i[j][0] /* Screen */
#define D(i,j) cal->i[j][1] /* Display */
long divider = (S(x,0) - S(x,2)) * (S(y,1) - S(y,2)) -
(S(x,1) - S(x,2)) * (S(y,0) - S(y,2));
if(divider == 0)
return -1;
else
C(divider) = divider;
C(A) = (D(x,0) - D(x,2)) * (S(y,1) - S(y,2)) -
(D(x,1) - D(x,2)) * (S(y,0) - S(y,2));
C(B) = (S(x,0) - S(x,2)) * (D(x,1) - D(x,2)) -
(D(x,0) - D(x,2)) * (S(x,1) - S(x,2));
C(C) = S(y,0) * (S(x,2) * D(x,1) - S(x,1) * D(x,2)) +
S(y,1) * (S(x,0) * D(x,2) - S(x,2) * D(x,0)) +
S(y,2) * (S(x,1) * D(x,0) - S(x,0) * D(x,1));
C(D) = (D(y,0) - D(y,2)) * (S(y,1) - S(y,2)) -
(D(y,1) - D(y,2)) * (S(y,0) - S(y,2));
C(E) = (S(x,0) - S(x,2)) * (D(y,1) - D(y,2)) -
(D(y,0) - D(y,2)) * (S(x,1) - S(x,2));
C(F) = S(y,0) * (S(x,2) * D(y,1) - S(x,1) * D(y,2)) +
S(y,1) * (S(x,0) * D(y,2) - S(x,2) * D(y,0)) +
S(y,2) * (S(x,1) * D(y,0) - S(x,0) * D(y,1));
logf("A: %lX B: %lX C: %lX", C(A), C(B), C(C));
logf("D: %lX E: %lX F: %lX", C(D), C(E), C(F));
logf("divider: %lX", C(divider));
return 0;
#undef C
#undef S
#undef D
}
static void map_pixels(int *x, int *y)
{
#define C(x) calibration_parameters.x
int _x = *x, _y = *y;
*x = (C(A) * _x + C(B) * _y + C(C)) / C(divider);
*y = (C(D) * _x + C(E) * _y + C(F)) / C(divider);
#undef C
}
/* TODO: add jitter (and others) filter */
int touchscreen_to_pixels(int x, int y, int *data)
{
if(!touch_enabled)
return 0;
x &= 0xFFFF;
y &= 0xFFFF;
map_pixels(&x, &y);
if (current_mode == TOUCHSCREEN_BUTTON)
{
int column = 0, row = 0;
if (x < LCD_WIDTH/3 - BUTTON_MARGIN_X)
column = 0;
else if (x > LCD_WIDTH/3 + BUTTON_MARGIN_X &&
x < 2*LCD_WIDTH/3 - BUTTON_MARGIN_X)
column = 1;
else if (x > 2*LCD_WIDTH/3 + BUTTON_MARGIN_X)
column = 2;
else
return BUTTON_NONE;
if (y < LCD_HEIGHT/3 - BUTTON_MARGIN_Y)
row = 0;
else if (y > LCD_HEIGHT/3 + BUTTON_MARGIN_Y &&
y < 2*LCD_HEIGHT/3 - BUTTON_MARGIN_Y)
row = 1;
else if (y > 2*LCD_HEIGHT/3 + BUTTON_MARGIN_Y)
row = 2;
else
return BUTTON_NONE;
return touchscreen_buttons[row][column];
}
else
{
*data = (x << 16 | y);
return BUTTON_TOUCHSCREEN;
}
}
void touchscreen_set_mode(enum touchscreen_mode mode)
{
current_mode = mode;
}
enum touchscreen_mode touchscreen_get_mode(void)
{
return current_mode;
}
#ifndef HAS_BUTTON_HOLD
void touchscreen_enable(bool en)
{
if(en != touch_enabled)
{
touch_enabled = en;
touchscreen_enable_device(en);
}
}
bool touchscreen_is_enabled(void)
{
return touch_enabled;
}
#endif
Introducing Targets iBasso DX50 & iBasso DX90 The port to for this two targets has been entirely developped by Ilia Sergachev (alias Il or xzcc). His source can be found at https://bitbucket.org/isergachev/rockbox . The few necesary modifications for the DX90 port was done by headwhacker form head-fi.org. Unfortunately i could not try out the final state of the DX90 port. The port is hosted on android (without java) as standalone app. The official Firmware is required to run this port. Ilia did modify the source files for the "android" target in the rockbox source to make the DX port work. The work I did was to separate the code for DX50 (&DX90) from the android target. On this Target Ilia used source from tinyalsa from AOSP. I did not touch that part of the code because I do not understand it. What else I changed from Ilias sources besides the separation from the target "android": * removed a dirty hack to keep backlight off * changed value battery meter to voltage battery meter * made all plugins compile (named target as "standalone") and added keymaps * i added the graphics for the manual but did not do anything else for the manual yet * minor optimizations known bugs: * timers are slowed donw when playback is active (tinyalsa related?) * some minor bugs Things to do: * The main prolem will be how to install the app correctly. A guy called DOC2008 added a CWM (by androtab.info) to the official firmware and Ilia made a CWM installation script and a dualboot selector (rbutils/ibassoboot, build with ndk-build). We will have to find a way to install rockbox in a proper way without breaking any copyrights. Maybe ADB is an option but it is not enable with OF by default. Patching the OF is probably the way to go. * All the wiki and manual to build: needed: android ndk installed, android sdk installed with additional build-tools 19.1.0 installed ./tools/configure select iBasso DX50 or iBasso DX90 make -j apk the content of rockbox.zip/.rockbox needs to be copied to /system/rockbox/app_rockbox/rockbox/ (rockbox app not needed) the content of libs/armeabi to /system/rockbox/lib/ (rockbox app needed) The boot selector is needed as /system/bin/MangoPlayer and the iBasso app as /system/bin/MangoPlayer_original. There is also the "vold" file. The one from OF does not work with DX50 rockbox (DX90 works!?), the one from Ilia is necessary. Until we have found a proper way to install it, it can only be installed following the instructions of Ilia on his bitbucket page, using the CWM-OF and his installation script package. Change-Id: Ic4faaf84824c162aabcc08e492cee6e0068719d0 Reviewed-on: http://gerrit.rockbox.org/941 Tested: Chiwen Chang <rock1104.tw@yahoo.com.tw> Reviewed-by: Michael Giacomelli <giac2000@hotmail.com>
2014-08-30 11:15:53 +00:00
#if ((CONFIG_PLATFORM & PLATFORM_ANDROID) == 0) || defined(DX50) || defined(DX90)
/* android has an API for this */
#define TOUCH_SLOP 16u
#define REFERENCE_DPI 160
int touchscreen_get_scroll_threshold(void)
{
#ifdef LCD_DPI
const int dpi = LCD_DPI;
#else
const int dpi = lcd_get_dpi();
#endif
/* Inspired by Android calculation
*
* float density = real dpi / reference dpi (=160)
* int threshold = (int) (density * TOUCH_SLOP + 0.5f);(original calculation)
*
* + 0.5f is for rounding, we use fixed point math to achieve that
*/
int result = dpi * (TOUCH_SLOP<<1) / REFERENCE_DPI;
result += result & 1; /* round up if needed */
return result>>1;
}
#endif