File:  [OS/2 SDKs] / pmsdk / samples / comtalk / avio.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:28:17 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: pmsdk-1989, HEAD
Microsoft OS/2 SDK PM 02-24-1989

/*
	avio.c -- AVIO handling routines
	For a cleaner implementation, look at the BROWSE application.

	Implements scrollbars, sets up an AVIO Presentation Space
	Intrinsically linked with a circular queue routine

	Created by Microsoft Corporation, 1989
*/

#define  INCL_AVIO
#define	 INCL_DEV
#define  INCL_VIO
#define	 INCL_WIN
#include <os2.h>
#include "global.h"
#include "circleq.h"	/* Get Circular Buffer routines */
#include "avio.h"	/* Prototype our routines */
#include <stdio.h>	/* Needed to open LOG file */
/*
    Constants
*/
#define AVIO_PS_ROWS	25	/* Dimensions of the AVIO PS */
#define AVIO_PS_COLUMNS	MAXLINELEN
#define	CATTRBYTES	1	/* 1 or 3 attribute bytes/cell */
#define	DEFPAGEWIDTH	5	/* Default pagesizes */
#define	DEFPAGEHEIGHT	5

char	Blank[2] = { 0x20, 0x07 };

/*
    Macros to make the code more readable
*/
/* Upper and Lower Bound Calculations */
#define	Abs(a)		(((a) > 0) ? (a) : (-(a)))
#define LowerBound(pos, disp, lbound) Max(pos - disp, lbound)
#define UpperBound(pos, disp, ubound) Min(pos + disp, ubound)

/* Scroll Bar Abbreviations */

#define	DisableSB(hSB)	WinSetParent(hSB,  HWND_OBJECT, FALSE)
#define	EnableSB(hSB)	WinSetParent(hSB, hWndSBParent, FALSE)
#define	HBarHeight()	(fNeedHorz ? lHSBHeight : 0L)
#define	VBarWidth()	(fNeedVert ? lVSBWidth  : 0L)
#define SetScroll(h, pos, max) \
    WinSendMsg(h, SBM_SETSCROLLBAR, MPFROM2SHORT(pos, 0), MPFROM2SHORT(0, max))
#define	UpdateFrame(sb)	\
    WinSendMsg(hWndSBParent, WM_UPDATEFRAME, MPFROMLONG(sb), 0L)
#define	UpdateOff(w)	WinEnableWindowUpdate(w, FALSE)
#define	UpdateOn(w)	WinEnableWindowUpdate(w, TRUE)

/* Scrolling Macros */
#define	ClearScreen()	ScrollUp(-1)
#define ScrollDown(n)	VioScrollDn(0, 0, -1, -1, n, Blank, hVPS)
#define	ScrollUp(n)	VioScrollUp(0, 0, -1, -1, n, Blank, hVPS)
#define	SetCursor(x, y)	VioSetCurPos((USHORT) x, (USHORT) y, hVPS)

/* Miscellaneous */
/*
    If partial ANSI emulation is desired, use:
	VioSetCurPos((USHORT) x, (USHORT) y, hVPS); \
	VioWrtTTY(l->szText, l->cch, hVPS)
*/
#define Blast(l, x, y)	VioWrtCharStr(l->szText, l->cch, x, y, hVPS)
/*
    Calculate the number of characters in a page
    For nicer behavior, you can do rounding here
*/
#define CalcChars(pPg, pCh, default) \
	((pCh) ? (Max((int) ((pPg) / ((SHORT) pCh)), 0)) : (default))
#define	Value(value)	WinQuerySysValue(HWND_DESKTOP, value)
/*
    File-Local Variables
*/
HDC	hDC;		/* Device Context */
HVPS	hVPS;		/* Virtual PS */
int	iTopLine;	/* PS Line of window corner */
int	iCurCol; 	/* Current column of window corner */
int	cchPgWidth;	/* Width and height of our window */
int	cchPgHeight;
int	cchMaxHorz;	/* Scroll bar upper bounds */
int	cchMaxVert;	
BOOL	fNeedHorz;	/* Do we need the scroll bars or not? */
BOOL	fNeedVert;
HWND	hWndHScroll;	/* Window handles of ScrollBar windows */
HWND	hWndVScroll;
HWND	hWndSBParent;	/* Could mooch off the value in main(), but won't */
/*
    Measurements used to help make the window look nice
*/
LONG	lChWidth,   lChHeight;			/* Character size */
LONG	lHSBHeight, lVSBWidth;			/* Scrollbar measurements */
LONG	lMiscWidth, lMiscHeight;		/* Border, titlebar, ... */
int	iMaxWidth,  iMaxHeight;			/* Client area bounds  */
int	iMaxFrameWidth, iMaxFrameHeight;	/* Frame window bounds */
BOOL	fCreated;				/* AVIO PS created */
int	rc;					/* Return code */
VIOCURSORINFO vci;
/*
   Local prototypes
*/
void GetMeasurements(void);
void Update(USHORT, USHORT, USHORT, BOOL);
void Refresh(BOOL);
void WantCursor(BOOL);
void SetScrollPos(void);
void SetScrollPosHorz(void);
void SetScrollPosVert(void);
/*
    The actual routines
*/
void GetMeasurements(void) {
/*
    Get display parameters
*/
    /*
	Scroll bar widths and heights
    */
    lHSBHeight	= Value(SV_CYHSCROLL);
    lVSBWidth	= Value(SV_CXVSCROLL);
    /*
	Non-PS widths and heights
    */ 
    lMiscHeight	= (Value(SV_CYSIZEBORDER) << 1)	/* A border on each side */
		+ Value(SV_CYTITLEBAR)		/* The title bar...      */
		+ Value(SV_CYMENU)		/* ...and the menu bar   */
		+ Value(SV_CYBYTEALIGN);	/* ...and alignment	 */
		
    lMiscWidth	= (Value(SV_CXSIZEBORDER) << 1);/* A border on each side */
    /*
	Height and width of characters
    */
    rc = DevQueryCaps(hDC, CAPS_CHAR_HEIGHT, 1L, &lChHeight);
    rc = DevQueryCaps(hDC, CAPS_CHAR_WIDTH,  1L, &lChWidth);
    /*
	Compute size of client and frame windows
    */
    iMaxWidth		= (AVIO_PS_COLUMNS	* (int) lChWidth);
    iMaxHeight		= (AVIO_PS_ROWS		* (int) lChHeight);
    iMaxFrameWidth	= (iMaxWidth		+ (int) lMiscWidth);
    iMaxFrameHeight	= (iMaxHeight		+ (int) lMiscHeight);
    /*
	Compute cursor attributes
    */
    vci.yStart	= (USHORT) 0;
    vci.cEnd	= (USHORT) lChHeight - 1;
    vci.cx	= 0;
}

void AvioInit(HWND hWndFrame, HWND hWndClient) {
/*
    Initialize Presentation Space, Device Context, Scroll Bars
*/
    /*
	Create the AVIO Presentation Space
    */
    hDC = WinOpenWindowDC(hWndClient);
    VioCreatePS(&hVPS, AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, CATTRBYTES, 0);
    VioAssociate(hDC, hVPS);
    fCreated = TRUE;
    /*
	Turn on the cursor and home it
    */
    WantCursor(TRUE);
    SetCursor(0, 0);
    /*
	Snag scroll bar info
    */
    hWndHScroll  = WinWindowFromID(hWndFrame,  FID_HORZSCROLL);
    hWndVScroll  = WinWindowFromID(hWndFrame,  FID_VERTSCROLL);
    hWndSBParent = WinQueryWindow(hWndHScroll, QW_PARENT, FALSE);
    fNeedHorz	 = fNeedVert  = TRUE;
    /*
	Get character height in pixels, etc...
    */
    GetMeasurements();
}

void AvioStartup(HWND hWndClient) {
    SWP swp;
    /*
	Initialize the queue
    */
    QueInit();
    /*
	Initialize the screen
    */
    ClearScreen();
    WinQueryWindowPos(hWndClient, &swp);
    AvioSize(hWndClient, WM_NULL, NULL, MPFROM2SHORT(swp.cx, swp.cy));
}

void AvioScroll(USHORT SB_Command, USHORT usPosition, BOOL fHorizontal) {
/*
    Process the scroll bar messages

    These routines are symmetric; in fact, SB_LINELEFT = SB_LINEUP, etc...
    so one might note that this could be condensed.  It's left expanded for
    speed and clarity.  I bound the values each way so that we stay inside
    the AVIO presentation space.
*/
    if (fHorizontal) {  /* Horizontal Scroll Bar */
	switch (SB_Command) {
	    case SB_LINELEFT:
		iCurCol = LowerBound(iCurCol, 1, 0); break;
	    case SB_LINERIGHT:
		iCurCol = UpperBound(iCurCol, 1, cchMaxHorz); break;
	    case SB_PAGELEFT:
		iCurCol = LowerBound(iCurCol, cchPgWidth, 0); break;
	    case SB_PAGERIGHT:
		iCurCol = UpperBound(iCurCol, cchPgWidth, cchMaxHorz); break;
	    case SB_SLIDERTRACK:
		iCurCol = (SHORT) usPosition;
	    default: break;
	}
	if (SB_Command != SB_SLIDERTRACK)
	    SetScroll(hWndHScroll, iCurCol, cchMaxHorz);

    } else { /* Vertical Scroll Bar */
	switch (SB_Command) {
	    case SB_LINEUP:
		iTopLine = LowerBound(iTopLine, 1, 0); break;
	    case SB_LINEDOWN:
		iTopLine = UpperBound(iTopLine, 1, cchMaxVert); break;
	    case SB_PAGEUP:
		iTopLine = LowerBound(iTopLine, cchPgHeight, 0); break;
	    case SB_PAGEDOWN:
		iTopLine = UpperBound(iTopLine, cchPgHeight, cchMaxVert); break;
	    case SB_SLIDERTRACK:
		iTopLine = (SHORT) usPosition;
	    default: break;
	}
	if (SB_Command != SB_SLIDERTRACK)
	    SetScroll(hWndVScroll, iTopLine, cchMaxVert);
    }
    Refresh(FALSE);
}

MRESULT AvioSize(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {
/*
    Do the default AVIO sizing, and kyfe a few values
*/
    if (!fCreated) return 0L;
    /*
	Compute height and width of page in characters

	The scrollbars have already been subtracted out,
	since we are called by the client area.
    */
    cchPgHeight = CalcChars(SHORT2FROMMP(mp2), lChHeight, DEFPAGEHEIGHT); 
    cchPgWidth  = CalcChars(SHORT1FROMMP(mp2), lChWidth,  DEFPAGEWIDTH);
    /*
	Adjust scrollbar maximums
    */
    cchMaxVert = Max(AVIO_PS_ROWS    - cchPgHeight, 0);
    cchMaxHorz = Max(AVIO_PS_COLUMNS -  cchPgWidth, 0);
    /*
	Maintain scrollbar integrity
    */
    fNeedHorz = (cchMaxHorz > 0);
    fNeedVert = (cchMaxVert > 0);
    SetScroll(hWndHScroll, iCurCol  = Min(iCurCol, cchMaxHorz), cchMaxHorz);
    SetScroll(hWndVScroll, iTopLine = Min(iTopLine,cchMaxVert), cchMaxVert);
    /*
	Do the Scroll Bar shifting
    */
    Refresh(FALSE);
    /*
	Now, do the normal AVIO processing
    */
    return WinDefAVioWindowProc(hWnd, msg, mp1, mp2);
}

void Update
    (USHORT usLineNum, USHORT usHowMany, USHORT usStartLine, BOOL fForced) {
/*
    Updates usHowMany lines starting from usStartLine on screen.
    Starts at saved line usLineNum.  If fForced is set, all lines
    in range are displayed; otherwise it's lazy.
*/
    USHORT	i;				/* Loop index */
    USHORT	usWhichLine = usLineNum;	/* Line to be queried */
    Line	l;				/* Line to be output */

    for (i = usStartLine; i < (usStartLine + usHowMany); i++) {
	l = QueQuery(usWhichLine++);		/* Get the line */
	if (!l->fDrawn || fForced) {
	    if (l->cch) Blast(l, i, 0);		/* Print it out */
	    if (!l->fComplete) SetCursor(i, l->cch);
	    l->fDrawn = TRUE;
	}
    }
}

void Refresh(BOOL fRedraw) {
/*
    fRedraw forces full redraw if set 
*/
    SHORT  sDelta;
    int static iOldTopLine = -AVIO_PS_ROWS;

    VioSetOrg(0, iCurCol, hVPS); /* Get the free AVIO horizontal shift */
    sDelta = iTopLine - iOldTopLine; /* Compute vertical shift */
    if ((Abs(sDelta) < AVIO_PS_ROWS) && !fRedraw) {
	if (sDelta < 0) { 	/* Scroll Up -- make sDelta positive*/
	    ScrollDown(-sDelta);
	    Update(iTopLine, -sDelta, 0, TRUE);
	} else {		/* Scroll Down by sDelta */
	    ScrollUp(sDelta);
	    Update(iTopLine + cchPgHeight - sDelta, sDelta,
				cchPgHeight - sDelta, TRUE);
	}
    } else AvioRedraw();	/* Redo the entire screen */
    iOldTopLine = iTopLine;
}

void AvioClose (void) {
/*
    Termination routines
*/
    /*
	Destroy the Presentation Space
    */
    VioAssociate(NULL, hVPS);
    VioDestroyPS(hVPS);
    fCreated = FALSE;
}

void AvioPaint(HWND hWnd) {
    static HPS   hPS;
    static RECTL rcl;

    hPS = WinBeginPaint(hWnd, NULL, &rcl);
    VioShowPS(AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, hVPS);
    WinEndPaint(hPS);
} 

MRESULT AvioMinMax(PSWP pSWP) {
/*
    Control Maximizing
*/
    if (pSWP->fs & (SWP_MAXIMIZE | SWP_RESTORE)) {
	if (pSWP->fs & SWP_MAXIMIZE) {
	    /*
		Save cx, cy values for later origin displacement
	    */
	    int iOldcx = pSWP->cx;
	    int iOldcy = pSWP->cy;
	    /*
		Displace, and change to maximum size
	    */
	    pSWP->x += (iOldcx - (pSWP->cx = iMaxFrameWidth));
	    pSWP->y += (iOldcy - (pSWP->cy = iMaxFrameHeight));
	}
	/*
	    Now, fix the scroll bars
	*/
	AvioAdjustFrame(pSWP);
	return TRUE;
    }
    return FALSE;
}

void AvioClear(void) { ClearScreen(); }

void AvioAdjustFrame(PSWP pSWP) {
/*
    Trap WM_ADJUSTWINDOWPOS messages to the frame with this routine.
    Keep the window sized right, and control scrollbar visibility.
*/
    BOOL fNeededHorz = fNeedHorz;
    BOOL fNeededVert = fNeedVert;
/*
    Do scrollbar enable/disable calculations (but don't update the screen)
*/
    if (pSWP->fs & SWP_MINIMIZE) fNeedHorz = fNeedVert = FALSE;
    if ((pSWP->cx * pSWP->cy) == 0) return;
    /*
	Do we need them?
    */
    fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight));
    fNeedHorz = (pSWP->cx < (SHORT) (iMaxFrameWidth  + VBarWidth()));
    fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight + HBarHeight()));
/*
    Do width calculations to make sure we're staying small enough.
    The Tracking Rectangle shouldn't allow us to get too big.
*/
    /*
	Check if we're stretching too far
    */
    pSWP->cx = Min(pSWP->cx, iMaxFrameWidth  + (int) VBarWidth());
    pSWP->cy = Min(pSWP->cy, iMaxFrameHeight + (int) HBarHeight());
    /*
	...if so, fix, then add them!
    */
    AvioSize(NULL, WM_NULL, NULL, MPFROM2SHORT(
	pSWP->cx - (int) (lMiscWidth + VBarWidth()),
	pSWP->cy - (int) (lMiscHeight + HBarHeight()) ));

    if (fNeedHorz) {
	if (!fNeededHorz) {
	    EnableSB(hWndHScroll);
	    UpdateOff(hWndHScroll);
	    UpdateFrame(FCF_HORZSCROLL);
	    UpdateOn(hWndHScroll);
	}
    } else {
	if (fNeededHorz) {
	    DisableSB(hWndHScroll);
	    UpdateOff(hWndHScroll);
	    UpdateFrame(FCF_HORZSCROLL);
	    UpdateOn(hWndHScroll);
	}
    }
    if (fNeedVert) {
	if (!fNeededVert) {
	     EnableSB(hWndVScroll);
	     UpdateOff(hWndVScroll);
	     UpdateFrame(FCF_VERTSCROLL);
	     UpdateOn(hWndVScroll);
	}
    } else {
	if (fNeededVert) {
	     DisableSB(hWndVScroll);
	     UpdateOff(hWndVScroll);
	     UpdateFrame(FCF_VERTSCROLL);
	     UpdateOn(hWndVScroll);
	}
    }
}

void AvioTrackFrame(HWND hWnd, MPARAM mpTrackFlags) {
/*
    Takes action on WM_TRACKFRAME message
*/
    static TRACKINFO tiTrackInfo;
    /*
	Get the tracking information in the TrackInfo structure
    */
    WinSendMsg(hWnd, WM_QUERYTRACKINFO, mpTrackFlags, &tiTrackInfo);
    WinTrackRect(hWnd, NULL, &tiTrackInfo);
}

void AvioQueryTrackInfo(PTRACKINFO pTI) {
/*
    Forces the frame to be byte aligned and bounded
*/
    BOOL fMove;
    /*
	Get the grid set up for byte alignment

	Set cxGrid to half a character width, because sizing
	from the keyboard tries to move by half characters.
	Also, make sure we can move the window freely.
    */
    fMove = ((pTI->fs & TF_MOVE) == TF_MOVE);
    pTI->fs     |= TF_GRID;
    pTI->cxGrid  = (fMove) ? 1 : ((SHORT) (lChWidth << 1));
    pTI->cyGrid  = (fMove) ? 1 : ((SHORT) lChHeight);
    /*
	Bound the frame now
    */
    pTI->ptlMinTrackSize.x = (pTI->cxBorder << 1) + lMiscWidth;
    pTI->ptlMinTrackSize.y = (pTI->cyBorder << 1) + lMiscHeight;
    pTI->ptlMaxTrackSize.x = iMaxFrameWidth  + lVSBWidth +  (pTI->cxBorder <<1);
    pTI->ptlMaxTrackSize.y = iMaxFrameHeight + lHSBHeight + (pTI->cyBorder <<1);
}

BOOL AvioUpdateLines(BOOL fPage, BOOL *fPaging) {
/*
    Update the display
*/
    int	cLines;

    cLines = QueUpdateHead(AVIO_PS_ROWS, fPage, *fPaging);
    if (cLines == AVIO_PS_ROWS) *fPaging = TRUE;
    if (cLines > 0) {
	ScrollUp(cLines);
        Update(iTopLine + AVIO_PS_ROWS - cLines, cLines,
			AVIO_PS_ROWS - cLines, TRUE);
    }
    Update(iTopLine, cchPgHeight, 0, FALSE);
    return TRUE;
}

void AvioRedraw(void) {
/*
    Clear, then redraw the entire Presentation Space
*/
    ClearScreen();
    Update(iTopLine, cchPgHeight, 0, TRUE);
}

void WantCursor(BOOL fYes) {
/*
    Do the underscore cursor
*/
    vci.attr	= (USHORT) (fYes ? 0 : -1);
    vci.yStart	= 0;
    vci.cEnd	= (USHORT) lChHeight - 1;
    vci.cx	= 0;
    VioSetCurType(&vci, hVPS);
}

void AvioPageUp(void) {
/*
    Execute the Page Up instruction
*/
    int cLines;

    cLines = QuePageUp(AVIO_PS_ROWS);
    ScrollDown(cLines);
    Update(iTopLine, cLines, 0, TRUE);
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.