3 static char Copyright[] = "Copyright Martin Ayotte, 1993";
13 #include <X11/cursorfont.h>
26 static int ShowCursCount = 0;
27 static HCURSOR hActiveCursor;
28 static HCURSOR hEmptyCursor = 0;
31 static struct { SEGPTR name; HCURSOR cursor; } system_cursor[] =
46 #define NB_SYS_CURSORS (sizeof(system_cursor)/sizeof(system_cursor[0]))
49 /**********************************************************************
50 * LoadCursor [USER.173]
52 HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name)
59 CURSORDESCRIP *lpcurdesc;
63 unsigned char *cp1,*cp2;
64 dprintf_resource(stddeb,"LoadCursor: instance = %04x, name = %08lx\n",
65 instance, cursor_name);
68 for (i = 0; i < NB_SYS_CURSORS; i++)
69 if (system_cursor[i].name == cursor_name)
71 if (system_cursor[i].cursor) return system_cursor[i].cursor;
74 if (i == NB_SYS_CURSORS) return 0;
76 hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L);
77 if (hCursor == (HCURSOR)NULL) return 0;
78 if (!instance) system_cursor[i].cursor = hCursor;
80 dprintf_cursor(stddeb,"LoadCursor Alloc hCursor=%X\n", hCursor);
81 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
82 memset(lpcur, 0, sizeof(CURSORALLOC));
83 if (instance == (HANDLE)NULL) {
84 switch((LONG)cursor_name) {
86 lpcur->xcursor = XCreateFontCursor(display, XC_top_left_arrow);
87 GlobalUnlock(hCursor);
90 lpcur->xcursor = XCreateFontCursor(display, XC_crosshair);
91 GlobalUnlock(hCursor);
94 lpcur->xcursor = XCreateFontCursor(display, XC_xterm);
95 GlobalUnlock(hCursor);
98 lpcur->xcursor = XCreateFontCursor(display, XC_watch);
99 GlobalUnlock(hCursor);
102 lpcur->xcursor = XCreateFontCursor(display, XC_sb_v_double_arrow);
103 GlobalUnlock(hCursor);
106 lpcur->xcursor = XCreateFontCursor(display, XC_sb_h_double_arrow);
107 GlobalUnlock(hCursor);
111 lpcur->xcursor = XCreateFontCursor(display, XC_fleur);
112 GlobalUnlock(hCursor);
120 /* this code replaces all bitmap cursors with the default cursor */
121 lpcur->xcursor = XCreateFontCursor(display, XC_top_left_arrow);
122 GlobalUnlock(hCursor);
126 if (!(hdc = GetDC(0))) return 0;
127 if (!(hRsrc = FindResource( instance, cursor_name, RT_GROUP_CURSOR )))
132 rsc_mem = LoadResource(instance, hRsrc );
133 if (rsc_mem == (HANDLE)NULL) {
134 fprintf(stderr,"LoadCursor / Cursor %08lx not Found !\n", cursor_name);
138 lp = (WORD *)LockResource(rsc_mem);
140 FreeResource( rsc_mem );
144 lpcurdesc = (CURSORDESCRIP *)(lp + 3);
146 dprintf_cursor(stddeb,"LoadCursor / curReserved=%X\n", *lp);
147 dprintf_cursor(stddeb,"LoadCursor / curResourceType=%X\n", *(lp + 1));
148 dprintf_cursor(stddeb,"LoadCursor / curResourceCount=%X\n", *(lp + 2));
149 dprintf_cursor(stddeb,"LoadCursor / cursor Width=%d\n",
150 (int)lpcurdesc->Width);
151 dprintf_cursor(stddeb,"LoadCursor / cursor Height=%d\n",
152 (int)lpcurdesc->Height);
153 dprintf_cursor(stddeb,"LoadCursor / cursor curXHotspot=%d\n",
154 (int)lpcurdesc->curXHotspot);
155 dprintf_cursor(stddeb,"LoadCursor / cursor curYHotspot=%d\n",
156 (int)lpcurdesc->curYHotspot);
157 dprintf_cursor(stddeb,"LoadCursor / cursor curDIBSize=%lX\n",
158 (DWORD)lpcurdesc->curDIBSize);
159 dprintf_cursor(stddeb,"LoadCursor / cursor curDIBOffset=%lX\n",
160 (DWORD)lpcurdesc->curDIBOffset);
162 lpcur->descriptor = *lpcurdesc;
163 FreeResource( rsc_mem );
164 if (!(hRsrc = FindResource( instance,
165 MAKEINTRESOURCE(lpcurdesc->curDIBOffset),
171 rsc_mem = LoadResource(instance, hRsrc );
172 if (rsc_mem == (HANDLE)NULL) {
174 "LoadCursor / Cursor %08lx Bitmap not Found !\n", cursor_name);
178 lpl = (LONG *)LockResource(rsc_mem);
180 size = CONV_LONG (*lpl);
181 if (size == sizeof(BITMAPCOREHEADER)){
182 CONV_BITMAPCOREHEADER (lpl);
183 ((BITMAPINFOHEADER *)lpl)->biHeight /= 2;
184 lpcur->hBitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lpl );
185 } else if (size == sizeof(BITMAPINFOHEADER)){
186 CONV_BITMAPINFO (lpl);
187 ((BITMAPINFOHEADER *)lpl)->biHeight /= 2;
188 lpcur->hBitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lpl );
190 fprintf(stderr,"No bitmap for cursor?\n");
193 lpl = (LONG *)((char *)lpl + size + 8);
194 /* This is rather strange! The data is stored *BACKWARDS* and */
195 /* mirrored! But why?? FIXME: the image must be flipped at the Y */
196 /* axis, either here or in CreateCusor(); */
197 size = lpcur->descriptor.Height/2 * ((lpcur->descriptor.Width+7)/8);
199 dprintf_cursor(stddeb,"Before:\n");
200 for(i=0;i<2*size;i++) {
201 dprintf_cursor(stddeb,"%02x ",((unsigned char *)lpl)[i]);
202 if ((i & 7) == 7) dprintf_cursor(stddeb,"\n");
207 for(i = 0; i < size; i++) {
213 dprintf_cursor(stddeb,"After:\n");
214 for(i=0;i<2*size;i++) {
215 dprintf_cursor(stddeb,"%02x ",((unsigned char *)lpl)[i]);
216 if ((i & 7) == 7) dprintf_cursor(stddeb,"\n");
219 hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot,
220 lpcur->descriptor.curYHotspot, lpcur->descriptor.Width,
221 lpcur->descriptor.Height/2,
222 (LPSTR)lpl, ((LPSTR)lpl)+size);
224 FreeResource( rsc_mem );
225 GlobalUnlock(hCursor);
232 /***********************************************************************
233 * CreateCursorIconIndirect (USER.408)
235 * Returns handle to either an icon or a cursor. Used by CreateCursor
236 * and CreateIcon in Windoze, but will use same in this version.
238 HANDLE CreateCursorIconIndirect(HANDLE hInstance, LPCURSORICONINFO lpInfo,
239 LPSTR lpANDBits, /* bitmap data */
240 LPSTR lpXORBits /* masking data */)
242 return CreateIcon(hInstance,
243 lpInfo->nWidth, lpInfo->nHeight,
244 lpInfo->byPlanes, lpInfo->byBitsPix,
245 lpANDBits, lpXORBits);
249 /**********************************************************************
250 * CreateCursor [USER.406]
252 HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot,
253 short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane)
258 int bpllen = (nWidth + 7)/8 * nHeight;
259 char *tmpbpl = malloc(bpllen);
262 XColor bkcolor,fgcolor;
263 Colormap cmap = XDefaultColormap(display,XDefaultScreen(display));
265 dprintf_resource(stddeb,"CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n",
266 instance, nXhotspot, nYhotspot, nWidth, nHeight);
267 dprintf_resource(stddeb,"CreateCursor: inst=%04x lpANDbitPlane=%p lpXORbitPlane=%p\n",
268 instance, lpANDbitPlane, lpXORbitPlane);
270 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
271 hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L);
272 if (hCursor == (HCURSOR)NULL) {
273 ReleaseDC(GetDesktopWindow(), hdc);
276 dprintf_cursor(stddeb,"CreateCursor Alloc hCursor=%X\n", hCursor);
277 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
278 memset(lpcur, 0, sizeof(CURSORALLOC));
279 lpcur->descriptor.curXHotspot = nXhotspot;
280 lpcur->descriptor.curYHotspot = nYhotspot;
281 for(i=0; i<bpllen; i++) tmpbpl[i] = ~lpANDbitPlane[i];
282 lpcur->pixmask = XCreatePixmapFromBitmapData(
283 display, DefaultRootWindow(display),
284 tmpbpl, nWidth, nHeight, 1, 0, 1);
285 for(i=0; i<bpllen; i++) tmpbpl[i] ^= lpXORbitPlane[i];
286 lpcur->pixshape = XCreatePixmapFromBitmapData(
287 display, DefaultRootWindow(display),
288 tmpbpl, nWidth, nHeight, 1, 0, 1);
289 XParseColor(display,cmap,"#000000",&fgcolor);
290 XParseColor(display,cmap,"#ffffff",&bkcolor);
291 lpcur->xcursor = XCreatePixmapCursor(display,
292 lpcur->pixshape, lpcur->pixmask,
293 &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot,
294 lpcur->descriptor.curYHotspot);
296 XFreePixmap(display, lpcur->pixshape);
297 XFreePixmap(display, lpcur->pixmask);
298 ReleaseDC(GetDesktopWindow(), hdc);
299 GlobalUnlock(hCursor);
305 /**********************************************************************
306 * DestroyCursor [USER.458]
308 BOOL DestroyCursor(HCURSOR hCursor)
313 if (hCursor == 0) return FALSE;
314 for (i = 0; i < NB_SYS_CURSORS; i++) {
315 if (system_cursor[i].cursor == hCursor) return TRUE;
317 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
318 if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap);
319 GlobalUnlock(hCursor);
325 /**********************************************************************
328 * Internal helper function for SetCursor() and ShowCursor().
330 static void CURSOR_SetCursor( HCURSOR hCursor )
334 if (!(lpcur = (CURSORALLOC *)GlobalLock(hCursor))) return;
335 if (rootWindow != DefaultRootWindow(display))
337 XDefineCursor( display, rootWindow, lpcur->xcursor );
341 HWND hwnd = GetWindow( GetDesktopWindow(), GW_CHILD );
344 Window win = WIN_GetXWindow( hwnd );
345 if (win) XDefineCursor( display, win, lpcur->xcursor );
346 hwnd = GetWindow( hwnd, GW_HWNDNEXT );
349 GlobalUnlock( hCursor );
352 /**********************************************************************
353 * SetCursor [USER.69]
355 HCURSOR SetCursor(HCURSOR hCursor)
359 dprintf_cursor(stddeb,"SetCursor / hCursor=%04X !\n", hCursor);
360 hOldCursor = hActiveCursor;
361 hActiveCursor = hCursor;
362 if ((hCursor != hOldCursor) || (ShowCursCount < 0))
364 CURSOR_SetCursor( hCursor );
371 /**********************************************************************
372 * GetCursor [USER.247]
374 HCURSOR GetCursor(void)
376 return hActiveCursor;
380 /**********************************************************************
381 * SetCursorPos [USER.70]
383 void SetCursorPos(short x, short y)
385 dprintf_cursor(stddeb,"SetCursorPos // x=%d y=%d\n", x, y);
386 XWarpPointer( display, None, rootWindow, 0, 0, 0, 0, x, y );
390 /**********************************************************************
391 * GetCursorPos [USER.17]
393 void GetCursorPos(LPPOINT lpRetPoint)
398 unsigned int mousebut;
400 if (!lpRetPoint) return;
401 if (!XQueryPointer( display, rootWindow, &root, &child,
402 &rootX, &rootY, &childX, &childY, &mousebut ))
403 lpRetPoint->x = lpRetPoint->y = 0;
406 lpRetPoint->x = rootX + desktopX;
407 lpRetPoint->y = rootY + desktopY;
409 dprintf_cursor(stddeb,
410 "GetCursorPos // x=%d y=%d\n", lpRetPoint->x, lpRetPoint->y);
414 /**********************************************************************
415 * ShowCursor [USER.71]
417 int ShowCursor(BOOL bShow)
419 dprintf_cursor(stddeb, "ShowCursor(%d), count=%d\n", bShow, ShowCursCount);
423 if (++ShowCursCount == 0) /* Time to show it */
424 CURSOR_SetCursor( hActiveCursor );
428 if (--ShowCursCount == -1) /* Time to hide it */
431 hEmptyCursor = CreateCursor( 0, 1, 1, 1, 1,
432 "\xFF\xFF", "\xFF\xFF" );
433 CURSOR_SetCursor( hEmptyCursor );
440 /**********************************************************************
441 * ClipCursor [USER.16]
443 void ClipCursor(LPRECT lpNewClipRect)
445 if (!lpNewClipRect) SetRectEmpty( &ClipCursorRect );
446 else CopyRect( &ClipCursorRect, lpNewClipRect );
450 /**********************************************************************
451 * GetClipCursor [USER.309]
453 void GetClipCursor(LPRECT lpRetClipRect)
455 if (lpRetClipRect != NULL)
456 CopyRect(lpRetClipRect, &ClipCursorRect);