Initial import of 'rasops', the new raster operations set for wscons/rcons.
This commit is contained in:
parent
246f73e1a0
commit
14d2ed835e
7
sys/dev/rasops/Makefile
Normal file
7
sys/dev/rasops/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $NetBSD: Makefile,v 1.1 1999/04/13 00:17:57 ad Exp $
|
||||
|
||||
INCSDIR= /usr/include/dev/rasops
|
||||
|
||||
INCS= rasops.h
|
||||
|
||||
.include <bsd.kinc.mk>
|
21
sys/dev/rasops/README
Normal file
21
sys/dev/rasops/README
Normal file
@ -0,0 +1,21 @@
|
||||
$NetBSD: README,v 1.1 1999/04/13 00:17:57 ad Exp $
|
||||
|
||||
This directory contains 'rasops', a set of raster operations intended to
|
||||
replace the dev/rcons/raster stuff for both wscons and rcons. It yields
|
||||
significantly improved performance, supports multiple depths and color.
|
||||
|
||||
The stamp_mutex used by some of the colordepths is not fully atomic. It's
|
||||
designed to stop stamp corruption in the event that text is printed at
|
||||
interrupt time. Even if it fails, >99% of the time text will be white on
|
||||
black, so it doesn't really matter. Going to splhigh for each character is
|
||||
a Bad Thing.
|
||||
|
||||
Status of the various depths. Feel free to complete/test:
|
||||
|
||||
8 tested, complete
|
||||
15/16 untested, complete (endainness issues exist?)
|
||||
32 untested, complete (endainness issues exist?)
|
||||
1 untested, incomplete for non 8,16 pel fonts
|
||||
24 untested, incomplete, assumes RGB order
|
||||
|
||||
- Andy Doran <ad@NetBSD.org>, April 1999
|
11
sys/dev/rasops/files.rasops
Normal file
11
sys/dev/rasops/files.rasops
Normal file
@ -0,0 +1,11 @@
|
||||
# $NetBSD: files.rasops,v 1.1 1999/04/13 00:17:58 ad Exp $
|
||||
|
||||
file dev/rasops/rasops.c rasterconsole
|
||||
file dev/rasops/rasops1.c rasterconsole
|
||||
file dev/rasops/rasops8.c rasterconsole
|
||||
file dev/rasops/rasops15.c rasterconsole
|
||||
file dev/rasops/rasops24.c rasterconsole
|
||||
file dev/rasops/rasops32.c rasterconsole
|
||||
|
||||
defopt opt_rasops.h RASOPS1 RASOPS8 RASOPS15 RASOPS16 RASOPS24 RASOPS32
|
||||
RASOPS_CLIPPING
|
600
sys/dev/rasops/rasops.c
Normal file
600
sys/dev/rasops/rasops.c
Normal file
@ -0,0 +1,600 @@
|
||||
/* $NetBSD: rasops.c,v 1.1 1999/04/13 00:17:58 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Andy Doran <ad@NetBSD.org>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.1 1999/04/13 00:17:58 ad Exp $");
|
||||
|
||||
#include "opt_rasops.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wsfont/wsfont.h>
|
||||
#include <dev/rasops/rasops.h>
|
||||
|
||||
/* ANSI colormap (R,G,B). Upper 8 are high-intensity */
|
||||
u_char rasops_cmap[256*3] = {
|
||||
0x00, 0x00, 0x00, /* black */
|
||||
0x7f, 0x00, 0x00, /* red */
|
||||
0x00, 0x7f, 0x00, /* green */
|
||||
0x7f, 0x7f, 0x00, /* brown */
|
||||
0x00, 0x00, 0x7f, /* blue */
|
||||
0x7f, 0x00, 0x7f, /* magenta */
|
||||
0x00, 0x7f, 0x7f, /* cyan */
|
||||
0xc7, 0xc7, 0xc7, /* white - XXX too dim? */
|
||||
|
||||
0x7f, 0x7f, 0x7f, /* black */
|
||||
0xff, 0x00, 0x00, /* red */
|
||||
0x00, 0xff, 0x00, /* green */
|
||||
0xff, 0xff, 0x00, /* brown */
|
||||
0x00, 0x00, 0xff, /* blue */
|
||||
0xff, 0x00, 0xff, /* magenta */
|
||||
0x00, 0xff, 0xff, /* cyan */
|
||||
0xff, 0xff, 0xff, /* white */
|
||||
};
|
||||
|
||||
/* True if color is gray */
|
||||
u_char rasops_isgray[16] = {
|
||||
1, 0, 0, 0,
|
||||
0, 0, 0, 1,
|
||||
1, 0, 0, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
/* Common functions */
|
||||
static void rasops_copycols __P((void *, int, int, int, int));
|
||||
static void rasops_copyrows __P((void *, int, int, int));
|
||||
static int rasops_mapchar __P((void *, int, u_int *));
|
||||
static void rasops_cursor __P((void *, int, int, int));
|
||||
static int rasops_alloc_cattr __P((void *, int, int, int, long *));
|
||||
static int rasops_alloc_mattr __P((void *, int, int, int, long *));
|
||||
|
||||
/* Per-depth initalization functions */
|
||||
void rasops1_init __P((struct rasops_info *));
|
||||
void rasops8_init __P((struct rasops_info *));
|
||||
void rasops15_init __P((struct rasops_info *));
|
||||
void rasops24_init __P((struct rasops_info *));
|
||||
void rasops32_init __P((struct rasops_info *));
|
||||
|
||||
/*
|
||||
* Initalize a 'rasops_info' descriptor.
|
||||
*/
|
||||
int
|
||||
rasops_init(ri, wantrows, wantcols, clear, center)
|
||||
struct rasops_info *ri;
|
||||
int wantrows, wantcols, clear, center;
|
||||
{
|
||||
|
||||
/* Select a font if the caller doesn't care */
|
||||
if (ri->ri_font == NULL) {
|
||||
int cookie;
|
||||
|
||||
wsfont_init();
|
||||
|
||||
/* Want 8 pixel wide, don't care about aestethics */
|
||||
if ((cookie = wsfont_find(NULL, 8, 0, 0)) < 0)
|
||||
cookie = wsfont_find(NULL, 0, 0, 0);
|
||||
|
||||
if (cookie < 0) {
|
||||
printf("rasops_init: font table is empty\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (wsfont_lock(cookie, &ri->ri_font,
|
||||
WSFONT_LITTLE, WSFONT_LITTLE) < 0) {
|
||||
printf("rasops_init: couldn't lock font\n");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* This should never happen in reality... */
|
||||
#ifdef DEBUG
|
||||
if ((int)ri->ri_bits & 3) {
|
||||
printf("rasops_init: bits not aligned on 32-bit boundary\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((int)ri->ri_stride & 3) {
|
||||
printf("rasops_init: stride not aligned on 32-bit boundary\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ri->ri_font->fontwidth > 32) {
|
||||
printf("rasops_init: fontwidth > 32\n");
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fix color palette. We need this for the cursor to work. */
|
||||
rasops_cmap[255*3+0] = 0xff;
|
||||
rasops_cmap[255*3+1] = 0xff;
|
||||
rasops_cmap[255*3+2] = 0xff;
|
||||
|
||||
/* Don't care if the caller wants a hideously small console */
|
||||
if (wantrows < 10)
|
||||
wantrows = 5000;
|
||||
|
||||
if (wantcols < 20)
|
||||
wantcols = 5000;
|
||||
|
||||
/* Now constrain what they get */
|
||||
ri->ri_emuwidth = ri->ri_font->fontwidth * wantcols;
|
||||
ri->ri_emuheight = ri->ri_font->fontheight * wantrows;
|
||||
|
||||
if (ri->ri_emuwidth > ri->ri_width)
|
||||
ri->ri_emuwidth = ri->ri_width;
|
||||
|
||||
if (ri->ri_emuheight > ri->ri_height)
|
||||
ri->ri_emuheight = ri->ri_height;
|
||||
|
||||
/* Reduce width until aligned on a 32-bit boundary */
|
||||
while ((ri->ri_emuwidth*ri->ri_depth & 31) != 0)
|
||||
ri->ri_emuwidth--;
|
||||
|
||||
ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth;
|
||||
ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight;
|
||||
ri->ri_emustride = ri->ri_emuwidth * ri->ri_depth >> 3;
|
||||
ri->ri_delta = ri->ri_stride - ri->ri_emustride;
|
||||
ri->ri_ccol = 0;
|
||||
ri->ri_crow = 0;
|
||||
ri->ri_pelbytes = ri->ri_depth >> 3;
|
||||
|
||||
ri->ri_xscale = (ri->ri_font->fontwidth * ri->ri_depth) >> 3;
|
||||
ri->ri_yscale = ri->ri_font->fontheight * ri->ri_stride;
|
||||
ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ri->ri_delta & 3)
|
||||
panic("rasops_init: delta isn't aligned on 32-bit boundary!");
|
||||
#endif
|
||||
/* Clear the entire display */
|
||||
if (clear)
|
||||
bzero(ri->ri_bits, ri->ri_stride * ri->ri_height);
|
||||
|
||||
/* Now centre our window if needs be */
|
||||
ri->ri_origbits = ri->ri_bits;
|
||||
|
||||
if (center) {
|
||||
ri->ri_bits += ((ri->ri_stride - ri->ri_emustride) >> 1) & ~3;
|
||||
ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
|
||||
ri->ri_stride;
|
||||
}
|
||||
|
||||
/* Fill in defaults for operations set */
|
||||
ri->ri_ops.mapchar = rasops_mapchar;
|
||||
ri->ri_ops.copyrows = rasops_copyrows;
|
||||
ri->ri_ops.copycols = rasops_copycols;
|
||||
ri->ri_ops.cursor = rasops_cursor;
|
||||
|
||||
if (ri->ri_depth == 1 || ri->ri_forcemono)
|
||||
ri->ri_ops.alloc_attr = rasops_alloc_mattr;
|
||||
else
|
||||
ri->ri_ops.alloc_attr = rasops_alloc_cattr;
|
||||
|
||||
switch (ri->ri_depth) {
|
||||
#ifdef RASOPS1
|
||||
case 1:
|
||||
rasops1_init(ri);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef RASOPS8
|
||||
case 8:
|
||||
rasops8_init(ri);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(RASOPS15) || defined(RASOPS16)
|
||||
case 15:
|
||||
case 16:
|
||||
rasops15_init(ri);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef RASOPS24
|
||||
case 24:
|
||||
rasops24_init(ri);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef RASOPS24
|
||||
case 32:
|
||||
rasops32_init(ri);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ri->ri_flg = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ri->ri_flg = RASOPS_INITTED;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Map a character.
|
||||
*/
|
||||
static int
|
||||
rasops_mapchar(cookie, c, cp)
|
||||
void *cookie;
|
||||
int c;
|
||||
u_int *cp;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
if (c < ri->ri_font->firstchar) {
|
||||
*cp = ' ';
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (c - ri->ri_font->firstchar >= ri->ri_font->numchars) {
|
||||
*cp = ' ';
|
||||
return (0);
|
||||
}
|
||||
|
||||
*cp = c;
|
||||
return (5);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate a color attribute.
|
||||
*/
|
||||
static int
|
||||
rasops_alloc_cattr(cookie, fg, bg, flg, attr)
|
||||
void *cookie;
|
||||
int fg, bg, flg;
|
||||
long *attr;
|
||||
{
|
||||
int swap;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
fg &= 7;
|
||||
bg &= 7;
|
||||
flg &= 255;
|
||||
#endif
|
||||
if (flg & WSATTR_BLINK)
|
||||
return (EINVAL);
|
||||
|
||||
if (flg & WSATTR_REVERSE) {
|
||||
swap = fg;
|
||||
fg = bg;
|
||||
bg = swap;
|
||||
}
|
||||
|
||||
if (flg & WSATTR_HILIT)
|
||||
fg += 8;
|
||||
|
||||
flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
|
||||
|
||||
if (rasops_isgray[fg])
|
||||
flg |= 2;
|
||||
|
||||
if (rasops_isgray[bg])
|
||||
flg |= 4;
|
||||
|
||||
*attr = (bg << 16) | (fg << 24) | flg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate a mono attribute.
|
||||
*/
|
||||
static int
|
||||
rasops_alloc_mattr(cookie, fg, bg, flg, attr)
|
||||
void *cookie;
|
||||
int fg, bg, flg;
|
||||
long *attr;
|
||||
{
|
||||
int swap;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
flg &= 255;
|
||||
#endif
|
||||
fg = fg ? 1 : 0;
|
||||
bg = bg ? 1 : 0;
|
||||
|
||||
if (flg & WSATTR_BLINK)
|
||||
return (EINVAL);
|
||||
|
||||
if (!(flg & WSATTR_REVERSE) ^ !(flg & WSATTR_HILIT)) {
|
||||
swap = fg;
|
||||
fg = bg;
|
||||
bg = swap;
|
||||
}
|
||||
|
||||
*attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy rows.
|
||||
*/
|
||||
static void
|
||||
rasops_copyrows(cookie, src, dst, num)
|
||||
void *cookie;
|
||||
int src, dst, num;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *sp, *dp, *srp, *drp;
|
||||
int n8, n1, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (dst == src)
|
||||
return;
|
||||
|
||||
if (src < 0) {
|
||||
num += src;
|
||||
src = 0;
|
||||
}
|
||||
|
||||
if ((src + num) > ri->ri_rows)
|
||||
num = ri->ri_rows - src;
|
||||
|
||||
if (dst < 0) {
|
||||
num += dst;
|
||||
dst = 0;
|
||||
}
|
||||
|
||||
if ((dst + num) > ri->ri_rows)
|
||||
num = ri->ri_rows - dst;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num *= ri->ri_font->fontheight;
|
||||
n8 = ri->ri_emustride >> 5;
|
||||
n1 = (ri->ri_emustride >> 2) & 7;
|
||||
|
||||
if (dst < src) {
|
||||
sp = (int32_t *)(ri->ri_bits + src * ri->ri_yscale);
|
||||
dp = (int32_t *)(ri->ri_bits + dst * ri->ri_yscale);
|
||||
|
||||
while (num--) {
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = sp[0];
|
||||
dp[1] = sp[1];
|
||||
dp[2] = sp[2];
|
||||
dp[3] = sp[3];
|
||||
dp[4] = sp[4];
|
||||
dp[5] = sp[5];
|
||||
dp[6] = sp[6];
|
||||
dp[7] = sp[7];
|
||||
dp += 8;
|
||||
sp += 8;
|
||||
}
|
||||
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = *sp++;
|
||||
|
||||
DELTA(dp, ri->ri_delta, int32_t *);
|
||||
DELTA(sp, ri->ri_delta, int32_t *);
|
||||
}
|
||||
} else {
|
||||
src = ri->ri_font->fontheight * src + num - 1;
|
||||
dst = ri->ri_font->fontheight * dst + num - 1;
|
||||
|
||||
srp = (int32_t *)(ri->ri_bits + src * ri->ri_stride);
|
||||
drp = (int32_t *)(ri->ri_bits + dst * ri->ri_stride);
|
||||
|
||||
while (num--) {
|
||||
dp = drp;
|
||||
sp = srp;
|
||||
DELTA(srp, -ri->ri_stride, int32_t *);
|
||||
DELTA(drp, -ri->ri_stride, int32_t *);
|
||||
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = sp[0];
|
||||
dp[1] = sp[1];
|
||||
dp[2] = sp[2];
|
||||
dp[3] = sp[3];
|
||||
dp[4] = sp[4];
|
||||
dp[5] = sp[5];
|
||||
dp[6] = sp[6];
|
||||
dp[7] = sp[7];
|
||||
dp += 8;
|
||||
sp += 8;
|
||||
}
|
||||
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy columns. This is slow, and hard to optimize due to alignment,
|
||||
* and the fact that we have to copy both left->right and right->left.
|
||||
* We simply cop-out here and use bcopy(), since it handles all of
|
||||
* these cases anyway.
|
||||
*/
|
||||
static void
|
||||
rasops_copycols(cookie, row, src, dst, num)
|
||||
void *cookie;
|
||||
int row, src, dst, num;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
u_char *sp, *dp;
|
||||
int height;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (dst == src)
|
||||
return;
|
||||
|
||||
if (row < 0 || row >= ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (src < 0) {
|
||||
num += src;
|
||||
src = 0;
|
||||
}
|
||||
|
||||
if ((src + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - src;
|
||||
|
||||
if (dst < 0) {
|
||||
num += dst;
|
||||
dst = 0;
|
||||
}
|
||||
|
||||
if ((dst + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - dst;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num *= ri->ri_xscale;
|
||||
row *= ri->ri_yscale;
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
sp = ri->ri_bits + row + src * ri->ri_xscale;
|
||||
dp = ri->ri_bits + row + dst * ri->ri_xscale;
|
||||
|
||||
while (height--) {
|
||||
bcopy(sp, dp, num);
|
||||
dp += ri->ri_stride;
|
||||
sp += ri->ri_stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Turn cursor off/on.
|
||||
*/
|
||||
static void
|
||||
rasops_cursor(cookie, on, row, col)
|
||||
void *cookie;
|
||||
int on, row, col;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
/* Turn old cursor off */
|
||||
if (ri->ri_flg & RASOPS_CURSOR)
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (!(ri->ri_flg & RASOPS_CURSOR_CLIPPED))
|
||||
#endif
|
||||
ri->ri_do_cursor(ri);
|
||||
|
||||
/* Select new cursor */
|
||||
#ifdef RASOPS_CLIPPING
|
||||
ri->ri_flg &= ~RASOPS_CURSOR_CLIPPED;
|
||||
|
||||
if (row < 0 || row >= ri->ri_rows)
|
||||
ri->ri_flg |= RASOPS_CURSOR_CLIPPED;
|
||||
else if (col < 0 || col >= ri->ri_cols)
|
||||
ri->ri_flg |= RASOPS_CURSOR_CLIPPED;
|
||||
#endif
|
||||
ri->ri_crow = row;
|
||||
ri->ri_ccol = col;
|
||||
|
||||
if (on) {
|
||||
ri->ri_flg |= RASOPS_CURSOR;
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (!(ri->ri_flg & RASOPS_CURSOR_CLIPPED))
|
||||
#endif
|
||||
ri->ri_do_cursor(ri);
|
||||
} else
|
||||
ri->ri_flg &= ~RASOPS_CURSOR;
|
||||
}
|
||||
|
||||
|
||||
#if (RASOPS15 + RASOPS16 + RASOPS32)
|
||||
/*
|
||||
* Make the device colormap
|
||||
*/
|
||||
void
|
||||
rasops_init_devcmap(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
int i, c;
|
||||
u_char *p;
|
||||
|
||||
p = rasops_cmap;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (ri->ri_rnum <= 8)
|
||||
c = (*p++ >> (8 - ri->ri_rnum)) << ri->ri_rpos;
|
||||
else
|
||||
c = (*p++ << (ri->ri_rnum - 8)) << ri->ri_rpos;
|
||||
|
||||
if (ri->ri_gnum <= 8)
|
||||
c = (*p++ >> (8 - ri->ri_gnum)) << ri->ri_gpos;
|
||||
else
|
||||
c = (*p++ << (ri->ri_gnum - 8)) << ri->ri_gpos;
|
||||
|
||||
if (ri->ri_bnum <= 8)
|
||||
c = (*p++ >> (8 - ri->ri_bnum)) << ri->ri_bpos;
|
||||
else
|
||||
c = (*p++ << (ri->ri_bnum - 8)) << ri->ri_bpos;
|
||||
|
||||
ri->ri_devcmap[i] = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Unpack a rasops attribute
|
||||
*/
|
||||
void
|
||||
rasops_unpack_attr(attr, fg, bg, underline)
|
||||
long attr;
|
||||
int *fg, *bg, *underline;
|
||||
{
|
||||
|
||||
*fg = ((u_int)attr >> 24) & 15;
|
||||
*bg = ((u_int)attr >> 16) & 15;
|
||||
*underline = (u_int)attr & 1;
|
||||
}
|
123
sys/dev/rasops/rasops.h
Normal file
123
sys/dev/rasops/rasops.h
Normal file
@ -0,0 +1,123 @@
|
||||
/* $NetBSD: rasops.h,v 1.1 1999/04/13 00:17:59 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Andy Doran <ad@NetBSD.org>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _RASOPS_H_
|
||||
#define _RASOPS_H_ 1
|
||||
|
||||
/* Avoid dragging in dev/wscons/wsconsio.h */
|
||||
struct wsdisplay_font;
|
||||
|
||||
struct rasops_info {
|
||||
/* These must be filled in by the caller */
|
||||
int ri_depth; /* depth in bits */
|
||||
u_char *ri_bits; /* ptr to bits */
|
||||
int ri_width; /* width (pels) */
|
||||
int ri_height; /* height (pels) */
|
||||
int ri_stride; /* stride in bytes */
|
||||
|
||||
/* These can optionally be left NULL */
|
||||
struct wsdisplay_font *ri_font;/* font to use */
|
||||
void *ri_priv; /* driver private data */
|
||||
u_char ri_forcemono; /* force monochrome operation */
|
||||
u_char __pad0;
|
||||
|
||||
/*
|
||||
* These are optional and will default if zero. Meaningless
|
||||
* on depths other than 15, 16, 24 and 32 bits per pel. On
|
||||
* 24 bit displays, ri_{r,g,b}num must be 8.
|
||||
*/
|
||||
u_char ri_rnum; /* number of bits for red */
|
||||
u_char ri_gnum; /* number of bits for green */
|
||||
u_char ri_bnum; /* number of bits for blue */
|
||||
u_char ri_rpos; /* which bit red starts at */
|
||||
u_char ri_gpos; /* which bit green starts at */
|
||||
u_char ri_bpos; /* which bit blue starts at */
|
||||
|
||||
/* These are filled in by rasops_init() */
|
||||
int ri_emuwidth; /* width we actually care about */
|
||||
int ri_emuheight; /* height we actually care about */
|
||||
int ri_emustride; /* bytes per row we actually care about */
|
||||
int ri_rows; /* number of rows (characters, not pels) */
|
||||
int ri_cols; /* number of columns (characters, not pels) */
|
||||
int ri_delta; /* row delta in bytes */
|
||||
int ri_flg; /* flags */
|
||||
int ri_crow; /* cursor row */
|
||||
int ri_ccol; /* cursor column */
|
||||
int ri_pelbytes; /* bytes per pel */
|
||||
int ri_fontscale; /* fontheight * fontstride */
|
||||
int ri_xscale; /* fontwidth * pelbytes */
|
||||
int ri_yscale; /* fontheight * stride */
|
||||
u_char *ri_origbits; /* where screen bits actually start */
|
||||
|
||||
/* For 15, 16, 24, 32 bits */
|
||||
int32_t ri_devcmap[16]; /* device colormap (WSCOL_*) */
|
||||
|
||||
/* The emulops you need to use */
|
||||
struct wsdisplay_emulops ri_ops;
|
||||
|
||||
/* Callbacks so we can share some code */
|
||||
void (*ri_do_cursor)(struct rasops_info *);
|
||||
};
|
||||
|
||||
#define RASOPS_CURSOR (0x01) /* cursor is on */
|
||||
#define RASOPS_INITTED (0x02) /* struct is initialized */
|
||||
#define RASOPS_CURSOR_CLIPPED (0x04) /* cursor is clipped */
|
||||
|
||||
#define DELTA(p, d, cast) ((p) = (cast)((caddr_t)(p) + (d)))
|
||||
|
||||
/*
|
||||
* rasops_init().
|
||||
*
|
||||
* Integer parameters are: number of rows we'd like, number of columns we'd
|
||||
* like, whether we should clear the display and whether we should center
|
||||
* the output. Remember that what you'd like is always not what you get.
|
||||
*
|
||||
* In terms of optimization, fonts that are a multiple of 8 pixels wide
|
||||
* work the best: this is important, and will cost you if you don't use 'em.
|
||||
*/
|
||||
|
||||
/* rasops.c */
|
||||
int rasops_init __P((struct rasops_info *, int, int, int, int));
|
||||
void rasops_unpack_attr __P((long, int *, int *, int *));
|
||||
|
||||
/* This should not be called outside rasops */
|
||||
void rasops_init_devcmap __P((struct rasops_info *));
|
||||
|
||||
extern u_char rasops_isgray[16];
|
||||
extern u_char rasops_cmap[256*3];
|
||||
|
||||
#endif /* _RASOPS_H_ */
|
642
sys/dev/rasops/rasops1.c
Normal file
642
sys/dev/rasops/rasops1.c
Normal file
@ -0,0 +1,642 @@
|
||||
/* $NetBSD: rasops1.c,v 1.1 1999/04/13 00:17:59 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Andy Doran <ad@NetBSD.org>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opt_rasops.h"
|
||||
#ifdef RASOPS1
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.1 1999/04/13 00:17:59 ad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
#include <machine/endian.h>
|
||||
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/rasops/rasops.h>
|
||||
|
||||
static void rasops1_putchar __P((void *, int, int col, u_int, long));
|
||||
static void rasops1_putchar8 __P((void *, int, int col, u_int, long));
|
||||
static void rasops1_putchar16 __P((void *, int, int col, u_int, long));
|
||||
static void rasops1_copycols __P((void *, int, int, int, int));
|
||||
static void rasops1_erasecols __P((void *, int, int, int));
|
||||
static void rasops1_erasecols8 __P((void *, int, int, int));
|
||||
static void rasops1_eraserows __P((void *, int, int));
|
||||
static int32_t rasops1_fg_color __P((long));
|
||||
static int32_t rasops1_bg_color __P((long));
|
||||
static void rasops1_do_cursor __P((struct rasops_info *));
|
||||
static void rasops1_do_cursor8 __P((struct rasops_info *));
|
||||
|
||||
void rasops1_init __P((struct rasops_info *ri));
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
static u_int32_t rightmask[32] = {
|
||||
#else
|
||||
static u_int32_t leftmask[32] = {
|
||||
#endif
|
||||
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
|
||||
0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
|
||||
0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
|
||||
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
|
||||
0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
|
||||
0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
|
||||
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
|
||||
0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe,
|
||||
};
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
static u_int32_t leftmask[32] = {
|
||||
#else
|
||||
static u_int32_t rightmask[32] = {
|
||||
#endif
|
||||
0x00000000, 0x00000001, 0x00000003, 0x00000007,
|
||||
0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
|
||||
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
|
||||
0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
|
||||
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
|
||||
0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
|
||||
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
|
||||
0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initalize rasops_info struct for this colordepth.
|
||||
*/
|
||||
void
|
||||
rasops1_init(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
|
||||
switch (ri->ri_font->fontwidth) {
|
||||
case 8:
|
||||
ri->ri_ops.putchar = rasops1_putchar8;
|
||||
break;
|
||||
case 16:
|
||||
ri->ri_ops.putchar = rasops1_putchar16;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* XXX we don't support anything other than 8 and 16 pel
|
||||
* wide fonts yet. rasops1_copycols needs to be finished, the
|
||||
* other routines will need to be checked.
|
||||
*/
|
||||
panic("rasops1_init: not completed - see this location in src for details");
|
||||
ri->ri_ops.putchar = rasops1_putchar;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ri->ri_font->fontwidth & 7) {
|
||||
ri->ri_ops.erasecols = rasops1_erasecols;
|
||||
ri->ri_ops.copycols = rasops1_copycols;
|
||||
ri->ri_do_cursor = rasops1_do_cursor;
|
||||
} else {
|
||||
ri->ri_ops.erasecols = rasops1_erasecols8;
|
||||
/* use default copycols */
|
||||
ri->ri_do_cursor = rasops1_do_cursor8;
|
||||
}
|
||||
|
||||
ri->ri_ops.eraserows = rasops1_eraserows;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get foreground color from attribute and copy across all 4 bytes
|
||||
* in a int32_t.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops1_fg_color(long attr)
|
||||
{
|
||||
|
||||
return (attr & 0x0f000000) ? 0xffffffff : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get background color from attribute and copy across all 4 bytes
|
||||
* in a int32_t.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops1_bg_color(long attr)
|
||||
{
|
||||
|
||||
return (attr & 0x000f0000) ? 0xffffffff : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is the generic version.
|
||||
*/
|
||||
static void
|
||||
rasops1_putchar(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
|
||||
/* XXX i need implemention */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 8-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops1_putchar8(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
int height, fs, rs, bg, fg;
|
||||
struct rasops_info *ri;
|
||||
u_char *fr, *rp;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0 || row >= ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0 || col >= ri->ri_cols)
|
||||
return;
|
||||
#endif
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
rs = ri->ri_stride;
|
||||
|
||||
bg = (attr & 0x000f0000) ? 0xff : 0;
|
||||
fg = (attr & 0x0f000000) ? 0xff : 0;
|
||||
|
||||
/* If fg and bg match this becomes a space character */
|
||||
if (fg == bg || uc == ' ') {
|
||||
while (height--) {
|
||||
*rp = bg;
|
||||
rp += rs;
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
/* NOT fontbits if bg is white */
|
||||
if (bg) {
|
||||
while (height--) {
|
||||
*rp = ~*fr;
|
||||
fr += fs;
|
||||
rp += rs;
|
||||
}
|
||||
} else {
|
||||
while (height--) {
|
||||
*rp = *fr;
|
||||
fr += fs;
|
||||
rp += rs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do underline */
|
||||
if (attr & 1)
|
||||
rp[-(ri->ri_stride << 1)] = fg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 16-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops1_putchar16(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
int height, fs, rs, bg, fg;
|
||||
struct rasops_info *ri;
|
||||
u_char *fr, *rp;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0 || row >= ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0 || col >= ri->ri_cols)
|
||||
return;
|
||||
#endif
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
rs = ri->ri_stride;
|
||||
|
||||
bg = (attr & 0x000f0000) ? 0xffff : 0;
|
||||
fg = (attr & 0x0f000000) ? 0xffff : 0;
|
||||
|
||||
/* If fg and bg match this becomes a space character */
|
||||
if (fg == bg || uc == ' ') {
|
||||
while (height--) {
|
||||
*(int16_t *)rp = bg;
|
||||
rp += rs;
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
/* NOT fontbits if bg is white */
|
||||
if (bg) {
|
||||
while (height--) {
|
||||
rp[0] = ~fr[0];
|
||||
rp[1] = ~fr[1];
|
||||
fr += fs;
|
||||
rp += rs;
|
||||
}
|
||||
} else {
|
||||
while (height--) {
|
||||
rp[0] = fr[0];
|
||||
rp[1] = fr[1];
|
||||
fr += fs;
|
||||
rp += rs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do underline */
|
||||
if (attr & 1)
|
||||
*(int16_t *)(rp - (ri->ri_stride << 1)) = fg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase columns.
|
||||
*/
|
||||
static void
|
||||
rasops1_erasecols(cookie, row, col, num, attr)
|
||||
void *cookie;
|
||||
int row, num;
|
||||
long attr;
|
||||
{
|
||||
int32_t *dp, *rp, lmask, rmask, lclr, rclr, clr;
|
||||
struct rasops_info *ri;
|
||||
int nint, height, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0 || row > ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0) {
|
||||
num += col;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if ((col + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - col;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
col *= ri->ri_fontwidth;
|
||||
num *= ri->ri_fontwidth;
|
||||
|
||||
/*
|
||||
* lmask: mask for leftmost int32
|
||||
* rmask: mask for rightmost int32
|
||||
* nint: number of full int32s
|
||||
*/
|
||||
lmask = leftmask[col & 31];
|
||||
rmask = rightmask[(col + num) & 31];
|
||||
nint = ((col + num) & ~31) - ((col + 31) & ~31) >> 5;
|
||||
|
||||
/* Merge both masks if the span is encapsulated within one int32 */
|
||||
if (col & ~31 == (col + num) & ~31) {
|
||||
lmask &= rmask;
|
||||
rmask = 0;
|
||||
}
|
||||
|
||||
clr = rasops1_bg_color(attr);
|
||||
lclr = clr & lmask;
|
||||
rclr = clr & rmask;
|
||||
lmask = ~lmask;
|
||||
rmask = ~rmask;
|
||||
height = ri->ri_fontheight;
|
||||
rp = ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3);
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
|
||||
if (lmask != 0xffffffffU)
|
||||
*dp++ = (*dp & lmask) | lclr;
|
||||
|
||||
for (cnt = nint; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
if (rmask != 0xffffffffU)
|
||||
*dp = (*dp & rmask) | rclr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase columns for fonts that are a multiple of 8 pels in width.
|
||||
*/
|
||||
static void
|
||||
rasops1_erasecols8(cookie, row, col, num, attr)
|
||||
void *cookie;
|
||||
int row, col, num;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dst;
|
||||
u_char *dstb, *rp;
|
||||
int clr, height, cnt, slop1, slop2;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0 || row >= ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0) {
|
||||
num += col;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if ((col + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - col;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num = num * ri->ri_xscale;
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
clr = rasops1_bg_color(attr);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
slop1 = (int)rp & 3;
|
||||
slop2 = (num - slop1) & 3;
|
||||
num = (num - slop1 - slop2) >> 2;
|
||||
|
||||
while (height--) {
|
||||
dstb = rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
/* Align span to 4 bytes */
|
||||
for (cnt = slop1; cnt; cnt--)
|
||||
*dstb++ = (u_char)clr;
|
||||
|
||||
dst = (int32_t *)dstb;
|
||||
|
||||
/* Write 4 bytes per loop */
|
||||
for (cnt = num; cnt; cnt--)
|
||||
*dst++ = clr;
|
||||
|
||||
/* Write unaligned trailing slop */
|
||||
if (slop2 == 0)
|
||||
continue;
|
||||
|
||||
dstb = (u_char *)dst;
|
||||
|
||||
for (cnt = slop2; cnt; cnt--)
|
||||
*dstb++ = (u_char)clr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actually paint the cursor.
|
||||
*/
|
||||
static void
|
||||
rasops1_do_cursor(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
int32_t *dp, *rp, lmask, rmask;
|
||||
int height, row, col;
|
||||
|
||||
row = ri->ri_crow;
|
||||
col = ri->ri_ccol * ri->ri_fontwidth;
|
||||
|
||||
/*
|
||||
* lmask: mask for leftmost int32
|
||||
* rmask: mask for rightmost int32
|
||||
*/
|
||||
lmask = leftmask[col & 31];
|
||||
rmask = rightmask[(col + ri->ri_fontwidth) & 31];
|
||||
|
||||
/* Merge both masks if the span is encapsulated within one int32 */
|
||||
if (col & ~31 == (col + ri->ri_fontwidth) & ~31) {
|
||||
lmask &= rmask;
|
||||
rmask = 0;
|
||||
}
|
||||
|
||||
lmask = ~lmask;
|
||||
rmask = ~rmask;
|
||||
height = ri->ri_fontheight;
|
||||
rp = ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3);
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
|
||||
*dp++ = ((*dp & lmask) ^ lmask) | (*dp & ~lmask);
|
||||
|
||||
if (rmask != 0xffffffffU)
|
||||
*dp = ((*dp & rmask) ^ rmask) | (*dp & ~rmask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint cursors that are a multiple of 8 pels in size.
|
||||
*/
|
||||
static void
|
||||
rasops1_do_cursor8(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
int width, height, cnt;
|
||||
u_char *dp, *rp;
|
||||
|
||||
height = ri->ri_fontheight;
|
||||
width = ri->ri_fontwidth >> 3;
|
||||
rp = ri->ri_bits + ri->ri_crow * ri->ri_yscale +
|
||||
ri->ri_ccol * ri->ri_xscale;
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = width; cnt; cnt--)
|
||||
*dp++ ^= 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase rows.
|
||||
*/
|
||||
static void
|
||||
rasops1_eraserows(cookie, row, num, attr)
|
||||
void *cookie;
|
||||
int row, num;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp, clr;
|
||||
int n8, n1, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0) {
|
||||
num += row;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
if ((row + num) > ri->ri_rows)
|
||||
num = ri->ri_rows - row;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num *= ri->ri_font->fontheight;
|
||||
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
|
||||
clr = rasops1_bg_color(attr);
|
||||
|
||||
n8 = ri->ri_emustride >> 5;
|
||||
n1 = (ri->ri_emustride >> 2) & 7;
|
||||
|
||||
while (num--) {
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp[3] = clr;
|
||||
dp[4] = clr;
|
||||
dp[5] = clr;
|
||||
dp[6] = clr;
|
||||
dp[7] = clr;
|
||||
dp += 8;
|
||||
}
|
||||
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
DELTA(dp, ri->ri_delta, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy columns. This is slow. Ick! You'd better use a font with
|
||||
* a width that's a multiple of 8 pels, otherwise this is used...
|
||||
*/
|
||||
static void
|
||||
rasops1_copycols(cookie, row, src, src)
|
||||
void *cookie;
|
||||
int row, src, dst;
|
||||
{
|
||||
#ifdef notyet
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp, *drp, *sp, *srp, lmask, rmask;
|
||||
int nint, height, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0 || row >= ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0) {
|
||||
num += col;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if ((col + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - col;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
src *= ri->ri_fontwidth;
|
||||
dst *= ri->ri_fontwidth;
|
||||
num *= ri->ri_fontwidth;
|
||||
|
||||
/*
|
||||
* lmask: mask for leftmost int32
|
||||
* rmask: mask for rightmost int32
|
||||
* nint: number of full int32s
|
||||
*/
|
||||
lmask = leftmask[col & 31];
|
||||
rmask = rightmask[(col + num) & 31];
|
||||
nint = ((col + num) & ~31) - ((col + 31) & ~31) >> 5;
|
||||
|
||||
/* Merge both masks if the span is encapsulated within one int32 */
|
||||
if (col & ~31 == (col + num) & ~31) {
|
||||
lmask &= rmask;
|
||||
rmask = 0;
|
||||
}
|
||||
|
||||
lmask = ~lmask;
|
||||
rmask = ~rmask;
|
||||
height = ri->ri_fontheight;
|
||||
drp = ri->ri_bits + row*ri->ri_yscale + ((dst >> 3) & ~3);
|
||||
srp = ri->ri_bits + row*ri->ri_yscale + ((src >> 3) & ~3);
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
|
||||
if (lmask != 0xffffffffU)
|
||||
*dp++ = (*dp & lmask) | lclr;
|
||||
|
||||
for (cnt = nint; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
if (rmask != 0xffffffffU)
|
||||
*dp = (*dp & rmask) | rclr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* RASOPS1 */
|
646
sys/dev/rasops/rasops15.c
Normal file
646
sys/dev/rasops/rasops15.c
Normal file
@ -0,0 +1,646 @@
|
||||
/* $NetBSD: rasops15.c,v 1.1 1999/04/13 00:18:00 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Andy Doran <ad@NetBSD.org>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opt_rasops.h"
|
||||
#ifdef RASOPS15
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rasops15.c,v 1.1 1999/04/13 00:18:00 ad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/rasops/rasops.h>
|
||||
|
||||
static void rasops15_putchar __P((void *, int, int, u_int, long attr));
|
||||
static void rasops15_putchar8 __P((void *, int, int, u_int, long attr));
|
||||
static void rasops15_putchar12 __P((void *, int, int, u_int, long attr));
|
||||
static void rasops15_putchar16 __P((void *, int, int, u_int, long attr));
|
||||
static void rasops15_erasecols __P((void *, int, int, int, long));
|
||||
static void rasops15_eraserows __P((void *, int, int, long));
|
||||
static void rasops15_makestamp __P((struct rasops_info *, long));
|
||||
static int32_t rasops15_bg_color __P((struct rasops_info *, long));
|
||||
static void rasops15_do_cursor __P((struct rasops_info *));
|
||||
|
||||
void rasops15_init __P((struct rasops_info *ri));
|
||||
|
||||
/*
|
||||
* (2x2)x1 stamp for optimized character blitting
|
||||
*/
|
||||
static int32_t stamp[32];
|
||||
static long stamp_attr;
|
||||
static int stamp_mutex; /* XXX see note in readme */
|
||||
|
||||
/*
|
||||
* XXX this confuses the hell out of gcc2 (not egcs) which always insists
|
||||
* that the shift count is negative.
|
||||
*
|
||||
* offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
|
||||
* destination int32_t[0] = STAMP_READ(offset)
|
||||
* destination int32_t[1] = STAMP_READ(offset + 4)
|
||||
*/
|
||||
#define STAMP_SHIFT(fb,n) ((n*4-3) >= 0 ? (fb)>>(n*4-3):(fb)<<-(n*4-3))
|
||||
#define STAMP_MASK (15 << 3)
|
||||
#define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
|
||||
|
||||
|
||||
/*
|
||||
* Initalize rasops_info struct for this colordepth.
|
||||
*/
|
||||
void
|
||||
rasops15_init(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
|
||||
switch (ri->ri_font->fontwidth) {
|
||||
case 8:
|
||||
ri->ri_ops.putchar = rasops15_putchar8;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
ri->ri_ops.putchar = rasops15_putchar12;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
ri->ri_ops.putchar = rasops15_putchar16;
|
||||
break;
|
||||
|
||||
default:
|
||||
ri->ri_ops.putchar = rasops15_putchar;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Select defaults for color masks if none selected */
|
||||
if (ri->ri_rnum == 0) {
|
||||
ri->ri_rnum = 5;
|
||||
ri->ri_rpos = 0;
|
||||
ri->ri_gnum = 5 + (ri->ri_depth == 16);
|
||||
ri->ri_gpos = 5;
|
||||
ri->ri_bnum = 5;
|
||||
ri->ri_bpos = 10 + (ri->ri_depth == 16);
|
||||
}
|
||||
|
||||
ri->ri_ops.erasecols = rasops15_erasecols;
|
||||
ri->ri_ops.eraserows = rasops15_eraserows;
|
||||
ri->ri_do_cursor = rasops15_do_cursor;
|
||||
rasops_init_devcmap(ri);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get background color from attribute and copy across all 4 bytes
|
||||
* in a int32_t.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops15_bg_color(ri, attr)
|
||||
struct rasops_info *ri;
|
||||
long attr;
|
||||
{
|
||||
int32_t bg;
|
||||
|
||||
bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
|
||||
return bg | (bg << 16);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actually turn the cursor on or off. This does the dirty work for
|
||||
* rasops_cursor().
|
||||
*/
|
||||
static void
|
||||
rasops15_do_cursor(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
u_char *rp, *dp;
|
||||
int full1, height, cnt, slop1, slop2, row, col;
|
||||
int32_t planemask;
|
||||
|
||||
row = ri->ri_crow;
|
||||
col = ri->ri_ccol;
|
||||
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
slop1 = (int)rp & 2;
|
||||
slop2 = (ri->ri_xscale - slop1) & 2;
|
||||
full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
|
||||
planemask = ri->ri_devcmap[15] | (ri->ri_devcmap[15] << 16);
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
if (slop1) {
|
||||
*(int16_t *)dp ^= (int16_t)planemask;
|
||||
dp += 2;
|
||||
}
|
||||
|
||||
for (cnt = full1; cnt; cnt--) {
|
||||
*(int32_t *)dp ^= planemask;
|
||||
dp += 4;
|
||||
}
|
||||
|
||||
if (slop2)
|
||||
*(int16_t *)dp ^= (int16_t)planemask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase columns.
|
||||
*/
|
||||
static void
|
||||
rasops15_erasecols(cookie, row, col, num, attr)
|
||||
void *cookie;
|
||||
int row, num;
|
||||
long attr;
|
||||
{
|
||||
int n8, clr, height, cnt, slop1, slop2;
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp;
|
||||
u_char *rp;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
/* Catches 'row < 0' case too */
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0) {
|
||||
num += col;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if ((col + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - col;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
num *= ri->ri_xscale;
|
||||
clr = rasops15_bg_color(ri, attr);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
slop1 = (int)rp & 2;
|
||||
slop2 = (num - slop1) & 2;
|
||||
num = num - slop1 - slop2;
|
||||
n8 = num >> 5;
|
||||
num = (num >> 2) & 7;
|
||||
|
||||
while (height--) {
|
||||
dp = (u_int32_t *)rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
/* Align span to 4 bytes */
|
||||
if (slop1) {
|
||||
*(int16_t *)dp = (int16_t)clr;
|
||||
DELTA(dp, 2, int32_t *);
|
||||
}
|
||||
|
||||
/* Write 32 bytes per loop */
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp[3] = clr;
|
||||
dp[4] = clr;
|
||||
dp[5] = clr;
|
||||
dp[6] = clr;
|
||||
dp[7] = clr;
|
||||
dp += 8;
|
||||
}
|
||||
|
||||
/* Write 4 bytes per loop */
|
||||
for (cnt = num; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
/* Write unaligned trailing slop */
|
||||
if (slop2)
|
||||
*(int16_t *)dp = (int16_t)clr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character.
|
||||
*/
|
||||
static void
|
||||
rasops15_putchar(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int fb, width, height, cnt, clr[2];
|
||||
u_char *dp, *rp, *fr;
|
||||
|
||||
if (uc == (u_int)-1) {
|
||||
rasops15_erasecols(cookie, row, col, 1, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
/* Catches 'row < 0' case too */
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols)
|
||||
return;
|
||||
#endif
|
||||
|
||||
uc -= ri->ri_font->firstchar;
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
|
||||
height = ri->ri_font->fontheight;
|
||||
width = ri->ri_font->fontwidth;
|
||||
|
||||
clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 15];
|
||||
clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 15];
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
|
||||
fr += ri->ri_font->stride;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = width; cnt; cnt--) {
|
||||
*(int16_t *)dp = (int16_t)clr[(fb >> 31) & 1];
|
||||
fb <<= 1;
|
||||
dp += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Recompute the (2x2)x1 blitting stamp.
|
||||
*/
|
||||
static void
|
||||
rasops15_makestamp(ri, attr)
|
||||
struct rasops_info *ri;
|
||||
long attr;
|
||||
{
|
||||
int32_t fg, bg;
|
||||
int i;
|
||||
|
||||
fg = ri->ri_devcmap[((u_int)attr >> 24) & 15];
|
||||
bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
|
||||
stamp_attr = attr;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
stamp[i << 1] = (i & 8 ? fg : bg);
|
||||
stamp[i << 1] |= ((i & 4 ? fg : bg) << 16);
|
||||
stamp[(i << 1) + 1] = (i & 2 ? fg : bg);
|
||||
stamp[(i << 1) + 1] |= ((i & 1 ? fg : bg) << 16);
|
||||
#else
|
||||
stamp[i << 1] = (i & 1 ? fg : bg);
|
||||
stamp[i << 1] |= ((i & 2 ? fg : bg) << 16);
|
||||
stamp[(i << 1) + 1] = (i & 4 ? fg : bg);
|
||||
stamp[(i << 1) + 1] |= ((i & 8 ? fg : bg) << 16);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 8-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops15_putchar8(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int height, so, fs;
|
||||
int32_t *rp;
|
||||
u_char *fr;
|
||||
|
||||
/* Can't risk remaking the stamp if it's already in use */
|
||||
if (stamp_mutex++) {
|
||||
stamp_mutex--;
|
||||
rasops15_putchar(cookie, row, col, uc, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recompute stamp? */
|
||||
if (attr != stamp_attr)
|
||||
rasops15_makestamp(ri, attr);
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
if (uc == (u_int)-1) {
|
||||
while (height--) {
|
||||
rp[0] = stamp[0];
|
||||
rp[1] = stamp[0];
|
||||
rp[2] = stamp[0];
|
||||
rp[3] = stamp[0];
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
|
||||
rp[0] = STAMP_READ(so);
|
||||
rp[1] = STAMP_READ(so + 4);
|
||||
|
||||
so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
|
||||
rp[2] = STAMP_READ(so);
|
||||
rp[3] = STAMP_READ(so + 4);
|
||||
|
||||
fr += fs;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
stamp_mutex--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 12-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops15_putchar12(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int height, so, fs;
|
||||
int32_t *rp;
|
||||
u_char *fr;
|
||||
|
||||
/* Can't risk remaking the stamp if it's already in use */
|
||||
if (stamp_mutex++) {
|
||||
stamp_mutex--;
|
||||
rasops15_putchar(cookie, row, col, uc, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recompute stamp? */
|
||||
if (attr != stamp_attr)
|
||||
rasops15_makestamp(ri, attr);
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
if (uc == (u_int)-1) {
|
||||
while (height--) {
|
||||
rp[0] = stamp[0];
|
||||
rp[1] = stamp[0];
|
||||
rp[2] = stamp[0];
|
||||
rp[3] = stamp[0];
|
||||
rp[4] = stamp[0];
|
||||
rp[5] = stamp[0];
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
|
||||
rp[0] = STAMP_READ(so);
|
||||
rp[1] = STAMP_READ(so + 4);
|
||||
|
||||
so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
|
||||
rp[2] = STAMP_READ(so);
|
||||
rp[3] = STAMP_READ(so + 4);
|
||||
|
||||
so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
|
||||
rp[4] = STAMP_READ(so);
|
||||
rp[5] = STAMP_READ(so + 4);
|
||||
|
||||
fr += fs;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
stamp_mutex--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 16-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops15_putchar16(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int height, so, fs;
|
||||
int32_t *rp;
|
||||
u_char *fr;
|
||||
|
||||
/* Can't risk remaking the stamp if it's already in use */
|
||||
if (stamp_mutex++) {
|
||||
stamp_mutex--;
|
||||
rasops15_putchar(cookie, row, col, uc, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recompute stamp? */
|
||||
if (attr != stamp_attr)
|
||||
rasops15_makestamp(ri, attr);
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
if (uc == (u_int)-1) {
|
||||
while (height--) {
|
||||
rp[0] = stamp[0];
|
||||
rp[1] = stamp[0];
|
||||
rp[2] = stamp[0];
|
||||
rp[3] = stamp[0];
|
||||
rp[4] = stamp[0];
|
||||
rp[5] = stamp[0];
|
||||
rp[6] = stamp[0];
|
||||
rp[7] = stamp[0];
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
|
||||
rp[0] = STAMP_READ(so);
|
||||
rp[1] = STAMP_READ(so + 4);
|
||||
|
||||
so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
|
||||
rp[2] = STAMP_READ(so);
|
||||
rp[3] = STAMP_READ(so + 4);
|
||||
|
||||
so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
|
||||
rp[4] = STAMP_READ(so);
|
||||
rp[5] = STAMP_READ(so + 4);
|
||||
|
||||
so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
|
||||
rp[6] = STAMP_READ(so);
|
||||
rp[7] = STAMP_READ(so + 4);
|
||||
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
fr += fs;
|
||||
}
|
||||
}
|
||||
|
||||
stamp_mutex--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase rows.
|
||||
*/
|
||||
static void
|
||||
rasops15_eraserows(cookie, row, num, attr)
|
||||
void *cookie;
|
||||
int row, num;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp, clr;
|
||||
int n8, n1, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0) {
|
||||
num += row;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
if ((row + num) > ri->ri_rows)
|
||||
num = ri->ri_rows - row;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num *= ri->ri_font->fontheight;
|
||||
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
|
||||
clr = rasops15_bg_color(ri, attr);
|
||||
|
||||
n8 = ri->ri_emustride >> 5;
|
||||
n1 = (ri->ri_emustride >> 2) & 7;
|
||||
|
||||
while (num--) {
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp[3] = clr;
|
||||
dp[4] = clr;
|
||||
dp[5] = clr;
|
||||
dp[6] = clr;
|
||||
dp[7] = clr;
|
||||
dp += 8;
|
||||
}
|
||||
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
DELTA(dp, ri->ri_delta, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RASOPS15 */
|
449
sys/dev/rasops/rasops24.c
Normal file
449
sys/dev/rasops/rasops24.c
Normal file
@ -0,0 +1,449 @@
|
||||
/* $NetBSD: rasops24.c,v 1.1 1999/04/13 00:18:00 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Andy Doran <ad@NetBSD.org>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.1 1999/04/13 00:18:00 ad Exp $");
|
||||
|
||||
#include "opt_rasops.h"
|
||||
#ifdef RASOPS24
|
||||
#error This is dangerously incomplete.
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/rasops/rasops.h>
|
||||
|
||||
static void rasops24_putchar __P((void *, int, int, u_int, long attr));
|
||||
static void rasops24_erasecols __P((void *, int, int, int, long));
|
||||
static void rasops24_eraserows __P((void *, int, int, long));
|
||||
static int rasops24_alloc_attr __P((void *, int, int, int, long *));
|
||||
static void rasops24_make_bgstamp __P((int, u_char *));
|
||||
static int32_t rasops24_fg_color __P((struct rasops_info *, long));
|
||||
static int32_t rasops24_bg_color __P((struct rasops_info *, long));
|
||||
static void rasops24_do_cursor __P((struct rasops_info *));
|
||||
|
||||
void rasops24_init __P((struct rasops_info *ri));
|
||||
|
||||
/*
|
||||
* Initalize rasops_info struct for this colordepth.
|
||||
*/
|
||||
void
|
||||
rasops24_init(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
|
||||
switch (ri->ri_font->fontwidth) {
|
||||
case 8:
|
||||
ri->ri_ops.putchar = rasops15_putchar8;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
ri->ri_ops.putchar = rasops15_putchar12;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
ri->ri_ops.putchar = rasops15_putchar16;
|
||||
break;
|
||||
|
||||
default:
|
||||
ri->ri_ops.putchar = rasops15_putchar;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Select defaults for color positions if none selected */
|
||||
if (ri->ri_rnum == 0) {
|
||||
ri->ri_rnum = 8;
|
||||
ri->ri_gnum = 8;
|
||||
ri->ri_bnum = 8;
|
||||
ri->ri_rpos = 0;
|
||||
ri->ri_gpos = 8;
|
||||
ri->ri_bpos = 16;
|
||||
}
|
||||
|
||||
ri->ri_ops.erasecols = rasops25_erasecols;
|
||||
ri->ri_ops.eraserows = rasops25_eraserows;
|
||||
ri->ri_do_cursor = rasops25_do_cursor;
|
||||
rasops_init_devcmap(ri);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get foreground color from attribute and copy across all 4 bytes
|
||||
* in a int32_t.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops24_fg_color(ri, attr)
|
||||
struct rasops_info *ri;
|
||||
long attr;
|
||||
{
|
||||
int32_t fg;
|
||||
|
||||
fg = ri->ri_devcmap[((u_int)attr >> 24) & 15];
|
||||
|
||||
/* Copy across all 4 bytes if the color is gray */
|
||||
if (attr & 2)
|
||||
fg |= fg << 8;
|
||||
|
||||
return fg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get background color from attribute and copy across all 4 bytes
|
||||
* in a int32_t.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops24_bg_color(ri, attr)
|
||||
struct rasops_info *ri;
|
||||
long attr;
|
||||
{
|
||||
int32_t bg;
|
||||
|
||||
bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
|
||||
|
||||
/* Copy across all 4 bytes if the color is gray */
|
||||
if (attr & 4)
|
||||
bg |= bg << 8;
|
||||
|
||||
return bg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actually turn the cursor on or off. This does the dirty work for
|
||||
* rasops_cursor().
|
||||
*/
|
||||
static void
|
||||
rasops24_do_cursor(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
int full1, height, cnt, slop1, slop2, row, col;
|
||||
u_char *dp, *rp;
|
||||
|
||||
row = ri->ri_crow;
|
||||
col = ri->ri_ccol;
|
||||
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
slop1 = (int)rp & 3;
|
||||
slop2 = (ri->ri_xscale - slop1) & 3;
|
||||
full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = slop1; cnt; cnt--)
|
||||
*dp++ ^= 0xff;
|
||||
|
||||
for (cnt = full1; cnt; cnt--) {
|
||||
*(int32_t *)dp ^= 0xffffffff;
|
||||
dp += 4;
|
||||
}
|
||||
|
||||
for (cnt = slop2; cnt; cnt--)
|
||||
*dp++ ^= 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase columns.
|
||||
*/
|
||||
static void
|
||||
rasops24_erasecols(cookie, row, col, num, attr)
|
||||
void *cookie;
|
||||
int row, col, num;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp;
|
||||
u_char *rp;
|
||||
int n8, n1, clr, height, cnt, slop1, slop2;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
/* Catches 'row < 0' case too */
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0) {
|
||||
num += col;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if ((col + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - col;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
num *= ri->ri_xscale;
|
||||
clr = rasops24_bg_color(ri, attr);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
slop1 = (int)rp & 2;
|
||||
slop2 = (num - slop1) & 2;
|
||||
n8 = num >> 5;
|
||||
n1 = (num >> 2) & 7;
|
||||
|
||||
while (height--) {
|
||||
cnt = num;
|
||||
dp = (u_int32_t *)rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
/* Align span to 4 bytes */
|
||||
if (slop1) {
|
||||
*(int16_t *)dp = (int16_t)clr;
|
||||
DELTA(dp, 2, int32_t *);
|
||||
}
|
||||
|
||||
/* Write 32 bytes per loop */
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp[3] = clr;
|
||||
dp[4] = clr;
|
||||
dp[5] = clr;
|
||||
dp[6] = clr;
|
||||
dp[7] = clr;
|
||||
dp += 8;
|
||||
}
|
||||
|
||||
/* Write 4 bytes per loop */
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
/* Write unaligned trailing slop */
|
||||
if (slop2)
|
||||
*(int16_t *)dp = (int16_t)clr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character.
|
||||
*/
|
||||
static void
|
||||
rasops24_putchar(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
u_char *dp, *rp;
|
||||
int32_t *fr, clr[16], fb;
|
||||
int width, height, cnt;
|
||||
|
||||
if (uc == (u_int)-1) {
|
||||
rasops24_erasecols(cookie, row, col, 1, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols)
|
||||
return;
|
||||
#endif
|
||||
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
fr = (int32_t *)ri->ri_font->data + uc * ri->ri_font->fontheight;
|
||||
|
||||
height = ri->ri_font->fontheight;
|
||||
width = ri->ri_font->fontwidth;
|
||||
|
||||
clr[1] = ri->ri_devcmap[((u_int)attr >> 24)];
|
||||
clr[0] = ri->ri_devcmap[((u_int)attr >> 16)];
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
fb = *fr++;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = width; cnt; cnt--) {
|
||||
*(int16_t *)dp = (int16_t)clr[fb & 1];
|
||||
fb >>= 1;
|
||||
dp += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Construct a 12 byte by 1 byte blitting stamp. This uses the background
|
||||
* color only (for erasecols()/eraserows()).
|
||||
*/
|
||||
static void
|
||||
rasops24_make_bgstamp(i, bp)
|
||||
int i;
|
||||
u_char *bp;
|
||||
{
|
||||
u_char r, g, b;
|
||||
|
||||
i = (i >> 8) & 0xff;
|
||||
i = (i << 1) + i;
|
||||
r = rasops_cmap[i+0];
|
||||
g = rasops_cmap[i+1];
|
||||
b = rasops_cmap[i+2];
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
bp[0] = r; bp[1] = g; bp[2] = b; bp[3] = r;
|
||||
bp[4] = g; bp[5] = b; bp[6] = r; bp[7] = g;
|
||||
bp[8] = b; bp[9] = r; bp[10] = g; bp[11] = b;
|
||||
#else
|
||||
bp[3] = r; bp[2] = g; bp[1] = b; bp[0] = r;
|
||||
bp[7] = g; bp[6] = b; bp[5] = r; bp[4] = g;
|
||||
bp[11] = b; bp[10] = r; bp[9] = g; bp[8] = b;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase rows.
|
||||
*/
|
||||
static void
|
||||
rasops24_eraserows(cookie, row, num, attr)
|
||||
void *cookie;
|
||||
int row, num;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp, clr, stamp[3];
|
||||
int n9, n3, n1, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0) {
|
||||
num += row;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
if ((row + num) > ri->ri_rows)
|
||||
num = ri->ri_rows - row;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num *= ri->ri_font->fontheight;
|
||||
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
|
||||
|
||||
n9 = ri->ri_emustride / 36;
|
||||
cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
|
||||
|
||||
n3 = (ri->ri_emustride - cnt) / 12;
|
||||
cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
|
||||
|
||||
n1 = (ri->ri_emustride - cnt) >> 2;
|
||||
|
||||
/* If the color is gray, we can cheat... */
|
||||
if (attr & ATTR_GRAY_BG) {
|
||||
clr = rasops24_bg_color(ri, attr);
|
||||
|
||||
while (num--) {
|
||||
for (cnt = n9; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp[3] = clr;
|
||||
dp[4] = clr;
|
||||
dp[5] = clr;
|
||||
dp[6] = clr;
|
||||
dp[7] = clr;
|
||||
dp[8] = clr;
|
||||
dp += 9;
|
||||
}
|
||||
|
||||
for (cnt = n3; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp += 3;
|
||||
}
|
||||
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
DELTA(dp, ri->ri_delta, int32_t *);
|
||||
}
|
||||
} else {
|
||||
rasops24_make_bgstamp((int)attr, (u_char *)stamp);
|
||||
|
||||
while (num--) {
|
||||
for (cnt = n9; cnt; cnt--) {
|
||||
dp[0] = stamp[0];
|
||||
dp[1] = stamp[1];
|
||||
dp[2] = stamp[2];
|
||||
dp[3] = stamp[0];
|
||||
dp[4] = stamp[1];
|
||||
dp[5] = stamp[2];
|
||||
dp[6] = stamp[0];
|
||||
dp[7] = stamp[1];
|
||||
dp[8] = stamp[2];
|
||||
dp += 9;
|
||||
}
|
||||
|
||||
for (cnt = n3; cnt; cnt--) {
|
||||
dp[0] = stamp[0];
|
||||
dp[1] = stamp[1];
|
||||
dp[2] = stamp[2];
|
||||
dp += 3;
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < n1; cnt++)
|
||||
*dp++ = stamp[cnt];
|
||||
|
||||
DELTA(dp, ri->ri_delta, int32_t *);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RASOPS24 */
|
324
sys/dev/rasops/rasops32.c
Normal file
324
sys/dev/rasops/rasops32.c
Normal file
@ -0,0 +1,324 @@
|
||||
/* $NetBSD: rasops32.c,v 1.1 1999/04/13 00:18:01 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Andy Doran <ad@NetBSD.org>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opt_rasops.h"
|
||||
#ifdef RASOPS32
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.1 1999/04/13 00:18:01 ad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/rasops/rasops.h>
|
||||
|
||||
static void rasops32_putchar __P((void *, int, int, u_int, long attr));
|
||||
static void rasops32_erasecols __P((void *, int, int, int, long));
|
||||
static void rasops32_eraserows __P((void *, int, int, long));
|
||||
static int32_t rasops32_fg_color __P((struct rasops_info *, long));
|
||||
static int32_t rasops32_bg_color __P((struct rasops_info *, long));
|
||||
static void rasops32_do_cursor __P((struct rasops_info *));
|
||||
void rasops32_init __P((struct rasops_info *ri));
|
||||
|
||||
/*
|
||||
* Initalize a 'rasops_info' descriptor for this depth.
|
||||
*/
|
||||
void
|
||||
rasops32_init(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
|
||||
/*
|
||||
* This sucks. There is little optimization you can do with this
|
||||
* colordepth on 32-bit machines.
|
||||
*
|
||||
* XXX c'mon sparc, alpha ppl?
|
||||
*/
|
||||
ri->ri_ops.putchar = rasops32_putchar;
|
||||
ri->ri_ops.erasecols = rasops32_erasecols;
|
||||
ri->ri_ops.eraserows = rasops32_eraserows;
|
||||
ri->ri_do_cursor = rasops32_do_cursor;
|
||||
rasops_init_devcmap(ri);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get background color from attribute.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops32_bg_color(ri, attr)
|
||||
struct rasops_info *ri;
|
||||
long attr;
|
||||
{
|
||||
|
||||
return ri->ri_devcmap[((int32_t)attr >> 24) & 15];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get foreground color from attribute.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops32_fg_color(ri, attr)
|
||||
struct rasops_info *ri;
|
||||
long attr;
|
||||
{
|
||||
|
||||
return ri->ri_devcmap[((int32_t)attr >> 16) & 15];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actually turn the cursor on or off. This does the dirty work for
|
||||
* rasops_cursor().
|
||||
*/
|
||||
static void
|
||||
rasops32_do_cursor(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
u_char *rp;
|
||||
int32_t *dp, planemask;
|
||||
int num, height, cnt, row, col;
|
||||
|
||||
row = ri->ri_crow;
|
||||
col = ri->ri_ccol;
|
||||
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
height = ri->ri_font->fontheight;
|
||||
num = ri->ri_xscale >> 2;
|
||||
planemask = ri->ri_devcmap[15];
|
||||
|
||||
while (height--) {
|
||||
dp = (int32_t *)rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = num; cnt; cnt--)
|
||||
*dp++ ^= planemask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character.
|
||||
*/
|
||||
static void
|
||||
rasops32_putchar(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp, *rp, clr[2];
|
||||
u_char *fr;
|
||||
int width, height, cnt, fs, fb;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
/* Catches 'row < 0' case too */
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols)
|
||||
return;
|
||||
#endif
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
|
||||
height = ri->ri_font->fontheight;
|
||||
width = ri->ri_font->fontwidth;
|
||||
clr[0] = rasops32_bg_color(ri, attr);
|
||||
clr[1] = rasops32_fg_color(ri, attr);
|
||||
|
||||
if (uc == ' ') {
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
|
||||
for (cnt = width; cnt; cnt--)
|
||||
*dp++ = clr[0];
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
|
||||
fr += fs;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
|
||||
for (cnt = width; cnt; cnt--) {
|
||||
*dp++ = clr[(fb >> 31) & 1];
|
||||
fb <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do underline */
|
||||
if (attr & 1) {
|
||||
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
|
||||
|
||||
while (width--)
|
||||
*rp++ = clr[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase rows.
|
||||
*/
|
||||
static void
|
||||
rasops32_eraserows(cookie, row, num, attr)
|
||||
void *cookie;
|
||||
int row, num;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp, clr;
|
||||
int n8, n1, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0) {
|
||||
num += row;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
if ((row + num) > ri->ri_rows)
|
||||
num = ri->ri_rows - row;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num *= ri->ri_font->fontheight;
|
||||
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
|
||||
clr = rasops32_bg_color(ri, attr);
|
||||
|
||||
n8 = ri->ri_emustride >> 5;
|
||||
n1 = (ri->ri_emustride >> 2) & 7;
|
||||
|
||||
while (num--) {
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp[3] = clr;
|
||||
dp[4] = clr;
|
||||
dp[5] = clr;
|
||||
dp[6] = clr;
|
||||
dp[7] = clr;
|
||||
dp += 8;
|
||||
}
|
||||
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
DELTA(dp, ri->ri_delta, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase columns.
|
||||
*/
|
||||
static void
|
||||
rasops32_erasecols(cookie, row, col, num, attr)
|
||||
void *cookie;
|
||||
int row, col, num;
|
||||
long attr;
|
||||
{
|
||||
int n8, clr, height, cnt;
|
||||
struct rasops_info *ri;
|
||||
int32_t *dst;
|
||||
u_char *rp;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0) {
|
||||
num += col;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if ((col + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - col;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num = num * ri->ri_xscale;
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
clr = rasops32_bg_color(ri, attr);
|
||||
height = ri->ri_font->fontheight;
|
||||
n8 = num >> 5;
|
||||
num = (num >> 2) & 7;
|
||||
|
||||
while (height--) {
|
||||
dst = (int32_t *)rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dst[0] = clr;
|
||||
dst[1] = clr;
|
||||
dst[2] = clr;
|
||||
dst[3] = clr;
|
||||
dst[4] = clr;
|
||||
dst[5] = clr;
|
||||
dst[6] = clr;
|
||||
dst[7] = clr;
|
||||
dst += 8;
|
||||
}
|
||||
|
||||
for (cnt = num; cnt; cnt--)
|
||||
*dst++ = clr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RASOPS32 */
|
634
sys/dev/rasops/rasops8.c
Normal file
634
sys/dev/rasops/rasops8.c
Normal file
@ -0,0 +1,634 @@
|
||||
/* $NetBSD: rasops8.c,v 1.1 1999/04/13 00:18:01 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Andy Doran <ad@NetBSD.org>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opt_rasops.h"
|
||||
#ifdef RASOPS8
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.1 1999/04/13 00:18:01 ad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/rasops/rasops.h>
|
||||
|
||||
static void rasops8_putchar __P((void *, int, int, u_int, long attr));
|
||||
static void rasops8_putchar8 __P((void *, int, int, u_int, long attr));
|
||||
static void rasops8_putchar12 __P((void *, int, int, u_int, long attr));
|
||||
static void rasops8_putchar16 __P((void *, int, int, u_int, long attr));
|
||||
static void rasops8_erasecols __P((void *, int, int, int, long));
|
||||
static void rasops8_eraserows __P((void *, int, int, long));
|
||||
static void rasops8_makestamp __P((long));
|
||||
static int32_t rasops8_bg_color __P((long));
|
||||
static void rasops8_do_cursor __P((struct rasops_info *));
|
||||
void rasops8_init __P((struct rasops_info *ri));
|
||||
|
||||
/*
|
||||
* 4x1 stamp for optimized character blitting
|
||||
*/
|
||||
static int32_t stamp[16];
|
||||
static long stamp_attr;
|
||||
static int stamp_mutex; /* XXX see note in README */
|
||||
|
||||
/*
|
||||
* XXX this confuses the hell out of gcc2 (not egcs) which always insists
|
||||
* that the shift count is negative.
|
||||
*
|
||||
* offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
|
||||
* destination = STAMP_READ(offset)
|
||||
*/
|
||||
#define STAMP_SHIFT(fb,n) ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
|
||||
#define STAMP_MASK (15 << 2)
|
||||
#define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
|
||||
|
||||
|
||||
/*
|
||||
* Initalize a 'rasops_info' descriptor for this depth.
|
||||
*/
|
||||
void
|
||||
rasops8_init(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
|
||||
switch (ri->ri_font->fontwidth) {
|
||||
case 8:
|
||||
ri->ri_ops.putchar = rasops8_putchar8;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
ri->ri_ops.putchar = rasops8_putchar12;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
ri->ri_ops.putchar = rasops8_putchar16;
|
||||
break;
|
||||
|
||||
default:
|
||||
ri->ri_ops.putchar = rasops8_putchar;
|
||||
break;
|
||||
}
|
||||
|
||||
ri->ri_ops.erasecols = rasops8_erasecols;
|
||||
ri->ri_ops.eraserows = rasops8_eraserows;
|
||||
ri->ri_do_cursor = rasops8_do_cursor;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get background color from attribute and copy across all 4 bytes
|
||||
* of an int32_t.
|
||||
*/
|
||||
static __inline__ int32_t
|
||||
rasops8_bg_color(attr)
|
||||
long attr;
|
||||
{
|
||||
int32_t bg;
|
||||
|
||||
bg = ((int32_t)attr >> 16) & 15;
|
||||
return bg | (bg << 8) | (bg << 16) | (bg << 24);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actually turn the cursor on or off. This does the dirty work for
|
||||
* rasops_cursor().
|
||||
*/
|
||||
static void
|
||||
rasops8_do_cursor(ri)
|
||||
struct rasops_info *ri;
|
||||
{
|
||||
u_char *dp, *rp;
|
||||
int full1, height, cnt, slop1, slop2, row, col;
|
||||
|
||||
row = ri->ri_crow;
|
||||
col = ri->ri_ccol;
|
||||
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
slop1 = (int)rp & 3;
|
||||
slop2 = (ri->ri_xscale - slop1) & 3;
|
||||
full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = slop1; cnt; cnt--)
|
||||
*dp++ ^= 0xff;
|
||||
|
||||
for (cnt = full1; cnt; cnt--) {
|
||||
*(int32_t *)dp ^= 0xffffffff;
|
||||
dp += 4;
|
||||
}
|
||||
|
||||
for (cnt = slop2; cnt; cnt--)
|
||||
*dp++ ^= 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character.
|
||||
*/
|
||||
static void
|
||||
rasops8_putchar(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
u_char *dp, *rp, *fr, clr[2];
|
||||
int width, height, cnt, fs, fb;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
/* Catches 'row < 0' case too */
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols)
|
||||
return;
|
||||
#endif
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
|
||||
height = ri->ri_font->fontheight;
|
||||
width = ri->ri_font->fontwidth;
|
||||
clr[0] = (u_char)(attr >> 16);
|
||||
clr[1] = (u_char)(attr >> 24);
|
||||
|
||||
if (uc == ' ') {
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = width; cnt; cnt--)
|
||||
*dp++ = clr[0];
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
dp = rp;
|
||||
fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
|
||||
fr += fs;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
for (cnt = width; cnt; cnt--) {
|
||||
*dp++ = clr[(fb >> 31) & 1];
|
||||
fb <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do underline */
|
||||
if (attr & 1) {
|
||||
rp -= (ri->ri_stride << 1);
|
||||
|
||||
while (width--)
|
||||
*rp++ = clr[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Recompute the 4x1 blitting stamp.
|
||||
*/
|
||||
static void
|
||||
rasops8_makestamp(long attr)
|
||||
{
|
||||
int i;
|
||||
int32_t fg, bg;
|
||||
|
||||
fg = (attr >> 24) & 15;
|
||||
bg = (attr >> 16) & 15;
|
||||
stamp_attr = attr;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
stamp[i] = (i & 8 ? fg : bg);
|
||||
stamp[i] |= ((i & 4 ? fg : bg) << 8);
|
||||
stamp[i] |= ((i & 2 ? fg : bg) << 16);
|
||||
stamp[i] |= ((i & 1 ? fg : bg) << 24);
|
||||
#else
|
||||
stamp[i] = (i & 1 ? fg : bg);
|
||||
stamp[i] |= ((i & 2 ? fg : bg) << 8);
|
||||
stamp[i] |= ((i & 4 ? fg : bg) << 16);
|
||||
stamp[i] |= ((i & 8 ? fg : bg) << 24);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 8-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops8_putchar8(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int height, fs;
|
||||
int32_t *rp;
|
||||
u_char *fr;
|
||||
|
||||
/* Can't risk remaking the stamp if it's already in use */
|
||||
if (stamp_mutex++) {
|
||||
stamp_mutex--;
|
||||
rasops8_putchar(cookie, row, col, uc, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recompute stamp? */
|
||||
if (attr != stamp_attr)
|
||||
rasops8_makestamp(attr);
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
if (uc == ' ') {
|
||||
while (height--) {
|
||||
rp[0] = stamp[0];
|
||||
rp[1] = stamp[0];
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
|
||||
rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
|
||||
|
||||
fr += fs;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do underline */
|
||||
if (attr & 1) {
|
||||
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
|
||||
rp[0] = stamp[15];
|
||||
rp[1] = stamp[15];
|
||||
}
|
||||
|
||||
stamp_mutex--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 12-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops8_putchar12(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int height, fs;
|
||||
int32_t *rp;
|
||||
u_char *fr;
|
||||
|
||||
/* Can't risk remaking the stamp if it's already in use */
|
||||
if (stamp_mutex++) {
|
||||
stamp_mutex--;
|
||||
rasops8_putchar(cookie, row, col, uc, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recompute stamp? */
|
||||
if (attr != stamp_attr)
|
||||
rasops8_makestamp(attr);
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
if (uc == ' ') {
|
||||
while (height--) {
|
||||
rp[0] = stamp[0];
|
||||
rp[1] = stamp[0];
|
||||
rp[2] = stamp[0];
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
|
||||
rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
|
||||
rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
|
||||
|
||||
fr += fs;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do underline */
|
||||
if (attr & 1) {
|
||||
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
|
||||
rp[0] = stamp[15];
|
||||
rp[1] = stamp[15];
|
||||
rp[2] = stamp[15];
|
||||
}
|
||||
|
||||
stamp_mutex--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Paint a single character. This is for 16-pixel wide fonts.
|
||||
*/
|
||||
static void
|
||||
rasops8_putchar16(cookie, row, col, uc, attr)
|
||||
void *cookie;
|
||||
int row, col;
|
||||
u_int uc;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int height, fs;
|
||||
int32_t *rp;
|
||||
u_char *fr;
|
||||
|
||||
/* Can't risk remaking the stamp if it's already in use */
|
||||
if (stamp_mutex++) {
|
||||
stamp_mutex--;
|
||||
rasops8_putchar(cookie, row, col, uc, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)col >= (unsigned)ri->ri_cols) {
|
||||
stamp_mutex--;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recompute stamp? */
|
||||
if (attr != stamp_attr)
|
||||
rasops8_makestamp(attr);
|
||||
|
||||
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
if (uc == ' ') {
|
||||
while (height--) {
|
||||
rp[0] = stamp[0];
|
||||
rp[1] = stamp[0];
|
||||
rp[2] = stamp[0];
|
||||
rp[3] = stamp[0];
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
} else {
|
||||
uc -= ri->ri_font->firstchar;
|
||||
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
|
||||
fs = ri->ri_font->stride;
|
||||
|
||||
while (height--) {
|
||||
rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
|
||||
rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
|
||||
rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
|
||||
rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
|
||||
|
||||
fr += fs;
|
||||
DELTA(rp, ri->ri_stride, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do underline */
|
||||
if (attr & 1) {
|
||||
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
|
||||
rp[0] = stamp[15];
|
||||
rp[1] = stamp[15];
|
||||
rp[2] = stamp[15];
|
||||
rp[3] = stamp[15];
|
||||
}
|
||||
|
||||
stamp_mutex--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase rows.
|
||||
*/
|
||||
static void
|
||||
rasops8_eraserows(cookie, row, num, attr)
|
||||
void *cookie;
|
||||
int row, num;
|
||||
long attr;
|
||||
{
|
||||
struct rasops_info *ri;
|
||||
int32_t *dp, clr;
|
||||
int n8, n1, cnt;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if (row < 0) {
|
||||
num += row;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
if ((row + num) > ri->ri_rows)
|
||||
num = ri->ri_rows - row;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num *= ri->ri_font->fontheight;
|
||||
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
|
||||
clr = rasops8_bg_color(attr);
|
||||
|
||||
n8 = ri->ri_emustride >> 5;
|
||||
n1 = (ri->ri_emustride >> 2) & 7;
|
||||
|
||||
while (num--) {
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dp[0] = clr;
|
||||
dp[1] = clr;
|
||||
dp[2] = clr;
|
||||
dp[3] = clr;
|
||||
dp[4] = clr;
|
||||
dp[5] = clr;
|
||||
dp[6] = clr;
|
||||
dp[7] = clr;
|
||||
dp += 8;
|
||||
}
|
||||
|
||||
for (cnt = n1; cnt; cnt--)
|
||||
*dp++ = clr;
|
||||
|
||||
DELTA(dp, ri->ri_delta, int32_t *);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Erase columns.
|
||||
*/
|
||||
static void
|
||||
rasops8_erasecols(cookie, row, col, num, attr)
|
||||
void *cookie;
|
||||
int row, col, num;
|
||||
long attr;
|
||||
{
|
||||
int n8, clr, height, cnt, slop1, slop2;
|
||||
struct rasops_info *ri;
|
||||
int32_t *dst;
|
||||
u_char *dstb, *rp;
|
||||
|
||||
ri = (struct rasops_info *)cookie;
|
||||
|
||||
#ifdef RASOPS_CLIPPING
|
||||
if ((unsigned)row >= (unsigned)ri->ri_rows)
|
||||
return;
|
||||
|
||||
if (col < 0) {
|
||||
num += col;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if ((col + num) > ri->ri_cols)
|
||||
num = ri->ri_cols - col;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
num = num * ri->ri_xscale;
|
||||
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
|
||||
clr = rasops8_bg_color(attr);
|
||||
height = ri->ri_font->fontheight;
|
||||
|
||||
slop1 = (int)rp & 3;
|
||||
slop2 = (num - slop1) & 3;
|
||||
num -= slop1 + slop2;
|
||||
n8 = num >> 5;
|
||||
num = (num >> 2) & 7;
|
||||
|
||||
while (height--) {
|
||||
dstb = rp;
|
||||
rp += ri->ri_stride;
|
||||
|
||||
/* Align span to 4 bytes */
|
||||
for (cnt = slop1; cnt; cnt--)
|
||||
*dstb++ = (u_char)clr;
|
||||
|
||||
dst = (int32_t *)dstb;
|
||||
|
||||
/* Write 32 bytes per loop */
|
||||
for (cnt = n8; cnt; cnt--) {
|
||||
dst[0] = clr;
|
||||
dst[1] = clr;
|
||||
dst[2] = clr;
|
||||
dst[3] = clr;
|
||||
dst[4] = clr;
|
||||
dst[5] = clr;
|
||||
dst[6] = clr;
|
||||
dst[7] = clr;
|
||||
dst += 8;
|
||||
}
|
||||
|
||||
/* Write 4 bytes per loop */
|
||||
for (cnt = num; cnt; cnt--)
|
||||
*dst++ = clr;
|
||||
|
||||
/* Write unaligned trailing slop */
|
||||
if (slop2 == 0)
|
||||
continue;
|
||||
|
||||
dstb = (u_char *)dst;
|
||||
|
||||
for (cnt = slop2; cnt; cnt--)
|
||||
*dstb++ = (u_char)clr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RASOPS8 */
|
Loading…
Reference in New Issue
Block a user