Permalink
Browse files

Merge branch 'evdev_inversion'

At last! See patches for details, tester for tests.
  • Loading branch information...
tias committed Jun 26, 2012
2 parents 5909553 + 840bb21 commit 62bc3eb1a3fe9541290715116aebccbfdc56577b
Showing with 84 additions and 1 deletion.
  1. +1 −1 src/calibrator.hh
  2. +81 −0 src/calibrator/Evdev.cpp
  3. +2 −0 src/calibrator/Evdev.hpp
View
@@ -171,7 +171,7 @@ public:
/// add a click with the given coordinates
bool add_click(int x, int y);
/// calculate and apply the calibration
bool finish(int width, int height);
virtual bool finish(int width, int height);
/// get the sysfs name of the device,
/// returns NULL if it can not be found
const char* get_sysfs_name();
View
@@ -30,6 +30,7 @@
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 1
@@ -175,6 +176,86 @@ CalibratorEvdev::~CalibratorEvdev () {
XCloseDisplay(display);
}
// From Calibrator but with evdev specific invertion option
// KEEP IN SYNC with Calibrator::finish() !!
bool CalibratorEvdev::finish(int width, int height)
{
if (get_numclicks() != NUM_POINTS) {
return false;
}
// new axis origin and scaling
// based on old_axys: inversion/swapping is relative to the old axis
XYinfo new_axis(old_axys);
// calculate average of clicks
float x_min = (clicked.x[UL] + clicked.x[LL])/2.0;
float x_max = (clicked.x[UR] + clicked.x[LR])/2.0;
float y_min = (clicked.y[UL] + clicked.y[UR])/2.0;
float y_max = (clicked.y[LL] + clicked.y[LR])/2.0;
// When evdev detects an invert_X/Y option,
// it performs the following *crazy* code just before returning
// val = (pEvdev->absinfo[i].maximum - val + pEvdev->absinfo[i].minimum);
// undo this crazy step before doing the regular calibration routine
if (old_axys.x.invert) {
x_min = width - x_min;
x_max = width - x_max;
// avoid invert_x property from here on,
// the calibration code can handle this dynamically!
new_axis.x.invert = false;
}
if (old_axys.y.invert) {
y_min = height - y_min;
y_max = height - y_max;
// avoid invert_y property from here on,
// the calibration code can handle this dynamically!
new_axis.y.invert = false;
}
// end of evdev inversion crazyness
// Should x and y be swapped?
if (abs(clicked.x[UL] - clicked.x[UR]) < abs(clicked.y[UL] - clicked.y[UR])) {
new_axis.swap_xy = !new_axis.swap_xy;
std::swap(x_min, y_min);
std::swap(x_max, y_max);
}
// the screen was divided in num_blocks blocks, and the touch points were at
// one block away from the true edges of the screen.
const float block_x = width/(float)num_blocks;
const float block_y = height/(float)num_blocks;
// rescale these blocks from the range of the drawn touchpoints to the range of the
// actually clicked coordinates, and substract/add from the clicked coordinates
// to obtain the coordinates corresponding to the edges of the screen.
float scale_x = (x_max - x_min)/(width - 2*block_x);
x_min -= block_x * scale_x;
x_max += block_x * scale_x;
float scale_y = (y_max - y_min)/(height - 2*block_y);
y_min -= block_y * scale_y;
y_max += block_y * scale_y;
// now, undo the transformations done by the X server, to obtain the true 'raw' value in X.
// The raw value was scaled from old_axis to the device min/max, and from the device min/max
// to the screen min/max
// hence, the reverse transformation is from screen to old_axis
x_min = scaleAxis(x_min, old_axys.x.max, old_axys.x.min, width, 0);
x_max = scaleAxis(x_max, old_axys.x.max, old_axys.x.min, width, 0);
y_min = scaleAxis(y_min, old_axys.y.max, old_axys.y.min, height, 0);
y_max = scaleAxis(y_max, old_axys.y.max, old_axys.y.min, height, 0);
// round and put in new_axis struct
new_axis.x.min = round(x_min); new_axis.x.max = round(x_max);
new_axis.y.min = round(y_min); new_axis.y.max = round(y_max);
// finish the data, driver/calibrator specific
return finish_data(new_axis);
}
// Activate calibrated data and output it
bool CalibratorEvdev::finish_data(const XYinfo new_axys)
{
View
@@ -58,6 +58,8 @@ class CalibratorEvdev: public Calibrator
const char* geometry=0);
~CalibratorEvdev();
/// calculate and apply the calibration
virtual bool finish(int width, int height);
virtual bool finish_data(const XYinfo new_axys);
bool set_swapxy(const int swap_xy);

0 comments on commit 62bc3eb

Please sign in to comment.