Hallo,
Ich meine nicht das der Con-Server die Fenster zeichnet, sondern dass er sich um die ganzen Sachen kümmert die ein GUI-App so machen muss.
Was soll der Con-Server denn sein? Entweder die Benennung ist falsch oder ich kann nicht nachvollziehen, was er tun soll.
Entweder er kümmert sich um den Textmodus, oder er kümmert sich um den Textmodus und die Kommunikation mit dem GUI-Server. In letzterem Falle ist das Design kaputt. Oder soll er im Textmodus einen Textmodus-Treiber besitzen (und die Grafikkarte ansteuern und das Terminal bereitstellen und Escapesequenzen verarbeiten) und im Grafikmodus ein Terminalemulator sein (der dem GUI-Server sagt "mach ein Fenster", dadrin selbst die Zeichen malt, ein Terminal bereitstellt und die Escapesequenzen verarbeitet)?
Das ist unelegant, weil du damit den Terminalemulator auf exakt den gleichen Terminaltyp beschränkst, wie den Textmodus-eigenen und außerdem müsste dein Con-Server dann zusätzlich noch Ahnung von Grafik UND vom GUI-Server haben. Damit baust du Abhängigkeiten so zusammen, dass du später die einzelnen Module nicht mehr ersetzen kannst (was ja ein Hauptvorteil von meinem System ist). Plus: Der Con-Server wird wesentlich komplexer.
Sprich es kommt ne Msg vom GUI-Server das mit der Maus in das Fenster geklickt wurde, diese Msg soll dann vom Con-Server bearbeitet werden usw. (was es da halt noch so alles an Msgs geben kann z.B. Fenstergröße hat sich geändert).
Der GUI-Server sollte sich um die Fenster kümmern, nicht der Con-Server. Außerdem sollte der Input-Server seine Daten an den Server senden, der gerade für den Bildschirm zuständig ist - also entweder den Con-Server, wenn du im Textmodus bist, oder dem GUI-Server, wenn du im Grafikmodus bist.
Diese ganze GUI-App Geschichte würde ich halt am liebsten von einem Terminal-Emulator fern halten, damit der im Textmodus und im Grafikmodus benutzt werden kann ohne das er sich darum selber kümmern muss.
Ist deine Entscheidung. Genau das würde ich anders lösen - der Terminalemulator ist eine GUI-App.
Ich stelle mir den Terminal-Emulator so vor, das der Stdout zum Con-Server (oder GUI-Server) schickt und als Stdin bekommt er Daten von der Shell/dem Textmodus-App. Das einzige was er (der Emulator) machen soll ist die Escape-Sequenzen zu übersetzen, mehr nicht und dann kann er nämlich einfach als Vermittler im Text- und im Grafikmodus eingesetzt werden.
Also dein Textmodus (d.h. Con-Server) sollte garkeinen Terminalemulator besitzen, sondern direkt ANSI o.ä. implementieren. Das ist dann eine solide Basis, die auch gut auf die vorhandenen Hardwaremöglichkeiten mappt.
Im GUI sind zuviele Sachen anders, daher solltest du den Textmodus vom Grafikmodus vollständig trennen. (Du kannst ja meinetwegen eine von beiden Servern verwendete Lib bauen, die ANSI spricht.) Der Terminalemulator ist dann eine Anwendung für den Grafikmodus, der ein Terminal emuliert (daher der Name). Beide Terminaltypen (im Text- oder im Grafikmodus) sind übrigens nicht identisch: Im Grafikmodus kannst du vt100-Features wie doppeltbreite Schriftzeichen, fett, unterstrichen usw. verwenden, die du im Textmodus garnicht implementieren kannst.
Zumal dein GUI-Server sich primär um die GUI kümmern sollte und nicht um Textmodusprogramme. Das ist Aufgabe des Terminalemulators. Und dein Con-Server hat sich gefälligst um den reinen Textmodus zu kümmern und nicht um Textanwendungen, die in einem Fenster (verantwortlich: GUI-Server fürs Fenster, Terminalemulator für den Text dadrin) laufen. Das hängt vor allem mit dem Rendering zusammen, denn rendern tun entweder die Anwendungen selbst oder aber der GUI-Server. Niemand sonst.
Solch eine Flexibilität wäre halt net bzw. Wiederverwendbarkeit.
Naja, wenn du eine ANSI-Schnittstelle implementierst, dann kannst du die an beiden Stellen verwenden.
Außerdem kämpfen dann nicht zwei Server um begrenzte Ressourcen (Con-/GUI-Server kämpfen sonst um Tastatur und Bildschirm) - es ist nur einer zuständig.
Deswegen ja die Anmeldesequenz des GUI-Servers. Der meldet sich beim Input-Server, dass er jetzt zuständig ist und nicht mehr der Con-Server und dem Con-Server sagt er das auch nochmal (bzw. (siehst du das dann weiter unten) "ersetzt" er den Con-Server für den Textmodus mit dem Con-Server für den Grafikmodus).
Warum so kompliziert? Erstens sind dann Textmodus und Grafikmodus voneinander abhängig und zweitens muss dein Con-Server, der ja nur für den Textmodus zuständig sein sollte, auch noch Ahnung vom Grafikmodus haben. Wie willst du später TrueType-Fonts rendern - soll das auch der Con-Server machen? Da mappen dann Zeichenanzahlen nicht mehr auf Pixelbreite, was du bei jedem Textmodusprogramm aber als gegeben annehmen kannst. Du würdest den GUI-Server zur Fensterverwaltung und den Con-Server zum Rendering einsetzen, das ist doof.
Ich weiß nicht wie das unter Linux läuft, aber unter Windows funktioniert es das man einfach nen Doppel-Klick auf nen Textmodus-App macht und dann öffnet sich ne Textkonsole (im Hintergrund läuft dann unter W7 conhost.exe, glaub ich).
Unter Linux öffnet sich da nichts. stdin/stdout werden auf /dev/null gemappt, fertig. Bei Windows wird automatisch ein Terminalemulator geöffnet. Das kannst du halten, wie du möchtest.
Deswegen überlege ich halt wie ich das am besten Umsetze, da so eine Funktionalität schon nicht schlecht wäre, ich das aber auch gerne schon vorher geplant haben will, damit ich nachher nicht nen Rewrite machen muss.
Hatte ich beschrieben, du öffnest ein Fenster, wenn ein Textmodusprogramm ohne vorhandenes Fenster (also mit dummy-stdout) etwas ausgibt...
Wenn ich deine Variante umsetze, dann muss ich im Grafikmodus immer erst nen Terminal-Emulator öffnen damit ich ein Textmodus-App ausführen kann (und auch was sehe) und dieser muss sich bewusst sein das er gerade im Grafikmodus läuft und das er dann die ganzen Fenster-Msgs handlen muss.
Genau das ist Aufgabe eines Terminalemulators. Er ist kein Terminal, er emuliert eins. Außerdem ist der Terminalemulator ein Grafikprogramm und funktioniert ohne Grafikmodus garnicht erst. => Eingabeaufforderung oder xterm.
(Was mir in dem Zusammenhang noch einfällt, hat man unter Linux eigentlich ne Umgebungsvariable wo drinsteht welche Shell benutzt werden soll? Weil die müsste ja immer vom Terminal-Emulator mitgestartet werden.)
Wird sie auch. Entweder es wird die Standardshell des Benutzers verwendet (steht in /etc/passwd) oder es wird im Terminalemulator eine Anwendung konfiguriert (bei xterm mit "-e").
In dem Moment, wo du den GUI-Server startest, sollte dieser inklusive aller enthaltenen Anwendungen beendet werden, da der GUI-Server einen eigenen Grafiktreiber lädt.
Das hätte ich dann halt so lösen wollen, das der Con-Server dann (deswegen soll sich der GUI-Server beim Con-Server anmelden) für jede laufende Terminal-Emulation ein Konsolenfenster aufmacht und die Programme da drin dann einfach weiterlaufen als wäre nichts gewesen (deswegen auch Doublebuffering in Software).
Unhandlich, weil dann dein Con-Server (a) was von Grafik verstehen muss (b) mit dem GUI-Server kommunizieren muss.
Du könntest allerdings eine Schnittstelle definieren, über die der Con-Server bei seinem Ende sämtliche stdin/stdout/stderr-Tripel an den GUI-Server übermittelt und der sich dann darum kümmert, dass dafür neue Fenster geöffnet werden. Oder auch nicht, wenn bestimmte Programme nur im Hintergrund laufen und eh kein Fenster kriegen sollen (z.B. das Textmodus-Uhrzeit-Widget, was oben rechts die aktuelle Uhrzeit anzeigt - dafür brauchts kein Fenster).
Mein Problem ist einfach das ich den Con-Server gerne so gestalten würde, dass er keinen Code hat der was mit dem Grafischenmodus zu tun hat, aber ich will auch nicht das der GUI-Server sich um alles was mit nem Konsolenfenster zutun hat kümmern muss.
Das Konsolenfenster ist für den GUI-Server ein Fenster wie jedes andere und für das System eine Anwendung wie jede andere. Was da
drin ist, ist Aufgabe des Terminalemulators. Fertig.
Der GUI-Server soll einfach nur Fenster verwalten und er soll zu jedem Fenster (ob nun Konsolenfenster oder "normales" Fenster) einen "Ansprechpartner" haben und genau den habe ich halt für Konsolen-Apps noch nicht gefunden.
Wer wäre es denn für nicht-konsolen-Apps?
Der Terminal-Emulator (wie oben geschrieben) soll einfach nur die Escape-Sequenzen übersetzen mehr nicht! Stell dir den Terminal-Emulator wie nen Druckertreiber vor, der keine "Ausgabe" (in dem Sinne das er nen Fenster oder sowas bräuchte) macht, sondern einfach nur von einer Sprache in eine andere Übersetzt.
Er soll also ANSI/vt100 in ... ja, in was eigentlich übersetzen? Im Textmodus in VGA-Speicherzugriffe und im Grafikmodus in Anweisungen für den GUI-Server? Würde ich trennen.
Das hätte auch den Vorteil, das ich dann einfach nur nen Doppel-Klick auf nen Terminal-Emulator machen muss (der so auch im Textmodus funktioniert) und der halt als Stdout ne Leitung zum Con-Server bekommt und ein neues Fenster aufgeht bzw. im Textmodus, würde dann halt ne neue virtuelle Konsole "aufgehen".
Definier lieber ein Protokoll zur korrekten Übergabe von Textanwendungen von einem Server zum anderen. Zumal du eh nur einen Server zu jedem Zeitpunkt aktiv hast (deine Grafikkarte kann gleichzeitig nur entweder Text oder Grafik ausgeben, außerdem ist das Umschalten bei speziellen Grafiktreibern schwierig) und du wahrscheinlich zwar viel mit Textanwendungen in Terminalemulatoren arbeitest (xterm, Eingabeaufforderung), aber eher selten gleichzeitig(!) noch mit Fullscreen-Textmodusanwendungen arbeitest (unter Windows nicht möglich, da es keinen Textmodus gibt; unter Linux wären das die 6 virtuellen Terminals auf Strg+Alt+F1-F6, auf der 7 läuft meist der X-Server).
Das ganze würde jetzt darauf hinauslaufen, das ich einen Con-Server für den Textmodus habe (wo ich mir auch noch nicht sicher bin, wie dieser mit dem VGA-Treiber/Textmodus-Treiber kommuniziert) und einen Con-Server für den Grafikmodus habe, welcher dann halt dem GUI-Server sagt, dass er nen neues Fenster braucht und das sich dieser Con-Server (für den Grafikmodus) dann um die ganzen Msgs, die da so vom GUI-Server kommen, kümmert.
Dann mach einen Con-Server, der ausschließlich Textmodus macht und den VGA-Textmodus-Treiber gleich integriert hat und einen GUI-Server, der sich ausschließlich um den Grafikmodus kümmert und den VGA-Grafikmodus-Treiber integriert hat und einen Terminal-Emulator, der Textmodus auf einer grafischen Oberfläche emuliert.
Was hat der Con-Server denn mit der GUI zu tun? Ist das Entgegennehmen von Tastendrücken und Mausbewegungen nicht eher Aufgabe vom Terminalemulator?
Naja, das sollte der Input-Server tun, die Ereignisse werden dann vom GUI-Server durchgekaut und an den Terminalemulator weitergereicht.
Wie ich es mir am Anfang vorgestellt hatte, und wie ich denke, dass es Sinn ergibt, ist, dass der Con-Server sozusagen ein Textmodus-Terminalemulator mit eingebautem Textmodus-Grafiktreiber ist.
So meinte ich das.
Ich will mir halt "ersparen" 2mal den selben Code zu schreiben. Deswegen soll der Terminal-Emulator ja auch nur so "wenig" können.
Du hast im Grafikmodus aber wesentlich mehr Möglichkeiten, die eine eigene Implementation rechtfertigen können ("unterstrichen" geht bei VGA-Karten nunmal nicht).
Der Con-Server hätte halt eine allgmeine "Sprache" in die übersetzt werden muss und der Con-Server verwaltet die ganzen Konsolen, sprich er weiß welche gerade im Vordergrund ist und leitet die Daten vom Intput-Server entsprechend weiter und er macht das ganze Double-Buffering.
Oh, eine allgemeine Sprache. Noch eine. Warum nicht ANSI? Alle Anwendungen sprechen ohnehin ANSI (oder lassen sich mit ncurses so konfigurieren) und wenn dein Terminal nur ANSI versteht, dann reicht das doch aus. Du müsstest in dem Moment nur zwei Übersetzer bauen: ANSI=>VGAText und ANSI=>Framebuffer. Das erste macht dein Con-Server, das zweite macht dein Terminalemulator (der Fensterinhalt selbst ist ja ein Framebuffer mit z.B. 200x150px). Ich bezweifle, dass du da großartig Code teilen kannst.
Das ist der Terminalemulator, ein ganz normales GUI-Programm.
Und genau das will ich halt so nicht machen. Für mich soll der Terminal-Emulator immer nur eine Art Übersetzer sein, nicht mehr und nicht weniger.
Dann nenn ihn anders. Ein Terminalemulator ist ein GUI-Programm, welches in seinem Fenster ein Terminal emuliert. Nicht weniger.
Der Terminal-Emulator soll von z.B. vt100 in eine allgemeine vom Con-Server unterstützte "Sprache" übersetzen. So halte ich mir halt die Möglichkeit offen noch andere Sachen als vt100 zu unterstützen ohne das ich das alles in ein Programm packen müsste. Ob das sinnvoll ist sei erstmal dahin gestellt.
Ist es nicht. Deine Anwendungen sprechen durch die Bank weg ANSI/vt100 und das musst du darstellen. Wenn du plötzlich Anwendungen hast, die IBM3270 sprechen, dann musst du die auch darstellen. Also schreibst du am besten einen Wrapper von IBM3270 auf ANSI (was u.U. nur mit Einschränkungen möglich ist) oder aber du verzichtest für den VGA-Textmodus/Con-Server auf diese Möglichkeit. Für den Grafikmodus schreibst du dir dann einen Terminalemulator (die App!), welcher IBM3270 in sein Fenster rendert, weil dort kannst du es komplett flexibel machen. Und es dann als App umzusetzen, ist ohnehin sinnvoller.
Bedenke, dass du außer ANSI eigentlich nichts brauchst. Alle halbwegs modernen Textmodusanwendungen sprechen ANSI und etwas Neues wird es in dem Bereich nicht mehr geben, da der Textmodus durch den Grafikmodus ersetzt wurde. Windows unterstützt bis heute nur ein halbfertiges ANSI plus eine unvollständige Implementation der VGA-Textmodusregister in den Eingabeaufforderungen.
[...]
Ich hoffe du kannst jetzt meine Motivation für dieses "Design" nachvollziehen.
Ja, und ich halte es für relativ kompliziert, mit schlecht abgesteckten Aufgabenbereichen. Und vor allem zugeschnitten auf Textanwendungen, also unflexibel.
Ich kann verstehen, dass du "alles" anders machen möchtest als der Rest, aber manche Sachen sind halt einfach sinnvoll, wie sie anderswo eingesetzt werden.
Gruß,
Svenska