Release 940405
[wine/gsoc-2012-control.git] / misc / cursor.c
blobfa2d0ec5bb1ad3e3e549b5ce734d99934dd4ee9a
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;
130 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
131 rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR,
132 &image_size);
133 if (rsc_mem == (HANDLE)NULL) {
134 printf("LoadCursor / Cursor %08X not Found !\n", cursor_name);
135 ReleaseDC(GetDesktopWindow(), hdc);
136 return 0;
138 lp = (WORD *)GlobalLock(rsc_mem);
139 if (lp == NULL) {
140 GlobalFree(rsc_mem);
141 ReleaseDC(GetDesktopWindow(), hdc);
142 return 0;
144 lpcurdesc = (CURSORDESCRIP *)(lp + 3);
145 #ifdef DEBUG_CURSOR
146 printf("LoadCursor / image_size=%d\n", image_size);
147 printf("LoadCursor / curReserved=%X\n", *lp);
148 printf("LoadCursor / curResourceType=%X\n", *(lp + 1));
149 printf("LoadCursor / curResourceCount=%X\n", *(lp + 2));
150 printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width);
151 printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height);
152 printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot);
153 printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot);
154 printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize);
155 printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset);
156 #endif
157 lpcur->descriptor = *lpcurdesc;
158 GlobalUnlock(rsc_mem);
159 GlobalFree(rsc_mem);
160 rsc_mem = RSC_LoadResource(instance,
161 MAKEINTRESOURCE(lpcurdesc->curDIBOffset),
162 NE_RSCTYPE_CURSOR, &image_size);
163 if (rsc_mem == (HANDLE)NULL) {
164 printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name);
165 ReleaseDC(GetDesktopWindow(), hdc);
166 return 0;
168 lp = (WORD *)GlobalLock(rsc_mem);
169 if (lp == NULL) {
170 GlobalFree(rsc_mem);
171 ReleaseDC(GetDesktopWindow(), hdc);
172 return 0;
174 lp += 2;
175 for (j = 0; j < 16; j++)
176 printf("%04X ", *(lp + j));
178 if (*lp == sizeof(BITMAPINFOHEADER))
179 lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp);
180 else
182 lpcur->hBitmap = 0;
183 lp += sizeof(BITMAP);
184 for (i = 0; i < 81; i++) {
185 char temp = *((char *)lp + 162 + i);
186 *((char *)lp + 162 + i) = *((char *)lp + 324 - i);
187 *((char *)lp + 324 - i) = temp;
189 lpcur->pixshape = XCreatePixmapFromBitmapData(
190 XT_display, DefaultRootWindow(XT_display),
191 ((char *)lp + 211), 32, 32,
193 lpcurdesc->Width / 2, lpcurdesc->Height / 4,
195 WhitePixel(XT_display, DefaultScreen(XT_display)),
196 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
197 lpcur->pixmask = XCreatePixmapFromBitmapData(
198 XT_display, DefaultRootWindow(XT_display),
199 ((char *)lp + 211), 32, 32,
200 WhitePixel(XT_display, DefaultScreen(XT_display)),
201 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
202 memset(&bkcolor, 0, sizeof(XColor));
203 memset(&fgcolor, 0, sizeof(XColor));
204 bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display));
205 fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
206 printf("LoadCursor / before XCreatePixmapCursor !\n");
207 lpcur->xcursor = XCreatePixmapCursor(XT_display,
208 lpcur->pixshape, lpcur->pixmask,
209 &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot,
210 lpcur->descriptor.curYHotspot);
211 GlobalUnlock(rsc_mem);
212 GlobalFree(rsc_mem);
214 hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot,
215 lpcur->descriptor.curYHotspot, 32, 32,
216 (LPSTR)lp + 211, , (LPSTR)lp + 211);
218 XFreePixmap(XT_display, lpcur->pixshape);
219 XFreePixmap(XT_display, lpcur->pixmask);
220 ReleaseDC(GetDesktopWindow(), hdc);
221 GlobalUnlock(hCursor);
222 return hCursor;
227 /**********************************************************************
228 * CreateCursor [USER.406]
230 HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot,
231 short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane)
233 XColor bkcolor;
234 XColor fgcolor;
235 HCURSOR hCursor;
236 CURSORALLOC *lpcur;
237 BITMAP BitMap;
238 HBITMAP hBitMap;
239 HDC hMemDC;
240 HDC hdc;
241 int i, j;
242 #ifdef DEBUG_RESOURCE
243 printf("CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n",
244 instance, nXhotspot, nYhotspot, nWidth, nHeight);
245 printf("CreateCursor: inst=%04x lpANDbitPlane=%08X lpXORbitPlane=%08X\n",
246 instance, lpANDbitPlane, lpXORbitPlane);
247 #endif
248 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
249 hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L);
250 if (hCursor == (HCURSOR)NULL) {
251 ReleaseDC(GetDesktopWindow(), hdc);
252 return 0;
254 printf("CreateCursor Alloc hCursor=%X\n", hCursor);
255 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
256 memset(lpcur, 0, sizeof(CURSORALLOC));
257 lpcur->descriptor.curXHotspot = nXhotspot;
258 lpcur->descriptor.curYHotspot = nYhotspot;
259 lpcur->pixshape = XCreatePixmapFromBitmapData(
260 XT_display, DefaultRootWindow(XT_display),
261 lpXORbitPlane, nWidth, nHeight,
262 WhitePixel(XT_display, DefaultScreen(XT_display)),
263 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
264 lpcur->pixmask = XCreatePixmapFromBitmapData(
265 XT_display, DefaultRootWindow(XT_display),
266 lpANDbitPlane, nWidth, nHeight,
267 WhitePixel(XT_display, DefaultScreen(XT_display)),
268 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
269 memset(&bkcolor, 0, sizeof(XColor));
270 memset(&fgcolor, 0, sizeof(XColor));
271 bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display));
272 fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
273 lpcur->xcursor = XCreatePixmapCursor(XT_display,
274 lpcur->pixshape, lpcur->pixmask,
275 &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot,
276 lpcur->descriptor.curYHotspot);
277 XFreePixmap(XT_display, lpcur->pixshape);
278 XFreePixmap(XT_display, lpcur->pixmask);
279 ReleaseDC(GetDesktopWindow(), hdc);
280 GlobalUnlock(hCursor);
281 return hCursor;
286 /**********************************************************************
287 * DestroyCursor [USER.458]
289 BOOL DestroyCursor(HCURSOR hCursor)
291 CURSORALLOC *lpcur;
292 if (hCursor == (HCURSOR)NULL) return FALSE;
293 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
294 if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap);
295 GlobalUnlock(hCursor);
296 GlobalFree(hCursor);
297 return TRUE;
301 /**********************************************************************
302 * CURSOR_SetWinCursor
304 * Set the cursor for a given window. To be used instead of SetCursor()
305 * wherever possible.
307 HCURSOR CURSOR_SetWinCursor( HWND hwnd, HCURSOR hCursor )
309 CURSORALLOC *lpcur;
310 HCURSOR hOldCursor;
311 WND * wndPtr = WIN_FindWndPtr( hwnd );
313 if (!wndPtr || !hCursor) return 0;
314 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
315 hOldCursor = hActiveCursor;
316 if (hActiveCursor != hCursor) ShowCursCount = 0;
317 if (ShowCursCount >= 0)
318 XDefineCursor( display, wndPtr->window, lpcur->xcursor );
319 GlobalUnlock(hCursor);
320 hActiveCursor = hCursor;
321 return hOldCursor;
325 /**********************************************************************
326 * SetCursor [USER.69]
328 HCURSOR SetCursor(HCURSOR hCursor)
330 HDC hDC;
331 HDC hMemDC;
332 BITMAP bm;
333 CURSORALLOC *lpcur;
334 HCURSOR hOldCursor;
335 Window root, child;
336 int rootX, rootY;
337 int childX, childY;
338 unsigned int mousebut;
339 #ifdef DEBUG_CURSOR
340 printf("SetCursor / hCursor=%04X !\n", hCursor);
341 #endif
342 if (hCursor == (HCURSOR)NULL) return FALSE;
343 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
344 hOldCursor = hActiveCursor;
345 #ifdef DEBUG_CURSOR
346 printf("SetCursor / lpcur->xcursor=%08X !\n", &lpcur->xcursor);
347 XQueryPointer(XT_display, DefaultRootWindow(XT_display),
348 &root, &child, &rootX, &rootY, &childX, &childY, &mousebut);
349 printf("SetCursor / winHasCursor=%08X !\n", winHasCursor);
350 printf("SetCursor / child=%08X !\n", child);
351 #endif
352 if (hActiveCursor != hCursor) ShowCursCount = 0;
353 if ((ShowCursCount >= 0) & (winHasCursor != 0)) {
354 /* XUndefineCursor(XT_display, winHasCursor); */
355 XDefineCursor(XT_display, winHasCursor, lpcur->xcursor);
357 GlobalUnlock(hCursor);
358 hActiveCursor = hCursor;
359 return hOldCursor;
363 /**********************************************************************
364 * SetCursorPos [USER.70]
366 void SetCursorPos(short x, short y)
368 #ifdef DEBUG_CURSOR
369 printf("SetCursorPos // x=%d y=%d\n", x, y);
370 #endif
371 XWarpPointer( display, None, rootWindow, 0, 0, 0, 0, x, y );
375 /**********************************************************************
376 * GetCursorPos [USER.17]
378 void GetCursorPos(LPPOINT lpRetPoint)
380 Window root, child;
381 int rootX, rootY;
382 int childX, childY;
383 unsigned int mousebut;
385 if (!lpRetPoint) return;
386 if (!XQueryPointer( display, rootWindow, &root, &child,
387 &rootX, &rootY, &childX, &childY, &mousebut ))
388 lpRetPoint->x = lpRetPoint->y = 0;
389 else
391 lpRetPoint->x = rootX + desktopX;
392 lpRetPoint->y = rootY + desktopY;
394 #ifdef DEBUG_CURSOR
395 printf("GetCursorPos // x=%d y=%d\n", lpRetPoint->x, lpRetPoint->y);
396 #endif
400 /**********************************************************************
401 * ShowCursor [USER.71]
403 int ShowCursor(BOOL bShow)
405 HCURSOR hCursor;
406 #ifdef DEBUG_CURSOR
407 printf("ShowCursor bShow=%d ShowCount=%d !\n", bShow, ShowCursCount);
408 #endif
409 if (bShow)
410 ShowCursCount++;
411 else
412 ShowCursCount--;
413 if (ShowCursCount >= 0) {
414 /* if (hCursor == (HCURSOR)NULL) */
415 hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
416 SetCursor(hCursor);
418 else {
419 /* XUndefineCursor(XT_display, winHasCursor); */
420 if (hEmptyCursor == (HCURSOR)NULL)
421 hEmptyCursor = CreateCursor((HINSTANCE)NULL, 1, 1, 1, 1,
422 "\xFF\xFF", "\xFF\xFF");
423 hCursor = SetCursor(hEmptyCursor);
424 hActiveCursor = hCursor;
426 return 0;
430 /**********************************************************************
431 * ClipCursor [USER.16]
433 void ClipCursor(LPRECT lpNewClipRect)
435 CopyRect(&ClipCursorRect, lpNewClipRect);
439 /**********************************************************************
440 * GetClipCursor [USER.309]
442 void GetClipCursor(LPRECT lpRetClipRect)
444 if (lpRetClipRect != NULL)
445 CopyRect(lpRetClipRect, &ClipCursorRect);