[BACK]Return to wsfont.c CVS log [TXT][DIR] Up to [local] / sys / dev / wsfont

Annotation of sys/dev/wsfont/wsfont.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: wsfont.c,v 1.20 2006/08/06 16:00:46 miod Exp $ */
        !             2: /*     $NetBSD: wsfont.c,v 1.17 2001/02/07 13:59:24 ad Exp $   */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1999 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Andrew Doran.
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  * 2. Redistributions in binary form must reproduce the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer in the
        !            18:  *    documentation and/or other materials provided with the distribution.
        !            19:  * 3. All advertising materials mentioning features or use of this software
        !            20:  *    must display the following acknowledgement:
        !            21:  *     This product includes software developed by the NetBSD
        !            22:  *     Foundation, Inc. and its contributors.
        !            23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            24:  *    contributors may be used to endorse or promote products derived
        !            25:  *    from this software without specific prior written permission.
        !            26:  *
        !            27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            37:  * POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: #include <sys/types.h>
        !            41: #include <sys/param.h>
        !            42: #include <sys/systm.h>
        !            43: #include <sys/time.h>
        !            44: #include <sys/malloc.h>
        !            45:
        !            46: #include <dev/wscons/wsdisplayvar.h>
        !            47: #include <dev/wscons/wsconsio.h>
        !            48: #include <dev/wsfont/wsfont.h>
        !            49:
        !            50: #include "wsfont_glue.h"       /* NRASOPS_ROTATION */
        !            51:
        !            52: #undef HAVE_FONT
        !            53:
        !            54: #ifdef FONT_QVSS8x15
        !            55: #define HAVE_FONT 1
        !            56: #include <dev/wsfont/qvss8x15.h>
        !            57: #endif
        !            58:
        !            59: #ifdef FONT_LUCIDA16x29
        !            60: #define HAVE_FONT 1
        !            61: #include <dev/wsfont/lucida16x29.h>
        !            62: #endif
        !            63:
        !            64: #ifdef FONT_VT220L8x8
        !            65: #define HAVE_FONT 1
        !            66: #include <dev/wsfont/vt220l8x8.h>
        !            67: #endif
        !            68:
        !            69: #ifdef FONT_VT220L8x10
        !            70: #define HAVE_FONT 1
        !            71: #include <dev/wsfont/vt220l8x10.h>
        !            72: #endif
        !            73:
        !            74: #ifdef FONT_SONY8x16
        !            75: #define HAVE_FONT 1
        !            76: #include <dev/wsfont/sony8x16.h>
        !            77: #endif
        !            78:
        !            79: #ifdef FONT_SONY12x24
        !            80: #define HAVE_FONT 1
        !            81: #include <dev/wsfont/sony12x24.h>
        !            82: #endif
        !            83:
        !            84: #ifdef FONT_OMRON12x20
        !            85: #define HAVE_FONT 1
        !            86: #include <dev/wsfont/omron12x20.h>
        !            87: #endif
        !            88:
        !            89: #ifdef FONT_BOLD8x16
        !            90: #define HAVE_FONT 1
        !            91: #include <dev/wsfont/bold8x16.h>
        !            92: #endif
        !            93:
        !            94: #ifdef FONT_GALLANT12x22
        !            95: #define HAVE_FONT 1
        !            96: #endif
        !            97:
        !            98: #ifdef FONT_BOLD8x16_ISO1
        !            99: #define HAVE_FONT 1
        !           100: #endif
        !           101:
        !           102: /*
        !           103:  * Make sure we always have at least one font.
        !           104:  * Sparc, sparc64 always provide a 8x16 font and a larger 12x22 font.
        !           105:  * Other platforms also provide both, but the 12x22 font is omitted if
        !           106:  * option SMALL_KERNEL.
        !           107:  */
        !           108: #ifndef HAVE_FONT
        !           109: #define HAVE_FONT 1
        !           110:
        !           111: #define        FONT_BOLD8x16_ISO1
        !           112: #if defined(__sparc__) || defined(__sparc64__) || defined(luna88k) || !defined(SMALL_KERNEL)
        !           113: #define        FONT_GALLANT12x22
        !           114: #endif
        !           115:
        !           116: #endif /* HAVE_FONT */
        !           117:
        !           118: #ifdef FONT_BOLD8x16_ISO1
        !           119: #include <dev/wsfont/bold8x16-iso1.h>
        !           120: #endif
        !           121:
        !           122: #ifdef FONT_GALLANT12x22
        !           123: #include <dev/wsfont/gallant12x22.h>
        !           124: #endif
        !           125:
        !           126: /* Placeholder struct used for linked list */
        !           127: struct font {
        !           128:        struct  font *next;
        !           129:        struct  font *prev;
        !           130:        struct  wsdisplay_font *font;
        !           131:        u_short lockcount;
        !           132:        u_short cookie;
        !           133:        u_short flg;
        !           134: };
        !           135:
        !           136: /* Our list of built-in fonts */
        !           137: static struct font *list, builtin_fonts[] = {
        !           138: #ifdef FONT_BOLD8x16
        !           139:        { NULL, NULL, &bold8x16, 0, 1, WSFONT_STATIC | WSFONT_BUILTIN  },
        !           140: #endif
        !           141: #ifdef FONT_BOLD8x16_ISO1
        !           142:        { NULL, NULL, &bold8x16_iso1, 0, 2, WSFONT_STATIC | WSFONT_BUILTIN },
        !           143: #endif
        !           144: #ifdef FONT_COURIER11x18
        !           145:        { NULL, NULL, &courier11x18, 0, 3, WSFONT_STATIC | WSFONT_BUILTIN },
        !           146: #endif
        !           147: #ifdef FONT_GALLANT12x22
        !           148:        { NULL, NULL, &gallant12x22, 0, 4, WSFONT_STATIC | WSFONT_BUILTIN },
        !           149: #endif
        !           150: #ifdef FONT_LUCIDA16x29
        !           151:        { NULL, NULL, &lucida16x29, 0, 5, WSFONT_STATIC | WSFONT_BUILTIN },
        !           152: #endif
        !           153: #ifdef FONT_QVSS8x15
        !           154:        { NULL, NULL, &qvss8x15, 0, 6, WSFONT_STATIC | WSFONT_BUILTIN },
        !           155: #endif
        !           156: #ifdef FONT_VT220L8x8
        !           157:        { NULL, NULL, &vt220l8x8, 0, 7, WSFONT_STATIC | WSFONT_BUILTIN },
        !           158: #endif
        !           159: #ifdef FONT_VT220L8x10
        !           160:        { NULL, NULL, &vt220l8x10, 0, 8, WSFONT_STATIC | WSFONT_BUILTIN },
        !           161: #endif
        !           162: #ifdef FONT_SONY8x16
        !           163:        { NULL, NULL, &sony8x16, 0, 9, WSFONT_STATIC | WSFONT_BUILTIN },
        !           164: #endif
        !           165: #ifdef FONT_SONY12x24
        !           166:        { NULL, NULL, &sony12x24, 0, 10, WSFONT_STATIC | WSFONT_BUILTIN },
        !           167: #endif
        !           168: #ifdef FONT_OMRON12x20
        !           169:        { NULL, NULL, &omron12x20, 0, 11, WSFONT_STATIC | WSFONT_BUILTIN },
        !           170: #endif
        !           171:        { NULL, NULL, NULL, 0 },
        !           172: };
        !           173:
        !           174: #if !defined(SMALL_KERNEL) || defined(__alpha__)
        !           175:
        !           176: /* Reverse the bit order in a byte */
        !           177: static const u_char reverse[256] = {
        !           178:        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
        !           179:        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
        !           180:        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
        !           181:        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
        !           182:        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
        !           183:        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
        !           184:        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
        !           185:        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
        !           186:        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
        !           187:        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
        !           188:        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
        !           189:        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
        !           190:        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
        !           191:        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
        !           192:        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
        !           193:        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
        !           194:        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
        !           195:        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
        !           196:        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
        !           197:        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
        !           198:        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
        !           199:        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
        !           200:        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
        !           201:        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
        !           202:        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
        !           203:        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
        !           204:        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
        !           205:        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
        !           206:        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
        !           207:        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
        !           208:        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
        !           209:        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
        !           210: };
        !           211:
        !           212: #endif
        !           213:
        !           214: static struct font *wsfont_find0(int);
        !           215:
        !           216: #if !defined(SMALL_KERNEL) || defined(__alpha__)
        !           217:
        !           218: /*
        !           219:  * Reverse the bit order of a font
        !           220:  */
        !           221: static void    wsfont_revbit(struct wsdisplay_font *);
        !           222: static void
        !           223: wsfont_revbit(font)
        !           224:        struct wsdisplay_font *font;
        !           225: {
        !           226:        u_char *p, *m;
        !           227:
        !           228:        p = (u_char *)font->data;
        !           229:        m = p + font->stride * font->numchars * font->fontheight;
        !           230:
        !           231:        for (; p < m; p++)
        !           232:                *p = reverse[*p];
        !           233: }
        !           234:
        !           235: #endif
        !           236:
        !           237: #if !defined(SMALL_KERNEL)
        !           238:
        !           239: /*
        !           240:  * Reverse the byte order of a font
        !           241:  */
        !           242: static void    wsfont_revbyte(struct wsdisplay_font *);
        !           243: static void
        !           244: wsfont_revbyte(font)
        !           245:        struct wsdisplay_font *font;
        !           246: {
        !           247:        int x, l, r, nr;
        !           248:        u_char *rp;
        !           249:
        !           250:        if (font->stride == 1)
        !           251:                return;
        !           252:
        !           253:        rp = (u_char *)font->data;
        !           254:        nr = font->numchars * font->fontheight;
        !           255:
        !           256:        while (nr--) {
        !           257:                l = 0;
        !           258:                r = font->stride - 1;
        !           259:
        !           260:                while (l < r) {
        !           261:                        x = rp[l];
        !           262:                        rp[l] = rp[r];
        !           263:                        rp[r] = x;
        !           264:                        l++, r--;
        !           265:                }
        !           266:
        !           267:                rp += font->stride;
        !           268:        }
        !           269: }
        !           270:
        !           271: #endif
        !           272:
        !           273: /*
        !           274:  * Enumerate the list of fonts
        !           275:  */
        !           276: void
        !           277: wsfont_enum(cb)
        !           278:        void (*cb)(char *, int, int, int);
        !           279: {
        !           280:        struct wsdisplay_font *f;
        !           281:        struct font *ent;
        !           282:        int s;
        !           283:
        !           284:        s = splhigh();
        !           285:
        !           286:        for (ent = list; ent; ent = ent->next) {
        !           287:                f = ent->font;
        !           288:                cb(f->name, f->fontwidth, f->fontheight, f->stride);
        !           289:        }
        !           290:
        !           291:        splx(s);
        !           292: }
        !           293:
        !           294: #if NRASOPS_ROTATION > 0
        !           295:
        !           296: struct wsdisplay_font *wsfont_rotate_internal(struct wsdisplay_font *);
        !           297:
        !           298: struct wsdisplay_font *
        !           299: wsfont_rotate_internal(struct wsdisplay_font *font)
        !           300: {
        !           301:        int b, n, r, newstride;
        !           302:        struct wsdisplay_font *newfont;
        !           303:        char *newbits;
        !           304:
        !           305:        /* Duplicate the existing font... */
        !           306:        newfont = malloc(sizeof *font, M_DEVBUF, M_WAITOK);
        !           307:        if (newfont == NULL)
        !           308:                return (NULL);
        !           309:
        !           310:        bcopy(font, newfont, sizeof *font);
        !           311:        newfont->cookie = NULL;
        !           312:
        !           313:        /* Allocate a buffer big enough for the rotated font. */
        !           314:        newstride = (font->fontheight + 7) / 8;
        !           315:        newbits = malloc(newstride * font->fontwidth * font->numchars,
        !           316:            M_DEVBUF, M_WAITOK);
        !           317:        if (newbits == NULL) {
        !           318:                free(newfont, M_DEVBUF);
        !           319:                return (NULL);
        !           320:        }
        !           321:
        !           322:        bzero(newbits, newstride * font->fontwidth * font->numchars);
        !           323:
        !           324:        /* Rotate the font a bit at a time. */
        !           325:        for (n = 0; n < font->numchars; n++) {
        !           326:                char *ch = font->data + (n * font->stride * font->fontheight);
        !           327:
        !           328:                for (r = 0; r < font->fontheight; r++) {
        !           329:                        for (b = 0; b < font->fontwidth; b++) {
        !           330:                                unsigned char *rb;
        !           331:
        !           332:                                rb = ch + (font->stride * r) + (b / 8);
        !           333:                                if (*rb & (0x80 >> (b % 8))) {
        !           334:                                        unsigned char *rrb;
        !           335:
        !           336:                                        rrb = newbits + newstride - 1 - (r / 8)
        !           337:                                            + (n * newstride * font->fontwidth)
        !           338:                                            + (newstride * b);
        !           339:                                        *rrb |= (1 << (r % 8));
        !           340:                                }
        !           341:                        }
        !           342:                }
        !           343:        }
        !           344:
        !           345:        newfont->data = newbits;
        !           346:
        !           347:        /* Update font sizes. */
        !           348:        newfont->stride = newstride;
        !           349:        newfont->fontwidth = font->fontheight;
        !           350:        newfont->fontheight = font->fontwidth;
        !           351:
        !           352:        if (wsfont_add(newfont, 0) != 0) {
        !           353:                /*
        !           354:                 * If we seem to have rotated this font already, drop the
        !           355:                 * new one...
        !           356:                 */
        !           357:                free(newbits, M_DEVBUF);
        !           358:                free(newfont, M_DEVBUF);
        !           359:                newfont = NULL;
        !           360:        }
        !           361:
        !           362:        return (newfont);
        !           363: }
        !           364:
        !           365: int
        !           366: wsfont_rotate(int cookie)
        !           367: {
        !           368:        int s, ncookie;
        !           369:        struct wsdisplay_font *font;
        !           370:        struct font *origfont;
        !           371:
        !           372:        s = splhigh();
        !           373:        origfont = wsfont_find0(cookie);
        !           374:        splx(s);
        !           375:
        !           376:        font = wsfont_rotate_internal(origfont->font);
        !           377:        if (font == NULL)
        !           378:                return (-1);
        !           379:
        !           380:        ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight,
        !           381:            font->stride);
        !           382:
        !           383:        return (ncookie);
        !           384: }
        !           385:
        !           386: #endif /* NRASOPS_ROTATION */
        !           387:
        !           388: /*
        !           389:  * Initialize list with WSFONT_BUILTIN fonts
        !           390:  */
        !           391: void
        !           392: wsfont_init(void)
        !           393: {
        !           394:        static int again;
        !           395:        int i;
        !           396:
        !           397:        if (again != 0)
        !           398:                return;
        !           399:        again = 1;
        !           400:
        !           401:        for (i = 0; builtin_fonts[i].font != NULL; i++) {
        !           402:                builtin_fonts[i].next = list;
        !           403:                list = &builtin_fonts[i];
        !           404:        }
        !           405: }
        !           406:
        !           407: /*
        !           408:  * Find a font by cookie. Called at splhigh.
        !           409:  */
        !           410: static struct font *
        !           411: wsfont_find0(cookie)
        !           412:        int cookie;
        !           413: {
        !           414:        struct font *ent;
        !           415:
        !           416:        for (ent = list; ent != NULL; ent = ent->next)
        !           417:                if (ent->cookie == cookie)
        !           418:                        return (ent);
        !           419:
        !           420:        return (NULL);
        !           421: }
        !           422:
        !           423: /*
        !           424:  * Find a font.
        !           425:  */
        !           426: int
        !           427: wsfont_find(name, width, height, stride)
        !           428:        char *name;
        !           429:        int width, height, stride;
        !           430: {
        !           431:        struct font *ent;
        !           432:        int s;
        !           433:
        !           434:        s = splhigh();
        !           435:
        !           436:        for (ent = list; ent != NULL; ent = ent->next) {
        !           437:                if (height != 0 && ent->font->fontheight != height)
        !           438:                        continue;
        !           439:
        !           440:                if (width != 0 && ent->font->fontwidth != width)
        !           441:                        continue;
        !           442:
        !           443:                if (stride != 0 && ent->font->stride != stride)
        !           444:                        continue;
        !           445:
        !           446:                if (name != NULL && strcmp(ent->font->name, name) != 0)
        !           447:                        continue;
        !           448:
        !           449:                splx(s);
        !           450:                return (ent->cookie);
        !           451:        }
        !           452:
        !           453:        splx(s);
        !           454:        return (-1);
        !           455: }
        !           456:
        !           457: /*
        !           458:  * Add a font to the list.
        !           459:  */
        !           460: int
        !           461: wsfont_add(font, copy)
        !           462:        struct wsdisplay_font *font;
        !           463:        int copy;
        !           464: {
        !           465:        static int cookiegen = 666;
        !           466:        struct font *ent;
        !           467:        size_t size;
        !           468:        int s;
        !           469:
        !           470:        s = splhigh();
        !           471:
        !           472:        /* Don't allow exact duplicates */
        !           473:        if (wsfont_find(font->name, font->fontwidth, font->fontheight,
        !           474:            font->stride) >= 0) {
        !           475:                splx(s);
        !           476:                return (-1);
        !           477:        }
        !           478:
        !           479:        MALLOC(ent, struct font *, sizeof *ent, M_DEVBUF, M_WAITOK);
        !           480:
        !           481:        ent->lockcount = 0;
        !           482:        ent->flg = 0;
        !           483:        ent->cookie = cookiegen++;
        !           484:        ent->next = list;
        !           485:        ent->prev = NULL;
        !           486:
        !           487:        /* Is this font statically allocated? */
        !           488:        if (!copy) {
        !           489:                ent->font = font;
        !           490:                ent->flg = WSFONT_STATIC;
        !           491:        } else {
        !           492:                MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font,
        !           493:                    M_DEVBUF, M_WAITOK);
        !           494:                memcpy(ent->font, font, sizeof(*ent->font));
        !           495:
        !           496:                size = font->fontheight * font->numchars * font->stride;
        !           497:                MALLOC(ent->font->data, void *, size, M_DEVBUF, M_WAITOK);
        !           498:                memcpy(ent->font->data, font->data, size);
        !           499:                ent->flg = 0;
        !           500:        }
        !           501:
        !           502:        /* Now link into the list and return */
        !           503:        list = ent;
        !           504:        splx(s);
        !           505:        return (0);
        !           506: }
        !           507:
        !           508: /*
        !           509:  * Remove a font.
        !           510:  */
        !           511: #ifdef notyet
        !           512: int
        !           513: wsfont_remove(cookie)
        !           514:        int cookie;
        !           515: {
        !           516:        struct font *ent;
        !           517:        int s;
        !           518:
        !           519:        s = splhigh();
        !           520:
        !           521:        if ((ent = wsfont_find0(cookie)) == NULL) {
        !           522:                splx(s);
        !           523:                return (-1);
        !           524:        }
        !           525:
        !           526:        if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) {
        !           527:                splx(s);
        !           528:                return (-1);
        !           529:        }
        !           530:
        !           531:        /* Don't free statically allocated font data */
        !           532:        if ((ent->flg & WSFONT_STATIC) != 0) {
        !           533:                FREE(ent->font->data, M_DEVBUF);
        !           534:                FREE(ent->font, M_DEVBUF);
        !           535:        }
        !           536:
        !           537:        /* Remove from list, free entry */
        !           538:        if (ent->prev)
        !           539:                ent->prev->next = ent->next;
        !           540:        else
        !           541:                list = ent->next;
        !           542:
        !           543:        if (ent->next)
        !           544:                ent->next->prev = ent->prev;
        !           545:
        !           546:        FREE(ent, M_DEVBUF);
        !           547:        splx(s);
        !           548:        return (0);
        !           549: }
        !           550: #endif
        !           551:
        !           552: /*
        !           553:  * Lock a given font and return new lockcount. This fails if the cookie
        !           554:  * is invalid, or if the font is already locked and the bit/byte order
        !           555:  * requested by the caller differs.
        !           556:  */
        !           557: int
        !           558: wsfont_lock(cookie, ptr, bitorder, byteorder)
        !           559:        int cookie;
        !           560:        struct wsdisplay_font **ptr;
        !           561:        int bitorder, byteorder;
        !           562: {
        !           563:        struct font *ent;
        !           564:        int s, lc;
        !           565:
        !           566:        s = splhigh();
        !           567:
        !           568:        if ((ent = wsfont_find0(cookie)) != NULL) {
        !           569:                if (bitorder && bitorder != ent->font->bitorder) {
        !           570: #if !defined(SMALL_KERNEL) || defined(__alpha__)
        !           571:                        if (ent->lockcount) {
        !           572:                                splx(s);
        !           573:                                return (-1);
        !           574:                        }
        !           575:                        wsfont_revbit(ent->font);
        !           576:                        ent->font->bitorder = bitorder;
        !           577: #else
        !           578:                        splx(s);
        !           579:                        return (-1);
        !           580: #endif
        !           581:                }
        !           582:
        !           583:                if (byteorder && byteorder != ent->font->byteorder) {
        !           584: #if !defined(SMALL_KERNEL)
        !           585:                        if (ent->lockcount) {
        !           586:                                splx(s);
        !           587:                                return (-1);
        !           588:                        }
        !           589:                        wsfont_revbyte(ent->font);
        !           590:                        ent->font->byteorder = byteorder;
        !           591: #else
        !           592:                        splx(s);
        !           593:                        return (-1);
        !           594: #endif
        !           595:                }
        !           596:
        !           597:                lc = ++ent->lockcount;
        !           598:                *ptr = ent->font;
        !           599:        } else
        !           600:                lc = -1;
        !           601:
        !           602:        splx(s);
        !           603:        return (lc);
        !           604: }
        !           605:
        !           606: /*
        !           607:  * Get font flags and lockcount.
        !           608:  */
        !           609: int
        !           610: wsfont_getflg(cookie, flg, lc)
        !           611:        int cookie, *flg, *lc;
        !           612: {
        !           613:        struct font *ent;
        !           614:        int s;
        !           615:
        !           616:        s = splhigh();
        !           617:
        !           618:        if ((ent = wsfont_find0(cookie)) != NULL) {
        !           619:                *flg = ent->flg;
        !           620:                *lc = ent->lockcount;
        !           621:        }
        !           622:
        !           623:        splx(s);
        !           624:        return (ent != NULL ? 0 : -1);
        !           625: }
        !           626:
        !           627: /*
        !           628:  * Unlock a given font and return new lockcount.
        !           629:  */
        !           630: int
        !           631: wsfont_unlock(cookie)
        !           632:        int cookie;
        !           633: {
        !           634:        struct font *ent;
        !           635:        int s, lc;
        !           636:
        !           637:        s = splhigh();
        !           638:
        !           639:        if ((ent = wsfont_find0(cookie)) != NULL) {
        !           640:                if (ent->lockcount == 0)
        !           641:                        panic("wsfont_unlock: font not locked");
        !           642:                lc = --ent->lockcount;
        !           643:        } else
        !           644:                lc = -1;
        !           645:
        !           646:        splx(s);
        !           647:        return (lc);
        !           648: }
        !           649:
        !           650: #if !defined(SMALL_KERNEL)
        !           651:
        !           652: /*
        !           653:  * Unicode to font encoding mappings
        !           654:  */
        !           655:
        !           656: /*
        !           657:  * To save memory, font encoding tables use a two level lookup.
        !           658:  * First the high byte of the Unicode is used to lookup the level 2
        !           659:  * table, then the low byte indexes that table.  Level 2 tables that are
        !           660:  * not needed are omitted (NULL), and both level 1 and level 2 tables
        !           661:  * have base and size attributes to keep their size down.
        !           662:  */
        !           663:
        !           664: struct wsfont_level1_glyphmap {
        !           665:        struct wsfont_level2_glyphmap **level2;
        !           666:        int base;       /* High byte for first level2 entry     */
        !           667:        int size;       /* Number of level2 entries             */
        !           668: };
        !           669:
        !           670: struct wsfont_level2_glyphmap {
        !           671:        int base;       /* Low byte for first character         */
        !           672:        int size;       /* Number of characters                 */
        !           673:        void *chars;    /* Pointer to character number entries  */
        !           674:        int width;      /* Size of each entry in bytes (1,2,4)  */
        !           675: };
        !           676:
        !           677: #define null16                 \
        !           678:        NULL, NULL, NULL, NULL, \
        !           679:        NULL, NULL, NULL, NULL, \
        !           680:        NULL, NULL, NULL, NULL, \
        !           681:        NULL, NULL, NULL, NULL
        !           682:
        !           683: /*
        !           684:  * IBM 437 maps
        !           685:  */
        !           686:
        !           687: static u_int8_t
        !           688: ibm437_chars_0[] = {
        !           689:         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
        !           690:        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
        !           691:        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
        !           692:        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
        !           693:        64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
        !           694:        80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
        !           695:        96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
        !           696:        112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
        !           697:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           698:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           699:        255,173,155,156, 0, 157, 0,  0,  0,  0, 166,174,170, 0,  0,  0,
        !           700:         0, 241,253, 0,  0,  0,  0, 249, 0,  0, 167,175,172,171, 0, 168,
        !           701:         0,  0,  0,  0, 142,143,146,128, 0, 144, 0,  0,  0,  0,  0,  0,
        !           702:         0, 165, 0,  0,  0,  0, 153, 0,  0,  0,  0,  0, 154, 0,  0,  0,
        !           703:        133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
        !           704:         0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0,  0, 152
        !           705: },
        !           706: ibm437_chars_1[] = {
        !           707:        159
        !           708: },
        !           709: ibm437_chars_3[] = {
        !           710:        226, 0,  0,  0,  0, 233, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           711:        228, 0,  0, 232, 0,  0, 234, 0,  0,  0,  0,  0,  0,  0, 224,225,
        !           712:         0, 235,238, 0,  0,  0,  0,  0,  0, 230, 0,  0,  0, 227, 0,  0,
        !           713:        229,231
        !           714: },
        !           715: ibm437_chars_32[] = {
        !           716:        252, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           717:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           718:         0,  0,  0,  0,  0,  0,  0,  0, 158
        !           719: },
        !           720: ibm437_chars_34[] = {
        !           721:        237, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           722:         0,  0,  0, 248,250,251, 0,  0,  0, 236, 0,  0,  0,  0,  0,  0,
        !           723:         0,  0,  0,  0, 239, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           724:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           725:         0,  0,  0, 247, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           726:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,  0,  0,243,
        !           727:        242
        !           728: },
        !           729: ibm437_chars_35[] = {
        !           730:        169, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           731:        244,245
        !           732: },
        !           733: ibm437_chars_37[] = {
        !           734:        196,205,179,186, 0,  0,  0,  0,  0,  0,  0,  0, 218,213,214,201,
        !           735:        191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0,  0,
        !           736:        199, 0,  0, 204,180,181, 0,  0, 182, 0,  0, 185,194, 0,  0, 209,
        !           737:        210, 0,  0, 203,193, 0,  0, 207,208, 0,  0, 202,197, 0,  0, 216,
        !           738:         0,  0, 215, 0,  0,  0,  0,  0,  0,  0,  0, 206, 0,  0,  0,  0,
        !           739:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           740:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           741:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           742:        223, 0,  0,  0, 220, 0,  0,  0, 219, 0,  0,  0, 221, 0,  0,  0,
        !           743:        222,176,177,178, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           744:        254
        !           745: };
        !           746:
        !           747: static struct wsfont_level2_glyphmap
        !           748: ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 },
        !           749: ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 },
        !           750: ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 },
        !           751: ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 },
        !           752: ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 },
        !           753: ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 },
        !           754: ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 };
        !           755:
        !           756: static struct wsfont_level2_glyphmap *ibm437_level1[] = {
        !           757:        &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
        !           758:        NULL, NULL, NULL, NULL,
        !           759:        NULL, NULL, NULL, NULL,
        !           760:        NULL, NULL, NULL, NULL,
        !           761:        NULL, NULL, NULL, NULL,
        !           762:        NULL, NULL, NULL, NULL,
        !           763:        NULL, NULL, NULL, NULL,
        !           764:        NULL, NULL, NULL, NULL,
        !           765:        &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
        !           766:        NULL, &ibm437_level2_37
        !           767: };
        !           768:
        !           769:
        !           770: /*
        !           771:  * ISO-8859-7 maps
        !           772:  */
        !           773:
        !           774: static u_int8_t
        !           775: iso7_chars_0[] = {
        !           776:         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
        !           777:        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
        !           778:        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
        !           779:        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
        !           780:        64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
        !           781:        80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
        !           782:        96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
        !           783:        112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
        !           784:        128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
        !           785:        144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
        !           786:        160, 0,  0, 163, 0,  0, 166,167,168,169, 0, 171,172,173, 0,  0,
        !           787:        176,177,178,179,180, 0,  0, 183, 0,  0,  0, 187, 0, 189
        !           788: },
        !           789: iso7_chars_3[] = {
        !           790:        182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
        !           791:        198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
        !           792:        214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
        !           793:        230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
        !           794:        246,247,248,249,250,251,252,253,254, 0,  0,  0,  0,  0,  0,  0,
        !           795:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        !           796:         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 181
        !           797: },
        !           798: iso7_chars_32[] = {
        !           799:        175, 0,  0,  0,  0, 162, 0, 161
        !           800: };
        !           801:
        !           802: static struct wsfont_level2_glyphmap
        !           803: iso7_level2_0 = { 0, 190, iso7_chars_0, 1 },
        !           804: iso7_level2_3 = { 134, 111, iso7_chars_3, 1 },
        !           805: iso7_level2_32 = { 20, 8, iso7_chars_32, 1 };
        !           806:
        !           807: static struct wsfont_level2_glyphmap *iso7_level1[] = {
        !           808:        &iso7_level2_0, NULL, NULL, &iso7_level2_3,
        !           809:        NULL, NULL, NULL, NULL,
        !           810:        NULL, NULL, NULL, NULL,
        !           811:        NULL, NULL, NULL, NULL,
        !           812:        NULL, NULL, NULL, NULL,
        !           813:        NULL, NULL, NULL, NULL,
        !           814:        NULL, NULL, NULL, NULL,
        !           815:        NULL, NULL, NULL, NULL,
        !           816:        &iso7_level2_32
        !           817: };
        !           818:
        !           819:
        !           820: static struct wsfont_level1_glyphmap encodings[] = {
        !           821:        { NULL, 0, 0 },                 /* WSDISPLAY_FONTENC_ISO */
        !           822:        { ibm437_level1, 0, 38 },       /* WSDISPLAY_FONTENC_IBM */
        !           823:        { NULL, 0, 0 },                 /* WSDISPLAY_FONTENC_PCVT */
        !           824:        { iso7_level1, 0, 33 },         /* WSDISPLAY_FONTENC_ISO7 */
        !           825: };
        !           826:
        !           827: #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
        !           828:
        !           829: #endif /* !SMALL_KERNEL */
        !           830:
        !           831: /*
        !           832:  * Remap Unicode character to glyph
        !           833:  */
        !           834: int
        !           835: wsfont_map_unichar(font, c)
        !           836:        struct wsdisplay_font *font;
        !           837:        int c;
        !           838: {
        !           839:        if (font->encoding == WSDISPLAY_FONTENC_ISO)
        !           840:                return c;
        !           841:        else
        !           842: #if !defined(SMALL_KERNEL)
        !           843:        if (font->encoding < 0 || font->encoding > MAX_ENCODING)
        !           844:                return (-1);
        !           845:        else {
        !           846:                int hi = (c >> 8), lo = c & 255;
        !           847:                struct wsfont_level1_glyphmap *map1 =
        !           848:                        &encodings[font->encoding];
        !           849:
        !           850:                if (hi >= map1->base && hi < map1->base + map1->size) {
        !           851:                        struct wsfont_level2_glyphmap *map2 =
        !           852:                          map1->level2[hi - map1->base];
        !           853:
        !           854:                        if (map2 != NULL &&
        !           855:                            lo >= map2->base && lo < map2->base + map2->size) {
        !           856:
        !           857:                                lo -= map2->base;
        !           858:
        !           859:                                switch(map2->width) {
        !           860:                                case 1:
        !           861:                                        c = (((u_int8_t *)map2->chars)[lo]);
        !           862:                                        break;
        !           863:                                case 2:
        !           864:                                        c = (((u_int16_t *)map2->chars)[lo]);
        !           865:                                        break;
        !           866:                                case 4:
        !           867:                                        c = (((u_int32_t *)map2->chars)[lo]);
        !           868:                                        break;
        !           869:                                }
        !           870:
        !           871:                                if (c == 0 && lo != 0)
        !           872:                                        return (-1);
        !           873:                                else
        !           874:                                        return (c);
        !           875:
        !           876:                        } else {
        !           877:                                return (-1);
        !           878:                        }
        !           879:
        !           880:                } else {
        !           881:                        return (-1);
        !           882:                }
        !           883:
        !           884:        }
        !           885: #else
        !           886:        return (-1);
        !           887: #endif /* SMALL_KERNEL */
        !           888: }

CVSweb