Resolves tdf#138051 - UI picker text blocks buttons
[LibreOffice.git] / vcl / osx / salobj.cxx
blob6cf114f20c1b8a54597f05c577b1f733c0634ff7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
21 #include <tools/debug.hxx>
22 #include <vcl/opengl/OpenGLContext.hxx>
23 #include <vcl/opengl/OpenGLHelper.hxx>
24 #include <opengl/zone.hxx>
26 #include <osx/saldata.hxx>
27 #include <osx/salframe.h>
28 #include <osx/salinst.h>
29 #include <osx/salobj.h>
30 #include <osx/runinmain.hxx>
32 #include <AppKit/NSOpenGLView.h>
34 AquaSalObject::AquaSalObject( AquaSalFrame* pFrame, SystemWindowData const * pWindowData ) :
35 mpFrame( pFrame ),
36 mnClipX( -1 ),
37 mnClipY( -1 ),
38 mnClipWidth( -1 ),
39 mnClipHeight( -1 ),
40 mbClip( false ),
41 mnX( 0 ),
42 mnY( 0 ),
43 mnWidth( 20 ),
44 mnHeight( 20 )
46 maSysData.mpNSView = nullptr;
47 maSysData.mbOpenGL = false;
49 NSRect aInitFrame = { NSZeroPoint, { 20, 20 } };
50 mpClipView = [[NSClipView alloc] initWithFrame: aInitFrame ];
51 if( mpClipView )
53 [mpFrame->getNSView() addSubview: mpClipView];
54 [mpClipView setHidden: YES];
56 if (pWindowData && pWindowData->bOpenGL)
58 maSysData.mbOpenGL = true;
59 SAL_WNODEPRECATED_DECLARATIONS_PUSH
60 // "'NSOpenGLPixelFormat' is deprecated: first deprecated in macOS 10.14 - Please use
61 // Metal or MetalKit."
62 NSOpenGLPixelFormat* pixFormat = nullptr;
63 SAL_WNODEPRECATED_DECLARATIONS_POP
65 if (pWindowData->bLegacy)
67 SAL_WNODEPRECATED_DECLARATIONS_PUSH
68 // "'NSOpenGLPixelFormatAttribute' is deprecated: first deprecated in macOS 10.14"
69 NSOpenGLPixelFormatAttribute const aAttributes[] =
70 SAL_WNODEPRECATED_DECLARATIONS_POP
72 SAL_WNODEPRECATED_DECLARATIONS_PUSH
73 // "'NSOpenGLPFADoubleBuffer' is deprecated: first deprecated in macOS 10.14",
74 // "'NSOpenGLPFAAlphaSize' is deprecated: first deprecated in macOS 10.14",
75 // "'NSOpenGLPFAColorSize' is deprecated: first deprecated in macOS 10.14",
76 // "'NSOpenGLPFADepthSize' is deprecated: first deprecated in macOS 10.14",
77 // "'NSOpenGLPFAMultisample' is deprecated: first deprecated in macOS 10.14",
78 // "'NSOpenGLPFASampleBuffers' is deprecated: first deprecated in macOS 10.14",
79 // "'NSOpenGLPixelFormatAttribute' is deprecated: first deprecated in macOS
80 // 10.14",
81 // "'NSOpenGLPFASamples' is deprecated: first deprecated in macOS 10.14"
82 NSOpenGLPFADoubleBuffer,
83 NSOpenGLPFAAlphaSize, 8,
84 NSOpenGLPFAColorSize, 24,
85 NSOpenGLPFADepthSize, 24,
86 NSOpenGLPFAMultisample,
87 NSOpenGLPFASampleBuffers, NSOpenGLPixelFormatAttribute(1),
88 NSOpenGLPFASamples, NSOpenGLPixelFormatAttribute(4),
89 SAL_WNODEPRECATED_DECLARATIONS_POP
92 SAL_WNODEPRECATED_DECLARATIONS_PUSH
93 // "'NSOpenGLPixelFormat' is deprecated: first deprecated in macOS 10.14 - Please
94 // use Metal or MetalKit."
95 pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:aAttributes];
96 SAL_WNODEPRECATED_DECLARATIONS_POP
98 else
100 SAL_WNODEPRECATED_DECLARATIONS_PUSH
101 // "'NSOpenGLPixelFormatAttribute' is deprecated: first deprecated in macOS 10.14"
102 NSOpenGLPixelFormatAttribute const aAttributes[] =
103 SAL_WNODEPRECATED_DECLARATIONS_POP
105 SAL_WNODEPRECATED_DECLARATIONS_PUSH
106 // "'NSOpenGLPFAOpenGLProfile' is deprecated: first deprecated in macOS 10.14",
107 // "'NSOpenGLProfileVersion3_2Core' is deprecated: first deprecated in macOS
108 // 10.14",
109 // "'NSOpenGLPFADoubleBuffer' is deprecated: first deprecated in macOS 10.14",
110 // "'NSOpenGLPFAAlphaSize' is deprecated: first deprecated in macOS 10.14",
111 // "'NSOpenGLPFAColorSize' is deprecated: first deprecated in macOS 10.14",
112 // "'NSOpenGLPFADepthSize' is deprecated: first deprecated in macOS 10.14",
113 // "'NSOpenGLPFAMultisample' is deprecated: first deprecated in macOS 10.14",
114 // "'NSOpenGLPFASampleBuffers' is deprecated: first deprecated in macOS 10.14",
115 // "'NSOpenGLPixelFormatAttribute' is deprecated: first deprecated in macOS
116 // 10.14",
117 // "'NSOpenGLPFASamples' is deprecated: first deprecated in macOS 10.14"
118 NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
119 NSOpenGLPFADoubleBuffer,
120 NSOpenGLPFAAlphaSize, 8,
121 NSOpenGLPFAColorSize, 24,
122 NSOpenGLPFADepthSize, 24,
123 NSOpenGLPFAMultisample,
124 NSOpenGLPFASampleBuffers, NSOpenGLPixelFormatAttribute(1),
125 NSOpenGLPFASamples, NSOpenGLPixelFormatAttribute(4),
126 SAL_WNODEPRECATED_DECLARATIONS_POP
129 SAL_WNODEPRECATED_DECLARATIONS_PUSH
130 // "'NSOpenGLPixelFormat' is deprecated: first deprecated in macOS 10.14 - Please
131 // use Metal or MetalKit."
132 pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:aAttributes];
133 SAL_WNODEPRECATED_DECLARATIONS_POP
136 SAL_WNODEPRECATED_DECLARATIONS_PUSH
137 // "'NSOpenGLView' is deprecated: first deprecated in macOS 10.14 - Please use MTKView
138 // instead."
139 maSysData.mpNSView = [[NSOpenGLView alloc] initWithFrame: aInitFrame pixelFormat:pixFormat];
140 SAL_WNODEPRECATED_DECLARATIONS_POP
142 else
144 maSysData.mpNSView = [[NSView alloc] initWithFrame: aInitFrame];
147 if( maSysData.mpNSView )
149 if( mpClipView )
150 [mpClipView setDocumentView: maSysData.mpNSView];
154 AquaSalObject::~AquaSalObject()
156 assert( GetSalData()->mpInstance->IsMainThread() );
158 if( maSysData.mpNSView )
160 NSView *pView = maSysData.mpNSView;
161 [pView removeFromSuperview];
162 [pView release];
164 if( mpClipView )
166 [mpClipView removeFromSuperview];
167 [mpClipView release];
171 // Please note that the talk about QTMovieView below presumably refers
172 // to stuff in the QuickTime avmedia thingie, and that QuickTime is
173 // deprecated, not available for 64-bit code, and won't thus be used
174 // in a "modern" build of LO anyway. So the relevance of the comment
175 // is unclear.
178 sadly there seems to be no way to impose clipping on a child view,
179 especially a QTMovieView which seems to ignore the current context
180 completely. Also there is no real way to shape a window; on Aqua a
181 similar effect to non-rectangular windows is achieved by using a
182 non-opaque window and not painting where one wants the background
183 to shine through.
185 With respect to SalObject this leaves us to having an NSClipView
186 containing the child view. Even a QTMovieView respects the boundaries of
187 that, which gives us a clip "region" consisting of one rectangle.
188 This is gives us an 80% solution only, though.
191 void AquaSalObject::ResetClipRegion()
193 mbClip = false;
194 setClippedPosSize();
197 void AquaSalObject::BeginSetClipRegion( sal_uInt32 )
199 mbClip = false;
202 void AquaSalObject::UnionClipRegion(
203 tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight )
205 if( mbClip )
207 if( nX < mnClipX )
209 mnClipWidth += mnClipX - nX;
210 mnClipX = nX;
212 if( nX + nWidth > mnClipX + mnClipWidth )
213 mnClipWidth = nX + nWidth - mnClipX;
214 if( nY < mnClipY )
216 mnClipHeight += mnClipY - nY;
217 mnClipY = nY;
219 if( nY + nHeight > mnClipY + mnClipHeight )
220 mnClipHeight = nY + nHeight - mnClipY;
222 else
224 mnClipX = nX;
225 mnClipY = nY;
226 mnClipWidth = nWidth;
227 mnClipHeight = nHeight;
228 mbClip = true;
232 void AquaSalObject::EndSetClipRegion()
234 setClippedPosSize();
237 void AquaSalObject::SetPosSize(
238 tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight )
240 mnX = nX;
241 mnY = nY;
242 mnWidth = nWidth;
243 mnHeight = nHeight;
244 setClippedPosSize();
247 void AquaSalObject::setClippedPosSize()
249 OSX_SALDATA_RUNINMAIN( setClippedPosSize() )
251 NSRect aViewRect = { NSZeroPoint, NSMakeSize( mnWidth, mnHeight) };
252 if( maSysData.mpNSView )
254 NSView* pNSView = maSysData.mpNSView;
255 [pNSView setFrame: aViewRect];
258 NSRect aClipViewRect = NSMakeRect( mnX, mnY, mnWidth, mnHeight);
259 NSPoint aClipPt = NSZeroPoint;
260 if( mbClip )
262 aClipViewRect.origin.x += mnClipX;
263 aClipViewRect.origin.y += mnClipY;
264 aClipViewRect.size.width = mnClipWidth;
265 aClipViewRect.size.height = mnClipHeight;
266 aClipPt.x = mnClipX;
267 if( mnClipY == 0 )
268 aClipPt.y = mnHeight - mnClipHeight;
271 mpFrame->VCLToCocoa( aClipViewRect, false );
272 [mpClipView setFrame: aClipViewRect];
274 [mpClipView scrollToPoint: aClipPt];
277 void AquaSalObject::Show( bool bVisible )
279 if( !mpClipView )
280 return;
282 OSX_SALDATA_RUNINMAIN( Show( bVisible ) )
284 [mpClipView setHidden: (bVisible ? NO : YES)];
287 const SystemEnvData* AquaSalObject::GetSystemData() const
289 return &maSysData;
292 namespace {
294 class AquaOpenGLContext : public OpenGLContext
296 public:
297 virtual void initWindow() override;
299 private:
300 GLWindow m_aGLWin;
302 virtual const GLWindow& getOpenGLWindow() const override { return m_aGLWin; }
303 virtual GLWindow& getModifiableOpenGLWindow() override { return m_aGLWin; }
304 SAL_WNODEPRECATED_DECLARATIONS_PUSH
305 // "'NSOpenGLView' is deprecated: first deprecated in macOS 10.14 - Please use MTKView
306 // instead."
307 NSOpenGLView* getOpenGLView();
308 SAL_WNODEPRECATED_DECLARATIONS_POP
309 virtual bool ImplInit() override;
310 virtual SystemWindowData generateWinData(vcl::Window* pParent, bool bRequestLegacyContext) override;
311 virtual void makeCurrent() override;
312 virtual void destroyCurrentContext() override;
313 virtual void resetCurrent() override;
314 virtual void swapBuffers() override;
319 void AquaOpenGLContext::resetCurrent()
321 OSX_SALDATA_RUNINMAIN( resetCurrent() )
323 clearCurrent();
325 OpenGLZone aZone;
327 (void) this; // loplugin:staticmethods
328 SAL_WNODEPRECATED_DECLARATIONS_PUSH
329 // "'NSOpenGLContext' is deprecated: first deprecated in macOS 10.14 - Please use Metal or
330 // MetalKit."
331 [NSOpenGLContext clearCurrentContext];
332 SAL_WNODEPRECATED_DECLARATIONS_POP
335 void AquaOpenGLContext::makeCurrent()
337 OSX_SALDATA_RUNINMAIN( makeCurrent() )
339 if (isCurrent())
340 return;
342 OpenGLZone aZone;
344 clearCurrent();
346 SAL_WNODEPRECATED_DECLARATIONS_PUSH
347 // "'NSOpenGLView' is deprecated: first deprecated in macOS 10.14 - Please use MTKView
348 // instead."
349 NSOpenGLView* pView = getOpenGLView();
350 SAL_WNODEPRECATED_DECLARATIONS_POP
351 [[pView openGLContext] makeCurrentContext];
353 registerAsCurrent();
356 void AquaOpenGLContext::swapBuffers()
358 OSX_SALDATA_RUNINMAIN( swapBuffers() )
360 OpenGLZone aZone;
362 SAL_WNODEPRECATED_DECLARATIONS_PUSH
363 // "'NSOpenGLView' is deprecated: first deprecated in macOS 10.14 - Please use MTKView
364 // instead."
365 NSOpenGLView* pView = getOpenGLView();
366 SAL_WNODEPRECATED_DECLARATIONS_POP
367 [[pView openGLContext] flushBuffer];
369 BuffersSwapped();
372 SystemWindowData AquaOpenGLContext::generateWinData(vcl::Window* /*pParent*/, bool bRequestLegacyContext)
374 SystemWindowData aWinData;
375 aWinData.bOpenGL = true;
376 aWinData.bLegacy = bRequestLegacyContext;
377 return aWinData;
380 void AquaOpenGLContext::destroyCurrentContext()
382 OSX_SALDATA_RUNINMAIN( destroyCurrentContext() )
383 SAL_WNODEPRECATED_DECLARATIONS_PUSH
384 // "'NSOpenGLContext' is deprecated: first deprecated in macOS 10.14 - Please use Metal or
385 // MetalKit."
386 [NSOpenGLContext clearCurrentContext];
387 SAL_WNODEPRECATED_DECLARATIONS_POP
390 void AquaOpenGLContext::initWindow()
392 OSX_SALDATA_RUNINMAIN( initWindow() )
394 if( !m_pChildWindow )
396 SystemWindowData winData = generateWinData(mpWindow, mbRequestLegacyContext);
397 m_pChildWindow = VclPtr<SystemChildWindow>::Create(mpWindow, 0, &winData, false);
400 if (m_pChildWindow)
402 InitChildWindow(m_pChildWindow.get());
406 bool AquaOpenGLContext::ImplInit()
408 OSX_SALDATA_RUNINMAIN_UNION( ImplInit(), boolean )
410 OpenGLZone aZone;
412 VCL_GL_INFO("OpenGLContext::ImplInit----start");
413 SAL_WNODEPRECATED_DECLARATIONS_PUSH
414 // "'NSOpenGLView' is deprecated: first deprecated in macOS 10.14 - Please use MTKView
415 // instead."
416 NSOpenGLView* pView = getOpenGLView();
417 SAL_WNODEPRECATED_DECLARATIONS_POP
418 [[pView openGLContext] makeCurrentContext];
420 bool bRet = InitGL();
421 InitGLDebugging();
422 return bRet;
425 SAL_WNODEPRECATED_DECLARATIONS_PUSH
426 // "'NSOpenGLView' is deprecated: first deprecated in macOS 10.14 - Please use MTKView
427 // instead."
428 NSOpenGLView* AquaOpenGLContext::getOpenGLView()
429 SAL_WNODEPRECATED_DECLARATIONS_POP
431 SAL_WNODEPRECATED_DECLARATIONS_PUSH
432 // "'NSOpenGLView' is deprecated: first deprecated in macOS 10.14 - Please use MTKView
433 // instead."
434 return reinterpret_cast<NSOpenGLView*>(m_pChildWindow->GetSystemData()->mpNSView);
435 SAL_WNODEPRECATED_DECLARATIONS_POP
438 OpenGLContext* AquaSalInstance::CreateOpenGLContext()
440 OSX_SALDATA_RUNINMAIN_POINTER( CreateOpenGLContext(), OpenGLContext* )
441 return new AquaOpenGLContext;
444 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */