diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 40254450..6b8dd5ab 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -37,9 +37,12 @@ termptygfx.c termptygfx.h \ termptyext.c termptyext.h \ utf8.c utf8.h \ win.c win.h \ -utils.c utils.h +utils.c utils.h \ +extns.h -tycat_SOURCES = tycat.c +tycat_SOURCES = \ +tycat.c \ +extns.h tycat_CPPFLAGS = -I. \ -DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \ diff --git a/src/bin/extns.h b/src/bin/extns.h new file mode 100644 index 00000000..e65c8a3d --- /dev/null +++ b/src/bin/extns.h @@ -0,0 +1,39 @@ +static const char *extn_img[] = +{ + ".png", ".jpg", ".jpeg", ".jpe", ".jfif", ".tif", ".tiff", ".gif", + ".bmp", ".ico", ".ppm", ".pgm", ".pbm", ".pnm", ".xpm", ".psd", ".wbmp", + ".cur", ".xcf", ".xcf.gz", ".arw", ".cr2", ".crw", ".dcr", ".dng", ".k25", + ".kdc", ".erf", ".mrw", ".nef", ".nrf", ".nrw", ".orf", ".raw", ".rw2", + ".rw2", ".pef", ".raf", ".sr2", ".srf", ".x3f", ".webp", + NULL +}; + +static const char *extn_scale[] = +{ + ".svg", ".svgz", ".svg.gz", ".ps", ".ps.gz", ".pdf", + NULL +}; + +static const char *extn_edj[] = +{ + ".edj", + NULL +}; + +static const char *extn_mov[] = +{ + ".asf", ".avi", ".bdm", ".bdmv", ".clpi", ".cpi", ".dv", ".fla", ".flv", + ".m1v", ".m2t", ".m2v", ".m4v", ".mkv", ".mov", ".mp2", ".mp2ts", ".mp4", + ".mpe", ".mpeg", ".mpg", ".mpl", ".mpls", ".mts", ".mxf", ".nut", ".nuv", + ".ogg", ".ogm", ".ogv", ".qt", ".rm", ".rmj", ".rmm", ".rms", ".rmvb", + ".rmx", ".rv", ".swf", ".ts", ".weba", ".webm", ".wmv", ".3g2", ".3gp", + ".3gp2", ".3gpp", ".3gpp2", ".3p2", ".264", + ".mp3", ".aac", ".wav", + NULL +}; + +static const char *extn_aud[] = +{ + ".mp3", ".aac", ".wav", + NULL +}; diff --git a/src/bin/media.c b/src/bin/media.c index aedfa150..6d8740ca 100644 --- a/src/bin/media.c +++ b/src/bin/media.c @@ -38,39 +38,7 @@ struct _Media static Evas_Smart *_smart = NULL; static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL; -static const char *extn_img[] = -{ - ".png", ".jpg", ".jpeg", ".jpe", ".jfif", ".tif", ".tiff", ".gif", - ".bmp", ".ico", ".ppm", ".pgm", ".pbm", ".pnm", ".xpm", ".psd", ".wbmp", - ".cur", ".xcf", ".xcf.gz", ".arw", ".cr2", ".crw", ".dcr", ".dng", ".k25", - ".kdc", ".erf", ".mrw", ".nef", ".nrf", ".nrw", ".orf", ".raw", ".rw2", - ".rw2", ".pef", ".raf", ".sr2", ".srf", ".x3f", ".webp", - NULL -}; - -static const char *extn_scale[] = -{ - ".svg", ".svgz", ".svg.gz", ".ps", ".ps.gz", ".pdf", - NULL -}; - -static const char *extn_edj[] = -{ - ".edj", - NULL -}; - -static const char *extn_mov[] = -{ - ".asf", ".avi", ".bdm", ".bdmv", ".clpi", ".cpi", ".dv", ".fla", ".flv", - ".m1v", ".m2t", ".m2v", ".m4v", ".mkv", ".mov", ".mp2", ".mp2ts", ".mp4", - ".mpe", ".mpeg", ".mpg", ".mpl", ".mpls", ".mts", ".mxf", ".nut", ".nuv", - ".ogg", ".ogm", ".ogv", ".qt", ".rm", ".rmj", ".rmm", ".rms", ".rmvb", - ".rmx", ".rv", ".swf", ".ts", ".weba", ".webm", ".wmv", ".3g2", ".3gp", - ".3gp2", ".3gpp", ".3gpp2", ".3p2", ".264", - ".mp3", ".aac", ".wav", - NULL -}; +#include "extns.h" static const char * _is_fmt(const char *f, const char **extn) diff --git a/src/bin/termpty.c b/src/bin/termpty.c index 926be1f9..6cf0da56 100644 --- a/src/bin/termpty.c +++ b/src/bin/termpty.c @@ -514,10 +514,12 @@ termpty_resize(Termpty *ty, int w, int h) c1 = &(olds[y * oldw]); c2 = &(TERMPTY_SCREEN(ty, 0, y)); _termpty_text_copy(ty, c1, c2, ww); + termpty_cell_fill(ty, NULL, c1, ww); c1 = &(olds2[y * oldw]); c2 = &(ty->screen2[y * ty->w]); _termpty_text_copy(ty, c1, c2, ww); + termpty_cell_fill(ty, NULL, c1, ww); } ty->circular_offset = 0; @@ -634,5 +636,103 @@ termpty_block_id_get(Termcell *cell, int *x, int *y) Termblock * termpty_block_get(Termpty *ty, int id) { + if (!ty->block.blocks) return NULL; return eina_hash_find(ty->block.blocks, &id); } + + + + + +static void +_handle_block_codepoint_overwrite(Termpty *ty, int oldc, int newc) +{ + Termblock *tb; + int ido = 0, idn = 0; + + if (oldc & 0x80000000) ido = (oldc >> 18) & 0x1fff; + if (newc & 0x80000000) idn = (newc >> 18) & 0x1fff; + if (((oldc & 0x80000000) && (newc & 0x80000000)) && (idn == ido)) return; + + if (oldc & 0x80000000) + { + tb = termpty_block_get(ty, ido); + if (!tb) return; + tb->refs--; + if (tb->refs == 0) + { + if (tb->active) + ty->block.active = eina_list_remove(ty->block.active, tb); + eina_hash_del(ty->block.blocks, &ido, tb); + } + } + + if (newc & 0x80000000) + { + tb = termpty_block_get(ty, idn); + if (!tb) return; + tb->refs++; + } +} + +void +termpty_cell_copy(Termpty *ty, Termcell *src, Termcell *dst, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + _handle_block_codepoint_overwrite(ty, dst[i].codepoint, src[i].codepoint); + dst[i] = src[i]; + } +} + +void +termpty_cell_swap(Termpty *ty __UNUSED__, Termcell *src, Termcell *dst, int n) +{ + int i; + Termcell t; + + for (i = 0; i < n; i++) + { + t = dst[i]; + dst[i] = src[i]; + dst[i] = t; + } +} + +void +termpty_cell_fill(Termpty *ty, Termcell *src, Termcell *dst, int n) +{ + int i; + + if (src) + { + for (i = 0; i < n; i++) + { + _handle_block_codepoint_overwrite(ty, dst[i].codepoint, src[0].codepoint); + dst[i] = src[0]; + } + } + else + { + for (i = 0; i < n; i++) + { + _handle_block_codepoint_overwrite(ty, dst[i].codepoint, 0); + memset(&(dst[i]), 0, sizeof(*dst)); + } + } +} + +void +termpty_cell_codepoint_att_fill(Termpty *ty, int codepoint, Termatt att, Termcell *dst, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + _handle_block_codepoint_overwrite(ty, dst[i].codepoint, codepoint); + dst[i].codepoint = codepoint; + dst[i].att = att; + } +} diff --git a/src/bin/termpty.h b/src/bin/termpty.h index 3b4497ae..974d74fb 100644 --- a/src/bin/termpty.h +++ b/src/bin/termpty.h @@ -141,6 +141,7 @@ struct _Termblock { int id; int type; + int refs; short w, h; short x, y; const char *path; @@ -177,6 +178,11 @@ void termpty_block_insert(Termpty *ty, int ch, Termblock *blk); int termpty_block_id_get(Termcell *cell, int *x, int *y); Termblock *termpty_block_get(Termpty *ty, int id); +void termpty_cell_copy(Termpty *ty, Termcell *src, Termcell *dst, int n); +void termpty_cell_swap(Termpty *ty, Termcell *src, Termcell *dst, int n); +void termpty_cell_fill(Termpty *ty, Termcell *src, Termcell *dst, int n); +void termpty_cell_codepoint_att_fill(Termpty *ty, int codepoint, Termatt att, Termcell *dst, int n); + extern int _termpty_log_dom; #define TERMPTY_SCREEN(Tpty, X, Y) \ diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index 2fc7e49a..059e1a25 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c @@ -461,9 +461,9 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) for (x = ty->state.cx; x < (ty->w); x++) { if (x < lim) - cells[x] = cells[x + arg]; + termpty_cell_copy(ty, &(cells[x + arg]), &(cells[x]), 1); else - memset(&(cells[x]), 0, sizeof(*cells)); + termpty_cell_fill(ty, NULL, &(cells[x]), 1); } } break; @@ -702,13 +702,10 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) size = ty->w * ty->h; // swap screen content now for (i = 0; i < size; i++) - { - Termcell t; - - t = ty->screen[(i + ty->circular_offset) % ty->h]; - ty->screen[(i + ty->circular_offset) % ty->h] = ty->screen2[i]; - ty->screen2[i] = t; - } + termpty_cell_swap(ty, + &(ty->screen[(i + ty->circular_offset) % ty->h]), + &(ty->screen2[i]), + 1); ty->altbuf = !ty->altbuf; if (ty->cb.cancel_sel.func) ty->cb.cancel_sel.func(ty->cb.cancel_sel.data); @@ -963,10 +960,18 @@ static int _handle_esc_terminology(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) { Eina_Unicode *cc; - Eina_Unicode buf[4096], *b; + Eina_Unicode *buf, bufsmall[1024], *b; char *s; - int slen = 0; + int blen = 0, slen = 0; + cc = (Eina_Unicode *)c; + while ((cc < ce) && (*cc != 0x0)) + { + blen++; + cc++; + } + buf = bufsmall; + if (blen > (int)(sizeof(bufsmall) - 10)) buf = malloc(blen + 10); cc = (Eina_Unicode *)c; b = buf; while ((cc < ce) && (*cc != 0x0)) @@ -976,8 +981,12 @@ _handle_esc_terminology(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) cc++; } *b = 0; - if (*cc == 0x0) cc++; - else return 0; + if ((*cc == 0x0) && (cc < ce)) cc++; + else + { + if (buf != bufsmall) free(buf); + return 0; + } // commands are stored in the buffer, 0 bytes not allowd (end marker) s = eina_unicode_unicode_to_utf8(buf, &slen); ty->cur_cmd = s; @@ -987,6 +996,7 @@ _handle_esc_terminology(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) } ty->cur_cmd = NULL; if (s) free(s); + if (buf != bufsmall) free(buf); return cc - c; } @@ -1112,7 +1122,7 @@ _handle_esc(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) if (len < 2) return 0; if (c[1] == '8') { - int i, size; + int size; Termcell *cells; DBG("reset to init mode and clear then fill with E"); @@ -1126,7 +1136,10 @@ _handle_esc(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) size = ty->w * ty->h; if (cells) { - for (i = 0; i < size; i++) cells[i].codepoint = 'E'; + Termatt att; + + memset((&att), 0, sizeof(att)); + termpty_cell_codepoint_att_fill(ty, 'E', att, cells, size); } } return 2; @@ -1293,6 +1306,7 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, Eina_Unicode *ce) default: ERR("unhandled char 0x%02x", c[0]); ty->state.had_cr = 0; + sleep(1); return 1; } } diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c index 22bf4a11..7c2b765a 100644 --- a/src/bin/termptyops.c +++ b/src/bin/termptyops.c @@ -20,17 +20,12 @@ static void _text_clear(Termpty *ty, Termcell *cells, int count, int val, Eina_Bool inherit_att) { - int i; Termcell src; - memset(&src, 0, sizeof (src)); - + memset(&src, 0, sizeof(src)); src.codepoint = val; - if (inherit_att) src.att = ty->state.att; - - for (i = 0; i < count; i++) - memcpy(cells + i, &src, sizeof (src)); + termpty_cell_fill(ty, &src, cells, count); } static void @@ -43,7 +38,12 @@ _text_save_top(Termpty *ty) ts->w = ty->w; _termpty_text_copy(ty, &(TERMPTY_SCREEN(ty, 0, 0)), ts->cell, ty->w); if (!ty->back) ty->back = calloc(1, sizeof(Termsave *) * ty->backmax); - if (ty->back[ty->backpos]) free(ty->back[ty->backpos]); + if (ty->back[ty->backpos]) + { + termpty_cell_fill(ty, NULL, ty->back[ty->backpos]->cell, + ty->back[ty->backpos]->w); + free(ty->back[ty->backpos]); + } ty->back[ty->backpos] = ts; ty->backpos++; if (ty->backpos >= ty->backmax) ty->backpos = 0; @@ -52,9 +52,9 @@ _text_save_top(Termpty *ty) } void -_termpty_text_copy(Termpty *ty __UNUSED__, Termcell *cells, Termcell *dest, int count) +_termpty_text_copy(Termpty *ty, Termcell *cells, Termcell *dest, int count) { - memcpy(dest, cells, sizeof(*(cells)) * count); + termpty_cell_copy(ty, cells, dest, count); } void @@ -190,20 +190,18 @@ _termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len) if (ty->state.insert) { for (j = ty->w - 1; j > ty->state.cx; j--) - cells[j] = cells[j - 1]; + termpty_cell_copy(ty, &(cells[j - 1]), &(cells[j]), 1); } g = _termpty_charset_trans(codepoints[i], ty->state.charsetch); - cells[ty->state.cx].codepoint = g; - cells[ty->state.cx].att = ty->state.att; + termpty_cell_codepoint_att_fill(ty, g, ty->state.att, + &(cells[ty->state.cx]), 1); #if defined(SUPPORT_DBLWIDTH) cells[ty->state.cx].att.dblwidth = _termpty_is_dblwidth_get(ty, g); if ((cells[ty->state.cx].att.dblwidth) && (ty->state.cx < (ty->w - 1))) - { - cells[ty->state.cx + 1].codepoint = 0; - cells[ty->state.cx + 1].att = cells[ty->state.cx].att; - } + termpty_cell_codepoint_att_fill(ty, 0, cells[ty->state.cx].att, + &(cells[ty->state.cx + 1]), 1); #endif if (ty->state.wrap) { @@ -330,7 +328,7 @@ void _termpty_clear_all(Termpty *ty) { if (!ty->screen) return; - memset(ty->screen, 0, sizeof(*(ty->screen)) * ty->w * ty->h); + termpty_cell_fill(ty, NULL, ty->screen, ty->w * ty->h); } void diff --git a/src/bin/tycat.c b/src/bin/tycat.c index 16df96dd..565144d2 100644 --- a/src/bin/tycat.c +++ b/src/bin/tycat.c @@ -24,6 +24,8 @@ Evas_Object *o = NULL; struct termios told, tnew; int tw = 0, th = 0, cw = 0, ch = 0; +#include "extns.h" + static int echo_off(void) { @@ -55,6 +57,21 @@ scaleterm(int w, int h, int *iw, int *ih) } } +static const char * +is_fmt(const char *f, const char **extn) +{ + int i, len, l; + + len = strlen(f); + for (i = 0; extn[i]; i++) + { + l = strlen(extn[i]); + if (len < l) continue; + if (!strcasecmp(extn[i], f + len - l)) return extn[i]; + } + return NULL; +} + static void prnt(const char *path, int w, int h, int mode) { @@ -84,7 +101,6 @@ prnt(const char *path, int w, int h, int mode) line[i++] = 'e'; line[i++] = 0; line[i++] = '\n'; - line[i++] = 0; for (y = 0; y < h; y++) { if (write(0, line, i) < 0) perror("write"); @@ -164,15 +180,24 @@ main(int argc, char **argv) rp = ecore_file_realpath(path); if (rp) { - o = evas_object_image_add(evas); - evas_object_image_file_set(o, rp, NULL); - evas_object_image_size_get(o, &w, &h); - if ((w >= 0) && (h > 0)) + if ((is_fmt(rp, extn_img)) || + (is_fmt(rp, extn_scale)) || + (is_fmt(rp, extn_mov))) { - scaleterm(w, h, &iw, &ih); - prnt(rp, iw, ih, mode); + o = evas_object_image_add(evas); + evas_object_image_file_set(o, rp, NULL); + evas_object_image_size_get(o, &w, &h); + if ((w >= 0) && (h > 0)) + { + scaleterm(w, h, &iw, &ih); + prnt(rp, iw, ih, mode); + goto done; + } + evas_object_del(o); + o = NULL; } - else + + if (is_fmt(rp, extn_edj)) { Eina_Bool ok = EINA_TRUE; @@ -199,36 +224,44 @@ main(int argc, char **argv) } scaleterm(mw, mh, &iw, &ih); prnt(rp, iw, ih, mode); + goto done; } - else + evas_object_del(o); + o = NULL; + } + + if ((is_fmt(rp, extn_aud)) || + (is_fmt(rp, extn_mov))) + { + Eina_Bool ok = EINA_TRUE; + + o = emotion_object_add(evas); + ok = emotion_object_init(o, NULL); + if (ok) { - ok = EINA_TRUE; - - evas_object_del(o); - - o = emotion_object_add(evas); - ok = emotion_object_init(o, NULL); - if (ok) + if (emotion_object_file_set(o, rp)) { - if (emotion_object_file_set(o, rp)) + emotion_object_audio_mute_set(o, EINA_TRUE); + if (emotion_object_video_handled_get(o)) { - emotion_object_audio_mute_set(o, EINA_TRUE); - if (emotion_object_video_handled_get(o)) + emotion_object_size_get(o, &w, &h); + if ((w >= 0) && (h > 0)) { - emotion_object_size_get(o, &w, &h); - if ((w >= 0) && (h > 0)) - { - scaleterm(w, h, &iw, &ih); - prnt(rp, iw, ih, mode); - } + scaleterm(w, h, &iw, &ih); + prnt(rp, iw, ih, mode); } - else - prnt(rp, tw, 3, NOIMG); } + else + prnt(rp, tw, 3, NOIMG); + goto done; } } + evas_object_del(o); + o = NULL; } - evas_object_del(o); +done: + if (o) evas_object_del(o); + o = NULL; free(rp); } evas_norender(evas);