Software developers for embedded devices have just now begun to discover the power of developing and running their software on GNU/Linux.
As graphical environments on embedded devices have also become a crucial point for any kind of application it is majorly important to use a stable and flexible graphics system for this purpose.
Therefore, this paper makes the far-reaching attempt at explaining, describing and elaborating on Nano-X, THE free and OpenSource graphical windowing environment of choice for smaller devices.
Unfortunately, up to this point, material concerning good and complete introductions to the Nano-X API is rarely to be found. With this paper a resourceful piece of collected and easy-to-understand compact knowledge base has been compiled for practical or any other kind of use.
As this paper has been intentionally written to be used within the frames of software development for analytical gadgets, a concrete device, that is the Open Frame Smart Panel (OFSP) from Ultratronik, is taken under scrutiny and shown to be a viable device for the tasks at hand.
Furthermore, some additionally relevant topics concerning Unix (especially serial port communication) are also discussed in some detail.
Inhaltsverzeichnis
Einleitung
1 Grundlegendes
1.1 Software und Analysetechnik
1.2 Problemstellung
2 Hardware
2.1 OFSP — Open Frame Smart Panel
3 Betriebssoftware
3.1 EmbeddedSystems
3.2 Windows CE TM
3.3 Ultratronik Linux Distribution
3.4 XWindow Systeme
3.5 CrossCompiler
4 NanoX — Die schlanke XWindow Variante
4.1 Gesamtüberblick
4.2 Lizenz und Bedingungen
4.3 Einrichtung des Systems
4.4 Einführung in die NanoX Programmierbibliothek
4.4.1 Fenster
4.4.2 Graphische Kontexte
4.4.3 Ereignisse
4.4.3.1 Ereignistypen
4.4.3.2 Ereignisverarbeitung
4.4.3.3 Ereignisorientierte Anwendungsprogrammierung
4.5 Der NanoX Server
4.6 NanoX API und Microwindows API
4.6.1 Kernkonzepte im Vergleich
4.6.2 NanoX API oder Microwindows API — Ein Fazit
4.7 State Saver — Visueller Zustandsspeicher
4.7.1 Verwendung
4.7.2 Funktionsweise
4.7.3 Kompilierungshinweise
4.8 dkbd — Eine virtuelle Tastatur für das OFSP
4.8.1 Anwendungskonzeption
4.8.2 Programmiertechnische Umsetzung
4.8.2.1 Abstrakt
4.8.2.2 Grundlegender Code
4.8.2.3 Ereignisverarbeitender Code
4.9 Die TinyWidgets Bibliothek
4.9.1.4 Grundlegendes
4.9.1.5 Grundlegende Verwendung
5 Zusammenfassung
6 Ausblick
A Anhang I
A.1 Linux Serialschnittstellenkommunikation
A.1.1 Grundlegendes
A.1.2 Überprüfung der Schnittstellenfunktionalität
A.1.3 Programmierung
B Anhang II
B.1 NanoX Kurzreferenz
B.1.1 Fenstereigenschaften
B.1.2 Ereignisstrukturen und Ereignistypen
B.1.3 NanoX Zeichenroutinen
C Anhang III
C.1 Quelltext der virtuellen Tastatur „dkbd“
C.1.1.1 QuelltextDatei dkbd.h
C.1.1.2 QuelltextDatei dkbd.c
C.1.1.3 QuelltextDatei stuff.c
C.2 Der Zustandsspeichers „state saver“
C.2.1 Hinweise zur Verwendung
C.2.1.1 Package description
C.2.1.2 Package use
C.2.2 Quelltext einer Beispielanwendung
C.2.3 Quelltext des Zustandsspeichers
C.3 Quelltext eines einfachen NanoX Ladebalkens
C.3.1 HeaderDatei sbar.h
C.3.2 QuelltextDatei sbar.c
C.4 Quelltext der TinyWidgets und SerialportTestanwendung
Glossar
Literatur
Quellen
Abbildungsverzeichnis
Tabellenverzeichnis
Rechtliche Hinweise
Eidesstattliche Erklärung
Danksagung
Vorwort
Aufgrund des Vorhabens, dem Leser einen möglichst leichten Textfluss zu ermöglichen, sind bestimmte verwendete Begriffe und spezielle Terminologien im Glossar am Ende dieser Arbeit verzeichnet und erläutert. Im Glossar aufzufindende Einträge sind bei ih rem ersten Auftreten im Text punktiert unterstrichen.
Es sei weiterhin darauf hingewiesen, dass der Leser dieser Arbeit grundlegende Kenntnisse des GNU/LinuxSystems sowie der Bedienung der interaktiven UnixShell besitzen sollte, dennoch für alles Weitere kein spezielles Vorwissen notwendig ist. Wich tige weiterführende Unixrelevante Konzepte werden weitestgehend beschrieben und – soweit es der Rahmen dieser Arbeit zulässt – ausgeführt.
Einleitung
In der Softwareentwicklung stellt jeder Schritt einer Neu bzw. Umorientierung auf al ternative Entwicklungstechniken und werkzeuge einen wohl überlegten Eingriff in die Produktivität eines Unternehmens dar.
Dabei besteht die Unsicherheit, die richtige Entscheidung getroffen zu haben. Zum einen ist ein erheblicher Arbeitszeitaufwand notwendig, die entsprechenden Fähig und Fertigkeiten zu erwerben, die für professionelle Produktentwicklungen notwendig sind, zum anderen bleibt zunächst der Aufwand ungerechtfertigt, bis sich ein effektiver Nut zen nach einer längerfristigen Zeitperiode abzeichnen kann, dessen Eintreten nicht vor hersehbar ist.
Trotz eines in der letzten Zeit stark zugenommenen Herantastens vieler Unternehmen an OpenSourceLösungen als Alternativen zu ihren bisherigen Herangehensweisen, ist hier die Vorsicht besonders groß und aus stereotypisierender Sicht auch gerechtfertigt.
Wie oftmals missverstanden, ist die Verwendung oder gar Entwicklung von kom merzieller OpenSourceSoftware nicht gleichbedeutend mit der bedingungs und wil lenlosen Übergabe von kostspieligen Neuentwicklungen an Konkurrenz oder böswillige Kräfte, sondern ein verständnisvolles Geben und Nehmen innerhalb der Gemeinschaft freier Softwareentwickler.
Durch diese Art von gemeinsamen Teilen wird nicht nur die Zeit der kompletten Neuentwicklung von Grundlagensoftware eingespart, sondern auch die Beständigkeit, Stabilität und Integrität von „Source code“ insgesamt verbessert, da der Anspruch der Perfektion nicht im Kleinen, aber in der großen nach Vollendung strebenden OpenSource Gemeinschaft von allen getragen wird.
Aus den Gründen eine grundlegend solide Wissensbasis sowie einen Ausgangspunkt für potenzielle Entwicklungen von Embedded LinuxAnwendungen für das Gerät OFSP (Open Frame Smart Panel) von der Firma Ultratronik aus Herrsching zu schaffen, wurde diese Arbeit mit dem Ziel initiiert, wertvolle Vorarbeiten zu leisten, indem Grundlagen zusammengefasst bzw. erweitert werden und gesammeltes Wissen lehrreich und struk turiert dargeboten wird.
Dabei wurden die Schwerpunkte so gewählt, dass sie den grundlegenden Fragestel lungen in der Entwicklung von graphischen Anwendungen analytischer Software mit hilfe der NanoX Bibliothek möglichst gerecht werden können. Denn gerade für NanoX existieren nur wenige und mindergute Anleitungen, die in ihrem Beispielreichtum und ihrer Vollständigkeit eher große Lücken aufzuweisen haben.
Im Rahmen dieser Arbeit wurden zudem Beispielapplikationen zur Anwendung von NanoX, zur Anwendung der TinyWidgets Bibliothek sowie zur Benutzung der Serial schnitte unter Linux erstellt. Weiterhin wurde eine kleine Erweiterung zur NanoX Bi bliothek vorgenommen (siehe Abschnitt 4.7).
Ferner wird am Ende diese Arbeit auf die für die Kommunikation mit externen Ge räten sehr wichtige Ansteuerung und Programmierung der Seriellen Schnittstelle unter Linux genauer eingegangen (siehe Abschnitt A.1).
1 Grundlegendes
1.1 Software und Analysetechnik
Der Einsatz von Software zur Auswertung aufgenommener Messdaten bietet gegenüber manuellen Methoden zahlreiche Vorteile: Es können Aussagen in kürzerer Zeit und zu verlässiger getroffen sowie sehr einfach und anschaulich dargestellt werden.
Zunehmend komplexere Problemstellungen erfordern zuverlässigere Methoden, die anfallenden Datenmengen untersuchen zu können. Durch den Einsatz von Software ist es möglich solche Probleme schnell und bequem zu lösen.
1.2 Problemstellung
In einem Unternehmen der Entwicklung und Produktion von Mess und Analysegerä ten besteht der ständige Anspruch der Verbesserung bestehender Produkte sowie deren Software und der effizienteren Gestaltung der Verfahren, die dazu notwendig sind.
Gerade aber im Bereich der Software besteht sehr oft das Problem, dass stark lizenz pflichtige Programmpakete zuerst kostenintensiv zu erwerben und dann, wenn in An wendung, kostenaufwendig zu warten sind. Dieses wirkt aus Sicht dieser Arbeit dem hohen Anspruch der Effizienz entgegen. Ob die Flexibilität analytischer Geräte durch ein hohes Maß an proprietärer BasisSoftware eingeschränkt wird und ob die Entscheidung für OpenSourceProdukte deshalb als bessere Wahl gelten kann, ist je nach Situation ab zuwägen:
Gründe, die gerade ein mittelständisches produktorientiertes Unternehmen mit we niger Entwicklungskapazitäten zur Abwägung bewegen sollten, sind der zusätzlich ent stehende Mehraufwand der Einarbeitung in anwendungspraxisfremde Programmier verfahren, die oftmals nicht oder noch nicht vorhandene Hardware und Treiberun terstützung von vielen OpenSourceBibliotheken, der fehlende (gute) Support eines SoftwareAnbieters sowie die Abklärung eventueller Verletzungen der Bedingungen un terschiedlicher freiersoftware Lizenzen .
Dennoch bietet es sich an, im weiten Feld der vorhandenen SoftwarePakete nach Al ternativen zu suchen, die auf den Grundideen, die durch freier Software vertreten wer den, fundiert sind.
Das NanoX Projekt ist als eine OpenSource „Windowing environment“ ein sehr gu tes Produkt, um durchdachte graphische Benutzerschnittstellen für verschiedenste An wendungen zu erstellen und auf in komplexeren Messgeräten integrierten Computer Geräten laufen zu lassen.
Die Hardware, d. h. das ebenfalls einleitend erwähnte OFSP (Open Frame Smart Pa nel) von Ultratronik, soll zunächst im folgenden Abschnitt als ein freie Software unter stützendes, universelles Gerät vorgestellt werden, welches sich als Steuereinheit in ein analytisches Gerät integrieren ließe.
2 Hardware
2.1 OFSP — Open Frame Smart Panel
Grundlegend kann das OFSP („Open Frame Smart Panel“) der Firma Ultratronik als ein vollwertiges Computersystem verstanden werden, dessen kleine Größe und hohe Leis tung es besonders geeignet für die Integrierung als „Embedded device“ (siehe Abschnitt 3.1) in größere funktionale Geräte macht.
Der aufgesetzte Touchscreen hat eine Auflösung von 320x240 Pixel und stellt die ge samte Interaktionsschnittstelle zwischen Gerät und Anwender dar. Dadurch ist es mög lich, relativ komplexe graphische Benutzeroberflächen darzustellen und bestimmte an wendungsrelevante Software direkt am Endgerät, an welches das OFSP angeschlossen ist, laufen zu lassen. Betrachtung und Auswertung von z. B. aufgenommenen Messdaten können dabei in einem bestimmten Maße unmittelbar durchgeführt werden.
Zur Ausstattung des OFSP gehören wei terhin eine 10/100 MBit Ethernet, eine USB sowie zwei RS232SeriellSchnittstellen. Dabei werden USB und serielle Schnittstelle zur In teraktion mit dem zu steuernden Gerät ver wendet, wogegen die EthernetSchnittstelle zur Kommunikation mit externen Systemen, oft auch für die anschließende Weiterverarbeitung aufgenommener Daten, verwendet wird. Das OFSP operiert vor allem bei sehr langen Be triebszeiten energiesparend.
Ein wichtiger Punkt für die ökonomische Verwendung ist weiterhin, dass das OFSP durch seine auf das Notwendigste reduzierte
Abbildung 1: Die OFSP Hardware[1]
Abbildung in dieser Leseprobe nicht enthalten
HardwareAusstattung sehr kostengünstig erwerbbar ist. Durch vielseitige Einsetzbar keit an verschiedenste zu kontrollierende Geräte kann das OFSP ohnehin als ein sehr flexibles Produkt angesehen werden.
Die verwendete MIPSProzessorArchitektur wird herstellerseitig zum einen von dem Betriebssystem Windows CETM unterstützt, zum anderen aber auch durch eine von Ultratronik modifizierte DebianGNU/Linux[2] Distribution.
Ultratronik, in ihrer Beschreibung des Gerätes, bezeichnet den Einplattencomputer
„OFSP5“ mit eigenständiger Betriebssoftware als MMI („ManMachineInterface“) und hebt vor allem die „Kostengünstigkeit, Modularität, Integrationsfähigkeit, Erweiterbar keit sowie die Langfristigkeit“ [Q11] des Produktes hervor.
In der Tat kann das OFSP als Universallösung vieler Problemstellungen der softwa rebasierenden Benutzerinteraktion sowie der Steuerung eines Gerätes gelten.
3 Betriebssoftware
In diesem Abschnitt ist Grundlegendes zur Betriebssoftware von Computersystemen („Embedded devices“), die in größere Geräte als Einheit der Übernahme von Steuerfunk tionen integriert sind, erläutert.
3.1 EmbeddedSystems
Ist eine Computersoftware so konzipiert, dass sie in einer Steuereinheit eines bestimm ten Gerätes ganz spezielle Aufgaben der Regelung und Überwachung wahrnimmt, so spricht man von einem EmbeddedSystem („Eingebettetes System“). [Q8]
Häufig sind solche EmbeddedSystems sehr speziell und hardwarespezifisch, d. h. nur für die Verwendung in einem bestimmten Gerät entworfen und daher nur auf dieses beschränkt. Neue Geräte würden demnach den Aufwand der Entwickelung eines kom plett neuen Betriebssystems nach sich ziehen.
Deshalb ist es sehr vorteilhaft, vollständige Betriebssysteme in der Steuereinheit eines Gerätes zu verwenden und lediglich gewissen Programmen, die auf diesem System als simple Anwendung ausgeführt werden, die eigentlichen Regelungs und Steueraufgaben zukommen zu lassen.
Nach diesem Prinzip ist vorgesehen, das im Abschnitt zuvor beschriebene OFSP als integrierbare Steuereinheit für verschiedenste Arten an Mess und Analysegeräten zu diskutieren. Im nächsten Abschnitt soll deshalb als Betriebssystem auf das stark proprie täre Windows CETM kurz eingegangen werden, um danach die GNU/LinuxAlternative vorzustellen.
3.2 Windows CE TM
Windows CETM , welches für ressourcenarme Geräte konzipiert wurde, d. h. für Gerä te, die einen Arbeitsspeicher von wenigen Megabyte, eine geringe Prozessorleistung so wie wenig Festplattenspeicher besitzen, ist ein populäres, weit verbreitetes und nach abschätzbarer Einarbeitungszeit leicht programmierbares Produkt der Firma Microsoft. Dennoch sind diese scheinbaren Vorzüge kritisch zu betrachten:
Es ist vor allem anzumerken, dass Microsoft Windows CETM Versionen als OEM Versionen („Original Equipment Manufacturer“[3]) so modifiziert sind, dass sie nach den Bedingungen eines stark monetärbelastenden Kontrakts mit einem Hardwarehersteller nur für spezielle Geräte angepasst und lauffähig sind. Außerdem sind fast alle weiteren SoftwareProdukte, die für Windows CETM existieren, mit ähnlichem Hintergrund ver sehen. Die Entwicklung neuer Software geschieht hier nach dem sogenannten „Closed source“Prinzip[4].
Trotz alledem sind eine Vielzahl von komfortablen Entwicklungsumgebungen für Windows CETM vorhanden, so z. B. Visual Studio für komplexe Entwicklungen, Platform Builder für Treiberentwicklungen und zudem das populäre Embedded Visual C++.
Da das Verständnis der LinuxAlternative vorangetrieben werden soll, wird die Ul tratronik Linux Distribution, welche speziell für die Verwendung mit dem OFSP entwi ckelt wurde, im folgenden Abschnitt genauer behandelt.
3.3 Ultratronik Linux Distribution
Aus dem Ultratronik Linux Handbuch heißt es:
„The Ultratronik Linux Distribution is a GPL licensed and royalty free set of Linux tools and projects to enable the development of applications and device drivers for HW based on Ultratronik MMI solutions.“ [Q7]
Bei Ultratronik Linux handelt es sich prinzipiell um ein speziell modifiziertes Debian Linux, für das ebenfalls von Ultratronik vertriebene OFSP. Deshalb ist eine Kompatibilität zum verwendeten HardwareSystem des OFSP hundertprozentig gegeben.
Die CDROM der Distribution beinhaltet vorerstellte RootVerzeichnisse mit unter schiedlichen Konfigurationen, die für die verschiedenen MMILösungen von Ulktratro nik jeweils unterschiedlich aufgebaut sind. Beim OFSP5 ist das RootVerzeichnis nach dem Mikrokontroller „VR4181A“, auf welchem das HardwareSystem aufbaut, benannt und im Verzeichnis rootfs/rootfs_VR4181A zu finden. Auf einem ausgelieferten Gerät sollte allerdings das grundlegende RootDateisystem bereits vorhanden sein.
Die Distribution beinhaltet des weiteren NanoX sowie die TinyWidgets Erweite rung zum NanoX System, welches die graphische Basissoftware als „Windowing sys tem“darstellt.
Weiterhin ist eine Toolchain, welche CLIB (C Bibliothek), GCC (GNU C Compiler) und GDB (GNU Debugger) beinhaltet, vorhanden. Für die Installation der Toolchain auf dem Gerät ist es lediglich notwendig, sie in das RootVerzeichnis mittels des tar Befehls zu extrahieren[5]:
tar xfjv <CDROM>/toolchain/ gcc3.3.5glibc2.3.2.tar.bz2 directory=/ Außerdem sind einige Beispielapplikationen, die neben einfachen „Hello world“ Programmen außerdem die Ansteuerung bestimmter Hardware demonstrieren, auf dem Datenträger enthalten.
Für genauere Information empfiehlt es sich, das auf der CDROM im Ordner doc/ zu findene „Ultratronik Linux User Distribution Users Manual“ zu konsultieren.
3.4 XWindow Systeme
Für die graphische Ausgabe ist es in einem System zum einen notwendig grundlegende Treiber (z. B. für die Graphikkarte), welche auf niedrigster Ebene („lowlevel“) operie ren, vorzuimplementieren, zum anderen aber auch, darauf aufbauend, Programmierbi bliotheken, die sogenannte A. .P.I., als höhere Abstraktionsebene anzubieten, welche einem Entwickler eine leicht bedienbare, geräteunabhängige (portable) und gut dokumentierte Schnittstelle bieten.
Das auf GNU/LinuxSystemen heutzutage am meisten zur Realisierung dieses Kon zepts verwendete SoftwarePaket ist das XWindowSystem, welches auch unter dem Namen X11 bekannt ist.
Es wurde 1984 am MIT (Massachusetts Institute of Technology) als Projekt initiali siert, um ein graphisches System zu entwickeln, welches sowohl lokal als auch über eine Datenfernübertragungsleitung in der Lage sein sollte, graphische Routinen und Primiti ven bereitzustellen. Um dies zu ermöglichen, wurde ein Client/Server Modell und ein spezielles Protokoll entwickelt. [Q20]
Die generelle hohe Rechengeschwindigkeit und Speicherkapazität moderner Com putersysteme unterstützt den mittlerweile riesig gewordenen Funktionsumfang des X WindowSystems relativ problemlos. X11 bleibt allerdings gerade deshalb für ressour cenarme Geräte sehr ungeeignet.
Aus diesem Grund wurde das NanoX Projekt (Microwindows[6]) mit dem Vorhaben ins Leben gerufen, für EmbeddedSystems, d. h. Handhelds, EmbeddedSteuereinheiten, etc. eine leicht programmierbare und problemlos lauffähige Alternative darzustellen, die niedrige Systemanforderungen voraussetzt. Innerhalb des NanoX Projektes wird eben falls das oben erwähnte Client/ServerModell mit einem eigenen Protokoll sehr aus schöpfend inkorporiert.
Vorteilhaft an NanoX ist außerdem, dass sich mit der Programmierbibliothek des X WindowSystems (Xlib) geschriebene Programme mit abschätzbar wenig Programmier aufwand zu unter NanoX lauffähigen Applikationen portieren lassen. Die Entwicklung von graphischen, leicht zu portierenden LinuxAnwendung kann vor diesem Hinter grund guten Gewissens vollzogen werden.
Im nächsten Abschnitt wird hinführend zur Entwicklung von NanoX Anwendungen erläutert, wie Programme generell für das OFSP kompiliert werden können.
3.5 CrossCompiler
CrossCompiler werden generell verwendet, um auf einem sogenannten BuildHost den generischen und portablen Quelltext eines Programmes in eine dem kompilierenden Sys tem „fremde“ Maschinensprache zu übersetzen. Das Kompilat ist dann auf einem soge nannten TargetHost, für welches die Applikation fremdkompiliert wurde, lauffähig, da die ausführbare Datei mithilfe von Maschinensprachinstruktionen erstellt wurde, wel che für den BuildHost unverständlichen, aber für den TargetHost verständlichen bzw. ausführbar sind.
Bei den meisten Computersystemen handelt es sich um solche, welche Intel Assembler Maschinensprache verwenden und deren Instruktionen vom Prozessor be arbeitet werden können. Da es sich aber beim Prozessor des OFSP um eine MIPS Prozessorarchitektur handelt, muss auf einem BuildHost ein CrossKompilat erstellt werden.
Gewöhnlicherweise steht dazu auf dem BuildHost ein spezieller Compiler zur Ver fügung, welcher in der Lage ist, systemfremden AssemblerCode zu produzieren, d. h. ein lauffähiges Programm für den TargetHost zu erstellen.
Die von Ultratronik herausgegebene CDROM der Ultratronik Linux Distributi on beinhaltet einen bereits voreingerichteten und für IntelProzessoren vorkompilier ten GNUCompiler, um CProgramme für die MIPSProzessorarchitektur zu erzeugen (CrossCompiler).
Für die Installation dieses CrossCompilers muss das sich im Verzeichnis Toolchain auf der CDROM befindliche Archiv gcc3.3.5glibc2.3.2 mittels des tarTools lediglich extrahiert und das anschließend erhaltene Ver zeichnis usr/mipsellinux einschließlich Ordnerstruktur und Inhalt in das RootVerzeichnis des HostEntwicklungsystems kopiert werden. Die Binary /usr/mipsellinux/bin/mipsellinuxgcc stellt dann den eigentlichen auf dem HostSystem lauffähigen Compiler dar, welcher für die Kompilierung für Anwen dungen für das TargetSytem nun zur Verwendung bereit steht.
4 NanoX — Die schlanke XWindow Variante
Ziel in diesem Teil ist es, das Konzept und die grundlegende Funktionalität der Nano X API weitestgehend zu ergründen und einen tieferen Einblick in die Benutzung der Programmierbibliothek zu geben.
4.1 Gesamtüberblick
„The NanoX Window System is an Open Source project aimed at bringing the features of modern graphical windowing environments to smaller devices and platforms.“ [Q13]
Bei NanoX handelt es sich um ein freies SoftwareProdukt für Linux, welches grundle gende Graphik und ManagementRoutinen moderner fensterbasierter Benutzeroberflä chen für ressourcenarme Geräte zur Verfügung stellt.
Gegenüber anderen XWindow Systemen ist NanoX selbst mit einfachster Hardware zuverlässig und stabil lauffähig, bietet aber daher auch nur einen begrenzteren Funk tionsumfang. Dieser ist allerdings für kleinere Geräte und deren Anwendungsbereich oftmals vollkommen ausreichend.
NanoX ist ohne Probleme auf einer Vielzahl von Architekturen lauffähig, wie z. B. Intel 16/32 Bit, MIPS oder PowerPC. Beim OFSP handelt es sich um ein auf der MIPS R4000 Prozessorarchitektur basierendes System. Ein LinuxSystem, dessen Kernel Fra mebuffer unterstützt, d. h. Kernel ab Version 2.2.x, sollte vorhanden sein.
Das NanoX System wurde in drei separaten Ebenen nach dem sogenannten „Glue layer Prinzip.“ konzipiert. In der ersten untersten Ebene, der Treiberebene („Driver le vel“), werden HardwareRoutinen für Maus, Bildschirm, u. ä. implementiert, um sie dann für die zweite, die Betriebsebene („Engine level“), der sogenannten MicroGUI, be reitzustellen. Dabei werden in der ersten Ebene sehr viele verschiedene Treiber für eine Vielzahl an Hardwareprodukten unterstützt. Die zweite Ebene kann als eine Art geräte und plattformunabhängige Umsetzung der graphischen Zeichenroutinen und der dazu notwendigen Algorithmen verstanden werden. [Q10, 1, 17]
Abbildung in dieser Leseprobe nicht enthalten
Bei der dritten Abstraktionsebene, der eigentlichen Anwendungsebene, steht einem Programmierer der volle Funktionsumfang der Bibliothek als API zur Verfügung.
Besonders interessant ist hierbei, dass NanoX zwei verschiedene APIs zur Verwen dung anbietet. Bei der ersten handelt es sich um die sogenannte NanoX API, welche sehr an die des XWindow Systems angelehnt ist und bei der zweiten um die sogenannte Mi crowindows API, welche Anlehnung an die in der WindowsProgrammierung verwen dete APIW (Win32TM API) findet, allerdings nicht den vollen Funktionsumfang dieser unterstützt. [Q19]
Durch diese Anlehnung an zwei sehr populäre APIs können Anwendungen, die auf Xlib (XWindow) basieren, bzw. Anwendungen, welche die Windows APITM benutzen, zu unter NanoX lauffähigen Programmen mit etwas Aufwand portiert werden.
In dieser Arbeit soll die NanoX API vorgestellt und verwendet werden, da sie die Möglichkeiten, welche die unter der Anwendungsebene liegenden Schichten, d. h. der Betriebs und Treiberebene, implementierungstechnisch besser nutzen kann (siehe Ab schnitt 4.6 „NanoX API oder Microwindows API“).
4.2 Lizenz und Bedingungen
Bei der Entwicklung von proprietärer Software besteht oft das Problem, dass die Ver wendung von unter der GPL („GNU General Public License“) lizenzierter Software zu Problemen führen kann, denn es gilt laut den Lizenzbedingungen der GPL, dass sie zu einer anschließenden Lizenzierung der neu entwickelten Software unter ihr verpflichtet. Da es allerdings nicht sinnvoll erscheint, den Quelltext eines letztendlichen Produktes freizugeben, kann dies sehr einschränken, gerade wo doch eine Vielzahl an nützlicher G. .N. U. .Software bei der Entwicklung als Werkzeug oder auch als Programmierbibliothek vorhanden ist.
Eine Alternative dazu bietet die MPL („Mozilla Public License“), unter welcher Nano X ebenfalls lizenziert ist: Anders als die GPL verpflichtet die MPL zwar auch dazu, dass alle SoftwareDerivate unter ihr lizenziert werden, hat aber dennoch einige Lockerungen zur strengeren GPL. So wird z. B. die Einteilung zwischen den Rechten des Originalau tors einer Software und den Rechten derer, die SoftwareDerivate erzeugen, getroffen.
Die NanoX Bibliothek ist sowohl unter der GPL als auch unter der MPL zweifach lizenziert.
Bei letzterer ist es genauso möglich, auf dem OriginalQuelltext einer Software auf zubauen oder eine Programmierbibliothek zu verwenden, wobei allerdings nur der ur sprünglich übernommene Kernteil auch unter der MPL lizenziert bleiben muss und der andere, letztendlich hinzugefügte Anteil, beliebig unter jeglicher anderer Software Lizenz lizenziert werden darf. [Q12]
Demnach sind bei der Verwendung der NanoX Bibliothek auch im kommerziel len Verwendungsbereich keinerlei Einschränkungen erkennbar. Der Quelltextanteil einer proprietären Neuentwicklung muss bei der Verwendung der MPL also nicht veröffent licht werden.
4.3 Einrichtung des Systems
Die Entwicklung von NanoX wurde leider im Jahre 2005 eingestellt, weswegen es sich bei der neusten Version um Microwindows 0.90 handelt, dessen Quelltext unter http://www.microwindows.org heruntergeladen werden kann.
Nach dem Dekomprimieren des Archivs mittels des Konsolenkommandos tar xvf microwindows0.90.tar.gz sollte der „Build tree.“ im Paketverzeichnis vorhanden sein.
Nicht wie bei Installationen unter vielen LinuxSystemen üblich, muss hier vor dem Kompilieren das configureSkript ausgeführt werden, sondern lediglich die Datei config im src/Quelltextverzeichnis editiert werden, um bestimmte Einstellungen, wie z. B. Mausunterstützung, Framebufferverwendung oder die zu benutzenden Sys temfonts (Schriftarten), zu tätigen[7].
Wichtig ist, dass in der configDatei die Prozessorarchitektur des späteren Nano X ausführenden Systems durch die Zeile ARCH= korrekt angegeben wird, d. h. für die MIPSArchitektur würde sie ARCH = LINUXMIPS lauten.
Es soll also crosskompiliert werden, d. h. in diesem Falle, dass das NanoX System für eine andere Architektur als die des kompilierenden Systems übersetzt wird, muss beim Ausführen des makeSkripts der in Abschnitt 3.5 eingerichtete Crosscompiler dem Programm G.N.U Make. zur Verwendung angegeben werden:
./make install prefix=/usr/mipsellinux/ withbuildgcc=/usr/bin/mipsellinuxgcc Nach dem Kompilieren sollten nun alle nötigen ausführbaren Dateien („Binaries“) im Ordner src/bin des MicrowindowsVerzeichnisses vorhanden sein[8].
Bei der ausführbaren Datei nanoX handelt es sich um den eigentlichen „XServer“ , d. h. um das Programm, welches grundlegende lowlevel Routinen und Hardware Primitiven implementiert.
Die weiterhin wichtige BinaryDatei nanowm ist der NanoX „Window manager“, welcher dafür zuständig ist NanoX Applikationen in einer fensterbasierten Umgebung („Windowin environment“) anzuordnen und zu verwalten.
Wird NanoX auf einem System betrieben, so sollte zunächst das NanoX Basissystem ( nanoX) und anschließend der Fenstermanager ( nanowm) gestartet werden[9].
Während der Entwicklung von Software für das Endgerät (in diesem Fall das OFSP) kann die Möglichkeit verwendet werden, NanoX auf einem XWindow System, d. h. auf einem Host, welcher X11 als graphisches System verwendet, zu emulieren, sodass An wendungen schon beim Entwickeln getestet werden können. Dazu ist es lediglich not wendig vor dem Kompilieren die Zeile X11 = Y und die Zeile FRAMEBUFFER = N in der Konfigurationsdatei INSTALL zu setzen.
Es ist weiterhin wichtig, dass die statischen NanoX Bibliotheken, welche nach dem Kompilieren im Verzeichnis src/lib mit der Endung *.a vorhanden sind, auf dem HostEntwicklungssystem in das Verzeichnis usr/lib kopiert werden müssen. Ebenso
müssen die Microwindows HeaderDateien in das Verzeichnis /usr/include auf dem HostSystem von dem Verzeichnis src/include kopiert werden. Damit ist sicherge stellt, dass der CCompiler die IncludeDateien bzw. Bibliotheken vorfindet. Beim Kom pilieren muss nun lediglich der Parameter lnanoX , welcher für die NanoX Biblio thek steht, in der Kommandozeile beim gcc Aufruf übergeben werden.
4.4 Einführung in die NanoX Programmierbibliothek
Da die NanoX API in der Programmiersprache C implementiert wurde, handelt es sich bei dieser auch um die Sprache, in welcher NanoX Anwendungen generell geschrieben werden, so auch in dieser Arbeit.
Mit dem Ziel, einen ersten Überblick über das Arbeiten mit der NanoX API zu be kommen, wird hier der Quelltext einer einfachen NanoX Anwendung angebracht, wel cher allerdings bereits viele wichtige Kernpunkte der Programmierung beinhaltet.
Abbildung in dieser Leseprobe nicht enthalten
Betrachten wir die im Quelltext auftretenden Einzelheiten vorerst einmal nicht, so ist die Grundidee eines NanoX Programmes sehr schnell verständlich.
Ein Fenster wird erzeugt, auf welches mithilfe eines so genannten Graphischen Kon texts Ausgaben erfolgen können.
Weiterhin wird deutlich, dass verschiedene Ereignisse existieren, die auftreten kön nen, und im unteren Teil des Programms in eine Endlosschleife, der sogenannten Ereig nisschleife, abgefragt werden.
Ersichtlich ist in der Beispielanwendung auch, dass beim Auftreten des Ereignisses
GR_EVENT_TYPE_EXPOSURE, des sogenannten „Sichtbarkeitsereignisses“[10], der Text
„Hello World“ auf dem Fenster ausgegeben wird.
In den folgenden Abschnitten wird auf die im Beispiel bereits verwendeten Kernkon zepte der NanoX API näher eingegangen werden[11].
4.4.1 Fenster
Fenster sind ein rechteckiger Pixelraum mit einer Höhe und einer Breite sowie X und Y Koordinaten des linken oberen Eckpunktes. Sie sind in einer Baumstruktur registriert, d. h. ein Fenster kann als Elter („Parent“) beliebig viele Kinderfenster („Children“) besitzen.
Das sogenannte Hauptfenster („Rootwindow“) stellt dabei den gesamten Bildschirm als „Fenster“ dar und ist das HauptElter aller anderen Fenster. Es ist als Fenster nicht entfernbar, verhält sich aber ansonsten wie ein reguläres Fenster, auf dem Ereignisse wahrgenommen werden sowie Ausgaben getätigt werden können.
Die Positionsangaben eines Fensters sind außerdem immer eine Angabe relativ zum ElterFenster, dessen oberster linker Eckpunkt die Koordinaten X=0 und Y=0 besitzt.
Kommt es zur Überlappung von Geschwisterfenstern (Fenster mit dem gleichen El ter), so legt ein veränderbarer Präzedenzwert fest, welches Fenster vollständig sichtbar ist und welches durch seine Geschwister verdeckt werden kann.
Außerdem besitzen alle Fenster eine Hintergrundfarbe, wobei ein neu erstelltes oder ein geleertes Fenster immer mit dieser vollständig gefüllt ist.
Für ein Fenster existiert weiterhin ein optionaler Rahmen, der mit einer variablen Breite und Farbe definiert ist. Besitzt ein Fenster einen Rahmen (Rahmenbreite > 0), so ist dieser um das Fenster gezeichnet, d. h. er beeinflusst die Ausmaße des durch das Fenster aufgespannten relativen Koordinatensystems nicht.
Um ein Fenster zu erstellen, geht man wie folgt vor:
Zunächst deklariert man eine Variable mit dem von der NanoX API definiertem Ty pen GR_WINDOW_ID, welcher die Identifikationsnummer des Fensters darstellt:
GR_WINDOW_ID fenster;
Als nächstes erzeugt man mithilfe der Funktion GrNewWindow (...) ein neues Fenster und weist den Rückgabewert dieser der eben deklarierten Variable zu, womit die ID des Fensters gespeichert ist.
fenster = \ GrNewWindow(GR_ROOT_WINDOW_ID, 10, 10, 20, 20, 4, WHITE, BLUE);
Die Parameter der Funktion GrNewWindow (...) sind in dieser Reihenfolge das ElterFenster, welches hier im konkreten Fall das Hauptfenster durch die Konstante GR_ROOT_WINDOW_ID, die XKoordinate des Fensters, die YKoordinate des Fensters, die Fensterbreite, die Fensterhöhe, die Rahmenbreite, die Fensterhintergrundfarbe sowie die Rahmenfarbe repräsentiert.
Im Beispiel ist also ein Fenster an der Position (10 , 10) mit den Ausmaßen 10x10, der Hintergrundfarbe weiß und der Rahmenfarbe blau erzeugt worden.
Dabei ist das Hauptfenster vom Typ GR_WINDOW_ID, X und YKoordinate vom Typ GR_COORD, Fensterbreite und höhe sowie Rahmenbreite vom Typ GR_SIZE. Positions und Größenangaben verhalten sich wie Integervariablen.
Ein Fenster kann sichtbar oder unsichtbar sein („mapped“ oder „unmapped“), wobei auf ihm, wenn unsichtbar, keine Ereignisse auftreten können. Ansonsten verhält es sich genauso wie ein sichtbares Fenster. Ein neu erstelltes Fenster ist immer unsichtbar und muss deshalb erst sichtbar gemacht werden:
GrMapWindow(fenster);
Es ist möglich, einem Fenster einen speziellen Mauszeiger zuzuordnen. Kinder ei nes Fenster haben, wenn erstellt, den gleichen Mauszeiger wie das ElterFenster. Für ein Fenster kann solch eine Zuordnung durch die Funktion GrSetWindowCursor (...) geschehen.
Wissenswert ist auch, dass zwei Fensterarten existieren. Das sind zum einen Ein/AusgabeFenster, welche normal sichtbar sind und in welche ausgegeben werden kann, zum anderen unsichtbare rahmenlose „NurEingabe“ Fenster, in welche nicht aus geben werden kann. Sie fangen Ereignisse ab bzw. ändern den Mauszeiger an bestimm ten Bildschirmregionen. „NurEingabe“ Fenster können auch nur solche als Kinderfens ter besitzen.
4.4.2 Graphische Kontexte
Ein Graphischer Kontext („Graphics Contexts“)[12] bezeichnet eine Menge von Eigenschaf ten (wie Farbe, Dicke, Art), die beim Zeichnen graphischer Objekte eine Rolle spielen. D. h. anstatt diese Eigenschaften bei jeder Zeichenoperation einzeln als Parameter des ent sprechenden Funktionsaufrufs anzugeben, wird ein eigenschaftsspeichernder GK ver wendet. Die einzige Eigenschaft, die ein graphischer Kontext nicht vereinen kann, sind die für jedes graphische Objekt individuellen Positionskoordinaten.
Für einen neuen GK muss Speicher allokiert werden, womit dieser eine einzigartige Identifikationsnummer erhält:
GR_GC_ID graphischer_kontext = GrNewGC();
Ein neuer GK ist mit Standardeigenschaften ausgestattet, d. h. zum Beispiel der Vorder und Hintergrundfarbe weiß und der Dicke 0.
Gewöhnlicherweise wird für jede Gruppe ähnlicher graphischer Elemente ein GK angelegt, der dann im Programm mehrfach für eben diese Gruppe verwendet werden kann.
Eine typische Eigenschaft eines GK ist z. B. der Zeichenmodus, welcher das Vor gehen beim Zeichnen eines jeden Pixels beschreibt. Für einen bestimmten GK kann er mit der Funktion GrSetGCMode (GR_GC_ID gk, int mode) gesetzt werden. Die modusbeschreibende Integervariable der Parameterliste kann die konstanten Werte GR_MODE_SET (Standardmodus), welcher Pixel unverändert zeichnet, sowie GR_MODE_XOR, GR_MODE_OR oder GR_MODE_AND besitzen, welche die Farbadditi on nach der jeweils im Konstantennamen erkennbaren Methode durchführen.
Eine weitere Eigenschaft eines GK ist die Schriftart, welche als Standardschriftart durch die Integervariable 0 angegeben wird. Die in fortlaufender Nummerierung fol genden Schriftarten sind Systemschriftarten. Wie viele dieser genau existieren, ist un terschiedlich und vom System abhängig. Weitere Schriftarten müssten erst beim graphi schen Server des NanoX Systems registriert werden. Die Schriftart eines GK wird mit der Funktion GrSetGCFont (GR_GC_ID gk, GR_FONT_ID font) festgelegt.
Weiterhin existierende Eigenschaften sind Vordergrund bzw. Hintergrundfarbe, die mit GrSetGCForeground (...) bzw. GrSetGCBackground (...) gesetzt werden können, wobei die Standardhintergrundfarbe schwarz ist. Hierbei gibt eine bool’sche Va riable als weitere GKEigenschaft an, ob der Hintergrund beim Zeichnen überhaupt ver wendet werden soll. Diese kann mittels GrSetGCUseBackground (GR_GC_ID gk, GR_BOOL bool) gesetzt werden.
Neben diesen Grundeigenschaften existieren einige weitere, die im NanoX Hand buch kurz beschrieben werden.
4.4.3 Ereignisse
4.4.3.1 Ereignistypen
Ein Ereignis beschreibt eine Statusänderung von Tastatur, Maus oder Bildschirm, die vom Benutzer hervorgerufen wurde. Dabei werden durch Hardware hervorgerufene Ereignis se als physische bezeichnet.
Tritt ein Ereignis auf, so kann ein NanoX Programm darauf reagieren, indem es Er eignisse von der Ereignisschlange („Event queue“) des NanoX Servers abruft, welche dort für eine Anwendung angestellt werden.
Weiterhin wird die Art eines Ereignisses durch dessen Ereignistyp bestimmt. Da ei ne Vielzahl von Ereignissen auftreten können, assoziiert NanoX mit jedem Ereignis eine sogenannte Ereignisstruktur, welche Informationen über das Ereignis enthält (z. B. bei Mausereignissen die Koordinaten des Mauszeigers, oder bei Tastaturereignissen die ge drückte Taste).
Bei einer Ereignisstruktur handelt es sich also um eine CKollektion ( struct) meh rerer Objekte, welche in ihrer Gesamtheit spezifische Informationen über ein Ereignis mit einem bestimmten Ereignistyp liefert.
Das typendefinierte[13] GR_EVENT stellt ein polymorphes Konstrukt dar und ist in Wahrheit lediglich eine CVariante („Union“), welche als Elemente seiner Ausprägung alle in NanoX vorhandenen Ereignisstrukturen enthält. Somit kann ein jedes Ereignis den Typ GR_EVENT besitzen. Dieses Ereignis kann nun aber auch nach einer Fallun terscheidung mittels des typeFeldes, welches, da es in jeder Ereignisstruktur existiert, auch als Element der Variante abgefragt werden kann, in den richtigen Typen umgewan delt werden (cast), um Zugriff auf die ereignisstrukturspezifischen Informationen eines bestimmten Ereignisses zu bekommen.
Somit korrespondiert eine ereignistypbeschreibende Integerkonstante (Ereignistyp) mit einer oder mehreren typendefinierten Ereignisstrukturen. Mehrere deshalb, da eini ge unterschiedliche Ereignisse gleiche Informationen liefern, d. h. gleiche Strukturfelder besitzen, wie z. B. Ereignisstrukturen vom Typ GR_EVENT_TYPE_BUTTON_DOWN und GR_EVENT_TYPE_BUTTON_UP (Taste gedrückt und Taste losgelassen).
Eine auflistende Beschreibung aller Ereignisstrukturen und der mit ihnen korrespon dierenden Ereignistypen kann dem Anhang B.1.2 entnommen werden.
4.4.3.2 Ereignisverarbeitung
Ereignisse sind an ein Fenster gebunden, d. h. sie können auf dem Bereich, der durch die Ausmaße des Fensters definiert ist, auftreten.
Hierzu müssen sie allerdings beim Fenster dafür registriert sein, was durch die Funktion GrSelectEvents( GR_WINDOW_ID fenster, GR_EVENT_MASK ereignis_maske)[14] realisiert wird. Dabei stellt die Variable ereignis_maske vom Typ GR_EVENT_MASK eine logische ODER Verknüpfung einzelner BitWerte bestimmter Ereignismasken mittels des „ |“Symbols dar und repräsentiert dadurch einen speziellen Ereignistyp.[15]
Die Typnamen aller Ereignismasken sind denen des Ereignistyps sehr ähnlich. Ist der Ereignistyp z. B. durch die Integerkonstante GR_EVENT_TYPE_BUTTON_DOWN beschrieben, so wäre der dazugehörige Maskenname nichts weiter als GR_EVENT_MASK_BUTTON_DOWN.
Ist ein Fenster Kind eines anderen und tritt auf ihm ein Ereignis auf, welches nicht von ihm, aber bei seinem Elter registriert ist, so bemerkt das Elter das Ereignis des Kindfens ters. Es kann dann mittels des Feldes wid einer Ereignisstruktur die Fensteridentifikation des Fensters ermitteln, auf welchem das Ereignis auftrat.
Erwähnenswert ist zudem, dass ein sogenannter Eingabefokus („Input focus“) exis tiert. D. h. wenn ein Tastaturereignis eintritt, wird es von dem Fenster registriert, über welchem sich der Mauszeiger momentan befindet. Mit der Funktion GR_WINDOW_ID GrGetFocus (void) kann das Fenster ermittelt werden, welches im Moment den Ein gabefokus besitzt. Mit der Funktion GrSetFocus (GR_WINDOW_ID fenster) kann dieser auf ein beliebiges Fenster verlegt werden.
4.4.3.3 Ereignisorientierte Anwendungsprogrammierung
Die für eine gesamte Anwendung (egal welches Fenster) auftretenden Ereignisse werden von NanoX in einer Ereignisschlange („Event queue“) organisiert.
Möchte man überprüfen, ob ein neues Ereignis für die Anwendung auf getreten ist, so verwendet man die Funktion int GrPeekEvent (GR_EVENT * ereignis_zeiger), welche als Parameter einen EreignisstrukturZeiger erhält, der auf
die Ereignisstruktur des nächsten anstehenden Ereignisses zeigen wird, ohne das dieses von der Schlange entfernt wurde. Die Funktion gibt 1 zurück, wenn ein Ereignis vorhan den ist, 0 wenn nicht.
Erst mit der Funktion GrGetNextEvent (GR_EVENT * ereignis_zeiger) ent fernt man das nächst anstehende Ereignis von der Schlange und erhält einen Zeiger vom Typ GR_EVENT * auf eine Ereignisstruktur.
In einer Anwendung kann man nun mithilfe einer endlos laufenden Ereignisschleife jeweils das nächste Ereignis abfragen und je nach Ereignistyp der erhaltenen Ereigniss truktur entscheiden, welches Ereignis auftrat und wie mit den erhaltenen Informationen verfahren werden soll (siehe Anfangsbeispiel in Abschnitt 4.4).
Ein spezielles Ereignis namens GR_EVENT_EXPOSURE, das sogenannte „Sichtbar keitsereignis“, tritt dann einmalig auf, wenn ein Fenster vollständig sichtbar wird. Schreibt man NanoX Anwendungen, so ist es wichtig zu wissen, dass Fensterinhalte nicht gespeichert werden, d. h. sie gehen bei Überlappungen verloren und müssen somit neu gezeichnet werden.
Das kann geschehen, indem der Teilbereich (oder der gesamte Fensterbereich) genau dann neu gezeichnet wird, wenn er sichtbar geworden ist. Hierzu ist das Sichtbarkeitser eignis sehr dienlich, denn tritt es in der Ereignisschleife der Anwendung auf, d. h. wird das Fenster oder ein Teil dessen angezeigt, kann die Anweisung zum Neuzeichnen aus geführt werden.
Daraus folgt außerdem, dass permanente graphische Fensterinhalte im Quelltext nicht gleich nach dem Erstellen des Fensters gezeichnet werden sollten, sondern erst dann, wenn das Sichtbarkeitsereignis des entsprechenden Fensters in der Ereignisschlei fe der Anwendung auftritt. Möchte man dennoch permanent Inhalte realisieren, so kann man auf die im Rahmen dieser Arbeit entwickelte State Saver Erweiterung zurückgrei fen (siehe Abschnitt 4.7).
Zuletzt existiert als ein besonderes Ereignis das sogenannte „Fensterschließereignis“. Um zu ermöglichen, dass ein Fenster beim Betätigen des Fensterschließbuttons, wel cher sich in der rechten oberen Fensterecke befindet, geschlossen wird, muss in der Er eignisschleife der Anwendung auf das Eintreten eben dieses Ereignisses mit dem Ty pen GR_EVENT_CLOSE_REQ geprüft werden. Hiernach kann dann das Fenster rekursiv mithilfe der Funktion GrDestroyWindow (GR_WINDOW_ID) entfernt werden, d. h. es werden auch alle Kinder dieses Fensters aus dem Speicher entfernt. Soll eine NanoX An wendung vollends beendet werden, so empfiehlt sich, die Verbindung mit dem NanoX Server mittels GrClose(void) zu beenden.
Für eine Auflistung aller NanoX Funktionen empfiehlt es sich, das englischsprachige „Microwindows NanoX API Reference Manual“ zu konsultieren.
4.5 Der NanoX Server
Hier noch einige Worte zum schon mehrfach erwähnten NanoX Server. Dahinter näm lich verbirgt sich ein Kernkonzept der NanoX API, bei welchem es sich um das soge nannte Client/ServerModell handelt.
Der Server stellt einen seperaten Prozess, d. h. ein eigenständiges Programm dar, wel cher mit dem Ausführen der NanoX Binary ( nanoX) gestartet wird. Dieser stellt dann einen Unix domain socket. (.U.D.S.) bereit, zu welchem sich ein oder mehrere Clients ver binden können und über welchen sie kommunizieren.
Der Client stellt dabei die eigentliche vom Programmierer entwickelte Anwendung dar. Wie oben schon verwendet, muss in einer Applikation die Funktion GrOpen() zu Beginn aufgerufen werden, um eine Verbindung zum NanoX herzustellen sowie die Funktion GrClose() am Ende, um die Verbindung wieder zu trennen.
ClientFunktionen, d. h. alle Funktionen der NanoX API, welche in einer An wendung verwendet werden, sind dadurch gekennzeichnet, dass sie das Präfix Gr mit im Funktionsnamen tragen. Ein bekanntes Beispiel dessen ist die Funktion GrGetNextEvent(...), welche anstehende Ereignisse vom NanoX Server über die ClientSocket Verbindung abholt.
Außerdem werden alle Aufrufe für Zeichenroutinen, Fensterroutinen, etc. auch über die durch den Socket hergestellte Verbindung bewältigt. Jeder Aufruf einer GrClient Funktion resuliert auf dem anderen Ende der Verbindung in dem Aufruf einer entspre chenden durch das Präfix Gd gekennzeichneten ServerFunktion.
Zu vermerken ist, dass trotz des Vorteils kleinerer Anwendungen und besserer Lauf zeit die Benutzung des Client/Server Modells nicht zwingend geschehen muss. Kom piliert man nämlich NanoX mit Option LINK_APP_INTO_SERVER = Y in der Datei src/config gesetzt, so kann auf ServerFunktionen direkt zugegriffen werden.
Erwähnenswert ist weiterhin, dass im Client/ServerModell sogenannter „S.h. a. r.e.d. m. .e.m. .o.r.y“ zum Datenaustausch zwischen Server und Anwendung stattfindet, um die Effizienz des Zugriffes auf gemeinsame Ressourcen zu verbessern.
4.6 NanoX API und Microwindows API
Der Hauptvorteil der Microwindows API besteht wohl darin, dass sie einen ernstzu nehmenden Versuch darstellt, mit der Win32TM API kompatibel zu sein, auch wenn die Erfüllung dieser Zielstellung bisher eher fraglich erscheint.
In diesem Abschnitt sind Vor und Nachteile beider APIs vergleichend besprochen.
4.6.1 Kernkonzepte im Vergleich
Hingegen zu den Ereignissen der NanoX API existieren in der Microwindows API, ähn lich der WindowsTM API, sogenannte „Nachrichten“, welche in einer sogenannten Nach richtenschlange („Message queue“) der Anwendung überreicht werden und welche ver schiedene Hard und SoftwareEreignisse repräsentiert.
Wie in der WindowsTM API auch, werden Nachrichten, die mit einer speziellen HandlerFunktion eines bestimmten Fensters vom Programmierer zuvor assoziert wor den sind, nacheinander vom „Message queue“ geholt und mittels der Funktion DispatchMessage(MSG*) an den entsprechenden Handler verteilt. Demnach existiert auch eine Art Ereignisschleife (die sogenannte „Nachrichtenschleife“ ) in der Microwin dows API, nur wird die „Ereignisverarbeitung“ hier streng fensterorientiert vorgenom men.
Ähnlich den Graphischen Kontexten („Graphics Context“) der NanoX API existiert ein sogenannter „Device context“, der es ermöglicht, bestimmte Eigenschaften der zu zeichnenden graphischen Objekte zusammenzufassen. Um allerdings auf den Bildschirm frei auszugeben, ist es hier nötig, einen „Screen device context“ zunächst zu erschaffen, wohingegen bei NanoX lediglich das Hauptfenster im Graphischen Kontext spezifiziert werden muss (siehe Abschnitt 4.4.2). [Q9]
4.6.2 NanoX API oder Microwindows API — Ein Fazit
Unstrittig ist, dass der Einstieg in die NanoX Programmierung für Windows CETM Programmierer durch die Microwindows API leichter möglich ist.
Wichtig hingegen zu wissen ist, dass, entscheidet man sich für die Microwindows API, keine Entwicklung unter LinuxHost Systemen möglich ist, da keine X11 Unterstüt zung angeboten wird.
Ein sehr beeinträchtigender Nachteil ist, dass Anwendungen, die mit der Micro windows API entwickelt wurden, nicht nach dem in Abschnitt 4.5 beschriebenen Client/ServerModell kompiliert und ausgeführt werden können.
Gerade allerdings dieses Modellkonzept bietet besonders für die Laufzeit und Uni versalität guter Anwendungen klare Vorteile. Denn durch den abgeschlossen laufenden Server werden anstatt direkter Datenstrukturzeiger lediglich einfache clientseitige Auf rufe von bestimmten internen Prozeduren durchgeführt, die vom Server in der Beach tung von Ressourcen, die durch andere registrierte ClientAnwendungen beansprucht werden, schneller und effizienter durchgeführt werden können. Außerdem sind, profan formuliert, Programme, die nicht alle graphischen Routinen in ihrer Binary hinzugefügt („gelinkt“) haben müssen, da sie den Server und dessen Aufrufe verwenden, wesentlich kleiner in ihrer Dateigröße. Dem könnte deshalb bei ressourcenarmen Geräten eine wich tige Bedeutung zukommen.
Der wichtige Aspekt, dass, grundlegend ausgedrückt, für Linux entwickelt wird, d.h. auch Methodiken der Programmierung unter Linux utilitarisiert werden sollten, darf nicht außer acht gelassen werden.
Programmierungen mithilfe der eingeschränkten Microwindows API sind daher zwar realisierbar und mögen sogar in der ersten Phase des Wechsels von Win32TM auf LinuxProgrammierung einfacher erscheinen, benachteiligen allerdings auf lange Sicht, da die Systemnähe nicht hundertprozentig vorhanden ist und außerdem die Entwick lungsmöglichkeiten unter LinuxHost Systemen nicht gegeben sind, da X11 nicht so wie bei der NanoX API unterstützt wird. D. h. praktisch, dass das Testen und Entwickeln von Anwendungen viel aufwendiger und zeitintensiver vollzogen werden muss.
Die NanoX API hingegen ist aufgrund ihrer Nähe zur XLib, ihres größeren und bes ser dokumentierten Funktionsumfangs, ihrer Erweiterung durch die TinyWidgets Biblio thek (siehe Abschnitt 4.9) und ihrer hohen generelleren Akzeptiertheit und verbreiteten Verwendung eine bessere Wahl, die langfristige Entwicklungssicherheit und Integrier barkeit verspricht. [Q10]
4.7 State Saver — Visueller Zustandsspeicher
Die Problematik der NanoX API so einmalig auf einem Fenster auszugeben, dass die Inhalte permanent während der Laufzeit bestehen bleiben, wurde bereits in Abschnitt
4.4.3.3 kurz angesprochen.
Besonders bei aufwendigeren Ausgaben kann ein Neuzeichnen wertvolle Rechenka pazitäten konsumieren, weshalb der Mehraufwand einer temporären Speicherung beste hender Fensterinhalte sinnvoll erscheint. Dies wird durch die im Rahmen dieser Arbeit entwickelte StateSaver Erweiterung auf eine besondere Art realisiert.
Um die State SaverErweiterung benutzen zu können, sind einige wenige Verände rungen im Quelltext einer NanoX Anwendung notwendig (siehe Anhang C.2.2 für eine komplette Beispielanwendung).
4.7.1 Verwendung
Um den Zustand eines existierenden Fensters speichern zu können, muss ein Objekt vom Typ STATE_AREA* angelegt werden. Mittels der Funktion new_saved_area( GR_WINDOW_ID ), welche eine FensterIdentifikationsnummer erhält, wird ein neuer Zustandsspeicher eben für dieses Fenster angelegt.
STATE_AREA* zustandsspeicher_fenster1 = \
new_saved_area( fenster1_id );
In einer Programmabfolge könnte nun bereits anfangs und ohne auf das Auftreten eines Sichtbarkeitsereignisses für das Fenster zu warten[16], eine Ausgabe auf dem Fenster erfolgen, da es durch die Funktion renew_state( STATE_AREA* ) zu jedem belie bigen Zeitpunkt möglich ist, den aktuellen visuellen Zustand des Fensters zu speichern. Implizit bedeutet dies, dass diese Funktion immer dann aufgerufen werden sollte, wenn der Fensterinhalt verändert wurde.
renew_state( zustandsspeicher_fenster1 );
Im Unterschied zur Ereignisabfrage in der Ereignisschleife regulärer Anwendun gen mittels der Funktion GrGetNextEvent(...), muss diese nun durch die Funkti on StateSaverGetNextEvent(GR_EVENT*) substituiert werden. Die grundlegende Funktionsweise dieser neuen Prozedur unterscheidet sich für den Anwender nicht von der vorherigen, erlaubt allerdings der Erweiterung, Fensterinhaltsaktualisierungen dann, wenn notwendig, durchzuführen.
Möchte man Ereignisse zu einem Fenster hinzufügen, dann ist es bei der Benutzung der State Saver Erweiterung wichtig, dass die Funktion StateSaverAddEvents( GR_WINDOW_ID , GR_EVENT_MASK) anstatt der Funktion GrSelectEvents(...) verwendet wird, da letztere alle bereits gesetzten Bits der B. i.t.m. a. s. k. e. überschreibt.
Hat man z. B. beim oben erwähnten Fenster mit der ID fenster1_id vor, das Ab fragen des Ereignisses zum benutzergewünschten Schließen des Fensters abzufragen, so gestaltet sich der Quelltext folgendermaßen:
StateSaverAddEvents( fenster1_id, GR_EVENT_MASK_CLOSE_REQ );
Genauso sollte auch nun die Funktion StateSaverRemoveEvents( fenster1_id, GR_EVENT_MASK_CLOSE_REQ ) benutzt werden, um das Abfra gen von Ereignissen für ein Fenster abzustellen bzw. zu entfernen.
Am Ende eines ordnungsgemäß arbeitenden CProgrammes sollte jeder während des Ablaufes allokierte Speicher auch wieder freigegeben werden, weshalb im Falle der Ver
wendung des StateSavers die Funktion destroy_saved_area( STATE_AREA* ) für jeden zuvor erstellten Zustandsspeicher aufzurufen ist.
4.7.2 Funktionsweise
Das Kernstück des State Savers benutzt die Methode GdReadArea(...) (zu finden in der Datei engine/devdraw.c) des geräteunabhängigen „Engine levels“ , bzw. der Mi croGUI (siehe Abschnitt 4.1). Diese Methode erledigt nichts weiter, als bestimmte Pixel werte eines definierten Bereiches mithilfe der NanoX Kernfunktion ReadPixel(...) auszulesen und die Rückgabewerte des Typs MWPIXELVAL in einen Array von Pixeln des Typs GR_PIXELVAL zu speichern und zurückzugeben.
Die StateSaverErweiterungen nutzt diese Möglichkeit und verwaltet bestimmte Spei cherstrukuren, die verschiedenste Stati aktueller graphischer Ausprägungen von Fens tern darstellen, die dann, wenn notwendig, eine Wiederherstellung erfahren[17].
4.7.3 Kompilierungshinweise
Bei der Kompilierung ist darauf zu achten, dass zum einen die benötigte HeaderDatei state_saver.h im IncludePfad des Compilers vorhanden ist, zum anderen aber auch, das die statische StateSaver Bibliothek ssaver.a vom Linker gefunden bzw. auch verwendet wird. Dazu setzt man die CompilerFlags I<Pfad_zu_Header>, L<Pfad_zu_Library> sowie lssaver.a, bei der Eingabe in die Linux Kommandozeile.
4.8 dkbd — Eine virtuelle Tastatur für das OFSP
Eine sinnvolle Beispielapplikation der Anwendung der NanoX Programmierbibliothek stellt die graphische Tastatur „dkbd“ dar, die außerdem gleichzeitig eine komfortable Eingabemöglichkeit für das touchscreengesteuerte OFSP bietet und deshalb im Rahmen dieser Arbeit entwickelt wurde.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 2: Screenshots der Eingabe in ein LinuxTerminal mithilfe der virtuellen Tas tatur auf dem mit Ultratronik Linux betriebenem OFSP.
4.8.1 Anwendungskonzeption
1. Ein permanent sichtbares „Startfenster“ („Launcher Window“) steht am linken obe ren Bildschirmrand dem Benutzer dauerhaft zur Verfügung.
2. Vom Aufruferfenster aus kann die Haupttastatur aufgerufen werden. Außerdem sind auf ihm graphische Elemente für die Entertaste („Carriage Return“) sowie für die Rücktaste („Backspace“) vorhanden.
3. Die Haupttastatur befindet sich, wenn bei Bedarf aufgerufen, als polygonal be grenzte Fensterfläche am unteren Rand des Bildschirmes.
4. Auf der Haupttastatur sind die wesentlichen Elemente einer realen Tastatur als vir tuelle Repräsentation auffindbar.
5. Schreibt man auf der Haupttastatur, so werden die einzelnen Zeichen („Charac ters“) zunächst in einen Puffer („Buffer“) geschrieben und erst beim Schließen der Haupttastatur an den NanoX Tastaturtreiber weitergegeben.
4.8.2 Programmiertechnische Umsetzung
In diesem Abschnitt ist die konkrete Konzeptrealisierung geschildert, wobei besonders auf NanoX relevanten Quellcode eingegangen wird.
4.8.2.1 Abstrakt
Alle abstrakten Annahmen über eine Tastatur sind durch CDatenstrukturen in der HeaderDatei
dkbd.h realisiert (siehe für den Quelltext Anhang C.1).
Konzeptual stellt eine Tastatur nichts weiter dar, als eine Ansammlung von Tasten in einer bestimmten Ordnung. Deshalb wird die gesamte Tastatur als Array an Tasten angesehen.
Eine Taste wird durch die CStruktur struct key dargestellt, welche folgende In formationen über genau eine Taste enthält:
1. Die Koordinaten zweier Punkte, welche ein Rechteck aufspannen und damit die Position und Benutzerzugänglichkeit der Taste festlegen.
2. Der ASCIIKeycode des Zeichens, welches durch die Taste repräsentiert wird.
3. Zwei Objekte vom Typ GR_IMAGE_ID, welche eine Graphik der Taste im betätigten sowie unbetätigtem Zustand bereitstellen.
Weiterhin ist es möglich, dass sich die Bedeutung oder Belegung einer speziellen Tas te zu einer bestimmten Zeit ändert, um z. B. Großbuchstaben oder Sonderzeichen darzu stellen. Daher wurde der Typ layout eingeführt, welcher die Werte NORMAL, SHIFT, FN[18] für Objekte diesen Typs bereitstellt.
Somit stellen sie drei Zustände dar, sogenannte TastaturLayouts, in welchem jede Taste der Tastatur eine bestimmte Belegung vorweist. Aus diesem Grund ist das Konzept einer Tastatur als TastenArrays auf einen zweidimensionalen Array erweiterbar, wobei die erste Dimension das Layout und die zweite Dimension die Tasten dieses Layouts repräsentieren.
Zusätzlich existieren weitere „losgelöste“ Tasten, so wie z. B. die des Launcher Fensters für die Haupttastatur.
4.8.2.2 Grundlegender Code
Nach dem Verbindungsaufbau zum NanoX Server wird zunächst ein „F.i.le. d. e. s. c.r.ip. .to. r. “ zur SoftwareTastatur.P.ip. .e im Schreibmodus geöffnet. An diesen File des criptor können dann anschließend Daten geschrieben werden, die letztendlich Tasten drücke darstellen. Der NanoX Server übernimmt dabei die eigentliche Kommunikation mit der Hardware.
Hiernach werden nun die Graphiken für jede einzelne Taste[19] im normalen und ak tivierten (gedrückten) Zustand in den Speicher von der Festplatte geladen[20]. Dies wird so vollzogen, damit der anschließende Zugriff auf die Graphiken bei Tastendruck oder Layoutwechsel schnell geschehen kann, da ein Festplattenzugriff sehr viel mehr Zeit be nötigen würde.
Um Graphiken zu laden, wird die NanoX Funktion GrLoadImageFromFile ( const char* dateipfad, int flags ), welche ein Objekt vom Typ GR_IMAGE_ID zurückgibt, benutzt. Dieser Rückgabewert ist die ID der nun im Speicher befindlichen Graphik.[21] Die im zweiten Parameter angegebenen Flags spielen eine untergeordnete Rolle und werden deshalb mit 0 angegeben.
Wird ein Tastaturlayout gezeichnet, so werden alle Tasten zunächst auf einer soge nannten „P. i.x.m. .a.p.“[22] ausgegeben. Auf einer Pixmap können prinzipell alle Ausgabe und Zeichenmethoden genauso wie auf einem gewöhnlichen Fenster benutzt werden. Eine Pixmap ist jedoch nicht sichtbar, kann aber bei Bedarf „auf ein Fenster“ kopiert werden. Dadurch werden ihre gesamten graphischen Inhalte von dem Fenster, auf wel ches die Pixmap kopiert wird, übernommen. Eine Pixmap wird, wie ein gewöhnliches Fenster auch, durch den Typ GR_WINDOW_ID repräsentiert.[23]
GR_WINDOW_ID pixmap = GrNewPixmap(GR_SIZE, GR_SIZE, NULL);
Der erste Parameter stellt die Breite, der zweite die Höhe des neuen Pixmaps dar. Der dritte wird nicht verwendet und hat generell keine Bedeutung.
Nun können alle Tasten des Layouts traversiert und ausgeben werden, wozu folgen der Funktionsaufruf benutzt wird:
GrDrawImageToFit (GR_DRAW_ID, GR_GC_ID, GR_COORD, GR_COORD, GR_SIZE, GR_SIZE, GR_IMAGE_ID);
Der erste Parameter bezeichnet hierbei die Pixmap, der zweite und dritte Parameter die Position der Ausgabe, der vierte und fünfte die Breite sowie die Höhe des Auszuge benden und der letzte Parameter die ID der sich im Speicher befindlichen Graphik.
[...]
[1] Diese Graphik wurde http://www.ultratronik.de, der Ultratronik Webseite, entnommen.
[2]„Debian is a free operating system (OS) for your computer. Debian uses the Linux kernel (the core of an operating system), but most of the basic OS tools come from the GNU project; hence the name GNU/Linux.“ [Q6]
[3]Originalausrüstungshersteller
[4]Der eigentliche Quelltext eines Programmes ist nur einem kleinen Kreis von Entwicklern und Autori sierten bekannt ist.
[5]Kommando in dieser Form dem „Ultratonik Linux Distribution“Handbuch entnommen [Q7].
[6]Das NanoX Projekt trug einmal den Namen Microwindows. Es musste allerdings auf Verlangen eines größeren U.S.Amerikanischen Softwarekonzerns umbenannt werden, da dieser äußerte, dass ihr Betrieb system mit ähnlichem Namen mit dem ursprünglichen Namen des Projekts hätte verwechselt werden kön nen.
[7]Einstellungen dieser Art können in der Konfigurationsdatei config im src/Ordner des NanoX Quelltextes entnommen werden.
[8]Die beiden ausführbaren Dateien nanoX und nanowm sollten anschließend z. B. in das Verzeichnis /usr/bin kopiert werden, sodass diese global verfügbar sind.
[9]Soll dieser Prozess bei jedem Systemstart automatisch durchgeführt werden, so kann dies durch einen Eintrag in die Systeminitialisierungsdatei /etc/initab geschehen.
[10]expose <engl.> = anzeigen, aussetzen
[11]Verschiedenste Publikationen wurden zur Erstellung und Ausarbeitung dieses Teils herangezogen. Sie he dazu folgende Quellen im Quellenverzeichnis: [Q4, 3, 15, 18, 2].
[12]Im Folgenden soll die Abkürzung GK für graphischer Kontext verwendet werden.
[13]Einer Struktur ( struct) wurde mittels der typedefAnweisung ein Typenname zugeordnet.
[14]Zu vermerken ist, dass die Funktion GrSelectEvents(...) alle ausgewählten Ereignismasken des Fensters überschreibt, d. h. um Ereignisse hinzuzufügen, muss anders verfahren werden (siehe 4.7).
[15]Für eine genauere Erläuterung und eine Auflistung aller Ereignisstrukturen und deren Ereignistypen siehe Anhang B.1.2.
[16]So wie üblich bei gewöhnlichen NanoX Anwendungen.
[17]Für genaueres sollte der ausdokumentierte Quelltext des StateSavers konsuliert werden. Siehe dazu Anhang C.2.3.
[18] NORMAL stellt das „normale“ TastaturLayout dar, in welchem z. B. alle Buchstabentasten die Belegung von Kleinbuchstaben besitzen. SHIFT hingegen ist das Layout, in welchem die ShiftTaste betätigt wurde und FN ist die sogenannte Funktionstaste, mit welcher die Belegung der Tasten für Zahlen und Sonderzei chen ausgenutzt wird.
[19]Jede einzelne Tastengraphik hat die Ausmaße von 28x26 Pixel. Die Gesamttastatur ist so konzipiert, dass 11 Tasten in einer Reihe auf dem 320x240 Pixel großen Touchscreen angezeigt werden können. Die Graphiken der Tasten befinden sich im Unterverzeichnis dkbd/kbd.
[20]Man beachte die Statusanzeige während des Ladevorgangs beim Starten der Anwendung. Der Quell text dieses einfachen Ladebalkens kann dem Anhang C.3 entnommen werden.
[21]Um Graphiken auch wirklich mit NanoX anzeigen zu können, ist darauf zu achten, dass der NanoX Server mit den richtigen Einstellungen für das zu verwendende GraphikDateiformat kompiliert wurde. Da zu editiere man die Datei config im Microwindows SourceVerzeichnis vor dem Kompilieren und editiere die Einträge HAVE_<FORMAT>_SUPPORT = N, für das entsprechende Format, zu = Y.
[22]Der Typ GR_DRAW_ID steht für ein sogenanntes „Drawable“, d. h. ein NanoX Objekt, auf dem aus gegeben bzw. gezeichnet werden kann. Werden Variablen des Typen GR_WINDOW_ID an z. B. die Funktion GrDrawImageToFit(...) übergeben, so erfolgt ein impliziter Typcast.
[23]Pixmaps werden auch häufig als eine Art Framebuffer benutzt und eingesetzt.
-
-
-
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X. -
-
Upload your own papers! Earn money and win an iPhone X.