%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}    % fr š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.  Fr 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 fr \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 fr Popups
    \item Undo-Button, Help-Button
    \item Eselsohr (Flugecke)
  \end{itemize}
\item Ruby beinhaltet Funktionen fr 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{} 
untersttzen bzw. nutzen m”chte, erh„lt mit \ruby{} eben noch runde 
Radiobuttons etc. Der Vorteil ist, daž der Overhead fr 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 ntzt 
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 fr 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.

%Wrde 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{} sttzt. Der User wrde das zu 
%wrdigen 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 fr \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 
fr kommerzielle Software verwendet werden darf, sehen Oliver Scheel und 
ich keine Grnde, diese Kombination aufzugeben. Die Grnde dafr sind 
mehr philosophisch zu sehen (wie oben aufgefhrt).  Jeder ist herzlich 
dazu eingeladen, dieser Philosophie in seiner Software zu folgen.

Viel Spaž und wenig Probleme mit \ruby{} wnscht Ihnen\\
\hspace*{10em}Markus M. Nick


%% Lizenzbedingungen %%

\Chapter{Lizenzbedingungen}
\ruby\ ist Freeware. Sie drfen \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 fr den Download keine 
gesonderte Gebhr erhoben wird. Zuwiderhandlungen werde ich 
strafrechtlich verfolgen!

Fr 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 fr 
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, fr die Geld verlangt 
wird, ist die Verwendung von \ruby{} beim Autor anzuzeigen (Brief/Postkarte 
oder E-Mail mit Adresse und Telefonnummer und kurzem Produktinfo gengt).

Weitere Bedingungen sind daran nicht geknpft.  šber eine angemessene Spende 
und/oder die Zusendung der Software selbst wrde 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:} \hspace*{4cm} &   \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 \\
    \multicolumn{2}{l}{55129 Mainz-Ebersheim \quad  (neue PLZ ab 1.7.93)} \\
    Germany                     &   \\
 \\
  \underline{Telefon:}    &  \underline{E-Mail:} \\
  (Germany)--6136--45647  &  \verb|Markus_Nick @ WI2| \quad  (im Mausnet) \\
  ({\em NIE} vor 11 Uhr)  &  \verb|Markus_Nick@wi2.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 
Rckumschlag} 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 Gebhr o.„. ist auch dies m”glich.

Um die Konsistenz der verfgbaren 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 fr \ruby{}. 
 \ruby{} wird so geliefert, wie es ist, ohne jede Haftung, weder 
implizite oder explizite, einschliežlich, ohne Einsch„nkung, der Haftung 
fr die Zweckm„žigkeit und Verwendungstchtigkeit fr 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 fr Service, Reparaturen 
und Korrekturen.

Sie k”nnen den Autor in keinem Fall fr 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 
Untchtigkeit von \Ruby{} fr 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 fr 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 fr 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-Mens 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 verfgbar:
\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} verknpft werden. Beachten 
Sie bitte, daž die Kn”pfe alle zumindest entweder \cw{SELECTABLE} oder 
\cw{TOUCHEXIT} sein mssen.

Um einen Button mit einem {\em Shortcut} zu belegen, setzt man einfach vor den 
gewnschten 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 fr 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.) verknpft 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(...)| fr 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 Programmstck 
       direkt verwenden 

       WICHTIG: Die Resource muž bereits initialisiert 
       -------- sein, d.h. die Pointer mssen 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 fr Checkboxes und Radio-Buttons.  Hierbei steht 0 fr 10pt und 2 fr 
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 berhren.  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 zurckgesprungen wird (wird das 
       Programm beim Speicherberlauf 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 Speicherberlauf 
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 fr die RUBY_USERBLKs zur Verfgung steht.
    Voraussetzung: ruby_no_mem ist != 0 */
extern void (*ruby_no_mem)(OBJECT *tree, int obj);
\end{verbatim}
\end{itemize}


\Subchapter{Popup-Mens}

\ruby{} verfgt auch ber zwei Funktionen fr Popup-Mens.  Die eine 
(\verb|pop_it_up()|) erleichtert die Arbeit mit dem Popup-Mens 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 Prfen des Rckgabewertes von 
\verb|form_do()| feststellen, ob der Aufruf per Tastatur erfolgte (Rckgabe 
ist Infofeld) oder per Mausklick (Rckgabe ist Popup-Button).

Zurerst zur Funktion \verb|pop_it_up()|.  Wenn Ihnen deren Funktionalit„t 
ausreicht, mssen 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 (ntzlich fr 
                               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 
                            (fr 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 fhrte
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 dafr 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).  Fr 
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 fr die linke und Bit~1 fr 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 gedrckt, so erfolgt die Selektion im 
Popupmen durch das Loslassen der Maustaste, andernfalls durch das Drcken 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 Rckkehr -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()| 
fr 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, mssen Sie sich selbst darum kmmern.

\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 
                           (fr 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 Meneintrag 
                            (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 
Submens 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()| fr'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 
Submens 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 
Submens 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()| zurck 
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 ursprngliche Objekttyp (z.B. \verb|G_BUTTON|) wird 
durch \verb|G_USERDEF| ersetzt.  In diesem Zuge wird das ursprngliche 
\verb|ob_spec| durch einen Zeiger auf eine erweiterte 
\verb|USERBLK|-Struktur ersetzt, die sogenannte die 
\verb|RUBY_USERBLK|-Struktur.  Die ursprnglichen 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, mssen 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 fr 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 
aufgefhrten 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 fr 
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 
wrde 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 zurck.  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 
fr \verb|vst_height(...)| enth„lt.  Ggf. kann das High-Word zus„tzlich 
noch die Gr”že des sogenannten \cw{IBM}-Systemfonts enthalten.

Das obenstehende Programmstck darf ohne spezielle Bedingungen in andere 
Software eingebunden werden.


\Subchapter{Erweiterungen fr \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 Mens und 
Popup-Mens 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 prft 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 mssen dann nur noch die Zeichenroutine in \verb|ub_code| 
eintragen (siehe Beispiel).

Die "`Hook-Funktion"' gibt \verb|TRUE| zurck, wenn \ruby{} sich nicht mehr um 
dieses OBJECT kmmern soll.  Damit werden Doppelinterpretationen 
ausgeschlossen.  \verb|FALSE| signalisiert \ruby{}, daž es ganz normal 
verfahren soll, d.h. seine \verb|ob_type|-Prfungen auf \verb|XG_BUTTON| usw. 
durchfhrt.

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 dafr 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()| mssen 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 Verfgung stellen? 
 Am besten stellen Sie eine kurze Info und ein Beispielprogramm zusammen und 
schicken mir dies.  Ich werde dann zumindest im Mausnet und Starnet fr 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 fr 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 eingebrgert, immer \verb|OK| grož zu schreiben und \verb|Abbruch| in 
normaler Grož-Klein-Schreibung zu verwenden.  Da sich die Bezeichnungen OK 
und Abbruch eingebrgert 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 Tastendrcke 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 Rckfragen 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 fr die Mitarbeit und Untersttzung 
bei der Entwicklung von \ruby{} bedanken:
\begin{itemize}
\item Oliver Scheel -- insbesondere fr \ltmf{} -- ohne \ltmf{} g„be es 
n„mlich kein \ruby{} -- und fr seine grožartige Untersttzung bei der 
Entwicklung von \ruby{} und beim Beta-Testen.
\item Dieter Linde fr's sorgf„ltige Beta-Testen, die konstruktiven 
Fehlermeldungen und Anregungen.
\end{itemize}

\Subchapter{Warenzeichen}
\begin{itemize}
\item Atari und Atari ST und TT sind geschtzte Warenzeichen der Atari Corp.
\item GEM ist ein geschtztes Warenzeichen von Digital Research Corp.
\item LaserC ist ein geschtztes Warenzeichen von Megamax Inc.
\end{itemize}

Diverse in diesem Text verwendete Namen sind m”glicherweise urheberrechtlich 
geschtzt.  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
