440 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			440 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
| /* COPYRIGHT AND PERMISSION NOTICE
 | |
| 
 | |
| Copyright (c) 2000, 2001 Nokia Home Communications
 | |
| 
 | |
| All rights reserved.
 | |
| 
 | |
| Permission is hereby granted, free of charge, to any person obtaining
 | |
| a copy of this software and associated documentation files (the
 | |
| "Software"), to deal in the Software without restriction, including
 | |
| without limitation the rights to use, copy, modify, merge, publish,
 | |
| distribute, and/or sell copies of the Software, and to permit persons
 | |
| to whom the Software is furnished to do so, provided that the above
 | |
| copyright notice(s) and this permission notice appear in all copies of
 | |
| the Software and that both the above copyright notice(s) and this
 | |
| permission notice appear in supporting documentation.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | |
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 | |
| OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 | |
| HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
 | |
| 
 | |
| Except as contained in this notice, the name of a copyright holder
 | |
| shall not be used in advertising or otherwise to promote the sale, use
 | |
| or other dealings in this Software without prior written authorization
 | |
| of the copyright holder.
 | |
| 
 | |
| X Window System is a trademark of The Open Group */
 | |
| 
 | |
| /**************************************************************************
 | |
| 
 | |
| Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 | |
| All Rights Reserved.
 | |
| 
 | |
| Permission is hereby granted, free of charge, to any person obtaining a
 | |
| copy of this software and associated documentation files (the
 | |
| "Software"), to deal in the Software without restriction, including
 | |
| without limitation the rights to use, copy, modify, merge, publish,
 | |
| distribute, sub license, and/or sell copies of the Software, and to
 | |
| permit persons to whom the Software is furnished to do so, subject to
 | |
| the following conditions:
 | |
| 
 | |
| The above copyright notice and this permission notice (including the
 | |
| next paragraph) shall be included in all copies or substantial portions
 | |
| of the Software.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | |
| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 | |
| IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 | |
| ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | |
| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | |
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
| 
 | |
| **************************************************************************/
 | |
| 
 | |
| 
 | |
| 
 | |
| /* $RCSId: xc/programs/Xserver/hw/kdrive/i810/i810_cursor.c,v 1.2 2001/12/10 16:34:20 keithp Exp $ */
 | |
| 
 | |
| /* i810_cursor.c: KDrive hardware cursor routines for the i810 chipset */
 | |
| 
 | |
| /*
 | |
|  * Authors:
 | |
|  *   Keith Whitwell <keith@tungstengraphics.com>
 | |
|  *   Pontus Lidman <pontus.lidman@nokia.com>
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include <config.h>
 | |
| #endif
 | |
| #include "kdrive.h"
 | |
| #include "kxv.h"
 | |
| #include "i810.h"
 | |
| #include "cursorstr.h"
 | |
| 
 | |
| #define SetupCursor(s)	    KdScreenPriv(pScreen); \
 | |
| 			    i810CardInfo(pScreenPriv); \
 | |
| 			    i810ScreenInfo(pScreenPriv); \
 | |
| 			    i810Cursor *pCurPriv = &i810s->cursor
 | |
| 
 | |
| 
 | |
| static void
 | |
| writeStandardMMIO(I810CardInfo *i810c, int addr, CARD8 val)
 | |
| {
 | |
|   moutb(addr, val);
 | |
| }
 | |
| 
 | |
| static void
 | |
| _i810MoveCursor(ScreenPtr pScreen, int x, int y)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810CardInfo(pScreenPriv);
 | |
|     int flag;
 | |
| 
 | |
|     if (I810_DEBUG & DEBUG_VERBOSE_CURSOR)
 | |
|       ErrorF( "I810SetCursorPosition %d %d\n", x, y);
 | |
| 
 | |
|     x += i810c->CursorOffset;
 | |
| 
 | |
|     if (x >= 0) flag = CURSOR_X_POS;
 | |
|     else {
 | |
|         flag = CURSOR_X_NEG;
 | |
|         x=-x;
 | |
|     }
 | |
| 
 | |
|     OUTREG8( CURSOR_X_LO, x&0xFF);
 | |
|     OUTREG8( CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
 | |
|     
 | |
|     if (y >= 0) flag = CURSOR_Y_POS;
 | |
|     else {
 | |
|         flag = CURSOR_Y_NEG;
 | |
|         y=-y;
 | |
|     }
 | |
|     OUTREG8( CURSOR_Y_LO, y&0xFF);
 | |
|     OUTREG8( CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
 | |
| 
 | |
|     /* Enable cursor */
 | |
|     OUTREG( CURSOR_BASEADDR, i810c->CursorPhysical);
 | |
|     OUTREG8( CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
 | |
| 
 | |
| }
 | |
| 
 | |
| static void i810LoadCursor(ScreenPtr pScreen, int x, int y);
 | |
| 
 | |
| static void
 | |
| i810MoveCursor (ScreenPtr pScreen, int x, int y)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
|     
 | |
|     if (!pCurPriv->has_cursor)
 | |
| 	return;
 | |
|     
 | |
|     if (!pScreenPriv->enabled)
 | |
| 	return;
 | |
|     
 | |
|     _i810MoveCursor (pScreen, x, y);
 | |
| 
 | |
|     i810LoadCursor(pScreen, x, y);
 | |
| }
 | |
| 
 | |
| static void
 | |
| _i810SetCursorColors(ScreenPtr pScreen)
 | |
| {
 | |
| 
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810CardInfo(pScreenPriv);
 | |
|     int tmp;
 | |
| 
 | |
|     int bg = 0xffffff;
 | |
|     int fg = 0x000000;
 | |
| 
 | |
|     tmp=INREG8(PIXPIPE_CONFIG_0);
 | |
|     tmp |= EXTENDED_PALETTE;
 | |
|     OUTREG8( PIXPIPE_CONFIG_0, tmp);
 | |
| 
 | |
|     writeStandardMMIO(i810c, DACMASK, 0xFF);
 | |
|     writeStandardMMIO(i810c, DACWX, 0x04);
 | |
| 
 | |
|     writeStandardMMIO(i810c, DACDATA, (bg & 0x00FF0000) >> 16);
 | |
|     writeStandardMMIO(i810c, DACDATA, (bg & 0x0000FF00) >> 8);
 | |
|     writeStandardMMIO(i810c, DACDATA, (bg & 0x000000FF));
 | |
| 
 | |
|     writeStandardMMIO(i810c, DACDATA, (fg & 0x00FF0000) >> 16);
 | |
|     writeStandardMMIO(i810c, DACDATA, (fg & 0x0000FF00) >> 8);
 | |
|     writeStandardMMIO(i810c, DACDATA, (fg & 0x000000FF));
 | |
| 
 | |
|     tmp=INREG8( PIXPIPE_CONFIG_0 );
 | |
|     tmp &= ~EXTENDED_PALETTE;
 | |
|     OUTREG8( PIXPIPE_CONFIG_0, tmp );
 | |
| }
 | |
| 
 | |
| #define InvertBits32(v) { \
 | |
|     v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
 | |
|     v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
 | |
|     v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
 | |
| }
 | |
| 
 | |
| static void i810LoadCursor(ScreenPtr pScreen, int x, int y)
 | |
| {
 | |
|     SetupCursor(pScreen);
 | |
| 
 | |
|     int		    h;
 | |
|     unsigned int   *msk, *mskLine, *src, *srcLine;
 | |
|     
 | |
|     int		    i, j;
 | |
|     int		    src_stride, src_width;
 | |
| 
 | |
|     CursorPtr	    pCursor = pCurPriv->pCursor;
 | |
|     CursorBitsPtr   bits = pCursor->bits;
 | |
|     CARD8 tmp;
 | |
|     unsigned int *ram, *ramLine;
 | |
| 
 | |
|     pCurPriv->pCursor = pCursor;
 | |
|     pCurPriv->xhot = pCursor->bits->xhot;
 | |
|     pCurPriv->yhot = pCursor->bits->yhot;
 | |
| 
 | |
|     ramLine = (unsigned int *) (i810c->FbBase + i810c->CursorStart);
 | |
|     mskLine = (unsigned int *) (bits->mask);
 | |
|     srcLine = (unsigned int *) (bits->source);
 | |
| 
 | |
|     h = bits->height;
 | |
|     if (h > I810_CURSOR_HEIGHT)
 | |
| 	h = I810_CURSOR_HEIGHT;
 | |
| 
 | |
|     src_stride = BitmapBytePad(bits->width);		/* bytes per line */
 | |
|     src_stride = (src_stride +3) >> 2;
 | |
|     src_width = (bits->width + 31) >> 5;
 | |
| 
 | |
|     for (i = 0; i < I810_CURSOR_HEIGHT; i++) {
 | |
| 
 | |
| 	msk = mskLine;
 | |
| 	src = srcLine;
 | |
|         ram = ramLine;
 | |
| 	mskLine += src_stride;
 | |
| 	srcLine += src_stride;
 | |
|         ramLine += I810_CURSOR_WIDTH / 16;
 | |
| 
 | |
| 	for (j = 0; j < I810_CURSOR_WIDTH / 32; j++) {
 | |
| 
 | |
| 	    unsigned long  m, s;
 | |
| 
 | |
| 	    if (i < h && j < src_width) 
 | |
| 	    {
 | |
| 		m = *msk++;
 | |
| 		s = *src++ & m;
 | |
| 		m = ~m;
 | |
| 		/* mask off right side */
 | |
| 		if (j == src_width - 1 && (bits->width & 31))
 | |
| 		{
 | |
| 		    m |= 0xffffffff << (bits->width & 31);
 | |
| 		}
 | |
| 	    }
 | |
| 	    else
 | |
| 	    {
 | |
| 		m = 0xffffffff;
 | |
| 		s = 0x00000000;
 | |
| 	    }
 | |
| 
 | |
|             InvertBits32(s);
 | |
|             InvertBits32(m);
 | |
| 
 | |
|             ram[2+j]=s;
 | |
|             ram[0+j]=m;
 | |
| 	}
 | |
|     }
 | |
|     /* Set new color */
 | |
|     _i810SetCursorColors (pScreen);
 | |
|      
 | |
|     /* Move to new position */
 | |
|     _i810MoveCursor (pScreen, x, y);
 | |
|     
 | |
|     /* Enable cursor */
 | |
|     OUTREG( CURSOR_BASEADDR, i810c->CursorPhysical);
 | |
|     OUTREG8( CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
 | |
|     
 | |
|     tmp = INREG8( PIXPIPE_CONFIG_0 );
 | |
|     tmp |= HW_CURSOR_ENABLE;
 | |
|     OUTREG8( PIXPIPE_CONFIG_0, tmp);
 | |
| }
 | |
| 
 | |
| static void
 | |
| i810UnloadCursor(ScreenPtr pScreen)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810CardInfo(pScreenPriv);
 | |
| 
 | |
|     unsigned char tmp;
 | |
|     
 | |
|     tmp=INREG8( PIXPIPE_CONFIG_0 );
 | |
|     tmp &= ~HW_CURSOR_ENABLE;
 | |
|     OUTREG8( PIXPIPE_CONFIG_0, tmp);
 | |
| }
 | |
| 
 | |
| 
 | |
| static Bool
 | |
| i810RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
| 
 | |
|     if (!pScreenPriv->enabled)
 | |
| 	return TRUE;
 | |
|     
 | |
|     /* miRecolorCursor does this */
 | |
|     if (pCurPriv->pCursor == pCursor)
 | |
|     {
 | |
| 	if (pCursor)
 | |
| 	{
 | |
| 	    int	    x, y;
 | |
| 	    
 | |
| 	    miPointerPosition (&x, &y);
 | |
| 	    i810LoadCursor (pScreen, x, y);
 | |
| 	}
 | |
|     }
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| static Bool
 | |
| i810UnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
 | |
| {
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| static void
 | |
| i810SetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
| 
 | |
|     pCurPriv->pCursor = pCursor;
 | |
|     
 | |
|     if (!pScreenPriv->enabled)
 | |
| 	return;
 | |
|     
 | |
|     if (pCursor)
 | |
| 	i810LoadCursor (pScreen, x, y);
 | |
|     else
 | |
| 	i810UnloadCursor (pScreen);
 | |
| }
 | |
| 
 | |
| miPointerSpriteFuncRec i810PointerSpriteFuncs = {
 | |
|     i810RealizeCursor,
 | |
|     i810UnrealizeCursor,
 | |
|     i810SetCursor,
 | |
|     i810MoveCursor,
 | |
| };
 | |
| 
 | |
| static void
 | |
| i810QueryBestSize (int class, 
 | |
|                    unsigned short *pwidth, unsigned short *pheight, 
 | |
|                    ScreenPtr pScreen)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
| 
 | |
|     switch (class)
 | |
|     {
 | |
|     case CursorShape:
 | |
| 	if (*pwidth > pCurPriv->width)
 | |
| 	    *pwidth = pCurPriv->width;
 | |
| 	if (*pheight > pCurPriv->height)
 | |
| 	    *pheight = pCurPriv->height;
 | |
| 	if (*pwidth > pScreen->width)
 | |
| 	    *pwidth = pScreen->width;
 | |
| 	if (*pheight > pScreen->height)
 | |
| 	    *pheight = pScreen->height;
 | |
| 	break;
 | |
|     default:
 | |
| 	fbQueryBestSize (class, pwidth, pheight, pScreen);
 | |
| 	break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| Bool
 | |
| i810CursorInit(ScreenPtr pScreen)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810CardInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
| 
 | |
|     if (!i810c->CursorStart) {
 | |
| 	pCurPriv->has_cursor = FALSE;
 | |
| 	return FALSE;
 | |
|     }
 | |
| 
 | |
|     pCurPriv->width = I810_CURSOR_WIDTH;
 | |
|     pCurPriv->height= I810_CURSOR_HEIGHT;
 | |
|     pScreen->QueryBestSize = i810QueryBestSize;
 | |
|     miPointerInitialize (pScreen,
 | |
| 			 &i810PointerSpriteFuncs,
 | |
| 			 &kdPointerScreenFuncs,
 | |
| 			 FALSE);
 | |
|     pCurPriv->has_cursor = TRUE;
 | |
|     pCurPriv->pCursor = NULL;
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| void
 | |
| i810CursorEnable (ScreenPtr pScreen)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
| 
 | |
|     if (pCurPriv->has_cursor)
 | |
|     {
 | |
| 	if (pCurPriv->pCursor)
 | |
| 	{
 | |
| 	    int	    x, y;
 | |
| 	    
 | |
| 	    miPointerPosition (&x, &y);
 | |
| 	    i810LoadCursor (pScreen, x, y);
 | |
| 	}
 | |
| 	else
 | |
| 	    i810UnloadCursor (pScreen);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| i810CursorDisable (ScreenPtr pScreen)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
| 
 | |
|     if (!pScreenPriv->enabled)
 | |
| 	return;
 | |
|     
 | |
|     if (pCurPriv->has_cursor)
 | |
|     {
 | |
| 	if (pCurPriv->pCursor)
 | |
| 	{
 | |
| 	    i810UnloadCursor (pScreen);
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| i810CursorFini (ScreenPtr pScreen)
 | |
| {
 | |
|     KdScreenPriv(pScreen);
 | |
|     i810ScreenInfo(pScreenPriv);
 | |
|     i810Cursor *pCurPriv = &i810s->cursor;
 | |
| 
 | |
|     pCurPriv->pCursor = NULL;
 | |
| }
 | |
| 
 |