ReactOS 0.4.16-dev-401-g45b008d
cursoricon.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS user32.dll
3 * COPYRIGHT: GPL - See COPYING in the top level directory
4 * FILE: win32ss/user/user32/windows/cursoricon.c
5 * PURPOSE: cursor and icons implementation
6 * PROGRAMMER: Jérôme Gardou (jerome.gardou@reactos.org)
7 */
8
9#include <user32.h>
10
13//WINE_DECLARE_DEBUG_CHANNEL(resource);
14
15/* We only use Wide string functions */
16#undef MAKEINTRESOURCE
17#define MAKEINTRESOURCE MAKEINTRESOURCEW
18
19/************* USER32 INTERNAL FUNCTIONS **********/
20
22{
23 if (!gpsi->hIconSmWindows)
24 {
25 ERR("Loading System Cursors\n");
42 }
43}
44
45/* This callback routine is called directly after switching to gui mode */
49 ULONG ArgumentLength)
50{
51 BOOL *DefaultCursor = (BOOL*)Arguments;
52 HCURSOR hCursor;
53
54 /* Load system cursors first */
56
57 if(*DefaultCursor)
58 {
59 /* set default cursor */
60 hCursor = LoadCursorW(0, IDC_ARROW);
61 SetCursor(hCursor);
62 }
63 else
64 {
65 /* FIXME load system cursor scheme */
66 SetCursor(0);
67 hCursor = LoadCursorW(0, IDC_ARROW);
68 SetCursor(hCursor);
69 }
70
71 return(ZwCallbackReturn(&hCursor, sizeof(HCURSOR), STATUS_SUCCESS));
72}
73
75{
76 return NtUserGetIconSize(hIcon, 0, &size->cx, &size->cy);
77}
78
80{
82 return NULL;
83}
84
85/************* IMPLEMENTATION HELPERS ******************/
86
87static const WCHAR DISPLAYW[] = L"DISPLAY";
88
89static void *map_fileW( LPCWSTR name, LPDWORD filesize )
90{
91 HANDLE hFile, hMapping;
92 LPVOID ptr = NULL;
93
97 {
98 hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
99 if (hMapping)
100 {
101 ptr = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
102 CloseHandle( hMapping );
103 if (filesize)
104 *filesize = GetFileSize( hFile, NULL );
105 }
107 }
108 return ptr;
109}
110
111static int get_dib_image_size( int width, int height, int depth )
112{
113 return (((width * depth + 31) / 8) & ~3) * abs( height );
114}
115
117{
118 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
119 {
120 const RGBTRIPLE *rgb = ((const BITMAPCOREINFO*)info)->bmciColors;
121
122 if (((const BITMAPCOREINFO*)info)->bmciHeader.bcBitCount != 1) return FALSE;
123
124 /* Check if the first color is black */
125 if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
126 {
127 rgb++;
128
129 /* Check if the second color is white */
130 return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
131 && (rgb->rgbtBlue == 0xff));
132 }
133 else return FALSE;
134 }
135 else /* assume BITMAPINFOHEADER */
136 {
137 const RGBQUAD *rgb = info->bmiColors;
138
139 if (info->bmiHeader.biBitCount != 1) return FALSE;
140
141 /* Check if the first color is black */
142 if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
143 (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
144 {
145 rgb++;
146
147 /* Check if the second color is white */
148 return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
149 && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
150 }
151 else return FALSE;
152 }
153}
154
155/* Return the size of the bitmap info structure including color table and
156 * the bytes required for 3 DWORDS if this is a BI_BITFIELDS bmp. */
157static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
158{
159 unsigned int colors, size, masks = 0;
160
161 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
162 {
163 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
164 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
165 return sizeof(BITMAPCOREHEADER) + colors *
166 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
167 }
168 else /* assume BITMAPINFOHEADER */
169 {
170 colors = info->bmiHeader.biClrUsed;
171 if (colors > 256) /* buffer overflow otherwise */
172 colors = 256;
173 if (!colors && (info->bmiHeader.biBitCount <= 8))
174 colors = 1 << info->bmiHeader.biBitCount;
175 /* Account for BI_BITFIELDS in BITMAPINFOHEADER(v1-v3) bmp's. The
176 * 'max' selection using biSize below will exclude v4 & v5's. */
177 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
178 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
179 /* Test for BI_BITFIELDS format and either 16 or 32 bpp.
180 * If so, account for the 3 DWORD masks (RGB Order).
181 * BITMAPCOREHEADER tested above has no 16 or 32 bpp types.
182 * See table "All of the possible pixel formats in a DIB"
183 * at https://en.wikipedia.org/wiki/BMP_file_format. */
184 if (info->bmiHeader.biSize >= sizeof(BITMAPV4HEADER) &&
185 info->bmiHeader.biCompression == BI_BITFIELDS &&
186 (info->bmiHeader.biBitCount == 16 || info->bmiHeader.biBitCount == 32))
187 {
188 size += 3 * sizeof(DWORD); // BI_BITFIELDS
189 }
190 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
191 }
192}
193
196{
197 #define CR 13
198 #define LF 10
199 #define EOFM 26 // DOS End Of File Marker
200 #define HighBitDetect 0x89 // Byte with high bit set to test if not 7-bit
201 /* wine's definition */
202 static const BYTE png_sig_pattern[] = { HighBitDetect, 'P', 'N', 'G', CR, LF, EOFM, LF };
203 if (header->biSize == sizeof(BITMAPCOREHEADER))
204 {
205 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
206 *width = core->bcWidth;
207 *height = core->bcHeight;
208 *bpp = core->bcBitCount;
209 *compr = 0;
210 return 0;
211 }
212 else if (header->biSize == sizeof(BITMAPINFOHEADER) ||
213 header->biSize == sizeof(BITMAPV4HEADER) ||
214 header->biSize == sizeof(BITMAPV5HEADER))
215 {
216 *width = header->biWidth;
217 *height = header->biHeight;
218 *bpp = header->biBitCount;
219 *compr = header->biCompression;
220 return 1;
221 }
222 if (memcmp(&header->biSize, png_sig_pattern, sizeof(png_sig_pattern)) == 0)
223 {
224 ERR("Cannot yet display PNG icons\n");
225 /* for PNG format details see https://en.wikipedia.org/wiki/PNG */
226 }
227 else
228 {
229 ERR("Unknown/wrong size for header of 0x%x\n", header->biSize );
230 }
231 return -1;
232}
233
234/* copy an icon bitmap, even when it can't be selected into a DC */
235/* helper for CreateIconIndirect */
236static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
237{
239 BITMAP bm;
240 HBITMAP hbmpPrev;
241
242 GetObjectW(src, sizeof(bm), &bm);
243
244 hbmpPrev = SelectObject(hdc, src);
245
246 if (!hbmpPrev) /* do it the hard way */
247 {
249 void *bits;
250
251 if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return;
252 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
253 info->bmiHeader.biWidth = bm.bmWidth;
254 info->bmiHeader.biHeight = bm.bmHeight;
255 info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
256 info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
257 info->bmiHeader.biCompression = BI_RGB;
258 info->bmiHeader.biSizeImage = get_dib_image_size( bm.bmWidth, bm.bmHeight, info->bmiHeader.biBitCount );
259 info->bmiHeader.biXPelsPerMeter = 0;
260 info->bmiHeader.biYPelsPerMeter = 0;
261 info->bmiHeader.biClrUsed = 0;
262 info->bmiHeader.biClrImportant = 0;
263 bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
264 if (bits && GetDIBits( hdc, src, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
265 StretchDIBits( hdc_dst, 0, 0, dst_width, dst_height,
266 0, 0, bm.bmWidth, bm.bmHeight, bits, info, DIB_RGB_COLORS, SRCCOPY );
267
270 }
271 else
272 {
273 StretchBlt( hdc_dst, 0, 0, dst_width, dst_height, hdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
274 SelectObject(hdc, hbmpPrev);
275 }
276
277 DeleteDC( hdc );
278}
279
280/***********************************************************************
281 * bmi_has_alpha
282 */
283static BOOL bmi_has_alpha( const BITMAPINFO *info, const void *bits )
284{
285 int i;
286 BOOL has_alpha = FALSE;
287 const unsigned char *ptr = bits;
288
289 if (info->bmiHeader.biBitCount != 32) return FALSE;
290 for (i = 0; i < info->bmiHeader.biWidth * abs(info->bmiHeader.biHeight); i++, ptr += 4)
291 if ((has_alpha = (ptr[3] != 0))) break;
292 return has_alpha;
293}
294
295/***********************************************************************
296 * create_alpha_bitmap
297 *
298 * Create the alpha bitmap for a 32-bpp icon that has an alpha channel.
299 */
300static
304 _In_opt_ BITMAPINFO *src_info,
305 _In_opt_ const void *color_bits,
308{
310 HDC hdc = NULL, hdcScreen;
311 unsigned char *ptr;
312 void *bits = NULL;
313 ULONG size;
314
315 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
316 if (!hdcScreen)
317 return NULL;
318 hdc = CreateCompatibleDC(hdcScreen);
319 if (!hdc)
320 {
321 DeleteDC(hdcScreen);
322 return NULL;
323 }
324
325 if (color)
326 {
327 BITMAP bm;
329
330 TRACE("Creating alpha bitmap from existing bitmap.\n");
331
332 if (!GetObjectW( color, sizeof(bm), &bm ))
333 goto done;
334 if (bm.bmBitsPixel != 32)
335 goto done;
336
337 size = get_dib_image_size(bm.bmWidth, bm.bmHeight, 32);
338
339 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
340 if(!info)
341 goto done;
342 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
343 info->bmiHeader.biWidth = bm.bmWidth;
344 info->bmiHeader.biHeight = -bm.bmHeight;
345 info->bmiHeader.biPlanes = 1;
346 info->bmiHeader.biBitCount = 32;
347 info->bmiHeader.biCompression = BI_RGB;
348 info->bmiHeader.biSizeImage = size;
349 info->bmiHeader.biXPelsPerMeter = 0;
350 info->bmiHeader.biYPelsPerMeter = 0;
351 info->bmiHeader.biClrUsed = 0;
352 info->bmiHeader.biClrImportant = 0;
353
355 if(!bits)
356 {
358 goto done;
359 }
360 if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
361 {
363 goto done;
364 }
365 if (!bmi_has_alpha( info, bits ))
366 {
368 goto done;
369 }
370
371 /* pre-multiply by alpha */
372 for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
373 {
374 unsigned int alpha = ptr[3];
375 ptr[0] = (ptr[0] * alpha) / 255;
376 ptr[1] = (ptr[1] * alpha) / 255;
377 ptr[2] = (ptr[2] * alpha) / 255;
378 }
379
380 /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
382
384 }
385 else
386 {
387 WORD bpp;
388 DWORD compr;
389 LONG orig_width, orig_height;
390
391 TRACE("Creating alpha bitmap from bitmap info.\n");
392
393 if(!bmi_has_alpha(src_info, color_bits))
394 goto done;
395
396 if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &orig_width, &orig_height, &bpp, &compr))
397 goto done;
398 if(bpp != 32)
399 goto done;
400
401 size = get_dib_image_size(orig_width, orig_height, bpp);
403 if(!bits)
404 goto done;
405 CopyMemory(bits, color_bits, size);
406 /* pre-multiply by alpha */
407 for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
408 {
409 unsigned int alpha = ptr[3];
410 ptr[0] = (ptr[0] * alpha) / 255;
411 ptr[1] = (ptr[1] * alpha) / 255;
412 ptr[2] = (ptr[2] * alpha) / 255;
413 }
414
415 /* Create the bitmap. Set the bitmap info to have the right width and height */
416 if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
417 {
418 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = width;
419 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = height;
420 }
421 else
422 {
423 src_info->bmiHeader.biWidth = width;
424 src_info->bmiHeader.biHeight = height;
425 }
426 /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
427 alpha = CreateDIBitmap(hdcScreen, NULL, 2, NULL, src_info, DIB_RGB_COLORS);
428 /* Restore values */
429 if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
430 {
431 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = orig_width;
432 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = orig_height;
433 }
434 else
435 {
436 src_info->bmiHeader.biWidth = orig_width;
437 src_info->bmiHeader.biHeight = orig_height;
438 }
439 if(!alpha)
440 goto done;
442 if(!hbmpOld)
443 {
445 alpha = NULL;
446 goto done;
447 }
448 if(!StretchDIBits( hdc, 0, 0, width, height,
449 0, 0, orig_width, orig_height,
450 bits, src_info, DIB_RGB_COLORS, SRCCOPY ))
451 {
453 hbmpOld = NULL;
455 alpha = NULL;
456 }
457 else
458 {
460 }
461 }
462
463done:
464 DeleteDC(hdcScreen);
465 DeleteDC( hdc );
466 if(bits) HeapFree(GetProcessHeap(), 0, bits);
467
468 TRACE("Returning 0x%08x.\n", alpha);
469 return alpha;
470}
471
472#include "pshpack1.h"
473
474typedef struct {
475 BYTE bWidth;
476 BYTE bHeight;
477 BYTE bColorCount;
478 BYTE bReserved;
479 WORD xHotspot;
480 WORD yHotspot;
481 DWORD dwDIBSize;
482 DWORD dwDIBOffset;
484
485typedef struct
486{
487 WORD idReserved;
488 WORD idType;
489 WORD idCount;
490 CURSORICONFILEDIRENTRY idEntries[1];
492
493#include "poppack.h"
494
499 _In_ int cxDesired,
500 _In_ int cyDesired,
501 _In_ BOOL bIcon,
502 _In_ DWORD fuLoad
503)
504{
505 CURSORICONDIR* fakeDir;
506 CURSORICONDIRENTRY* fakeEntry;
507 WORD i;
509
510 /* Check our file is what it claims to be */
511 if ( dwFileSize < sizeof(*dir) )
512 return NULL;
513
514 if (dwFileSize < FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount]))
515 return NULL;
516
517 /*
518 * Cute little hack:
519 * We allocate a buffer, fake it as if it was a pointer to a resource in a module,
520 * pass it to LookupIconIdFromDirectoryEx and get back the index we have to use
521 */
522 fakeDir = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(CURSORICONDIR, idEntries[dir->idCount]));
523 if(!fakeDir)
524 {
526 return NULL;
527 }
528 fakeDir->idReserved = 0;
529 fakeDir->idType = dir->idType;
530 fakeDir->idCount = dir->idCount;
531 for(i = 0; i<dir->idCount; i++)
532 {
533 fakeEntry = &fakeDir->idEntries[i];
534 entry = &dir->idEntries[i];
535 /* Take this as an occasion to perform a size check */
536 if ((entry->dwDIBOffset > dwFileSize)
537 || ((entry->dwDIBOffset + entry->dwDIBSize) > dwFileSize))
538 {
539 ERR("Corrupted icon file?.\n");
540 HeapFree(GetProcessHeap(), 0, fakeDir);
541 return NULL;
542 }
543 /* File icon/cursors are not like resource ones */
544 if(bIcon)
545 {
546 fakeEntry->ResInfo.icon.bWidth = entry->bWidth;
547 fakeEntry->ResInfo.icon.bHeight = entry->bHeight;
548 fakeEntry->ResInfo.icon.bColorCount = 0;
549 fakeEntry->ResInfo.icon.bReserved = 0;
550 }
551 else
552 {
553 fakeEntry->ResInfo.cursor.wWidth = entry->bWidth;
554 fakeEntry->ResInfo.cursor.wHeight = entry->bHeight;
555 }
556 /* Let's assume there's always one plane */
557 fakeEntry->wPlanes = 1;
558 /* We must get the bitcount from the BITMAPINFOHEADER itself */
559 if (((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biSize == sizeof(BITMAPCOREHEADER))
560 fakeEntry->wBitCount = ((BITMAPCOREHEADER *)((char *)dir + entry->dwDIBOffset))->bcBitCount;
561 else
562 fakeEntry->wBitCount = ((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biBitCount;
563 fakeEntry->dwBytesInRes = entry->dwDIBSize;
564 fakeEntry->wResId = i + 1;
565 }
566
567 /* Now call LookupIconIdFromResourceEx */
568 i = LookupIconIdFromDirectoryEx((PBYTE)fakeDir, bIcon, cxDesired, cyDesired, fuLoad & LR_MONOCHROME);
569 /* We don't need this anymore */
570 HeapFree(GetProcessHeap(), 0, fakeDir);
571 if(i == 0)
572 {
573 WARN("Unable to get a fit entry index.\n");
574 return NULL;
575 }
576
577 /* We found it */
578 return &dir->idEntries[i-1];
579}
580
581DWORD
583 _In_ const LPBYTE dir,
585 _In_ int cxDesired,
586 _In_ int cyDesired,
587 _In_ BOOL bIcon,
588 _In_ DWORD fuLoad,
589 _Out_ POINT *ptHotSpot
590)
591{
593
594 entry = get_best_icon_file_entry((CURSORICONFILEDIR *) dir, dwFileSize, cxDesired, cyDesired, bIcon, fuLoad);
595
596 if(ptHotSpot)
597 {
598 ptHotSpot->x = entry->xHotspot;
599 ptHotSpot->y = entry->yHotspot;
600 }
601
602 if(entry)
603 return entry->dwDIBOffset;
604
605 return 0;
606}
607
608
609
610/************* IMPLEMENTATION CORE ****************/
611
614 _In_ const BITMAPINFO *pbmi
615)
616{
618 BOOL monochrome = is_dib_monochrome(pbmi);
620 WORD bpp;
621 DWORD compr;
622 int ibmpType;
623 HDC hdc, hdcScreen;
624 BITMAPINFO* pbmiCopy;
626 BOOL bResult = FALSE;
627 const VOID *pvColor, *pvMask;
628
629 ibmpType = DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr);
630 /* Invalid data */
631 if(ibmpType < 0)
632 return FALSE;
633
634 /* No compression for icons */
635 if(compr != BI_RGB)
636 return FALSE;
637
638 /* If no dimensions were set, use the one from the icon */
639 if(!pdata->cx) pdata->cx = width;
640 if(!pdata->cy) pdata->cy = height < 0 ? -height/2 : height/2;
641
642 /* Fix the hotspot coords */
643 if(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR))
644 {
645 if(pdata->cx != width)
646 pdata->xHotspot = (pdata->xHotspot * pdata->cx) / width;
647 if(pdata->cy != height/2)
648 pdata->yHotspot = (pdata->yHotspot * pdata->cy * 2) / height;
649 }
650 else
651 {
652 pdata->xHotspot = pdata->cx/2;
653 pdata->yHotspot = pdata->cy/2;
654 }
655
656 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
657 if(!hdcScreen)
658 return FALSE;
659 hdc = CreateCompatibleDC(hdcScreen);
660 if(!hdc)
661 {
662 DeleteDC(hdcScreen);
663 return FALSE;
664 }
665
666 pbmiCopy = HeapAlloc(GetProcessHeap(), 0, max(ubmiSize, FIELD_OFFSET(BITMAPINFO, bmiColors[3])));
667 if(!pbmiCopy)
668 goto done;
669 RtlCopyMemory(pbmiCopy, pbmi, ubmiSize);
670
671 /* In an icon/cursor, the BITMAPINFO holds twice the height */
672 if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
673 ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2;
674 else
675 pbmiCopy->bmiHeader.biHeight /= 2;
676 height /= 2;
677
678 pvColor = (const char*)pbmi + ubmiSize;
679 pvMask = (const char*)pvColor +
681
682 /* Set XOR bits */
683 if(monochrome)
684 {
685 /* Create the 1bpp bitmap which will contain everything */
686 pdata->hbmColor = NULL;
687 pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy * 2, 1, 1, NULL);
688 if(!pdata->hbmMask)
689 goto done;
690 hbmpOld = SelectObject(hdc, pdata->hbmMask);
691 if(!hbmpOld)
692 goto done;
693
694 if(!StretchDIBits(hdc, 0, pdata->cy, pdata->cx, pdata->cy,
695 0, 0, width, height,
696 pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
697 goto done;
698 pdata->bpp = 1;
699 }
700 else
701 {
702 /* Create the bitmap. It has to be compatible with the screen surface */
703 pdata->hbmColor = CreateCompatibleBitmap(hdcScreen, pdata->cx, pdata->cy);
704 if(!pdata->hbmColor)
705 goto done;
706 /* Create the 1bpp mask bitmap */
707 pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy, 1, 1, NULL);
708 if(!pdata->hbmMask)
709 goto done;
710 hbmpOld = SelectObject(hdc, pdata->hbmColor);
711 if(!hbmpOld)
712 goto done;
713 if(!StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
714 0, 0, width, height,
715 pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
716 goto done;
717 pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL);
718 pdata->hbmAlpha = create_alpha_bitmap(NULL, pbmiCopy, pvColor, pdata->cx, pdata->cy);
719
720 /* Now convert the info to monochrome for the mask bits */
721 if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
722 {
723 RGBQUAD *rgb = pbmiCopy->bmiColors;
724
725 pbmiCopy->bmiHeader.biClrUsed = pbmiCopy->bmiHeader.biClrImportant = 2;
726 rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
727 rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
728 rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
729 pbmiCopy->bmiHeader.biBitCount = 1;
730 }
731 else
732 {
733 RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pbmiCopy) + 1);
734
735 rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
736 rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
737 ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount = 1;
738 }
739 }
740 /* Set the mask bits */
741 if(!SelectObject(hdc, pdata->hbmMask))
742 goto done;
743 bResult = StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
744 0, 0, width, height,
745 pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0;
746
747done:
748 DeleteDC(hdcScreen);
750 DeleteDC(hdc);
751 if(pbmiCopy) HeapFree(GetProcessHeap(), 0, pbmiCopy);
752 /* Clean up in case of failure */
753 if(!bResult)
754 {
755 if(pdata->hbmMask) DeleteObject(pdata->hbmMask);
756 if(pdata->hbmColor) DeleteObject(pdata->hbmColor);
757 if(pdata->hbmAlpha) DeleteObject(pdata->hbmAlpha);
758 }
759 return bResult;
760}
761
763 _Out_ CURSORDATA* pCursorData,
764 _In_ ICONINFO* pIconInfo
765)
766{
767 BITMAP bm;
768
769 ZeroMemory(pCursorData, sizeof(*pCursorData));
770 if(pIconInfo->hbmColor)
771 {
772 /* We must convert the color bitmap to screen format */
773 HDC hdcScreen, hdcMem;
774 HBITMAP hbmpPrev;
775
776 /* The mask dictates its dimensions */
777 if (!GetObject(pIconInfo->hbmMask, sizeof(bm), &bm))
778 return FALSE;
779 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
780 if(!hdcScreen)
781 return FALSE;
782 hdcMem = CreateCompatibleDC(hdcScreen);
783 if(!hdcMem)
784 {
785 DeleteDC(hdcScreen);
786 return FALSE;
787 }
788 pCursorData->hbmColor = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
789 DeleteDC(hdcScreen);
790 if (!pCursorData->hbmColor)
791 {
793 return FALSE;
794 }
795 hbmpPrev = SelectObject(hdcMem, pCursorData->hbmColor);
796 if (!hbmpPrev)
797 {
799 DeleteObject(pCursorData->hbmColor);
800 return FALSE;
801 }
802 stretch_blt_icon( hdcMem, bm.bmWidth, bm.bmHeight, pIconInfo->hbmColor);
803 SelectObject(hdcMem, hbmpPrev);
805 }
806 pCursorData->hbmMask = CopyImage(pIconInfo->hbmMask, IMAGE_BITMAP, 0, 0, LR_MONOCHROME);
807 if(!pCursorData->hbmMask)
808 return FALSE;
809
810 /* Now, fill some information */
811 pCursorData->rt = (USHORT)((ULONG_PTR)(pIconInfo->fIcon ? RT_ICON : RT_CURSOR));
812 if(pCursorData->hbmColor)
813 {
814 GetObject(pCursorData->hbmColor, sizeof(bm), &bm);
815 pCursorData->bpp = bm.bmBitsPixel;
816 pCursorData->cx = bm.bmWidth;
817 pCursorData->cy = bm.bmHeight;
818 if(pCursorData->bpp == 32)
819 pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor, NULL, NULL, 0, 0);
820 }
821 else
822 {
823 GetObject(pCursorData->hbmMask, sizeof(bm), &bm);
824 pCursorData->bpp = 1;
825 pCursorData->cx = bm.bmWidth;
826 pCursorData->cy = bm.bmHeight/2;
827 }
828
829 if(pIconInfo->fIcon)
830 {
831 pCursorData->xHotspot = pCursorData->cx/2;
832 pCursorData->yHotspot = pCursorData->cy/2;
833 }
834 else
835 {
836 pCursorData->xHotspot = pIconInfo->xHotspot;
837 pCursorData->yHotspot = pIconInfo->yHotspot;
838 }
839
840 return TRUE;
841}
842
843
844#define RIFF_FOURCC( c0, c1, c2, c3 ) \
845 ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
846 ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
847
848#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
849#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
850#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
851#define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
852#define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
853#define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
854#define ANI_rate_ID RIFF_FOURCC('r', 'a', 't', 'e')
855
856#define ANI_FLAG_ICON 0x1
857#define ANI_FLAG_SEQUENCE 0x2
858
859#include <pshpack1.h>
860typedef struct {
861 DWORD header_size;
862 DWORD num_frames;
863 DWORD num_steps;
864 DWORD width;
866 DWORD bpp;
867 DWORD num_planes;
868 DWORD display_rate;
869 DWORD flags;
870} ani_header;
871
872typedef struct {
874 const unsigned char *data;
876#include <poppack.h>
877
878static void dump_ani_header( const ani_header *header )
879{
880 TRACE(" header size: %d\n", header->header_size);
881 TRACE(" frames: %d\n", header->num_frames);
882 TRACE(" steps: %d\n", header->num_steps);
883 TRACE(" width: %d\n", header->width);
884 TRACE(" height: %d\n", header->height);
885 TRACE(" bpp: %d\n", header->bpp);
886 TRACE(" planes: %d\n", header->num_planes);
887 TRACE(" display rate: %d\n", header->display_rate);
888 TRACE(" flags: 0x%08x\n", header->flags);
889}
890
891/* Find an animated cursor chunk, given its type and ID */
892static void riff_find_chunk( DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk )
893{
894 const unsigned char *ptr = parent_chunk->data;
895 const unsigned char *end = parent_chunk->data + (parent_chunk->data_size - (2 * sizeof(DWORD)));
896
897 if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) end -= sizeof(DWORD);
898
899 while (ptr < end)
900 {
901 if ((!chunk_type && *(const DWORD *)ptr == chunk_id )
902 || (chunk_type && *(const DWORD *)ptr == chunk_type && *((const DWORD *)ptr + 2) == chunk_id ))
903 {
904 ptr += sizeof(DWORD);
905 chunk->data_size = (*(const DWORD *)ptr + 1) & ~1;
906 ptr += sizeof(DWORD);
907 if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) ptr += sizeof(DWORD);
908 chunk->data = ptr;
909
910 return;
911 }
912
913 ptr += sizeof(DWORD);
914 ptr += (*(const DWORD *)ptr + 1) & ~1;
915 ptr += sizeof(DWORD);
916 }
917}
918
920 _Inout_ CURSORDATA* pCurData,
921 _In_ const BYTE *pData,
922 _In_ DWORD dwDataSize,
923 _In_ DWORD fuLoad
924)
925{
926 UINT i;
927 const ani_header *pHeader;
928 riff_chunk_t root_chunk = { dwDataSize, pData };
929 riff_chunk_t ACON_chunk = {0};
930 riff_chunk_t anih_chunk = {0};
931 riff_chunk_t fram_chunk = {0};
932 riff_chunk_t rate_chunk = {0};
933 riff_chunk_t seq_chunk = {0};
934 const unsigned char *icon_chunk;
935 const unsigned char *icon_data;
936
937 /* Find the root chunk */
938 riff_find_chunk( ANI_ACON_ID, ANI_RIFF_ID, &root_chunk, &ACON_chunk );
939 if (!ACON_chunk.data)
940 {
941 ERR("Failed to get root chunk.\n");
942 return FALSE;
943 }
944
945 /* Find the header chunk */
946 riff_find_chunk( ANI_anih_ID, 0, &ACON_chunk, &anih_chunk );
947 if (!ACON_chunk.data)
948 {
949 ERR("Failed to get header chunk.\n");
950 return FALSE;
951 }
952 pHeader = (ani_header*)anih_chunk.data;
954
955 /* Set up the master data */
956 pCurData->CURSORF_flags |= CURSORF_ACON;
957 pCurData->cpcur = pHeader->num_frames;
958 pCurData->cicur = pHeader->num_steps;
959 pCurData->iicur = pHeader->display_rate;
960
961 /* Get the sequences */
962 if (pHeader->flags & ANI_FLAG_SEQUENCE)
963 {
964 riff_find_chunk( ANI_seq__ID, 0, &ACON_chunk, &seq_chunk );
965 if (!seq_chunk.data)
966 {
967 ERR("No sequence data although the flag is set!\n");
968 return FALSE;
969 }
970 }
971
972 /* Get the frame rates */
973 riff_find_chunk( ANI_rate_ID, 0, &ACON_chunk, &rate_chunk );
974 if (rate_chunk.data)
975 pCurData->ajifRate = (INT*)rate_chunk.data;
976
977 /* Get the frames chunk */
978 riff_find_chunk( ANI_fram_ID, ANI_LIST_ID, &ACON_chunk, &fram_chunk );
979 if (!fram_chunk.data)
980 {
981 ERR("Failed to get icon list.\n");
982 return 0;
983 }
984 icon_chunk = fram_chunk.data;
985 icon_data = fram_chunk.data + (2 * sizeof(DWORD));
986
987 if(pHeader->num_frames > 1)
988 {
989 /* Allocate frame descriptors, step indices and rates */
990 pCurData->aspcur = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
991 pHeader->num_frames * sizeof(CURSORDATA) + pHeader->num_steps * (sizeof(DWORD) + sizeof(INT)));
992 if(!pCurData->aspcur)
993 {
995 return FALSE;
996 }
997 pCurData->aicur = (DWORD*)(pCurData->aspcur + pHeader->num_frames);
998 pCurData->ajifRate = (INT*)(pCurData->aicur + pHeader->num_steps);
999 }
1000
1001 for(i=0; i < pHeader->num_frames; i++)
1002 {
1003 CURSORDATA* pFrameData;
1004 const DWORD chunk_size = *(const DWORD *)(icon_chunk + sizeof(DWORD));
1005 const BITMAPINFO* pbmi;
1006
1007 if(pHeader->num_frames > 1)
1008 pFrameData = &pCurData->aspcur[i];
1009 else
1010 pFrameData = pCurData;
1011
1012 pFrameData->rt = pCurData->rt;
1013
1014 if (pHeader->flags & ANI_FLAG_ICON)
1015 {
1016 /* The chunks describe an icon file */
1018 (const CURSORICONFILEDIR *) icon_data,
1019 chunk_size,
1020 pCurData->cx,
1021 pCurData->cy,
1022 TRUE,
1023 fuLoad);
1024 if(!pDirEntry)
1025 {
1026 ERR("Unable to find the right file entry for frame %d.\n", i);
1027 goto error;
1028 }
1029 pFrameData->xHotspot = pDirEntry->xHotspot;
1030 pFrameData->yHotspot = pDirEntry->yHotspot;
1031 if(!pHeader->width || !pHeader->height)
1032 {
1033 pFrameData->cx = pDirEntry->bWidth;
1034 pFrameData->cy = pDirEntry->bHeight;
1035 }
1036 else
1037 {
1038 pFrameData->cx = pHeader->width;
1039 pFrameData->cy = pHeader->height;
1040 }
1041 pbmi = (const BITMAPINFO *) (icon_data + pDirEntry->dwDIBOffset);
1042 }
1043 else
1044 {
1045 /* The chunks just describe bitmaps */
1046 pbmi = (const BITMAPINFO *)icon_data;
1047 pFrameData->xHotspot = pFrameData->yHotspot = 0;
1048 }
1049
1050 /* Do the real work */
1052
1053 if(pHeader->num_frames > 1)
1054 pFrameData->CURSORF_flags |= CURSORF_ACONFRAME;
1055 else
1056 pFrameData->CURSORF_flags &= ~CURSORF_ACON;
1057
1058
1059 /* Next frame */
1060 icon_chunk += chunk_size + (2 * sizeof(DWORD));
1061 icon_data = icon_chunk + (2 * sizeof(DWORD));
1062 }
1063
1064 if(pHeader->num_frames <= 1)
1065 return TRUE;
1066
1067 if(rate_chunk.data)
1068 CopyMemory(pCurData->ajifRate, rate_chunk.data, pHeader->num_steps * sizeof(INT));
1069 else
1070 {
1071 for(i=0; i < pHeader->num_steps; i++)
1072 pCurData->ajifRate[i] = pHeader->display_rate;
1073 }
1074
1075 if (pHeader->flags & ANI_FLAG_SEQUENCE)
1076 {
1077 CopyMemory(pCurData->aicur, seq_chunk.data, pHeader->num_steps * sizeof(DWORD));
1078 }
1079 else
1080 {
1081 for(i=0; i < pHeader->num_steps; i++)
1082 pCurData->aicur[i] = i;
1083 }
1084
1085 return TRUE;
1086
1087error:
1088 HeapFree(GetProcessHeap(), 0, pCurData->aspcur);
1089 ZeroMemory(pCurData, sizeof(CURSORDATA));
1090 return FALSE;
1091}
1092
1093
1094static
1095HBITMAP
1098 _In_ LPCWSTR lpszName,
1099 _In_ int cxDesired,
1100 _In_ int cyDesired,
1101 _In_ UINT fuLoad
1102)
1103{
1104 const BITMAPINFO* pbmi;
1105 BITMAPINFO* pbmiScaled = NULL;
1106 BITMAPINFO* pbmiCopy = NULL;
1107 const VOID* pvMapping = NULL;
1108 DWORD dwOffset = 0;
1109 HGLOBAL hgRsrc = NULL;
1110 int iBMISize;
1111 PVOID pvBits;
1112 HDC hdcScreen = NULL;
1113 HDC hdc = NULL;
1114 HBITMAP hbmpOld, hbmpRet = NULL;
1115 LONG width, height;
1116 WORD bpp;
1117 DWORD compr, ResSize = 0;
1118
1119 /* Map the bitmap info */
1120 if(fuLoad & LR_LOADFROMFILE)
1121 {
1122 const BITMAPFILEHEADER* pbmfh;
1123
1124 pvMapping = map_fileW(lpszName, NULL);
1125 if(!pvMapping)
1126 return NULL;
1127 pbmfh = pvMapping;
1128 if (pbmfh->bfType != 0x4d42 /* 'BM' */)
1129 {
1130 WARN("Invalid/unsupported bitmap format!\n");
1131 goto end;
1132 }
1133 pbmi = (const BITMAPINFO*)(pbmfh + 1);
1134
1135 /* Get the image bits */
1136 if(pbmfh->bfOffBits)
1137 dwOffset = pbmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
1138 }
1139 else
1140 {
1141 HRSRC hrsrc;
1142
1143 /* Caller wants an OEM bitmap */
1144 if(!hinst)
1146 hrsrc = FindResourceW(hinst, lpszName, RT_BITMAP);
1147 if(!hrsrc)
1148 return NULL;
1149 hgRsrc = LoadResource(hinst, hrsrc);
1150 if(!hgRsrc)
1151 return NULL;
1152 pbmi = LockResource(hgRsrc);
1153 if(!pbmi)
1154 return NULL;
1155 ResSize = SizeofResource(hinst, hrsrc);
1156 }
1157
1158 /* Fix up values */
1159 if(DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr) == -1)
1160 goto end;
1161 if((width > 65535) || (height > 65535))
1162 goto end;
1163 if(cxDesired == 0)
1164 cxDesired = width;
1165 if(cyDesired == 0)
1166 cyDesired = height;
1167 else if(height < 0)
1168 cyDesired = -cyDesired;
1169
1171
1172 /* Get a pointer to the image data */
1173 pvBits = (char*)pbmi + (dwOffset ? dwOffset : iBMISize);
1174
1175 /* Create a copy of the info describing the bitmap in the file */
1176 pbmiCopy = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1177 if(!pbmiCopy)
1178 goto end;
1179 CopyMemory(pbmiCopy, pbmi, iBMISize);
1180
1181 TRACE("Size Image %d, Size Header %d, ResSize %d\n",
1182 pbmiCopy->bmiHeader.biSizeImage, pbmiCopy->bmiHeader.biSize, ResSize);
1183
1184 /* HACK: If this is a binutils' windres.exe compiled 16 or 32 bpp bitmap
1185 * using BI_BITFIELDS, then a bug causes it to fail to include
1186 * the bytes for the bitfields. So, we have to substract out the
1187 * size of the bitfields previously included from bitmap_info_size. */
1188 if (compr == BI_BITFIELDS && (bpp == 16 || bpp == 32) &&
1189 pbmiCopy->bmiHeader.biSizeImage + pbmiCopy->bmiHeader.biSize == ResSize)
1190 {
1191 /* GCC pointer to the image data has 12 less bytes than MSVC */
1192 pvBits = (char*)pvBits - 12;
1193 WARN("Found GCC Resource Compiled 16-bpp or 32-bpp error\n");
1194 }
1195
1196 /* Fix it up, if needed */
1197 if(fuLoad & (LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS))
1198 {
1199 WORD bpp, incr, numColors;
1200 char* pbmiColors;
1201 RGBTRIPLE* ptr;
1202 COLORREF crWindow, cr3DShadow, cr3DFace, cr3DLight;
1203 BYTE pixel = *((BYTE*)pvBits);
1204 UINT i;
1205
1206 if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1207 {
1208 bpp = ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount;
1209 numColors = 1 << bpp;
1210 /* BITMAPCOREINFO holds RGBTRIPLEs */
1211 incr = 3;
1212 }
1213 else
1214 {
1215 bpp = pbmiCopy->bmiHeader.biBitCount;
1216 /* BITMAPINFOHEADER holds RGBQUADs */
1217 incr = 4;
1218 numColors = pbmiCopy->bmiHeader.biClrUsed;
1219 if(numColors > 256) numColors = 256;
1220 if (!numColors && (bpp <= 8)) numColors = 1 << bpp;
1221 }
1222
1223 if(bpp > 8)
1224 goto create_bitmap;
1225
1226 pbmiColors = (char*)pbmiCopy + pbmiCopy->bmiHeader.biSize;
1227
1228 /* Get the relevant colors */
1229 crWindow = GetSysColor(COLOR_WINDOW);
1230 cr3DShadow = GetSysColor(COLOR_3DSHADOW);
1231 cr3DFace = GetSysColor(COLOR_3DFACE);
1232 cr3DLight = GetSysColor(COLOR_3DLIGHT);
1233
1234 /* Fix the transparent palette entry */
1235 if(fuLoad & LR_LOADTRANSPARENT)
1236 {
1237 switch(bpp)
1238 {
1239 case 1: pixel >>= 7; break;
1240 case 4: pixel >>= 4; break;
1241 case 8: break;
1242 default:
1243 FIXME("Unhandled bit depth %d.\n", bpp);
1244 goto create_bitmap;
1245 }
1246
1247 if(pixel >= numColors)
1248 {
1249 ERR("Wrong pixel passed in.\n");
1250 goto create_bitmap;
1251 }
1252
1253 /* If both flags are set, we must use COLOR_3DFACE */
1254 if(fuLoad & LR_LOADMAP3DCOLORS) crWindow = cr3DFace;
1255
1256 /* Define the color */
1257 ptr = (RGBTRIPLE*)(pbmiColors + pixel*incr);
1258 ptr->rgbtBlue = GetBValue(crWindow);
1259 ptr->rgbtGreen = GetGValue(crWindow);
1260 ptr->rgbtRed = GetRValue(crWindow);
1261 goto create_bitmap;
1262 }
1263
1264 /* If we are here, then LR_LOADMAP3DCOLORS is set without LR_TRANSPARENT */
1265 for(i = 0; i<numColors; i++)
1266 {
1267 ptr = (RGBTRIPLE*)(pbmiColors + i*incr);
1268 if((ptr->rgbtBlue == ptr->rgbtRed) && (ptr->rgbtBlue == ptr->rgbtGreen))
1269 {
1270 if(ptr->rgbtBlue == 128)
1271 {
1272 ptr->rgbtBlue = GetBValue(cr3DShadow);
1273 ptr->rgbtGreen = GetGValue(cr3DShadow);
1274 ptr->rgbtRed = GetRValue(cr3DShadow);
1275 }
1276 if(ptr->rgbtBlue == 192)
1277 {
1278 ptr->rgbtBlue = GetBValue(cr3DFace);
1279 ptr->rgbtGreen = GetGValue(cr3DFace);
1280 ptr->rgbtRed = GetRValue(cr3DFace);
1281 }
1282 if(ptr->rgbtBlue == 223)
1283 {
1284 ptr->rgbtBlue = GetBValue(cr3DLight);
1285 ptr->rgbtGreen = GetGValue(cr3DLight);
1286 ptr->rgbtRed = GetRValue(cr3DLight);
1287 }
1288 }
1289 }
1290 }
1291
1293 if(fuLoad & LR_CREATEDIBSECTION)
1294 {
1295 /* Allocate the BMI describing the new bitmap */
1296 pbmiScaled = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1297 if(!pbmiScaled)
1298 goto end;
1299 CopyMemory(pbmiScaled, pbmiCopy, iBMISize);
1300
1301 /* Fix it up */
1302 if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1303 {
1304 BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader;
1305 pbmch->bcWidth = cxDesired;
1306 pbmch->bcHeight = cyDesired;
1307 }
1308 else
1309 {
1310 pbmiScaled->bmiHeader.biWidth = cxDesired;
1311 pbmiScaled->bmiHeader.biHeight = cyDesired;
1312 /* No compression for DIB sections */
1313 pbmiScaled->bmiHeader.biCompression = BI_RGB;
1314 }
1315 }
1316
1317 /* Top-down image */
1318 if(cyDesired < 0) cyDesired = -cyDesired;
1319
1320 /* We need a device context */
1321 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
1322 if(!hdcScreen)
1323 goto end;
1324 hdc = CreateCompatibleDC(hdcScreen);
1325 if(!hdc)
1326 goto end;
1327
1328 /* Now create the bitmap */
1329 if(fuLoad & LR_CREATEDIBSECTION)
1330 hbmpRet = CreateDIBSection(hdc, pbmiScaled, DIB_RGB_COLORS, NULL, 0, 0);
1331 else
1332 {
1333 if(is_dib_monochrome(pbmiCopy) || (fuLoad & LR_MONOCHROME))
1334 hbmpRet = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL);
1335 else
1336 hbmpRet = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired);
1337 }
1338
1339 if(!hbmpRet)
1340 goto end;
1341
1342 hbmpOld = SelectObject(hdc, hbmpRet);
1343 if(!hbmpOld)
1344 goto end;
1345 if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
1346 0, 0, width, height,
1347 pvBits, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
1348 {
1349 ERR("StretchDIBits failed!.\n");
1351 DeleteObject(hbmpRet);
1352 hbmpRet = NULL;
1353 goto end;
1354 }
1355
1357
1358end:
1359 if(hdcScreen)
1360 DeleteDC(hdcScreen);
1361 if(hdc)
1362 DeleteDC(hdc);
1363 if(pbmiScaled)
1364 HeapFree(GetProcessHeap(), 0, pbmiScaled);
1365 if(pbmiCopy)
1366 HeapFree(GetProcessHeap(), 0, pbmiCopy);
1367 if (pvMapping)
1368 UnmapViewOfFile( pvMapping );
1369 if(hgRsrc)
1370 FreeResource(hgRsrc);
1371
1372 return hbmpRet;
1373}
1374
1375
1376static
1377HANDLE
1379 _In_ LPCWSTR lpszName,
1380 _In_ int cxDesired,
1381 _In_ int cyDesired,
1382 _In_ UINT fuLoad,
1383 _In_ BOOL bIcon
1384)
1385{
1387 const CURSORICONFILEDIR *dir;
1388 DWORD filesize = 0;
1389 LPBYTE bits;
1390 HANDLE hCurIcon = NULL;
1391 CURSORDATA cursorData;
1392
1393 TRACE("loading %s\n", debugstr_w( lpszName ));
1394
1395 bits = map_fileW( lpszName, &filesize );
1396 if (!bits)
1397 return NULL;
1398
1399 /* Check for .ani. */
1400 if (memcmp( bits, "RIFF", 4 ) == 0)
1401 {
1403 goto end;
1404 }
1405
1407 entry = get_best_icon_file_entry(dir, filesize, cxDesired, cyDesired, bIcon, fuLoad);
1408 if(!entry)
1409 goto end;
1410
1411 /* Fix dimensions */
1412 if(!cxDesired) cxDesired = entry->bWidth;
1413 if(!cyDesired) cyDesired = entry->bHeight;
1414 /* A bit of preparation */
1415 ZeroMemory(&cursorData, sizeof(cursorData));
1416 if(!bIcon)
1417 {
1418 cursorData.xHotspot = entry->xHotspot;
1419 cursorData.yHotspot = entry->yHotspot;
1420 }
1421 cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
1422
1423 /* Do the dance */
1424 if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)(&bits[entry->dwDIBOffset])))
1425 {
1426 ERR("Failing File is \n '%S'.\n", lpszName);
1427 goto end;
1428 }
1429
1431 if(!hCurIcon)
1432 goto end;
1433
1434 /* Tell win32k */
1435 if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData))
1436 {
1437 NtUserDestroyCursor(hCurIcon, TRUE);
1438 goto end_error;
1439 }
1440
1441end:
1443 return hCurIcon;
1444
1445 /* Clean up */
1446end_error:
1447 DeleteObject(cursorData.hbmMask);
1448 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1449 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1451
1452 return NULL;
1453}
1454
1455static
1456HANDLE
1459 _In_ LPCWSTR lpszName,
1460 _In_ int cxDesired,
1461 _In_ int cyDesired,
1462 _In_ UINT fuLoad,
1463 _In_ BOOL bIcon
1464)
1465{
1466 HRSRC hrsrc;
1467 HANDLE handle, hCurIcon = NULL;
1469 WORD wResId;
1470 LPBYTE bits;
1471 CURSORDATA cursorData;
1472 BOOL bStatus;
1473 UNICODE_STRING ustrRsrc;
1474 UNICODE_STRING ustrModule = {0, 0, NULL};
1475
1476 /* Fix width/height */
1477 if(fuLoad & LR_DEFAULTSIZE)
1478 {
1479 if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR);
1480 if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR);
1481 }
1482
1483 if(fuLoad & LR_LOADFROMFILE)
1484 {
1485 return CURSORICON_LoadFromFileW(lpszName, cxDesired, cyDesired, fuLoad, bIcon);
1486 }
1487
1488 /* Check if caller wants OEM icons */
1489 if(!hinst)
1491
1492 if(lpszName)
1493 {
1494 /* Prepare the resource name string */
1495 if(IS_INTRESOURCE(lpszName))
1496 {
1497 ustrRsrc.Buffer = (LPWSTR)lpszName;
1498 ustrRsrc.Length = 0;
1499 ustrRsrc.MaximumLength = 0;
1500 }
1501 else
1502 RtlInitUnicodeString(&ustrRsrc, lpszName);
1503 }
1504
1506 {
1507 /* We don't have a real module for GetModuleFileName, construct a fake name instead.
1508 * GetIconInfoEx reveals the name used by Windows. */
1509 LPCWSTR fakeNameFmt = sizeof(void*) > 4 ? L"\x01%016IX" : L"\x01%08IX";
1510 ustrModule.MaximumLength = 18 * sizeof(WCHAR);
1511 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
1512 if (!ustrModule.Buffer)
1513 {
1515 return NULL;
1516 }
1517 ustrModule.Length = wsprintfW(ustrModule.Buffer, fakeNameFmt, hinst) * sizeof(WCHAR);
1518 }
1519 else if(hinst)
1520 {
1522 /* Get the module name string */
1523 while (TRUE)
1524 {
1525 DWORD ret;
1526 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
1527 if (!ustrModule.Buffer)
1528 {
1530 return NULL;
1531 }
1532 ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
1533 if(ret == 0)
1534 {
1535 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1536 return NULL;
1537 }
1538
1539 /* This API is completely broken... */
1540 if (ret == size)
1541 {
1542 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1543 size *= 2;
1544 continue;
1545 }
1546
1547 ustrModule.Buffer[ret] = UNICODE_NULL;
1548 ustrModule.Length = ret * sizeof(WCHAR);
1549 ustrModule.MaximumLength = size * sizeof(WCHAR);
1550 break;
1551 }
1552 }
1553
1554 if(fuLoad & LR_SHARED)
1555 {
1557
1558 TRACE("Checking for an LR_SHARED cursor/icon.\n");
1559 /* Ask win32k */
1560 param.bIcon = bIcon;
1561 param.cx = cxDesired;
1562 param.cy = cyDesired;
1563 hCurIcon = NtUserFindExistingCursorIcon(&ustrModule, &ustrRsrc, &param);
1564 if(hCurIcon)
1565 {
1566 /* Woohoo, got it! */
1567 TRACE("MATCH! %p\n",hCurIcon);
1568 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1569 return hCurIcon;
1570 }
1571 }
1572
1573 /* Find resource ID */
1574 hrsrc = FindResourceW(
1575 hinst,
1576 lpszName,
1577 bIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
1578
1579 /* We let FindResource, LoadResource, etc. call SetLastError */
1580 if(!hrsrc)
1581 goto done;
1582
1583 handle = LoadResource(hinst, hrsrc);
1584 if(!handle)
1585 goto done;
1586
1588 if(!dir)
1589 goto done;
1590
1591 wResId = LookupIconIdFromDirectoryEx((PBYTE)dir, bIcon, cxDesired, cyDesired, fuLoad);
1593
1594 /* Get the relevant resource pointer */
1595 hrsrc = FindResourceW(
1596 hinst,
1597 MAKEINTRESOURCEW(wResId),
1598 bIcon ? RT_ICON : RT_CURSOR);
1599 if(!hrsrc)
1600 goto done;
1601
1602 handle = LoadResource(hinst, hrsrc);
1603 if(!handle)
1604 goto done;
1605
1607 if(!bits)
1608 {
1610 goto done;
1611 }
1612
1613 ZeroMemory(&cursorData, sizeof(cursorData));
1614
1615 /* This is from resource */
1617
1618 if(dir->idType == 2)
1619 {
1620 /* idType == 2 for cursor resources */
1621 SHORT* ptr = (SHORT*)bits;
1622 cursorData.xHotspot = ptr[0];
1623 cursorData.yHotspot = ptr[1];
1624 bits += 2*sizeof(SHORT);
1625 }
1626 cursorData.cx = cxDesired;
1627 cursorData.cy = cyDesired;
1628 cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
1629
1630 /* Get the bitmaps */
1632 &cursorData,
1633 (BITMAPINFO*)bits);
1634
1636
1637 if(!bStatus)
1638 goto done;
1639
1640 /* Create the handle */
1642 if(!hCurIcon)
1643 {
1644 goto end_error;
1645 }
1646
1647 if(fuLoad & LR_SHARED)
1648 {
1649 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
1650 }
1651
1652 /* Tell win32k */
1653 bStatus = NtUserSetCursorIconData(hCurIcon, hinst ? &ustrModule : NULL, lpszName ? &ustrRsrc : NULL, &cursorData);
1654
1655 if(!bStatus)
1656 {
1657 NtUserDestroyCursor(hCurIcon, TRUE);
1658 goto end_error;
1659 }
1660
1661done:
1662 if(ustrModule.Buffer)
1663 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1664 return hCurIcon;
1665
1666end_error:
1667 if(ustrModule.Buffer)
1668 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1669 DeleteObject(cursorData.hbmMask);
1670 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1671 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1672
1673 return NULL;
1674}
1675
1676static
1677HBITMAP
1679 _In_ HBITMAP hnd,
1680 _In_ int desiredx,
1681 _In_ int desiredy,
1683)
1684{
1685 HBITMAP res = NULL;
1686 DIBSECTION ds;
1687 int objSize;
1688 BITMAPINFO * bi;
1689
1690 objSize = GetObjectW( hnd, sizeof(ds), &ds );
1691 if (!objSize) return 0;
1692 if ((desiredx < 0) || (desiredy < 0)) return 0;
1693
1695 {
1696 FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
1697 }
1698
1699 if (flags & LR_COPYRETURNORG)
1700 {
1701 FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n");
1702 }
1703
1704 if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
1705 if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
1706
1707 /* Allocate memory for a BITMAPINFOHEADER structure and a
1708 color table. The maximum number of colors in a color table
1709 is 256 which corresponds to a bitmap with depth 8.
1710 Bitmaps with higher depths don't have color tables. */
1711 bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1712 if (!bi) return 0;
1713
1714 bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
1715 bi->bmiHeader.biPlanes = ds.dsBm.bmPlanes;
1716 bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
1718
1720 {
1721 /* Create a DIB section. LR_MONOCHROME is ignored */
1722 void * bits;
1724
1725 if (objSize == sizeof(DIBSECTION))
1726 {
1727 /* The source bitmap is a DIB.
1728 Get its attributes to create an exact copy */
1729 memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
1730 }
1731
1732 bi->bmiHeader.biWidth = desiredx;
1733 bi->bmiHeader.biHeight = desiredy;
1734
1735 /* Get the color table or the color masks */
1736 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
1737
1739 DeleteDC(dc);
1740 }
1741 else
1742 {
1743 /* Create a device-dependent bitmap */
1744
1745 BOOL monochrome = (flags & LR_MONOCHROME);
1746
1747 if (objSize == sizeof(DIBSECTION))
1748 {
1749 /* The source bitmap is a DIB section.
1750 Get its attributes */
1752 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
1753 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
1754 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
1755 DeleteDC(dc);
1756
1757 if (!monochrome && ds.dsBm.bmBitsPixel == 1)
1758 {
1759 /* Look if the colors of the DIB are black and white */
1760
1761 monochrome =
1762 (bi->bmiColors[0].rgbRed == 0xff
1763 && bi->bmiColors[0].rgbGreen == 0xff
1764 && bi->bmiColors[0].rgbBlue == 0xff
1765 && bi->bmiColors[0].rgbReserved == 0
1766 && bi->bmiColors[1].rgbRed == 0
1767 && bi->bmiColors[1].rgbGreen == 0
1768 && bi->bmiColors[1].rgbBlue == 0
1769 && bi->bmiColors[1].rgbReserved == 0)
1770 ||
1771 (bi->bmiColors[0].rgbRed == 0
1772 && bi->bmiColors[0].rgbGreen == 0
1773 && bi->bmiColors[0].rgbBlue == 0
1774 && bi->bmiColors[0].rgbReserved == 0
1775 && bi->bmiColors[1].rgbRed == 0xff
1776 && bi->bmiColors[1].rgbGreen == 0xff
1777 && bi->bmiColors[1].rgbBlue == 0xff
1778 && bi->bmiColors[1].rgbReserved == 0);
1779 }
1780 }
1781 else if (!monochrome)
1782 {
1783 monochrome = ds.dsBm.bmBitsPixel == 1;
1784 }
1785
1786 if (monochrome)
1787 {
1788 res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
1789 }
1790 else
1791 {
1792 HDC screenDC = GetDC(NULL);
1793 res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
1794 ReleaseDC(NULL, screenDC);
1795 }
1796 }
1797
1798 if (res)
1799 {
1800 /* Only copy the bitmap if it's a DIB section or if it's
1801 compatible to the screen */
1802 BOOL copyContents;
1803
1804 if (objSize == sizeof(DIBSECTION))
1805 {
1806 copyContents = TRUE;
1807 }
1808 else
1809 {
1810 HDC screenDC = GetDC(NULL);
1811 int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
1812 ReleaseDC(NULL, screenDC);
1813
1814 copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
1815 }
1816
1817 if (copyContents)
1818 {
1819 /* The source bitmap may already be selected in a device context,
1820 use GetDIBits/StretchDIBits and not StretchBlt */
1821
1822 HDC dc;
1823 void * bits;
1824
1826
1827 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
1828 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
1829 bi->bmiHeader.biSizeImage = 0;
1830 bi->bmiHeader.biClrUsed = 0;
1831 bi->bmiHeader.biClrImportant = 0;
1832
1833 /* Fill in biSizeImage */
1834 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
1836
1837 if (bits)
1838 {
1839 HBITMAP oldBmp;
1840
1841 /* Get the image bits of the source bitmap */
1842 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
1843
1844 /* Copy it to the destination bitmap */
1845 oldBmp = SelectObject(dc, res);
1846 StretchDIBits(dc, 0, 0, desiredx, desiredy,
1847 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
1849 SelectObject(dc, oldBmp);
1850
1852 }
1853
1854 DeleteDC(dc);
1855 }
1856
1857 if (flags & LR_COPYDELETEORG)
1858 {
1859 DeleteObject(hnd);
1860 }
1861 }
1862 HeapFree(GetProcessHeap(), 0, bi);
1863 return res;
1864}
1865
1866static
1867HICON
1869 _In_ HICON hicon,
1870 _In_ BOOL bIcon,
1871 _In_ int cxDesired,
1872 _In_ int cyDesired,
1873 _In_ UINT fuFlags
1874)
1875{
1876 HICON ret = NULL;
1877 ICONINFO ii;
1878 CURSORDATA CursorData;
1879
1880 if (fuFlags & LR_COPYFROMRESOURCE)
1881 {
1882 /* Get the icon module/resource names */
1883 UNICODE_STRING ustrModule;
1884 UNICODE_STRING ustrRsrc;
1886
1887 ustrModule.MaximumLength = 0;
1888 ustrRsrc.MaximumLength = 0;
1889
1890 /* Get the buffer size */
1891 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
1892 {
1893 return NULL;
1894 }
1895
1896 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
1897 if (!ustrModule.Buffer)
1898 {
1900 return NULL;
1901 }
1902
1903 if (ustrRsrc.MaximumLength)
1904 {
1905 ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
1906 if (!ustrRsrc.Buffer)
1907 {
1908 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1910 return NULL;
1911 }
1912 }
1913
1914 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
1915 {
1916 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1917 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
1918 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
1919 return NULL;
1920 }
1921
1922 /* NULL-terminate our strings */
1923 ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL;
1924 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
1925 ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = UNICODE_NULL;
1926
1927 TRACE("Got module %wZ, resource %p (%S).\n", &ustrModule,
1928 ustrRsrc.Buffer, IS_INTRESOURCE(ustrRsrc.Buffer) ? L"" : ustrRsrc.Buffer);
1929
1930 /* Get the module handle or load the module */
1931 hModule = LoadLibraryExW(ustrModule.Buffer, NULL, /* NT6+: LOAD_LIBRARY_AS_IMAGE_RESOURCE | */ LOAD_LIBRARY_AS_DATAFILE);
1932 if (!hModule)
1933 {
1935 ERR("Unable to load/use module '%wZ' in process %lu, error %lu.\n", &ustrModule, GetCurrentProcessId(), err);
1937 goto leave;
1938 }
1939
1940 /* Call the relevant function */
1942 hModule,
1943 ustrRsrc.Buffer,
1944 cxDesired,
1945 cyDesired,
1946 fuFlags & (LR_DEFAULTSIZE | LR_SHARED),
1947 bIcon);
1948
1950
1951 /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
1952 leave:
1953 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1954 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
1955 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
1956
1957 TRACE("Returning 0x%08x.\n", ret);
1958
1959 return ret;
1960 }
1961
1962 /* This is a regular copy */
1963 if (fuFlags & ~(LR_COPYDELETEORG | LR_SHARED))
1964 FIXME("Unimplemented flags: 0x%08x\n", fuFlags);
1965
1966 if (!GetIconInfo(hicon, &ii))
1967 {
1968 ERR("GetIconInfo failed.\n");
1969 return NULL;
1970 }
1971
1972 /* This is CreateIconIndirect with the LR_SHARED coat added */
1973 if (!CURSORICON_GetCursorDataFromIconInfo(&CursorData, &ii))
1974 goto Leave;
1975
1976 if (fuFlags & LR_SHARED)
1977 CursorData.CURSORF_flags |= CURSORF_LRSHARED;
1978
1980 if (!ret)
1981 goto Leave;
1982
1983 if (!NtUserSetCursorIconData(ret, NULL, NULL, &CursorData))
1984 {
1986 goto Leave;
1987 }
1988
1989Leave:
1991 if (ii.hbmColor) DeleteObject(ii.hbmColor);
1992
1993 if (ret && (fuFlags & LR_COPYDELETEORG))
1994 DestroyIcon(hicon);
1995
1996 return ret;
1997}
1998
2001{
2003 HANDLE Result;
2004 Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Arguments;
2005
2006 Result = CopyImage(Common->hImage,
2007 Common->uType,
2008 Common->cxDesired,
2009 Common->cyDesired,
2010 Common->fuFlags);
2011
2012 return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS);
2013}
2014
2015
2016/************* PUBLIC FUNCTIONS *******************/
2017
2018#define COPYIMAGE_VALID_FLAGS ( \
2019 LR_SHARED | LR_COPYFROMRESOURCE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | 0x800 | \
2020 LR_VGACOLOR | LR_LOADREALSIZE | LR_DEFAULTSIZE | LR_LOADTRANSPARENT | LR_LOADFROMFILE | \
2021 LR_COPYDELETEORG | LR_COPYRETURNORG | LR_COLOR | LR_MONOCHROME \
2022)
2023
2025 _In_ HANDLE hImage,
2026 _In_ UINT uType,
2027 _In_ int cxDesired,
2028 _In_ int cyDesired,
2029 _In_ UINT fuFlags
2030)
2031{
2032 TRACE("hImage=%p, uType=%u, cxDesired=%d, cyDesired=%d, fuFlags=%x\n",
2033 hImage, uType, cxDesired, cyDesired, fuFlags);
2034
2035 if (fuFlags & ~COPYIMAGE_VALID_FLAGS)
2036 {
2038 return NULL;
2039 }
2040
2041 switch(uType)
2042 {
2043 case IMAGE_BITMAP:
2044 if (!hImage)
2045 {
2047 break;
2048 }
2049 return BITMAP_CopyImage(hImage, cxDesired, cyDesired, fuFlags);
2050 case IMAGE_CURSOR:
2051 case IMAGE_ICON:
2052 {
2053 HANDLE handle;
2054 if (!hImage)
2055 {
2057 break;
2058 }
2059 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired, cyDesired, fuFlags);
2060 if (!handle && (fuFlags & LR_COPYFROMRESOURCE))
2061 {
2062 /* Test if the hImage is the same size as what we want by getting
2063 * its BITMAP and comparing its dimensions to the desired size. */
2064 BITMAP bm;
2065
2066 ICONINFO iconinfo = { 0 };
2067 if (!GetIconInfo(hImage, &iconinfo))
2068 {
2069 ERR("GetIconInfo Failed. hImage %p\n", hImage);
2070 return NULL;
2071 }
2072 if (!GetObject(iconinfo.hbmColor, sizeof(bm), &bm))
2073 {
2074 ERR("GetObject Failed. iconinfo %p\n", iconinfo);
2075 return NULL;
2076 }
2077
2078 DeleteObject(iconinfo.hbmMask);
2079 DeleteObject(iconinfo.hbmColor);
2080
2081 /* If the images are the same size remove LF_COPYFROMRESOURCE and try again */
2082 if (cxDesired == bm.bmWidth && cyDesired == bm.bmHeight)
2083 {
2084 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired,
2085 cyDesired, (fuFlags & ~LR_COPYFROMRESOURCE));
2086 }
2087 }
2088 return handle;
2089 }
2090 default:
2092 break;
2093 }
2094 return NULL;
2095}
2096
2099)
2100{
2101 return CURSORICON_CopyImage(hIcon, FALSE, 0, 0, 0);
2102}
2103
2105 _In_ HDC hDC,
2106 _In_ int X,
2107 _In_ int Y,
2109)
2110{
2111 return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
2112}
2113
2115 _In_ HDC hdc,
2116 _In_ int xLeft,
2117 _In_ int yTop,
2119 _In_ int cxWidth,
2120 _In_ int cyWidth,
2121 _In_ UINT istepIfAniCur,
2122 _In_opt_ HBRUSH hbrFlickerFreeDraw,
2123 _In_ UINT diFlags
2124)
2125{
2126 return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
2127 istepIfAniCur, hbrFlickerFreeDraw, diFlags,
2128 0, 0);
2129}
2130
2133 _Out_ PICONINFO piconinfo
2134)
2135{
2136 return NtUserGetIconInfo(hIcon, piconinfo, NULL, NULL, NULL, FALSE);
2137}
2138
2141)
2142{
2144}
2145
2148 _In_ LPCSTR lpIconName
2149)
2150{
2151 TRACE("%p, %s\n", hInstance, debugstr_a(lpIconName));
2152
2153 return LoadImageA(hInstance,
2154 lpIconName,
2155 IMAGE_ICON,
2156 0,
2157 0,
2159}
2160
2163 _In_ LPCWSTR lpIconName
2164)
2165{
2166 TRACE("%p, %s\n", hInstance, debugstr_w(lpIconName));
2167
2168 return LoadImageW(hInstance,
2169 lpIconName,
2170 IMAGE_ICON,
2171 0,
2172 0,
2174}
2175
2178 _In_ LPCSTR lpCursorName
2179)
2180{
2181 TRACE("%p, %s\n", hInstance, debugstr_a(lpCursorName));
2182
2183 return LoadImageA(hInstance,
2184 lpCursorName,
2186 0,
2187 0,
2189}
2190
2193 _In_ LPCWSTR lpCursorName
2194)
2195{
2196 TRACE("%p, %s\n", hInstance, debugstr_w(lpCursorName));
2197
2198 return LoadImageW(hInstance,
2199 lpCursorName,
2201 0,
2202 0,
2204}
2205
2208)
2209{
2210 TRACE("%s\n", debugstr_a(lpFileName));
2211
2212 return LoadImageA(NULL,
2213 lpFileName,
2215 0,
2216 0,
2218}
2219
2222)
2223{
2224 TRACE("%s\n", debugstr_w(lpFileName));
2225
2226 return LoadImageW(NULL,
2227 lpFileName,
2229 0,
2230 0,
2232}
2233
2236 _In_ LPCSTR lpBitmapName
2237)
2238{
2239 TRACE("%p, %s\n", hInstance, debugstr_a(lpBitmapName));
2240
2241 return LoadImageA(hInstance,
2242 lpBitmapName,
2244 0,
2245 0,
2246 0);
2247}
2248
2251 _In_ LPCWSTR lpBitmapName
2252)
2253{
2254 TRACE("%p, %s\n", hInstance, debugstr_w(lpBitmapName));
2255
2256 return LoadImageW(hInstance,
2257 lpBitmapName,
2259 0,
2260 0,
2261 0);
2262}
2263
2266 _In_ LPCSTR lpszName,
2267 _In_ UINT uType,
2268 _In_ int cxDesired,
2269 _In_ int cyDesired,
2270 _In_ UINT fuLoad
2271)
2272{
2273 HANDLE res;
2274 LPWSTR u_name;
2275 DWORD len;
2276
2277 if (IS_INTRESOURCE(lpszName))
2278 return LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired, cyDesired, fuLoad);
2279
2280 len = MultiByteToWideChar( CP_ACP, 0, lpszName, -1, NULL, 0 );
2281 u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2282 MultiByteToWideChar( CP_ACP, 0, lpszName, -1, u_name, len );
2283
2284 res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
2285 HeapFree(GetProcessHeap(), 0, u_name);
2286 return res;
2287}
2288
2291 _In_ LPCWSTR lpszName,
2292 _In_ UINT uType,
2293 _In_ int cxDesired,
2294 _In_ int cyDesired,
2295 _In_ UINT fuLoad
2296)
2297{
2298 TRACE("hinst 0x%p, name %s, uType 0x%08x, cxDesired %d, cyDesired %d, fuLoad 0x%08x.\n",
2299 hinst, debugstr_w(lpszName), uType, cxDesired, cyDesired, fuLoad);
2300 /* Redirect to each implementation */
2301 switch(uType)
2302 {
2303 case IMAGE_BITMAP:
2304 return BITMAP_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
2305 case IMAGE_CURSOR:
2306 case IMAGE_ICON:
2307 return CURSORICON_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad, uType == IMAGE_ICON);
2308 default:
2310 break;
2311 }
2312 return NULL;
2313}
2314
2316 _In_ PBYTE presbits,
2317 _In_ BOOL fIcon
2318)
2319{
2320 return LookupIconIdFromDirectoryEx( presbits, fIcon,
2323}
2324
2326 _In_ PBYTE presbits,
2327 _In_ BOOL fIcon,
2328 _In_ int cxDesired,
2329 _In_ int cyDesired,
2331)
2332{
2333 WORD bppDesired;
2334 CURSORICONDIR* dir = (CURSORICONDIR*)presbits;
2336 int i, numMatch = 0, iIndex = -1;
2337 WORD width, height, BitCount = 0;
2338 BOOL notPaletted = FALSE;
2339 ULONG bestScore = 0xFFFFFFFF, score;
2340
2341 TRACE("%p, %x, %i, %i, %x.\n", presbits, fIcon, cxDesired, cyDesired, Flags);
2342
2343 if(!(dir && !dir->idReserved && (dir->idType & 3)))
2344 {
2345 WARN("Invalid resource.\n");
2346 return 0;
2347 }
2348
2349 if(Flags & LR_MONOCHROME)
2350 bppDesired = 1;
2351 else
2352 {
2353 HDC icScreen;
2354 icScreen = CreateICW(DISPLAYW, NULL, NULL, NULL);
2355 if(!icScreen)
2356 return FALSE;
2357
2358 bppDesired = GetDeviceCaps(icScreen, BITSPIXEL);
2359 DeleteDC(icScreen);
2360 }
2361
2362 if(!cxDesired)
2363 cxDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR) : 256;
2364 if(!cyDesired)
2365 cyDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR) : 256;
2366
2367 /* Find the best match for the desired size */
2368 for(i = 0; i < dir->idCount; i++)
2369 {
2370 entry = &dir->idEntries[i];
2371 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2372 /* Height is twice as big in cursor resources */
2373 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2374 /* 0 represents 256 */
2375 if(!width) width = 256;
2376 if(!height) height = 256;
2377 /* Calculate the "score" (lower is better) */
2378 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2379 if( score > bestScore)
2380 continue;
2381 /* Bigger than requested lowers the score */
2382 if(width > cxDesired)
2383 score -= width - cxDesired;
2384 if(height > cyDesired)
2385 score -= height - cyDesired;
2386 if(score > bestScore)
2387 continue;
2388 if(score == bestScore)
2389 {
2390 if(entry->wBitCount > BitCount)
2391 BitCount = entry->wBitCount;
2392 numMatch++;
2393 continue;
2394 }
2395 iIndex = i;
2396 numMatch = 1;
2397 bestScore = score;
2398 BitCount = entry->wBitCount;
2399 }
2400
2401 if(numMatch == 1)
2402 {
2403 /* Only one entry fits the asked dimensions */
2404 return dir->idEntries[iIndex].wResId;
2405 }
2406
2407 /* Avoid paletted icons on non-paletted device */
2408 if (bppDesired > 8 && BitCount > 8)
2409 notPaletted = TRUE;
2410
2411 BitCount = 0;
2412 iIndex = -1;
2413 /* Now find the entry with the best depth */
2414 for(i = 0; i < dir->idCount; i++)
2415 {
2416 entry = &dir->idEntries[i];
2417 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2418 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2419 /* 0 represents 256 */
2420 if(!width) width = 256;
2421 if(!height) height = 256;
2422 /* Check if this is the best match we had */
2423 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2424 if(width > cxDesired)
2425 score -= width - cxDesired;
2426 if(height > cyDesired)
2427 score -= height - cyDesired;
2428 if(score != bestScore)
2429 continue;
2430 /* Exact match? */
2431 if(entry->wBitCount == bppDesired)
2432 return entry->wResId;
2433 /* We take the highest possible but smaller than the display depth */
2434 if((entry->wBitCount > BitCount) && (entry->wBitCount < bppDesired))
2435 {
2436 /* Avoid paletted icons on non paletted devices */
2437 if ((entry->wBitCount <= 8) && notPaletted)
2438 continue;
2439 iIndex = i;
2440 BitCount = entry->wBitCount;
2441 }
2442 }
2443
2444 if(iIndex >= 0)
2445 return dir->idEntries[iIndex].wResId;
2446
2447 /* No inferior or equal depth available. Get the smallest bigger one */
2448 BitCount = 0xFFFF;
2449 iIndex = -1;
2450 for(i = 0; i < dir->idCount; i++)
2451 {
2452 entry = &dir->idEntries[i];
2453 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2454 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2455 /* 0 represents 256 */
2456 if(!width) width = 256;
2457 if(!height) height = 256;
2458 /* Check if this is the best match we had */
2459 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2460 if(width > cxDesired)
2461 score -= width - cxDesired;
2462 if(height > cyDesired)
2463 score -= height - cyDesired;
2464 if(score != bestScore)
2465 continue;
2466 /* Check the bit depth */
2467 if(entry->wBitCount < BitCount)
2468 {
2469 if((entry->wBitCount <= 8) && notPaletted)
2470 continue;
2471 iIndex = i;
2472 BitCount = entry->wBitCount;
2473 }
2474 }
2475 if (iIndex >= 0)
2476 return dir->idEntries[iIndex].wResId;
2477
2478 return 0;
2479}
2480
2483 _In_ int nWidth,
2484 _In_ int nHeight,
2485 _In_ BYTE cPlanes,
2486 _In_ BYTE cBitsPixel,
2487 _In_ const BYTE *lpbANDbits,
2488 _In_ const BYTE *lpbXORbits
2489)
2490{
2491 ICONINFO iinfo;
2492 HICON hIcon;
2493
2494 TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
2495 nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits, lpbANDbits);
2496
2497 iinfo.fIcon = TRUE;
2498 iinfo.xHotspot = nWidth / 2;
2499 iinfo.yHotspot = nHeight / 2;
2500 if (cPlanes * cBitsPixel > 1)
2501 {
2502 iinfo.hbmColor = CreateBitmap( nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits );
2503 iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpbANDbits );
2504 }
2505 else
2506 {
2507 iinfo.hbmMask = CreateBitmap( nWidth, nHeight * 2, 1, 1, lpbANDbits );
2508 iinfo.hbmColor = NULL;
2509 }
2510
2511 hIcon = CreateIconIndirect( &iinfo );
2512
2513 DeleteObject( iinfo.hbmMask );
2514 if (iinfo.hbmColor) DeleteObject( iinfo.hbmColor );
2515
2516 return hIcon;
2517}
2518
2520 _In_ PBYTE presbits,
2521 _In_ DWORD dwResSize,
2522 _In_ BOOL fIcon,
2523 _In_ DWORD dwVer
2524)
2525{
2526 return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
2527}
2528
2530 _In_ PBYTE pbIconBits,
2531 _In_ DWORD cbIconBits,
2532 _In_ BOOL fIcon,
2534 _In_ int cxDesired,
2535 _In_ int cyDesired,
2537)
2538{
2539 CURSORDATA cursorData;
2540 HICON hIcon;
2541 BOOL isAnimated;
2542
2543 TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags);
2544
2546 {
2547 if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
2548 if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
2549 }
2550
2551 ZeroMemory(&cursorData, sizeof(cursorData));
2552 cursorData.cx = cxDesired;
2553 cursorData.cy = cyDesired;
2554 cursorData.rt = (USHORT)((ULONG_PTR)(fIcon ? RT_ICON : RT_CURSOR));
2555
2556 /* Convert to win32k-ready data */
2557 if(!memcmp(pbIconBits, "RIFF", 4))
2558 {
2559 if(!CURSORICON_GetCursorDataFromANI(&cursorData, pbIconBits, cbIconBits, uFlags))
2560 {
2561 ERR("Could not get cursor data from .ani.\n");
2562 return NULL;
2563 }
2564 isAnimated = !!(cursorData.CURSORF_flags & CURSORF_ACON);
2565 }
2566 else
2567 {
2568 /* It is possible to pass Icon Directories to this API */
2569 int wResId = LookupIconIdFromDirectoryEx(pbIconBits, fIcon, cxDesired, cyDesired, uFlags);
2570 HANDLE ResHandle = NULL;
2571#ifdef __REACTOS__
2572 if (wResId && (pbIconBits[4] != sizeof(BITMAPINFOHEADER)))
2573#else
2574 if(wResId)
2575#endif
2576 {
2578 HRSRC hrsrc;
2579 CURSORICONDIR* pCurIconDir = (CURSORICONDIR*)pbIconBits;
2580
2581 TRACE("Pointer points to a directory structure.\n");
2582
2583 /* So this is a pointer to an icon directory structure. Find the module */
2584 if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
2585 (LPCWSTR)pbIconBits,
2586 &hinst))
2587 {
2588 return NULL;
2589 }
2590
2591 /* Check we were given the right type of resource */
2592 if((fIcon && pCurIconDir->idType == 2) || (!fIcon && pCurIconDir->idType == 1))
2593 {
2594 WARN("Got a %s directory pointer, but called for a %s\n", fIcon ? "cursor" : "icon", fIcon ? "icon" : "cursor");
2595 return NULL;
2596 }
2597
2598 /* Get the relevant resource pointer */
2599 hrsrc = FindResourceW(
2600 hinst,
2601 MAKEINTRESOURCEW(wResId),
2602 fIcon ? RT_ICON : RT_CURSOR);
2603 if (!hrsrc)
2604 return NULL;
2605
2606 ResHandle = LoadResource(hinst, hrsrc);
2607 if (!ResHandle)
2608 return NULL;
2609
2610 pbIconBits = LockResource(ResHandle);
2611 if (!pbIconBits)
2612 {
2613 FreeResource(ResHandle);
2614 return NULL;
2615 }
2616 }
2617 if(!fIcon)
2618 {
2619 WORD* pt = (WORD*)pbIconBits;
2620 cursorData.xHotspot = *pt++;
2621 cursorData.yHotspot = *pt++;
2622 pbIconBits = (PBYTE)pt;
2623 }
2624
2625 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)pbIconBits))
2626 {
2627 ERR("Couldn't fill the CURSORDATA structure.\n");
2628 if (ResHandle)
2629 FreeResource(ResHandle);
2630 return NULL;
2631 }
2632 if (ResHandle)
2633 FreeResource(ResHandle);
2634 isAnimated = FALSE;
2635 }
2636
2637 if (uFlags & LR_SHARED)
2638 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
2639
2640 hIcon = NtUserxCreateEmptyCurObject(isAnimated);
2641 if (!hIcon)
2642 goto end_error;
2643
2644 if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData))
2645 {
2646 ERR("NtUserSetCursorIconData failed.\n");
2648 goto end_error;
2649 }
2650
2651 if(isAnimated)
2652 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2653
2654 return hIcon;
2655
2656 /* Clean up */
2657end_error:
2658 if(isAnimated)
2659 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2660 DeleteObject(cursorData.hbmMask);
2661 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2662 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2663
2664 return NULL;
2665}
2666
2668 _In_ PICONINFO piconinfo
2669)
2670{
2671 /* As simple as creating a handle, and let win32k deal with the bitmaps */
2672 HICON hiconRet;
2673 CURSORDATA cursorData;
2674
2675 TRACE("%p.\n", piconinfo);
2676
2677 ZeroMemory(&cursorData, sizeof(cursorData));
2678
2679 if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo))
2680 return NULL;
2681
2683 if(!hiconRet)
2684 goto end_error;
2685
2686 if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
2687 {
2688 NtUserDestroyCursor(hiconRet, FALSE);
2689 goto end_error;
2690 }
2691
2692 TRACE("Returning 0x%08x.\n", hiconRet);
2693
2694 return hiconRet;
2695
2696end_error:
2697 /* Clean up */
2698 DeleteObject(cursorData.hbmMask);
2699 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2700 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2701
2702 return NULL;
2703}
2704
2707 _In_ int xHotSpot,
2708 _In_ int yHotSpot,
2709 _In_ int nWidth,
2710 _In_ int nHeight,
2711 _In_ const VOID *pvANDPlane,
2712 _In_ const VOID *pvXORPlane
2713)
2714{
2715 ICONINFO info;
2716 HCURSOR hCursor;
2717
2718 TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
2719 nWidth, nHeight, xHotSpot, yHotSpot, pvXORPlane, pvANDPlane);
2720
2721 info.fIcon = FALSE;
2722 info.xHotspot = xHotSpot;
2723 info.yHotspot = yHotSpot;
2724 info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, pvANDPlane );
2725 info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, pvXORPlane );
2726 hCursor = CreateIconIndirect( &info );
2727 DeleteObject( info.hbmMask );
2728 DeleteObject( info.hbmColor );
2729 return hCursor;
2730}
2731
2733 _In_ HCURSOR hcur,
2734 _In_ DWORD id
2735)
2736{
2737 if (hcur == NULL)
2738 {
2740 if (hcur == NULL)
2741 {
2742 return FALSE;
2743 }
2744 }
2745 return NtUserSetSystemCursor(hcur,id);
2746}
2747
2749 _In_ int X,
2750 _In_ int Y
2751)
2752{
2753 return NtUserxSetCursorPos(X,Y);
2754}
2755
2757 _Out_ LPPOINT lpPoint
2758)
2759{
2760 return NtUserxGetCursorPos(lpPoint);
2761}
2762
2764 _In_ BOOL bShow
2765)
2766{
2767 return NtUserxShowCursor(bShow);
2768}
2769
2771{
2773}
2774
2776 _In_ HCURSOR hCursor
2777)
2778{
2779 return NtUserDestroyCursor(hCursor, FALSE);
2780}
2781
2782HCURSOR
2783WINAPI
2784GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
2785{
2786 return NtUserGetCursorFrameInfo(hCursor, istep, rate_jiffies, num_steps);
2787}
static HDC hDC
Definition: 3dtext.c:33
DWORD dwVersion
Definition: LocaleTests.cpp:63
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
unsigned int dir
Definition: maze.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define leave
Definition: btrfs_drv.h:138
HINSTANCE hInstance
Definition: charmap.c:19
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD bpp
Definition: surface.c:185
#define Y(I)
UINT uFlags
Definition: api.c:59
HMODULE hModule
Definition: animate.c:44
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define UnmapViewOfFile
Definition: compat.h:746
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define TRACE_(x)
Definition: compat.h:76
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define FreeLibrary(x)
Definition: compat.h:748
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define MapViewOfFile
Definition: compat.h:745
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const BYTE png_sig_pattern[]
Definition: image.c:4818
PSERVERINFO gpsi
Definition: imm.c:18
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define pt(x, y)
Definition: drawing.c:79
#define BI_RGB
Definition: precomp.h:56
#define GetBValue(quad)
Definition: precomp.h:75
#define GetGValue(quad)
Definition: precomp.h:74
ULONG RGBQUAD
Definition: precomp.h:59
#define GetRValue(quad)
Definition: precomp.h:73
r reserved
Definition: btrfs.c:3006
HINSTANCE hInst
Definition: dxdiag.c:13
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint color
Definition: glext.h:6243
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLbitfield flags
Definition: glext.h:7161
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FxContextHeader * pHeader
Definition: handleapi.cpp:604
#define ds
Definition: i386-dis.c:443
const char cursor[]
Definition: icontest.c:13
#define CURSORF_LRSHARED
Definition: ntuser.h:1201
@ THREADSTATE_GETCURSOR
Definition: ntuser.h:2478
#define CURSORF_FROMRESOURCE
Definition: ntuser.h:1199
DWORD_PTR NTAPI NtUserGetThreadState(DWORD Routine)
Definition: misc.c:240
#define CURSORF_ACONFRAME
Definition: ntuser.h:1204
#define CURSORF_ACON
Definition: ntuser.h:1202
#define bits
Definition: infblock.c:15
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define LDR_IS_RESOURCE(handle)
Definition: ldrtypes.h:105
HANDLE hbmpOld
Definition: magnifier.c:54
static const WCHAR dc[]
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BI_BITFIELDS
Definition: mmreg.h:507
#define FILE_FLAG_RANDOM_ACCESS
Definition: disk.h:44
static PVOID ptr
Definition: dispmode.c:27
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HINSTANCE hinst
Definition: edit.c:551
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static const BYTE masks[8]
Definition: dib.c:2760
static PROTOCOLDATA * pdata
Definition: protocol.c:158
static HBITMAP create_bitmap(void)
Definition: clipboard.c:534
#define ANI_FLAG_SEQUENCE
Definition: cursoricon.c:70
#define ANI_fram_ID
Definition: cursoricon.c:65
#define ANI_RIFF_ID
Definition: cursoricon.c:60
#define ANI_LIST_ID
Definition: cursoricon.c:61
#define ANI_ACON_ID
Definition: cursoricon.c:62
#define ANI_FLAG_ICON
Definition: cursoricon.c:69
#define ANI_anih_ID
Definition: cursoricon.c:63
static DWORD DWORD istep
Definition: cursoricon.c:1638
#define ANI_seq__ID
Definition: cursoricon.c:64
#define ANI_rate_ID
Definition: cursoricon.c:67
DWORD dwFileSize
Definition: more.c:40
HICON hIcon
Definition: msconfig.c:44
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI NTSTATUS NTAPI ZwCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS Status)
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
#define L(x)
Definition: ntvdm.h:50
EXTINLINE BOOL NtUserxSetCursorPos(INT x, INT y)
Definition: ntwrapper.h:676
EXTINLINE BOOL NtUserxGetCursorPos(POINT *lpPoint)
Definition: ntwrapper.h:811
EXTINLINE HICON NtUserxCreateEmptyCurObject(DWORD_PTR Param)
Definition: ntwrapper.h:616
EXTINLINE INT NtUserxShowCursor(BOOL bShow)
Definition: ntwrapper.h:606
#define RT_BITMAP
Definition: pedump.c:364
BYTE * PBYTE
Definition: pedump.c:66
#define RT_ICON
Definition: pedump.c:365
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define RT_GROUP_CURSOR
Definition: pedump.c:374
unsigned short USHORT
Definition: pedump.c:61
#define RT_GROUP_ICON
Definition: pedump.c:375
#define RT_CURSOR
Definition: pedump.c:363
#define err(...)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
union CURSORICONDIRENTRY::@5124 ResInfo
ICONRESDIR icon
Definition: ntusrtyp.h:88
DWORD dwBytesInRes
Definition: ntusrtyp.h:93
CURSORRESDIR cursor
Definition: ntusrtyp.h:89
WORD idReserved
Definition: ntusrtyp.h:99
CURSORICONDIRENTRY idEntries[1]
Definition: ntusrtyp.h:102
WORD idCount
Definition: ntusrtyp.h:101
WORD wWidth
Definition: ntusrtyp.h:69
WORD wHeight
Definition: ntusrtyp.h:70
BYTE bReserved
Definition: ntusrtyp.h:64
BYTE bColorCount
Definition: ntusrtyp.h:63
BYTE bHeight
Definition: ntusrtyp.h:62
BYTE bWidth
Definition: ntusrtyp.h:61
Definition: bl.h:1331
DWORD yHotspot
Definition: winuser.h:3128
BOOL fIcon
Definition: winuser.h:3126
DWORD xHotspot
Definition: winuser.h:3127
HBITMAP hbmColor
Definition: winuser.h:3130
HBITMAP hbmMask
Definition: winuser.h:3129
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: name.c:39
const unsigned char * data
Definition: cursoricon.c:874
DWORD data_size
Definition: cursoricon.c:873
ULONG biClrImportant
Definition: precomp.h:52
USHORT biBitCount
Definition: precomp.h:46
ULONG biCompression
Definition: precomp.h:47
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
RGBQUAD bmiColors[1]
Definition: wingdi.h:1477
HBITMAP hbmMask
Definition: ntuser.h:1182
ULONG CURSORF_flags
Definition: ntuser.h:1179
ULONG cy
Definition: ntuser.h:1189
ULONG cx
Definition: ntuser.h:1188
HBITMAP hbmColor
Definition: ntuser.h:1183
HBITMAP hbmAlpha
Definition: ntuser.h:1184
SHORT xHotspot
Definition: ntuser.h:1180
USHORT rt
Definition: ntuser.h:1177
struct tagCURSORDATA * aspcur
Definition: ntuser.h:1192
SHORT yHotspot
Definition: ntuser.h:1181
UCHAR rgbReserved
Definition: bootanim.c:106
UCHAR rgbBlue
Definition: bootanim.c:103
UCHAR rgbRed
Definition: bootanim.c:105
UCHAR rgbGreen
Definition: bootanim.c:104
BYTE rgbtBlue
Definition: wingdi.h:1438
#define max(a, b)
Definition: svc.c:63
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
HINSTANCE User32Instance
Definition: dllmain.c:27
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:641
int ret
HDC hdcMem
Definition: welcome.c:104
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
struct _COPYIMAGE_CALLBACK_ARGUMENTS * PCOPYIMAGE_CALLBACK_ARGUMENTS
BOOL APIENTRY NtUserDrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags, BOOL bMetaHDC, PVOID pDIXData)
Definition: cursoricon.c:2084
BOOL APIENTRY NtUserGetIconSize(HANDLE hCurIcon, UINT istepIfAniCur, PLONG plcx, PLONG plcy)
Definition: cursoricon.c:590
HICON NTAPI NtUserFindExistingCursorIcon(_In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING pustrRsrc, _In_ FINDEXISTINGCURICONPARAM *param)
Definition: cursoricon.c:861
BOOL APIENTRY NtUserDestroyCursor(_In_ HANDLE hCurIcon, _In_ BOOL bForce)
Definition: cursoricon.c:793
__kernel_entry BOOL APIENTRY NtUserSetCursorIconData(_In_ HCURSOR hcursor, _In_opt_ PUNICODE_STRING pustrModule, _In_opt_ PUNICODE_STRING pustrRsrc, _In_ const CURSORDATA *pCursorData)
Definition: cursoricon.c:1510
BOOL APIENTRY NtUserSetSystemCursor(HCURSOR hcur, DWORD id)
Definition: cursoricon.c:2201
HCURSOR NTAPI NtUserGetCursorFrameInfo(HCURSOR hCursor, DWORD istep, INT *rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:2131
static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse)
Definition: cursoricon.c:157
HCURSOR WINAPI CreateCursor(_In_opt_ HINSTANCE hInst, _In_ int xHotSpot, _In_ int yHotSpot, _In_ int nWidth, _In_ int nHeight, _In_ const VOID *pvANDPlane, _In_ const VOID *pvXORPlane)
Definition: cursoricon.c:2705
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpBitmapName)
Definition: cursoricon.c:2249
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ UINT uType, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad)
Definition: cursoricon.c:2289
#define EOFM
HCURSOR WINAPI LoadCursorFromFileW(_In_ LPCWSTR lpFileName)
Definition: cursoricon.c:2220
static BOOL CURSORICON_GetCursorDataFromIconInfo(_Out_ CURSORDATA *pCursorData, _In_ ICONINFO *pIconInfo)
Definition: cursoricon.c:762
BOOL WINAPI GetCursorPos(_Out_ LPPOINT lpPoint)
Definition: cursoricon.c:2756
static BOOL CURSORICON_GetCursorDataFromBMI(_Inout_ CURSORDATA *pdata, _In_ const BITMAPINFO *pbmi)
Definition: cursoricon.c:612
#define LF
static void * map_fileW(LPCWSTR name, LPDWORD filesize)
Definition: cursoricon.c:89
BOOL WINAPI SetSystemCursor(_In_ HCURSOR hcur, _In_ DWORD id)
Definition: cursoricon.c:2732
BOOL get_icon_size(HICON hIcon, SIZE *size)
Definition: cursoricon.c:74
static void riff_find_chunk(DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk)
Definition: cursoricon.c:892
HCURSOR WINAPI LoadCursorFromFileA(_In_ LPCSTR lpFileName)
Definition: cursoricon.c:2206
HCURSOR CursorIconToCursor(HICON hIcon, BOOL SemiTransparent)
Definition: cursoricon.c:79
NTSTATUS WINAPI User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:48
DWORD get_best_icon_file_offset(_In_ const LPBYTE dir, _In_ DWORD dwFileSize, _In_ int cxDesired, _In_ int cyDesired, _In_ BOOL bIcon, _In_ DWORD fuLoad, _Out_ POINT *ptHotSpot)
Definition: cursoricon.c:582
static int get_dib_image_size(int width, int height, int depth)
Definition: cursoricon.c:111
int WINAPI LookupIconIdFromDirectory(_In_ PBYTE presbits, _In_ BOOL fIcon)
Definition: cursoricon.c:2315
#define COPYIMAGE_VALID_FLAGS
Definition: cursoricon.c:2018
static BOOL bmi_has_alpha(const BITMAPINFO *info, const void *bits)
Definition: cursoricon.c:283
HICON WINAPI CreateIconFromResourceEx(_In_ PBYTE pbIconBits, _In_ DWORD cbIconBits, _In_ BOOL fIcon, _In_ DWORD dwVersion, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT uFlags)
Definition: cursoricon.c:2529
static BOOL CURSORICON_GetCursorDataFromANI(_Inout_ CURSORDATA *pCurData, _In_ const BYTE *pData, _In_ DWORD dwDataSize, _In_ DWORD fuLoad)
Definition: cursoricon.c:919
BOOL WINAPI SetCursorPos(_In_ int X, _In_ int Y)
Definition: cursoricon.c:2748
#define CR
static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
Definition: cursoricon.c:236
static HANDLE CURSORICON_LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad, _In_ BOOL bIcon)
Definition: cursoricon.c:1457
static HBITMAP BITMAP_LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad)
Definition: cursoricon.c:1096
static HBITMAP create_alpha_bitmap(_In_opt_ HBITMAP color, _In_opt_ BITMAPINFO *src_info, _In_opt_ const void *color_bits, _In_ LONG width, _In_ LONG height)
Definition: cursoricon.c:302
static BOOL is_dib_monochrome(const BITMAPINFO *info)
Definition: cursoricon.c:116
const CURSORICONFILEDIRENTRY * get_best_icon_file_entry(_In_ const CURSORICONFILEDIR *dir, _In_ DWORD dwFileSize, _In_ int cxDesired, _In_ int cyDesired, _In_ BOOL bIcon, _In_ DWORD fuLoad)
Definition: cursoricon.c:496
static HBITMAP BITMAP_CopyImage(_In_ HBITMAP hnd, _In_ int desiredx, _In_ int desiredy, _In_ UINT flags)
Definition: cursoricon.c:1678
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpCursorName)
Definition: cursoricon.c:2191
static HANDLE CURSORICON_LoadFromFileW(_In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad, _In_ BOOL bIcon)
Definition: cursoricon.c:1378
#define HighBitDetect
HCURSOR WINAPI GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:2784
static int DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, LONG *width, LONG *height, WORD *bpp, DWORD *compr)
Definition: cursoricon.c:194
HBITMAP WINAPI LoadBitmapA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpBitmapName)
Definition: cursoricon.c:2234
int WINAPI LookupIconIdFromDirectoryEx(_In_ PBYTE presbits, _In_ BOOL fIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT Flags)
Definition: cursoricon.c:2325
NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:2000
VOID LoadSystemCursors(VOID)
Definition: cursoricon.c:21
static void dump_ani_header(const ani_header *header)
Definition: cursoricon.c:878
static const WCHAR DISPLAYW[]
Definition: cursoricon.c:87
HICON WINAPI CopyIcon(_In_ HICON hIcon)
Definition: cursoricon.c:2097
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2161
static HICON CURSORICON_CopyImage(_In_ HICON hicon, _In_ BOOL bIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuFlags)
Definition: cursoricon.c:1868
#define ZeroMemory
Definition: winbase.h:1737
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpFileName
Definition: winbase.h:3096
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:368
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define CopyMemory
Definition: winbase.h:1735
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3521
int * PINT
Definition: windef.h:177
DWORD COLORREF
Definition: windef.h:300
HICON HCURSOR
Definition: windef.h:299
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_CURSOR_HANDLE
Definition: winerror.h:883
#define DIB_RGB_COLORS
Definition: wingdi.h:367
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
struct tagBITMAPFILEHEADER BITMAPFILEHEADER
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define DI_COMPAT
Definition: wingdi.h:68
int WINAPI GetDIBits(_In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT start, _In_ UINT cLines, _Out_opt_ LPVOID lpvBits, _At_((LPBITMAPINFOHEADER) lpbmi, _Inout_) LPBITMAPINFO lpbmi, _In_ UINT usage)
HDC WINAPI CreateICW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_opt_ const DEVMODEW *)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define DI_NORMAL
Definition: wingdi.h:72
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
#define SRCCOPY
Definition: wingdi.h:333
HCURSOR WINAPI GetCursor(void)
Definition: cursoricon.c:2770
#define PLANES
Definition: wingdi.h:721
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define BITSPIXEL
Definition: wingdi.h:720
#define CBM_INIT
Definition: wingdi.h:365
#define GetObject
Definition: wingdi.h:4468
BOOL WINAPI DeleteDC(_In_ HDC)
HBITMAP WINAPI CreateDIBitmap(_In_ HDC hdc, _In_opt_ const BITMAPINFOHEADER *pbmih, _In_ DWORD fdwInit, _In_opt_ const VOID *pvInit, _In_opt_ const BITMAPINFO *pbmi, _In_ UINT uUsage)
#define DI_DEFAULTSIZE
Definition: wingdi.h:69
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HICON WINAPI CreateIconFromResource(_In_reads_bytes_(dwResSize) PBYTE presbits, _In_ DWORD dwResSize, _In_ BOOL fIcon, _In_ DWORD dwVer)
DWORD WINAPI GetSysColor(_In_ int)
#define IMAGE_BITMAP
Definition: winuser.h:211
#define LR_LOADTRANSPARENT
Definition: winuser.h:1096
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2667
BOOL WINAPI DestroyCursor(_In_ HCURSOR)
Definition: cursoricon.c:2775
#define COLOR_WINDOW
Definition: winuser.h:921
#define LR_LOADFROMFILE
Definition: winuser.h:1095
#define IMAGE_ICON
Definition: winuser.h:212
HICON WINAPI CreateIcon(_In_opt_ HINSTANCE, _In_ int, _In_ int, _In_ BYTE, _In_ BYTE, _In_ const BYTE *, _In_ const BYTE *)
Definition: cursoricon.c:2481
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2131
#define IDC_SIZENESW
Definition: winuser.h:693
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define LR_COPYFROMRESOURCE
Definition: winuser.h:1102
#define LR_CREATEDIBSECTION
Definition: winuser.h:1101
BOOL WINAPI DrawIcon(_In_ HDC, _In_ int, _In_ int, _In_ HICON)
Definition: cursoricon.c:2104
#define IDC_NO
Definition: winuser.h:697
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define IDC_ARROW
Definition: winuser.h:687
#define LR_MONOCHROME
Definition: winuser.h:1091
int WINAPI ShowCursor(_In_ BOOL)
Definition: cursoricon.c:2763
#define IDC_SIZENWSE
Definition: winuser.h:692
#define COLOR_3DSHADOW
Definition: winuser.h:934
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define IDC_SIZEALL
Definition: winuser.h:696
#define LR_COPYRETURNORG
Definition: winuser.h:1093
#define IDC_UPARROW
Definition: winuser.h:691
HANDLE WINAPI CopyImage(_In_ HANDLE, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2024
#define IDC_SIZENS
Definition: winuser.h:695
#define IDC_CROSS
Definition: winuser.h:690
#define SM_CYICON
Definition: winuser.h:976
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2146
#define IDC_HELP
Definition: winuser.h:700
#define IDC_APPSTARTING
Definition: winuser.h:699
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:2114
#define IDC_IBEAM
Definition: winuser.h:688
#define LR_COPYDELETEORG
Definition: winuser.h:1094
HDC WINAPI GetDC(_In_opt_ HWND)
#define LR_SHARED
Definition: winuser.h:1103
#define IMAGE_CURSOR
Definition: winuser.h:213
#define IDC_ICON
Definition: winuser.h:701
HANDLE WINAPI LoadImageA(_In_opt_ HINSTANCE hInst, _In_ LPCSTR name, _In_ UINT type, _In_ int cx, _In_ int cy, _In_ UINT fuLoad)
Definition: cursoricon.c:2264
#define IDC_WAIT
Definition: winuser.h:689
#define IDC_HAND
Definition: winuser.h:698
#define LR_DEFAULTSIZE
Definition: winuser.h:1097
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define SM_CYCURSOR
Definition: winuser.h:978
#define IDC_SIZE
Definition: winuser.h:702
#define LR_LOADMAP3DCOLORS
Definition: winuser.h:1100
#define SM_CXICON
Definition: winuser.h:975
#define IDC_SIZEWE
Definition: winuser.h:694
int WINAPI GetSystemMetrics(_In_ int)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2176
#define COLOR_3DLIGHT
Definition: winuser.h:943
#define SM_CXCURSOR
Definition: winuser.h:977
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2139
#define COLOR_3DFACE
Definition: winuser.h:932
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193