DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦382bfa310⟧ TextFile

    Length: 5020 (0x139c)
    Types: TextFile
    Notes: UNIX file
    Names: »dmenu1.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦2d53db1df⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »hr/src/desk/dmenu1.c« 

TextFile

#include "desk.h"
#define	MIN(x,y)	((x) < (y) ? (x) : (y) )

/************************************************************************

    Support Routines:

	mu_OpenMenu -	Open a menu window.
	mu_Draw -	Draw the menu window frame and contents.
	mu_FindItem -	Find a menu window and item that contains the pt.
	mu_InvertItem -	Invert the item of the given menu window.
	mu_NClose -	Close active menu levels N through last.

 ************************************************************************/


int mu_OpenMenu(id, pt)
unsigned id;
POINT	 pt;
{
	register MENU	*m;
	register int	dimx, dimy;

#ifdef DEBUG
	printf("\tIn mu_OpenMenu:\t%d, (%d,%d)\n", id, pt.x, pt.y);
#endif
	m = &mu_menu[id];

	if ( id >= NMENU || mu_am.ma_menu )
		return -1;
	if ( !m->mn_n || !R_point_in(dskBitmap.rect, pt) )
		return -1;

	/*
	 *	Determine where and how big the window should be, given
	 *	the requirements of the menu and the constraints on the
	 *	window location (dskBitmap.rect).
	 */
	dimx = LMARGIN + RMARGIN + m->mn_width;
	dimy = UMARGIN + DMARGIN + m->mn_height;
	if ( dimx + pt.x > dskBitmap.rect.corner.x )
		pt.x = dskBitmap.rect.corner.x - dimx;
	if ( dimy + pt.y > dskBitmap.rect.corner.y )
		pt.y = dskBitmap.rect.corner.y - dimy;
	mu_am.ma_menu = &mu_menu[id];
	mu_am.ma_elt = -1;
	mu_am.ma_rect.origin = pt;
	mu_am.ma_rect.corner.x = pt.x + dimx;
	mu_am.ma_rect.corner.y = pt.y + dimy;
	mu_am.ma_rect = R_Intersection(mu_am.ma_rect, dskBitmap.rect);

	mu_am.ma_crect.corner.x = (mu_am.ma_crect.origin.x = mu_am.ma_rect.origin.x) + m->mn_width;
	mu_am.ma_crect.corner.y = (mu_am.ma_crect.origin.y = mu_am.ma_rect.origin.y) + m->mn_height;
	mu_am.ma_crect = R_offset(mu_am.ma_crect, LMARGIN, UMARGIN);

	if ( (mu_am.ma_heap = D_Open(&mu_am.ma_rect)) < 0 )
		return -1;
	else
	{
#ifdef DEBUG
		dumpamenu(&mu_am);
#endif
		mu_Draw();
		return 0;
	}
}



mu_Draw()
{
	register MENU	*m;
	register IMENU	*mi;
	register int	i;
	POINT	pt;
	RECT	rect;

#ifdef DEBUG
	printf("In mu_Draw:\n");
#endif
	m = mu_am.ma_menu;
	mi= m->mn_item;

	/*
	 *	Draw Frame
	 */
	dskClip = mu_am.ma_rect;
	rect.origin = mu_am.ma_rect.origin;
	rect.corner.x = mu_am.ma_rect.origin.x + m->mn_width + LMARGIN + 1;
	rect.corner.y = mu_am.ma_rect.origin.y + m->mn_height + UMARGIN + 1;
	D_Frame(&rect, 1);
	rect.origin.x = rect.corner.x;
	rect.origin.y += 4;
	rect.corner.x += 4;
	rect.corner.y += 4;
	InvertRect(&rect);
	rect.origin.x = mu_am.ma_rect.origin.x + 4;
	rect.corner.x -= 4;
	rect.origin.y = rect.corner.y - 4;
	InvertRect(&rect);

	/*
	 *	Draw contents
	 */
	pt = mu_am.ma_rect.origin;
	dskClip = mu_am.ma_crect;
	pt.x += LMARGIN + MHFILL;
	pt.y += UMARGIN + dskFntA;
	for ( i = m->mn_n ; i ; i-- )
	{
		if ( mi->mi_len == 2*MHFILL )
		{
			/* Empty item gets a horizontal line */
			rect.origin.x = mu_am.ma_crect.origin.x;
			rect.corner.x = mu_am.ma_crect.corner.x;
			rect.origin.y = pt.y - dskFntA + dskFntH/2;
			rect.corner.y = rect.origin.y + 1;
			InvertRect(&rect);
		}
		else if ( mi->mi_clen )
			D_Str(mi->mi_str, mi->mi_clen, pt);
		pt.y += dskFntH;
		mi++;
	}
}


/*
**  mu_FindItem(pt, ptr) - Return item id of element within point 'pt'.
**
**	Entry:	pt,	physical point coordinate
**		ptr,	^ for returning a child menu's origin.
**
**	Exit:	-1,	if not inside any menu element of the active menu
**		menu element number, otherwise
**
**	Note:	A point for fixing the location of a child menu (if any for
**		the menu element) is returned indirectly through pointer 'pt',
**		in physical coordinates. The point is meaningless if the
**		function returns -1. Note, a horizontal menu generates a child
**		below it; a vertical menu generates a child to the right of it.
*/
mu_FindItem(pt, ptr)
POINT pt;
register POINT *ptr;
{
	register IMENU	*mi;
	int	x;
	int	i;
	int	n;

	if ( !R_point_in(mu_am.ma_rect, pt) )
		return -1;

	if ( pt.y < mu_am.ma_crect.origin.y )
		n = 0;
	else
		n = (MIN(pt.y, mu_am.ma_crect.corner.y-1) - mu_am.ma_crect.origin.y)/dskFntH;
	ptr->x = mu_am.ma_rect.corner.x;
	ptr->y = mu_am.ma_crect.origin.y + n * dskFntH;
	mi = &mu_am.ma_menu->mn_item[n];

	if ( mi->mi_clen == 0 || (mi->mi_flag & 01) == 0 )
		return -1;
	return n;
}


mu_InvertItem()
{
	register IMENU	*mi;
	register int	n;
	RECT	 rect;

	/*
	 *	Don't do inactive or empty menu items
	 */
	if ( (n = mu_am.ma_elt) == -1 )
		return;
	mi = &mu_am.ma_menu->mn_item[n];
	if ( mi->mi_clen == 0 || (mi->mi_flag & 01) == 0 )
		return;
#ifdef DEBUG
	printf("\tIn mu_InvertItem:\titem=%d\t", n);
#endif

	/*
	 *	Toggle the on/off indicator of the menu item.
	 */
	mi->mi_flag ^= 02;

	/*
	 *	Calculate in physical coordinates the rectangle to
	 *	invert.  Then invert it!
	 */
	rect.origin.x = LMARGIN;
	rect.origin.y = UMARGIN + dskFntH*n;
	rect.corner.x = LMARGIN + mu_am.ma_crect.corner.x - mu_am.ma_crect.origin.x;
	rect.corner.y = rect.origin.y + dskFntH;
	rect = R_addp(rect, mu_am.ma_rect.origin);
#ifdef DEBUG	
	printf("(%d,%d),(%d,%d)\n", rect.origin.x, rect.origin.y, rect.corner.x, rect.corner.y);
#endif
	InvertRect(&rect);
}