Commit c0d43fb5 authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winemac: Implement layered windows: SetLayeredWindowAttributes() and UpdateLayeredWindow().

parent 2d4bcc47
......@@ -34,6 +34,11 @@
NSBezierPath* shape;
BOOL shapeChangedSinceLastDraw;
BOOL colorKeyed;
CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue;
BOOL usePerPixelAlpha;
}
@end
......@@ -72,6 +72,10 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
@property (nonatomic) BOOL shapeChangedSinceLastDraw;
@property (readonly, nonatomic) BOOL needsTransparency;
@property (nonatomic) BOOL colorKeyed;
@property (nonatomic) CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue;
@property (nonatomic) BOOL usePerPixelAlpha;
+ (void) flipRect:(NSRect*)rect;
@end
......@@ -117,13 +121,28 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
[window.shape addClip];
if (window.colorKeyed)
{
CGImageRef maskedImage;
CGFloat components[] = { window.colorKeyRed - 0.5, window.colorKeyRed + 0.5,
window.colorKeyGreen - 0.5, window.colorKeyGreen + 0.5,
window.colorKeyBlue - 0.5, window.colorKeyBlue + 0.5 };
maskedImage = CGImageCreateWithMaskingColors(image, components);
if (maskedImage)
{
CGImageRelease(image);
image = maskedImage;
}
}
context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextDrawImage(context, imageRect, image);
CGImageRelease(image);
if (window.shapeChangedSinceLastDraw)
if (window.shapeChangedSinceLastDraw || window.colorKeyed ||
window.usePerPixelAlpha)
{
window.shapeChangedSinceLastDraw = FALSE;
[window invalidateShadow];
......@@ -143,6 +162,8 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
@synthesize disabled, noActivate, floating, latentParentWindow;
@synthesize surface, surface_mutex;
@synthesize shape, shapeChangedSinceLastDraw;
@synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue;
@synthesize usePerPixelAlpha;
+ (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)wf
windowFrame:(NSRect)window_frame
......@@ -338,7 +359,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
- (BOOL) needsTransparency
{
return (self.shape != nil);
return self.shape || self.colorKeyed || self.usePerPixelAlpha;
}
- (void) checkTransparency
......@@ -640,3 +661,68 @@ void macdrv_set_window_shape(macdrv_window w, const CGRect *rects, int count)
[pool release];
}
/***********************************************************************
* macdrv_set_window_alpha
*/
void macdrv_set_window_alpha(macdrv_window w, CGFloat alpha)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
WineWindow* window = (WineWindow*)w;
[window setAlphaValue:alpha];
[pool release];
}
/***********************************************************************
* macdrv_set_window_color_key
*/
void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat keyGreen,
CGFloat keyBlue)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
WineWindow* window = (WineWindow*)w;
OnMainThread(^{
window.colorKeyed = TRUE;
window.colorKeyRed = keyRed;
window.colorKeyGreen = keyGreen;
window.colorKeyBlue = keyBlue;
[window checkTransparency];
});
[pool release];
}
/***********************************************************************
* macdrv_clear_window_color_key
*/
void macdrv_clear_window_color_key(macdrv_window w)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
WineWindow* window = (WineWindow*)w;
OnMainThread(^{
window.colorKeyed = FALSE;
[window checkTransparency];
});
[pool release];
}
/***********************************************************************
* macdrv_window_use_per_pixel_alpha
*/
void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
WineWindow* window = (WineWindow*)w;
OnMainThread(^{
window.usePerPixelAlpha = use_per_pixel_alpha;
[window checkTransparency];
});
[pool release];
}
......@@ -88,13 +88,17 @@ struct macdrv_win_data
RECT window_rect; /* USER window rectangle relative to parent */
RECT whole_rect; /* Mac window rectangle for the whole window relative to parent */
RECT client_rect; /* client area relative to parent */
COLORREF color_key; /* color key for layered window; CLR_INVALID is not color keyed */
BOOL on_screen : 1; /* is window ordered in? */
BOOL shaped : 1; /* is window using a custom region shape? */
BOOL layered : 1; /* is window layered and with valid attributes? */
BOOL per_pixel_alpha : 1; /* is window using per-pixel alpha? */
struct window_surface *surface;
};
extern RGNDATA *get_region_data(HRGN hrgn, HDC hdc_lptodp) DECLSPEC_HIDDEN;
extern struct window_surface *create_surface(macdrv_window window, const RECT *rect) DECLSPEC_HIDDEN;
extern struct window_surface *create_surface(macdrv_window window, const RECT *rect, BOOL use_alpha) DECLSPEC_HIDDEN;
extern void set_window_surface(macdrv_window window, struct window_surface *window_surface) DECLSPEC_HIDDEN;
extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha) DECLSPEC_HIDDEN;
#endif /* __WINE_MACDRV_H */
......@@ -154,5 +154,10 @@ extern CGImageRef create_surface_image(void *window_surface, CGRect *rect, int c
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;
extern void macdrv_set_window_alpha(macdrv_window w, CGFloat alpha) DECLSPEC_HIDDEN;
extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat keyGreen,
CGFloat keyBlue) DECLSPEC_HIDDEN;
extern void macdrv_clear_window_color_key(macdrv_window w) DECLSPEC_HIDDEN;
extern void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha) DECLSPEC_HIDDEN;
#endif /* __WINE_MACDRV_COCOA_H */
......@@ -61,6 +61,7 @@ struct macdrv_window_surface
struct window_surface header;
macdrv_window window;
RECT bounds;
BOOL use_alpha;
RGNDATA *region_data;
BYTE *bits;
pthread_mutex_t mutex;
......@@ -184,7 +185,7 @@ static const struct window_surface_funcs macdrv_surface_funcs =
/***********************************************************************
* create_surface
*/
struct window_surface *create_surface(macdrv_window window, const RECT *rect)
struct window_surface *create_surface(macdrv_window window, const RECT *rect, BOOL use_alpha)
{
struct macdrv_window_surface *surface;
int width = rect->right - rect->left, height = rect->bottom - rect->top;
......@@ -229,6 +230,7 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect)
surface->header.ref = 1;
surface->window = window;
reset_bounds(&surface->bounds);
surface->use_alpha = use_alpha;
surface->bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, surface->info.bmiHeader.biSizeImage);
if (!surface->bits) goto failed;
......@@ -243,6 +245,15 @@ failed:
}
/***********************************************************************
* set_surface_use_alpha
*/
void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha)
{
struct macdrv_window_surface *surface = get_mac_surface(window_surface);
surface->use_alpha = use_alpha;
}
/***********************************************************************
* set_window_surface
*/
void set_window_surface(macdrv_window window, struct window_surface *window_surface)
......@@ -310,6 +321,7 @@ CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_dat
CGColorSpaceRef colorspace;
CGDataProviderRef provider;
int bytes_per_row, offset, size;
CGImageAlphaInfo alphaInfo;
visrect = CGRectOffset(*rect, -surface->header.rect.left, -surface->header.rect.top);
......@@ -328,9 +340,10 @@ CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_dat
else
provider = CGDataProviderCreateWithData(NULL, surface->bits + offset, size, NULL);
alphaInfo = surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
cgimage = CGImageCreate(CGRectGetWidth(visrect), CGRectGetHeight(visrect),
8, 32, bytes_per_row, colorspace,
kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
alphaInfo | kCGBitmapByteOrder32Little,
provider, NULL, FALSE, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorspace);
......
......@@ -9,10 +9,12 @@
@ cdecl DestroyWindow(long) macdrv_DestroyWindow
@ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors
@ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo
@ cdecl SetLayeredWindowAttributes(long long long long) macdrv_SetLayeredWindowAttributes
@ 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 UpdateLayeredWindow(long ptr ptr) macdrv_UpdateLayeredWindow
@ 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment