Spätestens seit der Einführung von Vektorfonts erfreut sich das GDOS, das jahrelang auf dem Atari ein Schattendasein führte, steigender Beliebtheit. Immer mehr Programme bieten die Möglichkeit, für die Ausgabe (und teilweise auch für die Eingabe) einen anderen Font als den Systemfont zu verwenden.
Um nun einen Font auswählen zu können, benötigt man einen Fontselektor. Und damit nicht jeder Programmierer sein eigenes Süppchen kocht und im Sinne einer einheitlichen Bedienung entstand der Wunsch nach einer Systemerweiterung, die einen Fontselektor — ähnlich wie einen Fileselektor — für alle Programme zur Verfügung stellt.
Das erste derartige Programm war der UFSL von Michael Thänitz. Er stellt über einen Cookie Routinen zum Aufruf eines Fontselektors zur Verfügung. Diese Schnittstelle wird bereits von einer Reihe von Programmen verwendet und es gibt auch bereits weitere Fontselektoren, die über diese Schnittstelle aufgerufen werden können.
Zwar läßt sich nun über die UFSL–Schnittstelle ein Fontselektor aufrufen, doch hat diese Schnittstelle bereits eine Reihe von — zum Teil inkompatiblen — Änderungen und Erweiterungen hinter sich. Daher gehen die meisten Programme heute davon aus, daß sie nur die ursprüngliche einfache UFSL-Schnittstelle zur Verfügung haben. Im Endeffekt bleiben also die Erweiterungen ungenutzt und wenn in einem Programm dann doch einmal ein etwas leistungsfähigerer Fontselektor benötigt wird, dann geht man doch wieder dazu über, extra für das Programm einen neuen Fontselektor zu schreiben. Etwas überspitzt formuliert wird hier also die Idee eines externen Fontselektors ad absurdum geführt …
Durch den Wildwuchs
an der UFSL-Schnittstelle erschien es
sinnvoller, einen klaren Trennstrich zu ziehen und eine komplett neue
Schnittstelle zu entwickeln, die dann auch über einen neuen Cookie
angeboten wird.
Dieser Text beschreibt diese neue Schnittstelle, über die nicht nur einfach ein Fontselektor aufgerufen, sondern auch in vielfältiger Weise Einfluß auf diesen genommen werden kann.
Über die xFSL–Schnittstelle hat der Aufrufer (d.h. das Programm, das den Fontselektor aufruft) wesentlich mehr Einfluß auf den Fontselektor, sein Verhalten und auf die zur Auswahl angebotenen Fonts.
Bei der Konzeption der neuen Schnittstelle wurde versucht, auf die Möglichkeiten der verschiedenen Programmiersprachen Rücksicht zu nehmen (z.B. Vermeidung von Zeigern auf Funktionen) und gleichzeitig für mögliche Erweiterungen der Schnittstelle gerüstet zu sein.
Die Anpassung eines Programms an die xFSL–Schnittstelle sollte eine Sache von wenigen Minuten sein, zumal Beispielaufrufe in verschiedenen Programmiersprachen mitgeliefert werden. Die Umsetzung spezieller Wünsche ist natürlich u.U. etwas aufwendiger, sollte aber auch kein unlösbares Problem darstellen.
Es folgt die Beschreibung des xFSL–Cookies sowie der verschiedenen xFSL–Aufrufe und Parameter …
Wenn ein Fontselektor installiert ist, der die
xFSL–Schnittstelle unterstützt, dann existiert ein Cookie
xFSL
, dessen Wert ein Zeiger auf die folgende Struktur
ist:
typedef struct { unsigned long xfsl; /* Magic 'xFSL' */ unsigned int revision; /* Schnittstellen-Revision */ unsigned long product; /* Kennung des Fontselektors */ unsigned int version; /* Version des Fontselektors */ xFSL_INPUT xfsl_input; /* einfacher Aufruf */ xFSL_INIT xfsl_init; /* Init-Aufruf */ xFSL_EVENT xfsl_event; /* Event-Aufruf */ xFSL_EXIT xfsl_exit; /* Exit-Aufruf */ xFSL_INFO xfsl_info; /* Info-Aufruf */ } xFSL;
Die Komponenten der Struktur im einzelnen:
(xfsl | Hier steht, nur zur Sicherheit, nochmals die
ASCII–Zeichenfolge xFSL(entspricht hexadezimal $7846534C). | ||||||||
revision | Dies ist die Revisionsnummer der xFSL–Schnittstelle, sie
enthält z.Z. den Wert 4. Sollte die Schnittstelle erweitert werden,
so werden dort entsprechend höhere Werte zu finden sein.
| ||||||||
product | Hier findet sich eine Kennung für den tatsächlich
installierten Fontselektor. Diese Angabe ist jedoch nur als
zusätzliche Information gedacht und sollte von Anwendungsprogrammen,
die den Fontselektor aufrufen wollen, nicht ausgewertet
werden!
Bisher verwendete Kennungen:
Die Kennung (wie auch die folgende Versionsnummer) wurde nur für Programme eingeführt, die eine Information über den installierten Fontselektor ausgeben wollen (z.B. das Programm SysInfo). | ||||||||
version | Die Versionsnummer des installierten Fontselektors als
BCD–Zahl (z.B. hexadezimal $100 für Version 1.00). Hier gelten
sinngemäß die Anmerkungen zum Feld `product'.
| ||||||||
xfsl_input | Dies ist der Einsprungpunkt für einen vereinfachten Aufruf des
Fontselektors. Der Fontselektor erscheint dann immer als modaler
Dialog und die meisten zusätzlichen Features der
xFSL–Schnittstelle können nicht angesprochen werden.
| ||||||||
xfsl_init, xfsl_event, xfsl_exit | Diese drei Funktionen bilden zusammen den erweiterten
Fontselektor–Aufruf. Hierüber können alle neuen Features
angesprochen werden. Die Vorgehensweise entspricht dem Darstellen
eines GEM-Dialogs:
| ||||||||
xfsl_info | Über diese Aufruf können einige der Features des
installierten Fontselektors abgefragt werden, z.B.
Drag&Drop–Unterstützung.
|
xfsl_input ist der Einsprungpunkt für einen vereinfachten Aufruf. Der Fontselektor kann darüber nur als modaler Dialog aufgerufen werden. Außerdem kann eine Überschrift angegeben und eingeschränkt werden, welche Arten von Fonts der Selektor zur Auswahl stellen soll.
int xfsl_input (int vdihandle, unsigned int fontflags, const char *headline, int *id, int *size );
Die Parameter im einzelnen:
vdihandle | Hier übergeben Sie das Handle einer von Ihrem Programm bereits
geöffneten virtuellen VDI–Workstation (wenn Sie in Ihrem
Programm einen Font einstellen wollen, müssen Sie ja ohnehin eine
solche VDI-Workstation öffnen). Der Fontselektor übernimmt dann
den auf dieser Workstation gerade eingestellten Font als aktuellen
Font (vorausgesetzt, er wird durch die Fontflags überhaupt zur
Auswahl gestellt).
Statt eines gültigen Handles können Sie aber auch einfach eine Null übergeben, dann wird der Fontselektor den Font anzeigen, den Sie in den Parametern `id' und `size' übergeben. Wenn Sie ein VDI–Workstation–Handle übergeben, wird der ausgewählte Font auf dieser Workstation auch gleich eingestellt. |
fontflags | Über die Fontflags können Sie festlegen, welche Fonts
überhaupt zur Auswahl gestellt werden.
|
headline | Hier können Sie eine Überschrift angeben, die dann im
Fontselektor erscheint. Fehlt die Überschrift (Übergabe von 0L),
dann wird ein Defaulttext (Fontauswahlo.ä.) eingesetzt. |
id | In dieser Variablen wird die ID des ausgewählten Zeichensatzes
zurückgeliefert (natürlich nur, wenn auch wirklich ein Zeichensatz
ausgewählt wurde). Dieser Zeichensatz kann nun direkt mit der
VDI-Funktion vst_font() eingestellt werden.
Wenn Sie in `vdihandle' eine Null übergeben, wird der Fontselektor den in `id' angegebenen Font anzeigen. |
size | In dieser Variablen wird die Größe des ausgewählten Fonts in
Punkt zurückgegeben (auch nur, wenn wirklich ein neuer Zeichensatz
ausgewählt wurde). Wenn es sich um einen Bitmapfont handelt, kann
diese Größe mit der VDI–Funktion vst_point eingestellt
werden. Für Vektorfonts sollte die Funktion vst_arbpt aufgerufen
werden.
Wenn Sie in `vdihandle' eine Null übergeben, wird der Fontselektor den in `id' angegebenen Font in der in `size' angegebenen Größe anzeigen. |
Rückgaben
xfsl_input liefert eine negative Zahl zurück, wenn ein
Fehler aufgetreten ist. Eine 0 wird zurückgegeben, wenn
Abbruch
angewählt wurde. Wird eine 1 zurück geliefert, dann
wurde ein neuer Font ausgewählt.
Die Rückgabewerte sind für alle xFSL–Funktionen gleich und aufwärtskompatibel zu den Rückgabewerten des UFSL.
Der erweiterte xFSL–Aufruf besteht aus drei einzelnen Funktionsaufrufen:
xfsl_init | Stellt den Fontselektor auf dem Bildschirm dar. Außerdem
werden hier die Parameter übergeben.
|
xfsl_event | Diese Funktion wird solange immer wieder aufgerufen, bis im
Fontselektor ein Font ausgewählt, oder Abbruchangewählt wurde. |
xfsl_exit | Entfernt den Fontselektor wieder vom Bildschirm.
|
In C kann das dann beispielsweise so ausssehen:
xhandle = xfsl->xfsl_init (vdihandle, &xpar); if (xhandle >= 0) { do { ret = xfsl->xfsl_event (xhandle, 0L); if (ret == xFS_HELP) ...; /* Hilfefunktion aufrufen */ else if (ret == xFS_POPUP) ...; /* Popup behandeln */ else if (ret == xFS_EVENT) ...; /* AES-Event bearbeiten */ } while ((ret != xFS_OK) && (ret != xFS_STOP)); xfsl->xfsl_exit (xhandle); }
Diese Dreiteilung
hat u.a. den Vorteil, daß zur
Bearbeitung der Ereignisse (Hilfe–Button, Popup,
AES–Events) keine Zeiger auf Funktionen übergeben werden
müssen (was in einigen Programmiersprachen nur schwer zu realisieren
ist). Auch läßt sich die Schnittstelle so leicht um weitere
Ereignisse erweitern, falls dies einmal nötig sein sollte.
Dieser Aufruf bringt nicht nur den Fontselektor auf den Bildschirm, er bestimmt auch, welche Fonts angezeigt werden sollen, ob ein User–Popup verwendet wird und einiges mehr.
int xsfl_init (int vdihandle, xFSL_PAR *xpar );
Die beiden Parameter bedeuten:
vdihandle | Hier übergeben Sie, wie schon beim vereinfachten Aufruf, das
Handle einer von Ihrem Programm bereits geöffneten virtuellen
VDI–Workstation oder einfach eine Null.
Wenn Sie ein gültiges Workstation–Handle übergeben, wird der Fontselektor den auf dieser Workstation aktuellen Font übernehmen und anzeigen — sofern er duch die Fontflags (in der xFSL_PAR–Struktur) überhaupt zur Auswahl gestellt wird. Ist dies nicht der Fall, wird der Fontselektor einen Font aus den zur Verfügung stehenden auswählen und anzeigen. Übergeben Sie als Workstation–Handle eine Null, dann wird der Font aus der PFONTINFO–Struktur (auf die ein Zeiger in der xFSL_PAR–Struktur zeigt) übernommen und angezeigt. Wenn Sie ein VDI–Workstation–Handle übergeben, wird der ausgewählte Font auf dieser Workstation auch gleich eingestellt. |
xpar | Dies ist ein Zeiger (d.h. die Adresse) auf eine
xFSL_PAR–Struktur, die alle weiteren Angaben für den
Fontselektor enthält.
Wegen der Vielzahl der Möglichkeiten wurde dieser Struktur ein eigener Abschnitt gewidmet. |
Für die Returncodes der Funktion gilt wieder: Ein negativer Rückgabewert deutet auf einen Fehler hin. Positive Werte haben hier eine etwas abweichende Bedeutung: Eine 0 heißt, der Fontselektor wurde (erfolgreich) als modaler Dialog geöffnet. Andere positive Werte entsprechen dem Fensterhandle des geöffneten Fontselektors. Somit können Sie das Fenster des Fontselektors beispielsweise bei einem AV–Server anmelden.
Im Erfolgsfalle (Rückgabe größer oder gleich 0) sollten Sie sich das Handle in einer Variablen merken, da es für die folgenden Aufrufe (xfsl_event und xfsl_exit) noch benötigt wird.
Hinweis: Wenn der Fontselektor als Fenster dargestellt werden sollte, xfsl_init aber den Fehler xFS_NO_WINDOW liefert (kein Fenster mehr frei), dann sollte möglichst versucht werden, den Fontselektor wenigstens als Dialog darzustellen (Kontrollflag CC_WINDOW löschen und nochmals xfsl_init aufrufen).
Merke: Der Anwender will einen Fontselektor, keine Fehlermeldung.
Wenn der Fontselektor initialisiert und auf den Bildschirm gebracht wurde, übernimmt xfsl_event die Hauptarbeit.
int xfsl_event (int xhandle, EVENT *event );
Die beiden Parameter bedeuten:
xhandle | Das Handle des Fontselektors, wie es von xfsl_init
geliefert wurde.
|
event | Zeiger auf eine EVENT–Struktur, wie sie von Pure
C verwendet wird. In dieser Struktur liefert der Fontselektor
AES–Events zurück, die er nicht selbst bearbeiten konnte.
Außerdem können Sie über die Eingabeparameter dem Fontselektor auch
mitteilen, über welche Ereignisse sie überhaupt unterrichtet werden
wollen.
Der Zeiger kann aber auch einfach Null sein, wenn Sie keine (weiteren) Events auswerten wollen. Soll der Fontselektor als Fensterdialog betrieben werden und der Aufrufer (d.h. Ihr Programm) hat noch weitere Fenster offen, dann müssen Sie aber zumindest die Redraw–Meldungen auswerten! Beispiel: Wenn Sie in `ev_mflags' das Flag MU_MESAG setzen, wird der Fontselektor alle eintreffenden AES–Nachrichten, die er nicht selbst bearbeiten kann, an den Aufrufer zurückliefern. Hinweis: Es ist natürlich auch möglich, Timer–Events zu bekommen. Diese sollten aber sparsam eingesetzt werden und nicht zu kurz sein, da der Fontselektor dazu jedesmal erst seine eigene Event–Schleife verlassen muß. 250 ms mögen als — unverbindliche — untere Grenze gelten. |
Die möglichen Rückgabewerte von xfsl_event:
xFS_STOP | Im Fontselektor wurde der Button Abbruchoder (so vorhanden) der Closer des Fensterdialogs angewählt. Wenn das Kontrollflag CC_CLOSER gesetzt ist und der Closer angeklickt wurde, enthält die PFONTINFO–Struktur, auf die der Zeiger in der xFSL_PAR–Struktur zeigt, aber trotzdem Angaben darüber, welcher Font zuletzt im Fontselektor angewählt worden war. Anders wäre diese Information sonst ja nicht zu erhalten. |
xFS_OK | Es wurde ein Font ausgewählt und OKangewählt. Welcher Font ausgewählt wurde, beschreibt die PFONTINFO–Struktur, auf die der Zeiger in der xFSL_PAR–Struktur zeigt. Wenn bei xfsl_init ein gültiges VDI–Handle übergeben wurde, dann wird der ausgewählte Font auch gleich auf dieser VDI–Workstation eingestellt. |
xFS_HELP | Der Hilfe–Button wurde angewählt (kann natürlich nur
auftreten, wenn Sie ihn haben einblenden lassen). Es liegt nun am
Aufrufer, wie er darauf reagiert. Im Normalfall wird man wohl eine
Hilfe geben, z.B. indem man eine Hilfsseite anzeigt oder anzeigen
läßt.
|
xFS_EVENT | Ein AES–Event ist aufgetreten, den der Fontselektor
nicht bearbeiten konnte (z.B. eine Redraw–Meldung für ein
anderes Fenster). Welcher Event es genau war, können Sie dem Feld
`ev_mwich' der EVENT–Struktur entnehmen.
Accessories sollten bei Eintreffen der Nachricht AC_CLOSE den Aufruf von xfsl_exit nicht vergessen! Gleiches gilt analog für die Nachricht AP_TERM. |
xFS_POPUP | Am User–Popup (sofern vorhanden) wurde ein Veränderung
vorgenommen. Bei dem Popup–Eintrag, der geändert wurde, ist im
Element `fontflags' das Bit FF_CHANGED gesetzt. Der
Popup–Eintrag, der jetzt angewählt wurde und bei Rückkehr in
den Fontselektor (beim nächsten xfsl_event–Aufruf) der
aktuelle des Popups sein wird, steht im Element `sel_entry'.
Sie haben jetzt noch die Möglichkeit, Änderungen an den Popup–Einträgen vorzunehmen, beispielsweise die Fontflags zu ändern oder den geänderten Font in alle anderen Popup-Einträge zu übernehmen (auf diese Weise ist es auch möglich, das Popup für eine andere Information zu verwenden, die mit den ausgewählten Fonts nichts zu tun hat). Die Texte und die Anzahl der Popup-Einträge dürfen aber nicht verändert werden! |
andere Werte: | Andere positive Werte sollten ignoriert werden. Es ist
möglich, daß die Schnittstelle um weitere Rückgabewerte
(Ereignisse) erweitert wird.
Negative Werte zeigen einen Fehler an, der Fontselektor sollte dann abgebrochen werden. Dazu muß aber unbedingt noch xfsl_exit aufgerufen werden! |
Mit dem xfsl_exit–Aufruf wird der Fontselektor wieder vom Bildschirm entfernt:
void xfsl_exit (int xhandle);
Dabei ist `xhandle' wieder das Handle des Fontselektors, wie es von xfsl_init geliefert wurde.
xfsl_exit muß immer dann aufgerufen werden, wenn die
Behandlung des Fontselektors beendet werden soll. Sei es dadurch, daß
ein Font ausgewählt oder Abbruch
angewählt wurde, oder daß
xfsl_event einen Fehler meldete. Wenn schon der
xfsl_init–Aufruf fehlgeschlagen ist, darf
xfsl_exit nicht aufgerufen werden (logisch, da man ja auch
kein gültiges Handle hat).
Der Aufruf von xfsl_exit sollte auch bei Eintreffen der Nachrichten AC_CLOSE und AP_TERM nicht vergessen werden!
Über diesen Aufruf können einige der Features des installierten Fontselektors abgefragt werden:
long xfsl_info (void);
Wenn der Rückgabewert positiv ist, dann stehen die folgenden Flags für vorhandene Features (negative Rückgabewerte sind, wie üblich, Fehlermeldungen):
Name | Wert | Bedeutung |
XF_SIZE | 0x0001 | Größenänderung möglich |
XF_COLOR | 0x0002 | Farbänderung möglich |
XF_ATTR | 0x0004 | Attributänderung möglich |
XF_WIDTH | 0x0008 | Breitenänderung möglich |
XF_KERN | 0x0010 | Kerningänderung möglich |
XF_SKEW | 0x0020 | Neigungsänderung möglich |
XF_ALIGN | 0x0040 | Änderung der Ausrichtung möglich |
XF_ROTATION | 0x0080 | Textrotation möglich |
XF_FIX31 | 0x0100 | fix31-Unterstützung |
XF_POPUP | 0x0200 | Popup-Unterstützung |
XF_DRAGDROP | 0x0400 | Drag&Drop-Unterstützung |
XF_MAPPING | 0x0800 | beherrscht Mapping |
Weitere Features des Fontselektors lassen sich indirekt über das Element `control' der xFSL_PAR–Struktur abfragen: Bei einem erfolgreichen xfsl_init–Aufruf werden diejenigen Kontrollflags gelöscht, die der Fontselektor nicht kennt.
Bei den Aufrufen xfsl_input und xfsl_init kann jeweils das Handle einer vom Aufrufer bereits geöffneten virtuellen VDI–Workstation übergeben werden. Davon, ob man tatsächlich ein Handle einer Workstation oder einfach eine Null übergibt, hängt das weitere Verhalten des Fontselektors ab:
Übergibt man ein gültiges Handle, so wird der Fontselektor versuchen, den auf der entsprechenden Workstation gerade aktuellen Font zu ermitteln und diesen dann — sofern er zu den übergebenen Fontflags paßt — auch einstellen und zur Auswahl anbieten. Paßt der aktuelle Font nicht zu den Fontflags (wenn z.B. nur Vektorfonts angeboten werden sollen, der aktuelle Font aber ein Bitmapfont ist), so wird der Fontselektor einen Font aus den tatsächlich angebotenen auswählen und als aktuellen Font präsentieren.
Wählt der Anwender nun einen Font aus und beendet den
Fontselektor mit OK
, so wird dieser Font auch gleich auf der
übergebenen Workstation eingestellt, so daß das aufrufende Programm
dies nicht mehr übernehmen muß.
Dabei gilt es zu beachten, daß der Fontselektor ebenfalls eine eigene VDI–Workstation öffnet und diese intern und zur Auswahl der Fonts verwendet. U.a. wird er für diese Workstation auch vst_load_fonts() aufrufen (sofern ein GDOS installiert ist). Dies kann zu unerwarteten Resultaten führen, wenn auf der übergebenen Workstation noch kein vst_load_fonts() aufgerufen wurde und der Anwender im Fontselektor einen Font auswählt, der erst nach einem vst_load_fonts()–Aufruf zur Verfügung steht!
Statt eines Workstation–Handles kann man aber auch einfach eine Null übergeben. Der Fontselektor wird den aktuellen Font dann aus den übergebenen Parametern (beim xfsl_input–Aufruf) bzw. aus der xFSL_PAR–Struktur (beim xfsl_init–Aufruf) ermitteln.
Der ausgewählte Font wird dann (logischerweise) auch nur in den Parametern bzw. der xFSL_PAR–Struktur zurückgegeben und der Aufrufer muß ihn dann selbst einstellen.
Über diese Struktur haben Sie weitgehenden Einfluß auf das Verhalten des Fontselektors und die Art der dargestellten Fonts. Daher fällt die Beschreibung der Möglichkeiten auch etwas länger aus …
typedef struct { int par_size; /* Größe der xFSL_PAR-Struktur */ int pfi_size; /* Größe der PFONTINFO-Struktur */ unsigned long control; /* Kontrollflags */ const char *headline; /* Überschrift oder 0L */ const char *example; /* Beispieltext oder 0L */ const char *helptext; /* Text des Hilfe-Buttons od. 0L */ PFONTINFO *font; /* Zeiger auf Fontinfo-Struktur */ unsigned int fontflags; /* erlaubte Fontarten */ const char *poptext; /* Text vor dem Popup oder 0L */ int num_entries; /* Anzahl der Einträge (0..n) */ int sel_entry; /* Selektierter Eintrag (0..n-1) */ xFSL_PENTRY *popup; /* Zeiger auf ein Popup oder 0L */ char *helpinfo; /* Zeiger auf Hilfedatei/-seite */ } xFSL_PAR;
Trotz der Vielzahl der Einträge ist eigentlich alles ganz einfach, zumal Sie Felder, die Sie nicht benötigen oder deren Bedeutung Ihnen noch nicht klar ist, einfach mit Null ausfüllen können, worauf der Fontselektor dann sinnvolle Defaultwerte annehmen wird.
Die Felder im einzelnen:
par_size | Dieses Feld darf nicht auf Null gesetzt werden, hier wird die
Größe der xFSL_PAR–Struktur in Bytes eingetragen,
weshalb man in C einfach schreiben kann
xpar.par_size=sizeof(xFSL_PAR); Die Größe der Struktur beträgt z.Z. 42 Bytes. Sollte die Struktur erweitert werden, kann der Fontselektor an der Größenangabe erkennen, ob er es mit einer neuen oder einer alten Struktur zu tun hat. |
pfi_size | Auch dieses Feld darf nicht Null sein, hier muß die Größe
der PFONTINFO–Struktur eingetragen werden, also
xpar.pfi_size=sizeof(PFONTINFO); Die aktuelle Größe der PFONTINFO–Struktur beträgt 38 Bytes und könnte ebenfalls in Zukunft erweitert werden. |
control | Dies sind die sogenannten Kontrollflags, über die das
Verhalten des Fontselektors beeinflußt werden kann (z.B. ob er als
Fenster oder als Dialog erscheinen soll).
Diesen Flags wurde ein eigener Abschnitt gewidmet. |
headline | Dies ist, wie schon vom einfachen Aufruf her bekannt, ein
Zeiger auf eine Überschrift für den Fontselektor. Fehlt diese (d.h.
`headline' enthält Null), dann wird der Fontselektor eine
Default–Überschrift einsetzen.
Die Länge der Überschrift sollte sich in dem noch vom UFSL vorgegebenen Rahmen (34 Zeichen) bewegen, der Fontselektor wird längere Überschriften aber ggfs. kürzen. |
example | Ein Zeiger auf einen Beispieltext. Der Fontselektor zeigt für
den jeweils eingestellten Font ein Schriftbeispiel an, dessen Text
hiermit vorgegeben werden kann. Fehlt dieser Text (d.h.
`example' enthält Null), wird der Fontselektor einen
Defaulttext anzeigen (z.B. den Namen des jeweiligen Zeichensatzes).
|
helptext | Dies ist der Text für einen Button, der links unten im
Fontselektor eingeblendet werden kann. Im Normalfall wird man dort
einen Button mit der Aufschrift Hilfeoder Helpeinblenden wollen, um dem Anwender die Funktion des Fontselektors zu erklären, und wofür der ausgewählte Font verwendet wird. Fehlt dieser Text (d.h. `helptext' enthält Null), wird auch kein Hilfe-Button eingeblendet. Dann wird xfsl_event auch nicht den Rückgabewert xFS_HELP liefern. Man sollte einen kurzen Text wählen (etwa 8 Zeichen), der Fontselektor wird längere Texte aber ggfs. kürzen. |
font | Dies ist ein Zeiger auf eine Struktur (PFONTINFO), die
einen Font beschreibt. Die Struktur wird sowohl zur Übergabe von
Werten an den Fontselektor als auch zur Rückgabe des ausgewählten
Fonts verwendet.
Auch dieser Struktur ist ein eigener Abschnitt gewidmet. |
fontflags | Dies sind wieder die vom einfachen Aufruf bekannten Fontflags,
mit denen Sie die zur Auswahl gestellten Fonts beeinflußen können.
|
poptext, num_entries, sel_entry, popup: | Mit diesen vier Parametern können Sie ein zusätzliches Popup
in den Fontselektor einblenden lassen. Wegen der vielfältigen
Möglichkeiten gibt's dafür auch wieder einen eigenen Abschnitt.
Wollen Sie kein Popup, so setzen Sie diese vier Werte einfach auf Null. |
helpinfo | Dies ist ein reiner Ausgabeparameter: Wenn der
Hilfe–Button angewählt wurde (sofern vorhanden, siehe
`helptext'), dann steht hier ein Zeiger auf einen Dateinamen
einer Hilfedatei und den Namen einer Seite, die angezeigt werden kann.
Der Dateiname wird ohne Pfad und Extension angegeben, der Seitenname
folgt direkt dahinter, durch ein Komma getrennt.
Der String darf nur gelesen, aber nicht verändert werden! Wenn Sie bei xFS_HELP nicht selbst eine Hilfe anzeigen wollen, dann können Sie mit diesen Informationen ein Hilfesystem (z.B. ST–Guide) aufrufen. Beispiel: xfsl_event gibt xFS_HELP zurück, in `helpinfo' findet sich ein Zeiger auf den String toll,Der tollste Fontselektor aller Zeiten Daraus läßt sich dann folgender Aufruf für ST-Guide erstellen: *:\toll.hyp Der tollste Fontselektor aller Zeiten Man hängt also an den Dateinamen die Extension für das jeweilige Hilfesystem an und übergibt den Teil nach dem ersten Komma als Seitenname. |
Um es nochmals zu betonen: Felder, die sie nicht benötigen oder noch nicht verstehen, können Sie zunächst einfach auf Null setzen. Ausnahmen sind nur
`par_size', die Größe der
xFSL_PAR–Struktur selbst
`pfi_size', die Größe der
PFONTINFO–Struktur
`font', der Zeiger auf die
PFONTINFO–Struktur
Über die Kontrollflags kann das Verhalten des Fontselektors beeinflußt werden.
Name | Wert | Bedeutung |
CC_WINDOW | 0x0001 | Fontselektor als Fenster |
CC_APPMODAL | 0x0002 | Fontselektor ist applikationsmodal |
CC_FIX31 | 0x0004 | alle Größenangaben in 1/65536 Punkt |
CC_FAKESTYLE | 0x0008 | Schnitte simulieren (nur Bitmapfonts) |
CC_CLOSER | 0x0010 | Fenster mit Closer, kein OK-Button |
CC_NOSIZE | 0x0100 | Größe nicht ändern |
CC_NOCOLOR | 0x0200 | Farbe nicht ändern |
CC_NOATTR | 0x0400 | Attribute nicht ändern |
CC_NOWIDTH | 0x0800 | Breite nicht ändern |
CC_NOKERN | 0x1000 | Kerning nicht ändern |
CC_NOSKEW | 0x2000 | Skewing nicht ändern |
CC_NOALIGN | 0x4000 | Ausrichtung nicht ändern |
CC_NOROTATION | 0x8000 | Textrotation nicht ändern |
CC_DFLTSIZE | 0x10000 | Schriftgröße "Default" |
CC_INVSTYLE | 0x20000 | Attribut "Invers" |
Die Funktion der einzelnen Flags sollte sich schon aus den Namen und den Kurzbeschreibungen ergeben. Hier noch einige Anmerkungen:
CC_APPMODAL
Applikationsmodal
heißt, daß das Programm in einen Modus
versetzt wird, in dem nur noch der Fontselektor bearbeitet werden
kann. Im wesentlichen bedeutet das, daß der Fontselektor alle
WM_TOPPED–Nachrichten für andere Fenster des
aufrufenden Programms abfängt und nicht weiterleitet, sondern
sich stattdessen selbst zum obersten Fenster macht. Damit soll dem
Anwender signalisiert werden, daß er zuerst den Fontselektor
bearbeiten soll, bevor er eine andere Aktion im Programm auslösen
kann.
Der Aufrufer sollte in diesem Modus natürlich darauf
verzichten, eigene Fenster selbst mit wind_set(WF_TOP) zum
obersten Fenster zu machen.
CC_FAKESTYLE
Dies ist eine Spezialität, die z.Z. nur Calvino anbietet: Bei
denjenigen Bitmapfonts, bei denen keine leichten, kursiven bzw. fetten
Schnitte vorliegen, werden die jeweils fehlenden Schnitte mit der
VDI–Funktion vst_effects() simuliert.
CC_CLOSER
Wenn dieses Flag und CC_WINDOW gesetzt sind, wird der
Fontselektor mit einem Closer versehen, während der OK– und der
Abbruch–Button versteckt werden. Gedacht ist dies für die
Fälle, in denen der Fontselektor als reiner
Drag&Drop–Selektor eingesetzt werden soll.
CC_NO...
Über diese Flags kann bestimmt werden, welche Einstellungen nicht
verändert werden sollen. Beispielsweise könnte ein Programm
verhindern wollen, daß die Größe eines Zeichensatzes geändert
wird, während eine Änderung des Fonts selbst ermöglicht werden
soll. Dann muß der Aufrufer nur das Flag CC_NOSIZE setzen.
Beachten Sie aber, daß Sie trotz gesetztem
CC_NO...–Flag immer einen gültigen Wert übergeben
müssen. Die Bedeutung dieser Flags ist also, daß die vorgegebenen
Werte nicht verändert werden können und nicht, daß die Werte nicht
von Interesse sind.
Bitte beachten: Nicht alle Fontselektoren unterstützen auch alle Kontrollflags! Wenn ein Fontselektor ein Flag nicht unterstützt, so wird er es einfach ignorieren. Bei einem erfolgreichen(!) xfsl_init-Aufruf wird der Fontselektor diejenigen Flags im Element `control' der xFSL_PAR-Struktur löschen, die er nicht versteht.
Diese Struktur beschreibt einen Font. Sie enthält nach dem Aufruf des Fontselektors den ausgewählten Font. Zudem werden diese Angaben vom Fontselektor schon beim Aufruf ausgewertet (und der so beschriebene Font angezeigt), wenn als VDI–Handle eine Null übergeben wird.
typedef struct { int fontid; /* ID des Fonts */ int fonttype; /* Typ des Fonts */ char *fontname; /* Name des Fonts */ union fsize fontsize; /* Fontgröße in pt oder fix31 */ union fsize fontwidth; /* Breite in pt oder fix31 */ char trackkern; /* Track-Kerning */ char pairkern; /* Paar-Kerning */ int fontattr; /* Attribute */ int fontskew; /* Neigung */ int fontcol; /* Farbe */ int backcol; /* Text-Hintergrundfarbe */ int halign; /* horizontale Textausrichtung */ int valign; /* vertikale Textausrichtung */ int rotation; /* Textrotation in 1/10 Grad */ int validtype; /* Typ (V_CHAR_...) oder Mapping */ int *validchars; /* benötigte Zeichen oder 0L */ } PFONTINFO;
Die Elemente im einzelnen:
fontid | Die ID des Fonts, wie sie auch von der VDI–Funktion
vqt_name() zurückgegegeben wird. Die Font–ID ist eine
Zahl ungleich Null (kann also auch negativ sein).
| |||||||||||||||
fonttype | Der Typ des Fonts, wie er ab Speedo 5 bzw. NVDI 3 verwendet
wird:
Diese Angaben sind z.Z. nur zur Information, aber ohne Bedeutung für den Fontselektor. Allerdings wird es künftig möglich sein, einen Font nicht nur anhand seiner ID, sondern auch anhand seines Namens zu setzen, wobei dann noch zusätzlich der Fonttyp benötigt wird. Der Fonttyp ist aber auch von Interesse, wenn man die Größe des Fonts ändern will: Bei Bitmapfonts geschieht dies mit der VDI–Funktion vst_point(), bei allen anderen Typen (Vektorfonts) mit der Funktion vst_arbpt(). | |||||||||||||||
fontname | Der Name des Fonts, wie er von vqt_name() geliefert
wurde (möglicherweise wurden mehrfache Leerzeichen entfernt).
Der Aufrufer muß selbst genügend Platz für den Fontnamen zur Verfügung stellen, also für 32 Zeichen und ein Nullbyte! Wenn Sie den Fontnamen nicht benötigen, können Sie den Zeiger auch einfach auf Null setzen. | |||||||||||||||
fontsize | Die Größe des Fonts in Punkt (pt) oder 1/65536 Punkt (Typ
fix31): union fsize { int size; /* Fontgröße in Punkt */ fix31 size31; /* Fontgröße in 1/65536 Punkt */ }; Welche der beiden Angaben gültig ist, wird global über das Kontrollflag CC_FIX31 geregelt. | |||||||||||||||
fontwidth | Breite des Fonts in Punkt (pt) oder 1/65536 Punkt (Typ
fix31): union fsize { int size; /* Fontgröße in Punkt */ fix31 size31; /* Fontgröße in 1/65536 Punkt */ }; Welche der beiden Angaben gültig ist, wird global über das Kontrollflag CC_FIX31 geregelt. Die Breite kann mit den VDI–Funktionen vst_width() in Punkt und mit vst_setsize() in fix31 eingestellt werden. | |||||||||||||||
trackkern | Dieser Parameter gibt die Art des Track–Kernings für
vst_kern() an. Gültige Werte sind:
| |||||||||||||||
pairkern | Mit diesem Parameter kann das Pair–Kerning aus– (0)
oder eingeschaltet (1) werden, vgl. vst_kern().
| |||||||||||||||
fontattr | Dies sind die Fontattribute (Texteffekte), wie sie auch von der
VDI–Funktion vst_effects() verwendet werden.
Calvino verwendet dieses Feld nur dann, wenn das Kontrollflag CC_FAKESTYLE gesetzt ist. | |||||||||||||||
fontskew | Die Neigung des Fonts in 1/10 Grad, vgl. vst_skew().
| |||||||||||||||
fontcol | Die Farbe des Fonts. Es werden die VDI–Farben verwendet,
d.h. 0 = Weiß, 1 = Schwarz, usw., vgl. vst_color().
| |||||||||||||||
backcol | Die Hintergrundfarbe des Textes. Es werden die
VDI–Farben verwendet, d.h. 0 = Weiß, 1 = Schwarz, usw. Das
Setzen einer Text–Hintergrundfarbe wird vom VDI nicht direkt
unterstützt, es obliegt daher dem Aufrufer, ob und wie dieser
Parameter verwendet wird.
| |||||||||||||||
halign | Hierüber kann die horizontale Textausrichtung angegeben
werden: Der Text soll linksbündig, rechtsbündig oder zentriert
ausgegeben werden.
Diese Werte entsprechen dem Parameter für die horizontale Ausrichtung beim VDI–Aufruf vst_alignment(). | |||||||||||||||
valign | Hierüber kann die vertikale Textausrichtung angegeben werden:
Der Text soll an der Oberkante oder der Unterkante ausgerichtet oder
(vertikal) zentriert ausgegeben werden.
Diese Werte entsprechen absichtlich nicht dem Parameter zur vertikalen Ausrichtung bei vst_alignment()! Die dort verwendeten Werte ( Zeichenunterkante, Zeichenzellenunterkante) sind für den normalen Anwender wenig intuitiv und sollten daher nicht Teil des User–Interfaces sein (was sie bei der Auswahl im Fontselektor aber wären). Die Ausrichtung muß daher vom aufrufenden Programm in die richtigenWerte konvertiert werden. | |||||||||||||||
rotation | Textrotation in 1/10 Grad, wie sie auch von der
VDI–Funktion vst_rotation() verwendet wird.
|
Fehlen noch die beiden Parameter `validtype' und `validchars':
Manchmal ist es wichtig, sicherzustellen, daß der Font bestimmte Zeichen enthält. Dafür gibt es zwei Möglichkeiten:
Wenn `validchars' Null ist, kann man mit `validtype' eine der folgenden vier Gruppen von Zeichen auswählen:
Name | Wert Bereich Kommentar | ||
V_CHAR_IND | -1 | - | "egal" |
V_CHAR_ASC | -2 | 32-126 | alle druckbaren ASCII-Zeichen |
V_CHAR_PRT | -3 | 32-255 | alle druckbaren Zeichen |
V_CHAR_ALL | -4 | 0-255 | wirklich alle Zeichen |
Diese vier Gruppen dürften die häufigsten Anwendungsfälle abdecken.
Wenn sowohl `validtype' als auch `validchars' Null sind, wird der Fontselektor dies wie V_CHAR_IND behandeln, ebenso bei anderen ungültigen Werten in `validtype'.
Wenn die vier Gruppen einmal nicht ausreichen, so kann man stattdessen über `validtype' und `validchars' auch genauer angeben, welche Zeichen benötigt werden:
validtype | enthält dann einen Wert für das vom GDOS zu verwendende
Mapping (vgl. vst_charmap()).
Die freie Wahl des Mappings steht nur mit einem entsprechenden GDOS (SpeedoGDOS oder NVDI ab Version 3) zur Verfügung. Z.Z. sind folgende Mappings definiert:
Wenn das GDOS kein Mapping beherrscht, wird der Fontselektor nur MAP_ASCII akzeptieren, alle anderen Mappings werden dann ignoriert und ein Test auf Vorhandensein bestimmter Zeichen wird nicht durchgeführt. | |||||||||
validchars | ist ein Zeiger auf ein Array von Integers (Words), über das
angegeben werden kann, welche Zeichen der Font unbedingt enthalten
soll.
Das Array besteht aus einer Folge von Von–Bis–Paaren:
Beispiel: Es sollen nur Fonts angeboten werden, die alle druckbaren ASCII–Zeichen sowie die deutschen Umlaute enthalten. xFSL_PAR xpar; |
Zukünftige GDOSse werden wahrscheinlich weitere Mappings unterstützen (BICS, Unicode, …). Durch die verwendete Codierung wird der Fontselektor auch diese korrekt beherrschen: Das in `validtype' übergebene Mapping wird einfach eingestellt und dann das Vorhandensein der Zeichen aus `validchars' abgetestet.
Anmerkung: Die diversen Möglichkeiten mit den Parametern `validtype' und `validchars' sollten sparsam und mit Bedacht verwendet werden, da das notwendige Testen der Zeichen je nach GDOS recht lange dauern kann.
Für das benutzerdefinierte Popup (kurz User-Popup) existieren die folgenden Felder in der xFSL_PAR–Struktur:
poptext | Zeiger auf einen Text, der vor dem Popup erscheinen soll oder
0L. Dem Fontselektor steht es frei, diesen Text zu ignorieren.
|
num_entries | Anzahl Einträge (d.h. Zeilen) im Popup. Steht hier eine Null,
so wird kein Popup angezeigt. Es sollten nicht mehr als 16 Einträge
verwendet werden, auch wenn einzelne Fontselektoren u.U. auch mehr
Einträge unterstützen.
|
sel_entry | Der selektierte Eintrag im Popup (gezählt wird ab 0). Der
Fontselektor legt hier die Nummer des angewählten Popup-Eintrags ab
und liest den Wert bei jedem Aufruf von xfsl_event wieder neu
aus. Somit können Sie den Fontselektor z.B. auch zwingen, statt dem
angewählten Eintrag Nummer 3 den mit der Nummer 5 zu aktivieren (bei
xFS_POPUP meldet der Fontselektor nur, welcher Eintrag
angewählt wurde, aktiviert wird dieser erst beim Rücksprung in den
Fontselektor).
|
popup | Dies ist ein Zeiger auf ein Array von
xFSL_PENTRY-Elementen. An der angegebenen Adresse müssen
genau so viele Elemente stehen, wie in `num_entries' angegeben
wurden.
|
Ein Eintrag im Popup ist wie folgt aufgebaut:
typedef struct { char *entry; /* Text des Popup-Eintrags */ PFONTINFO *fontinfo; /* Zeiger auf Fontinfo-Struktur */ unsigned int fontflags; /* erlaubte Fontarten */ long funcflags; /* Funktionsflags, nur für HuGo! */ } xFSL_PENTRY;
Die Bedeutung der Elemente dieser Struktur sollte nach den vorangegangenen Ausführungen klar sein. Die Funktionsflags entsprechen den Kontrollflags, bis auf die Flags, die das globale Verhalten des Fontselektors beeinflußen (CC_WINDOW etc.). Diese werden hier ignoriert.
Wichtig: Der Zeiger auf die PFONTINFO–Struktur darf nicht Null sein!
Wenn der Text eines Eintrags mit einem `-' beginnt, wird der entsprechende Eintrag disabled (in heller Schrift und nicht anwählbar) dargestellt. Dies ist in erster Linie für Trennlinien zwischen den Einträgen gedacht.
Verwendung
Im Prinzip kann man drei Einsatzgebiete für das User-Popup sehen:
Jeder Popup-Eintrag stellt den Font für einen bestimmten
Programmteil ein. Beispielsweise könnte man in einem bestimmten
Fenster eines Programms nur nicht–proportionale Fonts zulassen
wollen, in einem anderen keine Vektorfonts, in einem dritten alle
Fonts.
Jeder Eintrag stellt eine gewisse Gruppe von Fonts zur
Verfügung. Braucht man beispielsweise oft Vektorfonts, könnte ein
Popup mit den Einträgen nur Vektorfonts
und alle Fonts
konstruiert werden.
Das Popup kann aber auch für etwas ganz anderes verwendet
werden. Man könnte hier noch eine Information unterbringen, die zwar
nichts mit Fonts, aber mit dem Fenster zu tun hat, für das man einen
Font einstellen will. Beispielsweise könnte für ein
Consolen–Fenster die Art, wie inverse Zeichen darzustellen sind,
in Form eines Popups mit den Einträgen invers
, fett
,
unterstrichen
zur Auswahl angeboten werden.
Will man das Popup so zweckentfremden, so muß man bei der
Meldung xFS_POPUP den geänderten Font (der sich am gesetzten
FF_CHANGED–Flag erkennen läßt) in alle anderen
Popup-Einträge übertragen, da sich sonst der im Fontselektor
angezeigte Font ändern würde!
Über die Fontflags können die zur Auswahl gestellten Fonts eingeschränkt werden:
Name | Wert | Bedeutung |
FF_SYSTEM | 0x0001 | Systemfont (zusätzlich) anzeigen |
FF_MONOSPACED | 0x0002 | monospaced Fonts anzeigen |
FF_PROPORTIONAL | 0x0004 | proportionale Fonts anzeigen |
FF_BITMAP | 0x0008 | Bitmapfonts anzeigen |
FF_SPD | 0x0010 | Speedofonts anzeigen |
FF_TTF | 0x0020 | TrueType-Fonts anzeigen |
FF_PFB | 0x0040 | Type-1-Fonts anzeigen |
FF_CFN | 0x0080 | Calamusfonts anzeigen (n.i.) |
FF_VECTOR | 0x00F0 | alle Vektorfonts anzeigen |
FF_ALL | 0x00FE | alle Fonts anzeigen |
FF_CHANGED | 0x8000 | Änderung erfolgt (nur im Popup) |
Die Werte sind so gewählt, daß die einzelnen Flags miteinander verodert werden können. Setzt man für die Fontflags also beispielsweise FF_MONOSPACED|FF_VECTOR ein, so werden nur unproportionale Vektorfonts zur Auswahl gestellt.
Zudem gilt:
FF_SYSTEM hat Vorrang, d.h. wenn dieses Flag gesetzt
ist, wird der Systemfont auf jeden Fall mit zur Auswahl gestellt.
Wenn FF_SYSTEM nicht gesetzt ist, wird der Systemfont
genau dann zur Auswahl gestellt, wenn seine Eigenschaften den
gesetzten Flags entsprechen.
Wenn weder FF_MONOSPACED noch FF_PROPORTIONAL
gesetzt sind, werden die Fontflags so behandelt, als seien beide Flags
gesetzt.
Dies gilt analog für FF_VECTOR und FF_BITMAP.
Wenn FF_VECTOR gesetzt wird, werden automatisch alle
Vektorfont–Formate angeboten. Eine feinere Unterteilung ist aber
auf Wunsch durch die Flags FF_SPD, …, FF_CFN
möglich.
Bitte beachten: Calamus–Fonts (und somit das Flag
FF_CFN) werden z.Z. noch von keinem GDOS unterstützt!
Das Flag FF_CHANGED wird nur dazu verwendet, um im
User–Popup die Einstellungen zu markieren, die sich geändert
haben. Der Fontselektor setzt dieses Flag nur, wertet es aber selbst
nicht aus.
Alle xFSL–Aufrufe liefern einheitliche Returncodes (Rückgabewerte) zurück. Dabei steht eine negative Zahl für einen Fehler, eine positive Zahl (oder Null) bedeutet Erfolg bzw. ein Ereignis.
Name | Wert | Bedeutung |
xFS_PARERROR | -9 | Parameterfehler, z.B. Aufruf nach Rev. 3 |
xFS_LOADERROR | -8 | Fehler beim Nachladen des xFSL-Moduls |
xFS_RES_ERROR | -7 | Auflösung zu klein (mind. 640x400 Punkte) |
xFS_NO_HANDLE | -6 | Kein VDI-Handle frei |
xFS_NO_WINDOW | -5 | Kein Fenster(handle) frei |
xFS_NO_FONTS | -4 | Keine Fonts geladen |
xFS_NO_FONTSIZE | -3 | Fontgröße nicht identifizierbar |
xFS_ACTIVE | -2 | Fontselektor ist bereits aktiv |
xFS_ERROR | -1 | allgemeiner Fehler (Speichermangel o.ä.) |
xFS_STOP | 0 | <Abbruch> gewählt |
xFS_OK | 1 | <Ok> gewählt |
xFS_HELP | 2 | Hilfe-Button angewählt |
xFS_EVENT | 3 | AES-Event aufgetreten |
xFS_POPUP | 4 | Änderung am User-Popup |
Diese Werte wurden aufwärtskompatibel zum Fontselektor UFSL gewählt (dieser kennt die Returncodes -4, -3, -2, -1, 0 und 1).
Darüber hinaus können auch Gemdos-Fehlermeldungen (Werte kleiner oder gleich -32) auftreten, insbesondere kann xfsl_init auch den Wert EINVFN (-32) liefern, wenn der Fontselektor den erweiterten Aufruf nicht unterstützt.
Beim Aufruf xfsl_init entsprechen positive Rückgabewerte dem Fensterhandle des Fontselektors (0 bedeutet, daß der Fontselektor als modaler Dialog geöffnet wurde).
Es ist möglich, daß die Liste der Returncodes in Zukunft um weitere Fehler (Werte kleiner -9) oder Ereignisse (Werte größer 4) erweitert wird. Dies sollte beim Programmentwurf berücksichtigt werden: Bei unbekannten Fehlern sollte abgebrochen, unbekannte Ereignisse sollten ignoriert werden.
Die GEM–Bibliothek von Pure C verwendet eine spezielle Struktur, in der die Parameter der AES-Funktion evnt_multi() zusammengefaßt sind. Diese Struktur wird auch von xfsl_event verwendet.
typedef struct /* Special type for EventMulti */ { /* Eingabeparameter */ int ev_mflags, ev_mbclicks, ev_bmask, ev_mbstate, ev_mm1flags, ev_mm1x, ev_mm1y, ev_mm1width, ev_mm1height, ev_mm2flags, ev_mm2x, ev_mm2y, ev_mm2width, ev_mm2height, ev_mtlocount, ev_mthicount; /* Ausgabeparameter */ int ev_mwich, ev_mmox, ev_mmoy, ev_mmobutton, ev_mmokstate, ev_mkreturn, ev_mbreturn; /* Message-Buffer */ int ev_mmgpbuf[8]; } EVENT;
Die Elemente der Struktur entsprechen denen des evnt_multi()–Aufrufs. Auch die Reihenfolge der Parameter ist — bis auf wenige Ausnahmen — identisch. Das Feld `ev_mwich' enthält die aufgetretenen Events in der gleichen Kodierung wie `ev_mflags'.
In den folgenden Abschnitten soll versucht werden, noch einige Tips und Hinweise zur xFSL–Schnittstelle zu geben.
Angesichts der Vielzahl der Parameter und Einstellmöglichkeiten erscheint folgender Hinweis angebracht:
Ein xFSL–Aufruf ist einfacher als es zunächst scheint.
Insbesondere kann hier die Strategie der schrittweisen
Verfeinerung
angewendet werden, da man (fast) alle Parameter
zunächst einmal auf Null setzen kann.
Ein möglichst einfacher xFSL–Aufruf kann z.B. so aussehen:
#include <stdio.h> #include <aes.h> #include <vdi.h> #include <xfsl.h> void call_xfsl (void) { int xhandle, xret; xFSL_PAR xpar; PFONTINFO pfont; xFSL *xfsl; memset (&xpar, 0, sizeof (xFSL_PAR)); memset (&pfont, 0, sizeof (PFONTINFO)); xpar.par_size = sizeof (xFSL_PAR); xpar.pfi_size = sizeof (PFONTINFO); xpar.font = &pfont; xpar.font->fontcol = BLACK; if (get_cookie ('xFSL', &xfsl)) { xhandle = xfsl->xfsl_init (0, &xpar); if (xhandle >= 0) { do xret = xfsl->xfsl_event (xhandle, 0L); while (xret > xFS_OK); xfsl->xfsl_exit (xhandle); if (xret == xFS_STOP) printf ("Abbruch\n"); else if (xret == xFS_OK) printf ("Font mit ID %d ausgewählt\n", xpar.font->fontid); else if (xret < 0) printf ("Fehler %d\n", xret); } else printf ("Fehler %d\n", xhandle); } else printf ("Cookie nicht gefunden!\n"); }
Mit den beiden memset–Aufrufen werden alle Elemente der Strukturen xFSL_PAR und PFONTINFO auf Null gesetzt. Anschließend werden einige unbedingt nötige Werte eingetragen:
die Adresse der PFONTINFO–Struktur wird in der
xFSL_PAR–Struktur eingetragen
die Schriftfarbe wird auf schwarz gesetzt (dies könnte man
auch weglassen, aber normalerweise wird man ja in schwarzer Schrift
auf weißem Grund schreiben wollen)
Mehr ist an Vorbereitungen nicht nötig, es folgt nun der eigentliche Aufruf. Zunächst wird der xFSL–Cookie gesucht. Im Erfolgsfall wird nun der Fontselektor initialisiert, indem die xFSL_PAR–Struktur übergeben wird. War dieser Aufruf erfolgreich (`xhandle' ist größer oder gleich Null), so befindet sich der Fontselektor bereits auf dem Bildschirm. In der Hauptschleife wird nun gewartet, bis der Fontselektor entweder mit xFS_STOP oder xFS_OK vom Anwender beendet wird oder bis ein Fehler auftritt (andere positive Rückgabewerte werden hier einfach ignoriert). Mit dem Aufruf von xfsl_exit wird der Fontselektor wieder vom Bildschirm entfernt und anschließend der Rückgabewert ausgewertet.
Das war doch gar nicht so kompliziert, oder? Von hier aus können Sie nun mit den diversen Parametern und Flags weiter experimentieren.
Wie kann ich feststellen, welche Features der Fontselektor bietet?
Direkt kann dies für einige Features über die Funktion xfsl_info geschehen. Indirekt können weitere Features über das Feld `control' in der xFSL_PAR–Struktur abgefragt werden: Nach einem erfolgreichen xfsl_init–Aufruf wird der Fontselektor diejenigen Kontrollflags löschen, die er nicht versteht.
Wie soll sich mein Programm verhalten, wenn es feststellt, daß der Fontselektor das gewünschte Feature nicht unterstützt?
Wenn überhaupt ein Fontselektor installiert ist, sollte dieser auch auf jeden Fall verwendet werden. Je nachdem, wie wichtig das vermißte Feature ist, könnte sich Ihr Programm nach Alternativen umsehen (z.B. über das Font-Protokoll) oder versuchen, das fehlende Feature zu kompensieren.
Auch hier gilt wieder: Der Anwender wollte einen Fontselektor, keine Fehlermeldung. Wenn das fehlende Feature nur schwer zu kompensieren ist, dann sollten Sie den Anwender einmalig(!) mit einem entsprechenden Hinweis informieren, aber trotzdem den Fontselektor aufrufen. Auch wenn die Auswahl dann nicht mit dem gewünschten Komfort geschehen kann, ist dies für den Anwender immer noch weniger frustrierend, als überhaupt keinen Font auswählen zu können.
Einige Beispiele: Sollte über das Popup der Font für bestimmte Fenster des Programms eingestellt werden, so sollte er bei fehlendem Popup für das oberste Fenster des Programms übernommen werden. Unterstützt der Fontselektor das Sperren der Größenänderung nicht, so sollte die zurückgelieferte Größe einfach ignoriert werden und — wenn sie von der gewünschten Größe abweicht — der Anwender durch einen Hinweis davon in Kenntnis gesetzt werden.
Man sollte sich übrigens nicht darauf verlassen, daß der Fontselektor beim nächsten Aufruf noch der gleiche ist bzw. die gleichen Features unterstützt! Die Fontselektoren, die mit einem Overlay (XFSL.OVL) arbeiten können durch einfaches Umkopieren des Overlays jederzeit ohne Reset ausgewechselt werden.
Was hat es mit diesem Mapping
auf sich?
Vektorfonts enthalten meist wesentlich mehr als die üblichen
256 Zeichen, noch dazu normalerweise nicht in der gewohnten
ASCII–Codierung (beispielsweise könnte das Leerzeichen auf
Position 0 statt auf 32 liegen). Daher werden die entsprechenden
Zeichen aus dem Font auf die normalen
256 Zeichen
gemappt
(d.h. abgebildet), so daß sich das Leerzeichen wie
gewohnt an Position 32 befindet, unabhängig davon, welche Position es
innerhalb des Fonts hat. Dieses bezeichnet man als ASCII–Mapping.
Per Default ist das ASCII–Mapping aktiv. Dadurch kann man
aber die Zeichen, die außerhalb des ASCII–Zeichensatzes liegen,
nicht ansprechen. Als zweites Mapping steht daher das direkte
Mapping
zur Verfügung. Hier hat man nun Zugriff auf alle
Zeichen eines Fonts. Allerdings muß man dazu auch wissen, um welche
Art von Font es sich handelt und wieviele Zeichen der Font enthält:
Speedofonts haben meist 564 Zeichen, TrueType–Fonts können
(theoretisch) bis zu 65536 Zeichen enthalten. Diese Information
erhält man nach dem Umschalten auf das direkte Mapping mit der
VDI–Funktion vqt_fontinfo():
int minADE, maxADE; vst_charmap(handle,0); vqt_fontinfo(handle,&minADE,&maxADE,dumarray,&dummy,dumarray);
In `minADE' erhält man den kleinsten, in `maxADE' den größten gültigen Zeichenindex.
Das direkte Mapping ist für normale Anwendungen nur
eingeschränkt brauchbar. Im Gegensatz zum ASCII–Mapping, das ein
einheitliches Mapping für alle Arten von Fonts darstellt, muß man
hier nämlich ganz genau wissen, um welche Art von Font es sich
handelt. So haben z.B. die Speedo–Symbolfonts eine andere
Codierung als die normalen
Speedofonts. D.h. daß man an
Position 64 eines solchen Symbolfonts nicht das gleiche Zeichen
vorfinden wird wie bei einem normalen
Speedofont.
Andere Mappings als ASCII sind daher z.Z. für den Großteil der Programme uninteressant. Künftige GDOSse werden aber möglicherweise noch andere einheitliche Mappings (z.B. Unicode oder BICS) anbieten, bei denen man sich dann wieder darauf verlassen kann, daß an einer bestimmten Position auch immer das gleiche Zeichen liegt (ähnlich wie beim ASCII–Mapping, nur eben auch bei Positionen größer 255).
Die Beschreibung der xFSL–Schnittstelle in diesem Text erfolgt in Pure C. In den folgenden Abschnitten werden die Datentypen und Besonderheiten von Pure C näher beschrieben, damit xFSL–Aufrufe auch aus anderen Programmiersprachen und C–Dialekten gelingen.
In diesem Text werden die folgenden Datentypen verwendet:
Name Größe ---------------------------------------- int 16 Bit mit Vorzeichen unsigned int 16 Bit ohne Vorzeichen long 32 Bit mit Vorzeichen unsigned long 32 Bit ohne Vorzeichen
Der Datentyp char ist ein (ASCII–)Zeichen und wird hier nur als Zeigertyp verwendet, d.h. als Zeiger auf einen C–String (eine Folge von Zeichen, die mit einem Nullbyte abgeschloßen sind).
Union
Eine Union entspricht einem varianten Record in Pascal. Es
handelt sich um eine Struktur, deren einzelne Elemente
übereinander
liegen, d.h. denselben Speicherbereich belegen.
Welches Element gerade gültig ist, ergibt sich aus dem Kontext bzw.
bleibt dem Programmierer überlassen.
Beispiel: In der Struktur PFONTINFO wird für die Größenangabe eine Union `fsize' verwendet:
union fsize { int size; /* Fontgröße in Punkt */ fix31 size31; /* Fontgröße in 1/65536 Punkt */ };
Der Speicherbedarf dieser Union beträgt vier Bytes, da der Typ fix31 vier Bytes groß ist. Man könnte nun dem Element `size31' eine Größenangabe in 1/65536 Punkt zuweisen und dann den Wert in ganzen Punkt aus dem Element `size' auslesen — dies ist aber nicht empfehlenswert, da bei der Umrechnung fix31 nach pt immer gerundet werden sollte, s.u.
Der Datentyp fix31 ist eine Festkommazahl, bei dem die oberen 16 Bit den vorzeichenbehafteten Vorkomma-Anteil darstellen und die unteren 16 Bit den vorzeichenlosen Nachkomma-Anteil. Er wird ausschließlich für Größenangaben von Fonts verwendet, die damit auf 1/65536 Punkt genau angegeben werden können.
Bei der Umrechnung von fix31 nach pt darf man das Runden nicht vergessen. Zitat aus dem NVDI–Guide:
Man darf nie, nie, niemals den Nachkommateil einfach abschneiden!
Die Übergabe der Parameter bei allen xFSL–Aufrufen geschieht über den Stack nach C–Konvention. D.h. daß der beim Aufruf am weitesten rechts stehende Parameter zuerst auf den Stack gelegt wird und der am weitesten links stehende Parameter zum Schluß, d.h. beim Einsprung in den Fontselektor, obenauf liegt.
Pure C übergibt die Parameter an Funktionen normalerweise in
Registern. Für eine Übergabe über den Stack muß entweder das
Schlüsselwort cdecl
verwendet werden (wie im
Includefile XFSL.H geschehen) oder der Compilerschalter
-H
gesetzt werden.
Das Schlüsselwort cdecl
ist eine
Pure–C–spezifische Erweiterung und wird daher bei
gesetztem Compilerschalter -A
(ANSI-Konformität)
angemahnt.
Revision 4
Aufgrund eines kleinen Designfehlers in den älteren
Revisionen, der die Erweiterbarkeit der Schnittstelle einschränkte,
ist Revision 4 nicht kompatibel zu älteren Revisionen. Dies
sollte in der Praxis kein Problem darstellen, da der Fontselektor
Aufrufe nach dem alten Schema mit einem Fehler quittieren wird. Die
alte Revision 3 wird im Laufe der Zeit verschwinden.
neue Parameter in der PFONTINFO–Struktur:
Text–Hintergrundfarbe (`backcol')
Textausrichtung (`halign' und `valign')
Textrotation (`rotation')
Angabe von Zeichen, die der ausgewählte Font unbedingt
enthalten soll (`validtype' und `validchars')
die PFONTINFO–Struktur wird auch bei Rückgabe
xFS_STOP mit den Werten des zuletzt im Fontselektor
ausgewählten Fonts gefüllt
Codierung der Fontflags geändert (feinere Unterscheidung der
Vektorformate)
Revision 3
die erste öffentlich verfügbare Schnittstellen–Revision
ältere Revisionen
ältere Revisionen können getrost ignoriert werden, da diese
niemals in einem für eine größere Öffentlichkeit verfügbaren
Programm in Erscheinung getreten sind
Es folgt eine Übersicht über alle z.Z. erhältlichen Fontselektoren, die über eine UFSL– oder eine xFSL–Schnittstelle (oder beides) verfügen.
Desweiteren folgt eine Liste von Programmen, die einen Fontselektor mit einer der beiden Schnittstellen verwenden.
Eine kleine Übersicht über die existierenden Fontselektoren:
von Michael Thänitz
Dies ist der Prototyp aller externen Fontselektoren. Die letzte
veröffentliche Version ist 0.97, danach hat Michael leider die
Entwicklung eingestellt. Dankenswerterweise hat er aber die Quelltexte
veröffentlicht.
von Holger Weets und Christoph Zwerschke
Ein kleiner, aber auch etwas spartanischer Fontselektor von Holger
Weets, der seit der Version 1.02 von Christoph Zwerschke
weiterentwickelt wird. Ab der Version 1.02 wird auch die
xFSL-Schnittstelle unterstützt.
von Stefan Rogel
Der xUFSL bietet gegenüber den bisher genannten Fontselektoren
viele zusätzliche Features. Da diese über die existierende
UFSL-Schnittstelle nicht angesprochen werden konnten, hat Stefan die
Schnittstelle erweitert. Das Design der ersten Version war, vorsichtig
ausgedrückt, umstritten
. Letzte veröffentlichte Version:
1.05. Nachfolger des xUFSL ist …
von Stefan Rogel
HuGo! ist der an die xFSL–Schnittstelle angepaßte
Nachfolger des xUFSL (die UFSL-Schnittstelle wird ebenfalls noch
unterstützt, nicht aber die speziellen Erweiterungen des xUFSL an der
UFSL–Schnittstelle). Die Namensänderung wurde vollzogen, um
Verwechslungen zu vermeiden.
von Dirk Haun
Zusammen mit HuGo! der erste Fontselektor mit
xFSL–Schnittstelle. Auch Calvino unterstützt noch die einfache
UFSL–Schnittstelle.
von Christian Grunenberg
Diese beiden Programme arbeiten auf Drag&Drop–Basis, sie
unterstützen also weder die UFSL– noch die
xFSL–Schnittstelle, dafür aber das Font–Protokoll.
FONT_SEL ist ein Fontselektor, FONT_PAL eine
Fontpalette (mit integriertem Fontselektor).
Folgende Programme unterstützen einen externen Fontselektor (Stand 16.08.1998, alle Angaben und E-Mail-Adressen ohne Gewähr):
Program | Category | Author | UFSL | xFSL |
800XL-Deejay | Laufwerksemulator | Kolja Koischwitz | + | |
APP_List | Systemutility | Ralf Zimmermann | + | |
Bellini | Grafikprogramm | Ingo Dehne | + | |
BibelST | Bibel-Software | Reinhard Bartel | + | |
Cat2Maus | MausTausch | Harald Sommerfeldt | + | |
Chatwin | Shell | Dirk Haun @ LB | +F | +F |
CyPress | Textverarbeitung | Rene Bartholomay | +F | |
DB-Point | Newsreader | Michael Heng | + | |
Disk Cake | Diskutility | Christoph Zwerschke | + | + |
Egale | Dateiutility | David Reitter | + | + |
Everest | Editor | Oliver Schmidt | + | |
Face Value | App.Builder/Lib | Vegard Hofsoy | - | + |
Floh | Filelisten-Util. | Heiko Schaefer | + | |
GEMAR | Backup | Steffen Engel | + | |
GEM-Fontviewer | Zeichensatz-Anzeige | Reinhard Bartel | + | + |
GEM-Plan | Tabellenverwaltung | Reiner Rosin | +F | |
Hitchcock | Systemutility | Thorsten Pohlmann | + | |
IdeaList | ASCII-Druckprogramm | Christoph Bartholme | + | |
Imagin | Funktionsplotter | Reinhard Maier | + | |
Jedi | GAL-Assembler | Ralf Zimmermann | + | |
Kandinsky | Zeichenprogramm | Ulrich Rossgoderer | + | |
MagiC!Conf | MagiC-Utility | Christian Ratsch | + | |
MasterBrowse | Dateiviewer | Michel Forget | + | |
MenuInfo | Systemutility | Dirk Hagedorn | +F | |
Okami | Newsreader | Wolfram Rösler | + | |
Photo Line | Bildverarbeitung | Gerhard Huber | + | |
QED | Editor | Christian Felsch | + | |
RoadRunner | Autofahrtplanung | Andreas Schrell | +F | |
SaugUtility | dito | Frank Rüger | + | |
Schecks | Businessoftware | Christian Lehmann | + | |
ST-Guide | Hypertext | Holger Weets | + | |
STJ-Oberon | Programmiersprache | Stephan Junker | + | + |
Texel | Tabellenkalkulation | Thomas Much | + | + |
UpToCASE | CASE-Tool | Michael Nolte | + | |
VESAL | Lernprogramm | Peter Klasen | + | |
Zeig's mir | Dateiviewer | Reiner Rosin | + | +F |
(+: unterstützt, F: als Fensterdialog; E-Mail-Adressen: MausNet)
Der Vollständigkeit halber folgt hier noch die Original–Beschreibung von Michael Thänitz zur ursprünglichen UFSL-Schnittstelle:
Programmierschnittstelle:
UFSL ist eine Fontauswahlbox für den Autoordner. Sie bietet dem Programmierer eine einfache Programmierschnittstelle über einen Cookie.
Der Cookie lautet: UFSL
.
Der Cookie liefert einen Zeiger auf folgende Struktur:
typedef struct { unsigned long id; /* UFSL ID (UFSL) */ unsigned int version; /* Version (BCD-Format) */ int dialtyp; /* 0=Dialog, 1=Fenster */ int cdecl (*font_selinit)(void); int cdecl (*font_selinput)( int vdihandle, int dummy, char *text, /* eigener Text, max. 34 Zeichen */ int ftype, /* 1=nur monospaced Fonts, 0=alles */ int *fretid, /* eingestellte FontId */ int *fretsize /* eingestellte Fontgröße */ ); OBJECT *helpbutton; /* Typ: BOXTEXT */ void cdecl (*helpfunc)(void); /* Benutzerdefinierte Helpfkt. */ /**** ab Version 0.91 ********************************************/ char *examplestr; /* Beispieltext für Fontdarstellung */ /**** ab Version 0.96 ********************************************/ void cdecl (*msgfunc)(int event, int msgbuf[]);/* Redrawfunktion */ /**** ab Version 0.97 ********************************************/ int cdecl (*fontsel_exinput)( int vdihandle, int ftype, /* 1=nur monospaced Fonts, 0=alles */ char *text, /* eigener Text, max. 34 Zeichen */ int *fretid, /* eingestellte FontId */ int *fretsize /* eingestellte Fontgröße */ ); } UFSL;
Aufruf:
UFSL *ufsl; ufsl=(UFSL *)get_cookie('UFSL'); ufsl->helpfunc= my_helpfunc; /* Hilfefunktion oder NULL */ ufsl->msgfunc = my_msghandler; /* Redrawfunktion oder NULL, Dialtyp beachten */ ufsl->fontsel_input(vdihandle,"Bitte Font auswählen",0,&id,&size); oder ufsl->fontsel_input(vdihandle,NULL,0,&id,&size);
Returncodes:
1 : Alles OK, Werte gültig. 0 : Abbruch gewählt. -1 : Out of memory. -2 : Unzulässiger Mehrfachaufruf. -3 : Fontgröße konnte nicht identifiziert werden. -4 : Anzahl Fonts muß größer null sein.
Sonderfunktionen:
void cdecl (*helpfunc)(void); /* Benutzerdefinierte Helpfkt. */
UFSL kann eine benutzerdefinierbare Hilfefunktion über den ebenfalls optionalen Hilfebutton aufrufen. helpfunc() benötigt keine Parameter und liefert auch keinen Wert zurück.
void cdecl (*msgfunc)(int event, int msgbuf[]); /* Redrawfunktion */
Bei Verwendung von UFSL als Fensterdialog ist es notwendig eine Redrawfunktion zur Verfügung zu stellen. Sie schickt die anfallenden Events an das aufrufende Programm zurück, damit nach Verschieben des Dialogs die Hintergrundfenster restauriert werden können. msgfunc() liefert als ersten Parameter das Ergebnis von evnt_multi() und als zweiten Parameter die MsgPipe. Ein Returncode wird nicht benötigt. Das Anwenderprogramm muß die nötigen Routinen zur Fensterbehandlung zur Verfügung stellen. wind_update(..._UPDATE) wird von UFSL nicht gesetzt, obliegt also dem rufenden Anwenderprogramm. Prinzipbedingt (?) ist die Memoryprotection von MTOS auszuschalten.
Grundsätzlich gilt es zu überlegen, ob tatsächlich alle Events entsprechend beantwortet werden sollen. Ein WM_TOPPED, das andere eigene Fenster nach vorn bringt, sollte wohl nicht beantwortet werden, da UFSL naturgemäß nur applikationsmodal sein kann, da UFSL ja in einem eigenen form_do() sprich evnt_multi() kreist.
Autoren anderer Fontselektoren sind dazu eingeladen, sich der xFSL–Schnittstelle anzuschließen. Im Prinzip kann jeder Fontselektor, der als TSR konzipiert ist, mit der xFSL–Schnittstelle ausgerüstet werden.
Damit keine Mißverständnisse entstehen: Die
Overlay–Technik und die Reentranz, wie sie Calvino und HuGo!
bieten, sind nicht Teil der eigentlichen Schnittstelle und müssen von
anderen Fontselektoren daher auch nicht unterstützt werden.
Allerdings ist auch die Schnittstelle zwischen dem residenten Teil
(Shell
) und dem nachgeladenen Teil (Overlay
) genormt und
kann daher auch von anderen Fontselektoren verwendet werden. Eine
Beschreibung dieser internen Schnittstelle ist auf Anfrage
erhältlich, siehe Kontaktadressen
.
Da bereits eine Reihe von Programmen die alte UFSL–Schnittstelle unterstützen, erscheint es ratsam, auch in neuen Fontselektoren diese Schnittstelle noch zur Verfügung zu stellen. Jedoch zeigt ein kurzer Blick auf diese Programme, daß sie fast ausschließlich den Fontselektor als modalen Dialog aufrufen. Die Empfehlung lautet daher, eine minimale UFSL–Unterstützung einzubauen (nur als modaler Dialog) und dafür die xFSL–Schnittstelle möglichst weitgehend zu implementieren, da zu erwarten steht, daß gerade die — nun endlich genormten — Erweiterungen gegenüber der UFSL-Schnittstelle von den Programmen verwendet werden sollen.
Ein Fontselektor sollte möglichst die folgenden zusätzlichen Features bieten:
Größenänderung möglich
Insbesondere ist damit gemeint, daß nicht nur eine Größe
ausgewählt, sondern bei Vektorfonts auch die Zwischengrößen
eingestellt werden können.
fix31–Unterstützung
Für einige Anwendungen reicht die Einstellung der Fontgröße in
Punkt nicht aus, daher sollte auch eine Einstellung in 1/65536 Punkt
möglich sein.
User–Popup
Durch das zusätzliche Popup wird der Fontselektor flexibler
einsetzbar.
Drag&Drop–Unterstützung
Neben dem traditionellen
Aufruf über den Cookie kommen
Lösungen auf Drag&Drop–Basis immer mehr in Mode. Wenn der
Fontselektor von sich aus schon Drag&Drop unterstützt, läßt er
sich leicht durch ein kleines Frontend
-Programm in einen
vollwertigen Drag&Drop–Selektor verwandeln.
Folgende Konventionen wurden für einen xFSL–Fontselektor vereinbart:
Wenn der Fontselektor über einen Closer verfügt, so wird
dieser als Abbruch
interpretiert, d.h. es wird xFS_STOP
zurückgegeben. Ist das Kontrollflag CC_CLOSER gesetzt, wird
der gerade aktuelle Font aber trotzdem zurückgegeben (in der
PFONTINFO–Struktur in xFSL_PAR).
Wenn der erweiterte Aufruf (xfsl_init,
xfsl_event und xfsl_exit) nicht unterstützt wird,
muß zumindest eine Dummy–Funktion für xfsl_init
installiert werden, die immer -32 (Gemdos–Fehlermeldung
EINVFN, ungültige Funktionsnummer) zurückgibt.
Es wird aber dringend empfohlen, den erweiterten Aufruf
anzubieten, da dieser am häufigsten verwendet wird.
Es ist legal, daß der Fontselektor beim erweiterten Aufruf nur
als modaler Dialog erscheint. Bei gesetztem CC_WINDOW sollte
xfsl_init dann aber xFS_NO_WINDOW zurückgeben, damit
sich der Aufrufer darauf einstellen kann.