Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
0bb1aadb
Commit
0bb1aadb
authored
Mar 11, 2011
by
Erich Hoover
Committed by
Alexandre Julliard
Mar 16, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Add get/release routines for accessing cursor frames.
parent
22cc5471
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
126 additions
and
52 deletions
+126
-52
cursoricon.c
dlls/user32/cursoricon.c
+126
-52
No files found.
dlls/user32/cursoricon.c
View file @
0bb1aadb
...
...
@@ -83,6 +83,8 @@ static struct list icon_cache = LIST_INIT( icon_cache );
struct
cursoricon_frame
{
UINT
width
;
/* frame-specific width */
UINT
height
;
/* frame-specific height */
UINT
delay
;
/* frame-specific delay between this frame and the next (in jiffies) */
HBITMAP
color
;
/* color bitmap */
HBITMAP
alpha
;
/* pre-multiplied alpha bitmap for 32-bpp icons */
...
...
@@ -98,8 +100,6 @@ struct cursoricon_object
LPWSTR
resname
;
/* resource name for icons loaded from resources */
HRSRC
rsrc
;
/* resource for shared icons */
BOOL
is_icon
;
/* whether icon or cursor */
UINT
width
;
UINT
height
;
POINT
hotspot
;
UINT
num_frames
;
/* number of frames in the icon/cursor */
UINT
num_steps
;
/* number of sequence steps in the icon/cursor */
...
...
@@ -135,6 +135,16 @@ static void release_icon_ptr( HICON handle, struct cursoricon_object *ptr )
release_user_handle_ptr
(
ptr
);
}
static
struct
cursoricon_frame
*
get_icon_frame
(
struct
cursoricon_object
*
obj
,
int
istep
)
{
return
&
obj
->
frames
[
istep
];
}
static
void
release_icon_frame
(
struct
cursoricon_object
*
obj
,
int
istep
,
struct
cursoricon_frame
*
frame
)
{
/* placeholder */
}
static
BOOL
free_icon_handle
(
HICON
handle
)
{
struct
cursoricon_object
*
obj
=
free_user_handle
(
handle
,
USER_ICON
);
...
...
@@ -149,9 +159,12 @@ static BOOL free_icon_handle( HICON handle )
for
(
i
=
0
;
i
<
obj
->
num_frames
;
i
++
)
{
if
(
obj
->
frames
[
i
].
alpha
)
DeleteObject
(
obj
->
frames
[
i
].
alpha
);
if
(
obj
->
frames
[
i
].
color
)
DeleteObject
(
obj
->
frames
[
i
].
color
);
DeleteObject
(
obj
->
frames
[
i
].
mask
);
struct
cursoricon_frame
*
frame
=
get_icon_frame
(
obj
,
i
);
if
(
frame
->
alpha
)
DeleteObject
(
frame
->
alpha
);
if
(
frame
->
color
)
DeleteObject
(
frame
->
color
);
DeleteObject
(
frame
->
mask
);
release_icon_frame
(
obj
,
0
,
frame
);
}
if
(
!
IS_INTRESOURCE
(
obj
->
resname
))
HeapFree
(
GetProcessHeap
(),
0
,
obj
->
resname
);
HeapFree
(
GetProcessHeap
(),
0
,
obj
);
...
...
@@ -396,10 +409,13 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
BOOL
get_icon_size
(
HICON
handle
,
SIZE
*
size
)
{
struct
cursoricon_object
*
info
;
struct
cursoricon_frame
*
frame
;
if
(
!
(
info
=
get_icon_ptr
(
handle
)))
return
FALSE
;
size
->
cx
=
info
->
width
;
size
->
cy
=
info
->
height
;
frame
=
get_icon_frame
(
info
,
0
);
size
->
cx
=
frame
->
width
;
size
->
cy
=
frame
->
height
;
release_icon_frame
(
info
,
0
,
frame
);
release_icon_ptr
(
handle
,
info
);
return
TRUE
;
}
...
...
@@ -845,16 +861,19 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi, HMODULE module, LPCW
if
(
hObj
)
{
struct
cursoricon_object
*
info
=
get_icon_ptr
(
hObj
);
struct
cursoricon_frame
*
frame
;
info
->
is_icon
=
bIcon
;
info
->
module
=
module
;
info
->
hotspot
=
hotspot
;
info
->
width
=
width
;
info
->
height
=
height
;
info
->
frames
[
0
].
delay
=
~
0
;
info
->
frames
[
0
].
color
=
color
;
info
->
frames
[
0
].
mask
=
mask
;
info
->
frames
[
0
].
alpha
=
alpha
;
frame
=
get_icon_frame
(
info
,
0
);
frame
->
delay
=
~
0
;
frame
->
width
=
width
;
frame
->
height
=
height
;
frame
->
color
=
color
;
frame
->
mask
=
mask
;
frame
->
alpha
=
alpha
;
release_icon_frame
(
info
,
0
,
frame
);
if
(
!
IS_INTRESOURCE
(
resname
))
{
info
->
resname
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
strlenW
(
resname
)
+
1
)
*
sizeof
(
WCHAR
)
);
...
...
@@ -1065,8 +1084,9 @@ static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
for
(
i
=
0
;
i
<
header
.
num_frames
;
i
++
)
{
const
DWORD
chunk_size
=
*
(
const
DWORD
*
)(
icon_chunk
+
sizeof
(
DWORD
));
struct
cursoricon_frame
*
frame
=
&
info
->
frames
[
i
];
const
CURSORICONFILEDIRENTRY
*
entry
;
struct
cursoricon_frame
*
frame
;
INT
frameWidth
,
frameHeight
;
const
BITMAPINFO
*
bmi
;
entry
=
CURSORICON_FindBestIconFile
((
const
CURSORICONFILEDIR
*
)
icon_data
,
...
...
@@ -1077,16 +1097,20 @@ static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
info
->
hotspot
.
y
=
entry
->
yHotspot
;
if
(
!
header
.
width
||
!
header
.
height
)
{
header
.
w
idth
=
entry
->
bWidth
;
header
.
h
eight
=
entry
->
bHeight
;
frameW
idth
=
entry
->
bWidth
;
frameH
eight
=
entry
->
bHeight
;
}
if
(
frame_rates
)
frame
->
delay
=
frame_rates
[
i
];
else
frame
->
delay
=
~
0
;
{
frameWidth
=
header
.
width
;
frameHeight
=
header
.
height
;
}
frame
=
get_icon_frame
(
info
,
i
);
frame
->
width
=
frameWidth
;
frame
->
height
=
frameHeight
;
/* Grab a frame from the animation */
if
(
!
create_icon_bitmaps
(
bmi
,
header
.
width
,
header
.
h
eight
,
if
(
!
create_icon_bitmaps
(
bmi
,
frameWidth
,
frameH
eight
,
&
frame
->
color
,
&
frame
->
mask
,
&
frame
->
alpha
))
{
FIXME_
(
cursor
)(
"failed to convert animated cursor frame.
\n
"
);
...
...
@@ -1102,6 +1126,13 @@ static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
break
;
}
/* Setup the animated frame */
if
(
frame_rates
)
frame
->
delay
=
frame_rates
[
i
];
else
frame
->
delay
=
~
0
;
release_icon_frame
(
info
,
i
,
frame
);
/* Advance to the next chunk */
icon_chunk
+=
chunk_size
+
(
2
*
sizeof
(
DWORD
));
icon_data
=
icon_chunk
+
(
2
*
sizeof
(
DWORD
));
...
...
@@ -1121,8 +1152,6 @@ static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
info
->
num_steps
=
1
;
info
->
delay
=
0
;
}
info
->
width
=
header
.
width
;
info
->
height
=
header
.
height
;
release_icon_ptr
(
cursor
,
info
);
return
cursor
;
...
...
@@ -1423,15 +1452,32 @@ HICON WINAPI CopyIcon( HICON hIcon )
}
if
((
hNew
=
alloc_icon_handle
(
1
)))
{
struct
cursoricon_frame
*
frameOld
,
*
frameNew
;
ptrNew
=
get_icon_ptr
(
hNew
);
ptrNew
->
is_icon
=
ptrOld
->
is_icon
;
ptrNew
->
width
=
ptrOld
->
width
;
ptrNew
->
height
=
ptrOld
->
height
;
ptrNew
->
hotspot
=
ptrOld
->
hotspot
;
ptrNew
->
frames
[
0
].
delay
=
ptrOld
->
frames
[
0
].
delay
;
ptrNew
->
frames
[
0
].
mask
=
copy_bitmap
(
ptrOld
->
frames
[
0
].
mask
);
ptrNew
->
frames
[
0
].
color
=
copy_bitmap
(
ptrOld
->
frames
[
0
].
color
);
ptrNew
->
frames
[
0
].
alpha
=
copy_bitmap
(
ptrOld
->
frames
[
0
].
alpha
);
if
(
!
(
frameOld
=
get_icon_frame
(
ptrOld
,
0
)))
{
release_icon_ptr
(
hIcon
,
ptrOld
);
SetLastError
(
ERROR_INVALID_CURSOR_HANDLE
);
return
0
;
}
if
(
!
(
frameNew
=
get_icon_frame
(
ptrNew
,
0
)))
{
release_icon_frame
(
ptrOld
,
0
,
frameOld
);
release_icon_ptr
(
hIcon
,
ptrOld
);
SetLastError
(
ERROR_INVALID_CURSOR_HANDLE
);
return
0
;
}
frameNew
->
delay
=
0
;
frameNew
->
width
=
frameOld
->
width
;
frameNew
->
height
=
frameOld
->
height
;
frameNew
->
mask
=
copy_bitmap
(
frameOld
->
mask
);
frameNew
->
color
=
copy_bitmap
(
frameOld
->
color
);
frameNew
->
alpha
=
copy_bitmap
(
frameOld
->
alpha
);
release_icon_frame
(
ptrOld
,
0
,
frameOld
);
release_icon_frame
(
ptrNew
,
0
,
frameNew
);
release_icon_ptr
(
hNew
,
ptrNew
);
}
release_icon_ptr
(
hIcon
,
ptrOld
);
...
...
@@ -1758,15 +1804,19 @@ HCURSOR WINAPI GetCursorFrameInfo(HCURSOR hCursor, DWORD unk1, DWORD istep, DWOR
}
else
{
struct
cursoricon_frame
*
frame
;
frame
=
get_icon_frame
(
ptr
,
istep
);
if
(
ptr
->
num_steps
==
1
)
*
num_steps
=
~
0
;
else
*
num_steps
=
ptr
->
num_steps
;
/* If this specific frame does not have a delay then use the global delay */
if
(
ptr
->
frames
[
istep
].
delay
==
~
0
)
if
(
frame
->
delay
==
~
0
)
*
rate_jiffies
=
ptr
->
delay
;
else
*
rate_jiffies
=
ptr
->
frames
[
istep
].
delay
;
*
rate_jiffies
=
frame
->
delay
;
release_icon_frame
(
ptr
,
istep
,
frame
);
}
}
...
...
@@ -1822,6 +1872,7 @@ BOOL WINAPI GetIconInfoExA( HICON icon, ICONINFOEXA *info )
*/
BOOL
WINAPI
GetIconInfoExW
(
HICON
icon
,
ICONINFOEXW
*
info
)
{
struct
cursoricon_frame
*
frame
;
struct
cursoricon_object
*
ptr
;
HMODULE
module
;
BOOL
ret
=
TRUE
;
...
...
@@ -1837,13 +1888,21 @@ BOOL WINAPI GetIconInfoExW( HICON icon, ICONINFOEXW *info )
return
FALSE
;
}
TRACE
(
"%p => %dx%d
\n
"
,
icon
,
ptr
->
width
,
ptr
->
height
);
frame
=
get_icon_frame
(
ptr
,
0
);
if
(
!
frame
)
{
release_icon_ptr
(
icon
,
ptr
);
SetLastError
(
ERROR_INVALID_CURSOR_HANDLE
);
return
FALSE
;
}
TRACE
(
"%p => %dx%d
\n
"
,
icon
,
frame
->
width
,
frame
->
height
);
info
->
fIcon
=
ptr
->
is_icon
;
info
->
xHotspot
=
ptr
->
hotspot
.
x
;
info
->
yHotspot
=
ptr
->
hotspot
.
y
;
info
->
hbmColor
=
copy_bitmap
(
ptr
->
frames
[
0
].
color
);
info
->
hbmMask
=
copy_bitmap
(
ptr
->
frames
[
0
].
mask
);
info
->
hbmColor
=
copy_bitmap
(
frame
->
color
);
info
->
hbmMask
=
copy_bitmap
(
frame
->
mask
);
info
->
wResID
=
0
;
info
->
szModName
[
0
]
=
0
;
info
->
szResName
[
0
]
=
0
;
...
...
@@ -1852,13 +1911,14 @@ BOOL WINAPI GetIconInfoExW( HICON icon, ICONINFOEXW *info )
if
(
IS_INTRESOURCE
(
ptr
->
resname
))
info
->
wResID
=
LOWORD
(
ptr
->
resname
);
else
lstrcpynW
(
info
->
szResName
,
ptr
->
resname
,
MAX_PATH
);
}
if
(
!
info
->
hbmMask
||
(
!
info
->
hbmColor
&&
ptr
->
frames
[
0
].
color
))
if
(
!
info
->
hbmMask
||
(
!
info
->
hbmColor
&&
frame
->
color
))
{
DeleteObject
(
info
->
hbmMask
);
DeleteObject
(
info
->
hbmColor
);
ret
=
FALSE
;
}
module
=
ptr
->
module
;
release_icon_frame
(
ptr
,
0
,
frame
);
release_icon_ptr
(
icon
,
ptr
);
if
(
ret
&&
module
)
GetModuleFileNameW
(
module
,
info
->
szModName
,
MAX_PATH
);
return
ret
;
...
...
@@ -1967,14 +2027,17 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
if
(
hObj
)
{
struct
cursoricon_object
*
info
=
get_icon_ptr
(
hObj
);
struct
cursoricon_frame
*
frame
;
info
->
is_icon
=
iconinfo
->
fIcon
;
info
->
width
=
width
;
info
->
height
=
height
;
info
->
frames
[
0
].
delay
=
~
0
;
info
->
frames
[
0
].
color
=
color
;
info
->
frames
[
0
].
mask
=
mask
;
info
->
frames
[
0
].
alpha
=
create_alpha_bitmap
(
iconinfo
->
hbmColor
,
mask
,
NULL
,
NULL
);
frame
=
get_icon_frame
(
info
,
0
);
frame
->
delay
=
~
0
;
frame
->
width
=
width
;
frame
->
height
=
height
;
frame
->
color
=
color
;
frame
->
mask
=
mask
;
frame
->
alpha
=
create_alpha_bitmap
(
iconinfo
->
hbmColor
,
mask
,
NULL
,
NULL
);
release_icon_frame
(
info
,
0
,
frame
);
if
(
info
->
is_icon
)
{
info
->
hotspot
.
x
=
width
/
2
;
...
...
@@ -2017,6 +2080,7 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
INT
cxWidth
,
INT
cyWidth
,
UINT
istep
,
HBRUSH
hbr
,
UINT
flags
)
{
struct
cursoricon_frame
*
frame
;
struct
cursoricon_object
*
ptr
;
HDC
hdc_dest
,
hMemDC
;
BOOL
result
=
FALSE
,
DoOffscreen
;
...
...
@@ -2034,8 +2098,15 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
release_icon_ptr
(
hIcon
,
ptr
);
return
FALSE
;
}
if
(
!
(
frame
=
get_icon_frame
(
ptr
,
istep
)))
{
FIXME_
(
icon
)(
"Error retrieving icon frame %d
\n
"
,
istep
);
release_icon_ptr
(
hIcon
,
ptr
);
return
FALSE
;
}
if
(
!
(
hMemDC
=
CreateCompatibleDC
(
hdc
)))
{
release_icon_frame
(
ptr
,
istep
,
frame
);
release_icon_ptr
(
hIcon
,
ptr
);
return
FALSE
;
}
...
...
@@ -2049,14 +2120,14 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
if
(
flags
&
DI_DEFAULTSIZE
)
cxWidth
=
GetSystemMetrics
(
SM_CXICON
);
else
cxWidth
=
ptr
->
width
;
cxWidth
=
frame
->
width
;
}
if
(
cyWidth
==
0
)
{
if
(
flags
&
DI_DEFAULTSIZE
)
cyWidth
=
GetSystemMetrics
(
SM_CYICON
);
else
cyWidth
=
ptr
->
height
;
cyWidth
=
frame
->
height
;
}
DoOffscreen
=
(
GetObjectType
(
hbr
)
==
OBJ_BRUSH
);
...
...
@@ -2091,7 +2162,7 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
oldFg
=
SetTextColor
(
hdc
,
RGB
(
0
,
0
,
0
)
);
oldBg
=
SetBkColor
(
hdc
,
RGB
(
255
,
255
,
255
)
);
if
(
ptr
->
frames
[
istep
].
alpha
&&
(
flags
&
DI_IMAGE
))
if
(
frame
->
alpha
&&
(
flags
&
DI_IMAGE
))
{
BOOL
is_mono
=
FALSE
;
...
...
@@ -2104,34 +2175,36 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
if
(
!
is_mono
)
{
BLENDFUNCTION
pixelblend
=
{
AC_SRC_OVER
,
0
,
255
,
AC_SRC_ALPHA
};
SelectObject
(
hMemDC
,
ptr
->
frames
[
istep
].
alpha
);
SelectObject
(
hMemDC
,
frame
->
alpha
);
if
(
GdiAlphaBlend
(
hdc_dest
,
x
,
y
,
cxWidth
,
cyWidth
,
hMemDC
,
0
,
0
,
ptr
->
width
,
ptr
->
height
,
pixelblend
))
goto
done
;
0
,
0
,
frame
->
width
,
frame
->
height
,
pixelblend
))
goto
done
;
}
}
if
(
flags
&
DI_MASK
)
{
SelectObject
(
hMemDC
,
ptr
->
frames
[
istep
].
mask
);
SelectObject
(
hMemDC
,
frame
->
mask
);
StretchBlt
(
hdc_dest
,
x
,
y
,
cxWidth
,
cyWidth
,
hMemDC
,
0
,
0
,
ptr
->
width
,
ptr
->
height
,
SRCAND
);
hMemDC
,
0
,
0
,
frame
->
width
,
frame
->
height
,
SRCAND
);
}
if
(
flags
&
DI_IMAGE
)
{
if
(
ptr
->
frames
[
istep
].
color
)
if
(
frame
->
color
)
{
DWORD
rop
=
(
flags
&
DI_MASK
)
?
SRCINVERT
:
SRCCOPY
;
SelectObject
(
hMemDC
,
ptr
->
frames
[
istep
].
color
);
SelectObject
(
hMemDC
,
frame
->
color
);
StretchBlt
(
hdc_dest
,
x
,
y
,
cxWidth
,
cyWidth
,
hMemDC
,
0
,
0
,
ptr
->
width
,
ptr
->
height
,
rop
);
hMemDC
,
0
,
0
,
frame
->
width
,
frame
->
height
,
rop
);
}
else
{
DWORD
rop
=
(
flags
&
DI_MASK
)
?
SRCINVERT
:
SRCCOPY
;
SelectObject
(
hMemDC
,
ptr
->
frames
[
istep
].
mask
);
SelectObject
(
hMemDC
,
frame
->
mask
);
StretchBlt
(
hdc_dest
,
x
,
y
,
cxWidth
,
cyWidth
,
hMemDC
,
0
,
ptr
->
height
,
ptr
->
width
,
ptr
->
height
,
rop
);
hMemDC
,
0
,
frame
->
height
,
frame
->
width
,
frame
->
height
,
rop
);
}
}
...
...
@@ -2146,6 +2219,7 @@ done:
if
(
hB_off
)
DeleteObject
(
hB_off
);
failed:
DeleteDC
(
hMemDC
);
release_icon_frame
(
ptr
,
istep
,
frame
);
release_icon_ptr
(
hIcon
,
ptr
);
return
result
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment