[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

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