Kapitel 8 - Das Photon microGUI® Windowing System
Das Photon microGUI Windowing System
Dieses Kapitel beinhaltet die folgenden Themen:
- Ein grafischer Mikrokernel
- Der Photon Ereignisraum
- Grafiktreiber
- Skalierbare Fonts
- Mehrsprachige Unterstützung durch Unicode
- Animationsunterstützung
- Druck-Unterstützung
- Der Photon Fenster-Manager
- Widget-Bibliothek
- Zusammenfassung
Ein grafischer Mikrokernel
Viele embedded Systeme benötigen für die Interaktion mit der Applikation ein UI. Für komplexe Applikationen oder für maximale Benutzerfreundlichkeit ist ein grafisches Fenstersystem eine logische Wahl. Wie auch immer, die Fenstersysteme auf Desktop PCs benötigen einfach zu viel Systemressourcen, um in embedded Systemen, wo Speicher und Ressourcen limitiert sind, praktikabel zu sein.
Bezugnehmend auf die erfolgreiche Annäherung der QNX Mikrokernelarchitektur an eine POSIX OS Umgebung für embedded Systeme, haben wir diesen Kurs in der Entwicklung des Photon microGUI Windowing Systems fortgesetzt.
Um ein Mikrokernel OS erfolgreich zu implementieren, mussten wir zuerst den Mikrokernel so weit optimieren, daß die Kernelaufrufe für IPC so klein und effizient wie möglich wurden (da die Performance des gesamten OS auf der nachrichtenbasierenden IPC beruht). Nachdem diese hochoptimierte IPC implementiert war, waren wir in der Lage, eine GUI als einen grafischen ``Mikrokernel'' Prozeß zu strukturieren mit einem Team von kooperierenden Prozessen um ihn herum, welche diese IPC benutzen.
Obwohl es auf den ersten Blick ähnlich aussieht wie der Bau eines grafischen Systems um eine klassische Client/Server-Architektur, wie es bereits durch das X Window System genutzt wird, unterscheidet sich die Architektur von Photon jedoch durch eine Restriktion der implementierten Funktionalitäten innerhalb des grafischen Mikrokernels (oder Server) und durch die Distribution der GUI Funktionalitäten an die kooperierenden Prozesse.
Der Photon Mikrokernel läuft als winziger Prozeß (45K Code) mit nur ein paar fundamentalen Funktionen, welche externe optionale Prozesse benutzen, um eine high-level Funktionalität eines Fenstersystems zu bieten. Ironischerweise existiert für den Photon Mikrokernel selber kein ``Windows''. Der Photon Mikrokernel kann weder irgendetwas ``zeichnen'', noch einen Stift, eine Maus oder eine Tatstatur verwalten.
Um eine GUI Umgebung zu managen, erzeugt Photon einen drei-dimensionalen Ereignisraum, im folgenden ``Event Space'' genannt. Er beschränkt sich selbst nur auf das Verwalten von Regionen und die Verarbeitung und Lenkung der unterschiedlichen Ereignisse, die sich durch diesen Raum bewegen.
Diese Abstraktion ist sehr ähnlich dem Konzept eines Mikrokernel Betriebssystems, welches selbst unfähig ist, Dateisysteme oder Geräte zu bedienen, statt dessen aber auf externe Prozesse vertraut, um diese high-level Dienste bereitzustellen. Genau wie dieses einem Mikrokernel Betriebssystem erlaubt, seine Größe und Funktionalität zu skalieren, so erlaubt es auch einer Mikrokernel GUI sich so zu verhalten.
Die Abstraktion eines Kernel implementiert durch den Photon Mikrokernel ist die eines abstrakten, grafischen Event Space (Ereignisraum), welcher durch andere Prozesse mit regions (Regionen) bevölkert werden kann. Durch die Benutzung der IPC von QNX, um mit dem Photon Mikrokernel zu kommunizieren, manipulieren diese anderen Prozesse ihre Regionen, um einen höherwertigen oder aufwendigeren grafischen Service bereitzustellen. Durch Entfernen der Prozesse, welche Dienste bereitstellen, kann Photon auf Systeme herunter skaliert werden, die stark limitierte Ressourcen haben; durch Hinzufügen solcher Prozesse, kann Photon bis zu voller Desktop Funktionalität heraufskaliert werden.
Der Photon Event Space
Der durch den Photon Mikrokernel verwaltete ``Event Space'' kann als leere Hülle mit einer ``Root Region'' im Hintergrund betrachtet werden. Den Endbenutzer kann man sich als in diesen Event Space ``hineinschauend'' vorstellen. Applikationen plazieren ``Regionen'' in den drei-dimensionalen Raum zwischen der Root-Region und dem Endbenutzer; sie benutzen diese Regionen, um verschiedene Typen von ``Ereignissen (Events)'' in diesem Raum zu generieren, zu akzeptieren oder zu konsumieren.
Prozesse, die Gerätetreiber-Dienste bereitstellen, plazieren Regionen im Vordergrund des Event Spaces. In Anlehnung an die Verwaltung des Event Space und der Root-Region pflegt der Photon Mikrokernel einen Mahl-Zeiger, projeziert als Zeichenereignisse in Richtung Betrachter.
Photon benutzt eine Reihe von Regionen, beginnend bei der Root- Region im Hintergrund des Photon Event Space bis zu der grafischen Region im Vordergrund. Zeichenereignisse beginnen in der Region einer Applikation und bewegen sich vorwärts in Richtung grafische Region. Eingabeereignisse starten in der Region des Zeigers, bzw. der der Tastatur und reisen in Richtung Root-Region.
Wir können uns diese Ereignisse, die durch diesen Raum reisen, als ``Photone'' vorstellen (woher dieses Fenstersystem seinen Namen hat). Ereignisse selbst bestehen aus einer Liste von Rechtecken mit einigen anhängenden Daten. Während diese Ereignisse durch den Event Space fliegen, schneiden ihre Rechtecklisten die dort durch verschiedene Prozesse (Applikationen) plazierten ``Regionen''.
Ereignisse, die von der Root-Region des Event Spaces aus reisen, werden als auswärts reisend bezeichnet (oder dem Benutzer entgegen), während Ereignisse von dem Benutzer als inwärts, der Root-Region im Hintergrund des Event Spaces entgegen reisend, bezeichnet werden.
Die Interaktion zwischen Ereignissen und Regionen bildet die Basis für die Ein- und Ausgabe in Photon. Zeiger-, Maus- und Tastatur-Ereignisse reisen von dem Benutzer in Richtung Root-Ebene, mit dem Standort des ihnen zugeordneten On-Screen Zeigers. Zeichen-Ereignisse entstehen aus Regionen und reisen der Geräte Ebene und dem Benutzer entgegen.
Regionen
Regionen werden in einer hierarchischen Familie aus Rechtecken, welche ihren Standort in dem drei-dimensionalen Event Space definieren, verwaltet. Eine Region hat zusätzliche Attribute, welche definieren, wie sie mit verschiedenen Ereignisklassen interagiert, wenn diese die Region durchkreuzen. Die Interaktionen, welche eine Region mit Ereignissen haben kann, werden durch zwei Bitmasken definiert:
- sensitiv-Bitmaske
- Durchlässigkeit (opaque)-Bitmaske.
Die sensitiv-Bitmaske benutzt spezifische Ereignistypen, um zu definieren, über welche Schnittpunkte der Prozeß, dem die Region gehört, informiert werden will. Ein Bit in der sensitive-Bitmaske definiert, ob die Region sensitiv fü ein Ereignis dieses Typs ist oder nicht. Sobald ein Ereignis eine Region kreuzt, bei der das Bit für dieses Ereignis gesetzt ist, wird eine Kopie des Ereignisses in die Warteschlange des Applikationsprozesses gestellt, dem die Region gehört. Diese Benachrichtigung modifiziert das Ereignis nicht.
Die Durchlässigkeits-Bitmaske (im folgenden opaque-Bitmaske genannt) wird benutzt, um zu definieren, bei welchen Ereignissen die Region durchsichtig ist. Für jeden Ereignistyp wird in der Opaque-Maske ein Bit gesetzt, welches definiert, ob die Region für dieses Ereignis undurchlässig oder transparent ist. Die ``optische Undurchlässigkeit'' für ein Ereignis ist implementiert durch die Modifizierung des Ereignisses selbst, sobald es den Schnittpunkt einer Region passiert.
Diese zwei Bitmasken können kombiniert werden, um ein Variete aus Ereignissen im Event Space zusammenzustellen. Die vier möglichen Kombinationen sind:
Bitmasken Kombination: | Beschreibung: |
---|---|
Nicht sensitiv, transparent | Das Ereignis passiert unmodifiziert die Region, ohne daß der Eigentümer der Region benachrichtigt wird. Der Prozeß, dem die Region gehört, ist einfach nicht an dem Ereignis interessiert. |
Nicht sensitiv, undurchsichtig | Das Ereignis wird an die Region ``geheftet'', sobald es die Region passiert; der Besitzer der Region wird nicht benachrichtigt. Beispielsweise würden die meisten Applikationen diese Attributkombination für Zeichenereignisse nutzen, so daß ein Applikationsfenster nicht durch Zeichenereignisse aus darunterliegenden Fenstern überschrieben wird. |
Sensitiv, transparent | Eine Kopie des Ereignisses wird an den Eigentümer der Region geschickt; das Ereignis setzt sich unmodifiziert durch den Event Space fort. Ein Prozeß, der die Flüge von Ereignissen mitschreiben möchte, könnte diese Kombination benutzen. |
Sensitiv, undurchsichtig | Eine Kopie des Ereignisses wird an den Besitzer der Region geschickt; das Ereignis wird außerdem an die Region geheftet, sobald es sie passiert. Durch das Setzen dieser Bitmaskenkombination kann eine Applikation wie ein Ereignisfilter oder Übersetzer arbeiten. Die Applikation kann jedes erhaltene Ereignis verarbeiten und es, in willkürlicher Art und Weise umgewandelt, möglicherweise in eine neue Richtung reisend und vielleicht durch eine neue Koordinate im Event Space verändert, regenerieren. Eine Region kann zum Beispiel Stiftereignisse absorbieren, auf diese Ereignisse Handschriftenerkennung durchführen und dann die equivalenten Tastaturereignisse generieren. |
Ereignisse (Events)
Wie Regionen kommen auch Ereignisse in verschiedenen Klassen vor und haben unterschiedliche Attribute. Ein Ereignis wird definiert durch:
- die hervorbringende Region
- einen Typ
- eine Richtung
- eine anhängende Liste aus Rechtecken
- einige ereignisspezifische Daten (optional).
Im Gegensatz zu den meisten Fenstersystemen klassifiziert Photon beides, Eingabe (Stift, Maus, Tastatur, etc.) und Ausgabe (Zeichen Anfragen), als Ereignisse. Ereignisse können sowohl durch die Regionen, die die Prozesse im Event Space plaziert haben, als auch durch den Photon Mikrokernel selber generiert werden. Ereignistypen werden definiert für:
- Tastatureingaben
- Stift und Mausklick Aktionen
- Stift und Maus Bewegung
- Kreuzungen von Regionsgrenzen
- sichtbare und verdeckte Ereignisse
- Zeichen-Ereignisse
- Ziehen und Ablegen.
Applikationsprozesse können entweder nach diesen Ereignissen fragen, blockieren und auf ihr Erscheinen warten, oder asynchron über ein anstehendes Ereignis informiert werden.
Die an das Ereignis angeheftete Rechteckliste kann eine oder mehrere rechteckicke Regionen beschreiben oder sie kann eine ``Punkt-Quelle'' sein - ein einziges Rechteck, bei dem die obere linke Ecke der unteren rechten Ecke entspricht.
Sobald ein Ereignis eine undurchsichtige Region kreuzt, wird das Rechteck der Region aus der Rechteckliste des Ereignisses ``ausgeschnitten'', so daß die Liste lediglich den Teil des Ereignisses beschreibt, der ultimativ sichtbar wäre.
Der beste Weg, darzustellen, wie dieses Ausschneiden (im folgenden ``clipping'' genannt) durchgeführt wird, ist, die Änderungen in der Rechteckliste eines Zeichenereignisses zu untersuchen, während es durch verschiedene sich kreuzende Regionen reist. Wenn das Zeichenereignis das erste Mal erzeugt wird, besteht die Rechteckliste lediglich aus einem einzigen, einfachen Rechteck, welches die Region, aus der das Ereignis entstanden ist, beschreibt.
Wenn das Ereignis durch eine Region kommt, welche die obere linke Ecke aus dem Zeichenereignis clipped, wird die Rechteckliste so modifiziert, daß sie nur die zwei Rechtecke enthält, welche den verbleibenden zu zeichnenden Raum definieren. Diese verbleibenden Rechtecke nennt man "Tiles (Kacheln)."
Ebenfalls wird jedesmal, wenn das Zeichenereignis eine für Zeichenereignisse undurchsichtige Region kreuzt, die Rechteckliste so modifiziert, daß sie das repräsentiert, was von dem Zeichenereignis sichtbar bleibt, nachdem die undurchsichtige Region wieder ``herausgeschnitten'' wurde. Zu guter Letzt wird die Rechteckliste, sobald sie auf einen Grafiktreiber trifft, ganz präzise nur noch den Teil des Zeichenereignisses definieren, welcher sichtbar ist.
Für Zeichenereignisse undurchsichtige Regionen werden ausgeschnitten; mit einem Bereich als Ergebnis, der aus rechteckigen Teilen besteht.
Wenn das Ereignis völlig aus dem Schnittpunkt einer Region herausgeschnitten ist, wird das Zeichenereignis aufhören zu existieren. Dieser Mechanismus von ``undurchsichtigen'' Fenstern, welcher die Rechteckliste eines Zeichenereignisses modifiziert, ist der gleiche, wie er für die Anzeige benutzt wird, um Zeichenereignisse einer tiefer liegenden Region (und ihrer zugehörigen Prozesse), in Richtung Betrachter reisen zu lassen.
Grafiktreiber
Grafiktreiber werden als Prozesse implementiert, die eine Region im Vordergrund des Event Spaces plazieren. Statt für Stift-, Maus- oder Tastatur-Ereignisse ist eine Grafiktreiber-Region sensitiv für Zeichenereignisse, welche aus dem Event Space kommen. Sobald Zeichenereignisse die Region schneiden, werden diese von dem Grafiktreiber Prozeß empfangen. In Folge dessen kann man sich die Region so vorstellen, daß sie mit ``Phosphor,'' überzogen ist, welcher durch den Aufprall von ``Photonen'' illuminiert wird.
Da Photon Zeichenkommandos zu Stapeln akkumuliert, welche als einzelne Zeichenereignisse ausgesand werden, enthält jedes vom Treiber erhaltene Zeichenereignis eine Liste individueller grafischer Befehle für die Wiedergabe. Nach einiger Zeit werden sich die Rechtecke der ``Clipping-Liste'' überschneiden und exakt beschreiben, welche Teilbereiche der Zeichenliste auf dem Bildschirm dargestellt werden sollen. Die Aufgabe des Treibers ist es, diese angeheftete Liste in eine visuelle Wiedergabe auf der von ihm kontrollierten Grafikhardware zu transformieren.
Ein Vorteil des Auslieferns einer ``Clipping-Liste'' an den Treiber ist, daß jede Zeichenanfrage einen signifikanten ``Stapel'' an Arbeiten repräsentiert. Da die Grafikhardware immer leistungsfähiger wird, können immer mehr dieser ``Arbeitstapel'' direkt an die Grafikhardware übergeben werden. Viele Chips für Bildschirmcontroller verarbeiten ein einzelnes Clipping-Rechteck; einige verarbeiten bereits mehrere Rechtecke.
Obwohl der Gebrauch von QNX IPC, um Zeichenanfragen von der Applikation zum Grafiktreiber zu senden, als ein unakzeptabler Aufwand erscheinen mag, demonstriert unsere Durchsatzmessung, daß diese Implementation eine genauso gute Performance bietet, als ob die Applikation ihre Aufrufe direkt in den Grafiktreiber schickt. Ein Grund für solchen Durchsatz ist der, daß eine Vielzahl von Zeichenaufrufen mit dem Ereignismechanismus gestapelt werden können. Der sowieso schon minimale Aufwand des leichtgewichtigen IPC von QNX erlaubt es, sich über viele Zeichenaufrufe zu amortisieren.
Vielzählige Grafiktreiber
Da Grafiktreiber einfach eine Region in den Photon Event Space legen und diese Region ein Rechteck beschreibt, welches von Zeichenereignissen geschnitten werden kann, ist es folglich klar, daß mehrere Grafiktreiber für mehrere Grafikkontrollerkarten, jeder präsent mit seiner zeichenereignissensitiven Region im gleichen Event Space, eingesetzt werden können.
Diese Vielzahl von Regionen könnten aneinander angrenzend plaziert werden und einen Bereich von ``beschreibbaren Kacheln'' darstellen oder sich in unterschiedlichen Arten überlappen. Da Photon Netzwerktransparenz von QNX erbt, können Photonapplikationen oder Treiber auf jedem Netzwerkknoten laufen und zusätzlichen Grafiktreibern erlauben, den grafischen Raum von Photon auf die physikalischen Bildschirme von vielen vernetzten Computern zu zeigen. Durch das Überlappen der Grafiktreiber-Regionen können die Grafikereignisse auf viele Bildschirme repliziert werden.
Viele interessante Applikationen werden durch diese Fähigkeit möglich. Zum Beispiel kann der Operator einer Fabrik mit einem drahtlosen tragbaren LAN Computer zu einer Arbeitsstation gehen und ein Fenster von einem betriebseigenem Kontrollschirm auf seinen tragbaren Computer öffnen und dann mit dem Kontrollsystem auf dem Betriebsgelände arbeiten.
In anderen Umgebungen könnte ein Embedded System ohne UI einen Bildschirm auf jeden vernetzten Computer projezieren. Diese Art der Verbindung ermöglicht ebenfalls nützliche Arbeitsmodi für Anwender von Computern - eine Gruppe von Leuten könnte simultan den gleichen Applikationsbildschirm sehen und gemeinsam an der Applikation arbeiten.
Aus Sicht der Applikation wirkt dies wie ein einziger, einheitlicher grafischer Raum. Aus der Perspektive des Benutzers, wirkt dies wie eine nahtlos verbundene Zusammenstellung aus Computern, bei denen Fenster von einem physikalischen Bildschirm zu einem anderen über Netzwerkverbindungen gezogen werden können.
Farbmodell
Von dem Grafiktreiber werden Farben durch eine 24-Bit RGB Menge (8 Bit für jeweils rot, grün und blau) verarbeitet. Das Ergebnis ist eine Spanne von 16.777.216 Farben. Abhängig von der aktuellen Bildschirmhardware wird der Treiber entweder die 24-Bit Farben direkt von der darunterliegenden Hardware benutzen oder verschiedene Techniken nutzen, um die gewünschte Farbe von weniger leistungsfähiger Hardware erzeugen zu lassen.
Da die Grafiktreiber eine hardwareunabhängige Farbrepräsentation nutzen, können Applikationen dargestellt werden, ohne daß Hardware mit unterschiedlichen Farbmodellen modifiziert werden muß. Dadurch wird es Applikationen möglich, von Bildschirm zu Bildschirm ``gezogen'' zu werden ohne sich für das Farbmodell der darunter liegenden Hardware interessieren zu müssen.
Skalierbare Schriften
In Anlehnung an die volle Unterstützung von Bitmap Schriften unterstützt Photon auch skalierbare Schriften. Diese Schriften können zu jeder virtuellen Punktgröße skaliert und mit anti-aliasing versehen werden (16 Schattierungen), um eine klare, reine Ausgabe auf dem Bildschirm für praktisch jede Auflösung zu bieten.
Photon's skalierbare Schriften werden von einem Hochgeschwindigkeits-Schriftenserver erzeugt, welcher hochkomprimierte Schriftdaten aus portierbaren Schriftressourcedateien (*.pfr) entnimmt, und dann die Form der Zeichen zu jeder Punktgröße und Auflösung zurückgibt. Beachten Sie, daß PFR-Dateien eine Kompression besser als 2-zu-1 über PostScript-Fonts erreicht.
Schriftsätze
Core Latin Satz
Der Core Latin Satz von Photon (latin1.pfr), welcher die Unicode Basic Latin (U+0000 - U+007F) und die Latin-1 Supplement (U+0080 - U+00FF) Zeichensätze enthält, beinhaltet die folgenden skalierbaren Schriften:
- Dutch
- Dutch Bold
- Dutch Italic
- Dutch Bold Italic
- Swiss
- Swiss Bold
- Swiss Italic
- Swiss Bold Italic
- Courier
- Courier Bold
- Courier Italic
- Courier Bold Italic
Extended Latin Satz
Der Extended Latin Satz von Photon (latinx.pfr) enthält die Unicode Latin Extended-A (U+0100 - U+017F) und Latin Extended-B (U+0180 - U+0217) Sätze. Der Extended Latin Satz beinhaltet diese Schriften:
- Dutch
- Dutch Bold
- Dutch Italic (algorithmisch generiert)
- Dutch Bold Italic (algorithmisch generiert)
- Swiss
- Swiss Bold
- Swiss Italic (algorithmisch generiert)
- Swiss Bold Italic (algorithmisch generiert)
Unterstützte Sprachen
Ausgestattet mit dem Photon Core Latin Satz kann der Entwickler einen Host unterstützen, welcher folgende Sprachen enthält:
Dänisch
Deutsch
Englisch
Finnisch
Französisch
Hawaiianisch
Indonesisch
Irisch
Isländisch
Italienisch
Niederländisch
Norwegisch
Portugiesisch
Schwedisch
Spanisch
Suaheli
Durch das Hinzufügen des Photon Extended Latin Satzes (latinx.pfr) kann der Entwickler weitere Sprachen hinzufügen, wie:
Afrikaans
Baskisch
Esperanto
Estnisch
Grönländisch
Katalanisch
Kroatisch
Lettisch
Litauisch
Maltesisch
Polnisch
Rumänisch
Slowakisch
Tschechisch
Türkisch
Ungarisch
Walisisch
Internationale Sprachergänzungen
Für Photon sind einige Sprachergänzungen verfügbar:
- Japanische Spracherweiterung- bietet Entwicklern volle Unterstützung für japanische Schriftzeichen.
Neben einem kompletten Satz an PFR-Dateien (Hon Mincho Kanji Satz) enthält das Paket auch einen Front-End Prozessor, welcher es Benutzern erlaubt, Eingaben entweder mit einer englischen oder einer japanischen Tastatur zu machen (über die popuäre in Japan genutzte VJE Eingabe Methode).
- Chinesische Spracherweiterung - bietet Entwicklern volle Unterstützung für chinesische Schriftzeichen sowie eine korrespondierende Eingabemethode.
- Koreanische Spracherweiterung - bietet Entwicklern volle Unterstützung für koreanische Schriftzeichen sowie eine korrespondierende Eingabemethode.
- Kyrillischer Sprachsupport - bietet Entwicklern volle Unterstützung für Russisch oder jede andere Sprache, die auf dem kyrillischen Alphabet basiert. Dieses Paket enthält auch die passenden Tastaturtreiber um englische oder kyrillische Tastaturen zu unterstützen.
Mehrsprachige Unterstützung durch Unicode
Photon ist darauf ausgelegt, internationale Schriftzeichen zu verarbeiten. Dem Unicode Standard (ISO/IEC 10646) folgend versorgt Photon Entwickler mit der Möglichkeit, Applikationen zu entwickeln, welche sehr einfach die Hauptsprachen und Schriften der Welt unterstützt.
Unicode wurde auf dem ASCII Zeichensatz modeliert, benutzt aber eine 16-Bit Dekodierung, um multilingualen Text zu unterstützen. Es gibt keinen Bedarf an Escape-Sequenzen oder Kontrollcodes, wenn ein Zeichen in einer Sprache spezifiziert wird. Beachten Sie, daß die Dekodierung von Unicode konventionell alle Zeichen berührt - sowohl Alphabeten, Ideographen, oder Symbole - in exakt der gleichen Weise.
UTF-8 Dekodierung
Früher als UTF-2 bekannt, ist das UTF-8 (für "8-Bit Formen") Transformationsformat designed, um den Gebrauch von Unicode Zeichendaten in 8-Bit UNIX-Umgebungen zu ermöglichen.
Hier einige der Hauptmerkmale von UTF-8:
- Die Unicode Zeichen von U+0000 bis U+007E (ASCII Satz) werden dem UTF-8 Code Bytes 00 bis 7E (ASCII Werte) zugeordnet.
- ASCII Werte erscheinen ansonsten nicht in einer UTF-8 Transformation, sie geben komplette Kompatibilität zu historischen Dateisystemen, welche ASCII Bytes parsen.
- UTF-8 vereinfacht die Konvertierung zu und von Unicode Text.
- Das erste Byte indiziert die Anzahl der in einer Multibyte Sequenz folgenden Bytes, was ein effizientes Vorwärtsparsen erlaubt.
- Das Finden des Anfanges eines Zeichens, ausgehend von einer willkürlichen Stelle innerhalb eines Bytestranges ist effizient, weil Sie höchstens vier Bytes zurück suchen müssen, um ein einfach zu erkennendes Initialbyte zu finden. Zum Beispiel:
isInitialByte = ((byte & 0xC0) != 0x80);
- UTF-8 ist ziemlich kompakt im Vergleich zu der Anzahl der Bytes, die zur Kodierung genutzt werden.
Die Betriebssystem Bibliothek (Watcom 11.0) beinhaltet einen Satz von Umformungsfunktionen:
Funktion | Beschreibung |
---|---|
_itow() | Konvertiert int in Wide (16 Bit/Zeichen) Zeichenstrings |
_ltow() | Konvertiert long int in Wide Zeichenstrings |
mblen() | Länge eines Multibyte Strings in Zeichen |
mbtowc() | Konvertiert Multibyte Zeichen in Wide Zeichen |
mbstowcs() | Konvertiert Multibyte Strings zu Wide Zeichen Strings |
_ultow() | Konvertiert unsigned long int zu Wide Zeichenstrings |
_utow() | Konvertiert unsigned int zu Wide Zeichenstring |
wctomb() | Konvertiert Wide Zeichen zu ihren Multibyterepräsentationen |
wcstod() | Konvertiert Wide Zeichen Strings zu double |
wcstol() | Konvertiert Wide Zeichen Strings zu long int |
wcstombs() | Konvertiert Wide Zeichen Strings zu Multibyte Strings |
wcstoul() | Konvertiert Wide Zeichen Strings zu unsigned long int |
_wtof() | Konvertiert Wide Zeichen Strings zu double |
_wtoi() | Konvertiert Wide Zeichen Strings zu int |
_wtol() | Konvertiert Wide Zeichen Strings zu long int |
In Anlehnung an die oben genannten Konvertierungsfunktionen können Entwickler sich auch der Photon eigenen PxTranslate Bibliotheksfunktionen bedienen, welche verschiedene Zeichensatzkodierungen zu und von UTF-8 beherschen.
Animationsunterstützung
Photon bietet flimmerfreie Animationen über ein spezielles "doppel Puffer" Container Widget (PtDBContainer), welches einen optimierten Speicherkontext zum Zeichnen benutzt.
Das PtDBContainer Widget nutzt einen Block aus Shared Memory, welcher groß genug ist, um ein ganzes Bild darin zu speichern. Wenn nötig, läd es auch die Shared Render Bibliothek.
Druck-Unterstützung
Photon bietet eine eingebaute Druckunterstützung für unterschiedliche Arten von Ausgaben, inklusive:
- Bitmap Dateien
- PostScript
- Hewlett-Packard PCL
- Epson ESC/P2
Photon wird mit einem Druckerauswahl-Dialog zur Einstellung von Druckoptionen ausgeliefert, um das Drucken innerhalb von individuellen Applikationen für Entwickler einfacher zu gestalten.
Der Photon Fenster-Manager
Das Hinzufügen eines Fenster-Managers in Photon erzeugt eine voll funktionierende GUI der Desktopklasse. Der Fenster-Manager ist komplett optional und kann für die meisten Klassen von embedded Systemen weggelassen werden. Ist der Fenster-Manager vorhanden erlaubt er dem Benutzer Applikationsfenster zu bewegen, sie in ihrer Größe zu verändern und sie zu Ikonen zu machen.
Der Fenster-Manager ist auf dem Konzept des Filterns von Ereignissen aufgebaut. Er plaziert Regionen hinter Applikationsregionen, worauf eine Titelzeile, Vergrößerungsflächen und andere ``Fenstersteuerelemente'' gezeichnet und bearbeitet werden. Da der austauschbare Fenster-Manager das aktuelle ``Look and Feel'' der Umgebung implementiert, können verschiedene UI-Varianten optional installiert werden.
Widget-Bibliothek
Photon liefert eine Bibliothek aus Komponenten, welche man als widgets kennt - Objekte, welche das meiste ihres Verhaltens auf dem Bildschirm automatisch verwalten können, ohne expliziten Programmieraufwand. Als Ergebnis kann eine komplette Applikation sehr schnell erstellt werden, indem Widgets in verschiedenen Arten kombiniert werden und dann den entsprechenden Rückruffunktionen der Widgets C Code hinzugefügt wird. Der Photon Application Builder (PhAB), welcher als Teil des Photon Entwicklungssystems enthalten ist, liefert eine extensive Widget-Palette in seiner visuellen Entwicklungsumgebung.
Photon liefert eine große Auswahl solcher Widgets:
- Basis Widgets (z. B. ein Button)
- Container Widgets (z. B. ein Fensterwidget)
- Advanced Widgets (z. B. ein HTML Bildschirmwidget).
Basis Widgets
Label Widget (PtLabel)
Das Label Widget wird hauptsächlich dazu benutzt, Textinformationen darzustellen. Das PtLabel Widget ist die Superklasse für alle textbasierten Widgets und bietet viele einstellbare Attribute (z. B. Zeichen-Schriftbilder, Pop-Up Balloons, Farbe, Rahmen, Ausrichtung, Ränder, etc.), welche alle in ihren Subklassen eingebaut sind.
Push Button Widget (PtButton)
Schaltflächen (Push Buttons) sind eine notwendige Komponente in jedem fensterbasierten System. Sie haben einen drei-D-Effekt, welcher sich ändert, wenn sie gedrückt werden. Sie geben somit einen visuellen Hinweis, um dem Benutzer zu zeigen, daß sie ausgewählt wurden. In Anlehnung an dieses visuelle Verhalten rufen Push Buttons automatisch eine von der Applikation definierte Callback-Funktion auf, wenn sie selektiert sind.
Texteingabe Widgets (PtText, PtMultiText)
Photon bietet zwei Texteingabe Widgets:
- ein einfaches, einzeiliges Eingabe Widget (PtText), welches im Allgemeinen in Formularen benutzt wird
- ein leistungsfähiges, einem Wordprozessor ähnendels Mehrzeilen-Widget (PtMultiText), welches volle Editierbefehle, Wortumbrüche, automatisches Blättern und Multi-Font-Zeilensegmente bietet.
Toggle Button Widgets (PtToggleButton, PtOnOffButton)
Toggle Buttons sind Objekte, die zwei Zustände wiedergeben - entweder an oder aus. Photon unterstützt zwei verschiedene Typen solcher Toggle Buttons, jedes mit einer anderen visuellen Wiedergabe. Sie werden benutzt, um Zustandsinformationen darzustellen oder zu erfragen, bezogen auf eine Aktion, welche ausgeführt werden soll.
Grafische Widgets (PtArc, PtPixel, PtRectangle, PtLine, PtPolygon, PtEllipse, PtBezier, PtGrid)
Photon mangelt es nicht an grafischen Widgets. Es gibt ein Widget, welches einfache Linien und Rechtecke liefert und Widgets die komplexe segmentierte Bezier Kurven darstellen. Grafische Widgets bieten Attribute für Farben, Füllungen, Muster, Strichstärken, Linienverbindungen und vieles mehr.
Scrollbar Widget (PtScrollbar)
Ein Scrollbar Widget wird benutzt, um durch einen sichtbaren Bereich zu blättern. Ein Scrollbar wird mit anderen Widgets kombiniert, um das Blättern zu erlauben, (z. B. PtList, PtScrollArea).
Separator Widget (PtSeparator)
Das Separator Widget wird benutzt, um zwei oder mehrere verschiedene Bereiche zu trennen und somit ein besseres visuelles Erscheinungsbild zu geben. Der Separator kann auf viele verschiedene Stile und Erscheinungen angepaßt werden.
Slider Widget (PtSlider)
Slider unterscheiden sich von Scrollbars. Eine Scrollbar definiert einen Bereich, wohingegen ein Slider einen einzelnen Wert definiert. Das Slider-Widget bietet eine weite Liste von einstellbaren Attributen.
Timer Widget (PtTimer)
Das Timer Widget macht den Gebrauch von Zeitgebern zu einer Kleinigkeit. Dieses Widget hat keine visuelle Erscheinung - es definiert lediglich einen Rückruf, wann immer ein Zeitgeberereignis ausgelöst wird. Die Applikation setzt den Wert des Zeitgebers und optional seinen Wiederholungswert. Sobald der Zeitgeber ausgelöst ist, wird die Applikation benachrichtigt.
Grafische Bilder Widgets (PtBitmap, PtLabel, PtButton)
Photon unterstützt nahezu jeden grafischen Dateistandart, so daß Sie Grafiken importieren und innerhalb von Widgets darstellen können. Viele Photon Widgets unterstützen die Darstellung direkt - die bekanntesten sind PtButton für die Erstellung von Push-Buttons und PtLabel für die Darstellung von Bildern.
Progress Bar Widget (RtProgress)
Wenn eine Applikation etwas tun muß, was einige Zeit in Anspruch nimmt, (z. B. das Laden einer Datei), kann sie das Progress Bar Widget nutzen, um den Benutzer darüber zu informieren, was gerade passiert und, viel wichtiger, wieviel Zeit der Prozeß noch benötigt. Das Progress Bar Widget kann horizontal oder vertikal sein und hat viele Attribute zur Anpassung.
Nachrichten Widget (PtMessage)
Pop-up Nachrichten und Notifikationen sind annähernd gleich in einer Fensterumgebung. Photon liefert ein sehr handliches Nachrichtendialog Widget, welches eine Nachricht und bis zu drei Buttons für die Benutzerreaktion darstellt. Es gibt zusätzlich einen sehr nützlichen modalen Dialog-Funktionsaufruf (PtAskQuestion()), welcher auf dem Nachrichten Widget basiert.
Numerischec Widgets (PtNumericInteger, PtNumericFloat)
Die PtNumericInteger Klasse läßt den Benutzer Integer Werte zwischen gegebenen Minimum- und Maximum-Werten eingeben. Die PtNumericFloat Klasse läßt den Benutzer Fließkomma-Werte eingeben.
Ein PtUpDown Widget wird ebenfalls angezeigt, um dem Benutzer zu erlauben, den gesetzen Wert zu erhöhen oder herabzusetzen.
Container Widgets
Fenster und Icon Widgets (PtWindow, PtIcon)
Fenster sind die Hauptcontainer für Applikationen. Die Haupt UI Komponeneten (Menüs, Symbolleisten, etc.) erscheinen mit dem Fenster Widget. Das Widget behandelt automatisch alle notwendigen Interaktionen mit dem Photon Fenster-Manager (PWM) - alles was Sie spezifizieren müssen ist, was zurückgegeben oder verwaltet werden soll, bzw. was nicht.
Icon Widgets stehen in engem Zusammenhang mit Fenstern und werden in den Photon Desktop Manager Startordnern und der PWM Taskleiste dargestellt.
Bulletin Board Widgets (PtPane)
Bulletin Board Widgets sind einfache Container Widgets, welche dazu genutzt werden, andere Widgets aufzunehmen. Obwohl es sich hierbei um Vater Widgets handelt, verwalten sie ihre Sohn Widgets in keinster Weise. Sie sind sehr nützlich, um Formularlayouts, wie sie allgemein in Dialogfenstern gefunden werden, zu entwerfen.
Gruppen Widget (PtGroup)
Das Gruppen Widget ist ein sehr leistungsfähiges Widget, welches die Geometrien all seiner Söhne verwaltet. Es kann die Widgets horizontal, vertikal oder in einer Matrix anordnen. Das Gruppen Widget kann mit den Seiten jedes anderen Containers verankert werden (wie ein Fenster), so daß es seine Größe automatisch mit dem Fenster ändert. Das Gruppen Widget bietet auch Attribute, welche es Ihnen ermöglichen zu spezifizieren, ob die Söhne so verändert werden sollen, daß sie sich an die Gruppe anpassen.
Scroll Bereich Widget (PtScrollArea)
Das Scroll Bereich Widget ist ein leistungsstarkes Widget, welches einen Blickpunkt in einen potentiell größeren Container bietet. Sie können uneingeschränkt Widgets in einen scrollbaren Bereich legen. Er wird automatisch eine Bildlaufleiste anzeigen, wenn die Widgets nicht innerhalb des sichtbaren Bereiches eingebettet sind. Scroll Bereich Widgets könnten benutzt werden, um einen Betrachter für Textdateien, Wordprozessoren oder spezielle Listen, etc. zu implementieren.
Um Sohn Widgets schnell zu verschieben, benutzt das Scroll Bereich Widget einen Hardware Blitter (vorausgesetzt der darunterliegende Grafiktreiber unterstützt ihn).
Hintergrund Widget (PtBkgd)
Das Hintergrund Widget unterstützt eine Möglichkeit, ausgefallene Hintergrundbilder zu erzeugen, angefangen bei einfachen Farbabstufungen bis hin zu gekachelten Texturen. Fast jede Hintergrundanforderung wird durch dieses Widget verarbeitet.
Advanced Widgets
Menü Widgets (PtMenu, PtMenuBar, PtMenuButton)
Photon liefert für jedes Menü entsprechende Möglichkeiten. Es existiert ein Widget zur Vereinfachung der Erzeugung einer Standard Menüzeile. Das Menü Widget bietet die Pop-Up Darstellung, das Klick-und-Zieh, Anwählen und Klicken, Tastaturnavigation und Selektions-Methode von Menüeinträgen. Das Menübutton Widget wird benutzt, um individuelle Menüeinträge zu erzeugen.
Listen Widget (PtList)
Das Listen Widget ist ein sehr leistungsstarkes Widget, welches eine Liste von Einträgen verwaltet. Es liefert viele verschiedene Auswahlmodi, inklusive Einzelselektion, Mehrfachauswahl und eingeschränkter Auswahl. Das Listen Widget unterstützt auch mehrspaltige Listen, indem es ein Teiler Widget benutzt (PtDivider).
Pulldown Listen Widget (PtComboBox)
Das Pulldown Listen Widget kombiniert das PtText Widget (für Texteingaben) mit einem Pulldown Button für die Darstellung eines Listen Widgets. Wenn der Benutzer aus dieser Liste etwas auswählt, wird das Text Widget automatisch mit der momentanen Auswahl aktualisiert. Das Pulldown Listen Widget ist sehr nützlich für die Darstellung einer Liste mit Einträgen, wenn nur ein kleiner Raum zu Verfügung steht. Dialoge und Container in Embedded Systemen sind typische Kandidaten hierfür.
Baum Widget (PtTree)
Das Baum Widget ist dem Listen Widget ähnlich - tatsächlich haben sie den gleichen Ursprung. Der Hauptunterschied ist der, daß das Baum Widget die Einträge in hierarchischer Anordnung darstellt. Einträge, Zweige genannt, können expandiert oder zusammengefaßt werden. Die Anzahl solcher Zweige ist nicht eingeschränkt. Jeder Zweig kann sein eigenes darzustellendes Bild definieren. Bäume sind deshalb nützlich, da sie Informationen in einer sehr logischen Art und Weise darstellen.
Photon Applikationen, die das Baum Widget eingebaut haben: der Dateimanager (Darstellung von Verzeichnissen), PhAB (Widget Gestaltung), vsin (Prozeß-Liste), und viele mehr.
Terminal Widgets (PtTty, PtTerminal)
Stellen Sie sich vor, Sie haben eine Textkonsole in Ihrer Applikation. Das ist genau das, was dieses Widget macht. Es erzeugt und verwaltet ein vollständiges textbasiertes Terminal innerhalb eines Widgets. Legen Sie es einfach in Ihre Applikation und schon haben Sie Ihr ganz eigenes pterm erzeugt (unsere Terminal-Applikation).
Das Terminal Widget hört hier aber nicht auf - es liefert zusätzlich eine komplette Cut-and-Paste Funktionalität sowie eine Schnellhilfe, indem jedweder Text innerhalb des Widgets hervorgehoben wird.
Teiler Widget (PtDivider)
Dieses leistungsstarke Widget verwaltet seine Söhne in einer einzigartigen und nützlichen Art und Weise. Wenn Sie zwei oder mehrere Widgets in ein Teiler Widget legen, setzt es automatisch kleine Separatoren zwischen die Sohn-Widgets. Der Benutzer kann durch hin- und zurückziehen des Separators das Sohn-Widget dazu bringen, auf jeder Seite des Separators die Größe anzupassen. Für die Erzeugung von größenveränderbaren Spaltenüberschriften in Listen ist das sehr nützlich. Es ist tatsächlich so, daß Sie automatisch Ihre einfache Liste in eine vergrößerbare Liste mit vielen Spalten umwandeln, wenn Sie ein Teiler Widget in ein Listen Widget legen.
Teiler sind aber nicht nur auf Beschriftungen oder Buttons beschränkt. Jedes Widgets kann hineingelegt werden, um vergrößerbare Bäume, Scroll Bereiche, etc. Seite an Seite zu erzeugen.
Trendkurven Widget (RtTrend)
Echtzeitsysteme benötigen oftmals Trendkurven. Photon wird mit einem Trendkurven Widget ausgeliefert, welches die simultane Darstellung vieler Trendkurven gleichzeitig unterstützt. Wenn Ihre Grafikhardware maskierte Blits unterstützt, kann es daneben auch den Trend über Gitterlinien fließend laufen lassen.
Echtzeit Meß Widget (RtMeter)
Das RtMeter Widget wird als Halbkreis mit Winkeln von 1/3, 1/2, und 2/3 dargestellt. Die Nadel kann mit der Maus, über die Tastatur oder durch das Programm bewegt werden. Ein einfacher Mausklick kann den Messer zu der aktuellen Mausposition bewegen. Das "ziehen" der Maus veranlaßt die Nadel, der Maus über die Messwerte zu folgen.
Schriftauswahl Dialog (PtFontSel)
Um die große Auswahl an für Photon verfügbare Schriften anzupassen, wird ein Schriftauswahl Widget angeboten. Dieses Widget kann die Dateien mit den Standartschriftarten lesen und eine Liste aller verfügbaren Schriften anzeigen. Es läßt Sie den Schriftsatz und den Stil (Fett, Kursiv, etc.) wählen und zusätzlich angeben, ob die Schriftart anti-aliased sein soll.
Dateiauswahl Widget (PtFileSel)
Das PtFileSel Widget ist ein Baum Widget, welches Dateien, Verzeichnisse, Verweise auf Dateien oder Verzeichnisse oder sonstige Einträge anzeigt. Neben der Auswahl einer einzelnen Datei durch eine Applikation können Benutzer dieses Widget auch nutzen, um durch ein vollständiges Dateisystem zu navigieren, um ihre eigenen Dateien und Verzeichnisse auszuwählen.
Drucker Auswahl Dialog (PtPrintSel)
Das PtPrintSel Widget läßt einen Benutzer einen Drucker auswählen oder seine Einstellungen kontrollieren. Der Benutzer kann zusätzlich einen bestimmten Druckbereich (z. B. Seite 2-7) sowie die Anzahl der zu druckenden Kopien festlegen.
HTML Anzeige Widget (PtHtml)
Der Gebrauch des HTML Widgets macht es leicht, eine angepaßte Anzeige für Hilfetexte zu erzeugen. Er formatiert eine Standard-HTML Datei und läd automatisch alle enthaltenen Bilder. Er kann die Größe verändern, Blättern, einfach alles was Sie benötigen. Dieses Widget ist ideal, um Anzeigen für Hilfetexte zum Einsatz in Touchscreen-Umgebungen zu erzeugen.
Widget Design-Werkzeug
Sollten Ihnen all die Standard Photon Widgets nicht ausreichen, können Sie einfach Ihre eigenen bauen! Im Lieferumfang des Photon Entwicklungssystems ist eine komplette Dokumentation sowie Beispielsourcecode enthalten, um Ihre eigenen Widgets zu erzeugen. Sie können aus bestehenden Widgets Sub-Klassen erzeugen, um ihre Funktionalität zu übernehmen oder einen komplett neuen Widget Klassen Baum erzeugen. Ihre Widget Möglichkeiten sind endlos.
Zusammenfassung
Photon geht einen völlig neuen Weg bei der Erzeugung einer GUI - es benutzt, im Gegensatz zu anderen monolithischen Fenstersystemen, einen Mikrokernel und ein Team aus kooperierenden Prozessen. Als Ergebnis liefert Photon eine einmalige Leistungsklasse einer GUI:
- Bei knappen Speicherressourcen bietet Photon einen hohen Grad an Fensterfunktionalität in Umgebungen, in denen sonst nur eine kleine Grafikbibliothek Platz hätte.
- Photon bietet eine sehr flexible, durch den Benutzer ausbaufähige und skalierbare Architektur, die es Entwicklern ermöglicht, die GUI an ihre eigenen Applikationen anzupassen.
- Durch die flexible Anbindung verschiedener Plattformen können Photon Applikationen von jeder virtuell verbundenen Bildschirmumgebung genutzt werden.