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
2d4bcc47
Commit
2d4bcc47
authored
Jan 14, 2013
by
Ken Thomases
Committed by
Alexandre Julliard
Jan 15, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Implement SetWindowRgn.
parent
7d6ebfa7
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
250 additions
and
16 deletions
+250
-16
cocoa_window.h
dlls/winemac.drv/cocoa_window.h
+3
-0
cocoa_window.m
dlls/winemac.drv/cocoa_window.m
+81
-0
macdrv.h
dlls/winemac.drv/macdrv.h
+7
-0
macdrv_cocoa.h
dlls/winemac.drv/macdrv_cocoa.h
+1
-0
window.c
dlls/winemac.drv/window.c
+156
-16
winemac.drv.spec
dlls/winemac.drv/winemac.drv.spec
+2
-0
No files found.
dlls/winemac.drv/cocoa_window.h
View file @
2d4bcc47
...
...
@@ -31,6 +31,9 @@
void
*
surface
;
pthread_mutex_t
*
surface_mutex
;
NSBezierPath
*
shape
;
BOOL
shapeChangedSinceLastDraw
;
}
@end
dlls/winemac.drv/cocoa_window.m
View file @
2d4bcc47
...
...
@@ -68,6 +68,10 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
@property
(
nonatomic
)
void
*
surface
;
@property
(
nonatomic
)
pthread_mutex_t
*
surface_mutex
;
@property
(
copy
,
nonatomic
)
NSBezierPath
*
shape
;
@property
(
nonatomic
)
BOOL
shapeChangedSinceLastDraw
;
@property
(
readonly
,
nonatomic
)
BOOL
needsTransparency
;
+
(
void
)
flipRect
:(
NSRect
*
)
rect
;
@end
...
...
@@ -111,11 +115,19 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
[
surfaceClip
addClip
];
}
[
window
.
shape
addClip
];
context
=
(
CGContextRef
)[[
NSGraphicsContext
currentContext
]
graphicsPort
];
CGContextSetBlendMode
(
context
,
kCGBlendModeCopy
);
CGContextDrawImage
(
context
,
imageRect
,
image
);
CGImageRelease
(
image
);
if
(
window
.
shapeChangedSinceLastDraw
)
{
window
.
shapeChangedSinceLastDraw
=
FALSE
;
[
window
invalidateShadow
];
}
}
}
...
...
@@ -130,6 +142,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
@synthesize
disabled
,
noActivate
,
floating
,
latentParentWindow
;
@synthesize
surface
,
surface_mutex
;
@synthesize
shape
,
shapeChangedSinceLastDraw
;
+
(
WineWindow
*
)
createWindowWithFeatures
:(
const
struct
macdrv_window_features
*
)
wf
windowFrame
:(
NSRect
)
window_frame
...
...
@@ -171,6 +184,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
-
(
void
)
dealloc
{
[
latentParentWindow
release
];
[
shape
release
];
[
super
dealloc
];
}
...
...
@@ -322,6 +336,44 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
}
}
-
(
BOOL
)
needsTransparency
{
return
(
self
.
shape
!=
nil
);
}
-
(
void
)
checkTransparency
{
if
(
!
[
self
isOpaque
]
&&
!
self
.
needsTransparency
)
{
[
self
setBackgroundColor
:[
NSColor
windowBackgroundColor
]];
[
self
setOpaque
:
YES
];
}
else
if
([
self
isOpaque
]
&&
self
.
needsTransparency
)
{
[
self
setBackgroundColor
:[
NSColor
clearColor
]];
[
self
setOpaque
:
NO
];
}
}
-
(
void
)
setShape
:
(
NSBezierPath
*
)
newShape
{
if
(
shape
==
newShape
)
return
;
if
(
shape
&&
newShape
&&
[
shape
isEqual
:
newShape
])
return
;
if
(
shape
)
{
[[
self
contentView
]
setNeedsDisplayInRect
:[
shape
bounds
]];
[
shape
release
];
}
if
(
newShape
)
[[
self
contentView
]
setNeedsDisplayInRect
:[
newShape
bounds
]];
shape
=
[
newShape
copy
];
self
.
shapeChangedSinceLastDraw
=
TRUE
;
[
self
checkTransparency
];
}
/*
* ---------- NSWindow method overrides ----------
...
...
@@ -559,3 +611,32 @@ void macdrv_window_needs_display(macdrv_window w, CGRect rect)
[
pool
release
];
}
/***********************************************************************
* macdrv_set_window_shape
*
* Sets the shape of a Cocoa window from an array of rectangles. If
* rects is NULL, resets the window's shape to its frame.
*/
void
macdrv_set_window_shape
(
macdrv_window
w
,
const
CGRect
*
rects
,
int
count
)
{
NSAutoreleasePool
*
pool
=
[[
NSAutoreleasePool
alloc
]
init
];
WineWindow
*
window
=
(
WineWindow
*
)
w
;
OnMainThread
(
^
{
if
(
!
rects
||
!
count
)
window
.
shape
=
nil
;
else
{
NSBezierPath
*
path
;
unsigned
int
i
;
path
=
[
NSBezierPath
bezierPath
];
for
(
i
=
0
;
i
<
count
;
i
++
)
[
path
appendBezierPathWithRect
:
NSRectFromCGRect
(
rects
[
i
])];
window
.
shape
=
path
;
}
});
[
pool
release
];
}
dlls/winemac.drv/macdrv.h
View file @
2d4bcc47
...
...
@@ -74,6 +74,12 @@ extern CGRect macdrv_get_desktop_rect(void) DECLSPEC_HIDDEN;
* Mac USER driver
*/
/* Mac driver private messages, must be in the range 0x80001000..0x80001fff */
enum
macdrv_window_messages
{
WM_MACDRV_SET_WIN_REGION
=
0x80001000
,
};
/* macdrv private window data */
struct
macdrv_win_data
{
...
...
@@ -83,6 +89,7 @@ struct macdrv_win_data
RECT
whole_rect
;
/* Mac window rectangle for the whole window relative to parent */
RECT
client_rect
;
/* client area relative to parent */
BOOL
on_screen
:
1
;
/* is window ordered in? */
BOOL
shaped
:
1
;
/* is window using a custom region shape? */
struct
window_surface
*
surface
;
};
...
...
dlls/winemac.drv/macdrv_cocoa.h
View file @
2d4bcc47
...
...
@@ -153,5 +153,6 @@ extern void macdrv_set_window_surface(macdrv_window w, void *surface, pthread_mu
extern
CGImageRef
create_surface_image
(
void
*
window_surface
,
CGRect
*
rect
,
int
copy_data
)
DECLSPEC_HIDDEN
;
extern
int
get_surface_region_rects
(
void
*
window_surface
,
const
CGRect
**
rects
,
int
*
count
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_window_needs_display
(
macdrv_window
w
,
CGRect
rect
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_set_window_shape
(
macdrv_window
w
,
const
CGRect
*
rects
,
int
count
)
DECLSPEC_HIDDEN
;
#endif
/* __WINE_MACDRV_COCOA_H */
dlls/winemac.drv/window.c
View file @
2d4bcc47
...
...
@@ -57,17 +57,20 @@ static void get_cocoa_window_features(struct macdrv_win_data *data,
if
((
style
&
WS_CAPTION
)
==
WS_CAPTION
&&
!
(
ex_style
&
WS_EX_LAYERED
))
{
wf
->
shadow
=
1
;
wf
->
title_bar
=
1
;
if
(
style
&
WS_SYSMENU
)
wf
->
close_button
=
1
;
if
(
style
&
WS_MINIMIZEBOX
)
wf
->
minimize_button
=
1
;
if
(
style
&
WS_MAXIMIZEBOX
)
wf
->
resizable
=
1
;
if
(
ex_style
&
WS_EX_TOOLWINDOW
)
wf
->
utility
=
1
;
if
(
!
data
->
shaped
)
{
wf
->
title_bar
=
1
;
if
(
style
&
WS_SYSMENU
)
wf
->
close_button
=
1
;
if
(
style
&
WS_MINIMIZEBOX
)
wf
->
minimize_button
=
1
;
if
(
style
&
WS_MAXIMIZEBOX
)
wf
->
resizable
=
1
;
if
(
ex_style
&
WS_EX_TOOLWINDOW
)
wf
->
utility
=
1
;
}
}
if
(
ex_style
&
WS_EX_DLGMODALFRAME
)
wf
->
shadow
=
1
;
else
if
(
style
&
WS_THICKFRAME
)
{
wf
->
shadow
=
1
;
wf
->
resizable
=
1
;
if
(
!
data
->
shaped
)
wf
->
resizable
=
1
;
}
else
if
((
style
&
(
WS_DLGFRAME
|
WS_BORDER
))
==
WS_DLGFRAME
)
wf
->
shadow
=
1
;
}
...
...
@@ -118,25 +121,28 @@ static void get_cocoa_window_state(struct macdrv_win_data *data,
static
void
get_mac_rect_offset
(
struct
macdrv_win_data
*
data
,
DWORD
style
,
RECT
*
rect
)
{
DWORD
ex_style
,
style_mask
=
0
,
ex_style_mask
=
0
;
struct
macdrv_window_features
wf
;
rect
->
top
=
rect
->
bottom
=
rect
->
left
=
rect
->
right
=
0
;
ex_style
=
GetWindowLongW
(
data
->
hwnd
,
GWL_EXSTYLE
);
get_cocoa_window_features
(
data
,
style
,
ex_style
,
&
wf
);
if
(
wf
.
title_bar
)
style_mask
|=
WS_CAPTION
;
if
(
wf
.
shadow
)
if
(
!
data
->
shaped
)
{
style_mask
|=
WS_DLGFRAME
|
WS_THICKFRAME
;
ex_style_mask
|=
WS_EX_DLGMODALFRAME
;
struct
macdrv_window_features
wf
;
get_cocoa_window_features
(
data
,
style
,
ex_style
,
&
wf
);
if
(
wf
.
title_bar
)
style_mask
|=
WS_CAPTION
;
if
(
wf
.
shadow
)
{
style_mask
|=
WS_DLGFRAME
|
WS_THICKFRAME
;
ex_style_mask
|=
WS_EX_DLGMODALFRAME
;
}
}
AdjustWindowRectEx
(
rect
,
style
&
style_mask
,
FALSE
,
ex_style
&
ex_style_mask
);
TRACE
(
"%p/%p style %08x ex_style %08x -> %s
\n
"
,
data
->
hwnd
,
data
->
cocoa_window
,
style
,
ex_style
,
wine_dbgstr_rect
(
rect
));
TRACE
(
"%p/%p style %08x ex_style %08x
shaped %d
-> %s
\n
"
,
data
->
hwnd
,
data
->
cocoa_window
,
style
,
ex_style
,
data
->
shaped
,
wine_dbgstr_rect
(
rect
));
}
...
...
@@ -324,6 +330,70 @@ static void set_cocoa_window_properties(struct macdrv_win_data *data)
}
/***********************************************************************
* sync_window_region
*
* Update the window region.
*/
static
void
sync_window_region
(
struct
macdrv_win_data
*
data
,
HRGN
win_region
)
{
HRGN
hrgn
=
win_region
;
RGNDATA
*
region_data
;
const
CGRect
*
rects
;
int
count
;
if
(
!
data
->
cocoa_window
)
return
;
data
->
shaped
=
FALSE
;
if
(
hrgn
==
(
HRGN
)
1
)
/* hack: win_region == 1 means retrieve region from server */
{
if
(
!
(
hrgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
)))
return
;
if
(
GetWindowRgn
(
data
->
hwnd
,
hrgn
)
==
ERROR
)
{
DeleteObject
(
hrgn
);
hrgn
=
0
;
}
}
if
(
hrgn
&&
GetWindowLongW
(
data
->
hwnd
,
GWL_EXSTYLE
)
&
WS_EX_LAYOUTRTL
)
MirrorRgn
(
data
->
hwnd
,
hrgn
);
if
(
hrgn
)
{
OffsetRgn
(
hrgn
,
data
->
window_rect
.
left
-
data
->
whole_rect
.
left
,
data
->
window_rect
.
top
-
data
->
whole_rect
.
top
);
}
region_data
=
get_region_data
(
hrgn
,
0
);
if
(
region_data
)
{
rects
=
(
CGRect
*
)
region_data
->
Buffer
;
count
=
region_data
->
rdh
.
nCount
;
/* Special case optimization. If the region entirely encloses the Cocoa
window, it's the same as there being no region. It's potentially
hard/slow to test this for arbitrary regions, so we just check for
very simple regions. */
if
(
count
==
1
&&
CGRectContainsRect
(
rects
[
0
],
cgrect_from_rect
(
data
->
whole_rect
)))
{
TRACE
(
"optimizing for simple region that contains Cocoa content rect
\n
"
);
rects
=
NULL
;
count
=
0
;
}
}
else
{
rects
=
NULL
;
count
=
0
;
}
TRACE
(
"win %p/%p win_region %p rects %p count %d
\n
"
,
data
->
hwnd
,
data
->
cocoa_window
,
win_region
,
rects
,
count
);
macdrv_set_window_shape
(
data
->
cocoa_window
,
rects
,
count
);
HeapFree
(
GetProcessHeap
(),
0
,
region_data
);
data
->
shaped
=
(
region_data
!=
NULL
);
if
(
hrgn
&&
hrgn
!=
win_region
)
DeleteObject
(
hrgn
);
}
/**********************************************************************
* create_cocoa_window
*
...
...
@@ -335,6 +405,15 @@ static void create_cocoa_window(struct macdrv_win_data *data)
struct
macdrv_window_features
wf
;
CGRect
frame
;
DWORD
style
,
ex_style
;
HRGN
win_rgn
;
if
((
win_rgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
))
&&
GetWindowRgn
(
data
->
hwnd
,
win_rgn
)
==
ERROR
)
{
DeleteObject
(
win_rgn
);
win_rgn
=
0
;
}
data
->
shaped
=
(
win_rgn
!=
0
);
style
=
GetWindowLongW
(
data
->
hwnd
,
GWL_STYLE
);
ex_style
=
GetWindowLongW
(
data
->
hwnd
,
GWL_EXSTYLE
);
...
...
@@ -352,13 +431,19 @@ static void create_cocoa_window(struct macdrv_win_data *data)
wine_dbgstr_rect
(
&
data
->
whole_rect
),
wine_dbgstr_rect
(
&
data
->
client_rect
));
data
->
cocoa_window
=
macdrv_create_cocoa_window
(
&
wf
,
frame
);
if
(
!
data
->
cocoa_window
)
return
;
if
(
!
data
->
cocoa_window
)
goto
done
;
set_cocoa_window_properties
(
data
);
/* set the window text */
if
(
!
InternalGetWindowText
(
data
->
hwnd
,
text
,
sizeof
(
text
)
/
sizeof
(
WCHAR
)))
text
[
0
]
=
0
;
macdrv_set_cocoa_window_title
(
data
->
cocoa_window
,
text
,
strlenW
(
text
));
/* set the window region */
if
(
win_rgn
)
sync_window_region
(
data
,
win_rgn
);
done:
if
(
win_rgn
)
DeleteObject
(
win_rgn
);
}
...
...
@@ -495,6 +580,7 @@ static void sync_window_position(struct macdrv_win_data *data, UINT swp_flags)
constrain_window_frame
(
&
frame
);
data
->
on_screen
=
macdrv_set_cocoa_window_frame
(
data
->
cocoa_window
,
&
frame
);
if
(
data
->
shaped
)
sync_window_region
(
data
,
(
HRGN
)
1
);
TRACE
(
"win %p/%p pos %s
\n
"
,
data
->
hwnd
,
data
->
cocoa_window
,
wine_dbgstr_rect
(
&
data
->
whole_rect
));
...
...
@@ -672,6 +758,35 @@ void CDECL macdrv_SetParent(HWND hwnd, HWND parent, HWND old_parent)
/***********************************************************************
* SetWindowRgn (MACDRV.@)
*
* Assign specified region to window (for non-rectangular windows)
*/
int
CDECL
macdrv_SetWindowRgn
(
HWND
hwnd
,
HRGN
hrgn
,
BOOL
redraw
)
{
struct
macdrv_win_data
*
data
;
TRACE
(
"%p, %p, %d
\n
"
,
hwnd
,
hrgn
,
redraw
);
if
((
data
=
get_win_data
(
hwnd
)))
{
sync_window_region
(
data
,
hrgn
);
release_win_data
(
data
);
}
else
{
DWORD
procid
;
GetWindowThreadProcessId
(
hwnd
,
&
procid
);
if
(
procid
!=
GetCurrentProcessId
())
SendMessageW
(
hwnd
,
WM_MACDRV_SET_WIN_REGION
,
0
,
0
);
}
return
TRUE
;
}
/***********************************************************************
* SetWindowStyle (MACDRV.@)
*
* Update the state of the Cocoa window to reflect a style change
...
...
@@ -706,6 +821,31 @@ void CDECL macdrv_SetWindowText(HWND hwnd, LPCWSTR text)
}
/**********************************************************************
* WindowMessage (MACDRV.@)
*/
LRESULT
CDECL
macdrv_WindowMessage
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
)
{
struct
macdrv_win_data
*
data
;
TRACE
(
"%p, %u, %u, %lu
\n
"
,
hwnd
,
msg
,
(
unsigned
)
wp
,
lp
);
switch
(
msg
)
{
case
WM_MACDRV_SET_WIN_REGION
:
if
((
data
=
get_win_data
(
hwnd
)))
{
sync_window_region
(
data
,
(
HRGN
)
1
);
release_win_data
(
data
);
}
return
0
;
}
FIXME
(
"unrecognized window msg %x hwnd %p wp %lx lp %lx
\n
"
,
msg
,
hwnd
,
wp
,
lp
);
return
0
;
}
static
inline
RECT
get_surface_rect
(
const
RECT
*
visible_rect
)
{
RECT
rect
;
...
...
dlls/winemac.drv/winemac.drv.spec
View file @
2d4bcc47
...
...
@@ -10,7 +10,9 @@
@ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors
@ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo
@ cdecl SetParent(long long long) macdrv_SetParent
@ cdecl SetWindowRgn(long long long) macdrv_SetWindowRgn
@ cdecl SetWindowStyle(ptr long ptr) macdrv_SetWindowStyle
@ cdecl SetWindowText(long wstr) macdrv_SetWindowText
@ cdecl WindowMessage(long long long long) macdrv_WindowMessage
@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) macdrv_WindowPosChanged
@ cdecl WindowPosChanging(long long long ptr ptr ptr ptr) macdrv_WindowPosChanging
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