diff options
Diffstat (limited to 'src/vwm.c')
-rw-r--r-- | src/vwm.c | 394 |
1 files changed, 212 insertions, 182 deletions
@@ -26,8 +26,6 @@ #include <X11/extensions/Xdamage.h> /* Damage extension, enables receipt of damage events, reports visible regions needing updating (compositing) */ #include <X11/extensions/Xrender.h> /* Render extension, enables use of alpha channels and accelerated rendering of surfaces having alpha (compositing) */ #include <X11/extensions/Xcomposite.h> /* Composite extension, enables off-screen redirection of window rendering (compositing) */ -#include <unistd.h> -#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -48,8 +46,6 @@ #include "xevent.h" #include "xwindow.h" -static vwm_t vwm; - /* Sync */ static int sync_event, sync_error; @@ -60,235 +56,269 @@ static int randr_event, randr_error; /* Compositing */ static int composite_event, composite_error, composite_opcode; -static int errhandler(Display *display, XErrorEvent *err) -{ - /* TODO */ - return 1; -} -int main(int argc, char *argv[]) +static vwm_t * vwm_startup(void) { - int err = 0; - XEvent event; - Cursor pointer; - struct pollfd pfd; - char *console_args[] = {"xterm", "-class", CONSOLE_WM_CLASS, "-e", "/bin/sh", "-c", "screen -D -RR " CONSOLE_SESSION_STRING, NULL}; - char *quit_console_args[] = {"/bin/sh", "-c", "screen -dr " CONSOLE_SESSION_STRING " -X quit", NULL}; - -#define reterr_if(_cond, _fmt, _args...) \ - err++;\ - if (_cond) {\ - VWM_ERROR(_fmt, ##_args);\ - return err;\ - } + Cursor pointer; + char *console_args[] = {"xterm", "-class", CONSOLE_WM_CLASS, "-e", "/bin/sh", "-c", "screen -D -RR " CONSOLE_SESSION_STRING, NULL}; + vwm_t *vwm; - INIT_LIST_HEAD(&vwm.desktops); - INIT_LIST_HEAD(&vwm.desktops_mru); - INIT_LIST_HEAD(&vwm.windows_mru); - INIT_LIST_HEAD(&vwm.xwindows); - - /* open connection with the server */ - reterr_if((vwm.display = XOpenDisplay(NULL)) == NULL, "Cannot open display"); + if (!(vwm = calloc(1, sizeof(vwm_t)))) { + VWM_ERROR("Unable to allocate vwm_t"); + goto _err; + } - /* prevent children from inheriting the X connection */ - reterr_if(fcntl(ConnectionNumber(vwm.display), F_SETFD, FD_CLOEXEC) < 0, "Cannot set FD_CLOEXEC on X connection"); + INIT_LIST_HEAD(&vwm->desktops); + INIT_LIST_HEAD(&vwm->desktops_mru); + INIT_LIST_HEAD(&vwm->windows_mru); + INIT_LIST_HEAD(&vwm->xwindows); - /* get our scheduling priority, clients are launched with a priority LAUNCHED_RELATIVE_PRIORITY nicer than this */ - reterr_if((vwm.priority = getpriority(PRIO_PROCESS, getpid())) == -1, "Cannot get scheduling priority"); + if (!(vwm->xserver = vwm_xserver_open())) { + VWM_ERROR("Failed to open xserver"); + goto _err_free; + } - XSetErrorHandler(errhandler); + /* query the needed X extensions */ + if (!XQueryExtension(VWM_XDISPLAY(vwm), COMPOSITE_NAME, &composite_opcode, &composite_event, &composite_error)) { + VWM_ERROR("No composite extension available"); + goto _err_xclose; + } - vwm.screen_num = DefaultScreen(vwm.display); + if (!XDamageQueryExtension(VWM_XDISPLAY(vwm), &vwm->damage_event, &vwm->damage_error)) { + VWM_ERROR("No damage extension available"); + goto _err_xclose; + } - /* query the needed X extensions */ - reterr_if(!XQueryExtension (vwm.display, COMPOSITE_NAME, &composite_opcode, &composite_event, &composite_error), "No composite extension available"); - reterr_if(!XDamageQueryExtension(vwm.display, &vwm.damage_event, &vwm.damage_error), "No damage extension available"); - if (XSyncQueryExtension(vwm.display, &sync_event, &sync_error)) { + if (XSyncQueryExtension(VWM_XDISPLAY(vwm), &sync_event, &sync_error)) { /* set the window manager to the maximum X client priority */ - XSyncSetPriority(vwm.display, VWM_XROOT(&vwm), 0x7fffffff); + XSyncSetPriority(VWM_XDISPLAY(vwm), VWM_XROOT(vwm), 0x7fffffff); } - if (XineramaQueryExtension(vwm.display, &xinerama_event, &xinerama_error)) { - vwm.xinerama_screens = XineramaQueryScreens(vwm.display, &vwm.xinerama_screens_cnt); + if (XineramaQueryExtension(VWM_XDISPLAY(vwm), &xinerama_event, &xinerama_error)) { + vwm->xinerama_screens = XineramaQueryScreens(VWM_XDISPLAY(vwm), &vwm->xinerama_screens_cnt); } - if (XRRQueryExtension(vwm.display, &randr_event, &randr_error)) { - XRRSelectInput(vwm.display, VWM_XROOT(&vwm), RRScreenChangeNotifyMask); + if (XRRQueryExtension(VWM_XDISPLAY(vwm), &randr_event, &randr_error)) { + XRRSelectInput(VWM_XDISPLAY(vwm), VWM_XROOT(vwm), RRScreenChangeNotifyMask); } - /* allocate colors, I make assumptions about the X server's color capabilities since I'll only use this on modern-ish computers... */ - vwm.cmap = DefaultColormap(vwm.display, vwm.screen_num); + /* get our scheduling priority, clients are launched with a priority LAUNCHED_RELATIVE_PRIORITY nicer than this */ + if ((vwm->priority = getpriority(PRIO_PROCESS, getpid())) == -1) { + VWM_ERROR("Cannot get scheduling priority"); + goto _err_xclose; + } + + vwm->wm_delete_atom = XInternAtom(VWM_XDISPLAY(vwm), "WM_DELETE_WINDOW", False); + vwm->wm_protocols_atom = XInternAtom(VWM_XDISPLAY(vwm), "WM_PROTOCOLS", False); + vwm->wm_pid_atom = XInternAtom(VWM_XDISPLAY(vwm), "_NET_WM_PID", False); + /* allocate colors, I make assumptions about the X server's color capabilities since I'll only use this on modern-ish computers... */ #define color(_sym, _str) \ - XAllocNamedColor(vwm.display, vwm.cmap, _str, &vwm.colors._sym ## _color, &vwm.colors._sym ## _color); + XAllocNamedColor(VWM_XDISPLAY(vwm), VWM_XCMAP(vwm), _str, &vwm->colors._sym ## _color, &vwm->colors._sym ## _color); #include "colors.def" #undef color - vwm.wm_delete_atom = XInternAtom(vwm.display, "WM_DELETE_WINDOW", False); - vwm.wm_protocols_atom = XInternAtom(vwm.display, "WM_PROTOCOLS", False); - vwm.wm_pid_atom = XInternAtom(vwm.display, "_NET_WM_PID", False); - - XSelectInput(vwm.display, VWM_XROOT(&vwm), + XSelectInput(VWM_XDISPLAY(vwm), VWM_XROOT(vwm), PropertyChangeMask | SubstructureNotifyMask | SubstructureRedirectMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask); - XGrabKey(vwm.display, AnyKey, WM_GRAB_MODIFIER, VWM_XROOT(&vwm), False, GrabModeAsync, GrabModeAsync); + XGrabKey(VWM_XDISPLAY(vwm), AnyKey, WM_GRAB_MODIFIER, VWM_XROOT(vwm), False, GrabModeAsync, GrabModeAsync); - XFlush(vwm.display); + XFlush(VWM_XDISPLAY(vwm)); - XSetInputFocus(vwm.display, VWM_XROOT(&vwm), RevertToPointerRoot, CurrentTime); + XSetInputFocus(VWM_XDISPLAY(vwm), VWM_XROOT(vwm), RevertToPointerRoot, CurrentTime); /* create initial virtual desktop */ - vwm_desktop_focus(&vwm, vwm_desktop_create(&vwm, NULL)); - vwm_desktop_mru(&vwm, vwm.focused_desktop); + vwm_desktop_focus(vwm, vwm_desktop_create(vwm, NULL)); + vwm_desktop_mru(vwm, vwm->focused_desktop); /* manage all preexisting windows */ - vwm_xwin_create_existing(&vwm); + vwm_xwin_create_existing(vwm); - /* create GC for logo drawing and window rubber-banding */ - vwm.gc = XCreateGC(vwm.display, VWM_XROOT(&vwm), 0, NULL); - XSetSubwindowMode(vwm.display, vwm.gc, IncludeInferiors); - XSetFunction(vwm.display, vwm.gc, GXxor); + /* setup GC for logo drawing and window rubber-banding */ + XSetSubwindowMode(VWM_XDISPLAY(vwm), VWM_XGC(vwm), IncludeInferiors); + XSetFunction(VWM_XDISPLAY(vwm), VWM_XGC(vwm), GXxor); /* launch the console here so it's likely ready by the time the logo animation finishes (there's no need to synchronize with it currently) */ - vwm_launch(&vwm, console_args, VWM_LAUNCH_MODE_BG); + vwm_launch(vwm, console_args, VWM_LAUNCH_MODE_BG); /* first the logo color is the foreground */ - XSetForeground(vwm.display, vwm.gc, vwm.colors.logo_color.pixel); - vwm_draw_logo(&vwm); + XSetForeground(VWM_XDISPLAY(vwm), VWM_XGC(vwm), vwm->colors.logo_color.pixel); + vwm_draw_logo(vwm); /* change to the rubber-banding foreground color */ - XSetForeground(vwm.display, vwm.gc, vwm.colors.rubberband_color.pixel); + XSetForeground(VWM_XDISPLAY(vwm), VWM_XGC(vwm), vwm->colors.rubberband_color.pixel); - XClearWindow(vwm.display, VWM_XROOT(&vwm)); + XClearWindow(VWM_XDISPLAY(vwm), VWM_XROOT(vwm)); /* set the pointer */ - pointer = XCreateFontCursor(vwm.display, XC_X_cursor); - XDefineCursor(vwm.display, VWM_XROOT(&vwm), pointer); + pointer = XCreateFontCursor(VWM_XDISPLAY(vwm), XC_X_cursor); + XDefineCursor(VWM_XDISPLAY(vwm), VWM_XROOT(vwm), pointer); + + return vwm; + + +_err_xclose: + vwm_xserver_close(vwm->xserver); + +_err_free: + free(vwm); + +_err: + return NULL; +} + + +void vwm_shutdown(vwm_t *vwm) +{ + char *quit_console_args[] = {"/bin/sh", "-c", "screen -dr " CONSOLE_SESSION_STRING " -X quit", NULL}; + + vwm_launch(vwm, quit_console_args, VWM_LAUNCH_MODE_FG); + vwm_xserver_close(vwm->xserver); + /* TODO there's more shit to cleanup here, but we're exiting anyways. */ + free(vwm); +} + + +void vwm_process_event(vwm_t *vwm) +{ + XEvent event; + + XNextEvent(VWM_XDISPLAY(vwm), &event); + switch (event.type) { + case KeyPress: + VWM_TRACE("keypress"); + vwm_xevent_handle_key_press(vwm, &event.xkey); + break; + + case KeyRelease: + VWM_TRACE("keyrelease"); + vwm_xevent_handle_key_release(vwm, &event.xkey); + break; + + case ButtonPress: + VWM_TRACE("buttonpresss"); + vwm_xevent_handle_button_press(vwm, &event.xbutton); + break; + + case MotionNotify: + //VWM_TRACE("motionnotify"); + vwm_xevent_handle_motion_notify(vwm, &event.xmotion); + break; + + case ButtonRelease: + VWM_TRACE("buttonrelease"); + vwm_xevent_handle_button_release(vwm, &event.xbutton); + break; + + case CreateNotify: + VWM_TRACE("createnotify"); + vwm_xevent_handle_create_notify(vwm, &event.xcreatewindow); + break; + + case DestroyNotify: + VWM_TRACE("destroynotify"); + vwm_xevent_handle_destroy_notify(vwm, &event.xdestroywindow); + break; + + case ConfigureRequest: + VWM_TRACE("configurerequest"); + vwm_xevent_handle_configure_request(vwm, &event.xconfigurerequest); + break; + + case ConfigureNotify: + VWM_TRACE("configurenotify"); + vwm_xevent_handle_configure_notify(vwm, &event.xconfigure); + break; + + case UnmapNotify: + VWM_TRACE("unmapnotify"); + vwm_xevent_handle_unmap_notify(vwm, &event.xunmap); + break; + + case MapNotify: + VWM_TRACE("mapnotify"); + vwm_xevent_handle_map_notify(vwm, &event.xmap); + break; + + case MapRequest: + VWM_TRACE("maprequest"); + vwm_xevent_handle_map_request(vwm, &event.xmaprequest); + break; + + case PropertyNotify: + VWM_TRACE("property notify"); + vwm_xevent_handle_property_notify(vwm, &event.xproperty); + break; + + case MappingNotify: + VWM_TRACE("mapping notify"); + vwm_xevent_handle_mapping_notify(vwm, &event.xmapping); + break; + + case Expose: + VWM_TRACE("expose"); + break; + + case GravityNotify: + VWM_TRACE("gravitynotify"); + break; + + case ReparentNotify: + VWM_TRACE("reparentnotify"); + break; + + default: + if (event.type == randr_event + RRScreenChangeNotify) { + VWM_TRACE("rrscreenchangenotify"); + if (vwm->xinerama_screens) XFree(vwm->xinerama_screens); + vwm->xinerama_screens = XineramaQueryScreens(VWM_XDISPLAY(vwm), &vwm->xinerama_screens_cnt); + + vwm_composite_invalidate_root(vwm); + } else if (event.type == vwm->damage_event + XDamageNotify) { + //VWM_TRACE("damagenotify"); + vwm_composite_damage_event(vwm, (XDamageNotifyEvent *)&event); + } else { + VWM_ERROR("Unhandled X op %i", event.type); + } + break; + } +} + + +int main(int argc, char *argv[]) +{ + vwm_t *vwm; + struct pollfd pfd; + + if (!(vwm = vwm_startup())) { + VWM_ERROR("Unable to startup vwm"); + goto _err; + } pfd.events = POLLIN; pfd.revents = 0; - pfd.fd = ConnectionNumber(vwm.display); + pfd.fd = ConnectionNumber(VWM_XDISPLAY(vwm)); - while (!vwm.done) { + while (!vwm->done) { do { int delay; - vwm_overlay_update(&vwm, &delay); - XFlush(vwm.display); + vwm_overlay_update(vwm, &delay); + XFlush(VWM_XDISPLAY(vwm)); - if (!XPending(vwm.display)) { + if (!XPending(VWM_XDISPLAY(vwm))) { if (poll(&pfd, 1, delay) == 0) break; } - XNextEvent(vwm.display, &event); - switch (event.type) { - case KeyPress: - VWM_TRACE("keypress"); - vwm_xevent_handle_key_press(&vwm, &event.xkey); - break; - - case KeyRelease: - VWM_TRACE("keyrelease"); - vwm_xevent_handle_key_release(&vwm, &event.xkey); - break; - - case ButtonPress: - VWM_TRACE("buttonpresss"); - vwm_xevent_handle_button_press(&vwm, &event.xbutton); - break; - - case MotionNotify: - //VWM_TRACE("motionnotify"); - vwm_xevent_handle_motion_notify(&vwm, &event.xmotion); - break; - - case ButtonRelease: - VWM_TRACE("buttonrelease"); - vwm_xevent_handle_button_release(&vwm, &event.xbutton); - break; - - case CreateNotify: - VWM_TRACE("createnotify"); - vwm_xevent_handle_create_notify(&vwm, &event.xcreatewindow); - break; - - case DestroyNotify: - VWM_TRACE("destroynotify"); - vwm_xevent_handle_destroy_notify(&vwm, &event.xdestroywindow); - break; - - case ConfigureRequest: - VWM_TRACE("configurerequest"); - vwm_xevent_handle_configure_request(&vwm, &event.xconfigurerequest); - break; - - case ConfigureNotify: - VWM_TRACE("configurenotify"); - vwm_xevent_handle_configure_notify(&vwm, &event.xconfigure); - break; - - case UnmapNotify: - VWM_TRACE("unmapnotify"); - vwm_xevent_handle_unmap_notify(&vwm, &event.xunmap); - break; - - case MapNotify: - VWM_TRACE("mapnotify"); - vwm_xevent_handle_map_notify(&vwm, &event.xmap); - break; - - case MapRequest: - VWM_TRACE("maprequest"); - vwm_xevent_handle_map_request(&vwm, &event.xmaprequest); - break; - - case PropertyNotify: - VWM_TRACE("property notify"); - vwm_xevent_handle_property_notify(&vwm, &event.xproperty); - break; - - case MappingNotify: - VWM_TRACE("mapping notify"); - vwm_xevent_handle_mapping_notify(&vwm, &event.xmapping); - break; - - case Expose: - VWM_TRACE("expose"); - break; - - case GravityNotify: - VWM_TRACE("gravitynotify"); - break; - - case ReparentNotify: - VWM_TRACE("reparentnotify"); - break; - - default: - if (event.type == randr_event + RRScreenChangeNotify) { - VWM_TRACE("rrscreenchangenotify"); - if (vwm.xinerama_screens) XFree(vwm.xinerama_screens); - vwm.xinerama_screens = XineramaQueryScreens(vwm.display, &vwm.xinerama_screens_cnt); - - vwm_composite_invalidate_root(&vwm); - } else if (event.type == vwm.damage_event + XDamageNotify) { - //VWM_TRACE("damagenotify"); - vwm_composite_damage_event(&vwm, (XDamageNotifyEvent *)&event); - } else { - VWM_ERROR("Unhandled X op %i", event.type); - } - break; - } - } while (QLength(vwm.display)); + vwm_process_event(vwm); + } while (QLength(VWM_XDISPLAY(vwm))); - vwm_composite_paint_all(&vwm); + vwm_composite_paint_all(vwm); } - /* tear down console */ - vwm_launch(&vwm, quit_console_args, VWM_LAUNCH_MODE_FG); + vwm_shutdown(vwm); - /* close connection to server */ - XFlush(vwm.display); - XCloseDisplay(vwm.display); + return EXIT_SUCCESS; - return 0; +_err: + return EXIT_FAILURE; } |