diff --git a/README b/README index 29020d41..bdafdc72 100644 --- a/README +++ b/README @@ -54,7 +54,7 @@ Shift+Keypad-Multiply = Reset font size to 10 Shift+Keypad-Divide = Copy highlight to Clipboard (same as ctrl+c in gui apps) Ctrl+PgUp = switch focus to previous terminal inside a window Ctrl+PgDn = switch focus to next terminal inside a window -Ctrl+t = create new terminal on top of current inside window (tabs) (not implemented) +Ctrl+Shift+t = create new terminal on top of current inside window (tabs) (not implemented) Ctrl+Shift+PgUp = split terminal horizontally (1 term above the other) Ctrl+Shift+PgDn = split terminal vertically (1 term to the left of the other) Alt+Home = Enter command mode (enter commands to control terminology itself) @@ -123,3 +123,11 @@ at[on/true/yes/off/false/no] ap[on/true/yes/off/false/no] = set the terminal alpha state to be on, or off permanently +qs + = query grid and font size. stdin will have written to it: + W;H;FW;FH\n + where W is the width of the terminal grid in characters + where H is the height of the terminal grid in characters + where FW is the width of 1 character cell in pixels + where FH is the height of 1 character cell in pixels + diff --git a/configure.ac b/configure.ac index 472e158a..72edef04 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,7 @@ requirements="\ eet >= 1.7.0 \ evas >= 1.7.0 \ ecore >= 1.7.0 \ + ecore-evas >= 1.7.0 \ edje >= 1.7.0 \ emotion >= 1.7.0 \ ecore-input >= 1.7.0 \ diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 4a0f218b..b0134821 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = Makefile.in -bin_PROGRAMS = terminology +bin_PROGRAMS = terminology tcat terminology_CPPFLAGS = -I. \ -DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \ @@ -38,3 +38,11 @@ termptyext.c termptyext.h \ utf8.c utf8.h \ win.c win.h \ utils.c utils.h + +tcat_SOURCES = tcat.c + +tcat_CPPFLAGS = -I. \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(pkgdatadir)\" @TERMINOLOGY_CFLAGS@ + +tcat_LDADD = @TERMINOLOGY_LIBS@ diff --git a/src/bin/media.c b/src/bin/media.c index f882f27f..aedfa150 100644 --- a/src/bin/media.c +++ b/src/bin/media.c @@ -158,7 +158,7 @@ _type_img_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ { int iw = 1, ih = 1; - if (sd->mode == MEDIA_BG) + if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_BG) { iw = w; ih = (sd->ih * w) / sd->iw; @@ -169,7 +169,7 @@ _type_img_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ if (iw < w) iw = w; } } - else if (sd->mode == MEDIA_POP) + else if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_POP) { iw = w; ih = (sd->ih * w) / sd->iw; @@ -185,6 +185,11 @@ _type_img_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ ih = sd->ih; } } + else if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_STRETCH) + { + iw = w; + ih = h; + } x += ((w - iw) / 2); y += ((h - ih) / 2); w = iw; @@ -247,7 +252,7 @@ _type_scale_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Eva { int iw = 1, ih = 1; - if (sd->mode == MEDIA_BG) + if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_BG) { iw = w; ih = (sd->ih * w) / sd->iw; @@ -258,7 +263,7 @@ _type_scale_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Eva if (iw < w) iw = w; } } - else if (sd->mode == MEDIA_POP) + else if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_POP) { iw = w; ih = (sd->ih * w) / sd->iw; @@ -269,6 +274,11 @@ _type_scale_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Eva if (iw > w) iw = w; } } + else if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_STRETCH) + { + iw = w; + ih = h; + } x += ((w - iw) / 2); y += ((h - ih) / 2); w = iw; @@ -514,6 +524,9 @@ _type_mov_init(Evas_Object *obj) evas_object_smart_callback_add(o, "ref_change", _cb_mov_ref, obj); emotion_object_file_set(o, sd->realf); + if (((sd->mode & MEDIA_OPTIONS_MASK) & MEDIA_RECOVER) + && (sd->type == TYPE_MOV) && (sd->o_img)) + emotion_object_last_position_load(sd->o_img); evas_object_smart_member_add(o, obj); evas_object_clip_set(o, sd->clip); @@ -568,7 +581,7 @@ _type_mov_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ if (ratio > 0.0) sd->iw = (sd->ih * ratio) + 0.5; else ratio = (double)sd->iw / (double)sd->ih; - if (sd->mode == MEDIA_BG) + if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_BG) { iw = w; ih = w / ratio; @@ -579,7 +592,7 @@ _type_mov_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ if (iw < w) iw = w; } } - else if (sd->mode == MEDIA_POP) + else if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_POP) { iw = w; ih = w / ratio; @@ -590,6 +603,11 @@ _type_mov_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ if (iw > w) iw = w; } } + else if ((sd->mode & MEDIA_SIZE_MASK) == MEDIA_STRETCH) + { + iw = w; + ih = h; + } x += ((w - iw) / 2); y += ((h - ih) / 2); w = iw; @@ -624,6 +642,9 @@ _smart_del(Evas_Object *obj) { Media *sd = evas_object_smart_data_get(obj); if (!sd) return; + if (((sd->mode & MEDIA_OPTIONS_MASK) & MEDIA_SAVE) + && (sd->type == TYPE_MOV) && (sd->o_img)) + emotion_object_last_position_save(sd->o_img); if (sd->url) { ecore_event_handler_del(sd->url_prog_hand); diff --git a/src/bin/media.h b/src/bin/media.h index 8d99e93b..7a238a24 100644 --- a/src/bin/media.h +++ b/src/bin/media.h @@ -1,8 +1,15 @@ #ifndef _MEDIA_H__ #define _MEDIA_H__ 1 -#define MEDIA_BG 0 -#define MEDIA_POP 1 +#define MEDIA_SIZE_MASK 0x000f +#define MEDIA_OPTIONS_MASK 0x00f0 +// enum list types +#define MEDIA_BG 0x0000 +#define MEDIA_POP 0x0001 +#define MEDIA_STRETCH 0x0002 +// bitmask for options - on or off +#define MEDIA_RECOVER 0x0010 +#define MEDIA_SAVE 0x0020 #define TYPE_UNKNOWN -1 #define TYPE_IMG 0 diff --git a/src/bin/tcat.c b/src/bin/tcat.c new file mode 100644 index 00000000..6797db49 --- /dev/null +++ b/src/bin/tcat.c @@ -0,0 +1,147 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + CENTER, + FILL, + STRETCH +}; + +Ecore_Evas *ee = NULL; +Evas *evas = NULL; +Evas_Object *o = NULL; +struct termios told, tnew; +int tw = 0, th = 0, cw = 0, ch = 0; +int w = 0, h = 0; +int iw = 0, ih = 0; + +static int +echo_off(void) +{ + if (tcgetattr(0, &told) != 0) return -1; + tnew = told; + tnew.c_lflag &= ~ECHO; + if (tcsetattr(0, TCSAFLUSH, &tnew) != 0) return -1; + return 0; +} + +static int +echo_on(void) +{ + return tcsetattr(0, TCSAFLUSH, &told); +} + +int +main(int argc, char **argv) +{ + char buf[8192]; + + if (!getenv("TERMINOLOGY")) return 0; + if (argc <= 1) + { + printf("Usage: %s [-s|-f|-c] FILE1 [FILE2 ...]\n" + "\n" + " -s Stretch file to fill nearest character cell size\n" + " -f Fill file to totally cover character cells with no gaps\n" + " -c Center file in nearest character cells but only scale down (default)\n", + argv[0]); + return 0; + } + eina_init(); + ecore_init(); + evas_init(); + ecore_evas_init(); + ee = ecore_evas_buffer_new(1, 1); + if (ee) + { + int i, mode = CENTER; + + evas = ecore_evas_get(ee); + o = evas_object_image_add(evas); + for (i = 1; i < argc; i++) + { + char *path; + + if (!strcmp(argv[i], "-c")) + { + mode = CENTER; + i++; + if (i >= argc) return 0; + } + else if (!strcmp(argv[i], "-s")) + { + mode = STRETCH; + i++; + if (i >= argc) return 0; + } + else if (!strcmp(argv[i], "-f")) + { + mode = FILL; + i++; + if (i >= argc) return 0; + } + + path = argv[i]; + evas_object_image_file_set(o, path, NULL); + evas_object_image_size_get(o, &w, &h); + if ((w >= 0) && (h > 0)) + { + int x, y; + + echo_off(); + snprintf(buf, sizeof(buf), "%c}qs", 0x1b); + write(0, buf, strlen(buf) + 1); + if (scanf("%i;%i;%i;%i", &tw, &th, &cw, &ch) != 4) + { + echo_on(); + continue; + } + echo_on(); + if ((tw <= 0) || (th <= 0) || (cw <= 1) || (ch <= 1)) + continue; + if (w > (tw * cw)) + { + iw = tw; + ih = ((h * (tw * cw) / w) + (ch - 1)) / ch; + } + else + { + iw = (w + (cw - 1)) / cw; + ih = (h + (ch - 1)) / ch; + } + if (mode == CENTER) + snprintf(buf, sizeof(buf), "%c}ic%i;%i;%s", + 0x1b, iw, ih, path); + else if (mode == FILL) + snprintf(buf, sizeof(buf), "%c}if%i;%i;%s", + 0x1b, iw, ih, path); + else + snprintf(buf, sizeof(buf), "%c}is%i;%i;%s", + 0x1b, iw, ih, path); + write(0, buf, strlen(buf) + 1); + for (y = 0; y < ih; y++) + { + for (x = 0; x < iw; x++) + { + write(0, "#", 1); + } + write(0, "\n", 1); + } + } + } +// ecore_main_loop_begin(); + ecore_evas_free(ee); + } + ecore_evas_shutdown(); + evas_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return 0; +} diff --git a/src/bin/termio.c b/src/bin/termio.c index ba53deba..585fc156 100644 --- a/src/bin/termio.c +++ b/src/bin/termio.c @@ -388,11 +388,18 @@ _smart_apply(Evas_Object *obj) { Termio *sd = evas_object_smart_data_get(obj); Evas_Coord ox, oy, ow, oh; + Eina_List *l, *ln; + Termblock *blk; int j, x, y, w, ch1 = 0, ch2 = 0, inv = 0; if (!sd) return; evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); - + + EINA_LIST_FOREACH(sd->pty->block.active, l, blk) + { + blk->was_active = blk->active; + blk->active = EINA_FALSE; + } inv = sd->pty->state.reverse; for (y = 0; y < sd->grid.h; y++) { @@ -428,7 +435,67 @@ _smart_apply(Evas_Object *obj) } else { - if (cells[j].att.invisible) + int bid, bx = 0, by = 0; + + bid = termpty_block_id_get(&(cells[j]), &bx, &by); + if (bid >= 0) + { + if (ch1 < 0) ch1 = x; + ch2 = x; + tc[x].codepoint = 0; + tc[x].fg_extended = 0; + tc[x].bg_extended = 0; + tc[x].underline = 0; + tc[x].strikethrough = 0; + tc[x].fg = COL_INVIS; + tc[x].bg = COL_INVIS; +#if defined(SUPPORT_DBLWIDTH) + tc[x].double_width = 0; +#endif + blk = termpty_block_get(sd->pty, bid); + if (blk) + { + if (!blk->active) + { + blk->active = EINA_TRUE; + if (!blk->obj) + { + int type = 0; + int media = MEDIA_STRETCH; + + if (blk->scale_stretch) + media = MEDIA_STRETCH; + else if (blk->scale_center) + media = MEDIA_POP; + else if (blk->scale_fill) + media = MEDIA_BG; + if (!blk->was_active_before) + media |= MEDIA_SAVE; + else + media |= MEDIA_RECOVER | MEDIA_SAVE; + blk->obj = media_add(obj, blk->path, + sd->config, + media, &type); + blk->type = type; + evas_object_smart_member_add(blk->obj, obj); + evas_object_stack_above(blk->obj, sd->grid.obj); + evas_object_show(blk->obj); + } + blk->was_active_before = EINA_TRUE; + if (!blk->was_active) + sd->pty->block.active = eina_list_append(sd->pty->block.active, blk); + } + blk->x = (x - bx); + blk->y = (y - by); + evas_object_move(blk->obj, + ox + (blk->x * sd->font.chw), + oy + (blk->y * sd->font.chh)); + evas_object_resize(blk->obj, + blk->w * sd->font.chw, + blk->h * sd->font.chh); + } + } + else if (cells[j].att.invisible) { if ((tc[x].codepoint != 0) || (tc[x].bg != COL_INVIS) || @@ -546,6 +613,21 @@ _smart_apply(Evas_Object *obj) ch2 - ch1 + 1, 1); } + EINA_LIST_FOREACH_SAFE(sd->pty->block.active, l, ln, blk) + { + if (!blk->active) + { + blk->was_active = EINA_FALSE; + if (blk->obj) + { + evas_object_del(blk->obj); + blk->obj = NULL; + } + sd->pty->block.active = eina_list_remove_list + (sd->pty->block.active, l); + } + } + if ((sd->scroll != 0) || (sd->pty->state.hidecursor)) evas_object_hide(sd->cur.obj); else @@ -992,11 +1074,6 @@ _smart_cb_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, evas_object_smart_callback_call(data, "next", NULL); goto end; } - else if (!strcmp(ev->keyname, "t")) - { - evas_object_smart_callback_call(data, "new", NULL); - goto end; - } } if ((!evas_key_modifier_is_set(ev->modifiers, "Alt")) && (evas_key_modifier_is_set(ev->modifiers, "Control")) && @@ -1012,6 +1089,11 @@ _smart_cb_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, evas_object_smart_callback_call(data, "split,v", NULL); goto end; } + else if (!strcmp(ev->keyname, "t")) + { + evas_object_smart_callback_call(data, "new", NULL); + goto end; + } } if ((evas_key_modifier_is_set(ev->modifiers, "Alt")) && (!evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -2521,6 +2603,67 @@ _smart_pty_command(void *data) sd = evas_object_smart_data_get(obj); if (!sd) return; if (!sd->pty->cur_cmd) return; + if (sd->pty->cur_cmd[0] == 'i') + { + if ((sd->pty->cur_cmd[1] == 's') || + (sd->pty->cur_cmd[1] == 'c') || + (sd->pty->cur_cmd[1] == 'f')) + { + const char *p, *p0, *path; + int ww = 0, hh = 0; + + // exact size in CHAR CELLS - WW (decimal) width CELLS, + // HH (decimal) in CELLS. + // + // isWW;HH;PATH + for (p0 = p = &(sd->pty->cur_cmd[2]); *p; p++) + { + if (*p == ';') + { + ww = strtol(p0, NULL, 10); + p++; + break; + } + } + for (p0 = p; *p; p++) + { + if (*p == ';') + { + hh = strtol(p0, NULL, 10); + p++; + break; + } + } + path = p; + if ((ww < 512) && (hh < 512)) + { + Termblock *blk = termpty_block_new(sd->pty, ww, hh, path); + if (blk) + { + if (sd->pty->cur_cmd[1] == 's') + blk->scale_stretch = EINA_TRUE; + else if (sd->pty->cur_cmd[1] == 'c') + blk->scale_center = EINA_TRUE; + else if (sd->pty->cur_cmd[1] == 'f') + blk->scale_fill = EINA_TRUE; + termpty_block_insert(sd->pty, blk); + } + } + return; + } + } + else if (sd->pty->cur_cmd[0] == 'q') + { + if (sd->pty->cur_cmd[1] == 's') + { + char buf[256]; + + snprintf(buf, sizeof(buf), "%i;%i;%i;%i\n", + sd->grid.w, sd->grid.h, sd->font.chw, sd->font.chh); + termpty_write(sd->pty, buf, strlen(buf)); + return; + } + } evas_object_smart_callback_call(obj, "command", (void *)sd->pty->cur_cmd); } diff --git a/src/bin/termpty.c b/src/bin/termpty.c index 36f35d26..77402d64 100644 --- a/src/bin/termpty.c +++ b/src/bin/termpty.c @@ -377,6 +377,8 @@ err: void termpty_free(Termpty *ty) { + if (ty->block.blocks) eina_hash_free(ty->block.blocks); + if (ty->block.active) eina_list_free(ty->block.active); if (ty->fd >= 0) close(ty->fd); if (ty->slavefd >= 0) close(ty->slavefd); if (ty->pid >= 0) @@ -548,3 +550,78 @@ termpty_pid_get(const Termpty *ty) { return ty->pid; } + +void +termpty_block_free(Termblock *tb) +{ + if (tb->path) eina_stringshare_del(tb->path); + if (tb->obj) evas_object_del(tb->obj); + free(tb); +} + +Termblock * +termpty_block_new(Termpty *ty, int w, int h, const char *path) +{ + Termblock *tb; + int id; + + id = ty->block.curid; + if (!ty->block.blocks) + ty->block.blocks = eina_hash_int32_new((Eina_Free_Cb)termpty_block_free); + if (!ty->block.blocks) return NULL; + tb = eina_hash_find(ty->block.blocks, &id); + if (tb) + { + if (tb->active) + ty->block.active = eina_list_remove(ty->block.active, tb); + eina_hash_del(ty->block.blocks, &id, tb); + } + tb = calloc(1, sizeof(Termblock)); + if (!tb) return NULL; + tb->id = id; + tb->w = w; + tb->h = h; + tb->path = eina_stringshare_add(path); + eina_hash_add(ty->block.blocks, &id, tb); + ty->block.curid++; + if (ty->block.curid >= 8192) ty->block.curid = 0; + return tb; +} + +void +termpty_block_insert(Termpty *ty, Termblock *blk) +{ + // bit 0-8 = y (9b 0->511) + // bit 9-17 = x (9b 0->511) + // bit 18-30 = id (13b 0->8191) + // bit 31 = 1 + // + // fg/bg = 8+8bit unused. (use for extra id bits? so 16 + 13 == 29bit?) + // + // cp = (1 << 31) | ((id 0x1fff) << 18) | ((x & 0x1ff) << 9) | (y & 0x1ff); + + ty->block.expecting.left = blk->w * blk->h; + ty->block.expecting.x = 0; + ty->block.expecting.y = 0; + ty->block.expecting.id = blk->id; + ty->block.expecting.w = blk->w; + ty->block.expecting.h = blk->h; +} + +int +termpty_block_id_get(Termcell *cell, int *x, int *y) +{ + int id; + + if (!(cell->codepoint & 0x80000000)) return -1; + id = (cell->codepoint >> 18) & 0x1fff; + *x = (cell->codepoint >> 9) & 0x1ff; + *y = cell->codepoint & 0x1ff; + return id; +} + +Termblock * +termpty_block_get(Termpty *ty, int id) +{ + return eina_hash_find(ty->block.blocks, &id); +} diff --git a/src/bin/termpty.h b/src/bin/termpty.h index 4e91db0d..54f93ad9 100644 --- a/src/bin/termpty.h +++ b/src/bin/termpty.h @@ -3,6 +3,7 @@ typedef struct _Termcell Termcell; typedef struct _Termatt Termatt; typedef struct _Termstate Termstate; typedef struct _Termsave Termsave; +typedef struct _Termblock Termblock; #define COL_DEF 0 #define COL_BLACK 1 @@ -96,22 +97,30 @@ struct _Termpty } change, scroll, set_title, set_icon, cancel_sel, exited, bell, command; } cb; struct { - const char *title; - const char *icon; + const char *title, *icon; } prop; - int w, h; - int fd, slavefd; - pid_t pid; const char *cur_cmd; Termcell *screen, *screen2; Termsave **back; + int *buf; + int buflen; + int w, h; + int fd, slavefd; int circular_offset; int backmax, backpos; int backscroll_num; - int *buf; - int buflen; + struct { + int curid; + Eina_Hash *blocks; + Eina_List *active; + struct { + int left, id; + int x, y, w, h; + } expecting; + } block; Termstate state, save, swap; int exit_code; + pid_t pid; unsigned int altbuf : 1; unsigned int mouse_mode : 3; unsigned int mouse_ext : 2; @@ -129,17 +138,39 @@ struct _Termsave Termcell cell[1]; }; -void termpty_init(void); -void termpty_shutdown(void); +struct _Termblock +{ + int id; + int type; + short w, h; + short x, y; + const char *path; + Evas_Object *obj; + Eina_Bool scale_stretch : 1; + Eina_Bool scale_center : 1; + Eina_Bool scale_fill : 1; + + Eina_Bool active : 1; + Eina_Bool was_active : 1; + Eina_Bool was_active_before : 1; +}; -Termpty *termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd, int w, int h, int backscroll); -void termpty_free(Termpty *ty); -Termcell *termpty_cellrow_get(Termpty *ty, int y, int *wret); -void termpty_write(Termpty *ty, const char *input, int len); -void termpty_resize(Termpty *ty, int w, int h); -void termpty_backscroll_set(Termpty *ty, int size); +void termpty_init(void); +void termpty_shutdown(void); -pid_t termpty_pid_get(const Termpty *ty); +Termpty *termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd, int w, int h, int backscroll); +void termpty_free(Termpty *ty); +Termcell *termpty_cellrow_get(Termpty *ty, int y, int *wret); +void termpty_write(Termpty *ty, const char *input, int len); +void termpty_resize(Termpty *ty, int w, int h); +void termpty_backscroll_set(Termpty *ty, int size); + +pid_t termpty_pid_get(const Termpty *ty); +void termpty_block_free(Termblock *tb); +Termblock *termpty_block_new(Termpty *ty, int w, int h, const char *path); +void termpty_block_insert(Termpty *ty, Termblock *blk); +int termpty_block_id_get(Termcell *cell, int *x, int *y); +Termblock *termpty_block_get(Termpty *ty, int id); extern int _termpty_log_dom; diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index 0c692ab2..ce0d5b3c 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c @@ -1310,7 +1310,33 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, Eina_Unicode *ce) if (len == 0) return 0; return 1 + len; } - + else if (ty->block.expecting.left > 0) + { + if (c[0] == '#') + { + Eina_Unicode cp; + + cp = (1 << 31) | + ((ty->block.expecting.id & 0x1fff) << 18) | + ((ty->block.expecting.x & 0x1ff) << 9) | + (ty->block.expecting.y & 0x1ff); + ty->block.expecting.x++; + if (ty->block.expecting.x >= ty->block.expecting.w) + { + ty->block.expecting.x = 0; + ty->block.expecting.y++; + } + ty->block.expecting.left--; + _termpty_text_append(ty, &cp, 1); + return 1; + } + else + { + _termpty_text_append(ty, c, 1); + ty->state.had_cr = 0; + return 1; + } + } cc = (int *)c; DBG("txt: ["); while ((cc < ce) && (*cc >= 0x20) && (*cc != 0x7f))