Merged term-autowrap branch

master
Yevgen Muntyan 2005-12-03 20:29:23 +00:00
parent 26c760e74b
commit 0fdbf51632
17 changed files with 1159 additions and 118 deletions

View File

@ -36,7 +36,7 @@
<useconfiguration>debug</useconfiguration>
</general>
<run>
<mainprogram>./mterm</mainprogram>
<mainprogram>./medit</mainprogram>
<directoryradio>executable</directoryradio>
<customdirectory>/</customdirectory>
<programargs></programargs>
@ -192,7 +192,7 @@
<abortonerror>true</abortonerror>
<numberofjobs>1</numberofjobs>
<dontact>false</dontact>
<makebin/>
<makebin></makebin>
<prio>0</prio>
</make>
</kdevautoproject>
@ -268,16 +268,16 @@
</kdevdoctreeview>
<kdevfilecreate>
<filetypes>
<type icon="source" ext="g" name="GAP source" create="template" >
<type icon="source" ext="g" create="template" name="GAP source" >
<descr>A new empty GAP source file</descr>
</type>
<type icon="source_cpp" ext="cpp" name="C++ Source" create="template" >
<type icon="source_cpp" ext="cpp" create="template" name="C++ Source" >
<descr>A new empty C++ file.</descr>
</type>
<type icon="source_h" ext="h" name="C/C++ Header" create="template" >
<type icon="source_h" ext="h" create="template" name="C/C++ Header" >
<descr>A new empty header file for C/C++.</descr>
</type>
<type icon="source_c" ext="c" name="C Source" create="template" >
<type icon="source_c" ext="c" create="template" name="C Source" >
<descr>A new empty C file.</descr>
</type>
</filetypes>

View File

@ -354,6 +354,28 @@
;; From mooterm.h
(define-method get_screen_size
(of-object "MooTerm")
(c-name "moo_term_get_screen_size")
(return-type "none")
(parameters
'("guint*" "columns")
'("guint*" "rows")
)
)
(define-method char_height
(of-object "MooTerm")
(c-name "moo_term_char_height")
(return-type "guint")
)
(define-method char_width
(of-object "MooTerm")
(c-name "moo_term_char_width")
(return-type "guint")
)
(define-method set_adjustment
(of-object "MooTerm")
(c-name "moo_term_set_adjustment")

View File

@ -212,3 +212,40 @@ _wrap_moo_term_window_to_buffer_coords (PyGObject *self, PyObject *args)
moo_term_window_to_buffer_coords (MOO_TERM(self->obj), x, y, &buf_x, &buf_y);
return Py_BuildValue((char*) "(ii)", buf_x, buf_y);
}
%%
override moo_term_feed varargs
static PyObject *
_wrap_moo_term_feed (PyGObject *self, PyObject *args)
{
char *string;
int len;
if (!PyArg_ParseTuple (args, (char*) "s#:MooTerm.feed", &string, &len))
return NULL;
moo_term_feed (MOO_TERM (self->obj), string, len);
return_None;
}
%%
override moo_term_feed_child varargs
static PyObject *
_wrap_moo_term_feed_child (PyGObject *self, PyObject *args)
{
char *string;
int len;
if (!PyArg_ParseTuple (args, (char*) "s#:MooTerm.feed_child", &string, &len))
return NULL;
moo_term_feed_child (MOO_TERM (self->obj), string, len);
return_None;
}
%%
override moo_term_get_screen_size noargs
static PyObject *
_wrap_moo_term_get_screen_size (PyGObject *self)
{
guint columns, rows;
moo_term_get_screen_size (MOO_TERM (self->obj), &columns, &rows);
return Py_BuildValue ((char*) "(ii)", columns, rows);
}

View File

@ -316,18 +316,22 @@ _moo_term_cursor_moved (MooTerm *term,
return;
new_row = buf_cursor_row (buf);
new_col = buf_cursor_col (buf);
new_col = buf_cursor_col_display (buf);
if (term->priv->cursor_visible && term->priv->blink_cursor_visible)
if (new_row != (int) term->priv->cursor_row ||
new_col != (int) term->priv->cursor_col)
{
invalidate_screen_cell (term,
term->priv->cursor_row,
term->priv->cursor_col);
invalidate_screen_cell (term, new_row, new_col);
}
if (term->priv->cursor_visible && term->priv->blink_cursor_visible)
{
invalidate_screen_cell (term,
term->priv->cursor_row,
term->priv->cursor_col);
invalidate_screen_cell (term, new_row, new_col);
}
term->priv->cursor_col = new_col;
term->priv->cursor_row = new_row;
term->priv->cursor_col = new_col;
term->priv->cursor_row = new_row;
}
}
@ -568,7 +572,7 @@ term_draw_range (MooTerm *term,
if (term->priv->cursor_visible && term->priv->blink_cursor_visible &&
term->priv->cursor_row + buf_scrollback (term->priv->buffer) == abs_row)
{
guint cursor = buf_cursor_col (term->priv->buffer);
guint cursor = buf_cursor_col_display (term->priv->buffer);
if (cursor >= start && cursor < start + len)
{

View File

@ -93,7 +93,8 @@ struct _MooTermPrivate {
guint cursor_col;
struct {
guint cursor_row, cursor_col;
guint cursor_row, cursor_col; /* these are real cursor coordinates in buffer
(it may be different from what's displayed in AWM mode) */
MooTermTextAttr attr;
int GL, GR;
gboolean autowrap;

View File

@ -1368,7 +1368,7 @@ moo_term_get_iter_at_cursor (MooTerm *term,
g_return_if_fail (iter != NULL);
FILL_ITER (iter, term, buf_cursor_row_abs (term->priv->buffer),
buf_cursor_col (term->priv->buffer));
buf_cursor_col_display (term->priv->buffer));
}

View File

@ -111,13 +111,13 @@ G_STMT_START { \
#define VT_RIS moo_term_reset (parser->term)
#define VT_CBT(n) _moo_term_buffer_back_tab (parser->term->priv->buffer, n)
#define VT_CHA(n) _moo_term_buffer_cursor_move_to (parser->term->priv->buffer, -1, n)
#define VT_CHA(n) _moo_term_buffer_cursor_move_to (parser->term->priv->buffer, -1, (n)-1) /* XXX is it right? */
#define VT_CHT(n) _moo_term_buffer_tab (parser->term->priv->buffer, n)
#define VT_CNL(n) _moo_term_buffer_cursor_next_line (parser->term->priv->buffer, n)
#define VT_CPL(n) _moo_term_buffer_cursor_prev_line (parser->term->priv->buffer, n)
#define VT_HPA(n) _moo_term_buffer_cursor_move_to (parser->term->priv->buffer, -1, n)
#define VT_HPA(n) _moo_term_buffer_cursor_move_to (parser->term->priv->buffer, -1, (n)-1) /* XXX is it right? */
#define VT_HPR(n) _moo_term_buffer_cursor_move (parser->term->priv->buffer, 0, n)
#define VT_VPA(n) _moo_term_buffer_cursor_move_to (parser->term->priv->buffer, n, -1)
#define VT_VPA(n) _moo_term_buffer_cursor_move_to (parser->term->priv->buffer, (n)-1, -1) /* XXX is it right? */
#define VT_VPR(n) _moo_term_buffer_cursor_move (parser->term->priv->buffer, n, 0)
#define VT_DECALN _moo_term_buffer_decaln (parser->term->priv->buffer)

View File

@ -892,6 +892,21 @@ _moo_term_size_changed (MooTerm *term)
}
void
moo_term_get_screen_size (MooTerm *term,
guint *columns,
guint *rows)
{
g_return_if_fail (MOO_IS_TERM (term));
if (rows)
*rows = term->priv->height;
if (columns)
*columns = term->priv->width;
}
gboolean moo_term_fork_command (MooTerm *term,
const MooTermCommand *cmd,
const char *working_dir,
@ -1568,11 +1583,11 @@ _moo_term_dsr (MooTerm *term,
if (extended)
answer = g_strdup_printf (VT_CSI_ "%d;%d;0R",
buf_cursor_row (buf) + 1,
buf_cursor_col (buf) + 1);
buf_cursor_col_real (buf) + 1);
else
answer = g_strdup_printf (VT_CSI_ "%d;%dR",
buf_cursor_row (buf) + 1,
buf_cursor_col (buf) + 1);
buf_cursor_col_real (buf) + 1);
break;
case 75:
answer = g_strdup (VT_CSI_ "?70n");
@ -1666,7 +1681,7 @@ menu_position_func (G_GNUC_UNUSED GtkMenu *menu,
window = GTK_WIDGET(term)->window;
gdk_window_get_origin (window, px, py);
cursor_col = buf_cursor_col (term->priv->buffer);
cursor_col = buf_cursor_col_display (term->priv->buffer);
cursor_row = buf_cursor_row (term->priv->buffer);
cursor_row += buf_scrollback (term->priv->buffer);
@ -2219,3 +2234,21 @@ moo_term_erase_binding_get_type (void)
return type;
}
guint
moo_term_char_height (MooTerm *term)
{
g_return_val_if_fail (MOO_IS_TERM (term), 0);
g_return_val_if_fail (GTK_WIDGET_REALIZED (term), 0);
return term_char_height (term);
}
guint
moo_term_char_width (MooTerm *term)
{
g_return_val_if_fail (MOO_IS_TERM (term), 0);
g_return_val_if_fail (GTK_WIDGET_REALIZED (term), 0);
return term_char_width (term);
}

View File

@ -131,6 +131,10 @@ void moo_term_feed_child (MooTerm *term,
const char *string,
int len);
void moo_term_get_screen_size (MooTerm *term,
guint *columns,
guint *rows);
void moo_term_scroll_to_top (MooTerm *term);
void moo_term_scroll_to_bottom (MooTerm *term);
void moo_term_scroll_lines (MooTerm *term,
@ -157,6 +161,9 @@ void moo_term_set_cursor_blink_time (MooTerm *term,
void moo_term_reset (MooTerm *term);
void moo_term_soft_reset (MooTerm *term);
guint moo_term_char_height (MooTerm *term);
guint moo_term_char_width (MooTerm *term);
MooTermProfile *moo_term_profile_new (const char *name,
const MooTermCommand *cmd,

View File

@ -61,8 +61,9 @@ struct _MooTermBufferPrivate {
gboolean scrolling_region_set;
/* independent of scrolling region */
guint cursor_row;
guint cursor_col;
guint _cursor_row;
guint _cursor_col; /* 0..width - it equals width if a character
was inserted at the last column in AWM mode */
GList *tab_stops;
@ -176,17 +177,23 @@ inline static guint buf_screen_height (MooTermBuffer *buf)
inline static guint buf_cursor_row (MooTermBuffer *buf)
{
return buf->priv->cursor_row;
return buf->priv->_cursor_row;
}
inline static guint buf_cursor_row_abs (MooTermBuffer *buf)
{
return buf->priv->cursor_row + buf_scrollback (buf);
return buf->priv->_cursor_row + buf_scrollback (buf);
}
inline static guint buf_cursor_col (MooTermBuffer *buf)
inline static guint buf_cursor_col_real (MooTermBuffer *buf)
{
return buf->priv->cursor_col;
return buf->priv->_cursor_col;
}
inline static guint buf_cursor_col_display (MooTermBuffer *buf)
{
return buf->priv->_cursor_col >= buf->priv->screen_width ?
buf->priv->screen_width - 1 : buf->priv->_cursor_col;
}
inline static GdkRegion *buf_get_changed(MooTermBuffer *buf)

View File

@ -364,6 +364,14 @@ _moo_term_buffer_scrollback_changed (MooTermBuffer *buf)
}
static void
clamp_cursor_col (MooTermBuffer *buf)
{
if (buf->priv->_cursor_col >= buf->priv->screen_width)
buf->priv->_cursor_col = buf->priv->screen_width - 1;
}
static void
set_screen_width (MooTermBuffer *buf,
guint width)
@ -378,7 +386,7 @@ set_screen_width (MooTermBuffer *buf,
if (old_width != width)
{
if (buf->priv->cursor_col >= width)
if (buf->priv->_cursor_col >= width)
_moo_term_buffer_cursor_move_to (buf, -1, width - 1);
if (old_width < width)
@ -392,10 +400,8 @@ set_screen_width (MooTermBuffer *buf,
buf_changed_add_rect (buf, changed);
_moo_term_buffer_changed (buf);
}
else
{
reset_tab_stops (buf);
}
reset_tab_stops (buf);
for (i = 0; i < height; ++i)
_moo_term_line_resize (buf_screen_line (buf, i),
@ -448,9 +454,9 @@ static void set_screen_height (MooTermBuffer *buf,
buf->priv->lines->len - remove,
remove);
if (buf->priv->cursor_row >= height)
if (buf->priv->_cursor_row >= height)
{
buf->priv->cursor_row = height - 1;
buf->priv->_cursor_row = height - 1;
cursor_moved = TRUE;
}
}
@ -478,7 +484,7 @@ static void set_screen_height (MooTermBuffer *buf,
{
guint remove = old_height - height;
if (buf->priv->cursor_row < height)
if (buf->priv->_cursor_row < height)
{
for (i = height; i < old_height; ++i)
delete_line (buf, buf_screen_line (buf, i), TRUE, TRUE);
@ -488,11 +494,11 @@ static void set_screen_height (MooTermBuffer *buf,
}
else
{
guint del = old_height - 1 - buf->priv->cursor_row;
guint del = old_height - 1 - buf->priv->_cursor_row;
if (del)
{
for (i = buf->priv->cursor_row + 1; i < old_height; ++i)
for (i = buf->priv->_cursor_row + 1; i < old_height; ++i)
delete_line (buf, buf_screen_line (buf, i), TRUE, TRUE);
g_ptr_array_remove_range (buf->priv->lines,
buf->priv->lines->len - del,
@ -507,9 +513,9 @@ static void set_screen_height (MooTermBuffer *buf,
content_changed = TRUE;
}
if (buf->priv->cursor_row >= height)
if (buf->priv->_cursor_row >= height)
{
buf->priv->cursor_row = height - 1;
buf->priv->_cursor_row = height - 1;
cursor_moved = TRUE;
}
}
@ -547,11 +553,12 @@ _moo_term_buffer_cursor_move (MooTermBuffer *buf,
{
int width = buf_screen_width (buf);
int height = buf_screen_height (buf);
int cursor_row = buf_cursor_row (buf);
int cursor_col = buf_cursor_col (buf);
int cursor_row, cursor_col;
cursor_col += cols;
cursor_row += rows;
clamp_cursor_col (buf);
cursor_row = buf_cursor_row (buf) + rows;
cursor_col = buf_cursor_col_real (buf) + cols;
/* XXX MODE_REVERSE_WRAPAROUND */
@ -583,7 +590,7 @@ void _moo_term_buffer_cursor_move_to (MooTermBuffer *buf,
int width = buf_screen_width (buf);
int height = buf_screen_height (buf);
guint old_row = buf_cursor_row (buf);
guint old_col = buf_cursor_col (buf);
guint old_col = buf_cursor_col_display (buf); /* XXX apparently it's correct, but.. */
if (row < 0)
row = old_row;
@ -592,11 +599,11 @@ void _moo_term_buffer_cursor_move_to (MooTermBuffer *buf,
if (col < 0)
col = old_col;
else if (col >= width)
col = width - 1;
else if (col > width)
col = width;
buf->priv->cursor_row = row;
buf->priv->cursor_col = col;
buf->priv->_cursor_row = row;
buf->priv->_cursor_col = col;
_moo_term_buffer_cursor_moved (buf);
}
@ -607,8 +614,7 @@ static void buf_print_unichar_real (MooTermBuffer *buf,
gunichar c)
{
MooTermLine *line;
guint width = buf_screen_width (buf);
guint cursor_row = buf_cursor_row (buf);
guint width, cursor_row;
if (c <= MAX_GRAPH)
{
@ -637,35 +643,39 @@ static void buf_print_unichar_real (MooTermBuffer *buf,
}
}
line = buf_screen_line (buf, cursor_row);
g_assert (_moo_term_line_width (line) == width);
width = buf_screen_width (buf);
cursor_row = buf_cursor_row (buf);
if (buf_get_mode (MODE_IRM))
if (buf->priv->_cursor_col == width)
{
_moo_term_line_insert_unichar (line, buf->priv->cursor_col++,
c, 1, buf->priv->current_attr);
buf_changed_add_range (buf, cursor_row,
buf->priv->cursor_col - 1,
width - buf->priv->cursor_col + 1);
}
else
{
_moo_term_line_set_unichar (line, buf->priv->cursor_col++,
c, 1, buf->priv->current_attr);
buf_changed_add_range (buf, cursor_row,
buf->priv->cursor_col - 1, 1);
}
if (buf->priv->cursor_col == width)
{
buf->priv->cursor_col--;
buf->priv->_cursor_col--;
if (c != '\t' && buf_get_mode (MODE_DECAWM))
{
_moo_term_line_set_wrapped (line);
_moo_term_buffer_new_line (buf);
cursor_row = buf_cursor_row (buf);
}
}
line = buf_screen_line (buf, cursor_row);
g_assert (_moo_term_line_width (line) == width);
if (buf_get_mode (MODE_IRM))
{
_moo_term_line_insert_unichar (line, buf->priv->_cursor_col++,
c, 1, buf->priv->current_attr);
buf_changed_add_range (buf, cursor_row,
buf->priv->_cursor_col - 1,
width - buf->priv->_cursor_col + 1);
}
else
{
_moo_term_line_set_unichar (line, buf->priv->_cursor_col++,
c, 1, buf->priv->current_attr);
buf_changed_add_range (buf, cursor_row,
buf->priv->_cursor_col - 1, 1);
}
}
@ -801,7 +811,7 @@ _moo_term_buffer_clear_tab_stop (MooTermBuffer *buf,
case CLEAR_TAB_AT_CURSOR:
buf->priv->tab_stops =
g_list_remove (buf->priv->tab_stops,
GUINT_TO_POINTER (buf_cursor_col (buf)));
GUINT_TO_POINTER (buf_cursor_col_real (buf)));
case CLEAR_ALL_TABS:
g_list_free (buf->priv->tab_stops);
@ -825,7 +835,7 @@ cmp_guints (gconstpointer a, gconstpointer b)
void
_moo_term_buffer_set_tab_stop (MooTermBuffer *buf)
{
guint cursor = buf_cursor_col (buf);
guint cursor = buf_cursor_col_real (buf);
if (!g_list_find (buf->priv->tab_stops, GUINT_TO_POINTER (cursor)))
buf->priv->tab_stops =
@ -998,12 +1008,14 @@ _moo_term_buffer_cuu (MooTermBuffer *buf,
guint i;
guint top = buf->priv->top_margin;
if (buf->priv->cursor_row < top)
clamp_cursor_col (buf);
if (buf->priv->_cursor_row < top)
top = 0;
_moo_term_buffer_freeze_cursor_notify (buf);
for (i = 0; i < n && buf->priv->cursor_row > top; ++i)
for (i = 0; i < n && buf->priv->_cursor_row > top; ++i)
_moo_term_buffer_cursor_move (buf, -1, 0);
_moo_term_buffer_thaw_cursor_notify (buf);
@ -1018,12 +1030,14 @@ _moo_term_buffer_cud (MooTermBuffer *buf,
guint i;
guint bottom = buf->priv->bottom_margin;
if (buf->priv->cursor_row > bottom)
clamp_cursor_col (buf);
if (buf->priv->_cursor_row > bottom)
bottom = buf_screen_height (buf) - 1;
_moo_term_buffer_freeze_cursor_notify (buf);
for (i = 0; i < n && buf->priv->cursor_row < bottom; ++i)
for (i = 0; i < n && buf->priv->_cursor_row < bottom; ++i)
_moo_term_buffer_cursor_move (buf, 1, 0);
_moo_term_buffer_thaw_cursor_notify (buf);
@ -1048,6 +1062,8 @@ _moo_term_buffer_index (MooTermBuffer *buf)
guint screen_height = buf_screen_height (buf);
guint width = buf_screen_width (buf);
clamp_cursor_col (buf);
g_assert (cursor_row < screen_height);
if (buf_get_mode (MODE_CA) || buf->priv->scrolling_region_set)
@ -1083,7 +1099,7 @@ _moo_term_buffer_index (MooTermBuffer *buf)
}
else
{
buf->priv->cursor_row += 1;
buf->priv->_cursor_row += 1;
}
}
else
@ -1102,7 +1118,7 @@ _moo_term_buffer_index (MooTermBuffer *buf)
}
else
{
buf->priv->cursor_row += 1;
buf->priv->_cursor_row += 1;
}
}
@ -1119,6 +1135,8 @@ _moo_term_buffer_reverse_index (MooTermBuffer *buf)
guint bottom = buf->priv->bottom_margin + buf->priv->screen_offset;
guint cursor = buf_cursor_row (buf) + buf->priv->screen_offset;
clamp_cursor_col (buf);
g_assert (cursor <= bottom && cursor >= top);
if (cursor == top)
@ -1140,7 +1158,7 @@ _moo_term_buffer_reverse_index (MooTermBuffer *buf)
}
else
{
buf->priv->cursor_row -= 1;
buf->priv->_cursor_row -= 1;
}
NOTIFY;
@ -1163,10 +1181,10 @@ _moo_term_buffer_tab (MooTermBuffer *buf,
_moo_term_buffer_freeze_cursor_notify (buf);
for (i = 0; i < n && buf->priv->cursor_col < width; ++i)
for (i = 0; i < n && buf->priv->_cursor_col < width; ++i)
{
_moo_term_buffer_cursor_move_to (buf, -1,
_moo_term_buffer_next_tab_stop (buf, buf->priv->cursor_col));
_moo_term_buffer_next_tab_stop (buf, buf->priv->_cursor_col));
}
_moo_term_buffer_thaw_cursor_notify (buf);
@ -1182,10 +1200,10 @@ _moo_term_buffer_back_tab (MooTermBuffer *buf,
_moo_term_buffer_freeze_cursor_notify (buf);
for (i = 0; i < n && buf->priv->cursor_col > 0; ++i)
for (i = 0; i < n && buf->priv->_cursor_col > 0; ++i)
{
_moo_term_buffer_cursor_move_to (buf, -1,
_moo_term_buffer_prev_tab_stop (buf, buf->priv->cursor_col));
_moo_term_buffer_prev_tab_stop (buf, buf->priv->_cursor_col));
}
_moo_term_buffer_thaw_cursor_notify (buf);
@ -1313,9 +1331,13 @@ _moo_term_buffer_delete_char (MooTermBuffer *buf,
guint n)
{
MooTermLine *line;
guint cursor_col = buf_cursor_col (buf);
guint cursor_row = buf_cursor_row (buf);
guint cursor_col;
guint cursor_row;
clamp_cursor_col (buf);
cursor_col = buf_cursor_col_real (buf);
cursor_row = buf_cursor_row (buf);
g_assert (cursor_col < buf_screen_width (buf));
if (!n || cursor_row > buf->priv->bottom_margin ||
@ -1357,8 +1379,11 @@ void
_moo_term_buffer_erase_char (MooTermBuffer *buf,
guint n)
{
guint cursor_col = buf_cursor_col (buf);
guint cursor_row = buf_cursor_row (buf);
guint cursor_col, cursor_row;
clamp_cursor_col (buf);
cursor_col = buf_cursor_col_real (buf);
cursor_row = buf_cursor_row (buf);
g_assert (cursor_col < buf_screen_width (buf));
@ -1372,13 +1397,17 @@ _moo_term_buffer_erase_in_display (MooTermBuffer *buf,
EraseType what)
{
guint i;
guint cursor_col = buf_cursor_col (buf);
guint cursor_row = buf_cursor_row (buf);
guint cursor_col, cursor_row;
guint width = buf_screen_width (buf);
guint height = buf_screen_height (buf);
g_return_if_fail (what == 0 || what == 1 || what == 2);
clamp_cursor_col (buf);
cursor_col = buf_cursor_col_real (buf);
cursor_row = buf_cursor_row (buf);
FREEZE_CHANGED;
switch (what)
@ -1411,10 +1440,14 @@ void
_moo_term_buffer_erase_in_line (MooTermBuffer *buf,
EraseType what)
{
guint cursor_col = buf_cursor_col (buf);
guint cursor_row = buf_cursor_row (buf);
guint cursor_col, cursor_row;
guint width = buf_screen_width (buf);
clamp_cursor_col (buf);
cursor_col = buf_cursor_col_real (buf);
cursor_row = buf_cursor_row (buf);
g_return_if_fail (what == 0 || what == 1 || what == 2);
switch (what)
@ -1442,9 +1475,11 @@ _moo_term_buffer_insert_char (MooTermBuffer *buf,
guint n)
{
MooTermLine *line;
guint cursor_col = buf_cursor_col (buf);
guint cursor_col = buf_cursor_col_display (buf);
guint cursor_row = buf_cursor_row (buf);
/* XXX what about autowrapping here? */
g_assert (cursor_col < buf_screen_width (buf));
if (!n || cursor_row > buf->priv->bottom_margin ||
@ -1490,13 +1525,13 @@ void
_moo_term_buffer_delete_line (MooTermBuffer *buf,
guint n)
{
guint cursor = buf->priv->cursor_row + buf->priv->screen_offset;
guint cursor = buf->priv->_cursor_row + buf->priv->screen_offset;
guint top = buf->priv->top_margin + buf->priv->screen_offset;
guint bottom = buf->priv->bottom_margin + buf->priv->screen_offset;
guint i;
GdkRectangle changed = {
0, buf->priv->cursor_row,
0, buf->priv->_cursor_row,
buf->priv->screen_width,
bottom - cursor + 1
};
@ -1531,21 +1566,21 @@ void
_moo_term_buffer_insert_line (MooTermBuffer *buf,
guint n)
{
guint cursor = buf->priv->cursor_row + buf->priv->screen_offset;
guint cursor = buf->priv->_cursor_row + buf->priv->screen_offset;
guint top = buf->priv->top_margin + buf->priv->screen_offset;
guint bottom = buf->priv->bottom_margin + buf->priv->screen_offset;
guint i;
GdkRectangle changed = {
0, buf->priv->cursor_row,
0, buf->priv->_cursor_row,
buf->priv->screen_width,
buf->priv->bottom_margin - buf->priv->cursor_row + 1
buf->priv->bottom_margin - buf->priv->_cursor_row + 1
};
g_return_if_fail (n != 0);
g_return_if_fail (top <= cursor && cursor <= bottom);
/* TODO: scroll the window */
/* TODO: scroll the gdk window */
if (n > bottom - cursor + 1)
n = bottom - cursor + 1;
@ -1588,10 +1623,16 @@ void moo_term_buffer_set_mode (MooTermBuffer *buf,
buf->priv->modes[mode] = set;
break;
case MODE_DECOM:
buf->priv->modes[mode] = set;
/* vttest says this homes cursor */
if (set)
_moo_term_buffer_cup (buf, 0, 0);
break;
/* these do not require anything special, just record the value */
case MODE_IRM:
case MODE_LNM:
case MODE_DECOM:
case MODE_DECAWM:
case MODE_REVERSE_WRAPAROUND: /* TODO*/
buf->priv->modes[mode] = set;
@ -1629,7 +1670,7 @@ _moo_term_buffer_set_ca_mode (MooTermBuffer *buf,
static void
set_defaults (MooTermBuffer *buf)
{
buf->priv->cursor_col = buf->priv->cursor_row = 0;
buf->priv->_cursor_col = buf->priv->_cursor_row = 0;
buf->priv->top_margin = 0;
buf->priv->bottom_margin = buf->priv->screen_height - 1;
@ -1700,8 +1741,8 @@ _moo_term_buffer_cursor_next_line (MooTermBuffer *buf,
for (i = 0; i < n ; ++i)
{
if (buf->priv->cursor_row + 1 < buf->priv->screen_height)
_moo_term_buffer_cursor_move_to (buf, buf->priv->cursor_row + 1, 0);
if (buf->priv->_cursor_row + 1 < buf->priv->screen_height)
_moo_term_buffer_cursor_move_to (buf, buf->priv->_cursor_row + 1, 0);
else
break;
}
@ -1721,8 +1762,8 @@ _moo_term_buffer_cursor_prev_line (MooTermBuffer *buf,
for (i = 0; i < n ; ++i)
{
if (buf->priv->cursor_row > 0)
_moo_term_buffer_cursor_move_to (buf, buf->priv->cursor_row - 1, 0);
if (buf->priv->_cursor_row > 0)
_moo_term_buffer_cursor_move_to (buf, buf->priv->_cursor_row - 1, 0);
else
break;
}

View File

@ -227,12 +227,12 @@ _moo_term_line_erase_range (MooTermLine *line,
MooTermTextAttr attr)
{
guint i;
guint last = MIN ((guint) (line->width - 1), pos + len);
guint end = MIN ((guint) line->width, pos + len);
if ((int) last == line->width - 1)
if ((int) end >= line->len)
line->len = MIN (line->len, pos);
for (i = pos; i < last; ++i)
for (i = pos; i < end; ++i)
{
line->cells[i].ch = EMPTY_CHAR;
line->cells[i].attr = attr;
@ -334,14 +334,13 @@ _moo_term_line_insert_unichar (MooTermLine *line,
if (c != EMPTY_CHAR)
{
if (pos + num >= line->width)
line->len = line->width;
else if (pos >= line->len)
line->len = pos + num;
else
if (pos <= line->len)
line->len += num;
else
line->len = pos + num;
g_assert (line->len <= line->width);
if (line->len > line->width)
line->len = line->width;
}
if (pos + num >= line->width)

View File

@ -74,7 +74,7 @@ static InputIter *iter_new (MooTermParser *parser)
static gboolean iter_eof (InputIter *iter)
{
return !iter->old && iter->offset ==
return !iter->old && iter->offset >=
iter->parser->input.data_len;
}

View File

@ -23,7 +23,7 @@ if MOO_BUILD_EDIT
medit = medit
endif
if MOO_BUILD_TERM
# noinst_PROGRAMS += mterm termbuffer
#noinst_PROGRAMS += mterm #termbuffer
endif
if MOO_BUILD_UTILS
# noinst_PROGRAMS += testpanedfileview

View File

@ -89,6 +89,14 @@ static void set_width (MooTerm *term, guint width, GtkWindow *window)
}
static gboolean
invalidate (gpointer term)
{
_moo_term_invalidate_all (term);
return TRUE;
}
int main (int argc, char *argv[])
{
const char *cmd = NULL;
@ -118,6 +126,8 @@ int main (int argc, char *argv[])
"font-name", "Courier New 11",
NULL));
g_timeout_add (1000, invalidate, term);
gtk_container_add (GTK_CONTAINER (swin), term);
gtk_widget_show_all (win);

53
tests/testterm.py Normal file
View File

@ -0,0 +1,53 @@
import gtk
from pyconsole import Console
def create_terminal():
import vttest
win = gtk.Window()
win.set_default_size(700, 500)
swin = gtk.ScrolledWindow()
win.add(swin)
swin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
term = vttest.VtTest()
term.set_property("font-name", "Courier New 11")
swin.add(term)
win.show_all()
win.set_resize_mode(gtk.RESIZE_IMMEDIATE)
swin.set_resize_mode(gtk.RESIZE_IMMEDIATE)
def set_width(term, width, window):
height = term.char_height() * 25
width *= term.char_width()
term.set_size_request(width, height)
window.resize(10, 10)
window.check_resize()
window.window.process_updates(True)
term.connect("set-width", set_width, win)
term.connect("set-window-title", lambda term,title,win: win.set_title(title), win)
term.connect("bell", lambda *whatever: gtk.gdk.beep())
return term
if __name__ == '__main__':
window = gtk.Window()
swin = gtk.ScrolledWindow()
swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
window.add(swin)
swin.add(Console(use_rlcompleter=False,
locals={'create_terminal' : create_terminal},
start_script="import gtk\n" + \
"import moo\n" + \
"import vttest\n" + \
"term = create_terminal()\n"))
window.set_default_size(400, 300)
window.show_all()
if not gtk.main_level():
window.connect("destroy", gtk.main_quit)
gtk.main()

827
tests/vttest.py Normal file
View File

@ -0,0 +1,827 @@
import moo
DEFAULT_SPEED = 9600
LOG_ENABLED = False
BEL = '\007'
SO = '\016'
SI = '\017'
ESC = '\033'
CSI = '\233'
SS3 = '\217'
DCS = '\220'
ST = '\234'
GATM = 1 ## guarded area transfer (disabled)
KAM = 2 ## keyboard action
CRM = 3 ## control representation (setup)
IRM = 4 ## insert/replace
SRTM = 5 ## status reporting transfer (disabled)
ERM = 6 ## erasure mode (non-DEC)
VEM = 7 ## vertical editing (disabled)
BDSM = 8 ## bi-directional support mode (non-DEC)
DCSM = 9 ## device component select mode (non-DEC)
HEM = 10 ## horizontal editing (disabled)
PUM = 11 ## positioning unit (disabled)
SRM = 12 ## send/receive
FEAM = 13 ## format effector action (disabled)
FETM = 14 ## format effector transfer (disabled)
MATM = 15 ## multiple area transfer (disabled)
TTM = 16 ## transfer termination (disabled)
SATM = 17 ## selected area transfer (disabled)
TSM = 18 ## tabulation stop (disabled)
EBM = 19 ## editing boundary (disabled)
LNM = 20 ## line feed/new line
DECCKM = 1 ## cursor keys
DECANM = 2 ## ANSI
DECCOLM = 3 ## column
DECSCLM = 4 ## scrolling
DECSCNM = 5 ## screen
DECOM = 6 ## origin
DECAWM = 7 ## autowrap
DECARM = 8 ## autorepeat
DECEDM = 10 ## edit
DECLTM = 11 ## line transmit
DECSCFDM = 13 ## space compression field delimiter
DECTEM = 14 ## transmission execution
DECEKEM = 16 ## edit key execution
DECPFF = 18 ## print form feed
DECPEX = 19 ## printer extent
DECTCEM = 25 ## text cursor enable
DECRLM = 34 ## left-to-right
DECTEK = 35 ## 4010/4014 emulation
DECHEM = 36 ## Hebrew encoding
DECNRCM = 42 ## national replacement character set
DECGEPM = 43 ## graphics expanded print
DECGPCM = 44 ## graphics print color
DECGPCS = 45 ## graphics print color syntax
DECGPBM = 46 ## graphics print background
DECGRPM = 47 ## graphics rotated print
DEC131TM = 53 ## VT131 transmit
DECNAKB = 57 ## Greek/N-A Keyboard Mapping
DECHCCM = 60 ## horizontal cursor coupling (disabled)
DECVCCM = 61 ## vertical cursor coupling
DECPCCM = 64 ## page cursor coupling
DECNKM = 66 ## numeric keypad
DECBKM = 67 ## backarrow key
DECKBUM = 68 ## keyboard usage
DECVSSM = 69 ## vertical split
DECXRLM = 73 ## transmit rate linking
DECKPM = 81 ## keyboard positioning
DECNCSM = 95 ## no clearing screen on column change
DECRLCM = 96 ## right-to-left copy
DECCRTSM = 97 ## CRT save
DECARSM = 98 ## auto resize
DECMCM = 99 ## modem control
DECAAM = 100 ## auto answerback
DECCANSM = 101 ## conceal answerback
DECNULM = 102 ## null
DECHDPXM = 103 ## half duplex
DECESKM = 104 ## enable secondary keyboard language
DECOSCNM = 106 ## overscan
DECFWM = 111 ## framed windows
DECRPL = 112 ## review previous lines
DECHWUM = 113 ## host wake-up mode (CRT and energy saver)
DECATCUM = 114 ## alternate text color underline
DECATCBM = 115 ## alternate text color blink
DECBBSM = 116 ## bold and blink style
DECECM = 117 ## erase color
soft_scroll = 0
#/******************************************************************************/
csi_7 = ESC + '['
csi_8 = chr(0x9b)
dcs_7 = ESC + 'P'
dcs_8 = chr(0x90)
osc_7 = ESC + ']'
osc_8 = chr(0x9d)
ss3_7 = ESC + 'O'
ss3_8 = chr(0x8f)
st_7 = ESC + '\\'
st_8 = chr(0x9c)
class VtTest(moo.term.Term):
def __init__(self):
moo.term.Term.__init__(self)
self.brkrd = 0
self.input_8bits = False
self.log_disabled = False
self.max_cols = 132
self.max_lines = 24
self.min_cols = 80
self.output_8bits = False
self.reading = 0
self.tty_speed = DEFAULT_SPEED
self.use_padding = False
def csi_input(self):
if self.input_8bits: return csi_8
else: return csi_7
def csi_output(self):
if self.output_8bits: return csi_8
else: return csi_7
def dcs_input(self):
if self.input_8bits: return dcs_8
else: return dcs_7
def dcs_output(self):
if self.output_8bits: return dcs_8
else: return dcs_7
def osc_input(self):
if self.input_8bits: return osc_8
else: return osc_7
def osc_output(self):
if self.output_8bits: return osc_8
else: return osc_7
def ss3_input(self):
if self.input_8bits: return ss3_8
else: return ss3_7
def ss3_output(self):
if self.output_8bits: return ss3_8
else: return ss3_7
def st_input(self):
if self.input_8bits: return st_8
else: return st_7
def st_output(self):
if self.output_8bits: return st_8
else: return st_7
def padding(self, msecs):
if self.use_padding:
count = (3 * msecs * tty_speed + DEFAULT_SPEED - 1) / DEFAULT_SPEED
while count > 0:
count -= 1
self.feed('\0')
def extra_padding(self, msecs):
if self.use_padding:
if self.soft_scroll:
self.padding(msecs * 4)
else:
self.padding(msecs)
def println(self, s):
self.feed(s + "\r\n")
return 1
def do_csi(self, fmt, *args):
self.feed(self.csi_output())
self.feed(fmt % args)
def do_dcs(self, fmt, *args):
self.feed(self.dcs_output())
self.feed(fmt % args)
def do_osc(self, fmt, *args):
self.feed(self.osc_output())
self.feed(fmt % args)
def send_char(self, c):
self.feed(chr(c))
def esc(self, s):
self.feed(ESC + s)
def brc(self, pn, c):
self.do_csi("%d%s", pn, c)
def brc2(self, pn1, pn2, c):
self.do_csi("%d;%d%s", pn1, pn2, c)
def brc3(self, pn1, pn2, pn3, c):
self.do_csi("%d;%d;%d%s", pn1, pn2, pn3, c)
def cbt(self, pn):
self.brc(pn, 'Z')
## Cursor Character Absolute
def cha(self, pn):
self.brc(pn, 'G')
## Cursor Forward Tabulation
def cht(self, pn):
self.brc(pn, 'I')
# Cursor Next Line
def cnl(self, pn):
self.brc(pn, 'E')
# Cursor Previous Line
def cpl(self, pn):
brc(pn, 'F')
# Cursor Backward
def cub(self, pn):
self.brc(pn, 'D')
self.padding(2)
# Cursor Down
def cud(self, pn):
self.brc(pn, 'B')
self.extra_padding(2)
# Cursor Forward
def cuf(self, pn):
self.brc(pn, 'C')
self.padding(2)
def cup(self, pn1, pn2): # Cursor Position
self.brc2(pn1, pn2, 'H')
self.padding(5) # 10 for vt220
return 1 # used for indenting
def cuu(self, pn): # Cursor Up
self.brc(pn, 'A')
self.extra_padding(2)
def da(self): # Device Attributes
self.brc(0, 'c')
def decaln(self): # Screen Alignment Display
self.esc("#8")
def decarm(self, flag): # DECARM autorepeat
if flag:
self.sm("?8") # autorepeat
else:
self.rm("?8") # no autorepeat
def decawm(self, flag): # DECAWM autowrap
if flag:
self.sm("?7") # autowrap
else:
self.rm("?7") # no autowrap
def decbi(self): # VT400: Back Index
self.esc("6")
self.padding(40)
def decbkm(self, flag): # VT400: Backarrow key
if flag:
self.sm("?67") # backspace
else:
self.rm("?67") # delete
def deccara(self, top, left, bottom, right, attr):
self.do_csi("%d%d%d%d%d$r", top, left, bottom, right, attr)
def decckm(self, flag): # DECCKM Cursor Keys
if flag:
self.sm("?1") # application
else:
self.rm("?1") # normal
def deccolm(self, flag): # DECCOLM 80/132 Columns
if flag:
self.sm("?3") # 132 columns
else:
self.rm("?3") # 80 columns
def deccra(self, Pts, Pl, Pbs, Prs, Pps, Ptd, Pld, Ppd):
self.do_csi("%d%d%d%d%d%d%d%d$v",
Pts, # top-line border
Pl, # left-line border
Pbs, # bottom-line border
Prs, # right-line border
Pps, # source page number
Ptd, # destination top-line border
Pld, # destination left-line border
Ppd) # destination page number
def decdc(self, pn): # VT400 Delete Column
self.do_csi("%d'~", pn)
self.padding(10 * pn)
return 1
def decefr(self, top, left, bottom, right): # DECterm Enable filter rectangle
self.do_csi("%d%d%d%d'w", top, left, bottom, right)
def decelr(self, all_or_one, pixels_or_cells): # DECterm Enable Locator Reporting
self.do_csi("%d%d'z", all_or_one, pixels_or_cells)
def decera(self, top, left, bottom, right): # VT400 Erase Rectangular area
self.do_csi("%d%d%d%d$z", top, left, bottom, right)
def decdhl(self, lower): # Double Height Line (also double width)
if lower:
self.esc("#4")
else:
self.esc("#3")
def decdwl(self): # Double Wide Line
self.esc("#6")
def decfi(self): # VT400: Forward Index
self.esc("9")
self.padding(40)
def decfra(self, c, top, left, bottom, right): # VT400 Fill Rectangular area
self.do_csi("%d%d%d%d%d$x", c, top, left, bottom, right)
def decid(self): # required for VT52, not recommended above VT100
self.esc("Z") # Identify
def decic(self, pn): # VT400 Insert Column
self.do_csi("%d'}", pn)
self.padding(10 * pn)
return 1
def deckbum(self, flag): # VT400: Keyboard Usage
if flag:
self.sm("?68") # data processing
else:
self.rm("?68") # typewriter
def deckpam(self): # Keypad Application Mode
self.esc("=")
def deckpm(self, flag): # VT400: Keyboard Position
if flag:
self.sm("?81") # position reports
else:
self.rm("?81") # character codes
def deckpnm(self): # Keypad Numeric Mode
self.esc(">")
def decll(self, ps): # Load LEDs
self.do_csi("%sq", ps)
def decnkm(self, flag): # VT400: Numeric Keypad
if flag:
self.sm("?66") # application
else:
self.rm("?66") # numeric
def decom(self, flag): # DECOM Origin
if flag:
self.sm("?6") # relative
else:
self.rm("?6") # absolute
def decpex(self, flag): # VT220: printer extent mode
if flag:
self.sm("?19") # full screen (page)
else:
self.rm("?19") # scrolling region
def decpff(self, flag): # VT220: print form feed mode
if flag:
self.sm("?18") # form feed
else:
self.rm("?18") # no form feed
def decnrcm(self, flag): # VT220: National replacement character set
if flag:
self.sm("?42") # national
else:
self.rm("?42") # multinational
def decrara(self, top, left, bottom, right, attr):
self.do_csi("%d%d%d%d%d$t", top, left, bottom, right, attr)
def decrc(self): # Restore Cursor
self.esc("8")
def decreqtparm(self, pn): # Request Terminal Parameters
self.brc(pn, 'x')
def decrqlp(self, mode): # DECterm Request Locator Position
self.do_csi("%d'|", mode)
def decrqss(self, pn): # VT200 Request Status-String
self.do_dcs("$q%s", pn)
def decsace(self, flag): # VT400 Select attribute change extent
if flag:
self.do_csi("%d*x", 2)
else:
self.do_csi("%d*x", 0)
def decsasd(self, pn): # VT200 Select active status display
self.do_csi("%d$}", pn)
def decsc(self): # Save Cursor
self.esc("7")
def decsca(self, pn1): # VT200 select character attribute (protect)
self.do_csi("%d\"q", pn1)
def decsclm(self, flag): # Scrolling mode (smooth/jump)
if flag:
self.sm("?4") # smooth scrolling
else:
self.rm("?4") # jump-scrolling scrolling
self.soft_scroll = flag
def decscnm(self, flag): # Screen mode (inverse-video)
if flag:
self.sm("?5") # inverse video
else:
self.rm("?5") # normal video
self.padding(200)
def decsed(self, pn1): # VT200 selective erase in display
self.do_csi("?%dJ", pn1)
def decsel(self, pn1): # VT200 selective erase in line
self.do_csi("?%dK", pn1)
def decsera(self, top, left, bottom, right): # VT400 Selective erase rectangular area
self.do_csi("%d%d%d%d${", top, left, bottom, right)
def decsle(self, mode): # DECterm Select Locator Events
self.do_csi("%d'{", mode)
def decsnls(self, pn): # VT400 Select number of lines per screen
self.do_csi("%d*|", pn)
def decssdt(self, pn): # VT200 Select status line type
self.do_csi("%d$~", pn)
def decstbm(self, pn1, pn2): # Set Top and Bottom Margins
if pn1 or pn2:
self.brc2(pn1, pn2, 'r')
else:
self.esc("[r")
# Good for >24-line terminals
def decstr(self): # VT200 Soft terminal reset
self.do_csi("!p")
def decswl(self): # Single Width Line
self.esc("#5")
def dectst(self, pn): # Invoke Confidence Test
self.brc2(2, pn, 'y')
def dsr(self, pn): # Device Status Report
self.brc(pn, 'n')
def ed(self, pn): # Erase in Display
self.brc(pn, 'J')
self.padding(50)
def el(self, pn): # Erase in Line
self.brc(pn, 'K')
self.padding(3) # 4 for vt400
def ech(self, pn): # Erase character(s)
self.brc(pn, 'X')
def hpa(self, pn): # Character Position Absolute
self.brc(pn, '`')
def hts(self): # Horizontal Tabulation Set
self.esc("H")
def hvp(self, pn1, pn2): # Horizontal and Vertical Position
self.brc2(pn1, pn2, 'f')
def ind(self): # Index
self.esc("D")
self.padding(20) # vt220
# The functions beginning "mc_" are variations of Media Copy (MC)
def mc_autoprint(self, flag): # VT220: auto print mode
if flag:
self.do_csi("?%di", 5)
else:
self.do_csi("?%di", 4)
def mc_printer_controller(self, flag): # VT220: printer controller mode
if flag:
self.do_csi("%di", 5)
else:
self.do_csi("%di", 4)
def mc_print_page(self): # VT220: print page
self.do_csi("i")
def mc_print_composed(self): # VT300: print composed main display
self.do_csi("?10i")
def mc_print_all_pages(self): # VT300: print composed all pages
self.do_csi("?11i")
def mc_print_cursor_line(self): # VT220: print cursor line
self.do_csi("?1i")
def mc_printer_start(self, flag): # VT300: start/stop printer-to-host session
if flag:
self.do_csi("?%di", 9)
else:
self.do_csi("?%di", 8)
def mc_printer_assign(self, flag): # VT300: assign/release printer to active session
if flag:
self.do_csi("?%di", 18)
else:
self.do_csi("?%di", 19)
def nel(self): # Next Line
self.esc("E")
def rep(self, pn): # Repeat
self.do_csi("%db", pn)
def ri(self): # Reverse Index
self.esc("M")
self.extra_padding(5) # 14 on vt220
def ris(self): # Reset to Initial State
self.esc("c")
def rm(self, ps): # Reset Mode
self.do_csi("%sl", ps)
def s8c1t(self, flag): # Tell terminal to respond with 7-bit or 8-bit controls
self.input_8bits = flag
if flag:
self.esc(" G") # select 8-bit controls
else:
self.esc(" F") # select 7-bit controls
self.zleep(300)
# /*
# * If g is zero,
# * designate G0 as character set c
# * designate G1 as character set B (ASCII)
# * shift-in (select G0 into GL).
# * If g is nonzero
# * designate G0 as character set B (ASCII)
# * designate G1 as character set c
# * shift-out (select G1 into GL).
# * See also scs_normal() and scs_graphics().
# */
def scs(self, g, c): # Select character Set
if g:
self.esc("%c%c" % (')', c))
else:
self.esc("%c%c" % ('(', c))
if g:
self.esc("%c%c" % (')', 'B'))
else:
self.esc("%c%c" % ('(', 'B'))
if g: self.feed(SO)
else: self.feed(SI)
self.padding(4)
def sd(self, pn): # Scroll Down
self.brc(pn, 'T')
def sgr(self, ps): # Select Graphic Rendition
self.do_csi("%sm", ps)
self.padding(2)
def sl(self, pn): # Scroll Left
self.do_csi("%d @", pn)
def sm(self, ps): # Set Mode
self.do_csi("%sh", ps)
def sr(self, pn): # Scroll Right
self.do_csi("%d A", pn)
def srm(self, flag): # VT400: Send/Receive mode
if flag:
self.sm("12") # local echo off
else:
self.rm("12") # local echo on
def su(self, pn): # Scroll Up
self.brc(pn, 'S')
self.extra_padding(5)
def tbc(self, pn): # Tabulation Clear
self.brc(pn, 'g')
def dch(self, pn): # Delete character
self.brc(pn, 'P')
def ich(self, pn): # Insert character -- not in VT102
self.brc(pn, '@')
def dl(self, pn): # Delete line
self.brc(pn, 'M')
def il(self, pn): # Insert line
self.brc(pn, 'L')
def vpa(self, pn): # Line Position Absolute
self.brc(pn, 'd')
def vt52cub1(self): # cursor left
self.esc("D")
self.padding(5)
def vt52cud1(self): # cursor down
self.esc("B")
self.padding(5)
def vt52cuf1(self): # cursor right
self.esc("C")
self.padding(5)
def vt52cup(self, l, c): # direct cursor address
self.esc("Y%c%c" % (l + 31, c + 31))
self.padding(5)
def vt52cuu1(self): # cursor up
self.esc("A")
self.padding(5)
def vt52ed(self): # erase to end of screen
self.esc("J")
self.padding(5)
def vt52el(self): # erase to end of line
self.esc("K")
self.padding(5)
def vt52home(self): # cursor to home
self.esc("H")
self.padding(5)
def vt52ri(self): # reverse line feed
self.esc("I")
self.padding(5)
def tst_movements(self, N=26):
ctext = "This is a correct sentence";
self.deccolm(False)
width = 80
# Compute left/right columns for a 60-column box centered in 'width'
inner_l = (width - 60) / 2;
inner_r = 61 + inner_l;
hlfxtra = (width - 80) / 2;
self.decaln();
self.cup( 9,inner_l); self.ed(1);
self.cup(18,60+hlfxtra); self.ed(0); self.el(1);
self.cup( 9,inner_r); self.el(0);
# 132: 36..97 */
# 80: 10..71 */
for row in range(10,17):
self.cup(row, inner_l); self.el(1);
self.cup(row, inner_r); self.el(0);
self.cup(17,30); self.el(2);
for col in range(1,width+1):
self.hvp(self.max_lines, col); self.feed("*");
self.hvp( 1, col); self.feed("*");
self.cup(2,2);
for row in range(2,self.max_lines):
self.feed("+");
self.cub(1);
self.ind();
self.cup(self.max_lines-1,width-1);
l = range(2, self.max_lines)
l.reverse
for row in l:
self.feed("+");
self.cub(1); self.ri();
self.cup(2,1);
for row in range(2, self.max_lines):
self.feed("*"); self.cup(row, width);
self.feed("*");
self.cub(10);
if (row < 10): self.nel();
else: self.feed("\n");
self.cup(2,10);
self.cub(42+hlfxtra); self.cuf(2);
for col in range(3, width-1):
self.feed("+");
self.cuf(0); self.cub(2); self.cuf(1);
self.cup(self.max_lines-1,inner_r-1);
self.cuf(42+hlfxtra); self.cub(2);
l = range(3, width-1)
l.reverse()
for col in l:
self.feed("+");
self.cub(1); self.cuf(1); self.cub(0); self.feed("%c" % (8,));
self.cup( 1, 1); self.cuu(10); self.cuu(1); self.cuu(0);
self.cup(self.max_lines,width); self.cud(10); self.cud(1); self.cud(0);
self.cup(10,2+inner_l);
for row in range(10, 16):
for col in range(2+inner_l, inner_r-1): self.feed(" ");
self.cud(1); self.cub(58);
self.cuu(5); self.cuf(1);
self.feed("The screen should be cleared, and have an unbroken bor-");
self.cup(12,inner_l+3);
self.feed("der of *'s and +'s around the edge, and exactly in the");
self.cup(13,inner_l+3);
self.feed("middle there should be a frame of E's around this text");
self.cup(14,inner_l+3);
self.feed("with one (1) free position around it. ");
for i in range(1):
on_left = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
on_right = "abcdefghijklmnopqrstuvwxyz";
height = len(on_left) - 1;
region = self.max_lines - 6;
height = 10;
self.deccolm(False); width = self.min_cols
self.println("Test of autowrap, mixing control and print characters.");
self.println("The left/right margins should have letters in order:");
self.decstbm(3, region + 3);
self.decom(True)
for i in range(N):
if i % 4 == 0:
self.cup(region + 1, 1)
self.feed(on_left[i]);
self.cup(region + 1, width)
self.feed(on_right[i]);
self.feed("\n");
elif i % 4 == 1:
self.cup(region, width)
self.feed(on_right[i - 1] + on_left[i])
self.cup(region + 1, width)
self.feed(on_left[i] + "\010 " + on_right[i]);
self.feed("\n");
elif i % 4 == 2:
self.cup(region + 1, width)
self.feed(on_left[i] + "\010\010\011\011" + on_right[i]);
self.cup(region + 1, 2)
self.feed("\010" + on_left[i] + "\n");
else:
self.cup(region + 1, width)
self.feed("\n");
self.cup(region, 1)
self.feed(on_left[i]);
self.cup(region, width)
self.feed(on_right[i]);
# self.decom(False);
# self.decstbm(0, 0);
# self.cup(self.max_lines - 2, 1);
# self.deccolm(False)
# vt_clear(2);
# vt_move(1,1);
# println("Test of cursor-control characters inside ESC sequences.");
# println("Below should be four identical lines:");
# println("");
# println("A B C D E F G H I");
# for (i = 1; i < 10; i++) {
# printf("%c", '@' + i);
# do_csi("2\010C"); /* Two forward, one backspace */
# }
# println("");
# /* Now put CR in CUF sequence. */
# printf("A ");
# for (i = 2; i < 10; i++)
# printf("%s\015%dC%c", csi_output(), 2 * i - 2, '@' + i);
# println("");
# /* Now put VT in CUU sequence. */
# rm("20");
# for (i = 1; i < 10; i++) {
# printf("%c ", '@' + i);
# do_csi("1\013A");
# }
# println("");
# println("");
# holdit();
#
# if (LOG_ENABLED)
# fprintf(log_fp, "tst_movements leading zeros in ESC sequences\n");
#
# vt_clear(2);
# vt_move(1,1);
# println("Test of leading zeros in ESC sequences.");
# printf("Two lines below you should see the sentence \"%s\".",ctext);
# for (col = 1; *ctext; col++)
# printf("%s00000000004;00000000%dH%c", csi_output(), col, *ctext++);
# cup(20,1);
#
# restore_ttymodes();
# return MENU_HOLD;
# }