home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / deskutils / _a_l / boota / C-source / c / BootA < prev    next >
Encoding:
Text File  |  1991-12-18  |  51.9 KB  |  1,471 lines

  1. /* > c.BootA - (c) Paul Witheridge - Version 2.00 - 18 December 1991 */
  2.  
  3. /*===================================================================*/
  4. /*                                                                   */
  5. /*  BootA  -  boots up non-resident applications                     */
  6. /*  -----                                                            */
  7. /*                                                                   */
  8. /*  BootA is a Risc-OS Wimp-based application which is designed to   */
  9. /*  make it easy to set up Risc-OS style application directories for */
  10. /*  running non Wimp-based applications and utilities which would    */
  11. /*  otherwise have to be started by command outside the Desktop      */
  12. /*  environment or from within an !Edit task window (or at the very  */
  13. /*  least by pressing f12 in the Desktop in order to enter the       */
  14. /*  command).                                                        */
  15. /*                                                                   */
  16. /*  These 'pseudo-applications' are refered to as 'client            */
  17. /*  applications' to emphasise that they rely on BootA to do many of */
  18. /*  the things for them that a real Risc-OS application does for     */
  19. /*  itself.                                                          */
  20. /*                                                                   */
  21. /*  BootA provides the following services for its client             */
  22. /*  applications:                                                    */
  23. /*                                                                   */
  24. /*  - installing the client application's icon on the icon bar       */
  25. /*    when the user double-clicks the mouse select (or adjust)       */
  26. /*    buttons on the corresponding icon in a directory viewer        */
  27. /*    window                                                         */
  28. /*                                                                   */
  29. /*  - displaying a menu with a 'quit' option when the mouse 'menu'   */
  30. /*    button is clicked on the installed icon and removing it from   */
  31. /*    the icon bar if this 'quit' option is selected                 */
  32. /*                                                                   */
  33. /*  - providing a 'help' option in the same menu and displaying a    */
  34. /*    brief help message when this 'help' option is selected         */
  35. /*                                                                   */
  36. /*  - running the application when the mouse 'select' or 'adjust'    */
  37. /*    buttons are clicked on the installed icon, or when a file or   */
  38. /*    directory is dragged to it (clicking 'adjust' over the         */
  39. /*    installed icon will also remove it from the icon bar)          */
  40. /*                                                                   */
  41. /*  - responding to requests for help text from the '!Help'          */
  42. /*    application (which displays the text in an 'Interactive        */
  43. /*    help' window)                                                  */
  44. /*                                                                   */
  45. /*  - supplying additional input ('command options') to the          */
  46. /*    application when it is run.                                    */
  47. /*                                                                   */
  48. /*                                                                   */
  49. /*  BootA must be started up by the following command:               */
  50. /*                                                                   */
  51. /*    *RUN BootA  arg1  arg2  arg3  ...  argn                        */
  52. /*                                                                   */
  53. /*  where 'argi' is the name of a client application to be installed */
  54. /*  on the icon bar or specifies a file containing a list of such    */
  55. /*  applications (in which case 'argi' must be specified in the      */
  56. /*  form '-FILE filespec').                                          */
  57. /*                                                                   */
  58. /*-------------------------------------------------------------------*/
  59. /*                                                                   */
  60. /*  COPYRIGHT NOTICE                                                 */
  61. /*                                                                   */
  62. /*  BootA is subject to Copyright.                                   */
  63. /*                                                                   */
  64. /*  Permission is granted by the author to any recipient of this     */
  65. /*  material to use and make/disseminate copies of the application   */
  66. /*  provided that no charges are made for doing so (other than to    */
  67. /*  cover any cost of media or postage) and that this notice is      */
  68. /*  included with all copies.                                        */
  69. /*                                                                   */
  70. /*===================================================================*/
  71.  
  72. #include "kernel.h"                   /* ARC specifics               */
  73. #include "swis.h"                     /* SWI numbers                 */
  74. #include <ctype.h>                    /* Character handling          */
  75. #include <stddef.h>                   /* Standard definitions        */
  76. #include <stdio.h>                    /* Input/output                */
  77. #include <stdlib.h>                   /* General utilities           */
  78. #include <string.h>                   /* String handling             */
  79.  
  80. #include "useful.h"                   /* Useful definitions          */
  81.  
  82. /*-------------------------------------------------------------------*/
  83. /*  Control block definitions                                        */
  84. /*-------------------------------------------------------------------*/
  85.  
  86. struct windowblock                    /* FORMAT OF WINDOW BLOCK      */
  87. {
  88.   int visible_area_minX ;             /* visible area min X coord    */
  89.   int visible_area_minY ;             /* visible area min Y coord    */
  90.   int visible_area_maxX ;             /* visible area max X coord    */
  91.   int visible_area_maxY ;             /* visible area max Y coord    */
  92.   int scroll_X_offset ;               /* scroll X offset             */
  93.   int scroll_Y_offset ;               /* scroll Y offset             */
  94.   int handle_to_open_behind ;         /* window to open behind       */
  95.   int flags ;                         /* flags                       */
  96.   char title_foreground_colour ;      /* title foreground colour     */
  97.   char title_background_colour ;      /* title background colour     */
  98.   char work_area_foreground_colour ;  /* workarea foreground colour  */
  99.   char work_area_background_colour ;  /* workarea background colour  */
  100.   char scroll_bar_outer_colour ;      /* scroll bar outer colour     */
  101.   char scroll_bar_inner_colour ;      /* scroll bar inner colour     */
  102.   char title_highlight_colour ;       /* title highlight background  */
  103.   char reserved1 ;                    /* must be zero                */
  104.   int  workarea_minX ;                /* work area min X coord       */
  105.   int  workarea_minY ;                /* work area min Y coord       */
  106.   int  workarea_maxX ;                /* work area max X coord       */
  107.   int  workarea_maxY ;                /* work area max Y coord       */
  108.   int  title_icon_flags ;             /* title bar icon flags        */
  109.   int  workarea_button_type ;         /* workarea button type        */
  110.   int  sprite_block_ptr ;             /* ptr to sprite c.block       */
  111.   short min_window_width ;            /* minimum window width        */
  112.   short min_window_height ;           /* minimum window height       */
  113.   char title[12] ;                    /* title                       */
  114.   int  nicons ;                       /* number of icons             */
  115. } ;
  116.  
  117. struct iconblock                      /* FORMAT OF ICON BLOCK        */
  118. {
  119.   int minX_bound ;                    /* bounding box mix x-coord    */
  120.   int minY_bound ;                    /* bounding box mix y-coord    */
  121.   int maxX_bound ;                    /* bounding box max x-coord    */
  122.   int maxY_bound ;                    /* bounding box max y-coord    */
  123.   int flags ;                         /* icon flags                  */
  124.   char name[12] ;                     /* sprite name or text         */
  125. } ;
  126.  
  127. struct indiconblock                   /* FORMAT OF ICON BLOCK        */
  128. {
  129.   int minX_bound ;                    /* bounding box mix x-coord    */
  130.   int minY_bound ;                    /* bounding box mix y-coord    */
  131.   int maxX_bound ;                    /* bounding box max x-coord    */
  132.   int maxY_bound ;                    /* bounding box max y-coord    */
  133.   int flags ;                         /* icon flags                  */
  134.   char *bufptr ;                      /* pointer to text buffer      */
  135.   char *vldnptr ;                     /* pointer to validation str   */
  136.   int buflen ;                        /* buffer length               */
  137. } ;
  138.  
  139. struct menublock                      /* FORMAT OF MENU BLOCK        */
  140. {
  141.   char title[12] ;                    /* menu title                  */
  142.   char title_foreground_colour ;      /* title foreground colour     */
  143.   char title_background_colour ;      /* title background colour     */
  144.   char work_area_foreground_colour ;  /* workarea foreground colour  */
  145.   char work_area_background_colour ;  /* workarea background colour  */
  146.   int width ;                         /* menu item width             */
  147.   int height ;                        /* menu item height            */
  148.   int vertical_gap ;                  /* gap between items           */
  149. } ;
  150.  
  151. struct menuitem                       /* FORMAT OF MENU ITEM BLOCK   */
  152. {
  153.   int menu_flags ;                    /* menu flags                  */
  154.   int submenu ;                       /* submenu ptr or window hndl  */
  155.   int icon_flags ;                    /* icon flags                  */
  156.   char icon_data[12] ;                /* icon data (e.g. text)       */
  157. } ;
  158.  
  159. struct clientblk                      /* FORMAT OF APPL QUEUE ENTRY  */
  160. {
  161.   struct clientblk *next ;            /* Pointer to next block       */
  162.   struct clientblk *prev ;            /* Pointer to previous block   */
  163.   int icon_handle ;                   /* Handle of icon              */
  164.   char *helptxt ;                     /* Pointer to help text        */
  165.   char *cmdopts ;                     /* Pointer to command options  */
  166.   char name[12] ;                     /* Application name            */
  167.   char vldtnstr[1] ;                  /* Start of validation string  */
  168.   char sprite[13] ;                   /* Sprite name                 */
  169.   char fullname[1] ;                  /* Full path+leaf for appl     */
  170. } ;
  171.  
  172. /*-------------------------------------------------------------------*/
  173. /*  Global data definitions                                          */
  174. /*-------------------------------------------------------------------*/
  175.  
  176. static int taskid ;                          /* task id              */
  177. static struct clientblk *clientqueue = NULL ;/* application q ptr    */
  178. static struct clientblk *clientptr ;         /* ptr to chosen appl   */
  179. static int block[64] ;                       /* wimp poll block      */
  180. static char cmdoptsbuf[50] ;                 /* work buf for cmdopts */
  181.  
  182. static const char helptxt[] =         /* Default help text           */
  183.  
  184.   "This icon has been installed by BootA. Drag a file or directory"
  185.   " here to process it. Click MENU on !BootA in directory viewer and"
  186.   " select HELP for more detailed information." ;
  187.  
  188. /*-------------------------------------------------------------------*/
  189. /*  Menu definitions                                                 */
  190. /*-------------------------------------------------------------------*/
  191.  
  192. static struct
  193. {
  194.   struct menublock prefix ;           /* Menu has four items         */
  195.   struct menuitem  item0 ;            /*   0. Info                   */
  196.   struct menuitem  item1 ;            /*   1. Help                   */
  197.   struct menuitem  item2 ;            /*   2. CmdOpts                */
  198.   struct menuitem  item3 ;            /*   3. Quit                   */
  199. } menu =
  200. {
  201.   {                               /* ---- MENU PREFIX ----------     */
  202.     "!BootA",                       /* menu title                    */
  203.     7,                              /* title foreground colour       */
  204.     2,                              /* title background colour       */
  205.     7,                              /* workarea foreground colour    */
  206.     0,                              /* workarea background colour    */
  207.     118,                            /* menu item width               */
  208.     44,                             /* menu item height              */
  209.     0                               /* gap between items             */
  210.   },
  211.   {                               /* ----- MENU ITEM 0 ---------     */
  212.     0x00,                           /* menu flags                    */
  213.     -1,                             /* submenu ptr or window hndl    */
  214.     0x07000001,                     /* icon flags                    */
  215.     "Info"                          /* icon data (e.g. text)         */
  216.   },
  217.   {                               /* ----- MENU ITEM 1 ---------     */
  218.     0x00,                           /* menu flags                    */
  219.     -1,                             /* submenu ptr or window hndl    */
  220.     0x07000001,                     /* icon flags                    */
  221.     "Help"                          /* icon data (e.g. text)         */
  222.   },
  223.   {                               /* ----- MENU ITEM 2 ---------     */
  224.     0x00,                           /* menu flags                    */
  225.     -1,                             /* submenu ptr or window hndl    */
  226.     0x07000001,                     /* icon flags                    */
  227.     "CmdOpts"                       /* icon data (e.g. text)         */
  228.   },
  229.   {                               /* ----- MENU ITEM 3 ---------     */
  230.     0x80,                           /* menu flags                    */
  231.     -1,                             /* submenu ptr or window hndl    */
  232.     0x07000001,                     /* icon flags                    */
  233.     "Quit"                          /* icon data (e.g. text)         */
  234.   },
  235. } ;
  236.  
  237. /*-------------------------------------------------------------------*/
  238. /*  Information window definitions                                   */
  239. /*-------------------------------------------------------------------*/
  240.  
  241. #define infolblxmin 16
  242. #define infolblxmax 16+(8*16)+8
  243. #define infotxtxmin 16+(8*16)+8 + 8
  244. #define infotxtxmax 16+(8*16)+8 + 8+8+(30*16)+8
  245. #define infowidth   16+(8*16)+8 + 8+8+(30*16)+8+16
  246. #define infotxtymin 8
  247. #define infotxtymax 56
  248. #define infotxtdpth 56
  249. #define infodepth   8+(4*56)
  250.  
  251. static struct
  252. {
  253.   struct windowblock  window ;       /* base window block            */
  254.   struct iconblock    icon0 ;        /* icon for "Version:"          */
  255.   struct iconblock    icon1 ;        /* icon for "Author:"           */
  256.   struct iconblock    icon2 ;        /* icon for "Purpose:"          */
  257.   struct iconblock    icon3 ;        /* icon for "Name:"             */
  258.   struct indiconblock icon4 ;        /* icon for version text        */
  259.   struct indiconblock icon5 ;        /* icon for author text         */
  260.   struct indiconblock icon6 ;        /* icon for purpose text        */
  261.   struct iconblock    icon7 ;        /* icon for "BootA"             */
  262. } info_window =
  263. {
  264.   {
  265.     0,                               /* visible area min X coord     */
  266.     0,                               /* visible area min Y coord     */
  267.     infowidth,                       /* visible area max X coord     */
  268.     infodepth,                       /* visible area max Y coord     */
  269.     0,                               /* scroll X offset              */
  270.     infodepth,                       /* scroll Y offset              */
  271.     -1,                              /* window to open behind        */
  272.     0x84000012,                      /* flags                        */
  273.     7,                               /* title foreground colour      */
  274.     2,                               /* title background colour      */
  275.     7,                               /* workarea foreground colour   */
  276.     1,                               /* workarea background colour   */
  277.     0,                               /* scroll bar outer colour      */
  278.     0,                               /* scroll bar inner colour      */
  279.     0,                               /* title highlight background   */
  280.     0,                               /* must be zero                 */
  281.     0,                               /* work area min X coord        */
  282.     0,                               /* work area min Y coord        */
  283.     infowidth,                       /* work area max X coord        */
  284.     infodepth,                       /* work area max Y coord        */
  285.     0x00000009,                      /* title bar icon flags         */
  286.     0<<16,                           /* workarea button type         */
  287.     -1,                              /* ptr to sprite c.block        */
  288.     0,                               /* minimum window width         */
  289.     0,                               /* minimum window height        */
  290.     "Information",                   /* title                        */
  291.     8                                /* number of icons              */
  292.   },
  293.   {                                /* --- ICON BLOCK # 0 -------     */
  294.     infolblxmin,                     /* Bounding box min x           */
  295.     infotxtymin+0*infotxtdpth,       /* Bounding box min y           */
  296.     infolblxmax,                     /* Bounding box max x           */
  297.     infotxtymax+0*infotxtdpth,       /* Bounding box max y           */
  298.     0x07000211,                      /* Icon flags                   */
  299.     "Version:"
  300.   },
  301.   {                                /* --- ICON BLOCK # 1 -------     */
  302.     infolblxmin,                     /* Bounding box min x           */
  303.     infotxtymin+1*infotxtdpth,       /* Bounding box min y           */
  304.     infolblxmax,                     /* Bounding box max x           */
  305.     infotxtymax+1*infotxtdpth,       /* Bounding box max y           */
  306.     0x07000211,                      /* Icon flags                   */
  307.     "Author:"
  308.   },
  309.   {                                /* --- ICON BLOCK # 2 -------     */
  310.     infolblxmin,                     /* Bounding box min x           */
  311.     infotxtymin+2*infotxtdpth,       /* Bounding box min y           */
  312.     infolblxmax,                     /* Bounding box max x           */
  313.     infotxtymax+2*infotxtdpth,       /* Bounding box max y           */
  314.     0x07000211,                      /* Icon flags                   */
  315.     "Purpose:"
  316.   },
  317.   {                                /* --- ICON BLOCK # 3 -------     */
  318.     infolblxmin,                     /* Bounding box min x           */
  319.     infotxtymin+3*infotxtdpth,       /* Bounding box min y           */
  320.     infolblxmax,                     /* Bounding box max x           */
  321.     infotxtymax+3*infotxtdpth,       /* Bounding box max y           */
  322.     0x07000211,                      /* Icon flags                   */
  323.     "Name:"
  324.   },
  325.   {                                /* --- ICON BLOCK # 4 -------     */
  326.     infotxtxmin,                     /* Bounding box min x           */
  327.     infotxtymin+0*infotxtdpth,       /* Bounding box min y           */
  328.     infotxtxmax,                     /* Bounding box max x           */
  329.     infotxtymax+0*infotxtdpth,       /* Bounding box max y           */
  330.     0x07000135,                      /* Icon flags                   */
  331.     "2.00 (18th December 1991)",
  332.     (char *)-1,
  333.     1
  334.   },
  335.   {                                /* --- ICON BLOCK # 5 -------     */
  336.     infotxtxmin,                     /* Bounding box min x           */
  337.     infotxtymin+1*infotxtdpth,       /* Bounding box min y           */
  338.     infotxtxmax,                     /* Bounding box max x           */
  339.     infotxtymax+1*infotxtdpth,       /* Bounding box max y           */
  340.     0x07000135,                      /* Icon flags                   */
  341.     "(c) Paul Witheridge",
  342.     (char *)-1,
  343.     1
  344.   },
  345.   {                                /* --- ICON BLOCK # 6 -------     */
  346.     infotxtxmin,                     /* Bounding box min x           */
  347.     infotxtymin+2*infotxtdpth,       /* Bounding box min y           */
  348.     infotxtxmax,                     /* Bounding box max x           */
  349.     infotxtymax+2*infotxtdpth,       /* Bounding box max y           */
  350.     0x07000135,                      /* Icon flags                   */
  351.     "Supports non-WIMP applications",
  352.     (char *)-1,
  353.     1
  354.   },
  355.   {                                /* --- ICON BLOCK # 7 -------     */
  356.     infotxtxmin,                     /* Bounding box min x           */
  357.     infotxtymin+3*infotxtdpth,       /* Bounding box min y           */
  358.     infotxtxmax,                     /* Bounding box max x           */
  359.     infotxtymax+3*infotxtdpth,       /* Bounding box max y           */
  360.     0x07000035,                      /* Icon flags                   */
  361.     "BootA"                          /* Text                         */
  362.   }
  363. } ;
  364.  
  365. /*-------------------------------------------------------------------*/
  366. /*  Help window definitions                                          */
  367. /*-------------------------------------------------------------------*/
  368.  
  369. static struct windowblock help_window =
  370. {                                    /* ---- WINDOW BLOCK BASE ---   */
  371.   0,                                   /* visible area min X coord   */
  372.   0,                                   /* visible area min Y coord   */
  373.   60*16,                               /* visible area max X coord   */
  374.   5*32,                                /* visible area max Y coord   */
  375.   0,                                   /* scroll X offset            */
  376.   5*32,                                /* scroll Y offset            */
  377.   -1,                                  /* window to open behind      */
  378.   0x84000002,                          /* flags                      */
  379.   7,                                   /* title foreground colour    */
  380.   2,                                   /* title background colour    */
  381.   7,                                   /* workarea foreground colour */
  382.   0,                                   /* workarea background colour */
  383.   0,                                   /* scroll bar outer colour    */
  384.   0,                                   /* scroll bar inner colour    */
  385.   9,                                   /* title highlight background */
  386.   0,                                   /* must be zero               */
  387.   0,                                   /* work area min X coord      */
  388.   0,                                   /* work area min Y coord      */
  389.   60*16,                               /* work area max X coord      */
  390.   5*32,                                /* work area max Y coord      */
  391.   0x00000009,                          /* title bar icon flags       */
  392.   0,                                   /* workarea button type       */
  393.   -1,                                  /* ptr to sprite c.block      */
  394.   0,                                   /* minimum window width       */
  395.   0,                                   /* minimum window height      */
  396.   "Help",                              /* title                      */
  397.   0                                    /* no icons                   */
  398. } ;
  399.  
  400. /*-------------------------------------------------------------------*/
  401. /*  Command options window definitions                               */
  402. /*-------------------------------------------------------------------*/
  403.  
  404. static struct
  405. {
  406.   struct windowblock window ;        /* Base window block            */
  407.   struct indiconblock icon0 ;        /* Writeable icon for input     */
  408. } cmdopts_window =
  409. {
  410.   {                                /* ---- WINDOW BLOCK BASE ---     */
  411.     0,                               /* visible area min X coord     */
  412.     0,                               /* visible area min Y coord     */
  413.     38*16,                           /* visible area max X coord     */
  414.     2*32,                            /* visible area max Y coord     */
  415.     0,                               /* scroll X offset              */
  416.     2*32,                            /* scroll Y offset              */
  417.     -1,                              /* window to open behind        */
  418.     0x84000012,                      /* flags                        */
  419.     7,                               /* title foreground colour      */
  420.     2,                               /* title background colour      */
  421.     7,                               /* workarea foreground colour   */
  422.     1,                               /* workarea background colour   */
  423.     0,                               /* scroll bar outer colour      */
  424.     0,                               /* scroll bar inner colour      */
  425.     9,                               /* title highlight background   */
  426.     0,                               /* must be zero                 */
  427.     0,                               /* work area min X coord        */
  428.     0,                               /* work area min Y coord        */
  429.     38*16,                           /* work area max X coord        */
  430.     2*32,                            /* work area max Y coord        */
  431.     0x00000009,                      /* title bar icon flags         */
  432.     0<<16,                           /* workarea button type         */
  433.     -1,                              /* ptr to sprite c.block        */
  434.     0,                               /* minimum window width         */
  435.     0,                               /* minimum window height        */
  436.     "CmdOpts",                       /* title                        */
  437.     1                                /* number of icons              */
  438.   },
  439.   {                                /* --- ICON BLOCK -----------     */
  440.     0,                               /* Bounding box min x           */
  441.     0,                               /* Bounding box min y           */
  442.     38*16,                           /* Bounding box max x           */
  443.     2*32,                            /* Bounding box max y           */
  444.     0x0700F131,                      /* Icon flags                   */
  445.     cmdoptsbuf,                      /* Text buffer pointer          */
  446.     (char *)-1,                      /* Validation string pointer    */
  447.     sizeof(cmdoptsbuf)               /* Text buffer length           */
  448.   }
  449. } ;
  450.  
  451. /*-------------------------------------------------------------------*/
  452. /*  Declare functions local in scope to this file.                   */
  453. /*-------------------------------------------------------------------*/
  454.  
  455. static void initboota(const int argc,const char *const argv[]) ;
  456. static void send(const int actioncode,const char *fullname) ;
  457. static int wimpinit(const char *taskname) ;
  458. static void wimpterm(void) ;
  459. static int wimppoll(const int pollmask) ;
  460. static void wimpredraw(void) ;
  461. static void wimpopen(void) ;
  462. static void mouse(void) ;
  463. static void processkey(void) ;
  464. static void choose(void) ;
  465. static void receive(const enum boolean reply) ;
  466. static void acknowledge(_kernel_swi_regs *regsptr,const enum boolean reply) ;
  467. static void installappl(const char *fullname) ;
  468. static void runappl(const int filetype,const char *fullname) ;
  469. static void removeappl(void) ;
  470. static void help(void) ;
  471. static int createicon(void) ;
  472. static int delicon(const int handle) ;
  473. static char *installtext(const char *leaf,size_t maxlen) ;
  474. static void displaymenu(const int xcoord) ;
  475. static enum boolean adjust(void) ;
  476. static struct clientblk *findclient(const int icon_handle) ;
  477. static void *ualloc(size_t len) ;
  478. static void errormsg(const int errno,const char *errmsg) ;
  479. static enum boolean stricmp(const char *s1, const char *s2) ;
  480. static void strip(char *strptr) ;
  481. static char *gstrans(char * inout) ;
  482. static void setvar(const char *varname,const char *value) ;
  483. static void plot(int type,int x,int y) ;
  484. static void vdu24(int x1,int y1,int x2,int y2) ;
  485. static void vdutwo(int n) ;
  486. static void debug(const int debugid,const char *debugmsg) ;
  487. static void debugwait(void) ;
  488.  
  489. /*===================================================================*/
  490. /*  main program                                                     */
  491. /*===================================================================*/
  492.  
  493. int main(const int argc,const char *const argv[])
  494. {
  495.   initboota(argc,argv) ;
  496.  
  497.   do
  498.   {
  499.     switch ( wimppoll(0x00081831) )
  500.     {
  501.       case 1 :
  502.         wimpredraw() ;
  503.         break ;
  504.       case 2 :
  505.         wimpopen() ;
  506.         break ;
  507.       case 6 :
  508.         mouse() ;
  509.         break ;
  510.       case 8 :
  511.         processkey() ;
  512.         break ;
  513.       case 9 :
  514.         choose() ;
  515.         break ;
  516.       case 17 :
  517.         receive(FALSE) ;
  518.         break ;
  519.       case 18 :
  520.         receive(TRUE) ;
  521.         break ;
  522.     }
  523.   } FOREVER ;
  524. }
  525.  
  526. /*===================================================================*/
  527. /*  InitBootA  -  initialise BootA application itself                */
  528. /*===================================================================*/
  529.  
  530. static void initboota(const int argc,const char *const argv[])
  531. {
  532.   _kernel_swi_regs regs ;
  533.   int pollresponse ;
  534.   int i ;
  535.   int len ;
  536.   int c ;
  537.   int file_handle ;
  538.   char workbuf[120] ;
  539.  
  540.   taskid = wimpinit("BootA") ;
  541.  
  542.   send(0x211170,"BootA starting") ;
  543.   pollresponse = wimppoll(0x00061970) ;
  544.  
  545.   if ( pollresponse == 19 )
  546.   {
  547.     regs.r[1] = (int)&info_window ;
  548.     _kernel_swi(Wimp_CreateWindow,®s,®s) ;
  549.     menu.item0.submenu = regs.r[0] ;
  550.     regs.r[1] = (int)&help_window ;
  551.     _kernel_swi(Wimp_CreateWindow,®s,®s) ;
  552.     menu.item1.submenu = regs.r[0] ;
  553.     regs.r[1] = (int)&cmdopts_window ;
  554.     _kernel_swi(Wimp_CreateWindow,®s,®s) ;
  555.     menu.item2.submenu = regs.r[0] ;
  556.   }
  557.  
  558.   for ( i = 1 ; i < argc ; i++ )
  559.   {
  560.     if ( stricmp(argv[i],"-FILE") )
  561.     {
  562.       i++ ;
  563.       if ( i < argc )
  564.       {
  565.         if ( (file_handle = _kernel_osfind(0x40,(char *)argv[i])) == 0 )
  566.         {
  567.           sprintf(workbuf,"Cannot open '%.50s'",argv[i]) ;
  568.           errormsg(99,workbuf) ;
  569.         }
  570.         else
  571.         {
  572.           do
  573.           {
  574.             for ( len = 0 ; len < sizeof(workbuf)-1 ; len++ )
  575.             {
  576.               if ( (c = _kernel_osbget(file_handle)) == EOF ||
  577.                    c < 0x20 )
  578.               {
  579.                 break ;
  580.               }
  581.               workbuf[len] = c ;
  582.             }
  583.             workbuf[len] = '\0' ;
  584.             if ( len != 0 && workbuf[0] != '|' )
  585.             {
  586.               gstrans(workbuf) ;
  587.               strip(workbuf) ;
  588.               if ( pollresponse == 19 )
  589.               {
  590.                 installappl(workbuf) ;
  591.               }
  592.               else
  593.               {
  594.                 send(0x211171,workbuf) ;
  595.               }
  596.             }
  597.           } while ( c != EOF ) ;
  598.           _kernel_osfind(0x00,(char *)file_handle) ;
  599.         }
  600.       }
  601.     }
  602.     else
  603.     {
  604.       strcpy(workbuf,argv[i]) ;
  605.       gstrans(workbuf) ;
  606.       strip(workbuf) ;
  607.       if ( pollresponse == 19 )
  608.       {
  609.         installappl(workbuf) ;
  610.       }
  611.       else
  612.       {
  613.         send(0x211171,workbuf) ;
  614.       }
  615.     }
  616.   }
  617.   if ( clientqueue == NULL )
  618.   {
  619.     wimpterm() ;
  620.   }
  621. }
  622.  
  623. /*===================================================================*/
  624. /*  Send  -  send message requesting application installation        */
  625. /*===================================================================*/
  626.  
  627. static void send(const int actioncode,const char *fullname)
  628. {
  629.   _kernel_swi_regs regs ;
  630.  
  631.   block[0] = (strlen(fullname)+1+20+3) & 0xFC ;
  632.   block[3] = 0 ;
  633.   block[4] = actioncode ;
  634.   strcpy((char *)&block[5],fullname) ;
  635.   regs.r[0] = 18 ;
  636.   regs.r[1] = (int)block ;
  637.   regs.r[2] = 0 ;
  638.   _kernel_swi(Wimp_SendMessage,®s,®s) ;
  639. }
  640.  
  641. /*===================================================================*/
  642. /*  WimpInit  -  connect task to Window Manager                      */
  643. /*===================================================================*/
  644.  
  645. static int wimpinit(const char *taskname)
  646. {
  647.   _kernel_swi_regs regs ;
  648.  
  649.   regs.r[0] = 200 ;
  650.   regs.r[1] = 0x4B534154 ;
  651.   regs.r[2] = (int)taskname ;
  652.   _kernel_swi(Wimp_Initialise,®s,®s) ;
  653.   return regs.r[1] ;
  654. }
  655.  
  656. /*===================================================================*/
  657. /*  WimpTerm  -  disconnect task from Window Manager & exit          */
  658. /*===================================================================*/
  659.  
  660. static void wimpterm(void)
  661. {
  662.   _kernel_swi_regs regs ;
  663.  
  664.    regs.r[0] = taskid ;
  665.    regs.r[1] = 0x4B534154 ;
  666.   _kernel_swi(Wimp_CloseDown,®s,®s) ;
  667.   exit(0) ;
  668. }
  669.  
  670. /*===================================================================*/
  671. /*  WimpPoll  -  poll wimp for events                                */
  672. /*===================================================================*/
  673.  
  674. static int wimppoll(const int pollmask)
  675. {
  676.   _kernel_swi_regs regs ;
  677.  
  678.   regs.r[0] = pollmask ;
  679.   regs.r[1] = (int)block ;
  680.   _kernel_swi(Wimp_Poll,®s,®s) ;
  681.   return regs.r[0] ;
  682. }
  683.  
  684. /*===================================================================*/
  685. /*  WimpRedraw - redraw window                                       */
  686. /*===================================================================*/
  687.  
  688. static void wimpredraw(void)
  689. {
  690.   _kernel_swi_regs regs ;
  691.   int xorg,yorg ;
  692.  
  693.   regs.r[1] = (int)block ;
  694.   _kernel_swi(Wimp_RedrawWindow,®s,®s) ;
  695.   while ( regs.r[0] != 0 )
  696.   {
  697.     vdu24(xorg=block[7]+8,block[8]+16,block[9]-8,yorg=block[10]-16) ;
  698.     plot(4,xorg,yorg) ;
  699.     if ( clientptr != NULL && clientptr->helptxt != NULL )
  700.     {
  701.       regs.r[0] = (int)(clientptr->helptxt) ;
  702.     }
  703.     else
  704.     {
  705.       regs.r[0] = (int)helptxt ;
  706.     }
  707.     regs.r[1] = regs.r[2] = 0 ;
  708.     _kernel_swi(OS_PrettyPrint,®s,®s) ;
  709.     regs.r[1] = (int)block ;
  710.     _kernel_swi(Wimp_GetRectangle,®s,®s) ;
  711.   }
  712. }
  713.  
  714. /*===================================================================*/
  715. /*  WimpOpen  -  open window                                         */
  716. /*===================================================================*/
  717.  
  718. static void wimpopen(void)
  719. {
  720.   _kernel_swi_regs regs ;
  721.  
  722.   regs.r[1] = (int)block ;
  723.   _kernel_swi(Wimp_OpenWindow,®s,®s) ;
  724. }
  725.  
  726. /*===================================================================*/
  727. /*  Mouse  -  handle mouse click on icon                             */
  728. /*===================================================================*/
  729.  
  730. static void mouse(void)
  731. {
  732.   if ( block[3] != -2 || (clientptr = findclient(block[4])) == NULL )
  733.   {
  734.     return ;
  735.   }
  736.   if ( block[2] & 0x02 )
  737.   {
  738.     displaymenu(block[0]) ;
  739.   }
  740.   else if ( block[2] & 0x05 )
  741.   {
  742.     runappl(-1,"") ;
  743.     if ( block[2] & 0x01 )
  744.     {
  745.       removeappl() ;
  746.     }
  747.   }
  748. }
  749.  
  750. /*===================================================================*/
  751. /*  processkey  -  process key press                                 */
  752. /*===================================================================*/
  753.  
  754. static void processkey(void)
  755. {
  756.   _kernel_swi_regs regs ;
  757.  
  758.   if ( block[6] == '\r' && clientptr != NULL )
  759.   {
  760.     strip(cmdoptsbuf) ;
  761.     free(clientptr->cmdopts) ;
  762.     clientptr->cmdopts = NULL ;
  763.     if ( cmdoptsbuf[0] != '\0' )
  764.     {
  765.       strcpy((clientptr->cmdopts = ualloc(strlen(cmdoptsbuf)+1)),
  766.             cmdoptsbuf) ;
  767.     }
  768.     clientptr = NULL ;
  769.     regs.r[1] = -1 ;
  770.     _kernel_swi(Wimp_CreateMenu,®s,®s) ;
  771.   }
  772.   else
  773.   {
  774.     regs.r[0] = block[6] ;
  775.     _kernel_swi(Wimp_ProcessKey,®s,®s) ;
  776.   }
  777. }
  778.  
  779. /*===================================================================*/
  780. /*  choose - handle selection from menu                              */
  781. /*===================================================================*/
  782.  
  783. static void choose(void)
  784. {
  785.   if ( block[0] == 3 )
  786.   {
  787.     removeappl() ;
  788.   }
  789.   else
  790.   {
  791.     if ( adjust() )
  792.    {
  793.      displaymenu(0) ;
  794.    }
  795.   }
  796. }
  797.  
  798. /*===================================================================*/
  799. /*  receive  - process incoming message                              */
  800. /*===================================================================*/
  801.  
  802. static void receive(const enum boolean reply)
  803. {
  804.   _kernel_swi_regs regs ;
  805.  
  806.   switch ( block[4] )
  807.   {
  808.     case 0 :
  809.       wimpterm() ;
  810.       break ;
  811.  
  812.     case 3 :
  813.       if ( (clientptr = findclient(block[6])) != NULL )
  814.       {
  815.         block[3] = block[2] ;
  816.         block[4]  = 4 ;
  817.         regs.r[0] = 17 ;
  818.         regs.r[1] = (int)block ;
  819.         regs.r[2] = block[1] ;
  820.         _kernel_swi(Wimp_SendMessage,®s,®s) ;
  821.         runappl(block[10],(char *)&block[11]) ;
  822.       }
  823.       break ;
  824.  
  825.     case 0x502 :
  826.       help() ;
  827.       break ;
  828.  
  829.     case 0x211170 :
  830.       acknowledge(®s,reply) ;
  831.       break ;
  832.  
  833.     case 0x211171 :
  834.       acknowledge(®s,reply) ;
  835.       installappl((char*)&block[5]) ;
  836.       break ;
  837.  
  838.     case 0x211172 :
  839.       if ( (clientptr = findclient(block[5])) != NULL )
  840.       {
  841.         strncpy(clientptr->sprite,(char*)&block[6],
  842.                 sizeof(clientptr->sprite)-1) ;
  843.         clientptr->sprite[sizeof(clientptr->sprite)-1] = '\0' ;
  844.         acknowledge(®s,reply) ;
  845.         block[0] = -2 ;
  846.         block[1] = clientptr->icon_handle ;
  847.         regs.r[1] = (int)&block[0] ;
  848.         _kernel_swi(Wimp_GetIconState,®s,®s) ;
  849.         regs.r[0] = -2 ;
  850.         regs.r[1] = block[2] ;         /* Add 32 units to upper y     */
  851.         regs.r[2] = block[3] ;         /* coord to make it work with  */
  852.         regs.r[3] = block[4] ;         /* RISC OS 2. RISC OS 3 is OK. */
  853.         regs.r[4] = block[5] + 32 ;
  854.         _kernel_swi(Wimp_ForceRedraw,®s,®s) ;
  855.       }
  856.       break ;
  857.  
  858.     case 0x211173 :
  859.       if ( (clientptr = findclient(block[5])) != NULL )
  860.       {
  861.         acknowledge(®s,reply) ;
  862.         removeappl() ;
  863.       }
  864.       break ;
  865.   }
  866. }
  867.  
  868. /*===================================================================*/
  869. /*  acknowledge -  return confirmation to type 18 wimp message       */
  870. /*===================================================================*/
  871.  
  872. static void acknowledge(_kernel_swi_regs *regsptr,const enum boolean reply)
  873. {
  874.   if ( reply )
  875.   {
  876.     block[3] = block[2] ;
  877.     regsptr->r[0] = 19 ;
  878.     regsptr->r[1] = (int)block ;
  879.     regsptr->r[2] = block[1] ;
  880.     _kernel_swi(Wimp_SendMessage,regsptr,regsptr) ;
  881.   }
  882. }
  883.  
  884. /*===================================================================*/
  885. /*  installappl - install application on icon bar                    */
  886. /*===================================================================*/
  887.  
  888. static void installappl(const char *fullname)
  889. {
  890.   _kernel_osfile_block osfileblk ;
  891.   _kernel_oserror *errptr ;
  892.   int result ;
  893.   const char *p ;
  894.   char msg[120] ;
  895.  
  896.   if ( (p = strrchr(fullname,'.')) == NULL )
  897.   {
  898.     p = fullname - 1 ;
  899.   }
  900.   p++ ;
  901.  
  902.   if ( (result =_kernel_osfile(17,fullname,&osfileblk)) == _kernel_ERROR )
  903.   {
  904.     errptr = _kernel_last_oserror() ;
  905.     sprintf(msg,"'%.50s' - %.50s",fullname,errptr->errmess) ;
  906.     errormsg(errptr->errnum,msg) ;
  907.     return ;
  908.   }
  909.  
  910.   if ( result == 0 )
  911.   {
  912.     sprintf(msg,"'%.50s' - not found",fullname) ;
  913.     errormsg(99,msg) ;
  914.     return ;
  915.   }
  916.  
  917.   if ( result != 2 || *p != '!' )
  918.   {
  919.     sprintf(msg,"'%.50s' - not application",fullname) ;
  920.     errormsg(99,msg) ;
  921.     return ;
  922.   }
  923.  
  924.   clientptr = ualloc(sizeof(*clientptr)+strlen(fullname)) ;
  925.  
  926.   strncpy(clientptr->name,p,sizeof(clientptr->name)) ;
  927.   strncpy(clientptr->sprite,p,sizeof(clientptr->sprite)) ;
  928.   strcpy(clientptr->fullname,fullname) ;
  929.  
  930.   if ( (clientptr->icon_handle = createicon()) != -1 )
  931.   {
  932.     clientptr->prev = NULL ;
  933.     clientptr->next = clientqueue ;
  934.     if ( clientqueue != NULL )
  935.     {
  936.       clientqueue->prev = clientptr ;
  937.     }
  938.     clientqueue = clientptr ;
  939.     clientptr->helptxt = installtext("!HelpMsg",231) ;
  940.     clientptr->cmdopts = installtext("!CmdOpts",50) ;
  941.   }
  942.   else
  943.   {
  944.     free(clientptr) ;
  945.   }
  946.   clientptr = NULL ;
  947. }
  948.  
  949. /*===================================================================*/
  950. /*  runappl  -  run application                                      */
  951. /*===================================================================*/
  952.  
  953. static void runappl(const int filetype,const char *fullname)
  954. {
  955.   char *optsptr ;
  956.   char *workbuf ;
  957.   char *p ;
  958.   const char *object ;
  959.   const char *type ;
  960.   const char *dirptr ;
  961.   const char *leafptr ;
  962.   _kernel_swi_regs regs ;
  963.  
  964.   if ( (optsptr = clientptr->cmdopts) == NULL )
  965.   {
  966.     optsptr = "" ;
  967.   }
  968.  
  969.   workbuf = ualloc(strlen(clientptr->fullname) +
  970.         strlen(fullname) + strlen(optsptr) + 13) ;
  971.  
  972.   switch ( filetype )
  973.   {
  974.     case 0x2000 :
  975.  
  976.       object = "APPL" ;
  977.       type   = "DIR" ;
  978.       dirptr = fullname ;
  979.       leafptr = "" ;
  980.       break ;
  981.  
  982.     case 0x1000 :
  983.  
  984.       type = object = "DIR" ;
  985.       dirptr = fullname ;
  986.       leafptr = "" ;
  987.       break ;
  988.  
  989.     case -1 :
  990.  
  991.       type = object = "NONE" ;
  992.       dirptr = "@" ;
  993.       leafptr = "" ;
  994.       break ;
  995.  
  996.     default :
  997.  
  998.       object = "FILE" ;
  999.       strcpy(workbuf,fullname) ;
  1000.       if ( (p = strrchr(workbuf,'.')) == NULL )
  1001.       {
  1002.         dirptr = "@" ;
  1003.         leafptr = fullname ;
  1004.       }
  1005.       else
  1006.       {
  1007.         *p = '\0' ;
  1008.         dirptr = workbuf ;
  1009.         leafptr = p + 1 ;
  1010.       }
  1011.       regs.r[0] = 18 ;
  1012.       regs.r[2] = filetype ;
  1013.       _kernel_swi(OS_FSControl,®s,®s) ;
  1014.       regs.r[4] = 0 ;
  1015.       strip((char *)&(regs.r[2])) ;
  1016.       type = (char *)&(regs.r[2]) ;
  1017.   }
  1018.  
  1019.   setvar("BootA$Object",object) ;
  1020.   setvar("BootA$Dir",dirptr) ;
  1021.   setvar("BootA$Type",type) ;
  1022.   setvar("BootA$leaf",leafptr) ;
  1023.   setvar("BootA$CmdOpts",optsptr) ;
  1024.   sprintf(workbuf,"%i",clientptr->icon_handle) ;
  1025.   setvar("BootA$Handle",workbuf) ;
  1026.  
  1027.   sprintf(workbuf,"Run %s.!RunA %s %s",
  1028.         clientptr->fullname,fullname,optsptr) ;
  1029.   regs.r[0] = (int)workbuf ;
  1030.   _kernel_swi(Wimp_StartTask,®s,®s) ;
  1031.  
  1032.   free(workbuf) ;
  1033. }
  1034.  
  1035. /*===================================================================*/
  1036. /*  removeappl  -  remove application from icon bar                  */
  1037. /*===================================================================*/
  1038.  
  1039. static void removeappl(void)
  1040. {
  1041.   if ( clientptr == NULL )
  1042.   {
  1043.     return ;
  1044.   }
  1045.  
  1046.   delicon(clientptr->icon_handle) ;
  1047.  
  1048.   free(clientptr->helptxt) ;
  1049.   free(clientptr->cmdopts) ;
  1050.  
  1051.   if ( clientptr->prev == NULL )
  1052.   {
  1053.     clientqueue = clientptr->next ;
  1054.   }
  1055.   else
  1056.   {
  1057.     clientptr->prev->next = clientptr->next ;
  1058.   }
  1059.  
  1060.   if ( clientptr->next != NULL )
  1061.   {
  1062.     clientptr->next->prev = clientptr->prev ;
  1063.   }
  1064.  
  1065.   free(clientptr) ;
  1066.  
  1067.   clientptr = NULL ;
  1068.  
  1069.   if ( clientqueue == NULL )
  1070.   {
  1071.     wimpterm() ;
  1072.   }
  1073. }
  1074.  
  1075. /*===================================================================*/
  1076. /*  help  -  respond to message from !info                           */
  1077. /*===================================================================*/
  1078.  
  1079. static void help(void)
  1080. {
  1081.   _kernel_swi_regs regs ;
  1082.   struct clientblk *clientptr ;
  1083.  
  1084.   if ( block[8] != -2 )
  1085.   {
  1086.     return ;
  1087.   }
  1088.   block[3] = block[2] ;
  1089.   block[4] = 0x503 ;
  1090.   strcpy((char *)&block[5],
  1091.         (clientptr = findclient(block[9])) != NULL &&
  1092.         clientptr->helptxt != NULL ?
  1093.         (const char *)(clientptr->helptxt) : helptxt) ;
  1094.   block[0] = (strlen((char *)&block[5]) + 24) & 0xFC ;
  1095.   regs.r[0] = 17 ;
  1096.   regs.r[1] = (int)block ;
  1097.   regs.r[2] = block[1] ;
  1098.   _kernel_swi(Wimp_SendMessage,®s,®s) ;
  1099. }
  1100.  
  1101. /*===================================================================*/
  1102. /*  createicon  -  create icon on icon bar                           */
  1103. /*===================================================================*/
  1104.  
  1105. static int createicon(void)
  1106. {
  1107.   struct
  1108.   {
  1109.     int window_handle ;
  1110.     struct indiconblock indirect ;
  1111.   } pblock ;
  1112.   _kernel_swi_regs regs ;
  1113.   int mode, width, height, len ;
  1114.   char *command ;
  1115.  
  1116.   pblock.window_handle    = -1 ;
  1117.   pblock.indirect.flags   = 0x1700310A ;
  1118.   pblock.indirect.bufptr  = clientptr->sprite ;
  1119.   pblock.indirect.vldnptr = (char *)1 ;
  1120.   pblock.indirect.buflen  = 1 ;
  1121.  
  1122.   regs.r[0] = 40 ;
  1123.   regs.r[2] = (int)clientptr->sprite ;
  1124.   if ( _kernel_swi(Wimp_SpriteOp,®s,®s) != NULL )
  1125.   {
  1126.     command = ualloc(strlen(clientptr->fullname)+24) ;
  1127.     sprintf(command,"Run %s.!Boot",clientptr->fullname) ;
  1128.     if ( _kernel_system(command,0) == _kernel_ERROR )
  1129.     {
  1130.       sprintf(command,"IconSprites %s.!Sprites",clientptr->fullname) ;
  1131.       _kernel_oscli(command) ;
  1132.     }
  1133.     free(command) ;
  1134.     regs.r[0] = 40 ;
  1135.     regs.r[2] = (int)clientptr->sprite ;
  1136.     if ( _kernel_swi(Wimp_SpriteOp,®s,®s) != NULL )
  1137.     {
  1138.       pblock.indirect.flags   = 0x1700310B ;
  1139.       pblock.indirect.bufptr  = clientptr->name ;
  1140.       pblock.indirect.vldnptr = clientptr->vldtnstr ;
  1141.       strncpy(clientptr->vldtnstr,"Sapplication",
  1142.             sizeof(clientptr->vldtnstr) + sizeof(clientptr->sprite)) ;
  1143.       regs.r[0] = 40 ;
  1144.       regs.r[2] = (int)clientptr->sprite ;
  1145.       if ( _kernel_swi(Wimp_SpriteOp,®s,®s) != NULL )
  1146.       {
  1147.         errormsg(99,"Sprite 'application' not found") ;
  1148.         clientptr->icon_handle = -1 ;
  1149.         return -1 ;
  1150.       }
  1151.     }
  1152.   }
  1153.   width  = regs.r[3] ;
  1154.   height = regs.r[4] ;
  1155.   mode   = regs.r[6] ;
  1156.  
  1157.   regs.r[0] = mode ;
  1158.   regs.r[1] = 4 ;
  1159.   _kernel_swi(OS_ReadModeVariable,®s,®s) ;
  1160.   width <<= regs.r[2] ;
  1161.  
  1162.   regs.r[0] = mode ;
  1163.   regs.r[1] = 5 ;
  1164.   _kernel_swi(OS_ReadModeVariable,®s,®s) ;
  1165.   height <<= regs.r[2] ;
  1166.  
  1167.   pblock.indirect.minX_bound = 0 ;
  1168.   pblock.indirect.maxX_bound = width ;
  1169.  
  1170.   if ( pblock.indirect.flags & 1 )
  1171.   {
  1172.     if ( width < (len = (strlen(clientptr->name) * 16)) )
  1173.     {
  1174.       pblock.indirect.maxX_bound = len ;
  1175.     }
  1176.     pblock.indirect.minY_bound = -16 ;
  1177.     pblock.indirect.maxY_bound = 20 + height ;
  1178.   }
  1179.   else
  1180.   {
  1181.     pblock.indirect.minY_bound = 0 ;
  1182.     pblock.indirect.maxY_bound = height ;
  1183.   }
  1184.   regs.r[1] = (int)&pblock ;
  1185.   _kernel_swi(Wimp_CreateIcon,®s,®s) ;
  1186.   return regs.r[0] ;
  1187. }
  1188.  
  1189. /*===================================================================*/
  1190. /*  delicon - delete icon from icon bar                              */
  1191. /*===================================================================*/
  1192.  
  1193. static int delicon(const int handle)
  1194. {
  1195.   struct
  1196.   {
  1197.     int window_handle ;
  1198.     int icon_handle ;
  1199.   } delicon_block ;
  1200.   _kernel_swi_regs regs ;
  1201.  
  1202.   delicon_block.window_handle = -2 ;
  1203.   delicon_block.icon_handle   = handle ;
  1204.   regs.r[1] = (int)&delicon_block ;
  1205.   _kernel_swi(Wimp_DeleteIcon,®s,®s) ;
  1206.   return -1 ;
  1207. }
  1208.  
  1209. /*===================================================================*/
  1210. /*  InstallText  -  install help/cmdopts text for application        */
  1211. /*===================================================================*/
  1212.  
  1213. static char *installtext(const char *leaf,size_t maxlen)
  1214. {
  1215.   int file_handle ;
  1216.   unsigned i ;
  1217.   int c ;
  1218.   char textarea[256] ;
  1219.  
  1220.   sprintf(textarea,"%s.%s",clientptr->fullname,leaf) ;
  1221.   if ( (file_handle = _kernel_osfind(0x40,textarea)) == 0 )
  1222.   {
  1223.     return NULL ;
  1224.   }
  1225.  
  1226.   i = 0 ;
  1227.   maxlen-- ;
  1228.   while ( (c = _kernel_osbget(file_handle)) != EOF )
  1229.   {
  1230.     if ( i == maxlen )
  1231.     {
  1232.       break ;
  1233.     }
  1234.     textarea[i++] = c ;
  1235.   }
  1236.   textarea[i] = '\0' ;
  1237.  
  1238.   _kernel_osfind(0x00,(char *)file_handle) ;
  1239.  
  1240.   return strcpy(ualloc(i+1),textarea) ;
  1241. }
  1242.  
  1243. /*===================================================================*/
  1244. /*  displaymenu  -  display menu                                     */
  1245. /*===================================================================*/
  1246.  
  1247. static void displaymenu(const int xcoord)
  1248. {
  1249.   _kernel_swi_regs regs ;
  1250.  
  1251.   cmdoptsbuf[0] = '\0' ;
  1252.   if ( clientptr->cmdopts != NULL )
  1253.   {
  1254.     strcpy(cmdoptsbuf,clientptr->cmdopts) ;
  1255.   }
  1256.   regs.r[1] = (int)&menu ;
  1257.   regs.r[2] = xcoord - 64 ;
  1258.   regs.r[3] = 96 + 4 * 44 + 44 ;
  1259.  _kernel_swi(Wimp_CreateMenu,®s,®s) ;
  1260. }
  1261.  
  1262. /*===================================================================*/
  1263. /*  adjust  -  check if adjust button pressed                        */
  1264. /*===================================================================*/
  1265.  
  1266. static enum boolean adjust(void)
  1267. {
  1268.   _kernel_swi_regs regs ;
  1269.   regs.r[1] = (int)block ;
  1270.   _kernel_swi(Wimp_GetPointerInfo,®s,®s) ;
  1271.   return (block[2] & 0x01) ? TRUE : FALSE ;
  1272. }
  1273.  
  1274. /*===================================================================*/
  1275. /*  findclient  -  find control block for client application         */
  1276. /*===================================================================*/
  1277.  
  1278. static struct clientblk *findclient(const int icon_handle)
  1279. {
  1280.   struct clientblk *clientptr ;
  1281.  
  1282.   for ( clientptr = clientqueue ;
  1283.         clientptr != NULL ;
  1284.         clientptr = clientptr->next )
  1285.   {
  1286.     if ( icon_handle == clientptr->icon_handle )
  1287.     {
  1288.       return clientptr ;
  1289.     }
  1290.   }
  1291.   return NULL ;
  1292. }
  1293.  
  1294. /*===================================================================*/
  1295. /*  ualloc  -  unconditional memory allocation                       */
  1296. /*===================================================================*/
  1297.  
  1298. static void *ualloc(size_t len)
  1299. {
  1300.   void *ptr ;
  1301.  
  1302.   if ( (ptr = malloc(len)) == NULL )
  1303.   {
  1304.     errormsg(0,"Out of memory") ;
  1305.     wimpterm() ;
  1306.   }
  1307.   return ptr ;
  1308. }
  1309.  
  1310. /*===================================================================*/
  1311. /*  errormsg  -  issue error message                                 */
  1312. /*===================================================================*/
  1313.  
  1314. static void errormsg(const int errno,const char *errmsg)
  1315. {
  1316.   struct
  1317.   {
  1318.     int errno ;
  1319.     char errmsg[120] ;
  1320.   } errblk ;
  1321.   _kernel_swi_regs regs ;
  1322.  
  1323.   errblk.errno = errno ;
  1324.   strcpy(errblk.errmsg,errmsg) ;
  1325.   regs.r[0] = (int)&errblk ;
  1326.   regs.r[1] = 0x00000001 ;
  1327.   regs.r[2] = (int)"BootA" ;
  1328.   _kernel_swi(Wimp_ReportError,®s,®s) ;
  1329. }
  1330.  
  1331. /*===================================================================*/
  1332. /*  stricmp  -  upper case compare                                   */
  1333. /*===================================================================*/
  1334.  
  1335. static enum boolean stricmp(const char *s1, const char *s2)
  1336. {
  1337.   int i ;
  1338.  
  1339.   for ( i = 0 ; s1[i] != '\0' ; i++ )
  1340.   {
  1341.     if ( toupper(s1[i]) != toupper(s2[i]) )
  1342.     {
  1343.       return FALSE ;
  1344.     }
  1345.   }
  1346.   if ( s2[i] != '\0' )
  1347.   {
  1348.     return FALSE ;
  1349.   }
  1350.   return TRUE ;
  1351. }
  1352.  
  1353. /*===================================================================*/
  1354. /*  strip  -  strip leading and trailing blanks from string          */
  1355. /*===================================================================*/
  1356.  
  1357. static void strip(char *strptr)
  1358. {
  1359.   int i,j ;
  1360.  
  1361.   for ( i = 0, j = strspn(strptr," " ) ;
  1362.       (strptr[i] = strptr[j]) != '\0' ;
  1363.       i++, j++) ;
  1364.  
  1365.   do
  1366.   {
  1367.     i-- ;
  1368.     if ( i < 0 )
  1369.     {
  1370.       break ;
  1371.     }
  1372.   } while ( strptr[i] == ' ' ) ;
  1373.  
  1374.   strptr[i+1] = '\0' ;
  1375. }
  1376.  
  1377. /*===================================================================*/
  1378. /*  gstrans  -  perform system variable substitution etc             */
  1379. /*===================================================================*/
  1380.  
  1381. static char *gstrans(char *inout)
  1382. {
  1383.   _kernel_swi_regs regs ;
  1384.   char workbuf[120] ;
  1385.  
  1386.   regs.r[0] = (int)inout ;
  1387.   regs.r[1] = (int)workbuf ;
  1388.   regs.r[2] = sizeof(workbuf)-1 ;
  1389.   _kernel_swi(OS_GSTrans,®s,®s) ;
  1390.   workbuf[regs.r[2]] = '\0' ;
  1391.   strcpy(inout,workbuf) ;
  1392.   return inout ;
  1393. }
  1394.  
  1395. /*===================================================================*/
  1396. /*  setvar  -  set system variable value                             */
  1397. /*===================================================================*/
  1398.  
  1399. static void setvar(const char *varname,const char *value)
  1400. {
  1401.   _kernel_swi_regs regs ;
  1402.  
  1403.   regs.r[0] = (int)varname ;
  1404.   regs.r[1] = ( value == NULL ) ? (int)"" : (int)value ;
  1405.   regs.r[2] = regs.r[3] = regs.r[4] = 0 ;
  1406.   _kernel_swi(OS_SetVarVal,®s,®s) ;
  1407. }
  1408.  
  1409. /*===================================================================*/
  1410. /*  Plot -  move/draw/plot function                                  */
  1411. /*===================================================================*/
  1412.  
  1413. static void plot(int type,int x,int y)
  1414. {
  1415.   _kernel_swi_regs regs ;
  1416.   regs.r[0] = type ;
  1417.   regs.r[1] = x ;
  1418.   regs.r[2] = y ;
  1419.   _kernel_swi(OS_Plot,®s,®s) ;
  1420. }
  1421.  
  1422. /*===================================================================*/
  1423. /*  vdu24 - set graphics window                                      */
  1424. /*===================================================================*/
  1425.  
  1426. static void vdu24(int x1,int y1,int x2,int y2)
  1427. {
  1428.   _kernel_oswrch(24) ;
  1429.   vdutwo(x1) ;
  1430.   vdutwo(y1) ;
  1431.   vdutwo(x2) ;
  1432.   vdutwo(y2) ;
  1433. }
  1434.  
  1435. /*===================================================================*/
  1436. /*  vdutwo - write two byte value to oswrch                          */
  1437. /*===================================================================*/
  1438.  
  1439. static void vdutwo(int n)
  1440. {
  1441.   _kernel_oswrch(n) ;
  1442.   _kernel_oswrch(n >> 8) ;
  1443. }
  1444.  
  1445. /*===================================================================*/
  1446. /*  debug                                                            */
  1447. /*===================================================================*/
  1448.  
  1449. static void debug(const int debugid,const char *debugmsg)
  1450. {
  1451.   _kernel_oswrch(4) ;
  1452.   printf("%d ===> %s\n",debugid,debugmsg) ;
  1453.   _kernel_oswrch(5) ;
  1454. }
  1455.  
  1456. /*===================================================================*/
  1457. /*  debugwait                                                        */
  1458. /*===================================================================*/
  1459.  
  1460. static void debugwait(void)
  1461. {
  1462.   do
  1463.   {
  1464.   } while ( (_kernel_osbyte(129,-1,-1) & 0xffff) == 0 ) ;
  1465.   do
  1466.   {
  1467.   } while ( (_kernel_osbyte(129,-1,-1) & 0xffff) != 0 ) ;
  1468. }
  1469.  
  1470. /*===================================================================*/
  1471.