                Fernsteuern von GEM-Applikationen mit

                              GEMScript

                       15.11.1998 (Release 1.2)

                                 von

              Thomas Much, Holger Weets, Manfred Lippert


Inhaltsverzeichnis
==================

 1  Einleitung

 2  Das Konzept im berblick

 3  GEM-Nachrichten
    3.1  Initialisierung
         3.1.1  GS_REQUEST
         3.1.2  GS_REPLY
         3.1.3  Die GS_INFO-Struktur
    3.2  Abmeldung
         3.2.1  GS_QUIT
    3.3  Fernsteuerung
         3.3.1  GS_COMMAND
         3.3.2  GS_ACK
    3.4  Makros
         3.4.1  GS_OPENMACRO
         3.4.2  GS_MACRO
         3.4.3  GS_WRITE
         3.4.4  GS_CLOSEMACRO

 4  Nachstarten eines GS-Interpreters

 5  Standard-GS-Kommandos
    5.1  AppGetLongName
    5.2  CheckCommand
    5.3  Close
    5.4  Copy
    5.5  Cut
    5.6  Delete
    5.7  GetAllCommands
    5.8  GetFront
    5.9  New
    5.10  Open
    5.11  Paste
    5.12  Print
    5.13  Quit
    5.14  Save
    5.15  SaveAs
    5.16  SelectAll
    5.17  ToFront
    5.18  Undo

 6  Weitere GS-Kommandos
    6.1  Exec
    6.2  CheckApp

 7  Parameter
    7.1  Leere Parameter
    7.2  Hex-codierte Parameter
    7.3  Datei
    7.4  Datei+Pfad
    7.5  Script

Anhang
======

 A  History

 B  Kontakt



1  Einleitung
*************

GEMScript ist ein Protokoll, um GEM-Applikationen fernzusteuern. Das
Protokoll selbst ist sehr einfach gehalten, so da es fr
Programmierer kein groes Problem darstellt, GEMScript in ihren
Programmen zu untersttzen.

Diese Dokumentation definiert dieses GEMScript-Protokoll und ist somit
in erster Linie an Programmierer gerichtet. Wohlgemerkt handelt es
sich bei GEMScript noch nicht um ein konkretes Programm, sondern nur
um die Definition einer Kommunikation zwischen GEM-Programmen:

Die am hufigsten auftretende Anwendung einer Kommunikation mittels
GEMScript drfte die durch einen Script-Interpreter darstellen. Einen
solchen Interpreter stellt z.B. "Scripter" von Holger Weets dar.
Festgelegt durch ein Script in einer Sprache, die dieser Interpreter
versteht, verschickt der Interpreter ber das definierte GEMScript-
Protokoll Kommandos an GEM-Programme, die dann die gewnschten
Aktionen ausfhren:

Natrlich knnen auch GEM-Programme ohne einen Script-Interpreter
untereinander per GEMScript kommunizieren.

Die hohe Flexibilitt des GEMScript-Protokolls erffnet sich dadurch,
da in keinster Weise die Kommandos vorgeschrieben sind, die versendet
werden. Es ist nur definiert wie Kommandos verschickt werden, nicht
aber welche Kommandos dies sind.

Jede Applikation kann also ihre eigenen Kommandos bereitstellen, je
nach dem, welche Fhigkeiten sie eben hat. Ein Zeichenprogramm wird
beispielsweise sicher andere Kommandos bereitstellen wollen, als ein
Desktop oder eine Tabellenkalkulation.

Es gibt jedoch ein paar Standard-Kommandos, die in nahezu jeder
Applikation sinnvoll erscheinen, z.B. das ffnen eines Dokumentes.
Daher beschreibt diese GEMScript-Dokumentation ebenfalls einen Satz
solcher Standard-GS-Kommandos, an die sich jede GEMScript-fhige
Applikation - soweit mglich - halten sollte. Zwingend ist dies jedoch
nicht.



2  Das Konzept im berblick
***************************

Wie im Vorwort schon erwhnt, handelt es sich bei GEMScript um eine
Kommunikation zwischen GEM-Programmen, bei der Kommandos verschickt
werden.

Der eigentliche Austausch basiert auf normalen AES-Nachrichten.

Das zugrundeliegende Prinzip der Kommunikation dabei ist eigentlich
recht einfach:

 1. Eine Applikation, die mit einer anderen kommunizieren mchte,
     meldet sich zunchst einmal bei dieser Applikation an ("Hallo!
     Hier bin ich und mchte mich gerne mit dir per GEMScript
     unterhalten."). Dazu gibt es die Nachrichten GS_REQUEST und
     GS_REPLY.

 2. Danach kann bereits die "Session" beginnen, d.h. man schickt sich
     munter Kommandos zu. Dazu gibt es die Nachrichten GS_COMMAND und
     GS_ACK. Die Applikationen unterhalten sich, und sagen
     gegenseitig, was zu tun ist. In den meisten Fllen luft das
     ganze recht einseitig ab, d.h. eine Applikation kommandiert, was
     zu tun ist (normalerweise der Script-Interpreter) und die andere
     Applikation fhrt es aus. Natrlich sind aber auch andere
     "Gesprche" denkbar.

 3. Will sich eine Applikation nicht mehr unterhalten, meldet sie sich
     einfach wieder ab ("Tsch dann!"). Dazu gibt es die Nachricht
     GS_QUIT.

Fr Leute, denen das zu einfach ist, gibt es noch ein kleines
Schmankerl, das man in seine GEMScript-fhigen Applikationen einbauen
kann - aber nicht unbedingt mu: Die Aufnahme von Aktionen (Makros).
Eine Applikation, die das untersttzt, nennt man "aufnahmefhig".

Dazu wird nun zwingend ein Script-Interpreter gebraucht, der noch dazu
fhig sein mu, Kommandos aufzuzeichnen, um sie spter wieder
abspielen zu knnen. Er mu quasi selbstndig Scripts erstellen,
aufgrund der Informationen, die ihm eine Applikation liefert. Fhrt
man ein solches entstandene Script zu einem spteren Zeitpunkt aus, so
wiederholt die Applikation sinngem genau das, was sie bei der
Aufnahme gemacht hat.

Hier der prinzipielle Ablauf einer Aufnahme:

 1. Der Benutzer aktiviert die Aufnahme in einer Applikation. Die
     Applikation sucht daraufhin den GEMScript-Interpreter (startet
     ihn gegebenenfalls nach) und initialisiert die GEMScript-
     Kommunikation in gewohnter Weise mit GS_REQUEST/GS_REPLY. Meist
     mu der Benutzer nun noch ein File auswhlen, in der das
     aufzunehmende Script landen soll.

 2. Die Applikation gibt dem Interpreter bekannt, da sie jetzt gerne
     aufnehmen mchte. Dazu existiert die Nachricht GS_OPENMACRO. Ist
     der Interpreter einverstanden, schickt er GS_MACRO zurck, als
     Zeichen, da nun die Aufnahme beginnen kann.

 3. Die Applikation sendet nun alle Aktionen, die aufgenommen werden
     sollen, mit der Nachricht GS_WRITE an den Interpreter. Dieser
     erzeugt daraus das Script.

 4. Beendet der Benutzer die Aufnahme, so sagt die Applikation dies
     dem Interpreter mit der Nachricht GS_CLOSEMACRO. Fertig.

Hat man eine Applikation erst mal GEMScript-fhig gemacht, stellt im
Grunde also auch die Aufnahmefhigkeit kein groes Problem mehr dar.

Um das ganze zu vervollstndigen gibt es noch eine weitere kleine
Variante der Aufnahme: Die applikationsbergreifende Aufnahme.

Dazu ist eine weitere spezielle Applikation ntig, die diese Aufnahme
koordiniert: Der Aufnahme-Server. Der Desktop "jinnee" funktioniert
beispielsweise als ein solcher Server. Auch diese
applikationsbergreifende Aufnahme sei kurz erlutert:

 1. Der Benutzer aktviert die applikationsbergreifende Aufnahme im
     Aufnahme-Server. Wie bei einer normalen Aufnahme, sucht dieser
     Server den GEMScript-Interpreter und initialisiert die
     GEMScript-Kommunikation mit GS_REQUEST/GS_REPLY.

 2. Wie bei der normalen Aufnahme, beginnt der Server, eine Aufnahme
     beim Interpreter zu starten (GS_OPENMACRO). Der Interpreter
     antwortet mit GS_MACRO.

 3. Auerdem versucht der Aufnahme-Server GEMScript-Kontakt zu allen
     laufenden Applikationen aufzunehmen (GS_REQUEST/GS_REPLY). Bei
     Applikationen, bei denen dies geklappt hat, lst der Server quasi
     "von auen" eine Aufnahme mit der Nachricht GS_MACRO aus. Sind
     die Applikationen von auen aufnahmefhig, fangen sie jetzt an,
     munter ihre Kommandos per GS_WRITE an den Server zu schicken.
     (Fr die Applikationen ist der Server in diesem Falle der
     Interpreter.)

 4. Der Server sammelt alle aufzunehmenden Kommandos aller laufenden
     Applikationen, kennzeichnet diese speziell (um sie spter beim
     Abspielen des Scripts wieder zu erkennen), und schickt diese
     neuen Kommandos als "seine" aufzunehmenden Kommandos an den
     Interpreter weiter. Dieser zeichnet sie im Script auf.

 4. Beendet der Benutzer die Aufnahme, unterbricht der Server die
     Aufnahme bei allen Applikationen ebenfalls wieder "von auen".
     Ebenso beendet er seine eigene Aufnahme beim Interpreter. (Beides
     mit GS_CLOSEMACRO). Fertig.

 5. Spielt man das entstandene Script ab, so findet der Interpreter
     nur Kommandos, die fr den Server bestimmt sind, und schickt
     diese dann auch an ihn. Der Server wiederum erkennt, da es sich
     um Kommandos anderer Applikationen handelt, und leitet sie
     entsprechend einfach weiter. Hier sieht man den Vorteil, den der
     Server hat, wenn es sich um ein Desktop handelt (wie im Falle
     jinnee): Luft eine Applikation beim Abspielen des Scripts nicht,
     kann er diese meist ohne groen Aufwand einfach nachstarten,
     sofern die Applikation im Desktop angemeldet ist.

Nach diesem berblick der Mglichkeiten kann die konkrete
Dokumentation des GEMScript-Protokolls beginnen.



3  GEM-Nachrichten
******************


3.1  Initialisierung
====================


3.1.1  GS_REQUEST
-----------------

Um festzustellen, ob eine Applikation GEMScript untersttzt, schickt
man ihr folgende Message.

GS_REQUEST
msg[0] 0x1350 (4944)
msg[1] ap_id
msg[2] 0
msg[3]
    +  Pointer auf GS_INFO-Struktur
msg[4]
msg[5] 0
msg[6] 0
msg[7] beliebige ID (auer -1)


Als ID darf jede beliebige Nummer, auer -1 gewhlt werden. ID -1 ist
die "ungltige ID". Das macht es fr den Programmierer leichter, da er
die ungltige ID -1 intern z.B. fr nicht aktive GEMScript-
Verbindungen benutzen kann und kein extra Flag braucht (falls er sowas
berhaupt bentigt).

Antwort:

Wenn die Applikation GEMScript versteht, erhlt man als Antwort
GS_REPLY.

Man mu jede Applikation natrlich nur einmal vor dem ersten Kommando
auf GEMScript testen.


3.1.2  GS_REPLY
---------------

GS_REPLY wird von einer GEMScript-fhigen Applikation als Antwort auf
GS_REQUEST verschickt.

GS_REPLY
msg[0] 0x1351 (4945)
msg[1] ap_id
msg[2] 0
msg[3]
    +  Pointer auf GS_INFO-Struktur
msg[4]
msg[5] 0
msg[6] 0:     OK, Applikation kann GS-Kommunikation durchfhren
       2:     "Bitte andere ID"
       sonst: Fehler, GS-Kommunikation derzeit nicht mglich
msg[7] ID aus GS_REQUEST


Wenn eine Applikation in msg[6] einen Fehler meldet, drfen an sie
keine weiteren GS-Nachrichten geschickt werden. Man kann aber zu einem
spteren Zeitpunkt mit GS_REQUEST erneut die GEMScript-Fhigkeit
erfragen.

Man beachte, da eine Applikation mehrere GS_REQUEST-Nachrichten
erhalten kann. Zum einen knnen verschiedene Applikationen eine
Kommunikation beginnen, aber durch die ID kann eine Applikation sogar
in mehreren "Sessions" gleichzeitig kommunizieren.

Ist eine Applikation nur auf eine laufende Kommunikation gleichzeitig
ausgelegt (z.B. weil der aktuelle Kommunikationspartner in einer
globalen Variablen vermerkt wird), so mu darauf geachtet werden, da
alle folgenden GS_REQUEST-Nachrichten korrekt abgelehnt werden, wenn
bereits eine Kommunikation luft. (Am besten mit dem Wert 1 in
msg[6].)

Anwortet die Applikation in msg[6] mit 2, so bittet sie um eine andere
Session ID. Man whlt also eine andere Session-ID und versucht erneut
ein GS_REQUEST. Der Grund: Schicken sich zwei Applikationen
gegenseitig zeitgleich ein GS_REQUEST mit gleicher Session ID (uerst
unwahrscheinlich, aber mglich), so wren nachfolgende Kommandos den
Sessions nicht eindeutig zuzuordnen. Eine Applikation, die gerade ein
GS_REQUEST abgeschickt hat und (whrend sie eigentlich auf GS_REPLY
wartet) ebenfalls ein GS_REQUEST derselben Partner-Applikation mit
gleicher Session-ID bekommt, mu dieses GS_REQUEST mit msg[6] = 2
ablehnen.


3.1.3  Die GS_INFO-Struktur
---------------------------


typedef struct {
   long len;       /* Lnge der Struktur in Bytes                      */
   int  version;   /* Versionsnummer des Protokolles beim Sender
                      (z.Z. 0x0120 = 1.2)                              */
   int  msgs;      /* Bitmap der untersttzten Nachrichten und
                      Fhigkeiten (GSM_xxx)                            */
   long ext;       /* benutzte Endung, etwa '.SIC'                     */
} GS_INFO;

GSM_COMMAND   = 0x0001  /* kann GS_COMMAND empfangen                   */
GSM_MACRO     = 0x0002  /* kann GS_OPENMACRO, GS_WRITE und GS_CLOSEMACRO
                         empfangen, GS_MACRO verschicken
                         (Interpreter)                                 */
GSM_WRITE     = 0x0004  /* kann GS_OPENMACRO, GS_WRITE und GS_CLOSEMACRO
                         verschicken, GS_MACRO empfangen
                         (aufnahmefhige Applikation)                  */
GSM_HEXCODING = 0x0008  /* Hex-Codierung wird verstanden               */


Anmerkungen zur GS_INFO-Struktur:

    Die Struktur mu per Mxalloc() im globalen Speicher alloziert
     sein.

    Die Strukur darf vom Empfnger nicht verndert werden. D.h.
     GS_REQUEST- und GS_REPLY-Sender mssen jeweils ihre eigene
     Struktur allozieren.

    Da man nicht feststellen kann, wann der Empfnger die Struktur
     ausgelesen hat, sollte sie grundstzlich verfgbar sein. Es
     empfiehlt sich daher, die Struktur am Anfang des Programmes zu
     allozieren und erst am Ende wieder freizugeben.

    long belegt 32 Bit. Entspricht also auch size_t oder dem
     sizeof()-Typ in Pure-C.

    int belegt 16 Bit.

    ext ist fr den Interpreter gedacht. Andere Applikationen knnen
     hier 0 eintragen.

    Die Fhigkeiten eines GEMScript-Partners sollten mglichst immer
     ber "msgs" abgefragt werden, und nicht ber die Versionsnummer
     (version) des untersttzten Protokolles.


3.2  Abmeldung
==============


3.2.1  GS_QUIT
--------------

GS_QUIT sollte an den Kommunikationspartner geschickt werden, wenn
eine fernsteuernde Applikation keine GS_COMMAND-Befehle mehr
verschickt oder wenn eine ferngesteuerte Applikation solche
Nachrichten nicht mehr auswerten kann/mchte (z.B. weil die
Applikation terminiert).

GS_QUIT
msg[0] 0x1354 (4948)
msg[1] ap_id
msg[2] 0
msg[3] 0
msg[4] 0
msg[5] 0
msg[6] 0
msg[7] ID aus GS_REQUEST


3.3  Fernsteuerung
==================


3.3.1  GS_COMMAND
-----------------

GS_COMMAND
msg[0] 0x1352 (4946)
msg[1] ap_id
msg[2] 0
msg[3]
    +  Pointer auf Kommandozeile, s.u.
msg[4]
msg[5] 0
msg[6] 0
msg[7] ID aus GS_REQUEST

Die Kommandozeile enthlt das eigentliche Kommando, gefolgt von
optionalen Parametern. Kommando und Parameter sind durch ASCII #0
getrennt, am Ende der Kommandozeile steht ASCII #0#0, in C-Notation
also z.B.

"Kommando\0Parameter 1\0Parameter 2\0\0"

Die Kommandos mssen beim Empfnger ohne Beachtung der Gro-/
Kleinschreibung ausgewertet werden. Dabei wre es schn, wenn
mglichst viele Standard-GS-Kommandos untersttzt wrden.

Siehe auch: Parameter (siehe "Parameter").

Die Zeichenkette mu per Mxalloc() im globalen Speicher alloziert
sein.

Antwort:

Als Antwort erhlt man die Nachricht GS_ACK, die zum Freigeben dieses
Speichers benutzt werden kann.


3.3.2  GS_ACK
-------------

Folgende Nachricht wird von einer GEMScript-fhigen Applikation als
Antwort auf GS_COMMAND verschickt. Die fernsteuernde Applikation kann
beim Empfang dieser Nachricht z.B. den Speicher vom msg[3/4] wieder
freigeben.

GS_ACK
msg[0] 0x1353 (4947)
msg[1] ap_id
msg[2] 0
msg[3]
    +  exakt die Werte der empfangenen GS_COMMAND-Nachricht
msg[4]
msg[5]
    +  Ergebnis bzw. Fehlermeldung als ASCIIZZ-Text (s.u.) oder NULL
msg[6]
msg[7] 0: (GSACK_OK)      OK, Kommando wurde oder wird ausgefhrt
       1: (GSACK_UNKNOWN) Kommando unbekannt
       2: (GSACK_ERROR)   Fehler (Kommando nicht ausgefhrt)

Wird in msg[5/6] eine Rckgabe geliefert, liegt diese im Format wie
die GS_COMMAND-Kommandozeile vor, also die einzelnen Werte durch ASCII
#0 getrennt mit ASCII #0#0 am Ende des Rckgabestrings.

Antwort:

Wenn die auswertende Applikation in msg[5/6] ein Ergebnis der Funktion
oder eine Fehlerbeschreibung liefert (also einen Wert ungleich NULL),
mu die fernsteuernde Applikation folgende Antwort zurckschicken. Die
auswertende Applikation kann dann ihrerseits den Ergebnisspeicher
freigeben.

GS_ACK
msg[0] 0x1353 (4947)
msg[1] ap_id
msg[2] 0
msg[3] 0
msg[4] 0
msg[5]
    +  exakt die Werte der empfangenen GS_ACK-Nachricht
msg[6]
msg[7] 0

Anmerkungen zum Rckgabestring:

Der Rckgabewert eines Kommandos sollte immer ber msg[5]+msg[6]
zurckgegeben werden, man sollte nicht msg[7] dafr "mibrauchen".
Dies gilt vor allem fr Kommandos, die wahr oder falsch zurckliefern.
Sofern das Kommando korrekt ausgefhrt werden konnte, sollte man bei
"wahr" einen beliebigen nicht-leeren Rckgabestring (z.B. "1")
zurckliefern, bei "false" empfiehlt sich Leerstring oder Nullpointer.

Dies ist z.B. fr den Interpreter "Scripter" von Holger sehr
praktisch, denn dann knnen True/False-Kommandos bequem durch
folgendes Script abgefragt werden:

if (kommando(...))
{
        /* wahr */
}
else
{
        /* falsch */
}

Wrde das Ergebnis ist msg[7] zurckgeliefert, mte man im Beispiel
"Scripter" folgendes schreiben:

kommando(...)
if (errno == 0)
{
        /* wahr */
}
else
{
        /* falsch */
}


3.4  Makros
===========


3.4.1  GS_OPENMACRO
-------------------

GS_OPENMACRO
(App->Interpreter)
msg[0] 0x1355 (4949)
msg[1] ap_id
msg[2] 0
msg[3]
    +  Pointer auf Dateinamen, unter dem das Script gespeichert werden soll
msg[4]
msg[5] 0
msg[6] 0
msg[7] 0

Eine Applikation will vom Script-Interpreter aufgenommen werden. Als
Antwort bekommt sie GS_MACRO.

Der Interpreter sollte ber die Environment-Variable GEMSCRIPT gesucht
und ggf. auch nachgestartet werden.

Die Datei-Endung fr Scripte kann die Applikation vom Interpreter ber
die GS_INFO-Struktur bei GS_REPLY erfahren. Diese Endung wird evtl.
fr den Fileselector bentigt, den man in den meisten Fllen vor einer
Aufnahme aufrufen wird.

Zusammenfassung des Ablaufs einer Aufnahme:

    Interpreter suchen und ggf. nachstarten. (GEMSCRIPT-Variable)

    Beim Interpreter anmelden (GS_REQUEST)

    Interpreter anwortet mit GS_REPLY (liefert GS_INFO)

    Fileselector aufrufen (Extension aus GS_INFO vom Interpreter)

    Aufnahme mit GS_OPENMACRO starten

    Interpreter liefert GS_MACRO

    Aufnahme per GS_WRITE/GS_ACK

    Am Ende Aufnahme mit GS_CLOSEMACRO beenden


3.4.2  GS_MACRO
---------------

GS_MACRO
(Interpreter->App)
msg[0] 0x1356 (4950)
msg[1] ap_id
msg[2] 0
msg[3]
    +  exakt die Werte der empfangenen GS_OPENMACRO-Nachricht
       oder NULL bei Aufnahme-Aufforderung
msg[4]
msg[5] ID (am einfachsten das Dateihandle) zur Identifizierung des Scripts
msg[6] 0: Datei ist geffnet, Aufzeichnung kann beginnen; sonst: Fehler
msg[7] 0

Zu beachten: GS_MACRO kann auch ohne ein vorheriges GS_OPENMACRO
auftreten. msg[3/4] ist dann NULL.

Dieser Fall soll quasi als Aufforderung zur Aufnahme betrachtet
werden, wodurch z.B. eine applikationsbergreifende Aufnahme durch
einen externen Aufnahme-Server mglich ist. Die Applikation wird also
aufgefordert, ab jetzt alle Aktionen per GS_WRITE an den Aufnahme-
Server (der das GS_MACRO gesendet hat) zu schicken.

Will oder kann die Applikation gerade nicht aufnehmen, so mu sie ein
GS_CLOSEMACRO zurcksenden.

Man beachte, da auch hier die ID -1 ("ungltige ID") nicht bergeben
werden darf.

Zusammenfassung des Ablaufs einer erzwungenen Aufnahme:

    Aufnahmeserver (z.B. jinnee) meldet sich mit GS_REQUEST bei der
     Applikation an. Applikation antwortet mit GS_REPLY.
     Aufnahmeserver stellt ber GS_INFO-Struktur fest, da Applikation
     GS_MACRO kann, also aufnahmefhig ist.

    Aufnahmeserver erzwingt Aufnahme mit GS_MACRO (NULL im
     Dateinamen)

    Applikation antwortet entweder mit GS_CLOSEMACRO (Ablehnung) oder
     nimmt einfach mit GS_WRITE/GS_ACK die Aktionen auf.

    Aufnahmeserver oder Applikation beendet Aufnahme mit
     GS_CLOSEMACRO


3.4.3  GS_WRITE
---------------

GS_WRITE
(App->Interpreter)
msg[0] 0x1357 (4951)
msg[1] ap_id
msg[2] 0
msg[3]
    +  Pointer auf Kommandozeile (wie bei GS_COMMAND)
msg[4]
msg[5] ID aus GS_MACRO
msg[6] 0
msg[7] 0

Der Interpreter antwortet auf diese Nachricht wie bei GS_COMMAND mit
GS_ACK, ohne allerdings in msg[5/6] ein Ergebnis zurckzuliefern.

Falls in diesem GS_ACK ein Fehler signalisiert wird, sollten keine
weiteren GS_WRITE-Nachrichten verschickt werden.


3.4.4  GS_CLOSEMACRO
--------------------

GS_CLOSEMACRO
(App->Interpreter / Interpreter->App)
msg[0] 0x1358 (4952)
msg[1] ap_id
msg[2] 0
msg[3] 0
msg[4] 0
msg[5] ID aus GS_MACRO
msg[6] 0
msg[7] 0

Beendet die Aufzeichnung eines Scripts.

Zu beachten: Die Aufnahme kann von beiden Seiten beendet werden.
Sowohl von der aufnehmenden Applikation selbst, als auch vom
Interpreter (Aufnahme-Server bei applikationsbergreifender Aufnahme).



4  Nachstarten eines GS-Interpreters
************************************

Damit Applikationen (z.B. zum Aufzeichnen von Makros) einen GS-
Interpreter per appl_find() finden oder - falls ein solcher nicht
luft - nachstarten knnen, kann im Environment die Variable GEMSCRIPT
gesetzt werden, beispielsweise


  #_ENV GEMSCRIPT=D:\SCRIPTER\SCRIPTER.APP




5  Standard-GS-Kommandos
************************

Die Standard-Kommandos sind als Vorschlge zur Implementierung in
Applikationen gedacht. Sie sind keinesfalls als verbindlich anzusehen,
und falls sie implementiert werden, sind auch die Parameter nicht
verbindlich. Nicht jedes Programm eignet sich fr bestimmte Standard-
Kommandos, oder aber es machen bestimmte Fhigkeiten eines Programmes
eine abweichende Erweiterung eines Standard-Kommandos sinnvoll.


5.1  AppGetLongName
===================

Kommando: AppGetLongName
Parameter: keine
Rckgabe: String

Liefert den "langen" Namen des Programmes zurck, da der Proze-Name,
den man ber das System ermittelt aus historischen Grnden meist nur 8
Zeichen lang ist. Dieser lngere Name kann z.B. von Programmen
verwendet werden, die alle laufenden Applikation anzeigen, wie z.B.
MultiStrip oder AppLine. Als Rckgabe ist auch ein Leerstring erlaubt
(nicht jedoch NULL). Damit wird angezeigt, da der Proze in oben
genannten Programmen nicht angezeigt werden will. Dies ist z.B. bei
nebenlufigen Threads sinnvoll. In den langen Namen sollten keine
Versions-Informationen oder hnliches stehen, da das meist nicht der
bersichtlichkeit dient.


5.2  CheckCommand
=================

Kommando: CheckCommand
Parameter: Kommando-Name
Rckgabe: "1" oder "0" (bzw. "" oder NULL)

Dieses Kommando liefert "1" zurck, wenn die Applikation das als
Parameter bergebene Kommando untersttzt.

Eine Applikation die beispielsweise das Kommando "Open" kennt, das
Kommando "Save" jedoch nicht, liefert bei "CheckCommand\0Open\0\0" den
String "1\0\0" und bei "CheckCommand\0Save\0\0" den String "0\0\0"
zurck.

Achtung: Statt "0" kann optional auch entweder ein Leerstring "" oder
sogar ein Nullzeiger (NULL) zurckgeliefert werden!


5.3  Close
==========

Kommando:  Close
Parameter: Datei (optional)
Rckgabe:  keine

Schliet das der Datei entsprechende Fenster. Wenn keine Datei
bergeben wurde, wird das oberste Fenster geschlossen. Das Kommando
darf auch so implementiert sein, da mehrere Datei-Parameter auf
einmal bergeben werden knnen.


5.4  Copy
=========

Kommando:  Copy
Parameter: Datei (optional)
Rckgabe:  keine

Kopiert die Selektion der angegebenen Datei auf das Klemmbrett. Wenn
keine Datei angegeben ist, wird die Selektion des obersten Fensters
verwendet.


5.5  Cut
========

Kommando:  Cut
Parameter: Datei (optional)
Rckgabe:  keine

Schneidet die Selektion der angegebenen Datei aus und schreibt sie auf
das Klemmbrett. Wenn keine Datei angegeben ist, wird die Selektion des
obersten Fensters verwendet.


5.6  Delete
===========

Kommando:  Delete
Parameter: Datei (optional)
Rckgabe:  keine

Schneidet die Selektion der angegebenen Datei aus. Wenn keine Datei
angegeben ist, wird die Selektion des obersten Fensters verwendet.


5.7  GetAllCommands
===================

Kommando: GetAllCommands
Parameter: keine
Rckgabe: Strings

Liefert alle Kommandos zurck, die die Applikation versteht. Hinter
den Kommandos knnen - mssen aber nicht - Parameter spezifiziert
werden.

Eine Applikation, die z.B. die Kommandos "Open" und "Close" versteht,
knnte beispielsweise folgenden Ergebnis-String (C-Notation) liefern:

"Open\0Close\0\0".

Sie knnte aber auch das ganze genauer spezifizieren und folgendes
liefern:

"Open [<file>]\0Close [<file>]\0\0".

Das Kommando dient mehr dazu, dem Script-Programmierer einen berblick
ber verstandene Kommandos zu liefern, als automatisch ausgewertet zu
werden.

Um automatisch festzustellen, ob ein bestimmtes Kommando vorhanden
ist, sollte man besser CheckCommand benutzen.


5.8  GetFront
=============

Kommando:  GetFront
Parameter: keine
Rckgabe:  Datei oder Datei+Pfad

Falls das oberste Fenster der Applikation einen Namen besitzt, mit dem
es in den GS-Kommandos identifiziert werden kann, sollte dieser als
Antwort auf dieses Kommando zurckgeliefert werden.


5.9  New
========

Kommando:  New
Parameter: keine
Rckgabe:  keine

Legt ein neues Dokument an.


5.10  Open
==========

Kommando:  Open
Parameter: Datei+Pfad (optional)
Rckgabe:  keine

ffnet die angegebene Datei. Wenn keine Datei bergeben wurde, sollte
dem Benutzer die Dateiauswahlbox o.. angezeigt werden. Das Kommando
darf auch so implementiert sein, da mehrere Datei-Parameter auf
einmal bergeben werden knnen.


5.11  Paste
===========

Kommando:  Paste
Parameter: Datei (optional)
Rckgabe:  keine

Fgt den Inhalt des Klemmbretts in die Selektion der angebenenen Datei
ein. Wenn keine Datei angegeben ist, wird die Selektion des obersten
Fensters verwendet.


5.12  Print
===========

Kommando:  Print
Parameter: Datei (optional)
Rckgabe:  keine

Druckt die angegebene Datei aus. Wenn keine Datei angegeben ist, wird
das oberste Fenster ausgedruckt. Das Kommando darf auch so
implementiert sein, da mehrere Datei-Parameter auf einmal bergeben
werden knnen.


5.13  Quit
==========

Kommando:  Quit
Parameter: keine
Rckgabe:  keine

Beendet die Applikation.


5.14  Save
==========

Kommando:  Save
Parameter: Datei (optional)
Rckgabe:  keine

Speichert die angegebene Datei. Wenn keine Datei bergeben wurde, wird
das oberste Fenster gespeichert. Das Kommando darf auch so
implementiert sein, da mehrere Datei-Parameter auf einmal bergeben
werden knnen.


5.15  SaveAs
============

Kommando:  SaveAs
Parameter: Datei, Datei (optional)
Rckgabe:  keine

Dieses Kommando hat mindestens einen, maximal zwei Parameter. Der
erste bezeichnet den neuen Dateinamen, der zweite das zu speichernde
Fenster. Wenn der zweite Parameter nicht angegeben ist, wird das
oberste Fenster unter dem Dateinamen des ersten Parameters
gespeichert.


5.16  SelectAll
===============

Kommando:  SelectAll
Parameter: Datei (optional)
Rckgabe:  keine

Markiert die gesamte angegebene Datei. Wenn keine Datei angegeben ist,
wird das Dokument im obersten Fenster selektiert.


5.17  ToFront
=============

Kommando:  ToFront
Parameter: Datei
Rckgabe:  keine

Bringt das Fenster mit der angegebenen Datei nach vorne.


5.18  Undo
==========

Kommando:  Undo
Parameter: Datei (optional)
Rckgabe:  keine

Macht die letzte Aktion in der angegebenen Datei rckgngig. Wenn
keine Datei angegeben ist, wird die letzte Aktion im obersten Fenster
rckgngig gemacht.



6  Weitere GS-Kommandos
***********************

Dieser Abschnitt beschreibt weniger wichtige Standard-Kommandos, die
evtl. nur bei bestimmten Applikationen Sinn machen.


6.1  Exec
=========

Kommando:  Exec
Parameter: <Script> <Parameter>
Rckgabe:  keine

Dieses Kommando mu von jedem GEMScript-Interpreter untersttzt
werden. Es dient dazu, Script-Dateien auszufhren.

Mit <Script> wird die Script-Datei angegeben, dabei mu der
Interpreter mindestens eine komplette Pfadangabe samt Extension
verstehen.

<Parameter> (optional) steht fr weitere beliebige Parameter, die an
das Script weitergegeben werden, falls dies der Interpreter erlaubt.


6.2  CheckApp
=============

Kommando:  CheckApp
Parameter: Datei
Rckgabe:  keine

Versucht, die angegebene Datei nachzustarten. Wird z.B. vom Desktop
jinnee untersttzt.



7  Parameter
************

Mehrere Parameter sind durch ASCII #0 getrennt, und das Ende der
Kommandozeile ist mit ASCII #0#0 gekennzeichnet (siehe GS_COMMAND).

Wichtig: Parameter, die mit einem der ASCII-Zeichen #1 bis
einschlielich #6 anfangen, sind fr spezielle Zwecke reserviert.
Derzeit sind nur #1 (leerer Parameter) und #2 (Hex-Codierung)
definiert. Parameter, die mit ASCII-Zeichen #3 bis #6 anfangen, mssen
also derzeit ignoriert werden.

Beispiel:

"Kommando\0Parameter 1\0\3Dies wird derzeit ignoriert\0Parameter 2\0\0"


7.1  Leere Parameter
====================

Durch die Nullbyte-Trennung der Parameter mute fr den Sonderfall
"leerer Parameter" eine Ausnahme eingefhrt werden:

Leere Parameter werden durch das ASCII-Zeichen #1 gekennzeichnet, z.B.

"Kommando\0Gleich folgt ein leerer Parameter\0\1\0Gemerkt?\0\0"

Alle Zeichen, die dem #1-Zeichen folgen (aber noch zum leeren
Parameter gehren) sind zu ignorieren, z.B.

"Kommando\0Gleich leerer Parameter\0\1dies ignorieren\0Dies nicht\0\0"


7.2  Hex-codierte Parameter
===========================

Um die bergabe beliebiger ASCII-Zeichen zu ermglichen (man denke an
die reservierten Zeichen #1 bis #6), existiert folgende Hex-Codierung:

Beginnt ein Parameter mit dem ASCII-Zeichen #2, so sind die folgenden
Zeichen als Hex-Codierung aufzufassen, d.h. es folgen Paare von
Hexadezimal-Ziffern (0 bis F), die jeweils ein Byte beschreiben.

Beispiel:

"Kommando\0\2""010248414C4C4F\0\0"

Der erste Parameter nach dem Kommando "Kommando" besteht vorne aus den
beiden ASCII-Zeichen #1 und #2 (codiert als "0102") und anschlieend
dem Text "HALLO" (codiert als "48414C4C4F"). Der Parameter wird also
als "\1\2HALLO" interpretiert.

Anmerkung: Nicht von dem beiden eingefgten Anfhrungszeichen stren
lassen, damit wird in der Programmiersprache C vermieden, da die "0"
als zur "2" gehrig erkannt wird, und somit fschlicherweise das
ASCII-Zeichen #20 in den String eingefgt wrde.

Die Behelfsziffern "A" bis "F" knnen sowohl gro, als auch klein
geschrieben werden!


7.3  Datei
==========

Der Datei-Parameter bezeichnet einen Dateinamen (mit oder ohne
Pfadangabe). Da einzelne Kommandos durch ASCII #0 getrennt werden,
erfolgt kein (!) Quoting.

GEMScript-fhige Applikationen stellen i.d.R. mit einem solchen
Parameter fest, welches Fenster von einem Kommando betroffen ist. Wenn
ein direkter Vergleich von Kommando-Dateinamen und dem Fenster
zugewiesenen Dateinamen keinen Erfolg bringt, sollte die Applikation
nach einer mglichst groen bereinstimmung von Teilstrings suchen.


7.4  Datei+Pfad
===============

Dieser Parameter bezeichnet einen Dateinamen mit absoluter Pfadangabe.


7.5  Script
===========

Dieser Parameter bezeichnet eine Script-Datei (fr das Exec-Kommando).
Es handelt sich um eine Datei-Angabe, wobei die Endung der konkreten
Script-Datei auch weggelassen werden kann. Falls die absolute
Pfadangabe fehlt, mu er Interpreter in der Lage sein, die Datei zu
finden (z.B. weil sie im Verzeichnis des Interpreters liegt).




A  History
**********

 Rev 1.2 (15.11.98)

         "Bitte andere Session-ID" bei GS_REPLY.

         GSM_HEXCODING.

         Hinweis, da man mglichst immer msgs statt version in
          GS_INFO auswerten sollte.

         CheckCommand als Standard-Kommando aufgenommen.

         GetAllCommands als Standard-Kommando aufgenommen.

 Rev 1.1 (24.03.98)

         Hex-Codierung eingefhrt

         ungltige ID eingefhrt

         AppGetLongName als Standard-Kommando aufgenommen.

         Nicht-Verpflichtung der Standard-Kommandos deutlicher
          erklrt.

 Rev 1.0 (14.11.97)

         erste ffentliche Version



B  Kontakt
**********


Thomas Much, Gerwigstrae 46, D-76131 Karlsruhe, Germany

Fax:       +49 / (0)721 / 62 28 21

EMail:     Thomas Much @ KA2                 (MausNet)
           Thomas_Much@ka2.maus.de
           Thomas.Much@stud.uni-karlsruhe.de (Internet)


Holger Weets, Damm 25, D-26135 Oldenburg, Germany

EMail:     Holger Weets @ OL       (MausNet)
           Holger_Weets@ol.maus.de (Internet)


Manfred Lippert, Rennweg 46, D-90489 Nrnberg, Germany

EMail:     Manfred Lippert @ N       (MausNet)
           Manfred_Lippert@n.maus.de
           mani@mani.de              (Internet)





