/* Copyright (c) 1999 Decklin Foster <fosterd@hartwick.edu>
Copyright (c) 2000 Linus Nilsson <d96ln@efd.lth.se> */
#include "yawm.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/* The never-ending event-loop */
void do_event_loop() {
XEvent ev;
/* Remember to save those KeyCodes globally later instead of
looking them up every time */
/* XGrab M-tab, SM-Tab and F{1, 2, 3} so these symbols are not
sent to the clients aswell */
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("Tab")),
Mod1Mask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("Tab")),
Mod1Mask | ShiftMask, root, True, GrabModeAsync,
GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F1")),
AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F2")),
AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F3")),
AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F4")),
AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
/* Start the child that updates the clock in the taskbar */
if (USE_TASKBAR) {
taskbar_start();
}
/* Start the event-loop */
while (1) {
//printf("Waiting for next event. Ev is #%x\n", &ev);
XNextEvent(dpy, &ev);
//printf("Caught new event\n");
#ifdef DEBUG
show_event(ev);
#endif
switch (ev.type) {
case ButtonPress:
handle_button_event(&ev.xbutton); break;
case ConfigureRequest:
handle_configure_request(&ev.xconfigurerequest); break;
case MapRequest:
handle_map_request(&ev.xmaprequest); break;
case UnmapNotify:
handle_unmap_event(&ev.xunmap); break;
case ClientMessage:
handle_client_message(&ev.xclient); break;
case ColormapNotify:
handle_colormap_change(&ev.xcolormap); break;
case PropertyNotify:
handle_property_change(&ev.xproperty); break;
case EnterNotify:
handle_enter_event(&ev.xcrossing); break;
case Expose:
handle_expose_event(&ev.xexpose);
break;
case ReparentNotify:
handle_reparent_event(&ev.xreparent);
break;
case KeyPress:
handle_keypress_event(&ev.xkey);
break;
#ifdef SHAPE
default: if (shape && ev.type == shape_event)
handle_shape_change((XShapeEvent *)&ev);
#endif
}
}
}
/* quit_nicely is totally way fucked up. needs to be cleaned up after
all features are added. exit() is used in the meantime */
void quit_nicely() {
XFreeFont(dpy, font);
if (opt_new1) {
free(opt_new1);
}
while (head_client) {
remove_client(head_client, 1);
}
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XInstallColormap(dpy, DefaultColormap(dpy, screen));
XCloseDisplay(dpy);
exit(0);
}
void err(char *fmt, ...) {
va_list argp;
fprintf(stderr, "yawm: ");
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, 0);
if (e->error_code == BadAccess && e->resourceid == root) {
err("root window unavailible (maybe another wm is running?)");
exit(1);
}
#ifdef DEBUG
else {
char msg[80];
XGetErrorText(dpy, e->error_code, msg, sizeof(msg));
err("X error (%#x): %s", e->resourceid, msg);
}
#endif
if (c) remove_client(c, 0);
return 0;
}
#ifdef DEBUG
void show_event(XEvent e) {
char *s;
Window w;
switch (e.type) {
case ButtonPress:
s = "ButtonPress"; w = e.xbutton.window; break;
case ButtonRelease:
s = "ButtonRelease"; w = e.xbutton.window; break;
case ClientMessage:
s = "ClientMessage"; w = e.xclient.window; break;
case ColormapNotify:
s = "ColormapNotify"; w = e.xcolormap.window; break;
case ConfigureNotify:
s = "ConfigNotify"; w = e.xconfigure.window; break;
case ConfigureRequest:
s = "ConfigRequest"; w = e.xconfigurerequest.window; break;
case CreateNotify:
s = "CreateNotify"; w = e.xcreatewindow.window; break;
case DestroyNotify:
s = "DestroyNotify"; w = e.xdestroywindow.window; break;
case EnterNotify:
s = "EnterNotify"; w = e.xcrossing.window; break;
case LeaveNotify:
s = "LeaveNotify"; w = e.xcrossing.window; break;
case KeyPress:
s = "KeyPressEvent"; w = e.xkey.window; break;
case Expose:
s = "ExposeEvent"; w = e.xexpose.window; break;
case MapNotify:
s = "MapNotify"; w = e.xmap.window; break;
case MapRequest:
s = "MapRequest"; w = e.xmaprequest.window; break;
case MappingNotify:
s = "MappingNotify"; w = e.xmapping.window; break;
case MotionNotify:
s = "MotionNotify"; w = e.xmotion.window; break;
case PropertyNotify:
s = "PropertyNotify"; w = e.xproperty.window; break;
case ReparentNotify:
s = "ReparentNotify"; w = e.xreparent.window; break;
case ResizeRequest:
s = "ResizeRequest"; w = e.xresizerequest.window; break;
case UnmapNotify:
s = "UnmapNotify"; w = e.xunmap.window; break;
default:
s = "unknown event"; w = None; break;
}
err("recieved %s,\twindow = %#x", s, w);
}
void dump_clients() {
Client *c;
for (c = head_client; c; c = c->next)
err("%s (%d, %d): %#x (%#x) @ %d,%d", c->name, wm_state(c),
c->ignore_unmap, c->window, c->parent, c->x, c->y);
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1