/* TinyWM is written by Nick Welch <[email protected]> in 2005 & 2011.
* This software is in the public domain and is provided AS IS with NO WARRANTY
*
* tfurrows: added actions for mod1+left click and mod1+middle click
*           added exit(0) on mod1+right click at screen position 0,0
*           added mod1+F2 to lower focus window
*           added mod1+F3 to shrink window or restore
*           added mod1+F4 to close/destroy window
*/

#include <X11/Xlib.h>
#include <stdlib.h>

#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define LCRUN "/usr/bin/xterm -fg white -bg black &"
#define MCRUN "/usr/bin/perl /home/jlyman/bin/deskpad &"

int main(void) {

       Display * dpy;
       XWindowAttributes attr;
       XButtonEvent start;
       XEvent ev;

       if(!(dpy = XOpenDisplay(0x0))) return 1;

       XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F1")), Mod1Mask,
               DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
       XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F2")), Mod1Mask,
               DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
       XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F3")), Mod1Mask,
               DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
       XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F4")), Mod1Mask,
               DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);

       XGrabButton(dpy, 1, Mod1Mask, DefaultRootWindow(dpy), True,
               ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
       XGrabButton(dpy, 2, Mod1Mask, DefaultRootWindow(dpy), True,
               ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
       XGrabButton(dpy, 3, Mod1Mask, DefaultRootWindow(dpy), True,
               ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);

       start.subwindow = None;
       for(;;) {
               XNextEvent(dpy, &ev);
               if(ev.type == KeyPress && ev.xkey.subwindow != None) {
                       switch(ev.xkey.keycode) {
                               case 0x43:
                                       XRaiseWindow(dpy, ev.xkey.subwindow);
                                       XSetInputFocus(dpy, ev.xkey.subwindow, RevertToPointerRoot, CurrentTime);
                                       XSync(dpy,True);
                                       break;
                               case 0x44:
                                       XLowerWindow(dpy, ev.xkey.subwindow);
                                       break;
                               case 0x45:
                                       XGetWindowAttributes(dpy, ev.xbutton.subwindow, &attr);
                                       if(attr.width == 150) {
                                               XResizeWindow(dpy, ev.xkey.subwindow, 500, 300);
                                               XRaiseWindow(dpy, ev.xkey.subwindow);
                                       } else {
                                               XResizeWindow(dpy, ev.xkey.subwindow, 150, 20);
                                               XLowerWindow(dpy, ev.xkey.subwindow);
                                       }
                                       break;
                               case 0x46:
                                       XDestroyWindow(dpy, ev.xkey.subwindow);
                                       break;
                       }
               } else if(ev.type == ButtonPress && ev.xbutton.subwindow != None) {
                       XGetWindowAttributes(dpy, ev.xbutton.subwindow, &attr);
                       start = ev.xbutton;
                       XRaiseWindow(dpy, start.subwindow);
                       XSetInputFocus(dpy, start.subwindow, RevertToPointerRoot, CurrentTime);
                       XSync(dpy,True);
               } else if(ev.type == MotionNotify && start.subwindow != None) {
                       int xdiff = ev.xbutton.x_root - start.x_root;
                       int ydiff = ev.xbutton.y_root - start.y_root;
                       XMoveResizeWindow(dpy, start.subwindow,
                       attr.x + (start.button==1 ? xdiff : 0),
                       attr.y + (start.button==1 ? ydiff : 0),
                       MAX(1, attr.width + (start.button==3 ? xdiff : 0)),
                       MAX(1, attr.height + (start.button==3 ? ydiff : 0)));
               } else if(ev.type == ButtonPress && ev.xbutton.subwindow == 0) {
                       switch(ev.xbutton.button) {
                               case Button1:
                                       system(LCRUN);
                                       break;
                               case Button2:
                                       system(MCRUN);
                                       break;
                               case Button3:
                                       if(ev.xbutton.x == 0 && ev.xbutton.y == 0)
                                               exit(0);
                                       break;
                       }
               } else if(ev.type == ButtonRelease) {
                       start.subwindow = None;
               }
       }
}