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