Logo ROOT  
Reference Guide
ROOTOpenGLView.mm
Go to the documentation of this file.
1// @(#)root/graf2d:$Id$
2// Author: Timur Pocheptsov 26/04/2012
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <cassert>
13
14#include "ROOTOpenGLView.h"
15#include "X11Events.h"
16#include "TGCocoa.h"
17
18namespace ROOT {
19namespace MacOSX {
20namespace OpenGL {
21
22//______________________________________________________________________________
24{
25 assert(glView != nil && "GLViewIsValid, glView parameter is nil");
26
27 if ([glView isHiddenOrHasHiddenAncestor]) {
28 //This will result in "invalid drawable" message
29 //from -setView:.
30 return false;
31 }
32
33 const NSRect visibleRect = [glView visibleRect];
34 if (visibleRect.size.width < 1. || visibleRect.size.height < 1.) {
35 //Another reason for "invalid drawable" message.
36 return false;
37 }
38
39 return true;
40}
41
42}
43}
44}
45
46@implementation ROOTOpenGLView
47
48@synthesize fOpenGLContext;
49@synthesize fUpdateContext;
50
51//______________________________________________________________________________
52- (id) initWithFrame : (NSRect) frameRect pixelFormat : (NSOpenGLPixelFormat *) format
53{
54 if (self = [super initWithFrame : frameRect windowAttributes : 0]) {
55 [self setHidden : YES];//Not sure.
56 fIsOverlapped = NO;
57 fPixelFormat = [format retain];
58
59 if ([[NSScreen mainScreen] backingScaleFactor] > 1.)
60 [self setWantsBestResolutionOpenGLSurface : YES];
61 }
62
63 return self;
64}
65
66//______________________________________________________________________________
67- (void) dealloc
68{
69 if (fOpenGLContext && [fOpenGLContext view] == self)
70 [fOpenGLContext clearDrawable];
71
72 self.fOpenGLContext = nil;
73 [fPixelFormat release];
74 //View does not own context.
75 [super dealloc];
76}
77
78//______________________________________________________________________________
79- (NSOpenGLPixelFormat *) pixelFormat
80{
81 return fPixelFormat;
82}
83
84//______________________________________________________________________________
85- (void) setPixelFormat : (NSOpenGLPixelFormat *) pixelFormat
86{
88 [fPixelFormat release];
89 fPixelFormat = [pixelFormat retain];
90 }
91}
92
93//X11Drawable protocol.
94
95//______________________________________________________________________________
97{
98 return YES;
99}
100
101//______________________________________________________________________________
103{
104 //GL-view does not have/need any "back buffer".
105 return nil;
106}
107
108//______________________________________________________________________________
109- (void) setFBackBuffer : (QuartzPixmap *) notUsed
110{
111 //GL-view does not have/need any "back buffer".
112#pragma unused(notUsed)
113}
114
115//______________________________________________________________________________
116- (void) mapWindow
117{
118 [self setHidden : NO];
119}
120
121//______________________________________________________________________________
123{
124 //GL-view can not have any subwindows.
125 assert([[self subviews] count] == 0 && "mapSubwindows, GL-view has children");
126}
127
128//______________________________________________________________________________
130{
131 //The only node in the tree is 'self'.
132 if (self.fMapState == kIsViewable) {
133 if (self.fEventMask & kStructureNotifyMask) {
134 assert(dynamic_cast<TGCocoa *>(gVirtualX) &&
135 "configureNotifyTree, gVirtualX is either null or has type different from TGCocoa");
136 TGCocoa * const vx = static_cast<TGCocoa *>(gVirtualX);
137 vx->GetEventTranslator()->GenerateConfigureNotifyEvent(self, self.frame);
138 }
139 }
140}
141
142//______________________________________________________________________________
144{
145 return fIsOverlapped;
146}
147
148//______________________________________________________________________________
149- (void) setOverlapped : (BOOL) overlap
150{
151 //If GL-view is overlapped by another view,
152 //it must be hidden (overwise it will be always on top,
153 //producing some strange-looking buggy GUI).
154
155 fIsOverlapped = overlap;
156 [self setHidden : fIsOverlapped];
157
158 if (!overlap) {
159 assert(dynamic_cast<TGCocoa *>(gVirtualX) != 0 &&
160 "setFrameSize:, gVirtualX is either null or has a type, different from TGCocoa");
161 [fOpenGLContext update];
162 //View becomes visible, geometry can be changed at this point,
163 //notify ROOT's GL code about this changes.
164 TGCocoa * const vx = static_cast<TGCocoa *>(gVirtualX);
165 vx->GetEventTranslator()->GenerateConfigureNotifyEvent(self, self.frame);
166 vx->GetEventTranslator()->GenerateExposeEvent(self, self.frame);
167 }
168}
169
170//______________________________________________________________________________
171- (BOOL) isFlipped
172{
173 return YES;
174}
175
176//______________________________________________________________________________
177- (void) setFrame : (NSRect) newFrame
178{
179 //In case of TBrowser, setFrame started infinite recursion:
180 //HandleConfigure for embedded main frame emits signal, slot
181 //calls layout, layout calls setFrame -> HandleConfigure and etc. etc.
182 if (NSEqualRects(newFrame, self.frame))
183 return;
184
185 [super setFrame : newFrame];
186}
187
188//______________________________________________________________________________
189- (void) setFrameSize : (NSSize) newSize
190{
191 //Check, if setFrameSize calls setFrame.
192
193 [super setFrameSize : newSize];
194
195 if (![self isHiddenOrHasHiddenAncestor] && !fIsOverlapped)
196 [fOpenGLContext update];
197 else
198 fUpdateContext = YES;
199
200 if ((self.fEventMask & kStructureNotifyMask) && (self.fMapState == kIsViewable || fIsOverlapped == YES)) {
201 assert(dynamic_cast<TGCocoa *>(gVirtualX) != 0 &&
202 "setFrameSize:, gVirtualX is either null or has a type, different from TGCocoa");
203 TGCocoa * const vx = static_cast<TGCocoa *>(gVirtualX);
204 vx->GetEventTranslator()->GenerateConfigureNotifyEvent(self, self.frame);
205 vx->GetEventTranslator()->GenerateExposeEvent(self, self.frame);
206 }
207}
208
209//______________________________________________________________________________
210- (void) drawRect : (NSRect) dirtyRect
211{
212#pragma unused(dirtyRect)
213}
214
215//______________________________________________________________________________
216
217- (BOOL) wantsLayer
218{
219 return NO;
220}
221
222//______________________________________________________________________________
223
224- (void) setLayer:(CALayer *) layer
225{
226#pragma unused(layer)
227}
228
229@end
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
const Mask_t kStructureNotifyMask
Definition: GuiTypes.h:166
@ kIsViewable
Definition: GuiTypes.h:46
XFontStruct * id
Definition: TGX11.cxx:109
#define gVirtualX
Definition: TVirtualX.h:338
void GenerateExposeEvent(NSView< X11Window > *view, const NSRect &exposedRect)
Definition: X11Events.mm:1174
void GenerateConfigureNotifyEvent(NSView< X11Window > *view, const NSRect &newFrame)
Definition: X11Events.mm:1149
This class implements TVirtualX interface for MacOS X, using Cocoa and Quartz 2D.
Definition: TGCocoa.h:58
ROOT::MacOSX::X11::EventTranslator * GetEventTranslator() const
Definition: TGCocoa.mm:4399
NSOpenGLContext * fOpenGLContext
NSOpenGLPixelFormat * pixelFormat()
QuartzPixmap * fBackBuffer
NSOpenGLPixelFormat * fPixelFormat
bool GLViewIsValidDrawable(ROOTOpenGLView *glView)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...