From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/cocoa_window.h | 3 - dlls/winemac.drv/cocoa_window.m | 104 ++++++++++++++------------------ dlls/winemac.drv/macdrv.h | 1 - dlls/winemac.drv/macdrv_cocoa.h | 4 +- dlls/winemac.drv/surface.c | 27 ++++++++- dlls/winemac.drv/window.c | 39 ++---------- 6 files changed, 78 insertions(+), 100 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h index b5168d0c128..804297f55a0 100644 --- a/dlls/winemac.drv/cocoa_window.h +++ b/dlls/winemac.drv/cocoa_window.h @@ -52,9 +52,6 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
BOOL shapeChangedSinceLastDraw;
- BOOL colorKeyed; - CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue; - BOOL usePerPixelAlpha;
NSUInteger lastModifierFlags; diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index bae2e21fb48..866306d3511 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -367,6 +367,7 @@ @interface WineContentView : WineBaseView <NSTextInputClient, NSViewLayerContent { CGRect surfaceRect; CGImageRef colorImage; + CGImageRef shapeImage;
NSMutableArray* glContexts; NSMutableArray* pendingGlContexts; @@ -413,8 +414,6 @@ @interface WineWindow () @property (nonatomic) BOOL shapeChangedSinceLastDraw; @property (readonly, nonatomic) BOOL needsTransparency;
-@property (nonatomic) BOOL colorKeyed; -@property (nonatomic) CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue; @property (nonatomic) BOOL usePerPixelAlpha;
@property (assign, nonatomic) void* himc; @@ -503,6 +502,7 @@ - (void) dealloc [glContexts release]; [pendingGlContexts release]; CGImageRelease(colorImage); + CGImageRelease(shapeImage); [super dealloc]; }
@@ -519,7 +519,7 @@ - (BOOL) wantsUpdateLayer - (void) updateLayer { WineWindow* window = (WineWindow*)[self window]; - CGImageRef image; + CGImageRef image, maskedImage; CGRect imageRect; CALayer* layer = [self layer];
@@ -535,21 +535,10 @@ - (void) updateLayer imageRect.size.width *= layer.contentsScale; imageRect.size.height *= layer.contentsScale;
- image = CGImageCreateWithImageInRect(colorImage, imageRect); - - 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; - } - } + maskedImage = shapeImage ? CGImageCreateWithMask(colorImage, shapeImage) + : CGImageRetain(colorImage); + image = CGImageCreateWithImageInRect(maskedImage, imageRect); + CGImageRelease(maskedImage);
if (image) { @@ -561,7 +550,7 @@ - (void) updateLayer // If the window may be transparent, then we have to invalidate the // shadow every time we draw. Also, if this is the first time we've // drawn since changing from transparent to opaque. - if (window.colorKeyed || window.usePerPixelAlpha || window.shapeChangedSinceLastDraw) + if (shapeImage || window.usePerPixelAlpha || window.shapeChangedSinceLastDraw) { window.shapeChangedSinceLastDraw = FALSE; [window invalidateShadow]; @@ -580,6 +569,17 @@ - (void) setColorImage:(CGImageRef)image colorImage = CGImageRetain(image); }
+ - (void) setShapeImage:(CGImageRef)image + { + CGImageRelease(shapeImage); + shapeImage = CGImageRetain(image); + } + + - (BOOL) hasShapeImage + { + return !!shapeImage; + } + - (void) viewWillDraw { [super viewWillDraw]; @@ -1017,7 +1017,6 @@ @implementation WineWindow @synthesize disabled, noForeground, preventsAppActivation, floating, fullscreen, fakingClose, closing, latentParentWindow, hwnd, queue; @synthesize drawnSinceShown; @synthesize shapeChangedSinceLastDraw; - @synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue; @synthesize usePerPixelAlpha; @synthesize himc, commandDone;
@@ -2071,8 +2070,9 @@ - (void) setDisabled:(BOOL)newValue
- (BOOL) needsTransparency { - return self.contentView.layer.mask || self.colorKeyed || self.usePerPixelAlpha || - (gl_surface_mode == GL_SURFACE_BEHIND && [(WineContentView*)self.contentView hasGLDescendant]); + WineContentView *view = self.contentView; + return self.contentView.layer.mask || [view hasShapeImage] || self.usePerPixelAlpha || + (gl_surface_mode == GL_SURFACE_BEHIND && [view hasGLDescendant]); }
- (void) checkTransparency @@ -3521,6 +3521,30 @@ void macdrv_window_set_color_image(macdrv_window w, CGImageRef image, CGRect rec } }
+ +/*********************************************************************** + * macdrv_window_set_shape_image + */ +void macdrv_window_set_shape_image(macdrv_window w, CGImageRef image) +{ +@autoreleasepool +{ + WineWindow* window = (WineWindow*)w; + + CGImageRetain(image); + + OnMainThreadAsync(^{ + WineContentView *view = [window contentView]; + + [view setShapeImage:image]; + [view setNeedsDisplay:true]; + [window checkTransparency]; + + CGImageRelease(image); + }); +} +} + /*********************************************************************** * macdrv_set_window_shape * @@ -3567,42 +3591,6 @@ void macdrv_set_window_alpha(macdrv_window w, CGFloat alpha) } }
-/*********************************************************************** - * macdrv_set_window_color_key - */ -void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat keyGreen, - CGFloat keyBlue) -{ -@autoreleasepool -{ - WineWindow* window = (WineWindow*)w; - - OnMainThread(^{ - window.colorKeyed = TRUE; - window.colorKeyRed = keyRed; - window.colorKeyGreen = keyGreen; - window.colorKeyBlue = keyBlue; - [window checkTransparency]; - }); -} -} - -/*********************************************************************** - * macdrv_clear_window_color_key - */ -void macdrv_clear_window_color_key(macdrv_window w) -{ -@autoreleasepool -{ - WineWindow* window = (WineWindow*)w; - - OnMainThread(^{ - window.colorKeyed = FALSE; - [window checkTransparency]; - }); -} -} - /*********************************************************************** * macdrv_window_use_per_pixel_alpha */ diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 8b9e908bc1a..d126c38b081 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -189,7 +189,6 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p RECT whole_rect; /* Mac window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to parent */ int pixel_format; /* pixel format for GL */ - COLORREF color_key; /* color key for layered window; CLR_INVALID is not color keyed */ HANDLE drag_event; /* event to signal that Cocoa-driven window dragging has ended */ unsigned int on_screen : 1; /* is window ordered in? (minimized or not) */ unsigned int shaped : 1; /* is window using a custom region shape? */ diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 30ab06c3662..94821eef6bf 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -553,11 +553,9 @@ extern void macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev, extern void macdrv_get_cocoa_window_frame(macdrv_window w, CGRect* out_frame); extern void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent); extern void macdrv_window_set_color_image(macdrv_window w, CGImageRef image, CGRect rect, CGRect dirty); +extern void macdrv_window_set_shape_image(macdrv_window w, CGImageRef image); extern void macdrv_set_window_shape(macdrv_window w, const CGRect *rects, int count); extern void macdrv_set_window_alpha(macdrv_window w, CGFloat alpha); -extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat keyGreen, - CGFloat keyBlue); -extern void macdrv_clear_window_color_key(macdrv_window w); extern void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha); extern void macdrv_give_cocoa_window_focus(macdrv_window w, int activate); extern void macdrv_set_window_min_max_sizes(macdrv_window w, CGSize min_size, CGSize max_size); diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index fa34a5122ab..43e57e79845 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -95,6 +95,31 @@ static BOOL macdrv_surface_flush(struct window_surface *window_surface, const RE macdrv_window_set_color_image(surface->window, image, cgrect_from_rect(*rect), cgrect_from_rect(*dirty)); CGImageRelease(image);
+ if (shape_changed) + { + if (!shape_bits) + macdrv_window_set_shape_image(surface->window, NULL); + else + { + const BYTE *src = shape_bits; + CGDataProviderRef provider; + CGImageRef image; + BYTE *dst; + UINT i; + + if (!(provider = data_provider_create(shape_info->bmiHeader.biSizeImage, (void **)&dst))) return TRUE; + for (i = 0; i < shape_info->bmiHeader.biSizeImage; i++) dst[i] = ~src[i]; /* CGImage mask bits are inverted */ + + image = CGImageMaskCreate(shape_info->bmiHeader.biWidth, abs(shape_info->bmiHeader.biHeight), 1, 1, + shape_info->bmiHeader.biSizeImage / abs(shape_info->bmiHeader.biHeight), + provider, NULL, retina_on); + CGDataProviderRelease(provider); + + macdrv_window_set_shape_image(surface->window, image); + CGImageRelease(image); + } + } + return TRUE; }
@@ -166,7 +191,7 @@ static struct window_surface *create_surface(HWND hwnd, macdrv_window window, co } if (desc.hDeviceDc) NtUserReleaseDC(hwnd, desc.hDeviceDc);
- if (!(surface = calloc(1, sizeof(*surface)))) goto failed; + if (!(surface = calloc(1, sizeof(*surface)))) return NULL; if (!window_surface_init(&surface->header, &macdrv_surface_funcs, hwnd, rect, info, bitmap)) goto failed;
surface->window = window; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 0784b0e4e39..1e51501a66d 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -278,7 +278,6 @@ static struct macdrv_win_data *alloc_win_data(HWND hwnd) if ((data = calloc(1, sizeof(*data)))) { data->hwnd = hwnd; - data->color_key = CLR_INVALID; data->swap_interval = 1; pthread_mutex_lock(&win_data_mutex); if (!win_datas) @@ -485,7 +484,7 @@ static inline void add_bounds_rect(RECT *bounds, const RECT *rect) /*********************************************************************** * sync_window_opacity */ -static void sync_window_opacity(struct macdrv_win_data *data, COLORREF key, BYTE alpha, +static void sync_window_opacity(struct macdrv_win_data *data, BYTE alpha, BOOL per_pixel_alpha, DWORD flags) { CGFloat opacity = 1.0; @@ -496,33 +495,6 @@ static void sync_window_opacity(struct macdrv_win_data *data, COLORREF key, BYTE TRACE("setting window %p/%p alpha to %g\n", data->hwnd, data->cocoa_window, opacity); macdrv_set_window_alpha(data->cocoa_window, opacity);
- if (flags & LWA_COLORKEY) - { - /* FIXME: treat PALETTEINDEX and DIBINDEX as black */ - if ((key & (1 << 24)) || key >> 16 == 0x10ff) - key = RGB(0, 0, 0); - } - else - key = CLR_INVALID; - - if (data->color_key != key) - { - if (key == CLR_INVALID) - { - TRACE("clearing color-key for window %p/%p\n", data->hwnd, data->cocoa_window); - macdrv_clear_window_color_key(data->cocoa_window); - } - else - { - TRACE("setting color-key for window %p/%p to RGB %d,%d,%d\n", data->hwnd, data->cocoa_window, - GetRValue(key), GetGValue(key), GetBValue(key)); - macdrv_set_window_color_key(data->cocoa_window, GetRValue(key), GetGValue(key), GetBValue(key)); - } - - data->color_key = key; - needs_flush = TRUE; - } - if (!data->per_pixel_alpha != !per_pixel_alpha) { TRACE("setting window %p/%p per-pixel-alpha to %d\n", data->hwnd, data->cocoa_window, per_pixel_alpha); @@ -757,7 +729,7 @@ static void create_cocoa_window(struct macdrv_win_data *data)
/* set the window opacity */ if (!NtUserGetLayeredWindowAttributes(data->hwnd, &key, &alpha, &layered_flags)) layered_flags = 0; - sync_window_opacity(data, key, alpha, FALSE, layered_flags); + sync_window_opacity(data, alpha, FALSE, layered_flags);
done: if (win_rgn) NtGdiDeleteObjectApp(win_rgn); @@ -778,7 +750,6 @@ static void destroy_cocoa_window(struct macdrv_win_data *data) macdrv_destroy_cocoa_window(data->cocoa_window); data->cocoa_window = 0; data->on_screen = FALSE; - data->color_key = CLR_INVALID; if (data->surface) window_surface_release(data->surface); data->surface = NULL; if (data->unminimized_surface) window_surface_release(data->unminimized_surface); @@ -1686,7 +1657,7 @@ void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alpha, DWOR if (data->surface) window_surface_set_layered(data->surface, key, alpha << 24, 0); if (data->cocoa_window) { - sync_window_opacity(data, key, alpha, FALSE, flags); + sync_window_opacity(data, alpha, FALSE, flags); /* since layered attributes are now set, can now show the window */ if ((NtUserGetWindowLongW(hwnd, GWL_STYLE) & WS_VISIBLE) && !data->on_screen) show_window(data); @@ -1781,7 +1752,7 @@ void macdrv_SetWindowStyle(HWND hwnd, INT offset, STYLESTRUCT *style) { data->layered = FALSE; data->ulw_layered = FALSE; - sync_window_opacity(data, 0, 0, FALSE, 0); + sync_window_opacity(data, 0, FALSE, 0); if (data->surface) window_surface_set_layered(data->surface, CLR_INVALID, -1, 0); }
@@ -1905,7 +1876,7 @@ void macdrv_UpdateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF col show_window(data);
/* The ULW flags are a superset of the LWA flags. */ - sync_window_opacity(data, color_key, 255, TRUE, flags); + sync_window_opacity(data, 255, TRUE, flags); release_win_data(data); } }