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

char	*version[] =
{
	"rio version 1.0, Copyright (c) 1994-1996 David Hogan, (c) 2004 Russ Cox", 0,
};

Display 		*dpy;
ScreenInfo	*screens;
int 			initting;
XFontStruct 	*font;
int 			nostalgia;
char			**myargv;
char			*termprog;
char			*shell;
Bool			shape;
int 			_border = 4;
int 			_corner = 25;
int 			_inset = 1;
int 			curtime;
int 			debug;
int 			signalled;
int 			scrolling;
int 			num_screens;
int			solidsweep = 0;
int			numvirtuals = 0;

Atom		exit_rio;
Atom		restart_rio;
Atom		wm_state;
Atom		wm_change_state;
Atom		wm_protocols;
Atom		wm_delete;
Atom		wm_take_focus;
Atom		wm_lose_focus;
Atom		wm_colormaps;
Atom		_rio_running;
Atom		_rio_hold_mode;

char	*fontlist[] = {
	"lucm.latin1.9",
	"blit",
	"*-lucidatypewriter-bold-*-14-*-75-*",
	"*-lucidatypewriter-medium-*-12-*-75-*",
	"9x15bold",
	"fixed",
	"*",
	0,
};

void
usage(void)
{
	fprintf(stderr, "usage: rio [-grey] [-font fname] [-s] [-term prog] [-version] [-virtuals num] [exit|restart]\n");
	exit(1);
}

int
main(int argc, char *argv[])
{
	int i, background, do_exit, do_restart;
	char *fname;
	int shape_event;
#ifdef SHAPE
	int dummy;
#endif

	shape_event = 0;
	myargv = argv;			/* for restart */

	do_exit = do_restart = 0;
	background = 0;
	font = 0;
	fname = 0;
	for(i = 1; i < argc; i++)
		if(strcmp(argv[i], "-nostalgia") == 0)
			nostalgia++;
		else if(strcmp(argv[i], "-grey") == 0)
			background = 1;
		else if(strcmp(argv[i], "-debug") == 0)
			debug++;
		else if(strcmp(argv[i], "-font") == 0 && i+1<argc){
			i++;
			fname = argv[i];
		}
		else if(strcmp(argv[i], "-term") == 0 && i+1<argc)
			termprog = argv[++i];
		else if(strcmp(argv[i], "-virtuals") == 0 && i+1<argc){
			numvirtuals = atoi(argv[++i]);
			if(numvirtuals < 0 || numvirtuals > 12){
				fprintf(stderr, "rio: wrong number of virtual displays, defaulting to 4\n");
				numvirtuals = 4;
			}
		} else if(strcmp(argv[i], "-version") == 0){
			fprintf(stderr, "%s", version[0]);
			if(PATCHLEVEL > 0)
				fprintf(stderr, "; patch level %d", PATCHLEVEL);
			fprintf(stderr, "\n");
			exit(0);
		}
		else if(strcmp(argv[i], "-s") == 0){
			scrolling = 1;
		}
		else if(argv[i][0] == '-')
			usage();
		else
			break;
	for(; i < argc; i++)
		if(strcmp(argv[i], "exit") == 0)
			do_exit++;
		else if(strcmp(argv[i], "restart") == 0)
			do_restart++;
		else
			usage();

	if(do_exit && do_restart)
		usage();

	shell = (char *)getenv("SHELL");
	if(shell == NULL)
		shell = DEFSHELL;

	dpy = XOpenDisplay("");
	if(dpy == 0)
		fatal("can't open display");

	initting = 1;
	XSetErrorHandler(handler);
	if(signal(SIGTERM, sighandler) == SIG_IGN)
		signal(SIGTERM, SIG_IGN);
	if(signal(SIGINT, sighandler) == SIG_IGN)
		signal(SIGINT, SIG_IGN);
	if(signal(SIGHUP, sighandler) == SIG_IGN)
		signal(SIGHUP, SIG_IGN);

	exit_rio = XInternAtom(dpy, "9WM_EXIT", False);
	restart_rio = XInternAtom(dpy, "9WM_RESTART", False);

	curtime = -1;		/* don't care */
	if(do_exit){
		sendcmessage(DefaultRootWindow(dpy), exit_rio, 0L, 1, 1);
		XSync(dpy, False);
		exit(0);
	}
	if(do_restart){
		sendcmessage(DefaultRootWindow(dpy), restart_rio, 0L, 1, 1);
		XSync(dpy, False);
		exit(0);
	}

	if(0) XSynchronize(dpy, True);

	wm_state = XInternAtom(dpy, "WM_STATE", False);
	wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False);
	wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
	wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
	wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
	wm_lose_focus = XInternAtom(dpy, "_9WM_LOSE_FOCUS", False);
	wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
	_rio_running = XInternAtom(dpy, "_9WM_RUNNING", False);
	_rio_hold_mode = XInternAtom(dpy, "_9WM_HOLD_MODE", False);

	if(fname != 0)
		if((font = XLoadQueryFont(dpy, fname)) == 0)
			fprintf(stderr, "rio: warning: can't load font %s\n", fname);

	if(font == 0){
		i = 0;
		for(;;){
			fname = fontlist[i++];
			if(fname == 0){
				fprintf(stderr, "rio: warning: can't find a font\n");
				break;
			}
			font = XLoadQueryFont(dpy, fname);
			if(font != 0)
				break;
		}
	}
	if(nostalgia){
		_border--;
		_inset--;
	}

#ifdef	SHAPE
	shape = XShapeQueryExtension(dpy, &shape_event, &dummy);
#endif

	num_screens = ScreenCount(dpy);
	screens = (ScreenInfo *)malloc(sizeof(ScreenInfo) * num_screens);

	for(i = 0; i < num_screens; i++)
		initscreen(&screens[i], i, background);

	initb2menu(numvirtuals);

	/* set selection so that 9term knows we're running */
	curtime = CurrentTime;
	XSetSelectionOwner(dpy, _rio_running, screens[0].menuwin, timestamp());

	XSync(dpy, False);
	initting = 0;

	nofocus();

	for(i = 0; i < num_screens; i++)
		scanwins(&screens[i]);

	keysetup();
	mainloop(shape_event);
	return 0;
}

void
initscreen(ScreenInfo *s, int i, int background)
{
	char *ds, *colon, *dot1;
	unsigned long mask;
	unsigned long gmask;
	XGCValues gv;
	XSetWindowAttributes attr;
	XVisualInfo xvi;
	XSetWindowAttributes attrs;

	s->num = i;
	s->root = RootWindow(dpy, i);
	s->def_cmap = DefaultColormap(dpy, i);
	s->min_cmaps = MinCmapsOfScreen(ScreenOfDisplay(dpy, i));
	s->depth = DefaultDepth(dpy, i);

	/* 
	 * Figure out underlying screen format.
	 */
	if(XMatchVisualInfo(dpy, i, 16, TrueColor, &xvi)
	|| XMatchVisualInfo(dpy, i, 16, DirectColor, &xvi)){
		s->vis = xvi.visual;
		s->depth = 16;
	}
	else
	if(XMatchVisualInfo(dpy, i, 15, TrueColor, &xvi)
	|| XMatchVisualInfo(dpy, i, 15, DirectColor, &xvi)){
		s->vis = xvi.visual;
		s->depth = 15;
	}
	else
	if(XMatchVisualInfo(dpy, i, 24, TrueColor, &xvi)
	|| XMatchVisualInfo(dpy, i, 24, DirectColor, &xvi)){
		s->vis = xvi.visual;
		s->depth = 24;
	}
	else
	if(XMatchVisualInfo(dpy, i, 8, PseudoColor, &xvi)
	|| XMatchVisualInfo(dpy, i, 8, StaticColor, &xvi)){
		s->vis = xvi.visual;
		s->depth = 8;
	}
	else{
		s->depth = DefaultDepth(dpy, i);
		if(s->depth != 8){
			fprintf(stderr, "can't understand depth %d screen", s->depth);
			exit(1);
		}
		s->vis = DefaultVisual(dpy, i);
	}
	if(DefaultDepth(dpy, i) != s->depth){
		s->def_cmap = XCreateColormap(dpy, s->root, s->vis, AllocNone); 
	}

	ds = DisplayString(dpy);
	colon = rindex(ds, ':');
	if(colon && num_screens > 1){
		strcpy(s->display, "DISPLAY=");
		strcat(s->display, ds);
		colon = s->display + 8 + (colon - ds);	/* use version in buf */
		dot1 = index(colon, '.');	/* first period after colon */
		if(!dot1)
			dot1 = colon + strlen(colon);	/* if not there, append */
		sprintf(dot1, ".%d", i);
	}
	else
		s->display[0] = '\0';

	s->black = BlackPixel(dpy, i);
	s->white = WhitePixel(dpy, i);
	s->activeholdborder = colorpixel(dpy, s, s->depth, 0x000099, s->white);
	s->inactiveholdborder = colorpixel(dpy, s, s->depth, 0x005DBB, s->black);
	s->activeborder = colorpixel(dpy, s, s->depth, 0x55AAAA, s->black);
	s->inactiveborder = colorpixel(dpy, s, s->depth, 0x9EEEEE, s->white);
	s->red = colorpixel(dpy, s, s->depth, 0xDD0000, s->white);
	s->width = WidthOfScreen(ScreenOfDisplay(dpy, i));
	s->height = HeightOfScreen(ScreenOfDisplay(dpy, i));
	s->bkup[0] = XCreatePixmap(dpy, s->root, 2*s->width, BORDER, DefaultDepth(dpy, i));
	s->bkup[1] = XCreatePixmap(dpy, s->root, BORDER, 2*s->height, DefaultDepth(dpy, i));

	gv.foreground = s->black^s->white;
	gv.background = s->white;
	gv.function = GXxor;
	gv.line_width = 0;
	gv.subwindow_mode = IncludeInferiors;
	gmask = GCForeground | GCBackground | GCFunction | GCLineWidth
		| GCSubwindowMode;
	if(font != 0){
		gv.font = font->fid;
		gmask |= GCFont;
	}
	s->gc = XCreateGC(dpy, s->root, gmask, &gv);

	gv.function = GXcopy;
	s->gccopy = XCreateGC(dpy, s->root, gmask, &gv);

	gv.foreground = s->red;
	s->gcred = XCreateGC(dpy, s->root, gmask, &gv);

	gv.foreground = colorpixel(dpy, s, s->depth, 0xEEEEEE, s->black);
	s->gcsweep = XCreateGC(dpy, s->root, gmask, &gv);

	initcurs(s);

	attr.cursor = s->arrow;
	attr.event_mask = SubstructureRedirectMask
		| SubstructureNotifyMask | ColormapChangeMask
		| ButtonPressMask | ButtonReleaseMask | PropertyChangeMask |
		KeyPressMask;
	mask = CWCursor|CWEventMask;
	XChangeWindowAttributes(dpy, s->root, mask, &attr);
	XSync(dpy, False);

	if(background){
		XSetWindowBackgroundPixmap(dpy, s->root, s->root_pixmap);
		XClearWindow(dpy, s->root);
	} else
		system("xsetroot -solid grey30");

	attrs.border_pixel =  colorpixel(dpy, s, s->depth, 0x88CC88, s->black);
	attrs.background_pixel =  colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
	attrs.colormap = s->def_cmap;

	s->menuwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 2,
						s->depth,
						CopyFromParent,
						s->vis,
						CWBackPixel | CWBorderPixel | CWColormap,
						&attrs
						);


	gv.foreground = colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
	s->gcmenubg = XCreateGC(dpy, s->menuwin, gmask, &gv);

	gv.foreground = colorpixel(dpy, s, s->depth, 0x448844, s->black);
	s->gcmenubgs = XCreateGC(dpy, s->menuwin, gmask, &gv);

	gv.foreground = s->black;
	gv.background = colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
	s->gcmenufg = XCreateGC(dpy, s->menuwin, gmask, &gv);

	gv.foreground = colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
	gv.background = colorpixel(dpy, s, s->depth, 0x448844, s->black);
	s->gcmenufgs = XCreateGC(dpy, s->menuwin, gmask, &gv);

	attrs.border_pixel =  s->red;
	attrs.background_pixel =  colorpixel(dpy, s, s->depth, 0xEEEEEE, s->black);
	attrs.colormap = s->def_cmap;
	s->sweepwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 4,
						s->depth,
						CopyFromParent,
						s->vis,
						CWBackPixel | CWBorderPixel | CWColormap,
						&attrs
						);
}

ScreenInfo*
getscreen(Window w)
{
	int i;

	for(i = 0; i < num_screens; i++)
		if(screens[i].root == w)
			return &screens[i];

	return 0;
}

Time
timestamp(void)
{
	XEvent ev;

	if(curtime == CurrentTime){
		XChangeProperty(dpy, screens[0].root, _rio_running, _rio_running, 8,
				PropModeAppend, (unsigned char *)"", 0);
		XMaskEvent(dpy, PropertyChangeMask, &ev);
		curtime = ev.xproperty.time;
	}
	return curtime;
}

void
sendcmessage(Window w, Atom a, long x, int isroot, int usemask)
{
	XEvent ev;
	int status;
	long mask;

	memset(&ev, 0, sizeof(ev));
	ev.xclient.type = ClientMessage;
	ev.xclient.window = w;
	ev.xclient.message_type = a;
	ev.xclient.format = 32;
	ev.xclient.data.l[0] = x;
	ev.xclient.data.l[1] = timestamp();
	mask = 0;
	if(usemask){
		mask |= KeyPressMask;	/* seems to be necessary */
		if(isroot)
			mask |= SubstructureRedirectMask;		/* magic! */
		else
			mask |= ExposureMask;	/* not really correct but so be it */
	}
	status = XSendEvent(dpy, w, False, mask, &ev);
	if(status == 0)
		fprintf(stderr, "rio: sendcmessage failed\n");
}

void
sendconfig(Client *c)
{
	XConfigureEvent ce;

	ce.type = ConfigureNotify;
	ce.event = c->window;
	ce.window = c->window;
	ce.x = c->x;
	ce.y = c->y;
	ce.width = c->dx;
	ce.height = c->dy;
	ce.border_width = c->border;
	ce.above = None;
	ce.override_redirect = 0;
	XSendEvent(dpy, c->window, False, StructureNotifyMask, (XEvent*)&ce);
}

void
sighandler(void)
{
	signalled = 1;
}

void
getevent(XEvent *e)
{
	int fd;
	fd_set rfds;
	struct timeval t;

	if(!signalled){
		if(QLength(dpy) > 0){
			XNextEvent(dpy, e);
			return;
		}
		fd = ConnectionNumber(dpy);
		FD_ZERO(&rfds);
		FD_SET(fd, &rfds);
		t.tv_sec = t.tv_usec = 0;
		if(select(fd+1, &rfds, NULL, NULL, &t) == 1){
			XNextEvent(dpy, e);
			return;
		}
		XFlush(dpy);
		FD_SET(fd, &rfds);
		if(select(fd+1, &rfds, NULL, NULL, NULL) == 1){
			XNextEvent(dpy, e);
			return;
		}
		if(errno != EINTR || !signalled){
			perror("rio: select failed");
			exit(1);
		}
	}
	fprintf(stderr, "rio: exiting on signal\n");
	cleanup();
	exit(1);
}

void
cleanup(void)
{
	Client *c, *cc[2], *next;
	XWindowChanges wc;
	int i;

	/* order of un-reparenting determines final stacking order... */
	cc[0] = cc[1] = 0;
	for(c = clients; c; c = next){
		next = c->next;
		i = normal(c);
		c->next = cc[i];
		cc[i] = c;
	}

	for(i = 0; i < 2; i++){
		for(c = cc[i]; c; c = c->next){
			if(!withdrawn(c)){
				gravitate(c, 1);
				XReparentWindow(dpy, c->window, c->screen->root,
						c->x, c->y);
			}
			wc.border_width = c->border;
			XConfigureWindow(dpy, c->window, CWBorderWidth, &wc);
		}
	}

	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, timestamp());
	for(i = 0; i < num_screens; i++)
		cmapnofocus(&screens[i]);
	XCloseDisplay(dpy);
}
