home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 615 / cpx_kurs / source / demo_cpx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-16  |  14.7 KB  |  389 lines

  1. /*  DEMO_CPX.C
  2.  *  Ein Demo-CPX-Modul
  3.  *
  4.  *  aus: Wir basteln uns ein CPX
  5.  *       CPX-Kurs Teil 1
  6.  *       TOS Magazin
  7.  *
  8.  *  (c)1992 by Richard Kurz
  9.  *  Vogelherdbogen 62
  10.  *  7992 Tettnang
  11.  *
  12.  *  Erstellt mit Pure C
  13.  */
  14.  
  15. #include <aes.h>
  16. #include <tos.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stddef.h>
  21. #include <portab.h>
  22. #include "cpx.h"
  23. #include "democpx.h"
  24. #pragma warn -rpt 
  25. #include "democpx.rsh"
  26. #pragma warn +rpt 
  27.  
  28. #define TRUE 1
  29. #define FALSE 0
  30.  
  31. /* Eine handvoll Prototypen */
  32. CPXINFO * cdecl cpx_init(XCPB *Xcpb);
  33. WORD cdecl cpx_call(GRECT *re); 
  34. void save_par(void);
  35. void ch_htext(void);
  36. void ch_vtext(void);
  37. void do_ok(void);
  38. void init_dialog(void); 
  39. WORD handle_dialog(WORD button, WORD *msg);
  40.  
  41. /* Globale Variablen */
  42. GRECT   *w_rect;        /* Die Koordinaten des Fensters.        */
  43. int     *cpx_buffer;    /* Dort lagert XControl die Daten.      */
  44. XCPB    *xcpb;          /* Zeiger auf die XControl-Funktionen.  */
  45. CPXINFO cpxinfo;        /* Zeiger auf unsere Funktionen für     */
  46.                         /* XControl.                            */
  47. MFORM   mzeiger;        /* Parkplatz für den Mauszeiger.        */
  48.  
  49. int hslide,             /* Wert für den horizontalen Slider.    */
  50.     vslide,             /* Wert für den vertikalen Slider.      */
  51.     popup;              /* Flag für PopUp AN oder AUS.          */
  52.  
  53. OBJECT  *dialog;        /* Zeiger auf unseren Dialog.           */
  54.  
  55. /* Externe Variablen aus den Assemblerteil */
  56. extern int  shslide,    /* Speicherplatz für hslide.            */
  57.             svslide,    /* Speicherplatz für vslide             */
  58.             spopup;     /* Speicherplatz für popup              */
  59.  
  60.  
  61. CPXINFO * cdecl cpx_init(XCPB *Xcpb)
  62. /* Diese Funktion wird wärend der XControl-Initialisierung und  */
  63. /* bei jeder Aktivierung unseres CPX-Moduls als erstes          */
  64. /* gestartet. Sie erhält einen Zeiger auf die CPX-Funktionen    */
  65. /* und muß einen Zeiger auf die eigenen Funktionen oder NULL    */
  66. /* bzw. 1 zurückgeben.                                          */
  67. {
  68.     xcpb=Xcpb;
  69.  
  70.  
  71.     if(xcpb->booting)
  72.     /* Dieses Flag zeigt an ob es der erste Aufruf (wärend der  */
  73.     /* XControl-Initialisierung) ist.                           */
  74.     {
  75.         /* Wir holen uns den Puffer-Bereich von XControl und    */
  76.         /* legen in ihm die Startvorgaben ab.                   */
  77.         cpx_buffer=(int *)(*xcpb->Get_Buffer)();
  78.         cpx_buffer[0]=shslide;
  79.         cpx_buffer[1]=svslide;
  80.         cpx_buffer[2]=spopup;
  81.         
  82.         /* Wärend der Initialisierung muß eine 1 zurückgegeben  */
  83.         /* werden, wenn das CPX-Modul nicht set_only sein soll. */
  84.         return ((CPXINFO *)1);
  85.     }
  86.  
  87.     if(!xcpb->SkipRshFix)
  88.     /* In diesem Flag wird festgehalten, ob der OBJECT-Baum     */
  89.     /* schon angepaßt wurde.                                    */
  90.     {
  91.         /* Wir passen den OBJECT-Baum an.                       */
  92.         (*xcpb->rsh_fix)(NUM_OBS,NUM_FRSTR,NUM_FRIMG,NUM_TREE,
  93.                          rs_object,rs_tedinfo,rs_strings,rs_iconblk,
  94.                          rs_bitblk,rs_frstr,rs_frimg,rs_trindex,
  95.                          rs_imdope);
  96.     }
  97.     dialog=(OBJECT *)rs_trindex[DIALOG];
  98.  
  99.     /* In die CPXINFO-Struktur müssen unsere Funktionen ein-    */
  100.     /* getragen werden.                                         */
  101.     cpxinfo.cpx_call    =cpx_call;
  102.     cpxinfo.cpx_draw    =NULL;
  103.     cpxinfo.cpx_wmove   =NULL;
  104.     cpxinfo.cpx_timer   =NULL;
  105.     cpxinfo.cpx_key     =NULL;
  106.     cpxinfo.cpx_button  =NULL;
  107.     cpxinfo.cpx_m1      =NULL;
  108.     cpxinfo.cpx_m2      =NULL;
  109.     cpxinfo.cpx_hook    =NULL;
  110.     cpxinfo.cpx_close   =NULL;
  111.     
  112.     /* Mit der Rückgabe unserer Funktionen melden wir uns beim  */
  113.     /* XControl an.                                             */
  114.     return(&cpxinfo);
  115. } /* cpx_init */
  116.  
  117. WORD cdecl cpx_call(GRECT *rect)
  118. /* Hier steht der Hauptteil, er wird von XControl bei der       */
  119. /* Aktivierung unseres Moduls nach cpx_init aufgerufen.         */
  120. /* In *rect stehen die Koordinaten des XControl-Fensters.       */
  121. /* Bei einem Xform_do-CPX (wie in unserem Fall), muß immer 0    */
  122. /* zurückgegeben werden.                                        */
  123. {
  124.     WORD msg[8];        /* Puffer für Xform_do.                 */
  125.     WORD button,        /* Welches Schweinderl ähh button.      */
  126.          ende;          /* Flag für's ENDE.                     */
  127.  
  128.     /* Unser Dialog muß angepaßt werden.                        */
  129.     w_rect=rect;
  130.     dialog[ROOT].ob_x=w_rect->g_x;
  131.     dialog[ROOT].ob_y=w_rect->g_y;
  132.     
  133.     /* Initialiseren und zeichnen.                              */
  134.     init_dialog();
  135.     objc_draw(dialog,ROOT,MAX_DEPTH,
  136.                 w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  137.     do
  138.     { 
  139.         /* Wir überlassen XControl die Verwaltung des Dialogs.  */
  140.         button=(*xcpb->Xform_do)(dialog,0,msg);
  141.         /* Nun müssen wir arbeiten.                             */
  142.         ende=handle_dialog(button,msg);
  143.     } while(!ende);
  144.     
  145.     /* Ende unseres Moduls, XControl ist wieder an der Reihe.   */
  146.     return(FALSE);
  147. } /* cpx_call */
  148.  
  149. WORD handle_dialog(WORD button, WORD *msg)
  150. /* Hier behandeln wir die Objekte, die angeklickt wurden.       */
  151. /* In button steht die Objekt-Nr. und in msg ein Zeiger auf     */
  152. /* einen Messag-Buffer (ähnlich wie evnt_mesag).                */
  153. {
  154.     GRECT r1;           /* Koordinaten-Feld.                    */
  155.     WORD p,ox,oy;       /* Hilfsvariablen.                      */
  156.     WORD mx,my,mk,kb;   /* Variablen für das Mäusekind.         */
  157.     char *items[4];     /* Zeiger-Feld für die PopUp-Menüs.     */
  158.     
  159.     /* Das Ausmaskieren eines Doppel-Clicks gestaltet sich hier */
  160.     /* etwas komplizierter als bei form_do, da Xform_do als     */
  161.     /* Flag für Nachrichten -1 liefert.                         */
  162.     if((button!=-1)&&(button & 0x8000))
  163.         button &= 0x7fff;
  164.  
  165.     switch(button)
  166.     {
  167.         /* Ein PopUp als Schalter!                              */
  168.         case POPUP:
  169.             /* Die einzelnen Menüpunkte für ein PopUp müssen    */
  170.             /* immer gleich lang sein! Am Anfang müssen zwei    */
  171.             /* Leerzeichen und am Ende mindestens eines stehen. */
  172.             items[0]="  Aus ";
  173.             items[1]="  An  ";
  174.             
  175.             /* XControl braucht die Koordinaten des PopUp-      */
  176.             /* Buttons. Also lassen wir sie uns berechnen.      */
  177.             objc_offset(dialog,POPUP,&r1.g_x,&r1.g_y);
  178.             r1.g_w=dialog[POPUP].ob_width;
  179.             r1.g_h=dialog[POPUP].ob_height;
  180.             
  181.             /* Die Hauptarbeit übernimmt XControl (Atari sei    */
  182.             /* Dank).                                           */
  183.             p=(*xcpb->Popup)(items,2,popup,3,&r1,w_rect);
  184.             
  185.             /* Je nach ausgewählten Menü-Punkt muß der Button   */
  186.             /* noch verändert und neu gezeichnet werden.        */
  187.             if(p==1)
  188.                 dialog[POPUP].ob_spec.free_string="An";
  189.             else if(p==0)
  190.                 dialog[POPUP].ob_spec.free_string="Aus";
  191.             if(p!=-1)
  192.             {
  193.                 popup=p;
  194.                 objc_draw(dialog,POPUP,MAX_DEPTH,w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  195.             }
  196.             break;
  197.  
  198.         /* Und schon wieder ein PopUp, aber diesmal nicht       */
  199.         /* als Schalter, sondern als Menü.                      */
  200.         case MENU:
  201.             /* Es gelten die gleichen Regeln wie bei POPUP.     */
  202.             items[0]="  Info...       ";
  203.             items[1]="  Hier könnten  ";
  204.             items[2]="  Ihre Einträge ";
  205.             items[3]="  stehen!       ";
  206.             
  207.             objc_offset(dialog,MENU,&r1.g_x,&r1.g_y);
  208.             r1.g_w=dialog[MENU].ob_width;
  209.             r1.g_h=dialog[MENU].ob_height;
  210.             
  211.             p=(*xcpb->Popup)(items,4,-1,3,&r1,w_rect);
  212.             if(p==0)
  213.                 form_alert(1,"[1][Demo CPX-Modul|1992 by R.Kurz| |TOS Magazin][ Okay ]");               
  214.             else if(p!=-1)
  215.                 form_alert(1,"[1][Selber machen|ist angesagt!][ Juchu ]");              
  216.             break;
  217.             
  218.         /* Es wird glatt, wir schlittern ein wenig (horizontal) */
  219.         /* XControl vereinfacht die Slider-Behandlung. (Toll)   */
  220.         case HMINUS:
  221.             (*xcpb->Sl_arrow)(dialog,HVATER,HTEXT,button,-1,0,80,&hslide,1,ch_htext);
  222.             break;
  223.         case HPLUS: 
  224.             (*xcpb->Sl_arrow)(dialog,HVATER,HTEXT,button,1,0,80,&hslide,1,ch_htext);
  225.             break;
  226.         case HVATER:
  227.             /* Wurde auf das 'Unterteil' des Sliders geklickt,  */
  228.             /* muß noch berechnet werden, ob der User rauf oder */
  229.             /* runter meint.                                    */
  230.             objc_offset(dialog,HTEXT,&ox,&oy);
  231.             graf_mkstate(&mx,&my,&mk,&kb);
  232.             p= mx>ox ? 10: -10;
  233.             (*xcpb->Sl_arrow)(dialog,HVATER,HTEXT,-1,p,0,80,&hslide,1,ch_htext);
  234.             break;
  235.         case HTEXT:
  236.             /* Aha, jemand möchte mit der Hand schieben.        */
  237.             /* Wenn die Mausform geändert wird, sollte die alte */
  238.             /* Form gespeichert und danach wieder restauriert   */
  239.             /* werden.                                          */
  240.             (*xcpb->MFsave)(MFSAVE, &mzeiger);
  241.             graf_mouse(FLAT_HAND,NULL);
  242.             (*xcpb->Sl_dragx)(dialog,HVATER,HTEXT,1,80,&hslide,ch_htext);
  243.             (*xcpb->MFsave)(MFRESTORE, &mzeiger);
  244.             break;
  245.         
  246.         /* Noch ein Slider, aber diesmal vertikal.              */
  247.         case VMINUS:
  248.             (*xcpb->Sl_arrow)(dialog,VVATER,VTEXT,button,-1,1,40,&vslide,0,ch_vtext);
  249.             break;
  250.         case VPLUS:
  251.             (*xcpb->Sl_arrow)(dialog,VVATER,VTEXT,button,1,1,40,&vslide,0,ch_vtext);
  252.             break;
  253.         case VVATER:
  254.             objc_offset(dialog,VTEXT,&ox,&oy);
  255.             graf_mkstate(&mx,&my,&mk,&kb);
  256.             p= my>oy ? -5 : 5;
  257.             (*xcpb->Sl_arrow)(dialog,VVATER,VTEXT,-1,p,1,40,&vslide,0,ch_vtext);
  258.             break;
  259.         case VTEXT:
  260.             (*xcpb->MFsave)(MFSAVE, &mzeiger);
  261.             graf_mouse(FLAT_HAND,NULL);
  262.             (*xcpb->Sl_dragy)(dialog,VVATER,VTEXT,1,40,&vslide,ch_vtext);
  263.             (*xcpb->MFsave)(MFRESTORE, &mzeiger);
  264.             break;
  265.  
  266.         case SICHERN:
  267.             /* Wer sich für's SICHERN interessiert, dem sei     */
  268.             /* save_par() empfohlen.                            */
  269.             save_par();
  270.             dialog[button].ob_state &= ~SELECTED;
  271.             objc_draw(dialog,button,1,
  272.                     w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  273.             break;
  274.         case OKAY:
  275.             /* Bei OKAY werden noch die Betriebsparameter       */
  276.             /* gesichert                                        */
  277.             do_ok();
  278.         case ABBRUCH:
  279.             dialog[button].ob_state &= ~SELECTED;
  280.             return(TRUE);
  281.  
  282.         default:
  283.             /* Wenn Xform_do -1 zurückliefert, ist etwas im     */
  284.             /* Busche, bzw. im Message-Puffer. Der Aufbau des   */
  285.             /* Puffers ist ähnlich wie bei evnt_mesag.          */
  286.             if(button==-1)
  287.             {
  288.                 switch(msg[0])
  289.                 {
  290.                     case WM_CLOSED:
  291.                     /* Wurde das Fenster geschlossen, wird das  */
  292.                     /* wie OKAY behandelt.                      */
  293.                         do_ok();
  294.                     case AC_CLOSE:
  295.                     /* Bei AC_CLOSE nichts wie raus! Wurde vom  */
  296.                     /* Modul Speicher angefordert oder sind     */
  297.                     /* Dateien geöffnet, unbedingt aufräumen!!  */
  298.                         return(TRUE);
  299.                     case CT_KEY:
  300.                     /* Jemand hat eine Sondertaste gedrückt.    */
  301.                     /* Help, Undo, Funktions-Tasten usw.        */
  302.                         if(msg[3]==0x6200)      /* Help         */
  303.                         {
  304.                             form_alert(1,"[0][Hiiiiilfe !!!! ][ Ah ja ]");
  305.                         }
  306.                         else if(msg[3]==0x6100) /* Undo         */
  307.                         {
  308.                             p=form_alert(2,"[2][Undo oder nicht Undo|ist hier die Frage][ Ja | Nein ]");                            
  309.                             if(p==1)
  310.                             {
  311.                                 init_dialog();
  312.                                 objc_draw(dialog,ROOT,MAX_DEPTH,
  313.                                            w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  314.                             }
  315.                         }
  316.                     case WM_REDRAW:
  317.                     /* Darum braucht sich ein Xform_do-Modul    */
  318.                     /* nicht kümmern. Nur Event-Module haben    */
  319.                     /* Arbeit damit.                            */
  320.                     default:
  321.                         break;
  322.                 }
  323.             }
  324.             break;
  325.     }
  326.     return(FALSE);
  327. } /* handle_dialog */
  328.  
  329. void init_dialog(void)
  330. /* Aus dem permanenten Puffer von XControl werden die Werte     */
  331. /* geholt und der Object-Baum angepaßt.                         */
  332. {
  333.     cpx_buffer=(int *)(*xcpb->Get_Buffer)();
  334.     hslide=cpx_buffer[0];
  335.     vslide=cpx_buffer[1];
  336.     popup=cpx_buffer[2];
  337.     
  338.  
  339.     (*xcpb->Sl_x)(dialog,HVATER,HTEXT,hslide,0,80,ch_htext);
  340.     (*xcpb->Sl_y)(dialog,VVATER,VTEXT,vslide,1,40,ch_vtext);
  341.  
  342.     if(popup) dialog[POPUP].ob_spec.free_string="An";
  343.     else      dialog[POPUP].ob_spec.free_string="Aus";
  344. } /* init_dialog */
  345.  
  346. void save_par(void)
  347. /* Die Parameter werden von XControl an den Anfang des Daten-   */
  348. /* segmts gesichert. Bitte den Assemblerteil anschauen!         */
  349. {
  350.     if((*xcpb->XGen_Alert)(SAVE_DEFAULTS))
  351.     {
  352.         cpx_buffer[0]=hslide;
  353.         cpx_buffer[1]=vslide;
  354.         cpx_buffer[2]=popup;
  355.         shslide=hslide;
  356.         svslide=vslide;
  357.         spopup=popup;
  358.  
  359.         if(!(*xcpb->CPX_Save)(&shslide,6))
  360.             (*xcpb->XGen_Alert)(FILE_ERR);
  361.     }
  362. } /* save_par */
  363.  
  364. void ch_htext(void)
  365. /* Aktualisiert den Text im horizontalen Slider.                */
  366. {
  367.     static char s[10];
  368.     
  369.     sprintf(s,"%i",hslide);
  370.     dialog[HTEXT].ob_spec.free_string=s; 
  371. } /* ch_htext */
  372.  
  373. void ch_vtext(void)
  374. /* Aktualisiert den Text im vertikalen Slider.                  */
  375. {
  376.     static char s[10];
  377.     
  378.     sprintf(s,"%i",vslide);
  379.     dialog[VTEXT].ob_spec.free_string=s; 
  380. } /* ch_vtext */
  381.  
  382. void do_ok(void)
  383. /* Sichert die Parameter im permanenten Puffer von XControl.    */
  384. {
  385.     cpx_buffer[0]=hslide;
  386.     cpx_buffer[1]=vslide;
  387.     cpx_buffer[2]=popup;
  388. } /* do_ok */
  389.