home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume9 / xterm / part03 / cursor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-20  |  6.2 KB  |  289 lines

  1. /*
  2.  *    $Source: /u1/X/xterm/RCS/cursor.c,v $
  3.  *    $Header: cursor.c,v 10.100 86/12/01 14:43:54 jg Rel $
  4.  */
  5.  
  6. #ifndef lint
  7. static char *rcsid_cursor_c = "$Header: cursor.c,v 10.100 86/12/01 14:43:54 jg Rel $";
  8. #endif    lint
  9.  
  10. #include <X/mit-copyright.h>
  11.  
  12. /* Copyright 1984, 1985   Massachusetts Institute of Technology        */
  13.  
  14. /* cursor.c */
  15.  
  16.  
  17. #ifndef lint
  18. static char sccs_id[] = "@(#)cursor.c\tX10/6.6B\t12/26/86";
  19. #endif    lint
  20.  
  21. #include <X/Xlib.h>
  22. #include <stdio.h>
  23. #include <sys/ioctl.h>
  24. #include "scrollbar.h"
  25. #include "ptyx.h"
  26.  
  27. /*
  28.  * Moves the cursor to the specified position, checking for bounds.
  29.  * (this includes scrolling regions)
  30.  * The origin is considered to be 0, 0 for this procedure.
  31.  * In the status line, the cursor moves only horizontally.
  32.  */
  33. CursorSet(screen, row, col, flags)
  34. register Screen    *screen;
  35. register int    row, col;
  36. unsigned    flags;
  37. {
  38.     register int maxr;
  39.  
  40.     col = (col < 0 ? 0 : col);
  41.     screen->cur_col = (col <= screen->max_col ? col : screen->max_col);
  42.     if(!screen->instatus) {
  43.         maxr = screen->max_row;
  44.         if (flags & ORIGIN) {
  45.             row += screen->top_marg;
  46.             maxr = screen->bot_marg;
  47.         }
  48.         row = (row < 0 ? 0 : row);
  49.         screen->cur_row = (row <= maxr ? row : maxr);
  50.     }
  51.     screen->do_wrap = 0;
  52. }
  53.  
  54. /*
  55.  * moves the cursor left n, no wrap around
  56.  */
  57. CursorBack(screen, n)
  58. register Screen    *screen;
  59. int        n;
  60. {
  61.     register int i, j, k, rev;
  62.     extern Terminal term;
  63.  
  64.     if((rev = (term.flags & (REVERSEWRAP | WRAPAROUND)) ==
  65.      (REVERSEWRAP | WRAPAROUND)) && screen->do_wrap)
  66.         n--;
  67.     if ((screen->cur_col -= n) < 0) {
  68.         if(rev) {
  69.             if((i = (j = screen->max_col + 1) * screen->cur_row +
  70.              screen->cur_col) < 0) {
  71.                 k = j * (screen->max_row + 1);
  72.                 i += ((-i) / k + 1) * k;
  73.             }
  74.             screen->cur_row = i / j;
  75.             screen->cur_col = i % j;
  76.         } else
  77.             screen->cur_col = 0;
  78.     }
  79.     screen->do_wrap = 0;
  80. }
  81.  
  82. /*
  83.  * moves the cursor forward n, no wraparound
  84.  */
  85. CursorForward(screen, n)
  86. register Screen    *screen;
  87. int        n;
  88. {
  89.     screen->cur_col += n;
  90.     if (screen->cur_col > screen->max_col)
  91.         screen->cur_col = screen->max_col;
  92.     screen->do_wrap = 0;
  93. }
  94.  
  95. /* 
  96.  * moves the cursor down n, no scrolling.
  97.  * Won't pass bottom margin or bottom of screen.
  98.  */
  99. CursorDown(screen, n)
  100. register Screen    *screen;
  101. int        n;
  102. {
  103.     register int max;
  104.  
  105.     max = (screen->cur_row > screen->bot_marg ?
  106.         screen->max_row : screen->bot_marg);
  107.  
  108.     screen->cur_row += n;
  109.     if (screen->cur_row > max)
  110.         screen->cur_row = max;
  111.     screen->do_wrap = 0;
  112. }
  113.  
  114. /* 
  115.  * moves the cursor up n, no linestarving.
  116.  * Won't pass top margin or top of screen.
  117.  */
  118. CursorUp(screen, n)
  119. register Screen    *screen;
  120. int        n;
  121. {
  122.     register int min;
  123.  
  124.     min = (screen->cur_row < screen->top_marg ?
  125.         0 : screen->top_marg);
  126.  
  127.     screen->cur_row -= n;
  128.     if (screen->cur_row < min)
  129.         screen->cur_row = min;
  130.     screen->do_wrap = 0;
  131. }
  132.  
  133. /* 
  134.  * Moves cursor down amount lines, scrolls if necessary.
  135.  * Won't leave scrolling region. No carriage return.
  136.  */
  137. Index(screen, amount)
  138. register Screen    *screen;
  139. register int    amount;
  140. {
  141.     register int lines, j;
  142.     register char *str;
  143.     int n;
  144.     XEvent ev;
  145.  
  146.     /* 
  147.      * indexing when below scrolling region is cursor down.
  148.      * if cursor high enough, no scrolling necessary.
  149.      */
  150.     if (screen->cur_row > screen->bot_marg
  151.      || screen->cur_row + amount <= screen->bot_marg) {
  152.         if(screen->pagemode)
  153.             screen->pagecnt += amount;
  154.         CursorDown(screen, amount);
  155.         return;
  156.     }
  157.  
  158.     CursorDown(screen, j = screen->bot_marg - screen->cur_row);
  159.     amount -= j;
  160.     if((lines = screen->bot_marg - screen->top_marg - screen->pageoverlap)
  161.      <= 0)
  162.         lines = 1;
  163.     if(!screen->pagemode || (amount + screen->pagecnt) <= lines) {
  164.         if(screen->pagemode)
  165.             screen->pagecnt += amount;
  166.         Scroll(screen, amount);
  167.         return;
  168.     }
  169.     ioctl(screen->respond, TIOCSTOP, NULL);
  170.     if(screen->cursor_state)
  171.         HideCursor();
  172.     if((j = lines - screen->pagecnt) > 0) {
  173.         Scroll(screen, j);
  174.         amount -= j;
  175.     }
  176.     do {
  177.         if(screen->scroll_amt)
  178.             FlushScroll(screen);
  179.         j = FALSE;
  180.         do {
  181.             XNextEvent(&ev);
  182.             switch((int)ev.type) {
  183.              case KeyPressed:
  184.                 str = XLookupMapping(&ev, &n);
  185.                 if(n > 0) {
  186.                     if(*str == '\r')
  187.                         screen->pagecnt = (lines - 1);
  188.                     else if(*str < ' ' || *str == '\177') {
  189.                         screen->pagecnt = 0;
  190.                         Input(&term.keyboard, screen,
  191.                          &ev);
  192.                         ioctl(screen->respond, TIOCSTOP,
  193.                          NULL);
  194.                     } else
  195.                         screen->pagecnt = 0;
  196.                 } else
  197.                     screen->pagecnt = 0;
  198.                 j = TRUE;
  199.                 break;
  200.              case ButtonPressed:
  201.              case ButtonReleased:
  202.                 screen->pagecnt = amount;
  203.                 xeventpass(&ev);
  204.                 if(!screen->pagemode) {
  205.                     Scroll(screen, amount);
  206.                     ioctl(screen->respond, TIOCSTART, NULL);
  207.                     return;
  208.                 }
  209.                 break;
  210.              default:
  211.                 xeventpass(&ev);
  212.                 break;
  213.             }
  214.         } while(!j);
  215.         j = lines - screen->pagecnt;
  216.         if(j > amount)
  217.             j = amount;
  218.         Scroll(screen, j);
  219.         screen->pagecnt += j;
  220.     } while((amount -= j) > 0);
  221.     ioctl(screen->respond, TIOCSTART, NULL);
  222. }
  223.  
  224. /*
  225.  * Moves cursor up amount lines, reverse scrolls if necessary.
  226.  * Won't leave scrolling region. No carriage return.
  227.  */
  228. RevIndex(screen, amount)
  229. register Screen    *screen;
  230. register int    amount;
  231. {
  232.     /*
  233.      * reverse indexing when above scrolling region is cursor up.
  234.      * if cursor low enough, no reverse indexing needed
  235.      */
  236.     if (screen->cur_row < screen->top_marg
  237.      || screen->cur_row-amount >= screen->top_marg) {
  238.         CursorUp(screen, amount);
  239.         return;
  240.     }
  241.  
  242.     RevScroll(screen, amount - (screen->cur_row - screen->top_marg));
  243.     CursorUp(screen, screen->cur_row - screen->top_marg);
  244. }
  245.  
  246. /*
  247.  * Moves Cursor To First Column In Line
  248.  */
  249. CarriageReturn(screen)
  250. register Screen *screen;
  251. {
  252.     screen->cur_col = 0;
  253.     screen->do_wrap = 0;
  254. }
  255.  
  256. /*
  257.  * Save Cursor and Attributes
  258.  */
  259. CursorSave(term, sc)
  260. register Terminal *term;
  261. register SavedCursor *sc;
  262. {
  263.     register Screen *screen = &term->screen;
  264.  
  265.     sc->row = screen->cur_row;
  266.     sc->col = screen->cur_col;
  267.     sc->flags = term->flags;
  268.     sc->curgl = screen->curgl;
  269.     sc->curgr = screen->curgr;
  270.     bcopy(screen->gsets, sc->gsets, sizeof(screen->gsets));
  271. }
  272.  
  273. /*
  274.  * Restore Cursor and Attributes
  275.  */
  276. CursorRestore(term, sc)
  277. register Terminal *term;
  278. register SavedCursor *sc;
  279. {
  280.     register Screen *screen = &term->screen;
  281.  
  282.     bcopy(sc->gsets, screen->gsets, sizeof(screen->gsets));
  283.     screen->curgl = sc->curgl;
  284.     screen->curgr = sc->curgr;
  285.     term->flags &= ~(BOLD|INVERSE|UNDERLINE);
  286.     term->flags |= sc->flags & (BOLD|INVERSE|UNDERLINE);
  287.     CursorSet(screen, sc->row, sc->col, term->flags);
  288. }
  289.