home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
COMTALK.ZIP
/
AVIO.C
next >
Wrap
C/C++ Source or Header
|
1989-02-08
|
15KB
|
508 lines
/*
AVIO action routines
Modeled after BROWSEr routines
Implements scrollbars, sets up an AVIO Presentation Space
Intrinsically linked with a circular queue routine
*/
#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
*/
/*
Get the grid set up for byte alignment
*/
pTI->fs |= TF_GRID;
pTI->cxGrid = (SHORT) lChWidth;
pTI->cyGrid = (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);
}