Logo ROOT  
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 
32 namespace ROOT {
33 namespace MacOSX {
34 namespace 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.
44  Util::AutoreleasePool pool;
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 //______________________________________________________________________________
63 bool 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 //______________________________________________________________________________
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 //______________________________________________________________________________
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  return 0;
126  }
127 #endif
128  assert(winIter != fDrawables.end() && "GetWindow, non-existing window requested");
129  return (NSObject<X11Window> *)winIter->second.Get();
130 }
131 
132 //______________________________________________________________________________
134 {
135  drawable_iterator drawableIter = fDrawables.find(drawableID);
136  assert(drawableIter != fDrawables.end() && "DeleteDrawable, non existing drawableID");
137 
138  NSObject<X11Drawable> * const base = drawableIter->second.Get();
139  if ([base isKindOfClass : [QuartzView class]]) {
140  [(QuartzView *)base removeFromSuperview];
141  ((QuartzView *)base).fParentView = nil;
142  } else if ([base isKindOfClass : [QuartzWindow class]]) {
143  QuartzWindow *qw = (QuartzWindow *)base;
144  qw.fContentView.fParentView = nil;
145  [qw.fContentView removeFromSuperview];
146  qw.contentView = nil;
147  qw.fIsDeleted = YES;
148 
149  if (qw.fMainWindow) {
150  [qw.fMainWindow removeChildWindow : qw];
151  qw.fMainWindow = nil;
152  }
153 
154  [qw orderOut:nil];
155  }
156 
157  fDrawables.erase(drawableIter);//StrongReference should do work here.
158 }
159 
160 //______________________________________________________________________________
161 Handle_t CocoaPrivate::RegisterGLContext(NSOpenGLContext *glContext)
162 {
163  assert(fGLContextToHandle.find(glContext) == fGLContextToHandle.end() && "RegisterGLContext, context was registered already");
164 
165  //Strong es-guarantee guarantee - if we have an exception, everything is rolled-back.
166 
167  bool contextInserted = false;
168  try {
170  contextInserted = true;
172  } catch (const std::exception &) {//bad alloc in one of two insertions.
173  if (contextInserted)
175  throw;
176  }
177 
178  return fFreeGLContextID++;
179 }
180 
181 //______________________________________________________________________________
183 {
184  assert(fHandleToGLContext.find(contextID) != fHandleToGLContext.end() && "DeleteGLContext, bad context id");
185 
186  handle2ctx_map::iterator h2cIt = fHandleToGLContext.find(contextID);
187 
188  ctx2handle_map::iterator c2hIt = fGLContextToHandle.find(h2cIt->second.Get());
189  assert(c2hIt != fGLContextToHandle.end() && "DeleteGLContext, inconsistent context map");
190 
191  fGLContextToHandle.erase(c2hIt);
192  fHandleToGLContext.erase(h2cIt);//RAII does work here.
193 }
194 
195 //______________________________________________________________________________
196 NSOpenGLContext *CocoaPrivate::GetGLContextForHandle(Handle_t ctxID)
197 {
198  if (fHandleToGLContext.find(ctxID) == fHandleToGLContext.end())
199  return nil;
200 
201  return fHandleToGLContext[ctxID].Get();
202 }
203 
204 //______________________________________________________________________________
205 Handle_t CocoaPrivate::GetHandleForGLContext(NSOpenGLContext *glContext)
206 {
207  if (fGLContextToHandle.find(glContext) == fGLContextToHandle.end())
208  return Handle_t();
209 
210  return fGLContextToHandle[glContext];
211 }
212 
213 //______________________________________________________________________________
215 {
216  fFakeGLWindow.Reset(fakeWin);
217 }
218 
219 //______________________________________________________________________________
221 {
222  return fFakeGLWindow.Get();
223 }
224 
225 //______________________________________________________________________________
226 void CocoaPrivate::ReplaceDrawable(Drawable_t drawableID, NSObject *nsObj)
227 {
228  drawable_iterator drawableIter = fDrawables.find(drawableID);
229  assert(drawableIter != fDrawables.end() && "ReplaceDrawable, can not replace non existing drawable");
230  drawableIter->second.Reset(nsObj);
231 }
232 
233 }//Details
234 }//MacOSX
235 }//ROOT
ROOT::MacOSX::Details::CocoaPrivate::DeleteGLContext
void DeleteGLContext(Handle_t contextID)
ROOT::MacOSX::Details::CocoaPrivate::fFakeGLWindow
Util::NSStrongReference< QuartzWindow > fFakeGLWindow
Definition: CocoaPrivate.h:108
ROOT::MacOSX::Details::CocoaPrivate::fCurrentDrawableID
Drawable_t fCurrentDrawableID
Definition: CocoaPrivate.h:93
CocoaUtils.h
QuartzWindow.h
ROOT::MacOSX::Details::CocoaPrivate::GetWindow
NSObject< X11Window > * GetWindow(Window_t windowID) const
ROOT::MacOSX::Details::CocoaPrivate::GetRootWindowID
Window_t GetRootWindowID() const
ROOT::MacOSX::Details::CocoaPrivate::fGLContextToHandle
ctx2handle_map fGLContextToHandle
Definition: CocoaPrivate.h:105
ROOT::MacOSX::Details::CocoaPrivate::IsRootWindow
bool IsRootWindow(Window_t windowID) const
ROOT::MacOSX::Details::CocoaPrivate::CocoaPrivate
CocoaPrivate()
BatchHelpers::init
EvaluateInfo init(std::vector< RooRealProxy > parameters, std::vector< ArrayWrapper * > wrappers, std::vector< double * > arrays, size_t begin, size_t batchSize)
ROOT::MacOSX::Details::CocoaPrivate::SetFakeGLWindow
void SetFakeGLWindow(QuartzWindow *fakeWin)
ROOT::MacOSX::Details::CocoaPrivate::RegisterDrawable
Drawable_t RegisterDrawable(NSObject *nsObj)
ROOT::MacOSX::Details::CocoaPrivate::ReplaceDrawable
void ReplaceDrawable(Drawable_t drawableID, NSObject *nsObj)
ROOTOpenGLView.h
ROOT::MacOSX::Details::CocoaPrivate::fFreeGLContextID
Handle_t fFreeGLContextID
Definition: CocoaPrivate.h:107
ROOTApplicationDelegate.h
ROOT::MacOSX::Details::CocoaPrivate::~CocoaPrivate
~CocoaPrivate()
ROOT::MacOSX::Details::CocoaPrivate::DeleteDrawable
void DeleteDrawable(Drawable_t drawableID)
Drawable_t
Handle_t Drawable_t
Definition: GuiTypes.h:30
ROOT::MacOSX::Details::CocoaPrivate::fFreeDrawableIDs
std::vector< Drawable_t > fFreeDrawableIDs
Definition: CocoaPrivate.h:95
ROOT::MacOSX::Details::CocoaPrivate::RegisterGLContext
Handle_t RegisterGLContext(NSOpenGLContext *glContext)
ROOT::MacOSX::Details::CocoaPrivate::fHandleToGLContext
handle2ctx_map fHandleToGLContext
Definition: CocoaPrivate.h:104
ROOT::MacOSX::Util::NSStrongReference::Reset
void Reset(NSObject *object)
Definition: CocoaUtils.h:122
QuartzView
Definition: QuartzWindow.h:183
ROOT::MacOSX::Details::CocoaPrivate::fDrawables
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > > fDrawables
Definition: CocoaPrivate.h:97
QuartzWindow::fMainWindow
QuartzWindow * fMainWindow
Definition: QuartzWindow.h:58
Window_t
Handle_t Window_t
Definition: GuiTypes.h:28
ROOT::MacOSX::Details::CocoaPrivate::GetGLContextForHandle
NSOpenGLContext * GetGLContextForHandle(Handle_t contextID)
ROOT::MacOSX::Details
Definition: TMacOSXSystem.h:42
ROOT::MacOSX::Details::CocoaPrivate::GetDrawable
NSObject< X11Drawable > * GetDrawable(Drawable_t drawableD) const
ROOT::MacOSX::Details::CocoaPrivate::GetHandleForGLContext
Handle_t GetHandleForGLContext(NSOpenGLContext *glContext)
ROOT::MacOSX::Util::NSStrongReference::Get
DerivedType * Get() const
Definition: CocoaUtils.h:117
Handle_t
ULong_t Handle_t
Definition: GuiTypes.h:25
NSObject
QuartzView::fParentView
QuartzView * fParentView
Definition: QuartzWindow.h:196
ROOT::MacOSX::Details::CocoaPrivate::GetFakeGLWindow
QuartzWindow * GetFakeGLWindow()
ROOT::MacOSX::Details::CocoaPrivate::drawable_iterator
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > >::iterator drawable_iterator
Definition: CocoaPrivate.h:98
QuartzWindow::fIsDeleted
BOOL fIsDeleted
Definition: QuartzWindow.h:64
ROOT
VSD Structures.
Definition: StringConv.hxx:21
QuartzWindow::fContentView
QuartzView * fContentView
Definition: QuartzWindow.h:61
ROOTApplicationDelegate
Definition: ROOTApplicationDelegate.h:6
ROOT::MacOSX::Details::CocoaPrivate::const_drawable_iterator
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > >::const_iterator const_drawable_iterator
Definition: CocoaPrivate.h:99
CocoaPrivate.h
QuartzWindow
Definition: QuartzWindow.h:56