home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / COMTALK.ZIP / AVIO.C next >
C/C++ Source or Header  |  1989-02-08  |  15KB  |  508 lines

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