aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--screen-redraw.c10
-rw-r--r--screen-write.c84
-rw-r--r--tmux.h13
-rw-r--r--tty.c96
4 files changed, 124 insertions, 79 deletions
diff --git a/screen-redraw.c b/screen-redraw.c
index fc3d3eb9..917f7175 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -1,4 +1,4 @@
-/* $Id: screen-redraw.c,v 1.21 2009-02-11 06:50:15 nicm Exp $ */
+/* $Id: screen-redraw.c,v 1.22 2009-02-11 17:04:38 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -135,15 +135,13 @@ screen_redraw_line(struct client *c, struct screen *s, u_int oy, u_int py)
if (sx > c->sx)
sx = c->sx;
for (i = 0; i < sx; i++) {
- s->cx = i;
- s->cy = py;
-
gc = grid_view_peek_cell(s->grid, i, py);
+ tty_cursor(&c->tty, i, py, oy);
if (screen_check_selection(s, i, py)) {
memcpy(&tc, &s->sel.cell, sizeof tc);
tc.data = gc->data;
- tty_cell(&c->tty, s, oy, &tc);
+ tty_cell(&c->tty, &tc);
} else
- tty_cell(&c->tty, s, oy, gc);
+ tty_cell(&c->tty, gc);
}
}
diff --git a/screen-write.c b/screen-write.c
index 490b0927..4553b2a0 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -1,4 +1,4 @@
-/* $Id: screen-write.c,v 1.32 2009-02-11 06:31:09 nicm Exp $ */
+/* $Id: screen-write.c,v 1.33 2009-02-11 17:04:39 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -22,6 +22,8 @@
#include "tmux.h"
+void screen_write_save(struct screen_write_ctx *);
+
/* Initialise writing with a window. */
void
screen_write_start(
@@ -95,6 +97,19 @@ screen_write_copy(struct screen_write_ctx *ctx,
}
}
+/* Save cursor and region positions. */
+void
+screen_write_save(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ s->old_cx = s->cx;
+ s->old_cy = s->cy;
+
+ s->old_rlower = s->rlower;
+ s->old_rupper = s->rupper;
+}
+
/* Cursor up by ny. */
void
screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny)
@@ -177,10 +192,12 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0)
return;
- tty_write_cmd(ctx->wp, TTY_INSERTCHARACTER, nx);
+ screen_write_save(ctx);
if (s->cx <= screen_size_x(s) - 1)
grid_view_insert_cells(s->grid, s->cx, s->cy, nx);
+
+ tty_write_cmd(ctx->wp, TTY_INSERTCHARACTER, nx);
}
/* Delete nx characters. */
@@ -197,10 +214,12 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0)
return;
- tty_write_cmd(ctx->wp, TTY_DELETECHARACTER, nx);
+ screen_write_save(ctx);
if (s->cx <= screen_size_x(s) - 1)
grid_view_delete_cells(s->grid, s->cx, s->cy, nx);
+
+ tty_write_cmd(ctx->wp, TTY_DELETECHARACTER, nx);
}
/* Insert ny lines. */
@@ -217,7 +236,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0)
return;
- tty_write_cmd(ctx->wp, TTY_INSERTLINE, ny);
+ screen_write_save(ctx);
if (s->cy < s->rupper || s->cy > s->rlower)
grid_view_insert_lines(s->grid, s->cy, ny);
@@ -225,6 +244,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
grid_view_insert_lines_region(
s->grid, s->rupper, s->rlower, s->cy, ny);
}
+
+ tty_write_cmd(ctx->wp, TTY_INSERTLINE, ny);
}
/* Delete ny lines. */
@@ -241,7 +262,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0)
return;
- tty_write_cmd(ctx->wp, TTY_DELETELINE, ny);
+ screen_write_save(ctx);
if (s->cy < s->rupper || s->cy > s->rlower)
grid_view_delete_lines(s->grid, s->cy, ny);
@@ -249,6 +270,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny)
grid_view_delete_lines_region(
s->grid, s->rupper, s->rlower, s->cy, ny);
}
+
+ tty_write_cmd(ctx->wp, TTY_DELETELINE, ny);
}
/* Clear line at cursor. */
@@ -257,9 +280,11 @@ screen_write_clearline(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
- tty_write_cmd(ctx->wp, TTY_CLEARLINE);
+ screen_write_save(ctx);
grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1);
+
+ tty_write_cmd(ctx->wp, TTY_CLEARLINE);
}
/* Clear to end of line from cursor. */
@@ -269,12 +294,14 @@ screen_write_clearendofline(struct screen_write_ctx *ctx)
struct screen *s = ctx->s;
u_int sx;
- sx = screen_size_x(s);
+ screen_write_save(ctx);
- tty_write_cmd(ctx->wp, TTY_CLEARENDOFLINE);
+ sx = screen_size_x(s);
if (s->cx <= sx - 1)
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
+
+ tty_write_cmd(ctx->wp, TTY_CLEARENDOFLINE);
}
/* Clear to start of line from cursor. */
@@ -284,14 +311,16 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx)
struct screen *s = ctx->s;
u_int sx;
- sx = screen_size_x(s);
+ screen_write_save(ctx);
- tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFLINE);
+ sx = screen_size_x(s);
if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1);
else
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1);
+
+ tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFLINE);
}
/* Move cursor to px,py. */
@@ -327,12 +356,14 @@ screen_write_reverseindex(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
- tty_write_cmd(ctx->wp, TTY_REVERSEINDEX);
+ screen_write_save(ctx);
if (s->cy == s->rupper)
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
else if (s->cy > 0)
s->cy--;
+
+ tty_write_cmd(ctx->wp, TTY_REVERSEINDEX);
}
/* Set scroll region. */
@@ -387,12 +418,14 @@ screen_write_linefeed(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
- tty_write_cmd(ctx->wp, TTY_LINEFEED);
+ screen_write_save(ctx);
if (s->cy == s->rlower)
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
else if (s->cy < screen_size_y(s) - 1)
s->cy++;
+
+ tty_write_cmd(ctx->wp, TTY_LINEFEED);
}
/* Carriage return (cursor to start of line). */
@@ -435,14 +468,16 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx)
struct screen *s = ctx->s;
u_int sx, sy;
+ screen_write_save(ctx);
+
sx = screen_size_x(s);
sy = screen_size_y(s);
- tty_write_cmd(ctx->wp, TTY_CLEARENDOFSCREEN);
-
if (s->cx <= sx - 1)
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1));
+
+ tty_write_cmd(ctx->wp, TTY_CLEARENDOFSCREEN);
}
/* Clear to start of screen. */
@@ -452,9 +487,9 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
struct screen *s = ctx->s;
u_int sx;
- sx = screen_size_x(s);
+ screen_write_save(ctx);
- tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN);
+ sx = screen_size_x(s);
if (s->cy > 0)
grid_view_clear(s->grid, 0, 0, sx, s->cy - 1);
@@ -462,6 +497,8 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
grid_view_clear(s->grid, 0, s->cy, sx, 1);
else
grid_view_clear(s->grid, 0, s->cy, s->cx, 1);
+
+ tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN);
}
/* Clear entire screen. */
@@ -470,9 +507,11 @@ screen_write_clearscreen(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
- tty_write_cmd(ctx->wp, TTY_CLEARSCREEN);
+ screen_write_save(ctx);
grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s));
+
+ tty_write_cmd(ctx->wp, TTY_CLEARSCREEN);
}
/* Write cell data. */
@@ -572,15 +611,18 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
ic->flags |= GRID_FLAG_PADDING;
}
- /* Write the actual cell. */
+ /* Set the cell. */
grid_view_set_cell(gd, s->cx, s->cy, gc);
+
+ /* Move the cursor. */
+ screen_write_save(ctx);
+ s->cx += width;
+
+ /* Draw to the screen if necessary. */
if (screen_check_selection(s, s->cx, s->cy)) {
memcpy(&tc, &s->sel.cell, sizeof tc);
tc.data = gc->data;
tty_write_cmd(ctx->wp, TTY_CELL, &tc);
} else
tty_write_cmd(ctx->wp, TTY_CELL, gc);
-
- /* Move the cursor. */
- s->cx += width;
}
diff --git a/tmux.h b/tmux.h
index 19980417..6a5a259c 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.266 2009-02-11 07:02:34 nicm Exp $ */
+/* $Id: tmux.h,v 1.267 2009-02-11 17:04:39 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -496,9 +496,15 @@ struct screen {
u_int cx; /* cursor x */
u_int cy; /* cursor y */
+ u_int old_cx;
+ u_int old_cy;
+
u_int rupper; /* scroll region top */
u_int rlower; /* scroll region bottom */
+ u_int old_rupper;
+ u_int old_rlower;
+
int mode;
struct screen_sel sel;
@@ -1011,9 +1017,10 @@ void options_set_number(struct options *, const char *, long long);
long long options_get_number(struct options *, const char *);
/* tty.c */
+void tty_reset(struct tty *);
+void tty_region(struct tty *, u_int, u_int, u_int);
void tty_cursor(struct tty *, u_int, u_int, u_int);
-void tty_cell(struct tty *,
- struct screen *, u_int, const struct grid_cell *);
+void tty_cell(struct tty *, const struct grid_cell *);
void tty_putcode(struct tty *, enum tty_code_code);
void tty_putcode1(struct tty *, enum tty_code_code, int);
void tty_putcode2(struct tty *, enum tty_code_code, int, int);
diff --git a/tty.c b/tty.c
index 70ab6ff9..959a8d79 100644
--- a/tty.c
+++ b/tty.c
@@ -1,4 +1,4 @@
-/* $Id: tty.c,v 1.67 2009-02-11 07:02:34 nicm Exp $ */
+/* $Id: tty.c,v 1.68 2009-02-11 17:04:39 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,8 +35,6 @@ void tty_emulate_repeat(
void tty_raw(struct tty *, const char *);
-void tty_reset(struct tty *);
-void tty_region(struct tty *, struct screen *, u_int);
void tty_attributes(struct tty *, const struct grid_cell *);
void tty_attributes_fg(struct tty *, const struct grid_cell *);
void tty_attributes_bg(struct tty *, const struct grid_cell *);
@@ -399,7 +397,7 @@ tty_cmd_insertcharacter(struct tty *tty, struct window_pane *wp, va_list ap)
ua = va_arg(ap, u_int);
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
if (tty_term_has(tty->term, TTYC_ICH) ||
tty_term_has(tty->term, TTYC_ICH1))
@@ -409,7 +407,7 @@ tty_cmd_insertcharacter(struct tty *tty, struct window_pane *wp, va_list ap)
while (ua-- > 0)
tty_putc(tty, ' ');
tty_putcode(tty, TTYC_RMIR);
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx);
}
}
@@ -422,7 +420,7 @@ tty_cmd_deletecharacter(struct tty *tty, struct window_pane *wp, va_list ap)
ua = va_arg(ap, u_int);
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua);
}
@@ -436,8 +434,8 @@ tty_cmd_insertline(struct tty *tty, struct window_pane *wp, va_list ap)
ua = va_arg(ap, u_int);
tty_reset(tty);
- tty_region(tty, s, wp->yoff);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua);
}
@@ -451,8 +449,8 @@ tty_cmd_deleteline(struct tty *tty, struct window_pane *wp, va_list ap)
ua = va_arg(ap, u_int);
tty_reset(tty);
- tty_region(tty, s, wp->yoff);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua);
}
@@ -464,17 +462,17 @@ tty_cmd_clearline(struct tty *tty, struct window_pane *wp, unused va_list ap)
u_int i;
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
if (tty_term_has(tty->term, TTYC_EL)) {
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, 0);
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, 0);
tty_putcode(tty, TTYC_EL);
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx);
} else {
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, 0);
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, 0);
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx);
}
}
@@ -486,15 +484,15 @@ tty_cmd_clearendofline(
u_int i;
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
if (tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else {
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx);
- for (i = s->cx; i < screen_size_x(s); i++)
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx);
+ for (i = s->old_cx; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx);
}
}
@@ -506,15 +504,15 @@ tty_cmd_clearstartofline(
u_int i;
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
if (tty_term_has(tty->term, TTYC_EL1))
tty_putcode(tty, TTYC_EL1);
else {
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, 0);
- for (i = 0; i < s->cx + 1; i++)
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, 0);
+ for (i = 0; i < s->old_cx + 1; i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx);
}
}
@@ -524,8 +522,8 @@ tty_cmd_reverseindex(struct tty *tty, struct window_pane *wp, unused va_list ap)
struct screen *s = wp->screen;
tty_reset(tty);
- tty_region(tty, s, wp->yoff);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
tty_putcode(tty, TTYC_RI);
}
@@ -536,8 +534,8 @@ tty_cmd_linefeed(struct tty *tty, struct window_pane *wp, unused va_list ap)
struct screen *s = wp->screen;
tty_reset(tty);
- tty_region(tty, s, wp->yoff);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
tty_putc(tty, '\n');
tty->cy++;
@@ -553,23 +551,23 @@ tty_cmd_clearendofscreen(
oy = wp->yoff;
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, wp->yoff);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
if (tty_term_has(tty->term, TTYC_EL)) {
- for (i = oy + s->cy; i < oy + screen_size_y(s); i++) {
+ for (i = oy + s->old_cy; i < oy + screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1)
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
}
} else {
- for (i = s->cx; i < screen_size_y(s); i++)
+ for (i = s->old_cx; i < screen_size_y(s); i++)
tty_putc(tty, ' ');
- for (j = oy + s->cy; j < oy + screen_size_y(s); j++) {
+ for (j = oy + s->old_cy; j < oy + screen_size_y(s); j++) {
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
}
}
- tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, s->old_cx);
}
void
@@ -582,24 +580,24 @@ tty_cmd_clearstartofscreen(
oy = wp->yoff;
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, oy);
+ tty_cursor(tty, s->old_cx, s->old_cy, oy);
tty_putcode2(tty, TTYC_CUP, oy, 0);
if (tty_term_has(tty->term, TTYC_EL)) {
- for (i = 0; i < oy + s->cy; i++) {
+ for (i = 0; i < oy + s->old_cy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
}
- tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
+ tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, 0);
} else {
- for (j = 0; j < oy + s->cy; j++) {
+ for (j = 0; j < oy + s->old_cy; j++) {
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
}
}
- for (i = 0; i < s->cx; i++)
+ for (i = 0; i < s->old_cx; i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, s->old_cx);
}
void
@@ -612,7 +610,7 @@ tty_cmd_clearscreen(
oy = wp->yoff;
tty_reset(tty);
- tty_cursor(tty, s->cx, s->cy, oy);
+ tty_cursor(tty, s->old_cx, s->old_cy, oy);
tty_putcode2(tty, TTYC_CUP, oy, 0);
if (tty_term_has(tty->term, TTYC_EL)) {
@@ -627,28 +625,28 @@ tty_cmd_clearscreen(
tty_putc(tty, ' ');
}
}
- tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, s->old_cx);
}
void
tty_cmd_cell(struct tty *tty, struct window_pane *wp, va_list ap)
{
+ struct screen *s = wp->screen;
struct grid_cell *gc;
gc = va_arg(ap, struct grid_cell *);
- tty_cell(tty, wp->screen, wp->yoff, gc);
+ tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
+
+ tty_cell(tty, gc);
}
void
-tty_cell(
- struct tty *tty, struct screen *s, u_int oy, const struct grid_cell *gc)
+tty_cell(struct tty *tty, const struct grid_cell *gc)
{
u_int i, width;
u_char out[4];
- tty_cursor(tty, s->cx, s->cy, oy);
-
/* If this is a padding character, do nothing. */
if (gc->flags & GRID_FLAG_PADDING)
return;
@@ -697,11 +695,11 @@ tty_reset(struct tty *tty)
}
void
-tty_region(struct tty *tty, struct screen *s, u_int oy)
+tty_region(struct tty *tty, u_int rupper, u_int rlower, u_int oy)
{
- if (tty->rlower != oy + s->rlower || tty->rupper != oy + s->rupper) {
- tty->rlower = oy + s->rlower;
- tty->rupper = oy + s->rupper;
+ if (tty->rlower != oy + rlower || tty->rupper != oy + rupper) {
+ tty->rlower = oy + rlower;
+ tty->rupper = oy + rupper;
tty->cx = 0;
tty->cy = 0;
tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower);