/* Copyright (c) 1999 Decklin Foster Copyright (c) 2000 Linus Nilsson */ #include "yawm.h" #include #include #include /* 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