summaryrefslogtreecommitdiff
path: root/support/latexdraw/digitizer
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/latexdraw/digitizer
Initial commit
Diffstat (limited to 'support/latexdraw/digitizer')
-rw-r--r--support/latexdraw/digitizer/digitizer.c360
-rw-r--r--support/latexdraw/digitizer/digitizer.h29
2 files changed, 389 insertions, 0 deletions
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 <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <termio.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#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<strlen(config); i++)
+ write(device, &config[i], 1);
+
+ /* Groesse des Displays holen und Digitizer skalieren */
+ XGetWindowAttributes(display, DefaultRootWindow(display), &attribs);
+ config[0] = 'r';
+ config[1] = attribs.width & 0xff;
+ config[2] = (attribs.width & 0xff00) >> 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<n; i++)
+ zwsp[count++] = buffer[i];
+ }
+
+ /* Eine komplette Nachricht da ? */
+ while (count >= 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<count ; i++)
+ zwsp[i] = zwsp[DIGI_MSG_LEN+i];
+
+ if (*button != 0)
+ write(device, cmd2, strlen(cmd2));
+ else
+ write(device, cmd1, strlen(cmd1));
+
+ erg = 1;
+ }
+ else
+ {
+ /* Nachricht war Muell also neuen Beginn suchen */
+ buffer[0] = 0;
+ while (10 != buffer[0])
+ read(device, buffer, 1);
+ /* Puffer als geloescht markieren */
+ count = 0;
+ }
+ /* fprintf(stderr,"(%d|%d | %d)\n", *x, *y, *button); */
+ }
+
+
+ return (erg);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ Digitizer Koordinaten so umwandeln, dass aus ihnen LaTeXDraw-Koordinaten
+ werden
+*/
+static void translate_digi_to_ltd(x_in, y_in, x_out, y_out)
+int x_in,
+ y_in;
+int *x_out,
+ *y_out;
+{
+ *x_out = x_in;
+ *y_out = win_h - y_in;
+#ifdef DEBUG
+ fprintf(stderr, "(%d|%d) ==> (%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);