diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-17 14:12:26 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-17 14:12:26 +0000 |
commit | c8d02aa959d3543239701d7170e0255c49ad6d9e (patch) | |
tree | dff730a0992022105fa3b2795edc1af5055dbc80 /console-tools/loadfont.c | |
parent | eb084779d7f3feba414d679006d4f1633451677f (diff) | |
download | busybox-w32-c8d02aa959d3543239701d7170e0255c49ad6d9e.tar.gz busybox-w32-c8d02aa959d3543239701d7170e0255c49ad6d9e.tar.bz2 busybox-w32-c8d02aa959d3543239701d7170e0255c49ad6d9e.zip |
setfont: new applet by Vladimir
Diffstat (limited to 'console-tools/loadfont.c')
-rw-r--r-- | console-tools/loadfont.c | 140 |
1 files changed, 78 insertions, 62 deletions
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 | ||
31 | static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize) | 31 | static 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 | ||
61 | static void | 60 | static void do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize) |
62 | do_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 | ||
99 | static void loadnewfont(int fd) | 97 | static 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 | ||
169 | int loadfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 142 | int loadfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
170 | int loadfont_main(int argc, char **argv UNUSED_PARAM) | 143 | int 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 | ||
169 | int setfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
170 | int 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 | ||