Dokumentation zu GEMLIB.A Geschrieben mit und fr Sozobon-C von Holger Weets benutzt wurde die GEMFAST - Bibliothek Version 1.31 Stand: 11.09.91, Version 2.0 Kurz-šbersicht: void fm_center(OBJECT *addr) void fm_mcenter(OBJECT *addr) void fm_sdial(OBJECT *addr) void fm_fdial(OBJECT *addr) void i_rmbut() void e_rmbut() void val_save(OBJECT *addr) void val_restore(OBJECT *addr, flag) int mousex() int mousey() int mousebut() void m_type(int maustyp) void m_arrow() void m_bee() void show_mouse() void hide_mouse() void ob_draw(OBJECT *addr, int index) char *gt_ptext(OBJECT *addr, int index) int fsel(char *name, char *titel) int fsel_e(char *name, char *titel, char *extension) int fsel_exinput(char *path, char *name, int *button, char *title) void sbitblt(int x1, int y1, int w, int h, int x2, int y2, int modus) void mbitblt(int x, int y, int w, int h, char *mem, int flag) int vwk_open() int vq_gdos() int dialog(OBJECT *addr) int adialog(OBJECT *addr) char *scr_save(OBJECT *addr) void scr_restore(OBJECT *addr, char *mem) Beschreibung der Funktionen: void fm_center(OBJECT *addr) Diese Funktion zentriert einen Objekt-Baum in der Mitte des Bild- schirmes. Da bei Verwendung der GEMLIB-Fnktionen die bei form_center() anzugebenen x/y/w/h - Koordinaten nicht ben”tigt werden, wurde diese Funktion implementiert. void fm_mcenter(OBJECT *addr) Diese Funktion richtet einen Objekt-Baum nach der Position der Maus aus. Wenn m”glich, erscheint der Dialog so auf dem Bildschirm, daž seine linke obere Ecke mit der Mausposition identisch ist. Es ist immer gew„hrleistet, daž der Dialog nicht aus dem Bildschirm hinaus- ragt und nicht in die Menue-Zeile rutscht. void fm_sdial(OBJECT *addr) Diese Funktion ist eine Kurzform von form_dial(FMD_START, ...) void fm_fdial(OBJECT *addr) Diese Funktion ist eine Kurzform von form_dial(FMD_FINISH, ...) int mousex() Diese Funktion liefert die X-Position der Maus. int mousey() Diese Funktion liefert die X-Position der Maus. int mousebut() Diese Funktion liefert den Zustand der Maustasten. Die drei letztgenannten Funktionen bedienen sich der Funktion graf_mkstate(). Sie haben den Vorteil, daž niemals berflssige Parameter bergeben werden, aužerdem verkrzt die Verwendung dieser Funktionen die Programml„nge. Die drei letztgenannten Funktionen wurden in Assembler geschrieben und befinden sich im selben Modul. Zusammen sind sie nur unwesentlich l„nger, als ein (!) Aufruf von graf_mkstate(). void i_rmbut() Diese Funktion installiert eine Funktion zur šberlistung von GEM, was die Abfrage der rechten Maustaste angeht. Insbesondere mit der evnt_multi() - Funktion ist es nicht m”glich, gleichzeitig die linke und die rechte Maustaste abzufragen. Diese Funktion behebt diesen Mangel: der multi() - Aufruf liefert zwar immer noch als Ereignis die linke Maustaste, jedoch kann die wirklich gedrckte Taste aus dem Wert der Variablen abgelesen werden: ist sie ungleich 0, so wurde die rechte Maustaste gedrckt, ansonsten die linke. Da fr die Installation der Routine das VDI ben”tigt wird, muž eine globale Variable existieren, in der das Handle der ge”ffneten Workstation steht. void e_rmbut() Diese Funktion ist das Gegenstck zu i_rmbut() und muž UNBEDINGT sp„testens am Ende des Programmes aufgerufen werden. Am Besten wie folgt vorgehen: . . i_rmbut(); event = evnt_multi(...); e_rmbut(); . . int vwk_open() Diese Funktion fhrt die Standard-Anmeldung beim VDI durch, indem eine virtuelle Workstation geoeffnet und deren Handle als Funktions-Ergebnis zurckgeliefert wird. Dieses Handle sollte in eine globale Variable geschrieben werden, damit das Abmelden am Ende des Programmes ordnungs- gem„ž ablaufen kann. int fsel(char *name, char *titel) Diese Funktion dient dazu, einen Dateinamen per Fileselectbox zu holen. Je nach Betriebs-System wird die jeweils neuste Fileselectbox benutzt, um den Dateinamen einzulesen. (Dazu muž AES mit appl_init() initiali- siert worden sein und somit in global[] Werte stehen) Der Default-Name wird in mitgegeben, in dieser Variablen wird auch der vollst„ndige Name der gew„hlten Datei zurckgeliefert. Der String in dient als šberschrift, bei der alten Fileselectbox wird er ber diese in einer weižen Box dargestellt, ansonsten direkt in ihr. Achtung: die Box-Attribute der Workstation werden ver„ndert. Exportiert werden die Variablen char pfad[] und char lastfile[] In steht der zuletzt verwendete Pfad, er wird ebenfalls ver- wendet, falls leer oder unvollst„ndig ist. Diese Variable wird berschrieben. In steht der zuletzt verwendete Dateiname, dieser wird verwendet, wenn leer ist. Auf diese Variable kann zugegriffen werden durch die Deklaration 'extern char lastfile[], pfad[];'. Zurckgegeben wird der gedrckte Knopf, also 1: OK 0: ABBRUCH int fsel_e(char *name, char *titel, char *extension) Funktioniert wie fsel(), nur daž hier zus„tzlich eine Endung mitgegeben wird (bei fsel() ist dies immer '*.*') Die Extension wird hierbei OHNE '*.' angegeben. Beispiel: fsel_e(name, "select file", "C") int fsel_exinput(char *path, char *name, int *button, char *title) Diese Funktion ersetzt die aus AESFAST, welche die Tests selbst durchfhrt, ob nun TOS >= 1.04 aktuell ist, und im negativen Fall eine Simulation der neuen Box mit der alten vornimmt. Damit w„re die Simulation bei Verwendung der fsel-Funktionen aus GEMLIB jedoch doppelt vorhanden! Da meine Simulation genauso gut funktio- niert, seine jedoch erheblich l„nger ist, habe ich ein neues Binding hierfr geschrieben. Alle betreffenden Programme sollten etwa 700 Bytes krzer werden (!) void ob_draw(OBJECT *addr, int index) Diese Funktion ist eine Kurzform von objc_draw(addr, index, 8, 0, 0, 0, 0); int dialog(OBJECT *addr) Diese Funktion fhrt einen vollst„ndigen Standard-Dialog aus. Der Dialog wird zun„chst zentriert und gezeichnet. Dann wird die AES-Funktion form_do() aufgerufen, und aus deren Ergebnis das Bit 15 (Kennzeichnung fr: Dialog wurde mit Doppelklick verlassen) ausgefiltert, die Abstrze wegen vergessener Abfrage auf dieses Bit geh”ren also der Vergangenheit an. Ist der Dialog beendet, so wird er (mit fm_fdial(), siehe dort) vom Bildschirm verbannt, sp„testens nach dem n„chsten redraw() ist er weg. Aužerdem wird der Status des Exit-Objektes, der vom GEM auf SELECTED gesetzt wird, wieder in den alten Zustand berfhrt. Zurckgegeben wird (natrlich) die Nummer des Exit-Buttons. int adialog(OBJECT *addr) Funktioniert wie dialog(), nur daž der Bildschirm-Hintergrund mittels scr_save() gerettet und mit scr_restore() (siehe dort) wieder- hergestellt wird, was bei Programmen, die mit Fenstern arbeiten, einen betr„chtlichen Geschwindigkeits-Vorteil bringt. char *scr_save(OBJECT *addr) Diese Funktion berechnet aus , welcher Teil des Bildschirmes durch daž Objekt verdeckt wrde, und rettet diesen. Hierzu wird ein entsprechend grožer Speicher per malloc() geholt und der Bildschirm- Ausschnitt mittels mbitblt() in diesen kopiert. Zurckgeliefert wird ein Zeiger auf diesen Speicherbereich. void scr_restore(OBJECT *addr, char *mem); Diese Funktion ist das Gegenstck zu scr_save(). Sie stellt den durch das Objekt verdeckten Bildschirm-Ausschnitt wieder her und gibt den dafr ben”tigten Speicher wieder frei. void sbitblt(int x1, int y1, int w, int h, int x2, int y2, int modus) Diese Funktion kopiert den rechteckigen Bildschirm-Ausschnitt (x1, y1, w, h) an die Bildschirm-Position (x2, y2, w, h), wobei der Verknpfungs-Modus ist (die Werte hierfr k”nnen z.B. im Profibuch oder im Programmierer-Lexikon nachgelesen werden). Diese Routine l„uft in allen Aufl”sungen und erwartet einen globalen Parameter namens , in dem das Handle einer virtuellen Workstation (open_vwk() ) steht. Aužer sind natrlich alle Parameter Pixel-Koordinaten, und be- nutzt wird die VDI-Funtion vro_cpyfm(). Das Maus ein- und aus-schalten ist in dieser Funktion bereits enthalten. void mbitblt(int x, int y, int w, int h, char *mem, int flag) Diese Funktion kopiert einen rechteckigen Bildschirm-Ausschnitt in den Speicher und umgekehrt. Ist ungleich 0, so wird der Bildschirm-Ausschnitt (x,y,w,h) an die Adresse kopiert (VORSICHT: an dieser Adresse muž gengend Speicher zur Verfgung stehen !!!) Wenn hingegen gleich 0 ist, dann wird der Speicherbereich ab in den Bildschirm-Ausschnitt (x,y,w,h) kopiert. Da sich VDI die ursprngliche Gr”že des im Speicher befindlichen BIT-Blocks nicht merkt, kommt es zu merkwrdigen Effekten, wenn die ursprngliche Breite nicht mit der aktuellen bereinstimmt. TIP: Breite und H”he in die ersten beiden Words des Speicherbereiches schreiben, und als Parameter dann *mem fr w, *(mem+1) fr h und mem+2 fr mem bergeben. Auch diese Funktion arbeitet in allen Aufl”sungen und erwartet einen globalen Parameter namens (Bedeutung siehe oben). Vor Aufruf dieser Funktion sollte die Maus ausgeschaltet werden, da sie sonst evtl. berschrieben bzw. mitkopiert wird. Das Maus ein- und ausschalten wurde hier untrlassen, damit sich diese Funktion auch zur Verwendung in USERDEF-Objekten eignet. void hide_mouse() Diese Funktion schaltet die Maus aus (graf_mouse()). void show_mouse() Diese Funktion schaltet die Maus ein. (graf_mouse()). Da GEM die Auf- rufe von M_OFF und M_ON mitz„hlt, mssen immer genausoviele show_mouse() Aufrufe get„tigt werden, wie vorher hide_mouse() Aufrufe gemacht wurden, damit die Maus wieder sichtbar wird. void m_type(int maustyp) Diese Funktion setzt den Mautyp per graf_mouse(). void m_arrow() Diese Funktion setzt das Aussehen der Maus auf die Pfeil-Form. void m_bee() Diese Funktion setzt das Aussehen der Maus auf die Bienen-Form. Die fnf letztgenannten Funktionen wurden in Assembler geschrieben und befinden sich alle im selben Modul. Dadurch sind alle Funktionen zusammen nur etwa so lang, wie zwei graf_mouse() - Aufrufe in C. void val_save(OBJECT *addr) Diese Funktion merkt sich die Zust„nde aller ver„nderlichen Objekte in einer Dialogbox. Es sind dies all diejenigen Objekte, bei denen entweder das SELECTABLE-, EXIT-, TOUCHEXIT- oder EDITABLE- Flag gesetzt sind. Bei editierbaren Objekten wird der zu editierende String kopiert ( aus dem TEDINFO), und bei den anderen Objekten wird der Wert von kopiert. val_save() wird im Zusammenhang mit der folgenden Funktion verwendet, um die Programmier-Arbeit, die fr die Umsetzung eines Abbruch-Knopfes n”tig ist (alle Žnderungen rckg„ngig zu machen), einzusparen. void val_restore(OBJECT *addr, int flag) Diese Funktion ist sozusagen das Gegenstck zu val_save(). Wird fr ein Wert ungleich 0 bergeben, so werden alle Žnderungen, die seit dem Aufruf von val_save() am Dialog per form_do durchgefhrt wurden, rckg„ngig gemacht. Wird zu 0 bergeben, so werden nur die Kopien der ver„nderlichen Objekt-Parameter gel”scht. Beispiel: Bisher sah eine Dialog-Routine etwa so aus: int merk1, merk2, ...; char t1[50], t2[50], ...; merk1 = Test[KNOPF1].ob_state; /* Knopf 1 merken */ merk2 = Test[KNOPF2].ob_state; /* Knopf 2 merken */ . . /*** Strings merken ***/ strcpy(t1, ((TEDINFO *)(Test[EDIT1].ob_spec)->te_ptext); strcpy(t2, ((TEDINFO *)(Test[EDIT2].ob_spec)->te_ptext); . . box_draw(Test); erg = form_do(Test, 0); box_undraw(Test); if (erg == CANCEL) { /* Shit: Abbruch... */ Test[KNOPF1].ob_state = merk1; Test[KNOPF2].ob_state = merk2; . . strcpy(((TEDINFO *)(Test[EDIT1].ob_spec)->te_ptext, t1); strcpy(((TEDINFO *)(Test[EDIT2].ob_spec)->te_ptext, t2); . . } Mit den beschriebenen Funktionen sieht das ganze so aus: val_save(Test); /* alle Werte retten */ box_draw(Test); /* Dialog zeichnen */ erg = form_do(Test, 0); /* ausfllen lassen */ box_undraw(Test); /* Dialog entfernen */ val_restore(Test, (erg == CANCEL)); /* alte Werte ggfls. */ /* wiederherstellen */ Man stelle sich die Code-Einsparung bei 20 solcher Funktionen mit jeweils 10 Kn”pfen und 5 Edit-Feldern vor ... char *gt_ptext(OBJECT *addr, int index) Diese Funktion liefert einen Zeiger auf das Textfeld in der TEDINFO- Struktur des Objektes addr[i], ist also eine Kurzform von p = ((TEDINFO *)addr[i].ob_spec)->te_ptext Die Funktion hat den Vorteil der besseren Lesbarkeit und macht Programme, die h„ufig TEDINFO's auslesen, krzer. int vq_gdos() Diese Funktion testet, ob GDOS installiert ist, oder nicht. Falls nicht, so liefert sie 0, einen Wert ungleich 0 sonst. Diese Funktion ist unver„ndert aus dem Profibuch bernommen worden.