/* * MAIN.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved. * */ #include "defs.h" #include #include Prototype short Xsize, Ysize; Prototype short XTbase, YTbase; Prototype short Rows, Columns; Prototype short Xbase, Ybase; Prototype short Xpixs, Ypixs; Prototype ubyte *av[]; Prototype char Wdisable; Prototype void ipchandler (void); Prototype void initipc (void); Prototype void do_ipc (void); Prototype void do_iconify (void); Prototype void do_tomouse (void); Prototype void iconify (void); Prototype void uniconify (void); Prototype void do_newwindow (); Prototype void do_openwindow(); Prototype struct Window *TOpenWindow (struct NewWindow *); Prototype struct Window *opensharedwindow (struct NewWindow *); Prototype void closesharedwindow (struct Window *); Prototype int getyn (char *); Prototype void title (char *); Prototype void window_title (void); Prototype void set_window_params (void); Prototype void exiterr (char *); Prototype int breakcheck (void); Prototype void breakreset (void); Prototype void do_resize (void); Prototype int ops (char **, int); typedef struct Process PROC; typedef struct WBStartup WBS; typedef struct DiskObject DISKOBJ; #define IDCMPFLAGS CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE|MENUPICK extern void GeometryToNW(char *, struct NewWindow *); extern WIN *OpenWindow(); extern void *OpenLibrary(); extern void *GetDiskObject(); struct NewWindow Nw = { 0, 1, 0 , 0 , -1, -1, /* width, height filled in by program */ IDCMPFLAGS, ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP, NULL, NULL, (ubyte *)" WAIT ", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN }; short Sharedrefs; short Oldtlen = 999; /* Old Title Length */ struct MsgPort *Sharedport; static DISKOBJ *Do; WBS *Wbs; short Xsize, Ysize; /* font character sizes */ short Rows, Columns; /* character rows/cols available */ short Xbase, Ybase; /* offset pixel base for display */ short XTbase,YTbase; /* used for text display */ short Xpixs, Ypixs; /* actual # X/Y pixels available */ short Mx, My; ubyte *av[8]; char Quitflag; char Overide; char Wdisable = 1; /* Disable icon save */ char MShowTitle, MForceTitle; #ifdef NOTDEF PORT *IPCPort; #endif PORT *IPCRPort; long Mask; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Library *IconBase; extern int Enable_Abort; static char *Ffile; int main(int, char **); int wbmain(wbs) WBS *wbs; { return(main(0, wbs)); } int main(mac, mav) int mac; char **mav; { char nf, ni; /* # files on command line */ char notdone; /* for endless loop */ char iawm = 0; /* overide mouse buttons */ char dontwait = 0; /* don't wait for a message */ short i; short Code; PROC *proc = (PROC *)FindTask(NULL); BPTR origlock; fclose(stdin); /*fclose(stdout);*/ /* assume person will run >nil: */ fclose(stderr); /* close stderr & console ref. */ origlock = CurrentDir(DupLock((BPTR)proc->pr_CurrentDir)); NewList((LIST *)&DBase); NewList((LIST *)&PBase); IntuitionBase = OpenLibrary("intuition.library", 0); GfxBase = OpenLibrary("graphics.library", 0); if (IntuitionBase == (void *)NULL || GfxBase == (void *)NULL) exiterr("cannot open intuition or graphics library"); init_command(); String = (char *)malloc(1); /* initialize scanf variable */ *String = 0; if (mac == 0) { /* WORKBENCH STARTUP */ Wdisable = 0; /* allow icon save */ Wbs = (WBS *)mav; IconBase = OpenLibrary("icon.library", 0); if (IconBase == NULL) exiterr("unable to open icon library"); } #if AREXX { mountrequest(0); openrexx(); /* do this after the last possible call to exiterr() */ mountrequest(1); } #endif resethash(); if (Wbs) { if (Wbs->sm_ArgList[0].wa_Lock) { BPTR savelock = CurrentDir((BPTR)Wbs->sm_ArgList[0].wa_Lock); if (Do = GetDiskObject(Wbs->sm_ArgList[0].wa_Name)) { ops(Do->do_ToolTypes, 1); FreeDiskObject(Do); } CurrentDir(savelock); } nf = Wbs->sm_NumArgs - 1; mac = 99; } else { nf = ops(mav+1, 0); } for (ni = 0, i = 1; i < mac; ++i) { char *str; DISKOBJ *dso; if (Wbs) { if (i > nf) break; str = Wbs->sm_ArgList[i].wa_Name; UnLock(CurrentDir(DupLock((BPTR)Wbs->sm_ArgList[i].wa_Lock))); if (dso = GetDiskObject(Wbs->sm_ArgList[i].wa_Name)) { ops(dso->do_ToolTypes, 1); FreeDiskObject(dso); } } else { str = mav[i]; if (*str == '-') continue; } do_newwindow(); ++ni; av[0] = (ubyte *)"newfile"; av[1] = (ubyte *)str; do_edit(); MForceTitle = 1; window_title(); } if (nf == 0) /* no files to edit */ do_newwindow(); mountrequest(0); av[0] = NULL; av[1] = (ubyte *)"s:.edrc"; do_source(); av[0] = NULL; av[1] = (ubyte *)((Ffile) ? Ffile : ".edrc"); do_source(); mountrequest(1); { /* 1.29c */ ED *ep; ED *eb = Ep; if (eb) { for (ep = (ED *)eb->Node.mln_Succ; ep->Node.mln_Succ; ep = (ED *)ep->Node.mln_Succ) { ep->Tabstop = eb->Tabstop; ep->Margin = eb->Margin; ep->Insertmode = eb->Insertmode; ep->IgnoreCase = eb->IgnoreCase; ep->Wordwrap = eb->Wordwrap; if (eb->Font) { ep->Font = eb->Font; ++eb->Font->tf_Accessors; } } } } title("DME V1.43 \251Copyright 1988-1990 by Matthew Dillon, All Rights Reserved "); Mask |= 1 << Ep->Win->UserPort->mp_SigBit; loop: if (!Ep->iconmode) text_cursor(1); for (notdone = 1; !Quitflag && notdone;) { char mmove = 0; short mqual; if (!Ep->iconmode) window_title(); if (dontwait) { --dontwait; } else { Wait(Mask); } /* * NOTE: due to operation of breakcheck(), the userport signal * may not be set even if there are messages pending. */ { IMESS *im; while (im = (IMESS *)GetMsg(Ep->Win->UserPort)) { Msgchk = 1; Abortcommand = 0; Code = im->Code; if (im->IDCMPWindow != Ep->Win) { Overide = 0; if (Comlinemode) escapecomlinemode(); text_sync(); MShowTitle = 0; if (!Ep->iconmode) window_title(); if (text_switch(im->IDCMPWindow) == 0) { ReplyMsg((MSG *)im); continue; } } Mx = im->MouseX; My = im->MouseY; switch(im->Class) { case NEWSIZE: if (!Ep->iconmode) { if (Comlinemode) escapecomlinemode(); set_window_params(); if (!text_sync()) text_redisplay(); text_cursor(1); } break; case MOUSEBUTTONS: switch(Code) { case SELECTDOWN: case MENUDOWN: if (Ep->iconmode || iawm) { uniconify(); break; } Forbid(); Ep->Win->Flags |= REPORTMOUSE; Permit(); uniconify(); text_cursor(0); keyctl(NULL, im->Code|0x80, im->Qualifier); text_cursor(1); break; case SELECTUP: case MENUUP: Forbid(); Ep->Win->Flags &= ~REPORTMOUSE; Permit(); break; } break; case RAWKEY: if ((im->Code & 0x80) == 0) { /* Handled in command interpreter. if (Ep->iconmode) { uniconify(); break; } */ text_cursor(0); keyctl(im, im->Code, im->Qualifier); text_cursor(1); } break; case MENUPICK: { char *str = menu_cmd(im); if (str) { str = strcpy(malloc(strlen(str)+1), str); text_cursor(0); do_command(str); free(str); text_cursor(1); } } break; case CLOSEWINDOW: if (Comlinemode) escapecomlinemode(); text_sync(); notdone = 0; break; case ACTIVEWINDOW: if (!Ep->iconmode) iawm = 1; break; case MOUSEMOVE: mmove = 1; mqual = im->Qualifier; break; } if (im) ReplyMsg((MSG *)im); if (notdone == 0 || Quitflag) { dontwait = 2; goto boom; } } } iawm = 0; if (mmove) { uniconify(); mmove = 0; text_cursor(0); keyctl(NULL, QMOVE, mqual); text_cursor(1); } closesharedwindow(NULL); } boom: text_sync(); if (Ep->Modified && !Overide) { uniconify(); Overide = 1; title("*** File has been modified ***"); Quitflag = 0; goto loop; } SetWindowTitles(Ep->Win, "", (char *)-1); { WIN *win = Ep->Win; text_uninit(); closesharedwindow(win); } if (Ep) { Quitflag = 0; if (!Ep->iconmode) set_window_params(); text_load(); MShowTitle = 0; goto loop; } closesharedwindow(NULL); #if AREXX closerexx(); #endif UnLock(CurrentDir(origlock)); if (IPCRPort) DeletePort(IPCRPort); if (IconBase) CloseLibrary(IconBase); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); IconBase = GfxBase = IntuitionBase = 0; dealloc_hash(); return(0); } void do_iconify() { text_sync(); if (!Comlinemode) iconify(); } void do_tomouse() { text_position((Mx-Xbase)/Xsize, (My-Ybase)/Ysize); } void iconify() { WIN *newwin; ED *ep = Ep; WIN *win = ep->Win; if (!ep->iconmode) { ep->Winx = win->LeftEdge; ep->Winy = win->TopEdge; ep->Winwidth = win->Width; ep->Winheight = win->Height; Nw.Height = win->RPort->TxHeight + 3; Nw.Width = 20 + 5*8 + strlen(ep->Name) * (win->RPort->TxWidth + win->RPort->TxSpacing); if (ep->Modified) Nw.Width -= 3*8; Nw.LeftEdge= ep->IWinx; Nw.TopEdge = ep->IWiny; if (Nw.LeftEdge + Nw.Width > win->WScreen->Width) Nw.LeftEdge = win->WScreen->Width - Nw.Width; if (Nw.TopEdge + Nw.Height > win->WScreen->Height) Nw.TopEdge = win->WScreen->Height - Nw.Height; Nw.Title = ep->Wtitle; Nw.Flags &= ~(WINDOWSIZING|WINDOWDEPTH|ACTIVATE); if (ep->Modified) Nw.Flags &= ~WINDOWCLOSE; Nw.Flags |= BORDERLESS; Nw.DetailPen = ep->BGPen; Nw.BlockPen = ep->FGPen; if (win->Flags & WINDOWACTIVE) /* KTS */ Nw.Flags |= ACTIVATE; sprintf(ep->Wtitle, "%s ", ep->Name); if (newwin = opensharedwindow(&Nw)) { closesharedwindow(win); Nw.BlockPen = -1; ep->iconmode = 1; ep->Win = newwin; } Nw.Flags |= WINDOWSIZING|WINDOWDEPTH|WINDOWCLOSE|ACTIVATE; Nw.Flags &= ~BORDERLESS; } } void uniconify() { ED *ep = Ep; WIN *win = ep->Win; WIN *newwin; RP *rp; if (ep->iconmode) { ep->IWinx = win->LeftEdge; ep->IWiny = win->TopEdge; Nw.LeftEdge = ep->Winx; Nw.TopEdge = ep->Winy; Nw.Width = ep->Winwidth; Nw.Height = ep->Winheight; Nw.Title = ep->Wtitle; Nw.DetailPen = ep->BGPen; Nw.BlockPen = ep->FGPen; if (newwin = opensharedwindow(&Nw)) { closesharedwindow(win); win= ep->Win = newwin; rp = win->RPort; menu_strip(win); if (ep->Font) SetFont(rp, ep->Font); set_window_params(); if (!text_sync()) text_redisplay(); text_cursor(1); MShowTitle = 0; window_title(); ep->iconmode = 0; } } } void do_newwindow() { WIN *win; if (Ep) text_sync(); Nw.Title = (ubyte *)" OK "; if (text_init(Ep, NULL, &Nw)) { if (win = opensharedwindow(&Nw)) { menu_strip(win); Ep->Win = win; set_window_params(); text_load(); } else { text_uninit(); } } } /* * openwindow with geometry specification. Negative number specify * relative-right / relative-left (leftedge & topedge), or relative-width / * relative height (width & height). * * * * Example: +10+10-20-20 Open window centered on screen 10 pixels * from the border on all sides. */ void do_openwindow() { WIN *win; if (Ep) text_sync(); Nw.Title = (ubyte *)" OK "; if (text_init(Ep, NULL, &Nw)) { GeometryToNW(av[1], &Nw); if (win = opensharedwindow(&Nw)) { menu_strip(win); Ep->Win = win; set_window_params(); text_load(); } else { text_uninit(); } } } WIN * TOpenWindow(nw) struct NewWindow *nw; { WIN *win; while ((win = OpenWindow(nw)) == NULL) { if (nw->Width < 50 || nw->Height < 50) break; nw->Width -= 10; nw->Height-= 10; } return(win); } WIN * opensharedwindow(nw) struct NewWindow *nw; { WIN *win; if (Sharedport) nw->IDCMPFlags = NULL; else nw->IDCMPFlags = IDCMPFLAGS; win = TOpenWindow(nw); if (win) { long xend = win->Width - win->BorderRight - 1; long yend = win->Height- win->BorderBottom - 1; if (Sharedport) { win->UserPort = Sharedport; ModifyIDCMP(win, IDCMPFLAGS); } else { Sharedport = win->UserPort; } ++Sharedrefs; if (xend > win->BorderLeft && yend > win->BorderTop) { SetAPen(win->RPort, nw->DetailPen); RectFill(win->RPort, win->BorderLeft, win->BorderTop, xend, yend); SetAPen(win->RPort, nw->BlockPen); } } return(win); } void closesharedwindow(win) WIN *win; { static WIN *wunlink; char notoktoclosenow = 0; if (win) { SetWindowTitles(win, "", (char *)-1); ClearMenuStrip(win); Forbid(); win->UserPort = NULL; ModifyIDCMP(win, GADGETUP); /* NEVER occurs */ notoktoclosenow = 1; Permit(); if (notoktoclosenow) { win->UserData = (char *)wunlink; wunlink = win; } else { CloseWindow(win); } --Sharedrefs; } else { if (Sharedrefs == 0 && Sharedport) { DeletePort(Sharedport); Sharedport = NULL; } for (win = wunlink; win; win = wunlink) { wunlink = (WIN *)win->UserData; CloseWindow(win); } wunlink = NULL; } } getyn(text) char *text; { int result; ITEXT *body, *pos, *neg; body = (ITEXT *)AllocMem(sizeof(ITEXT), 0); pos = (ITEXT *)AllocMem(sizeof(ITEXT), 0); neg = (ITEXT *)AllocMem(sizeof(ITEXT), 0); clrmem(body, sizeof(ITEXT)); clrmem(pos , sizeof(ITEXT)); clrmem(neg , sizeof(ITEXT)); body->BackPen = pos->BackPen = neg->BackPen = 1; body->DrawMode= pos->DrawMode= neg->DrawMode= AUTODRAWMODE; body->LeftEdge = 10; body->TopEdge = 12; body->IText = (ubyte *)text; pos->LeftEdge = AUTOLEFTEDGE; pos->TopEdge = AUTOTOPEDGE; pos->IText = (ubyte *)"OK"; neg->LeftEdge = AUTOLEFTEDGE; neg->TopEdge = AUTOTOPEDGE; neg->IText = (ubyte *)"CANCEL"; result = AutoRequest(Ep->Win,body,pos,neg,0,0,320,58); FreeMem(body, sizeof(ITEXT)); FreeMem(pos , sizeof(ITEXT)); FreeMem(neg , sizeof(ITEXT)); return(result); } void title(buf) char *buf; { SetWindowTitles(Ep->Win, buf, (char *)-1); Oldtlen = 999; MShowTitle = 3; } void window_title() { int len, maxlen; if (memoryfail) { title(" -- NO MEMORY -- "); memoryfail = 0; text_redisplay(); } if (MForceTitle) { MShowTitle = 0; MForceTitle = 0; } if (MShowTitle) { --MShowTitle; return; } { char *mod; FONT *oldfont; ED *ep = Ep; WIN *win = ep->Win; RP *rp = win->RPort; mod = (ep->Modified) ? " (modified)" : " "; sprintf(ep->Wtitle, "%3ld/%-3ld %3ld %s%s ", text_lineno(), text_lines(), text_colno()+1, text_name(), mod); if (!text_imode()) strcat(ep->Wtitle, "Ovr "); len = strlen(ep->Wtitle); if (len < Columns && Columns < 128) { setmem(ep->Wtitle+len, Columns - len + 1, ' '); ep->Wtitle[Columns + 1] = 0; } /* * Update title */ oldfont = win->RPort->Font; SetFont(rp, win->WScreen->RastPort.Font); win->Title = ep->Wtitle; SetAPen(rp, ep->FGPen); SetBPen(rp, ep->TPen); Move(rp, 30, rp->Font->tf_Baseline+1); maxlen = (win->Width-96)/rp->Font->tf_XSize; if (maxlen < 0) maxlen = 0; if (len > maxlen) len = Oldtlen = maxlen; if (Oldtlen > maxlen) Oldtlen = maxlen; Text(rp, ep->Wtitle, len); /* No flash */ while (Oldtlen - len >= (int)sizeof(Space)) { Text(rp, Space, sizeof(Space)); Oldtlen -= sizeof(Space); } if (Oldtlen - len > 0) Text(rp, Space, Oldtlen - len); Oldtlen = len; /* Oldtlen might have been < */ SetAPen(rp, ep->FGPen); SetBPen(rp, ep->BGPen); SetFont(rp, oldfont); } } void set_window_params() { ED *ep = Ep; WIN *win = ep->Win; RP *rp = win->RPort; Xsize = rp->Font->tf_XSize; Ysize = rp->Font->tf_YSize; Xbase = win->BorderLeft; Ybase = win->BorderTop; Xpixs = win->Width - win->BorderRight - Xbase; Ypixs = win->Height- win->BorderBottom- Ybase; Columns = Xpixs / Xsize; Rows = Ypixs / Ysize; XTbase = Xbase; YTbase = Ybase + rp->Font->tf_Baseline; SetAPen(rp, ep->FGPen); SetBPen(rp, ep->BGPen); } void exiterr(str) char *str; { if (Output()) { Write(Output(),str,strlen(str)); Write(Output(),"\n",1); } exit(1); } /* * Check break by scanning pending messages in the I stream for a ^C. * Msgchk forces a check, else the check is only made if the signal is * set in the I stream (the signal is reset). */ breakcheck() { IMESS *im; WIN *win = Ep->Win; struct List *list = &win->UserPort->mp_MsgList; if (Msgchk || (SetSignal(0,0) & (1<UserPort->mp_SigBit))) { Msgchk = 0; SetSignal(0,1<UserPort->mp_SigBit); im = (IMESS *)list->lh_Head; Forbid(); for (; im != (IMESS *)&list->lh_Tail; im = (IMESS *)im->ExecMessage.mn_Node.ln_Succ) { if (im->Class == RAWKEY && (im->Qualifier & 0xFB) == 0x08 && im->Code == CtlC) { Permit(); SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C); return(1); } } Permit(); } return(0); } void breakreset() { SetSignal(0, SIGBREAKF_CTRL_C); } /* * resize cols rows */ void do_resize() { WIN *win = Ep->Win; int cols = atoi(av[1]); int rows = atoi(av[2]); short width = (cols*win->RPort->Font->tf_XSize) + win->BorderLeft + win->BorderRight; short height= (rows*win->RPort->Font->tf_YSize) + win->BorderTop + win->BorderBottom; if (width < 16 || height < 16 || width > win->WScreen->Width - win->LeftEdge || height > win->WScreen->Height - win->TopEdge) { title ("window too big (try moving to upper left corner and retrying)"); return; } SizeWindow(win, width - win->Width, height - win->Height); Delay(50*2); /* wait 2 seconds */ } ops(av, iswb) char **av; { short nonops; short i; long val; char *str; for (i = nonops = 0; str = av[i]; ++i) { if (iswb) { if (strncmp(str, "ARG", 3) == 0) { while (*str && *str != '-') ++str; } } if (*str == '-') { val = atoi(str+2); switch(str[1]) { case 'f': Ffile = str+2; break; case 'b': /*SizeOveride = 1;*/ break; case 't': /*Nwtopedge = val;*/ break; case 'l': /*Nwleftedge= val;*/ break; case 'w': /*SizeOveride = 1;*/ /*Nwwidth = val;*/ break; case 'h': /*SizeOveride = 1;*/ /*Nwheight = val;*/ break; } } else { ++nonops; } } return((int)nonops); } /* * Convert geometry to nw params. */ char * geoskip(ptr, pval, psgn) char *ptr; int *pval; int *psgn; { if (*ptr == '-') *psgn = -1; else *psgn = 1; if (*ptr == '-' || *ptr == '+') ++ptr; *pval = atoi(ptr); while (*ptr >= '0' && *ptr <= '9') ++ptr; return(ptr); } void GeometryToNW(geo, nw) char *geo; struct NewWindow *nw; { int n; int sign; struct Screen scr; GetScreenData(&scr, sizeof(scr), WBENCHSCREEN, NULL); if (*geo) { geo = geoskip(geo, &n, &sign); if (sign > 0) nw->LeftEdge = n; else nw->LeftEdge = scr.Width - n; } if (*geo) { geo = geoskip(geo, &n, &sign); if (sign > 0) nw->TopEdge = n; else nw->TopEdge = scr.Height - n; } if (*geo) { geo = geoskip(geo, &n, &sign); if (sign > 0) nw->Width = n; else nw->Width = scr.Width - nw->LeftEdge - n; } if (*geo) { geo = geoskip(geo, &n, &sign); if (sign > 0) nw->Height = n; else nw->Height = scr.Height - nw->TopEdge - n; } }