aboutsummaryrefslogtreecommitdiff
path: root/console-tools
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-08-17 14:12:26 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-08-17 14:12:26 +0000
commitc8d02aa959d3543239701d7170e0255c49ad6d9e (patch)
treedff730a0992022105fa3b2795edc1af5055dbc80 /console-tools
parenteb084779d7f3feba414d679006d4f1633451677f (diff)
downloadbusybox-w32-c8d02aa959d3543239701d7170e0255c49ad6d9e.tar.gz
busybox-w32-c8d02aa959d3543239701d7170e0255c49ad6d9e.tar.bz2
busybox-w32-c8d02aa959d3543239701d7170e0255c49ad6d9e.zip
setfont: new applet by Vladimir
Diffstat (limited to 'console-tools')
-rw-r--r--console-tools/Config.in6
-rw-r--r--console-tools/Kbuild1
-rw-r--r--console-tools/loadfont.c140
3 files changed, 85 insertions, 62 deletions
diff --git a/console-tools/Config.in b/console-tools/Config.in
index 4b7f02d25..efba9cd09 100644
--- a/console-tools/Config.in
+++ b/console-tools/Config.in
@@ -95,6 +95,12 @@ config FEATURE_SETCONSOLE_LONG_OPTIONS
95 help 95 help
96 Support long options for the setconsole applet. 96 Support long options for the setconsole applet.
97 97
98config SETFONT
99 bool "setfont"
100 default n
101 help
102 Allows to load console screen map. Useful for i18n.
103
98config SETKEYCODES 104config SETKEYCODES
99 bool "setkeycodes" 105 bool "setkeycodes"
100 default n 106 default n
diff --git a/console-tools/Kbuild b/console-tools/Kbuild
index cf3825ec6..0a182500e 100644
--- a/console-tools/Kbuild
+++ b/console-tools/Kbuild
@@ -16,5 +16,6 @@ lib-$(CONFIG_LOADKMAP) += loadkmap.o
16lib-$(CONFIG_OPENVT) += openvt.o 16lib-$(CONFIG_OPENVT) += openvt.o
17lib-$(CONFIG_RESET) += reset.o 17lib-$(CONFIG_RESET) += reset.o
18lib-$(CONFIG_RESIZE) += resize.o 18lib-$(CONFIG_RESIZE) += resize.o
19lib-$(CONFIG_SETFONT) += loadfont.o
19lib-$(CONFIG_SETKEYCODES) += setkeycodes.o 20lib-$(CONFIG_SETKEYCODES) += setkeycodes.o
20lib-$(CONFIG_SETLOGCONS) += setlogcons.o 21lib-$(CONFIG_SETLOGCONS) += setlogcons.o
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c
index 567aa38ae..78700706f 100644
--- a/console-tools/loadfont.c
+++ b/console-tools/loadfont.c
@@ -26,7 +26,7 @@ struct psf_header {
26 unsigned char charsize; /* Character size */ 26 unsigned char charsize; /* Character size */
27}; 27};
28 28
29#define PSF_MAGIC_OK(x) ((x).magic1 == PSF_MAGIC1 && (x).magic2 == PSF_MAGIC2) 29#define PSF_MAGIC_OK(x) ((x)->magic1 == PSF_MAGIC1 && (x)->magic2 == PSF_MAGIC2)
30 30
31static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize) 31static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
32{ 32{
@@ -37,7 +37,6 @@ static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
37 bb_error_msg_and_die("bad character size %d", unit); 37 bb_error_msg_and_die("bad character size %d", unit);
38 38
39 buf = xzalloc(16 * 1024); 39 buf = xzalloc(16 * 1024);
40 /*memset(buf, 0, 16 * 1024);*/
41 for (i = 0; i < fontsize; i++) 40 for (i = 0; i < fontsize; i++)
42 memcpy(buf + (32 * i), inbuf + (unit * i), unit); 41 memcpy(buf + (32 * i), inbuf + (unit * i), unit);
43 42
@@ -58,8 +57,7 @@ static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
58 free(buf); 57 free(buf);
59} 58}
60 59
61static void 60static void do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
62do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
63{ 61{
64 struct unimapinit advice; 62 struct unimapinit advice;
65 struct unimapdesc ud; 63 struct unimapdesc ud;
@@ -68,7 +66,7 @@ do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
68 int glyph; 66 int glyph;
69 uint16_t unicode; 67 uint16_t unicode;
70 68
71 maxct = tailsz; /* more than enough */ 69 maxct = tailsz; /* more than enough */
72 up = xmalloc(maxct * sizeof(struct unipair)); 70 up = xmalloc(maxct * sizeof(struct unipair));
73 71
74 for (glyph = 0; glyph < fontsize; glyph++) { 72 for (glyph = 0; glyph < fontsize; glyph++) {
@@ -96,86 +94,104 @@ do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
96 xioctl(fd, PIO_UNIMAP, &ud); 94 xioctl(fd, PIO_UNIMAP, &ud);
97} 95}
98 96
99static void loadnewfont(int fd) 97static void do_load(int fd, struct psf_header *psfhdr, size_t len)
100{ 98{
101 enum { INBUF_SIZE = 32*1024 + 1 };
102
103 int unit; 99 int unit;
104 unsigned inputlth, offset; 100 int fontsize;
105 /* Was on stack, but 32k is a bit too much: */ 101 int hastable;
106 unsigned char *inbuf = xmalloc(INBUF_SIZE); 102 unsigned head0, head = head;
107
108 /*
109 * We used to look at the length of the input file
110 * with stat(); now that we accept compressed files,
111 * just read the entire file.
112 */
113 inputlth = full_read(STDIN_FILENO, inbuf, INBUF_SIZE);
114 if (inputlth < 0)
115 bb_perror_msg_and_die("error reading input font");
116 if (inputlth >= INBUF_SIZE)
117 bb_error_msg_and_die("font too large");
118 103
119 /* test for psf first */ 104 /* test for psf first */
120 { 105 if (len >= sizeof(struct psf_header) && PSF_MAGIC_OK(psfhdr)) {
121 struct psf_header psfhdr; 106 if (psfhdr->mode > PSF_MAXMODE)
122 int fontsize;
123 int hastable;
124 unsigned head0, head;
125
126 if (inputlth < sizeof(struct psf_header))
127 goto no_psf;
128
129 psfhdr = *(struct psf_header *) &inbuf[0];
130
131 if (!PSF_MAGIC_OK(psfhdr))
132 goto no_psf;
133
134 if (psfhdr.mode > PSF_MAXMODE)
135 bb_error_msg_and_die("unsupported psf file mode"); 107 bb_error_msg_and_die("unsupported psf file mode");
136 fontsize = ((psfhdr.mode & PSF_MODE512) ? 512 : 256); 108 fontsize = ((psfhdr->mode & PSF_MODE512) ? 512 : 256);
137#if !defined(PIO_FONTX) || defined(__sparc__) 109#if !defined(PIO_FONTX) || defined(__sparc__)
138 if (fontsize != 256) 110 if (fontsize != 256)
139 bb_error_msg_and_die("only fontsize 256 supported"); 111 bb_error_msg_and_die("only fontsize 256 supported");
140#endif 112#endif
141 hastable = (psfhdr.mode & PSF_MODEHASTAB); 113 hastable = (psfhdr->mode & PSF_MODEHASTAB);
142 unit = psfhdr.charsize; 114 unit = psfhdr->charsize;
143 head0 = sizeof(struct psf_header); 115 head0 = sizeof(struct psf_header);
144 116
145 head = head0 + fontsize * unit; 117 head = head0 + fontsize * unit;
146 if (head > inputlth || (!hastable && head != inputlth)) 118 if (head > len || (!hastable && head != len))
147 bb_error_msg_and_die("input file: bad length"); 119 bb_error_msg_and_die("input file: bad length");
148 do_loadfont(fd, inbuf + head0, unit, fontsize);
149 if (hastable)
150 do_loadtable(fd, inbuf + head, inputlth - head, fontsize);
151 return;
152 }
153
154 no_psf:
155 /* file with three code pages? */
156 if (inputlth == 9780) {
157 offset = 40;
158 unit = 16;
159 } else { 120 } else {
160 /* bare font */ 121 /* file with three code pages? */
161 if (inputlth & 0377) 122 if (len == 9780) {
162 bb_error_msg_and_die("bad input file size"); 123 head0 = 40;
163 offset = 0; 124 unit = 16;
164 unit = inputlth / 256; 125 } else {
126 /* bare font */
127 if (len & 0377)
128 bb_error_msg_and_die("input file: bad length");
129 head0 = 0;
130 unit = len / 256;
131 }
132 fontsize = 256;
133 hastable = 0;
165 } 134 }
166 do_loadfont(fd, inbuf + offset, unit, 256); 135
136 do_loadfont(fd, (unsigned char *)psfhdr + head0, unit, fontsize);
137 if (hastable)
138 do_loadtable(fd, (unsigned char *)psfhdr + head, len - head, fontsize);
167} 139}
168 140
141#if ENABLE_LOADFONT
169int loadfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 142int loadfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
170int loadfont_main(int argc, char **argv UNUSED_PARAM) 143int loadfont_main(int argc UNUSED_PARAM, char **argv)
171{ 144{
145 size_t len;
146 struct psf_header *psfhdr;
147
148 // no arguments allowed!
149 opt_complementary = "=0";
150 getopt32(argv, "");
151
152 /*
153 * We used to look at the length of the input file
154 * with stat(); now that we accept compressed files,
155 * just read the entire file.
156 */
157 len = 32*1024; // can't be larger
158 psfhdr = (struct psf_header *) xmalloc_read(STDIN_FILENO, &len);
159 // xmalloc_open_zipped_read_close(filename, &len);
160 if (!psfhdr)
161 bb_perror_msg_and_die("error reading input font");
162 do_load(get_console_fd_or_die(), psfhdr, len);
163
164 return EXIT_SUCCESS;
165}
166#endif
167
168#if ENABLE_SETFONT
169int setfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
170int setfont_main(int argc UNUSED_PARAM, char **argv)
171{
172 size_t len;
173 struct psf_header *psfhdr;
174 char *mapfilename;
172 int fd; 175 int fd;
173 176
174 if (argc != 1) 177 opt_complementary = "=1";
175 bb_show_usage(); 178 getopt32(argv, "m:", &mapfilename);
179 argv += optind;
176 180
181 // load font
182 len = 32*1024; // can't be larger
183 psfhdr = (struct psf_header *) xmalloc_open_zipped_read_close(*argv, &len);
177 fd = get_console_fd_or_die(); 184 fd = get_console_fd_or_die();
178 loadnewfont(fd); 185 do_load(fd, psfhdr, len);
186
187 // load the screen map, if any
188 if (option_mask32 & 1) { // -m
189 void *map = xmalloc_open_zipped_read_close(mapfilename, &len);
190 if (len == E_TABSZ || len == 2*E_TABSZ) {
191 xioctl(fd, (len == 2*E_TABSZ) ? PIO_UNISCRNMAP : PIO_SCRNMAP, map);
192 }
193 }
179 194
180 return EXIT_SUCCESS; 195 return EXIT_SUCCESS;
181} 196}
197#endif