Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
c2202929
Commit
c2202929
authored
Jun 29, 2009
by
Joel Holdsworth
Committed by
Alexandre Julliard
Oct 05, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Fixed CURSORICON_CreateIconFromBMI to preserve the alpha channel.
parent
ee09534c
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
84 additions
and
57 deletions
+84
-57
cursoricon.c
dlls/user32/cursoricon.c
+84
-57
No files found.
dlls/user32/cursoricon.c
View file @
c2202929
...
...
@@ -659,6 +659,39 @@ static CURSORICONFILEDIRENTRY *CURSORICON_FindBestIconFile( CURSORICONFILEDIR *d
return
&
dir
->
idEntries
[
n
];
}
/***********************************************************************
* stretch_blt_icon
*
* A helper function that stretches a bitmap buffer into an HBITMAP.
*
* PARAMS
* hDest [I] The handle of the destination bitmap.
* pDestInfo [I] The BITMAPINFO of the destination bitmap.
* pSrcInfo [I] The BITMAPINFO of the source bitmap.
* pSrcBits [I] A pointer to the source bitmap buffer.
**/
static
BOOL
stretch_blt_icon
(
HBITMAP
hDest
,
BITMAPINFO
*
pDestInfo
,
BITMAPINFO
*
pSrcInfo
,
char
*
pSrcBits
)
{
HBITMAP
hOld
;
BOOL
res
=
FALSE
;
static
HDC
hdcMem
=
NULL
;
if
(
!
hdcMem
)
hdcMem
=
CreateCompatibleDC
(
screen_dc
);
if
(
hdcMem
)
{
hOld
=
SelectObject
(
hdcMem
,
hDest
);
res
=
StretchDIBits
(
hdcMem
,
0
,
0
,
pDestInfo
->
bmiHeader
.
biWidth
,
pDestInfo
->
bmiHeader
.
biHeight
,
0
,
0
,
pSrcInfo
->
bmiHeader
.
biWidth
,
pSrcInfo
->
bmiHeader
.
biHeight
,
pSrcBits
,
pSrcInfo
,
DIB_RGB_COLORS
,
SRCCOPY
);
SelectObject
(
hdcMem
,
hOld
);
}
return
res
;
}
static
HICON
CURSORICON_CreateIconFromBMI
(
BITMAPINFO
*
bmi
,
POINT16
hotspot
,
BOOL
bIcon
,
DWORD
dwVersion
,
...
...
@@ -666,12 +699,11 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
UINT
cFlag
)
{
HGLOBAL16
hObj
;
static
HDC
hdcMem
;
int
sizeAnd
,
sizeXor
;
HBITMAP
hAndBits
=
0
,
hXorBits
=
0
;
/* error condition for later */
BITMAP
bmpXor
,
bmpAnd
;
BOOL
DoStretch
;
INT
size
;
BITMAPINFO
*
pSrcInfo
,
*
pDestInfo
;
if
(
dwVersion
==
0x00020000
)
{
...
...
@@ -693,11 +725,10 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
if
(
!
width
)
width
=
bmi
->
bmiHeader
.
biWidth
;
if
(
!
height
)
height
=
bmi
->
bmiHeader
.
biHeight
/
2
;
DoStretch
=
(
bmi
->
bmiHeader
.
biHeight
/
2
!=
height
)
||
(
bmi
->
bmiHeader
.
biWidth
!=
width
);
/* Scale the hotspot */
if
(
DoStretch
&&
hotspot
.
x
!=
ICON_HOTSPOT
&&
hotspot
.
y
!=
ICON_HOTSPOT
)
if
(((
bmi
->
bmiHeader
.
biHeight
/
2
!=
height
)
||
(
bmi
->
bmiHeader
.
biWidth
!=
width
))
&&
hotspot
.
x
!=
ICON_HOTSPOT
&&
hotspot
.
y
!=
ICON_HOTSPOT
)
{
hotspot
.
x
=
(
hotspot
.
x
*
width
)
/
bmi
->
bmiHeader
.
biWidth
;
hotspot
.
y
=
(
hotspot
.
y
*
height
)
/
(
bmi
->
bmiHeader
.
biHeight
/
2
);
...
...
@@ -706,8 +737,6 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
if
(
!
screen_dc
)
screen_dc
=
CreateDCW
(
DISPLAYW
,
NULL
,
NULL
,
NULL
);
if
(
screen_dc
)
{
BITMAPINFO
*
pInfo
;
/* Make sure we have room for the monochrome bitmap later on.
* Note that BITMAPINFOINFO and BITMAPCOREHEADER are the same
* up to and including the biBitCount. In-memory icon resource
...
...
@@ -719,40 +748,47 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
* BYTE icAND[] // DIB bits for AND mask
*/
if
((
pInfo
=
HeapAlloc
(
GetProcessHeap
(),
0
,
max
(
size
,
sizeof
(
BITMAPINFOHEADER
)
+
2
*
sizeof
(
RGBQUAD
)))))
pSrcInfo
=
HeapAlloc
(
GetProcessHeap
(),
0
,
max
(
size
,
sizeof
(
BITMAPINFOHEADER
)
+
2
*
sizeof
(
RGBQUAD
)));
pDestInfo
=
HeapAlloc
(
GetProcessHeap
(),
0
,
max
(
size
,
sizeof
(
BITMAPINFOHEADER
)
+
2
*
sizeof
(
RGBQUAD
)));
if
(
pSrcInfo
&&
pDestInfo
)
{
memcpy
(
pInfo
,
bmi
,
size
);
pInfo
->
bmiHeader
.
biHeight
/=
2
;
memcpy
(
pSrcInfo
,
bmi
,
size
);
pSrcInfo
->
bmiHeader
.
biHeight
/=
2
;
memcpy
(
pDestInfo
,
bmi
,
size
);
pDestInfo
->
bmiHeader
.
biWidth
=
width
;
pDestInfo
->
bmiHeader
.
biHeight
=
height
;
pDestInfo
->
bmiHeader
.
biSizeImage
=
0
;
/* Create the XOR bitmap */
if
(
pSrcInfo
->
bmiHeader
.
biBitCount
==
32
)
{
void
*
pDIBBuffer
=
NULL
;
hXorBits
=
CreateDIBSection
(
screen_dc
,
pDestInfo
,
DIB_RGB_COLORS
,
&
pDIBBuffer
,
NULL
,
0
);
if
(
DoStretch
)
{
hXorBits
=
CreateCompatibleBitmap
(
screen_dc
,
width
,
height
);
if
(
hXorBits
)
{
HBITMAP
hOld
;
BOOL
res
=
FALSE
;
if
(
!
hdcMem
)
hdcMem
=
CreateCompatibleDC
(
screen_dc
);
if
(
hdcMem
)
{
hOld
=
SelectObject
(
hdcMem
,
hXorBits
);
res
=
StretchDIBits
(
hdcMem
,
0
,
0
,
width
,
height
,
0
,
0
,
bmi
->
bmiHeader
.
biWidth
,
bmi
->
bmiHeader
.
biHeight
/
2
,
(
char
*
)
bmi
+
size
,
pInfo
,
DIB_RGB_COLORS
,
SRCCOPY
);
SelectObject
(
hdcMem
,
hOld
);
if
(
!
stretch_blt_icon
(
hXorBits
,
pDestInfo
,
pSrcInfo
,
(
char
*
)
bmi
+
size
))
{
DeleteObject
(
hXorBits
);
hXorBits
=
0
;
}
if
(
!
res
)
{
DeleteObject
(
hXorBits
);
hXorBits
=
0
;
}
}
}
else
{
if
(
is_dib_monochrome
(
bmi
))
{
hXorBits
=
CreateBitmap
(
width
,
height
,
1
,
1
,
NULL
);
SetDIBits
(
screen_dc
,
hXorBits
,
0
,
height
,
(
char
*
)
bmi
+
size
,
pInfo
,
DIB_RGB_COLORS
);
}
else
hXorBits
=
CreateDIBitmap
(
screen_dc
,
&
pInfo
->
bmiHeader
,
CBM_INIT
,
(
char
*
)
bmi
+
size
,
pInfo
,
DIB_RGB_COLORS
);
{
hXorBits
=
CreateCompatibleBitmap
(
screen_dc
,
width
,
height
);
if
(
hXorBits
)
{
if
(
!
stretch_blt_icon
(
hXorBits
,
pDestInfo
,
pSrcInfo
,
(
char
*
)
bmi
+
size
))
{
DeleteObject
(
hXorBits
);
hXorBits
=
0
;
}
}
}
if
(
hXorBits
)
...
...
@@ -761,51 +797,42 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
get_dib_width_bytes
(
bmi
->
bmiHeader
.
biWidth
,
bmi
->
bmiHeader
.
biBitCount
)
*
abs
(
bmi
->
bmiHeader
.
biHeight
)
/
2
;
pInfo
->
bmiHeader
.
biBitCount
=
1
;
if
(
pInfo
->
bmiHeader
.
biSize
!=
sizeof
(
BITMAPCOREHEADER
))
p
Src
Info
->
bmiHeader
.
biBitCount
=
1
;
if
(
p
Src
Info
->
bmiHeader
.
biSize
!=
sizeof
(
BITMAPCOREHEADER
))
{
RGBQUAD
*
rgb
=
pInfo
->
bmiColors
;
RGBQUAD
*
rgb
=
p
Src
Info
->
bmiColors
;
p
Info
->
bmiHeader
.
biClrUsed
=
p
Info
->
bmiHeader
.
biClrImportant
=
2
;
p
SrcInfo
->
bmiHeader
.
biClrUsed
=
pSrc
Info
->
bmiHeader
.
biClrImportant
=
2
;
rgb
[
0
].
rgbBlue
=
rgb
[
0
].
rgbGreen
=
rgb
[
0
].
rgbRed
=
0x00
;
rgb
[
1
].
rgbBlue
=
rgb
[
1
].
rgbGreen
=
rgb
[
1
].
rgbRed
=
0xff
;
rgb
[
0
].
rgbReserved
=
rgb
[
1
].
rgbReserved
=
0
;
}
else
{
RGBTRIPLE
*
rgb
=
(
RGBTRIPLE
*
)(((
BITMAPCOREHEADER
*
)
pInfo
)
+
1
);
RGBTRIPLE
*
rgb
=
(
RGBTRIPLE
*
)(((
BITMAPCOREHEADER
*
)
p
Src
Info
)
+
1
);
rgb
[
0
].
rgbtBlue
=
rgb
[
0
].
rgbtGreen
=
rgb
[
0
].
rgbtRed
=
0x00
;
rgb
[
1
].
rgbtBlue
=
rgb
[
1
].
rgbtGreen
=
rgb
[
1
].
rgbtRed
=
0xff
;
}
/* Create the AND bitmap */
if
(
DoStretch
)
{
if
((
hAndBits
=
CreateBitmap
(
width
,
height
,
1
,
1
,
NULL
)))
{
HBITMAP
hOld
;
BOOL
res
=
FALSE
;
if
(
!
hdcMem
)
hdcMem
=
CreateCompatibleDC
(
screen_dc
);
if
(
hdcMem
)
{
hOld
=
SelectObject
(
hdcMem
,
hAndBits
);
res
=
StretchDIBits
(
hdcMem
,
0
,
0
,
width
,
height
,
0
,
0
,
pInfo
->
bmiHeader
.
biWidth
,
pInfo
->
bmiHeader
.
biHeight
,
xbits
,
pInfo
,
DIB_RGB_COLORS
,
SRCCOPY
);
SelectObject
(
hdcMem
,
hOld
);
}
if
(
!
res
)
{
DeleteObject
(
hAndBits
);
hAndBits
=
0
;
}
}
}
else
{
hAndBits
=
CreateBitmap
(
width
,
height
,
1
,
1
,
NULL
);
if
(
hAndBits
)
SetDIBits
(
screen_dc
,
hAndBits
,
0
,
height
,
xbits
,
pInfo
,
DIB_RGB_COLORS
);
if
(
!
stretch_blt_icon
(
hAndBits
,
pDestInfo
,
pSrcInfo
,
xbits
))
{
DeleteObject
(
hAndBits
);
hAndBits
=
0
;
}
if
(
!
hAndBits
)
{
DeleteObject
(
hXorBits
);
hXorBits
=
0
;
}
if
(
!
hAndBits
)
DeleteObject
(
hXorBits
);
}
HeapFree
(
GetProcessHeap
(),
0
,
pInfo
);
HeapFree
(
GetProcessHeap
(),
0
,
pSrcInfo
);
HeapFree
(
GetProcessHeap
(),
0
,
pDestInfo
);
}
}
...
...
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