Blame src/setvtrgb.c

Packit Service 50ad14
#include "config.h"
Packit Service 50ad14
Packit Service 50ad14
#include <stdio.h>
Packit Service 50ad14
#include <stdlib.h>
Packit Service 50ad14
#include <unistd.h>
Packit Service 50ad14
#include <getopt.h>
Packit Service 50ad14
#include <sys/ioctl.h>
Packit Service 50ad14
#include <linux/kd.h>
Packit Service 50ad14
#include <errno.h>
Packit Service 50ad14
#include "kbd.h"
Packit Service 50ad14
#include "getfd.h"
Packit Service 50ad14
#include "nls.h"
Packit Service 50ad14
#include "version.h"
Packit Service 50ad14
#include "kbd_error.h"
Packit Service 50ad14
Packit Service 50ad14
static unsigned char cmap[3 * 16];
Packit Service 50ad14
Packit Service 50ad14
/* Standard VGA terminal colors, matching those hardcoded in the Linux kernel's
Packit Service 50ad14
 * drivers/char/vt.c
Packit Service 50ad14
 */
Packit Service 50ad14
unsigned char vga_colors[] = {
Packit Service 50ad14
	0x00, 0x00, 0x00,
Packit Service 50ad14
	0xaa, 0x00, 0x00,
Packit Service 50ad14
	0x00, 0xaa, 0x00,
Packit Service 50ad14
	0xaa, 0x55, 0x00,
Packit Service 50ad14
	0x00, 0x00, 0xaa,
Packit Service 50ad14
	0xaa, 0x00, 0xaa,
Packit Service 50ad14
	0x00, 0xaa, 0xaa,
Packit Service 50ad14
	0xaa, 0xaa, 0xaa,
Packit Service 50ad14
	0x55, 0x55, 0x55,
Packit Service 50ad14
	0xff, 0x55, 0x55,
Packit Service 50ad14
	0x55, 0xff, 0x55,
Packit Service 50ad14
	0xff, 0xff, 0x55,
Packit Service 50ad14
	0x55, 0x55, 0xff,
Packit Service 50ad14
	0xff, 0x55, 0xff,
Packit Service 50ad14
	0x55, 0xff, 0xff,
Packit Service 50ad14
	0xff, 0xff, 0xff,
Packit Service 50ad14
};
Packit Service 50ad14
Packit Service 50ad14
static void __attribute__((noreturn))
Packit Service 50ad14
usage(int code)
Packit Service 50ad14
{
Packit Service 50ad14
	fprintf(stderr,
Packit Service 50ad14
	        _("Usage: %s [-h] [-V]\n"
Packit Service 50ad14
	          "       %s vga|FILE|-\n"
Packit Service 50ad14
	          "\n"
Packit Service 50ad14
	          "If you use the FILE parameter, FILE should be exactly 3 lines of\n"
Packit Service 50ad14
	          "comma-separated decimal values for RED, GREEN, and BLUE.\n"
Packit Service 50ad14
	          "\n"
Packit Service 50ad14
	          "To seed a valid FILE:\n"
Packit Service 50ad14
	          "   cat /sys/module/vt/parameters/default_{red,grn,blu} > FILE\n"
Packit Service 50ad14
	          "\n"
Packit Service 50ad14
	          "and then edit the values in FILE.\n"
Packit Service 50ad14
	          "\n"
Packit Service 50ad14
	          "Other options:\n"
Packit Service 50ad14
	          "   -h     print this usage message\n"
Packit Service 50ad14
	          "   -V     print version number\n"
Packit Service 50ad14
	          "\n"),
Packit Service 50ad14
	        progname, progname);
Packit Service 50ad14
	exit(code);
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
static void
Packit Service 50ad14
parse_file(FILE *fd, const char *filename)
Packit Service 50ad14
{
Packit Service 50ad14
	int c;
Packit Service 50ad14
	unsigned int rows, cols, val;
Packit Service 50ad14
Packit Service 50ad14
	for (rows = 0; rows < 3; rows++) {
Packit Service 50ad14
		for (cols = 0; cols < 16; cols++) {
Packit Service 50ad14
			if ((c = fscanf(fd, "%u", &val)) != 1) {
Packit Service 50ad14
				if (c == EOF)
Packit Service 50ad14
					kbd_error(EXIT_FAILURE, errno, "fscanf");
Packit Service 50ad14
Packit Service 50ad14
				kbd_error(EXIT_FAILURE, 0, _("Error: %s: Invalid value in field %u in line %u."),
Packit Service 50ad14
				          filename, rows + 1, cols + 1);
Packit Service 50ad14
			}
Packit Service 50ad14
Packit Service 50ad14
			cmap[rows + cols * 3] = (unsigned char)val;
Packit Service 50ad14
Packit Service 50ad14
			if (cols < 15 && fgetc(fd) != ',')
Packit Service 50ad14
				kbd_error(EXIT_FAILURE, 0, _("Error: %s: Insufficient number of fields in line %u."),
Packit Service 50ad14
				          filename, rows + 1);
Packit Service 50ad14
		}
Packit Service 50ad14
Packit Service 50ad14
		if ((c = fgetc(fd)) == EOF)
Packit Service 50ad14
			kbd_error(EXIT_FAILURE, 0, _("Error: %s: Line %u has ended unexpectedly.\n"),
Packit Service 50ad14
			          filename, rows + 1);
Packit Service 50ad14
Packit Service 50ad14
		if (c != '\n')
Packit Service 50ad14
			kbd_error(EXIT_FAILURE, 0, _("Error: %s: Line %u is too long.\n"),
Packit Service 50ad14
			          filename, rows + 1);
Packit Service 50ad14
	}
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
int main(int argc, char **argv)
Packit Service 50ad14
{
Packit Service 50ad14
	int c, fd;
Packit Service 50ad14
	const char *file;
Packit Service 50ad14
	unsigned char *colormap = cmap;
Packit Service 50ad14
	FILE *f;
Packit Service 50ad14
Packit Service 50ad14
	set_progname(argv[0]);
Packit Service 50ad14
Packit Service 50ad14
	setlocale(LC_ALL, "");
Packit Service 50ad14
	bindtextdomain(PACKAGE_NAME, LOCALEDIR);
Packit Service 50ad14
	textdomain(PACKAGE_NAME);
Packit Service 50ad14
Packit Service 50ad14
	while ((c = getopt(argc, argv, "hV")) != EOF) {
Packit Service 50ad14
		switch (c) {
Packit Service 50ad14
			case 'V':
Packit Service 50ad14
				print_version_and_exit();
Packit Service 50ad14
				break;
Packit Service 50ad14
			case 'h':
Packit Service 50ad14
				usage(EXIT_SUCCESS);
Packit Service 50ad14
				break;
Packit Service 50ad14
		}
Packit Service 50ad14
	}
Packit Service 50ad14
Packit Service 50ad14
	if (optind == argc)
Packit Service 50ad14
		usage(EXIT_FAILURE);
Packit Service 50ad14
Packit Service 50ad14
	file = argv[optind];
Packit Service 50ad14
Packit Service 50ad14
	if (!strcmp(file, "vga")) {
Packit Service 50ad14
		colormap = vga_colors;
Packit Service 50ad14
Packit Service 50ad14
	} else if (!strcmp(file, "-")) {
Packit Service 50ad14
		parse_file(stdin, "stdin");
Packit Service 50ad14
Packit Service 50ad14
	} else {
Packit Service 50ad14
		if ((f = fopen(file, "r")) == NULL)
Packit Service 50ad14
			kbd_error(EXIT_FAILURE, errno, "fopen");
Packit Service 50ad14
Packit Service 50ad14
		parse_file(f, file);
Packit Service 50ad14
		fclose(f);
Packit Service 50ad14
	}
Packit Service 50ad14
Packit Service 50ad14
	if ((fd = getfd(NULL)) < 0)
Packit Service 50ad14
		kbd_error(EXIT_FAILURE, 0, _("Couldn't get a file descriptor referring to the console"));
Packit Service 50ad14
Packit Service 50ad14
	/* Apply the color map to the tty via ioctl */
Packit Service 50ad14
	if (ioctl(fd, PIO_CMAP, colormap) == -1)
Packit Service 50ad14
		kbd_error(EXIT_FAILURE, errno, "ioctl");
Packit Service 50ad14
Packit Service 50ad14
	close(fd);
Packit Service 50ad14
Packit Service 50ad14
	return EXIT_SUCCESS;
Packit Service 50ad14
}