i740_cursor.c revision 301ea0f4
1301ea0f4Smrg
2301ea0f4Smrg/**************************************************************************
3301ea0f4Smrg
4301ea0f4SmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5301ea0f4SmrgAll Rights Reserved.
6301ea0f4Smrg
7301ea0f4SmrgPermission is hereby granted, free of charge, to any person obtaining a
8301ea0f4Smrgcopy of this software and associated documentation files (the
9301ea0f4Smrg"Software"), to deal in the Software without restriction, including
10301ea0f4Smrgwithout limitation the rights to use, copy, modify, merge, publish,
11301ea0f4Smrgdistribute, sub license, and/or sell copies of the Software, and to
12301ea0f4Smrgpermit persons to whom the Software is furnished to do so, subject to
13301ea0f4Smrgthe following conditions:
14301ea0f4Smrg
15301ea0f4SmrgThe above copyright notice and this permission notice (including the
16301ea0f4Smrgnext paragraph) shall be included in all copies or substantial portions
17301ea0f4Smrgof the Software.
18301ea0f4Smrg
19301ea0f4SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20301ea0f4SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21301ea0f4SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22301ea0f4SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23301ea0f4SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24301ea0f4SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25301ea0f4SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26301ea0f4Smrg
27301ea0f4Smrg**************************************************************************/
28301ea0f4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c,v 1.4 2000/02/23 04:47:13 martin Exp $ */
29301ea0f4Smrg
30301ea0f4Smrg/*
31301ea0f4Smrg * Authors:
32301ea0f4Smrg *   Daryll Strauss <daryll@precisioninsight.com>
33301ea0f4Smrg *
34301ea0f4Smrg */
35301ea0f4Smrg
36301ea0f4Smrg#ifdef HAVE_CONFIG_H
37301ea0f4Smrg#include "config.h"
38301ea0f4Smrg#endif
39301ea0f4Smrg
40301ea0f4Smrg#include "xf86.h"
41301ea0f4Smrg#include "xf86_OSproc.h"
42301ea0f4Smrg#include "compiler.h"
43301ea0f4Smrg
44301ea0f4Smrg#include "xf86fbman.h"
45301ea0f4Smrg
46301ea0f4Smrg#include "vgaHW.h"
47301ea0f4Smrg#include "xf86xv.h"
48301ea0f4Smrg#include "i740.h"
49301ea0f4Smrg
50301ea0f4Smrgstatic void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
51301ea0f4Smrgstatic void I740ShowCursor(ScrnInfoPtr pScrn);
52301ea0f4Smrgstatic void I740HideCursor(ScrnInfoPtr pScrn);
53301ea0f4Smrgstatic void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
54301ea0f4Smrgstatic void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
55301ea0f4Smrgstatic Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
56301ea0f4Smrg
57301ea0f4SmrgBool
58301ea0f4SmrgI740CursorInit(ScreenPtr pScreen)
59301ea0f4Smrg{
60301ea0f4Smrg  ScrnInfoPtr pScrn;
61301ea0f4Smrg  I740Ptr pI740;
62301ea0f4Smrg  xf86CursorInfoPtr infoPtr;
63301ea0f4Smrg  FBAreaPtr fbarea;
64301ea0f4Smrg
65301ea0f4Smrg  pScrn = xf86Screens[pScreen->myNum];
66301ea0f4Smrg  pI740 = I740PTR(pScrn);
67301ea0f4Smrg  pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
68301ea0f4Smrg  if (!infoPtr) return FALSE;
69301ea0f4Smrg
70301ea0f4Smrg  infoPtr->MaxWidth = 64;
71301ea0f4Smrg  infoPtr->MaxHeight = 64;
72301ea0f4Smrg  infoPtr->Flags =  HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
73301ea0f4Smrg    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
74301ea0f4Smrg    HARDWARE_CURSOR_INVERT_MASK |
75301ea0f4Smrg    HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
76301ea0f4Smrg    HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
77301ea0f4Smrg    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
78301ea0f4Smrg
79301ea0f4Smrg  infoPtr->SetCursorColors = I740SetCursorColors;
80301ea0f4Smrg  infoPtr->SetCursorPosition = I740SetCursorPosition;
81301ea0f4Smrg  infoPtr->LoadCursorImage = I740LoadCursorImage;
82301ea0f4Smrg  infoPtr->HideCursor = I740HideCursor;
83301ea0f4Smrg  infoPtr->ShowCursor = I740ShowCursor;
84301ea0f4Smrg  infoPtr->UseHWCursor = I740UseHWCursor;
85301ea0f4Smrg
86301ea0f4Smrg/*
87301ea0f4Smrg * Allocate a region the full width and tall enough
88301ea0f4Smrg * that at least 6K of video memory is consumed.
89301ea0f4Smrg * Then use a 1 kilobyte piece that is 4K byte aligned
90301ea0f4Smrg * within that region. KAO.
91301ea0f4Smrg */
92301ea0f4Smrg  fbarea = xf86AllocateOffscreenArea(pScreen,
93301ea0f4Smrg				pScrn->displayWidth,
94301ea0f4Smrg				((6*1024)/(pScrn->displayWidth*pI740->cpp))+1,
95301ea0f4Smrg				0,0,0,0);
96301ea0f4Smrg  if (fbarea == NULL) {
97301ea0f4Smrg    pI740->CursorStart=0;
98301ea0f4Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
99301ea0f4Smrg	       "Hardware cursor disabled due to failure allocating offscreen memory.\n");
100301ea0f4Smrg  }
101301ea0f4Smrg  else {
102301ea0f4Smrg    pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000);
103301ea0f4Smrg  }
104301ea0f4Smrg  /*
105301ea0f4Smrg   * Perhaps move the cursor to the beginning of the frame buffer
106301ea0f4Smrg   * so that it never fails?
107301ea0f4Smrg   */
108301ea0f4Smrg  if (pI740->CursorStart>4*1024*1024) {
109301ea0f4Smrg    pI740->CursorStart=0;
110301ea0f4Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
111301ea0f4Smrg	       "Disabling hardware cursor due to large framebuffer\n");
112301ea0f4Smrg  }
113301ea0f4Smrg  return xf86InitCursor(pScreen, infoPtr);
114301ea0f4Smrg}
115301ea0f4Smrg
116301ea0f4Smrgstatic Bool
117301ea0f4SmrgI740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) {
118301ea0f4Smrg  ScrnInfoPtr pScrn;
119301ea0f4Smrg  I740Ptr pI740;
120301ea0f4Smrg
121301ea0f4Smrg  pScrn = xf86Screens[pScreen->myNum];
122301ea0f4Smrg  pI740 = I740PTR(pScrn);
123301ea0f4Smrg  if (pScrn->currentMode->Flags&V_DBLSCAN)
124301ea0f4Smrg    return FALSE;
125301ea0f4Smrg  if (!pI740->CursorStart) return FALSE;
126301ea0f4Smrg  return TRUE;
127301ea0f4Smrg}
128301ea0f4Smrg
129301ea0f4Smrgstatic void
130301ea0f4SmrgI740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) {
131301ea0f4Smrg  I740Ptr pI740;
132301ea0f4Smrg  int x, y;
133301ea0f4Smrg  CARD8 *pcurs;
134301ea0f4Smrg
135301ea0f4Smrg  pI740 = I740PTR(pScrn);
136301ea0f4Smrg  pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart);
137301ea0f4Smrg  for (y = 0; y < 64; y++) {
138301ea0f4Smrg    for (x = 0; x < 64 / 4; x++) {
139301ea0f4Smrg      *pcurs++ = *src++;
140301ea0f4Smrg    }
141301ea0f4Smrg  }
142301ea0f4Smrg}
143301ea0f4Smrg
144301ea0f4Smrgstatic void
145301ea0f4SmrgI740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) {
146301ea0f4Smrg  I740Ptr pI740;
147301ea0f4Smrg  int flag;
148301ea0f4Smrg
149301ea0f4Smrg  pI740 = I740PTR(pScrn);
150301ea0f4Smrg  if (x >= 0) flag = CURSOR_X_POS;
151301ea0f4Smrg  else {
152301ea0f4Smrg    flag = CURSOR_X_NEG;
153301ea0f4Smrg    x=-x;
154301ea0f4Smrg  }
155301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF);
156301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
157301ea0f4Smrg
158301ea0f4Smrg  if (y >= 0) flag = CURSOR_Y_POS;
159301ea0f4Smrg  else {
160301ea0f4Smrg    flag = CURSOR_Y_NEG;
161301ea0f4Smrg    y=-y;
162301ea0f4Smrg  }
163301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF);
164301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
165301ea0f4Smrg}
166301ea0f4Smrg
167301ea0f4Smrgstatic void
168301ea0f4SmrgI740ShowCursor(ScrnInfoPtr pScrn) {
169301ea0f4Smrg  I740Ptr pI740;
170301ea0f4Smrg  unsigned char tmp;
171301ea0f4Smrg
172301ea0f4Smrg  pI740 = I740PTR(pScrn);
173301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO,
174301ea0f4Smrg		      (pI740->CursorStart & 0x0000F000) >> 8);
175301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI,
176301ea0f4Smrg		      (pI740->CursorStart & 0x003F0000) >> 16);
177301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_CONTROL,
178301ea0f4Smrg		      CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
179301ea0f4Smrg
180301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
181301ea0f4Smrg  tmp |= HW_CURSOR_ENABLE;
182301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
183301ea0f4Smrg}
184301ea0f4Smrg
185301ea0f4Smrgstatic void
186301ea0f4SmrgI740HideCursor(ScrnInfoPtr pScrn) {
187301ea0f4Smrg  unsigned char tmp;
188301ea0f4Smrg  I740Ptr pI740;
189301ea0f4Smrg
190301ea0f4Smrg  pI740 = I740PTR(pScrn);
191301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
192301ea0f4Smrg  tmp &= ~HW_CURSOR_ENABLE;
193301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
194301ea0f4Smrg}
195301ea0f4Smrg
196301ea0f4Smrgstatic void
197301ea0f4SmrgI740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) {
198301ea0f4Smrg  int tmp;
199301ea0f4Smrg  I740Ptr pI740;
200301ea0f4Smrg
201301ea0f4Smrg  pI740 = I740PTR(pScrn);
202301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
203301ea0f4Smrg  tmp |= EXTENDED_PALETTE;
204301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
205301ea0f4Smrg
206301ea0f4Smrg  pI740->writeStandard(pI740, DACMASK, 0xFF);
207301ea0f4Smrg  pI740->writeStandard(pI740, DACWX, 0x04);
208301ea0f4Smrg
209301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16);
210301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8);
211301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF));
212301ea0f4Smrg
213301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16);
214301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8);
215301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF));
216301ea0f4Smrg
217301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
218301ea0f4Smrg  tmp &= ~EXTENDED_PALETTE;
219301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
220301ea0f4Smrg}
221301ea0f4Smrg
222301ea0f4Smrg
223301ea0f4Smrg
224