i740_cursor.c revision 301ea0f4
1
2/**************************************************************************
3
4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5All Rights Reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining a
8copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sub license, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice (including the
16next paragraph) shall be included in all copies or substantial portions
17of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27**************************************************************************/
28/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c,v 1.4 2000/02/23 04:47:13 martin Exp $ */
29
30/*
31 * Authors:
32 *   Daryll Strauss <daryll@precisioninsight.com>
33 *
34 */
35
36#ifdef HAVE_CONFIG_H
37#include "config.h"
38#endif
39
40#include "xf86.h"
41#include "xf86_OSproc.h"
42#include "compiler.h"
43
44#include "xf86fbman.h"
45
46#include "vgaHW.h"
47#include "xf86xv.h"
48#include "i740.h"
49
50static void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
51static void I740ShowCursor(ScrnInfoPtr pScrn);
52static void I740HideCursor(ScrnInfoPtr pScrn);
53static void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
54static void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
55static Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
56
57Bool
58I740CursorInit(ScreenPtr pScreen)
59{
60  ScrnInfoPtr pScrn;
61  I740Ptr pI740;
62  xf86CursorInfoPtr infoPtr;
63  FBAreaPtr fbarea;
64
65  pScrn = xf86Screens[pScreen->myNum];
66  pI740 = I740PTR(pScrn);
67  pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
68  if (!infoPtr) return FALSE;
69
70  infoPtr->MaxWidth = 64;
71  infoPtr->MaxHeight = 64;
72  infoPtr->Flags =  HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
73    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
74    HARDWARE_CURSOR_INVERT_MASK |
75    HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
76    HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
77    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
78
79  infoPtr->SetCursorColors = I740SetCursorColors;
80  infoPtr->SetCursorPosition = I740SetCursorPosition;
81  infoPtr->LoadCursorImage = I740LoadCursorImage;
82  infoPtr->HideCursor = I740HideCursor;
83  infoPtr->ShowCursor = I740ShowCursor;
84  infoPtr->UseHWCursor = I740UseHWCursor;
85
86/*
87 * Allocate a region the full width and tall enough
88 * that at least 6K of video memory is consumed.
89 * Then use a 1 kilobyte piece that is 4K byte aligned
90 * within that region. KAO.
91 */
92  fbarea = xf86AllocateOffscreenArea(pScreen,
93				pScrn->displayWidth,
94				((6*1024)/(pScrn->displayWidth*pI740->cpp))+1,
95				0,0,0,0);
96  if (fbarea == NULL) {
97    pI740->CursorStart=0;
98    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
99	       "Hardware cursor disabled due to failure allocating offscreen memory.\n");
100  }
101  else {
102    pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000);
103  }
104  /*
105   * Perhaps move the cursor to the beginning of the frame buffer
106   * so that it never fails?
107   */
108  if (pI740->CursorStart>4*1024*1024) {
109    pI740->CursorStart=0;
110    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
111	       "Disabling hardware cursor due to large framebuffer\n");
112  }
113  return xf86InitCursor(pScreen, infoPtr);
114}
115
116static Bool
117I740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) {
118  ScrnInfoPtr pScrn;
119  I740Ptr pI740;
120
121  pScrn = xf86Screens[pScreen->myNum];
122  pI740 = I740PTR(pScrn);
123  if (pScrn->currentMode->Flags&V_DBLSCAN)
124    return FALSE;
125  if (!pI740->CursorStart) return FALSE;
126  return TRUE;
127}
128
129static void
130I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) {
131  I740Ptr pI740;
132  int x, y;
133  CARD8 *pcurs;
134
135  pI740 = I740PTR(pScrn);
136  pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart);
137  for (y = 0; y < 64; y++) {
138    for (x = 0; x < 64 / 4; x++) {
139      *pcurs++ = *src++;
140    }
141  }
142}
143
144static void
145I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) {
146  I740Ptr pI740;
147  int flag;
148
149  pI740 = I740PTR(pScrn);
150  if (x >= 0) flag = CURSOR_X_POS;
151  else {
152    flag = CURSOR_X_NEG;
153    x=-x;
154  }
155  pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF);
156  pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
157
158  if (y >= 0) flag = CURSOR_Y_POS;
159  else {
160    flag = CURSOR_Y_NEG;
161    y=-y;
162  }
163  pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF);
164  pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
165}
166
167static void
168I740ShowCursor(ScrnInfoPtr pScrn) {
169  I740Ptr pI740;
170  unsigned char tmp;
171
172  pI740 = I740PTR(pScrn);
173  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO,
174		      (pI740->CursorStart & 0x0000F000) >> 8);
175  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI,
176		      (pI740->CursorStart & 0x003F0000) >> 16);
177  pI740->writeControl(pI740, XRX, CURSOR_CONTROL,
178		      CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
179
180  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
181  tmp |= HW_CURSOR_ENABLE;
182  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
183}
184
185static void
186I740HideCursor(ScrnInfoPtr pScrn) {
187  unsigned char tmp;
188  I740Ptr pI740;
189
190  pI740 = I740PTR(pScrn);
191  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
192  tmp &= ~HW_CURSOR_ENABLE;
193  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
194}
195
196static void
197I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) {
198  int tmp;
199  I740Ptr pI740;
200
201  pI740 = I740PTR(pScrn);
202  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
203  tmp |= EXTENDED_PALETTE;
204  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
205
206  pI740->writeStandard(pI740, DACMASK, 0xFF);
207  pI740->writeStandard(pI740, DACWX, 0x04);
208
209  pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16);
210  pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8);
211  pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF));
212
213  pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16);
214  pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8);
215  pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF));
216
217  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
218  tmp &= ~EXTENDED_PALETTE;
219  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
220}
221
222
223
224