/**************************************************************************** Steal.c This file contains the main definitions of Steal 1.1 by Rick van Rein. Please, do not be shocked at the sight FiniteStateMachine (); Those goto's are the logical implementation of a finite state machine; This is also structured programming, only different from the conventional way. I thought it would suit answering to Intuition's messages better. Rick van Rein, November 4, 1990 ****************************************************************************/ #include #include #include #include #include int OpenPrintFile (); void ClosePrintFile (); void mprintf (); /* The routines that perform the real action of stealing: */ int PrintScreen (); int PrintWindow (); int PrintMenu (); int PrintGadget (); struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Window *win; struct Image *StdCheckMark; /* For reference by the Print module */ static struct TextAttr StdTextAttr= { (UBYTE *) "topaz.font", 8, FS_NORMAL, NULL }; struct TextFont *StdFont; /* For ALL IntuiTexts; contains Topaz 8. Use it! */ static struct IntuiMessage *LastIntuiMessage=NULL; #define TOTALIDCMP ( GADGETUP | GADGETDOWN | CLOSEWINDOW | INACTIVEWINDOW ) #define BLUE_0 0 #define WHITE_1 1 #define BLACK_2 2 #define ORANGE_3 3 SHORT xy0 []= { 5,12, 634,12, 634,61, 5,61, 5,12 }; struct Border bor0= /* Inner border for Window */ { -100,-22, /* LeftEdge,TopEdge */ ORANGE_3,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 5, /* Count */ xy0, /* XY */ NULL /* NextBorder */ }; SHORT xy1 []= { -4,-3, 448,-3, 448,14, -4,14, -4,-3 }; struct Border bor1= { -80,-2, /* LeftEdge,TopEdge */ ORANGE_3,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 5, /* Count */ xy1, /* XY */ &bor0 /* NextBorder */ }; SHORT xy2 []= { -1,-1, 445,-1, 445,12, -1,12, -1,-1 }; struct Border bor2= { -80,-2, /* LeftEdge,TopEdge */ WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 5, /* Count */ xy2, /* XY */ &bor1 /* NextBorder */ }; struct IntuiText itx1= { WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ -76,0, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "FileName:", /* IText */ NULL /* NextText */ }; struct IntuiText itx2= { BLACK_2,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ -75,1, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "FileName:", /* IText */ &itx1 /* NextText */ }; char str1 [201]=""; char undo1 [201]; struct StringInfo sin1= { (UBYTE *) str1,(UBYTE *) undo1, /* Buffer,UndoBuffer */ 0, /* BufferPos */ 201, /* MaxChars */ 0 /* DispPos */ /* Intuition initializes and maintains all other variables for you */ }; struct Gadget gad1= { NULL, /* NextGadget */ 100,22, /* LeftEdge,TopEdge */ 365,8, /* Width,Height */ GADGHCOMP, /* Flags */ GADGIMMEDIATE | RELVERIFY, /* Activation */ STRGADGET, /* GadgetType */ (APTR) &bor2, /* GadgetRender (Border) */ NULL, /* SelectRender */ &itx2, /* GadgetText */ 0x00000000, /* MutualExclude */ (APTR) &sin1, /* SpecialInfo (StringInfo) */ 1, /* GadgetID */ 0x00000000, /* UserData */ }; SHORT xy3 []= { -4,-3, 138,-3, 138,14, -4,14, -4,-3 }; struct Border bor3= { 0,0, /* LeftEdge,TopEdge */ ORANGE_3,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 5, /* Count */ xy3, /* XY */ NULL /* NextBorder */ }; SHORT xy4 []= { -1,-1, 135,-1, 135,12, -1,12, -1,-1 }; struct Border bor4= { 0,0, /* LeftEdge,TopEdge */ WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 5, /* Count */ xy4, /* XY */ &bor3 /* NextBorder */ }; struct IntuiText itx3= { WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 19,2, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Screen", /* IText */ NULL /* NextText */ }; struct IntuiText itx4= { BLACK_2,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 20,3, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Screen", /* IText */ &itx3 /* NextText */ }; struct Gadget gad2= { &gad1, /* NextGadget */ 20,42, /* LeftEdge,TopEdge */ 135,12, /* Width,Height */ GADGHCOMP, /* Flags */ RELVERIFY, /* Activation */ BOOLGADGET, /* GadgetType */ (APTR) &bor4, /* GadgetRender (Border) */ NULL, /* SelectRender */ &itx4, /* GadgetText */ 0x00000000, /* MutualExclude */ NULL, /* SpecialInfo (BoolInfo) */ 2, /* GadgetID */ 0x00000000, /* UserData */ }; struct IntuiText itx5= { WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 19,2, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Window", /* IText */ NULL /* NextText */ }; struct IntuiText itx6= { BLACK_2,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 20,3, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Window", /* IText */ &itx5 /* NextText */ }; struct Gadget gad3= { &gad2, /* NextGadget */ 175,42, /* LeftEdge,TopEdge */ 135,12, /* Width,Height */ GADGHCOMP, /* Flags */ RELVERIFY, /* Activation */ BOOLGADGET, /* GadgetType */ (APTR) &bor4, /* GadgetRender (Border) */ NULL, /* SelectRender */ &itx6, /* GadgetText */ 0x00000000, /* MutualExclude */ NULL, /* SpecialInfo (BoolInfo) */ 3, /* GadgetID */ 0x00000000, /* UserData */ }; struct IntuiText itx7= { WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 23,2, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Menu", /* IText */ NULL /* NextText */ }; struct IntuiText itx8= { BLACK_2,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 24,3, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Menu", /* IText */ &itx7 /* NextText */ }; struct Gadget gad4= { &gad3, /* NextGadget */ 330,42, /* LeftEdge,TopEdge */ 135,12, /* Width,Height */ GADGHCOMP, /* Flags */ RELVERIFY, /* Activation */ BOOLGADGET, /* GadgetType */ (APTR) &bor4, /* GadgetRender (Border) */ NULL, /* SelectRender */ &itx8, /* GadgetText */ 0x00000000, /* MutualExclude */ NULL, /* SpecialInfo (BoolInfo) */ 4, /* GadgetID */ 0x00000000, /* UserData */ }; struct IntuiText itx9= { WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 19,2, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Gadget", /* IText */ NULL /* NextText */ }; struct IntuiText itx10= { BLACK_2,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 20,3, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Steal Gadget", /* IText */ &itx9 /* NextText */ }; struct Gadget gad5= { &gad4, /* NextGadget */ 485,42, /* LeftEdge,TopEdge */ 135,12, /* Width,Height */ GADGHCOMP, /* Flags */ RELVERIFY, /* Activation */ BOOLGADGET, /* GadgetType */ (APTR) &bor4, /* GadgetRender (Border) */ NULL, /* SelectRender */ &itx10, /* GadgetText */ 0x00000000, /* MutualExclude */ NULL, /* SpecialInfo (BoolInfo) */ 5, /* GadgetID */ 0x00000000, /* UserData */ }; struct IntuiText itx11= { WHITE_1,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 19,2, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Cancel action", /* IText */ NULL /* NextText */ }; struct IntuiText itx12= { BLACK_2,BLUE_0, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 20,3, /* LeftEdge, TopEdge */ NULL, /* ITextFont */ (UBYTE *) "Cancel action", /* IText */ &itx11 /* NextText */ }; struct Gadget gad6= { &gad5, /* NextGadget */ 485,20, /* LeftEdge,TopEdge */ 135,12, /* Width,Height */ GADGHCOMP, /* Flags */ RELVERIFY, /* Activation */ BOOLGADGET, /* GadgetType */ (APTR) &bor4, /* GadgetRender (Border) */ NULL, /* SelectRender */ &itx12, /* GadgetText */ 0x00000000, /* MutualExclude */ NULL, /* SpecialInfo (BoolInfo) */ 6, /* GadgetID */ 0x00000000, /* UserData */ }; struct NewWindow nwin= { 0,12, /* LeftEdge,TopEdge */ 640,64, /* Width,Height */ BLUE_0,WHITE_1, /* DetailPen,BlockPen */ TOTALIDCMP, /* IDCMPFlags */ WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SIMPLE_REFRESH | ACTIVATE | WINDOWACTIVE | WINDOWTICKED, /* Flags */ &gad6, /* FirstGadget */ NULL, /* CheckMark */ (UBYTE *) "Steal 1.1 --- Copyright 1990 Rick van Rein ", /* Title */ NULL, /* Screen */ NULL, /* BitMap */ 640,64, /* MinWidth,MinHeight */ 640,64, /* MaxWidth,MaxHeight */ WBENCHSCREEN /* Type */ }; #define filename str1 /***** Report an error, that was given as a string: */ char REPORT_COPYRIGHT []="Steal 1.1 --- Copyright 1990 Rick van Rein "; char REPORT_BUSY []="Steal 1.1 --- Sneaking into Intuition right now - Hold your breath "; char REPORT_SEL_SCREEN []="Steal 1.1 --- Select a Screen or Cancel "; char REPORT_SEL_WINDOW []="Steal 1.1 --- Select a Window or Cancel "; char REPORT_SEL_MENU []="Steal 1.1 --- Select a Window with a Menu or Cancel "; char REPORT_SEL_GADGET []="Steal 1.1 --- Select a Gadget or Cancel "; char ERR_CANCEL []="Steal 1.1 --- Cancel selected "; char ERR_NOWINDOW []="Steal 1.1 --- No Window at mouse position "; char ERR_NOMENU []="Steal 1.1 --- That Window does not bear a Menu "; char ERR_NOGADGET []="Steal 1.1 --- No Gadget at mouse position "; char ERR_NOFILE []="Steal 1.1 --- Can't open file - Try again please "; char ERR_NOSCREEN []="Steal 1.1 --- No Screen is available (?) "; void Error (str) char *str; { SetWindowTitles (win,str,-1L); /* Leave Screens title alone */ ActivateWindow (win); /* To make title better readable */ ScreenToFront (win->WScreen); DisplayBeep (0L); } void Report (str) char *str; { SetWindowTitles (win,str,-1L); } /***** The GADGETUP have internal names, see below. Decode an IMsg and find the internal type: */ #define GUP_STR 0x01000000L #define GUP_SCREEN 0x02000000L #define GUP_WINDOW 0x04000000L #define GUP_MENU 0x08000000L #define GUP_GADGET 0x10000000L #define GUP_CANCEL 0x20000000L #define GUP_STEAL ( GUP_SCREEN | GUP_WINDOW | GUP_MENU | GUP_GADGET ) long DecodeIDCMP (imsg) struct IntuiMessage *imsg; { long class=imsg->Class; if (class & GADGETUP) class=GUP_STR << (((struct Gadget *) imsg->IAddress)->GadgetID -1); return class; } /***** Get an IntuiMessage that suits us right now; sel uses internal IDCMP-codes: */ /* NOTE: Before we return an IntuiMessage, we first ReplyMsg the last one we returned, if any */ struct IntuiMessage *GetIDCMP (sel) long sel; { struct Node *this,*next; if (LastIntuiMessage) { ReplyMsg (LastIntuiMessage); LastIntuiMessage=NULL; } do { WaitPort (win->UserPort); this=(struct Node *) GetMsg (win->UserPort); if (sel & DecodeIDCMP (this)) return (LastIntuiMessage=(struct IntuiMessage *) this); /* Indeed an assignment! */ else ReplyMsg (this); } while (1); /* Escape this loop with return */ } /***** Find the Gadget on which the mouse is currently; Also give the Error if needed: */ struct Gadget *FindActiveGadget () { struct Gadget *gad; struct Window *wdw; struct Screen *scr; int x,y,relx,rely; wdw=IntuitionBase->ActiveWindow; if (!wdw) { Error (ERR_NOWINDOW); return NULL; } scr=wdw->WScreen; /* Of course it's there! What else should contain this window? */ x=scr->MouseX - wdw->LeftEdge; /* MouseX relative to Window */ y=scr->MouseY - wdw->TopEdge; /* MouseY relative to Window */ gad=wdw->FirstGadget; while (gad) { relx=x - gad->LeftEdge; /* MouseX relative to Gadget */ rely=y - gad->TopEdge; /* MouseY relative to Gadget */ if (gad->Flags & GRELRIGHT) relx-=wdw->Width-1; if (gad->Flags & GRELBOTTOM) rely-=wdw->Height-1; if (relx>=0 && rely>=0 && relxWidth && relyHeight) return gad; /* Found it!!! */ gad=gad->NextGadget; } Error (ERR_NOGADGET); return NULL; } /***** The finite state machine: */ void FiniteStateMachine () { ULONG IBaseLock; struct IntuiMessage *im; long oldclass; struct Window *wdw; struct Screen *scr; struct Gadget *gad; int nr; /* State 0: Activate the string and start inputing it: */ ACT_START: ActivateGadget (&gad1,win,0L); /* State 1: Input a string in the (now active) string-Gadget */ START: im=GetIDCMP (GADGETDOWN | CLOSEWINDOW | GUP_STR | GUP_STEAL | GUP_CANCEL); if (im->Class==GADGETDOWN) goto START; if (im->Class==CLOSEWINDOW) goto EXIT; if (DecodeIDCMP (im)==GUP_CANCEL) DisplayBeep (0L); /* Test if the file with the given stringname can be opened: */ if (!OpenPrintFile (filename)) { Error (ERR_NOFILE); goto ACT_START; } Report (REPORT_COPYRIGHT); if (DecodeIDCMP (im) & (GUP_STEAL | CLOSEWINDOW)) goto LOOPTEST; /* State 2: Wait for some signal from the IDCMP in this main WAIT-STATE */ LOOP: im=GetIDCMP (CLOSEWINDOW | GADGETDOWN | GUP_STEAL); /* State 3: Process the signal that was last read: */ LOOPTEST: oldclass=DecodeIDCMP (im); if (oldclass==CLOSEWINDOW) goto CLOSE_EXIT; if (oldclass==GADGETDOWN) /* Only string reports GADGETDOWN */ goto NEWSTRING; /* State 4: We now have to steal. Wait for INACTIVEWINDOW to tell us what to steal: */ STEAL: switch (oldclass) /* Ask user to click item to be stolen */ { case GUP_SCREEN: Report (REPORT_SEL_SCREEN); break; case GUP_WINDOW: Report (REPORT_SEL_WINDOW); break; case GUP_MENU: Report (REPORT_SEL_MENU); break; case GUP_GADGET: Report (REPORT_SEL_GADGET); break; } /* Now, before looking at what item the user selected, first be sure all IntuiMsgs that were still pending are gone: */ while (im = (struct IntuiMessage *) GetMsg (win->UserPort)) ReplyMsg (im); im=GetIDCMP (CLOSEWINDOW | INACTIVEWINDOW | GUP_CANCEL | GUP_STEAL | GADGETDOWN); if (im->Class==CLOSEWINDOW) goto CLOSE_EXIT; if (im->Class==GADGETUP) /* Must be a GUP_CANCEL or some GUP_STEAL */ { if (DecodeIDCMP (im) & GUP_STEAL) goto LOOPTEST; else { Error (ERR_CANCEL); goto LOOP; } } if (im->Class==GADGETDOWN) /* This must have been the string-Gadget. Timing ??? */ goto NEWSTRING; Report (REPORT_BUSY); IBaseLock = LockIBase (0L); switch (oldclass) { case GUP_SCREEN: goto STEALSCREEN; case GUP_WINDOW: goto STEALWINDOW; case GUP_MENU: goto STEALMENU; case GUP_GADGET: goto STEALGADGET; } STEALSCREEN: if (scr=IntuitionBase->ActiveScreen) { nr=PrintScreen (scr); goto REPORT; } Error (ERR_NOSCREEN); goto JUSTLOOP; STEALWINDOW: if (wdw=IntuitionBase->ActiveWindow) { nr=PrintWindow (wdw,0); goto REPORT; } Error (ERR_NOWINDOW); goto JUSTLOOP; STEALMENU: if (wdw=IntuitionBase->ActiveWindow) { if (!wdw->MenuStrip) { Error (ERR_NOMENU); goto JUSTLOOP; } nr=PrintMenu (wdw->MenuStrip); goto REPORT; } Error (ERR_NOWINDOW); goto JUSTLOOP; STEALGADGET: if (gad=FindActiveGadget ()) { nr=PrintGadget (gad,0); goto REPORT; } goto JUSTLOOP; NEWSTRING: ClosePrintFile (); goto START; REPORT: Error (REPORT_COPYRIGHT); JUSTLOOP: UnlockIBase (IBaseLock); goto LOOP; CLOSE_EXIT: ClosePrintFile (); EXIT: ; } int main () { if (!(IntuitionBase=(struct IntuitionBase *) OpenLibrary ("intuition.library",0L))) { puts ("\tSteal: Can't open intuition.library somehow (?)"); exit (0); } if (!(GfxBase=(struct GfxBase *) OpenLibrary ("graphics.library",0L))) { puts ("\tSteal: Can't open graphics.library somehow (?)"); CloseLibrary (IntuitionBase); exit (0); } strcpy (filename,"Stolen.c"); if (win=OpenWindow (&nwin)) { StdCheckMark=win->CheckMark; StdFont=(struct TextFont *) OpenFont (&StdTextAttr); win->IFont=StdFont; SetFont (win->RPort,StdFont); SetFont (win->BorderRPort,StdFont); FiniteStateMachine (); if (LastIntuiMessage) ReplyMsg (LastIntuiMessage); if (StdFont) CloseFont (StdFont); CloseWindow (win); } else puts ("\tSteal: Couldn't open window"); CloseLibrary (GfxBase); CloseLibrary (IntuitionBase); return 0; }