/* Include files for X 11 */ #include #include #include #include #include #include #include #include #include #include "digitizer.h" /* ---------------------------------------------------------------------- */ #define DIGI_MSG_LEN 13 /* Laenge der Digitizer Message */ #define MAX_MSG 5 /* Anzahl der MSG die ueberlesen werden */ #define DIGI_INIT_STRING "@cG\"" /* Stream-Mode / Grid-Mode */ #define TRUE (0==0) #define FALSE (1==0) /* #define DEBUG Um Debugging einzuschalten */ /* ---------------------------------------------------------------------- */ /* Modulglobale Variable */ static int device; static int win_x, win_y, win_w, win_h; static int display_height; static int win_pos_unknown = TRUE; /* ---------------------------------------------------------------------- */ /* Position und Groesse des LaTeXDraw-Fensters speichern */ void save_win_pos(x, y, w, h) int x, y, w, h; { if (win_pos_unknown) { /* Erster Aufruf ==> alles merken */ win_x = x; win_y = y; win_w = w; win_h = h; win_pos_unknown = FALSE; #ifdef DEBUG fprintf(stderr, "Alles neu : (%d|%d|%d|%d)\n", win_x, win_y, win_w, win_h); #endif } else { if ((win_w == w) && (win_h == h)) { /* Position des Fensters hat sich veraendert */ win_x = x; win_y = y; #ifdef DEBUG fprintf(stderr, "Neue Position : (%d|%d)\n", win_x, win_y); #endif } else { /* Groesse des Fensters hat sich veraendert */ win_w = w; win_h = h; #ifdef DEBUG fprintf(stderr, "Neue Groesse : (%d|%d)\n", win_w, win_h); #endif } } } /* ---------------------------------------------------------------------- */ /* Verbindung zum Digitizer herstellen und Digitizer initialisieren */ int init_digitizer(display) Display *display; { char config[32]; int i; struct termio termbuf; XWindowAttributes attribs; device = open("/dev/tty01", O_RDWR); if (-1 == device) { printf("\r\nDevice konnte nicht geoeffnet werden"); return(-1); } if (-1 == ioctl(device,TCGETA,&termbuf)) { printf("\r\nFehler beim lesen der KONFIG, Fehler %d",errno); return(-1); } termbuf.c_iflag &= ~(INLCR | ICRNL | IUCLC | ISTRIP | BRKINT); termbuf.c_oflag &= ~OPOST; termbuf.c_lflag &= ~(ICANON | ISIG | ECHO); termbuf.c_cc[VMIN] = 0; termbuf.c_cc[VTIME] = 0; termbuf.c_cflag &= ~CBAUD; termbuf.c_cflag |= B9600; termbuf.c_cflag &= ~CSIZE; termbuf.c_cflag |= CS8; termbuf.c_cflag &= ~CSTOPB; termbuf.c_cflag &= ~PARENB; if (-1 == ioctl(device,TCSETA,&termbuf)) { printf("\r\nFehler device %d",errno); return(-1); } /* presence stream mode */ strcpy(config, DIGI_INIT_STRING); for (i=0; i> 8; config[3] = attribs.height & 0xff; config[4] = (attribs.height & 0xff00) >> 8; write(device, config, 5); display_height = attribs.height; return(1); } /* ---------------------------------------------------------------------- */ /* Aus der seriellen Schnittstelle ankommende Zeichen lesen Insgesamt werden MAX_MSG Nachrichten eingelesen, von denen die letzte in *x,*y,*button zurueckgegeben wird */ static int readit(x,y,button) int *x, *y, *button; { /* Zwischenspeicher fuer eingegangene Meldungen */ static char zwsp[(MAX_MSG+1)*DIGI_MSG_LEN]; static int count = 0; /* Kommandos fuer Digitizer Mode */ char cmd1[] = "G!"; /* Wert nur nach Bewegung */ char cmd2[] = "G "; /* Immer Werte senden */ char buffer[MAX_MSG*DIGI_MSG_LEN]; int i,n; int erg; /* Im Zweifelsfall kein Ergebniss vorhanden */ erg = 0; /* Maximal eine Nachricht einlesen */ n = read(device, buffer, 4*DIGI_MSG_LEN); /* Gelesene Zeichen in den Puffer kopieren */ if (0 != n) { for (i=0; i= DIGI_MSG_LEN) { /* Ist der String korrekt aufgebaut */ if (zwsp[12] == 10) { /* Korrekter String */ *x = *y = *button = 0; for (i=0;i<4;i++) { *x = *x * 10 + (zwsp[i] - '0'); *y = *y * 10 + (zwsp[5+i] - '0'); } *button = zwsp[10] - '0'; count -= DIGI_MSG_LEN; for (i=0; i (%d|%d)\n", x_in,y_in, *x_out, *y_out); #endif } /* ---------------------------------------------------------------------- */ /* Koordianten eines Digitizer-Events in LTD-Koordinaten umrechnen */ void translate_x_to_ltd(x_in, y_in, x_out, y_out) int x_in, y_in; double *x_out, *y_out; { *x_out = (double)x_in; /* *y_out = (double)(y_in - win_h); */ *y_out = (double)(win_h - y_in); #ifdef DEBUG fprintf(stderr, "x->digi (%d|%d) ==> (%f|%f)\n", x_in,y_in, *x_out, *y_out); #endif } /* ---------------------------------------------------------------------- */ /* Digitizer-Nachrichten erzeugen */ int process_digitizer(display, window) Display *display; Window window; { static int old_x = -1; static int old_y = -1; static int old_b = -1; int x,y, this_x, this_y, this_b; int stateField[] = {0, Button2Mask, Button1Mask, Button4Mask, Button3Mask}; int buttonField[] = {0, 2, 1, 4, 3}; long motionEventField[] = {0, Button2MotionMask, Button1MotionMask, Button4MotionMask, Button3MotionMask}; XEvent myEvent; int event_b; long event_mask; /* Wert vom Digitizer holen */ if (0 == readit(&x, &y, &this_b)) return(FALSE); /* Koordinaten fuer LaTeXDraw umsetzen */ translate_digi_to_ltd(x,y, &this_x, &this_y); if ((this_x != old_x) || (this_y != old_y)) { /* Bewegung des Cursors ausfuehren */ XWarpPointer(display, None, window, /*DefaultRootWindow(display),*/ 0, 0, 0, 0, this_x, this_y); old_x = this_x; old_y = this_y; if ((this_b != 0) && (this_b <= 4)) { myEvent.type = MotionNotify; myEvent.xany.display = display; myEvent.xmotion.window = window; myEvent.xmotion.x = this_x; myEvent.xmotion.y = this_y; myEvent.xmotion.state = stateField[this_b]; event_mask = motionEventField[this_b]; XSendEvent(display, PointerWindow, 0, event_mask, &myEvent); } } /* Button - Event */ if ((this_b != abs(old_b)) && (this_b <= 4)) { /* Button press oder release */ if (old_b < 0) { event_b = -old_b; old_b = 0; myEvent.type = ButtonRelease; event_mask = ButtonReleaseMask; } else { event_b = this_b; old_b = -this_b; myEvent.type = ButtonPress; event_mask = ButtonPressMask; } myEvent.xany.display = display; myEvent.xbutton.window = window; myEvent.xbutton.x = this_x; myEvent.xbutton.y = this_y; myEvent.xbutton.state = stateField[event_b]; myEvent.xbutton.button = buttonField[event_b]; XSendEvent(display, PointerWindow, 0, event_mask, &myEvent); } /* XEvent rausschreiben */ XSync(display, 0); return(TRUE); }