A generic touchscreen calibration program for X.Org
Revision | 5a0f5d1eda1a814d7690af3291b3323f41277ce8 (tree) |
---|---|
Time | 2010-01-24 07:17:38 |
Author | Tias Guns <tias@ulys...> |
Commiter | Tias Guns |
use exceptions to detect if a calibrator is applicable or not
A constructor will throw a custom exception if it is not applicable,
this reduces code duplication in the evdev calibrator.
Also cleaned up the messages in the constructors.
@@ -49,8 +49,6 @@ public: | ||
49 | 49 | |
50 | 50 | virtual bool finish_data(const XYinfo new_axys, int swap_xy); |
51 | 51 | |
52 | - static Bool check_driver(const char* const name); | |
53 | - | |
54 | 52 | // xinput functions (from the xinput source) |
55 | 53 | static Atom parse_atom(Display *display, const char* name); |
56 | 54 | static XDeviceInfo* find_device_info(Display *display, const char* name, Bool only_extended); |
@@ -60,42 +58,48 @@ public: | ||
60 | 58 | CalibratorEvdev::CalibratorEvdev(const char* const drivername0, const XYinfo& axys0) |
61 | 59 | : Calibrator(drivername0, axys0) |
62 | 60 | { |
63 | - printf("Calibrating EVDEV driver for \"%s\"\n", drivername); | |
64 | - | |
65 | 61 | // init |
66 | 62 | display = XOpenDisplay(NULL); |
67 | 63 | if (display == NULL) { |
68 | - fprintf(stderr, "Unable to connect to X server\n"); | |
69 | - return; | |
64 | + throw WrongCalibratorException("Evdev: Unable to connect to X server"); | |
70 | 65 | } |
71 | 66 | |
72 | 67 | info = find_device_info(display, drivername, False); |
73 | 68 | if (!info) { |
74 | - fprintf(stderr, "unable to find device %s\n", drivername); | |
75 | - return; | |
69 | + XCloseDisplay(display); | |
70 | + throw WrongCalibratorException("Evdev: Unable to find device"); | |
76 | 71 | } |
77 | 72 | |
78 | 73 | dev = XOpenDevice(display, info->id); |
79 | 74 | if (!dev) { |
80 | - fprintf(stderr, "unable to open device '%s'\n", info->name); | |
81 | - return; | |
75 | + XCloseDisplay(display); | |
76 | + throw WrongCalibratorException("Evdev: Unable to open device"); | |
82 | 77 | } |
83 | 78 | |
84 | - // get "Evdev Axis Calibration" property | |
85 | - Atom property = parse_atom(display, "Evdev Axis Calibration"); | |
79 | + // XGetDeviceProperty vars | |
80 | + Atom property; | |
86 | 81 | Atom act_type; |
87 | 82 | int act_format; |
88 | 83 | unsigned long nitems, bytes_after; |
89 | 84 | unsigned char *data, *ptr; |
85 | + | |
86 | + // get "Evdev Axis Calibration" property | |
87 | + property = parse_atom(display, "Evdev Axis Calibration"); | |
90 | 88 | if (XGetDeviceProperty(display, dev, property, 0, 1000, False, |
91 | 89 | AnyPropertyType, &act_type, &act_format, |
92 | - &nitems, &bytes_after, &data) == Success) | |
90 | + &nitems, &bytes_after, &data) != Success) | |
93 | 91 | { |
92 | + XCloseDevice(display, dev); | |
93 | + XCloseDisplay(display); | |
94 | + throw WrongCalibratorException("Evdev: \"Evdev Axis Calibration\" property missing, not a (valid) evdev device"); | |
95 | + | |
96 | + } else { | |
94 | 97 | if (act_format != 32 || act_type != XA_INTEGER) { |
95 | - fprintf(stderr, "Error: unexpected format or type from \"Evdev Axis Calibration\" property.\n"); | |
96 | - } | |
98 | + XCloseDevice(display, dev); | |
99 | + XCloseDisplay(display); | |
100 | + throw WrongCalibratorException("Evdev: invalid \"Evdev Axis Calibration\" property format"); | |
97 | 101 | |
98 | - if (nitems != 0) { | |
102 | + } else if (nitems != 0) { | |
99 | 103 | ptr = data; |
100 | 104 | |
101 | 105 | old_axys.x_min = *((long*)ptr); |
@@ -106,14 +110,16 @@ CalibratorEvdev::CalibratorEvdev(const char* const drivername0, const XYinfo& ax | ||
106 | 110 | ptr += sizeof(long); |
107 | 111 | old_axys.y_max = *((long*)ptr); |
108 | 112 | ptr += sizeof(long); |
109 | - | |
110 | - printf("Read current calibration data from XInput: min_x=%d, max_x=%d and min_y=%d, max_y=%d\n", | |
111 | - old_axys.x_min, old_axys.x_max, old_axys.y_min, old_axys.y_max); | |
112 | 113 | } |
113 | 114 | |
114 | 115 | XFree(data); |
115 | - } else | |
116 | - printf("\tFetch failure for 'Evdev Axis Calibration', continuing nonetheless\n"); | |
116 | + } | |
117 | + | |
118 | + // TODO: swap_xy and flip_x/flip_y stuff | |
119 | + | |
120 | + printf("Calibrating EVDEV driver for \"%s\"\n", drivername); | |
121 | + printf("\tcurrent calibration values (from XInput): min_x=%d, max_x=%d and min_y=%d, max_y=%d\n", | |
122 | + old_axys.x_min, old_axys.x_max, old_axys.y_min, old_axys.y_max); | |
117 | 123 | } |
118 | 124 | |
119 | 125 | CalibratorEvdev::~CalibratorEvdev () { |
@@ -178,62 +184,6 @@ bool CalibratorEvdev::finish_data(const XYinfo new_axys, int swap_xy) | ||
178 | 184 | return success; |
179 | 185 | } |
180 | 186 | |
181 | -Bool CalibratorEvdev::check_driver(const char *name) { | |
182 | - Display *display; | |
183 | - XDeviceInfo *info; | |
184 | - XDevice *dev; | |
185 | - int nprops; | |
186 | - Atom *props; | |
187 | - Bool found = False; | |
188 | - | |
189 | - display = XOpenDisplay(NULL); | |
190 | - if (display == NULL) { | |
191 | - //fprintf(stderr, "Unable to connect to X server"); | |
192 | - return false; | |
193 | - } | |
194 | - | |
195 | - info = find_device_info(display, name, False); | |
196 | - if (!info) | |
197 | - { | |
198 | - XCloseDisplay(display); | |
199 | - //fprintf(stderr, "unable to find device %s\n", name); | |
200 | - return false; | |
201 | - } | |
202 | - | |
203 | - dev = XOpenDevice(display, info->id); | |
204 | - if (!dev) | |
205 | - { | |
206 | - XCloseDisplay(display); | |
207 | - //fprintf(stderr, "unable to open device '%s'\n", info->name); | |
208 | - return false; | |
209 | - } | |
210 | - | |
211 | - props = XListDeviceProperties(display, dev, &nprops); | |
212 | - if (!nprops) | |
213 | - { | |
214 | - XCloseDevice(display, dev); | |
215 | - XCloseDisplay(display); | |
216 | - //printf("Device '%s' does not report any properties.\n", info->name); | |
217 | - return false; | |
218 | - } | |
219 | - | |
220 | - // check if "Evdev Axis Calibration" exists, then its an evdev driver | |
221 | - while(nprops--) | |
222 | - { | |
223 | - if (strcmp(XGetAtomName(display, props[nprops]), | |
224 | - "Evdev Axis Calibration") == 0) { | |
225 | - found = True; | |
226 | - break; | |
227 | - } | |
228 | - } | |
229 | - | |
230 | - XFree(props); | |
231 | - XCloseDevice(display, dev); | |
232 | - XCloseDisplay(display); | |
233 | - | |
234 | - return found; | |
235 | -} | |
236 | - | |
237 | 187 | Atom CalibratorEvdev::parse_atom(Display *display, const char *name) { |
238 | 188 | Bool is_atom = True; |
239 | 189 | int i; |
@@ -135,6 +135,9 @@ protected: | ||
135 | 135 | CalibratorUsbtouchscreen::CalibratorUsbtouchscreen(const char* const drivername0, const XYinfo& axys0) |
136 | 136 | : Calibrator(drivername0, axys0) |
137 | 137 | { |
138 | + if (strcmp(drivername, "Usbtouchscreen") != 0) | |
139 | + throw WrongCalibratorException("Not a usbtouchscreen device"); | |
140 | + | |
138 | 141 | // Reset the currently running kernel |
139 | 142 | read_bool_parameter(p_transform_xy, val_transform_xy); |
140 | 143 | read_bool_parameter(p_flip_x, val_flip_x); |
@@ -145,6 +148,8 @@ CalibratorUsbtouchscreen::CalibratorUsbtouchscreen(const char* const drivername0 | ||
145 | 148 | write_bool_parameter(p_flip_x, false); |
146 | 149 | write_bool_parameter(p_flip_y, false); |
147 | 150 | write_bool_parameter(p_swap_xy, false); |
151 | + | |
152 | + printf("Calibrating Usbtouchscreen, through the kernel module\n"); | |
148 | 153 | } |
149 | 154 | |
150 | 155 | CalibratorUsbtouchscreen::~CalibratorUsbtouchscreen() |
@@ -35,10 +35,10 @@ public: | ||
35 | 35 | CalibratorXorgPrint::CalibratorXorgPrint(const char* const drivername0, const XYinfo& axys0) |
36 | 36 | : Calibrator(drivername0, axys0) |
37 | 37 | { |
38 | - printf ("Calibrating Xorg driver \"%s\" (currently having min_x=%d, max_x=%d and min_y=%d, max_y=%d)\n", | |
39 | - drivername, old_axys.x_min, old_axys.x_max, | |
40 | - old_axys.y_min, old_axys.y_max); | |
41 | - printf("\tIf the current calibration data is estimated wrong then either supply it manually with --precalib <minx> <maxx> <miny> <maxy> or run the 'get_precalib.sh' script to automatically get it from your current Xorg configuration (through hal).\n"); | |
38 | + printf("Calibrating standard Xorg driver \"%s\"\n", drivername); | |
39 | + printf("\tcurrent calibration values: min_x=%d, max_x=%d and min_y=%d, max_y=%d\n", | |
40 | + old_axys.x_min, old_axys.x_max, old_axys.y_min, old_axys.y_max); | |
41 | + printf("\tIf these values are estimated wrong, either supply it manually with the --precalib option, or run the 'get_precalib.sh' script to automatically get it (through HAL).\n"); | |
42 | 42 | } |
43 | 43 | |
44 | 44 | bool CalibratorXorgPrint::finish_data(const XYinfo new_axys, int swap_xy) |
@@ -79,6 +79,12 @@ struct XYinfo { | ||
79 | 79 | x_min(xmi), x_max(xma), y_min(ymi), y_max(yma) {} |
80 | 80 | }; |
81 | 81 | |
82 | +class WrongCalibratorException : public std::invalid_argument { | |
83 | + public: | |
84 | + WrongCalibratorException(const std::string& msg = "") : | |
85 | + std::invalid_argument(msg) {} | |
86 | +}; | |
87 | + | |
82 | 88 | // all need struct XYinfo, and some the consts too |
83 | 89 | #include "calibrator.cpp" |
84 | 90 | #include "calibrators/calibratorXorgPrint.cpp" |
@@ -227,21 +233,26 @@ Calibrator* main_common(int argc, char** argv) | ||
227 | 233 | axys.y_max = pre_axys.y_max; |
228 | 234 | } |
229 | 235 | |
230 | - Calibrator* calibrator; | |
236 | + | |
231 | 237 | // Different driver, different backend behaviour |
232 | - if (strcmp(drivername, "Usbtouchscreen") == 0) | |
238 | + try { | |
233 | 239 | // Usbtouchscreen driver |
234 | - calibrator = new CalibratorUsbtouchscreen(drivername, axys); | |
235 | - else { | |
236 | - // unable to know device driver from its name alone | |
237 | - // either its EVDEV or a normal Xorg touchscreen driver | |
238 | - if (CalibratorEvdev::check_driver(drivername)) { | |
239 | - // Evdev driver | |
240 | - calibrator = new CalibratorEvdev(drivername, axys); | |
241 | - } else { | |
242 | - // EVTouch is handled as a normal Xorg driver | |
243 | - calibrator = new CalibratorXorgPrint(drivername, axys); | |
244 | - } | |
240 | + return new CalibratorUsbtouchscreen(drivername, axys); | |
241 | + | |
242 | + } catch(WrongCalibratorException& x) { | |
243 | + // TODO: verbose output | |
244 | + //printf("%s\n", x.what()); | |
245 | 245 | } |
246 | - return calibrator; | |
246 | + | |
247 | + try { | |
248 | + // next, try Evdev driver | |
249 | + return new CalibratorEvdev(drivername, axys); | |
250 | + | |
251 | + } catch(WrongCalibratorException& x) { | |
252 | + // TODO: verbose output | |
253 | + //printf("%s\n", x.what()); | |
254 | + } | |
255 | + | |
256 | + // lastly, presume a standard Xorg driver (evtouch, mutouch, ...) | |
257 | + return new CalibratorXorgPrint(drivername, axys); | |
247 | 258 | } |