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
37b33a9d
Commit
37b33a9d
authored
Mar 07, 2013
by
Ken Thomases
Committed by
Alexandre Julliard
Mar 08, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Improve handling of "invert" pixels in monochrome cursors.
parent
05d56542
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
79 additions
and
30 deletions
+79
-30
mouse.c
dlls/winemac.drv/mouse.c
+79
-30
No files found.
dlls/winemac.drv/mouse.c
View file @
37b33a9d
...
...
@@ -258,21 +258,6 @@ done:
}
/***********************************************************************
* release_provider_cfdata
*
* Helper for create_monochrome_cursor. A CFData is used by two
* different CGDataProviders, using different offsets. One of them is
* constructed with a pointer to the bytes, not a reference to the
* CFData object (because of the offset). So, the CFData is CFRetain'ed
* on its behalf at creation and released here.
*/
void
release_provider_cfdata
(
void
*
info
,
const
void
*
data
,
size_t
size
)
{
CFRelease
(
info
);
}
/***********************************************************************
* create_monochrome_cursor
*/
CFArrayRef
create_monochrome_cursor
(
HDC
hdc
,
const
ICONINFOEXW
*
icon
,
int
width
,
int
height
)
...
...
@@ -280,6 +265,9 @@ CFArrayRef create_monochrome_cursor(HDC hdc, const ICONINFOEXW *icon, int width,
char
buffer
[
FIELD_OFFSET
(
BITMAPINFO
,
bmiColors
[
256
])];
BITMAPINFO
*
info
=
(
BITMAPINFO
*
)
buffer
;
unsigned
int
width_bytes
=
(
width
+
31
)
/
32
*
4
;
unsigned
long
*
and_bits
=
NULL
,
*
xor_bits
;
unsigned
long
*
data_bits
;
int
count
,
i
;
CGColorSpaceRef
colorspace
;
CFMutableDataRef
data
;
CGDataProviderRef
provider
;
...
...
@@ -306,43 +294,86 @@ CFArrayRef create_monochrome_cursor(HDC hdc, const ICONINFOEXW *icon, int width,
info
->
bmiHeader
.
biClrUsed
=
0
;
info
->
bmiHeader
.
biClrImportant
=
0
;
/* This will be owned by the data provider for the mask image and released
when it is destroyed. */
data
=
CFDataCreateMutable
(
NULL
,
info
->
bmiHeader
.
biSizeImage
);
if
(
!
data
)
and_bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
info
->
bmiHeader
.
biSizeImage
);
if
(
!
and_bits
)
{
WARN
(
"failed to
create data
\n
"
);
WARN
(
"failed to
allocate and_bits
\n
"
);
return
NULL
;
}
CFDataSetLength
(
data
,
info
->
bmiHeader
.
biSizeImage
);
xor_bits
=
(
unsigned
long
*
)((
char
*
)
and_bits
+
info
->
bmiHeader
.
biSizeImage
/
2
);
if
(
!
GetDIBits
(
hdc
,
icon
->
hbmMask
,
0
,
height
*
2
,
CFDataGetMutableBytePtr
(
data
)
,
info
,
DIB_RGB_COLORS
))
if
(
!
GetDIBits
(
hdc
,
icon
->
hbmMask
,
0
,
height
*
2
,
and_bits
,
info
,
DIB_RGB_COLORS
))
{
WARN
(
"GetDIBits failed
\n
"
);
CFRelease
(
data
);
HeapFree
(
GetProcessHeap
(),
0
,
and_bits
);
return
NULL
;
}
/* On Windows, the pixels of a monochrome cursor can have four effects:
draw black, draw white, leave unchanged (transparent), or invert. The Mac
only supports the first three. It can't do pixels which invert the
background. Since the background is usually white, I am arbitrarily
mapping "invert" to "draw black". This entails bitwise math between the
cursor's AND mask and XOR mask:
AND | XOR | Windows cursor pixel
--------------------------------
0 | 0 | black
0 | 1 | white
1 | 0 | transparent
1 | 1 | invert
AND | XOR | Mac image
---------------------
0 | 0 | black (0)
0 | 1 | white (1)
1 | 0 | don't care
1 | 1 | black (0)
AND | XOR | Mac mask
---------------------------
0 | 0 | paint (0)
0 | 1 | paint (0)
1 | 0 | don't paint (1)
1 | 1 | paint (0)
So, Mac image = AND ^ XOR and Mac mask = AND & ~XOR.
*/
/* Create data for Mac image. */
data
=
CFDataCreateMutable
(
NULL
,
info
->
bmiHeader
.
biSizeImage
/
2
);
if
(
!
data
)
{
WARN
(
"failed to create data
\n
"
);
HeapFree
(
GetProcessHeap
(),
0
,
and_bits
);
return
NULL
;
}
/* image data = AND mask */
CFDataAppendBytes
(
data
,
(
UInt8
*
)
and_bits
,
info
->
bmiHeader
.
biSizeImage
/
2
);
/* image data ^= XOR mask */
data_bits
=
(
unsigned
long
*
)
CFDataGetMutableBytePtr
(
data
);
count
=
(
info
->
bmiHeader
.
biSizeImage
/
2
)
/
sizeof
(
*
data_bits
);
for
(
i
=
0
;
i
<
count
;
i
++
)
data_bits
[
i
]
^=
xor_bits
[
i
];
colorspace
=
CGColorSpaceCreateWithName
(
kCGColorSpaceGenericGray
);
if
(
!
colorspace
)
{
WARN
(
"failed to create colorspace
\n
"
);
CFRelease
(
data
);
HeapFree
(
GetProcessHeap
(),
0
,
and_bits
);
return
NULL
;
}
/* The data object needs to live as long as this provider, so retain it an
extra time and have the provider's data-release callback release it. */
provider
=
CGDataProviderCreateWithData
(
data
,
CFDataGetBytePtr
(
data
)
+
width_bytes
*
height
,
width_bytes
*
height
,
release_provider_cfdata
);
provider
=
CGDataProviderCreateWithCFData
(
data
);
CFRelease
(
data
);
if
(
!
provider
)
{
WARN
(
"failed to create data provider
\n
"
);
CGColorSpaceRelease
(
colorspace
);
CFRelease
(
data
);
HeapFree
(
GetProcessHeap
(),
0
,
and_bits
);
return
NULL
;
}
CFRetain
(
data
);
cgimage
=
CGImageCreate
(
width
,
height
,
1
,
1
,
width_bytes
,
colorspace
,
kCGImageAlphaNone
|
kCGBitmapByteOrderDefault
,
...
...
@@ -352,10 +383,28 @@ CFArrayRef create_monochrome_cursor(HDC hdc, const ICONINFOEXW *icon, int width,
if
(
!
cgimage
)
{
WARN
(
"failed to create image
\n
"
);
CFRelease
(
data
);
HeapFree
(
GetProcessHeap
(),
0
,
and_bits
);
return
NULL
;
}
/* Create data for mask. */
data
=
CFDataCreateMutable
(
NULL
,
info
->
bmiHeader
.
biSizeImage
/
2
);
if
(
!
data
)
{
WARN
(
"failed to create data
\n
"
);
CGImageRelease
(
cgimage
);
HeapFree
(
GetProcessHeap
(),
0
,
and_bits
);
return
NULL
;
}
/* mask data = AND mask */
CFDataAppendBytes
(
data
,
(
UInt8
*
)
and_bits
,
info
->
bmiHeader
.
biSizeImage
/
2
);
/* mask data &= ~XOR mask */
data_bits
=
(
unsigned
long
*
)
CFDataGetMutableBytePtr
(
data
);
for
(
i
=
0
;
i
<
count
;
i
++
)
data_bits
[
i
]
&=
~
xor_bits
[
i
];
HeapFree
(
GetProcessHeap
(),
0
,
and_bits
);
provider
=
CGDataProviderCreateWithCFData
(
data
);
CFRelease
(
data
);
if
(
!
provider
)
...
...
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