[comp.sources.amiga] v90i067: Snap 1.4 - cut, store, and paste between windows, Part01/04

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (02/12/90)

Submitted-by: micke@slaka.sirius.se (Mikael Karlsson)
Posting-number: Volume 90, Issue 067
Archive-name: util/snap-1.4/part01

Snap is the perfect tool for the lazy typer. Isn't it irritating when you
look at something on the screen and think: "That is what I'm going to type."?
What if you could just point at it and get the computer to type it for you?
That's where Snap comes to the rescue.  Another thing that irritates me is
that I'm sitting in front of THE computer and still I must have pen and paper
available to scribble down something from the screen that I know I will need
later. Snap provides a solution to that problem also. Just frame it and Snap
creates a window with a copy of the screen contents. Perfect for snapping
text from later on. 

Important changes:

o You can't use the new Snap to turn off the old version.
o Delays are now specified in milliseconds.
o You can now change parameters without removing and re-installing Snap.
o Use 'snap -Q'/'snap quit' to remove Snap.

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 4)."
# Contents:  .DistFiles README source source/clip.c source/frame.c
#   source/makefile source/minrexx.h source/misc.c source/openclose.c
#   source/patch.c source/rexx.c source/saveilbm.c source/snap.h
#   source/snapasm.s source/snapgfx.c
# Wrapped by tadguy@xanth on Sun Feb 11 17:48:43 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f '.DistFiles' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'.DistFiles'\"
else
echo shar: Extracting \"'.DistFiles'\" \(371 characters\)
sed "s/^X//" >'.DistFiles' <<'END_OF_FILE'
X.DistFiles
XREADME
Xsnap
Xsettings
Xsnap.doc
Xsnap.info
Xstartsnap.rexx
Xsource/clip.c
Xsource/frame.c
Xsource/handler.s
Xsource/ikm.c
Xsource/makefile
Xsource/minrexx.c
Xsource/minrexx.h
Xsource/misc.c
Xsource/openclose.c
Xsource/patch.c
Xsource/rexx.c
Xsource/saveilbm.c
Xsource/settings.c
Xsource/snap.c
Xsource/snap.h
Xsource/snapasm.s
Xsource/snapchars.c
Xsource/snapgfx.c
Xsource/windows.c
END_OF_FILE
if test 371 -ne `wc -c <'.DistFiles'`; then
    echo shar: \"'.DistFiles'\" unpacked with wrong size!
fi
# end of '.DistFiles'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(244 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XImportant changes:
X
Xo You can't use the new Snap to turn off the old version.
X
Xo Delays are now specified in milliseconds.
X
Xo You can now change parameters without removing and
X  re-installing Snap.
X
Xo Use 'snap -Q'/'snap quit' to remove Snap.
END_OF_FILE
if test 244 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test ! -d 'source' ; then
    echo shar: Creating directory \"'source'\"
    mkdir 'source'
fi
if test -f 'source/clip.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/clip.c'\"
else
echo shar: Extracting \"'source/clip.c'\" \(2562 characters\)
sed "s/^X//" >'source/clip.c' <<'END_OF_FILE'
X/* This is just plain clipboard handling */
X
XIMPORT struct IOClipReq *ClipReq;
X
XULONG ReadClip(ClipReq, Buf, BufSize, Action)
Xstruct IOClipReq *ClipReq;
XSTRPTR Buf;
XULONG BufSize;
XSHORT Action;
X{
X    ULONG Length;
X    ClipReq->io_Command = CMD_READ;
X    ClipReq->io_Data = Buf;
X    ClipReq->io_Length = BufSize-1L;       /* space for '\0' */
X    if (Action == CLIP_FIRST) {
X        ClipReq->io_Offset = 0L;
X        ClipReq->io_ClipID = 0L;
X    }
X    DoIO(ClipReq);
X    Length = ClipReq->io_Actual;
X    Buf[Length] = '\0';
X    if (Action == CLIP_LAST) {
X        ClipReq->io_Command = CMD_READ;
X        ClipReq->io_Data = NULL;
X        ClipReq->io_Length = 1L;
X        DoIO(ClipReq);                    /* Null read to terminate */
X    }
X    return(Length);
X}
X
XVOID WriteClip(ClipReq, Buf, BufSize, Action)
Xstruct IOClipReq *ClipReq;
XSTRPTR Buf;
XULONG BufSize;
XSHORT Action;
X{
X    if (Action == CLIP_FIRST) {
X        ClipReq->io_Offset = 0L;
X        ClipReq->io_ClipID = 0L;
X    }
X    ClipReq->io_Command = CMD_WRITE;
X    ClipReq->io_Data = Buf;
X    ClipReq->io_Length = BufSize;
X    DoIO(ClipReq);
X    if (Action == CLIP_LAST) {
X        ClipReq->io_Command = CMD_UPDATE;
X        DoIO(ClipReq);
X    }
X}
X
XVOID SaveClip(SnapSpace, SnapSize)
XUBYTE *SnapSpace;
XULONG SnapSize;
X{
X    ULONG Len;
X    WriteClip(ClipReq, "FORM", 4L, CLIP_FIRST);
X    Len = SnapSize+12;
X    WriteClip(ClipReq, (STRPTR)&Len, 4L, CLIP_CONT);
X    WriteClip(ClipReq, "FTXT", 4L, CLIP_CONT);
X    WriteClip(ClipReq, "CHRS", 4L, CLIP_CONT);
X    Len = SnapSize;
X    WriteClip(ClipReq, (STRPTR)&Len, 4L, CLIP_CONT);
X    WriteClip(ClipReq, SnapSpace, Len, CLIP_LAST);
X}
X
Xstruct Snap *FetchClip()
X{
X    struct Snap *Snap = NULL;
X    ULONG temp;
X    ULONG ID[2];
X
X    (VOID)ReadClip(ClipReq, (STRPTR)&ID, 5L, CLIP_FIRST);    /* FORM */
X    if (!strcmp((STRPTR)&ID, "FORM")) {
X        (VOID)ReadClip(ClipReq, (STRPTR)&ID, 5L, CLIP_CONT);     /* size */
X        (VOID)ReadClip(ClipReq, (STRPTR)&ID, 5L, CLIP_CONT);     /* FTXT */
X        if (!strcmp((STRPTR)&ID, "FTXT")) {
X            (VOID)ReadClip(ClipReq, (STRPTR)&ID, 5L, CLIP_CONT);     /* CHRS */
X            if (!strcmp((STRPTR)&ID, "CHRS")) {
X                (VOID)ReadClip(ClipReq, (STRPTR)&ID, 5L, CLIP_CONT); /* #chars */
X                temp = ID[0];
X                Snap = AllocMem((LONG)sizeof(struct Snap)+temp,
X                  MEMF_PUBLIC|MEMF_CLEAR);
X                Snap->Size = sizeof(struct Snap)+temp;
X                ReadClip(ClipReq, &Snap->Chars[0], Snap->Size+1L, CLIP_LAST);
X            }
X        }
X    }
X    return(Snap);
X}
END_OF_FILE
if test 2562 -ne `wc -c <'source/clip.c'`; then
    echo shar: \"'source/clip.c'\" unpacked with wrong size!
fi
# end of 'source/clip.c'
fi
if test -f 'source/frame.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/frame.c'\"
else
echo shar: Extracting \"'source/frame.c'\" \(1217 characters\)
sed "s/^X//" >'source/frame.c' <<'END_OF_FILE'
XIMPORT struct RastPort rp;
X
XPoint OldFrame[9];
XPoint NewFrame[9];
XLONG OFType = 0;
XUWORD Ptrn;
X
XSTATIC VOID MultiDraw(rp, num, xy)
Xstruct RastPort *rp;
XLONG num;
XPoint *xy;
X{
X    REGISTER LONG i = 0;
X    REGISTER Point *coord = xy;
X    while (i<num) {
X        Move(rp, (LONG)coord->x, (LONG)coord->y);
X        coord++;
X        Draw(rp, (LONG)coord->x, (LONG)coord->y);
X        i++;
X    }
X}
X
XVOID crawl_frame(dir)
XLONG dir;
X{
X    REGISTER UWORD temp = Ptrn;
X    if (dir) {
X        Ptrn = ((Ptrn<<1) & 0xfffe) | ((Ptrn & 0x8000)>>15);
X    } else {
X        Ptrn = ((Ptrn>>1) & 0x7fff) | ((Ptrn & 1)<<15);
X    }
X    temp ^= Ptrn;
X    SetDrPt(&rp, temp);
X    MultiDraw(&rp, OFType, &OldFrame[0]);
X    SetDrPt(&rp, Ptrn);
X}
X
XVOID erase_frame()
X{
X    if (OFType) {
X        MultiDraw(&rp, OFType, &OldFrame[0]);
X        OFType = 0;
X    }
X}
X
XVOID draw_frame(ft)
XLONG ft;
X{
X    REGISTER LONG i;
X      /* Remove old frame */
X    WaitTOF();
X    erase_frame();
X      /* Draw the new frame */
X    SetDrPt(&rp, Ptrn);
X    MultiDraw(&rp, ft, &NewFrame[0]);
X      /* save the frame for erasing later */
X    for (i=0; i<=ft; i++) {
X        OldFrame[i].x = NewFrame[i].x;
X        OldFrame[i].y = NewFrame[i].y;
X    }
X    OFType = ft;
X}
END_OF_FILE
if test 1217 -ne `wc -c <'source/frame.c'`; then
    echo shar: \"'source/frame.c'\" unpacked with wrong size!
fi
# end of 'source/frame.c'
fi
if test -f 'source/makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/makefile'\"
else
echo shar: Extracting \"'source/makefile'\" \(1232 characters\)
sed "s/^X//" >'source/makefile' <<'END_OF_FILE'
XOBJS=snap.o openclose.o clip.o patch.o handler.o snapgfx.o \
X snapchars.o frame.o misc.o ikm.o snapasm.o saveilbm.o windows.o \
X rexx.o minrexx.o
XEXE=snap
XSYMS=$(EXE).sym
XSYMSRC=$(EXE).h
XQUICKSYMS=ram:$(SYMS)
X
X# Rexx stuff - Only available with Aztec
XREXXCC=-dSNAPREXX
XREXXOBJS=rexxglue
X
X# Aztec
XCCFLAGS=-q +I$(QUICKSYMS) $(REXXCC)
XASFLAGS=
XLNFLAGS=
XLNOBJS=detach $(REXXOBJS) -lc -la
XSYMFLAGS=+l +h$(SYMS) -o ram:null.o
XCC=cc
XAS=as
XLN=ln
X
X#Lattice
X#CCFLAGS=-v -H$(QUICKSYMS) # -O
X#ASFLAGS=-iLattice:Asm-include/
X#LNFLAGS=NOALVS SC SD ND TO $(EXE) FROM lib:cback.o
X#LNOBJS=LIB lib:lc.lib lib:amiga.lib
X#SYMFLAGS=-ph -o$(SYMS)
X#CC=lc
X#AS=asm
X#LN=blink
X
X.c.o:
X    $(CC) $(CCFLAGS) -o$*.o $*.c
X
X.s.o:
X    $(AS) $(ASFLAGS) $*.s
X
Xall: $(SYMS) $(QUICKSYMS) $(EXE)
X
X# Lattice link
X#$(EXE): $(OBJS) $(EXE).lnk
X#    blink with $(EXE).lnk
X
X#Aztec link
X$(EXE):    $(OBJS)
X    $(LN) $(LNFLAGS) $(OBJS) $(LNOBJS)
X
X$(EXE).lnk:
X    echo >ram:l1 "$(LNFLAGS)"
X    echo >ram:l2 "$(OBJS)"
X    echo >ram:l3 "$(LNOBJS)"
X    join ram:l1 ram:l2 ram:l3 as $(EXE).lnk
X    delete ram:l1 ram:l2 ram:l3
X
X$(SYMS): $(SYMSRC)
X    copy $(SYMSRC) ram:temp.c
X    $(CC) $(SYMFLAGS) ram:temp.c
X    delete ram:temp.c
X
X$(QUICKSYMS): $(SYMS)
X    copy $(SYMS) $(QUICKSYMS)
END_OF_FILE
if test 1232 -ne `wc -c <'source/makefile'`; then
    echo shar: \"'source/makefile'\" unpacked with wrong size!
fi
# end of 'source/makefile'
fi
if test -f 'source/minrexx.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/minrexx.h'\"
else
echo shar: Extracting \"'source/minrexx.h'\" \(808 characters\)
sed "s/^X//" >'source/minrexx.h' <<'END_OF_FILE'
X/*
X *   Includes for minrexx.c; please refer to that file for
X *   further documentation.
X */
X#include <rexx/rxslib.h>
X/*
X *   This is the list of functions we can access.  (Cheap forward
X *   declarations, too.)
X */
Xlong upRexxPort() ;
Xvoid dnRexxPort() ;
Xvoid dispRexxPort() ;
Xstruct RexxMsg *sendRexxCmd() ;
Xstruct RexxMsg *syncRexxCmd() ;
Xstruct RexxMsg *asyncRexxCmd() ;
Xvoid replyRexxCmd() ;
X/*
X *   Maximum messages that can be pending, and the return codes
X *   for two bad situations.
X */
X#define MAXRXOUTSTANDING (300)
X#define RXERRORIMGONE (100)
X#define RXERRORNOCMD (30)
X/*
X *   This is the association list you build up (statically or
X *   dynamically) that should be terminated with an entry with
X *   NULL for the name . . .
X */
Xstruct rexxCommandList {
X   char *name ;
X   APTR userdata ;
X} ;
END_OF_FILE
if test 808 -ne `wc -c <'source/minrexx.h'`; then
    echo shar: \"'source/minrexx.h'\" unpacked with wrong size!
fi
# end of 'source/minrexx.h'
fi
if test -f 'source/misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/misc.c'\"
else
echo shar: Extracting \"'source/misc.c'\" \(2829 characters\)
sed "s/^X//" >'source/misc.c' <<'END_OF_FILE'
X/* Auto: make
X*/
X
X#define SCREENTOP\
X   (screen->TopEdge << ((screen->ViewPort.Modes & LACE)? 0: 1))
X
XIMPORT struct SnapRsrc *SnapRsrc;
XIMPORT struct IntuitionBase *IntuitionBase;
XIMPORT struct MinList CachedWindows;
X
Xstruct Screen *WhichScreen()
X{
X    REGISTER struct Screen *screen;
X    Forbid();
X    screen = IntuitionBase->FirstScreen;
X    while (screen && IntuitionBase->MouseY < SCREENTOP) {
X        screen = screen->NextScreen;
X    }
X    if (screen == NULL) {     /* Shouldn't happen */
X        screen = IntuitionBase->ActiveScreen;
X    }
X    Permit();
X    return screen;
X}
X
Xstruct Window *WhichWindow(screen)
Xstruct Screen *screen;
X{
X    struct Layer *layer;
X    layer = (struct Layer *)WhichLayer(&screen->LayerInfo,
X      (LONG)screen->MouseX, (LONG)screen->MouseY);
X    if (layer) {
X        return (struct Window *)layer->Window;
X    } else {
X        return NULL;
X    }
X}
X
XVOID FreePlanes(bm, width, height)
Xstruct BitMap *bm;
XLONG width, height;
X{
X    SHORT i;
X    for (i=0; i < bm->Depth; i++) {
X        if (bm->Planes[i]) {
X            FreeRaster(bm->Planes[i], width, height);
X        }
X    }
X}
X
XWORD AllocPlanes(bm, width, height)
Xstruct BitMap *bm;
XLONG width, height;
X{
X    WORD i;
X    for (i=0; i < bm->Depth; i++) {
X        bm->Planes[i] = NULL;
X    }
X    for (i=0; i < bm->Depth; i++) {
X        if (!(bm->Planes[i] = AllocRaster(width, height))) {
X            return 0;
X        }
X        BltClear(bm->Planes[i], RASSIZE(width, height), NULL);
X    }
X    return 1;
X}
X
XVOID CacheWindow(Win, xoff, yoff, fw, fh)
Xstruct Window *Win;
XLONG xoff;
XLONG yoff;
XSHORT fw;
XSHORT fh;
X{
X    struct CacheWindow *cw;
X    if (!(cw = AllocMem((LONG)sizeof(struct CacheWindow),
X      MEMF_PUBLIC|MEMF_CLEAR))) {
X        return;
X    }
X    cw->Window = Win;
X    cw->xoff = xoff;
X    cw->yoff = yoff;
X    cw->fw = fw;
X    cw->fh = fh;
X    AddHead((struct List *)&CachedWindows, (struct Node *)cw);
X    if (SnapRsrc->CacheSize > 0) {
X        --SnapRsrc->CacheSize;
X    } else {
X        FreeMem(RemTail((struct List *)&CachedWindows),
X          (LONG)sizeof(struct CacheWindow));
X    }
X}
X
Xstruct CacheWindow *GetCachedWindow(Screen, Win)
Xstruct Screen *Screen;
Xstruct Window *Win;
X{
X    struct CacheWindow *cw = (struct CacheWindow *)CachedWindows.mlh_Head;
X
X    while (cw->Node.mln_Succ) {
X        if (cw->Window == Win) {
X            LONG LockVal = LockIBase(0L);
X            REGISTER struct Window *w = Screen->FirstWindow;
X            while (w && w != Win) {
X                w = w->NextWindow;
X            }
X            UnlockIBase(LockVal);
X            if (!w) {
X                return NULL;
X            }
X            Remove((struct Node *)cw);
X            AddHead((struct List *)&CachedWindows, (struct Node *)cw);
X            return cw;
X        }
X        cw = (struct CacheWindow *)cw->Node.mln_Succ;
X    }
X    return NULL;
X}
END_OF_FILE
if test 2829 -ne `wc -c <'source/misc.c'`; then
    echo shar: \"'source/misc.c'\" unpacked with wrong size!
fi
# end of 'source/misc.c'
fi
if test -f 'source/openclose.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/openclose.c'\"
else
echo shar: Extracting \"'source/openclose.c'\" \(7742 characters\)
sed "s/^X//" >'source/openclose.c' <<'END_OF_FILE'
X/* Auto: make
X*/
X
XIMPORT LONGBITS startsignal, insertsignal, cancelsignal, donesignal;
XIMPORT LONGBITS movesignal, clicksignal, timersignal, initsignal, cwsignal;
XIMPORT ULONG startsignum, insertsignum, cancelsignum, donesignum;
XIMPORT ULONG movesignum, clicksignum, timersignum, initsignum, cwsignum;
X
X/* program */
XIMPORT struct SnapRsrc *SnapRsrc;
XIMPORT struct Task *MyTask;
X
X/* Snap state machine */
XIMPORT WORD action;
XIMPORT WORD state;
X
X/* clipboard */
XIMPORT struct IOClipReq *ClipReq;
XIMPORT struct MsgPort *ClipPort;
X
X/* timer device */
XIMPORT struct MsgPort *TimerPort;
XIMPORT struct timerequest MyTR;
X
X/* input device */
XIMPORT struct MsgPort *inputDevPort;
XIMPORT struct Interrupt handlerStuff;
XIMPORT struct IOStdReq *inputRequestBlock;
X
XIMPORT UBYTE *CharData;
X
X/* console */
XIMPORT struct MsgPort *ConPort;
XIMPORT struct IOStdReq *ConIOR;
XIMPORT struct KeyMap keymap;
X
X/* windows */
XIMPORT struct MsgPort *Sharedport;
XIMPORT SHORT Sharedrefs;
XIMPORT struct MinList CachedWindows;
X
X/* libraries */
XIMPORT struct IntuitionBase *IntuitionBase;
XIMPORT struct GfxBase       *GfxBase;
XIMPORT struct LayersBase    *LayersBase;
XIMPORT struct ArpBase       *ArpBase;
X
X/* graphics */
XIMPORT struct RastPort TempRp;
XIMPORT struct BitMap TempBM;
XIMPORT UBYTE *TempRaster;
X
XIMPORT struct Image DiskImage;
XUWORD ImData[24] = {
X    /* BitPlane 0 */
X    0xFFFF,
X    0xF00F,
X    0xF7EF,
X    0xF42F,
X    0xF7EF,
X    0xF00F,
X    0xF3CF,
X    0xF2CF,
X    0xF2CF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF,
X    0xFFFF
X};
X
XVOID CloseStuff()
X{
X    SafeRestore();
X    {
X        struct CacheWindow *cw;
X        while (cw = (struct CacheWindow *)
X          RemHead((struct List *)&CachedWindows)) {
X            FreeMem(cw, (LONG)sizeof(struct CacheWindow));
X        }
X    }
X    if (DiskImage.ImageData) FreeMem(DiskImage.ImageData, 32L);
X    if (TempRaster)         FreeRaster(TempRaster, 16L, 16L);
X    if (CharData)           FreeMem(CharData, 256L*32);
X    if (inputRequestBlock) {
X        if (inputRequestBlock->io_Device) {
X            inputRequestBlock->io_Command = IND_REMHANDLER;  /* Remove handler */
X            inputRequestBlock->io_Data    = (APTR)&handlerStuff;
X            DoIO(inputRequestBlock);
X            CloseDevice(inputRequestBlock);
X        }
X        DeleteExtIO(inputRequestBlock);
X    }
X    if (inputDevPort)       DeletePort(inputDevPort);
X    if (TimerPort) {
X        DeletePort(TimerPort);
X        CloseDevice((struct IOStdReq *)&MyTR);
X    }
X    if (ConIOR) {
X        CloseDevice(ConIOR);
X        DeleteExtIO(ConIOR);
X    }
X    if (ConPort)            DeletePort(ConPort);
X    if (ClipReq) {
X        if (ClipReq->io_Device) {
X            CloseDevice(ClipReq);
X        }
X        DeleteExtIO(ClipReq);
X    }
X    if (ClipPort)           DeletePort(ClipPort);
X    if (startsignum != -1)  FreeSignal(startsignum);
X    if (donesignum != -1)   FreeSignal(donesignum);
X    if (cancelsignum != -1) FreeSignal(cancelsignum);
X    if (movesignum != -1)   FreeSignal(movesignum);
X    if (insertsignum != -1) FreeSignal(insertsignum);
X    if (clicksignum != -1)  FreeSignal(clicksignum);
X    if (timersignum != -1)  FreeSignal(timersignum);
X    if (initsignum != -1)   FreeSignal(initsignum);
X    if (cwsignum != -1)     FreeSignal(cwsignum);
X    if (SnapRsrc) {
X        RemResource(SnapRsrc);
X        Kill(SnapRsrc);
X    }
X    if (ArpBase)            CloseLibrary((struct Library *)ArpBase);
X    if (IntuitionBase)      CloseLibrary((struct Library *)IntuitionBase);
X    if (GfxBase)            CloseLibrary((struct Library *)GfxBase);
X    if (LayersBase)         CloseLibrary((struct Library *)LayersBase);
X}
X
XWORD OpenStuff()
X{
X    action = noaction;
X    state  = waiting;
X    inputRequestBlock = NULL;
X
X    Sharedrefs = 0;
X    Sharedport = NULL;
X    NewList((struct NewList *)&CachedWindows);
X
X    /* Set up everything we need. */
X
X    /* libraries */
X
X    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L)))
X        return 0;
X    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0L)))
X        return 0;
X    if (!(LayersBase = (struct LayersBase *)OpenLibrary("layers.library", 0L)))
X        return 0;
X    ArpBase = (struct ArpBase *)OpenLibrary(ArpName, ArpVersion);
X
X    /* signals */
X
X    if ((startsignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((insertsignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((cancelsignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((donesignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((movesignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((clicksignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((timersignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((initsignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    if ((cwsignum = AllocSignal(-1L)) == -1L)
X        return 0;
X    MyTask = FindTask(NULL);                  /* Find myself to Signal me.  */
X    startsignal  = 1L << startsignum;         /* No good to use bit numbers */
X    insertsignal = 1L << insertsignum;
X    cancelsignal = 1L << cancelsignum;
X    donesignal   = 1L << donesignum;
X    movesignal   = 1L << movesignum;
X    clicksignal  = 1L << clicksignum;
X    timersignal  = 1L << timersignum;
X    initsignal   = 1L << initsignum;
X    cwsignal     = 1L << cwsignum;
X
X    /* clipboard device */
X
X    if (!(ClipPort = CreatePort(0L, 0L)))
X        return 0;
X    if (!(ClipReq = (struct IOClipReq *)CreateExtIO(ClipPort, (LONG)sizeof(*ClipReq))))
X        return 0;
X    if (OpenDevice("clipboard.device", 0L, ClipReq, 0L))
X        return 0;
X    ClipReq->io_ClipID = 0L;
X
X    /* console device */
X
X    if (!(ConPort = CreatePort(0L, 0L)))
X        return 0;
X    if (!(ConIOR = (struct IOStdReq *)CreateExtIO(ConPort, (LONG)sizeof(struct IOStdReq))))
X        return 0;
X    if (OpenDevice("console.device", -1L, ConIOR, 0L))
X        return 0;
X
X    /* timer device */
X    if (!(TimerPort = CreatePort(NULL, 0L)))
X        return 0;
X    if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IOStdReq *)&MyTR, 0L))
X        return 0;
X    MyTR.tr_node.io_Message.mn_ReplyPort = TimerPort;
X    MyTR.tr_node.io_Command = TR_ADDREQUEST;
X
X    /* input devive */
X
X    if (!(inputDevPort = CreatePort(0L, 0L)))
X        return 0;
X    if (!(inputRequestBlock = (struct IOStdReq *)CreateExtIO(inputDevPort, (LONG)sizeof(struct IOStdReq))))
X        return 0;
X    if (OpenDevice("input.device", 0L, inputRequestBlock, 0L))
X        return 0;
X
X    /* input handler */
X
X    handlerStuff.is_Data = (APTR)0x534E4150; /* Set up for installation of */
X    handlerStuff.is_Code = myhandler;        /* myhandler.                 */
X    handlerStuff.is_Node.ln_Pri = SnapRsrc->Priority;
X                                             /* Ahead of intuition, please */
X    handlerStuff.is_Node.ln_Name = "Snap Input Handler";
X
X    inputRequestBlock->io_Command = IND_ADDHANDLER;
X    inputRequestBlock->io_Data    = (APTR)&handlerStuff;
X
X    DoIO(inputRequestBlock);  /* Add me. */
X
X
X    /* Aligned font bitmap to use when matching */
X
X    if (!(CharData = AllocRaster(16L, 256L*16))) {
X        return 0;
X    }
X
X    /* temporary raster */
X
X    if (!(TempRaster = AllocRaster(16L, 16L)))
X        return 0;
X    InitRastPort(&TempRp);                   /* Init RastPort used for */
X    InitBitMap(&TempBM, 1L, 16L, 16L);       /* Locating position of   */
X    TempBM.Planes[0] = TempRaster;           /* first character.       */
X    TempRp.BitMap = &TempBM;
X
X    if (!(DiskImage.ImageData = AllocMem(48L, MEMF_CHIP))) {
X        return 0;
X    }
X    CopyMem((char *)&ImData[0], (char *)DiskImage.ImageData, 48L);
X    return 1;
X}
END_OF_FILE
if test 7742 -ne `wc -c <'source/openclose.c'`; then
    echo shar: \"'source/openclose.c'\" unpacked with wrong size!
fi
# end of 'source/openclose.c'
fi
if test -f 'source/patch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/patch.c'\"
else
echo shar: Extracting \"'source/patch.c'\" \(1837 characters\)
sed "s/^X//" >'source/patch.c' <<'END_OF_FILE'
X/* This patch is a quite ugly way to solve the problem
X** that occurs when Intuition tries to draw something
X** in a screen which has it's layers locked.
X** The problem is solved by disabling dangerous functions.
X** Some functions remain because they require more work.
X** An example of this is OpenWindow(), since OpenWindow()
X** can't be as easily ignored as the functions that ARE
X** patched here. OpenWindow() would require some sort of
X** semaphore locking and waiting - and so we're back where
X** we started.
X*/
X
Xtypedef VOID (*FPTR)();
X
XIMPORT struct IntuitionBase *IntuitionBase;
X#define LVOWindowToBack   -0x0132L
X#define LVOWindowToFront  -0x0138L
X#define LVOActivateWindow -0x01c2L
X
XVOID myActivateWindow(), myWindowToFront(), myWindowToBack();
X
XLONG oldActivateWindow, oldWindowToFront, oldWindowToBack;
X
XSTATIC WORD patched = 0;
X
XVOID SafePatch()
X{
X    if (!patched) {
X        Forbid();     /* I don't expect interrupts to do much intuition */
X        oldActivateWindow = (LONG)SetFunction((struct Library *)IntuitionBase,
X          LVOActivateWindow, (FPTR)myActivateWindow);
X        oldWindowToFront = (LONG)SetFunction((struct Library *)IntuitionBase,
X          LVOWindowToFront, (FPTR)myWindowToFront);
X        oldWindowToBack =  (LONG)SetFunction((struct Library *)IntuitionBase,
X          LVOWindowToBack, (FPTR)myWindowToBack);
X        Permit();
X        patched = 1;
X    }
X}
X
XVOID SafeRestore()
X{
X    if (patched) {
X        Forbid();
X        (VOID)SetFunction((struct Library *)IntuitionBase,
X          LVOActivateWindow, (FPTR)oldActivateWindow);
X        (VOID)SetFunction((struct Library *)IntuitionBase,
X          LVOWindowToFront, (FPTR)oldWindowToFront);
X        (VOID)SetFunction((struct Library *)IntuitionBase,
X          LVOWindowToBack, (FPTR)oldWindowToBack);
X        Permit();
X        patched = 0;
X    }
X}
END_OF_FILE
if test 1837 -ne `wc -c <'source/patch.c'`; then
    echo shar: \"'source/patch.c'\" unpacked with wrong size!
fi
# end of 'source/patch.c'
fi
if test -f 'source/rexx.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/rexx.c'\"
else
echo shar: Extracting \"'source/rexx.c'\" \(847 characters\)
sed "s/^X//" >'source/rexx.c' <<'END_OF_FILE'
X/* Auto: make
X*/
X
X#ifdef SNAPREXX
X#include "minrexx.h"
X
XIMPORT struct SnapRsrc *SnapRsrc;
X
XVOID rexxprepend(), rexxappend();
Xint disp();
X
Xstruct rexxCommandList rcl[] = {
X    { "prepend", (APTR)&rexxprepend },
X    { "append", (APTR)&rexxappend },
X    { NULL, NULL }
X};
X
Xchar result[17];
X
Xint disp(msg, dat, p)
Xregister struct RexxMsg *msg ;
Xregister struct rexxCommandList *dat ;
Xchar *p ;
X{
X    result[0] = '\0';
X    ((int (*)())(dat->userdata))(msg, p) ;
X    replyRexxCmd(msg, 0L, 0L, &result[0]);
X    return 1;
X}
X
XVOID pend(addr, p)
Xchar *addr;
Xchar *p;
X{
X    strcpy(&result[0], addr);
X    if (*p) {
X        strncpy(addr, p + 1, 16);
X    }
X}
X
XVOID rexxprepend(msg, p)
Xstruct RexxMsg *msg ;
Xchar *p ;
X{
X    pend(&SnapRsrc->Prepend[0], p);
X}
X
XVOID rexxappend(msg, p)
Xstruct RexxMsg *msg ;
Xchar *p ;
X{
X    pend(&SnapRsrc->Append[0], p);
X}
X
X#endif
END_OF_FILE
if test 847 -ne `wc -c <'source/rexx.c'`; then
    echo shar: \"'source/rexx.c'\" unpacked with wrong size!
fi
# end of 'source/rexx.c'
fi
if test -f 'source/saveilbm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/saveilbm.c'\"
else
echo shar: Extracting \"'source/saveilbm.c'\" \(5748 characters\)
sed "s/^X//" >'source/saveilbm.c' <<'END_OF_FILE'
X/* Auto: make
X*/
X
XIMPORT BPTR SnapFile;
XIMPORT BYTE TranspBuf[];
X
X#define ID(a,b,c,d) ((a << 24L) | (b << 16L) | (c << 8L) | (d))
X
Xstruct ckHdr {
X    LONG ChunkName;
X    LONG ChunkSize;
X};
X
Xstruct BitMapHeader
X{
X   UWORD w,h;
X   WORD  x,y;
X   UBYTE nPlanes;
X   UBYTE masking;
X   UBYTE compression;
X   UBYTE pad1;
X   UWORD transparentColor;
X   UBYTE xAspect, yAspect;
X   WORD  pageWidth, pageHeight;
X};
X
Xstruct ckHdr FORM = {
X    ID('F','O','R','M'),
X    0L
X};
XLONG TYPE = ID('I','L','B','M');
X
Xstruct ckHdr BMHD = {
X    ID('B','M','H','D'),
X    sizeof(struct BitMapHeader)
X};
Xstruct BitMapHeader BMHdr = {
X   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
X};
X
Xstruct ckHdr CAMG = {
X    ID('C','A','M','G'),
X    4L
X};
XULONG ViewMode = NULL;
X
Xstruct ckHdr CMAP = {
X    ID('C','M','A','P'),
X    0L
X};
X
Xstruct ckHdr BODY = {
X    ID('B','O','D','Y'),
X    0L
X};
X
XUBYTE *buf;
XWORD bufcnt;
XULONG totalsize;
X
XWORD bumpmode;
X#define BUMP_CALC   1
X#define BUMP_SAVE   2
X
XWORD bump(cnt, dataptr, size)
XWORD cnt;
XUBYTE *dataptr;
XWORD size;
X{
X    REGISTER LONG tsize = size;
X    if (tsize) {
X        totalsize += tsize + 1;     /* Don't forget the count-byte */
X    }
X    if (bumpmode == BUMP_CALC) {    /* Just calculating? */
X        return 1;                   /* Don't do the save */
X    }
X    if (bufcnt + tsize + 1 >= 4096 || tsize == 0) {
X        if (Write(SnapFile, buf, (LONG)bufcnt) == -1L) {
X            return 0;
X        }
X        bufcnt = 0;
X    }
X    buf[bufcnt++] = cnt;
X    CopyMem((char *)dataptr, (char *)&buf[bufcnt], tsize);
X    bufcnt += tsize;
X    return 1;
X}
X
XULONG WriteBody(BM)
Xstruct BitMap *BM;
X{
X    WORD scanline, plane;
X    REGISTER WORD bpr = BM->BytesPerRow;
X    REGISTER WORD i, j;
X    LONG offset = 0L;
X    REGISTER UBYTE data;
X    REGISTER UBYTE *bd;
X
X    totalsize = 0L;
X
X    if (!(buf = AllocMem(4096L, MEMF_PUBLIC))) {
X        return NULL;
X    }
X
X    bufcnt = 0;
X    for (scanline = 0; scanline < BM->Rows; ++scanline) {
X        for (plane = 0; plane < BM->Depth; ++plane) {
X            bd = BM->Planes[plane]+offset;
X            i = 1;
X            j = bpr - 1;
X            data = bd[0];
X            while (j) {
X                if (bd[i] == data) {        /* Equal bytes? */
X                    --i;                    /* First equal byte */
X                    if (i > 0) {            /* Old "random" data to save */
X                        if (!bump((WORD)(i - 1), bd, i)) {
X                            return NULL;
X                        }
X                    }
X                    bd = &bd[i];        /* Start of equal bytes */
X                    i = 2;              /* 0 & 1 is equal       */
X                    --j;
X                    while (i < 128 && j && bd[i] == data) {
X                        ++i;
X                        --j;
X                    }
X                    if (!bump((WORD)-(i - 1), &bd[i - 1], 1)) {
X                        return NULL;
X                    }
X                    goto new_block;
X                } else {                    /* Not equal. Check block range */
X                    if (i == 128) {         /* Block limit                  */
X                        if (!bump((WORD)(i - 1), bd, i)) {
X                            return NULL;
X                        }
Xnew_block:
X                        bd = &bd[i];  /* Start new block              */
X                        i = 0;
X                        if (j == 0) {
X                            break;
X                        }
X                    }
X                }
X                  /* Different byte or a new start */
X                data = bd[i];               /* New possible equal       */
Xnext_byte:
X                ++i;
X                --j;
X            }
X            if (i != 0) {                   /* Data to save */
X                if (!bump((WORD)(i - 1), bd, i)) {
X                    return NULL;
X                }
X            }
X        }
X        offset += BM->BytesPerRow;
X    }
X    if (!bump(0, NULL, 0)) {   /* Flush any bytes left if the buffer */
X        return NULL;
X    }
X    FreeMem(buf, 4096L);
X    return totalsize;
X}
X
XWORD SaveGS(GS)
Xstruct GfxSnap *GS;
X{
X    ULONG BODYPos;
X    UBYTE *oldtitle;
X
X    oldtitle = GS->window->Title;
X    SetWindowTitles(GS->window, "Saving...", NULL);
X
X    bumpmode = BUMP_SAVE;
X
X    BMHdr.w = GS->BM.BytesPerRow * 8;
X    BMHdr.h = GS->height;
X    BMHdr.x = BMHdr.y = 0;
X    BMHdr.nPlanes = GS->depth;
X    BMHdr.masking = 0;
X    BMHdr.compression = 1;
X    BMHdr.transparentColor = dectoint(TranspBuf);
X    BMHdr.xAspect = BMHdr.xAspect = 1;
X    BMHdr.pageWidth = GS->pagew;
X    BMHdr.pageHeight = GS->pageh;
X    ViewMode = GS->viewmode;
X
X    CMAP.ChunkSize = (LONG)3 * (GS->viewmode & HAM ? 16 : 1L << GS->depth);
X
X    if (Write(SnapFile, (char *)&FORM,
X      (LONG)(sizeof(FORM) + sizeof(TYPE) +
X             sizeof(BMHD) + sizeof(BMHdr) +
X             sizeof(CAMG) + sizeof(ViewMode) +
X             sizeof(CMAP))) == -1L) {
X        return 0;
X    }
X    if (Write(SnapFile, (char *)&GS->rgb[0], CMAP.ChunkSize) == -1L) {
X        return 0;
X    }
X    BODYPos = Seek(SnapFile, 0L, OFFSET_CURRENT);
X    if (Write(SnapFile, (char *)&BODY, (LONG)sizeof(BODY)) == -1L) {
X        return 0;
X    }
X    if (!(BODY.ChunkSize = WriteBody(&GS->BM))) {
X        return 0;
X    }
X    FORM.ChunkSize = BODYPos - sizeof(FORM) + sizeof(BODY) + BODY.ChunkSize;
X    if (FORM.ChunkSize & 1) {                       /* Odd size */
X        if (Write(SnapFile, "X", 1L) == -1L) {
X            return 0;
X        }
X        ++FORM.ChunkSize;
X    }
X    Seek(SnapFile, 0L, OFFSET_BEGINNING);
X    Write(SnapFile, (char *)&FORM, (LONG)sizeof(FORM));
X    Seek(SnapFile, BODYPos, OFFSET_BEGINNING);
X    Write(SnapFile, (char *)&BODY, (LONG)sizeof(BODY));
X    SetWindowTitles(GS->window, oldtitle, NULL);
X    return 1;
X}
END_OF_FILE
if test 5748 -ne `wc -c <'source/saveilbm.c'`; then
    echo shar: \"'source/saveilbm.c'\" unpacked with wrong size!
fi
# end of 'source/saveilbm.c'
fi
if test -f 'source/snap.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/snap.h'\"
else
echo shar: Extracting \"'source/snap.h'\" \(5276 characters\)
sed "s/^X//" >'source/snap.h' <<'END_OF_FILE'
X#include <intuition/intuitionbase.h>
X#ifdef AZTEC_C
X#include <functions.h>
Xstruct IORequest *CreateExtIO(); /* This is a kludge that is necessary    */
X                                 /* since this definition is missing from */
X                                 /* manx's <functions.h> include file.    */
X#endif AZTEC_C
X#include <libraries/arpbase.h>
X#include <devices/input.h>
X#include <devices/keymap.h>
X#include <devices/console.h>
X#include <devices/clipboard.h>
X#include <exec/memory.h>
X#include <exec/interrupts.h>
X#include <graphics/gfxmacros.h>
X
X#define Create(_Obj)     AllocMem((LONG)sizeof(struct _Obj), MEMF_PUBLIC|MEMF_CLEAR)
X#define Kill(_Obj)       FreeMem(_Obj, (LONG)sizeof(*_Obj))
X#define Delete(_Obj)     if (_Obj) FreeMem(_Obj, (LONG)sizeof(*_Obj))
X
X#define SNAPRSRC "Snap.resource"
X
Xstruct SnapRsrc {
X    struct Node node;
X    struct Task *Task;
X    WORD Priority;
X    WORD gfxqual;
X    WORD textqual;
X    WORD insertkey;
X    WORD cwkey;
X    char Prepend[17];
X    char Append[17];
X    WORD flags;
X    LONG chardelay;
X    LONG linedelay;
X    UWORD CrawlPtrn;
X    WORD StartUnit;
X    WORD FrameMask;
X    WORD GadOffset;
X    WORD CacheSize;
X    WORD BadChar;
X};
X
X#define XEROX           1
X#define EARLYPATCH      2
X#define TRUEUNDERSCORE  4
X#define JOINLONG        8
X
Xstruct Snap {
X    ULONG Size;
X    char Chars[1];
X};
X
Xstruct GfxSnap {
X    struct Gadget DiskGad;
X    struct Gadget VProp;
X    struct Gadget HProp;
X    struct PropInfo VInfo;
X    struct PropInfo HInfo;
X    struct Image VImage;
X    struct Image HImage;
X    LONG x, y;
X    LONG width, height;
X    LONG depth;
X    LONG viewmode;
X    char rgb[32][3];
X    SHORT pagew;
X    SHORT pageh;
X    struct Window *window;
X    struct BitMap BM;
X};
X
Xstruct CacheWindow {
X    struct MinNode Node;
X    struct Window *Window;
X    SHORT xoff;
X    SHORT yoff;
X    SHORT fw;
X    SHORT fh;
X};
X
X#define SAVEGAD 1
X#define DISKGAD 2
X#define NAMEGAD 3
X#define VPROP   4
X#define HPROP   5
X
X#define CLIP_FIRST 0
X#define CLIP_CONT  1
X#define CLIP_LAST  2
X
X#define TitleFont(win) ((struct TextFont *)(win->IFont ? win->IFont : win->RPort->Font))
X
X#define Swap2L(_x,_y) { REGISTER LONG _t = _x; _x = _y; _y = _t; }
X
X#define noaction 0
X#define snapgfx  1  /* window */
X#define snaptext 2  /* text */
X#define insert   4  /* inserting */
X
X#define waiting   0
X#define selregion 1
X#define waitext   2
X#define selgfx    3
X#define waitgfx   4
X
X#define UNIT_FRAME 1 /* rect of chars */
X#define UNIT_CHAR  2 /* characters with line wrap */
X#define UNIT_WORD  3 /* words with line wrap */
X#define UNIT_LINE  4 /* lines */
X
X#ifdef LATTICE
X#include <string.h>     /* Prototyping of string functions */
X#include <stdlib.h>     /* Prototyping of standard lib functions */
X#endif
X
X/* C_Args & ARGs borrowed from the Arp include file */
X
XULONG ReadClip ARGs( (struct IOClipReq *, STRPTR, ULONG, WORD) );
XVOID WriteClip ARGs( (struct IOClipReq *, STRPTR, ULONG, WORD) );
XVOID SaveClip ARGs( (UBYTE *, ULONG) );
Xstruct Snap *FetchClip ARGs( (VOID) );
XVOID MultiDraw ARGs( (struct RastPort *, LONG, Point *) );
XVOID crawl_frame ARGs( (LONG) );
XVOID erase_frame ARGs( (VOID) );
XVOID draw_frame ARGs( (LONG) );
XULONG InvertKeyMap ARGs( (ULONG, struct InputEvent *, struct KeyMap *) );
XUWORD LowKeyInvert ARGs( (register UBYTE, struct KeyMap *, UWORD *, UWORD *, ULONG *) );
XVOID IndexKey ARGs( (ULONG, struct KeyMap *, ULONG *) );
XWORD checkNormal ARGs( (LONG, UBYTE, UWORD, UWORD *) );
XWORD checkVanilla ARGs( (UBYTE *, UBYTE, UWORD *) );
XWORD checkDead ARGs( (UBYTE **, UBYTE, UWORD *, ULONG *) );
XWORD deadQual ARGs( (WORD, UWORD *) );
Xstruct Screen *WhichScreen ARGs( (VOID) );
Xstruct Window *WhichWindow ARGs( (struct Screen *) );
XVOID FreePlanes ARGs( (struct BitMap *, LONG, LONG) );
XWORD AllocPlanes ARGs( (struct BitMap *, LONG, LONG) );
XVOID CacheWindow ARGs( (struct Window *, LONG, LONG, SHORT, SHORT) );
Xstruct CacheWindow *GetCachedWindow ARGs( (struct Screen *, struct Window *) );
XVOID CloseStuff ARGs( (VOID) );
XWORD OpenStuff ARGs( (VOID) );
XVOID SafePatch ARGs( (VOID) );
XVOID SafeRestore ARGs( (VOID) );
XWORD bump ARGs( (WORD, UBYTE *, WORD) );
XULONG WriteBody ARGs( (struct BitMap *) );
XWORD SaveGS ARGs( (struct GfxSnap *) );
XWORD isdigit ARGs( (char) );
XLONG dectoint ARGs( (char *) );
XLONG hextoint ARGs( (char *) );
XVOID InsertAscii ARGs( (ULONG) );
XVOID GadText ARGs( (struct Gadget *, char *, LONG) );
XVOID SwapColorMap ARGs( (struct GfxSnap *) );
XVOID CheckWindowMsgs ARGs( (VOID) );
XVOID SetSnapFont ARGs( (struct TextFont *) );
XWORD IsSpace ARGs( (LONG, LONG) );
XVOID update_frame ARGs( (VOID) );
XVOID FindWord ARGs( (VOID) );
XVOID ChangeUnit ARGs( (VOID) );
XVOID ExtendSelection ARGs( (VOID) );
XWORD SnapChars ARGs( (VOID) );
XWORD HandleChars ARGs( (VOID) );
XVOID FixHeights ARGs( (VOID) );
Xstruct GfxSnap *SnapGfx ARGs( (struct RastPort *) );
XVOID ExtendGfx ARGs( (VOID) );
XVOID gfx_frame ARGs( (VOID) );
XWORD HandleGfx ARGs( (VOID) );
Xstruct Window *opensharedwindow ARGs( (struct NewWindow *) );
XVOID closesharedwindow ARGs( (struct Window *) );
XVOID SetUpBorder ARGs( (struct Border *, struct Gadget *) );
XVOID AdjustSize ARGs( (struct GfxSnap *) );
XVOID SyncGS ARGs( (struct GfxSnap *) );
XSHORT OpenCW ARGs( (VOID) );
XUBYTE C_Args interpret ARGs( (UWORD *) );
XVOID CopyFont ARGs( (VOID) );
XVOID myhandler();
END_OF_FILE
if test 5276 -ne `wc -c <'source/snap.h'`; then
    echo shar: \"'source/snap.h'\" unpacked with wrong size!
fi
# end of 'source/snap.h'
fi
if test -f 'source/snapasm.s' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/snapasm.s'\"
else
echo shar: Extracting \"'source/snapasm.s'\" \(8453 characters\)
sed "s/^X//" >'source/snapasm.s' <<'END_OF_FILE'
X        XDEF    _interpret       ; Bitmap-to-Ascii function
X        XDEF    _CopyFont        ; Copies a font and aligns it to 16 bit.
X        XREF    _CharData        ; Font data
X        XREF    _SrcData
X        XREF    _CharLoc
X        XREF    _Modulo
X        XREF    _FontWidth
X        XREF    _FontHeight
X        XREF    _Underscore
X        XREF    _TrueUnderscore
X        XREF    _LoChar
X        XREF    _HiChar
X        XREF    _IFlags
X
X        XDEF   _myActivateWindow
X        XDEF   _myWindowToFront
X        XDEF   _myWindowToBack
X
X        SECTION CODE
X
XUSC     equ 1                   ; Interpreted char was underscored
XPUSC    equ 2                   ; Prevoius char was underscored
XPUS     equ 4                   ; Pending underscored space
X
X_interpret:
X        link    a5,#0
X        movem.l d1-d6/a1,-(sp)   ; Free a couple of registers
X        move.l  8(a5),a1         ; Bitmap
X        move.w  (a1),d2          ; First row
X        moveq   #0,d4            ; Code
X        move.b  _LoChar,d4       ; First char
X        move.w  _FontWidth,d0
X        asl.w   #1,d0            ; Times two for words
X        lea     MaskTable,a0
X        move.w  0(a0,d0.w),d3    ; d3 := mask
X        move.l  _CharData,a0     ; Char image data
X        bclr.b  #PUS,_IFlags     ; No pending-underscored-space
X.lp1
X        cmpi.b  #31,d4           ; Into printable characters yet?
X        bhi     .Search          ; If yes, go and start searching
X        addq    #1,d4            ; Move to next char
X        adda.l  #32,a0           ; Increment bitmap ptr also
X        bra     .lp1             ; Back to check again
X.Search
X        cmp.w   (a0),d2          ; Compare first word
X        bne     .tryinverted     ; Not this one
X        bclr.b  #USC,_IFlags     ; Assume not underscored
X        moveq   #1,d5            ; current word
X        moveq   #0,d6            ; Modulo
X.morerows
X        addq    #2,d6            ; Add modulo - next bit row in image data
X        move.w  0(a0,d6.w),d1    ; Character row
X        cmp.w   0(a1,d6.w),d1
X        beq     .stdmatch        ; Rows matched
X        cmp.w   _Underscore,d5   ; Could it be the underscore line?
X        bne     .tryinverted     ; Nope
X        tst.b   _TrueUnderscore  ; Use true underscore?
X        beq     .uscmatch        ; No. Let's hope it's okay
X        moveq   #0,d1            ;   00000000
X        move.w  0(a0,d6.w),d0    ;   00110000
X        or.w    d0,d1            ;   00110000
X        rol.l   #2,d1            ; 0011000000
X        or.w    d0,d1            ; 0011110000
X        ror.l   #1,d1            ;  X01111000
X        eor.w   d3,d1            ;   10000111
X        or.w    d0,d1            ;   10110111
X        move.w  0(a1,d6.w),d0
X        eor.w   d0,d1            ;   Zero if equal
X                                 ; But, let's skip the last bit since it
X                                 ; may be affected by the next character
X        lsr.w   #1,d1            ; Shift one step right
X        and.w   d3,d1            ; Mask out last bit
X        bne     .tryinverted
X.uscmatch
X        bset.b  #USC,_IFlags     ; Set underscored flag
X.stdmatch
X        addq    #1,d5            ; Next row in bitmap
X        cmp.w   _FontHeight,d5   ; Are we done?
X        bne     .morerows        ; Not yet
X        cmp.b   #32,d4           ; Space
X        bne     .notuspace
X        ; Space. Check for underscore
X        btst.b  #USC,_IFlags     ; Underscored char?
X        beq     .notuspace       ; Nope, everything ok
X        ; Underscored space. Check if previous char was underscored
X        btst.b  #PUSC,_IFlags    ; Previous char underscored?
X        bne     .okuspace        ; Yep, ok underscored space
X        ; Previous char not underscored. Set pending-underscored-space flag
X        ; and go on to check if the normal underscore char matches
X        bset.b  #PUS,_IFlags
X        bra     .tryinverted
X
X.notuspace
X.okuspace
X        bclr.b  #PUSC,_IFlags    ; Clear previous-underscored
X        btst.b  #USC,_IFlags     ; Underscored char?
X        beq     .interpreted     ; Nope
X        bset.b  #PUSC,_IFlags    ; Set previous-underscored
X        bra     .interpreted     ; Got it
X
X.tryinverted
X        move.w  (a0),d1          ; Copy first row
X        eor.w   d3,d1            ; and invert the bits
X        cmp.w   d2,d1            ; Compare inverted rows
X        bne     .trybold         ; No match
X        moveq   #1,d5            ; current row
X        moveq   #0,d6            ; Modulo
X.moreinverted
X        addq    #2,d6
X        move.w  0(a0,d6.w),d1    ; Character row
X        eor.w   d3,d1            ; and invert the bits
X        cmp.w   0(a1,d6.w),d1
X        bne     .trybold         ; Rows didn't match
X        addq    #1,d5            ; Next row in bitmap
X        cmp.w   _FontHeight,d5   ; Are we done?
X        bne     .moreinverted    ; Not yet
X        bra     .interpreted     ; Got it
X
X.trybold
X        move.w  (a0),d1          ; Copy first row
X        lsr.w   #1,d1            ; Shift one step left
X        or.w    (a0),d1          ; Make bold
X        and.w   d3,d1            ; and mask out unwanted bits
X        cmp.w   d2,d1            ; Compare bold rows
X        bne     .trynext         ; No match
X        moveq   #1,d5            ; current row
X        moveq   #0,d6            ; Modulo
X.morebold
X        addq    #2,d6
X        move.w  0(a0,d6.w),d1    ; Character row
X        lsr.w   #1,d1            ; Shift one step left
X        or.w    0(a0,d6.w),d1    ; Make bold
X        and.w   d3,d1            ; and mask out unwanted bits
X        cmp.w   0(a1,d6.w),d1
X        bne     .trynext         ; Rows didn't match
X        addq    #1,d5            ; Next row in bitmap
X        cmp.w   _FontHeight,d5   ; Are we done?
X        bne     .morebold        ; Not yet
X        bra     .interpreted     ; Got it
X
X.trynext
X        adda.l  #32,a0           ; Try next character, 32 bytes/char
X        addq    #1,d4            ;
X        cmp.b   _HiChar,d4       ; Tried all chars?
X        bne     .Search          ; More to try
X        move.l  #255,d4          ; Not found
X        btst.b  #PUS,_IFlags     ; Hey, perhaps it was an underscored space?
X        beq     .interpreted     ; Nope, return not-found
X        move.l  #32,d4
X
X.interpreted
X        move.l  d4,d0
X        movem.l (sp)+,d1-d6/a1
X        unlk    a5
X        rts
X
X
X_CopyFont:
X        movem.l d2-d5/a2-a3,-(sp)   ; Free a couple of registers
X        moveq   #0,d0
X        move.l  _CharData,a2        ; a2 := Destination area
X        move.l  _CharLoc,a3
X        move.b  _LoChar,d5
X        move.w  _Modulo,d3
X
X.NextChar
X        move.w  (a3),d0             ; Get char location
X        adda.w  #4,a3               ; To next, and skip width
X        move.w  d0,d1
X        and.w   #15,d1              ; Shift amount
X        eori.b  #15,d1              ; Negate shift value
X        addq.b  #1,d1               ; d1 := Shift Amount
X
X        move.l  _SrcData,a0
X        lsr.w   #3,d0               ; Byte offset
X        bclr    #0,d0               ; But we deal in words
X        adda.w  d0,a0               ; a0 := chardata
X
X        move.w  _FontWidth,d0
X        asl.w   #1,d0               ; Times two for words
X        lea     MaskTable,a1
X        move.w  0(a1,d0.w),d2       ; d2 := mask
X
X        moveq   #0,d4
X        move.w  _FontHeight,d4
X        move.l  a2,a1               ; a1 := Destination area
X        adda.w  #32,a2              ; a2 to next dest area
X        bra     .loop
X.copyrow
X        move.l  (a0),d0             ; Get character row
X        adda.w  d3,a0               ; Add modulo -- To next row
X        lsr.l   d1,d0               ; Shift data to bit 0 alignment
X        and.w   d2,d0               ; Mask out unwanted bits
X        move.w  d0,(a1)+            ; Save row
X.loop
X        dbra    d4,.copyrow         ; Do all rows
X
X        addq    #1,d5               ; Next char
X        cmp.b   _HiChar,d5          ; Finished?
X        bne     .NextChar           ; Nope -- do next.
X        movem.l (sp)+,d2-d5/a2-a3
X        rts
X
XMaskTable
X        dc.w    $0000
X        dc.w    $8000
X        dc.w    $c000
X        dc.w    $e000
X        dc.w    $f000
X        dc.w    $f800
X        dc.w    $fc00
X        dc.w    $fe00
X        dc.w    $ff00
X        dc.w    $ff80
X        dc.w    $ffc0
X        dc.w    $ffe0
X        dc.w    $fff0
X        dc.w    $fff8
X        dc.w    $fffc
X        dc.w    $fffe
X        dc.w    $ffff
X
X
X_myActivateWindow:
X        rts
X
X_myWindowToFront:
X        rts
X
X_myWindowToBack:
X        rts
X
X        END
END_OF_FILE
if test 8453 -ne `wc -c <'source/snapasm.s'`; then
    echo shar: \"'source/snapasm.s'\" unpacked with wrong size!
fi
# end of 'source/snapasm.s'
fi
if test -f 'source/snapgfx.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'source/snapgfx.c'\"
else
echo shar: Extracting \"'source/snapgfx.c'\" \(8157 characters\)
sed "s/^X//" >'source/snapgfx.c' <<'END_OF_FILE'
X/* Auto: make
X*/
X
XIMPORT struct SnapRsrc *SnapRsrc;
XIMPORT struct Image DiskImage;
XIMPORT struct Gadget DiskGad;
XIMPORT struct Gadget VProp, HProp;
XIMPORT struct PropInfo VInfo, HInfo;
XIMPORT struct Image VImage, HImage;
XIMPORT struct NewWindow Nw;
XIMPORT UBYTE *WindowTitle;
X
X#define MINWIDTH (24 + SnapRsrc->GadOffset + 16)
X#define MINHEIGHT 15
X
XLONG xl; /* leftmost x position */
XLONG xr; /* rightmost x position */
XLONG yt; /* topmost y position */
XLONG yb; /* bottommost y position */
XLONG mx, my; /* Mouse position in pixels */
X
X#define GfxFrame 4L
XIMPORT Point OldFrame[];
XIMPORT Point NewFrame[];
XIMPORT LONG OFType;        /* Old frame type: ShortFrame/LongFrame */
XIMPORT UWORD Ptrn;
XIMPORT WORD Pattern[];
X
XIMPORT struct RastPort MyRP;
XIMPORT struct BitMap MyBM;
XIMPORT struct Screen *theScreen;
Xstruct Layer_Info *LockedLayerInfo;
XIMPORT struct RastPort rp;
X
XIMPORT LONGBITS cancelsignal, donesignal, movesignal, clicksignal, timersignal;
XIMPORT WORD action;
X
XLONG TitleBarHeight;
XLONG ContentsFontHeight;
X
XVOID FixHeights()
X{
X    struct Screen WBScreen;
X    if (GetScreenData((char *)&WBScreen, (LONG)sizeof(struct Screen), WBENCHSCREEN, NULL)) {
X          /* Now this is a good practice */
X        TitleBarHeight = WBScreen.RastPort.TxHeight+2;
X        ContentsFontHeight = WBScreen.Font->ta_YSize;
X    } else {
X          /* Sorry, but I don't realise how this could fail.
X             Well, if we're snapping on another screen and
X             WB is closed and it can't be opened by GetScreenData()...
X             Anyway, IF this should happen -- Use Topaz 8 */
X        TitleBarHeight = 10;
X        ContentsFontHeight = 8;
X    }
X}
X
X/* SnapGfx is the actual graphics snapper.
X** It steals the bitmap data from the given rastport
X** and puts it in a separate bitmap.
X** It also prepares the NewWindow structure according
X** to the snapped bitmap.
X** The coordinates are assumed to be valid.
X*/
X
Xstruct GfxSnap *SnapGfx(rp)
Xstruct RastPort *rp;
X{
X    struct GfxSnap *GS;
X    LONG i;
X
X    GS = Create(GfxSnap);
X    if (!GS) {
X        return NULL;
X    }
X
X    GS->x = xl;
X    GS->y = yt;
X    GS->width = xr - xl + 1;
X    GS->height = yb - yt + 1;
X    GS->depth = rp->BitMap->Depth;
X    GS->viewmode = theScreen->ViewPort.Modes;
X    GS->pagew = theScreen->Width;
X    GS->pageh = theScreen->Height;
X    i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
X      /* Copy the color map in case we should need it later */
X    while (i--) {
X        ULONG col = GetRGB4(theScreen->ViewPort.ColorMap, i);
X        GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
X        GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
X        GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
X    }
X      /* Set up a nice bitmap */
X    InitBitMap(&GS->BM, GS->depth, GS->width, GS->height);
X      /* Get a handle on the bitmap */
X    InitRastPort(&MyRP);
X    MyRP.BitMap = &GS->BM;
X    if (!AllocPlanes(&GS->BM, GS->width, GS->height)) {
X        FreePlanes(&GS->BM, GS->width, GS->height);
X        Kill(GS);
X        return NULL;
X    }
X      /* Copy the selected part of the screen */
X    ClipBlit(rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
X    Nw.LeftEdge = xl;
X    Nw.TopEdge = yt;
X    Nw.Width = GS->width + 18;                   /* Two pixels on each side */
X    Nw.Height = GS->height + TitleBarHeight + 9; /* Bar & scroll bar */
X    Nw.Title = WindowTitle;
X    Nw.MaxWidth = Nw.Width;
X    Nw.MaxHeight = Nw.Height;
X    CopyMem((char *)&DiskGad, (char *)&GS->DiskGad,
X      (LONG)sizeof(DiskGad) + sizeof(VProp) + sizeof(HProp) +
X      sizeof(VInfo) + sizeof(HInfo) + sizeof(VImage) + sizeof(HImage));
X    GS->DiskGad.NextGadget = &GS->VProp;
X    GS->DiskGad.LeftEdge = -(SnapRsrc->GadOffset+16);
X    GS->DiskGad.Height = TitleBarHeight - 2;
X    DiskImage.Height = TitleBarHeight;
X    GS->VProp.NextGadget = &GS->HProp;
X    GS->VProp.TopEdge = TitleBarHeight;
X    GS->VProp.Height = -8 - TitleBarHeight;
X    GS->VProp.GadgetRender = (APTR)&GS->VImage;
X    GS->VProp.SpecialInfo = (APTR)&GS->VInfo;
X    GS->HProp.NextGadget = NULL;
X    GS->HProp.GadgetRender = (APTR)&GS->HImage;
X    GS->HProp.SpecialInfo = (APTR)&GS->HInfo;
X    return GS;
X}
X
XVOID ExtendGfx()
X{
X    /* Fix which row we're talking about */
X    if (my-yt < yb-my) {       /* Find closest row */
X        yt = my;               /* change top row */
X    } else {
X        yb = my;               /* change bottom row */
X    }
X    if (mx-xl < xr-mx) {
X        xl = mx;
X    } else {
X        xr = mx;
X    }
X}
X
XVOID gfx_frame()
X{
X    NewFrame[0].x = xl;  NewFrame[0].y = yt;
X    NewFrame[1].x = xr;  NewFrame[1].y = yt;
X    NewFrame[2].x = xr;  NewFrame[2].y = yb;
X    NewFrame[3].x = xl;  NewFrame[3].y = yb;
X    NewFrame[4].x = xl;  NewFrame[4].y = yt;
X    draw_frame(GfxFrame);
X}
X
XWORD HandleGfx()
X{
X    theScreen = WhichScreen();   /* Find out where we are */
X    if (!theScreen) {            /* Don't know? Forget it. */
X        action = noaction;
X        return 0;
X    }
X      /* Lock everything - find out what happens */
X    LockedLayerInfo = &theScreen->LayerInfo;
X    LockLayers(LockedLayerInfo);
X
X      /* Get a copy. Don't mess with somebody else's RP. */
X    CopyMem((char *)&theScreen->RastPort, (char *)&rp, (long)sizeof(struct RastPort));
X    SetDrMd(&rp, COMPLEMENT);
X
X    xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
X    if (xl < 0) {
X        xl = 0;
X    }
X    if (xl >= theScreen->Width) {  /* Check those corners. Check those corners. */
X        xl = theScreen->Width - 1;
X    }
X    yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
X    if (yt < 0) {
X        yt = 0;
X    }
X    if (yt >= theScreen->Height) {
X        yt = theScreen->Height - 1;
X    }
X    xr = xl;
X    yb = yt;
X    Ptrn = (SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[UNIT_FRAME]);
X    OFType = 0L;
X    gfx_frame();
X
X    FOREVER {
X        REGISTER LONGBITS sig =
X          Wait(movesignal|clicksignal|cancelsignal|donesignal|timersignal);
X
X        if ((sig & timersignal) && (SnapRsrc->CrawlPtrn != 0xffff)) {
X            crawl_frame(1L);
X        }
X
X        if (sig & movesignal || sig & clicksignal) {
X            mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
X            if (mx < 0) {
X                mx = 0;
X            }
X            if (mx>=theScreen->Width) {
X                mx = theScreen->Width - 1;
X            }
X            my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
X            if (my < 0) {
X                my = 0;
X            }
X            if (my>=theScreen->Height) {
X                my = theScreen->Height - 1;
X            }
X            ExtendGfx();
X            gfx_frame();
X        }
X        if (sig & cancelsignal) {          /* Cancelled? */
X            erase_frame();
X            UnlockLayers(LockedLayerInfo);
X            return 0;
X        }
X        if (sig & donesignal) {            /* Finished. Copy gfx. */
X            struct GfxSnap *GS;
X
X            erase_frame();
X            if (xr < xl + MINWIDTH) {          /* Can't have too small windows */
X                xr = xl + MINWIDTH;
X            }
X            if (xr >= theScreen->Width) {
X                xl -= xr - theScreen->Width - 1;
X                xr = theScreen->Width - 1;
X            }
X            if (yb < yt + MINHEIGHT) {
X                yb = yt + MINHEIGHT;
X            }
X            if (yb >= theScreen->Height) {
X                yt -= yb - theScreen->Height - 1;
X                yb = theScreen->Height - 1;
X            }
X            FixHeights();
X            GS = SnapGfx(&rp); /* Snap! */
X            UnlockLayers(LockedLayerInfo);
X            if (GS) {
X                if (GS->window = opensharedwindow(&Nw)) {
X                    GS->window->UserData = (BYTE *)GS;
X                      /* Put gfx in our new window */
X                    (VOID)AddGList(GS->window, &GS->DiskGad, 0L, 3L, NULL);
X                    RefreshGList(&GS->DiskGad, GS->window, NULL, 3L);
X                    AdjustSize(GS);
X                } else {
X                    FreePlanes(&GS->BM, GS->width, GS->height);
X                    Kill(GS);
X                }
X            } else { /* Good question */
X            }
X            action = noaction;
X            return 0;
X        }
X    }
X}
END_OF_FILE
if test 8157 -ne `wc -c <'source/snapgfx.c'`; then
    echo shar: \"'source/snapgfx.c'\" unpacked with wrong size!
fi
# end of 'source/snapgfx.c'
fi
echo shar: End of archive 1 \(of 4\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general dicussion to comp.sys.amiga.