X-Git-Url: https://jasonwoof.com/gitweb/?p=st.git;a=blobdiff_plain;f=st.c;h=8059b1656c11587a12d412bea31462b33cba266f;hp=bfbe799fece6de22fb32b7351f6ee50dc6b29c1d;hb=866590521609ba35606e53990e381bdc2adf742f;hpb=76a8e5f72b542f230d7248c09efe202a12bc3771 diff --git a/st.c b/st.c index bfbe799..8059b16 100644 --- a/st.c +++ b/st.c @@ -96,8 +96,8 @@ enum cursor_movement { enum cursor_state { CURSOR_DEFAULT = 0, - CURSOR_HIDE = 1, - CURSOR_WRAPNEXT = 2 + CURSOR_WRAPNEXT = 1, + CURSOR_ORIGIN = 2 }; enum glyph_state { @@ -115,7 +115,8 @@ enum term_mode { MODE_MOUSEMOTION = 64, MODE_MOUSE = 32|64, MODE_REVERSE = 128, - MODE_KBDLOCK = 256 + MODE_KBDLOCK = 256, + MODE_HIDE = 512 }; enum escape_state { @@ -300,6 +301,7 @@ static void tdeleteline(int); static void tinsertblank(int); static void tinsertblankline(int); static void tmoveto(int, int); +static void tmoveato(int x, int y); static void tnew(int, int); static void tnewline(int); static void tputtab(bool); @@ -673,6 +675,10 @@ bpress(XEvent *e) { sel.mode = 1; sel.ex = sel.bx = x2col(e->xbutton.x); sel.ey = sel.by = y2row(e->xbutton.y); + } else if(e->xbutton.button == Button4) { + ttywrite("\031", 1); + } else if(e->xbutton.button == Button5) { + ttywrite("\005", 1); } } @@ -1072,6 +1078,8 @@ treset(void) { term.mode = MODE_WRAP; tclearregion(0, 0, term.col-1, term.row-1); + tmoveto(0, 0); + tcursor(CURSOR_SAVE); } void @@ -1205,10 +1213,25 @@ csiparse(void) { } } +/* for absolute user moves, when decom is set */ +void +tmoveato(int x, int y) { + tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0)); +} + void tmoveto(int x, int y) { + int miny, maxy; + + if(term.c.state & CURSOR_ORIGIN) { + miny = term.top; + maxy = term.bot; + } else { + miny = 0; + maxy = term.row - 1; + } LIMIT(x, 0, term.col-1); - LIMIT(y, 0, term.row-1); + LIMIT(y, miny, maxy); term.c.state &= ~CURSOR_WRAPNEXT; term.c.x = x; term.c.y = y; @@ -1450,18 +1473,25 @@ tsetmode(bool priv, bool set, int *args, int narg) { if(mode != term.mode) redraw(); break; - case 6: /* XXX: DECOM -- Origin */ + case 6: /* DECOM -- Origin */ + MODBIT(term.c.state, set, CURSOR_ORIGIN); + tmoveato(0, 0); break; case 7: /* DECAWM -- Auto wrap */ MODBIT(term.mode, set, MODE_WRAP); break; - case 8: /* XXX: DECARM -- Auto repeat */ - break; case 0: /* Error (IGNORED) */ + case 2: /* DECANM -- ANSI/VT52 (IGNORED) */ + case 3: /* DECCOLM -- Column (IGNORED) */ + case 4: /* DECSCLM -- Scroll (IGNORED) */ + case 8: /* DECARM -- Auto repeat (IGNORED) */ + case 18: /* DECPFF -- Printer feed (IGNORED) */ + case 19: /* DECPEX -- Printer extent (IGNORED) */ + case 42: /* DECNRCM -- National characters (IGNORED) */ case 12: /* att610 -- Start blinking cursor (IGNORED) */ break; - case 25: - MODBIT(term.c.state, !set, CURSOR_HIDE); + case 25: /* DECTCEM -- Text Cursor Enable Mode */ + MODBIT(term.mode, !set, MODE_HIDE); break; case 1000: /* 1000,1002: enable xterm mouse report */ MODBIT(term.mode, set, MODE_MOUSEBTN); @@ -1471,26 +1501,20 @@ tsetmode(bool priv, bool set, int *args, int narg) { break; case 1049: /* = 1047 and 1048 */ case 47: - case 1047: - if(IS_SET(MODE_ALTSCREEN)) + case 1047: { + bool alt = IS_SET(MODE_ALTSCREEN) != 0; + if(alt) tclearregion(0, 0, term.col-1, term.row-1); - if((set && !IS_SET(MODE_ALTSCREEN)) || - (!set && IS_SET(MODE_ALTSCREEN))) { + if(set ^ alt) /* set is always 1 or 0 */ tswapscreen(); - } if(*args != 1049) break; + } /* pass through */ case 1048: tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); break; default: - /* case 2: DECANM -- ANSI/VT52 (NOT SUPPOURTED) */ - /* case 3: DECCOLM -- Column (NOT SUPPORTED) */ - /* case 4: DECSCLM -- Scroll (NOT SUPPORTED) */ - /* case 18: DECPFF -- Printer feed (NOT SUPPORTED) */ - /* case 19: DECPEX -- Printer extent (NOT SUPPORTED) */ - /* case 42: DECNRCM -- National characters (NOT SUPPORTED) */ fprintf(stderr, "erresc: unknown private set/reset mode %d\n", *args); @@ -1537,11 +1561,11 @@ csihandle(void) { tinsertblank(csiescseq.arg[0]); break; case 'A': /* CUU -- Cursor Up */ - case 'e': DEFAULT(csiescseq.arg[0], 1); tmoveto(term.c.x, term.c.y-csiescseq.arg[0]); break; case 'B': /* CUD -- Cursor Down */ + case 'e': /* VPR --Cursor Down */ DEFAULT(csiescseq.arg[0], 1); tmoveto(term.c.x, term.c.y+csiescseq.arg[0]); break; @@ -1550,7 +1574,7 @@ csihandle(void) { ttywrite(VT102ID, sizeof(VT102ID) - 1); break; case 'C': /* CUF -- Cursor Forward */ - case 'a': + case 'a': /* HPR -- Cursor Forward */ DEFAULT(csiescseq.arg[0], 1); tmoveto(term.c.x+csiescseq.arg[0], term.c.y); break; @@ -1587,7 +1611,7 @@ csihandle(void) { case 'f': /* HVP */ DEFAULT(csiescseq.arg[0], 1); DEFAULT(csiescseq.arg[1], 1); - tmoveto(csiescseq.arg[1]-1, csiescseq.arg[0]-1); + tmoveato(csiescseq.arg[1]-1, csiescseq.arg[0]-1); break; case 'I': /* CHT -- Cursor Forward Tabulation tab stops */ DEFAULT(csiescseq.arg[0], 1); @@ -1661,7 +1685,7 @@ csihandle(void) { break; case 'd': /* VPA -- Move to */ DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x, csiescseq.arg[0]-1); + tmoveato(term.c.x, csiescseq.arg[0]-1); break; case 'h': /* SM -- Set terminal mode */ tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg); @@ -1676,7 +1700,7 @@ csihandle(void) { DEFAULT(csiescseq.arg[0], 1); DEFAULT(csiescseq.arg[1], term.row); tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1); - tmoveto(0, 0); + tmoveato(0, 0); } break; case 's': /* DECSC -- Save cursor position (ANSI.SYS) */ @@ -1834,8 +1858,8 @@ tputc(char *c, int len) { } } /* - * STR sequences must be checked before of anything - * because it can use some control codes as part of the sequence + * STR sequences must be checked before anything else + * because it can use some control codes as part of the sequence. */ if(term.esc & ESC_STR) { switch(ascii) { @@ -1855,6 +1879,7 @@ tputc(char *c, int len) { } return; } + /* * Actions of control codes must be performed as soon they arrive * because they can be embedded inside a control sequence, and @@ -1895,11 +1920,11 @@ tputc(char *c, int len) { case '\030': /* CAN */ csireset(); return; - case '\005': /* ENQ (IGNORED) */ - case '\000': /* NUL (IGNORED) */ - case '\021': /* XON (IGNORED) */ - case '\023': /* XOFF (IGNORED) */ - case 0177: /* DEL (IGNORED) */ + case '\005': /* ENQ (IGNORED) */ + case '\000': /* NUL (IGNORED) */ + case '\021': /* XON (IGNORED) */ + case '\023': /* XOFF (IGNORED) */ + case 0177: /* DEL (IGNORED) */ return; } } else if(term.esc & ESC_START) { @@ -2112,10 +2137,10 @@ tresize(int col, int row) { /* update terminal size */ term.col = col; term.row = row; - /* make use of the LIMIT in tmoveto */ - tmoveto(term.c.x, term.c.y); /* reset scrolling region */ tsetscroll(0, row-1); + /* make use of the LIMIT in tmoveto */ + tmoveto(term.c.x, term.c.y); return (slide > 0); } @@ -2398,9 +2423,6 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { *temp, revfg, revbg; XRenderColor colfg, colbg; - if(base.mode & ATTR_REVERSE) - temp = fg, fg = bg, bg = temp; - if(base.mode & ATTR_BOLD) { if(BETWEEN(base.fg, 0, 7)) { /* basic system colors */ @@ -2450,6 +2472,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { } } + if(base.mode & ATTR_REVERSE) + temp = fg, fg = bg, bg = temp; + XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen, &extents); width = extents.xOff; @@ -2500,7 +2525,7 @@ xdrawcursor(void) { } /* draw the new one */ - if(!(term.c.state & CURSOR_HIDE)) { + if(!(IS_SET(MODE_HIDE))) { if(!(xw.state & WIN_FOCUSED)) g.bg = defaultucs; @@ -2541,9 +2566,9 @@ drawregion(int x1, int y1, int x2, int y2) { int ic, ib, x, y, ox, sl; Glyph base, new; char buf[DRAW_BUF_SIZ]; - bool ena_sel = sel.bx != -1, alt = IS_SET(MODE_ALTSCREEN); + bool ena_sel = sel.bx != -1, alt = IS_SET(MODE_ALTSCREEN) != 0; - if((sel.alt && !alt) || (!sel.alt && alt)) + if((sel.alt != 0) ^ alt) ena_sel = 0; if(!(xw.state & WIN_VISIBLE)) return; @@ -2694,6 +2719,9 @@ kpress(XEvent *ev) { selpaste(); break; case XK_Return: + if(meta) + ttywrite("\033", 1); + if(IS_SET(MODE_CRLF)) { ttywrite("\r\n", 2); } else { @@ -2742,8 +2770,6 @@ cresize(int width, int height) col = (xw.w - 2*borderpx) / xw.cw; row = (xw.h - 2*borderpx) / xw.ch; - if(col == term.col && row == term.row) - return; tresize(col, row); xresize(col, row);