2058 lines
54 KiB
C
2058 lines
54 KiB
C
/* $NetBSD: fb_sub.c,v 1.4 1998/08/21 14:52:29 tsubai Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 1992, 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to Berkeley by
|
|
* Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
|
|
*
|
|
* 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 University of
|
|
* California, Berkeley and its contributors.
|
|
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
|
*
|
|
* from: $Hdr: fb_sub.c,v 4.300 91/06/27 20:43:09 root Rel41 $ SONY
|
|
*
|
|
* @(#)fb_sub.c 8.2 (Berkeley) 9/23/93
|
|
*/
|
|
|
|
#include "fb.h"
|
|
#if NFB > 0
|
|
/*
|
|
* Frame buffer driver
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#include <sys/device.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/proc.h>
|
|
|
|
#include <machine/cpu.h>
|
|
#include <machine/framebuf.h>
|
|
#include <machine/locore.h>
|
|
|
|
#include <newsmips/dev/fbreg.h>
|
|
|
|
#ifdef CPU_DOUBLE
|
|
#ifdef IPC_MRX
|
|
#include "../ipc/newsipc.h"
|
|
#ifdef mips
|
|
#define ipc_phys(x) K0_TT0(x)
|
|
#define ipc_log(x) TT0_K0(x)
|
|
#else /* mips */
|
|
#define ipc_phys(x) (caddr_t)((int)(x) & ~0x80000000)
|
|
#define ipc_log(x) (caddr_t)((int)(x) | 0x80000000)
|
|
#endif /* mips */
|
|
#endif /* IPC_MRX */
|
|
#else /* CPU_DOUBLE */
|
|
#define ipc_phys(x) (caddr_t)((int)(x))
|
|
#define ipc_log(x) (caddr_t)((int)(x) | 0x80000000)
|
|
#endif /* CPU_DOUBLE */
|
|
|
|
#define MAX_FBMAP 3
|
|
static struct fb_map fbmap[MAX_FBMAP];
|
|
|
|
/* bitblt type */
|
|
#define BLTTYPE(ts, td) ((ts) << 2 | (td))
|
|
|
|
static lSrcDest srcdestlist[MAX_BATCHBITBLT];
|
|
#define MAX_SIZE (MAX_BATCHBITBLT * sizeof(lSrcDest))
|
|
|
|
#define ODD_ADDR(x) (((unsigned)(x))&1)
|
|
|
|
#ifdef NOTYET
|
|
#define MAXMSEG 4
|
|
static int segind;
|
|
static struct memseg {
|
|
caddr_t adrs;
|
|
int len;
|
|
int rw;
|
|
caddr_t oadrs;
|
|
int olen;
|
|
struct fb_map *map;
|
|
} mseg[MAXMSEG];
|
|
#endif /* NOTYET */
|
|
|
|
#define BASE(a) ((int)(a) & ~(NBPG - 1))
|
|
|
|
#define MIPS_KSEG0_TO_KSEG1(x) MIPS_PHYS_TO_KSEG1(x)
|
|
|
|
extern int fbstart();
|
|
extern void MachFlushDCache();
|
|
|
|
#ifdef CPU_DOUBLE
|
|
COPYIN(src, dst, len, seg)
|
|
caddr_t src;
|
|
caddr_t dst;
|
|
int len;
|
|
int seg;
|
|
{
|
|
|
|
switch (seg) {
|
|
case UIO_SYSSPACE:
|
|
bcopy(src, dst, len);
|
|
return (0);
|
|
case UIO_USERSPACE:
|
|
return (copyin(src, dst, len));
|
|
default:
|
|
panic("COPYIN: seg");
|
|
/* NOTREACHED */
|
|
}
|
|
}
|
|
#endif /* CPU_DOUBLE */
|
|
|
|
#ifdef NOTYET
|
|
fbgetmap(addr, len, map)
|
|
caddr_t addr;
|
|
int len;
|
|
struct fb_map *map;
|
|
{
|
|
register struct pte *pte;
|
|
register caddr_t *p;
|
|
unsigned v;
|
|
register int npf;
|
|
int o;
|
|
|
|
v = pmax_btop(addr);
|
|
o = (int)addr & PGOFSET;
|
|
npf = btoc(len + o);
|
|
if (npf > NFBMAP)
|
|
return (EINVAL);
|
|
|
|
map->fm_vaddr = addr;
|
|
map->fm_offset = o;
|
|
map->fm_count = len;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
if (addr >= (caddr_t)KERNBASE) {
|
|
#ifdef mips
|
|
p = map->fm_addr;
|
|
if (MACH_IS_CACHED(addr)) {
|
|
addr = ptob(v);
|
|
while (--npf >= 0) {
|
|
*p++ = (caddr_t)K0_TT0(addr);
|
|
addr += NBPG;
|
|
}
|
|
return (0);
|
|
}
|
|
if (MACH_IS_MAPPED(addr))
|
|
pte = kvtopte(addr);
|
|
else if (addr >= (caddr_t)&u)
|
|
pte = curproc->p_addr + btop(addr - (caddr_t)&u);
|
|
else
|
|
panic("fbgetmap: bad kernel addr");
|
|
while (--npf >= 0)
|
|
*p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));
|
|
#else /* mips */
|
|
pte = kvtopte(addr);
|
|
p = map->fm_addr;
|
|
while (--npf >= 0)
|
|
*p++ = (caddr_t)ptob(pte++->pg_pfnum);
|
|
#endif /* mips */
|
|
return (0);
|
|
}
|
|
pte = vtopte(curproc, v); /*KU:XXXXXXXXXXXXXXXXXX*/
|
|
p = map->fm_addr;
|
|
while (--npf >= 0) {
|
|
if (pte->pg_pfnum == 0)
|
|
panic("iop zero uentry");
|
|
#ifdef mips
|
|
*p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));
|
|
#else
|
|
*p++ = (caddr_t)ptob(pte++->pg_pfnum);
|
|
#endif
|
|
}
|
|
|
|
#endif /* CPU_DOUBLE */
|
|
return (0);
|
|
}
|
|
|
|
fblockmem(ad, len, rw, map, seg)
|
|
register caddr_t ad;
|
|
register int len;
|
|
int rw;
|
|
struct fb_map *map;
|
|
int seg;
|
|
{
|
|
register struct memseg *msp;
|
|
|
|
/* validity check */
|
|
if (len < 0)
|
|
return EFAULT;
|
|
else if (len == 0)
|
|
return 0;
|
|
else if (ad == 0)
|
|
return EFAULT;
|
|
else if (seg == UIO_USERSPACE &&
|
|
!useracc(ad, len, rw == B_READ ? B_WRITE : B_READ))
|
|
return EFAULT;
|
|
else if (segind >= MAXMSEG)
|
|
return EFAULT;
|
|
|
|
/* insertion sort */
|
|
for (msp = mseg + segind - 1; msp >= mseg; msp--) {
|
|
if (msp->adrs > ad)
|
|
*(msp + 1) = *msp;
|
|
else
|
|
break;
|
|
}
|
|
msp++;
|
|
#ifdef CPU_SINGLE
|
|
switch (seg) {
|
|
case UIO_SYSSPACE:
|
|
map->fm_vaddr = ad;
|
|
map->fm_offset = 0;
|
|
break;
|
|
case UIO_USERSPACE:
|
|
msp->adrs = (caddr_t)BASE(ad);
|
|
msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;
|
|
break;
|
|
default:
|
|
panic("fblockmem: seg");
|
|
/* NOTREACHED */
|
|
}
|
|
#else /* CPU_SINGLE */
|
|
msp->adrs = (caddr_t)BASE(ad);
|
|
msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;
|
|
#endif /* CPU_SINGLE */
|
|
msp->rw = rw;
|
|
msp->oadrs = ad;
|
|
msp->olen = len;
|
|
msp->map = map;
|
|
segind++;
|
|
|
|
return (0);
|
|
}
|
|
|
|
fblocksbitmap(bm, rw, map)
|
|
register lBitmap *bm;
|
|
int rw;
|
|
struct fb_map *map;
|
|
{
|
|
register int len;
|
|
register int error = 0;
|
|
|
|
if (bm->depth > 32)
|
|
return EINVAL;
|
|
if (bm->type == BM_FB || bm->type == BM_0 || bm->type == BM_1)
|
|
return 0;
|
|
if (bm->type == BM_MEM)
|
|
len = bm->width * bm->rect.extent.y * bm->depth * sizeof(Word);
|
|
if (len < 0 || len > FB_MAX_IO)
|
|
return(EINVAL);
|
|
error = fblockmem((caddr_t)(bm->base), len, rw, map, UIO_USERSPACE);
|
|
if (error)
|
|
return error;
|
|
|
|
bm->base = (Word *)ipc_phys(map);
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
fbinitlock()
|
|
{
|
|
segind = 0;
|
|
}
|
|
|
|
void
|
|
fbdolock()
|
|
{
|
|
register struct memseg *msp0, *msp1, *mspl;
|
|
register int i, tlen;
|
|
|
|
mspl = mseg + segind;
|
|
for (msp0 = mseg, msp1 = mseg + 1; msp1 < mspl; msp0++, msp1++) {
|
|
if (msp0->adrs + msp0->len > msp1->adrs) {
|
|
tlen = msp1->adrs - msp0->adrs + msp1->len;
|
|
msp1->adrs = msp0->adrs;
|
|
msp1->len = msp0->len > tlen ? msp0->len : tlen;
|
|
msp0->len = 0;
|
|
msp1->rw = (msp0->rw == B_READ || msp1->rw == B_READ) ?
|
|
B_READ : B_WRITE;
|
|
}
|
|
}
|
|
|
|
/* lock */
|
|
curproc->p_flag |= P_PHYSIO;
|
|
for (i = 0; i < segind; i++)
|
|
if (mseg[i].len && mseg[i].adrs && mseg[i].adrs
|
|
< (caddr_t)KERNBASE)
|
|
vslock(curproc, mseg[i].adrs, mseg[i].len);
|
|
|
|
/* make map */
|
|
for (i = 0; i < segind; i++)
|
|
fbgetmap(mseg[i].oadrs, mseg[i].olen, mseg[i].map);
|
|
}
|
|
|
|
void
|
|
fbunlock()
|
|
{
|
|
register int i;
|
|
int s = splfb();
|
|
|
|
for (i = 0; i < segind; i++) {
|
|
if (mseg[i].len && mseg[i].adrs && mseg[i].adrs
|
|
< (caddr_t)KERNBASE) {
|
|
vsunlock(curproc, mseg[i].adrs, mseg[i].len, mseg[i].rw);
|
|
#if defined(mips) && defined(CPU_DOUBLE)
|
|
if (mseg[i].rw == B_READ)
|
|
clean_kudcache(curproc,
|
|
mseg[i].adrs, mseg[i].len);
|
|
#endif
|
|
}
|
|
}
|
|
curproc->p_flag &= ~P_PHYSIO;
|
|
splx(s);
|
|
|
|
/* for 'fbinitlock() o wasureru ukkariyasan'... */
|
|
segind = 0;
|
|
}
|
|
#endif /* NOTYET */
|
|
|
|
int
|
|
checkbitmap(bm)
|
|
register lBitmap *bm;
|
|
{
|
|
if (bm->depth > 32)
|
|
return EINVAL;
|
|
|
|
switch(bm->type) {
|
|
case BM_FB:
|
|
case BM_0:
|
|
case BM_1:
|
|
break;
|
|
case BM_MEM:
|
|
if (ODD_ADDR(bm->base))
|
|
return EINVAL;
|
|
if (bm->width == 0)
|
|
return EINVAL;
|
|
if ((bm->width * bm->rect.extent.y) << 1 > FB_MAX_IO)
|
|
return EINVAL;
|
|
break;
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
|
|
if (bm->rect.extent.x < 0 || bm->rect.extent.y < 0)
|
|
return EINVAL;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
checkdepth(sbm, dbm)
|
|
lBitmap *sbm, *dbm;
|
|
{
|
|
register int ds = sbm->depth;
|
|
register int dd = dbm->depth;
|
|
|
|
if (ds > 1 && dd > 1 && ds != dd)
|
|
return -1;
|
|
else
|
|
return((ds > 1) << 1 | (dd > 1));
|
|
}
|
|
|
|
#ifdef NOTYET
|
|
dobitblt(fbp, sbm, dbm)
|
|
struct fbreg *fbp;
|
|
lBitmap *sbm, *dbm;
|
|
{
|
|
register int error;
|
|
|
|
if (error = fblocksbitmap(sbm, B_WRITE, fbmap))
|
|
return error;
|
|
if (error = fblocksbitmap(dbm, B_READ, fbmap + 1))
|
|
return error;
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
|
|
/* reset address */
|
|
if (sbm->type == BM_MEM)
|
|
sbm->base =
|
|
(Word *)((struct fb_map *)ipc_log(sbm->base))->fm_vaddr;
|
|
if (dbm->type == BM_MEM)
|
|
dbm->base =
|
|
(Word *)((struct fb_map *)ipc_log(dbm->base))->fm_vaddr;
|
|
return 0;
|
|
}
|
|
|
|
fbnbitblt(fbp, cmd)
|
|
register struct fbreg *fbp;
|
|
register lBitblt *cmd;
|
|
{
|
|
register lBitblt *regcmd;
|
|
register int len, lens, lend;
|
|
register int i;
|
|
int pmask, mode;
|
|
int error = 0;
|
|
int blttype = BLTTYPE(cmd->srcBitmap.type, cmd->destBitmap.type);
|
|
|
|
#ifdef CPU_DOUBLE
|
|
if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_0, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_1, BM_MEM))) {
|
|
return(mfbnbitblt(fbp, cmd));
|
|
/* NOTREACHED */
|
|
}
|
|
#endif
|
|
|
|
fbinitlock();
|
|
if (error = checkbitmap(&cmd->srcBitmap))
|
|
return error;
|
|
if (error = checkbitmap(&cmd->destBitmap))
|
|
return error;
|
|
if ((mode = checkdepth(&cmd->srcBitmap, &cmd->destBitmap)) < 0)
|
|
return EINVAL;
|
|
|
|
fbp->fb_command = FB_CBITBLT;
|
|
fbp->fb_bitblt = *cmd;
|
|
regcmd = &fbp->fb_bitblt;
|
|
|
|
/* process bitblt command */
|
|
switch (blttype) {
|
|
case BLTTYPE(BM_FB, BM_FB):
|
|
case BLTTYPE(BM_0, BM_FB):
|
|
case BLTTYPE(BM_1, BM_FB):
|
|
fbstart(fbp, 0);
|
|
break;
|
|
|
|
case BLTTYPE(BM_FB, BM_MEM):
|
|
case BLTTYPE(BM_0, BM_MEM):
|
|
case BLTTYPE(BM_1, BM_MEM):
|
|
len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
|
|
if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
/* bitblt each plane */
|
|
regcmd->destBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
for (i = 0; i < cmd->destBitmap.depth; i++) {
|
|
if (mode == 3) /* N to N */
|
|
regcmd->planemask = pmask & (1 << i);
|
|
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
|
|
regcmd->destBitmap.base += len >> 1;
|
|
if (mode == 1) { /* N to N */
|
|
regcmd->planemask >>= 1;
|
|
regcmd->fore_color >>= 1;
|
|
regcmd->aux_color >>= 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BLTTYPE(BM_MEM, BM_FB):
|
|
len = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
|
|
|
|
if (len * cmd->srcBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
/* bitblt each plane */
|
|
regcmd->srcBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
if (mode == 2) { /* N to 1 */
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++)
|
|
if (pmask & (1 << i))
|
|
break;
|
|
if (i >= cmd->srcBitmap.depth)
|
|
return 0;
|
|
regcmd->srcBitmap.base += (len >> 1) * i;
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
/* else (N to N) */
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++) {
|
|
regcmd->planemask = pmask & (1 << i);
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->srcBitmap.base += len >> 1;
|
|
regcmd->planemask >>= 1;
|
|
}
|
|
return 0;
|
|
|
|
case BLTTYPE(BM_MEM, BM_MEM):
|
|
lens = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
|
|
lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
|
|
if (lens * cmd->srcBitmap.depth <= FB_MAX_IO &&
|
|
lend * cmd->destBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
regcmd->srcBitmap.depth = 1;
|
|
regcmd->destBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
if (mode == 2) { /* N to 1 */
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++)
|
|
if (pmask & (1 << i))
|
|
break;
|
|
if (i >= cmd->srcBitmap.depth)
|
|
return 0;
|
|
regcmd->srcBitmap.base += (lens >> 1) * i;
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
} else if (mode == 1) { /* 1 to N */
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++) {
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->planemask >>= 1;
|
|
regcmd->fore_color >>= 1;
|
|
regcmd->aux_color >>= 1;
|
|
regcmd->destBitmap.base += lend >> 1;
|
|
}
|
|
return 0;
|
|
} else { /* N to N */
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++) {
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->srcBitmap.base += lens >> 1;
|
|
regcmd->destBitmap.base += lend >> 1;
|
|
regcmd->planemask >>= 1;
|
|
}
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
fbbitblt(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sBitblt *cmd;
|
|
{
|
|
lBitblt lcmd;
|
|
register lBitblt *lcmdp;
|
|
|
|
lcmdp = &lcmd;
|
|
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->srcBitmap.type = cmd->srcBitmap.type;
|
|
lcmdp->srcBitmap.depth = cmd->srcBitmap.depth;
|
|
lcmdp->srcBitmap.width = cmd->srcBitmap.width;
|
|
lcmdp->srcBitmap.rect.origin.x = cmd->srcBitmap.rect.origin.x;
|
|
lcmdp->srcBitmap.rect.origin.y = cmd->srcBitmap.rect.origin.y;
|
|
lcmdp->srcBitmap.rect.extent.x = cmd->srcBitmap.rect.extent.x;
|
|
lcmdp->srcBitmap.rect.extent.y = cmd->srcBitmap.rect.extent.y;
|
|
lcmdp->srcBitmap.base = cmd->srcBitmap.base;
|
|
lcmdp->srcRect.origin.x = cmd->srcRect.origin.x;
|
|
lcmdp->srcRect.origin.y = cmd->srcRect.origin.y;
|
|
lcmdp->srcRect.extent.x = cmd->srcRect.extent.x;
|
|
lcmdp->srcRect.extent.y = cmd->srcRect.extent.y;
|
|
lcmdp->destBitmap.type = cmd->destBitmap.type;
|
|
lcmdp->destBitmap.depth = cmd->destBitmap.depth;
|
|
lcmdp->destBitmap.width = cmd->destBitmap.width;
|
|
lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
|
|
lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
|
|
lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
|
|
lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
|
|
lcmdp->destBitmap.base = cmd->destBitmap.base;
|
|
lcmdp->destClip.origin.x = cmd->destClip.origin.x;
|
|
lcmdp->destClip.origin.y = cmd->destClip.origin.y;
|
|
lcmdp->destClip.extent.x = cmd->destClip.extent.x;
|
|
lcmdp->destClip.extent.y = cmd->destClip.extent.y;
|
|
lcmdp->destPoint.x = cmd->destPoint.x;
|
|
lcmdp->destPoint.y = cmd->destPoint.y;
|
|
return (fbnbitblt(fbp, lcmdp));
|
|
}
|
|
|
|
procbatchbitblt(fbp, mode, cmd)
|
|
struct fbreg *fbp;
|
|
int mode;
|
|
register lBatchBitblt *cmd;
|
|
{
|
|
register lBatchBitblt *regcmd;
|
|
register int len, lens, lend;
|
|
register int i;
|
|
int pmask;
|
|
int error = 0;
|
|
|
|
regcmd = &fbp->fb_batchbitblt;
|
|
/* process batch bitblt command */
|
|
switch (BLTTYPE(regcmd->srcBitmap.type, regcmd->destBitmap.type)) {
|
|
case BLTTYPE(BM_FB, BM_FB):
|
|
case BLTTYPE(BM_0, BM_FB):
|
|
case BLTTYPE(BM_1, BM_FB):
|
|
fbdolock();
|
|
fbstart(fbp, cmd->nSrcDest);
|
|
fbunlock();
|
|
break;
|
|
|
|
case BLTTYPE(BM_FB, BM_MEM):
|
|
case BLTTYPE(BM_0, BM_MEM):
|
|
case BLTTYPE(BM_1, BM_MEM):
|
|
len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
|
|
if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
/* bitblt each plane */
|
|
regcmd->destBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
for (i = 0; i < cmd->destBitmap.depth; i++) {
|
|
if (mode == 3) /* N to N */
|
|
regcmd->planemask = pmask & (1 << i);
|
|
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
|
|
regcmd->destBitmap.base += len >> 1;
|
|
if (mode == 1) { /* N to N */
|
|
regcmd->planemask >>= 1;
|
|
regcmd->fore_color >>= 1;
|
|
regcmd->aux_color >>= 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BLTTYPE(BM_MEM, BM_FB):
|
|
len = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
|
|
|
|
if (len * cmd->srcBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
/* bitblt each plane */
|
|
regcmd->srcBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
if (mode == 2) { /* N to 1 */
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++)
|
|
if (pmask & (1 << i))
|
|
break;
|
|
if (i >= cmd->srcBitmap.depth)
|
|
return 0;
|
|
regcmd->srcBitmap.base += (len >> 1) * i;
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
/* else (N to N) */
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++) {
|
|
regcmd->planemask = pmask & (1 << i);
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->srcBitmap.base += len >> 1;
|
|
regcmd->planemask >>= 1;
|
|
}
|
|
return 0;
|
|
|
|
case BLTTYPE(BM_MEM, BM_MEM):
|
|
lens = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
|
|
lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
|
|
if (lens * cmd->srcBitmap.depth <= FB_MAX_IO &&
|
|
lend * cmd->destBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
regcmd->srcBitmap.depth = 1;
|
|
regcmd->destBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
if (mode == 2) { /* N to 1 */
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++)
|
|
if (pmask & (1 << i))
|
|
break;
|
|
if (i >= cmd->srcBitmap.depth)
|
|
return 0;
|
|
regcmd->srcBitmap.base += (lens >> 1) * i;
|
|
error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
} else if (mode == 1) { /* 1 to N */
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++) {
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->planemask >>= 1;
|
|
regcmd->fore_color >>= 1;
|
|
regcmd->aux_color >>= 1;
|
|
regcmd->destBitmap.base += lend >> 1;
|
|
}
|
|
return 0;
|
|
} else { /* N to N */
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
for (i = 0; i < cmd->srcBitmap.depth; i++) {
|
|
if (error = dobitblt(fbp, ®cmd->srcBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->srcBitmap.base += lens >> 1;
|
|
regcmd->destBitmap.base += lend >> 1;
|
|
regcmd->planemask >>= 1;
|
|
}
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
fbnbatchbitblt(fbp, cmd, seg)
|
|
register struct fbreg *fbp;
|
|
register lBatchBitblt *cmd;
|
|
int seg;
|
|
{
|
|
register int error;
|
|
register int mode;
|
|
register int len;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
int blttype = BLTTYPE(cmd->srcBitmap.type, cmd->destBitmap.type);
|
|
|
|
if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_0, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_1, BM_MEM))) {
|
|
return(mfbnbatchbitblt(fbp, cmd, seg));
|
|
/* notreached */
|
|
}
|
|
#endif
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CBATCHBITBLT;
|
|
fbp->fb_batchbitblt = *cmd;
|
|
|
|
if (error = checkbitmap(&cmd->srcBitmap))
|
|
return error;
|
|
if (error = checkbitmap(&cmd->destBitmap))
|
|
return error;
|
|
if ((mode = checkdepth(&cmd->srcBitmap, &cmd->destBitmap)) < 0)
|
|
return EINVAL;
|
|
|
|
#ifdef CPU_SINGLE
|
|
if ((len = cmd->nSrcDest * sizeof(lSrcDest)) <= 0)
|
|
return EINVAL;
|
|
if (error = fblockmem((caddr_t)cmd->srcDestList,
|
|
len, B_WRITE, fbmap + 2, seg))
|
|
return error;
|
|
fbp->fb_batchbitblt.srcDestList = (lSrcDest *)ipc_phys(fbmap + 2);
|
|
error = procbatchbitblt(fbp, mode, cmd);
|
|
#else
|
|
fbp->fb_batchbitblt.srcDestList = (lSrcDest*)ipc_phys(srcdestlist);
|
|
while(cmd->nSrcDest > 0) {
|
|
len = min(cmd->nSrcDest, (MAX_SIZE / sizeof(lSrcDest)));
|
|
error = COPYIN((caddr_t)cmd->srcDestList, (caddr_t)srcdestlist,
|
|
len * sizeof(lSrcDest), seg);
|
|
if (error)
|
|
return error;
|
|
cmd->nSrcDest -= len;
|
|
cmd->srcDestList += len;
|
|
fbp->fb_batchbitblt.nSrcDest = len;
|
|
|
|
if (error = procbatchbitblt(fbp, mode, cmd))
|
|
return error;
|
|
}
|
|
#endif /* CPU_DOUBLE */
|
|
return error;
|
|
}
|
|
|
|
fbbatchbitblt(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sBatchBitblt *cmd;
|
|
{
|
|
lBatchBitblt lcmd;
|
|
register lBatchBitblt *lcmdp;
|
|
static lSrcDest ls[100];
|
|
register lSrcDest *lp;
|
|
register sSrcDest *sp;
|
|
register int ns;
|
|
|
|
lcmdp = &lcmd;
|
|
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->srcBitmap.type = cmd->srcBitmap.type;
|
|
lcmdp->srcBitmap.depth = cmd->srcBitmap.depth;
|
|
lcmdp->srcBitmap.width = cmd->srcBitmap.width;
|
|
lcmdp->srcBitmap.rect.origin.x = cmd->srcBitmap.rect.origin.x;
|
|
lcmdp->srcBitmap.rect.origin.y = cmd->srcBitmap.rect.origin.y;
|
|
lcmdp->srcBitmap.rect.extent.x = cmd->srcBitmap.rect.extent.x;
|
|
lcmdp->srcBitmap.rect.extent.y = cmd->srcBitmap.rect.extent.y;
|
|
lcmdp->srcBitmap.base = cmd->srcBitmap.base;
|
|
lcmdp->destBitmap.type = cmd->destBitmap.type;
|
|
lcmdp->destBitmap.depth = cmd->destBitmap.depth;
|
|
lcmdp->destBitmap.width = cmd->destBitmap.width;
|
|
lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
|
|
lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
|
|
lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
|
|
lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
|
|
lcmdp->destBitmap.base = cmd->destBitmap.base;
|
|
lcmdp->destClip.origin.x = cmd->destClip.origin.x;
|
|
lcmdp->destClip.origin.y = cmd->destClip.origin.y;
|
|
lcmdp->destClip.extent.x = cmd->destClip.extent.x;
|
|
lcmdp->destClip.extent.y = cmd->destClip.extent.y;
|
|
lcmdp->srcDestList = ls;
|
|
sp = (sSrcDest *)cmd->srcDestList;
|
|
while (cmd->nSrcDest) {
|
|
lcmdp->nSrcDest = ns = min(cmd->nSrcDest, 100);
|
|
cmd->nSrcDest -= ns;
|
|
lp = ls;
|
|
while (ns-- > 0) {
|
|
int error;
|
|
sSrcDest tmp;
|
|
|
|
error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof(tmp));
|
|
if (error)
|
|
return (error);
|
|
lp->srcRect.origin.x = tmp.srcRect.origin.x;
|
|
lp->srcRect.origin.y = tmp.srcRect.origin.y;
|
|
lp->srcRect.extent.x = tmp.srcRect.extent.x;
|
|
lp->srcRect.extent.y = tmp.srcRect.extent.y;
|
|
lp->destPoint.x = tmp.destPoint.x;
|
|
lp->destPoint.y = tmp.destPoint.y;
|
|
lp++;
|
|
sp++;
|
|
}
|
|
fbnbatchbitblt(fbp, lcmdp, UIO_SYSSPACE);
|
|
}
|
|
}
|
|
|
|
fbntilebitblt(fbp, cmd)
|
|
register struct fbreg *fbp;
|
|
register lTileBitblt *cmd;
|
|
{
|
|
register lTileBitblt *regcmd;
|
|
register int len, lens, lend;
|
|
register int i;
|
|
int mode;
|
|
int pmask;
|
|
int error;
|
|
int blttype = BLTTYPE(cmd->ptnBitmap.type, cmd->destBitmap.type);
|
|
|
|
#ifdef CPU_DOUBLE
|
|
if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_0, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_1, BM_MEM))) {
|
|
return(mfbntilebitblt(fbp, cmd));
|
|
/* NOTREACHED */
|
|
}
|
|
#endif
|
|
|
|
if (error = checkbitmap(&cmd->ptnBitmap))
|
|
return error;
|
|
if (error = checkbitmap(&cmd->destBitmap))
|
|
return error;
|
|
if ((mode = checkdepth(&cmd->ptnBitmap, &cmd->destBitmap)) < 0)
|
|
return EINVAL;
|
|
|
|
fbp->fb_command = FB_CTILEBITBLT;
|
|
fbp->fb_tilebitblt = *cmd;
|
|
regcmd = &fbp->fb_tilebitblt;
|
|
|
|
/* process bitblt command */
|
|
switch (blttype) {
|
|
case BLTTYPE(BM_FB, BM_FB):
|
|
case BLTTYPE(BM_0, BM_FB):
|
|
case BLTTYPE(BM_1, BM_FB):
|
|
fbstart(fbp, 0);
|
|
break;
|
|
|
|
case BLTTYPE(BM_FB, BM_MEM):
|
|
case BLTTYPE(BM_0, BM_MEM):
|
|
case BLTTYPE(BM_1, BM_MEM):
|
|
len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
|
|
if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
/* bitblt each plane */
|
|
regcmd->destBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
for (i = 0; i < cmd->destBitmap.depth; i++) {
|
|
if (mode == 3) /* N to N */
|
|
regcmd->planemask = pmask & (1 << i);
|
|
|
|
if (error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
|
|
regcmd->destBitmap.base += len >> 1;
|
|
if (mode == 1) { /* N to N */
|
|
regcmd->planemask >>= 1;
|
|
regcmd->fore_color >>= 1;
|
|
regcmd->aux_color >>= 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BLTTYPE(BM_MEM, BM_FB):
|
|
len = cmd->ptnBitmap.width * cmd->ptnBitmap.rect.extent.y << 1;
|
|
|
|
if (len * cmd->ptnBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
/* bitblt each plane */
|
|
regcmd->ptnBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
if (mode == 2) { /* N to 1 */
|
|
for (i = 0; i < cmd->ptnBitmap.depth; i++)
|
|
if (pmask & (1 << i))
|
|
break;
|
|
if (i >= cmd->ptnBitmap.depth)
|
|
return 0;
|
|
regcmd->ptnBitmap.base += (len >> 1) * i;
|
|
error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
/* else (N to N) */
|
|
for (i = 0; i < cmd->ptnBitmap.depth; i++) {
|
|
regcmd->planemask = pmask & (1 << i);
|
|
if (error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->ptnBitmap.base += len >> 1;
|
|
regcmd->planemask >>= 1;
|
|
}
|
|
return 0;
|
|
|
|
case BLTTYPE(BM_MEM, BM_MEM):
|
|
lens = cmd->ptnBitmap.width * cmd->ptnBitmap.rect.extent.y << 1;
|
|
lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
|
|
if (lens * cmd->ptnBitmap.depth <= FB_MAX_IO &&
|
|
lend * cmd->destBitmap.depth <= FB_MAX_IO) {
|
|
error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
}
|
|
|
|
regcmd->ptnBitmap.depth = 1;
|
|
regcmd->destBitmap.depth = 1;
|
|
pmask = regcmd->planemask;
|
|
if (mode == 2) { /* N to 1 */
|
|
regcmd->fore_color = 0xff;
|
|
regcmd->aux_color = 0;
|
|
for (i = 0; i < cmd->ptnBitmap.depth; i++)
|
|
if (pmask & (1 << i))
|
|
break;
|
|
if (i >= cmd->ptnBitmap.depth)
|
|
return 0;
|
|
regcmd->ptnBitmap.base += (lens >> 1) * i;
|
|
error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap);
|
|
return error;
|
|
} else if (mode == 1) { /* 1 to N */
|
|
for (i = 0; i < cmd->ptnBitmap.depth; i++) {
|
|
if (error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->planemask >>= 1;
|
|
regcmd->fore_color >>= 1;
|
|
regcmd->aux_color >>= 1;
|
|
regcmd->destBitmap.base += lend >> 1;
|
|
}
|
|
return 0;
|
|
} else { /* N to N */
|
|
for (i = 0; i < cmd->ptnBitmap.depth; i++) {
|
|
if (error = dobitblt(fbp, ®cmd->ptnBitmap,
|
|
®cmd->destBitmap))
|
|
return error;
|
|
regcmd->ptnBitmap.base += lens >> 1;
|
|
regcmd->destBitmap.base += lend >> 1;
|
|
regcmd->planemask >>= 1;
|
|
}
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
fbtilebitblt(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sTileBitblt *cmd;
|
|
{
|
|
lTileBitblt lcmd;
|
|
register lTileBitblt *lcmdp;
|
|
|
|
lcmdp = &lcmd;
|
|
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->ptnBitmap.type = cmd->ptnBitmap.type;
|
|
lcmdp->ptnBitmap.depth = cmd->ptnBitmap.depth;
|
|
lcmdp->ptnBitmap.width = cmd->ptnBitmap.width;
|
|
lcmdp->ptnBitmap.rect.origin.x = cmd->ptnBitmap.rect.origin.x;
|
|
lcmdp->ptnBitmap.rect.origin.y = cmd->ptnBitmap.rect.origin.y;
|
|
lcmdp->ptnBitmap.rect.extent.x = cmd->ptnBitmap.rect.extent.x;
|
|
lcmdp->ptnBitmap.rect.extent.y = cmd->ptnBitmap.rect.extent.y;
|
|
lcmdp->ptnBitmap.base = cmd->ptnBitmap.base;
|
|
lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
|
|
lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
|
|
lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
|
|
lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
|
|
lcmdp->refPoint.x = cmd->refPoint.x;
|
|
lcmdp->refPoint.y = cmd->refPoint.y;
|
|
lcmdp->destBitmap.type = cmd->destBitmap.type;
|
|
lcmdp->destBitmap.depth = cmd->destBitmap.depth;
|
|
lcmdp->destBitmap.width = cmd->destBitmap.width;
|
|
lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
|
|
lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
|
|
lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
|
|
lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
|
|
lcmdp->destBitmap.base = cmd->destBitmap.base;
|
|
lcmdp->destClip.origin.x = cmd->destClip.origin.x;
|
|
lcmdp->destClip.origin.y = cmd->destClip.origin.y;
|
|
lcmdp->destClip.extent.x = cmd->destClip.extent.x;
|
|
lcmdp->destClip.extent.y = cmd->destClip.extent.y;
|
|
lcmdp->destRect.origin.x = cmd->destRect.origin.x;
|
|
lcmdp->destRect.origin.y = cmd->destRect.origin.y;
|
|
lcmdp->destRect.extent.x = cmd->destRect.extent.x;
|
|
lcmdp->destRect.extent.y = cmd->destRect.extent.y;
|
|
return (fbntilebitblt(fbp, lcmdp));
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
fbbitblt3(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
sBitblt3 *cmd;
|
|
{
|
|
return ENXIO;
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
fbnbitblt3(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
lBitblt3 *cmd;
|
|
{
|
|
return ENXIO;
|
|
}
|
|
|
|
fbnpolyline(fbp, cmd, dj, seg)
|
|
struct fbreg *fbp;
|
|
register lPrimLine *cmd;
|
|
int dj; /* if not zero, disjoint polyline */
|
|
int seg;
|
|
{
|
|
register int error = 0;
|
|
register int len;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
if(cmd->drawBM.type == BM_MEM) {
|
|
return(mfbnpolyline(fbp, cmd, dj, seg));
|
|
/* NOTREACHED */
|
|
}
|
|
#endif
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = dj ? FB_CDJPOLYLINE : FB_CPOLYLINE;
|
|
fbp->fb_polyline = *cmd;
|
|
|
|
if ((cmd->np & 1) && dj)
|
|
return EINVAL;
|
|
|
|
#ifdef CPU_SINGLE
|
|
if (error = fblocksbitmap(&fbp->fb_polyline.drawBM, B_READ, fbmap))
|
|
return error;
|
|
if ((len = cmd->np * sizeof(lPoint)) <= 0)
|
|
return EINVAL;
|
|
error = fblockmem((caddr_t)cmd->plist, len, B_WRITE, fbmap + 1, seg);
|
|
if (error)
|
|
return error;
|
|
fbp->fb_polyline.plist = (lPoint *)ipc_phys(fbmap + 1);
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
#else /* CPU_SINGLE */
|
|
fbp->fb_polyline.plist = (lPoint *)ipc_phys(srcdestlist);
|
|
while (cmd->np > 0) {
|
|
len = min(cmd->np, ((MAX_SIZE / sizeof(lPoint)) & ~1));
|
|
fbp->fb_polyline.np = len;
|
|
if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
|
|
len * sizeof(lPoint), seg)) {
|
|
return error;
|
|
}
|
|
cmd->np -= len;
|
|
cmd->plist += len;
|
|
|
|
if (fbp->fb_polyline.drawBM.type == BM_MEM) {
|
|
if (error = fblocksbitmap(&fbp->fb_polyline.drawBM,
|
|
B_READ, fbmap)) {
|
|
return error;
|
|
}
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
} else if (cmd->np)
|
|
fbstart(fbp, 1);
|
|
else
|
|
fbstart(fbp, 0);
|
|
if (!dj && cmd->np) {
|
|
cmd->np++;
|
|
cmd->plist--;
|
|
}
|
|
}
|
|
#endif /* CPU_SINGLE */
|
|
return error;
|
|
}
|
|
|
|
fbpolyline(fbp, cmd, dj)
|
|
struct fbreg *fbp;
|
|
register sPrimLine *cmd;
|
|
int dj;
|
|
{
|
|
lPrimLine lcmd;
|
|
register lPrimLine *lcmdp;
|
|
static lPoint pl[100];
|
|
register lPoint *lp;
|
|
register sPoint *sp;
|
|
register int np;
|
|
|
|
lcmdp = &lcmd;
|
|
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->drawBM.type = cmd->drawBM.type;
|
|
lcmdp->drawBM.depth = cmd->drawBM.depth;
|
|
lcmdp->drawBM.width = cmd->drawBM.width;
|
|
lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
|
|
lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
|
|
lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
|
|
lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
|
|
lcmdp->drawBM.base = cmd->drawBM.base;
|
|
lcmdp->clip.origin.x = cmd->clip.origin.x;
|
|
lcmdp->clip.origin.y = cmd->clip.origin.y;
|
|
lcmdp->clip.extent.x = cmd->clip.extent.x;
|
|
lcmdp->clip.extent.y = cmd->clip.extent.y;
|
|
lcmdp->lptn = cmd->lptn;
|
|
lcmdp->dlpf = cmd->dlpf;
|
|
lcmdp->plist = pl;
|
|
sp = (sPoint *)cmd->plist;
|
|
while (cmd->np) {
|
|
lcmdp->np = np = min(cmd->np, 100);
|
|
cmd->np -= np;
|
|
lp = pl;
|
|
while (np-- > 0) {
|
|
int error;
|
|
sPoint tmp;
|
|
|
|
if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
|
|
return (error);
|
|
lp->x = tmp.x;
|
|
lp->y = tmp.y;
|
|
lp++;
|
|
sp++;
|
|
}
|
|
fbnpolyline(fbp, lcmdp, dj, UIO_SYSSPACE);
|
|
}
|
|
}
|
|
|
|
fbnfillscan(fbp, cmd, seg)
|
|
struct fbreg *fbp;
|
|
register lPrimFill *cmd;
|
|
int seg;
|
|
{
|
|
register int error;
|
|
register int len;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
|
|
|
|
if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_0, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_1, BM_MEM))) {
|
|
return(mfbnfillscan(fbp, cmd, seg));
|
|
/* NOTREACHED */
|
|
}
|
|
#endif
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CFILLSCAN;
|
|
fbp->fb_fillscan = *cmd;
|
|
|
|
#ifdef CPU_SINGLE
|
|
if (error = fblocksbitmap(&fbp->fb_fillscan.ptnBM, B_WRITE, fbmap))
|
|
return error;
|
|
if (error = fblocksbitmap(&fbp->fb_fillscan.drawBM, B_READ, fbmap + 1))
|
|
return error;
|
|
if ((len = cmd->nscan * sizeof(lScanl)) <= 0)
|
|
return EINVAL;
|
|
if (error = fblockmem(cmd->scan, len, B_WRITE, fbmap + 2, seg))
|
|
return error;
|
|
fbp->fb_fillscan.scan = (lScanl *)ipc_phys(fbmap + 2);
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
#else /* CPU_SINGLE */
|
|
fbp->fb_fillscan.scan = (lScanl *)ipc_phys(srcdestlist);
|
|
while (cmd->nscan > 0) {
|
|
len = min(cmd->nscan, (MAX_SIZE / sizeof(lScanl)));
|
|
fbp->fb_fillscan.nscan = len;
|
|
if (error = COPYIN((caddr_t)cmd->scan, (caddr_t)srcdestlist,
|
|
len * sizeof(lScanl), seg)) {
|
|
return error;
|
|
}
|
|
cmd->nscan -= len;
|
|
cmd->scan += len;
|
|
if (fbp->fb_fillscan.ptnBM.type == BM_MEM ||
|
|
fbp->fb_fillscan.drawBM.type == BM_MEM) {
|
|
|
|
if (error = fblocksbitmap(&fbp->fb_fillscan.ptnBM,
|
|
B_WRITE, fbmap)) {
|
|
return error;
|
|
}
|
|
if (error = fblocksbitmap(&fbp->fb_fillscan.drawBM,
|
|
B_READ, fbmap + 1)) {
|
|
return error;
|
|
}
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
} else if (cmd->nscan)
|
|
fbstart(fbp, 1);
|
|
else
|
|
fbstart(fbp, 0);
|
|
}
|
|
#endif /* CPU_SINGLE */
|
|
return error;
|
|
}
|
|
|
|
fbfillscan(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sPrimFill *cmd;
|
|
{
|
|
lPrimFill lcmd;
|
|
register lPrimFill *lcmdp;
|
|
static lScanl ls[100];
|
|
register lScanl *lp;
|
|
register sScanl *sp;
|
|
register int ns;
|
|
|
|
lcmdp = &lcmd;
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->refPoint.x = cmd->refPoint.x;
|
|
lcmdp->refPoint.y = cmd->refPoint.y;
|
|
lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
|
|
lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
|
|
lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
|
|
lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
|
|
lcmdp->ptnBM.type = cmd->ptnBM.type;
|
|
lcmdp->ptnBM.depth = cmd->ptnBM.depth;
|
|
lcmdp->ptnBM.width = cmd->ptnBM.width;
|
|
lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
|
|
lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
|
|
lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
|
|
lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
|
|
lcmdp->ptnBM.base = cmd->ptnBM.base;
|
|
lcmdp->drawBM.type = cmd->drawBM.type;
|
|
lcmdp->drawBM.depth = cmd->drawBM.depth;
|
|
lcmdp->drawBM.width = cmd->drawBM.width;
|
|
lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
|
|
lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
|
|
lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
|
|
lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
|
|
lcmdp->drawBM.base = cmd->drawBM.base;
|
|
lcmdp->clip.origin.x = cmd->clip.origin.x;
|
|
lcmdp->clip.origin.y = cmd->clip.origin.y;
|
|
lcmdp->clip.extent.x = cmd->clip.extent.x;
|
|
lcmdp->clip.extent.y = cmd->clip.extent.y;
|
|
lcmdp->scan = ls;
|
|
sp = (sScanl *)cmd->scan;
|
|
while (cmd->nscan) {
|
|
lcmdp->nscan = ns = min(cmd->nscan, 100);
|
|
cmd->nscan -= ns;
|
|
lp = ls;
|
|
while (ns-- > 0) {
|
|
int error;
|
|
sScanl tmp;
|
|
|
|
if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
|
|
return (error);
|
|
lp->x0 = tmp.x0;
|
|
lp->x1 = tmp.x1;
|
|
lp->y = tmp.y;
|
|
lp++;
|
|
sp++;
|
|
}
|
|
fbnfillscan(fbp, lcmdp, UIO_SYSSPACE);
|
|
}
|
|
}
|
|
|
|
fbnrectangle(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register lPrimRect *cmd;
|
|
{
|
|
register int error = 0;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
|
|
|
|
if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_0, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_1, BM_MEM))) {
|
|
return(mfbnrectangle(fbp, cmd));
|
|
/* NOTREACHED */
|
|
}
|
|
#endif /* CPU_DOUBLE */
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CRECTANGLE;
|
|
fbp->fb_rectangle = *cmd;
|
|
|
|
if (error = fblocksbitmap(&fbp->fb_rectangle.drawBM, B_READ, fbmap))
|
|
return error;
|
|
if (error = fblocksbitmap(&fbp->fb_rectangle.ptnBM, B_WRITE, fbmap + 1))
|
|
return error;
|
|
|
|
if (fbp->fb_rectangle.drawBM.type == BM_MEM ||
|
|
fbp->fb_rectangle.ptnBM.type == BM_MEM) {
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
} else {
|
|
fbstart(fbp, 0);
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
fbrectangle(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sPrimRect *cmd;
|
|
{
|
|
lPrimRect lcmd;
|
|
register lPrimRect *lcmdp;
|
|
|
|
lcmdp = &lcmd;
|
|
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->rect.origin.x = cmd->rect.origin.x;
|
|
lcmdp->rect.origin.y = cmd->rect.origin.y;
|
|
lcmdp->rect.extent.x = cmd->rect.extent.x;
|
|
lcmdp->rect.extent.y = cmd->rect.extent.y;
|
|
lcmdp->refPoint.x = cmd->refPoint.x;
|
|
lcmdp->refPoint.y = cmd->refPoint.y;
|
|
lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
|
|
lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
|
|
lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
|
|
lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
|
|
lcmdp->ptnBM.type = cmd->ptnBM.type;
|
|
lcmdp->ptnBM.depth = cmd->ptnBM.depth;
|
|
lcmdp->ptnBM.width = cmd->ptnBM.width;
|
|
lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
|
|
lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
|
|
lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
|
|
lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
|
|
lcmdp->ptnBM.base = cmd->ptnBM.base;
|
|
lcmdp->drawBM.type = cmd->drawBM.type;
|
|
lcmdp->drawBM.depth = cmd->drawBM.depth;
|
|
lcmdp->drawBM.width = cmd->drawBM.width;
|
|
lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
|
|
lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
|
|
lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
|
|
lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
|
|
lcmdp->drawBM.base = cmd->drawBM.base;
|
|
lcmdp->clip.origin.x = cmd->clip.origin.x;
|
|
lcmdp->clip.origin.y = cmd->clip.origin.y;
|
|
lcmdp->clip.extent.x = cmd->clip.extent.x;
|
|
lcmdp->clip.extent.y = cmd->clip.extent.y;
|
|
return (fbnrectangle(fbp, lcmdp));
|
|
}
|
|
|
|
fbnpolymarker(fbp, cmd, seg)
|
|
register struct fbreg *fbp;
|
|
register lPrimMarker *cmd;
|
|
int seg;
|
|
{
|
|
register int error;
|
|
register int len;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
|
|
|
|
if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_0, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_1, BM_MEM))) {
|
|
return(mfbnpolymarker(fbp, cmd, seg));
|
|
/* NOTREACHED */
|
|
}
|
|
#endif /* CPU_DOUBLE */
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CPOLYMARKER;
|
|
fbp->fb_polymarker = *cmd;
|
|
|
|
#ifdef CPU_SINGLE
|
|
if (error = fblocksbitmap(&fbp->fb_polymarker.ptnBM, B_WRITE, fbmap))
|
|
return error;
|
|
if (error = fblocksbitmap(&fbp->fb_polymarker.drawBM, B_READ, fbmap+1))
|
|
return error;
|
|
if ((len = cmd->np * sizeof(lPoint)) <= 0)
|
|
return EINVAL;
|
|
if (error = fblockmem(cmd->plist, len, B_WRITE, fbmap + 2, seg))
|
|
return error;
|
|
fbp->fb_polymarker.plist = (lPoint *)ipc_phys(fbmap + 2);
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
#else /* CPU_SINGLE */
|
|
fbp->fb_polymarker.plist = (lPoint *)ipc_phys(srcdestlist);
|
|
while (cmd->np > 0) {
|
|
len = min(cmd->np, (MAX_SIZE / sizeof(lPoint)));
|
|
fbp->fb_polymarker.np = len;
|
|
if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
|
|
len * sizeof(lPoint), seg)) {
|
|
return error;
|
|
}
|
|
cmd->np -= len;
|
|
cmd->plist += len;
|
|
|
|
if (fbp->fb_polymarker.ptnBM.type == BM_MEM ||
|
|
fbp->fb_polymarker.drawBM.type == BM_MEM) {
|
|
|
|
if (error = fblocksbitmap(&fbp->fb_polymarker.ptnBM,
|
|
B_WRITE, fbmap)) {
|
|
return error;
|
|
}
|
|
if (error = fblocksbitmap(&fbp->fb_polymarker.drawBM,
|
|
B_READ, fbmap + 1)) {
|
|
return error;
|
|
}
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
} else if (cmd->np)
|
|
fbstart(fbp, 1);
|
|
else
|
|
fbstart(fbp, 0);
|
|
}
|
|
#endif /* CPU_SINGLE */
|
|
return error;
|
|
}
|
|
|
|
fbpolymarker(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sPrimMarker *cmd;
|
|
{
|
|
lPrimMarker lcmd;
|
|
register lPrimMarker *lcmdp;
|
|
static lPoint pl[100];
|
|
register lPoint *lp;
|
|
register sPoint *sp;
|
|
register int np;
|
|
|
|
lcmdp = &lcmd;
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
|
|
lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
|
|
lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
|
|
lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
|
|
lcmdp->ptnBM.type = cmd->ptnBM.type;
|
|
lcmdp->ptnBM.depth = cmd->ptnBM.depth;
|
|
lcmdp->ptnBM.width = cmd->ptnBM.width;
|
|
lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
|
|
lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
|
|
lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
|
|
lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
|
|
lcmdp->ptnBM.base = cmd->ptnBM.base;
|
|
lcmdp->drawBM.type = cmd->drawBM.type;
|
|
lcmdp->drawBM.depth = cmd->drawBM.depth;
|
|
lcmdp->drawBM.width = cmd->drawBM.width;
|
|
lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
|
|
lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
|
|
lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
|
|
lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
|
|
lcmdp->drawBM.base = cmd->drawBM.base;
|
|
lcmdp->clip.origin.x = cmd->clip.origin.x;
|
|
lcmdp->clip.origin.y = cmd->clip.origin.y;
|
|
lcmdp->clip.extent.x = cmd->clip.extent.x;
|
|
lcmdp->clip.extent.y = cmd->clip.extent.y;
|
|
lcmdp->plist = pl;
|
|
sp = (sPoint *)cmd->plist;
|
|
while (cmd->np) {
|
|
lcmdp->np = np = min(cmd->np, 100);
|
|
cmd->np -= np;
|
|
while (np-- > 0) {
|
|
int error;
|
|
sPoint tmp;
|
|
|
|
if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
|
|
return (error);
|
|
lp->x = tmp.x;
|
|
lp->y = tmp.y;
|
|
lp++;
|
|
sp++;
|
|
}
|
|
fbnpolymarker(fbp, lcmdp, UIO_SYSSPACE);
|
|
}
|
|
}
|
|
|
|
fbnpolydot(fbp, cmd, seg)
|
|
register struct fbreg *fbp;
|
|
register lPrimDot *cmd;
|
|
int seg;
|
|
{
|
|
register int error;
|
|
register int len;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
if (cmd->drawBM.type == BM_MEM)
|
|
return (mfbnpolydot(fbp, cmd, seg));
|
|
#endif
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CPOLYDOT;
|
|
fbp->fb_polydot = *cmd;
|
|
|
|
#ifdef CPU_SINGLE
|
|
if (error = fblocksbitmap(&fbp->fb_polydot.drawBM, B_READ, fbmap + 1))
|
|
return error;
|
|
if ((len = cmd->np * sizeof(lPoint)) <= 0)
|
|
return EINVAL;
|
|
if (error = fblockmem(cmd->plist, len, B_WRITE, fbmap + 2, seg))
|
|
return error;
|
|
fbp->fb_polydot.plist = (lPoint *)ipc_phys(fbmap + 2);
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
#else /* CPU_SINGLE */
|
|
fbp->fb_polydot.plist = (lPoint *)ipc_phys(srcdestlist);
|
|
while (cmd->np > 0) {
|
|
len = min(cmd->np, (MAX_SIZE / sizeof(lPoint)));
|
|
fbp->fb_polydot.np = len;
|
|
if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
|
|
len * sizeof(lPoint), seg)) {
|
|
return error;
|
|
}
|
|
cmd->np -= len;
|
|
cmd->plist += len;
|
|
|
|
if (fbp->fb_polydot.drawBM.type == BM_MEM) {
|
|
if (error = fblocksbitmap(&fbp->fb_polydot.drawBM,
|
|
B_READ, fbmap + 1)) {
|
|
return error;
|
|
}
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
} else if (cmd->np)
|
|
fbstart(fbp, 1);
|
|
else
|
|
fbstart(fbp, 0);
|
|
}
|
|
#endif /* CPU_SINGLE */
|
|
return error;
|
|
}
|
|
|
|
fbpolydot(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sPrimDot *cmd;
|
|
{
|
|
lPrimDot lcmd;
|
|
register lPrimDot *lcmdp;
|
|
static lPoint pl[100];
|
|
register lPoint *lp;
|
|
register sPoint *sp;
|
|
register int np;
|
|
|
|
lcmdp = &lcmd;
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->drawBM.type = cmd->drawBM.type;
|
|
lcmdp->drawBM.depth = cmd->drawBM.depth;
|
|
lcmdp->drawBM.width = cmd->drawBM.width;
|
|
lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
|
|
lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
|
|
lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
|
|
lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
|
|
lcmdp->drawBM.base = cmd->drawBM.base;
|
|
lcmdp->clip.origin.x = cmd->clip.origin.x;
|
|
lcmdp->clip.origin.y = cmd->clip.origin.y;
|
|
lcmdp->clip.extent.x = cmd->clip.extent.x;
|
|
lcmdp->clip.extent.y = cmd->clip.extent.y;
|
|
lcmdp->plist = pl;
|
|
sp = (sPoint *)cmd->plist;
|
|
while (cmd->np) {
|
|
lcmdp->np = np = min(cmd->np, 100);
|
|
cmd->np -= np;
|
|
while (np-- > 0) {
|
|
int error;
|
|
sPoint tmp;
|
|
|
|
if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
|
|
return (error);
|
|
lp->x = tmp.x;
|
|
lp->y = tmp.y;
|
|
lp++;
|
|
sp++;
|
|
}
|
|
fbnpolydot(fbp, lcmdp, UIO_SYSSPACE);
|
|
}
|
|
}
|
|
|
|
fbntext(fbp, cmd)
|
|
register struct fbreg *fbp;
|
|
register lPrimText *cmd;
|
|
{
|
|
register int error;
|
|
|
|
#ifdef CPU_DOUBLE
|
|
int blttype = BLTTYPE(cmd->fontBM.type, cmd->drawBM.type);
|
|
|
|
if ((cmd->type == ASCII) &&
|
|
((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_0, BM_MEM)) ||
|
|
(blttype == BLTTYPE(BM_1, BM_MEM)))
|
|
) {
|
|
return(mfbntext(fbp, cmd));
|
|
/* NOTREACHED */
|
|
}
|
|
#endif /* CPU_DOUBLE */
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CTEXT;
|
|
fbp->fb_text = *cmd;
|
|
|
|
|
|
if (error = fblocksbitmap(&fbp->fb_text.drawBM, B_READ, fbmap))
|
|
return error;
|
|
|
|
if (cmd->type == ASCII) {
|
|
if (error = fblocksbitmap(&fbp->fb_text.fontBM,
|
|
B_WRITE, fbmap + 1)) {
|
|
return error;
|
|
}
|
|
}
|
|
|
|
#ifdef CPU_SINGLE
|
|
if (error = fblockmem(cmd->str, cmd->len, B_WRITE, fbmap + 2, UIO_USERSPACE))
|
|
return error;
|
|
fbp->fb_text.str = (unsigned char *)ipc_phys(fbmap + 2);
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
#else /* CPU_SINGLE */
|
|
fbp->fb_text.str = (unsigned char *)ipc_phys(srcdestlist);
|
|
if (error = COPYIN((caddr_t)cmd->str,
|
|
(caddr_t)srcdestlist, cmd->len, UIO_USERSPACE)) {
|
|
return error;
|
|
}
|
|
|
|
if (fbp->fb_text.drawBM.type == BM_MEM ||
|
|
(cmd->type == ASCII && fbp->fb_text.fontBM.type == BM_MEM)) {
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
} else
|
|
fbstart(fbp, 0);
|
|
#endif /* CPU_SINGLE */
|
|
return error;
|
|
}
|
|
|
|
fbtext(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
register sPrimText *cmd;
|
|
{
|
|
lPrimText lcmd;
|
|
register lPrimText *lcmdp;
|
|
|
|
lcmdp = &lcmd;
|
|
|
|
lcmdp->func = cmd->func;
|
|
lcmdp->transp = cmd->transp;
|
|
lcmdp->fore_color = cmd->fore_color;
|
|
lcmdp->aux_color = cmd->aux_color;
|
|
lcmdp->planemask = cmd->planemask;
|
|
lcmdp->type = cmd->type;
|
|
lcmdp->p.x = cmd->p.x;
|
|
lcmdp->p.y = cmd->p.y;
|
|
lcmdp->dx = cmd->dx;
|
|
lcmdp->dy = cmd->dy;
|
|
lcmdp->ex_factor = cmd->ex_factor;
|
|
lcmdp->fp.x = cmd->fp.x;
|
|
lcmdp->fp.y = cmd->fp.y;
|
|
lcmdp->width = cmd->width;
|
|
lcmdp->height = cmd->height;
|
|
lcmdp->column = cmd->column;
|
|
lcmdp->first_chr = cmd->first_chr;
|
|
lcmdp->last_chr = cmd->last_chr;
|
|
lcmdp->fontBM.type = cmd->fontBM.type;
|
|
lcmdp->fontBM.depth = cmd->fontBM.depth;
|
|
lcmdp->fontBM.width = cmd->fontBM.width;
|
|
lcmdp->fontBM.rect.origin.x = cmd->fontBM.rect.origin.x;
|
|
lcmdp->fontBM.rect.origin.y = cmd->fontBM.rect.origin.y;
|
|
lcmdp->fontBM.rect.extent.x = cmd->fontBM.rect.extent.x;
|
|
lcmdp->fontBM.rect.extent.y = cmd->fontBM.rect.extent.y;
|
|
lcmdp->fontBM.base = cmd->fontBM.base;
|
|
lcmdp->drawBM.type = cmd->drawBM.type;
|
|
lcmdp->drawBM.depth = cmd->drawBM.depth;
|
|
lcmdp->drawBM.width = cmd->drawBM.width;
|
|
lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
|
|
lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
|
|
lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
|
|
lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
|
|
lcmdp->drawBM.base = cmd->drawBM.base;
|
|
lcmdp->clip.origin.x = cmd->clip.origin.x;
|
|
lcmdp->clip.origin.y = cmd->clip.origin.y;
|
|
lcmdp->clip.extent.x = cmd->clip.extent.x;
|
|
lcmdp->clip.extent.y = cmd->clip.extent.y;
|
|
lcmdp->len = cmd->len;
|
|
lcmdp->str = cmd->str;
|
|
return (fbntext(fbp, lcmdp));
|
|
}
|
|
#endif /* NOTYET */
|
|
|
|
int
|
|
fbsetcursor(fbp, data)
|
|
struct fbreg *fbp;
|
|
sCursor *data;
|
|
{
|
|
register struct fbreg *fbregp;
|
|
|
|
fbregp = fbp;
|
|
|
|
fbregp->fb_command = FB_CSETCURSOR;
|
|
fbregp->fb_cursor.func = data->func;
|
|
fbregp->fb_cursor.cursor_color = data->cursor_color;
|
|
fbregp->fb_cursor.mask_color = data->mask_color;
|
|
fbregp->fb_cursor.hot.x = data->hot.x;
|
|
fbregp->fb_cursor.hot.y = data->hot.y;
|
|
fbregp->fb_cursor.size.x = data->size.x;
|
|
fbregp->fb_cursor.size.y = data->size.y;
|
|
fbregp->fb_cursor.cursorRect.origin.x = data->cursorRect.origin.x;
|
|
fbregp->fb_cursor.cursorRect.origin.y = data->cursorRect.origin.y;
|
|
fbregp->fb_cursor.cursorRect.extent.x = data->cursorRect.extent.x;
|
|
fbregp->fb_cursor.cursorRect.extent.y = data->cursorRect.extent.y;
|
|
fbregp->fb_cursor.maskRect.origin.x = data->maskRect.origin.x;
|
|
fbregp->fb_cursor.maskRect.origin.y = data->maskRect.origin.y;
|
|
fbregp->fb_cursor.maskRect.extent.x = data->maskRect.extent.x;
|
|
fbregp->fb_cursor.maskRect.extent.y = data->maskRect.extent.y;
|
|
fbregp->fb_cursor.saveRect.origin.x = data->saveRect.origin.x;
|
|
fbregp->fb_cursor.saveRect.origin.y = data->saveRect.origin.y;
|
|
fbregp->fb_cursor.saveRect.extent.x = data->saveRect.extent.x;
|
|
fbregp->fb_cursor.saveRect.extent.y = data->saveRect.extent.y;
|
|
fbregp->fb_cursor.moveArea.origin.x = data->moveArea.origin.x;
|
|
fbregp->fb_cursor.moveArea.origin.y = data->moveArea.origin.y;
|
|
fbregp->fb_cursor.moveArea.extent.x = data->moveArea.extent.x;
|
|
fbregp->fb_cursor.moveArea.extent.y = data->moveArea.extent.y;
|
|
fbstart(fbp, 0);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
fbnsetcursor(fbp, data)
|
|
struct fbreg *fbp;
|
|
lCursor *data;
|
|
{
|
|
register struct fbreg *fbregp;
|
|
|
|
fbregp = fbp;
|
|
|
|
fbregp->fb_command = FB_CSETCURSOR;
|
|
fbregp->fb_cursor.func = data->func;
|
|
fbregp->fb_cursor.cursor_color = data->cursor_color;
|
|
fbregp->fb_cursor.mask_color = data->mask_color;
|
|
fbregp->fb_cursor.hot.x = data->hot.x;
|
|
fbregp->fb_cursor.hot.y = data->hot.y;
|
|
fbregp->fb_cursor.size.x = data->size.x;
|
|
fbregp->fb_cursor.size.y = data->size.y;
|
|
fbregp->fb_cursor.cursorRect.origin.x = data->cursorRect.origin.x;
|
|
fbregp->fb_cursor.cursorRect.origin.y = data->cursorRect.origin.y;
|
|
fbregp->fb_cursor.cursorRect.extent.x = data->cursorRect.extent.x;
|
|
fbregp->fb_cursor.cursorRect.extent.y = data->cursorRect.extent.y;
|
|
fbregp->fb_cursor.maskRect.origin.x = data->maskRect.origin.x;
|
|
fbregp->fb_cursor.maskRect.origin.y = data->maskRect.origin.y;
|
|
fbregp->fb_cursor.maskRect.extent.x = data->maskRect.extent.x;
|
|
fbregp->fb_cursor.maskRect.extent.y = data->maskRect.extent.y;
|
|
fbregp->fb_cursor.saveRect.origin.x = data->saveRect.origin.x;
|
|
fbregp->fb_cursor.saveRect.origin.y = data->saveRect.origin.y;
|
|
fbregp->fb_cursor.saveRect.extent.x = data->saveRect.extent.x;
|
|
fbregp->fb_cursor.saveRect.extent.y = data->saveRect.extent.y;
|
|
fbregp->fb_cursor.moveArea.origin.x = data->moveArea.origin.x;
|
|
fbregp->fb_cursor.moveArea.origin.y = data->moveArea.origin.y;
|
|
fbregp->fb_cursor.moveArea.extent.x = data->moveArea.extent.x;
|
|
fbregp->fb_cursor.moveArea.extent.y = data->moveArea.extent.y;
|
|
fbstart(fbp, 0);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
fbgetscrtype(fbp, data)
|
|
struct fbreg *fbp;
|
|
sScrType *data;
|
|
{
|
|
fbp->fb_command = FB_CGETSCRTYPE;
|
|
fbstart(fbp, 1);
|
|
data->colorwidth = fbp->fb_scrtype.colorwidth;
|
|
data->plane = fbp->fb_scrtype.plane;
|
|
data->bufferrect.origin.x = fbp->fb_scrtype.bufferrect.origin.x;
|
|
data->bufferrect.origin.y = fbp->fb_scrtype.bufferrect.origin.y;
|
|
data->bufferrect.extent.x = fbp->fb_scrtype.bufferrect.extent.x;
|
|
data->bufferrect.extent.y = fbp->fb_scrtype.bufferrect.extent.y;
|
|
data->visiblerect.origin.x = fbp->fb_scrtype.visiblerect.origin.x;
|
|
data->visiblerect.origin.y = fbp->fb_scrtype.visiblerect.origin.y;
|
|
data->visiblerect.extent.x = fbp->fb_scrtype.visiblerect.extent.x;
|
|
data->visiblerect.extent.y = fbp->fb_scrtype.visiblerect.extent.y;
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
fbsetxy(fbp, data)
|
|
struct fbreg *fbp;
|
|
sPoint *data;
|
|
{
|
|
fbp->fb_command = FB_CSETXY;
|
|
fbp->fb_point.x = data->x;
|
|
fbp->fb_point.y = data->y;
|
|
fbstart(fbp, 0);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
fbsetpalette(fbp, data)
|
|
struct fbreg *fbp;
|
|
sPalette *data;
|
|
{
|
|
fbp->fb_command = FB_CSETPALETTE;
|
|
fbp->fb_palette.count = 1;
|
|
*(sPalette *)srcdestlist = *data;
|
|
#ifdef CPU_SINGLE
|
|
fbmap[0].fm_vaddr = (caddr_t)srcdestlist;
|
|
fbmap[0].fm_offset = 0;
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
|
|
#else
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
|
|
#endif
|
|
fbstart(fbp, 0);
|
|
return 0;
|
|
}
|
|
|
|
#ifdef NOTYET
|
|
fbnsetpalette(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
lPalette *cmd;
|
|
{
|
|
register int error;
|
|
register int count;
|
|
#ifdef CPU_SINGLE
|
|
register int len;
|
|
#endif
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CSETPALETTE;
|
|
#ifdef CPU_SINGLE
|
|
fbp->fb_palette.count = cmd->count;
|
|
if ((len = cmd->count * sizeof(sPalette)) <= 0)
|
|
return EINVAL;
|
|
if (error = fblockmem(cmd->palette, len, B_WRITE, fbmap, UIO_USERSPACE))
|
|
return error;
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
#else /* CPU_SINGLE */
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
|
|
while (cmd->count > 0) {
|
|
count = min(cmd->count, (MAX_SIZE / sizeof(sPalette)));
|
|
fbp->fb_palette.count = count;
|
|
if (error = COPYIN((caddr_t)cmd->palette, (caddr_t)srcdestlist,
|
|
count * sizeof(sPalette), UIO_USERSPACE)) {
|
|
break;
|
|
}
|
|
cmd->count -= count;
|
|
cmd->palette += count;
|
|
|
|
fbstart(fbp, 0);
|
|
}
|
|
#endif /* CPU_SINGLE */
|
|
return error;
|
|
}
|
|
#endif /* NOTYET */
|
|
|
|
int
|
|
fbgetpalette(fbp, data)
|
|
struct fbreg *fbp;
|
|
sPalette *data;
|
|
{
|
|
fbp->fb_command = FB_CGETPALETTE;
|
|
fbp->fb_palette.count = 1;
|
|
*(sPalette *)srcdestlist = *data;
|
|
#ifdef CPU_SINGLE
|
|
fbmap[0].fm_vaddr = (caddr_t)srcdestlist;
|
|
fbmap[0].fm_offset = 0;
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
|
|
#else
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
|
|
#endif
|
|
fbstart(fbp, 1);
|
|
#ifdef mips
|
|
MachFlushDCache((vaddr_t)srcdestlist, sizeof (sPalette));
|
|
*data = *(sPalette *)MIPS_KSEG0_TO_KSEG1(srcdestlist);
|
|
#else
|
|
*data = *(sPalette *)srcdestlist;
|
|
#endif
|
|
return fbp->fb_result;
|
|
}
|
|
|
|
#ifdef NOTYET
|
|
fbngetpalette(fbp, cmd)
|
|
struct fbreg *fbp;
|
|
lPalette *cmd;
|
|
{
|
|
register int error;
|
|
register int count;
|
|
#ifdef CPU_SINGLE
|
|
register int len;
|
|
#else
|
|
register int savecount;
|
|
register sPalette *savep;
|
|
#endif
|
|
|
|
fbinitlock();
|
|
fbp->fb_command = FB_CGETPALETTE;
|
|
#ifdef CPU_SINGLE
|
|
fbp->fb_palette.count = cmd->count;
|
|
if ((len = cmd->count * sizeof(sPalette)) <= 0)
|
|
return EINVAL;
|
|
if (error = fblockmem(cmd->palette, len, B_WRITE, fbmap, UIO_USERSPACE))
|
|
return error;
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
|
|
|
|
fbdolock();
|
|
fbstart(fbp, 1);
|
|
fbunlock();
|
|
#else /* CPU_SINGLE */
|
|
savecount = cmd->count;
|
|
savep = cmd->palette;
|
|
fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
|
|
while (cmd->count > 0) {
|
|
count = min(cmd->count, (MAX_SIZE / sizeof(sPalette)));
|
|
fbp->fb_palette.count = count;
|
|
if (error = COPYIN((caddr_t)cmd->palette, (caddr_t)srcdestlist,
|
|
count * sizeof(sPalette), UIO_USERSPACE)) {
|
|
break;
|
|
}
|
|
fbstart(fbp, 1);
|
|
#ifdef mips
|
|
MachFlushDCache((caddr_t)srcdestlist, sizeof (sPalette));
|
|
error = copyout((caddr_t)MACH_CACHED_TO_UNCACHED(srcdestlist),
|
|
(caddr_t)cmd->palette,
|
|
count * sizeof(sPalette));
|
|
#else
|
|
error = copyout((caddr_t)srcdestlist,
|
|
(caddr_t)cmd->palette,
|
|
count * sizeof(sPalette));
|
|
#endif
|
|
if (error)
|
|
break;
|
|
cmd->count -= count;
|
|
cmd->palette += count;
|
|
}
|
|
cmd->count = savecount;
|
|
cmd->palette = savep;
|
|
#endif /* CPU_SINGLE */
|
|
return fbp->fb_result;
|
|
}
|
|
#endif /* NOTYET */
|
|
#endif /* NFB > 0 */
|