1428d7b3dSmrg
2428d7b3dSmrg/**************************************************************************
3428d7b3dSmrg
4428d7b3dSmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5428d7b3dSmrgAll Rights Reserved.
6428d7b3dSmrg
7428d7b3dSmrgPermission is hereby granted, free of charge, to any person obtaining a
8428d7b3dSmrgcopy of this software and associated documentation files (the
9428d7b3dSmrg"Software"), to deal in the Software without restriction, including
10428d7b3dSmrgwithout limitation the rights to use, copy, modify, merge, publish,
11428d7b3dSmrgdistribute, sub license, and/or sell copies of the Software, and to
12428d7b3dSmrgpermit persons to whom the Software is furnished to do so, subject to
13428d7b3dSmrgthe following conditions:
14428d7b3dSmrg
15428d7b3dSmrgThe above copyright notice and this permission notice (including the
16428d7b3dSmrgnext paragraph) shall be included in all copies or substantial portions
17428d7b3dSmrgof the Software.
18428d7b3dSmrg
19428d7b3dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20428d7b3dSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21428d7b3dSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22428d7b3dSmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23428d7b3dSmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24428d7b3dSmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25428d7b3dSmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26428d7b3dSmrg
27428d7b3dSmrg**************************************************************************/
28428d7b3dSmrg
29428d7b3dSmrg#ifdef HAVE_CONFIG_H
30428d7b3dSmrg#include "config.h"
31428d7b3dSmrg#endif
32428d7b3dSmrg
33428d7b3dSmrg/*
34428d7b3dSmrg * Authors:
35428d7b3dSmrg *   Keith Whitwell <keith@tungstengraphics.com>
36428d7b3dSmrg *
37428d7b3dSmrg * Add ARGB HW cursor support:
38428d7b3dSmrg *   Alan Hourihane <alanh@tungstengraphics.com>
39428d7b3dSmrg *
40428d7b3dSmrg */
41428d7b3dSmrg
42428d7b3dSmrg#include "xorg-server.h"
43428d7b3dSmrg#include "xf86.h"
44428d7b3dSmrg#include "xf86_OSproc.h"
45428d7b3dSmrg#include "compiler.h"
46428d7b3dSmrg
47428d7b3dSmrg#include "xf86fbman.h"
48428d7b3dSmrg
49428d7b3dSmrg#include "i810.h"
50428d7b3dSmrg
51428d7b3dSmrgstatic Bool I810UseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
52428d7b3dSmrgstatic void I810LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
53428d7b3dSmrgstatic void I810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
54428d7b3dSmrgstatic void I810ShowCursor(ScrnInfoPtr pScrn);
55428d7b3dSmrgstatic void I810HideCursor(ScrnInfoPtr pScrn);
56428d7b3dSmrgstatic void I810SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
57428d7b3dSmrgstatic void I810SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
58428d7b3dSmrgstatic Bool I810UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
59428d7b3dSmrg
60428d7b3dSmrgBool
61428d7b3dSmrgI810CursorInit(ScreenPtr pScreen)
62428d7b3dSmrg{
63428d7b3dSmrg   ScrnInfoPtr pScrn;
64428d7b3dSmrg   I810Ptr pI810;
65428d7b3dSmrg   xf86CursorInfoPtr infoPtr;
66428d7b3dSmrg
67428d7b3dSmrg   pScrn = xf86ScreenToScrn(pScreen);
68428d7b3dSmrg   pI810 = I810PTR(pScrn);
69428d7b3dSmrg   pI810->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
70428d7b3dSmrg   if (!infoPtr)
71428d7b3dSmrg      return FALSE;
72428d7b3dSmrg
73428d7b3dSmrg   infoPtr->MaxWidth = 64;
74428d7b3dSmrg   infoPtr->MaxHeight = 64;
75428d7b3dSmrg   infoPtr->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
76428d7b3dSmrg		     HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
77428d7b3dSmrg		     HARDWARE_CURSOR_INVERT_MASK |
78428d7b3dSmrg		     HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
79428d7b3dSmrg		     HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
80428d7b3dSmrg		     HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 0);
81428d7b3dSmrg
82428d7b3dSmrg   infoPtr->SetCursorColors = I810SetCursorColors;
83428d7b3dSmrg   infoPtr->SetCursorPosition = I810SetCursorPosition;
84428d7b3dSmrg   infoPtr->LoadCursorImage = I810LoadCursorImage;
85428d7b3dSmrg   infoPtr->HideCursor = I810HideCursor;
86428d7b3dSmrg   infoPtr->ShowCursor = I810ShowCursor;
87428d7b3dSmrg   infoPtr->UseHWCursor = I810UseHWCursor;
88428d7b3dSmrg#ifdef ARGB_CURSOR
89428d7b3dSmrg   pI810->CursorIsARGB = FALSE;
90428d7b3dSmrg
91428d7b3dSmrg   if (!pI810->CursorARGBPhysical) {
92428d7b3dSmrg      infoPtr->UseHWCursorARGB = I810UseHWCursorARGB;
93428d7b3dSmrg      infoPtr->LoadCursorARGB = I810LoadCursorARGB;
94428d7b3dSmrg   }
95428d7b3dSmrg#endif
96428d7b3dSmrg
97428d7b3dSmrg   return xf86InitCursor(pScreen, infoPtr);
98428d7b3dSmrg}
99428d7b3dSmrg
100428d7b3dSmrg#ifdef ARGB_CURSOR
101428d7b3dSmrg#include "cursorstr.h"
102428d7b3dSmrg
103428d7b3dSmrgstatic Bool I810UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
104428d7b3dSmrg{
105428d7b3dSmrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
106428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
107428d7b3dSmrg
108428d7b3dSmrg   if (!pI810->CursorARGBPhysical)
109428d7b3dSmrg      return FALSE;
110428d7b3dSmrg
111428d7b3dSmrg   if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64)
112428d7b3dSmrg      return TRUE;
113428d7b3dSmrg
114428d7b3dSmrg   return FALSE;
115428d7b3dSmrg}
116428d7b3dSmrg
117428d7b3dSmrgstatic void I810LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
118428d7b3dSmrg{
119428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
120428d7b3dSmrg   uint32_t *pcurs = (uint32_t *) (pI810->FbBase + pI810->CursorStart);
121428d7b3dSmrg   uint32_t *image = (uint32_t *) pCurs->bits->argb;
122428d7b3dSmrg   int x, y, w, h;
123428d7b3dSmrg
124428d7b3dSmrg#ifdef ARGB_CURSOR
125428d7b3dSmrg   pI810->CursorIsARGB = TRUE;
126428d7b3dSmrg#endif
127428d7b3dSmrg
128428d7b3dSmrg   w = pCurs->bits->width;
129428d7b3dSmrg   h = pCurs->bits->height;
130428d7b3dSmrg
131428d7b3dSmrg   for (y = 0; y < h; y++)
132428d7b3dSmrg   {
133428d7b3dSmrg      for (x = 0; x < w; x++)
134428d7b3dSmrg         *pcurs++ = *image++;
135428d7b3dSmrg      for (; x < 64; x++)
136428d7b3dSmrg         *pcurs++ = 0;
137428d7b3dSmrg   }
138428d7b3dSmrg
139428d7b3dSmrg   for (; y < 64; y++)
140428d7b3dSmrg      for (x = 0; x < 64; x++)
141428d7b3dSmrg         *pcurs++ = 0;
142428d7b3dSmrg}
143428d7b3dSmrg#endif
144428d7b3dSmrg
145428d7b3dSmrgstatic Bool
146428d7b3dSmrgI810UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
147428d7b3dSmrg{
148428d7b3dSmrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
149428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
150428d7b3dSmrg
151428d7b3dSmrg   if (!pI810->CursorPhysical)
152428d7b3dSmrg      return FALSE;
153428d7b3dSmrg   else
154428d7b3dSmrg      return TRUE;
155428d7b3dSmrg}
156428d7b3dSmrg
157428d7b3dSmrgstatic void
158428d7b3dSmrgI810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
159428d7b3dSmrg{
160428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
161428d7b3dSmrg   uint8_t *pcurs = (uint8_t *) (pI810->FbBase + pI810->CursorStart);
162428d7b3dSmrg   int x, y;
163428d7b3dSmrg
164428d7b3dSmrg#ifdef ARGB_CURSOR
165428d7b3dSmrg   pI810->CursorIsARGB = FALSE;
166428d7b3dSmrg#endif
167428d7b3dSmrg
168428d7b3dSmrg   for (y = 0; y < 64; y++) {
169428d7b3dSmrg      for (x = 0; x < 64 / 4; x++) {
170428d7b3dSmrg	 *pcurs++ = *src++;
171428d7b3dSmrg      }
172428d7b3dSmrg   }
173428d7b3dSmrg}
174428d7b3dSmrg
175428d7b3dSmrgstatic void
176428d7b3dSmrgI810SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
177428d7b3dSmrg{
178428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
179428d7b3dSmrg   int flag;
180428d7b3dSmrg
181428d7b3dSmrg   x += pI810->CursorOffset;
182428d7b3dSmrg
183428d7b3dSmrg   if (x >= 0)
184428d7b3dSmrg      flag = CURSOR_X_POS;
185428d7b3dSmrg   else {
186428d7b3dSmrg      flag = CURSOR_X_NEG;
187428d7b3dSmrg      x = -x;
188428d7b3dSmrg   }
189428d7b3dSmrg
190428d7b3dSmrg   OUTREG8(CURSOR_X_LO, x & 0xFF);
191428d7b3dSmrg   OUTREG8(CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
192428d7b3dSmrg
193428d7b3dSmrg   if (y >= 0)
194428d7b3dSmrg      flag = CURSOR_Y_POS;
195428d7b3dSmrg   else {
196428d7b3dSmrg      flag = CURSOR_Y_NEG;
197428d7b3dSmrg      y = -y;
198428d7b3dSmrg   }
199428d7b3dSmrg   OUTREG8(CURSOR_Y_LO, y & 0xFF);
200428d7b3dSmrg   OUTREG8(CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
201428d7b3dSmrg
202428d7b3dSmrg   if (pI810->CursorIsARGB)
203428d7b3dSmrg      OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical);
204428d7b3dSmrg   else
205428d7b3dSmrg      OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical);
206428d7b3dSmrg}
207428d7b3dSmrg
208428d7b3dSmrgstatic void
209428d7b3dSmrgI810ShowCursor(ScrnInfoPtr pScrn)
210428d7b3dSmrg{
211428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
212428d7b3dSmrg   unsigned char tmp;
213428d7b3dSmrg
214428d7b3dSmrg   if (pI810->CursorIsARGB) {
215428d7b3dSmrg      OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical);
216428d7b3dSmrg      OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_ARGB_AX);
217428d7b3dSmrg   } else {
218428d7b3dSmrg      OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical);
219428d7b3dSmrg      OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
220428d7b3dSmrg   }
221428d7b3dSmrg
222428d7b3dSmrg   tmp = INREG8(PIXPIPE_CONFIG_0);
223428d7b3dSmrg   tmp |= HW_CURSOR_ENABLE;
224428d7b3dSmrg   OUTREG8(PIXPIPE_CONFIG_0, tmp);
225428d7b3dSmrg}
226428d7b3dSmrg
227428d7b3dSmrgstatic void
228428d7b3dSmrgI810HideCursor(ScrnInfoPtr pScrn)
229428d7b3dSmrg{
230428d7b3dSmrg   unsigned char tmp;
231428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
232428d7b3dSmrg
233428d7b3dSmrg   tmp = INREG8(PIXPIPE_CONFIG_0);
234428d7b3dSmrg   tmp &= ~HW_CURSOR_ENABLE;
235428d7b3dSmrg   OUTREG8(PIXPIPE_CONFIG_0, tmp);
236428d7b3dSmrg}
237428d7b3dSmrg
238428d7b3dSmrgstatic void
239428d7b3dSmrgI810SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
240428d7b3dSmrg{
241428d7b3dSmrg   int tmp;
242428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
243428d7b3dSmrg   vgaHWPtr hwp;
244428d7b3dSmrg
245428d7b3dSmrg#ifdef ARGB_CURSOR
246428d7b3dSmrg   if (pI810->CursorIsARGB)
247428d7b3dSmrg      return;
248428d7b3dSmrg#endif
249428d7b3dSmrg
250428d7b3dSmrg   hwp = VGAHWPTR(pScrn);
251428d7b3dSmrg
252428d7b3dSmrg   tmp = INREG8(PIXPIPE_CONFIG_0);
253428d7b3dSmrg   tmp |= EXTENDED_PALETTE;
254428d7b3dSmrg   OUTREG8(PIXPIPE_CONFIG_0, tmp);
255428d7b3dSmrg
256428d7b3dSmrg   hwp->writeDacMask(hwp, 0xFF);
257428d7b3dSmrg   hwp->writeDacWriteAddr(hwp, 0x04);
258428d7b3dSmrg
259428d7b3dSmrg   hwp->writeDacData(hwp, (bg & 0x00FF0000) >> 16);
260428d7b3dSmrg   hwp->writeDacData(hwp, (bg & 0x0000FF00) >> 8);
261428d7b3dSmrg   hwp->writeDacData(hwp, (bg & 0x000000FF));
262428d7b3dSmrg
263428d7b3dSmrg   hwp->writeDacData(hwp, (fg & 0x00FF0000) >> 16);
264428d7b3dSmrg   hwp->writeDacData(hwp, (fg & 0x0000FF00) >> 8);
265428d7b3dSmrg   hwp->writeDacData(hwp, (fg & 0x000000FF));
266428d7b3dSmrg
267428d7b3dSmrg   tmp = INREG8(PIXPIPE_CONFIG_0);
268428d7b3dSmrg   tmp &= ~EXTENDED_PALETTE;
269428d7b3dSmrg   OUTREG8(PIXPIPE_CONFIG_0, tmp);
270428d7b3dSmrg}
271