gx_cursor.c revision 04007eba
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 "xf86.h"
38#include "xf86_OSproc.h"
39#include "xf86Pci.h"
40#include "xf86PciInfo.h"
41#include "geode.h"
42
43/* Forward declarations of the functions */
44static void GXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg);
45static void GXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y);
46static Bool GXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
47extern void GXSetVideoPosition(int x, int y, int width, int height,
48                               short src_w, short src_h, short drw_w,
49                               short drw_h, int id, int offset,
50                               ScrnInfoPtr pScrn);
51
52/*----------------------------------------------------------------------------
53 * GXHWCursorInit.
54 *
55 * Description	:This function sets the cursor information by probing the
56 * 				hardware.
57 *
58 * Parameters.
59 *     pScrn	:Screeen pointer structure.
60 *
61 * Returns		:TRUE on success and FALSE on Failure
62 *
63 * Comments		:Geode supports the hardware_cursor,no need to enable SW
64 *              cursor.
65 *----------------------------------------------------------------------------
66 */
67Bool
68GXHWCursorInit(ScreenPtr pScrn)
69{
70    ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn);
71    GeodeRec *pGeode = GEODEPTR(pScrni);
72    xf86CursorInfoPtr infoPtr;
73
74    infoPtr = xf86CreateCursorInfoRec();
75    if (!infoPtr)
76        return FALSE;
77    /* the geode structure is intiallized with the cursor infoRec */
78    pGeode->CursorInfo = infoPtr;
79    infoPtr->MaxWidth = 32;
80    infoPtr->MaxHeight = 32;
81    /* seeting up the cursor flags */
82    infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
83        HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
84        HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
85    /* cursor info ptr is intiallized with the values obtained from
86     * * durnago calls
87     */
88    infoPtr->SetCursorColors = GXSetCursorColors;
89    infoPtr->SetCursorPosition = GXSetCursorPosition;
90    infoPtr->LoadCursorImage = GXLoadCursorImage;
91    infoPtr->HideCursor = GXHideCursor;
92    infoPtr->ShowCursor = GXShowCursor;
93    infoPtr->UseHWCursor = GXUseHWCursor;
94    return (xf86InitCursor(pScrn, infoPtr));
95}
96
97/*----------------------------------------------------------------------------
98 * GXSetCursorColors.
99 *
100 * Description	:This function sets the cursor foreground and background
101 *              colors
102 * Parameters:
103 *    pScrn:	Screeen pointer structure.
104 *    bg:		Specifies the color value of cursor background color.
105 *    fg:		Specifies the color value of cursor foreground color.
106 *
107 * Returns:	none.
108 *
109 * Comments:	The integer color value passed by this function is
110 *              converted into  * RGB  value by the gfx_set_color routines.
111 *----------------------------------------------------------------------------
112 */
113static void
114GXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg)
115{
116    GFX(set_cursor_colors(bg, fg));
117}
118
119/*----------------------------------------------------------------------------
120 * GXSetCursorPosition.
121 *
122 * Description	:This function sets the cursor co -ordinates and enable the
123 *               cursor.
124 *
125 * Parameters:
126 *		pScrn: 	Screeen pointer structure.
127 *    	    x:  Specifies the x-cordinates of the cursor.
128 *    	    y: 	Specifies the y co-ordinate of the cursor.
129 *
130 * Returns: none.
131 *
132 *----------------------------------------------------------------------------
133 */
134static void
135GXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y)
136{
137    static unsigned long panOffset = 0;
138    GeodeRec *pGeode = GEODEPTR(pScrni);
139    int savex, savey;
140    int newX, newY;
141
142    /* Adjust xf86HWCursor messing about */
143
144    savex = x + pScrni->frameX0;
145    savey = y + pScrni->frameY0;
146
147    switch (pGeode->rotation) {
148    default:
149        ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__,
150               pGeode->rotation);
151    case RR_Rotate_0:
152        newX = savex;
153        newY = savey;
154        break;
155
156    case RR_Rotate_90:
157        newX = savey;
158        newY = pScrni->pScreen->width - savex;
159        break;
160
161    case RR_Rotate_180:
162        newX = pScrni->pScreen->width - savex;
163        newY = pScrni->pScreen->height - savey;
164        break;
165
166    case RR_Rotate_270:
167        newX = pScrni->pScreen->height - savey;
168        newY = savex;
169        break;
170    }
171
172    newX += pScrni->frameX0;
173    newY += pScrni->frameY0;
174
175    //ErrorF("Turned (%d,%d) into (%d,%d)\n", x,y,newX, newY);
176
177    if (newX < -31)
178        newX = -31;
179    if (newY < -31)
180        newY = -31;
181
182    gfx_set_cursor_position(pGeode->CursorStartOffset, newX + 31, newY + 31,
183                            31, 31);
184    gfx_set_cursor_enable(1);
185
186    if ((pGeode->OverlayON) && (pGeode->Panel)) {
187        pGeode->PrevDisplayOffset = gfx_get_display_offset();
188        if (pGeode->PrevDisplayOffset != panOffset) {
189            GXSetVideoPosition(pGeode->video_x, pGeode->video_y,
190                               pGeode->video_w, pGeode->video_h,
191                               pGeode->video_srcw, pGeode->video_srch,
192                               pGeode->video_dstw, pGeode->video_dsth,
193                               pGeode->video_id, pGeode->video_offset,
194                               pGeode->video_scrnptr);
195            panOffset = pGeode->PrevDisplayOffset;
196        }
197    }
198}
199
200/*----------------------------------------------------------------------------
201 * GXLoadCursorImage
202 *
203 * Description:	This function loads the 32x32 cursor pattern.The shape
204 *              and color is set by AND and XOR masking of arrays of 32
205 *              DWORD.
206 * Parameters:
207 *    pScrn: 	Screeen pointer structure.
208 *    src: 		Specifies cursor data.
209 *
210 * Returns: 	none
211 *
212 *----------------------------------------------------------------------------
213 */
214void
215GXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src)
216{
217    int i, n, x, y, newX, newY;
218    unsigned long andMask[32], xorMask[32];
219    GeodeRec *pGeode = GEODEPTR(pScrni);
220    unsigned long mskb, rowb;
221    unsigned char *rowp = &src[0];
222    unsigned char *mskp = &src[128];
223
224    if (src != NULL) {
225        mskb = rowb = 0;
226        for (y = 32; --y >= 0;)
227            andMask[y] = xorMask[y] = 0;
228        for (y = 0; y < 32; ++y) {
229            for (x = 0; x < 32; ++x) {
230                if ((i = x & 7) == 0) {
231                    rowb = (*rowp & *mskp);
232                    mskb = ~(*mskp);
233                    ++rowp;
234                    ++mskp;
235                }
236
237                switch (pGeode->rotation) {
238                default:
239                    ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__,
240                           pGeode->rotation);
241                case RR_Rotate_0:
242                    newX = x;
243                    newY = y;
244                    break;
245                case RR_Rotate_90:
246                    newX = y;
247                    newY = 31 - x;
248                    break;
249                case RR_Rotate_180:
250                    newX = 31 - x;
251                    newY = 31 - y;
252                    break;
253                case RR_Rotate_270:
254                    newX = 31 - y;
255                    newY = x;
256                    break;
257                }
258
259                i = 7 - i;
260                n = 31 - newX;
261                andMask[newY] |= (((mskb >> i) & 1) << n);
262                xorMask[newY] |= (((rowb >> i) & 1) << n);
263            }
264        }
265    }
266    else {
267        for (y = 32; --y >= 0;) {
268            andMask[y] = ~0;
269            xorMask[y] = 0;
270        }
271    }
272
273    gfx_set_cursor_shape32(pGeode->CursorStartOffset, &andMask[0], &xorMask[0]);
274}
275
276/*----------------------------------------------------------------------------
277 * GXHideCursor.
278 *
279 * Description:	This function will disable the cursor.
280 *
281 * Parameters:
282 *    	pScrn: 	Handles to the Screeen pointer structure.
283 *
284 * Returns: 	none.
285 *
286 * Comments:	gfx_set_cursor enable function is hardcoded to disable
287 *				the cursor.
288 *----------------------------------------------------------------------------
289 */
290void
291GXHideCursor(ScrnInfoPtr pScrni)
292{
293    gfx_set_cursor_enable(0);
294}
295
296/*----------------------------------------------------------------------------
297 * GXShowCursor
298 *
299 * Description	:This function will enable  the cursor.
300 *
301 * Parameters:
302 *	pScrn		:Handles to the Screeen pointer structure.
303 *
304 * Returns      :none
305 *
306 * Comments		:gfx_set_cursor enable function is hardcoded to enable the
307 * 				cursor
308 *----------------------------------------------------------------------------
309 */
310void
311GXShowCursor(ScrnInfoPtr pScrni)
312{
313    GFX(set_cursor_enable(1));
314}
315
316/*----------------------------------------------------------------------------
317 * GXUseHwCursor.
318 *
319 * Description	:This function will sets the hardware cursor flag in
320 *              pscreen  structure.
321 *
322 * Parameters.
323 *		pScrn	:Handles to the Screeen pointer structure.
324 *
325 * Returns		:none
326 *
327 * Comments		:none
328 *
329 *----------------------------------------------------------------------------
330 */
331static Bool
332GXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
333{
334    ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn);
335    GeodeRec *pGeode = GEODEPTR(pScrni);
336
337    return pGeode->HWCursor;
338}
339