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 >
Wrap
C/C++ Source or Header
|
2000-09-30
|
32KB
|
1,010 lines
/* -*-C-*-
$Id: x11term.c,v 1.27 2000/10/01 02:14:14 cph Exp $
Copyright (c) 1989-2000 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* X11 terminal for Edwin. */
#include "scheme.h"
#include "prims.h"
#include "x11.h"
struct xterm_extra
{
/* Dimensions of the window, in characters. Valid character
coordinates are nonnegative integers strictly less than these
limits. */
unsigned int x_size;
unsigned int y_size;
/* Position of the cursor, in character coordinates. */
unsigned int cursor_x;
unsigned int cursor_y;
/* Character map of the window's contents. See `XTERM_CHAR_LOC' for
the address arithmetic. */
char * character_map;
/* Bit map of the window's highlighting. */
char * highlight_map;
/* Nonzero iff the cursor is drawn on the window. */
char cursor_visible_p;
/* Nonzero iff the cursor should be drawn on the window. */
char cursor_enabled_p;
};
#define XW_EXTRA(xw) ((struct xterm_extra *) ((xw) -> extra))
#define XW_X_CSIZE(xw) ((XW_EXTRA (xw)) -> x_size)
#define XW_Y_CSIZE(xw) ((XW_EXTRA (xw)) -> y_size)
#define XW_CURSOR_X(xw) ((XW_EXTRA (xw)) -> cursor_x)
#define XW_CURSOR_Y(xw) ((XW_EXTRA (xw)) -> cursor_y)
#define XW_CHARACTER_MAP(xw) ((XW_EXTRA (xw)) -> character_map)
#define XW_HIGHLIGHT_MAP(xw) ((XW_EXTRA (xw)) -> highlight_map)
#define XW_CURSOR_VISIBLE_P(xw) ((XW_EXTRA (xw)) -> cursor_visible_p)
#define XW_CURSOR_ENABLED_P(xw) ((XW_EXTRA (xw)) -> cursor_enabled_p)
#define XTERM_CHAR_INDEX(xw, x, y) (((y) * (XW_X_CSIZE (xw))) + (x))
#define XTERM_CHAR_LOC(xw, index) ((XW_CHARACTER_MAP (xw)) + (index))
#define XTERM_CHAR(xw, index) (* (XTERM_CHAR_LOC (xw, index)))
#define XTERM_HL_LOC(xw, index) ((XW_HIGHLIGHT_MAP (xw)) + (index))
#define XTERM_HL(xw, index) (* (XTERM_HL_LOC (xw, index)))
#define XTERM_HL_GC(xw, hl) (hl ? (XW_REVERSE_GC (xw)) : (XW_NORMAL_GC (xw)))
#define HL_ARG(arg) arg_index_integer (arg, 2)
#define RESOURCE_NAME "schemeTerminal"
#define RESOURCE_CLASS "SchemeTerminal"
#define DEFAULT_GEOMETRY "80x40+0+0"
#define BLANK_CHAR ' '
#define DEFAULT_HL 0
#define XTERM_X_PIXEL(xw, x) \
(((x) * (FONT_WIDTH (XW_FONT (xw)))) + (XW_INTERNAL_BORDER_WIDTH (xw)))
#define XTERM_Y_PIXEL(xw, y) \
(((y) * (FONT_HEIGHT (XW_FONT (xw)))) + (XW_INTERNAL_BORDER_WIDTH (xw)))
#define XTERM_DRAW_CHARS(xw, x, y, s, n, gc) \
XDrawImageString \
((XW_DISPLAY (xw)), \
(XW_WINDOW (xw)), \
gc, \
(XTERM_X_PIXEL (xw, x)), \
((XTERM_Y_PIXEL (xw, y)) + (FONT_BASE (XW_FONT (xw)))), \
s, \
n)
#define CURSOR_IN_RECTANGLE(xw, x_start, x_end, y_start, y_end) \
(((x_start) <= (XW_CURSOR_X (xw))) \
&& ((XW_CURSOR_X (xw)) < (x_end)) \
&& ((y_start) <= (XW_CURSOR_Y (xw))) \
&& ((XW_CURSOR_Y (xw)) < (y_end)))
static void
DEFUN (xterm_erase_cursor, (xw), struct xwindow * xw)
{
if (XW_CURSOR_VISIBLE_P (xw))
{
unsigned int x = (XW_CURSOR_X (xw));
unsigned int y = (XW_CURSOR_Y (xw));
unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
XTERM_DRAW_CHARS
(xw, x, y,
(XTERM_CHAR_LOC (xw, index)),
1,
(XTERM_HL_GC (xw, (XTERM_HL (xw, index)))));
(XW_CURSOR_VISIBLE_P (xw)) = 0;
}
}
static void
DEFUN (xterm_draw_cursor, (xw), struct xwindow * xw)
{
if ((XW_CURSOR_ENABLED_P (xw)) && (! (XW_CURSOR_VISIBLE_P (xw))))
{
unsigned int x = (XW_CURSOR_X (xw));
unsigned int y = (XW_CURSOR_Y (xw));
unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
int hl = (XTERM_HL (xw, index));
XTERM_DRAW_CHARS
(xw, x, y,
(XTERM_CHAR_LOC (xw, index)),
1,
((hl && ((XW_FOREGROUND_PIXEL (xw)) == (XW_CURSOR_PIXEL (xw))))
? (XW_NORMAL_GC (xw))
: (XW_CURSOR_GC (xw))));
(XW_CURSOR_VISIBLE_P (xw)) = 1;
}
}
static void
DEFUN (xterm_process_event, (xw, event),
struct xwindow * xw AND
XEvent * event)
{
}
static XSizeHints *
DEFUN (xterm_make_size_hints, (font, extra),
XFontStruct * font AND
unsigned int extra)
{
XSizeHints * size_hints = (XAllocSizeHints ());
if (size_hints == 0)
error_external_return ();
(size_hints -> flags) = (PResizeInc | PMinSize | PBaseSize);
(size_hints -> width_inc) = (FONT_WIDTH (font));
(size_hints -> height_inc) = (FONT_HEIGHT (font));
(size_hints -> min_width) = extra;
(size_hints -> min_height) = extra;
(size_hints -> base_width) = extra;
(size_hints -> base_height) = extra;
return (size_hints);
}
static void
DEFUN (xterm_set_wm_normal_hints, (xw, size_hints, geometry_mask, x, y),
struct xwindow * xw AND
XSizeHints * size_hints AND
int geometry_mask AND
unsigned int x AND
unsigned int y)
{
(size_hints -> flags) |=
((((geometry_mask & XValue) && (geometry_mask & YValue))
? USPosition : PPosition)
| (((geometry_mask & WidthValue) && (geometry_mask & HeightValue))
? USSize : PSize));
(size_hints -> x) = x;
(size_hints -> y) = y;
(size_hints -> width) =
(((XW_X_CSIZE (xw)) * (size_hints -> width_inc))
+ (size_hints -> base_width));
(size_hints -> height) =
(((XW_Y_CSIZE (xw)) * (size_hints -> height_inc))
+ (size_hints -> base_height));
XSetWMNormalHints ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), size_hints);
XFree ((caddr_t) size_hints);
}
static void
DEFUN (xterm_update_normal_hints, (xw), struct xwindow * xw)
{
xterm_set_wm_normal_hints
(xw,
(xterm_make_size_hints
((XW_FONT (xw)),
(2 * (XW_INTERNAL_BORDER_WIDTH (xw))))),
0, 0, 0);
}
static void
DEFUN (xterm_deallocate, (xw), struct xwindow * xw)
{
free (XW_CHARACTER_MAP (xw));
free (XW_HIGHLIGHT_MAP (xw));
}
static SCHEME_OBJECT
DEFUN (xterm_x_coordinate_map, (xw, x), struct xwindow * xw AND unsigned int x)
{
return (ulong_to_integer (x / (FONT_WIDTH (XW_FONT (xw)))));
}
static SCHEME_OBJECT
DEFUN (xterm_y_coordinate_map, (xw, y), struct xwindow * xw AND unsigned int y)
{
return (ulong_to_integer (y / (FONT_HEIGHT (XW_FONT (xw)))));
}
static void
DEFUN (xterm_copy_map_line, (xw, x_start, x_end, y_from, y_to),
struct xwindow * xw AND
unsigned int x_start AND
unsigned int x_end AND
unsigned int y_from AND
unsigned int y_to)
{
{
char * from_scan =
(XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_from))));
char * from_end =
(XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_end, y_from))));
char * to_scan =
(XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_to))));
while (from_scan < from_end)
(*to_scan++) = (*from_scan++);
}
{
char * from_scan =
(XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_from))));
char * from_end =
(XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_end, y_from))));
char * to_scan =
(XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_to))));
while (from_scan < from_end)
(*to_scan++) = (*from_scan++);
}
}
static void
DEFUN (xterm_dump_contents, (xw, x_start, x_end, y_start, y_end),
struct xwindow * xw AND
unsigned int x_start AND
unsigned int x_end AND
unsigned int y_start AND
unsigned int y_end)
{
char * character_map = (XW_CHARACTER_MAP (xw));
char * highlight_map = (XW_HIGHLIGHT_MAP (xw));
if (x_start < x_end)
{
unsigned int yi;
for (yi = y_start; (yi < y_end); yi += 1)
{
unsigned int index = (XTERM_CHAR_INDEX (xw, 0, yi));
char * line_char = (&character_map[index]);
char * line_hl = (&highlight_map[index]);
unsigned int xi = x_start;
while (1)
{
unsigned int hl = (line_hl[xi]);
unsigned int xj = (xi + 1);
while ((xj < x_end) && ((line_hl[xj]) == hl))
xj += 1;
XTERM_DRAW_CHARS (xw, xi, yi,
(&line_char[xi]),
(xj - xi),
(XTERM_HL_GC (xw, hl)));
if (xj == x_end)
break;
xi = xj;
}
}
if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, y_end))
{
(XW_CURSOR_VISIBLE_P (xw)) = 0;
xterm_draw_cursor (xw);
}
}
}
static void
DEFUN (xterm_dump_rectangle, (xw, x, y, width, height),
struct xwindow * xw AND
unsigned int x AND
unsigned int y AND
unsigned int width AND
unsigned int height)
{
XFontStruct * font = (XW_FONT (xw));
unsigned int fwidth = (FONT_WIDTH (font));
unsigned int fheight = (FONT_HEIGHT (font));
unsigned int border = (XW_INTERNAL_BORDER_WIDTH (xw));
if (x < border)
{
width -= (border - x);
x = 0;
}
else
x -= border;
if ((x + width) > (XW_X_SIZE (xw)))
width = ((XW_X_SIZE (xw)) - x);
if (y < border)
{
height -= (border - y);
y = 0;
}
else
y -= border;
if ((y + height) > (XW_Y_SIZE (xw)))
height = ((XW_Y_SIZE (xw)) - y);
{
unsigned int x_start = (x / fwidth);
unsigned int x_end = (((x + width) + (fwidth - 1)) / fwidth);
unsigned int y_start = (y / fheight);
unsigned int y_end = (((y + height) + (fheight - 1)) / fheight);
if (x_end > (XW_X_CSIZE (xw)))
x_end = (XW_X_CSIZE (xw));
if (y_end > (XW_Y_CSIZE (xw)))
y_end = (XW_Y_CSIZE (xw));
xterm_dump_contents (xw, x_start, x_end, y_start, y_end);
}
XFlush (XW_DISPLAY (xw));
}
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
static void
DEFUN (xterm_reconfigure, (xw, width, height),
struct xwindow * xw AND
unsigned int width AND
unsigned int height)
{
unsigned int extra = (2 * (XW_INTERNAL_BORDER_WIDTH (xw)));
unsigned int x_size = ((width < extra) ? 0 : (width - extra));
unsigned int y_size = ((height < extra) ? 0 : (height - extra));
if ((x_size != (XW_X_SIZE (xw))) || (y_size != (XW_Y_SIZE (xw))))
{
unsigned int x_csize = (x_size / (FONT_WIDTH (XW_FONT (xw))));
unsigned int y_csize = (y_size / (FONT_HEIGHT (XW_FONT (xw))));
char * new_char_map = (x_malloc (x_csize * y_csize));
char * new_hl_map = (x_malloc (x_csize * y_csize));
unsigned int old_x_csize = (XW_X_CSIZE (xw));
unsigned int min_x_csize = (MIN (x_csize, old_x_csize));
unsigned int min_y_csize = (MIN (y_csize, (XW_Y_CSIZE (xw))));
int x_clipped = (old_x_csize - x_csize);
char * new_scan_char = new_char_map;
char * new_scan_hl = new_hl_map;
char * new_end;
char * old_scan_char = (XW_CHARACTER_MAP (xw));
char * old_scan_hl = (XW_HIGHLIGHT_MAP (xw));
char * old_end;
unsigned int new_y = 0;
for (; (new_y < min_y_csize); new_y += 1)
{
old_end = (old_scan_char + min_x_csize);
while (old_scan_char < old_end)
{
(*new_scan_char++) = (*old_scan_char++);
(*new_scan_hl++) = (*old_scan_hl++);
}
if (x_clipped < 0)
{
new_end = (new_scan_char + ((unsigned int) (- x_clipped)));
while (new_scan_char < new_end)
{
(*new_scan_char++) = BLANK_CHAR;
(*new_scan_hl++) = DEFAULT_HL;
}
}
else if (x_clipped > 0)
{
old_scan_char += ((unsigned int) x_clipped);
old_scan_hl += ((unsigned int) x_clipped);
}
}
for (; (new_y < y_csize); new_y += 1)
{
new_end = (new_scan_char + x_csize);
while (new_scan_char < new_end)
{
(*new_scan_char++) = BLANK_CHAR;
(*new_scan_hl++) = DEFAULT_HL;
}
}
free (XW_CHARACTER_MAP (xw));
free (XW_HIGHLIGHT_MAP (xw));
(XW_X_SIZE (xw)) = x_size;
(XW_Y_SIZE (xw)) = y_size;
(XW_CLIP_X (xw)) = 0;
(XW_CLIP_Y (xw)) = 0;
(XW_CLIP_WIDTH (xw)) = x_size;
(XW_CLIP_HEIGHT (xw)) = y_size;
(XW_X_CSIZE (xw)) = x_csize;
(XW_Y_CSIZE (xw)) = y_csize;
(XW_CHARACTER_MAP (xw))= new_char_map;
(XW_HIGHLIGHT_MAP (xw))= new_hl_map;
XClearWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
xterm_dump_contents (xw, 0, 0, x_csize, y_csize);
xterm_update_normal_hints (xw);
XFlush (XW_DISPLAY (xw));
}
}
DEFINE_PRIMITIVE ("XTERM-RECONFIGURE", Prim_xterm_reconfigure, 3, 3, 0)
{
PRIMITIVE_HEADER (3);
xterm_reconfigure ((x_window_arg (1)),
(arg_ulong_integer (2)),
(arg_ulong_integer (3)));
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-DUMP-RECTANGLE", Prim_xterm_dump_rectangle, 5, 5, 0)
{
PRIMITIVE_HEADER (5);
xterm_dump_rectangle ((x_window_arg (1)),
(arg_ulong_integer (2)),
(arg_ulong_integer (3)),
(arg_ulong_integer (4)),
(arg_ulong_integer (5)));
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-MAP-X-COORDINATE", Prim_xterm_map_x_coordinate, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int xp = (arg_ulong_integer (2));
int bx = (xp - (XW_INTERNAL_BORDER_WIDTH (xw)));
PRIMITIVE_RETURN
(long_to_integer
(((bx < 0) ? 0
: (bx >= (XW_X_SIZE (xw))) ? ((XW_X_SIZE (xw)) - 1)
: bx)
/ (FONT_WIDTH (XW_FONT (xw)))));
}
}
DEFINE_PRIMITIVE ("XTERM-MAP-Y-COORDINATE", Prim_xterm_map_y_coordinate, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int yp = (arg_ulong_integer (2));
int by = (yp - (XW_INTERNAL_BORDER_WIDTH (xw)));
PRIMITIVE_RETURN
(long_to_integer
(((by < 0) ? 0
: (by >= (XW_Y_SIZE (xw))) ? ((XW_Y_SIZE (xw)) - 1)
: by)
/ (FONT_HEIGHT (XW_FONT (xw)))));
}
}
DEFINE_PRIMITIVE ("XTERM-MAP-X-SIZE", Prim_xterm_map_x_size, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
{
struct xwindow * xw = (x_window_arg (1));
int width =
((arg_nonnegative_integer (2)) - (2 * (XW_INTERNAL_BORDER_WIDTH (xw))));
PRIMITIVE_RETURN
(ulong_to_integer
((width < 0) ? 0 : (width / (FONT_WIDTH (XW_FONT (xw))))));
}
}
DEFINE_PRIMITIVE ("XTERM-MAP-Y-SIZE", Prim_xterm_map_y_size, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
{
struct xwindow * xw = (x_window_arg (1));
int height =
((arg_nonnegative_integer (2)) - (2 * (XW_INTERNAL_BORDER_WIDTH (xw))));
PRIMITIVE_RETURN
(ulong_to_integer
((height < 0) ? 0 : (height / (FONT_HEIGHT (XW_FONT (xw))))));
}
}
DEFINE_PRIMITIVE ("XTERM-OPEN-WINDOW", Prim_xterm_open_window, 3, 3, 0)
{
PRIMITIVE_HEADER (3);
{
struct xdisplay * xd = (x_display_arg (1));
Display * display = (XD_DISPLAY (xd));
struct drawing_attributes attributes;
struct xwindow_methods methods;
CONST char * resource_name = RESOURCE_NAME;
CONST char * resource_class = RESOURCE_CLASS;
int map_p;
x_decode_window_map_arg
((ARG_REF (3)), (&resource_name), (&resource_class), (&map_p));
x_default_attributes
(display, resource_name, resource_class, (&attributes));
(methods . deallocator) = xterm_deallocate;
(methods . event_processor) = xterm_process_event;
(methods . x_coordinate_map) = xterm_x_coordinate_map;
(methods . y_coordinate_map) = xterm_y_coordinate_map;
(methods . update_normal_hints) = xterm_update_normal_hints;
{
unsigned int extra = (2 * (attributes . internal_border_width));
int x_pos;
int y_pos;
int x_size;
int y_size;
XSizeHints * size_hints =
(xterm_make_size_hints ((attributes . font), extra));
int geometry_mask =
(XWMGeometry
(display,
(DefaultScreen (display)),
(((ARG_REF (2)) == SHARP_F)
? (x_get_default
(display, resource_name, resource_class,
"geometry", "Geometry", 0))
: (STRING_ARG (2))),
DEFAULT_GEOMETRY,
(attributes . border_width),
size_hints,
(&x_pos), (&y_pos), (&x_size), (&y_size),
(& (size_hints -> win_gravity))));
unsigned int x_csize =
((x_size - (size_hints -> base_width)) / (size_hints -> width_inc));
unsigned int y_csize =
((y_size - (size_hints -> base_height)) / (size_hints -> height_inc));
Window window =
(XCreateSimpleWindow
(display, (RootWindow (display, (DefaultScreen (display)))),
x_pos, y_pos, x_size, y_size,
(attributes . border_width),
(attributes . border_pixel),
(attributes . background_pixel)));
if (window == 0)
error_external_return ();
{
struct xwindow * xw =
(x_make_window
(xd,
window,
(x_size - (size_hints -> base_width)),
(y_size - (size_hints -> base_height)),
(&attributes),
(&methods),
(sizeof (struct xterm_extra))));
unsigned int map_size = (x_csize * y_csize);
(XW_X_CSIZE (xw)) = x_csize;
(XW_Y_CSIZE (xw)) = y_csize;
(XW_CURSOR_X (xw)) = 0;
(XW_CURSOR_Y (xw)) = 0;
(XW_CURSOR_VISIBLE_P (xw)) = 0;
(XW_CURSOR_ENABLED_P (xw)) = 1;
{
char * scan = (x_malloc (map_size));
char * end = (scan + map_size);
(XW_CHARACTER_MAP (xw)) = scan;
while (scan < end)
(*scan++) = BLANK_CHAR;
}
{
char * scan = (x_malloc (map_size));
char * end = (scan + map_size);
(XW_HIGHLIGHT_MAP (xw)) = scan;
while (scan < end)
(*scan++) = DEFAULT_HL;
}
(size_hints -> flags) |= PWinGravity;
xterm_set_wm_normal_hints
(xw, size_hints, geometry_mask, x_pos, y_pos);
xw_set_wm_input_hint (xw, 1);
xw_set_wm_name (xw, "scheme-terminal");
xw_set_wm_icon_name (xw, "scheme-terminal");
xw_make_window_map (xw, resource_name, resource_class, map_p);
PRIMITIVE_RETURN (XW_TO_OBJECT (xw));
}
}
}
}
DEFINE_PRIMITIVE ("XTERM-X-SIZE", Prim_xterm_x_size, 1, 1, 0)
{
PRIMITIVE_HEADER (1);
PRIMITIVE_RETURN (ulong_to_integer (XW_X_CSIZE (x_window_arg (1))));
}
DEFINE_PRIMITIVE ("XTERM-Y-SIZE", Prim_xterm_y_size, 1, 1, 0)
{
PRIMITIVE_HEADER (1);
PRIMITIVE_RETURN (ulong_to_integer (XW_Y_CSIZE (x_window_arg (1))));
}
DEFINE_PRIMITIVE ("XTERM-SET-SIZE", Prim_xterm_set_size, 3, 3, 0)
{
struct xwindow * xw;
int extra;
XFontStruct * font;
PRIMITIVE_HEADER (3);
xw = (x_window_arg (1));
extra = (2 * (XW_INTERNAL_BORDER_WIDTH (xw)));
font = (XW_FONT (xw));
XResizeWindow
((XW_DISPLAY (xw)),
(XW_WINDOW (xw)),
(((arg_ulong_integer (2)) * (FONT_WIDTH (font))) + extra),
(((arg_ulong_integer (3)) * (FONT_HEIGHT (font))) + extra));
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-ENABLE-CURSOR", Prim_xterm_enable_cursor, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
(XW_CURSOR_ENABLED_P (x_window_arg (1))) = (BOOLEAN_ARG (2));
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-ERASE-CURSOR", Prim_xterm_erase_cursor, 1, 1, 0)
{
PRIMITIVE_HEADER (1);
xterm_erase_cursor (x_window_arg (1));
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-DRAW-CURSOR", Prim_xterm_draw_cursor, 1, 1, 0)
{
PRIMITIVE_HEADER (1);
xterm_draw_cursor (x_window_arg (1));
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-WRITE-CURSOR!", Prim_xterm_write_cursor, 3, 3, 0)
{
PRIMITIVE_HEADER (3);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x = (arg_ulong_index_integer (2, (XW_X_CSIZE (xw))));
unsigned int y = (arg_ulong_index_integer (3, (XW_Y_CSIZE (xw))));
if ((x != (XW_CURSOR_X (xw))) || (y != (XW_CURSOR_Y (xw))))
{
xterm_erase_cursor (xw);
(XW_CURSOR_X (xw)) = x;
(XW_CURSOR_Y (xw)) = y;
}
xterm_draw_cursor (xw);
}
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-WRITE-CHAR!", Prim_xterm_write_char, 5, 5, 0)
{
PRIMITIVE_HEADER (5);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x = (arg_ulong_index_integer (2, (XW_X_CSIZE (xw))));
unsigned int y = (arg_ulong_index_integer (3, (XW_Y_CSIZE (xw))));
int c = (arg_ascii_char (4));
unsigned int hl = (HL_ARG (5));
unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
char * map_ptr = (XTERM_CHAR_LOC (xw, index));
(*map_ptr) = c;
(XTERM_HL (xw, index)) = hl;
XTERM_DRAW_CHARS (xw, x, y, map_ptr, 1, (XTERM_HL_GC (xw, hl)));
if (((XW_CURSOR_X (xw)) == x) && ((XW_CURSOR_Y (xw)) == y))
{
(XW_CURSOR_VISIBLE_P (xw)) = 0;
xterm_draw_cursor (xw);
}
}
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-WRITE-SUBSTRING!", Prim_xterm_write_substring, 7, 7, 0)
{
PRIMITIVE_HEADER (7);
CHECK_ARG (4, STRING_P);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x = (arg_ulong_index_integer (2, (XW_X_CSIZE (xw))));
unsigned int y = (arg_ulong_index_integer (3, (XW_Y_CSIZE (xw))));
SCHEME_OBJECT string = (ARG_REF (4));
unsigned int end
= (arg_ulong_index_integer (6, ((STRING_LENGTH (string)) + 1)));
unsigned int start = (arg_ulong_index_integer (5, (end + 1)));
unsigned int hl = (HL_ARG (7));
unsigned int length = (end - start);
unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
if ((x + length) > (XW_X_CSIZE (xw)))
error_bad_range_arg (2);
{
unsigned char * string_scan = (STRING_LOC (string, start));
unsigned char * string_end = (STRING_LOC (string, end));
char * char_scan = (XTERM_CHAR_LOC (xw, index));
char * hl_scan = (XTERM_HL_LOC (xw, index));
while (string_scan < string_end)
{
(*char_scan++) = (*string_scan++);
(*hl_scan++) = hl;
}
}
XTERM_DRAW_CHARS
(xw, x, y, (XTERM_CHAR_LOC (xw, index)), length, (XTERM_HL_GC (xw, hl)));
if ((x <= (XW_CURSOR_X (xw))) && ((XW_CURSOR_X (xw)) < (x + length))
&& (y == (XW_CURSOR_Y (xw))))
{
(XW_CURSOR_VISIBLE_P (xw)) = 0;
xterm_draw_cursor (xw);
}
}
PRIMITIVE_RETURN (UNSPECIFIC);
}
static void
DEFUN (xterm_clear_rectangle, (xw, x_start, x_end, y_start, y_end, hl),
struct xwindow * xw AND
unsigned int x_start AND
unsigned int x_end AND
unsigned int y_start AND
unsigned int y_end AND
unsigned int hl)
{
unsigned int x_length = (x_end - x_start);
unsigned int y;
for (y = y_start; (y < y_end); y += 1)
{
unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
{
char * scan = (XTERM_CHAR_LOC (xw, index));
char * end = (scan + x_length);
while (scan < end)
(*scan++) = BLANK_CHAR;
}
{
char * scan = (XTERM_HL_LOC (xw, index));
char * end = (scan + x_length);
while (scan < end)
(*scan++) = hl;
}
}
if (hl != 0)
{
GC hl_gc = (XTERM_HL_GC (xw, hl));
for (y = y_start; (y < y_end); y += 1)
XTERM_DRAW_CHARS
(xw, x_start, y,
(XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y)))),
x_length, hl_gc);
}
else if ((x_start == 0)
&& (y_start == 0)
&& (x_end == (XW_X_CSIZE (xw)))
&& (y_end == (XW_Y_CSIZE (xw))))
XClearWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
else
XClearArea ((XW_DISPLAY (xw)),
(XW_WINDOW (xw)),
(XTERM_X_PIXEL (xw, x_start)),
(XTERM_Y_PIXEL (xw, y_start)),
(x_length * (FONT_WIDTH (XW_FONT (xw)))),
((y_end - y_start) * (FONT_HEIGHT (XW_FONT (xw)))),
False);
}
DEFINE_PRIMITIVE ("XTERM-CLEAR-RECTANGLE!", Prim_xterm_clear_rectangle, 6, 6, 0)
{
PRIMITIVE_HEADER (6);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x_end
= (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
unsigned int y_end
= (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
unsigned int hl = (HL_ARG (6));
if ((x_start < x_end) && (y_start < y_end))
{
xterm_clear_rectangle (xw, x_start, x_end, y_start, y_end, hl);
if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, y_end))
{
(XW_CURSOR_VISIBLE_P (xw)) = 0;
xterm_draw_cursor (xw);
}
}
}
PRIMITIVE_RETURN (UNSPECIFIC);
}
static void
DEFUN (xterm_scroll_lines_up, (xw, x_start, x_end, y_start, y_end, lines),
struct xwindow * xw AND
unsigned int x_start AND
unsigned int x_end AND
unsigned int y_start AND
unsigned int y_end AND
unsigned int lines)
{
{
unsigned int y_to = y_start;
unsigned int y_from = (y_to + lines);
while (y_from < y_end)
xterm_copy_map_line (xw, x_start, x_end, (y_from++), (y_to++));
}
XCopyArea ((XW_DISPLAY (xw)),
(XW_WINDOW (xw)),
(XW_WINDOW (xw)),
(XW_NORMAL_GC (xw)),
(XTERM_X_PIXEL (xw, x_start)),
(XTERM_Y_PIXEL (xw, (y_start + lines))),
((x_end - x_start) * (FONT_WIDTH (XW_FONT (xw)))),
(((y_end - y_start) - lines) * (FONT_HEIGHT (XW_FONT (xw)))),
(XTERM_X_PIXEL (xw, x_start)),
(XTERM_Y_PIXEL (xw, y_start)));
}
DEFINE_PRIMITIVE ("XTERM-SCROLL-LINES-UP", Prim_xterm_scroll_lines_up, 6, 6,
"(XTERM-SCROLL-LINES-UP XTERM X-START X-END Y-START Y-END LINES)\n\
Scroll the contents of the region up by LINES.")
{
PRIMITIVE_HEADER (6);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x_end
= (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
unsigned int y_end
= (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
unsigned int lines = (arg_ulong_index_integer (6, (y_end - y_start)));
if ((0 < lines) && (x_start < x_end) && (y_start < y_end))
{
if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, (y_start + lines), y_end))
{
xterm_erase_cursor (xw);
xterm_scroll_lines_up (xw, x_start, x_end, y_start, y_end, lines);
xterm_draw_cursor (xw);
}
else
{
xterm_scroll_lines_up (xw, x_start, x_end, y_start, y_end, lines);
if (CURSOR_IN_RECTANGLE
(xw, x_start, x_end, y_start, (y_end - lines)))
{
(XW_CURSOR_VISIBLE_P (xw)) = 0;
xterm_draw_cursor (xw);
}
}
}
}
PRIMITIVE_RETURN (UNSPECIFIC);
}
static void
DEFUN (xterm_scroll_lines_down, (xw, x_start, x_end, y_start, y_end, lines),
struct xwindow * xw AND
unsigned int x_start AND
unsigned int x_end AND
unsigned int y_start AND
unsigned int y_end AND
unsigned int lines)
{
{
unsigned int y_to = y_end;
unsigned int y_from = (y_to - lines);
while (y_from > y_start)
xterm_copy_map_line (xw, x_start, x_end, (--y_from), (--y_to));
}
XCopyArea ((XW_DISPLAY (xw)),
(XW_WINDOW (xw)),
(XW_WINDOW (xw)),
(XW_NORMAL_GC (xw)),
(XTERM_X_PIXEL (xw, x_start)),
(XTERM_Y_PIXEL (xw, y_start)),
((x_end - x_start) * (FONT_WIDTH (XW_FONT (xw)))),
(((y_end - y_start) - lines) * (FONT_HEIGHT (XW_FONT (xw)))),
(XTERM_X_PIXEL (xw, x_start)),
(XTERM_Y_PIXEL (xw, (y_start + lines))));
}
DEFINE_PRIMITIVE ("XTERM-SCROLL-LINES-DOWN", Prim_xterm_scroll_lines_down, 6, 6,
"(XTERM-SCROLL-LINES-DOWN XTERM X-START X-END Y-START Y-END LINES)\n\
Scroll the contents of the region down by LINES.")
{
PRIMITIVE_HEADER (6);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x_end
= (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
unsigned int y_end
= (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
unsigned int lines = (arg_ulong_index_integer (6, (y_end - y_start)));
if ((0 < lines) && (x_start < x_end) && (y_start < y_end))
{
if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, (y_end - lines)))
{
xterm_erase_cursor (xw);
xterm_scroll_lines_down
(xw, x_start, x_end, y_start, y_end, lines);
xterm_draw_cursor (xw);
}
else
{
xterm_scroll_lines_down
(xw, x_start, x_end, y_start, y_end, lines);
if (CURSOR_IN_RECTANGLE
(xw, x_start, x_end, (y_start + lines), y_end))
{
(XW_CURSOR_VISIBLE_P (xw)) = 0;
xterm_draw_cursor (xw);
}
}
}
}
PRIMITIVE_RETURN (UNSPECIFIC);
}
DEFINE_PRIMITIVE ("XTERM-SAVE-CONTENTS", Prim_xterm_save_contents, 5, 5,
"(XTERM-SAVE-CONTENTS XW X-START X-END Y-START Y-END)\n\
Get the contents of the terminal screen rectangle as a string.\n\
The string contains alternating (CHARACTER, HIGHLIGHT) pairs.\n\
The pairs are organized in row-major order from (X-START, Y-START).")
{
PRIMITIVE_HEADER (5);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x_end
= (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
unsigned int y_end
= (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
unsigned int x_length = (x_end - x_start);
unsigned int string_length = (2 * x_length * (y_end - y_start));
SCHEME_OBJECT string = (allocate_string (string_length));
if (string_length > 0)
{
char * string_scan = ((char *) (STRING_LOC (string, 0)));
unsigned int y;
for (y = y_start; (y < y_end); y += 1)
{
unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
char * char_scan = (XTERM_CHAR_LOC (xw, index));
char * char_end = (char_scan + x_length);
char * hl_scan = (XTERM_HL_LOC (xw, index));
while (char_scan < char_end)
{
(*string_scan++) = (*char_scan++);
(*string_scan++) = (*hl_scan++);
}
}
}
PRIMITIVE_RETURN (string);
}
}
DEFINE_PRIMITIVE ("XTERM-RESTORE-CONTENTS", Prim_xterm_restore_contents, 6, 6,
"(xterm-restore-contents xterm x-start x-end y-start y-end contents)\n\
Replace the terminal screen rectangle with CONTENTS.\n\
See `XTERM-SCREEN-CONTENTS' for the format of CONTENTS.")
{
PRIMITIVE_HEADER (6);
CHECK_ARG (6, STRING_P);
{
struct xwindow * xw = (x_window_arg (1));
unsigned int x_end
= (arg_ulong_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
unsigned int y_end
= (arg_ulong_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
unsigned int x_start = (arg_ulong_index_integer (2, (x_end + 1)));
unsigned int y_start = (arg_ulong_index_integer (4, (y_end + 1)));
unsigned int x_length = (x_end - x_start);
unsigned int string_length = (2 * x_length * (y_end - y_start));
SCHEME_OBJECT string = (ARG_REF (6));
if ((STRING_LENGTH (string)) != string_length)
error_bad_range_arg (6);
if (string_length > 0)
{
char * string_scan = ((char *) (STRING_LOC (string, 0)));
unsigned int y;
for (y = y_start; (y < y_end); y += 1)
{
unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
char * char_scan = (XTERM_CHAR_LOC (xw, index));
char * char_end = (char_scan + x_length);
char * hl_scan = (XTERM_HL_LOC (xw, index));
while (char_scan < char_end)
{
(*char_scan++) = (*string_scan++);
(*hl_scan++) = (*string_scan++);
}
}
xterm_dump_contents (xw, x_start, x_end, y_start, y_end);
}
}
PRIMITIVE_RETURN (UNSPECIFIC);
}