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

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

1.1     ! nbrk        1: /*     $OpenBSD: rasops.c,v 1.17 2006/12/02 18:02:53 miod Exp $        */
        !             2: /*     $NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus 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/param.h>
        !            41: #include <sys/systm.h>
        !            42: #include <sys/time.h>
        !            43:
        !            44: #include <machine/endian.h>
        !            45:
        !            46: #include <dev/wscons/wsdisplayvar.h>
        !            47: #include <dev/wscons/wsconsio.h>
        !            48: #include <dev/wsfont/wsfont.h>
        !            49: #include <dev/rasops/rasops.h>
        !            50:
        !            51: #ifndef _KERNEL
        !            52: #include <errno.h>
        !            53: #endif
        !            54:
        !            55: /* ANSI colormap (R,G,B) */
        !            56:
        !            57: #define        NORMAL_BLACK    0x000000
        !            58: #define        NORMAL_RED      0x7f0000
        !            59: #define        NORMAL_GREEN    0x007f00
        !            60: #define        NORMAL_BROWN    0x7f7f00
        !            61: #define        NORMAL_BLUE     0x00007f
        !            62: #define        NORMAL_MAGENTA  0x7f007f
        !            63: #define        NORMAL_CYAN     0x007f7f
        !            64: #define        NORMAL_WHITE    0xc7c7c7        /* XXX too dim? */
        !            65:
        !            66: #define        HILITE_BLACK    0x7f7f7f
        !            67: #define        HILITE_RED      0xff0000
        !            68: #define        HILITE_GREEN    0x00ff00
        !            69: #define        HILITE_BROWN    0xffff00
        !            70: #define        HILITE_BLUE     0x0000ff
        !            71: #define        HILITE_MAGENTA  0xff00ff
        !            72: #define        HILITE_CYAN     0x00ffff
        !            73: #define        HILITE_WHITE    0xffffff
        !            74:
        !            75: const u_char rasops_cmap[256 * 3] = {
        !            76: #define        _C(x)   ((x) & 0xff0000) >> 16, ((x) & 0x00ff00) >> 8, ((x) & 0x0000ff)
        !            77:
        !            78:        _C(NORMAL_BLACK),
        !            79:        _C(NORMAL_RED),
        !            80:        _C(NORMAL_GREEN),
        !            81:        _C(NORMAL_BROWN),
        !            82:        _C(NORMAL_BLUE),
        !            83:        _C(NORMAL_MAGENTA),
        !            84:        _C(NORMAL_CYAN),
        !            85:        _C(NORMAL_WHITE),
        !            86:
        !            87:        _C(HILITE_BLACK),
        !            88:        _C(HILITE_RED),
        !            89:        _C(HILITE_GREEN),
        !            90:        _C(HILITE_BROWN),
        !            91:        _C(HILITE_BLUE),
        !            92:        _C(HILITE_MAGENTA),
        !            93:        _C(HILITE_CYAN),
        !            94:        _C(HILITE_WHITE),
        !            95:
        !            96:        /*
        !            97:         * For the cursor, we need the last 16 colors to be the
        !            98:         * opposite of the first 16. Fill the intermediate space with
        !            99:         * white completely for simplicity.
        !           100:         */
        !           101: #define _CMWHITE16 \
        !           102:        _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), \
        !           103:        _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), \
        !           104:        _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), \
        !           105:        _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE),
        !           106:        _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
        !           107:        _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
        !           108:        _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
        !           109: #undef _CMWHITE16
        !           110:
        !           111:        _C(~HILITE_WHITE),
        !           112:        _C(~HILITE_CYAN),
        !           113:        _C(~HILITE_MAGENTA),
        !           114:        _C(~HILITE_BLUE),
        !           115:        _C(~HILITE_BROWN),
        !           116:        _C(~HILITE_GREEN),
        !           117:        _C(~HILITE_RED),
        !           118:        _C(~HILITE_BLACK),
        !           119:
        !           120:        _C(~NORMAL_WHITE),
        !           121:        _C(~NORMAL_CYAN),
        !           122:        _C(~NORMAL_MAGENTA),
        !           123:        _C(~NORMAL_BLUE),
        !           124:        _C(~NORMAL_BROWN),
        !           125:        _C(~NORMAL_GREEN),
        !           126:        _C(~NORMAL_RED),
        !           127:        _C(~NORMAL_BLACK),
        !           128:
        !           129: #undef _C
        !           130: };
        !           131:
        !           132: /* True if color is gray */
        !           133: const u_char rasops_isgray[16] = {
        !           134:        1, 0, 0, 0,
        !           135:        0, 0, 0, 1,
        !           136:        1, 0, 0, 0,
        !           137:        0, 0, 0, 1
        !           138: };
        !           139:
        !           140: /* Generic functions */
        !           141: void   rasops_copycols(void *, int, int, int, int);
        !           142: void   rasops_copyrows(void *, int, int, int);
        !           143: int    rasops_mapchar(void *, int, u_int *);
        !           144: void   rasops_cursor(void *, int, int, int);
        !           145: int    rasops_alloc_cattr(void *, int, int, int, long *);
        !           146: int    rasops_alloc_mattr(void *, int, int, int, long *);
        !           147: void   rasops_do_cursor(struct rasops_info *);
        !           148: void   rasops_init_devcmap(struct rasops_info *);
        !           149: void   rasops_unpack_attr(void *, long, int *, int *, int *);
        !           150: #if NRASOPS_BSWAP > 0
        !           151: static void slow_ovbcopy(void *, void *, size_t);
        !           152: #endif
        !           153: #if NRASOPS_ROTATION > 0
        !           154: void   rasops_copychar(void *, int, int, int, int);
        !           155: void   rasops_copycols_rotated(void *, int, int, int, int);
        !           156: void   rasops_copyrows_rotated(void *, int, int, int);
        !           157: void   rasops_erasecols_rotated(void *, int, int, int, long);
        !           158: void   rasops_eraserows_rotated(void *, int, int, long);
        !           159: void   rasops_putchar_rotated(void *, int, int, u_int, long);
        !           160: void   rasops_rotate_font(int *);
        !           161:
        !           162: /*
        !           163:  * List of all rotated fonts
        !           164:  */
        !           165: SLIST_HEAD(, rotatedfont) rotatedfonts = SLIST_HEAD_INITIALIZER(rotatedfonts);
        !           166: struct rotatedfont {
        !           167:        SLIST_ENTRY(rotatedfont) rf_next;
        !           168:        int rf_cookie;
        !           169:        int rf_rotated;
        !           170: };
        !           171: #endif
        !           172:
        !           173: /*
        !           174:  * Initialize a 'rasops_info' descriptor.
        !           175:  */
        !           176: int
        !           177: rasops_init(ri, wantrows, wantcols)
        !           178:        struct rasops_info *ri;
        !           179:        int wantrows, wantcols;
        !           180: {
        !           181:
        !           182: #ifdef _KERNEL
        !           183:        /* Select a font if the caller doesn't care */
        !           184:        if (ri->ri_font == NULL) {
        !           185:                int cookie;
        !           186:
        !           187:                wsfont_init();
        !           188:
        !           189:                if (ri->ri_width > 80*12)
        !           190:                        /* High res screen, choose a big font */
        !           191:                        cookie = wsfont_find(NULL, 12, 0, 0);
        !           192:                else
        !           193:                        /*  lower res, choose a 8 pixel wide font */
        !           194:                        cookie = wsfont_find(NULL, 8, 0, 0);
        !           195:
        !           196:                if (cookie <= 0)
        !           197:                        cookie = wsfont_find(NULL, 0, 0, 0);
        !           198:
        !           199:                if (cookie <= 0) {
        !           200:                        printf("rasops_init: font table is empty\n");
        !           201:                        return (-1);
        !           202:                }
        !           203:
        !           204: #if NRASOPS_ROTATION > 0
        !           205:                /*
        !           206:                 * Pick the rotated version of this font. This will create it
        !           207:                 * if necessary.
        !           208:                 */
        !           209:                if (ri->ri_flg & RI_ROTATE_CW)
        !           210:                        rasops_rotate_font(&cookie);
        !           211: #endif
        !           212:
        !           213:                if (wsfont_lock(cookie, &ri->ri_font,
        !           214:                    WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R) <= 0) {
        !           215:                        printf("rasops_init: couldn't lock font\n");
        !           216:                        return (-1);
        !           217:                }
        !           218:
        !           219:                ri->ri_wsfcookie = cookie;
        !           220:        }
        !           221: #endif
        !           222:
        !           223:        /* This should never happen in reality... */
        !           224: #ifdef DEBUG
        !           225:        if ((long)ri->ri_bits & 3) {
        !           226:                printf("rasops_init: bits not aligned on 32-bit boundary\n");
        !           227:                return (-1);
        !           228:        }
        !           229:
        !           230:        if ((int)ri->ri_stride & 3) {
        !           231:                printf("rasops_init: stride not aligned on 32-bit boundary\n");
        !           232:                return (-1);
        !           233:        }
        !           234: #endif
        !           235:
        !           236:        if (rasops_reconfig(ri, wantrows, wantcols))
        !           237:                return (-1);
        !           238:
        !           239:        rasops_init_devcmap(ri);
        !           240:        return (0);
        !           241: }
        !           242:
        !           243: /*
        !           244:  * Reconfigure (because parameters have changed in some way).
        !           245:  */
        !           246: int
        !           247: rasops_reconfig(ri, wantrows, wantcols)
        !           248:        struct rasops_info *ri;
        !           249:        int wantrows, wantcols;
        !           250: {
        !           251:        int l, bpp, s;
        !           252:
        !           253:        s = splhigh();
        !           254:
        !           255:        if (ri->ri_font->fontwidth > 32 || ri->ri_font->fontwidth < 4)
        !           256:                panic("rasops_init: fontwidth assumptions botched!");
        !           257:
        !           258:        /* Need this to frob the setup below */
        !           259:        bpp = (ri->ri_depth == 15 ? 16 : ri->ri_depth);
        !           260:
        !           261:        if ((ri->ri_flg & RI_CFGDONE) != 0)
        !           262:                ri->ri_bits = ri->ri_origbits;
        !           263:
        !           264:        /* Don't care if the caller wants a hideously small console */
        !           265:        if (wantrows < 10)
        !           266:                wantrows = 10;
        !           267:
        !           268:        if (wantcols < 20)
        !           269:                wantcols = 20;
        !           270:
        !           271:        /* Now constrain what they get */
        !           272:        ri->ri_emuwidth = ri->ri_font->fontwidth * wantcols;
        !           273:        ri->ri_emuheight = ri->ri_font->fontheight * wantrows;
        !           274:
        !           275:        if (ri->ri_emuwidth > ri->ri_width)
        !           276:                ri->ri_emuwidth = ri->ri_width;
        !           277:
        !           278:        if (ri->ri_emuheight > ri->ri_height)
        !           279:                ri->ri_emuheight = ri->ri_height;
        !           280:
        !           281:        /* Reduce width until aligned on a 32-bit boundary */
        !           282:        while ((ri->ri_emuwidth * bpp & 31) != 0)
        !           283:                ri->ri_emuwidth--;
        !           284:
        !           285: #if NRASOPS_ROTATION > 0
        !           286:        if (ri->ri_flg & RI_ROTATE_CW) {
        !           287:                ri->ri_rows = ri->ri_emuwidth / ri->ri_font->fontwidth;
        !           288:                ri->ri_cols = ri->ri_emuheight / ri->ri_font->fontheight;
        !           289:        } else
        !           290: #endif
        !           291:        {
        !           292:                ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth;
        !           293:                ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight;
        !           294:        }
        !           295:        ri->ri_emustride = ri->ri_emuwidth * bpp >> 3;
        !           296:        ri->ri_delta = ri->ri_stride - ri->ri_emustride;
        !           297:        ri->ri_ccol = 0;
        !           298:        ri->ri_crow = 0;
        !           299:        ri->ri_pelbytes = bpp >> 3;
        !           300:
        !           301:        ri->ri_xscale = (ri->ri_font->fontwidth * bpp) >> 3;
        !           302:        ri->ri_yscale = ri->ri_font->fontheight * ri->ri_stride;
        !           303:        ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride;
        !           304:
        !           305: #ifdef DEBUG
        !           306:        if ((ri->ri_delta & 3) != 0)
        !           307:                panic("rasops_init: ri_delta not aligned on 32-bit boundary");
        !           308: #endif
        !           309:        /* Clear the entire display */
        !           310:        if ((ri->ri_flg & RI_CLEAR) != 0) {
        !           311:                memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
        !           312:                ri->ri_flg &= ~RI_CLEARMARGINS;
        !           313:        }
        !           314:
        !           315:        /* Now centre our window if needs be */
        !           316:        ri->ri_origbits = ri->ri_bits;
        !           317:
        !           318:        if ((ri->ri_flg & RI_CENTER) != 0) {
        !           319:                ri->ri_bits += (((ri->ri_width * bpp >> 3) -
        !           320:                    ri->ri_emustride) >> 1) & ~3;
        !           321:                ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
        !           322:                    ri->ri_stride;
        !           323:
        !           324:                ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
        !           325:                   / ri->ri_stride;
        !           326:                ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
        !           327:                   % ri->ri_stride) * 8 / bpp);
        !           328:        } else
        !           329:                ri->ri_xorigin = ri->ri_yorigin = 0;
        !           330:
        !           331:        /* Clear the margins */
        !           332:        if ((ri->ri_flg & RI_CLEARMARGINS) != 0) {
        !           333:                memset(ri->ri_origbits, 0, ri->ri_bits - ri->ri_origbits);
        !           334:                for (l = 0; l < ri->ri_emuheight; l++)
        !           335:                        memset(ri->ri_bits + ri->ri_emustride +
        !           336:                            l * ri->ri_stride, 0,
        !           337:                            ri->ri_stride - ri->ri_emustride);
        !           338:                memset(ri->ri_bits + ri->ri_emuheight * ri->ri_stride, 0,
        !           339:                    (ri->ri_origbits + ri->ri_height * ri->ri_stride) -
        !           340:                    (ri->ri_bits + ri->ri_emuheight * ri->ri_stride));
        !           341:        }
        !           342:
        !           343:        /*
        !           344:         * Fill in defaults for operations set.  XXX this nukes private
        !           345:         * routines used by accelerated fb drivers.
        !           346:         */
        !           347:        ri->ri_ops.mapchar = rasops_mapchar;
        !           348:        ri->ri_ops.copyrows = rasops_copyrows;
        !           349:        ri->ri_ops.copycols = rasops_copycols;
        !           350:        ri->ri_ops.erasecols = rasops_erasecols;
        !           351:        ri->ri_ops.eraserows = rasops_eraserows;
        !           352:        ri->ri_ops.cursor = rasops_cursor;
        !           353:        ri->ri_ops.unpack_attr = rasops_unpack_attr;
        !           354:        ri->ri_do_cursor = rasops_do_cursor;
        !           355:        ri->ri_updatecursor = NULL;
        !           356:
        !           357:        if (ri->ri_depth < 8 || (ri->ri_flg & RI_FORCEMONO) != 0) {
        !           358:                ri->ri_ops.alloc_attr = rasops_alloc_mattr;
        !           359:                ri->ri_caps = WSSCREEN_UNDERLINE | WSSCREEN_REVERSE;
        !           360:        } else {
        !           361:                ri->ri_ops.alloc_attr = rasops_alloc_cattr;
        !           362:                ri->ri_caps = WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
        !           363:                    WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
        !           364:        }
        !           365:
        !           366:        switch (ri->ri_depth) {
        !           367: #if NRASOPS1 > 0
        !           368:        case 1:
        !           369:                rasops1_init(ri);
        !           370:                break;
        !           371: #endif
        !           372: #if NRASOPS2 > 0
        !           373:        case 2:
        !           374:                rasops2_init(ri);
        !           375:                break;
        !           376: #endif
        !           377: #if NRASOPS4 > 0
        !           378:        case 4:
        !           379:                rasops4_init(ri);
        !           380:                break;
        !           381: #endif
        !           382: #if NRASOPS8 > 0
        !           383:        case 8:
        !           384:                rasops8_init(ri);
        !           385:                break;
        !           386: #endif
        !           387: #if NRASOPS15 > 0 || NRASOPS16 > 0
        !           388:        case 15:
        !           389:        case 16:
        !           390:                rasops15_init(ri);
        !           391:                break;
        !           392: #endif
        !           393: #if NRASOPS24 > 0
        !           394:        case 24:
        !           395:                rasops24_init(ri);
        !           396:                break;
        !           397: #endif
        !           398: #if NRASOPS32 > 0
        !           399:        case 32:
        !           400:                rasops32_init(ri);
        !           401:                break;
        !           402: #endif
        !           403:        default:
        !           404:                ri->ri_flg &= ~RI_CFGDONE;
        !           405:                splx(s);
        !           406:                return (-1);
        !           407:        }
        !           408:
        !           409: #if NRASOPS_ROTATION > 0
        !           410:        if (ri->ri_flg & RI_ROTATE_CW) {
        !           411:                ri->ri_real_ops = ri->ri_ops;
        !           412:                ri->ri_ops.copycols = rasops_copycols_rotated;
        !           413:                ri->ri_ops.copyrows = rasops_copyrows_rotated;
        !           414:                ri->ri_ops.erasecols = rasops_erasecols_rotated;
        !           415:                ri->ri_ops.eraserows = rasops_eraserows_rotated;
        !           416:                ri->ri_ops.putchar = rasops_putchar_rotated;
        !           417:        }
        !           418: #endif
        !           419:
        !           420:        ri->ri_flg |= RI_CFGDONE;
        !           421:        splx(s);
        !           422:        return (0);
        !           423: }
        !           424:
        !           425: /*
        !           426:  * Map a character.
        !           427:  */
        !           428: int
        !           429: rasops_mapchar(cookie, c, cp)
        !           430:        void *cookie;
        !           431:        int c;
        !           432:        u_int *cp;
        !           433: {
        !           434:        struct rasops_info *ri;
        !           435:
        !           436:        ri = (struct rasops_info *)cookie;
        !           437:
        !           438: #ifdef DIAGNOSTIC
        !           439:        if (ri->ri_font == NULL)
        !           440:                panic("rasops_mapchar: no font selected");
        !           441: #endif
        !           442:        if (ri->ri_font->encoding != WSDISPLAY_FONTENC_ISO) {
        !           443:
        !           444:                if ( (c = wsfont_map_unichar(ri->ri_font, c)) < 0) {
        !           445:
        !           446:                        *cp = ' ';
        !           447:                        return (0);
        !           448:
        !           449:                }
        !           450:        }
        !           451:
        !           452:
        !           453:        if (c < ri->ri_font->firstchar) {
        !           454:                *cp = ' ';
        !           455:                return (0);
        !           456:        }
        !           457:
        !           458:        if (c - ri->ri_font->firstchar >= ri->ri_font->numchars) {
        !           459:                *cp = ' ';
        !           460:                return (0);
        !           461:        }
        !           462:
        !           463:        *cp = c;
        !           464:        return (5);
        !           465: }
        !           466:
        !           467: /*
        !           468:  * Allocate a color attribute.
        !           469:  */
        !           470: int
        !           471: rasops_alloc_cattr(cookie, fg, bg, flg, attr)
        !           472:        void *cookie;
        !           473:        int fg, bg, flg;
        !           474:        long *attr;
        !           475: {
        !           476:        int swap;
        !           477:
        !           478: #ifdef RASOPS_CLIPPING
        !           479:        fg &= 7;
        !           480:        bg &= 7;
        !           481: #endif
        !           482:        if ((flg & WSATTR_BLINK) != 0)
        !           483:                return (EINVAL);
        !           484:
        !           485:        if ((flg & WSATTR_WSCOLORS) == 0) {
        !           486:                fg = WSCOL_WHITE;
        !           487:                bg = WSCOL_BLACK;
        !           488:        }
        !           489:
        !           490:        if ((flg & WSATTR_REVERSE) != 0) {
        !           491:                swap = fg;
        !           492:                fg = bg;
        !           493:                bg = swap;
        !           494:        }
        !           495:
        !           496:        if ((flg & WSATTR_HILIT) != 0)
        !           497:                fg += 8;
        !           498:
        !           499:        flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
        !           500:
        !           501:        if (rasops_isgray[fg])
        !           502:                flg |= 2;
        !           503:
        !           504:        if (rasops_isgray[bg])
        !           505:                flg |= 4;
        !           506:
        !           507:        *attr = (bg << 16) | (fg << 24) | flg;
        !           508:        return (0);
        !           509: }
        !           510:
        !           511: /*
        !           512:  * Allocate a mono attribute.
        !           513:  */
        !           514: int
        !           515: rasops_alloc_mattr(cookie, fg, bg, flg, attr)
        !           516:        void *cookie;
        !           517:        int fg, bg, flg;
        !           518:        long *attr;
        !           519: {
        !           520:        int swap;
        !           521:
        !           522:        if ((flg & (WSATTR_BLINK | WSATTR_HILIT | WSATTR_WSCOLORS)) != 0)
        !           523:                return (EINVAL);
        !           524:
        !           525:        fg = 1;
        !           526:        bg = 0;
        !           527:
        !           528:        if ((flg & WSATTR_REVERSE) != 0) {
        !           529:                swap = fg;
        !           530:                fg = bg;
        !           531:                bg = swap;
        !           532:        }
        !           533:
        !           534:        *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6);
        !           535:        return (0);
        !           536: }
        !           537:
        !           538: /*
        !           539:  * Copy rows.
        !           540:  */
        !           541: void
        !           542: rasops_copyrows(cookie, src, dst, num)
        !           543:        void *cookie;
        !           544:        int src, dst, num;
        !           545: {
        !           546:        int32_t *sp, *dp, *srp, *drp;
        !           547:        struct rasops_info *ri;
        !           548:        int n8, n1, cnt, delta;
        !           549:
        !           550:        ri = (struct rasops_info *)cookie;
        !           551:
        !           552: #ifdef RASOPS_CLIPPING
        !           553:        if (dst == src)
        !           554:                return;
        !           555:
        !           556:        if (src < 0) {
        !           557:                num += src;
        !           558:                src = 0;
        !           559:        }
        !           560:
        !           561:        if ((src + num) > ri->ri_rows)
        !           562:                num = ri->ri_rows - src;
        !           563:
        !           564:        if (dst < 0) {
        !           565:                num += dst;
        !           566:                dst = 0;
        !           567:        }
        !           568:
        !           569:        if ((dst + num) > ri->ri_rows)
        !           570:                num = ri->ri_rows - dst;
        !           571:
        !           572:        if (num <= 0)
        !           573:                return;
        !           574: #endif
        !           575:
        !           576:        num *= ri->ri_font->fontheight;
        !           577:        n8 = ri->ri_emustride >> 5;
        !           578:        n1 = (ri->ri_emustride >> 2) & 7;
        !           579:
        !           580:        if (dst < src) {
        !           581:                srp = (int32_t *)(ri->ri_bits + src * ri->ri_yscale);
        !           582:                drp = (int32_t *)(ri->ri_bits + dst * ri->ri_yscale);
        !           583:                delta = ri->ri_stride;
        !           584:        } else {
        !           585:                src = ri->ri_font->fontheight * src + num - 1;
        !           586:                dst = ri->ri_font->fontheight * dst + num - 1;
        !           587:                srp = (int32_t *)(ri->ri_bits + src * ri->ri_stride);
        !           588:                drp = (int32_t *)(ri->ri_bits + dst * ri->ri_stride);
        !           589:                delta = -ri->ri_stride;
        !           590:        }
        !           591:
        !           592:        while (num--) {
        !           593:                dp = drp;
        !           594:                sp = srp;
        !           595:                DELTA(drp, delta, int32_t *);
        !           596:                DELTA(srp, delta, int32_t *);
        !           597:
        !           598:                for (cnt = n8; cnt; cnt--) {
        !           599:                        dp[0] = sp[0];
        !           600:                        dp[1] = sp[1];
        !           601:                        dp[2] = sp[2];
        !           602:                        dp[3] = sp[3];
        !           603:                        dp[4] = sp[4];
        !           604:                        dp[5] = sp[5];
        !           605:                        dp[6] = sp[6];
        !           606:                        dp[7] = sp[7];
        !           607:                        dp += 8;
        !           608:                        sp += 8;
        !           609:                }
        !           610:
        !           611:                for (cnt = n1; cnt; cnt--)
        !           612:                        *dp++ = *sp++;
        !           613:        }
        !           614: }
        !           615:
        !           616: /*
        !           617:  * Copy columns. This is slow, and hard to optimize due to alignment,
        !           618:  * and the fact that we have to copy both left->right and right->left.
        !           619:  * We simply cop-out here and use ovbcopy(), since it handles all of
        !           620:  * these cases anyway.
        !           621:  */
        !           622: void
        !           623: rasops_copycols(cookie, row, src, dst, num)
        !           624:        void *cookie;
        !           625:        int row, src, dst, num;
        !           626: {
        !           627:        struct rasops_info *ri;
        !           628:        u_char *sp, *dp;
        !           629:        int height;
        !           630:
        !           631:        ri = (struct rasops_info *)cookie;
        !           632:
        !           633: #ifdef RASOPS_CLIPPING
        !           634:        if (dst == src)
        !           635:                return;
        !           636:
        !           637:        /* Catches < 0 case too */
        !           638:        if ((unsigned)row >= (unsigned)ri->ri_rows)
        !           639:                return;
        !           640:
        !           641:        if (src < 0) {
        !           642:                num += src;
        !           643:                src = 0;
        !           644:        }
        !           645:
        !           646:        if ((src + num) > ri->ri_cols)
        !           647:                num = ri->ri_cols - src;
        !           648:
        !           649:        if (dst < 0) {
        !           650:                num += dst;
        !           651:                dst = 0;
        !           652:        }
        !           653:
        !           654:        if ((dst + num) > ri->ri_cols)
        !           655:                num = ri->ri_cols - dst;
        !           656:
        !           657:        if (num <= 0)
        !           658:                return;
        !           659: #endif
        !           660:
        !           661:        num *= ri->ri_xscale;
        !           662:        row *= ri->ri_yscale;
        !           663:        height = ri->ri_font->fontheight;
        !           664:
        !           665:        sp = ri->ri_bits + row + src * ri->ri_xscale;
        !           666:        dp = ri->ri_bits + row + dst * ri->ri_xscale;
        !           667:
        !           668: #if NRASOPS_BSWAP > 0
        !           669:        if (ri->ri_flg & RI_BSWAP) {
        !           670:                while (height--) {
        !           671:                        slow_ovbcopy(sp, dp, num);
        !           672:                        dp += ri->ri_stride;
        !           673:                        sp += ri->ri_stride;
        !           674:                }
        !           675:        } else
        !           676: #endif
        !           677:        {
        !           678:                while (height--) {
        !           679:                        ovbcopy(sp, dp, num);
        !           680:                        dp += ri->ri_stride;
        !           681:                        sp += ri->ri_stride;
        !           682:                }
        !           683:        }
        !           684: }
        !           685:
        !           686: /*
        !           687:  * Turn cursor off/on.
        !           688:  */
        !           689: void
        !           690: rasops_cursor(cookie, on, row, col)
        !           691:        void *cookie;
        !           692:        int on, row, col;
        !           693: {
        !           694:        struct rasops_info *ri;
        !           695:
        !           696:        ri = (struct rasops_info *)cookie;
        !           697:
        !           698:        /* Turn old cursor off */
        !           699:        if ((ri->ri_flg & RI_CURSOR) != 0)
        !           700: #ifdef RASOPS_CLIPPING
        !           701:                if ((ri->ri_flg & RI_CURSORCLIP) == 0)
        !           702: #endif
        !           703:                        ri->ri_do_cursor(ri);
        !           704:
        !           705:        /* Select new cursor */
        !           706: #ifdef RASOPS_CLIPPING
        !           707:        ri->ri_flg &= ~RI_CURSORCLIP;
        !           708:
        !           709:        if (row < 0 || row >= ri->ri_rows)
        !           710:                ri->ri_flg |= RI_CURSORCLIP;
        !           711:        else if (col < 0 || col >= ri->ri_cols)
        !           712:                ri->ri_flg |= RI_CURSORCLIP;
        !           713: #endif
        !           714:        ri->ri_crow = row;
        !           715:        ri->ri_ccol = col;
        !           716:
        !           717:        if (ri->ri_updatecursor != NULL)
        !           718:                ri->ri_updatecursor(ri);
        !           719:
        !           720:        if (on) {
        !           721:                ri->ri_flg |= RI_CURSOR;
        !           722: #ifdef RASOPS_CLIPPING
        !           723:                if ((ri->ri_flg & RI_CURSORCLIP) == 0)
        !           724: #endif
        !           725:                        ri->ri_do_cursor(ri);
        !           726:        } else
        !           727:                ri->ri_flg &= ~RI_CURSOR;
        !           728: }
        !           729:
        !           730: /*
        !           731:  * Make the device colormap
        !           732:  */
        !           733: void
        !           734: rasops_init_devcmap(ri)
        !           735:        struct rasops_info *ri;
        !           736: {
        !           737:        int i;
        !           738: #if NRASOPS15 > 0 || NRASOPS16 > 0 || NRASOPS24 > 0 || NRASOPS32 > 0
        !           739:        const u_char *p;
        !           740: #endif
        !           741: #if NRASOPS4 > 0 || NRASOPS15 > 0 || NRASOPS16 > 0 || NRASOPS24 > 0 || NRASOPS32 > 0
        !           742:        int c;
        !           743: #endif
        !           744:
        !           745:        switch (ri->ri_depth) {
        !           746: #if NRASOPS1 > 0
        !           747:        case 1:
        !           748:                ri->ri_devcmap[0] = 0;
        !           749:                for (i = 1; i < 16; i++)
        !           750:                        ri->ri_devcmap[i] = 0xffffffff;
        !           751:                return;
        !           752: #endif
        !           753: #if NRASOPS2 > 0
        !           754:        case 2:
        !           755:                for (i = 1; i < 15; i++)
        !           756:                        ri->ri_devcmap[i] = 0xaaaaaaaa;
        !           757:
        !           758:                ri->ri_devcmap[0] = 0;
        !           759:                ri->ri_devcmap[8] = 0x55555555;
        !           760:                ri->ri_devcmap[15] = 0xffffffff;
        !           761:                return;
        !           762: #endif
        !           763: #if NRASOPS4 > 0
        !           764:        case 4:
        !           765:                for (i = 0; i < 16; i++) {
        !           766:                        c = i | (i << 4);
        !           767:                        ri->ri_devcmap[i] = c | (c<<8) | (c<<16) | (c<<24);
        !           768:                }
        !           769:                return;
        !           770: #endif
        !           771: #if NRASOPS8 > 0
        !           772:        case 8:
        !           773:                for (i = 0; i < 16; i++)
        !           774:                        ri->ri_devcmap[i] = i | (i<<8) | (i<<16) | (i<<24);
        !           775:                return;
        !           776: #endif
        !           777:        default:
        !           778:                break;
        !           779:        }
        !           780:
        !           781: #if NRASOPS15 > 0 || NRASOPS16 > 0 || NRASOPS24 > 0 || NRASOPS32 > 0
        !           782:        p = rasops_cmap;
        !           783:
        !           784:        for (i = 0; i < 16; i++) {
        !           785:                if (ri->ri_rnum <= 8)
        !           786:                        c = (*p >> (8 - ri->ri_rnum)) << ri->ri_rpos;
        !           787:                else
        !           788:                        c = (*p << (ri->ri_rnum - 8)) << ri->ri_rpos;
        !           789:                p++;
        !           790:
        !           791:                if (ri->ri_gnum <= 8)
        !           792:                        c |= (*p >> (8 - ri->ri_gnum)) << ri->ri_gpos;
        !           793:                else
        !           794:                        c |= (*p << (ri->ri_gnum - 8)) << ri->ri_gpos;
        !           795:                p++;
        !           796:
        !           797:                if (ri->ri_bnum <= 8)
        !           798:                        c |= (*p >> (8 - ri->ri_bnum)) << ri->ri_bpos;
        !           799:                else
        !           800:                        c |= (*p << (ri->ri_bnum - 8)) << ri->ri_bpos;
        !           801:                p++;
        !           802:
        !           803:                /* Fill the word for generic routines, which want this */
        !           804:                if (ri->ri_depth == 24)
        !           805:                        c = c | ((c & 0xff) << 24);
        !           806:                else if (ri->ri_depth <= 16)
        !           807:                        c = c | (c << 16);
        !           808:
        !           809:                /* 24bpp does bswap on the fly. {32,16,15}bpp do it here. */
        !           810: #if NRASOPS_BSWAP > 0
        !           811:                if ((ri->ri_flg & RI_BSWAP) == 0)
        !           812:                        ri->ri_devcmap[i] = c;
        !           813:                else if (ri->ri_depth == 32)
        !           814:                        ri->ri_devcmap[i] = swap32(c);
        !           815:                else if (ri->ri_depth == 16 || ri->ri_depth == 15)
        !           816:                        ri->ri_devcmap[i] = swap16(c);
        !           817:                else
        !           818:                        ri->ri_devcmap[i] = c;
        !           819: #else
        !           820:                ri->ri_devcmap[i] = c;
        !           821: #endif
        !           822:        }
        !           823: #endif
        !           824: }
        !           825:
        !           826: /*
        !           827:  * Unpack a rasops attribute
        !           828:  */
        !           829: void
        !           830: rasops_unpack_attr(cookie, attr, fg, bg, underline)
        !           831:        void *cookie;
        !           832:        long attr;
        !           833:        int *fg, *bg, *underline;
        !           834: {
        !           835:        *fg = ((u_int)attr >> 24) & 0xf;
        !           836:        *bg = ((u_int)attr >> 16) & 0xf;
        !           837:        if (underline != NULL)
        !           838:                *underline = (u_int)attr & 1;
        !           839: }
        !           840:
        !           841: /*
        !           842:  * Erase rows
        !           843:  */
        !           844: void
        !           845: rasops_eraserows(cookie, row, num, attr)
        !           846:        void *cookie;
        !           847:        int row, num;
        !           848:        long attr;
        !           849: {
        !           850:        struct rasops_info *ri;
        !           851:        int np, nw, cnt, delta;
        !           852:        int32_t *dp, clr;
        !           853:
        !           854:        ri = (struct rasops_info *)cookie;
        !           855:
        !           856: #ifdef RASOPS_CLIPPING
        !           857:        if (row < 0) {
        !           858:                num += row;
        !           859:                row = 0;
        !           860:        }
        !           861:
        !           862:        if ((row + num) > ri->ri_rows)
        !           863:                num = ri->ri_rows - row;
        !           864:
        !           865:        if (num <= 0)
        !           866:                return;
        !           867: #endif
        !           868:
        !           869:        clr = ri->ri_devcmap[(attr >> 16) & 0xf];
        !           870:
        !           871:        /*
        !           872:         * XXX The wsdisplay_emulops interface seems a little deficient in
        !           873:         * that there is no way to clear the *entire* screen. We provide a
        !           874:         * workaround here: if the entire console area is being cleared, and
        !           875:         * the RI_FULLCLEAR flag is set, clear the entire display.
        !           876:         */
        !           877:        if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
        !           878:                np = ri->ri_stride >> 5;
        !           879:                nw = (ri->ri_stride >> 2) & 7;
        !           880:                num = ri->ri_height;
        !           881:                dp = (int32_t *)ri->ri_origbits;
        !           882:                delta = 0;
        !           883:        } else {
        !           884:                np = ri->ri_emustride >> 5;
        !           885:                nw = (ri->ri_emustride >> 2) & 7;
        !           886:                num *= ri->ri_font->fontheight;
        !           887:                dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
        !           888:                delta = ri->ri_delta;
        !           889:        }
        !           890:
        !           891:        while (num--) {
        !           892:                for (cnt = np; cnt; cnt--) {
        !           893:                        dp[0] = clr;
        !           894:                        dp[1] = clr;
        !           895:                        dp[2] = clr;
        !           896:                        dp[3] = clr;
        !           897:                        dp[4] = clr;
        !           898:                        dp[5] = clr;
        !           899:                        dp[6] = clr;
        !           900:                        dp[7] = clr;
        !           901:                        dp += 8;
        !           902:                }
        !           903:
        !           904:                for (cnt = nw; cnt; cnt--) {
        !           905:                        *(int32_t *)dp = clr;
        !           906:                        DELTA(dp, 4, int32_t *);
        !           907:                }
        !           908:
        !           909:                DELTA(dp, delta, int32_t *);
        !           910:        }
        !           911: }
        !           912:
        !           913: /*
        !           914:  * Actually turn the cursor on or off. This does the dirty work for
        !           915:  * rasops_cursor().
        !           916:  */
        !           917: void
        !           918: rasops_do_cursor(ri)
        !           919:        struct rasops_info *ri;
        !           920: {
        !           921:        int full1, height, cnt, slop1, slop2, row, col;
        !           922:        u_char *dp, *rp;
        !           923:
        !           924: #if NRASOPS_ROTATION > 0
        !           925:        if (ri->ri_flg & RI_ROTATE_CW) {
        !           926:                /* Rotate rows/columns */
        !           927:                row = ri->ri_ccol;
        !           928:                col = ri->ri_rows - ri->ri_crow - 1;
        !           929:        } else
        !           930: #endif
        !           931:        {
        !           932:                row = ri->ri_crow;
        !           933:                col = ri->ri_ccol;
        !           934:        }
        !           935:
        !           936:        rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
        !           937:        height = ri->ri_font->fontheight;
        !           938:        slop1 = (4 - ((long)rp & 3)) & 3;
        !           939:
        !           940:        if (slop1 > ri->ri_xscale)
        !           941:                slop1 = ri->ri_xscale;
        !           942:
        !           943:        slop2 = (ri->ri_xscale - slop1) & 3;
        !           944:        full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
        !           945:
        !           946:        if ((slop1 | slop2) == 0) {
        !           947:                /* A common case */
        !           948:                while (height--) {
        !           949:                        dp = rp;
        !           950:                        rp += ri->ri_stride;
        !           951:
        !           952:                        for (cnt = full1; cnt; cnt--) {
        !           953:                                *(int32_t *)dp ^= ~0;
        !           954:                                dp += 4;
        !           955:                        }
        !           956:                }
        !           957:        } else {
        !           958:                /* XXX this is stupid.. use masks instead */
        !           959:                while (height--) {
        !           960:                        dp = rp;
        !           961:                        rp += ri->ri_stride;
        !           962:
        !           963:                        if (slop1 & 1)
        !           964:                                *dp++ ^= ~0;
        !           965:
        !           966:                        if (slop1 & 2) {
        !           967:                                *(int16_t *)dp ^= ~0;
        !           968:                                dp += 2;
        !           969:                        }
        !           970:
        !           971:                        for (cnt = full1; cnt; cnt--) {
        !           972:                                *(int32_t *)dp ^= ~0;
        !           973:                                dp += 4;
        !           974:                        }
        !           975:
        !           976:                        if (slop2 & 1)
        !           977:                                *dp++ ^= ~0;
        !           978:
        !           979:                        if (slop2 & 2)
        !           980:                                *(int16_t *)dp ^= ~0;
        !           981:                }
        !           982:        }
        !           983: }
        !           984:
        !           985: /*
        !           986:  * Erase columns.
        !           987:  */
        !           988: void
        !           989: rasops_erasecols(cookie, row, col, num, attr)
        !           990:        void *cookie;
        !           991:        int row, col, num;
        !           992:        long attr;
        !           993: {
        !           994:        int n8, height, cnt, slop1, slop2, clr;
        !           995:        struct rasops_info *ri;
        !           996:        int32_t *rp, *dp;
        !           997:
        !           998:        ri = (struct rasops_info *)cookie;
        !           999:
        !          1000: #ifdef RASOPS_CLIPPING
        !          1001:        if ((unsigned)row >= (unsigned)ri->ri_rows)
        !          1002:                return;
        !          1003:
        !          1004:        if (col < 0) {
        !          1005:                num += col;
        !          1006:                col = 0;
        !          1007:        }
        !          1008:
        !          1009:        if ((col + num) > ri->ri_cols)
        !          1010:                num = ri->ri_cols - col;
        !          1011:
        !          1012:        if (num <= 0)
        !          1013:                return;
        !          1014: #endif
        !          1015:
        !          1016:        num = num * ri->ri_xscale;
        !          1017:        rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
        !          1018:        height = ri->ri_font->fontheight;
        !          1019:        clr = ri->ri_devcmap[(attr >> 16) & 0xf];
        !          1020:
        !          1021:        /* Don't bother using the full loop for <= 32 pels */
        !          1022:        if (num <= 32) {
        !          1023:                if (((num | ri->ri_xscale) & 3) == 0) {
        !          1024:                        /* Word aligned blt */
        !          1025:                        num >>= 2;
        !          1026:
        !          1027:                        while (height--) {
        !          1028:                                dp = rp;
        !          1029:                                DELTA(rp, ri->ri_stride, int32_t *);
        !          1030:
        !          1031:                                for (cnt = num; cnt; cnt--)
        !          1032:                                        *dp++ = clr;
        !          1033:                        }
        !          1034:                } else if (((num | ri->ri_xscale) & 1) == 0) {
        !          1035:                        /*
        !          1036:                         * Halfword aligned blt. This is needed so the
        !          1037:                         * 15/16 bit ops can use this function.
        !          1038:                         */
        !          1039:                        num >>= 1;
        !          1040:
        !          1041:                        while (height--) {
        !          1042:                                dp = rp;
        !          1043:                                DELTA(rp, ri->ri_stride, int32_t *);
        !          1044:
        !          1045:                                for (cnt = num; cnt; cnt--) {
        !          1046:                                        *(int16_t *)dp = clr;
        !          1047:                                        DELTA(dp, 2, int32_t *);
        !          1048:                                }
        !          1049:                        }
        !          1050:                } else {
        !          1051:                        while (height--) {
        !          1052:                                dp = rp;
        !          1053:                                DELTA(rp, ri->ri_stride, int32_t *);
        !          1054:
        !          1055:                                for (cnt = num; cnt; cnt--) {
        !          1056:                                        *(u_char *)dp = clr;
        !          1057:                                        DELTA(dp, 1, int32_t *);
        !          1058:                                }
        !          1059:                        }
        !          1060:                }
        !          1061:
        !          1062:                return;
        !          1063:        }
        !          1064:
        !          1065:        slop1 = (4 - ((long)rp & 3)) & 3;
        !          1066:        slop2 = (num - slop1) & 3;
        !          1067:        num -= slop1 + slop2;
        !          1068:        n8 = num >> 5;
        !          1069:        num = (num >> 2) & 7;
        !          1070:
        !          1071:        while (height--) {
        !          1072:                dp = rp;
        !          1073:                DELTA(rp, ri->ri_stride, int32_t *);
        !          1074:
        !          1075:                /* Align span to 4 bytes */
        !          1076:                if (slop1 & 1) {
        !          1077:                        *(u_char *)dp = clr;
        !          1078:                        DELTA(dp, 1, int32_t *);
        !          1079:                }
        !          1080:
        !          1081:                if (slop1 & 2) {
        !          1082:                        *(int16_t *)dp = clr;
        !          1083:                        DELTA(dp, 2, int32_t *);
        !          1084:                }
        !          1085:
        !          1086:                /* Write 32 bytes per loop */
        !          1087:                for (cnt = n8; cnt; cnt--) {
        !          1088:                        dp[0] = clr;
        !          1089:                        dp[1] = clr;
        !          1090:                        dp[2] = clr;
        !          1091:                        dp[3] = clr;
        !          1092:                        dp[4] = clr;
        !          1093:                        dp[5] = clr;
        !          1094:                        dp[6] = clr;
        !          1095:                        dp[7] = clr;
        !          1096:                        dp += 8;
        !          1097:                }
        !          1098:
        !          1099:                /* Write 4 bytes per loop */
        !          1100:                for (cnt = num; cnt; cnt--)
        !          1101:                        *dp++ = clr;
        !          1102:
        !          1103:                /* Write unaligned trailing slop */
        !          1104:                if (slop2 & 1) {
        !          1105:                        *(u_char *)dp = clr;
        !          1106:                        DELTA(dp, 1, int32_t *);
        !          1107:                }
        !          1108:
        !          1109:                if (slop2 & 2)
        !          1110:                        *(int16_t *)dp = clr;
        !          1111:        }
        !          1112: }
        !          1113:
        !          1114: #if NRASOPS_ROTATION > 0
        !          1115: /*
        !          1116:  * Quarter clockwise rotation routines (originally intended for the
        !          1117:  * built-in Zaurus C3x00 display in 16bpp).
        !          1118:  */
        !          1119:
        !          1120: #include <sys/malloc.h>
        !          1121:
        !          1122: void
        !          1123: rasops_rotate_font(int *cookie)
        !          1124: {
        !          1125:        struct rotatedfont *f;
        !          1126:        int ncookie;
        !          1127:
        !          1128:        SLIST_FOREACH(f, &rotatedfonts, rf_next) {
        !          1129:                if (f->rf_cookie == *cookie) {
        !          1130:                        *cookie = f->rf_rotated;
        !          1131:                        return;
        !          1132:                }
        !          1133:        }
        !          1134:
        !          1135:        /*
        !          1136:         * We did not find a rotated version of this font. Ask the wsfont
        !          1137:         * code to compute one for us.
        !          1138:         */
        !          1139:
        !          1140:        f = malloc(sizeof(struct rotatedfont), M_DEVBUF, M_WAITOK);
        !          1141:        if (f == NULL)
        !          1142:                return;
        !          1143:
        !          1144:        if ((ncookie = wsfont_rotate(*cookie)) == -1)
        !          1145:                return;
        !          1146:
        !          1147:        f->rf_cookie = *cookie;
        !          1148:        f->rf_rotated = ncookie;
        !          1149:        SLIST_INSERT_HEAD(&rotatedfonts, f, rf_next);
        !          1150:
        !          1151:        *cookie = ncookie;
        !          1152: }
        !          1153:
        !          1154: void
        !          1155: rasops_copychar(cookie, srcrow, dstrow, srccol, dstcol)
        !          1156:        void *cookie;
        !          1157:        int srcrow, dstrow, srccol, dstcol;
        !          1158: {
        !          1159:        struct rasops_info *ri;
        !          1160:        u_char *sp, *dp;
        !          1161:        int height;
        !          1162:        int r_srcrow, r_dstrow, r_srccol, r_dstcol;
        !          1163:
        !          1164:        ri = (struct rasops_info *)cookie;
        !          1165:
        !          1166:        r_srcrow = srccol;
        !          1167:        r_dstrow = dstcol;
        !          1168:        r_srccol = ri->ri_rows - srcrow - 1;
        !          1169:        r_dstcol = ri->ri_rows - dstrow - 1;
        !          1170:
        !          1171:        r_srcrow *= ri->ri_yscale;
        !          1172:        r_dstrow *= ri->ri_yscale;
        !          1173:        height = ri->ri_font->fontheight;
        !          1174:
        !          1175:        sp = ri->ri_bits + r_srcrow + r_srccol * ri->ri_xscale;
        !          1176:        dp = ri->ri_bits + r_dstrow + r_dstcol * ri->ri_xscale;
        !          1177:
        !          1178: #if NRASOPS_BSWAP > 0
        !          1179:        if (ri->ri_flg & RI_BSWAP) {
        !          1180:                while (height--) {
        !          1181:                        slow_ovbcopy(sp, dp, ri->ri_xscale);
        !          1182:                        dp += ri->ri_stride;
        !          1183:                        sp += ri->ri_stride;
        !          1184:                }
        !          1185:        } else
        !          1186: #endif
        !          1187:        {
        !          1188:                while (height--) {
        !          1189:                        ovbcopy(sp, dp, ri->ri_xscale);
        !          1190:                        dp += ri->ri_stride;
        !          1191:                        sp += ri->ri_stride;
        !          1192:                }
        !          1193:        }
        !          1194: }
        !          1195:
        !          1196: void
        !          1197: rasops_putchar_rotated(cookie, row, col, uc, attr)
        !          1198:        void *cookie;
        !          1199:        int row, col;
        !          1200:        u_int uc;
        !          1201:        long attr;
        !          1202: {
        !          1203:        struct rasops_info *ri;
        !          1204:        u_char *rp;
        !          1205:        int height;
        !          1206:
        !          1207:        ri = (struct rasops_info *)cookie;
        !          1208:
        !          1209:        /* Do rotated char sans (side)underline */
        !          1210:        ri->ri_real_ops.putchar(cookie, col, ri->ri_rows - row - 1, uc,
        !          1211:            attr & ~1);
        !          1212:
        !          1213:        /* Do rotated underline */
        !          1214:        rp = ri->ri_bits + col * ri->ri_yscale + (ri->ri_rows - row - 1) *
        !          1215:            ri->ri_xscale;
        !          1216:        height = ri->ri_font->fontheight;
        !          1217:
        !          1218:        /* XXX this assumes 16-bit color depth */
        !          1219:        if ((attr & 1) != 0) {
        !          1220:                int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
        !          1221:
        !          1222:                while (height--) {
        !          1223:                        *(int16_t *)rp = c;
        !          1224:                        rp += ri->ri_stride;
        !          1225:                }
        !          1226:        }
        !          1227: }
        !          1228:
        !          1229: void
        !          1230: rasops_erasecols_rotated(cookie, row, col, num, attr)
        !          1231:        void *cookie;
        !          1232:        int row, col, num;
        !          1233:        long attr;
        !          1234: {
        !          1235:        struct rasops_info *ri;
        !          1236:        int i;
        !          1237:
        !          1238:        ri = (struct rasops_info *)cookie;
        !          1239:
        !          1240:        for (i = col; i < col + num; i++)
        !          1241:                ri->ri_ops.putchar(cookie, row, i, ' ', attr);
        !          1242: }
        !          1243:
        !          1244: /* XXX: these could likely be optimised somewhat. */
        !          1245: void
        !          1246: rasops_copyrows_rotated(cookie, src, dst, num)
        !          1247:        void *cookie;
        !          1248:        int src, dst, num;
        !          1249: {
        !          1250:        struct rasops_info *ri = (struct rasops_info *)cookie;
        !          1251:        int col, roff;
        !          1252:
        !          1253:        if (src > dst)
        !          1254:                for (roff = 0; roff < num; roff++)
        !          1255:                        for (col = 0; col < ri->ri_cols; col++)
        !          1256:                                rasops_copychar(cookie, src + roff, dst + roff,
        !          1257:                                    col, col);
        !          1258:        else
        !          1259:                for (roff = num - 1; roff >= 0; roff--)
        !          1260:                        for (col = 0; col < ri->ri_cols; col++)
        !          1261:                                rasops_copychar(cookie, src + roff, dst + roff,
        !          1262:                                    col, col);
        !          1263: }
        !          1264:
        !          1265: void
        !          1266: rasops_copycols_rotated(cookie, row, src, dst, num)
        !          1267:        void *cookie;
        !          1268:        int row, src, dst, num;
        !          1269: {
        !          1270:        int coff;
        !          1271:
        !          1272:        if (src > dst)
        !          1273:                for (coff = 0; coff < num; coff++)
        !          1274:                        rasops_copychar(cookie, row, row, src + coff, dst + coff);
        !          1275:        else
        !          1276:                for (coff = num - 1; coff >= 0; coff--)
        !          1277:                        rasops_copychar(cookie, row, row, src + coff, dst + coff);
        !          1278: }
        !          1279:
        !          1280: void
        !          1281: rasops_eraserows_rotated(cookie, row, num, attr)
        !          1282:        void *cookie;
        !          1283:        int row, num;
        !          1284:        long attr;
        !          1285: {
        !          1286:        struct rasops_info *ri;
        !          1287:        int col, rn;
        !          1288:
        !          1289:        ri = (struct rasops_info *)cookie;
        !          1290:
        !          1291:        for (rn = row; rn < row + num; rn++)
        !          1292:                for (col = 0; col < ri->ri_cols; col++)
        !          1293:                        ri->ri_ops.putchar(cookie, rn, col, ' ', attr);
        !          1294: }
        !          1295: #endif /* NRASOPS_ROTATION */
        !          1296:
        !          1297: #if NRASOPS_BSWAP > 0
        !          1298: /*
        !          1299:  * Strictly byte-only ovbcopy() version, to be used with RI_BSWAP, as the
        !          1300:  * regular ovbcopy() may want to optimize things by doing larger-than-byte
        !          1301:  * reads or write. This may confuse things if src and dst have different
        !          1302:  * alignments.
        !          1303:  */
        !          1304: void
        !          1305: slow_ovbcopy(void *s, void *d, size_t len)
        !          1306: {
        !          1307:        u_int8_t *src = s;
        !          1308:        u_int8_t *dst = d;
        !          1309:
        !          1310:        if ((vaddr_t)dst <= (vaddr_t)src) {
        !          1311:                while (len-- != 0)
        !          1312:                        *dst++ = *src++;
        !          1313:        } else {
        !          1314:                src += len;
        !          1315:                dst += len;
        !          1316:                if (len != 0)
        !          1317:                        while (--len != 0)
        !          1318:                                *--dst = *--src;
        !          1319:        }
        !          1320: }
        !          1321: #endif /* NRASOPS_BSWAP */

CVSweb