/* clear last row of the scrolling region */
for (i = 0; i < rt->cols; i++) {
- rt->cells[rt->pd->scrollbottom][i].ch = 0x20;
+ rt->cells[rt->pd->scrollbottom][i].ch = 0x20;
rt->cells[rt->pd->scrollbottom][i].attr = 0x70;
}
}
if (rt->insert) {
int i;
- for(i = rt->cols - 1; i >= rt->ccol+1; i--)
+ for(i = rt->cols - 1; i >= rt->ccol+1; i--) {
rt->cells[rt->crow][i] = rt->cells[rt->crow][i-1];
+ }
}
- rt->cells[rt->crow][rt->ccol].ch = c;
+ rt->cells[rt->crow][rt->ccol].ch = c;
rt->cells[rt->crow][rt->ccol].attr = rt->curattr;
rt->ccol++;
cancel_escape_sequence(rt);
}
-void rote_vt_inject(RoteTerm *rt, const char *data, int len)
+int rote_vt_inject(RoteTerm *rt, const char *data, int len)
{
- int i;
-
- for (i = 0; i < len; i++, data++) {
- if (*data == 0)
- continue; /* completely ignore NUL */
-
- if (*data >= 1 && *data <= 31) {
+ for (; len-- > 0; data++) {
+ if ((unsigned char)*data <= 31) {
handle_control_char(rt, *data);
continue;
}
put_normal_char(rt, *data);
}
}
+
+ return 0;
}
/****************************************************************************/
c <= (r == end_row ? end_col : rt->cols - 1);
c++)
{
- rt->cells[r][c].ch = 0x20;
+ rt->cells[r][c].ch = 0x20;
rt->cells[r][c].attr = rt->curattr;
}
}
}
for (i = erase_start; i <= erase_end; i++) {
- rt->cells[rt->crow][i].ch = 0x20;
+ rt->cells[rt->crow][i].ch = 0x20;
rt->cells[rt->crow][i].attr = rt->curattr;
}
}
for (i = rt->ccol; i < rt->ccol + n; i++) {
- rt->cells[rt->crow][i].ch = 0x20;
+ rt->cells[rt->crow][i].ch = 0x20;
rt->cells[rt->crow][i].attr = rt->curattr;
}
if (i + n < rt->cols) {
rt->cells[rt->crow][i] = rt->cells[rt->crow][i + n];
} else {
- rt->cells[rt->crow][i].ch = 0x20;
+ rt->cells[rt->crow][i].ch = 0x20;
rt->cells[rt->crow][i].attr = rt->curattr;
}
}
for (i = rt->crow; i < rt->crow + n && i <= rt->pd->scrollbottom; i++) {
rt->line_dirty[i] = true;
for (j = 0; j < rt->cols; j++) {
- rt->cells[i][j].ch = 0x20, rt->cells[i][j].attr = rt->curattr;
+ rt->cells[i][j].ch = 0x20;
+ rt->cells[i][j].attr = rt->curattr;
}
}
memcpy(rt->cells[i], rt->cells[i+n], sizeof(RoteCell) * rt->cols);
} else {
for (j = 0; j < rt->cols; j++) {
- rt->cells[i][j].ch = 0x20, rt->cells[i][j].attr = rt->curattr;
+ rt->cells[i][j].ch = 0x20;
+ rt->cells[i][j].attr = rt->curattr;
}
}
}
int i;
for (i = rt->ccol; i < rt->ccol + n && i < rt->cols; i++) {
- rt->cells[rt->crow][i].ch = 0x20;
+ rt->cells[rt->crow][i].ch = 0x20;
rt->cells[rt->crow][i].attr = rt->curattr;
}
if (ROTE_ATTR_BLINK(attr)) wattron(win, A_BLINK);
}
-static inline unsigned char ensure_printable(unsigned char ch)
+static inline unsigned char ensure_printable(unsigned int ch)
{
return ch >= 32 ? ch : 32;
}
return read(rt->pty, buf, buflen);
}
-void rote_vt_write(RoteTerm *rt, const char *data, int len)
+int rote_vt_write(RoteTerm *rt, const char *data, int len)
{
+ int res;
+
if (rt->pty < 0) {
- /* no pty, so just inject the data plain and simple */
- rote_vt_inject(rt, data, len);
- return;
+ errno = EINVAL;
+ return -1;
}
- /* write data to pty. Keep calling write() until we have written
- * everything. */
- while (len > 0) {
- int byteswritten = write(rt->pty, data, len);
- if (byteswritten < 0) {
- /* very ugly way to inform the error. Improvements welcome! */
- static char errormsg[] = "\n(ROTE: pty write() error)\n";
- rote_vt_inject(rt, errormsg, strlen(errormsg));
- return;
- }
-
- data += byteswritten;
- len -= byteswritten;
+ again:
+ res = write(rt->pty, data, len);
+ if (res < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ goto again;
}
+
+ return res;
}
void *rote_vt_take_snapshot(RoteTerm *rt)
void rote_vt_keypress(RoteTerm *rt, int keycode)
{
- char c = (char) keycode;
+ char c = (char)keycode;
+ const char *buf;
+ int len;
if (keytable['\n'] == NULL)
keytable_init();
if (keycode >= 0 && keycode < KEY_MAX && keytable[keycode]) {
- rote_vt_write(rt, keytable[keycode], strlen(keytable[keycode]));
+ buf = keytable[keycode];
+ len = strlen(keytable[keycode]);
} else {
- rote_vt_write(rt, &c, 1); /* not special, just write it */
+ buf = &c;
+ len = 1;
+ }
+
+ while (len > 0) {
+ int res = rote_vt_write(rt, buf, len);
+ if (res < 0)
+ return;
+
+ buf += res;
+ len -= res;
}
}
void rote_vt_forsake_child(RoteTerm *rt);
int rote_vt_read(RoteTerm *rt, char *buf, int buflen);
-
-/* Puts data into the terminal: if there is a forked process running,
- * the data will be sent to it. If there is no forked process,
- * the data will simply be injected into the terminal (as in
- * rote_vt_inject) */
-void rote_vt_write(RoteTerm *rt, const char *data, int length);
+int rote_vt_write(RoteTerm *rt, const char *data, int length);
/* Inject data into the terminal. <data> needs NOT be 0-terminated:
* its length is solely determined by the <length> parameter. Please
* running in the terminal (if any). For that, you might want
* to use rote_vt_write.
*/
-void rote_vt_inject(RoteTerm *rt, const char *data, int length);
+int rote_vt_inject(RoteTerm *rt, const char *data, int length);
#ifdef USE_NCURSES
/* Paints the virtual terminal screen on the given window, putting