1 /***********************************************************
3 Copyright 1987, 1998 The Open Group
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
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
26 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
30 Permission to use, copy, modify, and distribute this software and its
31 documentation for any purpose and without fee is hereby granted,
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46 ******************************************************************/
50 #ifdef HAVE_DIX_CONFIG_H
51 #include <dix-config.h>
57 #include "scrnintstr.h"
58 #include "dixstruct.h"
59 #include "cursorstr.h"
60 #include "dixfontstr.h"
63 typedef struct _GlyphShare
{
65 unsigned short sourceChar
;
66 unsigned short maskChar
;
68 struct _GlyphShare
*next
;
69 } GlyphShare
, *GlyphSharePtr
;
71 static GlyphSharePtr sharedGlyphs
= (GlyphSharePtr
)NULL
;
74 static CARD32 cursorSerial
;
78 FreeCursorBits(CursorBitsPtr bits
)
80 if (--bits
->refcnt
> 0)
87 if (bits
->refcnt
== 0)
89 GlyphSharePtr
*prev
, this;
91 for (prev
= &sharedGlyphs
;
92 (this = *prev
) && (this->bits
!= bits
);
98 CloseFont(this->font
, (Font
)0);
106 * To be called indirectly by DeleteResource; must use exactly two args.
108 * \param value must conform to DeleteType
111 FreeCursor(pointer value
, XID cid
)
114 CursorPtr pCurs
= (CursorPtr
)value
;
118 if ( --pCurs
->refcnt
> 0)
121 for (nscr
= 0; nscr
< screenInfo
.numScreens
; nscr
++)
123 pscr
= screenInfo
.screens
[nscr
];
124 (void)( *pscr
->UnrealizeCursor
)( pscr
, pCurs
);
126 FreeCursorBits(pCurs
->bits
);
133 * We check for empty cursors so that we won't have to display them
136 CheckForEmptyMask(CursorBitsPtr bits
)
138 unsigned char *msk
= bits
->mask
;
139 int n
= BitmapBytePad(bits
->width
) * bits
->height
;
141 bits
->emptyMask
= FALSE
;
143 if(*(msk
++) != 0) return;
147 CARD32
*argb
= bits
->argb
;
148 int n
= bits
->width
* bits
->height
;
150 if (*argb
++ & 0xff000000) return;
153 bits
->emptyMask
= TRUE
;
157 * does nothing about the resource table, just creates the data structure.
158 * does not copy the src and mask bits
160 * \param psrcbits server-defined padding
161 * \param pmaskbits server-defined padding
162 * \param argb no padding
165 AllocCursorARGB(unsigned char *psrcbits
, unsigned char *pmaskbits
, CARD32
*argb
,
167 unsigned foreRed
, unsigned foreGreen
, unsigned foreBlue
,
168 unsigned backRed
, unsigned backGreen
, unsigned backBlue
)
175 pCurs
= (CursorPtr
)xalloc(sizeof(CursorRec
) + sizeof(CursorBits
));
180 return (CursorPtr
)NULL
;
182 bits
= (CursorBitsPtr
)((char *)pCurs
+ sizeof(CursorRec
));
183 bits
->source
= psrcbits
;
184 bits
->mask
= pmaskbits
;
188 bits
->width
= cm
->width
;
189 bits
->height
= cm
->height
;
190 bits
->xhot
= cm
->xhot
;
191 bits
->yhot
= cm
->yhot
;
193 CheckForEmptyMask(bits
);
198 pCurs
->serialNumber
= ++cursorSerial
;
202 pCurs
->foreRed
= foreRed
;
203 pCurs
->foreGreen
= foreGreen
;
204 pCurs
->foreBlue
= foreBlue
;
206 pCurs
->backRed
= backRed
;
207 pCurs
->backGreen
= backGreen
;
208 pCurs
->backBlue
= backBlue
;
211 * realize the cursor for every screen
213 for (nscr
= 0; nscr
< screenInfo
.numScreens
; nscr
++)
215 pscr
= screenInfo
.screens
[nscr
];
216 if (!( *pscr
->RealizeCursor
)( pscr
, pCurs
))
220 pscr
= screenInfo
.screens
[nscr
];
221 ( *pscr
->UnrealizeCursor
)( pscr
, pCurs
);
223 FreeCursorBits(bits
);
225 return (CursorPtr
)NULL
;
233 * \param psrcbits server-defined padding
234 * \param pmaskbits server-defined padding
237 AllocCursor(unsigned char *psrcbits
, unsigned char *pmaskbits
,
239 unsigned foreRed
, unsigned foreGreen
, unsigned foreBlue
,
240 unsigned backRed
, unsigned backGreen
, unsigned backBlue
)
242 return AllocCursorARGB (psrcbits
, pmaskbits
, (CARD32
*) 0, cm
,
243 foreRed
, foreGreen
, foreBlue
,
244 backRed
, backGreen
, backBlue
);
248 AllocGlyphCursor(Font source
, unsigned sourceChar
, Font mask
, unsigned maskChar
,
249 unsigned foreRed
, unsigned foreGreen
, unsigned foreBlue
,
250 unsigned backRed
, unsigned backGreen
, unsigned backBlue
,
251 CursorPtr
*ppCurs
, ClientPtr client
)
253 FontPtr sourcefont
, maskfont
;
254 unsigned char *srcbits
;
255 unsigned char *mskbits
;
262 GlyphSharePtr pShare
;
264 sourcefont
= (FontPtr
) SecurityLookupIDByType(client
, source
, RT_FONT
,
266 maskfont
= (FontPtr
) SecurityLookupIDByType(client
, mask
, RT_FONT
,
271 client
->errorValue
= source
;
274 if (!maskfont
&& (mask
!= None
))
276 client
->errorValue
= mask
;
279 if (sourcefont
!= maskfont
)
280 pShare
= (GlyphSharePtr
)NULL
;
283 for (pShare
= sharedGlyphs
;
285 ((pShare
->font
!= sourcefont
) ||
286 (pShare
->sourceChar
!= sourceChar
) ||
287 (pShare
->maskChar
!= maskChar
));
288 pShare
= pShare
->next
)
293 pCurs
= (CursorPtr
)xalloc(sizeof(CursorRec
));
301 if (!CursorMetricsFromGlyph(sourcefont
, sourceChar
, &cm
))
303 client
->errorValue
= sourceChar
;
309 unsigned char *mskptr
;
311 n
= BitmapBytePad(cm
.width
)*(long)cm
.height
;
312 mskptr
= mskbits
= (unsigned char *)xalloc(n
);
320 if (!CursorMetricsFromGlyph(maskfont
, maskChar
, &cm
))
322 client
->errorValue
= maskChar
;
325 if ((res
= ServerBitsFromGlyph(maskfont
, maskChar
, &cm
, &mskbits
)) != 0)
328 if ((res
= ServerBitsFromGlyph(sourcefont
, sourceChar
, &cm
, &srcbits
)) != 0)
333 if (sourcefont
!= maskfont
)
335 pCurs
= (CursorPtr
)xalloc(sizeof(CursorRec
) + sizeof(CursorBits
));
337 bits
= (CursorBitsPtr
)((char *)pCurs
+ sizeof(CursorRec
));
339 bits
= (CursorBitsPtr
)NULL
;
343 pCurs
= (CursorPtr
)xalloc(sizeof(CursorRec
));
345 bits
= (CursorBitsPtr
)xalloc(sizeof(CursorBits
));
347 bits
= (CursorBitsPtr
)NULL
;
356 bits
->source
= srcbits
;
357 bits
->mask
= mskbits
;
361 bits
->width
= cm
.width
;
362 bits
->height
= cm
.height
;
363 bits
->xhot
= cm
.xhot
;
364 bits
->yhot
= cm
.yhot
;
365 if (sourcefont
!= maskfont
)
370 pShare
= (GlyphSharePtr
)xalloc(sizeof(GlyphShare
));
373 FreeCursorBits(bits
);
376 pShare
->font
= sourcefont
;
377 sourcefont
->refcnt
++;
378 pShare
->sourceChar
= sourceChar
;
379 pShare
->maskChar
= maskChar
;
381 pShare
->next
= sharedGlyphs
;
382 sharedGlyphs
= pShare
;
385 CheckForEmptyMask(bits
);
389 pCurs
->serialNumber
= ++cursorSerial
;
393 pCurs
->foreRed
= foreRed
;
394 pCurs
->foreGreen
= foreGreen
;
395 pCurs
->foreBlue
= foreBlue
;
397 pCurs
->backRed
= backRed
;
398 pCurs
->backGreen
= backGreen
;
399 pCurs
->backBlue
= backBlue
;
402 * realize the cursor for every screen
404 for (nscr
= 0; nscr
< screenInfo
.numScreens
; nscr
++)
406 pscr
= screenInfo
.screens
[nscr
];
407 if (!( *pscr
->RealizeCursor
)( pscr
, pCurs
))
411 pscr
= screenInfo
.screens
[nscr
];
412 ( *pscr
->UnrealizeCursor
)( pscr
, pCurs
);
414 FreeCursorBits(pCurs
->bits
);
425 * look up the name of a font
427 * add the font to the resource table
428 * make a cursor from the glyphs
429 * add the cursor to the resource table
430 *************************************************************/
433 CreateRootCursor(char *unused1
, unsigned int unused2
)
436 #ifdef NULL_ROOT_CURSOR
444 #ifdef NULL_ROOT_CURSOR
450 curs
= AllocCursor(NULL
, NULL
, &cm
, 0, 0, 0, 0, 0, 0);
452 if (curs
== NullCursor
)
455 fontID
= FakeClientID(0);
456 err
= OpenFont(serverClient
, fontID
, FontLoadAll
| FontOpenSync
,
457 (unsigned)strlen(defaultCursorFont
), defaultCursorFont
);
461 cursorfont
= (FontPtr
)LookupIDByType(fontID
, RT_FONT
);
464 if (AllocGlyphCursor(fontID
, 0, fontID
, 1,
465 0, 0, 0, ~0, ~0, ~0, &curs
, serverClient
) != Success
)
469 if (!AddResource(FakeClientID(0), RT_CURSOR
, (pointer
)curs
))