From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/latexdraw/digitizer/digitizer.c | 360 ++++++++++++++++++++++++++++++++ support/latexdraw/digitizer/digitizer.h | 29 +++ 2 files changed, 389 insertions(+) create mode 100644 support/latexdraw/digitizer/digitizer.c create mode 100644 support/latexdraw/digitizer/digitizer.h (limited to 'support/latexdraw/digitizer') diff --git a/support/latexdraw/digitizer/digitizer.c b/support/latexdraw/digitizer/digitizer.c new file mode 100644 index 0000000000..8fbb886a94 --- /dev/null +++ b/support/latexdraw/digitizer/digitizer.c @@ -0,0 +1,360 @@ +/* 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); +} + diff --git a/support/latexdraw/digitizer/digitizer.h b/support/latexdraw/digitizer/digitizer.h new file mode 100644 index 0000000000..f075a2d6bf --- /dev/null +++ b/support/latexdraw/digitizer/digitizer.h @@ -0,0 +1,29 @@ + +/* ---------------------------------------------------------------------- */ + +/* + Position und Groesse des LaTeXDraw-Fensters speichern +*/ +void save_win_pos(int x, int y, int w, int h); + +/* ---------------------------------------------------------------------- */ + +/* + Verbindung zum Digitizer herstellen und Digitizer initialisieren +*/ +int init_digitizer(Display *display); + +/* ---------------------------------------------------------------------- */ + +/* + Koordianten eines Digitizer-Events in LTD-Koordinaten umrechnen +*/ +void translate_x_to_ltd(int x_in, int y_in, double *x_out, double *y_out); + + +/* ---------------------------------------------------------------------- */ + +/* + Digitizer-Nachrichten erzeugen +*/ +int process_digitizer(Display *display, Window window); -- cgit v1.2.3