home *** CD-ROM | disk | FTP | other *** search
- {---------------------------------------------------------------------------}
- { gsxlib2.pas - Pascal GSX Bibliothek: }
- { GDPs, Eingabe-Funktionen }
- {---------------------------------------------------------------------------}
-
- { Inhalt:
- Bar, Circle_Segment, Circle, Graph_Chars, Get_Color, Get_Cell_Array,
- Set_Input_Mode, Locate, Valuate, Choice, Input_String }
-
- {**-----------------------------------------------------------------------**}
- {** Hier folgen die Generalized-Drawing-Primitives. Diese Zeichenmakros **}
- {** sind von 1 (= Bar) bis 5 (= GraphChar) durchnummeriert. **}
- {** Dadurch kann man aus dem Wert von 'GDPs' unmittelbar entnehmen, bis **}
- {** zu welchem GDP diese vom Treiber unterstuetzt werden. **}
- {** (siehe Begleitartikel: GSX, die unbek. Groesse, Teil 1, Heft 1/87. **}
- {**-----------------------------------------------------------------------**}
-
- { Zeichnen eines durch Eckkoordinaten bestimmten Rechtecks. Benutzt werden
- die aktuellen 'Fill'-Attribute. }
-
- PROCEDURE Bar (xlb, ylb, { linke, untere Ecke }
- xrt, yrt: INTEGER); { rechte, obere Ecke }
-
- BEGIN
- contrl[1] := 11; contrl[2] := 2; contrl[6] := 1;
- ptsin[1] := xlb; ptsin[2] := ylb;
- ptsin[3] := xrt; ptsin[4] := yrt;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- END;
-
- {---------------------------------------------------------------------------}
- { Ein Kreissegment als Kreisbogen (Arc) oder Tortenstueck (PieSlice) zeich-
- nen. 'xc', 'yc' = Kreismittelpunkt, 'xs', 'ys' gibt den Startpunkt des
- Kreisbogens an, 'angle' den Winkel. Ist 'angle' positiv, wird das Kreis-
- segment im Uhrzeigersinn gezeichnet, andernfalls gegen selbigen. }
-
- PROCEDURE Circle_Segment (SegmentType: Circle_Types;
- xc, yc, xs, ys, angle: REAL);
-
- VAR xe, ye: INTEGER;
- a, b, t, r: REAL;
-
- BEGIN
- { die fehlenden, konsisdenten Parameter fuer GSX berechnen: }
- t := ys-yc;
- r := Sqrt(Sqr(xs-xc)+Sqr(t));
- t := t/r;
- a := ArcTan(t/Sqrt(1-t*t))*180.0/pi;
- IF a < 0 THEN a := 360.0-a;
- b := a-angle;
- IF b < 0 THEN b := 360.0-b;
- t := (180.0-b)*pi/180.0;
- xe := -Round(r*cos(t)-xc);
- ye := Round(r*sin(t)+yc);
-
- contrl[1] := 11; contrl[2] := 4; contrl[6] := SegmentType;
- ptsin[1] := Round(xc); ptsin[2]:= Round(yc);
- IF angle < 0.0 THEN
- BEGIN
- intin[1] := Round(b*10); intin[2] := Round(a*10);
- ptsin[3] := xe; ptsin[4] := ye;
- ptsin[5] := Round(xs); ptsin[6] := Round(ys);
- END
- ELSE
- BEGIN
- intin[1] := Round(a*10); intin[2] := Round(b*10);
- ptsin[3] := Round(xs); ptsin[4] := Round(ys);
- ptsin[5] := xe; ptsin[6] := ye;
- END;
- ptsin[7] := Round(r);
- ptsin[8] := 0;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- END;
-
- {---------------------------------------------------------------------------}
- { Einen Kreis, der durch die Koordinaten xc,yc (Mittelpunkt) und xu,yu (auf
- dem Kreis liegend) bestimmt ist, zeichnen. Es werden die aktuellen 'Fill'-
- Attribute benutzt. Die Parameter sind vom Typ REAL, da Turbo-Pascal Pro-
- bleme mit den Zwischenergebnissen bei der Berechnung des Radius (ptsin[5])
- hat. }
-
- PROCEDURE Circle (xc, yc, xu, yu: REAL);
-
- BEGIN
- contrl[1] := 11; contrl[2] := 3; contrl[6] := 4;
- ptsin[1] := Round(xc); ptsin[2] := Round(yc);
- ptsin[3] := Round(xu); ptsin[4] := Round(yu);
- ptsin[5] := Round(Sqrt(Sqr(xu-xc)+Sqr(yu-yc))); ptsin[6] := 0;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- END;
-
- {---------------------------------------------------------------------------}
- { Zeichenkette mit Grafikzeichen aus dem Sonderzeichensatz mancher Drucker
- (Diablo, Epson) ab der Position x,y drucken. }
-
- PROCEDURE Graph_Chars (x, y: INTEGER; VAR s: VDI_STRING);
-
- BEGIN
- contrl[1] := 11; contrl[2] := 1; contrl[4] := Length(s);
- ptsin[1] := x; ptsin[2] := y;
- FOR x := 1 TO Length(s) DO
- intin[x] := Ord(s[x]);
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- END;
-
- {---------------------------------------------------------------------------}
- { Ende der GDPs }
- {---------------------------------------------------------------------------}
- { Die Prozedur gibt zurueck, wie die Farbe 'Color_Index' aus Rot, Gruen
- und Blau zusammengesetzt ist (s.a. Set_Color). Wenn im Parameter 'Rea-
- lized' TRUE uebergeben wird, wird die vom Geraet tatsaechlich reali-
- sierte Farbmischung zurueckgegeben, sonst die bei der Einstellung mit
- 'Set_Color' verlangte. Die Farbwerte werden in Promille (0-1000) zu-
- rueck gegeben. }
-
- PROCEDURE Get_Color (Color: Color_Index; Realized: BOOLEAN;
- VAR Red, Green, Blue: INTEGER);
-
- BEGIN
- contrl[1] := 26; contrl[2] := 0;
- intin[1] := Color; intin[2] := Ord(Realized);
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- VDI_Error := (contrl[3] <> 0) OR (intout[1] <> Color);
- Red := intout[2];
- Green := intout[3];
- Blue := intout[4]
- END;
-
- {---------------------------------------------------------------------------}
- { Fol. Prozedur holt in Umkehrung von 'Cell_Array' die Farbmusterdefintion
- einer Flaeche. Falls ein Pixel nicht eindeutig einer Farbe zugeordnet
- werden kann, wird 'Invalid' gleich TRUE gesetzt. Falls im 'ColorIndex-
- Array nach dem Prozedur-Aufruf fuer einen Pixel der Farbindex -1 steht,
- konnte dieser nicht bestimmt werden. Weiteres siehe Begleittext. }
-
- PROCEDURE Get_Cell_Array (xlb, ylb, { linke, untere Ecke }
- xrt, yrt: INTEGER; { rechte, obere Ecke }
- VAR Rows,
- Columns: INTEGER;
- VAR ColorIndexArray: VDI_intout;
- VAR Invalid: BOOLEAN);
-
- BEGIN
- contrl[1] := 27; contrl[2] := 2;
- contrl[4] := Rows*Columns; contrl[6] := Columns; contrl[7] := Rows;
- ptsin[1] := xlb; ptsin[2] := ylb;
- ptsin[3] := xrt; ptsin[4] := yrt;
- VDI_Call(contrl, intin, ColorIndexArray, ptsin, ptsout);
- Columns := contrl[8]; Rows := contrl[9];
- Invalid := (contrl[10] = 1);
- END;
-
- {---------------------------------------------------------------------------}
- { GSX-Eingabefunktionen }
- {---------------------------------------------------------------------------}
- { Eingabe-Modus fuer das logisches Geraet 'Device' setzen.
- 'Mode = Request' bewirkt, dass auf ein Eingabeereignis gewartet wird,
- bevor zum Anwenderprogramm zurueckgekehrt wird. Bei 'Mode = Sample'
- wird der aktuelle Status bzw. die aktuelle Position des Eingabe-Geraetes
- o h n e Warten zurueckgegeben. }
-
- FUNCTION Set_Input_Mode (Device: Input_Devices;
- Mode: Input_Modes): Input_Modes;
-
- BEGIN
- contrl[1] := 33; contrl[2] := 0;
- intin[1] := Device; intin[2] := Mode;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- Set_Input_Mode := intout[1];
- END;
-
- {---------------------------------------------------------------------------}
- { Position des spez. Positionierungs-Gerates in Geraete-Koordinaten zurueck-
- geben.
- Request-Mode:
- Auf dem Bildschirm erscheint ein Graphik-Cursor an der Position (x,y),
- der abhaengig vom 'Locator_Device' mit den Cursortasten, Maus oder Joy-
- stick manoevriert werden kann, bis ein Tastendruck folgt.
- Die gedrueckte Taste wird als CHARacter in 'terminator' zurueckgegeben.
- In x und y stehen die neuen Cursor-Koordinaten.
- Sample-Mode:
- Sinngemaess wie Request, der Cursor wird jedoch nicht dargestellt und
- auch kein Abschluss der Eingabe durch Tastendruck erwartet.
- Wenn die Koordinaten geaendert wurden, werden die neuen zurueckgegeben.
- Findet ein Tastendruck statt, wird das entspr. Zeichen zurueckgegeben.
- Geschieht nichts, wird auch nichts zurueckgegeben.
- Fuer beide Modis gilt: 'terminator' = Char(0), wenn keine abschliessen-
- de Taste gedrueckt wurde. Wenn das abschliessende Zeichen nicht von der
- Tastatur sondern z.B. von einer Maus kommt, geben die Maustasten in auf-
- steigender Reihenfolge char(32), char(33), char(34)... zurueck. }
-
- PROCEDURE Locate (Locator: Locator_Devices; InputMode: Input_Modes;
- VAR x, y: INTEGER; VAR terminator: CHAR);
-
- BEGIN
- contrl[1] := 28; contrl[2] := 1;
- intin[1] := Locator;
- ptsin[1] := x; ptsin[2] := y;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- VDI_Error := FALSE;
- terminator := Char(0);
- IF InputMode = Request THEN
- BEGIN
- IF (contrl[5] = 0) THEN
- VDI_Error := TRUE
- ELSE
- terminator := Char(intout[1]);
- x := ptsout[1];
- y := ptsout[2];
- END
- ELSE
- BEGIN
- IF (contrl[5] = 1) THEN
- terminator := Char(intout[1]);
- IF (contrl[3] = 1) THEN
- BEGIN
- x := ptsout[1];
- y := ptsout[2];
- END;
- END;
- END;
-
- {---------------------------------------------------------------------------}
- { Denn Wert der Variable 'Value' mit z.B einem Paddle oder den Cursor-up-
- und Cursor-down-Tasten aendern. Auch hier die Unterscheidung zwischen den
- beiden Input-Modis wie bei 'Locate'.
- Typische Implementation der Cursor-Tasten:
- Cursor-up addiert 10 zu 'Value', Cursor-down subtrahiert entsprechend.
- Wird eine der beiden Tasten zusammen mit SHIFT gedrueckt, wird entspr.
- 1 addiert bzw. subtrahiert. }
-
- PROCEDURE Valuate (InputMode: Input_Modes;
- VAR Value: INTEGER; VAR terminator: CHAR);
-
- BEGIN
- contrl[1] := 29; contrl[2] := 0; intin[2] := Value;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- terminator := Char(0);
- IF InputMode = Request THEN
- BEGIN
- Value := intout[1];
- terminator := Char(intout[2]);
- END
- ELSE
- BEGIN
- IF (contrl[5] = 1) THEN
- Value := intout[1];
- IF (contrl[5] = 2) THEN
- terminator := Char(intout[2]);
- END;
- END;
-
- {---------------------------------------------------------------------------}
- { Auswahl vom selektierten 'Wahl'-Geraet. 'Device' = 1 entspricht den
- Funktions-Tasten, 'Device' > 1 ist geraeteabhaengig. Die Funktions-
- Tasten sind von 1 an aufsteigend durchnummeriert, wobei die Anzahl
- geraeteabhaengig ist. Im Request-Modus wird solange gewartet, bis
- eine gueltige Funktions-Taste gedrueckt wurde; ihre Nummer wird zu-
- rueckgegeben. Im Sample-Modus wird ebenfalls die Nummer einer Funk-
- tions-Taste zurueckgegeben, falls eine gedrueckt wurde. Wurde eine
- Nicht-Funktions-Taste gedrueckt, so wird ihr n e g a t i v e r Wert
- als Terminator zurueckgegeben. Wurde keine Taste gedrueckt, wird der
- Wert 0 geliefert. }
-
- FUNCTION Choice (Device: INTEGER; InputMode: Input_Modes): INTEGER;
-
- BEGIN
- contrl[1] := 30; contrl[2] := 0; intin[1] := Device;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- IF InputMode = Request THEN
- Choice := intout[1]
- ELSE
- CASE contrl[5] OF
- 0: Choice := 0;
- 1: Choice := intout[1];
- 2: Choice := -intout[2];
- END;
- END;
-
- {---------------------------------------------------------------------------}
- { Zeichenkette vom spez. Geraet einlesen, falls dieses dafuer geeignet.
- 'Device' = 1 ist die Tastatur der Konsole. Andere Werte fuer 'Device'
- sind geraeteabhaengig.
- Request-Modus:
- Es werden solange Zeichen eingelesen, bis RETURN/ENTER eingegeben oder
- 'maxlen' erreicht wird. Wenn 'Echo' = TRUE, so wird der Text in den
- aktuellen Text-Attributen ab der Position (x,y) auf dem Bildschirm
- dargestellt.
- Sample-Modus:
- Es werden die im Puffer 'anstehenden' Zeichen eingelesen, bis eine
- der folgenden Bedingungen eintritt:
- - es ist kein weiteres Zeichen verfuegbar
- - RETURN/ENTER wurde angetroffen
- - 'maxlen' wurde erreicht
- Es wird sofort zum Programm zurueckgekehrt, wenn keine Eingabe vorliegt.
-
- PROCEDURE Input_String (Device, maxlen: INTEGER;
- InputMode: Input_Modes;
- Echo: BOOLEAN; x, y: INTEGER;
- VAR st: VDI_STRING);
-
- BEGIN
- contrl[1] := 31; intin[1] := Device; intin[2] := maxlen;
- IF InputMode = Sample THEN
- contrl[2] := 0
- ELSE
- BEGIN
- contrl[2] := Ord(Echo); intin[3] := contrl[2];
- ptsin[1] := x; ptsin[2] := y;
- END;
- VDI_Call(contrl, intin, intout, ptsin, ptsout);
- st[0] := contrl[5];
- FOR x := 1 TO contrl[5] DO
- st[x] := Char(intout[x]);
- END;
-
- {---------------------------------------------------------------------------}
- { Ende von gsxlib2.pas }