CODING ★ BENUTZEROBERFLAECHE CEUS V1.0 - TEIL 2: DER WINDOW-MANAGER (I) (CPC AMSTRAD INTERNATIONAL) ★

Menu - RSXBenutzeroberflaeche CEUS v1.0 - Teil 2: Der Window-Manager (I) (CPC Amstrad International)
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

Haben Sie die letzte Folge gut Überstunden? Ja? Gut, denn jetzt geht es erst richtig los. In diesem Teil kommt das Grundgerüst des komfortablen Window-Managers auf Sie zu. Komfortabel ist immer nur relativ . Natürlich kann man auf dem CPC keinen Window-Manager wie X-Windows oder MS-Windows realisieren. Dazu hat er ganz einfach zu wenig Speicherplatz, und die Berechnungen dafür würden vermutlich wesentlich mehr Zeit verschlingen, als man opfern kann. Also, ein bißchen Selbstbeschränkung muß sein, aber in diesem Rahmen läßt sich schon einiges machen.

Aber was macht dieser Window-Manager denn nun konkret? Nun, im Prinzip übernimmt er die gesamte Fensterverwaltung auf dem CPC. Nicht mehr -aber auch nicht weniger.

Und wie funktioniert diese Fensterverwaltung überhaupt?

Ein Fenster ist ja bekanntlich (vergleiche 1. Folge) ein unabhängiger Bildausschnitt. der andere Bildausschnitte und den Hintergrund nicht beeinflußt. Und damit wäre auch schon das größte Problem der Fensterverwaltung angesprochen: Ein Fenster muß so gestaltet werden, daß man cs über andere Fenster legen und wieder entfernen kann, ohne diese anderen Fenster oder ihren Inhalt zu zerstören. Man merkt sich also den Hintergrund, über dem ein Fenster eröffnet wird. Und das kann man? Ja, natürlich kann man das, aber...

All you need is memory

Machen wir einmal eine kleine Überschlagsrechnung: Angenommen, wir wollen im Mode 2 ein Fenster ab den Koordinaten 5/5 mit der Länge 50/15 Zeichen eröffnen (wer eine Fensterverwaltung im Mode 0 machen will, dem ist eh' nicht mehr zu helfen). Ein Zeichen im Mode 2 belegt 8 Bytes im Bildschirmspeicher. Das Window ist 50 mal 15 Zeichen groß, macht nach Eva Zwerg 15*50*8 = 6000 Bytes nur für dieses eine Window. Dazu kommen noch die Daten für den Rahmen und den Schatten, in unserem Beispiel weitere 1072 Byte. Das sind fast 7 kByte, wenn man jetzt noch fünf weitere Fenster eröffnen will, kann's schon mal ziemlich eng im Speicher werden.

Diese ganzen Probleme gäbe cs natürlich nicht, wenn der CPC wie seine großen Brüder mit den drei Buchstaben einen ordentlichen Textmodus hätte. Da bräuchte man nur noch 1768 Byte, ja wenn...

Er hat aber nicht, und so müssen wir uns damit abfinden, daß ein Programm, wird es länger, auch weniger Windows auf einmal offenhalten darf. Und wenn cs noch so unlogisch klingt - wer gerade Lust dazu hat, kann nachher ja einmal die Window-Routinen so umschreiben, daß sie den Hintergrund in die zweiten 64 kByte eines CPC 6128 auslagern - es geht, immerhin vier ganzbildschirmgroße Fenster unterzubringen. Nicht ganz so sinnvoll, aber durchaus denkbar wäre es, die Daten auf Diskette auszulagern. Da haben dann schon elf Windows Platz, aber auch nur, wenn die Diskette sonst nicht gebraucht wird — und cs ist ziemlich langsam. Ach, hätte man doch nur eine Festplatte, da würden dann bei 20 MByte...

Alles steht im BASIC-Handbuch...

Das Prinzip ist also klar. Wir brauchen eine Routine, die einen bestimmten Bereich des Bildschirms in einen bestimmten anderen Bereich des Speichers auslagert. Aber in welchen? Dieses Problem haben wir zum Glück nicht mehr, denn darum haben sich die Entwickler des BASIC im CPC schon gekümmert. Solange noch genügend freier Speicher da ist. braucht man nur zum Betriebssystem zu gehen und es lieb zu bitten, doch mal eben ein bißchen davon herauszurücken: denn wozu soll man alles selber machen, was andere schon (und besser?) geschaffen haben. Merke: Betriebssysteme sind dazu da, um sie zu benutzen, und nicht, um sie zu umgehen!

Mit dem Memory-Befehl wird die Obergrenze des BASIC zur Verfügung stehenden Speichers festgelegt. Man braucht nur auszurechnen, wieviel Platz man denn eigentlich benötigt (Achtung: der Platzbedarf pro Zeichen ist modusabhängig, die Betriebssystem-Routine SCR CHAR POSITION (#BC1A) liefert im B-Register die Zeichenbreite in Byte zurück), sich die derzeitige Memory-Ad resse zu holen (steht an Adresse #AE5E beim CPC 6128, die Werte für CPC 464/664 stehen - sofern abweichend - im Listing)), den benötigten Platz davon abzuziehen und die Memory-Routinc aufzurufen (#F808 — ist eigentlich nicht der ganze MEMORY-Befehl, reicht aber für unsere Zwecke aus). Wenn der benötigte Platz nicht mehr da ist, meldet sich die Memory-Routine schon von ganz alleine mit einem freundlichen 'Memory full'.

Für das alles ist der Befehl |WINDOW.IN,x,y,xd,yd,@adr%,@)len% zuständig, er speichert den Bereich von x,y (Zeichcnkoordinaten) bis x + xd,y +yd ab und gibt in den Variablen adr% und len% die Adresse und die Länge des Bereichs zurück, in dem der Ausschnitt gespeichert wurde.

DIE BEFEHLE DES CEUS WINDOW-MANAGER (l.Teil)
|WINDOW.IN,x,y,xd,yd, @adr%,@len%(x,y Textkoordinaten: xd,yd Breite bzw. Höhe des Ausschnittes in Tcxt-zeichen; adr%,len Adresse und Länge des reservierten Speichers (WICHTIG: INTEGERVARIABLEN!)) Sichert einen Bildausschnitt im Speicher ab Adresse adr%.
|WINDOW.OUT,x,y,xd,yd,adr,len%Blendet einen gesicherten Bildausschnitt wieder ein und gibt den Speicher frei.
Variablen siehe |WINDOW.IN
|WINDOW.DRAW, x ,y, xd , ydStellt einen Fensterrahmen mit Schatten um die angegebenen Koordinaten dar und löscht den Inhalt.
|SHADOW.ONSchaltet den Schatten ein (Standard).
|SHADOW.OFFSchaltet den Schatten aus.
|WINDOW.OPEN,num,x1,y1,x2,y2(num Windownummer für BASIC; x ½ und y ½ sind die Koordinaten der linken oberen und rechten unteren Ecke des Windows)
Öffnet ein Fenster über den angegebenen Koordinaten.
|WINDOW. CLOSESchließt das oberste Window. Die Koordinaten müssen im Bereich 2/2 bis 79(39,19)/24 liegen; num ist eine Windownummer zwischen 0 und 7.

...fast alles

Nicht ganz so einfach ist das Wieder-einblenden. Zuerst muß man auch hier einfach die Bildschirmadresse holen. Dann den gespeicherten Ausschnitt einfach wieder zurückschreiben und den Speicher, der für den Ausschnitt belegt wurde, wieder freigeben; denn der liegt sonst ziemlich brach als Speicherleiche herum, und so etwas können wir nun wirklich nicht dulden. Wenn man nun einfach einen Ausschnitt speichert und wieder einblendet, dann ist das noch kein großes Problem. Man braucht nur die Speicherobergrenze wieder heraufzusetzen. Aber was macht man, wenn das Betriebssystem seine Symboltabellen ' unter unserem Ausschnitt abgelegt hat oder wenn wieder ein Kassettenbuffer .im Weg ist? Zuerst: Wenn der Kassettenbuffer im Weg ist und man ihn nicht loswerden kann, macht man gar nichts; dann ist der Speicher, der darüber belegt war, weg! Pech gehabt; also:

Wichtig!

Nie ein Window öffnen, dann eine Datei eröffnen und versuchen das Window wieder zu schließen, solange die Datei noch offen ist (gilt auch umgekehrt). Immer FIFO-Prinzip beachten (first in. first out: hier: immer alle Operationen erst dann zu Ende bringen, wenn alle später begonnenen schon fertig sind)!

In allen anderen Fällen stehen wirzwar nicht ohne Probleme dar, aber immerhin sind diese lösbar. Ein Buffer, der nicht mehr gebraucht wird, kann einfach mit einer BASIC-Routine (#F761) unschädlich gemacht werden; die Symboltabellen sind da schon etwas schwieriger. Um sie loszuwerden, muß man ihre Adresse holen und sic eventuell 'von Hand* an das Ende des freizugebenden Bereichs kopieren, ihre Adresse korrigieren und dann einen entsprechend weiter unten liegenden Bereich freigeben. Diese Aufgaben übernimmt die Routine MEMFR. die von dem Befehl

|WINDOW.OUT,x,y,xd,yd,adr,len

aufgerufen wird. Er blendet den gesicherten Ausschnitt wieder in den Bildschirmspeicher ein.

Jetzt bekommt die Handlung einen Rahmen

Ein gesicherter Ausschnitt macht noch kein Fenster. Schließlich hat eine Benutzeroberfläche etwas mit Benutzerfreundlichkeit zu tun und letzteres etwas mit Ergonomie und dieses wieder mit Design. Zu Deutsch: Unsere Windows sollen schöner werden.

Dieses Aussehen erledigt der Befehl

|WINDOW.DRAW,x,y,xd,yd.

Er löscht den angegebenen Bereich des Bildschirms und zeichnet einen Rahmen und einen Schatten drumherum.

Ach ja, der Schatten. Der ist sowieso ein Thema für sich. Der CEUS-Schatten verhält sich in unterschiedlichen Modi natürlich auch unterschiedlich. In Mode 2 wird er einfach durch eine Zeile und eine Spalte invertierter Zeichen links unterhalb des Fensters dargestellt. Im Mode l hingegen verändert er die Farben der Bildpunkte, die in seinem Bereich liegen, nach dem Schema PEN 0 wird zu PEN 2, PEN 1 bleibt und PEN 2 und 3 werden zu PEN 1. Bei einer Farbverteilung wie 0 weiß, 1 schwarz und 2 grau oder 0 gelb, 1 rot und 2 orange (3 jeweils beliebig) ergibt sich so ein durchaus realistischer Schatteneffekt. Was im Mode 0 geschieht, wissen wir auch nicht so genau (vergleiche Bemerkung über Windows im Mode 0); es ergibt sich ein Schatteneffekt ähnlich dem im Mode 1, aber nach welchen Regeln...?

Licht und Schatten

Die Realisierung dieses Effektes ist eine ziemliche Bit-Schieberei über mehrere Masken, deren Erklärung im einzelnen zu viel Platz brauchen würde, wir können daher nur auf das Assemblerlisting verweisen. Falls jemandem dieser wundervolle Schatten nicht gefallen sollte, kann er ihn natürlich auch abschalten mit |SHADOW.OFF, bzw. wieder einschalten mit |SHADOW.ON, dies muß aber selbstverständlich vor der Darstellung geschehen. Die Parameter für |WINDOW.DRAW müssen übrigens so gewählt werden, daß der gesamte Fensterinhalt zwischen den Koordinaten 2/2 und 79(39,19)/24 liegt, da immer (auch ohne Schatten) auf jeder Seite des Windows ein Zeichen für den Rahmen benötigt wird.

Viele Kleine ergeben ein Großes

Nachdem jetzt sämtliche Befehle zur Verfügung stehen, mit denen man EIN Fenster auf dem Bildschirm eröffnen und verwalten kann, fehlt jetzt nur noch ein Befehl, der dies umfassend, allgemein und für MEHRERE Windows erledigt. Für diesen Zweck gibt es die Befehle

|WINDOW.OPEN,num,x1,y1 ,x2,y2 und

|WINDOW.CLOSE.

|WINDOW.OPEN eröffnet ein Window. weist ihm die Betriebssystemnummer num (von 0-7) zu, rettet den Hintergrund, trägt es in eine Tabelle ein und stellt es auf dem Bildschirm dar; |WINDOW.CLOSE entfernt es vom Bildschirm und aus der Tabelle und gibt seinen Speicher wieder frei. Die Windownummer entspricht dabei den jeweiligen BASIC-Nummern, das heißt, das Fenster kann mit 'PRINT #num' beschrieben werden. Damit diese Funktionen ausgeführt werden können, müssen einige Parameter zwischengespeichert werden. Da wären zum einen natürlich die Koordinaten - woher soll der Befehl sonst wissen, welchen Bereich er freigeben soll? - dann der belegte Speicher, die Nummer des Windows und die Position des Windows in der Tabelle - denn es kann ja immernur das oberste Fenster geschlossen werden, sonst werden eventuell dar-überliegende Fenster zerstört. |WINDOW.OPEN speichert nun alle diese Werte in entsprechenden Tabellen ab, und |WINDOW.CLOSE braucht sie danach nur auszulesen und die Tabelle zu korrigieren (die Tabellen sind jeweils neun Einträge lang, obwohl nur acht Fenster eröffnet werden können; das erleichtert die Verwaltung und hält einen Platz als Koordinatenzwischenspeicher frei - er wird später noch gebraucht).

Übrigens: Sämtliche RSX-Befehle sind mit einer Parameterkontrolle ausgerüstet, die im Fehlerfall die richtige Systemmeldung ('lmproper argument' oder 'Operand missing') auslöst (vergleiche 1. Folge).

Beim nächsten Mal...

Das wär's dann erst einmal für diese Folge. Im nächsten Heft kommen dann einige nette Zusätze für den Window-Manager auf Sie zu, mit denen man Windows einen Namen geben, sie verstecken oder unter anderen Fenstern hervorholen kann. Wer es bis dahin nicht aushält, der kann sich ja des Speicherplatzproblems annehmen. Neben den oben genannten Lösungsansätzen gibt es ja auch noch einen Kompressor für die Daten.

Der müßte dann allerdings irgendwie schon vorher wissen, wie lang das Komprimat wird; denn wieviel Speicher soll sonst abgezwackt werden?

Man könnte ihn dazu einfach zweimal ablaufen lassen, wenn das nur nicht s viel Zeit kosten würde... Also, dies Aufgabe ist mit Sicherheit anspruchs voller als die Verlegung der Ausschnitte in die zweiten 64 kByte des 6128 aber unlösbar? Bestimmt nicht!

Jörg Schwieder/jf, CPCAI

★ PUBLISHER: CPC Amstrad International
★ YEARE: 1989 , 1990
★ CONFIG: 64K + AMSDOS
★ LANGUAGE:
★ LiCENCE: ???
★ COLLECTION: CPC AMSTRAD INTERNATIONAL 1990
★ AUTHOR: Joerg Schwieder

 

Page précédente : Benutzeroberflaeche CEUS v1.0 - Teil 1 : Grundlagen der grafischen Benutzeroberflächen
★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
» RSX-CEUS  v1-SOURCEPACK    GERMANDATE: 2020-04-18
DL: 678
TYPE: ZIP
SiZE: 20Ko
NOTE:
.HFE: Χ

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Applications » Ultra-Basic v2
» Applications » RSX - Amsdoc ROM
» Applications » Instant Access
» Applications » RSX-Druck (CPC Amstrad International)
» Applications » Rsx - Fast Screen (CPC Amstrad International)
» Applications » RSX Turbo-Tape (Schneider Aktiv)
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 698 millisecondes et consultée 871 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.