Das AES (Application Environment Services) bildet die obere Schicht des GEM. Es befasst sich mit all jenen GEM-Bestandteilen, die über elementare Grafikausgaben und -eingaben hinausgehen. Da das AES ausschließlich VDI- und GEMDOS-Aufrufe tätigt, ist es sowohl von der Grafikhardware, vom Eingabegerät als auch vom Dateisystem unabhängig. In diesem Abschnitt werden die folgenden Punkte behandelt:
Auch beim AES gibt es eine interessante Entwicklung, denn verschiedene Programmierer haben mittlerweile eigene AES-Clones angekündigt; zur Zeit sind hier die Projekte N.AES und XaAES zu nennen. Neben einer stetigen Weiterentwicklung darf man wohl auch auf eine Quelltext-Version dieser GEM Komponente hoffen.
Querverweis: Style-Guidelines
Um zu testen, ob eine Applikation als Programm oder als Accessorie gestartet worden ist, kann man wie folgt vorgehen:
wenn beim Programmstart das Register a0 den Wert Null hat, dann
handelt es sich um einen normalen Programmstart
anderenfalls handelt es sich um ein Accessorie, und Register a0
enthält einen Zeiger auf die (unvollständig) ausgefüllte BASEPAGE.
Die TPA ist bereits passend geschrumpft (auf die Summe von
Basepagegröße und der Länge der drei Programmsegmente), ein Stack
muß erst noch angelegt werden.
Hinweis: Mit diesen Informationen ist es kein Problem, den Startupcode für ein Programm so zu gestalten, daß es selbständig erkennt, wie das Programm gestartet worden ist, und entsprechend die Initialisierung fortzusetzen. Bei den meisten C-Compilern wird im Startupcode automatisch die externe Variable _app initialisiert, die genau dann gleich Null ist, wenn das Programm als Accessorie gestartet worden ist. Damit kann man Programme so entwickeln, daß sie sowohl als Accessorie als auch als normales Programm eingesetzt werden können.
Querverweis: AES Accessories in MagiC Programmstart und TPA
Unter MagiC sind Accessories den Programmen fast gleichgestellt. Ihre Fenster bleiben beim Programmwechsel erhalten. Sie dürfen Menü und Desktophintergrund besitzen, Programme nachladen, Speicher anfordern, Dateien öffnen, schließen, löschen, kopieren usw.
Da kein Grund mehr besteht, beim Programmwechsel Fenster zu schließen, gibt es keine AC_CLOSE Meldung mehr. Accessories werden vom System nicht von Programmen unterschieden, abgesehen davon, daß sie sich keinesfalls beenden dürfen. ACCs dürfen sich wie unter GEM/2 auch wieder im Menü abmelden, und zwar mit dem AES-Aufruf menu_unregister(). Anstelle von ACCs sind unter MagiC Applikationen sinnvoll, die einfach nur eine Menüleiste mit einem Menü anmelden und im APP- Autostart- Ordner liegen. Diese Applikationen kann man dann bei Bedarf nachladen und auch wieder entfernen.
Hinweis: Ab MagiC-4 können Accessories zur Laufzeit nachgestartet werden. Ferner ist es möglich, bei einem Klick auf einen Accessory-Eintrag (und gedrückter Control-Taste) das entsprechende Accessory zu entfernen. Ein Nachteil ist, daß Accessories z.Zt. noch kein Pexec mit Modus 104 ausführen dürfen.
Querverweis: AES GEM Startupcode für Accessories shel_write
Unter den verfügbaren Fenstern nimmt das Desktop- oder Hintergrundfenster eine besondere Rolle ein. Es besitzt die Kennung 0, nimmt die gesamte Bildschirmfläche in Anspruch, ist immer geöffnet und kann auch nicht geschlossen werden. Der Arbeitsbereich ist die Fläche unter der Menüleiste. Nur in diesem Arbeitsbereich dürfen andere Programme Bildschirmausgaben machen oder eigene Fenster öffnen.
Normalerweise erscheint der Arbeitsbereich des Desktop als solide grüne Fläche (im Farbbetrieb) bzw. als graues Raster (im Monochrombetrieb). Der Screen-Manager kümmert sich völlig selbsttätig um den Redraw; über einen Aufruf von wind_set können Anwendungsprogramme einen beliebigen anderen Objektbaum als Hintergrund verankern. Auch dann kümmert sich der Screen-Manager um das fällige Neuzeichnen von Bildausschnitten. Obwohl diese Möglichkeit sehr verlockend ist, gibt es etliche Gründe, die gegen eine Benutzung des Desktop-Fensters sprechen; der wichtigste:
auch unter einem multitaskingfähigen GEM (MagiC oder
MultiTOS), kann es nur einen Bildschirmhintergrund geben.
Dieser sollte dem Programm vorbehalten bleiben, das daraus den meisten
Nutzen ziehen kann - in der Regel ist dies das Desktop bzw. ein
Desktop-Ersatz wie z.B. die Shell Gemini.
Fazit: Der Desktop-Hintergrund sollte nach Möglichkeit in eigenen Programmen nicht benutzt werden.
Querverweis: AES wind_set WF_NEWDESK
Um Dateien im Klemmbrett abzulegen, sollte man folgendermaßen vorgehen:
Der Dateiname ist immer 'scrap.', die Namenserweiterung (Suffix) hängt dabei vom gewählten Format ab; nach Möglichkeit sollte immer eines der folgenden Standardformate unterstützt werden:
Suffix | Bedeutung |
gem | Vektorgrafiken im Metafile-Format |
img | Pixelbilder im XIMG-Format |
txt | ASCII-Textdatei, jede Zeile mit CR/LF abgeschlossen |
Zusätzlich kann man eines oder mehrere der folgenden Formate unterstützen (der Empfänger hat dann die Möglichkeit, das Format mit den meisten Informationen zu benutzen):
Suffix | Bedeutung |
asc | ASCII-Textdatei, jeder Absatz mit CR/LF abgeschlossen |
csv | ASCII-Datei mit durch Kommata getrennten Zahlen |
cvg | Calamus Vektorgrafik-Format |
dif | Export-Datei von Tabellenkalkulationen |
eps | Encapsulated PostScript |
1wp | Wordplus-Format |
rtf | Microsoft Rich Text Format |
tex | TeX |
Das empfangende Programm sollte zunächst überprüfen, welche der vorhandenen Dateien die meisten Informationen enthält, und dann diese Datei nehmen.
Wichtig: Jede der Dateien im Klemmbrett enthält prinzipiell die gleichen Informationen, nur eben in einem anderen Format. Die Textverarbeitung Papyrus z.B. importiert 'scrap.rtf' nur dann, wenn das eigene Format 'scrap.pap' nicht gefunden werden konnte.
Aus den obigen Erklärungen wird ersichtlich, daß sich immer nur ein Datenobjekt (allerdings in verschiedenen Formaten) auf einmal im Klemmbrett befinden kann.
Querverweis: Klemmbrett-Funktionen scrp_clear Style-Guidelines
Die Datenstruktur des Objektbaums ist zwar kein Baum im Sinne eines Binärbaums, besitzt jedoch innerhalb eines Zeigers die logischen Verkettungen eines Baums, mit Vorgängern und Nachfolgern. Die Spezifikation von Vorgängern und Nachfolgern wird durch Indizes auf ein Array vorgenommen.
Die Baumstruktur der einzelnen Objekte kann man sich am leichtesten an Hand eines einfachen Beispiels veranschaulichen: Ein Menü setzt sich zunächst aus der Menüleiste zusammen. Diese enthält wiederum mehrere Titeltexte. Die Titeltexte sind also direkt in der Menüleiste enthalten, sie sind beide Nachfolger des Objekts 'Menüleiste', bewegen sich also auf der selben hierarchischen Ebene. Das Objekt Menüleiste verweist mit ob_head auf den ersten Menütitel und mit ob_tail auf den letzten Menütitel. Im ersten Menütitel dient der Zeiger ob_next zur Adressierung des nächsten Menütitels. Die Verkettung weist also folgende Struktur auf:
Menüleiste: +---------+---------+--------+ | ob_head | ob_tail | ... | | o | o | | +----|----+----|----+--------+ | +-------------------------+ V V +---------+---------+--------+ +---------+---------+--------+ | ... | ob_next | ... | ... | ... | ... | ... | | | o | | | | | | +---------+----|----+--------+ +---------+---------+--------+ 1.Menütitel | n-ter Menütitel +-----> 2.Menütitel
Welche Aktionen mit einem Objekt durchgeführt werden dürfen, wird in ob_flags festgelegt. Der Zustand eines Objekts wird im Eintrag ob_state festgehalten. Der Eintrag ob_type legt den Objekttyp fest. Manche Objekte benötigen zur exakten Festlegung eine zusätzliche Datenstruktur, wie TEDINFO oder BITBLK. In ob_spec wird dann ein Zeiger auf diese zusätzliche Struktur abgelegt. Zusammenfassend nochmals der Gesamtaufbau der Datenstruktur für Objekte OBJECT:
+-------------+ | ob_next | Index für das nächste Objekt +-------------+ | ob_head | Index des ersten Kindes +-------------+ | ob_tail | Index des letzten Kindes +-------------+ | ob_type | Objektart +-------------+ | ob_flags | Manipulationsflags +-------------+ | ob_state | Objektstatus +-------------+ | ob_spec | siehe unter Objektart +-------------+ | ob_x | relative x-Koordiante zum Eltern-Objekt +-------------+ | ob_y | relative y-Koordinate zum Eltern-Objekt +-------------+ | ob_width | Breite des Objekts +-------------+ | ob_height | Höhe des Objekts +-------------+
Querverweis: Objektfarben des AES Objektart Manipulationsflags Objektstatus
Folgende Objektarten stehen zur Auswahl:
Art | Bedeutung
| ||||||
G_BOX (20) | Rechteckiger Kasten. ob_spec enthält verschiedene
Informationen über Rahmenstärke, Farbe und ähnliches.
| ||||||
G_TEXT (21) | Grafiktext, ob_spec zeigt auf TEDINFO-Struktur.
| ||||||
G_BOXTEXT (22) | rechteckiger Kasten mit Grafiktext, ob_spec zeigt auf
TEDINFO-Struktur.
| ||||||
G_IMAGE (23) | Bild, ob_spec zeigt auf BITBLK-Struktur.
| ||||||
G_USERDEF (24) | Benutzerdefinierte Funktion zum Zeichnen eines eigenen Objekts.
ob_spec verweist auf eine USERBLK Struktur.
| ||||||
G_IBOX (25) | Transparentes Rechteck, das nur gesehen werden kann, wenn die
Umrandung nicht die Dicke Null hat. ob_spec enthält weitere
Informationen über das Aussehen.
| ||||||
G_BUTTON (26) | Text mit Rahmen für Optionsauswahl. ob_spec zeigt auf eine
Zeichenkette mit dem Text, der in dem Knopf erscheinen soll.
Neu ab MagiC-Version 3.0: Ist das Objektflag WHITEBAK gesetzt, und Bit-15 im Objektstatus = 0, so wird der Button unterstrichen; dabei gilt: (Highbyte&0xf) von ob_state ist die gewünschte Unterstreichposition. Falls hingegen Bit-15 = 1 ist, so handelt es sich um einen Sonderbutton (Radio-Button oder Checkbox). Weitere Besonderheiten: WHITEBAK=1, Bit-15 = 1 und in ob_state
(dabei ist wieder (Highbyte&0xf) von ob_state die Unterstreichposition). Das Vorhandensein dieser Features sollte am besten über die Funktion appl_getinfo (Opcode 13) ermittelt werden. | ||||||
G_BOXCHAR (27) | Rechteck, mit einem Zeichen. In ob_spec wird nicht nur das
Aussehen der Umrandung, sondern auch das Zeichen definiert.
| ||||||
G_STRING (28) | Zeichenkette, ob_spec zeigt auf den String.
Neu ab MagiC-Version 3.0: Ist das Objektflag WHITEBAK gesetzt, und das Highbyte von ob_state != -1, so wird der String unterstrichen; die Unterstreich-Position wird dabei durch (Highbyte & 0xf) von ob_state geregelt. Bei gesetztem WHITEBAK-Flag und Highbyte von ob_state = -1, wird der komplette String unterstrichen. Das Vorhandensein dieser Features sollte am besten per appl_getinfo (Opcode 13) ermittelt werden. | ||||||
G_FTEXT (29) | Formatierter Grafiktext, ob_spec zeigt auf TEDINFO-Struktur
| ||||||
G_FBOXTEXT (30) | Rechteck mit formatiertem Grafiktext, ob_spec zeigt auf
TEDINFO-Struktur.
| ||||||
G_ICON (31) | Icon-Symbol, ob_spec zeigt auf die ICONBLK-Struktur.
| ||||||
G_TITLE (32) | Titel eines Drop-Down-Menüs, ob_spec zeigt auf den String.
Ab MagiC-2 kann dabei auch ein Buchstabe unterstrichen werden. Dies geht wie folgt: WHITEBAK in ob_state setzen
| ||||||
G_CICON (33) | Farb-Icon, ob_spec zeigt auf die CICONBLK-Struktur.
| ||||||
G_CLRICN (33) | Colour icon, ob_spec zeigt auf die ICONBLK-Struktur. Supported
in the ViewMAX/3 beta and in FreeGEM
| ||||||
G_SWBUTTON (34) | Cycle-Button (d.h. ein Button, der beim Anklicken seinen Text
zyklisch ändert), ob_spec zeigt auf eine SWINFO-Struktur. Das
Vorhandensein dieses Objekttyps sollte per appl_getinfo (Opcode 13) erfragt
werden.
| ||||||
G_DTMFDB (34) | For internal AES use only: desktop image. The ob_spec is a
pointer to a MFDB structure. Supported in the ViewMAX/3 beta and in
FreeGEM.
| ||||||
G_POPUP (35) | PopUp-Menü, ob_spec zeigt auf eine POPINFO-Struktur. Falls das
Menü mehr als 16 Einträge umfaßt, so ist dieses scrollbar. Das
Vorhandensein dieses Objekttyps sollte per appl_getinfo (Opcode 13) erfragt
werden. Hinweis: G_POPUP sieht wie G_BUTTON aus, die Zeichenkette wird
jedoch nicht zentriert, um möglichst mit den Zeichenketten im Menü
auf einer Linie zu liegen.
| ||||||
G_WINTITLE (36) | Diese Objektnummer wird von MagiC intern dazu verwendet,
Fenstertitel darzustellen. Der Aufbau dieses Objekttyps kann sich
jederzeit ändern und wird daher nicht dokumentiert.
| ||||||
G_EDIT (37) | Ab MagiC 5.20 steht ein in einer Shared-Library implementiertes
Editobjekt zur Verfügung. ob_spec verweist auf das Objekt. Achtung:
Dieser Typ wird von den Funktionen form_do, form_xdo, form_button, form_keybd,
objc_edit, wdlg_evnt und wdlg_do z.Zt. noch nicht unterstützt, d.h.
die entsprechenden Ereignisse müssen selbst (per edit_evnt) an das
Objekt weitergeleitet werden.
| ||||||
G_SHORTCUT (38) | Dieser Typ wird ähnlich wie G_STRING behandelt, ein
vorhandenes Tastaturkürzel wird jedoch abgespalten und rechtsbündig
ausgegeben. Das Vorhandensein dieses Objekttyps sollte per appl_getinfo
(Opcode 13) erfragt werden.
Die Einführung proportionaler AES-Zeichensätze machte eine neue Strategie für die Ausrichtung der Menüeinträge erforderlich. Um Tastaturkürzel rechtsbündig ausrichten zu können, werden Objekte vom Typ G_STRING innerhalb eines Menüs entsprechend in Kommando und Kürzel aufgespalten. Diese Strategie versagt jedoch bei Menüs, die vom Programm selbst, z.B. innerhalb eines Fensters oder eines Popup-Menüs, verwaltet werden. Um auch hier eine brauchbare Ausrichtung zu erreichen, mußte dieser neue Objekttyp eingeführt werden. | ||||||
G_SLIST (39) | XaAES extended object - scrolling list
|
Hinweis: Für G_BOX, G_IBOX und G_BOXCHAR zeigt die Komponente ob_spec der OBJECT-Struktur nicht auf eine andere Datenstruktur, sondern enthält weitere Informationen zum Aussehen des Objektes. Dabei gilt:
Bits | Bedeutung | ||||||||||||
24..31 | darzustellendes Zeichen (nur bei G_BOXCHAR) | ||||||||||||
16..23 |
| ||||||||||||
12..15 | Rahmenfarbe (0..15) | ||||||||||||
08..11 | Textfarbe (0..15) | ||||||||||||
7 | Text transparent (0) oder deckend (1) | ||||||||||||
04..06 |
| ||||||||||||
00..03 | Innenfarbe (0..15) |
Das Hibyte wird vom AES nur für Submenüs verwendet. Ist das höchste Bit von ob_type 0x8000, sowie das Bit SUBMENU in ob_flags gesetzt, so geben die Bits 8..14 an, welches Submenü mit dem Menüeintrag gekoppelt ist. Jede Applikation kann daher maximal 128 Submenüs haben. MagiC liest aus ob_type stets nur das Lowbyte aus, außer für die Submenü-Behandlung. TOS reagiert auf unbekannte Objekttypen (z.B. die reinen MagiC-Typen G_SWBUTTON usw.) sauber, d.h. die Objekte werden nicht gezeichnet.
Querverweis: Objektstruktur im AES Objektfarben des AES
Die folgende Tabelle enthält die vordefinierten Objektfarben. Einzelheiten hängen natürlich von der gewählten Bildauflösung, sowie den Einstellungen des Benutzers ab.
Nummer | Farbe | Standard RGB-Werte |
WHITE (00) | Weiß | 1000, 1000, 1000 |
BLACK (01) | Schwarz | 0, 0, 0 |
RED (02) | Rot | 1000, 0, 0 |
GREEN (03) | Grün | 0, 1000, 0 |
BLUE (04) | Blau | 0, 0, 1000 |
CYAN (05) | Cyan | 0, 1000, 1000 |
YELLOW (06) | Gelb | 1000, 1000, 0 |
MAGENTA (07) | Magenta | 1000, 0, 1000 |
DWHITE (08) | Hellgrau | 752, 752, 752 |
DBLACK (09) | Dunkelgrau | 501, 501, 501 |
DRED (10) | Dunkelrot | 713, 0, 0 |
DGREEN (11) | Dunkelgrün | 0, 713, 0 |
DBLUE (12) | Dunkelblau | 0, 0, 713 |
DCYAN (13) | Dunkelcyan | 0, 713, 713 |
DYELLOW (14) | Dunkelgelb | 713, 713, 0 |
DMAGENTA (15) | Dunkelmagenta | 713, 0, 713 |
Hinweis: Diese Farben entsprechen auch weitestgehend den unter Windows und OS/2 verwendeten Iconfarben. Über ein geeignetes CPX-Modul können die richtigen RGB-Werte für die ersten 16 Farben eingestellt werden.
Querverweis: Objektstruktur im AES Objektarten des AES
Die Manipulationsflags eines Objektes bestimmen seine Eigenschaften. Folgende Möglichkeiten stehen zu Auswahl:
Flag | Bedeutung
| ||||||||||||||
NONE (0x0000) | Keine Eigenschaften.
| ||||||||||||||
SELECTABLE (0x0001) | Das Objekt ist selektierbar.
| ||||||||||||||
DEFAULT (0x0002) | Wenn der Benutzer die 'Return' oder 'Enter' Taste drückt, wird
dieses Objekt automatisch selektiert. Diese Flag ist pro Baum nur
einmal zugelassen.
| ||||||||||||||
EXIT (0x0004) | Beim Anklicken eines solchen Objektes wird der Dialog beendet
(siehe auch form_do).
| ||||||||||||||
EDITABLE (0x0008) | Dieses Objekt kann vom Benutzer mittels der Tastatur editiert
werden.
| ||||||||||||||
RBUTTON (0x0010) | Haben im selben Objektbaum mehrere Objekte die eigenschaft
RBUTTON, so kann immer nur eines dieser Objekte selektiert sein. Diese
Objekte sollten alle Kinder eines Elternobjekts mit der Objektart
G_IBOX sein. Wird ein anderes Objekt dieser Gruppe ausgewählt, wird
das zuvor selektierte automatisch deselektiert.
| ||||||||||||||
LASTOB (0x0020) | Hierbei handelt es sich um das letzte Objekt innerhalb eines
Objektbaumes.
| ||||||||||||||
TOUCHEXIT (0x0040) | Der Dialog (siehe auch form_do) wird beendet, sobald sich der
Mauszeiger über diesem Objekt befindet, und der linke Mausknopf
gedrückt wird.
| ||||||||||||||
HIDETREE (0x0080) | Das Objekt und seine Kinder werden von objc_draw und objc_find
nicht mehr bemerkt, sobald dieses Flag gesetzt ist. Weiterhin wird das
Flag ab MagiC 5.20 auch von form_keybd ausgewertet, wenn Objekte zu
Tastenkürzeln gesucht werden. Eine Eingabe in versteckte Objekte ist
jedoch immer noch möglich. Um dies zu verhindern, muß das Flag
EDITABLE gelöscht werden.
| ||||||||||||||
INDIRECT (0x0100) | ob_spec zeigt nun auf einen weiteren Zeiger, der dann auf den
eigentlichen Wert von ob_spec zeigt (siehe auch OBJECT). Auf diese
Weise lassen sich die Standarddatenstrukturen wie TEDINFO etc. auf
einfache Art erweitern.
| ||||||||||||||
FL3DIND (0x0200) | Dieses Objekt erzeugt unter MultiTOS ein dreidimensionales
Objekt (unter MagiC (ab Version 3.0) erst ab 16 Farben, und wenn der
3D-Effekt nicht abgeschaltet wurde). Im 3D-Betrieb wird dies als
Indikator aufgefaßt. Bei diesen Objekten handelt es sich i.d.R. um
Buttons, die einen Status anzeigen, beispielsweise Radio-Buttons.
| ||||||||||||||
ESCCANCEL (0x0200) | Das Drücken der ESC Taste entspricht einem Anwählen des
Objekts mit diesem Flag. Deshalb darf es nur ein Default Objekt in
einem Dialog geben. Only effective in ViewMAX/2 and later.
| ||||||||||||||
FL3DBAK (0x0400) | Dieses Objekt wird im 3D-Betrieb als Hintergrund aufgefaßt,
und entsprechend gezeichnet. Es empfiehlt sich in Dialogen mit
3D-Buttons das ROOT Objekt mit diesem Flag zu belegen. Gleiches gilt
für Eingabefelder und Textobjekte, denn nur so wird eine einheitliche
Hintergrundfarbe erhalten.
Siehe auch (0x4000). | ||||||||||||||
BITBUTTON (0x0400) | Dieses Flag wurde mit ViewMAX beta eingeführt, wird dort aber
nicht benutzt. Vermutlich enthält ein Button mit diesem Flag eine
Bitmap anstelle eines Textes. Only effective in ViewMAX/2 and later.
| ||||||||||||||
FL3DACT (0x0600) | Dieses Objekt wird im 3D-Betrieb als Aktivator aufgefaßt. Bei
diesen Objekten handelt es sich i.d.R. um Buttons, mit denen man
Dialoge verlassen, oder sonstwie eine Aktion hervorrufen kann.
| ||||||||||||||
SUBMENU (0x0800) | Wird in MultiTOS und ab MagiC 5.10 verwendet, um Submenüs zu
kennzeichnen. menu_attach setzt dieses Bit in einem Menüeintrag, um
zu kennzeichnen, daß hier ein Submenü angehängt ist. Das Hibyte von
ob_type enthält dann die Submenü-Nummer (128..255) d.h. Bit 15 von
ob_type ist immer gleichzeitig mit SUBMENU gesetzt.
| ||||||||||||||
SCROLLER (0x0800) | Das Drücken der PAGEUP Taste entspricht einem Anwählen des
ersten Objekts mit diesem Flag in dem Dialog. Das Drücken der
PAGEDOWN Taste entspricht einem Anwählen des letzten Objekts mit
diesem Flag. Only effective in ViewMAX/2 and later.
| ||||||||||||||
FLAG3D (0x1000) | Ein Objekt mit dieserm Flag wird mit einem 3D Rahmen
gezeichnet. Ab ViewMAX/2 wird jeder Button automatisch mit einem 3D
Rahmen gezeichnet. Dazu wird die Color Categorie (siehe USECOLOURCAT)
benutzt. Only effective in ViewMAX/2 and later.
| ||||||||||||||
USECOLOURCAT (0x2000) | Die Farbe des Objekts ist kein Farbindex des VDI sondern ein
Eintrag in einer Tabelle mit Farben für bestimmte Kategorien. Diese
Tabellle hat 16 Einträge. ViewMAX benutzt die folgenden Kategorien:
Wahrscheinlich ist beabsichtigt, die Kategorien 0 bis 7 durch die Applikation definieren zu lassen, während 8 bis 15 für das System reserviert sind. Die Einstellung wird in ViewMAX.INI (GEM.CFG in FreeGEM) gespeichert und besteht aus jeweils einen Vordergrund, Hintergrund, Füllstil und Füllindex. Only effective in ViewMAX/2 and later. | ||||||||||||||
FL3DBAK (0x4000) | 3D background (sunken rather than raised).
To check for this feature, use appl_init and check that bit 3 of xbuf.abilities is set. | ||||||||||||||
SUBMENU (0x8000) | Not implemented in any known PC AES
|
Querverweis: Objektstruktur im AES Objektarten des AES
Vom Objektstatus hängt es ab, wie ein Objekt später auf dem Bildschirm dargestellt wird. Ein Objektstatus kann von folgendem Typ sein:
Status | Bedeutung
|
| |
NORMAL (0x0000) | Normale Darstellung.
|
SELECTED (0x0001) | Inverse Darstellung, dh. das Objekt ist selektiert.
|
CROSSED (0x0002) | Falls die Objektart BOX ist, wird das Objekt mit
durchgestrichen gezeichnet.
|
CHECKED (0x0004) | Am linken Objektrand befindet sich ein Häkchen.
|
DISABLED (0x0008) | Das Objekt wird grau dargestellt und ist nicht mehr
selektierbar.
|
OUTLINED (0x0010) | Das Objekt bekommt einen Rahmen.
|
SHADOWED (0x0020) | Ein Schatten wird unter das Objekt gezeichnet.
|
WHITEBAK (0x0040) | Auf PC-GEM bewirkt dies, daß die Icon-Maske nicht
mitgezeichnet wird, was u.U. die Ausgabe beschleunigen kann.
Ab MagiC-3 wird hiermit das Unterstreichen von Zeichenketten gesteuert. Dieses Feature kann über appl_getinfo (Opcode 13) ermittelt werden. |
DRAW3D (0x0080) | Ein Objekt soll mit 3D-Effekt gezeichnet werden. Dieses Flag
ist nur für PC-GEM interessant, und wird vom Atari-AES (so z.B. auch
in MagiC) ignoriert.
|
HIGHLIGHTED (0x0100) | Ein Objekt mit diesem State wird mit einer gestrichelten Line,
die mit MD_XOR gezeichnet wird, umrandet. Dieser State wurde mit
ViewMAX beta eingeführt.
|
UNHIGHLIGHTED (0x0200) | Bei einem Objekt mit diesem State wird beim Zeichnen explizit
eine durch den State HIGHLIGHTED gezeichnete Umrandung entfernt. Dazu
muß wie folgt vorgegangen werden: Zuerst muß der State HIGHLIGHTED
gelöscht werden, dann der State UNHIGHLIGHTED gesetzt werden und
anschließend das Objekt mit der Funktion objc_draw neu gezeichnet
werden. Ein Neuzeichnen des Objekts ohne den State UNHIGHLIGHTED
würde die Umrandung nicht löschen, da sie außerhalb des Bereichs
liegt, den das Objekt belegt. Nach dem Neuzeichnen sollte der State
UNHIGHLIGHTED wieder gelöscht werden. Dieser State wurde mit ViewMAX
beta eingeführt.
|
UNDERLINE (0x0f00) | Dieser Opcode steht unter MagiC ab Version 2.0 zur Verfügung,
und legt die Position und Größe des Unterstriches bei Objekten vom
Typ G_STRING, G_TITLE und G_BUTTON fest.
|
XSTATE (0xf000) | Dieser Opcode steht unter MagiC ab Version 2.0 zur Verfügung,
und sorgt für das Umschalten bei den verschiedenen Button-Typen
(G_STRING, G_TITLE und G_BUTTON).
|
In GEM/5, CROSSED makes the object draw in 3D:
GEM/5 can be detected by calling vqt_name for font 1. If nothing is returned, GEM/5 is running.
Recent FreeGEM builds contain a system based on the GEM/5 one, but extended and backwards-compatible. The DRAW3D state is used instead of CROSSED:
To check for these abilities, use appl_init and check that bit 3 of xbuf.abilities is set.
Querverweis: Objektstruktur im AES Objektarten des AES
Der Quarter-Screen-Buffer wird vom Screen-Manager benötigt, um beim Herunterklappen von Drop-Down-Menüs den Inhalt des Menühintergrundes zu retten. Auch bei der Anzeige von Alarmboxen kommt der 'QSB' (so die gebräuchliche Abkürzung) zum Einsatz. Normalerweise sollte seine Größe von der Anzahl der Farbebenen und der Größe des Systemzeichensatzes, nicht aber von der Gesamtgröße des Bildschirms abhängen.
Eine gute Formel wäre:
500(Zeichen) * Platzbedarf eines Zeichens * Farbebenen
Damit käme man in der Auflösung 'ST-Hoch' genau auf den Wert 8000 (also ein Viertel des Bildspeichers). Leider ist das AES in vielen Fällen jedoch nicht so clever; die folgende Tabelle enthält eine Übersicht über die benutzten Algorithmen einiger GEM-Versionen:
GEM-Version | Methode zum Setzen des QSB |
1.0 und 1.2 | statisch, 8000 Bytes |
1.4 | dynamisch, ein Viertel des Bildspeichers |
3.0 | dynamisch, die Hälfte des Bildspeichers |
Hinweis: Die GEM-Versionen 1.0 und 1.2 (also bis einschließlich TOS-Version 1.02) sind mithin nicht für Farbgrafikkarten vorbereitet - einer unter mehreren Gründen, warum man selbst bei Benutzung eines speziellen VDI-Treibers unter diesen GEM-Versionen Farbgrafikkarten nicht einsetzen kann.
Querverweis: GEM
Um dem Problem sich überlappender Fenster zu begegnen, unterhält das AES für jedes Fenster die sogenannte Rechteckliste; alle Elemente dieser Liste ergeben gerade den komplett sichtbaren Arbeitsbereich des entsprechenden Fensters.
Um ein Fenster (bzw. dessen Inhalt) neu zu zeichnen erfragt man zunächst per wind_get( WF_FIRSTXYWH) das erste Rechteck der o.g. Liste. Dann stellt man fest, ob sich dieses Rechteck mit dem neu zu zeichnenden Bildschirmbereich überschneidet; dann und nur dann zeichnet man diesen Bereich unter Ausnutzung von vs_clip neu.
Diese Methode wird mit allen übrigen Elementen der Rechteckliste fortgesetzt, bis die Höhe und Breite eines Rechtecks den Wert Null besitzen.
Querverweis: Clipping WM_REDRAW wind_get wind_update
Der Screen-Manager ist immer aktiv und überwacht die Position des Mauszeigers, wenn dieser den Arbeitsbereich der Fenster anderer Applikationen verläßt. Die hier in Frage kommenden Flächen sind die Rahmen der Fenster, die Drop-Down-Menüs und die Menüleiste.
Beim Berühren des Menübereichs sorgt der Screen-Manager selbsttätig dafür daß der vom Menü belegte Bildschirmausschnitt gesichert und anschließend wiederhergestellt wird (dazu wird der Quarter-Screen-Buffer benutzt).
Auch Manipulationen an den Fensterkontrollen führen nicht zu dauerhaften Veränderungen des Bildspeichers; Resultat der Interaktionen mit dem Screen-Manager sind die sogenannten Mitteilungsereignisse, die die zuständige Applikation über die Aktion des Benutzers informieren.
Hinweis: Die ID des Screen-Managers kann übrigens leicht durch einen Aufruf von appl_find("SCRENMGR") ermittelt werden.
Querverweis: AES GEM Nachrichten
Ab AES-Version 4.1 unterstützt das Betriebssystem sogenannte Toolbars. Es handelt sich dabei um einen OBJECT-Baum, der unterhalb der Info-Zeile eines Fensters (und über dem Arbeitsbereich) plaziert wird, und die Darstellung von Buttons, Icons etc. im Fenster ermöglicht.
Wie bereits von den Fensterroutinen bekannt, wird die Verwaltung einer Toolbar zwischen dem AES und der Applikation aufgeteilt. Dabei ist das AES für die folgenden Aktionen verantwortlich:
Die Applikation hingegen muss sich um die folgenden Dinge kümmern:
Bei der Unterstützung von Toolbars in eigenen Programmen sollten die folgenden Punkte beachtet werden:
Querverweis:
WF_TOOLBAR WF_FTOOLBAR WF_NTOOLBAR WM_TOOLBAR wind_get wind_set
Bei der Neuzeichnung (von Teilen) der Toolbar ist, wie üblich, die Rechteckliste zu beachten. Da die bisherigen wind_get Opcodes WF_FIRSTXYWH und WF_NEXTXYWH jedoch nur den Arbeitsbereich eines Fensters berücksichtigen, wurden zwei neue Parameter (WF_FTOOLBAR und WF_NTOOLBAR) eingeführt, mit deren Hilfe die Rechteckliste für eine Toolbar abgefragt werden kann.
Ein Redraw (von Teilen) der Toolbar kann in den folgenden Situationen notwendig sein:
Nicht notwendig ist ein Neuzeichnen z.B. in folgenden Fällen:
Querverweis: Rechteckliste eines Fensters Toolbar-Support
Zur Handhabung von Toolbars kann eine Applikation auf den Window-Manager des AES zurückgreifen. Im einzelnen:
Um eine Toolbar an ein Fenster anzuheften, genügt ein Aufruf von wind_set(handle, WF_TOOLBAR, ...) mit der Adresse des Toolbar-Objektbaumes. Falls dieser Aufruf durchgeführt wird während das Fenster geöffnet ist, so ist dieses selbst für die korrekte Berechnung der Höhe der Toolbar verantwortlich.
Um eine Toolbar gegen eine andere auszutauschen, kann auf einen Aufruf von wind_set(handle, WF_TOOLBAR, ...) mit der Adresse der neuen Toolbar zurückgegriffen werden. Falls dieser Aufruf durchgeführt wird während das Fenster geöffnet ist, so ist dieses selbst für die korrekte Berechnung der Höhe der (neuen) Toolbar verantwortlich.
Um eine Toolbar aus einem Fenster zu lösen, ist ein Aufruf von wind_set(handle, WF_TOOLBAR, ...) mit NULL Parametern erforderlich. Falls dieser Aufruf durchgeführt wird während das Fenster geöffnet ist, so ist dieses selbst für die korrekte weitere Bearbeitung verantwortlich.
Darüber hinaus sind die folgenden Punkte zu beachten:
Querverweis: AES GEM Toolbar-Support
Beim Einsatz der Funktion wind_calc auf Fenster, die eine Toolbar beinhalten, sind einige Probleme zu berücksichtigen:
Da dieser Funktion keine Fenster-Kennung (Window-Handle) übergeben wird, können die gewünschten Größen nicht korrekt berechnet werden, wenn sich eine Toolbar im Fenster befindet. Der Grund liegt ganz einfach darin, daß das AES in diesem Fall keine Informationen über die Toolbar, und speziell über deren Größe besitzt.
Daher müssen in diesem Fall die von wind_calc gelieferten Werte von der Applikation weiter aufbereitet werden. Da das Programm auf den entsprechenden OBJECT-Baum (und damit auch auf die Höhe der Toolbar) zugreifen kann, ist dies problemlos möglich. Konkret:
Hinweis: Die Höhe der Toolbar sollte neben der Höhe des eigentlichen Objektes den Platzbedarf für Spezialeffekte (3D, Shadowing, etc.) beinhalten.
Querverweis: WF_FTOOLBAR WF_NTOOLBAR WM_TOOLBAR objc_sysvar
Das AES wird über ein einziges Unterprogramm aufgerufen, dem 6 Parameter übergeben werden; es handelt sich dabei um Adressen verschiedener Arrays, die zur Ein-/Ausgabe-Kommunikation benutzt werden. Um eine AES-Funktion aufzurufen, muß der folgende Parameterblock mit den Adressen der unten beschriebenen Arrays bestückt werden:
typedef struct { int16_t *cb_pcontrol; /* Zeiger auf control-Array */ int16_t *cb_pglobal; /* Zeiger auf global-Array */ int16_t *cb_pintin; /* Zeiger auf int_in-Array */ int16_t *cb_pintout; /* Zeiger auf int_out-Array */ int16_t *cb_padrin; /* Zeiger auf adr_in-Array */ int16_t *cb_padrout; /* Zeiger auf adr_out-Array */ } AESPB;
Die Adresse dieses Parameterblocks (der sich auf dem Stack befindet), muß dann im Register d1 vermerkt, und zusätzlich Register d0.w mit dem Wert 0xc8 (200) gefüllt werden. Durch einen TRAP #2 Systemaufruf kann dann das AES direkt aufgerufen werden. Für den Pure-Assembler könnte das z.B. so aussehen:
.EXPORT aes ; Funktion exportieren .CODE ; Beginn des Code-Segments aes: MOVE.L 4(sp),D1 ; Adresse des Parameterblocks MOVE.W #200,D0 ; Opcode des AES TRAP #2 ; GEM aufrufen RTS ; raus hier .END ; Ende des Moduls
Darüber, welche Register verändert werden dürfen, gibt es keine klaren Informationen. Tatsache ist jedoch, daß die entsprechenden Routinen im ROM alle Register retten.
Nun zu den einzelnen Arrays. Über jedes Feld können bestimmte Ein- bzw. Ausgaben getätigt werden; es gilt:
int16_t control[5] | Über dieses Feld werden Informationen über die aufgerufene
Funktion und ihre Parameter festgelegt. Es gilt:
Darüber, welche Informationen vor einem AES-Aufruf gesetzt werden müssen, gibt es keine klaren Informationen. Nötig ist es auf jeden Fall für die Elemente [0],[1] und [3]. Wenig sinnvoll erscheint es für die Elemente [2] und [4] zu sein - schließlich wissen die AES-Funktionen ja selbst, wie viele Werte sie in den Ausgabefeldern zurückliefern. | ||||||||||||||||||||||
int16_t global[15] | Dieses Feld enthält globale Daten für die Applikation und
wird teils von appl_init, teils von anderen AES-Funktionen benutzt,
und automatisch gefüllt. Es gilt:
| ||||||||||||||||||||||
int16_t int_in[16] | Über dieses Feld werden alle 16-Bit großen Eingabeparameter übergeben. | ||||||||||||||||||||||
int16_t int_out[10] | Über dieses Feld liefert das AES alle 16-Bit großen Rückgabewerte. | ||||||||||||||||||||||
int32_t addr_in[8] | Dieses Feld dient zur Übermittlung von Zeigern (z.B. Zeiger auf Zeichenketten) an AES Funktionen. | ||||||||||||||||||||||
int32_t addr_out[2] | Über dieses Feld werden 32-Bit große Werte vom AES zurückgeliefert. |
Achtung: Wenn das Betriebssystem Threads unterstützt, muss unbedingt darauf geachtet werden, eine Multithread-sichere Bibliothek zu verwenden. Insbesondere muss sichergestellt werden, daß jeder Thread sein eigenes global-Feld (s.o) erhält.
Querverweis: Beispiel-Binding VDI-Bindings TOS Liste
Die Funktion 'crys_if' (Crystal Interface) sorgt für die Besetzung des control-Arrays, und macht den eigentlichen AES-Aufruf. Dazu bedient sie sich einer Tabelle, in der für jede einzelne AES-Funktion die Werte für control[1], control[2] und control[3] vermerkt sind.
AESPB c; int16_t crys_if (int16_t opcode) { int16_t i, *paesb; control[0] = opcode; paespb = &ctrl_cnts[ (opcode-10)*3 ]; for (i = 1; i < 4; i++) control[i] = *paespb++; aes (c); return (int_out[0]); } /* crys_if */
Die dabei verwendete Tabelle könnte beispielsweise folgendermaßen aufgebaut sein:
.GLOBAL ctrl_cnts .DATA ctrl_cnts: .dc.b 0, 1, 0 ; appl_init .dc.b 2, 1, 1 ; appl_read .dc.b 2, 1, 1 ; appl_write ... ... ... .END
Querverweis: AES-Bindings GEM