update for HEAD-2003091401
[reactos.git] / subsys / win32k / objects / cursoricon.c
1 #undef WIN32_LEAN_AND_MEAN
2 #include <ddk/ntddk.h>
3 #include <ddk/ntddmou.h>
4 #include <win32k/win32k.h>
5 #include <windows.h>
6 #include <stdlib.h>
7 #include <win32k/cursoricon.h>
8 #include <win32k/bitmaps.h>
9 #include <include/winsta.h>
10 #include <include/error.h>
11 #include <include/mouse.h>
12 #include <include/window.h>
13 #include <internal/safe.h>
14
15 #define NDEBUG
16 #include <win32k/debug1.h>
17
18 BOOL FASTCALL IconCursor_InternalDelete( PICONCURSOROBJ pIconCursor )
19 {
20         ASSERT( pIconCursor );
21         if( pIconCursor->ANDBitmap.bmBits )
22                 ExFreePool(pIconCursor->ANDBitmap.bmBits);
23         if( pIconCursor->XORBitmap.bmBits )
24                 ExFreePool(pIconCursor->XORBitmap.bmBits);      
25         return TRUE;
26 }
27
28
29 /*
30  * @implemented
31  */
32 HICON 
33 STDCALL 
34 NtGdiCreateIcon(BOOL fIcon,
35                 INT  Width,
36                 INT  Height,
37                 UINT  Planes,
38                 UINT  BitsPerPel,
39                 DWORD xHotspot,
40                 DWORD yHotspot,
41                 CONST VOID *ANDBits,
42                 CONST VOID *XORBits)
43 {
44         PICONCURSOROBJ icon;
45         HICON hIcon;
46         
47         Planes = (BYTE) Planes;
48         BitsPerPel = (BYTE) BitsPerPel; 
49
50         /* Check parameters */
51         if (!Height || !Width)
52         {
53                 return 0;
54         }
55         if (Planes != 1)
56         {
57                 UNIMPLEMENTED;
58                 return  0;
59         }
60         
61         /* Create the ICONCURSOROBJ object*/
62         hIcon = ICONCURSOROBJ_AllocIconCursor ();
63         if (!hIcon)
64         {
65                 DPRINT("NtGdiCreateIcon: ICONCURSOROBJ_AllocIconCursor(hIcon == 0x%x) returned 0\n", hIcon);
66                 return 0;
67         }
68         
69         icon = ICONCURSOROBJ_LockIconCursor(hIcon);
70         
71         /* Set up the basic icon stuff */
72         icon->fIcon = TRUE;
73         icon->xHotspot = xHotspot;
74         icon->yHotspot = yHotspot;
75         
76         /* Setup the icon mask and icon color bitmaps */
77         icon->ANDBitmap.bmType = 0;
78         icon->ANDBitmap.bmWidth = Width;
79         icon->ANDBitmap.bmHeight = Height;
80         icon->ANDBitmap.bmPlanes = 1;
81         icon->ANDBitmap.bmBitsPixel = 1;
82         icon->ANDBitmap.bmWidthBytes = BITMAPOBJ_GetWidthBytes (Width, 1);
83         icon->ANDBitmap.bmBits = NULL;
84
85         icon->XORBitmap.bmType = 0;
86         icon->XORBitmap.bmWidth = Width;
87         icon->XORBitmap.bmHeight = Height;
88         icon->XORBitmap.bmPlanes = Planes;
89         icon->XORBitmap.bmBitsPixel = BitsPerPel;
90         icon->XORBitmap.bmWidthBytes = BITMAPOBJ_GetWidthBytes (Width, BitsPerPel);
91         icon->XORBitmap.bmBits = NULL;  
92         
93         /* allocate memory for the icon mask and icon color bitmaps,  
94            this will be freed in IconCursor_InternalDelete */
95     icon->ANDBitmap.bmBits = ExAllocatePool(PagedPool, Height * icon->ANDBitmap.bmWidthBytes);
96     icon->XORBitmap.bmBits = ExAllocatePool(PagedPool, Height * icon->XORBitmap.bmWidthBytes);
97
98         /* set the bits of the mask and color bitmaps */
99         if (ANDBits)
100         {
101                 memcpy(icon->ANDBitmap.bmBits, (PVOID)ANDBits, Height * icon->ANDBitmap.bmWidthBytes);
102         }
103
104         if (XORBits)
105         {
106                 memcpy(icon->XORBitmap.bmBits, (PVOID)XORBits, Height * icon->XORBitmap.bmWidthBytes);          
107         }
108         
109         ICONCURSOROBJ_UnlockIconCursor( hIcon );
110
111         return hIcon;
112 }
113
114
115 /*
116  * @implemented
117  */
118 DWORD
119 STDCALL
120 NtUserGetIconInfo(
121   HICON hIcon,
122   PBOOL fIcon,
123   PDWORD xHotspot,
124   PDWORD yHotspot,
125   HBITMAP *hbmMask,
126   HBITMAP *hbmColor)
127 {
128   PICONCURSOROBJ icon;
129
130   icon = ICONCURSOROBJ_LockIconCursor(hIcon);
131   
132   if (!icon)
133   {
134         DPRINT1("NtUserGetIconInfo: ICONCURSOROBJ_LockIconCursor(hIcon == 0x%x) returned 0\n", hIcon);
135         return FALSE;
136   }
137
138   *fIcon = icon->fIcon ;
139   *xHotspot = icon->xHotspot;
140   *yHotspot = icon->yHotspot;
141
142   *hbmMask = NtGdiCreateBitmap(icon->ANDBitmap.bmWidth,
143                               icon->ANDBitmap.bmHeight,
144                               icon->ANDBitmap.bmPlanes,
145                               icon->ANDBitmap.bmBitsPixel,
146                               icon->ANDBitmap.bmBits);
147
148   *hbmColor = NtGdiCreateBitmap(icon->XORBitmap.bmWidth,
149                                icon->XORBitmap.bmHeight,
150                                icon->XORBitmap.bmPlanes,
151                                icon->XORBitmap.bmBitsPixel,
152                                icon->XORBitmap.bmBits);
153
154   ICONCURSOROBJ_UnlockIconCursor(hIcon);
155
156   if (!*hbmMask || !*hbmColor)
157     return FALSE;
158     
159   return TRUE;
160 }
161
162
163 /*
164  * @implemented
165  */
166 BOOL
167 STDCALL
168 NtUserGetIconSize(
169   HICON hIcon,
170   BOOL *fIcon,
171   LONG *Width,
172   LONG *Height)
173 {
174   PICONCURSOROBJ icon;
175   
176   if (!hIcon || !Width || !Width)
177     return FALSE;
178
179   icon = ICONCURSOROBJ_LockIconCursor(hIcon);
180   
181   if (!icon)
182   {
183         DPRINT1("NtUserGetIconInfo: ICONCURSOROBJ_LockIconCursor() returned 0\n");
184         return FALSE;
185   }
186   
187   if(fIcon) *fIcon = icon->fIcon;
188   *Width = icon->ANDBitmap.bmWidth;
189   *Width = icon->ANDBitmap.bmHeight;
190   
191   ICONCURSOROBJ_UnlockIconCursor(hIcon);
192     
193   return TRUE;
194 }
195
196
197 /*
198  * @unimplemented
199  */
200 DWORD
201 STDCALL
202 NtUserGetCursorFrameInfo(
203   DWORD Unknown0,
204   DWORD Unknown1,
205   DWORD Unknown2,
206   DWORD Unknown3)
207 {
208   UNIMPLEMENTED
209
210   return 0;
211 }
212
213
214 /*
215  * @unimplemented
216  */
217 BOOL
218 STDCALL
219 NtUserGetCursorInfo(
220   PCURSORINFO pci)
221 {
222   UNIMPLEMENTED
223
224   return 0;
225 }
226
227
228 /*
229  * @implemented
230  */
231 BOOL
232 STDCALL
233 NtUserClipCursor(
234   RECT *UnsafeRect)
235 {
236   /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
237   
238   PWINSTATION_OBJECT WinStaObject;
239   PSYSTEM_CURSORINFO CurInfo;
240   PWINDOW_OBJECT DesktopWindow;
241   RECT Rect;
242
243   NTSTATUS Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
244                                        KernelMode,
245                                        0,
246                                        &WinStaObject);
247   if (!NT_SUCCESS(Status))
248   {
249     DPRINT1("Validation of window station handle (0x%X) failed\n",
250       PROCESS_WINDOW_STATION());
251     SetLastWin32Error(Status);
252     return FALSE;
253   }
254
255   if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
256   {
257     ObDereferenceObject(WinStaObject);
258     SetLastWin32Error(ERROR_INVALID_PARAMETER);
259     return FALSE;
260   }
261   
262   CurInfo = &WinStaObject->SystemCursor;
263   if(UnsafeRect)
264   {
265     if((Rect.right >= Rect.left) &&
266        (Rect.bottom >= Rect.top))
267     {
268       DesktopWindow = IntGetWindowObject(WinStaObject->ActiveDesktop->DesktopWindow);
269       CurInfo->CursorClipInfo.IsClipped = TRUE;
270       CurInfo->CursorClipInfo.Left = max(Rect.left, DesktopWindow->WindowRect.left);
271       CurInfo->CursorClipInfo.Top = max(Rect.top, DesktopWindow->WindowRect.top);
272       CurInfo->CursorClipInfo.Right = min(Rect.right, DesktopWindow->WindowRect.right);
273       CurInfo->CursorClipInfo.Bottom = min(Rect.bottom, DesktopWindow->WindowRect.bottom);
274       IntReleaseWindowObject(DesktopWindow);
275     
276       MouseMoveCursor(CurInfo->x, CurInfo->y);  
277     }
278   }
279   else
280     WinStaObject->SystemCursor.CursorClipInfo.IsClipped = FALSE;
281     
282   ObDereferenceObject(WinStaObject);
283   
284   return TRUE;
285 }
286
287
288 /*
289  * @unimplemented
290  */
291 BOOL
292 STDCALL
293 NtUserDestroyCursor(
294   HCURSOR hCursor,
295   DWORD Unknown)
296 {
297   UNIMPLEMENTED
298
299   return 0;
300 }
301
302
303 /*
304  * @unimplemented
305  */
306 DWORD
307 STDCALL
308 NtUserFindExistingCursorIcon(
309   DWORD Unknown0,
310   DWORD Unknown1,
311   DWORD Unknown2)
312 {
313   UNIMPLEMENTED
314
315   return 0;
316 }
317
318
319 /*
320  * @implemented
321  */
322 BOOL
323 STDCALL
324 NtUserGetClipCursor(
325   RECT *lpRect)
326 {
327   /* FIXME - check if process has WINSTA_READATTRIBUTES */
328   
329   PWINSTATION_OBJECT WinStaObject;
330   
331   if(!lpRect)
332     return FALSE;
333
334   NTSTATUS Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
335                                        KernelMode,
336                                        0,
337                                        &WinStaObject);
338   if (!NT_SUCCESS(Status))
339   {
340     DPRINT("Validation of window station handle (0x%X) failed\n",
341       PROCESS_WINDOW_STATION());
342     SetLastWin32Error(Status);
343     return FALSE;
344   }
345   
346   if(WinStaObject->SystemCursor.CursorClipInfo.IsClipped)
347   {
348     lpRect->left = WinStaObject->SystemCursor.CursorClipInfo.Left;
349     lpRect->top = WinStaObject->SystemCursor.CursorClipInfo.Top;
350     lpRect->right = WinStaObject->SystemCursor.CursorClipInfo.Right;
351     lpRect->bottom = WinStaObject->SystemCursor.CursorClipInfo.Bottom;
352   }
353   else
354   {
355     lpRect->left = 0;
356     lpRect->top = 0;
357     lpRect->right = NtUserGetSystemMetrics(SM_CXSCREEN);
358     lpRect->bottom = NtUserGetSystemMetrics(SM_CYSCREEN);
359   }
360     
361   ObDereferenceObject(WinStaObject);
362   
363   return TRUE;
364 }
365
366
367 /*
368  * @unimplemented
369  */
370 HCURSOR
371 STDCALL
372 NtUserSetCursor(
373   HCURSOR hCursor)
374 {
375   UNIMPLEMENTED
376
377   return 0;
378 }
379
380
381 /*
382  * @unimplemented
383  */
384 BOOL
385 STDCALL
386 NtUserSetCursorContents(
387   HCURSOR hCursor,
388   DWORD Unknown)
389 {
390   UNIMPLEMENTED
391
392   return 0;
393 }
394
395
396 /*
397  * @unimplemented
398  */
399 BOOL
400 STDCALL
401 NtUserSetCursorIconData(
402   HICON hIcon,
403   PBOOL fIcon,
404   PDWORD xHotspot,
405   PDWORD yHotspot)
406 {
407   UNIMPLEMENTED
408
409   return 0;
410 }
411
412
413 /*
414  * @implemented
415  */
416 BOOL
417 STDCALL
418 NtUserSetSystemCursor(
419   HCURSOR hcur,
420   DWORD id)
421 {
422   BOOL res = FALSE;
423
424   return res;
425 }