/* 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);
		}
	}

	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;

	/* 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;
	}
	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)) {
			XGetWindowAttributes(dpy, c->window, &attr);
			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]);
	}
}
