/*
 * fgconsole.c - aeb - 960123 - Print foreground console
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <linux/kd.h>
#include <fcntl.h>
#include <errno.h>
#include "console.h"


cConsole::cConsole(void) {
	fDesc = getFd(NULL);
}

bool cConsole::SetFG(int sessNum) {
   if (ioctl(fDesc,VT_ACTIVATE, sessNum)) {
      perror("chvt: VT_ACTIVATE");
      return false;
   }
   if (ioctl(fDesc,VT_WAITACTIVE,sessNum)) {
      perror("VT_WAITACTIVE");
      return false;
   }
   return true;
}


int cConsole::QueryFG(void) {
	struct vt_stat vtstat;
	if (ioctl(fDesc, VT_GETSTATE, &vtstat)) {
		perror("fgconsole: VT_GETSTATE");
		return -1;
	}
	return vtstat.v_active;
}


int cConsole::isConsole(int fd) {
	char arg;

	arg = 0;
	return (ioctl(fd, KDGKBTYPE, &arg) == 0
		&& ((arg == KB_101) || (arg == KB_84)));
}

int cConsole::openConsole(const char *fnam) {
   int fd;
	/*
	 * For ioctl purposes we only need some fd and permissions
	 * do not matter. But setfont:activatemap() does a write.
	 */
	fd = open(fnam, O_RDWR);
	if (fd < 0 && errno == EACCES)
		fd = open(fnam, O_WRONLY);
	if (fd < 0 && errno == EACCES)
		fd = open(fnam, O_RDONLY);
	if (fd < 0)
		return -1;
	if (!isConsole(fd)) {
		close(fd);
		return -1;
	}
	return fd;
}

int cConsole::getFd(const char *fnam) {
	int fd;

	if (fnam) {
		fd = openConsole(fnam);
		if (fd >= 0)
			return fd;
		fprintf(stderr,"Couldnt open %s\n", fnam);
		return (-1);
	}

	fd = openConsole("/dev/tty");
	if (fd >= 0)
		return fd;

	fd = openConsole("/dev/tty0");
	if (fd >= 0)
		return fd;

	fd = openConsole("/dev/vc/0");
	if (fd >= 0)
		return fd;

	fd = openConsole("/dev/console");
	if (fd >= 0)
		return fd;

	for (fd = 0; fd < 3; fd++)
		if (isConsole(fd))
			return fd;

	fprintf(stderr,"Couldnt get a file descriptor referring to the console\n");
	return -1;		/* total failure */
}
