summaryrefslogtreecommitdiffstats
path: root/tools/aewm-drakx/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aewm-drakx/client.c')
-rw-r--r--tools/aewm-drakx/client.c123
1 files changed, 123 insertions, 0 deletions
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);
+}