/* * MAIN.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved. * */ #include "defs.h" #include #include #include #include #ifdef LATTICE #include int __stdargs CXBRK(void); __stdargs /* bug in lcr.lib */ CXBRK() { return(0); } #endif short Deemu[] = { DMSTRT, 0, 0, DMNW, 0,10,16,16,-32,-40,0xFFFF, DMEND, 0, 0 }; #define DMNWOFF 4 #define IDCMPFLAGS CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE|MENUPICK extern WIN *OpenWindow(); extern char *menu_cmd(); 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; WIN *Win; RP *Rp; 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 SizeOveride; char Wdisable = 1; /* Disable icon save */ char MShowTitle, MForceTitle; short Nwwidth, Nwheight, Nwtopedge, Nwleftedge, Nwtmpwidth, Nwtmpheight; PORT *IPCPort; PORT *IPCRPort; long Mask; extern int Enable_Abort; extern WIN *opensharedwindow(); static char *Ffile; void main ARGS((int, char **)); void 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); long origlock; fclose(stdin); fclose(stdout); fclose(stderr); /* close stderr & console ref. */ origlock = CurrentDir(DupLock(proc->pr_CurrentDir)); NewList((LIST *)&DBase); NewList((LIST *)&PBase); if (!openlibs(INTUITION_LIB|GRAPHICS_LIB)) exiterr("cannot open intuition or graphics library"); #ifndef NODRES initipc(); #endif InitDeemuNW(Deemu+DMNWOFF, &Nw); init_command(); Nwwidth = Nw.Width; /* Parameters for new windows */ Nwheight = Nw.Height; Nwtopedge = Nw.TopEdge; Nwleftedge = Nw.LeftEdge; #ifndef LATTICE Enable_Abort= 0; /* disable break */ #endif String = (char *)malloc(1); /* initialize scanf variable */ *String = 0; if (mac == 0) { /* WORKBENCH STARTUP */ Wdisable = 0; /* allow icon save */ Wbs = (WBS *)mav; if (!openlibs(ICON_LIB)) exiterr("unable to open icon library"); } #if AREXX /* * Alpha 1.4 bug, OpenLibrary() crashes if the library does not exist! */ { extern IBASE *IntuitionBase; /* if (IntuitionBase->LibNode.lib_Version < 36) { */ 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) { long savelock = CurrentDir(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) { register char *str; register DISKOBJ *dso; if (Wbs) { if (i > nf) break; str = Wbs->sm_ArgList[i].wa_Name; UnLock(CurrentDir(DupLock(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(nf > 1, ni * 10); ++ni; av[0] = (ubyte *)"newfile"; av[1] = (ubyte *)str; do_edit(); MForceTitle = 1; window_title(); } if (nf == 0) /* no files to edit */ do_newwindow(nf > 1, ni * 10); 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 */ register ED *ep; register 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.38 \251Copyright 1988 by Matthew Dillon, All Rights Reserved "); Mask |= 1 << 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. * * NOTE2: CheckPort() requires dres.library, which will be loaded * if IPCPort exists because the IPC needs it also. */ #ifndef NODRES if (IPCPort && CheckPort(IPCPort)) ipchandler(); #endif { register IMESS *im; while (im = (IMESS *)GetMsg(Win->UserPort)) { Msgchk = 1; Abortcommand = 0; Code = im->Code; if (im->IDCMPWindow != 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(); Win->Flags |= REPORTMOUSE; Permit(); uniconify(); text_cursor(0); keyctl(NULL, im->Code|0x80, im->Qualifier); text_cursor(1); break; case SELECTUP: case MENUUP: Forbid(); 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: { register 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(Win, "", (char *)-1); text_uninit(); /* uninitialize text portion */ closesharedwindow(Win); if (((ED *)DBase.mlh_Head)->Node.mln_Succ) { Quitflag = 0; Win = Ep->Win; /* make arbitrary other window act. */ Rp = Win->RPort; if (!Ep->iconmode) set_window_params(); text_load(); MShowTitle = 0; goto loop; } closesharedwindow(NULL); #if AREXX closerexx(); #endif UnLock(CurrentDir(origlock)); #ifndef NODRES if (IPCPort) CloseIPC(IPCPort); #endif if (IPCRPort) DeletePort(IPCRPort); closelibs((uword)-1); dealloc_hash(); } #ifndef NODRES void ipchandler() { register IPCMSG *msg; register char *ptr; while (msg = (IPCMSG *)GetMsg(IPCPort)) { register long error = 0; if (ptr = (char *)msg->TBuf) { /* Valid msg, */ register ED *ed; /* For this project */ if (ptr[0] == 0) ed = Ep; else if ((ed = finded(ptr, 0)) == NULL) error = IF_NOTFND; if (ed) { if (ed != Ep) text_switch(ed->Win); if (!Ep->iconmode) text_cursor(0); while (*ptr++); /* Skip Project Name */ do_command(ptr); } } ReplyIPC(msg, NULL, 0, error); } } /* * If it is possible, create an IPC port for DME. IF_ALLOC specifies that * incomming static messages should be re-allocated automatically because * we will be destroying the input buffer for messages we process. */ void initipc() { mountrequest(0); if (openlibs(DRES_LIB)) { mountrequest(1); if (IPCPort = OpenIPC("dme.CMD", IF_ALLOC)) { Mask |= 1 << IPCPort->mp_SigBit; IPCRPort = CreatePort(NULL,0); } } mountrequest(1); } /* * IPC appname projname command */ void do_ipc() { char *buf; char buf2[64]; IPCMSG msg; short len; if (!IPCPort) initipc(); if (!IPCPort) { Abortcommand = 1; title("dres.library not installed"); return; } buf = malloc(len = strlen(av[2])+strlen(av[3])+2); strcpy(buf, av[2]); strcpy(buf+strlen(buf)+1, av[3]); strcpy(buf2, av[1]); strcat(buf2, ".CMD"); msg.Msg.mn_ReplyPort = IPCRPort; msg.TBuf = (APTR)buf; msg.TLen = len; msg.TFlags = IF_NOCOPY; DoIPC2(buf2, &msg, ipchandler, IPCPort); if (msg.RFlags & IF_ERROR) { if (msg.RFlags & IF_NOAPP) title("Application not found"); else title("Remote error"); } FreeIPC(&msg); free(buf); } #endif void do_iconify() { text_sync(); if (!Comlinemode) iconify(); } void do_tomouse() { text_position((Mx-Xbase)/Xsize, (My-Ybase)/Ysize); } void iconify() { WIN *newwin; if (!Ep->iconmode) { Ep->Winx = Win->LeftEdge; Ep->Winy = Win->TopEdge; Ep->Winwidth = Win->Width; Ep->Winheight = Win->Height; Nw.Height = 10; Nw.Width = 20 + 5*8 + strlen(Ep->Name)*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); Nw.Flags |= BORDERLESS; Nw.BlockPen = (Ep->Modified) ? 3 : -1; if (Win->Flags & WINDOWACTIVE) /* KTS */ Nw.Flags |= ACTIVATE; sprintf(Ep->Wtitle, "%s ", Ep->Name); if (newwin = opensharedwindow(&Nw)) { closesharedwindow(Win); Win = Ep->Win = newwin; Nw.BlockPen = -1; Nw.Flags |= WINDOWSIZING|WINDOWDEPTH; Nw.Flags &= ~BORDERLESS; Rp = Win->RPort; Ep->iconmode = 1; } } } void uniconify() { if (Ep->iconmode) { Ep->IWinx = Win->LeftEdge; Ep->IWiny = Win->TopEdge; closesharedwindow(Win); Nw.LeftEdge = Ep->Winx; Nw.TopEdge = Ep->Winy; Nw.Width = Ep->Winwidth; Nw.Height = Ep->Winheight; Nw.Title = Ep->Wtitle; Win = Ep->Win = opensharedwindow(&Nw); menu_strip(Win); Rp = Win->RPort; 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(makesmall, deltaheight) { WIN *win; int msadj = makesmall; if (SizeOveride) msadj = 0; if (Ep) text_sync(); Nw.Title = (ubyte *)" OK "; Nw.Width = (Nwtmpwidth) ? Nwtmpwidth : Nwwidth; Nw.Height= (Nwtmpheight)? Nwtmpheight: Nwheight; Nwtmpwidth = Nwtmpheight = 0; Nw.LeftEdge = Nwleftedge; Nw.TopEdge = Nwtopedge; if (msadj > 0) { /* deltaheight must be valid */ Nw.TopEdge = deltaheight + 16; Nw.LeftEdge= 10*8; Nw.Flags &= ~ACTIVATE; Nw.Width = 40*8; Nw.Height= 10*8; if (Nw.TopEdge + Nw.Height > 200) Nw.TopEdge = deltaheight = 200 - Nw.Height; } win = opensharedwindow(&Nw); menu_strip(win); Nw.Flags |= ACTIVATE; if (win) { Win = win; /* set new window */ Rp = Win->RPort; set_window_params(); text_init(); /* initialize */ text_load(); if (makesmall != -1) /* if deltaheight valid */ Ep->IWiny = deltaheight + 16; } } 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) { if (Sharedport) { win->UserPort = Sharedport; ModifyIDCMP(win, IDCMPFLAGS); } else { Sharedport = win->UserPort; } ++Sharedrefs; } 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); BZero(body, sizeof(ITEXT)); BZero(pos , sizeof(ITEXT)); BZero(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(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(Win, buf, (char *)-1); Oldtlen = 999; MShowTitle = 3; } void window_title() { register int len, maxlen; if (memoryfail) { title(" -- NO MEMORY -- "); memoryfail = 0; text_redisplay(); } if (MForceTitle) { MShowTitle = 0; MForceTitle = 0; } if (MShowTitle) { --MShowTitle; return; } { register char *mod; FONT *oldfont; 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) { BSet(Ep->Wtitle+len, Columns - len + 1, ' '); Ep->Wtitle[Columns + 1] = 0; } /* * Update title */ oldfont = Win->RPort->Font; SetFont(Win->RPort, Win->WScreen->RastPort.Font); Win->Title = Ep->Wtitle; SetAPen(Rp, 0); SetBPen(Rp, Win->BlockPen); Move(Rp, 30, Win->RPort->Font->tf_Baseline+1); maxlen = (Win->Width-96)/Win->RPort->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, 1); SetBPen(Rp, 0); SetFont(Win->RPort, oldfont); } } void set_window_params() { 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; } 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; register 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); } /* * leftedge n * topedge n * width n * height n * tmpwidth n * tmpheight n */ void do_windowparm() { int val = atoi(av[1]); if (av[0][0] == 't' && av[0][1] == 'm') { /* tmpwidth/tmpheight */ if (av[0][3] == 'w') Nwtmpwidth = val; if (av[0][3] == 'h') Nwtmpheight= val; return; } switch(av[0][0]) { case 'l': Nwleftedge = val; break; case 't': Nwtopedge = val; break; case 'w': Nwwidth = val; break; case 'h': Nwheight = val; break; } } /* * resize cols rows */ void do_resize() { 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) register char *av[]; { register short nonops; register short i; register long val; register 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); }