ROOT  6.06/09
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.
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 //______________________________________________________________________________
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 //______________________________________________________________________________
91 NSObject<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 //______________________________________________________________________________
112 NSObject<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 //______________________________________________________________________________
160 Handle_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 {
168  fHandleToGLContext[fFreeGLContextID] = glContext;
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 //______________________________________________________________________________
196 {
197  if (fHandleToGLContext.find(ctxID) == fHandleToGLContext.end())
198  return nil;
199 
200  return fHandleToGLContext[ctxID].Get();
201 }
202 
203 //______________________________________________________________________________
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 //______________________________________________________________________________
225 void 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
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > >::const_iterator const_drawable_iterator
Definition: CocoaPrivate.h:111
NSObject< X11Drawable > * GetDrawable(Drawable_t drawableD) const
Definition: CocoaPrivate.mm:91
void DeleteGLContext(Handle_t contextID)
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
Util::NSStrongReference< QuartzWindow > fFakeGLWindow
Definition: CocoaPrivate.h:120
#define assert(cond)
Definition: unittest.h:542
QuartzView * fContentView
Definition: QuartzWindow.h:46
void ReplaceDrawable(Drawable_t drawableID, NSObject *nsObj)
Handle_t Drawable_t
Definition: GuiTypes.h:32
NSOpenGLContext * GetGLContextForHandle(Handle_t contextID)
Drawable_t RegisterDrawable(NSObject *nsObj)
Definition: CocoaPrivate.mm:69
void SetFakeGLWindow(QuartzWindow *fakeWin)
QuartzView * fParentView
Definition: QuartzWindow.h:180
DerivedType * Get() const
Definition: CocoaUtils.h:93
void DeleteDrawable(Drawable_t drawableID)
std::vector< Drawable_t > fFreeDrawableIDs
Definition: CocoaPrivate.h:107
Handle_t RegisterGLContext(NSOpenGLContext *glContext)
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > > fDrawables
Definition: CocoaPrivate.h:109
QuartzWindow * fMainWindow
Definition: QuartzWindow.h:42
static Int_t init()
NSObject< X11Window > * GetWindow(Window_t windowID) const
void Reset(NSObject *object)
Definition: CocoaUtils.h:98
Handle_t GetHandleForGLContext(NSOpenGLContext *glContext)
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > >::iterator drawable_iterator
Definition: CocoaPrivate.h:110
Handle_t Window_t
Definition: GuiTypes.h:30
bool IsRootWindow(Window_t windowID) const
Definition: CocoaPrivate.mm:63
ULong_t Handle_t
Definition: GuiTypes.h:27