home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xibm.zip
/
mpel
/
mpelCursor.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-06
|
15KB
|
552 lines
/*
* Copyright IBM Corporation 1987,1988,1989
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of IBM not be
* used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
* IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
*/
#ifndef lint
static char *rcsid = "$Id: mpelCursor.c,v 5.0 1992/02/06 13:49:48 jfc Exp jfc $";
#endif
/*
* xcursor.c -- software cursor
*/
#include "X.h"
#include "Xproto.h"
#include "cursorstr.h"
#include "misc.h"
#include "scrnintstr.h"
#include "colormapst.h"
#include "pixmapstr.h"
#include "OScompiler.h"
#include "ibmScreen.h"
#include "ibmColor.h"
#ifdef PGC
#include "pgc.h"
extern pgcScreenRec pgcScreenInfo[];
#define CMAP(scr) pgcScreenInfo[scr->myNum].InstalledColormap
#else
#include "ppc.h"
#define CMAP(scr) ((ppcScrnPriv *)scr->devPrivate)->InstalledColormap
#endif
#include "mpel.h"
#include "mpelHdwr.h"
#include "mpelFifo.h"
#include "ibmTrace.h"
#define CURSOR_MAX_SIZE ((32 / 8) * 32)
static void mpel4x4();
/* Global Cursor State Semaphore */
int mpelcursorSemaphore = 0;
static int screen_index;
static short c_x;
static short c_y;
static int cursor_not_displayed = TRUE;
static int cursor_is_valid = FALSE;
static mpelRectangle last_save;
/*** ==================================================================***/
/*
* mpelPutCursorOn( x, y )
*/
static void
mpelPutCursorOn( x, y )
register short int x, y;
{
register CursorPtr curCursor;
register unsigned int byteSize;
int w, h;
mpelVPMBLTDestination saveBlit;
if ( ibmScreenState( screen_index ) != SCREEN_ACTIVE )
return;
curCursor = ibmCurrentCursor( screen_index );
if (x >= MPEL_WIDTH || (x + curCursor->bits->width) < 0)
return; /* off the screen, don't bother */
MPELSetPlaneMask(0);
h = MIN(curCursor->bits->height, 32);
w = (curCursor->bits->width > 16) ? 32 : 16;
byteSize = (w >> 3) * h;
/* Save The Existing Image */
saveBlit.destaddr = mpelAddr( MPEL_CURSOR_SAVE );
saveBlit.source.lleft.x = x;
saveBlit.source.lleft.y = MPEL_HEIGHT - h - y;
saveBlit.source.uright.x = x + w - 1;
saveBlit.source.uright.y = MPEL_HEIGHT - 1 - y;
saveBlit.comp = 0x0001;
last_save = saveBlit.source;
MPELVPMBLTDest(&saveBlit);
if (x > MPEL_WIDTH - w || x < w || y < h || y > MPEL_HEIGHT - h) {
mpelBLTImmedWColorExpansion cursorBlit;
cursorBlit.dest.lleft.x = x;
cursorBlit.dest.lleft.y = MPEL_HEIGHT - h - y;
cursorBlit.dest.uright.x = x + 31;
cursorBlit.dest.uright.y = MPEL_HEIGHT - 1 - y;
cursorBlit.alu = GXcopy + 1;
cursorBlit.color = ((unsigned int *)curCursor->devPriv[screen_index])[0];
/* round width up to 32 for byteSize */
if(w < 32)
byteSize = 4 * h;
MPELBLTImmedWColorExpansion(byteSize, &cursorBlit);
if(x + w > MPEL_WIDTH)
{
int i;
unsigned int mask = (-1) << ((x + w) - MPEL_WIDTH);
int xxx[32];
if(w == 16)
mask <<= 16;
for(i = 0;i < h;i++)
xxx[i] = ((unsigned int *)curCursor->bits->devPriv[screen_index])[64+i]&mask;
MPELSendData(byteSize, xxx);
cursorBlit.color =
((unsigned int *)curCursor->devPriv[screen_index])[1];
MPELBLTImmedWColorExpansion(byteSize, &cursorBlit);
for(i = 0;i < h;i++)
xxx[i] = ((unsigned int *)curCursor->bits->devPriv[screen_index])[96+i]&mask;
MPELSendData(byteSize, xxx);
} else {
MPELSendData(byteSize,
(char *)curCursor->bits->devPriv[screen_index]+256);
cursorBlit.color =
((unsigned int *)curCursor->devPriv[screen_index])[1];
MPELBLTImmedWColorExpansion(byteSize, &cursorBlit);
MPELSendData(byteSize,
(char *)curCursor->bits->devPriv[screen_index]+384);
}
} else {
mpelBLTImmed4x4WColorExpansion cursorBlit;
h = (h + 3) & ~3;
byteSize = (w >> 3) * h;
cursorBlit.dest.lleft.x = x;
cursorBlit.dest.lleft.y = MPEL_HEIGHT - h - y;
cursorBlit.dest.uright.x = x + w - 1;
cursorBlit.dest.uright.y = MPEL_HEIGHT - 1 - y;
cursorBlit.color = ((unsigned int *)curCursor->devPriv[screen_index])[0];
MPELBLTImmed4x4WColorExpansion(byteSize, &cursorBlit);
MPELSendData(byteSize,
(unsigned short *)curCursor->bits->devPriv[screen_index]);
cursorBlit.color = ((unsigned int *)curCursor->devPriv[screen_index])[1];
MPELBLTImmed4x4WColorExpansion(byteSize, &cursorBlit);
MPELSendData(byteSize,
(unsigned short *)curCursor->bits->devPriv[screen_index] + 64);
}
/* Cursor Is Now Active */
cursor_not_displayed = 0;
return;
}
/*** ==================================================================***/
int
mpelRemoveCursor()
{
if (!cursor_not_displayed
&& (ibmScreenState(screen_index) == SCREEN_ACTIVE)) {
register CursorPtr curCursor;
mpelSrcBLTVPM blt;
MPELSetPlaneMask(0);
curCursor = ibmCurrentCursor(screen_index);
blt.srcaddr = mpelAddr(MPEL_CURSOR_SAVE);
blt.dest = last_save;
blt.bpixel = 0x0008;
blt.alu = GXcopy + 1;
MPELSrcBLTVPM(&blt);
}
return cursor_not_displayed = TRUE;
}
/*** ==================================================================***/
void
mpelShowCursor( x, y )
register short x, y;
{
register CursorPtr curCursor = ibmCurrentCursor( screen_index );
if ( ibmScreenState( screen_index ) != SCREEN_ACTIVE ) {
c_x = x - curCursor->bits->xhot;
c_y = y - curCursor->bits->yhot;
}
if ( !cursor_not_displayed ) {
(void) mpelRemoveCursor();
x -= curCursor->bits->xhot;
y -= curCursor->bits->yhot;
}
c_x = x;
c_y = y;
if ( cursor_is_valid )
mpelPutCursorOn( x, y );
return;
}
/*** ================================================================== ***/
/* check if the cursor is in this rectangle. if so, remove and return TRUE
else return FALSE */
int
mpelCheckCursor(x, y, lx, ly)
register const int x, y, lx, ly;
{
register CursorPtr curCursor = ibmCurrentCursor(screen_index);
if (!mpelcursorSemaphore && !cursor_not_displayed
&& (ibmScreenState(screen_index) == SCREEN_ACTIVE)
&& !(( x >= ( c_x + (curCursor->bits->width > 16 ? 32 : 16)))
|| (y >= ( c_y + MIN(curCursor->bits->height, 32)))
|| (( x + lx ) <= c_x)
|| (( y + ly ) <= c_y)))
return mpelRemoveCursor();
else
return FALSE;
/*NOTREACHED*/
}
/*** ==================================================================***/
void mpelReplaceCursor()
{
if (cursor_not_displayed && !mpelcursorSemaphore &&
ibmScreenState(screen_index) == SCREEN_ACTIVE)
mpelShowCursor(c_x, c_y);
return;
}
/*** ==================================================================***/
void mpelRecolorCursor(pScr, pCurs, displayed)
ScreenPtr pScr;
CursorPtr pCurs;
Bool displayed;
{
TRACE(("mpelRecolorCursor(%#x, %#x, %d)\n", pScr, pCurs, displayed));
if(displayed)
mpelDisplayCursor(pScr, pCurs);
}
static void
mpelCursorColormap(pCurs, cmap, pScrn)
register ColormapPtr cmap;
register CursorPtr pCurs;
ScreenPtr pScrn;
{
xColorItem c;
register int scrn;
if (pScrn)
scrn = pScrn->myNum;
else
scrn = screen_index;
if(pCurs == NULL)
{
pCurs = ibmCurrentCursor(scrn);
if (pCurs == NULL)
{
ErrorF("mpelCursorColormap: no cursor\n");
return;
}
}
if(pCurs->devPriv[scrn] == NULL)
{
ErrorF("mpelCursorColormap: cursor unrealized\n");
return;
}
c.pixel = 0;
c.red = pCurs->foreRed;
c.green = pCurs->foreGreen;
c.blue = pCurs->foreBlue;
c.flags = DoRed | DoGreen | DoBlue;
FakeAllocColor(cmap, &c);
((unsigned int *)pCurs->devPriv[scrn])[0] = c.pixel;
FakeFreeColor(cmap, c.pixel);
c.red = pCurs->backRed;
c.green = pCurs->backGreen;
c.blue = pCurs->backBlue;
FakeAllocColor(cmap, &c);
((unsigned int *)pCurs->devPriv[scrn])[1] = c.pixel;
FakeFreeColor(cmap, c.pixel);
return;
}
void mpel_ppcRecolorCursor(cmap)
ColormapPtr cmap;
{
mpelCursorColormap(0, cmap, 0);
}
/* ************************************************************************** */
void
mpelCursorInit( index )
register int index;
{
TRACE( ( "mpelCursorInit()\n" ));
ibmCursorShow( index ) = mpelShowCursor;
ibmCurrentCursor( index ) = NULL;
cursor_is_valid = FALSE;
screen_index = index;
c_x = 0;
c_y = 0;
mpelcursorSemaphore = 0;
cursor_not_displayed = TRUE;
return;
}
/*** ============================================================***/
Bool
mpelRealizeCursor( pScr, pCurs )
register ScreenPtr pScr;
register CursorPtr pCurs;
{
register unsigned long int *pFG, *pBG;
register unsigned long int *psrcImage;
register unsigned long int *psrcMask;
register int i;
register unsigned long int endbits;
int srcWidth;
int srcHeight;
int srcRealWidth;
char *tmpbits;
if (pCurs == 0)
{
ErrorF("mpelRealizeCursor: no cursor\n");
return FALSE;
}
if (!(pCurs->bits->devPriv[pScr->myNum] = (pointer) Xalloc(512)) ||
!(pCurs->devPriv[pScr->myNum] = (pointer) Xalloc(8)))
{
pCurs->bits->devPriv[pScr->myNum] = 0;
ErrorF("mpelRealizeCursor: can't malloc\n");
return FALSE;
}
TRACE(("mpelRealizeCursor(pScr=0x%x,pCurs=0x%x) {devPriv[%d] = %#x, %#x}\n",
pScr, pCurs, pScr->myNum, pCurs->devPriv[pScr->myNum],
pCurs->bits->devPriv[pScr->myNum]));
tmpbits = (char *)pCurs->bits->devPriv[pScr->myNum] + 256;
bzero(tmpbits, 256);
pFG = (unsigned long *) tmpbits;
pBG = pFG + 32;
psrcImage = (unsigned long int *) pCurs->bits->source;
psrcMask = (unsigned long int *) pCurs->bits->mask;
srcRealWidth = ( pCurs->bits->width + 31 ) / 32;
srcWidth = MIN( pCurs->bits->width, 32 );
srcHeight = MIN( pCurs->bits->height, 32 );
endbits = -1 << ( 32 - srcWidth );
for ( i = srcHeight; i-- ; )
{
*pFG++ = (*psrcMask & endbits) & *psrcImage;
*pBG++ = (*psrcMask & endbits) & ~ *psrcImage;
psrcImage = psrcImage + srcRealWidth;
psrcMask = psrcMask + srcRealWidth;
}
mpel4x4(tmpbits, srcWidth, srcHeight,
(unsigned short *)pCurs->bits->devPriv[pScr->myNum]);
mpel4x4(tmpbits+128, srcWidth, srcHeight,
(unsigned short *)pCurs->bits->devPriv[pScr->myNum] + 64);
mpelCursorColormap(pCurs, CMAP(pScr), pScr);
TRACE(("exiting mpelRealizeCursor\n"));
return TRUE;
}
/*** ============================================================***/
Bool
mpelUnrealizeCursor( pScr, pCurs )
register ScreenPtr pScr;
register CursorPtr pCurs;
{
TRACE(("mpelUnrealizeCursor(pScr=0x%x,pCurs=0x%x)\n", pScr, pCurs));
if(pCurs == ibmCurrentCursor(pScr->myNum))
{
TRACE(("\tcursor %#x busy.\n", pCurs));
return FALSE;
}
if(pCurs->bits->refcnt <= 1)
{
Xfree((char *)pCurs->bits->devPriv[pScr->myNum]);
pCurs->bits->devPriv[ pScr->myNum ] = 0;
}
Xfree((char *) pCurs->devPriv[pScr->myNum]);
pCurs->devPriv[pScr->myNum] = 0;
if ( ibmCurrentCursor( pScr->myNum ) == pCurs )
cursor_is_valid = FALSE;
return TRUE;
}
/*** ============================================================***/
Bool
mpelDisplayCursor( pScr, pCurs )
ScreenPtr pScr;
CursorPtr pCurs;
{
register int i;
TRACE(("mpelDisplayCursor(%#x, %#x) {%#x, %#x}\n",
pScr, pCurs,
pCurs->devPriv[pScr->myNum], pCurs->bits->devPriv[pScr->myNum]));
/* cleanup old cursor */
if ( cursor_is_valid ) {
CursorPtr curCursor;
if ( !cursor_not_displayed )
(void) mpelRemoveCursor();
curCursor = ibmCurrentCursor( pScr->myNum );
c_x += curCursor->bits->xhot;
c_y += curCursor->bits->yhot;
}
i = pScr->myNum;
TRACE(("\tscreen %d, bits %#x\n", i, pCurs->bits));
ibmCurrentCursor( i ) = pCurs;
ibmCursorHotX( i ) = pCurs->bits->xhot;
ibmCursorHotY( i ) = pCurs->bits->yhot;
mpelCursorColormap(pCurs, CMAP(pScr), pScr);
c_x -= pCurs->bits->xhot;
c_y -= pCurs->bits->yhot;
mpelPutCursorOn( c_x, c_y );
return cursor_is_valid = TRUE;
}
/*** ==================================================================***/
void
mpelRevalidateCursor()
{
cursor_not_displayed = FALSE;
if ( cursor_is_valid )
mpelPutCursorOn( c_x, c_y );
return;
}
/* Take a pointer to bitmap data, and format it into a set of 4x4 blocks
* suitable for use with mpel blt vpm 4x4 w/ color expansion.
*
* bits -- source data
* dst -- where to put formatted bits (round up size to multiple of 4)
* sw, sh -- source dimensions
*/
static void mpel4x4(bits, sw, sh, dst)
char *bits;
short *dst;
int sw, sh;
{
int dw = (sw + 15) & ~15;
int dh = (sh + 15) & ~15;
int xc, yc;
int src_al = (sw / 8 + 3) & ~3;
TRACE(("mpel4x4(%#x, %d, %d, %#x) src_al %d dw %d dh %d\n",
bits, sw, sh, dst, src_al, dw, dh));
bzero((char *)dst, 128);
if(sh & 3)
{
yc = (sh & ~3);
for(xc = 0; xc < (dw >> 3); xc++)
{
register unsigned int i;
union { unsigned int i;
unsigned char c[4];
} u;
u.i = 0;
switch(sh & 3)
{
case 3:
u.c[2] = *(bits + xc + (yc + 2) * src_al);
case 2:
u.c[1] = *(bits + xc + (yc + 1) * src_al);
case 1:
u.c[0] = *(bits + xc + yc * src_al);
}
i = u.i;
*dst++ = ((i & 0xf0000000) >> 16) | ((i & 0x00f00000) >> 12) |
((i & 0x0000f000) >> 8) | ((i & 0x000000f0) >> 4);
*dst++ = ((i & 0x0f000000) >> 12) | ((i & 0x000f0000) >> 8) |
((i & 0x00000f00) >> 4) | (i & 0x0000000f);
}
}
for(yc = ((sh-4)&~3); yc >= 0; yc -= 4)
{
register int yaddr; /* y * src_al */
yaddr = yc * src_al;
for(xc = 0; xc < (dw>>3); xc++)
{
register unsigned int i;
union { unsigned int i;
unsigned char c[4];
} u;
u.c[0] = *(bits + xc + yaddr);
u.c[1] = *(bits + xc + yaddr + src_al);
u.c[2] = *(bits + xc + yaddr + 2 * src_al);
u.c[3] = *(bits + xc + yaddr + 3 * src_al);
i = u.i;
*dst++ = ((i & 0xf0000000) >> 16) | ((i & 0x00f00000) >> 12) |
((i & 0x0000f000) >> 8) | ((i & 0x000000f0) >> 4);
*dst++ = ((i & 0x0f000000) >> 12) | ((i & 0x000f0000) >> 8) |
((i & 0x00000f00) >> 4) | (i & 0x0000000f);
}
}
}