| @@ -1,1102 +1,1134 @@ | | | @@ -1,1102 +1,1134 @@ |
1 | /* | | 1 | /* |
2 | * Copyright 1995, 1999 by Patrick Lecoanet, France. <lecoanet@cena.dgac.fr> | | 2 | * Copyright 1995, 1999 by Patrick Lecoanet, France. <lecoanet@cena.dgac.fr> |
3 | * | | 3 | * |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | | 4 | * Permission to use, copy, modify, distribute, and sell this software and its |
5 | * documentation for any purpose is hereby granted without fee, provided that | | 5 | * documentation for any purpose is hereby granted without fee, provided that |
6 | * the above copyright notice appear in all copies and that both that | | 6 | * the above copyright notice appear in all copies and that both that |
7 | * copyright notice and this permission notice appear in supporting | | 7 | * copyright notice and this permission notice appear in supporting |
8 | * documentation, and that the name of Patrick Lecoanet not be used in | | 8 | * documentation, and that the name of Patrick Lecoanet not be used in |
9 | * advertising or publicity pertaining to distribution of the software without | | 9 | * advertising or publicity pertaining to distribution of the software without |
10 | * specific, written prior permission. Patrick Lecoanet makes no | | 10 | * specific, written prior permission. Patrick Lecoanet makes no |
11 | * representations about the suitability of this software for any purpose. It | | 11 | * representations about the suitability of this software for any purpose. It |
12 | * is provided "as is" without express or implied warranty. | | 12 | * is provided "as is" without express or implied warranty. |
13 | * | | 13 | * |
14 | * PATRICK LECOANET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | | 14 | * PATRICK LECOANET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | | 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
16 | * EVENT SHALL PATRICK LECOANET BE LIABLE FOR ANY SPECIAL, INDIRECT OR | | 16 | * EVENT SHALL PATRICK LECOANET BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | | 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | | 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | | 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
20 | * PERFORMANCE OF THIS SOFTWARE. | | 20 | * PERFORMANCE OF THIS SOFTWARE. |
21 | * | | 21 | * |
22 | */ | | 22 | */ |
23 | | | 23 | |
24 | /* | | 24 | /* |
25 | ******************************************************************************* | | 25 | ******************************************************************************* |
26 | ******************************************************************************* | | 26 | ******************************************************************************* |
27 | * | | 27 | * |
28 | * This driver is able to deal with Elographics SmartSet serial controllers. | | 28 | * This driver is able to deal with Elographics SmartSet serial controllers. |
29 | * It uses only a subset of the functions provided through the protocol. | | 29 | * It uses only a subset of the functions provided through the protocol. |
30 | * | | 30 | * |
31 | * SUPPORT FOR E281-2310 and compatible controllers added with help of: | | 31 | * SUPPORT FOR E281-2310 and compatible controllers added with help of: |
32 | * 1996/01/17 Juergen P. Meier (jpm@mailserv.rz.fh-muenchen.de) and | | 32 | * 1996/01/17 Juergen P. Meier (jpm@mailserv.rz.fh-muenchen.de) and |
33 | * 1998/03/25 G.Felkel@edelmann.de | | 33 | * 1998/03/25 G.Felkel@edelmann.de |
34 | * | | 34 | * |
35 | * The E281-2310 is a somewhat lobotomized 2210. | | 35 | * The E281-2310 is a somewhat lobotomized 2210. |
36 | * It does not support the c,g,h,k,l,p,q,s and t commands. | | 36 | * It does not support the c,g,h,k,l,p,q,s and t commands. |
37 | * Especially the P command, which is used to check the baud rate. | | 37 | * Especially the P command, which is used to check the baud rate. |
38 | * The E281-2310 however semms to use always 9600bps, 8bit, 1stop | | 38 | * The E281-2310 however semms to use always 9600bps, 8bit, 1stop |
39 | * no parity, Hardwarehandshake (RTS-CTS) (which are the drivers | | 39 | * no parity, Hardwarehandshake (RTS-CTS) (which are the drivers |
40 | * default values) | | 40 | * default values) |
41 | * | | 41 | * |
42 | ******************************************************************************* | | 42 | ******************************************************************************* |
43 | ******************************************************************************* | | 43 | ******************************************************************************* |
44 | */ | | 44 | */ |
45 | | | 45 | |
46 | #ifdef HAVE_CONFIG_H | | 46 | #ifdef HAVE_CONFIG_H |
47 | #include "config.h" | | 47 | #include "config.h" |
48 | #endif | | 48 | #endif |
49 | | | 49 | |
50 | #include "xorgVersion.h" | | 50 | #include "xorgVersion.h" |
51 | | | 51 | |
52 | | | 52 | |
53 | #include "misc.h" | | 53 | #include "misc.h" |
54 | #include "xf86.h" | | 54 | #include "xf86.h" |
55 | #include "xf86_OSproc.h" | | 55 | #include "xf86_OSproc.h" |
56 | #include "xf86Xinput.h" | | 56 | #include "xf86Xinput.h" |
57 | #include "exevents.h" | | 57 | #include "exevents.h" |
58 | | | 58 | |
59 | #include "xf86Module.h" | | 59 | #include "xf86Module.h" |
60 | | | 60 | |
61 | /** | | 61 | /** |
62 | * models to be treated specially. | | 62 | * models to be treated specially. |
63 | */ | | 63 | */ |
64 | #define MODEL_UNKNOWN -1 | | 64 | #define MODEL_UNKNOWN -1 |
65 | #define MODEL_SUNIT_D 1 | | 65 | #define MODEL_SUNIT_D 1 |
66 | | | 66 | |
67 | typedef struct { | | 67 | typedef struct { |
68 | int type; | | 68 | int type; |
69 | const char *name; | | 69 | const char *name; |
70 | } Model; | | 70 | } Model; |
71 | | | 71 | |
72 | static Model SupportedModels[] = | | 72 | static Model SupportedModels[] = |
73 | { | | 73 | { |
74 | {MODEL_SUNIT_D, "Sunit dSeries"}, /* sunit dSeries models don't reply to queries */ | | 74 | {MODEL_SUNIT_D, "Sunit dSeries"}, /* sunit dSeries models don't reply to queries */ |
75 | {MODEL_UNKNOWN, NULL} | | 75 | {MODEL_UNKNOWN, NULL} |
76 | }; | | 76 | }; |
77 | /* | | 77 | /* |
78 | *************************************************************************** | | 78 | *************************************************************************** |
79 | * | | 79 | * |
80 | * Default constants. | | 80 | * Default constants. |
81 | * | | 81 | * |
82 | *************************************************************************** | | 82 | *************************************************************************** |
83 | */ | | 83 | */ |
84 | #define ELO_MAX_TRIALS 3 /* Number of timeouts waiting for a */ | | 84 | #define ELO_MAX_TRIALS 3 /* Number of timeouts waiting for a */ |
85 | /* pending reply. */ | | 85 | /* pending reply. */ |
86 | #define ELO_MAX_WAIT 100000 /* Max wait time for a reply (microsec) */ | | 86 | #define ELO_MAX_WAIT 100000 /* Max wait time for a reply (microsec) */ |
87 | #define ELO_UNTOUCH_DELAY 5 /* 100 ms */ | | 87 | #define ELO_UNTOUCH_DELAY 5 /* 100 ms */ |
88 | #define ELO_REPORT_DELAY 1 /* 40 ms or 25 motion reports/s */ | | 88 | #define ELO_REPORT_DELAY 1 /* 40 ms or 25 motion reports/s */ |
89 | #define ELO_LINK_SPEED B9600 /* 9600 Bauds */ | | 89 | #define ELO_LINK_SPEED B9600 /* 9600 Bauds */ |
90 | #define ELO_PORT "/dev/ttyS1" | | 90 | #define ELO_PORT "/dev/ttyS1" |
91 | | | 91 | |
92 | #define DEFAULT_MAX_X 3000 | | 92 | #define DEFAULT_MAX_X 3000 |
93 | #define DEFAULT_MIN_X 600 | | 93 | #define DEFAULT_MIN_X 600 |
94 | #define DEFAULT_MAX_Y 3000 | | 94 | #define DEFAULT_MAX_Y 3000 |
95 | #define DEFAULT_MIN_Y 600 | | 95 | #define DEFAULT_MIN_Y 600 |
96 | | | 96 | |
97 | | | 97 | |
98 | /* | | 98 | /* |
99 | *************************************************************************** | | 99 | *************************************************************************** |
100 | * | | 100 | * |
101 | * Protocol constants. | | 101 | * Protocol constants. |
102 | * | | 102 | * |
103 | *************************************************************************** | | 103 | *************************************************************************** |
104 | */ | | 104 | */ |
105 | #define ELO_PACKET_SIZE 10 | | 105 | #define ELO_PACKET_SIZE 10 |
106 | | | 106 | |
107 | #define ELO_SYNC_BYTE 'U' /* Sync byte. First of a packet. */ | | 107 | #define ELO_SYNC_BYTE 'U' /* Sync byte. First of a packet. */ |
108 | #define ELO_TOUCH 'T' /* Report of touchs and motions. Not * | | 108 | #define ELO_TOUCH 'T' /* Report of touchs and motions. Not * |
109 | * used by 2310. */ | | 109 | * used by 2310. */ |
110 | #define ELO_OWNER 'O' /* Report vendor name. */ | | 110 | #define ELO_OWNER 'O' /* Report vendor name. */ |
111 | #define ELO_ID 'I' /* Report of type and features. */ | | 111 | #define ELO_ID 'I' /* Report of type and features. */ |
112 | #define ELO_MODE 'M' /* Set current operating mode. */ | | 112 | #define ELO_MODE 'M' /* Set current operating mode. */ |
113 | #define ELO_PARAMETER 'P' /* Set the serial parameters. */ | | 113 | #define ELO_PARAMETER 'P' /* Set the serial parameters. */ |
114 | #define ELO_REPORT 'B' /* Set touch reports timings. */ | | 114 | #define ELO_REPORT 'B' /* Set touch reports timings. */ |
115 | #define ELO_ACK 'A' /* Acknowledge packet */ | | 115 | #define ELO_ACK 'A' /* Acknowledge packet */ |
116 | | | 116 | |
117 | #define ELO_INIT_CHECKSUM 0xAA /* Initial value of checksum. */ | | 117 | #define ELO_INIT_CHECKSUM 0xAA /* Initial value of checksum. */ |
118 | | | 118 | |
119 | #define ELO_PRESS 0x01 /* Flags in ELO_TOUCH status byte */ | | 119 | #define ELO_PRESS 0x01 /* Flags in ELO_TOUCH status byte */ |
120 | #define ELO_STREAM 0x02 | | 120 | #define ELO_STREAM 0x02 |
121 | #define ELO_RELEASE 0x04 | | 121 | #define ELO_RELEASE 0x04 |
122 | | | 122 | |
123 | #define ELO_TOUCH_MODE 0x01 /* Flags in ELO_MODE command */ | | 123 | #define ELO_TOUCH_MODE 0x01 /* Flags in ELO_MODE command */ |
124 | #define ELO_STREAM_MODE 0x02 | | 124 | #define ELO_STREAM_MODE 0x02 |
125 | #define ELO_UNTOUCH_MODE 0x04 | | 125 | #define ELO_UNTOUCH_MODE 0x04 |
126 | #define ELO_RANGE_CHECK_MODE 0x40 | | 126 | #define ELO_RANGE_CHECK_MODE 0x40 |
127 | #define ELO_TRIM_MODE 0x02 | | 127 | #define ELO_TRIM_MODE 0x02 |
128 | #define ELO_CALIB_MODE 0x04 | | 128 | #define ELO_CALIB_MODE 0x04 |
129 | #define ELO_SCALING_MODE 0x08 | | 129 | #define ELO_SCALING_MODE 0x08 |
130 | #define ELO_TRACKING_MODE 0x40 | | 130 | #define ELO_TRACKING_MODE 0x40 |
131 | | | 131 | |
132 | #define ELO_SERIAL_SPEED 0x06 /* Flags for high speed serial (19200) */ | | 132 | #define ELO_SERIAL_SPEED 0x06 /* Flags for high speed serial (19200) */ |
133 | #define ELO_SERIAL_MASK 0xF8 | | 133 | #define ELO_SERIAL_MASK 0xF8 |
134 | | | 134 | |
135 | #define ELO_SERIAL_IO '0' /* Indicator byte for PARAMETER command */ | | 135 | #define ELO_SERIAL_IO '0' /* Indicator byte for PARAMETER command */ |
136 | | | 136 | |
137 | | | 137 | |
138 | /* | | 138 | /* |
139 | *************************************************************************** | | 139 | *************************************************************************** |
140 | * | | 140 | * |
141 | * Usefull macros. | | 141 | * Usefull macros. |
142 | * | | 142 | * |
143 | *************************************************************************** | | 143 | *************************************************************************** |
144 | */ | | 144 | */ |
145 | #define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1)) | | 145 | #define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1)) |
146 | #define SYSCALL(call) while(((call) == -1) && (errno == EINTR)) | | 146 | #define SYSCALL(call) while(((call) == -1) && (errno == EINTR)) |
147 | | | 147 | |
148 | /* This one is handy, thanx Fred ! */ | | 148 | /* This one is handy, thanx Fred ! */ |
149 | #ifdef DBG | | 149 | #ifdef DBG |
150 | #undef DBG | | 150 | #undef DBG |
151 | #endif | | 151 | #endif |
152 | #ifdef DEBUG | | 152 | #ifdef DEBUG |
153 | #undef DEBUG | | 153 | #undef DEBUG |
154 | #endif | | 154 | #endif |
155 | | | 155 | |
156 | static int debug_level = 0; | | 156 | static int debug_level = 0; |
157 | #define DEBUG 1 | | 157 | #define DEBUG 1 |
158 | #if DEBUG | | 158 | #if DEBUG |
159 | #define DBG(lvl, f) {if ((lvl) <= debug_level) f;} | | 159 | #define DBG(lvl, f) {if ((lvl) <= debug_level) f;} |
160 | #else | | 160 | #else |
161 | #define DBG(lvl, f) | | 161 | #define DBG(lvl, f) |
162 | #endif | | 162 | #endif |
163 | | | 163 | |
164 | #undef SYSCALL | | 164 | #undef SYSCALL |
165 | #undef read | | 165 | #undef read |
166 | #undef write | | 166 | #undef write |
167 | #undef close | | 167 | #undef close |
168 | #define SYSCALL(call) call | | 168 | #define SYSCALL(call) call |
169 | #define read(fd, ptr, num) xf86ReadSerial(fd, ptr, num) | | 169 | #define read(fd, ptr, num) xf86ReadSerial(fd, ptr, num) |
170 | #define write(fd, ptr, num) xf86WriteSerial(fd, ptr, num) | | 170 | #define write(fd, ptr, num) xf86WriteSerial(fd, ptr, num) |
171 | #define close(fd) xf86CloseSerial(fd) | | 171 | #define close(fd) xf86CloseSerial(fd) |
172 | | | 172 | |
173 | | | 173 | |
174 | /* | | 174 | /* |
175 | *************************************************************************** | | 175 | *************************************************************************** |
176 | * | | 176 | * |
177 | * Device private records. | | 177 | * Device private records. |
178 | * | | 178 | * |
179 | *************************************************************************** | | 179 | *************************************************************************** |
180 | */ | | 180 | */ |
181 | typedef struct _EloPrivateRec { | | 181 | typedef struct _EloPrivateRec { |
182 | char *input_dev; /* The touchscreen input tty */ | | 182 | char *input_dev; /* The touchscreen input tty */ |
183 | int min_x; /* Minimum x reported by calibration */ | | 183 | int min_x; /* Minimum x reported by calibration */ |
184 | int max_x; /* Maximum x */ | | 184 | int max_x; /* Maximum x */ |
185 | int min_y; /* Minimum y reported by calibration */ | | 185 | int min_y; /* Minimum y reported by calibration */ |
186 | int max_y; /* Maximum y */ | | 186 | int max_y; /* Maximum y */ |
187 | int untouch_delay; /* Delay before reporting an untouch (in ms) */ | | 187 | int untouch_delay; /* Delay before reporting an untouch (in ms) */ |
188 | int report_delay; /* Delay between touch report packets */ | | 188 | int report_delay; /* Delay between touch report packets */ |
189 | int screen_no; /* Screen associated with the device */ | | 189 | int screen_no; /* Screen associated with the device */ |
190 | int screen_width; /* Width of the associated X screen */ | | 190 | int screen_width; /* Width of the associated X screen */ |
191 | int screen_height; /* Height of the screen */ | | 191 | int screen_height; /* Height of the screen */ |
192 | Bool inited; /* The controller has already been configured ? */ | | 192 | Bool inited; /* The controller has already been configured ? */ |
193 | Bool is_a_2310; /* Set if the smartset is a 2310. */ | | 193 | Bool is_a_2310; /* Set if the smartset is a 2310. */ |
194 | int checksum; /* Current checksum of data in assembly buffer */ | | 194 | int checksum; /* Current checksum of data in assembly buffer */ |
195 | int packet_buf_p; /* Assembly buffer pointer */ | | 195 | int packet_buf_p; /* Assembly buffer pointer */ |
196 | int swap_axes; /* Swap X an Y axes if != 0 */ | | 196 | int swap_axes; /* Swap X an Y axes if != 0 */ |
197 | unsigned char packet_buf[ELO_PACKET_SIZE]; /* Assembly buffer */ | | 197 | unsigned char packet_buf[ELO_PACKET_SIZE]; /* Assembly buffer */ |
198 | int model; /* one of MODEL_... */ | | 198 | int model; /* one of MODEL_... */ |
199 | } EloPrivateRec, *EloPrivatePtr; | | 199 | } EloPrivateRec, *EloPrivatePtr; |
200 | | | 200 | |
201 | /* | | 201 | /* |
202 | *************************************************************************** | | 202 | *************************************************************************** |
203 | * | | 203 | * |
204 | * xf86EloGetPacket -- | | 204 | * xf86EloGetPacket -- |
205 | * Read a packet from the port. Try to synchronize with start of | | 205 | * Read a packet from the port. Try to synchronize with start of |
206 | * packet and compute checksum. | | 206 | * packet and compute checksum. |
207 | * The packet structure read by this function is as follow: | | 207 | * The packet structure read by this function is as follow: |
208 | * Byte 0 : ELO_SYNC_BYTE | | 208 | * Byte 0 : ELO_SYNC_BYTE |
209 | * Byte 1 | | 209 | * Byte 1 |
210 | * ... | | 210 | * ... |
211 | * Byte 8 : packet data | | 211 | * Byte 8 : packet data |
212 | * Byte 9 : checksum of bytes 0 to 8 | | 212 | * Byte 9 : checksum of bytes 0 to 8 |
213 | * | | 213 | * |
214 | * This function returns if a valid packet has been assembled in | | 214 | * This function returns if a valid packet has been assembled in |
215 | * buffer or if no more data is available. | | 215 | * buffer or if no more data is available. |
216 | * | | 216 | * |
217 | * Returns Success if a packet is successfully assembled including | | 217 | * Returns Success if a packet is successfully assembled including |
218 | * testing checksum. If a packet checksum is incorrect, it is discarded. | | 218 | * testing checksum. If a packet checksum is incorrect, it is discarded. |
219 | * Bytes preceding the ELO_SYNC_BYTE are also discarded. | | 219 | * Bytes preceding the ELO_SYNC_BYTE are also discarded. |
220 | * Returns !Success if out of data while reading. The start of the | | 220 | * Returns !Success if out of data while reading. The start of the |
221 | * partially assembled packet is left in buffer, buffer_p and | | 221 | * partially assembled packet is left in buffer, buffer_p and |
222 | * checksum reflect the current state of assembly. | | 222 | * checksum reflect the current state of assembly. |
223 | * | | 223 | * |
224 | *************************************************************************** | | 224 | *************************************************************************** |
225 | */ | | 225 | */ |
226 | static Bool | | 226 | static Bool |
227 | xf86EloGetPacket(unsigned char *buffer, | | 227 | xf86EloGetPacket(unsigned char *buffer, |
228 | int *buffer_p, | | 228 | int *buffer_p, |
229 | int *checksum, | | 229 | int *checksum, |
230 | int fd) | | 230 | int fd) |
231 | { | | 231 | { |
232 | int num_bytes; | | 232 | int num_bytes; |
233 | Bool ok; | | 233 | Bool ok; |
234 | | | 234 | |
235 | DBG(4, ErrorF("Entering xf86EloGetPacket with checksum == %d and buffer_p == %d\n", | | 235 | DBG(4, ErrorF("Entering xf86EloGetPacket with checksum == %d and buffer_p == %d\n", |
236 | *checksum, *buffer_p)); | | 236 | *checksum, *buffer_p)); |
237 | | | 237 | |
238 | /* | | 238 | /* |
239 | * Try to read enough bytes to fill up the packet buffer. | | 239 | * Try to read enough bytes to fill up the packet buffer. |
240 | */ | | 240 | */ |
241 | DBG(4, ErrorF("buffer_p is %d, Trying to read %d bytes from link\n", | | 241 | DBG(4, ErrorF("buffer_p is %d, Trying to read %d bytes from link\n", |
242 | *buffer_p, ELO_PACKET_SIZE - *buffer_p)); | | 242 | *buffer_p, ELO_PACKET_SIZE - *buffer_p)); |
243 | SYSCALL(num_bytes = read(fd, | | 243 | SYSCALL(num_bytes = read(fd, |
244 | (char *) (buffer + *buffer_p), | | 244 | (char *) (buffer + *buffer_p), |
245 | ELO_PACKET_SIZE - *buffer_p)); | | 245 | ELO_PACKET_SIZE - *buffer_p)); |
246 | | | 246 | |
247 | /* | | 247 | /* |
248 | * Okay, give up. | | 248 | * Okay, give up. |
249 | */ | | 249 | */ |
250 | if (num_bytes < 0) { | | 250 | if (num_bytes < 0) { |
251 | ErrorF("System error while reading from Elographics touchscreen."); | | 251 | ErrorF("System error while reading from Elographics touchscreen."); |
252 | return !Success; | | 252 | return !Success; |
253 | } | | 253 | } |
254 | DBG(4, ErrorF("Read %d bytes\n", num_bytes)); | | 254 | DBG(4, ErrorF("Read %d bytes\n", num_bytes)); |
255 | | | 255 | |
256 | while (num_bytes) { | | 256 | while (num_bytes) { |
257 | /* | | 257 | /* |
258 | * Sync with the start of a packet. | | 258 | * Sync with the start of a packet. |
259 | */ | | 259 | */ |
260 | if ((*buffer_p == 0) && (buffer[0] != ELO_SYNC_BYTE)) { | | 260 | if ((*buffer_p == 0) && (buffer[0] != ELO_SYNC_BYTE)) { |
261 | /* | | 261 | /* |
262 | * No match, shift data one byte toward the start of the buffer. | | 262 | * No match, shift data one byte toward the start of the buffer. |
263 | */ | | 263 | */ |
264 | ErrorF("Elographics: Dropping one byte in an attempt to synchronize: '%c' 0x%X\n", | | 264 | ErrorF("Elographics: Dropping one byte in an attempt to synchronize: '%c' 0x%X\n", |
265 | buffer[0], buffer[0]); | | 265 | buffer[0], buffer[0]); |
266 | memcpy(&buffer[0], &buffer[1], num_bytes-1); | | 266 | memcpy(&buffer[0], &buffer[1], num_bytes-1); |
267 | } | | 267 | } |
268 | else { | | 268 | else { |
269 | /* | | 269 | /* |
270 | * Compute checksum in assembly buffer. | | 270 | * Compute checksum in assembly buffer. |
271 | */ | | 271 | */ |
272 | if (*buffer_p < ELO_PACKET_SIZE-1) { | | 272 | if (*buffer_p < ELO_PACKET_SIZE-1) { |
273 | *checksum = *checksum + buffer[*buffer_p]; | | 273 | *checksum = *checksum + buffer[*buffer_p]; |
274 | *checksum = *checksum % 256; | | 274 | *checksum = *checksum % 256; |
275 | DBG(4, ErrorF(" 0x%X-->0x%X ", buffer[*buffer_p], *checksum)); | | 275 | DBG(4, ErrorF(" 0x%X-->0x%X ", buffer[*buffer_p], *checksum)); |
276 | } | | 276 | } |
277 | (*buffer_p)++; | | 277 | (*buffer_p)++; |
278 | } | | 278 | } |
279 | num_bytes--; | | 279 | num_bytes--; |
280 | } | | 280 | } |
281 | | | 281 | |
282 | if (*buffer_p == ELO_PACKET_SIZE) { | | 282 | if (*buffer_p == ELO_PACKET_SIZE) { |
283 | /* | | 283 | /* |
284 | * Got a packet, validate checksum and reset state. | | 284 | * Got a packet, validate checksum and reset state. |
285 | */ | | 285 | */ |
286 | ok = (*checksum == buffer[ELO_PACKET_SIZE-1]); | | 286 | ok = (*checksum == buffer[ELO_PACKET_SIZE-1]); |
287 | DBG(3, ErrorF("Expecting checksum %d, got %d\n", *checksum, buffer[ELO_PACKET_SIZE-1])); | | 287 | DBG(3, ErrorF("Expecting checksum %d, got %d\n", *checksum, buffer[ELO_PACKET_SIZE-1])); |
288 | *checksum = ELO_INIT_CHECKSUM; | | 288 | *checksum = ELO_INIT_CHECKSUM; |
289 | *buffer_p = 0; | | 289 | *buffer_p = 0; |
290 | | | 290 | |
291 | if (!ok) { | | 291 | if (!ok) { |
292 | ErrorF("Checksum error on Elographics touchscreen link\n"); | | 292 | ErrorF("Checksum error on Elographics touchscreen link\n"); |
293 | return !Success; | | 293 | return !Success; |
294 | } | | 294 | } |
295 | | | 295 | |
296 | /* | | 296 | /* |
297 | * Valid packet received report it. | | 297 | * Valid packet received report it. |
298 | */ | | 298 | */ |
299 | return Success; | | 299 | return Success; |
300 | } | | 300 | } |
301 | else { | | 301 | else { |
302 | return !Success; | | 302 | return !Success; |
303 | } | | 303 | } |
304 | } | | 304 | } |
305 | | | 305 | |
306 | | | 306 | |
307 | /* | | 307 | /* |
308 | *************************************************************************** | | 308 | *************************************************************************** |
309 | * | | 309 | * |
310 | * xf86EloReadInput -- | | 310 | * xf86EloReadInput -- |
311 | * Read all pending report packets from the touchscreen and enqueue | | 311 | * Read all pending report packets from the touchscreen and enqueue |
312 | * them. | | 312 | * them. |
313 | * If a packet is not fully received it is deferred until the next | | 313 | * If a packet is not fully received it is deferred until the next |
314 | * call to the function. | | 314 | * call to the function. |
315 | * Packets recognized by this function comply with the format: | | 315 | * Packets recognized by this function comply with the format: |
316 | * | | 316 | * |
317 | * Byte 1 : ELO_TOUCH | | 317 | * Byte 1 : ELO_TOUCH |
318 | * Byte 2 : Packet type | | 318 | * Byte 2 : Packet type |
319 | * Bit 2 : Pen Up (Release) | | 319 | * Bit 2 : Pen Up (Release) |
320 | * Bit 1 : Position (Stream) | | 320 | * Bit 1 : Position (Stream) |
321 | * Bit 0 : Pen Down (Press) | | 321 | * Bit 0 : Pen Down (Press) |
322 | * Byte 3 : X coordinate (lower bits) | | 322 | * Byte 3 : X coordinate (lower bits) |
323 | * Byte 4 : X coordinate (upper bits) | | 323 | * Byte 4 : X coordinate (upper bits) |
324 | * Byte 5 : Y coordinate (lower bits) | | 324 | * Byte 5 : Y coordinate (lower bits) |
325 | * Byte 6 : Y coordinate (upper bits) | | 325 | * Byte 6 : Y coordinate (upper bits) |
326 | * Byte 7 : Z coordinate (lower bits) | | 326 | * Byte 7 : Z coordinate (lower bits) |
327 | * Byte 8 : Z coordinates (upper bits) | | 327 | * Byte 8 : Z coordinates (upper bits) |
328 | * | | 328 | * |
329 | * | | 329 | * |
330 | *************************************************************************** | | 330 | *************************************************************************** |
331 | */ | | 331 | */ |
332 | static void | | 332 | static void |
333 | xf86EloReadInput(InputInfoPtr pInfo) | | 333 | xf86EloReadInput(InputInfoPtr pInfo) |
334 | { | | 334 | { |
335 | EloPrivatePtr priv = (EloPrivatePtr)(pInfo->private); | | 335 | EloPrivatePtr priv = (EloPrivatePtr)(pInfo->private); |
336 | int cur_x, cur_y; | | 336 | int cur_x, cur_y; |
337 | int state; | | 337 | int state; |
338 | | | 338 | |
339 | DBG(4, ErrorF("Entering ReadInput\n")); | | 339 | DBG(4, ErrorF("Entering ReadInput\n")); |
340 | | | 340 | |
341 | /* | | 341 | /* |
342 | * Read bytes until there's no data left. We may have more or less than | | 342 | * Read bytes until there's no data left. We may have more or less than |
343 | * one packet worth of data in the OS buffer. | | 343 | * one packet worth of data in the OS buffer. |
344 | */ | | 344 | */ |
345 | do { | | 345 | do { |
346 | if(xf86EloGetPacket(priv->packet_buf, | | 346 | if(xf86EloGetPacket(priv->packet_buf, |
347 | &priv->packet_buf_p, | | 347 | &priv->packet_buf_p, |
348 | &priv->checksum, | | 348 | &priv->checksum, |
349 | pInfo->fd) != Success) | | 349 | pInfo->fd) != Success) |
350 | continue; | | 350 | continue; |
351 | | | 351 | |
352 | /* | | 352 | /* |
353 | * Process only ELO_TOUCHs here. | | 353 | * Process only ELO_TOUCHs here. |
354 | */ | | 354 | */ |
355 | if (priv->packet_buf[1] == ELO_TOUCH) { | | 355 | if (priv->packet_buf[1] == ELO_TOUCH) { |
356 | /* | | 356 | /* |
357 | * First stick together the various pieces. | | 357 | * First stick together the various pieces. |
358 | */ | | 358 | */ |
359 | cur_x = WORD_ASSEMBLY(priv->packet_buf[3], priv->packet_buf[4]); | | 359 | cur_x = WORD_ASSEMBLY(priv->packet_buf[3], priv->packet_buf[4]); |
360 | cur_y = WORD_ASSEMBLY(priv->packet_buf[5], priv->packet_buf[6]); | | 360 | cur_y = WORD_ASSEMBLY(priv->packet_buf[5], priv->packet_buf[6]); |
361 | state = priv->packet_buf[2] & 0x07; | | 361 | state = priv->packet_buf[2] & 0x07; |
362 | | | 362 | |
| | | 363 | DBG(5, ErrorF("ELO got: x(%d), y(%d), %s\n", |
| | | 364 | cur_x, cur_y, |
| | | 365 | (state == ELO_PRESS) ? "Press" : |
| | | 366 | ((state == ELO_RELEASE) ? "Release" : "Stream"))); |
| | | 367 | |
| | | 368 | if (priv->min_y > priv->max_y) { |
| | | 369 | /* inverted y axis */ |
| | | 370 | cur_y = priv->max_y - cur_y + priv->min_y; |
| | | 371 | } |
| | | 372 | |
| | | 373 | if (priv->min_x > priv->max_x) { |
| | | 374 | /* inverted x axis */ |
| | | 375 | cur_x = priv->max_x - cur_x + priv->min_x; |
| | | 376 | } |
| | | 377 | |
| | | 378 | |
363 | /* | | 379 | /* |
364 | * Send events. | | 380 | * Send events. |
365 | * | | 381 | * |
366 | * We *must* generate a motion before a button change if pointer | | 382 | * We *must* generate a motion before a button change if pointer |
367 | * location has changed as DIX assumes this. This is why we always | | 383 | * location has changed as DIX assumes this. This is why we always |
368 | * emit a motion, regardless of the kind of packet processed. | | 384 | * emit a motion, regardless of the kind of packet processed. |
369 | */ | | 385 | */ |
370 | xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, cur_x, cur_y); | | 386 | xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, cur_x, cur_y); |
371 | | | 387 | |
372 | /* | | 388 | /* |
373 | * Emit a button press or release. | | 389 | * Emit a button press or release. |
374 | */ | | 390 | */ |
375 | if (state == ELO_PRESS || state == ELO_RELEASE) { | | 391 | if (state == ELO_PRESS || state == ELO_RELEASE) { |
376 | xf86PostButtonEvent(pInfo->dev, TRUE, 1, state == ELO_PRESS, 0, 2, cur_x, cur_y); | | 392 | xf86PostButtonEvent(pInfo->dev, TRUE, 1, state == ELO_PRESS, 0, 2, cur_x, cur_y); |
377 | } | | 393 | } |
378 | | | 394 | |
379 | DBG(3, ErrorF("TouchScreen: x(%d), y(%d), %s\n", | | 395 | DBG(3, ErrorF("TouchScreen: x(%d), y(%d), %s\n", |
380 | cur_x, cur_y, | | 396 | cur_x, cur_y, |
381 | (state == ELO_PRESS) ? "Press" : ((state == ELO_RELEASE) ? "Release" : "Stream"))); | | 397 | (state == ELO_PRESS) ? "Press" : ((state == ELO_RELEASE) ? "Release" : "Stream"))); |
382 | } | | 398 | } |
383 | } | | 399 | } |
384 | while (xf86WaitForInput(pInfo->fd, 0) > 0); /* don't wait, just check */ | | 400 | while (xf86WaitForInput(pInfo->fd, 0) > 0); /* don't wait, just check */ |
385 | } | | 401 | } |
386 | | | 402 | |
387 | | | 403 | |
388 | /* | | 404 | /* |
389 | *************************************************************************** | | 405 | *************************************************************************** |
390 | * | | 406 | * |
391 | * xf86EloSendPacket -- | | 407 | * xf86EloSendPacket -- |
392 | * Emit an height bytes packet to the controller. | | 408 | * Emit an height bytes packet to the controller. |
393 | * The function expects a valid buffer containing the | | 409 | * The function expects a valid buffer containing the |
394 | * command to be sent to the controller. It fills it with the | | 410 | * command to be sent to the controller. It fills it with the |
395 | * leading sync character an the trailing checksum byte. | | 411 | * leading sync character an the trailing checksum byte. |
396 | * | | 412 | * |
397 | *************************************************************************** | | 413 | *************************************************************************** |
398 | */ | | 414 | */ |
399 | static Bool | | 415 | static Bool |
400 | xf86EloSendPacket(unsigned char *packet, | | 416 | xf86EloSendPacket(unsigned char *packet, |
401 | int fd) | | 417 | int fd) |
402 | { | | 418 | { |
403 | int i, result; | | 419 | int i, result; |
404 | int sum = ELO_INIT_CHECKSUM; | | 420 | int sum = ELO_INIT_CHECKSUM; |
405 | | | 421 | |
406 | packet[0] = ELO_SYNC_BYTE; | | 422 | packet[0] = ELO_SYNC_BYTE; |
407 | for (i = 0; i < ELO_PACKET_SIZE-1; i++) { | | 423 | for (i = 0; i < ELO_PACKET_SIZE-1; i++) { |
408 | sum += packet[i]; | | 424 | sum += packet[i]; |
409 | sum &= 0xFF; | | 425 | sum &= 0xFF; |
410 | } | | 426 | } |
411 | packet[ELO_PACKET_SIZE-1] = sum; | | 427 | packet[ELO_PACKET_SIZE-1] = sum; |
412 | | | 428 | |
413 | DBG(4, ErrorF("Sending packet : 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X \n", | | 429 | DBG(4, ErrorF("Sending packet : 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X \n", |
414 | packet[0], packet[1], packet[2], packet[3], packet[4], | | 430 | packet[0], packet[1], packet[2], packet[3], packet[4], |
415 | packet[5], packet[6], packet[7], packet[8], packet[9])); | | 431 | packet[5], packet[6], packet[7], packet[8], packet[9])); |
416 | SYSCALL(result = write(fd, packet, ELO_PACKET_SIZE)); | | 432 | SYSCALL(result = write(fd, packet, ELO_PACKET_SIZE)); |
417 | if (result != ELO_PACKET_SIZE) { | | 433 | if (result != ELO_PACKET_SIZE) { |
418 | DBG(5, ErrorF("System error while sending to Elographics touchscreen.\n")); | | 434 | DBG(5, ErrorF("System error while sending to Elographics touchscreen.\n")); |
419 | return !Success; | | 435 | return !Success; |
420 | } | | 436 | } |
421 | else { | | 437 | else { |
422 | return Success; | | 438 | return Success; |
423 | } | | 439 | } |
424 | } | | 440 | } |
425 | | | 441 | |
426 | | | 442 | |
427 | /* | | 443 | /* |
428 | *************************************************************************** | | 444 | *************************************************************************** |
429 | * | | 445 | * |
430 | * xf86EloWaitReply -- | | 446 | * xf86EloWaitReply -- |
431 | * It is assumed that the reply will be in the few next bytes | | 447 | * It is assumed that the reply will be in the few next bytes |
432 | * read and will be available very soon after the query post. if | | 448 | * read and will be available very soon after the query post. if |
433 | * these two asumptions are not met, there are chances that the server | | 449 | * these two asumptions are not met, there are chances that the server |
434 | * will be stuck for a while. | | 450 | * will be stuck for a while. |
435 | * The reply type need to match parameter 'type'. | | 451 | * The reply type need to match parameter 'type'. |
436 | * The reply is left in reply. The function returns Success if the | | 452 | * The reply is left in reply. The function returns Success if the |
437 | * reply is valid and !Success otherwise. | | 453 | * reply is valid and !Success otherwise. |
438 | * | | 454 | * |
439 | *************************************************************************** | | 455 | *************************************************************************** |
440 | */ | | 456 | */ |
441 | | | 457 | |
442 | static Bool | | 458 | static Bool |
443 | xf86EloWaitReply(unsigned char type, | | 459 | xf86EloWaitReply(unsigned char type, |
444 | unsigned char *reply, | | 460 | unsigned char *reply, |
445 | int fd) | | 461 | int fd) |
446 | { | | 462 | { |
447 | Bool ok; | | 463 | Bool ok; |
448 | int i, result; | | 464 | int i, result; |
449 | int reply_p = 0; | | 465 | int reply_p = 0; |
450 | int sum = ELO_INIT_CHECKSUM; | | 466 | int sum = ELO_INIT_CHECKSUM; |
451 | | | 467 | |
452 | DBG(4, ErrorF("Waiting a '%c' reply\n", type)); | | 468 | DBG(4, ErrorF("Waiting a '%c' reply\n", type)); |
453 | i = ELO_MAX_TRIALS; | | 469 | i = ELO_MAX_TRIALS; |
454 | do { | | 470 | do { |
455 | ok = !Success; | | 471 | ok = !Success; |
456 | | | 472 | |
457 | /* | | 473 | /* |
458 | * Wait half a second for the reply. The fuse counts down each | | 474 | * Wait half a second for the reply. The fuse counts down each |
459 | * timeout and each wrong packet. | | 475 | * timeout and each wrong packet. |
460 | */ | | 476 | */ |
461 | DBG(4, ErrorF("Waiting %d ms for data from port\n", ELO_MAX_WAIT / 1000)); | | 477 | DBG(4, ErrorF("Waiting %d ms for data from port\n", ELO_MAX_WAIT / 1000)); |
462 | result = xf86WaitForInput(fd, ELO_MAX_WAIT); | | 478 | result = xf86WaitForInput(fd, ELO_MAX_WAIT); |
463 | if (result > 0) { | | 479 | if (result > 0) { |
464 | ok = xf86EloGetPacket(reply, &reply_p, &sum, fd); | | 480 | ok = xf86EloGetPacket(reply, &reply_p, &sum, fd); |
465 | /* | | 481 | /* |
466 | * Do not report an error on a 'P' query as the controller | | 482 | * Do not report an error on a 'P' query as the controller |
467 | * might be a 2310. | | 483 | * might be a 2310. |
468 | */ | | 484 | */ |
469 | if (ok == Success && reply[1] != type && type != ELO_PARAMETER) { | | 485 | if (ok == Success && reply[1] != type && type != ELO_PARAMETER) { |
470 | DBG(3, ErrorF("Wrong reply received\n")); | | 486 | DBG(3, ErrorF("Wrong reply received\n")); |
471 | ok = !Success; | | 487 | ok = !Success; |
472 | } | | 488 | } |
473 | } | | 489 | } |
474 | else { | | 490 | else { |
475 | DBG(3, ErrorF("No answer from link : %d\n", result)); | | 491 | DBG(3, ErrorF("No answer from link : %d\n", result)); |
476 | } | | 492 | } |
477 | | | 493 | |
478 | if (result == 0) { | | 494 | if (result == 0) { |
479 | i--; | | 495 | i--; |
480 | } | | 496 | } |
481 | } while(ok != Success && i); | | 497 | } while(ok != Success && i); |
482 | | | 498 | |
483 | return ok; | | 499 | return ok; |
484 | } | | 500 | } |
485 | | | 501 | |
486 | | | 502 | |
487 | /* | | 503 | /* |
488 | *************************************************************************** | | 504 | *************************************************************************** |
489 | * | | 505 | * |
490 | * xf86EloWaitAck -- | | 506 | * xf86EloWaitAck -- |
491 | * Wait for an acknowledge from the controller. Returns Success if | | 507 | * Wait for an acknowledge from the controller. Returns Success if |
492 | * acknowledge received and reported no errors. | | 508 | * acknowledge received and reported no errors. |
493 | * | | 509 | * |
494 | *************************************************************************** | | 510 | *************************************************************************** |
495 | */ | | 511 | */ |
496 | static Bool | | 512 | static Bool |
497 | xf86EloWaitAck(int fd) | | 513 | xf86EloWaitAck(int fd) |
498 | { | | 514 | { |
499 | unsigned char packet[ELO_PACKET_SIZE]; | | 515 | unsigned char packet[ELO_PACKET_SIZE]; |
500 | int i, nb_errors; | | 516 | int i, nb_errors; |
501 | | | 517 | |
502 | if (xf86EloWaitReply(ELO_ACK, packet, fd) == Success) { | | 518 | if (xf86EloWaitReply(ELO_ACK, packet, fd) == Success) { |
503 | for (i = 0, nb_errors = 0; i < 4; i++) { | | 519 | for (i = 0, nb_errors = 0; i < 4; i++) { |
504 | if (packet[2 + i] != '0') { | | 520 | if (packet[2 + i] != '0') { |
505 | nb_errors++; | | 521 | nb_errors++; |
506 | } | | 522 | } |
507 | } | | 523 | } |
508 | if (nb_errors != 0) { | | 524 | if (nb_errors != 0) { |
509 | DBG(2, ErrorF("Elographics acknowledge packet reports %d errors\n", | | 525 | DBG(2, ErrorF("Elographics acknowledge packet reports %d errors\n", |
510 | nb_errors)); | | 526 | nb_errors)); |
511 | } | | 527 | } |
512 | return Success; | | 528 | return Success; |
513 | /* return (nb_errors < 4) ? Success : !Success;*/ | | 529 | /* return (nb_errors < 4) ? Success : !Success;*/ |
514 | } | | 530 | } |
515 | else { | | 531 | else { |
516 | return !Success; | | 532 | return !Success; |
517 | } | | 533 | } |
518 | } | | 534 | } |
519 | | | 535 | |
520 | | | 536 | |
521 | /* | | 537 | /* |
522 | *************************************************************************** | | 538 | *************************************************************************** |
523 | * | | 539 | * |
524 | * xf86EloSendQuery -- | | 540 | * xf86EloSendQuery -- |
525 | * Emit a query to the controller and blocks until the reply and | | 541 | * Emit a query to the controller and blocks until the reply and |
526 | * the acknowledge are read. | | 542 | * the acknowledge are read. |
527 | * | | 543 | * |
528 | * The reply is left in reply. The function returns Success if the | | 544 | * The reply is left in reply. The function returns Success if the |
529 | * reply is valid and !Success otherwise. | | 545 | * reply is valid and !Success otherwise. |
530 | * | | 546 | * |
531 | *************************************************************************** | | 547 | *************************************************************************** |
532 | */ | | 548 | */ |
533 | static Bool | | 549 | static Bool |
534 | xf86EloSendQuery(unsigned char *request, | | 550 | xf86EloSendQuery(unsigned char *request, |
535 | unsigned char *reply, | | 551 | unsigned char *reply, |
536 | int fd) | | 552 | int fd) |
537 | { | | 553 | { |
538 | Bool ok; | | 554 | Bool ok; |
539 | | | 555 | |
540 | if (xf86EloSendPacket(request, fd) == Success) { | | 556 | if (xf86EloSendPacket(request, fd) == Success) { |
541 | ok = xf86EloWaitReply(toupper(request[1]), reply, fd); | | 557 | ok = xf86EloWaitReply(toupper(request[1]), reply, fd); |
542 | if (ok == Success) { | | 558 | if (ok == Success) { |
543 | ok = xf86EloWaitAck(fd); | | 559 | ok = xf86EloWaitAck(fd); |
544 | } | | 560 | } |
545 | return ok; | | 561 | return ok; |
546 | } | | 562 | } |
547 | else { | | 563 | else { |
548 | return !Success; | | 564 | return !Success; |
549 | } | | 565 | } |
550 | } | | 566 | } |
551 | | | 567 | |
552 | | | 568 | |
553 | /* | | 569 | /* |
554 | *************************************************************************** | | 570 | *************************************************************************** |
555 | * | | 571 | * |
556 | * xf86EloSendControl -- | | 572 | * xf86EloSendControl -- |
557 | * Emit a control command to the controller and wait for acknowledge. | | 573 | * Emit a control command to the controller and wait for acknowledge. |
558 | * | | 574 | * |
559 | * Returns Success if acknowledge received and reported no error. | | 575 | * Returns Success if acknowledge received and reported no error. |
560 | * | | 576 | * |
561 | *************************************************************************** | | 577 | *************************************************************************** |
562 | */ | | 578 | */ |
563 | static Bool | | 579 | static Bool |
564 | xf86EloSendControl(unsigned char *control, | | 580 | xf86EloSendControl(unsigned char *control, |
565 | int fd) | | 581 | int fd) |
566 | { | | 582 | { |
567 | if (xf86EloSendPacket(control, fd) == Success) { | | 583 | if (xf86EloSendPacket(control, fd) == Success) { |
568 | return xf86EloWaitAck(fd); | | 584 | return xf86EloWaitAck(fd); |
569 | } | | 585 | } |
570 | else { | | 586 | else { |
571 | return !Success; | | 587 | return !Success; |
572 | } | | 588 | } |
573 | } | | 589 | } |
574 | | | 590 | |
575 | | | 591 | |
576 | /* | | 592 | /* |
577 | *************************************************************************** | | 593 | *************************************************************************** |
578 | * | | 594 | * |
579 | * xf86EloPrintIdent -- | | 595 | * xf86EloPrintIdent -- |
580 | * Print type of touchscreen and features on controller board. | | 596 | * Print type of touchscreen and features on controller board. |
581 | * | | 597 | * |
582 | *************************************************************************** | | 598 | *************************************************************************** |
583 | */ | | 599 | */ |
584 | static void | | 600 | static void |
585 | xf86EloPrintIdent(unsigned char *packet, | | 601 | xf86EloPrintIdent(unsigned char *packet, |
586 | EloPrivatePtr priv) | | 602 | EloPrivatePtr priv) |
587 | { | | 603 | { |
588 | xf86Msg(X_PROBED, "Elographics touchscreen is a "); | | 604 | xf86Msg(X_PROBED, "Elographics touchscreen is a "); |
589 | switch(packet[2]) { | | 605 | switch(packet[2]) { |
590 | case '0': | | 606 | case '0': |
591 | xf86Msg(X_NONE, "AccuTouch"); | | 607 | xf86Msg(X_NONE, "AccuTouch"); |
592 | break; | | 608 | break; |
593 | case '1': | | 609 | case '1': |
594 | xf86Msg(X_NONE, "DuraTouch"); | | 610 | xf86Msg(X_NONE, "DuraTouch"); |
595 | break; | | 611 | break; |
596 | case '2': | | 612 | case '2': |
597 | xf86Msg(X_NONE, "Intellitouch"); | | 613 | xf86Msg(X_NONE, "Intellitouch"); |
598 | break; | | 614 | break; |
599 | } | | 615 | } |
600 | xf86Msg(X_NONE, ", connected through a "); | | 616 | xf86Msg(X_NONE, ", connected through a "); |
601 | switch(packet[3]) { | | 617 | switch(packet[3]) { |
602 | case '0': | | 618 | case '0': |
603 | xf86Msg(X_NONE, "serial link.\n"); | | 619 | xf86Msg(X_NONE, "serial link.\n"); |
604 | break; | | 620 | break; |
605 | case '1': | | 621 | case '1': |
606 | xf86Msg(X_NONE, "PC-Bus port.\n"); | | 622 | xf86Msg(X_NONE, "PC-Bus port.\n"); |
607 | break; | | 623 | break; |
608 | case '2': | | 624 | case '2': |
609 | xf86Msg(X_NONE, "Micro Channel port.\n"); | | 625 | xf86Msg(X_NONE, "Micro Channel port.\n"); |
610 | break; | | 626 | break; |
611 | } | | 627 | } |
612 | xf86Msg(X_PROBED, "The controller is a model "); | | 628 | xf86Msg(X_PROBED, "The controller is a model "); |
613 | if (packet[8] & 1) { | | 629 | if (packet[8] & 1) { |
614 | if (priv->is_a_2310) { | | 630 | if (priv->is_a_2310) { |
615 | xf86Msg(X_NONE, "E281-2310"); | | 631 | xf86Msg(X_NONE, "E281-2310"); |
616 | } | | 632 | } |
617 | else { | | 633 | else { |
618 | xf86Msg(X_NONE, "E271-2210"); | | 634 | xf86Msg(X_NONE, "E271-2210"); |
619 | } | | 635 | } |
620 | } | | 636 | } |
621 | else { | | 637 | else { |
622 | xf86Msg(X_NONE, "E271-2200"); | | 638 | xf86Msg(X_NONE, "E271-2200"); |
623 | } | | 639 | } |
624 | xf86Msg(X_NONE, ", firmware revision %d.%d.\n", packet[6], packet[5]); | | 640 | xf86Msg(X_NONE, ", firmware revision %d.%d.\n", packet[6], packet[5]); |
625 | | | 641 | |
626 | if (packet[4]) { | | 642 | if (packet[4]) { |
627 | xf86Msg(X_PROBED, " Additional features:\n"); | | 643 | xf86Msg(X_PROBED, " Additional features:\n"); |
628 | if (packet[4] & 0x10) { | | 644 | if (packet[4] & 0x10) { |
629 | xf86Msg(X_PROBED, " External A/D converter\n"); | | 645 | xf86Msg(X_PROBED, " External A/D converter\n"); |
630 | } | | 646 | } |
631 | if (packet[4] & 0x20) { | | 647 | if (packet[4] & 0x20) { |
632 | xf86Msg(X_PROBED, " 32Ko RAM\n"); | | 648 | xf86Msg(X_PROBED, " 32Ko RAM\n"); |
633 | } | | 649 | } |
634 | if (packet[4] & 0x40) { | | 650 | if (packet[4] & 0x40) { |
635 | xf86Msg(X_PROBED, " RAM onboard\n"); | | 651 | xf86Msg(X_PROBED, " RAM onboard\n"); |
636 | } | | 652 | } |
637 | if (packet[4] & 0x80) { | | 653 | if (packet[4] & 0x80) { |
638 | xf86Msg(X_PROBED, " Z axis active\n"); | | 654 | xf86Msg(X_PROBED, " Z axis active\n"); |
639 | } | | 655 | } |
640 | xf86Msg(X_NONE, "\n"); | | 656 | xf86Msg(X_NONE, "\n"); |
641 | } | | 657 | } |
642 | } | | 658 | } |
643 | | | 659 | |
644 | | | 660 | |
645 | /* | | 661 | /* |
646 | *************************************************************************** | | 662 | *************************************************************************** |
647 | * | | 663 | * |
648 | * xf86EloPtrControl -- | | 664 | * xf86EloPtrControl -- |
649 | * | | 665 | * |
650 | *************************************************************************** | | 666 | *************************************************************************** |
651 | */ | | 667 | */ |
652 | | | 668 | |
653 | static void | | 669 | static void |
654 | xf86EloPtrControl(DeviceIntPtr dev, | | 670 | xf86EloPtrControl(DeviceIntPtr dev, |
655 | PtrCtrl *ctrl) | | 671 | PtrCtrl *ctrl) |
656 | { | | 672 | { |
657 | } | | 673 | } |
658 | | | 674 | |
659 | | | 675 | |
660 | | | 676 | |
661 | /* | | 677 | /* |
662 | *************************************************************************** | | 678 | *************************************************************************** |
663 | * | | 679 | * |
664 | * xf86EloControl -- | | 680 | * xf86EloControl -- |
665 | * | | 681 | * |
666 | *************************************************************************** | | 682 | *************************************************************************** |
667 | */ | | 683 | */ |
668 | static Bool | | 684 | static Bool |
669 | xf86EloControl(DeviceIntPtr dev, | | 685 | xf86EloControl(DeviceIntPtr dev, |
670 | int mode) | | 686 | int mode) |
671 | { | | 687 | { |
672 | InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; | | 688 | InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; |
673 | EloPrivatePtr priv = (EloPrivatePtr)(pInfo->private); | | 689 | EloPrivatePtr priv = (EloPrivatePtr)(pInfo->private); |
674 | unsigned char map[] = { 0, 1 }; | | 690 | unsigned char map[] = { 0, 1 }; |
675 | unsigned char req[ELO_PACKET_SIZE]; | | 691 | unsigned char req[ELO_PACKET_SIZE]; |
676 | unsigned char reply[ELO_PACKET_SIZE]; | | 692 | unsigned char reply[ELO_PACKET_SIZE]; |
677 | Atom btn_label; | | 693 | Atom btn_label; |
678 | Atom axis_labels[2] = { 0, 0 }; | | 694 | Atom axis_labels[2] = { 0, 0 }; |
| | | 695 | int x0, x1, y0, y1; |
679 | | | 696 | |
680 | switch(mode) { | | 697 | switch(mode) { |
681 | | | 698 | |
682 | case DEVICE_INIT: | | 699 | case DEVICE_INIT: |
683 | { | | 700 | { |
684 | DBG(2, ErrorF("Elographics touchscreen init...\n")); | | 701 | DBG(2, ErrorF("Elographics touchscreen init...\n")); |
685 | | | 702 | |
686 | if (priv->screen_no >= screenInfo.numScreens || | | 703 | if (priv->screen_no >= screenInfo.numScreens || |
687 | priv->screen_no < 0) { | | 704 | priv->screen_no < 0) { |
688 | priv->screen_no = 0; | | 705 | priv->screen_no = 0; |
689 | } | | 706 | } |
690 | priv->screen_width = screenInfo.screens[priv->screen_no]->width; | | 707 | priv->screen_width = screenInfo.screens[priv->screen_no]->width; |
691 | priv->screen_height = screenInfo.screens[priv->screen_no]->height; | | 708 | priv->screen_height = screenInfo.screens[priv->screen_no]->height; |
692 | | | 709 | |
693 | /* | | 710 | /* |
694 | * Device reports button press for up to 1 button. | | 711 | * Device reports button press for up to 1 button. |
695 | */ | | 712 | */ |
696 | if (InitButtonClassDeviceStruct(dev, 1, &btn_label, map) == FALSE) { | | 713 | if (InitButtonClassDeviceStruct(dev, 1, &btn_label, map) == FALSE) { |
697 | ErrorF("Unable to allocate Elographics touchscreen ButtonClassDeviceStruct\n"); | | 714 | ErrorF("Unable to allocate Elographics touchscreen ButtonClassDeviceStruct\n"); |
698 | return !Success; | | 715 | return !Success; |
699 | } | | 716 | } |
700 | | | 717 | |
701 | if (InitFocusClassDeviceStruct(dev) == FALSE) { | | 718 | if (InitFocusClassDeviceStruct(dev) == FALSE) { |
702 | ErrorF("Unable to allocate Elographics touchscreen FocusClassDeviceStruct\n"); | | 719 | ErrorF("Unable to allocate Elographics touchscreen FocusClassDeviceStruct\n"); |
703 | return !Success; | | 720 | return !Success; |
704 | } | | 721 | } |
705 | if (InitPtrFeedbackClassDeviceStruct(dev, xf86EloPtrControl) == FALSE) { | | 722 | if (InitPtrFeedbackClassDeviceStruct(dev, xf86EloPtrControl) == FALSE) { |
706 | ErrorF("unable to init ptr feedback\n"); | | 723 | ErrorF("unable to init ptr feedback\n"); |
707 | return !Success; | | 724 | return !Success; |
708 | } | | 725 | } |
709 | /* | | 726 | /* |
710 | * Device reports motions on 2 axes in absolute coordinates. | | 727 | * Device reports motions on 2 axes in absolute coordinates. |
711 | * Axes min and max values are reported in raw coordinates. | | 728 | * Axes min and max values are reported in raw coordinates. |
712 | * Resolution is computed roughly by the difference between | | 729 | * Resolution is computed roughly by the difference between |
713 | * max and min values scaled from the approximate size of the | | 730 | * max and min values scaled from the approximate size of the |
714 | * screen to fit one meter. | | 731 | * screen to fit one meter. |
715 | */ | | 732 | */ |
716 | if (InitValuatorClassDeviceStruct(dev, 2, axis_labels, | | 733 | if (InitValuatorClassDeviceStruct(dev, 2, axis_labels, |
717 | GetMotionHistorySize(), Absolute) == FALSE) { | | 734 | GetMotionHistorySize(), Absolute) == FALSE) { |
718 | ErrorF("Unable to allocate Elographics touchscreen ValuatorClassDeviceStruct\n"); | | 735 | ErrorF("Unable to allocate Elographics touchscreen ValuatorClassDeviceStruct\n"); |
719 | return !Success; | | 736 | return !Success; |
720 | } | | 737 | } |
721 | else { | | 738 | else { |
| | | 739 | |
| | | 740 | /* Correct the coordinates for possibly inverted axis. |
| | | 741 | Leave priv->variables untouched so we can check for |
| | | 742 | inversion on incoming events. |
| | | 743 | */ |
| | | 744 | y0 = min(priv->min_y, priv->max_y); |
| | | 745 | y1 = max(priv->min_y, priv->max_y); |
| | | 746 | x0 = min(priv->min_x, priv->max_x); |
| | | 747 | x1 = max(priv->min_x, priv->max_x); |
| | | 748 | |
722 | /* I will map coordinates myself */ | | 749 | /* I will map coordinates myself */ |
723 | InitValuatorAxisStruct(dev, 0, | | 750 | InitValuatorAxisStruct(dev, 0, |
724 | axis_labels[0], | | 751 | axis_labels[0], |
725 | priv->min_x, priv->max_x, | | 752 | x0, x1, |
726 | 9500, | | 753 | 9500, |
727 | 0 /* min_res */, | | 754 | 0 /* min_res */, |
728 | 9500 /* max_res */, | | 755 | 9500 /* max_res */, |
729 | Absolute); | | 756 | Absolute); |
730 | InitValuatorAxisStruct(dev, 1, | | 757 | InitValuatorAxisStruct(dev, 1, |
731 | axis_labels[1], | | 758 | axis_labels[1], |
732 | priv->min_y, priv->max_y, | | 759 | y0, y1, |
733 | 10500, | | 760 | 10500, |
734 | 0 /* min_res */, | | 761 | 0 /* min_res */, |
735 | 10500 /* max_res */, | | 762 | 10500 /* max_res */, |
736 | Absolute); | | 763 | Absolute); |
737 | } | | 764 | } |
738 | | | 765 | |
739 | if (InitFocusClassDeviceStruct(dev) == FALSE) { | | 766 | if (InitFocusClassDeviceStruct(dev) == FALSE) { |
740 | ErrorF("Unable to allocate Elographics touchscreen FocusClassDeviceStruct\n"); | | 767 | ErrorF("Unable to allocate Elographics touchscreen FocusClassDeviceStruct\n"); |
741 | } | | 768 | } |
742 | | | 769 | |
743 | /* | | 770 | /* |
744 | * Allocate the motion events buffer. | | 771 | * Allocate the motion events buffer. |
745 | */ | | 772 | */ |
746 | xf86MotionHistoryAllocate(pInfo); | | 773 | xf86MotionHistoryAllocate(pInfo); |
747 | | | 774 | |
748 | | | 775 | |
749 | DBG(2, ErrorF("Done.\n")); | | 776 | DBG(2, ErrorF("Done.\n")); |
750 | return Success; | | 777 | return Success; |
751 | } | | 778 | } |
752 | | | 779 | |
753 | case DEVICE_ON: | | 780 | case DEVICE_ON: |
754 | DBG(2, ErrorF("Elographics touchscreen on...\n")); | | 781 | DBG(2, ErrorF("Elographics touchscreen on...\n")); |
755 | | | 782 | |
756 | if (pInfo->fd < 0) { | | 783 | if (pInfo->fd < 0) { |
757 | | | 784 | |
758 | DBG(2, ErrorF("Elographics touchscreen opening : %s\n", priv->input_dev)); | | 785 | DBG(2, ErrorF("Elographics touchscreen opening : %s\n", priv->input_dev)); |
759 | pInfo->fd = xf86OpenSerial(pInfo->options); | | 786 | pInfo->fd = xf86OpenSerial(pInfo->options); |
760 | if (pInfo->fd < 0) { | | 787 | if (pInfo->fd < 0) { |
761 | ErrorF("Unable to open Elographics touchscreen device"); | | 788 | ErrorF("Unable to open Elographics touchscreen device"); |
762 | return !Success; | | 789 | return !Success; |
763 | } | | 790 | } |
764 | | | 791 | |
765 | if (priv->model != MODEL_SUNIT_D) | | 792 | if (priv->model != MODEL_SUNIT_D) |
766 | { | | 793 | { |
767 | /* | | 794 | /* |
768 | * Try to see if the link is at the specified rate and | | 795 | * Try to see if the link is at the specified rate and |
769 | * ask the controller to report various infos. | | 796 | * ask the controller to report various infos. |
770 | */ | | 797 | */ |
771 | memset(req, 0, ELO_PACKET_SIZE); | | 798 | memset(req, 0, ELO_PACKET_SIZE); |
772 | req[1] = tolower(ELO_PARAMETER); | | 799 | req[1] = tolower(ELO_PARAMETER); |
773 | if (xf86EloSendQuery(req, reply, pInfo->fd) != Success) { | | 800 | if (xf86EloSendQuery(req, reply, pInfo->fd) != Success) { |
774 | priv->is_a_2310 = 1; | | 801 | priv->is_a_2310 = 1; |
775 | ErrorF("Not at the specified rate or model 2310, will continue\n"); | | 802 | ErrorF("Not at the specified rate or model 2310, will continue\n"); |
776 | } | | 803 | } |
777 | | | 804 | |
778 | /* | | 805 | /* |
779 | * Ask the controller to report various infos. | | 806 | * Ask the controller to report various infos. |
780 | */ | | 807 | */ |
781 | memset(req, 0, ELO_PACKET_SIZE); | | 808 | memset(req, 0, ELO_PACKET_SIZE); |
782 | req[1] = tolower(ELO_ID); | | 809 | req[1] = tolower(ELO_ID); |
783 | if (xf86EloSendQuery(req, reply, pInfo->fd) == Success) { | | 810 | if (xf86EloSendQuery(req, reply, pInfo->fd) == Success) { |
784 | xf86EloPrintIdent(reply, priv); | | 811 | xf86EloPrintIdent(reply, priv); |
785 | } | | 812 | } |
786 | else { | | 813 | else { |
787 | DBG(2, ErrorF("Unable to ask Elographics touchscreen identification... Maybe it's GeneralTouch touchscreen...\n")); | | 814 | DBG(2, ErrorF("Unable to ask Elographics touchscreen identification... Maybe it's GeneralTouch touchscreen...\n")); |
788 | } | | 815 | } |
789 | | | 816 | |
790 | /* | | 817 | /* |
791 | * Set the operating mode: Stream, no scaling, no calibration, | | 818 | * Set the operating mode: Stream, no scaling, no calibration, |
792 | * no range checking, no trim, tracking enabled. | | 819 | * no range checking, no trim, tracking enabled. |
793 | */ | | 820 | */ |
794 | memset(req, 0, ELO_PACKET_SIZE); | | 821 | memset(req, 0, ELO_PACKET_SIZE); |
795 | req[1] = ELO_MODE; | | 822 | req[1] = ELO_MODE; |
796 | req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE; | | 823 | req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE; |
797 | req[4] = ELO_TRACKING_MODE; | | 824 | req[4] = ELO_TRACKING_MODE; |
798 | if (xf86EloSendControl(req, pInfo->fd) != Success) { | | 825 | if (xf86EloSendControl(req, pInfo->fd) != Success) { |
799 | DBG(2, ErrorF("Unable to change Elographics touchscreen operating mode... Maybe it's GeneralTouch touchscreen...\n")); | | 826 | DBG(2, ErrorF("Unable to change Elographics touchscreen operating mode... Maybe it's GeneralTouch touchscreen...\n")); |
800 | } | | 827 | } |
801 | | | 828 | |
802 | /* | | 829 | /* |
803 | * Set the touch reports timings from configuration data. | | 830 | * Set the touch reports timings from configuration data. |
804 | */ | | 831 | */ |
805 | memset(req, 0, ELO_PACKET_SIZE); | | 832 | memset(req, 0, ELO_PACKET_SIZE); |
806 | req[1] = ELO_REPORT; | | 833 | req[1] = ELO_REPORT; |
807 | req[2] = priv->untouch_delay; | | 834 | req[2] = priv->untouch_delay; |
808 | req[3] = priv->report_delay; | | 835 | req[3] = priv->report_delay; |
809 | if (xf86EloSendControl(req, pInfo->fd) != Success) { | | 836 | if (xf86EloSendControl(req, pInfo->fd) != Success) { |
810 | DBG(2, ErrorF("Unable to change Elographics touchscreen reports timings... Maybe it's GeneralTouch touchscreen...\n")); | | 837 | DBG(2, ErrorF("Unable to change Elographics touchscreen reports timings... Maybe it's GeneralTouch touchscreen...\n")); |
811 | } | | 838 | } |
812 | } | | 839 | } |
813 | xf86AddEnabledDevice(pInfo); | | 840 | xf86AddEnabledDevice(pInfo); |
814 | dev->public.on = TRUE; | | 841 | dev->public.on = TRUE; |
815 | } | | 842 | } |
816 | | | 843 | |
817 | DBG(2, ErrorF("Done\n")); | | 844 | DBG(2, ErrorF("Done\n")); |
818 | return Success; | | 845 | return Success; |
819 | | | 846 | |
820 | /* | | 847 | /* |
821 | * Deactivate the device. After this, the device will not emit | | 848 | * Deactivate the device. After this, the device will not emit |
822 | * events until a subsequent DEVICE_ON. Thus, we can momentarily | | 849 | * events until a subsequent DEVICE_ON. Thus, we can momentarily |
823 | * close the port. | | 850 | * close the port. |
824 | */ | | 851 | */ |
825 | case DEVICE_OFF: | | 852 | case DEVICE_OFF: |
826 | DBG(2, ErrorF("Elographics touchscreen off...\n")); | | 853 | DBG(2, ErrorF("Elographics touchscreen off...\n")); |
827 | dev->public.on = FALSE; | | 854 | dev->public.on = FALSE; |
828 | if (pInfo->fd >= 0) { | | 855 | if (pInfo->fd >= 0) { |
829 | xf86RemoveEnabledDevice(pInfo); | | 856 | xf86RemoveEnabledDevice(pInfo); |
830 | } | | 857 | } |
831 | SYSCALL(close(pInfo->fd)); | | 858 | SYSCALL(close(pInfo->fd)); |
832 | pInfo->fd = -1; | | 859 | pInfo->fd = -1; |
833 | DBG(2, ErrorF("Done\n")); | | 860 | DBG(2, ErrorF("Done\n")); |
834 | return Success; | | 861 | return Success; |
835 | | | 862 | |
836 | /* | | 863 | /* |
837 | * Final close before server exit. This is used during server shutdown. | | 864 | * Final close before server exit. This is used during server shutdown. |
838 | * Close the port and free all the resources. | | 865 | * Close the port and free all the resources. |
839 | */ | | 866 | */ |
840 | case DEVICE_CLOSE: | | 867 | case DEVICE_CLOSE: |
841 | DBG(2, ErrorF("Elographics touchscreen close...\n")); | | 868 | DBG(2, ErrorF("Elographics touchscreen close...\n")); |
842 | dev->public.on = FALSE; | | 869 | dev->public.on = FALSE; |
843 | if (pInfo->fd >= 0) { | | 870 | if (pInfo->fd >= 0) { |
844 | xf86RemoveEnabledDevice(pInfo); | | 871 | xf86RemoveEnabledDevice(pInfo); |
845 | } | | 872 | } |
846 | SYSCALL(close(pInfo->fd)); | | 873 | SYSCALL(close(pInfo->fd)); |
847 | pInfo->fd = -1; | | 874 | pInfo->fd = -1; |
848 | DBG(2, ErrorF("Done\n")); | | 875 | DBG(2, ErrorF("Done\n")); |
849 | return Success; | | 876 | return Success; |
850 | | | 877 | |
| | | 878 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) * 100 + GET_ABI_MINOR(ABI_XINPUT_VERSION) >= 1901 |
| | | 879 | case DEVICE_ABORT: |
| | | 880 | return Success; |
| | | 881 | #endif |
| | | 882 | |
851 | default: | | 883 | default: |
852 | ErrorF("unsupported mode=%d\n", mode); | | 884 | ErrorF("unsupported mode=%d\n", mode); |
853 | return BadValue; | | 885 | return BadValue; |
854 | } | | 886 | } |
855 | } | | 887 | } |
856 | | | 888 | |
857 | /* | | 889 | /* |
858 | *************************************************************************** | | 890 | *************************************************************************** |
859 | * | | 891 | * |
860 | * xf86EloAllocate -- | | 892 | * xf86EloAllocate -- |
861 | * | | 893 | * |
862 | *************************************************************************** | | 894 | *************************************************************************** |
863 | */ | | 895 | */ |
864 | static int | | 896 | static int |
865 | xf86EloAllocate(InputDriverPtr drv, InputInfoPtr pInfo) | | 897 | xf86EloAllocate(InputDriverPtr drv, InputInfoPtr pInfo) |
866 | { | | 898 | { |
867 | EloPrivatePtr priv; | | 899 | EloPrivatePtr priv; |
868 | | | 900 | |
869 | priv = malloc(sizeof(EloPrivateRec)); | | 901 | priv = malloc(sizeof(EloPrivateRec)); |
870 | if (!priv) | | 902 | if (!priv) |
871 | return BadAlloc; | | 903 | return BadAlloc; |
872 | | | 904 | |
873 | priv->input_dev = strdup(ELO_PORT); | | 905 | priv->input_dev = strdup(ELO_PORT); |
874 | priv->min_x = 0; | | 906 | priv->min_x = 0; |
875 | priv->max_x = 3000; | | 907 | priv->max_x = 3000; |
876 | priv->min_y = 0; | | 908 | priv->min_y = 0; |
877 | priv->max_y = 3000; | | 909 | priv->max_y = 3000; |
878 | priv->untouch_delay = ELO_UNTOUCH_DELAY; | | 910 | priv->untouch_delay = ELO_UNTOUCH_DELAY; |
879 | priv->report_delay = ELO_REPORT_DELAY; | | 911 | priv->report_delay = ELO_REPORT_DELAY; |
880 | priv->screen_no = 0; | | 912 | priv->screen_no = 0; |
881 | priv->screen_width = -1; | | 913 | priv->screen_width = -1; |
882 | priv->screen_height = -1; | | 914 | priv->screen_height = -1; |
883 | priv->inited = 0; | | 915 | priv->inited = 0; |
884 | priv->is_a_2310 = 0; | | 916 | priv->is_a_2310 = 0; |
885 | priv->checksum = ELO_INIT_CHECKSUM; | | 917 | priv->checksum = ELO_INIT_CHECKSUM; |
886 | priv->packet_buf_p = 0; | | 918 | priv->packet_buf_p = 0; |
887 | priv->swap_axes = 0; | | 919 | priv->swap_axes = 0; |
888 | | | 920 | |
889 | pInfo->device_control = xf86EloControl; | | 921 | pInfo->device_control = xf86EloControl; |
890 | pInfo->read_input = xf86EloReadInput; | | 922 | pInfo->read_input = xf86EloReadInput; |
891 | pInfo->control_proc = NULL; | | 923 | pInfo->control_proc = NULL; |
892 | pInfo->switch_mode = NULL; | | 924 | pInfo->switch_mode = NULL; |
893 | pInfo->private = priv; | | 925 | pInfo->private = priv; |
894 | pInfo->type_name = XI_TOUCHSCREEN; | | 926 | pInfo->type_name = XI_TOUCHSCREEN; |
895 | | | 927 | |
896 | return Success; | | 928 | return Success; |
897 | } | | 929 | } |
898 | | | 930 | |
899 | | | 931 | |
900 | static void | | 932 | static void |
901 | xf86EloUninit(InputDriverPtr drv, | | 933 | xf86EloUninit(InputDriverPtr drv, |
902 | InputInfoPtr pInfo, | | 934 | InputInfoPtr pInfo, |
903 | int flags) | | 935 | int flags) |
904 | { | | 936 | { |
905 | EloPrivatePtr priv = (EloPrivatePtr) pInfo->private; | | 937 | EloPrivatePtr priv = (EloPrivatePtr) pInfo->private; |
906 | | | 938 | |
907 | free(priv->input_dev); | | 939 | free(priv->input_dev); |
908 | free(priv); | | 940 | free(priv); |
909 | pInfo->private = NULL; | | 941 | pInfo->private = NULL; |
910 | xf86DeleteInput(pInfo, 0); | | 942 | xf86DeleteInput(pInfo, 0); |
911 | } | | 943 | } |
912 | | | 944 | |
913 | static | | 945 | static |
914 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 18 | | 946 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 18 |
915 | const | | 947 | const |
916 | #endif | | 948 | #endif |
917 | char *default_options[] = { | | 949 | char *default_options[] = { |
918 | "BaudRate", "9600", | | 950 | "BaudRate", "9600", |
919 | "StopBits", "1", | | 951 | "StopBits", "1", |
920 | "DataBits", "8", | | 952 | "DataBits", "8", |
921 | "Parity", "None", | | 953 | "Parity", "None", |
922 | "FlowControl", "None", | | 954 | "FlowControl", "None", |
923 | NULL | | 955 | NULL |
924 | }; | | 956 | }; |
925 | | | 957 | |
926 | static int | | 958 | static int |
927 | xf86EloInit(InputDriverPtr drv, | | 959 | xf86EloInit(InputDriverPtr drv, |
928 | InputInfoPtr pInfo, | | 960 | InputInfoPtr pInfo, |
929 | int flags) | | 961 | int flags) |
930 | { | | 962 | { |
931 | EloPrivatePtr priv=NULL; | | 963 | EloPrivatePtr priv=NULL; |
932 | const char *str; | | 964 | const char *str; |
933 | int portrait = 0; | | 965 | int portrait = 0; |
934 | int height, width; | | 966 | int height, width; |
935 | char *opt_model; | | 967 | char *opt_model; |
936 | Model* model; | | 968 | Model* model; |
937 | int rc; | | 969 | int rc; |
938 | | | 970 | |
939 | | | 971 | |
940 | rc = xf86EloAllocate(drv, pInfo); | | 972 | rc = xf86EloAllocate(drv, pInfo); |
941 | if (rc != Success) | | 973 | if (rc != Success) |
942 | return rc; | | 974 | return rc; |
943 | | | 975 | |
944 | priv = pInfo->private; | | 976 | priv = pInfo->private; |
945 | | | 977 | |
946 | str = xf86SetStrOption(pInfo->options, "Device", NULL); | | 978 | str = xf86SetStrOption(pInfo->options, "Device", NULL); |
947 | if (!str) { | | 979 | if (!str) { |
948 | xf86Msg(X_ERROR, "%s: No Device specified in Elographics module config.\n", | | 980 | xf86Msg(X_ERROR, "%s: No Device specified in Elographics module config.\n", |
949 | pInfo->name); | | 981 | pInfo->name); |
950 | return BadValue; | | 982 | return BadValue; |
951 | } else { | | 983 | } else { |
952 | pInfo->fd = xf86OpenSerial(pInfo->options); | | 984 | pInfo->fd = xf86OpenSerial(pInfo->options); |
953 | if (pInfo->fd < 0) { | | 985 | if (pInfo->fd < 0) { |
954 | xf86Msg(X_ERROR, "%s: Unable to open Elographics touchscreen device %s", pInfo->name, str); | | 986 | xf86Msg(X_ERROR, "%s: Unable to open Elographics touchscreen device %s", pInfo->name, str); |
955 | return BadValue; | | 987 | return BadValue; |
956 | } | | 988 | } |
957 | xf86CloseSerial(pInfo->fd); | | 989 | xf86CloseSerial(pInfo->fd); |
958 | pInfo->fd = -1; | | 990 | pInfo->fd = -1; |
959 | } | | 991 | } |
960 | | | 992 | |
961 | priv->input_dev = strdup(str); | | 993 | priv->input_dev = strdup(str); |
962 | | | 994 | |
963 | opt_model = xf86SetStrOption(pInfo->options, "Model", NULL); | | 995 | opt_model = xf86SetStrOption(pInfo->options, "Model", NULL); |
964 | model = SupportedModels; | | 996 | model = SupportedModels; |
965 | priv->model = MODEL_UNKNOWN; | | 997 | priv->model = MODEL_UNKNOWN; |
966 | while(model->type != MODEL_UNKNOWN && opt_model) | | 998 | while(model->type != MODEL_UNKNOWN && opt_model) |
967 | { | | 999 | { |
968 | if (!strcmp(model->name, opt_model)) | | 1000 | if (!strcmp(model->name, opt_model)) |
969 | { | | 1001 | { |
970 | priv->model = model->type; | | 1002 | priv->model = model->type; |
971 | break; | | 1003 | break; |
972 | } | | 1004 | } |
973 | model++; | | 1005 | model++; |
974 | } | | 1006 | } |
975 | | | 1007 | |
976 | priv->screen_no = xf86SetIntOption(pInfo->options, "ScreenNo", 0); | | 1008 | priv->screen_no = xf86SetIntOption(pInfo->options, "ScreenNo", 0); |
977 | xf86Msg(X_CONFIG, "Elographics associated screen: %d\n", priv->screen_no); | | 1009 | xf86Msg(X_CONFIG, "Elographics associated screen: %d\n", priv->screen_no); |
978 | priv->untouch_delay = xf86SetIntOption(pInfo->options, "UntouchDelay", ELO_UNTOUCH_DELAY); | | 1010 | priv->untouch_delay = xf86SetIntOption(pInfo->options, "UntouchDelay", ELO_UNTOUCH_DELAY); |
979 | xf86Msg(X_CONFIG, "Elographics untouch delay: %d ms\n", priv->untouch_delay*10); | | 1011 | xf86Msg(X_CONFIG, "Elographics untouch delay: %d ms\n", priv->untouch_delay*10); |
980 | priv->report_delay = xf86SetIntOption(pInfo->options, "ReportDelay", ELO_REPORT_DELAY); | | 1012 | priv->report_delay = xf86SetIntOption(pInfo->options, "ReportDelay", ELO_REPORT_DELAY); |
981 | xf86Msg(X_CONFIG, "Elographics report delay: %d ms\n", priv->report_delay*10); | | 1013 | xf86Msg(X_CONFIG, "Elographics report delay: %d ms\n", priv->report_delay*10); |
982 | priv->max_x = xf86SetIntOption(pInfo->options, "MaxX", 3000); | | 1014 | priv->max_x = xf86SetIntOption(pInfo->options, "MaxX", 3000); |
983 | xf86Msg(X_CONFIG, "Elographics maximum x position: %d\n", priv->max_x); | | 1015 | xf86Msg(X_CONFIG, "Elographics maximum x position: %d\n", priv->max_x); |
984 | priv->min_x = xf86SetIntOption(pInfo->options, "MinX", 0); | | 1016 | priv->min_x = xf86SetIntOption(pInfo->options, "MinX", 0); |
985 | xf86Msg(X_CONFIG, "Elographics minimum x position: %d\n", priv->min_x); | | 1017 | xf86Msg(X_CONFIG, "Elographics minimum x position: %d\n", priv->min_x); |
986 | priv->max_y = xf86SetIntOption(pInfo->options, "MaxY", 3000); | | 1018 | priv->max_y = xf86SetIntOption(pInfo->options, "MaxY", 3000); |
987 | xf86Msg(X_CONFIG, "Elographics maximum y position: %d\n", priv->max_y); | | 1019 | xf86Msg(X_CONFIG, "Elographics maximum y position: %d\n", priv->max_y); |
988 | priv->min_y = xf86SetIntOption(pInfo->options, "MinY", 0); | | 1020 | priv->min_y = xf86SetIntOption(pInfo->options, "MinY", 0); |
989 | xf86Msg(X_CONFIG, "Elographics minimum y position: %d\n", priv->min_y); | | 1021 | xf86Msg(X_CONFIG, "Elographics minimum y position: %d\n", priv->min_y); |
990 | priv->swap_axes = xf86SetBoolOption(pInfo->options, "SwapXY", 0); | | 1022 | priv->swap_axes = xf86SetBoolOption(pInfo->options, "SwapXY", 0); |
991 | if (priv->swap_axes) { | | 1023 | if (priv->swap_axes) { |
992 | xf86Msg(X_CONFIG, "Elographics device will work with X and Y axes swapped\n"); | | 1024 | xf86Msg(X_CONFIG, "Elographics device will work with X and Y axes swapped\n"); |
993 | } | | 1025 | } |
994 | debug_level = xf86SetIntOption(pInfo->options, "DebugLevel", 0); | | 1026 | debug_level = xf86SetIntOption(pInfo->options, "DebugLevel", 0); |
995 | if (debug_level) { | | 1027 | if (debug_level) { |
996 | #if DEBUG | | 1028 | #if DEBUG |
997 | xf86Msg(X_CONFIG, "Elographics debug level sets to %d\n", debug_level); | | 1029 | xf86Msg(X_CONFIG, "Elographics debug level sets to %d\n", debug_level); |
998 | #else | | 1030 | #else |
999 | xf86Msg(X_INFO, "Elographics debug not available\n"); | | 1031 | xf86Msg(X_INFO, "Elographics debug not available\n"); |
1000 | #endif | | 1032 | #endif |
1001 | } | | 1033 | } |
1002 | str = xf86SetStrOption(pInfo->options, "PortraitMode", "Landscape"); | | 1034 | str = xf86SetStrOption(pInfo->options, "PortraitMode", "Landscape"); |
1003 | if (strcmp(str, "Portrait") == 0) { | | 1035 | if (strcmp(str, "Portrait") == 0) { |
1004 | portrait = 1; | | 1036 | portrait = 1; |
1005 | } | | 1037 | } |
1006 | else if (strcmp(str, "PortraitCCW") == 0) { | | 1038 | else if (strcmp(str, "PortraitCCW") == 0) { |
1007 | portrait = -1; | | 1039 | portrait = -1; |
1008 | } | | 1040 | } |
1009 | else if (strcmp(str, "Landscape") != 0) { | | 1041 | else if (strcmp(str, "Landscape") != 0) { |
1010 | xf86Msg(X_ERROR, "Elographics portrait mode should be: Portrait, Landscape or PortraitCCW"); | | 1042 | xf86Msg(X_ERROR, "Elographics portrait mode should be: Portrait, Landscape or PortraitCCW"); |
1011 | str = "Landscape"; | | 1043 | str = "Landscape"; |
1012 | } | | 1044 | } |
1013 | xf86Msg(X_CONFIG, "Elographics device will work in %s mode\n", str); | | 1045 | xf86Msg(X_CONFIG, "Elographics device will work in %s mode\n", str); |
1014 | | | 1046 | |
1015 | width = priv->max_x - priv->min_x; | | 1047 | width = priv->max_x - priv->min_x; |
1016 | height = priv->max_y - priv->min_y; | | 1048 | height = priv->max_y - priv->min_y; |
1017 | if (width == 0) { | | 1049 | if (width == 0) { |
1018 | xf86Msg(X_ERROR, "Elographics: Cannot configure touchscreen with width 0\n"); | | 1050 | xf86Msg(X_ERROR, "Elographics: Cannot configure touchscreen with width 0\n"); |
1019 | return BadValue; | | 1051 | return BadValue; |
1020 | } | | 1052 | } |
1021 | else if (width < 0) { | | 1053 | else if (width < 0) { |
1022 | xf86Msg(X_INFO, "Elographics: reverse x mode (minimum x position >= maximum x position)\n"); | | 1054 | xf86Msg(X_INFO, "Elographics: reverse x mode (minimum x position >= maximum x position)\n"); |
1023 | } | | 1055 | } |
1024 | if (height == 0) { | | 1056 | if (height == 0) { |
1025 | xf86Msg(X_ERROR, "Elographics: Cannot configure touchscreen with height 0\n"); | | 1057 | xf86Msg(X_ERROR, "Elographics: Cannot configure touchscreen with height 0\n"); |
1026 | return BadValue; | | 1058 | return BadValue; |
1027 | } | | 1059 | } |
1028 | else if (height < 0) { | | 1060 | else if (height < 0) { |
1029 | xf86Msg(X_INFO, "Elographics: reverse y mode (minimum y position >= maximum y position)\n"); | | 1061 | xf86Msg(X_INFO, "Elographics: reverse y mode (minimum y position >= maximum y position)\n"); |
1030 | } | | 1062 | } |
1031 | | | 1063 | |
1032 | if (portrait == 1) { | | 1064 | if (portrait == 1) { |
1033 | /* | | 1065 | /* |
1034 | * Portrait Clockwise: reverse Y axis and exchange X and Y. | | 1066 | * Portrait Clockwise: reverse Y axis and exchange X and Y. |
1035 | */ | | 1067 | */ |
1036 | int tmp; | | 1068 | int tmp; |
1037 | tmp = priv->min_y; | | 1069 | tmp = priv->min_y; |
1038 | priv->min_y = priv->max_y; | | 1070 | priv->min_y = priv->max_y; |
1039 | priv->max_y = tmp; | | 1071 | priv->max_y = tmp; |
1040 | priv->swap_axes = (priv->swap_axes==0) ? 1 : 0; | | 1072 | priv->swap_axes = (priv->swap_axes==0) ? 1 : 0; |
1041 | } | | 1073 | } |
1042 | else if (portrait == -1) { | | 1074 | else if (portrait == -1) { |
1043 | /* | | 1075 | /* |
1044 | * Portrait Counter Clockwise: reverse X axis and exchange X and Y. | | 1076 | * Portrait Counter Clockwise: reverse X axis and exchange X and Y. |
1045 | */ | | 1077 | */ |
1046 | int tmp; | | 1078 | int tmp; |
1047 | tmp = priv->min_x; | | 1079 | tmp = priv->min_x; |
1048 | priv->min_x = priv->max_x; | | 1080 | priv->min_x = priv->max_x; |
1049 | priv->max_x = tmp; | | 1081 | priv->max_x = tmp; |
1050 | priv->swap_axes = (priv->swap_axes==0) ? 1 : 0; | | 1082 | priv->swap_axes = (priv->swap_axes==0) ? 1 : 0; |
1051 | } | | 1083 | } |
1052 | | | 1084 | |
1053 | return Success; | | 1085 | return Success; |
1054 | } | | 1086 | } |
1055 | | | 1087 | |
1056 | _X_EXPORT InputDriverRec ELOGRAPHICS = { | | 1088 | _X_EXPORT InputDriverRec ELOGRAPHICS = { |
1057 | 1, /* driver version */ | | 1089 | 1, /* driver version */ |
1058 | "elographics", /* driver name */ | | 1090 | "elographics", /* driver name */ |
1059 | NULL, /* identify */ | | 1091 | NULL, /* identify */ |
1060 | xf86EloInit, /* pre-init */ | | 1092 | xf86EloInit, /* pre-init */ |
1061 | xf86EloUninit, /* un-init */ | | 1093 | xf86EloUninit, /* un-init */ |
1062 | NULL, /* module */ | | 1094 | NULL, /* module */ |
1063 | default_options | | 1095 | default_options |
1064 | }; | | 1096 | }; |
1065 | | | 1097 | |
1066 | static pointer | | 1098 | static pointer |
1067 | Plug(pointer module, | | 1099 | Plug(pointer module, |
1068 | pointer options, | | 1100 | pointer options, |
1069 | int *errmaj, | | 1101 | int *errmaj, |
1070 | int *errmin) | | 1102 | int *errmin) |
1071 | { | | 1103 | { |
1072 | xf86AddInputDriver(&ELOGRAPHICS, module, 0); | | 1104 | xf86AddInputDriver(&ELOGRAPHICS, module, 0); |
1073 | | | 1105 | |
1074 | return module; | | 1106 | return module; |
1075 | } | | 1107 | } |
1076 | | | 1108 | |
1077 | static void | | 1109 | static void |
1078 | Unplug(pointer p) | | 1110 | Unplug(pointer p) |
1079 | { | | 1111 | { |
1080 | DBG(1, ErrorF("EloUnplug\n")); | | 1112 | DBG(1, ErrorF("EloUnplug\n")); |
1081 | } | | 1113 | } |
1082 | | | 1114 | |
1083 | static XF86ModuleVersionInfo version_rec = { | | 1115 | static XF86ModuleVersionInfo version_rec = { |
1084 | "elographics", | | 1116 | "elographics", |
1085 | MODULEVENDORSTRING, | | 1117 | MODULEVENDORSTRING, |
1086 | MODINFOSTRING1, | | 1118 | MODINFOSTRING1, |
1087 | MODINFOSTRING2, | | 1119 | MODINFOSTRING2, |
1088 | XORG_VERSION_CURRENT, | | 1120 | XORG_VERSION_CURRENT, |
1089 | PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, | | 1121 | PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, |
1090 | ABI_CLASS_XINPUT, | | 1122 | ABI_CLASS_XINPUT, |
1091 | ABI_XINPUT_VERSION, | | 1123 | ABI_XINPUT_VERSION, |
1092 | MOD_CLASS_XINPUT, | | 1124 | MOD_CLASS_XINPUT, |
1093 | { 0, 0, 0, 0 } | | 1125 | { 0, 0, 0, 0 } |
1094 | }; | | 1126 | }; |
1095 | | | 1127 | |
1096 | /* | | 1128 | /* |
1097 | * This is the entry point in the module. The name | | 1129 | * This is the entry point in the module. The name |
1098 | * is setup after the pattern <module_name>ModuleData. | | 1130 | * is setup after the pattern <module_name>ModuleData. |
1099 | * Do not change it. | | 1131 | * Do not change it. |
1100 | */ | | 1132 | */ |
1101 | _X_EXPORT XF86ModuleData elographicsModuleData = { &version_rec, Plug, Unplug }; | | 1133 | _X_EXPORT XF86ModuleData elographicsModuleData = { &version_rec, Plug, Unplug }; |
1102 | | | 1134 | |