home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / x11term.c < prev    next >
C/C++ Source or Header  |  2000-09-30  |  32KB  |  1,010 lines

  1. /* -*-C-*-
  2.  
  3. $Id: x11term.c,v 1.27 2000/10/01 02:14:14 cph Exp $
  4.  
  5. Copyright (c) 1989-2000 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. /* X11 terminal for Edwin. */
  23.  
  24. #include "scheme.h"
  25. #include "prims.h"
  26. #include "x11.h"
  27.  
  28. struct xterm_extra
  29. {
  30.   /* Dimensions of the window, in characters.  Valid character
  31.      coordinates are nonnegative integers strictly less than these
  32.      limits. */
  33.   unsigned int x_size;
  34.   unsigned int y_size;
  35.  
  36.   /* Position of the cursor, in character coordinates. */
  37.   unsigned int cursor_x;
  38.   unsigned int cursor_y;
  39.  
  40.   /* Character map of the window's contents.  See `XTERM_CHAR_LOC' for
  41.      the address arithmetic. */
  42.   char * character_map;
  43.  
  44.   /* Bit map of the window's highlighting. */
  45.   char * highlight_map;
  46.  
  47.   /* Nonzero iff the cursor is drawn on the window. */
  48.   char cursor_visible_p;
  49.  
  50.   /* Nonzero iff the cursor should be drawn on the window. */
  51.   char cursor_enabled_p;
  52. };
  53.  
  54. #define XW_EXTRA(xw) ((struct xterm_extra *) ((xw) -> extra))
  55.  
  56. #define XW_X_CSIZE(xw) ((XW_EXTRA (xw)) -> x_size)
  57. #define XW_Y_CSIZE(xw) ((XW_EXTRA (xw)) -> y_size)
  58. #define XW_CURSOR_X(xw) ((XW_EXTRA (xw)) -> cursor_x)
  59. #define XW_CURSOR_Y(xw) ((XW_EXTRA (xw)) -> cursor_y)
  60. #define XW_CHARACTER_MAP(xw) ((XW_EXTRA (xw)) -> character_map)
  61. #define XW_HIGHLIGHT_MAP(xw) ((XW_EXTRA (xw)) -> highlight_map)
  62. #define XW_CURSOR_VISIBLE_P(xw) ((XW_EXTRA (xw)) -> cursor_visible_p)
  63. #define XW_CURSOR_ENABLED_P(xw) ((XW_EXTRA (xw)) -> cursor_enabled_p)
  64.  
  65. #define XTERM_CHAR_INDEX(xw, x, y) (((y) * (XW_X_CSIZE (xw))) + (x))
  66. #define XTERM_CHAR_LOC(xw, index) ((XW_CHARACTER_MAP (xw)) + (index))
  67. #define XTERM_CHAR(xw, index) (* (XTERM_CHAR_LOC (xw, index)))
  68. #define XTERM_HL_LOC(xw, index) ((XW_HIGHLIGHT_MAP (xw)) + (index))
  69. #define XTERM_HL(xw, index) (* (XTERM_HL_LOC (xw, index)))
  70.  
  71. #define XTERM_HL_GC(xw, hl) (hl ? (XW_REVERSE_GC (xw)) : (XW_NORMAL_GC (xw)))
  72.  
  73. #define HL_ARG(arg) arg_index_integer (arg, 2)
  74.  
  75. #define RESOURCE_NAME "schemeTerminal"
  76. #define RESOURCE_CLASS "SchemeTerminal"
  77. #define DEFAULT_GEOMETRY "80x40+0+0"
  78. #define BLANK_CHAR ' '
  79. #define DEFAULT_HL 0
  80.  
  81. #define XTERM_X_PIXEL(xw, x)                        \
  82.   (((x) * (FONT_WIDTH (XW_FONT (xw)))) + (XW_INTERNAL_BORDER_WIDTH (xw)))
  83.  
  84. #define XTERM_Y_PIXEL(xw, y)                        \
  85.   (((y) * (FONT_HEIGHT (XW_FONT (xw)))) + (XW_INTERNAL_BORDER_WIDTH (xw)))
  86.  
  87. #define XTERM_DRAW_CHARS(xw, x, y, s, n, gc)                \
  88.   XDrawImageString                            \
  89.     ((XW_DISPLAY (xw)),                            \
  90.      (XW_WINDOW (xw)),                            \
  91.      gc,                                \
  92.      (XTERM_X_PIXEL (xw, x)),                        \
  93.      ((XTERM_Y_PIXEL (xw, y)) + (FONT_BASE (XW_FONT (xw)))),        \
  94.      s,                                    \
  95.      n)
  96.  
  97. #define CURSOR_IN_RECTANGLE(xw, x_start, x_end, y_start, y_end)        \
  98.   (((x_start) <= (XW_CURSOR_X (xw)))                    \
  99.    && ((XW_CURSOR_X (xw)) < (x_end))                    \
  100.    && ((y_start) <= (XW_CURSOR_Y (xw)))                    \
  101.    && ((XW_CURSOR_Y (xw)) < (y_end)))
  102.  
  103. static void
  104. DEFUN (xterm_erase_cursor, (xw), struct xwindow * xw)
  105. {
  106.   if (XW_CURSOR_VISIBLE_P (xw))
  107.     {
  108.       unsigned int x = (XW_CURSOR_X (xw));
  109.       unsigned int y = (XW_CURSOR_Y (xw));
  110.       unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
  111.       XTERM_DRAW_CHARS
  112.     (xw, x, y,
  113.      (XTERM_CHAR_LOC (xw, index)),
  114.      1,
  115.      (XTERM_HL_GC (xw, (XTERM_HL (xw, index)))));
  116.       (XW_CURSOR_VISIBLE_P (xw)) = 0;
  117.     }
  118. }
  119.  
  120. static void
  121. DEFUN (xterm_draw_cursor, (xw), struct xwindow * xw)
  122. {
  123.   if ((XW_CURSOR_ENABLED_P (xw)) && (! (XW_CURSOR_VISIBLE_P (xw))))
  124.     {
  125.       unsigned int x = (XW_CURSOR_X (xw));
  126.       unsigned int y = (XW_CURSOR_Y (xw));
  127.       unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
  128.       int hl = (XTERM_HL (xw, index));
  129.       XTERM_DRAW_CHARS
  130.     (xw, x, y,
  131.      (XTERM_CHAR_LOC (xw, index)),
  132.      1,
  133.      ((hl && ((XW_FOREGROUND_PIXEL (xw)) == (XW_CURSOR_PIXEL (xw))))
  134.       ? (XW_NORMAL_GC (xw))
  135.       : (XW_CURSOR_GC (xw))));
  136.       (XW_CURSOR_VISIBLE_P (xw)) = 1;
  137.     }
  138. }
  139.  
  140. static void
  141. DEFUN (xterm_process_event, (xw, event),
  142.        struct xwindow * xw AND
  143.        XEvent * event)
  144. {
  145. }
  146.  
  147. static XSizeHints *
  148. DEFUN (xterm_make_size_hints, (font, extra),
  149.        XFontStruct * font AND
  150.        unsigned int extra)
  151. {
  152.   XSizeHints * size_hints = (XAllocSizeHints ());
  153.   if (size_hints == 0)
  154.     error_external_return ();
  155.   (size_hints -> flags) = (PResizeInc | PMinSize | PBaseSize);
  156.   (size_hints -> width_inc) = (FONT_WIDTH (font));
  157.   (size_hints -> height_inc) = (FONT_HEIGHT (font));
  158.   (size_hints -> min_width) = extra;
  159.   (size_hints -> min_height) = extra;
  160.   (size_hints -> base_width) = extra;
  161.   (size_hints -> base_height) = extra;
  162.   return (size_hints);
  163. }
  164.  
  165. static void
  166. DEFUN (xterm_set_wm_normal_hints, (xw, size_hints, geometry_mask, x, y),
  167.        struct xwindow * xw AND
  168.        XSizeHints * size_hints AND
  169.        int geometry_mask AND
  170.        unsigned int x AND
  171.        unsigned int y)
  172. {
  173.   (size_hints -> flags) |=
  174.     ((((geometry_mask & XValue) && (geometry_mask & YValue))
  175.       ? USPosition : PPosition)
  176.      | (((geometry_mask & WidthValue) && (geometry_mask & HeightValue))
  177.     ? USSize : PSize));
  178.   (size_hints -> x) = x;
  179.   (size_hints -> y) = y;
  180.   (size_hints -> width) =
  181.     (((XW_X_CSIZE (xw)) * (size_hints -> width_inc))
  182.      + (size_hints -> base_width));
  183.   (size_hints -> height) =
  184.     (((XW_Y_CSIZE (xw)) * (size_hints -> height_inc))
  185.      + (size_hints -> base_height));
  186.   XSetWMNormalHints ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), size_hints);
  187.   XFree ((caddr_t) size_hints);
  188. }
  189.  
  190. static void
  191. DEFUN (xterm_update_normal_hints, (xw), struct xwindow * xw)
  192. {
  193.   xterm_set_wm_normal_hints
  194.     (xw,
  195.      (xterm_make_size_hints
  196.       ((XW_FONT (xw)),
  197.        (2 * (XW_INTERNAL_BORDER_WIDTH (xw))))),
  198.      0, 0, 0);
  199. }
  200.  
  201. static void
  202. DEFUN (xterm_deallocate, (xw), struct xwindow * xw)
  203. {
  204.   free (XW_CHARACTER_MAP (xw));
  205.   free (XW_HIGHLIGHT_MAP (xw));
  206. }
  207.  
  208. static SCHEME_OBJECT
  209. DEFUN (xterm_x_coordinate_map, (xw, x), struct xwindow * xw AND unsigned int x)
  210. {
  211.   return (ulong_to_integer (x / (FONT_WIDTH (XW_FONT (xw)))));
  212. }
  213.  
  214. static SCHEME_OBJECT
  215. DEFUN (xterm_y_coordinate_map, (xw, y), struct xwindow * xw AND unsigned int y)
  216. {
  217.   return (ulong_to_integer (y / (FONT_HEIGHT (XW_FONT (xw)))));
  218. }
  219.  
  220. static void
  221. DEFUN (xterm_copy_map_line, (xw, x_start, x_end, y_from, y_to),
  222.        struct xwindow * xw AND
  223.        unsigned int x_start AND
  224.        unsigned int x_end AND
  225.        unsigned int y_from AND
  226.        unsigned int y_to)
  227. {
  228.   {
  229.     char * from_scan =
  230.       (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_from))));
  231.     char * from_end =
  232.       (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_end, y_from))));
  233.     char * to_scan =
  234.       (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_to))));
  235.     while (from_scan < from_end)
  236.       (*to_scan++) = (*from_scan++);
  237.   }
  238.   {
  239.     char * from_scan =
  240.       (XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_from))));
  241.     char * from_end =
  242.       (XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_end, y_from))));
  243.     char * to_scan =
  244.       (XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_to))));
  245.     while (from_scan < from_end)
  246.       (*to_scan++) = (*from_scan++);
  247.   }
  248. }
  249.  
  250. static void
  251. DEFUN (xterm_dump_contents, (xw, x_start, x_end, y_start, y_end),
  252.        struct xwindow * xw AND
  253.        unsigned int x_start AND
  254.        unsigned int x_end AND
  255.        unsigned int y_start AND
  256.        unsigned int y_end)
  257. {
  258.   char * character_map = (XW_CHARACTER_MAP (xw));
  259.   char * highlight_map = (XW_HIGHLIGHT_MAP (xw));
  260.   if (x_start < x_end)
  261.     {
  262.       unsigned int yi;
  263.       for (yi = y_start; (yi < y_end); yi += 1)
  264.     {
  265.       unsigned int index = (XTERM_CHAR_INDEX (xw, 0, yi));
  266.       char * line_char = (&character_map[index]);
  267.       char * line_hl = (&highlight_map[index]);
  268.       unsigned int xi = x_start;
  269.       while (1)
  270.         {
  271.           unsigned int hl = (line_hl[xi]);
  272.           unsigned int xj = (xi + 1);
  273.           while ((xj < x_end) && ((line_hl[xj]) == hl))
  274.         xj += 1;
  275.           XTERM_DRAW_CHARS (xw, xi, yi,
  276.                 (&line_char[xi]),
  277.                 (xj - xi),
  278.                 (XTERM_HL_GC (xw, hl)));
  279.           if (xj == x_end)
  280.         break;
  281.           xi = xj;
  282.         }
  283.     }
  284.       if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, y_end))
  285.     {
  286.       (XW_CURSOR_VISIBLE_P (xw)) = 0;
  287.       xterm_draw_cursor (xw);
  288.     }
  289.     }
  290. }
  291.  
  292. static void
  293. DEFUN (xterm_dump_rectangle, (xw, x, y, width, height),
  294.        struct xwindow * xw AND
  295.        unsigned int x AND
  296.        unsigned int y AND
  297.        unsigned int width AND
  298.        unsigned int height)
  299. {
  300.   XFontStruct * font = (XW_FONT (xw));
  301.   unsigned int fwidth = (FONT_WIDTH (font));
  302.   unsigned int fheight = (FONT_HEIGHT (font));
  303.   unsigned int border = (XW_INTERNAL_BORDER_WIDTH (xw));
  304.   if (x < border)
  305.     {
  306.       width -= (border - x);
  307.       x = 0;
  308.     }
  309.   else
  310.     x -= border;
  311.   if ((x + width) > (XW_X_SIZE (xw)))
  312.     width = ((XW_X_SIZE (xw)) - x);
  313.   if (y < border)
  314.     {
  315.       height -= (border - y);
  316.       y = 0;
  317.     }
  318.   else
  319.     y -= border;
  320.   if ((y + height) > (XW_Y_SIZE (xw)))
  321.     height = ((XW_Y_SIZE (xw)) - y);
  322.   {
  323.     unsigned int x_start = (x / fwidth);
  324.     unsigned int x_end = (((x + width) + (fwidth - 1)) / fwidth);
  325.     unsigned int y_start = (y / fheight);
  326.     unsigned int y_end = (((y + height) + (fheight - 1)) / fheight);
  327.     if (x_end > (XW_X_CSIZE (xw)))
  328.       x_end = (XW_X_CSIZE (xw));
  329.     if (y_end > (XW_Y_CSIZE (xw)))
  330.       y_end = (XW_Y_CSIZE (xw));
  331.     xterm_dump_contents (xw, x_start, x_end, y_start, y_end);
  332.   }
  333.   XFlush (XW_DISPLAY (xw));
  334. }
  335.  
  336. #define MIN(x, y) (((x) < (y)) ? (x) : (y))
  337.  
  338. static void
  339. DEFUN (xterm_reconfigure, (xw, width, height),
  340.        struct xwindow * xw AND
  341.        unsigned int width AND
  342.        unsigned int height)
  343. {
  344.   unsigned int extra = (2 * (XW_INTERNAL_BORDER_WIDTH (xw)));
  345.   unsigned int x_size = ((width < extra) ? 0 : (width - extra));
  346.   unsigned int y_size = ((height < extra) ? 0 : (height - extra));
  347.   if ((x_size != (XW_X_SIZE (xw))) || (y_size != (XW_Y_SIZE (xw))))
  348.     {
  349.       unsigned int x_csize = (x_size / (FONT_WIDTH (XW_FONT (xw))));
  350.       unsigned int y_csize = (y_size / (FONT_HEIGHT (XW_FONT (xw))));
  351.       char * new_char_map = (x_malloc (x_csize * y_csize));
  352.       char * new_hl_map = (x_malloc (x_csize * y_csize));
  353.       unsigned int old_x_csize = (XW_X_CSIZE (xw));
  354.       unsigned int min_x_csize = (MIN (x_csize, old_x_csize));
  355.       unsigned int min_y_csize = (MIN (y_csize, (XW_Y_CSIZE (xw))));
  356.       int x_clipped = (old_x_csize - x_csize);
  357.       char * new_scan_char = new_char_map;
  358.       char * new_scan_hl = new_hl_map;
  359.       char * new_end;
  360.       char * old_scan_char = (XW_CHARACTER_MAP (xw));
  361.       char * old_scan_hl = (XW_HIGHLIGHT_MAP (xw));
  362.       char * old_end;
  363.       unsigned int new_y = 0;
  364.       for (; (new_y < min_y_csize); new_y += 1)
  365.     {
  366.       old_end = (old_scan_char + min_x_csize);
  367.       while (old_scan_char < old_end)
  368.         {
  369.           (*new_scan_char++) = (*old_scan_char++);
  370.           (*new_scan_hl++) = (*old_scan_hl++);
  371.         }
  372.       if (x_clipped < 0)
  373.         {
  374.           new_end = (new_scan_char + ((unsigned int) (- x_clipped)));
  375.           while (new_scan_char < new_end)
  376.         {
  377.           (*new_scan_char++) = BLANK_CHAR;
  378.           (*new_scan_hl++) = DEFAULT_HL;
  379.         }
  380.         }
  381.       else if (x_clipped > 0)
  382.         {
  383.           old_scan_char += ((unsigned int) x_clipped);
  384.           old_scan_hl += ((unsigned int) x_clipped);
  385.         }
  386.     }
  387.       for (; (new_y < y_csize); new_y += 1)
  388.     {
  389.       new_end = (new_scan_char + x_csize);
  390.       while (new_scan_char < new_end)
  391.         {
  392.           (*new_scan_char++) = BLANK_CHAR;
  393.           (*new_scan_hl++) = DEFAULT_HL;
  394.         }
  395.     }
  396.       free (XW_CHARACTER_MAP (xw));
  397.       free (XW_HIGHLIGHT_MAP (xw));
  398.       (XW_X_SIZE (xw)) = x_size;
  399.       (XW_Y_SIZE (xw)) = y_size;
  400.       (XW_CLIP_X (xw)) = 0;
  401.       (XW_CLIP_Y (xw)) = 0;
  402.       (XW_CLIP_WIDTH (xw)) = x_size;
  403.       (XW_CLIP_HEIGHT (xw)) = y_size;
  404.       (XW_X_CSIZE (xw)) = x_csize;
  405.       (XW_Y_CSIZE (xw)) = y_csize;
  406.       (XW_CHARACTER_MAP (xw))= new_char_map;
  407.       (XW_HIGHLIGHT_MAP (xw))= new_hl_map;
  408.       XClearWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
  409.       xterm_dump_contents (xw, 0, 0, x_csize, y_csize);
  410.       xterm_update_normal_hints (xw);
  411.       XFlush (XW_DISPLAY (xw));
  412.     }
  413. }
  414.  
  415. DEFINE_PRIMITIVE ("XTERM-RECONFIGURE", Prim_xterm_reconfigure, 3, 3, 0)
  416. {
  417.   PRIMITIVE_HEADER (3);
  418.   xterm_reconfigure ((x_window_arg (1)),
  419.              (arg_ulong_integer (2)),
  420.              (arg_ulong_integer (3)));
  421.   PRIMITIVE_RETURN (UNSPECIFIC);
  422. }
  423.  
  424. DEFINE_PRIMITIVE ("XTERM-DUMP-RECTANGLE", Prim_xterm_dump_rectangle, 5, 5, 0)
  425. {
  426.   PRIMITIVE_HEADER (5);
  427.   xterm_dump_rectangle ((x_window_arg (1)),
  428.             (arg_ulong_integer (2)),
  429.             (arg_ulong_integer (3)),
  430.             (arg_ulong_integer (4)),
  431.             (arg_ulong_integer (5)));
  432.   PRIMITIVE_RETURN (UNSPECIFIC);
  433. }
  434.  
  435. DEFINE_PRIMITIVE ("XTERM-MAP-X-COORDINATE", Prim_xterm_map_x_coordinate, 2, 2, 0)
  436. {
  437.   PRIMITIVE_HEADER (2);
  438.   {
  439.     struct xwindow * xw = (x_window_arg (1));
  440.     unsigned int xp = (arg_ulong_integer (2));
  441.     int bx = (xp - (XW_INTERNAL_BORDER_WIDTH (xw)));
  442.     PRIMITIVE_RETURN
  443.       (long_to_integer
  444.        (((bx < 0) ? 0
  445.      : (bx >= (XW_X_SIZE (xw))) ? ((XW_X_SIZE (xw)) - 1)
  446.      : bx)
  447.     / (FONT_WIDTH (XW_FONT (xw)))));
  448.   }
  449. }
  450.  
  451. DEFINE_PRIMITIVE ("XTERM-MAP-Y-COORDINATE", Prim_xterm_map_y_coordinate, 2, 2, 0)
  452. {
  453.   PRIMITIVE_HEADER (2);
  454.   {
  455.     struct xwindow * xw = (x_window_arg (1));
  456.     unsigned int yp = (arg_ulong_integer (2));
  457.     int by = (yp - (XW_INTERNAL_BORDER_WIDTH (xw)));
  458.     PRIMITIVE_RETURN
  459.       (long_to_integer
  460.        (((by < 0) ? 0
  461.      : (by >= (XW_Y_SIZE (xw))) ? ((XW_Y_SIZE (xw)) - 1)
  462.      : by)
  463.     / (FONT_HEIGHT (XW_FONT (xw)))));
  464.   }
  465. }
  466.  
  467. DEFINE_PRIMITIVE ("XTERM-MAP-X-SIZE", Prim_xterm_map_x_size, 2, 2, 0)
  468. {
  469.   PRIMITIVE_HEADER (2);
  470.   {
  471.     struct xwindow * xw = (x_window_arg (1));
  472.     int width =
  473.       ((arg_nonnegative_integer (2)) - (2 * (XW_INTERNAL_BORDER_WIDTH (xw))));
  474.     PRIMITIVE_RETURN
  475.       (ulong_to_integer
  476.        ((width < 0) ? 0 : (width / (FONT_WIDTH (XW_FONT (xw))))));
  477.   }
  478. }
  479.  
  480. DEFINE_PRIMITIVE ("XTERM-MAP-Y-SIZE", Prim_xterm_map_y_size, 2, 2, 0)
  481. {
  482.   PRIMITIVE_HEADER (2);
  483.   {
  484.     struct xwindow * xw = (x_window_arg (1));
  485.     int height =
  486.       ((arg_nonnegative_integer (2)) - (2 * (XW_INTERNAL_BORDER_WIDTH (xw))));
  487.     PRIMITIVE_RETURN
  488.       (ulong_to_integer
  489.        ((height < 0) ? 0 : (height / (FONT_HEIGHT (XW_FONT (xw))))));
  490.   }
  491. }
  492.  
  493. DEFINE_PRIMITIVE ("XTERM-OPEN-WINDOW", Prim_xterm_open_window, 3, 3, 0)
  494. {
  495.   PRIMITIVE_HEADER (3);
  496.   {
  497.     struct xdisplay * xd = (x_display_arg (1));
  498.     Display * display = (XD_DISPLAY (xd));
  499.     struct drawing_attributes attributes;
  500.     struct xwindow_methods methods;
  501.     CONST char * resource_name = RESOURCE_NAME;
  502.     CONST char * resource_class = RESOURCE_CLASS;
  503.     int map_p;
  504.     
  505.     x_decode_window_map_arg
  506.       ((ARG_REF (3)), (&resource_name), (&resource_class), (&map_p));
  507.     x_default_attributes
  508.       (display, resource_name, resource_class, (&attributes));
  509.     (methods . deallocator) = xterm_deallocate;
  510.     (methods . event_processor) = xterm_process_event;
  511.     (methods . x_coordinate_map) = xterm_x_coordinate_map;
  512.     (methods . y_coordinate_map) = xterm_y_coordinate_map;
  513.     (methods . update_normal_hints) = xterm_update_normal_hints;
  514.     {
  515.       unsigned int extra = (2 * (attributes . internal_border_width));
  516.       int x_pos;
  517.       int y_pos;
  518.       int x_size;
  519.       int y_size;
  520.       XSizeHints * size_hints =
  521.     (xterm_make_size_hints ((attributes . font), extra));
  522.       int geometry_mask =
  523.     (XWMGeometry
  524.      (display,
  525.       (DefaultScreen (display)),
  526.       (((ARG_REF (2)) == SHARP_F)
  527.        ? (x_get_default
  528.           (display, resource_name, resource_class,
  529.            "geometry", "Geometry", 0))
  530.        : (STRING_ARG (2))),
  531.       DEFAULT_GEOMETRY,
  532.       (attributes . border_width),
  533.       size_hints,
  534.       (&x_pos), (&y_pos), (&x_size), (&y_size),
  535.       (& (size_hints -> win_gravity))));
  536.       unsigned int x_csize =
  537.     ((x_size - (size_hints -> base_width)) / (size_hints -> width_inc));
  538.       unsigned int y_csize =
  539.     ((y_size - (size_hints -> base_height)) / (size_hints -> height_inc));
  540.       Window window =
  541.     (XCreateSimpleWindow
  542.      (display, (RootWindow (display, (DefaultScreen (display)))),
  543.       x_pos, y_pos, x_size, y_size,
  544.       (attributes . border_width),
  545.       (attributes . border_pixel),
  546.       (attributes . background_pixel)));
  547.       if (window == 0)
  548.     error_external_return ();
  549.       {
  550.     struct xwindow * xw =
  551.       (x_make_window
  552.        (xd,
  553.         window,
  554.         (x_size - (size_hints -> base_width)),
  555.         (y_size - (size_hints -> base_height)),
  556.         (&attributes),
  557.         (&methods),
  558.         (sizeof (struct xterm_extra))));
  559.     unsigned int map_size = (x_csize * y_csize);
  560.     (XW_X_CSIZE (xw)) = x_csize;
  561.     (XW_Y_CSIZE (xw)) = y_csize;
  562.     (XW_CURSOR_X (xw)) = 0;
  563.     (XW_CURSOR_Y (xw)) = 0;
  564.     (XW_CURSOR_VISIBLE_P (xw)) = 0;
  565.     (XW_CURSOR_ENABLED_P (xw)) = 1;
  566.     {
  567.       char * scan = (x_malloc (map_size));
  568.       char * end = (scan + map_size);
  569.       (XW_CHARACTER_MAP (xw)) = scan;
  570.       while (scan < end)
  571.         (*scan++) = BLANK_CHAR;
  572.     }
  573.     {
  574.       char * scan = (x_malloc (map_size));
  575.       char * end = (scan + map_size);
  576.       (XW_HIGHLIGHT_MAP (xw)) = scan;
  577.       while (scan < end)
  578.         (*scan++) = DEFAULT_HL;
  579.     }
  580.     (size_hints -> flags) |= PWinGravity;
  581.     xterm_set_wm_normal_hints
  582.       (xw, size_hints, geometry_mask, x_pos, y_pos);
  583.     xw_set_wm_input_hint (xw, 1);
  584.     xw_set_wm_name (xw, "scheme-terminal");
  585.     xw_set_wm_icon_name (xw, "scheme-terminal");
  586.     xw_make_window_map (xw, resource_name, resource_class, map_p);
  587.     PRIMITIVE_RETURN (XW_TO_OBJECT (xw));
  588.       }
  589.     }
  590.   }
  591. }
  592.  
  593. DEFINE_PRIMITIVE ("XTERM-X-SIZE", Prim_xterm_x_size, 1, 1, 0)
  594. {
  595.   PRIMITIVE_HEADER (1);
  596.   PRIMITIVE_RETURN (ulong_to_integer (XW_X_CSIZE (x_window_arg (1))));
  597. }
  598.  
  599. DEFINE_PRIMITIVE ("XTERM-Y-SIZE", Prim_xterm_y_size, 1, 1, 0)
  600. {
  601.   PRIMITIVE_HEADER (1);
  602.   PRIMITIVE_RETURN (ulong_to_integer (XW_Y_CSIZE (x_window_arg (1))));
  603. }
  604.  
  605. DEFINE_PRIMITIVE ("XTERM-SET-SIZE", Prim_xterm_set_size, 3, 3, 0)
  606. {
  607.   struct xwindow * xw;
  608.   int extra;
  609.   XFontStruct * font;
  610.   PRIMITIVE_HEADER (3);
  611.   xw = (x_window_arg (1));
  612.   extra = (2 * (XW_INTERNAL_BORDER_WIDTH (xw)));
  613.   font = (XW_FONT (xw));
  614.   XResizeWindow
  615.     ((XW_DISPLAY (xw)),
  616.      (XW_WINDOW (xw)),
  617.      (((arg_ulong_integer (2)) * (FONT_WIDTH (font))) + extra),
  618.      (((arg_ulong_integer (3)) * (FONT_HEIGHT (font))) + extra));
  619.   PRIMITIVE_RETURN (UNSPECIFIC);
  620. }
  621.  
  622. DEFINE_PRIMITIVE ("XTERM-ENABLE-CURSOR", Prim_xterm_enable_cursor, 2, 2, 0)
  623. {
  624.   PRIMITIVE_HEADER (2);
  625.   (XW_CURSOR_ENABLED_P (x_window_arg (1))) = (BOOLEAN_ARG (2));
  626.   PRIMITIVE_RETURN (UNSPECIFIC);
  627. }
  628.  
  629. DEFINE_PRIMITIVE ("XTERM-ERASE-CURSOR", Prim_xterm_erase_cursor, 1, 1, 0)
  630. {
  631.   PRIMITIVE_HEADER (1);
  632.   xterm_erase_cursor (x_window_arg (1));
  633.   PRIMITIVE_RETURN (UNSPECIFIC);
  634. }
  635.  
  636. DEFINE_PRIMITIVE ("XTERM-DRAW-CURSOR", Prim_xterm_draw_cursor, 1, 1, 0)
  637. {
  638.   PRIMITIVE_HEADER (1);
  639.   xterm_draw_cursor (x_window_arg (1));
  640.   PRIMITIVE_RETURN (UNSPECIFIC);
  641. }
  642.  
  643. DEFINE_PRIMITIVE ("XTERM-WRITE-CURSOR!", Prim_xterm_write_cursor, 3, 3, 0)
  644. {
  645.   PRIMITIVE_HEADER (3);
  646.   {
  647.     struct xwindow * xw = (x_window_arg (1));
  648.     unsigned int x = (arg_ulong_index_integer (2, (XW_X_CSIZE (xw))));
  649.     unsigned int y = (arg_ulong_index_integer (3, (XW_Y_CSIZE (xw))));
  650.     if ((x != (XW_CURSOR_X (xw))) || (y != (XW_CURSOR_Y (xw))))
  651.       {
  652.     xterm_erase_cursor (xw);
  653.     (XW_CURSOR_X (xw)) = x;
  654.     (XW_CURSOR_Y (xw)) = y;
  655.       }
  656.     xterm_draw_cursor (xw);
  657.   }
  658.   PRIMITIVE_RETURN (UNSPECIFIC);
  659. }
  660.  
  661. DEFINE_PRIMITIVE ("XTERM-WRITE-CHAR!", Prim_xterm_write_char, 5, 5, 0)
  662. {
  663.   PRIMITIVE_HEADER (5);
  664.   {
  665.     struct xwindow * xw = (x_window_arg (1));
  666.     unsigned int x = (arg_ulong_index_integer (2, (XW_X_CSIZE (xw))));
  667.     unsigned int y = (arg_ulong_index_integer (3, (XW_Y_CSIZE (xw))));
  668.     int c = (arg_ascii_char (4));
  669.     unsigned int hl = (HL_ARG (5));
  670.     unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
  671.     char * map_ptr = (XTERM_CHAR_LOC (xw, index));
  672.     (*map_ptr) = c;
  673.     (XTERM_HL (xw, index)) = hl;
  674.     XTERM_DRAW_CHARS (xw, x, y, map_ptr, 1, (XTERM_HL_GC (xw, hl)));
  675.     if (((XW_CURSOR_X (xw)) == x) && ((XW_CURSOR_Y (xw)) == y))
  676.       {
  677.     (XW_CURSOR_VISIBLE_P (xw)) = 0;
  678.     xterm_draw_cursor (xw);
  679.       }
  680.   }
  681.   PRIMITIVE_RETURN (UNSPECIFIC);
  682. }
  683.  
  684. DEFINE_PRIMITIVE ("XTERM-WRITE-SUBSTRING!", Prim_xterm_write_substring, 7, 7, 0)
  685. {
  686.   PRIMITIVE_HEADER (7);
  687.   CHECK_ARG (4, STRING_P);
  688.   {
  689.     struct xwindow * xw = (x_window_arg (1));
  690.     unsigned int x = (arg_ulong_index_integer (2, (XW_X_CSIZE (xw))));
  691.     unsigned int y = (arg_ulong_index_integer (3, (XW_Y_CSIZE (xw))));
  692.     SCHEME_OBJECT string = (ARG_REF (4));
  693.     unsigned int end
  694.       = (arg_ulong_index_integer (6, ((STRING_LENGTH (string)) + 1)));
  695.     unsigned int start = (arg_ulong_index_integer (5, (end + 1)));
  696.     unsigned int hl = (HL_ARG (7));
  697.     unsigned int length = (end - start);
  698.     unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
  699.     if ((x + length) > (XW_X_CSIZE (xw)))
  700.       error_bad_range_arg (2);
  701.     {
  702.       unsigned char * string_scan = (STRING_LOC (string, start));
  703.       unsigned char * string_end = (STRING_LOC (string, end));
  704.       char * char_scan = (XTERM_CHAR_LOC (xw, index));
  705.       char * hl_scan = (XTERM_HL_LOC (xw, index));
  706.       while (string_scan < string_end)
  707.     {
  708.       (*char_scan++) = (*string_scan++);
  709.       (*hl_scan++) = hl;
  710.     }
  711.     }
  712.     XTERM_DRAW_CHARS
  713.       (xw, x, y, (XTERM_CHAR_LOC (xw, index)), length, (XTERM_HL_GC (xw, hl)));
  714.     if ((x <= (XW_CURSOR_X (xw))) && ((XW_CURSOR_X (xw)) < (x + length))
  715.     && (y == (XW_CURSOR_Y (xw))))
  716.       {
  717.     (XW_CURSOR_VISIBLE_P (xw)) = 0;
  718.     xterm_draw_cursor (xw);
  719.       }
  720.   }
  721.   PRIMITIVE_RETURN (UNSPECIFIC);
  722. }
  723.  
  724. static void
  725. DEFUN (xterm_clear_rectangle, (xw, x_start, x_end, y_start, y_end, hl),
  726.        struct xwindow * xw AND
  727.        unsigned int x_start AND
  728.        unsigned int x_end AND
  729.        unsigned int y_start AND
  730.        unsigned int y_end AND
  731.        unsigned int hl)
  732. {
  733.   unsigned int x_length = (x_end - x_start);
  734.   unsigned int y;
  735.   for (y = y_start; (y < y_end); y += 1)
  736.     {
  737.       unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
  738.       {
  739.     char * scan = (XTERM_CHAR_LOC (xw, index));
  740.     char * end = (scan + x_length);
  741.     while (scan < end)
  742.       (*scan++) = BLANK_CHAR;
  743.       }
  744.       {
  745.     char * scan = (XTERM_HL_LOC (xw, index));
  746.     char * end = (scan + x_length);
  747.     while (scan < end)
  748.       (*scan++) = hl;
  749.       }
  750.     }
  751.   if (hl != 0)
  752.     {
  753.       GC hl_gc = (XTERM_HL_GC (xw, hl));
  754.       for (y = y_start; (y < y_end); y += 1)
  755.     XTERM_DRAW_CHARS
  756.       (xw, x_start, y,
  757.        (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y)))),
  758.        x_length, hl_gc);
  759.     }
  760.   else if ((x_start == 0)
  761.        && (y_start == 0)
  762.        && (x_end == (XW_X_CSIZE (xw)))
  763.        && (y_end == (XW_Y_CSIZE (xw))))
  764.     XClearWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
  765.   else
  766.     XClearArea ((XW_DISPLAY (xw)),
  767.         (XW_WINDOW (xw)),
  768.         (XTERM_X_PIXEL (xw, x_start)),
  769.         (XTERM_Y_PIXEL (xw, y_start)),
  770.         (x_length * (FONT_WIDTH (XW_FONT (xw)))),
  771.         ((y_end - y_start) * (FONT_HEIGHT (XW_FONT (xw)))),
  772.         False);
  773. }
  774.  
  775. DEFINE_PRIMITIVE ("XTERM-CLEAR-RECTANGLE!", Prim_xterm_clear_rectangle, 6, 6, 0)
  776. {
  777.   PRIMITIVE_HEADER (6);
  778.   {
  779.     struct xwindow * xw = (x_window_arg (1));
  780.     unsigned int x_end
  781.       = (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  782.     unsigned int y_end
  783.       = (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  784.     unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
  785.     unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
  786.     unsigned int hl = (HL_ARG (6));
  787.     if ((x_start < x_end) && (y_start < y_end))
  788.       {
  789.     xterm_clear_rectangle (xw, x_start, x_end, y_start, y_end, hl);
  790.     if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, y_end))
  791.       {
  792.         (XW_CURSOR_VISIBLE_P (xw)) = 0;
  793.         xterm_draw_cursor (xw);
  794.       }
  795.       }
  796.   }
  797.   PRIMITIVE_RETURN (UNSPECIFIC);
  798. }
  799.  
  800. static void
  801. DEFUN (xterm_scroll_lines_up, (xw, x_start, x_end, y_start, y_end, lines),
  802.        struct xwindow * xw AND
  803.        unsigned int x_start AND
  804.        unsigned int x_end AND
  805.        unsigned int y_start AND
  806.        unsigned int y_end AND
  807.        unsigned int lines)
  808. {
  809.   {
  810.     unsigned int y_to = y_start;
  811.     unsigned int y_from = (y_to + lines);
  812.     while (y_from < y_end)
  813.       xterm_copy_map_line (xw, x_start, x_end, (y_from++), (y_to++));
  814.   }
  815.   XCopyArea ((XW_DISPLAY (xw)),
  816.          (XW_WINDOW (xw)),
  817.          (XW_WINDOW (xw)),
  818.          (XW_NORMAL_GC (xw)),
  819.          (XTERM_X_PIXEL (xw, x_start)),
  820.          (XTERM_Y_PIXEL (xw, (y_start + lines))),
  821.          ((x_end - x_start) * (FONT_WIDTH (XW_FONT (xw)))),
  822.          (((y_end - y_start) - lines) * (FONT_HEIGHT (XW_FONT (xw)))),
  823.          (XTERM_X_PIXEL (xw, x_start)),
  824.          (XTERM_Y_PIXEL (xw, y_start)));
  825. }
  826.  
  827. DEFINE_PRIMITIVE ("XTERM-SCROLL-LINES-UP", Prim_xterm_scroll_lines_up, 6, 6,
  828.   "(XTERM-SCROLL-LINES-UP XTERM X-START X-END Y-START Y-END LINES)\n\
  829. Scroll the contents of the region up by LINES.")
  830. {
  831.   PRIMITIVE_HEADER (6);
  832.   {
  833.     struct xwindow * xw = (x_window_arg (1));
  834.     unsigned int x_end
  835.       = (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  836.     unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
  837.     unsigned int y_end
  838.       = (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  839.     unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
  840.     unsigned int lines = (arg_ulong_index_integer (6, (y_end - y_start)));
  841.     if ((0 < lines) && (x_start < x_end) && (y_start < y_end))
  842.       {
  843.     if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, (y_start + lines), y_end))
  844.       {
  845.         xterm_erase_cursor (xw);
  846.         xterm_scroll_lines_up (xw, x_start, x_end, y_start, y_end, lines);
  847.         xterm_draw_cursor (xw);
  848.       }
  849.     else
  850.       {
  851.         xterm_scroll_lines_up (xw, x_start, x_end, y_start, y_end, lines);
  852.         if (CURSOR_IN_RECTANGLE
  853.         (xw, x_start, x_end, y_start, (y_end - lines)))
  854.           {
  855.         (XW_CURSOR_VISIBLE_P (xw)) = 0;
  856.         xterm_draw_cursor (xw);
  857.           }
  858.       }
  859.       }
  860.   }
  861.   PRIMITIVE_RETURN (UNSPECIFIC);
  862. }
  863.  
  864. static void
  865. DEFUN (xterm_scroll_lines_down, (xw, x_start, x_end, y_start, y_end, lines),
  866.        struct xwindow * xw AND
  867.        unsigned int x_start AND
  868.        unsigned int x_end AND
  869.        unsigned int y_start AND
  870.        unsigned int y_end AND
  871.        unsigned int lines)
  872. {
  873.   {
  874.     unsigned int y_to = y_end;
  875.     unsigned int y_from = (y_to - lines);
  876.     while (y_from > y_start)
  877.       xterm_copy_map_line (xw, x_start, x_end, (--y_from), (--y_to));
  878.   }
  879.   XCopyArea ((XW_DISPLAY (xw)),
  880.          (XW_WINDOW (xw)),
  881.          (XW_WINDOW (xw)),
  882.          (XW_NORMAL_GC (xw)),
  883.          (XTERM_X_PIXEL (xw, x_start)),
  884.          (XTERM_Y_PIXEL (xw, y_start)),
  885.          ((x_end - x_start) * (FONT_WIDTH (XW_FONT (xw)))),
  886.          (((y_end - y_start) - lines) * (FONT_HEIGHT (XW_FONT (xw)))),
  887.          (XTERM_X_PIXEL (xw, x_start)),
  888.          (XTERM_Y_PIXEL (xw, (y_start + lines))));
  889. }
  890.  
  891. DEFINE_PRIMITIVE ("XTERM-SCROLL-LINES-DOWN", Prim_xterm_scroll_lines_down, 6, 6,
  892.   "(XTERM-SCROLL-LINES-DOWN XTERM X-START X-END Y-START Y-END LINES)\n\
  893. Scroll the contents of the region down by LINES.")
  894. {
  895.   PRIMITIVE_HEADER (6);
  896.   {
  897.     struct xwindow * xw = (x_window_arg (1));
  898.     unsigned int x_end
  899.       = (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  900.     unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
  901.     unsigned int y_end
  902.       = (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  903.     unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
  904.     unsigned int lines = (arg_ulong_index_integer (6, (y_end - y_start)));
  905.     if ((0 < lines) && (x_start < x_end) && (y_start < y_end))
  906.       {
  907.     if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, (y_end - lines)))
  908.       {
  909.         xterm_erase_cursor (xw);
  910.         xterm_scroll_lines_down
  911.           (xw, x_start, x_end, y_start, y_end, lines);
  912.         xterm_draw_cursor (xw);
  913.       }
  914.     else
  915.       {
  916.         xterm_scroll_lines_down
  917.           (xw, x_start, x_end, y_start, y_end, lines);
  918.         if (CURSOR_IN_RECTANGLE
  919.         (xw, x_start, x_end, (y_start + lines), y_end))
  920.           {
  921.         (XW_CURSOR_VISIBLE_P (xw)) = 0;
  922.         xterm_draw_cursor (xw);
  923.           }
  924.       }
  925.       }
  926.   }
  927.   PRIMITIVE_RETURN (UNSPECIFIC);
  928. }
  929.  
  930. DEFINE_PRIMITIVE ("XTERM-SAVE-CONTENTS", Prim_xterm_save_contents, 5, 5,
  931.   "(XTERM-SAVE-CONTENTS XW X-START X-END Y-START Y-END)\n\
  932. Get the contents of the terminal screen rectangle as a string.\n\
  933. The string contains alternating (CHARACTER, HIGHLIGHT) pairs.\n\
  934. The pairs are organized in row-major order from (X-START, Y-START).")
  935. {
  936.   PRIMITIVE_HEADER (5);
  937.   {
  938.     struct xwindow * xw = (x_window_arg (1));
  939.     unsigned int x_end
  940.       = (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  941.     unsigned int y_end
  942.       = (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  943.     unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
  944.     unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
  945.     unsigned int x_length = (x_end - x_start);
  946.     unsigned int string_length = (2 * x_length * (y_end - y_start));
  947.     SCHEME_OBJECT string = (allocate_string (string_length));
  948.     if (string_length > 0)
  949.       {
  950.     char * string_scan = ((char *) (STRING_LOC (string, 0)));
  951.     unsigned int y;
  952.     for (y = y_start; (y < y_end); y += 1)
  953.       {
  954.         unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
  955.         char * char_scan = (XTERM_CHAR_LOC (xw, index));
  956.         char * char_end = (char_scan + x_length);
  957.         char * hl_scan = (XTERM_HL_LOC (xw, index));
  958.         while (char_scan < char_end)
  959.           {
  960.         (*string_scan++) = (*char_scan++);
  961.         (*string_scan++) = (*hl_scan++);
  962.           }
  963.       }
  964.       }
  965.     PRIMITIVE_RETURN (string);
  966.   }
  967. }
  968.  
  969. DEFINE_PRIMITIVE ("XTERM-RESTORE-CONTENTS", Prim_xterm_restore_contents, 6, 6,
  970.   "(xterm-restore-contents xterm x-start x-end y-start y-end contents)\n\
  971. Replace the terminal screen rectangle with CONTENTS.\n\
  972. See `XTERM-SCREEN-CONTENTS' for the format of CONTENTS.")
  973. {
  974.   PRIMITIVE_HEADER (6);
  975.   CHECK_ARG (6, STRING_P);
  976.   {
  977.     struct xwindow * xw = (x_window_arg (1));
  978.     unsigned int x_end
  979.       = (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  980.     unsigned int y_end
  981.       = (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  982.     unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
  983.     unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
  984.     unsigned int x_length = (x_end - x_start);
  985.     unsigned int string_length = (2 * x_length * (y_end - y_start));
  986.     SCHEME_OBJECT string = (ARG_REF (6));
  987.     if ((STRING_LENGTH (string)) != string_length)
  988.       error_bad_range_arg (6);
  989.     if (string_length > 0)
  990.       {
  991.     char * string_scan = ((char *) (STRING_LOC (string, 0)));
  992.     unsigned int y;
  993.     for (y = y_start; (y < y_end); y += 1)
  994.       {
  995.         unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
  996.         char * char_scan = (XTERM_CHAR_LOC (xw, index));
  997.         char * char_end = (char_scan + x_length);
  998.         char * hl_scan = (XTERM_HL_LOC (xw, index));
  999.         while (char_scan < char_end)
  1000.           {
  1001.         (*char_scan++) = (*string_scan++);
  1002.         (*hl_scan++) = (*string_scan++);
  1003.           }
  1004.       }
  1005.     xterm_dump_contents (xw, x_start, x_end, y_start, y_end);
  1006.       }
  1007.   }
  1008.   PRIMITIVE_RETURN (UNSPECIFIC);
  1009. }
  1010.