/*
 * BadWM - minimalistic window manager for the X Window System
 * Copyright (C) Robert Annessi <robert@annessi.at>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include "include/BadWM.h"
#include <X11/Xproto.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "include/config.h"

/* Now do this by fork()ing twice so we don't have to worry about SIGCHLDs */
void spawn(char *cmd, char *args) {
	pid_t pid;
	char **new_args;
	new_args = set_args(args);

	if (current_screen && current_screen->display)
		putenv(current_screen->display);
	if (!(pid = fork())) {
		setsid();
		switch (fork()) {
			case 0:
				execvp(cmd, new_args);
				bad_debug(0, "Couldn't respawn new shell: %s\n", cmd);
				bad_debug(0, "Reason -> %s: %s\n", cmd, strerror(errno));
				break;
			default:
				_exit(0);
		}
	}
	if (pid > 0)
		wait(NULL);
}

void handle_signal(int signo) {
	int i;
	/* SIGCHLD check no longer necessary */
	/* Quit Nicely */
	quitting = 1;
	while(head_client) remove_client(head_client);
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
	if (font) XFreeFont(dpy, font);
	for (i = 0; i < num_screens; i++) {
		XFreeGC(dpy, screens[i].invert_gc);
		XInstallColormap(dpy, DefaultColormap(dpy, screens[i].screen));
	}
	free(screens);
	XCloseDisplay(dpy);
	exit(0);
}

int handle_xerror(Display *dsply, XErrorEvent *e) {
	Client *c = find_client(e->resourceid);

	/* If this error actually occurred while setting up the new
	 * window, best let make_new_client() know not to bother */
	if (initialising != None && e->resourceid == initialising) {
		#ifdef DEBUG
                	bad_debug(1,"**SAVED?** handle_xerror() caught error %d while initialising\n", e->error_code);
		#endif
		initialising = None;
		return 0;
	}
	#ifdef DEBUG
		bad_debug(1,"**ERK** handle_xerror() caught an XErrorEvent: %d\n", e->error_code);           
	#endif
	/* if (e->error_code == BadAccess && e->resourceid == root) { */
	if (e->error_code == BadAccess && e->request_code == X_ChangeWindowAttributes) {
		exit(1);
	}
	#ifdef DEBUG
		 bad_debug(1,"XError %x\n", e->error_code);
	#endif
	/* Kludge aroung IE misbehaviour */
	if (e->error_code == 0x8 && e->request_code == 0x0c && e->minor_code == 0x00) {
		#ifdef DEBUG
                	bad_debug(1,"IE kludge - ignoring XError\n");
		#endif
		return 0;
	}

	if (c) {
		#ifdef DEBUG
                	bad_debug(1,"calling remove_client()\n");
		#endif
		remove_client(c);
	}
	return 0;
}

int ignore_xerror(Display *dsply, XErrorEvent *e) {
	#ifdef DEBUG
		bad_debug(1,"XErrorEvent: %d\n", e->error_code);
	#endif
	return 0;
}

int is_int(char *string)
{
	int i;
	for(i=0; i < strlen(string); i++)
	{
		if(!isdigit(string[i]))
		{
			#ifdef DEBUG
				bad_debug(5, "%s is an invalid integer!\n", string);
			#endif
			return -1;
		}
	}
	return atoi(string);
}


syntax highlighted by Code2HTML, v. 0.9.1