Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / osx / salobj.cxx
blob9e6e746d5b350a03ae09a495025bb0c92929ea30
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 <vcl/opengl/OpenGLContext.hxx>
22 #include <vcl/opengl/OpenGLHelper.hxx>
23 #include <opengl/zone.hxx>
25 #include "osx/saldata.hxx"
26 #include "osx/salframe.h"
27 #include "osx/salinst.h"
28 #include "osx/salobj.h"
30 #include <AppKit/NSOpenGLView.h>
32 AquaSalObject::AquaSalObject( AquaSalFrame* pFrame, SystemWindowData* pWindowData ) :
33 mpFrame( pFrame ),
34 mnClipX( -1 ),
35 mnClipY( -1 ),
36 mnClipWidth( -1 ),
37 mnClipHeight( -1 ),
38 mbClip( false ),
39 mnX( 0 ),
40 mnY( 0 ),
41 mnWidth( 20 ),
42 mnHeight( 20 )
44 maSysData.nSize = sizeof( maSysData );
45 maSysData.mpNSView = nullptr;
46 maSysData.mbOpenGL = false;
48 NSRect aInitFrame = { NSZeroPoint, { 20, 20 } };
49 mpClipView = [[NSClipView alloc] initWithFrame: aInitFrame ];
50 if( mpClipView )
52 [mpFrame->getNSView() addSubview: mpClipView];
53 [mpClipView setHidden: YES];
55 if (pWindowData && pWindowData->bOpenGL)
57 maSysData.mbOpenGL = true;
58 NSOpenGLPixelFormat* pixFormat = nullptr;
60 if (pWindowData->bLegacy)
62 NSOpenGLPixelFormatAttribute aAttributes[] =
64 NSOpenGLPFADoubleBuffer,
65 NSOpenGLPFAAlphaSize, 8,
66 NSOpenGLPFAColorSize, 24,
67 NSOpenGLPFADepthSize, 24,
68 NSOpenGLPFAMultisample,
69 NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)1,
70 NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)4,
73 pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:aAttributes];
75 else
77 NSOpenGLPixelFormatAttribute aAttributes[] =
79 NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
80 NSOpenGLPFADoubleBuffer,
81 NSOpenGLPFAAlphaSize, 8,
82 NSOpenGLPFAColorSize, 24,
83 NSOpenGLPFADepthSize, 24,
84 NSOpenGLPFAMultisample,
85 NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)1,
86 NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)4,
89 pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:aAttributes];
92 maSysData.mpNSView = [[NSOpenGLView alloc] initWithFrame: aInitFrame pixelFormat:pixFormat];
94 else
96 maSysData.mpNSView = [[NSView alloc] initWithFrame: aInitFrame];
99 if( maSysData.mpNSView )
101 if( mpClipView )
102 [mpClipView setDocumentView: maSysData.mpNSView];
106 AquaSalObject::~AquaSalObject()
108 if( maSysData.mpNSView )
110 NSView *pView = maSysData.mpNSView;
111 [pView removeFromSuperview];
112 [pView release];
114 if( mpClipView )
116 [mpClipView removeFromSuperview];
117 [mpClipView release];
121 // Please note that the talk about QTMovieView below presumably refers
122 // to stuff in the QuickTime avmedia thingie, and that QuickTime is
123 // deprecated, not available for 64-bit code, and won't thus be used
124 // in a "modern" build of LO anyway. So the relevance of the comment
125 // is unclear.
128 sadly there seems to be no way to impose clipping on a child view,
129 especially a QTMovieView which seems to ignore the current context
130 completely. Also there is no real way to shape a window; on Aqua a
131 similar effect to non-rectangular windows is achieved by using a
132 non-opaque window and not painting where one wants the background
133 to shine through.
135 With respect to SalObject this leaves us to having an NSClipView
136 containing the child view. Even a QTMovieView respects the boundaries of
137 that, which gives us a clip "region" consisting of one rectangle.
138 This is gives us an 80% solution only, though.
141 void AquaSalObject::ResetClipRegion()
143 mbClip = false;
144 setClippedPosSize();
147 void AquaSalObject::BeginSetClipRegion( sal_uLong )
149 mbClip = false;
152 void AquaSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
154 if( mbClip )
156 if( nX < mnClipX )
158 mnClipWidth += mnClipX - nX;
159 mnClipX = nX;
161 if( nX + nWidth > mnClipX + mnClipWidth )
162 mnClipWidth = nX + nWidth - mnClipX;
163 if( nY < mnClipY )
165 mnClipHeight += mnClipY - nY;
166 mnClipY = nY;
168 if( nY + nHeight > mnClipY + mnClipHeight )
169 mnClipHeight = nY + nHeight - mnClipY;
171 else
173 mnClipX = nX;
174 mnClipY = nY;
175 mnClipWidth = nWidth;
176 mnClipHeight = nHeight;
177 mbClip = true;
181 void AquaSalObject::EndSetClipRegion()
183 setClippedPosSize();
186 void AquaSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
188 mnX = nX;
189 mnY = nY;
190 mnWidth = nWidth;
191 mnHeight = nHeight;
192 setClippedPosSize();
195 void AquaSalObject::setClippedPosSize()
197 NSRect aViewRect = { NSZeroPoint, NSMakeSize( mnWidth, mnHeight) };
198 if( maSysData.mpNSView )
200 NSView* pNSView = maSysData.mpNSView;
201 [pNSView setFrame: aViewRect];
204 NSRect aClipViewRect = NSMakeRect( mnX, mnY, mnWidth, mnHeight);
205 NSPoint aClipPt = NSZeroPoint;
206 if( mbClip )
208 aClipViewRect.origin.x += mnClipX;
209 aClipViewRect.origin.y += mnClipY;
210 aClipViewRect.size.width = mnClipWidth;
211 aClipViewRect.size.height = mnClipHeight;
212 aClipPt.x = mnClipX;
213 if( mnClipY == 0 )
214 aClipPt.y = mnHeight - mnClipHeight;
217 mpFrame->VCLToCocoa( aClipViewRect, false );
218 [mpClipView setFrame: aClipViewRect];
220 [mpClipView scrollToPoint: aClipPt];
223 void AquaSalObject::Show( bool bVisible )
225 if( mpClipView )
226 [mpClipView setHidden: (bVisible ? NO : YES)];
229 const SystemEnvData* AquaSalObject::GetSystemData() const
231 return &maSysData;
234 class AquaOpenGLContext : public OpenGLContext
236 public:
237 virtual bool initWindow() override;
238 private:
239 GLWindow m_aGLWin;
240 virtual const GLWindow& getOpenGLWindow() const override { return m_aGLWin; }
241 virtual GLWindow& getModifiableOpenGLWindow() override { return m_aGLWin; }
242 NSOpenGLView* getOpenGLView();
243 virtual bool ImplInit() override;
244 virtual SystemWindowData generateWinData(vcl::Window* pParent, bool bRequestLegacyContext) override;
245 virtual void makeCurrent() override;
246 virtual void destroyCurrentContext() override;
247 virtual void resetCurrent() override;
248 virtual void swapBuffers() override;
251 void AquaOpenGLContext::resetCurrent()
253 clearCurrent();
255 OpenGLZone aZone;
257 (void) this; // loplugin:staticmethods
258 [NSOpenGLContext clearCurrentContext];
261 void AquaOpenGLContext::makeCurrent()
263 if (isCurrent())
264 return;
266 OpenGLZone aZone;
268 clearCurrent();
270 NSOpenGLView* pView = getOpenGLView();
271 [[pView openGLContext] makeCurrentContext];
273 registerAsCurrent();
276 void AquaOpenGLContext::swapBuffers()
278 OpenGLZone aZone;
280 NSOpenGLView* pView = getOpenGLView();
281 [[pView openGLContext] flushBuffer];
283 BuffersSwapped();
286 SystemWindowData AquaOpenGLContext::generateWinData(vcl::Window* /*pParent*/, bool bRequestLegacyContext)
288 SystemWindowData aWinData;
289 aWinData.bOpenGL = true;
290 aWinData.bLegacy = bRequestLegacyContext;
291 aWinData.nSize = sizeof(aWinData);
292 return aWinData;
295 void AquaOpenGLContext::destroyCurrentContext()
297 [NSOpenGLContext clearCurrentContext];
300 bool AquaOpenGLContext::initWindow()
302 if( !m_pChildWindow )
304 SystemWindowData winData = generateWinData(mpWindow, mbRequestLegacyContext);
305 m_pChildWindow = VclPtr<SystemChildWindow>::Create(mpWindow, 0, &winData, false);
308 if (m_pChildWindow)
310 InitChildWindow(m_pChildWindow.get());
313 return true;
316 bool AquaOpenGLContext::ImplInit()
318 OpenGLZone aZone;
320 VCL_GL_INFO("OpenGLContext::ImplInit----start");
321 NSOpenGLView* pView = getOpenGLView();
322 [[pView openGLContext] makeCurrentContext];
324 bool bRet = InitGL();
325 InitGLDebugging();
326 return bRet;
329 NSOpenGLView* AquaOpenGLContext::getOpenGLView()
331 return reinterpret_cast<NSOpenGLView*>(m_pChildWindow->GetSystemData()->mpNSView);
334 OpenGLContext* AquaSalInstance::CreateOpenGLContext()
336 return new AquaOpenGLContext;
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */