home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / d / handy / !Handy / c / MyWindow < prev   
Encoding:
Text File  |  1993-09-20  |  7.6 KB  |  276 lines

  1. /*
  2.     File:    MyWindow.c
  3.     Author:  Copyright © 1993 Paul Vernon
  4.     Version: 1.00 (19 Mar 1992)
  5.     Purpose: My High-level window management functions:
  6.                 these do not clone the windows, so only one open at once!
  7. */
  8.  
  9. #include "DeskLib:Wimp.h"
  10. #include "DeskLib:StringCR.h"
  11. #include "DeskLib:Error.h"
  12. #include "DeskLib:LinkList.h"
  13. #include "DeskLib:Template.h"
  14. #include "DeskLib:WimpSWIs.h"
  15. #include "DeskLib:Error.h"
  16. #include "DeskLib:Screen.h"
  17. #include "DeskLib:Event.h"
  18. #include "MyWindow.h"
  19.  
  20. #include <stdlib.h>
  21. #include <string.h>
  22.  
  23. static linklist_header mywindow_listanchor;
  24.  
  25. typedef struct
  26. {
  27.   linklist_header header;
  28.   window_handle   window;
  29.   char            templatename[wimp_MAXNAME +1];
  30.   window_block    *memory;                           /* template block       */
  31. } windowrec;
  32.  
  33. /* Tries to find window of name windowname, returns handle if exists else NULL*/
  34. extern window_handle MyWindow_Find(char *windowname)
  35. {
  36.     windowrec     *ptr;
  37.  
  38.     ptr = (windowrec *) mywindow_listanchor.next;
  39.     while (ptr != NULL){
  40.  
  41.         if (strcmpcr(ptr->templatename, windowname)==0){
  42.             break;
  43.         }
  44.         ptr = (windowrec *) ptr->header.next;
  45.     }
  46.     if (ptr != NULL){
  47.         return(ptr->window);            /* Window does exist */
  48.     }
  49.     return NULL;                        /* Does not exist     */
  50. }
  51.  
  52. #define ERRBASE 1
  53. #define ERR1 ERRBASE+0
  54. #define ERRMESS1 "Insufficient memory to open window"
  55.  
  56. extern window_handle MyWindow_Create(char *windowname)
  57. {
  58.     windowrec     *record;
  59.     window_block  *windowptr;
  60.     window_handle window;
  61.  
  62.     windowptr = Template_Find(windowname);
  63.  
  64.     Wimp_CreateWindow(windowptr, &window);
  65.  
  66.     record = (windowrec *) malloc(sizeof(windowrec));
  67.     if (record == NULL)  Error_ReportFatalInternal(ERR1, ERRMESS1);
  68.  
  69.     LinkList_AddToHead(&mywindow_listanchor, &(record->header));
  70.  
  71.     strncpy(record->templatename, windowname, wimp_MAXNAME);
  72.     record->templatename[wimp_MAXNAME] = 0;       /*Record of name for help  */
  73.  
  74.     record->window = window;                      /*Remember window handle   */
  75.     record->memory = windowptr;                   /*template window block*/
  76.  
  77.   return(window);
  78. }
  79.  
  80. extern void MyWindow_Delete(window_handle window)
  81. {
  82.   windowrec       *ptr;
  83.  
  84.   Event_ReleaseWindow(window);       /* Release all handlers for this window */
  85.  
  86.   Wimp_CloseWindow(window);                                  /* say bye bye! */
  87.   Wimp_DeleteWindow(window);
  88.  
  89.   ptr = (windowrec *) mywindow_listanchor.next;
  90.   while (ptr != NULL)
  91.   {
  92.     if (ptr->window == window)
  93.       break;
  94.     ptr = (windowrec *) ptr->header.next;
  95.   }
  96.  
  97.   if (ptr == NULL)
  98.     return;
  99.  
  100.   LinkList_Unlink(&mywindow_listanchor, &(ptr->header));
  101.  
  102.   free(ptr);                         /* ... and the window's list entry      */
  103. }
  104.  
  105.  
  106. extern void MyWindow_DeleteAll(void)
  107. /* as Window_Delete changes the window list, enougth to repeatly
  108.     delete the first element */ 
  109. {
  110.     windowrec       *ptr;
  111.  
  112.     ptr = (windowrec *) mywindow_listanchor.next;
  113.  
  114.     while (ptr != NULL)
  115.     {
  116.         Error_Report(0,"Deleting :%s",ptr->templatename);
  117.            Event_ReleaseWindow(ptr->window);
  118.            Error_Check(Wimp_CloseWindow(ptr->window));
  119.         Error_Check(Wimp_DeleteWindow(ptr->window));
  120.         LinkList_Unlink(&mywindow_listanchor, &(ptr->header));
  121.         free(ptr);
  122.         ptr = (windowrec *) mywindow_listanchor.next;
  123.     }
  124. }
  125.  
  126. static wimp_point lastopenpos = {-1, -1};
  127.  
  128.  
  129. extern void Window_Show(window_handle window, window_openpos openpos)
  130. {
  131.   window_state  wstate;
  132.   wimp_point    moveto = {0, 0};
  133.   int           w, h;
  134.  
  135.   Screen_CacheModeInfo();            /* Ensure got correct screen mode info. */
  136.  
  137.   Wimp_GetWindowState(window, &wstate);
  138.   wstate.openblock.behind = -1;                             /* open in front */
  139.  
  140.   w = wstate.openblock.screenrect.max.x - wstate.openblock.screenrect.min.x;
  141.   h = wstate.openblock.screenrect.max.y - wstate.openblock.screenrect.min.y;
  142.                                         
  143.   switch(openpos)
  144.   {
  145.     case open_CENTERED:
  146.       moveto.x = (screen_size.x - w) / 2;
  147.       moveto.y = (screen_size.y + h) / 2;
  148.       break;
  149.  
  150.     case open_OVERCARET:
  151.       {
  152.         caret_block  caret;
  153.         window_state wstate;
  154.  
  155.         Wimp_GetCaretPosition(&caret);
  156.  
  157.         if (caret.window > 0)
  158.         {
  159.           Wimp_GetWindowState(caret.window, &wstate);
  160.  
  161.           moveto.x = wstate.openblock.screenrect.min.x +
  162.                      (caret.offset.x - wstate.openblock.scroll.x) - 64;
  163.           moveto.y = wstate.openblock.screenrect.max.y -
  164.                      (caret.offset.y - wstate.openblock.scroll.y) + 64;
  165.         }
  166.         else
  167.         {
  168.           /* No caret, so just open centered on screen */
  169.           moveto.x = (screen_size.x - w) / 2;
  170.           moveto.y = (screen_size.y + h) / 2;
  171.         }
  172.       }
  173.       break;
  174.  
  175.     case open_UNDERPOINTER:
  176.       {
  177.         mouse_block ptr;
  178.  
  179.         Wimp_GetPointerInfo(&ptr);
  180.         moveto.x = ptr.pos.x - 64;
  181.         moveto.y = ptr.pos.y + 64;
  182.       }
  183.       break;
  184.  
  185.     case open_NEARLAST:
  186.       if (lastopenpos.x >= 0)
  187.       {
  188.         moveto.x = lastopenpos.x + 16;
  189.         moveto.y = lastopenpos.y - 16;
  190.       }
  191.       else
  192.       {
  193.         moveto.x = (screen_size.x - w) / 2;
  194.         moveto.y = (screen_size.y + h) / 2;
  195.       }
  196.       
  197.       if (moveto.x > ((screen_size.x / 2) + 128))
  198.         moveto.x = (screen_size.x / 2) - 128;
  199.  
  200.       if (moveto.y < ((screen_size.y / 2) - 128))
  201.         moveto.y = (screen_size.y / 2) + 128;
  202.       break;
  203.  
  204.     default:
  205.       /* Open wherever it is defined in the template file. */
  206.       moveto.x = wstate.openblock.screenrect.min.x;
  207.       moveto.y = wstate.openblock.screenrect.max.y;
  208.       break;
  209.   }
  210.  
  211.   if (moveto.x < 0)  moveto.x = 0;
  212.   if (moveto.y < 64) moveto.y = 64;
  213.   if (moveto.x > screen_size.x - 96) moveto.x = screen_size.x - 96;
  214.   if (moveto.y > screen_size.y - 32) moveto.y = screen_size.y - 32;
  215.  
  216.   wstate.openblock.screenrect.min.x = moveto.x;
  217.   wstate.openblock.screenrect.max.y = moveto.y;
  218.  
  219.   wstate.openblock.screenrect.max.x = wstate.openblock.screenrect.min.x + w;
  220.   wstate.openblock.screenrect.min.y = wstate.openblock.screenrect.max.y - h;
  221.  
  222.   if (openpos == open_NEARLAST)
  223.   {
  224.     lastopenpos.x = wstate.openblock.screenrect.min.x;  /* save last open pos*/
  225.     lastopenpos.y = wstate.openblock.screenrect.max.y;
  226.   }
  227.  
  228.   Wimp_OpenWindow(&wstate.openblock);
  229. }
  230.  
  231. extern void Window_GetInfo(window_handle window, window_info *result)
  232. /* Returns just the window part of the window_info block (strips icon defn.s)
  233.  * The real solution would be to find out how many icons were in the window
  234.  * and then get a flex block big enough for the whole thing and then do it,
  235.  * but you can't read the number of icons until you have read the window_info
  236.  * so it's a bit difficult! As a result, I just use a 4kB block to hold
  237.  * the window definition in.
  238.  *      NOTE THAT THIS WILL CRASH IF A WINDOW HAS TOO MANY ICONS!!!!!
  239.  *      (anything more than about 120 icons will cause undefined results)
  240.  */
  241. {
  242.   int         block[1024];             /* 4096 bytes for winfo return block */
  243.   window_info *winfo = (window_info *) &block[0];
  244.  
  245.   winfo->window = window;
  246.   Wimp_GetWindowInfo(winfo);
  247.   memcpy(result, winfo, sizeof(window_info));
  248. }
  249.  
  250. extern BOOL Window_HelpHandler(event_pollblock *event, void *reference);
  251.  
  252.  
  253. /* NOTE:
  254.  * By #defining "USE_EVENTMSG" on compilation, the HelpHandler will be
  255.  * called ONLY for a HelpRequest message, but this will also pull in the
  256.  * "EventMsg" code.
  257.  *
  258.  * This function is basically here to show you how to include the
  259.  * Window_HelpHandler under your own steam, using either EventMsg or Event
  260.  *
  261.  * use: #define USE_EVENTMSG 1
  262.  *
  263.  */
  264.  
  265. extern BOOL Window_AutoHelp(window_handle window, icon_handle icon)
  266. {
  267. #ifdef USE_EVENTMSG
  268.   return(EventMsg_Claim(message_HELPREQUEST, window,
  269.                           Window_HelpHandler, NULL);
  270. #else
  271.   return(Event_Claim(event_USERMESSAGERECORDED, window, icon,
  272.                                                  Window_HelpHandler, NULL));
  273. #endif
  274. }
  275.  
  276.