Release 940912
[wine/multimedia.git] / misc / cursor.c
blob91e88ef44e5a31b52577683640ca36baff93d94d
1 /*
2 * WINE
3 */
4 static char Copyright[] = "Copyright Martin Ayotte, 1993";
6 /*
7 #define DEBUG_CURSOR
8 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17 #include <X11/cursorfont.h>
18 #include <X11/Xlib.h>
19 #include "prototypes.h"
20 #include "windows.h"
21 #include "win.h"
22 #include "gdi.h"
23 #include "wine.h"
24 #include "cursor.h"
26 static int ShowCursCount = 0;
27 static HCURSOR hActiveCursor;
28 static HCURSOR hEmptyCursor = 0;
29 RECT ClipCursorRect;
30 extern HINSTANCE hSysRes;
31 extern Window winHasCursor;
32 extern int desktopX, desktopY; /* misc/main.c */
34 static struct { LPSTR name; HCURSOR cursor; } system_cursor[] =
36 { IDC_ARROW, 0 },
37 { IDC_IBEAM, 0 },
38 { IDC_WAIT, 0 },
39 { IDC_CROSS, 0 },
40 { IDC_UPARROW, 0 },
41 { IDC_SIZE, 0 },
42 { IDC_ICON, 0 },
43 { IDC_SIZENWSE, 0 },
44 { IDC_SIZENESW, 0 },
45 { IDC_SIZEWE, 0 },
46 { IDC_SIZENS, 0 }
49 #define NB_SYS_CURSORS (sizeof(system_cursor)/sizeof(system_cursor[0]))
52 /**********************************************************************
53 * LoadCursor [USER.173]
55 HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name)
57 XColor bkcolor;
58 XColor fgcolor;
59 HCURSOR hCursor;
60 HANDLE rsc_mem;
61 WORD *lp;
62 CURSORDESCRIP *lpcurdesc;
63 CURSORALLOC *lpcur;
64 BITMAP BitMap;
65 HBITMAP hBitMap;
66 HDC hMemDC;
67 HDC hdc;
68 int i, j, image_size;
69 #ifdef DEBUG_RESOURCE
70 printf("LoadCursor: instance = %04x, name = %08x\n",
71 instance, cursor_name);
72 #endif
74 if (!instance)
76 for (i = 0; i < NB_SYS_CURSORS; i++)
77 if (system_cursor[i].name == cursor_name)
79 hCursor = system_cursor[i].cursor;
80 break;
82 if (i == NB_SYS_CURSORS) return 0;
83 if (hCursor) return hCursor;
85 hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L);
86 if (hCursor == (HCURSOR)NULL) return 0;
87 if (!instance) system_cursor[i].cursor = hCursor;
89 #ifdef DEBUG_CURSOR
90 printf("LoadCursor Alloc hCursor=%X\n", hCursor);
91 #endif
92 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
93 memset(lpcur, 0, sizeof(CURSORALLOC));
94 if (instance == (HANDLE)NULL) {
95 instance = hSysRes;
96 switch((LONG)cursor_name) {
97 case IDC_ARROW:
98 lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow);
99 GlobalUnlock(hCursor);
100 return hCursor;
101 case IDC_CROSS:
102 lpcur->xcursor = XCreateFontCursor(XT_display, XC_crosshair);
103 GlobalUnlock(hCursor);
104 return hCursor;
105 case IDC_IBEAM:
106 lpcur->xcursor = XCreateFontCursor(XT_display, XC_xterm);
107 GlobalUnlock(hCursor);
108 return hCursor;
109 case IDC_WAIT:
110 lpcur->xcursor = XCreateFontCursor(XT_display, XC_watch);
111 GlobalUnlock(hCursor);
112 return hCursor;
113 case IDC_SIZENS:
114 lpcur->xcursor = XCreateFontCursor(XT_display, XC_sb_v_double_arrow);
115 GlobalUnlock(hCursor);
116 return hCursor;
117 case IDC_SIZEWE:
118 lpcur->xcursor = XCreateFontCursor(XT_display, XC_sb_h_double_arrow);
119 GlobalUnlock(hCursor);
120 return hCursor;
121 case IDC_SIZENWSE:
122 case IDC_SIZENESW:
123 lpcur->xcursor = XCreateFontCursor(XT_display, XC_fleur);
124 GlobalUnlock(hCursor);
125 return hCursor;
126 default:
127 break;
131 #if 1
132 lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow);
133 GlobalUnlock(hCursor);
134 return hCursor;
135 #endif
137 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
138 rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR,
139 &image_size);
140 if (rsc_mem == (HANDLE)NULL) {
141 printf("LoadCursor / Cursor %08X not Found !\n", cursor_name);
142 ReleaseDC(GetDesktopWindow(), hdc);
143 return 0;
145 lp = (WORD *)GlobalLock(rsc_mem);
146 if (lp == NULL) {
147 GlobalFree(rsc_mem);
148 ReleaseDC(GetDesktopWindow(), hdc);
149 return 0;
151 lpcurdesc = (CURSORDESCRIP *)(lp + 3);
152 #ifdef DEBUG_CURSOR
153 printf("LoadCursor / image_size=%d\n", image_size);
154 printf("LoadCursor / curReserved=%X\n", *lp);
155 printf("LoadCursor / curResourceType=%X\n", *(lp + 1));
156 printf("LoadCursor / curResourceCount=%X\n", *(lp + 2));
157 printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width);
158 printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height);
159 printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot);
160 printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot);
161 printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize);
162 printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset);
163 #endif
164 lpcur->descriptor = *lpcurdesc;
165 GlobalUnlock(rsc_mem);
166 GlobalFree(rsc_mem);
167 rsc_mem = RSC_LoadResource(instance,
168 MAKEINTRESOURCE(lpcurdesc->curDIBOffset),
169 NE_RSCTYPE_CURSOR, &image_size);
170 if (rsc_mem == (HANDLE)NULL) {
171 printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name);
172 ReleaseDC(GetDesktopWindow(), hdc);
173 return 0;
175 lp = (WORD *)GlobalLock(rsc_mem);
176 if (lp == NULL) {
177 GlobalFree(rsc_mem);
178 ReleaseDC(GetDesktopWindow(), hdc);
179 return 0;
181 lp++;
182 for (j = 0; j < 16; j++)
183 printf("%04X ", *(lp + j));
185 if (*lp == sizeof(BITMAPINFOHEADER))
186 lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp);
187 else
189 lpcur->hBitmap = 0;
190 /* lp += sizeof(BITMAP); */
191 for (i = 0; i < 81; i++) {
192 char temp = *((char *)lp + 162 + i);
193 *((char *)lp + 162 + i) = *((char *)lp + 324 - i);
194 *((char *)lp + 324 - i) = temp;
196 lpcur->pixshape = XCreatePixmapFromBitmapData(
197 XT_display, DefaultRootWindow(XT_display),
198 ((char *)lp + 211), 32, 32,
200 lpcurdesc->Width / 2, lpcurdesc->Height / 4,
202 WhitePixel(XT_display, DefaultScreen(XT_display)),
203 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
204 lpcur->pixmask = XCreatePixmapFromBitmapData(
205 XT_display, DefaultRootWindow(XT_display),
206 ((char *)lp + 211), 32, 32,
207 WhitePixel(XT_display, DefaultScreen(XT_display)),
208 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
209 memset(&bkcolor, 0, sizeof(XColor));
210 memset(&fgcolor, 0, sizeof(XColor));
211 bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display));
212 fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
213 printf("LoadCursor / before XCreatePixmapCursor !\n");
214 lpcur->xcursor = XCreatePixmapCursor(XT_display,
215 lpcur->pixshape, lpcur->pixmask,
216 &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot,
217 lpcur->descriptor.curYHotspot);
218 GlobalUnlock(rsc_mem);
219 GlobalFree(rsc_mem);
221 hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot,
222 lpcur->descriptor.curYHotspot, 32, 32,
223 (LPSTR)lp + 211, , (LPSTR)lp + 211);
225 XFreePixmap(XT_display, lpcur->pixshape);
226 XFreePixmap(XT_display, lpcur->pixmask);
227 ReleaseDC(GetDesktopWindow(), hdc);
228 GlobalUnlock(hCursor);
229 return hCursor;
234 /**********************************************************************
235 * CreateCursor [USER.406]
237 HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot,
238 short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane)
240 XColor bkcolor;
241 XColor fgcolor;
242 HCURSOR hCursor;
243 CURSORALLOC *lpcur;
244 BITMAP BitMap;
245 HBITMAP hBitMap;
246 HDC hMemDC;
247 HDC hdc;
248 int i, j;
249 #ifdef DEBUG_RESOURCE
250 printf("CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n",
251 instance, nXhotspot, nYhotspot, nWidth, nHeight);
252 printf("CreateCursor: inst=%04x lpANDbitPlane=%08X lpXORbitPlane=%08X\n",
253 instance, lpANDbitPlane, lpXORbitPlane);
254 #endif
255 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
256 hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L);
257 if (hCursor == (HCURSOR)NULL) {
258 ReleaseDC(GetDesktopWindow(), hdc);
259 return 0;
261 printf("CreateCursor Alloc hCursor=%X\n", hCursor);
262 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
263 memset(lpcur, 0, sizeof(CURSORALLOC));
264 lpcur->descriptor.curXHotspot = nXhotspot;
265 lpcur->descriptor.curYHotspot = nYhotspot;
266 lpcur->pixshape = XCreatePixmapFromBitmapData(
267 XT_display, DefaultRootWindow(XT_display),
268 lpXORbitPlane, nWidth, nHeight,
269 WhitePixel(XT_display, DefaultScreen(XT_display)),
270 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
271 lpcur->pixmask = XCreatePixmapFromBitmapData(
272 XT_display, DefaultRootWindow(XT_display),
273 lpANDbitPlane, nWidth, nHeight,
274 WhitePixel(XT_display, DefaultScreen(XT_display)),
275 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
276 memset(&bkcolor, 0, sizeof(XColor));
277 memset(&fgcolor, 0, sizeof(XColor));
278 bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display));
279 fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
280 lpcur->xcursor = XCreatePixmapCursor(XT_display,
281 lpcur->pixshape, lpcur->pixmask,
282 &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot,
283 lpcur->descriptor.curYHotspot);
284 XFreePixmap(XT_display, lpcur->pixshape);
285 XFreePixmap(XT_display, lpcur->pixmask);
286 ReleaseDC(GetDesktopWindow(), hdc);
287 GlobalUnlock(hCursor);
288 return hCursor;
293 /**********************************************************************
294 * DestroyCursor [USER.458]
296 BOOL DestroyCursor(HCURSOR hCursor)
298 CURSORALLOC *lpcur;
299 if (hCursor == (HCURSOR)NULL) return FALSE;
300 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
301 if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap);
302 GlobalUnlock(hCursor);
303 GlobalFree(hCursor);
304 return TRUE;
308 /**********************************************************************
309 * CURSOR_SetWinCursor
311 * Set the cursor for a given window. To be used instead of SetCursor()
312 * wherever possible.
314 HCURSOR CURSOR_SetWinCursor( HWND hwnd, HCURSOR hCursor )
316 CURSORALLOC *lpcur;
317 HCURSOR hOldCursor;
318 WND * wndPtr = WIN_FindWndPtr( hwnd );
320 if (!wndPtr || !hCursor) return 0;
321 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
322 hOldCursor = hActiveCursor;
323 if (hActiveCursor != hCursor) ShowCursCount = 0;
324 if (ShowCursCount >= 0)
325 XDefineCursor( display, wndPtr->window, lpcur->xcursor );
326 GlobalUnlock(hCursor);
327 hActiveCursor = hCursor;
328 return hOldCursor;
332 /**********************************************************************
333 * SetCursor [USER.69]
335 HCURSOR SetCursor(HCURSOR hCursor)
337 HDC hDC;
338 HDC hMemDC;
339 BITMAP bm;
340 CURSORALLOC *lpcur;
341 HCURSOR hOldCursor;
342 Window root, child;
343 int rootX, rootY;
344 int childX, childY;
345 unsigned int mousebut;
346 #ifdef DEBUG_CURSOR
347 printf("SetCursor / hCursor=%04X !\n", hCursor);
348 #endif
349 if (hCursor == (HCURSOR)NULL) return FALSE;
350 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
351 hOldCursor = hActiveCursor;
352 #ifdef DEBUG_CURSOR
353 printf("SetCursor / lpcur->xcursor=%08X !\n", &lpcur->xcursor);
354 XQueryPointer(XT_display, DefaultRootWindow(XT_display),
355 &root, &child, &rootX, &rootY, &childX, &childY, &mousebut);
356 printf("SetCursor / winHasCursor=%08X !\n", winHasCursor);
357 printf("SetCursor / child=%08X !\n", child);
358 #endif
359 if (hActiveCursor != hCursor) ShowCursCount = 0;
360 if ((ShowCursCount >= 0) & (winHasCursor != 0)) {
361 /* XUndefineCursor(XT_display, winHasCursor); */
362 XDefineCursor(XT_display, winHasCursor, lpcur->xcursor);
364 GlobalUnlock(hCursor);
365 hActiveCursor = hCursor;
366 return hOldCursor;
369 /**********************************************************************
370 * GetCursor [USER.247]
372 HCURSOR GetCursor(void)
374 return hActiveCursor;
377 /**********************************************************************
378 * SetCursorPos [USER.70]
380 void SetCursorPos(short x, short y)
382 #ifdef DEBUG_CURSOR
383 printf("SetCursorPos // x=%d y=%d\n", x, y);
384 #endif
385 XWarpPointer( display, None, rootWindow, 0, 0, 0, 0, x, y );
389 /**********************************************************************
390 * GetCursorPos [USER.17]
392 void GetCursorPos(LPPOINT lpRetPoint)
394 Window root, child;
395 int rootX, rootY;
396 int childX, childY;
397 unsigned int mousebut;
399 if (!lpRetPoint) return;
400 if (!XQueryPointer( display, rootWindow, &root, &child,
401 &rootX, &rootY, &childX, &childY, &mousebut ))
402 lpRetPoint->x = lpRetPoint->y = 0;
403 else
405 lpRetPoint->x = rootX + desktopX;
406 lpRetPoint->y = rootY + desktopY;
408 #ifdef DEBUG_CURSOR
409 printf("GetCursorPos // x=%d y=%d\n", lpRetPoint->x, lpRetPoint->y);
410 #endif
414 /**********************************************************************
415 * ShowCursor [USER.71]
417 int ShowCursor(BOOL bShow)
419 HCURSOR hCursor;
420 #ifdef DEBUG_CURSOR
421 printf("ShowCursor bShow=%d ShowCount=%d !\n", bShow, ShowCursCount);
422 #endif
423 if (bShow)
424 ShowCursCount++;
425 else
426 ShowCursCount--;
427 if (ShowCursCount >= 0) {
428 /* if (hCursor == (HCURSOR)NULL) */
429 hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
430 SetCursor(hCursor);
432 else {
433 /* XUndefineCursor(XT_display, winHasCursor); */
434 if (hEmptyCursor == (HCURSOR)NULL)
435 hEmptyCursor = CreateCursor((HINSTANCE)NULL, 1, 1, 1, 1,
436 "\xFF\xFF", "\xFF\xFF");
437 hCursor = SetCursor(hEmptyCursor);
438 hActiveCursor = hCursor;
440 return 0;
444 /**********************************************************************
445 * ClipCursor [USER.16]
447 void ClipCursor(LPRECT lpNewClipRect)
449 CopyRect(&ClipCursorRect, lpNewClipRect);
453 /**********************************************************************
454 * GetClipCursor [USER.309]
456 void GetClipCursor(LPRECT lpRetClipRect)
458 if (lpRetClipRect != NULL)
459 CopyRect(lpRetClipRect, &ClipCursorRect);