Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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//______________________________________________________________________________
92{
93 const_drawable_iterator drawableIter = fDrawables.find(drawableID);
94
95 if (drawableIter == fDrawables.end()) {
96 NSLog(@"Fatal error: requested drawable %lu is not found among currently valid drawables.", drawableID);
97 /*
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 return nil;
107 }
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//______________________________________________________________________________
161Handle_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//______________________________________________________________________________
196NSOpenGLContext *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//______________________________________________________________________________
205Handle_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//______________________________________________________________________________
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
Handle_t Window_t
Window handle.
Definition GuiTypes.h:29
Handle_t Drawable_t
Drawable handle.
Definition GuiTypes.h:31
ULongptr_t Handle_t
Generic resource handle.
Definition GuiTypes.h:26
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
Util::NSStrongReference< QuartzWindow > fFakeGLWindow
NSObject< X11Drawable > * GetDrawable(Drawable_t drawableD) const
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > >::const_iterator const_drawable_iterator
void DeleteGLContext(Handle_t contextID)
std::vector< Drawable_t > fFreeDrawableIDs
Handle_t RegisterGLContext(NSOpenGLContext *glContext)
NSObject< X11Window > * GetWindow(Window_t windowID) const
std::map< unsigned, Util::NSStrongReference< NSObject< X11Drawable > > > fDrawables
void ReplaceDrawable(Drawable_t drawableID, NSObject *nsObj)
NSOpenGLContext * GetGLContextForHandle(Handle_t contextID)
bool IsRootWindow(Window_t windowID) const
QuartzView * fParentView
QuartzWindow * fMainWindow
QuartzView * fContentView
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.