home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / fldlib93 / source / fldlib.c next >
Encoding:
C/C++ Source or Header  |  1994-05-21  |  19.1 KB  |  653 lines

  1. /**********************************
  2.  *                                *
  3.  *    FLDLIB v0.93 SOURCE CODE    *
  4.  *     (C) M. J. Maisey 1994      *
  5.  *  View with a tab setting of 2  *
  6.  *                                *
  7.  **********************************/
  8.  
  9.  
  10. #include <aes.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "icon.c"
  14.  
  15.  
  16. /* FLD structure - used internally by FLYDIAL */
  17. /* Can be accessed externally by fld_getfld() */
  18.  
  19. typedef struct fly_dialog  {
  20.     int                                 windowhandle;
  21.     short                                fldhandle,
  22.                                              type,
  23.                                              focus,
  24.                                              index;
  25.     char                                 *title;
  26.     char                                iconified;
  27.     OBJECT                            *form;
  28.     int                                 (*xredraw)(int, GRECT*);
  29.     struct fly_dialog     *next;
  30. } FLD;
  31.  
  32.  
  33. /* Global variables - internally used */
  34.  
  35. FLD*        fld_first = NULL;
  36. OBJECT*    fld_tempform;
  37. int            fld_tempstart,
  38.                 fld_tempdepth;
  39. int            fld_progability;
  40. char        fld_iconinitialised = 0;
  41.  
  42.  
  43. /* Function prototypes - externally available functions */
  44.  
  45. short    fld_open(OBJECT *form, short centred, char *title, short type);
  46. void    fld_draw(short fldhandle, int startobj, int depth);
  47. short fld_key(short kc, short *type, short *fldhandle);
  48. short    fld_mouse(short x, short y, short numclicks, short *type, short *fldhandle);
  49. int        fld_mesag(short *msgbuf);
  50. void    fld_exit(void);
  51. void    fld_close(short fldhandle);
  52. int        fld_getwin(short fldhandle);
  53. FLD*    fld_getfld(short fldhandle);
  54. OBJECT*fld_getform(short fldhandle);
  55. FLD*    fld_findtype(short type);
  56. FLD*    fld_findform(OBJECT *form);
  57. short fld_do(OBJECT *tree, char *title);
  58. short fld_domulti(short *type, short *fldhandle);
  59. void    fld_ability(int bitmask);
  60.  
  61.  
  62. /* Function prototypes - internal use */
  63.  
  64. FLD*    fld_add(short *fldhandle);
  65. void    fld_remove(short fldhandle);
  66. FLD*    fld_findwin(int windowhandle);
  67. int        fld_drawform(int handle, GRECT *area);
  68. int        fld_drawicon(int handle, GRECT *area);
  69.  
  70.  
  71. /* Form positions on opening */
  72.  
  73. #define FLDC_NONE        0        /* No centreing */
  74. #define FLDC_SCREEN    1        /* Centre on screen */
  75. #define FLDC_MOUSE    2        /* Centre on mouse pointer */
  76.  
  77.  
  78. /* Ability codes */
  79.  
  80. #define FLDA_NONE   0x0000   /* No special program abilities */
  81. #define FLDA_CLOSE  0x0001   /* Close dialog handling */
  82. #define FLDA_ICON   0x0002   /* Iconify handling */
  83.  
  84.  
  85. /* fld_mouse/fld_key/fld_mesag return values */
  86.  
  87. #define FLDR_NONE   -1       /* No action required */
  88.  
  89.  
  90. /* fld_add(): Add new fly_dialog to list              */
  91. /*            Returns: pointer to new fly_dialog      */
  92. /*            New handle -> fldhandle                 */
  93. /*                      INTERNAL                      */
  94.  
  95. FLD *fld_add(short *fldhandle)  {
  96.     FLD *temp = fld_first;
  97.  
  98.     if (fld_first == NULL)  {
  99.         temp = fld_first = (FLD *) malloc(sizeof(FLD));
  100.         *fldhandle = 1;
  101.     } else {
  102.         for (;temp->next != NULL; temp = temp->next);
  103.         *fldhandle = temp->fldhandle + 1;
  104.         temp->next = (FLD *) malloc(sizeof(FLD));
  105.         temp = temp->next;
  106.     }
  107.  
  108.     temp->windowhandle = 0;
  109.     temp->fldhandle = *fldhandle;
  110.     temp->type = 0;
  111.     temp->title = NULL;
  112.     temp->iconified = 0;
  113.     temp->form = NULL;
  114.     temp->xredraw = NULL;
  115.     temp->next = NULL;
  116.  
  117.     return temp;
  118. }
  119.  
  120.  
  121. /* fld_remove(): Remove fly_dialog from list          */
  122. /*               fldhandle -> handle to be removed    */
  123. /*                      INTERNAL                      */
  124.  
  125. void fld_remove(short fldhandle)  {
  126.     FLD *old = NULL, *temp = fld_first;
  127.  
  128.     for (; temp != NULL;)  {
  129.         if (temp->fldhandle == fldhandle) break;
  130.         old = temp;
  131.         temp = temp->next;
  132.     }
  133.  
  134.     if (temp != NULL)  {
  135.         if (old == NULL)  {
  136.             fld_first = temp->next;
  137.             free((void *) temp->title);
  138.             free((void *) temp);
  139.         } else {
  140.             old->next = temp->next;
  141.             free((void *) temp->title);
  142.             free((void *) temp);
  143.         }
  144.     }
  145. }
  146.  
  147.  
  148. /* fld_findwin(): Find fly_dialog for window          */
  149. /*            Returns: pointer to fly_dialog if found */
  150. /*                     NULL if not found              */
  151. /*            windowhandle -> handle of window(!)     */
  152. /*                      INTERNAL                      */
  153.  
  154. FLD *fld_findwin(int windowhandle)  {
  155.     FLD *temp = fld_first;
  156.  
  157.     for (; temp != NULL; temp = temp->next)
  158.         if (temp->windowhandle == windowhandle) break;
  159.  
  160.     return temp;
  161. }
  162.  
  163.  
  164. /* fld_open(): Open new flying dialog                 */
  165. /*            Returns: handle of new fly_dialog       */
  166. /*                     -1 if problem                  */
  167. /*            form -> pointer to object tree          */
  168. /*            centred -> centreing of pointer         */
  169. /*            title -> window title                   */
  170. /*            type -> type of fly_dialog              */
  171. /*                      EXTERNAL                      */
  172.  
  173. short    fld_open(OBJECT *form, short centred, char *title, short type)  {
  174.     short fldhandle, x, y, w, h, dummy, wx, wy, ww, wh, max, tempobj, dy, parts;
  175.     FLD *temp = fld_first;
  176.  
  177.     for (; temp != NULL; temp = temp->next)  {
  178.         if (temp->form == form)  {
  179.             wind_set(temp->windowhandle, WF_TOP);
  180.             return temp->fldhandle;
  181.         }
  182.     }
  183.  
  184.     switch (centred)  {
  185.     case FLDC_NONE:
  186.         objc_offset(form, 0, &x, &y);
  187.         w = form->ob_width;
  188.         h = form->ob_height;
  189.         break;
  190.     case FLDC_SCREEN:
  191.         form_center(form, &x, &y, &w, &h);
  192.         break;
  193.     case FLDC_MOUSE:
  194.         w = form->ob_width;
  195.         h = form->ob_height;
  196.         graf_mkstate(&x, &y, &dummy, &dummy);
  197.         x -= w / 2;
  198.         y -= h / 2;
  199.         form->ob_x = x;
  200.         form->ob_y = y;
  201.         if (x < 0) x = 0;
  202.         if (y < 0) y = 0;
  203.         break;
  204.     }
  205.     
  206.     if (fld_progability & FLDA_CLOSE)
  207.         parts = NAME|MOVE|CLOSE;
  208.     else
  209.         parts = NAME|MOVE;
  210.     
  211.     if (fld_progability & FLDA_ICON)
  212.         parts |= SMALLER;
  213.  
  214.     temp = fld_add(&fldhandle);
  215.     temp->form = form;
  216.     wind_calc(WC_BORDER, parts, x, y, w, h, &wx, &wy, &ww, &wh);
  217.     wx++;wy++;ww-=2;wh-=2;
  218.     
  219.     wind_get(DESK, WF_PREVXYWH, &dummy, &dy, &dummy, &dummy);
  220.     if (wy < dy)  {
  221.         temp->form->ob_y = dy + y - wy;
  222.         wy = dy;
  223.     }
  224.     
  225.     temp->windowhandle = wind_create(parts, wx, wy, ww, wh);
  226.     temp->title = (char *) malloc(strlen(title)+2);
  227.     temp->type = type;
  228.     strcpy(temp->title, title);
  229.     wind_title(temp->windowhandle, temp->title);
  230.     wind_open(temp->windowhandle, wx, wy, ww, wh);
  231.  
  232.     /* Initialise edit */
  233.     max = temp->form->ob_tail;
  234.     for (tempobj = 0; tempobj <= max; tempobj++)
  235.         if (temp->form[tempobj].ob_flags & EDITABLE)  break;
  236.  
  237.     if (tempobj <= max)  {                /* Check editable object found */
  238.         temp->focus = tempobj;
  239.         objc_edit(temp->form, temp->focus, 0, &temp->index, ED_INIT);
  240.     } else
  241.         temp->focus = -1;
  242.  
  243.     return fldhandle;
  244. }
  245.  
  246.  
  247. /* fld_getfld(): Find fly_dialog given a handle       */
  248. /*            Returns: pointer to fly_dialog if found */
  249. /*                     NULL if not found              */
  250. /*                      EXTERNAL                      */
  251.  
  252. FLD *fld_getfld(short fldhandle)  {
  253.     FLD *temp = fld_first;
  254.  
  255.     for (; temp != NULL; temp = temp->next)
  256.         if (temp->fldhandle == fldhandle) break;
  257.  
  258.     if (temp != NULL)
  259.         return temp;
  260.  
  261.     return NULL;
  262. }
  263.  
  264.  
  265. /* fld_drawform: called only via wind_redraw()        */
  266. /*                      INTERNAL                      */
  267.  
  268. int fld_drawform(int handle, GRECT *area)  {
  269.     objc_draw(fld_tempform, fld_tempstart, fld_tempdepth, area->g_x, area->g_y, area->g_w, area->g_h);
  270.  
  271.     return 1;
  272. }
  273.  
  274.  
  275. /* fld_drawicon: called only via wind_redraw()        */
  276. /*                      INTERNAL                      */
  277.  
  278. int fld_drawicon(int handle, GRECT *area)  {
  279.     short x, y, w, h;
  280.     
  281.     wind_get(handle, WF_WORKXYWH, &x, &y, &w, &h);
  282.     FLD_ICONFORM->ob_x = x;
  283.     FLD_ICONFORM->ob_y = y;
  284.     FLD_ICONFORM->ob_width = w;
  285.     FLD_ICONFORM->ob_height = h;
  286.     
  287.     FLD_ICONFORM[1].ob_x = w / 2 - FLD_ICONFORM[1].ob_width / 2;
  288.     FLD_ICONFORM[1].ob_y = h / 2 - FLD_ICONFORM[1].ob_height / 2;
  289.     
  290.     objc_draw(FLD_ICONFORM, 0, 7, area->g_x, area->g_y, area->g_w, area->g_h);
  291.  
  292.     return 1;
  293. }
  294.  
  295.  
  296. /* fld_draw(): Find fly_dialog given a handle         */
  297. /*             fldhandle -> fly_dialog handle         */
  298. /*             startobj -> start object for draw      */
  299. /*             depth -> maximum depth to draw to      */
  300. /*                      EXTERNAL                      */
  301.  
  302. void fld_draw(short fldhandle, int startobj, int depth)  {
  303.     FLD *temp;
  304.     GRECT rect;
  305.  
  306.     temp = fld_getfld(fldhandle);
  307.     if (temp == NULL) return;
  308.  
  309.     fld_tempform = temp->form;
  310.     fld_tempstart = startobj;
  311.     fld_tempdepth = depth;
  312.  
  313.     wind_get(DESK, WF_PREVXYWH, &rect.g_x, &rect.g_y, &rect.g_w, &rect.g_h);
  314.     if (temp->focus != -1) objc_edit(temp->form, temp->focus, 0, &temp->index, ED_END);
  315.     wind_redraw(temp->windowhandle, &rect, fld_drawform);
  316.     if (temp->xredraw != NULL)
  317.         wind_redraw(temp->windowhandle, &rect, temp->xredraw);
  318.     if (temp->focus != -1) objc_edit(temp->form, temp->focus, 0, &temp->index, ED_INIT);
  319. }
  320.  
  321.  
  322. /* fld_key(): Deal with keypress                      */
  323. /*   Returns: -1 (FLDR_NONE) if no object selected    */
  324. /*            OR selected object                      */
  325. /*            kc -> keypress from evnt_multi()        */
  326. /*            relevent fly_dialog type -> type        */
  327. /*            relevent fly_dialog handle -> fldhandle */
  328. /*                      EXTERNAL                      */
  329.  
  330. short fld_key(short kc, short *type, short *fldhandle)  {
  331.     FLD *temp;
  332.     short windowhandle, nextob;
  333.  
  334.     wind_get(0, WF_TOP, &windowhandle, NULL, NULL, NULL);
  335.     temp = fld_findwin(windowhandle);
  336.     if (temp == NULL) return FLDR_NONE;
  337.  
  338.     *fldhandle = temp->fldhandle;
  339.     *type = temp->type;
  340.  
  341.  
  342.     if (temp->iconified == 0)  {
  343.             /* Process kc for special chars */
  344.         if (form_keybd(temp->form, temp->focus, 0, kc, &nextob, &kc) == 0)
  345.                 /* Return default object if <return> pressed */
  346.             return nextob;
  347.  
  348.             /* Process valid keypress */
  349.         if (kc)  {
  350.             objc_edit(temp->form, temp->focus, kc, &temp->index, ED_CHAR);
  351.         }
  352.  
  353.             /* Check for new focus object */
  354.         if ((nextob != 0) && (nextob != temp->focus) && (temp->focus != -1))  {
  355.             objc_edit(temp->form, temp->focus, 0, &temp->index, ED_END);
  356.             temp->focus = nextob;
  357.             objc_edit(temp->form, temp->focus, 0, &temp->index, ED_INIT);
  358.         }
  359.     }
  360.  
  361.     return FLDR_NONE;
  362. }
  363.  
  364.  
  365. /* fld_mouse(): Deal with mouse click                   */
  366. /*     Returns: -1 (FLDR_NONE) if no object selected    */
  367. /*              OR selected object                      */
  368. /*              x,y -> mouse pos. from evnt_multi()     */
  369. /*              numclicks -> number of clicks from      */
  370. /*                           evnt_multi                 */
  371. /*              relevent fly_dialog type -> type        */
  372. /*              relevent fly_dialog handle -> fldhandle */
  373. /*                      EXTERNAL                        */
  374.  
  375. short fld_mouse(short x, short y, short numclicks, short *type, short *fldhandle)  {
  376.     FLD *temp;
  377.     int obj;
  378.     short windowhandle, nextob;
  379.  
  380.     wind_get(0, WF_TOP, &windowhandle, NULL, NULL, NULL);
  381.     temp = fld_findwin(windowhandle);
  382.     if (temp == NULL) return FLDR_NONE;
  383.  
  384.     *fldhandle = temp->fldhandle;
  385.     *type = temp->type;
  386.  
  387.     if (temp->iconified == 0)  {
  388.         if ( (obj = objc_find(temp->form, 0, 7, x, y)) == -1)
  389.             return FLDR_NONE;
  390.  
  391.         if (form_button(temp->form, obj, numclicks, &nextob) == 0)
  392.             return obj;
  393.  
  394.             /* Check for new focus object */
  395.         if ((nextob != 0) && (nextob != temp->focus) && (temp->focus != -1))  {
  396.             objc_edit(temp->form, temp->focus, 0, &temp->index, ED_END);
  397.             temp->focus = nextob;
  398.             objc_edit(temp->form, temp->focus, 0, &temp->index, ED_INIT);
  399.         }
  400.     }
  401.  
  402.     return FLDR_NONE;
  403. }
  404.  
  405.  
  406. /* fld_event(): Handle GEM event                         */
  407. /*     Returns: -1 (FLDR_NONE) if dialogs still open     */
  408. /*           OR fldhandle of closed dialog               */
  409. /*              msgbuf -> message buffer from evnt_multi */
  410. /*                        EXTERNAL                       */
  411.  
  412. int fld_mesag(short *msgbuf)  {
  413.     FLD *temp;
  414.     short x, y, w, h;
  415.  
  416.     if (fld_first == NULL) return FLDR_NONE;
  417.  
  418.     switch (msgbuf[0])  {
  419.     case WM_REDRAW:
  420.         if ( (temp = fld_findwin(msgbuf[3])) == NULL)  return FLDR_NONE;
  421.         if (temp->iconified)
  422.             wind_redraw(temp->windowhandle, (GRECT *) (msgbuf + 4), fld_drawicon);
  423.         else  {
  424.             fld_tempform = temp->form;
  425.             fld_tempstart = 0;
  426.             fld_tempdepth = 7;
  427.             if (temp->focus != -1)  objc_edit(temp->form, temp->focus, 0, &temp->index, ED_END);
  428.                 wind_redraw(temp->windowhandle, (GRECT *) (msgbuf + 4), fld_drawform);
  429.             if (temp->xredraw != NULL)
  430.                 wind_redraw(temp->windowhandle, (GRECT *) (msgbuf + 4), temp->xredraw);
  431.             if (temp->focus != -1)  objc_edit(temp->form, temp->focus, 0, &temp->index, ED_INIT);
  432.         }
  433.         break;
  434.     case WM_MOVED:
  435.         if ( (temp = fld_findwin(msgbuf[3])) == NULL)  return FLDR_NONE;
  436.         if (temp->iconified == 0)
  437.             if (temp->focus != -1)  objc_edit(temp->form, temp->focus, 0, &temp->index, ED_END);
  438.         wind_get(temp->windowhandle, WF_CURRXYWH, &x, &y, &w, &h);
  439.         wind_set(temp->windowhandle, WF_CURRXYWH, msgbuf[4], msgbuf[5], msgbuf[6], msgbuf[7]);
  440.         if (temp->iconified == 0)  {
  441.             temp->form->ob_x += msgbuf[4] - x;
  442.             temp->form->ob_y += msgbuf[5] - y;
  443.             if (temp->focus != -1)  objc_edit(temp->form, temp->focus, 0, &temp->index, ED_INIT);
  444.         }
  445.         break;
  446.     case WM_TOPPED:
  447.         if ( (temp = fld_findwin(msgbuf[3])) == NULL)  return FLDR_NONE;
  448.         wind_set(temp->windowhandle, WF_TOP);
  449.         break;
  450.     case WM_CLOSED:
  451.         if ( (temp = fld_findwin(msgbuf[3])) == NULL)  return FLDR_NONE;
  452.         return temp->fldhandle;
  453.         break;
  454.     case WM_ICONIFY:
  455.         if ( (temp = fld_findwin(msgbuf[3])) == NULL)  return FLDR_NONE;
  456.         wind_set(temp->windowhandle, WF_ICONIFY, msgbuf[4], msgbuf[5], msgbuf[6], msgbuf[7]);
  457.         temp->iconified = 1;
  458.         if (fld_iconinitialised == 0)  {
  459.             fld_iconinitialised = 1;
  460.             rsrc_init();
  461.         }
  462.         break;
  463.     case WM_UNICONIFY:
  464.         if ( (temp = fld_findwin(msgbuf[3])) == NULL)  return FLDR_NONE;
  465.         wind_set(temp->windowhandle, WF_UNICONIFY, msgbuf[4], msgbuf[5], msgbuf[6], msgbuf[7]);
  466.         temp->iconified = 0;
  467.         break;
  468.     }
  469.     
  470.     return FLDR_NONE;
  471. }
  472.  
  473.  
  474. /* fld_exit(): Clean up on program exit                  */
  475. /*                        EXTERNAL                       */
  476.  
  477. void fld_exit(void)  {
  478.     while (fld_first != NULL)  {
  479.         wind_close(fld_first->windowhandle);
  480.         wind_delete(fld_first->windowhandle);
  481.         fld_remove(fld_first->fldhandle);
  482.     }
  483. }
  484.  
  485.  
  486. /* fld_close(): Close fly_dialog                         */
  487. /*              fldhandle -> fly_dialog handle           */
  488. /*                        EXTERNAL                       */
  489.  
  490. void fld_close(short fldhandle)  {
  491.     FLD *temp;
  492.  
  493.     if ( (temp = fld_getfld(fldhandle)) == NULL)
  494.         return;
  495.  
  496.     wind_close(temp->windowhandle);
  497.     wind_delete(temp->windowhandle);
  498.     fld_remove(fldhandle);
  499. }
  500.  
  501.  
  502. /* fld_getwin(): Get windowhandle for given fldhandle    */
  503. /*      Returns: -1 if fly_dialog not found              */
  504. /*               OR window handle                        */
  505. /*               fldhandle -> fly_dialog handle          */
  506. /*                        EXTERNAL                       */
  507.  
  508. int fld_getwin(short fldhandle)  {
  509.     FLD *temp;
  510.  
  511.     if ( (temp = fld_getfld(fldhandle)) == NULL)
  512.         return -1;
  513.  
  514.     return temp->windowhandle;
  515. }
  516.  
  517.  
  518. /* fld_getform(): Get object tree for given fldhandle    */
  519. /*       Returns: NULL if fly_dialog not found           */
  520. /*                OR pointer to tree                     */
  521. /*                fldhandle -> fly_dialog handle         */
  522. /*                        EXTERNAL                       */
  523.  
  524. OBJECT *fld_getform(short fldhandle)  {
  525.     FLD *temp;
  526.  
  527.     if ( (temp = fld_getfld(fldhandle)) == NULL)
  528.         return NULL;
  529.  
  530.     return temp->form;
  531. }
  532.  
  533.  
  534. /* fld_findtype(): Get fly_dialog for given type         */
  535. /*        Returns: NULL if type not found                */
  536. /*                 OR pointer to fly_dialog              */
  537. /*                 type -> fly_dialog type               */
  538. /*                        EXTERNAL                       */
  539.  
  540.  
  541. FLD *fld_findtype(short type)  {
  542.     FLD *temp = fld_first;
  543.  
  544.     for (; temp != NULL; temp = temp->next)
  545.         if (temp->type == type) break;
  546.  
  547.     return temp;
  548. }
  549.  
  550.  
  551. /* fld_findform(): Get fly_dialog for given form         */
  552. /*        Returns: NULL if form not found                */
  553. /*                 OR pointer to fly_dialog              */
  554. /*                 form -> address of object tree        */
  555. /*                        EXTERNAL                       */
  556.  
  557.  
  558. FLD *fld_findform(OBJECT *form)  {
  559.     FLD *temp = fld_first;
  560.  
  561.     for (; temp != NULL; temp = temp->next)
  562.         if (temp->form == form) break;
  563.  
  564.     return temp;
  565. }
  566.  
  567.  
  568. /* fld_ability(): Set ability of program to handle new   */
  569. /*                FLDLIB features                        */
  570. /*                bitmask -> bitmask of features handled */
  571. /*                       EXTERNAL                        */
  572.  
  573. void fld_ability(int bitmask)  {
  574.     fld_progability = bitmask;
  575. }
  576.  
  577.  
  578. /* fld_do(): Manage single flying dialog                 */
  579. /*  Returns: index of object clicked on                  */
  580. /*           -1 if there are already flying dialogs open */
  581. /*           -1 (FLDR_NONE) if the dialog is closed      */
  582. /*              without an object being clicked          */
  583. /*              (when fld_ability(FLDA_CLOSE); called)   */
  584. /*           tree -> object tree to manage               */
  585. /*           title -> title of window                    */
  586. /*                        EXTERNAL                       */
  587.  
  588. short fld_do(OBJECT *tree, char *title)  {
  589.     short msgbuf[8], mx, my, mb, mk, kc, numclicks, evnts, ret, fldhandle, type;
  590.  
  591.     if (fld_first != NULL) return -1;
  592.  
  593.     fld_open(tree, FLDC_SCREEN, title, 0);
  594.  
  595.     while (1)  {
  596.         evnts = evnt_multi(MU_KEYBD|MU_BUTTON|MU_MESAG, 2, 1, 1,  /* Flags + clicks */
  597.                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* Rects to watch (none) */
  598.                            msgbuf, 0, 0, &mx, &my, &mb, &mk, /* Msg buffer + mouse click */
  599.                            &kc, &numclicks);
  600.  
  601.         if (evnts & MU_KEYBD)
  602.             if ((ret = fld_key(kc, &type, &fldhandle)) != FLDR_NONE)  {
  603.                 fld_close(fldhandle);
  604.                 return ret;
  605.             }
  606.         if (evnts & MU_BUTTON)
  607.             if ((ret = fld_mouse(mx, my, numclicks, &type, &fldhandle)) != FLDR_NONE)  {
  608.                 fld_close(fldhandle);
  609.                 return ret;
  610.             }
  611.         if (evnts & MU_MESAG)
  612.             if ((ret = fld_mesag(msgbuf)) != FLDR_NONE)  {
  613.                 fld_close(ret);
  614.                 return FLDR_NONE;
  615.             }
  616.     }
  617.  
  618.     return 0;
  619. }
  620.  
  621.  
  622. /* fld_domulti(): Manage multiple flying dialogs                */
  623. /*       Returns: index of object clicked on                    */
  624. /*             OR the negative fldhandle of a closed dialog     */
  625. /*                type of fly_dialog with selected obj -> type  */
  626. /*                fly_dialog handle -> fldhandle                */
  627. /*                             EXTERNAL                         */
  628.  
  629. short fld_domulti(short *type, short *fldhandle)  {
  630.     short msgbuf[8], mx, my, mb, mk, kc, numclicks, evnts, ret;
  631.  
  632.     while (1)  {
  633.         evnts = evnt_multi(MU_KEYBD|MU_BUTTON|MU_MESAG, 2, 1, 1,  /* Flags + clicks */
  634.                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* Rects to watch (none) */
  635.                            msgbuf, 0, 0, &mx, &my, &mb, &mk, /* Msg buffer + mouse click */
  636.                            &kc, &numclicks);
  637.  
  638.         if (evnts & MU_KEYBD)
  639.             if ((ret = fld_key(kc, type, fldhandle)) != FLDR_NONE)  {
  640.                 return ret;
  641.             }
  642.         if (evnts & MU_BUTTON)
  643.             if ((ret = fld_mouse(mx, my, numclicks, type, fldhandle)) != FLDR_NONE)  {
  644.                 return ret;
  645.             }
  646.         if (evnts & MU_MESAG)
  647.             if ((ret = fld_mesag(msgbuf)) != FLDR_NONE)  {
  648.                 return -ret;
  649.             }
  650.     }
  651.  
  652.     return 0;
  653. }