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
2e363267
Commit
2e363267
authored
May 23, 2017
by
Huw Davies
Committed by
Alexandre Julliard
May 23, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Synthesize dibs or bitmaps as appropriate.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
e27708f2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
163 additions
and
7 deletions
+163
-7
datacache.c
dlls/ole32/datacache.c
+79
-7
ole2.c
dlls/ole32/tests/ole2.c
+84
-0
No files found.
dlls/ole32/datacache.c
View file @
2e363267
...
...
@@ -297,13 +297,21 @@ static void DataCache_Destroy(
static
DataCacheEntry
*
DataCache_GetEntryForFormatEtc
(
DataCache
*
This
,
const
FORMATETC
*
formatetc
)
{
DataCacheEntry
*
cache_entry
;
FORMATETC
fmt
=
*
formatetc
;
if
(
fmt
.
cfFormat
==
CF_BITMAP
)
{
fmt
.
cfFormat
=
CF_DIB
;
fmt
.
tymed
=
TYMED_HGLOBAL
;
}
LIST_FOR_EACH_ENTRY
(
cache_entry
,
&
This
->
cache_list
,
DataCacheEntry
,
entry
)
{
/* FIXME: also compare DVTARGETDEVICEs */
if
((
!
cache_entry
->
fmtetc
.
cfFormat
||
!
f
ormatetc
->
cfFormat
||
(
formatetc
->
cfFormat
==
cache_entry
->
fmtetc
.
cfFormat
))
&&
(
f
ormatetc
->
dwAspect
==
cache_entry
->
fmtetc
.
dwAspect
)
&&
(
f
ormatetc
->
lindex
==
cache_entry
->
fmtetc
.
lindex
)
&&
(
!
cache_entry
->
fmtetc
.
tymed
||
!
f
ormatetc
->
tymed
||
(
formatetc
->
tymed
==
cache_entry
->
fmtetc
.
tymed
)))
if
((
!
cache_entry
->
fmtetc
.
cfFormat
||
!
f
mt
.
cfFormat
||
(
fmt
.
cfFormat
==
cache_entry
->
fmtetc
.
cfFormat
))
&&
(
f
mt
.
dwAspect
==
cache_entry
->
fmtetc
.
dwAspect
)
&&
(
f
mt
.
lindex
==
cache_entry
->
fmtetc
.
lindex
)
&&
(
!
cache_entry
->
fmtetc
.
tymed
||
!
f
mt
.
tymed
||
(
fmt
.
tymed
==
cache_entry
->
fmtetc
.
tymed
)))
return
cache_entry
;
}
return
NULL
;
...
...
@@ -901,11 +909,56 @@ static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
return
S_OK
;
}
static
HGLOBAL
synthesize_dib
(
HBITMAP
bm
)
{
HDC
hdc
=
GetDC
(
0
);
BITMAPINFOHEADER
header
;
BITMAPINFO
*
bmi
;
HGLOBAL
ret
=
0
;
DWORD
header_size
;
memset
(
&
header
,
0
,
sizeof
(
header
)
);
header
.
biSize
=
sizeof
(
header
);
if
(
!
GetDIBits
(
hdc
,
bm
,
0
,
0
,
NULL
,
(
BITMAPINFO
*
)
&
header
,
DIB_RGB_COLORS
))
goto
done
;
header_size
=
bitmap_info_size
(
(
BITMAPINFO
*
)
&
header
,
DIB_RGB_COLORS
);
if
(
!
(
ret
=
GlobalAlloc
(
GMEM_MOVEABLE
,
header_size
+
header
.
biSizeImage
)))
goto
done
;
bmi
=
GlobalLock
(
ret
);
memset
(
bmi
,
0
,
header_size
);
memcpy
(
bmi
,
&
header
,
header
.
biSize
);
GetDIBits
(
hdc
,
bm
,
0
,
abs
(
header
.
biHeight
),
(
char
*
)
bmi
+
header_size
,
bmi
,
DIB_RGB_COLORS
);
GlobalUnlock
(
ret
);
done:
ReleaseDC
(
0
,
hdc
);
return
ret
;
}
static
HBITMAP
synthesize_bitmap
(
HGLOBAL
dib
)
{
HBITMAP
ret
=
0
;
BITMAPINFO
*
bmi
;
HDC
hdc
=
GetDC
(
0
);
if
((
bmi
=
GlobalLock
(
dib
)))
{
/* FIXME: validate data size */
ret
=
CreateDIBitmap
(
hdc
,
&
bmi
->
bmiHeader
,
CBM_INIT
,
(
char
*
)
bmi
+
bitmap_info_size
(
bmi
,
DIB_RGB_COLORS
),
bmi
,
DIB_RGB_COLORS
);
GlobalUnlock
(
dib
);
}
ReleaseDC
(
0
,
hdc
);
return
ret
;
}
static
HRESULT
DataCacheEntry_SetData
(
DataCacheEntry
*
cache_entry
,
const
FORMATETC
*
formatetc
,
const
STGMEDIUM
*
stgmedium
,
STGMEDIUM
*
stgmedium
,
BOOL
fRelease
)
{
STGMEDIUM
dib_copy
;
if
((
!
cache_entry
->
fmtetc
.
cfFormat
&&
!
formatetc
->
cfFormat
)
||
(
cache_entry
->
fmtetc
.
tymed
==
TYMED_NULL
&&
formatetc
->
tymed
==
TYMED_NULL
)
||
stgmedium
->
tymed
==
TYMED_NULL
)
...
...
@@ -917,6 +970,17 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
cache_entry
->
dirty
=
TRUE
;
ReleaseStgMedium
(
&
cache_entry
->
stgmedium
);
cache_entry
->
data_cf
=
cache_entry
->
fmtetc
.
cfFormat
?
cache_entry
->
fmtetc
.
cfFormat
:
formatetc
->
cfFormat
;
if
(
formatetc
->
cfFormat
==
CF_BITMAP
)
{
dib_copy
.
tymed
=
TYMED_HGLOBAL
;
dib_copy
.
u
.
hGlobal
=
synthesize_dib
(
stgmedium
->
u
.
hBitmap
);
dib_copy
.
pUnkForRelease
=
NULL
;
if
(
fRelease
)
ReleaseStgMedium
(
stgmedium
);
stgmedium
=
&
dib_copy
;
fRelease
=
TRUE
;
}
if
(
fRelease
)
{
cache_entry
->
stgmedium
=
*
stgmedium
;
...
...
@@ -927,7 +991,7 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
&
cache_entry
->
stgmedium
,
stgmedium
);
}
static
HRESULT
DataCacheEntry_GetData
(
DataCacheEntry
*
cache_entry
,
STGMEDIUM
*
stgmedium
)
static
HRESULT
DataCacheEntry_GetData
(
DataCacheEntry
*
cache_entry
,
FORMATETC
*
fmt
,
STGMEDIUM
*
stgmedium
)
{
if
(
cache_entry
->
stgmedium
.
tymed
==
TYMED_NULL
&&
cache_entry
->
stream
)
{
...
...
@@ -937,6 +1001,14 @@ static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, STGMEDIUM *st
}
if
(
cache_entry
->
stgmedium
.
tymed
==
TYMED_NULL
)
return
OLE_E_BLANK
;
if
(
fmt
->
cfFormat
==
CF_BITMAP
)
{
stgmedium
->
tymed
=
TYMED_GDI
;
stgmedium
->
u
.
hBitmap
=
synthesize_bitmap
(
cache_entry
->
stgmedium
.
u
.
hGlobal
);
stgmedium
->
pUnkForRelease
=
NULL
;
return
S_OK
;
}
return
copy_stg_medium
(
cache_entry
->
data_cf
,
stgmedium
,
&
cache_entry
->
stgmedium
);
}
...
...
@@ -1109,7 +1181,7 @@ static HRESULT WINAPI DataCache_GetData(
if
(
!
cache_entry
)
return
OLE_E_BLANK
;
return
DataCacheEntry_GetData
(
cache_entry
,
pmedium
);
return
DataCacheEntry_GetData
(
cache_entry
,
p
formatetcIn
,
p
medium
);
}
static
HRESULT
WINAPI
DataCache_GetDataHere
(
...
...
dlls/ole32/tests/ole2.c
View file @
2e363267
...
...
@@ -1993,6 +1993,18 @@ static IStorage *create_storage( int num )
return
stg
;
}
static
HGLOBAL
create_dib
(
void
)
{
HGLOBAL
h
;
void
*
ptr
;
h
=
GlobalAlloc
(
GMEM_MOVEABLE
,
sizeof
(
dib
)
-
sizeof
(
BITMAPFILEHEADER
)
);
ptr
=
GlobalLock
(
h
);
memcpy
(
ptr
,
dib
+
sizeof
(
BITMAPFILEHEADER
),
sizeof
(
dib
)
-
sizeof
(
BITMAPFILEHEADER
)
);
GlobalUnlock
(
h
);
return
h
;
}
static
void
test_data_cache_dib_contents_stream
(
int
num
)
{
HRESULT
hr
;
...
...
@@ -2083,12 +2095,33 @@ static void test_data_cache_dib_contents_stream(int num)
IUnknown_Release
(
unk
);
}
static
void
check_bitmap_size
(
HBITMAP
h
,
int
cx
,
int
cy
)
{
BITMAP
bm
;
GetObjectW
(
h
,
sizeof
(
bm
),
&
bm
);
ok
(
bm
.
bmWidth
==
cx
,
"got %d expect %d
\n
"
,
bm
.
bmWidth
,
cx
);
ok
(
bm
.
bmHeight
==
cy
,
"got %d expect %d
\n
"
,
bm
.
bmHeight
,
cy
);
}
static
void
check_dib_size
(
HGLOBAL
h
,
int
cx
,
int
cy
)
{
BITMAPINFO
*
info
;
info
=
GlobalLock
(
h
);
ok
(
info
->
bmiHeader
.
biWidth
==
cx
,
"got %d expect %d
\n
"
,
info
->
bmiHeader
.
biWidth
,
cx
);
ok
(
info
->
bmiHeader
.
biHeight
==
cy
,
"got %d expect %d
\n
"
,
info
->
bmiHeader
.
biHeight
,
cy
);
GlobalUnlock
(
h
);
}
static
void
test_data_cache_bitmap
(
void
)
{
HRESULT
hr
;
IOleCache2
*
cache
;
IDataObject
*
data
;
FORMATETC
fmt
;
DWORD
conn
;
STGMEDIUM
med
;
STATDATA
expect
[]
=
{
{{
CF_DIB
,
0
,
DVASPECT_CONTENT
,
-
1
,
TYMED_HGLOBAL
},
0
,
NULL
,
0
},
...
...
@@ -2165,6 +2198,57 @@ static void test_data_cache_bitmap(void)
check_enum_cache
(
cache
,
expect
,
2
);
/* Try setting a 1x1 bitmap */
hr
=
IOleCache2_QueryInterface
(
cache
,
&
IID_IDataObject
,
(
void
**
)
&
data
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
med
.
tymed
=
TYMED_GDI
;
U
(
med
).
hBitmap
=
CreateBitmap
(
1
,
1
,
1
,
1
,
NULL
);
med
.
pUnkForRelease
=
NULL
;
hr
=
IOleCache2_SetData
(
cache
,
&
fmt
,
&
med
,
TRUE
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
IDataObject_GetData
(
data
,
&
fmt
,
&
med
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
ok
(
med
.
tymed
==
TYMED_GDI
,
"got %d
\n
"
,
med
.
tymed
);
check_bitmap_size
(
U
(
med
).
hBitmap
,
1
,
1
);
ReleaseStgMedium
(
&
med
);
fmt
.
cfFormat
=
CF_DIB
;
fmt
.
tymed
=
TYMED_HGLOBAL
;
hr
=
IDataObject_GetData
(
data
,
&
fmt
,
&
med
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
ok
(
med
.
tymed
==
TYMED_HGLOBAL
,
"got %d
\n
"
,
med
.
tymed
);
check_dib_size
(
U
(
med
).
hGlobal
,
1
,
1
);
ReleaseStgMedium
(
&
med
);
/* Now set a 2x1 dib */
fmt
.
cfFormat
=
CF_DIB
;
fmt
.
tymed
=
TYMED_HGLOBAL
;
med
.
tymed
=
TYMED_HGLOBAL
;
U
(
med
).
hGlobal
=
create_dib
();
hr
=
IOleCache2_SetData
(
cache
,
&
fmt
,
&
med
,
TRUE
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
fmt
.
cfFormat
=
CF_BITMAP
;
fmt
.
tymed
=
TYMED_GDI
;
hr
=
IDataObject_GetData
(
data
,
&
fmt
,
&
med
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
ok
(
med
.
tymed
==
TYMED_GDI
,
"got %d
\n
"
,
med
.
tymed
);
check_bitmap_size
(
U
(
med
).
hBitmap
,
2
,
1
);
ReleaseStgMedium
(
&
med
);
fmt
.
cfFormat
=
CF_DIB
;
fmt
.
tymed
=
TYMED_HGLOBAL
;
hr
=
IDataObject_GetData
(
data
,
&
fmt
,
&
med
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
ok
(
med
.
tymed
==
TYMED_HGLOBAL
,
"got %d
\n
"
,
med
.
tymed
);
check_dib_size
(
U
(
med
).
hGlobal
,
2
,
1
);
ReleaseStgMedium
(
&
med
);
IDataObject_Release
(
data
);
IOleCache2_Release
(
cache
);
}
...
...
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