A generic touchscreen calibration program for X.Org
Revision | f984959413ee7f0a2b1004730382f3731a1f47ee (tree) |
---|---|
Time | 2010-01-24 07:16:49 |
Author | Tias Guns <tias@ulys...> |
Commiter | Tias Guns |
make finish() and finish_data() return a boolean
also add comments to calibrator.hh
@@ -48,8 +48,12 @@ bool Calibrator::add_click(double x, double y) | ||
48 | 48 | return true; |
49 | 49 | } |
50 | 50 | |
51 | -void Calibrator::finish(int width, int height) | |
51 | +bool Calibrator::finish(int width, int height) | |
52 | 52 | { |
53 | + if (get_numclicks() != 4) { | |
54 | + return false; | |
55 | + } | |
56 | + | |
53 | 57 | // Should x and y be swapped? |
54 | 58 | const bool swap_xy = (abs (clicked_x [UL] - clicked_x [UR]) < abs (clicked_y [UL] - clicked_y [UR])); |
55 | 59 | if (swap_xy) { |
@@ -83,6 +87,6 @@ void Calibrator::finish(int width, int height) | ||
83 | 87 | std::swap(axys.y_min, axys.x_max); |
84 | 88 | } |
85 | 89 | |
86 | - // finish the data, driver specific | |
87 | - finish_data(axys, swap_xy); | |
90 | + // finish the data, driver/calibrator specific | |
91 | + return finish_data(axys, swap_xy); | |
88 | 92 | } |
@@ -28,19 +28,32 @@ | ||
28 | 28 | class Calibrator |
29 | 29 | { |
30 | 30 | public: |
31 | + /* Constructor for a specific calibrator | |
32 | + * | |
33 | + * The constructor will throw an exception, | |
34 | + * if the touchscreen is not of the type it supports | |
35 | + */ | |
31 | 36 | Calibrator(const char* const drivername, const XYinfo& axys); |
32 | 37 | ~Calibrator() {} |
33 | 38 | |
39 | + // get the number of clicks already registered | |
34 | 40 | int get_numclicks(); |
41 | + // add a click with the given coordinates | |
35 | 42 | bool add_click(double x, double y); |
36 | - void finish(int width, int height); | |
43 | + // calculate and apply the calibration | |
44 | + bool finish(int width, int height); | |
37 | 45 | |
38 | 46 | protected: |
39 | - virtual void finish_data(const XYinfo new_axys, int swap_xy) =0; | |
47 | + // overloaded function that applies the new calibration | |
48 | + virtual bool finish_data(const XYinfo new_axys, int swap_xy) =0; | |
40 | 49 | |
50 | + // name of the device (driver) | |
41 | 51 | const char* const drivername; |
52 | + // original axys values | |
42 | 53 | XYinfo old_axys; |
54 | + // nr of clicks registered | |
43 | 55 | int num_clicks; |
56 | + // click coordinates | |
44 | 57 | double clicked_x[4], clicked_y[4]; |
45 | 58 | }; |
46 | 59 |
@@ -47,7 +47,7 @@ public: | ||
47 | 47 | CalibratorEvdev(const char* const drivername, const XYinfo& axys); |
48 | 48 | ~CalibratorEvdev(); |
49 | 49 | |
50 | - virtual void finish_data(const XYinfo new_axys, int swap_xy); | |
50 | + virtual bool finish_data(const XYinfo new_axys, int swap_xy); | |
51 | 51 | |
52 | 52 | static Bool check_driver(const char* const name); |
53 | 53 |
@@ -121,13 +121,15 @@ CalibratorEvdev::~CalibratorEvdev () { | ||
121 | 121 | XCloseDisplay(display); |
122 | 122 | } |
123 | 123 | |
124 | -void CalibratorEvdev::finish_data(const XYinfo new_axys, int swap_xy) | |
124 | +bool CalibratorEvdev::finish_data(const XYinfo new_axys, int swap_xy) | |
125 | 125 | { |
126 | 126 | printf("\nTo make the settings permanent, create add a startup script for your window manager with the following command(s):\n"); |
127 | 127 | if (swap_xy) |
128 | 128 | printf(" xinput set-int-prop \"%s\" \"Evdev Axes Swap\" 8 %d\n", drivername, swap_xy); |
129 | 129 | printf(" xinput set-int-prop \"%s\" \"Evdev Axis Calibration\" 32 %d %d %d %d\n", drivername, new_axys.x_min, new_axys.x_max, new_axys.y_min, new_axys.y_max); |
130 | 130 | |
131 | + bool success = true; | |
132 | + | |
131 | 133 | printf("\nDoing dynamic recalibration:\n"); |
132 | 134 | // Evdev Axes Swap |
133 | 135 | if (swap_xy) { |
@@ -142,7 +144,8 @@ void CalibratorEvdev::finish_data(const XYinfo new_axys, int swap_xy) | ||
142 | 144 | sprintf(str_swap_xy, "%d", swap_xy); |
143 | 145 | arr_cmd[2] = str_swap_xy; |
144 | 146 | |
145 | - do_set_prop(display, XA_INTEGER, 8, 3, arr_cmd); | |
147 | + int ret = xinput_do_set_prop(display, XA_INTEGER, 8, 3, arr_cmd); | |
148 | + success &= (ret == EXIT_SUCCESS); | |
146 | 149 | } |
147 | 150 | |
148 | 151 | // Evdev Axis Calibration |
@@ -166,10 +169,13 @@ void CalibratorEvdev::finish_data(const XYinfo new_axys, int swap_xy) | ||
166 | 169 | sprintf(str_max_y, "%d", new_axys.y_max); |
167 | 170 | arr_cmd[5] = str_max_y; |
168 | 171 | |
169 | - do_set_prop(display, XA_INTEGER, 32, 6, arr_cmd); | |
172 | + int ret = xinput_do_set_prop(display, XA_INTEGER, 32, 6, arr_cmd); | |
173 | + success &= (ret == EXIT_SUCCESS); | |
170 | 174 | |
171 | 175 | // close |
172 | 176 | XSync(display, False); |
177 | + | |
178 | + return success; | |
173 | 179 | } |
174 | 180 | |
175 | 181 | Bool CalibratorEvdev::check_driver(const char *name) { |
@@ -54,7 +54,7 @@ public: | ||
54 | 54 | CalibratorUsbtouchscreen(const char* const drivername, const XYinfo& axys); |
55 | 55 | ~CalibratorUsbtouchscreen(); |
56 | 56 | |
57 | - virtual void finish_data(const XYinfo new_axys, int swap_xy); | |
57 | + virtual bool finish_data(const XYinfo new_axys, int swap_xy); | |
58 | 58 | |
59 | 59 | protected: |
60 | 60 | // Globals for kernel parameters from startup. |
@@ -156,7 +156,7 @@ CalibratorUsbtouchscreen::~CalibratorUsbtouchscreen() | ||
156 | 156 | write_bool_parameter (p_swap_xy, val_swap_xy); |
157 | 157 | } |
158 | 158 | |
159 | -void CalibratorUsbtouchscreen::finish_data(const XYinfo new_axys, int swap_xy) | |
159 | +bool CalibratorUsbtouchscreen::finish_data(const XYinfo new_axys, int swap_xy) | |
160 | 160 | { |
161 | 161 | // New ranges |
162 | 162 | const int range_x = (new_axys.x_max - new_axys.x_min); |
@@ -183,7 +183,7 @@ void CalibratorUsbtouchscreen::finish_data(const XYinfo new_axys, int swap_xy) | ||
183 | 183 | if (fid == NULL) { |
184 | 184 | fprintf(stderr, "Error: Can't open '%s' for reading. Make sure you have the necesary rights\n", modprobe_conf_local); |
185 | 185 | fprintf(stderr, "New calibration data NOT saved\n"); |
186 | - return; | |
186 | + return false; | |
187 | 187 | } |
188 | 188 | |
189 | 189 | std::string new_contents; |
@@ -213,8 +213,10 @@ void CalibratorUsbtouchscreen::finish_data(const XYinfo new_axys, int swap_xy) | ||
213 | 213 | if (fid == NULL) { |
214 | 214 | fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necesary rights\n", modprobe_conf_local); |
215 | 215 | fprintf(stderr, "New calibration data NOT saved\n"); |
216 | - return; | |
216 | + return false; | |
217 | 217 | } |
218 | 218 | fprintf(fid, "%s", new_contents.c_str ()); |
219 | 219 | fclose(fid); |
220 | + | |
221 | + return true; | |
220 | 222 | } |
@@ -29,7 +29,7 @@ class CalibratorXorgPrint: public Calibrator | ||
29 | 29 | public: |
30 | 30 | CalibratorXorgPrint(const char* const drivername, const XYinfo& axys); |
31 | 31 | |
32 | - virtual void finish_data(const XYinfo new_axys, int swap_xy); | |
32 | + virtual bool finish_data(const XYinfo new_axys, int swap_xy); | |
33 | 33 | }; |
34 | 34 | |
35 | 35 | CalibratorXorgPrint::CalibratorXorgPrint(const char* const drivername0, const XYinfo& axys0) |
@@ -41,7 +41,7 @@ CalibratorXorgPrint::CalibratorXorgPrint(const char* const drivername0, const XY | ||
41 | 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"); |
42 | 42 | } |
43 | 43 | |
44 | -void CalibratorXorgPrint::finish_data(const XYinfo new_axys, int swap_xy) | |
44 | +bool CalibratorXorgPrint::finish_data(const XYinfo new_axys, int swap_xy) | |
45 | 45 | { |
46 | 46 | // FDI policy output |
47 | 47 | printf("\nNew method for making the calibration permanent: create an FDI policy file like /etc/hal/fdi/policy/touchscreen.fdi with:\n\ |
@@ -67,4 +67,6 @@ void CalibratorXorgPrint::finish_data(const XYinfo new_axys, int swap_xy) | ||
67 | 67 | new_axys.y_max, old_axys.y_max); |
68 | 68 | if (swap_xy != 0) |
69 | 69 | printf("\tOption\t\"SwapXY\"\t\"%d\"\n", swap_xy); |
70 | + | |
71 | + return true; | |
70 | 72 | } |
@@ -213,9 +213,15 @@ bool CalibrationArea::on_button_press_event(GdkEventButton *event) | ||
213 | 213 | // Are we done yet? |
214 | 214 | if (calibrator->get_numclicks() >= 4) { |
215 | 215 | // Recalibrate |
216 | - calibrator->finish(display_width, display_height); | |
217 | - | |
218 | - exit(0); | |
216 | + bool success = calibrator->finish(display_width, display_height); | |
217 | + | |
218 | + if (success) { | |
219 | + exit(0); | |
220 | + } else { | |
221 | + // TODO, in GUI ? | |
222 | + fprintf(stderr, "Error: unable to apply or save configuration values"); | |
223 | + exit(1); | |
224 | + } | |
219 | 225 | } |
220 | 226 | |
221 | 227 | // Force a redraw |
@@ -265,9 +265,15 @@ bool GuiCalibratorX11::on_button_press_event(XEvent event) | ||
265 | 265 | // Are we done yet? |
266 | 266 | if (calibrator->get_numclicks() >= 4) { |
267 | 267 | // Recalibrate |
268 | - calibrator->finish(display_width, display_height); | |
269 | - | |
270 | - exit(0); | |
268 | + bool success = calibrator->finish(display_width, display_height); | |
269 | + | |
270 | + if (success) { | |
271 | + exit(0); | |
272 | + } else { | |
273 | + // TODO, in GUI ? | |
274 | + fprintf(stderr, "Error: unable to apply or save configuration values"); | |
275 | + exit(1); | |
276 | + } | |
271 | 277 | } |
272 | 278 | |
273 | 279 | // Force a redraw |