/* 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 KeyPress:
			keypress(&ev.xkey);
			break;
		case KeyRelease:
			keyrelease(&ev.xkey);
			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)
{
	int i;
	Client *c;

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

	if(numvirtuals > 1)
		for(i=0; i<numvirtuals; i++)
			if(currents[i] == c)
				currents[i] = 0;

	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_protocols)
		return;
	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(!ffm)
	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 */
		if(!ffm)
			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]);
	}
}
