TOS2GEM: TOS-Ausgaben sauber im GEM-Fenster (2)

Nachdem wir im ersten Teil des Artikels den TOS2GEM-Cookie, die Bedeutung der einzelnen Variablen und die prinzipielle Vorgehensweise kennengelernt haben, kommen wir nun zur praktischen Anwendung von TOS2GEM. Damit die Benutzung in eigenen Programmen so einfach wie möglich wird, haben wir eine kleine Library entwickelt, die Standardaufgaben - wie das Reservieren und das Freigeben von TOS2GEM - in weiten Teilen übernimmt.

Die einzelnen Routinen werden weitestgehend in der Reihenfolge ihres Auftretens in der Library erklärt. Des weiteren wird beschrieben, in welchem Zustand sich das Programm vor dem Aufruf der Routine befinden muß und was der Benutzer nach der Ausführung noch tun kann oder zu tun hat.

Listings

Aus Platzgründen müssen wir in dieser Ausgabe leider auf den Abdruck von umfangreichen Listings verzichten. Alle Listings, ausführbaren Programme und Beispielapplikationen befinden sich auf der Megadisk zum Heft 4/95 (April-Ausgabe). Die speziellen Listings, die in dieser Ausgabe besprochen werden, sind zusätzlich auch noch einmal auf der aktuellen Megadisk.

Vorbereitung

Die Library ist, wie schon erwähnt, dafür da, dem Benutzer Standardaufgaben abzunehmen. Dazu stellt sie einige Routinen, die in Tabelle 1 zu sehen sind.

Um die Library benutzen zu können, kopiert man die Dateien uset2g.lib und uset2g.h in die entsprechenden Verzeichnisse, included uset2g.h und linkt uset2g.lib dazu. Mehr ist nicht notwendig.

Die Library wird, genauso wie TOS2GEM selbst, über eine Struktur gesteuert. Diese ist in uset2g.h definiert (siehe Listing 1).

Auf diese Struktur kann, nach erfolgreicher Initialisierung, über die Variable TOS2GEM *t2g zugegriffen werden. Diese ist schon in der Header-Datei als ‘extern’ deklariert und darf deshalb nicht mehr definiert werden.

Sämtliche Konstanten sind in uset2g.h definiert. Um die Werte zu erfahren, sollte man in Listing 2 nachsehen. Man sollte niemals direkt auf die Cookie-Struktur von TOS2GEM schreibend zugreifen, da die Library sonst total durcheinander kommt. Alle Werte des Cookies werden von den Library-Funktionen automatisch auf die richtigen Werte gesetzt.

Um Änderungen am TOS2GEM-Screen zu tätigen, ändert man die Werte in der t2g-Struktur und benutzt die Routine change_t2gstats. Danach sollte man noch überprüfen, ob die t2g-Struktur andere Werte als die übergebenen angenommen hat. Eventuell falsch eingetragene Werte werden korrigiert.

Beschreibung der Routinen

WORD init_t2g( WORD t2g_columns,
WORD t2g_lines, WORD t2g_buffer,
WORD t2g_fontnr, WORD t2g_fontsize, 
WORD t2g_txtcol, WORD t2g_mindate, 
WORD t2g_winkind, BOOLEAN cursor_hndl, 
BOOLEAN whole_buffer,
BOOLEAN lines_columns);

Diese Routine reserviert und bereitet TOS2GEM für unsere Applikation vor. Sie führt dabei folgende Schritte durch:

  1. Speicher für die TOS2GEM-Struktur allozieren.
  2. Überprüfen, ob TOS2GEM installiert ist.
  3. Testen, ob die installierte TOS2GEM-Version neu genug ist, um mit unserer Applikation zu arbeiten. Dies ist für zukünftige Erweiterungen von TOS2GEM und auch der Library notwendig.
  4. TOS2GEM für unsere Applikation reservieren.
  5. Für TOS2GEM eine VDI-Workstation öffnen.

Wenn jeweils einer dieser Schritte nicht funktioniert, so kann TOS2GEM nicht benutzt werden. Die Initialisierungsroutine wird dann verlassen und das System wieder in genau den Zustand versetzt, der vor dem Aufruf der Routine vorhanden war. Der gelieferte Return-Code gibt Auskunft darüber, warum TOS2GEM nicht installiert werden konnte.

Klappt alles, kommen nun die übergebenen Variablen zum Zuge, die in Tabelle 2 ersichtlich sind. Die zurückgegebenen Werte sind in Tabelle 3 aufgeführt.

TOS2GEM ist jetzt für unsere Applikation reserviert und der Cookie schon mit allen notwendigen Werten belegt. Die Ausgabeumlenkung wurde noch nicht eingeschaltet, da noch kein GEM-Fenster für TOS2GEM geöffnet wurde. Dies sollte nach dem Aufruf dieser Routine erfolgen (per ca/c_t2gwindow). Danach muß man einmalig die init-Routine aus der TOS2GEM-Cookie-Struktur aufrufen, um TOS2GEM zu initialisieren (Näheres dazu steht im 1. Teil des Artikels).

graf_maus( M_OFF, 0L ); /* Maus abschalten */
wind updatef BEG_UPDATE ); /* Bildschirm sperren */
t2g->cookie->init(); (* TOS2GEM initialisieren */

Nach diesem Aufruf ist die Ausgabeumlenkung aktiv. Möchte man die Umlenkung nicht sofort verwenden, kann man sie mittels

t2g->cookie->switch_output();
    /* Ausgabe umschalten */ 
wind_update( END_UPDATE);
    /* Bildschirm freigeben */ 
graf_maus( M_ON, 0L);
    /* Maus anschalten */ 
t2g->cur_text_offset =
    /* Die zuletzt gültigen Werte für */ 
t2g->cookie->text_offset;
    /* cur_text_offset, cur_y_offset und */ 
t2g->cur_y_offset =
    /* cur_x_offset auslesen bzw.setzen. */ 
t2g->cookie->y_offset;
    /* Dies muß nach jeder Abschaltung der */ 
t2g->cur_x_offset = 0;
/* Umlenkung getan werden! */

wieder inaktivieren. Beim erneuten Aktivieren ist darauf zu achten, daß der komplette TOS2GEM-Screen sichtbar, also in der Regel das GEM-Fenster getoppt, die Maus abgeschaltet und auch der Bildschirm wieder für andere Applikationen gesperrt ist.

t2g_columns : soviele Spalten soll der TOS2GEM-Screen haben (2..MAXC0LUMNS)

t2g_lines : soviele Zeilen soll der TOS2GEM-Screen haben (2..MAXLINES)

t2g_buffer : Anzahl der Zeilen, die über die TOS2GEM-Screen Zeilenanzahl hinaus gepuffert werden sollen. Man hat dann die Möglichkeit, sich alte Ausgaben durch zurückscrollen anzusehen. Wird hier 0 übergeben, gibt es keinen ‘Backscroll’-Puffer.

t2g_fontnr : VDI-Fontnummer des Fonts für die Textdarstellung. Es darf allerdings KEIN PROPORTIONALFONT verwendet werden!!

t2g_fontsize : die Größe dieses Fonts in Punkt

t2g_fontcol : und dessen Darstellungsfarbe

t2gjnindate : dieses Datum muß TOS2GEM mindestens besitzen, um mit unserer Applikation arbeiten zu können. Ist das Datum unwichtig, kann man Null übergeben.

t2g_winkind : Fensterelemente des GEM-Fensters, das den TOS2GEM-Screen beinhaltet.

cursor handle : für den TOS2GEM-Cursor soll eine weitere VDI-Workstation geöffnet werden. Dadurch wird die Ausgabe in den TOS2GEM-Screen wesentlich schneller (etwa um den Faktor 1.8). Kann diese nicht geöffnet werden, wird kein Fehler gemeldet, es wird einfach kein Extra-Handle benutzt.

whole_buffer : Die Library unterstützt zwei Möglichkeiten, TOS2GEM zu verwenden. Mit dieser Variablen bestimmt man, ob sich die Scroll- und Sliderberechnungen auf den gesamten Textpuffer beziehen sollen (TRUE) oder nur auf den Bereich, in dem bisher Ausgaben stehen (FALSE).

lines columns : wird hier TRUE übergeben, dann werden die Environment-Variablen COLUMNS, LINES/ROWS ausgewertet, wenn sie vorhanden sind. Bei FALSE werden sie ignoriert.

Tabelle 2

typedef struct
{
    WORD columns,   /* Anzahl Spalten */
    lines,          /* Anzahl Zeilen */
    linebuffer,     /* Zeilen die über die Screengröße 
                       hinaus gepuffert werden sollen */ 
    fontnr,         /* VDI-Fontnummer für TOS2GEM-Screen */
    fontsize,       /* VDI-Fontgroße für TOS2GEM-Screen */
    fontcol,        /* VDI-Textfarbe für TOS2GEM-Screen */
    winkind,
    /* Fensterelemente des GEM-Fensters, das den TOS2GEM-Screen enthält */ 
    cur_text_offset,
    /* aktueller Wert von text_offset, damit Scrollen im Textpuffer möglich ist */ 
    cur_x_offset,   /* zum horizontalen Scrollen des sichtbaren Auschnitts */ 
    cur_y_offset,   /* aktueller Wert von y_offset zum vertikalen Scrollen */ 
    work_out[57];   /* Ausgabearray der für TOS2GEM geöffneten VDI-Workstation */
    BOOLEAN whole_buffer;
    /* wird im ganzen Textpuffer gescrollt
       oder nur in dem bisher gefüllten Teil? */ 
    TOS2GEM_COOKIE *cookie; /* Zeiger auf die Cookie-Struktur */
} TOS2GEM;
T2G_NOERROR : es ist kein Fehler aufgetreten/alles OK.

T2G_OLDTOS2GEM : das installierte TOS2GEM ist zu alt.

T2G_NOTINSTALLED : TOS2GEM ist nicht im Speicher installiert.

T2G_CANNOTRESERVE : TOS2GEM kann nicht für diese Applikation reserviert werden.

Dies kann nur auftreten, wenn eine andere Applikation vergessen hat TOS2GEM freizugeben oder abgestürzt ist. Die einzige Abhilfe ist hierbei das Programm 'T2G_RESET.PRG' aufzurufen, das TOS2GEM wieder freigibt.

Vorsicht: Unter einer Multitasking-Umgebung kann dieser Fall auch eintreten, wenn eine parallel laufende Applikation TOS2GEM bereits reserviert hat. Allerdings ist der Haupteinsatzbereich von TOS2GEM ohnehin SingleTOS.

T2G_NOVDIHANDLE : es kann keine weitere VDI-Workstation geöffnet werden.

T2G_OUTOFMEMORY : es ist kein Speicher mehr frei.

Tabelle 3

Für die Aktivierung verwendet man wieder switch_output(). Diese Routine schaltet also immer zwischen aktiver und inaktiver Umlenkung her. Bei abgeschalteter Umlenkung kann man dann mit dem GEM-Fenster machen was man will, wie z.B. das Fenster verschieben, darin scrollen oder die Größe ändern.

VOID exit_t2g( VOID);

Diese Routine dient dazu, TOS2GEM wieder für andere Anwendungen nutzbar zu machen. Dabei werden sämtlicher allozierter Speicher und die VDI-Handles freigegeben sowie die Reservierung von TOS2GEM aufgehoben. Um TOS2GEM erneut zu nutzen, muß danach erst wieder init_t2g aufgerufen werden. Beim Beenden unserer Applikation und erfolgreichem init_t2g muß diese Routine aufgerufen werden, damit andere Applikationen ebenfalls in den Genuß von TOS2GEM kommen können.

Mit der nächsten Routine können wir uns ein GEM-Fenster berechnen lassen, das den TOS2GEM-Screen enthalten soll.

WORD calc_t2gwindow( GRECT *win_area, 
    GRECT *win_work, WORD max_columns, 
    WORD max_lines);

Diese Routine sollte immer dann aufgerufen werden, wenn TOS2GEM gerade per init_t2g vorbereitet wurde und man noch kein GEM-Fenster geöffnet hat oder Änderungen am TOS2GEM-Screen mittels change_t2gstats vorgenommen wurden und man sein GEM-Fenster danach wieder auf eine bestimmte Maximalgröße setzen will. Es werden die Außenmaße und der Arbeitsbereich des GEM-Fensters berechnet und in *win_area und *win_work zurückgegeben. Dabei werden evtl, vorhandene Werte darin ignoriert.

Mit den beiden anderen Variablen - max_columns und max_lines - kann man eine maximale Größe (in Zeichen) für das GEM-Fenster angeben, die kleiner oder gleich der TOS2GEM-Screen-Größe sein muß. Über gibt man jeweils einen Wert < 2, so wird versucht, das Fenster so groß wie den TOS2GEM-Screen zu berechnen. Dabei wird darauf geachtet, daß es noch komplett auf den Bildschirm paßt.

Nach dem Aufruf dieser Routine kann man dann mit den zurückgelieferten Werten ein GEM-Fenster öffnen bzw. ein bereits offenes auf diese setzen.

Dazu ein kleines Beispiel: Der TOS2GEM-Screen ist 90x80 Zeichen groß. Übergibt man nun in max_columns und maxjines jeweils 0, so wird versucht, die Werte für ein GEM-Fenster mit 90x80 Zeichen zu berechnen. Übergibt man für max_columns 50 und max_lines 20, so wird ein GEM-Fenster für genau diese Größe berechnet.

Die nachfolgenden Routinen sind für die Benutzung nicht notwendig, jedoch nehmen sie einiges an Arbeit ab, wenn man eine etwas komfortablere TOS2GEM-Einbindung wünscht.

WORD change_t2gstats( GRECT *win_area, GRECT *win_work, WORD type );

Diese Routine verändert in Abhängigkeit von der Variablen type bestimmte Eigenschaften desTOS2GEM-Screens.

*win_area - enthält die Außenmaße des GEM-Fenster, das den TOS2GEM-Screen beinhaltet.

*win_work - dito, nur daß hier der Arbeitsbereich enthalten ist.

type - Steuer-Flag für die gewünschten Änderungen, type kann folgende Werte annehmen:
T2G_CLEARBUFFER
: - der TOS2GEM-Screen soll gelöscht werden, d.h., es wird der gesammte Textpuffer einschließlich des ‘Backscroll’-Puffers gelöscht.

T2G_CHGSCREENSIZE : - die TOS2GEM-Screen-Größe soll gändert werden.

T2G_CHGBUFFER : - der TOS2GEM-'Backscroll’-Puffer soll geändert werden.

T2G_CHGFONT : - die Font-Nummer und -Größe oder die Textfarbe für die Darstellung soll geändert werden.

win_area und win_work werden dabei, falls nötig, an die neuen Gegebenheiten angepaßt, und zwar mit möglichst geringen Änderungen. Durch ‘Verodern’ können auch mehrere Dinge gleichzeitig verändert werden.

Vor Aufruf der Routine

T2G_CHGFONT : - die gewünschten Werte (t2g_fontnr, t2g_fontsize, t2g_fontcol) in die t2g-Struktur eintragen.
T2G_CLEARBUFFER, T2G_CHG-SCREENSIZE und T2G_CHGBUFFER

Auch hier folgt zur näheren Erläuterung ein Beispiel: Die aktuelle Font-Größe soll von 8 Punkt auf 10 Punkt vergrößert werden. Zur gleichen Zeit soll aber auch der TOS2GEM-Screen von 90x80 Zeichen auf 50x20 Zeichen verkleinert werden, und es soll kein ‘Backscroll’-Puffer mehr vorhanden sein.

t2g->columns = 50; 
t2g->lines = 20; 
t2g->buffer = 0; 
t2g->fontsize = 10;

Fenster toppen:

change_t2gstats(&win_area, &win_work, T2G_CHGSCREENSIZE|T2G_CHGBUFFER|T2G_CHGFONT);

Fenstermaße neu setzen:

VOID redraw_t2gwindow( GRECT *win_work, GRECT *box, BOOLEAN clipping);

Diese Routine zeichnet den Inhalt des TOS2GEM-Fensters in einem bestimmten Bereich neu. Sie kann (bei abgeschalteter Ausgabeumlenkung) zu jeder Zeit aufgerufen werden, vor allem aber, wenn man eine Redraw-Message erhält oder das TOS2GEM-Fenster mit change_t2gstats verändert hat. Dabei kann man zusätzlich angeben, ob mit Clipping oder ohne gezeichnet werden soll.

*win_work - ein Zeiger auf den Arbeitsbereich des GEM-Fensters
*box - ein Zeiger auf den Bereich, der in dem GEM-Fenster redrawed werden soll, z.B. der mit WF_FIRSTXYWH oder WF_NEXTXYWH ermittelte.
*clipping - TRUE: mit Clipping zeichnen. FALSE: ohne Clipping zeichnen.

WORD moved_t2gwindow(GRECT win_work);

Diese Routine wird dazu verwendet, den TOS2GEM-Screen an neue Bildschirmkoordinaten anzupassen, beispielsweise, wenn das GEM-Fenster an eine andere Stelle verschoben wurde. Übergeben wird hierbei in win_work der Arbeitsbereich des GEM-Fensters an der neuen Position.

BOOLEAN adjust_t2gwindow (GRECT *new_area, GRECT *win_work,
    WORD *new_x_offset, WORD *new_y_offset);

Wenn man das GEM-Fenster, das TOS2GEM beinhaltet, in seiner Größe verändert, so muß man sämtliche Variablen der Cookie-Struktur auch anpassen. Diese Routine dient nun dazu, TOS2GEM an diese neue Fenstergröße anzupassen sowie eine eventuell falsche Größe zu korrigieren. Die Variable *new_area muß beim Aufruf die aktuellen Ausmaße des GEM-Fensters enthalten.

Zurückgeliefert bekommt man in *new_area und *win_work die neuen Maße des GEM-Fensters. Die Variablen *new_x_offset und *new_y_offset enthalten dann die neuen Werte von cur_x_offset und cur_y_offset aus der t2g-Struktur, die allerdings noch in diese Struktur übernommen werden müssen. Dies wird noch nicht automatisch gemacht, um die Möglichkeit zu bieten, mit der Differenz zu den alten Werten zu arbeiten, z.B. um den Inhalt zu scrollen. Der Rückgabewert von adjust_t2gwindow gibt darüber Auskunft, ob sich die Offsets geändert haben und daher gescrollt oder neu gezeichnet werden muß.

VOID scroll_t2gwindow( WORD x_jump,
WORD y_jump, WORD *new_x_offset,
WORD *new_y_offset,
WORD *new_text_offset);

Diese Funktion dient dazu, den sichtbaren Ausschnitt des TOS2GEM-Screens zu verschieben. Dies ist in erster Linie dann der Fall, wenn man für das GEM-Fenster WM_ARROWED- oder WM_-HSLID/WM_VSLID-Nachrichten bekommt. Den Variablen x_jump/y_jump übergibt man die Anzahl Zeichen, die gescrollt wurden. Dabei bedeuten positive Werte für xJump eine Verschiebung nach rechts und negative eine nach links. Analog für y_jump nur dann eben nach oben und unten. Wird nicht gescrollt, so übergibt man in der entsprechenden Variablen den Wert 0.

Zurückgeliefert bekommt man dann in *new_y_offset, *new_x_offset und *new_text_offset die neuen Positionen für cur_x_offset, cur_y_offset und cur_text_offset. Im Anschluß muß die Applikation den Inhalt mit den neuen Werten neu zeichnen oder verschieben und selbständig in die t2g-Struktur eintragen. Dies wird nicht von der Routine übernommen, um ein Neuzeichnen unter Berücksichtigung der Änderung gegenüber den alten Werten zu ermöglichen.

VOID calc_t2gdeltas( WORD *dx, WORD *dy);

Um die Berechnung der ‘Jump’-Werte bei Slider-Bewegungen stark zu vereinfachen, wurde die nächste Routine geschrieben. Mit ihr lassen sich aus Slider-Differenzwerten (neue Position-alte Position), sogenante ‘Jump’-Werte für scroll_t2gwindow berechnen. Diese können dann direkt als Wert für die Variablen x_jump/y_jump eingetragen werden.

Bei der Parameterübergabe enthält *dx die Slider-Differenz horizontal, also (neue Slider-Position - alte Slider-Position) und *dy analog die Differenz für die Vertikale. Hat sich eine Position nicht geändert, so sollte der alte Wert dafür übergeben werden.

Zurückgeliefert bekommt man dann in den gleichen Variablen den Differenzwert in Zeichen, für scroll_t2gwindow. Man sollte bei den neuen Slider-Positionen 1000 und < 1 nicht diese Funktion verwenden, sondern direkt die neuen Werte für die einzelnen Offset-Werte berechnen und in die t2g-Struktur eintragen:

Horizontal:

< 1:  t2g->cur_x_offset = 0;
1000: t2g->cur_x_offset = t2g->cookie 
      ->x_size - t2g->cookie->x_vis; 

Vertikal:

< 1:  t2g->cur_y_offset = t2g->cur_text_offset = 0;
1000: t2g->cur_y_offset = t2g->cookie-> y_size - t2g->cookie->y_vis; 
      t2g->cur_text_offset = calc_t2gmax_text_offset();

VOID calc_t2gsliders( WORD *x_size,
WORD *y_size, WORD *x_pos,
WORD *y_pos);

Mit dieser Funktion werden Größe und Position der Slider für das GEM-Fenster berechnet, das den TOS2GEM-Screen enthält und ein Scrollen in diesem ermöglicht. Die errechneten Werte können danach direkt mit wind_set gesetzt werden.

*x_size - Größe des horizontalen Sliders
*y_size - Größe des vertikalen Sliders
*x_pos - Position des horizontalen Sliders
*y_pos - Position des vertikalen Sliders

WORD calc_t2gmax_text_offset( void);

Mit Hilfe dieser Funktion ist es möglich, den für den gewählten Textpuffer-Scroll-Typ (whole_buffer, siehe dazu t2g_init) maximalen Wert für cur_text_offset zu bestimmen, um beispielsweise direkt an das Ende des Textpuffers springen zu können. Diesen Wert liefert die Funktion zurück.

Zum Abschluß

Wir hoffen, daß durch diesen Artikel die Benutzung von TOS2GEM klargeworden und die Library ein nützliches Tool für dessen Unterstützung ist. Zur Zeit unterstützen zwei Programme TOS2GEM: Da ist einmal das alternative Desktop ‘THING’ von Arno Welzel, der in den letzten Wochen (in positiver Weise) für großen Diskussionsstoff gesorgt hat, und die ‘POVSHELL’ von Dirk Klemmt ab Version 1.3. Des weiteren haben sich schon einige weitere Leute gemeldet, die TOS2GEM in ihren Programmen unterstützen wollen. Wer ebenfalls TOS2GEM unterstützen möchte und noch Fragen hat, kann sich sehr gerne mit uns in Verbindung setzen.

Autor von TOS2GEM:
Thomas Binder
Johann-Valentin-May-Straße 7 64665 Alsbach-Hähnlein

Autor von uset2g.lib:
Dirk Klemmt Heimchen weg 41 65929 Frankfurt



Aus: ST-Computer 05 / 1995, Seite 94

Links

Copyright-Bestimmungen: siehe Über diese Seite