|
|
1.1 ! root 1: /* ! 2: avio.c -- AVIO handling routines ! 3: For a cleaner implementation, look at the BROWSE application. ! 4: ! 5: Implements scrollbars, sets up an AVIO Presentation Space ! 6: Intrinsically linked with a circular queue routine ! 7: ! 8: Created by Microsoft Corporation, 1989 ! 9: */ ! 10: ! 11: #define INCL_AVIO ! 12: #define INCL_DEV ! 13: #define INCL_VIO ! 14: #define INCL_WIN ! 15: #include <os2.h> ! 16: #include "global.h" ! 17: #include "circleq.h" /* Get Circular Buffer routines */ ! 18: #include "avio.h" /* Prototype our routines */ ! 19: #include <stdio.h> /* Needed to open LOG file */ ! 20: /* ! 21: Constants ! 22: */ ! 23: #define AVIO_PS_ROWS 25 /* Dimensions of the AVIO PS */ ! 24: #define AVIO_PS_COLUMNS MAXLINELEN ! 25: #define CATTRBYTES 1 /* 1 or 3 attribute bytes/cell */ ! 26: #define DEFPAGEWIDTH 5 /* Default pagesizes */ ! 27: #define DEFPAGEHEIGHT 5 ! 28: ! 29: char Blank[2] = { 0x20, 0x07 }; ! 30: ! 31: /* ! 32: Macros to make the code more readable ! 33: */ ! 34: /* Upper and Lower Bound Calculations */ ! 35: #define Abs(a) (((a) > 0) ? (a) : (-(a))) ! 36: #define LowerBound(pos, disp, lbound) Max(pos - disp, lbound) ! 37: #define UpperBound(pos, disp, ubound) Min(pos + disp, ubound) ! 38: ! 39: /* Scroll Bar Abbreviations */ ! 40: ! 41: #define DisableSB(hSB) WinSetParent(hSB, HWND_OBJECT, FALSE) ! 42: #define EnableSB(hSB) WinSetParent(hSB, hWndSBParent, FALSE) ! 43: #define HBarHeight() (fNeedHorz ? lHSBHeight : 0L) ! 44: #define VBarWidth() (fNeedVert ? lVSBWidth : 0L) ! 45: #define SetScroll(h, pos, max) \ ! 46: WinSendMsg(h, SBM_SETSCROLLBAR, MPFROM2SHORT(pos, 0), MPFROM2SHORT(0, max)) ! 47: #define UpdateFrame(sb) \ ! 48: WinSendMsg(hWndSBParent, WM_UPDATEFRAME, MPFROMLONG(sb), 0L) ! 49: #define UpdateOff(w) WinEnableWindowUpdate(w, FALSE) ! 50: #define UpdateOn(w) WinEnableWindowUpdate(w, TRUE) ! 51: ! 52: /* Scrolling Macros */ ! 53: #define ClearScreen() ScrollUp(-1) ! 54: #define ScrollDown(n) VioScrollDn(0, 0, -1, -1, n, Blank, hVPS) ! 55: #define ScrollUp(n) VioScrollUp(0, 0, -1, -1, n, Blank, hVPS) ! 56: #define SetCursor(x, y) VioSetCurPos((USHORT) x, (USHORT) y, hVPS) ! 57: ! 58: /* Miscellaneous */ ! 59: /* ! 60: If partial ANSI emulation is desired, use: ! 61: VioSetCurPos((USHORT) x, (USHORT) y, hVPS); \ ! 62: VioWrtTTY(l->szText, l->cch, hVPS) ! 63: */ ! 64: #define Blast(l, x, y) VioWrtCharStr(l->szText, l->cch, x, y, hVPS) ! 65: /* ! 66: Calculate the number of characters in a page ! 67: For nicer behavior, you can do rounding here ! 68: */ ! 69: #define CalcChars(pPg, pCh, default) \ ! 70: ((pCh) ? (Max((int) ((pPg) / ((SHORT) pCh)), 0)) : (default)) ! 71: #define Value(value) WinQuerySysValue(HWND_DESKTOP, value) ! 72: /* ! 73: File-Local Variables ! 74: */ ! 75: HDC hDC; /* Device Context */ ! 76: HVPS hVPS; /* Virtual PS */ ! 77: int iTopLine; /* PS Line of window corner */ ! 78: int iCurCol; /* Current column of window corner */ ! 79: int cchPgWidth; /* Width and height of our window */ ! 80: int cchPgHeight; ! 81: int cchMaxHorz; /* Scroll bar upper bounds */ ! 82: int cchMaxVert; ! 83: BOOL fNeedHorz; /* Do we need the scroll bars or not? */ ! 84: BOOL fNeedVert; ! 85: HWND hWndHScroll; /* Window handles of ScrollBar windows */ ! 86: HWND hWndVScroll; ! 87: HWND hWndSBParent; /* Could mooch off the value in main(), but won't */ ! 88: /* ! 89: Measurements used to help make the window look nice ! 90: */ ! 91: LONG lChWidth, lChHeight; /* Character size */ ! 92: LONG lHSBHeight, lVSBWidth; /* Scrollbar measurements */ ! 93: LONG lMiscWidth, lMiscHeight; /* Border, titlebar, ... */ ! 94: int iMaxWidth, iMaxHeight; /* Client area bounds */ ! 95: int iMaxFrameWidth, iMaxFrameHeight; /* Frame window bounds */ ! 96: BOOL fCreated; /* AVIO PS created */ ! 97: int rc; /* Return code */ ! 98: VIOCURSORINFO vci; ! 99: /* ! 100: Local prototypes ! 101: */ ! 102: void GetMeasurements(void); ! 103: void Update(USHORT, USHORT, USHORT, BOOL); ! 104: void Refresh(BOOL); ! 105: void WantCursor(BOOL); ! 106: void SetScrollPos(void); ! 107: void SetScrollPosHorz(void); ! 108: void SetScrollPosVert(void); ! 109: /* ! 110: The actual routines ! 111: */ ! 112: void GetMeasurements(void) { ! 113: /* ! 114: Get display parameters ! 115: */ ! 116: /* ! 117: Scroll bar widths and heights ! 118: */ ! 119: lHSBHeight = Value(SV_CYHSCROLL); ! 120: lVSBWidth = Value(SV_CXVSCROLL); ! 121: /* ! 122: Non-PS widths and heights ! 123: */ ! 124: lMiscHeight = (Value(SV_CYSIZEBORDER) << 1) /* A border on each side */ ! 125: + Value(SV_CYTITLEBAR) /* The title bar... */ ! 126: + Value(SV_CYMENU) /* ...and the menu bar */ ! 127: + Value(SV_CYBYTEALIGN); /* ...and alignment */ ! 128: ! 129: lMiscWidth = (Value(SV_CXSIZEBORDER) << 1);/* A border on each side */ ! 130: /* ! 131: Height and width of characters ! 132: */ ! 133: rc = DevQueryCaps(hDC, CAPS_CHAR_HEIGHT, 1L, &lChHeight); ! 134: rc = DevQueryCaps(hDC, CAPS_CHAR_WIDTH, 1L, &lChWidth); ! 135: /* ! 136: Compute size of client and frame windows ! 137: */ ! 138: iMaxWidth = (AVIO_PS_COLUMNS * (int) lChWidth); ! 139: iMaxHeight = (AVIO_PS_ROWS * (int) lChHeight); ! 140: iMaxFrameWidth = (iMaxWidth + (int) lMiscWidth); ! 141: iMaxFrameHeight = (iMaxHeight + (int) lMiscHeight); ! 142: /* ! 143: Compute cursor attributes ! 144: */ ! 145: vci.yStart = (USHORT) 0; ! 146: vci.cEnd = (USHORT) lChHeight - 1; ! 147: vci.cx = 0; ! 148: } ! 149: ! 150: void AvioInit(HWND hWndFrame, HWND hWndClient) { ! 151: /* ! 152: Initialize Presentation Space, Device Context, Scroll Bars ! 153: */ ! 154: /* ! 155: Create the AVIO Presentation Space ! 156: */ ! 157: hDC = WinOpenWindowDC(hWndClient); ! 158: VioCreatePS(&hVPS, AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, CATTRBYTES, 0); ! 159: VioAssociate(hDC, hVPS); ! 160: fCreated = TRUE; ! 161: /* ! 162: Turn on the cursor and home it ! 163: */ ! 164: WantCursor(TRUE); ! 165: SetCursor(0, 0); ! 166: /* ! 167: Snag scroll bar info ! 168: */ ! 169: hWndHScroll = WinWindowFromID(hWndFrame, FID_HORZSCROLL); ! 170: hWndVScroll = WinWindowFromID(hWndFrame, FID_VERTSCROLL); ! 171: hWndSBParent = WinQueryWindow(hWndHScroll, QW_PARENT, FALSE); ! 172: fNeedHorz = fNeedVert = TRUE; ! 173: /* ! 174: Get character height in pixels, etc... ! 175: */ ! 176: GetMeasurements(); ! 177: } ! 178: ! 179: void AvioStartup(HWND hWndClient) { ! 180: SWP swp; ! 181: /* ! 182: Initialize the queue ! 183: */ ! 184: QueInit(); ! 185: /* ! 186: Initialize the screen ! 187: */ ! 188: ClearScreen(); ! 189: WinQueryWindowPos(hWndClient, &swp); ! 190: AvioSize(hWndClient, WM_NULL, NULL, MPFROM2SHORT(swp.cx, swp.cy)); ! 191: } ! 192: ! 193: void AvioScroll(USHORT SB_Command, USHORT usPosition, BOOL fHorizontal) { ! 194: /* ! 195: Process the scroll bar messages ! 196: ! 197: These routines are symmetric; in fact, SB_LINELEFT = SB_LINEUP, etc... ! 198: so one might note that this could be condensed. It's left expanded for ! 199: speed and clarity. I bound the values each way so that we stay inside ! 200: the AVIO presentation space. ! 201: */ ! 202: if (fHorizontal) { /* Horizontal Scroll Bar */ ! 203: switch (SB_Command) { ! 204: case SB_LINELEFT: ! 205: iCurCol = LowerBound(iCurCol, 1, 0); break; ! 206: case SB_LINERIGHT: ! 207: iCurCol = UpperBound(iCurCol, 1, cchMaxHorz); break; ! 208: case SB_PAGELEFT: ! 209: iCurCol = LowerBound(iCurCol, cchPgWidth, 0); break; ! 210: case SB_PAGERIGHT: ! 211: iCurCol = UpperBound(iCurCol, cchPgWidth, cchMaxHorz); break; ! 212: case SB_SLIDERTRACK: ! 213: iCurCol = (SHORT) usPosition; ! 214: default: break; ! 215: } ! 216: if (SB_Command != SB_SLIDERTRACK) ! 217: SetScroll(hWndHScroll, iCurCol, cchMaxHorz); ! 218: ! 219: } else { /* Vertical Scroll Bar */ ! 220: switch (SB_Command) { ! 221: case SB_LINEUP: ! 222: iTopLine = LowerBound(iTopLine, 1, 0); break; ! 223: case SB_LINEDOWN: ! 224: iTopLine = UpperBound(iTopLine, 1, cchMaxVert); break; ! 225: case SB_PAGEUP: ! 226: iTopLine = LowerBound(iTopLine, cchPgHeight, 0); break; ! 227: case SB_PAGEDOWN: ! 228: iTopLine = UpperBound(iTopLine, cchPgHeight, cchMaxVert); break; ! 229: case SB_SLIDERTRACK: ! 230: iTopLine = (SHORT) usPosition; ! 231: default: break; ! 232: } ! 233: if (SB_Command != SB_SLIDERTRACK) ! 234: SetScroll(hWndVScroll, iTopLine, cchMaxVert); ! 235: } ! 236: Refresh(FALSE); ! 237: } ! 238: ! 239: MRESULT AvioSize(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) { ! 240: /* ! 241: Do the default AVIO sizing, and kyfe a few values ! 242: */ ! 243: if (!fCreated) return 0L; ! 244: /* ! 245: Compute height and width of page in characters ! 246: ! 247: The scrollbars have already been subtracted out, ! 248: since we are called by the client area. ! 249: */ ! 250: cchPgHeight = CalcChars(SHORT2FROMMP(mp2), lChHeight, DEFPAGEHEIGHT); ! 251: cchPgWidth = CalcChars(SHORT1FROMMP(mp2), lChWidth, DEFPAGEWIDTH); ! 252: /* ! 253: Adjust scrollbar maximums ! 254: */ ! 255: cchMaxVert = Max(AVIO_PS_ROWS - cchPgHeight, 0); ! 256: cchMaxHorz = Max(AVIO_PS_COLUMNS - cchPgWidth, 0); ! 257: /* ! 258: Maintain scrollbar integrity ! 259: */ ! 260: fNeedHorz = (cchMaxHorz > 0); ! 261: fNeedVert = (cchMaxVert > 0); ! 262: SetScroll(hWndHScroll, iCurCol = Min(iCurCol, cchMaxHorz), cchMaxHorz); ! 263: SetScroll(hWndVScroll, iTopLine = Min(iTopLine,cchMaxVert), cchMaxVert); ! 264: /* ! 265: Do the Scroll Bar shifting ! 266: */ ! 267: Refresh(FALSE); ! 268: /* ! 269: Now, do the normal AVIO processing ! 270: */ ! 271: return WinDefAVioWindowProc(hWnd, msg, mp1, mp2); ! 272: } ! 273: ! 274: void Update ! 275: (USHORT usLineNum, USHORT usHowMany, USHORT usStartLine, BOOL fForced) { ! 276: /* ! 277: Updates usHowMany lines starting from usStartLine on screen. ! 278: Starts at saved line usLineNum. If fForced is set, all lines ! 279: in range are displayed; otherwise it's lazy. ! 280: */ ! 281: USHORT i; /* Loop index */ ! 282: USHORT usWhichLine = usLineNum; /* Line to be queried */ ! 283: Line l; /* Line to be output */ ! 284: ! 285: for (i = usStartLine; i < (usStartLine + usHowMany); i++) { ! 286: l = QueQuery(usWhichLine++); /* Get the line */ ! 287: if (!l->fDrawn || fForced) { ! 288: if (l->cch) Blast(l, i, 0); /* Print it out */ ! 289: if (!l->fComplete) SetCursor(i, l->cch); ! 290: l->fDrawn = TRUE; ! 291: } ! 292: } ! 293: } ! 294: ! 295: void Refresh(BOOL fRedraw) { ! 296: /* ! 297: fRedraw forces full redraw if set ! 298: */ ! 299: SHORT sDelta; ! 300: int static iOldTopLine = -AVIO_PS_ROWS; ! 301: ! 302: VioSetOrg(0, iCurCol, hVPS); /* Get the free AVIO horizontal shift */ ! 303: sDelta = iTopLine - iOldTopLine; /* Compute vertical shift */ ! 304: if ((Abs(sDelta) < AVIO_PS_ROWS) && !fRedraw) { ! 305: if (sDelta < 0) { /* Scroll Up -- make sDelta positive*/ ! 306: ScrollDown(-sDelta); ! 307: Update(iTopLine, -sDelta, 0, TRUE); ! 308: } else { /* Scroll Down by sDelta */ ! 309: ScrollUp(sDelta); ! 310: Update(iTopLine + cchPgHeight - sDelta, sDelta, ! 311: cchPgHeight - sDelta, TRUE); ! 312: } ! 313: } else AvioRedraw(); /* Redo the entire screen */ ! 314: iOldTopLine = iTopLine; ! 315: } ! 316: ! 317: void AvioClose (void) { ! 318: /* ! 319: Termination routines ! 320: */ ! 321: /* ! 322: Destroy the Presentation Space ! 323: */ ! 324: VioAssociate(NULL, hVPS); ! 325: VioDestroyPS(hVPS); ! 326: fCreated = FALSE; ! 327: } ! 328: ! 329: void AvioPaint(HWND hWnd) { ! 330: static HPS hPS; ! 331: static RECTL rcl; ! 332: ! 333: hPS = WinBeginPaint(hWnd, NULL, &rcl); ! 334: VioShowPS(AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, hVPS); ! 335: WinEndPaint(hPS); ! 336: } ! 337: ! 338: MRESULT AvioMinMax(PSWP pSWP) { ! 339: /* ! 340: Control Maximizing ! 341: */ ! 342: if (pSWP->fs & (SWP_MAXIMIZE | SWP_RESTORE)) { ! 343: if (pSWP->fs & SWP_MAXIMIZE) { ! 344: /* ! 345: Save cx, cy values for later origin displacement ! 346: */ ! 347: int iOldcx = pSWP->cx; ! 348: int iOldcy = pSWP->cy; ! 349: /* ! 350: Displace, and change to maximum size ! 351: */ ! 352: pSWP->x += (iOldcx - (pSWP->cx = iMaxFrameWidth)); ! 353: pSWP->y += (iOldcy - (pSWP->cy = iMaxFrameHeight)); ! 354: } ! 355: /* ! 356: Now, fix the scroll bars ! 357: */ ! 358: AvioAdjustFrame(pSWP); ! 359: return TRUE; ! 360: } ! 361: return FALSE; ! 362: } ! 363: ! 364: void AvioClear(void) { ClearScreen(); } ! 365: ! 366: void AvioAdjustFrame(PSWP pSWP) { ! 367: /* ! 368: Trap WM_ADJUSTWINDOWPOS messages to the frame with this routine. ! 369: Keep the window sized right, and control scrollbar visibility. ! 370: */ ! 371: BOOL fNeededHorz = fNeedHorz; ! 372: BOOL fNeededVert = fNeedVert; ! 373: /* ! 374: Do scrollbar enable/disable calculations (but don't update the screen) ! 375: */ ! 376: if (pSWP->fs & SWP_MINIMIZE) fNeedHorz = fNeedVert = FALSE; ! 377: if ((pSWP->cx * pSWP->cy) == 0) return; ! 378: /* ! 379: Do we need them? ! 380: */ ! 381: fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight)); ! 382: fNeedHorz = (pSWP->cx < (SHORT) (iMaxFrameWidth + VBarWidth())); ! 383: fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight + HBarHeight())); ! 384: /* ! 385: Do width calculations to make sure we're staying small enough. ! 386: The Tracking Rectangle shouldn't allow us to get too big. ! 387: */ ! 388: /* ! 389: Check if we're stretching too far ! 390: */ ! 391: pSWP->cx = Min(pSWP->cx, iMaxFrameWidth + (int) VBarWidth()); ! 392: pSWP->cy = Min(pSWP->cy, iMaxFrameHeight + (int) HBarHeight()); ! 393: /* ! 394: ...if so, fix, then add them! ! 395: */ ! 396: AvioSize(NULL, WM_NULL, NULL, MPFROM2SHORT( ! 397: pSWP->cx - (int) (lMiscWidth + VBarWidth()), ! 398: pSWP->cy - (int) (lMiscHeight + HBarHeight()) )); ! 399: ! 400: if (fNeedHorz) { ! 401: if (!fNeededHorz) { ! 402: EnableSB(hWndHScroll); ! 403: UpdateOff(hWndHScroll); ! 404: UpdateFrame(FCF_HORZSCROLL); ! 405: UpdateOn(hWndHScroll); ! 406: } ! 407: } else { ! 408: if (fNeededHorz) { ! 409: DisableSB(hWndHScroll); ! 410: UpdateOff(hWndHScroll); ! 411: UpdateFrame(FCF_HORZSCROLL); ! 412: UpdateOn(hWndHScroll); ! 413: } ! 414: } ! 415: if (fNeedVert) { ! 416: if (!fNeededVert) { ! 417: EnableSB(hWndVScroll); ! 418: UpdateOff(hWndVScroll); ! 419: UpdateFrame(FCF_VERTSCROLL); ! 420: UpdateOn(hWndVScroll); ! 421: } ! 422: } else { ! 423: if (fNeededVert) { ! 424: DisableSB(hWndVScroll); ! 425: UpdateOff(hWndVScroll); ! 426: UpdateFrame(FCF_VERTSCROLL); ! 427: UpdateOn(hWndVScroll); ! 428: } ! 429: } ! 430: } ! 431: ! 432: void AvioTrackFrame(HWND hWnd, MPARAM mpTrackFlags) { ! 433: /* ! 434: Takes action on WM_TRACKFRAME message ! 435: */ ! 436: static TRACKINFO tiTrackInfo; ! 437: /* ! 438: Get the tracking information in the TrackInfo structure ! 439: */ ! 440: WinSendMsg(hWnd, WM_QUERYTRACKINFO, mpTrackFlags, &tiTrackInfo); ! 441: WinTrackRect(hWnd, NULL, &tiTrackInfo); ! 442: } ! 443: ! 444: void AvioQueryTrackInfo(PTRACKINFO pTI) { ! 445: /* ! 446: Forces the frame to be byte aligned and bounded ! 447: */ ! 448: BOOL fMove; ! 449: /* ! 450: Get the grid set up for byte alignment ! 451: ! 452: Set cxGrid to half a character width, because sizing ! 453: from the keyboard tries to move by half characters. ! 454: Also, make sure we can move the window freely. ! 455: */ ! 456: fMove = ((pTI->fs & TF_MOVE) == TF_MOVE); ! 457: pTI->fs |= TF_GRID; ! 458: pTI->cxGrid = (fMove) ? 1 : ((SHORT) (lChWidth << 1)); ! 459: pTI->cyGrid = (fMove) ? 1 : ((SHORT) lChHeight); ! 460: /* ! 461: Bound the frame now ! 462: */ ! 463: pTI->ptlMinTrackSize.x = (pTI->cxBorder << 1) + lMiscWidth; ! 464: pTI->ptlMinTrackSize.y = (pTI->cyBorder << 1) + lMiscHeight; ! 465: pTI->ptlMaxTrackSize.x = iMaxFrameWidth + lVSBWidth + (pTI->cxBorder <<1); ! 466: pTI->ptlMaxTrackSize.y = iMaxFrameHeight + lHSBHeight + (pTI->cyBorder <<1); ! 467: } ! 468: ! 469: BOOL AvioUpdateLines(BOOL fPage, BOOL *fPaging) { ! 470: /* ! 471: Update the display ! 472: */ ! 473: int cLines; ! 474: ! 475: cLines = QueUpdateHead(AVIO_PS_ROWS, fPage, *fPaging); ! 476: if (cLines == AVIO_PS_ROWS) *fPaging = TRUE; ! 477: if (cLines > 0) { ! 478: ScrollUp(cLines); ! 479: Update(iTopLine + AVIO_PS_ROWS - cLines, cLines, ! 480: AVIO_PS_ROWS - cLines, TRUE); ! 481: } ! 482: Update(iTopLine, cchPgHeight, 0, FALSE); ! 483: return TRUE; ! 484: } ! 485: ! 486: void AvioRedraw(void) { ! 487: /* ! 488: Clear, then redraw the entire Presentation Space ! 489: */ ! 490: ClearScreen(); ! 491: Update(iTopLine, cchPgHeight, 0, TRUE); ! 492: } ! 493: ! 494: void WantCursor(BOOL fYes) { ! 495: /* ! 496: Do the underscore cursor ! 497: */ ! 498: vci.attr = (USHORT) (fYes ? 0 : -1); ! 499: vci.yStart = 0; ! 500: vci.cEnd = (USHORT) lChHeight - 1; ! 501: vci.cx = 0; ! 502: VioSetCurType(&vci, hVPS); ! 503: } ! 504: ! 505: void AvioPageUp(void) { ! 506: /* ! 507: Execute the Page Up instruction ! 508: */ ! 509: int cLines; ! 510: ! 511: cLines = QuePageUp(AVIO_PS_ROWS); ! 512: ScrollDown(cLines); ! 513: Update(iTopLine, cLines, 0, TRUE); ! 514: } ! 515:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.