home *** CD-ROM | disk | FTP | other *** search
/ Computer Club Elmshorn Atari PD / CCE_PD.iso / pc / 0600 / CCE_0682.ZIP / CCE_0682.PD / DSPSHELL / C_SOURCE / POWERGEM.C < prev    next >
C/C++ Source or Header  |  1993-09-23  |  73KB  |  2,286 lines

  1. /* ---------------------------------------------------------------------- */
  2. /* PowerGem Library, Version 1.1                                          */
  3. /*                                                                          */
  4. /* by Boris Sander                                                          */
  5. /* Gerh.-Hauptmann-Str. 23                                                  */
  6. /* 4350 Recklinghausen                                                      */
  7. /*                                                                          */
  8. /* Copyright (c) 1992 by ICP - Innovativ Computer-Presse GmbH & Co. KG    */
  9. /* erweitert und, soweit sichtbar ,fehlerbereinigt von Mario Bahr              */
  10. /* ---------------------------------------------------------------------- */
  11. #include <stdio.h>
  12. #include <stddef.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <aes.h>
  16. #include <vdi.h>
  17. #include <tos.h>
  18. #include "powergem.h"
  19.  
  20. /* gehört eigentlich in aes.h */
  21. #ifndef WF_BOTTOM
  22. #define WF_BOTTOM 25
  23. #endif
  24. /* ---------------------------------------------------------------------- */
  25. /* Funktionsprototypen                                                    */
  26. /* ---------------------------------------------------------------------- */
  27. struct WINDOW      *alloc_window(void);
  28. struct BUTTON_LIST *alloc_button(struct WINDOW *win);
  29. struct KEY_LIST    *alloc_key(void);
  30. struct MENU_LIST   *alloc_menu(void);
  31. struct MSG_LIST    *alloc_msg(void);
  32.  
  33. boolean compare_grect(GRECT *r1, GRECT *r2);
  34. void    copy_grect(GRECT *r1, GRECT *r2);
  35. void    clipping(int vdi_handle, GRECT *r, int mode);
  36. void    blank(struct WINDOW *, int x, int y, int w, int h);
  37.  
  38. void sort_win_by_top(struct WINDOW *win);
  39. void kill_window(int wh);
  40. void win_manager(int msg, struct WINDOW *win, int x, int y, int w, int h);
  41. void change_slider_size(struct WINDOW *win);
  42. void new_slider_pos(struct WINDOW *win);
  43. void hndl_slider_pos(struct WINDOW *win, int what, int position);
  44.  
  45. int  find_obj(OBJECT *tree);
  46. int  fm_inifld(OBJECT *tree, int start_fld);
  47. void draw_dial(struct WINDOW *win, GRECT *rc);
  48. void draw_object(struct WINDOW *win,int obj_index);
  49. void align_dial(struct WINDOW *win);
  50. void align_panel(struct WINDOW *win);
  51. boolean check_rect(int x,int y,GRECT *rect);
  52.  
  53. void button_manager(int m_x, int m_y, int m_button, int k_state);
  54. void kill_button(struct WINDOW *win);
  55.  
  56. void key_manager(int code);
  57. void kill_key(void);
  58.  
  59. void menu_manager(int title, int item, int scan_code);
  60. void menu_all_change(int menu_flag);          
  61. void kill_menu(void);
  62.  
  63. void msg_manager(int *event);
  64. void kill_msg(void);
  65. void all_free(void);
  66.  
  67. #define DESK_TOP (void *)-1UL
  68. /* ---------------------------------------------------------------------- */
  69. /* Globale Variablen                                                      */
  70. /* ---------------------------------------------------------------------- */
  71. struct MSG_LIST  *msg_start;
  72. struct KEY_LIST  *key_start;
  73. struct MENU_LIST *menu_start; 
  74. struct WINDOW *start, *help; 
  75. MFDB screen;                 /* Struktur für Bildschirmparameter   */
  76.  
  77. struct A_CNTRL app_cntrl;
  78.  
  79. /* ---------------------------------------------------------------------- */
  80. /* Programmdeskriptor initialisieren, Resourcedatei laden, Menü darst.    */
  81. /* ---------------------------------------------------------------------- */
  82. boolean init_powergem(char *rsc_name, int menu_index)
  83. {
  84.     register int i;
  85.     int phys_handle;
  86.     int work_in[11], work_out[57],work_ext[57];
  87.     char alert_text[80];
  88.     /* Alle globalen Variablen Null setzen */
  89.     msg_start  = NULL;
  90.     key_start  = NULL;
  91.     menu_start =  NULL;
  92.     start= help = NULL;
  93.     memset( &app_cntrl, 0, sizeof(struct A_CNTRL));
  94.  
  95.     if ((app_cntrl.ap_id = appl_init()) != -1)
  96.     {
  97.         phys_handle = graf_handle(&app_cntrl.gl_wchar, &app_cntrl.gl_hchar,
  98.                                   &app_cntrl.gl_wbox, &app_cntrl.gl_hbox);
  99.         work_in[0] = Getrez() + 2;
  100.         for (i =1 ; i < 10; work_in[i++] = 1);
  101.         work_in[10] = 2;
  102.         app_cntrl.vdi_handle = phys_handle;
  103.  
  104.         v_opnvwk(work_in, &app_cntrl.vdi_handle, work_out);
  105.         vq_extnd(app_cntrl.vdi_handle,1,work_ext);
  106.  
  107.        /* füllt die vollständige BITBLK-Struktur des Bildschirms */     
  108.        screen.fd_addr=NULL;              /* Bildspeicherbasisadresse */
  109.        screen.fd_w=work_out[0]+1;     /* Blockbreite in Pixeln    */
  110.        screen.fd_h=work_out[1]+1;     /* Höhe des Blocks in Pixeln*/
  111.        screen.fd_wdwidth=((screen.fd_w+15)>>4);
  112.                                         /* Blockbreite in Integern  */
  113.        screen.fd_stand=0;            /* geräteabhängiges Format  */
  114.        screen.fd_nplanes=work_ext[4];/* Anzahl der Farbebenen    */
  115.        screen.fd_r1=screen.fd_r2=screen.fd_r3=0;
  116.                                         /* reserviert               */
  117.     }
  118.     else
  119.     {
  120.         sprintf(alert_text, "[3][Applikation konnte nicht|angemeldet werden!|"
  121.                 "][Abbruch]");
  122.         form_alert(1, alert_text);
  123.         return(FALSE);
  124.     } 
  125.  
  126.     /* Warnung, wenn Resource-Datei nicht geladen werden konnte -> Abbruch */
  127.     if (!rsrc_load(rsc_name))
  128.     { 
  129.         sprintf(alert_text, "[3][Die Resource-Datei|  %s|konnte nicht geladen|"
  130.                 "werden!][Abbruch]", rsc_name);
  131.         form_alert(1, alert_text);
  132.         return(FALSE);
  133.     }    
  134.     
  135.     if (rsrc_gaddr(0, menu_index, &app_cntrl.menu))
  136.         menu_bar(app_cntrl.menu, 1);
  137.     else 
  138.         return(FALSE);
  139.     
  140.     wind_get(0, WF_WORKXYWH, &app_cntrl.workarea.g_x,
  141.              &app_cntrl.workarea.g_y, &app_cntrl.workarea.g_w, 
  142.              &app_cntrl.workarea.g_h);
  143.     return(TRUE);
  144. }
  145. /***********************************************************
  146.  * Stellt den DESKTOP-Hintergrund dar                        *    
  147.  ***********************************************************/
  148. boolean init_desktop(int desk)
  149. {
  150. OBJECT *desktop;
  151. extern GEMPARBLK _GemParBlk;
  152. if(rsrc_gaddr(R_TREE,desk,&desktop) &&     _GemParBlk.global[0]<0x0400
  153.                                          && _GemParBlk.global[1] == 1  )
  154.     {
  155.     desktop[ROOT].ob_x =app_cntrl.workarea.g_x;
  156.     desktop[ROOT].ob_y =app_cntrl.workarea.g_y;
  157.     desktop[ROOT].ob_width =app_cntrl.workarea.g_w;
  158.     desktop[ROOT].ob_height=app_cntrl.workarea.g_h;
  159.     wind_set(0,WF_NEWDESK,desktop,ROOT,MAX_DEPTH);
  160.         objc_draw(desktop, 0,ROOT, desktop[ROOT].ob_x
  161.          , desktop[ROOT].ob_y, desktop[ROOT].ob_width,desktop[ROOT].ob_height);
  162.     }
  163. else
  164.     return FALSE;
  165. return TRUE;
  166. }
  167. /***************************
  168.  * Screenadresse ermitteln *
  169.  ***************************/
  170. MFDB *get_screen(void)
  171. {
  172.     return(&screen);
  173. }
  174. /***************************************** 
  175.  * Oberstes Fenster je nach Typ          *
  176.  * Input:  Typ des Fensters                 *
  177.  * Output: wh_handle                     *
  178.  *****************************************/
  179. struct WINDOW *get_lastwin(int typ) 
  180. {
  181. struct WINDOW *win_b;
  182.  
  183. win_b=start;
  184. if(win_b == NULL)
  185.     return NULL;
  186. if( (win_b->type&3) == typ)
  187.    return start;        /* Etwa oberstes Fenster ? */
  188.  
  189. while(win_b->next != NULL)
  190.     {
  191.     win_b=win_b->next;
  192.     if((win_b->type&3) == typ)
  193.         return win_b;       
  194.     }
  195. return NULL;
  196. }    
  197. /**************************************************
  198.  * Ermittlungn des Powergemeigenen VDI-Handles    *
  199.  **************************************************/
  200. int get_handle(void)
  201. {
  202.     return(app_cntrl.vdi_handle);
  203. }    
  204.  
  205. /**************************************
  206.  * PowerGEM anmelden zum verlassen       *
  207.  **************************************/
  208. void exit_powergem(void)
  209. {
  210. app_cntrl.quit = TRUE;    /* Quit-Flag auf TRUE setzen (für multi) */
  211. }
  212. /******************************************
  213.  * Gibt die Resourcen von PowerGEM frei   *
  214.  ******************************************/
  215. void all_free(void)
  216. {
  217. int x,y,w,h,wh;
  218. extern GEMPARBLK _GemParBlk;
  219.     
  220. /* Prüfen, ob noch Fenster offen sind */
  221. help = start;
  222. while(start)
  223.     {
  224.     /* Fenster schließen, Speicher freigeben */
  225.     start = help->next;
  226.     wind_get(help->w_handle, WF_CURRXYWH, &x, &y, &w, &h);
  227.     graf_shrinkbox(0,0,0,0, x,y,w,h);
  228.     wind_close(help->w_handle); 
  229.     wind_delete(help->w_handle);
  230.     if ((help->type & DIAL_WINDOW) || (help->type & PANEL_WINDOW))
  231.         kill_button(help);
  232.     if(help->close_code)
  233.         help->close_code(help);/* Resourcen des Anwenders ebenfalls freigeben */
  234.     kill_window(help->w_handle); 
  235.     help = start;
  236.     }
  237.             
  238. /* evtl. Key-Liste freigeben */
  239. if (key_start)
  240.     kill_key();
  241.  
  242. /* evtl. Message-Liste freigeben */ 
  243. if (msg_start)
  244.     kill_msg();
  245.     
  246. /* evtl. Menu-Liste freigeben */
  247. if (menu_start)
  248.     kill_menu();
  249.         
  250. /* Menü löschen */
  251.     menu_bar(app_cntrl.menu, 0);
  252.  
  253. /* Resource-Speicher freigeben */
  254.     rsrc_free();
  255.  
  256. /* Erst ab TOS 1.4 ! -Fenster der Accssories auch schließen !*/
  257. wind_get(0, WF_TOP, &wh, 0,0,0);/* Oberstes Fenster ermitteln  */  
  258. if(_GemParBlk.global[0] >= 0x140 && wh > 0)
  259.     wind_new();      
  260. }
  261. /* ---------------------------------------------------------------------- */
  262. /* Adresse des Programmdeskriptors ermitteln                              */
  263. /* ---------------------------------------------------------------------- */
  264. struct A_CNTRL *get_app_cntrl()
  265. {
  266.     return(&app_cntrl);
  267. }
  268. /**************************************************************************
  269.  * Sortiert WINDOW-next-Pointer neu (für Fensterreihenfolge bei Tastatur- * 
  270.  * topping)                                                               *
  271.  * Zugriff auf globalen start-Zeiger                                      *
  272.  * Input: win getopptes Fenster                                            *    
  273.  **************************************************************************/
  274. void sort_win_by_top(struct WINDOW *win)
  275. {
  276. struct WINDOW *win_b;
  277.  
  278. win_b=start;
  279.     
  280. if( win != start)         /* sonst win schon oberstes Fenster */
  281.     {
  282.     while(win_b->next != win) /* Vorgänger suchen */
  283.         win_b = win_b->next;
  284.     win_b->next = win->next; /* Bekommt nun Zeiger auf dem ich zeige    */
  285.     win->next = start;       /* Zeige nun auf das ehemals erste Element */
  286.     start = win;             /* Werde erstes Element                    */
  287.     }
  288. }    
  289.  
  290. /**************************************************************************
  291.  * Speicher für WINDOW-Struktur alloziieren                               *
  292.  **************************************************************************/
  293. struct WINDOW *alloc_window(void)
  294. {
  295.     help = start;           
  296.     start = (struct WINDOW *)calloc(1,sizeof(struct WINDOW)); 
  297.     if (!start)
  298.         return(NULL);
  299.     start->next = help;     
  300.     return(start);          
  301. }
  302.  
  303. /************************************************************************
  304.  * WINDOW-struct-Speicher freigeben                                     *
  305.  * Input: wh Fensterhandle                                              *
  306.  ************************************************************************/
  307. void kill_window(int wh)
  308. {
  309. struct WINDOW *ptr;
  310.  
  311. ptr = get_winfh(wh);            
  312. if (ptr) 
  313.     {
  314.     help = start; 
  315.     if (help == ptr)    /* Wenn erstes Element */             
  316.         {
  317.         if (ptr->next)   /* wenn es einen Nachfolger gibt */
  318.             {
  319.             start = help->next; /* Element freigeben, Zeiger verbiegen */
  320.             if (ptr->slider)
  321.                 free(ptr->slider);    
  322.             if (ptr->dialog)         
  323.                 free(ptr->dialog);    
  324.             free(ptr); 
  325.             }
  326.         else        
  327.             {
  328.             start = help = NULL; /* Es gibt keinen Nachfolger -> alles */
  329.             if (ptr->slider)        /* auf NULL setzen, freigeben */
  330.                 free(ptr->slider);
  331.             if (ptr->dialog)
  332.                 free(ptr->dialog);
  333.             free(ptr);
  334.             }
  335.         }
  336.     else 
  337.         {                                    
  338.         while (help->next != ptr) /* Vorgänger suchen */
  339.             help = help->next;
  340.                 
  341.         if (!ptr->next)   /* Wenn es keinen Nachfolger gibt */ 
  342.             {
  343.             help->next = 0; /* dann löschen */
  344.             if (ptr->slider)
  345.                 free(ptr->slider);
  346.             if (ptr->dialog)
  347.                 free(ptr->dialog);
  348.             free(ptr);
  349.             }
  350.         else              /* Ansonsten Zeiger verbiegen und löschen */
  351.             {
  352.             help->next = ptr->next;
  353.             if (ptr->slider)
  354.                 free(ptr->slider);
  355.             if (ptr->dialog)
  356.                 free(ptr->dialog);
  357.             free(ptr);
  358.             }
  359.         }
  360.     }
  361. }
  362.  
  363. /* ---------------------------------------------------------------------- */
  364. /* Suche anhand des gegebenen Window Handles die passende WINDOW Struktur */
  365. /* Ergebnis: Adresse der WINDOW Struktur, ansonsten NULL                    */
  366. /* ---------------------------------------------------------------------- */
  367. struct WINDOW *get_winfh(int wh)
  368. {
  369.     help = start;
  370.     while(help)
  371.     {
  372.         if (help->w_handle == wh)
  373.             return(help);
  374.         help = help->next;
  375.     }
  376.     return(NULL);
  377. }
  378.  
  379. /* ---------------------------------------------------------------------- */
  380. /* Suche anhand des gegebenen Fensternamens die passende WINDOW Struktur  */
  381. /* Ergebnis: Adresse der WINDOW Struktur, ansonsten NULL                    */
  382. /* ---------------------------------------------------------------------- */
  383. struct WINDOW *get_winfn(char *name)
  384. {
  385.     help = start;
  386.     while(help)
  387.     {
  388.         if (!(strcmp(help->name, name)))
  389.             return(help);
  390.         help = help->next;
  391.     }
  392.     return(NULL);
  393. }
  394. /**************************************************************************
  395.  * Stellt das aktive Fenster fest                                         *
  396.  * Output: Zeiger auf WINDOW-Struktur oder NULL                           *
  397.  **************************************************************************/
  398.  struct WINDOW *get_activwin(void)
  399.  {
  400.  int wh;
  401.  
  402. wind_get(0, WF_TOP, &wh, 0,0,0);     /* Oberstes Fenster ermitteln  */  
  403. if(wh > 0)
  404.     return(get_winfh(wh));
  405. return NULL;
  406.  }
  407.   
  408. /**************************************************************************
  409.  * Macht das jetzige Fenster zum letzten                                  *
  410.  * Zugriff auf globalen start-Zeiger                                      *
  411.  **************************************************************************/
  412. void untop_win(void)
  413. {
  414. struct WINDOW *win_b1,*win_b2;
  415.  
  416. if(start == NULL)
  417.     return;
  418.     
  419. if( start->next != NULL)
  420.     {
  421.     win_b1=start;
  422.     win_b2=start;
  423.     wind_set(start->w_handle, WF_BOTTOM, 0,0,0,0); 
  424.  
  425.     start=start->next;    /* darunterliegende Fenster nach oben */
  426.     while( win_b2->next != NULL)  /* letzte Fenster suchen */
  427.         win_b2=win_b2->next;
  428.  
  429.     win_b2->next=win_b1; /* erhält Zeiger auf ehemals erstes Fenster     */
  430.     win_b1->next=NULL;   /* ehemals erstes Fenster hat keinen Nachfolger */    
  431.     wind_set(start->w_handle, WF_TOP, 0,0,0,0); 
  432.     app_cntrl.w_handle = start->w_handle;
  433.     if (start->type & DIAL_WINDOW)         /* üblichen Reaktionen */
  434.         start->dialog->cont = TRUE;
  435.     if (start->type & DIAL_WINDOW)
  436.         start->dialog->cont = TRUE;
  437.     if(start->wtop_code)         /* Erste Reaktion des Fensters */ 
  438.         start->wtop_code(start);
  439.     }
  440. }
  441. /* ---------------------------------------------------------------------- */
  442. /* Kopieren einer Rechteckstruktur                                        */
  443. /* ---------------------------------------------------------------------- */
  444. void copy_grect(GRECT *src, GRECT *dest)
  445. {
  446.     dest->g_x = src->g_x;
  447.     dest->g_y = src->g_y;
  448.     dest->g_w = src->g_w;
  449.     dest->g_h = src->g_h;
  450. }
  451.  
  452. /* ---------------------------------------------------------------------- */
  453. /* Vergleich zweier Rechteckstrukturen, Ergebnis: TRUE oder FALSE         */
  454. /* ---------------------------------------------------------------------- */
  455. boolean compare_grect(GRECT *r1, GRECT *r2)
  456. {
  457.     return((r1->g_x & r2->g_x) &
  458.            (r1->g_y & r2->g_y) &
  459.            (r1->g_w & r2->g_w) &
  460.            (r1->g_h & r2->g_h));
  461. }
  462.     
  463. /* ---------------------------------------------------------------------- */
  464. /* Schnittmenge zweier Rechtecke berechnen                                */
  465. /* ---------------------------------------------------------------------- */
  466. boolean rc_intersect(GRECT *r1, GRECT *r2)
  467. {
  468.     int x, y, w, h;
  469.     
  470.     x = max(r2->g_x, r1->g_x);
  471.     y = max(r2->g_y, r1->g_y);
  472.     w = min(r2->g_x + r2->g_w, r1->g_x + r1->g_w);
  473.     h = min(r2->g_y + r2->g_h, r1->g_y + r1->g_h);
  474.     r2->g_x = x;
  475.     r2->g_y = y;
  476.     r2->g_w = w - x;
  477.     r2->g_h = h - y;
  478.     return((boolean)((w > x) && (h > y)));
  479. }
  480.  
  481. /* ---------------------------------------------------------------------- */
  482. /* Bildschirmausgabe "clippen"                                            */
  483. /* ---------------------------------------------------------------------- */
  484. void clipping(int vdi_handle, GRECT *r, int mode)
  485. {
  486.     int pxy[4];
  487.     
  488.     pxy[0] = r->g_x;
  489.     pxy[1] = r->g_y;
  490.     pxy[2] = r->g_x + r->g_w - 1;
  491.     pxy[3] = r->g_y + r->g_h - 1;
  492.     vs_clip(vdi_handle, mode, pxy);
  493. }
  494.  
  495. /* ---------------------------------------------------------------------- */
  496. /* Bereich löschen                                                        */
  497. /* ---------------------------------------------------------------------- */
  498. /* Alle Füllattributeinstellungen der Workstation werden gesichert und    */
  499. /* zurückgesetzt                                                            */
  500. /* ---------------------------------------------------------------------- */
  501. void blank(struct WINDOW *win, int x, int y, int w, int h)
  502. {
  503.     GRECT r1, r2;
  504.     int pxy[4];
  505.     int attr[5];
  506.  
  507.     if(start == NULL)
  508.         return;
  509.         
  510.     vqf_attributes(app_cntrl.vdi_handle, attr);
  511.     if(win==NULL) /* Alles updaten */
  512.         {
  513.         win=start;
  514.         x=app_cntrl.workarea.g_x;
  515.         y=app_cntrl.workarea.g_y;
  516.         w=app_cntrl.workarea.g_w;
  517.         h=app_cntrl.workarea.g_h;
  518.         }
  519.     else
  520.         {
  521.         if(win->type&8)        
  522.             return;    /* Dieses Fenster wird geschloßen -> REDRAW sinnlos */
  523.         }
  524.     r2.g_x = pxy[0] = x;
  525.     r2.g_y = pxy[1] = y;
  526.     r2.g_w = w;
  527.     r2.g_h = h;
  528.     pxy[2] = x + w - 1;
  529.     pxy[3] = y + h - 1;
  530.     
  531.     graf_mouse(M_OFF, 0);
  532.     wind_get(win->w_handle, WF_FIRSTXYWH, &r1.g_x, &r1.g_y, &r1.g_w,
  533.                 &r1.g_h);
  534.     
  535.     while (r1.g_w && r1.g_h)
  536.         {
  537.         if (rc_intersect(&r2, &r1) == TRUE)
  538.             {
  539.             clipping(app_cntrl.vdi_handle, &r1, TRUE);
  540.             vsf_color(app_cntrl.vdi_handle, 1);
  541.             vsf_interior(app_cntrl.vdi_handle, 0);
  542.             vsf_style(app_cntrl.vdi_handle, 0);
  543.             vswr_mode(app_cntrl.vdi_handle, 0);
  544.             vsf_perimeter(app_cntrl.vdi_handle, 0);
  545.             wind_update(BEG_UPDATE);
  546.             if ((win->type&3) != DIAL_WINDOW)
  547.                 {    
  548.                 if (win->type & PANEL_WINDOW)
  549.                     {
  550.                     v_bar(app_cntrl.vdi_handle, pxy);
  551.                     draw_dial(win, &r1);
  552.                     }
  553.                 if(win->draw_code)
  554.                     win->draw_code(win);
  555.                 }
  556.             else
  557.                 draw_dial(win, &r1);
  558.             wind_update(END_UPDATE);
  559.             clipping(app_cntrl.vdi_handle, &r1, FALSE);
  560.             vsf_interior(app_cntrl.vdi_handle,  attr[0]);
  561.             vsf_color(app_cntrl.vdi_handle,     attr[1]);
  562.             vsf_style(app_cntrl.vdi_handle,     attr[2]);
  563.             vswr_mode(app_cntrl.vdi_handle,     attr[3]);
  564.             vsf_perimeter(app_cntrl.vdi_handle, attr[4]);
  565.         }
  566.         wind_get(win->w_handle, WF_NEXTXYWH, &r1.g_x, &r1.g_y, &r1.g_w,
  567.                   &r1.g_h);
  568.     }
  569.     clipping(app_cntrl.vdi_handle, &r1, FALSE);
  570.     graf_mouse(M_ON, 0);
  571. }
  572.  
  573.  
  574. /* ---------------------------------------------------------------------- */
  575. /* Rechteck #1 beobachten                                                 */
  576. /* ---------------------------------------------------------------------- */
  577. void watch_r1(int flag, GRECT *rc, void (*code)(void))
  578. {
  579.     if (rc)
  580.         app_cntrl.multi_flags |= MU_M1;
  581.     else
  582.         app_cntrl.multi_flags &= ~MU_M1;
  583.  
  584.     app_cntrl.m1_flag = flag;
  585.     copy_grect(rc, &app_cntrl.m1);
  586.     app_cntrl.m1_code = code;
  587. }
  588.  
  589. /* ---------------------------------------------------------------------- */
  590. /* Rechteck #2 beobachten                                                 */
  591. /* ---------------------------------------------------------------------- */
  592. void watch_r2(int flag, GRECT *rc, void (*code)(void))
  593. {
  594.     if (rc)
  595.         app_cntrl.multi_flags |= MU_M2;
  596.     else
  597.         app_cntrl.multi_flags &= ~MU_M2;
  598.  
  599.     app_cntrl.m2_flag = flag;
  600.     copy_grect(rc, &app_cntrl.m2);
  601.     app_cntrl.m2_code = code;
  602. }
  603.  
  604. /* ---------------------------------------------------------------------- */
  605. /* Zeitabschnitt abwarten                                                 */
  606. /* ---------------------------------------------------------------------- */
  607. void watch_timer(int low, int high, void (*code)(void))
  608. {
  609.     if (low == 0 && high == 0)
  610.         app_cntrl.multi_flags &= ~MU_TIMER;
  611.  
  612.     else
  613.         app_cntrl.multi_flags |= MU_TIMER;
  614.  
  615.     app_cntrl.mt_locount = low;
  616.     app_cntrl.mt_hicount = high;
  617.     app_cntrl.time_code  = code;
  618. }
  619.  
  620. /* ---------------------------------------------------------------------- */
  621. /* Ereignisse einstellen, auf die multi() reagiert                        */
  622. /* ---------------------------------------------------------------------- */
  623. void watch_events(int flags, int clicks, int mask, int state)
  624. {
  625.     app_cntrl.multi_flags = flags;
  626.     app_cntrl.mb_clicks   = clicks;
  627.     app_cntrl.mb_mask     = mask;
  628.     app_cntrl.mb_state    = state;
  629. }
  630.  
  631.  
  632. /* ---------------------------------------------------------------------- */
  633. /* Ereignisverwaltung                                                     */
  634. /* ---------------------------------------------------------------------- */
  635. void multi()
  636. {
  637. int event = 0, mmo_x, mmo_y, mm_button, mmok_state, mk_return, mb_return;
  638. int msgbuff[8] = {0,0,0,0,0,0,0,0},
  639.      buffer[8]  = {0,0,0,0,0,0,0,0};
  640. int sel_obj, obj_state;
  641. GRECT h1,h2;
  642. struct WINDOW *win;
  643. struct BUTTON_LIST *button_help;
  644. int wh;
  645.  
  646. do
  647. {
  648.     copy_grect(&app_cntrl.m1, &h1);
  649.     copy_grect(&app_cntrl.m2, &h2); 
  650.     if(app_cntrl.modal != NULL)            /* wenn modales Fenster */
  651.         win=app_cntrl.modal;
  652.     else
  653.         {
  654.         wind_get(0, WF_TOP, &wh, 0,0,0);     /* Oberstes Fenster ermitteln  */  
  655.         win = get_winfh(app_cntrl.w_handle); 
  656.         if(win)
  657.             {
  658.             /* Modale Dialogbox -> andere Aktionen sperren */
  659.             if((win->type&MODAL)==MODAL && app_cntrl.modal == NULL )
  660.                 {
  661.                 app_cntrl.modal = win;
  662.                 menu_all_change(0);    /* alle Menüeinträge disablen   */      
  663.                                 /* (ACC noch bedienbar !!       */
  664.                 }
  665.             }
  666.         }                
  667.     /* Wenn externes Fenster 'getopped' ist und wenn es sich um einen */
  668.     /* Dialog handelt, passiert nichts */
  669.     if ((win) && (win->type & DIAL_WINDOW) && (win->w_handle != wh))
  670.         win->dialog->cont = FALSE;  
  671.  
  672.     /* Wenn es ein Dialog ist und es editierbare Texte gibt, dann */
  673.     /* wird der Cursor an der akt. Position im Text eingeschaltet */
  674.     if ((win) && (win->type & DIAL_WINDOW) && 
  675.          (win->dialog->next_obj != 0) &&
  676.          (win->dialog->edit_obj != win->dialog->next_obj))
  677.         {
  678.         if (win->dialog->cont) 
  679.             {    
  680.             if(ObjTree(win)[win->dialog->next_obj].ob_type ==G_FTEXT 
  681.             || ObjTree(win)[win->dialog->next_obj].ob_type ==G_FBOXTEXT)
  682.                 win->dialog->edit_obj = win->dialog->next_obj;
  683.             win->dialog->next_obj = 0;
  684.             objc_edit(win->dialog->tree, win->dialog->edit_obj, 0,
  685.                          &(win->dialog->idx), ED_INIT);
  686.             }
  687.         }
  688.  
  689.     /* Ereignisse abwarten, die im Programmdeskriptor festgelegt */
  690.     /* wurden */
  691.     event = evnt_multi(app_cntrl.multi_flags, app_cntrl.mb_clicks,
  692.                        app_cntrl.mb_mask, app_cntrl.mb_state,
  693.                        app_cntrl.m1_flag, h1.g_x, h1.g_y, h1.g_w, h1.g_h,
  694.                        app_cntrl.m2_flag, h2.g_x, h2.g_y, h2.g_w, h2.g_h, 
  695.                        msgbuff, app_cntrl.mt_locount,
  696.                        app_cntrl.mt_hicount, &mmo_x, &mmo_y, &mm_button,
  697.                        &mmok_state, &mk_return, &mb_return);
  698.     
  699.     if (event & MU_MESAG)
  700.         {
  701.         /* Hat das Ereignis was mit Fenstern zu tun ? */
  702.         if (msgbuff[0] >= WM_REDRAW && WM_NEWTOP >= msgbuff[0])
  703.             {
  704.             if(app_cntrl.modal != NULL && (msgbuff[0] == WM_TOPPED) ) 
  705.                 {
  706.                 if(win == app_cntrl.modal)
  707.                     printf("\a");
  708.                 }
  709.             else
  710.                 win = get_winfh(msgbuff[3]);
  711.             if(win)
  712.                 {
  713.                 wind_update(BEG_UPDATE);
  714.                 win_manager(msgbuff[0], win, msgbuff[4],
  715.                     msgbuff[5], msgbuff[6], msgbuff[7]);
  716.                 wind_update(END_UPDATE);
  717.                 }
  718.             }
  719.         else 
  720.             {
  721.             if ((msgbuff[0] & MN_SELECTED) && app_cntrl.modal==NULL)
  722.                 menu_manager(msgbuff[3], msgbuff[4], 0);
  723.         /* Hier kann der Programmierer im Message Manager auf andere */
  724.         /* Nachrichten reagieren, z.B. Schnittstelle via appl_write  */
  725.             else
  726.                 {
  727.                 if(app_cntrl.modal==NULL)
  728.                     msg_manager(msgbuff);           
  729.                 }
  730.             }
  731.         }
  732.     
  733.     /* Wurde eine Taste betätigt ? */
  734.     if (event & MU_KEYBD)
  735.         {
  736.         if(app_cntrl.modal != NULL)            /* wenn modales Fenster */
  737.             win=app_cntrl.modal;
  738.         else
  739.             win = get_winfh(app_cntrl.w_handle); 
  740.         
  741.         /* Wenn es ein Dialog ist */
  742.         if ((win) && (win->type & DIAL_WINDOW))
  743.         {
  744.             /* dann bearbeite Taste und editiere den aktuellen Text */
  745.             win->dialog->cont = form_keybd(win->dialog->tree,
  746.                                            win->dialog->edit_obj,
  747.                                            win->dialog->next_obj, mk_return, 
  748.                                            &(win->dialog->next_obj), 
  749.                                            &mk_return);
  750.             if (!win->dialog->cont)
  751.             {
  752.                 button_help = win->dialog->button_start;
  753.                 while(button_help->obj_index != win->dialog->next_obj)
  754.                     button_help = button_help->next;
  755.                 if (button_help->obj_index == win->dialog->next_obj)
  756.                 {
  757.                     if(button_help->action)
  758.                         button_help->action();
  759.                     obj_state = win->dialog->tree[win->dialog->next_obj].
  760.                                 ob_state;
  761.                     obj_state ^= SELECTED;
  762.                     objc_change(win->dialog->tree, win->dialog->next_obj, 0, 
  763.                                    win->workarea.g_x, win->workarea.g_y, 
  764.                                   win->workarea.g_w, win->workarea.g_h, 
  765.                                  obj_state, 1);
  766.  
  767.                     if (button_help->redraw)
  768.                         {
  769.                         buffer[0] = WM_REDRAW;
  770.                         buffer[1] = app_cntrl.ap_id;
  771.                         buffer[3] = win->w_handle;
  772.                         buffer[4] = win->workarea.g_x;
  773.                         buffer[5] = win->workarea.g_y;
  774.                         buffer[6] = win->workarea.g_w;
  775.                         buffer[7] = win->workarea.g_h;
  776.                         appl_write(app_cntrl.ap_id, 16, buffer);
  777.                         }
  778.                     }
  779.                 }                         
  780.             if ((mk_return) && (win->dialog->cont)) 
  781.                 objc_edit(win->dialog->tree, win->dialog->edit_obj,
  782.                           mk_return, &(win->dialog->idx), ED_CHAR);
  783.  
  784.             if ((!win->dialog->cont) || ((win->dialog->next_obj != 0) &&
  785.                  (win->dialog->next_obj != win->dialog->edit_obj)))
  786.                 objc_edit(win->dialog->tree, win->dialog->edit_obj, 0,
  787.                       &(win->dialog->idx), ED_END);     
  788.             }
  789. /*        if (((mk_return & 0xff) < 0x20 || (mk_return & 0xff) > 0x7e)*/
  790.  
  791.         if(app_cntrl.modal == NULL)
  792.             {
  793.             menu_manager(0,0, mk_return);
  794.             key_manager(mk_return);
  795.             }
  796.         else 
  797.             {
  798.             if ((win) && (win->key_code))
  799.                 win->key_code(win, (char)mk_return & 0xff);
  800.             }
  801.         }
  802.         
  803.     /* Wurde Maustaste betätigt ? */
  804.     if (event & MU_BUTTON)
  805.         {
  806.         if(app_cntrl.modal != NULL) 
  807.             win = app_cntrl.modal;
  808.         else
  809.             win = get_winfh(app_cntrl.w_handle);
  810.         /* wenn normales Fenster */     
  811.         if ((win) && (win->type&3) == DATA_WINDOW)
  812.             {  /* innerhalb des Fensters  */
  813.             if (check_rect(mmo_x,mmo_y,&win->workarea))
  814.                 {
  815.                 if (win->button_code)
  816.                     win->button_code(win, mmo_x, mmo_y, mm_button, mmok_state);
  817.                 }    
  818.             else  /* außerhalb des Fensters */
  819.                 {    
  820.                 if (app_cntrl.button_code && app_cntrl.modal == NULL)
  821.                     app_cntrl.button_code(mmo_x, mmo_y, mm_button, mmok_state);
  822.                 }
  823.             }    
  824.         else 
  825.             {    /* außerhalb der Fenster und kein eigenes Fenster aktiv */
  826.             if ((!win) && (app_cntrl.button_code) && app_cntrl.modal == NULL )
  827.                 app_cntrl.button_code(mmo_x, mmo_y, mm_button, mmok_state);
  828.             }
  829.         /* Dialog und Panelfenster */        
  830.         if ((win) && ((win->type & DIAL_WINDOW) || (win->type & PANEL_WINDOW)))
  831.             {
  832.             /* Bei Dialogen wird überprüft, ob ein OBJECT angeklickt wurde */
  833.             win->dialog->next_obj = objc_find(win->dialog->tree,0,8,mmo_x, mmo_y);
  834.             /* Wenn ja, wird der Objektstatus angepaßt und ggfl. ein */
  835.             /* neuer editierbarer Text initialisiert */
  836.             if (win->dialog->next_obj >= 0)
  837.                 { 
  838.                 int ob_flags=ObjTree(win)[win->dialog->next_obj].ob_flags;
  839.                 sel_obj = win->dialog->next_obj;
  840.  
  841.                 /* Fixing bei form_button da Fehler bei Touchexit und Exit */
  842.                 if((ob_flags&EXIT) || (ob_flags&TOUCHEXIT))
  843.                     {
  844.                     ObjTree(win)[win->dialog->next_obj].ob_state^=SELECTED;
  845.                     win->dialog->cont= FALSE;
  846.                     }
  847.                 else
  848.                     win->dialog->cont = form_button(win->dialog->tree, 
  849.                                         win->dialog->next_obj, mb_return,
  850.                                         &(win->dialog->next_obj));
  851.                 if ( ((!win->dialog->cont) || win->dialog->next_obj != 0) &&
  852.                     (win->dialog->next_obj != win->dialog->edit_obj) &&
  853.                     (win->type & DIAL_WINDOW))
  854.                         {
  855.                         objc_edit(win->dialog->tree, win->dialog->edit_obj, 0,
  856.                                   &(win->dialog->idx), ED_END);     
  857.                         win->dialog->cont=TRUE;
  858.                         }
  859.                 /* Aktion ausführen, die den ausgewählten Button betrifft */ 
  860.                 if (win->dialog->tree[sel_obj].ob_state & SELECTED)
  861.                     button_manager(mmo_x, mmo_y, mm_button, mmok_state);
  862.                 else if (win->dialog->tree[sel_obj].ob_flags & TOUCHEXIT)
  863.                     button_manager(mmo_x, mmo_y, mm_button, mmok_state);
  864.                 if (win->dialog->release)
  865.                     win->dialog->release(sel_obj, win->dialog->tree[sel_obj].ob_state);
  866.                 }
  867.             else /* wenn kein OBJECT angeklickt worden ist */ 
  868.                 {
  869.                 if ((win->type & PANEL_WINDOW) && check_rect(mmo_x,mmo_y,&win->workarea))
  870.                     {  /* innerhalb des Panelfensters aber außerhalb des Dialoges */
  871.                     if (win->button_code)
  872.                         win->button_code(win, mmo_x, mmo_y, mm_button, mmok_state);
  873.                     }    
  874.                 else 
  875.                     {
  876.                     if (app_cntrl.button_code && app_cntrl.modal == NULL )
  877.                     /*    {*/
  878.                         app_cntrl.button_code(mmo_x, mmo_y, mm_button, mmok_state);    
  879.     /* geändert */
  880.                         if ((win->type & DIAL_WINDOW) || ((win->dialog->next_obj != 0) &&
  881.                              (win->dialog->next_obj != win->dialog->edit_obj)))
  882.                             {
  883.                             objc_edit(win->dialog->tree, win->dialog->edit_obj, 0,
  884.                                       &(win->dialog->idx), ED_END);     
  885.                             win->dialog->next_obj = win->dialog->edit_obj;
  886.                             win->dialog->edit_obj = 0;
  887.                             }
  888.                 /*        } */
  889.                     }
  890.                 }
  891.             }
  892.         }        
  893.     /* Wurde der Mauspfeil in ein Rechteck hinein oder aus einem Recht- */
  894.     /* eck heraus bewegt, dann die zugehörige Aktion bearbeiten */
  895.     if (event & MU_M1 && app_cntrl.modal == NULL)
  896.         if (app_cntrl.m1_code)
  897.             app_cntrl.m1_code();
  898.         
  899.     if (event & MU_M2 && app_cntrl.modal == NULL)
  900.         if (app_cntrl.m2_code)
  901.             app_cntrl.m2_code();
  902.         
  903.     /* Aktion zu einem Zeitereignis aufrufen */
  904.     if (event & MU_TIMER && app_cntrl.modal == NULL)
  905.         {
  906.         if (app_cntrl.time_code)
  907.             app_cntrl.time_code();
  908.         }
  909.         
  910.     } while (!app_cntrl.quit); /* Solange bis der Anwender das Programm */
  911.                                         /* verlassen möchte */
  912.     all_free();
  913.     v_clsvwk(app_cntrl.vdi_handle);
  914.     appl_exit();
  915. }
  916.  
  917. /* ---------------------------------------------------------------------- */
  918. /* Sliderstruktur initialisieren                                          */
  919. /* ---------------------------------------------------------------------- */
  920. boolean init_slider(struct WINDOW *win, int x_elements, int y_elements,
  921.                           int x_size, int y_size)
  922. {
  923.     struct slide_def *ptr;
  924.      
  925.     /* Ist noch genug Speicher da ? */
  926.     if ((ptr = (struct slide_def *)calloc(1, sizeof(struct slide_def)))
  927.          != NULL)
  928.     {
  929.         win->slider = ptr;
  930.         win->slider->x_elements = x_elements;
  931.         win->slider->y_elements = y_elements;
  932.         win->slider->x_size     = x_size;
  933.         win->slider->y_size     = y_size;
  934.         
  935.         win->slider->x_offset   = 0;
  936.         win->slider->y_offset   = 0;
  937.         win->slider->x_cursor   = 0;
  938.         win->slider->y_cursor   = 0;
  939.             
  940.         change_slider_size(win); /* Slidergrößen anpassen  */
  941.         new_slider_pos(win);
  942.         return(TRUE);
  943.     }
  944.     else
  945.     {
  946.         form_alert(1,"[3][Slider konnte nicht|initialisiert werden!][Sorry]");
  947.         return(FALSE);
  948.     }
  949. }
  950.  
  951. /* ---------------------------------------------------------------------- */
  952. /* Hor. und vert. Slidergrößen anpassen                                   */
  953. /* ---------------------------------------------------------------------- */
  954. void change_slider_size(struct WINDOW *win)
  955. {
  956.     float x,y;
  957.     
  958.     if (win->slider)
  959.     {
  960.         x = 1000.0 / (float)win->slider->x_elements;
  961.         x *= (float)win->workarea.g_w / (float)win->slider->x_size;
  962.         y = 1000.0 / (float)win->slider->y_elements;
  963.         y *= (float)win->workarea.g_h / (float)win->slider->y_size;
  964.                     
  965.         wind_set(win->w_handle, WF_HSLSIZE, (unsigned int)x, 0, 0, 0);
  966.         wind_set(win->w_handle, WF_VSLSIZE, (unsigned int)y, 0, 0, 0);
  967.  
  968.         if (win->workarea.g_w/win->slider->x_size+win->slider->x_offset >
  969.              win->slider->x_elements )
  970.             set_x_slider(win,(int)((float)win->slider->x_elements - 
  971.                                 (float)win->workarea.g_w/win->slider->x_size));
  972.  
  973.         if (win->workarea.g_h/win->slider->y_size+win->slider->y_offset >
  974.              win->slider->y_elements )
  975.             set_y_slider(win,(int)((float)win->slider->y_elements - 
  976.                                 (float)win->workarea.g_h/win->slider->y_size));
  977.     }
  978. }
  979.  
  980.  
  981. /* ---------------------------------------------------------------------- */
  982. /* Sliderposition verwalten                                               */
  983. /* ---------------------------------------------------------------------- */
  984. void hndl_slider_pos(struct WINDOW *win, int what, int position)
  985. {
  986.     long x,y;
  987.     int  w,h;
  988.     int sx_b,sy_b;
  989.     static int change;
  990.     
  991.     sy_b=win->slider->y_offset;
  992.     sx_b=win->slider->x_offset; /* Zwischenspeichern */
  993.     if ((w = win->workarea.g_w / win->slider->x_size) * win->slider->x_size 
  994.           > win->workarea.g_w)
  995.         w--;
  996.    if ((h = win->workarea.g_h / win->slider->y_size) * win->slider->y_size
  997.          > win->workarea.g_h)
  998.        h--;
  999.  
  1000.     switch (what)
  1001.     {
  1002.         case PAGE_UP:
  1003.             if (win->slider->y_offset >= h)
  1004.             {
  1005.                 win->slider->y_offset -= h;
  1006.                 change = 2;
  1007.             }
  1008.             else if (win->slider->y_offset > 0)
  1009.             {
  1010.                 win->slider->y_offset = 0;
  1011.                 change = 1;
  1012.             }
  1013.             if (win->slider->y_cursor > win->slider->y_offset + h - 1)
  1014.                 win->slider->y_cursor = win->slider->y_offset + h - 1;    
  1015.             break;
  1016.         
  1017.         case PAGE_DN:
  1018.             if (win->slider->y_offset + 2*h < win->slider->y_elements)
  1019.             {
  1020.                 win->slider->y_offset += h;
  1021.                 change = 2;
  1022.             }
  1023.             else if (win->slider->y_offset < win->slider->y_elements - h)
  1024.             {
  1025.                 win->slider->y_offset = win->slider->y_elements - h;
  1026.                 change = 1;
  1027.             }
  1028.             if (win->slider->y_cursor < win->slider->y_offset)
  1029.                 win->slider->y_cursor = win->slider->y_offset;
  1030.             break;
  1031.             
  1032.         case PAGE_LF:
  1033.             if (win->slider->x_offset >= w)
  1034.             {
  1035.                 win->slider->x_offset -= w;
  1036.                 change = 2;
  1037.             }
  1038.             else if (win->slider->x_offset > 0)
  1039.             {
  1040.                 win->slider->x_offset = 0;
  1041.                 change = 1;
  1042.             }
  1043.             if (win->slider->x_cursor > win->slider->x_offset + w - 1)
  1044.                 win->slider->x_cursor = win->slider->x_offset + w - 1;
  1045.             break;
  1046.         
  1047.         case PAGE_RT:
  1048.             if (win->slider->x_offset + 2*w < win->slider->x_elements)
  1049.             {
  1050.                 win->slider->x_offset += w;
  1051.                 change = 2;
  1052.             }
  1053.             else if (win->slider->x_offset < win->slider->x_elements - w)
  1054.             {
  1055.                 win->slider->x_offset = win->slider->x_elements - w;
  1056.                 change = 1;
  1057.             }
  1058.             if (win->slider->x_cursor < win->slider->x_elements)
  1059.                 win->slider->x_cursor = win->slider->x_elements;
  1060.             break;
  1061.             
  1062.         case CLMN_LF:
  1063.             if (win->slider->x_offset > 0)
  1064.             {
  1065.                 win->slider->x_offset--;
  1066.                 change = 2;
  1067.                 if (win->slider->x_cursor > win->slider->x_offset + w - 1)
  1068.                     win->slider->x_cursor--;
  1069.             }
  1070.             else 
  1071.                 change = 0;
  1072.             break;
  1073.             
  1074.         case CLMN_RT:
  1075.             if (win->slider->x_offset + w - 1 < win->slider->x_elements - 1)
  1076.             {
  1077.                 win->slider->x_offset++;
  1078.                 change = 2;
  1079.                 if (win->slider->x_cursor < win->slider->x_offset)
  1080.                     win->slider->x_cursor++;
  1081.             }
  1082.             else
  1083.                 change = 0;
  1084.             break;
  1085.             
  1086.         case ROW_UP:
  1087.             if (win->slider->y_offset > 0)
  1088.             {
  1089.                 win->slider->y_offset--;
  1090.                 change = 2;
  1091.                 if (win->slider->y_cursor > win->slider->y_offset + h - 1)
  1092.                     win->slider->y_cursor--;
  1093.             }
  1094.             else
  1095.                 change = 0;
  1096.             break;
  1097.             
  1098.         case ROW_DN:
  1099.             if (win->slider->y_offset + h - 1 < win->slider->y_elements - 1)
  1100.             {
  1101.                 win->slider->y_offset++;
  1102.                 change = 2;
  1103.                 if (win->slider->y_cursor < win->slider->y_offset)
  1104.                     win->slider->y_cursor++;
  1105.             }
  1106.             else
  1107.                 change = 0;
  1108.             break;
  1109.             
  1110.         case H_SLIDE:
  1111.             x = win->slider->x_elements - win->workarea.g_w / 
  1112.                  win->slider->x_size;
  1113.             x *= position;
  1114.             x /= 1000;
  1115.             win->slider->x_offset = (unsigned int)x;
  1116.             change = 1;
  1117.             break;
  1118.  
  1119.         case V_SLIDE:
  1120.             y = win->slider->y_elements - win->workarea.g_h /
  1121.                  win->slider->y_size;
  1122.             y *= position;
  1123.             y /= 1000;
  1124.             win->slider->y_offset = (unsigned int)y; 
  1125.             change = 1;
  1126.     }
  1127.  
  1128.     if (change > 0 && ( win->slider->y_offset != sy_b || win->slider->x_offset!= sx_b) )
  1129.     {
  1130.         new_slider_pos(win);
  1131.     }
  1132.     if (change == 1)
  1133.         change = 0;
  1134. }
  1135.  
  1136.  
  1137. /**************************************************************************
  1138.  * Sliderposition innerhalb des Fensters setzen                           *
  1139.  * Dazu werden die einfach die Sliderkoordinaten abgefragt                   *    
  1140.  * Input: win: Fensterverwaltungsstruktur u.a . mit den Daten für die     *
  1141.  *                Slider des aktuellen Fensters                              *    
  1142.  **************************************************************************/
  1143. void new_slider_pos(struct WINDOW *win)
  1144. {
  1145.     float x,y;
  1146.             
  1147.     if (win->slider)
  1148.     {
  1149.         if(win->slider->x_offset==win->slider->x_elements)
  1150.             x=1000.0; /* wegen Quantisierung */
  1151.         else
  1152.             {
  1153.             if(win->slider->x_elements - win->workarea.g_w / 
  1154.                 win->slider->x_size!=0)
  1155.                 {
  1156.                 x =( 1000.0 / ((float)win->slider->x_elements 
  1157.                 -(float)win->workarea.g_w /(float)win->slider->x_size));
  1158.                 x *= win->slider->x_offset;
  1159.                 }
  1160.             else x=0.0;
  1161.             }
  1162.         if(win->slider->y_offset==win->slider->y_elements)
  1163.             y=1000.0;
  1164.         else
  1165.             {    
  1166.             if(win->slider->y_elements - win->workarea.g_h / 
  1167.                 win->slider->y_size!=0)
  1168.                 {            
  1169.                 y =(1000.0 / ((float)win->slider->y_elements
  1170.                 - (float)win->workarea.g_h/(float)win->slider->y_size));
  1171.                 y *= win->slider->y_offset;
  1172.                 }
  1173.             else y=0.0; 
  1174.             }
  1175.         wind_set(win->w_handle, WF_VSLIDE, (unsigned int)y, 0, 0, 0);
  1176.         wind_set(win->w_handle, WF_HSLIDE, (unsigned int)x, 0, 0, 0);
  1177.         /* Window Redraw erzwingen */
  1178.         blank(win, win->workarea.g_x, win->workarea.g_y,
  1179.                 win->workarea.g_w, win->workarea.g_h); 
  1180.     }
  1181. }
  1182.  
  1183.  
  1184. /* ---------------------------------------------------------------------- */
  1185. /* Zeile einfügen (z.B. in Textfenster)                                   */
  1186. /* ---------------------------------------------------------------------- */
  1187. void add_rows(struct WINDOW *win, int count)
  1188. {
  1189.     win->slider->y_elements += count;
  1190.     if(win->slider->y_elements<=0) 
  1191.         win->slider->y_elements = 1;
  1192.                  
  1193. }
  1194.  
  1195. /* ---------------------------------------------------------------------- */
  1196. /* Spalte einfügen                                                        */
  1197. /* ---------------------------------------------------------------------- */
  1198. void add_columne(struct WINDOW *win, int count)
  1199. {
  1200.     win->slider->x_elements += count;
  1201.     if(win->slider->x_elements<=0)
  1202.         win->slider->x_elements = 1;
  1203. }
  1204.      
  1205. /* ---------------------------------------------------------------------- */
  1206. /* Fensterstruktur generieren                                             */
  1207. /* ---------------------------------------------------------------------- */
  1208. struct WINDOW *create_window(GRECT *max, GRECT *real, int min_w, int min_h,
  1209.                                       int flags, int type, 
  1210.                                       void (*draw_code)(struct WINDOW *win),
  1211.                                       void (*slide_code)(struct WINDOW *win,
  1212.                                                          int message),
  1213.                                       void (*button_code)(struct WINDOW *win, int mx,
  1214.                                                             int my, int mb, int ks),
  1215.                                       void (*key_code)(struct WINDOW *win,
  1216.                                                                char ascii),
  1217.                                       void (*wtop_code)(struct WINDOW *win),
  1218.                                       int  (*close_code)(struct WINDOW *win))
  1219.  
  1220. {
  1221.     int wh;
  1222.     struct WINDOW *ptr;
  1223.     
  1224.     if(start) /* eventuell im letzen Fensters Cursor ausschalten */
  1225.         {
  1226.         if( start->type & DIAL_WINDOW)
  1227.             {
  1228.             if(ObjTree(start)[start->dialog->edit_obj].ob_type ==G_FTEXT 
  1229.             || ObjTree(start)[start->dialog->edit_obj].ob_type ==G_FBOXTEXT)
  1230.             objc_edit(start->dialog->tree, start->dialog->edit_obj, 0,
  1231.             &(start->dialog->idx), ED_END);     
  1232.             }
  1233.         }
  1234.     ptr = alloc_window();
  1235.     if (!ptr)
  1236.     {
  1237.         form_alert(1,"[3][Kein Speicher frei!|Kann Fenster nicht öffnen.]"
  1238.                       "[Abbruch]");    
  1239.         return(FALSE);
  1240.     } 
  1241.     
  1242.     if ((wh =  wind_create(flags, max->g_x, max->g_y, max->g_w, 
  1243.           max->g_h)) < 0)
  1244.     {    
  1245.         form_alert(1,"[3][Zuviele Fenster offen!|Bitte schließen Sie ein|"
  1246.                       "nicht mehr benötigtes Fenster.][Okay]");
  1247.         return(FALSE);
  1248.     }
  1249.     
  1250.     /* Struktur initialisieren */
  1251.     ptr->w_handle    = wh;
  1252.     ptr->type        = (type&7);     
  1253.     if (type & DATA_WINDOW)
  1254.         ptr->dialog   = NULL;
  1255.     ptr->fulled      = compare_grect(max, real);
  1256.     ptr->flags       = flags;
  1257.     ptr->min_w       = min_w;
  1258.     ptr->min_h       = min_h;
  1259.     ptr->draw_code   = draw_code;
  1260.     ptr->slide_code  = slide_code;
  1261.     ptr->key_code    = key_code;
  1262.     ptr->button_code = button_code;
  1263.     ptr->wtop_code   = wtop_code;
  1264.     ptr->close_code   = close_code;
  1265.     ptr->slider      = NULL;
  1266.     copy_grect(real, &ptr->actual_position);
  1267.  
  1268.     return(ptr);
  1269. }
  1270.  
  1271.  
  1272. /* ---------------------------------------------------------------------- */
  1273. /* Panel-Window generieren                                                */
  1274. /* ---------------------------------------------------------------------- */
  1275. struct WINDOW *create_pwindow(int obj_name, GRECT *max, GRECT *real,
  1276.                               int min_w, int min_h, int flags,int modal,
  1277.                               int align,
  1278.                               void (*draw_code)(struct WINDOW *win),
  1279.                               void (*slide_code)(struct WINDOW *win, 
  1280.                                                  int message),
  1281.                               void (*button_code)(struct WINDOW *win, int mx,
  1282.                                                       int my, int mb, int ks),
  1283.                               void (*key_code)(struct WINDOW *win,
  1284.                                                char ascii),
  1285.                               void (*wtop_code)(struct WINDOW *win),
  1286.  
  1287.                               void (*release)(int obj_index, int obj_state))
  1288. {
  1289.     struct WINDOW *ptr;
  1290.     OBJECT *tree;
  1291.     int msgbuff[8] = {0,0,0,0,0,0,0,0};
  1292.     int type_flag= PANEL_WINDOW;
  1293.  
  1294.     if (rsrc_gaddr(0, obj_name, &tree))
  1295.     {
  1296.         help = start;
  1297.         while (help)
  1298.         {
  1299.             if ((help->dialog) && (help->dialog->tree) && 
  1300.                  (help->dialog->tree == tree))
  1301.             {
  1302.                 msgbuff[0] = WM_TOPPED;
  1303.                 msgbuff[1] = app_cntrl.ap_id;
  1304.                 msgbuff[3] = help->w_handle;
  1305.                 appl_write(app_cntrl.ap_id, 16, msgbuff);
  1306.                 return(NULL);
  1307.             }
  1308.             help = help->next;
  1309.         }
  1310.         if(modal)
  1311.             type_flag|=MODAL;
  1312.         ptr = create_window(max, real, min_w, min_h, flags, type_flag,
  1313.                                   draw_code, slide_code, button_code
  1314.                                       , key_code,wtop_code,0);
  1315.         if (!ptr)
  1316.             return(NULL);
  1317.         
  1318.         ptr->dialog = (struct dial *)calloc(1, sizeof(struct dial));
  1319.         if (!ptr->dialog)
  1320.             return(NULL);
  1321.         
  1322.         ptr->dialog->tree    = tree;
  1323.         ptr->dialog->release = release;
  1324.         ptr->dialog->align   = align;
  1325.         return(ptr);
  1326.     }
  1327.     else
  1328.         return(NULL);
  1329. }
  1330.                                                                                                          
  1331.  
  1332. /* ---------------------------------------------------------------------- */
  1333. /* Fenster öffnen                                                         */
  1334. /* ---------------------------------------------------------------------- */
  1335. void open_window(struct WINDOW *win, char *name, char *info) 
  1336. {
  1337.     strcpy(win->name, name);
  1338.     wind_set(win->w_handle, WF_NAME, win->name, 0, 0);
  1339.     if (win->flags & INFO)
  1340.     {
  1341.         strcpy(win->info, info);
  1342.         wind_set(win->w_handle, WF_INFO, win->info, 0, 0);
  1343.     }
  1344.     else
  1345.         strcpy(win->info, "\0");
  1346.  
  1347.     graf_growbox(0,0,0,0, win->actual_position.g_x, win->actual_position.g_y,
  1348.                  win->actual_position.g_w, win->actual_position.g_h);
  1349.     wind_open(win->w_handle, win->actual_position.g_x, win->actual_position.g_y,
  1350.               win->actual_position.g_w, win->actual_position.g_h);
  1351.     wind_get(win->w_handle, WF_WORKXYWH, &win->workarea.g_x, &win->workarea.g_y,
  1352.              &win->workarea.g_w, &win->workarea.g_h);
  1353.  
  1354.     if (win->slider)
  1355.         change_slider_size(win);
  1356.     
  1357.     if (win->type & DIAL_WINDOW)
  1358.         align_dial(win);
  1359.         
  1360.     if (win->type & PANEL_WINDOW)
  1361.         align_panel(win);
  1362.         
  1363.     /* Window Handle in Programmdeskriptor eintragen */
  1364.     app_cntrl.w_handle = win->w_handle;
  1365.     blank(win, win->workarea.g_x, win->workarea.g_y,
  1366.             win->workarea.g_w, win->workarea.g_h);  /* REDRAW erzwingen */
  1367.     if(win->wtop_code!=NULL) /* Erste Reaktion des Fensters */ 
  1368.         win->wtop_code(win);
  1369.  
  1370. }    
  1371.  
  1372.  
  1373. /* ---------------------------------------------------------------------- */
  1374. /* PANEL an Fensterkoordinaten anpassen                                   */
  1375. /* ---------------------------------------------------------------------- */
  1376. void align_panel(struct WINDOW *win)
  1377. {
  1378.     win->dialog->tree->ob_x = win->workarea.g_x;
  1379.     win->dialog->tree->ob_y = win->workarea.g_y;
  1380.         
  1381.     switch(win->dialog->align)
  1382.     {
  1383.         case ALIGN_X:
  1384.             win->dialog->tree->ob_width = win->workarea.g_w;
  1385.             win->workarea.g_y += win->dialog->tree->ob_height;
  1386.             win->workarea.g_h -= win->dialog->tree->ob_height;
  1387.             break;
  1388.         case ALIGN_Y:
  1389.             win->dialog->tree->ob_height = win->workarea.g_h;
  1390.             win->workarea.g_x += win->dialog->tree->ob_width;
  1391.             win->workarea.g_w -= win->dialog->tree->ob_width;
  1392.     }
  1393. }
  1394.  
  1395.  
  1396. /* ---------------------------------------------------------------------- */
  1397. /* DIALOG an Fensterkoordinaten anpassen                                  */
  1398. /* ---------------------------------------------------------------------- */
  1399. void align_dial(struct WINDOW *win)
  1400. {
  1401.     win->dialog->tree->ob_x = win->workarea.g_x;
  1402.     win->dialog->tree->ob_y = win->workarea.g_y;
  1403.     win->dialog->tree->ob_width = win->workarea.g_w;
  1404.     win->dialog->tree->ob_height = win->workarea.g_h;
  1405. }
  1406.  
  1407. /* ---------------------------------------------------------------------- */
  1408. /* Window Manager                                                         */
  1409. /* ---------------------------------------------------------------------- */
  1410. void win_manager(int msg, struct WINDOW *ptr, int x, int y, int w, int h)
  1411. {
  1412.     int act_wh;
  1413.     struct WINDOW *win;
  1414.     if(ptr==NULL)
  1415.         {
  1416.         printf("\n The worst case in the win_manager!");
  1417.         return; /* Das schlimmste verhindern (kommt manchmal vor !)*/
  1418.         }
  1419.         
  1420.     switch(msg)
  1421.     {
  1422.         case WM_REDRAW:            /* Window wird neu gezeichnet */
  1423.             blank(ptr, x,y,w,h);
  1424.             if (ptr->type & DIAL_WINDOW) /* Wenn Dialog, dann prüfe, ob */
  1425.             {                            /* Fenster ganz oben liegt */
  1426.                 wind_get(0, WF_TOP, &act_wh, 0,0,0);
  1427.                 if (act_wh == ptr->w_handle) /* Wenn ja, erzwinge */
  1428.                 {                            /* Cursor Redraw     */
  1429.                     ptr->dialog->cont     = TRUE;
  1430.                     ptr->dialog->next_obj = ptr->dialog->edit_obj;
  1431.                     ptr->dialog->edit_obj = 0;
  1432.                 }
  1433.             }
  1434.             break;
  1435.         case WM_CLOSED:      /* Fenster soll geschlossen werden */
  1436.             if(ptr->close_code!=NULL)   /* POWERGEM-Nutzer gibt frei */
  1437.                 if(ptr->close_code(ptr) !=0 )
  1438.                     break;    /* Will es der POWERGEM-Nutzer auch ? */
  1439.             if(app_cntrl.modal != NULL)
  1440.                 {
  1441.                 app_cntrl.modal=NULL; /* Fenster nach schließen der modalen
  1442.                                   Dialogbox freigeben */
  1443.                 menu_all_change(1); /* Menü wie vorher an */
  1444.                 }
  1445.             wind_get(ptr->w_handle, WF_CURRXYWH, &x, &y, &w, &h);
  1446.             graf_shrinkbox(0,0,0,0, x,y,w,h);
  1447.             wind_close(ptr->w_handle); 
  1448.             wind_delete(ptr->w_handle); /* Alles, was mit dem Fenster zusam- */
  1449.             if (ptr->type & DIAL_WINDOW || (ptr->type & PANEL_WINDOW))
  1450.                 kill_button(ptr);
  1451.             kill_window(ptr->w_handle); /* menhängt, wird aus dem Speicher   */
  1452.             wind_get(0, WF_TOP, &(app_cntrl.w_handle), 0,0,0); /* entfernt   */
  1453.             ptr=get_winfh(app_cntrl.w_handle);
  1454.             if(ptr)
  1455.                 {
  1456.                 if(ptr->wtop_code) /* das Fenster darunter wurde somit   */
  1457.                     ptr->wtop_code(ptr);/* unfreiwillig getoppt          */  
  1458.                 }    
  1459.             break;
  1460.         case WM_MOVED:  /* Fenster wurde verschoben/vergrößert/verkleinert */
  1461.         case WM_SIZED:  /* Neue Fensterausmaße erfragen */
  1462.             wind_set(ptr->w_handle, WF_CURRXYWH, x,y,max(ptr->min_w,
  1463.                   min(w,ptr->actual_position.g_w)), max(ptr->min_h,
  1464.                           min(h,ptr->actual_position.g_h)));
  1465.  
  1466.             wind_get(ptr->w_handle, WF_WORKXYWH, &ptr->workarea.g_x, &ptr->workarea.g_y,
  1467.                         &ptr->workarea.g_w, &ptr->workarea.g_h);
  1468.               
  1469.             if (ptr->type & DIAL_WINDOW) /* Bei Dialogen wird die OBJECT- */
  1470.                 align_dial(ptr);
  1471.  
  1472.             if (ptr->type & PANEL_WINDOW)
  1473.                 align_panel(ptr);
  1474.  
  1475.             change_slider_size(ptr);
  1476.             break;
  1477.         case WM_TOPPED: /* Neues Fenster soll nach oben gebracht werden */
  1478.         case WM_NEWTOP:
  1479.             win=start; /* evtl. Cursor im alten Fenster aus !*/
  1480.             if(win)
  1481.                 {
  1482.                 if( win->type & DIAL_WINDOW)
  1483.                     {
  1484.                     if(ObjTree(win)[win->dialog->edit_obj].ob_type ==G_FTEXT 
  1485.                     || ObjTree(win)[win->dialog->edit_obj].ob_type ==G_FBOXTEXT)
  1486.                     objc_edit(win->dialog->tree, win->dialog->edit_obj, 0,
  1487.                           &(win->dialog->idx), ED_END);     
  1488.                     }
  1489.                 }
  1490.             wind_set(ptr->w_handle, WF_TOP, 0,0,0,0);
  1491.             win = get_winfh(app_cntrl.w_handle);
  1492.             if(!win)
  1493.                 break;
  1494.             if (win->type & DIAL_WINDOW)
  1495.                 win->dialog->cont = FALSE;
  1496.             app_cntrl.w_handle = ptr->w_handle;
  1497.             win = get_winfh(ptr->w_handle);
  1498.             if(!win)
  1499.                 printf("\n Great mistake 2 in win_manager !");
  1500.             if (win->type & DIAL_WINDOW)
  1501.                 win->dialog->cont = TRUE;
  1502.             if(win->wtop_code)         /* Erste Reaktion des Fensters */ 
  1503.                 win->wtop_code(win);
  1504.             sort_win_by_top(win);  /* Pointer neu sortieren */
  1505.             break;
  1506.         case WM_FULLED: /* Fenster auf volle Größe/letzte Position bringen */
  1507.             if ((ptr->fulled ^= TRUE))
  1508.                 wind_get(ptr->w_handle, WF_FULLXYWH, &x, &y, &w, &h);
  1509.             else
  1510.                 wind_get(ptr->w_handle, WF_PREVXYWH, &x, &y, &w, &h);
  1511.             wind_set(ptr->w_handle, WF_CURRXYWH, x,y,w,h);
  1512.             wind_get(ptr->w_handle, WF_WORKXYWH, &ptr->workarea.g_x, &ptr->workarea.g_y,
  1513.                         &ptr->workarea.g_w, &ptr->workarea.g_h);          
  1514.  
  1515.             if (ptr->type & PANEL_WINDOW)
  1516.                 align_panel(ptr);
  1517.  
  1518.               change_slider_size(ptr);            
  1519.             break;
  1520.         case WM_ARROWED: /* Sliderverwaltung */
  1521.             hndl_slider_pos(ptr, x, 0);
  1522.             break;
  1523.         case WM_VSLID:
  1524.             hndl_slider_pos(ptr, V_SLIDE, x);
  1525.             break;
  1526.         case WM_HSLID:
  1527.             hndl_slider_pos(ptr, H_SLIDE, x);
  1528.     }
  1529. }
  1530.  
  1531.  
  1532.  
  1533. /* ---------------------------------------------------------------------- */
  1534. /* Auskunftsfunktionen                                                    */
  1535. /* ---------------------------------------------------------------------- */
  1536. /************************************************
  1537.  * Arbeitsbereich eines  Fensters bzw. des      * 
  1538.  * Desktops ermitteln                            *
  1539.  * Input: win Zeiger auf Window-Struktur        *
  1540.  *            (bei Null -> Desktop-Koordinaten) *
  1541.  *           rc  Zeiger auf Rechteckstruktur für   *
  1542.  *            Ergebnisdaten                        *
  1543.  ************************************************/
  1544. void get_workarea(struct WINDOW *win, GRECT *rc)
  1545. {
  1546. if(win)    
  1547.     copy_grect(&win->workarea, rc);
  1548. else
  1549.     copy_grect(&app_cntrl.workarea, rc);
  1550. }    
  1551.  
  1552. /* ---------------------------------------------------------------------- */
  1553. /* Fensterposition ermitteln                                              */
  1554. /* ---------------------------------------------------------------------- */
  1555. void get_winpos(struct WINDOW *win, GRECT *rc)
  1556. {
  1557.     copy_grect(&win->actual_position, rc);
  1558. }
  1559.  
  1560. /**************************************************************************
  1561.  * Horizontale Sliderposition abfragen                                      *
  1562.  * Input: win Zeiger auf aktuelle Fensterverwaltungsstruktur              *
  1563.  **************************************************************************/
  1564. int get_y_slider(struct WINDOW *win)
  1565. {
  1566. if(win)
  1567.     {
  1568.     if(win->slider)
  1569.         return(win->slider->y_offset);
  1570.     }
  1571. return 0;    
  1572. }
  1573.  
  1574. /**************************************************************************
  1575.  * Vertikale Sliderposition abfragen                                      *
  1576.  * Input: win Zeiger auf aktuelle Fensterverwaltungsstruktur              *
  1577.  **************************************************************************/
  1578. int get_x_slider(struct WINDOW *win)
  1579. {
  1580. if(win)
  1581.     {
  1582.     if(win->slider)
  1583.         return(win->slider->x_offset);
  1584.     }
  1585. return 0;    
  1586. }
  1587.  
  1588. /* ---------------------------------------------------------------------- */
  1589. /* Änderungsfunktionen                                                    */
  1590. /* ---------------------------------------------------------------------- */
  1591. /***************************
  1592.  * Setzt die Mausposition  *
  1593.  ***************************/
  1594. void set_mousepos(int x,int y)
  1595. {
  1596. int buf[4];
  1597. buf[0]=0;        /* muß null sein           */
  1598. buf[1]=2;        /* Code für Mausbewegung */
  1599. buf[2]=x;        /* x-Koordinate             */
  1600. buf[3]=y;        /* y-Koordinate             */
  1601. appl_tplay(&buf[0],1,100); /* abspielen  */
  1602. }
  1603. /**************************************************************************
  1604.  * Horizontale Sliderposition setzen evtl. Unter/überschreitungen          *
  1605.  * werden erkannt und korrigiert                                           *
  1606.  * Slider wird upgedatet                                                  *    
  1607.  * Input: win Zeiger auf aktuelle Fensterverwaltungsstruktur              *
  1608.  *        new neuer Wert                                                  *    
  1609.  **************************************************************************/
  1610. void set_y_slider(struct WINDOW *win,int new_y_offset)
  1611. {
  1612. int h;
  1613.  
  1614. if(win)
  1615.     {
  1616.     if(win->slider)
  1617.         {    
  1618.         if((h = win->workarea.g_h / win->slider->y_size) 
  1619.         * win->slider->y_size > win->workarea.g_h)
  1620.             h--;
  1621.  
  1622.         if(new_y_offset < 0)
  1623.             new_y_offset=0;
  1624.         else
  1625.             if((long)new_y_offset + (long)h > (long)win->slider->y_elements)
  1626.                 new_y_offset=  win->slider->y_elements-h;            
  1627.             
  1628.         if(new_y_offset == win->slider->y_offset)
  1629.             return;
  1630.         else
  1631.             {
  1632.             win->slider->y_offset=new_y_offset;
  1633.             new_slider_pos(win); /* Slider updaten */
  1634.             }
  1635.         }
  1636.     }
  1637. }
  1638. /**************************************************************************
  1639.  * Vertikale Sliderposition setzen evtl. Unter/überschreitungen                *
  1640.  * werden erkannt und korrigiert                                           *
  1641.  * Input: win Zeiger auf aktuelle Fensterverwaltungsstruktur              *
  1642.  *        new neuer Wert                                                  *    
  1643.  **************************************************************************/
  1644. void set_x_slider(struct WINDOW *win,int new_x_offset)
  1645. {
  1646. int w;
  1647.  
  1648. if(win)
  1649.     {
  1650.     if(win->slider)
  1651.         {
  1652.         if((w = win->workarea.g_w / win->slider->x_size) 
  1653.         * win->slider->x_size > win->workarea.g_w)
  1654.             w--;
  1655.         if(new_x_offset < 0)
  1656.             new_x_offset=0;
  1657.         else
  1658.             if((long)new_x_offset + (long)w > (long)win->slider->x_elements)
  1659.                 new_x_offset=  win->slider->x_elements-w;            
  1660.  
  1661.         if(new_x_offset < 0)
  1662.             new_x_offset=0;
  1663.  
  1664.         if(win->slider->x_offset == new_x_offset)
  1665.             return;
  1666.         else
  1667.             {
  1668.             win->slider->x_offset=new_x_offset;
  1669.             new_slider_pos(win); /* Slider updaten */
  1670.             }
  1671.         }
  1672.     }
  1673. }
  1674.     
  1675.  
  1676. /* ---------------------------------------------------------------------- */
  1677. /* Fensterposition setzen                                                 */
  1678. /* ---------------------------------------------------------------------- */
  1679. void set_winpos(struct WINDOW *win, GRECT *rc)
  1680. {
  1681.     copy_grect(rc, &win->actual_position);
  1682. }
  1683. /* ---------------------------------------------------------------------- */
  1684. /* Dialog Manager                                                         */
  1685. /* ---------------------------------------------------------------------- */
  1686. /* Dialog erzeugen                                                                  */
  1687. /* ---------------------------------------------------------------------- */
  1688. struct WINDOW *create_dial(int obj_name, int start_obj, int wi_flags,int modal, 
  1689.                            void (*slide_code)(struct WINDOW *win,
  1690.                                                int message), 
  1691.                            void (*button_code)(struct WINDOW *win, int mx,
  1692.                                                    int my, int mb, int ks),
  1693.                            void (*key_code)(struct WINDOW *win,
  1694.                                             char ascii),
  1695.                              void (*wtop_code)(struct WINDOW *win),
  1696.  
  1697.                            void (*release)(int obj_index, int obj_state))                               
  1698. {
  1699.     struct WINDOW *win;
  1700.     OBJECT *tree;
  1701.     GRECT r1 = {0,0,0,0}, r2 = {0,0,0,0};
  1702.     int msgbuff[8] = {0,0,0,0,0,0,0,0};
  1703.     int type_flag=DIAL_WINDOW;
  1704.     int mx,my,dummy;
  1705.  
  1706.     if(modal)
  1707.         type_flag|=MODAL;                
  1708.  
  1709.     if (rsrc_gaddr(0, obj_name, &tree))
  1710.     {
  1711.         help = start;
  1712.         while (help)
  1713.         {
  1714.             if ((help->dialog) && (help->dialog->tree) && 
  1715.                  (help->dialog->tree == tree))
  1716.             {
  1717.                 msgbuff[0] = WM_TOPPED;
  1718.                 msgbuff[1] = app_cntrl.ap_id;
  1719.                 msgbuff[3] = help->w_handle;
  1720.                 appl_write(app_cntrl.ap_id, 16, msgbuff);
  1721.  
  1722.                 if(!(help->type & DIAL_WINDOW))
  1723.                     return(NULL);
  1724.                 help->dialog->next_obj = fm_inifld(help->dialog->tree, start_obj);
  1725.                 help->type        = type_flag&7;     
  1726.                 help->slide_code  = slide_code;
  1727.                 help->button_code = button_code;
  1728.                 help->key_code    = key_code;                            
  1729.                 help->wtop_code   = wtop_code;
  1730.                 help->dialog->release = release;
  1731.                 return(help); /* es läßt sich darüber streiten ob
  1732.                 NULL oder help (Es wurde dementsprechend vorher 
  1733.                 diese Dialogbox mit z. B. evtl. anderen ! TEXTEN geschloßen).  
  1734.                 Vorsicht ist trotzdem geboten ! */    
  1735.             }
  1736.             help = help->next;
  1737.         }
  1738.  
  1739.         wind_get(0, WF_WORKXYWH, &r1.g_x, &r1.g_y, &r1.g_w, &r1.g_h);
  1740.     
  1741.         r2.g_x = tree->ob_x;
  1742.         r2.g_y = tree->ob_y;
  1743.         r2.g_w = tree->ob_width;
  1744.         r2.g_h = tree->ob_height;
  1745.         wind_calc(0, wi_flags, r2.g_x, r2.g_y, r2.g_w, r2.g_h,
  1746.                     &r2.g_x, &r2.g_y, &r2.g_w, &r2.g_h);
  1747.         
  1748.         /* unter der Maus positionieren */
  1749.         graf_mkstate( &mx,&my,&dummy,&dummy);
  1750.         r2.g_x= mx + r2.g_w/2; 
  1751.         r2.g_y= my + r2.g_h/2;
  1752.         r2.g_x=  min(r2.g_x - r2.g_w,app_cntrl.workarea.g_x +
  1753.         app_cntrl.workarea.g_w -r2.g_w);
  1754.         
  1755.         r2.g_y=  min(r2.g_y - r2.g_h,app_cntrl.workarea.g_y +
  1756.         app_cntrl.workarea.g_h -r2.g_h);
  1757.         r2.g_x = max(r2.g_x,app_cntrl.workarea.g_x);
  1758.         r2.g_y = max(r2.g_y,app_cntrl.workarea.g_y);
  1759.         
  1760.         win = create_window(&r1, &r2, tree->ob_width, tree->ob_height,
  1761.                                   wi_flags, type_flag, 0, slide_code, button_code,
  1762.                                   key_code,wtop_code,0);
  1763.         if (!win)
  1764.             return(NULL);        
  1765.     
  1766.         wind_calc(1, wi_flags, r2.g_x, r2.g_y, r2.g_w, r2.g_h,
  1767.                      &r2.g_x, &r2.g_y, &r2.g_w, &r2.g_h);
  1768.         tree->ob_x = r2.g_x;
  1769.         tree->ob_y = r2.g_y; 
  1770.     
  1771.         win->dialog = (struct dial *)calloc(1, sizeof(struct dial));
  1772.         if (!win->dialog)
  1773.             return(NULL);
  1774.         
  1775.         win->dialog->release = release;
  1776.         win->dialog->tree = tree;
  1777.         win->dialog->cont = TRUE;
  1778.         win->dialog->next_obj = fm_inifld(win->dialog->tree, start_obj);
  1779.         win->dialog->edit_obj = 0;
  1780.         return(win);
  1781.     }
  1782.     else
  1783.         return(NULL);
  1784. }   
  1785.  
  1786.  
  1787. void draw_dial(struct WINDOW *win, GRECT *rc)
  1788. {
  1789.     objc_draw(win->dialog->tree, 0,MAX_DEPTH, 
  1790.                                   rc->g_x, rc->g_y, rc->g_w, rc->g_h);
  1791. }
  1792.  
  1793. void draw_object(struct WINDOW *win,int obj_index)
  1794.     {
  1795.     int x,y,w,h;
  1796.  
  1797.     x=win->dialog->tree[obj_index].ob_x + win->dialog->tree[0].ob_x;
  1798.     y=win->dialog->tree[obj_index].ob_y + win->dialog->tree[0].ob_y;;
  1799.     w=win->dialog->tree[obj_index].ob_width + win->dialog->tree[0].ob_width;
  1800.     h=win->dialog->tree[obj_index].ob_height + win->dialog->tree[0].ob_height;
  1801.     objc_draw( win->dialog->tree,obj_index,0,x,y,w,h);
  1802.     }
  1803.  
  1804. int fm_inifld(OBJECT *tree, int start_obj)
  1805. {
  1806.     if (start_obj == 0)
  1807.         start_obj = find_obj(tree);
  1808.     return(start_obj);
  1809. }
  1810.  
  1811.  
  1812. int find_obj(OBJECT *tree)
  1813. {
  1814.     int obj = 0;
  1815.     
  1816.     while (!(tree[obj].ob_flags & LASTOB))
  1817.     {
  1818.         if (tree[obj].ob_flags & EDITABLE)
  1819.             return(obj);
  1820.         obj++;
  1821.     }
  1822.     return(0);
  1823. }
  1824.  
  1825. /* ---------------------------------------------------------------------- */
  1826. /* Button Manager                                                                              */
  1827. /* ---------------------------------------------------------------------- */
  1828. /* DESKTOP Button-Funktion anmelden                                       */
  1829. /* ---------------------------------------------------------------------- */
  1830. void set_button_fnc(void (*button_code)(int m_x, int m_y, int mb_state,
  1831.                         int k_state))
  1832. {
  1833.     app_cntrl.button_code = button_code;
  1834. }
  1835.  
  1836.  
  1837. /* ---------------------------------------------------------------------- */
  1838. /* Speicher für Button-Ereignis alloziieren                               */
  1839. /* ---------------------------------------------------------------------- */
  1840. struct BUTTON_LIST *alloc_button(struct WINDOW *win)
  1841. {
  1842.     struct BUTTON_LIST *help;
  1843.  
  1844.     help = win->dialog->button_start;
  1845.     win->dialog->button_start = (struct BUTTON_LIST *)calloc(1,
  1846.                                  sizeof(struct BUTTON_LIST));
  1847.     win->dialog->button_start->next = help;
  1848.     return(win->dialog->button_start);
  1849. }
  1850.  
  1851.  
  1852. /* ---------------------------------------------------------------------- */
  1853. /* Button-Ereignis anmelden                                               */
  1854. /* ---------------------------------------------------------------------- */
  1855. void button_action(struct WINDOW *win, int obj_index, void (*action)(void),
  1856.                          boolean redraw)
  1857. {
  1858.     struct BUTTON_LIST *ptr;
  1859.     ptr = alloc_button(win);
  1860.     if (ptr)
  1861.     {
  1862.          ptr->tree      = win->dialog->tree;
  1863.         ptr->obj_index = obj_index;
  1864.         ptr->action    = action;
  1865.         ptr->redraw    = redraw;
  1866.     }
  1867. }
  1868.  
  1869.  
  1870. /* ---------------------------------------------------------------------- */
  1871. /* Button-Ereignisse bearbeiten                                                       */
  1872. /* ---------------------------------------------------------------------- */
  1873. void button_manager(int m_x, int m_y, int m_button, int k_state)
  1874. {
  1875.     struct BUTTON_LIST *help;
  1876.  
  1877.     int obj_index, obj_state;
  1878.     struct WINDOW *win;
  1879.     int buffer[8] = {0,0,0,0,0,0,0,0};
  1880.     
  1881.     win = get_winfh(app_cntrl.w_handle);
  1882.     if(!win)
  1883.         {printf("\n Great Error in button_manager");return;}
  1884.     
  1885.     if ((win->type & DIAL_WINDOW) || (win->type & PANEL_WINDOW))
  1886.     {
  1887.         if ((obj_index = objc_find(win->dialog->tree, 0, 8, m_x, m_y)) >= 0)
  1888.             {
  1889.             help = win->dialog->button_start;
  1890.             while (help) 
  1891.                 {
  1892.                 if (obj_index == help->obj_index)
  1893.                     {
  1894.                     if ((win->dialog->tree[obj_index].ob_flags & TOUCHEXIT))
  1895.                         {
  1896.                         obj_state = win->dialog->tree[obj_index].ob_state;
  1897.                         obj_state ^= SELECTED;
  1898.                         objc_change(win->dialog->tree, obj_index, 0, 
  1899.                                     win->workarea.g_x, win->workarea.g_y, 
  1900.                                     win->workarea.g_w, win->workarea.g_h, 
  1901.                                     obj_state, 1);
  1902.                         }
  1903.                     
  1904.                     if(help->action);
  1905.                         help->action();
  1906.     
  1907.                     if (help->redraw)
  1908.                         {
  1909.                         buffer[0] = WM_REDRAW;
  1910.                         buffer[1] = app_cntrl.ap_id;
  1911.                         buffer[3] = win->w_handle;
  1912.                         buffer[4] = win->workarea.g_x;
  1913.                         buffer[5] = win->workarea.g_y;
  1914.                         buffer[6] = win->workarea.g_w;
  1915.                         buffer[7] = win->workarea.g_h;
  1916.                         appl_write(app_cntrl.ap_id, 16, buffer);
  1917.                         }
  1918.  
  1919.                     break;
  1920.                     }
  1921.                 help = help->next;
  1922.                 }
  1923.             }
  1924.         else
  1925.             if(win->button_code)
  1926.                 win->button_code(win, m_x, m_y, m_button, k_state); 
  1927.     }
  1928. }
  1929.  
  1930.  
  1931. /* ---------------------------------------------------------------------- */
  1932. /* Button-Liste freigeben                                                                */
  1933. /* ---------------------------------------------------------------------- */
  1934. void kill_button(struct WINDOW *win)
  1935. {
  1936.     struct BUTTON_LIST *help;
  1937.  
  1938.     help = win->dialog->button_start;
  1939.     while(win->dialog->button_start)
  1940.     {
  1941.         win->dialog->button_start = help->next;
  1942.         free(help);
  1943.         help = win->dialog->button_start;
  1944.     }
  1945. }
  1946.     
  1947.     
  1948.  
  1949. /* ---------------------------------------------------------------------- */
  1950. /* Dialog abbrechen (bsp. "Abbruch" - Button im Dialog gedrückt)          */
  1951. /* ---------------------------------------------------------------------- */
  1952. void break_dial(void)
  1953. {
  1954. break_win(get_winfh(app_cntrl.w_handle));
  1955. }
  1956. /*********************************************************
  1957.  * Fenster schließen, so ist es auch möglich, Fenster      *
  1958.  * per Tastatur zu schließen.                             *    
  1959.  * Input: win    zu schließendes Fenster                     *
  1960.  *********************************************************/
  1961. void break_win(struct WINDOW *win)
  1962. {
  1963. int buffer[8] = {0,0,0,0,0,0,0,0};
  1964.  
  1965. if (win)
  1966.     {
  1967.     win->type|=CLOSED;/* Kennung, so daß keine sinnlosen REDRAWS */
  1968.     buffer[0] = WM_CLOSED;
  1969.     buffer[1] = app_cntrl.ap_id;
  1970.     buffer[3] = win->w_handle;
  1971.     appl_write(app_cntrl.ap_id, 16, buffer);
  1972.     }
  1973. }
  1974. /******************************************************************
  1975.  * Adresse eines Zeichenbuffers in TEDINFO-Struktur eintragen     *        
  1976.  * und updaten                                                       *            
  1977.  * Input: win Fensterstruktur                                       *
  1978.  *        obj_index upzudatendes Objekt                              *
  1979.  *        buf Zeiger auf neuen Text                                  *
  1980.  *          lenght Länge des Textes                                  *            
  1981.  *        redraw Sofortiges Redraw bei TRUE                       *
  1982.  ******************************************************************/
  1983. void set_text(struct WINDOW *win, int obj_index, char *buf, int length,
  1984.                                                         boolean redraw)
  1985. {
  1986. if(!win)
  1987.     return;
  1988. win->dialog->tree[obj_index].ob_spec.tedinfo->te_ptext  = buf;
  1989. win->dialog->tree[obj_index].ob_spec.tedinfo->te_txtlen = length+1;
  1990.  
  1991. if(redraw ==TRUE) /* REDRAW */
  1992.     {
  1993.     int x,y,w,h;
  1994.     x=win->dialog->tree[obj_index].ob_x + win->dialog->tree[0].ob_x;
  1995.     y=win->dialog->tree[obj_index].ob_y + win->dialog->tree[0].ob_y;;
  1996.     w=win->dialog->tree[obj_index].ob_width;
  1997.     h=win->dialog->tree[obj_index].ob_height;
  1998.     blank(win, x, y, w, h);
  1999.     }
  2000. }
  2001. /********************************************************
  2002.  * Testet ob übergebene Koordinatenpaar innerhalb       *
  2003.  * eines Rechteckes sind.                               *
  2004.  * Input: x    x-Koordinate                             *  
  2005.  *        y    y-Koordinate                             *
  2006.  *        rect Zeiger auf Rechteckkoordinaten           *                   
  2007.  * Output: TRUE innerhalb des Rechteckes                *
  2008.  *         FALSE außerhalb                              *              
  2009.  ********************************************************/
  2010. boolean check_rect(int x,int y,GRECT *rect)
  2011. {
  2012. if(x >= rect->g_x && y >= rect->g_y &&
  2013.    x <= (rect->g_x + rect->g_w) && y <= (rect->g_y + rect->g_h))
  2014.     return TRUE;
  2015.  
  2016. return FALSE;
  2017. }
  2018. /* ---------------------------------------------------------------------- */
  2019. /* Button selektieren                                                                       */
  2020. /* ---------------------------------------------------------------------- */
  2021. void select_btn(struct WINDOW *win, int obj_index, boolean redraw)
  2022. {
  2023.     if ((win) && (obj_index != 0) && (!(win->dialog->tree[obj_index].ob_state
  2024.          & SELECTED)))
  2025.         objc_change(win->dialog->tree, obj_index, 0, win->workarea.g_x,
  2026.                         win->workarea.g_y, win->workarea.g_w, win->workarea.g_h,
  2027.                         win->dialog->tree[obj_index].ob_state | SELECTED, redraw);
  2028. }
  2029.  
  2030.  
  2031. /* ---------------------------------------------------------------------- */
  2032. /* Button deselektieren                                                   */
  2033. /* ---------------------------------------------------------------------- */
  2034. void unselect_btn(struct WINDOW *win, int obj_index, boolean redraw)
  2035. {
  2036.     if ((win) && (obj_index != 0) && (win->dialog->tree[obj_index].ob_state 
  2037.          & SELECTED))
  2038.         objc_change(win->dialog->tree, obj_index, 0, win->workarea.g_x,
  2039.                        win->workarea.g_y, win->workarea.g_w, win->workarea.g_h,
  2040.                        win->dialog->tree[obj_index].ob_state ^ SELECTED, redraw);
  2041. }
  2042.  
  2043.  
  2044.  
  2045. /* ---------------------------------------------------------------------- */
  2046. /* Button selektiert ?  --> TRUE oder FALSE                               */
  2047. /* ---------------------------------------------------------------------- */
  2048. boolean get_objstate(struct WINDOW *win, int obj_index)                   
  2049. {
  2050.     return(win->dialog->tree[obj_index].ob_state & SELECTED);
  2051. }
  2052.     
  2053. /* ---------------------------------------------------------------------- */
  2054. /* Key Manager                                                            */
  2055. /* ---------------------------------------------------------------------- */
  2056. /* Speicher für Tastatur-Ereignis alloziieren                                      */
  2057. /* ---------------------------------------------------------------------- */
  2058. struct KEY_LIST *alloc_key()
  2059. {
  2060.     struct KEY_LIST *help;
  2061.     
  2062.     help = key_start;
  2063.     key_start = (struct KEY_LIST *)calloc(1, sizeof(struct KEY_LIST));
  2064.     key_start->next = help;
  2065.     return(key_start);
  2066. }
  2067.  
  2068.  
  2069. /* ---------------------------------------------------------------------- */
  2070. /* Tastatur-Ereignis anmelden                                                             */
  2071. /* ---------------------------------------------------------------------- */
  2072. void key_action(int code, void (*action)(void))
  2073. {
  2074.     struct KEY_LIST *ptr;
  2075.     ptr = alloc_key();
  2076.     if (ptr)
  2077.     {
  2078.          ptr->code   = code;
  2079.         ptr->action = action;
  2080.     }
  2081. }
  2082.  
  2083.  
  2084. /* ---------------------------------------------------------------------- */
  2085. /* Tastatur-Ereignisse bearbeiten                                         */
  2086. /* ---------------------------------------------------------------------- */
  2087. void key_manager(int code)
  2088. {
  2089.     struct KEY_LIST *help;
  2090.     
  2091.     help = key_start;
  2092.  
  2093.     while (help)
  2094.     {
  2095.         if (code == help->code)
  2096.             if(help->action)
  2097.                 help->action();
  2098.         help = help->next;
  2099.     } 
  2100. }    
  2101.  
  2102.  
  2103.  
  2104. /* ---------------------------------------------------------------------- */
  2105. /* Key-Liste freigeben                                                                      */
  2106. /* ---------------------------------------------------------------------- */
  2107. void kill_key(void)
  2108. {
  2109.     struct KEY_LIST *help;
  2110.  
  2111.     help = key_start;
  2112.     while(key_start)
  2113.     {
  2114.         key_start = help->next;
  2115.         free(help);
  2116.         help = key_start;
  2117.     }
  2118. }
  2119.  
  2120. /* ---------------------------------------------------------------------- */
  2121. /* Menu Manager                                                                               */
  2122. /* ---------------------------------------------------------------------- */
  2123. /* Speicher für Menü-Ereignis reservieren                                 */
  2124. /* ---------------------------------------------------------------------- */                 
  2125. struct MENU_LIST *alloc_menu(void)
  2126. {
  2127.     struct MENU_LIST *help;
  2128.  
  2129.     help = menu_start;
  2130.     menu_start = (struct MENU_LIST *)calloc(1, sizeof(struct MENU_LIST));
  2131.     menu_start->next = help;
  2132.     return(menu_start);
  2133. }
  2134.  
  2135.  
  2136. /* ---------------------------------------------------------------------- */
  2137. /* Menü-Ereignis anmelden                                                 */
  2138. /* ---------------------------------------------------------------------- */
  2139. void menu_action(int title, int item, int scan_code, void (*action)(void))
  2140. {
  2141.     struct MENU_LIST *ptr;
  2142.     ptr = alloc_menu();
  2143.     if (ptr)
  2144.     {
  2145.          ptr->title     = title;
  2146.         ptr->item      = item;
  2147.         ptr->scan_code = scan_code;
  2148.         ptr->action    = action;
  2149.     }
  2150. /*******************************************
  2151.  * Menüeinträge ein/auschalten             *
  2152.  * Input: menu_flag 0 ALLE auschalten        *
  2153.  *                  1 Zustand rücksetzen   *
  2154.  *******************************************/
  2155. void menu_all_change(int menu_flag)          
  2156. {
  2157. struct MENU_LIST *help;
  2158.     
  2159. help = menu_start;
  2160. while(help)
  2161.     {
  2162.     menu_ienable( app_cntrl.menu,help->item,menu_flag );
  2163.  
  2164.     if(((app_cntrl.menu+help->item)->ob_state&DISABLED) == 0 &&
  2165.         menu_flag==0)
  2166.         menu_ienable( app_cntrl.menu,help->item,0);
  2167.  
  2168.     if(((app_cntrl.menu+help->item)->ob_state&DISABLED) == 1 &&
  2169.         menu_flag==1)
  2170.         menu_ienable( app_cntrl.menu,help->item,1);
  2171.     
  2172.     help = help->next;
  2173.     }
  2174. }
  2175.  
  2176. /* ---------------------------------------------------------------------- */
  2177. /* Menü-Ereignisse bearbeiten                                             */
  2178. /* ---------------------------------------------------------------------- */
  2179. void menu_manager(int title, int item, int scan_code)
  2180. {
  2181.     struct MENU_LIST *help;
  2182.     OBJECT *menue;
  2183.     menue=get_app_cntrl()->menu;
  2184.     help = menu_start;
  2185.  
  2186.     while (help)
  2187.     {
  2188.         if (((title == help->title && item == help->item) ||
  2189.              (scan_code == help->scan_code)) &&     
  2190.              (((menue+help->item)->ob_state&DISABLED) == 0)) 
  2191.              
  2192.         {
  2193.             if(help->action)
  2194.                 help->action();
  2195.             menu_tnormal(app_cntrl.menu, title, 1);
  2196.             return;
  2197.         }
  2198.         help = help->next;
  2199.     }         
  2200. }    
  2201.  
  2202.  
  2203. /* ---------------------------------------------------------------------- */
  2204. /* Menu-Liste freigeben                                                   */
  2205. /* ---------------------------------------------------------------------- */
  2206. void kill_menu()
  2207. {
  2208.     struct MENU_LIST *help;
  2209.  
  2210.     help = menu_start;
  2211.     while(menu_start)
  2212.     {
  2213.         menu_start = help->next;
  2214.         free(help);
  2215.         help = menu_start;
  2216.     }
  2217. }
  2218.  
  2219. /*------------------------------------------------------------------------*/
  2220. /* Message Manager                                                                     */
  2221. /*------------------------------------------------------------------------*/
  2222. /* Speicher für Message-Ereignis alloziieren                              */
  2223. /* ---------------------------------------------------------------------- */
  2224. struct MSG_LIST *alloc_msg(void)
  2225. {
  2226.     struct MSG_LIST *help;
  2227.     
  2228.     help = msg_start;
  2229.     msg_start = (struct MSG_LIST *)calloc(1, sizeof(struct MSG_LIST));
  2230.     msg_start->next = help;
  2231.     return(msg_start);
  2232. }
  2233.  
  2234.  
  2235.  
  2236. /*------------------------------------------------------------------------*/
  2237. /* Message-Ereignis anmelden                                              */
  2238. /* ---------------------------------------------------------------------- */
  2239. void msg_action(int event, void (*action)(int *))
  2240. {
  2241.     struct MSG_LIST *ptr;
  2242.     ptr = alloc_msg();
  2243.     if (ptr)
  2244.     {
  2245.          ptr->event  = event;
  2246.         ptr->action = action;
  2247.     }
  2248. }
  2249.  
  2250.  
  2251.  
  2252. /*------------------------------------------------------------------------*/
  2253. /* Message-Ereignisse bearbeiten                                          */
  2254. /* ---------------------------------------------------------------------- */
  2255. void msg_manager(int *event)
  2256. {
  2257.     struct MSG_LIST *help;
  2258.     
  2259.     help = msg_start;
  2260.     while (help) 
  2261.     {
  2262.         if (event[0] == help->event)
  2263.             help->action(event);
  2264.         help = help->next;
  2265.     } 
  2266. }    
  2267.  
  2268.  
  2269.  
  2270. /*------------------------------------------------------------------------*/
  2271. /* Message-Liste freigeben                                                */
  2272. /* ---------------------------------------------------------------------- */
  2273. void kill_msg()
  2274. {
  2275.     struct MSG_LIST *help;
  2276.  
  2277.     help = msg_start;
  2278.     while(msg_start)
  2279.     {
  2280.         msg_start = help->next;
  2281.         free(help);
  2282.         help = msg_start;
  2283.     }
  2284. }
  2285. /* EOF */