X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=72e57c8f73a868fc7871429b3ed22ddd17b21bcb;hb=907cb8bfa69926616639f9a19127117b37326029;hp=a60377bd9b78a4b71d1b0b23e41b5ee8461807db;hpb=6f260ba164ee302b50398e529f71e305e435504a;p=st.git diff --git a/st.c b/st.c index a60377b..72e57c8 100644 --- a/st.c +++ b/st.c @@ -34,9 +34,13 @@ #endif #define USAGE \ - "st-" VERSION ", (c) 2010-2011 st engineers\n" \ + "st " VERSION " (c) 2010-2011 st engineers\n" \ "usage: st [-t title] [-c class] [-w windowid] [-v] [-e command...]\n" +/* XEMBED messages */ +#define XEMBED_FOCUS_IN 4 +#define XEMBED_FOCUS_OUT 5 + /* Arbitrary sizes */ #define ESC_TITLE_SIZ 256 #define ESC_BUF_SIZ 256 @@ -122,6 +126,7 @@ typedef struct { Colormap cmap; Window win; Pixmap buf; + Atom xembed; XIM xim; XIC xic; int scr; @@ -219,6 +224,7 @@ static void visibility(XEvent *); static void unmap(XEvent *); static char* kmap(KeySym, unsigned int state); static void kpress(XEvent *); +static void cmessage(XEvent *); static void resize(XEvent *); static void focus(XEvent *); static void brelease(XEvent *); @@ -231,6 +237,7 @@ static void selinit(void); static inline int selected(int, int); static void selcopy(void); static void selpaste(); +static void selscroll(int, int); static int utf8decode(char *, long *); static int utf8encode(long *, char *); @@ -239,12 +246,11 @@ static int isfullutf8(char *, int); static void (*handler[LASTEvent])(XEvent *) = { [KeyPress] = kpress, + [ClientMessage] = cmessage, [ConfigureNotify] = resize, [VisibilityNotify] = visibility, [UnmapNotify] = unmap, [Expose] = expose, - [EnterNotify] = focus, - [LeaveNotify] = focus, [FocusIn] = focus, [FocusOut] = focus, [MotionNotify] = bmotion, @@ -801,6 +807,8 @@ tscrolldown(int orig, int n) { term.line[i] = term.line[i-n]; term.line[i-n] = temp; } + + selscroll(orig, n); } void @@ -816,6 +824,31 @@ tscrollup(int orig, int n) { term.line[i] = term.line[i+n]; term.line[i+n] = temp; } + + selscroll(orig, -n); +} + +void +selscroll(int orig, int n) { + if(sel.bx == -1) + return; + + if(BETWEEN(sel.by, orig, term.bot) || BETWEEN(sel.ey, orig, term.bot)) { + if((sel.by += n) > term.bot || (sel.ey += n) < term.top) { + sel.bx = -1; + return; + } + if(sel.by < term.top) { + sel.by = term.top; + sel.bx = 0; + } + if(sel.ey > term.bot) { + sel.ey = term.bot; + sel.ex = term.col; + } + sel.b.y = sel.by, sel.b.x = sel.bx; + sel.e.y = sel.ey, sel.e.x = sel.ex; + } } void @@ -1072,6 +1105,7 @@ csihandle(void) { break; /* XXX: (CSI n I) CHT -- Cursor Forward Tabulation tab stops */ case 'J': /* ED -- Clear screen */ + sel.bx = -1; switch(escseq.arg[0]) { case 0: /* below */ tclearregion(term.c.x, term.c.y, term.col-1, term.c.y); @@ -1377,6 +1411,7 @@ tputc(char *c) { } } } else { + if(sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey)) sel.bx = -1; switch(ascii) { case '\t': tputtab(); @@ -1506,7 +1541,7 @@ xloadcols(void) { XColor color; unsigned long white = WhitePixel(xw.dpy, xw.scr); - for(i = 0; i < 16; i++) { + for(i = 0; i < LEN(colorname); i++) { if(!XAllocNamedColor(xw.dpy, xw.cmap, colorname[i], &color, &color)) { dc.col[i] = white; fprintf(stderr, "Could not allocate color '%s'\n", colorname[i]); @@ -1629,8 +1664,8 @@ xinit(void) { xloadcols(); /* window - default size */ - xw.bufh = 24 * xw.ch; - xw.bufw = 80 * xw.cw; + xw.bufh = term.row * xw.ch; + xw.bufw = term.col * xw.cw; xw.h = xw.bufh + 2*BORDER; xw.w = xw.bufw + 2*BORDER; @@ -1668,6 +1703,8 @@ xinit(void) { &(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff}, &(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000}); + xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); + XStoreName(xw.dpy, xw.win, opt_title ? opt_title : "st"); XMapWindow(xw.dpy, xw.win); xhints(); @@ -1824,7 +1861,7 @@ xseturgency(int add) { void focus(XEvent *ev) { - if(ev->type == FocusIn || ev->type == EnterNotify) { + if(ev->type == FocusIn) { xw.state |= WIN_FOCUSED; xseturgency(0); } else @@ -1895,6 +1932,21 @@ kpress(XEvent *ev) { } void +cmessage(XEvent *e) { + /* See xembed specs + http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html */ + if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { + if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { + xw.state |= WIN_FOCUSED; + xseturgency(0); + } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { + xw.state &= ~WIN_FOCUSED; + } + draw(); + } +} + +void resize(XEvent *e) { int col, row;