diff --git a/dlls/winemac.drv/cocoa_opengl.m b/dlls/winemac.drv/cocoa_opengl.m index 2f46b87ba33..ec2b19198c2 100644 --- a/dlls/winemac.drv/cocoa_opengl.m +++ b/dlls/winemac.drv/cocoa_opengl.m @@ -109,7 +109,7 @@ - (void) clearToBlackIfNeeded glDrawBuffer(GL_FRONT_AND_BACK); glDisable(GL_SCISSOR_TEST); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glClearColor(0, 0, 0, 1); + glClearColor(0, 0, 0, gl_surface_mode == GL_SURFACE_IN_FRONT_TRANSPARENT ? 0 : 1); glClear(GL_COLOR_BUFFER_BIT); diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index f68a1c56f78..4ac03a77a2d 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -198,6 +198,7 @@ @interface WineWindow () @property (readonly, copy, nonatomic) NSArray* childWineWindows; - (void) updateColorSpace; + - (void) updateForGLSubviews; - (BOOL) becameEligibleParentOrChild; - (void) becameIneligibleChild; @@ -334,14 +335,14 @@ - (void) addGLContext:(WineOpenGLContext*)context [self setNeedsDisplay:YES]; } - [(WineWindow*)[self window] updateColorSpace]; + [(WineWindow*)[self window] updateForGLSubviews]; } - (void) removeGLContext:(WineOpenGLContext*)context { [glContexts removeObjectIdenticalTo:context]; [pendingGlContexts removeObjectIdenticalTo:context]; - [(WineWindow*)[self window] updateColorSpace]; + [(WineWindow*)[self window] updateForGLSubviews]; } - (void) updateGLContexts @@ -1402,7 +1403,8 @@ - (void) setDisabled:(BOOL)newValue - (BOOL) needsTransparency { - return self.shape || self.colorKeyed || self.usePerPixelAlpha; + return self.shape || self.colorKeyed || self.usePerPixelAlpha || + (gl_surface_mode == GL_SURFACE_BEHIND && [[self.contentView valueForKeyPath:@"subviews.@max.hasGLContext"] boolValue]); } - (void) checkTransparency @@ -1775,6 +1777,13 @@ - (void) updateColorSpace [self setColorSpace:[NSColorSpace genericRGBColorSpace]]; } + - (void) updateForGLSubviews + { + [self updateColorSpace]; + if (gl_surface_mode == GL_SURFACE_BEHIND) + [self checkTransparency]; + } + /* * ---------- NSResponder method overrides ---------- @@ -2683,7 +2692,7 @@ macdrv_view macdrv_create_view(macdrv_window w, CGRect rect) name:NSApplicationDidChangeScreenParametersNotification object:NSApp]; [[window contentView] addSubview:view]; - [window updateColorSpace]; + [window updateForGLSubviews]; }); [pool release]; @@ -2712,7 +2721,7 @@ void macdrv_dispose_view(macdrv_view v) object:NSApp]; [view removeFromSuperview]; [view release]; - [window updateColorSpace]; + [window updateForGLSubviews]; }); [pool release]; @@ -2737,15 +2746,15 @@ void macdrv_set_view_window_and_frame(macdrv_view v, macdrv_window w, CGRect rec BOOL changedWindow = (window && window != [view window]); NSRect newFrame = NSRectFromCGRect(rect); NSRect oldFrame = [view frame]; - BOOL needUpdateWindowColorSpace = FALSE; + BOOL needUpdateWindowForGLSubviews = FALSE; if (changedWindow) { WineWindow* oldWindow = (WineWindow*)[view window]; [view removeFromSuperview]; - [oldWindow updateColorSpace]; + [oldWindow updateForGLSubviews]; [[window contentView] addSubview:view]; - needUpdateWindowColorSpace = TRUE; + needUpdateWindowForGLSubviews = TRUE; } if (!NSEqualRects(oldFrame, newFrame)) @@ -2759,11 +2768,11 @@ void macdrv_set_view_window_and_frame(macdrv_view v, macdrv_window w, CGRect rec else [view setFrame:newFrame]; [view setNeedsDisplay:YES]; - needUpdateWindowColorSpace = TRUE; + needUpdateWindowForGLSubviews = TRUE; } - if (needUpdateWindowColorSpace) - [(WineWindow*)[view window] updateColorSpace]; + if (needUpdateWindowForGLSubviews) + [(WineWindow*)[view window] updateForGLSubviews]; }); [pool release]; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 4b68adca2f0..d5e3f4669a6 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -117,6 +117,12 @@ TOPMOST_FLOAT_INACTIVE_ALL, }; +enum { + GL_SURFACE_IN_FRONT_OPAQUE, + GL_SURFACE_IN_FRONT_TRANSPARENT, + GL_SURFACE_BEHIND, +}; + enum { MACDRV_HOTKEY_SUCCESS, MACDRV_HOTKEY_ALREADY_REGISTERED, @@ -149,6 +155,7 @@ extern int allow_immovable_windows DECLSPEC_HIDDEN; extern int cursor_clipping_locks_windows DECLSPEC_HIDDEN; extern int use_precise_scrolling DECLSPEC_HIDDEN; +extern int gl_surface_mode DECLSPEC_HIDDEN; extern int macdrv_start_cocoa_app(unsigned long long tickcount) DECLSPEC_HIDDEN; extern void macdrv_window_rejected_focus(const struct macdrv_event *event) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index 38352a82bb6..62c70df64df 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -57,6 +57,7 @@ BOOL disable_window_decorations = FALSE; int allow_immovable_windows = TRUE; int cursor_clipping_locks_windows = TRUE; int use_precise_scrolling = TRUE; +int gl_surface_mode = GL_SURFACE_IN_FRONT_OPAQUE; HMODULE macdrv_module = 0; @@ -183,6 +184,16 @@ static void setup_options(void) if (!get_config_key(hkey, appkey, "UsePreciseScrolling", buffer, sizeof(buffer))) use_precise_scrolling = IS_OPTION_TRUE(buffer[0]); + if (!get_config_key(hkey, appkey, "OpenGLSurfaceMode", buffer, sizeof(buffer))) + { + if (!strcmp(buffer, "transparent")) + gl_surface_mode = GL_SURFACE_IN_FRONT_TRANSPARENT; + else if (!strcmp(buffer, "behind")) + gl_surface_mode = GL_SURFACE_BEHIND; + else + gl_surface_mode = GL_SURFACE_IN_FRONT_OPAQUE; + } + if (appkey) RegCloseKey(appkey); if (hkey) RegCloseKey(hkey); } diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 220efa3be0d..a6f1440a004 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1480,6 +1480,21 @@ static BOOL create_context(struct wgl_context *context, CGLContextObj share, uns return FALSE; } + if (gl_surface_mode == GL_SURFACE_IN_FRONT_TRANSPARENT) + { + GLint opacity = 0; + err = CGLSetParameter(context->cglcontext, kCGLCPSurfaceOpacity, &opacity); + if (err != kCGLNoError) + WARN("CGLSetParameter(kCGLCPSurfaceOpacity) failed with error %d %s; leaving opaque\n", err, CGLErrorString(err)); + } + else if (gl_surface_mode == GL_SURFACE_BEHIND) + { + GLint order = -1; + err = CGLSetParameter(context->cglcontext, kCGLCPSurfaceOrder, &order); + if (err != kCGLNoError) + WARN("CGLSetParameter(kCGLCPSurfaceOrder) failed with error %d %s; leaving in front\n", err, CGLErrorString(err)); + } + context->context = macdrv_create_opengl_context(context->cglcontext); CGLReleaseContext(context->cglcontext); if (!context->context) @@ -1638,7 +1653,7 @@ static BOOL set_pixel_format(HDC hdc, int fmt, BOOL allow_reset) done: release_win_data(data); - if (ret) __wine_set_pixel_format(hwnd, fmt); + if (ret && gl_surface_mode == GL_SURFACE_BEHIND) __wine_set_pixel_format(hwnd, fmt); return ret; }