diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-16 19:35:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-16 19:35:42 +0000 |
commit | 53f219ebbe76ed0321ee9ec33336de2f70ece275 (patch) | |
tree | 26440e50da4c96f7de0ea971913dd0e1220ea276 /console-tools/loadfont.c | |
parent | a1e16c9298756e54161d9bf7d24b03415e2707c0 (diff) | |
download | busybox-w32-53f219ebbe76ed0321ee9ec33336de2f70ece275.tar.gz busybox-w32-53f219ebbe76ed0321ee9ec33336de2f70ece275.tar.bz2 busybox-w32-53f219ebbe76ed0321ee9ec33336de2f70ece275.zip |
setfont: support -m and -C, support -m TEXTUAL_MAP (by Vladimir)
build system: fixlet for echo applet config
function old new delta
setfont_main 157 387 +230
ctoi - 75 +75
packed_usage 24921 24950 +29
Diffstat (limited to 'console-tools/loadfont.c')
-rw-r--r-- | console-tools/loadfont.c | 117 |
1 files changed, 104 insertions, 13 deletions
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c index ce4734c86..38dad3f32 100644 --- a/console-tools/loadfont.c +++ b/console-tools/loadfont.c | |||
@@ -17,7 +17,7 @@ enum { | |||
17 | PSF_MODE512 = 0x01, | 17 | PSF_MODE512 = 0x01, |
18 | PSF_MODEHASTAB = 0x02, | 18 | PSF_MODEHASTAB = 0x02, |
19 | PSF_MAXMODE = 0x03, | 19 | PSF_MAXMODE = 0x03, |
20 | PSF_SEPARATOR = 0xFFFF | 20 | PSF_SEPARATOR = 0xffff |
21 | }; | 21 | }; |
22 | 22 | ||
23 | struct psf_header { | 23 | struct psf_header { |
@@ -165,6 +165,8 @@ int loadfont_main(int argc UNUSED_PARAM, char **argv) | |||
165 | } | 165 | } |
166 | #endif | 166 | #endif |
167 | 167 | ||
168 | #if ENABLE_SETFONT | ||
169 | |||
168 | /* | 170 | /* |
169 | kbd-1.12: | 171 | kbd-1.12: |
170 | 172 | ||
@@ -198,36 +200,125 @@ setfont [-O font+umap.orig] [-o font.orig] [-om cmap.orig] | |||
198 | -V Version | 200 | -V Version |
199 | */ | 201 | */ |
200 | 202 | ||
201 | #if ENABLE_SETFONT | 203 | #if ENABLE_FEATURE_SETFONT_TEXTUAL_MAP |
204 | static int ctoi(char *s) | ||
205 | { | ||
206 | if (s[0] == '\'' && s[1] != '\0' && s[2] == '\'' && s[3] == '\0') | ||
207 | return s[1]; | ||
208 | // U+ means 0x | ||
209 | if (s[0] == 'U' && s[1] == '+') { | ||
210 | s[0] = '0'; | ||
211 | s[1] = 'x'; | ||
212 | } | ||
213 | if (!isdigit(s[0])) | ||
214 | return -1; | ||
215 | return xstrtoul(s, 0); | ||
216 | } | ||
217 | #endif | ||
218 | |||
202 | int setfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 219 | int setfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
203 | int setfont_main(int argc UNUSED_PARAM, char **argv) | 220 | int setfont_main(int argc UNUSED_PARAM, char **argv) |
204 | { | 221 | { |
205 | size_t len; | 222 | size_t len; |
223 | unsigned opts; | ||
224 | int fd; | ||
206 | struct psf_header *psfhdr; | 225 | struct psf_header *psfhdr; |
207 | char *mapfilename; | 226 | char *mapfilename; |
208 | int fd; | 227 | const char *tty_name = CURRENT_TTY; |
209 | 228 | ||
210 | opt_complementary = "=1"; | 229 | opt_complementary = "=1"; |
211 | getopt32(argv, "m:", &mapfilename); | 230 | opts = getopt32(argv, "m:C:", &mapfilename, &tty_name); |
212 | argv += optind; | 231 | argv += optind; |
213 | 232 | ||
233 | fd = xopen(tty_name, O_NONBLOCK); | ||
234 | |||
235 | if (sizeof(CONFIG_DEFAULT_SETFONT_DIR) > 1) { // if not "" | ||
236 | if (strchr(*argv, '/') != NULL) { | ||
237 | // goto default fonts location. don't die if doesn't exist | ||
238 | chdir(CONFIG_DEFAULT_SETFONT_DIR "/consolefonts"); | ||
239 | // buglet: we don't return to current dir... | ||
240 | // affects "setfont FONT -m ./MAP" case | ||
241 | } | ||
242 | } | ||
214 | // load font | 243 | // load font |
215 | len = 32*1024; // can't be larger | 244 | len = 32*1024; // can't be larger |
216 | psfhdr = (struct psf_header *) xmalloc_open_zipped_read_close(*argv, &len); | 245 | psfhdr = (struct psf_header *) xmalloc_open_zipped_read_close(*argv, &len); |
217 | fd = get_console_fd_or_die(); | ||
218 | do_load(fd, psfhdr, len); | 246 | do_load(fd, psfhdr, len); |
219 | 247 | ||
220 | // load the screen map, if any | 248 | // load the screen map, if any |
221 | if (option_mask32 & 1) { // -m | 249 | if (opts & 1) { // -m |
222 | void *map = xmalloc_open_zipped_read_close(mapfilename, &len); | 250 | unsigned mode = PIO_SCRNMAP; |
251 | void *map; | ||
252 | |||
253 | if (sizeof(CONFIG_DEFAULT_SETFONT_DIR) > 1) { // if not "" | ||
254 | if (strchr(mapfilename, '/') != NULL) { | ||
255 | // goto default keymaps location | ||
256 | chdir(CONFIG_DEFAULT_SETFONT_DIR "/consoletrans"); | ||
257 | } | ||
258 | } | ||
259 | // fetch keymap | ||
260 | map = xmalloc_open_zipped_read_close(mapfilename, &len); | ||
261 | if (!map) | ||
262 | bb_simple_perror_msg_and_die(mapfilename); | ||
263 | // file size is 256 or 512 bytes? -> assume binary map | ||
223 | if (len == E_TABSZ || len == 2*E_TABSZ) { | 264 | if (len == E_TABSZ || len == 2*E_TABSZ) { |
224 | //TODO: support textual Unicode console maps: | 265 | if (len == 2*E_TABSZ) |
225 | // 0x00 U+0000 # NULL (NUL) | 266 | mode = PIO_UNISCRNMAP; |
226 | // 0x01 U+0001 # START OF HEADING (SOH) | ||
227 | // 0x02 U+0002 # START OF TEXT (STX) | ||
228 | // 0x03 U+0003 # END OF TEXT (ETX) | ||
229 | xioctl(fd, (len == 2*E_TABSZ) ? PIO_UNISCRNMAP : PIO_SCRNMAP, map); | ||
230 | } | 267 | } |
268 | #if ENABLE_FEATURE_SETFONT_TEXTUAL_MAP | ||
269 | // assume textual Unicode console maps: | ||
270 | // 0x00 U+0000 # NULL (NUL) | ||
271 | // 0x01 U+0001 # START OF HEADING (SOH) | ||
272 | // 0x02 U+0002 # START OF TEXT (STX) | ||
273 | // 0x03 U+0003 # END OF TEXT (ETX) | ||
274 | else { | ||
275 | int i; | ||
276 | char *token[2]; | ||
277 | parser_t *parser; | ||
278 | |||
279 | if (ENABLE_FEATURE_CLEAN_UP) | ||
280 | free(map); | ||
281 | map = xmalloc(E_TABSZ * sizeof(unsigned short)); | ||
282 | |||
283 | #define unicodes ((unsigned short *)map) | ||
284 | // fill vanilla map | ||
285 | for (i = 0; i < E_TABSZ; i++) | ||
286 | unicodes[i] = 0xf000 + i; | ||
287 | |||
288 | parser = config_open(mapfilename); | ||
289 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL | PARSE_MIN_DIE)) { | ||
290 | // parse code/value pair | ||
291 | int a = ctoi(token[0]); | ||
292 | int b = ctoi(token[1]); | ||
293 | if (a < 0 || a >= E_TABSZ | ||
294 | || b < 0 || b > 65535 | ||
295 | ) { | ||
296 | bb_error_msg_and_die("map format"); | ||
297 | } | ||
298 | // patch map | ||
299 | unicodes[a] = b; | ||
300 | // unicode character is met? | ||
301 | if (b > 255) | ||
302 | mode = PIO_UNISCRNMAP; | ||
303 | } | ||
304 | if (ENABLE_FEATURE_CLEAN_UP) | ||
305 | config_close(parser); | ||
306 | |||
307 | if (mode != PIO_UNISCRNMAP) { | ||
308 | #define asciis ((unsigned char *)map) | ||
309 | for (i = 0; i < E_TABSZ; i++) | ||
310 | asciis[i] = unicodes[i]; | ||
311 | #undef asciis | ||
312 | } | ||
313 | #undef unicodes | ||
314 | } | ||
315 | #endif // ENABLE_FEATURE_SETFONT_TEXTUAL_MAP | ||
316 | |||
317 | // do set screen map | ||
318 | xioctl(fd, mode, map); | ||
319 | |||
320 | if (ENABLE_FEATURE_CLEAN_UP) | ||
321 | free(map); | ||
231 | } | 322 | } |
232 | 323 | ||
233 | return EXIT_SUCCESS; | 324 | return EXIT_SUCCESS; |