%format latexg
%
%   Anleitung zu RUBY
%
%   Copyright (C) 1991, 1992 by Markus M. Nick

\documentstyle[german, din_a4]{report}
\newenvironment{maxipage}{}{}   % wenn kein refman oder mnreport vorhanden
\newenvironment{fullpage}{}{}   % wenn kein refman oder mnreport vorhanden
\newlength{\fullwidth}\fullwidth\textwidth % wenn kein -"- vorhanden

%%\documentstyle[german,refman]{report}

%%\documentstyle[german]{mnreport}

\ifx\MNReport\undefined      % kein MNReport.sty vorhanden?
    % Pech...  Aber man kann ja Abhilfe schaffen
    \def\Chapter#1{\chapter{#1}}
    \def\Subchapter#1{\section{#1}}
    \def\Section#1{\subsection{#1}}
    \def\Subsection#1{\subsubsection{#1}}
\else
    % Sie haben MNReport.sty -- wie das?
\typeout{Wie kommen Sie zu MNReport.sty, wenn Sie nicht gerade ic, rs oder %
mmn sind?}
    \def\Chapter#1{\chapter{#1}}
    \def\Subchapter#1{\subchapter{#1}}
    \def\Section#1{\section{#1}}
    \def\Subsection#1{\subsection{#1}}
\fi
 
\def\ruby{{\bf Ruby}}
\def\Ruby{Ruby}    % f�r �berschriften
\def\ltmf{{\bf Let~'em~Fly!}}

\newfont{\VeryHuge}{cminch scaled 1000}

\title{\VeryHuge RUBY \\ \large Yet Another Gem}
\author{\copyright\ 1991, 1992 Markus M. Nick}
\date{29.02.92}

\pagestyle{headings}
\sloppy

\begin {document}

% new commands

\newcommand{\cw}[1]{{\tt #1}}
\newcommand{\key}[1]{{\tt [#1]}}
\def\skey#1#2{{\tt [#1][#2]}}

% Titelblatt

\begin {fullpage}
\maketitle
\end {fullpage}


\tableofcontents


%% Die Einleitung %%

\Chapter{Einleitung}
Es ist soweit.  \ruby{} ist fertig.  F�r die, die noch nicht wissen, was 
\ruby{} ist, hier ein kurzer �berblick �ber die Features:
\begin{itemize}
\item \ruby{} setzt Resource-Format der My/Fly/MagicDials f�r \ltmf{} um, 
d.h. die Dialoge fliegen �ber \ltmf{} und die Checkboxes etc. stammen {\em 
direkt}\/ von \ruby{}.
  \item Spezielle Object-Typen:
  \begin{itemize}
    \item Checkboxes, runde Radiobuttons
    \item tastaturbedienbare Buttons (�ber \ltmf{})
    \item unterstrichener Text
    \item Circle-Button f�r Popups
    \item Undo-Button, Help-Button
    \item Eselsohr (Flugecke)
  \end{itemize}
\item Ruby beinhaltet Funktionen f�r ein �u�erst simples Popup-Handling.
\item \ruby{} ist zus�tzlich noch erweiterbar, d.h. Sie k�nnen selbst 
zus�tzliche Objekttypen definieren u.�.
\end{itemize}

"`Nicht schlecht sprach der Specht, aber WAS soll das?"' werden Sie nun 
vielleicht fragen.  Nun --- wer in seinen Programmen \ltmf{} 
unterst�tzen bzw. nutzen m�chte, erh�lt mit \ruby{} eben noch runde 
Radiobuttons etc. Der Vorteil ist, da� der Overhead f�r das Fliegen, die 
Keydials usw. nur einmal im System liegt --- n�mlich bei \ltmf{}.  Wenn nun 
Oliver Scheel sein \ltmf{} verbessert (z.B. den Extended Editor), dann n�tzt 
das allen Programmen, die \ltmf{} nutzen {\em ohne}\/ den Umweg �ber ein 
zus�tzliches Update.

L��t man ein Programm, das mittels \ruby{} \ltmf{} nutzt, ohne \ltmf{} 
laufen, dann k�nnen die Dialoge eben nicht fliegen und sind nicht 
tastaturbedienbar (Shortcuts f�r Buttons fallen weg). Wer also auf den 
Komfort des Fliegens und der erweiterten Tastaturbedienung verzichten 
will, weil er vielleicht noch 25~KByte mehr Speicher ben�tigt, mu� er 
trotzdem nicht auf das gewohnte Erscheinungsbild des Programms 
verzichten.

Manche halten mehr von Programmen, die diese Features fest eingebaut haben 
(GEMINI, Rufus, Interface).  Allerdings --- jedes Programm, das z.B. 
Tastaturbedienung und einen Extended Editor fest eingebaut hat, unterscheidet 
sich in der Bedienung der Edit-Felder und anderen Dingen sicherlich von 
Programmen, die eine andere Library verwenden.

%W�rde Oliver Scheel beispielsweise ein ge�ndertes \ltmf{} ver�ffentlichen, 
%in dem tastaturbedienbare Buttons statt �ber [Alt]+Taste �ber 
%[Control]+Taste angesprochen werden, dann �ndert sich das in jedem Programm, 
%das sich auf \ruby{} und damit auf \ltmf{} st�tzt. Der User w�rde das zu 
%w�rdigen wissen.

Im Sinne einer Vereinheitlichung ist das Ausnutzen der Features von 
\ltmf{} auf jeden Fall die bessere L�sung.  Der Overhead durch \ruby{} 
betr�gt lediglich 5~KByte pro Programm. 

\ruby{} ist als Library f�r \ltmf{} gedacht. Am besten sieht man \ltmf{} 
als Betriebssystemerweiterung und Ruby als komfortable Library dazu, 
wobei es auch ohne \ltmf{} l�uft --- nur eben mit weniger Komfort.

Da es sowohl \ruby{} als auch \ltmf{} als Freeware gibt und \ruby{} auch 
f�r kommerzielle Software verwendet werden darf, sehen Oliver Scheel und 
ich keine Gr�nde, diese Kombination aufzugeben. Die Gr�nde daf�r sind 
mehr philosophisch zu sehen (wie oben aufgef�hrt).  Jeder ist herzlich 
dazu eingeladen, dieser Philosophie in seiner Software zu folgen.

Viel Spa� und wenig Probleme mit \ruby{} w�nscht Ihnen\\
\hspace*{10em}Markus M. Nick


%% Lizenzbedingungen %%

\Chapter{Lizenzbedingungen}
\ruby\ ist Freeware. Sie d�rfen \ruby\ frei kopieren und weitergeben. Der 
Verkauf von \ruby\ oder der Vertrieb �ber PD-Versender ist ohne die 
schriftliche Genehmigung des Authors nicht gestattet. Die Verbreitung 
�ber Mailboxen und BBSe ist gestattet, wenn f�r den Download keine 
gesonderte Geb�hr erhoben wird. Zuwiderhandlungen werde ich 
strafrechtlich verfolgen!

F�r von \ruby{} abgeleitete Derivate gilt das gleiche.

\ruby{} mu� immer komplett weitergegeben werden.  In der Datei 
\verb|READ_ME| finden Sie eine Liste aller Dateien, die zu \ruby{} 
geh�ren.

Unter den folgenden Bedingungen k�nnen Sie \ruby\ in Ihre Software 
einbinden:
\begin{itemize}
\item Im Programm und in der Dokumentation zum Programm mu� darauf 
hingewiesen werden, da� \ruby\ verwendet wurde.
\item Es mu� darauf hingewiesen werden, da� weder \ruby\ noch dessen Autor f�r 
das Layout der Dialoge des Programms verantwortlich ist (Entbindung von dieser 
Pflicht auf Anfrage). 
\end{itemize}

\Subchapter{Verwendung von \Ruby{} in kostenpflichtiger Software}
Wenn Sie \ruby{} in Software verwenden m�chten, die Geld einspielen soll, d.h. 
kommerzielle Produkte, aber auch Shareware und Freeware, f�r die Geld verlangt 
wird, ist die Verwendung von \ruby{} beim Autor anzuzeigen (Brief/Postkarte 
oder E-Mail mit Adresse und Telefonnummer und kurzem Produktinfo gen�gt).

Weitere Bedingungen sind daran nicht gekn�pft.  �ber eine angemessene Spende 
und/oder die Zusendung der Software selbst w�rde ich mich sehr freuen. 
 Ggf. kann ich Ihnen auch eine Rechnung �ber den gespendeten Betrag 
ausstellen.

Wenn Ihnen durch \ruby{} Probleme entstehen, lassen Sie es mich wissen. 

\begin{tabular}{ll}
    \underline{Postanschrift:}  &   \underline{Bankverbindung:} \\
    Markus M. Nick              &   Sparda-Bank Mainz e.G. \\
    Hinter der Kirche 20        &   BLZ 550 905 00 \\
    W-6500 Mainz 41             &   Konto-Nr. 604 581 \\
    Germany                     &   \\
 \\
  \underline{Telefon:}    &  \underline{E-Mail:} \\
  (Germany)--6136--45647  &  \verb|Markus_Nick @ MZ| \quad  (im Mausnet) \\
  ({\em NIE} vor 11 Uhr)  &  \verb|Markus_Nick@mz.maus.de| \quad (im 
Internet)
\end{tabular}

Wenn Sie keinen Servicevertrag (siehe unten) abgeschlossen haben, legen Sie 
bei Anfragen aller Art bitte immer einen frankierten und adressierten {\em 
R�ckumschlag} bei (ggf. auch eine Diskette).  Ich bitte um Verst�ndnis, da� 
ich nicht auch noch die Portokosten tragen kann, da \ruby{} ja Freeware ist -- 
in gewissem Sinne auch "`Free Software"'.


\Subchapter{Source, Service und Updates}
Sind Sie am Source, an automatischen Updates, Benachrichtigung bei Updates 
und/oder Serviceleistungen interessiert, dann wenden Sie sich bitte an mich. 
 Gegen eine Geb�hr o.�. ist auch dies m�glich.

Um die Konsistenz der verf�gbaren Versionen von \ruby{} zu gew�hrleisten, 
m�chte ich den Source nicht v�llig freigeben.  Sollte ich jedoch eines Tages 
das System wechseln, also alle meine STs verkaufen oder verschrotten [\dots], 
wird der Source zuvor freigegeben werden.

Sollten Sie einen Compiler besitzen, der keines der bereitgestellten 
Object-Files lesen kann, dann kontaktieren Sie mich bitte. Ich bin 
sicher, da� wir einen Weg finden werden.

\Subchapter{Dementi}

Da \ruby{} frei ist, gibt es keine Haftung jeglicher Art f�r \ruby{}. 
 \ruby{} wird so geliefert, wie es ist, ohne jede Haftung, weder 
implizite oder explizite, einschlie�lich, ohne Einsch�nkung, der Haftung 
f�r die Zweckm��igkeit und Verwendungst�chtigkeit f�r einen bestimmten 
Zweck.  Das gesamte Risko bzgl. Quali�t und Performance von \ruby{} liegt 
bei Ihnen, verehrter Anwender.  Sollte \ruby{} M�ngel irgendeiner Art 
aufweisen, so tragen Sie die alle n�tigen Kosten f�r Service, Reparaturen 
und Korrekturen.

Sie k�nnen den Autor in keinem Fall f�r irgendwelche Sch�den zur 
Verantwortung ziehen, weder im allgemeinen noch im speziellen oder 
zuf�lligen Fall, oder bei Folgesch�den oder solchen die aus der 
Unt�chtigkeit von \Ruby{} f�r einen bestimmten Zweck oder in 
Zusammenarbeit mit anderer Software entstehen -- selbst dann nicht, wenn 
Sie vom Autor oder anderen Personen darauf hingewiesen wurden.

Kurzum, jede Verantwortung f�r die Verwendung und Anwendung von \Ruby{} 
liegt bei Ihnen, lieber User.

Mit "`\ruby{}"' ist die komplette Distribution gemeint, die in der Datei 
\verb|READ_ME| aufgelistet ist, d.h. alle Sourcen, Header, Objekt-Dateien, 
Libraries sowie die Dokumentation und die speziellen Hinweis-Texte.

Anmerkung: Bei Servicevertr�gen lauten die Bedingungen etwas anders.  Der 
Autor tr�gt in diesem Fall die Kosten f�r den Updateservice von \Ruby{}.



%% Verwendung von Ruby in eigenen Programmen %%

\Chapter{Verwendung von \Ruby}

Um \ruby{} zu verwenden, sollten Sie den Header \verb|ruby.h| includen.

Ich empfehle Ihnen, eine Kopie des Beispielprogramms anzulegen und mit dieser 
zun�chst ein wenig zu experimentieren.  Schauen Sie sich auch den Source an. 
 Er zeigt, wie man ganz einfach mit Popup-Men�s umgehen kann.


%% Zus�tzliche Objekttypen %%

\Subchapter{Zus�tzliche Objekttypen}
Alle zus�tzlichen Objekttypen werden �ber das Highbyte des Elements 
\cw{ob\_type} der Struktur \cw{OBJECT} eingestellt. In 
Resource-Construction-Sets kann man diese �ber Felder mit Namen wie 
"`erweiterer Objekttyp" einstellen.

Folgende erweiterte Objekttypen sind verf�gbar:
\begin{description}
  \item[17 -- \cw{XG\_FLYBUTTON}] Kennzeichnet ein Objekt mit exklusiven 
"`Flugrechten"'. Maximal ein Objekt pro Formular kann ein 
\cw{XG\_FLYBUTTON} sein.

Ist das Objekt vom Typ \cw{G\_IBOX} und als \cw{OUTLINED} und \cw{SHADOWED} 
gekennzeichnet, wird es durch ein Eselsohr ersetzt.

  \item[18 -- \cw{XG\_BUTTON}] Der besondere Edelstein in \ruby. Hierunter 
verstecken sich gleich drei Typen von Kn�pfen:

  \begin{description}
    \item[Runder Radiobutton:] Hierbei handelt es sich um die mittlerweile 
auch auf dem ST/TT recht verbreiteten runden Radiobuttons, die man ja vom 
Macintosh her kennt.  Man kreiert dazu -- wie �blich -- einen Radiobutton 
(\cw{SELECTABLE} und \cw{RBUTTON}) kennzeichnet ihn dann mit dem 
\verb|Xob_type|~18.
    \item[Ankreuzfeld:] Das Ankreuzfeld ist ebenfalls schon recht verbreitet. 
 Man legt einfach einen normalen Button an und kennzeichnet ihn als 
\cw{SELECTABLE} und mit dem \verb|Xob_type|~18.
    \item[Keybutton:] Das ist ein Exit-Button mit oder ohne Shortcut.  Man 
legt einfach den Button an und kennzeichnet ihn mit \cw{SELECTABLE}, \cw{EXIT} 
und dem \verb|Xob_type|~18.  Setzt man zus�tzlich \verb|ob_flags| \#11 
(\verb/ob_flags |= 0x0800/), so wird dadurch der Default-Abbruch-Button 
gekennzeichnen, der auch mit der Taste \key{Undo} selektiert werden kann.
  \end{description}
Diese Kn�pfe k�nnen mit den konventionellen Objekt-Typen \cw{G\_BUTTON}, 
\cw{G\_STRING}, \cw{G\_TEXT} und \cw{G\_BOXTEXT} verkn�pft werden. Beachten 
Sie bitte, da� die Kn�pfe alle zumindest entweder \cw{SELECTABLE} oder 
\cw{TOUCHEXIT} sein m�ssen.

Um einen Button mit einem {\em Shortcut} zu belegen, setzt man einfach vor den 
gew�nschten Buchstaben im Button-Text ein '['.  Zum Beispiel $$\mbox{\tt 
T[oll}$$ bewirkt, da� die Kombination \skey{Alt}{O} den Button selektiert (und 
deselektiert).
  \item[21 -- \cw{XG\_HELPBUT}] entspricht \cw{XG\_BUTTON}, wobei der Knopf 
exklusiv mit der Taste \key{Help} belegt wird.
  \item[31 -- \cw{XG\_UNDOBUT}] entspricht \cw{XG\_BUTTON}, wobei der Knopf 
exklusiv mit der Taste \key{Undo} belegt wird.
  \item[19 -- \cw{XG\_TITLE}:] Unterstrichener Text. Der Text wird auf der 
Breite der umrandenden Box unterstrichen.
  \item[20 -- \cw{XG\_BOXTITLE}:] Box mit Titeltext, der auf dem Rahmen 
steht.
  \item[22 -- \cw{XG\_POPUP}] Circle-Button f�r Popups.
\end{description}

Soweit keine Einschr�nkungen angegeben sind, k�nnen die neuen Objekttypen 
nach Belieben mit den konventionellen (\cw{G\_BOX}, \cw{G\_BUTTON}, 
\cw{G\_TEXT} usw.) verkn�pft werden.

\begin{maxipage}
\begin{minipage}{\fullwidth}
\begin{tabular}{|l|cl|l|l|}
\hline
Bedeutung & \multicolumn{2}{c|}{\cw{Xob\_type}\footnote{erweiterter 
Objekttyp}} & \cw{ob\_flags} & \cw{ob\_state} \\
\hline
Eselsohr & 17 & \cw{XG\_FLYBUTTON} & \cw{TOUCHEXIT} & \cw{CROSSED|OUTLINED} 
\\
Exklusives Flugobjekt & 17 & \cw{XG\_FLYBUTTON} & \cw{TOUCHEXIT} & \\
EXIT-Keybutton & 18 & \cw{XG\_BUTTON} & \cw{EXIT|SELECTABLE} & \\
TOUCHEXIT-Keybutton & 18 & \cw{XG\_BUTTON} & \cw{TOUCHEXIT} & \\
Runder Radiobutton & 18 & \cw{XG\_BUTTON} & \cw{RBUTTON|SELECTABLE} & \\
Ankreuzfeld & 18 & \cw{XG\_BUTTON} & \cw{SELECTABLE} & \\
Circlebutton & 22 & \cw{XG\_POPUP} & & \\
Box mit Titel & 20 & \cw{XG\_BOXTITLE} & & \\
Unterstrichener Text & 19 & \cw{XG\_TITLE} & & \\
\hline
\end{tabular}
\end{minipage}
\end{maxipage}

%%

\Subchapter{Initialisierung der Dialoge im Programm}
Da die zus�tzlichen Objekttypen sozusagen kodiert im Resource abgelegt 
werden, ist eine Initialisierung der Dialoge n�tig.  Diese Initialisierung 
sollte nur Dialog nur einmal erfolgen.  Es gibt dabei zwei M�glichkeiten:
\begin{itemize}
\item Komplette Initialisierung einer geladenen Resource mit der Funktion 
\verb|rsrc_ruby()|.  Das erledigt man am besten direkt nach dem Laden der 
Resource.  Beispiel:
\begin{verbatim}
    /* Resource laden */
    if (!rsrc_load("STUFF.RSC")) {
        /* nicht gefunden => und Tsch��... */
        ...;
    }

    /* und Dialoge initialisieren */
    if (!rsrc_ruby()) {
        /* irgendwas ist mit der Resource faul...
           derzeit bedeutet das, da� der Pointer 
           auf die Resource 0 ist */
        ...;
    }
\end{verbatim}
\verb|rsrc_ruby()| entnimmt die Adresse der Resource aus 
\verb|global[7..8]|, die auf den Resourceheader zeigt und holt sich von 
dort die Anzahl der B�ume in der Resource.  Mit einer Iteration �ber die 
Indices wird mittels \verb|rsrc_gaddr(...)| jeweils die Baumadresse 
festgestellt und \verb|ruby(...)| f�r diesen Baum aufgerufen.
\item Einzelne Initialisierung jedes Baumes mit \verb|ruby(tree)|, wobei 
\verb|tree| vom Typ \verb|OBJECT*| ist.  Das ist z.B. dann n�tig, wenn die 
Resource direkt ins Programm eingebunden wird und diese keinen Header hat.

Statt einzelner Aufrufe, kann man auch analog zu \verb|rsrc_ruby()| mit 
einer Iteration �ber die Baumindices alle B�ume in einer for-Schleife 
initialisieren.

Beispiel:
\begin{verbatim}
    /* - NUM_TREE ist die Anzahl der B�ume
       - rs_trindex[] enth�lt die Adressen der B�ume
       Bei Verwendung einer `.RSH'-Datei des DRI/Atari-
       RCS 2.x kann man das folgende Programmst�ck 
       direkt verwenden 

       WICHTIG: Die Resource mu� bereits initialisiert 
       -------- sein, d.h. die Pointer m�ssen bereits 
                gesetzt sein. */
    int tidx;
    for (tidx = 0; tidx < NUM_TREE; tidx++) {
        OBJECT *tree = (OBJECT*)rs_trindex[tidx];
        ruby(tree);
    }
\end{verbatim}
\end{itemize}

\Subchapter{Spezielle Optionen von \Ruby}
Die Variable \verb|ruby_options| enth�lt ein paar Informationen �ber 
\ruby{} und gestattet einige Einstellungen.  Derzeit sieht die Defintion 
der Struktur wie folgt aus:

\begin{verbatim}
/* ==== ruby options ==== */

struct RUBY_OPTIONS {
    char *version;
    int btn_10pt_idx;    /* 0/2: 10pt or 11pt check box 
                                 or radio button */
    char (*m_alloc)(size_t);  /* Ruby alloziert �ber diese 
                                 Funktion Speicher */
};

extern struct RUBY_OPTIONS ruby_options;
\end{verbatim}

\begin{itemize}
\item Das Element \verb|version| enth�lt eine Versionsinfo.  Das Format ist 
derzeit undefiniert.  Die Version zeigt auch lediglich das Vorhandensein 
von neueren Funktionen oder Objekttypen an.  Eigentlich ist die Info 
unwichtig, da Sie ja beim Linken bestimmen, was Sie genau linken\dots
\item \verb|btn_10pt_idx| erm�glicht die Auswahl aus zwei verschiedenen 
H�hen f�r Checkboxes und Radio-Buttons.  Hierbei steht 0 f�r 10pt und 2 f�r 
11pt.  Am besten probieren Sie es selbst aus.  Die 10pt-Icons sind auf 
jeden Fall dann geeigneter, wenn mehrere Checkboxes untereinander stehen, 
da diese sich bei 11pt ber�hren.  Diese Einstellung wird global 
vorgenommen, um zumindest bei den Buttons ein einheitliches 
Erscheinungsbild des \ruby{} nutzenden Programms zu gew�hrleisten.
\item \ruby{} wandelt intern fast alle speziellen Objekttypen in 
\verb|G_USERDEF|-Objekte um.  Dabei ist die Anforderung von Speicher 
mittels erforderlich, um die \verb|RUBY_USERDEF|-Objekte anzulegen (siehe 
unten).  Zur Allokation von Speicher ruft \ruby{} daher immer 
\verb|(*ruby_options.m_alloc)(the_size)| zur Allokation von Speicher auf. 
 Der Parameter \verb|the_size| ist dabei vom Typ \verb|size_t|. 
 \verb|ruby_options.m_alloc| ist mit der Standardbibliotheksfunktion 
\verb|malloc| vorbesetzt.  Sie k�nnen jedoch diesen Wert durch Zuweisung 
�berschreiben, bevor irgendeine Funktion von \ruby{} aufgerufen wird.

Beispiel:
\begin{verbatim}
    /* Das eigene "malloc()" mu� sich wie das Vorbild 
       aus der Standardbibliothek verhalten, d.h. ist 
       der Speicher voll, mu� 0 geliefert werden, sofern 
       zum Aufruf zur�ckgesprungen wird (wird das 
       Programm beim Speicher�berlauf direkt terminiert, 
       kann das entfallen...) */
    void *my_malloc(size_t);
    ...
    /* Ruby soll die programmeigene Speicherverwaltung 
       verwenden */
    ruby_options.m_alloc = my_malloc;
\end{verbatim}

Derzeit wird nur bei der Initialisierung der Dialoge durch \ruby{} Speicher 
alloziert.  

Erh�lt \ruby{} von \verb|(*ruby_options.m_alloc)(...)| einen Null-Pointer 
als Resultat, so wird die Funktion \verb|(*ruby_no_mem)| mit der Adresse 
des Baumes und dem Index im Baum aufgerufen, bei dem der Speicher�berlauf 
aufgetreten ist.  Per default ist \verb|ruby_no_mem| 0.  Dabei wird dann 
lediglich die Initialisierung beendet, d.h. die Funktion \verb|ruby(...)| 
terminiert.

\begin{verbatim}
/* ==== other globals ==== */

/* ruby_no_mem() wird aufgerufen, wenn kein Speicher 
    mehr f�r die RUBY_USERBLKs zur Verf�gung steht.
    Voraussetzung: ruby_no_mem ist != 0 */
extern void (*ruby_no_mem)(OBJECT *tree, int obj);
\end{verbatim}
\end{itemize}


\Subchapter{Popup-Men�s}

\ruby{} verf�gt auch �ber zwei Funktionen f�r Popup-Men�s.  Die eine 
(\verb|pop_it_up()|) erleichtert die Arbeit mit dem Popup-Men�s und die andere 
(\verb|ruby_popup()|) beinhaltet das Popup selbst.  Das Popup kann �brigens 
nicht nur in Dialogen verwendet werden, sondern auch an anderen Stellen.

Das Popup kann komplett mit der Tastatur bedient werden (Cursortasten und 
\key{Return} oder \key{Space}).  Dies teilen Sie \verb|pop_it_up()| mit dem 
Parameter \verb|key_call| mit.  Zum Aufruf per Tastatur sollte das zum Popup 
geh�rende Infofeld als \verb|XG_BUTTON| mit \verb|TOUCHEXIT| gekennzeichnet 
werden und diesem die Tastenkombination zugeordnet werden.  Im 
Beispielprogramm sehen Sie das.  So k�nnen durch Pr�fen des R�ckgabewertes von 
\verb|form_do()| feststellen, ob der Aufruf per Tastatur erfolgte (R�ckgabe 
ist Infofeld) oder per Mausklick (R�ckgabe ist Popup-Button).

Zurerst zur Funktion \verb|pop_it_up()|.  Wenn Ihnen deren Funktionalit�t 
ausreicht, m�ssen Sie sich im Normalfall gar nicht mit \verb|ruby_popup()| 
"`abgeben"'.  Die Parameterliste ist recht umfangreich und gestattet allerlei 
Einstellungen.  Im folgenden erst mal der Funktionskopf mit den 
Kurzbeschreibungen der Parameter:

\begin{verbatim}
enum POP_ACTION { pop_next,         // zum n�chsten Eintrag
                  pop_prev,         // zum vorhergehenden Eintrag
                  pop_choose };     // Auswahl im Popup selbst

int release_time = 10;  /* Zeit in ms, die auf das Loslassen der Maustaste 
                            vor dem eigentlichen Popup gewartet wird */

BOOLEAN pop_it_up(tree, btn, info, 
                  pop, popbox,
                  action, wrap_around, active_state, redraw_button,
                  ev_mbmask, ev_mbstate,
                  key_call,
                  mitem, lastkey, bgr_saved)
OBJECT *tree; // I: Dialog-OBJECT-Baum, der den Button `btn' enth�lt
int btn;      // I: Button, der den Text des ausgew�hlen Popupeintrags enth�lt
int info;     /* I: Baum-Index des Infotextes links vom Button `btn' (wird 
                      w�hrend des Popups invertiert dargestellt, wenn >= 0) */
OBJECT *pop;  // I: Baum, der das Popup enth�lt
int popbox;   // I: Index des Popups selbst (normalerweise 0)
enum POP_ACTION action; // I: was zu tun ist (siehe enum POP_ACTION)
BOOLEAN wrap_around;    // I: TRUE: automatischer Wrap-Around (n�tzlich f�r 
                               Circle-Buttons)
int active_state;       // I: spezieller Status, mit dem der aktive 
                               Popupeintrag gekennzeichnet wird 
                               (meist CHECKED oder 0)
BOOLEAN redraw_button;  /* I: TRUE: automatischer Button-`btn'-Redraw
                               (nur bei gleichem Objekttyp im Popup und 
                                im Button `btn') */
int ev_mbmask;       /* I: die Maustasten, die beachtet werden sollen 
                            (f�r evnt_multi()) */
int ev_mbstate;      /* I: der Status, der zum Beenden des Popups gefordert 
                            wird (given to evnt_multi()) */
BOOLEAN key_call;    // I: TRUE: Aufruf via Taste,  FALSE: via Mausklick
int *mitem;          // I/O: der aktive/selektierte Popupeintrag
int *lastkey;        // O: Code der Taste, die zum Verlassen f�hrte
BOOLEAN *bgr_saved;  // O: TRUE: Hintergrund konnte gesichert werden
/*
    RETURN  TRUE        Auswahl vorgenommen
            FALSE       Auswahl abgebrochen
*/
\end{verbatim}

Wenn \verb|action == pop_choose| gilt, wird das Popup angezeigt.  Links vom 
Popup sollte sich auf gleicher H�he eine Beschreibung (Object \verb|info|) 
befinden, die von \verb|pop_it_up()| w�hrend der Auswahl aus dem Popupmen� 
selektiert dargestellt wird (nach den Human Interface Guidelines).  Im 
Beispielprogramm ist das deutlich zu sehen.

Das Popup wird mit dem vorselektierte Popupeintrag (\verb|*mitem|, wenn $\ge 
0$) automatisch auf den Popup-Button \verb|btn| ausgerichtet, soweit es die 
Ausma�e des Popup und die Position des Popup-Buttons zulassen.

Wird der Circle-Button angeklickt, so sollte mit \verb|action == pop_next| und 
\verb|wrap_around == TRUE| gearbeitet werden.  Dies bewirkt, da� vom letzten 
Eintrag automatisch zu ersten gesprungen wird.

\verb|button_redraw == TRUE| veranla�t, da� der Popup-Button \verb|btn|, der 
den ausgew�hlten Popupeintrag enth�lt automatisch aktualisiert und neu 
gezeichnet wird.  Dies ist nur m�glich, wenn alle Popupeintr�ge und der 
Popup-Button vom gleichen oder �hnlichen Objekttyp sind, d.h. \verb|ob_spec| 
auf die gleiche Struktur zeigt.  Die Ursache daf�r liegt darin, da� hierbei 
einfach das \verb|ob_spec| vom Popupeintrag in den Popup-Button \verb|btn| 
kopiert wird.

Mit \verb|ev_mbmask| kann man z.B. eine Auswahl mit der rechten Maustaste 
bewirken.  In diesem Fall mu� \verb|ev_mbmask == 2| sein (Bit 1 gesetzt).  F�r 
die linke Maustaste mu� \verb|ev_mbmask == 1| gelten (Bit 0 gesetzt -- wie 
beim AES).  Der Wert wird direkt �ber \verb|ruby_popup()| an 
\verb|evnt_multi()| weitergegeben.

\verb|ev_mbstate| enth�lt den Maustastenstatus, der zum Beenden der Auswahl im 
Popup anliegen mu�.  Es gilt die gleiche Belegung wie bei \verb|ev_mbmask|, 
d.h. Bit~0 f�r die linke und Bit~1 f�r die rechte Maustaste.

Eine Besonderheit:  \verb|pop_it_up()| wartet \verb|release_time| 
Millisekunden auf das Loslassen der in \verb|ev_mbmask| angegebenen 
Maustasten.  Sind diese Tasten dann noch gedr�ckt, so erfolgt die Selektion im 
Popupmen� durch das Loslassen der Maustaste, andernfalls durch das Dr�cken der 
Taste (testen Sie es einmal mal im Beispielprogramm).  \verb|release_time| ist 
auf 10~ms voreingestellt.

\verb|*mitem| enth�lt immer den Object-Index des zuletzt ausgew�hlen 
Popupeintrags.  D.h. wird die Auswahl abgebrochen, so ist \verb|*mitem| 
unver�ndert.  Ist \verb|*mitem| nach der R�ckkehr -1, so konnte kein Eintrag 
ausgew�hlt werden (\verb|pop_next| und alle Eintr�ge sind disabled).

Wenn der Speicher nicht ausreicht, kann der Hintergrund nicht gesichert 
werden.  Das wird mit \verb|*bgr_saved == FALSE| angezeigt.  In diesem Fall 
mu� die Applikation den vom Popup �berdeckten Teil des Dialogs neu zeichnen. 
 Da die Funktion \verb|ruby_popup()| in einem solchen Fall automatisch 
\verb|form_dial(FMD_FINISH,...)| aufruft, erh�lt man eine entsprechende 
\verb|WM_REDRAW|-Message vom AES.

Bemerkung:  \verb|ruby_popup()| verwendet \verb|Malloc()| und \verb|Mfree()| 
f�r die Speicherallokation und -freigabe.

Damit auch unter MultiGEM und in Accessories das Popup richtig funktioniert, 
ruft \verb|pop_it_up()| \verb|wind_update(BEG_MCTRL)| und 
\verb|wind_update(END_MCTRL)| auf.  Wenn Sie stattdessen \verb|ruby_popup()| 
verwenden, m�ssen Sie sich selbst darum k�mmern.

\begin{verbatim}
typedef BOOLEAN (*MITEM_SEL)(OBJECT *pop, 
                    BOOLEAN *mo_choose, 
                    int sel_mitem,  /* aktueller Eintrag im aufrufenden 
                                        Popup `pop' */
                    int *mitem, int *lastkey);

BOOLEAN ruby_popup(pop, pop_box, 
                    px, py, ev_mbmask, ev_mbstate,
                    presel_1st, item_sel, tit_rect, 
                    mo_choose,
                    mitem, lastkey, bgr_saved)
OBJECT *pop;        // I: Baum, der das Popup enth�lt
int pop_box;        // I: Index des Popups selbst (normalerweise 0)
int px, py;
int ev_mbmask;      /* I: die Maustasten, die beachtet werden sollen 
                           (f�r evnt_multi()) */
int ev_mbstate;     /* I: der Status, der zum Beenden des Popups gefordert 
                           wird (given to evnt_multi()) */
BOOLEAN presel_1st; // I: TRUE: 1. Eintrag vorselektieren
MITEM_SEL item_sel; // I: Funktion, die aufgerufen wird, wenn ein Eintrag 
                            selektiert wird
GRECT *tit_rect;    // I: wird dieser Bereich "betreten", so wird die Funktion 
                            terminiert (wenn != 0)
BOOLEAN *mo_choose; // I: TRUE: Mausauswahl, FALSE: Auswahl mit Tastatur
                            (Umschaltung erfolgt automatisch)
int *mitem;         // I/O: ausgew�hlter Men�eintrag 
                            (in: der, nach dem das Popup ausgerichtet wird)
int *lastkey;       // O: key-code, der das Verlassen verursacht hat
BOOLEAN *bgr_saved; // O: TRUE: Hintergrund konnte gesichert werden
/*
        RETURN  TRUE        Auswahl vorgenommen
                FALSE       Auswahl abgebrochen
*/
\end{verbatim}

Mit \verb|ruby_popup()| direkt zu arbeiten lohnt sich nur, wenn Sie Popups mit 
Submen�s programmieren m�chten.  Das ist m�glich und wurde auch schon mit 
dieser Funktion im Entmauser realisiert.  Dazu ist eine Funktion vom Typ 
\verb|MITEM_SEL| bereitzustellen, die immer dann aufgerufen, wenn ein Eintrag 
selektiert wurde.  Diese Funktion wird dann wieder \verb|ruby_popup()| f�r's 
Popup aufrufen, wobei ab dem ersten rekursiven Aufruf noch \verb|tit_rect| 
mitgeliefert wird.  \verb|tit_rect| enth�lt dann Koordinaten des Eintrags im 
�bergeordneten Popupmen�.  Denn genau dann, wenn die Maus auf diesen zeigt, 
mu� das Submen� ja wieder weggeklappt werden.

Mit den Cursortasten (rechts, links) kann nach auch per Tastatur in die 
Submen�s hinein bzw. diese verlassen.

Achten Sie bitte darauf, \verb|wind_update(BEG_MCTRL)| vor \verb|ruby_popup()| 
und danach \verb|wind_update(END_MCTRL)| aufzurufen, damit Ihre Applikation 
bzw. Ihr Accessory auch die volle Kontrolle �ber Maus und Tastatur erh�lt (bei 
Submen�s reicht ein \verb|BEG_MCTRL|).  Unterlassen Sie dies, so kehrt das AES 
u.U. nie mehr zum \verb|evnt_multi()|-Aufruf von \verb|ruby_popup()| zur�ck 
und ihre Applikation wird zur Speicher- und Bildschirmleiche. 
 \verb|pop_it_up()| t�tigt die \verb|wind_update|-Aufrufe selbst.


%% Interna von RUBY %%

\Chapter{Interna von \Ruby}
Einige Interna von \ruby{} sollen hier dokumentiert werden.

\Subchapter{Die RUBY\_USERBLK-Struktur}
Einige der zus�tzlichen Objekttypen werden durch \verb|G_USERDEF|-Objekte 
implementiert, d.h. der urspr�ngliche Objekttyp (z.B. \verb|G_BUTTON|) wird 
durch \verb|G_USERDEF| ersetzt.  In diesem Zuge wird das urspr�ngliche 
\verb|ob_spec| durch einen Zeiger auf eine erweiterte 
\verb|USERBLK|-Struktur ersetzt, die sogenannte die 
\verb|RUBY_USERBLK|-Struktur.  Die urspr�nglichen Werte von \verb|ob_type| 
und \verb|ob_spec| werden in der \verb|ub_type| und in \verb|ub_spec| in 
der \verb|RUBY_USERBLK|-Struktur ablegt, um weiterhin darauf zugreifen zu 
k�nnen.  Das Element \verb|text_offset| bestimmt einen Offset, um den der 
Text bei der Ausgabe verschoben wird.  Dieser sollte z.B. von \ltmf{} 
verwendet werden, um die korrekte Position des Shortcut-"`Strichleins"' von 
auch bei Radio-Buttons und Checkboxen zu garantieren.

Die \verb|RUBY_USERBLK|-Struktur ist noch durch eine Magic abgesichert, die 
den Wert \verb|0x09800665L| haben mu�.  Nur dann sind die beschriebenen Daten 
auch wirklich vorhanden.

\begin{verbatim}
/* ==== Ruby's special extended USERBLK ==== */
typedef struct {
    int cdecl (*ub_code) _((PARMBLK*));
    OBSPEC ub_spec;     /* original ob_spec */
    int ub_type;        /* original ob_type */
    long ruby_magic;    /* the RUBY_MAGIC */
    int text_offset;    /* offset for drawing the text (pixel) */
} RUBY_USERBLK;

#define RUBY_MAGIC  0x09800665L     /* g [m/s^2] */
\end{verbatim}

N�here Informationen �ber die Funktion und Anwendung von 
\verb|USERBLK|-Struktur und \verb|G_USERDEF|-Objekten k�nnen Sie in 
einschl�giger Literatur finden.


\Subchapter{Globale Variablen, die von \Ruby{} ben�tigt werden}
\ruby{} ben�tigt einige wenige globale Variablen.  Diese werden von den 
beigelegten Modulen meiner GEM-Library bereitgestellt.  Wenn Sie diese 
Module nicht verwenden m�chten, m�ssen Sie folgende Variablen 
bereitstellen:

\tabular{l|l}
 \it Variable/Funktion & Bedeutung \\
 \hline
 \verb|lib_handle|    & ein Virtual-VDI-Screen-Workstation-Handle, \\
                      & mit dem \ruby{} machen darf, was es will\dots \\
 \verb|std_fdb|       & MFDB f�r den Bildschirm, der auch die Anzahl \\
                      & der Planes des Bildschirms und die Ma�e des \\
                      & Bildschirm enth�lt.\\
 \verb|xdesk .. hdesk| & Ma�e des Desktops, die man mit \\
                       & \verb|wind_get(0, WF_WORKXYWH ...)| erh�lt. \\
 \verb|get_cookie(...)|  & Funktion aus der \ltmf{}-Bibliothek \\
 \verb|fix_image(...)|   & diese Funkion ist in \verb|rfiximag.c| enthalten \\
 \verb|clip_start(...)|  & \\
 \verb|clip_end(...)|    & diese beiden Funktionen sind in \verb|clip_it.c| 
enthalten \\
\endtabular

Der Source \verb|rubyinit.c| enth�lt Code, der die in der Liste 
aufgef�hrten Variablen deklariert und initialisiert.  Beachten Sie bitte 
die Hinweise im Source selbst.

Noch eine Anmerkung zur Variable \verb|lib_handle|.  Dieses Handle 
verwendet \ruby{}, um seine VDI-Ausgaben und -Operationen zu t�tigen. 
 \ruby{} setzt die VDI-Attribute vor allen Ausgaben und Operationen auf die 
ben�tigten Werte.  Daher kann \verb|lib_handle| ohne weiteres auch f�r 
andere Libraries verwendet werden.  Ich selbst verwende \verb|lib_handle| 
in meinen Libraries und \verb|handle| in meinen Programmen, um in Programm 
und Libraries unabh�ngig mit dem VDI arbeiten zu k�nnen.

\ruby{} ben�tigt schachtelbares Clipping.  Ohne schachtelbares Clipping 
w�rde das Popup nicht korrekt arbeiten, weil im Popup selbst ein 
"`Ruby-OBJECT"' enthalten ist.  Daher habe ich die Funktionen 
\verb|clip_start()| und \verb|clip_end()| implementiert.  Erstere stellt 
einen neuen Clipping-Bereich ein und merkt sich den alten.  Letztere 
schaltet zum alten Clipping-Bereich zur�ck.  Die Schachtelungstiefe 
betr�gt derzeit 20, ist aber im Modul \verb|clip_it.c| einstellbar 
(\verb|CLIP_STK_DEPTH|).  Das Modul \verb|clip_it.c| ist bereits in die 
Libraries integriert (nicht DRI/Alcyon und Megamax LaserC Objectfiles).

Die PureC/TurboC-Version ben�tigt au�erdem noch die beiden Funktionen 
\verb|save_regs()| und \verb|restore_regs()|, die vom Assembler-Source 
\verb|tc\sr_regs.s| bereitgestellt werden.


\Subchapter{Die Gr��e des SMALL-Systemfonts und das Cookie SMAL}
Die Gr��e des sogenannten \cw{SMALL}-Systemfonts wird weder vom VDI noch 
vom AES direkt geliefert.  Daher bedient sich \ruby{} eines "`Tricks"', 
der auch von Atari selbst verwendet wird.  Nach dem �ffnen einer 
virtuellen Screen-Workstation steht die minimale Zeichenh�he in 
\verb|work_out[46]|.  Da Atari selbst im AES so die Gr��e des {\tt 
SMALL}-Systemfonts ermittelt, ist mit einer �nderung nicht so schnell zu 
rechnen.

\begin{verbatim}
int work_out[57], attrib[10];
long *the_smal_cookie;

/* LTMF-cookie */
ltmf_cookie = (LTMFLY*)_get_cookie(cookie_LTMF);

/* characters extents of the system fonts */
vq_extnd(lib_handle, 0, work_out);
vqt_attributes(lib_handle, attrib);
ibm_height = attrib[7];     /* aktuelle Zeichenh�he */
sml_height = work_out[46];  /* minimale Zeichenh�he */
vst_font(lib_handle, 1);
vst_effects(lib_handle, 0);
vst_height(lib_handle, sml_height, &dummy, &dummy, 
                            &sml_pix_width, &sml_pix_height);
vst_height(lib_handle, ibm_height, &dummy, &dummy, 
                            &ibm_pix_width, &ibm_pix_height);

if (the_smal_cookie = _get_cookie(cookie_SMAL)) {
    register int foo;
    if (foo = (int)(*(long*)the_smal_cookie & 0x0000FFFFL))
        sml_height = foo;
        if (foo = (int)((*(long*)the_smal_cookie & 0xFFFF0000L) >> 16))
            ibm_height = foo;
}
\end{verbatim}

Sollte die Gr��e des \cw{SMALL}-Systemfonts irgendwann einmal nicht mehr 
in \verb|work_out[46]| stehen, dann k�nnen alle Programm, die \ruby{} 
verwenden durch ein TSR (Terminate\&Stay-Resident-Auto-Ordner-Programm) 
umkonfiguriert werden.  Dieses TSR mu� lediglich ein Cookie anlegen, das 
im Low-Word die Gr��e des \cw{SMALL}-Systemfonts passend als Parameter 
f�r \verb|vst_height(...)| enth�lt.  Ggf. kann das High-Word zus�tzlich 
noch die Gr��e des sogenannten \cw{IBM}-Systemfonts enthalten.

Das obenstehende Programmst�ck darf ohne spezielle Bedingungen in andere 
Software eingebunden werden.


\Subchapter{Erweiterungen f�r \Ruby -- der \Ruby-Hook}

Auf recht einfache Art und Weise k�nnen Sie \ruby{} um eigene spezielle 
Objekt-Typen erweitern oder Objekte irgendwie modifizieren.  Als Beispiel 
liegt das Modul \verb|repldlin.c| bei, das die Trennzeilen in Men�s und 
Popup-Men�s durch eine richtige Linie ersetzt (\'a la Gemini).

Das Prinzip ist ganz einfach.  Bevor \ruby{} ein OBJECT eines Baumes irgendwie 
bearbeitet, wird �ber den Pointer \verb|ruby_hook| eine Funktion aufgerufen, 
die das OBJECT pr�ft und ggf. modifiziert und eine USERDEF-Routine 
installiert.  Dazu empfiehlt sich die Verwendung von 
\verb|install_ruby_userblk()|, das das einen \verb|RUBY_USERBLK| vollst�ndig 
installiert.  Sie m�ssen dann nur noch die Zeichenroutine in \verb|ub_code| 
eintragen (siehe Beispiel).

Die "`Hook-Funktion"' gibt \verb|TRUE| zur�ck, wenn \ruby{} sich nicht mehr um 
dieses OBJECT k�mmern soll.  Damit werden Doppelinterpretationen 
ausgeschlossen.  \verb|FALSE| signalisiert \ruby{}, da� es ganz normal 
verfahren soll, d.h. seine \verb|ob_type|-Pr�fungen auf \verb|XG_BUTTON| usw. 
durchf�hrt.

Damit mehrere Hooks eingeh�ngt werden k�nnen, mu� beim Installieren eines 
Hooks der als Pointer-Wert von \verb|ruby_hook| gespeichert werden und im 
eigenen Hook �ber den alten Pointer-Wert in den n�chste Hook sprungen werden. 
 Ein n�chster Hook existiert nur dann, der alte Pointer-Wert != 0 ist.  Im 
Beispiel ist der Mechanismus deutlich zu erkennen.

Achten Sie in der Zeichen-Funktion (\verb|draw_dash_line()| im Beispiel) bitte 
auf Clipping.  Verwenden Sie bitte daf�r die Funktionen \verb|clip_start()| 
und \verb|clip_end()| aus dem Modul \verb|clip_it.c|.  Diese Funktionen 
erm�glichen die Schachtelung von Clipping-Areas.  Wenn Sie dies nicht machen, 
kann es passieren, da� z.B. das Popup nicht mehr verschwindet o.�.  Sie k�nnen 
sich den Effekt anschauen, indem Sie im Beispiel einfach mal 
\verb|clip_start()| durch den entsprechenden \verb|vs_clip()|-Aufruf 
ersetzen und \verb|clip_end()| weglassen.  Schleu�lich, was?  Also: 
 Immer \verb|clip_start()| und \verb|clip_end()| verwenden.

Wenn Sie das Clipping ganz unterlassen, wird Ihre Erweiterung in 
Fensterdialogen nicht korrekt funktionieren, da dort der Redraw anhand von 
Rechtecklisten vorgenommen wird und Clipping somit unerl��lich ist.

Wenn Sie eine Ruby-Erweiterung programmieren m�chten, verwenden Sie am besten 
das Beispiel-Modul und modifizieren dies auf geeignete Art und Weise.  In 
\verb|draw_dash_line()| m�ssen Sie beispielsweise nur die Aufrufe der 
VDI-Funktionen zum Zeichnen ersetzen und die Erkennung im Hook anpassen.

Sie m�chten Ihre Ruby-Erweiterungen auch anderen Leuten zur Verf�gung stellen? 
 Am besten stellen Sie eine kurze Info und ein Beispielprogramm zusammen und 
schicken mir dies.  Ich werde dann zumindest im Mausnet und Starnet f�r eine 
gewisse Verbreitung sorgen k�nnen.


%% 

\Chapter{Bemerkungen zum Design von Dialogen}
Halten Sie das Design der Dialoge einheitlich.  Schauen Sie sich ab besten 
Software an, die ebenso die Features von \ruby{} bzw. entsprechende 
Features anderer Libraries verwendet (Beispiele:  Gemini, CAT, Rufus). 
 Orientieren Sie sich daran.

Ein paar Richtlinien m�chte ich Ihnen noch mit auf den Weg geben:
\begin{itemize}
\item Halten Sie den Hintergrund Ihrer Dialoge m�glichst einfach.  Am 
unaufdringlichsten ist ein einfacher wei�er Hintergrund {\em ohne} Muster. 
 Damit heben sich Dialoge auf bestens vom grauen Desktophintergrund ab.
\item Sorgen Sie f�r eine einheitliche Strukturierung Ihrerer Formulare. 
 Oben kommt die �berschrift hin, dann die ganzen Einstellungen und unten 
die Buttons zum Verlassen des Dialogs.
\item Die Button zum Verlassen des Dialogs sollten in allen Dialogen an der 
gleichen Position in der gleichen Reihenfolge stehen.  Ich pers�nlich ziehe 
die Reihenfolge \verb|OK|--\verb|Abbruch| vor.  Bei der Schreibweise hat es 
sich eingeb�rgert, immer \verb|OK| gro� zu schreiben und \verb|Abbruch| in 
normaler Gro�-Klein-Schreibung zu verwenden.  Da sich die Bezeichnungen OK 
und Abbruch eingeb�rgert haben, m�chte ich Ihnen nahelegen, diese ebenso zu 
verwenden.
\end{itemize}


\Subchapter{Implementierung}

Zur Implementierung habe ich derzeit nur einen einzigen, aber sehr wichtigen 
Hinweis.

\begin{itemize}
\item Packen Sie die Aufrufe der Dialoge immer in 
\verb|wind_update(BEG_UPDATE)| -- \verb|wind_update(END_UPDATE)|, da sonst 
Fehlfunktionen bei Accessories oder unter MultiGEM auftreten.  Wenn Sie das 
n�mlich vergessen, werden Klicks und Tastendr�cke u.U. an das oberste Fenster 
und nicht an den Dialog weitergeleitet.  Die Folgen k�nnen Sie sich selbst 
ausmalen\dots
\end{itemize}

Haben Sie weitere Vorschl�ge, um die dieses Kapitel erweitert werden 
sollte, dann lassen Sie es mich bitte wissen.


%% Bugreports %%

\Chapter{Bugreports}

Wenn Sie irgendwelche Fehler in \ruby{} entdecken, so benachrichtigen Sie 
mich bitte.  Als Programmierer sollten Sie wissen, was ich dazu wohl 
ben�tigen werde und �ber das Problem wissen soll und mu�.

Schicken Sie Bugreports bitte m�glichst per E-Mail, um mir R�ckfragen zu 
erm�glichen.

\begin{tabular}{l}
  \underline{E-Mail:} \\
  \verb|Markus_Nick @ MZ| \quad  (im Mausnet) \\
  \verb|Markus_Nick@mz.maus.de| \quad (im Internet)
\end{tabular}


%% Danksagungen (DSACK) %%

\Chapter{Abspann}
\Subchapter{Acknowledgements}
Ich m�chte mich bei folgenden Leuten f�r die Mitarbeit und Unterst�tzung 
bei der Entwicklung von \ruby{} bedanken:
\begin{itemize}
\item Oliver Scheel -- insbesondere f�r \ltmf{} -- ohne \ltmf{} g�be es 
n�mlich kein \ruby{} -- und f�r seine gro�artige Unterst�tzung bei der 
Entwicklung von \ruby{} und beim Beta-Testen.
\item Dieter Linde f�r's sorgf�ltige Beta-Testen, die konstruktiven 
Fehlermeldungen und Anregungen.
\end{itemize}

\Subchapter{Warenzeichen}
\begin{itemize}
\item Atari und Atari ST und TT sind gesch�tzte Warenzeichen der Atari Corp.
\item GEM ist ein gesch�tztes Warenzeichen von Digital Research Corp.
\item LaserC ist ein gesch�tztes Warenzeichen von Megamax Inc.
\end{itemize}

Diverse in diesem Text verwendete Namen sind m�glicherweise urheberrechtlich 
gesch�tzt.  Daraus, da� diese nicht kenntlich gemacht sind, kann nicht 
geschlossen werden, da� sie frei von Rechten Dritter sind.

Weiterhin:
\begin{itemize}
\item GNU-CC ist ein Produkt der Free Software Foundation
\item \ltmf{} ist Freeware von Oliver Scheel (Oliver Scheel @ K)
\item "`Three Flights Up"' ist die Library zu Let 'em Fly! von Oliver 
Scheel
\end{itemize}

\end{document}



% eof
