getout = 1;
}
-int my_custom_handler(RoteTerm *rt __attribute__((unused)), const char *es)
-{
- int color;
- int i, j;
-
- /* if the escape sequence does not begin with '{', we give up */
- if (*es != '{') return ROTE_HANDLERESULT_NOWAY;
-
- /* ok, now we know it begins with '{'. Now, if it does not end with '}',
- * it is not yet complete */
- if (es[strlen(es)-1] != '}') return ROTE_HANDLERESULT_NOTYET;
-
- /* ok, the sequence is complete */
- color = atoi(es + 1);
- if (color < 0 || color > 7) return false; /* don't recognize it */
-
- /* paint the background with that color */
- attrset(COLOR_PAIR(color * 8));
- move(0, 0);
- for (i = 0; i < screen_h; i++) for (j = 0; j < screen_w; j++) addch(' ');
- touchwin(stdscr);
- refresh();
-
- /* touch term_win to force it to do a full redraw next time */
- touchwin(term_win);
-
- /* and redraw the terminal window */
- wrefresh(term_win);
-
- /* escape sequence was handled ok */
- return ROTE_HANDLERESULT_OK;
-}
-
int main(int argc, char *argv[])
{
RoteTerm *rt;
rt = rote_vt_create(h, w);
rote_vt_forkpty(rt, "/bin/bash --login");
- /* add a sample custom escape sequence handler... say we want to handle
- * the sequence, say, \e{N}, which will change the application's background
- * color to N (where N is a number between 0 and 7). */
- rote_vt_install_handler(rt, my_custom_handler);
-
/* keep reading keypresses from the user and passing them to the terminal;
* also, redraw the terminal to the window at each iteration */
ch = '\0';
static inline void clamp_cursor_to_bounds(RoteTerm *rt)
{
- if (rt->crow < 0) rt->curpos_dirty = true, rt->crow = 0;
- if (rt->ccol < 0) rt->curpos_dirty = true, rt->ccol = 0;
-
- if (rt->crow >= rt->rows)
- rt->curpos_dirty = true, rt->crow = rt->rows - 1;
+ if (rt->crow < 0) {
+ rt->curpos_dirty = true;
+ rt->crow = 0;
+ }
+ if (rt->ccol < 0) {
+ rt->curpos_dirty = true;
+ rt->ccol = 0;
+ }
- if (rt->ccol >= rt->cols)
- rt->curpos_dirty = true, rt->ccol = rt->cols - 1;
+ if (rt->crow >= rt->rows) {
+ rt->curpos_dirty = true;
+ rt->crow = rt->rows - 1;
+ }
+ if (rt->ccol >= rt->cols) {
+ rt->curpos_dirty = true;
+ rt->ccol = rt->cols - 1;
+ }
}
static void cursor_line_down(RoteTerm *rt)
/* clear first row of the scrolling region */
for (i = 0; i < rt->cols; i++) {
- rt->cells[rt->pd->scrolltop][i].ch = 0x20;
+ rt->cells[rt->pd->scrolltop][i].ch = 0x20;
rt->cells[rt->pd->scrolltop][i].attr = 0x70;
}
}
-static inline void put_normal_char(RoteTerm *rt, char c)
+static inline void put_normal_char(RoteTerm *rt, int c)
{
if (rt->ccol >= rt->cols) {
rt->ccol = 0;
rt->curpos_dirty = true;
}
-static inline void put_graphmode_char(RoteTerm *rt, char c)
+static inline void put_graphmode_char(RoteTerm *rt, int c)
{
char nc;
/* do some very pitiful translation to regular ascii chars */
break;
case '\n': /* line feed */
- rt->ccol = 0; cursor_line_down(rt);
+ rt->ccol = 0;
+ cursor_line_down(rt);
rt->curpos_dirty = true;
break;
case '\b': /* backspace */
- if (rt->ccol > 0) rt->ccol--;
+ if (rt->ccol > 0)
+ rt->ccol--;
rt->curpos_dirty = true;
break;
case '\t': /* tab */
- rt->ccol += 8 - (rt->ccol % 8);
+ rt->ccol = (rt->ccol + 8) & ~7;
clamp_cursor_to_bounds(rt);
break;
}
}
-static inline bool is_valid_csi_ender(char c)
+static inline bool is_valid_csi_ender(int c)
{
return (c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
char firstchar = rt->pd->esbuf[0];
char lastchar = rt->pd->esbuf[rt->pd->esbuf_len-1];
- if (!firstchar) return; /* too early to do anything */
-
- if (rt->pd->handler) {
- /* call custom handler */
-
- int answer = (*(rt->pd->handler))(rt, rt->pd->esbuf);
- if (answer == ROTE_HANDLERESULT_OK) {
- /* successfully handled */
-
- cancel_escape_sequence(rt);
- return;
- } else
- if (answer == ROTE_HANDLERESULT_NOTYET) {
- /* handler might handle it when more characters are appended to
- * it. So for now we don't interpret it */
- return;
- }
-
- /* If we got here then answer == ROTE_HANDLERESULT_NOWAY */
- /* handler said it can't handle that escape sequence,
- * but we can still try handling it ourselves, so
- * we proceed normally. */
- }
+ if (!firstchar)
+ return; /* too early to do anything */
/* interpret ESC-M as reverse line-feed */
if (firstchar == 'M') {
}
}
-void rote_vt_install_handler(RoteTerm *rt, rote_es_handler_t handler)
-{
- rt->pd->handler = handler;
-}
-
void *rote_vt_take_snapshot(RoteTerm *rt)
{
const int bytes_per_row = sizeof(RoteCell) * rt->cols;
* needed, e.g. on a call to rote_vt_forkpty. */
int rote_vt_get_pty_fd(RoteTerm *rt);
-/* Declaration of custom escape sequence callback type. See the
- * rote_vt_add_es_handler function for more info */
-typedef int (*rote_es_handler_t)(RoteTerm *rt, const char *es);
-
-/* Installs a custom escape sequence handler for the given RoteTerm.
- * The handler will be called by the library every time it tries to
- * recognize an escape sequence; depending on the return value of the
- * handler, it will proceed in a different manner. See the description
- * of the possible return values (ROTE_HANDLERESULT_* constants) below
- * for more info.
- *
- * This handler will be called EACH TIME THE ESCAPE SEQUENCE BUFFER
- * RECEIVES A CHARACTER. Therefore, it must execute speedily in order
- * not to create too heavy a performance penalty. In particular, the
- * writer of the handler should take care to quickly test for invalid
- * or incomplete escape sequences before trying to do more elaborate
- * parsing.
- *
- * The handler will NOT be called with an empty escape sequence (i.e.
- * one in which only the initial ESC was received).
- *
- * The custom handler receives the terminal it pertains to and the
- * escape sequence as a string (without the initial escape character).
- *
- * The handler may of course modify the terminal as it sees fit, taking
- * care not to corrupt it of course (in particular, it should appropriately
- * raise the line_dirty[] and curpos_dirty flags to indicate what it has
- * changed).
- */
-void rote_vt_install_handler(RoteTerm *rt, rote_es_handler_t handler);
-
-/* Possible return values for the custom handler function and their
- * meanings: */
-#define ROTE_HANDLERESULT_OK 0 /* means escape sequence was handled */
-
-#define ROTE_HANDLERESULT_NOTYET 1 /* means the escape sequence was not
- * recognized yet, but there is hope that
- * it still will once more characters
- * arrive (i.e. it is not yet complete).
- *
- * The library will thus continue collecting
- * characters and calling the handler as
- * each character arrives until
- * either OK or NOWAY is returned.
- */
-
-#define ROTE_HANDLERESULT_NOWAY 2 /* means the escape sequence was not
- * recognized, and there is no chance
- * that it will even if more characters
- * are added to it. */
-
#endif /* MADTTY_MADTTY_H */
int pty; /* file descriptor for the pty attached to
* this terminal. -1 if none. */
-
- /* custom escape sequence handler */
- rote_es_handler_t handler;
};
/* Interprets a CSI escape sequence stored in rt->pd->esbuf,