wsfont.c revision 1.12 1 /* $NetBSD: wsfont.c,v 1.12 2000/01/07 03:25:46 enami 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 Andy 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.12 2000/01/07 03:25:46 enami 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