1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include "button-target.h"
25 #include "touchscreen.h"
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)
34 static enum touchscreen_mode current_mode
= TOUCHSCREEN_POINT
;
35 static const int touchscreen_buttons
[3][3] =
37 {BUTTON_TOPLEFT
, BUTTON_TOPMIDDLE
, BUTTON_TOPRIGHT
},
38 {BUTTON_MIDLEFT
, BUTTON_CENTER
, BUTTON_MIDRIGHT
},
39 {BUTTON_BOTTOMLEFT
, BUTTON_BOTTOMMIDDLE
, BUTTON_BOTTOMRIGHT
}
42 #ifndef DEFAULT_TOUCHSCREEN_CALIBRATION
43 #define DEFAULT_TOUCHSCREEN_CALIBRATION { .A=1, .B=0, .C=0, \
48 struct touchscreen_parameter calibration_parameters
49 = DEFAULT_TOUCHSCREEN_CALIBRATION
;
50 const struct touchscreen_parameter default_calibration_parameters
51 = DEFAULT_TOUCHSCREEN_CALIBRATION
;
53 void touchscreen_disable_mapping(void)
55 #define C(x) calibration_parameters.x
57 C(B
) = C(C
) = C(D
) = C(F
) = 0;
62 void touchscreen_reset_mapping(void)
64 memcpy(&calibration_parameters
, &default_calibration_parameters
,
65 sizeof(struct touchscreen_parameter
));
68 int touchscreen_calibrate(struct touchscreen_calibration
*cal
)
70 #define C(x) calibration_parameters.x /* Calibration */
71 #define S(i,j) cal->i[j][0] /* Screen */
72 #define D(i,j) cal->i[j][1] /* Display */
73 long divider
= (S(x
,0) - S(x
,2)) * (S(y
,1) - S(y
,2)) -
74 (S(x
,1) - S(x
,2)) * (S(y
,0) - S(y
,2));
81 C(A
) = (D(x
,0) - D(x
,2)) * (S(y
,1) - S(y
,2)) -
82 (D(x
,1) - D(x
,2)) * (S(y
,0) - S(y
,2));
84 C(B
) = (S(x
,0) - S(x
,2)) * (D(x
,1) - D(x
,2)) -
85 (D(x
,0) - D(x
,2)) * (S(x
,1) - S(x
,2));
87 C(C
) = S(y
,0) * (S(x
,2) * D(x
,1) - S(x
,1) * D(x
,2)) +
88 S(y
,1) * (S(x
,0) * D(x
,2) - S(x
,2) * D(x
,0)) +
89 S(y
,2) * (S(x
,1) * D(x
,0) - S(x
,0) * D(x
,1));
91 C(D
) = (D(y
,0) - D(y
,2)) * (S(y
,1) - S(y
,2)) -
92 (D(y
,1) - D(y
,2)) * (S(y
,0) - S(y
,2));
94 C(E
) = (S(x
,0) - S(x
,2)) * (D(y
,1) - D(y
,2)) -
95 (D(y
,0) - D(y
,2)) * (S(x
,1) - S(x
,2));
97 C(F
) = S(y
,0) * (S(x
,2) * D(y
,1) - S(x
,1) * D(y
,2)) +
98 S(y
,1) * (S(x
,0) * D(y
,2) - S(x
,2) * D(y
,0)) +
99 S(y
,2) * (S(x
,1) * D(y
,0) - S(x
,0) * D(y
,1));
101 logf("A: %lX B: %lX C: %lX", C(A
), C(B
), C(C
));
102 logf("D: %lX E: %lX F: %lX", C(D
), C(E
), C(F
));
103 logf("divider: %lX", C(divider
));
111 static void map_pixels(int *x
, int *y
)
113 #define C(x) calibration_parameters.x
114 int _x
= *x
, _y
= *y
;
116 *x
= (C(A
) * _x
+ C(B
) * _y
+ C(C
)) / C(divider
);
117 *y
= (C(D
) * _x
+ C(E
) * _y
+ C(F
)) / C(divider
);
121 /* TODO: add jitter (and others) filter */
122 int touchscreen_to_pixels(int x
, int y
, int *data
)
129 if (current_mode
== TOUCHSCREEN_BUTTON
)
131 int column
= 0, row
= 0;
133 if (x
< LCD_WIDTH
/3 - BUTTON_MARGIN_X
)
135 else if (x
> LCD_WIDTH
/3 + BUTTON_MARGIN_X
&&
136 x
< 2*LCD_WIDTH
/3 - BUTTON_MARGIN_X
)
138 else if (x
> 2*LCD_WIDTH
/3 + BUTTON_MARGIN_X
)
143 if (y
< LCD_HEIGHT
/3 - BUTTON_MARGIN_Y
)
145 else if (y
> LCD_HEIGHT
/3 + BUTTON_MARGIN_Y
&&
146 y
< 2*LCD_HEIGHT
/3 - BUTTON_MARGIN_Y
)
148 else if (y
> 2*LCD_HEIGHT
/3 + BUTTON_MARGIN_Y
)
153 return touchscreen_buttons
[row
][column
];
157 *data
= (x
<< 16 | y
);
158 return BUTTON_TOUCHSCREEN
;
162 void touchscreen_set_mode(enum touchscreen_mode mode
)
167 enum touchscreen_mode
touchscreen_get_mode(void)
173 #if ((CONFIG_PLATFORM & PLATFORM_ANDROID) == 0)
174 /* android has an API for this */
176 #define TOUCH_SLOP 16u
177 #define REFERENCE_DPI 160
179 int touchscreen_get_scroll_threshold(void)
182 const int dpi
= LCD_DPI
;
184 const int dpi
= lcd_get_dpi();
187 /* Inspired by Android calculation
189 * float density = real dpi / reference dpi (=160)
190 * int threshold = (int) (density * TOUCH_SLOP + 0.5f);(original calculation)
192 * + 0.5f is for rounding, we use fixed point math to achieve that
195 int result
= dpi
* (TOUCH_SLOP
<<1) / REFERENCE_DPI
;
196 result
+= result
& 1; /* round up if needed */