home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / p / popups / Docs / ExampleSrc / c / _Report < prev    next >
Encoding:
Text File  |  1993-05-21  |  8.5 KB  |  270 lines

  1. /*  File:     _Report.c
  2.  *  Purpose:  Supplies functionality for a PopUp
  3.  *  Author:   © Copyright 1993 Jason Williams
  4.  *            All rights reserved
  5.  */
  6.  
  7. #include <string.h> 
  8.  
  9. #include "DeskLib:WimpSWIs.h"
  10. #include "DeskLib:Icon.h"
  11. #include "DeskLib:Keycodes.h"
  12. #include "DeskLib:Sound.h"
  13. #include "DeskLib:StringCR.h"
  14. #include "DeskLib:Template.h"
  15.  
  16. #include "Server.h"
  17.  
  18.  
  19. typedef struct
  20. {
  21.   int  flags;
  22.   char oktext[12];
  23.   char canceltext[12];
  24.   char appname[12];
  25.   char message[188];
  26. } report_data;
  27.  
  28.  
  29. typedef struct
  30. {
  31.   int flags;
  32.   window_block *window;
  33. } report_workspace;
  34.  
  35.  
  36. /*  First of all, we define a handler_info structure for our PopUp handler
  37.  *  which describes it to the manager. This is referenced externally
  38.  *  by the server to find the procedure to call with events for any PopUp
  39.  *  of this type, etc.
  40.  *  (We also prototype the handler function so we can reference it here)
  41.  */
  42.  
  43. static int Handler_Report(int, ctrl_block *, void *, event_pollblock *);
  44.  
  45. handler_info HandlerInfo_Report =
  46. {
  47.   "Report",                                  /* PopUp type/name string       */
  48.   0x00000003,                                /* Flag word (MENU/STATIC)      */
  49.   Handler_Report,                            /* Handler procedure            */
  50.   16                                         /* Instantiation workspace size */
  51. };
  52.  
  53.  
  54.  
  55. static BOOL Finished(ctrl_block *ctrl, report_workspace *ws, BOOL okpressed)
  56. /*  We have finished (are closing the window). Return state indicating if
  57.  *  the window was 'OKed' or Cancelled.
  58.  *  Note that we can kill the menu because we don't allow a Menu Leaf version
  59.  *  of the window, and we ALWAYS return a state message to the client so that
  60.  *  they don't sit waiting for us ad infinitum!
  61.  */
  62. {
  63.   /*  IF we are a MENU instantiation, then we must be very careful.
  64.    *  If we just delete the window, but the menu was still 'open', the WIMP
  65.    *  crashes (and burns (and rolls (and explodes violently))).
  66.    *  However, if we always kill the menu, we get a nasty effect - if the
  67.    *  user clicked menu elsewhere to get rid of us, our menu has been closed
  68.    *  and the new menu shown BEFORE we are called, and so we kill the wrong
  69.    *  menu - nasty.
  70.    *  Luckily, we can tell if our window is still open as a menu - if the
  71.    *  window is still open! So we check this, and only close the existing menu
  72.    *  if we are a MENU PopUp and our window is still open.
  73.    */
  74.  
  75.   if (ctrl != NULL)          /* Have we managed to create the window at all? */
  76.   {
  77.     if (ws->window == NULL)        /* No clone'd template data, so is a menu */
  78.     {
  79.       window_state state;
  80.  
  81.       Wimp_GetWindowState(ctrl->basewindow, &state);
  82.       if (state.flags.data.open)
  83.         Wimp_CreateMenu((menu_block *) -1, 0, 0);
  84.     }
  85.  
  86.     Wimp_DeleteWindow(ctrl->basewindow);
  87.   }
  88.  
  89.   if (ws->window != NULL)                       /* If static, release memory */
  90.     Template_Free(&ws->window);                 /* used by cloned template   */
  91.  
  92.   ws->flags &= 0xffffff00;                      /* Return User handle + flag */
  93.   if (okpressed) ws->flags |= 0x02; else ws->flags |= 0x01;
  94.  
  95.   SendState(&ws->flags, sizeof(int));
  96.  
  97.   KillMe();
  98.   return(TRUE);
  99. }
  100.  
  101.  
  102.  
  103. /*  The Handler_ function referenced in the above info struct will handle all
  104.  *  calls from the server during normal operation...
  105.  */
  106.  
  107. static BOOL Handler_Report(int reasoncode, ctrl_block *ctrl,
  108.                            void *privateworkspace, event_pollblock *event)
  109. {
  110.   report_workspace *ws = privateworkspace;
  111.  
  112.   switch(reasoncode)
  113.   {
  114.     case REASON_OPEN:
  115.       {
  116.         window_handle windowhandle;
  117.         window_block  *window;
  118.         report_data  *info;
  119.  
  120.         info = (report_data *) (((int)event) + POPUP_DATA_OFFSET);
  121.         ws->flags = info->flags;
  122.  
  123.         /*  Find the template. NOTE that if you provide a STATIC popup, you
  124.          *  MUST support multiple instantiations, so MUST use Template_Clone()
  125.          *  Also note that if bringing up a MENU LEAF window, we must clone
  126.          *  our template data into the RMA so the WIMP does not crash! ;-(
  127.           */
  128.         if (ctrl->appflags & APPFLAGS_ISSTATIC)
  129.           ws->window = window = Template_Clone("Report", 0);
  130.         else
  131.         {
  132.           Wimp_CreateMenu((menu_block *) -1, 0, 0);    /* Kill previous menu */
  133.           ws->window = NULL;
  134.           if((ctrl->appflags & APPFLAGS_ISLEAF) == 0)
  135.             window = Template_Find("Report");
  136.           else
  137.           {
  138.             Finished(NULL, ws, FALSE);
  139.             return(FALSE);
  140.           }
  141.         }
  142.  
  143.         if (window == NULL)
  144.         {
  145.           Finished(NULL, ws, FALSE);
  146.           return(FALSE);
  147.         }
  148.  
  149.         /*  Create the window, and fill in its icons with the data given
  150.          *  to us in the pollblock. (DATA_BASE is defined above)
  151.          */
  152.         strcpy(window->title.indirecttext.buffer, "Message");
  153.         if (info->appname[0] > 31)
  154.         {
  155.           strcatcr(window->title.indirecttext.buffer, " from ");
  156.           strcatcr(window->title.indirecttext.buffer, info->appname);
  157.         }
  158.  
  159.         Wimp_CreateWindow(window, &windowhandle);
  160.         info->message[187] = 0;
  161.  
  162.         if (info->flags & 0x02)
  163.           SetIconText(windowhandle, 0, info->oktext);
  164.         if (info->flags & 0x01)
  165.           SetIconText(windowhandle, 2, info->canceltext);
  166.  
  167.         SetIconText(windowhandle, 1, info->message);
  168.  
  169.         if ((info->flags & 3) != 3)                    /* Only want 1 button */
  170.         {
  171.           int icon, dead, halfwidth, wmiddle;
  172.           icon_createblock icreate;
  173.  
  174.           if (info->flags & 0x02)
  175.             { icon = 0; dead = 2;  }
  176.           else
  177.             { icon = 2; dead = 0;  }
  178.  
  179.           icreate.window = windowhandle;            /* Move the icon we want */
  180.           Wimp_GetIconState(windowhandle, icon, &icreate.icondata);
  181.           Wimp_DeleteIcon(windowhandle, icon);
  182.  
  183.           wmiddle = (window->workarearect.max.x -     /* Center it in window */
  184.                      window->workarearect.min.x) / 2;
  185.           halfwidth = (icreate.icondata.workarearect.max.x -
  186.                        icreate.icondata.workarearect.min.x) / 2;
  187.  
  188.           icreate.icondata.workarearect.min.x = wmiddle - halfwidth;
  189.           icreate.icondata.workarearect.max.x = wmiddle + halfwidth;
  190.           Wimp_CreateIcon(&icreate, &icon);
  191.  
  192.           Wimp_DeleteIcon(windowhandle, dead);  /* And delete the other icon */
  193.         }
  194.  
  195.         if (ctrl->appflags & APPFLAGS_ISSTATIC)
  196.           ShowStaticPopUp(windowhandle, ctrl->openx, ctrl->openy);
  197.  
  198.         Sound_SysBeep();
  199.  
  200.         ctrl->pollmask.value = ~( (1 << event_CLOSE) |
  201.                                   (1 << event_CLICK) |
  202.                                   (1 << event_KEY)   |
  203.                                   (1 << event_NULL)  );
  204.         ctrl->basewindow = windowhandle;     /* Let server know windowhandle */
  205.       }
  206.       return(TRUE);
  207.  
  208.  
  209.     case REASON_CLOSE:                          /* Quietly close our window  */
  210.       return(Finished(ctrl, ws, FALSE));
  211.  
  212.  
  213.     case REASON_EVENT:                                /* Handle a WIMP Event */
  214.       switch(event->type)
  215.       {
  216.         case event_NULL:
  217.           /*  We need to check frequently if our window has been closed, as
  218.            *  under RISC OS 2.00 the Wimp doesn't tell us if it has done so!
  219.            */
  220.           {
  221.             window_state wstate;
  222.  
  223.             Wimp_GetWindowState(ctrl->basewindow, &wstate);
  224.             if (!wstate.flags.data.open)    /* Window has indeed been closed */
  225.               return(Finished(ctrl, ws, FALSE));
  226.           }
  227.           break;
  228.  
  229.         case event_CLOSE:
  230.           if (event->data.openblock.window == ctrl->basewindow)
  231.             return(Finished(ctrl, ws, FALSE));
  232.           break;
  233.  
  234.         case event_CLICK:
  235.          if (event->data.mouse.window == ctrl->basewindow)
  236.           {
  237.             switch(event->data.mouse.icon)
  238.             {
  239.               case 0:  /* OK     */
  240.                 return(Finished(ctrl, ws, TRUE));
  241.  
  242.               case 2:  /* Cancel */
  243.                 return(Finished(ctrl, ws, FALSE));
  244.             }
  245.             return(TRUE);
  246.           }
  247.           break;          
  248.  
  249.         case event_KEY:
  250.          if (event->data.key.caret.window == ctrl->basewindow)
  251.           {
  252.             switch(event->data.key.code)
  253.             {
  254.               case keycode_RETURN:
  255.                 return(Finished(ctrl, ws, TRUE));
  256.  
  257.               case keycode_ESCAPE:             /* Needed for the static case */
  258.                 return(Finished(ctrl, ws, FALSE));
  259.             }
  260.             return(TRUE);
  261.           }
  262.           break;
  263.       }
  264.       break;
  265.   }
  266.  
  267.   return(FALSE);          /* If we didn't handle this call, we MUST return 0 */
  268. }
  269.  
  270.