Linux console tools development discussion
 help / color / mirror / Atom feed
From: Alexey Gladkov <gladkov.alexey@gmail.com>
To: Linux console tools development discussion <kbd@lists.altlinux.org>
Cc: Dustin Kirkland <kirkland@ubuntu.com>,
	Michael Schutte <michi@debian.org>
Subject: Re: [kbd] Feature Request: add the setvtrgb utility
Date: Sat, 02 Apr 2011 03:39:04 +0400
Message-ID: <4D966218.1000909@gmail.com> (raw)
In-Reply-To: <AANLkTi=pvp8zcCLEvwTuFE3EMmavA4OPD6Pi-exHWBax@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 485 bytes --]

29.03.2011 00:29, Dustin Kirkland wrote:
> We're carrying a new feature in Ubuntu's kbd package, provided by a
> neat little utility called /sbin/setvtrgb.

Thanks, I like the idea. I'm not quite happy with your implementation,
though:

I'm not sure that "char s[1024];" buffer is necessary;
Error diagnostics is difficult to understand;
Memory allocated by calloc() is never freed.

I wrote a different implementation (see attachment).
What do you think about it?

-- 
Rgrds, legion


[-- Attachment #2: setvtrgb.c --]
[-- Type: text/plain, Size: 3088 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <errno.h>
#include <error.h>
#include "getfd.h"
#include "nls.h"
#include "version.h"

static unsigned char *cmap;

/* Standard VGA terminal colors, matching those hardcoded in the Linux kernel's
 * drivers/char/vt.c
 */
unsigned char vga_colors[] = {
	0x00, 0x00, 0x00,
	0xaa, 0x00, 0x00,
	0x00, 0xaa, 0x00,
	0xaa, 0x55, 0x00,
	0x00, 0x00, 0xaa,
	0xaa, 0x00, 0xaa,
	0x00, 0xaa, 0xaa,
	0xaa, 0xaa, 0xaa,
	0x55, 0x55, 0x55,
	0xff, 0x55, 0x55,
	0x55, 0xff, 0x55,
	0xff, 0xff, 0x55,
	0x55, 0x55, 0xff,
	0xff, 0x55, 0xff,
	0x55, 0xff, 0xff,
	0xff, 0xff, 0xff,
};

static void attr_noreturn
usage(int code)
{
	fprintf(stderr,
		_("Usage: %s vga|FILE|-\n"
		"\n"
		"If you use the FILE parameter, FILE should be exactly 3 lines of\n"
		"comma-separated decimal values for RED, GREEN, and BLUE.\n"
		"\n"
		"To seed a valid FILE:\n"
		"   cat /sys/module/vt/parameters/default_{red,grn,blu} > FILE\n"
		"\n"
		"and then edit the values in FILE.\n"
		"\n"),
		progname);
	exit(code);
}

static void
set_colormap(unsigned char *colormap)
{
	int fd = getfd(NULL);

	/* Apply the color map to the tty via ioctl */
	if (ioctl(fd, PIO_CMAP, colormap) == -1)
		error(EXIT_FAILURE, errno, "ioctl");

	close(fd);
}

static void
parse_file(FILE *fd, const char *filename)
{
	int c;
	unsigned int rows, cols, val;

	if ((cmap = calloc(3 * 16, sizeof(unsigned char))) == NULL)
		error(EXIT_FAILURE, errno, "calloc");

	for (rows = 0; rows < 3; rows++) {
		cols = 0;

		while (cols < 16) {
			if ((c = fscanf(fd, "%u", &val)) != 1) {
				if (c == EOF)
					error(EXIT_FAILURE, errno, "fscanf");

				error(EXIT_FAILURE, 0, _("Error: %s: Invalid value in field %u in line %u."),
				      filename, rows + 1, cols + 1);
			}

			cmap[rows + cols * 3] = (unsigned char) val;

			if (cols < 15 && fgetc(fd) != ',')
				error(EXIT_FAILURE, 0, _("Error: %s: Insufficient number of fields in line %u."),
				      filename, rows + 1);
			cols++;
		}

		if ((c = fgetc(fd)) == EOF)
			error(EXIT_FAILURE, 0, _("Error: %s: Line %u has ended unexpectedly.\n"),
			      filename, rows + 1); 

		if (c != '\n')
			error(EXIT_FAILURE, 0, _("Error: %s: Line %u is too long.\n"),
			      filename, rows + 1);
	}
}

int
main(int argc, char **argv) {
	int c;
	const char *file;
	FILE *fd;

	set_progname(argv[0]);

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE_NAME, LOCALEDIR);
	textdomain(PACKAGE_NAME);

	while ((c = getopt(argc, argv, "hV")) != EOF) {
		switch (c) {
			case 'V':
				print_version_and_exit();
				break;
			case 'h':
				usage(EXIT_SUCCESS);
				break;
		}
	}

	if (optind == argc)
		usage(EXIT_FAILURE);

	file = argv[optind];

	if (!strcmp(file, "vga")) {
		set_colormap(vga_colors);
		return EXIT_SUCCESS;

	} else if (!strcmp(file, "-")) {
		parse_file(stdin, "stdin");

	} else {
		if ((fd = fopen(file, "r")) == NULL)
			error(EXIT_FAILURE, errno, "fopen");

		parse_file(fd, file);
		fclose(fd);
	}

	set_colormap(cmap);
	free(cmap);

	return EXIT_SUCCESS;
}

  reply	other threads:[~2011-04-01 23:39 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-28 20:29 ` Dustin Kirkland
2011-04-01 23:39   ` Alexey Gladkov [this message]
2011-04-04 14:12       ` Alexey Gladkov
2011-04-04 14:49           ` Alexey Gladkov
2011-04-04 15:02             ` Dustin Kirkland
2011-04-04 16:38           ` Michael Schutte

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D966218.1000909@gmail.com \
    --to=gladkov.alexey@gmail.com \
    --cc=kbd@lists.altlinux.org \
    --cc=kirkland@ubuntu.com \
    --cc=michi@debian.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux console tools development discussion

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/kbd/0 kbd/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 kbd kbd/ http://lore.altlinux.org/kbd \
		kbd@lists.altlinux.org kbd@lists.altlinux.ru kbd@lists.altlinux.com
	public-inbox-index kbd

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.kbd


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git