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