[unix-pc.sources] Window iconifier for 7300

daveb@llama.UUCP (12/07/87)

Here is a convenient program for people running small fonts on their
7300 or 3b1s.  Run out of a shell window, it saves the state and
collapses into a small window with a drag icon.  This lets you put
something aside for later use.

Once the window is closed, mousing the [X], or selecting the window
contents with the mouse will open the saved window at it's previous
location.

What I really want is an even smaller draggable window without using the
stupid borders, like a SunTools icon.  Or X windows.  Yeah, that's it...

-dB

/*
** close.c -- 7300 close window, then restore state.
**
** 12/6/87 Dave Brower {sun, mtxinu, cpsc6a}!rtech!daveb.
**
** This is used with a 120 or 132 character system font, where
** you want shell windows around, but not taking up screen space.
** X-ing a "closed" window restores it to full glory.
**
** This has code swiped from barry schein and the STORE's etch program,
** and is hereby placed in the public domain.
*/

# include	<stdio.h>
# include	<sys/types.h>
# include	<sys/window.h>
# include	<sys/mouse.h>
# include	<kcodes.h>

typedef unsigned short  U;

/* inside the window */

#define XMAX	uw.uw_width			/* in pixels		*/
#define YMAX	uw.uw_height			/* in pixels		*/
#define BPERBY	8				/* bits per byte	*/
#define XMAXB	((XMAX+(BPERBY-1))/BPERBY)	/* in bytes		*/
#define YMAXB	YMAX				/* same as pixels	*/

int Wn;				/* window */
struct uwdata	uw;		/* current window data */
struct uwdata	Suw;		/* Saved window data */
U Sbitmap[ 15660 ];		/* Saved screen */

main()
{
    char but;
    short x0, y0;
    struct umdata mouse;

    Wn = 1;
    if ( ioctl( Wn, WIOCGETD, &uw) != 0 )
    {
	fprintf(stderr, "Can't close a non-window.\n");
	exit(1);
    }
    winit();
    keypad(0,1);
    iconify();
    for(;;)
    {
	if( ioctl(Wn, WIOCGETMOUSE, &mouse) < 0 )
	    oops("mouse get");
	mouse.um_flags = MSDOWN;
	if( ioctl(Wn, WIOCSETMOUSE, &mouse) < 0 )
	    oops("mouse set");
	waitmouse(Wn, &x0, &y0, &but);
	if( but )
	    restore();
    }
    /*NOTREACHED*/
}

/*
** Turn the window into an "icon".
*/
iconify()
{
    /* save the bitmap */
    if( wrastop(Wn, (U*)0,0, Sbitmap, XMAXB, 0,0, 0,0, XMAX, YMAX,
	SRCSRC, DSTSRC, (U*)0 ) < 0 )
	oops("save wrastop");

    /* save the window state */
    Suw = uw;

    /* shrink to small draggable window */
    uw.uw_uflags &= ~(NBORDER | BORDRESIZE | BORDHELP);
    uw.uw_uflags |= BORDCANCEL;
    uw.uw_height = 2 * uw.uw_vs;
    uw.uw_width = 18 * uw.uw_hs;
    if( ioctl( Wn, WIOCSETD, &uw ) < 0 )
	restore();

    /* Turn cursor off */
    fprintf(stderr, "\n\nClosed window\033[=1C" );
}



/*
** Restore the window to the saved size and state.
*/
restore()
{
    uw = Suw;
    if( ioctl( Wn, WIOCSETD, &uw ) < 0 )
	oops("restore WIOCSETD");

    if ( wrastop(Wn, Sbitmap, XMAXB, (U*)0,0, 0,0, 0,0, XMAX, YMAX,
	    SRCSRC, DSTSRC, (U*)0 ) < 0 )
	oops("restore wrastop");

    /* position cursor to the end, and turn it on */
    fprintf(stderr, "\033[24;1H\033[=0C");

    wexit( 0 );
}


/*
** Wait for and return mouse motion.
** Presumes a suitable WIOCSETMOUSE has already been done.
*/
waitmouse(wn, xp, yp, bp)
short wn;
short *xp, *yp;
char *bp;
{
    int c;
    int x, y;
    int btni, dummy;

    for (;;)
    {
	c = wgetc(wn);

	/* Cancl is also the moused 'X' in the border */
	if ( c == Exit || c == Cancl || c == s_Cancl || c == EOF )
		restore();

	if (c == Mouse)
	{
	    wreadmouse(wn, &x, &y, &btni, &dummy);
	    *xp = x;
	    *yp = y;
	    *bp = btni;
	    return;
	}
    }
}


/*
** fatal error, print error and wexit.
*/
oops( msg )
char *msg;
{
	perror(msg);
	wexit( 1 );
}

"I don't care what you say, as long as you spell my name right."
{amdahl, cbosgd, mtxinu, ptsfa, sun}!rtech!daveb daveb@rtech.uucp