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