Skip to content

Commit

Permalink
Merge branch 'evdev_emulation_interface'
Browse files Browse the repository at this point in the history
Evdev 2.7.0 tester

It shows that the evdev regression is in the use of the invert_x/invert_y option, together with axis swapping (which is silly, because invert_x/invert_y are options you don't manually need to specify because of the mathematical properties of xf86ScaleAxis)
  • Loading branch information
tias committed Jun 26, 2012
2 parents b0d30f1 + 91e4860 commit bf97fcc
Show file tree
Hide file tree
Showing 10 changed files with 314 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/Makefile.am
Expand Up @@ -51,7 +51,7 @@ xinput_calibrator_CXXFLAGS = $(XINPUT_CFLAGS) $(GTKMM_CFLAGS) $(AM_CXXFLAGS)
xinput_calibrator_LDFLAGS = -Wl,--as-needed xinput_calibrator_LDFLAGS = -Wl,--as-needed
endif endif


tester_SOURCES = tester.cpp calibrator.cpp calibrator/Tester.cpp tester_SOURCES = tester.cpp calibrator.cpp calibrator/Tester.cpp calibrator/Evdev.cpp calibrator/EvdevTester.cpp
tester_LDADD = $(XINPUT_LIBS) $(XRANDR_LIBS) $(X11_LIBS) tester_LDADD = $(XINPUT_LIBS) $(XRANDR_LIBS) $(X11_LIBS)
tester_CXXFLAGS = $(XINPUT_CFLAGS) $(X11_CFLAGS) $(XRANDR_CFLAGS) $(AM_CXXFLAGS) tester_CXXFLAGS = $(XINPUT_CFLAGS) $(X11_CFLAGS) $(XRANDR_CFLAGS) $(AM_CXXFLAGS)


Expand Down
18 changes: 17 additions & 1 deletion src/calibrator.hh
Expand Up @@ -96,7 +96,7 @@ struct XYinfo {
swap_xy = !swap_xy; swap_xy = !swap_xy;
} }


void do_xf86ScaleAxis(XYinfo& to, XYinfo& from) { void do_xf86ScaleAxis(const XYinfo& to, const XYinfo& from) {
x.min = xf86ScaleAxis(x.min, to.x.max, to.x.min, from.x.max, from.x.min); x.min = xf86ScaleAxis(x.min, to.x.max, to.x.min, from.x.max, from.x.min);
x.max = xf86ScaleAxis(x.max, to.x.max, to.x.min, from.x.max, from.x.min); x.max = xf86ScaleAxis(x.max, to.x.max, to.x.min, from.x.max, from.x.min);
y.min = xf86ScaleAxis(y.min, to.y.max, to.y.min, from.y.max, from.y.min); y.min = xf86ScaleAxis(y.min, to.y.max, to.y.min, from.y.max, from.y.min);
Expand Down Expand Up @@ -233,4 +233,20 @@ protected:
const char* geometry; const char* geometry;
}; };


// Interfance for a CalibratorTester
class CalibratorTesterInterface
{
public:
// emulate the driver processing the coordinates in 'raw'
virtual XYinfo emulate_driver(const XYinfo& raw, bool useNewAxis, const XYinfo& screen, const XYinfo& device) = 0;

virtual void new_axis_print() = 0;

//* From Calibrator
/// add a click with the given coordinates
virtual bool add_click(int x, int y) = 0;
/// calculate and apply the calibration
virtual bool finish(int width, int height) = 0;
};

#endif #endif
8 changes: 8 additions & 0 deletions src/calibrator/Evdev.cpp
Expand Up @@ -160,6 +160,14 @@ CalibratorEvdev::CalibratorEvdev(const char* const device_name0,
#endif // HAVE_XI_PROP #endif // HAVE_XI_PROP


} }
// protected pass-through constructor for subclasses
CalibratorEvdev::CalibratorEvdev(const char* const device_name0,
const XYinfo& axys0,
const int thr_misclick,
const int thr_doubleclick,
const OutputType output_type,
const char* geometry)
: Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry) { }


// Destructor // Destructor
CalibratorEvdev::~CalibratorEvdev () { CalibratorEvdev::~CalibratorEvdev () {
Expand Down
20 changes: 17 additions & 3 deletions src/calibrator/Evdev.hpp
Expand Up @@ -38,10 +38,24 @@ class CalibratorEvdev: public Calibrator
XDeviceInfo *devInfo; XDeviceInfo *devInfo;
XDevice *dev; XDevice *dev;


protected:
// protected constructor: should only be used by subclasses!
// (pass-through to Calibrator)
CalibratorEvdev(const char* const device_name,
const XYinfo& axys,
const int thr_misclick=0,
const int thr_doubleclick=0,
const OutputType output_type=OUTYPE_AUTO,
const char* geometry=0);

public: public:
CalibratorEvdev(const char* const device_name, const XYinfo& axys, CalibratorEvdev(const char* const device_name,
XID device_id=(XID)-1, const int thr_misclick=0, const int thr_doubleclick=0, const XYinfo& axys,
const OutputType output_type=OUTYPE_AUTO, const char* geometry=0); XID device_id=(XID)-1,
const int thr_misclick=0,
const int thr_doubleclick=0,
const OutputType output_type=OUTYPE_AUTO,
const char* geometry=0);
~CalibratorEvdev(); ~CalibratorEvdev();


virtual bool finish_data(const XYinfo new_axys); virtual bool finish_data(const XYinfo new_axys);
Expand Down
163 changes: 163 additions & 0 deletions src/calibrator/EvdevTester.cpp
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2009 Tias Guns
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "calibrator/Evdev.hpp"
#include "calibrator/EvdevTester.hpp"

#include <cstdio>

CalibratorEvdevTester::CalibratorEvdevTester(const char* const device_name0, const XYinfo& axys0, const int thr_misclick, const int thr_doubleclick, const OutputType output_type, const char* geometry)
: CalibratorEvdev(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry)
{
//printf("Starting test driver\n");
}

bool CalibratorEvdevTester::finish_data(const XYinfo axis)
{
new_axis = axis;

return true;
}

XYinfo CalibratorEvdevTester::emulate_driver(const XYinfo& raw, bool useNewAxis, const XYinfo& screen, const XYinfo& device) {
XYinfo calibAxis;
if (useNewAxis)
calibAxis = new_axis;
else
calibAxis = old_axys;

// call evdev's code (minimally modified to fit us)
int mins[2] = {raw.x.min, raw.y.min};
evdev_270_processvaluator(device, calibAxis, mins);
int maxs[2] = {raw.x.max, raw.y.max};
evdev_270_processvaluator(device, calibAxis, maxs);

XYinfo result(mins[0], maxs[0], mins[1], maxs[1]);


// the last step is usually done by the X server,
// or transparently somewhere on the way
result.do_xf86ScaleAxis(screen, device);
return result;
}

// return in 'vals'
void CalibratorEvdevTester::evdev_270_processvaluator(const XYinfo& devAxis, const XYinfo& axis, int* vals)
{
//int vals[2] = {valX, valY};
int absinfo_min[2] = {devAxis.x.min, devAxis.y.min};
int absinfo_max[2] = {devAxis.x.max, devAxis.y.max};

/*
* Code from xf86-input-evdev: src/evdev.c
* function: static void EvdevProcessValuators(InputInfoPtr pInfo)
* last change: 2011-12-14 'Fix absolute events with swapped axes'
* last change id: 8d6dfd13b0c4177305555294218e366a6cddc83f
*
* All valuator_mask_isset() test can be skipped here:
* its a requirement to have both X and Y coordinates
*/
int i;

// if (pEvdev->swap_axes) {
if (axis.swap_xy) {
int swapped_isset[2] = {0, 0};
int swapped_values[2];

for(i = 0; i <= 1; i++) {
//if (valuator_mask_isset(pEvdev->vals, i)) {
swapped_isset[1 - i] = 1;

/* in all sensible cases, the absinfo is the same for the
* X and Y axis. In that case, the below simplifies to:
* wapped_values[1 - i] = vals[i]
* However, the code below accounts for the oddball
* device for which this would not be the case.
*/
swapped_values[1 - i] =
//xf86ScaleAxis(valuator_mask_get(pEvdev->vals, i),
// pEvdev->absinfo[1 - i].maximum,
// pEvdev->absinfo[1 - i].minimum,
// pEvdev->absinfo[i].maximum,
// pEvdev->absinfo[i].minimum);
xf86ScaleAxis(vals[i],
absinfo_max[1 - i],
absinfo_min[1 - i],
absinfo_max[i],
absinfo_min[i]);
//}
}

for (i = 0; i <= 1; i++) {
if (swapped_isset[i])
//valuator_mask_set(pEvdev->vals, i, swapped_values[i]);
vals[i] = swapped_values[i];
//else
// valuator_mask_unset(pEvdev->vals, i);
}
}

for (i = 0; i <= 1; i++) {
int val;
int calib_min;
int calib_max;

//if (!valuator_mask_isset(pEvdev->vals, i))
// continue;

//val = valuator_mask_get(pEvdev->vals, i);
val = vals[i];

if (i == 0) {
//calib_min = pEvdev->calibration.min_x;
calib_min = axis.x.min;
//calib_max = pEvdev->calibration.max_x;
calib_max = axis.x.max;
} else {
//calib_min = pEvdev->calibration.min_y;
calib_min = axis.y.min;
//calib_max = pEvdev->calibration.max_y;
calib_max = axis.y.max;
}

//if (pEvdev->flags & EVDEV_CALIBRATED)
if (true)
//val = xf86ScaleAxis(val, pEvdev->absinfo[i].maximum,
// pEvdev->absinfo[i].minimum, calib_max,
// calib_min);
val = xf86ScaleAxis(val, absinfo_max[i],
absinfo_min[i], calib_max,
calib_min);

//if ((i == 0 && pEvdev->invert_x) || (i == 1 && pEvdev->invert_y))
if ((i == 0 && axis.x.invert) || (i == 1 && axis.y.invert))
//val = (pEvdev->absinfo[i].maximum - val +
// pEvdev->absinfo[i].minimum);
val = (absinfo_max[i] - val +
absinfo_min[i]);

//valuator_mask_set(pEvdev->vals, i, val);
vals[i] = val;
}

//return vals;
}
65 changes: 65 additions & 0 deletions src/calibrator/EvdevTester.hpp
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2009 Tias Guns
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef CALIBRATOR_EVDEV_TESTER_HPP
#define CALIBRATOR_EVDEV_TESTER_HPP

#include "calibrator.hh"
#include "calibrator/Evdev.hpp"

/***************************************
* Class for testing the evdev
* calibration routine
***************************************/
class CalibratorEvdevTester: public CalibratorTesterInterface, public CalibratorEvdev
{
protected:
// store the new axis for use in driver emulation
XYinfo new_axis;

public:
CalibratorEvdevTester(const char* const device_name, const XYinfo& axys,
const int thr_misclick=0, const int thr_doubleclick=0,
const OutputType output_type=OUTYPE_AUTO, const char* geometry=0);

virtual bool finish_data(const XYinfo new_axis);

// emulate the driver processing the coordinates in 'raw'
virtual XYinfo emulate_driver(const XYinfo& raw, bool useNewAxis, const XYinfo& screen, const XYinfo& device);

virtual void new_axis_print() {
new_axis.print();
}

//* From CalibratorEvdev
virtual bool add_click(int x, int y) {
return CalibratorEvdev::add_click(x, y);
}
virtual bool finish(int width, int height) {
return CalibratorEvdev::finish(width, height);
}

// evdev 2.7.0 EvdevProcessValuators code, modified to fit us
void evdev_270_processvaluator(const XYinfo& devAxis, const XYinfo& axis, int* vals);
};

#endif
3 changes: 2 additions & 1 deletion src/calibrator/Makefile.am
Expand Up @@ -2,4 +2,5 @@ EXTRA_DIST = \
Evdev.cpp \ Evdev.cpp \
Usbtouchscreen.cpp \ Usbtouchscreen.cpp \
XorgPrint.cpp \ XorgPrint.cpp \
Tester.cpp Tester.cpp \
EvdevTester.cpp
2 changes: 1 addition & 1 deletion src/calibrator/Tester.cpp
Expand Up @@ -37,7 +37,7 @@ bool CalibratorTester::finish_data(const XYinfo axis)
return true; return true;
} }


XYinfo CalibratorTester::emulate_driver(XYinfo& raw, bool useNewAxis, XYinfo screen, XYinfo device) { XYinfo CalibratorTester::emulate_driver(const XYinfo& raw, bool useNewAxis, const XYinfo& screen, const XYinfo& device) {
XYinfo calibAxis; XYinfo calibAxis;
if (useNewAxis) if (useNewAxis)
calibAxis = new_axis; calibAxis = new_axis;
Expand Down
21 changes: 16 additions & 5 deletions src/calibrator/Tester.hpp
Expand Up @@ -26,10 +26,10 @@
#include "calibrator.hh" #include "calibrator.hh"


/*************************************** /***************************************
* Class for generic Xorg driver, * Class for testing the generic
* outputs new Xorg.conf and FDI policy, on stdout * calibration routine
***************************************/ ***************************************/
class CalibratorTester: public Calibrator class CalibratorTester: public CalibratorTesterInterface, public Calibrator
{ {
protected: protected:
// store the new axis for use in driver emulation // store the new axis for use in driver emulation
Expand All @@ -43,11 +43,22 @@ class CalibratorTester: public Calibrator
virtual bool finish_data(const XYinfo new_axis); virtual bool finish_data(const XYinfo new_axis);


// emulate the driver processing the coordinates in 'raw' // emulate the driver processing the coordinates in 'raw'
XYinfo emulate_driver(XYinfo& raw, bool useNewAxis, XYinfo screen, XYinfo device); virtual XYinfo emulate_driver(const XYinfo& raw,
bool useNewAxis,
const XYinfo& screen,
const XYinfo& device);


void new_axis_print() { virtual void new_axis_print() {
new_axis.print(); new_axis.print();
} }

//* From Calibrator
virtual bool add_click(int x, int y) {
return Calibrator::add_click(x, y);
}
virtual bool finish(int width, int height) {
return Calibrator::finish(width, height);
}
}; };


#endif #endif

0 comments on commit bf97fcc

Please sign in to comment.