diff options
Diffstat (limited to 'tools/aewm-drakx')
-rw-r--r-- | tools/aewm-drakx/Makefile | 10 | ||||
-rw-r--r-- | tools/aewm-drakx/README | 53 | ||||
-rw-r--r-- | tools/aewm-drakx/aewm-drakx.c | 53 | ||||
-rw-r--r-- | tools/aewm-drakx/aewm.h | 32 | ||||
-rw-r--r-- | tools/aewm-drakx/client.c | 123 | ||||
-rw-r--r-- | tools/aewm-drakx/events.c | 105 | ||||
-rw-r--r-- | tools/aewm-drakx/misc.c | 30 |
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; +} |