Add pancyrillic font
[platform/upstream/kbd.git] / src / setvtrgb.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <getopt.h>
5 #include <sys/ioctl.h>
6 #include <linux/kd.h>
7 #include <errno.h>
8 #include <error.h>
9 #include "kbd.h"
10 #include "getfd.h"
11 #include "nls.h"
12 #include "version.h"
13
14 static unsigned char *cmap;
15
16 /* Standard VGA terminal colors, matching those hardcoded in the Linux kernel's
17  * drivers/char/vt.c
18  */
19 unsigned char vga_colors[] = {
20         0x00, 0x00, 0x00,
21         0xaa, 0x00, 0x00,
22         0x00, 0xaa, 0x00,
23         0xaa, 0x55, 0x00,
24         0x00, 0x00, 0xaa,
25         0xaa, 0x00, 0xaa,
26         0x00, 0xaa, 0xaa,
27         0xaa, 0xaa, 0xaa,
28         0x55, 0x55, 0x55,
29         0xff, 0x55, 0x55,
30         0x55, 0xff, 0x55,
31         0xff, 0xff, 0x55,
32         0x55, 0x55, 0xff,
33         0xff, 0x55, 0xff,
34         0x55, 0xff, 0xff,
35         0xff, 0xff, 0xff,
36 };
37
38 static void __attribute__ ((noreturn))
39 usage(int code)
40 {
41         fprintf(stderr,
42                 _("Usage: %s vga|FILE|-\n"
43                 "\n"
44                 "If you use the FILE parameter, FILE should be exactly 3 lines of\n"
45                 "comma-separated decimal values for RED, GREEN, and BLUE.\n"
46                 "\n"
47                 "To seed a valid FILE:\n"
48                 "   cat /sys/module/vt/parameters/default_{red,grn,blu} > FILE\n"
49                 "\n"
50                 "and then edit the values in FILE.\n"
51                 "\n"),
52                 progname);
53         exit(code);
54 }
55
56 static void
57 set_colormap(unsigned char *colormap)
58 {
59         int fd = getfd(NULL);
60
61         /* Apply the color map to the tty via ioctl */
62         if (ioctl(fd, PIO_CMAP, colormap) == -1)
63                 error(EXIT_FAILURE, errno, "ioctl");
64
65         close(fd);
66 }
67
68 static void
69 parse_file(FILE *fd, const char *filename)
70 {
71         int c;
72         unsigned int rows, cols, val;
73
74         if ((cmap = calloc(3 * 16, sizeof(unsigned char))) == NULL)
75                 error(EXIT_FAILURE, errno, "calloc");
76
77         for (rows = 0; rows < 3; rows++) {
78                 cols = 0;
79
80                 while (cols < 16) {
81                         if ((c = fscanf(fd, "%u", &val)) != 1) {
82                                 if (c == EOF)
83                                         error(EXIT_FAILURE, errno, "fscanf");
84
85                                 error(EXIT_FAILURE, 0, _("Error: %s: Invalid value in field %u in line %u."),
86                                       filename, rows + 1, cols + 1);
87                         }
88
89                         cmap[rows + cols * 3] = (unsigned char) val;
90
91                         if (cols < 15 && fgetc(fd) != ',')
92                                 error(EXIT_FAILURE, 0, _("Error: %s: Insufficient number of fields in line %u."),
93                                       filename, rows + 1);
94                         cols++;
95                 }
96
97                 if ((c = fgetc(fd)) == EOF)
98                         error(EXIT_FAILURE, 0, _("Error: %s: Line %u has ended unexpectedly.\n"),
99                               filename, rows + 1); 
100
101                 if (c != '\n')
102                         error(EXIT_FAILURE, 0, _("Error: %s: Line %u is too long.\n"),
103                               filename, rows + 1);
104         }
105 }
106
107 int
108 main(int argc, char **argv) {
109         int c;
110         const char *file;
111         FILE *fd;
112
113         set_progname(argv[0]);
114
115         setlocale(LC_ALL, "");
116         bindtextdomain(PACKAGE_NAME, LOCALEDIR);
117         textdomain(PACKAGE_NAME);
118
119         while ((c = getopt(argc, argv, "hV")) != EOF) {
120                 switch (c) {
121                         case 'V':
122                                 print_version_and_exit();
123                                 break;
124                         case 'h':
125                                 usage(EXIT_SUCCESS);
126                                 break;
127                 }
128         }
129
130         if (optind == argc)
131                 usage(EXIT_FAILURE);
132
133         file = argv[optind];
134
135         if (!strcmp(file, "vga")) {
136                 set_colormap(vga_colors);
137                 return EXIT_SUCCESS;
138
139         } else if (!strcmp(file, "-")) {
140                 parse_file(stdin, "stdin");
141
142         } else {
143                 if ((fd = fopen(file, "r")) == NULL)
144                         error(EXIT_FAILURE, errno, "fopen");
145
146                 parse_file(fd, file);
147                 fclose(fd);
148         }
149
150         set_colormap(cmap);
151         free(cmap);
152
153         return EXIT_SUCCESS;
154 }