/* * This file sends out REXX commands. Now we start to get into * the fun stuff. Actually, it's pretty straightforward, from * the TeX information. * * For now, we do a no-no; we open and close the emacs port. * Actually, this is probably fine, as we only expect REXX to * send us messages in response to our messages. * * The first thing we do is set up a cliplist variable called * mg. */ #include "exec/ports.h" #include "functions.h" #include "fcntl.h" #include "rexx/storage.h" /* * This is a hack. */ #undef TRUE #undef FALSE #undef VOID #include "def.h" extern BUFFER *curbp ; extern WINDOW *curwp ; struct MsgPort *mgport, *rport ; long waitbits ; struct REXXmsg { struct Message msgheader ; long *RexxTask, *LibBase ; long Command, Result1, Result2 ; char *Arg0, *Arg1, *Arg2 ; /* The rest we really don't care about */ char *Args[13] ; void *PassPort, *CommAddr, *FileExt ; long Stdin, Stdout, avail ; } *REXXmsg, setCmsg ; /* * This routine dispatches any REXX messages coming * in. We simply call our brand new fancy parsing * routine! (Getting some of those strings right * might be fun, though . . .) */ mgdisp() { register char *p ; while (REXXmsg = (struct REXXmsg *)GetMsg(mgport)) { ewprintf(REXXmsg->Arg0) ; REXXmsg->Result1 = (excline(REXXmsg->Arg0) == TRUE ? 0 : 1) ; REXXmsg->Result2 = 0 ; ReplyMsg(REXXmsg) ; } } openmsgs() { Forbid() ; if (FindPort("mg")==NULL) mgport = CreatePort("mg", 0L) ; Permit() ; REXXmsg = NULL ; rport = CreatePort("mg:reply", 0L) ; } closemsgs() { if (mgport) { FreeSignal((long)(mgport->mp_SigBit)) ; RemPort(mgport) ; mgdisp() ; DeletePort(mgport) ; } if (rport) { FreeSignal((long)(rport->mp_SigBit)) ; RemPort(rport) ; DeletePort(rport) ; } } struct MsgPort *rexxport ; poststring(n,s) char *n, *s ; { setCmsg.Arg0 = n ; setCmsg.Arg1 = s ; setCmsg.Arg2 = (char *)(long)strlen(s) ; setCmsg.Command = RXADDCON ; setCmsg.msgheader.mn_Node.ln_Type = NT_MESSAGE ; setCmsg.msgheader.mn_ReplyPort = rport ; Forbid() ; rexxport = FindPort("REXX") ; if (rexxport) { PutMsg(rexxport, &setCmsg) ; } Permit() ; if (rexxport) { WaitPort(rport) ; GetMsg(rport) ; } } int pendingrexx ; rexxcommand(f, n, k) { register BUFFER *bp; int s; char cmd[120]; if (pendingrexx) return(FALSE) ; pendingrexx = 1 ; openmsgs() ; if (rport == NULL || mgport == NULL) goto failure ; /* * Now we tell everyone the name of the file we are editing, * if any. */ poststring("mg.BufferName", ((curbp && curbp->b_fname[0]) ? curbp->b_bname : "")) ; /* * Now, finally, we send out the message to the REXX port. */ if ((s=ereply("REXX command: ", cmd, 120)) != TRUE) goto sfailure ; setCmsg.Arg0 = cmd ; setCmsg.Arg1 = (char *)(long)strlen(setCmsg.Arg0) ; setCmsg.Command = RXCOMM | RXFB_TOKEN | RXFB_NOIO ; setCmsg.FileExt = "mg" ; setCmsg.CommAddr = "mg" ; setCmsg.msgheader.mn_Node.ln_Type = NT_MESSAGE ; setCmsg.msgheader.mn_ReplyPort = rport ; Forbid() ; rexxport = FindPort("REXX") ; if (rexxport) { PutMsg(rexxport, &setCmsg) ; } Permit() ; if (! rexxport) goto failure ; /* * Now we iterate, waiting until we get the correct message. */ waitbits = (1L << rport->mp_SigBit) | (1L << mgport->mp_SigBit) ; while (1) { Wait(waitbits) ; mgdisp() ; if (GetMsg(rport)) { s = (setCmsg.Result1 ? FALSE : TRUE) ; goto sfailure ; } } failure: s = FALSE ; sfailure: /* * Here we clean up by closing down and deleting the ports. */ closemsgs() ; pendingrexx = 0 ; return(s) ; } static char *rline(p) struct LINE *p ; { p->l_text[p->l_used] = 0 ; return(p->l_text) ; } static char *rint(i) short i ; { static char temp[8] ; char *p ; p = temp + 7 ; *p-- = 0 ; do { *p = ( i % 10 ) + '0' ; i = i / 10 ; p-- ; } while (i != 0) ; return(p+1) ; } publishline() { if (! curbp) return(FALSE) ; if (! pendingrexx) openmsgs() ; if (rport == NULL || mgport == NULL) { closemsgs() ; return(FALSE) ; } if (curwp->w_dotp) { poststring("mg.DotLine", rline(curwp->w_dotp)) ; poststring("mg.DotPos", rint(curwp->w_doto)) ; } else { poststring("mg.DotLine", "") ; poststring("mg.DotPos", "") ; } /* if (curwp->w_markp) { poststring("mg.MarkLine", rline(curwp->w_markp)) ; poststring("mg.MarkPos", rint(curwp->w_marko)) ; } else { poststring("mg.MarkLine", "") ; poststring("mg.MarkPos", "") ; } */ if (! pendingrexx) closemsgs() ; return(TRUE) ; } extern struct Window *EmW ; windowfront() { if (EmW) WindowToFront(EmW) ; return(TRUE) ; } windowback() { if (EmW) WindowToBack(EmW) ; return(TRUE) ; } /* * Bump our priority by 2. (Editors are important!) */ static int oprior ; bumpprior() { struct Task *task ; task = FindTask(0L) ; oprior = task->tc_Node.ln_Pri ; SetTaskPri(task, (long)(2+oprior)) ; } unbumpprior() { struct Task *task ; task = FindTask(0L) ; SetTaskPri(task, (long)oprior) ; }