~ubuntu-branches/ubuntu/precise/xorg-server/precise

1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
1
/*
2
 * Copyright © 2007 Keith Packard
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
3
 * Copyright © 2010 Aaron Plattner
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
4
 *
5
 * Permission to use, copy, modify, distribute, and sell this software and its
6
 * documentation for any purpose is hereby granted without fee, provided that
7
 * the above copyright notice appear in all copies and that both that copyright
8
 * notice and this permission notice appear in supporting documentation, and
9
 * that the name of the copyright holders not be used in advertising or
10
 * publicity pertaining to distribution of the software without specific,
11
 * written prior permission.  The copyright holders make no representations
12
 * about the suitability of this software for any purpose.  It is provided "as
13
 * is" without express or implied warranty.
14
 *
15
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21
 * OF THIS SOFTWARE.
22
 */
23
24
#ifdef HAVE_XORG_CONFIG_H
25
#include <xorg-config.h>
26
#else
27
#ifdef HAVE_CONFIG_H
28
#include <config.h>
29
#endif
30
#endif
31
32
#include <stddef.h>
33
#include <string.h>
34
#include <stdio.h>
35
36
#include "xf86.h"
37
#include "xf86DDC.h"
38
#include "xf86Crtc.h"
39
#include "xf86Modes.h"
40
#include "xf86RandR12.h"
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
41
#include "xf86CursorPriv.h"
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
42
#include "X11/extensions/render.h"
0.8.1 by Julien Cristau
Import upstream version 1.6.99.903
43
#include "X11/extensions/dpmsconst.h"
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
44
#include "X11/Xatom.h"
45
#include "picturestr.h"
46
#include "cursorstr.h"
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
47
#include "inputstr.h"
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
48
49
/*
50
 * Given a screen coordinate, rotate back to a cursor source coordinate
51
 */
52
static void
53
xf86_crtc_rotate_coord (Rotation    rotation,
54
			int	    width,
55
			int	    height,
56
			int	    x_dst,
57
			int	    y_dst,
58
			int	    *x_src,
59
			int	    *y_src)
60
{
1.1.7 by Timo Aaltonen
Import upstream version 1.4
61
    int t;
62
    
63
    switch (rotation & 0xf) {
64
    case RR_Rotate_0:
65
	break;
66
    case RR_Rotate_90:
67
	t = x_dst;
68
	x_dst = height - y_dst - 1;
69
	y_dst = t;
70
	break;
71
    case RR_Rotate_180:
72
	x_dst = width - x_dst - 1;
73
	y_dst = height - y_dst - 1;
74
	break;
75
    case RR_Rotate_270:
76
	t = x_dst;
77
	x_dst = y_dst;
78
	y_dst = width - t - 1;
79
	break;
80
    }
81
    if (rotation & RR_Reflect_X)
82
	x_dst = width - x_dst - 1;
83
    if (rotation & RR_Reflect_Y)
84
	y_dst = height - y_dst - 1;
85
    *x_src = x_dst;
86
    *y_src = y_dst;
87
}
88
89
/*
90
 * Given a cursor source  coordinate, rotate to a screen coordinate
91
 */
92
static void
93
xf86_crtc_rotate_coord_back (Rotation    rotation,
94
			     int	    width,
95
			     int	    height,
96
			     int	    x_dst,
97
			     int	    y_dst,
98
			     int	    *x_src,
99
			     int	    *y_src)
100
{
101
    int t;
102
    
103
    if (rotation & RR_Reflect_X)
104
	x_dst = width - x_dst - 1;
105
    if (rotation & RR_Reflect_Y)
106
	y_dst = height - y_dst - 1;
107
108
    switch (rotation & 0xf) {
109
    case RR_Rotate_0:
110
	break;
111
    case RR_Rotate_90:
112
	t = x_dst;
113
	x_dst = y_dst;
114
	y_dst = width - t - 1;
115
	break;
116
    case RR_Rotate_180:
117
	x_dst = width - x_dst - 1;
118
	y_dst = height - y_dst - 1;
119
	break;
120
    case RR_Rotate_270:
121
	t = x_dst;
122
	x_dst = height - y_dst - 1;
123
	y_dst = t;
124
	break;
125
    }
126
    *x_src = x_dst;
127
    *y_src = y_dst;
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
128
}
129
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
130
struct cursor_bit {
131
    CARD8 *byte;
132
    char bitpos;
133
};
134
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
135
/*
136
 * Convert an x coordinate to a position within the cursor bitmap
137
 */
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
138
static struct cursor_bit
139
cursor_bitpos (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y,
140
	       Bool mask)
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
141
{
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
142
    const int flags = cursor_info->Flags;
143
    const Bool interleaved =
144
	!!(flags & (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
145
		    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 |
146
		    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 |
147
		    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
148
		    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64));
149
    const int width = cursor_info->MaxWidth;
150
    const int height = cursor_info->MaxHeight;
151
    const int stride = interleaved ? width / 4 : width / 8;
152
153
    struct cursor_bit ret;
154
155
    image += y * stride;
156
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
157
    if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)
158
	mask = !mask;
159
    if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED)
160
	x = (x & ~3) | (3 - (x & 3));
1.1.14 by Timo Aaltonen
Import upstream version 1.4.99.905
161
    if (((flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) == 0) ==
162
	(X_BYTE_ORDER == X_BIG_ENDIAN))
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
163
	x = (x & ~7) | (7 - (x & 7));
164
    if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1)
165
	x = (x << 1) + mask;
166
    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8)
167
	x = ((x & ~7) << 1) | (mask << 3) | (x & 7);
168
    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16)
169
	x = ((x & ~15) << 1) | (mask << 4) | (x & 15);
170
    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32)
171
	x = ((x & ~31) << 1) | (mask << 5) | (x & 31);
172
    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)
173
	x = ((x & ~63) << 1) | (mask << 6) | (x & 63);
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
174
    else if (mask)
175
	image += stride * height;
176
177
    ret.byte = image + (x / 8);
178
    ret.bitpos = x & 7;
179
180
    return ret;
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
181
}
182
183
/*
184
 * Fetch one bit from a cursor bitmap
185
 */
186
static CARD8
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
187
get_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
188
{
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
189
    struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
190
    return (*bit.byte >> bit.bitpos) & 1;
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
191
}
192
193
/*
194
 * Set one bit in a cursor bitmap
195
 */
196
static void
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
197
set_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
198
{
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
199
    struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
200
    *bit.byte |= 1 << bit.bitpos;
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
201
}
202
    
203
/*
204
 * Load a two color cursor into a driver that supports only ARGB cursors
205
 */
206
static void
207
xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
208
{
209
    ScrnInfoPtr		scrn = crtc->scrn;
210
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
211
    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
212
    CARD32		*cursor_image = (CARD32 *) xf86_config->cursor_image;
213
    int			x, y;
214
    int			xin, yin;
215
    int			flags = cursor_info->Flags;
216
    CARD32		bits;
217
218
#ifdef ARGB_CURSOR
219
    crtc->cursor_argb = FALSE;
220
#endif
221
222
    for (y = 0; y < cursor_info->MaxHeight; y++)
223
	for (x = 0; x < cursor_info->MaxWidth; x++) 
224
	{
225
	    xf86_crtc_rotate_coord (crtc->rotation,
226
				    cursor_info->MaxWidth,
227
				    cursor_info->MaxHeight,
228
				    x, y, &xin, &yin);
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
229
	    if (get_bit (src, cursor_info, xin, yin, TRUE) ==
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
230
		((flags & HARDWARE_CURSOR_INVERT_MASK) == 0))
231
	    {
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
232
		if (get_bit (src, cursor_info, xin, yin, FALSE))
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
233
		    bits = xf86_config->cursor_fg;
234
		else
235
		    bits = xf86_config->cursor_bg;
236
	    }
237
	    else
238
		bits = 0;
239
	    cursor_image[y * cursor_info->MaxWidth + x] = bits;
240
	}
241
    crtc->funcs->load_cursor_argb (crtc, cursor_image);
242
}
243
244
/*
245
 * Set the colors for a two-color cursor (ignore for ARGB cursors)
246
 */
247
static void
248
xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
249
{
250
    ScreenPtr		screen = scrn->pScreen;
251
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
252
    CursorPtr		cursor = xf86_config->cursor;
253
    int			c;
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
254
    CARD8		*bits = cursor ?
255
        dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen))
256
      : NULL;
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
257
258
    /* Save ARGB versions of these colors */
259
    xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
260
    xf86_config->cursor_bg = (CARD32) bg | 0xff000000;
261
    
262
    for (c = 0; c < xf86_config->num_crtc; c++)
263
    {
264
	xf86CrtcPtr crtc = xf86_config->crtc[c];
265
266
	if (crtc->enabled && !crtc->cursor_argb)
267
	{
268
	    if (crtc->funcs->load_cursor_image)
269
		crtc->funcs->set_cursor_colors (crtc, bg, fg);
270
	    else if (bits)
271
		xf86_crtc_convert_cursor_to_argb (crtc, bits);
272
	}
273
    }
274
}
275
276
static void
277
xf86_crtc_hide_cursor (xf86CrtcPtr crtc)
278
{
279
    if (crtc->cursor_shown)
280
    {
281
	crtc->funcs->hide_cursor (crtc);
282
	crtc->cursor_shown = FALSE;
283
    }
284
}
285
0.8.1 by Julien Cristau
Import upstream version 1.6.99.903
286
void
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
287
xf86_hide_cursors (ScrnInfoPtr scrn)
288
{
289
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
290
    int			c;
291
292
    xf86_config->cursor_on = FALSE;
293
    for (c = 0; c < xf86_config->num_crtc; c++)
294
    {
295
	xf86CrtcPtr crtc = xf86_config->crtc[c];
296
297
	if (crtc->enabled)
298
	    xf86_crtc_hide_cursor (crtc);
299
    }
300
}
301
    
302
static void
303
xf86_crtc_show_cursor (xf86CrtcPtr crtc)
304
{
305
    if (!crtc->cursor_shown && crtc->cursor_in_range)
306
    {
307
	crtc->funcs->show_cursor (crtc);
308
	crtc->cursor_shown = TRUE;
309
    }
310
}
311
0.8.1 by Julien Cristau
Import upstream version 1.6.99.903
312
void
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
313
xf86_show_cursors (ScrnInfoPtr scrn)
314
{
315
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
316
    int			c;
317
318
    xf86_config->cursor_on = TRUE;
319
    for (c = 0; c < xf86_config->num_crtc; c++)
320
    {
321
	xf86CrtcPtr crtc = xf86_config->crtc[c];
322
323
	if (crtc->enabled)
324
	    xf86_crtc_show_cursor (crtc);
325
    }
326
}
327
    
328
static void
329
xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
330
{
331
    ScrnInfoPtr		scrn = crtc->scrn;
332
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
333
    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
334
    DisplayModePtr	mode = &crtc->mode;
335
    Bool		in_range;
1.1.7 by Timo Aaltonen
Import upstream version 1.4
336
    int			dx, dy;
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
337
1.1.7 by Timo Aaltonen
Import upstream version 1.4
338
    /*
339
     * Transform position of cursor on screen
340
     */
1.1.38 by Christopher James Halse Rogers
Import upstream version 1.9.99.901+git20110131.be3be758
341
    if (crtc->sprite_transform_in_use)
1.1.7 by Timo Aaltonen
Import upstream version 1.4
342
    {
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
343
	ScreenPtr	screen = scrn->pScreen;
344
	xf86CursorScreenPtr ScreenPriv =
345
	    (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
346
						  xf86CursorScreenKey);
347
	struct pict_f_vector   v;
348
0.9.5 by Julien Cristau
Import upstream version 1.8.99.904
349
	v.v[0] = (x + ScreenPriv->HotX) + 0.5;
350
	v.v[1] = (y + ScreenPriv->HotY) + 0.5;
351
	v.v[2] = 1;
1.1.38 by Christopher James Halse Rogers
Import upstream version 1.9.99.901+git20110131.be3be758
352
	pixman_f_transform_point (&crtc->f_screen_to_crtc, &v);
0.9.5 by Julien Cristau
Import upstream version 1.8.99.904
353
	/* cursor will have 0.5 added to it already so floor is sufficent */
354
	x = floor (v.v[0]);
355
	y = floor (v.v[1]);
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
356
	/*
357
	 * Transform position of cursor upper left corner
358
	 */
359
	xf86_crtc_rotate_coord_back (crtc->rotation,
360
				     cursor_info->MaxWidth,
361
				     cursor_info->MaxHeight,
362
				     ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy);
363
	x -= dx;
364
	y -= dy;
365
   }
1.1.7 by Timo Aaltonen
Import upstream version 1.4
366
    else
367
    {
368
	x -= crtc->x;
369
	y -= crtc->y;
370
    }
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
371
372
    /*
373
     * Disable the cursor when it is outside the viewport
374
     */
375
    in_range = TRUE;
376
    if (x >= mode->HDisplay || y >= mode->VDisplay ||
377
	x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight) 
378
    {
379
	in_range = FALSE;
380
	x = 0;
381
	y = 0;
382
    }
383
384
    crtc->cursor_in_range = in_range;
385
    
386
    if (in_range)
387
    {
388
	crtc->funcs->set_cursor_position (crtc, x, y);
389
	xf86_crtc_show_cursor (crtc);
390
    }
391
    else
392
	xf86_crtc_hide_cursor (crtc);
393
}
394
395
static void
396
xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y)
397
{
398
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
399
    int			c;
400
401
    /* undo what xf86HWCurs did to the coordinates */
402
    x += scrn->frameX0;
403
    y += scrn->frameY0;
404
    for (c = 0; c < xf86_config->num_crtc; c++)
405
    {
406
	xf86CrtcPtr crtc = xf86_config->crtc[c];
407
408
	if (crtc->enabled)
409
	    xf86_crtc_set_cursor_position (crtc, x, y);
410
    }
411
}
412
    
413
/*
414
 * Load a two-color cursor into a crtc, performing rotation as needed
415
 */
416
static void
417
xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
418
{
419
    ScrnInfoPtr		scrn = crtc->scrn;
420
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
421
    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
422
    CARD8		*cursor_image;
423
424
#ifdef ARGB_CURSOR
425
    crtc->cursor_argb = FALSE;
426
#endif
427
428
    if (crtc->rotation == RR_Rotate_0)
429
	cursor_image = src;
430
    else
431
    {
432
        int x, y;
433
    	int xin, yin;
434
	int stride = cursor_info->MaxWidth >> 2;
435
	
436
	cursor_image = xf86_config->cursor_image;
1.1.14 by Timo Aaltonen
Import upstream version 1.4.99.905
437
	memset(cursor_image, 0, cursor_info->MaxHeight * stride);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
438
	
439
        for (y = 0; y < cursor_info->MaxHeight; y++)
440
	    for (x = 0; x < cursor_info->MaxWidth; x++) 
441
	    {
442
		xf86_crtc_rotate_coord (crtc->rotation,
443
					cursor_info->MaxWidth,
444
					cursor_info->MaxHeight,
445
					x, y, &xin, &yin);
0.9.10 by Cyril Brulebois
Import upstream version 1.9.2.902
446
		if (get_bit(src, cursor_info, xin, yin, FALSE))
447
		    set_bit(cursor_image, cursor_info, x, y, FALSE);
448
		if (get_bit(src, cursor_info, xin, yin, TRUE))
449
		    set_bit(cursor_image, cursor_info, x, y, TRUE);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
450
	    }
451
    }
452
    crtc->funcs->load_cursor_image (crtc, cursor_image);
453
}
454
    
455
/*
456
 * Load a cursor image into all active CRTCs
457
 */
458
static void
459
xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src)
460
{
461
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
462
    int			c;
463
464
    for (c = 0; c < xf86_config->num_crtc; c++)
465
    {
466
	xf86CrtcPtr crtc = xf86_config->crtc[c];
467
468
	if (crtc->enabled)
469
	{
470
	    if (crtc->funcs->load_cursor_image)
471
		xf86_crtc_load_cursor_image (crtc, src);
472
	    else if (crtc->funcs->load_cursor_argb)
473
		xf86_crtc_convert_cursor_to_argb (crtc, src);
474
	}
475
    }
476
}
477
478
static Bool
479
xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor)
480
{
481
    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
482
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
483
    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
484
0.9.3 by Julien Cristau
Import upstream version 1.8.1
485
    ++cursor->refcnt;
1.1.7 by Timo Aaltonen
Import upstream version 1.4
486
    if (xf86_config->cursor)
487
	FreeCursor (xf86_config->cursor, None);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
488
    xf86_config->cursor = cursor;
0.9.3 by Julien Cristau
Import upstream version 1.8.1
489
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
490
    if (cursor->bits->width > cursor_info->MaxWidth ||
491
	cursor->bits->height> cursor_info->MaxHeight)
492
	return FALSE;
493
494
    return TRUE;
495
}
496
497
static Bool
498
xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor)
499
{
500
    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
501
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
502
    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
503
    
0.8.1 by Julien Cristau
Import upstream version 1.6.99.903
504
    ++cursor->refcnt;
1.1.7 by Timo Aaltonen
Import upstream version 1.4
505
    if (xf86_config->cursor)
506
	FreeCursor (xf86_config->cursor, None);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
507
    xf86_config->cursor = cursor;
508
    
509
    /* Make sure ARGB support is available */
510
    if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
511
	return FALSE;
512
    
513
    if (cursor->bits->width > cursor_info->MaxWidth ||
514
	cursor->bits->height> cursor_info->MaxHeight)
515
	return FALSE;
516
517
    return TRUE;
518
}
519
520
static void
521
xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
522
{
523
    ScrnInfoPtr		scrn = crtc->scrn;
524
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
525
    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
526
    CARD32		*cursor_image = (CARD32 *) xf86_config->cursor_image;
527
    CARD32		*cursor_source = (CARD32 *) cursor->bits->argb;
528
    int			x, y;
529
    int			xin, yin;
530
    CARD32		bits;
531
    int			source_width = cursor->bits->width;
532
    int			source_height = cursor->bits->height;
533
    int			image_width = cursor_info->MaxWidth;
534
    int			image_height = cursor_info->MaxHeight;
535
    
536
    for (y = 0; y < image_height; y++)
537
	for (x = 0; x < image_width; x++)
538
	{
539
	    xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
540
				    x, y, &xin, &yin);
541
	    if (xin < source_width && yin < source_height)
542
		bits = cursor_source[yin * source_width + xin];
543
	    else
544
		bits = 0;
545
	    cursor_image[y * image_width + x] = bits;
546
	}
547
    
548
    crtc->funcs->load_cursor_argb (crtc, cursor_image);
549
}
550
551
static void
552
xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor)
553
{
554
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
555
    int			c;
556
557
    for (c = 0; c < xf86_config->num_crtc; c++)
558
    {
559
	xf86CrtcPtr crtc = xf86_config->crtc[c];
560
561
	if (crtc->enabled)
562
	    xf86_crtc_load_cursor_argb (crtc, cursor);
563
    }
564
}
565
0.8.1 by Julien Cristau
Import upstream version 1.6.99.903
566
Bool
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
567
xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
568
{
569
    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
570
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
571
    xf86CursorInfoPtr	cursor_info;
572
573
    cursor_info = xf86CreateCursorInfoRec();
574
    if (!cursor_info)
575
	return FALSE;
576
0.9.5 by Julien Cristau
Import upstream version 1.8.99.904
577
    xf86_config->cursor_image = malloc(max_width * max_height * 4);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
578
579
    if (!xf86_config->cursor_image)
580
    {
581
	xf86DestroyCursorInfoRec (cursor_info);
582
	return FALSE;
583
    }
584
	
585
    xf86_config->cursor_info = cursor_info;
586
587
    cursor_info->MaxWidth = max_width;
588
    cursor_info->MaxHeight = max_height;
589
    cursor_info->Flags = flags;
590
591
    cursor_info->SetCursorColors = xf86_set_cursor_colors;
592
    cursor_info->SetCursorPosition = xf86_set_cursor_position;
593
    cursor_info->LoadCursorImage = xf86_load_cursor_image;
594
    cursor_info->HideCursor = xf86_hide_cursors;
595
    cursor_info->ShowCursor = xf86_show_cursors;
596
    cursor_info->UseHWCursor = xf86_use_hw_cursor;
597
#ifdef ARGB_CURSOR
598
    if (flags & HARDWARE_CURSOR_ARGB)
599
    {
600
	cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
601
	cursor_info->LoadCursorARGB = xf86_load_cursor_argb;
602
    }
603
#endif
604
    
605
    xf86_config->cursor = NULL;
606
    xf86_hide_cursors (scrn);
607
    
608
    return xf86InitCursor (screen, cursor_info);
609
}
610
611
/**
612
 * Called when anything on the screen is reconfigured.
613
 *
614
 * Reloads cursor images as needed, then adjusts cursor positions
615
 */
616
0.8.1 by Julien Cristau
Import upstream version 1.6.99.903
617
void
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
618
xf86_reload_cursors (ScreenPtr screen)
619
{
620
    ScrnInfoPtr		scrn;
621
    xf86CrtcConfigPtr   xf86_config;
622
    xf86CursorInfoPtr   cursor_info;
623
    CursorPtr		cursor;
624
    int			x, y;
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
625
    xf86CursorScreenPtr cursor_screen_priv;
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
626
    
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
627
    /* initial mode setting will not have set a screen yet.
628
       May be called before the devices are initialised.
629
     */
630
    if (!screen || !inputInfo.pointer)
631
	return;
632
    cursor_screen_priv = dixLookupPrivate(&screen->devPrivates,
633
					  xf86CursorScreenKey);
634
    /* return if HW cursor is inactive, to avoid displaying two cursors */
0.9.4 by Julien Cristau
Import upstream version 1.8.1.901
635
    if (!cursor_screen_priv || !cursor_screen_priv->isUp)
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
636
	return;
637
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
638
    scrn = xf86Screens[screen->myNum];
639
    xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
640
641
    /* make sure the cursor code has been initialized */
642
    cursor_info = xf86_config->cursor_info;
643
    if (!cursor_info)
644
	return;
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
645
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
646
    cursor = xf86_config->cursor;
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
647
    GetSpritePosition (inputInfo.pointer, &x, &y);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
648
    if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
649
	(*cursor_info->HideCursor)(scrn);
650
651
    if (cursor)
652
    {
1.1.20 by Timo Aaltonen
Import upstream version 1.5.99.3
653
	void *src = dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen));
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
654
#ifdef ARGB_CURSOR
655
	if (cursor->bits->argb && cursor_info->LoadCursorARGB)
656
	    (*cursor_info->LoadCursorARGB) (scrn, cursor);
1.1.15 by Timo Aaltonen
Import upstream version 1.4.99.906
657
	else if (src)
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
658
#endif
0.5.2 by Julien Cristau
Import upstream version 1.6.3.901
659
	    (*cursor_info->LoadCursorImage)(scrn, src);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
660
0.5.2 by Julien Cristau
Import upstream version 1.6.3.901
661
	x += scrn->frameX0 + cursor_screen_priv->HotX;
662
	y += scrn->frameY0 + cursor_screen_priv->HotY;
663
	(*cursor_info->SetCursorPosition)(scrn, x, y);
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
664
    }
665
}
666
667
/**
668
 * Clean up CRTC-based cursor code
669
 */
0.8.1 by Julien Cristau
Import upstream version 1.6.99.903
670
void
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
671
xf86_cursors_fini (ScreenPtr screen)
672
{
673
    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
674
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
675
    
676
    if (xf86_config->cursor_info)
677
    {
678
	xf86DestroyCursorInfoRec (xf86_config->cursor_info);
679
	xf86_config->cursor_info = NULL;
680
    }
0.9.5 by Julien Cristau
Import upstream version 1.8.99.904
681
    free(xf86_config->cursor_image);
682
    xf86_config->cursor_image = NULL;
1.1.7 by Timo Aaltonen
Import upstream version 1.4
683
    if (xf86_config->cursor)
684
    {
685
	FreeCursor (xf86_config->cursor, None);
686
	xf86_config->cursor = NULL;
687
    }
1.1.6 by Bryce Harrington
Import upstream version 1.3.0.0.dfsg
688
}