4 * Main control section and user interface
6 * © 1994-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Glass.
13 * Glass is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * Glass is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with Glass. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 /*----- Header files ------------------------------------------------------*/
31 * ANSI standard headers
49 #include "steel/Steel.h"
51 #include "steel/viewer.h"
52 #include "steel/mem.h"
53 #include "steel/caretptr.h"
54 #include "steel/buttons.h"
55 #include "steel/sculptrix.h"
56 #include "steel/flex.h"
76 /*----- External dependencies ---------------------------------------------*/
78 extern char date[], cright[];
81 /*----- Static global variables -------------------------------------------*/
83 static BOOL glass_genDump; /* Send timings to dump (stderr) */
84 static BOOL glass_noWindow; /* Turn off the nice intro window */
86 /*----- Icon bar handlers -------------------------------------------------*/
89 * BOOL glass_unknowns(wimp_eventstr *e,void *handle)
92 * Vets unknown events. The important ones at the moment are
93 * Message_DataOpen and Message_PreQuit. Glass 1.xx supports the RISC
94 * OS 3 prequit convention to avoid the old misunderstanding. This may
95 * cause problems under RISC OS 2. If so, they'll just have to upgrade...
98 * wimp_eventstr *e == the event in question
102 * TRUE if the event has now been processed.
105 static BOOL glass_unknowns(wimp_eventstr *e,void *handle)
116 case wimp_ESENDWANTACK:
117 switch (e->data.msg.hdr.action)
120 filetype=xferrecv_checkinsert(&filename);
123 case 0xfec: /* Template file */
124 xferrecv_insertfileok();
125 tfile_loadFromFile(filename,xferrecv_nameToImport());
131 if (tfile_okToQuit(TRUE))
132 intMsgs_send(glass_KILLFILES);
135 e->data.msg.hdr.your_ref=e->data.msg.hdr.my_ref;
136 wimpt_noerr(wimp_sendmessage(wimp_EACK,
138 e->data.msg.hdr.task));
142 case wimp_MMODECHANGE:
143 intMsgs_send(glass_MODECHANGE);
146 sprintf(buff,"Run %s\n",getenv("Glass$Dir"));
148 r.r[1]=e->data.msg.data.savedesk.filehandle;
151 wimpt_noerr(os_swix(XOS_GBPB,&r));
161 * void glass_ibarHandler(ibicon i,ibicon_eventType e,void *handle)
164 * Handles events for the icon bar icon (such as help requests, load and
165 * save messages, and of course mouse clicks).
168 * ibicon i == the handle of the icon
169 * ibicon_eventType e == what has happened
170 * void *handle == a dummy handle
173 static void glass_ibarHandler(ibicon i,ibicon_eventType e,void *handle)
175 int filetype; /* Filetype of a file to import */
176 char *filename; /* Filename of a file */
177 int estsize; /* Estimated size of a file to import */
178 void *p; /* Pointer to loaded file */
179 unused(i); /* Not actually interested in the icon */
180 unused(handle); /* Not at all interested in the handle */
181 switch (e) /* Find out what's going on */
183 case ibicon_LEFTCLICK: /* Clicked with select */
186 if (t=tfile_createTemplateFile(msgs_lookup("tfUNT")),t)
187 viewer_display(t->v);
190 case ibicon_RIGHTCLICK: /* Clicked with adjust */
191 break; /* Ignore it and hope it goes away */
192 case ibicon_LOAD: /* Load request from Filer */
193 filetype=xferrecv_checkinsert(&filename); /* Get information */
196 case 0xfec: /* Template file */
197 tfile_loadFromFile(filename,xferrecv_nameToImport());
198 xferrecv_insertfileok();
202 case ibicon_SAVE: /* Save from another application */
203 filetype=xferrecv_checkimport(&estsize); /* Get information */
206 case 0xfec: /* Template file */
207 if (xferrecv_returnImportedBlock(&p)!=-1)
209 tfile_loadFromMemory(&p,xferrecv_nameToImport());
216 case ibicon_HELP: /* Help request */
217 help_startHelp(); /* Start a help reply */
218 help_addLine(msgs_lookup("wehIB"));
219 help_endHelp(); /* Send the message back */
225 * void glass_ibarMenuHandler(int hit[],void *handle)
228 * Processes menu clicks for the icon bar menu.
231 * int hit[] == array of menu hits
232 * void *handle == 0 (dummy handle)
235 static void glass_ibarMenuHandler(int hit[],void *handle)
237 unused(handle); /* This menu not attached to data struct */
238 switch (hit[0]) /* Check which item was chosen */
240 case glass_IBARINFO: /* About this program */
242 msgs_lookup("wePUR"),
247 case glass_IBARPREFS: /* Preferences dialogue */
248 gPrefs_edit(); /* Edit the preferences... */
250 case glass_IBARTBOX: /* Toolbox (window manipulation) */
251 toolbox(); /* Handles it all... */
253 case glass_IBARHEAPINFO: /* Heap info display */
254 indir_heapInfo(); /* Display */
256 case glass_IBARQUIT: /* Quit program */
257 if (tfile_okToQuit(TRUE)) /* Check the user is sure about this */
258 exit(0); /* End Glass and announce success */
264 * void glass_ibarMenuHelp(int hit[],void *handle)
267 * Help processor for icon bar menu.
270 * int hit[] == the item to give help for
271 * void *handle == a dummy handle
274 static void glass_ibarMenuHelp(int hit[],void *handle)
278 help_readFromMenu("wemhIB",hit);
282 /*----- Initialisation ----------------------------------------------------*/
285 * void glass_exit(void)
288 * Exit handler, creates internal broadcast to close down everything.
291 static void glass_exit(void)
293 intMsgs_send(glass_CLOSEDOWN);
297 * void glass_iconbar(void)
300 * Sets up the icon bar during Glass initialisation. Essentially, it
301 * installs an icon bar, attaches a menu to it, and gives it a handler.
302 * It also establishes a handler for loading and mouse clicks.
305 static void glass_iconbar(void)
307 ibicon i; /* Handle for the icon we will create */
308 menu m; /* The menu to attach to the icon */
309 m=menu_new("Glass",msgs_lookup("weIBM"));
310 i=ibicon_create(ibicon_RIGHT,"!glass",ibicon_WIMPAREA,0,0);
311 ibicon_attachMenu(i,m,glass_ibarMenuHandler,glass_ibarMenuHelp,0);
312 ibicon_eventHandler(i,glass_ibarHandler,0);
316 * void glass_scanCLI(int argc,char *argv[],BOOL inited)
319 * Scans command line string and loads relevant files
322 * int argc == the number of words in the string
323 * char *argv[] == the words, as an array of strings
324 * BOOL inited == whether we have initialised the WIMP
327 static void glass_scanCLI(int argc,char *argv[],BOOL inited)
332 if (utils_caselessCmp(argv[i],"-genDump")==0)
334 else if (utils_caselessCmp(argv[i],"-noWindow")==0)
336 else if (utils_caselessCmp(argv[i],"-help")==0)
340 "Glass %i.%02i (%s)\n"
344 "Command line syntax:\n"
345 " Glass [<option> | <filename>]...\n"
347 "<filename> == file name to load\n"
348 "<option> is one of:\n"
349 " -help == display this help\n"
350 " -genDump == dump timings and other crap to stderr\n"
351 " -noWindow == don't display startup window\n",
361 tfile_loadFromFile(argv[i],argv[i]);
367 * void glass_wait(int cs)
370 * Makes everything stand still for a bit
373 * in cs == number of centiseconds to wait
376 static void glass_wait(int cs)
380 wimpt_noerr(os_swix(XOS_ReadMonotonicTime,&r)); /* Now wait for a bit */
382 while (r.r[0]-waiting<cs) /* Half a second should do... */
383 wimpt_noerr(os_swix(XOS_ReadMonotonicTime,&r)); /* Get the time again */
387 * void glass_initProgress(dbox d,char *message,int percent)
390 * Updates the display on the loading window while we;re initialising
394 * dbox d == the dbox being used
395 * char *message == the message to display in the little icon. A null
396 * pointer indicates that the message is not to change.
397 * int percent == the percentage complete so far
400 static void glass_initProgress(dbox d,char *message,int percent)
409 buttons_updateSlider(d,glass_CRSLIDER,100,percent,8,FALSE);
410 dbox_setfield(d,glass_CRPERCENT,"%i",percent);
412 dbox_setfield(d,glass_CRDOING,"%s",message);
415 visdelay_percent(percent);
419 "Glass init timing: %s - %i\n",
420 message ? message : "ditto",
426 * void glass_initialise(int argc,char *argv[])
429 * Does all the tedious initialisation procedure, and the bit with the
433 * int argc == the number of words in the CLI string
434 * char *argv[] == the words, as an array of strings
437 static void glass_initialise(int argc,char *argv[])
445 _dll_setname("Glass");
447 glass_scanCLI(argc,argv,FALSE); /* Scan command line arguments */
448 visdelay_begin(); /* Turn on the hourglass immediately */
450 /* --- Set up STEEL's options --- *
452 * We need to enable all the external module support, because we need
453 * to handle templates written to use them. The non-WIMP shading is just
457 #ifdef glass_DEBUGGING
462 wimpt_ONOWIMPSHADE | \
469 wimpt_ONOWIMPSHADE | \
470 wimpt_OREMSAVEICON | \
474 wimpt_setOptions(_options,_options);
476 wimpt_init("Glass"); /* Crank up the WIMP */
477 res_init("Glass"); /* Point to resource files */
478 mem_flexdInit(0, 0); /* Initialise flex system */
480 resspr_init(); /* Load my copious quantities of sprites */
483 template_readfile(res_name("LoadTpl"));
485 r.r[0]=17; /* Need to find the size of banner sprite */
486 r.r[1]=(int)res_name("LoadSpr"); /* Set up name */
487 wimpt_noerr(os_swix(XOS_File,&r)); /* Do the call */
488 if (!flex_alloc((flex_ptr)&a,r.r[4]+4)) /* Allocate memory for sprites*/
489 a=0; /* If failed, don't show sprites */
492 sprite_area_initialise(a,r.r[4]+4); /* Initialise sprite area (!) */
493 wimpt_noerr(sprite_area_load(a,res_name("LoadSpr")));
494 /* Do the load as required */
495 template_syshandle("loading")->spritearea=a; /* Rig sprite area */
497 if (d=dbox_create("loading"),d) /* Create the dialogue box */
505 dbox_setfield(d, glass_CRGPLNOTE,
506 "Glass is free software; it may be modified and/or "
507 "redistributed under the terms of the GNU General "
509 dbox_setfield(d, glass_CRNOWARRANTY,
510 "Glass is distributed in the hope that it will be "
511 "useful, but WITHOUT ANY WARRANTY.");
512 dbox_display(d,dbox_STATIC_CENTRE); /* Display */
513 rdr.w=dbox_syshandle(d); /* Draw the window on the screen NOW */
514 wimpt_noerr(wimp_redraw_wind(&rdr,&more)); /* Start redraw process */
515 while (more) /* Carry on till it's all done */
517 wimpt_noerr(sculptrix_redrawWindow(&rdr)); /* Do the 3D bitties */
518 buttons_redrawSlider(d,glass_CRSLIDER,100,0,8,FALSE); /* Slider */
519 wimpt_noerr(wimp_get_rectangle(&rdr,&more)); /* Get the next bit */
523 visdelay_percent(0); /* If no box, give percentage, at least */
527 flex_free((flex_ptr)&a);
532 visdelay_percent(0); /* If no box, give percentage, at least */
534 glass_initProgress(d,msgs_lookup("weILM:Loading messages"),0);
535 msgs_init(); /* Read messages file (for help messages) */
537 glass_initProgress(d,msgs_lookup("weILW"),15);
539 werr_init(); /* Load nice error box */
541 glass_initProgress(d,msgs_lookup("weLDF"),43);
546 glass_iconbar(); /* Set up the icon bar appropriately */
548 glass_initProgress(d,msgs_lookup("weIRP"),53);
551 caretPtr("ptr_caret",resspr_area(),4,5); /* Enable pointer change */
552 win_add_unknown_event_processor(glass_unknowns,0); /* OPEN, PREQUIT */
553 event_returnMenuHelp(TRUE);
555 glass_initProgress(d,msgs_lookup("weILD"),61);
557 glass_scanCLI(argc,argv,TRUE); /* Scan command line arguments again */
559 dbox_display(d,dbox_STATIC_LASTPOS);
560 atexit(glass_exit); /* Exit handler to free up fonts */
564 glass_initProgress(d,msgs_lookup("weIFI"),100);
569 visdelay_end(); /* Finished initialisation */
573 * int main(int argc,char *argv[])
576 * Control initially passed to this routine. It essentially sets up all
577 * initial handlers (the icon bar etc.) and lets the event system handle
581 * int argc == the number of command line arguments passed
582 * char *argv == an array of command line arguments
585 * zero == successful completion
586 * nonzero == abnormal termination
588 * Defined return codes are:
591 int main(int argc,char *argv[])
593 exception_handler e; /* Point to return to on an exception */
594 glass_initialise(argc,argv); /* Perform necessary initialisation */
595 visdelay_begin(); /* Display hourglass between polls */
596 (void)exception_registerHandler(e); /* Return here if anything goes amiss*/
597 mem_useMalloc(); /* Ensure use of standard heap */
598 for(;;) /* And now, just process events until... */
599 event_process(); /* ...kingdom come. */
600 return (0); /* Return successfully */