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
29/*
30 * Authors:
31 *   Daryll Strauss <daryll@precisioninsight.com>
32 *
33 */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include "xf86.h"
40#include "xf86_OSproc.h"
41#include "compiler.h"
42
43#include "xf86fbman.h"
44
45#include "vgaHW.h"
46#include "xf86xv.h"
47#include "i740.h"
48
49static void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
50static void I740ShowCursor(ScrnInfoPtr pScrn);
51static void I740HideCursor(ScrnInfoPtr pScrn);
52static void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
53static void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
54static Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
55
56Bool
57I740CursorInit(ScreenPtr pScreen)
58{
59  ScrnInfoPtr pScrn;
60  I740Ptr pI740;
61  xf86CursorInfoPtr infoPtr;
62  FBAreaPtr fbarea;
63
64  pScrn = xf86ScreenToScrn(pScreen);
65  pI740 = I740PTR(pScrn);
66  pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
67  if (!infoPtr) return FALSE;
68
69  infoPtr->MaxWidth = 64;
70  infoPtr->MaxHeight = 64;
71  infoPtr->Flags =  HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
72    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
73    HARDWARE_CURSOR_INVERT_MASK |
74    HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
75    HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
76    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
77
78  infoPtr->SetCursorColors = I740SetCursorColors;
79  infoPtr->SetCursorPosition = I740SetCursorPosition;
80  infoPtr->LoadCursorImage = I740LoadCursorImage;
81  infoPtr->HideCursor = I740HideCursor;
82  infoPtr->ShowCursor = I740ShowCursor;
83  infoPtr->UseHWCursor = I740UseHWCursor;
84
85/*
86 * Allocate a region the full width and tall enough
87 * that at least 6K of video memory is consumed.
88 * Then use a 1 kilobyte piece that is 4K byte aligned
89 * within that region. KAO.
90 */
91  fbarea = xf86AllocateOffscreenArea(pScreen,
92				pScrn->displayWidth,
93				((6*1024)/(pScrn->displayWidth*pI740->cpp))+1,
94				0,0,0,0);
95  if (fbarea == NULL) {
96    pI740->CursorStart=0;
97    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
98	       "Hardware cursor disabled due to failure allocating offscreen memory.\n");
99  }
100  else {
101    pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000);
102  }
103  /*
104   * Perhaps move the cursor to the beginning of the frame buffer
105   * so that it never fails?
106   */
107  if (pI740->CursorStart>4*1024*1024) {
108    pI740->CursorStart=0;
109    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
110	       "Disabling hardware cursor due to large framebuffer\n");
111  }
112  return xf86InitCursor(pScreen, infoPtr);
113}
114
115static Bool
116I740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) {
117  ScrnInfoPtr pScrn;
118  I740Ptr pI740;
119
120  pScrn = xf86ScreenToScrn(pScreen);
121  pI740 = I740PTR(pScrn);
122  if (pScrn->currentMode->Flags&V_DBLSCAN)
123    return FALSE;
124  if (!pI740->CursorStart) return FALSE;
125  return TRUE;
126}
127
128static void
129I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) {
130  I740Ptr pI740;
131  int x, y;
132  CARD8 *pcurs;
133
134  pI740 = I740PTR(pScrn);
135  pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart);
136  for (y = 0; y < 64; y++) {
137    for (x = 0; x < 64 / 4; x++) {
138      *pcurs++ = *src++;
139    }
140  }
141}
142
143static void
144I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) {
145  I740Ptr pI740;
146  int flag;
147
148  pI740 = I740PTR(pScrn);
149  if (x >= 0) flag = CURSOR_X_POS;
150  else {
151    flag = CURSOR_X_NEG;
152    x=-x;
153  }
154  pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF);
155  pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
156
157  if (y >= 0) flag = CURSOR_Y_POS;
158  else {
159    flag = CURSOR_Y_NEG;
160    y=-y;
161  }
162  pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF);
163  pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
164}
165
166static void
167I740ShowCursor(ScrnInfoPtr pScrn) {
168  I740Ptr pI740;
169  unsigned char tmp;
170
171  pI740 = I740PTR(pScrn);
172  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO,
173		      (pI740->CursorStart & 0x0000F000) >> 8);
174  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI,
175		      (pI740->CursorStart & 0x003F0000) >> 16);
176  pI740->writeControl(pI740, XRX, CURSOR_CONTROL,
177		      CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
178
179  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
180  tmp |= HW_CURSOR_ENABLE;
181  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
182}
183
184static void
185I740HideCursor(ScrnInfoPtr pScrn) {
186  unsigned char tmp;
187  I740Ptr pI740;
188
189  pI740 = I740PTR(pScrn);
190  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
191  tmp &= ~HW_CURSOR_ENABLE;
192  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
193}
194
195static void
196I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) {
197  int tmp;
198  I740Ptr pI740;
199
200  pI740 = I740PTR(pScrn);
201  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
202  tmp |= EXTENDED_PALETTE;
203  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
204
205  pI740->writeStandard(pI740, DACMASK, 0xFF);
206  pI740->writeStandard(pI740, DACWX, 0x04);
207
208  pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16);
209  pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8);
210  pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF));
211
212  pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16);
213  pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8);
214  pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF));
215
216  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
217  tmp &= ~EXTENDED_PALETTE;
218  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
219}
220
221
222
223