home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * LEACH Ver 1.3
- *
- * This is an auxilery program to Digi-View 2.0. Leach analyses Digi-View's
- * Intuition structures and worms its way in between Intuition and the Host.
- * The purpose of Leach is to provide a "ruler" line that appears on the Host's
- * display screen. See leach.doc for details.
- *
- * THIS FILE USES 4 COLUMN TAB STOPS AND 80 COLUMNS
- *
- *****************************************************************************/
-
-
- #include <functions.h>
- #include <exec/ports.h>
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/libraries.h>
- #include <exec/tasks.h>
- #include <graphics/gfx.h>
- #include <graphics/rastport.h>
- #include <graphics/text.h>
- #include <intuition/intuitionbase.h>
- #include <stdio.h>
-
-
- struct Library *GfxBase = NULL;
- struct Library *IntuitionBase = NULL;
-
-
- /*********************** SCREEN AND WINDOW STUFF **************************/
-
- /*--------------------------------------------------------------------------*
- * Leach uses its screen just for the status display window. It displays the
- * ruler on the Host's screen. globals.h declares most of the Host variables.
- *--------------------------------------------------------------------------*/
-
- #define SHOWGAD swind_gad[0]
- #define MOVEGAD swind_gad[1]
-
- #define GLOBAL
- #include "globals.h"
-
- /************ LEACH'S STATUS DISPLAY NEWSCREEN STRUCTURE ******************/
-
- static UBYTE ScrTitle[] = " Leach Ver 1.3 ";
-
- struct NewScreen LeachScreen =
- {
- 0, 178, /* LeftEdge, TopEdge */
- 640, 22, 2, /* Width, Height, Depth */
- 0, 1, /* Detail & Block pens. */
- HIRES, /* View Modes */
- CUSTOMSCREEN, /* Type */
- NULL, /* Text attributes */
- ScrTitle,
- NULL, /* Pointer to screen gadget list. */
- NULL /* Pointer to custom bitmap. */
- };
-
-
- /****** The rest of this stuff is for Leach's status display window. ******/
-
- extern struct Gadget swind_gad[];
-
- static UBYTE StatWindTitle[] =
- " Digi-Leach V1.3 Copyright (c) 1988 by Drew Lucy ";
-
- struct NewWindow LeachWindow =
- {
- 0, 0, /* Upper left corner X & Y */
- 640, 22, /* Width and Height. Full width, Two lines tall. */
- 0, 1, /* Detail & Block Pens(UBYTEs) */
- GADGETUP | /* IDCMP Flags (ULONG) */
- CLOSEWINDOW,
- SMART_REFRESH | /* Window Flags (ULONG) */
- WINDOWCLOSE,
-
- swind_gad, /* Pointer to first gadget. */
- NULL, /* Pointer to Checkmark image */
- StatWindTitle, /* Pointer to Window Title */
- NULL, /* Ptr to Leach's screen */
- NULL, /* Pointer to bitmap. */
- 00, 00, /* Min width & height. */
- 00, 00, /* Max width & height */
- CUSTOMSCREEN /* Screen type for this window */
- };
-
-
- /************************** INTUITEXT STRUCTURE *****************************/
-
- /*----------------------------------------------------------------------------*
- * Status display window text. The values of the x's, y's, etc get overwritten
- * at run time. Any changes to this string must be reflected in the constants
- * of update_status().
- *----------------------------------------------------------------------------*/
-
- UBYTE stext[] = "X1= 110 Y1= 150 X2= 210 Y2= 150 Len= 0100 Slope= 000.0 ";
-
- struct IntuiText statustext =
- {
- 1, 0, /* Front and Back Pens. */
- JAM2, /* Blank out background. */
- 4, 11, /* Left edge and Top edge. */
- NULL, /* Use default font. */
- &stext[0], /* Pointer to text string. */
- NULL /* Next IntuiText structure */
- };
-
-
- /***************************** BORDER STRUCTURE *****************************/
-
- #define XOR COMPLEMENT
-
- /*--------------------------------------------------------------------------*
- * This is the array of ruler screen coordinate pairs. Initialization needs
- * to be kept in sync with the IntuiText string initialization. Using a
- * Border struct for one dumb line is probably overkill.
- *--------------------------------------------------------------------------*/
-
- short endpoints[4] = {110, 150, 210, 150};
-
-
- struct Border ruler =
- {
- 0, 0, /* LeftEdge & TopEdge offsets. */
- 0, 0, /* Front and back pens. Neither is used in XOR mode. */
- XOR, /* Draw mode. JAM1 is the other choice. */
- 2, /* Number of coordinate pairs. */
- endpoints, /* Pointer to array of coordinate pairs */
- NULL /* Pointer to next Border structure. */
- };
-
-
-
- /*******************************************************************************
- * Eat shit and die!
- ******************************************************************************/
-
- cleanup()
- {
-
- /* Erase ruler, if it is on. */
-
- if ( (SHOWGAD.Flags & SELECTED) && HostRPort )
- {
- restore_line();
- }
- restore_pointer(); /* Make sure Host's mouse pointer is installed. */
-
- /*--------------------------------------------------------------------------*
- * If we know our Task address and have installed it in Host's IDCMP...
- * Restore the original Host IDCMP flags and return control of its UserPort.
- * Note that the general IDCMP flags are reunited with the IDCMP verification
- * flags, which were stored separately.
- *---------------------------------------------------------------------- ----*/
-
- if (LeachTask && LeachTask == HostUPort->mp_SigTask)
- {
- Forbid();
- ModifyIDCMP(HostWind, (HostIDCMPflags | HostVERflags) );
- HostUPort->mp_SigTask = HostTask;
- Permit();
- }
-
- if (LeachSig && LeachSig != -(1L) )
- FreeSignal(LeachSig);
-
- if (HostWind)
- {
- /*----------------------------------------------------------------------*
- * ReportMouse() doesn't work with Manx C, so turn the flag off directly.
- * Extract Leach's menu from the Host's menu strip if it exists.
- *----------------------------------------------------------------------*/
-
- HostWind->Flags = HostFlags;
- remove_menu();
- }
- if (MyPort)
- {
- myport_event();
- if (MySig)
- FreeSignal( (long)MySig );
- FreeMem(MyPort, (long)sizeof(struct MsgPort) );
- }
- if (StatWind) CloseWindow(StatWind);
- if (StatScreen) CloseScreen(StatScreen);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (GfxBase) CloseLibrary(GfxBase);
-
- WBenchToFront(); /* Force WB screen to front in case of error msgs. */
-
- exit();
-
- } /* End of cleanup() */
-
-
- /**************************************************************************
- * Create a MsgPort that the Host can return IntuiMessages to. This port is
- * key to the overall scheme for tapping in to the message traffic between
- * the Host and Intuition. Leach is going to alter the ReplyPort in
- * messages passed on to the Host so they will be ReplyMsg()'d to this port
- * instead of being returned directly to Intuition.
- **************************************************************************/
-
- create_myport()
- {
- MyPort = CreatePort("MYPORT", 0L);
- if (!MyPort)
- {
- puts("Create of MyPort failed.");
- return(FALSE);
- }
- MySig = MyPort->mp_SigBit;
-
- return(TRUE);
-
- } /* End of create_myport() */
-
-
- /**************************************************************************
- * Routine finds the menu and item numbers of the Host's QUIT menu item
- * by inspecting the Host's menu list item by item.
- **************************************************************************/
-
- find_quit()
- {
-
- static UBYTE target[] = "QUIT";
- UBYTE menu, item;
- UBYTE found_quit; /* Is NOT the global variable */
- struct Menu *mptr; /* Working pointer to current menu. */
- struct MenuItem *iptr; /* Working pointer to current menu item. */
- UBYTE *text; /* Working pointer to menu item text. */
- short i; /* Generic integer. */
-
- mptr = HostMenuStrip;
- menu = item = 0;
- found_quit = FALSE;
-
- while ( mptr && !found_quit) /* While more menus... */
- {
- iptr = mptr->FirstItem;
-
- while (iptr && !found_quit) /* While more menu items... */
- {
- text = ( (struct IntuiText *)(iptr->ItemFill) )->IText;
- while (*text == ' ') ++text; /* Skip leading spaces. */
-
- for (i = 0; (i < 4) && (toupper(text[i]) == target[i]); ++i);
- if (i == 4)
- {
- found_quit = TRUE;
- H_quit_item = item;
- }
- else
- {
- ++item;
- iptr = iptr->NextItem;
- }
- }
- if (found_quit)
- {
- H_quit_menu = menu;
- }
- else
- {
- ++menu;
- item = 0;
- mptr = mptr->NextMenu;
- }
- }
- if (!found_quit)
- {
- puts("Can't find Host's QUIT menu item.");
- cleanup(102);
- }
-
- return( (int)found_quit );
-
- } /* End of find_quit() */
-
-
- /****************************************************************************
- * This function initializes the color registers for the ViewPort.
- ****************************************************************************/
-
- SetStatScrColors()
- {
- SetRGB4(StatVP, 0L, 0L, 0L, 0L); /* Black */
- SetRGB4(StatVP, 1L, 12L, 12L, 12L); /* White */
- SetRGB4(StatVP, 2L, 0L, 8L, 12L);
- SetRGB4(StatVP, 3L, 15L, 6L, 0L);
-
- } /* End of SetStatScrColors() */
-
-
- /******************************************************************************
- * Main Routine
- ******************************************************************************/
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
- int i;
-
- /********************* PROCESS COMMAND LINE ARGUMENTS ********************/
-
- if ( (argv[1][0] == '?') || (argc > 2) )
- {
- puts("USAGE: Run Leach after having run a compatible Host program. The");
- puts(" default Host is any of the Digi-View programs. If attaching");
- puts(" Leach to some other Host, specify the Host's screen title");
- puts(" exactly as it appears in the Host's Screen struct and");
- puts(" hopefully on the screen's title bar. For example\n\n");
- puts(" run leach \"Aegis Images V1.1\"\n");
- exit(0);
- }
-
-
- /********************** OPEN THE SYSTEM LIBRARIES *************************/
-
- if ( !(GfxBase = OpenLibrary("graphics.library", 0L) ) )
- {
- puts("Can't open Graphics Library.");
- exit();
- }
- if ( !(IntuitionBase = OpenLibrary("intuition.library", 0L) ) )
- {
- puts("Can't open Intuition Library.");
- cleanup(106);
- }
-
-
- /************* FIND HOST'S SCREEN AND OTHER VITAL STATISTICS **************/
-
- Forbid(); /* ################# Shut down multitasking ################# */
-
- HostTitle = "Digi-View";
- if (argc == 2) HostTitle = argv[1];
- HostScreen = ( (struct IntuitionBase *) IntuitionBase )->FirstScreen;
-
- while (HostScreen)
- {
- if (HostScreen->DefaultTitle)
- {
- for (i = 0; HostScreen->DefaultTitle[i] == ' '; ++i);
-
- if ( strcmp(&HostScreen->DefaultTitle[i], HostTitle) )
- {
- HostScreen = HostScreen->NextScreen;
- }
- else /* It is the Host! */
- {
- /* Collect some basic info on the Host. */
-
- HostWind = HostScreen->FirstWindow;
- HostRPort = HostWind->RPort;
- HostUPort = HostWind->UserPort;
- HostTask = HostUPort->mp_SigTask;
- HostSig = HostUPort->mp_SigBit; /* 0 - 31, not a mask */
- charwidth = HostRPort->TxWidth;
- charheight = HostRPort->TxHeight;
- HostFlags = HostWind->Flags;
- HostMenuStrip = HostWind->MenuStrip;
- HostIDCMPflags = HostWind->IDCMPFlags;
- HostVERflags = HostIDCMPflags & (MENUVERIFY | REQVERIFY |
- SIZEVERIFY);
- HostIDCMPflags &= ~HostVERflags;
-
- /* HostIDCMPflags now have the Verification flag bits */
- /* removed and stored separately in HostVERflags. */
-
- break; /* Kill while loop */
- }
- }
- else
- {
- HostScreen = HostScreen->NextScreen;
- }
- } /* end of while (HostScreen) */
-
- /*--------------------------------------------------------------------------*
- * Bump Leach's task priority to one higher than the Host's. We must be able
- * to preempt the Host immediately, when a msg arrives at the Host's IDCMP.
- *--------------------------------------------------------------------------*/
-
- LeachTask = FindTask(0L);
- LeachTask->tc_Node.ln_Pri = HostTask->tc_Node.ln_Pri + 1;
-
- Permit(); /* ################# Re-enable multitasking ################# */
-
- if ( !(HostScreen && HostWind && HostRPort && HostUPort && HostTask) )
- {
- printf("Some Host parameter is NULL. Is %s running?\n", HostTitle);
- cleanup(108);
- }
-
- H_found_quit = find_quit(); /* Find the Host's QUIT menu item */
-
-
- /*-------------------------- Diddle Host's IDCMP -------------------------*
- * The objective is to replace the Host's task pointer with one that belongs
- * to the Leach. There after, Intuition will signal Leach instead of the
- * Host when a msg arrives at the Host's UserPort. LeachSig isn't actually
- * used anywhere in the program. I just wanted to be sure that Leach never
- * used the signal for anything else. See the file tech-notes for additional
- * comments on this subject.
- *--------------------------------------------------------------------------*/
-
- LeachSig = AllocSignal( (ULONG)HostSig ); /* Returns a long that's 1-32. */
-
- if ( LeachSig != HostSig)
- {
- puts("Unable to allocate Leach Signal bit.");
- cleanup(110);
- }
- HostUPort->mp_SigTask = LeachTask;
-
-
- /********************** LAST MINUTE EMERGENCIES ***********************/
-
- SetStatScrColors(); /* Sets 1st 4 color regs for status screen */
-
- /*----------------------------------------------------------------------*
- * Leach wants to know when the Host window becomes active, so it can
- * ignore the mouse click. If the Host had any verification flags set,
- * they were extracted from HostIDCMPflags so, this is also were Host
- * verification will get shut down for the duration.
- *----------------------------------------------------------------------*/
-
- HostIDCMPmods = ACTIVEWINDOW;
- ModifyIDCMP(HostWind, HostIDCMPflags | HostIDCMPmods);
- HostFlagsmods = 0L;
-
- /*--------------------------------------------------------------------------*
- * Initially Leach had trouble working with interlaced Hosts. There was some
- * kind of View/ViewPort conflict, I think. Rather than fix this, I decided
- * to duck the problem by making Leach's screen match the Host's. So, we
- * check out the Host Screen's height to tell if it's interlaced. This will
- * screw up if not running on an NTSC Amiga.
- *--------------------------------------------------------------------------*/
-
- if (HostScreen->Height > 200)
- {
- LeachScreen.ViewModes |= LACE;
- LeachScreen.TopEdge = 400 - LeachScreen.Height;
- }
-
-
- /***************** OPEN LEACH SCREEN AND STATUS WINDOW ********************/
-
- if (! ( StatScreen = OpenScreen(&LeachScreen) ) )
- {
- puts("Couldn't open Leach's Screen.");
- cleanup(112);
- }
-
- /* Only thing StatVP is currently used for is to set the color registers. */
-
- StatVP = &(StatScreen->ViewPort);
-
- LeachWindow.Screen = StatScreen;
-
- if (! ( StatWind = OpenWindow(&LeachWindow) ) )
- {
- puts("Couldn't open Leach's window.");
- cleanup(114);
- }
- StatRPort = StatWind->RPort;
- PrintIText(StatRPort, &statustext, 0L, 0L); /* Initial endpoints */
- install_menu();
- ScreenToFront(HostScreen);
-
- event_processor(); /* Currently doesn't return but just in case... */
-
- cleanup(116); /* Rap it up and quit. */
-
- return;
-
- } /* End of main() */
-
-
- /****************************************************************************
- * A debugging routine that dumps out all the global Host parameters. *
-
- disp_host_params()
- {
- printf("Host screen title = %s.\n", HostScreen->DefaultTitle);
- printf("Host Screen @ $%lx. Host Window @ $%lx.\n", HostScreen, HostWind);
- printf("Host UserPort @ $%lx. Host RastPort @ $%lx.\n", HostUPort, HostRPort);
- printf("Host Task @ $%lx. Host SigBit is $%x.\n", HostTask, HostSig);
- printf("Leach Task @ $%lx. Leach SigBit is $%x.\n", LeachTask, LeachSig);
- printf("Leach priority = %d. Host priority = %d.\n", LeachTask->tc_Node.ln_Pri,
- HostTask->tc_Node.ln_Pri);
- }
- ****************************************************************************/
-
-