JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
fix custom key handling.
[st.git] / st.c
diff --git a/st.c b/st.c
index e705fca..a60377b 100644 (file)
--- a/st.c
+++ b/st.c
@@ -35,7 +35,7 @@
 
 #define USAGE \
        "st-" VERSION ", (c) 2010-2011 st engineers\n" \
-       "usage: st [-t title] [-c class] [-v] [-e command...]\n"
+       "usage: st [-t title] [-c class] [-w windowid] [-v] [-e command...]\n"
 
 /* Arbitrary sizes */
 #define ESC_TITLE_SIZ 256
@@ -43,6 +43,8 @@
 #define ESC_ARG_SIZ   16
 #define DRAW_BUF_SIZ  1024
 #define UTF_SIZ       4
+#define XK_NO_MOD     UINT_MAX
+#define XK_ANY_MOD    0
 
 #define SERRNO strerror(errno)
 #define MIN(a, b)  ((a) < (b) ? (a) : (b))
@@ -241,6 +243,8 @@ static void (*handler[LASTEvent])(XEvent *) = {
        [VisibilityNotify] = visibility,
        [UnmapNotify] = unmap,
        [Expose] = expose,
+       [EnterNotify] = focus,
+       [LeaveNotify] = focus,
        [FocusIn] = focus,
        [FocusOut] = focus,
        [MotionNotify] = bmotion,
@@ -260,6 +264,7 @@ static pid_t pid;
 static Selection sel;
 static char **opt_cmd  = NULL;
 static char *opt_title = NULL;
+static char *opt_embed = NULL;
 static char *opt_class = NULL;
 
 int
@@ -483,8 +488,7 @@ selcopy(void) {
 
 void
 selnotify(XEvent *e) {
-       unsigned long nitems;
-       unsigned long ofs, rem;
+       unsigned long nitems, ofs, rem;
        int format;
        unsigned char *data;
        Atom type;
@@ -615,7 +619,7 @@ bmotion(XEvent *e) {
                if(oldey != sel.ey || oldex != sel.ex) {
                        int starty = MIN(oldey, sel.ey);
                        int endy = MAX(oldey, sel.ey);
-                       drawregion(0, (starty > 0 ? starty : 0), term.col, (sel.ey < term.row ? endy+1 : term.row));
+                       drawregion(0, (starty > 0 ? starty : 0), term.col, (endy < term.row ? endy+1 : term.row));
                }
        }
 }
@@ -767,7 +771,7 @@ tnew(int col, int row) {
        term.row = row, term.col = col;
        term.line = malloc(term.row * sizeof(Line));
        term.alt  = malloc(term.row * sizeof(Line));
-       for(row = 0 ; row < term.row; row++) {
+       for(row = 0; row < term.row; row++) {
                term.line[row] = malloc(term.col * sizeof(Glyph));
                term.alt [row] = malloc(term.col * sizeof(Glyph));
        }
@@ -1141,12 +1145,13 @@ csihandle(void) {
                                term.mode &= ~MODE_MOUSEMOTION;
                                break;
                        case 1049: /* = 1047 and 1048 */
+                       case 47:
                        case 1047:
                                if(IS_SET(MODE_ALTSCREEN)) {
                                        tclearregion(0, 0, term.col-1, term.row-1);
                                        tswapscreen();
                                }
-                               if(escseq.arg[0] == 1047)
+                               if(escseq.arg[0] != 1049)
                                        break;
                        case 1048:
                                tcursor(CURSOR_LOAD);
@@ -1213,12 +1218,13 @@ csihandle(void) {
                                term.mode |= MODE_MOUSEMOTION;
                                break;
                        case 1049: /* = 1047 and 1048 */
+                       case 47:
                        case 1047:
                                if(IS_SET(MODE_ALTSCREEN))
                                        tclearregion(0, 0, term.col-1, term.row-1);
                                else
                                        tswapscreen();
-                               if(escseq.arg[0] == 1047)
+                               if(escseq.arg[0] != 1049)
                                        break;
                        case 1048:
                                tcursor(CURSOR_SAVE);
@@ -1605,6 +1611,7 @@ void
 xinit(void) {
        XSetWindowAttributes attrs;
        Cursor cursor;
+       Window parent;
 
        if(!(xw.dpy = XOpenDisplay(NULL)))
                die("Can't open display\n");
@@ -1632,10 +1639,12 @@ xinit(void) {
        attrs.bit_gravity = NorthWestGravity;
        attrs.event_mask = FocusChangeMask | KeyPressMask
                | ExposureMask | VisibilityChangeMask | StructureNotifyMask
-               | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
+               | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask
+               | EnterWindowMask | LeaveWindowMask;
        attrs.colormap = xw.cmap;
 
-       xw.win = XCreateWindow(xw.dpy, XRootWindow(xw.dpy, xw.scr), 0, 0,
+       parent = opt_embed ? strtol(opt_embed, NULL, 0) : XRootWindow(xw.dpy, xw.scr);
+       xw.win = XCreateWindow(xw.dpy, parent, 0, 0,
                        xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
                        XDefaultVisual(xw.dpy, xw.scr),
                        CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
@@ -1815,7 +1824,7 @@ xseturgency(int add) {
 
 void
 focus(XEvent *ev) {
-       if(ev->type == FocusIn) {
+       if(ev->type == FocusIn || ev->type == EnterNotify) {
                xw.state |= WIN_FOCUSED;
                xseturgency(0);
        } else
@@ -1826,9 +1835,12 @@ focus(XEvent *ev) {
 char*
 kmap(KeySym k, unsigned int state) {
        int i;
-       for(i = 0; i < LEN(key); i++)
-               if(key[i].k == k && (key[i].mask == 0 || key[i].mask & state))
+       state &= ~Mod2Mask;
+       for(i = 0; i < LEN(key); i++) {
+               unsigned int mask = key[i].mask;
+               if(key[i].k == k && ((state & mask) == mask || (mask == XK_NO_MOD && !state)))
                        return (char*)key[i].s;
+       }
        return NULL;
 }
 
@@ -1942,6 +1954,9 @@ main(int argc, char *argv[]) {
                case 'c':
                        if(++i < argc) opt_class = argv[i];
                        break;
+               case 'w':
+                       if(++i < argc) opt_embed = argv[i];
+                       break;
                case 'e': 
                        /* eat every remaining arguments */
                        if(++i < argc) opt_cmd = &argv[i];