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
edea44f0
Commit
edea44f0
authored
Sep 12, 2012
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winex11: Add support for the LWA_COLORKEY layered window attribute.
parent
425f0a25
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
213 additions
and
8 deletions
+213
-8
bitblt.c
dlls/winex11.drv/bitblt.c
+192
-2
window.c
dlls/winex11.drv/window.c
+19
-5
x11drv.h
dlls/winex11.drv/x11drv.h
+2
-1
No files found.
dlls/winex11.drv/bitblt.c
View file @
edea44f0
...
...
@@ -26,12 +26,19 @@
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#ifdef HAVE_LIBXSHAPE
#include <X11/extensions/shape.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winternl.h"
#include "x11drv.h"
#include "winternl.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
bitblt
);
...
...
@@ -1538,6 +1545,7 @@ struct x11drv_window_surface
XImage
*
image
;
RECT
bounds
;
BOOL
is_r8g8b8
;
COLORREF
color_key
;
struct
gdi_image_bits
bits
;
CRITICAL_SECTION
crit
;
BITMAPINFO
info
;
/* variable size, must be last */
...
...
@@ -1548,6 +1556,169 @@ static struct x11drv_window_surface *get_x11_surface( struct window_surface *sur
return
(
struct
x11drv_window_surface
*
)
surface
;
}
static
inline
UINT
get_color_component
(
UINT
color
,
UINT
mask
)
{
int
shift
;
for
(
shift
=
0
;
!
(
mask
&
1
);
shift
++
)
mask
>>=
1
;
return
(
color
*
mask
/
255
)
<<
shift
;
}
static
inline
void
flush_rgn_data
(
HRGN
rgn
,
RGNDATA
*
data
)
{
HRGN
tmp
=
ExtCreateRegion
(
NULL
,
data
->
rdh
.
dwSize
+
data
->
rdh
.
nRgnSize
,
data
);
CombineRgn
(
rgn
,
rgn
,
tmp
,
RGN_OR
);
DeleteObject
(
tmp
);
data
->
rdh
.
nCount
=
0
;
}
static
inline
void
add_row
(
HRGN
rgn
,
RGNDATA
*
data
,
int
x
,
int
y
,
int
len
)
{
RECT
*
rect
=
(
RECT
*
)
data
->
Buffer
+
data
->
rdh
.
nCount
;
if
(
len
<=
0
)
return
;
rect
->
left
=
x
;
rect
->
top
=
y
;
rect
->
right
=
x
+
len
;
rect
->
bottom
=
y
+
1
;
data
->
rdh
.
nCount
++
;
if
(
data
->
rdh
.
nCount
*
sizeof
(
RECT
)
>
data
->
rdh
.
nRgnSize
-
sizeof
(
RECT
))
flush_rgn_data
(
rgn
,
data
);
}
/***********************************************************************
* update_surface_region
*/
static
void
update_surface_region
(
struct
x11drv_window_surface
*
surface
)
{
#ifdef HAVE_LIBXSHAPE
char
buffer
[
4096
];
RGNDATA
*
data
=
(
RGNDATA
*
)
buffer
;
BITMAPINFO
*
info
=
&
surface
->
info
;
UINT
*
masks
=
(
UINT
*
)
info
->
bmiColors
;
int
x
,
y
,
start
,
width
;
HRGN
rgn
;
if
(
surface
->
color_key
==
CLR_INVALID
)
{
XShapeCombineMask
(
gdi_display
,
surface
->
window
,
ShapeBounding
,
0
,
0
,
None
,
ShapeSet
);
return
;
}
data
->
rdh
.
dwSize
=
sizeof
(
data
->
rdh
);
data
->
rdh
.
iType
=
RDH_RECTANGLES
;
data
->
rdh
.
nCount
=
0
;
data
->
rdh
.
nRgnSize
=
sizeof
(
buffer
)
-
sizeof
(
data
->
rdh
);
rgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
width
=
surface
->
header
.
rect
.
right
-
surface
->
header
.
rect
.
left
;
switch
(
info
->
bmiHeader
.
biBitCount
)
{
case
16
:
{
WORD
*
bits
=
surface
->
bits
.
ptr
;
int
stride
=
(
width
+
1
)
&
~
1
;
UINT
mask
=
masks
[
0
]
|
masks
[
1
]
|
masks
[
2
];
for
(
y
=
surface
->
header
.
rect
.
top
;
y
<
surface
->
header
.
rect
.
bottom
;
y
++
,
bits
+=
stride
)
{
x
=
0
;
while
(
x
<
width
)
{
while
(
x
<
width
&&
(
bits
[
x
]
&
mask
)
==
surface
->
color_key
)
x
++
;
start
=
x
;
while
(
x
<
width
&&
(
bits
[
x
]
&
mask
)
!=
surface
->
color_key
)
x
++
;
add_row
(
rgn
,
data
,
surface
->
header
.
rect
.
left
+
start
,
y
,
x
-
start
);
}
}
break
;
}
case
24
:
{
BYTE
*
bits
=
surface
->
bits
.
ptr
;
int
stride
=
(
width
*
3
+
3
)
&
~
3
;
for
(
y
=
surface
->
header
.
rect
.
top
;
y
<
surface
->
header
.
rect
.
bottom
;
y
++
,
bits
+=
stride
)
{
x
=
0
;
while
(
x
<
width
)
{
while
(
x
<
width
&&
(
bits
[
x
*
3
]
==
GetBValue
(
surface
->
color_key
))
&&
(
bits
[
x
*
3
+
1
]
==
GetGValue
(
surface
->
color_key
))
&&
(
bits
[
x
*
3
+
2
]
==
GetRValue
(
surface
->
color_key
)))
x
++
;
start
=
x
;
while
(
x
<
width
&&
((
bits
[
x
*
3
]
!=
GetBValue
(
surface
->
color_key
))
||
(
bits
[
x
*
3
+
1
]
!=
GetGValue
(
surface
->
color_key
))
||
(
bits
[
x
*
3
+
2
]
!=
GetRValue
(
surface
->
color_key
))))
x
++
;
add_row
(
rgn
,
data
,
surface
->
header
.
rect
.
left
+
start
,
y
,
x
-
start
);
}
}
break
;
}
case
32
:
{
DWORD
*
bits
=
surface
->
bits
.
ptr
;
UINT
mask
=
info
->
bmiHeader
.
biCompression
==
BI_RGB
?
0xffffff
:
(
masks
[
0
]
|
masks
[
1
]
|
masks
[
2
]);
for
(
y
=
surface
->
header
.
rect
.
top
;
y
<
surface
->
header
.
rect
.
bottom
;
y
++
,
bits
+=
width
)
{
x
=
0
;
while
(
x
<
width
)
{
while
(
x
<
width
&&
(
bits
[
x
]
&
mask
)
==
surface
->
color_key
)
x
++
;
start
=
x
;
while
(
x
<
width
&&
(
bits
[
x
]
&
mask
)
!=
surface
->
color_key
)
x
++
;
add_row
(
rgn
,
data
,
surface
->
header
.
rect
.
left
+
start
,
y
,
x
-
start
);
}
}
break
;
}
default:
assert
(
0
);
}
if
(
data
->
rdh
.
nCount
)
flush_rgn_data
(
rgn
,
data
);
if
((
data
=
X11DRV_GetRegionData
(
rgn
,
0
)))
{
XShapeCombineRectangles
(
gdi_display
,
surface
->
window
,
ShapeBounding
,
0
,
0
,
(
XRectangle
*
)
data
->
Buffer
,
data
->
rdh
.
nCount
,
ShapeSet
,
YXBanded
);
HeapFree
(
GetProcessHeap
(),
0
,
data
);
}
DeleteObject
(
rgn
);
#endif
}
/***********************************************************************
* set_color_key
*/
static
void
set_color_key
(
struct
x11drv_window_surface
*
surface
,
COLORREF
key
)
{
UINT
*
masks
=
(
UINT
*
)
surface
->
info
.
bmiColors
;
if
(
key
==
CLR_INVALID
)
surface
->
color_key
=
CLR_INVALID
;
else
if
(
surface
->
info
.
bmiHeader
.
biBitCount
<=
8
)
surface
->
color_key
=
CLR_INVALID
;
else
if
(
key
&
(
1
<<
24
))
/* PALETTEINDEX */
surface
->
color_key
=
0
;
else
if
(
key
>>
16
==
0x10ff
)
/* DIBINDEX */
surface
->
color_key
=
0
;
else
if
(
surface
->
info
.
bmiHeader
.
biBitCount
==
24
)
surface
->
color_key
=
key
;
else
if
(
surface
->
info
.
bmiHeader
.
biCompression
==
BI_RGB
)
surface
->
color_key
=
(
GetRValue
(
key
)
<<
16
)
|
(
GetGValue
(
key
)
<<
8
)
|
GetBValue
(
key
);
else
surface
->
color_key
=
get_color_component
(
GetRValue
(
key
),
masks
[
0
]
)
|
get_color_component
(
GetGValue
(
key
),
masks
[
1
]
)
|
get_color_component
(
GetBValue
(
key
),
masks
[
2
]
);
}
/***********************************************************************
* x11drv_surface_lock
*/
...
...
@@ -1611,6 +1782,8 @@ static void x11drv_surface_flush( struct window_surface *window_surface )
surface
,
coords
.
width
,
coords
.
height
,
wine_dbgstr_rect
(
&
surface
->
bounds
),
surface
->
bits
.
ptr
);
if
(
surface
->
color_key
!=
CLR_INVALID
)
update_surface_region
(
surface
);
if
(
surface
->
image
->
bits_per_pixel
==
4
||
surface
->
image
->
bits_per_pixel
==
8
)
mapping
=
X11DRV_PALETTE_PaletteToXPixel
;
...
...
@@ -1662,7 +1835,8 @@ static const struct window_surface_funcs x11drv_surface_funcs =
/***********************************************************************
* create_surface
*/
struct
window_surface
*
create_surface
(
Window
window
,
const
XVisualInfo
*
vis
,
const
RECT
*
rect
)
struct
window_surface
*
create_surface
(
Window
window
,
const
XVisualInfo
*
vis
,
const
RECT
*
rect
,
COLORREF
color_key
)
{
const
XPixmapFormatValues
*
format
=
pixmap_formats
[
vis
->
depth
];
struct
x11drv_window_surface
*
surface
;
...
...
@@ -1688,6 +1862,7 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co
surface
->
header
.
ref
=
1
;
surface
->
window
=
window
;
surface
->
is_r8g8b8
=
is_r8g8b8
(
vis
);
set_color_key
(
surface
,
color_key
);
reset_bounds
(
&
surface
->
bounds
);
if
(
!
(
surface
->
bits
.
ptr
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
surface
->
info
.
bmiHeader
.
biSizeImage
)))
...
...
@@ -1709,3 +1884,18 @@ failed:
x11drv_surface_destroy
(
&
surface
->
header
);
return
NULL
;
}
/***********************************************************************
* set_surface_color_key
*/
void
set_surface_color_key
(
struct
window_surface
*
window_surface
,
COLORREF
color_key
)
{
struct
x11drv_window_surface
*
surface
=
get_x11_surface
(
window_surface
);
COLORREF
prev
;
window_surface
->
funcs
->
lock
(
window_surface
);
prev
=
surface
->
color_key
;
set_color_key
(
surface
,
color_key
);
if
(
surface
->
color_key
!=
prev
)
update_surface_region
(
surface
);
window_surface
->
funcs
->
unlock
(
window_surface
);
}
dlls/winex11.drv/window.c
View file @
edea44f0
...
...
@@ -396,8 +396,6 @@ static void sync_window_opacity( Display *display, Window win,
if
(
flags
&
LWA_ALPHA
)
opacity
=
(
0xffffffff
/
0xff
)
*
alpha
;
if
(
flags
&
LWA_COLORKEY
)
FIXME
(
"LWA_COLORKEY not supported
\n
"
);
if
(
opacity
==
0xffffffff
)
XDeleteProperty
(
display
,
win
,
x11drv_atom
(
_NET_WM_WINDOW_OPACITY
)
);
else
...
...
@@ -1447,7 +1445,10 @@ void CDECL X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
set_wm_hints
(
thread_display
(),
data
);
if
(
offset
==
GWL_EXSTYLE
&&
(
changed
&
WS_EX_LAYERED
))
/* changing WS_EX_LAYERED resets attributes */
{
sync_window_opacity
(
thread_display
(),
data
->
whole_window
,
0
,
0
,
0
);
if
(
data
->
surface
)
set_surface_color_key
(
data
->
surface
,
CLR_INVALID
);
}
}
...
...
@@ -1971,6 +1972,9 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
struct
x11drv_win_data
*
data
=
X11DRV_get_win_data
(
hwnd
);
RECT
surface_rect
;
XVisualInfo
vis
;
DWORD
flags
;
COLORREF
key
;
BOOL
layered
=
GetWindowLongW
(
hwnd
,
GWL_EXSTYLE
)
&
WS_EX_LAYERED
;
if
(
!
data
&&
!
(
data
=
X11DRV_create_win_data
(
hwnd
,
window_rect
,
client_rect
)))
return
;
...
...
@@ -1991,7 +1995,7 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
if
(
swp_flags
&
SWP_HIDEWINDOW
)
return
;
if
(
data
->
whole_window
==
root_window
)
return
;
if
(
has_gl_drawable
(
hwnd
))
return
;
if
(
!
client_side_graphics
)
return
;
if
(
!
client_side_graphics
&&
!
layered
)
return
;
surface_rect
=
get_surface_rect
(
visible_rect
);
if
(
data
->
surface
)
...
...
@@ -2013,7 +2017,10 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
vis
.
red_mask
=
visual
->
red_mask
;
vis
.
green_mask
=
visual
->
green_mask
;
vis
.
blue_mask
=
visual
->
blue_mask
;
*
surface
=
create_surface
(
data
->
whole_window
,
&
vis
,
&
surface_rect
);
if
(
!
layered
||
!
GetLayeredWindowAttributes
(
hwnd
,
&
key
,
NULL
,
&
flags
)
||
!
(
flags
&
LWA_COLORKEY
))
key
=
CLR_INVALID
;
*
surface
=
create_surface
(
data
->
whole_window
,
&
vis
,
&
surface_rect
,
key
);
}
...
...
@@ -2239,11 +2246,18 @@ void CDECL X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alph
{
if
(
data
->
whole_window
)
sync_window_opacity
(
thread_display
(),
data
->
whole_window
,
key
,
alpha
,
flags
);
if
(
data
->
surface
)
set_surface_color_key
(
data
->
surface
,
(
flags
&
LWA_COLORKEY
)
?
key
:
CLR_INVALID
);
}
else
{
Window
win
=
X11DRV_get_whole_window
(
hwnd
);
if
(
win
)
sync_window_opacity
(
gdi_display
,
win
,
key
,
alpha
,
flags
);
if
(
win
)
{
sync_window_opacity
(
gdi_display
,
win
,
key
,
alpha
,
flags
);
if
(
flags
&
LWA_COLORKEY
)
FIXME
(
"LWA_COLORKEY not supported on foreign thread window %p
\n
"
,
hwnd
);
}
}
}
...
...
dlls/winex11.drv/x11drv.h
View file @
edea44f0
...
...
@@ -190,7 +190,8 @@ extern Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const B
const
struct
gdi_image_bits
*
bits
,
UINT
coloruse
)
DECLSPEC_HIDDEN
;
extern
DWORD
get_pixmap_image
(
Pixmap
pixmap
,
int
width
,
int
height
,
const
XVisualInfo
*
vis
,
BITMAPINFO
*
info
,
struct
gdi_image_bits
*
bits
)
DECLSPEC_HIDDEN
;
extern
struct
window_surface
*
create_surface
(
Window
window
,
const
XVisualInfo
*
vis
,
const
RECT
*
rect
)
DECLSPEC_HIDDEN
;
extern
struct
window_surface
*
create_surface
(
Window
window
,
const
XVisualInfo
*
vis
,
const
RECT
*
rect
,
COLORREF
color_key
)
DECLSPEC_HIDDEN
;
extern
void
set_surface_color_key
(
struct
window_surface
*
window_surface
,
COLORREF
color_key
)
DECLSPEC_HIDDEN
;
extern
RGNDATA
*
X11DRV_GetRegionData
(
HRGN
hrgn
,
HDC
hdc_lptodp
)
DECLSPEC_HIDDEN
;
extern
BOOL
add_extra_clipping_region
(
X11DRV_PDEVICE
*
dev
,
HRGN
rgn
)
DECLSPEC_HIDDEN
;
...
...
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