/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
#include <stdio.h>
#include <stdlib.h>
#include <X11/X.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#include "dat.h"
#include "fns.h"
#include "patchlevel.h"

void
mainloop(int shape_event)
{
	XEvent ev;

	for (;;) {
		getevent(&ev);

#ifdef	DEBUG_EV
		if (debug) {
			ShowEvent(&ev);
			printf("\n");
		}
#endif
		switch (ev.type) {
		default:
#ifdef	SHAPE
			if (shape && ev.type == shape_event)
				shapenotify((XShapeEvent *)&ev);
			else
#endif
				fprintf(stderr, "rio: unknown ev.type %d\n", ev.type);
			break;
		case ButtonPress:
			button(&ev.xbutton);
			break;
		case ButtonRelease:
			break;
		case MapRequest:
			mapreq(&ev.xmaprequest);
			break;
		case ConfigureRequest:
			configurereq(&ev.xconfigurerequest);
			break;
		case CirculateRequest:
			circulatereq(&ev.xcirculaterequest);
			break;
		case UnmapNotify:
			unmap(&ev.xunmap);
			break;
		case CreateNotify:
			newwindow(&ev.xcreatewindow);
			break;
		case DestroyNotify:
			destroy(ev.xdestroywindow.window);
			break;
		case ClientMessage:
			clientmesg(&ev.xclient);
			break;
		case ColormapNotify:
			cmap(&ev.xcolormap);
			break;
		case PropertyNotify:
			property(&ev.xproperty);
			break;
		case SelectionClear:
			fprintf(stderr, "rio: SelectionClear (this should not happen)\n");
			break;
		case SelectionNotify:
			fprintf(stderr, "rio: SelectionNotify (this should not happen)\n");
			break;
		case SelectionRequest:
			fprintf(stderr, "rio: SelectionRequest (this should not happen)\n");
			break;
		case EnterNotify:
			enter(&ev.xcrossing);
			break;
		case LeaveNotify:
			leave(&ev.xcrossing);
			break;
		case ReparentNotify:
			reparent(&ev.xreparent);
			break;
		case FocusIn:
			focusin(&ev.xfocus);
			break;
		case MotionNotify:
			motionnotify(&ev.xmotion);
			break;
		case Expose:
		case NoExpose:
		case FocusOut:
		case ConfigureNotify:
		case MapNotify:
		case MappingNotify:
		case GraphicsExpose:
			/* not interested */
			trace("ignore", 0, &ev);
			break;
		}
	}
}


void
configurereq(XConfigureRequestEvent *e)
{
	XWindowChanges wc;
	Client *c;

	/* we don't set curtime as nothing here uses it */
	c = getclient(e->window, 0);
	trace("configurereq", c, e);

	e->value_mask &= ~CWSibling;

	if (c) {
		gravitate(c, 1);
		if (e->value_mask & CWX)
			c->x = e->x;
		if (e->value_mask & CWY)
			c->y = e->y;
		if (e->value_mask & CWWidth)
			c->dx = e->width;
		if (e->value_mask & CWHeight)
			c->dy = e->height;
		if (e->value_mask & CWBorderWidth)
			c->border = e->border_width;
		gravitate(c, 0);
		if (e->value_mask & CWStackMode) {
			if (wc.stack_mode == Above)
				top(c);
			else
				e->value_mask &= ~CWStackMode;
		}
		if (c->parent != c->screen->root && c->window == e->window) {
			wc.x = c->x-BORDER;
			wc.y = c->y-BORDER;
			wc.width = c->dx+2*BORDER;
			wc.height = c->dy+2*BORDER;
			wc.border_width = 1;
			wc.sibling = None;
			wc.stack_mode = e->detail;
			XConfigureWindow(dpy, c->parent, e->value_mask, &wc);
			sendconfig(c);
			top(c);	
			active(c);
		}
	}

	if (c && c->init) {
		wc.x = BORDER;
		wc.y = BORDER;
	}
	else {
		wc.x = e->x;
		wc.y = e->y;
	}
	wc.width = e->width;
	wc.height = e->height;
	wc.border_width = 0;
	wc.sibling = None;
	wc.stack_mode = Above;
	e->value_mask &= ~CWStackMode;
	e->value_mask |= CWBorderWidth;

	XConfigureWindow(dpy, e->window, e->value_mask, &wc);
}

void
mapreq(XMapRequestEvent *e)
{
	Client *c;
	int i;

	curtime = CurrentTime;
	c = getclient(e->window, 0);
	trace("mapreq", c, e);

	if (c == 0 || c->window != e->window) {
		/* workaround for stupid NCDware */
		fprintf(stderr, "rio: bad mapreq c %p w %x, rescanning\n",
			c, (int)e->window);
		for (i = 0; i < num_screens; i++)
			scanwins(&screens[i]);
		c = getclient(e->window, 0);
		if (c == 0 || c->window != e->window) {
			fprintf(stderr, "rio: window not found after rescan\n");
			return;
		}
	}

	switch (c->state) {
	case WithdrawnState:
		if (c->parent == c->screen->root) {
			if (!manage(c, 0))
				return;
			break;
		}
		XReparentWindow(dpy, c->window, c->parent, BORDER-1, BORDER-1);
		XAddToSaveSet(dpy, c->window);
		/* fall through... */
	case NormalState:
		XMapWindow(dpy, c->window);
		XMapRaised(dpy, c->parent);
		top(c);
		setstate(c, NormalState);
		if (c->trans != None && current && c->trans == current->window)
				active(c);
		break;
	case IconicState:
		unhidec(c, 1);
		break;
	}
}

void
unmap(XUnmapEvent *e)
{
	Client *c;

	curtime = CurrentTime;
	c = getclient(e->window, 0);
	if (c) {
		switch (c->state) {
		case IconicState:
			if (e->send_event) {
				unhidec(c, 0);
				withdraw(c);
			}
			break;
		case NormalState:
			if (c == current)
				nofocus();
			if (!c->reparenting)
				withdraw(c);
			break;
		}
		c->reparenting = 0;
	}
}

void
circulatereq(XCirculateRequestEvent *e)
{
	fprintf(stderr, "It must be the warlock Krill!\n");  /* ☺ */
}

void
newwindow(XCreateWindowEvent *e)
{
	Client *c;
	ScreenInfo *s;

	/* we don't set curtime as nothing here uses it */
	if (e->override_redirect)
		return;
	c = getclient(e->window, 1);
	if (c && c->window == e->window && (s = getscreen(e->parent))) {
		c->x = e->x;
		c->y = e->y;
		c->dx = e->width;
		c->dy = e->height;
		c->border = e->border_width;
		c->screen = s;
		if (c->parent == None)
			c->parent = c->screen->root;
	}
}

void
destroy(Window w)
{
	Client *c;

	curtime = CurrentTime;
	c = getclient(w, 0);
	if (c == 0)
		return;

	rmclient(c);

	/* flush any errors generated by the window's sudden demise */
	ignore_badwindow = 1;
	XSync(dpy, False);
	ignore_badwindow = 0;
}

void
clientmesg(XClientMessageEvent *e)
{
	Client *c;

	curtime = CurrentTime;
	if (e->message_type == exit_rio) {
		cleanup();
		exit(0);
	}
	if (e->message_type == restart_rio) {
		fprintf(stderr, "*** rio restarting ***\n");
		cleanup();
		execvp(myargv[0], myargv);
		perror("rio: exec failed");
		exit(1);
	}
	if (e->message_type == wm_change_state) {
		c = getclient(e->window, 0);
		if (e->format == 32 && e->data.l[0] == IconicState && c != 0) {
			if (normal(c))
				hide(c);
		}
		else
			fprintf(stderr, "rio: WM_CHANGE_STATE: format %d data %d w 0x%x\n",
				(int)e->format, (int)e->data.l[0], (int)e->window);
		return;
	}
	fprintf(stderr, "rio: strange ClientMessage, type 0x%x window 0x%x\n",
		(int)e->message_type, (int)e->window);
}

void
cmap(XColormapEvent *e)
{
	Client *c;
	int i;

	/* we don't set curtime as nothing here uses it */
	if (e->new) {
		c = getclient(e->window, 0);
		if (c) {
			c->cmap = e->colormap;
			if (c == current)
				cmapfocus(c);
		}
		else
			for (c = clients; c; c = c->next) {
				for (i = 0; i < c->ncmapwins; i++)
					if (c->cmapwins[i] == e->window) {
						c->wmcmaps[i] = e->colormap;
						if (c == current)
							cmapfocus(c);
						return;
					}
			}
	}
}

void
property(XPropertyEvent *e)
{
	Atom a;
	int delete;
	Client *c;
	long msize;

	/* we don't set curtime as nothing here uses it */
	a = e->atom;
	delete = (e->state == PropertyDelete);
	c = getclient(e->window, 0);
	if (c == 0)
		return;

	switch (a) {
	case XA_WM_ICON_NAME:
		if (c->iconname != 0)
			XFree((char*) c->iconname);
		c->iconname = delete ? 0 : getprop(c->window, a);
		setlabel(c);
		renamec(c, c->label);
		return;
	case XA_WM_NAME:
		if (c->name != 0)
			XFree((char*) c->name);
		c->name = delete ? 0 : getprop(c->window, a);
		setlabel(c);
		renamec(c, c->label);
		return;
	case XA_WM_TRANSIENT_FOR:
		gettrans(c);
		return;
	case XA_WM_HINTS:
	case XA_WM_SIZE_HINTS:
	case XA_WM_ZOOM_HINTS:
		/* placeholders to not forget.  ignore for now.  -Axel */
		return;
	case XA_WM_NORMAL_HINTS:
		if (XGetWMNormalHints(dpy, c->window, &c->size, &msize) == 0 || c->size.flags == 0)
			c->size.flags = PSize;	/* not specified - punt */
		return;
	}
	if (a == _rio_hold_mode) {
		c->hold = getiprop(c->window, _rio_hold_mode);
		if (c == current)
			draw_border(c, 1);
	}
	else if (a == wm_colormaps) {
		getcmaps(c);
		if (c == current)
			cmapfocus(c);
	}
}

void
reparent(XReparentEvent *e)
{
	Client *c;
	XWindowAttributes attr;
	ScreenInfo *s;

	/* we don't set curtime as nothing here uses it */
	if (!getscreen(e->event) || e->override_redirect)
		return;
	if ((s = getscreen(e->parent)) != 0) {
		c = getclient(e->window, 1);
		if (c != 0 && (c->dx == 0 || c->dy == 0)) {
			/* flush any errors */
			ignore_badwindow = 1;
			XGetWindowAttributes(dpy, c->window, &attr);
			XSync(dpy, False);
			ignore_badwindow = 0;

			c->x = attr.x;
			c->y = attr.y;
			c->dx = attr.width;
			c->dy = attr.height;
			c->border = attr.border_width;
			c->screen = s;
			if (c->parent == None)
				c->parent = c->screen->root;
		}
	}
	else {
		c = getclient(e->window, 0);
		if (c != 0 && (c->parent == c->screen->root || withdrawn(c)))
			rmclient(c);
	}
}

#ifdef	SHAPE
void
shapenotify(XShapeEvent *e)
{
	Client *c;

	/* we don't set curtime as nothing here uses it */
	c = getclient(e->window, 0);
	if (c == 0)
		return;

	setshape(c);
}
#endif

void
enter(XCrossingEvent *e)
{
	Client *c;

	curtime = e->time;
	if (e->mode != NotifyGrab || e->detail != NotifyNonlinearVirtual)
		return;
	c = getclient(e->window, 0);
	if (c != 0 && c != current) {
		/* someone grabbed the pointer; make them current */
		XMapRaised(dpy, c->parent);
		top(c);
		active(c);
	}
}

void
leave(XCrossingEvent *e)
{
	Client *c;

	c = getclient(e->window, 0);
	if (c)
		XUndefineCursor(dpy, c->parent);
/* 	XDefineCursor(dpy, c->parent, c->screen->arrow); */
}

void
focusin(XFocusChangeEvent *e)
{
	Client *c;

	curtime = CurrentTime;
	if (e->detail != NotifyNonlinearVirtual)
		return;
	c = getclient(e->window, 0);
	if (c != 0 && c->window == e->window && c != current) {
		/* someone grabbed keyboard or seized focus; make them current */
		XMapRaised(dpy, c->parent);
		top(c);
		active(c);
	}
}

BorderOrient
borderorient(Client *c, int x, int y)
{
	if (x <= BORDER) {
		if (y <= CORNER) {
			if (debug) fprintf(stderr, "topleft\n");
			return BorderWNW;
		}
		if (y >= (c->dy + 2*BORDER) - CORNER) {
			if (debug) fprintf(stderr, "botleft\n");
			return BorderWSW;
		}
		if (y > CORNER &&
	        y < (c->dy + 2*BORDER) - CORNER) {
			if (debug) fprintf(stderr, "left\n");
			return BorderW;
		}
	} else if (x <= CORNER) {
		if (y <= BORDER) {
			if (debug) fprintf(stderr, "topleft\n");
			return BorderNNW;
		}
		if  (y >= (c->dy + BORDER)) {
			if (debug) fprintf(stderr, "botleft\n");
			return BorderSSW;
		}
	} else if (x >= (c->dx + BORDER)) {
		if (y <= CORNER) {
			if (debug) fprintf(stderr, "topright\n");
			return BorderENE;
		}
		if (y >= (c->dy + 2*BORDER) - CORNER) {
			if (debug) fprintf(stderr, "botright\n");
			return BorderESE;
		}
		if (y > CORNER &&
			y < (c->dy + 2*BORDER) - CORNER) {
			if (debug) fprintf(stderr, "right\n");
			return BorderE;
		}
	} else if (x >= (c->dx + 2*BORDER) - CORNER) {
		if (y <= BORDER) {
			if (debug) fprintf(stderr, "topright\n");
			return BorderNNE;
		}
		if  (y >= (c->dy + BORDER)) {
			if (debug) fprintf(stderr, "botright\n");
			return BorderSSE;
		}
	} else if (x > CORNER &&
		       x < (c->dx + 2*BORDER) - CORNER) {
		if (y <= BORDER) {
			if (debug) fprintf(stderr, "top\n");
			return BorderN;
		}
		if (y >= (c->dy + BORDER)) {
			if (debug) fprintf(stderr, "bot\n");
			return BorderS;
		}
	}
	return BorderUnknown;
}

void
motionnotify(XMotionEvent *e)
{
	Client *c;
	BorderOrient bl;

	c = getclient(e->window, 0);
	if (c) {
		bl = borderorient(c, e->x, e->y);
		if (bl == BorderUnknown)
			XUndefineCursor(dpy, c->parent);
		else
			XDefineCursor(dpy, c->parent, c->screen->bordcurs[bl]);
	}
}
