home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / spirit / tut / !Lesson5_C_Lesson5 < prev    next >
Encoding:
Text File  |  1993-12-06  |  14.1 KB  |  497 lines

  1. /*
  2.  *      Title     : Lesson 5
  3.  *      System    : New Risc-OS library. */
  4. #define Version     "1.0"
  5. /*      Copyright : (c) John Winters
  6.  *      Date      : 28th November, 1993
  7.  *      Author    : John H. Winters
  8.  *
  9.  *      Function  : Lesson 5 of the Spirit library tutorial.
  10.  *
  11.  *      At last, a "Hello World" program.
  12.  *
  13.  *      N.B.  We use the high-level font opening routines in WinAppLib,
  14.  *      rather than the low-level ones in FontLib, so that they will be
  15.  *      closed automatically when the program exits.
  16.  *
  17.  *
  18.  *      Modification history.
  19.  *
  20.  *      Version   : 
  21.  *      Date      : 
  22.  *      Author    : 
  23.  *      Changes   : 
  24.  *
  25.  */
  26.  
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include "fontlib.h"
  30. #include "winapp.h"
  31.  
  32. /*
  33.  *==========================================================================
  34.  *
  35.  *  Hash defines.
  36.  *
  37.  *==========================================================================
  38.  */
  39.  
  40. #define FONT_SIZE  50   /* Point size of font to use */
  41. #define MENU_INFO   0   /* Menu entry for information */
  42. #define MENU_QUIT   1   /* Menu entry to quit */
  43. #define TFN_VERSION 4   /* Field number for version string */
  44.  
  45. /*
  46.  *==========================================================================
  47.  *
  48.  *  Local data.
  49.  *
  50.  *==========================================================================
  51.  */
  52.  
  53. /*
  54.  *  The following data items describe the font we are going
  55.  *  to use.
  56.  */
  57. static const t_font_descriptor *FontDescriptor ;
  58. static char                     FontName [256] = "Trinity.Medium" ;
  59. static unsigned int             FontResolution = 0 ;
  60. static unsigned int             FontSize       = FONT_SIZE * 16 ;
  61. /*
  62.  *  The text we propose to print.
  63.  */
  64. static const char        Text []     = "Hello World" ;
  65. /*
  66.  *  Handle on the dialogue box which we use to give process information.
  67.  */
  68. static t_dbox          InfoDbox ;
  69. /*
  70.  *  Name of our template file.
  71.  */
  72. static const char      TemplateFileName [] = "Templates" ;
  73. /*
  74.  *  String to place in our information dialogue box.
  75.  */
  76. static char            VersionString [] = Version " (28th November, 1993)" ;
  77. /*
  78.  *  Handle for our window.
  79.  */
  80. static t_window_handle WindowHandle ;
  81.  
  82. /*
  83.  *==========================================================================
  84.  *
  85.  *  Externally visible data.
  86.  *
  87.  *==========================================================================
  88.  */
  89.  
  90. /*
  91.  *  This data item gives the name of the directory to look in when loading
  92.  *  resources.  It will make the library code look for an environment
  93.  *  variable <Lesson5$Dir> which points to the correct directory.
  94.  */
  95. const char WA_resource_dir [] = "Lesson5" ;
  96. /*
  97.  *  This data item defines the task name.
  98.  */
  99. const char WA_task_name [] = "Lesson 5" ;
  100.  
  101. /*
  102.  *==========================================================================
  103.  *
  104.  *  Forward declarations.
  105.  *
  106.  *==========================================================================
  107.  */
  108.  
  109. static unsigned int ClickHandler (
  110.     t_poll_block *poll_block,
  111.     void         *reference) ;
  112.  
  113. static unsigned int FontHandler (
  114.     void     *reference,
  115.     const u8 *name) ;
  116.  
  117. static void MenuHandler (
  118.     void      *reference,
  119.     const int *hit) ;
  120.  
  121. static uint RedrawHandler (
  122.     t_poll_block *poll_block,
  123.     void         *reference) ;
  124.  
  125. /*
  126.  *==========================================================================
  127.  *
  128.  *  Externally visible routines.
  129.  *
  130.  *==========================================================================
  131.  */
  132.  
  133. unsigned int WA_BeginProcessing (void)
  134.  
  135. /*
  136.  *  Function :
  137.  *                  This routine is called after we have succesfully
  138.  *                  called WIMP_Initialise and are ready to go ahead.
  139.  *
  140.  *  Parameters :
  141.  *                  None.
  142.  *
  143.  *  Returns :
  144.  *                  TRUE if we are happy to go on, FALSE otherwise.
  145.  *
  146.  */
  147.  
  148. {
  149.     t_menu_block    *MainMenu ;
  150.  
  151.     /*
  152.      *  Create a menu to attach to our icon.  The syntax for the menu
  153.      *  string is as for Acorn's product.
  154.      */
  155.     MainMenu = WA_BuildMenu (WA_resource_dir,
  156.                              ">Info, Quit") ;
  157.     if (MainMenu == NULL)
  158.     {
  159.         LOG_Error ("Failed to create a menu.\n") ;
  160.     }
  161.     else
  162.     {
  163.         /*
  164.          *  Now create a dialogue box from the template we loaded
  165.          *  earlier.  It's a non-persistent one (FALSE), and
  166.          *  doesn't require a handler or reference (NULL, NULL).
  167.          */
  168.         InfoDbox = WA_CreateDbox ("ProgInfo", FALSE, NULL, NULL) ;
  169.         if (InfoDbox == NULL)
  170.         {
  171.             LOG_Error ("Can't create information dbox.\n") ;
  172.         }
  173.         else
  174.         {
  175.             /*
  176.              *  Inject our current version number into the dialogue
  177.              *  box.
  178.              */
  179.             WA_SetDboxField (InfoDbox,
  180.                              TFN_VERSION,
  181.                              VersionString) ;
  182.             /*
  183.              *  Create a window.  Note the use of WA_CreateWindow
  184.              *  instead of WIMP_CreateWindow.  The former does more
  185.              *  work for us (cloning the template etc.) and registers
  186.              *  a default handler.
  187.              */
  188.             if ((WA_CreateWindow ("Window", NULL, &WindowHandle)) &&
  189.                 (WA_ClaimEvent (ET_RedrawRequest,
  190.                                 WindowHandle,
  191.                                 DONT_CARE,
  192.                                 RedrawHandler,
  193.                                 NULL)))
  194.             {
  195.                 /*
  196.                  *  Now pop our icon on the bar, and attach a menu to it.
  197.                  *  If an error occurs it will be reported for us.
  198.                  */
  199.                 return ((WA_IconToBar ("!lesson5", TRUE)) &&
  200.                         (WA_AttachMenu (ICON_BAR,
  201.                                         MainMenu,
  202.                                         MenuHandler,
  203.                                         NULL)) &&
  204.                         (WA_ClaimEvent (ET_MouseClick,
  205.                                         ICON_BAR,
  206.                                         DONT_CARE,
  207.                                         ClickHandler,
  208.                                         NULL)) &&
  209.                         (WA_AttachFontMenu (WindowHandle,
  210.                                             FALSE,
  211.                                             FontName,
  212.                                             FontHandler,
  213.                                             NULL))) ;
  214.             }
  215.         }
  216.     }
  217.     return (FALSE) ;
  218. }
  219.  
  220.  
  221. unsigned int WA_LoadResources (void)
  222.  
  223. /*
  224.  *  Function :
  225.  *                  This is our opportunity to load whatever resources
  226.  *                  we require before WIMP_Initialise is called.
  227.  *
  228.  *  Parameters :
  229.  *                  None.
  230.  *
  231.  *  Returns :
  232.  *                  TRUE if we are happy to go on, FALSE otherwise.
  233.  *
  234.  */
  235.  
  236. {
  237.     t_LOG_HandlerMask mask ;
  238.  
  239.     /*
  240.      *  Arrange for any messages to appear in a pop-up box.  A more
  241.      *  sophisticated application would probably arrange its own
  242.      *  message handling, but this easy method is provided for noddy
  243.      *  code.
  244.      */
  245.     mask.value             = 0 ;
  246.     mask.b.LHM_Debug       = TRUE ;
  247.     mask.b.LHM_Info        = TRUE ;
  248.     mask.b.LHM_Warning     = TRUE ;
  249.     mask.b.LHM_Error       = TRUE ;
  250.     mask.b.LHM_SevereError = TRUE ;
  251.     WA_SetPopupErrors (mask) ;
  252.     /*
  253.      *  Now we need a sprite to put on the icon bar, and a template
  254.      *  for our information box.  Note that we are here loading our sprite
  255.      *  from the !Sprites file in our application directory.  If we were
  256.      *  using more than one sprite, we would probably use a separate
  257.      *  sprite file.
  258.      */
  259.     return ((WA_LoadSprites ("!Sprites")) &&
  260.             (WA_LoadTemplate (TemplateFileName, "ProgInfo")) &&
  261.             (WA_LoadTemplate (TemplateFileName, "Window")) &&
  262.             ((FontDescriptor = WA_OpenFont (FontName,
  263.                                             FontSize,
  264.                                             FontSize,
  265.                                             FontResolution,
  266.                                             FontResolution)) != NULL)) ;
  267. }
  268.  
  269. /*
  270.  *==========================================================================
  271.  *
  272.  *  Local routines.
  273.  *
  274.  *==========================================================================
  275.  */
  276.  
  277. static unsigned int ClickHandler (
  278.     t_poll_block *poll_block,
  279.     void         *reference)
  280.  
  281. /*
  282.  *  Function :
  283.  *                  Click handler.
  284.  *
  285.  *  Parameters :
  286.  *                  poll_block  Pointer to block describing the event.
  287.  *                  reference   Ignored.
  288.  *
  289.  *  Returns :
  290.  *                  TRUE if we handled the event, FALSE otherwise.
  291.  *
  292.  */
  293.  
  294. {
  295.     t_state_block state ;
  296.  
  297.     reference = reference ;
  298.     /*
  299.      *  Check for left or right.
  300.      */
  301.     if ((poll_block->data.mc.button_state.m.adjust) ||
  302.         (poll_block->data.mc.button_state.m.select))
  303.     {
  304.         /*
  305.          *  The customer has clicked on our icon.  Display our window.
  306.          *  If it is already on view, this sequence will have the effect
  307.          *  of bringing it to the front.
  308.          */
  309.         if (LOG_OSError (WIMP_GetWindowState (WindowHandle,
  310.                                               &state)) == NULL)
  311.         {
  312.             state.open_block.behind = -1 ;
  313.             LOG_OSError (WIMP_OpenWindow (&(state.open_block))) ;
  314.         }
  315.         return (TRUE) ;
  316.     }
  317.     else
  318.     {
  319.         return (FALSE) ;
  320.     }
  321. }
  322.  
  323.  
  324. static unsigned int FontHandler (
  325.     void     *reference,
  326.     const u8 *name)
  327.  
  328. /*
  329.  *  Function :
  330.  *                  Handles notifications of font changes.
  331.  *
  332.  *  Parameters :
  333.  *                  reference   Ignored.
  334.  *                  name        New font name.
  335.  *
  336.  *  Returns :
  337.  *                  None.
  338.  *
  339.  */
  340.  
  341. {
  342.     const t_font_descriptor *descriptor ;
  343.     unsigned int             height ;
  344.     t_redraw_block           redraw_block ;
  345.     unsigned int             result ;
  346.     t_state_block            state_block ;
  347.     unsigned int             width ;
  348.  
  349.     reference = reference ;
  350.     result    = FALSE ;
  351.     if (*name != '\0')
  352.     {
  353.         descriptor = WA_OpenFont (name,
  354.                                   FontSize,
  355.                                   FontSize,
  356.                                   FontResolution,
  357.                                   FontResolution) ;
  358.         if (descriptor != NULL)
  359.         {
  360.             WA_CloseFont (FontDescriptor) ;
  361.             strcpy (FontName, name) ;
  362.             FontDescriptor = descriptor ;
  363.             if (LOG_OSError (WIMP_GetWindowState (WindowHandle,
  364.                                                   &state_block)) == NULL)
  365.             {
  366.                 if (state_block.flags.is_open)
  367.                 {
  368.                     /*
  369.                      *  As a short cut here, we could just invalidate the
  370.                      *  rectangular area of the screen which our visible work
  371.                      *  area is occupying.  Unfortunately, this would cause any
  372.                      *  window overlaying it to flicker.
  373.                      */
  374.                     height = state_block.open_block.visible_area.max.y -
  375.                              state_block.open_block.visible_area.min.y ;
  376.                     width  = state_block.open_block.visible_area.max.x -
  377.                              state_block.open_block.visible_area.min.x ;
  378.                     redraw_block.handle = WindowHandle ;
  379.                     redraw_block.visible_area.min.x =
  380.                       state_block.open_block.scroll_offset.x ;
  381.                     redraw_block.visible_area.min.y =
  382.                       state_block.open_block.scroll_offset.y - height ;
  383.                     redraw_block.visible_area.max.x =
  384.                       state_block.open_block.scroll_offset.x + width ;
  385.                     redraw_block.visible_area.max.y =
  386.                       state_block.open_block.scroll_offset.y ;
  387.                     LOG_OSError (WIMP_ForceRedraw (&redraw_block)) ;
  388.                 }
  389.             }
  390.             /*
  391.              *  We have changed font.  Set result to TRUE so that our
  392.              *  menu will be updated with appropriate ticks.
  393.              */
  394.             result = TRUE ;
  395.         }
  396.     }
  397.     return (result) ;
  398. }
  399.  
  400.  
  401. static void MenuHandler (
  402.     void      *reference,
  403.     const int *hit)
  404.  
  405. /*
  406.  *  Function :
  407.  *                  Menu event handler.
  408.  *
  409.  *  Parameters :
  410.  *                  reference  Ignored.
  411.  *                  hit        Indication of the menu hit.
  412.  *
  413.  *  Returns :
  414.  *                  None.
  415.  *
  416.  */
  417.  
  418. {
  419.     reference = reference ;
  420.     /*
  421.      *  See which menu entry has been chosen.
  422.      */
  423.     switch (hit [0])
  424.     {
  425.         case MENU_INFO :
  426.             WA_DisplayDbox (InfoDbox) ;
  427.             break ;
  428.  
  429.         case MENU_QUIT :
  430.             /*
  431.              *  This call causes our application to exit in an
  432.              *  orderly manner.
  433.              */
  434.             WA_WindUp () ;
  435.             break ;
  436.  
  437.     }
  438. }
  439.  
  440.  
  441. static uint RedrawHandler (
  442.     t_poll_block *poll_block,
  443.     void         *reference)
  444.  
  445. /*
  446.  *  Function :
  447.  *                  Handle incoming redraw requests.
  448.  *
  449.  *  Parameters :
  450.  *                  poll_block  Poll block describing event.
  451.  *                  reference   Ignored.
  452.  *
  453.  *  Returns :
  454.  *                  TRUE if we handled it, FALSE if we didn't.
  455.  *
  456.  */
  457.  
  458. {
  459.     uint                    more ;
  460.     static t_font_plot_type plot_type = {
  461.         FALSE,  /* Graphics justify */
  462.         FALSE,  /* Rubout */
  463.         FALSE,  /* 2  bits unused */
  464.  
  465.         TRUE,   /* OS units */
  466.         FALSE,  /* Use Coordinate block */
  467.         FALSE,  /* Use transformation matrix */
  468.         FALSE,  /* Use length value */
  469.  
  470.         TRUE,   /* Use font handle */
  471.         FALSE,  /* Do kerning */
  472.         FALSE,  /* Write from right to left */
  473.         0       /* The rest */
  474.     } ;
  475.     t_redraw_block          rb ;
  476.  
  477.     reference = reference ;
  478.     WIMP_SetFontColours (8, 0) ;
  479.     rb.handle = poll_block->data.ob.window_handle ;
  480.     if (LOG_OSError (WIMP_RedrawWindow (&rb, &more)) == NULL)
  481.     {
  482.         while (more)
  483.         {
  484.             FONT_Paint (FontDescriptor->handle,
  485.                         Text,
  486.                         plot_type,
  487.                         rb.visible_area.min.x - rb.scroll_offset.x + 25,
  488.                         rb.visible_area.max.y - rb.scroll_offset.y - 200,
  489.                         NULL,
  490.                         NULL,
  491.                         0) ;
  492.             WIMP_GetRectangle (&rb, &more) ;
  493.         }
  494.     }
  495.     return (TRUE) ;
  496. }
  497.