A generic touchscreen calibration program for X.Org
修订版 | 6ca429f54c523268e87c76395bbd2a822d7d04d3 (tree) |
---|---|
时间 | 2013-02-08 05:32:56 |
作者 | Tias Guns <tias@ulys...> |
Commiter | Tias Guns |
Merge pull request #47 from schnitzeltony/write-file-param
Add a new parameter --output-filename
@@ -37,10 +37,11 @@ bool Calibrator::verbose = false; | ||
37 | 37 | Calibrator::Calibrator(const char* const device_name0, const XYinfo& axys0, |
38 | 38 | const int thr_misclick, const int thr_doubleclick, |
39 | 39 | const OutputType output_type0, const char* geometry0, |
40 | - const bool use_timeout0) | |
40 | + const bool use_timeout0, const char* output_filename0) | |
41 | 41 | : device_name(device_name0), |
42 | 42 | threshold_doubleclick(thr_doubleclick), threshold_misclick(thr_misclick), |
43 | - output_type(output_type0), geometry(geometry0), use_timeout(use_timeout0) | |
43 | + output_type(output_type0), geometry(geometry0), use_timeout(use_timeout0), | |
44 | + output_filename(output_filename0) | |
44 | 45 | { |
45 | 46 | old_axys = axys0; |
46 | 47 |
@@ -30,6 +30,9 @@ | ||
30 | 30 | #include <stdio.h> |
31 | 31 | #include <vector> |
32 | 32 | |
33 | +// XXX: we currently don't handle lines that are longer than this | |
34 | +#define MAX_LINE_LEN 1024 | |
35 | + | |
33 | 36 | int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min); |
34 | 37 | float scaleAxis(float Cx, int to_max, int to_min, int from_max, int from_min); |
35 | 38 |
@@ -145,9 +148,10 @@ public: | ||
145 | 148 | const int thr_doubleclick=0, |
146 | 149 | const OutputType output_type=OUTYPE_AUTO, |
147 | 150 | const char* geometry=0, |
148 | - const bool use_timeout=1); | |
151 | + const bool use_timeout=1, | |
152 | + const char* output_filename = 0); | |
149 | 153 | |
150 | - ~Calibrator() {} | |
154 | + virtual ~Calibrator() {} | |
151 | 155 | |
152 | 156 | /// set the doubleclick treshold |
153 | 157 | void set_threshold_doubleclick(int t) |
@@ -180,6 +184,10 @@ public: | ||
180 | 184 | const bool get_use_timeout() const |
181 | 185 | { return use_timeout; } |
182 | 186 | |
187 | + /// get output filename set at cmdline or NULL | |
188 | + const char* get_output_filename() const | |
189 | + { return output_filename; } | |
190 | + | |
183 | 191 | protected: |
184 | 192 | /// check whether the coordinates are along the respective axis |
185 | 193 | bool along_axis(int xy, int x0, int y0); |
@@ -230,6 +238,9 @@ protected: | ||
230 | 238 | const char* geometry; |
231 | 239 | |
232 | 240 | const bool use_timeout; |
241 | + | |
242 | + // manually specified output filename | |
243 | + const char* output_filename; | |
233 | 244 | }; |
234 | 245 | |
235 | 246 | // Interfance for a CalibratorTester |
@@ -47,8 +47,9 @@ CalibratorEvdev::CalibratorEvdev(const char* const device_name0, | ||
47 | 47 | const int thr_doubleclick, |
48 | 48 | const OutputType output_type, |
49 | 49 | const char* geometry, |
50 | - const bool use_timeout) | |
51 | - : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, use_timeout) | |
50 | + const bool use_timeout, | |
51 | + const char* output_filename) | |
52 | + : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, use_timeout, output_filename) | |
52 | 53 | { |
53 | 54 | // init |
54 | 55 | display = XOpenDisplay(NULL); |
@@ -166,8 +167,9 @@ CalibratorEvdev::CalibratorEvdev(const char* const device_name0, | ||
166 | 167 | const int thr_doubleclick, |
167 | 168 | const OutputType output_type, |
168 | 169 | const char* geometry, |
169 | - const bool use_timeout) | |
170 | - : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry) { } | |
170 | + const bool use_timeout, | |
171 | + const char* output_filename) | |
172 | + : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, output_filename) { } | |
171 | 173 | |
172 | 174 | // Destructor |
173 | 175 | CalibratorEvdev::~CalibratorEvdev () { |
@@ -515,18 +517,41 @@ bool CalibratorEvdev::output_xorgconfd(const XYinfo new_axys) | ||
515 | 517 | if (not_sysfs_name) |
516 | 518 | sysfs_name = "!!Name_Of_TouchScreen!!"; |
517 | 519 | |
520 | + if(output_filename == NULL || not_sysfs_name) | |
521 | + printf(" copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf' (/usr/share/X11/xorg.conf.d/ in some distro's)\n"); | |
522 | + else | |
523 | + printf(" writing xorg.conf calibration data to '%s'\n", output_filename); | |
524 | + | |
518 | 525 | // xorg.conf.d snippet |
519 | - printf(" copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf' (/usr/share/X11/xorg.conf.d/ in some distro's)\n"); | |
520 | - printf("Section \"InputClass\"\n"); | |
521 | - printf(" Identifier \"calibration\"\n"); | |
522 | - printf(" MatchProduct \"%s\"\n", sysfs_name); | |
523 | - printf(" Option \"Calibration\" \"%d %d %d %d\"\n", | |
526 | + char line[MAX_LINE_LEN]; | |
527 | + std::string outstr; | |
528 | + | |
529 | + outstr += "Section \"InputClass\"\n"; | |
530 | + outstr += " Identifier \"calibration\"\n"; | |
531 | + sprintf(line, " MatchProduct \"%s\"\n", sysfs_name); | |
532 | + outstr += line; | |
533 | + sprintf(line, " Option \"Calibration\" \"%d %d %d %d\"\n", | |
524 | 534 | new_axys.x.min, new_axys.x.max, new_axys.y.min, new_axys.y.max); |
525 | - printf(" Option \"SwapAxes\" \"%d\"\n", new_axys.swap_xy); | |
526 | - printf("EndSection\n"); | |
535 | + outstr += line; | |
536 | + sprintf(line, " Option \"SwapAxes\" \"%d\"\n", new_axys.swap_xy); | |
537 | + outstr += line; | |
538 | + outstr += "EndSection\n"; | |
527 | 539 | |
540 | + // console out | |
541 | + printf("%s", outstr.c_str()); | |
528 | 542 | if (not_sysfs_name) |
529 | 543 | printf("\nChange '%s' to your device's name in the snippet above.\n", sysfs_name); |
544 | + // file out | |
545 | + else if(output_filename != NULL) { | |
546 | + FILE* fid = fopen(output_filename, "w"); | |
547 | + if (fid == NULL) { | |
548 | + fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necessary rights\n", output_filename); | |
549 | + fprintf(stderr, "New calibration data NOT saved\n"); | |
550 | + return false; | |
551 | + } | |
552 | + fprintf(fid, "%s", outstr.c_str()); | |
553 | + fclose(fid); | |
554 | + } | |
530 | 555 | |
531 | 556 | return true; |
532 | 557 | } |
@@ -538,26 +563,71 @@ bool CalibratorEvdev::output_hal(const XYinfo new_axys) | ||
538 | 563 | if (not_sysfs_name) |
539 | 564 | sysfs_name = "!!Name_Of_TouchScreen!!"; |
540 | 565 | |
541 | - // HAL policy output | |
542 | - printf(" copy the policy below into '/etc/hal/fdi/policy/touchscreen.fdi'\n\ | |
543 | -<match key=\"info.product\" contains=\"%s\">\n\ | |
544 | - <merge key=\"input.x11_options.calibration\" type=\"string\">%d %d %d %d</merge>\n" | |
545 | - , sysfs_name, new_axys.x.min, new_axys.x.max, new_axys.y.min, new_axys.y.max); | |
546 | - printf(" <merge key=\"input.x11_options.swapaxes\" type=\"string\">%d</merge>\n", new_axys.swap_xy); | |
547 | - printf("</match>\n"); | |
566 | + if(output_filename == NULL || not_sysfs_name) | |
567 | + printf(" copy the policy below into '/etc/hal/fdi/policy/touchscreen.fdi'\n"); | |
568 | + else | |
569 | + printf(" writing HAL calibration data to '%s'\n", output_filename); | |
548 | 570 | |
571 | + // HAL policy output | |
572 | + char line[MAX_LINE_LEN]; | |
573 | + std::string outstr; | |
574 | + | |
575 | + sprintf(line, "<match key=\"info.product\" contains=\"%s\">\n", sysfs_name); | |
576 | + outstr += line; | |
577 | + sprintf(line, " <merge key=\"input.x11_options.calibration\" type=\"string\">%d %d %d %d</merge>\n", | |
578 | + new_axys.x.min, new_axys.x.max, new_axys.y.min, new_axys.y.max); | |
579 | + outstr += line; | |
580 | + sprintf(line, " <merge key=\"input.x11_options.swapaxes\" type=\"string\">%d</merge>\n", | |
581 | + new_axys.swap_xy); | |
582 | + outstr += "</match>\n"; | |
583 | + // console out | |
584 | + printf("%s", outstr.c_str()); | |
549 | 585 | if (not_sysfs_name) |
550 | 586 | printf("\nChange '%s' to your device's name in the config above.\n", sysfs_name); |
587 | + // file out | |
588 | + else if(output_filename != NULL) { | |
589 | + FILE* fid = fopen(output_filename, "w"); | |
590 | + if (fid == NULL) { | |
591 | + fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necessary rights\n", output_filename); | |
592 | + fprintf(stderr, "New calibration data NOT saved\n"); | |
593 | + return false; | |
594 | + } | |
595 | + fprintf(fid, "%s", outstr.c_str()); | |
596 | + fclose(fid); | |
597 | + } | |
551 | 598 | |
552 | 599 | return true; |
553 | 600 | } |
554 | 601 | |
555 | 602 | bool CalibratorEvdev::output_xinput(const XYinfo new_axys) |
556 | 603 | { |
604 | + if(output_filename == NULL) | |
605 | + printf(" Install the 'xinput' tool and copy the command(s) below in a script that starts with your X session\n"); | |
606 | + else | |
607 | + printf(" writing calibration script to '%s'\n", output_filename); | |
608 | + | |
557 | 609 | // create startup script |
558 | - printf(" Install the 'xinput' tool and copy the command(s) below in a script that starts with your X session\n"); | |
559 | - printf(" xinput set-int-prop \"%s\" \"Evdev Axis Calibration\" 32 %d %d %d %d\n", device_name, new_axys.x.min, new_axys.x.max, new_axys.y.min, new_axys.y.max); | |
560 | - printf(" xinput set-int-prop \"%s\" \"Evdev Axes Swap\" 8 %d\n", device_name, new_axys.swap_xy); | |
610 | + char line[MAX_LINE_LEN]; | |
611 | + std::string outstr; | |
612 | + | |
613 | + sprintf(line, " xinput set-int-prop \"%s\" \"Evdev Axis Calibration\" 32 %d %d %d %d\n", device_name, new_axys.x.min, new_axys.x.max, new_axys.y.min, new_axys.y.max); | |
614 | + outstr += line; | |
615 | + sprintf(line, " xinput set-int-prop \"%s\" \"Evdev Axes Swap\" 8 %d\n", device_name, new_axys.swap_xy); | |
616 | + outstr += line; | |
617 | + | |
618 | + // console out | |
619 | + printf("%s", outstr.c_str()); | |
620 | + // file out | |
621 | + if(output_filename != NULL) { | |
622 | + FILE* fid = fopen(output_filename, "w"); | |
623 | + if (fid == NULL) { | |
624 | + fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necessary rights\n", output_filename); | |
625 | + fprintf(stderr, "New calibration data NOT saved\n"); | |
626 | + return false; | |
627 | + } | |
628 | + fprintf(fid, "%s", outstr.c_str()); | |
629 | + fclose(fid); | |
630 | + } | |
561 | 631 | |
562 | 632 | return true; |
563 | 633 | } |
@@ -47,7 +47,8 @@ protected: | ||
47 | 47 | const int thr_doubleclick=0, |
48 | 48 | const OutputType output_type=OUTYPE_AUTO, |
49 | 49 | const char* geometry=0, |
50 | - const bool use_timeout=false); | |
50 | + const bool use_timeout=false, | |
51 | + const char* output_filename = 0); | |
51 | 52 | |
52 | 53 | public: |
53 | 54 | CalibratorEvdev(const char* const device_name, |
@@ -57,8 +58,9 @@ public: | ||
57 | 58 | const int thr_doubleclick=0, |
58 | 59 | const OutputType output_type=OUTYPE_AUTO, |
59 | 60 | const char* geometry=0, |
60 | - const bool use_timeout=false); | |
61 | - ~CalibratorEvdev(); | |
61 | + const bool use_timeout=false, | |
62 | + const char* output_filename = 0); | |
63 | + virtual ~CalibratorEvdev(); | |
62 | 64 | |
63 | 65 | /// calculate and apply the calibration |
64 | 66 | virtual bool finish(int width, int height); |
@@ -48,8 +48,8 @@ static const char *p_flip_x = "flip_x"; | ||
48 | 48 | static const char *p_flip_y = "flip_y"; |
49 | 49 | static const char *p_swap_xy = "swap_xy"; |
50 | 50 | |
51 | -CalibratorUsbtouchscreen::CalibratorUsbtouchscreen(const char* const device_name0, const XYinfo& axys0, const int thr_misclick, const int thr_doubleclick, const OutputType output_type, const char* geometry, const bool use_timeout) | |
52 | - : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, use_timeout) | |
51 | +CalibratorUsbtouchscreen::CalibratorUsbtouchscreen(const char* const device_name0, const XYinfo& axys0, const int thr_misclick, const int thr_doubleclick, const OutputType output_type, const char* geometry, const bool use_timeout, const char* output_filename) | |
52 | + : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, use_timeout, output_filename) | |
53 | 53 | { |
54 | 54 | if (strcmp(device_name, "Usbtouchscreen") != 0) |
55 | 55 | throw WrongCalibratorException("Not a usbtouchscreen device"); |
@@ -104,16 +104,17 @@ bool CalibratorUsbtouchscreen::finish_data(const XYinfo new_axys) | ||
104 | 104 | write_bool_parameter(p_swap_xy, new_axys.swap_xy); |
105 | 105 | |
106 | 106 | // Read, then write calibration parameters to modprobe_conf_local, |
107 | - // to keep the for the next boot | |
108 | - FILE *fid = fopen(modprobe_conf_local, "r"); | |
107 | + // or the file set by --output-filename to keep the for the next boot | |
108 | + const char* filename = output_filename == NULL ? modprobe_conf_local : output_filename; | |
109 | + FILE *fid = fopen(filename, "r"); | |
109 | 110 | if (fid == NULL) { |
110 | - fprintf(stderr, "Error: Can't open '%s' for reading. Make sure you have the necessary rights\n", modprobe_conf_local); | |
111 | + fprintf(stderr, "Error: Can't open '%s' for reading. Make sure you have the necessary rights\n", filename); | |
111 | 112 | fprintf(stderr, "New calibration data NOT saved\n"); |
112 | 113 | return false; |
113 | 114 | } |
114 | 115 | |
115 | 116 | std::string new_contents; |
116 | - const int len = 1024; // XXX: we currently don't handle lines that are longer than this | |
117 | + const int len = MAX_LINE_LEN; | |
117 | 118 | char line[len]; |
118 | 119 | const char *opt = "options usbtouchscreen"; |
119 | 120 | const int opt_len = strlen(opt); |
@@ -135,9 +136,9 @@ bool CalibratorUsbtouchscreen::finish_data(const XYinfo new_axys) | ||
135 | 136 | p_flip_y, yesno(flip_y), p_swap_xy, yesno(new_axys.swap_xy)); |
136 | 137 | new_contents += new_opt; |
137 | 138 | |
138 | - fid = fopen(modprobe_conf_local, "w"); | |
139 | + fid = fopen(filename, "w"); | |
139 | 140 | if (fid == NULL) { |
140 | - fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necessary rights\n", modprobe_conf_local); | |
141 | + fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necessary rights\n", filename); | |
141 | 142 | fprintf(stderr, "New calibration data NOT saved\n"); |
142 | 143 | return false; |
143 | 144 | } |
@@ -35,8 +35,8 @@ public: | ||
35 | 35 | CalibratorUsbtouchscreen(const char* const device_name, const XYinfo& axys, |
36 | 36 | const int thr_misclick=0, const int thr_doubleclick=0, |
37 | 37 | const OutputType output_type=OUTYPE_AUTO, const char* geometry=0, |
38 | - const bool use_timeout=false); | |
39 | - ~CalibratorUsbtouchscreen(); | |
38 | + const bool use_timeout=false, const char* output_filename = 0); | |
39 | + virtual ~CalibratorUsbtouchscreen(); | |
40 | 40 | |
41 | 41 | virtual bool finish_data(const XYinfo new_axys); |
42 | 42 |
@@ -24,8 +24,8 @@ | ||
24 | 24 | |
25 | 25 | #include <cstdio> |
26 | 26 | |
27 | -CalibratorXorgPrint::CalibratorXorgPrint(const char* const device_name0, const XYinfo& axys0, const int thr_misclick, const int thr_doubleclick, const OutputType output_type, const char* geometry, const bool use_timeout) | |
28 | - : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, use_timeout) | |
27 | +CalibratorXorgPrint::CalibratorXorgPrint(const char* const device_name0, const XYinfo& axys0, const int thr_misclick, const int thr_doubleclick, const OutputType output_type, const char* geometry, const bool use_timeout, const char* output_filename) | |
28 | + : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, use_timeout, output_filename) | |
29 | 29 | { |
30 | 30 | printf("Calibrating standard Xorg driver \"%s\"\n", device_name); |
31 | 31 | printf("\tcurrent calibration values: min_x=%d, max_x=%d and min_y=%d, max_y=%d\n", |
@@ -69,22 +69,50 @@ bool CalibratorXorgPrint::output_xorgconfd(const XYinfo new_axys) | ||
69 | 69 | if (not_sysfs_name) |
70 | 70 | sysfs_name = "!!Name_Of_TouchScreen!!"; |
71 | 71 | |
72 | + if(output_filename == NULL || not_sysfs_name) | |
73 | + printf(" copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf' (/usr/share/X11/xorg.conf.d/ in some distro's)\n"); | |
74 | + else | |
75 | + printf(" writing calibration script to '%s'\n", output_filename); | |
76 | + | |
72 | 77 | // xorg.conf.d snippet |
73 | - printf(" copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf' (/usr/share/X11/xorg.conf.d/ in some distro's)\n"); | |
74 | - printf("Section \"InputClass\"\n"); | |
75 | - printf(" Identifier \"calibration\"\n"); | |
76 | - printf(" MatchProduct \"%s\"\n", sysfs_name); | |
77 | - printf(" Option \"MinX\" \"%d\"\n", new_axys.x.min); | |
78 | - printf(" Option \"MaxX\" \"%d\"\n", new_axys.x.max); | |
79 | - printf(" Option \"MinY\" \"%d\"\n", new_axys.y.min); | |
80 | - printf(" Option \"MaxY\" \"%d\"\n", new_axys.y.max); | |
81 | - printf(" Option \"SwapXY\" \"%d\" # unless it was already set to 1\n", new_axys.swap_xy); | |
82 | - printf(" Option \"InvertX\" \"%d\" # unless it was already set\n", new_axys.x.invert); | |
83 | - printf(" Option \"InvertY\" \"%d\" # unless it was already set\n", new_axys.y.invert); | |
84 | - printf("EndSection\n"); | |
78 | + char line[MAX_LINE_LEN]; | |
79 | + std::string outstr; | |
80 | + | |
81 | + outstr += "Section \"InputClass\"\n"; | |
82 | + outstr += " Identifier \"calibration\"\n"; | |
83 | + sprintf(line, " MatchProduct \"%s\"\n", sysfs_name); | |
84 | + outstr += line; | |
85 | + sprintf(line, " Option \"MinX\" \"%d\"\n", new_axys.x.min); | |
86 | + outstr += line; | |
87 | + sprintf(line, " Option \"MaxX\" \"%d\"\n", new_axys.x.max); | |
88 | + outstr += line; | |
89 | + sprintf(line, " Option \"MinY\" \"%d\"\n", new_axys.y.min); | |
90 | + outstr += line; | |
91 | + sprintf(line, " Option \"MaxY\" \"%d\"\n", new_axys.y.max); | |
92 | + outstr += line; | |
93 | + sprintf(line, " Option \"SwapXY\" \"%d\" # unless it was already set to 1\n", new_axys.swap_xy); | |
94 | + outstr += line; | |
95 | + sprintf(line, " Option \"InvertX\" \"%d\" # unless it was already set\n", new_axys.x.invert); | |
96 | + outstr += line; | |
97 | + sprintf(line, " Option \"InvertY\" \"%d\" # unless it was already set\n", new_axys.y.invert); | |
98 | + outstr += line; | |
99 | + outstr += "EndSection\n"; | |
85 | 100 | |
101 | + // console out | |
102 | + printf("%s", outstr.c_str()); | |
86 | 103 | if (not_sysfs_name) |
87 | 104 | printf("\nChange '%s' to your device's name in the config above.\n", sysfs_name); |
105 | + // file out | |
106 | + else if(output_filename != NULL) { | |
107 | + FILE* fid = fopen(output_filename, "w"); | |
108 | + if (fid == NULL) { | |
109 | + fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necessary rights\n", output_filename); | |
110 | + fprintf(stderr, "New calibration data NOT saved\n"); | |
111 | + return false; | |
112 | + } | |
113 | + fprintf(fid, "%s", outstr.c_str()); | |
114 | + fclose(fid); | |
115 | + } | |
88 | 116 | |
89 | 117 | return true; |
90 | 118 | } |
@@ -96,21 +124,48 @@ bool CalibratorXorgPrint::output_hal(const XYinfo new_axys) | ||
96 | 124 | if (not_sysfs_name) |
97 | 125 | sysfs_name = "!!Name_Of_TouchScreen!!"; |
98 | 126 | |
127 | + if(output_filename == NULL || not_sysfs_name) | |
128 | + printf(" copy the policy below into '/etc/hal/fdi/policy/touchscreen.fdi'\n"); | |
129 | + else | |
130 | + printf(" writing HAL calibration data to '%s'\n", output_filename); | |
131 | + | |
99 | 132 | // HAL policy output |
100 | - printf(" copy the policy below into '/etc/hal/fdi/policy/touchscreen.fdi'\n\ | |
101 | -<match key=\"info.product\" contains=\"%s\">\n\ | |
102 | - <merge key=\"input.x11_options.minx\" type=\"string\">%d</merge>\n\ | |
103 | - <merge key=\"input.x11_options.maxx\" type=\"string\">%d</merge>\n\ | |
104 | - <merge key=\"input.x11_options.miny\" type=\"string\">%d</merge>\n\ | |
105 | - <merge key=\"input.x11_options.maxy\" type=\"string\">%d</merge>\n" | |
106 | - , sysfs_name, new_axys.x.min, new_axys.x.max, new_axys.y.min, new_axys.y.max); | |
107 | - printf(" <merge key=\"input.x11_options.swapxy\" type=\"string\">%d</merge>\n", new_axys.swap_xy); | |
108 | - printf(" <merge key=\"input.x11_options.invertx\" type=\"string\">%d</merge>\n", new_axys.x.invert); | |
109 | - printf(" <merge key=\"input.x11_options.inverty\" type=\"string\">%d</merge>\n", new_axys.y.invert); | |
110 | - printf("</match>\n"); | |
133 | + char line[MAX_LINE_LEN]; | |
134 | + std::string outstr; | |
135 | + | |
136 | + sprintf(line, "<match key=\"info.product\" contains=\"%s\">\n", sysfs_name); | |
137 | + outstr += line; | |
138 | + sprintf(line, " <merge key=\"input.x11_options.minx\" type=\"string\">%d</merge>\n", new_axys.x.min); | |
139 | + outstr += line; | |
140 | + sprintf(line, " <merge key=\"input.x11_options.maxx\" type=\"string\">%d</merge>\n", new_axys.x.max); | |
141 | + outstr += line; | |
142 | + sprintf(line, " <merge key=\"input.x11_options.miny\" type=\"string\">%d</merge>\n", new_axys.y.min); | |
143 | + outstr += line; | |
144 | + sprintf(line, " <merge key=\"input.x11_options.maxy\" type=\"string\">%d</merge>\n", new_axys.y.max); | |
145 | + outstr += line; | |
146 | + sprintf(line, " <merge key=\"input.x11_options.swapxy\" type=\"string\">%d</merge>\n", new_axys.swap_xy); | |
147 | + outstr += line; | |
148 | + sprintf(line, " <merge key=\"input.x11_options.invertx\" type=\"string\">%d</merge>\n", new_axys.x.invert); | |
149 | + outstr += line; | |
150 | + sprintf(line, " <merge key=\"input.x11_options.inverty\" type=\"string\">%d</merge>\n", new_axys.y.invert); | |
151 | + outstr += line; | |
152 | + outstr += "</match>\n"; | |
111 | 153 | |
154 | + // console out | |
155 | + printf("%s", outstr.c_str()); | |
112 | 156 | if (not_sysfs_name) |
113 | 157 | printf("\nChange '%s' to your device's name in the config above.\n", sysfs_name); |
158 | + // file out | |
159 | + else if(output_filename != NULL) { | |
160 | + FILE* fid = fopen(output_filename, "w"); | |
161 | + if (fid == NULL) { | |
162 | + fprintf(stderr, "Error: Can't open '%s' for writing. Make sure you have the necessary rights\n", output_filename); | |
163 | + fprintf(stderr, "New calibration data NOT saved\n"); | |
164 | + return false; | |
165 | + } | |
166 | + fprintf(fid, "%s", outstr.c_str()); | |
167 | + fclose(fid); | |
168 | + } | |
114 | 169 | |
115 | 170 | return true; |
116 | 171 | } |
@@ -35,7 +35,7 @@ public: | ||
35 | 35 | CalibratorXorgPrint(const char* const device_name, const XYinfo& axys, |
36 | 36 | const int thr_misclick=0, const int thr_doubleclick=0, |
37 | 37 | const OutputType output_type=OUTYPE_AUTO, const char* geometry=0, |
38 | - const bool use_timeout=false); | |
38 | + const bool use_timeout=false, const char* output_filename = 0); | |
39 | 39 | |
40 | 40 | virtual bool finish_data(const XYinfo new_axys); |
41 | 41 |
@@ -180,6 +180,7 @@ static void usage(char* cmd, unsigned thr_misclick) | ||
180 | 180 | fprintf(stderr, "\t--fake: emulate a fake device (for testing purposes)\n"); |
181 | 181 | fprintf(stderr, "\t--geometry: manually provide the geometry (width and height) for the calibration window\n"); |
182 | 182 | fprintf(stderr, "\t--no-timeout: turns off the timeout\n"); |
183 | + fprintf(stderr, "\t--output-filename: write calibration data to file (USB: override default /etc/modprobe.conf.local\n"); | |
183 | 184 | } |
184 | 185 | |
185 | 186 | Calibrator* Calibrator::make_calibrator(int argc, char** argv) |
@@ -191,6 +192,7 @@ Calibrator* Calibrator::make_calibrator(int argc, char** argv) | ||
191 | 192 | XYinfo pre_axys; |
192 | 193 | const char* pre_device = NULL; |
193 | 194 | const char* geometry = NULL; |
195 | + const char* output_filename = NULL; | |
194 | 196 | unsigned thr_misclick = 15; |
195 | 197 | unsigned thr_doubleclick = 7; |
196 | 198 | OutputType output_type = OUTYPE_AUTO; |
@@ -289,6 +291,11 @@ Calibrator* Calibrator::make_calibrator(int argc, char** argv) | ||
289 | 291 | // Disable timeout |
290 | 292 | if (strcmp("--no-timeout", argv[i]) == 0) { |
291 | 293 | use_timeout = false; |
294 | + } else | |
295 | + | |
296 | + // Output file | |
297 | + if (strcmp("--output-filename", argv[i]) == 0) { | |
298 | + output_filename = argv[++i]; | |
292 | 299 | } |
293 | 300 | |
294 | 301 | // unknown option |
@@ -363,7 +370,8 @@ Calibrator* Calibrator::make_calibrator(int argc, char** argv) | ||
363 | 370 | try { |
364 | 371 | // try Usbtouchscreen driver |
365 | 372 | return new CalibratorUsbtouchscreen(device_name, device_axys, |
366 | - thr_misclick, thr_doubleclick, output_type, geometry, use_timeout); | |
373 | + thr_misclick, thr_doubleclick, output_type, geometry, | |
374 | + use_timeout, output_filename); | |
367 | 375 | |
368 | 376 | } catch(WrongCalibratorException& x) { |
369 | 377 | if (verbose) |
@@ -373,7 +381,8 @@ Calibrator* Calibrator::make_calibrator(int argc, char** argv) | ||
373 | 381 | try { |
374 | 382 | // next, try Evdev driver (with XID) |
375 | 383 | return new CalibratorEvdev(device_name, device_axys, device_id, |
376 | - thr_misclick, thr_doubleclick, output_type, geometry, use_timeout); | |
384 | + thr_misclick, thr_doubleclick, output_type, geometry, | |
385 | + use_timeout, output_filename); | |
377 | 386 | |
378 | 387 | } catch(WrongCalibratorException& x) { |
379 | 388 | if (verbose) |
@@ -382,5 +391,6 @@ Calibrator* Calibrator::make_calibrator(int argc, char** argv) | ||
382 | 391 | |
383 | 392 | // lastly, presume a standard Xorg driver (evtouch, mutouch, ...) |
384 | 393 | return new CalibratorXorgPrint(device_name, device_axys, |
385 | - thr_misclick, thr_doubleclick, output_type, geometry, use_timeout); | |
394 | + thr_misclick, thr_doubleclick, output_type, geometry, | |
395 | + use_timeout, output_filename); | |
386 | 396 | } |