1 /* $NetBSD: wsfont.c,v 1.13 2000/06/13 13:37:06 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.13 2000/06/13 13:37:06 ad Exp $"); 41 42 #include "opt_wsfont.h" 43 44 #include <sys/types.h> 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/time.h> 48 #include <sys/malloc.h> 49 50 #include <dev/wscons/wsdisplayvar.h> 51 #include <dev/wscons/wsconsio.h> 52 #include <dev/wsfont/wsfont.h> 53 54 #undef HAVE_FONT 55 56 #ifdef FONT_QVSS8x15 57 #define HAVE_FONT 1 58 #include <dev/wsfont/qvss8x15.h> 59 #endif 60 61 #ifdef FONT_GALLANT12x22 62 #define HAVE_FONT 1 63 #include <dev/wsfont/gallant12x22.h> 64 #endif 65 66 #ifdef FONT_LUCIDA16x29 67 #define HAVE_FONT 1 68 #include <dev/wsfont/lucida16x29.h> 69 #endif 70 71 #ifdef FONT_VT220L8x8 72 #define HAVE_FONT 1 73 #include <dev/wsfont/vt220l8x8.h> 74 #endif 75 76 #ifdef FONT_VT220L8x10 77 #define HAVE_FONT 1 78 #include <dev/wsfont/vt220l8x10.h> 79 #endif 80 81 /* Make sure we always have at least one font. */ 82 #ifndef HAVE_FONT 83 #define HAVE_FONT 1 84 #define FONT_BOLD8x16 1 85 #endif 86 87 #ifdef FONT_BOLD8x16 88 #include <dev/wsfont/bold8x16.h> 89 #endif 90 91 /* Placeholder struct used for linked list */ 92 struct font { 93 struct font *next; 94 struct font *prev; 95 struct wsdisplay_font *font; 96 u_short lockcount; 97 u_short cookie; 98 u_short flg; 99 }; 100 101 /* Our list of built-in fonts */ 102 static struct font *list, builtin_fonts[] = { 103 #ifdef FONT_BOLD8x16 104 { NULL, NULL, &bold8x16, 0, 1, WSFONT_STATIC | WSFONT_BUILTIN }, 105 #endif 106 #ifdef FONT_ISO8x16 107 { NULL, NULL, &iso8x16, 0, 2, WSFONT_STATIC | WSFONT_BUILTIN }, 108 #endif 109 #ifdef FONT_COURIER11x18 110 { NULL, NULL, &courier11x18, 0, 3, WSFONT_STATIC | WSFONT_BUILTIN }, 111 #endif 112 #ifdef FONT_GALLANT12x22 113 { NULL, NULL, &gallant12x22, 0, 4, WSFONT_STATIC | WSFONT_BUILTIN }, 114 #endif 115 #ifdef FONT_LUCIDA16x29 116 { NULL, NULL, &lucida16x29, 0, 5, WSFONT_STATIC | WSFONT_BUILTIN }, 117 #endif 118 #ifdef FONT_QVSS8x15 119 { NULL, NULL, &qvss8x15, 0, 6, WSFONT_STATIC | WSFONT_BUILTIN }, 120 #endif 121 #ifdef FONT_VT220L8x8 122 { NULL, NULL, &vt220l8x8, 0, 7, WSFONT_STATIC | WSFONT_BUILTIN }, 123 #endif 124 #ifdef FONT_VT220L8x10 125 { NULL, NULL, &vt220l8x10, 0, 8, WSFONT_STATIC | WSFONT_BUILTIN }, 126 #endif 127 { NULL, NULL, NULL, 0 }, 128 }; 129 130 /* Reverse the bit order in a byte */ 131 static const u_char reverse[256] = { 132 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 133 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 134 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 135 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 136 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 137 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 138 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 139 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 140 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 141 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 142 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 143 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 144 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 145 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 146 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 147 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 148 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 149 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 150 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 151 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 152 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 153 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 154 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 155 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 156 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 157 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 158 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 159 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 160 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 161 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 162 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 163 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 164 }; 165 166 static struct font *wsfont_find0 __P((int)); 167 static void wsfont_revbit __P((struct wsdisplay_font *)); 168 static void wsfont_revbyte __P((struct wsdisplay_font *)); 169 170 /* 171 * Reverse the bit order of a font 172 */ 173 static void 174 wsfont_revbit(font) 175 struct wsdisplay_font *font; 176 { 177 u_char *p, *m; 178 179 p = (u_char *)font->data; 180 m = p + font->stride * font->numchars * font->fontheight; 181 182 while (p < m) 183 *p++ = reverse[*p]; 184 } 185 186 /* 187 * Reverse the byte order of a font 188 */ 189 static void 190 wsfont_revbyte(font) 191 struct wsdisplay_font *font; 192 { 193 int x, l, r, nr; 194 u_char *rp; 195 196 if (font->stride == 1) 197 return; 198 199 rp = (u_char *)font->data; 200 nr = font->numchars * font->fontheight; 201 202 while (nr--) { 203 l = 0; 204 r = font->stride - 1; 205 206 while (l < r) { 207 x = rp[l]; 208 rp[l] = rp[r]; 209 rp[r] = x; 210 l++, r--; 211 } 212 213 rp += font->stride; 214 } 215 } 216 217 /* 218 * Enumarate the list of fonts 219 */ 220 void 221 wsfont_enum(cb) 222 void (*cb) __P((char *, int, int, int)); 223 { 224 struct wsdisplay_font *f; 225 struct font *ent; 226 int s; 227 228 s = splhigh(); 229 230 for (ent = list; ent; ent = ent->next) { 231 f = ent->font; 232 cb(f->name, f->fontwidth, f->fontheight, f->stride); 233 } 234 235 splx(s); 236 } 237 238 /* 239 * Initialize list with WSFONT_BUILTIN fonts 240 */ 241 void 242 wsfont_init(void) 243 { 244 static int again; 245 int i; 246 247 if (again != 0) 248 return; 249 again = 1; 250 251 for (i = 0; builtin_fonts[i].font != NULL; i++) { 252 builtin_fonts[i].next = list; 253 list = &builtin_fonts[i]; 254 } 255 } 256 257 /* 258 * Find a font by cookie. Called at splhigh. 259 */ 260 static struct font * 261 wsfont_find0(cookie) 262 int cookie; 263 { 264 struct font *ent; 265 266 for (ent = list; ent != NULL; ent = ent->next) 267 if (ent->cookie == cookie) 268 return (ent); 269 270 return (NULL); 271 } 272 273 /* 274 * Find a font. 275 */ 276 int 277 wsfont_find(name, width, height, stride) 278 char *name; 279 int width, height, stride; 280 { 281 struct font *ent; 282 int s; 283 284 s = splhigh(); 285 286 for (ent = list; ent != NULL; ent = ent->next) { 287 if (height != 0 && ent->font->fontheight != height) 288 continue; 289 290 if (width != 0 && ent->font->fontwidth != width) 291 continue; 292 293 if (stride != 0 && ent->font->stride != stride) 294 continue; 295 296 if (name != NULL && strcmp(ent->font->name, name) != 0) 297 continue; 298 299 splx(s); 300 return (ent->cookie); 301 } 302 303 splx(s); 304 return (-1); 305 } 306 307 /* 308 * Add a font to the list. 309 */ 310 #ifdef notyet 311 int 312 wsfont_add(font, copy) 313 struct wsdisplay_font *font; 314 int copy; 315 { 316 static int cookiegen = 666; 317 struct font *ent; 318 size_t size; 319 int s; 320 321 s = splhigh(); 322 323 /* Don't allow exact duplicates */ 324 if (wsfont_find(font->name, font->fontwidth, font->fontheight, 325 font->stride) >= 0) { 326 splx(s); 327 return (-1); 328 } 329 330 MALLOC(ent, struct font *, sizeof *ent, M_DEVBUF, M_WAITOK); 331 332 ent->lockcount = 0; 333 ent->flg = 0; 334 ent->cookie = cookiegen++; 335 ent->next = list; 336 ent->prev = NULL; 337 338 /* Is this font statically allocated? */ 339 if (!copy) { 340 ent->font = font; 341 ent->flg = WSFONT_STATIC; 342 } else { 343 MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font, 344 M_DEVBUF, M_WAITOK); 345 memcpy(ent->font, font, sizeof(*ent->font)); 346 347 size = font->fontheight * font->numchars * font->stride; 348 MALLOC(ent->font->data, void *, size, M_DEVBUF, M_WAITOK); 349 memcpy(ent->font->data, font->data, size); 350 ent->flg = 0; 351 } 352 353 /* Now link into the list and return */ 354 list = ent; 355 splx(s); 356 return (0); 357 } 358 #endif 359 360 /* 361 * Remove a font. 362 */ 363 #ifdef notyet 364 int 365 wsfont_remove(cookie) 366 int cookie; 367 { 368 struct font *ent; 369 int s; 370 371 s = splhigh(); 372 373 if ((ent = wsfont_find0(cookie)) == NULL) { 374 splx(s); 375 return (-1); 376 } 377 378 if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) { 379 splx(s); 380 return (-1); 381 } 382 383 /* Don't free statically allocated font data */ 384 if ((ent->flg & WSFONT_STATIC) != 0) { 385 FREE(ent->font->data, M_DEVBUF); 386 FREE(ent->font, M_DEVBUF); 387 } 388 389 /* Remove from list, free entry */ 390 if (ent->prev) 391 ent->prev->next = ent->next; 392 else 393 list = ent->next; 394 395 if (ent->next) 396 ent->next->prev = ent->prev; 397 398 FREE(ent, M_DEVBUF); 399 splx(s); 400 return (0); 401 } 402 #endif 403 404 /* 405 * Lock a given font and return new lockcount. This fails if the cookie 406 * is invalid, or if the font is already locked and the bit/byte order 407 * requested by the caller differs. 408 */ 409 int 410 wsfont_lock(cookie, ptr, bitorder, byteorder) 411 int cookie; 412 struct wsdisplay_font **ptr; 413 int bitorder, byteorder; 414 { 415 struct font *ent; 416 int s, lc; 417 418 s = splhigh(); 419 420 if ((ent = wsfont_find0(cookie)) != NULL) { 421 if (bitorder && bitorder != ent->font->bitorder) { 422 if (ent->lockcount) { 423 splx(s); 424 return (-1); 425 } 426 wsfont_revbit(ent->font); 427 ent->font->bitorder = bitorder; 428 } 429 430 if (byteorder && byteorder != ent->font->byteorder) { 431 if (ent->lockcount) { 432 splx(s); 433 return (-1); 434 } 435 wsfont_revbyte(ent->font); 436 ent->font->byteorder = byteorder; 437 } 438 439 lc = ++ent->lockcount; 440 *ptr = ent->font; 441 } else 442 lc = -1; 443 444 splx(s); 445 return (lc); 446 } 447 448 /* 449 * Get font flags and lockcount. 450 */ 451 int 452 wsfont_getflg(cookie, flg, lc) 453 int cookie, *flg, *lc; 454 { 455 struct font *ent; 456 int s; 457 458 s = splhigh(); 459 460 if ((ent = wsfont_find0(cookie)) != NULL) { 461 *flg = ent->flg; 462 *lc = ent->lockcount; 463 } 464 465 splx(s); 466 return (ent != NULL ? 0 : -1); 467 } 468 469 /* 470 * Unlock a given font and return new lockcount. 471 */ 472 int 473 wsfont_unlock(cookie) 474 int cookie; 475 { 476 struct font *ent; 477 int s, lc; 478 479 s = splhigh(); 480 481 if ((ent = wsfont_find0(cookie)) != NULL) { 482 if (ent->lockcount == 0) 483 panic("wsfont_unlock: font not locked\n"); 484 lc = --ent->lockcount; 485 } else 486 lc = -1; 487 488 splx(s); 489 return (lc); 490 } 491