/* 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 (e->detail == 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 (e->value_mask & CWStackMode) {
				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]);
	}
}
