summaryrefslogtreecommitdiff
path: root/support/latexdraw/latexdraw.c
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/latexdraw.c
Initial commit
Diffstat (limited to 'support/latexdraw/latexdraw.c')
-rw-r--r--support/latexdraw/latexdraw.c10677
1 files changed, 10677 insertions, 0 deletions
diff --git a/support/latexdraw/latexdraw.c b/support/latexdraw/latexdraw.c
new file mode 100644
index 0000000000..66451f0aba
--- /dev/null
+++ b/support/latexdraw/latexdraw.c
@@ -0,0 +1,10677 @@
+
+/* Das Programm erlaubt das Erstellen von Zeichnungen */
+/* fuer LaTeX. Notwendig ist hierzu latexdraw.sty mit */
+/* den darin aufgerufenen sty-Dateien */
+/* interner Koordinatenursprung fuer Zeichnung und Menue */
+/* links unten am Schirm. */
+/* Weiteres in der Beschreibung latexdraw.tex */
+/* Stand 09.05.1999, copyright: H.-J. Siegert, TUM */
+/* nichtkommerzielle Nutzung F&L Hochschulen erlaubt */
+/* gegen Stand v. 19.03.1999 undelete ->UnDelete */
+/* gegen Stand v. 23.08.1998 STDIN ueber thread */
+/* gegen Stand v. 22.08.1998 Dateiname im Window-Namen */
+/* gegen Stand v. 12.04.1998 eigene cmap, wenn noetig */
+/* gegen Stand v. 28.10.1997 cast bei wi in rotate */
+/* gegen Stand v. 02.08.1997 erweitert fuer read von stdin */
+/* gegen Stand v. 17.06.1997 dgrenz Faktor 0.3 statt 0.5 */
+/* gegen Stand v. 19.03.1997 groessere Differenz beim */
+/* Ausrichten vertikale, horizontale Linien */
+/* gegen Stand v. 03.02.1997 kein snap bei fill */
+/* neue Abstandsberechnungen */
+/* gegen Stand v. 11.01.1997 bei Kuerzung wg Pfeilen wird */
+/* nicht mehr TeX-Definition der Winkel verwendet */
+/* gegen Stand v. 24.12.1996 alle Elemente gezeichnet bei */
+/* blinken, Abstandsmodifikation unterschiedlich bei */
+/* Selektion gefuellter und nichtgefuellter Elemente */
+/* gegen Stand v. 20.10.1996 Fehler bei Ausgabe Rechteck */
+/* gegen Stand v. 17.09.1996 Fehler in Pfeilen bei Boegen */
+/* gegen Stand v. 16.09.1996 Abfrage der Attribute m"oglich */
+/* gegen Stand v. 17.08.1996 Fehler in LaTeX-Datei bei */
+/* Pieslice (Klammer zu viel) */
+/* gegen Stand v. 27.07.1996 ^k bei Zeicheneingabe */
+/* gegen Stand v. 22.07.1996 ifdef XK_KP_... */
+/* autom. Erzeugung LaTeX-Datei ohne Oeffnung Fenster */
+/* (Parameter -io beim Aufruf) */
+/* gegen Stand v. 16.05.1996 Ausgabe Linien gepunktet, */
+/* strichpunktiert neue Form; LdpArc, LdpEllarc und */
+/* LdpBezier mit verkuerzten Boegen wegen Pfeilen! */
+/* gegen Stand v. 25.12.1995 auch Cursortasten v. Keypad */
+/* gegen Stand v. 19.06.1995 Menuefont ist Option */
+/* gegen Stand v. 12.06.1995 bessere Pfeilspitzen */
+/* gegen Stand v. 02.06.1995 usleep wg. Linux umbenannt */
+/* gegen Stand v. 13.05.1995 Fehler in Darstellung Bezier */
+/* gegen Stand v. 27.04.1995 weitere Farben, Bezier gefuellt*/
+/* Entkopplung Farbnummer und Anordnung Farbe im Menue */
+/* autom. Anordnung Farben im Menue */
+/* gegen Stand v. 26.04.1995 Fehler bei Texteingabe */
+/* gegen Stand v. 15.04.1995 Korrektur Auswahlrechteck cut, */
+/* statt ires,fres static, Fehler in trim und connect */
+/* bei Verschieben dazwischen */
+/* gegen Stand v. 07.04.1995 Korrektur chatt bei Text */
+/* gegen Stand v. 05.04.1995 Digitalisiertablett */
+/* gegen Stand v. 02.04.1995 auch Anklickpunkt bei connect */
+/* gegen Stand v. 22.03.1995 rot, CapProjecting */
+/* gegen Stand v. 19.03.1995 Lesen Versionen < 4.0 */
+/* gegen Stand v. 02.03.1995 Laenge Text unabhaengig von */
+/* der Fensterbreite */
+/* gegen Stand v. 26.02.1995 Fehler bei Abbruch Text */
+/* korrigiert, Textposition in chatt aufgenommen */
+/* gegen Stand v. 31.01.1995 laengerer Eingabestring */
+/* gegen Stand v. 29.01.1995 Fehler in selekt. chatt behoben*/
+/* gegen Stand v. 04.01.1995 Selektives chatt,Aufruf-Param. */
+/* gegen Stand v. 31.12.1994 Grauwerte bei Monochromschirm */
+/* gegen Stand v. 30.09.1994 Andere Berechnung Bezier */
+/* gegen Stand v. 21.09.1994 Anordnung Menue */
+/* gegen Stand v. 17.09.1994 trim fuer Recht-,Drei-,Viereck */
+/* gegen Stand v. 12.09.1994 Auswahlrechteck bei newgroup */
+/* gegen Stand v. 20.08.1994 andere Blinkzeiten */
+/* gegen Stand v. 17.08.1994 connect mit allen Elementen */
+/* gegen Stand v. 28.07.1994 Realisierung von Gruppen */
+/* gegen Stand v. 24.07.1994 undo bei loeschen d. backspace */
+/* blinken ausgewaehlter Elemente bei mcopy mmove */
+/* gegen Stand v. 02.07.1994 Ausrichten Punkte in x oder y */
+/* gegen Stand v. 18.06.1994 XSetInputFocus und ^a,^e */
+/* gegen Stand v. 06.06.1994 fuellen vorhandener Elemente */
+/* gegen Stand v. 02.05.1994 neben up auch down */
+/* gegen Stand v. 15.04.1994 Gerade mit Pfeilen st"arker */
+/* eingekuerzt */
+/* gegen Stand v. 08.04.1994 gespeicherte Ausgabeoptionen */
+/* und neue Makros aLdPfeil,eLdPfeil und LdpLine */
+/* gegen Stand v. 22.3.1994 uralte Versionsnummern mit CV */
+/* werden richtig erkannt */
+/* gegen Stand v. 18.03.94 Darstellung Text, der editiert */
+/* wird, an alter Position vermeiden */
+/* gegen Stand v. 11.03.94 Rundung korrigiert */
+/* gegen Stand v. 28.01.94 Gitterwerte werden ausgegeben */
+/* gegen Stand v. 22.01.94 parallele Linie kippt nicht */
+/* gegen Stand v. 20.01.94 Cursortasten bewegen Bild, */
+/* gegen Stand v. 27.11.93 Erweiterung extend auf Boegen, */
+/* redraw, */
+/* gegen Stand v. 01.11.93 Verbesserung minmax-Berechnung */
+/* gegen Stand v. 23.9.93 Definition documentstyle moeglich */
+/* gegen Stand v. 23.08.1993 Farben neu definiert */
+/* gegen Stand v. 10.8.93 bezier Linientyp variabel */
+/* gegen Stand v. 3.7.93 gefuellte Segmente */
+/* gegen Stand v. 18.5.92 Aenderung bei pbezabstand */
+/* gegen Stand v. 20.12.1992 vorwaerts/rueckwaerts Taste 3, */
+/* xend, yend fuer umgebendes Rechteck andersartig bestimmt */
+/* farbige Zeichnungelemente */
+/* email: siegert@informatik.tu-muenchen.dbp.de */
+
+
+#include <Xlib.h>
+#include <Xutil.h>
+#include <Xos.h>
+#include <X.h>
+#include <keysym.h>
+#include <keysymdef.h>
+#include <Xresource.h>
+#include <cursorfont.h>
+
+#include <stdio.h>
+#include <bitmaps/icon>
+#include <ctype.h>
+#include <math.h>
+#include <setjmp.h>
+#include <assert.h>
+#include <string.h>
+/*#include <strings.h>*/
+/*# include <sys/types.h>*/
+
+#ifdef THREAD
+#include <pthread.h>
+#endif
+
+#ifdef TABLETT
+#include "digitizer.h"
+#endif
+
+#define Char char /* Characters (not bytes) */
+#define Static static /* Private global funcs and vars */
+#define Void void
+#define siintround(a) (long) (a) /* Rundung bei double nach long */
+
+#define boolean long
+#define cboolean char
+#define true 1L
+#define false 0L
+#define unbekannt -1
+#ifdef TABLETT
+#define window_name "LaTeXdraw (Siegert, TUM, C15.29)Digi"
+#endif
+#ifndef TABLETT
+#define window_name "LaTeXdraw (Siegert, TUM, C15.29)"
+#endif
+#define icon_name "latexdraw"
+#define intfiletext "LaTeXdraw output file:"
+#define extfiletext "LaTeX output file:"
+#define zel 5000 /*Anzahl Zeichnungselemente*/
+#define zstr 300 /*Anzahl Stringelemente*/
+#define maxldicke 20 /*Liniendicke 1..20 vorhanden */
+
+#define xzmax00 552.0 /*Window-Zeichenbereichbreite x*/
+#define yzmax00 760.0 ; /*Window-Hoehe, Zeichenbereichhoehe y*/
+#define xfont "8x13bold" /* Windowfont Menue, Prompt*/
+#define ersatzfont "8x13" /* Ersatz, falls Textfont fehlt*/
+#define ztextfonts 19 /* Zahl Fonts fuer Text in Zeichnung */
+ /* Fonts in inittextfonts definiert */
+#define dminein 3.0 /*minimale Laengen bei der Eingabe*/
+
+#define pi 3.141592653
+#define einrueck " " /*einruecken in TEX*/
+#define kom ","
+#define blank " "
+
+#define verlline 30.0
+#define texfaktorv 0.3 /*1 pixel = texfaktor mm, Voreinstellung!*/
+
+#define maxpunkte 1000
+#define maxstrl 123 /* maximale Stringlaenge */
+#define maxgruppen 500 /* maximale Anzahl Gruppen */
+
+#define zrequw 5 /* Zahl der gleichzeitigen Requestwindows */
+#define prxachse " end point x axis?"
+#define pryachse " end point y axis?"
+#define pranfwi " beginning of arc?"
+#define prendwi " end of arc?"
+#define prendwisektor " end of arc for next sector?"
+#define prpoint3 " point 3?"
+#define prpoint4 " point 4?"
+#define docstylestd "\\documentstyle[latexdraw]{article}"
+#define docstyle2e "\\documentclass{article}\\input{latexdraw.sty}"
+
+#define wg 3600.0
+#define wh 1800.0
+#define wv 900.0
+#define wdv 2700.0
+#define initabstand 300000.0
+#define maxabstand 10.0
+/* Umrechnung Linienstaerke in pts */
+#define lw2pt 0.57
+
+
+/* Definitionen fuer Suchen von ausgewaehlten Elementen */
+/* Wird auch in array suchtypok[][] verwendet */
+#define alleelem 0
+#define nurtrimel 1
+#define nurboundel 2
+#define nurgerade 3
+#define nurmpel 4
+#define nurextendel 5
+#define nurfillel 6
+
+
+#define schwarz 0L
+#define weiss 1L
+#define maxzahlfarben 100L
+#define paint 1L
+#define erase 0L
+#define maxlenmenfarbe 9L
+#define maxlenfarbe 20L
+#define somenspalten 3L
+
+#define tastatur_erwartet 1
+#define click_erwartet 2
+#define phase2 10
+
+#ifndef XK_KP_Left
+#define XK_KP_Left XK_Left
+#define XK_KP_Right XK_Right
+#define XK_KP_Up XK_Up
+#define XK_KP_Down XK_Down
+#endif
+
+#define tastecursleft1 XK_Left
+#define tastecursright1 XK_Right
+#define tastecursup1 XK_Up
+#define tastecursdown1 XK_Down
+
+#define tastecursleft2 XK_KP_Left
+#define tastecursright2 XK_KP_Right
+#define tastecursup2 XK_KP_Up
+#define tastecursdown2 XK_KP_Down
+
+#define tastea XK_a
+#define tasted XK_d
+#define tastee XK_e
+#define tastek XK_k
+#define tasteplus1 XK_plus
+#define tasteplus2 XK_KP_Add
+#define tasteminus1 XK_minus
+#define tasteminus2 XK_KP_Subtract
+#define tastedelete XK_Delete
+#define tastebackspace XK_BackSpace
+#define tastereturn XK_Return
+#define tastecontroll XK_Control_L
+#define tastecontrolr XK_Control_R
+#define tasteundo XK_Undo
+#define button1 1
+#define button2 2
+#define button3 3
+#define ttext 2 /*elementtypen*/
+#define tgerade 3
+#define tkreis 5
+#define tkreisgef 6
+#define tkreisbogen 7
+#define tell 8
+#define tellgef 9
+#define tellbogen 10
+#define trechteckgef 11
+#define tbezier 12
+#define tdreieckgef 13
+#define tviereckgef 14
+#define tkreissektorgef 15
+#define tellsektorgef 16
+#define tbeziergef 17
+
+#define mende 1 /*menue_nummern*/
+#define mtext 2
+#define mgerade 3
+#define mkreis 4
+#define mell 5
+#define mrechteck 6
+#define mbezier 7
+#define mpolygon 8
+#define mspiegeln 9
+#define mkopieren 10
+#define mbewegen 11
+#define mergaenzen 12
+#define mausdehnen 13
+#define mbrechen 14
+#define mloeschen 15
+#define meinrasten 16
+#define mgefuellt 17
+#define mverbunden 17
+#define mbogen 18
+#define mparallel 19
+#define mlot 20
+#define mmittelpunkt 21
+#define mpfeilanf 22
+#define mpfeilende 23
+#define mdick 24
+#define mgestrichelt 25
+#define mgepunktet 26
+#define mlschieben 27
+#define moschieben 28
+#define muschieben 29
+#define mrschieben 30
+#define mgitter 31
+#define mcenter 32
+#define mgross 33
+#define mklein 34
+#define mxytastatur 35
+#define msave 36
+#define mkopbewmaus 37
+#define mredraw 38
+#define mltext 39
+#define mrtext 40
+#define mbtext 41
+#define mttext 42
+#define mladen 43
+#define mfont 44
+#define mcut 45
+#define mpaste 46
+#define mdreieck 47
+#define mcolor 48
+#define mviereck 49
+#define mup 50
+#define mchangelineattr 51
+#define mdegrees 52
+#define mdown 53
+#define mfill 54
+#define mgroupmode 55
+#define mnewgroup 56
+#define mungroup 57
+#define mshowgroup 58
+#define mgroupok 59
+#define mconnect 60
+#define mconnxy 61
+#define mconnyx 62
+#define mrot 63
+#define mwinkelrot 64
+#define mcapprojecting 65
+#define mconnpoint 66
+#define mqueryattr 67
+#define mread 68
+#define mreadzeit 69
+#define zmenue 69
+
+
+typedef Char tmenue[zmenue+1][maxstrl+1];
+typedef double telr[zel+1];
+typedef long teli[zel+1];
+typedef cboolean telb[zel+1];
+typedef Char tstr[zstr+1][maxstrl+1];
+typedef double tpunkte[6];
+
+typedef struct tbezierkoeff {
+ double ax, bx, cx, dx, dreiax, zweibx, ay, by, cy, dy, dreiay, zweiby;
+} tbezierkoeff;
+
+typedef double terg[5];
+
+
+Static long zelmax;
+Static double xanf,yanf,xend,yend,xsnap,ysnap,xprompt,yprompt;
+Static double xlast,ylast;
+Static int irootx, irooty, iwinx, iwiny, ixzmax,iyzmax;
+unsigned int keysbuttons;
+Static double xzmax0,yzmax0,xzmax,yzmax,xgr,xgrf,
+ kaestchenbreite,kaestchenhoehe;
+
+Static double curs_x,curs_y;
+Static double fgradbo, fbograd, texfaktor,version;
+Static boolean zeichnen;
+Static double texdashl, texdotg, texinterd, gridw, gridw0, gridx0, gridy0,
+ gridwx1, gridwy1, gridwx2, gridwy2, xmittelzei, ymittelzei;
+Static long ltype, lwidth, lends;
+Static Char dateiname[maxstrl+1],texdateiname[maxstrl+1];
+Static FILE *datdeskr;
+Static double xmarker[5], ymarker[5];
+Static boolean bmarker[5];
+Static Char pr1[maxstrl+1], pr2[maxstrl+1], pr3[maxstrl+1],
+ pr4[maxstrl+1], pr5[maxstrl+1], pr6[maxstrl+1];
+Static Char tpr1res[maxstrl+1], tpr2res[maxstrl+1],
+ tpr3res[maxstrl+1], tpr4res[maxstrl+1];
+Static Char EinText[maxstrl+1];
+Static Char nullstr[maxstrl+1];
+Static Char docstyle[maxstrl+1];
+
+Static tmenue menue, pr2menue, pr3menue;
+Static double xam[zmenue + 1], yam[zmenue + 1], xem[zmenue + 1],
+ yem[zmenue + 1];
+Static boolean selmenue[zmenue + 1];
+Static long radiogroup[zmenue + 1];
+Static double rpxarray[maxpunkte], rpyarray[maxpunkte];
+Static long vater[maxgruppen+1], umbenennung[maxgruppen+1];
+long grumax; /*Maximalzahl aktueller Gruppen*/
+Static cboolean gruppentag[maxgruppen+1];
+Static boolean aenderunggruppen;
+Static teli typ, sequenz, group;
+Static telb blink, blinkalt;
+Static telr x1, y1_, x2, y2, xb1, yb1, xb2, yb2, wanf, wend;
+Static telr elxmin, elxmax, elymin, elymax;
+Static teli lineende, linedicke, linetype;
+Static telr laenge1, laenge2, rotwi, crw, srw;
+Static teli textno;
+Static tstr texte;
+Static long blinkend, blinkfarbe; /* blinkfarbe == paint oder erase */
+Static long blinkintervallzaehler;
+struct timeval st_delay;
+Static long winkelrotate;
+Static boolean changelende, changelstyle, changelwidth, changecolor;
+Static boolean changefont, changeposition;
+Static Char textausrichtung[9][maxstrl+1];
+Static double wzeichenhoehe,wzeichenascent,wzeichendescent, wzeichenbreite;
+Static double textzeichenhoehe[ztextfonts],textzeichenascent[ztextfonts],
+ textzeichenbreite[ztextfonts];
+Static Char textfont[ztextfonts][maxstrl+1],
+ textfontmakro[ztextfonts][maxstrl+1],
+ textfontlabel[ztextfonts][maxstrl+1],
+ menuefont[maxstrl+1];
+Static long fontnummer, stdfontnummer,
+ folgefont[ztextfonts], prevfont[ztextfonts];
+Static long aktldicke;
+Static double breite, hoehe, nbreite, nhoehe;
+Static boolean quer0format,querformat,mitvorspann,nmitvorspann,oldunitlength;
+Static long phase=0;/* fuer mehrere verbundene Aktionen */
+Static long phasexyein;
+Static long erwartet, winerwartet, koordinateneingegeben;
+Static long texterase;
+Static long controlan;
+Static long tposres, export_kmark, export_relsel, import_zelsel;
+Static long geoeffnet, dragbox;
+Static XEvent report;
+Static Char eingabezeile[maxstrl+1];
+Static long aktreadzeit, readphase = 0;
+Static double readdxx,readdyy,readf;
+#ifdef THREAD
+Static pthread_t threadID;
+#ifdef LINUX
+#define pthread_attr_default NULL
+#endif
+#endif
+
+Static long threadausel=0, threadaktiv, threadrunning = 0;
+Static Time requesttime, lasteventtime;
+Static boolean wartendexport, requestbelegt[zrequw], requestaktiv[zrequw];
+Static boolean tablett; /*true falls Digitizer angeschlossen */
+Static boolean nur_texausgabe;
+Static XSelectionEvent selnotify[zrequw];
+Static Atom latexdraw_object, latexdraw_text, latexdraw_selection;
+Static long requestkakt[zrequw];
+Static Colormap cmap;
+Static XColor rgbistdef[maxzahlfarben];
+Static char farbname[maxzahlfarben][maxlenfarbe+1];
+Static char menfarbname[maxzahlfarben][maxlenmenfarbe+1];
+Static long farbposfarbnr[maxzahlfarben],farbnrfarbpos[maxzahlfarben];
+Static long aktzahlfarben;
+Static long aktcolor,letztesgrau,aktposcolor;
+Static Pixmap graystipple[9];
+Static char graybits[10][2] ={{0x04,0x00},{0x04,0x10},{0x12,0x48},{0x52,0x58},
+ {0x5a,0x52},
+ {0xad,0xa7},{0xed,0xb7},{0xfb,0xe7},{0xfb,0xef},
+ {0xff, 0xff}};
+
+/*fuer Grauwerte der Farben */
+#define hcolorbits 16 /* Hoehe colorstipple in Pixels */
+#define bcolorbits 16 /* Breite colorstipple in Pixels */
+Static char colorbits[hcolorbits*bcolorbits/8+1];
+Static Pixmap colorstipple[maxzahlfarben]; /*fuer Grauwerte der Farben */
+Static boolean nocolors;
+
+Static double intensity[maxzahlfarben]; /* Helligkeit */
+Static GC gcinverse, gcxor,gcstd, somengctext[ztextfonts],
+ gctext[ztextfonts], gczeichnung;
+Static Visual *visual;
+Static char winname[maxstrl+1];
+Static border_width=4;
+Static XSizeHints size_hints;
+Static XFontStruct *font_info, *text_font_info[ztextfonts];
+Static char *display_name = NULL;
+Static Display *display;
+Static Cursor busycursor,textcursor,clickcursor;
+Static long screen;
+Static Window win, rootwin, childwin;
+Static XComposeStatus compose;
+Static KeySym keysym;
+Static Pixmap pixmap;
+Static long button1gedrueckt, button2gedrueckt, button3gedrueckt;
+
+Static char symstr[maxstrl+1];
+
+/* Feld, das angibt, ob ein Zeichnungselemettyp (1. Parameter) bei */
+/* einem bestimmten Suchvorgang (z.B. nurtrimel, 2. Parameter) */
+/* beruecksichtigt werden soll. ja = 'y', nein = 'n' */
+/* alleelem,nurtrimel,nurboundel,nurgerade,nurmpel,nurextendel,nurfillel */
+
+Static char suchtypok[18][7]={
+ {'n', 'n', 'n', 'n', 'n', 'n', 'n'}, /*frei*/
+ {'n', 'n', 'n', 'n', 'n', 'n', 'n'}, /*frei*/
+ {'y', 'n', 'n', 'n', 'n', 'n', 'n'}, /*ttext*/
+ {'y', 'y', 'y', 'y', 'y', 'y', 'y'}, /*tgerade*/
+ {'n', 'n', 'n', 'n', 'n', 'n', 'n'}, /*frei*/
+ {'y', 'y', 'y', 'n', 'y', 'n', 'y'}, /*tkreis*/
+ {'y', 'y', 'y', 'n', 'y', 'n', 'n'}, /*tkreisgef*/
+ {'y', 'y', 'y', 'n', 'y', 'y', 'y'}, /*tkreisbogen*/
+ {'y', 'y', 'y', 'n', 'y', 'n', 'y'}, /*tell*/
+ {'y', 'y', 'y', 'n', 'y', 'n', 'n'}, /*tellgef*/
+ {'y', 'y', 'y', 'n', 'y', 'y', 'y'}, /*tellbogen*/
+ {'y', 'n', 'y', 'n', 'y', 'n', 'n'}, /*trechteckgef*/
+ {'y', 'n', 'n', 'n', 'n', 'n', 'y'}, /*tbezier*/
+ {'y', 'n', 'y', 'n', 'y', 'n', 'n'}, /*tdreieckgef*/
+ {'y', 'n', 'y', 'n', 'n', 'n', 'n'}, /*tviereckgef*/
+ {'y', 'y', 'y', 'n', 'y', 'y', 'n'}, /*tkreissektorgef*/
+ {'y', 'y', 'y', 'n', 'y', 'y', 'n'}, /*tellsektorgef*/
+ {'y', 'n', 'n', 'n', 'n', 'n', 'n'}, /*tbeziergef*/
+};
+
+
+
+Static void test(i)
+{
+printf("******test#: %ld\n",i);
+}
+
+Static Void konkat(s, s1, s2)
+Char *s1, *s2, *s;
+/* Konkatenation von strings s1 und s2 */
+{
+ long i,n1,n2;
+
+ n1 = strlen(s1);
+ n2 = strlen(s2);
+ for(i=0;i<=n1;i++)
+ s[i]=s1[i];
+ for(i=0;i<=n2;i++)
+ s[n1+i]=s2[i];
+}
+
+
+Static double frand()
+{ /* einfacher Zufallszahlengenerator aus 0...1*/
+ static long seed=314159267;
+ double xx;
+
+ seed=69069*seed;
+ xx = seed;
+ xx = xx/4294967296.0+0.5;
+ if (xx<0.0) xx = 0.0;
+ if(xx>=1.0) xx = 0.99;
+ return xx;
+}
+
+
+Static Void strfirst(namestring,anz)
+ Char *namestring;
+ long anz;
+/* anz=Anzahl Zeichen, die bleiben */
+{
+ long ls;
+ ls=strlen(namestring);
+ if (ls==0) return;
+ if (anz >=ls) return;
+ if (anz <0) anz=0;
+ namestring[anz]='\0';
+}
+
+Static Void strlast(namestring,anz)
+ Char *namestring;
+ long anz;
+/* anz=Anzahl Zeichen, die wegfallen*/
+{
+ long i,ls;
+ ls=strlen(namestring);
+ if (anz>=ls) {
+ strcpy(namestring,nullstr);
+ return;
+ }
+ if (anz<=0) return;
+ for (i=anz;i<=ls;i++){
+ namestring[i-anz]=namestring[i];
+ }
+}
+
+Static Void strinsert(c,nstring,pos)
+ Char *c, *nstring;
+ long pos;
+/* fuege c als pos-tes Zeichen (Index: pos - 1) in nstring ein*/
+{
+ long i,n,index;
+
+ n=strlen(nstring);
+ index=pos-1;
+ if (index > n) index = n;
+ for (i=n;i>=index;i--)
+ nstring[i+1]=nstring[i];
+ nstring[index] = *c;
+}
+
+Static Void strdelete(nstring,pos)
+ Char *nstring;
+ long pos;
+/*loesche pos-tes Zeichen (Index: pos - 1) in nstring*/
+{
+ long i,n,index;
+
+ n=strlen(nstring);
+ index=pos-1;
+ for (i=index;i<n;i++)
+ nstring[i]=nstring[i+1];
+}
+
+Static Void substringcpy(s,ss,anfpos,zahlzeichen)
+ Char *s, *ss;
+ long anfpos,zahlzeichen;
+ /* substring aus ss mit vorgegebener Anzahl von Zeichen ab der */
+ /* Position anfpos (erste Position ist 0!) nach s uebertragen */
+{
+ long apos, ls, i, n;
+
+ apos = anfpos;
+ if (anfpos < 0)
+ apos = 0;
+ ls = strlen(ss)-apos;
+ if (ls > zahlzeichen)
+ ls = zahlzeichen;
+ for (i=0;i<ls;i++)
+ s[i] = ss[i+apos];
+ s[ls] = '\0';
+}
+
+
+
+Static Void trenneextension(s)
+Char *s;
+/* Extension von Dateinamen trennen */
+{
+ long i,n;
+ n=strlen(s)-1;
+ if (n<0) return;
+ for (i=n;i>0;i--) { /* i>0 wegen Punkt am Anfang */
+ if (s[i] == '/') return;
+ if (s[i] == '.') {
+ s[i]='\0';
+ return;
+ }
+ }
+}
+
+
+Static boolean strvergl(s1,s2)
+ Char *s1,*s2;
+{
+ long ls,i;
+ if ((ls=strlen(s1))!=strlen(s2)) return false;
+ for (i=0;i<ls;i++){ if (s1[i]!=s2[i]) return false;}
+ return true;
+}
+
+Static boolean istnullstr(s1)
+ Char *s1;
+{
+ if (*s1==*nullstr) return true;
+ else return false;
+}
+
+Static void protokoll(s1,s2)
+Char *s1,*s2;
+{
+printf("%s%s\n",s1,s2);
+}
+
+Static long rgb2hsv2ordnung(r,g,b,skalierung)
+long r,g,b,skalierung; /* 0..skalierung*/
+{ /* Berechnung der Reihenfolge der Farben im Menue nach dem */
+ /* hsv-Modell mit vier Gruppierungen */
+
+ long ordnung,max,min,diff;
+ double h,s,v,rdist,gdist,bdist;
+ /* hsv = hue saturation value */
+ max = r;
+ if (g > max) max = g;
+ if (b > max) max = b;
+ min = r;
+ if (g < min) min = g;
+ if (b < min) min = b;
+ diff = max - min;
+ v = 1.0*max/skalierung;
+ if ((max ==0)||(diff==0)) { /*Grauwerte */
+ ordnung = 100.0*(1.0-v);
+ if (v==0.0) ordnung = 0L; /* schwarz */
+ if (v==1.0) ordnung = 1L; /* weiss */
+ return ordnung;
+ }
+ s = 1.0*diff/max;
+ rdist = 1.0*(max-r)/diff;
+ gdist = 1.0*(max-g)/diff;
+ bdist = 1.0*(max-b)/diff;
+ if (b==max) h = 4.0+gdist-rdist;
+ if (g==max) h = 2.0+rdist-bdist;
+ if (r==max) h = bdist-gdist;
+ h = h/6.0;
+ if (h < 0.0) h += 1.0;
+ ordnung = 4; /* light, hell*/
+ if ((s>=0.3)&&(v>0.81)) ordnung = 3; /* pale,hell */
+ if ((s>=0.7)&&(v>0.81)) ordnung = 1; /* gesaettigt, hell */
+ if (v<=0.81) ordnung = 2; /* dunkle Farben */
+ ordnung = 1000.0*(ordnung+h);
+ ordnung = 100.0*(ordnung+(1.0-v));
+ ordnung = 100.0*(ordnung+(1.0-s));
+ return ordnung;
+/* Anmerkung: ordnung steht zunaechst in farbposfarbnr[nr] */
+}
+
+Static Void reihenfolgefarben()
+{/* Anordnung der Farben gemaess Ordungskriterium in farbposfarbnr[nr]*/
+ /* farbposfarbnr und farbnrfarbpos besetzen */
+
+ long i,j,nr,nrtmp,postmp;
+
+ for (nr=0;nr<aktzahlfarben;nr++) farbnrfarbpos[nr]=nr;
+ /* jetzt nach ordnung aus rgb2hsv2ordnung sortieren */
+ for (i=0;i<aktzahlfarben;i++) {
+ for (j=aktzahlfarben-1;j>i;j--) {
+ if (farbposfarbnr[j] < farbposfarbnr[i]) {
+ postmp = farbnrfarbpos[i];
+ nrtmp = farbposfarbnr[i];
+ farbnrfarbpos[i] = farbnrfarbpos[j];
+ farbnrfarbpos[j] = postmp;
+ farbposfarbnr[i] = farbposfarbnr[j];
+ farbposfarbnr[j] = nrtmp;
+ }
+ }
+ }
+ for (nr=0;nr<aktzahlfarben;nr++)
+ farbposfarbnr[farbnrfarbpos[nr]] = nr;
+}
+
+Static long schreibenausdatei();
+Static Void berechneminmax();
+
+Static Void fehler(i)
+long i;
+{ Char name[maxstrl+1]; long taste, phase, msel;
+ taste=1; phase=0; msel = mende;
+ strcpy(name, "?");
+ switch (i) {
+ case 1:
+ strcpy(name, "too many objects");
+ break;
+ case 2:
+ strcpy(name, "too many text objects");
+ break;
+ case 3:
+ strcpy(name, "too many objects in input file");
+ break;
+ case 4:
+ strcpy(name, "too many points for bezier object");
+ break;
+ case 5:
+ strcpy(name, "negative sqrt");
+ break;
+ case 6:
+ strcpy(name, "can't connect to X-Server");
+ konkat(name,name, XDisplayName(display_name));
+ break;
+ case 7:
+ strcpy(name,"can't load window font");
+ break;
+ case 8:
+ strcpy(name,"can't load text font");
+ break;
+ case 9:
+ strcpy(name,"mismatch in number of text fonts");
+ break;
+ case 10:
+ strcpy(name,"sort, last element not free");
+ break;
+ case 11:
+ strcpy(name,"definition groups in input file not ok, type == 0");
+ break;
+ case 12:
+ strcpy(name,"definition groups in input file not ok, element# wrong");
+ break;
+ case 13:
+ strcpy(name,"definition groups in input file not ok, group# wrong");
+ break;
+ case 14:
+ strcpy(name,"definition groups in input file not ok, node# wrong");
+ break;
+ case 15:
+ strcpy(name,"definition groups in input file not ok, fathernode# wrong");
+ break;
+ case 16:
+ strcpy(name,"definition groups in input file not ok");
+ break;
+ case 17:
+ strcpy(name,"not enough groups available");
+ break;
+ case 18:
+ strcpy(name,"couldn't connect to digitizer");
+ }/*case*/
+ protokoll("******error******: ", name);
+ phase=schreibenausdatei(&msel,"error.epc",taste, phase);
+ exit(-1);
+}
+
+
+Static int myerrorhandler(display,error)
+Display *display;
+XErrorEvent *error;
+{
+ char msg[100];
+ XGetErrorText(display, error->error_code,msg,100);
+ protokoll("warning XError: ",msg);
+ return 0;
+}
+
+Static Void readzeitsymbol()
+{
+ Char sss[10];
+ sprintf(sss,"d:%lds",aktreadzeit);
+ strcpy(menue[mreadzeit],sss);
+}
+
+
+Static Void strichsymbol()
+{
+ Char sss[10];
+ sprintf(sss,"=%2ld",aktldicke);
+ strcpy(menue[mdick],sss);
+}
+
+Static Void colorsymbol()
+{
+ Char sss[maxlenmenfarbe+5];
+ sprintf(sss,"%2ld:%s",aktcolor,menfarbname[aktcolor]);
+ strcpy(menue[mcolor],sss);
+}
+
+Static long tastegedrueckt()
+ {
+ unsigned long mask;
+ mask=KeyPressMask|KeyReleaseMask;
+ if(XCheckWindowEvent(display,win,mask,&report)==true) return 1;
+ else return 0;
+ }
+
+
+Static Void welt_to_bildschirm(xx, yy, xpix, ypix)
+double xx, yy;
+long *xpix, *ypix;
+/* Umrechnung Punkt (xx,yy) in Bildschirmkoordinaten */
+{
+
+ *xpix = siintround(xx);
+ *ypix = siintround(yzmax - yy);
+}
+
+Static Void getweltkoord(xx, yy)
+double *xx, *yy;
+
+/* Punkt in event report in weltkoord umrechnen */
+{
+ long ix,iy;
+
+#ifdef TABLETT
+ if ( (tablett) && (report.xany.send_event))
+ translate_x_to_ltd(report.xbutton.x, report.xbutton.y, xx, yy);
+ else
+#endif
+ {
+ ix=report.xbutton.x;
+ *xx = ix;
+ iy=iyzmax - report.xbutton.y;
+ *yy= iy;
+ }
+}
+
+Static Void getmotionweltkoord(ix, iy, xx, yy)
+long ix, iy;
+double *xx, *yy;
+
+/* Punkt ix, iy in weltkoord umrechnen */
+{
+ *xx = ix;
+ *yy= (iyzmax - iy);
+}
+
+Static long si_iabs(x)
+long x;
+/* Absolutwert ganze Zahl */
+{ if (x < 0)
+ return (-x);
+ else return x;
+}
+
+Static Void rechteckbildschirmkoord(x1,y1,x2,y2,ix,iy,width,height)
+ double x1,y1,x2,y2;
+ long *ix,*iy,*width,*height;
+/* Bestimmen Bildschirm-Koordinaten Rechteck */
+{ long ix2,iy2;
+ welt_to_bildschirm(x1,y1,ix,iy);
+ welt_to_bildschirm(x2,y2,&ix2,&iy2);
+ *width= si_iabs(ix2-*ix);
+ *height= si_iabs(iy2-*iy);
+ if (*ix > ix2) *ix=ix2;
+ if (*iy > iy2) *iy=iy2;
+}
+
+Static Void setcolor(display,gc,zcolor)
+ Display *display;
+ GC gc;
+ long zcolor;
+{
+ XSetBackground(display,gc,rgbistdef[weiss].pixel);
+ if ((zcolor==weiss) || (zcolor==schwarz)) {
+ XSetFillStyle(display,gc,FillSolid);
+ XSetForeground(display,gc,rgbistdef[zcolor].pixel);
+ return;
+ }
+ if ((zcolor >= aktzahlfarben)||(zcolor <0)) {
+ XSetFillStyle(display,gc,FillSolid);
+ XSetForeground(display,gc,rgbistdef[schwarz].pixel);
+ return;
+ }
+ if (zcolor <= letztesgrau) {/* graustufen */
+ XSetFillStyle(display,gc,FillOpaqueStippled);
+ XSetStipple(display,gc,graystipple[zcolor-2]);
+ XSetForeground(display,gc,rgbistdef[schwarz].pixel);
+ return;
+ }
+ if (nocolors == false) {
+ XSetFillStyle(display,gc,FillSolid);
+ XSetForeground(display,gc,rgbistdef[zcolor].pixel);
+ }
+ else {
+ XSetFillStyle(display,gc,FillOpaqueStippled);
+ XSetStipple(display,gc,colorstipple[zcolor]);
+ XSetForeground(display,gc,rgbistdef[zcolor].pixel);
+ }
+}
+
+Static Void rechteckinverse(x1,y1,x2,y2)
+ double x1,y1,x2,y2;
+{
+ long ix,iy,width,height;
+ rechteckbildschirmkoord(x1,y1,x2,y2,&ix,&iy,&width,&height);
+ XFillRectangle(display,win,gcinverse,ix,iy,width,height);
+}
+
+
+Static Void xorrechteck(x1,y1,x2,y2)
+ double x1,y1,x2,y2;
+{
+ long ix,iy,width,height;
+ rechteckbildschirmkoord(x1,y1,x2,y2,&ix,&iy,&width,&height);
+ if ((width<5) && (height<5)) return;
+ if (width<5) width=1;
+ if (height<5) height=1;
+ if (x1 < xgr) return;
+ if (x2 < xgr) return;
+ XDrawRectangle(display,win,gcinverse,ix,iy,width,height);
+}
+
+Static Void menuerechteck(x1,y1,x2,y2)
+ double x1,y1,x2,y2;
+{
+ long ix,iy,width,height;
+ rechteckbildschirmkoord(x1,y1,x2,y2,&ix,&iy,&width,&height);
+ setcolor(display,gcstd,schwarz);
+ XDrawRectangle(display,win,gcstd,ix,iy,width,height);
+}
+
+
+Static Void setvalues(display,gc,zcolor,line_type,lwidth,lende)
+ Display *display;
+ GC gc;
+ long zcolor,line_type,lwidth,lende;
+
+{long line_style,cap_style,lw;
+ double grunddash, grunddot;
+ long dashlist_length;
+ char dashlist[10];
+
+
+ lw = 0.7*lwidth;
+ grunddash = 1.6*lw;
+ if (grunddash <= 3.0)
+ grunddash = 4.0;
+ grunddot = lw;
+ if (grunddot <= 3.0)
+ grunddot = 2.0;
+ else
+ grunddot = 1.0;
+ if (lende == 4)
+ cap_style = CapProjecting;
+ else
+ cap_style = CapButt;
+ if (line_type < 2) line_style=LineSolid;
+ else {
+ if (lw > 3)
+ cap_style = CapRound;
+ else
+ cap_style = CapButt;
+ line_style=LineOnOffDash;
+ dashlist_length = 2;
+ switch (line_type) {
+ case 3: /* gepunktet */
+ dashlist_length = 2;
+ dashlist[0]=grunddot;
+ dashlist[1]=grunddash;
+ break;
+ case 5: /* gestrichelt */
+ dashlist_length = 2;
+ dashlist[0]=2.0*grunddash;
+ dashlist[1]=grunddash;
+ break;
+ case 6: /* Textlinie */
+ dashlist_length = 6;
+ dashlist[0]=4;
+ dashlist[1]=3;
+ dashlist[2]=2;
+ dashlist[3]=2;
+ dashlist[4]=2;
+ dashlist[5]=3;
+ break;
+ case 7: /* strichpunktiert */
+ dashlist_length = 4;
+ dashlist[0]=2.0*grunddash;
+ dashlist[1]=grunddash;
+ dashlist[2]=grunddot;
+ dashlist[3]=grunddash;
+ break;
+ default: /*nicht definierte Faelle */
+ dashlist_length = 6;
+ dashlist[0]=2;
+ dashlist[1]=2;
+ dashlist[2]=2;
+ dashlist[3]=2;
+ dashlist[4]=2;
+ dashlist[5]=5;
+ }
+ XSetDashes(display,gc,0,dashlist,dashlist_length);
+ }
+ XSetLineAttributes(display,gc,lw,line_style,cap_style,JoinBevel);
+ setcolor(display,gc,zcolor);
+}
+
+Static Void ausfillpolygon(anzp,zcolor)
+ long anzp,zcolor;
+{
+ long ix,iy,k;
+ double xx,yy;
+ XPoint points[maxpunkte];
+ for (k=0;k<anzp;k++) {
+ xx=rpxarray[k];
+ yy=rpyarray[k];
+ welt_to_bildschirm(xx,yy,&ix,&iy);
+ points[k].x = ix;
+ points[k].y = iy;
+ }
+ setvalues(display,gczeichnung,zcolor,0L,0L,0L);
+ XFillPolygon(display,win,gczeichnung,points,anzp,
+ Complex,CoordModeOrigin);
+}
+
+Static Void setze_clip_bereiche(display)
+ Display *display;
+
+{long zcolor,line_type,ix,iy,width,height,lwidth,i;
+ XRectangle rectangles[1];
+
+ /* Clip-Bereich fuer Zeichnung*/
+ rechteckbildschirmkoord(xgr,yzmax,xzmax,yprompt+wzeichenhoehe,
+ &ix,&iy,&width,&height);
+ rectangles[0].x=ix;
+ rectangles[0].y=iy;
+ rectangles[0].width=width;
+ rectangles[0].height=height;
+ XSetClipRectangles(display,gczeichnung,0,0,rectangles,1,Unsorted);
+ for (i=0; i<ztextfonts; i++)
+ {
+ XSetClipRectangles(display, gctext[i],0,0,rectangles,1,Unsorted);
+ }
+}
+
+
+Static Void setzefont(i,sqnr,fm,fl,fn)
+ long i, *sqnr;
+ char *fn, *fm, *fl;
+{
+ strcpy(textfont[i],fn);
+ strcpy(textfontmakro[i],fm);
+ strcpy(textfontlabel[i],fl);
+ prevfont[i]=*sqnr;
+ folgefont[*sqnr]=i;
+ *sqnr=i;
+ folgefont[i]=stdfontnummer;
+ prevfont[1]=i;
+}
+
+Static Void inittextfonts()
+{
+ long sqnr;
+ /* Definition der Fonts fuer Schriften in der Zeichnung */
+ /* vierte Pos fuer Menue, Texte gleich lang! */
+ /* Param 1: Fontnummer */
+ /* Param 2: Makroname, der vor Text kommt */
+ /* Param 3: Anzeige im Menue */
+ /* Param 4: Fontname */
+ /* Reihenfolge Aufschreibung = Reihenfolge Anzeige */
+
+ if (ztextfonts != 19) fehler(9);
+
+ sqnr = 0;
+ stdfontnummer= 1;
+ setzefont(1, &sqnr, nullstr, " ", "-*-times-medium-r-*-*-17-*");
+ /* Standardfont und immer immer erster Font */
+ setzefont(0, &sqnr, "\\FVIpt " , "6pt ", "-*-times-medium-r-*-*-8-*");
+ setzefont(2, &sqnr, "\\FVIIIpt ", "8pt ", "-*-times-medium-r-*-*-10-*");
+ setzefont(3, &sqnr, "\\FXpt " , "10pt ", "-*-times-medium-r-*-*-14-*");
+ setzefont(4, &sqnr, "\\FXIIpt " , "12pt ", "-*-times-medium-r-*-*-17-*");
+ setzefont(5, &sqnr, "\\FXIVpt ", "14pt ", "-*-times-medium-r-*-*-20-*");
+ setzefont(6, &sqnr, "\\FXVIIIpt ","18pt ", "-*-times-medium-r-*-*-24-*");
+
+ setzefont(7, &sqnr, "\\FVIbpt " ,"6bpt ", "-*-times-bold-r-*-*-8-*");
+ setzefont(8, &sqnr, "\\FVIIIbpt ","8bpt ", "-*-times-bold-r-*-*-10-*");
+ setzefont(9, &sqnr, "\\FXbpt " ,"10bpt", "-*-times-bold-r-*-*-14-*");
+ setzefont(10, &sqnr, "\\FXIIbpt ","12bpt", "-*-times-bold-r-*-*-17-*");
+ setzefont(11, &sqnr, "\\FXIVbpt ","14bpt", "-*-times-bold-r-*-*-20-*");
+ setzefont(12, &sqnr, "\\FXVIIIbpt ","18bpt", "-*-times-bold-r-*-*-24-*");
+
+ setzefont(13, &sqnr, "\\FVIipt " , "6ipt ", "-*-times-medium-i-*-*-8-*");
+ setzefont(14, &sqnr, "\\FVIIIipt ", "8ipt ", "-*-times-medium-i-*-*-10-*");
+ setzefont(15, &sqnr, "\\FXipt " , "10ipt", "-*-times-medium-i-*-*-14-*");
+ setzefont(16, &sqnr, "\\FXIIipt " , "12ipt", "-*-times-medium-i-*-*-17-*");
+ setzefont(17, &sqnr, "\\FXIVipt ", "14ipt", "-*-times-medium-i-*-*-20-*");
+ setzefont(18, &sqnr, "\\FXVIIIipt ", "18ipt","-*-times-medium-i-*-*-24-*");
+
+}
+
+
+Static Void initgctext(display,win,valuemask,values)
+ Display *display;
+ Window win;
+ unsigned long valuemask;
+ XGCValues *values;
+{ long i,hilf;
+ char fontname[maxstrl+1];
+
+ inittextfonts();
+ for (i=0; i<ztextfonts; i++) {
+ strcpy(fontname,textfont[i]);
+ if ((text_font_info[i] = XLoadQueryFont(display,fontname)) == NULL)
+ {protokoll("can't load font: ", fontname);
+ strcpy(fontname,ersatzfont);
+ if ((text_font_info[i] = XLoadQueryFont(display,fontname)) == NULL)
+ fehler(8);}
+ values->font=text_font_info[i]->fid;
+ hilf=text_font_info[i]->ascent;
+ textzeichenascent[i]=hilf;
+ hilf=text_font_info[i]->descent;
+ textzeichenhoehe[i]=hilf + textzeichenascent[i];
+ hilf=XTextWidth(text_font_info[i],"x",1);
+ textzeichenbreite[i]=hilf;
+ values->line_width=0;
+ values->line_style=LineSolid;
+ somengctext[i] = XCreateGC(display,win,valuemask,values);
+ gctext[i] = XCreateGC(display,win,valuemask,values);
+ }
+}
+
+
+Static Void init_window_font(display)
+ Display *display;
+{
+ long hilf,ls,lsmax;
+ char fontname[maxstrl+1];
+
+ strcpy(fontname,menuefont);
+ if ((font_info = XLoadQueryFont(display,fontname)) == NULL)
+ {protokoll("can't load font: ", fontname);
+ fehler(7);}
+ hilf=font_info->ascent;
+ wzeichenascent=hilf;
+ hilf=font_info->descent;
+ wzeichendescent = hilf;
+ wzeichenhoehe=wzeichendescent + wzeichenascent;
+ hilf=XTextWidth(font_info,"x",1);
+ wzeichenbreite=hilf;
+ lsmax=0;
+ for (hilf=1;hilf<=zmenue;hilf++)
+ {
+ ls=strlen(menue[hilf]);
+ if (ls>lsmax) lsmax=ls;
+ }
+ for (hilf=0;hilf<aktzahlfarben;hilf++)
+ {
+ ls=strlen(menfarbname[hilf])+1;
+ if (ls>lsmax) lsmax=ls;
+ }
+ kaestchenbreite = lsmax;
+ kaestchenbreite = (kaestchenbreite+3.0)*wzeichenbreite;
+ kaestchenhoehe=1.2*wzeichenhoehe;
+ xgrf= somenspalten*kaestchenhoehe+1.0*wzeichenbreite;
+ xgr=xgrf+kaestchenbreite +3.0*wzeichenbreite;
+ xzmax=xzmax0+xgr;
+ yzmax=yzmax0;
+ if (quer0format==true){
+ xzmax=yzmax0+xgr;
+ yzmax=xzmax0+1.5*wzeichenhoehe;
+ }
+ xprompt=wzeichenbreite;
+ yprompt=0.5*wzeichenhoehe;
+ ixzmax=(long)floor(xzmax);
+ iyzmax=(long)floor(yzmax);
+}
+
+
+Static Void initGC(screen, display, win)
+ long screen;
+ Display *display;
+ Window win;
+/* Erzeugen aller gc und des Fonts */
+{
+ unsigned long valuemask = 0;
+ XGCValues values;
+ char fontname[maxstrl+1];
+
+ strcpy(fontname,menuefont);
+ valuemask=(GCForeground|GCBackground|GCFunction|GCLineWidth|
+ GCLineStyle|GCCapStyle|GCJoinStyle|GCFillStyle|GCFillRule|
+ GCFont|GCDashOffset|GCDashList|GCArcMode);
+ values.function=GXcopy;
+ values.cap_style=CapButt;
+ values.join_style=JoinBevel;
+ values.fill_style=FillSolid;
+ values.fill_rule=WindingRule;
+ values.arc_mode=ArcPieSlice;
+ values.dash_offset=0;
+ values.dashes=4;
+ if ((font_info = XLoadQueryFont(display,fontname)) == NULL)
+ {protokoll("can't load font: ", fontname);
+ fehler(7);}
+ values.font=font_info->fid;
+ values.line_width=2;
+ values.line_style=LineSolid;
+ values.foreground=BlackPixel(display,screen);
+ values.background=WhitePixel(display,screen);
+ gcinverse = XCreateGC(display,win,valuemask,&values);
+ XSetFunction(display,gcinverse,GXinvert);
+ XSetPlaneMask(display,gcinverse,
+ BlackPixel(display,screen)^WhitePixel(display,screen));
+ gcxor = XCreateGC(display,win,valuemask,&values);
+ XSetFunction(display,gcxor,GXxor);
+ XSetPlaneMask(display,gcxor,
+ BlackPixel(display,screen)^WhitePixel(display,screen));
+ values.line_width=1;
+ gcstd = XCreateGC(display,win,valuemask,&values);
+ gczeichnung= XCreateGC(display,win,valuemask,&values);
+ initgctext(display, win,valuemask,&values);
+}
+
+Static Void systemstipple(display,win,nr,intensitaet)
+ Display *display;
+ Window win;
+ long nr;
+ double intensitaet;
+{ /* erzeugen systematisches Stipple fuer Farben bei Monochrom */
+ long i, bitnr, j, k, helligkeit, maxbits, maxbytes, offset;
+ double faktor;
+
+ maxbits = hcolorbits*bcolorbits;
+ maxbytes = maxbits/8;
+ if (maxbits > 8*maxbytes) maxbytes++;
+ helligkeit = maxbits*intensitaet;
+ if ((helligkeit % 2)==0) helligkeit++; /* damit keine | _ Linien */
+ offset = helligkeit % 8;
+ faktor = (double)maxbits/(double)helligkeit;
+ for (i=0;i<maxbytes;i++)
+ colorbits[i] = 255; /* ganz schwarz */
+ for (i=0; i<=helligkeit;i++) {/* stipples loeschen */
+ bitnr = faktor*i + offset;
+ if (frand()>0.95) /* etwas Zufall ! */
+ bitnr++;
+ j = bitnr/8; j = j % maxbytes;
+ k = bitnr % 8;
+ colorbits[j] = colorbits[j] & (~ (1<<k)); /*k.Bit in j.Zeile*/
+ }
+ colorstipple[nr] = XCreateBitmapFromData(display,win,colorbits,
+ bcolorbits,hcolorbits);
+}
+
+Static Void initfarben(screen, display, win)
+ long screen;
+ Display *display;
+ Window win;
+/* Erzeugen aller verfuegbaren Farben */
+{
+ long i, nr, erg, ordnung, nvh;
+ double h,s,v;
+ Char colorname[maxlenfarbe+1];
+ XColor rgbsolldef;
+ XWindowAttributes winattr;
+
+ nvh = 0;
+ cmap=DefaultColormap(display,screen);
+ for (nr=0;nr<aktzahlfarben;nr++) {
+ strcpy(colorname, farbname[nr]);
+ erg=XAllocNamedColor(display,cmap,colorname,&(rgbistdef[nr]),&rgbsolldef);
+ if (erg!=1) {
+ printf("color %s not available\n",colorname);
+ nvh++;
+ }
+ if ((erg!=1)||((nr>=2)&&
+ (rgbistdef[nr].red ==rgbistdef[weiss].red)&&
+ (rgbistdef[nr].green==rgbistdef[weiss].green)&&
+ (rgbistdef[nr].blue ==rgbistdef[weiss].blue))){
+ rgbistdef[nr].pixel=rgbistdef[schwarz].pixel;
+ rgbistdef[nr].red=rgbistdef[schwarz].red;
+ rgbistdef[nr].green=rgbistdef[schwarz].green;
+ rgbistdef[nr].blue=rgbistdef[schwarz].blue;
+ rgbistdef[nr].flags=rgbistdef[schwarz].flags;
+ }
+ /* Helligkeit 0..1 bestimmen */
+ intensity[nr] = (0.299*rgbsolldef.red + 0.587*rgbsolldef.green
+ + 0.114*rgbsolldef.blue)/65535.0;
+ if (nr <= letztesgrau)
+ farbposfarbnr[nr]=nr;
+ else
+ farbposfarbnr[nr]=rgb2hsv2ordnung(rgbsolldef.red,
+ rgbsolldef.green,rgbsolldef.blue,65535);
+
+ if (nocolors == true) {
+ systemstipple(display, win, nr,intensity[nr]);
+ }
+ }
+ if (nvh != 0) {
+ printf("we try to allocate own colormap\n");
+ nvh = XGetWindowAttributes(display,win,&winattr);
+ if (nvh != 0) {
+ cmap = XCreateColormap(display,win,winattr.visual,AllocNone);
+ XSetWindowColormap(display,win,cmap);
+ for (nr=0;nr<aktzahlfarben;nr++) {
+ strcpy(colorname, farbname[nr]);
+ erg=XAllocNamedColor(display,cmap,colorname,&(rgbistdef[nr]),&rgbsolldef);
+ if (erg!=1) {
+ printf("color %s not available in own colormap\n",colorname);
+ }
+ if ((erg!=1)||((nr>=2)&&
+ (rgbistdef[nr].red ==rgbistdef[weiss].red)&&
+ (rgbistdef[nr].green==rgbistdef[weiss].green)&&
+ (rgbistdef[nr].blue ==rgbistdef[weiss].blue))){
+ rgbistdef[nr].pixel=rgbistdef[schwarz].pixel;
+ rgbistdef[nr].red=rgbistdef[schwarz].red;
+ rgbistdef[nr].green=rgbistdef[schwarz].green;
+ rgbistdef[nr].blue=rgbistdef[schwarz].blue;
+ rgbistdef[nr].flags=rgbistdef[schwarz].flags;
+ }
+ /* Helligkeit 0..1 bestimmen */
+ intensity[nr] = (0.299*rgbsolldef.red + 0.587*rgbsolldef.green
+ + 0.114*rgbsolldef.blue)/65535.0;
+ if (nr <= letztesgrau)
+ farbposfarbnr[nr]=nr;
+ else
+ farbposfarbnr[nr]=rgb2hsv2ordnung(rgbsolldef.red,
+ rgbsolldef.green,rgbsolldef.blue,65535);
+
+ if (nocolors == true) {
+ systemstipple(display, win, nr,intensity[nr]);
+ }
+ }
+ }
+ }
+
+
+ for (i=0;i <= 8;i++) {
+ /* Bitmaps fuer grau erzeugen */
+ graystipple[i]=XCreateBitmapFromData(display,win,graybits[i],4,4);
+ }
+}
+
+Static Void eintragefarbname(nr, colorname)
+ long *nr;
+ Char *colorname;
+/* Eintragen eines Farbnamens */
+/* nr ist Farbnummer, die auch in Farbmakros verwendet wird */
+
+{ long i, m;
+ Char cc;
+
+ if (*nr >= maxzahlfarben) return; /*ignorieren, zu viele Farben*/
+ strcpy(farbname[*nr],colorname);
+ m=strlen(colorname);
+ /* verkuerzten Farbnamen fuer Menue erzeugen */
+ if (m<=maxlenmenfarbe) strcpy(menfarbname[*nr],colorname);
+ else {
+ for (i=0; i<maxlenmenfarbe;i++) menfarbname[*nr][i]=colorname[i];
+ cc=colorname[m-1];
+ if ((cc>='0')&&(cc<='9')) menfarbname[*nr][maxlenmenfarbe-1]=cc;
+ menfarbname[*nr][maxlenmenfarbe]='\0';
+ }
+ *nr = *nr+1;
+}
+
+Static Void initfarbnamen()
+/* Erzeugen aller verfuegbaren Farbnamen */
+/* Reihenfolge der Aufrufe bestimmt Farbnummer in Latex */
+/* deshalb darf Reihenfolge nicht mehr ver"andert werden !!! */
+/* die Positionsnummer im Farbmenue wird spaeter berechnet */
+{ long nr;
+
+ nr=0;
+ eintragefarbname(&nr, "black");
+ eintragefarbname(&nr, "white");
+ eintragefarbname(&nr, "gray90");
+ eintragefarbname(&nr, "gray80");
+ eintragefarbname(&nr, "gray70");
+ eintragefarbname(&nr, "gray60");
+ eintragefarbname(&nr, "gray50");
+ eintragefarbname(&nr, "gray40");
+ eintragefarbname(&nr, "gray30");
+ eintragefarbname(&nr, "gray20");
+ eintragefarbname(&nr, "gray10");
+ letztesgrau = nr-1; /*maximal 10*/
+ if (letztesgrau > 10) {letztesgrau = 10; nr=11;}
+ eintragefarbname(&nr, "red1");
+ eintragefarbname(&nr, "orange1");
+ eintragefarbname(&nr, "sienna1");
+ eintragefarbname(&nr, "gold1");
+ eintragefarbname(&nr, "yellow");
+ eintragefarbname(&nr, "chartreuse1");
+ eintragefarbname(&nr, "green");
+ eintragefarbname(&nr, "SpringGreen1");
+ eintragefarbname(&nr, "cyan");
+ eintragefarbname(&nr, "blue");
+ eintragefarbname(&nr, "DarkOrchid1");
+ eintragefarbname(&nr, "orchid1");
+ eintragefarbname(&nr, "magenta");
+ eintragefarbname(&nr, "red3");
+ eintragefarbname(&nr, "orange3");
+ eintragefarbname(&nr, "brown2");
+ eintragefarbname(&nr, "orange2");
+ eintragefarbname(&nr, "yellow3");
+ eintragefarbname(&nr, "chartreuse3");
+ eintragefarbname(&nr, "green3");
+ eintragefarbname(&nr, "SpringGreen3");
+ eintragefarbname(&nr, "cyan3");
+ eintragefarbname(&nr, "blue3");
+ eintragefarbname(&nr, "DarkOrchid3");
+ eintragefarbname(&nr, "orchid3");
+ eintragefarbname(&nr, "magenta3");
+ eintragefarbname(&nr, "MistyRose1");
+ eintragefarbname(&nr, "PeachPuff1");
+ eintragefarbname(&nr, "RosyBrown1");
+ eintragefarbname(&nr, "khaki1");
+ eintragefarbname(&nr, "LightYellow1");
+ eintragefarbname(&nr, "wheat1");
+ eintragefarbname(&nr, "MintCream");
+ eintragefarbname(&nr, "PaleGreen1");
+ eintragefarbname(&nr, "LightCyan1");
+ eintragefarbname(&nr, "LightBlue1");
+ eintragefarbname(&nr, "thistle1");
+ eintragefarbname(&nr, "plum1");
+ eintragefarbname(&nr, "LavenderBlush1");
+ eintragefarbname(&nr, "PaleTurquoise1");
+ eintragefarbname(&nr, "DarkSeaGreen1");
+ eintragefarbname(&nr, "aquamarine1");
+ eintragefarbname(&nr, "DeepSkyBlue1");
+ eintragefarbname(&nr, "SlateBlue1");
+ eintragefarbname(&nr, "MediumOrchid1");
+ eintragefarbname(&nr, "IndianRed1");
+ eintragefarbname(&nr, "DeepPink1");
+ eintragefarbname(&nr, "brown1");
+
+ if (nr > maxzahlfarben) aktzahlfarben=maxzahlfarben;
+ else aktzahlfarben = nr;
+}
+
+Static Void schluss(i)
+long i;
+{
+ XCloseDisplay(display);
+ if (datdeskr != NULL)
+ fclose(datdeskr);
+ exit(i);
+}
+
+
+Static double si_fabs(x)
+double x;
+/* Absolutwert GP-Zahl */
+{
+ if (x < 0.0)
+ return (-x);
+ else return (x);
+}
+
+Static double sisqrt(term, x)
+double term, x;
+/* Wurzel mit Ausgleich Rundungsfehler */
+/* Wurzel aus neg. Zahl gibt neg. Wert */
+{
+ if (x > 0.0)
+ return sqrt(x);
+ else if (si_fabs(x) <= si_fabs(term) * 0.001)
+ return 0.0;
+ else
+ return (-sqrt(si_fabs(x)));
+}
+
+Static double sifsqrt(term, x)
+double term, x;
+/* Wurzel mit Ausgleich Rundungsfehler */
+/* Wurzel aus neg. Zahl gibt Fehler */
+{
+ double w;
+ w = sisqrt(term, x);
+ if (w < 0.0)
+ fehler(5L);
+ return w;
+}
+
+Static double fsign(x)
+double x;
+/* Vorzeichen einer GP-Zahl */
+{
+ if (x >= 0.0)
+ return 1.0;
+ else
+ return -1.0;
+}
+
+Static Void glersterord(a, b, anz, erg)
+double a, b;
+long *anz;
+double *erg;
+/* Gl. ax+b=0 loesen */
+/* Anzahl anz der Loesungen in erg[1],... */
+{
+ *anz = 0;
+ if (a != 0.0) {
+ *anz = 1;
+ erg[1] = -(b / a);
+ }
+}
+
+Static Void glzweiterord(a, b, c, anz, erg)
+double a, b, c;
+long *anz;
+double *erg;
+/* Gl. ax*x+b*x+c=0 loesen */
+/* Anzahl anz der Loesungen in erg[1],... */
+{
+ double w, n;
+ if (a == 0.0) {
+ glersterord(b, c, anz, erg);
+ return;
+ }
+ w = b * b - 4.0 * a * c;
+ n = 1.0 / (2.0 * a);
+ w = sisqrt(b * b, w);
+ if (w < 0.0)
+ *anz = 0;
+ if (w == 0.0) {
+ *anz = 1;
+ erg[1] = -b * n;
+ }
+ if (w <= 0.0)
+ return;
+ *anz = 2;
+ erg[1] = (w - b) * n;
+ erg[2] = (-b - w) * n;
+}
+
+
+Static double drittewurzel(x)
+double x;
+{
+ return (-fsign(x) * exp(log(si_fabs(x)) / 3.0));
+}
+
+
+Static double Cosh(x)
+double x;
+{
+ return ((exp(x) + exp(-x)) / 2.0);
+}
+
+
+Static double Sinh(x)
+double x;
+{
+ return ((exp(x) - exp(-x)) / 2.0);
+}
+
+
+Static double arcosh(x)
+double x;
+{
+ /* x ist groesser 1 !*/
+ return log(x + sifsqrt(1.0, x * x - 1.0));
+}
+
+
+Static double arsinh(x)
+double x;
+{
+ return log(x + sifsqrt(1.0, x * x + 1.0));
+}
+
+
+Static Void nachkorr(a, b, c, d, e, x)
+double a, b, c, d, e, *x;
+/* Nachkorrektur einer Loesung x einer Gleichung */
+/* a*x*x*x*x+b*x*x*x+c*x*x+d*x+e=0 */
+/* durch Newton-Extrapolation */
+{
+ double g, gstr, gzwstr, dx;
+ dx = 0.0;
+ g = (((a * *x + b) * *x + c) * *x + d) * *x + e;
+ gstr = ((4.0 * a * *x + 3.0 * b) * *x + 2.0 * c) * *x + d;
+ if (0.1 * si_fabs(*x * gstr) > si_fabs(g)) /*Korrektur sinnvoll*/
+ dx = -(g / gstr);
+ else { /*Doppelnullstelle */
+ gzwstr = (2.0 * a * *x + b) * 6.0 * *x + 2.0 * c;
+ if (0.1 * si_fabs(*x * gzwstr) > si_fabs(gstr))
+ dx = -(gstr / gzwstr);
+ }
+ *x += dx;
+}
+
+
+Static Void gldritterord(a, b, c, d, anz, erg)
+double a, b, c, d;
+long *anz;
+double *erg;
+/* Gl. ax*x*x+b*x*x+c*x+d=0 loesen */
+/* Anzahl anz der Loesungen in erg[1],... */
+{
+ double p, q, eda, det, r, cphi, sphi, phi, korr;
+ long i;
+ if (a == 0.0) {
+ glzweiterord(b, c, d, anz, erg);
+ goto _L1;
+ }
+ if (si_fabs(d) < 0.001) {
+ glzweiterord(a, b, c, anz, erg);
+ (*anz)++;
+ erg[*anz] = 0.0;
+ goto _L1;
+ }
+ eda = 1 / a;
+ korr = b * eda / -3.0;
+ p = (3.0 * a * c - b * b) * eda * eda / 9.0;
+ q = ((b * b * b * eda / 27.0 - b * c / 6.0) * eda + d / 2.0) * eda;
+ det = q * q + p * p * p;
+ r = fsign(q) * sifsqrt(1.0, si_fabs(p));
+ if (p == 0.0 && q == 0.0) {
+ *anz = 1;
+ erg[1] = korr;
+ goto _L1;
+ }
+ if (p == 0.0) {
+ *anz = 1;
+ erg[1] = drittewurzel(-2.0 * q) + korr;
+ goto _L1;
+ }
+ if (p < 0.0 && det <= 0.0) {
+ cphi = q / (r * r * r);
+ if (cphi == 0.0)
+ phi = pi / 2.0;
+ else {
+ sphi = sifsqrt(1.0, 1.0 - cphi * cphi);
+ phi = atan(sphi / cphi);
+ }
+ *anz = 3;
+ erg[1] = korr - 2.0 * r * cos(phi / 3.0);
+ erg[2] = 2.0 * r * cos((pi - phi) / 3.0) + korr;
+ erg[3] = 2.0 * r * cos((pi + phi) / 3.0) + korr;
+ goto _L1;
+ }
+ if (p < 0.0 && det > 0.0) {
+ *anz = 1;
+ erg[1] = korr - 2.0 * r * Cosh(arcosh(q / (r * r * r)) / 3.0);
+ goto _L1;
+ }
+ *anz = 1;
+ erg[1] = korr - 2.0 * r * Sinh(arsinh(q / (r * r * r)) / 3.0);
+_L1:
+ for (i = 1; i <= *anz; i++)
+ nachkorr(0.0, a, b, c, d, &erg[i]);
+}
+
+
+Static Void glvierterord(a, b, c, d, e, anz, erg)
+double a, b, c, d, e;
+long *anz;
+double *erg;
+/* Gl. a*x*x*x*x+b*x*x*x+c*x*x+d*x+e=0 loesen */
+/* Anzahl anz der Loesungen in erg[1],... */
+{
+ double ga, eda, b1, c1, d1, e1, y, w;
+ terg erg1;
+ long anz1, i;
+ if (a == 0.0) {
+ gldritterord(b, c, d, e, anz, erg);
+ goto _L1;
+ }
+ if (si_fabs(e) < 0.001) {
+ gldritterord(a, b, c, d, anz, erg);
+ (*anz)++;
+ erg[*anz] = 0.0;
+ goto _L1;
+ }
+ if (b == 0.0 && d == 0.0) {
+ glzweiterord(a, c, e, &anz1, erg1);
+ *anz = 0;
+ for (i = 1; i <= anz1; i++) {
+ w = sisqrt(1.0, erg1[i]);
+ if (w >= 0.0) {
+ *anz += 2;
+ erg[*anz - 1] = w;
+ erg[*anz] = -w;
+ }
+ }
+ goto _L1;
+ }
+ eda = 1 / a;
+ b1 = b * eda;
+ c1 = c * eda;
+ d1 = d * eda;
+ e1 = e * eda;
+ gldritterord(8.0, -4.0 * c1, 2.0 * b1 * d1 - 8.0 * e1,
+ e1 * (4.0 * c1 - b1 * b1) - d1 * d1, anz, erg);
+ y = erg[1];
+ ga = 8.0 * y + b1 * b1 - 4.0 * c1;
+ if (si_fabs(8.0 * y) > si_fabs(b1 * b1))
+ w = 8.0 * y;
+ else
+ w = b1 * b1;
+ if (si_fabs(w) < si_fabs(4.0 * c1))
+ w = 4.0 * c1;
+ ga = sisqrt(w, ga);
+ *anz = 0;
+ if (ga < 0.0)
+ goto _L1;
+ eda = b1 * y - d1;
+ if (ga == 0.0 && si_fabs(eda) > 0.001)
+ goto _L1;
+ if (ga == 0.0 && si_fabs(eda) <= 0.001)
+ eda = 0.0;
+ else
+ eda /= ga;
+ glzweiterord(1.0, (b1 + ga) / 2.0, y + eda, &anz1, erg1);
+ glzweiterord(1.0, (b1 - ga) / 2.0, y - eda, anz, erg);
+ for (i = 1; i <= anz1; i++)
+ erg[*anz + i] = erg1[i];
+ *anz += anz1;
+_L1:
+ for (i = 1; i <= *anz; i++)
+ nachkorr(a, b, c, d, e, &erg[i]);
+}
+
+
+Static Void initgrid()
+{
+ gridw0 = 5.0 / texfaktorv;
+ gridw = gridw0;
+ gridx0 = xmittelzei;
+ gridy0 = ymittelzei;
+ gridwx1 = 1.0;
+ gridwy1 = 0.0;
+ gridwx2 = 0.0;
+ gridwy2 = 1.0;
+}
+
+Static Void ftausch(x, y)
+double *x, *y;
+{
+ double c;
+
+ c = *x;
+ *x = *y;
+ *y = c;
+}
+
+Static Void initgruppentag(tag)
+long tag;
+{
+ long i;
+
+ for (i=0; i<=grumax; i++)
+ gruppentag[i] = tag;
+}
+
+Static long sohn(i, gruppe)
+long gruppe, i;
+{ /*i. Sohn der Gruppe im Baum */
+ /* Null falls keiner vorhanden */
+ long j, k;
+
+ if ((gruppe < 1)||(gruppe >grumax)) return 0;
+ k = 0;
+ for (j=1;j<=grumax;j++) {
+ if (vater[j]==gruppe) {
+ k++;
+ if (k==i) return j;
+ }
+ }
+ return 0;
+}
+
+Static long gruppenwurzel(elsel)
+long elsel;
+{ /* oberste Gruppe, zu der die angegebene Gruppe gehoert */
+ /* Null es gibt keine */
+ long i, gruppe;
+
+ gruppe = group[elsel];
+ if ((gruppe < 1)||(gruppe >grumax)) return 0;
+ i = gruppe;
+ while (vater[i] != 0)
+ i = vater[i];
+ return i;
+}
+
+Static Void markteilbaum(gruppe,tag)
+long gruppe,tag;
+{
+ long j,g;
+
+ j = 1;
+ while ( (g=sohn(j,gruppe)) != 0) {/* j. Sohn von gruppe untersuchen */
+ j++;
+ markteilbaum(g,tag);
+ }
+ gruppentag[gruppe] = tag;
+}
+
+Static Void blinkgruppe(elsel)
+long elsel;
+{/* bei allen Elementen, die zur Gruppe des angegebenen Elements und */
+ /* den darueberliegenden Gruppen gehoeren wird blink gesetzt */
+ /* blink wird vorher nicht geloescht ! */
+ long i,gw;
+
+ if ((elsel<1)||(typ[elsel]<=0)||(elsel >zelmax)) return;
+ blink[elsel]=true;
+ gw=gruppenwurzel(elsel);
+ if (gw==0) return;
+ markteilbaum(gw,true);
+ for (i=1;i<=zelmax;i++) {
+ if ((typ[i] >0) && (group[i] != 0) &&
+ (gruppentag[group[i]] == true)) {
+ /* Element gehoert zu der Gruppe */
+ blink[i]=true;
+ }
+ }
+ /* alle Elemente der Gruppe sind markiert */
+}
+
+
+Static long freiegruppe()
+{
+ long i;
+
+ for (i=1;i<=maxgruppen;i++)
+ if (vater[i]==-1){/*freies Element*/
+ vater[i]=0;
+ gruppentag[i] = false;
+ if (i>grumax)
+ grumax = i;
+ return i;
+ }
+ fehler(17);
+}
+
+Static Void gruppieren(elsel,wurzel)
+long elsel, wurzel;
+{ /* neue Gruppe bilden */
+
+ long g;
+
+ g = gruppenwurzel(elsel);
+ if (g==wurzel) return;
+ if (g==0) /* Element direkt in Gruppe */
+ group[elsel] = wurzel;
+ else
+ vater[g]=wurzel;
+}
+
+Static Void grumaxbestimmen()
+{
+ long i;
+
+ for (i=grumax;i>0;i--) {
+ if (vater[i] != -1)
+ break;
+ }
+ grumax = i;
+}
+
+Static Void loeschegruppe(elsel)
+long elsel;
+{
+ long i, vorh, wurzel;
+
+ vorh=false;
+ wurzel = gruppenwurzel(elsel);
+ if (wurzel == 0) {/* nur ein Element */
+ group[elsel] = 0;
+ return;
+ }
+ for (i=1;i<=grumax;i++) {
+ if (vater[i]==wurzel) {
+ vater[i]=0;
+ }
+ }
+ vater[wurzel]=-1; /*Gruppennummer wieder frei */
+ grumaxbestimmen();
+ /* Direkt an Wurzel haengende Eelemente vereinzeln */
+ for (i=1;i<=zelmax;i++) {
+ if (group[i]==wurzel)
+ group[i]=0;
+ }
+}
+
+Static Void unbenutztegruppenfreigeben()
+{
+ long elsel, g, gw;
+
+ if (aenderunggruppen == false)
+ return;
+ aenderunggruppen = false;
+ initgruppentag(false);
+ for (elsel=1;elsel <= zelmax; elsel++) {
+ if (typ[elsel] > 0) {
+ g = group[elsel];
+ if (g != 0)
+ gruppentag[g] = true;
+ }
+ }
+ LL: ;
+ for (g=1;g<=grumax;g++) {
+ if (gruppentag[g] == true){
+ if (vater[g] == -1)
+ vater[g] =0;
+ if ((vater[g] > 0)&&(gruppentag[vater[g]] ==false)) {
+ gruppentag[vater[g]] = true;
+ goto LL;
+ }
+ }
+ }
+ /* nicht benoetigte Gruppen freigeben ! */
+ for (g=1;g<=grumax;g++) {
+ if (gruppentag[g] == false)
+ vater[g] = -1;
+ }
+ grumaxbestimmen();
+}
+
+Static Void gruppenumbenennen()
+{
+/* es werden die Gruppen zur Umbenennung vorgesehen, deren Gruppentag */
+/* true ist */
+ long i,imax,ineu,v,vneu,g;
+
+ for (i=1;i<=grumax;i++)
+ umbenennung[i] = i;
+ if (selmenue[mgroupmode] == false) return;
+ imax = grumax;
+ for (i=1;i<=imax;i++) {
+ if (gruppentag[i] == true) {
+ g = freiegruppe();
+ gruppentag[g] = false;
+ umbenennung[i] = g;
+ aenderunggruppen = true;
+ }
+ }
+ for (i=1;i<=imax;i++) {
+ if (gruppentag[i] == true) {
+ v = vater[i];
+ if (v != 0)
+ vneu = umbenennung[v];
+ else
+ vneu = 0;
+ ineu = umbenennung[i];
+ vater[ineu] = vneu;
+ }
+ }
+}
+
+
+Static Void bestimmeneuegruppe(elsel)
+long elsel;
+{
+ if (group[elsel] == 0) return;
+ if (selmenue[mgroupmode] == true)
+ group[elsel] = umbenennung[group[elsel]];
+ else
+ group[elsel] = 0;
+}
+
+Static double ppabstand(x1, y1, x2, y2)
+double x1, y1, x2, y2;
+/* Abstand zweier Punkte */
+{
+ double dx, dy;
+
+ dx = (x2 - x1);
+ dy = (y2 - y1);
+ return (sifsqrt(1.0, dx * dx + dy * dy));
+}
+
+
+Static Void cursan(x, y)
+double x, y;
+/* Text-Cursor anschalten */
+{
+ double yrel;
+ curs_x=x;
+ curs_y=y;
+ yrel=y-wzeichendescent;
+ rechteckinverse(x,yrel,x+wzeichenbreite,yrel+wzeichenhoehe);
+}
+
+
+Static boolean nglw(a, b)
+ double a, b;
+ /* true, falls naeherungsweise gleiche Winkel */
+{
+ if (si_fabs(a - b) < 2.0)
+ return true;
+ else
+ return false;
+}
+
+
+Static boolean nglx(a, b)
+ double a, b;
+ /* true, falls naeherungsweise gleiche Koordinaten */
+{
+ if (si_fabs(a - b) < 0.1)
+ return true;
+ else
+ return false;
+}
+
+
+Static Void pskalieren(x, y, dx, dy, f)
+double *x, *y, dx, dy, f;
+/* Translation Punkt x,y um dx,dy, Skalierungsfaktor f*/
+/* Ergebnis wieder in x,y */
+{
+ *x = (*x - xmittelzei) * f + xmittelzei + dx;
+ *y = (*y - ymittelzei) * f + ymittelzei + dy;
+}
+
+Static Void ausmenueelement();
+
+Static Void somenfontwahl(i)
+ long i;
+{
+ fontnummer = i;
+ strcpy(menue[mfont],textfontlabel[fontnummer]);
+ ausmenueelement(mfont);
+}
+
+
+Static Void setzeakttextfont(elsel)
+long elsel;
+{
+ long fontart;
+
+ fontart = linetype[elsel];
+ if (fontart < 0) fontart = 0;
+ if (fontart >= ztextfonts) fontart = ztextfonts -1;
+ somenfontwahl(fontart);
+}
+
+Static Void textparam(elsel)
+long elsel;
+/* Berechenbare Parameter fuer Texte bestimmen */
+{
+ double th, thh, tl, tlh, ll, rl, dy;
+ long lage, fontart, lstr;
+ fontart = linetype[elsel];
+ if (fontart < 0) fontart = 0;
+ if (fontart >= ztextfonts) fontart = ztextfonts -1;
+ laenge1[elsel] = strlen(texte[textno[elsel]]);
+ lstr = siintround(laenge1[elsel]);
+ tl = XTextWidth(text_font_info[fontart],texte[textno[elsel]],lstr);
+ /*textbreite*/
+ tlh = 0.5 * tl;
+ th = textzeichenascent[fontart]; /*texthoehe*/
+ thh = 0.5 * th;
+ lage = (long)floor(si_fabs(laenge2[elsel]) + 0.2);
+ if (lage > 8) {/*eigentlich Fehlerfall*/
+ lage = 0;
+ laenge2[elsel] = 0.0;
+ }
+ switch (lage) { /*case*/
+ case 0: /*bl*/
+ ll = 0.0;
+ dy = 0.0;
+ break;
+ case 1: /*cc*/
+ ll = tlh;
+ dy = thh;
+ break;
+ case 2: /*rb*/
+ ll = tl;
+ dy = 0.0;
+ break;
+ case 3: /*cb*/
+ ll = tlh;
+ dy = 0.0;
+ break;
+ case 4: /*lt*/
+ ll = 0.0;
+ dy = th;
+ break;
+ case 5: /*rt*/
+ ll = tl;
+ dy = th;
+ break;
+ case 6: /*ct*/
+ ll = tlh;
+ dy = th;
+ break;
+ case 7: /*lc*/
+ ll = 0.0;
+ dy = thh;
+ break;
+ case 8: /*rc*/
+ ll = tl;
+ dy = thh;
+ break;
+ }
+ rl = tl - ll;
+ x2[elsel] = x1[elsel] - ll;
+ y2[elsel] = y1_[elsel] - dy;
+ xb2[elsel] = x1[elsel] + rl * crw[elsel];
+ yb2[elsel] = y1_[elsel] + rl * srw[elsel];
+ xb1[elsel] = x1[elsel] - ll * crw[elsel];
+ yb1[elsel] = y1_[elsel] - ll * srw[elsel];
+}
+
+
+Static Void skalieren(i, dx, dy, f)
+long i;
+double dx, dy, f;
+/* Skalieren Zeichnungselement i */
+{
+ pskalieren(&x1[i], &y1_[i], dx, dy, f);
+ pskalieren(&x2[i], &y2[i], dx, dy, f);
+ pskalieren(&xb1[i], &yb1[i], dx, dy, f);
+ pskalieren(&xb2[i], &yb2[i], dx, dy, f);
+ if (si_iabs(typ[i]) != ttext) {
+ laenge1[i] *= f;
+ laenge2[i] *= f;
+ }
+ else
+ textparam(i);
+ berechneminmax(i);
+}
+
+
+Static Void addtheorem(ca, sa, cb, sb, cab, sab)
+double ca, sa, cb, sb, *cab, *sab;
+{
+ *cab = ca * cb - sa * sb;
+ *sab = ca * sb + sa * cb;
+}
+
+
+Static Void ellpar(elsel, xm, ym, lx, ly, cr, sr)
+long elsel;
+double *xm, *ym, *lx, *ly, *cr, *sr;
+/* Parameter einer Ellipse zurueckgeben */
+{
+ *xm = x1[elsel];
+ *ym = y1_[elsel];
+ *lx = laenge1[elsel];
+ *ly = laenge2[elsel];
+ *cr = crw[elsel];
+ *sr = srw[elsel];
+}
+
+
+Static Void translation(dx, dy, xp, yp, xpr_, ypr_)
+ double dx, dy, xp, yp, *xpr_, *ypr_;
+ /* Koord. von p in neuem Koord.system, das um dx,dy translatiert*/
+{ *xpr_ = xp - dx;
+ *ypr_ = yp - dy;
+}
+
+
+Static Void rotation(cw, sw, xp, yp)
+ double cw, sw, *xp, *yp;
+ /*Koord. von p in neuem Koord.system, das positiv rotiert*/
+{
+ double hx, hy;
+ hx = cw * *xp + sw * *yp;
+ hy = cw * *yp - sw * *xp;
+ *xp = hx;
+ *yp = hy;
+}
+
+
+Static double winkel0(dx, dy, a, b)
+double dx, dy, a, b;
+/* Winkel von x_Achse zu Strecke von (0,0) zu (dx,dy) fuer Ellipse */
+/* mit Hauptachsen a und b und Mittelpunkt (0,0) */
+{
+ double at, rm;
+ if (dy == 0.0) {
+ if (dx >= 0.0)
+ at = 0.0;
+ else
+ at = wh;
+ goto _L1;
+ }
+ if (dx == 0.0) {
+ if (dy >= 0.0)
+ at = wv;
+ else
+ at = wdv;
+ goto _L1;
+ }
+ if (si_fabs(dy) > 10000.0 * si_fabs(dx)) { /*fast senkrecht*/
+ if (dy >= 0.0)
+ at = wv;
+ else
+ at = wdv;
+ goto _L1;
+ }
+ rm = si_fabs(a / b * (dy / dx));
+ at = fbograd * atan(rm);
+ /*spezielle Winkelrichtung gemaess Quadrant*/
+ if (dx < 0.0 && dy > 0.0)
+ at = wh - at;
+ if (dx < 0.0 && dy < 0.0)
+ at += wh;
+ if (dx > 0.0 && dy < 0.0)
+ at = wg - at;
+ if (si_fabs(at) < 0.01)
+ at = 0.0;
+ if (si_fabs(at - wg) < 0.01)
+ at = wg;
+_L1:
+ return at;
+}
+
+
+Static double winkelk(xm, ym, xp, yp)
+ double xm, ym, xp, yp;
+ /* Winkel von x_Achse zu Strecke von (xm,ym) zu (xp,yp)*/
+ /*xm,ym Mittelpunkt Kreis*/
+ /* xp,yp Koordinaten eines Punktes */
+{
+ double dx, dy;
+ translation(xm, ym, xp, yp, &dx, &dy);
+ return (winkel0(dx, dy, 1.0, 1.0));
+}
+
+
+Static Void setzewinkel(elsel, xm, ym, xp, yp)
+long elsel;
+double xm, ym, xp, yp;
+/* Berechne Drehwinkel des Zeichnungselementes elsel */
+{
+ rotwi[elsel] = winkelk(xm, ym, xp, yp);
+ crw[elsel] = cos(fgradbo * rotwi[elsel]);
+ srw[elsel] = sin(fgradbo * rotwi[elsel]);
+}
+
+
+Static Void ell_xy(xm, ym, a, b, cr, sr, xpr_, ypr_, xp, yp)
+ double xm, ym, a, b, cr, sr, xpr_, ypr_, *xp, *yp;
+ /* Umrechnung Punkt (xpr,ypr) im Ellipsenkoordinatensystem */
+ /* in das Weltkoordinatensystem, dort (xp,yp) */
+{
+ *xp = xpr_;
+ *yp = ypr_;
+ rotation(cr, -sr, xp, yp); /*Rotation um neg. Winkel*/
+ translation(-xm, -ym, *xp, *yp, xp, yp);
+}
+
+
+Static Void ellw_xy(xm, ym, a, b, cr, sr, w, xp, yp)
+ double xm, ym, a, b, cr, sr, w, *xp, *yp;
+ /* Punkt auf Ellipse durch Winkel w in Grad bei Ellipse definiert */
+ /* in Punkt (xp,yp) des Weltkoordinatensystems umrechnen */
+{
+ ell_xy(xm, ym, a, b, cr, sr, a * cos(w * fgradbo),
+ b * sin(w * fgradbo), xp, yp);
+}
+
+
+Static Void xy_ell(xm, ym, cr, sr, xp, yp, xpr_, ypr_)
+ double xm, ym, cr, sr, xp, yp, *xpr_, *ypr_;
+ /*Transformation Punkt (xp,yp) in Weltkoordinaten in */
+ /*Koordinatensystem der Ellipse, dort (xpr,ypr)*/
+{
+ translation(xm, ym, xp, yp, xpr_, ypr_);
+ rotation(cr, sr, xpr_, ypr_); /*Rotation um pos. Winkel*/
+}
+
+
+Static double winkelell(xm, ym, a, b, cr, sr, xp, yp)
+ double xm, ym, a, b, cr, sr, xp, yp;
+ /* xm,ym,a,b,cr,sr definieren Ellipse*/
+ /* xp,yp Punkt in Zeichenebene */
+ /* Winkel gesucht im Bezugskoordinatensystem der Ellipse*/
+{
+ double dx, dy;
+ xy_ell(xm, ym, cr, sr, xp, yp, &dx, &dy);
+ return (winkel0(dx, dy, a, b));
+}
+
+
+Static Void stdimagetextaus(twin, x, y, t, zcolor)
+Window twin;
+long zcolor;
+double x, y;
+Char *t;
+/* Ausgabe string t an Stelle x,y */
+{
+ long ix,iy,length;
+ length=strlen(t);
+ welt_to_bildschirm(x, y, &ix, &iy);
+ setcolor(display,gcstd,zcolor);
+ XDrawImageString(display,twin,gcstd,ix,iy,t,length);
+}
+
+Static Void stdtextaus(twin, x, y, t, zcolor)
+Window twin;
+long zcolor;
+double x, y;
+Char *t;
+/* Ausgabe string t an Stelle x,y */
+{
+ long ix,iy,length;
+ length=strlen(t);
+ welt_to_bildschirm(x, y, &ix, &iy);
+ setcolor(display,gcstd,zcolor);
+ XDrawString(display,twin,gcstd,ix,iy,t,length);
+}
+
+
+Static Void ztextaus(twin, elsel, x, y, t, zcolor, fontart)
+Window twin;
+long zcolor,fontart, elsel;
+double x, y;
+Char *t;
+/* Ausgabe string t an Stelle x,y in der Zeichnung */
+{ long ix,iy,length;
+
+ length=strlen(t);
+ welt_to_bildschirm(x, y, &ix, &iy);
+ setcolor(display,gctext[fontart],zcolor);
+ XDrawString(display,twin,gctext[fontart],ix,iy,t,length);
+}
+
+
+Static Void somentextaus(x, y, t, fontart)
+long fontart;
+double x, y;
+Char *t;
+/* Ausgabe string t an Stelle x,y in der Zeichnung */
+{
+ long ix,iy,lstr;
+ double dx;
+
+ lstr=strlen(t);
+ dx = XTextWidth(text_font_info[fontart],t,lstr);
+ welt_to_bildschirm(x-dx/2.0, y, &ix, &iy);
+ XDrawString(display,win,somengctext[fontart],ix,iy,t,lstr);
+}
+
+Static Void ausfarbkaestchen(xa,ye,xe,ya,zcolor)
+ double xa,ye,xe,ya;
+ long zcolor;
+{ long ix,iy,width,height;
+
+ rechteckbildschirmkoord(xa,ye,xe,ya,&ix,&iy,&width,&height);
+ setcolor(display,gcstd,zcolor);
+ XFillRectangle(display,win,gcstd,ix,iy,width,height);
+}
+
+Static Void faerbekaestchen(i, zcolor)
+ long i, zcolor;
+{
+ ausfarbkaestchen(xam[i],yem[i],xem[i],yam[i],zcolor);
+}
+
+Static Void somenbestxy(i, xa,ya,xe,ye,xt,yt)
+ long i;
+ double *xa,*ya,*xe,*ye,*xt,*yt;
+{ long reihe,spalte;
+
+ reihe= i/somenspalten;
+ spalte=i % somenspalten;
+ *xa=spalte*kaestchenhoehe+1.0*wzeichenbreite;
+ *ya=reihe*kaestchenhoehe+yprompt+1.5*wzeichenhoehe;
+ *xe=*xa+kaestchenhoehe;
+ *ye=*ya+kaestchenhoehe;
+ *xt=*xa+kaestchenhoehe/2.0;
+ *yt=*ya+kaestchenhoehe*0.1;
+}
+
+Static long somenbesti(x,y)
+ double x,y;
+{ long reihe,spalte;
+ double xa,ya;
+
+ xa=x-1.0*wzeichenbreite;
+ ya=y-yprompt-1.5*wzeichenhoehe;
+ if ((xa<0.0)||(ya<0.0)) return -1L;
+ spalte=xa/kaestchenhoehe;
+ reihe=ya/kaestchenhoehe;
+ return (reihe*somenspalten+spalte);
+}
+
+Static Void aussomenue()
+{ long i;
+ double xa,ya,xe,ye,xt,yt;
+
+ for (i=0;i<ztextfonts;i++) {
+ somenbestxy(i, &xa,&ya,&xe,&ye,&xt,&yt);
+ if (i!=1) somentextaus(xt,yt,"T",i);
+ }
+ for (i=0; i < aktzahlfarben; i++) {
+ somenbestxy(i+ztextfonts, &xa,&ya,&xe,&ye,&xt,&yt);
+ ausfarbkaestchen(xa,ye,xe,ya,farbnrfarbpos[i]);
+ }
+}
+
+Static Void prompt()
+/* Ausgabe Prompttext ab Stelle xprompt,yprompt */
+{
+ Char promptzeile[maxstrl+maxstrl+2];
+ long ls;
+ konkat(promptzeile,pr1,pr2); /*select/ menue[msel]*/
+ konkat(promptzeile,promptzeile,pr3); /*Hinweise*/
+ konkat(promptzeile,promptzeile,pr4); /*pr2menue[msel]*/
+ konkat(promptzeile,promptzeile,pr5); /*Text fuer Texteingabe*/
+ konkat(promptzeile,promptzeile,pr6); /*Eingabetext*/
+ ls = (long) floor((xzmax-xprompt)/wzeichenbreite);
+ if (ls >= maxstrl) ls=maxstrl;
+ ls = ls - strlen(promptzeile);
+ while (ls > 0) {
+ konkat(promptzeile,promptzeile,blank);
+ ls--;
+ }
+ stdimagetextaus(win,xprompt, yprompt, promptzeile,schwarz);
+}
+
+Static Void gridpunkt(mstrich, nstrich, x, y)
+ double mstrich,nstrich;
+ double *x, *y;
+{
+ *x = gridx0 + (mstrich * gridwx1 + nstrich * gridwx2) * gridw;
+ *y = gridy0 + (mstrich * gridwy1 + nstrich * gridwy2) * gridw;
+}
+
+
+Static Void textpositionieren()
+/* Positionieren des Textes im Fensterausschnitt */
+{ long lsa, ls, lsmax, tposoffset, ogrenzeoffset;
+
+ lsa = strlen(pr1)+strlen(pr2)+strlen(pr3)+strlen(pr4)+strlen(pr5);
+ ls = strlen(EinText);
+ lsmax = (long) floor((xzmax-xprompt)/wzeichenbreite)-3-lsa;
+ ogrenzeoffset = ls - lsmax;
+ if (ls <= lsmax)
+ tposoffset = 0;
+ else {
+ tposoffset = tposres - lsmax/2;
+ if (tposoffset < 0)
+ tposoffset = 0;
+ if (tposoffset > ogrenzeoffset)
+ tposoffset = ogrenzeoffset;
+ }
+ substringcpy(pr6,EinText,tposoffset,lsmax);
+ curs_x=xprompt+(tposres-tposoffset+lsa-1)*wzeichenbreite;
+ curs_y=yprompt;
+ if (geoeffnet==0) return;
+ cursan(curs_x, curs_y);
+}
+
+
+Static Void inittastaturtext(s,prtext, voll)
+Char *s,*prtext;
+long voll;
+/* Eingabe Tastaturtext */
+/* s ist Ergebnisstring, erst am Ende verfuegbar */
+/* s muss initialisiert sein */
+{
+ long ls,dphase;
+ Char csw[maxstrl+1];
+
+ erwartet=tastatur_erwartet;
+ strcpy(tpr1res,pr1);
+ strcpy(tpr2res,pr2);
+ strcpy(tpr3res,pr3);
+ strcpy(tpr4res,pr4);
+ if (voll==0) {
+ strcpy(pr1,nullstr);
+ strcpy(pr2,nullstr);
+ strcpy(pr3,nullstr);
+ strcpy(pr4,nullstr);
+ }
+ strcpy(pr5,prtext);
+ strcpy(EinText,s);
+ ls = strlen(EinText);
+ tposres = ls + 1;
+ textpositionieren();
+}
+
+
+Static long tastaturtext(taste)
+long taste;
+/* Eingabe Tastaturtext */
+/* Ergebnis ==0: String fertig eingegeben */
+/* Ergebnis !=0: String noch nicht mit Return abgeschlossen */
+{
+ long ls,lsa;
+ Char csw[maxstrl+1];
+
+ lsa = strlen(pr1)+strlen(pr2)+strlen(pr3)+strlen(pr4)+strlen(pr5);
+ ls = strlen(EinText);
+ if ((taste == tastecursright1)|| (taste == tastecursright2)) {
+ if (tposres <= ls) (tposres)++;
+ goto L0A;
+ }
+ if ((taste == tastecursleft1)||(taste == tastecursleft2)) {
+ if (tposres > 1) (tposres)--;
+ goto L0A;
+ }
+ if ((taste==tasted)&&(controlan==1L)) {/*delete */
+ if (ls >= tposres) strdelete(EinText, (int)tposres);
+ goto L0A;
+ }
+ if ((taste==tastea)&&(controlan==1L)) {/*an Anfang Zeile */
+ tposres = 1;
+ goto L0A;
+ }
+ if ((taste==tastee)&&(controlan==1L)) {/*an Ende Zeile */
+ tposres = ls+1;
+ goto L0A;
+ }
+ if ((taste==tastek)&&(controlan==1L)) {/*loeschen bis Ende Zeile */
+ EinText[tposres-1] = 0;
+ goto L0A;
+ }
+ if (taste == tastebackspace || taste == tastedelete) {
+ if (tposres > 1) {
+ (tposres)--;
+ strdelete(EinText, (int)tposres);
+ }
+ goto L0A;
+ }
+ if (taste == tastereturn) /*Return*/
+ goto LE;
+ if (taste == 13) /*cr*/
+ goto LE;
+ if (taste == 10) /*lf*/
+ goto LE;
+ if (taste < 32) /*illegale Zeichen*/
+ goto L0A;
+ if (taste >255) /*illegale Zeichen */
+ goto L0A;
+ if (ls >= maxstrl) /*max stringlaenge erreicht*/
+ goto LE;
+ sprintf(csw, "%c", (Char)taste);
+ if (tposres <= ls)
+ strinsert(csw, EinText, (int)tposres);
+ else
+ konkat(EinText, EinText,csw);
+ (tposres)++;
+ goto L0A;
+ LE:
+ strcpy(pr1,tpr1res);
+ strcpy(pr2,tpr2res);
+ strcpy(pr3,tpr3res);
+ strcpy(pr4,tpr4res);
+ strcpy(pr5,nullstr);
+ strcpy(pr6,nullstr);
+ erwartet=click_erwartet;
+ return 0;
+
+ L0A:
+ textpositionieren();
+ return 1;
+}
+
+Static Void ausmenuetext(i,zcolor)
+/* Ausdruck eines Textes im Element i des Menues */
+long i,zcolor;
+{
+ double dx,dy;
+ Char s[maxstrl+1];
+
+ dx=0.5*wzeichenbreite;
+ dy=(si_fabs(yem[i]-yam[i])-wzeichenhoehe)/2.0;
+ dy=0.8*dy + wzeichendescent;
+ strcpy(s, menue[i]);
+ stdtextaus(win,xam[i] + dx, yam[i] + dy,s,zcolor);
+}
+
+Static Void ausmenueelement(i)
+ long i;
+{
+ if ((selmenue[i]==true)&&(i!=mcolor)){
+ faerbekaestchen(i,schwarz);
+ ausmenuetext(i, weiss);
+ menuerechteck(xam[i],yam[i],xem[i],yem[i]);
+ return;
+ }
+ if (i!=mcolor){
+ faerbekaestchen(i,weiss);
+ ausmenuetext(i, schwarz);
+ menuerechteck(xam[i],yam[i],xem[i],yem[i]);
+ return;
+ }
+ faerbekaestchen(i,aktcolor);
+ if (aktcolor==weiss) {ausmenuetext(i, schwarz); goto LW;}
+ if (aktcolor==schwarz) {ausmenuetext(i, weiss); goto LW;}
+ if (aktcolor <= (long) (letztesgrau/2)) {ausmenuetext(i, schwarz); goto LW;}
+ if (aktcolor <= letztesgrau) {ausmenuetext(i, weiss); goto LW;}
+/* if (((rgbistdef[aktcolor].red & 0377) >100)||
+ ((rgbistdef[aktcolor].green & 0377)>100)||
+ ((rgbistdef[aktcolor].blue & 0377)>100))
+*/
+ if (intensity[aktcolor] > 0.5)
+ ausmenuetext(i, schwarz);
+ else
+ ausmenuetext(i, weiss);
+ LW:
+ menuerechteck(xam[i],yam[i],xem[i],yem[i]);
+}
+
+Static long xyein(x, y, taste, phase)
+ long phase,taste;
+ double *x, *y;
+{
+ long anz;
+ double lgx, lgy;
+ switch (phase){
+ case 0: goto L0;
+ default: goto L1;
+ }
+ L0:
+ inittastaturtext(nullstr,pr2menue[mxytastatur],1L);
+ return 1;
+ L1:
+ anz=sscanf(EinText,"%lf%lf",&lgx,&lgy);
+ if (anz!=2) {lgx=0; lgy=0;}
+ /* lgx,lgy im Grid-Koordinatensystem, also umrechnen */
+ gridpunkt(lgx, lgy, x, y);
+ selmenue[mxytastatur] = false;
+ ausmenueelement((long)mxytastatur);
+ return 0;
+}
+
+
+Static Void koeff_bezier(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, bk)
+double p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y;
+tbezierkoeff *bk;
+{
+ bk->dx = p0x;
+ bk->cx = (p1x - p0x) * 3.0;
+ bk->bx = (p2x - p1x) * 3.0 - bk->cx;
+ bk->ax = p3x - p0x - bk->cx - bk->bx;
+ bk->dreiax = 3.0 * bk->ax;
+ bk->zweibx = 2.0 * bk->bx;
+ bk->dy = p0y;
+ bk->cy = (p1y - p0y) * 3.0;
+ bk->by = (p2y - p1y) * 3.0 - bk->cy;
+ bk->ay = p3y - p0y - bk->cy - bk->by;
+ bk->dreiay = 3.0 * bk->ay;
+ bk->zweiby = 2.0 * bk->by;
+}
+
+
+Static Void punkt_bezier(elsel, t, prx, pry)
+long elsel;
+double t, *prx, *pry;
+{ double J0,J1,J2,J3,emt;
+
+ emt = 1.0-t;
+ J0=emt*emt*emt;
+ J1=3.0*t*emt*emt;
+ J2=3.0*t*t*emt;
+ J3=t*t*t;
+ *prx=x1[elsel]*J0+xb1[elsel]*J1+xb2[elsel]*J2+x2[elsel]*J3;
+ *pry=y1_[elsel]*J0+yb1[elsel]*J1+yb2[elsel]*J2+y2[elsel]*J3;
+}
+
+Static Void ableitung_bezier(elsel, t, dxdt, dydt)
+long elsel;
+double t, *dxdt,*dydt;
+{ double dJ0,dJ1,dJ2,dJ3,emt;
+
+ emt = 1.0-t;
+ dJ0=-3.0*emt*emt;
+ dJ1=3.0*emt*emt-6.0*t*emt;
+ dJ2=6.0*t*emt-3.0*t*t;
+ dJ3=3.0*t*t;
+ *dxdt= x1[elsel]*dJ0+xb1[elsel]*dJ1+xb2[elsel]*dJ2+x2[elsel]*dJ3;
+ *dydt=y1_[elsel]*dJ0+yb1[elsel]*dJ1+yb2[elsel]*dJ2+y2[elsel]*dJ3;
+}
+
+Static double pbezabstand(elsel, xp, yp)
+long elsel;
+double xp, yp;
+{
+ terg erg;
+ tbezierkoeff bk;
+ long i, anzt;
+ double p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, d, dmin, xb, yb;
+
+ p0x = x1[elsel];
+ p0y = y1_[elsel];
+ p1x = xb1[elsel];
+ p1y = yb1[elsel];
+ p2x = xb2[elsel];
+ p2y = yb2[elsel];
+ p3x = x2[elsel];
+ p3y = y2[elsel];
+ dmin = ppabstand(p0x, p0y, xp, yp);
+ d = ppabstand(p3x, p3y, xp, yp);
+ if (d < dmin)
+ dmin = d;
+ koeff_bezier(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, &bk);
+ gldritterord(bk.ax, bk.bx, bk.cx, bk.dx - xp, &anzt, erg);
+ for (i = 1; i <= anzt; i++) {
+ if ((erg[i] >= 0.0)&&(erg[i] <= 1.0)) { /*Aenderung 19.12.92.*/
+ punkt_bezier(elsel, erg[i], &xb, &yb);
+ d = ppabstand(xb, yb, xp, yp);
+ if (d < dmin) dmin = d;
+ }
+ }
+ gldritterord(bk.ay, bk.by, bk.cy, bk.dy - yp, &anzt, erg);
+ for (i = 1; i <= anzt; i++) {
+ if ((erg[i] >= 0.0)&&(erg[i] <= 1.0)) { /*Aenderung 19.12.92.*/
+ punkt_bezier(elsel, erg[i], &xb, &yb);
+ d = ppabstand(xb, yb, xp, yp);
+ if (d < dmin) dmin = d;
+ }
+ }
+ return dmin;
+}
+
+Static long getlinedicke(i)
+long i;
+{long ldicke;
+
+ ldicke=linedicke[i];
+ ldicke=ldicke % 100;
+ if (ldicke > maxldicke) ldicke=maxldicke;
+ return ldicke;
+}
+
+
+Static long getmenuecolor()
+{
+ return aktcolor;
+}
+
+Static long getlinecolor(i)
+long i;
+{long lcolor;
+
+ lcolor=schwarz; /*linecolor*/
+ if (linedicke[i] >=100) lcolor = linedicke[i]/100;
+ return lcolor;
+}
+
+
+Static long getzcolor(i, painterase)
+ long i, painterase;
+{ long lcolor, zcolor;
+
+ lcolor = getlinecolor(i); /*Farbe der Linie*/
+ zcolor = weiss; /*Farbe, die zu zeichnen*/
+ if (painterase==paint) zcolor=lcolor;
+ return zcolor;
+}
+
+
+Static Void getlineattribute(i, elemtyp, ltyp, ldicke, lende, lcolor)
+long i, elemtyp, *ltyp, *ldicke, *lende, *lcolor;
+{
+ if (i == 0) {
+ *lende = 0; /*kein Pfeil*/
+ if (selmenue[mpfeilende]==true) /*Pfeil am Ende*/
+ *lende = 2;
+ if (selmenue[mpfeilanf]==true) /*Pfeil am Anfang*/
+ *lende = 1;
+ if ((selmenue[mpfeilanf]==true) && (selmenue[mpfeilende]==true))
+ *lende = 3;
+ *ldicke = aktldicke; /*eingestellte Linienstaerke*/
+ *ltyp = 1; /*solid*/
+ if (selmenue[mgestrichelt]==true) /*_ _ */
+ *ltyp = 5;
+ if (selmenue[mgepunktet]==true) /*....*/
+ *ltyp = 3;
+ if ((selmenue[mgestrichelt]==true) && (selmenue[mgepunktet]==true))
+ /*_._*/
+ *ltyp = 7;
+ if ((selmenue[mcapprojecting] == true)&&(elemtyp == tgerade)&&
+ (*lende == 0)&&(*ltyp == 1))
+ *lende = 4; /*cap projecting */
+ *lcolor = getmenuecolor();
+ return;
+ }
+ *ltyp = linetype[i];
+ *ldicke = getlinedicke(i);
+ *lende = lineende[i];
+ *lcolor = getlinecolor(i);
+}
+
+Static Void setlineattribute(i, elsel)
+ long i, elsel;
+{long ltyp, ldicke, lende, lcolor;
+
+ getlineattribute(i, typ[elsel], &ltyp, &ldicke, &lende, &lcolor);
+ if (typ[elsel] != ttext) linetype[elsel] = ltyp;
+ linedicke[elsel] = 100*lcolor+ldicke;
+ lineende[elsel] = lende;
+}
+
+Static Void winpfeilaus(i, ende, xp, yp, x2, y2,zcolor)
+ long i, ende,zcolor;
+ double xp, yp, x2, y2;
+/* Pfeilspitze an xp,yp */
+/* Pfeilende in Richtung Punkt x2,y2 */
+/* ende=1 fuer Anfang, ende=2 fuer Ende */
+{
+ double d,lpf,bpf,sg,cg;
+ XPoint points[maxpunkte];
+ switch (lineende[i]){
+ case 0: return;
+ case 1: if (ende!=1) return; break;
+ case 2: if (ende!=2) return; break;
+ case 3: break;
+ case 4: return;
+ }
+ lpf=6.0+0.8*getlinedicke(i);/*Laenge Pfeil*/
+ bpf=(4.0+1.2*getlinedicke(i))*0.5;/*halbe Breite Pfeil*/
+ d=ppabstand(xp,yp,x2,y2);
+ if (d==0) return;
+ sg=(y2-yp)/d;
+ cg=(x2-xp)/d;
+ rpxarray[0] = xp;
+ rpyarray[0] = yp;
+ rpxarray[1] = xp+(cg*lpf-sg*bpf);
+ rpyarray[1] = yp+(sg*lpf+cg*bpf);
+ rpxarray[2] = xp+(cg*lpf+sg*bpf);
+ rpyarray[2] = yp+(sg*lpf-cg*bpf);
+ rpxarray[3] = xp;
+ rpyarray[3] = yp;
+ ausfillpolygon(4L,zcolor);
+}
+
+
+Static Void winpfeile(i,zcolor)
+long i, zcolor;
+{
+ double xm, ym, lx, ly, cr, sr,xp1,xp2,yp1,yp2;
+
+ switch (typ[i]) {
+ case tgerade:
+ winpfeilaus(i, 1L,x1[i],y1_[i],x2[i],y2[i],zcolor);
+ winpfeilaus(i, 2L,x2[i],y2[i],x1[i],y1_[i],zcolor);
+ break;
+ case tkreisbogen:
+ case tellbogen:
+ ellpar(i,&xm,&ym,&lx,&ly,&cr,&sr);
+ ellw_xy(xm,ym,lx,ly,cr,sr,wanf[i],&xp1,&yp1);
+ ellw_xy(xm,ym,lx,ly,cr,sr,wanf[i]+50,&xp2,&yp2);
+ winpfeilaus(i,1L,xp1,yp1,xp2,yp2,zcolor);
+ ellw_xy(xm,ym,lx,ly,cr,sr,wend[i],&xp1,&yp1);
+ ellw_xy(xm,ym,lx,ly,cr,sr,wend[i]-50,&xp2,&yp2);
+ winpfeilaus(i,2L,xp1,yp1,xp2,yp2,zcolor);
+ break;
+ case tbezier:
+ winpfeilaus(i, 1L, x1[i],y1_[i],xb1[i],yb1[i],zcolor);
+ winpfeilaus(i, 2L, x2[i],y2[i],xb2[i],yb2[i],zcolor);
+ break;
+ }/*case*/
+}
+
+
+Static Void auspolyline(zcolor,elsel,anzp)
+ long zcolor,elsel,anzp;
+ /* Koordinaten 1..anzp in rpxarray und rpyarray*/
+ /* elsel fuer Liniendefinition */
+ /* falls elsel = 0 dann Standardattribute verwenden */
+{
+ long ldicke,lende,ltyp,lcolor,ix,iy,k;
+ double xx,yy;
+ XPoint points[maxpunkte];
+ for (k=0;k<anzp;k++) {
+ xx=rpxarray[k];
+ yy=rpyarray[k];
+ welt_to_bildschirm(xx,yy,&ix,&iy);
+ points[k].x = ix;
+ points[k].y = iy;
+ }
+ if (elsel==0){
+ setvalues(display,gczeichnung,zcolor,0L,0L,0L);
+ XDrawLines(display,win,gczeichnung,
+ points,anzp,CoordModeOrigin);}
+ else {
+ getlineattribute(elsel, typ[elsel], &ltyp, &ldicke, &lende, &lcolor);
+ setvalues(display,gczeichnung,zcolor,ltyp,ldicke,lende);
+ XDrawLines(display,win,gczeichnung,points,anzp,CoordModeOrigin);
+ winpfeile(elsel,zcolor);
+ }
+}
+
+Static double pgxyabstand();
+
+Static Void bezierpunkte(x1,y1,x2,y2,x3,y3,x4,y4,anzp)
+ double x1,y1,x2,y2,x3,y3,x4,y4;
+ long *anzp;
+{ double x12,y12,x23,y23,x34,y34,x1223,y1223,x2334,y2334;
+ double x12232334, y12232334;
+
+ x23 = (x2+x3)*0.5;
+ y23 = (y2+y3)*0.5;
+ /*liegen Punkte ungefaehr auf einer Geraden? */
+ if ( (pgxyabstand(x1, y1, x4, y4, x2, y2)< 3.0)&&
+ (pgxyabstand(x1, y1, x4, y4, x3, y3)< 3.0)) {
+ rpxarray[*anzp] = x1;
+ rpyarray[*anzp] = y1;
+ rpxarray[*anzp+1] = x23;
+ rpyarray[*anzp+1] = y23;
+ *anzp += 2;
+ if (*anzp >= maxpunkte-2)
+ fehler(4L);
+ return;
+ }
+ x12 = (x1+x2)*0.5;
+ y12 = (y1+y2)*0.5;
+ x34 = (x3+x4)*0.5;
+ y34 = (y3+y4)*0.5;
+ x1223 = (x12+x23)*0.5;
+ y1223 = (y12+y23)*0.5;
+ x2334 = (x23+x34)*0.5;
+ y2334 = (y23+y34)*0.5;
+ x12232334 = (x1223+x2334)*0.5;
+ y12232334 = (y1223+y2334)*0.5;
+ bezierpunkte(x1,y1,x12,y12,x1223,y1223,x12232334,y12232334,anzp);
+ bezierpunkte(x12232334,y12232334,x2334,y2334,x34,y34,x4,y4,anzp);
+}
+
+Static Void minmaxbezier(elsel,anzp)
+ long elsel, anzp;
+{ long i;
+
+ elxmin[elsel]=rpxarray[0];
+ elxmax[elsel]=rpxarray[0];
+ elymin[elsel]=rpyarray[0];
+ elymax[elsel]=rpyarray[0];
+
+ for (i=1;i<anzp;i++) {
+ if (rpxarray[i] < elxmin[elsel])
+ elxmin[elsel]=rpxarray[i];
+ if (rpyarray[i] < elymin[elsel])
+ elymin[elsel]=rpyarray[i];
+ if (rpxarray[i] > elxmax[elsel])
+ elxmax[elsel]=rpxarray[i];
+ if (rpyarray[i] > elymax[elsel])
+ elymax[elsel]=rpyarray[i];
+ }
+}
+
+
+Static Void ausbezier(elsel,zcolor)
+long elsel,zcolor;
+{
+ long anzp;
+
+ anzp = 0;
+ bezierpunkte(x1[elsel],y1_[elsel],xb1[elsel],yb1[elsel],
+ xb2[elsel],yb2[elsel],x2[elsel],y2[elsel],&anzp);
+ rpxarray[anzp] = x2[elsel];
+ rpyarray[anzp] = y2[elsel];
+ anzp++;
+ minmaxbezier(elsel,anzp);
+ auspolyline(zcolor,elsel,anzp);
+}
+
+
+Static Void ausbeziergef(elsel,zcolor)
+long elsel,zcolor;
+{
+ long anzp;
+
+ anzp = 0;
+ bezierpunkte(x1[elsel],y1_[elsel],xb1[elsel],yb1[elsel],
+ xb2[elsel],yb2[elsel],x2[elsel],y2[elsel],&anzp);
+ rpxarray[anzp] = x2[elsel];
+ rpyarray[anzp] = y2[elsel];
+ anzp++;
+ minmaxbezier(elsel,anzp);
+ ausfillpolygon(anzp, zcolor);
+}
+
+Static Void kaestchen(i, anteil, teilung, pos)
+long i, anteil, teilung, *pos;
+{
+ long zeile, platz;
+ double dx, dy;
+
+ if (*pos == 0)
+ *pos = 11;
+ zeile = (long)(*pos / 10.0);
+ platz = *pos - zeile * 10;
+ dx = (xem[0] - xam[0]) / teilung;
+ dy = si_fabs(yem[0] - yam[0]);
+ xam[i] = xam[0] + (platz - 1) * dx;
+ xem[i] = xam[i] + anteil * dx;
+ if (si_fabs(xem[i]-xem[0]) < 1.0) xem[i]=xem[0];
+ yem[i] = yem[0] - zeile * dy;
+ yam[i] = yam[0] - zeile * dy;
+ platz += anteil;
+ if (platz > teilung) {
+ zeile++;
+ platz = 1;
+ }
+ *pos = zeile * 10 + platz;
+}
+
+
+Static Void init_tmenue()
+{
+ long i;
+
+ for (i = 1; i <= zmenue; i++)
+ strcpy(pr2menue[i], blank);
+ for (i = 1; i <= zmenue; i++)
+ strcpy(pr3menue[i], blank);
+ strcpy(menue[mende], "quit");
+ strcpy(pr2menue[mende],intfiletext);
+ strcpy(pr3menue[mende],extfiletext);
+ radiogroup[mende] = 1;
+ strcpy(menue[mladen], "load");
+ strcpy(pr2menue[mladen],"input file:");
+ radiogroup[mladen] = 1;
+ strcpy(menue[msave], "save");
+ strcpy(pr2menue[msave],intfiletext);
+ strcpy(pr3menue[msave],extfiletext);
+ radiogroup[msave] = 1;
+ strcpy(menue[mtext], "text");
+ strcpy(pr2menue[mtext], " position?");
+ strcpy(pr3menue[mtext], "?:");
+ radiogroup[mtext] = 1;
+ strcpy(menue[mgerade], "line");
+ strcpy(pr2menue[mgerade], " point 1?");
+ strcpy(pr3menue[mgerade], " point 2?");
+ radiogroup[mgerade] = 1;
+ strcpy(menue[mkreis], "circle");
+ strcpy(pr2menue[mkreis], " center point?");
+ strcpy(pr3menue[mkreis], " point on circle?");
+ radiogroup[mkreis] = 1;
+ strcpy(menue[mell], "ellipse");
+ strcpy(pr2menue[mell], " center point?");
+ strcpy(pr3menue[mell], prxachse);
+ radiogroup[mell] = 1;
+ strcpy(menue[mrechteck], "rectangle");
+ strcpy(pr2menue[mrechteck], " corner 1?");
+ strcpy(pr3menue[mrechteck], " corner 2?");
+ radiogroup[mrechteck] = 1;
+ strcpy(menue[mdreieck], "triangle");
+ strcpy(pr2menue[mdreieck], " point 1?");
+ strcpy(pr3menue[mdreieck], " point 2?");
+ radiogroup[mdreieck] = 1;
+ strcpy(menue[mviereck], "quadrangle");
+ strcpy(pr2menue[mviereck], " point 1?");
+ strcpy(pr3menue[mviereck], " point 2?");
+ radiogroup[mviereck] = 1;
+ strcpy(menue[mbezier], "Bezier");
+ strcpy(pr2menue[mbezier], " starting point?");
+ strcpy(pr3menue[mbezier], " end point?");
+ radiogroup[mbezier] = 1;
+ strcpy(menue[mpolygon], "polygon");
+ strcpy(pr2menue[mpolygon], " center point?");
+ strcpy(pr3menue[mpolygon], " point on circle?");
+ radiogroup[mpolygon] = 1;
+ strcpy(menue[mspiegeln], "mirror");
+ strcpy(pr2menue[mspiegeln], " mirror line?");
+ strcpy(pr3menue[mspiegeln], " object(s)?");
+ radiogroup[mspiegeln] = 1;
+ strcpy(menue[mkopieren], "copy");
+ strcpy(pr2menue[mkopieren], " reference line?");
+ strcpy(pr3menue[mkopieren], " destination line?");
+ radiogroup[mkopieren] = 1;
+ strcpy(menue[mkopbewmaus], "m");
+ strcpy(pr2menue[mkopbewmaus], " reference point?");
+ strcpy(pr3menue[mkopbewmaus], " destination point?");
+ radiogroup[mkopbewmaus] = 0;
+ strcpy(menue[mbewegen], "move");
+ strcpy(pr2menue[mbewegen], " reference line?");
+ strcpy(pr3menue[mbewegen], " destination line?");
+ radiogroup[mbewegen] = 1;
+ strcpy(menue[mergaenzen], "complete");
+ strcpy(pr2menue[mergaenzen], " line 1?");
+ strcpy(pr3menue[mergaenzen], " line 2?");
+ radiogroup[mergaenzen] = 1;
+ strcpy(menue[mausdehnen], "extend");
+ strcpy(pr2menue[mausdehnen], " line/arc?");
+ radiogroup[mausdehnen] = 1;
+ strcpy(menue[mbrechen], "trim");
+ strcpy(pr2menue[mbrechen], " remove part?");
+ radiogroup[mbrechen] = 1;
+ strcpy(menue[mloeschen], "delete");
+ strcpy(pr2menue[mloeschen], " object(s)?");
+ radiogroup[mloeschen] = 1;
+ strcpy(menue[mup], "up");
+ strcpy(pr2menue[mup], "/reverse print order, object(s)?");
+ radiogroup[mup] = 1;
+ strcpy(menue[mdown], "down");
+ strcpy(pr2menue[mdown], "/put in background, object(s) ?");
+ radiogroup[mdown] = 1;
+ strcpy(menue[meinrasten], "snap");
+ radiogroup[meinrasten] = 0;
+ strcpy(menue[mgefuellt], "*");
+ radiogroup[mgefuellt] = 0;
+ strcpy(menue[mbogen], "C");
+ radiogroup[mbogen] = 0;
+ strcpy(menue[mparallel], "||");
+ strcpy(pr2menue[mparallel], " direction of end point?");
+ strcpy(pr3menue[mparallel], " parallel line?");
+ radiogroup[mparallel] = 2;
+ strcpy(menue[mlot], "-|");
+ strcpy(pr3menue[mlot], " line for normal?");
+ radiogroup[mlot] = 2;
+ strcpy(menue[mmittelpunkt], "mp");
+ strcpy(pr2menue[mmittelpunkt], " (mp for center of object)");
+ radiogroup[mmittelpunkt] = 0;
+ strcpy(menue[mpfeilanf], "b>");
+ radiogroup[mpfeilanf] = 0;
+ strcpy(menue[mpfeilende], "e>");
+ radiogroup[mpfeilende] = 0;
+ strcpy(menue[mdick], "==");
+ radiogroup[mdick] = 0;
+ strcpy(menue[mgestrichelt], " _");
+ radiogroup[mgestrichelt] = 0;
+ strcpy(menue[mgepunktet], " .");
+ radiogroup[mgepunktet] = 0;
+ strcpy(menue[mlschieben], "<");
+ strcpy(pr2menue[mlschieben], " picture moves left");
+ radiogroup[mlschieben] = 0;
+ strcpy(menue[moschieben], "^");
+ strcpy(pr2menue[moschieben], " picture moves up");
+ radiogroup[moschieben] = 0;
+ strcpy(menue[muschieben], "v");
+ strcpy(pr2menue[muschieben], " picture moves down");
+ radiogroup[muschieben] = 0;
+ strcpy(menue[mrschieben], ">");
+ strcpy(pr2menue[mrschieben], " picture moves right");
+ radiogroup[mrschieben] = 0;
+ strcpy(menue[mredraw], "[]");
+ strcpy(pr2menue[mredraw], " redraw");
+ radiogroup[mredraw] = 0;
+ strcpy(menue[mgitter], "G");
+ strcpy(pr2menue[mgitter], " grid origin?");
+ radiogroup[mgitter] = 1;
+ strcpy(menue[mcenter], "o");
+ strcpy(pr2menue[mcenter], " picture to center");
+ radiogroup[mcenter] = 0;
+ strcpy(menue[mgross], "+");
+ strcpy(pr2menue[mgross], " zooming in");
+ radiogroup[mgross] = 0;
+ strcpy(menue[mklein], "-");
+ strcpy(pr2menue[mklein], " zooming out");
+ radiogroup[mklein] = 0;
+ strcpy(menue[mxytastatur], " xy");
+ strcpy(pr2menue[mxytastatur],
+ " key input of point in grid coordinates:");
+ radiogroup[mxytastatur] = 0;
+ strcpy(menue[mltext], "l");
+ radiogroup[mltext] = 4;
+ strcpy(menue[mrtext], "r");
+ radiogroup[mrtext] = 4;
+ strcpy(menue[mbtext], "b");
+ radiogroup[mbtext] = 5;
+ strcpy(menue[mttext], "t");
+ radiogroup[mttext] = 5;
+ strcpy(menue[mfont], nullstr);
+ radiogroup[mfont] = 0;
+ strcpy(menue[mcut], "cut");
+ strcpy(pr2menue[mcut]," reference point?");
+ radiogroup[mcut] = 1;
+ strcpy(menue[mpaste], "paste");
+ strcpy(pr2menue[mpaste]," destination point?");
+ radiogroup[mpaste] = 1;
+ strcpy(menue[mcolor], "color");
+ radiogroup[mcolor] = 0;
+ strcpy(menue[mchangelineattr], "chatt");
+ strcpy(pr2menue[mchangelineattr], " set attributes to change (= _ . b> e> |] font color l r b t) then select object(s)?");
+ radiogroup[mchangelineattr] = 1;
+ strcpy(menue[mdegrees], "deg");
+ strcpy(pr2menue[mdegrees], " input angle in degrees:");
+ radiogroup[mdegrees] = 0;
+ strcpy(menue[mfill], "fill");
+ strcpy(pr2menue[mfill], " circle, ellipse, arc or first line (to define triangle or quadrangle)?");
+ strcpy(pr3menue[mfill], " second line (to define triangle or quadrangle)?");
+ radiogroup[mfill] = 1;
+ strcpy(menue[mgroupmode], "groupmode");
+ radiogroup[mgroupmode] = 0;
+ strcpy(menue[mnewgroup], "newgroup");
+ strcpy(pr2menue[mnewgroup], " first(next) group to combine defined by object(s)?");
+ radiogroup[mnewgroup] = 1;
+ strcpy(menue[mungroup], "ungroup");
+ strcpy(pr2menue[mungroup], " group defined by object?, OK to ungroup");
+ radiogroup[mungroup] = 1;
+ strcpy(menue[mshowgroup], "showgroup");
+ strcpy(pr2menue[mshowgroup], " group defined by object?");
+ radiogroup[mshowgroup] = 1;
+ strcpy(menue[mgroupok], "OK");
+ strcpy(pr2menue[mgroupok], " group ok");
+ radiogroup[mgroupok] = 0;
+
+ strcpy(menue[mconnect], "connect");
+ strcpy(pr2menue[mconnect], " (not all object types allowed) object1?");
+ strcpy(pr3menue[mconnect], " (not all object types allowed) object2 or point?");
+ radiogroup[mconnect] = 1;
+ strcpy(menue[mconnxy], "X");
+ radiogroup[mconnxy] = 6;
+ strcpy(menue[mconnyx], "Y");
+ radiogroup[mconnyx] = 6;
+ strcpy(menue[mconnpoint], "p");
+ strcpy(menue[mqueryattr], "attr?");
+ strcpy(pr2menue[mqueryattr], " (color, font, linewidth) object?");
+ radiogroup[mqueryattr] = 1;
+ radiogroup[mconnpoint] = 0;
+ strcpy(menue[mrot], "rotate");
+ strcpy(pr2menue[mrot], " degrees, object(s)?");
+ strcpy(pr3menue[mrot], " degrees, pivot point?");
+ radiogroup[mrot] = 1;
+ strcpy(menue[mcapprojecting], "|]");
+ radiogroup[mcapprojecting] = 0;
+ strcpy(menue[mwinkelrot], "");
+ radiogroup[mwinkelrot] = 0;
+ strcpy(menue[mread], "stdin");
+ strcpy(pr2menue[mread]," ");
+ radiogroup[mread] = 1;
+ strcpy(menue[mreadzeit], "");
+ radiogroup[mreadzeit] = 0;
+/* maximale Nr. bei radiogroup ist 6 */
+/* 1 fuer normale Menueeintraege */
+/* 0 fuer Voreinstellungen */
+}
+
+Static Void init_kmenue()
+{
+ long pos,i; double dy;
+
+ xam[0] = xgrf+1.0*wzeichenbreite;
+ xem[0] = xam[0]+kaestchenbreite;
+ yam[0] = yzmax - 0.5*kaestchenhoehe;
+ yem[0] = yam[0]+ kaestchenhoehe;
+ /* Reihenfolge des Aufrufs gibt Reihenfolge der Anordnung */
+ /* 2. und 3. Parameter bei kaestchen: anteil, teilung */
+ pos = 0;
+ kaestchen((long)mtext, 1L, 2L, &pos);
+ kaestchen((long)mfont, 1L, 2L, &pos);
+ kaestchen((long)mgerade, 1L, 2L, &pos);
+ kaestchen((long)mkreis, 1L, 2L, &pos);
+ kaestchen((long)mell, 1L, 1L, &pos);
+ kaestchen((long)mrechteck, 1L, 1L, &pos);
+ kaestchen((long)mdreieck, 1L, 1L, &pos);
+ kaestchen((long)mviereck, 1L, 1L, &pos);
+ kaestchen((long)mbezier, 1L, 1L, &pos);
+ kaestchen((long)mpolygon, 1L, 1L, &pos);
+ kaestchen((long)mconnect, 5L, 8L, &pos);
+ kaestchen((long)mconnpoint, 1L, 8L, &pos);
+ kaestchen((long)mconnxy, 1L, 8L, &pos);
+ kaestchen((long)mconnyx, 1L, 8L, &pos);
+ kaestchen((long)mspiegeln, 1L, 2L, &pos);
+ kaestchen((long)mqueryattr, 1L, 2L, &pos);
+ kaestchen((long)mrot, 2L, 3L, &pos);
+ kaestchen((long)mwinkelrot, 1L, 3L, &pos);
+ kaestchen((long)mkopbewmaus, 1L, 8L, &pos);
+ kaestchen((long)mkopieren, 3L, 8L, &pos);
+ kaestchen((long)mbewegen, 4L, 8L, &pos);
+ kaestchen((long)mergaenzen, 1L, 1L, &pos);
+ kaestchen((long)mausdehnen, 1L, 2L, &pos);
+ kaestchen((long)mbrechen, 1L, 2L, &pos);
+ kaestchen((long)mloeschen, 1L, 2L, &pos);
+ kaestchen((long)mfill, 1L, 2L, &pos);
+ kaestchen((long)mup, 1L, 2L, &pos);
+ kaestchen((long)mdown, 1L, 2L, &pos);
+ kaestchen((long)mcut, 1L, 2L, &pos);
+ kaestchen((long)mpaste, 1L, 2L, &pos);
+ kaestchen((long)mltext, 1L, 4L, &pos);
+ kaestchen((long)mrtext, 1L, 4L, &pos);
+ kaestchen((long)mbtext, 1L, 4L, &pos);
+ kaestchen((long)mttext, 1L, 4L, &pos);
+ kaestchen((long)mgefuellt, 1L, 4L, &pos);
+ kaestchen((long)mbogen, 1L, 4L, &pos);
+ kaestchen((long)mparallel, 1L, 4L, &pos);
+ kaestchen((long)mlot, 1L, 4L, &pos);
+ kaestchen((long)mmittelpunkt, 1L, 4L, &pos);
+ kaestchen((long)mpfeilanf, 1L, 4L, &pos);
+ kaestchen((long)mpfeilende, 1L, 4L, &pos);
+ kaestchen((long)mcapprojecting, 1L, 4L, &pos);
+ kaestchen((long)mdick, 1L, 3L, &pos);
+ kaestchen((long)mgestrichelt, 1L, 3L, &pos);
+ kaestchen((long)mgepunktet, 1L, 3L, &pos);
+ kaestchen((long)mgroupmode, 1L, 1L, &pos);
+ kaestchen((long)mnewgroup, 1L, 1L, &pos);
+ kaestchen((long)mungroup, 3L, 4L, &pos);
+ kaestchen((long)mgroupok, 1L, 4L, &pos);
+ kaestchen((long)mshowgroup, 1L, 1L, &pos);
+ kaestchen((long)mlschieben, 1L, 5L, &pos);
+ kaestchen((long)moschieben, 1L, 5L, &pos);
+ kaestchen((long)mredraw, 1L, 5L, &pos);
+ kaestchen((long)muschieben, 1L, 5L, &pos);
+ kaestchen((long)mrschieben, 1L, 5L, &pos);
+ kaestchen((long)mgitter, 1L, 4L, &pos);
+ kaestchen((long)mcenter, 1L, 4L, &pos);
+ kaestchen((long)mgross, 1L, 4L, &pos);
+ kaestchen((long)mklein, 1L, 4L, &pos);
+ kaestchen((long)meinrasten, 1L, 3L, &pos);
+ kaestchen((long)mxytastatur, 1L, 3L, &pos);
+ kaestchen((long)mdegrees, 1L,3L, &pos);
+ kaestchen((long)mcolor, 1L, 1L, &pos);
+ kaestchen((long)mread, 1L, 2L, &pos);
+ kaestchen((long)mreadzeit, 1L, 2L, &pos);
+ kaestchen((long)mchangelineattr, 1L,2L, &pos);
+ kaestchen((long)mladen, 1L, 2L, &pos);
+ kaestchen((long)msave, 1L, 2L, &pos);
+ kaestchen((long)mende, 1L, 2L, &pos);
+
+ dy=yprompt+1.5*wzeichenhoehe-yam[mende];
+ for (i=1;i<=zmenue;i++) {yam[i] += dy; yem[i] += dy;}
+}
+
+Static Void ausmenue()
+/* Ausdruck des Menues */
+{
+ long i;
+ for (i = 1; i <= zmenue; i++)
+ ausmenueelement(i);
+ aussomenue();
+}
+
+Static Void mstrnstr(x, y, mstr, nstr)
+double x, y;
+long *mstr, *nstr;
+{
+ double dx, dy, f;
+
+ dx = x - gridx0;
+ dy = y - gridy0;
+ f = 1 / ((gridwx1 * gridwy2 - gridwx2 * gridwy1) * gridw);
+ *mstr = (long)floor((dx * gridwy2 - dy * gridwx2) * f + 0.5);
+ *nstr = (long)floor((dy * gridwx1 - dx * gridwy1) * f + 0.5);
+}
+
+
+Static Void gridsnap(x, y)
+double *x, *y;
+{
+ long mstrich, nstrich;
+ double xx,yy;
+ mstrnstr(*x, *y, &mstrich, &nstrich);
+ gridpunkt((double)mstrich, (double)nstrich, &xx, &yy);
+ *x=xx;
+ *y=yy;
+}
+
+
+Static Void naehe(x1, y1, x2, y2, xmin, ymin, min)
+double x1, y1, x2, y2, *xmin, *ymin, *min;
+{
+ double d, dx, dy;
+
+ dx = si_fabs(x2 - x1);
+ if (dx >= *min)
+ return;
+ dy = si_fabs(y2 - y1);
+ if (dy >= *min)
+ return;
+ d = ppabstand(x1, y1, x2, y2);
+ if (d >= *min)
+ return;
+ *min = d;
+ *xmin = x1;
+ *ymin = y1;
+}
+
+
+Static Void elsnap(x, y)
+double *x, *y;
+{
+ long i;
+ double xg, yg, xmin, ymin, min;
+ Static boolean relevant();
+
+ min = 5.0;
+ xmin = *x;
+ ymin = *y;
+ xg = *x;
+ yg = *y;
+ gridsnap(&xg, &yg);
+ naehe(xg, yg, *x, *y, &xmin, &ymin, &min);
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] > 0) {
+ if (relevant(i, *x, *y)==true) {
+ naehe(x1[i], y1_[i], *x, *y, &xmin, &ymin, &min);
+ switch (typ[i]) {
+
+ case tgerade: /*Gerade*/
+ naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min);
+ break;
+
+ case trechteckgef:
+ case tviereckgef:
+ naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min);
+ naehe(xb1[i], yb1[i], *x, *y, &xmin, &ymin, &min);
+ naehe(xb2[i], yb2[i], *x, *y, &xmin, &ymin, &min);
+ break;
+
+ case tdreieckgef:
+ naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min);
+ naehe(xb1[i], yb1[i], *x, *y, &xmin, &ymin, &min);
+ break;
+
+ case tkreisbogen:
+ case tellbogen: /*Bogen*/
+ case tkreissektorgef:
+ case tellsektorgef:
+ naehe(xb1[i], yb1[i], *x, *y, &xmin, &ymin, &min);
+ naehe(xb2[i], yb2[i], *x, *y, &xmin, &ymin, &min);
+ break;
+
+ case tbezier: /*Bezier*/
+ case tbeziergef:
+ naehe(x2[i], y2[i], *x, *y, &xmin, &ymin, &min);
+ break;
+ }/*case*/
+ }/*if relevant */
+ } /*if,for*/
+ }
+ *x = xmin;
+ *y = ymin;
+}
+
+Static Void marklinie(ix,iy,idx,idy,zcolor)
+ long zcolor,ix,iy,idx,idy;
+{
+ setvalues(display,gczeichnung,zcolor,0L,0L,0L);
+ XDrawLine(display,win,gczeichnung,ix-idx,iy-idy,ix+idx,iy+idy);
+}
+
+
+Static Void ausmarken(anzp, mtyp, mhoehe, zcolor)
+long anzp, mtyp, zcolor;
+double mhoehe;
+/* Koordinaten in rpxarray,rpyarray */
+{
+ long i,ix,iy,imhoehe;
+ double xx,yy;
+ XPoint points[maxpunkte],tpoints[10];
+ imhoehe = siintround(mhoehe);
+ if (anzp==0) return;
+ for (i=0;i<anzp;i++){
+ xx=rpxarray[i];
+ yy=rpyarray[i];
+ welt_to_bildschirm(xx,yy,&ix,&iy);
+ points[i].x=ix;
+ points[i].y=iy;
+ }
+ if (mtyp==1) {/* Punkte */
+ setvalues(display,gczeichnung,zcolor,0L,0L,0L);
+ XDrawPoints(display,win,gczeichnung,points,anzp,CoordModeOrigin);
+ return;
+ }
+ for (i=0;i<anzp;i++){/*Jede Marke einzeln zeichnen*/
+ xx=rpxarray[i];
+ yy=rpyarray[i];
+ ix=points[i].x;
+ iy=points[i].y;
+ switch (mtyp)
+ {
+ case 2: /*fuer click (45 Grad Kreuz liegend)*/
+ marklinie(ix,iy,imhoehe,imhoehe,zcolor);
+ marklinie(ix,iy,-imhoehe,imhoehe,zcolor);
+ break;
+ case 3: /*fuer Mittelpunkt Zeichnung (Stern)*/
+ marklinie(ix,iy,imhoehe,imhoehe,zcolor);
+ marklinie(ix,iy,-imhoehe,imhoehe,zcolor);
+ marklinie(ix,iy,0,imhoehe,zcolor);
+ marklinie(ix,iy,imhoehe,0,zcolor);
+ break;
+ case 4: /*fuer Textposition (Dreieck) */
+ tpoints[0].x=ix;
+ tpoints[0].y=iy;
+ tpoints[3].x=ix;
+ tpoints[3].y=iy;
+ welt_to_bildschirm(xx + .3*mhoehe,yy-mhoehe,&ix,&iy);
+ tpoints[1].x=ix;
+ tpoints[1].y=iy;
+ welt_to_bildschirm(xx - .3*mhoehe,yy-mhoehe,&ix,&iy);
+ tpoints[2].x=ix;
+ tpoints[2].y=iy;
+ setvalues(display,gczeichnung,zcolor,0L,0L,0L);
+ XDrawLines(display,win,gczeichnung,tpoints,4,CoordModeOrigin);
+ break;
+ }/* switch */
+ }
+}/*ausmarken*/
+
+
+Static Void einemarkeaus(x,y,mtyp,mhoehe,zcolor)
+ double x,y, mhoehe;
+ long mtyp,zcolor;
+{
+ rpxarray[0]=x;
+ rpyarray[0]=y;
+ ausmarken(1L,mtyp,mhoehe,zcolor);
+}
+
+
+Static Void setzetextmarke(x, y, zcolor)
+double x, y;
+long zcolor;
+{
+ long typmarke,i;
+ double hoehemarke;
+ typmarke = 4;
+ hoehemarke = wzeichenbreite;
+ einemarkeaus(x,y, typmarke, hoehemarke,zcolor);
+}
+
+Static Void setzeclickmarke(x, y, zcolor)
+double x, y;
+long zcolor;
+{
+ long typmarke,i;
+ double hoehemarke;
+ typmarke = 2;
+ hoehemarke = 6.0;
+ einemarkeaus(x,y, typmarke, hoehemarke,zcolor);
+}
+
+
+Static Void ausalleclickmarken()
+/* Markierung der Click-Punkte */
+{
+ long i;
+
+ for (i = 1; i <= 4; i++) {
+ if (bmarker[i]==true)
+ setzeclickmarke(xmarker[i], ymarker[i],schwarz);
+ }
+}
+
+
+Static Void neueclickmarke(x, y)
+double x, y;
+{
+ long i;
+
+ if (bmarker[1]==true)
+ setzeclickmarke(xmarker[1], ymarker[1],weiss);
+ for (i = 1; i <= 3; i++) {
+ xmarker[i] = xmarker[i + 1];
+ ymarker[i] = ymarker[i + 1];
+ bmarker[i] = bmarker[i + 1];
+ }
+ bmarker[4] = true;
+ xmarker[4] = x;
+ ymarker[4] = y;
+ setzeclickmarke(x, y, schwarz);
+}
+
+
+Static Void ijminmax(x, y, imin, imax, jmin, jmax)
+double x, y;
+long *imin, *imax, *jmin, *jmax;
+{
+ long i,j;
+
+ mstrnstr(x, y, &i, &j);
+ if (i < *imin)
+ *imin = i;
+ if (i > *imax)
+ *imax = i;
+ if (j < *jmin)
+ *jmin = j;
+ if (j > *jmax)
+ *jmax = j;
+}
+
+
+Static Void ausgrid(zcolor)
+long zcolor;
+{
+ long i, j, imin, jmin, imax, jmax, nn;
+ double x, y, hoehemarke;
+ nn = 0;
+ hoehemarke = 2.0;
+ einemarkeaus(gridx0, gridy0, 3L,hoehemarke, zcolor);
+ /*fuer Zentrum */
+ mstrnstr(xgr, yprompt, &i, &j);
+ imin = i;
+ imax = i;
+ jmin = j;
+ jmax = j;
+ ijminmax(xgr, yzmax, &imin, &imax, &jmin, &jmax);
+ ijminmax(xzmax, yprompt, &imin, &imax, &jmin, &jmax);
+ ijminmax(xzmax, yzmax, &imin, &imax, &jmin, &jmax);
+ hoehemarke = 1.0;
+ for (j = jmin; j <= jmax; j++) {
+ for (i = imin; i <= imax; i++) {
+ gridpunkt((double)i, (double)j, &x, &y);
+ rpxarray[nn]=x;
+ rpyarray[nn]=y;
+ nn++;
+ if (nn >= maxpunkte) {
+ ausmarken(nn,1L,hoehemarke,zcolor);
+ nn = 0;
+ }
+ }
+ }
+ if (nn > 0)
+ ausmarken(nn,1L,hoehemarke,zcolor);
+} /*ausgrid*/
+
+
+
+Static Void elskalieren(gridw, dxx, dyy, f)
+double *gridw, dxx, dyy, f;
+{
+ long i;
+ double dx, dy;
+
+ if (f != 1.0) {
+ *gridw = f * *gridw;
+ while (*gridw > 1.5 * gridw0)
+ *gridw /= 2.0;
+ while (*gridw < 0.6 * gridw0)
+ *gridw = 2.0 * *gridw;
+ }
+ i = (long)floor(dxx / *gridw + 0.5);
+ dx = i * *gridw;
+ i = (long)floor(dyy / *gridw + 0.5);
+ dy = i * *gridw;
+
+ /* fuer readstdin vermerken, welche Skalierungen durchgef"uhrt wurden */
+ readdxx = readdxx*f +dx;
+ readdyy = readdyy*f +dy;
+ readf = readf*f;
+
+ /* jetzt eigentliche Skalierung */
+
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] != 0)
+ skalieren(i, dx, dy, f);
+ }
+ for (i = 1; i <= 4; i++) {
+ if (bmarker[i]==true)
+ pskalieren(&xmarker[i], &ymarker[i], dx, dy, f);
+ }
+ pskalieren(&xlast, &ylast, dx, dy, f);
+ pskalieren(&gridx0, &gridy0, dx, dy, f);
+}
+
+
+Static Void minmax(xmin, xmax, ymin, ymax)
+double *xmin, *xmax, *ymin, *ymax;
+{
+ long i;
+ boolean erstes;
+
+ *xmax = 0.0;
+ *ymax = 0.0;
+ *xmin = 0.0;
+ *ymin = 0.0;
+ erstes = true;
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] > 0) { /*i*/
+ if (erstes==true) {
+ *xmax = elxmax[i];
+ *ymax = elymax[i];
+ *xmin = elxmin[i];
+ *ymin = elymin[i];
+ erstes = false;
+ }
+ if (elxmax[i] > *xmax) *xmax = elxmax[i];
+ if (elymax[i] > *ymax) *ymax = elymax[i];
+ if (elxmin[i] < *xmin) *xmin = elxmin[i];
+ if (elymin[i] < *ymin) *ymin = elymin[i];
+ }
+ }
+}
+
+Static boolean inwinkel(elsel, w)
+long elsel;
+double w;
+{
+ boolean erg;
+ double wa, we;
+
+ erg = false;
+ wa = wanf[elsel];
+ we = wend[elsel];
+ if (si_fabs(wa - w) < 5.0)
+ erg = true;
+ if (si_fabs(we - w) < 5.0)
+ erg = true;
+ if (we > wa) {
+ if (w >= wa && w <= we)
+ erg = true;
+ }
+ if (we <= wa) {
+ if (w <= we || w >= wa)
+ erg = true;
+ }
+ return erg;
+}
+
+Static Void initgrenzen(xp,yp,xxmax,xxmin,yymax,yymin)
+ double xp,yp,*xxmax,*xxmin,*yymax,*yymin;
+{
+ *xxmax = xp;
+ *xxmin = xp;
+ *yymax = yp;
+ *yymin = yp;
+}
+
+Void grenzen(xp,yp,xxmax,xxmin,yymax,yymin)
+ double xp, yp, *xxmax,*xxmin,*yymax,*yymin;
+{
+ if (xp > *xxmax) *xxmax = xp;
+ if (xp < *xxmin) *xxmin = xp;
+ if (yp > *yymax) *yymax = yp;
+ if (yp < *yymin) *yymin = yp;
+}
+
+Static Void ellgrenzpunkte(i,xxmax,xxmin,yymax,yymin)
+ long i;
+ double *xxmax,*xxmin,*yymax,*yymin;
+{
+ double xm,ym,lx,ly,cr,sr;
+ double xg1,yg1,w1,xg2,yg2,w2,xg3,yg3,w3,xg4,yg4,w4;
+ double h1,h2,h3,h4,h5;
+
+ ellpar(i,&xm,&ym,&lx,&ly,&cr,&sr);
+ h1 = lx*lx*cr*cr+ly*ly*sr*sr;
+ h2 = ly*ly*cr*cr+lx*lx*sr*sr;
+ h3 = cr*sr*(lx*lx-ly*ly);
+ h4 = sqrt(h1);
+ h5 = sqrt(h2);
+ xg1 = xm + h4;
+ xg2 = xm - h4;
+ yg1 = ym + h4*h3/h1;
+ yg2 = ym - h4*h3/h1;
+ w1 = winkelell(xm, ym, lx, ly, cr, sr, xg1, yg1);
+ w2 = winkelell(xm, ym, lx, ly, cr, sr, xg2, yg2);
+ yg3 = ym + h5;
+ yg4 = ym - h5;
+ xg3 = xm + h5*h3/h2;
+ xg4 = xm - h5*h3/h2;
+ w3 = winkelell(xm, ym, lx, ly, cr, sr, xg3, yg3);
+ w4 = winkelell(xm, ym, lx, ly, cr, sr, xg4, yg4);
+ if (inwinkel(i,w1)==true) grenzen(xg1,yg1,xxmax,xxmin,yymax,yymin);
+ if (inwinkel(i,w2)==true) grenzen(xg2,yg2,xxmax,xxmin,yymax,yymin);
+ if (inwinkel(i,w3)==true) grenzen(xg3,yg3,xxmax,xxmin,yymax,yymin);
+ if (inwinkel(i,w4)==true) grenzen(xg4,yg4,xxmax,xxmin,yymax,yymin);
+}
+
+
+Static Void berechneminmax(i)
+ long i;
+{
+ double xxmin,yymin,xxmax,yymax;
+ double xm,ym,lx,ly,cr,sr;
+
+ if (typ[i] <= 0) return;
+ switch (typ[i]) {
+
+ case ttext:
+ initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb2[i], yb2[i],&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case tgerade:
+ initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(x2[i], y2[i],&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case trechteckgef:
+ case tviereckgef:
+ initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(x2[i], y2[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb2[i], yb2[i],&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case tdreieckgef:
+ initgrenzen(x1[i], y1_[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(x2[i], y2[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case tkreis:
+ case tkreisgef:
+ ellpar(i,&xm,&ym,&lx,&ly,&cr,&sr);
+ initgrenzen(xm+lx, ym+ly,&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xm-lx, ym-ly,&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case tell:
+ case tellgef:
+ initgrenzen(x1[i],y1_[i],&xxmax,&xxmin,&yymax,&yymin);
+ ellgrenzpunkte(i,&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case tkreisbogen:
+ case tellbogen:
+ initgrenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb2[i],yb2[i],&xxmax,&xxmin,&yymax,&yymin);
+ ellgrenzpunkte(i,&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case tellsektorgef:
+ case tkreissektorgef:
+ initgrenzen(x1[i],y1_[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb1[i], yb1[i],&xxmax,&xxmin,&yymax,&yymin);
+ grenzen(xb2[i],yb2[i],&xxmax,&xxmin,&yymax,&yymin);
+ ellgrenzpunkte(i,&xxmax,&xxmin,&yymax,&yymin);
+ break;
+
+ case tbezier:
+ case tbeziergef:
+ /* keine minmax-Berechnung, da diese ueber ausel() erfolgt */
+ return;
+ }/*case*/
+ elxmin[i]=xxmin;
+ elxmax[i]=xxmax;
+ elymin[i]=yymin;
+ elymax[i]=yymax;
+}
+
+Static Void ausfastalles()
+{
+ static void ausnurelemente();
+ XClearWindow(display,win);
+ if (erwartet==tastatur_erwartet)
+ textpositionieren();
+ prompt();
+ ausmenue();
+ ausnurelemente();
+}
+
+
+Static Void ausalles()
+{
+ static void auselemente();
+ XClearWindow(display,win);
+ if (erwartet==tastatur_erwartet)
+ textpositionieren();
+ prompt();
+ ausmenue();
+ auselemente();
+ ausalleclickmarken();
+ if (erwartet==tastatur_erwartet)
+ cursan(curs_x,curs_y);
+}
+
+
+Static Void verschieben(art)
+long art;
+{
+ double f, fminus, fplus, dxx, dyy, xmax, ymax, xmin, ymin;
+ Char s1[maxstrl+1], s2[maxstrl+1], s3[maxstrl+1],
+ s4[maxstrl+1], s5[maxstrl+1], s6[maxstrl+1];
+
+ fplus = 1.5;
+ fminus = 1.0 / fplus;
+ strcpy(s1, pr1);
+ strcpy(s2, pr2);
+ strcpy(s3, pr3);
+ strcpy(s4, pr4);
+ strcpy(s5, pr5);
+ strcpy(s6, pr6);
+ strcpy(pr1, pr2menue[art]);
+ strcpy(pr2, nullstr);
+ strcpy(pr3, nullstr);
+ strcpy(pr4, nullstr);
+ strcpy(pr5, nullstr);
+ strcpy(pr6, nullstr);
+
+ prompt();
+ f = 1.0;
+ dxx = (long)floor((xzmax - xgr) / 4.0 + 0.5);
+ dyy = (long)floor(yzmax / 4.0 + 0.5);
+ switch (art) {
+
+ case mlschieben:
+ dyy = 0.0;
+ dxx = -dxx;
+ break;
+
+ case mrschieben:
+ dyy = 0.0;
+ break;
+
+ case moschieben:
+ dxx = 0.0;
+ break;
+
+ case muschieben:
+ dxx = 0.0;
+ dyy = -dyy;
+ break;
+
+ case mgross:
+ dxx = 0.0;
+ dyy = 0.0;
+ f = fplus;
+ break;
+
+ case mklein:
+ dxx = 0.0;
+ dyy = 0.0;
+ f = fminus;
+ break;
+
+ case mcenter:
+ minmax(&xmin, &xmax, &ymin, &ymax);
+ dxx = xmittelzei - (long)floor((xmax + xmin) * 0.5 + 0.5);
+ dyy = ymittelzei - (long)floor((ymax + ymin) * 0.5 + 0.5);
+ break;
+ }/*case*/
+ elskalieren(&gridw, dxx, dyy, f);
+ XClearWindow(display,win);
+ selmenue[art] = false;
+ strcpy(pr1, s1);
+ strcpy(pr2, s2);
+ strcpy(pr3, s3);
+ strcpy(pr4, s4);
+ strcpy(pr5, s5);
+ strcpy(pr6, s6);
+ ausalles();
+} /*schieben*/
+
+Static Void sondertaste (taste)
+long taste;
+{/* Behandlung von Tasten, die nicht bei */
+ /* erwarteter Texteingabe gedrueckt wurden */
+ if ((taste == tastecursleft1)||(taste == tastecursleft2))
+ verschieben((long)mlschieben);
+ if ((taste == tastecursright1)||(taste == tastecursright2))
+ verschieben((long)mrschieben);
+ if ((taste == tastecursup1)||(taste == tastecursup2))
+ verschieben((long)moschieben);
+ if ((taste == tastecursdown1)||(taste == tastecursdown2))
+ verschieben((long)muschieben);
+ if ((taste == tasteplus2)||(taste == tasteplus1))
+ verschieben((long)mgross);
+ if ((taste == tasteminus2)||(taste == tasteminus1))
+ verschieben((long)mklein);
+}
+
+Static Void control (taste, press)
+long taste, press;
+{
+ if ((taste == tastecontroll)||(taste == tastecontrolr))
+ controlan = press;
+}
+
+Static Void menueloc(x, y, i)
+double x, y;
+long *i;
+{
+ long j;
+
+ *i = 0;
+ for (j = 1; j <= zmenue; j++) {
+ if (x < xam[j])
+ goto _L1;
+ if (x > xem[j])
+ goto _L1;
+ if (y < yam[j])
+ goto _L1;
+ if (y > yem[j])
+ goto _L1;
+ *i = j;
+ goto _L2;
+_L1: ;
+ }
+ goto _L3;
+_L2:
+ if (*i==mredraw) {
+ *i=0;
+ ausalles();
+ return;
+ }
+ /* test ob Anklicken fuer changeattributs relevant */
+ if (*i==mpfeilanf) changelende = true;
+ if (*i==mpfeilende) changelende = true;
+ if (*i==mcapprojecting) changelende = true;
+ if (*i==mdick) changelwidth = true;
+ if (*i==mgestrichelt) changelstyle = true;
+ if (*i==mgepunktet) changelstyle = true;
+ if (*i==mfont) changefont = true;
+ if (*i==mcolor) changecolor = true;
+ if (*i==mltext) changeposition = true;
+ if (*i==mrtext) changeposition = true;
+ if (*i==mbtext) changeposition = true;
+ if (*i==mttext) changeposition = true;
+
+ if (!(radiogroup[*i] == 1 && selmenue[*i]==true)) {
+ if (selmenue[*i]==true) selmenue[*i] = false;
+ else selmenue[*i]=true;
+ ausmenueelement(*i);
+ }
+ if (radiogroup[*i] != 0 && selmenue[*i]==true) { /*if*/
+ for (j = 1; j <= zmenue; j++) {
+ if (*i != j && selmenue[j]==true && radiogroup[j] == radiogroup[*i]) {
+ selmenue[j] = false;
+ ausmenueelement(j);
+ }
+ } /*j*/
+ }
+_L3: ;
+}
+
+
+Static boolean gschnittpunkt(x1, y1, dx1, dy1, x2, y2, dx2, dy2, xs, ys)
+double x1, y1, dx1, dy1, x2, y2, dx2, dy2, *xs, *ys;
+{
+ boolean Result;
+ double xp, yp, m1, m2, dm, diffx12, diffy12;
+
+ /*Schnittpunkt zweier Geraden*/
+ Result = false;
+ diffx12 = x1 - x2;
+ diffy12 = y1 - y2;
+ xp = 0.0;
+ yp = 0.0;
+ if (dx1 == 0.0 && dx2 == 0.0) /*parallel*/
+ goto _L2;
+ if (dx1 == 0.0) {
+ xp = x1;
+ yp = dy2 / dx2 * diffx12 + y2;
+ goto _L1;
+ }
+ if (dx2 == 0.0) {
+ xp = x2;
+ yp = y1 - dy1 / dx1 * diffx12;
+ goto _L1;
+ }
+ if (dy1 == 0.0 && dy2 == 0.0) /*parallel*/
+ goto _L2;
+ if (dy1 == 0.0) {
+ xp = diffy12 * dx2 / dy2 + x2;
+ yp = y1;
+ goto _L1;
+ }
+ if (dy2 == 0.0) {
+ xp = x1 - diffy12 * dx1 / dy1;
+ yp = y2;
+ goto _L1;
+ }
+ m1 = dy1 / dx1;
+ m2 = dy2 / dx2;
+ if (si_fabs(m1 - m2) < 0.0001) /*parallel*/
+ goto _L2;
+ dm = m2 - m1;
+ dm = 1 / dm;
+ xp = diffy12 * dm + m2 * dm * x2 - m1 * dm * x1;
+ yp = m2 * dm * y1 - m1 * dm * m2 * diffx12 - m1 * dm * y2;
+_L1:
+ Result = true;
+_L2:
+ *xs = xp;
+ *ys = yp;
+ return Result;
+}
+
+
+Static boolean lot(x1, y1, dx1, dy1, xp, yp, xs, ys)
+double x1, y1, dx1, dy1, xp, yp, *xs, *ys;
+{
+ if (gschnittpunkt(x1, y1, dx1, dy1, xp, yp, -dy1, dx1, xs, ys)==true)
+ return true;
+ else
+ return false;
+}
+
+
+Static boolean inxystrecke(x1, y1, x2, y2, xs, ys)
+double x1, y1, x2, y2, xs, ys;
+{
+ double d, d1, d2;
+
+ d = ppabstand(x1, y1, x2, y2);
+ d1 = ppabstand(xs, ys, x1, y1);
+ d2 = ppabstand(xs, ys, x2, y2);
+ if ((d1 + d2) < (d + 3.0))
+ return true;
+ else
+ return false;
+}
+
+
+Static double pgxyabstand(x1, y1, x2, y2, xp, yp)
+double x1, y1, x2, y2, xp, yp;
+{
+ double xs,ys,d12,d1s,d2s,dmin;
+
+ dmin = initabstand;
+ lot(x1, y1, x2-x1, y2-y1, xp, yp, &xs, &ys);
+ d12=ppabstand(x1,y1,x2,y2);
+ d1s=ppabstand(x1,y1,xs,ys);
+ d2s=ppabstand(x2,y2,xs,ys);
+ if (inxystrecke(x1, y1, x2, y2, xs, ys)==true) {
+ /* Fusspunkt Lot ist etwa in Strecke */
+ /* nur dann wird Strecke als selektiert betrachtet! */
+ dmin = ppabstand(xp,yp,xs,ys);
+ }
+ return dmin;
+}
+
+Static double pgabstand(elsel, xp, yp)
+long elsel;
+double xp, yp;
+{ double dmin;
+
+ dmin = pgxyabstand(x1[elsel], y1_[elsel], x2[elsel], y2[elsel], xp, yp);
+ return dmin;
+}
+
+
+
+
+Static Void kopunvotext(elsel, i)
+long elsel, i;
+{
+ typ[i] = typ[elsel];
+ x1[i] = x1[elsel];
+ y1_[i] = y1_[elsel];
+ x2[i] = x2[elsel];
+ y2[i] = y2[elsel];
+ xb1[i] = xb1[elsel];
+ yb1[i] = yb1[elsel];
+ xb2[i] = xb2[elsel];
+ yb2[i] = yb2[elsel];
+ wanf[i] = wanf[elsel];
+ wend[i] = wend[elsel];
+ elxmin[i] =elxmin[elsel];
+ elxmax[i] =elxmax[elsel];
+ elymin[i] =elymin[elsel];
+ elymax[i] =elymax[elsel];
+ lineende[i] = lineende[elsel];
+ linedicke[i] = linedicke[elsel];
+ linetype[i] = linetype[elsel];
+ laenge1[i] = laenge1[elsel];
+ laenge2[i] = laenge2[elsel];
+ rotwi[i] = rotwi[elsel];
+ crw[i] = crw[elsel];
+ srw[i] = srw[elsel];
+ textno[i] = textno[elsel];
+ sequenz[i] = sequenz[elsel];
+ blink[i] = false; /* Beim Kopieren ist neues Element nicht */
+ /* selektiert !!!!! */
+ blinkalt[i] = false;
+ group[i] = group[elsel];
+}
+
+Static Void loescheelement(i)
+long i;
+{
+ if ((typ[i] == ttext) || (typ[i] == -ttext))
+ strcpy(texte[textno[i]],nullstr);
+ typ[i] = 0;
+}
+
+
+Static Void kompakt()
+{
+ /*belegte Elemente an Anfang der Liste*/
+ /*ohne Aenderung der Reihenfolge */
+ long i, delta;
+
+ delta=0;
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] <= 0) {
+ delta++;
+ loescheelement(i);
+ }
+ else {
+ if (delta != 0) {kopunvotext(i,i-delta); typ[i]=0;}
+ }
+ }
+ zelmax=zelmax-delta;
+}
+
+Static Void freieselement(k)
+long *k;
+{
+ long i;
+_L0:
+ if (zelmax==zel) fehler(1L);
+ zelmax++;
+ i = zelmax;
+ *k = i;
+ typ[i] = -1; /*vorlaeufig belegt*/
+ x1[i] = 0.0;
+ y1_[i] = 0.0;
+ x2[i] = 0.0;
+ y2[i] = 0.0;
+ xb1[i] = 0.0;
+ yb1[i] = 0.0;
+ xb2[i] = 0.0;
+ yb2[i] = 0.0;
+ wanf[i] = 0.0;
+ wend[i] = wg;
+ elxmin[i] = 0.0;
+ elxmax[i] = 0.0;
+ elymin[i] = 0.0;
+ elymax[i] = 0.0;
+ linedicke[i] = 1L;
+ lineende[i] = 0L;
+ linetype[i] = 1L;
+ laenge1[i] = 0.0;
+ laenge2[i] = 0.0;
+ rotwi[i] = 0.0;
+ crw[i] = 1.0;
+ srw[i] = 0.0;
+ textno[i] = 0;
+ sequenz[i] = 0;
+ blink[i] = false;
+ blinkalt[i] = false;
+ group[i] = 0;
+}
+
+Static Void freiestextel(k)
+long *k;
+{
+ long i;
+
+ for (i = 1; i <= zstr; i++) {
+ if (istnullstr(texte[i])==true)
+ goto _L1;
+ }
+ fehler(2L);
+_L1:
+ *k = i;
+}
+
+
+Static Void kopunv(elsel, i)
+long elsel, i;
+{ kopunvotext(elsel,i);
+ if (typ[i] != ttext)
+ return;
+ typ[i] = -ttext;
+ freiestextel(&textno[i]);
+ typ[i] = ttext;
+ strcpy(texte[textno[i]], texte[textno[elsel]]);
+}
+
+Static Void ausline(k,zcolor)
+ long k,zcolor;
+{
+ rpxarray[0]=x1[k];
+ rpyarray[0]=y1_[k];
+ rpxarray[1]=x2[k];
+ rpyarray[1]=y2[k];
+ auspolyline(zcolor,k,2L);
+}
+
+
+Static Void ausgefviereck(k,zcolor)
+long k,zcolor;
+{
+ rpxarray[0]=x1[k];
+ rpyarray[0]=y1_[k];
+ rpxarray[1]=xb1[k];
+ rpyarray[1]=yb1[k];
+ rpxarray[2]=x2[k];
+ rpyarray[2]=y2[k];
+ rpxarray[3]=xb2[k];
+ rpyarray[3]=yb2[k];
+ rpxarray[4]=x1[k];
+ rpyarray[4]=y1_[k];
+ ausfillpolygon(5L,zcolor);
+}
+
+Static Void ausgefdreieck(k,zcolor)
+long k,zcolor;
+{
+ rpxarray[0]=x1[k];
+ rpyarray[0]=y1_[k];
+ rpxarray[1]=x2[k];
+ rpyarray[1]=y2[k];
+ rpxarray[2]=xb1[k];
+ rpyarray[2]=yb1[k];
+ rpxarray[3]=x1[k];
+ rpyarray[3]=y1_[k];
+ ausfillpolygon(4L,zcolor);
+}
+
+Static Void austextline(k,zcolor)
+long k;
+{
+ long ix1,iy1,ix2,iy2;
+
+ welt_to_bildschirm(xb1[k], yb1[k], &ix1, &iy1);
+ welt_to_bildschirm(xb2[k], yb2[k], &ix2, &iy2);
+ setvalues(display,gczeichnung,zcolor,6L,0L,0L);
+ XDrawLine(display,win,gczeichnung,ix1,iy1,ix2,iy2);
+}
+
+
+Static Void bogenauspar(elsel,ltyp,ldicke,lende,lcolor,
+ ixa,iya,ilx,ily,iwa,idw)
+long elsel,*ltyp,*ldicke,*lcolor,*ixa,*iya,*ilx,*ily,*iwa,*idw;
+{
+ double xm,ym,lx,ly,cr,sr,wa,dw;
+ long ixm, iym;
+ ellpar(elsel, &xm, &ym, &lx, &ly, &cr, &sr);
+ getlineattribute(elsel, typ[elsel], ltyp, ldicke, lende, lcolor);
+ welt_to_bildschirm(xm-lx, ym+ly, ixa, iya);
+ *ilx = siintround(2.0*lx);
+ *ily = siintround(2.0*ly);
+ wa=wanf[elsel];
+ dw=wend[elsel]-wa;
+ if (dw<=0.0) dw += wg;
+ /* Winkel in Grad*64 */
+ *iwa=siintround(wa*6.4);
+ *idw=siintround(dw*6.4);
+}
+
+
+Static Void ausbogen(elsel,zcolor)
+ long elsel,zcolor;
+{
+ long ltyp,ldicke,lende,lcolor,ixa,iya,ilx,ily,iwa,idw;
+
+ bogenauspar(elsel,&ltyp,&ldicke,&lende,&lcolor,
+ &ixa,&iya,&ilx,&ily,&iwa,&idw);
+ setvalues(display,gczeichnung,zcolor,ltyp,ldicke,lende);
+ XDrawArc(display,win,gczeichnung,ixa,iya,ilx,ily,iwa,idw);
+ winpfeile(elsel,zcolor);
+}
+
+Static Void ausgefbogen(elsel,zcolor)
+ long elsel,zcolor;
+{
+ long ltyp,ldicke,lende,lcolor,ixa,iya,ilx,ily,iwa,idw;
+ bogenauspar(elsel,&ltyp,&ldicke,&lende,&lcolor,
+ &ixa,&iya,&ilx,&ily,&iwa,&idw);
+ setvalues(display,gczeichnung,zcolor,ltyp,ldicke,lende);
+ XFillArc(display,win,gczeichnung,ixa,iya,ilx,ily,iwa,idw);
+ winpfeile(elsel,zcolor);
+}
+
+Static Void ellipse2polygon(i,kerg)
+long i,*kerg;
+{
+ double umfang, lambda, lambdaq, xp, yp, dw, w,
+ xm, ym, lx, ly, lmax, cr, sr, wa, we;
+ long k, m;
+
+ ellpar(i, &xm, &ym, &lx, &ly, &cr, &sr);
+ lambda = (lx-ly)/(lx+ly);
+ lambdaq = lambda*lambda;
+ umfang = pi*(lx+ly)*(64.0-3.0*lambdaq*lambdaq)/(64.0-16*lambdaq);
+ m = umfang/10.0; /* ungefaehre Zahl der Strecken mit je 5 Pixel */
+ if (m < 10) m = 10;
+ if (m > maxpunkte) m = maxpunkte - 10;
+ if (m > 50) m = 50;
+ dw = wg/m;
+ wa = wanf[i];
+ we = wend[i];
+ w = wa;
+ if (we <= wa) we += wg;
+
+ k = 0;
+ while (w < we){
+ ellw_xy(xm, ym, lx, ly, cr, sr, w, &xp, &yp);
+ w += dw;
+ rpxarray[k]=xp;
+ rpyarray[k]=yp;
+ k++;
+ };
+ ellw_xy(xm, ym, lx, ly, cr, sr, we, &xp, &yp);
+ rpxarray[k]=xp;
+ rpyarray[k]=yp;
+ k++;
+ if (typ[i] == tellsektorgef) {
+ rpxarray[k]=xm;
+ rpyarray[k]=ym;
+ k++;
+ rpxarray[k]=rpxarray[0];
+ rpyarray[k]=rpyarray[0];
+ k++;
+ }
+ *kerg = k;
+}
+
+Static Void ausellgef(i,zcolor)
+long i,zcolor;
+{ long k;
+
+ ellipse2polygon(i,&k);
+ ausfillpolygon(k,zcolor);
+}
+
+Static Void ausellipse(i,zcolor)
+long i,zcolor;
+{ long k;
+
+ ellipse2polygon(i,&k);
+ auspolyline(zcolor,i,k);
+}
+
+Static Void ausel(i, painterase)
+long i, painterase;
+{ long fontart, zcolor;
+
+ zcolor = getzcolor(i, painterase);
+ /* zcolor ist Farbe der Zeichnung */
+ /* bestimmen aus Angabe color und Wert Farbe bei Element! */
+ switch (typ[i]) { /*case*/
+
+ case ttext:
+ if (rotwi[i] != 0.0) austextline(i,zcolor);
+ fontart=linetype[i];
+ if (i != texterase)
+ ztextaus(win, i, x2[i], y2[i], texte[textno[i]],zcolor,fontart);
+ setzetextmarke(x1[i], y1_[i], zcolor);
+ break;
+
+ case tgerade:
+ ausline(i,zcolor);
+ break;
+
+ case trechteckgef:
+ case tviereckgef:
+ ausgefviereck(i,zcolor);
+ break;
+
+ case tdreieckgef:
+ ausgefdreieck(i,zcolor);
+ break;
+
+ case tkreis:
+ ausbogen(i,zcolor);
+ break;
+
+ case tkreisgef:
+ case tkreissektorgef:
+ ausgefbogen(i,zcolor);
+ break;
+
+ case tkreisbogen:
+ ausbogen(i,zcolor);
+ break;
+
+ case tellgef:
+ case tellsektorgef:
+ ausellgef(i,zcolor);
+ break;
+
+ case tell:
+ case tellbogen:
+ ausellipse(i,zcolor);
+ break;
+
+ case tbezier:
+ ausbezier(i,zcolor);
+ break;
+
+ case tbeziergef:
+ ausbeziergef(i,zcolor);
+ break;
+ }
+}
+
+Static Void ltd_usleep(s, mu)
+long s, mu;
+{
+ st_delay.tv_usec = mu;
+ st_delay.tv_sec = s;
+ select(32, 0, 0, 0, &st_delay);
+}
+
+Static Void Flush_ltd_usleep(s, mu)
+long s, mu;
+{
+ XFlush(display);
+ /* ganz wichtig, damit vor sleep noch alles ausgegeben wird */
+ ltd_usleep(s, mu);
+}
+
+Static Void ausblinkelemente()
+{
+ long i,f;
+ f = 1;
+ if (tablett)
+ f = 10;
+ if (blinkintervallzaehler==0) {
+ /* blinkfarbe == paint oder erase ! */
+ if (blinkfarbe == erase) {
+ for (i = 1; i <= zelmax; i++)
+ if ((typ[i] > 0)&&(blink[i]==true)) ausel(i, erase);
+ for (i = 1; i <= zelmax; i++)
+ if ((typ[i] > 0)&&(blink[i]==false)) ausel(i, paint);
+ }
+ else
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] > 0) ausel(i, paint);
+ }
+ }
+ ausgrid(schwarz);
+ Flush_ltd_usleep(0L,(long)(100000/f));
+ /* 100/f ms Grund-Wartezeit bzw. Reaktionszeit */
+ if ((blinkfarbe==paint)&&(blinkintervallzaehler++ > 10*f)) {
+ blinkintervallzaehler = 0;
+ blinkfarbe=erase;
+ }
+ else {
+ if ((blinkfarbe==erase)&&(blinkintervallzaehler++ > 2*f)) {
+ blinkintervallzaehler = 0;
+ blinkfarbe=paint;
+ }
+ }
+}
+
+Static Void ausnurelemente()
+{
+ long i;
+
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] > 0)
+ ausel(i, paint);
+ } /* end for */
+ zeichnen = false;
+}
+
+Static Void auselemente()
+{
+ ausnurelemente();
+ ausalleclickmarken();
+ ausgrid(schwarz);
+}
+
+Static Void blinkenaus()
+{
+ blinkend = false;
+ auselemente();
+}
+
+Static Void blinkenan()
+{ long i;
+
+ for (i = 1; i <= zelmax; i++) {
+ blinkalt[i] = blink[i];
+ blink[i] = false;
+ }
+ if (blinkend==true)
+ blinkenaus();
+ blinkfarbe = erase;
+ blinkend = true;
+ blinkintervallzaehler = 0;
+}
+Static boolean duplikat();
+
+Static long interncreateline(elselalt, xx1, yy1, xx2, yy2)
+long elselalt;
+double xx1, yy1, xx2, yy2;
+{
+ double d;
+ long elsel, ldicke, ltyp, lende;
+
+ if (elselalt == 0) {
+ d = ppabstand(xx1, yy1, xx2, yy2);
+ if (d < dminein)
+ return 0;
+ }
+ freieselement(&elsel);
+ typ[elsel] = tgerade;
+ x1[elsel] = xx1;
+ y1_[elsel] = yy1;
+ x2[elsel] = xx2;
+ y2[elsel] = yy2;
+ setlineattribute(elselalt, elsel);
+ berechneminmax(elsel);
+ return elsel;
+}
+
+Static Void createline(elselalt, xx1, yy1, xx2, yy2)
+long elselalt;
+double xx1, yy1, xx2, yy2;
+{
+ long elsel;
+
+ elsel = interncreateline(elselalt, xx1, yy1, xx2, yy2);
+ if (elsel != 0)
+ ausel(elsel, paint);
+}
+
+Static long einbezier(x,y,taste,msel,phase)
+long *msel,phase,taste;
+double x,y;
+{
+ static long elsel;
+ long elselalt, ltyp, ldicke, lende;
+ static boolean fortsetzung;
+ double d1,d2;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ case 4: goto L4;
+ }
+ L0:
+ fortsetzung = false;
+ return 1;
+ L1:
+ freieselement(&elsel);
+ x1[elsel] = x;
+ y1_[elsel] = y;
+ strcpy(pr4, " end point of tangent to starting point?");
+ return 2;
+ L2:
+ xb1[elsel] = x;
+ yb1[elsel] = y;
+ if (si_fabs(x - x1[elsel]) < 3.0 && si_fabs(y - y1_[elsel]) < 3.0)
+ return 2;
+ strcpy(pr4, " first point of tangent to end point?");
+ return 3;
+ L3:
+ xb2[elsel] = x;
+ yb2[elsel] = y;
+ if (fortsetzung == true) {
+ /* Steigung bei Anfangspunkt beibehalten, aber die Entfernung zum */
+ /* Punkt 2 auf halben Abstand Punkt3 von Anfangspunkt setzen */
+ d1 = ppabstand(x1[elsel],y1_[elsel], xb1[elsel],yb1[elsel]);
+ d2 = ppabstand(x1[elsel],y1_[elsel], x,y);
+ if (d2==0.0)
+ d2=4.0;
+ xb1[elsel] = x1[elsel] + d2/d1*0.4*(xb1[elsel]-x1[elsel]);
+ yb1[elsel] = y1_[elsel] + d2/d1*0.4*(yb1[elsel]-y1_[elsel]);
+ }
+ strcpy(pr4, pr3menue[*msel]);
+ return 4;
+ L4:
+ x2[elsel] = x;
+ y2[elsel] = y;
+ if (si_fabs(x - xb2[elsel]) < 3.0 && si_fabs(y - yb2[elsel]) < 3.0)
+ return 4;
+ if (selmenue[mgefuellt] == true)
+ typ[elsel] = tbeziergef;
+ else
+ typ[elsel] = tbezier;
+ setlineattribute(0L, elsel);
+ /* berechneminmax(elsel); */
+ /* unnoetig, da bei ausel fuer bezier berechnet!! */
+ ausel(elsel, paint);
+ /* ggf. weiterfuehren der Bezierkurve */
+ elselalt=elsel;
+ freieselement(&elsel);
+ x1[elsel]=x2[elselalt];
+ y1_[elsel]=y2[elselalt];
+ xb1[elsel]=2*x1[elsel]-xb2[elselalt];
+ yb1[elsel]=2*y1_[elsel]-yb2[elselalt];
+ strcpy(pr4, " first point of tangent to end point?");
+ fortsetzung = true;
+ return 3;
+}
+
+
+Static Void ellanfendpunkt(i)
+long i;
+{
+ double lx, ly, xm, ym, cr, sr;
+
+ ellpar(i, &xm, &ym, &lx, &ly, &cr, &sr);
+ while (wanf[i] >= wg)
+ wanf[i] -= wg;
+ while (wanf[i] < 0.0)
+ wanf[i] += wg;
+ while (wend[i] > wg)
+ wend[i] -= wg;
+ while (wend[i] < 0.0)
+ wend[i] += wg;
+ ellw_xy(xm, ym, lx, ly, cr, sr, wanf[i], &xb1[i], &yb1[i]);
+ ellw_xy(xm, ym, lx, ly, cr, sr, wend[i], &xb2[i], &yb2[i]);
+}
+
+
+Static Void kreisanfendpunkt(i)
+long i;
+{
+ double xm, ym, rad;
+
+ xm = x1[i];
+ ym = y1_[i];
+ rad = laenge1[i];
+ while (wanf[i] >= wg)
+ wanf[i] -= wg;
+ while (wanf[i] < 0.0)
+ wanf[i] += wg;
+ while (wend[i] > wg)
+ wend[i] -= wg;
+ while (wend[i] < 0.0)
+ wend[i] += wg;
+ xb1[i] = xm + rad * cos(wanf[i] * fgradbo);
+ yb1[i] = ym + rad * sin(wanf[i] * fgradbo);
+ xb2[i] = xm + rad * cos(wend[i] * fgradbo);
+ yb2[i] = ym + rad * sin(wend[i] * fgradbo);
+}
+
+Static long winkeleingabe(w)
+double *w;
+{ long i; double wi;
+
+ if(istnullstr(EinText)==true) return 1;
+ i=sscanf(EinText,"%lf",&wi);
+ if (i!=1) return 2;
+ if ((wi > 4000)||(wi < -4000)) return 2;
+ while (wi > 360.0) wi -= 360.0;
+ while (wi < 0.0) wi += 360.0;
+ *w = wi*10;
+ return 0;
+}
+
+Static long einarc(x,y,elsel,taste,phase)
+ long elsel, taste, phase;
+ double x,y;
+ /* Eingabe Kreisbogen */
+{
+ long i, ltyp, ldicke, lende;
+
+ phase -= phase2;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ strcpy(pr4, pranfwi);
+ if (selmenue[mdegrees]==true)
+ inittastaturtext(nullstr,pr2menue[mdegrees],1L);
+ winerwartet = 1;
+ return (phase2+1);
+ L1:
+ if (taste==0) {/* stringeingabe*/
+ i = winkeleingabe(&wanf[elsel]);
+ if (i != 0) goto L0;
+ }
+ else
+ wanf[elsel] = winkelk(x1[elsel], y1_[elsel], x, y);
+ L1B:
+ winerwartet = 1;
+ strcpy(pr4, prendwi);
+ if (selmenue[mdegrees]==true)
+ inittastaturtext(nullstr,pr2menue[mdegrees],1L);
+ return (phase2+2);
+ L2:
+ if (taste==0) {/* stringeingabe*/
+ i = winkeleingabe(&wend[elsel]);
+ if (i != 0) goto L1B;
+ }
+ else
+ wend[elsel] = winkelk(x1[elsel], y1_[elsel], x, y);
+ winerwartet = 0;
+ if (si_fabs(wanf[elsel]-wend[elsel])<10) goto L1B;
+ setlineattribute(0L, elsel);
+ kreisanfendpunkt(elsel);
+ if (selmenue[mgefuellt]==true) {typ[elsel] = tkreissektorgef;}
+ else typ[elsel] = tkreisbogen;
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ if (typ[elsel] != tkreissektorgef) return 0;
+ /* anschliessenden Sektor eingeben, nur Endwinkel */
+ /* zunaechst bisherigen Sektor umspeichern */
+ freieselement(&i);
+ kopunv(elsel,i);
+ typ[elsel] = -1;
+ wanf[elsel] = wend[elsel];
+ strcpy(pr4, prendwisektor);
+ goto L1B;
+}
+
+
+
+Static Void normgrid()
+{
+ double a, dx, dy;
+
+ dx = gridwx1 + gridwx2;
+ dy = gridwy1 + gridwy2;
+ a = sifsqrt(1.0, dx * dx + dy * dy);
+ gridw0 = a;
+ gridw = a;
+ a = 1 / a;
+ gridwx1 *= a;
+ gridwy1 *= a;
+ gridwx2 *= a;
+ gridwy2 *= a;
+}
+
+Static Void selmenloeschen(msel)
+long *msel;
+{
+ selmenue[*msel]=false;
+ ausmenueelement(*msel);
+ *msel=0;
+}
+
+Static long eingitter(x,y,msel,phase)
+ long *msel,phase;
+ double x,y;
+ /*eingitter*/
+{
+ double dx, dy, a, c, aq, cq, cosa;
+ static double b, bq;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ }
+ L0:
+ strcpy(pr2, " grid");
+ ausgrid(weiss);
+ initgrid();
+ ausgrid(schwarz);
+ strcpy(pr4, pr2menue[*msel]);
+ return 1;
+ L1:
+ ausgrid(weiss);
+ gridx0 = x;
+ gridy0 = y;
+ ausgrid(schwarz);
+ strcpy(pr4, " first grid point to the right?");
+ return 2;
+ L2:
+ x -= gridx0;
+ y -= gridy0;
+ bq = x * x + y * y;
+ b = sifsqrt(1.0, bq);
+ if (b < 5) return 2;
+ ausgrid(weiss);
+ gridwx1 = x;
+ gridwy1 = y;
+ gridwx2 = -y;
+ gridwy2 = x;
+ normgrid();
+ ausgrid(schwarz);
+ strcpy(pr4, " first grid point up?");
+ return 3;
+ L3:
+ x -= gridx0;
+ y -= gridy0;
+ cq = x * x + y * y;
+ c = sifsqrt(1.0, cq);
+ if (c < 5) return 3;
+ dx = gridwx1 * gridw - x;
+ dy = gridwy1 * gridw - y;
+ aq = dx * dx + dy * dy;
+ a = sifsqrt(1.0, aq);
+ if (a < 5) return 3;
+ /*Kosinussatz*/
+ cosa = (aq - bq - cq) / (2 * b * c);
+ if (si_fabs(cosa) > 0.98) return 2;
+ ausgrid(weiss);
+ gridwx1 *= gridw;
+ gridwy1 *= gridw;
+ gridwx2 = x;
+ gridwy2 = y;
+ normgrid();
+ ausgrid(schwarz);
+ selmenloeschen(msel);
+ return 0;
+}
+
+
+Static long eincircle(x,y,taste,msel,phase)
+ long *msel,taste,phase;
+ double x,y;
+ /* Eingabe Kreis oder Kreisbogen */
+{
+ static long elsel;
+ long ltyp, ldicke, lende;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ default: goto L3; /* Fuer einarc */
+ }
+ L0:
+ return 1;
+ L1:
+ freieselement(&elsel);
+ x1[elsel] = x;
+ y1_[elsel] = y;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ laenge1[elsel] = ppabstand(x, y, x1[elsel], y1_[elsel]);
+ if (laenge1[elsel] < 2.0) laenge1[elsel] = 2.0;
+ laenge2[elsel] = laenge1[elsel];
+ setlineattribute(0L, elsel);
+ lineende[elsel] = 0;
+ if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]!=true)) {
+ typ[elsel] = tkreis;
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return 0;
+ }
+ if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]==true)) {
+ typ[elsel] = tkreisgef;
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return 0;
+ }
+ phase=phase2;
+ L3:
+ phase =einarc(x,y,elsel,taste,phase);
+ return phase;
+}
+
+
+Static boolean relevant(i, xp, yp)
+long i;
+double xp, yp;
+/* Pruefung, ob der Punkt relevant fuer */
+/* die Wahl des Elements i sein kann */
+{
+ double xanf, yanf, xend, yend, rmax;
+
+ if (typ[i] <=0) return false;
+ rmax = 1.05*maxabstand;
+ xanf=elxmin[i]-rmax;
+ xend=elxmax[i]+rmax;
+ yanf=elymin[i]-rmax;
+ yend=elymax[i]+rmax;
+ if ((xp >= xanf)&&(xp <= xend)&&
+ (yp >= yanf)&&(yp <= yend)) return true;
+ return false;
+}
+
+Static double pkreisabstand(i, xp, yp)
+long i;
+double xp, yp;
+{ double d, dmin;
+
+ dmin= initabstand;
+ d = si_fabs(ppabstand(x1[i], y1_[i], xp, yp) - laenge1[i]);
+ if (d < dmin)
+ dmin = d;
+ return dmin;
+}
+
+Static double pkreisboabstand(i, xp, yp)
+long i;
+double xp, yp;
+{
+ double d, w;
+
+ d = pkreisabstand(i, xp, yp);
+ if (d>=initabstand)
+ return d;
+ w = winkelk(x1[i], y1_[i], xp, yp);
+ if (inwinkel(i, w)==false)
+ return initabstand;
+ return d;
+}
+
+Static double pellabstand(i, xp, yp)
+long i;
+double xp, yp;
+{
+ double xell, yell, w, d, dmin;
+
+ dmin= initabstand;
+ w = winkelell(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], xp, yp);
+ ellw_xy(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], w, &xell,
+ &yell);
+ d = ppabstand(xp, yp, xell, yell);
+ if (d < dmin)
+ dmin = d;
+ return dmin;
+}
+
+Static double pellboabstand(i, xp, yp)
+long i;
+double xp, yp;
+{
+ double xell, yell, w, d, dmin;
+
+ dmin= initabstand;
+ w = winkelell(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], xp, yp);
+ ellw_xy(x1[i], y1_[i], laenge1[i], laenge2[i], crw[i], srw[i], w, &xell,
+ &yell);
+ d = ppabstand(xp, yp, xell, yell);
+ if (inwinkel(i, w)==false)
+ return dmin;
+ if (d < dmin)
+ dmin = d;
+ return dmin;
+}
+
+Static double pviereckabstand(i, xp, yp)
+long i;
+double xp, yp;
+{ double d, dmin;
+
+ dmin = pgxyabstand(x1[i], y1_[i], x2[i], y2[i], xp, yp);
+ d = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp);
+ if (d < dmin)
+ dmin = d;
+ d = pgxyabstand(xb1[i], yb1[i], x2[i], y2[i], xp, yp);
+ if (d < dmin)
+ dmin = d;
+ d = pgxyabstand(x2[i], y2[i], xb2[i], yb2[i], xp, yp);
+ if (d < dmin)
+ dmin = d;
+ d = pgxyabstand(xb2[i], yb2[i], x1[i], y1_[i], xp, yp);
+ if (d < dmin)
+ dmin = d;
+ return dmin;
+}
+
+Static double pdreieckabstand(i, xp, yp)
+long i;
+double xp, yp;
+{
+ double d, dmin;
+ dmin = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp);
+ d = pgxyabstand(xb1[i], yb1[i], x2[i], y2[i], xp, yp);
+ if (d < dmin)
+ dmin = d;
+ d = pgxyabstand(x2[i], y2[i], x1[i], y1_[i], xp, yp);
+ if (d < dmin)
+ dmin = d;
+ return dmin;
+}
+
+Static double abstmod1(d)
+double d;
+{/* fuer nicht gefuellte Elemente */
+ double x, dgrenz;
+ dgrenz = maxabstand*0.3;
+ if (d < dgrenz) return d;
+ x = (d-dgrenz)*2.0+dgrenz;
+ return x;
+}
+
+Static double abstmod2(d)
+double d;
+{/* fuer gefuellte Elemente */
+ double x, dgrenz;
+ dgrenz = maxabstand*0.3;
+ if (d < dgrenz) return (d+2.0);
+ x = (d-dgrenz)*0.5+dgrenz+2.0;
+ return x;
+}
+
+Static double abstelement(i, xp, yp)
+long i;
+double xp, yp;
+/* wird nur zur Selektion der Elemente benutzt, deshalb wird der */
+/* berechnete Abstand bei gefuellten Elementen und anderen Elementen */
+/* so modifiziert, dass bei gef. Elemeneten groessere Abstaende noch */
+/* zugelassen sind und kleinere Abstaende erhoeht werden */
+/* In der Naehe eines nichtgefuellten Element wird deshalb diese bevorzugt */
+
+{
+ double d, d2;
+
+ d = initabstand;
+ if (typ[i] <= 0)
+ goto _L1;
+ if (relevant(i, xp, yp)==false)
+ goto _L1;
+ switch (typ[i]) {
+
+ case ttext:
+ d = ppabstand(x1[i], y1_[i], xp, yp);
+ goto Lngef;
+
+ case tgerade:
+ d = pgabstand(i, xp, yp);
+ goto Lngef;
+
+ case trechteckgef:
+ case tviereckgef:
+ d = pviereckabstand(i, xp, yp);
+ goto Lgef;
+
+ case tdreieckgef:
+ d = pdreieckabstand(i, xp, yp);
+ goto Lgef;
+
+ case tkreis:
+ d = pkreisabstand(i, xp, yp);
+ goto Lngef;
+
+ case tkreisgef:
+ d = pkreisabstand(i, xp, yp);
+ goto Lgef;
+
+
+ case tkreisbogen:
+ d = pkreisboabstand(i, xp, yp);
+ goto Lngef;
+
+ case tkreissektorgef:
+ d = pkreisboabstand(i, xp, yp);
+ d2 = pgxyabstand(x1[i], y1_[i], xb2[i], yb2[i], xp, yp);
+ if (d2 < d) d = d2;
+ d2 = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp);
+ if (d2 < d) d = d2;
+ goto Lgef;
+
+ case tell:
+ d = pellabstand(i, xp, yp);
+ goto Lngef;
+
+ case tellgef:
+ d = pellabstand(i, xp, yp);
+ goto Lgef;
+
+ case tellbogen:
+ d = pellboabstand(i, xp, yp);
+ goto Lngef;
+
+ case tellsektorgef:
+ d = pellboabstand(i, xp, yp);
+ d2 = pgxyabstand(x1[i], y1_[i], xb2[i], yb2[i], xp, yp);
+ if (d2 < d) d = d2;
+ d2 = pgxyabstand(x1[i], y1_[i], xb1[i], yb1[i], xp, yp);
+ if (d2 < d) d = d2;
+ goto Lgef;
+
+ case tbezier:
+ d = pbezabstand(i, xp, yp);
+ goto Lngef;
+ case tbeziergef:
+ d = pbezabstand(i, xp, yp);
+ d2 = pgxyabstand(x1[i], y1_[i], x2[i], y2[i], xp, yp);
+ if (d2 < d) d = d2;
+ goto Lgef;
+ }/*case*/
+Lgef:
+ d = abstmod2(d);
+ return d;
+Lngef:
+ d= abstmod1(d);
+ return d;
+_L1:
+ return d;
+}
+
+
+Static Void sucheelement(art, elsel, xp, yp)
+long art, *elsel;
+double xp, yp;
+{
+ double dmin, d;
+ long i;
+
+ *elsel = 0;
+ dmin = 5.0*maxabstand;
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] > 0) {
+ if (suchtypok[typ[i]][art]=='y') {
+ d = abstelement(i, xp, yp);
+ if (d < dmin) {
+ dmin = d;
+ *elsel = i;
+ }
+ }
+ }
+ }
+}
+
+Static boolean blinkgruppeninre();
+Static boolean elementinre();
+
+Static boolean blinkelemente(xanf, yanf, xend, yend, elselmin)
+double xanf, yanf, xend, yend;
+long elselmin;
+{/* Alle Elemente/Gruppen im Bereich blink == true */
+ /* return true, falls solche vorhanden */
+ /* Falls Bereich: nur Elemente >= elselmin beruecksichtigt */
+ /* Blinken ist aber noch nicht aktiviert !! */
+ long elsel, erg;
+
+ blinkenan();
+ blinkend = false;
+ initgruppentag(false);
+ if (xanf == xend) { /*selecteinelement*/
+ sucheelement((long)alleelem, &elsel, xanf, yanf);
+ if (elsel == 0) {
+ return false;
+ }
+ if (selmenue[mgroupmode] == false){
+ blink[elsel] = true;
+ return true;
+ }
+ blinkgruppe(elsel);
+ return true;
+ }
+ if (selmenue[mgroupmode] == false){
+ erg = false;
+ for (elsel = elselmin; elsel <= zelmax; elsel++) {
+ if (elementinre(xanf, yanf, xend, yend, elsel)==true) {
+ blink[elsel] = true;
+ erg = true;
+ }
+ }
+ return erg;
+ }
+ return blinkgruppeninre(xanf, yanf, xend, yend, elselmin);
+}
+
+Static long einellarc(x,y,elsel,taste,phase)
+ long elsel,phase,taste;
+ double x,y;
+/* Eingabe Ellipsenbogen */
+{
+ long i, ltyp, ldicke, lende;
+
+ phase -= phase2;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ strcpy(pr4, pranfwi);
+ if (selmenue[mdegrees]==true)
+ inittastaturtext(nullstr,pr2menue[mdegrees],1L);
+ winerwartet = 1;
+ return (phase2+1);
+ L1:
+ if (taste==0) {/* stringeingabe*/
+ i = winkeleingabe(&wanf[elsel]);
+ if (i != 0) goto L0;
+ }
+ else
+ wanf[elsel] = winkelell(x1[elsel], y1_[elsel], laenge1[elsel],
+ laenge2[elsel], crw[elsel], srw[elsel], x, y);
+ L1B:
+ winerwartet = 1;
+ strcpy(pr4, prendwi);
+ if (selmenue[mdegrees]==true)
+ inittastaturtext(nullstr,pr2menue[mdegrees],1L);
+ return (phase2+2);
+ L2:
+ if (taste==0) {/* stringeingabe*/
+ i = winkeleingabe(&wend[elsel]);
+ if (i != 0) goto L1B;
+ }
+ else
+ wend[elsel] = winkelell(x1[elsel], y1_[elsel], laenge1[elsel],
+ laenge2[elsel], crw[elsel], srw[elsel], x, y);
+ winerwartet = 0;
+ if (si_fabs(wanf[elsel]-wend[elsel])<10) goto L1B;
+ setlineattribute(0L, elsel);
+ ellanfendpunkt(elsel);
+ if (selmenue[mgefuellt]==true) {typ[elsel] = tellsektorgef;}
+ else typ[elsel] = tellbogen;
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ if (typ[elsel] != tellsektorgef) return 0;
+ /* anschliessenden Sektor eingeben, nur Endwinkel */
+ /* zunaechst bisherigen Sektor umspeichern */
+ freieselement(&i);
+ kopunv(elsel,i);
+ typ[elsel] = -1;
+ wanf[elsel] = wend[elsel];
+ strcpy(pr4, prendwisektor);
+ goto L1B;
+}
+
+
+Static long einellipse(x,y,xa,ya,taste,msel,phase)
+long *msel,taste,phase;
+double x,y,xa,ya;
+/* Eingabe Ellipse */
+{
+ double xpr_, ypr_;
+ static long elsel, elselg;
+ long ltyp, ldicke, lende;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ case 4: goto L4;
+ default: goto L5; /* Phasen in einellarc */
+ }
+ L0:
+ return 1;
+ L1:
+ freieselement(&elsel);
+ x1[elsel] = x;
+ y1_[elsel] = y;
+ if (selmenue[mparallel]==true) {
+ strcpy(pr4, " line, parallel to major axis? ");
+ return 2;
+ }
+ strcpy(pr4, prxachse);
+ return 3;
+ L2:
+ sucheelement((long)nurgerade, &elselg,xa, ya);
+ if (elselg==0) return 2;
+ setzewinkel(elsel, x1[elselg], y1_[elselg], x2[elselg], y2[elselg]);
+ strcpy(pr4, prxachse);
+ return 3;
+ L3:
+ xy_ell(x1[elsel], y1_[elsel], crw[elsel], srw[elsel], x, y, &xpr_, &ypr_);
+ laenge1[elsel] = si_fabs(xpr_);
+ if (laenge1[elsel] < dminein) return 3;
+ strcpy(pr4, pryachse);
+ return 4;
+ L4:
+ xy_ell(x1[elsel], y1_[elsel], crw[elsel], srw[elsel], x, y, &xpr_, &ypr_);
+ laenge2[elsel] = si_fabs(ypr_);
+ if (laenge2[elsel] < dminein) return 4;
+ setlineattribute(0L, elsel);
+ lineende[elsel] = 0;
+ if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]!=true)) {
+ typ[elsel] = tell;
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return 0;
+ }
+ if ((selmenue[mbogen]!=true)&&(selmenue[mgefuellt]==true)) {
+ typ[elsel] = tellgef;
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return 0;
+ }
+ phase=phase2;
+ L5:
+ return (einellarc(x,y,elsel,taste,phase));
+}
+
+
+
+Static long einlinepp(x,y,xa,ya,elsel,taste,msel,phase)
+ long *msel, elsel,taste,phase;
+ double x,y,xa,ya;
+ /* Endpunkt der Strecke durch Punkt gegeben */
+{
+ phase -= phase2;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ strcpy(pr4, pr3menue[*msel]);
+ return (phase2+1);
+ L1:
+ x2[elsel]=x;
+ y2[elsel]=y;
+ createline(0L, x1[elsel], y1_[elsel], x2[elsel], y2[elsel]);
+ return 0;
+}
+
+
+Static long einlinepg(x,y,xa,ya,elsel,taste,msel,phase)
+ long *msel, elsel,taste,phase;
+ double x,y,xa,ya;
+ /* Endpunkt durch parallele Linie */
+{
+ double dx, dy, dxu, dyu;
+ long i;
+ phase -= phase2;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ strcpy(pr4, pr2menue[mparallel]);
+ return (phase2+1);
+ L1:
+ x2[elsel]=x;
+ y2[elsel]=y;
+ strcpy(pr4, pr3menue[mparallel]);
+ return (phase2+2);
+ L2:
+ sucheelement((long)nurgerade, &i, xa, ya);
+ if (i==0) return 2;
+ dx = x2[i] - x1[i];
+ dy = y2[i] - y1_[i];
+ dxu = x2[elsel] - x1[elsel];
+ dyu = y2[elsel] - y1_[elsel];
+ if (si_fabs(dx) > si_fabs(dy)) {
+ if (fsign(dxu)!=fsign(dx)){dx = -dx; dy = -dy;}
+ }
+ else {
+ if (fsign(dyu)!=fsign(dy)){dx = -dx; dy = -dy;}
+ }
+ x2[elsel] = x1[elsel] + dx;
+ y2[elsel] = y1_[elsel] + dy;
+ createline(0L, x1[elsel], y1_[elsel], x2[elsel], y2[elsel]);
+ return 0;
+}
+
+
+Static long einlinelot(x,y,xa,ya,elsel,taste,msel,phase)
+ long *msel, elsel,taste,phase;
+ double x,y,xa,ya;
+ /* Endpunkt der Geraden durch Lot auf andere Gerade */
+{
+ double dx, dy, xs, ys;
+ long i;
+ phase -= phase2;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ strcpy(pr4, pr3menue[mlot]);
+ return (phase2+1);
+ L1:
+ sucheelement((long)nurgerade, &i, xa, ya);
+ if (i==0) return (phase2+1);
+ dx = x2[i] - x1[i];
+ dy = y2[i] - y1_[i];
+ if (lot(x1[i], y1_[i], dx, dy, x1[elsel], y1_[elsel], &xs, &ys)==true)
+ createline(0L, x1[elsel], y1_[elsel], xs, ys);
+ return 0;
+}
+
+
+Static long einline(x,y,xa,ya,taste,msel,phase)
+ long *msel,taste,phase;
+ double x,y,xa,ya;
+/* Eingabe einer Strecke */
+{
+ static long elsel, art;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ default: goto L2; /* fuer einlinelot,einlinepg,einlinepp */
+ }
+ L0:
+ strcpy(pr4, pr2menue[*msel]);
+ freieselement(&elsel);
+ return 1;
+ L1:
+ /* erster Punkt */
+ x1[elsel]=x;
+ y1_[elsel]=y;
+ /*zweiter Punkt */
+ art=0;
+ if (selmenue[mparallel]==true) art=1;
+ if (selmenue[mlot]==true) art=2;
+ phase=phase2;
+ L2:
+ switch (art){
+ case 0:
+ phase=einlinepp(x,y,xa,ya,elsel,taste,msel,phase);
+ break;
+ case 1:
+ phase=einlinepg(x,y,xa,ya,elsel,taste,msel,phase);
+ break;
+ case 2:
+ phase=einlinelot(x,y,xa,ya,elsel,taste,msel,phase);
+ break;
+ }
+ if (phase!=0) return phase;
+ return 0;
+} /*line*/
+
+
+Static Void ergbox(el1, el2)
+long el1, el2;
+{
+ long i, j;
+ double xx[4], yy[4];
+
+ xx[0] = x1[el1];
+ yy[0] = y1_[el1];
+ xx[1] = x2[el1];
+ yy[1] = y2[el1];
+ xx[2] = x1[el2];
+ yy[2] = y1_[el2];
+ xx[3] = x2[el2];
+ yy[3] = y2[el2];
+ for (i = 0; i <= 1; i++) {
+ for (j = 2; j <= 3; j++) {
+ if (si_fabs(xx[i] - xx[j]) < 5.0 &&
+ si_fabs(yy[i] - yy[j]) < 5.0)
+ goto _L1;
+ }
+ }
+ goto _L2;
+_L1:
+ if (i == 0) {
+ ftausch(&xx[0], &xx[1]);
+ ftausch(&yy[0], &yy[1]);
+ }
+ if (j == 3) {
+ ftausch(&xx[2], &xx[3]);
+ ftausch(&yy[2], &yy[3]);
+ }
+ /* punkte 1 und 2 sind in der Naehe nun*/
+ createline(el2, xx[0], yy[0], xx[0] + xx[3] - xx[2], yy[0] + yy[3] - yy[2]);
+ createline(el1, xx[3], yy[3], xx[3] + xx[0] - xx[1], yy[3] + yy[0] - yy[1]);
+_L2: ;
+}
+
+Static long geteingabezeile(datdeskr)
+FILE *datdeskr;
+{ /* Zeile lesen, Zahl Zeichen zurueck, Grenze maxstrl */
+
+ long anz;
+
+ if (fgets(eingabezeile,maxstrl+1,datdeskr)==NULL)
+ anz = 1;
+ else
+ anz = strlen(eingabezeile);
+ anz--;
+ eingabezeile[anz] = '\0';
+ return anz;
+}
+
+Static Void eindateigruppen(datdeskr)
+FILE *datdeskr;
+{
+ long i, erfolg, gruppe, element, vorg;
+ /* den einzelnen Zeichnungselementen Gruppennummern zuordnen */
+ fscanf(datdeskr, "%ld", &gruppe);
+ while ((gruppe > 0)&&(gruppe <= maxgruppen)) {
+ fscanf(datdeskr, "%ld", &element);
+ while ((element > 0)&&(element <= zelmax)) {
+ if (typ[element]==0) fehler(11);
+ if (group[element] != 0) fehler(12);
+ group[element] = gruppe;
+ fscanf(datdeskr, "%ld", &element);
+ }
+ if (element != 0) fehler(12);
+ fscanf(datdeskr, "%ld", &gruppe);
+ }
+ if (gruppe != 0) fehler(13);
+ /* Gruppenbaum aufbauen */
+ fscanf(datdeskr, "%ld%ld", &gruppe, &vorg);
+ while ((gruppe > 0)&&(gruppe <= maxgruppen)) {
+ if ((vorg <=0)||(vorg >maxgruppen)) fehler(15);
+ if (vater[gruppe] != -1) fehler(15); /* Doppeldefinition */
+ vater[gruppe] = vorg;
+ fscanf(datdeskr, "%ld%ld", &gruppe, &vorg);
+ }
+ if (gruppe != 0) fehler(14);
+ /* Baum vervollstaendigen */
+ for (i=1;i<=maxgruppen;i++) {
+ if (vater[i] >0) {
+ if (vater[vater[i]] == -1) {
+ /* Gruppennummer noch nicht vergeben */
+ vater[vater[i]] = 0; /* ist ein oberster Knoten */
+ }
+ }
+ }
+ /* Sicherstellung, dass alle elementaren Gruppen im Baum */
+ /* aber auch keine unnoetigen */
+ grumax = maxgruppen;
+ aenderunggruppen = true;
+ unbenutztegruppenfreigeben();
+}
+
+
+Static long ausdateigruppen()
+{
+ long i, j, anz, gruppe, element, vorg;
+
+ /* Elemente sind komprimiert!!! */
+ for (i=1; i<=zelmax;i++) blink[i] = false;
+ for (i=1; i<=zelmax;i++) {
+ if ((blink[i] == false)&&(group[i] !=0)) {
+ anz = 0;
+ gruppe = group[i];
+ fprintf(datdeskr, "%ld ",gruppe);
+ for (j=i; j<=zelmax; j++) {
+ if (group[j]==gruppe) {
+ blink[j] = true;
+ anz++;
+ fprintf(datdeskr, "%ld ",j);
+ if (anz >10) {
+ anz = 0;
+ fprintf(datdeskr, "\n");
+ }
+ }/*if*/
+ }/* for j*/
+ fprintf(datdeskr, " 0\n"); /* Abschluss einer Gruppe */
+ }
+ }/*for i*/
+ fprintf(datdeskr, " 0 \n"); /* Abschluss elementare Gruppen */
+ /* Ausgabe der relevanten Teile des Baums */
+ for (i=1;i<=grumax;i++) {
+ if (vater[i] > 0) {
+ fprintf(datdeskr, "%ld %ld\n", i, vater[i]);
+ }
+ }
+ fprintf(datdeskr, "0 0"); /* Abschluss Knoten-Vater-Paare */
+}
+
+Static Void einvorspannepc(datdeskr)
+FILE *datdeskr;
+{
+ /* wegen readstdin ist die erste Zeile immer schon gelesen */
+ sscanf(eingabezeile, "%*[^123456789]%lg", &version);
+ geteingabezeile(datdeskr);
+ sscanf(eingabezeile, "%lg", &texfaktor);
+ geteingabezeile(datdeskr);
+ sscanf(eingabezeile, "%lg", &texdashl);
+ geteingabezeile(datdeskr);
+ sscanf(eingabezeile, "%lg", &texdotg);
+ geteingabezeile(datdeskr);
+ sscanf(eingabezeile, "%lg", &texinterd);
+ if (version < 4.0) {
+ geteingabezeile(datdeskr);
+ sscanf(eingabezeile, "%lg", &gridw0);
+ }
+ if (version >= 10.0) {
+ geteingabezeile(datdeskr);
+ sscanf(eingabezeile, "%lg%lg%lg%lg%lg%lg%lg%lg",
+ &gridw0, &gridw, &gridx0, &gridy0,
+ &gridwx1, &gridwy1, &gridwx2, &gridwy2);
+ }
+ if (version >= 11.0) {
+ geteingabezeile(datdeskr);
+ sscanf(eingabezeile, "%*lg%*lg%*lg%*lg%*lg%*lg%lg%lg%d%d",
+ &breite,&hoehe,&mitvorspann,&querformat);
+ }
+}
+
+Static long einlesenelement(datdeskr,elseladr)
+FILE *datdeskr;
+long *elseladr;
+{ /* auszuwertender String in eingabezeile bereits gelesen !!!! */
+ long i,k,anz;
+
+ freieselement(&i);
+ *elseladr = i;
+ typ[i]=0;
+ anz=sscanf(eingabezeile,
+ "%ld%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%ld%ld%ld%lg%lg%lg",
+ &typ[i], &x1[i], &y1_[i], &x2[i], &y2[i], &xb1[i], &yb1[i],
+ &xb2[i], &yb2[i], &wanf[i], &wend[i], &linedicke[i],
+ &lineende[i], &linetype[i], &laenge1[i], &laenge2[i], &rotwi[i]);
+ if (typ[i] <= 0)
+ return anz;
+ if (rotwi[i] != 0.0) {
+ crw[i] = cos(rotwi[i] * fgradbo);
+ srw[i] = sin(rotwi[i] * fgradbo);
+ }
+ switch (typ[i]) {
+
+ case tgerade:
+ laenge1[i] = ppabstand(x1[i], y1_[i], x2[i], y2[i]);
+ laenge2[i] = laenge1[i];
+ break;
+
+ case trechteckgef:
+ /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/
+ break;
+
+ case tellbogen:
+ case tellsektorgef:
+ ellanfendpunkt(i);
+ break;
+
+ case tkreisbogen:
+ case tkreissektorgef:
+ kreisanfendpunkt(i);
+ break;
+
+ case ttext:
+ freiestextel(&k);
+ textno[i] = k;
+ geteingabezeile(datdeskr);
+ strcpy(texte[k],eingabezeile);
+ textparam(i);
+ break;
+ }/*case*/
+ berechneminmax(i);
+ return anz;
+}
+
+
+
+Static long eindatei(msel,dateiname,taste,phase)
+Char *dateiname;
+long *msel, taste, phase;
+{
+ long i, k, anz;
+ double xxmin,xxmax,yymin,yymax;
+ Static Void init_neuezeichnung();
+
+switch (phase) {
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L1B;
+ default: goto L1;
+ }
+
+ L0:
+ inittastaturtext(dateiname, pr2menue[*msel],0L);
+ return 1;
+ L1:
+ strcpy(dateiname,EinText);
+ if(istnullstr(dateiname)==true) goto L3; /*ohne Initialisieren*/
+ L1B:
+ /* Einsprung nur fuer automatische Ausgabe */
+ datdeskr = fopen(dateiname, "r");
+ protokoll("open input file: ",dateiname);
+ init_neuezeichnung(); /* mit Initialisieren */
+ if (datdeskr == NULL) {
+ protokoll("can't open file ",dateiname);
+ goto L3;
+ }
+ /* wegen readstdin muss die erste Zeile immer schon gelesen sein*/
+ geteingabezeile(datdeskr);
+ einvorspannepc(datdeskr);
+
+ while (1) {
+ anz = geteingabezeile(datdeskr);
+ if (anz == 0)
+ fehler(3L);
+ anz = einlesenelement(datdeskr,&i);
+ if (typ[i] <= 0)
+ goto L2;
+ } /*while*/
+
+ L2: /*Ende*/
+ if (version >= 13.0) {/* Gruppen sind da!*/
+ eindateigruppen(datdeskr);
+ }
+ if (version < 11.0) {
+ minmax(&xxmin,&xxmax,&yymin,&yymax);
+ breite=(xxmax-xxmin)*texfaktor;
+ hoehe=(yymax-yymin)*texfaktor;
+ }
+
+ if (datdeskr != NULL) fclose(datdeskr);
+ datdeskr = NULL;
+ L3:
+ selmenloeschen(msel);
+ ausalles();
+ konkat(winname,window_name,": ");
+ konkat(winname,winname,dateiname);
+ XStoreName(display,win,winname);
+ return 0;
+}
+
+Static double dashlength()
+{
+ return (texdashl / texfaktor);
+}
+
+
+Static double dotgap(i)
+{
+ if (i==0) return (texdotg / texfaktor);
+ else return (texdotg*(1+0.15*getlinedicke(i)) / texfaktor);
+}
+
+
+Static double interdotgap()
+{
+ double h;
+
+ h = texinterd / texfaktor;
+ return h;
+}
+
+
+Static Void texpfeilaus(i, ende, xa, ya, dx, dy)
+long i, ende;
+double xa, ya, dx, dy;
+{
+ long dxv, dyv;
+ double w;
+
+ if (lineende[i] == 0) return;
+ if (lineende[i] == 4) return;
+ if (ende == 1 && (lineende[i] == 1 || lineende[i] == 3)) { /*am Anfang*/
+ w = 2.0 * pi - winkel0(-dx, -dy, 1.0, 1.0) * fgradbo;
+ fprintf(datdeskr, "\\aLdPfeil{%.3f,%.3f}{%.3f}{%d}\n",
+ xa, ya, w, getlinedicke(i));
+ fputs(einrueck, datdeskr);
+ }
+ if (ende == 2 && (lineende[i] == 2 || lineende[i] == 3)) { /*am Ende*/
+ w = 2.0 * pi - winkel0(-dx, -dy, 1.0, 1.0) * fgradbo;
+ fprintf(datdeskr, "\\eLdPfeil{%.3f,%.3f}{%.3f}{%d}\n",
+ xa, ya, w, getlinedicke(i));
+ fputs(einrueck, datdeskr);
+ }
+}
+
+Static Void texpfeilep(i,xa,ya,xe,ye)
+long i;
+double xa,ya,xe,ye; /* reduzierte Punkte */
+ /*bei tex ging put voraus*/
+{ double x0, y0, x, y, dx, dy;
+
+ x0=x1[i];
+ y0=y1_[i];
+ x=x0;
+ y=y0;
+ dx=xa-x;
+ dy=ya-y;
+ texpfeilaus(i, 1L, x-x0, y-y0, dx, dy);
+ x=x2[i];
+ y=y2[i];
+ dx=xe-x;
+ dy=ye-y;
+ texpfeilaus(i, 2L, x-x0, y-y0, dx, dy);
+}
+
+
+Static Void texpfeilew(i,redwa,redwe)
+long i;
+double redwa,redwe; /* Winkel im Bogenmass fuer reduzierten Bogen */
+ /*bei tex ging put und bei Ell. ggf rotiert voraus*/
+{ double lx, ly, w, x, y, dx, dy;
+
+ lx = laenge1[i];
+ ly = laenge2[i];
+ w = wanf[i] * fgradbo;
+ x = lx * cos(w);
+ y = ly * sin(w);
+ dx = lx * cos(redwa) - x;
+ dy = ly * sin(redwa) - y;
+ texpfeilaus(i, 1L, x, y, dx, dy);
+ w = wend[i] * fgradbo;
+ x = lx * cos(w);
+ y = ly * sin(w);
+ dx = lx * cos(redwe) - x;
+ dy = ly * sin(redwe) - y;
+ texpfeilaus(i, 2L, x, y, dx, dy);
+}
+
+
+Static double kuerzungsstrecke(elsel)
+ long elsel;
+{ /* Kuerzungsstrecke fuer Pfeile am Ende */
+ /* beim Aufrufer umzusetzen in Winkel bzw. Kuerzungsfaktoren */
+ double z;
+
+ /*z ist zu kuerzende Strecke in pixels, abhaengig von Formel fuer */
+ /*stdpfeile in pst-latexdraw.sty */
+ /* Der Faktor 1.5 ergibt sich durch Vergroesserung des Faktors 1.33, */
+ /* welcher die x-Koordinate angibt, die beim Pfeil die Breite */
+ /* ergibt, die der Linienstaerke der Linie entspricht. Pfeil u.a. */
+ /* definiert in pst-latexdraw.sty durch */
+ /* (-8,-3) */
+ /* (1.33,0.5) */
+ /* (-8,0) (1.33,0) (0,0) */
+ /*jeweils skaliert mit Faktor f=linienstaerke in pts * 0.27 + 0.4 */
+ /* gemaess Makro .... \code{#1 .27 mul .4 add dup scale .... */
+ z=(getlinedicke(elsel)*lw2pt*0.27+0.4)*2.0/texfaktor;
+ return z;
+}
+
+
+Static void pfeilreduktiongerade(elsel,xa,ya,xe,ye)
+ long elsel;
+ double *xa,*ya,*xe,*ye;
+{ /* Verkuerzung der Geraden wegen Pfeilen am Ende */
+ double d,z,k,dx,dy;
+
+ z = kuerzungsstrecke(elsel);
+ d=ppabstand(*xa,*ya,*xe,*ye);/*Laenge der Geraden*/
+ if (d<=0.0) d=1.0;
+ k=z/d;
+ if (k > 0.5) k = 0.5;
+ dx = k * (*xe);
+ dy = k * (*ye);
+
+ switch (lineende[elsel]) {
+
+ case 1:
+ *xa = dx;
+ *ya = dy;
+ break;
+
+ case 2:
+ *xe -= dx;
+ *ye -= dy;
+ break;
+
+ case 3:
+ *xa = dx;
+ *ya = dy;
+ *xe -= dx;
+ *ye -= dy;
+ break;
+ }/*case*/
+}
+
+Static double kuerzungswinkel(z,a,b,wa,wgr)
+double z,a,b,wa,wgr;
+/* Bestimmung von dw, um den Bogen bei wa zu kuerzen ist */
+/* alle Winkel im Bogenmass, mathematisch */
+/* wa und wgr begrenzen das sinnvolle Intervall und geben Richtung! */
+{ double xa,ya,dxa,dya,x,y,acw,asw,r,w,dw;
+
+ xa = a*cos(wa);
+ ya = b*sin(wa);
+ dxa = a*sin(wa);
+ dya = b*cos(wa);
+ r = sqrt(dxa*dxa+dya*dya)+1.0;
+ dw=z/r*fsign(wgr-wa)*0.05;
+ w=wa;
+LL:
+ x = a*cos(w);
+ y = b*sin(w);
+ if (ppabstand(x,y,xa,ya) >= z) {
+ dw = w-wa-dw;
+ return dw;
+ }
+ w += dw;
+ if ( ((dw>0)&&(w<=wgr))||((dw<0)&&(w>=wgr)) )
+ goto LL;
+ dw = w-wa-dw;
+ return dw;
+}
+
+Static void pfeilreduktionbogen(elsel,redwa,redwe)
+ long elsel;
+ double *redwa,*redwe;
+{ /* Verkuerzung der Boegen wegen Pfeilen am Ende */
+ /* redwa, redwe sind im Bogenmass, mathematisch, redwe > redwa */
+ /* redwa, redwe vorbesetzt!!! */
+ double mitte, a, b, z, dwa,dwe;
+
+ a = laenge1[elsel];
+ b = laenge2[elsel];
+ if (*redwe <= *redwa)
+ *redwe += 2.0*pi;
+ mitte = (*redwe + *redwa)*0.5;
+ z = kuerzungsstrecke(elsel);
+ dwa = kuerzungswinkel(z, a, b, *redwa, mitte);
+ dwe = kuerzungswinkel(z, a, b, *redwe, mitte);
+ switch (lineende[elsel]) {
+
+ case 1:
+ *redwa += dwa;
+ break;
+
+ case 2:
+ *redwe += dwe;
+ break;
+
+ case 3:
+ *redwa += dwa;
+ *redwe += dwe;
+ break;
+ }/*case*/
+}
+
+Static Void austexgerade(i)
+long i;
+{
+ double xa, ya, xe, ye, oxe, oye;
+
+ /*relativ zu x1,y1*/
+ xa = 0.0;
+ ya = 0.0;
+ xe = x2[i] - x1[i]; /*relative Koordinaten*/
+ ye = y2[i] - y1_[i];
+ oxe=xe;
+ oye=ye;
+ putc('{', datdeskr);
+ if (lineende[i] == 0) {
+ if (linetype[i]==1)
+ fprintf(datdeskr, "\\ldline(%.3f,%.3f)(%.3f,%.3f)}\n",
+ xa, ya, xe, ye);
+ else
+ fprintf(datdeskr, "\\ldline[%d](%.3f,%.3f)(%.3f,%.3f)}\n",
+ linetype[i], xa, ya, xe, ye);
+ }
+ else if (lineende[i] == 4) { /* capprojecting */
+ if (linetype[i]==1)
+ fprintf(datdeskr, "\\ldcpline(%.3f,%.3f)(%.3f,%.3f)}\n",
+ xa, ya, xe, ye);
+ else
+ fprintf(datdeskr, "\\ldcpline[%d](%.3f,%.3f)(%.3f,%.3f)}\n",
+ linetype[i], xa, ya, xe, ye);
+ }
+ else {
+ pfeilreduktiongerade(i,&xa,&ya,&xe,&ye);
+ texpfeilep(i,xa+x1[i],ya+y1_[i],xe+x1[i],ye+y1_[i]);
+ /* oxe,oye = Originalkoordinaten Endpunkt nicht verkuerzt */
+ fprintf(datdeskr,
+ "\\LdpLine{%d}{(%.3f,%.3f)}[%d](%.3f,%.3f)(%.3f,%.3f)}\n",
+ lineende[i], oxe, oye, linetype[i], xa, ya, xe, ye);
+ /* zweite }, damit put geschlossen wird */
+ }
+}
+
+Static double radwinkeltotex(radianw)
+double radianw;
+{ return (2.0 * pi - radianw); }
+
+Static double gradwinkeltotex(w)
+double w;
+{ return (2.0 * pi - w * fgradbo);}
+
+
+Static Void texwinkel(wa,we, texwa, texwe)
+double wa, we, *texwa, *texwe;
+{ /* Umrechnung math. Darstellung der Winkel in Darstellung in latex */
+ /* alle Winkel im Bogenmass */
+ *texwa = radwinkeltotex(we);
+ *texwe = radwinkeltotex(wa);
+ if (*texwe <= *texwa)
+ *texwe += 2.0 * pi;
+}
+
+
+Static Void austexgefrechteck(i)
+long i;
+{
+ double dx, dy;
+
+ /* put bzgl. x1,y1 ging voraus*/
+ dx = ppabstand(x1[i], y1_[i], xb1[i], yb1[i]);
+ dy = ppabstand(x1[i], y1_[i], xb2[i], yb2[i]);
+ fprintf(datdeskr, "{\\rule{%.3lf\\unitlength}{%.3lf\\unitlength}}\n",
+ dx,dy);
+}
+
+Static Void austexgefdreieck(i)
+long i;
+{
+ double x2rel,y2rel, xb1rel, yb1rel;
+
+ /* put bzgl. x1,y1 ging voraus*/
+ x2rel = x2[i]-x1[i];
+ y2rel = y2[i]-y1_[i];
+ xb1rel = xb1[i]-x1[i];
+ yb1rel = yb1[i]-y1_[i];
+ fprintf(datdeskr, "{\\gefdreieck(%.3lf,%.3lf)(%.3lf,%.3lf)}\n",
+ x2rel,y2rel,xb1rel,yb1rel);
+ /* erster und dritter Punkt ist Nullpunkt (d.h. relativ zu put!)*/
+}
+
+Static Void austexgefviereck(i)
+long i;
+{
+ double x2rel,y2rel, xb1rel, yb1rel, xb2rel, yb2rel;
+
+ /* put bzgl. x1,y1 ging voraus*/
+ x2rel = x2[i]-x1[i];
+ y2rel = y2[i]-y1_[i];
+ xb1rel = xb1[i]-x1[i];
+ yb1rel = yb1[i]-y1_[i];
+ xb2rel = xb2[i]-x1[i];
+ yb2rel = yb2[i]-y1_[i];
+ fprintf(datdeskr, "{\\gefviereck(%.3lf,%.3lf)(%.3lf,%.3lf)(%.3lf,%.3lf)}\n",
+ xb1rel,yb1rel,x2rel,y2rel,xb2rel,yb2rel);
+ /* erster und vierter Punkt ist Nullpunkt (d.h. relativ zu put!)*/
+}
+
+
+Static Void austexkreis(i)
+long i;
+{
+ double wa, we, redwa, redwe, texwa, texwe, lx, zlx, otexwa,otexwe;
+
+ /* put bzgl. x1,y1 ging voraus*/
+ putc('{', datdeskr);
+ lx = laenge1[i];
+ zlx=2.0 * lx;
+ wa = wanf[i] * fgradbo;
+ we = wend[i] * fgradbo;
+ redwa = wa;
+ redwe = we;
+ texwinkel(wa, we, &texwa, &texwe);
+ otexwa = texwa; /*Originalwerte vor Adaption an Pfeile*/
+ otexwe = texwe;
+
+ switch (typ[i]) {
+
+ case tkreis:
+ if (linetype[i]== 1)
+ fprintf(datdeskr, "\\circle{%.3f}}\n", zlx);
+ else
+ fprintf(datdeskr, "\\circle[%d]{%.3f}}\n", linetype[i], zlx);
+ break;
+
+ case tkreisgef:
+ fprintf(datdeskr, "\\circle*{%.3f}}\n", zlx);
+ break;
+
+ case tkreisbogen:
+ if (lineende[i]==0) {
+ if (linetype[i]== 1)
+ fprintf(datdeskr, "\\arc{%.3f}{%.3f}{%.3f}}\n", zlx, texwa, texwe);
+ else
+ fprintf(datdeskr, "\\arc[%d]{%.3f}{%.3f}{%.3f}}\n",
+ linetype[i], zlx, texwa, texwe);
+ }
+ else {
+ pfeilreduktionbogen(i, &redwa, &redwe);
+ texpfeilew(i,redwa,redwe);
+ texwinkel(redwa, redwe, &texwa, &texwe);
+ /* otexwa,otexwe = Originalwerte der Endpunkte */
+ fprintf(datdeskr, "\\LdpArc{%d}{%.3f}{%.3f}[%d]{%.3f}{%.3f}{%.3f}}\n",
+ lineende[i],otexwa,otexwe,linetype[i], zlx, texwa, texwe);
+ }
+ break;
+
+ case tkreissektorgef:
+ wa=0.1*wanf[i];
+ we=0.1*wend[i];
+ fprintf(datdeskr,"\\pieslice{%.3f}{%.3f}{%.2f}{%.2f}}\n",
+ zlx,zlx,wa,we);
+ break;
+ }
+}
+
+Static Void austexell(i)
+long i;
+{
+ double wa, we, redwa, redwe, texwa, texwe, lx, ly, zlx, zly, otexwa, otexwe;
+
+ /* put bzgl. x1,y1 ging voraus*/
+ putc('{', datdeskr);
+ lx = laenge1[i];
+ ly = laenge2[i];
+ zlx=2.0 * lx;
+ zly=2.0 * ly;
+ wa = wanf[i] * fgradbo;
+ we = wend[i] * fgradbo;
+ redwa = wa;
+ redwe = we;
+ texwinkel(wa, we, &texwa, &texwe);
+ otexwa=texwa;
+ otexwe=texwe;
+
+ switch (typ[i]) {
+ case tell:
+ if (linetype[i]== 1)
+ fprintf(datdeskr, "\\ellipse{%.3f}{%.3f}}\n", zlx, zly);
+ else
+ fprintf(datdeskr, "\\ellipse[%d]{%.3f}{%.3f}}\n",
+ linetype[i], zlx, zly);
+ break;
+ case tellgef:
+ fprintf(datdeskr, "\\ellipse*{%.3f}{%.3f}}\n", zlx, zly);
+ break;
+
+ case tellbogen:
+ if (lineende[i]==0) {
+ if (linetype[i]== 1)
+ fprintf(datdeskr, "\\ellarc{%.3f}{%.3f}{%.3f}{%.3f}}\n",
+ zlx, zly,texwa, texwe);
+ else
+ fprintf(datdeskr, "\\ellarc[%d]{%.3f}{%.3f}{%.3f}{%.3f}}\n",
+ linetype[i], zlx, zly, texwa, texwe);
+ }
+ else {
+ pfeilreduktionbogen(i, &redwa,&redwe);
+ texpfeilew(i,redwa,redwe);
+ texwinkel(redwa, redwe, &texwa, &texwe);
+ /* otexwa,otexwe = Originalwerte der Endpunkte */
+ fprintf(datdeskr,
+ "\\LdpEllarc{%d}{%.3f}{%.3f}[%d]{%.3f}{%.3f}{%.3f}{%.3f}}\n",
+ lineende[i],otexwa,otexwe,linetype[i], zlx, zly, texwa, texwe);
+ }
+ break;
+
+ case tellsektorgef:
+ wa=0.1*wanf[i];
+ we=0.1*wend[i];
+ fprintf(datdeskr,"\\pieslice{%.3f}{%.3f}{%.2f}{%.2f}}\n",
+ zlx,zly,wa,we);
+ break;
+ }
+}
+
+Static Void pfeilreduktionbezier(elsel,nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3)
+long elsel;
+double *nx0,*ny0,*nx1,*ny1,*nx2,*ny2,*nx3,*ny3;
+{ double z,d1,d2,t1,t2,dxdt,dydt;
+
+ z = kuerzungsstrecke(elsel);
+ d1= ppabstand(x1[elsel],y1_[elsel],xb1[elsel],yb1[elsel]);
+ d2= ppabstand(x2[elsel],y2[elsel],xb2[elsel],yb2[elsel]);
+ t1= z/(3.0*d1);
+ t2= 1.0-z/(3.0*d2);
+ switch (lineende[elsel]) {
+
+ case 1:
+ t2=1.0;
+ break;
+
+ case 2:
+ t1=0.0;
+ break;
+
+ case 3:
+ break;
+ }/*case*/
+ punkt_bezier(elsel,t1,nx0,ny0);
+ ableitung_bezier(elsel,t1,&dxdt,&dydt);
+ *nx1=dxdt/3.0 + *nx0;
+ *ny1=dydt/3.0 + *ny0;
+ punkt_bezier(elsel,t2,nx3,ny3);
+ ableitung_bezier(elsel,t2,&dxdt,&dydt);
+ *nx2=-dxdt/3.0 + *nx3;
+ *ny2=-dydt/3.0 + *ny3;
+}
+
+Static Void austexbezier(i)
+long i;
+{ double nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3;
+ /* neue Werte der Stuetzpunkte wegen Pfeilen*/
+
+ putc('{', datdeskr);
+ if (lineende[i]==0) {
+ if (linetype[i]==1)
+ fprintf(datdeskr, "\\bezier(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n",
+ xb1[i] - x1[i], yb1[i] - y1_[i],
+ xb2[i] - x1[i], yb2[i] - y1_[i],
+ x2[i] - x1[i], y2[i] - y1_[i]);
+ else
+ fprintf(datdeskr, "\\bezier[%d](%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n",
+ linetype[i], xb1[i] - x1[i], yb1[i] - y1_[i],
+ xb2[i] - x1[i], yb2[i] - y1_[i],
+ x2[i] - x1[i], y2[i] - y1_[i]);
+ }
+ else {
+ pfeilreduktionbezier(i,&nx0,&ny0,&nx1,&ny1,&nx2,&ny2,&nx3,&ny3);
+ texpfeilep(i,nx0,ny0,nx3,ny3);
+ /*zunaechst Originalstuetzpunkte, dann neue Stuetzpunkte wegen Pfeilen */
+ fprintf(datdeskr, "\\LdpBezier{%d}(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)[%d](%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n",
+ lineende[i], xb1[i] - x1[i], yb1[i] - y1_[i],
+ xb2[i] - x1[i], yb2[i] - y1_[i],
+ x2[i] - x1[i], y2[i] - y1_[i],
+ linetype[i], nx0 - x1[i], ny0 - y1_[i],
+ nx1 - x1[i], ny1 - y1_[i],
+ nx2 - x1[i], ny2 - y1_[i],
+ nx3 - x1[i], ny3 - y1_[i]);
+ }
+}
+
+
+Static Void austexbeziergef(i)
+long i;
+{
+
+ putc('{', datdeskr);
+ fprintf(datdeskr, "\\beziergef(%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)}\n",
+ xb1[i] - x1[i], yb1[i] - y1_[i],
+ xb2[i] - x1[i], yb2[i] - y1_[i],
+ x2[i] - x1[i], y2[i] - y1_[i]);
+}
+
+
+Static Void austextext(i)
+long i;
+{
+ long lage, fontart;
+ fontart = linetype[i];
+ lage = (long)floor(laenge2[i] + 0.5);
+ fprintf(datdeskr, "{\\makebox(0,0)%s{%s%s}}\n",
+ textausrichtung[lage],textfontmakro[fontart],texte[textno[i]]);
+}
+
+
+Static Void austexelement(i, xmin, ymin)
+long i;
+double xmin, ymin;
+{
+ double rrot, xa, ya;
+ long zcolor;
+
+ zcolor=getzcolor(i,paint);
+ rrot = 2.0 * pi - rotwi[i] * fgradbo;
+ xa = x1[i] - xmin;
+ ya = y1_[i] - ymin;
+ if (rotwi[i] == 0.0) {
+ if (zcolor==schwarz) fprintf(datdeskr, "\\put(%.3f,%.3f)",xa,ya);
+ else fprintf(datdeskr, "\\putc(%.3f,%.3f){%d}", xa, ya, zcolor);
+ }
+ else {
+ if (zcolor==schwarz)
+ fprintf(datdeskr, "\\rput[%.3f](%.3f,%.3f)", rrot,xa,ya);
+ else
+ fprintf(datdeskr, "\\rputc[%.3f](%.3f,%.3f){%d}", rrot,xa,ya,zcolor);
+ }
+
+ switch (typ[i]) { /*case*/
+
+ case ttext:
+ austextext(i);
+ break;
+
+ case tgerade:
+ austexgerade(i);
+ break;
+
+ case trechteckgef:
+ austexgefviereck(i);
+ break;
+
+ case tdreieckgef:
+ austexgefdreieck(i);
+ break;
+
+ case tviereckgef:
+ austexgefviereck(i);
+ break;
+
+ case tkreis:
+ case tkreisgef:
+ case tkreisbogen:
+ case tkreissektorgef:
+ austexkreis(i);
+ break;
+
+ case tell:
+ case tellgef:
+ case tellbogen:
+ case tellsektorgef:
+ austexell(i);
+ break;
+
+ case tbezier:
+ austexbezier(i);
+ break;
+ case tbeziergef:
+ austexbeziergef(i);
+ break;
+ }
+}
+
+
+Static Void auslinedicke(istdicke,solldicke)
+long *istdicke,solldicke;
+{
+ double ptdicke;
+ if (*istdicke != solldicke)
+ { *istdicke=solldicke;
+ ptdicke=lw2pt*solldicke;
+ fprintf(datdeskr,"\\ldlinewidth{%d}{%.1lf}\n",solldicke,ptdicke);
+ }
+}
+
+
+Static long austexdatei(msel, dateiname, taste, phase)
+Char *dateiname;
+long *msel,taste, phase;
+
+{
+ long i, akttexldicke;
+ double deltax, deltay, xxmax, yymax, xxmin, yymin;
+ double fx, fy;
+ Char altbh[maxstrl+1];
+
+ LANF:
+ switch (phase) {
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ case 4: goto L4;
+ case 5: goto L5;
+ case 6: goto L6;
+ case 7: goto L7;
+ }
+ L0:
+ strcpy(texdateiname,dateiname);
+ trenneextension(texdateiname);
+ konkat(texdateiname,texdateiname,".tex");
+ inittastaturtext(texdateiname,pr3menue[*msel],0L);
+ return 1;
+ L1:
+ strcpy(texdateiname,EinText);
+ if (istnullstr(texdateiname)==true) return 0;
+ inittastaturtext(nullstr,
+ "change output options ? (y/...)",0L);
+ return 2;
+ L2:
+ if (*EinText!='y') goto L7;
+ inittastaturtext(nullstr,
+ "LaTeX file ready to copy into LaTeX source ? (y/...)",0L);
+ return 3;
+ L3:
+ nmitvorspann=true;
+ if (*EinText=='y') nmitvorspann=false;
+ inittastaturtext(nullstr, "use old unitlength ? (y/...)",0L);
+ return 4;
+ L4:
+ oldunitlength=false;
+ if (*EinText=='y') {
+ nbreite=breite;
+ nhoehe=hoehe;
+ oldunitlength=true;
+ goto L5B;
+ }
+ L4B:
+ sprintf(altbh,"%.1f %.1f",breite,hoehe);
+ inittastaturtext(altbh,
+ "maximum width and height of LaTeX picture in mm? (DIN A4:210 296): ",0L);
+ return 5;
+ L5:
+ i=sscanf(EinText,"%lg%lg",&nbreite,&nhoehe);
+ if ((i!=2)||(nbreite<10.0)||(nhoehe<10.0)) goto L4B;
+ L5B:
+ inittastaturtext(nullstr,"rotate LaTeX picture? (y/...)",0L);
+ return 6;
+ L6:
+ /*Aenderungen erst durchfuehren, wenn Ausgabe wirklich erfolgt*/
+ querformat=true;
+ if (*EinText=='y') querformat=false;
+ mitvorspann=nmitvorspann;
+ hoehe=nhoehe;
+ breite=nbreite;
+ if (oldunitlength==false) {
+ minmax(&xxmin, &xxmax, &yymin, &yymax);
+ deltax = xxmax - xxmin;
+ if (deltax == 0.0) deltax = 1.0;
+ deltay = yymax - yymin;
+ if (deltay == 0.0) deltay = 1.0;
+ fx = breite / deltax;
+ fy = hoehe / deltay;
+ if (fx <= fy)
+ texfaktor = fx;
+ else
+ texfaktor = fy;
+ }
+
+ L7:
+ minmax(&xxmin, &xxmax, &yymin, &yymax);
+ deltax = xxmax - xxmin;
+ if (deltax == 0.0) deltax = 1.0;
+ deltay = yymax - yymin;
+ if (deltay == 0.0) deltay = 1.0;
+ datdeskr = fopen(texdateiname, "w");
+ protokoll(extfiletext,texdateiname);
+ if (datdeskr == NULL) {
+ protokoll("can't open file ",texdateiname);
+ return 0;
+ }
+ if (mitvorspann==true) {
+ fprintf(datdeskr,
+ "%s\n",docstyle);
+ fprintf(datdeskr, "\\begin{document}\n");
+ }
+
+ fprintf(datdeskr, "\\setlength{\\unitlength}{%.3lfmm}\n",texfaktor);
+ if (querformat==false) {
+ fprintf(datdeskr, "\\begin{picture}(%.3f,%.3f)\n", deltay,deltax);
+ fprintf(datdeskr, "\\rput[4.7124](%.3f,0){\n", deltay);
+ }
+ fprintf(datdeskr, "\\begin{picture}(%.3f,%.3f)\n", deltax,deltay);
+ akttexldicke = -1;
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] > 0) {
+ auslinedicke(&akttexldicke,getlinedicke(i));
+ austexelement(i, xxmin, yymin);
+ }
+ }
+ fprintf(datdeskr, "\\end{picture}\n");
+ if (querformat==false)
+ fprintf(datdeskr, "}\\end{picture}\n");
+ if (mitvorspann==true) {
+ fprintf(datdeskr, "\\end{document}\n");
+ }
+ fprintf(datdeskr, "%s\n", blank);
+ if (datdeskr != NULL)
+ fclose(datdeskr);
+ datdeskr = NULL;
+ return 0;
+}
+
+
+Static Void ausskalieren()
+{
+ double xmin, ymin, xmax, ymax, dx, dy, fx, fy, f;
+
+ minmax(&xmin, &xmax, &ymin, &ymax);
+ dx = xmax - xmin;
+ dy = ymax - ymin;
+ fx = 1.0;
+ fy = 1.0;
+ if (dx != 0.0) {
+ if (dx < 0.5 * xzmax)
+ fx = 0.5 * xzmax / dx;
+ if (dx > 4.0 * xzmax)
+ fx = 4.0 * xzmax / dx;
+ }
+ if (dy != 0.0) {
+ if (dy < 0.5 * yzmax)
+ fy = 0.5 * yzmax / dy;
+ if (dy > 4.0 * yzmax)
+ fy = 4.0 * yzmax / dy;
+ }
+ if (fx > fy)
+ f = fy;
+ else
+ f = fx;
+ pskalieren(&xmin, &ymin, 0.0, 0.0, f);
+ pskalieren(&xmax, &ymax, 0.0, 0.0, f);
+ dx = xmittelzei - (xmax + xmin) * 0.5;
+ dy = ymittelzei - (ymax + ymin) * 0.5;
+ elskalieren(&gridw, dx, dy, f);
+}
+
+Static long schreibenausdatei(msel,dateiname,taste,phase)
+Char *dateiname;
+long *msel,taste,phase;
+{
+ long i;
+ double xxmin, xxmax, yymin, yymax, dxpixel, dypixel;
+
+ if (istnullstr(dateiname) == true) return 0;
+ datdeskr = fopen(dateiname, "w");
+ if (datdeskr == NULL) {
+ protokoll("can't open file ",dateiname);
+ return 0;
+ }
+
+ kompakt();
+ protokoll(intfiletext,dateiname);
+ minmax(&xxmin, &xxmax, &yymin, &yymax);
+ dxpixel=xxmax-xxmin;
+ dypixel=yymax-yymin;
+ fprintf(datdeskr, "%s\n", window_name);
+ fprintf(datdeskr, "% .5E (TEXFAKTOR)\n", texfaktor);
+ fprintf(datdeskr, "% .5E (TEXDASHLAENGE)\n", texdashl);
+ fprintf(datdeskr, "% .5E (TEXDOTGAP)\n", texdotg);
+ fprintf(datdeskr, "% .5E (TEXINTERDOTGAP)\n", texinterd);
+ fprintf(datdeskr, "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f (GITTERWERTE)\n",
+ gridw0, gridw, gridx0, gridy0,
+ gridwx1, gridwy1, gridwx2, gridwy2);
+ fprintf(datdeskr,
+ "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %d %d (AUSGABEOPTIONEN)\n",
+ xxmin, yymin, xxmax, yymax, dxpixel, dypixel,
+ breite, hoehe, mitvorspann, querformat);
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] > 0) {
+ fprintf(datdeskr,
+ "%ld %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %ld %ld %ld %.3lf %.3lf %.3lf\n",
+ typ[i],x1[i],y1_[i],x2[i],y2[i],xb1[i],yb1[i],xb2[i], yb2[i],
+ wanf[i],wend[i],linedicke[i],lineende[i],linetype[i],
+ laenge1[i],laenge2[i],rotwi[i]);
+ if (typ[i] == ttext) /*text*/
+ fprintf(datdeskr, "%s\n", texte[textno[i]]);
+ }
+ }
+ fprintf(datdeskr,"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n");
+ ausdateigruppen();
+ if (datdeskr != NULL) fclose(datdeskr);
+ datdeskr = NULL;
+ return 0;
+}
+
+
+Static long ausdatei(msel,dateiname,taste,phase)
+Char *dateiname;
+long *msel,taste,phase;
+{
+ long i;
+
+ switch(phase) {
+ case 0: goto L0;
+ default: goto L1;
+ }
+
+ L0:
+ inittastaturtext(dateiname,pr2menue[*msel],0L);
+ return 1;
+ L1:
+ strcpy(dateiname,EinText);
+ return schreibenausdatei(msel,dateiname,taste,phase);
+}
+
+Static long extendline(elsel, xa, ya)
+long elsel;
+double xa, ya;
+{
+ double deltax, deltay, d1, d2, f, dx, dy;
+ dx = x2[elsel] - x1[elsel];
+ dy = y2[elsel] - y1_[elsel];
+ d1 = ppabstand(xa, ya, x1[elsel], y1_[elsel]);
+ d2 = ppabstand(xa, ya, x2[elsel], y2[elsel]);
+ deltax = 0.0;
+ deltay = 0.0;
+ f = dx * dx + dy * dy;
+ f = verlline / sifsqrt(1.0, f);
+ deltax = dx * f;
+ deltay = dy * f;
+ if (d2 < d1) { /*verl bei x2,y2*/
+ x2[elsel] += deltax;
+ y2[elsel] += deltay;
+ } else { /*verl bei x1,y1*/
+ x1[elsel] -= deltax;
+ y1_[elsel] -= deltay;
+ }
+}
+
+Static long extendbogen(elsel, xa, ya)
+long elsel;
+double xa, ya;
+{
+ double wa, we, wi;
+
+ wa = wanf[elsel];
+ we = wend[elsel];
+ if (we < wa) we += wg;
+ switch (typ[elsel]) {
+ case tkreisbogen:
+ case tkreissektorgef:
+ wi = winkelk(x1[elsel], y1_[elsel], xa, ya);
+ break;
+ case tellsektorgef:
+ case tellbogen:
+ wi = winkelell(x1[elsel], y1_[elsel], laenge1[elsel],
+ laenge2[elsel], crw[elsel], srw[elsel], xa, ya);
+ break;
+ }
+ if (!((wi >= wa) && (wi <= we))) wi += wg;
+ if (si_fabs(wi-wa) < si_fabs(wi-we)) { /* wa ausdehnen */
+ wa -= 150.0;
+ } else {/* we ausdehnen */
+ we += 150.0;
+ }
+ if ((we-wa) >= wg) {/* voller Kreis bzw. volle Ellipse */
+ wanf[elsel] = 0.0;
+ wend[elsel] = wg;
+ switch (typ[elsel]) {
+ case tkreisbogen:
+ typ[elsel] = tkreis;
+ break;
+ case tkreissektorgef:
+ typ[elsel] =tkreisgef;
+ break;
+ case tellsektorgef:
+ typ[elsel] =tellgef;
+ break;
+ case tellbogen:
+ typ[elsel] =tell;
+ break;
+ }
+ return;
+ }
+ /* Bogen bleibt */
+ while (wa > wg) wa -= wg;
+ while (we > wg) we -= wg;
+ while (wa < 0.0) wa += wg;
+ while (we < 0.0) we += wg;
+ wanf[elsel] = wa;
+ wend[elsel] = we;
+ switch (typ[elsel]) {
+ case tkreisbogen:
+ case tkreissektorgef:
+ kreisanfendpunkt(elsel);wi = winkelk(x1[elsel], y1_[elsel], xa, ya);
+ break;
+ case tellsektorgef:
+ case tellbogen:
+ ellanfendpunkt(elsel);
+ break;
+ }
+}
+
+Static long extend(xa, ya, msel, phase)
+long *msel,phase;
+double xa, ya;
+{
+ long elsel;
+ double deltax, deltay, d1, d2, f, dx, dy;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ return 1;
+ L1:
+ sucheelement((long)nurextendel, &elsel, xa, ya);
+ if (elsel==0) return 1;
+ ausel(elsel, erase);
+ switch (typ[elsel]) {
+ case tgerade:
+ extendline(elsel, xa, ya);
+ break;
+ case tkreisbogen:
+ case tkreissektorgef:
+ case tellsektorgef:
+ case tellbogen:
+ extendbogen(elsel, xa, ya);
+ break;
+ }
+ berechneminmax(elsel);
+ auselemente();
+ return 1;
+}
+
+
+Static long einbox(x,y,taste,msel,phase)
+ long *msel,taste,phase;
+ double x,y;
+{
+ static long elsel;
+ double dx, dy;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ return 1;
+ L1:
+ freieselement(&elsel);
+ x1[elsel]=x;
+ y1_[elsel]=y;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ x2[elsel]=x;
+ y2[elsel]=y;
+ dx = x2[elsel] - x1[elsel];
+ dy = y2[elsel] - y1_[elsel];
+ if (si_fabs(dx) < 2.0 || si_fabs(dy) < 2.0) return 2;
+ if (dx < 0) {
+ dx = -dx;
+ ftausch(&x1[elsel], &x2[elsel]);
+ }
+ if (dy < 0) {
+ dy = -dy;
+ ftausch(&y1_[elsel], &y2[elsel]);
+ }
+ xb1[elsel] = x1[elsel] + dx;
+ yb1[elsel] = y1_[elsel];
+ xb2[elsel] = x1[elsel];
+ yb2[elsel] = y1_[elsel] + dy;
+ if (selmenue[mgefuellt]==true) { /*gefuelltes Rechteck*/
+ typ[elsel] = trechteckgef;
+ setlineattribute(0L, elsel);
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return 0;
+ }
+ createline(0L, x1[elsel], y1_[elsel], xb1[elsel], yb1[elsel]);
+ createline(0L, xb1[elsel], yb1[elsel], x2[elsel], y2[elsel]);
+ createline(0L, x2[elsel], y2[elsel], xb2[elsel], yb2[elsel]);
+ createline(0L, xb2[elsel], yb2[elsel], x1[elsel], y1_[elsel]);
+ typ[elsel] = 0;
+ return 0;
+}
+
+
+Static long einboxll(xa,ya,msel,phase)
+ long *msel,phase;
+ double xa, ya;
+/* Ergaenzung zum Parallelogramm */
+{
+ static long elsel1, elsel2;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ strcpy(pr4, pr2menue[*msel]);
+ return 1;
+ L1:
+ sucheelement((long)nurgerade, &elsel1, xa, ya);
+ if (elsel1==0) return 1;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ sucheelement((long)nurgerade, &elsel2, xa, ya);
+ if (elsel2==0) return 2;
+ ergbox(elsel1, elsel2);
+ return 0;
+}
+
+Static long eindreieck(x,y,taste,msel,phase)
+ long *msel,taste,phase;
+ double x,y;
+{
+ static long elsel;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ }
+ L0:
+ return 1;
+ L1:
+ freieselement(&elsel);
+ x1[elsel]=x;
+ y1_[elsel]=y;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ x2[elsel]=x;
+ y2[elsel]=y;
+ if (ppabstand(x2[elsel], y2[elsel],x1[elsel],y1_[elsel]) < 3.0)
+ return 2;
+ strcpy(pr4,prpoint3);
+ return 3;
+ L3:
+ xb1[elsel]=x;
+ yb1[elsel]=y;
+ if (ppabstand(xb1[elsel], yb1[elsel],x1[elsel],y1_[elsel]) < 3.0)
+ return 3;
+ if (ppabstand(xb1[elsel], yb1[elsel],x2[elsel],y2[elsel]) < 3.0)
+ return 3;
+ if (selmenue[mgefuellt]==true) { /*gefuelltes Dreieck*/
+ typ[elsel] = tdreieckgef;
+ setlineattribute(0L, elsel);
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return 0;
+ }
+ createline(0L, x1[elsel], y1_[elsel], xb1[elsel], yb1[elsel]);
+ createline(0L, xb1[elsel], yb1[elsel], x2[elsel], y2[elsel]);
+ createline(0L, x2[elsel], y2[elsel], x1[elsel], y1_[elsel]);
+ typ[elsel] = 0;
+ return 0;
+}
+
+Static long einviereck(x,y,taste,msel,phase)
+ long *msel,taste,phase;
+ double x,y;
+{
+ static long elsel;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ case 4: goto L4;
+ }
+ L0:
+ return 1;
+ L1:
+ freieselement(&elsel);
+ x1[elsel]=x;
+ y1_[elsel]=y;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ xb1[elsel]=x;
+ yb1[elsel]=y;
+ if (ppabstand(xb1[elsel], yb1[elsel],x1[elsel],y1_[elsel]) < 3.0)
+ return 2;
+ strcpy(pr4,prpoint3);
+ return 3;
+ L3:
+ x2[elsel]=x;
+ y2[elsel]=y;
+ if (ppabstand(x2[elsel], y2[elsel],xb1[elsel],yb1[elsel]) < 3.0)
+ return 3;
+ if (ppabstand(x2[elsel], y2[elsel],x1[elsel],y1_[elsel]) < 3.0)
+ return 3;
+ strcpy(pr4,prpoint4);
+ return 4;
+ L4:
+ xb2[elsel]=x;
+ yb2[elsel]=y;
+ if (ppabstand(xb2[elsel], yb2[elsel],x1[elsel],y1_[elsel]) < 3.0)
+ return 4;
+ if (ppabstand(xb2[elsel], yb2[elsel],xb1[elsel],yb1[elsel]) < 3.0)
+ return 4;
+ if (ppabstand(xb2[elsel], yb2[elsel],x2[elsel],y2[elsel]) < 3.0)
+ return 4;
+ if (selmenue[mgefuellt]==true) { /*gefuelltes Viereck*/
+ typ[elsel] = tviereckgef;
+ setlineattribute(0L, elsel);
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return 0;
+ }
+ createline(0L, x1[elsel], y1_[elsel], xb1[elsel], yb1[elsel]);
+ createline(0L, xb1[elsel], yb1[elsel], x2[elsel], y2[elsel]);
+ createline(0L, x2[elsel], y2[elsel], xb2[elsel], yb2[elsel]);
+ createline(0L, xb2[elsel], yb2[elsel], x1[elsel], y1_[elsel]);
+ typ[elsel] = 0;
+ return 0;
+}
+
+Static Void setlagetext(elsel)
+ long elsel;
+{ /* Lage Text relativ zum Anklickpunkt bestimmen und alle davon */
+ /* abhaengigen Parameter im Zeichnungselement setzen */
+ long lrtb;
+
+ lrtb = 1;
+ if (selmenue[mbtext]==true)
+ lrtb = 3;
+ if (selmenue[mttext]==true)
+ lrtb = 6;
+ if (selmenue[mltext]==true) {
+ lrtb = 7;
+ if (selmenue[mbtext]==true)
+ lrtb = 0;
+ if (selmenue[mttext]==true)
+ lrtb = 4;
+ }
+ if (selmenue[mrtext]==true) {
+ lrtb = 8;
+ if (selmenue[mbtext]==true)
+ lrtb = 2;
+ if (selmenue[mttext]==true)
+ lrtb = 5;
+ }
+ laenge2[elsel] = lrtb;
+ textparam(elsel);
+ berechneminmax(elsel);
+}
+
+
+Static long eintext(x,y,xa,ya,taste,msel,phase)
+ long *msel,taste,phase;
+ double x,y,xa,ya;
+{
+ static long elsel, tsel;
+ long elselg;
+ double dx,dy;
+
+ switch (phase)
+ {
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ case 4: goto L4;
+ case 5: goto L5;
+ default: goto L6; /*fuer Textzeichen */
+ }
+
+ L0:
+ texterase=0L;
+ return 1;
+ L1:
+ for (elsel = 1; elsel <= zelmax; elsel++) {
+ if (typ[elsel] != ttext) continue;
+ if (si_fabs(y1_[elsel] - y) > 0.5) continue;
+ if (si_fabs(x1[elsel] - x) > 0.5) continue;
+ tsel = textno[elsel];
+ ausel(elsel, erase);
+ texterase=elsel;
+ zeichnen = true;
+ setzeakttextfont(elsel);
+ goto L5; /*Text zu modifizieren*/
+ }
+ texterase=0L;
+ freieselement(&elsel);
+ freiestextel(&tsel);
+ x1[elsel] = x;
+ y1_[elsel] = y;
+ if (selmenue[mparallel]==false) goto L4;
+ strcpy(pr4, pr2menue[mparallel]);
+ return 2;
+ L2:
+ x2[elsel] = xa;
+ y2[elsel] = ya;
+ strcpy(pr4, pr3menue[mparallel]);
+ return 3;
+ L3:
+ sucheelement((long)nurgerade, &elselg, xa, ya);
+ if (elselg==0) return 3;
+ strcpy(pr4,pr2menue[*msel]);
+ dx = si_fabs(x2[elselg] - x1[elselg]);
+ if ((x2[elsel] - x1[elsel]) < 0.0) dx = -dx;
+ dy = si_fabs(y2[elselg] - y1_[elselg]);
+ if ((y2[elsel] - y1_[elsel]) < 0.0) dy = - dy;
+ x2[elsel] = x1[elsel] + dx;
+ y2[elsel] = y1_[elsel] + dy;
+ setzewinkel(elsel, x1[elsel], y1_[elsel], x2[elsel], y2[elsel]);
+ L4:
+ setlineattribute(0L,elsel);
+ linetype[elsel] = stdfontnummer;
+ textno[elsel] = tsel;
+ strcpy(texte[tsel],nullstr);
+ L5:
+ inittastaturtext(texte[tsel], "text: ",0L);
+ return 6;
+ L6:
+ strcpy(texte[tsel], EinText);
+ if (istnullstr(texte[tsel]) == true) {
+ typ[elsel] = 0;
+ texterase=0L;
+ return 0;
+ }
+ typ[elsel] = ttext;
+ if (fontnummer != stdfontnummer)
+ linetype[elsel] = fontnummer;
+ setlagetext(elsel);
+ texterase=0L;
+ ausel(elsel, paint);
+ return 0;
+}
+
+Static Void initelemente()
+{
+ long i;
+
+ for (i = 0; i <= zel; i++) {
+ typ[i] = 0; /*Element frei*/
+ textno[i] = 0;
+ }
+ for (i = 1; i <= zstr; i++)
+ strcpy(texte[i],nullstr);
+ zelmax = 0;
+}
+
+
+Static Void drehpunkt(x1r, y1r, dx, dy, cd, sd, v, xp, yp)
+double x1r, y1r, dx, dy, cd, sd, v, *xp, *yp;
+{
+ double xx, yy;
+
+ /*Drehpunkt x1r,y1r*/
+ /*positiver Drehwinkel def. durch cd,sd*/
+ /*Vergroesserung v*/
+ /*Translation um dx,dy*/
+ translation(x1r, y1r, *xp, *yp, &xx, &yy);
+ xx *= v;
+ yy *= v;
+ rotation(cd, -sd, &xx, &yy);
+ translation(-dx, -dy, xx, yy, xp, yp);
+}
+
+
+Static Void drehpunkt1(i, x1r, y1r, dx, dy, cd, sd, v)
+long i;
+double x1r, y1r, dx, dy, cd, sd, v;
+{
+ drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &x1[i], &y1_[i]);
+}
+
+
+Static Void drehpunkt2(i, x1r, y1r, dx, dy, cd, sd, v)
+long i;
+double x1r, y1r, dx, dy, cd, sd, v;
+{
+ drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &x2[i], &y2[i]);
+}
+
+
+Static Void drehpunktb(i, x1r, y1r, dx, dy, cd, sd, v)
+long i;
+double x1r, y1r, dx, dy, cd, sd, v;
+{
+ drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &xb1[i], &yb1[i]);
+ drehpunkt(x1r, y1r, dx, dy, cd, sd, v, &xb2[i], &yb2[i]);
+}
+
+
+Static Void drehell0(i, xr1, yr1, dx, dy, cd, sd, v)
+long i;
+double xr1, yr1, dx, dy, cd, sd, v;
+{
+ double xl, yl, lx, ly;
+
+ lx = laenge1[i];
+ ly = laenge2[i];
+ ell_xy(x1[i], y1_[i], lx, ly, crw[i], srw[i], lx, 0.0, &xl, &yl);
+ drehpunkt(xr1, yr1, dx, dy, cd, sd, v, &xl, &yl);
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ laenge1[i] = lx * v;
+ laenge2[i] = ly * v;
+ setzewinkel(i, x1[i], y1_[i], xl, yl);
+}
+
+
+Static Void drehell(i, xr1, yr1, dx, dy, cd, sd, v)
+long i;
+double xr1, yr1, dx, dy, cd, sd, v;
+{
+ drehell0(i, xr1, yr1, dx, dy, cd, sd, v);
+}
+
+
+Static Void drehellbogen(i, xr1, yr1, dx, dy, cd, sd, v)
+long i;
+double xr1, yr1, dx, dy, cd, sd, v;
+{
+ double xm, ym, lx, ly, cr, sr;
+
+ drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehell0(i, xr1, yr1, dx, dy, cd, sd, v);
+ ellpar(i, &xm, &ym, &lx, &ly, &cr, &sr);
+ wanf[i] = winkelell(xm, ym, lx, ly, cr, sr, xb1[i], yb1[i]);
+ wend[i] = winkelell(xm, ym, lx, ly, cr, sr, xb2[i], yb2[i]);
+ ellanfendpunkt(i);
+}
+
+
+Static Void drehkbogen(i, xr1, yr1, dx, dy, cd, sd, v)
+long i;
+double xr1, yr1, dx, dy, cd, sd, v;
+{
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v);
+ laenge1[i] *= v;
+ laenge2[i] *= v;
+ wanf[i] = winkelk(x1[i], y1_[i], xb1[i], yb1[i]);
+ wend[i] = winkelk(x1[i], y1_[i], xb2[i], yb2[i]);
+}
+
+
+Static boolean testnotin(x, y, xa, ya, xe, ye)
+double x, y, xa, ya, xe, ye;
+{
+ boolean Result;
+
+ Result = true;
+ if (xa > xe) ftausch(&xa,&xe);
+ if (x < xa) goto _L1;
+ if (x > xe) goto _L1;
+ if (ya > ye) ftausch(&ya,&ye);
+ if (y < ya) goto _L1;
+ if (y > ye) goto _L1;
+ Result = false;
+_L1:
+ return Result;
+}
+
+Static boolean schnittellgeradeda(elsel,xa,ya,xe,ye)
+long elsel;
+double xa,ya,xe,ye;
+{
+ long i, anz;
+ double w;
+ terg wgerade, well;
+ Static Void gell00schnittp();
+
+ gell00schnittp(xa,ya,xe,ye,elsel,&anz,wgerade,well,false);
+ if (anz==0) return false;
+ for (i = 1; i <= anz; i++) {
+ if ((wgerade[i]>=0.0)&&(wgerade[i] <= 1.0)) return true;
+ }
+ return false;
+}
+
+Static boolean elementinre(xa, ya, xe, ye, i)
+double xa, ya, xe, ye;
+long i;
+{
+ boolean Result;
+
+ if (typ[i] <= 0)
+ return false;
+ if (xa > xe) ftausch(&xa,&xe);
+ if (ya > ye) ftausch(&ya,&ye);
+ if ((elxmin[i] >= xa)&&(elxmax[i] <= xe)&&
+ (elymin[i] >= ya)&&(elymax[i] <= ye))
+ return true;
+ return false;
+}
+
+
+Static boolean blinkgruppeninre(xa,ya,xe,ye,elselmin)
+double xa,ya,xe,ye;
+long elselmin;
+{ /* Gruppen im Rechteck, aber erst ab elselmin beachtet */
+ /* Nur neu selektierte Elemente: blink == true */
+ /* Nur neu selektierte Gruppen : gruppentag == true */
+ long i,j,g, etwasgetan, anz;
+
+ /* blinkenan(); schon gegeben in blinkelemente !! */
+ /* blinkend = false; schon gegeben in blinkelemente !! */
+ initgruppentag(unbekannt);
+ anz = 0;
+ for (i=elselmin;i<=zelmax;i++) {
+ if (typ[i]>0) {
+ g = group[i];
+ if (g==0) {
+ if (elementinre(xa, ya, xe, ye, i)==true) {
+ anz++;
+ blink[i] = true;
+ }
+ continue;
+ }
+ if (gruppentag[g] == false)
+ continue;
+ /* gruppentag unbekannt oder true */
+ if (elementinre(xa, ya, xe, ye, i)==true) {
+ gruppentag[g] = true;
+ }
+ else
+ markteilbaum(g,false);
+ }
+ }
+ /* jetzt Gruppenbaum untersuchen */
+ etwasgetan = true;
+ while (etwasgetan == true) {
+ etwasgetan = false;
+ for (i=1;i<=grumax;i++) {
+ if ( (gruppentag[i] == unbekannt)||
+ (gruppentag[i] == true) ) {
+ j = 1;
+ while ( (g=sohn(j,i)) != 0) {/* j. Sohn von i untersuchen */
+ j++;
+ if (gruppentag[g] == true)
+ continue;
+ if (gruppentag[g] == unbekannt)
+ break;
+ if (gruppentag[g] == false) {
+ markteilbaum(i, false);
+ etwasgetan = true;
+ break;
+ }
+ }
+ if (g==0) { /* Schleife normal zu Ende, alle Soehne true */
+ if (gruppentag[i] != true) {
+ gruppentag[i] = true;
+ etwasgetan = true;
+ }
+ }
+ }/* end if unbekannt */
+ }/*end Durchlauf durch Gruppen */
+ }/*solange etwas getan */
+ /* Alle Gruppen muessten jetzt bekannt sein, kein Test dafuer! */
+ /* Elemente nur in Rechteck, wenn Gruppe in Rechteck */
+ for (i=elselmin;i<=zelmax;i++) {
+ if (typ[i]>0) {
+ g = group[i];
+ if ((g != 0) && (gruppentag[g] == true)) {
+ anz++;
+ blink[i] = true;
+ }
+ }
+ }
+ if (anz > 0) return true;
+ blinkenaus();
+ return false;
+}
+
+Static boolean zukleineselement(i)
+long i;
+{/*Pruefung, ob Element i zu klein beim kopieren */
+
+ double minabm;
+ minabm = 0.1;
+
+ if (typ[i] <= 0)
+ return true;
+ switch (typ[i]) {
+ case ttext: /*Text*/
+ return false;
+
+ case tgerade: /*Gerade*/
+ if (ppabstand(x1[i], y1_[i], x2[i], y2[i]) < minabm)
+ goto zuklein;
+ break;
+
+ case trechteckgef:
+ case tviereckgef:
+ if (ppabstand(x1[i], y1_[i], x2[i], y2[i]) < minabm)
+ goto zuklein;
+ break;
+
+ case tdreieckgef:
+ if (ppabstand(x1[i], y1_[i], x2[i], y2[i]) < minabm)
+ goto zuklein;
+ break;
+
+ case tkreis:
+ case tkreisgef: /*Kreis*/
+ if (laenge1[i] < minabm)
+ goto zuklein;
+ break;
+
+ case tkreisbogen: /*Kreisbogen*/
+ case tkreissektorgef:
+ if (laenge1[i] < minabm)
+ goto zuklein;
+ break;
+
+ case tell:
+ case tellgef: /*Ellipse*/
+ if ((laenge1[i] < minabm) ||(laenge2[i] < minabm))
+ goto zuklein;
+ break;
+
+ case tellbogen: /*Ellipsenbogen*/
+ case tellsektorgef:
+ if ((laenge1[i] < minabm)|| (laenge2[i] < minabm))
+ goto zuklein;
+ break;
+
+ case tbezier: /*Bezier*/
+ case tbeziergef:
+ if (ppabstand(x1[i], y1_[i], xb1[i], yb1[i]) < minabm)
+ goto zuklein;
+ if (ppabstand(x2[i], y2[i], xb2[i], yb2[i]) < minabm)
+ goto zuklein;
+ break;
+ }/*case*/
+ return false;
+ /* zu klein */
+ zuklein:
+ typ[i] = 0;
+ return true;
+}
+
+
+Static long duplikat0(i,vollst)
+long i;
+boolean vollst;
+{/* Nummer j eines Zeichnungselements ist Ergebnis */
+ /* falls j != 0 ist j ein vorhandenes Duplikat zu i */
+ /* falls vollst == false werden */
+ /* lineende[i], linedicke[i], linetype[i] nicht beruecksichtigt */
+
+ long j;
+
+ for (j = 1; j <= zelmax; j++) {
+ if (typ[j] <= 0)
+ continue;
+ if ((typ[i] != typ[j]) || (i == j))
+ continue;
+ if (group[i] != group[j])
+ continue;
+ if (nglx(x1[i], x1[j])== false)
+ continue;
+ if (nglx(y1_[i], y1_[j])== false)
+ continue;
+ if (nglw(rotwi[i], rotwi[j])==false)
+ continue;
+ if (vollst == true) {
+ if (lineende[i] != lineende[j])
+ continue;
+ if (linedicke[i] != linedicke[j])
+ continue;
+ if (linetype[i] != linetype[j])
+ continue;
+ }
+ switch (typ[i]) {
+
+ case ttext: /*Text*/
+ if (strvergl(texte[textno[i]], texte[textno[j]])==true)
+ goto gleich;
+ break;
+
+ case tgerade: /*Gerade*/
+ if (nglx(x2[i], x2[j])==false)
+ continue;
+ if (nglx(y2[i], y2[j])==false)
+ continue;
+ goto gleich;
+
+ case trechteckgef:
+ case tviereckgef:
+ if (nglx(x2[i], x2[j])==false)
+ continue;
+ if (nglx(y2[i], y2[j])==false)
+ continue;
+ if (nglx(xb1[i], xb1[j])==false)
+ continue;
+ if (nglx(yb1[i], yb1[j])==false)
+ continue;
+ if (nglx(xb2[i], xb2[j])==false)
+ continue;
+ if (nglx(yb2[i], yb2[j])==false)
+ continue;
+ goto gleich;
+
+ case tdreieckgef:
+ if (nglx(x2[i], x2[j])==false)
+ continue;
+ if (nglx(y2[i], y2[j])==false)
+ continue;
+ if (nglx(xb1[i], xb1[j])==false)
+ continue;
+ if (nglx(yb1[i], yb1[j])==false)
+ continue;
+ goto gleich;
+
+ case tkreis:
+ case tkreisgef: /*Kreis*/
+ if (nglx(laenge1[i], laenge1[j])==false)
+ continue;
+ goto gleich;
+
+ case tkreisbogen: /*Kreisbogen*/
+ case tkreissektorgef:
+ if (nglx(laenge1[i], laenge1[j])==false)
+ continue;
+ if (nglw(wanf[i], wanf[j])==false)
+ continue;
+ if (nglw(wend[i], wend[j])==false)
+ continue;
+ goto gleich;
+
+ case tell:
+ case tellgef: /*Ellipse*/
+ if (nglx(laenge1[i], laenge1[j])==false)
+ continue;
+ if (nglx(laenge2[i], laenge2[j])==false)
+ continue;
+ goto gleich;
+
+ case tellbogen: /*Ellipsenbogen*/
+ case tellsektorgef:
+ if (nglx(laenge1[i], laenge1[j])==false)
+ continue;
+ if (nglx(laenge2[i], laenge2[j])==false)
+ continue;
+ if (nglw(wanf[i], wanf[j])==false)
+ continue;
+ if (nglw(wend[i], wend[j])==false)
+ continue;
+ goto gleich;
+
+ case tbezier: /*Bezier*/
+ case tbeziergef:
+ if (nglx(x2[i], x2[j])==false)
+ continue;
+ if (nglx(y2[i], y2[j])==false)
+ continue;
+ if (nglx(xb1[i], xb1[j])==false)
+ continue;
+ if (nglx(yb1[i], yb1[j])==false)
+ continue;
+ if (nglx(xb2[i], xb2[j])==false)
+ continue;
+ if (nglx(yb2[i], yb2[j])==false)
+ continue;
+ goto gleich;
+ }/*case*/
+ } /*for j*/
+ /*keine Duplikate*/
+ return 0;
+gleich: /* Duplikat */
+ return j;
+}
+
+Static boolean duplikat(i)
+long i;
+{/* zu kleine Abmessungen oder volles Duplikat */
+ long j;
+
+ if (zukleineselement(i)==true)
+ return true;
+ if ( (j=duplikat0(i,true))==0)
+ return false;
+ loescheelement(i);
+ return true;
+}
+
+Static Void kopeinel(elsel, xr1, yr1, dx, dy, v, cd, sd, kop, loeschen)
+long elsel;
+double xr1, yr1, dx, dy, v, cd, sd;
+boolean kop; long loeschen;
+{
+ long i;
+
+ if (kop==true) { /*kopieren*/
+ freieselement(&i);
+ kopunv(elsel, i);
+ } else { /*verschieben*/
+ i = elsel;
+ if (loeschen==1) ausel(i, erase);
+ zeichnen = true;
+ }
+ switch (typ[i]) {
+
+ case ttext: /*Text*/
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v);
+ setzewinkel(i, xb1[i], yb1[i], xb2[i], yb2[i]);
+ textparam(i);
+ break;
+
+ case tgerade:
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v);
+ break;
+
+ case trechteckgef:
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v);
+ /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/
+ break;
+
+ case tdreieckgef:
+ case tviereckgef:
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v);
+ break;
+
+ case tkreis:
+ case tkreisgef:
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ laenge1[i] *= v;
+ laenge2[i] *= v;
+ break;
+
+ case tkreisbogen:
+ case tkreissektorgef:
+ drehkbogen(i, xr1, yr1, dx, dy, cd, sd, v);
+ break;
+
+ case tell:
+ case tellgef:
+ drehell(i, xr1, yr1, dx, dy, cd, sd, v);
+ break;
+
+ case tellbogen:
+ case tellsektorgef:
+ drehellbogen(i, xr1, yr1, dx, dy, cd, sd, v);
+ break;
+
+ case tbezier:
+ case tbeziergef:
+ drehpunkt1(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunkt2(i, xr1, yr1, dx, dy, cd, sd, v);
+ drehpunktb(i, xr1, yr1, dx, dy, cd, sd, v);
+ break;
+ }/*case*/
+ if (kop==true) { /*kopieren*/
+ bestimmeneuegruppe(i);
+ if (duplikat(i)==false) {
+ berechneminmax(i);
+ ausel(i, paint);
+ }
+ }
+ else /*verschieben*/
+ berechneminmax(i);
+ ausel(i, paint);
+}
+
+
+Static boolean testkop(elsel, relsel, zelsel, kop)
+long elsel, relsel, zelsel;
+boolean kop;
+{
+ if (kop==true) /*Referenzstrecke und Zielstrecke mitkopieren*/
+ return (elsel != 0);
+ else /*Referenzstrecke und Zielstrecke nicht verschieben*/
+ if (elsel != 0 && elsel != zelsel && elsel != relsel) return true;
+ else return false;
+}
+
+
+Static Void kopel(xanf, yanf, xend, yend, xr1, yr1, dx, dy, v, cd, sd, msel,
+ kop, relsel, zelsel)
+double xanf, yanf, xend, yend, xr1, yr1, dx, dy, v, cd, sd;
+long *msel;
+boolean kop;
+long relsel, zelsel;
+{
+ long elsel,elselmin,zelmaxalt;
+
+ elselmin = 1;
+ while (blinkelemente(xanf, yanf, xend, yend,elselmin) == true) {
+ if (kop == true)
+ gruppenumbenennen();
+ zelmaxalt = zelmax;
+ for (elsel=elselmin;elsel <= zelmaxalt; elsel++) {
+ if (blink[elsel] == true) {
+ if (testkop(elsel, relsel, zelsel, kop)==true) {
+ kopeinel(elsel, xr1, yr1, dx, dy, v, cd, sd, kop, 1L);
+ }
+ }
+ }
+ unbenutztegruppenfreigeben();
+ if (xanf == xend) { /*Ein Element angeklickt*/
+ blinkenaus();
+ return;
+ }
+ /* Auswahlrechteck, evtl. neue Elemente darin */
+ elselmin = zelmaxalt+1;
+ if (tastegedrueckt()!=0) return;
+ } /*while */
+}
+
+
+Static long abbundkopieren(x,y,xanf,yanf,xend,yend,taste,msel,phase,kop)
+long *msel,phase,taste;
+double x,y,xanf,yanf,xend,yend;
+boolean kop;
+{
+ static long relsel, zelsel;
+ double x1r, y1r, x1z, y1z, dx, dy, dr, dz, v, cr, sr, cz, sz, cd, sd;
+
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ }
+ L0:
+ /* kompakt(); */
+ strcpy(pr4, pr2menue[*msel]);
+ return 1;
+ L1:
+ sucheelement((long)nurgerade, &relsel, xanf, yanf);
+ if (relsel==0) return 1;
+ dr = ppabstand(x1[relsel], y1_[relsel], x2[relsel], y2[relsel]);
+ if (dr == 0.0) return 1;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ sucheelement((long)nurgerade, &zelsel, xanf, yanf);
+ if (zelsel==0) return 2;
+ dz = ppabstand(x1[zelsel], y1_[zelsel], x2[zelsel], y2[zelsel]);
+ if (dz == 0.0) return 2;
+ strcpy(pr4," object(s)?");
+ return 3;
+ L3:
+ x1r = x1[relsel];
+ y1r = y1_[relsel];
+ x1z = x1[zelsel];
+ y1z = y1_[zelsel];
+ dx = x2[zelsel] - x1[zelsel];
+ dy = y2[zelsel] - y1_[zelsel];
+ dz = ppabstand(x1[zelsel], y1_[zelsel], x2[zelsel], y2[zelsel]);
+ dr = ppabstand(x1[relsel], y1_[relsel], x2[relsel], y2[relsel]);
+ v = dz / dr;
+ cz = dx / dz;
+ sz = dy / dz;
+ dx = x2[relsel] - x1[relsel];
+ dy = y2[relsel] - y1_[relsel];
+ cr = dx / dr;
+ sr = dy / dr;
+ addtheorem(cz, sz, cr, -sr, &cd, &sd); /*wz-wr*/
+ kopel(xanf, yanf, xend, yend, x1r, y1r, x1z, y1z, v, cd, sd, msel, kop,
+ relsel, zelsel);
+ return 3;
+}
+
+Static long translundkopieren(x,y,xanf,yanf,xend,yend,taste,msel,phase,kop)
+long *msel,phase,taste;
+double x,y,xanf,yanf,xend,yend;
+boolean kop;
+{
+ long i, elsel;
+ static long relsel;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ }
+ L0:
+ freieselement(&relsel);
+ strcpy(pr4," object(s)?");
+ return 1;
+ L1:
+ if (blinkelemente(xanf,yanf,xend,yend,1L) == false)
+ return 1;
+ blinkend = true;
+ if (xanf == xend) {/* ein Element war selektiert */
+ x1[relsel] = x;
+ y1_[relsel] = y;
+ strcpy(pr4, pr3menue[mkopbewmaus]);
+ return 3;
+ }
+ /* Auswahlrechteck war gegeben */
+ strcpy(pr4, pr2menue[mkopbewmaus]);
+ return 2;
+ L2:
+ /*Referenzpunkt angeben*/
+ x1[relsel] = x;
+ y1_[relsel] = y;
+ strcpy(pr4, pr3menue[mkopbewmaus]);
+ return 3;
+ L3:
+ if (kop==true)
+ gruppenumbenennen();
+ /*Zielpunkt angeben*/
+ for (elsel = 1; elsel <= zelmax; elsel++) {
+ if (blink[elsel] == true)
+ kopeinel(elsel, x1[relsel], y1_[relsel], x, y, 1.0, 1.0, 0.0, kop,1L);
+ }
+ if (kop==true)
+ return 3;
+ strcpy(pr4," object(s)?");
+ blinkenaus();
+ return 1;
+}
+
+
+Static long kopieren(x,y,xa,ya,xe,ye,taste,msel,phase)
+long *msel,phase,taste;
+double x,y,xa,xe,ya,ye;
+{
+ if (selmenue[mkopbewmaus]==true)
+ phase=translundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,true);
+ else
+ phase=abbundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,true);
+ return phase;
+}
+
+
+Static long bewegen(x,y,xa,ya,xe,ye,taste,msel,phase)
+long *msel,phase,taste;
+double x,y,xa,xe,ya,ye;
+{
+ if (selmenue[mkopbewmaus]==true)
+ phase=translundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,false);
+ else
+ phase=abbundkopieren(x,y,xa,ya,xe,ye,taste,msel,phase,false);
+ return phase;
+}
+
+Static long rotieren(x,y,xanf,yanf,xend,yend,taste,msel,phase)
+long *msel,phase,taste;
+double x,y,xanf,yanf,xend,yend;
+/* Rotation ein Objekt, eine Gruppe um den Anklickpunkt*/
+{
+ double xr,yr,xz,yz,v,cd,sd,wi;
+ long elsel, elselmin;
+ boolean kop;
+ static boolean auswrechteck;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ auswrechteck = false;
+ return 1;
+ L1:
+ if (blinkelemente(xanf,yanf,xend,yend,1L) == false)
+ return 1;
+ blinkend = true;
+ if (xanf == xend) /* ein Element war selektiert */
+ goto L2;
+ /* Auswahlrechteck war gegeben, Drehpunkt abfragen */
+ auswrechteck = true;
+ strcpy(pr4, pr3menue[mrot]);
+ return 2;
+ L2:
+ /*Drehpunkt jetzt bekannt*/
+ v = 1.0;
+ xr = x;
+ yr = y;
+ xz = xr;
+ yz = yr;
+ wi= winkelrotate;
+ wi = wi*pi/180.0;
+ cd = cos(wi);
+ sd = sin(wi);
+ kop = false;
+ for (elsel=1;elsel <= zelmax; elsel++) {
+ if (blink[elsel] == true) {
+ kopeinel(elsel, xr, yr, xz, yz, v, cd, sd, kop, 1L);
+ }
+ }
+ if (auswrechteck == false) {
+ /* kein Auswahlrechteck, neue Objekte selektieren */
+ strcpy(pr4,pr2menue[mrot]);
+ blinkenaus();
+ return 1;
+ }
+ /* Auswahlrechteck vorhanden, neue Drehung?? */
+ return 2;
+}
+
+Static long vorber_export(x,y,xa,ya,xe,ye,taste,msel,phase)
+long *msel,phase,taste;
+double x,y,xa,xe,ya,ye;
+{
+ long i, elsel;
+ static long kmark, relsel;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ XSetSelectionOwner(display,latexdraw_selection,win,requesttime);
+ if (XGetSelectionOwner(display,latexdraw_selection) != win)
+ { protokoll("XGetSelectionOwner"," failed"); return 0;}
+ freieselement(&relsel);
+ wartendexport = true;
+ kmark = 0; /*kmark, keine Objekte definiert */
+ export_relsel = relsel;
+ export_kmark = kmark;
+ strcpy(pr4, pr2menue[mcut]);
+ return 1;
+ L1:
+ /*Referenzpunkt angeben*/
+ x1[relsel] = x;
+ y1_[relsel] = y;
+ x2[relsel] = x;
+ y2[relsel] = y;
+ strcpy(pr4," object(s)?");
+ return 2;
+ L2:
+ strcpy(pr4," object(s)?");
+ if (blinkelemente(xa,ya,xe,ye,1L)== false){
+ if (kmark==0)
+ return 2;
+ }
+ else {
+ /* Elemente in der bisherigen Sequenz muessen unveraendert bleiben */
+ for (elsel = 1; elsel <= zelmax; elsel++) {
+ if (blink[elsel] == true) {
+ /* schon vorhanden ? */
+ for (i=1;i <=kmark;i++) {
+ if (sequenz[i] == elsel)
+ goto LL;
+ }
+ kmark++;
+ sequenz[kmark] = elsel;
+ }
+ LL:;
+ } /*for*/
+ }
+ blinkend = true;
+ /*alle Blinkelemente wieder setzen */
+ for (i=1;i <= kmark;i++)
+ blink[sequenz[i]] = true;
+ export_kmark = kmark;
+ return 2;
+}
+
+Static Void event_senden(r)
+long r;
+{ XEvent sendevent;
+ sendevent.xselection.type=selnotify[r].type;
+ sendevent.xselection.requestor=selnotify[r].requestor;
+ sendevent.xselection.selection=selnotify[r].selection;
+ sendevent.xselection.target=selnotify[r].target;
+ sendevent.xselection.property=selnotify[r].property;
+ sendevent.xselection.time=selnotify[r].time;
+
+XSendEvent(display,selnotify[r].requestor,True,NoEventMask,
+ &sendevent);
+}
+
+Static Void exportieren()
+{ long r, kakt,relsel,i,kmark,ls1,ls2;
+ char s1[255],s2[255];
+
+ if (selmenue[mcut]==false){ /* nichts geht mehr zurueck */
+ for (r=0;r<zrequw;r++) {
+ if (requestaktiv[r]==true && requestbelegt[r]==true){
+ selnotify[r].property=None;
+ event_senden(r);
+ }
+ requestbelegt[r]=false;
+ }
+ wartendexport=false;
+ return;
+ }
+
+ relsel=export_relsel; /* von vorber_export */
+ kmark=export_kmark; /* von vorber_export */
+ /* wenn nichts da, dann bleibt Wunsch stehen. Durch zyklischen Aufruf
+ in der Eventschleife werden alle Objekt gesendet, die bereits
+ definiert sind oder noch definiert werden */
+ for (r=0;r<zrequw;r++) {
+ if (requestaktiv[r]==true && requestbelegt[r]==true){
+ kakt=requestkakt[r];
+ if (kakt < kmark) { /* ewas zu senden da */
+ requestaktiv[r]=false;
+ requestkakt[r] += 1;
+ kakt++;
+ i = sequenz[kakt];
+ sprintf(s1,
+"%.3lf %.3lf %.3lf %.3lf %ld %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %ld %ld %ld %.3lf %.3lf %.3lf\n",
+ x1[relsel],y1_[relsel],x2[relsel],y2[relsel],
+ typ[i],x1[i],y1_[i],x2[i],y2[i],xb1[i],yb1[i],xb2[i], yb2[i],
+ wanf[i],wend[i],linedicke[i],lineende[i],linetype[i],
+ laenge1[i],laenge2[i],rotwi[i]);
+ ls1=strlen(s1);
+ XChangeProperty(display,selnotify[r].requestor,latexdraw_object,
+ latexdraw_object,8,PropModeReplace,s1,ls1);
+ if (typ[i] == ttext) { /*text*/
+ sprintf(s2, "%s\n", texte[textno[i]]);
+ ls2=strlen(s2);
+ XChangeProperty(display,selnotify[r].requestor,latexdraw_text,
+ latexdraw_text,8,PropModeReplace,s2,ls2);
+ }
+ event_senden(r);
+ } /*if kakt < kmark */
+ } /* if requestaktiv */
+ }/* for r*/
+}
+
+
+Static Void request_export(xsrrequestor,xsrproperty,xsrtarget,xsrtime)
+Window xsrrequestor;
+Atom xsrproperty,xsrtarget;
+Time xsrtime;
+{ /* Aufruf durch SelectionRequest */
+ long r;
+
+ /* gibt es noch alten request von dem requestor, dann nehmen */
+ for (r=0;r<zrequw;r++) {
+ if (requestbelegt[r]==true) {
+ if (xsrrequestor == selnotify[r].requestor) {
+ if (xsrtime > selnotify[r].time) goto L0;
+ goto L1;
+ }
+ }
+ }
+
+ /* Neueintrag in offene Requests */
+ for (r=0;r<zrequw;r++) {
+ if (requestbelegt[r]==false) goto L0;}
+ protokoll("too many requests:", "request ignored");
+ return;
+
+ L0:
+ requestbelegt[r]=true;
+ requestkakt[r]=0;
+ L1:
+ requestaktiv[r]=true;
+ selnotify[r].type=SelectionNotify;
+ selnotify[r].requestor=xsrrequestor;
+ selnotify[r].selection=latexdraw_selection;
+ selnotify[r].target=xsrtarget;
+ selnotify[r].property=xsrproperty;
+ selnotify[r].time=xsrtime;
+ exportieren();
+}
+
+
+Static long vorber_import(x,y,taste,msel,phase)
+long *msel,phase,taste;
+double x,y;
+{
+ long i, kmark, elsel;
+ static long zelsel;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ requesttime=lasteventtime;
+ freieselement(&zelsel);
+ import_zelsel=zelsel;
+ strcpy(pr4, pr2menue[mpaste]);
+ return 1;
+ L1:
+ /*Zielpunkt angeben*/
+ x1[zelsel] = x;
+ y1_[zelsel] = y;
+ x2[zelsel] = x;
+ y2[zelsel] = y;
+ strcpy(pr4, " select objects in other window");
+ /* SelectionRequest beim anderen Fenster */
+ XConvertSelection(display,latexdraw_selection,latexdraw_object,
+ latexdraw_object, win, requesttime);
+ L2:
+ return 2;
+}
+
+Static Void deleteprop()
+{ XDeleteProperty(display,win, latexdraw_object);
+ XDeleteProperty(display,win, latexdraw_text);
+}
+
+Static Void importieren(xsnproperty, xsntime, msel)
+Atom xsnproperty; Time xsntime; long *msel;
+{ /* Aufruf durch SelectionNotify */
+ long zelsel, i, k, ls1, ls2, bytesafter,anz;
+ Atom actualtype;
+ double xr1,yr1,xr2,yr2;
+ unsigned char *data;
+ int actualformat;
+
+ if (xsnproperty==None){
+ if (requesttime != xsntime) return;
+ if (selmenue[mpaste]==false) return;
+ selmenloeschen(msel);
+ return;
+ }
+ if (selmenue[mpaste]==false) {deleteprop(); return;}
+ if (requesttime != xsntime) {deleteprop(); return;}
+ zelsel=import_zelsel; /* von Vorbereiten import */
+ XGetWindowProperty(display, win, latexdraw_object,0,70,True,
+ latexdraw_object,&actualtype, &actualformat,
+ &ls1, &bytesafter,&data);
+ freieselement(&i);
+ anz=sscanf(data,
+ "%lg%lg%lg%lg%ld%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%ld%ld%ld%lg%lg%lg",
+ &xr1,&yr1,&xr2,&yr2,
+ &typ[i], &x1[i], &y1_[i], &x2[i], &y2[i], &xb1[i], &yb1[i],
+ &xb2[i], &yb2[i], &wanf[i], &wend[i], &linedicke[i],
+ &lineende[i], &linetype[i], &laenge1[i], &laenge2[i], &rotwi[i]);
+ XFree(data);
+ if ((typ[i] <= 0)|| (anz != 21)) {typ[i]=0; goto L0;}
+ if (rotwi[i] != 0.0) {
+ crw[i] = cos(rotwi[i] * fgradbo);
+ srw[i] = sin(rotwi[i] * fgradbo);
+ }
+ switch (typ[i]) {
+
+ case tgerade:
+ laenge1[i] = ppabstand(x1[i], y1_[i], x2[i], y2[i]);
+ laenge2[i] = laenge1[i];
+ break;
+
+ case trechteckgef:
+ /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/
+ break;
+
+ case tellbogen:
+ case tellsektorgef:
+ ellanfendpunkt(i);
+ break;
+
+ case tkreisbogen:
+ case tkreissektorgef:
+ kreisanfendpunkt(i);
+ break;
+
+ case ttext:
+ freiestextel(&k);
+ textno[i] = k;
+ XGetWindowProperty(display, win, latexdraw_text,0,70,True,
+ latexdraw_text,&actualtype, &actualformat,
+ &ls2, &bytesafter,&data);
+ strcpy(texte[k],data);
+ XFree(data);
+ textparam(i);
+ break;
+ }/*case*/
+ kopeinel(i, xr1,yr1,x1[zelsel], y1_[zelsel], 1.0, 1.0, 0.0,false,0L);
+ duplikat(i);
+ L0:
+ deleteprop();
+ /* neuen Request vorsichtshalber absetzen */
+ XConvertSelection(display,latexdraw_selection,latexdraw_object,
+ latexdraw_object, win, requesttime);
+}
+
+
+Static Void eldelete(elsel)
+long elsel;
+{
+ ausel(elsel, erase);
+ typ[elsel] = -typ[elsel];
+}
+
+
+Static Void UnDelete()
+{
+ long i, phase;
+
+ for (i = 1; i <= zelmax; i++) {
+ if (typ[i] < -1) {
+ typ[i] = -typ[i];
+ } /*if*/
+ }
+ auselemente();
+}
+
+
+Static long loeschen(xanf,yanf,xend,yend,taste,msel,phase)
+ long *msel,phase,taste;
+ double xanf,yanf,xend,yend;
+{
+ long elsel;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ strcpy(pr4, " UNDO = backspace oder delete oder undo");
+ return 1;
+ L1:
+ if (blinkelemente(xanf,yanf,xend,yend,1L)== false)
+ return 1;
+ for (elsel = 1; elsel <= zelmax; elsel++) {
+ if (blink[elsel] == true) {
+ if (group[elsel] != 0)
+ aenderunggruppen = true;
+ eldelete(elsel);
+ }
+ }
+ auselemente ();
+ return 1;
+} /*loeschen*/
+
+
+Static Void vorbsortieren()
+/* Vorbereiten Sortieren der Zeichnungselemente */
+/* sequenz enthaelt Sortierreihenfolge */
+/* Vorbereiten = jetzige Reihenfolge */
+{long i;
+ for (i=1; i<= zelmax; i++) {
+ if (typ[i] !=0) sequenz[i]=i;
+ else sequenz[i]= 3*zelmax;
+ }
+}
+
+Static Void sortieren()
+/* Sortieren der Zeichnungselemente gemaess sequenzwert */
+{ long i,j,temp;
+ if (typ[zel]!=0) fehler(10L); /*letztes Element muesste frei sein ! */
+ temp=zel;
+ /* nur im Bereich belegte Elemente sortieren */
+ for (i=1;i<=zelmax;i++) {
+ for (j=zelmax;j>i;j--) {
+ if (sequenz[j] < sequenz[i]) {
+ kopunvotext(i,temp);
+ kopunvotext(j,i);
+ kopunvotext(temp,j);
+ }
+ }
+ }
+ typ[temp]=0;
+}
+
+Static long up(xanf,yanf,xend,yend,taste,msel,phase)
+ long *msel,phase,taste;
+ double xanf,yanf,xend,yend;
+{/* Elemente in Vordergrund bringen */
+ long elsel, maxnr;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ return 1;
+ L1:
+ maxnr = zelmax;
+ if (blinkelemente(xanf,yanf,xend,yend,1L)== false)
+ return;
+ vorbsortieren();
+ for (elsel=zelmax; elsel >= 1; elsel--) {
+ if (blink[elsel] == true )
+ sequenz[elsel] = ++maxnr;
+ }
+ sortieren();
+ auselemente();
+ return 1;
+} /*end up*/
+
+
+Static long down(xanf,yanf,xend,yend,taste,msel,phase)
+ long *msel,phase,taste;
+ double xanf,yanf,xend,yend;
+{/* Elemente in Vordergrund bringen */
+ long elsel, maxnr;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ return 1;
+ L1:
+ maxnr = -zelmax-1;
+ if (blinkelemente(xanf,yanf,xend,yend,1L)== false)
+ return;
+ vorbsortieren();
+ for (elsel=1;elsel<=zelmax; elsel++) {
+ if (blink[elsel] ==true)
+ sequenz[elsel] = ++maxnr;
+ }
+ sortieren();
+ auselemente();
+ return 1;
+} /*end up*/
+
+Static Void elchangelineattr(elsel)
+long elsel;
+{ long ltyp1, ldicke1, lende1, lcolor1;
+ long ltyp2, ldicke2, lende2, lcolor2;
+ getlineattribute(elsel, typ[elsel], &ltyp1, &ldicke1, &lende1, &lcolor1);
+ ausel(elsel, erase);
+ getlineattribute(0L, typ[elsel], &ltyp2, &ldicke2, &lende2, &lcolor2);
+ if (changelende == true)
+ lineende[elsel] = lende2;
+ if ((changelstyle == true)&&(typ[elsel] != ttext))
+ linetype[elsel] = ltyp2;
+ if (changelwidth == true)
+ ldicke1 = ldicke2;
+ if (changecolor == true)
+ lcolor1 = lcolor2;
+ linedicke[elsel] = 100*lcolor1+ldicke1;
+ if ((typ[elsel] == ttext)&&(changefont == true)) {
+ linetype[elsel] = fontnummer;
+ textparam(elsel);
+ berechneminmax(elsel);
+ }
+ if ((typ[elsel] == ttext)&&(changeposition == true))
+ setlagetext(elsel);
+ zeichnen = true;
+}
+
+Static long changelineattr(xanf,yanf,xend,yend,taste,msel,phase)
+ long *msel,phase,taste;
+ double xanf,yanf,xend,yend;
+{/* Farbe Elemente veraendern*/
+ long elsel;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ /* nur aendern, falls nach chatt entspr. Element angeklickt wurde*/
+ changelende = false;
+ changelstyle = false;
+ changelwidth = false;
+ changecolor = false;
+ changefont = false;
+ changeposition = false;
+ return 1;
+ L1:
+ if (blinkelemente(xanf,yanf,xend,yend,1L)==false)
+ return 1;
+ for (elsel=1; elsel <= zelmax; elsel++) {
+ if (blink[elsel] == true)
+ elchangelineattr(elsel);
+ } /*for elsel*/
+ auselemente();
+ return 1;
+} /*end changelineattr*/
+
+Static long queryattr(xanf,yanf,taste,msel,phase)
+ long *msel,phase,taste;
+ double xanf,yanf;
+{/* Farbe eines Elements erfragen und einstellen */
+ long elsel, ltyp, lende;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ return 1;
+ L1:
+ if (blinkelemente(xanf,yanf,xend,yend,1L)== true) {
+ for (elsel=1;elsel<=zelmax; elsel++) {
+ if (blink[elsel] ==true){
+ getlineattribute(elsel, typ[elsel], &ltyp, &aktldicke, &lende,
+ &aktcolor);
+ strichsymbol();
+ ausmenueelement(mdick);
+ colorsymbol();
+ ausmenueelement(mcolor);
+ if (typ[elsel]==ttext)
+ setzeakttextfont(elsel);
+ return 1;
+ }
+ }
+ }
+ return 1;
+} /*end welchefarbe*/
+
+
+
+
+Static Void spgp(xg, yg, dx, dy, xp, yp)
+double xg, yg, dx, dy, *xp, *yp;
+{
+ double xs, ys;
+ boolean g;
+
+ /*Geradendefinition durch xg,yg,dx,dy*/
+ g = lot(xg, yg, dx, dy, *xp, *yp, &xs, &ys);
+ *xp += 2.0 * (xs - *xp);
+ *yp += 2.0 * (ys - *yp);
+}
+
+
+Static Void spg1(i, xg, yg, dx, dy)
+long i;
+double xg, yg, dx, dy;
+{
+ spgp(xg, yg, dx, dy, &x1[i], &y1_[i]);
+}
+
+
+Static Void spg2(i, xg, yg, dx, dy)
+long i;
+double xg, yg, dx, dy;
+{
+ spgp(xg, yg, dx, dy, &x2[i], &y2[i]);
+}
+
+
+Static Void spgb(i, xg, yg, dx, dy)
+long i;
+double xg, yg, dx, dy;
+{
+ spgp(xg, yg, dx, dy, &xb1[i], &yb1[i]);
+ spgp(xg, yg, dx, dy, &xb2[i], &yb2[i]);
+}
+
+
+Static Void spgell0(i, xg, yg, dx, dy)
+long i;
+double xg, yg, dx, dy;
+{
+ double xl, yl, lx, ly;
+
+ lx = laenge1[i];
+ ly = laenge2[i];
+ ell_xy(x1[i], y1_[i], lx, ly, crw[i], srw[i], lx, 0.0, &xl, &yl);
+ spgp(xg, yg, dx, dy, &xl, &yl);
+ /*gespiegelter Endpunkt x_Achse der Ellipse*/
+ spg1(i, xg, yg, dx, dy);
+ setzewinkel(i, x1[i], y1_[i], xl, yl);
+}
+
+
+Static Void spgell(i, xg, yg, dx, dy)
+long i;
+double xg, yg, dx, dy;
+{
+ spgell0(i, xg, yg, dx, dy);
+}
+
+
+Static Void spgellbogen(i, xg, yg, dx, dy)
+long i;
+double xg, yg, dx, dy;
+{
+ double xm, ym, lx, ly, cr, sr;
+
+ lx = laenge1[i];
+ ly = laenge2[i];
+ ftausch(&xb1[i], &xb2[i]);
+ ftausch(&yb1[i], &yb2[i]);
+ spgb(i, xg, yg, dx, dy);
+ spgell0(i, xg, yg, dx, dy);
+ xm = x1[i];
+ ym = y1_[i];
+ cr = crw[i];
+ sr = srw[i];
+ wanf[i] = winkelell(xm, ym, lx, ly, cr, sr, xb1[i], yb1[i]);
+ wend[i] = winkelell(xm, ym, lx, ly, cr, sr, xb2[i], yb2[i]);
+ ellanfendpunkt(i);
+}
+
+
+Static Void spgkbogen(i, xg, yg, dx, dy)
+long i;
+double xg, yg, dx, dy;
+{
+ ftausch(&xb1[i], &xb2[i]);
+ ftausch(&yb1[i], &yb2[i]);
+ spgb(i, xg, yg, dx, dy);
+ spg1(i, xg, yg, dx, dy);
+ wanf[i] = winkelk(x1[i], y1_[i], xb1[i], yb1[i]);
+ wend[i] = winkelk(x1[i], y1_[i], xb2[i], yb2[i]);
+}
+
+
+Static Void einelspiegeln(elsel, xg, yg, dx, dy)
+long elsel;
+double xg, yg, dx, dy;
+{
+ long i;
+
+ freieselement(&i);
+ kopunv(elsel, i);
+ switch (typ[i]) {
+
+ case ttext:
+ spg1(i, xg, yg, dx, dy);
+ spg2(i, xg, yg, dx, dy);
+ spgb(i, xg, yg, dx, dy);
+ setzewinkel(i, xb1[i], yb1[i], xb2[i], yb2[i]);
+ textparam(i);
+ break;
+
+ case tgerade:
+ spg1(i, xg, yg, dx, dy);
+ spg2(i, xg, yg, dx, dy);
+ break;
+
+ case trechteckgef:
+ spg1(i, xg, yg, dx, dy);
+ spg2(i, xg, yg, dx, dy);
+ spgb(i, xg, yg, dx, dy);
+ /*setzewinkel(i, x1[i], y1_[i], xb1[i], yb1[i]);*/
+ break;
+
+ case tdreieckgef:
+ case tviereckgef:
+ spg1(i, xg, yg, dx, dy);
+ spg2(i, xg, yg, dx, dy);
+ spgb(i, xg, yg, dx, dy);
+ break;
+
+ case tkreis:
+ case tkreisgef:
+ spg1(i, xg, yg, dx, dy);
+ break;
+
+ case tkreisbogen:
+ case tkreissektorgef:
+ spgkbogen(i, xg, yg, dx, dy);
+ break;
+
+ case tell:
+ case tellgef:
+ spgell(i, xg, yg, dx, dy);
+ break;
+
+ case tellbogen:
+ case tellsektorgef:
+ spgellbogen(i, xg, yg, dx, dy);
+ break;
+
+ case tbezier:
+ case tbeziergef:
+ spg1(i, xg, yg, dx, dy);
+ spg2(i, xg, yg, dx, dy);
+ spgb(i, xg, yg, dx, dy);
+ break;
+ }/*case*/
+ bestimmeneuegruppe(i);
+ if (duplikat(i)==false) {
+ berechneminmax(i);
+ ausel(i, paint);
+ }
+} /*einelspiegeln*/
+
+
+Static Void elspiegeln(xanf, yanf, xend, yend, xg, yg, dx, dy)
+double xanf, yanf, xend, yend, xg, yg, dx, dy;
+{
+ long elsel;
+
+ if (blinkelemente(xanf, yanf, xend, yend, 1L) == false )
+ return;
+ gruppenumbenennen();
+ for (elsel=1;elsel <=zelmax;elsel++) {
+ if (blink[elsel] == true) {
+ einelspiegeln(elsel, xg, yg, dx, dy);
+ }
+ }
+ unbenutztegruppenfreigeben();
+} /*elspiegeln*/
+
+
+Static long spiegeln(x,y,xanf,yanf,xend,yend,taste,msel,phase)
+long *msel,taste,phase;
+double x,y,xanf,yanf,xend,yend;
+{
+ static long elselg;
+ double xg, yg, dx, dy;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ strcpy(pr4, pr2menue[*msel]);
+ return 1;
+ L1:
+ sucheelement((long)nurgerade, &elselg, xanf, yanf);
+ if (elselg==0) return 1;
+ strcpy(pr4,pr3menue[*msel]);
+ return 2;
+ L2:
+ dx = x2[elselg] - x1[elselg];
+ dy = y2[elselg] - y1_[elselg];
+ xg = x1[elselg];
+ yg = y1_[elselg];
+ elspiegeln(xanf, yanf, xend, yend, xg, yg, dx, dy);
+ return 2;
+}
+
+
+Static long einpolygon(x,y,taste,msel,phase)
+ long *msel,taste,phase;
+ double x,y;
+{
+ double r, dwi, cd, sd, cwi, swi, xx1, yy1, xx2, yy2;
+ static long elsel;
+ long n, k, anz;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ default: goto L3;
+ }
+ L0:
+ freieselement(&elsel);
+ return 1;
+ L1:
+ x1[elsel] = x;
+ y1_[elsel] = y;
+ strcpy(pr3,nullstr);
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ r = ppabstand(x, y, x1[elsel], y1_[elsel]);
+ if (r < 2.0) r = 2.0;
+ laenge1[elsel]=r;
+ L2B:
+ if (selmenue[mverbunden]==true)
+ strcpy(pr3, "(connected) ");
+ else
+ strcpy(pr3, nullstr);
+ strcpy(pr4,nullstr);
+ inittastaturtext(nullstr, " number of edges?",1L);
+ return 3;
+ L3:
+ if (istnullstr(EinText) == true) goto L4;
+ anz=sscanf(EinText,"%ld",&n);
+ if ((anz!=1)|| (n == 0) || (n < 3)) goto L2B;
+ r=laenge1[elsel];
+ dwi = pi / n;
+ cd = cos(dwi);
+ sd = sin(dwi);
+ /*Anfang Winkel 0*/
+ cwi = 1.0;
+ swi = 0.0;
+ addtheorem(cd, sd, cd, sd, &cd, &sd); /*Winkel verdoppeln*/
+ xx1 = x1[elsel] + r * cwi;
+ yy1 = y1_[elsel] + r * swi;
+ for (k = 1; k <= n; k++) {
+ addtheorem(cd, sd, cwi, swi, &cwi, &swi);
+ xx2 = x1[elsel] + r * cwi;
+ yy2 = y1_[elsel] + r * swi;
+ if (selmenue[mverbunden]==true)
+ createline(0L, x1[elsel], y1_[elsel], xx2, yy2);
+ createline(0L, xx1, yy1, xx2, yy2);
+ xx1 = xx2;
+ yy1 = yy2;
+ }
+ L4:
+ strcpy(pr3,nullstr);
+ strcpy(pr4,pr2menue[*msel]);
+ return 1;
+} /*Polygon*/
+
+Static Void size_change(display,ix,iy)
+ Display *display;
+ long ix,iy;
+{ double xmalt,ymalt,dxm,dym;
+
+ ixzmax=ix;
+ xzmax=ix;
+ iyzmax=iy;
+ yzmax= iy;
+ xmalt = xmittelzei;
+ ymalt = ymittelzei;
+ xmittelzei = (xzmax - xgr) / 2.0 + xgr;
+ ymittelzei = (yzmax - yprompt - 12.0) / 2.0 + yprompt + 12.0;
+ setze_clip_bereiche(display);
+ /* fuer readstdin vermerken, welche Skalierungen durchgef"uhrt wurden */
+ dxm = xmalt-xmittelzei;
+ dym = ymalt-ymittelzei;
+ readdxx = readdxx + dxm*(1.0-readf);
+ readdyy = readdyy + dym*(1.0-readf);
+ /* Ende dieser Vermerke */
+}
+
+
+Static Void initmisc()
+{
+ long i;
+ xmittelzei = (xzmax - xgr) / 2.0 + xgr;
+ ymittelzei = (yzmax - yprompt - 12.0) / 2.0 + yprompt + 12.0;
+ fgradbo = pi / wh;
+ fbograd = wh / pi;
+
+ *nullstr = '\0';
+
+ strcpy(textausrichtung[0], "[bl]");
+ strcpy(textausrichtung[1],nullstr);
+ strcpy(textausrichtung[2], "[br]");
+ strcpy(textausrichtung[3], "[b]");
+ strcpy(textausrichtung[4], "[tl]");
+ strcpy(textausrichtung[5], "[tr]");
+ strcpy(textausrichtung[6], "[t]");
+ strcpy(textausrichtung[7], "[l]");
+ strcpy(textausrichtung[8], "[r]");
+}
+
+Static Void initcutpaste()
+{
+ long i;
+ wartendexport=false;
+ requesttime = 0;
+ lasteventtime = 0;
+ for (i=0;i<zrequw;i++) requestbelegt[i]=false;
+ latexdraw_object=XInternAtom(display,"latexdraw_object",False);
+ latexdraw_text =XInternAtom(display,"latexdraw_text",False);
+ latexdraw_selection =XInternAtom(display,"latexdraw_selection",False);
+}
+
+
+Static Void gell00schnittp(xx1,yy1,xx2,yy2,elsel,anz,wgerade,well,instrecke)
+long elsel, *anz;
+double xx1,yy1,xx2,yy2;
+double *wgerade, *well;
+boolean instrecke;
+{
+ double dx, dy, xm, ym, lx, ly, cr, sr, wwg, wwell, px,
+ py, a2, a1, a0;
+ long i, anzl;
+ terg wgl;
+
+ ellpar(elsel, &xm, &ym, &lx, &ly, &cr, &sr);
+ xy_ell(xm, ym, cr, sr, xx1, yy1, &xx1, &yy1);
+ xy_ell(xm, ym, cr, sr, xx2, yy2, &xx2, &yy2);
+ dx = xx2 - xx1;
+ dy = yy2 - yy1;
+ a2 = dx * dx / (lx * lx) + dy * dy / (ly * ly);
+ a1 = 2.0 * (xx1 * dx / (lx * lx) + yy1 * dy / (ly * ly));
+ a0 = xx1 * xx1 / (lx * lx) + yy1 * yy1 / (ly * ly) - 1.0;
+ glzweiterord(a2, a1, a0, &anzl, wgl);
+ *anz = 0;
+ for (i = 1; i <= anzl; i++) {
+ wwg = wgl[i];
+ if (instrecke == true) {
+ /* Pruefung, ob Schnittpunkt in Strecke*/
+ if ( (wwg < -0.1) || (wwg > 1.1) )
+ goto weiter; /* kein Schnittpunkt */
+ }
+
+ px = xx1 + dx * wwg;
+ py = yy1 + dy * wwg;
+ wwell = winkel0(px, py, lx, ly); /* w fuer Ellipse */
+ if (si_fabs(wwell - wanf[elsel]) < 0.1)
+ wwell = wanf[elsel];
+ if (si_fabs(wwell - wend[elsel]) < 0.1)
+ wwell = wend[elsel];
+ (*anz)++;
+ wgerade[*anz] = wwg;
+ well[*anz] = wwell;
+ if ((typ[elsel] == tkreisbogen || typ[elsel] == tellbogen ||
+ typ[elsel] == tkreissektorgef ||
+ typ[elsel] == tellsektorgef) &&
+ (inwinkel(elsel, wwell)==false))
+ /* Punkt ist doch kein Schnittpunkt */
+ (*anz)--;
+ weiter:;
+ } /*for*/
+}
+
+Static Void gell0schnittp(elselg,elsel,anz,wgerade,well,instrecke)
+long elselg, elsel, *anz;
+double *wgerade, *well;
+boolean instrecke;
+{
+ double xx1, yy1, xx2, yy2;
+
+ xx1 = x1[elselg];
+ yy1 = y1_[elselg];
+ xx2 = x2[elselg];
+ yy2 = y2[elselg];
+ gell00schnittp(xx1,yy1,xx2,yy2,elsel,anz,wgerade,well,instrecke);
+}
+
+
+Static Void testwawe(wp, wa, we, w)
+double wp, *wa, *we, w;
+{
+ if (si_fabs(w - wp) <= 0.001)
+ /* der Schnittpunkt ist so nahe am Anclickpunkt, dass eine */
+ /* Entscheidung sinnlos ist, bzw. der Schnittpunkt igoriert werden */
+ /* sollte, insbesondere im Zusammenhang von connect, wo */
+ /* Grenzpunkte als Clickpunkte verwendet werden. */
+ return;
+ if ((w < wp) && (w > *wa))
+ *wa = w;
+ if ((w > wp) && (w < *we))
+ *we = w;
+}
+
+
+Static Void testxyell(elsel, elsel1, xx1, yy1, wp, wa, we)
+long elsel, elsel1;
+double xx1, yy1, wp, *wa, *we;
+{
+ double w1, w, xxp, yyp, xx, yy, xm1, ym1, lx1, ly1, cr1, sr1, xm, ym, lx,
+ ly, cr, sr;
+
+ ellpar(elsel, &xm, &ym, &lx, &ly, &cr, &sr); /*Bezugsellipse elselp*/
+ ellpar(elsel1, &xm1, &ym1, &lx1, &ly1, &cr1, &sr1);
+ w1 = winkel0(xx1, yy1, lx1, ly1);
+ ell_xy(xm1, ym1, lx1, ly1, cr1, sr1, xx1, yy1, &xxp, &yyp);
+ /*testkreis(xxp,yyp,7.0);*/
+ if (inwinkel(elsel1, w1)==false)
+ goto _L1;
+ w = winkelell(xm, ym, lx, ly, cr, sr, xxp, yyp);
+ /*testkreis(xxp,yyp,6.0);*/
+ if (inwinkel(elsel, w)==false)
+ goto _L1;
+ ellw_xy(xm, ym, lx, ly, cr, sr, w, &xx, &yy);
+ /*testkreis(xx,yy,5.0);*/
+ if (ppabstand(xxp, yyp, xx, yy) > 5.0)
+ goto _L1;
+ /*testkreis(xx,yy,3.0);*/
+ testwawe(wp, wa, we, w);
+ testwawe(wp, wa, we, w + wg);
+ testwawe(wp, wa, we, w - wg);
+_L1: ;
+}
+
+
+Static Void ellellschnittp(elselp, elsel1, wp, wa, we)
+long elselp, elsel1;
+double *wp, *wa, *we;
+{
+ long i, anz;
+ terg x1erg;
+ double xm1, ym1, lx1, ly1, cr1, sr1, xm, ym, lx, ly, cr, sr, qlv, axx, axy,
+ ax0, ayx, ayy, ay0, bxx, byy, bx, by, bxy, b, c4, c3, c2, c1, c0,
+ xx1, yy1;
+
+ ellpar(elselp, &xm, &ym, &lx, &ly, &cr, &sr);
+ ellpar(elsel1, &xm1, &ym1, &lx1, &ly1, &cr1, &sr1);
+ qlv = ly1 / lx1;
+ qlv *= qlv;
+ axx = (cr * cr1 + sr * sr1) / lx;
+ axy = (sr * cr1 - cr * sr1) / lx;
+ ax0 = (cr * (xm1 - xm) + sr * (ym1 - ym)) / lx;
+ ayx = (cr * sr1 - sr * cr1) / ly;
+ ayy = (sr * sr1 + cr * cr1) / ly;
+ ay0 = (sr * (xm - xm1) + cr * (ym1 - ym)) / ly;
+ bxx = axx * axx + ayx * ayx;
+ byy = axy * axy + ayy * ayy;
+ bx = 2.0 * (axx * ax0 + ayx * ay0);
+ by = 2.0 * (axy * ax0 + ayy * ay0);
+ bxy = 2.0 * (axx * axy + ayx * ayy);
+ b = ax0 * ax0 + ay0 * ay0 - 1.0;
+ bxx -= qlv * byy;
+ b += byy * ly1 * ly1;
+ c4 = bxx * bxx + qlv * bxy * bxy;
+ c3 = 2.0 * (bxx * bx + qlv * by * bxy);
+ c2 = 2.0 * bxx * b + bx * bx + qlv * by * by - ly1 * ly1 * bxy * bxy;
+ c1 = 2.0 * (bx * b - ly1 * ly1 * by * bxy);
+ c0 = b * b - ly1 * ly1 * by * by;
+ glvierterord(c4, c3, c2, c1, c0, &anz, x1erg);
+ for (i = 1; i <= anz; i++) {
+ xx1 = x1erg[i];
+ yy1 = xx1 / lx1;
+ yy1 = 1.0 - yy1 * yy1;
+ yy1 = sisqrt(1.0, yy1);
+ if (yy1 >= 0.0) {
+ yy1 = ly1 * yy1;
+ testxyell(elselp, elsel1, xx1, yy1, *wp, wa, we);
+ testxyell(elselp, elsel1, xx1, -yy1, *wp, wa, we);
+ }
+ }
+}
+
+
+Static boolean ellbozuklein(r, wa, we)
+double r, wa, we;
+{
+ double dw;
+
+ dw = we - wa;
+ if (dw < 0.0)
+ dw += wg;
+ dw = r * dw * fgradbo;
+ if (dw < 3.0) return true;
+ else return false;
+}
+
+
+Static Void ellauftrennen(elselp, wa, we)
+long elselp;
+double wa, we;
+{
+ long i;
+ double lmax;
+
+ if (laenge1[elselp] > laenge2[elselp])
+ lmax = laenge1[elselp];
+ else
+ lmax = laenge2[elselp];
+ while (wa < 0.0)
+ wa += wg;
+ while (wa >= wg)
+ wa -= wg;
+ while (we < 0.0)
+ we += wg;
+ while (we >= wg)
+ we -= wg;
+ if (si_fabs(wanf[elselp] - wa) < 0.5)
+ wa = wanf[elselp];
+ if (si_fabs(wend[elselp] - we) < 0.5)
+ we = wend[elselp];
+ if (wa == wanf[elselp] && we == wend[elselp])
+ goto _L1;
+ switch (typ[elselp]) {
+
+
+ case tkreis:
+ case tkreisgef:
+ if (wa == we)
+ goto _L1;
+ ausel(elselp, erase);
+ wanf[elselp] = we;
+ wend[elselp] = wa;
+ if (typ[elselp] == tkreis) typ[elselp] = tkreisbogen;
+ else typ[elselp] = tkreissektorgef;
+ kreisanfendpunkt(elselp);
+ if (ellbozuklein(lmax, wanf[elselp], wend[elselp])==true)
+ typ[elselp] = 0;
+ else
+ berechneminmax(elselp);
+ ausel(elselp, paint);
+ break;
+
+ case tell:
+ case tellgef:
+ if (wa == we)
+ goto _L1;
+ ausel(elselp, erase);
+ wanf[elselp] = we;
+ wend[elselp] = wa;
+ if (typ[elselp] == tell) typ[elselp] = tellbogen;
+ else typ[elselp] = tellsektorgef;
+ ellanfendpunkt(elselp);
+ if (ellbozuklein(lmax, wanf[elselp], wend[elselp])==true)
+ typ[elselp] = 0;
+ else
+ berechneminmax(elselp);
+ ausel(elselp, paint);
+ break;
+
+ case tkreisbogen:
+ case tellbogen:
+ case tkreissektorgef:
+ case tellsektorgef:
+ ausel(elselp, erase);
+ if ((wa != wanf[elselp]) &
+ (ellbozuklein(lmax, wa, wanf[elselp])==false)) {
+ freieselement(&i);
+ kopunv(elselp, i);
+ wend[i] = wa;
+ ellanfendpunkt(i);
+ berechneminmax(i);
+ ausel(i, paint);
+ }
+ if ((we != wend[elselp]) &
+ (ellbozuklein(lmax, we, wend[elselp])==false)) {
+ freieselement(&i);
+ kopunv(elselp, i);
+ wanf[i] = we;
+ ellanfendpunkt(i);
+ berechneminmax(i);
+ ausel(i, paint);
+ }
+ typ[elselp] = 0;
+ break;
+ }/*case*/
+_L1: ;
+}
+
+
+Static Void ellgschnittp(elsel, elselg, wp, wa, we, instrecke)
+long elsel, elselg;
+double *wp, *wa, *we;
+boolean instrecke;
+{
+ long i, anz;
+ double w;
+ terg wgerade, well;
+
+ gell0schnittp(elselg, elsel, &anz, wgerade, well, instrecke);
+ for (i = 1; i <= anz; i++) {
+ w = well[i];
+ while (w > wg)
+ w -= wg;
+ while (w < 0.0)
+ w += wg;
+ testwawe(*wp, wa, we, w);
+ testwawe(*wp, wa, we, w + wg);
+ testwawe(*wp, wa, we, w - wg);
+ }
+}
+
+Static Void ellgischnittp(elsel, i, xx1,yy1,xx2,yy2, wp,wa,we, instrecke)
+long elsel, i;
+double xx1,yy1,xx2,yy2,*wp, *wa, *we;
+boolean instrecke;
+{ /* i ist freies Element, xx1, ... definieren Endpunkte einer Strecke */
+ /* mit der die Ellipse elsel geschnitten wird */
+ /* instrecke = true, dann muss der Schnittpunkt auch in der */
+ /* Strecke i liegen */
+
+
+ typ[i] = tgerade;
+ x1[i] = xx1;
+ y1_[i] = yy1;
+ x2[i] = xx2;
+ y2[i] = yy2;
+ ellgschnittp(elsel, i, wp, wa, we, instrecke);
+ typ[i] = -1;
+}
+
+
+
+Static Void ellschnittp(elselp, elsel, wp, wa, we, instrecke)
+long elselp, elsel;
+double *wp, *wa, *we;
+boolean instrecke;
+/* instrecke = true, dann muss der Schnittpunkt auch in der */
+/* Strecke elsel liegen, falls elsel Strecke */
+{
+ long i, e;
+ boolean sonderfall; /* fuer Schnittpunktberuecksichtigung in Strecken */
+
+ sonderfall = true;
+ e = elsel;
+ switch (typ[elsel]) {
+ case ttext:
+ break;
+ case tgerade:
+ ellgschnittp(elselp, elsel, wp, wa, we, instrecke);
+ break;
+ case tkreis:
+ case tkreisgef:
+ case tkreisbogen:
+ case tell:
+ case tellgef:
+ case tellbogen:
+ ellellschnittp(elselp, elsel, wp, wa, we);
+ break;
+ case tkreissektorgef:
+ case tellsektorgef:
+ freieselement(&i);
+ ellellschnittp(elselp, elsel, wp, wa, we);
+ ellgischnittp(elselp,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall);
+ ellgischnittp(elselp,i,x1[e],y1_[e],xb2[e],yb2[e],wp,wa,we,sonderfall);
+ break;
+ case tdreieckgef:
+ freieselement(&i);
+ ellgischnittp(elselp,i,x1[e],y1_[e],x2[e],y2[e],wp,wa,we,sonderfall);
+ ellgischnittp(elselp,i,x2[e],y2[e],xb1[e],yb1[e],wp,wa,we,sonderfall);
+ ellgischnittp(elselp,i,xb1[e],yb1[e],x1[e],y1_[e],wp,wa,we,sonderfall);
+ break;
+ case trechteckgef:
+ case tviereckgef:
+ freieselement(&i);
+ ellgischnittp(elselp,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall);
+ ellgischnittp(elselp,i,xb1[e],yb1[e],x2[e],y2[e],wp,wa,we,sonderfall);
+ ellgischnittp(elselp,i,x2[e],y2[e],xb2[e],yb2[e],wp,wa,we,sonderfall);
+ ellgischnittp(elselp,i,xb2[e],yb2[e],x1[e],y1_[e],wp,wa,we,sonderfall);
+ break;
+ case tbezier:
+ case tbeziergef:
+ break;
+ }/*case*/
+}
+
+
+Static Void etrim(elselp, elsel1, elsel2, xp, yp, instrecke)
+long elselp, elsel1, elsel2;
+double xp, yp;
+boolean instrecke;
+{
+ double xm, ym, lx, ly, cr, sr, wa, we, wp;
+
+ ellpar(elselp, &xm, &ym, &lx, &ly, &cr, &sr);
+ wp = winkelell(xm, ym, lx, ly, cr, sr, xp, yp);
+ wa = wanf[elselp];
+ we = wend[elselp];
+ if (typ[elselp] == tkreis || typ[elselp] == tell ||
+ typ[elselp] == tkreisgef || typ[elselp] == tellgef) {
+ wa -= wg;
+ we += wg;
+ }
+ if (wp < wa)
+ wp += wg;
+ if (we <= wa)
+ we += wg;
+ ellschnittp(elselp, elsel1, &wp, &wa, &we, instrecke);
+ if (elsel1 != elsel2)
+ ellschnittp(elselp, elsel2, &wp, &wa, &we, instrecke);
+ ellauftrennen(elselp, wa, we);
+}
+
+
+Static Void gellschnittp(elselp, elsel, wp, wa, we)
+long elselp, elsel;
+double *wp, *wa, *we;
+{
+ double w;
+ long anz, i;
+ terg wg_, well;
+
+ gell0schnittp(elselp, elsel, &anz, wg_, well, false);
+ for (i = 1; i <= anz; i++) {
+ w = wg_[i];
+ if (w > *wa && w < *we) {
+ if (w < *wp)
+ *wa = w;
+ else
+ *we = w;
+ }
+ } /*for i*/
+}
+
+
+Static double winkelg(elsel, xp, yp)
+long elsel;
+double xp, yp;
+{
+ double dx, dy;
+
+ dx = x2[elsel] - x1[elsel];
+ dy = y2[elsel] - y1_[elsel];
+ if (si_fabs(dx) > si_fabs(dy))
+ return ((xp - x1[elsel]) / dx);
+ else
+ return ((yp - y1_[elsel]) / dy);
+}
+
+
+Static Void ggschnittp(elselp, elsel, wp, wa, we, instrecke)
+long elselp, elsel;
+double *wp, *wa, *we;
+boolean instrecke;
+{ /* Schnittpunkt zweier Geraden, Schnittpunkt liegt in der durch */
+ /* elselp definierten Strecke. Falls instrecke true liegt der */
+ /* Schnittpunkt auch in der durch elsel definierten Strecke */
+ double dxp, dyp, dx, dy, xx1p, yy1p, xx1, yy1, n, z, vz, w;
+
+ xx1p = x1[elselp];
+ yy1p = y1_[elselp];
+ dxp = x2[elselp] - xx1p;
+ dyp = y2[elselp] - yy1p;
+ xx1 = x1[elsel];
+ yy1 = y1_[elsel];
+ dx = x2[elsel] - xx1;
+ dy = y2[elsel] - yy1;
+ n = dxp * dy - dx * dyp; /*xs,ys sei Schnittpunkt, n = nenner bei */
+ /* Ausdruck fuer xs, n==0: parallel */
+ if (n == 0.0)
+ goto L1;
+ /* m = (xs-xx1p)/dxp = z/n */
+ vz = fsign(n);
+ n = si_fabs(n);
+ z = vz * (dy * (xx1 - xx1p) + dx * (yy1p - yy1));
+ if (z <= -0.01 || z >= 1.01*n)
+ /* Schnittpunkt ausserhalb Strecke elselp */
+ goto L1;
+ w = z / n;
+ if (w <= *wa || w >= *we)
+ goto L1;
+ if (instrecke == true) {
+ /* Test, ob Schnittpunkt auch in zweiter Strecke */
+ z = vz*(dyp*(xx1-xx1p)+dxp*(yy1p-yy1));
+ if ((z < -0.01)||(z > 1.01*n))
+ goto L1;
+ }
+ testwawe(*wp, wa, we, w);
+L1: ;
+}
+
+
+Static Void ggischnittp(elselg, i, xx1,yy1,xx2,yy2, wp,wa,we, instrecke)
+long elselg, i;
+double xx1,yy1,xx2,yy2,*wp, *wa, *we;
+boolean instrecke;
+{ /* i ist freies Element, xx1, ... definieren Endpunkte einer Strecke */
+ /* mit der die Strecke elselg geschnitten wird */
+ /* instrecke = true, dann muss der Schnittpunkt auch in der */
+ /* Strecke i liegen */
+
+
+ typ[i] = tgerade;
+ x1[i] = xx1;
+ y1_[i] = yy1;
+ x2[i] = xx2;
+ y2[i] = yy2;
+ ggschnittp(elselg, i, wp, wa, we, instrecke);
+ typ[i] = -1;
+}
+
+
+
+Static Void gschnittp(elselg, elsel, wp, wa, we, instrecke)
+long elselg, elsel;
+double *wp, *wa, *we;
+boolean instrecke;
+{ /* Bestimmung wa und we fuer Schnittpunkt auf Strecke elselg mit */
+ /* anderem Zeichnungselement elsel. Falls elsel eine Strecke und */
+ /* instrecke = true, dann muss der Schnittpunkt auch in der */
+ /* Strecke elsel liegen */
+
+ long i, e;
+ boolean sonderfall; /* fuer Schnittpunkt in Strecke */
+
+ sonderfall = true;
+ e = elsel;
+ switch (typ[elsel]) {
+ case ttext:
+ break;
+ case tgerade:
+ ggschnittp(elselg, elsel, wp, wa, we, instrecke);
+ break;
+ case tkreis:
+ case tkreisgef:
+ case tkreisbogen:
+ case tell:
+ case tellgef:
+ case tellbogen:
+ gellschnittp(elselg, elsel, wp, wa, we);
+ break;
+ case tkreissektorgef:
+ case tellsektorgef:
+ freieselement(&i);
+ gellschnittp(elselg, elsel, wp, wa, we);
+ ggischnittp(elselg,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall);
+ ggischnittp(elselg,i,x1[e],y1_[e],xb2[e],yb2[e],wp,wa,we,sonderfall);
+ break;
+ case tdreieckgef:
+ freieselement(&i);
+ ggischnittp(elselg,i,x1[e],y1_[e],x2[e],y2[e],wp,wa,we,sonderfall);
+ ggischnittp(elselg,i,x2[e],y2[e],xb1[e],yb1[e],wp,wa,we,sonderfall);
+ ggischnittp(elselg,i,xb1[e],yb1[e],x1[e],y1_[e],wp,wa,we,sonderfall);
+ break;
+ case trechteckgef:
+ case tviereckgef:
+ freieselement(&i);
+ ggischnittp(elselg,i,x1[e],y1_[e],xb1[e],yb1[e],wp,wa,we,sonderfall);
+ ggischnittp(elselg,i,xb1[e],yb1[e],x2[e],y2[e],wp,wa,we,sonderfall);
+ ggischnittp(elselg,i,x2[e],y2[e],xb2[e],yb2[e],wp,wa,we,sonderfall);
+ ggischnittp(elselg,i,xb2[e],yb2[e],x1[e],y1_[e],wp,wa,we,sonderfall);
+ break;
+ case tbezier:
+ case tbeziergef:
+ break;
+ }/*case*/
+}
+
+
+Static Void gauftrennen(elsel, wa, we)
+long elsel;
+double wa, we;
+{
+ double xa, ya, xe, ye, xx1, yy1, xx2, yy2;
+
+ ausel(elsel, erase);
+ xx1 = x1[elsel];
+ yy1 = y1_[elsel];
+ xx2 = x2[elsel];
+ yy2 = y2[elsel];
+ xa = xx1 + (xx2 - xx1) * wa;
+ ya = yy1 + (yy2 - yy1) * wa;
+ xe = xx1 + (xx2 - xx1) * we;
+ ye = yy1 + (yy2 - yy1) * we;
+ if (wa == 0.0 && we == 1.0) /*beide Punkte bleiben*/
+ goto L1;
+ if (wa == 0.0) { /*Punkt 2 bleibt*/
+ x1[elsel] = xe;
+ y1_[elsel] = ye;
+ goto L1;
+ }
+ if (we == 1.0) { /*Punkt 1 bleibt*/
+ x2[elsel] = xa;
+ y2[elsel] = ya;
+ goto L1;
+ }
+ /*Ausschnitt entfaellt*/
+ if (ppabstand(xx1, yy1, xa, ya) > 3)
+ createline(elsel, xx1, yy1, xa, ya);
+ x1[elsel] = xe;
+ y1_[elsel] = ye;
+L1:
+ /* connect davon abhaengig, dass altes Element verwendet wird */
+ if (ppabstand(x1[elsel], y1_[elsel], x2[elsel], y2[elsel]) > 3){
+ berechneminmax(elsel);
+ ausel(elsel, paint);
+ return;
+ }
+ typ[elsel] = 0;
+}
+
+
+Static Void gtrim(elselp, elsel1, elsel2, xp, yp, instrecke)
+long elselp, elsel1, elsel2;
+double xp, yp;
+{ /* Trim mit der Geraden und nicht nur mit der Strecke, falls elsel1 */
+ /* oder elsel2 Strecken sind, falls instrecke = true */
+ double wa, we, wp;
+
+ wa = 0.0;
+ we = 1.0;
+ wp = winkelg(elselp, xp, yp);
+ if (wp > wa && wp < we) {
+ gschnittp(elselp, elsel1, &wp, &wa, &we, instrecke);
+ if (elsel1 != elsel2)
+ gschnittp(elselp, elsel2, &wp, &wa, &we, instrecke);
+ }
+ gauftrennen(elselp, wa, we);
+}
+
+
+Static long trim(xa,ya,msel,phase)
+ long *msel,phase;
+ double xa,ya;
+{
+ static long elselp, elsel1, elsel2, relsel;
+ double xp,yp;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ case 3: goto L3;
+ }
+ L0:
+ return 1;
+ L1:
+ sucheelement((long)nurtrimel, &elselp, xa, ya);
+ if (elselp==0) return 1;
+ freieselement(&relsel);
+ x1[relsel] = xa;
+ y1_[relsel] = ya;
+ strcpy(pr4, " bounding object 1?");
+ return 2;
+ L2:
+ sucheelement((long)nurboundel, &elsel1, xa, ya);
+ if ((elsel1==0)||(elsel1==elselp))
+ return 2;
+ strcpy(pr4, " bounding object 2?");
+ return 3;
+ L3:
+ sucheelement((long)nurboundel, &elsel2, xa, ya);
+ if ((elsel2==0)||(elsel2==elselp))
+ return 3;
+ xp=x1[relsel];
+ yp=y1_[relsel];
+ switch (typ[elselp]) {
+ case tgerade:
+ gtrim(elselp, elsel1, elsel2, xp, yp, false);
+ break;
+ case tkreis:
+ case tkreisgef:
+ case tkreisbogen:
+ case tkreissektorgef:
+ etrim(elselp, elsel1, elsel2, xp, yp, false);
+ break;
+ case tell:
+ case tellgef:
+ case tellbogen:
+ case tellsektorgef:
+ etrim(elselp, elsel1, elsel2, xp, yp, false);
+ break;
+ }/*case*/
+ auselemente();
+ return 0;
+} /*trim*/
+
+Static Void schwerpunkt(elsel,xs,ys)
+ long elsel;
+ double *xs,*ys;
+{/* Schwerpunkt Dreieck */
+ double dx1,dy1,dx2,dy2;
+
+ dx1 = (x2[elsel]+xb1[elsel])/2.0-x1[elsel];
+ dy1 = (y2[elsel]+yb1[elsel])/2.0-y1_[elsel];
+ dx2 = (x1[elsel]+xb1[elsel])/2.0-x2[elsel];
+ dy2 = (y1_[elsel]+yb1[elsel])/2.0-y2[elsel];
+ *xs = (x1[elsel]*dy1*dx2-x2[elsel]*dy2*dx1+(y2[elsel]-y1_[elsel])*dx1*dx2)
+ /(dy1*dx2-dy2*dx1);
+ *ys = (*xs-x1[elsel])*dy1/dx1+y1_[elsel];
+}
+
+
+Static Void fontwahl(taste)
+long taste;
+{
+ selmenue[mfont] = false;
+ if (taste==1) fontnummer = folgefont[fontnummer];
+ if (taste==3) fontnummer = prevfont[fontnummer];
+ strcpy(menue[mfont],textfontlabel[fontnummer]);
+ ausmenueelement(mfont);
+}
+
+Static Void dickenwahl(taste)
+long taste;
+{
+ selmenue[mdick]=false;
+ ausmenueelement(mdick);
+ if (taste==1) aktldicke = aktldicke +1;
+ if (taste==3) aktldicke = aktldicke -1;
+ if (aktldicke>maxldicke) aktldicke=1;
+ if (aktldicke<1) aktldicke=maxldicke;
+ strichsymbol();
+ ausmenueelement(mdick);
+}
+
+Static Void readzeitwahl(taste)
+long taste;
+{
+ long f;
+
+ f = 5;
+ if (aktreadzeit < 50) f = 2;
+ if (aktreadzeit < 20) f = 1;
+ selmenue[mreadzeit]=false;
+ if (taste==1) aktreadzeit += 1*f;
+ if (taste==3) aktreadzeit -= 1*f;
+ if (aktreadzeit>120) aktreadzeit = 120;
+ if (aktreadzeit<0) aktreadzeit = 0;
+ readzeitsymbol();
+ ausmenueelement(mreadzeit);
+}
+
+
+Static Void colorwahl(taste)
+long taste;
+{
+ long posnr;
+/* Fortschaltung mit Farbnummern und nicht Positionsnummern */
+
+ posnr = aktcolor;
+/* posnr = farbposfarbnr[aktcolor]; */
+ selmenue[mcolor]=false;
+ if (taste==1) posnr += 1;
+ if (taste==3) posnr -= 1;
+ if (posnr>=aktzahlfarben) posnr=0;
+ if (posnr<0) posnr=aktzahlfarben-1;
+ aktcolor = posnr;
+/* aktcolor = farbnrfarbpos[posnr]; */
+ colorsymbol();
+ ausmenueelement(mcolor);
+}
+
+Static Void somencolorwahl(i)
+long i;
+{
+ aktcolor = farbnrfarbpos[i];
+ colorsymbol();
+ ausmenueelement(mcolor);
+}
+
+Static Void winkelsymbol()
+{
+ Char sss[10];
+
+ sprintf(sss,"%3ld",winkelrotate);
+ strcpy(menue[mwinkelrot],sss);
+}
+
+Static Void setwinkelrot(x)
+ long x;
+{
+ winkelrotate = x;
+ winkelsymbol();
+ ausmenueelement(mwinkelrot);
+}
+
+Static Void winkelwahl(taste)
+ long taste;
+{
+ selmenue[mwinkelrot]=false;
+ if (taste==1) winkelrotate += 5;
+ if (taste==3) winkelrotate += 30;
+ if (winkelrotate > 360)
+ winkelrotate -= 360;
+ winkelsymbol();
+ ausmenueelement(mwinkelrot);
+}
+
+Static long savedateien(msel,dateiname,taste,phase)
+Char *dateiname;
+long *msel,taste,phase;
+{ long iphase;
+
+ iphase = phase;
+ switch (phase){
+ case 0: goto L0;
+ case 100: goto L1;
+ default: goto L2;
+ }
+ L0:
+ inittastaturtext(dateiname,pr2menue[*msel],0L);
+ return 100;
+ L1:
+ strcpy(dateiname, EinText);
+ iphase = 0;
+ L2:
+ iphase = austexdatei(msel,dateiname,taste,iphase);
+ if (iphase != 0) return iphase;
+ iphase=schreibenausdatei(msel,dateiname,taste,iphase);
+ selmenloeschen(msel);
+ return 0;
+}
+
+Static long fuellen(x, y, msel, phase)
+long *msel,phase;
+double x, y;
+{
+ static long i;
+ long k;
+ double xx1, yy1, xs, ys;
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ vorbsortieren();
+ return 1;
+ L1:
+ sucheelement((long)nurfillel, &k, x, y);
+ if (k == 0) return 1;
+ freieselement(&i);
+ kopunvotext(k,i);
+ typ[i] = -1;
+ switch (typ[k]) {
+ case tgerade:
+ xb1[i] = x;
+ yb1[i] = y;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ case tkreis:
+ typ[i] = tkreisgef;
+ break;
+ case tkreisbogen:
+ typ[i] = tkreissektorgef;
+ break;
+ case tell:
+ typ[i] = tellgef;
+ break;
+ case tellbogen:
+ typ[i] = tellsektorgef;
+ break;
+ case tbezier:
+ typ[i] = tbeziergef;
+ break;
+ }
+ goto L4;
+
+ L2: /* wird Dreieck oder Viereck */
+ sucheelement((long)nurgerade, &k, x, y);
+ if (k == 0) return 2;
+ xx1 = xb1[i];
+ yy1 = yb1[i];
+ typ[i]=tgerade;
+ /* wenn Schnittpunkt, dann Dreieck */
+ if (gschnittpunkt(x1[i],y1_[i],x2[i]-x1[i],y2[i]-y1_[i],
+ x1[k],y1_[k],x2[k]-x1[k],y2[k]-y1_[k],
+ &xs, &ys) == true) {
+ if ((inxystrecke(x1[i], y1_[i], x2[i], y2[i], xs, ys)== true)&&
+ (inxystrecke(x1[k], y1_[k], x2[k], y2[k], xs, ys)== true)) {
+ /*triangle*/
+ if (ppabstand(x1[i],y1_[i],xx1,yy1) > ppabstand(x1[i],y1_[i],xs,ys)) {
+ x1[i] = x2[i];
+ y1_[i] = y2[i];
+ }
+ x2[i] = xs;
+ y2[i] = ys;
+ xb1[i] = x1[k];
+ yb1[i] = y1_[k];
+ if (ppabstand(x1[k],y1_[k],x,y) > ppabstand(x1[k],y1_[k],xs,ys)) {
+ xb1[i] = x2[k];
+ yb1[i] = y2[k];
+ }
+ typ[i] = tdreieckgef;
+ goto L3;
+ }
+ }
+ /* Durch zwei Linien sind vier Punkte fuer ein Viereck (quadrangle) */
+ /* definiert. Da die zu verbindenden Punkte so noch nicht eindeutig */
+ /* definiert sind, wird vereinbart: Verbunden werden die beiden, dem */
+ /* jeweiligen Klickpunkt am naechsten liegenden Punkte */
+ if (ppabstand(x1[i],y1_[i],xx1,yy1) < ppabstand(x2[i],y2[i],xx1,yy1)) {
+ xb1[i] = x1[i];
+ yb1[i] = y1_[i];
+ x1[i] = x2[i];
+ y1_[i] = y2[i];
+ }
+ else {
+ xb1[i] = x2[i];
+ yb1[i] = y2[i];
+ }
+ if (ppabstand(x1[k],y1_[k],x,y) < ppabstand(x2[k],y2[k],x,y)) {
+ x2[i] = x1[k];
+ y2[i] = y1_[k];
+ xb2[i] = x2[k];
+ yb2[i] = y2[k];
+ }
+ else {
+ x2[i] = x2[k];
+ y2[i] = y2[k];
+ xb2[i] = x1[k];
+ yb2[i] = y1_[k];
+ }
+ typ[i] = tviereckgef;
+ L3:
+ berechneminmax(i);
+ L4:
+ setlineattribute(0L, i);
+ sequenz[i]= -10; /*wird erstes Element */
+ sortieren();
+ auselemente();
+ return 0;
+} /* end of fuellen */
+
+Static long showgroup(xanf,yanf,taste,msel,phase)
+double xanf,yanf;
+long taste, *msel,phase;
+{
+ long elsel;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ return 1;
+ L1:
+ sucheelement((long)alleelem, &elsel, xanf, yanf);
+ if (elsel != 0) {
+ blinkenan();
+ initgruppentag(false);
+ blinkgruppe(elsel);
+ }
+ return 1;
+}
+
+Static long newgroup(xanf,yanf,xend,yend,taste,msel,phase)
+double xanf,yanf,xend,yend;
+long taste, *msel,phase;
+{
+ long i,elsel,gelsel,gi;
+ static long wurzel;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ }
+ L0:
+ wurzel = 0;
+ /* alte Markierungen loeschen, da spaeter sonst verwertet */
+ for (i=1;i<=zelmax;i++)
+ blink[i] = false;
+ return 1;
+ L1:
+ if (blinkelemente(xanf, yanf, xend, yend, 1L)==false)
+ goto L0B;
+ if (wurzel == 0) {
+ /* alle bisher selektierten Elemente kennzeichen */
+ for (i=1;i<=zelmax;i++)
+ blink[i] = blink[i] || blinkalt[i];
+ /* Pruefen ob mindestens zwei verschiedene Gruppen */
+ elsel = 0;
+ for (i=1;i<=zelmax;i++) {
+ if ( (typ[i]>0)&&(blink[i]==true) ) {
+ if (elsel == 0) {
+ elsel = i;
+ gelsel = group[elsel];
+ }
+ else {
+ gi = group[i];
+ if ( (gi == 0) || (gelsel == 0) ||
+ (gruppenwurzel(i) != gruppenwurzel(elsel)) ) {
+ /* zwei Gruppen */
+ wurzel = freiegruppe();
+ break;
+ }
+ }
+ }
+ }
+ }/* end if wurzel == 0 */
+ if (wurzel == 0) {
+ /* nichts zu gruppieren */
+ goto L0B;
+ }
+ /* Neue Gruppe da und evtl. Elemente zu gruppieren */
+ for (i=1;i<=zelmax;i++) {
+ if ( (typ[i]>0)&&(blink[i]==true)&&
+ (gruppenwurzel(i) != wurzel) ){/* zufuegen */
+ gruppieren(i, wurzel);
+ }
+ }
+ L0B:
+ /* alle bisher selektierten Elemente kennzeichen */
+ for (i=1;i<=zelmax;i++) {
+ blink[i] = blink[i] || blinkalt[i];
+ if (blink[i] == true)
+ blinkend = true;
+ }
+ return 1;
+}
+
+Static long ungroup(xanf,yanf,taste,msel,phase)
+double xanf,yanf;
+long taste, *msel,phase;
+{
+ static long elsel;
+ long g;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ elsel = 0;
+ return 1;
+ L1:
+ sucheelement((long)alleelem, &elsel, xanf, yanf);
+ if (elsel != 0) {
+ blinkenan();
+ initgruppentag(false);
+ blinkgruppe(elsel);
+ }
+ return 1;
+ L2: /* bei OK gedrueckt */
+ if (elsel==0) return 0;
+ loeschegruppe(elsel);
+ blinkenan();
+ initgruppentag(false);
+ blinkgruppe(elsel);
+ return 1;
+}
+
+Static long groupok(msel, phase)
+long *msel, phase;
+{
+ selmenue[mgroupok]=false;
+ ausmenueelement(mgroupok);
+ if (*msel==mungroup)
+ return ungroup(0.0, 0.0, 1, msel,2);
+ return phase;
+}
+
+
+Static Void connectpunkt(elsel, xa, ya, xc, yc)
+long elsel;
+double xa, ya, *xc, *yc;
+{
+ long e;
+
+ switch (typ[elsel]) {
+ case ttext:
+ case tkreis :
+ case tkreisgef:
+ case tkreisbogen:
+ case tell:
+ case tellgef:
+ case tellbogen:
+ case tkreissektorgef:
+ case tellsektorgef:
+ *xc = x1[elsel];
+ *yc = y1_[elsel];
+ return;
+ case tgerade:
+ case trechteckgef:
+ *xc = (x1[elsel]+x2[elsel])*0.5;
+ *yc = (y1_[elsel]+y2[elsel])*0.5;
+ return;
+ case tviereckgef:
+ e = elsel;
+ if (gschnittpunkt(x1[e],y1_[e],xb2[e]-x1[e],yb2[e]-y1_[e],
+ x2[e],y2[e], xb1[e]-x2[e],yb1[e]-y2[e],
+ xc, yc) == true) {
+ if ((inxystrecke(x1[e],y1_[e],xb2[e],yb2[e], *xc,*yc)== true)&&
+ (inxystrecke(x2[e],y2[e], xb1[e],yb1[e], *xc,*yc)== true)) {
+ return;
+ }
+ }
+ if (gschnittpunkt(x1[e],y1_[e],xb1[e]-x1[e],yb1[e]-y1_[e],
+ x2[e],y2[e], xb2[e]-x2[e],yb2[e]-y2[e],
+ xc, yc) == true) {
+ if ((inxystrecke(x1[e],y1_[e],xb1[e],yb1[e], *xc,*yc)== true)&&
+ (inxystrecke(x2[e],y2[e], xb2[e],yb2[e], *xc,*yc)== true)) {
+ return;
+ }
+ }
+ *xc = (x1[elsel]+x2[elsel])*0.5;
+ *yc = (y1_[elsel]+y2[elsel])*0.5;
+ return;
+ case tdreieckgef:
+ schwerpunkt(elsel,xc,yc);
+ return;
+ case tbezier:
+ case tbeziergef:
+ if (ppabstand(xa,ya,x1[elsel],y1_[elsel]) <=
+ ppabstand(xa,ya,x2[elsel],y2[elsel])) {
+ *xc = x1[elsel];
+ *yc = y1_[elsel];
+ }
+ else {
+ *xc = x2[elsel];
+ *yc = y2[elsel];
+ }
+ return;
+ }
+}
+
+Static Void conngschnittp(elselg, elsel, wp, wa, we)
+long elselg, elsel;
+double *wp, *wa, *we;
+{ /* Trimmen der durch elselg bezeichneten Strecke mit elsel fuer */
+ /* connect. Der Schnittpunkt ist nur relevant, falls er bei Strecken */
+ /* in beiden Strecken liegt. Deshalb true beim Aufruf von gschnittp. */
+
+
+ *wa = 0.0;
+ *we = 1.0;
+
+ if (elsel == 0) return; /*nichts zu trimmen!*/
+
+ switch (typ[elsel]) {
+ case ttext:
+ break;
+ case tgerade:
+ case tkreis :
+ case tkreisgef:
+ case tkreisbogen:
+ case tell:
+ case tellgef:
+ case tellbogen:
+ case tkreissektorgef:
+ case tellsektorgef:
+ case tdreieckgef:
+ case trechteckgef:
+ case tviereckgef:
+ gschnittp(elselg, elsel, wp, wa, we, true);
+ break;
+ case tbezier:
+ case tbeziergef:
+ break;
+ }/*of switch */
+}
+
+Static Void conntrim(art, elselg, elsel1, elsel2)
+long art, elselg, elsel1, elsel2;
+{ /* Trimmen fuer connect, erst mit elsel1, dann mit elsel2. Der */
+ /* Schnittpunkt ist nur relevant, falls er bei Strecken in beiden */
+ /* Strecken liegt. Deshalb true beim Aufruf. */
+
+ double wa, we, wp;
+
+ switch (art) {
+
+ case 1:
+ wp = 0.0;
+ conngschnittp(elselg, elsel1, &wp, &wa, &we, true);
+ break;
+ case 2:
+ wp = 1.0;
+ conngschnittp(elselg, elsel2, &wp, &wa, &we, true);
+ break;
+ case 3:
+ wp = 0.0;
+ conngschnittp(elselg, elsel1, &wp, &wa, &we, true);
+ gauftrennen(elselg, wa, we);
+ if (typ[elselg] == 0) return;
+ wp = 1.0;
+ conngschnittp(elselg, elsel2, &wp, &wa, &we, true);
+ break;
+ }
+ gauftrennen(elselg, wa, we);
+}
+
+Static long connect(xs,ys,xa,ya,taste,msel,phase)
+double xs,ys,xa,ya;
+long taste,phase,*msel;
+{/* Verbindung zweier Elemente */
+
+ static long elsel1,elsel2, relsel;
+ long i1,i2;
+ double xc1,yc1,xc2,yc2;
+
+ switch (phase){
+ case 0: goto L0;
+ case 1: goto L1;
+ case 2: goto L2;
+ }
+ L0:
+ return 1;
+ L1:
+ sucheelement((long)alleelem, &elsel1, xa, ya);
+ if (elsel1 == 0) return 1;
+ freieselement(&relsel);
+ connectpunkt(elsel1, xa, ya, &xc1, &yc1);
+ x1[relsel] = xc1;
+ y1_[relsel] = yc1;
+ strcpy(pr4, pr3menue[*msel]);
+ return 2;
+ L2:
+ if (selmenue[mconnpoint] == false) {/*zweites Objekt gegeben*/
+ sucheelement((long)alleelem, &elsel2, xa, ya);
+ if ((elsel2 == 0)|| (elsel2 == elsel1)) return 2;
+ connectpunkt(elsel2, xa, ya, &xc2, &yc2);
+ }
+ else {/*Punkt anstelle eines zweiten Objekts */
+ xc2 = xs;
+ yc2 = ys;
+ elsel2 = 0L;
+ }
+ xc1 = x1[relsel];
+ yc1 = y1_[relsel];
+ if (selmenue[mconnxy] == true) {
+ i1 = interncreateline(0L, xc1,yc1,xc2,yc1);
+ i2 = interncreateline(0L, xc2,yc1,xc2,yc2);
+ goto L3;
+ }
+ if (selmenue[mconnyx] == true) {
+ i1 = interncreateline(0L, xc1,yc1,xc1,yc2);
+ i2 = interncreateline(0L, xc1,yc2,xc2,yc2);
+ goto L3;
+ }
+ /* direkte Verbindung */
+ i1 = interncreateline(0L, xc1,yc1,xc2,yc2);
+ if (i1 == 0)
+ return 0;
+ conntrim(3,i1, elsel1, elsel2);
+ return 0;
+ L3:
+ if ((i1 == 0) && (i2 == 0))
+ return 0;
+ if (i1 == 0) {
+ conntrim(3,i2, elsel1, elsel2);
+ return 0;
+ }
+ if (i2 == 0) {
+ conntrim(3,i1, elsel1, elsel2);
+ return 0;
+ }
+ lineende[i1] = 0L;
+ lineende[i2] = 0L;
+ if (selmenue[mcapprojecting] == true) {
+ lineende[i1] = 4L;
+ lineende[i2] = 4L;
+ }
+ if (selmenue[mpfeilanf] == true)
+ lineende[i1] = 1L;
+ if (selmenue[mpfeilende] == true)
+ lineende[i2] = 2L;
+ conntrim(1,i1, elsel1, elsel2);
+ conntrim(2,i2, elsel1, elsel2);
+ return 0;
+}
+
+Static long readstdin(msel,phase)
+long phase,*msel;
+{ long i,j,k,anz;
+ double xxmin,xxmax,yymin,yymax;
+
+ switch (readphase) {
+ case 0:
+ /* erster Aufruf */
+ readphase = 1;
+ case 1:
+ /* evtl. kommt jetzt Vorspann */
+ if (geteingabezeile(stdin)==0)
+ return readphase;
+ /* Vorspann lesen, falls da */
+ if (NULL != strstr(eingabezeile,"LaTeXdraw (Siegert, TUM, C")) {
+ /* es kommt epc-Vorspann */
+ readphase = 2;
+ }
+ else {
+ /* es kommen nur Zeichnungselemente */
+ readphase = 6;
+ }
+ return readphase;
+ case 2:
+ /* es beginnt neue Zeichnung, loesche alte Elemente !!*/
+ for (i = 1; i <= zelmax; i++)
+ typ[i] = 0;
+ kompakt();
+ /* EPC-Vorspann lesen, erste Zeile schon da */
+ einvorspannepc(stdin);
+ readphase = 3;
+ return readphase;
+ case 3:
+ /* einzelne Zeichnungslemente lesen */
+ anz = geteingabezeile(stdin);
+ if (anz == 0)
+ fehler(3L);
+ anz=einlesenelement(stdin,&i);
+ if (typ[i] == 0) {
+ /* das ist das Ende eines Bildes, es kommt noch Gruppeninformation */
+ readphase = 4;
+ }
+ else
+ skalieren(i,readdxx,readdyy,readf);
+ return readphase;
+ case 4:
+ /* Gruppeninformation kommt */
+ if (version >= 13.0) /* Gruppen sind da!*/
+ eindateigruppen(stdin);
+ if (version < 11.0) {
+ minmax(&xxmin,&xxmax,&yymin,&yymax);
+ breite=(xxmax-xxmin)*texfaktor;
+ hoehe=(yymax-yymin)*texfaktor;
+ }
+ ausfastalles();
+ readphase = 1;
+ if (aktreadzeit != 0)
+ ltd_usleep(aktreadzeit,0L); /* readzeit Sekunden warten */
+ return readphase;
+ case 5:
+ /* Zeichnungselement, wenn nur Zeichnungslemente */
+ anz = geteingabezeile(stdin);
+ if (anz == 0)
+ fehler(3L);
+ case 6:
+ readphase = 5;
+ anz=einlesenelement(stdin,&i);
+ if (typ[i] == 0) {
+ /* das ist das Ende eines Bildes, es kommt */
+ /* ggf. neues Bild oder weitere Elemente */
+ readphase = 1;
+ kompakt();
+ ausfastalles();
+ if (aktreadzeit != 0)
+ ltd_usleep(aktreadzeit,0L); /* readzeit Sekunden warten */
+ return readphase;
+ }
+ /*Zeichnungselement gelesen */
+ skalieren(i,readdxx,readdyy,readf);
+
+ if (typ[i] < 0) {
+ /* entsprechendes Element loeschen, falls da */
+ typ[i] = -typ[i];
+ if ( (j=duplikat0(i,true))!=0 )
+ loescheelement(j);
+ loescheelement(i);
+ }
+ else {
+ if ( (j = duplikat0(i,false))!=0 ) {
+ lineende[j] = lineende[i];
+ linedicke[j] = linedicke[i];
+ linetype[j] = linetype[i];
+ loescheelement(i);
+ }
+ }
+ kompakt();
+ return readphase;
+ }/* end of switch */
+}
+
+/* diese Prozedur wird als Thread ausgefuehrt !!!!! */
+/* kein Zugriff auf Display in dieser Prozedur */
+Static void* threadreadstdin(vpar)
+ void *vpar;
+{ /* threadaktiv und threadausel sind globale Variable*/
+
+ /* threadausel == 1 signalisiert der Umgebung, dass */
+ /* eingelesene Zeichnungselemente ausgegeben werden sollen */
+ /* Abfrage in Schleife bevor auf Event geprueft wird */
+
+ long i,j,k,anz;
+ double xxmin,xxmax,yymin,yymax;
+
+ while (1) {
+ if (aktreadzeit != 0)
+ ltd_usleep(aktreadzeit,0L); /* grundsaetzlich readzeit Sekunden warten */
+ while (threadaktiv==0){
+ ltd_usleep(5L,0L);
+ }
+ /* jetzt versuchen zu lesen */
+ /* evtl. kommt jetzt Vorspann */
+ while (geteingabezeile(stdin)==0) {};
+ /* Vorspann lesen, falls da */
+ if (NULL == strstr(eingabezeile,"LaTeXdraw (Siegert, TUM, C")) {
+ /* es kommen nur Zeichnungselemente */
+ goto einzelelemente;
+ }
+ /* es kommt epc-Vorspann */
+ /* es beginnt neue Zeichnung, loesche alte Elemente !!*/
+ for (i = 1; i <= zelmax; i++)
+ typ[i] = 0;
+ kompakt();
+ /* EPC-Vorspann lesen, erste Zeile schon da */
+ einvorspannepc(stdin);
+ while (1) {
+ /* einzelne Zeichnungslemente lesen */
+ anz = geteingabezeile(stdin);
+ if (anz == 0)
+ fehler(3L);
+ anz=einlesenelement(stdin,&i);
+ if (typ[i] == 0) {
+ /* das ist das Ende eines Bildes, es kommt noch Gruppeninformation */
+ goto gruppeninformation;
+ }
+ skalieren(i,readdxx,readdyy,readf);
+ }
+ gruppeninformation:
+ /* Gruppeninformation kommt */
+ if (version >= 13.0) /* Gruppen sind da!*/
+ eindateigruppen(stdin);
+ if (version < 11.0) {
+ minmax(&xxmin,&xxmax,&yymin,&yymax);
+ breite=(xxmax-xxmin)*texfaktor;
+ hoehe=(yymax-yymin)*texfaktor;
+ }
+ threadausel=1;
+ continue;
+ einzelelemente:
+ anz=einlesenelement(stdin,&i);
+ if (typ[i] == 0) {
+ /* das ist das Ende eines Bildes, es kommt */
+ /* ggf. neues Bild oder weitere Elemente */
+ }
+ else {
+ /*Zeichnungselement gelesen */
+ skalieren(i,readdxx,readdyy,readf);
+ if (typ[i] < 0) {
+ /* entsprechendes Element loeschen, falls da */
+ typ[i] = -typ[i];
+ if ( (j=duplikat0(i,true))!=0 )
+ loescheelement(j);
+ loescheelement(i);
+ }
+ else {
+ if ( (j = duplikat0(i,false))!=0 ) {
+ lineende[j] = lineende[i];
+ linedicke[j] = linedicke[i];
+ linetype[j] = linetype[i];
+ loescheelement(i);
+ }
+ }
+ }
+ threadausel=1;
+ }/* while (1) wird von thread nicht verlassen */
+}
+
+
+Static long aktion(msel,xs,ys,xa,ya,xe,ye,taste,phase)
+double xs,ys,xa,ya,xe,ye;
+long taste,phase,*msel;
+{
+ long i, elsel;
+ LA:
+ XDefineCursor(display,win,busycursor);
+ LM:
+ if (taste==0) goto LZ; /*es erfolgte eine Tastatureingabe*/
+ if ((xa < xgr) && (koordinateneingegeben==false)) {
+ /*x in Menuebereich */
+ if (xa<=xgrf) {
+ i=somenbesti(xa,ya);
+ if (i < 0) return phase;
+ if (i<ztextfonts) {
+ changefont=true; somenfontwahl(i); return phase;
+ }
+ i = i-ztextfonts;
+ if (i<aktzahlfarben) {
+ changecolor=true; somencolorwahl(i); return phase;
+ }
+ return phase;
+ }
+ menueloc(xa, ya, &i);
+ if (i == 0) return phase;
+ /* Sonderbehandlungen */
+ if (selmenue[mreadzeit]==true)
+ readzeitwahl(taste);
+ if (selmenue[mfont]==true)
+ fontwahl(taste);
+ if (selmenue[mdick]==true)
+ dickenwahl(taste);
+ if (selmenue[mcolor]==true)
+ colorwahl(taste);
+ if (selmenue[mwinkelrot] == true)
+ winkelwahl(taste);
+ if (selmenue[mlschieben]==true)
+ verschieben((long)mlschieben);
+ if (selmenue[mrschieben]==true)
+ verschieben((long)mrschieben);
+ if (selmenue[moschieben]==true)
+ verschieben((long)moschieben);
+ if (selmenue[muschieben]==true)
+ verschieben((long)muschieben);
+ if (selmenue[mgross]==true)
+ verschieben((long)mgross);
+ if (selmenue[mklein]==true)
+ verschieben((long)mklein);
+ if (selmenue[mcenter]==true)
+ verschieben((long)mcenter);
+ if (i==mxytastatur) {
+ if (selmenue[mxytastatur]==false) {
+ erwartet=click_erwartet;
+ strcpy(pr5,nullstr);
+ strcpy(pr6,nullstr);
+ }
+ if (selmenue[mxytastatur]==true) {
+ if ((erwartet==tastatur_erwartet)||(*msel==0)) {
+ selmenue[mxytastatur]=false;
+ ausmenueelement(mxytastatur);
+ }
+ if ((erwartet==click_erwartet)&&(*msel!=0)) {
+ phasexyein=0;
+ phasexyein=xyein(&xsnap, &ysnap,taste,phasexyein);
+ }
+ }
+ }
+ if ((i==mdegrees) && (winerwartet != 0)) {
+ if (selmenue[mdegrees]==true) {
+ if (selmenue[mxytastatur]==true) {
+ selmenue[mxytastatur]=false;
+ ausmenueelement(mxytastatur);
+ }
+ inittastaturtext(nullstr,pr2menue[mdegrees],1L);
+ }
+ if (selmenue[mdegrees]==false) {
+ erwartet=click_erwartet;
+ strcpy(pr5,nullstr);
+ strcpy(pr6,nullstr);
+ }
+ }
+ if (selmenue[mgroupok]==true)
+ phase=groupok(msel, phase);
+ if ( (i == mkopbewmaus) &&
+ ((*msel == mkopieren)||(*msel == mbewegen)) )
+ i =*msel;
+ if (radiogroup[i] != 1) return phase;
+ /*zurueck, falls kein neue Aktion erforderlich*/
+ /* Auswahl eines neuen Zeichenvorgangs */
+ /* falls Editieren Text abgebrochen wurde, Text wieder ausgeben */
+ if ((*msel == mtext)&&(texterase != 0L)) {
+ elsel = texterase;
+ texterase = 0L;
+ ausel(elsel, paint);
+ }
+ kompakt(); /*vorlauefig belegte Elemente freigeben*/
+ if (*msel == mloeschen)
+ unbenutztegruppenfreigeben();
+
+ *msel = i;
+ if (zeichnen==true)
+ { /*nach delete oder move wieder auszugeben*/
+ auselemente();
+ }
+ threadaktiv = 0;
+#ifdef THREAD
+ if (*msel == mread) {
+ threadaktiv = 1;
+ if (threadrunning == 0) {
+ threadrunning = 1;
+ pthread_create(&threadID,pthread_attr_default, (void*)threadreadstdin, NULL);
+ }
+ }
+#endif
+ phase=0;
+ erwartet = click_erwartet;
+ winerwartet = 0;
+ if (selmenue[mxytastatur]==true) {
+ selmenue[mxytastatur]=false;
+ ausmenueelement(mxytastatur);
+ }
+ /* Ende Aktion im Menuebereich */
+ }
+ LZ: if (phase == 0) {
+ blinkenaus();
+ strcpy(pr1, "select/ ");
+ strcpy(pr2, menue[*msel]);
+ strcpy(pr3, nullstr);
+ strcpy(pr4, pr2menue[*msel]);
+ strcpy(pr5, nullstr);
+ strcpy(pr6, nullstr);
+ }
+ koordinateneingegeben=false;
+ /* Aktion im Zeichenbereich */
+ if (*msel==0) return 0;
+ else if (*msel==mladen)
+ phase=eindatei(msel,dateiname,taste,phase);
+ else if (*msel==mende) {
+ phase=ausdatei(msel,dateiname,taste,phase);
+ if (phase==0) schluss(0); /* exit */
+ }
+ else if (*msel==msave) /*zwischenspeichern*/
+ phase = savedateien(msel,dateiname,taste,phase);
+ else if (*msel == mtext)
+ phase=eintext(xs,ys,xa,ya,taste,msel,phase);
+ else if (*msel == mgerade)
+ phase=einline(xs,ys,xa,ya,taste,msel,phase);
+ else if (*msel == mkreis)
+ phase=eincircle(xs,ys,taste,msel,phase);
+ else if (*msel == mell)
+ phase=einellipse(xs,ys,xa,ya,taste,msel,phase);
+ else if (*msel == mrechteck)
+ phase=einbox(xs,ys,taste,msel,phase);
+ else if (*msel == mdreieck)
+ phase=eindreieck(xs,ys,taste,msel,phase);
+ else if (*msel == mviereck)
+ phase=einviereck(xs,ys,taste,msel,phase);
+ else if (*msel == mbezier)
+ phase=einbezier(xs,ys,taste,msel,phase);
+ else if (*msel == mpolygon)
+ phase=einpolygon(xs,ys,taste,msel,phase);
+ else if (*msel == mspiegeln)
+ phase=spiegeln(xs,ys,xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mkopieren)
+ phase=kopieren(xs,ys,xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mbewegen)
+ phase=bewegen(xs,ys,xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mergaenzen)
+ phase=einboxll(xa,ya,msel,phase);
+ else if (*msel == mausdehnen)
+ phase=extend(xa, ya, msel,phase);
+ else if (*msel == mbrechen)
+ phase=trim(xa,ya,msel,phase);
+ else if (*msel == mloeschen)
+ phase=loeschen(xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mup)
+ phase=up(xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mdown)
+ phase=down(xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mchangelineattr)
+ phase=changelineattr(xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mgitter)
+ phase=eingitter(xs,ys,msel,phase);
+ else if (*msel == mcut)
+ phase=vorber_export(xs,ys,xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mpaste)
+ phase=vorber_import(xs,ys,taste,msel,phase);
+ else if (*msel == mfill)
+ phase=fuellen(xa,ya,msel,phase);
+ else if (*msel == mshowgroup)
+ phase=showgroup(xa,ya,taste,msel,phase);
+ else if (*msel== mnewgroup)
+ phase=newgroup(xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel== mungroup)
+ phase=ungroup(xa,ya,taste,msel,phase);
+ else if (*msel == mconnect)
+ phase = connect(xs,ys,xa,ya,taste,msel,phase);
+ else if (*msel == mrot)
+ phase=rotieren(xs,ys,xa,ya,xe,ye,taste,msel,phase);
+ else if (*msel == mqueryattr)
+ phase=queryattr(xa,ya,taste,msel,phase);
+#ifndef THREAD
+ /* nur bei keinem Thread */
+ else if (*msel == mread)
+ phase=readstdin(msel,phase);
+#endif
+ else return phase;
+ /* Ende im Zeichenbereich */
+ LE:
+ if (phase==0) goto LZ;
+ return phase;
+
+} /* Ende Aktion */
+
+Static Void init_neuezeichnung()
+{ long i;
+
+ texfaktor = texfaktorv;
+ breite=xzmax0*texfaktor;
+ hoehe=yzmax0*texfaktor;
+ mitvorspann=false;
+ querformat=true;
+ texdashl = 2.0;
+ texdotg = 1.8;
+ texinterd = 0.8;
+ version = 15.0;
+ initelemente();
+ initgrid();
+ fontnummer = stdfontnummer;
+ strcpy(menue[mfont],textfontlabel[fontnummer]);
+ aktldicke = 1;
+ strichsymbol();
+ readdxx = 0.0;
+ readdyy = 0.0;
+ readf = 1.0;
+ aktreadzeit = 2;
+ readzeitsymbol();
+ aktcolor = schwarz;
+ colorsymbol();
+ for (i = 1; i <= 4; i++)
+ bmarker[i] = false;
+ for (i=0;i<=maxgruppen;i++) {
+ vater[i] = -1;
+ umbenennung[i] = 0;
+ gruppentag[i] = false;
+ }
+ vater[0] = 0;
+ grumax = 0;
+}
+
+main(argc, argv)
+int argc;
+Char *argv[];
+{
+ long i, k, taste, iv, msel, elsel;
+
+ xzmax0 = xzmax00; /* Voreinstellung Gr"o\ss{}e Zeichenfenster */
+ yzmax0 = yzmax00;
+ quer0format=false;
+ tablett = false;
+ nur_texausgabe=false; /*Normalmodus interaktiv von latexdraw */
+ strcpy(docstyle, docstylestd); /* erste LaTeX-Zeile Standard */
+ strcpy(menuefont,xfont); /* Standard-Menuefont */
+ for (iv=1;iv<argc;iv++) {
+#ifdef TABLETT
+ if (strvergl(argv[iv],"-t")==true) tablett = true;
+#endif
+ if (strvergl(argv[iv],"-q")==true)
+ quer0format= true;
+ if (strvergl(argv[iv],"-l")==true)
+ quer0format= true;
+ if (strvergl(argv[iv],"-2e")==true)
+ strcpy(docstyle, docstyle2e); /* erste LaTeX-Zeile f"ur LaTeX2e */
+ if ((strvergl(argv[iv],"-d")==true)&&((iv+1) < argc))
+ strcpy(docstyle,argv[iv+1]); /* erste LaTeX-Zeile vom Benutzer */
+ if ((strvergl(argv[iv],"-f")==true)&&((iv+1) < argc))
+ strcpy(menuefont,argv[iv+1]); /* Menuefont des Benutzers */
+ if ((strvergl(argv[iv],"-s")==true)&&((iv+1) < argc)) {
+ /* Gr"o\ss{}e Zeichenfenster vom Benutzer, Form z.B. 480x375 */
+ i = sscanf(argv[iv+1],"%lgx%lg",&xzmax,&yzmax);
+ if ((i==2)&&(xzmax>0)&&(xzmax<2000)&&(yzmax>0)&&(yzmax<2000)) {
+ xzmax0 = xzmax;
+ yzmax0 = yzmax;
+ }
+ }
+ if ((strvergl(argv[iv],"-io")==true)&&((iv+2) < argc)) {
+ nur_texausgabe=true; /* nur LaTex-Ausgabedatei erzeugen!! */
+ strcpy(dateiname,argv[iv+1]); /* Name LaTexDraw-Eingabedatei */
+ strcpy(texdateiname,argv[iv+2]); /* Name LaTex-Ausgabedatei */
+ }
+ }
+
+ init_tmenue();
+ if (( display = XOpenDisplay(display_name))== NULL) fehler(6);
+ screen = DefaultScreen(display);
+ nocolors = false; /* Farben verfuegbar */
+ if (DisplayPlanes(display,screen)<=2)
+ /*monochrom oder wenige Graustufen*/ nocolors = true;
+ initfarbnamen();
+ init_window_font(display);
+ win = XCreateSimpleWindow(
+ display,RootWindow(display,screen),0,0,ixzmax,iyzmax,4,
+ BlackPixel(display,screen), WhitePixel(display,screen));
+ initfarben(screen, display, win);
+ reihenfolgefarben();
+ initGC(screen, display, win);
+ setze_clip_bereiche(display);
+ size_hints.flags = PPosition | PSize ;
+ size_hints.x = 0;
+ size_hints.y = 0;
+ size_hints.width = ixzmax;
+ size_hints.height = iyzmax;
+ XSetStandardProperties(display,win,window_name,icon_name,None,
+ argv,argc,&size_hints);
+ XSelectInput(display,win,ExposureMask | KeyPressMask | KeyReleaseMask |
+ ButtonPressMask | ButtonReleaseMask |
+ StructureNotifyMask | Button1MotionMask);
+ clickcursor=XCreateFontCursor(display,XC_left_ptr);
+ busycursor=XCreateFontCursor(display,XC_heart);
+ textcursor=XCreateFontCursor(display,XC_dotbox);
+ if (nur_texausgabe == false)
+ XMapWindow(display,win);
+ XSetInputFocus(display,PointerRoot,RevertToPointerRoot,CurrentTime);
+ XSetErrorHandler(myerrorhandler);
+ geoeffnet=0;
+ init_kmenue();
+ initmisc();
+ initcutpaste();
+#ifdef TABLETT
+ /* Falls ein Digitizer angeschlossen ist, initialisieren */
+ if (tablett) {
+ if (init_digitizer(display) == -1)
+ fehler(18);
+ }
+#endif
+ msel = 0;
+ datdeskr = NULL;
+ erwartet=click_erwartet;
+ winerwartet = 0;
+ phase=0;
+ if (nur_texausgabe == false)
+ strcpy(dateiname,nullstr);
+ curs_x = -100.0;
+ curs_y = -100.0;
+ LNEU:
+ init_neuezeichnung();
+ xlast=0.0;
+ ylast=0.0;
+ for (i = 1; i <= zmenue; i++)
+ selmenue[i] = false;
+ selmenue[msel] = true;
+ selmenue[meinrasten] = true;
+ selmenue[mltext] = true;
+ selmenue[mbtext] = true;
+ selmenue[mgroupmode] = true;
+ strcpy(pr1, "select/ ");
+ strcpy(pr2, menue[msel]);
+ strcpy(pr3, nullstr);
+ strcpy(pr4, nullstr);
+ strcpy(pr5, nullstr);
+ strcpy(pr6, nullstr);
+ taste=0;
+ button1gedrueckt =0;
+ button2gedrueckt =0;
+ button3gedrueckt =0;
+ controlan = 0;
+ blinkend = false;
+ koordinateneingegeben=false;
+ dragbox=0;
+ setwinkelrot(90);
+
+ if (nur_texausgabe == true) {
+ /* nur Erzeugung der LaTeX-Ausgabedatei */
+ /* Option -io bei Aufruf von latexdraw */
+ taste = 0;
+ msel = mladen;
+ phase = 2;
+ eindatei(&msel,dateiname,taste,phase);
+ msel = msave;
+ phase = 7;
+ austexdatei(&msel,dateiname,taste,phase);
+ schluss(0);
+ }
+
+/* Event-Schleife */
+while (1) {
+ if (geoeffnet==1) {
+ if (phase==0) {
+ strcpy(pr1,"select/");
+ strcpy(pr2,nullstr);
+ strcpy(pr3,nullstr);
+ strcpy(pr4,nullstr);
+ strcpy(pr5,nullstr);
+ strcpy(pr6,nullstr);
+ if (msel != 0) {
+ strcpy(pr1, "select/ ");
+ strcpy(pr2, menue[msel]);
+ strcpy(pr4, pr2menue[msel]);
+ }
+ }
+ prompt();
+ if (erwartet==click_erwartet)
+ XDefineCursor(display,win,clickcursor);
+ else {
+ XDefineCursor(display,win,textcursor);
+ cursan(curs_x,curs_y);
+ }
+ }
+ if ((blinkend==true)&&(geoeffnet==1)) {
+ while ( (int)XEventsQueued(display, QueuedAfterFlush) == 0) {
+#ifdef TABLETT
+ if (tablett)
+ process_digitizer(display, win);
+#endif
+ ausblinkelemente();
+ }
+ /* folgende zwei Befehle, damit nach Klick die Elemente */
+ /* ggf. sofort wieder geloescht dargestellt werden */
+ blinkfarbe = erase;
+ blinkintervallzaehler = 0;
+ }
+
+ /* Eingabe ueber digitizer oder STDIN, solange kein X-Event */
+ while ( (int)XEventsQueued(display, QueuedAfterFlush) == 0) {
+
+#ifdef TABLETT
+ if (tablett) {
+ process_digitizer(display, win);
+ }
+#endif
+
+#ifdef THREAD
+ if (threadausel==1) {
+ threadausel=0;
+ kompakt();
+ ausfastalles();
+ /* nachfolgendes sleep kleiner als sleep in thread (derzeit Sekunden) */
+ /* sonst geht Abfrage von threadausel nicht */
+ }
+#endif
+
+#ifndef THREAD
+ if (msel == mread) {
+ phase = readstdin(&msel,phase);
+ }
+#endif
+
+
+ ltd_usleep(0L,30000); /* 30 ms Wartezeit */
+ }
+
+
+
+ XNextEvent(display, &report);
+ if (dragbox==1) xorrechteck(xanf,yanf,xend,yend);
+ dragbox=0;
+ switch (report.type)
+ {
+ case Expose:
+ geoeffnet = 1;
+ /* weitere vorhandene Expose-Events ignorieren */
+ while (XCheckTypedEvent(display,Expose,&report)) ;
+ ausalles();
+ break;
+ case ConfigureNotify:
+#ifdef TABLETT
+ if (tablett)
+ save_win_pos(report.xconfigure.x, report.xconfigure.y,
+ report.xconfigure.width,report.xconfigure.height);
+#endif
+ size_change(display,
+ report.xconfigure.width,report.xconfigure.height);
+ break;
+ case ButtonPress:
+ if (report.xbutton.button==button1) button1gedrueckt=1;
+ if (report.xbutton.button==button2) button2gedrueckt=1;
+ if (report.xbutton.button==button3) button3gedrueckt=1;
+
+ taste=0;
+ if (button1gedrueckt==1) taste = 1;
+ if (button2gedrueckt==1) taste = 10*taste+2;
+ if (button3gedrueckt==1) taste = 10*taste+3;
+
+ getweltkoord(&xanf,&yanf);
+ xend=xanf;
+ yend=yanf;
+ break;
+
+ case MotionNotify:
+ while (XCheckMaskEvent(display,Button1MotionMask,&report));
+ if (erwartet != click_erwartet) break;
+ if (button1gedrueckt==0) break;
+ if (!XQueryPointer(display, win, &rootwin, &childwin,
+ &irootx, &irooty,&iwinx, &iwiny,
+ &keysbuttons)) break;
+ getmotionweltkoord(iwinx, iwiny, &xsnap, &ysnap);
+ if ((dragbox == 1)&&(si_iabs(xsnap-xend) < 2)&&
+ (si_iabs(ysnap-yend) < 2))
+ break;
+ xend = xsnap;
+ yend = ysnap;
+ xorrechteck(xanf,yanf,xend,yend);
+ dragbox=1;
+ break;
+
+ case ButtonRelease:
+ if (report.xbutton.button==button1) button1gedrueckt=0;
+ if (report.xbutton.button==button2) button2gedrueckt=0;
+ if (report.xbutton.button==button3) button3gedrueckt=0;
+ lasteventtime=report.xbutton.time;
+ getweltkoord(&xend,&yend);
+ if (xanf<xgr) {/* in Menue */
+ phase = aktion(&msel,xanf,yanf,xanf,yanf,xanf,yanf,taste,phase);
+ break;
+ }
+ if (erwartet != click_erwartet) break;
+ if (report.xbutton.button!=button1) break;
+ xsnap=xanf;
+ ysnap=yanf;
+ if (selmenue[meinrasten]==true) elsnap(&xsnap, &ysnap);
+ if (selmenue[mmittelpunkt]==true){
+ sucheelement((long)nurmpel, &elsel, xanf, yanf);
+ if (elsel!=0)
+ {
+ xsnap = x1[elsel];
+ ysnap = y1_[elsel];
+ if (typ[elsel] == tgerade || typ[elsel] == trechteckgef)
+ {
+ xsnap = (x1[elsel] + x2[elsel]) / 2;
+ ysnap = (y1_[elsel] + y2[elsel]) / 2;
+ }
+ if (typ[elsel] == tdreieckgef)
+ schwerpunkt(elsel,&xsnap,&ysnap);
+ }
+ }
+ if ((si_fabs(xanf-xend)>15.0)||(si_fabs(yanf-yend)>15.0)) {
+ if (si_fabs(xanf-xend) > si_fabs(yanf-yend)) {
+ /*horizontaler Strich, also horizontale Ausrichtung*/
+ if (si_fabs(xanf-xend)>15.0)
+ ysnap=ylast; /*Ausrichtung Punkt */
+ }
+ else {
+ /*vertikaler Strich, also vertikale Ausrichtung*/
+ if (si_fabs(yanf-yend)>15.0)
+ xsnap=xlast; /*Ausrichtung Punkt */
+ }
+ }
+ xlast=xsnap;
+ ylast=ysnap;
+ neueclickmarke(xsnap,ysnap);
+ if ((si_fabs(xanf-xend)<5.0)||(si_fabs(yanf-yend)<5.0)){
+ xend=xanf;
+ yend=yanf;
+ }
+ phase = aktion(&msel,xsnap,ysnap,xanf,yanf,xend,yend,taste,phase);
+ break;
+
+ case KeyPress:
+ taste=XLookupString(&report.xkey,symstr,maxstrl,&keysym,&compose);
+ if (keysym==NoSymbol) break;
+ taste= keysym;
+ control(taste, 1L);
+ if (erwartet != tastatur_erwartet) {/* Sondertasten */
+ if ( (msel==mloeschen)&&
+ ((taste==tastebackspace)||
+ (taste==tasteundo)||(taste == tastedelete)) ) {
+ /*loeschen ist aktiv, backspace bedeutet undo*/
+ UnDelete();
+ phase = 1;
+ }
+ sondertaste (taste);
+ break;
+ }
+ if (tastaturtext(taste)!=0) break;
+ taste = 0;
+ if (selmenue[mxytastatur]==true) {
+ phasexyein = xyein(&xsnap, &ysnap,taste,phasexyein);
+ xanf=xsnap;
+ yanf=ysnap;
+ xend=xsnap;
+ yend=ysnap;
+ neueclickmarke(xsnap,ysnap);
+ taste = 1;
+ koordinateneingegeben=true;
+ /* initialisierung in aktion ! */
+ }
+ phase =
+ aktion(&msel,xsnap,ysnap,xanf,yanf,xend,yend,taste,phase);
+ break;
+ case KeyRelease:
+ taste=XLookupString(&report.xkey,symstr,maxstrl,&keysym,&compose);
+ if (keysym==NoSymbol) break;
+ taste= keysym;
+ control(taste, 0L);
+ break;
+ case SelectionClear:
+ if (selmenue[mcut] == true)
+ {selmenloeschen(&msel); exportieren();}
+ break;
+ case SelectionNotify:
+ importieren(report.xselection.property,report.xselection.time,&msel);
+ break;
+ case SelectionRequest:
+ request_export(report.xselectionrequest.requestor,
+ report.xselectionrequest.property,
+ report.xselectionrequest.target,
+ report.xselectionrequest.time);
+ break;
+ } /* of case */
+ if (wartendexport==true) exportieren();
+ } /*end of while Event*/
+} /* End. */
+
+
+
+
+
+
+
+
+
+
+
+
+
+