3 static char Copyright[] = "Copyright Martin Ayotte, 1993";
13 #include <X11/cursorfont.h>
22 /* #define DEBUG_CURSOR */
23 /* #define DEBUG_RESOURCE */
27 static int ShowCursCount
= 0;
28 static HCURSOR hActiveCursor
;
29 static HCURSOR hEmptyCursor
= 0;
32 static struct { SEGPTR name
; HCURSOR cursor
; } system_cursor
[] =
47 #define NB_SYS_CURSORS (sizeof(system_cursor)/sizeof(system_cursor[0]))
50 /**********************************************************************
51 * LoadCursor [USER.173]
53 HCURSOR
LoadCursor(HANDLE instance
, SEGPTR cursor_name
)
60 CURSORDESCRIP
*lpcurdesc
;
64 unsigned char *cp1
,*cp2
;
65 dprintf_resource(stddeb
,"LoadCursor: instance = %04x, name = %08lx\n",
66 instance
, cursor_name
);
69 for (i
= 0; i
< NB_SYS_CURSORS
; i
++)
70 if (system_cursor
[i
].name
== cursor_name
)
72 if (system_cursor
[i
].cursor
) return system_cursor
[i
].cursor
;
75 if (i
== NB_SYS_CURSORS
) return 0;
77 hCursor
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(CURSORALLOC
) + 1024L);
78 if (hCursor
== (HCURSOR
)NULL
) return 0;
79 if (!instance
) system_cursor
[i
].cursor
= hCursor
;
81 dprintf_cursor(stddeb
,"LoadCursor Alloc hCursor=%X\n", hCursor
);
82 lpcur
= (CURSORALLOC
*)GlobalLock(hCursor
);
83 memset(lpcur
, 0, sizeof(CURSORALLOC
));
84 if (instance
== (HANDLE
)NULL
) {
85 switch((LONG
)cursor_name
) {
87 lpcur
->xcursor
= XCreateFontCursor(display
, XC_top_left_arrow
);
88 GlobalUnlock(hCursor
);
91 lpcur
->xcursor
= XCreateFontCursor(display
, XC_crosshair
);
92 GlobalUnlock(hCursor
);
95 lpcur
->xcursor
= XCreateFontCursor(display
, XC_xterm
);
96 GlobalUnlock(hCursor
);
99 lpcur
->xcursor
= XCreateFontCursor(display
, XC_watch
);
100 GlobalUnlock(hCursor
);
103 lpcur
->xcursor
= XCreateFontCursor(display
, XC_sb_v_double_arrow
);
104 GlobalUnlock(hCursor
);
107 lpcur
->xcursor
= XCreateFontCursor(display
, XC_sb_h_double_arrow
);
108 GlobalUnlock(hCursor
);
112 lpcur
->xcursor
= XCreateFontCursor(display
, XC_fleur
);
113 GlobalUnlock(hCursor
);
121 /* this code replaces all bitmap cursors with the default cursor */
122 lpcur
->xcursor
= XCreateFontCursor(display
, XC_top_left_arrow
);
123 GlobalUnlock(hCursor
);
127 if (!(hdc
= GetDC(0))) return 0;
128 if (!(hRsrc
= FindResource( instance
, cursor_name
, RT_GROUP_CURSOR
)))
133 rsc_mem
= LoadResource(instance
, hRsrc
);
134 if (rsc_mem
== (HANDLE
)NULL
) {
135 fprintf(stderr
,"LoadCursor / Cursor %08lx not Found !\n", cursor_name
);
139 lp
= (WORD
*)LockResource(rsc_mem
);
141 FreeResource( rsc_mem
);
145 lpcurdesc
= (CURSORDESCRIP
*)(lp
+ 3);
147 dprintf_cursor(stddeb
,"LoadCursor / curReserved=%X\n", *lp
);
148 dprintf_cursor(stddeb
,"LoadCursor / curResourceType=%X\n", *(lp
+ 1));
149 dprintf_cursor(stddeb
,"LoadCursor / curResourceCount=%X\n", *(lp
+ 2));
150 dprintf_cursor(stddeb
,"LoadCursor / cursor Width=%d\n",
151 (int)lpcurdesc
->Width
);
152 dprintf_cursor(stddeb
,"LoadCursor / cursor Height=%d\n",
153 (int)lpcurdesc
->Height
);
154 dprintf_cursor(stddeb
,"LoadCursor / cursor curXHotspot=%d\n",
155 (int)lpcurdesc
->curXHotspot
);
156 dprintf_cursor(stddeb
,"LoadCursor / cursor curYHotspot=%d\n",
157 (int)lpcurdesc
->curYHotspot
);
158 dprintf_cursor(stddeb
,"LoadCursor / cursor curDIBSize=%lX\n",
159 (DWORD
)lpcurdesc
->curDIBSize
);
160 dprintf_cursor(stddeb
,"LoadCursor / cursor curDIBOffset=%lX\n",
161 (DWORD
)lpcurdesc
->curDIBOffset
);
163 lpcur
->descriptor
= *lpcurdesc
;
164 FreeResource( rsc_mem
);
165 if (!(hRsrc
= FindResource( instance
,
166 MAKEINTRESOURCE(lpcurdesc
->curDIBOffset
),
172 rsc_mem
= LoadResource(instance
, hRsrc
);
173 if (rsc_mem
== (HANDLE
)NULL
) {
175 "LoadCursor / Cursor %08lx Bitmap not Found !\n", cursor_name
);
179 lpl
= (LONG
*)LockResource(rsc_mem
);
181 size
= CONV_LONG (*lpl
);
182 if (size
== sizeof(BITMAPCOREHEADER
)){
183 CONV_BITMAPCOREHEADER (lpl
);
184 ((BITMAPINFOHEADER
*)lpl
)->biHeight
/= 2;
185 lpcur
->hBitmap
= ConvertCoreBitmap( hdc
, (BITMAPCOREHEADER
*) lpl
);
186 } else if (size
== sizeof(BITMAPINFOHEADER
)){
187 CONV_BITMAPINFO (lpl
);
188 ((BITMAPINFOHEADER
*)lpl
)->biHeight
/= 2;
189 lpcur
->hBitmap
= ConvertInfoBitmap( hdc
, (BITMAPINFO
*) lpl
);
191 fprintf(stderr
,"No bitmap for cursor?\n");
194 lpl
= (char *)lpl
+ size
+ 8;
195 /* This is rather strange! The data is stored *BACKWARDS* and */
196 /* mirrored! But why?? FIXME: the image must be flipped at the Y */
197 /* axis, either here or in CreateCusor(); */
198 size
= lpcur
->descriptor
.Height
/2 * ((lpcur
->descriptor
.Width
+7)/8);
200 dprintf_cursor(stddeb
,"Before:\n");
201 for(i
=0;i
<2*size
;i
++) {
202 dprintf_cursor(stddeb
,"%02x ",((unsigned char *)lpl
)[i
]);
203 if ((i
& 7) == 7) dprintf_cursor(stddeb
,"\n");
208 for(i
= 0; i
< size
; i
++) {
214 dprintf_cursor(stddeb
,"After:\n");
215 for(i
=0;i
<2*size
;i
++) {
216 dprintf_cursor(stddeb
,"%02x ",((unsigned char *)lpl
)[i
]);
217 if ((i
& 7) == 7) dprintf_cursor(stddeb
,"\n");
220 hCursor
= CreateCursor(instance
, lpcur
->descriptor
.curXHotspot
,
221 lpcur
->descriptor
.curYHotspot
, lpcur
->descriptor
.Width
,
222 lpcur
->descriptor
.Height
/2,
223 (LPSTR
)lpl
, ((LPSTR
)lpl
)+size
);
225 FreeResource( rsc_mem
);
226 GlobalUnlock(hCursor
);
233 /**********************************************************************
234 * CreateCursor [USER.406]
236 HCURSOR
CreateCursor(HANDLE instance
, short nXhotspot
, short nYhotspot
,
237 short nWidth
, short nHeight
, LPSTR lpANDbitPlane
, LPSTR lpXORbitPlane
)
242 int bpllen
= (nWidth
+ 7)/8 * nHeight
;
243 char *tmpbpl
= malloc(bpllen
);
246 XColor bkcolor
,fgcolor
;
247 Colormap cmap
= XDefaultColormap(display
,XDefaultScreen(display
));
249 dprintf_resource(stddeb
,"CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n",
250 instance
, nXhotspot
, nYhotspot
, nWidth
, nHeight
);
251 dprintf_resource(stddeb
,"CreateCursor: inst=%04x lpANDbitPlane=%p lpXORbitPlane=%p\n",
252 instance
, lpANDbitPlane
, lpXORbitPlane
);
254 if (!(hdc
= GetDC(GetDesktopWindow()))) return 0;
255 hCursor
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(CURSORALLOC
) + 1024L);
256 if (hCursor
== (HCURSOR
)NULL
) {
257 ReleaseDC(GetDesktopWindow(), hdc
);
260 dprintf_cursor(stddeb
,"CreateCursor Alloc hCursor=%X\n", hCursor
);
261 lpcur
= (CURSORALLOC
*)GlobalLock(hCursor
);
262 memset(lpcur
, 0, sizeof(CURSORALLOC
));
263 lpcur
->descriptor
.curXHotspot
= nXhotspot
;
264 lpcur
->descriptor
.curYHotspot
= nYhotspot
;
265 for(i
=0; i
<bpllen
; i
++) tmpbpl
[i
] = ~lpANDbitPlane
[i
];
266 lpcur
->pixmask
= XCreatePixmapFromBitmapData(
267 display
, DefaultRootWindow(display
),
268 tmpbpl
, nWidth
, nHeight
, 1, 0, 1);
269 for(i
=0; i
<bpllen
; i
++) tmpbpl
[i
] ^= lpXORbitPlane
[i
];
270 lpcur
->pixshape
= XCreatePixmapFromBitmapData(
271 display
, DefaultRootWindow(display
),
272 tmpbpl
, nWidth
, nHeight
, 1, 0, 1);
273 XParseColor(display
,cmap
,"#000000",&fgcolor
);
274 XParseColor(display
,cmap
,"#ffffff",&bkcolor
);
275 lpcur
->xcursor
= XCreatePixmapCursor(display
,
276 lpcur
->pixshape
, lpcur
->pixmask
,
277 &fgcolor
, &bkcolor
, lpcur
->descriptor
.curXHotspot
,
278 lpcur
->descriptor
.curYHotspot
);
280 XFreePixmap(display
, lpcur
->pixshape
);
281 XFreePixmap(display
, lpcur
->pixmask
);
282 ReleaseDC(GetDesktopWindow(), hdc
);
283 GlobalUnlock(hCursor
);
289 /**********************************************************************
290 * DestroyCursor [USER.458]
292 BOOL
DestroyCursor(HCURSOR hCursor
)
295 if (hCursor
== (HCURSOR
)NULL
) return FALSE
;
296 lpcur
= (CURSORALLOC
*)GlobalLock(hCursor
);
297 if (lpcur
->hBitmap
!= (HBITMAP
)NULL
) DeleteObject(lpcur
->hBitmap
);
298 GlobalUnlock(hCursor
);
304 /**********************************************************************
307 * Internal helper function for SetCursor() and ShowCursor().
309 static void CURSOR_SetCursor( HCURSOR hCursor
)
313 if (!(lpcur
= (CURSORALLOC
*)GlobalLock(hCursor
))) return;
314 if (rootWindow
!= DefaultRootWindow(display
))
316 XDefineCursor( display
, rootWindow
, lpcur
->xcursor
);
320 HWND hwnd
= GetWindow( GetDesktopWindow(), GW_CHILD
);
323 Window win
= WIN_GetXWindow( hwnd
);
324 if (win
) XDefineCursor( display
, win
, lpcur
->xcursor
);
325 hwnd
= GetWindow( hwnd
, GW_HWNDNEXT
);
328 GlobalUnlock( hCursor
);
331 /**********************************************************************
332 * SetCursor [USER.69]
334 HCURSOR
SetCursor(HCURSOR hCursor
)
338 dprintf_cursor(stddeb
,"SetCursor / hCursor=%04X !\n", hCursor
);
339 hOldCursor
= hActiveCursor
;
340 hActiveCursor
= hCursor
;
341 if ((hCursor
!= hOldCursor
) || (ShowCursCount
< 0))
343 CURSOR_SetCursor( hCursor
);
350 /**********************************************************************
351 * GetCursor [USER.247]
353 HCURSOR
GetCursor(void)
355 return hActiveCursor
;
359 /**********************************************************************
360 * SetCursorPos [USER.70]
362 void SetCursorPos(short x
, short y
)
364 dprintf_cursor(stddeb
,"SetCursorPos // x=%d y=%d\n", x
, y
);
365 XWarpPointer( display
, None
, rootWindow
, 0, 0, 0, 0, x
, y
);
369 /**********************************************************************
370 * GetCursorPos [USER.17]
372 void GetCursorPos(LPPOINT lpRetPoint
)
377 unsigned int mousebut
;
379 if (!lpRetPoint
) return;
380 if (!XQueryPointer( display
, rootWindow
, &root
, &child
,
381 &rootX
, &rootY
, &childX
, &childY
, &mousebut
))
382 lpRetPoint
->x
= lpRetPoint
->y
= 0;
385 lpRetPoint
->x
= rootX
+ desktopX
;
386 lpRetPoint
->y
= rootY
+ desktopY
;
388 dprintf_cursor(stddeb
,
389 "GetCursorPos // x=%d y=%d\n", lpRetPoint
->x
, lpRetPoint
->y
);
393 /**********************************************************************
394 * ShowCursor [USER.71]
396 int ShowCursor(BOOL bShow
)
398 dprintf_cursor(stddeb
, "ShowCursor(%d), count=%d\n", bShow
, ShowCursCount
);
402 if (++ShowCursCount
== 0) /* Time to show it */
403 CURSOR_SetCursor( hActiveCursor
);
407 if (--ShowCursCount
== -1) /* Time to hide it */
410 hEmptyCursor
= CreateCursor( 0, 1, 1, 1, 1,
411 "\xFF\xFF", "\xFF\xFF" );
412 CURSOR_SetCursor( hEmptyCursor
);
419 /**********************************************************************
420 * ClipCursor [USER.16]
422 void ClipCursor(LPRECT lpNewClipRect
)
424 if (!lpNewClipRect
) SetRectEmpty( &ClipCursorRect
);
425 else CopyRect( &ClipCursorRect
, lpNewClipRect
);
429 /**********************************************************************
430 * GetClipCursor [USER.309]
432 void GetClipCursor(LPRECT lpRetClipRect
)
434 if (lpRetClipRect
!= NULL
)
435 CopyRect(lpRetClipRect
, &ClipCursorRect
);