1/* Copyright (c) 2003-2006 Advanced Micro Devices, Inc.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 *
21 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22 * contributors may be used to endorse or promote products derived from this
23 * software without specific prior written permission.
24 * */
25
26/*
27 * File Contents:   Xfree cursor implementation routines for geode HWcursor
28 *                  init.setting cursor color,image etc. are done here.
29 *
30 * Project:         Geode Xfree Frame buffer device driver.
31 * */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include "xorg-server.h"
38
39#include "xf86.h"
40#include "xf86_OSproc.h"
41#include "xf86Pci.h"
42// #include "xf86PciInfo.h"
43#include "geode.h"
44
45/* Forward declarations of the functions */
46static void GXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg);
47static void GXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y);
48static Bool GXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
49extern void GXSetVideoPosition(int x, int y, int width, int height,
50                               short src_w, short src_h, short drw_w,
51                               short drw_h, int id, int offset,
52                               ScrnInfoPtr pScrn);
53
54/*----------------------------------------------------------------------------
55 * GXHWCursorInit.
56 *
57 * Description	:This function sets the cursor information by probing the
58 * 				hardware.
59 *
60 * Parameters.
61 *     pScrn	:Screeen pointer structure.
62 *
63 * Returns		:TRUE on success and FALSE on Failure
64 *
65 * Comments		:Geode supports the hardware_cursor,no need to enable SW
66 *              cursor.
67 *----------------------------------------------------------------------------
68 */
69Bool
70GXHWCursorInit(ScreenPtr pScrn)
71{
72    ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn);
73    GeodeRec *pGeode = GEODEPTR(pScrni);
74    xf86CursorInfoPtr infoPtr;
75
76    infoPtr = xf86CreateCursorInfoRec();
77    if (!infoPtr)
78        return FALSE;
79    /* the geode structure is initialized with the cursor infoRec */
80    pGeode->CursorInfo = infoPtr;
81    infoPtr->MaxWidth = 32;
82    infoPtr->MaxHeight = 32;
83    /* setting up the cursor flags */
84    infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
85        HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
86        HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
87    /* cursor info ptr is initialized with the values obtained from
88     * * durnago calls
89     */
90    infoPtr->SetCursorColors = GXSetCursorColors;
91    infoPtr->SetCursorPosition = GXSetCursorPosition;
92    infoPtr->LoadCursorImage = GXLoadCursorImage;
93    infoPtr->HideCursor = GXHideCursor;
94    infoPtr->ShowCursor = GXShowCursor;
95    infoPtr->UseHWCursor = GXUseHWCursor;
96    return (xf86InitCursor(pScrn, infoPtr));
97}
98
99/*----------------------------------------------------------------------------
100 * GXSetCursorColors.
101 *
102 * Description	:This function sets the cursor foreground and background
103 *              colors
104 * Parameters:
105 *    pScrn:	Screeen pointer structure.
106 *    bg:		Specifies the color value of cursor background color.
107 *    fg:		Specifies the color value of cursor foreground color.
108 *
109 * Returns:	none.
110 *
111 * Comments:	The integer color value passed by this function is
112 *              converted into  * RGB  value by the gfx_set_color routines.
113 *----------------------------------------------------------------------------
114 */
115static void
116GXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg)
117{
118    GFX(set_cursor_colors(bg, fg));
119}
120
121/*----------------------------------------------------------------------------
122 * GXSetCursorPosition.
123 *
124 * Description	:This function sets the cursor co -ordinates and enable the
125 *               cursor.
126 *
127 * Parameters:
128 *		pScrn: 	Screeen pointer structure.
129 *    	    x:  Specifies the x-cordinates of the cursor.
130 *    	    y: 	Specifies the y coordinate of the cursor.
131 *
132 * Returns: none.
133 *
134 *----------------------------------------------------------------------------
135 */
136static void
137GXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y)
138{
139    static unsigned long panOffset = 0;
140    GeodeRec *pGeode = GEODEPTR(pScrni);
141    int savex, savey;
142    int newX, newY;
143
144    /* Adjust xf86HWCursor messing about */
145
146    savex = x + pScrni->frameX0;
147    savey = y + pScrni->frameY0;
148
149    switch (pGeode->rotation) {
150    default:
151        ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__,
152               pGeode->rotation);
153    case RR_Rotate_0:
154        newX = savex;
155        newY = savey;
156        break;
157
158    case RR_Rotate_90:
159        newX = savey;
160        newY = pScrni->pScreen->width - savex;
161        break;
162
163    case RR_Rotate_180:
164        newX = pScrni->pScreen->width - savex;
165        newY = pScrni->pScreen->height - savey;
166        break;
167
168    case RR_Rotate_270:
169        newX = pScrni->pScreen->height - savey;
170        newY = savex;
171        break;
172    }
173
174    newX += pScrni->frameX0;
175    newY += pScrni->frameY0;
176
177    //ErrorF("Turned (%d,%d) into (%d,%d)\n", x,y,newX, newY);
178
179    if (newX < -31)
180        newX = -31;
181    if (newY < -31)
182        newY = -31;
183
184    gfx_set_cursor_position(pGeode->CursorStartOffset, newX + 31, newY + 31,
185                            31, 31);
186    gfx_set_cursor_enable(1);
187
188    if ((pGeode->OverlayON) && (pGeode->Panel)) {
189        pGeode->PrevDisplayOffset = gfx_get_display_offset();
190        if (pGeode->PrevDisplayOffset != panOffset) {
191            GXSetVideoPosition(pGeode->video_x, pGeode->video_y,
192                               pGeode->video_w, pGeode->video_h,
193                               pGeode->video_srcw, pGeode->video_srch,
194                               pGeode->video_dstw, pGeode->video_dsth,
195                               pGeode->video_id, pGeode->video_offset,
196                               pGeode->video_scrnptr);
197            panOffset = pGeode->PrevDisplayOffset;
198        }
199    }
200}
201
202/*----------------------------------------------------------------------------
203 * GXLoadCursorImage
204 *
205 * Description:	This function loads the 32x32 cursor pattern.The shape
206 *              and color is set by AND and XOR masking of arrays of 32
207 *              DWORD.
208 * Parameters:
209 *    pScrn: 	Screeen pointer structure.
210 *    src: 		Specifies cursor data.
211 *
212 * Returns: 	none
213 *
214 *----------------------------------------------------------------------------
215 */
216void
217GXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src)
218{
219    int i, n, x, y, newX, newY;
220    unsigned long andMask[32], xorMask[32];
221    GeodeRec *pGeode = GEODEPTR(pScrni);
222    unsigned long mskb, rowb;
223    unsigned char *rowp = &src[0];
224    unsigned char *mskp = &src[128];
225
226    if (src != NULL) {
227        mskb = rowb = 0;
228        for (y = 32; --y >= 0;)
229            andMask[y] = xorMask[y] = 0;
230        for (y = 0; y < 32; ++y) {
231            for (x = 0; x < 32; ++x) {
232                if ((i = x & 7) == 0) {
233                    rowb = (*rowp & *mskp);
234                    mskb = ~(*mskp);
235                    ++rowp;
236                    ++mskp;
237                }
238
239                switch (pGeode->rotation) {
240                default:
241                    ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__,
242                           pGeode->rotation);
243                case RR_Rotate_0:
244                    newX = x;
245                    newY = y;
246                    break;
247                case RR_Rotate_90:
248                    newX = y;
249                    newY = 31 - x;
250                    break;
251                case RR_Rotate_180:
252                    newX = 31 - x;
253                    newY = 31 - y;
254                    break;
255                case RR_Rotate_270:
256                    newX = 31 - y;
257                    newY = x;
258                    break;
259                }
260
261                i = 7 - i;
262                n = 31 - newX;
263                andMask[newY] |= (((mskb >> i) & 1) << n);
264                xorMask[newY] |= (((rowb >> i) & 1) << n);
265            }
266        }
267    }
268    else {
269        for (y = 32; --y >= 0;) {
270            andMask[y] = ~0;
271            xorMask[y] = 0;
272        }
273    }
274
275    gfx_set_cursor_shape32(pGeode->CursorStartOffset, &andMask[0], &xorMask[0]);
276}
277
278/*----------------------------------------------------------------------------
279 * GXHideCursor.
280 *
281 * Description:	This function will disable the cursor.
282 *
283 * Parameters:
284 *    	pScrn: 	Handles to the Screeen pointer structure.
285 *
286 * Returns: 	none.
287 *
288 * Comments:	gfx_set_cursor enable function is hardcoded to disable
289 *				the cursor.
290 *----------------------------------------------------------------------------
291 */
292void
293GXHideCursor(ScrnInfoPtr pScrni)
294{
295    gfx_set_cursor_enable(0);
296}
297
298/*----------------------------------------------------------------------------
299 * GXShowCursor
300 *
301 * Description	:This function will enable  the cursor.
302 *
303 * Parameters:
304 *	pScrn		:Handles to the Screeen pointer structure.
305 *
306 * Returns      :none
307 *
308 * Comments		:gfx_set_cursor enable function is hardcoded to enable the
309 * 				cursor
310 *----------------------------------------------------------------------------
311 */
312void
313GXShowCursor(ScrnInfoPtr pScrni)
314{
315    GFX(set_cursor_enable(1));
316}
317
318/*----------------------------------------------------------------------------
319 * GXUseHwCursor.
320 *
321 * Description	:This function will sets the hardware cursor flag in
322 *              pscreen  structure.
323 *
324 * Parameters.
325 *		pScrn	:Handles to the Screeen pointer structure.
326 *
327 * Returns		:none
328 *
329 * Comments		:none
330 *
331 *----------------------------------------------------------------------------
332 */
333static Bool
334GXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
335{
336    ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn);
337    GeodeRec *pGeode = GEODEPTR(pScrni);
338
339    return pGeode->HWCursor;
340}
341