home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 1 / Amiga Tools.iso / egs-tools / egs_dev-disk / egsdemos / moreexamples / global / userwindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-06  |  27.2 KB  |  848 lines

  1.                      /*  UserWIndow.c
  2.                          This module is designed to handle all of the
  3.                          subtle things about gadget windows for you.
  4.                          I use this in EGS-Paint for every window that's
  5.                          not a DrawWindow (even the toolpanel and palette).
  6.                          This code is freely distributable (in its orignial
  7.                          state).
  8.                          Feel free to use this in your development, or just
  9.                          use it to gain some insight to how all this stuff
  10.                          works.
  11.                          I use the UserData item in the Window structure
  12.                          to reference back to the associated UserWindow.
  13.                          This helps in the message processing. (see any
  14.                          of the main modules.)
  15.                          Great Valley Products Inc.
  16.                          Patrick Hager  October 26, 1993.
  17.                       */
  18.  
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <proto/exec.h>
  24. #include "egslibraries.h"
  25.  
  26. #include <egs/egsintui.h>
  27. #include <egs/clib/egsintui_protos.h>
  28. #include <egs/pragmas/egsintui_pragmas.h>
  29. #include <egs/egsgadbox.h>
  30. #include <egs/clib/egsgadbox_protos.h>
  31. #include <egs/pragmas/egsgadbox_pragmas.h>
  32. #define EGSPUSERWINDOW
  33.  #include "userwindow.h"
  34. #undef EGSPUSERWINDOW
  35.  
  36.  
  37.  
  38.  
  39. void *UserList=NULL;          // Our list of UserWindows.
  40.  
  41. void RunUserWindow (UserInputWindowPtr UserWindow);
  42.  
  43.  
  44.  
  45.  
  46. /************************************
  47.               PUBLIC:   myFindGadget.
  48.                         Anyone can use this. When dealing with Master Gadgets,
  49.                         there are many type casts necessary to do a FindGadget,
  50.                         so this does it for you.
  51. ************************************/
  52. EI_GadgetPtr myFindGadget (EB_GadContext gadcon,long id) {
  53.   EI_GadgetPtr tgad;
  54.  
  55.   if (gadcon) {
  56.     if (tgad = EB_FindGadget ( ((EI_MasterGadPtr)gadcon->First)->FirstSon,
  57.                                ((EI_MasterGadPtr)gadcon->First)->NumSons,
  58.                                  id)) {
  59.       return tgad;
  60.     }
  61.     else
  62.       return NULL;
  63.   }
  64.   else
  65.     return NULL;
  66. }
  67.  
  68.  
  69. /**********************************
  70.   PUBLIC:  Init_UserWindow.
  71.            This routine must be run for each window you wish to create.
  72.            It clears all of the structures and NULLs all function
  73.            pointers. It must be run before an Open_UserWindow.
  74.            Once opened, don't run it again.
  75. **********************************/
  76. void Init_UserWindow (UserInputWindowPtr UserWindow, char *title, WORD  ModeFlags,
  77.                       EI_MenuPtr MenuPtr, struct MsgPort *Port) {
  78.  
  79.   if (UserWindow) {
  80.     UserWindow->Window=NULL;
  81.     UserWindow->GadCon=NULL;
  82.     UserWindow->Create=NULL;
  83.     UserWindow->Redraw=NULL;
  84.     UserWindow->Close=NULL;
  85.     UserWindow->GadgetDown=NULL;
  86.     UserWindow->IDCMP=NULL;
  87.     UserWindow->Menu=NULL;
  88.     UserWindow->RawKey=NULL;
  89.     UserWindow->VanillaKey=NULL;
  90.     UserWindow->MouseMove=NULL;
  91.     UserWindow->MouseButtons=NULL;
  92.  
  93.     UserWindow->UserData=NULL;
  94.     UserWindow->Title=NULL;
  95.     UserWindow->Next=NULL;
  96.     UserWindow->MenuPtr = MenuPtr;
  97.     UserWindow->Port=Port;
  98.     UserWindow->Signals=NULL;
  99.     UserWindow->ModeFlags=ModeFlags;
  100.     if (UserWindow->Title=(char *)malloc ((strlen (title)+2)*sizeof (char))) {
  101.       strcpy (UserWindow->Title,title);
  102.     }
  103.   }
  104. }
  105.  
  106.  
  107.  
  108.  
  109. /****************************************************
  110.   PUBLIC:  Open_UserWindow.
  111.            Call this routine to open a new UserWindow, or to open a UserWindow
  112.            which was previously closed.
  113. ***************************************************/
  114. BYTE Open_UserWindow (UserInputWindowPtr UserWindow, WORD x, WORD y) {
  115.  
  116.   BYTE ret=0;
  117.  
  118.   if (!UserWindow->Window) {
  119.                             // The window is not currently open on the Screen.
  120.     if (UserWindow->GadCon) {
  121.                             /* If the UserWindow's GadContext exists, then the
  122.                                window has been previously opened and closed.
  123.                                Now we can just reopen the window using the
  124.                                NewWindow structure contained in the
  125.                                GadContext.
  126.                             */
  127.       if (UserWindow->Window= EI_OpenWindow (UserWindow->GadCon->NewWin)) {
  128.         UserWindow->Window->UserData = (void *) UserWindow->UserData;
  129.         AddUserWindow (UserWindow);
  130.         EI_ActivateWindow (UserWindow->Window);
  131.         ret=1;
  132.       }
  133.       else {
  134.                             // Maybe no memory to open... We'll close to
  135.                             // clean things up.
  136.         Close_UserWindow (UserWindow);
  137.         ret=0;
  138.       }
  139.     }
  140.     else {
  141.                             /* This is the first time this window has been
  142.                                opened. We'll first create the window's
  143.                                gadget list, then attempt to open from
  144.                                the NewWindow structure contained in the
  145.                                newly created gadContext.
  146.                             */
  147.       //printf ("calling create.\n");
  148.       if (UserWindow->Window=Create_UserWindow (UserWindow,NULL,x,y)) {
  149.         //printf ("Created.\n");
  150.         //printf ("add to list...\n");
  151.         AddUserWindow (UserWindow);
  152.         //printf ("added!\n");
  153.         EI_ActivateWindow (UserWindow->Window);
  154.         ret = 1;
  155.       }
  156.       else {
  157.                             // Maybe no memory to open this window....
  158.                             // We'll close to clean things up.
  159.         Close_UserWindow (UserWindow);
  160.         ret=0;
  161.       }
  162.     }
  163.  
  164.     if (ret=1) {
  165.                            // Successfull Open.
  166.                            // Call the Redraw function if the UserWindow has
  167.                            // one...
  168.       if (UserWindow->Redraw)
  169.         UserWindow->Redraw (UserWindow);
  170.       ((WindowInfoPtr)UserWindow->Window->UserData)->UserWindow=UserWindow;
  171.     }
  172.   }
  173.   else {
  174.                            // Window is allready open. Let's just bring it
  175.                            // to the front.
  176.     EI_WindowToFront (UserWindow->Window);
  177.     ret = 1;
  178.   }
  179.   if ((ret)&&(UserWindow->ModeFlags&WINDOW_MODAL)) {
  180.                            /* If we had called Init_UserWindow and supplied
  181.                              the flag WINDOW_MODAL, it means we wish to run
  182.                              this window and only this window, until it is
  183.                              finished or closed. We will be stuck in
  184.                              RunUserWindow until that happens.
  185.                              We'll put all the other windows to sleep so the user
  186.                              can't click on them until this window is closed.
  187.                            */
  188.     RunUserWindow (UserWindow);
  189.   }
  190.  
  191.   return ret;
  192. }
  193.  
  194.  
  195.  
  196. /********************************
  197.      PUBLIC:     Close_UserWindow.
  198.                  This routine is called ONLY when the Window
  199.                  is closed the very last time.
  200.                  Otherwise, UserWindow.c will close the window and keep the old
  201.                  GadContext.
  202. ********************************/
  203. void Close_UserWindow (UserInputWindowPtr UserWindow) {
  204.  
  205.   if (UserWindow) {
  206.                                      // If the UserWindow has a close function,
  207.                                      // call it.
  208.       if (UserWindow->Close)
  209.         UserWindow->Close (UserWindow);
  210.     RemoveUserWindow (UserWindow);
  211.     if (UserWindow->Window) {
  212.       if (UserWindow->Window->UserData) {
  213.         free (UserWindow->Window->UserData);
  214.         UserWindow->UserData=NULL;
  215.       }
  216.       EI_CloseWindow (UserWindow->Window);
  217.       UserWindow->Window=NULL;
  218.     }
  219.     if (UserWindow->GadCon) {
  220.       EB_DeleteGadContext (UserWindow->GadCon);
  221.       UserWindow->GadCon = NULL;
  222.     }
  223.     if (UserWindow->Title) {
  224.       free (UserWindow->Title);
  225.       UserWindow->Title=NULL;
  226.     }
  227.   }
  228. }
  229.  
  230.  
  231. /********************************
  232.    PUBLIC:  Close_All_UserWindows.
  233.             Here's a quick way to end your program. This routine will close
  234.             any UserWindow currently on Screen (as well as any associated
  235.             Close function pointers so you can free any memory you may have
  236.             allocated along with that particular Window.
  237. ********************************/
  238. void Close_All_UserWindows (void) {
  239.   UserInputWindowPtr user;
  240.  
  241.   while (user=(UserInputWindowPtr)UserList) {
  242.     Close_UserWindow (user);
  243.   }
  244. }
  245.  
  246. /***************************************************
  247.   PRIVATE:  UserWindow_EventHandler.
  248.             This is the Event Handler used by the UserWindow module.
  249. ***************************************************/
  250. void UserWindow_EventHandler (struct EI_EIntuiMsg *Msg) {
  251.   ULONG class;
  252.   UWORD code;
  253.   WORD qual;
  254.   WORD x,y;
  255.   EI_GadgetPtr iaddress=NULL;
  256.   EI_WindowPtr win;
  257.   UserInputWindowPtr UserWindow;
  258.  
  259.   UserWindow= (UserInputWindowPtr) ((WindowInfoPtr)Msg->IDCMPWindow->UserData)->
  260.                                     UserWindow;
  261.   if (UserWindow->IDCMP) {
  262.     UserWindow->IDCMP (UserWindow,Msg);
  263.   }
  264.   else {
  265.     class = Msg->Class;
  266.     code = Msg->Code;
  267.     iaddress = Msg->IAddress;
  268.     qual = Msg->Qualifier;
  269.     win = Msg->IDCMPWindow;
  270.     x=Msg->MouseX;
  271.     y=Msg->MouseY;
  272.     ReplyMsg ( (struct Message *)Msg);
  273.  
  274.     switch (class) {
  275.                                  /* Here, a close window is temporary.
  276.                                     We copy the current window size,pos
  277.                                     to the UserWindow's GadContext's
  278.                                     NewWindow structure.
  279.                                  */
  280.       case EI_iCLOSEWINDOW:
  281.         if (UserWindow->Close)
  282.           UserWindow->Close (UserWindow);
  283.         RemoveUserWindow (UserWindow);
  284.         UserWindow->GadCon->NewWin->LeftEdge= UserWindow->Window->LeftEdge;
  285.         UserWindow->GadCon->NewWin->TopEdge = UserWindow->Window->TopEdge;
  286.         UserWindow->GadCon->NewWin->Width=UserWindow->Window->Width;
  287.         UserWindow->GadCon->NewWin->Height=UserWindow->Window->Height;
  288.         UserWindow->GadCon->NewWin->MinWidth=UserWindow->Window->MinWidth;
  289.         UserWindow->GadCon->NewWin->MinHeight=UserWindow->Window->MinHeight;
  290.         UserWindow->GadCon->NewWin->MaxWidth=UserWindow->Window->MaxWidth;
  291.         UserWindow->GadCon->NewWin->MaxHeight=UserWindow->Window->MaxHeight;
  292.         EI_CloseWindow (UserWindow->Window);
  293.         UserWindow->Window=NULL;
  294.         UserWindow->GadCon->NewWin->FirstGadgets->NextGadget=NULL;
  295.       break;
  296.  
  297.       case EI_iSIZEVERIFY:
  298.          SizeVerify_UserWindow (UserWindow);
  299.       break;
  300.  
  301.       case EI_iNEWSIZE:
  302.          NewSize_UserWindow (UserWindow);
  303.          if (UserWindow->Redraw)
  304.            UserWindow->Redraw (UserWindow);
  305.       break;
  306.  
  307.       case EI_iGADGETDOWN:
  308.          if (UserWindow->GadgetDown)
  309.            UserWindow->GadgetDown (UserWindow,iaddress);
  310.       break;
  311.  
  312.       case EI_iMENUPICK:
  313.          if (UserWindow->Menu)
  314.            UserWindow->Menu (UserWindow, code);
  315.       break;
  316.       case EI_iRAWKEY:
  317.         if (UserWindow->RawKey)
  318.           UserWindow->RawKey (UserWindow,code, qual);
  319.       break;
  320.  
  321.       case EI_iVANILLAKEY:
  322.         if (UserWindow->VanillaKey)
  323.           UserWindow->VanillaKey (UserWindow, code, qual, x, y);
  324.       break;
  325.  
  326.       case EI_iREFRESHWINDOW:
  327.         if (EI_BeginRefresh (UserWindow->Window,(LONG)iaddress)) {
  328.           if (UserWindow->Redraw) {
  329.             UserWindow->Redraw (UserWindow);
  330.           }
  331.           EI_EndRefresh (UserWindow->Window,TRUE);
  332.         }
  333.       break;
  334.  
  335.       case EI_iMOUSEMOVE:
  336.         if (UserWindow->MouseMove)
  337.           UserWindow->MouseMove (UserWindow, x, y);
  338.       break;
  339.  
  340.       case EI_iMOUSEBUTTONS:
  341.         if (UserWindow->MouseButtons)
  342.           UserWindow->MouseButtons (UserWindow, code, x, y);
  343.       break;
  344.  
  345.     }
  346.   }
  347. }
  348.  
  349.  
  350. /*********************************
  351.         PRIVATE:    SizeVerify_UserWindow.
  352.                     This routine is called on a size verify event.
  353. *********************************/
  354. void SizeVerify_UserWindow (UserInputWindowPtr UserWindow) {
  355.  
  356.   EI_LockIntuition ();
  357.   EI_RemoveGadget (UserWindow->Window,UserWindow->GadCon->First);
  358.   if (UserWindow->GadCon) {
  359.     EB_DeleteGadContext (UserWindow->GadCon);
  360.     UserWindow->GadCon=NULL;
  361.   }
  362.   EI_UnlockIntuition ();
  363. }
  364.  
  365.  
  366. /**********************************
  367.          PRIVATE:   NewSize_UserWindow.
  368.                     This routine is called on a newsize event.
  369. **********************************/
  370. void NewSize_UserWindow (UserInputWindowPtr UserWindow) {
  371.  
  372.   EI_LockIntuition ();
  373.   UserWindow->Window = Create_UserWindow (UserWindow,UserWindow->Window,
  374.                                           UserWindow->Window->LeftEdge,
  375.                                           UserWindow->Window->TopEdge);
  376.   EI_AddGadget (UserWindow->Window,UserWindow->GadCon->First);
  377.   EI_UnlockIntuition ();
  378. }
  379.  
  380.  
  381. /******************************
  382.     PRIVATE:    Create_UserWindow.
  383.                 Creates the gadboxes and gadgets for the
  384.                 Example Wand control panel (Stencil Options).
  385. *******************************/
  386. EI_WindowPtr Create_UserWindow (UserInputWindowPtr UserWindow,
  387.                                           EI_WindowPtr win, WORD x, WORD y) {
  388.   EB_GadBoxPtr root;
  389.   EI_WindowPtr retwin=NULL;
  390.  
  391.   //printf ("Create_UserWindow:\n");
  392.   UserWindow->GadCon = EB_CreateGadContext (NULL,NULL,-1,-1);
  393.  
  394.   //printf ("Calling Example_Create.\n");
  395.   if (root=UserWindow->Create (UserWindow)) {
  396.     //printf ("OK. Back...\n");
  397.     root = EB_CreateMasterWindow (UserWindow->GadCon,win,root);
  398.     if (EB_ProcessGadBoxes (UserWindow->GadCon,root)) {
  399.       UserWindow->GadCon->NewWin->IDCMPFlags = UserWindow->IDCMPFlags;
  400.       UserWindow->GadCon->NewWin->Bordef.SysGadgets = UserWindow->SysGadgets;
  401.       UserWindow->GadCon->NewWin->Flags = UserWindow->Flags;
  402.       UserWindow->GadCon->NewWin->Menu = UserWindow->MenuPtr;
  403.       UserWindow->GadCon->NewWin->Title = UserWindow->Title;
  404.       if (!(UserWindow->ModeFlags&WINDOW_MODAL)) {
  405.         UserWindow->GadCon->NewWin->Port=UserWindow->Port;
  406.       }
  407.       if ((x>=0)&&(y>=0)) {
  408.         UserWindow->GadCon->NewWin->LeftEdge =x;
  409.         UserWindow->GadCon->NewWin->TopEdge = y;
  410.       }
  411.       else {
  412.                              // First time only, open in center.
  413.         UserWindow->GadCon->NewWin->Flags|=EI_WINDOWCENTER;
  414.       }
  415.       if (win==NULL) {
  416.         retwin = EI_OpenWindow (UserWindow->GadCon->NewWin);
  417.         //printf ("Opened in create.\n");
  418.         //UserWindow->Window=retwin;
  419.         UserWindow->GadCon->NewWin->Flags&= (~EI_WINDOWCENTER);
  420.         if (retwin) {
  421.           if (UserWindow->Port==NULL)
  422.             UserWindow->Port=UserWindow->Window->UserPort;
  423.           if (retwin->UserData = (struct WindowInfo *) malloc (1*
  424.                               sizeof (struct WindowInfo))) {
  425.             ((struct WindowInfo *)retwin->UserData)->EventHandler =
  426.                                       UserWindow_EventHandler;
  427.             UserWindow->UserData=retwin->UserData;
  428.           }
  429.           else {
  430.             Close_UserWindow (UserWindow);
  431.             retwin=NULL;
  432.           }
  433.         }
  434.         else {
  435.           Close_UserWindow (UserWindow);
  436.           retwin=NULL;
  437.         }
  438.         return retwin;
  439.       }
  440.       else {
  441.         return (win);
  442.       }
  443.     }
  444.     else
  445.       return NULL;
  446.   }
  447.   else
  448.     return NULL;
  449. }
  450.  
  451. /*************************************
  452.   PRIVATE:  RunUserWindow.
  453.             This is here for MODAL windows. It will run the GUI of the
  454.             UserWindow, until it is closed (or finished).
  455. *************************************/
  456. void RunUserWindow (UserInputWindowPtr UserWindow) {
  457.   struct EI_EIntuiMsg *Msg;
  458.   ULONG class;
  459.   UWORD code;
  460.   WORD qual;
  461.   WORD x,y;
  462.   EI_GadgetPtr iaddress;
  463.   EI_WindowPtr win;
  464.  
  465.   if (UserWindow->ModeFlags&WINDOW_MODAL) {
  466.     while (!UserWindow->Signals&SIGNAL_CLOSE) {
  467.       Wait (1<<UserWindow->Window->UserPort->mp_SigBit);
  468.  
  469.       while (Msg = (struct EI_EIntuiMsg *)GetMsg (UserWindow->Window->UserPort)) {
  470.         class = Msg->Class;
  471.         code = Msg->Code;
  472.         qual = Msg->Qualifier;
  473.         x=Msg->MouseX;
  474.         y=Msg->MouseY;
  475.         iaddress=(EI_GadgetPtr)Msg->IAddress;
  476.         win=(EI_WindowPtr)Msg->IDCMPWindow;
  477.         ReplyMsg ( (struct Message *)Msg);
  478.  
  479.         switch (class) {
  480.           case EI_iCLOSEWINDOW:
  481.             UserWindow->Signals |= SIGNAL_CLOSE;
  482.           break;
  483.  
  484.           case EI_iSIZEVERIFY:
  485.              SizeVerify_UserWindow (UserWindow);
  486.           break;
  487.  
  488.           case EI_iNEWSIZE:
  489.              NewSize_UserWindow (UserWindow);
  490.              if (UserWindow->Redraw)
  491.                UserWindow->Redraw (UserWindow);
  492.           break;
  493.  
  494.           case EI_iGADGETDOWN:
  495.              if (UserWindow->GadgetDown)
  496.                UserWindow->GadgetDown (UserWindow,iaddress);
  497.           break;
  498.  
  499.           case EI_iMENUPICK:
  500.              if (UserWindow->Menu)
  501.                UserWindow->Menu (UserWindow, code);
  502.           break;
  503.           case EI_iRAWKEY:
  504.             if (UserWindow->RawKey)
  505.               UserWindow->RawKey (UserWindow,code, qual);
  506.           break;
  507.  
  508.           case EI_iVANILLAKEY:
  509.             if (UserWindow->VanillaKey)
  510.               UserWindow->VanillaKey (UserWindow, code, qual, x, y);
  511.           break;
  512.  
  513.           case EI_iREFRESHWINDOW:
  514.             if (EI_BeginRefresh (UserWindow->Window,(LONG)iaddress)) {
  515.               if (UserWindow->Redraw) {
  516.                 UserWindow->Redraw (UserWindow);
  517.               }
  518.               EI_EndRefresh (UserWindow->Window,TRUE);
  519.             }
  520.           break;
  521.  
  522.          case EI_iMOUSEMOVE:
  523.            if (UserWindow->MouseMove)
  524.              UserWindow->MouseMove (UserWindow, x, y);
  525.          break;
  526.  
  527.          case EI_iMOUSEBUTTONS:
  528.            if (UserWindow->MouseButtons)
  529.              UserWindow->MouseButtons (UserWindow, code, x, y);
  530.          break;
  531.  
  532.         }
  533.       }
  534.     }
  535.   }
  536. }
  537.  
  538.  
  539. void Sleep_All_UserWindows (void) {
  540.   UserInputWindowPtr user;
  541.  
  542.   user=(UserInputWindowPtr)UserList;
  543.   while (user) {
  544.     EI_SleepWindow (user->Window);
  545.     user=(UserInputWindowPtr)user->Next;
  546.   }
  547. }
  548.  
  549. void Wake_All_UserWindows (void) {
  550.   UserInputWindowPtr user;
  551.  
  552.   user=(UserInputWindowPtr)UserList;
  553.   while (user) {
  554.     EI_WakeWindow (user->Window);
  555.     user=(UserInputWindowPtr)user->Next;
  556.   }
  557. }
  558.  
  559.  
  560. /****************************
  561.   PRIVATE:  AddUserWindow.
  562.             This routine is called internally from UserWindow.c. It adds
  563.             a UserWindow to the linked list for management. If you need
  564.             to call this function yourself, add it's prototype to the
  565.             UserWindow.h file, but be carefll not to corrupt the
  566.             linked list.
  567. ****************************/
  568. void AddUserWindow (UserInputWindowPtr UserWindow) {
  569.  
  570.   //printf ("AddUserWindow.%x\n",UserWindow);
  571.   if (UserWindow) {
  572.     if (UserList==NULL) {
  573.       //printf ("added to beginning.\n");
  574.       UserList=(void *)UserWindow;
  575.       UserWindow->Next=NULL;
  576.     }
  577.     else {
  578.       //printf ("added to beginning, set poiunter to next.(%x)\n",UserList);
  579.       UserWindow->Next=UserList;
  580.       UserList=(void *)UserWindow;
  581.     }
  582.   }
  583. }
  584.  
  585. /****************************
  586.   PRIVATE:  RemoveUserWindow.
  587.             This routine is called internally from UserWindow.c. It removes
  588.             a UserWindow from the linked list for management. If you need
  589.             to call this function yourself, add it's prototype to the
  590.             UserWindow.h file, but be carefll not to corrupt the
  591.             linked list.
  592. ****************************/
  593. void RemoveUserWindow (UserInputWindowPtr UserWindow) {
  594.   UserInputWindowPtr user, lastuser;
  595.   BYTE Found=0;
  596.  
  597.   user=(UserInputWindowPtr)UserList;
  598.   lastuser=NULL;
  599.   while ((user)&&(!Found)) {
  600.     if (user==UserWindow) {
  601.       Found=1;
  602.       if (lastuser) {
  603.         //printf ("Found userwindow to remove.%08x\n",user);
  604.         //printf ("assigning lastuser->Next=user->next.%07x,%07x\n",lastuser->Next,user->Next);
  605.         lastuser->Next=user->Next;
  606.         user->Next=NULL;
  607.       }
  608.       else {
  609.         //printf ("Found userwindow to remove.%08x\n",user);
  610.         //printf ("Assigning userlist to user->Next.%08x\n",user->Next);
  611.         UserList=user->Next;
  612.         user->Next=NULL;
  613.       }
  614.     }
  615.     lastuser=user;
  616.     user=(UserInputWindowPtr)user->Next;
  617.   }
  618. }
  619.  
  620. /******************************************************
  621.                 Examples for code you need to write!
  622. *******************************************************
  623.  
  624. struct UserInputWindow Example_Request;
  625.  
  626. BYTE Open_ExampleWindow (WORD x, WORD y);
  627. EB_GadBoxPtr Create_Example (UserInputWindowPtr UserWindow);
  628. void Close_Example (UserInputWindowPtr UserWindow);
  629. void Redraw_Example (UserInputWindowPtr UserWindow);
  630. void Refresh_Example (UserInputWindowPtr UserWindow);
  631. void GadgetDown_Example (UserInputWindowPtr UserWindow, EI_GadgetPtr iaddress);
  632. void IDCMP_Example      (struct UserInputWindow *UserWindow, struct EI_EIntuiMsg *Msg);
  633.  
  634. void CloseDown_Example (void);
  635.  
  636. /***********************************
  637.    PUBLIC: Open_ExampleWindow.
  638.            This is called by anyone who wants to open the
  639.            Example Control Window.
  640. ***********************************/
  641. BYTE Open_ExampleWindow (WORD x, WORD y) {
  642.   static First=1;
  643.  
  644.   if (First) {
  645.     Init_UserWindow (&Example_Request,"FreeHand Example Control",0);
  646.     Example_Request.Redraw     = Redraw_Example;
  647.     Example_Request.GadgetDown = GadgetDown_Example;
  648.     Example_Request.Create     = Create_Example;
  649.     Example_Request.Close      = Close_Example;
  650.     Example_Request.IDCMP      = IDCMP_Example;
  651.     //Example_Request.Data = (LONG *)&RefreshFlag;  // ... or whatever....
  652.   }
  653.   if (!Open_UserWindow (&Example_Request,-1,-1)) {
  654.     SayOne ("No Memory to open FreeHand Example Control Panel.",-1,-1);
  655.     return 0;
  656.   }
  657.  
  658.   return 1;
  659. }
  660.  
  661. /*************************************
  662.    PRIVATE:  Create_Example.
  663.              This routine is called by the UserWindow routines.
  664.              It passes back a GadBoxPtr to the gadgets wanted.
  665. *************************************/
  666. EB_GadBoxPtr Create_Example (UserInputWindowPtr UserWindow) {
  667.   EB_GadBoxPtr root,help;
  668.   EB_GadContext gadcon;
  669.  
  670.   gadcon = UserWindow->GadCon;
  671.   root = EB_CreateVertiBox (gadcon);
  672.   EB_AddLastSon (root,EB_CreateVertiFill (gadcon,0,0));
  673.   return root;
  674. }
  675.  
  676. /*************************************
  677.    PRIVATE:  Close_Example.
  678.              This routine CANNOT be used to close the Example
  679.              Control Window!!! It is called by the UserWindow
  680.              routines to allow this window to clean up any
  681.              allocated memory.
  682.              To Close the Example Control Window, call
  683.              CloseDown_Example ();
  684. *************************************/
  685. void Close_Example (UserInputWindowPtr UserWindow) {
  686.  
  687.   //if (UserWindow->Data)
  688.   //  free (UserWindow->Data);  // or something...
  689. }
  690.  
  691. /**************************************
  692.     PUBLIC:  Redraw_Example.
  693.              This routine handles redraw events to the Example
  694.              Control Window. Called by UserWindow routines, and
  695.              could be called by other routines as well.
  696.              Also called on an EI_iREFRESHWINDOW message.
  697. **************************************/
  698. void Redraw_Example (UserInputWindowPtr UserWindow) {
  699.  
  700. }
  701.  
  702.  
  703. /**************************************
  704.    PUBLIC:  Refresh_Example.
  705.             This routine is called on a EI_iREFRESHWINDOW message.
  706.             If you have nothing to refresh, set the Example_Request.Refresh
  707.             to NULL.
  708. **************************************/
  709. void Refresh_Example (UserInputWindowPtr UserWindow) {
  710. }
  711.  
  712.  
  713. /**************************************
  714.     PRIVATE:  GadgetDown_Example.
  715.               This routine handles the gadget down events passed to the
  716.               Example Control Window.
  717. **************************************/
  718. void GadgetDown_Example (UserInputWindowPtr UserWindow, EI_GadgetPtr iaddress) {
  719.  
  720.  
  721.   switch (iaddress->GadgetID) {
  722.   }
  723. }
  724.  
  725. /**************************************
  726.     PRIVATE:  Menu_Example.
  727.               This routine handles the Menu events passed to the
  728.               Example Control Window.
  729. **************************************/
  730. char Menu_Example (UserInputWindowPtr UserWindow, UWORD code) {
  731.  
  732.  
  733. }
  734.  
  735.  
  736. /***************************************
  737.    PRIVATE:  IDCMP_Example.
  738.              This routine is used in place of GadgetDown_Example if
  739.              you need access to any IDCMP message, not just GadgetDown,
  740.              ie. MouseMove, MouseButton etc.
  741.              You must leave in the code found here, as the normal event
  742.              handler will NOT be called if this function is not NULL.
  743.              This includes rawkey, newsize etc.
  744.              Also note the GadgetDown_Example code will not be called,
  745.              even if it exists, if this function is called. So remember to
  746.              add in your gadget instructions as well.
  747.              Using just the GadgetDown_Example code makes your job MUCH
  748.              easier, but this is here if you have special applications
  749.              (ie. in my case the palette window (yes- its a UserWindow!))
  750. **************************************/
  751. void IDCMP_Example      (struct UserInputWindow *UserWindow, struct EI_EIntuiMsg *Msg){
  752.   ULONG class;
  753.   UWORD code;
  754.   WORD qual;
  755.   WORD x,y;
  756.   EI_GadgetPtr iaddress=NULL;
  757.   EI_WindowPtr win;
  758.  
  759.   class = Msg->Class;
  760.   code = Msg->Code;
  761.   iaddress = Msg->IAddress;
  762.   qual = Msg->Qualifier;
  763.   win = Msg->IDCMPWindow;
  764.   x=Msg->MouseX;
  765.   y=Msg->MouseY;
  766.   ReplyMsg ( (struct Message *)Msg);
  767.  
  768.   switch (class) {
  769.     case EI_iCLOSEWINDOW:
  770.       if (UserWindow->Close)
  771.         UserWindow->Close (UserWindow);
  772.       RemoveUserWindow (UserWindow);
  773.       UserWindow->GadCon->NewWin->LeftEdge= UserWindow->Window->LeftEdge;
  774.       UserWindow->GadCon->NewWin->TopEdge = UserWindow->Window->TopEdge;
  775.       UserWindow->GadCon->NewWin->Width=UserWindow->Window->Width;
  776.       UserWindow->GadCon->NewWin->Height=UserWindow->Window->Height;
  777.       UserWindow->GadCon->NewWin->MinWidth=UserWindow->Window->MinWidth;
  778.       UserWindow->GadCon->NewWin->MinHeight=UserWindow->Window->MinHeight;
  779.       UserWindow->GadCon->NewWin->MaxWidth=UserWindow->Window->MaxWidth;
  780.       UserWindow->GadCon->NewWin->MaxHeight=UserWindow->Window->MaxHeight;
  781.       EI_CloseWindow (UserWindow->Window);
  782.       UserWindow->Window=NULL;
  783.       UserWindow->GadCon->NewWin->FirstGadgets->NextGadget=NULL;
  784.       if (Last_Used_DrawWindow)
  785.         EI_ActivateWindow (Last_Used_DrawWindow->Window);
  786.       else
  787.         ActivateToolWindow ();
  788.     break;
  789.  
  790.     case EI_iSIZEVERIFY:
  791.        SizeVerify_UserWindow (UserWindow);
  792.     break;
  793.  
  794.     case EI_iNEWSIZE:
  795.        NewSize_UserWindow (UserWindow);
  796.        if (UserWindow->Redraw)
  797.          UserWindow->Redraw (UserWindow);
  798.     break;
  799.  
  800.     case EI_iGADGETDOWN:
  801.        switch (iaddress->GadgetID) {
  802.        }
  803.     break;
  804.     case EI_iMOUSEBUTTONS:
  805.       if (code==SELECTDOWN) {
  806.        }
  807.        else if (code == SELECTUP) {
  808.        }
  809.     break;
  810.  
  811.     case EI_iMOUSEMOVE:
  812.     break;
  813.  
  814.     case EI_iMENUPICK:
  815.       EGSPMenuPick (win,code);
  816.     break;
  817.     case EI_iRAWKEY:
  818.       ProcessRawKey (code,qual);
  819.     break;
  820.  
  821.     case EI_iVANILLAKEY:
  822.        ProcessVanillaKey (Last_Used_DrawWindow,code,qual,x,y);
  823.     break;
  824.  
  825.     case EI_iREFRESHWINDOW:
  826.       if (EI_BeginRefresh (UserWindow->Window,(LONG)iaddress)) {
  827.         if (UserWindow->Refresh) {
  828.           UserWindow->Refresh (UserWindow);
  829.         }
  830.         EI_EndRefresh (UserWindow->Window,TRUE);
  831.       }
  832.     break;
  833.   }
  834. }
  835.  
  836. /**************************************
  837.   PUBLIC:  CloseDown_Example.
  838.            This can be used to close down the Example Control Window,
  839.            however, it should really be closed by itself.
  840.            (or else through Close_All_UserWindows ());
  841. **************************************/
  842. void CloseDown_Example (void) {
  843.  
  844.   Close_UserWindow (&Example_Request);
  845. }
  846.  
  847. ******************************************************/
  848.