1 /*
2 * Copyright © 2007 Novell, Inc.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Novell, Inc. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * Novell, Inc. makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
14 *
15 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Author: David Reveman <davidr@novell.com>
24 */
25
26 #include <stdlib.h>
27
28 #include <compiz-core.h>
29
30 static void
setCursorMatrix(CompCursor * c)31 setCursorMatrix (CompCursor *c)
32 {
33 c->matrix = c->image->texture.matrix;
34 c->matrix.x0 -= (c->x * c->matrix.xx);
35 c->matrix.y0 -= (c->y * c->matrix.yy);
36 }
37
38 void
addCursor(CompScreen * s)39 addCursor (CompScreen *s)
40 {
41 CompCursor *c;
42
43 c = malloc (sizeof (CompCursor));
44 if (c)
45 {
46 c->screen = s;
47 c->image = NULL;
48 c->x = 0;
49 c->y = 0;
50
51 c->next = s->cursors;
52 s->cursors = c;
53
54 updateCursor (c, 0, 0, 0);
55
56 /* XFixesHideCursor (s->display->display, s->root); */
57 }
58 }
59
60 Bool
damageCursorRect(CompCursor * c,Bool initial,BoxPtr rect)61 damageCursorRect (CompCursor *c,
62 Bool initial,
63 BoxPtr rect)
64 {
65 return FALSE;
66 }
67
68 void
addCursorDamageRect(CompCursor * c,BoxPtr rect)69 addCursorDamageRect (CompCursor *c,
70 BoxPtr rect)
71 {
72 REGION region;
73
74 if (c->screen->damageMask & COMP_SCREEN_DAMAGE_ALL_MASK)
75 return;
76
77 region.extents = *rect;
78
79 if (!(*c->screen->damageCursorRect) (c, FALSE, ®ion.extents))
80 {
81 region.extents.x1 += c->x;
82 region.extents.y1 += c->y;
83 region.extents.x2 += c->x;
84 region.extents.y2 += c->y;
85
86 region.rects = ®ion.extents;
87 region.numRects = region.size = 1;
88
89 damageScreenRegion (c->screen, ®ion);
90 }
91 }
92
93 void
addCursorDamage(CompCursor * c)94 addCursorDamage (CompCursor *c)
95 {
96 BoxRec box;
97
98 if (c->screen->damageMask & COMP_SCREEN_DAMAGE_ALL_MASK)
99 return;
100
101 box.x1 = 0;
102 box.y1 = 0;
103 box.x2 = c->image->width;
104 box.y2 = c->image->height;
105
106 addCursorDamageRect (c, &box);
107 }
108
109 void
updateCursor(CompCursor * c,int x,int y,unsigned long serial)110 updateCursor (CompCursor *c,
111 int x,
112 int y,
113 unsigned long serial)
114 {
115 /* new current cursor */
116 if (!c->image || c->image->serial != serial)
117 {
118 CompCursorImage *cursorImage;
119
120 cursorImage = findCursorImageAtScreen (c->screen, serial);
121 if (!cursorImage)
122 {
123 Display *dpy = c->screen->display->display;
124 XFixesCursorImage *image;
125
126 image = XFixesGetCursorImage (dpy);
127 if (!image)
128 return;
129
130 cursorImage = malloc (sizeof (CompCursorImage));
131 if (!cursorImage)
132 {
133 XFree (image);
134 return;
135 }
136
137 x = image->x;
138 y = image->y;
139
140 cursorImage->serial = image->cursor_serial;
141 cursorImage->xhot = image->xhot;
142 cursorImage->yhot = image->yhot;
143 cursorImage->width = image->width;
144 cursorImage->height = image->height;
145
146 initTexture (c->screen, &cursorImage->texture);
147
148 if (!imageBufferToTexture (c->screen,
149 &cursorImage->texture,
150 (char *) image->pixels,
151 image->width,
152 image->height))
153 {
154 free (cursorImage);
155 XFree (image);
156 return;
157 }
158
159 XFree (image);
160
161 cursorImage->next = c->screen->cursorImages;
162 c->screen->cursorImages = cursorImage;
163 }
164
165 if (c->image)
166 addCursorDamage (c);
167
168 c->image = cursorImage;
169
170 c->x = x - c->image->xhot;
171 c->y = y - c->image->yhot;
172
173 setCursorMatrix (c);
174
175 addCursorDamage (c);
176 }
177 else
178 {
179 int newX, newY;
180
181 newX = x - c->image->xhot;
182 newY = y - c->image->yhot;
183
184 if (c->x != newX || c->y != newY)
185 {
186 addCursorDamage (c);
187
188 c->x = newX;
189 c->y = newY;
190
191 setCursorMatrix (c);
192
193 addCursorDamage (c);
194 }
195 }
196 }
197