1 1.24 uwe /* $NetBSD: wsfontload.c,v 1.24 2022/05/12 22:08:55 uwe Exp $ */ 2 1.1 drochner 3 1.1 drochner /* 4 1.1 drochner * Copyright (c) 1999 5 1.1 drochner * Matthias Drochner. All rights reserved. 6 1.1 drochner * 7 1.1 drochner * Redistribution and use in source and binary forms, with or without 8 1.1 drochner * modification, are permitted provided that the following conditions 9 1.1 drochner * are met: 10 1.1 drochner * 1. Redistributions of source code must retain the above copyright 11 1.1 drochner * notice, this list of conditions and the following disclaimer. 12 1.1 drochner * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 drochner * notice, this list of conditions and the following disclaimer in the 14 1.1 drochner * documentation and/or other materials provided with the distribution. 15 1.1 drochner * 16 1.1 drochner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 drochner * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 drochner * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 drochner * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 drochner * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 drochner * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 drochner * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 drochner * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 drochner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 drochner * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 drochner * 27 1.1 drochner */ 28 1.1 drochner 29 1.1 drochner #include <stdio.h> 30 1.1 drochner #include <fcntl.h> 31 1.6 cgd #include <stdlib.h> 32 1.4 matt #include <string.h> 33 1.1 drochner #include <unistd.h> 34 1.1 drochner #include <sys/types.h> 35 1.1 drochner #include <sys/ioctl.h> 36 1.19 macallan #include <sys/stat.h> 37 1.1 drochner #include <err.h> 38 1.1 drochner 39 1.1 drochner #include <dev/wscons/wsconsio.h> 40 1.1 drochner 41 1.8 drochner #define DEFDEV "/dev/wsfont" 42 1.3 ad #define DEFWIDTH 8 43 1.3 ad #define DEFHEIGHT 16 44 1.3 ad #define DEFENC WSDISPLAY_FONTENC_ISO 45 1.3 ad #define DEFBITORDER WSDISPLAY_FONTORDER_L2R 46 1.3 ad #define DEFBYTEORDER WSDISPLAY_FONTORDER_L2R 47 1.1 drochner 48 1.17 joerg __dead static void usage(void); 49 1.10 xtraeme static int getencoding(char *); 50 1.10 xtraeme static const char *rgetencoding(int); 51 1.10 xtraeme static const char *rgetfontorder(int); 52 1.5 hubertf 53 1.5 hubertf static struct { 54 1.10 xtraeme const char *name; 55 1.5 hubertf int val; 56 1.5 hubertf } fontorders[] = { 57 1.5 hubertf { "known", WSDISPLAY_FONTORDER_KNOWN}, 58 1.5 hubertf { "l2r", WSDISPLAY_FONTORDER_L2R}, 59 1.5 hubertf { "r2l", WSDISPLAY_FONTORDER_R2L}, 60 1.5 hubertf }; 61 1.5 hubertf 62 1.5 hubertf static struct { 63 1.10 xtraeme const char *name; 64 1.5 hubertf int val; 65 1.5 hubertf } encodings[] = { 66 1.5 hubertf {"iso", WSDISPLAY_FONTENC_ISO}, 67 1.5 hubertf {"ibm", WSDISPLAY_FONTENC_IBM}, 68 1.5 hubertf {"pcvt", WSDISPLAY_FONTENC_PCVT}, 69 1.7 drochner {"iso7", WSDISPLAY_FONTENC_ISO7}, 70 1.7 drochner {"iso2", WSDISPLAY_FONTENC_ISO2}, 71 1.15 drochner {"koi8r", WSDISPLAY_FONTENC_KOI8_R}, 72 1.5 hubertf }; 73 1.1 drochner 74 1.1 drochner static void 75 1.10 xtraeme usage(void) 76 1.1 drochner { 77 1.1 drochner 78 1.1 drochner (void)fprintf(stderr, 79 1.23 wiz "usage: %s [-Bbv] [-e encoding] [-f wsdev] [-h height]" 80 1.23 wiz " [-N name] [-w width] [fontfile]\n" 81 1.23 wiz " %s -l\n", 82 1.23 wiz getprogname(), 83 1.6 cgd getprogname()); 84 1.1 drochner exit(1); 85 1.1 drochner } 86 1.1 drochner 87 1.5 hubertf /* 88 1.11 snj * map given fontorder to its string representation 89 1.5 hubertf */ 90 1.10 xtraeme static const char * 91 1.10 xtraeme rgetfontorder(int fontorder) 92 1.5 hubertf { 93 1.14 lukem size_t i; 94 1.5 hubertf 95 1.5 hubertf for (i = 0; i < sizeof(fontorders) / sizeof(fontorders[0]); i++) 96 1.5 hubertf if (fontorders[i].val == fontorder) 97 1.5 hubertf return (fontorders[i].name); 98 1.5 hubertf 99 1.5 hubertf return "unknown"; 100 1.5 hubertf } 101 1.5 hubertf 102 1.5 hubertf /* 103 1.11 snj * map given encoding to its string representation 104 1.5 hubertf */ 105 1.10 xtraeme static const char * 106 1.10 xtraeme rgetencoding(int enc) 107 1.5 hubertf { 108 1.14 lukem size_t i; 109 1.5 hubertf 110 1.5 hubertf for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++) 111 1.5 hubertf if (encodings[i].val == enc) 112 1.5 hubertf return (encodings[i].name); 113 1.5 hubertf 114 1.5 hubertf return "unknown"; 115 1.5 hubertf } 116 1.5 hubertf 117 1.5 hubertf /* 118 1.5 hubertf * map given encoding string to integer value 119 1.5 hubertf */ 120 1.5 hubertf static int 121 1.10 xtraeme getencoding(char *name) 122 1.5 hubertf { 123 1.14 lukem size_t i; 124 1.14 lukem int j; 125 1.5 hubertf 126 1.5 hubertf for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++) 127 1.5 hubertf if (!strcmp(name, encodings[i].name)) 128 1.5 hubertf return (encodings[i].val); 129 1.5 hubertf 130 1.14 lukem if (sscanf(name, "%d", &j) != 1) 131 1.5 hubertf errx(1, "invalid encoding"); 132 1.14 lukem return (j); 133 1.5 hubertf } 134 1.5 hubertf 135 1.1 drochner int 136 1.10 xtraeme main(int argc, char **argv) 137 1.1 drochner { 138 1.10 xtraeme const char *wsdev; 139 1.1 drochner struct wsdisplay_font f; 140 1.19 macallan struct stat st; 141 1.1 drochner size_t len; 142 1.22 macallan int c, res, wsfd, ffd, verbose = 0, listfonts = 0; 143 1.21 macallan int use_embedded_name = 1; 144 1.1 drochner void *buf; 145 1.19 macallan char nbuf[65]; 146 1.1 drochner 147 1.1 drochner wsdev = DEFDEV; 148 1.1 drochner f.fontwidth = DEFWIDTH; 149 1.1 drochner f.fontheight = DEFHEIGHT; 150 1.1 drochner f.firstchar = 0; 151 1.1 drochner f.numchars = 256; 152 1.1 drochner f.stride = 0; 153 1.1 drochner f.encoding = DEFENC; 154 1.1 drochner f.name = 0; 155 1.3 ad f.bitorder = DEFBITORDER; 156 1.3 ad f.byteorder = DEFBYTEORDER; 157 1.1 drochner 158 1.22 macallan while ((c = getopt(argc, argv, "f:w:h:e:N:bBvl")) != -1) { 159 1.1 drochner switch (c) { 160 1.1 drochner case 'f': 161 1.1 drochner wsdev = optarg; 162 1.1 drochner break; 163 1.22 macallan case 'l': 164 1.22 macallan listfonts = 1; 165 1.22 macallan break; 166 1.1 drochner case 'w': 167 1.1 drochner if (sscanf(optarg, "%d", &f.fontwidth) != 1) 168 1.1 drochner errx(1, "invalid font width"); 169 1.1 drochner break; 170 1.1 drochner case 'h': 171 1.1 drochner if (sscanf(optarg, "%d", &f.fontheight) != 1) 172 1.1 drochner errx(1, "invalid font height"); 173 1.1 drochner break; 174 1.1 drochner case 'e': 175 1.1 drochner f.encoding = getencoding(optarg); 176 1.1 drochner break; 177 1.1 drochner case 'N': 178 1.1 drochner f.name = optarg; 179 1.21 macallan use_embedded_name = 0; 180 1.2 ad break; 181 1.2 ad case 'b': 182 1.2 ad f.bitorder = WSDISPLAY_FONTORDER_R2L; 183 1.2 ad break; 184 1.2 ad case 'B': 185 1.2 ad f.byteorder = WSDISPLAY_FONTORDER_R2L; 186 1.1 drochner break; 187 1.5 hubertf case 'v': 188 1.5 hubertf verbose = 1; 189 1.5 hubertf break; 190 1.1 drochner case '?': 191 1.1 drochner default: 192 1.1 drochner usage(); 193 1.1 drochner break; 194 1.1 drochner } 195 1.1 drochner } 196 1.1 drochner argc -= optind; 197 1.1 drochner argv += optind; 198 1.1 drochner 199 1.1 drochner if (argc > 1) 200 1.1 drochner usage(); 201 1.1 drochner 202 1.24 uwe wsfd = open(wsdev, listfonts ? O_RDONLY : O_RDWR, 0); 203 1.1 drochner if (wsfd < 0) 204 1.5 hubertf err(2, "open ws-device %s", wsdev); 205 1.1 drochner 206 1.22 macallan if (listfonts == 1) { 207 1.22 macallan struct wsdisplayio_fontinfo fi; 208 1.22 macallan int ret; 209 1.22 macallan unsigned int i; 210 1.22 macallan 211 1.22 macallan fi.fi_buffersize = 4096; 212 1.22 macallan fi.fi_numentries = 0; 213 1.22 macallan fi.fi_fonts = malloc(4096); 214 1.22 macallan ret = ioctl(wsfd, WSDISPLAYIO_LISTFONTS, &fi); 215 1.22 macallan if (fi.fi_fonts == NULL || ret != 0) { 216 1.22 macallan err(1, "error fetching font list\n"); 217 1.22 macallan } 218 1.22 macallan for (i = 0; i < fi.fi_numentries; i++) { 219 1.22 macallan printf("%s %dx%d\n", fi.fi_fonts[i].fd_name, 220 1.22 macallan fi.fi_fonts[i].fd_width, fi.fi_fonts[i].fd_height); 221 1.22 macallan } 222 1.22 macallan return 0; 223 1.22 macallan } 224 1.22 macallan 225 1.1 drochner if (argc > 0) { 226 1.1 drochner ffd = open(argv[0], O_RDONLY, 0); 227 1.1 drochner if (ffd < 0) 228 1.5 hubertf err(4, "open font %s", argv[0]); 229 1.1 drochner if (!f.name) 230 1.1 drochner f.name = argv[0]; 231 1.1 drochner } else 232 1.1 drochner ffd = 0; 233 1.1 drochner 234 1.1 drochner if (!f.stride) 235 1.1 drochner f.stride = (f.fontwidth + 7) / 8; 236 1.1 drochner len = f.fontheight * f.numchars * f.stride; 237 1.21 macallan if ((ffd != 0) && (fstat(ffd, &st) == 0)) { 238 1.20 macallan if ((off_t)len != st.st_size) { 239 1.19 macallan uint32_t foo = 0; 240 1.19 macallan char b[65]; 241 1.19 macallan len = st.st_size; 242 1.19 macallan /* read header */ 243 1.19 macallan read(ffd, b, 4); 244 1.19 macallan if (strncmp(b, "WSFT", 4) != 0) 245 1.19 macallan errx(1, "invalid wsf file "); 246 1.19 macallan read(ffd, b, 64); 247 1.21 macallan if (use_embedded_name) { 248 1.21 macallan b[64] = 0; 249 1.21 macallan strcpy(nbuf, b); 250 1.21 macallan f.name = nbuf; 251 1.21 macallan } 252 1.19 macallan read(ffd, &foo, 4); 253 1.19 macallan f.firstchar = le32toh(foo); 254 1.19 macallan read(ffd, &foo, 4); 255 1.19 macallan f.numchars = le32toh(foo); 256 1.19 macallan read(ffd, &foo, 4); 257 1.19 macallan f.encoding = le32toh(foo); 258 1.19 macallan read(ffd, &foo, 4); 259 1.19 macallan f.fontwidth = le32toh(foo); 260 1.19 macallan read(ffd, &foo, 4); 261 1.19 macallan f.fontheight = le32toh(foo); 262 1.19 macallan read(ffd, &foo, 4); 263 1.19 macallan f.stride = le32toh(foo); 264 1.19 macallan read(ffd, &foo, 4); 265 1.19 macallan f.bitorder = le32toh(foo); 266 1.19 macallan read(ffd, &foo, 4); 267 1.19 macallan f.byteorder = le32toh(foo); 268 1.19 macallan len = f.numchars * f.fontheight * f.stride; 269 1.19 macallan } 270 1.19 macallan } 271 1.19 macallan 272 1.1 drochner if (!len) 273 1.1 drochner errx(1, "invalid font size"); 274 1.1 drochner 275 1.1 drochner buf = malloc(len); 276 1.1 drochner if (!buf) 277 1.1 drochner errx(1, "malloc"); 278 1.1 drochner res = read(ffd, buf, len); 279 1.1 drochner if (res < 0) 280 1.1 drochner err(4, "read font"); 281 1.14 lukem if ((size_t)res != len) 282 1.1 drochner errx(4, "short read"); 283 1.1 drochner 284 1.1 drochner f.data = buf; 285 1.1 drochner 286 1.5 hubertf if (verbose) { 287 1.5 hubertf printf("name: %s\n", f.name); 288 1.5 hubertf printf("firstchar: %d\n", f.firstchar); 289 1.5 hubertf printf("numchars: %d\n", f.numchars); 290 1.5 hubertf printf("encoding: %s (%d)\n", 291 1.5 hubertf rgetencoding(f.encoding), f.encoding); 292 1.5 hubertf printf("fontwidth: %d\n", f.fontwidth); 293 1.5 hubertf printf("fontheight: %d\n", f.fontheight); 294 1.5 hubertf printf("stride: %d\n", f.stride); 295 1.5 hubertf printf("bitorder: %s (%d)\n", 296 1.5 hubertf rgetfontorder(f.bitorder), f.bitorder); 297 1.5 hubertf printf("byteorder: %s (%d)\n", 298 1.5 hubertf rgetfontorder(f.byteorder), f.byteorder); 299 1.5 hubertf } 300 1.5 hubertf 301 1.1 drochner res = ioctl(wsfd, WSDISPLAYIO_LDFONT, &f); 302 1.1 drochner if (res < 0) 303 1.1 drochner err(3, "WSDISPLAYIO_LDFONT"); 304 1.1 drochner 305 1.1 drochner return (0); 306 1.1 drochner } 307