Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for --no-timeout and compiler warnings #45

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 48 additions & 52 deletions src/calibrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,31 +144,42 @@ bool Calibrator::finish(int width, int height)
// 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;

// Should x and y be swapped?
bool swap_axes = false;
if (abs(clicked.x[UL] - clicked.x[UR]) < abs(clicked.y[UL] - clicked.y[UR])) {
swap_axes = true;
new_axis.swap_xy = !new_axis.swap_xy;
std::swap(x_min, y_min);
std::swap(x_max, y_max);

// These swaps result in a reflection of the clicks, about the line x=y.
std::swap(clicked.x[LL], clicked.x[UR]);
std::swap(clicked.y[LL], clicked.y[UR]);
}

// calculate average of clicks
double x_min = (clicked.x[UL] + clicked.x[LL])/2.0;
double x_max = (clicked.x[UR] + clicked.x[LR])/2.0;
double y_min = (clicked.y[UL] + clicked.y[UR])/2.0;
double y_max = (clicked.y[LL] + clicked.y[LR])/2.0;

// This has an empty implementation here, but derived classes
// may implement it to modify {x,y}_* and new_axis as needed.
// See Evdev.cpp which uses this routine to compensate for
// calculations done within the evdev device.
compensateForDevice( width, height, x_min, y_min, x_max, y_max, new_axis );

// 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;
const double block_x = width/(double)num_blocks;
const double block_y = height/(double)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);
double 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);

double scale_y = (y_max - y_min)/(height - 2*block_y);
y_min -= block_y * scale_y;
y_max += block_y * scale_y;

Expand All @@ -181,6 +192,10 @@ bool Calibrator::finish(int width, int height)
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);

if ( swap_axes ) {
std::swap( x_min, y_min );
std::swap( x_max, y_max );
}

// round and put in new_axis struct
new_axis.x.min = round(x_min); new_axis.x.max = round(x_max);
Expand Down Expand Up @@ -260,6 +275,19 @@ bool Calibrator::has_xorgconfd_support(Display* dpy) {
return has_support;
}

int
xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min)
{
double X = scaleAxis(Cx, to_max, to_min, from_max, from_min);

if (X > to_max)
X = to_max;
if (X < to_min)
X = to_min;

return (int)X;
}

/*
* FROM xf86Xinput.c
*
Expand All @@ -277,53 +305,21 @@ bool Calibrator::has_xorgconfd_support(Display* dpy) {
* e.g. to scale from device coordinates into screen coordinates, call
* xf86ScaleAxis(x, 0, screen_width, dev_min, dev_max);
*/
int
xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min)
double
scaleAxis(double Cx, int to_max, int to_min, int from_max, int from_min)
{
int X;
int64_t to_width = to_max - to_min;
int64_t from_width = from_max - from_min;

if (from_width) {
X = (int) (((to_width * (Cx - from_min)) / from_width) + to_min);
}
else {
X = 0;
printf("Divide by Zero in xf86ScaleAxis\n");
exit(1);
}

if (X > to_max)
X = to_max;
if (X < to_min)
X = to_min;
double X;
double to_width = to_max - to_min;
double from_width = from_max - from_min;

return X;
}

// same but without rounding to min/max
float
scaleAxis(float Cx, int to_max, int to_min, int from_max, int from_min)
{
float X;
int64_t to_width = to_max - to_min;
int64_t from_width = from_max - from_min;

if (from_width) {
if (from_max - from_min) {
X = (((to_width * (Cx - from_min)) / from_width) + to_min);
}
else {
X = 0;
X = 0.0;
printf("Divide by Zero in scaleAxis\n");
exit(1);
}

/* no rounding to max/min
if (X > to_max)
X = to_max;
if (X < to_min)
X = to_min;
*/

return X;
}
41 changes: 38 additions & 3 deletions src/calibrator.hh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include <vector>

int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min);
float scaleAxis(float Cx, int to_max, int to_min, int from_max, int from_min);
double scaleAxis(double Cx, int to_max, int to_min, int from_max, int from_min);

/*
* Number of blocks. We partition the screen into 'num_blocks' x 'num_blocks'
Expand Down Expand Up @@ -147,7 +147,7 @@ public:
const char* geometry=0,
const bool use_timeout=1);

~Calibrator() {}
virtual ~Calibrator() {}

/// set the doubleclick treshold
void set_threshold_doubleclick(int t)
Expand All @@ -171,8 +171,43 @@ public:

/// add a click with the given coordinates
bool add_click(int x, int y);

// Called by base class finish() method.
// Allows for derived class specific "adjustments" to be made
// just prior to the scaling and calibration calculations being
// performed.
//
// @param width
// The screen width, in pixels, as passed to calibrator::finish()
//
// @param height
// The screen height, in pixels, as passed to calibrator::finish()
//
// @param x_min
// The mean minimum x coordinate. Calculated in Calibrator::finish()
// like so: double x_min = (clicked.x[UL] + clicked.x[LL])/2.0;
//
// @param y_min
// The mean minimum y coordinate. Calculated in Calibrator::finish()
// like so: double y_min = (clicked.y[UL] + clicked.y[UR])/2.0;
//
// @param x_max
// The mean maximum x coordinate. Calculated in Calibrator::finish()
// like so: double x_max = (clicked.x[UR] + clicked.x[LR])/2.0;
//
// @param y_max
// The mean maximum x coordinate. Calculated in Calibrator::finish()
// like so: double y_max = (clicked.y[LL] + clicked.y[LR])/2.0;
//
// @param new_axis
// The axes calibration data, of type XYinfo, being set by calibrator:finish().
// This is ultimately passed as an arg to finish_data().
virtual void compensateForDevice( int width, int height, double &x_min, double &y_min,
double &x_max, double &y_max, XYinfo &new_axis ) {}

/// calculate and apply the calibration
virtual bool finish(int width, int height);
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();
Expand Down
96 changes: 39 additions & 57 deletions src/calibrator/Evdev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,84 +175,66 @@ 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)

// Called by base class finish() method.
// Allows for derived class specific "adjustments" to be made
// just prior to the scaling and calibration calculations being
// performed.
//
// @param width
// The screen width, in pixels, as passed to calibrator::finish()
//
// @param height
// The screen height, in pixels, as passed to calibrator::finish()
//
// @param x_min
// The mean minimum x coordinate. Calculated in Calibrator::finish()
// like so: float x_min = (clicked.x[UL] + clicked.x[LL])/2.0;
//
// @param y_min
// The mean minimum y coordinate. Calculated in Calibrator::finish()
// like so: float y_min = (clicked.y[UL] + clicked.y[UR])/2.0;
//
// @param x_max
// The mean maximum x coordinate. Calculated in Calibrator::finish()
// like so: float x_max = (clicked.x[UR] + clicked.x[LR])/2.0;
//
// @param y_max
// The mean maximum x coordinate. Calculated in Calibrator::finish()
// like so: float y_max = (clicked.y[LL] + clicked.y[LR])/2.0;
//
// @param new_axis
// The axes calibration data, of type XYinfo, being set by calibrator:finish().
// This is ultimately passed as an arg to finish_data().
void CalibratorEvdev::compensateForDevice( int width, int height, double &x_min,
double &y_min, double &x_max,
double &y_max, XYinfo &new_axis )
{
if (get_numclicks() != NUM_POINTS) {
return false;
if ( verbose ) {
printf( "DEBUG: compensating for evdev \"crazy\" code." );
}

// 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
Expand Down
34 changes: 33 additions & 1 deletion src/calibrator/Evdev.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,40 @@ class CalibratorEvdev: public Calibrator
const bool use_timeout=false);
~CalibratorEvdev();

// Called by base class finish() method.
// Allows for derived class specific "adjustments" to be made
// just prior to the scaling and calibration calculations being
// performed.
//
// @param width
// The screen width, in pixels, as passed to calibrator::finish()
//
// @param height
// The screen height, in pixels, as passed to calibrator::finish()
//
// @param x_min
// The mean minimum x coordinate. Calculated in Calibrator::finish()
// like so: double x_min = (clicked.x[UL] + clicked.x[LL])/2.0;
//
// @param y_min
// The mean minimum y coordinate. Calculated in Calibrator::finish()
// like so: double y_min = (clicked.y[UL] + clicked.y[UR])/2.0;
//
// @param x_max
// The mean maximum x coordinate. Calculated in Calibrator::finish()
// like so: double x_max = (clicked.x[UR] + clicked.x[LR])/2.0;
//
// @param y_max
// The mean maximum x coordinate. Calculated in Calibrator::finish()
// like so: double y_max = (clicked.y[LL] + clicked.y[LR])/2.0;
//
// @param new_axis
// The axes calibration data, of type XYinfo, being set by calibrator:finish().
// This is ultimately passed as an arg to finish_data().
virtual void compensateForDevice( int width, int height, double &x_min, double &y_min,
double &x_max, double &y_max, XYinfo &new_axis );

/// 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);
Expand Down
Loading