Object Exchange Protocol for GEM Applications (OEP)
---------------------------------------------------
(oder "Der Autor sollte zu seiner Idee stehen :-)")

Revision 0.7, 12.04.1995


Sinn und Zweck
--------------
OEP bietet die Mglichkeit, zwischen Objekten (Bilder, Samples, Texte etc.),
die in unterschiedlichen GEM Applikationen verwendet werden, eine Verbindung
(Link) herzustellen. Dieser Link wird, zumindest in den meisten Fllen, vom
User mittels einer Drag&Drop-Operation vollzogen. Die Applikationen knnen
allerdings auch jederzeit selbst Objekte austauschen.

Wird ein 'verbundenes' Objekt vom User/von einer Applikation verndert, kann
mittels OEP, jede Applikation, die dieses Objekt ebenfalls verarbeitet, davon
unterrichtet, und das Objekt somit systemweit auf den neuen Stand gebracht
werden.


Neue Eigenschaften der Applikationen
------------------------------------
OEP basiert auf dem MultiTOS-Drag&Drop-Protokoll. Applikationen die dieses
bereits untersttzen, knnen mit relativ geringem Aufwand OEP-fhig gemacht
werden. Sollte das D&D-Protokoll noch nicht untersttzt werden, erhlt die
Applikation durch OEP zustzlich die Eigenschaft, das normale Drag&Drop dem
User anzubieten.

Um dem Manger mitteilen zu knnen, das ein Objekt verndert wurde, sollte dem
User die Mglichkeit gegeben werden, dieses Ereignis explizit auslsen zu
knnen. Die einfachste Mglichkeit ist, das Versenden von OEP_UPDATE mit dem
Speichern des Dokumentes/Objektes zu verbinden. Eleganter wre es, einen neuen
Menpunkt (z.B. "Aktualisieren") oder ein spezielles Icon anzubieten, womit der
Benutzer auch einzelne Objekte innerhalb eines Dokumentes aktualisieren knnte.


Realisierung
------------
Ein Link besteht primr aus einer 4 Byte langen Kennzahl (Handle), die jedem
Objekt zugeordnet wird. Dieses Objekthandle mu von einer OEP-Managerapplikation
(Manager) angefordert werden. Das Objekthandle ist im System (solange der
Rechner in Betrieb ist) einmalig. Dadurch wird gewhrleistet, da das Handle
problemlos mittels AES-Messages versandt werden kann.

Applikationen sollten das Handle (bzw. die Strukturen OEP_OBHEADER oder
OEP_BIGOBHEADER) in Verbindung mit dem Objekt in ihren Dokumenten speichern, um
den Link jederzeit wiederherstellen zu knnen.

Eine weitere Lsung ist, alle Objekthandles (incl. zugehriger Struktur!) mit
einem Hinweis auf das Dokument, in dem das Objekt verwendet wird, zu speichern.
Das globale Speichern der Objekthandles hat den Vorteil, das die Applikation
beim Eintreffen einer OEP_UPDATE-Mitteilung lediglich diese Datei absuchen mu,
um festzustellen, ob das Objekt mit dem mitgeteilten Handle Verwendung findet.

Es wird empfohlen, als Dateiname fr die globale Objekthandle-Datei den
Programmdateinamen mit der Extension ".OEP" zu verwenden (z.B. WORDPLUS.OEP,
1ST_DEMO.OEP etc.), und diese im Verzeichnis des Programms abzulegen.

Diese Lsung ist allerdings weder ideal noch verbindlich.


Wo laufen sie denn?
-------------------
Eine Applikation (bzw. der Programmierer) mu wissen, welches Protokoll
bentigt wird. Natrlich knnen OLGA (Object Linking for GEM Applications) und
OEP gleichzeitig untersttzt werden. In der Regel wird dies allerdings nicht
der Fall sein, da meist nur ein Manager im System installiert ist.

Damit es fr Applikationsprogrammierer einfacher ist, OLGA und/oder OEP zu
untersttzen, haben Thomas Much (OLGA) und ich eine gemeinsame Initialisierung
entwickelt, die unter dem Oberbegriff "OLE" steht.

Um herauszufinden, ob ein OEP-Manager installiert ist, siehe weiter unten unter
'Der OEP-Manager'.

Das prinzipielle Vorgehen, ist folgendes:

- Fr OEP:
   1. appl_find("OEPMANGR"),
   2. Environment-Variable OEPMANAGER berprfen,
   3. erneut appl_find() mit dem Programmnamen von 2.,
   4. das unter 2. angegebene Programm nachstarten (sofern mglich).

- Fr OLGA (siehe OLGA-Dokumentation):
   1. appl_find("OLGA    ");
   2. Environment-Variable OLGAMANAGER berprfen,
   3. erneut appl_find() mit dem Programmnamen von 2.,
   4. das unter 2. angegebene Programm nachstarten (sofern mglich).

- Fr OLE (OLGA und/oder OEP):
   1. appl_find("OLEMANGR"),
   2. Environment-Variable OLEMANAGER berprfen,
   3. erneut appl_find() mit dem Programmnamen von 2.,
   4. das unter 2. angegebene Programm nachstarten (sofern mglich).


Der OEP-Manager
---------------
Ein wichtiger Bestandteil des OEP ist der Manager. Es handelt sich hierbei um
ein speziell entwickeltes Programm, dessen Funktionen auch problemlos in
alternativen Desktops implementiert werden knnen. Ein Teil des Protokolls wird
vom Manager abgewickelt, weshalb OEP-fhige Applikationen nicht mit allzuviel
Overhead aufgeblht werden.

Die AES-ID des aktiven OEP-Managers kann wie folgt ermittelt werden:

1. Durch appl_find("OEPMANGR").

2. Die Environmentvariable "OEPMANAGER" enthlt den kompletten Pfad der
   OEP-Managerapplikation (z.B. "OEPMANAGER=D:\OEP\MNGR4OEP.APP").
   Es sollte erneut getestet werden, ob appl_find("MNGR4OEP") ein gltiges
   Ergebnis zurckliefert.

3. Sollte weder durch 1. noch durch 2. ein Manager gefunden worden sein, kann
   die Applikationen das unter 2. angegebene Programm nachstarten. Nachdem sich
   der Manager installiert hat, sendet er folgende Message an alle laufenden
   Applikationen:

      msg[0] - OLE_NEW
      msg[1] - AES-ID des OLE-Managers
      msg[2] - 0
      msg[3] - OLGA: Bitmap (OL_MANAGER, OL_START, OL_PIPES)
      msg[4] - OLGA: max. Manager-Stufe des OLGA-Protokolls
      msg[5] - OEP:  OL_OEP (0x0001) gesetzt, falls der Manager OEP beherrscht
      msg[6] - OEP:  0, reserviert
      msg[7] - Versionsnummer des Managers, z.B. 0x0114 fr 1.14

   Sicherheitshalber sollten zu diesem Zeitpunkt alle OEP-Operationen (und
   entsprechende Menpunkte) nicht ausfhrbar sein.

Der Manager bietet verschiedene Konfigurationsmglichkeiten, so ist z.B. das
systemweite Updaten der Objekte an-/abschaltbar. Wenn der User nderungen an
den Manager-Einstellungen vornimmt, erhlt jede Applikation automatisch eine
OEP_CONFIG-Message.

Auf die OEP_CONFIG-Message mu nur reagiert werden, falls die AES-ID der
OEP_CONFIG-Message (msg[1]) unterschiedlich zu der bisher bekannten
Manager-AES-ID ist (siehe DEMO.C)!

Sollten zu diesem Zeitpunkt bereits Objekthandles benutzt werden (z.B. wurden
bereits OEP-Dokumente/Objekte geladen), so mssen diese dem Manager ebenfalls
bekanntgemacht werden (das Objekthandle mu also konvertiert werden).


Es war einmal ein Manager...
----------------------------
Der installierte Manager kann das System verlassen. Dies kann der Fall sein,
wenn der User ihm z.B. beendet oder das OS einen Shutdown durchfhrt. Der
Manager sendet der Applikation dann folgende Message:

   msg[0] - OLE_EXIT
   msg[1] - AES-ID des Managers
   msg[2] - 0
   msg[3] - 0 (reserviert)
   msg[4] - 0 (reserviert)
   msg[5] - 0 (reserviert)
   msg[6] - 0 (reserviert)
   msg[7] - 0 (reserviert)

Die Applikation sollte daraufhin keine OLE/OEP-Operationen durchfhren, da
keine zentrale Koordinierungsstelle im System installiert ist. Alle
Protokoll-spezifischen Menpunkte sollten unzugnglich gemacht werden.


Start von OEP-Applikationen
---------------------------
Zuerst sollte nach einem bereits installierten OEP-Manager gesucht werden (siehe
hierzu unter 'Der OEP-Manager').

Wenn die Applikation durch dieses Verfahren keinen Manager gefunden hat, sollte
sie auf alle OEP-Operationen verzichten (und entsprechende Menpunkte nicht
zugnglich machen). Ein nachtrglich gestarteter Manager meldet sich bei der
Applikation mit einer OLE_NEW-Message (siehe oben). War bis zu diesem Zeitpunkt
kein Manager installiert (oder ein neuer Manager installiert sich), mu ihm die
Applikation folgende Message senden:

   msg[0] - OLE_INIT
   msg[1] - AES-ID der Applikation
   msg[2] - 0
   msg[3] - 0 (fr OLGA relevant)
   msg[4] - 0 (fr OLGA relevant)
   msg[5] - OL_OEP (0x0001; OEP-Protokoll wird angefordert)
   msg[6] - 0 (fr OEP reserviert)
   msg[7] - maschinenlesbarer XAcc-Programmtyp (oder 0)
              "WP" = Textverarbeitung
              "DP" = DTP
              "ED" = Texteditor
              "DB" = Datenbank
              "SS" = Tabellenkalkulation
              "RG" = Rastergrafikprogramm
              "VG" = Vektorgrafikprogramm
              "GG" = allgemeines Grafikprogramm
              "MU" = Musikanwendung
              "CD" = CAD
              "DC" = Datenkommunikation
              "DT" = Desktop
              "PE" = Programmierumgebung

Wenn der installierte Manager sich bei der Applikation mit folgender Message
meldet, kann er der Applikation OEP-Support anbieten:

   msg[0] - OEP_CONFIG
   msg[1] - AES-ID des Managers
   msg[2] - 0
   msg[3] - Configurationbits (OEP_CONF_UPDT, OEP_CONF_SHOW etc.)
   msg[4] - Configurationbits (0, reserviert)
   msg[5] - Versionsnummer des Managers (z.B. 0x0100 = 1.00)
   msg[6] - 0 (reserviert)
   msg[7] - 0 (reserviert)

Wenn kein OEP-Manager installiert ist, sollte dem User durch einen Alert
mitgeteilt werden, das ein erweitertes Objekthandling nicht mglich ist (dies
bleibt jedoch dem Applikationsprogrammierer berlassen). Ein normaler Drag&Drop
sollte allerdings weiterhin mglich sein!


Beenden von OEP-Applikationen
-----------------------------
Applikationen mssen sich beim Manager nicht abmelden. Der Manager berprft
selbstndig, ob sich angemeldete Applikation noch im System befinden. Sollte
dies nicht der Fall sein, so wird die Applikation (und deren Links) automatisch
von Manager abgemeldet.

Um das OLE-Protokoll zu vervollstndigen, wurde eine Exit-Message eingefhrt.
Sie hat folgenden Aufbau:

   msg[0] - OLE_EXIT
   msg[1] - AES-ID der Applikation
   msg[2] - 0
   msg[3] - 0 (reserviert)
   msg[4] - 0 (reserviert)
   msg[5] - 0 (reserviert)
   msg[6] - 0 (reserviert)
   msg[7] - 0 (reserviert)

Diese Message sollte an den Manager gesendet werden, wenn die Applikation
terminiert. Der Manager erkennt allerdings auch selbstndig, wenn die
Applikation das System verlassen hat.


Neue Objekte/Drag&Drop
----------------------
Wenn der User ein Objekt einer anderen Applikation bergeben mchte, z.B.
durch eine D&D-Operation, mu...

a) ...sofern das Objekt bereits ein Original-Objekthandle (und ein momentan
   gltiges Objekthandle!) hat, nichts weiter unternommen werden. Es kann
   sofort zum Datenaustausch kommen (siehe unter 'Der Datenaustausch').

b) ...vom Manager ein Original-Objekthandle fr dieses Objekt erfragt werden.
   Hierzu startet die Applikation (Quellapp.) einen Drag&Drag mit dem Manager
   als Zielapplikation.

      msg[0] - AP_DRAGDROP
      msg[1] - AES-ID der Quellapp.
      msg[2] - 0
      msg[3] - 0 (Fensterhandle)
      msg[4] - -1 (= fake D&D)
      msg[5] - -1 (= fake D&D)
      msg[6] - 0 (Sondertastenstatus)
      msg[7] - Extension der D&D-Pipe

   Der Manager reagiert auf den D&D und erwartet nun von der Quellapp. den
   Datentyp "OEPD". Die Quellapp. verfhrt nun weiter nach dem D&D-Protokoll,
   und sendet dem Manager den Header fr den OEPD-Datentyp. Der Manager wird
   diesen akzeptieren, woaufhin die Quellapp. die Stuktur in die Pipe schreibt.
   Die OEPD-Struktur hat folgenden Aufbau:

      typedef struct
      {
          WORD    type;           /* Actionbit: OEP_OBNEW */
          LONG    id;             /* 0 = kein Original-Objekthandle vorhanden */
          UWORD   date;           /* [1] aktuelles GEMDOS-Datum */
          UWORD   time;           /* [1] aktuelle GEMDOS-Zeit */
          LONG    systime;        /* [1] aktueller Wert des 200Hz Timers */
          LONG    cid;            /* 0 = kein momentan gltiges Objekthandle */
          BYTE    obname[128];    /* [2] Beschreibung des Objektes */
          BYTE    obfile[128];    /* [2] Dateiname des Objektes */
          LONG    obtype;         /* [2] Objektart */
          LONG    res1;           /* 0, reserviert */
          LONG    res2;           /* 0, reserviert */
          BYTE    apname[32];     /* [2] Ausfhrlicher Name der Applikation */
          BYTE    apfile[10];     /* [2] Dateiname der Applikation */
          WORD    apid;           /* [2] AES-ID der Applikation */
          LONG    res3;           /* 0, reserviert */
          LONG    res4;           /* 0, reserviert */
          BYTE    crname[32];     /* [2] Ausfhrlicher Name der Erzeuger-APP */
          BYTE    crfile[10];     /* [2] Dateiname der Erzeuger-APP */
          WORD    crid;           /* [2] AES-ID der Erzeuger-APP */
          LONG    res5;           /* 0, reserviert */
          LONG    res6;           /* 0, reserviert */
          WORD    res7;           /* 0, reserviert */
          LONG    res8;           /* 0, reserviert */
      } OEPD_HEADER;

   [1] Die Quellapp. sollte sicherstellen, da nicht mehrere Objekthandle mit
       den identischen Daten erzeugt werden! Anhand dieser Daten entscheidet
       der Manager, ob sich identische Links im System befinden.

   [2] Alle Angaben mit dieser Kennung sind optional. D.h. sie mssen nicht
       angegeben werden, knnen allerdings vom Manager (oder einer anderen
       Applikation) nachtrglich angefordert werden (um z.B. dem User die
       Link-Daten anzuzeigen).

   Der Manager ermittelt nach der bertragung der OEPD-Struktur das neue
   Objekthandle und sendet der Quellapp. in der noch offenen Pipe eine 2 Byte
   Antwort. Diese 2 Bytes geben an, wieviele Bytes die Quellapp. aus der Pipe
   noch lesen soll. Im Moment wird folgende Struktur bertragen:

      typedef struct
      {
         LONG  link;
      } OEPD_DATA;

   Das in "link" mitgeteilte Original-Objekthandle gilt im momentan laufenden
   System auch als momentan gltiges Objekthandle! Sollte 'link' den Wert '-1'
   (minus Eins) enthalten, so konnte kein Objekthandle zugeteilt werden.
   Erweiterungen dieser Struktur sollten momentan ignoriert werden.

   Das Original-Objekthandle mu, zusammen mit den in der OEPD_HEADER-Struktur
   oben durch [1] gekennzeichneten Daten, von der Applikation als Kennung fr
   das Objekt gespeichert werden. Als absolutes Minimum hierfr, gilt folgende
   Struktur (Erweiterungen aus der Datentyp-Struktur werden empfohlen [vgl.
   OEP_BIGOBHEADER]):

      typedef struct
      {
         LONG  id;         /* Original-Objekthandle von OEP_LINK */
         UWORD date;       /* GEMDOS-Datum von OEP_NEWD */
         UWORD time;       /* GEMDOS-Zeit von OEP_NEWD */
         LONG  systime;    /* 200Hz Timerwert von OEP_NEWD */
         LONG  cid;        /* Momentan gltiges Objekthandle */
      } OEP_OBHEADER;

   Zuknftig mu, anhand des in AES-Messages mitgeteilten momentan gltigen
   Objekthandle, die Applikation das damit verbundene Objekt in Verbindung
   bringen knnen.

   ACHTUNG: Das Original-Objekthandle und die dazugehrenden Daten (date, time,
   systime) drfen niemals verndert werden! Das konvertierte Objekthandle
   (= momentan gltiges Objekthandle) hat nur im momentan laufenden System eine
   Bedeutung!


Importieren von Objekten
------------------------
Unter dem Import von Objekten versteht man unter OEP, das Einbringen von
Objekten, die bereits ein Original-Objekthandle besitzen (z.B. beim ffnen
eines bestehenden Dokumentes oder durch einen Drag&Drop etc.). Dieses
Original-Objekthandle mu dem aktuellen Stand im System angepasst werden.

Um dies zu erreichen, startet die Applikation (Quellapp.) einen Drag&Drop
mit dem Manager als Zielapplikation (siehe unter "Neue Objekte/Drag&Drop").
Die zu bertragende OEPD-Struktur mu folgende Daten beinhalten:

   typedef struct
   {
      WORD    type;           /* Actionbit: OEP_OBCONV */
      LONG    id;             /* Original-Objekthandle des Objektes */
      UWORD   date;           /* GEMDOS-Datum des Objektes */
      UWORD   time;           /* GEMDOS-Zeit des Objektes */
      LONG    systime;        /* Wert des 200Hz Timers des Objektes */
      LONG    cid;            /* momentan gltiges Objekthandle (oder 0) */
      BYTE    obname[128];    /* [1] Beschreibung des Objektes */
      BYTE    obfile[128];    /* [1] Dateiname des Objektes */
      LONG    obtype;         /* [1] Objektart */
      LONG    res1;           /* 0, reserviert */
      LONG    res2;           /* 0, reserviert */
      BYTE    apname[32];     /* [1] Ausfhrlicher Name der Applikation */
      BYTE    apfile[10];     /* [1] Dateiname der Applikation */
      WORD    apid;           /* [1] AES-ID der Applikation */
      LONG    res3;           /* 0, reserviert */
      LONG    res4;           /* 0, reserviert */
      BYTE    crname[32];     /* [1] Ausfhrlicher Name der Erzeuger-APP */
      BYTE    crfile[10];     /* [1] Dateiname der Erzeuger-APP */
      WORD    crid;           /* [1] AES-ID der Erzeuger-APP */
      LONG    res5;           /* 0, reserviert */
      LONG    res6;           /* 0, reserviert */
      WORD    res7;           /* 0, reserviert */
      LONG    res8;           /* 0, reserviert */
   } OEPD_HEADER;

   [1] Diese Daten sind optional. Siehe oben unter [2].

Der Manager ermittelt nach der bertragung der OEPD-Struktur das momentan
gltige Objekthandle, und verfhrt wie unter "Neue Objekte/Drag&Drop" angegeben.

ACHTUNG: Das Original-Objekthandle und die dazugehrenden Daten (date, time,
systime) drfen niemals verndert werden! Das konvertierte Objekthandle hat nur
im momentan laufenden System eine Bedeutung! Sobald das Dokument gespeichert
und erneut geffnet wird, mssen die Original-Objekthandle der verwendeten
Objekte erneut konvertiert werden!


Updaten von Objekten
--------------------
Wenn der User ein Objekt verndert hat bzw. wenn die Applikation angewiesen
wird, das Objekt als 'verndert' bekanntzugeben, schickt die Applikation
(Quellapp.) folgende Mitteilung an den Manager:

   msg[0] - OEP_UPDATE
   msg[1] - AES-ID der Quellapp.
   msg[2] - 0
   msg[3] - Actionbits: OEP_OBJECT - Objektdaten verndert
                        OEP_OBINFO - Objektinformationen verndert
                        OEP_APINFO - Applikationsinformationen verndert
                        OEP_CRINFO - Erzeugerapplikationsinformation verndert
   msg[4] - momentan gltiges Objekthandle (Highword)
   msg[5] - momentan gltiges Objekthandle (Lowword)
   msg[6] - 0 (reserviert)
   msg[7] - 0 (reserviert)

Der Manager bernimmt die Aufgabe, andere Applikationen von der Vernderung des
Objektes zu unterrichten. Applikationen bekommen vom Manager folgende Mitteilung
gesandt:

   msg[0] - OEP_UPDATE
   msg[1] - AES-ID des Managers
   msg[2] - 0
   msg[3] - Actionbits OEP_OBJECT, OEP_OBINFO, OEP_APINFO, OEP_CRINFO
   msg[4] - momentan gltiges Objekthandle (Highword)
   msg[5] - momentan gltiges Objekthandle (Lowword)
   msg[6] - AES-ID der Quellapp.
   msg[7] - 0 (reserviert)

Applikationen (Zielapp.), die die Daten des vernderten Objektes anfordern
mchten, senden der Quellapp. (msg[6] von OEP_UPDATE!) folgende Mitteilung:

   msg[0] - OEP_DATA
   msg[1] - AES-ID der Zielapp.
   msg[2] - 0
   msg[3] - Actionbits: OEP_OBJECT - Objektdaten anfordern
                        OEP_OBINFO - Objektinformationen anfordern
                        OEP_APINFO - Applikationsinformationen anfordern
                        OEP_CRINFO - Erzeugerapplikationsinformationen anfordern
   msg[4] - momentan gltiges Objekthandle (Highword)
   msg[5] - momentan gltiges Objekthandle (Lowword)
   msg[6] - 0 (reserviert)
   msg[7] - 0 (reserviert)

Daraufhin wird ein Drag&Drop von der Quellapp. auf die Zielapp. durchgefhrt.
Siehe unter 'Der Datenaustausch'.


Der Datenaustausch
------------------
Wenn das von der Quellapp. zu bertragende Objekt ein Original-Objekthandle
(und ein momentan gltiges Objekthandle!) besitzt, beginnt ein normaler
MultiTOS-Drag&Drop auf die Zielapp. Folgende Message mu an die Zielapp.
gesendet werden:

   msg[0] - AP_DRAGDROP
   msg[1] - AES-ID der Quellapp.
   msg[2] - 0
   msg[3] - Fensterhandle (0 = Desktophintergrund, -1 = ggf. neues Fenster)
   msg[4] - Maus X Position oder -1 (= fake D&D)
   msg[5] - Maus Y Position oder -1 (= fake D&D)
   msg[6] - Sondertastenstatus
   msg[7] - D&D-Pipe-Extension

Als erstes wird der OEPD-Datentyp gesendet. Diese Struktur wird grundstzlich
immer komplett gesendet, egal welche Daten (= Actionbits in OEP_DATA)
angefordert wurden! Die OEPD-Struktur hat folgenden Aufbau:

   typedef struct
   {
       WORD    type;           /* [1] Actionbits */
       LONG    id;             /* [2] Original-Objekthandle */
       UWORD   date;           /* [2] GEMDOS-Datum des Objektes */
       UWORD   time;           /* [2] GEMDOS-Zeit des Objektes */
       LONG    systime;        /* [2] 200Hz Timerwert des Objektes */
       LONG    cid;            /* [2] momentan gltiges Objekthandle */
       BYTE    obname[128];    /* [3] Beschreibung des Objektes */
       BYTE    obfile[128];    /* [3] Dateiname des Objektes */
       LONG    obtype;         /* [3] Objektart */
       LONG    res1;           /* 0, reserviert */
       LONG    res2;           /* 0, reserviert */
       BYTE    apname[32];     /* [4] Ausfhrlicher Name der Applikation */
       BYTE    apfile[10];     /* [4] Dateiname der Applikation */
       WORD    apid;           /* [4] AES-ID der Applikation */
       LONG    res3;           /* 0, reserviert */
       LONG    res4;           /* 0, reserviert */
       BYTE    crname[32];     /* [5] Ausfhrlicher Name der Erzeuger-APP */
       BYTE    crfile[10];     /* [5] Dateiname der Erzeuger-APP */
       WORD    crid;           /* [5] AES-ID der Erzeuger-APP */
       LONG    res5;           /* 0, reserviert */
       LONG    res6;           /* 0, reserviert */
       WORD    res7;           /* 0, reserviert */
       LONG    res8;           /* 0, reserviert */
   } OEPD_HEADER;

   [1] Es mssen die Actionbits gesetzt sein, die bei OEP_DATA angegeben
       wurden. Sollte die angeforderte Information nicht verfgbar sein, so
       darf das entsprechende Actionbit nicht gesetzt werden, damit die
       anfordernde Applikation dieses erkennen kann!

   [2] Diese Daten sollten immer angegeben werden, damit die Zielapplikation
       das angeprochene Objekt sicher identifizieren kann.

   [3] Actionbit OEP_OBINFO - Erluterung:
         obname[] - Beschreibung des Objektes (z.B. "Textblock aus SAMPLE.TXT"),
         obfile[] - Dateiname des Objektes (sofern vorhanden),
         obtype   - Bitvektor zur Bestimmung des Objektes (analog zur
                    SC_CHANGED Kennung der Scrap-Datei).

   [4] Actionbit OEP_APINFO - Erluterung:
         apname[] - Name der befragten/eigenen Applikation (z.B. "QED Editor"),
         apfile[] - Dateiname der Applikation (z.B. "QED" bei QED.APP; er soll
                    somit dem appl_find/appl_search-Format entsprechen),
         apid     - AES-ID der Applikation.

   [5] Actionbit OEP_CRINFO - Erluterung:
         crname[] - Name der Erzeuger-Applikation (Creator),
         crfile[] - Dateiname der Erzeuger-Applikation (siehe apfile[]),
         crid     - AES-ID der Erzeuger-Applikation (ist evtl. ungltig!)

   [3], [4], [5] Die unter diesen Nummern aufgefhrten Informationen knnen bei
       jedem Austausch der OEPD-Struktur bergeben werden. Natrlich sollte
       dies auch in den Actionbits bekanntgemacht/eingetragen werden.

War die bertragung dieses Datentyps...

a) ...erfolgreich, und die Objektdaten wurden angefordert (Actionbit OEP_OBJECT
   war gesetzt), wird anschlieend der Datenaustausch durchgefhrt. Dieser
   Datenaustausch mu der Zielapplikation natrlich erneut durch eine
   AP_DRAGDROP-Message mitgeteilt werden!

   Damit Applikationen einen Zusammenhang zwischen den OEPD-Daten und den
   bermittelten Objektdaten herstellen knnen, gilt der folgende Grundsatz:

   Ist im Feld 'type' der OEPD-Struktur das Actionbit OEP_OBJECT gesetzt, so
   wird mit dem nchsten D&D dieser Applikation die Objektdaten bermittelt.

b) ...erfolglos (Datentyp wurde nicht akzeptiert, kein Timeout!), wird der ganz
   normale AP_DRAGDROP-Vorgang weitergefhrt.

   Anschlieend mu dem Manager noch mitgeteilt werden, da das angeforderte
   Original-Objekthandle nicht benutzt wird. Hierzu wird folgende Mitteilung
   an den Manager gesendet:

      msg[0] - OEP_LINK
      msg[1] - AES-ID der Quellapp.
      msg[2] - 0
      msg[3] - Actionbit OEP_LINK_FREE
      msg[4] - Original-Objekthandle (Highword)
      msg[5] - Original-Objekthandle (Lowword)
      msg[6] - 0 (reserviert)
      msg[7] - 0 (reserviert)


OLE/OEP Definitionen
--------------------
/* OLE ID-Numbers for AES-Messages */

#define OLE_INIT        16962    /* Beim Manager anmelden */
#define OLE_EXIT        16963    /* Beim Manager abmelden/Manager terminiert */
#define OLE_NEW         16964    /* Manager wurde gestartet */
#define OL_OEP          0x0001   /* OEP-Protokoll verfgbar/anfordern */


/* OEP ID-Numbers for AES-Messages */

#define OEP_RES00       21000    /* reserviert */
#define OEP_CONFIG      21001    /* OEP-Konfigurationen */
#define OEP_INFO        21002    /* Informationen anfordern */
#define OEP_LINK        21003    /* Objekthandle-nderungen */
#define OEP_RES04       21004    /* reserviert */
#define OEP_UPDATE      21005    /* Objekt/Daten wurden verndert */
#define OEP_DATA        21006    /* Objekt/Daten anfordern */
#define OEP_CHANGED     21007    /* Wurde Objekt/Daten verndert? */
#define OEP_MANGRJOB    21008    /* Aufgabe an Manager abgeben */
#define OEP_RES09       21009    /* reserviert */
#define OEP_RES10       21010    /* reserviert */
#define OEP_RES11       21011    /* reserviert */
#define OEP_RES12       21012    /* reserviert */
#define OEP_RES13       21013    /* reserviert */
#define OEP_RES14       21014    /* reserviert */
#define OEP_RES15       21015    /* reserviert */
#define OEP_RES16       21016    /* reserviert */
#define OEP_RES17       21017    /* reserviert */
#define OEP_RES18       21018    /* reserviert */
#define OEP_RES19       21019    /* reserviert */


/* Configurationsbits from OEP_CONFIG */

#define OEP_CONF_UPDT   0x0001   /* Objekte systemweit aktualisieren */
#define OEP_CONF_SHOW   0x0002   /* Manager kann Links anzeigen */
#define OEP_CONF_USER   0x0004   /* User kann Links selbstndig verknpfen */
#define OEP_CONF_RESV   0x0008   /* reserviert */
#define OEP_CONF_GDOS   0x0010   /* Manager kann GDOS-Ausgaben bernehmen */


/* Actionbits from OEP_INFO */

#define OEP_INFO_CONF   0x0001   /* Konfiguration erfragen */


/* Actionbits from OEP_LINK */

#define OEP_LINK_FREE   0x0001   /* Objekthandle freigeben */
#define OEP_LINK_USER   0x0002   /* Usernderung: neues Objekthandle */


/* Actionbits from OEP_UPDATE, OEP_DATA and the "type"-field of OEPD */

#define OEP_OBNEW       0x0001   /* Neues Original-Objekthandle anfordern */
#define OEP_OBCONV      0x0002   /* Original-Objekthandle konvertieren */
#define OEP_ARES0       0x0004   /* reserviert */
#define OEP_ARES1       0x0008   /* reserviert */
#define OEP_GDOS        0x0010   /* GDOS-Ausgabe bernehmen */
#define OEP_ARES2       0x0020   /* reserviert */
#define OEP_ARES3       0x0040   /* reserviert */
#define OEP_ARES4       0x0080   /* reserviert */
#define OEP_OBJECT      0x0100   /* Objektdaten */
#define OEP_OBINFO      0x0200   /* Objektinformationen */
#define OEP_APINFO      0x0400   /* Applikationsinformationen */
#define OEP_CRINFO      0x0800   /* Erzeuger-Applikationsinformationen */


/* minimum Header for OEP-Objects */

typedef struct
{
   LONG  id;                     /* Original-Objekthandle */
   UWORD date;                   /* GEMDOS-Datum */
   UWORD time;                   /* GEMDOS-Zeit */
   LONG  systime;                /* Wert des 200Hz Timer */
   LONG  cid;                    /* momentan gltiges Objekthandle */
} OEP_OBHEADER;


/* big Header for OEP-Objects */

typedef struct
{
   LONG  id;                     /* Original-Objekthandle */
   UWORD date;                   /* GEMDOS-Datum */
   UWORD time;                   /* GEMDOS-Zeit */
   LONG  systime;                /* Wert des 200Hz Timer */
   LONG  cid;                    /* momentan gltiges Objekthandle */
   BYTE  obname[128];            /* Beschreibung des Objektes */
   BYTE  obfile[128];            /* Dateiname des Objektes */
   LONG  obtype;                 /* Objektart */
   BYTE  crname[32];             /* Name der Erzeuger-Applikation */
   BYTE  crfile[10];             /* Dateiname der Erzeuger-Applikation */
   WORD  crid;                   /* AES-ID der Erzeuger-Applikation */
   WORD  datacoming;             /* Objektdaten folgen... */
} OEP_BIGOBHEADER;


/* MultiTOS Drag&Drop datatype "Object Exchange Protocol Data" */

#define DD_OEP          "OEPD"


/* global definition for OLE/OEP Applications */

#define SEND_TOALL      -1       /* Message an alle APPs senden */
#define NO_MANAGER      -2       /* kein OLE-Manager installiert */

typedef struct
{
   WORD  apid;                   /* Applikations-ID */
   WORD  manager;                /* Manager-ID (-2 = nicht installiert) */
   WORD  ok;                     /* Manager beherrscht OEP */
   WORD  version;                /* Versionsnummer des Managers */
   WORD  config;                 /* Configurationbits */
   WORD  res;                    /* reserviert */
} OEP;


Anmerkungen
-----------
- OEP-Features:
  - nicht Dateiorientiert,
  - keine Pointer-Operationen,
  - basierend auf dem MultiTOS-D&D-Protokoll,
  - Links bleiben Rechnerbergreifend bestehen,
  - Datenbergabe nicht an spezielles Format gebunden,
  - relativ geringer Overhead in Applikationen,
  - lediglich 16 Bytes pro Objekt/Link (Minimum),
  - Links werden jederzeit (automatisch) hergestellt,
  - Applikationen mssen sich beim Manager nicht abmelden,
  - Link/Linkdaten knnen vom User gendert werden,
  - Updaten von Objekten im Manager konfigurierbar,
  - unabhngig von Memory Protection und virtuellem Adressraum,
  - minimalste Chance eines falschen (automatischen) Links,
  - Manager darf jeder OEP-Applikation beigelegt werden.
  - Manager (ohne Source) und Demoprogramm (mit C-Sourcen fr OEP und Drag&Drop)
    ist frei erhltlich.

- Der MultiTOS-D&D-Datentyp "OEPD" wurde von Eric R. Smith (Atari Corp., USA)
  zur Benutzung freigegeben und ist ab sofort fr OEP reserviert.

- Nicht (vollstndig) ausgefhrte Messages:
  - OEP_INFO, OEP_LINK, OEP_CHANGED, OEP_MANGRJOB.

- Nicht (vollstndig) ausgefhrte Actionbits:
  - OEP_GDOS,
  - OEP_CONF_UPDT, OEP_CONF_SHOW, OEP_CONF_USER, OEP_CONF_GDOS,
  - OEP_LINK_FREE, OEP_LINK_USER.


Revisionsnderungen
-------------------
0.6 auf 0.7:

  Dokumentation:
  - OLE_INIT ersetzt OEP_OK,
  - Reservierte OEP-AES-Message-Definitionen gendert,
  - OEP_OK entfernt (reserviert),
  - OEP-Struktur gendert/erweitert,
  - OEP_SERVJOB in OEP_MANGRJOB umbenannt,
  - OLE-Initialisierung (fr OLGA und OEP),
  - OLE_INIT, OLE_EXIT, OLE_NEW neu eingefhrt,
  - Aus 'OEP-Server' wurde 'OEP-Manager'.

  Demoprogramm:
  - oep_manager() in ole_manager() umbenannt und erweitert,
  - oep.ok wird analog zu oep.manager gesetzt (FALSE oder TRUE),
  - Neue Message-Behandlung: OLE_EXIT, OLE_NEW, OEP_CONFIG.


Autor/Fragen/Kritik/Anregungen
------------------------------
Sollten Sie Fragen, Kritiken oder Anregungen bezglich OEP haben, knnen Sie
sich jederzeit an mich wenden:

Sackpost (kann dauern):

   Alexander Lorenz
   Diemantstein 127
   86657 Bissingen

E-Mail (bevorzugt):

   MausNet: Alexander Lorenz @ N
   Internet: Alexander_Lorenz@n.maus.de

