Release 940301
[wine/gsoc-2012-control.git] / misc / cursor.c
blob931d538e411cfdb6027717014bd06fbdccc25562
1 /*
2 * WINE
3 */
4 static char Copyright[] = "Copyright Martin Ayotte, 1993";
6 /*
7 #define DEBUG_CURSOR
8 */
10 #include <X11/cursorfont.h>
11 #include <X11/Xlib.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include "prototypes.h"
19 #include "windows.h"
20 #include "win.h"
21 #include "gdi.h"
22 #include "wine.h"
23 #include "cursor.h"
25 static int ShowCursCount = 0;
26 static HCURSOR hActiveCursor;
27 static HCURSOR hEmptyCursor = 0;
28 RECT ClipCursorRect;
29 extern HINSTANCE hSysRes;
30 extern Window winHasCursor;
32 static struct { LPSTR name; HCURSOR cursor; } system_cursor[] =
34 { IDC_ARROW, 0 },
35 { IDC_IBEAM, 0 },
36 { IDC_WAIT, 0 },
37 { IDC_CROSS, 0 },
38 { IDC_UPARROW, 0 },
39 { IDC_SIZE, 0 },
40 { IDC_ICON, 0 },
41 { IDC_SIZENWSE, 0 },
42 { IDC_SIZENESW, 0 },
43 { IDC_SIZEWE, 0 },
44 { IDC_SIZENS, 0 }
47 #define NB_SYS_CURSORS (sizeof(system_cursor)/sizeof(system_cursor[0]))
50 /**********************************************************************
51 * LoadCursor [USER.173]
53 HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name)
55 XColor bkcolor;
56 XColor fgcolor;
57 HCURSOR hCursor;
58 HANDLE rsc_mem;
59 WORD *lp;
60 CURSORDESCRIP *lpcurdesc;
61 CURSORALLOC *lpcur;
62 BITMAP BitMap;
63 HBITMAP hBitMap;
64 HDC hMemDC;
65 HDC hdc;
66 int i, j, image_size;
67 #ifdef DEBUG_RESOURCE
68 printf("LoadCursor: instance = %04x, name = %08x\n",
69 instance, cursor_name);
70 #endif
72 if (!instance)
74 for (i = 0; i < NB_SYS_CURSORS; i++)
75 if (system_cursor[i].name == cursor_name)
77 hCursor = system_cursor[i].cursor;
78 break;
80 if (i == NB_SYS_CURSORS) return 0;
81 if (hCursor) return hCursor;
83 hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L);
84 if (hCursor == (HCURSOR)NULL) return 0;
85 if (!instance) system_cursor[i].cursor = hCursor;
87 #ifdef DEBUG_CURSOR
88 printf("LoadCursor Alloc hCursor=%X\n", hCursor);
89 #endif
90 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
91 memset(lpcur, 0, sizeof(CURSORALLOC));
92 if (instance == (HANDLE)NULL) {
93 instance = hSysRes;
94 switch((LONG)cursor_name) {
95 case IDC_ARROW:
96 lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow);
97 GlobalUnlock(hCursor);
98 return hCursor;
99 case IDC_CROSS:
100 lpcur->xcursor = XCreateFontCursor(XT_display, XC_crosshair);
101 GlobalUnlock(hCursor);
102 return hCursor;
103 case IDC_IBEAM:
104 lpcur->xcursor = XCreateFontCursor(XT_display, XC_xterm);
105 GlobalUnlock(hCursor);
106 return hCursor;
107 case IDC_WAIT:
108 lpcur->xcursor = XCreateFontCursor(XT_display, XC_watch);
109 GlobalUnlock(hCursor);
110 return hCursor;
111 case IDC_SIZENS:
112 lpcur->xcursor = XCreateFontCursor(XT_display, XC_sb_v_double_arrow);
113 GlobalUnlock(hCursor);
114 return hCursor;
115 case IDC_SIZEWE:
116 lpcur->xcursor = XCreateFontCursor(XT_display, XC_sb_h_double_arrow);
117 GlobalUnlock(hCursor);
118 return hCursor;
119 default:
120 break;
123 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
124 rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR,
125 &image_size);
126 if (rsc_mem == (HANDLE)NULL) {
127 printf("LoadCursor / Cursor %08X not Found !\n", cursor_name);
128 ReleaseDC(GetDesktopWindow(), hdc);
129 return 0;
131 lp = (WORD *)GlobalLock(rsc_mem);
132 if (lp == NULL) {
133 GlobalFree(rsc_mem);
134 ReleaseDC(GetDesktopWindow(), hdc);
135 return 0;
137 lpcurdesc = (CURSORDESCRIP *)(lp + 3);
138 #ifdef DEBUG_CURSOR
139 printf("LoadCursor / image_size=%d\n", image_size);
140 printf("LoadCursor / curReserved=%X\n", *lp);
141 printf("LoadCursor / curResourceType=%X\n", *(lp + 1));
142 printf("LoadCursor / curResourceCount=%X\n", *(lp + 2));
143 printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width);
144 printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height);
145 printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot);
146 printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot);
147 printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize);
148 printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset);
149 #endif
150 lpcur->descriptor = *lpcurdesc;
151 GlobalUnlock(rsc_mem);
152 GlobalFree(rsc_mem);
153 rsc_mem = RSC_LoadResource(instance,
154 MAKEINTRESOURCE(lpcurdesc->curDIBOffset),
155 NE_RSCTYPE_CURSOR, &image_size);
156 if (rsc_mem == (HANDLE)NULL) {
157 printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name);
158 ReleaseDC(GetDesktopWindow(), hdc);
159 return 0;
161 lp = (WORD *)GlobalLock(rsc_mem);
162 if (lp == NULL) {
163 GlobalFree(rsc_mem);
164 ReleaseDC(GetDesktopWindow(), hdc);
165 return 0;
167 lp += 2;
168 for (j = 0; j < 16; j++)
169 printf("%04X ", *(lp + j));
171 if (*lp == sizeof(BITMAPINFOHEADER))
172 lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp);
173 else
175 lpcur->hBitmap = 0;
176 lp += sizeof(BITMAP);
177 for (i = 0; i < 81; i++) {
178 char temp = *((char *)lp + 162 + i);
179 *((char *)lp + 162 + i) = *((char *)lp + 324 - i);
180 *((char *)lp + 324 - i) = temp;
182 lpcur->pixshape = XCreatePixmapFromBitmapData(
183 XT_display, DefaultRootWindow(XT_display),
184 ((char *)lp + 211), 32, 32,
186 lpcurdesc->Width / 2, lpcurdesc->Height / 4,
188 WhitePixel(XT_display, DefaultScreen(XT_display)),
189 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
190 lpcur->pixmask = XCreatePixmapFromBitmapData(
191 XT_display, DefaultRootWindow(XT_display),
192 ((char *)lp + 211), 32, 32,
193 WhitePixel(XT_display, DefaultScreen(XT_display)),
194 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
195 memset(&bkcolor, 0, sizeof(XColor));
196 memset(&fgcolor, 0, sizeof(XColor));
197 bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display));
198 fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
199 printf("LoadCursor / before XCreatePixmapCursor !\n");
200 lpcur->xcursor = XCreatePixmapCursor(XT_display,
201 lpcur->pixshape, lpcur->pixmask,
202 &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot,
203 lpcur->descriptor.curYHotspot);
204 GlobalUnlock(rsc_mem);
205 GlobalFree(rsc_mem);
207 hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot,
208 lpcur->descriptor.curYHotspot, 32, 32,
209 (LPSTR)lp + 211, , (LPSTR)lp + 211);
211 XFreePixmap(XT_display, lpcur->pixshape);
212 XFreePixmap(XT_display, lpcur->pixmask);
213 ReleaseDC(GetDesktopWindow(), hdc);
214 GlobalUnlock(hCursor);
215 return hCursor;
220 /**********************************************************************
221 * CreateCursor [USER.406]
223 HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot,
224 short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane)
226 XColor bkcolor;
227 XColor fgcolor;
228 HCURSOR hCursor;
229 CURSORALLOC *lpcur;
230 BITMAP BitMap;
231 HBITMAP hBitMap;
232 HDC hMemDC;
233 HDC hdc;
234 int i, j;
235 #ifdef DEBUG_RESOURCE
236 printf("CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n",
237 instance, nXhotspot, nYhotspot, nWidth, nHeight);
238 printf("CreateCursor: inst=%04x lpANDbitPlane=%08X lpXORbitPlane=%08X\n",
239 instance, lpANDbitPlane, lpXORbitPlane);
240 #endif
241 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
242 hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L);
243 if (hCursor == (HCURSOR)NULL) {
244 ReleaseDC(GetDesktopWindow(), hdc);
245 return 0;
247 printf("CreateCursor Alloc hCursor=%X\n", hCursor);
248 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
249 memset(lpcur, 0, sizeof(CURSORALLOC));
250 lpcur->descriptor.curXHotspot = nXhotspot;
251 lpcur->descriptor.curYHotspot = nYhotspot;
252 lpcur->pixshape = XCreatePixmapFromBitmapData(
253 XT_display, DefaultRootWindow(XT_display),
254 lpXORbitPlane, nWidth, nHeight,
255 WhitePixel(XT_display, DefaultScreen(XT_display)),
256 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
257 lpcur->pixmask = XCreatePixmapFromBitmapData(
258 XT_display, DefaultRootWindow(XT_display),
259 lpANDbitPlane, nWidth, nHeight,
260 WhitePixel(XT_display, DefaultScreen(XT_display)),
261 BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
262 memset(&bkcolor, 0, sizeof(XColor));
263 memset(&fgcolor, 0, sizeof(XColor));
264 bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display));
265 fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
266 lpcur->xcursor = XCreatePixmapCursor(XT_display,
267 lpcur->pixshape, lpcur->pixmask,
268 &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot,
269 lpcur->descriptor.curYHotspot);
270 XFreePixmap(XT_display, lpcur->pixshape);
271 XFreePixmap(XT_display, lpcur->pixmask);
272 ReleaseDC(GetDesktopWindow(), hdc);
273 GlobalUnlock(hCursor);
274 return hCursor;
279 /**********************************************************************
280 * DestroyCursor [USER.458]
282 BOOL DestroyCursor(HCURSOR hCursor)
284 CURSORALLOC *lpcur;
285 if (hCursor == (HCURSOR)NULL) return FALSE;
286 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
287 if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap);
288 GlobalUnlock(hCursor);
289 GlobalFree(hCursor);
290 return TRUE;
294 /**********************************************************************
295 * CURSOR_SetWinCursor
297 * Set the cursor for a given window. To be used instead of SetCursor()
298 * wherever possible.
300 HCURSOR CURSOR_SetWinCursor( HWND hwnd, HCURSOR hCursor )
302 CURSORALLOC *lpcur;
303 HCURSOR hOldCursor;
304 WND * wndPtr = WIN_FindWndPtr( hwnd );
306 if (!wndPtr || !hCursor) return 0;
307 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
308 hOldCursor = hActiveCursor;
309 if (hActiveCursor != hCursor) ShowCursCount = 0;
310 if (ShowCursCount >= 0)
311 XDefineCursor( display, wndPtr->window, lpcur->xcursor );
312 GlobalUnlock(hCursor);
313 hActiveCursor = hCursor;
314 return hOldCursor;
318 /**********************************************************************
319 * SetCursor [USER.69]
321 HCURSOR SetCursor(HCURSOR hCursor)
323 HDC hDC;
324 HDC hMemDC;
325 BITMAP bm;
326 CURSORALLOC *lpcur;
327 HCURSOR hOldCursor;
328 Window root, child;
329 int rootX, rootY;
330 int childX, childY;
331 unsigned int mousebut;
332 #ifdef DEBUG_CURSOR
333 printf("SetCursor / hCursor=%04X !\n", hCursor);
334 #endif
335 if (hCursor == (HCURSOR)NULL) return FALSE;
336 lpcur = (CURSORALLOC *)GlobalLock(hCursor);
337 hOldCursor = hActiveCursor;
338 #ifdef DEBUG_CURSOR
339 printf("SetCursor / lpcur->xcursor=%08X !\n", &lpcur->xcursor);
340 XQueryPointer(XT_display, DefaultRootWindow(XT_display),
341 &root, &child, &rootX, &rootY, &childX, &childY, &mousebut);
342 printf("SetCursor / winHasCursor=%08X !\n", winHasCursor);
343 printf("SetCursor / child=%08X !\n", child);
344 #endif
345 if (hActiveCursor != hCursor) ShowCursCount = 0;
346 if ((ShowCursCount >= 0) & (winHasCursor != 0)) {
347 /* XUndefineCursor(XT_display, winHasCursor); */
348 XDefineCursor(XT_display, winHasCursor, lpcur->xcursor);
350 GlobalUnlock(hCursor);
351 hActiveCursor = hCursor;
352 return hOldCursor;
356 /**********************************************************************
357 * SetCursorPos [USER.70]
359 void SetCursorPos(short x, short y)
361 Window root, child;
362 int rootX, rootY;
363 int childX, childY;
364 unsigned int mousebut;
365 #ifdef DEBUG_CURSOR
366 printf("SetCursorPos // x=%d y=%d\n", x, y);
367 #endif
368 XQueryPointer(XT_display, DefaultRootWindow(XT_display),
369 &root, &child, &rootX, &rootY, &childX, &childY, &mousebut);
370 XWarpPointer(XT_display, child, root, 0, 0,
371 DisplayWidth(XT_display, DefaultScreen(XT_display)),
372 DisplayHeight(XT_display, DefaultScreen(XT_display)),
373 (int)x, (int)y);
377 /**********************************************************************
378 * GetCursorPos [USER.17]
380 void GetCursorPos(LPPOINT lpRetPoint)
382 Window root, child;
383 int rootX, rootY;
384 int childX, childY;
385 unsigned int mousebut;
386 if (lpRetPoint != NULL) {
387 XQueryPointer(XT_display, DefaultRootWindow(XT_display),
388 &root, &child, &rootX, &rootY, &childX, &childY, &mousebut);
389 #ifdef DEBUG_CURSOR
390 printf("GetCursorPos // x=%d y=%d\n", rootX, rootY);
391 #endif
392 lpRetPoint->x = rootX;
393 lpRetPoint->y = rootY;
398 /**********************************************************************
399 * ShowCursor [USER.71]
401 int ShowCursor(BOOL bShow)
403 HCURSOR hCursor;
404 #ifdef DEBUG_CURSOR
405 printf("ShowCursor bShow=%d ShowCount=%d !\n", bShow, ShowCursCount);
406 #endif
407 if (bShow)
408 ShowCursCount++;
409 else
410 ShowCursCount--;
411 if (ShowCursCount >= 0) {
412 /* if (hCursor == (HCURSOR)NULL) */
413 hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
414 SetCursor(hCursor);
416 else {
417 /* XUndefineCursor(XT_display, winHasCursor); */
418 if (hEmptyCursor == (HCURSOR)NULL)
419 hEmptyCursor = CreateCursor((HINSTANCE)NULL, 1, 1, 1, 1,
420 "\xFF\xFF", "\xFF\xFF");
421 hCursor = SetCursor(hEmptyCursor);
422 hActiveCursor = hCursor;
424 return 0;
428 /**********************************************************************
429 * ClipCursor [USER.16]
431 void ClipCursor(LPRECT lpNewClipRect)
433 CopyRect(&ClipCursorRect, lpNewClipRect);
437 /**********************************************************************
438 * GetClipCursor [USER.309]
440 void GetClipCursor(LPRECT lpRetClipRect)
442 if (lpRetClipRect != NULL)
443 CopyRect(lpRetClipRect, &ClipCursorRect);