tadded several other stuff - dwm - [fork] customized build of dwm, the dynamic window manager
 (HTM) git clone git://src.adamsgaard.dk/dwm
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 439e15d09f6fa9271d3b49ef97194f0c80ebe161
 (DIR) parent 2de59d0f0927cec656fc4b9f6fc9ea178fb01c1e
 (HTM) Author: Anselm R. Garbe <garbeam@wmii.de>
       Date:   Mon, 10 Jul 2006 22:16:48 +0200
       
       added several other stuff
       
       Diffstat:
         M Makefile                            |       4 ++--
         A bar.c                               |      18 ++++++++++++++++++
         A client.c                            |      89 +++++++++++++++++++++++++++++++
         M config.h                            |       4 ++--
         M draw.c                              |       6 ++++++
         M draw.h                              |       1 +
         A event.c                             |     264 +++++++++++++++++++++++++++++++
         M menu.c                              |       9 ++++-----
         M util.c                              |      23 +++++++++++++++++++++++
         M util.h                              |       6 ++++--
         M wm.c                                |      51 +++++++++++++++++++++++--------
         M wm.h                                |      40 +++++++++++++++++++-------------
       
       12 files changed, 476 insertions(+), 39 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -3,11 +3,11 @@
        
        include config.mk
        
       -WMSRC = wm.c draw.c util.c
       +WMSRC = bar.c client.c draw.c event.c util.c wm.c
        WMOBJ = ${WMSRC:.c=.o}
        MENSRC = menu.c draw.c util.c
        MENOBJ = ${MENSRC:.c=.o}
       -MAN = gridwm.1
       +MAN1 = gridwm.1 gridmenu.1
        BIN = gridwm gridmenu     
        
        all: config gridwm gridmenu
 (DIR) diff --git a/bar.c b/bar.c
       t@@ -0,0 +1,18 @@
       +/*
       + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
       + * See LICENSE file for license details.
       + */
       +
       +#include "wm.h"
       +
       +void
       +draw_bar()
       +{
       +        brush.rect = barrect;
       +        brush.rect.x = brush.rect.y = 0;
       +        draw(dpy, &brush, False, 0);
       +
       +        XCopyArea(dpy, brush.drawable, barwin, brush.gc, 0, 0, barrect.width,
       +                        barrect.height, 0, 0);
       +        XFlush(dpy);
       +}
 (DIR) diff --git a/client.c b/client.c
       t@@ -0,0 +1,89 @@
       +/*
       + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
       + * See LICENSE file for license details.
       + */
       +
       +#include <string.h>
       +#include <X11/Xatom.h>
       +
       +#include "util.h"
       +#include "wm.h"
       +
       +static void
       +update_client_name(Client *c)
       +{
       +        XTextProperty name;
       +        int n;
       +        char **list = 0;
       +
       +        name.nitems = 0;
       +        c->name[0] = 0;
       +        XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
       +        if(!name.nitems)
       +                XGetWMName(dpy, c->win, &name);
       +        if(!name.nitems)
       +                return;
       +        if(name.encoding == XA_STRING)
       +                strncpy(c->name, (char *)name.value, sizeof(c->name));
       +        else {
       +                if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
       +                                && n > 0 && *list)
       +                {
       +                        strncpy(c->name, *list, sizeof(c->name));
       +                        XFreeStringList(list);
       +                }
       +        }
       +        XFree(name.value);
       +}
       +
       +Client *
       +create_client(Window w, XWindowAttributes *wa)
       +{
       +        Client *c;
       +        XSetWindowAttributes twa;
       +        long msize;
       +
       +        c = emallocz(sizeof(Client));
       +        c->win = w;
       +        c->r[RFloat].x = wa->x;
       +        c->r[RFloat].y = wa->y;
       +        c->r[RFloat].width = wa->width;
       +        c->r[RFloat].height = wa->height;
       +        c->border = wa->border_width;
       +        XSetWindowBorderWidth(dpy, c->win, 0);
       +        c->proto = win_proto(c->win);
       +        XGetTransientForHint(dpy, c->win, &c->trans);
       +        if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
       +                c->size.flags = PSize;
       +        c->fixedsize =
       +                (c->size.flags & PMinSize && c->size.flags & PMaxSize
       +                 && c->size.min_width == c->size.max_width
       +                 && c->size.min_height == c->size.max_height);
       +        XAddToSaveSet(dpy, c->win);
       +        update_client_name(c);
       +        twa.override_redirect = 1;
       +        twa.background_pixmap = ParentRelative;
       +        twa.event_mask = ExposureMask;
       +
       +        c->title = XCreateWindow(dpy, root, c->r[RFloat].x, c->r[RFloat].y,
       +                        c->r[RFloat].width, barrect.height, 0,
       +                        DefaultDepth(dpy, screen), CopyFromParent,
       +                        DefaultVisual(dpy, screen),
       +                        CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
       +        XFlush(dpy);
       +
       +#if 0
       +        for(t=&client, i=0; *t; t=&(*t)->next, i++);
       +        c->next = *t; /* *t == nil */
       +        *t = c;
       +#endif
       +        return c;
       +}
       +
       +void
       +manage(Client *c)
       +{
       +        XMapRaised(dpy, c->win);
       +        XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
       +        XFlush(dpy);
       +}
 (DIR) diff --git a/config.h b/config.h
       t@@ -4,6 +4,6 @@
         */
        
        #define FONT                "-*-terminus-medium-*-*-*-14-*-*-*-*-*-iso10646-*"
       -#define FGCOLOR                "#000000"
       -#define BGCOLOR                "#ffaa00"
       +#define BGCOLOR                "#000000"
       +#define FGCOLOR                "#ffaa00"
        #define BORDERCOLOR        "#000000"
 (DIR) diff --git a/draw.c b/draw.c
       t@@ -162,3 +162,9 @@ loadfont(Display *dpy, Fnt *font, const char *fontstr)
                }
                font->height = font->ascent + font->descent;
        }
       +
       +unsigned int
       +labelheight(Fnt *font)
       +{
       +        return font->height + 4;
       +}
 (DIR) diff --git a/draw.h b/draw.h
       t@@ -33,3 +33,4 @@ extern void loadcolors(Display *dpy, int screen, Brush *b,
        extern void loadfont(Display *dpy, Fnt *font, const char *fontstr);
        extern unsigned int textwidth_l(Fnt *font, char *text, unsigned int len);
        extern unsigned int textwidth(Fnt *font, char *text);
       +extern unsigned int labelheight(Fnt *font);
 (DIR) diff --git a/event.c b/event.c
       t@@ -0,0 +1,264 @@
       +/*
       + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
       + * See LICENSE file for license details.
       + */
       +
       +#include <fcntl.h>
       +#include <stdlib.h>
       +#include <string.h>
       +#include <X11/keysym.h>
       +
       +#include "wm.h"
       +
       +/* local functions */
       +static void configurerequest(XEvent *e);
       +static void destroynotify(XEvent *e);
       +static void enternotify(XEvent *e);
       +static void leavenotify(XEvent *e);
       +static void expose(XEvent *e);
       +static void keypress(XEvent *e);
       +static void keymapnotify(XEvent *e);
       +static void maprequest(XEvent *e);
       +static void propertynotify(XEvent *e);
       +static void unmapnotify(XEvent *e);
       +
       +void (*handler[LASTEvent]) (XEvent *) = {
       +        [ConfigureRequest] = configurerequest,
       +        [DestroyNotify] = destroynotify,
       +        [EnterNotify] = enternotify,
       +        [LeaveNotify] = leavenotify,
       +        [Expose] = expose,
       +        [KeyPress] = keypress,
       +        [KeymapNotify] = keymapnotify,
       +        [MapRequest] = maprequest,
       +        [PropertyNotify] = propertynotify,
       +        [UnmapNotify] = unmapnotify
       +};
       +
       +unsigned int
       +flush_masked_events(long even_mask)
       +{
       +        XEvent ev;
       +        unsigned int n = 0;
       +        while(XCheckMaskEvent(dpy, even_mask, &ev)) n++;
       +        return n;
       +}
       +
       +static void
       +configurerequest(XEvent *e)
       +{
       +#if 0
       +        XConfigureRequestEvent *ev = &e->xconfigurerequest;
       +        XWindowChanges wc;
       +        XRectangle *frect;
       +        Client *c;
       +
       +        c = client_of_win(ev->window);
       +        ev->value_mask &= ~CWSibling;
       +        if(c) {
       +                gravitate_client(c, True);
       +
       +                if(ev->value_mask & CWX)
       +                        c->rect.x = ev->x;
       +                if(ev->value_mask & CWY)
       +                        c->rect.y = ev->y;
       +                if(ev->value_mask & CWWidth)
       +                        c->rect.width = ev->width;
       +                if(ev->value_mask & CWHeight)
       +                        c->rect.height = ev->height;
       +                if(ev->value_mask & CWBorderWidth)
       +                        c->border = ev->border_width;
       +
       +                gravitate_client(c, False);
       +
       +                if(c->frame) {
       +                        if(c->sel->area->floating)
       +                                frect=&c->sel->rect;
       +                        else
       +                                frect=&c->sel->revert;
       +
       +                        if(c->rect.width >= screen->rect.width && c->rect.height >= screen->rect.height) {
       +                                frect->y = wc.y = -height_of_bar();
       +                                frect->x = wc.x = -def.border;
       +                        }
       +                        else {
       +                                frect->y = wc.y = c->rect.y - height_of_bar();
       +                                frect->x = wc.x = c->rect.x - def.border;
       +                        }
       +                        frect->width = wc.width = c->rect.width + 2 * def.border;
       +                        frect->height = wc.height = c->rect.height + def.border
       +                                + height_of_bar();
       +                        wc.border_width = 1;
       +                        wc.sibling = None;
       +                        wc.stack_mode = ev->detail;
       +                        if(c->sel->area->view != screen->sel)
       +                                wc.x += 2 * screen->rect.width;
       +                        if(c->sel->area->floating) {
       +                                XConfigureWindow(dpy, c->framewin, ev->value_mask, &wc);
       +                                configure_client(c);
       +                        }
       +                }
       +        }
       +
       +        wc.x = ev->x;
       +        wc.y = ev->y;
       +        wc.width = ev->width;
       +        wc.height = ev->height;
       +
       +        if(c && c->frame) {
       +                wc.x = def.border;
       +                wc.y = height_of_bar();
       +                wc.width = c->sel->rect.width - 2 * def.border;
       +                wc.height = c->sel->rect.height - def.border - height_of_bar();
       +        }
       +
       +        wc.border_width = 0;
       +        wc.sibling = None;
       +        wc.stack_mode = Above;
       +        ev->value_mask &= ~CWStackMode;
       +        ev->value_mask |= CWBorderWidth;
       +        XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
       +
       +        XFlush(dpy);
       +#endif
       +}
       +
       +static void
       +destroynotify(XEvent *e)
       +{
       +#if 0
       +        Client *c;
       +        XDestroyWindowEvent *ev = &e->xdestroywindow;
       +
       +        if((c = client_of_win(ev->window)))
       +                destroy_client(c);
       +#endif
       +}
       +
       +static void
       +enternotify(XEvent *e)
       +{
       +#if 0
       +        XCrossingEvent *ev = &e->xcrossing;
       +        Client *c;
       +
       +        if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
       +                return;
       +
       +        if((c = client_of_win(ev->window))) {
       +                Frame *f = c->sel;
       +                Area *a = f->area;
       +                if(a->mode == Colmax)
       +                        c = a->sel->client;
       +                focus(c, False);
       +        }
       +        else if(ev->window == root) {
       +                sel_screen = True;
       +                draw_frames();
       +        }
       +#endif
       +}
       +
       +static void
       +leavenotify(XEvent *e)
       +{
       +        XCrossingEvent *ev = &e->xcrossing;
       +
       +        if((ev->window == root) && !ev->same_screen) {
       +                sel_screen = True;
       +                /*draw_frames();*/
       +        }
       +}
       +
       +static void
       +expose(XEvent *e)
       +{
       +        XExposeEvent *ev = &e->xexpose;
       +
       +        if(ev->count == 0) {
       +                if(ev->window == barwin)
       +                        draw_bar();
       +        }
       +}
       +
       +static void
       +keypress(XEvent *e)
       +{
       +#if 0
       +        XKeyEvent *ev = &e->xkey;
       +        KeySym k = 0;
       +        char buf[32];
       +        int n;
       +        static Frame *f;
       +
       +
       +        ev->state &= valid_mask;
       +        if((f = frame_of_win(ev->window))) {
       +                buf[0] = 0;
       +                n = XLookupString(ev, buf, sizeof(buf), &k, 0);
       +                if(IsFunctionKey(k) || IsKeypadKey(k) || IsMiscFunctionKey(k)
       +                                || IsPFKey(k) || IsPrivateKeypadKey(k))
       +                        return;
       +                buf[n] = 0;
       +                blitz_kpress_input(&f->tagbar, ev->state, k, buf);
       +        }
       +        else
       +                key(root, ev->state, (KeyCode) ev->keycode);
       +#endif
       +}
       +
       +static void
       +keymapnotify(XEvent *e)
       +{
       +#if 0
       +        update_keys();
       +#endif
       +}
       +
       +static void
       +maprequest(XEvent *e)
       +{
       +#if 0
       +        XMapRequestEvent *ev = &e->xmaprequest;
       +        static XWindowAttributes wa;
       +
       +        if(!XGetWindowAttributes(dpy, ev->window, &wa))
       +                return;
       +
       +        if(wa.override_redirect) {
       +                XSelectInput(dpy, ev->window,
       +                                (StructureNotifyMask | PropertyChangeMask));
       +                return;
       +        }
       +
       +        if(!client_of_win(ev->window))
       +                manage_client(create_client(ev->window, &wa));
       +#endif
       +}
       +
       +static void
       +propertynotify(XEvent *e)
       +{
       +#if 0
       +        XPropertyEvent *ev = &e->xproperty;
       +        Client *c;
       +
       +        if(ev->state == PropertyDelete)
       +                return; /* ignore */
       +
       +        if((c = client_of_win(ev->window)))
       +                prop_client(c, ev);
       +#endif
       +}
       +
       +static void
       +unmapnotify(XEvent *e)
       +{
       +#if 0
       +        Client *c;
       +        XUnmapEvent *ev = &e->xunmap;
       +
       +        if((c = client_of_win(ev->window)))
       +                destroy_client(c);
       +#endif
       +}
 (DIR) diff --git a/menu.c b/menu.c
       t@@ -53,7 +53,7 @@ static const int seek = 30;                /* 30px */
        
        static Brush brush = {0};
        
       -static void draw_menu(void);
       +static void draw_menu();
        static void kpress(XKeyEvent * e);
        
        static char version[] = "gridmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
       t@@ -397,11 +397,10 @@ main(int argc, char *argv[])
        
                wa.override_redirect = 1;
                wa.background_pixmap = ParentRelative;
       -        wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask
       -                | SubstructureRedirectMask | SubstructureNotifyMask;
       +        wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask;
        
                rect.width = DisplayWidth(dpy, screen);
       -        rect.height = brush.font.height + 4;
       +        rect.height = labelheight(&brush.font);
                rect.y = DisplayHeight(dpy, screen) - rect.height;
                rect.x = 0;
        
       t@@ -413,7 +412,7 @@ main(int argc, char *argv[])
                XFlush(dpy);
        
                /* pixmap */
       -        brush.gc = XCreateGC(dpy, win, 0, 0);
       +        brush.gc = XCreateGC(dpy, root, 0, 0);
                brush.drawable = XCreatePixmap(dpy, win, rect.width, rect.height,
                                DefaultDepth(dpy, screen));
                XFlush(dpy);
 (DIR) diff --git a/util.c b/util.c
       t@@ -7,6 +7,11 @@
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
       +#include <sys/types.h>
       +#include <sys/wait.h>
       +#include <unistd.h>
       +
       +#include "util.h"
        
        void
        error(char *errstr, ...) {
       t@@ -75,3 +80,21 @@ swap(void **p1, void **p2)
                *p1 = *p2;
                *p2 = tmp;
        }
       +
       +void
       +spawn(Display *dpy, const char *shell, const char *cmd)
       +{
       +        if(!cmd || !shell)
       +                return;
       +        if(fork() == 0) {
       +                if(fork() == 0) {
       +                        if(dpy)
       +                                close(ConnectionNumber(dpy));
       +                        execl(shell, shell, "-c", cmd, (const char *)0);
       +                        fprintf(stderr, "gridwm: execl %s", shell);
       +                        perror(" failed");
       +                }
       +                exit (0);
       +        }
       +        wait(0);
       +}
 (DIR) diff --git a/util.h b/util.h
       t@@ -2,6 +2,7 @@
         * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
         * See LICENSE file for license details.
         */
       +#include <X11/Xlib.h>
        
        extern void error(char *errstr, ...);
        extern void *emallocz(unsigned int size);
       t@@ -12,5 +13,6 @@ extern char *estrdup(const char *str);
                        if(!(a)) \
                                failed_assert(#a, __FILE__, __LINE__); \
                } while (0)
       -void failed_assert(char *a, char *file, int line);
       -void swap(void **p1, void **p2);
       +extern void failed_assert(char *a, char *file, int line);
       +extern void swap(void **p1, void **p2);
       +extern void spawn(Display *dpy, const char *shell, const char *cmd);
 (DIR) diff --git a/wm.c b/wm.c
       t@@ -15,15 +15,15 @@
        
        /* X structs */
        Display *dpy;
       -Window root;
       -XRectangle rect;
       -Pixmap pmap;
       -Atom wm_atom[WMLast];
       -Atom net_atom[NetLast];
       +Window root, barwin;
       +Atom wm_atom[WMLast], net_atom[NetLast];
        Cursor cursor[CurLast];
       +XRectangle rect, barrect;
       +Bool running = True;
        
       +char *bartext, *shell;
        int screen, sel_screen;
       -unsigned int kmask, numlock_mask;
       +unsigned int lock_mask, numlock_mask;
        
        /* draw structs */
        Brush brush = {0};
       t@@ -166,7 +166,7 @@ init_lock_keys()
                }
                XFreeModifiermap(modmap);
        
       -        kmask = 255 & ~(numlock_mask | LockMask);
       +        lock_mask = 255 & ~(numlock_mask | LockMask);
        }
        
        static void
       t@@ -187,6 +187,7 @@ main(int argc, char *argv[])
                XSetWindowAttributes wa;
                unsigned int mask;
                Window w;
       +        XEvent ev;
        
                /* command line args */
                for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
       t@@ -218,6 +219,9 @@ main(int argc, char *argv[])
                if(other_wm_running)
                        error("gridwm: another window manager is already running\n");
        
       +        if(!(shell = getenv("SHELL")))
       +                shell = "/bin/sh";
       +
                rect.x = rect.y = 0;
                rect.width = DisplayWidth(dpy, screen);
                rect.height = DisplayHeight(dpy, screen);
       t@@ -244,19 +248,42 @@ main(int argc, char *argv[])
        
                init_lock_keys();
        
       -        pmap = XCreatePixmap(dpy, root, rect.width, rect.height,
       +        brush.drawable = XCreatePixmap(dpy, root, rect.width, rect.height,
                                DefaultDepth(dpy, screen));
       -
       -        wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
       -        wa.cursor = cursor[CurNormal];
       -        XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
       +        brush.gc = XCreateGC(dpy, root, 0, 0);
        
                /* style */
                loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR);
                loadfont(dpy, &brush.font, FONT);
        
       +        wa.override_redirect = 1;
       +        wa.background_pixmap = ParentRelative;
       +        wa.event_mask = ExposureMask;
       +
       +        barrect = rect;
       +        barrect.height = labelheight(&brush.font);
       +        barrect.y = rect.height - barrect.height;
       +        barwin = XCreateWindow(dpy, root, barrect.x, barrect.y,
       +                        barrect.width, barrect.height, 0, DefaultDepth(dpy, screen),
       +                        CopyFromParent, DefaultVisual(dpy, screen),
       +                        CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
       +        bartext = 0;
       +        XDefineCursor(dpy, barwin, cursor[CurNormal]);
       +        XMapRaised(dpy, barwin);
       +        draw_bar();
       +
       +        wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
       +        wa.cursor = cursor[CurNormal];
       +        XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
       +
                scan_wins();
        
       +        while(running) {
       +                XNextEvent(dpy, &ev);
       +                if(handler[ev.type])
       +                        (handler[ev.type]) (&ev); /* call handler */
       +        }
       +
                cleanup();
                XCloseDisplay(dpy);
        
 (DIR) diff --git a/wm.h b/wm.h
       t@@ -9,16 +9,14 @@
        
        #include <X11/Xutil.h>
        
       -/* WM atoms */
       +/* atoms */
        enum { WMState, WMProtocols, WMDelete, WMLast };
       -
       -/* NET atoms */
        enum { NetSupported, NetWMName, NetLast };
        
       -/* Cursor */
       +/* cursor */
        enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
        
       -/* Rects */
       +/* rects */
        enum { RFloat, RGrid, RLast };
        
        typedef struct Client Client;
       t@@ -28,35 +26,45 @@ struct Client {
                Tag *tag;
                char name[256];
                int proto;
       +        unsigned int border;
       +        Bool fixedsize;
                Window win;
                Window trans;
                Window title;
       -        GC gc;
                XSizeHints size;
                XRectangle r[RLast];
                Client *next;
       -        Client *tnext;
       -        Client *tprev;
       +        Client *snext;
        };
        
        struct Tag {
                char name[256];
       -        Client *clients;
       -        Client *sel;
       +        Client *stack;
                XRectangle r;
       +        Tag *next;
       +        Tag *cnext;
        };
        
        extern Display *dpy;
       -extern Window root;
       -extern XRectangle rect;
       -extern Atom wm_atom[WMLast];
       -extern Atom net_atom[NetLast];
       +extern Window root, barwin;
       +extern Atom wm_atom[WMLast], net_atom[NetLast];
        extern Cursor cursor[CurLast];
       -extern Pixmap pmap;
       +extern XRectangle rect, barrect;
       +extern Bool running;
       +extern void (*handler[LASTEvent]) (XEvent *);
        
        extern int screen, sel_screen;
       -extern unsigned int kmask, numlock_mask;
       +extern unsigned int lock_mask, numlock_mask;
       +extern char *bartext, *shell;
        
        extern Brush brush;
        
       +/* bar.c */
       +extern void draw_bar();
       +
       +/* client.c */
       +extern Client *create_client(Window w, XWindowAttributes *wa);
       +extern void manage(Client *c);
       +
        /* wm.c */
       +extern int win_proto(Window w);