home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c005 / 5.ddi / C / WNHIDE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-08-05  |  12.8 KB  |  447 lines

  1. /**
  2. *
  3. * Name        wnhide -- Conceal window but leave it attached to
  4. *              video display device and page.
  5. *
  6. * Synopsis    presult = wnhide(pwin);
  7. *
  8. *        BWINDOW *presult  Pointer to newly-hidden BWINDOW
  9. *                  structure, or NIL if failure.
  10. *        BWINDOW *pwin      Pointer to BWINDOW structure to
  11. *                  conceal.
  12. *
  13. * Description    This function makes a currently-displayed window
  14. *        invisible and restores the previous contents of the
  15. *        screen.  The window's location and border remain set so
  16. *        the window may later be redisplayed via WNUNHIDE.
  17. *
  18. *        An error occurs if pwin does not point to a valid window
  19. *        structure, or if the window has been designated "not
  20. *        removable", or if the window is not currently displayed.
  21. *
  22. *        Use WNREMOVE to remove the window and detach it from its
  23. *        location and border.  Use WNFORGET to detach it from its
  24. *        location and border without restoring the screen.
  25. *
  26. * Returns    presult       Pointer to newly-hidden BWINDOW
  27. *                  structure, or NIL if failure.
  28. *        *pwin          Several fields altered.
  29. *        b_pactnode[][]      Window node with active cursor.
  30. *        b_wnerr       Possible values:
  31. *                  (No change)       Success.
  32. *                  WN_BAD_WIN       *pwin is invalid.
  33. *                  WN_NOT_SHOWN       Not currently shown.
  34. *                  WN_CANT_HIDE       Not removable.
  35. *                  WN_BAD_NODE       Internal error.
  36. *                  WN_BAD_DEV       Internal error.
  37. *                  WN_ILL_DIM       Internal error.
  38. *                  WN_NULL_PTR       Internal error.
  39. *
  40. * Version    3.0  (C)Copyright Blaise Computing Inc. 1986
  41. *
  42. **/
  43.  
  44. #include <bwindow.h>
  45.  
  46.     /* Internal functions defined below:                  */
  47.  
  48.                       /* Hide covering windows.       */
  49. static WIN_NODE *undisp(WIN_NODE *,LOC *,DIM *);
  50.                       /* Mark lower windows uncovered.*/
  51. static WIN_NODE *uncovr(WIN_NODE *,LOC *,DIM *);
  52.                       /* Check for covering windows.  */
  53. static int     upcovr(WIN_NODE *,LOC *,DIM *);
  54.                       /* Redisplay covering windows.  */
  55. static WIN_NODE *redisp(WIN_NODE *);
  56.  
  57. BWINDOW *wnhide(pwin)
  58. BWINDOW *pwin;
  59. {
  60.     int      old_dev,old_page,old_npage;
  61.     int      mode,columns,act_page;
  62.     BWINDOW  *presult;
  63.     int      dev,page;
  64.     int      row,col,high,low;
  65.     WIN_NODE *pnode;
  66.  
  67.     if (wnvalwin(pwin) == NIL)          /* Validate window structure    */
  68.     {
  69.     wnerror(WN_BAD_WIN);
  70.     return NIL;
  71.     }
  72.  
  73.     if (pwin->options.hidden)          /* Quit if already invisible    */
  74.     return pwin;
  75.  
  76.     if (!pwin->options.removable)
  77.     {
  78.     wnerror(WN_CANT_HIDE);          /* Error if not removable       */
  79.     return NIL;
  80.     }
  81.  
  82.     old_page = b_curpage;          /* Note current page on former  */
  83.                       /* device.              */
  84.  
  85.                       /* Note former device.          */
  86.     old_dev  = scmode(&mode,&columns,&act_page);
  87.  
  88.     if (wnseldev(&pwin->where_prev,&pwin->prev.dim,&old_npage))
  89.     {                      /* Validate and select device   */
  90.     wnerror(WN_NOT_SHOWN);          /* and page.              */
  91.     return NIL;
  92.     }
  93.  
  94.     presult = pwin;              /* Temporarily remove higher    */
  95.                       /* windows which cover this one.*/
  96.     if (NIL == undisp(pwin->pnode,
  97.               &pwin->where_prev.corner,
  98.               &pwin->prev.dim))
  99.     presult = NIL;
  100.  
  101.     pwin->internals.temp_hid = 0;     /* Correct internal flag:       */
  102.                       /* this window was un-displayed */
  103.                       /* by UNDISP but NOT temporarily*/
  104.  
  105.     pwin->options.hidden = 1;
  106.                       /* Mark lower windows if          */
  107.                       /* uncovered.              */
  108.     if (uncovr(pwin->pnode,
  109.            &pwin->where_prev.corner,
  110.            &pwin->prev.dim)      == NIL)
  111.     presult = NIL;
  112.  
  113.     dev  = pwin->where_shown.dev;
  114.     page = pwin->where_shown.page;
  115.     if (b_pactnode[dev][page]->pwin == pwin)
  116.     {                      /* Then this window is the one  */
  117.                       /* whose cursor is active.      */
  118.     b_pactnode[dev][page] = NIL;
  119.                       /* Now no window has an active  */
  120.                       /* cursor.              */
  121.     sccurst(&row,&col,&high,&low);/* Retrieve cursor size.          */
  122.     scpgcur(1,high,low,CUR_NO_ADJUST);  /* Turn cursor off.       */
  123.     }
  124.     pwin->internals.cur_frozen = 1;
  125.  
  126.                       /* Redisplay higher windows.    */
  127.     if (redisp(pwin->pnode) == NIL)   /* (also mark lower windows     */
  128.     presult = NIL;              /* if covered).              */
  129.  
  130.                       /* Since we may have just       */
  131.                       /* exposed some windows, update */
  132.                       /* each lower window on this    */
  133.                       /* display page              */
  134.     for (pnode = b_wnlist[dev][pwin->where_shown.page];
  135.      pnode != NIL;
  136.      pnode = pnode->below)
  137.     {                      /* (except for the ones that    */
  138.     if (!pnode->pwin->options.delayed)    /* are delayed.)          */
  139.         if (wnupdate(pnode->pwin) == NIL)
  140.         {
  141.         presult = NIL;
  142.         break;
  143.         }
  144.     }
  145.  
  146.     scpage(old_npage);              /* Restore current page on new  */
  147.                       /* device.              */
  148.  
  149.     scchgdev(old_dev);              /* Restore old device.          */
  150.  
  151.     scpage(old_page);              /* Restore current page on old  */
  152.                       /* device.              */
  153.  
  154.     return presult;
  155. }
  156.  
  157. /**
  158. *
  159. * Name        undisp -- Temporarily remove ("un-display") windows
  160. *              covering a rectangular region on the screen.
  161. *
  162. * Synopsis    presult = *undisp(pnode,pcorner,pdim);
  163. *
  164. *        WIN_NODE *presult Copy of pnode, or NIL if failure.
  165. *        WIN_NODE *pnode   Pointer to node of lowermost window
  166. *                  to (possibly) remove.
  167. *        LOC     *pcorner Pointer to structure containing
  168. *                  upper left corner of region.
  169. *        DIM     *pdim      Pointer to structure containing
  170. *                  dimensions of region.
  171. *
  172. * Description    This function finds all windows covering (directly or
  173. *        indirectly) a rectangular region on a display screen and
  174. *        attempts to temporarily remove them.  The windows
  175. *        removed are flagged.
  176. *
  177. *        Hidden windows are not affected.
  178. *
  179. *        Non-removable windows are not actually removed.
  180. *
  181. * Returns    presult       Pointer to newly-hidden BWINDOW
  182. *                  structure, or NIL if failure.
  183. *        b_wnerr       Possible values:
  184. *                  (No change)       Success.
  185. *                  WN_BAD_NODE       Bad pnode or internal
  186. *                           error.
  187. *                  WN_BAD_DEV       Internal error.
  188. *                  WN_NULL_PTR       Internal error.
  189. *                  WN_ILL_DIM       Internal error.
  190. *
  191. **/
  192.  
  193. static WIN_NODE *undisp(pnode,pcorner,pdim)
  194. WIN_NODE    *pnode;
  195. LOC        *pcorner;
  196. DIM        *pdim;
  197. {
  198.     WIN_NODE *presult;
  199.     BWINDOW  *pwin;
  200.  
  201.     if (wnvalnod(pnode) == NIL)       /* Validate node.           */
  202.     {
  203.     wnerror(WN_BAD_NODE);
  204.     return NIL;
  205.     }
  206.  
  207.     presult = pnode;
  208.     pwin    = pnode->pwin;
  209.  
  210.     if (pnode->above != NIL)          /* First un-display higher      */
  211.     {                      /* windows that cover          */
  212.                       /* this rectangle.          */
  213.     if (NIL == undisp(pnode->above,
  214.               pcorner,
  215.               pdim))
  216.         presult = NIL;
  217.     }
  218.  
  219.                       /* If this window covers the    */
  220.                       /* rectangle,              */
  221.     if (   (!pwin->options.hidden)
  222.     && (!pwin->internals.temp_hid)
  223.     && wnovrlap(pcorner,             pdim,
  224.             &pwin->where_prev.corner,&pwin->prev.dim))
  225.     {                      /* then un-display this window. */
  226.  
  227.     if (pnode->above != NIL)      /* First un-display covering    */
  228.     {                  /* windows.              */
  229.         if (NIL == undisp(pnode->above,
  230.                   &pwin->where_prev.corner,
  231.                   &pwin->prev.dim))
  232.         presult = NIL;
  233.     }
  234.  
  235.                       /* Replace previous screen data */
  236.     if (pwin->options.removable)
  237.         if (wnputimg(&pwin->prev,&pwin->where_prev) == NIL)
  238.         presult = NIL;
  239.  
  240.     pwin->internals.temp_hid = 1; /* Temporarily hidden.          */
  241.     pwin->internals.dirty     = 0; /* No longer out-of-date.       */
  242.     }
  243.  
  244.     return presult;
  245. }
  246.  
  247. /**
  248. *
  249. * Name        uncovr -- Mark windows uncovered which are below a given
  250. *              window and are overlapped by a given
  251. *              rectangular region but by no other windows.
  252. *
  253. * Synopsis    presult = *uncovr(pnode,pcorner,pdim);
  254. *
  255. *        WIN_NODE *presult Copy of pnode, or NIL if failure.
  256. *        WIN_NODE *pnode   Pointer to node of uppermost window
  257. *                  to (possibly) flag.
  258. *        LOC     *pcorner Pointer to structure containing
  259. *                  upper left corner of region.
  260. *        DIM     *pdim      Pointer to structure containing
  261. *                  dimensions of region.
  262. *
  263. * Description    This function marks those windows as uncovered which are
  264. *        at or below a given window and are overlapped by a given
  265. *        rectangular region but by no other windows.
  266. *
  267. * Returns    presult       Pointer to newly-hidden BWINDOW
  268. *                  structure, or NIL if failure.
  269. *        b_wnerr       Possible values:
  270. *                  (No change)       Success.
  271. *                  WN_BAD_NODE       Bad pnode or internal
  272. *                           error.
  273. *
  274. **/
  275.  
  276. static WIN_NODE *uncovr(pnode,pcorner,pdim)
  277. WIN_NODE    *pnode;
  278. LOC        *pcorner;
  279. DIM        *pdim;
  280. {
  281.     WIN_NODE *presult;
  282.     BWINDOW  *pwin;
  283.  
  284.     if (wnvalnod(pnode) == NIL)
  285.     {
  286.     wnerror(WN_BAD_NODE);
  287.     return NIL;
  288.     }
  289.  
  290.     pwin = pnode->pwin;
  291.     if (wnovrlap(pcorner,          /* If rectangle overlaps this   */
  292.          pdim,              /* window,              */
  293.          &pwin->where_shown.corner,
  294.          &pwin->img.dim))
  295.     {
  296.     if (pnode->above == NIL         /* (unless higher windows */
  297.         || !upcovr(pnode->above,        /* overlap this one)      */
  298.                &pwin->where_shown.corner,
  299.                &pwin->img.dim))
  300.         pwin->internals.frozen         =       /* mark this win-  */
  301.         pwin->internals.any_data_covered = 0;  /* dow "uncovered".*/
  302.     }
  303.  
  304.     presult = pnode;
  305.     if (pnode->below != NIL)          /* Continue with lower windows. */
  306.     if (uncovr(pnode->below,pcorner,pdim) == NIL)
  307.         presult = NIL;
  308.  
  309.     return presult;
  310. }
  311.  
  312. /**
  313. *
  314. * Name        upcovr -- Check whether higher windows overlap a
  315. *              rectangular region.
  316. *
  317. * Synopsis    result = *upcovr(pnode,pcorner,pdim);
  318. *
  319. *        WIN_NODE *presult Copy of pnode, or NIL if failure.
  320. *        WIN_NODE *pnode   Pointer to node of window.
  321. *        LOC     *pcorner Pointer to structure containing
  322. *                  upper left corner of region.
  323. *        DIM     *pdim      Pointer to structure containing
  324. *                  dimensions of region.
  325. *
  326. * Description    Given a window node and the rectangle defined by *pdim
  327. *        and *pcorner, this function tells whether this window or
  328. *        any higher window overlaps this rectangle.
  329. *
  330. * Returns    presult       Pointer to newly-hidden BWINDOW
  331. *                  structure, or NIL if failure.
  332. *        b_wnerr       Possible values:
  333. *                  (No change)       Success.
  334. *                  WN_BAD_NODE       Bad pnode or internal
  335. *                           error.
  336. *
  337. **/
  338.  
  339. static int upcovr(pnode,pcorner,pdim)
  340. WIN_NODE   *pnode;
  341. LOC       *pcorner;
  342. DIM       *pdim;
  343. {
  344.     int result;
  345.  
  346.     if (wnvalnod(pnode) == NIL)       /* Quit if invalid node.          */
  347.     {
  348.     wnerror(WN_BAD_NODE);
  349.     return 0;
  350.     }
  351.  
  352.     if (!pnode->pwin->options.hidden
  353.     && wnovrlap(pcorner,          /* Check for rectangle overlap. */
  354.             pdim,
  355.             &(pnode->pwin->where_prev.corner),
  356.             &(pnode->pwin->prev.dim)))
  357.     result = 1;              /* Overlap.              */
  358.  
  359.     else if (pnode->above != NIL)     /* No overlap, so look higher.  */
  360.     result = upcovr(pnode->above,pcorner,pdim);
  361.  
  362.     else                  /* No higher windows to check,  */
  363.     result = 0;              /* so answer is "no".           */
  364.  
  365.  
  366.     return result;
  367. }
  368.  
  369. /**
  370. *
  371. * Name        redisp -- Redisplay windows at or above a given window
  372. *              window which have been temporarily hidden.
  373. *
  374. * Synopsis    presult = *redisp(pnode,pcorner,pdim);
  375. *
  376. *        WIN_NODE *presult Copy of pnode, or NIL if failure.
  377. *        WIN_NODE *pnode   Pointer to node of lowermost window
  378. *                  to (possibly) redisplay.
  379. *
  380. * Description    This function redisplays windows at or above a given
  381. *        window window which have been temporarily hidden.
  382. *
  383. *        Hidden windows are not affected.
  384. *
  385. *        Non-removable windows are redisplayed if they are
  386. *        flagged as having been temporarily removed.
  387. *
  388. * Returns    presult       Pointer to newly-hidden BWINDOW
  389. *                  structure, or NIL if failure.
  390. *        b_wnerr       Possible values:
  391. *                  (No change)       Success.
  392. *                  WN_BAD_NODE       Bad pnode or internal
  393. *                           error.
  394. *                  WN_BAD_DEV       Internal error.
  395. *                  WN_NULL_PTR       Internal error.
  396. *                  WN_ILL_DIM       Internal error.
  397. *
  398. **/
  399.  
  400. static WIN_NODE *redisp(pnode)
  401. WIN_NODE    *pnode;
  402. {
  403.     BWINDOW *pwin;
  404.  
  405.     if (wnvalnod(pnode) == NIL)       /* Validate node.           */
  406.     {
  407.     wnerror(WN_BAD_NODE);
  408.     return NIL;
  409.     }
  410.  
  411.     pwin = pnode->pwin;
  412.  
  413.     if (   (!pwin->options.hidden)    /* Skip if hidden by user       */
  414.                       /* or if not temporarily hidden.*/
  415.     && ( pwin->internals.temp_hid))
  416.     {
  417.                       /* Read previous screen contents*/
  418.     if (pwin->options.removable)
  419.         if (wngetimg(&pwin->prev,
  420.              &pwin->where_prev) == NIL)
  421.         return NIL;
  422.  
  423.     wnputbor(&pwin->img.dim,      /* Write border.              */
  424.          &pwin->bord,
  425.          &pwin->where_shown);
  426.  
  427.     if (wnputimg(&pwin->img,              /* Write data.  */
  428.              &pwin->where_shown) == NIL)
  429.         return NIL;
  430.  
  431.     pwin->internals.dirty     =    /* Output is now up-to-date.    */
  432.     pwin->internals.temp_hid = 0; /* No longer hidden.          */
  433.  
  434.     if (pnode->below != NIL)      /* Mark lower windows as covered*/
  435.         if (wncover(pnode->below,
  436.             &pwin->where_shown.corner,
  437.             &pwin->prev.dim)       == NIL)
  438.         return NIL;
  439.     }
  440.  
  441.     if (pnode->above != NIL)          /* Continue with higher windows.*/
  442.     if (redisp(pnode->above) == NIL)
  443.         return NIL;
  444.  
  445.     return pnode;
  446. }
  447.