summaryrefslogtreecommitdiffstats
path: root/tools/aewm-drakx
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aewm-drakx')
-rw-r--r--tools/aewm-drakx/Makefile10
-rw-r--r--tools/aewm-drakx/README53
-rw-r--r--tools/aewm-drakx/aewm-drakx.c53
-rw-r--r--tools/aewm-drakx/aewm.h32
-rw-r--r--tools/aewm-drakx/client.c123
-rw-r--r--tools/aewm-drakx/events.c105
-rw-r--r--tools/aewm-drakx/misc.c30
7 files changed, 406 insertions, 0 deletions
diff --git a/tools/aewm-drakx/Makefile b/tools/aewm-drakx/Makefile
new file mode 100644
index 000000000..ed1b95ecf
--- /dev/null
+++ b/tools/aewm-drakx/Makefile
@@ -0,0 +1,10 @@
+CFLAGS = -Wall -Os
+LDFLAGS = -L/usr/X11R6/lib -lX11
+CFILES = $(wildcard *.c)
+OFILES = $(CFILES:%.c=%.o)
+GOAL = aewm-drakx
+
+$(GOAL): $(OFILES)
+
+clean:
+ rm -f $(GOAL) $(OFILES) TAGS *~
diff --git a/tools/aewm-drakx/README b/tools/aewm-drakx/README
new file mode 100644
index 000000000..160ffb4d2
--- /dev/null
+++ b/tools/aewm-drakx/README
@@ -0,0 +1,53 @@
+aewm-drakx - A DrakX-aware X11 Window Manager
+======================================================================
+aewm-drakx is a stripped down version of aewm with keyboard focus added.
+The main and only purpose of aewm-drakx is to provide keyboard focus.
+
+Thanks to aewm author for his job. The already small aewm, gives a tiny WM
+(source < 4Kl, binary < 8KB) when stripped down of nearly everything.
+
+Pixel.
+
+
+aewm
+======================================================================
+http://www.red-bean.com/~decklin/aewm/.
+
+Author
+======================================================================
+
+aewm is maintained by Decklin Foster <decklin@red-bean.com>. If you
+have bug reports, comments, flames, want permission to change the
+license, or are just bored, send me email. Your messages are
+appreciated (but do read the thing above about virtual desktops ;-).
+
+License
+======================================================================
+
+Copyright (c) 1998-2001 Decklin Foster.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS", WITHOUT ANY EXPRESS
+OR IMPLIED WARRANTIES OF ANY KIND. IN NO EVENT SHALL THE AUTHOR BE
+HELD LIABLE FOR ANY DAMAGES CONNECTED WITH THE USE OF THIS PROGRAM.
+
+You are granted permission to copy, publish, distribute, and/or sell
+copies of this program and any modified versions or derived works,
+provided that this copyright and notice are not removed or altered.
+
+Portions of the code were based on 9wm, which contains this license:
+
+> 9wm is free software, and is Copyright (c) 1994 by David Hogan.
+> Permission is granted to all sentient beings to use this software,
+> to make copies of it, and to distribute those copies, provided
+> that:
+>
+> (1) the copyright and licence notices are left intact
+> (2) the recipients are aware that it is free software
+> (3) any unapproved changes in functionality are either
+> (i) only distributed as patches
+> or (ii) distributed as a new program which is not called 9wm
+> and whose documentation gives credit where it is due
+> (4) the author is not held responsible for any defects
+> or shortcomings in the software, or damages caused by it.
+>
+> There is no warranty for this software. Have a nice day.
diff --git a/tools/aewm-drakx/aewm-drakx.c b/tools/aewm-drakx/aewm-drakx.c
new file mode 100644
index 000000000..f550271c7
--- /dev/null
+++ b/tools/aewm-drakx/aewm-drakx.c
@@ -0,0 +1,53 @@
+/* aewm - a minimalistic X11 window manager. ------- vim:sw=4:et
+ * Copyright (c) 1998-2001 Decklin Foster <decklin@red-bean.com>
+ * Free software! Please see README for details and license. */
+
+#include "aewm.h"
+
+
+Display *dpy;
+Window root;
+Atom wm_state;
+
+static void scan_wins(void)
+{
+ unsigned int nwins, i;
+ Window dummyw1, dummyw2, *wins;
+ XWindowAttributes attr;
+
+ XQueryTree(dpy, root, &dummyw1, &dummyw2, &wins, &nwins);
+ for (i = 0; i < nwins; i++) {
+ XGetWindowAttributes(dpy, wins[i], &attr);
+ if (!attr.override_redirect && attr.map_state == IsViewable)
+ make_new_client(wins[i]);
+ }
+ XFree(wins);
+}
+
+static void setup_display(void)
+{
+ XSetWindowAttributes sattr;
+
+ dpy = XOpenDisplay(NULL);
+
+ if (!dpy) {
+ err("can't open display! check your DISPLAY variable.");
+ exit(1);
+ }
+
+ XSetErrorHandler(handle_xerror);
+ root = RootWindow(dpy, DefaultScreen(dpy));
+
+ wm_state = XInternAtom(dpy, "WM_STATE", False);
+
+ sattr.event_mask = SubstructureRedirectMask|SubstructureNotifyMask;
+ XChangeWindowAttributes(dpy, root, CWEventMask, &sattr);
+}
+
+
+int main()
+{
+ setup_display();
+ scan_wins();
+ do_event_loop();
+}
diff --git a/tools/aewm-drakx/aewm.h b/tools/aewm-drakx/aewm.h
new file mode 100644
index 000000000..d5c8a8b0e
--- /dev/null
+++ b/tools/aewm-drakx/aewm.h
@@ -0,0 +1,32 @@
+/* aewm - a minimalistic X11 window manager. ------- vim:sw=4:et
+ * Copyright (c) 1998-2001 Decklin Foster <decklin@red-bean.com>
+ * Free software! Please see README for details and license. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xutil.h>
+
+typedef struct _Client Client;
+
+struct _Client {
+ Client *next;
+ Window window;
+};
+
+extern Display *dpy;
+extern Atom wm_state;
+
+/* events.c */
+extern void do_event_loop(void);
+
+/* client.c */
+extern Client *find_client(Window);
+extern void set_wm_state(Client *, int);
+extern void remove_client(Client *);
+extern void make_new_client(Window);
+
+/* misc.c */
+void err(const char *, ...);
+int handle_xerror(Display *, XErrorEvent *);
+
diff --git a/tools/aewm-drakx/client.c b/tools/aewm-drakx/client.c
new file mode 100644
index 000000000..6f38f3150
--- /dev/null
+++ b/tools/aewm-drakx/client.c
@@ -0,0 +1,123 @@
+/* aewm - a minimalistic X11 window manager. ------- vim:sw=4:et
+ * Copyright (c) 1998-2001 Decklin Foster <decklin@red-bean.com>
+ * Free software! Please see README for details and license. */
+
+#include "aewm.h"
+#include <X11/Xmd.h>
+
+
+Client *head_client = NULL;
+
+Client *find_client(Window w)
+{
+ Client *c;
+
+ for (c = head_client; c; c = c->next)
+ if (c->window == w) return c;
+
+ return NULL;
+}
+
+
+void set_focus_on(Window w)
+{
+ char *name;
+ XFetchName(dpy, w, &name);
+ if (name && strcmp(name, "skip")) {
+ XSetInputFocus(dpy, w, RevertToPointerRoot, CurrentTime);
+#ifdef DEBUG
+ printf("aewm-drakx: adding %ld %s\n", w, name);
+#endif
+ }
+}
+
+/* Attempt to follow the ICCCM by explicity specifying 32 bits for
+ * this property. Does this goof up on 64 bit systems? */
+void set_wm_state(Client *c, int state)
+{
+ CARD32 data[2];
+
+ data[0] = state;
+ data[1] = None; /* Icon? We don't need no steenking icon. */
+
+ XChangeProperty(dpy, c->window, wm_state, wm_state,
+ 32, PropModeReplace, (unsigned char *)data, 2);
+}
+
+/* If we can't find a WM_STATE we're going to have to assume
+ * Withdrawn. This is not exactly optimal, since we can't really
+ * distinguish between the case where no WM has run yet and when the
+ * state was explicitly removed (Clients are allowed to either set the
+ * atom to Withdrawn or just remove it... yuck.) */
+long get_wm_state(Client *c)
+{
+ Atom real_type; int real_format;
+ unsigned long items_read, items_left;
+ long *data, state = WithdrawnState;
+
+ if (XGetWindowProperty(dpy, c->window, wm_state, 0L, 2L, False,
+ wm_state, &real_type, &real_format, &items_read, &items_left,
+ (unsigned char **) &data) == Success && items_read) {
+ state = *data;
+ XFree(data);
+ }
+ return state;
+}
+
+void remove_client(Client *c)
+{
+ int ignore_xerror(Display *dpy, XErrorEvent *e) { return 0; }
+
+ Client *p;
+
+ XGrabServer(dpy);
+ XSetErrorHandler(ignore_xerror);
+
+ set_wm_state(c, WithdrawnState);
+
+ if (head_client == c) head_client = c->next;
+ else for (p = head_client; p && p->next; p = p->next)
+ if (p->next == c) p->next = c->next;
+
+ free(c);
+
+ if (head_client) set_focus_on(head_client->window);
+
+ XSync(dpy, False);
+ XSetErrorHandler(handle_xerror);
+ XUngrabServer(dpy);
+}
+
+void make_new_client(Window w)
+{
+ Client *c;
+ XWindowAttributes attr;
+
+ c = malloc(sizeof *c);
+ c->next = head_client;
+ c->window = w;
+ head_client = c;
+
+ XGrabServer(dpy);
+ XGetWindowAttributes(dpy, w, &attr);
+
+
+ if (attr.map_state != IsViewable) {
+ XWMHints *hints;
+ set_wm_state(c, NormalState);
+ if ((hints = XGetWMHints(dpy, w))) {
+ if (hints->flags & StateHint) set_wm_state(c, hints->initial_state);
+ XFree(hints);
+ }
+ }
+ if (attr.map_state == IsViewable) {
+ XMapWindow(dpy, c->window);
+ set_wm_state(c, NormalState);
+ } else if (get_wm_state(c) == NormalState) {
+ XMapWindow(dpy, c->window);
+ }
+ set_focus_on(w);
+
+ XSync(dpy, False);
+ XUngrabServer(dpy);
+}
diff --git a/tools/aewm-drakx/events.c b/tools/aewm-drakx/events.c
new file mode 100644
index 000000000..4a6ba53a4
--- /dev/null
+++ b/tools/aewm-drakx/events.c
@@ -0,0 +1,105 @@
+/* aewm - a minimalistic X11 window manager. ------- vim:sw=4:et
+ * Copyright (c) 1998-2001 Decklin Foster <decklin@red-bean.com>
+ * Free software! Please see README for details and license. */
+
+#include "aewm.h"
+
+
+static void handle_configure_request(XConfigureRequestEvent *e)
+{
+ XWindowChanges wc;
+
+ wc.x = e->x;
+ wc.y = e->y;
+ wc.width = e->width;
+ wc.height = e->height;
+ wc.sibling = e->above;
+ wc.stack_mode = e->detail;
+ XConfigureWindow(dpy, e->window, e->value_mask, &wc);
+}
+
+static void handle_map_request(XMapRequestEvent *e)
+{
+ Client *c = find_client(e->window);
+
+ if (c) {
+ XMapWindow(dpy, c->window);
+ set_wm_state(c, NormalState);
+ } else {
+ make_new_client(e->window);
+ }
+}
+
+static void handle_destroy_event(XDestroyWindowEvent *e)
+{
+ Client *c = find_client(e->window);
+
+ if (c) remove_client(c);
+}
+
+
+#ifdef DEBUG
+#define SHOW_EV(name, memb) \
+ case name: s = #name; w = e.memb.window; break;
+#define SHOW(name) \
+ case name: return #name;
+
+void show_event(XEvent e)
+{
+ char *s = 0, buf[20];
+ char *dd = 0;
+ Window w = 0;
+ Client *c;
+
+ switch (e.type) {
+ SHOW_EV(ButtonPress, xbutton)
+ SHOW_EV(ButtonRelease, xbutton)
+ SHOW_EV(ClientMessage, xclient)
+ SHOW_EV(ColormapNotify, xcolormap)
+ SHOW_EV(ConfigureNotify, xconfigure)
+ SHOW_EV(ConfigureRequest, xconfigurerequest)
+ SHOW_EV(CreateNotify, xcreatewindow)
+ SHOW_EV(DestroyNotify, xdestroywindow)
+ SHOW_EV(EnterNotify, xcrossing)
+ SHOW_EV(Expose, xexpose)
+ SHOW_EV(MapNotify, xmap)
+ SHOW_EV(MapRequest, xmaprequest)
+ SHOW_EV(MappingNotify, xmapping)
+ SHOW_EV(MotionNotify, xmotion)
+ SHOW_EV(PropertyNotify, xproperty)
+ SHOW_EV(ReparentNotify, xreparent)
+ SHOW_EV(ResizeRequest, xresizerequest)
+ SHOW_EV(UnmapNotify, xunmap)
+ default:
+ break;
+ }
+
+ c = find_client(w);
+
+ if (c) XFetchName(dpy, c->window, &dd);
+
+ snprintf(buf, sizeof buf, dd ? dd : "");
+ err("%#-10lx: %-20s: %s", w, buf, s);
+}
+#endif
+
+
+void do_event_loop(void)
+{
+ XEvent ev;
+
+ for (;;) {
+ XNextEvent(dpy, &ev);
+#ifdef DEBUG
+ show_event(ev);
+#endif
+ switch (ev.type) {
+ case ConfigureRequest:
+ handle_configure_request(&ev.xconfigurerequest); break;
+ case MapRequest:
+ handle_map_request(&ev.xmaprequest); break;
+ case DestroyNotify:
+ handle_destroy_event(&ev.xdestroywindow); break;
+ }
+ }
+}
diff --git a/tools/aewm-drakx/misc.c b/tools/aewm-drakx/misc.c
new file mode 100644
index 000000000..9542c2cc3
--- /dev/null
+++ b/tools/aewm-drakx/misc.c
@@ -0,0 +1,30 @@
+/* aewm - a minimalistic X11 window manager. ------- vim:sw=4:et
+ * Copyright (c) 1998-2001 Decklin Foster <decklin@red-bean.com>
+ * Free software! Please see README for details and license. */
+
+#include "aewm.h"
+#include <stdarg.h>
+
+
+void err(const char *fmt, ...)
+{
+ va_list argp;
+
+ fprintf(stderr, "aewm: ");
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+ fprintf(stderr, "\n");
+}
+
+int handle_xerror(Display *dpy, XErrorEvent *e)
+{
+ Client *c = find_client(e->resourceid);
+
+ char msg[255];
+ XGetErrorText(dpy, e->error_code, msg, sizeof msg);
+ err("X error (%#lx): %s", e->resourceid, msg);
+
+ if (c) remove_client(c);
+ return 0;
+}