home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / m / mxterm.zip / mxterm / util.c < prev    next >
C/C++ Source or Header  |  1992-10-17  |  28KB  |  996 lines

  1. /*
  2.  *    $XConsortium: util.c,v 1.31 91/06/20 18:34:47 gildea Exp $
  3.  */
  4.  
  5. /*
  6.  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  7.  *
  8.  *                         All Rights Reserved
  9.  *
  10.  * Permission to use, copy, modify, and distribute this software and its
  11.  * documentation for any purpose and without fee is hereby granted,
  12.  * provided that the above copyright notice appear in all copies and that
  13.  * both that copyright notice and this permission notice appear in
  14.  * supporting documentation, and that the name of Digital Equipment
  15.  * Corporation not be used in advertising or publicity pertaining to
  16.  * distribution of the software without specific, written prior permission.
  17.  *
  18.  *
  19.  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  20.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  21.  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  22.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  23.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  24.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  25.  * SOFTWARE.
  26.  */
  27.  
  28. /* util.c */
  29.  
  30. #include "ptyx.h"
  31. #include "data.h"
  32. #include "error.h"
  33. #include "menu.h"
  34.  
  35. #include <stdio.h>
  36.  
  37. static void horizontal_copy_area();
  38. static void vertical_copy_area();
  39.  
  40. /*
  41.  * These routines are used for the jump scroll feature
  42.  */
  43. FlushScroll(screen)
  44. register TScreen *screen;
  45. {
  46.     register int i;
  47.     register int shift = -screen->topline;
  48.     register int bot = screen->max_row - shift;
  49.     register int refreshtop;
  50.     register int refreshheight;
  51.     register int scrolltop;
  52.     register int scrollheight;
  53.  
  54.     if(screen->cursor_state)
  55.         HideCursor();
  56.     if(screen->scroll_amt > 0) {
  57.         refreshheight = screen->refresh_amt;
  58.         scrollheight = screen->bot_marg - screen->top_marg -
  59.          refreshheight + 1;
  60.         if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
  61.          (i = screen->max_row - screen->scroll_amt + 1))
  62.             refreshtop = i;
  63.         if(screen->scrollWidget && !screen->alternate
  64.          && screen->top_marg == 0) {
  65.             scrolltop = 0;
  66.             if((scrollheight += shift) > i)
  67.                 scrollheight = i;
  68.             if((i = screen->bot_marg - bot) > 0 &&
  69.              (refreshheight -= i) < screen->scroll_amt)
  70.                 refreshheight = screen->scroll_amt;
  71.             if((i = screen->savedlines) < screen->savelines) {
  72.                 if((i += screen->scroll_amt) >
  73.                   screen->savelines)
  74.                     i = screen->savelines;
  75.                 screen->savedlines = i;
  76.                 ScrollBarDrawThumb(screen->scrollWidget);
  77.             }
  78.         } else {
  79.             scrolltop = screen->top_marg + shift;
  80.             if((i = bot - (screen->bot_marg - screen->refresh_amt +
  81.              screen->scroll_amt)) > 0) {
  82.                 if(bot < screen->bot_marg)
  83.                     refreshheight = screen->scroll_amt + i;
  84.             } else {
  85.                 scrollheight += i;
  86.                 refreshheight = screen->scroll_amt;
  87.                 if((i = screen->top_marg + screen->scroll_amt -
  88.                  1 - bot) > 0) {
  89.                     refreshtop += i;
  90.                     refreshheight -= i;
  91.                 }
  92.             }
  93.         }
  94.     } else {
  95.         refreshheight = -screen->refresh_amt;
  96.         scrollheight = screen->bot_marg - screen->top_marg -
  97.          refreshheight + 1;
  98.         refreshtop = screen->top_marg + shift;
  99.         scrolltop = refreshtop + refreshheight;
  100.         if((i = screen->bot_marg - bot) > 0)
  101.             scrollheight -= i;
  102.         if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
  103.             refreshheight -= i;
  104.     }
  105.     scrolling_copy_area(screen, scrolltop+screen->scroll_amt,
  106.                 scrollheight, screen->scroll_amt);
  107.     ScrollSelection(screen, -(screen->scroll_amt));
  108.     screen->scroll_amt = 0;
  109.     screen->refresh_amt = 0;
  110.     if(refreshheight > 0) {
  111.         XClearArea (
  112.             screen->display,
  113.             TextWindow(screen),
  114.             (int) screen->border + screen->scrollbar,
  115.             (int) refreshtop * FontHeight(screen) + screen->border,
  116.             (unsigned) Width(screen),
  117.             (unsigned) refreshheight * FontHeight(screen),
  118.             FALSE);
  119.         ScrnRefresh(screen, refreshtop, 0, refreshheight,
  120.          screen->max_col + 1, False);
  121.     }
  122. }
  123.  
  124. AddToRefresh(screen)
  125. register TScreen *screen;
  126. {
  127.     register int amount = screen->refresh_amt;
  128.     register int row = screen->cur_row;
  129.  
  130.     if(amount == 0)
  131.         return(0);
  132.     if(amount > 0) {
  133.         register int bottom;
  134.  
  135.         if(row == (bottom = screen->bot_marg) - amount) {
  136.             screen->refresh_amt++;
  137.             return(1);
  138.         }
  139.         return(row >= bottom - amount + 1 && row <= bottom);
  140.     } else {
  141.         register int top;
  142.  
  143.         amount = -amount;
  144.         if(row == (top = screen->top_marg) + amount) {
  145.             screen->refresh_amt--;
  146.             return(1);
  147.         }
  148.         return(row <= top + amount - 1 && row >= top);
  149.     }
  150. }
  151.  
  152. /* 
  153.  * scrolls the screen by amount lines, erases bottom, doesn't alter 
  154.  * cursor position (i.e. cursor moves down amount relative to text).
  155.  * All done within the scrolling region, of course. 
  156.  * requires: amount > 0
  157.  */
  158. Scroll(screen, amount)
  159. register TScreen *screen;
  160. register int amount;
  161. {
  162.     register int i = screen->bot_marg - screen->top_marg + 1;
  163.     register int shift;
  164.     register int bot;
  165.     register int refreshtop = 0;
  166.     register int refreshheight;
  167.     register int scrolltop;
  168.     register int scrollheight;
  169.  
  170.     if(screen->cursor_state)
  171.         HideCursor();
  172.     if (amount > i)
  173.         amount = i;
  174.     if(screen->jumpscroll) {
  175.     if(screen->scroll_amt > 0) {
  176.         if(screen->refresh_amt + amount > i)
  177.             FlushScroll(screen);
  178.         screen->scroll_amt += amount;
  179.         screen->refresh_amt += amount;
  180.     } else {
  181.         if(screen->scroll_amt < 0)
  182.             FlushScroll(screen);
  183.         screen->scroll_amt = amount;
  184.         screen->refresh_amt = amount;
  185.     }
  186.     refreshheight = 0;
  187.     } else {
  188.     ScrollSelection(screen, -(amount));
  189.     if (amount == i) {
  190.         ClearScreen(screen);
  191.         return;
  192.     }
  193.     shift = -screen->topline;
  194.     bot = screen->max_row - shift;
  195.     scrollheight = i - amount;
  196.     refreshheight = amount;
  197.     if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
  198.      (i = screen->max_row - refreshheight + 1))
  199.         refreshtop = i;
  200.     if(screen->scrollWidget && !screen->alternate
  201.      && screen->top_marg == 0) {
  202.         scrolltop = 0;
  203.         if((scrollheight += shift) > i)
  204.             scrollheight = i;
  205.         if((i = screen->savedlines) < screen->savelines) {
  206.             if((i += amount) > screen->savelines)
  207.                 i = screen->savelines;
  208.             screen->savedlines = i;
  209.             ScrollBarDrawThumb(screen->scrollWidget);
  210.         }
  211.     } else {
  212.         scrolltop = screen->top_marg + shift;
  213.         if((i = screen->bot_marg - bot) > 0) {
  214.             scrollheight -= i;
  215.             if((i = screen->top_marg + amount - 1 - bot) >= 0) {
  216.                 refreshtop += i;
  217.                 refreshheight -= i;
  218.             }
  219.         }
  220.     }
  221.  
  222.     if (screen->multiscroll && amount == 1 &&
  223.         screen->topline == 0 && screen->top_marg == 0 &&
  224.         screen->bot_marg == screen->max_row) {
  225.         if (screen->incopy < 0 && screen->scrolls == 0)
  226.         CopyWait(screen);
  227.         screen->scrolls++;
  228.     }
  229.     scrolling_copy_area(screen, scrolltop+amount, scrollheight, amount);
  230.     if(refreshheight > 0) {
  231.         XClearArea (
  232.            screen->display,
  233.            TextWindow(screen),
  234.            (int) screen->border + screen->scrollbar,
  235.            (int) refreshtop * FontHeight(screen) + screen->border,
  236.            (unsigned) Width(screen),
  237.            (unsigned) refreshheight * FontHeight(screen),
  238.            FALSE);
  239.         if(refreshheight > shift)
  240.             refreshheight = shift;
  241.     }
  242.     }
  243.     if(screen->scrollWidget && !screen->alternate && screen->top_marg == 0)
  244.         ScrnDeleteLine(screen->allbuf, screen->bot_marg +
  245.          screen->savelines, 0, amount, screen->max_col + 1);
  246.     else
  247.         ScrnDeleteLine(screen->buf, screen->bot_marg, screen->top_marg,
  248.          amount, screen->max_col + 1);
  249.     if(refreshheight > 0)
  250.         ScrnRefresh(screen, refreshtop, 0, refreshheight,
  251.          screen->max_col + 1, False);
  252. }
  253.  
  254.  
  255. /*
  256.  * Reverse scrolls the screen by amount lines, erases top, doesn't alter
  257.  * cursor position (i.e. cursor moves up amount relative to text).
  258.  * All done within the scrolling region, of course.
  259.  * Requires: amount > 0
  260.  */
  261. RevScroll(screen, amount)
  262. register TScreen *screen;
  263. register int amount;
  264. {
  265.     register int i = screen->bot_marg - screen->top_marg + 1;
  266.     register int shift;
  267.     register int bot;
  268.     register int refreshtop;
  269.     register int refreshheight;
  270.     register int scrolltop;
  271.     register int scrollheight;
  272.  
  273.     if(screen->cursor_state)
  274.         HideCursor();
  275.     if (amount > i)
  276.         amount = i;
  277.     if(screen->jumpscroll) {
  278.     if(screen->scroll_amt < 0) {
  279.         if(-screen->refresh_amt + amount > i)
  280.             FlushScroll(screen);
  281.         screen->scroll_amt -= amount;
  282.         screen->refresh_amt -= amount;
  283.     } else {
  284.         if(screen->scroll_amt > 0)
  285.             FlushScroll(screen);
  286.         screen->scroll_amt = -amount;
  287.         screen->refresh_amt = -amount;
  288.     }
  289.     } else {
  290.     shift = -screen->topline;
  291.     bot = screen->max_row - shift;
  292.     refreshheight = amount;
  293.     scrollheight = screen->bot_marg - screen->top_marg -
  294.      refreshheight + 1;
  295.     refreshtop = screen->top_marg + shift;
  296.     scrolltop = refreshtop + refreshheight;
  297.     if((i = screen->bot_marg - bot) > 0)
  298.         scrollheight -= i;
  299.     if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
  300.         refreshheight -= i;
  301.  
  302.     if (screen->multiscroll && amount == 1 &&
  303.         screen->topline == 0 && screen->top_marg == 0 &&
  304.         screen->bot_marg == screen->max_row) {
  305.         if (screen->incopy < 0 && screen->scrolls == 0)
  306.         CopyWait(screen);
  307.         screen->scrolls++;
  308.     }
  309.     scrolling_copy_area(screen, scrolltop-amount, scrollheight, -amount);
  310.     if(refreshheight > 0)
  311.         XClearArea (
  312.             screen->display,
  313.             TextWindow(screen),
  314.             (int) screen->border + screen->scrollbar,
  315.             (int) refreshtop * FontHeight(screen) + screen->border,
  316.             (unsigned) Width(screen),
  317.             (unsigned) refreshheight * FontHeight(screen),
  318.             FALSE);
  319.     }
  320.     ScrnInsertLine (screen->buf, screen->bot_marg, screen->top_marg,
  321.             amount, screen->max_col + 1);
  322. }
  323.  
  324. /*
  325.  * If cursor not in scrolling region, returns.  Else,
  326.  * inserts n blank lines at the cursor's position.  Lines above the
  327.  * bottom margin are lost.
  328.  */
  329. InsertLine (screen, n)
  330. register TScreen *screen;
  331. register int n;
  332. {
  333.     register int i;
  334.     register int shift;
  335.     register int bot;
  336.     register int refreshtop;
  337.     register int refreshheight;
  338.     register int scrolltop;
  339.     register int scrollheight;
  340.  
  341.     if (screen->cur_row < screen->top_marg ||
  342.      screen->cur_row > screen->bot_marg)
  343.         return;
  344.     if(screen->cursor_state)
  345.         HideCursor();
  346.     screen->do_wrap = 0;
  347.     if (n > (i = screen->bot_marg - screen->cur_row + 1))
  348.         n = i;
  349.     if(screen->jumpscroll) {
  350.     if(screen->scroll_amt <= 0 &&
  351.      screen->cur_row <= -screen->refresh_amt) {
  352.         if(-screen->refresh_amt + n > screen->max_row + 1)
  353.             FlushScroll(screen);
  354.         screen->scroll_amt -= n;
  355.         screen->refresh_amt -= n;
  356.     } else if(screen->scroll_amt)
  357.         FlushScroll(screen);
  358.     }
  359.     if(!screen->scroll_amt) {
  360.     shift = -screen->topline;
  361.     bot = screen->max_row - shift;
  362.     refreshheight = n;
  363.     scrollheight = screen->bot_marg - screen->cur_row - refreshheight + 1;
  364.     refreshtop = screen->cur_row + shift;
  365.     scrolltop = refreshtop + refreshheight;
  366.     if((i = screen->bot_marg - bot) > 0)
  367.         scrollheight -= i;
  368.     if((i = screen->cur_row + refreshheight - 1 - bot) > 0)
  369.         refreshheight -= i;
  370.     vertical_copy_area(screen, scrolltop-n, scrollheight, -n);
  371.     if(refreshheight > 0)
  372.         XClearArea (
  373.             screen->display,
  374.             TextWindow(screen),
  375.             (int) screen->border + screen->scrollbar,
  376.             (int) refreshtop * FontHeight(screen) + screen->border,
  377.             (unsigned) Width(screen),
  378.             (unsigned) refreshheight * FontHeight(screen),
  379.             FALSE);
  380.     }
  381.     /* adjust screen->buf */
  382.     ScrnInsertLine(screen->buf, screen->bot_marg, screen->cur_row, n,
  383.             screen->max_col + 1);
  384. }
  385.  
  386. /*
  387.  * If cursor not in scrolling region, returns.  Else, deletes n lines
  388.  * at the cursor's position, lines added at bottom margin are blank.
  389.  */
  390. DeleteLine(screen, n)
  391. register TScreen *screen;
  392. register int n;
  393. {
  394.     register int i;
  395.     register int shift;
  396.     register int bot;
  397.     register int refreshtop;
  398.     register int refreshheight;
  399.     register int scrolltop;
  400.     register int scrollheight;
  401.  
  402.     if (screen->cur_row < screen->top_marg ||
  403.      screen->cur_row > screen->bot_marg)
  404.         return;
  405.     if(screen->cursor_state)
  406.         HideCursor();
  407.     screen->do_wrap = 0;
  408.     if (n > (i = screen->bot_marg - screen->cur_row + 1))
  409.         n = i;
  410.     if(screen->jumpscroll) {
  411.     if(screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
  412.         if(screen->refresh_amt + n > screen->max_row + 1)
  413.             FlushScroll(screen);
  414.         screen->scroll_amt += n;
  415.         screen->refresh_amt += n;
  416.     } else if(screen->scroll_amt)
  417.         FlushScroll(screen);
  418.     }
  419.     if(!screen->scroll_amt) {
  420.  
  421.     shift = -screen->topline;
  422.     bot = screen->max_row - shift;
  423.     scrollheight = i - n;
  424.     refreshheight = n;
  425.     if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
  426.      (i = screen->max_row - refreshheight + 1))
  427.         refreshtop = i;
  428.     if(screen->scrollWidget && !screen->alternate && screen->cur_row == 0) {
  429.         scrolltop = 0;
  430.         if((scrollheight += shift) > i)
  431.             scrollheight = i;
  432.         if((i = screen->savedlines) < screen->savelines) {
  433.             if((i += n) > screen->savelines)
  434.                 i = screen->savelines;
  435.             screen->savedlines = i;
  436.             ScrollBarDrawThumb(screen->scrollWidget);
  437.         }
  438.     } else {
  439.         scrolltop = screen->cur_row + shift;
  440.         if((i = screen->bot_marg - bot) > 0) {
  441.             scrollheight -= i;
  442.             if((i = screen->cur_row + n - 1 - bot) >= 0) {
  443.                 refreshheight -= i;
  444.             }
  445.         }
  446.     }
  447.     vertical_copy_area(screen, scrolltop+n, scrollheight, n);
  448.     if(refreshheight > 0)
  449.         XClearArea (
  450.             screen->display,
  451.             TextWindow(screen),
  452.             (int) screen->border + screen->scrollbar,
  453.             (int) refreshtop * FontHeight(screen) + screen->border,
  454.             (unsigned) Width(screen),
  455.             (unsigned) refreshheight * FontHeight(screen),
  456.             FALSE);
  457.     }
  458.     /* adjust screen->buf */
  459.     if(screen->scrollWidget && !screen->alternate && screen->cur_row == 0)
  460.         ScrnDeleteLine(screen->allbuf, screen->bot_marg +
  461.          screen->savelines, 0, n, screen->max_col + 1);
  462.     else
  463.         ScrnDeleteLine(screen->buf, screen->bot_marg, screen->cur_row,
  464.          n, screen->max_col + 1);
  465. }
  466.  
  467. /*
  468.  * Insert n blanks at the cursor's position, no wraparound
  469.  */
  470. InsertChar (screen, n)
  471.     register TScreen *screen;
  472.     register int n;
  473. {
  474.         register int cx, cy;
  475.  
  476.     if(screen->cursor_state)
  477.         HideCursor();
  478.     screen->do_wrap = 0;
  479.     if(screen->cur_row - screen->topline <= screen->max_row) {
  480.         if(!AddToRefresh(screen)) {
  481.         if(screen->scroll_amt)
  482.             FlushScroll(screen);
  483.  
  484.         /*
  485.          * prevent InsertChar from shifting the end of a line over
  486.          * if it is being appended to
  487.          */
  488.         if (non_blank_line (screen->buf, screen->cur_row, 
  489.                     screen->cur_col, screen->max_col + 1))
  490.             horizontal_copy_area(screen, screen->cur_col,
  491.                      screen->max_col+1 - (screen->cur_col+n),
  492.                      n);
  493.     
  494.         cx = CursorX (screen, screen->cur_col);
  495.         cy = CursorY (screen, screen->cur_row);
  496.  
  497.         XFillRectangle(
  498.             screen->display,
  499.             TextWindow(screen), 
  500.             screen->reverseGC,
  501.             cx, cy,
  502.             (unsigned) n * FontWidth(screen), (unsigned) FontHeight(screen));
  503.         }
  504.     }
  505.     /* adjust screen->buf */
  506.     ScrnInsertChar(screen->buf, screen->cur_row, screen->cur_col, n,
  507.             screen->max_col + 1);
  508. }
  509.  
  510. /*
  511.  * Deletes n chars at the cursor's position, no wraparound.
  512.  */
  513. DeleteChar (screen, n)
  514.     register TScreen *screen;
  515.     register int    n;
  516. {
  517.     register int width;
  518.  
  519.     if(screen->cursor_state)
  520.         HideCursor();
  521.     screen->do_wrap = 0;
  522.     if (n > (width = screen->max_col + 1 - screen->cur_col))
  523.           n = width;
  524.         
  525.     if(screen->cur_row - screen->topline <= screen->max_row) {
  526.         if(!AddToRefresh(screen)) {
  527.         if(screen->scroll_amt)
  528.             FlushScroll(screen);
  529.     
  530.         horizontal_copy_area(screen, screen->cur_col+n,
  531.                      screen->max_col+1 - (screen->cur_col+n),
  532.                      -n);
  533.     
  534.         XFillRectangle
  535.             (screen->display, TextWindow(screen),
  536.              screen->reverseGC,
  537.              screen->border + screen->scrollbar
  538.                + Width(screen) - n*FontWidth(screen),
  539.              CursorY (screen, screen->cur_row), n * FontWidth(screen),
  540.              FontHeight(screen));
  541.         }
  542.     }
  543.     /* adjust screen->buf */
  544.     ScrnDeleteChar (screen->buf, screen->cur_row, screen->cur_col, n,
  545.             screen->max_col + 1);
  546.  
  547. }
  548.  
  549. /*
  550.  * Clear from cursor position to beginning of display, inclusive.
  551.  */
  552. ClearAbove (screen)
  553. register TScreen *screen;
  554. {
  555.     register top, height;
  556.  
  557.     if(screen->cursor_state)
  558.         HideCursor();
  559.     if((top = -screen->topline) <= screen->max_row) {
  560.         if(screen->scroll_amt)
  561.             FlushScroll(screen);
  562.         if((height = screen->cur_row + top) > screen->max_row)
  563.             height = screen->max_row;
  564.         if((height -= top) > 0)
  565.             XClearArea(screen->display, TextWindow(screen),
  566.              screen->border + screen->scrollbar, top *
  567.              FontHeight(screen) + screen->border,
  568.              Width(screen), height * FontHeight(screen), FALSE);
  569.  
  570.         if(screen->cur_row - screen->topline <= screen->max_row)
  571.             ClearLeft(screen);
  572.     }
  573.     ClearBufRows(screen, 0, screen->cur_row - 1);
  574. }
  575.  
  576. /*
  577.  * Clear from cursor position to end of display, inclusive.
  578.  */
  579. ClearBelow (screen)
  580. register TScreen *screen;
  581. {
  582.     register top;
  583.  
  584.     ClearRight(screen);
  585.     if((top = screen->cur_row - screen->topline) <= screen->max_row) {
  586.         if(screen->scroll_amt)
  587.             FlushScroll(screen);
  588.         if(++top <= screen->max_row)
  589.             XClearArea(screen->display, TextWindow(screen),
  590.              screen->border + screen->scrollbar, top *
  591.              FontHeight(screen) + screen->border,
  592.              Width(screen), (screen->max_row - top + 1) *
  593.              FontHeight(screen), FALSE);
  594.     }
  595.     ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
  596. }
  597.  
  598. /* 
  599.  * Clear last part of cursor's line, inclusive.
  600.  */
  601. ClearRight (screen)
  602. register TScreen *screen;
  603. {
  604.     if(screen->cursor_state)
  605.         HideCursor();
  606.     screen->do_wrap = 0;
  607.     if(screen->cur_row - screen->topline <= screen->max_row) {
  608.         if(!AddToRefresh(screen)) {
  609.     if(screen->scroll_amt)
  610.         FlushScroll(screen);
  611.         XFillRectangle(screen->display, TextWindow(screen),
  612.           screen->reverseGC,
  613.          CursorX(screen, screen->cur_col),
  614.          CursorY(screen, screen->cur_row),
  615.          Width(screen) - screen->cur_col * FontWidth(screen),
  616.          FontHeight(screen));
  617.         }
  618.     }
  619.     bzero(screen->buf [2 * screen->cur_row] + screen->cur_col,
  620.            (screen->max_col - screen->cur_col + 1));
  621.     bzero(screen->buf [2 * screen->cur_row + 1] + screen->cur_col,
  622.            (screen->max_col - screen->cur_col + 1));
  623.     /* with the right part cleared, we can't be wrapping */
  624.     screen->buf [2 * screen->cur_row + 1] [0] &= ~LINEWRAPPED;
  625. }
  626.  
  627. /*
  628.  * Clear first part of cursor's line, inclusive.
  629.  */
  630. ClearLeft (screen)
  631.     register TScreen *screen;
  632. {
  633.         int i;
  634.     Char *cp;
  635.  
  636.     if(screen->cursor_state)
  637.         HideCursor();
  638.     screen->do_wrap = 0;
  639.     if(screen->cur_row - screen->topline <= screen->max_row) {
  640.         if(!AddToRefresh(screen)) {
  641.         if(screen->scroll_amt)
  642.             FlushScroll(screen);
  643.         XFillRectangle (screen->display, TextWindow(screen),
  644.              screen->reverseGC,
  645.              screen->border + screen->scrollbar,
  646.               CursorY (screen, screen->cur_row),
  647.              (screen->cur_col + 1) * FontWidth(screen),
  648.              FontHeight(screen));
  649.         }
  650.     }
  651.     
  652.     for ( i=0, cp=screen->buf[2 * screen->cur_row];
  653.           i < screen->cur_col + 1;
  654.           i++, cp++)
  655.         *cp = ' ';
  656.     for ( i=0, cp=screen->buf[2 * screen->cur_row + 1];
  657.           i < screen->cur_col + 1;
  658.           i++, cp++)
  659.         *cp = CHARDRAWN;
  660. }
  661.  
  662. /* 
  663.  * Erase the cursor's line.
  664.  */
  665. ClearLine(screen)
  666. register TScreen *screen;
  667. {
  668.     if(screen->cursor_state)
  669.         HideCursor();
  670.     screen->do_wrap = 0;
  671.     if(screen->cur_row - screen->topline <= screen->max_row) {
  672.         if(!AddToRefresh(screen)) {
  673.         if(screen->scroll_amt)
  674.             FlushScroll(screen);
  675.         XFillRectangle (screen->display, TextWindow(screen), 
  676.              screen->reverseGC,
  677.              screen->border + screen->scrollbar,
  678.               CursorY (screen, screen->cur_row),
  679.              Width(screen), FontHeight(screen));
  680.         }
  681.     }
  682.     bzero (screen->buf [2 * screen->cur_row], (screen->max_col + 1));
  683.     bzero (screen->buf [2 * screen->cur_row + 1], (screen->max_col + 1));
  684. }
  685.  
  686. ClearScreen(screen)
  687. register TScreen *screen;
  688. {
  689.     register int top;
  690.  
  691.     if(screen->cursor_state)
  692.         HideCursor();
  693.     screen->do_wrap = 0;
  694.     if((top = -screen->topline) <= screen->max_row) {
  695.         if(screen->scroll_amt)
  696.             FlushScroll(screen);
  697.         if(top == 0)
  698.             XClearWindow(screen->display, TextWindow(screen));
  699.         else
  700.             XClearArea(screen->display, TextWindow(screen),
  701.              screen->border + screen->scrollbar, 
  702.              top * FontHeight(screen) + screen->border,    
  703.               Width(screen), (screen->max_row - top + 1) *
  704.              FontHeight(screen), FALSE);
  705.     }
  706.     ClearBufRows (screen, 0, screen->max_row);
  707. }
  708.  
  709. CopyWait(screen)
  710. register TScreen *screen;
  711. {
  712.     XEvent reply;
  713.     XEvent *rep = &reply;
  714.  
  715.     while (1) {
  716.         XWindowEvent (screen->display, VWindow(screen), 
  717.           ExposureMask, &reply);
  718.         switch (reply.type) {
  719.         case Expose:
  720.             HandleExposure (screen, &reply);
  721.             break;
  722.         case NoExpose:
  723.         case GraphicsExpose:
  724.             if (screen->incopy <= 0) {
  725.                 screen->incopy = 1;
  726.                 if (screen->scrolls > 0)
  727.                     screen->scrolls--;
  728.             }
  729.             if (reply.type == GraphicsExpose)
  730.                 HandleExposure (screen, &reply);
  731.  
  732.             if ((reply.type == NoExpose) ||
  733.                 ((XExposeEvent *)rep)->count == 0) {
  734.                 if (screen->incopy <= 0 && screen->scrolls > 0)
  735.                 screen->scrolls--;
  736.                 if (screen->scrolls == 0) {
  737.                 screen->incopy = 0;
  738.                 return;
  739.                 }
  740.                 screen->incopy = -1;
  741.             }
  742.             break;
  743.         }
  744.     }
  745. }
  746.  
  747. /*
  748.  * used by vertical_copy_area and and horizontal_copy_area
  749.  */
  750. static void
  751. copy_area(screen, src_x, src_y, width, height, dest_x, dest_y)
  752.     TScreen *screen;
  753.     int src_x, src_y;
  754.     unsigned int width, height;
  755.     int dest_x, dest_y;
  756. {
  757.     /* wait for previous CopyArea to complete unless
  758.        multiscroll is enabled and active */
  759.     if (screen->incopy  &&  screen->scrolls == 0)
  760.     CopyWait(screen);
  761.     screen->incopy = -1;
  762.  
  763.     /* save for translating Expose events */
  764.     screen->copy_src_x = src_x;
  765.     screen->copy_src_y = src_y;
  766.     screen->copy_width = width;
  767.     screen->copy_height = height;
  768.     screen->copy_dest_x = dest_x;
  769.     screen->copy_dest_y = dest_y;
  770.  
  771.     XCopyArea(screen->display, 
  772.           TextWindow(screen), TextWindow(screen),
  773.           screen->normalGC,
  774.           src_x, src_y, width, height, dest_x, dest_y);
  775. }
  776.  
  777. /*
  778.  * use when inserting or deleting characters on the current line
  779.  */
  780. static void
  781. horizontal_copy_area(screen, firstchar, nchars, amount)
  782.     TScreen *screen;
  783.     int firstchar;        /* char pos on screen to start copying at */
  784.     int nchars;
  785.     int amount;            /* number of characters to move right */
  786. {
  787.     int src_x = CursorX(screen, firstchar);
  788.     int src_y = CursorY(screen, screen->cur_row);
  789.  
  790.     copy_area(screen, src_x, src_y,
  791.           (unsigned)nchars*FontWidth(screen), FontHeight(screen),
  792.           src_x + amount*FontWidth(screen), src_y);
  793. }
  794.  
  795. /*
  796.  * use when inserting or deleting lines from the screen
  797.  */
  798. static void
  799. vertical_copy_area(screen, firstline, nlines, amount)
  800.     TScreen *screen;
  801.     int firstline;        /* line on screen to start copying at */
  802.     int nlines;
  803.     int amount;            /* number of lines to move up (neg=down) */
  804. {
  805.     if(nlines > 0) {
  806.     int src_x = screen->border + screen->scrollbar;
  807.     int src_y = firstline * FontHeight(screen) + screen->border;
  808.  
  809.     copy_area(screen, src_x, src_y,
  810.           (unsigned)Width(screen), nlines*FontHeight(screen),
  811.           src_x, src_y - amount*FontHeight(screen));
  812.     }
  813. }
  814.  
  815. /*
  816.  * use when scrolling the entire screen
  817.  */
  818. scrolling_copy_area(screen, firstline, nlines, amount)
  819.     TScreen *screen;
  820.     int firstline;        /* line on screen to start copying at */
  821.     int nlines;
  822.     int amount;            /* number of lines to move up (neg=down) */
  823. {
  824.  
  825.     if(nlines > 0) {
  826.     vertical_copy_area(screen, firstline, nlines, amount);
  827.     }
  828. }
  829.  
  830. /*
  831.  * Handler for Expose events on the VT widget.
  832.  * Returns 1 iff the area where the cursor was got refreshed.
  833.  */
  834. HandleExposure (screen, event)
  835.     register TScreen *screen;
  836.     register XEvent *event;
  837. {
  838.     register XExposeEvent *reply = (XExposeEvent *)event;
  839.  
  840.     /* if not doing CopyArea or if this is a GraphicsExpose, don't translate */
  841.     if(!screen->incopy  ||  event->type != Expose)
  842.     return handle_translated_exposure (screen, reply->x, reply->y,
  843.                        reply->width, reply->height);
  844.     else {
  845.     /* compute intersection of area being copied with
  846.        area being exposed. */
  847.     int both_x1 = Max(screen->copy_src_x, reply->x);
  848.     int both_y1 = Max(screen->copy_src_y, reply->y);
  849.     int both_x2 = Min(screen->copy_src_x+screen->copy_width,
  850.               reply->x+reply->width);
  851.     int both_y2 = Min(screen->copy_src_y+screen->copy_height,
  852.               reply->y+reply->height);
  853.     int value = 0;
  854.  
  855.     /* was anything copied affected? */
  856.     if(both_x2 > both_x1  && both_y2 > both_y1) {
  857.         /* do the copied area */
  858.         value = handle_translated_exposure
  859.         (screen, reply->x + screen->copy_dest_x - screen->copy_src_x,
  860.          reply->y + screen->copy_dest_y - screen->copy_src_y,
  861.          reply->width, reply->height);
  862.     }
  863.     /* was anything not copied affected? */
  864.     if(reply->x < both_x1 || reply->y < both_y1
  865.        || reply->x+reply->width > both_x2
  866.        || reply->y+reply->height > both_y2)
  867.         value = handle_translated_exposure (screen, reply->x, reply->y,
  868.                         reply->width, reply->height);
  869.  
  870.     return value;
  871.     }
  872. }
  873.  
  874. /*
  875.  * Called by the ExposeHandler to do the actual repaint after the coordinates
  876.  * have been translated to allow for any CopyArea in progress.
  877.  * The rectangle passed in is pixel coordinates.
  878.  */
  879. handle_translated_exposure (screen, rect_x, rect_y, rect_width, rect_height)
  880.     register TScreen *screen;
  881.     register int rect_x, rect_y;
  882.     register unsigned int rect_width, rect_height;
  883. {
  884.     register int toprow, leftcol, nrows, ncols;
  885.     extern Bool waiting_for_initial_map;
  886.  
  887.     toprow = (rect_y - screen->border) / FontHeight(screen);
  888.     if(toprow < 0)
  889.         toprow = 0;
  890.     leftcol = (rect_x - screen->border - screen->scrollbar)
  891.         / FontWidth(screen);
  892.     if(leftcol < 0)
  893.         leftcol = 0;
  894.     nrows = (rect_y + rect_height - 1 - screen->border) / 
  895.         FontHeight(screen) - toprow + 1;
  896.     ncols =
  897.      (rect_x + rect_width - 1 - screen->border - screen->scrollbar) /
  898.             FontWidth(screen) - leftcol + 1;
  899.     toprow -= screen->scrolls;
  900.     if (toprow < 0) {
  901.         nrows += toprow;
  902.         toprow = 0;
  903.     }
  904.     if (toprow + nrows - 1 > screen->max_row)
  905.         nrows = screen->max_row - toprow + 1;
  906.     if (leftcol + ncols - 1 > screen->max_col)
  907.         ncols = screen->max_col - leftcol + 1;
  908.  
  909.     if (nrows > 0 && ncols > 0) {
  910.         ScrnRefresh (screen, toprow, leftcol, nrows, ncols, False);
  911.         if (waiting_for_initial_map) {
  912.             first_map_occurred ();
  913.         }
  914.         if (screen->cur_row >= toprow &&
  915.             screen->cur_row < toprow + nrows &&
  916.             screen->cur_col >= leftcol &&
  917.             screen->cur_col < leftcol + ncols)
  918.             return (1);
  919.  
  920.     }
  921.     return (0);
  922. }
  923.  
  924. ReverseVideo (termw)
  925.     XtermWidget termw;
  926. {
  927.     register TScreen *screen = &termw->screen;
  928.     GC tmpGC;
  929.     Window tek = TWindow(screen);
  930.     unsigned long tmp;
  931.  
  932.     tmp = termw->core.background_pixel;
  933.     if(screen->cursorcolor == screen->foreground)
  934.         screen->cursorcolor = tmp;
  935.     termw->core.background_pixel = screen->foreground;
  936.     screen->foreground = tmp;
  937.  
  938.     tmp = screen->mousecolorback;
  939.     screen->mousecolorback = screen->mousecolor;
  940.     screen->mousecolor = tmp;
  941.  
  942.     tmpGC = screen->normalGC;
  943.     screen->normalGC = screen->reverseGC;
  944.     screen->reverseGC = tmpGC;
  945.  
  946.     tmpGC = screen->normalboldGC;
  947.     screen->normalboldGC = screen->reverseboldGC;
  948.     screen->reverseboldGC = tmpGC;
  949.  
  950.     recolor_cursor (screen->pointer_cursor, 
  951.             screen->mousecolor, screen->mousecolorback);
  952.     recolor_cursor (screen->arrow,
  953.             screen->mousecolor, screen->mousecolorback);
  954.  
  955.     termw->misc.re_verse = !termw->misc.re_verse;
  956.  
  957.     XDefineCursor(screen->display, TextWindow(screen), screen->pointer_cursor);
  958.     if(tek)
  959.         XDefineCursor(screen->display, tek, screen->arrow);
  960.  
  961.     
  962.     if(screen->scrollWidget)
  963.         ScrollBarReverseVideo(screen->scrollWidget);
  964.  
  965.     XSetWindowBackground(screen->display, TextWindow(screen), termw->core.background_pixel);
  966.     if(tek) {
  967.         TekReverseVideo(screen);
  968.     }
  969.     XClearWindow(screen->display, TextWindow(screen));
  970.     ScrnRefresh (screen, 0, 0, screen->max_row + 1,
  971.      screen->max_col + 1, False);
  972.     if(screen->Tshow) {
  973.         XClearWindow(screen->display, tek);
  974.         TekExpose((Widget)NULL, (XEvent *)NULL, (Region)NULL);
  975.     }
  976.     update_reversevideo();
  977. }
  978.  
  979.  
  980. recolor_cursor (cursor, fg, bg)
  981.     Cursor cursor;            /* X cursor ID to set */
  982.     unsigned long fg, bg;        /* pixel indexes to look up */
  983. {
  984.     register TScreen *screen = &term->screen;
  985.     register Display *dpy = screen->display;
  986.     XColor colordefs[2];        /* 0 is foreground, 1 is background */
  987.  
  988.     colordefs[0].pixel = fg;
  989.     colordefs[1].pixel = bg;
  990.     XQueryColors (dpy, DefaultColormap (dpy, DefaultScreen (dpy)),
  991.           colordefs, 2);
  992.     XRecolorCursor (dpy, cursor, colordefs, colordefs+1);
  993.     return;
  994. }
  995.  
  996.