JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
compose key patch. thx federico luna.
[st.git] / st.c
diff --git a/st.c b/st.c
index d2f8c2e..d1b90ef 100644 (file)
--- a/st.c
+++ b/st.c
@@ -107,6 +107,8 @@ typedef struct {
        Colormap cmap;
        Window win;
        Pixmap buf;
+       XIM xim;
+       XIC xic;
        int scr;
        int w;  /* window width  */
        int h;  /* window height */
@@ -114,7 +116,8 @@ typedef struct {
        int bufh; /* pixmap height */
        int ch; /* char height */
        int cw; /* char width  */
-       int hasfocus;
+       int focus;
+       int vis; /* is visible */
 } XWindow; 
 
 typedef struct {
@@ -187,6 +190,8 @@ static void xloadcols(void);
 static void xseturgency(int);
 
 static void expose(XEvent *);
+static void visibility(XEvent *);
+static void unmap(XEvent *);
 static char* kmap(KeySym);
 static void kpress(XEvent *);
 static void resize(XEvent *);
@@ -198,8 +203,10 @@ static void bmotion(XEvent *);
 
 static void (*handler[LASTEvent])(XEvent *) = {
        [KeyPress] = kpress,
-       [Expose] = expose,
        [ConfigureNotify] = resize,
+       [VisibilityNotify] = visibility,
+       [UnmapNotify] = unmap,
+       [Expose] = expose,
        [FocusIn] = focus,
        [FocusOut] = focus,
        [MotionNotify] = bmotion,
@@ -1038,7 +1045,7 @@ tputc(char c) {
                        tnewline();
                        break;
                case '\a':
-                       if(!xw.hasfocus)
+                       if(!xw.focus)
                                xseturgency(1);
                        break;
                case '\033':
@@ -1211,9 +1218,9 @@ xinit(void) {
        attrs.background_pixel = dc.col[DefaultBG];
        attrs.border_pixel = dc.col[DefaultBG];
        attrs.bit_gravity = NorthWestGravity;
-       attrs.event_mask = ExposureMask | KeyPressMask
-               | StructureNotifyMask | FocusChangeMask | PointerMotionMask
-               | ButtonPressMask | ButtonReleaseMask;
+       attrs.event_mask = FocusChangeMask | KeyPressMask
+               | ExposureMask | VisibilityChangeMask | StructureNotifyMask
+               | PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
        attrs.colormap = xw.cmap;
 
        xw.win = XCreateWindow(xw.dis, XRootWindow(xw.dis, xw.scr), 0, 0,
@@ -1223,6 +1230,13 @@ xinit(void) {
                        | CWColormap,
                        &attrs);
        xw.buf = XCreatePixmap(xw.dis, xw.win, xw.bufw, xw.bufh, XDefaultDepth(xw.dis, xw.scr));
+
+
+       /* input methods */
+       xw.xim = XOpenIM(xw.dis, NULL, NULL, NULL);
+       xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing 
+                                          | XIMStatusNothing, XNClientWindow, xw.win, 
+                                          XNFocusWindow, xw.win, NULL);
        /* gc */
        dc.gc = XCreateGC(xw.dis, xw.win, 0, NULL);
        
@@ -1281,7 +1295,7 @@ xdrawcursor(void) {
                xclear(oldx, oldy, oldx, oldy);
        
        /* draw the new one */
-       if(!(term.c.state & CURSOR_HIDE) && xw.hasfocus) {
+       if(!(term.c.state & CURSOR_HIDE) && xw.focus) {
                xdraws(&g.c, g, term.c.x, term.c.y, 1);
                oldx = term.c.x, oldy = term.c.y;
        }
@@ -1321,6 +1335,9 @@ draw(int redraw_all) {
        Glyph base, new;
        char buf[DRAW_BUF_SIZ];
 
+       if(!xw.vis)
+               return;
+
        xclear(0, 0, term.col-1, term.row-1);
        for(y = 0; y < term.row; y++) {
                base = term.line[y][0];
@@ -1358,6 +1375,19 @@ expose(XEvent *ev) {
 }
 
 void
+visibility(XEvent *ev) {
+       XVisibilityEvent *e = &ev->xvisibility;
+       /* XXX if this goes from 0 to 1, need a full redraw for next Expose,
+        * not just a buf copy */
+       xw.vis = e->state != VisibilityFullyObscured;
+}
+
+void
+unmap(XEvent *ev) {
+       xw.vis = 0;
+}
+
+void
 xseturgency(int add) {
        XWMHints *h = XGetWMHints(xw.dis, xw.win);
        h->flags = add ? (h->flags | XUrgencyHint) : (h->flags & ~XUrgencyHint);
@@ -1367,7 +1397,7 @@ xseturgency(int add) {
 
 void
 focus(XEvent *ev) {
-       if((xw.hasfocus = ev->type == FocusIn))
+       if((xw.focus = ev->type == FocusIn))
                xseturgency(0);
        draw(SCREEN_UPDATE);
 }
@@ -1390,10 +1420,11 @@ kpress(XEvent *ev) {
        int len;
        int meta;
        int shift;
+       Status status;
 
        meta = e->state & Mod1Mask;
        shift = e->state & ShiftMask;
-       len = XLookupString(e, buf, sizeof(buf), &ksym, NULL);
+       len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status);
 
        if((customkey = kmap(ksym)))
                ttywrite(customkey, strlen(customkey));
@@ -1463,6 +1494,8 @@ run(void) {
                }
                while(XPending(xw.dis)) {
                        XNextEvent(xw.dis, &ev);
+                       if (XFilterEvent(&ev, xw.win))
+                               continue;
                        if(handler[ev.type])
                                (handler[ev.type])(&ev);
                }