Logo ROOT   6.16/01
Reference Guide
CocoaPrivate.mm
Go to the documentation of this file.
1// @(#)root/graf2d:$Id$
2// Author: Timur Pocheptsov 29/11/2011
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#define DEBUG_ROOT_COCOA
13
14//#define NDEBUG
15
16#ifdef DEBUG_ROOT_COCOA
17#include <algorithm>
18#endif
19
20#include <stdexcept>
21#include <cassert>
22
23#include <OpenGL/OpenGL.h>
24#include <Cocoa/Cocoa.h>
25
27#include "ROOTOpenGLView.h"
28#include "CocoaPrivate.h"
29#include "QuartzWindow.h"
30#include "CocoaUtils.h"
31
32namespace ROOT {
33namespace MacOSX {
34namespace Details {
35
36//______________________________________________________________________________
38 : fCurrentDrawableID(GetRootWindowID() + 1), //Any real window has id > rootID.
39 //0 is also used by some X11 functions as None.
40 fFreeGLContextID(1),
41 fApplicationDelegate([[ROOTApplicationDelegate alloc] init])
42{
43 //Init NSApplication, if it was not done yet.
45 [NSApplication sharedApplication];
46}
47
48//______________________________________________________________________________
50{
51}
52
53//______________________________________________________________________________
55{
56 //First I had root ID == 0, but this is None in X11 and
57 //it can be used by ROOT, for example, I had trouble with
58 //gClient able to found TGWindow for None - crash!
59 return 1;
60}
61
62//______________________________________________________________________________
63bool CocoaPrivate::IsRootWindow(Window_t windowID)const
64{
65 return windowID == GetRootWindowID();
66}
67
68//______________________________________________________________________________
70{
71 //Return integer identifier for a new "drawable" (like in X11)
72
73 if (fCurrentDrawableID == 999)//I have to skip this, many thanks to ROOT who uses 999 as "all windows".
75
77
78 if (fFreeDrawableIDs.size()) {
79 newID = fFreeDrawableIDs.back();
80 fFreeDrawableIDs.pop_back();
81 } else
83
84 assert(fDrawables.find(newID) == fDrawables.end() && "RegisterDrawable, id for new drawable is still in use");
85 fDrawables[newID] = nsObj;
86
87 return newID;
88}
89
90//______________________________________________________________________________
91NSObject<X11Drawable> *CocoaPrivate::GetDrawable(Drawable_t drawableID)const
92{
93 const_drawable_iterator drawableIter = fDrawables.find(drawableID);
94
95#ifdef DEBUG_ROOT_COCOA
96 if (drawableIter == fDrawables.end()) {
97 NSLog(@"Fatal error: requested non-existing drawable %lu", drawableID);
98 //We do not care about efficiency, ROOT's gonna die on assert :)
99 std::vector<Drawable_t>::const_iterator deletedDrawable = std::find(fFreeDrawableIDs.begin(), fFreeDrawableIDs.end(), drawableID);
100 if (deletedDrawable != fFreeDrawableIDs.end()) {
101 NSLog(@"This drawable was deleted already");
102 } else {
103 NSLog(@"This drawable not found among allocated/deleted drawables");
104 }
105 }
106#endif
107 assert(drawableIter != fDrawables.end() && "GetDrawable, non-existing drawable requested");
108 return drawableIter->second.Get();
109}
110
111//______________________________________________________________________________
112NSObject<X11Window> *CocoaPrivate::GetWindow(Window_t windowID)const
113{
114 const_drawable_iterator winIter = fDrawables.find(windowID);
115#ifdef DEBUG_ROOT_COCOA
116 if (winIter == fDrawables.end()) {
117 NSLog(@"Fatal error: requested non-existing drawable %lu", windowID);
118 //We do not care about efficiency, ROOT's gonna die on assert :)
119 std::vector<Drawable_t>::const_iterator deletedDrawable = std::find(fFreeDrawableIDs.begin(), fFreeDrawableIDs.end(), windowID);
120 if (deletedDrawable != fFreeDrawableIDs.end()) {
121 NSLog(@"This window was deleted already");
122 } else {
123 NSLog(@"This window not found among allocated/deleted drawables");
124 }
125 }
126#endif
127 assert(winIter != fDrawables.end() && "GetWindow, non-existing window requested");
128 return (NSObject<X11Window> *)winIter->second.Get();
129}
130
131//______________________________________________________________________________
133{
134 drawable_iterator drawableIter = fDrawables.find(drawableID);
135 assert(drawableIter != fDrawables.end() && "DeleteDrawable, non existing drawableID");
136
137 NSObject<X11Drawable> * const base = drawableIter->second.Get();
138 if ([base isKindOfClass : [QuartzView class]]) {
139 [(QuartzView *)base removeFromSuperview];
140 ((QuartzView *)base).fParentView = nil;
141 } else if ([base isKindOfClass : [QuartzWindow class]]) {
142 QuartzWindow *qw = (QuartzWindow *)base;
143 qw.fContentView.fParentView = nil;
144 [qw.fContentView removeFromSuperview];
145 qw.contentView = nil;
146 qw.fIsDeleted = YES;
147
148 if (qw.fMainWindow) {
149 [qw.fMainWindow removeChildWindow : qw];
150 qw.fMainWindow = nil;
151 }
152
153 [qw orderOut:nil];
154 }
155
156 fDrawables.erase(drawableIter);//StrongReference should do work here.
157}
158
159//______________________________________________________________________________
160Handle_t CocoaPrivate::RegisterGLContext(NSOpenGLContext *glContext)
161{
162 assert(fGLContextToHandle.find(glContext) == fGLContextToHandle.end() && "RegisterGLContext, context was registered already");
163
164 //Strong es-guarantee guarantee - if we have an exception, everything is rolled-back.
165
166 bool contextInserted = false;
167 try {
169 contextInserted = true;
171 } catch (const std::exception &) {//bad alloc in one of two insertions.
172 if (contextInserted)
174 throw;
175 }
176
177 return fFreeGLContextID++;
178}
179
180//______________________________________________________________________________
182{
183 assert(fHandleToGLContext.find(contextID) != fHandleToGLContext.end() && "DeleteGLContext, bad context id");
184
185 handle2ctx_map::iterator h2cIt = fHandleToGLContext.find(contextID);
186
187 ctx2handle_map::iterator c2hIt = fGLContextToHandle.find(h2cIt->second.Get());
188 assert(c2hIt != fGLContextToHandle.end() && "DeleteGLContext, inconsistent context map");
189
190 fGLContextToHandle.erase(c2hIt);
191 fHandleToGLContext.erase(h2cIt);//RAII does work here.
192}
193
194//______________________________________________________________________________
195NSOpenGLContext *CocoaPrivate::GetGLContextForHandle(Handle_t ctxID)
196{
197 if (fHandleToGLContext.find(ctxID) == fHandleToGLContext.end())
198 return nil;
199
200 return fHandleToGLContext[ctxID].Get();
201}
202
203//______________________________________________________________________________
204Handle_t CocoaPrivate::GetHandleForGLContext(NSOpenGLContext *glContext)
205{
206 if (fGLContextToHandle.find(glContext) == fGLContextToHandle.end())
207 return Handle_t();
208
209 return fGLContextToHandle[glContext];
210}
211
212//______________________________________________________________________________
214{
215 fFakeGLWindow.Reset(fakeWin);
216}
217
218//______________________________________________________________________________
220{
221 return fFakeGLWindow.Get();
222}
223
224//______________________________________________________________________________
225void CocoaPrivate::ReplaceDrawable(Drawable_t drawableID, NSObject *nsObj)
226{
227 drawable_iterator drawableIter = fDrawables.find(drawableID);
228 assert(drawableIter != fDrawables.end() && "ReplaceDrawable, can not replace non existing drawable");
229 drawableIter->second.Reset(nsObj);
230}
231
232}//Details
233}//MacOSX
234}//ROOT
ULong_t Handle_t
Definition: GuiTypes.h:25
Handle_t Drawable_t
Definition: GuiTypes.h:30
Handle_t Window_t
Definition: GuiTypes.h:28
static Int_t init()
void SetFakeGLWindow(QuartzWindow *fakeWin)
Drawable_t RegisterDrawable(NSObject *nsObj)
void DeleteDrawable(Drawable_t drawableID)
Handle_t GetHandleForGLContext(NSOpenGLContext *glContext)
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > >::iterator drawable_iterator
Definition: CocoaPrivate.h:98
Util::NSStrongReference< QuartzWindow > fFakeGLWindow
Definition: CocoaPrivate.h:108
NSObject< X11Drawable > * GetDrawable(Drawable_t drawableD) const
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > >::const_iterator const_drawable_iterator
Definition: CocoaPrivate.h:99
void DeleteGLContext(Handle_t contextID)
std::vector< Drawable_t > fFreeDrawableIDs
Definition: CocoaPrivate.h:95
Handle_t RegisterGLContext(NSOpenGLContext *glContext)
NSObject< X11Window > * GetWindow(Window_t windowID) const
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > > fDrawables
Definition: CocoaPrivate.h:97
void ReplaceDrawable(Drawable_t drawableID, NSObject *nsObj)
NSOpenGLContext * GetGLContextForHandle(Handle_t contextID)
bool IsRootWindow(Window_t windowID) const
QuartzView * fParentView
Definition: QuartzWindow.h:165
QuartzView * fContentView
Definition: QuartzWindow.h:36
QuartzWindow * fMainWindow
Definition: QuartzWindow.h:33
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21