home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / comtalk / avio.c next >
Encoding:
C/C++ Source or Header  |  1990-07-10  |  14.8 KB  |  518 lines

  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. MRESULT AvioMinMax(PSWP pSWP) {
  338. /*
  339.     Control Maximizing
  340. */
  341.     if (pSWP->fs & (SWP_MAXIMIZE | SWP_RESTORE)) {
  342.     if (pSWP->fs & SWP_MAXIMIZE) {
  343.         /*
  344.         Save cx, cy values for later origin displacement
  345.         */
  346.         int iOldcx = pSWP->cx;
  347.         int iOldcy = pSWP->cy;
  348.         /*
  349.         Displace, and change to maximum size
  350.         */
  351.         pSWP->x += (iOldcx - (pSWP->cx = iMaxFrameWidth));
  352.         pSWP->y += (iOldcy - (pSWP->cy = iMaxFrameHeight));
  353.     }
  354.     /*
  355.         Now, fix the scroll bars
  356.     */
  357.     AvioAdjustFrame(pSWP);
  358.     return (MRESULT) TRUE;
  359.     }
  360.     return FALSE;
  361. }
  362.  
  363. void AvioClear(void) { ClearScreen(); }
  364.  
  365. void AvioAdjustFrame(PSWP pSWP) {
  366. /*
  367.     Trap WM_ADJUSTWINDOWPOS messages to the frame with this routine.
  368.     Keep the window sized right, and control scrollbar visibility.
  369. */
  370.     BOOL fNeededHorz = fNeedHorz;
  371.     BOOL fNeededVert = fNeedVert;
  372. /*
  373.     Do scrollbar enable/disable calculations (but don't update the screen)
  374. */
  375.     if (pSWP->fs & SWP_MINIMIZE) fNeedHorz = fNeedVert = FALSE;
  376.     if ((pSWP->cx * pSWP->cy) == 0) return;
  377.     /*
  378.     Do we need them?
  379.     */
  380.     fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight));
  381.     fNeedHorz = (pSWP->cx < (SHORT) (iMaxFrameWidth  + VBarWidth()));
  382.     fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight + HBarHeight()));
  383. /*
  384.     Do width calculations to make sure we're staying small enough.
  385.     The Tracking Rectangle shouldn't allow us to get too big.
  386. */
  387.     /*
  388.     Check if we're stretching too far
  389.     */
  390.     pSWP->cx = Min(pSWP->cx, iMaxFrameWidth  + (int) VBarWidth());
  391.     pSWP->cy = Min(pSWP->cy, iMaxFrameHeight + (int) HBarHeight());
  392.     /*
  393.     ...if so, fix, then add them!
  394.     */
  395.     AvioSize(NULL, WM_NULL, NULL, MPFROM2SHORT(
  396.     pSWP->cx - (int) (lMiscWidth + VBarWidth()),
  397.     pSWP->cy - (int) (lMiscHeight + HBarHeight()) ));
  398.  
  399.     if (fNeedHorz) {
  400.     if (!fNeededHorz) {
  401.         EnableSB(hWndHScroll);
  402.         UpdateOff(hWndHScroll);
  403.         UpdateFrame(FCF_HORZSCROLL);
  404.         UpdateOn(hWndHScroll);
  405.     }
  406.     } else {
  407.     if (fNeededHorz) {
  408.         DisableSB(hWndHScroll);
  409.         UpdateOff(hWndHScroll);
  410.         UpdateFrame(FCF_HORZSCROLL);
  411.         UpdateOn(hWndHScroll);
  412.     }
  413.     }
  414.     if (fNeedVert) {
  415.     if (!fNeededVert) {
  416.          EnableSB(hWndVScroll);
  417.          UpdateOff(hWndVScroll);
  418.          UpdateFrame(FCF_VERTSCROLL);
  419.          UpdateOn(hWndVScroll);
  420.     }
  421.     } else {
  422.     if (fNeededVert) {
  423.          DisableSB(hWndVScroll);
  424.          UpdateOff(hWndVScroll);
  425.          UpdateFrame(FCF_VERTSCROLL);
  426.          UpdateOn(hWndVScroll);
  427.     }
  428.     }
  429. }
  430.  
  431. void AvioTrackFrame(HWND hWnd, MPARAM mpTrackFlags) {
  432. /*
  433.     Takes action on WM_TRACKFRAME message
  434. */
  435.     static TRACKINFO tiTrackInfo;
  436.     /*
  437.     Get the tracking information in the TrackInfo structure
  438.     */
  439.     WinSendMsg(hWnd, WM_QUERYTRACKINFO, mpTrackFlags, &tiTrackInfo);
  440.     WinTrackRect(hWnd, NULL, &tiTrackInfo);
  441. }
  442.  
  443. void AvioQueryTrackInfo(PTRACKINFO pTI) {
  444. /*
  445.     Forces the frame to be byte aligned and bounded
  446. */
  447.     BOOL fMove;
  448.     /*
  449.     Get the grid set up for byte alignment
  450.  
  451.     Set cxGrid to half a character width, because sizing
  452.     from the keyboard tries to move by half characters.
  453.     Also, make sure we can move the window freely.
  454.     */
  455.     fMove = ((pTI->fs & TF_MOVE) == TF_MOVE);
  456.     pTI->fs     |= TF_GRID;
  457.     pTI->cxGrid  = (fMove) ? 1 : ((SHORT) lChWidth);
  458.     pTI->cyGrid  = (fMove) ? 1 : ((SHORT) lChHeight);
  459.     pTI->cxKeyboard = (SHORT) lChWidth;
  460.     pTI->cyKeyboard = (SHORT) lChHeight;
  461.     /*
  462.     Bound the frame now
  463.     */
  464.     pTI->ptlMinTrackSize.x = (pTI->cxBorder << 1) + lMiscWidth;
  465.     pTI->ptlMinTrackSize.y = (pTI->cyBorder << 1) + lMiscHeight;
  466.     pTI->ptlMaxTrackSize.x = iMaxFrameWidth  + lVSBWidth +  (pTI->cxBorder <<1);
  467.     pTI->ptlMaxTrackSize.y = iMaxFrameHeight + lHSBHeight + (pTI->cyBorder <<1);
  468. }
  469.  
  470. BOOL AvioUpdateLines(BOOL fPage, BOOL *fPaging) {
  471. /*
  472.     Update the display
  473. */
  474.     int    cLines;
  475.  
  476.     cLines = QueUpdateHead(AVIO_PS_ROWS, fPage, *fPaging);
  477.     if (cLines == AVIO_PS_ROWS) *fPaging = TRUE;
  478.     if (cLines > 0) {
  479.     ScrollUp(cLines);
  480.         Update(iTopLine + AVIO_PS_ROWS - cLines, cLines,
  481.             AVIO_PS_ROWS - cLines, TRUE);
  482.     }
  483.     Update(iTopLine, cchPgHeight, 0, FALSE);
  484.     return TRUE;
  485. }
  486.  
  487. void AvioRedraw(void) {
  488. /*
  489.     Clear, then redraw the entire Presentation Space
  490. */
  491.     ClearScreen();
  492.     Update(iTopLine, cchPgHeight, 0, TRUE);
  493. }
  494.  
  495. void WantCursor(BOOL fYes) {
  496. /*
  497.     Do the underscore cursor
  498. */
  499.     vci.attr    = (USHORT) (fYes ? 0 : -1);
  500.     vci.yStart    = 0;
  501.     vci.cEnd    = (USHORT) lChHeight - 1;
  502.     vci.cx    = 0;
  503.     VioSetCurType(&vci, hVPS);
  504. }
  505.  
  506. void AvioPageUp(void) {
  507. /*
  508.     Execute the Page Up instruction
  509. */
  510.     int cLines;
  511.  
  512.     cLines = QuePageUp(AVIO_PS_ROWS);
  513.     ScrollDown(cLines);
  514.     Update(iTopLine, cLines, 0, TRUE);
  515. }
  516.  
  517.