home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-23 | 21.3 KB | 1,054 lines |
- /* #define DEBUG */
-
- /* $Id: c.vmode 1.3 92/02/25 11:45:32 bdb Exp $
- *
- * $Log: c.vmode $
- * Revision 1.3 92/02/25 11:45:32 bdb
- * Changed newtasks behaviour to only trap on -trl ones,
- * and no longer use weird patch. This supports a newtask
- * command to replace taskwindow.
- *
- * Revision 1.2 92/02/20 11:03:22 bdb
- * Added cursor, passing on keys
- * dbox_query replaces error box.
- *
- * Revision 1.1 92/02/19 16:28:10 bdb
- * Initial revision
- *
- */
-
- #define REVISION "$Revision: 1.3 $"
- #define VERSION ( REVISION " " __DATE__ " " __TIME__ + 11 )
-
- #include "wimp.h"
- #include "wimpt.h"
- #include "win.h"
- #include "event.h"
- #include "res.h"
- #include "resspr.h"
- #include "menu.h"
- #include "template.h"
- #include "dbox.h"
- #include "dboxquery.h"
- #include "alarm.h"
- #include "baricon.h"
- #include "xfersend.h"
- #include "saveas.h"
- #include "werr.h"
- #include "flex.h"
- #include "visdelay.h"
- #include "akbd.h"
- #include "pointer.h"
- #include "bbc.h"
- #include "colourtran.h"
- #include "kernel.h"
- #include "swis.h"
- #include "swiv.h"
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <signal.h>
-
- #define min(x,y) ((x)<(y)?(x):(y))
- #define max(x,y) ((x)>(y)?(x):(y))
-
-
- enum themenu { MNULL, MKILL, MRECONNECT, MSUSPEND, MRESUME, MSAVE };
- #define themenuinit "Kill,Reconnect,Suspend,Resume,>Save"
-
- enum state { TDEAD, TSUSPENDED, TRUNNING };
-
- /* Container for info about a window */
- typedef struct win
- { wimp_w w; /* window handle */
- char title[256]; /* displayed title of window - indirecttext pts here */
- struct win *next;
- sprite_area *area;
- int osx,osy;
- int *save_area;
- char *pixtrans;
- wimp_t task;
- int mode;
- int l2bpp;
- int xeig,yeig;
- int changed;
- enum state state;
- int charx,chary;
- int curx,cury;
- } win;
-
- static os_error NoMem = { 0, "Out of Memory" };
-
- static win *thewins = NULL;
- static int newtasks = 1; /* Catch new taskwindows */
-
- static menu themenu;
- static menu barmenu=NULL;
- static wimp_i theicon;
-
- static int wimpversion;
-
- /* Saved win during drag or save/open message bounce */
- static win *savewin = NULL;
-
- /* Prototypes */
-
- #include "VMode.h"
-
- int main
- ( int argc, char *argv[] )
- {
- int i;
- init();
- for (i = 1; i<argc; i++)
- launchone(argv[i],0);
- for (;;)
- { event_process();
- }
- return 0;
- }
-
- void init
- ( void )
- {
- wimpversion = wimpt_init("VMode");
- #ifdef DEBUG
- signal(SIGABRT, SIG_DFL);
- signal(SIGFPE, SIG_DFL);
- signal(SIGILL, SIG_DFL);
- signal(SIGSEGV, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- #endif
- res_init("VMode");
- resspr_init();
- template_init();
- dbox_init();
- alarm_init();
- visdelay_init();
- flex_init();
- win_add_unknown_event_processor( unknownevent, NULL );
- theicon = baricon( "!VMode", 1, barclick );
- event_attachmenumaker( win_ICONBAR, barmenumaker, barmenuproc, NULL );
- themenu = menu_new( "VMode", themenuinit );
- newtasks = atoi(getenv("VMode$NewTasks"));
- }
-
- sprite_id *SprPtr
- (sprite_header *s)
- {
- static sprite_id id;
- id.tag = sprite_id_addr;
- id.s.addr = s;
- return &id;
- }
-
- sprite_id *SprNam
- (char *s)
- {
- static sprite_id id;
- id.tag = sprite_id_name;
- id.s.name = s;
- return &id;
- }
-
- menu menumaker
- ( void *h )
- { win *w = h;
- menu_setflags( themenu, MKILL, 0, (w->state==TDEAD) );
- menu_setflags( themenu, MRECONNECT, 0, (w->state!=TDEAD) );
- menu_setflags( themenu, MSUSPEND, 0, (w->state!=TRUNNING) );
- menu_setflags( themenu, MRESUME, 0, (w->state!=TSUSPENDED) );
- return themenu;
- }
-
- void menuproc
- ( void *h, char *hit )
- { wimp_mousestr m;
- wimp_msgstr msg;
- win *w = h;
- wimpt_noerr( wimp_get_point_info( &m ) );
- switch ( hit[0] )
- { case MKILL:
- msg.hdr.action = 0x808c4; /* TaskWindow_Morite */
- w->state = TDEAD;
- goto sendit;
- case MRECONNECT:
- wimp_starttask(w->title);
- w->state = TDEAD;
- break;
- case MSUSPEND:
- msg.hdr.action = 0x808c6; /* TaskWindow_Suspend */
- w->state = TSUSPENDED;
- goto sendit;
- case MRESUME:
- msg.hdr.action = 0x808c7; /* TaskWindow_Resume */
- w->state = TRUNNING;
- sendit:
- msg.hdr.your_ref = 0;
- msg.hdr.size = 20;
- wimpt_noerr( wimp_sendmessage( wimp_ESEND, &msg, w->task ) );
- break;
- case MSAVE:
- saveas( 0xff9, "screendump", 1, saveproc, 0, 0, w );
- break;
- }
- }
-
- BOOL saveproc
- ( char *filename, void *h )
- { win *w = h;
- BOOL b;
- b = !wimpt_complain(sprite_area_save(w->area,filename));
- if ( b && xfersend_file_is_safe() )
- h = NULL; /* maybe fiddle title */
- return b;
- }
-
- void winevent
- ( wimp_eventstr *e, void *h )
- { BOOL more;
- win *w = h;
- wimp_redrawstr r;
- switch ( e->e )
- { case wimp_EREDRAW:
- if (wimpt_checkmode())
- coltable(w);
- r.w = e->data.o.w;
- wimpt_noerr(wimp_redraw_wind(&r,&more));
- while (more)
- { int a,b;
- wimpt_noerr(sprite_put_scaled( w->area, SprNam("screen"), 0,
- r.box.x0-r.scx, r.box.y1-r.scy-w->osy, NULL, w->pixtrans));
- bbc_gcol(4,0);
- a = w->curx*w->charx+r.box.x0-r.scx;
- b = -(w->cury+1)*w->chary+r.box.y1-r.scy;
- bbc_rectanglefill(a,b,w->charx,w->chary-1);
- wimpt_noerr(wimp_get_rectangle(&r,&more));
- }
- break;
- case wimp_EOPEN:
- wimp_open_wind( &e->data.o );
- break;
- case wimp_ECLOSE:
- if (w->state==TDEAD || confirm("Task active. Kill and close?"))
- freewin( w );
- break;
- case wimp_EBUT:
- {
- switch ( e->data.but.m.bbits )
- { case wimp_BCLICKLEFT:
- case wimp_BCLICKRIGHT:
- case wimp_BDRAGLEFT:
- case wimp_BDRAGRIGHT:
- case wimp_BRIGHT:
- case wimp_BLEFT:
- grabcaret(w);
- break;
- }
- break;
- }
- case wimp_EKEY:
- { int code = e->data.key.chcode;
- if (code>0xFF)
- wimp_processkey(code);
- else
- { e->data.msg.hdr.action = 0x808c0; /* TaskWindow_Input */
- e->data.msg.hdr.your_ref = 0;
- e->data.msg.hdr.size = 28;
- e->data.msg.data.words[0]=1;
- e->data.msg.data.words[1]=code;
- wimpt_noerr( wimp_sendmessage( wimp_ESEND, &e->data.msg, w->task ) );
- } }
- break;
- case wimp_ESEND: case wimp_ESENDWANTACK:
- switch ( e->data.msg.hdr.action )
- { case wimp_MCLOSEDOWN:
- while (thewins)
- freewin(thewins);
- exit(0);
- break;
- }
- break;
- }
- }
-
- BOOL oktoquit
- ( void )
- {
- win *w;
- for ( w=thewins; w ; w=w->next)
- if (w->state!=TDEAD)
- break;
- if ( w )
- if ( confirm( "There are still tasks running under !VMode. Really quit?" ) )
- w=NULL;
- return w==NULL;
- }
-
- BOOL unknownevent
- ( wimp_eventstr *e, void *h )
- { win *w=h;
- sprite_state s, s2;
- wimp_redrawstr r;
- int *box;
- int s1;
- switch ( e->e )
- { case wimp_ENULL:
- s1 = 0;
- for (w = thewins; w; w = w->next)
- { if (w->changed)
- { int cx,cy;
- wimpt_noerr(sprite_outputtosprite(w->area, SprNam("screen"), w->save_area, s1?&s2:&s));
- s1 = 1;
- swix(OS_ChangedBox,IN(R0)|OUT(R1),-1,&box);
- r.w = w->w;
- r.box.x0 = box[1]<<w->xeig;
- r.box.y0 = (box[2]<<w->yeig)-w->osy;
- r.box.x1 = (box[3]+1<<w->xeig);
- r.box.y1 = (box[4]+1<<w->yeig)-w->osy;
- swix(OS_ChangedBox,IN(R0),2);
- if (r.box.x1>r.box.x0 && r.box.y1>r.box.y0)
- wimpt_noerr(wimp_force_redraw(&r));
- cx = bbc_pos();
- cy = bbc_vpos();
- if ( cx!=w->curx || cy!=w->cury )
- { r.w = w->w;
- r.box.x0 = w->curx*w->charx;
- r.box.y1 = -w->cury*w->chary;
- r.box.x1 = r.box.x0+w->charx;
- r.box.y0 = r.box.y1-w->chary;
- wimpt_noerr(wimp_force_redraw(&r));
- w->curx = cx;
- w->cury = cy;
- r.w = w->w;
- r.box.x0 = w->curx*w->charx;
- r.box.y1 = -w->cury*w->chary;
- r.box.x1 = r.box.x0+w->charx;
- r.box.y0 = r.box.y1-w->chary;
- wimpt_noerr(wimp_force_redraw(&r));
- }
- w->changed = 0;
- } }
- if (s1)
- wimpt_noerr(sprite_restorestate(s));
- break;
- case wimp_ESEND: case wimp_ESENDWANTACK:
- w = savewin;
- switch ( e->data.msg.hdr.action )
- { case wimp_MPREQUIT:
- if ( !oktoquit() )
- { ack( &e->data.msg );
- return TRUE;
- }
- break;
- case wimp_SAVEDESK:
- { int fh = e->data.msg.data.savedesk.filehandle;
- rofprintf( fh, "Run %s\n", getenv("VMode$Dir") );
- }
- break;
- case 0x808c5: /* TaskWindow_NewTask */
- if (newtasks && strstr(&e->data.msg.data.chars[0],"-ctrl"))
- {
- ack(&e->data.msg);
- /* the weird flag is now set to 0, since the above message cannot have really
- * come from taskwindow as its too broken to pass -ctrl through, and so we
- * don't have to worry about its other bugs
- */
- launchone(&e->data.msg.data.chars[0],0);
- }
- break;
- case 0x808c3: /* TaskWindow_Morio */
- for (w = thewins; w; w = w->next )
- if (w->task==e->data.msg.hdr.task)
- w->state = TDEAD;
- break;
- case 0x808c2: /* TaskWindow_Ego */
- w = (win *)e->data.msg.data.words[0];
- w->task = e->data.msg.hdr.task;
- w->state = TRUNNING;
- break;
- case 0x808c1: /* TaskWindow_Output */
- for ( w=thewins ; w ; w=w->next )
- if (w->task==e->data.msg.hdr.task)
- break;
- if (w)
- scribble( w, (char *)&e->data.msg.data.words[1], e->data.msg.data.words[0] );
- break;
- }
- break;
- case wimp_EACK:
- break;
- }
- return FALSE;
- }
-
- void barclick
- ( wimp_i i )
- { i = i;
- launchone("taskwindow -ctrl",0);
- }
-
- void launchone
- ( char *cmd, int weird )
- { wimp_wind *t;
- wimp_wstate s;
- win *w=claim(sizeof(win));
- /* NB taskwindow seems only to recognise a reply to a request for a server if
- * hex no.s with no &'s or flag names are used... odd!
- */
- if (weird)
- sprintf( w->title,"%s %08x %08x ", cmd, wimpt_task(), (int)w );
- else
- sprintf( w->title,"%s -task &%08x -txt &%08x ", cmd, wimpt_task(), (int)w );
- w->next = thewins;
- thewins = w;
- t = template_syshandle( "window" );
- t->title.indirecttext.buffer = w->title;
- t->title.indirecttext.bufflen = 256;
- wimpt_noerr( wimp_create_wind( t, &w->w ) );
- win_register_event_handler( w->w, winevent, (void *)w );
- event_attachmenumaker( w->w, menumaker, menuproc, (void *)w );
- w->area = NULL;
- w->pixtrans = NULL;
- w->save_area = NULL;
- if (!modeclear(w,0))
- {
- wimpt_noerr( wimp_get_wind_state( w->w, &s ) );
- wimpt_noerr( wimp_open_wind( &s.o ) );
- event_setmask( 0 );
- wimp_starttask(w->title);
- w->state = TDEAD;
- grabcaret(w);
- }
- else
- freewin(w);
- }
-
- void grabcaret
- ( win *w )
- { wimp_caretstr c;
- c.w = w->w;
- c.i = -1;
- c.x = 100;
- c.y = -100;
- c.height = 0|(1<<25); /* invisible */
- c.index = 0;
- wimpt_noerr(wimp_set_caret_pos(&c));
- }
-
- static int pal2[4]=
- {
- 0x0,
- 0xF0F0F007,
- };
- static int pal4[8]=
- {
- 0x0,
- 0xF001,
- 0xF0F003,
- 0xF0F0F007,
- };
- static int pal16[32]=
- {
- 0x0,
- 0xF001,
- 0xF00002,
- 0xF0F003,
- 0xF0000004,
- 0xF000F005,
- 0xF0F00006,
- 0xF0F0F007,
- 0x8,
- 0xF009,
- 0xF0000A,
- 0xF0F00B,
- 0xF000000C,
- 0xF000F00D,
- 0xF0F0000E,
- 0xF0F0F00F,
- };
- static int pal256[512]=
- {
- 0x10,
- 0x10101010,
- 0x20202010,
- 0x30303010,
- 0x4010,
- 0x10105010,
- 0x20206010,
- 0x30307010,
- 0x40000010,
- 0x50101010,
- 0x60202010,
- 0x70303010,
- 0x40004010,
- 0x50105010,
- 0x60206010,
- 0x70307010,
- 0x8010,
- 0x10109010,
- 0x2020A010,
- 0x3030B010,
- 0xC010,
- 0x1010D010,
- 0x2020E010,
- 0x3030F010,
- 0x40008010,
- 0x50109010,
- 0x6020A010,
- 0x7030B010,
- 0x4000C010,
- 0x5010D010,
- 0x6020E010,
- 0x7030F010,
- 0x400010,
- 0x10501010,
- 0x20602010,
- 0x30703010,
- 0x404010,
- 0x10505010,
- 0x20606010,
- 0x30707010,
- 0x40400010,
- 0x50501010,
- 0x60602010,
- 0x70703010,
- 0x40404010,
- 0x50505010,
- 0x60606010,
- 0x70707010,
- 0x408010,
- 0x10509010,
- 0x2060A010,
- 0x3070B010,
- 0x40C010,
- 0x1050D010,
- 0x2060E010,
- 0x3070F010,
- 0x40408010,
- 0x50509010,
- 0x6060A010,
- 0x7070B010,
- 0x4040C010,
- 0x5050D010,
- 0x6060E010,
- 0x7070F010,
- 0x800010,
- 0x10901010,
- 0x20A02010,
- 0x30B03010,
- 0x804010,
- 0x10905010,
- 0x20A06010,
- 0x30B07010,
- 0x40800010,
- 0x50901010,
- 0x60A02010,
- 0x70B03010,
- 0x40804010,
- 0x50905010,
- 0x60A06010,
- 0x70B07010,
- 0x808010,
- 0x10909010,
- 0x20A0A010,
- 0x30B0B010,
- 0x80C010,
- 0x1090D010,
- 0x20A0E010,
- 0x30B0F010,
- 0x40808010,
- 0x50909010,
- 0x60A0A010,
- 0x70B0B010,
- 0x4080C010,
- 0x5090D010,
- 0x60A0E010,
- 0x70B0F010,
- 0xC00010,
- 0x10D01010,
- 0x20E02010,
- 0x30F03010,
- 0xC04010,
- 0x10D05010,
- 0x20E06010,
- 0x30F07010,
- 0x40C00010,
- 0x50D01010,
- 0x60E02010,
- 0x70F03010,
- 0x40C04010,
- 0x50D05010,
- 0x60E06010,
- 0x70F07010,
- 0xC08010,
- 0x10D09010,
- 0x20E0A010,
- 0x30F0B010,
- 0xC0C010,
- 0x10D0D010,
- 0x20E0E010,
- 0x30F0F010,
- 0x40C08010,
- 0x50D09010,
- 0x60E0A010,
- 0x70F0B010,
- 0x40C0C010,
- 0x50D0D010,
- 0x60E0E010,
- 0x70F0F010,
- 0x80000010,
- 0x90101010,
- 0xA0202010,
- 0xB0303010,
- 0x80004010,
- 0x90105010,
- 0xA0206010,
- 0xB0307010,
- 0xC0000010,
- 0xD0101010,
- 0xE0202010,
- 0xF0303010,
- 0xC0004010,
- 0xD0105010,
- 0xE0206010,
- 0xF0307010,
- 0x80008010,
- 0x90109010,
- 0xA020A010,
- 0xB030B010,
- 0x8000C010,
- 0x9010D010,
- 0xA020E010,
- 0xB030F010,
- 0xC0008010,
- 0xD0109010,
- 0xE020A010,
- 0xF030B010,
- 0xC000C010,
- 0xD010D010,
- 0xE020E010,
- 0xF030F010,
- 0x80400010,
- 0x90501010,
- 0xA0602010,
- 0xB0703010,
- 0x80404010,
- 0x90505010,
- 0xA0606010,
- 0xB0707010,
- 0xC0400010,
- 0xD0501010,
- 0xE0602010,
- 0xF0703010,
- 0xC0404010,
- 0xD0505010,
- 0xE0606010,
- 0xF0707010,
- 0x80408010,
- 0x90509010,
- 0xA060A010,
- 0xB070B010,
- 0x8040C010,
- 0x9050D010,
- 0xA060E010,
- 0xB070F010,
- 0xC0408010,
- 0xD0509010,
- 0xE060A010,
- 0xF070B010,
- 0xC040C010,
- 0xD050D010,
- 0xE060E010,
- 0xF070F010,
- 0x80800010,
- 0x90901010,
- 0xA0A02010,
- 0xB0B03010,
- 0x80804010,
- 0x90905010,
- 0xA0A06010,
- 0xB0B07010,
- 0xC0800010,
- 0xD0901010,
- 0xE0A02010,
- 0xF0B03010,
- 0xC0804010,
- 0xD0905010,
- 0xE0A06010,
- 0xF0B07010,
- 0x80808010,
- 0x90909010,
- 0xA0A0A010,
- 0xB0B0B010,
- 0x8080C010,
- 0x9090D010,
- 0xA0A0E010,
- 0xB0B0F010,
- 0xC0808010,
- 0xD0909010,
- 0xE0A0A010,
- 0xF0B0B010,
- 0xC080C010,
- 0xD090D010,
- 0xE0A0E010,
- 0xF0B0F010,
- 0x80C00010,
- 0x90D01010,
- 0xA0E02010,
- 0xB0F03010,
- 0x80C04010,
- 0x90D05010,
- 0xA0E06010,
- 0xB0F07010,
- 0xC0C00010,
- 0xD0D01010,
- 0xE0E02010,
- 0xF0F03010,
- 0xC0C04010,
- 0xD0D05010,
- 0xE0E06010,
- 0xF0F07010,
- 0x80C08010,
- 0x90D09010,
- 0xA0E0A010,
- 0xB0F0B010,
- 0x80C0C010,
- 0x90D0D010,
- 0xA0E0E010,
- 0xB0F0F010,
- 0xC0C08010,
- 0xD0D09010,
- 0xE0E0A010,
- 0xF0F0B010,
- 0xC0C0C010,
- 0xD0D0D010,
- 0xE0E0E010,
- 0xF0F0F010,
- };
- static int *bpptab[4]={pal2,pal4,pal16,pal256};
-
- void modefree
- ( win *w )
- {
- if (w->area)
- flex_free((flex_ptr)&w->area);
- if (w->save_area)
- free(w->save_area);
- w->save_area=NULL;
- if (w->pixtrans)
- free(w->pixtrans);
- w->pixtrans=NULL;
- }
-
- os_error *modeclear
- ( win*w, int mode )
- {
- int size,bpp,x,y;
- sprite_state s;
- wimp_redrawstr r;
- wimp_wstate state;
- os_error *err;
- w->mode = mode;
- x = bbc_modevar(mode,bbc_XWindLimit)+1;
- y = bbc_modevar(mode,bbc_YWindLimit)+1;
- w->l2bpp = bbc_modevar(mode,bbc_Log2BPP);
- bpp = 1 << w->l2bpp;
- w->osx = x << (w->xeig=bbc_modevar(mode,bbc_XEigFactor));
- w->osy = y << (w->yeig=bbc_modevar(mode,bbc_YEigFactor));
- w->charx = 8 << w->xeig;
- w->chary = (bbc_modevar(mode,bbc_ModeFlags)&(1<<5)?16:8) << w->yeig;
- size = sizeof(sprite_area)+sizeof(sprite_header)+x*y*bpp/8;
- if (!flex_alloc((flex_ptr)&w->area, size))
- return wimpt_complain(&NoMem);
- sprite_area_initialise(w->area, size);
- err=wimpt_complain(sprite_create(w->area, "screen", sprite_nopalette, x, y, mode));
- if (err) return err;
- wimpt_noerr(sprite_sizeof_spritecontext(w->area, SprNam("screen"), &size));
- w->save_area = claim(size);
- w->save_area[0]=0;
- w->pixtrans = claim(1<<bpp);
- if (!w->save_area || !w->pixtrans)
- return wimpt_complain(&NoMem);
- wimpt_noerr(sprite_outputtosprite(w->area, SprNam("screen"), w->save_area, &s));
- swix(OS_ChangedBox,IN(R0),1);
- swix(OS_ChangedBox,IN(R0),2);
- wimpt_noerr(sprite_restorestate(s));
- coltable(w);
- r.w = w->w;
- r.box.x0 = 0; r.box.x1 = w->osx; r.box.y0 = -w->osy; r.box.y1 = 0;
- wimpt_noerr( wimp_get_wind_state( w->w, &state ) );
- if (state.o.box.x1 > state.o.box.x0+w->osx)
- state.o.box.x1 = state.o.box.x0+w->osx;
- if (state.o.box.y0 < state.o.box.y1-w->osy)
- state.o.box.y0 = state.o.box.y1-w->osy;
- if (state.o.x < w->osx - (state.o.box.x1 - state.o.box.x0))
- state.o.x = w->osx - (state.o.box.x1 - state.o.box.x0);
- if (state.o.y < (state.o.box.y1 - state.o.box.y0) - w->osy)
- state.o.y = (state.o.box.y1 - state.o.box.y0) - w->osy;
- wimpt_noerr(wimp_open_wind(&state.o));
- wimpt_noerr(wimp_set_extent(&r));
- wimpt_noerr(wimp_force_redraw(&r));
- return NULL;
- }
-
- void coltable
- ( win *w )
- {
- wimpt_noerr(colourtran_select_table(w->mode,(wimp_paletteword *)bpptab[w->l2bpp],-1,(wimp_paletteword *)-1,w->pixtrans));
- }
-
- void scribble
- ( win *w, char *data, int size )
- {
- sprite_state s;
- char *p;
- int q;
- wimpt_noerr(sprite_outputtosprite(w->area, SprNam("screen"), w->save_area, &s));
- while (size && (p = memchr( data, 22, size ))!=NULL)
- { if (p-data)
- swix( OS_WriteN, IN(R0|R1), data, p-data );
- size -= p-data;
- data = p;
- swix(OS_Byte,IN(R0|R1|R2)|OUT(R1),218,0,255,&q);
- if (!q && size>=2 )
- {
- wimpt_noerr(sprite_restorestate(s));
- modefree(w);
- if (modeclear(w,data[1]))
- { freewin(w);
- return;
- }
- size-=2;
- data+=2;
- wimpt_noerr(sprite_outputtosprite(w->area, SprNam("screen"), w->save_area, &s));
- }
- else
- { swix(OS_WriteC,IN(R0),*data++);
- size--;
- }
- }
- if (size)
- swix(OS_WriteN, IN(R0|R1), data, size);
- w->changed = 1;
- wimpt_noerr(sprite_restorestate(s));
- }
-
- menu barmenumaker
- ( void *h )
- {
- h=h;
- if ( !event_is_menu_being_recreated() )
- { if ( barmenu )
- menu_dispose( &barmenu, 0 );
- barmenu = menu_new( "VMode", ">Info,NewTasks,Quit" );
- menu_setflags( barmenu, 2, newtasks, 0 );
- }
- return barmenu;
- }
-
- void barmenuproc
- ( void *h, char *hit )
- {
- h=h;
- switch (hit[0])
- { case 1:
- infobox();
- break;
- case 2:
- newtasks = ! newtasks;
- break;
- case 3:
- if ( oktoquit() )
- { while (thewins)
- freewin(thewins);
- exit(0);
- }
- break;
- }
- }
-
- /*
- * Window manipulation
- */
-
- void newtitle
- ( win *w, char *n )
- { wimp_redrawstr r;
- wimp_wstate s;
- strcpy( w->title, n );
- r.w = w->w;
- wimpt_noerr( wimp_getwindowoutline( &r ) );
- wimpt_noerr( wimp_get_wind_state( w->w, &s ) );
- r.w = -1;
- r.box.y0 = s.o.box.y1;
- wimpt_noerr( wimp_force_redraw( &r ) );
- }
-
- void behind
- ( win *w, int where )
- { wimp_wstate s;
- wimpt_noerr( wimp_get_wind_state( w->w, &s ) );
- s.o.behind = where;
- wimpt_noerr( wimp_open_wind( &s.o ) );
- }
-
- void freewin
- ( win *w )
- {
- win **w1;
- if ( w->w )
- { win_register_event_handler( w->w, 0, 0 );
- alarm_removeall( (void *)w );
- wimpt_noerr(wimp_delete_wind(w->w));
- }
- for ( w1=&thewins; *w1!=w; w1=&(*w1)->next )
- if ( !*w1 )
- werr( 1, "Chain of windows broken" );
- if (w->state!=TDEAD)
- { wimp_msgstr msg;
- msg.hdr.action = 0x808c4; /* TaskWindow_Morite */
- msg.hdr.your_ref = 0;
- msg.hdr.size = 20;
- wimpt_noerr( wimp_sendmessage( wimp_ESEND, &msg, w->task ) );
- }
- *w1 = w->next;
- modefree(w);
- free(w);
- }
-
- /*
- * Wimp utility
- */
-
- int confirm
- ( char *s )
- { return dboxquery(s)==dboxquery_YES;
- }
-
- void infobox
- ( void )
- { dbox d;
- d = dbox_new("info");
- dbox_setfield(d, 3, VERSION );
- dbox_show(d);
- dbox_fillin(d);
- dbox_dispose(&d);
- }
-
- /*
- * Safe memory allocation
- */
-
- void *claim
- ( int size )
- { void *p;
- p = malloc( size );
- if ( !p )
- werr( 1, "out of memory" );
- return p;
- }
-
- void *reclaim
- ( void *q, int size )
- { void *p;
- p = realloc( q, size );
- if ( !p )
- werr( 1, "out of memory" );
- return p;
- }
-
- /*
- * Stuff to deal with sending Wimp messages
- */
-
- void reply
- ( wimp_msgstr* msg, int action )
- {
- msg->hdr.your_ref = msg->hdr.my_ref;
- msg->hdr.size = 44 + ( ( strlen( msg->data.datasaveok.name ) + 4 ) & -4 );
- msg->hdr.action = action;
- wimpt_noerr( wimp_sendmessage( wimp_ESEND, msg, msg->hdr.task ) );
- }
-
- void replywantack
- ( wimp_msgstr* msg, int action )
- {
- msg->hdr.your_ref = msg->hdr.my_ref;
- msg->hdr.size = 44 + ( ( strlen( msg->data.datasaveok.name ) + 4 ) & -4 );
- msg->hdr.action = action;
- wimpt_noerr( wimp_sendmessage( wimp_ESENDWANTACK, msg, msg->hdr.task ) );
- }
-
- void send
- ( wimp_msgstr* msg, int action, wimp_w w, wimp_i i )
- {
- msg->hdr.size = 44 + ( ( strlen( msg->data.datasaveok.name ) + 4 ) & -4 );
- msg->hdr.action = action;
- wimpt_noerr( wimp_sendwmessage( wimp_ESEND, msg, w, i ) );
- }
-
- void sendwantack
- ( wimp_msgstr* msg, int action, wimp_w w, wimp_i i )
- {
- msg->hdr.size = 44 + ( ( strlen( msg->data.datasaveok.name ) + 4 ) & -4 );
- msg->hdr.action = action;
- wimpt_noerr( wimp_sendwmessage( wimp_ESENDWANTACK, msg, w, i ) );
- }
-
- void ack
- ( wimp_msgstr* msg )
- {
- msg->hdr.your_ref = msg->hdr.my_ref;
- wimpt_noerr( wimp_sendmessage( wimp_ESEND, msg, msg->hdr.task ) );
- }
-
- void rofprintf
- ( int fh, char *fmt, ... )
- { char buf[256];
- va_list arg;
- _kernel_osgbpb_block b;
- va_start( arg, fmt );
- vsprintf( buf, fmt, arg );
- va_end( arg );
- b.dataptr = buf;
- b.nbytes = strlen( buf );
- if (_kernel_osgbpb( 2, fh, &b )==_kernel_ERROR)
- wimpt_complain( (os_error *)_kernel_last_oserror() );
- }
-
- void strins
- ( char *d, char *s )
- /* Insert string s at the beginning of string d */
- {
- int l=strlen(s);
- int m=strlen(d);
- memmove(&d[l],d,m+1);
- memmove(d,s,l);
- }
-
- char *strdup
- ( char *d )
- {
- int m=strlen(d);
- char *p = claim(m+1);
- if (p)
- strcpy( p, d );
- return p;
- }
-
- char *strjoin
- ( char *s, char *t )
- {
- int m=strlen(s);
- int n=strlen(t);
- char *p = claim( m+n+1 );
- if (p)
- { strcpy( p, s );
- strcpy( p+m, t );
- }
- return p;
- }
-
-