home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-12-18 | 51.9 KB | 1,471 lines |
- /* > c.BootA - (c) Paul Witheridge - Version 2.00 - 18 December 1991 */
-
- /*===================================================================*/
- /* */
- /* BootA - boots up non-resident applications */
- /* ----- */
- /* */
- /* BootA is a Risc-OS Wimp-based application which is designed to */
- /* make it easy to set up Risc-OS style application directories for */
- /* running non Wimp-based applications and utilities which would */
- /* otherwise have to be started by command outside the Desktop */
- /* environment or from within an !Edit task window (or at the very */
- /* least by pressing f12 in the Desktop in order to enter the */
- /* command). */
- /* */
- /* These 'pseudo-applications' are refered to as 'client */
- /* applications' to emphasise that they rely on BootA to do many of */
- /* the things for them that a real Risc-OS application does for */
- /* itself. */
- /* */
- /* BootA provides the following services for its client */
- /* applications: */
- /* */
- /* - installing the client application's icon on the icon bar */
- /* when the user double-clicks the mouse select (or adjust) */
- /* buttons on the corresponding icon in a directory viewer */
- /* window */
- /* */
- /* - displaying a menu with a 'quit' option when the mouse 'menu' */
- /* button is clicked on the installed icon and removing it from */
- /* the icon bar if this 'quit' option is selected */
- /* */
- /* - providing a 'help' option in the same menu and displaying a */
- /* brief help message when this 'help' option is selected */
- /* */
- /* - running the application when the mouse 'select' or 'adjust' */
- /* buttons are clicked on the installed icon, or when a file or */
- /* directory is dragged to it (clicking 'adjust' over the */
- /* installed icon will also remove it from the icon bar) */
- /* */
- /* - responding to requests for help text from the '!Help' */
- /* application (which displays the text in an 'Interactive */
- /* help' window) */
- /* */
- /* - supplying additional input ('command options') to the */
- /* application when it is run. */
- /* */
- /* */
- /* BootA must be started up by the following command: */
- /* */
- /* *RUN BootA arg1 arg2 arg3 ... argn */
- /* */
- /* where 'argi' is the name of a client application to be installed */
- /* on the icon bar or specifies a file containing a list of such */
- /* applications (in which case 'argi' must be specified in the */
- /* form '-FILE filespec'). */
- /* */
- /*-------------------------------------------------------------------*/
- /* */
- /* COPYRIGHT NOTICE */
- /* */
- /* BootA is subject to Copyright. */
- /* */
- /* Permission is granted by the author to any recipient of this */
- /* material to use and make/disseminate copies of the application */
- /* provided that no charges are made for doing so (other than to */
- /* cover any cost of media or postage) and that this notice is */
- /* included with all copies. */
- /* */
- /*===================================================================*/
-
- #include "kernel.h" /* ARC specifics */
- #include "swis.h" /* SWI numbers */
- #include <ctype.h> /* Character handling */
- #include <stddef.h> /* Standard definitions */
- #include <stdio.h> /* Input/output */
- #include <stdlib.h> /* General utilities */
- #include <string.h> /* String handling */
-
- #include "useful.h" /* Useful definitions */
-
- /*-------------------------------------------------------------------*/
- /* Control block definitions */
- /*-------------------------------------------------------------------*/
-
- struct windowblock /* FORMAT OF WINDOW BLOCK */
- {
- int visible_area_minX ; /* visible area min X coord */
- int visible_area_minY ; /* visible area min Y coord */
- int visible_area_maxX ; /* visible area max X coord */
- int visible_area_maxY ; /* visible area max Y coord */
- int scroll_X_offset ; /* scroll X offset */
- int scroll_Y_offset ; /* scroll Y offset */
- int handle_to_open_behind ; /* window to open behind */
- int flags ; /* flags */
- char title_foreground_colour ; /* title foreground colour */
- char title_background_colour ; /* title background colour */
- char work_area_foreground_colour ; /* workarea foreground colour */
- char work_area_background_colour ; /* workarea background colour */
- char scroll_bar_outer_colour ; /* scroll bar outer colour */
- char scroll_bar_inner_colour ; /* scroll bar inner colour */
- char title_highlight_colour ; /* title highlight background */
- char reserved1 ; /* must be zero */
- int workarea_minX ; /* work area min X coord */
- int workarea_minY ; /* work area min Y coord */
- int workarea_maxX ; /* work area max X coord */
- int workarea_maxY ; /* work area max Y coord */
- int title_icon_flags ; /* title bar icon flags */
- int workarea_button_type ; /* workarea button type */
- int sprite_block_ptr ; /* ptr to sprite c.block */
- short min_window_width ; /* minimum window width */
- short min_window_height ; /* minimum window height */
- char title[12] ; /* title */
- int nicons ; /* number of icons */
- } ;
-
- struct iconblock /* FORMAT OF ICON BLOCK */
- {
- int minX_bound ; /* bounding box mix x-coord */
- int minY_bound ; /* bounding box mix y-coord */
- int maxX_bound ; /* bounding box max x-coord */
- int maxY_bound ; /* bounding box max y-coord */
- int flags ; /* icon flags */
- char name[12] ; /* sprite name or text */
- } ;
-
- struct indiconblock /* FORMAT OF ICON BLOCK */
- {
- int minX_bound ; /* bounding box mix x-coord */
- int minY_bound ; /* bounding box mix y-coord */
- int maxX_bound ; /* bounding box max x-coord */
- int maxY_bound ; /* bounding box max y-coord */
- int flags ; /* icon flags */
- char *bufptr ; /* pointer to text buffer */
- char *vldnptr ; /* pointer to validation str */
- int buflen ; /* buffer length */
- } ;
-
- struct menublock /* FORMAT OF MENU BLOCK */
- {
- char title[12] ; /* menu title */
- char title_foreground_colour ; /* title foreground colour */
- char title_background_colour ; /* title background colour */
- char work_area_foreground_colour ; /* workarea foreground colour */
- char work_area_background_colour ; /* workarea background colour */
- int width ; /* menu item width */
- int height ; /* menu item height */
- int vertical_gap ; /* gap between items */
- } ;
-
- struct menuitem /* FORMAT OF MENU ITEM BLOCK */
- {
- int menu_flags ; /* menu flags */
- int submenu ; /* submenu ptr or window hndl */
- int icon_flags ; /* icon flags */
- char icon_data[12] ; /* icon data (e.g. text) */
- } ;
-
- struct clientblk /* FORMAT OF APPL QUEUE ENTRY */
- {
- struct clientblk *next ; /* Pointer to next block */
- struct clientblk *prev ; /* Pointer to previous block */
- int icon_handle ; /* Handle of icon */
- char *helptxt ; /* Pointer to help text */
- char *cmdopts ; /* Pointer to command options */
- char name[12] ; /* Application name */
- char vldtnstr[1] ; /* Start of validation string */
- char sprite[13] ; /* Sprite name */
- char fullname[1] ; /* Full path+leaf for appl */
- } ;
-
- /*-------------------------------------------------------------------*/
- /* Global data definitions */
- /*-------------------------------------------------------------------*/
-
- static int taskid ; /* task id */
- static struct clientblk *clientqueue = NULL ;/* application q ptr */
- static struct clientblk *clientptr ; /* ptr to chosen appl */
- static int block[64] ; /* wimp poll block */
- static char cmdoptsbuf[50] ; /* work buf for cmdopts */
-
- static const char helptxt[] = /* Default help text */
-
- "This icon has been installed by BootA. Drag a file or directory"
- " here to process it. Click MENU on !BootA in directory viewer and"
- " select HELP for more detailed information." ;
-
- /*-------------------------------------------------------------------*/
- /* Menu definitions */
- /*-------------------------------------------------------------------*/
-
- static struct
- {
- struct menublock prefix ; /* Menu has four items */
- struct menuitem item0 ; /* 0. Info */
- struct menuitem item1 ; /* 1. Help */
- struct menuitem item2 ; /* 2. CmdOpts */
- struct menuitem item3 ; /* 3. Quit */
- } menu =
- {
- { /* ---- MENU PREFIX ---------- */
- "!BootA", /* menu title */
- 7, /* title foreground colour */
- 2, /* title background colour */
- 7, /* workarea foreground colour */
- 0, /* workarea background colour */
- 118, /* menu item width */
- 44, /* menu item height */
- 0 /* gap between items */
- },
- { /* ----- MENU ITEM 0 --------- */
- 0x00, /* menu flags */
- -1, /* submenu ptr or window hndl */
- 0x07000001, /* icon flags */
- "Info" /* icon data (e.g. text) */
- },
- { /* ----- MENU ITEM 1 --------- */
- 0x00, /* menu flags */
- -1, /* submenu ptr or window hndl */
- 0x07000001, /* icon flags */
- "Help" /* icon data (e.g. text) */
- },
- { /* ----- MENU ITEM 2 --------- */
- 0x00, /* menu flags */
- -1, /* submenu ptr or window hndl */
- 0x07000001, /* icon flags */
- "CmdOpts" /* icon data (e.g. text) */
- },
- { /* ----- MENU ITEM 3 --------- */
- 0x80, /* menu flags */
- -1, /* submenu ptr or window hndl */
- 0x07000001, /* icon flags */
- "Quit" /* icon data (e.g. text) */
- },
- } ;
-
- /*-------------------------------------------------------------------*/
- /* Information window definitions */
- /*-------------------------------------------------------------------*/
-
- #define infolblxmin 16
- #define infolblxmax 16+(8*16)+8
- #define infotxtxmin 16+(8*16)+8 + 8
- #define infotxtxmax 16+(8*16)+8 + 8+8+(30*16)+8
- #define infowidth 16+(8*16)+8 + 8+8+(30*16)+8+16
- #define infotxtymin 8
- #define infotxtymax 56
- #define infotxtdpth 56
- #define infodepth 8+(4*56)
-
- static struct
- {
- struct windowblock window ; /* base window block */
- struct iconblock icon0 ; /* icon for "Version:" */
- struct iconblock icon1 ; /* icon for "Author:" */
- struct iconblock icon2 ; /* icon for "Purpose:" */
- struct iconblock icon3 ; /* icon for "Name:" */
- struct indiconblock icon4 ; /* icon for version text */
- struct indiconblock icon5 ; /* icon for author text */
- struct indiconblock icon6 ; /* icon for purpose text */
- struct iconblock icon7 ; /* icon for "BootA" */
- } info_window =
- {
- {
- 0, /* visible area min X coord */
- 0, /* visible area min Y coord */
- infowidth, /* visible area max X coord */
- infodepth, /* visible area max Y coord */
- 0, /* scroll X offset */
- infodepth, /* scroll Y offset */
- -1, /* window to open behind */
- 0x84000012, /* flags */
- 7, /* title foreground colour */
- 2, /* title background colour */
- 7, /* workarea foreground colour */
- 1, /* workarea background colour */
- 0, /* scroll bar outer colour */
- 0, /* scroll bar inner colour */
- 0, /* title highlight background */
- 0, /* must be zero */
- 0, /* work area min X coord */
- 0, /* work area min Y coord */
- infowidth, /* work area max X coord */
- infodepth, /* work area max Y coord */
- 0x00000009, /* title bar icon flags */
- 0<<16, /* workarea button type */
- -1, /* ptr to sprite c.block */
- 0, /* minimum window width */
- 0, /* minimum window height */
- "Information", /* title */
- 8 /* number of icons */
- },
- { /* --- ICON BLOCK # 0 ------- */
- infolblxmin, /* Bounding box min x */
- infotxtymin+0*infotxtdpth, /* Bounding box min y */
- infolblxmax, /* Bounding box max x */
- infotxtymax+0*infotxtdpth, /* Bounding box max y */
- 0x07000211, /* Icon flags */
- "Version:"
- },
- { /* --- ICON BLOCK # 1 ------- */
- infolblxmin, /* Bounding box min x */
- infotxtymin+1*infotxtdpth, /* Bounding box min y */
- infolblxmax, /* Bounding box max x */
- infotxtymax+1*infotxtdpth, /* Bounding box max y */
- 0x07000211, /* Icon flags */
- "Author:"
- },
- { /* --- ICON BLOCK # 2 ------- */
- infolblxmin, /* Bounding box min x */
- infotxtymin+2*infotxtdpth, /* Bounding box min y */
- infolblxmax, /* Bounding box max x */
- infotxtymax+2*infotxtdpth, /* Bounding box max y */
- 0x07000211, /* Icon flags */
- "Purpose:"
- },
- { /* --- ICON BLOCK # 3 ------- */
- infolblxmin, /* Bounding box min x */
- infotxtymin+3*infotxtdpth, /* Bounding box min y */
- infolblxmax, /* Bounding box max x */
- infotxtymax+3*infotxtdpth, /* Bounding box max y */
- 0x07000211, /* Icon flags */
- "Name:"
- },
- { /* --- ICON BLOCK # 4 ------- */
- infotxtxmin, /* Bounding box min x */
- infotxtymin+0*infotxtdpth, /* Bounding box min y */
- infotxtxmax, /* Bounding box max x */
- infotxtymax+0*infotxtdpth, /* Bounding box max y */
- 0x07000135, /* Icon flags */
- "2.00 (18th December 1991)",
- (char *)-1,
- 1
- },
- { /* --- ICON BLOCK # 5 ------- */
- infotxtxmin, /* Bounding box min x */
- infotxtymin+1*infotxtdpth, /* Bounding box min y */
- infotxtxmax, /* Bounding box max x */
- infotxtymax+1*infotxtdpth, /* Bounding box max y */
- 0x07000135, /* Icon flags */
- "(c) Paul Witheridge",
- (char *)-1,
- 1
- },
- { /* --- ICON BLOCK # 6 ------- */
- infotxtxmin, /* Bounding box min x */
- infotxtymin+2*infotxtdpth, /* Bounding box min y */
- infotxtxmax, /* Bounding box max x */
- infotxtymax+2*infotxtdpth, /* Bounding box max y */
- 0x07000135, /* Icon flags */
- "Supports non-WIMP applications",
- (char *)-1,
- 1
- },
- { /* --- ICON BLOCK # 7 ------- */
- infotxtxmin, /* Bounding box min x */
- infotxtymin+3*infotxtdpth, /* Bounding box min y */
- infotxtxmax, /* Bounding box max x */
- infotxtymax+3*infotxtdpth, /* Bounding box max y */
- 0x07000035, /* Icon flags */
- "BootA" /* Text */
- }
- } ;
-
- /*-------------------------------------------------------------------*/
- /* Help window definitions */
- /*-------------------------------------------------------------------*/
-
- static struct windowblock help_window =
- { /* ---- WINDOW BLOCK BASE --- */
- 0, /* visible area min X coord */
- 0, /* visible area min Y coord */
- 60*16, /* visible area max X coord */
- 5*32, /* visible area max Y coord */
- 0, /* scroll X offset */
- 5*32, /* scroll Y offset */
- -1, /* window to open behind */
- 0x84000002, /* flags */
- 7, /* title foreground colour */
- 2, /* title background colour */
- 7, /* workarea foreground colour */
- 0, /* workarea background colour */
- 0, /* scroll bar outer colour */
- 0, /* scroll bar inner colour */
- 9, /* title highlight background */
- 0, /* must be zero */
- 0, /* work area min X coord */
- 0, /* work area min Y coord */
- 60*16, /* work area max X coord */
- 5*32, /* work area max Y coord */
- 0x00000009, /* title bar icon flags */
- 0, /* workarea button type */
- -1, /* ptr to sprite c.block */
- 0, /* minimum window width */
- 0, /* minimum window height */
- "Help", /* title */
- 0 /* no icons */
- } ;
-
- /*-------------------------------------------------------------------*/
- /* Command options window definitions */
- /*-------------------------------------------------------------------*/
-
- static struct
- {
- struct windowblock window ; /* Base window block */
- struct indiconblock icon0 ; /* Writeable icon for input */
- } cmdopts_window =
- {
- { /* ---- WINDOW BLOCK BASE --- */
- 0, /* visible area min X coord */
- 0, /* visible area min Y coord */
- 38*16, /* visible area max X coord */
- 2*32, /* visible area max Y coord */
- 0, /* scroll X offset */
- 2*32, /* scroll Y offset */
- -1, /* window to open behind */
- 0x84000012, /* flags */
- 7, /* title foreground colour */
- 2, /* title background colour */
- 7, /* workarea foreground colour */
- 1, /* workarea background colour */
- 0, /* scroll bar outer colour */
- 0, /* scroll bar inner colour */
- 9, /* title highlight background */
- 0, /* must be zero */
- 0, /* work area min X coord */
- 0, /* work area min Y coord */
- 38*16, /* work area max X coord */
- 2*32, /* work area max Y coord */
- 0x00000009, /* title bar icon flags */
- 0<<16, /* workarea button type */
- -1, /* ptr to sprite c.block */
- 0, /* minimum window width */
- 0, /* minimum window height */
- "CmdOpts", /* title */
- 1 /* number of icons */
- },
- { /* --- ICON BLOCK ----------- */
- 0, /* Bounding box min x */
- 0, /* Bounding box min y */
- 38*16, /* Bounding box max x */
- 2*32, /* Bounding box max y */
- 0x0700F131, /* Icon flags */
- cmdoptsbuf, /* Text buffer pointer */
- (char *)-1, /* Validation string pointer */
- sizeof(cmdoptsbuf) /* Text buffer length */
- }
- } ;
-
- /*-------------------------------------------------------------------*/
- /* Declare functions local in scope to this file. */
- /*-------------------------------------------------------------------*/
-
- static void initboota(const int argc,const char *const argv[]) ;
- static void send(const int actioncode,const char *fullname) ;
- static int wimpinit(const char *taskname) ;
- static void wimpterm(void) ;
- static int wimppoll(const int pollmask) ;
- static void wimpredraw(void) ;
- static void wimpopen(void) ;
- static void mouse(void) ;
- static void processkey(void) ;
- static void choose(void) ;
- static void receive(const enum boolean reply) ;
- static void acknowledge(_kernel_swi_regs *regsptr,const enum boolean reply) ;
- static void installappl(const char *fullname) ;
- static void runappl(const int filetype,const char *fullname) ;
- static void removeappl(void) ;
- static void help(void) ;
- static int createicon(void) ;
- static int delicon(const int handle) ;
- static char *installtext(const char *leaf,size_t maxlen) ;
- static void displaymenu(const int xcoord) ;
- static enum boolean adjust(void) ;
- static struct clientblk *findclient(const int icon_handle) ;
- static void *ualloc(size_t len) ;
- static void errormsg(const int errno,const char *errmsg) ;
- static enum boolean stricmp(const char *s1, const char *s2) ;
- static void strip(char *strptr) ;
- static char *gstrans(char * inout) ;
- static void setvar(const char *varname,const char *value) ;
- static void plot(int type,int x,int y) ;
- static void vdu24(int x1,int y1,int x2,int y2) ;
- static void vdutwo(int n) ;
- static void debug(const int debugid,const char *debugmsg) ;
- static void debugwait(void) ;
-
- /*===================================================================*/
- /* main program */
- /*===================================================================*/
-
- int main(const int argc,const char *const argv[])
- {
- initboota(argc,argv) ;
-
- do
- {
- switch ( wimppoll(0x00081831) )
- {
- case 1 :
- wimpredraw() ;
- break ;
- case 2 :
- wimpopen() ;
- break ;
- case 6 :
- mouse() ;
- break ;
- case 8 :
- processkey() ;
- break ;
- case 9 :
- choose() ;
- break ;
- case 17 :
- receive(FALSE) ;
- break ;
- case 18 :
- receive(TRUE) ;
- break ;
- }
- } FOREVER ;
- }
-
- /*===================================================================*/
- /* InitBootA - initialise BootA application itself */
- /*===================================================================*/
-
- static void initboota(const int argc,const char *const argv[])
- {
- _kernel_swi_regs regs ;
- int pollresponse ;
- int i ;
- int len ;
- int c ;
- int file_handle ;
- char workbuf[120] ;
-
- taskid = wimpinit("BootA") ;
-
- send(0x211170,"BootA starting") ;
- pollresponse = wimppoll(0x00061970) ;
-
- if ( pollresponse == 19 )
- {
- regs.r[1] = (int)&info_window ;
- _kernel_swi(Wimp_CreateWindow,®s,®s) ;
- menu.item0.submenu = regs.r[0] ;
- regs.r[1] = (int)&help_window ;
- _kernel_swi(Wimp_CreateWindow,®s,®s) ;
- menu.item1.submenu = regs.r[0] ;
- regs.r[1] = (int)&cmdopts_window ;
- _kernel_swi(Wimp_CreateWindow,®s,®s) ;
- menu.item2.submenu = regs.r[0] ;
- }
-
- for ( i = 1 ; i < argc ; i++ )
- {
- if ( stricmp(argv[i],"-FILE") )
- {
- i++ ;
- if ( i < argc )
- {
- if ( (file_handle = _kernel_osfind(0x40,(char *)argv[i])) == 0 )
- {
- sprintf(workbuf,"Cannot open '%.50s'",argv[i]) ;
- errormsg(99,workbuf) ;
- }
- else
- {
- do
- {
- for ( len = 0 ; len < sizeof(workbuf)-1 ; len++ )
- {
- if ( (c = _kernel_osbget(file_handle)) == EOF ||
- c < 0x20 )
- {
- break ;
- }
- workbuf[len] = c ;
- }
- workbuf[len] = '\0' ;
- if ( len != 0 && workbuf[0] != '|' )
- {
- gstrans(workbuf) ;
- strip(workbuf) ;
- if ( pollresponse == 19 )
- {
- installappl(workbuf) ;
- }
- else
- {
- send(0x211171,workbuf) ;
- }
- }
- } while ( c != EOF ) ;
- _kernel_osfind(0x00,(char *)file_handle) ;
- }
- }
- }
- else
- {
- strcpy(workbuf,argv[i]) ;
- gstrans(workbuf) ;
- strip(workbuf) ;
- if ( pollresponse == 19 )
- {
- installappl(workbuf) ;
- }
- else
- {
- send(0x211171,workbuf) ;
- }
- }
- }
- if ( clientqueue == NULL )
- {
- wimpterm() ;
- }
- }
-
- /*===================================================================*/
- /* Send - send message requesting application installation */
- /*===================================================================*/
-
- static void send(const int actioncode,const char *fullname)
- {
- _kernel_swi_regs regs ;
-
- block[0] = (strlen(fullname)+1+20+3) & 0xFC ;
- block[3] = 0 ;
- block[4] = actioncode ;
- strcpy((char *)&block[5],fullname) ;
- regs.r[0] = 18 ;
- regs.r[1] = (int)block ;
- regs.r[2] = 0 ;
- _kernel_swi(Wimp_SendMessage,®s,®s) ;
- }
-
- /*===================================================================*/
- /* WimpInit - connect task to Window Manager */
- /*===================================================================*/
-
- static int wimpinit(const char *taskname)
- {
- _kernel_swi_regs regs ;
-
- regs.r[0] = 200 ;
- regs.r[1] = 0x4B534154 ;
- regs.r[2] = (int)taskname ;
- _kernel_swi(Wimp_Initialise,®s,®s) ;
- return regs.r[1] ;
- }
-
- /*===================================================================*/
- /* WimpTerm - disconnect task from Window Manager & exit */
- /*===================================================================*/
-
- static void wimpterm(void)
- {
- _kernel_swi_regs regs ;
-
- regs.r[0] = taskid ;
- regs.r[1] = 0x4B534154 ;
- _kernel_swi(Wimp_CloseDown,®s,®s) ;
- exit(0) ;
- }
-
- /*===================================================================*/
- /* WimpPoll - poll wimp for events */
- /*===================================================================*/
-
- static int wimppoll(const int pollmask)
- {
- _kernel_swi_regs regs ;
-
- regs.r[0] = pollmask ;
- regs.r[1] = (int)block ;
- _kernel_swi(Wimp_Poll,®s,®s) ;
- return regs.r[0] ;
- }
-
- /*===================================================================*/
- /* WimpRedraw - redraw window */
- /*===================================================================*/
-
- static void wimpredraw(void)
- {
- _kernel_swi_regs regs ;
- int xorg,yorg ;
-
- regs.r[1] = (int)block ;
- _kernel_swi(Wimp_RedrawWindow,®s,®s) ;
- while ( regs.r[0] != 0 )
- {
- vdu24(xorg=block[7]+8,block[8]+16,block[9]-8,yorg=block[10]-16) ;
- plot(4,xorg,yorg) ;
- if ( clientptr != NULL && clientptr->helptxt != NULL )
- {
- regs.r[0] = (int)(clientptr->helptxt) ;
- }
- else
- {
- regs.r[0] = (int)helptxt ;
- }
- regs.r[1] = regs.r[2] = 0 ;
- _kernel_swi(OS_PrettyPrint,®s,®s) ;
- regs.r[1] = (int)block ;
- _kernel_swi(Wimp_GetRectangle,®s,®s) ;
- }
- }
-
- /*===================================================================*/
- /* WimpOpen - open window */
- /*===================================================================*/
-
- static void wimpopen(void)
- {
- _kernel_swi_regs regs ;
-
- regs.r[1] = (int)block ;
- _kernel_swi(Wimp_OpenWindow,®s,®s) ;
- }
-
- /*===================================================================*/
- /* Mouse - handle mouse click on icon */
- /*===================================================================*/
-
- static void mouse(void)
- {
- if ( block[3] != -2 || (clientptr = findclient(block[4])) == NULL )
- {
- return ;
- }
- if ( block[2] & 0x02 )
- {
- displaymenu(block[0]) ;
- }
- else if ( block[2] & 0x05 )
- {
- runappl(-1,"") ;
- if ( block[2] & 0x01 )
- {
- removeappl() ;
- }
- }
- }
-
- /*===================================================================*/
- /* processkey - process key press */
- /*===================================================================*/
-
- static void processkey(void)
- {
- _kernel_swi_regs regs ;
-
- if ( block[6] == '\r' && clientptr != NULL )
- {
- strip(cmdoptsbuf) ;
- free(clientptr->cmdopts) ;
- clientptr->cmdopts = NULL ;
- if ( cmdoptsbuf[0] != '\0' )
- {
- strcpy((clientptr->cmdopts = ualloc(strlen(cmdoptsbuf)+1)),
- cmdoptsbuf) ;
- }
- clientptr = NULL ;
- regs.r[1] = -1 ;
- _kernel_swi(Wimp_CreateMenu,®s,®s) ;
- }
- else
- {
- regs.r[0] = block[6] ;
- _kernel_swi(Wimp_ProcessKey,®s,®s) ;
- }
- }
-
- /*===================================================================*/
- /* choose - handle selection from menu */
- /*===================================================================*/
-
- static void choose(void)
- {
- if ( block[0] == 3 )
- {
- removeappl() ;
- }
- else
- {
- if ( adjust() )
- {
- displaymenu(0) ;
- }
- }
- }
-
- /*===================================================================*/
- /* receive - process incoming message */
- /*===================================================================*/
-
- static void receive(const enum boolean reply)
- {
- _kernel_swi_regs regs ;
-
- switch ( block[4] )
- {
- case 0 :
- wimpterm() ;
- break ;
-
- case 3 :
- if ( (clientptr = findclient(block[6])) != NULL )
- {
- block[3] = block[2] ;
- block[4] = 4 ;
- regs.r[0] = 17 ;
- regs.r[1] = (int)block ;
- regs.r[2] = block[1] ;
- _kernel_swi(Wimp_SendMessage,®s,®s) ;
- runappl(block[10],(char *)&block[11]) ;
- }
- break ;
-
- case 0x502 :
- help() ;
- break ;
-
- case 0x211170 :
- acknowledge(®s,reply) ;
- break ;
-
- case 0x211171 :
- acknowledge(®s,reply) ;
- installappl((char*)&block[5]) ;
- break ;
-
- case 0x211172 :
- if ( (clientptr = findclient(block[5])) != NULL )
- {
- strncpy(clientptr->sprite,(char*)&block[6],
- sizeof(clientptr->sprite)-1) ;
- clientptr->sprite[sizeof(clientptr->sprite)-1] = '\0' ;
- acknowledge(®s,reply) ;
- block[0] = -2 ;
- block[1] = clientptr->icon_handle ;
- regs.r[1] = (int)&block[0] ;
- _kernel_swi(Wimp_GetIconState,®s,®s) ;
- regs.r[0] = -2 ;
- regs.r[1] = block[2] ; /* Add 32 units to upper y */
- regs.r[2] = block[3] ; /* coord to make it work with */
- regs.r[3] = block[4] ; /* RISC OS 2. RISC OS 3 is OK. */
- regs.r[4] = block[5] + 32 ;
- _kernel_swi(Wimp_ForceRedraw,®s,®s) ;
- }
- break ;
-
- case 0x211173 :
- if ( (clientptr = findclient(block[5])) != NULL )
- {
- acknowledge(®s,reply) ;
- removeappl() ;
- }
- break ;
- }
- }
-
- /*===================================================================*/
- /* acknowledge - return confirmation to type 18 wimp message */
- /*===================================================================*/
-
- static void acknowledge(_kernel_swi_regs *regsptr,const enum boolean reply)
- {
- if ( reply )
- {
- block[3] = block[2] ;
- regsptr->r[0] = 19 ;
- regsptr->r[1] = (int)block ;
- regsptr->r[2] = block[1] ;
- _kernel_swi(Wimp_SendMessage,regsptr,regsptr) ;
- }
- }
-
- /*===================================================================*/
- /* installappl - install application on icon bar */
- /*===================================================================*/
-
- static void installappl(const char *fullname)
- {
- _kernel_osfile_block osfileblk ;
- _kernel_oserror *errptr ;
- int result ;
- const char *p ;
- char msg[120] ;
-
- if ( (p = strrchr(fullname,'.')) == NULL )
- {
- p = fullname - 1 ;
- }
- p++ ;
-
- if ( (result =_kernel_osfile(17,fullname,&osfileblk)) == _kernel_ERROR )
- {
- errptr = _kernel_last_oserror() ;
- sprintf(msg,"'%.50s' - %.50s",fullname,errptr->errmess) ;
- errormsg(errptr->errnum,msg) ;
- return ;
- }
-
- if ( result == 0 )
- {
- sprintf(msg,"'%.50s' - not found",fullname) ;
- errormsg(99,msg) ;
- return ;
- }
-
- if ( result != 2 || *p != '!' )
- {
- sprintf(msg,"'%.50s' - not application",fullname) ;
- errormsg(99,msg) ;
- return ;
- }
-
- clientptr = ualloc(sizeof(*clientptr)+strlen(fullname)) ;
-
- strncpy(clientptr->name,p,sizeof(clientptr->name)) ;
- strncpy(clientptr->sprite,p,sizeof(clientptr->sprite)) ;
- strcpy(clientptr->fullname,fullname) ;
-
- if ( (clientptr->icon_handle = createicon()) != -1 )
- {
- clientptr->prev = NULL ;
- clientptr->next = clientqueue ;
- if ( clientqueue != NULL )
- {
- clientqueue->prev = clientptr ;
- }
- clientqueue = clientptr ;
- clientptr->helptxt = installtext("!HelpMsg",231) ;
- clientptr->cmdopts = installtext("!CmdOpts",50) ;
- }
- else
- {
- free(clientptr) ;
- }
- clientptr = NULL ;
- }
-
- /*===================================================================*/
- /* runappl - run application */
- /*===================================================================*/
-
- static void runappl(const int filetype,const char *fullname)
- {
- char *optsptr ;
- char *workbuf ;
- char *p ;
- const char *object ;
- const char *type ;
- const char *dirptr ;
- const char *leafptr ;
- _kernel_swi_regs regs ;
-
- if ( (optsptr = clientptr->cmdopts) == NULL )
- {
- optsptr = "" ;
- }
-
- workbuf = ualloc(strlen(clientptr->fullname) +
- strlen(fullname) + strlen(optsptr) + 13) ;
-
- switch ( filetype )
- {
- case 0x2000 :
-
- object = "APPL" ;
- type = "DIR" ;
- dirptr = fullname ;
- leafptr = "" ;
- break ;
-
- case 0x1000 :
-
- type = object = "DIR" ;
- dirptr = fullname ;
- leafptr = "" ;
- break ;
-
- case -1 :
-
- type = object = "NONE" ;
- dirptr = "@" ;
- leafptr = "" ;
- break ;
-
- default :
-
- object = "FILE" ;
- strcpy(workbuf,fullname) ;
- if ( (p = strrchr(workbuf,'.')) == NULL )
- {
- dirptr = "@" ;
- leafptr = fullname ;
- }
- else
- {
- *p = '\0' ;
- dirptr = workbuf ;
- leafptr = p + 1 ;
- }
- regs.r[0] = 18 ;
- regs.r[2] = filetype ;
- _kernel_swi(OS_FSControl,®s,®s) ;
- regs.r[4] = 0 ;
- strip((char *)&(regs.r[2])) ;
- type = (char *)&(regs.r[2]) ;
- }
-
- setvar("BootA$Object",object) ;
- setvar("BootA$Dir",dirptr) ;
- setvar("BootA$Type",type) ;
- setvar("BootA$leaf",leafptr) ;
- setvar("BootA$CmdOpts",optsptr) ;
- sprintf(workbuf,"%i",clientptr->icon_handle) ;
- setvar("BootA$Handle",workbuf) ;
-
- sprintf(workbuf,"Run %s.!RunA %s %s",
- clientptr->fullname,fullname,optsptr) ;
- regs.r[0] = (int)workbuf ;
- _kernel_swi(Wimp_StartTask,®s,®s) ;
-
- free(workbuf) ;
- }
-
- /*===================================================================*/
- /* removeappl - remove application from icon bar */
- /*===================================================================*/
-
- static void removeappl(void)
- {
- if ( clientptr == NULL )
- {
- return ;
- }
-
- delicon(clientptr->icon_handle) ;
-
- free(clientptr->helptxt) ;
- free(clientptr->cmdopts) ;
-
- if ( clientptr->prev == NULL )
- {
- clientqueue = clientptr->next ;
- }
- else
- {
- clientptr->prev->next = clientptr->next ;
- }
-
- if ( clientptr->next != NULL )
- {
- clientptr->next->prev = clientptr->prev ;
- }
-
- free(clientptr) ;
-
- clientptr = NULL ;
-
- if ( clientqueue == NULL )
- {
- wimpterm() ;
- }
- }
-
- /*===================================================================*/
- /* help - respond to message from !info */
- /*===================================================================*/
-
- static void help(void)
- {
- _kernel_swi_regs regs ;
- struct clientblk *clientptr ;
-
- if ( block[8] != -2 )
- {
- return ;
- }
- block[3] = block[2] ;
- block[4] = 0x503 ;
- strcpy((char *)&block[5],
- (clientptr = findclient(block[9])) != NULL &&
- clientptr->helptxt != NULL ?
- (const char *)(clientptr->helptxt) : helptxt) ;
- block[0] = (strlen((char *)&block[5]) + 24) & 0xFC ;
- regs.r[0] = 17 ;
- regs.r[1] = (int)block ;
- regs.r[2] = block[1] ;
- _kernel_swi(Wimp_SendMessage,®s,®s) ;
- }
-
- /*===================================================================*/
- /* createicon - create icon on icon bar */
- /*===================================================================*/
-
- static int createicon(void)
- {
- struct
- {
- int window_handle ;
- struct indiconblock indirect ;
- } pblock ;
- _kernel_swi_regs regs ;
- int mode, width, height, len ;
- char *command ;
-
- pblock.window_handle = -1 ;
- pblock.indirect.flags = 0x1700310A ;
- pblock.indirect.bufptr = clientptr->sprite ;
- pblock.indirect.vldnptr = (char *)1 ;
- pblock.indirect.buflen = 1 ;
-
- regs.r[0] = 40 ;
- regs.r[2] = (int)clientptr->sprite ;
- if ( _kernel_swi(Wimp_SpriteOp,®s,®s) != NULL )
- {
- command = ualloc(strlen(clientptr->fullname)+24) ;
- sprintf(command,"Run %s.!Boot",clientptr->fullname) ;
- if ( _kernel_system(command,0) == _kernel_ERROR )
- {
- sprintf(command,"IconSprites %s.!Sprites",clientptr->fullname) ;
- _kernel_oscli(command) ;
- }
- free(command) ;
- regs.r[0] = 40 ;
- regs.r[2] = (int)clientptr->sprite ;
- if ( _kernel_swi(Wimp_SpriteOp,®s,®s) != NULL )
- {
- pblock.indirect.flags = 0x1700310B ;
- pblock.indirect.bufptr = clientptr->name ;
- pblock.indirect.vldnptr = clientptr->vldtnstr ;
- strncpy(clientptr->vldtnstr,"Sapplication",
- sizeof(clientptr->vldtnstr) + sizeof(clientptr->sprite)) ;
- regs.r[0] = 40 ;
- regs.r[2] = (int)clientptr->sprite ;
- if ( _kernel_swi(Wimp_SpriteOp,®s,®s) != NULL )
- {
- errormsg(99,"Sprite 'application' not found") ;
- clientptr->icon_handle = -1 ;
- return -1 ;
- }
- }
- }
- width = regs.r[3] ;
- height = regs.r[4] ;
- mode = regs.r[6] ;
-
- regs.r[0] = mode ;
- regs.r[1] = 4 ;
- _kernel_swi(OS_ReadModeVariable,®s,®s) ;
- width <<= regs.r[2] ;
-
- regs.r[0] = mode ;
- regs.r[1] = 5 ;
- _kernel_swi(OS_ReadModeVariable,®s,®s) ;
- height <<= regs.r[2] ;
-
- pblock.indirect.minX_bound = 0 ;
- pblock.indirect.maxX_bound = width ;
-
- if ( pblock.indirect.flags & 1 )
- {
- if ( width < (len = (strlen(clientptr->name) * 16)) )
- {
- pblock.indirect.maxX_bound = len ;
- }
- pblock.indirect.minY_bound = -16 ;
- pblock.indirect.maxY_bound = 20 + height ;
- }
- else
- {
- pblock.indirect.minY_bound = 0 ;
- pblock.indirect.maxY_bound = height ;
- }
- regs.r[1] = (int)&pblock ;
- _kernel_swi(Wimp_CreateIcon,®s,®s) ;
- return regs.r[0] ;
- }
-
- /*===================================================================*/
- /* delicon - delete icon from icon bar */
- /*===================================================================*/
-
- static int delicon(const int handle)
- {
- struct
- {
- int window_handle ;
- int icon_handle ;
- } delicon_block ;
- _kernel_swi_regs regs ;
-
- delicon_block.window_handle = -2 ;
- delicon_block.icon_handle = handle ;
- regs.r[1] = (int)&delicon_block ;
- _kernel_swi(Wimp_DeleteIcon,®s,®s) ;
- return -1 ;
- }
-
- /*===================================================================*/
- /* InstallText - install help/cmdopts text for application */
- /*===================================================================*/
-
- static char *installtext(const char *leaf,size_t maxlen)
- {
- int file_handle ;
- unsigned i ;
- int c ;
- char textarea[256] ;
-
- sprintf(textarea,"%s.%s",clientptr->fullname,leaf) ;
- if ( (file_handle = _kernel_osfind(0x40,textarea)) == 0 )
- {
- return NULL ;
- }
-
- i = 0 ;
- maxlen-- ;
- while ( (c = _kernel_osbget(file_handle)) != EOF )
- {
- if ( i == maxlen )
- {
- break ;
- }
- textarea[i++] = c ;
- }
- textarea[i] = '\0' ;
-
- _kernel_osfind(0x00,(char *)file_handle) ;
-
- return strcpy(ualloc(i+1),textarea) ;
- }
-
- /*===================================================================*/
- /* displaymenu - display menu */
- /*===================================================================*/
-
- static void displaymenu(const int xcoord)
- {
- _kernel_swi_regs regs ;
-
- cmdoptsbuf[0] = '\0' ;
- if ( clientptr->cmdopts != NULL )
- {
- strcpy(cmdoptsbuf,clientptr->cmdopts) ;
- }
- regs.r[1] = (int)&menu ;
- regs.r[2] = xcoord - 64 ;
- regs.r[3] = 96 + 4 * 44 + 44 ;
- _kernel_swi(Wimp_CreateMenu,®s,®s) ;
- }
-
- /*===================================================================*/
- /* adjust - check if adjust button pressed */
- /*===================================================================*/
-
- static enum boolean adjust(void)
- {
- _kernel_swi_regs regs ;
- regs.r[1] = (int)block ;
- _kernel_swi(Wimp_GetPointerInfo,®s,®s) ;
- return (block[2] & 0x01) ? TRUE : FALSE ;
- }
-
- /*===================================================================*/
- /* findclient - find control block for client application */
- /*===================================================================*/
-
- static struct clientblk *findclient(const int icon_handle)
- {
- struct clientblk *clientptr ;
-
- for ( clientptr = clientqueue ;
- clientptr != NULL ;
- clientptr = clientptr->next )
- {
- if ( icon_handle == clientptr->icon_handle )
- {
- return clientptr ;
- }
- }
- return NULL ;
- }
-
- /*===================================================================*/
- /* ualloc - unconditional memory allocation */
- /*===================================================================*/
-
- static void *ualloc(size_t len)
- {
- void *ptr ;
-
- if ( (ptr = malloc(len)) == NULL )
- {
- errormsg(0,"Out of memory") ;
- wimpterm() ;
- }
- return ptr ;
- }
-
- /*===================================================================*/
- /* errormsg - issue error message */
- /*===================================================================*/
-
- static void errormsg(const int errno,const char *errmsg)
- {
- struct
- {
- int errno ;
- char errmsg[120] ;
- } errblk ;
- _kernel_swi_regs regs ;
-
- errblk.errno = errno ;
- strcpy(errblk.errmsg,errmsg) ;
- regs.r[0] = (int)&errblk ;
- regs.r[1] = 0x00000001 ;
- regs.r[2] = (int)"BootA" ;
- _kernel_swi(Wimp_ReportError,®s,®s) ;
- }
-
- /*===================================================================*/
- /* stricmp - upper case compare */
- /*===================================================================*/
-
- static enum boolean stricmp(const char *s1, const char *s2)
- {
- int i ;
-
- for ( i = 0 ; s1[i] != '\0' ; i++ )
- {
- if ( toupper(s1[i]) != toupper(s2[i]) )
- {
- return FALSE ;
- }
- }
- if ( s2[i] != '\0' )
- {
- return FALSE ;
- }
- return TRUE ;
- }
-
- /*===================================================================*/
- /* strip - strip leading and trailing blanks from string */
- /*===================================================================*/
-
- static void strip(char *strptr)
- {
- int i,j ;
-
- for ( i = 0, j = strspn(strptr," " ) ;
- (strptr[i] = strptr[j]) != '\0' ;
- i++, j++) ;
-
- do
- {
- i-- ;
- if ( i < 0 )
- {
- break ;
- }
- } while ( strptr[i] == ' ' ) ;
-
- strptr[i+1] = '\0' ;
- }
-
- /*===================================================================*/
- /* gstrans - perform system variable substitution etc */
- /*===================================================================*/
-
- static char *gstrans(char *inout)
- {
- _kernel_swi_regs regs ;
- char workbuf[120] ;
-
- regs.r[0] = (int)inout ;
- regs.r[1] = (int)workbuf ;
- regs.r[2] = sizeof(workbuf)-1 ;
- _kernel_swi(OS_GSTrans,®s,®s) ;
- workbuf[regs.r[2]] = '\0' ;
- strcpy(inout,workbuf) ;
- return inout ;
- }
-
- /*===================================================================*/
- /* setvar - set system variable value */
- /*===================================================================*/
-
- static void setvar(const char *varname,const char *value)
- {
- _kernel_swi_regs regs ;
-
- regs.r[0] = (int)varname ;
- regs.r[1] = ( value == NULL ) ? (int)"" : (int)value ;
- regs.r[2] = regs.r[3] = regs.r[4] = 0 ;
- _kernel_swi(OS_SetVarVal,®s,®s) ;
- }
-
- /*===================================================================*/
- /* Plot - move/draw/plot function */
- /*===================================================================*/
-
- static void plot(int type,int x,int y)
- {
- _kernel_swi_regs regs ;
- regs.r[0] = type ;
- regs.r[1] = x ;
- regs.r[2] = y ;
- _kernel_swi(OS_Plot,®s,®s) ;
- }
-
- /*===================================================================*/
- /* vdu24 - set graphics window */
- /*===================================================================*/
-
- static void vdu24(int x1,int y1,int x2,int y2)
- {
- _kernel_oswrch(24) ;
- vdutwo(x1) ;
- vdutwo(y1) ;
- vdutwo(x2) ;
- vdutwo(y2) ;
- }
-
- /*===================================================================*/
- /* vdutwo - write two byte value to oswrch */
- /*===================================================================*/
-
- static void vdutwo(int n)
- {
- _kernel_oswrch(n) ;
- _kernel_oswrch(n >> 8) ;
- }
-
- /*===================================================================*/
- /* debug */
- /*===================================================================*/
-
- static void debug(const int debugid,const char *debugmsg)
- {
- _kernel_oswrch(4) ;
- printf("%d ===> %s\n",debugid,debugmsg) ;
- _kernel_oswrch(5) ;
- }
-
- /*===================================================================*/
- /* debugwait */
- /*===================================================================*/
-
- static void debugwait(void)
- {
- do
- {
- } while ( (_kernel_osbyte(129,-1,-1) & 0xffff) == 0 ) ;
- do
- {
- } while ( (_kernel_osbyte(129,-1,-1) & 0xffff) != 0 ) ;
- }
-
- /*===================================================================*/
-