#include "globals.h" #include "minrexx.h" #include "NewARexxWdw.h" extern struct RxsLib *RexxSysBase; struct RexxMsg *LinerRexxMsg; int LinerDispatch(); extern void ModSearchWdw(); /*Function definitions private to arexx.c*/ void DoOpen(),DoSave(),DoDoubClick(),DoSetTitleMsg(); void DoGetStats(),DoPrintDisk(),DoGetChar(),DoGetWord(),DoGetLineText(); void DoCursorRight(),DoCursorLeft(),DoDoubSpacing(),DoInterlaced(); void DoIcons(),DoScrnSize(),DoStartingLevel(),DoLoadPrefs(),DoARexxSearch(); void DoInsertText(); void DoGetLine(),DoStartLine(),DoEndLine(),DoPushIn(),DoPullOut(); void DoFakeReturn(),SpecReplyToRexx(); void DoGetFilename(),DoPutPrefs(),DoExtendedModes(); struct rexxCommandList rcl[]= /*The list of all the ARexx commands and*/ { /*their associated functions*/ { "open" , (APTR)&DoOpen}, { "save" , (APTR)&DoSave}, { "getfilename" , (APTR)&DoGetFilename}, { "new" , (APTR)&NewAll}, { "printprinter", (APTR)&HandlePrintPrinter}, { "printdisk" , (APTR)&DoPrintDisk}, { "quit" , (APTR)&CloseStuff }, { "doubclick" , (APTR) &DoDoubClick}, { "settitlemsg" , (APTR) &DoSetTitleMsg}, { "getstats" , (APTR) &DoGetStats}, { "getchar" , (APTR) &DoGetChar}, { "getword" , (APTR) &DoGetWord}, { "getlinetext" , (APTR) &DoGetLineText}, { "cut" , (APTR) &HandleCut}, { "copy" , (APTR) &HandleCopy}, { "paste" , (APTR) &HandlePaste}, { "erase" , (APTR) &HandleErase}, { "cursorup" , (APTR) &CursorUp}, { "cursordown" , (APTR) &CursorDown}, { "cursorright" , (APTR) &DoCursorRight}, { "cursorleft" , (APTR) &DoCursorLeft}, { "totop" , (APTR) &JumpToTop}, { "tobottom" , (APTR) &JumpToBottom}, { "upscreen" , (APTR) &WholeScreenUp}, { "downscreen" , (APTR) &WholeScreenDown}, { "doubspacing" , (APTR) &DoDoubSpacing}, { "interlaced" , (APTR) &DoInterlaced}, { "extmodes" , (APTR) &DoExtendedModes}, { "icons" , (APTR) &DoIcons }, { "scrnsize" , (APTR)&DoScrnSize}, { "startinglevel" , (APTR)&DoStartingLevel}, { "loadprefs" , (APTR)&HandleReloadPrefs}, { "sveprefs" , (APTR)&DoPutPrefs}, { "search" , (APTR)&DoARexxSearch}, { "instext" , (APTR)&DoInsertText}, { "getline" , (APTR)&DoGetLine}, { "fakereturn" , (APTR)&DoFakeReturn}, { "fakebs" , (APTR)&HandleBS}, { "pushin" , (APTR)&DoPushIn}, { "pullout" , (APTR)&DoPullOut}, { "startline" , (APTR)&DoStartLine}, { "endline" , (APTR) &DoEndLine}, { NULL , NULL} }; void OpenARexx() /*Open the ARexx port*/ { ARexxSigBit=upRexxPort("liner",rcl,"liner",&LinerDispatch); } void CloseARexx() /*Close the ARexx port*/ { dnRexxPort(); } void CheckRexxPort() /*Check the ARexx port for commands*/ { dispRexxPort(); } int LinerDispatch(msg,rcl,p) /*The minrexx userdisp function*/ struct RexxMsg *msg; struct rexxCommandList *rcl; char *p; { LinerRexxMsg=(struct RexxMsg *)msg; ((int(*)())(rcl->userdata))(p); /*Call the function associated with the */ /*ARexx command received*/ /*If the function is one of those that returns something to ARexx*/ if(stricmp(rcl->name,"open")==0 || stricmp(rcl->name,"printdisk")==0 || stricmp(rcl->name,"getlinetext")==0 || stricmp(rcl->name,"getline")==0 || stricmp(rcl->name,"getchar")==0 || stricmp(rcl->name,"linersearch")==0 || stricmp(rcl->name,"getstats")==0 || stricmp(rcl->name,"getword")==0 || stricmp(rcl->name,"startinglevel")==0||stricmp(rcl->name,"fakereturn")==0 || stricmp(rcl->name,"pushin") || stricmp(rcl->name,"pullout") || stricmp(rcl->name,"getfilename") || stricmp(rcl->name,"sveprefs") ) return(1); /*Tell minrexx not to replyRexxCmd()*/ else return(0); } void DoOpen(p) /*Open a file under ARexx control*/ char *p; { /*Setup the filename*/ strcpy(FileName,&p[1]); if(ReadItemList(FileName,TRUE)) /*Do the read*/ { Modified=FALSE; TitleErrorCancel(); SplitFilename(FileName,SFileName,SDirName); replyRexxCmd(LinerRexxMsg,0,0,"true"); } else replyRexxCmd(LinerRexxMsg,0,0,"false"); } void DoSave(p) /*Save a file under ARexx*/ char *p; { strcpy(FileName,&p[1]); SplitFilename(FileName,SFileName,SDirName); Save(TRUE); /*Write the file out*/ } void DoGetFilename() { char filename[183]; strcpy(filename,SDirName); if(filename[strlen(filename)-1]!=':' && filename[strlen(filename)-1]!=NULL) strcat(filename,"/"); /*Append a / if not at the root*/ strcat(filename,SFileName); replyRexxCmd(LinerRexxMsg,0,0,filename); } void DoPrintDisk(p) /*Print a file to disk*/ char *p; { SplitFilename(++p,PFileName,PDirName); SpecReplyToRexx(HandlePrintDisk(TRUE,p)); } void DoDoubClick(p) /*Fake a double click (good for highlighting blocks)*/ char *p; { p++; PtrY=CurY; if(stricmp(p,"true")==0) /*if the click is meant to be outside a line*/ PtrX=1; else PtrX=CurX; HandleInvs(); BLastX=CurX; } void DoSetTitleMsg(p) /*Print message in 'p' in title bar*/ char *p; { TitleError(&p[1]); } void DoGetStats() /*Tell ARexx the CurrentItem's level, number, and */ { /*whether or not it's a continuation*/ char buffer1[7]; static char buffer2[12]; stci_d(buffer2,CurrentItem->Level); /*Convert the numbers into text*/ strcat(buffer2," "); stci_d(buffer1,CurrentItem->ItemNumber); strcat(buffer2,buffer1); if(CurrentItem->cont) strcat(buffer2," true"); /*true==continuation*/ else strcat(buffer2," false"); replyRexxCmd(LinerRexxMsg,0,0,buffer2); } void DoGetChar() /*Send the character under the cursor to ARexx*/ { char letter[2]; letter[1]=NULL; letter[0]=CurrentItem->Text[PosInText(CurrentItem->Level)];/*Get the letter*/ replyRexxCmd(LinerRexxMsg,0,0,letter); } void DoGetWord() /*Send the word under the cursor to ARexx*/ { static char result[80]; BYTE c; for(c=0;c<80;result[c++]=NULL); /*Clear the string (weird things happen*/ /*if I don't, and I don't know why...)*/ strcpy(result,""); GetWord(result,CurrentItem); replyRexxCmd(LinerRexxMsg,0,0,result); } void DoGetLineText() /*Send the current line's text to ARexx*/ { static char buffer[100]; strcpy(buffer,CurrentItem->Text); replyRexxCmd(LinerRexxMsg,0,0,buffer); } void DoCursorRight() /*Move the cursor to the right*/ { CursorRight(0); } void DoCursorLeft() /*Move the cursor to the left*/ { CursorLeft(0); } void DoDoubSpacing(p) /*Set the spacing*/ char *p; { p++; if(stricmp(p,"true")==0) /*Set double spacing*/ { if(!prefs.DS) /*If not double spaced*/ { DoubleSpacing(); ModifyMenus(32+StartingLevel); /*Change menus appropriately*/ } } else /*Unset double spacing*/ if(prefs.DS) /*If double spaced*/ { DoubleSpacing(); ModifyMenus(StartingLevel); } } void DoInterlaced(p) /*Determine whether the screen is/isn't interlaced*/ char *p; { p++; if(stricmp(p,"true")==0) switch(prefs.ScreenType) { case HIRES_KEY: prefs.ScreenType=HIRESLACE_KEY; break; case VGAPRODUCT_KEY: prefs.ScreenType=VGAPRODUCTLACE_KEY; } else switch(prefs.ScreenType) { case HIRESLACE_KEY: prefs.ScreenType=HIRES_KEY; break; case VGAPRODUCTLACE_KEY: prefs.ScreenType=VGAPRODUCT_KEY; } PutScreenTypeInMenu(); ChangeDisplay(); } /*Added in 'Liner 2.10: used to choose between screen modes*/ void DoExtendedModes(p) char *p; { p++; switch(*(p+2)) { case '0': prefs.ScreenType |= DEFAULT_MONITOR_ID; break; case '1': prefs.ScreenType |= NTSC_MONITOR_ID; break; case '2': prefs.ScreenType |= PAL_MONITOR_ID; } switch(*p) { case '0': prefs.ScreenType|=HIRES_KEY; break; case '1': prefs.ScreenType|=HIRESLACE_KEY; break; case '2': prefs.ScreenType=VGAPRODUCT_KEY; break; case '3': prefs.ScreenType=VGAPRODUCTLACE_KEY; break; case '4': prefs.ScreenType=A2024TENHERTZ_KEY; break; case '5': prefs.ScreenType=A2024FIFTEENHERTZ_KEY; } PutScreenTypeInMenu(); ChangeDisplay(); } void DoIcons(p) /*Set program to create/not create icons*/ char *p; { p++; prefs.Icons=(stricmp(p,"true")==0); ModifyIconMenu(); } void DoScrnSize(p) /*In pre-2.10 versions of 'Liner, this was used to*/ char *p; /*toggle between standard-sized and workbench-sized */ { /*screens. Under 2.10, it no longer has any meaning,*/ } /*but this routine remains for compatability reasons*/ void DoStartingLevel(p) /*Set the starting level*/ char *p; { int level; p++; p[1]=NULL; stcd_i(p,&level); /*Get the level (as a number)*/ if(level < 0 || level > 5) SpecReplyToRexx(FALSE); if(level == StartingLevel) SpecReplyToRexx(TRUE); if(prefs.DS) /*If double spaced*/ level+=32; /*Alter level for ModifyMenus()*/ ModifyMenus(level); StartingLevel=level; /*Record the new starting level*/ Refresh(); /*And update the display*/ SpecReplyToRexx(TRUE); } Interp(p) /*Used by DoARexxSearch. Determines if a parameter sent by*/ char p; /*ARexx specified setting a search variable to TRUE, FALSE, or*/ { /*leaving it unchanged*/ switch(p) { case 't': case 'T': return(TRUE); case 'f': case 'F': return(FALSE); case 'u': case 'U': return(100); /*Unchanged*/ } return(100); /*If none of the above, something's screwy. Best to not*/ } /*change anything*/ void DoInsertText(p) /*Insert a text string into the line after the cursor*/ char *p; { char WorkString[160]; UBYTE TempX; WorkString[0]=NULL; strcpy(WorkString,CurrentItem->Text); WorkString[PosInText(CurrentItem->Level)]=NULL; strcat(WorkString,&p[1]); strcat(WorkString,&CurrentItem->Text[PosInText(CurrentItem->Level)]); WorkString[MaxLen(CurrentItem->Level)]=NULL; strcpy(CurrentItem->Text,WorkString); TempX=CurX; PlotCursor(1,CurY); PrintItem(CurrentItem); PlotCursor(TempX,CurY); } void DoGetLine() /*Return an entire line to ARexx (incl. line number)*/ { static char buffer[100]; /*static to make sure it doesn't disappear*/ /*before the calling macro has had a chance to chew on it*/ MakeTextLine(buffer,CurrentItem); /*ARexx gets it*/ replyRexxCmd(LinerRexxMsg,0,0,buffer); } void DoFakeReturn(p) /*Let ARexx push the return button (i.e. create a line)*/ char *p; { BYTE stat; p++; if(stricmp(p,"shift")==0 || stricmp(p,"true")==0) stat=HandleReturn(3); else stat=HandleReturn(0); SpecReplyToRexx(stat); } void DoStartLine() { CursorLeft(8); /*Fake a SHIFT-CURSOR-LEFT*/ } void DoEndLine() { CursorRight(8); /*Fake a SHIFT-CURSOR-RIGHT*/ } void DoPushIn() /*Fake a TAB*/ { SpecReplyToRexx(HandleTAB(0)); } void DoPullOut() /*Fake a SHIFT-TAB*/ { SpecReplyToRexx(HandleTAB(3)); } void DoPutPrefs() { SpecReplyToRexx(PutPrefs("liner:liner.prefs",TRUE)); } void SpecReplyToRexx(stat) /*Send a 'true' or 'false' to ARexx*/ BYTE stat; { if(stat) replyRexxCmd(LinerRexxMsg,0,0,"true"); else replyRexxCmd(LinerRexxMsg,0,0,"false"); } void GetWord(result,item) /*Get the word under the cursor*/ char *result; struct LineItem *item; { BYTE start,end,pos; pos=PosInText(CurrentItem->Level); if(pos>=strlen(CurrentItem->Text)) { strcpy(result,""); return; } start=pos; if(pos!=0) { for(start--;CurrentItem->Text[start]!=' ' && start >= 0;start--); start++; } if(CurrentItem->Text[pos]!=NULL) /*Not at the end of the line...*/ for(end=pos;CurrentItem->Text[end]!=' ' && CurrentItem->Text[end]!=NULL; end++); strncpy(result,&CurrentItem->Text[start],end-start); } void EngageMacro(name) /*Start an external ARexx macro ('ENGAGE!' - J-LP :-)*/ char *name; { asyncRexxCmd(name); } void GetMacroInfo() /*Open the window to get the macro names*/ { struct Window *MacroWdw; struct IntuiMessage *mesg; struct Gadget junk,*gadg,*StrStart; struct StringInfo *si; BYTE c; ULONG add; add=Screen->Font->ta_YSize-Topaz.ta_YSize; gadg=(struct Gadget *)MakeButtonGadgets(&junk,ARexxButtons,VisInfo, &Topaz,AREXXBUTTONS,add); MakeStringGadgets(gadg,ARexxStrings,VisInfo,&Topaz,AREXXSTRINGS, ss,add); gadg=StrStart=(struct Gadget *)gadg->NextGadget; for(c=0;c<4;c++,gadg=(struct Gadget *)gadg->NextGadget->NextGadget) { si=(struct StringInfo *)gadg->SpecialInfo; strcpy(si->Buffer,prefs.Macro[c]); si=(struct StringInfo *)gadg->NextGadget->SpecialInfo; strcpy(si->Buffer,prefs.Name[c]); } NewWindowStructure1.Screen=(struct Screen *) Screen; NewWindowStructure1.FirstGadget=(struct Gadget *)junk.NextGadget; /*Make room for title bar*/ NewWindowStructure1.Height+=add; MacroWdw=(struct Window *)OpenWindow(&NewWindowStructure1); if(MacroWdw==NULL) { Leave(0,"Couldn't open the window!"); return; } /*Restore old value*/ NewWindowStructure1.Height-=add; PrintIText(MacroWdw->RPort,&IntuiTextList1,4,4+add); /*Print the text*/ /*Draw some bevel boxes*/ DrawBevelBoxA(MacroWdw->RPort,10,14+add,430,71,&beveltag[0]); DrawBevelBoxA(MacroWdw->RPort,10,88+add,430,25,&beveltag[0]); ActivateGadget(StrStart,MacroWdw,NULL); Wait(1<UserPort->mp_SigBit); /*Wait for a gadget to be*/ /*pressed, or return to be hit while in a string gadget*/ mesg=(struct IntuiMessage *)GetMsg(MacroWdw->UserPort); gadg=(APTR)mesg->IAddress; ReplyMsg(mesg); while(gadg->GadgetID < 9)/*While the gadget is a string gadget*/ { if(gadg->NextGadget != NULL) /*Advance to the next string gadget*/ ActivateGadget(gadg->NextGadget,MacroWdw,NULL); /*(if one exists)*/ /*And wait again...*/ Wait(1<UserPort->mp_SigBit); mesg=(struct IntuiMessage *)GetMsg(MacroWdw->UserPort); gadg=(APTR)mesg->IAddress; ReplyMsg(mesg); } if(gadg->GadgetID == 9) /*OK was pressed*/ { for(gadg=(struct Gadget *)StrStart,c=0;c<4; gadg=(struct Gadget *)gadg->NextGadget->NextGadget,c++) { si=(struct StringInfo *)gadg->SpecialInfo; strcpy(prefs.Macro[c],si->Buffer); si=(struct StringInfo *)gadg->NextGadget->SpecialInfo; strcpy(prefs.Name[c],si->Buffer); } CopyPrefsToMenus(); } CloseWindow(MacroWdw); FreeGadgets(junk.NextGadget); } void SplitFilename(Filename,file,dir) /*Split a full filename into */ char *Filename,*file,*dir; /*path, filename, and extension*/ { char path[150]; char ext[150]; strsfn(Filename,dir,path,file,ext); strcat(dir,path); strcpy(file,&Filename[strlen(dir)+((Filename[strlen(dir)]=='/') ? 1 : 0)]); } void DoARexxSearch(p) /*Do a search/replace*/ char *p; { BYTE cse,partial,repl,c,i,old; char search[80],replace[80]; search[0]=replace[0]=NULL; for(c=0;c<80;search[c++]=NULL) replace[c]=NULL; cse=Interp(p[1]); partial=Interp(p[2]); repl=Interp(p[3]); if(!(p[4]==NULL || p[5]==NULL)) /*If there is a word to search for*/ { /*use it. Otherwise, use what the user has specified*/ for(c=5,i=0;p[c] != NULL && p[c]!=' ';i++,c++); strncpy(search,&p[5],i); if(p[c]!=NULL && p[c+1]!=NULL) { for(old=++c,i=0;p[c]!=NULL && p[c]!=' ';++i,c++); strncpy(replace,&p[old],i); } } /*Set the appropriate search variables*/ ModifyParams(search,replace,cse,partial,repl); ModSearchWdw(); if(DoSearch(TRUE,TRUE)) /*Do the actual search*/ strcpy(search,"true"); else strcpy(search,"false"); /*Give ARexx the result*/ replyRexxCmd(LinerRexxMsg,0,0,search); } /*~~~End of arexx.c*/