2 * Cursor and icon support
4 * Copyright 1995 Alexandre Julliard
5 * 1996 Martin Von Loewis
12 * http://www.microsoft.com/win32dev/ui/icons.htm
14 * Cursors and icons are stored in a global heap block, with the
17 * CURSORICONINFO info;
21 * The bits structures are in the format of a device-dependent bitmap.
23 * This layout is very sub-optimal, as the bitmap bits are stored in
24 * the X client instead of in the server like other bitmaps; however,
25 * some programs (notably Paint Brush) expect to be able to manipulate
26 * the bits directly :-(
37 #include "cursoricon.h"
38 #include "sysmetrics.h"
45 extern UINT16
COLOR_GetSystemPaletteSize();
46 extern HGLOBAL16
USER_CallDefaultRsrcHandler( HGLOBAL16
, HMODULE16
, HRSRC16
);
48 Cursor CURSORICON_XCursor
= None
; /* Current X cursor */
49 static HCURSOR32 hActiveCursor
= 0; /* Active cursor */
50 static INT32 CURSOR_ShowCount
= 0; /* Cursor display count */
51 static RECT32 CURSOR_ClipRect
; /* Cursor clipping rect */
53 /**********************************************************************
54 * CURSORICON_FindBestIcon
56 * Find the icon closest to the requested size and number of colors.
58 static ICONDIRENTRY
*CURSORICON_FindBestIcon( CURSORICONDIR
*dir
, int width
,
59 int height
, int colors
)
61 int i
, maxcolors
, maxwidth
, maxheight
;
62 ICONDIRENTRY
*entry
, *bestEntry
= NULL
;
66 fprintf( stderr
, "Icon: empty directory!\n" );
69 if (dir
->idCount
== 1) return &dir
->idEntries
[0].icon
; /* No choice... */
71 /* First find the exact size with less colors */
74 for (i
= 0, entry
= &dir
->idEntries
[0].icon
; i
< dir
->idCount
; i
++,entry
++)
75 if ((entry
->bWidth
== width
) && (entry
->bHeight
== height
) &&
76 (entry
->bColorCount
<= colors
) && (entry
->bColorCount
> maxcolors
))
79 maxcolors
= entry
->bColorCount
;
81 if (bestEntry
) return bestEntry
;
83 /* First find the exact size with more colors */
86 for (i
= 0, entry
= &dir
->idEntries
[0].icon
; i
< dir
->idCount
; i
++,entry
++)
87 if ((entry
->bWidth
== width
) && (entry
->bHeight
== height
) &&
88 (entry
->bColorCount
> colors
) && (entry
->bColorCount
<= maxcolors
))
91 maxcolors
= entry
->bColorCount
;
93 if (bestEntry
) return bestEntry
;
95 /* Now find a smaller one with less colors */
97 maxcolors
= maxwidth
= maxheight
= 0;
98 for (i
= 0, entry
= &dir
->idEntries
[0].icon
; i
< dir
->idCount
; i
++,entry
++)
99 if ((entry
->bWidth
<= width
) && (entry
->bHeight
<= height
) &&
100 (entry
->bWidth
>= maxwidth
) && (entry
->bHeight
>= maxheight
) &&
101 (entry
->bColorCount
<= colors
) && (entry
->bColorCount
> maxcolors
))
104 maxwidth
= entry
->bWidth
;
105 maxheight
= entry
->bHeight
;
106 maxcolors
= entry
->bColorCount
;
108 if (bestEntry
) return bestEntry
;
110 /* Now find a smaller one with more colors */
113 maxwidth
= maxheight
= 0;
114 for (i
= 0, entry
= &dir
->idEntries
[0].icon
; i
< dir
->idCount
; i
++,entry
++)
115 if ((entry
->bWidth
<= width
) && (entry
->bHeight
<= height
) &&
116 (entry
->bWidth
>= maxwidth
) && (entry
->bHeight
>= maxheight
) &&
117 (entry
->bColorCount
> colors
) && (entry
->bColorCount
<= maxcolors
))
120 maxwidth
= entry
->bWidth
;
121 maxheight
= entry
->bHeight
;
122 maxcolors
= entry
->bColorCount
;
124 if (bestEntry
) return bestEntry
;
126 /* Now find a larger one with less colors */
129 maxwidth
= maxheight
= 255;
130 for (i
= 0, entry
= &dir
->idEntries
[0].icon
; i
< dir
->idCount
; i
++,entry
++)
131 if ((entry
->bWidth
<= maxwidth
) && (entry
->bHeight
<= maxheight
) &&
132 (entry
->bColorCount
<= colors
) && (entry
->bColorCount
> maxcolors
))
135 maxwidth
= entry
->bWidth
;
136 maxheight
= entry
->bHeight
;
137 maxcolors
= entry
->bColorCount
;
139 if (bestEntry
) return bestEntry
;
141 /* Now find a larger one with more colors */
143 maxcolors
= maxwidth
= maxheight
= 255;
144 for (i
= 0, entry
= &dir
->idEntries
[0].icon
; i
< dir
->idCount
; i
++,entry
++)
145 if ((entry
->bWidth
<= maxwidth
) && (entry
->bHeight
<= maxheight
) &&
146 (entry
->bColorCount
> colors
) && (entry
->bColorCount
<= maxcolors
))
149 maxwidth
= entry
->bWidth
;
150 maxheight
= entry
->bHeight
;
151 maxcolors
= entry
->bColorCount
;
158 /**********************************************************************
159 * CURSORICON_FindBestCursor
161 * Find the cursor closest to the requested size.
163 static CURSORDIRENTRY
*CURSORICON_FindBestCursor( CURSORICONDIR
*dir
,
164 int width
, int height
)
166 int i
, maxwidth
, maxheight
;
167 CURSORDIRENTRY
*entry
, *bestEntry
= NULL
;
169 if (dir
->idCount
< 1)
171 fprintf( stderr
, "Cursor: empty directory!\n" );
174 if (dir
->idCount
== 1) return &dir
->idEntries
[0].cursor
; /* No choice... */
176 /* First find the largest one smaller than or equal to the requested size*/
178 maxwidth
= maxheight
= 0;
179 for(i
= 0,entry
= &dir
->idEntries
[0].cursor
; i
< dir
->idCount
; i
++,entry
++)
180 if ((entry
->wWidth
<= width
) && (entry
->wHeight
<= height
) &&
181 (entry
->wWidth
> maxwidth
) && (entry
->wHeight
> maxheight
))
184 maxwidth
= entry
->wWidth
;
185 maxheight
= entry
->wHeight
;
187 if (bestEntry
) return bestEntry
;
189 /* Now find the smallest one larger than the requested size */
191 maxwidth
= maxheight
= 255;
192 for(i
= 0,entry
= &dir
->idEntries
[0].cursor
; i
< dir
->idCount
; i
++,entry
++)
193 if ((entry
->wWidth
< maxwidth
) && (entry
->wHeight
< maxheight
))
196 maxwidth
= entry
->wWidth
;
197 maxheight
= entry
->wHeight
;
204 /**********************************************************************
205 * CURSORICON_LoadDirEntry16
207 * Load the icon/cursor directory for a given resource name and find the
208 * best matching entry.
210 static BOOL32
CURSORICON_LoadDirEntry16( HINSTANCE32 hInstance
, SEGPTR name
,
211 INT32 width
, INT32 height
, INT32 colors
,
212 BOOL32 fCursor
, CURSORICONDIRENTRY
*dirEntry
)
217 CURSORICONDIRENTRY
*entry
= NULL
;
219 if (!(hRsrc
= FindResource16( hInstance
, name
,
220 fCursor
? RT_GROUP_CURSOR
: RT_GROUP_ICON
)))
222 if (!(hMem
= LoadResource16( hInstance
, hRsrc
))) return FALSE
;
223 if ((dir
= (CURSORICONDIR
*)LockResource16( hMem
)))
226 entry
= (CURSORICONDIRENTRY
*)CURSORICON_FindBestCursor( dir
,
229 entry
= (CURSORICONDIRENTRY
*)CURSORICON_FindBestIcon( dir
,
230 width
, height
, colors
);
231 if (entry
) *dirEntry
= *entry
;
233 FreeResource16( hMem
);
234 return (entry
!= NULL
);
238 /**********************************************************************
239 * CURSORICON_LoadDirEntry32
241 * Load the icon/cursor directory for a given resource name and find the
242 * best matching entry.
244 static BOOL32
CURSORICON_LoadDirEntry32( HINSTANCE32 hInstance
, LPCWSTR name
,
245 INT32 width
, INT32 height
, INT32 colors
,
246 BOOL32 fCursor
, CURSORICONDIRENTRY
*dirEntry
)
251 CURSORICONDIRENTRY
*entry
= NULL
;
253 if (!(hRsrc
= FindResource32W( hInstance
, name
,
254 (LPCWSTR
)(fCursor
? RT_GROUP_CURSOR
: RT_GROUP_ICON
) )))
256 if (!(hMem
= LoadResource32( hInstance
, hRsrc
))) return FALSE
;
257 if ((dir
= (CURSORICONDIR
*)LockResource32( hMem
)))
260 entry
= (CURSORICONDIRENTRY
*)CURSORICON_FindBestCursor( dir
,
263 entry
= (CURSORICONDIRENTRY
*)CURSORICON_FindBestIcon( dir
,
264 width
, height
, colors
);
265 if (entry
) *dirEntry
= *entry
;
267 FreeResource32( hMem
);
268 return (entry
!= NULL
);
272 /**********************************************************************
273 * CURSORICON_CreateFromResource
275 * Create a cursor or icon from in-memory resource template.
277 * FIXME: Adjust icon size when width and height are nonzero (stretchblt).
278 * Convert to mono when cFlag is LR_MONOCHROME. Do something
279 * with cbSize parameter as well.
281 static HGLOBAL16
CURSORICON_CreateFromResource( HINSTANCE32 hInstance
, HGLOBAL16 hObj
, LPBYTE bits
,
282 UINT32 cbSize
, BOOL32 bIcon
, DWORD dwVersion
,
283 INT32 width
, INT32 height
, UINT32 cFlag
)
285 int sizeAnd
, sizeXor
;
286 HBITMAP32 hAndBits
= 0, hXorBits
= 0; /* error condition for later */
287 BITMAPOBJ
*bmpXor
, *bmpAnd
;
288 POINT16 hotspot
= { 0 ,0 };
292 dprintf_cursor(stddeb
,"CreateFromResource: %08x (%u bytes), ver %08x, %ix%i %s %s\n",
293 (unsigned)bits
, cbSize
, (unsigned)dwVersion
, width
, height
,
294 bIcon
? "icon" : "cursor", cFlag
? "mono" : "" );
295 if (dwVersion
== 0x00020000)
297 fprintf(stdnimp
,"\t2.xx resources are not supported\n");
302 bmi
= (BITMAPINFO
*)bits
;
303 else /* get the hotspot */
305 POINT16
*pt
= (POINT16
*)bits
;
307 bmi
= (BITMAPINFO
*)(pt
+ 1);
310 /* Check bitmap header */
312 if ( (bmi
->bmiHeader
.biSize
!= sizeof(BITMAPCOREHEADER
)) &&
313 (bmi
->bmiHeader
.biSize
!= sizeof(BITMAPINFOHEADER
) ||
314 bmi
->bmiHeader
.biCompression
!= BI_RGB
) )
316 fprintf(stderr
,"\tinvalid resource bitmap header.\n");
320 if( (hdc
= GetDC32( 0 )) )
323 INT32 size
= DIB_BitmapInfoSize( bmi
, DIB_RGB_COLORS
);
325 /* Make sure we have room for the monochrome bitmap later on.
326 * Note that BITMAPINFOINFO and BITMAPCOREHEADER are the same
327 * up to and including the biBitCount. In-memory icon resource
328 * format is as follows:
330 * BITMAPINFOHEADER icHeader // DIB header
331 * RGBQUAD icColors[] // Color table
332 * BYTE icXOR[] // DIB bits for XOR mask
333 * BYTE icAND[] // DIB bits for AND mask
336 if( (pInfo
= (BITMAPINFO
*)HeapAlloc( GetProcessHeap(), 0,
337 MAX(size
, sizeof(BITMAPINFOHEADER
) + 2*sizeof(RGBQUAD
)))) )
339 memcpy( pInfo
, bmi
, size
);
340 pInfo
->bmiHeader
.biHeight
/= 2;
342 /* Create the XOR bitmap */
344 hXorBits
= CreateDIBitmap32( hdc
, &pInfo
->bmiHeader
, CBM_INIT
,
345 (char*)bmi
+ size
, pInfo
, DIB_RGB_COLORS
);
348 char* bits
= (char *)bmi
+ size
+ bmi
->bmiHeader
.biHeight
*
349 DIB_GetDIBWidthBytes(bmi
->bmiHeader
.biWidth
,
350 bmi
->bmiHeader
.biBitCount
) / 2;
352 pInfo
->bmiHeader
.biBitCount
= 1;
353 if (pInfo
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))
355 RGBQUAD
*rgb
= pInfo
->bmiColors
;
357 pInfo
->bmiHeader
.biClrUsed
= pInfo
->bmiHeader
.biClrImportant
= 2;
358 rgb
[0].rgbBlue
= rgb
[0].rgbGreen
= rgb
[0].rgbRed
= 0x00;
359 rgb
[1].rgbBlue
= rgb
[1].rgbGreen
= rgb
[1].rgbRed
= 0xff;
360 rgb
[0].rgbReserved
= rgb
[1].rgbReserved
= 0;
364 RGBTRIPLE
*rgb
= (RGBTRIPLE
*)(((BITMAPCOREHEADER
*)pInfo
) + 1);
366 rgb
[0].rgbtBlue
= rgb
[0].rgbtGreen
= rgb
[0].rgbtRed
= 0x00;
367 rgb
[1].rgbtBlue
= rgb
[1].rgbtGreen
= rgb
[1].rgbtRed
= 0xff;
370 /* Create the AND bitmap */
372 hAndBits
= CreateDIBitmap32( hdc
, &pInfo
->bmiHeader
, CBM_INIT
,
373 bits
, pInfo
, DIB_RGB_COLORS
);
374 if( !hAndBits
) DeleteObject32( hXorBits
);
376 HeapFree( GetProcessHeap(), 0, pInfo
);
378 ReleaseDC32( 0, hdc
);
381 if( !hXorBits
|| !hAndBits
)
383 fprintf(stderr
,"\tunable to create an icon bitmap.\n");
387 /* Now create the CURSORICONINFO structure */
389 bmpXor
= (BITMAPOBJ
*) GDI_GetObjPtr( hXorBits
, BITMAP_MAGIC
);
390 bmpAnd
= (BITMAPOBJ
*) GDI_GetObjPtr( hAndBits
, BITMAP_MAGIC
);
391 sizeXor
= bmpXor
->bitmap
.bmHeight
* bmpXor
->bitmap
.bmWidthBytes
;
392 sizeAnd
= bmpAnd
->bitmap
.bmHeight
* bmpAnd
->bitmap
.bmWidthBytes
;
394 if (hObj
) hObj
= GlobalReAlloc16( hObj
,
395 sizeof(CURSORICONINFO
) + sizeXor
+ sizeAnd
, GMEM_MOVEABLE
);
396 if (!hObj
) hObj
= GlobalAlloc16( GMEM_MOVEABLE
,
397 sizeof(CURSORICONINFO
) + sizeXor
+ sizeAnd
);
400 CURSORICONINFO
*info
;
402 /* Make it owned by the module */
403 if (hInstance
) FarSetOwner( hObj
, MODULE_HANDLEtoHMODULE16(hInstance
));
405 info
= (CURSORICONINFO
*)GlobalLock16( hObj
);
406 info
->ptHotSpot
.x
= hotspot
.x
;
407 info
->ptHotSpot
.y
= hotspot
.y
;
408 info
->nWidth
= bmpXor
->bitmap
.bmWidth
;
409 info
->nHeight
= bmpXor
->bitmap
.bmHeight
;
410 info
->nWidthBytes
= bmpXor
->bitmap
.bmWidthBytes
;
411 info
->bPlanes
= bmpXor
->bitmap
.bmPlanes
;
412 info
->bBitsPerPixel
= bmpXor
->bitmap
.bmBitsPixel
;
414 /* Transfer the bitmap bits to the CURSORICONINFO structure */
416 GetBitmapBits32( hAndBits
, sizeAnd
, (char *)(info
+ 1) );
417 GetBitmapBits32( hXorBits
, sizeXor
, (char *)(info
+ 1) + sizeAnd
);
418 GlobalUnlock16( hObj
);
421 DeleteObject32( hXorBits
);
422 DeleteObject32( hAndBits
);
427 /**********************************************************************
428 * CreateIconFromResourceEx16 (USER.450)
430 * FIXME: not sure about exact parameter types
432 HICON16 WINAPI
CreateIconFromResourceEx16( LPBYTE bits
, UINT16 cbSize
, BOOL16 bIcon
,
433 DWORD dwVersion
, INT16 width
, INT16 height
, UINT16 cFlag
)
435 TDB
* pTask
= (TDB
*)GlobalLock16( GetCurrentTask() );
437 return CURSORICON_CreateFromResource( pTask
->hInstance
, 0, bits
, cbSize
, bIcon
, dwVersion
,
438 width
, height
, cFlag
);
443 /**********************************************************************
444 * CreateIconFromResourceEx32 (USER32.76)
446 HICON32 WINAPI
CreateIconFromResourceEx32( LPBYTE bits
, UINT32 cbSize
,
447 BOOL32 bIcon
, DWORD dwVersion
,
448 INT32 width
, INT32 height
,
451 return CreateIconFromResourceEx16( bits
, cbSize
, bIcon
, dwVersion
, width
, height
, cFlag
);
455 /**********************************************************************
458 * Load a cursor or icon from a 16-bit resource.
460 static HGLOBAL16
CURSORICON_Load16( HINSTANCE16 hInstance
, SEGPTR name
,
461 INT32 width
, INT32 height
, INT32 colors
,
466 CURSORICONDIRENTRY dirEntry
;
468 if (!hInstance
) /* OEM cursor/icon */
470 if (HIWORD(name
)) /* Check for '#xxx' name */
472 char *ptr
= PTR_SEG_TO_LIN( name
);
473 if (ptr
[0] != '#') return 0;
474 if (!(name
= (SEGPTR
)atoi( ptr
+ 1 ))) return 0;
476 return OBM_LoadCursorIcon( LOWORD(name
), fCursor
);
479 /* Find the best entry in the directory */
481 if ( !CURSORICON_LoadDirEntry16( hInstance
, name
, width
, height
,
482 colors
, fCursor
, &dirEntry
) ) return 0;
483 /* Load the resource */
485 if ( (hRsrc
= FindResource16( hInstance
,
486 MAKEINTRESOURCE( dirEntry
.icon
.wResId
),
487 fCursor
? RT_CURSOR
: RT_ICON
)) )
489 /* 16-bit icon or cursor resources are processed
490 * transparently by the LoadResource16() via custom
491 * resource handlers set by SetResourceHandler().
494 if ( (handle
= LoadResource16( hInstance
, hRsrc
)) )
500 /**********************************************************************
503 * Load a cursor or icon from a 32-bit resource.
505 static HGLOBAL32
CURSORICON_Load32( HINSTANCE32 hInstance
, LPCWSTR name
,
506 int width
, int height
, int colors
,
511 CURSORICONDIRENTRY dirEntry
;
513 if(!hInstance
) /* OEM cursor/icon */
518 LPSTR ansi
= HEAP_strdupWtoA(GetProcessHeap(),0,name
);
519 if( ansi
[0]=='#') /*Check for '#xxx' name */
521 resid
= atoi(ansi
+1);
522 HeapFree( GetProcessHeap(), 0, ansi
);
526 HeapFree( GetProcessHeap(), 0, ansi
);
530 else resid
= LOWORD(name
);
531 return OBM_LoadCursorIcon(resid
, fCursor
);
534 /* Find the best entry in the directory */
536 if ( !CURSORICON_LoadDirEntry32( hInstance
, name
, width
, height
,
537 colors
, fCursor
, &dirEntry
) ) return 0;
538 /* Load the resource */
540 if ( (hRsrc
= FindResource32W( hInstance
,
541 (LPWSTR
) (DWORD
) dirEntry
.icon
.wResId
,
542 (LPWSTR
) (fCursor
? RT_CURSOR
: RT_ICON
))) )
545 if ( (handle
= LoadResource32( hInstance
, hRsrc
)) )
547 /* Hack to keep LoadCursor/Icon32() from spawning multiple
548 * copies of the same object.
550 #define pRsrcEntry ((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)
551 if( !pRsrcEntry
->ResourceHandle
)
553 LPBYTE bits
= (LPBYTE
)LockResource32( handle
);
554 h
= CURSORICON_CreateFromResource( hInstance
, 0, bits
, dirEntry
.icon
.dwBytesInRes
,
555 !fCursor
, 0x00030000, width
, height
, LR_DEFAULTCOLOR
);
556 pRsrcEntry
->ResourceHandle
= h
;
558 else h
= pRsrcEntry
->ResourceHandle
;
567 /***********************************************************************
570 * Make a copy of a cursor or icon.
572 static HGLOBAL16
CURSORICON_Copy( HINSTANCE16 hInstance
, HGLOBAL16 handle
)
574 char *ptrOld
, *ptrNew
;
578 if (!(ptrOld
= (char *)GlobalLock16( handle
))) return 0;
579 if (!(hInstance
= GetExePtr( hInstance
))) return 0;
580 size
= GlobalSize16( handle
);
581 hNew
= GlobalAlloc16( GMEM_MOVEABLE
, size
);
582 FarSetOwner( hNew
, hInstance
);
583 ptrNew
= (char *)GlobalLock16( hNew
);
584 memcpy( ptrNew
, ptrOld
, size
);
585 GlobalUnlock16( handle
);
586 GlobalUnlock16( hNew
);
590 /***********************************************************************
591 * CURSORICON_IconToCursor
593 * Converts bitmap to mono and truncates if icon is too large (should
594 * probably do StretchBlt() instead).
596 HCURSOR16
CURSORICON_IconToCursor(HICON16 hIcon
, BOOL32 bSemiTransparent
)
599 CURSORICONINFO
*pIcon
= NULL
;
600 HTASK16 hTask
= GetCurrentTask();
601 TDB
* pTask
= (TDB
*)GlobalLock16(hTask
);
604 if (!(pIcon
= (CURSORICONINFO
*)GlobalLock16( hIcon
))) return FALSE
;
605 if (pIcon
->bPlanes
* pIcon
->bBitsPerPixel
== 1)
606 hRet
= CURSORICON_Copy( pTask
->hInstance
, hIcon
);
611 int maxx
, maxy
, ix
, iy
, bpp
= pIcon
->bBitsPerPixel
;
612 BYTE
* psPtr
, *pxbPtr
= pXorBits
;
613 unsigned xor_width
, and_width
, val_base
= 0xffffffff >> (32 - bpp
);
619 dprintf_icon(stddeb
, "IconToCursor:[%04x] %ix%i %ibpp (bogus %ibps)\n",
620 hIcon
, pIcon
->nWidth
, pIcon
->nHeight
, pIcon
->bBitsPerPixel
, pIcon
->nWidthBytes
);
622 xor_width
= BITMAP_GetBitsWidth( pIcon
->nWidth
, bpp
);
623 and_width
= BITMAP_GetBitsWidth( pIcon
->nWidth
, 1 );
624 psPtr
= (BYTE
*)(pIcon
+ 1) + pIcon
->nHeight
* and_width
;
626 memset(pXorBits
, 0, 128);
627 cI
.bBitsPerPixel
= 1; cI
.bPlanes
= 1;
628 cI
.ptHotSpot
.x
= cI
.ptHotSpot
.y
= 15;
629 cI
.nWidth
= 32; cI
.nHeight
= 32;
630 cI
.nWidthBytes
= 4; /* 32x1bpp */
632 maxx
= (pIcon
->nWidth
> 32) ? 32 : pIcon
->nWidth
;
633 maxy
= (pIcon
->nHeight
> 32) ? 32 : pIcon
->nHeight
;
635 for( iy
= 0; iy
< maxy
; iy
++ )
637 unsigned shift
= iy
% 2;
639 memcpy( pAndBits
+ iy
* 4, (BYTE
*)(pIcon
+ 1) + iy
* and_width
,
640 (and_width
> 4) ? 4 : and_width
);
641 for( ix
= 0; ix
< maxx
; ix
++ )
643 if( bSemiTransparent
&& ((ix
+shift
)%2) )
645 /* set AND bit, XOR bit stays 0 */
647 pbc
= pAndBits
+ iy
* 4 + ix
/8;
648 *pbc
|= 0x80 >> (ix
%8);
652 /* keep AND bit, set XOR bit */
654 unsigned *psc
= (unsigned*)(psPtr
+ (ix
* bpp
)/8);
655 unsigned val
= ((*psc
) >> (ix
* bpp
)%8) & val_base
;
656 col
= COLOR_ToLogical(val
);
657 if( (GetRValue(col
) + GetGValue(col
) + GetBValue(col
)) > 0x180 )
660 *pbc
|= 0x80 >> (ix
%8);
668 hRet
= CreateCursorIconIndirect( pTask
->hInstance
, &cI
, pAndBits
, pXorBits
);
670 if( !hRet
) /* fall back on default drag cursor */
671 hRet
= CURSORICON_Copy( pTask
->hInstance
,
672 CURSORICON_Load16(0,MAKEINTRESOURCE(OCR_DRAGOBJECT
),
673 SYSMETRICS_CXCURSOR
, SYSMETRICS_CYCURSOR
, 1, TRUE
) );
680 /***********************************************************************
681 * LoadCursor16 (USER.173)
683 HCURSOR16 WINAPI
LoadCursor16( HINSTANCE16 hInstance
, SEGPTR name
)
686 dprintf_cursor( stddeb
, "LoadCursor16: %04x '%s'\n",
687 hInstance
, (char *)PTR_SEG_TO_LIN( name
) );
689 dprintf_cursor( stddeb
, "LoadCursor16: %04x %04x\n",
690 hInstance
, LOWORD(name
) );
692 return CURSORICON_Load16( hInstance
, name
,
693 SYSMETRICS_CXCURSOR
, SYSMETRICS_CYCURSOR
, 1, TRUE
);
697 /***********************************************************************
698 * LoadIcon16 (USER.174)
700 HICON16 WINAPI
LoadIcon16( HINSTANCE16 hInstance
, SEGPTR name
)
703 dprintf_icon( stddeb
, "LoadIcon: %04x '%s'\n",
704 hInstance
, (char *)PTR_SEG_TO_LIN( name
) );
706 dprintf_icon( stddeb
, "LoadIcon: %04x %04x\n",
707 hInstance
, LOWORD(name
) );
709 return CURSORICON_Load16( hInstance
, name
,
710 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
,
711 MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE
);
715 /***********************************************************************
716 * CreateCursor16 (USER.406)
718 HCURSOR16 WINAPI
CreateCursor16( HINSTANCE16 hInstance
,
719 INT16 xHotSpot
, INT16 yHotSpot
,
720 INT16 nWidth
, INT16 nHeight
,
721 LPCVOID lpANDbits
, LPCVOID lpXORbits
)
723 CURSORICONINFO info
= { { xHotSpot
, yHotSpot
}, nWidth
, nHeight
, 0, 1, 1 };
725 dprintf_cursor( stddeb
, "CreateCursor: %dx%d spot=%d,%d xor=%p and=%p\n",
726 nWidth
, nHeight
, xHotSpot
, yHotSpot
, lpXORbits
, lpANDbits
);
727 return CreateCursorIconIndirect( hInstance
, &info
, lpANDbits
, lpXORbits
);
731 /***********************************************************************
732 * CreateCursor32 (USER32.66)
734 HCURSOR32 WINAPI
CreateCursor32( HINSTANCE32 hInstance
,
735 INT32 xHotSpot
, INT32 yHotSpot
,
736 INT32 nWidth
, INT32 nHeight
,
737 LPCVOID lpANDbits
, LPCVOID lpXORbits
)
739 CURSORICONINFO info
= { { xHotSpot
, yHotSpot
}, nWidth
, nHeight
, 0, 1, 1 };
741 dprintf_cursor( stddeb
, "CreateCursor: %dx%d spot=%d,%d xor=%p and=%p\n",
742 nWidth
, nHeight
, xHotSpot
, yHotSpot
, lpXORbits
, lpANDbits
);
743 return CreateCursorIconIndirect( hInstance
, &info
, lpANDbits
, lpXORbits
);
747 /***********************************************************************
748 * CreateIcon16 (USER.407)
750 HICON16 WINAPI
CreateIcon16( HINSTANCE16 hInstance
, INT16 nWidth
,
751 INT16 nHeight
, BYTE bPlanes
, BYTE bBitsPixel
,
752 LPCVOID lpANDbits
, LPCVOID lpXORbits
)
754 CURSORICONINFO info
= { { 0, 0 }, nWidth
, nHeight
, 0, bPlanes
, bBitsPixel
};
756 dprintf_icon( stddeb
, "CreateIcon: %dx%dx%d, xor=%p, and=%p\n",
757 nWidth
, nHeight
, bPlanes
* bBitsPixel
, lpXORbits
, lpANDbits
);
758 return CreateCursorIconIndirect( hInstance
, &info
, lpANDbits
, lpXORbits
);
762 /***********************************************************************
763 * CreateIcon32 (USER32.74)
765 HICON32 WINAPI
CreateIcon32( HINSTANCE32 hInstance
, INT32 nWidth
,
766 INT32 nHeight
, BYTE bPlanes
, BYTE bBitsPixel
,
767 LPCVOID lpANDbits
, LPCVOID lpXORbits
)
769 CURSORICONINFO info
= { { 0, 0 }, nWidth
, nHeight
, 0, bPlanes
, bBitsPixel
};
771 dprintf_icon( stddeb
, "CreateIcon: %dx%dx%d, xor=%p, and=%p\n",
772 nWidth
, nHeight
, bPlanes
* bBitsPixel
, lpXORbits
, lpANDbits
);
773 return CreateCursorIconIndirect( hInstance
, &info
, lpANDbits
, lpXORbits
);
777 /***********************************************************************
778 * CreateCursorIconIndirect (USER.408)
780 HGLOBAL16 WINAPI
CreateCursorIconIndirect( HINSTANCE16 hInstance
,
781 CURSORICONINFO
*info
,
787 int sizeAnd
, sizeXor
;
789 hInstance
= GetExePtr( hInstance
); /* Make it a module handle */
790 if (!hInstance
|| !lpXORbits
|| !lpANDbits
|| info
->bPlanes
!= 1) return 0;
791 info
->nWidthBytes
= BITMAP_WIDTH_BYTES(info
->nWidth
,info
->bBitsPerPixel
);
792 sizeXor
= info
->nHeight
* info
->nWidthBytes
;
793 sizeAnd
= info
->nHeight
* BITMAP_WIDTH_BYTES( info
->nWidth
, 1 );
794 if (!(handle
= DirectResAlloc(hInstance
, 0x10,
795 sizeof(CURSORICONINFO
) + sizeXor
+ sizeAnd
)))
797 ptr
= (char *)GlobalLock16( handle
);
798 memcpy( ptr
, info
, sizeof(*info
) );
799 memcpy( ptr
+ sizeof(CURSORICONINFO
), lpANDbits
, sizeAnd
);
800 memcpy( ptr
+ sizeof(CURSORICONINFO
) + sizeAnd
, lpXORbits
, sizeXor
);
801 GlobalUnlock16( handle
);
806 /***********************************************************************
807 * CopyIcon16 (USER.368)
809 HICON16 WINAPI
CopyIcon16( HINSTANCE16 hInstance
, HICON16 hIcon
)
811 dprintf_icon( stddeb
, "CopyIcon16: %04x %04x\n", hInstance
, hIcon
);
812 return CURSORICON_Copy( hInstance
, hIcon
);
816 /***********************************************************************
817 * CopyIcon32 (USER32.59)
819 HICON32 WINAPI
CopyIcon32( HICON32 hIcon
)
821 dprintf_icon( stddeb
, "CopyIcon32: %04x\n", hIcon
);
822 return CURSORICON_Copy( 0, hIcon
);
826 /***********************************************************************
827 * CopyCursor16 (USER.369)
829 HCURSOR16 WINAPI
CopyCursor16( HINSTANCE16 hInstance
, HCURSOR16 hCursor
)
831 dprintf_cursor( stddeb
, "CopyCursor16: %04x %04x\n", hInstance
, hCursor
);
832 return CURSORICON_Copy( hInstance
, hCursor
);
836 /***********************************************************************
837 * DestroyIcon16 (USER.457)
839 BOOL16 WINAPI
DestroyIcon16( HICON16 hIcon
)
841 return DestroyIcon32( hIcon
);
845 /***********************************************************************
846 * DestroyIcon32 (USER32.132)
848 BOOL32 WINAPI
DestroyIcon32( HICON32 hIcon
)
850 dprintf_icon( stddeb
, "DestroyIcon: %04x\n", hIcon
);
851 /* FIXME: should check for OEM icon here */
852 return (FreeResource16( hIcon
) == 0);
856 /***********************************************************************
857 * DestroyCursor16 (USER.458)
859 BOOL16 WINAPI
DestroyCursor16( HCURSOR16 hCursor
)
861 return DestroyCursor32( hCursor
);
865 /***********************************************************************
866 * DestroyCursor32 (USER32.131)
868 BOOL32 WINAPI
DestroyCursor32( HCURSOR32 hCursor
)
870 dprintf_cursor( stddeb
, "DestroyCursor: %04x\n", hCursor
);
871 /* FIXME: should check for OEM cursor here */
872 return (FreeResource16( hCursor
) != 0);
876 /***********************************************************************
877 * DrawIcon16 (USER.84)
879 BOOL16 WINAPI
DrawIcon16( HDC16 hdc
, INT16 x
, INT16 y
, HICON16 hIcon
)
881 return DrawIcon32( hdc
, x
, y
, hIcon
);
885 /***********************************************************************
886 * DrawIcon32 (USER32.158)
888 BOOL32 WINAPI
DrawIcon32( HDC32 hdc
, INT32 x
, INT32 y
, HICON32 hIcon
)
892 HBITMAP32 hXorBits
, hAndBits
;
893 COLORREF oldFg
, oldBg
;
895 if (!(ptr
= (CURSORICONINFO
*)GlobalLock16( hIcon
))) return FALSE
;
896 if (!(hMemDC
= CreateCompatibleDC32( hdc
))) return FALSE
;
897 hAndBits
= CreateBitmap32( ptr
->nWidth
, ptr
->nHeight
, 1, 1,
899 hXorBits
= CreateBitmap32( ptr
->nWidth
, ptr
->nHeight
, ptr
->bPlanes
,
900 ptr
->bBitsPerPixel
, (char *)(ptr
+ 1)
901 + ptr
->nHeight
* BITMAP_WIDTH_BYTES(ptr
->nWidth
,1) );
902 oldFg
= SetTextColor32( hdc
, RGB(0,0,0) );
903 oldBg
= SetBkColor32( hdc
, RGB(255,255,255) );
905 if (hXorBits
&& hAndBits
)
907 HBITMAP32 hBitTemp
= SelectObject32( hMemDC
, hAndBits
);
908 BitBlt32( hdc
, x
, y
, ptr
->nWidth
, ptr
->nHeight
, hMemDC
, 0, 0, SRCAND
);
909 SelectObject32( hMemDC
, hXorBits
);
910 BitBlt32(hdc
, x
, y
, ptr
->nWidth
, ptr
->nHeight
, hMemDC
, 0, 0,SRCINVERT
);
911 SelectObject32( hMemDC
, hBitTemp
);
913 DeleteDC32( hMemDC
);
914 if (hXorBits
) DeleteObject32( hXorBits
);
915 if (hAndBits
) DeleteObject32( hAndBits
);
916 GlobalUnlock16( hIcon
);
917 SetTextColor32( hdc
, oldFg
);
918 SetBkColor32( hdc
, oldBg
);
923 /***********************************************************************
924 * DumpIcon (USER.459)
926 DWORD WINAPI
DumpIcon( SEGPTR pInfo
, WORD
*lpLen
,
927 SEGPTR
*lpXorBits
, SEGPTR
*lpAndBits
)
929 CURSORICONINFO
*info
= PTR_SEG_TO_LIN( pInfo
);
930 int sizeAnd
, sizeXor
;
933 sizeXor
= info
->nHeight
* info
->nWidthBytes
;
934 sizeAnd
= info
->nHeight
* BITMAP_WIDTH_BYTES( info
->nWidth
, 1 );
935 if (lpAndBits
) *lpAndBits
= pInfo
+ sizeof(CURSORICONINFO
);
936 if (lpXorBits
) *lpXorBits
= pInfo
+ sizeof(CURSORICONINFO
) + sizeAnd
;
937 if (lpLen
) *lpLen
= sizeof(CURSORICONINFO
) + sizeAnd
+ sizeXor
;
938 return MAKELONG( sizeXor
, sizeXor
);
942 /***********************************************************************
943 * CURSORICON_SetCursor
945 * Change the X cursor. Helper function for SetCursor() and ShowCursor().
947 static BOOL32
CURSORICON_SetCursor( HCURSOR16 hCursor
)
949 Pixmap pixmapBits
, pixmapMask
, pixmapAll
;
951 Cursor cursor
= None
;
953 if (!hCursor
) /* Create an empty cursor */
955 static const char data
[] = { 0 };
957 bg
.red
= bg
.green
= bg
.blue
= 0x0000;
958 pixmapBits
= XCreateBitmapFromData( display
, rootWindow
, data
, 1, 1 );
961 cursor
= XCreatePixmapCursor( display
, pixmapBits
, pixmapBits
,
963 XFreePixmap( display
, pixmapBits
);
966 else /* Create the X cursor from the bits */
971 if (!(ptr
= (CURSORICONINFO
*)GlobalLock16( hCursor
))) return FALSE
;
972 if (ptr
->bPlanes
* ptr
->bBitsPerPixel
!= 1)
974 fprintf( stderr
, "Cursor %04x has more than 1 bpp!\n", hCursor
);
978 /* Create a pixmap and transfer all the bits to it */
980 /* NOTE: Following hack works, but only because XFree depth
981 * 1 images really use 1 bit/pixel (and so the same layout
982 * as the Windows cursor data). Perhaps use a more generic
985 pixmapAll
= XCreatePixmap( display
, rootWindow
,
986 ptr
->nWidth
, ptr
->nHeight
* 2, 1 );
987 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
988 1, ZPixmap
, 0, (char *)(ptr
+ 1), ptr
->nWidth
,
989 ptr
->nHeight
* 2, 16, ptr
->nWidthBytes
);
992 extern void _XInitImageFuncPtrs( XImage
* );
993 image
->byte_order
= MSBFirst
;
994 image
->bitmap_bit_order
= MSBFirst
;
995 image
->bitmap_unit
= 16;
996 _XInitImageFuncPtrs(image
);
998 XPutImage( display
, pixmapAll
, BITMAP_monoGC
, image
,
999 0, 0, 0, 0, ptr
->nWidth
, ptr
->nHeight
* 2 );
1001 XDestroyImage( image
);
1004 /* Now create the 2 pixmaps for bits and mask */
1006 pixmapBits
= XCreatePixmap( display
, rootWindow
,
1007 ptr
->nWidth
, ptr
->nHeight
, 1 );
1008 pixmapMask
= XCreatePixmap( display
, rootWindow
,
1009 ptr
->nWidth
, ptr
->nHeight
, 1 );
1011 /* Make sure everything went OK so far */
1013 if (pixmapBits
&& pixmapMask
&& pixmapAll
)
1015 /* We have to do some magic here, as cursors are not fully
1016 * compatible between Windows and X11. Under X11, there
1017 * are only 3 possible color cursor: black, white and
1018 * masked. So we map the 4th Windows color (invert the
1019 * bits on the screen) to black. This require some boolean
1023 * Xor And Result | Bits Mask Result
1024 * 0 0 black | 0 1 background
1025 * 0 1 no change | X 0 no change
1026 * 1 0 white | 1 1 foreground
1027 * 1 1 inverted | 0 1 background
1030 * Bits = 'Xor' and not 'And'
1031 * Mask = 'Xor' or not 'And'
1033 * FIXME: apparently some servers do support 'inverted' color.
1034 * I don't know if it's correct per the X spec, but maybe
1035 * we ought to take advantage of it. -- AJ
1037 XCopyArea( display
, pixmapAll
, pixmapBits
, BITMAP_monoGC
,
1038 0, 0, ptr
->nWidth
, ptr
->nHeight
, 0, 0 );
1039 XCopyArea( display
, pixmapAll
, pixmapMask
, BITMAP_monoGC
,
1040 0, 0, ptr
->nWidth
, ptr
->nHeight
, 0, 0 );
1041 XSetFunction( display
, BITMAP_monoGC
, GXandReverse
);
1042 XCopyArea( display
, pixmapAll
, pixmapBits
, BITMAP_monoGC
,
1043 0, ptr
->nHeight
, ptr
->nWidth
, ptr
->nHeight
, 0, 0 );
1044 XSetFunction( display
, BITMAP_monoGC
, GXorReverse
);
1045 XCopyArea( display
, pixmapAll
, pixmapMask
, BITMAP_monoGC
,
1046 0, ptr
->nHeight
, ptr
->nWidth
, ptr
->nHeight
, 0, 0 );
1047 XSetFunction( display
, BITMAP_monoGC
, GXcopy
);
1048 fg
.red
= fg
.green
= fg
.blue
= 0xffff;
1049 bg
.red
= bg
.green
= bg
.blue
= 0x0000;
1050 cursor
= XCreatePixmapCursor( display
, pixmapBits
, pixmapMask
,
1051 &fg
, &bg
, ptr
->ptHotSpot
.x
, ptr
->ptHotSpot
.y
);
1054 /* Now free everything */
1056 if (pixmapAll
) XFreePixmap( display
, pixmapAll
);
1057 if (pixmapBits
) XFreePixmap( display
, pixmapBits
);
1058 if (pixmapMask
) XFreePixmap( display
, pixmapMask
);
1059 GlobalUnlock16( hCursor
);
1062 if (cursor
== None
) return FALSE
;
1063 if (CURSORICON_XCursor
!= None
) XFreeCursor( display
, CURSORICON_XCursor
);
1064 CURSORICON_XCursor
= cursor
;
1066 if (rootWindow
!= DefaultRootWindow(display
))
1068 /* Set the cursor on the desktop window */
1069 XDefineCursor( display
, rootWindow
, cursor
);
1073 /* Set the same cursor for all top-level windows */
1074 HWND32 hwnd
= GetWindow32( GetDesktopWindow32(), GW_CHILD
);
1077 Window win
= WIN_GetXWindow( hwnd
);
1078 if (win
) XDefineCursor( display
, win
, cursor
);
1079 hwnd
= GetWindow32( hwnd
, GW_HWNDNEXT
);
1086 /***********************************************************************
1087 * SetCursor16 (USER.69)
1089 HCURSOR16 WINAPI
SetCursor16( HCURSOR16 hCursor
)
1091 return (HCURSOR16
)SetCursor32( hCursor
);
1095 /***********************************************************************
1096 * SetCursor32 (USER32.471)
1098 HCURSOR32 WINAPI
SetCursor32( HCURSOR32 hCursor
)
1100 HCURSOR32 hOldCursor
;
1102 if (hCursor
== hActiveCursor
) return hActiveCursor
; /* No change */
1103 dprintf_cursor( stddeb
, "SetCursor: %04x\n", hCursor
);
1104 hOldCursor
= hActiveCursor
;
1105 hActiveCursor
= hCursor
;
1106 /* Change the cursor shape only if it is visible */
1107 if (CURSOR_ShowCount
>= 0)
1108 CALL_LARGE_STACK( CURSORICON_SetCursor
, hActiveCursor
);
1113 /***********************************************************************
1114 * SetCursorPos16 (USER.70)
1116 void WINAPI
SetCursorPos16( INT16 x
, INT16 y
)
1118 SetCursorPos32( x
, y
);
1122 /***********************************************************************
1123 * SetCursorPos32 (USER32.473)
1125 BOOL32 WINAPI
SetCursorPos32( INT32 x
, INT32 y
)
1127 dprintf_cursor( stddeb
, "SetCursorPos: x=%d y=%d\n", x
, y
);
1128 XWarpPointer( display
, rootWindow
, rootWindow
, 0, 0, 0, 0, x
, y
);
1133 /***********************************************************************
1134 * ShowCursor16 (USER.71)
1136 INT16 WINAPI
ShowCursor16( BOOL16 bShow
)
1138 return ShowCursor32( bShow
);
1142 /***********************************************************************
1143 * ShowCursor32 (USER32.529)
1145 INT32 WINAPI
ShowCursor32( BOOL32 bShow
)
1147 dprintf_cursor( stddeb
, "ShowCursor: %d, count=%d\n",
1148 bShow
, CURSOR_ShowCount
);
1152 if (++CURSOR_ShowCount
== 0) /* Show it */
1153 CALL_LARGE_STACK( CURSORICON_SetCursor
, hActiveCursor
);
1157 if (--CURSOR_ShowCount
== -1) /* Hide it */
1158 CALL_LARGE_STACK( CURSORICON_SetCursor
, 0 );
1160 return CURSOR_ShowCount
;
1164 /***********************************************************************
1165 * GetCursor16 (USER.247)
1167 HCURSOR16 WINAPI
GetCursor16(void)
1169 return hActiveCursor
;
1173 /***********************************************************************
1174 * GetCursor32 (USER32.226)
1176 HCURSOR32 WINAPI
GetCursor32(void)
1178 return hActiveCursor
;
1182 /***********************************************************************
1183 * ClipCursor16 (USER.16)
1185 BOOL16 WINAPI
ClipCursor16( const RECT16
*rect
)
1187 if (!rect
) SetRectEmpty32( &CURSOR_ClipRect
);
1188 else CONV_RECT16TO32( rect
, &CURSOR_ClipRect
);
1193 /***********************************************************************
1194 * ClipCursor32 (USER32.52)
1196 BOOL32 WINAPI
ClipCursor32( const RECT32
*rect
)
1198 if (!rect
) SetRectEmpty32( &CURSOR_ClipRect
);
1199 else CopyRect32( &CURSOR_ClipRect
, rect
);
1204 /***********************************************************************
1205 * GetCursorPos16 (USER.17)
1207 void WINAPI
GetCursorPos16( POINT16
*pt
)
1210 int rootX
, rootY
, childX
, childY
;
1211 unsigned int mousebut
;
1214 if (!XQueryPointer( display
, rootWindow
, &root
, &child
,
1215 &rootX
, &rootY
, &childX
, &childY
, &mousebut
))
1222 dprintf_cursor(stddeb
, "GetCursorPos: ret=%d,%d\n", pt
->x
, pt
->y
);
1226 /***********************************************************************
1227 * GetCursorPos32 (USER32.228)
1229 void WINAPI
GetCursorPos32( POINT32
*pt
)
1232 GetCursorPos16( &pt16
);
1233 if (pt
) CONV_POINT16TO32( &pt16
, pt
);
1237 /***********************************************************************
1238 * GetClipCursor16 (USER.309)
1240 void WINAPI
GetClipCursor16( RECT16
*rect
)
1242 if (rect
) CONV_RECT32TO16( &CURSOR_ClipRect
, rect
);
1246 /***********************************************************************
1247 * GetClipCursor32 (USER32.220)
1249 void WINAPI
GetClipCursor32( RECT32
*rect
)
1251 if (rect
) CopyRect32( rect
, &CURSOR_ClipRect
);
1254 /**********************************************************************
1255 * LookupIconIdFromDirectoryEx16 (USER.364)
1257 * FIXME: exact parameter sizes
1259 UINT16 WINAPI
LookupIconIdFromDirectoryEx16( CURSORICONDIR
*dir
, BOOL16 bIcon
,
1260 INT16 width
, INT16 height
, UINT16 cFlag
)
1263 if( dir
&& !dir
->idReserved
&& (dir
->idType
& 3) )
1265 int colors
= (cFlag
== LR_MONOCHROME
) ? 2 : COLOR_GetSystemPaletteSize();
1268 ICONDIRENTRY
* entry
;
1269 entry
= CURSORICON_FindBestIcon( dir
, width
, height
, colors
);
1270 if( entry
) retVal
= entry
->wResId
;
1274 CURSORDIRENTRY
* entry
;
1275 entry
= CURSORICON_FindBestCursor( dir
, width
, height
);
1276 if( entry
) retVal
= entry
->wResId
;
1279 else dprintf_cursor(stddeb
,"IconId: invalid resource directory\n");
1283 /**********************************************************************
1284 * LookupIconIdFromDirectoryEx32 (USER32.379)
1286 INT32 WINAPI
LookupIconIdFromDirectoryEx32( CURSORICONDIR
*dir
, BOOL32 bIcon
,
1287 INT32 width
, INT32 height
, UINT32 cFlag
)
1289 return LookupIconIdFromDirectoryEx16( dir
, bIcon
, width
, height
, cFlag
);
1292 /**********************************************************************
1293 * LookupIconIdFromDirectory (USER32.378)
1295 INT32 WINAPI
LookupIconIdFromDirectory( CURSORICONDIR
*dir
, BOOL32 bIcon
)
1297 return LookupIconIdFromDirectoryEx16( dir
, bIcon
,
1298 bIcon
? SYSMETRICS_CXICON
: SYSMETRICS_CXCURSOR
,
1299 bIcon
? SYSMETRICS_CYICON
: SYSMETRICS_CYCURSOR
, bIcon
? 0 : LR_MONOCHROME
);
1302 /**********************************************************************
1303 * GetIconID (USER.455)
1305 WORD WINAPI
GetIconID( HGLOBAL16 hResource
, DWORD resType
)
1307 CURSORICONDIR
*lpDir
= (CURSORICONDIR
*)GlobalLock16(hResource
);
1309 dprintf_cursor( stddeb
, "GetIconID: hRes=%04x, entries=%i\n",
1310 hResource
, lpDir
? lpDir
->idCount
: 0);
1315 return (WORD
)LookupIconIdFromDirectoryEx16( lpDir
, FALSE
,
1316 SYSMETRICS_CXCURSOR
, SYSMETRICS_CYCURSOR
, LR_MONOCHROME
);
1318 return (WORD
)LookupIconIdFromDirectoryEx16( lpDir
, TRUE
,
1319 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
, 0 );
1321 fprintf( stderr
, "GetIconID: invalid res type %ld\n", resType
);
1326 /**********************************************************************
1327 * LoadCursorIconHandler (USER.336)
1329 * Supposed to load resources of Windows 2.x applications.
1331 HGLOBAL16 WINAPI
LoadCursorIconHandler( HGLOBAL16 hResource
, HMODULE16 hModule
, HRSRC16 hRsrc
)
1333 fprintf(stderr
,"hModule[%04x]: old 2.x resources are not supported!\n", hModule
);
1334 return (HGLOBAL16
)0;
1337 /**********************************************************************
1338 * LoadDIBIconHandler (USER.357)
1340 * RT_ICON resource loader, installed by USER_SignalProc when module
1343 HGLOBAL16 WINAPI
LoadDIBIconHandler( HGLOBAL16 hMemObj
, HMODULE16 hModule
, HRSRC16 hRsrc
)
1345 /* If hResource is zero we must allocate a new memory block, if it's
1346 * non-zero but GlobalLock() returns NULL then it was discarded and
1347 * we have to recommit some memory, otherwise we just need to check
1348 * the block size. See LoadProc() in 16-bit SDK for more.
1351 hMemObj
= USER_CallDefaultRsrcHandler( hMemObj
, hModule
, hRsrc
);
1354 LPBYTE bits
= (LPBYTE
)GlobalLock16( hMemObj
);
1355 hMemObj
= CURSORICON_CreateFromResource( hModule
, hMemObj
, bits
,
1356 SizeofResource16(hModule
, hRsrc
), TRUE
, 0x00030000,
1357 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
, LR_DEFAULTCOLOR
);
1362 /**********************************************************************
1363 * LoadDIBCursorHandler (USER.356)
1365 * RT_CURSOR resource loader. Same as above.
1367 HGLOBAL16 WINAPI
LoadDIBCursorHandler( HGLOBAL16 hMemObj
, HMODULE16 hModule
, HRSRC16 hRsrc
)
1369 hMemObj
= USER_CallDefaultRsrcHandler( hMemObj
, hModule
, hRsrc
);
1372 LPBYTE bits
= (LPBYTE
)GlobalLock16( hMemObj
);
1373 hMemObj
= CURSORICON_CreateFromResource( hModule
, hMemObj
, bits
,
1374 SizeofResource16(hModule
, hRsrc
), FALSE
, 0x00030000,
1375 SYSMETRICS_CXCURSOR
, SYSMETRICS_CYCURSOR
, LR_MONOCHROME
);
1380 /**********************************************************************
1381 * LoadIconHandler (USER.456)
1383 HICON16 WINAPI
LoadIconHandler( HGLOBAL16 hResource
, BOOL16 bNew
)
1385 LPBYTE bits
= (LPBYTE
)LockResource16( hResource
);
1387 dprintf_cursor(stddeb
,"LoadIconHandler: hRes=%04x\n",hResource
);
1389 return CURSORICON_CreateFromResource( 0, 0, bits
, 0, TRUE
,
1390 bNew
? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR
);
1393 /***********************************************************************
1394 * LoadCursorW (USER32.361)
1396 HCURSOR32 WINAPI
LoadCursor32W(HINSTANCE32 hInstance
, LPCWSTR name
)
1398 return CURSORICON_Load32( hInstance
, name
,
1399 SYSMETRICS_CXCURSOR
, SYSMETRICS_CYCURSOR
, 1, TRUE
);
1402 /***********************************************************************
1403 * LoadCursorA (USER32.358)
1405 HCURSOR32 WINAPI
LoadCursor32A(HINSTANCE32 hInstance
, LPCSTR name
)
1409 return LoadCursor32W(hInstance
,(LPCWSTR
)name
);
1412 LPWSTR uni
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
1413 res
= LoadCursor32W(hInstance
, uni
);
1414 HeapFree( GetProcessHeap(), 0, uni
);
1419 /***********************************************************************
1420 * LoadIconW (USER32.363)
1422 HICON32 WINAPI
LoadIcon32W(HINSTANCE32 hInstance
, LPCWSTR name
)
1424 return CURSORICON_Load32( hInstance
, name
,
1425 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
,
1426 MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE
);
1429 /***********************************************************************
1430 * LoadIconA (USER32.362)
1432 HICON32 WINAPI
LoadIcon32A(HINSTANCE32 hInstance
, LPCSTR name
)
1437 return LoadIcon32W(hInstance
, (LPCWSTR
)name
);
1440 LPWSTR uni
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
1441 res
= LoadIcon32W( hInstance
, uni
);
1442 HeapFree( GetProcessHeap(), 0, uni
);
1447 /**********************************************************************
1448 * GetIconInfo (USER32.241)