A generic touchscreen calibration program for X.Org
修订版 | 555bdf12ae9c1b87f80bfb55d26b6cd90f55b4aa (tree) |
---|---|
时间 | 2012-06-27 06:05:08 |
作者 | Tias Guns <tias@ulys...> |
Commiter | Tias Guns |
Copy Calibrator::finish() literally to CalibratorEvdev::finish()
@@ -171,7 +171,7 @@ public: | ||
171 | 171 | /// add a click with the given coordinates |
172 | 172 | bool add_click(int x, int y); |
173 | 173 | /// calculate and apply the calibration |
174 | - bool finish(int width, int height); | |
174 | + virtual bool finish(int width, int height); | |
175 | 175 | /// get the sysfs name of the device, |
176 | 176 | /// returns NULL if it can not be found |
177 | 177 | const char* get_sysfs_name(); |
@@ -30,6 +30,7 @@ | ||
30 | 30 | #include <cstdio> |
31 | 31 | #include <cstring> |
32 | 32 | #include <cstdlib> |
33 | +#include <cmath> | |
33 | 34 | |
34 | 35 | #ifndef EXIT_SUCCESS |
35 | 36 | #define EXIT_SUCCESS 1 |
@@ -175,6 +176,64 @@ CalibratorEvdev::~CalibratorEvdev () { | ||
175 | 176 | XCloseDisplay(display); |
176 | 177 | } |
177 | 178 | |
179 | +// From Calibrator but with evdev specific invertion option | |
180 | +// KEEP IN SYNC with Calibrator::finish() !! | |
181 | +bool CalibratorEvdev::finish(int width, int height) | |
182 | +{ | |
183 | + if (get_numclicks() != NUM_POINTS) { | |
184 | + return false; | |
185 | + } | |
186 | + | |
187 | + // new axis origin and scaling | |
188 | + // based on old_axys: inversion/swapping is relative to the old axis | |
189 | + XYinfo new_axis(old_axys); | |
190 | + | |
191 | + | |
192 | + // calculate average of clicks | |
193 | + float x_min = (clicked.x[UL] + clicked.x[LL])/2.0; | |
194 | + float x_max = (clicked.x[UR] + clicked.x[LR])/2.0; | |
195 | + float y_min = (clicked.y[UL] + clicked.y[UR])/2.0; | |
196 | + float y_max = (clicked.y[LL] + clicked.y[LR])/2.0; | |
197 | + | |
198 | + // Should x and y be swapped? | |
199 | + if (abs(clicked.x[UL] - clicked.x[UR]) < abs(clicked.y[UL] - clicked.y[UR])) { | |
200 | + new_axis.swap_xy = !new_axis.swap_xy; | |
201 | + std::swap(x_min, y_min); | |
202 | + std::swap(x_max, y_max); | |
203 | + } | |
204 | + | |
205 | + // the screen was divided in num_blocks blocks, and the touch points were at | |
206 | + // one block away from the true edges of the screen. | |
207 | + const float block_x = width/(float)num_blocks; | |
208 | + const float block_y = height/(float)num_blocks; | |
209 | + // rescale these blocks from the range of the drawn touchpoints to the range of the | |
210 | + // actually clicked coordinates, and substract/add from the clicked coordinates | |
211 | + // to obtain the coordinates corresponding to the edges of the screen. | |
212 | + float scale_x = (x_max - x_min)/(width - 2*block_x); | |
213 | + x_min -= block_x * scale_x; | |
214 | + x_max += block_x * scale_x; | |
215 | + float scale_y = (y_max - y_min)/(height - 2*block_y); | |
216 | + y_min -= block_y * scale_y; | |
217 | + y_max += block_y * scale_y; | |
218 | + | |
219 | + // now, undo the transformations done by the X server, to obtain the true 'raw' value in X. | |
220 | + // The raw value was scaled from old_axis to the device min/max, and from the device min/max | |
221 | + // to the screen min/max | |
222 | + // hence, the reverse transformation is from screen to old_axis | |
223 | + x_min = scaleAxis(x_min, old_axys.x.max, old_axys.x.min, width, 0); | |
224 | + x_max = scaleAxis(x_max, old_axys.x.max, old_axys.x.min, width, 0); | |
225 | + y_min = scaleAxis(y_min, old_axys.y.max, old_axys.y.min, height, 0); | |
226 | + y_max = scaleAxis(y_max, old_axys.y.max, old_axys.y.min, height, 0); | |
227 | + | |
228 | + | |
229 | + // round and put in new_axis struct | |
230 | + new_axis.x.min = round(x_min); new_axis.x.max = round(x_max); | |
231 | + new_axis.y.min = round(y_min); new_axis.y.max = round(y_max); | |
232 | + | |
233 | + // finish the data, driver/calibrator specific | |
234 | + return finish_data(new_axis); | |
235 | +} | |
236 | + | |
178 | 237 | // Activate calibrated data and output it |
179 | 238 | bool CalibratorEvdev::finish_data(const XYinfo new_axys) |
180 | 239 | { |
@@ -58,6 +58,8 @@ public: | ||
58 | 58 | const char* geometry=0); |
59 | 59 | ~CalibratorEvdev(); |
60 | 60 | |
61 | + /// calculate and apply the calibration | |
62 | + virtual bool finish(int width, int height); | |
61 | 63 | virtual bool finish_data(const XYinfo new_axys); |
62 | 64 | |
63 | 65 | bool set_swapxy(const int swap_xy); |