/* * MWB_RESIDENT.C * * *** Must be compiled with LARGE code and data for manx since this code * will be executed directly from a LoadSeg(). Also must compile with * +B (no .begin statement): cc +BCDL * * *** Make no assumptions as to the initial condition of global data. * * signal 0 initial GO signal * signal 1 port signal * */ go() { mwb_resident(); Wait(0); } #include "mwb.h" #include #include typedef struct NewScreen NS; typedef struct Screen SCR; typedef struct NewWindow NW; typedef struct Window WIN; typedef struct IntuitionBase IB; struct TextAttr Ta = { "topaz.font", 8 }; extern char LVOOpenWindow; extern char LVOCloseWindow; long SysBase; IB *IntuitionBase; long oldopenvec; long oldclosevec; short sno; short uca; XPORT *Xport; extern long newopenwindow(), newclosewindow(); mwb_resident() { register XPORT *xport; register XMSG *xmsg; SysBase = *(long *)4; /* Get ExecBase */ sno = 0; uca = 1; Wait(1); /* Wait for 'GO' signal from MWB.C */ Xport = xport = FindPort(PORT_NAME);/* had better exist */ if (xport) { IntuitionBase = (IB *)OpenLibrary("intuition.library", 0); oldopenvec = SetFunction(IntuitionBase, &LVOOpenWindow, newopenwindow); oldclosevec= SetFunction(IntuitionBase, &LVOCloseWindow,newclosewindow); for (;;) { WaitPort(xport); /* wait for message */ xmsg = GetMsg(xport); switch(xmsg->com) { case OP_QUIT: goto done; case OP_CLOSEUNUSED: remscreens(); uca = 1; break; case OP_NEWSCREEN: for (sno = 0; sno < MAXSCREENS; ++sno) { if (xport->xit[sno].screen == 0) { xport->xit[sno] = xmsg->xit; xport->xit[sno].flags |= FL_DEFINED; uca = 0; break; } } break; case OP_SETSCREEN: if (xport->xit[xmsg->screeno].screen) { sno = xmsg->screeno; uca = 0; } break; case OP_STARTUP: break; } xmsg->com = 0; ReplyMsg(xmsg); } done: xmsg->com = remscreens(); SetFunction(IntuitionBase, &LVOOpenWindow, oldopenvec); SetFunction(IntuitionBase, &LVOCloseWindow,oldclosevec); CloseLibrary(IntuitionBase); ReplyMsg(xmsg); Wait(0); } } remscreens() { register XPORT *xport = Xport; register short i; register SCR *scr; short allnotclosed = 0; for (i = 1; i < MAXSCREENS; ++i) { scr = xport->xit[i].screen; if (scr) { if (scr->FirstWindow) { allnotclosed = -1; } else { CloseScreen(scr); xport->xit[i].screen = NULL; xport->xit[i].flags = 0; } } } return(allnotclosed); } /* * LIBRARY INTERCEPT ROUTINES. NOTE!! Called in context of some other * task. NOTE!! re-entrant. */ myopenwindow(nw, cnw) NW *nw, *cnw; { register XPORT *xport = Xport; register XIT *xuse, *xi; SCR *scr; short i; NS Ns; if ((nw->Type & SCREENTYPE) == WBENCHSCREEN) { if (uca) { scr = IntuitionBase->ActiveScreen; for (i = 0; i < MAXSCREENS; ++i) { if (xport->xit[i].screen == scr) { sno = i; break; } } } xi = xuse = &xport->xit[sno]; if (xi->screen == NULL) { if (!(xi->flags & FL_DEFINED)) xuse = &xport->xit[0]; Ns.LeftEdge = Ns.TopEdge = 0; Ns.Width = xuse->width; Ns.Height= xuse->height; Ns.Depth = xuse->depth; Ns.DetailPen = 0; Ns.BlockPen = 1; Ns.ViewModes = xuse->scrmodes|SPRITES; Ns.Type = CUSTOMSCREEN; Ns.Font = &Ta; Ns.DefaultTitle = xport->scrname; Ns.Gadgets = NULL; Ns.CustomBitMap = NULL; xi->screen = OpenScreen(&Ns); } if (xi->screen) { *cnw = *nw; nw = cnw; nw->Type = CUSTOMSCREEN; nw->Screen = xi->screen; } uca = 1; } return(nw); } myclosewindow(win) WIN *win; { return(win); } #asm _newopenwindow: sub.l #64,sp move.l sp,A1 ;pointer to some allocated memory movem.l D2/D3/A4/A6,-(sp) ;save some registers move.l A1,-(sp) ;push ptr to alloc. memory move.l A0,-(sp) ;push passed NW argument jsr _myopenwindow ;call C routine addq.l #8,sp ;pop move.l D0,A0 ;Place return argument into A0 move.l _oldopenvec,A1 ;actual OpenWindow() call movem.l (sp)+,D2/D3/A4/A6 ;restore some registers jsr (A1) ;make call add.l #64,sp ;deallocate allocated stack rts _newclosewindow: movem.l D2/D3/A4/A6,-(sp) move.l A0,-(sp) jsr _myclosewindow ;call with window argument. addq.l #4,sp move.l D0,A0 move.l _oldclosevec,A1 movem.l (sp)+,D2/D3/A4/A6 jmp (A1) #endasm