home *** CD-ROM | disk | FTP | other *** search
- ----------------------------------------------------------------------
- Vorwort
- ----------------------------------------------------------------------
-
- Die üblichen Aktionen zum Übertragen von Daten zwischen Programmen
- und Dateisystemen sind jedem, der schon einmal mit einem Archimedes
- unter RiscOS gearbeitet hat, bekannt. Für den Benutzer der Fenster-
- oberfläche WIMP stellt sich daß sehr einfach und intuitiv dar.
-
- Programmierer aus der Amiga-, Macintosh- oder Windows-Szene könnten
- jetzt vermuten, daß hinter diesem einfachen Verfahren des Icon-Herum
- schiebens eine ganze Menge Programmierarbeit steckt. Leute, die zum
- erstenmal vor einem Archimedes sitzen, kann man jedenfalls immer
- daran erkennen, daß sie eine Datei speichern wollen, indem sie die
- mittlere Maustaste drücken (und meist gedrückt halten), mit dem Maus-
- zeiger auf 'Save' gehen, diesen Menüpunkt dann irgendwie anwählen und
- sich wundern, daß kein typischer File-Requester erscheint.
-
- Es ist bei weitem nicht so kompliziert! Ganz im Gegenteil. Die
- einzige Voraussetzung, die man erfüllen muß, um nachfolgende Er-
- läuterungen zu verstehen, sind Kenntnisse über das Message-System
- des WIMP. Man kommt ohnehin nicht drumherum, wenn man eine Multi-
- tasking-Applikation unter RiscOS entwickeln will.
-
- ----------------------------------------------------------------------
- Das Data Transfer Protocol
- ----------------------------------------------------------------------
-
- Aus Programmierersicht läßt sich der Vorgang der Übertragung
- von Daten zwischen Applikationen noch einfacher verstehen. Ein
- wesentlicher Unterschied von RiscOS zu anderen Betriebssystem ist
- schon einmal die Tatsache, daß alle Dateisysteme unter RiscOS auch
- nichts anderes als (Module)-Tasks sind. Den krassesten Gegensatz zu
- diesem Konzept bildet wohl ein IBM-kompatibler PC, auf dem MS-DOS
- läuft.
-
- Für einen Archimedes-Programmierer bedeutet es jedenfalls, daß
- er Sonderfälle ausschließen kann: es macht keinen Unterschied,
- Daten auf Festplatte zu schreiben oder z.B. einem DTP-System
- zu übergeben. Zu diesem Zweck wurde ein Message-Protokoll ent-
- worfen, an das sich auch die Dateisysteme halten. Dadurch verrin-
- gert sich der Code-Overhead eines Programms zur Datenübertragung
- erheblich. Dieses Protokoll kommt mit 7 standardisierten Message-
- Strukturen aus:
-
- Message_DataSave 1
- Message_DataSaveAck 2
- Message_DataLoad 3
- Message_DataLoadAck 4
- Message_DataOpen 5
- Message_RamFetch 6
- Message_RamTransmit 7
-
- Die Struktur dieser Messages wird in den beiliegenden Dateien
- genauer beschrieben. Diese Datei beschreibt bloß die generellen
- Vorgänge und kann als Kurs für Einsteiger angesehen werden.
-
- Wird vom Benutzer eines Programms jetzt eine 'Speicheraktion'
- ausgelöst, werden einige (oder alle) Message-Strukturen in einer
- festgelegten Reihenfolge zwischen den beteiligten Tasks ver-
- sandt. Leider wird der von Acorn definierte Standard nicht in
- jedem Fall eingehalten.
-
- 1. Das Sichern von Daten in eine Datei.
- ---------------------------------------
- Ausgelöst wird diese Aktion durch den üblichen 'Save as:'-
- Dialog eines Programms. Dieser Dialog enthält mindestens
- ein Texticon, in das man den Endnamen der zu erzeugenden
- Datei schreiben kann sowie ein Icon, das auch den jeweiligen
- Typ der Datei anzeigen sollte.
- Folgendes geschieht:
-
- - Der Benutzer hat das Icon in ein Verzeichnisfenster
- gezogen und 'läßt es los'. Das Programm empfängt
- beim nächsten Aufruf von Wimp_Poll als Rückgabewert
- User_Drag_Box.
-
- - Das Programm ruft Wimp_GetPointerInfo auf. Es erhält
- folgende Informationen: absolute Koordinaten des
- Mauszeigers, Zustand der Maustasten sowie die Handle
- des Icons bzw. Fensters, in denen der Mauszeiger sich
- gerade befindet.
-
- - Das Programm schickt Message_DataSave an den Filer,
- indem es die vorher ermittelten Informationen benutzt.
- Weiterhin übergeben wird der Dateiendname, den der
- Benutzer der Datei gegeben hat.
-
- - Der Filer antwortet mit Message_DataSaveAck. Diese
- Message enthält den kompletten Pfadnamen der zu er-
- zeugenden Datei.
-
- - Das Programm sichert die Daten in diese Datei.
-
- - Das Programm schickt Message_DataLoad an den Filer.
- Diese Message enthält den zuvor übermittelten
- kompletten Pfadnamen der erzeugten Datei.
-
- - Der Filer antwortet mit Message_DataLoadAck.
-
- Wer die letzten beiden Schritte für überflüssig hält,
- sollte sich das folgende Beispiel durchlesen.
-
- 2. Das Übertragen von Daten zu einer anderen Applikation.
- ---------------------------------------------------------
- Der 'Save as:'-Dialog findet wieder Anwendung, mit dem
- Unterschied, daß das Icon nicht in einem Verzeichnis-
- fenster, sondern auf dem Iconbar-Icon oder Fenster einer
- anderen Applikation 'abgelegt' wird.
-
- - Wimp_Poll des übertragenden Programms ergibt ein
- Ereignis des Typs User_Drag_Box (siehe oben).
-
- - Das übertragende Programm ruf Wimp_GetPointerInfo auf.
-
- - Das Programm schickt Message_DataSave an das empfangende
- Programm, indem es die vorher ermittelten Informationen
- benutzt.
-
- => Bisher unterscheidet sich also noch nichts vom ersten
- Beispiel. Es ist für die übertragende Applikation
- auch nicht ohne weiteres erkennbar, um was für eine
- Art von Task es sich hier handelt.
-
- - Das empfangende Programm anwortet wie erwartet mit
- Message_DataSaveAck. Diese Message enthält üblicherweise
- den Pfadnamen einer temporären Datei <Wimp$Scrap>.
-
- - Das übertragende Programm sichert die Daten in diese
- temporäre Datei. (Der Filer erweitert die System-
- variable <Wimp$Scrap> zu einem kompletten Pfadnamen.)
-
- - Das übertragende Programm schickt Message_DataLoad an
- das empfangende Programm. Diese Message enthält den
- Pfadnamen aus der empfangenen Message_DataSaveAck,
- also z.B. <Wimp$Scrap>.
-
- - Das empfangende Programm lädt die Daten aus der tempo-
- rären Datei und löscht diese Datei.
-
- - Das empfangende Programm antwortet wie erwartet mit
- Message_DataLoadAck.
-
- => Wie man sieht, braucht ein Programm also gar nicht
- zu 'wissen', mit wem es zu tun hat. Der Vorgang der
- Datenübertragung ist immer der gleiche. Es folgt
- eine Kurzfassung der Vorgänge. Nehmen wir an, A will
- B die Datei C übertragen. D sei der Pfadname der
- temporären oder endgültigen Datei. Der Unterschied
- zwischen C und D ist, daß D nicht nur den gewünschten
- Endnamen der Datei, sondern auch Pfadangaben beinhal-
- tet. Der unter RiscOS 2 übliche Pfadname für D ist
- <Wimp$Scrap> = z.B. 'SCSI::HD0.$.!System.ScrapFile'.
-
- 1. A -> B: Message_DataSave C
- 2. B -> A: Message_DataSaveAck D
- 3. A: Sichert Daten in D
- 4. A -> B: Message_DataLoad D
- 5: B: Lädt die Daten aus D und löscht D
- 6: B -> A: Message_DataLoadAck D
-
- Der entscheidende Unterschied, der A verborgen bleibt,
- ist das Verhalten von B nach Schritt 4. Der Filer wird
- Schritt 5 natürlich nicht ausführen, er antwortet aber
- korrekt. Bekommt A auf Message_DataLoad keine Antwort
- der Form DataLoadAck, so hat A die Datei D zu löschen
- und eine Fehlermeldung auszugeben: 'Data transfer
- failed: Receiver died.'
-
-
- 3. Laden von Daten aus einer Datei
- ----------------------------------
- Wie sich aus den obigen Beispiel ersehen läßt, hat eine
- Applikation (!) eine Datei zu laden, wenn Message_DataLoad
- empfangen wird.
-
- Der übliche Weg, einem Programm eine derartige Nachricht
- zukommen zu lassen, ist ein Icon aus einem Verzeichnisfenster
- auf ein Fenster oder das Iconbar-Icon des Programms zu ziehen.
- Folgendes passiert:
-
- 1. Message_DataLoad <Kompl.PfadName> wird empfangen.
- 2. <Kompl.PfadName> laden.
- 3. Message_DataLoadAck <Kompl.PfadName> senden.
-
- => Zu beachten ist, daß in Schritt 2 die Datei nach dem
- Einlesen nicht gelöscht werden darf. Es muß also
- festgehalten werden, ob vorher Message_DataSave
- empfangen wurde, was ein sicheres Anzeichen dafür ist,
- daß es sich bei der 'Gegenstelle' ebenfalls um eine
- Applikation handelt.
-
- 4. Laden von Daten einer anderen Applikation
- --------------------------------------------
- Hier handelt es sich um Fall 2, nur von der Seite des
- Empfängers aus gesehen. Ich fasse nochmal zusammen:
-
- 1. Message_DataSave <DateiEndName> wird empfangen.
-
- 2. Message_DataSaveAck <Wimp$Scrap> senden.
-
- 3. Das andere Programm speichert in <Wimp$Scrap>.
-
- 4. Message_DataLoad <Wimp$Scrap> wird empfangen.
-
- 5. <Wimp$Scrap> laden und löschen.
-
- 6. Message_DataLoadAck <Wimp$Scrap> senden.
-
- => In diesem Fall muß die temporäre Datei gelöscht
- werden. Siehe Fall 3.
-
- => Schritt 5 darf erst ausgeführt werden, wenn auch
- die Aufforderung mittels Message_DataLoad einge-
- gangen ist (Schritt 4).
-
- 5. Automatisches Laden von Daten aus Dateien.
- ---------------------------------------------
- Dieser Fall unterscheidet sich nicht großartig von Fall 3,
- ist aber eines der Grundelemente des Desktops. Wie auch
- unter anderen Betriebssystemen kann man Dateien 'öffnen',
- 'starten' bzw. anzeigen lassen, indem man einen Doppel-
- klick über dem Icon der gewünschten Datei ausführt.
- Folgendes passiert:
-
- 1. Message_DataOpen <DateiEndName> wird empfangen.
-
- 2. <DateiEndName> laden.
-
- 3. Message_DataLoadAck <DateiEndName> senden.
-
- => Die Bedingung, ob eine Datei zu laden ist, ist deren
- Dateityp, der in der Message übermittelt wird. !Edit
- reagiert normalerweise auch nur auf Doppelklicks,
- wenn sie über Text-Dateien stattfinden.
-
- => Antwortet keine Applikation auf Message_DataOpen, so
- führt der Filer *Run <DateiEndName> aus, greift also
- auf eventuell definierte Systemvariablen zurück. Ist
- für den entsprechenden Dateityp nichts definiert,
- wird die Fehlermeldung 'No run action specified for
- this filetype' erzeugt.
-
- => Soll eine Datei aufgrund Message_DataOpen geladen
- werden, so ist das vor dem nächsten Aufruf von
- Wimp_Poll auch mit Message_DataLoadAck <DateiEndName>
- zu bestätigen. Geschieht das nicht, dann hat der
- Benutzer dummerweise zwei Exemplare des gleichen
- Programms auf dem Desktop, die beide die gleiche
- Datei geladen haben. Tritt dann noch der Fall auf,
- daß die bereits geladene Applikation nicht genug
- Speicher hat, um die Datei zu laden, wird die neu
- gestarte Applikation ebenfalls nicht genug Speicher
- zu Verfügung haben ... sprich: doppelte Fehlermeldung.
-
- 6. Datenübertragung via RAM
- ---------------------------
- Es gibt eine Erweiterung des Data Transfer Protocol, um
- die Übertragung von Daten zwischen zwei Applikationen zu
- beschleunigen. Hierbei werden die zu transferrierenden
- Daten nicht in einer temporären Datei zwischengelagert,
- sondern via Wimp_Transferblock direkt zwischen den
- Addressräumen der zwei beteiligten Programmen übertragen.
- Das oben beschriebene Protokoll wird wie folgt erweitert:
-
- Übertragen von Daten zu einer anderen Applikation
- -------------------------------------------------
- 1. A -> B: Message_DataSave <DateiEndName>
- 2. B -> A: Message_RAMFetch
- 3. A -> B: Message_RAMTransmit <data>
- 4. B -> A: Message_RAMFetch ...
-
- Die letzten beiden Schritte werden wiederholt, bis
- alle Daten gesendet und empfangen wurden.
-
- Laden von Daten einer anderen Applikation
- -----------------------------------------
- 1. B -> A: Message_DataSave <DateiEndName>
- 2. A -> B: Message_RAMFetch
- 3. A: Wenn Schritt 2 von B nicht bestätigt wird,
- wird vorgegangen wie üblich:
- Message_DataSaveAck <Wimp$Scrap> usw ...
- ansonsten: B -> A: Message_RAMTransmit
- 4. A: Daten empfangen und verarbeiten.
- 5. Solange der mittels Message_RAMTransmit proto-
- kollierte Buffer voll ist:
- A -> B: Message_RAMFetch
- B: Wimp_TransferBlock
- B -> A: Message_RAMTransmit
-
- => Wenn die erste Message_RAMFetch von der übertragenden
- Applikation B nicht bestätigt wird (also in Form einer
- User_Message_Acknowledge, Typ 19 zurück zum Absender
- A gelangt), sollte die empfangende Applikation A das
- übliche Verfahren via temporärer Datei verwenden.
-
- => Wenn eine der nachfolgenden Message_RAMFetch nicht
- von B (mit Message_RAMTransmit) beantwortet werden,
- sollte A den Empfang kommentarlos (d.h., ohne Fehler-
- meldung) abbrechen.
-
- => Die Daten selbst werden von B mit Wimp_TransferBlock
- übertragen. Die dazu benötigten Informationen, also
- die Adresse und die Größe des Buffers werden von A
- mittels Message_RAMFetch mitgeteilt.
-
- => Abbruchbedingung für den Übertragungsprozeß ist ein
- nicht voller Buffer. Ist die Anzahl der insgesamt zu
- übertragenden Bytes genau ein Mehrfaches der Größe
- des Buffers, so ist ein abschließendes Paar von
- Nachrichten zwischen den Applikationen zu senden,
- bei denen 0 Bytes zu übertragen sind.
-
- => Aus den Beschreibungen im Programmers Reference Manual
- geht leider nicht hervor, ob es erlaubt ist, die
- Größe des Buffers während der Übertragung zu ver-
- ändern. Hier gilt wieder: einige Programme reagieren
- in dieser Hinsicht empfindlich. Man sollte also darauf
- verzichten.
-