text: /*
   * Hardware cursor support for Leo (ZX)
   *
   * Copyright 2000 by Jakub Jelinek <jakub@redhat.com>.
   *
   * Permission to use, copy, modify, distribute, and sell this software
   * and its documentation for any purpose is hereby granted without
   * fee, 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 Jakub
   * Jelinek not be used in advertising or publicity pertaining to
   * distribution of the software without specific, written prior
   * permission.  Jakub Jelinek makes no representations about the
   * suitability of this software for any purpose.  It is provided "as
   * is" without express or implied warranty.
   *
   * JAKUB JELINEK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
   * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS, IN NO EVENT SHALL JAKUB JELINEK 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.
   */
  
  #ifdef HAVE_CONFIG_H
  #include "config.h"
  #endif
  
  #include "leo.h"
  
  static void LeoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
  static void LeoShowCursor(ScrnInfoPtr pScrn);
  static void LeoHideCursor(ScrnInfoPtr pScrn);
  static void LeoSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
  static void LeoSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
  
  static void
  LeoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
  {
      LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
      int i, j, x, y;
      unsigned int *data = (unsigned int *)src, value;
  
      pLeo->CursorData = src;
      x = pLeo->CursorShiftX;
      y = pLeo->CursorShiftY;
      if (x >= 32 || y >= 32)
  	y = 32;
      pLeo->dac->cur_type = 0;
      for (j = 0; j < 2; j++) {
  	data += y;
  	for (i = y; i < 32; i++, data++) {
  	    value = (*data >> 16) | (*data << 16);
  	    value = ((value & 0xff00ff00) >> 8) |
  		    ((value & 0x00ff00ff) << 8);
  	    pLeo->dac->cur_data = value >> x;
  	}
  	for (i = 0; i < y; i++)
  	    pLeo->dac->cur_data = 0;
      }
  }
  
  static void 
  LeoShowCursor(ScrnInfoPtr pScrn)
  {
      LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
  
      pLeo->dac->cur_misc |= 0x80;
  }
  
  static void
  LeoHideCursor(ScrnInfoPtr pScrn)
  {
      LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
  
      pLeo->dac->cur_misc &= ~0x80;
      pLeo->CursorData = NULL;
  }
  
  static void
  LeoSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
  {
      LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
      int CursorShiftX = 0, CursorShiftY = 0;
  
      if (x < 0) {
  	CursorShiftX = -x;
  	x = 0;
  	if (CursorShiftX > 32)
  	    CursorShiftX = 32;
      }
      if (y < 0) {
  	CursorShiftY = -y;
  	y = 0;
  	if (CursorShiftY > 32)
  	    CursorShiftY = 32;
      }
      pLeo->dac->cur_misc &= ~0x80;
      if ((CursorShiftX != pLeo->CursorShiftX ||
  	 CursorShiftY != pLeo->CursorShiftY) &&
  	pLeo->CursorData != NULL) {
  	pLeo->CursorShiftX = CursorShiftX;
  	pLeo->CursorShiftY = CursorShiftY;
  	LeoLoadCursorImage(pScrn, pLeo->CursorData);
      }
  	
      pLeo->dac->cur_cursxy = ((y & 0x7ff) << 11) | (x & 0x7ff);
      pLeo->dac->cur_misc |= 0x30;
      pLeo->dac->cur_misc |= 0x80;
  }
  
  static void
  LeoSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
  {
      LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
  
      pLeo->dac->cur_type = 0x50;
      pLeo->dac->cur_data = bg;
      pLeo->dac->cur_data = fg;
      pLeo->dac->cur_misc |= 0x03;
  }
  
  Bool 
  LeoHWCursorInit(ScreenPtr pScreen)
  {
      ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
      LeoPtr pLeo;
      xf86CursorInfoPtr infoPtr;
  
      pLeo = GET_LEO_FROM_SCRN(pScrn);
      pLeo->CursorShiftX = 0;
      pLeo->CursorShiftY = 0;
      pLeo->CursorData = NULL;
  
      infoPtr = xf86CreateCursorInfoRec();
      if(!infoPtr) return FALSE;
      
      pLeo->CursorInfoRec = infoPtr;
      pLeo->dac = (LeoCursor *)((char *)pLeo->fb + LEO_LX0_CURSOR_VOFF);
  
      infoPtr->MaxWidth = 32;
      infoPtr->MaxHeight = 32;
      infoPtr->Flags =  HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
  	HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
  	HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
  	HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
  
      infoPtr->SetCursorColors = LeoSetCursorColors;
      infoPtr->SetCursorPosition = LeoSetCursorPosition;
      infoPtr->LoadCursorImage = LeoLoadCursorImage;
      infoPtr->HideCursor = LeoHideCursor;
      infoPtr->ShowCursor = LeoShowCursor;
      infoPtr->UseHWCursor = NULL;
  
      return xf86InitCursor(pScreen, infoPtr);
  }
  