From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on sa.int.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00, DNS_FROM_OPENWHOIS, SPF_NEUTRAL autolearn=no version=3.2.5 Message-ID: <4D966218.1000909@gmail.com> Date: Sat, 02 Apr 2011 03:39:04 +0400 From: Alexey Gladkov User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.16pre) Gecko/20110308 Lightning/1.0b3pre Thunderbird/3.1.10pre MIME-Version: 1.0 To: Linux console tools development discussion References: In-Reply-To: X-Enigmail-Version: 1.1.2 Content-Type: multipart/mixed; boundary="------------090802090201090206070201" Cc: Dustin Kirkland , Michael Schutte Subject: Re: [kbd] Feature Request: add the setvtrgb utility X-BeenThere: kbd@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: Linux console tools development discussion List-Id: Linux console tools development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Apr 2011 23:39:11 -0000 Archived-At: List-Archive: This is a multi-part message in MIME format. --------------090802090201090206070201 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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 --------------090802090201090206070201 Content-Type: text/plain; name="setvtrgb.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="setvtrgb.c" #include #include #include #include #include #include #include #include #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; } --------------090802090201090206070201--