Logo ROOT   6.16/01
Reference Guide
TGCocoa.mm
Go to the documentation of this file.
1// @(#)root/graf2d:$Id$
2// Author: Timur Pocheptsov 22/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 NDEBUG
13
14#include "TGCocoa.h"
15
16// We want to pickup ROOT's glew and not the system OpenGL coming from:
17// ROOTOpenGLView.h ->QuartzWindow.h->Cocoa.h
18// Allowing TU's which include the system GL and then glew (from TGLIncludes)
19// leads to gltypes.h redefinition errors.
20#include "TGLIncludes.h"
21
22#include "ROOTOpenGLView.h"
23#include "CocoaConstants.h"
24#include "TMacOSXSystem.h"
25#include "CocoaPrivate.h"
26#include "QuartzWindow.h"
27#include "QuartzPixmap.h"
28#include "QuartzUtils.h"
29#include "X11Drawable.h"
30#include "QuartzText.h"
31#include "CocoaUtils.h"
32#include "MenuLoader.h"
33#include "TVirtualGL.h"
34#include "X11Events.h"
35#include "X11Buffer.h"
36#include "TGClient.h"
37#include "TGWindow.h"
38#include "TSystem.h"
39#include "TGFrame.h"
40#include "TGLIncludes.h"
41#include "TError.h"
42#include "TColor.h"
43#include "TROOT.h"
44#include "TEnv.h"
45#include "TVirtualMutex.h"
46
47#include <ApplicationServices/ApplicationServices.h>
48#include <OpenGL/OpenGL.h>
49#include <Cocoa/Cocoa.h>
50
51#include <algorithm>
52#include <stdexcept>
53#include <cassert>
54#include <cstring>
55#include <cstddef>
56#include <limits>
57
58
59//Style notes: I'm using a lot of asserts to check pre-conditions - mainly function parameters.
60//In asserts, expression always looks like 'p != 0' for "C++ pointer" (either object of built-in type
61//or C++ class), and 'p != nil' for object from Objective-C. There is no difference, this is to make
62//asserts more explicit. In conditional statement, it'll always be 'if (p)' or 'if (!p)' for both
63//C++ and Objective-C pointers/code.
64
65//I never use const qualifier for pointers to Objective-C objects since they are useless:
66//there are no cv-qualified methods (member-functions in C++) in Objective-C, and I do not use
67//'->' operator to access instance variables (data-members in C++) of Objective-C's object.
68//I also declare pointer as a const, if it's const:
69//NSWindow * const topLevelWindow = ... (and note, not pointer to const - no use with Obj-C).
70
71//Asserts on drawables ids usually only check, that it's not a 'root' window id (unless operation
72//is permitted on a 'root' window):
73//a) assert(!fPimpl->IsRootWindow(windowID)) and later I also check that windowID != 0 (kNone).
74//b) assert(drawableID > fPimpl->GetRootWindowID()) so drawableID can not be kNone and
75// can not be a 'root' window.
76
77//ROOT window has id 1. So if id > 1 (id > fPimpl->GetRootWindowID())
78//id is considered as valid (if it's out of range and > maximum valid id, this will be
79//caught by CocoaPrivate.
80
82namespace Util = ROOT::MacOSX::Util;
83namespace X11 = ROOT::MacOSX::X11;
84namespace Quartz = ROOT::Quartz;
86
87namespace {
88
89#pragma mark - Display configuration management.
90
91//______________________________________________________________________________
92void DisplayReconfigurationCallback(CGDirectDisplayID /*display*/, CGDisplayChangeSummaryFlags flags, void * /*userInfo*/)
93{
94 if (flags & kCGDisplayBeginConfigurationFlag)
95 return;
96
97 if (flags & kCGDisplayDesktopShapeChangedFlag) {
98 assert(dynamic_cast<TGCocoa *>(gVirtualX) != 0 && "DisplayReconfigurationCallback, gVirtualX"
99 " is either null or has a wrong type");
100 TGCocoa * const gCocoa = static_cast<TGCocoa *>(gVirtualX);
101 gCocoa->ReconfigureDisplay();
102 }
103}
104
105#pragma mark - Aux. functions called from GUI-rendering part.
106
107//______________________________________________________________________________
108void SetStrokeForegroundColorFromX11Context(CGContextRef ctx, const GCValues_t &gcVals)
109{
110 assert(ctx != 0 && "SetStrokeForegroundColorFromX11Context, parameter 'ctx' is null");
111
112 CGFloat rgb[3] = {};
113 if (gcVals.fMask & kGCForeground)
114 X11::PixelToRGB(gcVals.fForeground, rgb);
115 else
116 ::Warning("SetStrokeForegroundColorFromX11Context",
117 "x11 context does not have line color information");
118
119 CGContextSetRGBStrokeColor(ctx, rgb[0], rgb[1], rgb[2], 1.);
120}
121
122//______________________________________________________________________________
123void SetStrokeDashFromX11Context(CGContextRef ctx, const GCValues_t &gcVals)
124{
125 //Set line dash pattern (X11's LineOnOffDash line style).
126 assert(ctx != 0 && "SetStrokeDashFromX11Context, ctx parameter is null");
127
128 SetStrokeForegroundColorFromX11Context(ctx, gcVals);
129
130 static const std::size_t maxLength = sizeof gcVals.fDashes / sizeof gcVals.fDashes[0];
131 assert(maxLength >= std::size_t(gcVals.fDashLen) &&
132 "SetStrokeDashFromX11Context, x11 context has bad dash length > sizeof(fDashes)");
133
134 CGFloat dashes[maxLength] = {};
135 for (Int_t i = 0; i < gcVals.fDashLen; ++i)
136 dashes[i] = gcVals.fDashes[i];
137
138 CGContextSetLineDash(ctx, gcVals.fDashOffset, dashes, gcVals.fDashLen);
139}
140
141//______________________________________________________________________________
142void SetStrokeDoubleDashFromX11Context(CGContextRef /*ctx*/, const GCValues_t & /*gcVals*/)
143{
144 //assert(ctx != 0 && "SetStrokeDoubleDashFromX11Context, ctx parameter is null");
145 ::Warning("SetStrokeDoubleDashFromX11Context", "Not implemented yet, kick tpochep!");
146}
147
148//______________________________________________________________________________
149void SetStrokeParametersFromX11Context(CGContextRef ctx, const GCValues_t &gcVals)
150{
151 //Set line width and color from GCValues_t object.
152 //(GUI rendering).
153 assert(ctx != 0 && "SetStrokeParametersFromX11Context, parameter 'ctx' is null");
154
155 const Mask_t mask = gcVals.fMask;
156 if ((mask & kGCLineWidth) && gcVals.fLineWidth > 1)
157 CGContextSetLineWidth(ctx, gcVals.fLineWidth);
158 else
159 CGContextSetLineWidth(ctx, 1.);
160
161 CGContextSetLineDash(ctx, 0., 0, 0);
162
163 if (mask & kGCLineStyle) {
164 if (gcVals.fLineStyle == kLineSolid)
165 SetStrokeForegroundColorFromX11Context(ctx, gcVals);
166 else if (gcVals.fLineStyle == kLineOnOffDash)
167 SetStrokeDashFromX11Context(ctx, gcVals);
168 else if (gcVals.fLineStyle == kLineDoubleDash)
169 SetStrokeDoubleDashFromX11Context(ctx ,gcVals);
170 else {
171 ::Warning("SetStrokeParametersFromX11Context", "line style bit is set,"
172 " but line style is unknown");
173 SetStrokeForegroundColorFromX11Context(ctx, gcVals);
174 }
175 } else
176 SetStrokeForegroundColorFromX11Context(ctx, gcVals);
177}
178
179//______________________________________________________________________________
180void SetFilledAreaColorFromX11Context(CGContextRef ctx, const GCValues_t &gcVals)
181{
182 //Set fill color from "foreground" pixel color.
183 //(GUI rendering).
184 assert(ctx != 0 && "SetFilledAreaColorFromX11Context, parameter 'ctx' is null");
185
186 CGFloat rgb[3] = {};
187 if (gcVals.fMask & kGCForeground)
188 X11::PixelToRGB(gcVals.fForeground, rgb);
189 else
190 ::Warning("SetFilledAreaColorFromX11Context", "no fill color found in x11 context");
191
192 CGContextSetRGBFillColor(ctx, rgb[0], rgb[1], rgb[2], 1.);
193}
194
195struct PatternContext {
196 Mask_t fMask;
197 Int_t fFillStyle;
198 ULong_t fForeground;
199 ULong_t fBackground;
200 NSObject<X11Drawable> *fImage;//Either stipple or tile image.
201 CGSize fPhase;
202};
203
204
205//______________________________________________________________________________
206bool HasFillTiledStyle(Mask_t mask, Int_t fillStyle)
207{
208 return (mask & kGCFillStyle) && (fillStyle == kFillTiled);
209}
210
211//______________________________________________________________________________
212bool HasFillTiledStyle(const GCValues_t &gcVals)
213{
214 return HasFillTiledStyle(gcVals.fMask, gcVals.fFillStyle);
215}
216
217//______________________________________________________________________________
218bool HasFillStippledStyle(Mask_t mask, Int_t fillStyle)
219{
220 return (mask & kGCFillStyle) && (fillStyle == kFillStippled);
221}
222
223//______________________________________________________________________________
224bool HasFillStippledStyle(const GCValues_t &gcVals)
225{
226 return HasFillStippledStyle(gcVals.fMask, gcVals.fFillStyle);
227}
228
229//______________________________________________________________________________
230bool HasFillOpaqueStippledStyle(Mask_t mask, Int_t fillStyle)
231{
232 return (mask & kGCFillStyle) && (fillStyle == kFillOpaqueStippled);
233}
234
235//______________________________________________________________________________
236bool HasFillOpaqueStippledStyle(const GCValues_t &gcVals)
237{
238 return HasFillOpaqueStippledStyle(gcVals.fMask, gcVals.fFillStyle);
239}
240
241//______________________________________________________________________________
242void DrawTile(NSObject<X11Drawable> *patternImage, CGContextRef ctx)
243{
244 assert(patternImage != nil && "DrawTile, parameter 'patternImage' is nil");
245 assert(ctx != 0 && "DrawTile, ctx parameter is null");
246
247 const CGRect patternRect = CGRectMake(0, 0, patternImage.fWidth, patternImage.fHeight);
248 if ([patternImage isKindOfClass : [QuartzImage class]]) {
249 CGContextDrawImage(ctx, patternRect, ((QuartzImage *)patternImage).fImage);
250 } else if ([patternImage isKindOfClass : [QuartzPixmap class]]){
251 const Util::CFScopeGuard<CGImageRef> imageFromPixmap([((QuartzPixmap *)patternImage) createImageFromPixmap]);
252 assert(imageFromPixmap.Get() != 0 && "DrawTile, createImageFromPixmap failed");
253 CGContextDrawImage(ctx, patternRect, imageFromPixmap.Get());
254 } else
255 assert(0 && "DrawTile, pattern is neither a QuartzImage, nor a QuartzPixmap");
256}
257
258//______________________________________________________________________________
259void DrawPattern(void *info, CGContextRef ctx)
260{
261 //Pattern callback, either use foreground (and background, if any)
262 //color and stipple mask to draw a pattern, or use pixmap
263 //as a pattern image.
264 //(GUI rendering).
265 assert(info != 0 && "DrawPattern, parameter 'info' is null");
266 assert(ctx != 0 && "DrawPattern, parameter 'ctx' is null");
267
268 const PatternContext * const patternContext = (PatternContext *)info;
269 const Mask_t mask = patternContext->fMask;
270 const Int_t fillStyle = patternContext->fFillStyle;
271
272 NSObject<X11Drawable> * const patternImage = patternContext->fImage;
273 assert(patternImage != nil && "DrawPattern, pattern (stipple) image is nil");
274 const CGRect patternRect = CGRectMake(0, 0, patternImage.fWidth, patternImage.fHeight);
275
276 if (HasFillTiledStyle(mask, fillStyle)) {
277 DrawTile(patternImage, ctx);
278 } else if (HasFillStippledStyle(mask, fillStyle) || HasFillOpaqueStippledStyle(mask, fillStyle)) {
279 assert([patternImage isKindOfClass : [QuartzImage class]] &&
280 "DrawPattern, stipple must be a QuartzImage object");
281 QuartzImage * const image = (QuartzImage *)patternImage;
282 assert(image.fIsStippleMask == YES && "DrawPattern, image is not a stipple mask");
283
284 CGFloat rgb[3] = {};
285
286 if (HasFillOpaqueStippledStyle(mask,fillStyle)) {
287 //Fill background first.
288 assert((mask & kGCBackground) &&
289 "DrawPattern, fill style is FillOpaqueStippled, but background color is not set in a context");
290 X11::PixelToRGB(patternContext->fBackground, rgb);
291 CGContextSetRGBFillColor(ctx, rgb[0], rgb[1], rgb[2], 1.);
292 CGContextFillRect(ctx, patternRect);
293 }
294
295 //Fill rectangle with foreground colour, using stipple mask.
296 assert((mask & kGCForeground) && "DrawPattern, foreground color is not set");
297 X11::PixelToRGB(patternContext->fForeground, rgb);
298 CGContextSetRGBFillColor(ctx, rgb[0], rgb[1], rgb[2], 1.);
299 CGContextClipToMask(ctx, patternRect, image.fImage);
300 CGContextFillRect(ctx, patternRect);
301 } else {
302 //This can be a window background pixmap
303 DrawTile(patternImage, ctx);
304 }
305}
306
307//______________________________________________________________________________
308void SetFillPattern(CGContextRef ctx, const PatternContext *patternContext)
309{
310 //Create CGPatternRef to fill GUI elements with pattern.
311 //Pattern is a QuartzImage object, it can be either a mask,
312 //or pattern image itself.
313 //(GUI-rendering).
314 assert(ctx != 0 && "SetFillPattern, parameter 'ctx' is null");
315 assert(patternContext != 0 && "SetFillPattern, parameter 'patternContext' is null");
316 assert(patternContext->fImage != nil && "SetFillPattern, pattern image is nil");
317
318 const Util::CFScopeGuard<CGColorSpaceRef> patternColorSpace(CGColorSpaceCreatePattern(0));
319 CGContextSetFillColorSpace(ctx, patternColorSpace.Get());
320
321 CGPatternCallbacks callbacks = {};
322 callbacks.drawPattern = DrawPattern;
323 const CGRect patternRect = CGRectMake(0, 0, patternContext->fImage.fWidth, patternContext->fImage.fHeight);
324 const Util::CFScopeGuard<CGPatternRef> pattern(CGPatternCreate((void *)patternContext, patternRect, CGAffineTransformIdentity,
325 patternContext->fImage.fWidth, patternContext->fImage.fHeight,
326 kCGPatternTilingNoDistortion, true, &callbacks));
327 const CGFloat alpha = 1.;
328 CGContextSetFillPattern(ctx, pattern.Get(), &alpha);
329 CGContextSetPatternPhase(ctx, patternContext->fPhase);
330}
331
332//______________________________________________________________________________
333bool ParentRendersToChild(NSView<X11Window> *child)
334{
335 assert(child != nil && "ParentRendersToChild, parameter 'child' is nil");
336
337 //Adovo poluchaetsia, tashhem-ta! ;)
338 return (X11::ViewIsTextViewFrame(child, true) || X11::ViewIsHtmlViewFrame(child, true)) && !child.fContext &&
339 child.fMapState == kIsViewable && child.fParentView.fContext &&
340 !child.fIsOverlapped;
341}
342
343//______________________________________________________________________________
344bool IsNonPrintableAsciiCharacter(UniChar c)
345{
346 if (c == 9 || (c >= 32 && c < 127))
347 return false;
348
349 return true;
350}
351
352//______________________________________________________________________________
353void FixAscii(std::vector<UniChar> &text)
354{
355 //GUI text is essentially ASCII. Our GUI
356 //calculates text metrix 'per-symbol', this means,
357 //it never asks about 'Text' metrics, but 'T', 'e', 'x', 't'.
358 //Obviously, text does not fit any widget because of
359 //this and I have to place all glyphs manually.
360 //And here I have another problem from our GUI - it
361 //can easily feed TGCocoa with non-printable symbols
362 //(this is a bug). Obviously, I do not have glyphs for, say, form feed
363 //or 'data link escape'. So I have to fix ascii text before
364 //manual glyph rendering: DLE symbol - replaced by space (this
365 //is done in TGText, but due to a bug it fails to replace them all)
366 //Other non-printable symbols simply removed (and thus ignored).
367
368 //Replace remaining ^P symbols with whitespaces, I have not idea why
369 //TGTextView replaces only part of them and not all of them.
370 std::replace(text.begin(), text.end(), UniChar(16), UniChar(' '));
371
372 //Now, remove remaining non-printable characters (no glyphs exist for them).
373 text.erase(std::remove_if(text.begin(), text.end(), IsNonPrintableAsciiCharacter), text.end());
374}
375
376}
377
379
381
382//______________________________________________________________________________
384 : fSelectedDrawable(0),
385 fCocoaDraw(0),
386 fDrawMode(kCopy),
387 fDirectDraw(false),
388 fForegroundProcess(false),
389 fSetApp(true),
390 fDisplayShapeChanged(true)
391{
392 assert(dynamic_cast<TMacOSXSystem *>(gSystem) != nullptr &&
393 "TGCocoa, gSystem is eihter null or has a wrong type");
394 TMacOSXSystem * const system = (TMacOSXSystem *)gSystem;
395
396 if (!system->CocoaInitialized())
397 system->InitializeCocoa();
398
399 fPimpl.reset(new Details::CocoaPrivate);
400
402 fgDeleteWindowAtom = FindAtom("WM_DELETE_WINDOW", true);
403
404 CGDisplayRegisterReconfigurationCallback (DisplayReconfigurationCallback, 0);
405}
406
407//______________________________________________________________________________
408TGCocoa::TGCocoa(const char *name, const char *title)
409 : TVirtualX(name, title),
410 fSelectedDrawable(0),
411 fCocoaDraw(0),
412 fDrawMode(kCopy),
413 fDirectDraw(false),
414 fForegroundProcess(false),
415 fSetApp(true),
416 fDisplayShapeChanged(true)
417{
418 assert(dynamic_cast<TMacOSXSystem *>(gSystem) != nullptr &&
419 "TGCocoa, gSystem is eihter null or has a wrong type");
420 TMacOSXSystem * const system = (TMacOSXSystem *)gSystem;
421
422 if (!system->CocoaInitialized())
423 system->InitializeCocoa();
424
425 fPimpl.reset(new Details::CocoaPrivate);
426
428 fgDeleteWindowAtom = FindAtom("WM_DELETE_WINDOW", true);
429
430 CGDisplayRegisterReconfigurationCallback (DisplayReconfigurationCallback, 0);
431}
432
433//______________________________________________________________________________
435{
436 //
437 CGDisplayRemoveReconfigurationCallback (DisplayReconfigurationCallback, 0);
438}
439
440//General part (empty, since it's not an X server.
441
442//______________________________________________________________________________
443Bool_t TGCocoa::Init(void * /*display*/)
444{
445 //Nothing to initialize here, return true to make
446 //a caller happy.
447 return kTRUE;
448}
449
450
451//______________________________________________________________________________
452Int_t TGCocoa::OpenDisplay(const char * /*dpyName*/)
453{
454 //Noop.
455 return 0;
456}
457
458//______________________________________________________________________________
459const char *TGCocoa::DisplayName(const char *)
460{
461 //Noop.
462 return "dummy";
463}
464
465//______________________________________________________________________________
467{
468 //No, thank you, I'm not supporting any of X11 extensions!
469 return -1;
470}
471
472//______________________________________________________________________________
474{
475 //Noop.
476}
477
478//______________________________________________________________________________
480{
481 //Noop.
482 return 0;
483}
484
485//______________________________________________________________________________
487{
488 //Noop.
489 return 0;
490}
491
492//______________________________________________________________________________
494{
495 //Noop.
496 return 0;
497}
498
499//______________________________________________________________________________
501{
502 //Comment from TVirtualX:
503 // Returns the width of the screen in millimeters.
504 //End of comment.
505
506 return CGDisplayScreenSize(CGMainDisplayID()).width;
507}
508
509//______________________________________________________________________________
511{
512 //Comment from TVirtualX:
513 // Returns depth of screen (number of bit planes).
514 // Equivalent to GetPlanes().
515 //End of comment.
516
517 NSArray * const screens = [NSScreen screens];
518 assert(screens != nil && "screens array is nil");
519
520 NSScreen * const mainScreen = [screens objectAtIndex : 0];
521 assert(mainScreen != nil && "screen with index 0 is nil");
522
523 return NSBitsPerPixelFromDepth([mainScreen depth]);
524}
525
526//______________________________________________________________________________
528{
530
531 if (mode == 2) {
532 assert(gClient != 0 && "Update, gClient is null");
533 gClient->DoRedraw();//Call DoRedraw for all widgets, who need to be updated.
534 } else if (mode > 0) {
535 //Execute buffered commands.
536 fPimpl->fX11CommandBuffer.Flush(fPimpl.get());
537 }
538
539 if (fDirectDraw && mode != 2)
540 fPimpl->fX11CommandBuffer.FlushXOROps(fPimpl.get());
541}
542
543//______________________________________________________________________________
545{
547}
548
549//______________________________________________________________________________
551{
553 NSArray * const screens = [NSScreen screens];
554 assert(screens != nil && screens.count != 0 && "GetDisplayGeometry, no screens found");
555
556 NSRect frame = [(NSScreen *)[screens objectAtIndex : 0] frame];
557 CGFloat xMin = frame.origin.x, xMax = xMin + frame.size.width;
558 CGFloat yMin = frame.origin.y, yMax = yMin + frame.size.height;
559
560 for (NSUInteger i = 1, e = screens.count; i < e; ++i) {
561 frame = [(NSScreen *)[screens objectAtIndex : i] frame];
562 xMin = std::min(xMin, frame.origin.x);
563 xMax = std::max(xMax, frame.origin.x + frame.size.width);
564 yMin = std::min(yMin, frame.origin.y);
565 yMax = std::max(yMax, frame.origin.y + frame.size.height);
566 }
567
568 fDisplayRect.fX = int(xMin);
569 fDisplayRect.fY = int(yMin);
570 fDisplayRect.fWidth = unsigned(xMax - xMin);
571 fDisplayRect.fHeight = unsigned(yMax - yMin);
572
573 fDisplayShapeChanged = false;
574 }
575
576 return fDisplayRect;
577}
578
579#pragma mark - Window management part.
580
581//______________________________________________________________________________
583{
584 //Index, fixed and used only by 'root' window.
585 return fPimpl->GetRootWindowID();
586}
587
588//______________________________________________________________________________
590{
591 //InitWindow is a bad name, since this function
592 //creates a window, but this name comes from the TVirtualX interface.
593 //Actually, there is no special need in this function,
594 //it's a kind of simplified CreateWindow (with only
595 //one parameter). This function is called by TRootCanvas,
596 //to create a special window inside TGCanvas (thus parentID must be a valid window ID).
597 //TGX11/TGWin32 have internal array of such special windows,
598 //they return index into this array, instead of drawable's ids.
599 //I simply re-use CreateWindow and return a drawable's id.
600
601 assert(parentID != 0 && "InitWindow, parameter 'parentID' is 0");
602
603 //Use parent's attributes (as it's done in TGX11).
604 WindowAttributes_t attr = {};
605 if (fPimpl->IsRootWindow(parentID))
607 else
608 [fPimpl->GetWindow(parentID) getAttributes : &attr];
609
610 return CreateWindow(parentID, 0, 0, attr.fWidth, attr.fHeight, 0, attr.fDepth, attr.fClass, 0, 0, 0);
611}
612
613//______________________________________________________________________________
615{
616 //In case of TGX11/TGWin32, there is a mixture of
617 //casted X11 ids (Window_t) and indices in some internal array, which
618 //contains such an id. On Mac I always have indices. Yes, I'm smart.
619 return windowID;
620}
621
622//______________________________________________________________________________
624{
625 //This function can be called from pad/canvas, both for window and for pixmap.
626 fSelectedDrawable = windowID;
627}
628
629//______________________________________________________________________________
631{
632 //Clear the selected drawable OR pixmap (the name - from TVirtualX interface - is bad).
633 assert(fSelectedDrawable > fPimpl->GetRootWindowID() &&
634 "ClearWindow, fSelectedDrawable is invalid");
635
636 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(fSelectedDrawable);
637 if (drawable.fIsPixmap) {
638 //Pixmaps are white by default.
639 //This is bad - we can not have transparent sub-pads (in TCanvas)
640 //because of this. But there is no way how gVirtualX can
641 //obtain real pad's color and check for its transparency.
642 CGContextRef pixmapCtx = drawable.fContext;
643 assert(pixmapCtx != 0 && "ClearWindow, pixmap's context is null");
644 //const Quartz::CGStateGuard ctxGuard(pixmapCtx);
645 //CGContextSetRGBFillColor(pixmapCtx, 1., 1., 1., 1.);
646 //CGContextFillRect(pixmapCtx, CGRectMake(0, 0, drawable.fWidth, drawable.fHeight));
647 //Now we really clear!
648 CGContextClearRect(pixmapCtx, CGRectMake(0, 0, drawable.fWidth, drawable.fHeight));
649 } else {
650 //For a window ClearArea with w == 0 and h == 0 means the whole window.
651 ClearArea(fSelectedDrawable, 0, 0, 0, 0);
652 }
653}
654
655//______________________________________________________________________________
657{
658 //In TGX11, GetGeometry works with special windows, created by InitWindow
659 //(thus this function is called from TCanvas/TGCanvas/TRootCanvas).
660
661 //IMPORTANT: this function also translates x and y
662 //from parent's coordinates into screen coordinates - so, again, name "GetGeometry"
663 //from the TVirtualX interface is bad and misleading.
664
665 if (windowID < 0 || fPimpl->IsRootWindow(windowID)) {
666 //Comment in TVirtualX suggests, that wid can be < 0.
667 //This will be a screen's geometry.
668 WindowAttributes_t attr = {};
670 x = attr.fX;
671 y = attr.fY;
672 w = attr.fWidth;
673 h = attr.fHeight;
674 } else {
675 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(windowID);
676 x = drawable.fX;
677 y = drawable.fY;
678 w = drawable.fWidth;
679 h = drawable.fHeight;
680
681 if (!drawable.fIsPixmap) {
682 NSObject<X11Window> * const window = (NSObject<X11Window> *)drawable;
683 NSPoint srcPoint = {};
684 srcPoint.x = x;
685 srcPoint.y = y;
686 NSView<X11Window> * const view = window.fContentView.fParentView ? window.fContentView.fParentView : window.fContentView;
687 //View parameter for TranslateToScreen call must
688 //be parent view, since x and y are in parent's
689 //coordinate system.
690 const NSPoint dstPoint = X11::TranslateToScreen(view, srcPoint);
691 x = dstPoint.x;
692 y = dstPoint.y;
693 }
694 }
695}
696
697//______________________________________________________________________________
699{
700 //windowID is either kNone or a valid window id.
701 //x and y are coordinates of a top-left corner relative to the parent's coordinate system.
702
703 assert(!fPimpl->IsRootWindow(windowID) && "MoveWindow, called for root window");
704
705 if (!windowID)//From TGX11.
706 return;
707
708 [fPimpl->GetWindow(windowID) setX : x Y : y];
709}
710
711//______________________________________________________________________________
712void TGCocoa::RescaleWindow(Int_t /*wid*/, UInt_t /*w*/, UInt_t /*h*/)
713{
714 //This function is for TRootCanvas and related stuff, never gets
715 //called/used from/by any our GUI class.
716 //Noop.
717}
718
719//______________________________________________________________________________
721{
722 //This function does not resize window (it was done already by layout management?),
723 //it resizes "back buffer" if any.
724
725 if (!windowID)//From TGX11.
726 return;
727
728 assert(!fPimpl->IsRootWindow(windowID) &&
729 "ResizeWindow, parameter 'windowID' is a root window's id");
730
731 const Util::AutoreleasePool pool;
732
733 NSObject<X11Window> * const window = fPimpl->GetWindow(windowID);
734 if (window.fBackBuffer) {
735 const Drawable_t currentDrawable = fSelectedDrawable;
736 fSelectedDrawable = windowID;
738 fSelectedDrawable = currentDrawable;
739 }
740}
741
742//______________________________________________________________________________
744{
745 //This function is used by TCanvas/TPad:
746 //draw "back buffer" image into the view.
747 //fContentView (destination) MUST be a QuartzView.
748
749 //Basic es-guarantee: X11Buffer::AddUpdateWindow modifies vector with commands,
750 //if the following call to TGCocoa::Update will produce an exception dusing X11Buffer::Flush,
751 //initial state of X11Buffer can not be restored, but it still must be in some valid state.
752
753 assert(fSelectedDrawable > fPimpl->GetRootWindowID() &&
754 "UpdateWindow, fSelectedDrawable is not a valid window id");
755
756 //Have no idea, why this can happen with ROOT - done by TGDNDManager :(
757 if (fPimpl->GetDrawable(fSelectedDrawable).fIsPixmap == YES)
758 return;
759
760 NSObject<X11Window> * const window = fPimpl->GetWindow(fSelectedDrawable);
761
762 if (QuartzPixmap * const pixmap = window.fBackBuffer) {
763 assert([window.fContentView isKindOfClass : [QuartzView class]] && "UpdateWindow, content view is not a QuartzView");
764 QuartzView *dstView = (QuartzView *)window.fContentView;
765
766 if (dstView.fIsOverlapped)
767 return;
768
769 if (dstView.fContext) {
770 //We can draw directly.
771 const X11::Rectangle copyArea(0, 0, pixmap.fWidth, pixmap.fHeight);
772 [dstView copy : pixmap area : copyArea withMask : nil clipOrigin : X11::Point() toPoint : X11::Point()];
773 } else {
774 //Have to wait.
775 fPimpl->fX11CommandBuffer.AddUpdateWindow(dstView);
776 Update(1);
777 }
778 }
779}
780
781//______________________________________________________________________________
783{
784 //Window selected by SelectWindow.
785 return fSelectedDrawable;
786}
787
788//______________________________________________________________________________
790{
791 //Deletes selected window.
792}
793
794//______________________________________________________________________________
796{
797 //Should register a window created by Qt as a ROOT window,
798 //but since Qt-ROOT does not work on Mac and will never work,
799 //especially with version 4.8 - this implementation will always
800 //be empty.
801 return 0;
802}
803
804//______________________________________________________________________________
806{
807 //Remove window, created by Qt.
808}
809
810//______________________________________________________________________________
812 UInt_t clss, void *visual, SetWindowAttributes_t *attr, UInt_t wtype)
813{
814 //Create new window (top-level == QuartzWindow + QuartzView, or child == QuartzView)
815
816 //Strong es-guarantee - exception can be only during registration, class state will remain
817 //unchanged, no leaks (scope guards).
818
819 const Util::AutoreleasePool pool;
820
821 if (fPimpl->IsRootWindow(parentID)) {//parent == root window.
822 //Can throw:
823 QuartzWindow * const newWindow = X11::CreateTopLevelWindow(x, y, w, h, border,
824 depth, clss, visual, attr, wtype);
825 //Something like unique_ptr would perfectly solve the problem with raw pointer + a separate
826 //guard for this pointer, but it requires move semantics.
827 const Util::NSScopeGuard<QuartzWindow> winGuard(newWindow);
828 const Window_t result = fPimpl->RegisterDrawable(newWindow);//Can throw.
829 newWindow.fID = result;
830 [newWindow setAcceptsMouseMovedEvents : YES];
831
832 return result;
833 } else {
834 NSObject<X11Window> * const parentWin = fPimpl->GetWindow(parentID);
835 //OpenGL view can not have children.
836 assert([parentWin.fContentView isKindOfClass : [QuartzView class]] &&
837 "CreateWindow, parent view must be QuartzView");
838
839 //Can throw:
840 QuartzView * const childView = X11::CreateChildView((QuartzView *)parentWin.fContentView,
841 x, y, w, h, border, depth, clss, visual, attr, wtype);
842 const Util::NSScopeGuard<QuartzView> viewGuard(childView);
843 const Window_t result = fPimpl->RegisterDrawable(childView);//Can throw.
844 childView.fID = result;
845 [parentWin addChild : childView];
846
847 return result;
848 }
849}
850
851//______________________________________________________________________________
853{
854 //The XDestroyWindow function destroys the specified window as well as all of its subwindows
855 //and causes the X server to generate a DestroyNotify event for each window. The window
856 //should never be referenced again. If the window specified by the w argument is mapped,
857 //it is unmapped automatically. The ordering of the
858 //DestroyNotify events is such that for any given window being destroyed, DestroyNotify is generated
859 //on any inferiors of the window before being generated on the window itself. The ordering
860 //among siblings and across subhierarchies is not otherwise constrained.
861 //If the window you specified is a root window, no windows are destroyed. Destroying a mapped window
862 //will generate Expose events on other windows that were obscured by the window being destroyed.
863
864 //No-throw guarantee???
865
866 //I have NO idea why ROOT's GUI calls DestroyWindow with illegal
867 //window id, but it does.
868
869 if (!wid)
870 return;
871
872 if (fPimpl->IsRootWindow(wid))
873 return;
874
875 BOOL needFocusChange = NO;
876
877 {//Block to force autoreleasepool to drain.
878 const Util::AutoreleasePool pool;
879
880 fPimpl->fX11EventTranslator.CheckUnmappedView(wid);
881
882 assert(fPimpl->GetDrawable(wid).fIsPixmap == NO &&
883 "DestroyWindow, can not be called for QuartzPixmap or QuartzImage object");
884
885 NSObject<X11Window> * const window = fPimpl->GetWindow(wid);
886 if (fPimpl->fX11CommandBuffer.BufferSize())
887 fPimpl->fX11CommandBuffer.RemoveOperationsForDrawable(wid);
888
889 //TEST: "fix" a keyboard focus.
890 if ((needFocusChange = window == window.fQuartzWindow && window.fQuartzWindow.fHasFocus))
891 window.fHasFocus = NO;//If any.
892
894 if (window.fEventMask & kStructureNotifyMask)
895 fPimpl->fX11EventTranslator.GenerateDestroyNotify(wid);
896
897 //Interrupt modal loop (TGClient::WaitFor).
898 if (gClient->GetWaitForEvent() == kDestroyNotify && wid == gClient->GetWaitForWindow())
899 gClient->SetWaitForWindow(kNone);
900
901 fPimpl->DeleteDrawable(wid);
902 }
903
904 //"Fix" a keyboard focus.
905 if (needFocusChange)
907}
908
909//______________________________________________________________________________
911{
912 // The DestroySubwindows function destroys all inferior windows of the
913 // specified window, in bottom-to-top stacking order.
914
915 //No-throw guarantee??
916
917 //From TGX11:
918 if (!wid)
919 return;
920
921 if (fPimpl->IsRootWindow(wid))
922 return;
923
924 const Util::AutoreleasePool pool;
925
926 assert(fPimpl->GetDrawable(wid).fIsPixmap == NO &&
927 "DestroySubwindows, can not be called for QuartzPixmap or QuartzImage object");
928
929 NSObject<X11Window> *window = fPimpl->GetWindow(wid);
930
931 //I can not iterate on subviews array directly, since it'll be modified
932 //during this iteration - create a copy (and it'll also increase references,
933 //which will be decreased by guard's dtor).
934 const Util::NSScopeGuard<NSArray> children([[window.fContentView subviews] copy]);
935
936 for (NSView<X11Window> *child in children.Get())
937 DestroyWindow(child.fID);
938}
939
940//______________________________________________________________________________
942{
943 //No-throw guarantee.
944
945 if (!wid)//X11's None?
946 return;
947
948 if (fPimpl->IsRootWindow(wid))
950 else
951 [fPimpl->GetWindow(wid) getAttributes : &attr];
952}
953
954//______________________________________________________________________________
956{
957 //No-throw guarantee.
958
959 if (!wid)//From TGX11
960 return;
961
962 const Util::AutoreleasePool pool;
963
964 assert(!fPimpl->IsRootWindow(wid) && "ChangeWindowAttributes, called for root window");
965 assert(attr != 0 && "ChangeWindowAttributes, parameter 'attr' is null");
966
967 [fPimpl->GetWindow(wid) setAttributes : attr];
968}
969
970//______________________________________________________________________________
971void TGCocoa::SelectInput(Window_t windowID, UInt_t eventMask)
972{
973 //No-throw guarantee.
974
975 // Defines which input events the window is interested in. By default
976 // events are propageted up the window stack. This mask can also be
977 // set at window creation time via the SetWindowAttributes_t::fEventMask
978 // attribute.
979
980 //TGuiBldDragManager selects input on a 'root' window.
981 //TGWin32 has a check on windowID == 0.
982 if (windowID <= fPimpl->GetRootWindowID())
983 return;
984
985 NSObject<X11Window> * const window = fPimpl->GetWindow(windowID);
986 //XSelectInput overrides a previous mask.
987 window.fEventMask = eventMask;
988}
989
990//______________________________________________________________________________
992{
993 //Reparent view.
994 using namespace Details;
995
996 assert(!fPimpl->IsRootWindow(wid) && "ReparentChild, can not re-parent root window");
997
998 const Util::AutoreleasePool pool;
999
1000 NSView<X11Window> * const view = fPimpl->GetWindow(wid).fContentView;
1001 if (fPimpl->IsRootWindow(pid)) {
1002 //Make a top-level view from a child view.
1003 [view retain];
1004 [view removeFromSuperview];
1005 view.fParentView = nil;
1006
1007 NSRect frame = view.frame;
1008 frame.origin = NSPoint();
1009
1011 if (!view.fOverrideRedirect)
1012 styleMask |= kTitledWindowMask;
1013
1014 QuartzWindow * const newTopLevel = [[QuartzWindow alloc] initWithContentRect : frame
1015 styleMask : styleMask
1016 backing : NSBackingStoreBuffered
1017 defer : NO];
1018 [view setX : x Y : y];
1019 [newTopLevel addChild : view];
1020
1021 fPimpl->ReplaceDrawable(wid, newTopLevel);
1022
1023 [view release];
1024 [newTopLevel release];
1025 } else {
1026 [view retain];
1027 [view removeFromSuperview];
1028 //
1029 NSObject<X11Window> * const newParent = fPimpl->GetWindow(pid);
1030 assert(newParent.fIsPixmap == NO && "ReparentChild, pixmap can not be a new parent");
1031 [view setX : x Y : y];
1032 [newParent addChild : view];//It'll also update view's level, no need to call updateLevel.
1033 [view release];
1034 }
1035}
1036
1037//______________________________________________________________________________
1039{
1040 //Reparent top-level window.
1041 //I have to delete QuartzWindow here and place in its slot content view +
1042 //reparent this view into pid.
1043 if (fPimpl->IsRootWindow(pid))//Nothing to do, wid is already a top-level window.
1044 return;
1045
1046 const Util::AutoreleasePool pool;
1047
1048 NSView<X11Window> * const contentView = fPimpl->GetWindow(wid).fContentView;
1049 QuartzWindow * const topLevel = (QuartzWindow *)[contentView window];
1050 [contentView retain];
1051 [contentView removeFromSuperview];
1052 [topLevel setContentView : nil];
1053 fPimpl->ReplaceDrawable(wid, contentView);
1054 [contentView setX : x Y : y];
1055 [fPimpl->GetWindow(pid) addChild : contentView];//Will also replace view's level.
1056 [contentView release];
1057}
1058
1059//______________________________________________________________________________
1061{
1062 //Change window's parent (possibly creating new top-level window or destroying top-level window).
1063
1064 if (!wid) //From TGX11.
1065 return;
1066
1067 assert(!fPimpl->IsRootWindow(wid) && "ReparentWindow, can not re-parent root window");
1068
1069 NSView<X11Window> * const view = fPimpl->GetWindow(wid).fContentView;
1070 if (view.fParentView)
1071 ReparentChild(wid, pid, x, y);
1072 else
1073 //wid is a top-level window (or content view of such a window).
1074 ReparentTopLevel(wid, pid, x, y);
1075}
1076
1077//______________________________________________________________________________
1079{
1080 // Maps the window "wid" and all of its subwindows that have had map
1081 // requests. This function has no effect if the window is already mapped.
1082
1083 assert(!fPimpl->IsRootWindow(wid) && "MapWindow, called for root window");
1084
1085 const Util::AutoreleasePool pool;
1086
1088 [fPimpl->GetWindow(wid) mapWindow];
1089
1090 if (fSetApp) {
1093 fSetApp = false;
1094 }
1095}
1096
1097//______________________________________________________________________________
1099{
1100 // Maps all subwindows for the specified window "wid" in top-to-bottom
1101 // stacking order.
1102
1103 assert(!fPimpl->IsRootWindow(wid) && "MapSubwindows, called for 'root' window");
1104
1105 const Util::AutoreleasePool pool;
1106
1108 [fPimpl->GetWindow(wid) mapSubwindows];
1109}
1110
1111//______________________________________________________________________________
1113{
1114 // Maps the window "wid" and all of its subwindows that have had map
1115 // requests on the screen and put this window on the top of of the
1116 // stack of all windows.
1117
1118 assert(!fPimpl->IsRootWindow(wid) && "MapRaised, called for root window");
1119
1120 const Util::AutoreleasePool pool;
1121
1123 [fPimpl->GetWindow(wid) mapRaised];
1124
1125 if (fSetApp) {
1128 fSetApp = false;
1129 }
1130}
1131
1132//______________________________________________________________________________
1134{
1135 // Unmaps the specified window "wid". If the specified window is already
1136 // unmapped, this function has no effect. Any child window will no longer
1137 // be visible (but they are still mapped) until another map call is made
1138 // on the parent.
1139 assert(!fPimpl->IsRootWindow(wid) && "UnmapWindow, called for root window");
1140
1141 const Util::AutoreleasePool pool;
1142
1143 //If this window is a grab window or a parent of a grab window.
1144 fPimpl->fX11EventTranslator.CheckUnmappedView(wid);
1145
1146 NSObject<X11Window> * const win = fPimpl->GetWindow(wid);
1147 [win unmapWindow];
1148
1149 if (win == win.fQuartzWindow && win.fQuartzWindow.fHasFocus)
1150 X11::WindowLostFocus(win.fID);
1151
1152 win.fHasFocus = NO;
1153
1154 //if (window.fEventMask & kStructureNotifyMask)
1155 // fPimpl->fX11EventTranslator.GenerateUnmapNotify(wid);
1156
1157 //Interrupt modal loop (TGClient::WaitForUnmap).
1158 if (gClient->GetWaitForEvent() == kUnmapNotify && gClient->GetWaitForWindow() == wid)
1159 gClient->SetWaitForWindow(kNone);
1160}
1161
1162//______________________________________________________________________________
1164{
1165 // Raises the specified window to the top of the stack so that no
1166 // sibling window obscures it.
1167
1168 if (!wid)//From TGX11.
1169 return;
1170
1171 assert(!fPimpl->IsRootWindow(wid) && "RaiseWindow, called for root window");
1172
1173 if (!fPimpl->GetWindow(wid).fParentView)
1174 return;
1175
1176 [fPimpl->GetWindow(wid) raiseWindow];
1177}
1178
1179//______________________________________________________________________________
1181{
1182 // Lowers the specified window "wid" to the bottom of the stack so
1183 // that it does not obscure any sibling windows.
1184
1185 if (!wid)//From TGX11.
1186 return;
1187
1188 assert(!fPimpl->IsRootWindow(wid) && "LowerWindow, called for root window");
1189
1190 if (!fPimpl->GetWindow(wid).fParentView)
1191 return;
1192
1193 [fPimpl->GetWindow(wid) lowerWindow];
1194}
1195
1196//______________________________________________________________________________
1198{
1199 // Moves the specified window to the specified x and y coordinates.
1200 // It does not change the window's size, raise the window, or change
1201 // the mapping state of the window.
1202 //
1203 // x, y - coordinates, which define the new position of the window
1204 // relative to its parent.
1205
1206 if (!wid)//From TGX11.
1207 return;
1208
1209 assert(!fPimpl->IsRootWindow(wid) && "MoveWindow, called for root window");
1210 const Util::AutoreleasePool pool;
1211 [fPimpl->GetWindow(wid) setX : x Y : y];
1212}
1213
1214//______________________________________________________________________________
1216{
1217 // Changes the size and location of the specified window "wid" without
1218 // raising it.
1219 //
1220 // x, y - coordinates, which define the new position of the window
1221 // relative to its parent.
1222 // w, h - the width and height, which define the interior size of
1223 // the window
1224
1225 if (!wid)//From TGX11.
1226 return;
1227
1228 assert(!fPimpl->IsRootWindow(wid) && "MoveResizeWindow, called for 'root' window");
1229
1230 const Util::AutoreleasePool pool;
1231 [fPimpl->GetWindow(wid) setX : x Y : y width : w height : h];
1232}
1233
1234//______________________________________________________________________________
1236{
1237 if (!wid)//From TGX11.
1238 return;
1239
1240 assert(!fPimpl->IsRootWindow(wid) && "ResizeWindow, called for 'root' window");
1241
1242 const Util::AutoreleasePool pool;
1243
1244 //We can have this unfortunately.
1245 const UInt_t siMax = std::numeric_limits<Int_t>::max();
1246 if (w > siMax || h > siMax)
1247 return;
1248
1249 NSSize newSize = {};
1250 newSize.width = w;
1251 newSize.height = h;
1252
1253 [fPimpl->GetWindow(wid) setDrawableSize : newSize];
1254}
1255
1256//______________________________________________________________________________
1258{
1259 // Iconifies the window "wid".
1260 if (!wid)
1261 return;
1262
1263 assert(!fPimpl->IsRootWindow(wid) && "IconifyWindow, can not iconify the root window");
1264 assert(fPimpl->GetWindow(wid).fIsPixmap == NO && "IconifyWindow, invalid window id");
1265
1266 NSObject<X11Window> * const win = fPimpl->GetWindow(wid);
1267 assert(win.fQuartzWindow == win && "IconifyWindow, can be called only for a top level window");
1268
1269 fPimpl->fX11EventTranslator.CheckUnmappedView(wid);
1270
1271 NSObject<X11Window> * const window = fPimpl->GetWindow(wid);
1272 if (fPimpl->fX11CommandBuffer.BufferSize())
1273 fPimpl->fX11CommandBuffer.RemoveOperationsForDrawable(wid);
1274
1275 if (window.fQuartzWindow.fHasFocus) {
1276 X11::WindowLostFocus(win.fID);
1277 window.fQuartzWindow.fHasFocus = NO;
1278 }
1279
1280 [win.fQuartzWindow miniaturize : win.fQuartzWindow];
1281}
1282
1283//______________________________________________________________________________
1284void TGCocoa::TranslateCoordinates(Window_t srcWin, Window_t dstWin, Int_t srcX, Int_t srcY, Int_t &dstX, Int_t &dstY, Window_t &child)
1285{
1286 // Translates coordinates in one window to the coordinate space of another
1287 // window. It takes the "src_x" and "src_y" coordinates relative to the
1288 // source window's origin and returns these coordinates to "dest_x" and
1289 // "dest_y" relative to the destination window's origin.
1290
1291 // child - returns the child of "dest" if the coordinates
1292 // are contained in a mapped child of the destination
1293 // window; otherwise, child is set to 0
1294 child = 0;
1295 if (!srcWin || !dstWin)//This is from TGX11, looks like this can happen.
1296 return;
1297
1298 const bool srcIsRoot = fPimpl->IsRootWindow(srcWin);
1299 const bool dstIsRoot = fPimpl->IsRootWindow(dstWin);
1300
1301 if (srcIsRoot && dstIsRoot) {
1302 //This can happen with ROOT's GUI. Set dstX/Y equal to srcX/Y.
1303 //From man for XTranslateCoordinates it's not clear, what should be in child.
1304 dstX = srcX;
1305 dstY = srcY;
1306
1307 if (QuartzWindow * const qw = X11::FindWindowInPoint(srcX, srcY))
1308 child = qw.fID;
1309
1310 return;
1311 }
1312
1313 NSPoint srcPoint = {};
1314 srcPoint.x = srcX;
1315 srcPoint.y = srcY;
1316
1317 NSPoint dstPoint = {};
1318
1319
1320 if (dstIsRoot) {
1321 NSView<X11Window> * const srcView = fPimpl->GetWindow(srcWin).fContentView;
1322 dstPoint = X11::TranslateToScreen(srcView, srcPoint);
1323 } else if (srcIsRoot) {
1324 NSView<X11Window> * const dstView = fPimpl->GetWindow(dstWin).fContentView;
1325 dstPoint = X11::TranslateFromScreen(srcPoint, dstView);
1326
1327 if ([dstView superview]) {
1328 //hitTest requires a point in a superview's coordinate system.
1329 //Even contentView of QuartzWindow has a superview (NSThemeFrame),
1330 //so this should always work.
1331 dstPoint = [[dstView superview] convertPoint : dstPoint fromView : dstView];
1332 if (NSView<X11Window> * const view = (NSView<X11Window> *)[dstView hitTest : dstPoint]) {
1333 if (view != dstView && view.fMapState == kIsViewable)
1334 child = view.fID;
1335 }
1336 }
1337 } else {
1338 NSView<X11Window> * const srcView = fPimpl->GetWindow(srcWin).fContentView;
1339 NSView<X11Window> * const dstView = fPimpl->GetWindow(dstWin).fContentView;
1340
1341 dstPoint = X11::TranslateCoordinates(srcView, dstView, srcPoint);
1342 if ([dstView superview]) {
1343 //hitTest requires a point in a view's superview coordinate system.
1344 //Even contentView of QuartzWindow has a superview (NSThemeFrame),
1345 //so this should always work.
1346 const NSPoint pt = [[dstView superview] convertPoint : dstPoint fromView : dstView];
1347 if (NSView<X11Window> * const view = (NSView<X11Window> *)[dstView hitTest : pt]) {
1348 if (view != dstView && view.fMapState == kIsViewable)
1349 child = view.fID;
1350 }
1351 }
1352 }
1353
1354 dstX = dstPoint.x;
1355 dstY = dstPoint.y;
1356}
1357
1358//______________________________________________________________________________
1360{
1361 // Returns the location and the size of window "wid"
1362 //
1363 // x, y - coordinates of the upper-left outer corner relative to the
1364 // parent window's origin
1365 // w, h - the size of the window, not including the border.
1366
1367 //From GX11Gui.cxx:
1368 if (!wid)
1369 return;
1370
1371 if (fPimpl->IsRootWindow(wid)) {
1372 WindowAttributes_t attr = {};
1374 x = attr.fX;
1375 y = attr.fY;
1376 w = attr.fWidth;
1377 h = attr.fHeight;
1378 } else {
1379 NSObject<X11Drawable> *window = fPimpl->GetDrawable(wid);
1380 //ROOT can ask window size for ... non-window drawable.
1381 if (!window.fIsPixmap) {
1382 x = window.fX;
1383 y = window.fY;
1384 } else {
1385 x = 0;
1386 y = 0;
1387 }
1388
1389 w = window.fWidth;
1390 h = window.fHeight;
1391 }
1392}
1393
1394//______________________________________________________________________________
1396{
1397 //From TGX11:
1398 if (!wid)
1399 return;
1400
1401 assert(!fPimpl->IsRootWindow(wid) && "SetWindowBackground, can not set color for root window");
1402
1403 fPimpl->GetWindow(wid).fBackgroundPixel = color;
1404}
1405
1406//______________________________________________________________________________
1408{
1409 // Sets the background pixmap of the window "wid" to the specified
1410 // pixmap "pxm".
1411
1412 //From TGX11/TGWin32:
1413 if (!windowID)
1414 return;
1415
1416 assert(!fPimpl->IsRootWindow(windowID) &&
1417 "SetWindowBackgroundPixmap, can not set background for a root window");
1418 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
1419 "SetWindowBackgroundPixmap, invalid window id");
1420
1421 NSObject<X11Window> * const window = fPimpl->GetWindow(windowID);
1422 if (pixmapID == kNone) {
1423 window.fBackgroundPixmap = nil;
1424 return;
1425 }
1426
1427 assert(pixmapID > fPimpl->GetRootWindowID() &&
1428 "SetWindowBackgroundPixmap, parameter 'pixmapID' is not a valid pixmap id");
1429 assert(fPimpl->GetDrawable(pixmapID).fIsPixmap == YES &&
1430 "SetWindowBackgroundPixmap, bad drawable");
1431
1432 NSObject<X11Drawable> * const pixmapOrImage = fPimpl->GetDrawable(pixmapID);
1433 //X11 doc says, that pixmap can be freed immediately after call
1434 //XSetWindowBackgroundPixmap, so I have to copy a pixmap.
1435 Util::NSScopeGuard<QuartzImage> backgroundImage;
1436
1437 if ([pixmapOrImage isKindOfClass : [QuartzPixmap class]]) {
1438 backgroundImage.Reset([[QuartzImage alloc] initFromPixmap : (QuartzPixmap *)pixmapOrImage]);
1439 if (backgroundImage.Get())
1440 window.fBackgroundPixmap = backgroundImage.Get();//the window is retaining the image.
1441 } else {
1442 backgroundImage.Reset([[QuartzImage alloc] initFromImage : (QuartzImage *)pixmapOrImage]);
1443 if (backgroundImage.Get())
1444 window.fBackgroundPixmap = backgroundImage.Get();//the window is retaining the image.
1445 }
1446
1447 if (!backgroundImage.Get())
1448 //Detailed error message was issued by QuartzImage at this point.
1449 Error("SetWindowBackgroundPixmap", "QuartzImage initialization failed");
1450}
1451
1452//______________________________________________________________________________
1454{
1455 // Returns the parent of the window "windowID".
1456
1457 //0 or root (checked in TGX11):
1458 if (windowID <= fPimpl->GetRootWindowID())
1459 return windowID;
1460
1461 NSView<X11Window> *view = fPimpl->GetWindow(windowID).fContentView;
1462 return view.fParentView ? view.fParentView.fID : fPimpl->GetRootWindowID();
1463}
1464
1465//______________________________________________________________________________
1467{
1468 if (!wid || !name)//From TGX11.
1469 return;
1470
1471 const Util::AutoreleasePool pool;
1472
1473 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1474
1475 if ([(NSObject *)drawable isKindOfClass : [NSWindow class]]) {
1476 NSString * const windowTitle = [NSString stringWithCString : name encoding : NSASCIIStringEncoding];
1477 [(NSWindow *)drawable setTitle : windowTitle];
1478 }
1479}
1480
1481//______________________________________________________________________________
1482void TGCocoa::SetIconName(Window_t /*wid*/, char * /*name*/)
1483{
1484 //Noop.
1485}
1486
1487//______________________________________________________________________________
1489{
1490 //Noop.
1491}
1492
1493//______________________________________________________________________________
1494void TGCocoa::SetClassHints(Window_t /*wid*/, char * /*className*/, char * /*resourceName*/)
1495{
1496 //Noop.
1497}
1498
1499//______________________________________________________________________________
1500void TGCocoa::ShapeCombineMask(Window_t windowID, Int_t /*x*/, Int_t /*y*/, Pixmap_t pixmapID)
1501{
1502 //Comment from TVirtualX:
1503 // The Nonrectangular Window Shape Extension adds nonrectangular
1504 // windows to the System.
1505 // This allows for making shaped (partially transparent) windows
1506
1507 assert(!fPimpl->IsRootWindow(windowID) &&
1508 "ShapeCombineMask, windowID parameter is a 'root' window");
1509 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
1510 "ShapeCombineMask, windowID parameter is a bad window id");
1511 assert([fPimpl->GetDrawable(pixmapID) isKindOfClass : [QuartzImage class]] &&
1512 "ShapeCombineMask, pixmapID parameter must point to QuartzImage object");
1513
1514 if (fPimpl->GetWindow(windowID).fContentView.fParentView)
1515 return;
1516
1517 QuartzImage * const srcImage = (QuartzImage *)fPimpl->GetDrawable(pixmapID);
1518 assert(srcImage.fIsStippleMask == YES && "ShapeCombineMask, source image is not a stipple mask");
1519
1520 // There is some kind of problems with shape masks and
1521 // flipped views, I have to do an image flip here.
1522 const Util::NSScopeGuard<QuartzImage> image([[QuartzImage alloc] initFromImageFlipped : srcImage]);
1523 if (image.Get()) {
1524 QuartzWindow * const qw = fPimpl->GetWindow(windowID).fQuartzWindow;
1525 qw.fShapeCombineMask = image.Get();
1526 [qw setOpaque : NO];
1527 [qw setBackgroundColor : [NSColor clearColor]];
1528 }
1529}
1530
1531#pragma mark - "Window manager hints" set of functions.
1532
1533//______________________________________________________________________________
1534void TGCocoa::SetMWMHints(Window_t wid, UInt_t value, UInt_t funcs, UInt_t /*input*/)
1535{
1536 // Sets decoration style.
1537 using namespace Details;
1538
1539 assert(!fPimpl->IsRootWindow(wid) && "SetMWMHints, called for 'root' window");
1540
1541 QuartzWindow * const qw = fPimpl->GetWindow(wid).fQuartzWindow;
1542 NSUInteger newMask = 0;
1543
1544 if ([qw styleMask] & kTitledWindowMask) {//Do not modify this.
1545 newMask |= kTitledWindowMask;
1546 newMask |= kClosableWindowMask;
1547 }
1548
1549 if (value & kMWMFuncAll) {
1551 } else {
1552 if (value & kMWMDecorMinimize)
1553 newMask |= kMiniaturizableWindowMask;
1554 if (funcs & kMWMFuncResize)
1555 newMask |= kResizableWindowMask;
1556 }
1557
1558 [qw setStyleMask : newMask];
1559
1560 if (funcs & kMWMDecorAll) {
1561 if (!qw.fMainWindow) {//Do not touch buttons for transient window.
1562 [[qw standardWindowButton : NSWindowZoomButton] setEnabled : YES];
1563 [[qw standardWindowButton : NSWindowMiniaturizeButton] setEnabled : YES];
1564 }
1565 } else {
1566 if (!qw.fMainWindow) {//Do not touch transient window's titlebar.
1567 [[qw standardWindowButton : NSWindowZoomButton] setEnabled : funcs & kMWMDecorMaximize];
1568 [[qw standardWindowButton : NSWindowMiniaturizeButton] setEnabled : funcs & kMWMDecorMinimize];
1569 }
1570 }
1571}
1572
1573//______________________________________________________________________________
1574void TGCocoa::SetWMPosition(Window_t /*wid*/, Int_t /*x*/, Int_t /*y*/)
1575{
1576 //Noop.
1577}
1578
1579//______________________________________________________________________________
1580void TGCocoa::SetWMSize(Window_t /*wid*/, UInt_t /*w*/, UInt_t /*h*/)
1581{
1582 //Noop.
1583}
1584
1585//______________________________________________________________________________
1586void TGCocoa::SetWMSizeHints(Window_t wid, UInt_t wMin, UInt_t hMin, UInt_t wMax, UInt_t hMax, UInt_t /*wInc*/, UInt_t /*hInc*/)
1587{
1588 using namespace Details;
1589
1590 assert(!fPimpl->IsRootWindow(wid) && "SetWMSizeHints, called for root window");
1591
1593 const NSRect minRect = [NSWindow frameRectForContentRect : NSMakeRect(0., 0., wMin, hMin) styleMask : styleMask];
1594 const NSRect maxRect = [NSWindow frameRectForContentRect : NSMakeRect(0., 0., wMax, hMax) styleMask : styleMask];
1595
1596 QuartzWindow * const qw = fPimpl->GetWindow(wid).fQuartzWindow;
1597 [qw setMinSize : minRect.size];
1598 [qw setMaxSize : maxRect.size];
1599}
1600
1601//______________________________________________________________________________
1603{
1604 //Noop.
1605}
1606
1607//______________________________________________________________________________
1609{
1610 //Comment from TVirtualX:
1611 // Tells window manager that the window "wid" is a transient window
1612 // of the window "main_id". A window manager may decide not to decorate
1613 // a transient window or may treat it differently in other ways.
1614 //End of TVirtualX's comment.
1615
1616 //TGTransientFrame uses this hint to attach a window to some "main" window,
1617 //so that transient window is alway above the main window. This is used for
1618 //dialogs and dockable panels.
1619 assert(wid > fPimpl->GetRootWindowID() && "SetWMTransientHint, wid parameter is not a valid window id");
1620
1621 if (fPimpl->IsRootWindow(mainWid))
1622 return;
1623
1624 QuartzWindow * const mainWindow = fPimpl->GetWindow(mainWid).fQuartzWindow;
1625
1626 if (![mainWindow isVisible])
1627 return;
1628
1629 QuartzWindow * const transientWindow = fPimpl->GetWindow(wid).fQuartzWindow;
1630
1631 if (mainWindow != transientWindow) {
1632 if (transientWindow.fMainWindow) {
1633 if (transientWindow.fMainWindow != mainWindow)
1634 Error("SetWMTransientHint", "window is already transient for other window");
1635 } else {
1636 [[transientWindow standardWindowButton : NSWindowZoomButton] setEnabled : NO];
1637 [mainWindow addTransientWindow : transientWindow];
1638 }
1639 } else
1640 Warning("SetWMTransientHint", "transient and main windows are the same window");
1641}
1642
1643#pragma mark - GUI-rendering part.
1644
1645//______________________________________________________________________________
1647{
1648 //Can be called directly of when flushing command buffer.
1649 assert(!fPimpl->IsRootWindow(wid) && "DrawLineAux, called for root window");
1650
1651 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1652 CGContextRef ctx = drawable.fContext;
1653 assert(ctx != 0 && "DrawLineAux, context is null");
1654
1655 const Quartz::CGStateGuard ctxGuard(ctx);//Will restore state back.
1656 //Draw a line.
1657 //This draw line is a special GUI method, it's used not by ROOT's graphics, but
1658 //widgets. The problem is:
1659 //-I have to switch off anti-aliasing, since if anti-aliasing is on,
1660 //the line is thick and has different color.
1661 //-As soon as I switch-off anti-aliasing, and line is precise, I can not
1662 //draw a line [0, 0, -> w, 0].
1663 //I use a small translation, after all, this is ONLY gui method and it
1664 //will not affect anything except GUI.
1665
1666 CGContextSetAllowsAntialiasing(ctx, false);//Smoothed line is of wrong color and in a wrong position - this is bad for GUI.
1667
1668 if (!drawable.fIsPixmap)
1669 CGContextTranslateCTM(ctx, 0.5, 0.5);
1670 else {
1671 //Pixmap uses native Cocoa's left-low-corner system.
1672 y1 = Int_t(X11::LocalYROOTToCocoa(drawable, y1));
1673 y2 = Int_t(X11::LocalYROOTToCocoa(drawable, y2));
1674 }
1675
1676 SetStrokeParametersFromX11Context(ctx, gcVals);
1677 CGContextBeginPath(ctx);
1678 CGContextMoveToPoint(ctx, x1, y1);
1679 CGContextAddLineToPoint(ctx, x2, y2);
1680 CGContextStrokePath(ctx);
1681
1682 CGContextSetAllowsAntialiasing(ctx, true);//Somehow, it's not saved/restored, this affects ... window's titlebar.
1683}
1684
1685//______________________________________________________________________________
1687{
1688 //This function can be called:
1689 //a)'normal' way - from view's drawRect method.
1690 //b) for 'direct rendering' - operation was initiated by ROOT's GUI, not by
1691 // drawRect.
1692
1693 //From TGX11:
1694 if (!wid)
1695 return;
1696
1697 assert(!fPimpl->IsRootWindow(wid) && "DrawLine, called for root window");
1698 assert(gc > 0 && gc <= fX11Contexts.size() && "DrawLine, invalid context index");
1699
1700 const GCValues_t &gcVals = fX11Contexts[gc - 1];
1701
1702 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1703 if (!drawable.fIsPixmap) {
1704 NSObject<X11Window> * const window = (NSObject<X11Window> *)drawable;
1705 QuartzView * const view = (QuartzView *)window.fContentView;
1706
1707 if (ParentRendersToChild(view)) {
1708 if (X11::LockFocus(view)) {
1709 DrawLineAux(view.fID, gcVals, x1, y1, x2, y2);
1710 X11::UnlockFocus(view);
1711 return;
1712 }
1713 }
1714
1715 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
1716 if (!view.fContext)
1717 fPimpl->fX11CommandBuffer.AddDrawLine(wid, gcVals, x1, y1, x2, y2);
1718 else
1719 DrawLineAux(wid, gcVals, x1, y1, x2, y2);
1720 }
1721 } else {
1722 if (!IsCocoaDraw()) {
1723 fPimpl->fX11CommandBuffer.AddDrawLine(wid, gcVals, x1, y1, x2, y2);
1724 } else {
1725 DrawLineAux(wid, gcVals, x1, y1, x2, y2);
1726 }
1727 }
1728}
1729
1730//______________________________________________________________________________
1731void TGCocoa::DrawSegmentsAux(Drawable_t wid, const GCValues_t &gcVals, const Segment_t *segments, Int_t nSegments)
1732{
1733 assert(!fPimpl->IsRootWindow(wid) && "DrawSegmentsAux, called for root window");
1734 assert(segments != 0 && "DrawSegmentsAux, segments parameter is null");
1735 assert(nSegments > 0 && "DrawSegmentsAux, nSegments <= 0");
1736
1737 for (Int_t i = 0; i < nSegments; ++i)
1738 DrawLineAux(wid, gcVals, segments[i].fX1, segments[i].fY1 - 3, segments[i].fX2, segments[i].fY2 - 3);
1739}
1740
1741//______________________________________________________________________________
1742void TGCocoa::DrawSegments(Drawable_t wid, GContext_t gc, Segment_t *segments, Int_t nSegments)
1743{
1744 //Draw multiple line segments. Each line is specified by a pair of points.
1745
1746 //From TGX11:
1747 if (!wid)
1748 return;
1749
1750 assert(!fPimpl->IsRootWindow(wid) && "DrawSegments, called for root window");
1751 assert(gc > 0 && gc <= fX11Contexts.size() && "DrawSegments, invalid context index");
1752 assert(segments != 0 && "DrawSegments, parameter 'segments' is null");
1753 assert(nSegments > 0 && "DrawSegments, number of segments <= 0");
1754
1755 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1756 const GCValues_t &gcVals = fX11Contexts[gc - 1];
1757
1758 if (!drawable.fIsPixmap) {
1759 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(wid).fContentView;
1760
1761 if (ParentRendersToChild(view)) {
1762 if (X11::LockFocus(view)) {
1763 DrawSegmentsAux(view.fID, gcVals, segments, nSegments);
1764 X11::UnlockFocus(view);
1765 return;
1766 }
1767 }
1768
1769 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
1770 if (!view.fContext)
1771 fPimpl->fX11CommandBuffer.AddDrawSegments(wid, gcVals, segments, nSegments);
1772 else
1773 DrawSegmentsAux(wid, gcVals, segments, nSegments);
1774 }
1775 } else {
1776 if (!IsCocoaDraw())
1777 fPimpl->fX11CommandBuffer.AddDrawSegments(wid, gcVals, segments, nSegments);
1778 else
1779 DrawSegmentsAux(wid, gcVals, segments, nSegments);
1780 }
1781}
1782
1783//______________________________________________________________________________
1785{
1786 //Can be called directly or during flushing command buffer.
1787 assert(!fPimpl->IsRootWindow(wid) && "DrawRectangleAux, called for root window");
1788
1789 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1790
1791 if (!drawable.fIsPixmap) {
1792 //I can not draw a line at y == 0, shift the rectangle to 1 pixel (and reduce its height).
1793 if (!y) {
1794 y = 1;
1795 if (h)
1796 h -= 1;
1797 }
1798 } else {
1799 //Pixmap has native Cocoa's low-left-corner system.
1800 y = Int_t(X11::LocalYROOTToCocoa(drawable, y + h));
1801 }
1802
1803 CGContextRef ctx = fPimpl->GetDrawable(wid).fContext;
1804 assert(ctx && "DrawRectangleAux, context is null");
1805 const Quartz::CGStateGuard ctxGuard(ctx);//Will restore context state.
1806
1807 CGContextSetAllowsAntialiasing(ctx, false);
1808 //Line color from X11 context.
1809 SetStrokeParametersFromX11Context(ctx, gcVals);
1810
1811 const CGRect rect = CGRectMake(x, y, w, h);
1812 CGContextStrokeRect(ctx, rect);
1813
1814 CGContextSetAllowsAntialiasing(ctx, true);
1815}
1816
1817//______________________________________________________________________________
1819{
1820 //Can be called in a 'normal way' - from drawRect method (QuartzView)
1821 //or directly by ROOT.
1822
1823 if (!wid)//From TGX11.
1824 return;
1825
1826 assert(!fPimpl->IsRootWindow(wid) && "DrawRectangle, called for root window");
1827 assert(gc > 0 && gc <= fX11Contexts.size() && "DrawRectangle, invalid context index");
1828
1829 const GCValues_t &gcVals = fX11Contexts[gc - 1];
1830
1831 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1832
1833 if (!drawable.fIsPixmap) {
1834 NSObject<X11Window> * const window = (NSObject<X11Window> *)drawable;
1835 QuartzView * const view = (QuartzView *)window.fContentView;
1836
1837 if (ParentRendersToChild(view)) {
1838 if (X11::LockFocus(view)) {
1839 DrawRectangleAux(view.fID, gcVals, x, y, w, h);
1840 X11::UnlockFocus(view);
1841 return;
1842 }
1843 }
1844
1845 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
1846 if (!view.fContext)
1847 fPimpl->fX11CommandBuffer.AddDrawRectangle(wid, gcVals, x, y, w, h);
1848 else
1849 DrawRectangleAux(wid, gcVals, x, y, w, h);
1850 }
1851 } else {
1852 if (!IsCocoaDraw())
1853 fPimpl->fX11CommandBuffer.AddDrawRectangle(wid, gcVals, x, y, w, h);
1854 else
1855 DrawRectangleAux(wid, gcVals, x, y, w, h);
1856 }
1857}
1858
1859//______________________________________________________________________________
1861{
1862 //Can be called directly or when flushing command buffer.
1863 //Can be called directly or when flushing command buffer.
1864
1865 //From TGX11:
1866 if (!wid)
1867 return;
1868
1869 assert(!fPimpl->IsRootWindow(wid) && "FillRectangleAux, called for root window");
1870
1871 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1872 CGContextRef ctx = drawable.fContext;
1873 CGSize patternPhase = {};
1874
1875 if (drawable.fIsPixmap) {
1876 //Pixmap has low-left-corner based system.
1877 y = Int_t(X11::LocalYROOTToCocoa(drawable, y + h));
1878 }
1879
1880 const CGRect fillRect = CGRectMake(x, y, w, h);
1881
1882 if (!drawable.fIsPixmap) {
1883 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(wid).fContentView;
1884 if (view.fParentView) {
1885 const NSPoint origin = [view.fParentView convertPoint : view.frame.origin toView : nil];
1886 patternPhase.width = origin.x;
1887 patternPhase.height = origin.y;
1888 }
1889 }
1890
1891 const Quartz::CGStateGuard ctxGuard(ctx);//Will restore context state.
1892
1893 if (HasFillStippledStyle(gcVals) || HasFillOpaqueStippledStyle(gcVals) || HasFillTiledStyle(gcVals)) {
1894 PatternContext patternContext = {gcVals.fMask, gcVals.fFillStyle, 0, 0, nil, patternPhase};
1895
1896 if (HasFillStippledStyle(gcVals) || HasFillOpaqueStippledStyle(gcVals)) {
1897 assert(gcVals.fStipple != kNone &&
1898 "FillRectangleAux, fill_style is FillStippled/FillOpaqueStippled,"
1899 " but no stipple is set in a context");
1900
1901 patternContext.fForeground = gcVals.fForeground;
1902 patternContext.fImage = fPimpl->GetDrawable(gcVals.fStipple);
1903
1904 if (HasFillOpaqueStippledStyle(gcVals))
1905 patternContext.fBackground = gcVals.fBackground;
1906 } else {
1907 assert(gcVals.fTile != kNone &&
1908 "FillRectangleAux, fill_style is FillTiled, but not tile is set in a context");
1909
1910 patternContext.fImage = fPimpl->GetDrawable(gcVals.fTile);
1911 }
1912
1913 SetFillPattern(ctx, &patternContext);
1914 CGContextFillRect(ctx, fillRect);
1915
1916 return;
1917 }
1918
1919 SetFilledAreaColorFromX11Context(ctx, gcVals);
1920 CGContextFillRect(ctx, fillRect);
1921}
1922
1923//______________________________________________________________________________
1925{
1926 //Can be called in a 'normal way' - from drawRect method (QuartzView)
1927 //or directly by ROOT.
1928
1929 //From TGX11:
1930 if (!wid)
1931 return;
1932
1933 assert(!fPimpl->IsRootWindow(wid) && "FillRectangle, called for root window");
1934 assert(gc > 0 && gc <= fX11Contexts.size() && "FillRectangle, invalid context index");
1935
1936 const GCValues_t &gcVals = fX11Contexts[gc - 1];
1937 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1938
1939 if (!drawable.fIsPixmap) {
1940 NSObject<X11Window> * const window = (NSObject<X11Window> *)drawable;
1941 QuartzView * const view = (QuartzView *)window.fContentView;
1942
1943 if (ParentRendersToChild(view)) {
1944 if (X11::LockFocus(view)) {
1945 FillRectangleAux(view.fID, gcVals, x, y, w, h);
1946 X11::UnlockFocus(view);
1947 return;
1948 }
1949 }
1950
1951 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
1952 if (!view.fContext)
1953 fPimpl->fX11CommandBuffer.AddFillRectangle(wid, gcVals, x, y, w, h);
1954 else
1955 FillRectangleAux(wid, gcVals, x, y, w, h);
1956 }
1957 } else
1958 FillRectangleAux(wid, gcVals, x, y, w, h);
1959}
1960
1961//______________________________________________________________________________
1962void TGCocoa::FillPolygonAux(Window_t wid, const GCValues_t &gcVals, const Point_t *polygon, Int_t nPoints)
1963{
1964 //Can be called directly or when flushing command buffer.
1965
1966 //From TGX11:
1967 if (!wid)
1968 return;
1969
1970 assert(!fPimpl->IsRootWindow(wid) && "FillPolygonAux, called for root window");
1971 assert(polygon != 0 && "FillPolygonAux, parameter 'polygon' is null");
1972 assert(nPoints > 0 && "FillPolygonAux, number of points must be positive");
1973
1974 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
1975 CGContextRef ctx = drawable.fContext;
1976
1977 CGSize patternPhase = {};
1978
1979 if (!drawable.fIsPixmap) {
1980 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(wid).fContentView;
1981 const NSPoint origin = [view convertPoint : view.frame.origin toView : nil];
1982 patternPhase.width = origin.x;
1983 patternPhase.height = origin.y;
1984 }
1985
1986 const Quartz::CGStateGuard ctxGuard(ctx);//Will restore context state.
1987
1988 CGContextSetAllowsAntialiasing(ctx, false);
1989
1990 if (HasFillStippledStyle(gcVals) || HasFillOpaqueStippledStyle(gcVals) || HasFillTiledStyle(gcVals)) {
1991 PatternContext patternContext = {gcVals.fMask, gcVals.fFillStyle, 0, 0, nil, patternPhase};
1992
1993 if (HasFillStippledStyle(gcVals) || HasFillOpaqueStippledStyle(gcVals)) {
1994 assert(gcVals.fStipple != kNone &&
1995 "FillRectangleAux, fill style is FillStippled/FillOpaqueStippled,"
1996 " but no stipple is set in a context");
1997
1998 patternContext.fForeground = gcVals.fForeground;
1999 patternContext.fImage = fPimpl->GetDrawable(gcVals.fStipple);
2000
2001 if (HasFillOpaqueStippledStyle(gcVals))
2002 patternContext.fBackground = gcVals.fBackground;
2003 } else {
2004 assert(gcVals.fTile != kNone &&
2005 "FillRectangleAux, fill_style is FillTiled, but not tile is set in a context");
2006
2007 patternContext.fImage = fPimpl->GetDrawable(gcVals.fTile);
2008 }
2009
2010 SetFillPattern(ctx, &patternContext);
2011 } else
2012 SetFilledAreaColorFromX11Context(ctx, gcVals);
2013
2014 //This +2 -2 shit is the result of ROOT's GUI producing strange coordinates out of ....
2015 // - first noticed on checkmarks in a menu - they were all shifted.
2016
2017 CGContextBeginPath(ctx);
2018 if (!drawable.fIsPixmap) {
2019 CGContextMoveToPoint(ctx, polygon[0].fX, polygon[0].fY - 2);
2020 for (Int_t i = 1; i < nPoints; ++i)
2021 CGContextAddLineToPoint(ctx, polygon[i].fX, polygon[i].fY - 2);
2022 } else {
2023 CGContextMoveToPoint(ctx, polygon[0].fX, X11::LocalYROOTToCocoa(drawable, polygon[0].fY + 2));
2024 for (Int_t i = 1; i < nPoints; ++i)
2025 CGContextAddLineToPoint(ctx, polygon[i].fX, X11::LocalYROOTToCocoa(drawable, polygon[i].fY + 2));
2026 }
2027
2028 CGContextFillPath(ctx);
2029 CGContextSetAllowsAntialiasing(ctx, true);
2030}
2031
2032//______________________________________________________________________________
2033void TGCocoa::FillPolygon(Window_t wid, GContext_t gc, Point_t *polygon, Int_t nPoints)
2034{
2035 // Fills the region closed by the specified path. The path is closed
2036 // automatically if the last point in the list does not coincide with the
2037 // first point.
2038 //
2039 // Point_t *points - specifies an array of points
2040 // Int_t npnt - specifies the number of points in the array
2041 //
2042 // GC components in use: function, plane-mask, fill-style, fill-rule,
2043 // subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask. GC
2044 // mode-dependent components: foreground, background, tile, stipple,
2045 // tile-stipple-x-origin, and tile-stipple-y-origin.
2046 // (see also the GCValues_t structure)
2047
2048 //From TGX11:
2049 if (!wid)
2050 return;
2051
2052 assert(polygon != 0 && "FillPolygon, parameter 'polygon' is null");
2053 assert(nPoints > 0 && "FillPolygon, number of points must be positive");
2054 assert(gc > 0 && gc <= fX11Contexts.size() && "FillPolygon, invalid context index");
2055
2056 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
2057 const GCValues_t &gcVals = fX11Contexts[gc - 1];
2058
2059 if (!drawable.fIsPixmap) {
2060 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(wid).fContentView;
2061
2062 if (ParentRendersToChild(view)) {
2063 if (X11::LockFocus(view)) {
2064 FillPolygonAux(view.fID, gcVals, polygon, nPoints);
2065 X11::UnlockFocus(view);
2066 return;
2067 }
2068 }
2069
2070 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
2071 if (!view.fContext)
2072 fPimpl->fX11CommandBuffer.AddFillPolygon(wid, gcVals, polygon, nPoints);
2073 else
2074 FillPolygonAux(wid, gcVals, polygon, nPoints);
2075 }
2076 } else {
2077 if (!IsCocoaDraw())
2078 fPimpl->fX11CommandBuffer.AddFillPolygon(wid, gcVals, polygon, nPoints);
2079 else
2080 FillPolygonAux(wid, gcVals, polygon, nPoints);
2081 }
2082}
2083
2084//______________________________________________________________________________
2085void TGCocoa::CopyAreaAux(Drawable_t src, Drawable_t dst, const GCValues_t &gcVals, Int_t srcX, Int_t srcY,
2086 UInt_t width, UInt_t height, Int_t dstX, Int_t dstY)
2087{
2088 //Called directly or when flushing command buffer.
2089 if (!src || !dst)//Can this happen? From TGX11.
2090 return;
2091
2092 assert(!fPimpl->IsRootWindow(src) && "CopyAreaAux, src parameter is root window");
2093 assert(!fPimpl->IsRootWindow(dst) && "CopyAreaAux, dst parameter is root window");
2094
2095 //Some copy operations create autoreleased cocoa objects,
2096 //I do not want them to wait till run loop's iteration end to die.
2097 const Util::AutoreleasePool pool;
2098
2099 NSObject<X11Drawable> * const srcDrawable = fPimpl->GetDrawable(src);
2100 NSObject<X11Drawable> * const dstDrawable = fPimpl->GetDrawable(dst);
2101
2102 const X11::Point dstPoint(dstX, dstY);
2103 const X11::Rectangle copyArea(srcX, srcY, width, height);
2104
2105 QuartzImage *mask = nil;
2106 if ((gcVals.fMask & kGCClipMask) && gcVals.fClipMask) {
2107 assert(fPimpl->GetDrawable(gcVals.fClipMask).fIsPixmap == YES &&
2108 "CopyArea, mask is not a pixmap");
2109 mask = (QuartzImage *)fPimpl->GetDrawable(gcVals.fClipMask);
2110 }
2111
2112 X11::Point clipOrigin;
2113 if (gcVals.fMask & kGCClipXOrigin)
2114 clipOrigin.fX = gcVals.fClipXOrigin;
2115 if (gcVals.fMask & kGCClipYOrigin)
2116 clipOrigin.fY = gcVals.fClipYOrigin;
2117
2118 [dstDrawable copy : srcDrawable area : copyArea withMask : mask clipOrigin : clipOrigin toPoint : dstPoint];
2119}
2120
2121//______________________________________________________________________________
2123 UInt_t width, UInt_t height, Int_t dstX, Int_t dstY)
2124{
2125 if (!src || !dst)//Can this happen? From TGX11.
2126 return;
2127
2128 assert(!fPimpl->IsRootWindow(src) && "CopyArea, src parameter is root window");
2129 assert(!fPimpl->IsRootWindow(dst) && "CopyArea, dst parameter is root window");
2130 assert(gc > 0 && gc <= fX11Contexts.size() && "CopyArea, invalid context index");
2131
2132 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(dst);
2133 const GCValues_t &gcVals = fX11Contexts[gc - 1];
2134
2135 if (!drawable.fIsPixmap) {
2136 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(dst).fContentView;
2137
2138 if (ParentRendersToChild(view)) {
2139 if (X11::LockFocus(view)) {
2140 CopyAreaAux(src, dst, gcVals, srcX, srcY, width, height, dstX, dstY);
2141 X11::UnlockFocus(view);
2142 return;
2143 }
2144 }
2145
2146 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
2147 if (!view.fContext)
2148 fPimpl->fX11CommandBuffer.AddCopyArea(src, dst, gcVals, srcX, srcY, width, height, dstX, dstY);
2149 else
2150 CopyAreaAux(src, dst, gcVals, srcX, srcY, width, height, dstX, dstY);
2151 }
2152 } else {
2153 if (fPimpl->GetDrawable(src).fIsPixmap) {
2154 //Both are pixmaps, nothing is buffered for src (???).
2155 CopyAreaAux(src, dst, gcVals, srcX, srcY, width, height, dstX, dstY);
2156 } else {
2157 if (!IsCocoaDraw())
2158 fPimpl->fX11CommandBuffer.AddCopyArea(src, dst, gcVals, srcX, srcY, width, height, dstX, dstY);
2159 else
2160 CopyAreaAux(src, dst, gcVals, srcX, srcY, width, height, dstX, dstY);
2161 }
2162 }
2163}
2164
2165//______________________________________________________________________________
2166void TGCocoa::DrawStringAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, const char *text, Int_t len)
2167{
2168 //Can be called by ROOT directly, or indirectly by AppKit.
2169 assert(!fPimpl->IsRootWindow(wid) && "DrawStringAux, called for root window");
2170
2171 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
2172 CGContextRef ctx = drawable.fContext;
2173 assert(ctx != 0 && "DrawStringAux, context is null");
2174
2175 const Quartz::CGStateGuard ctxGuard(ctx);//Will reset parameters back.
2176
2177 CGContextSetTextMatrix(ctx, CGAffineTransformIdentity);
2178
2179 //View is flipped, I have to transform for text to work.
2180 if (!drawable.fIsPixmap) {
2181 CGContextTranslateCTM(ctx, 0., drawable.fHeight);
2182 CGContextScaleCTM(ctx, 1., -1.);
2183 }
2184
2185 //Text must be antialiased
2186 CGContextSetAllowsAntialiasing(ctx, true);
2187
2188 assert(gcVals.fMask & kGCFont && "DrawString, font is not set in a context");
2189
2190 if (len < 0)//Negative length can come from caller.
2191 len = std::strlen(text);
2192 //Text can be not black, for example, highlighted label.
2193 CGFloat textColor[4] = {0., 0., 0., 1.};//black by default.
2194 //I do not check the results here, it's ok to have a black text.
2195 if (gcVals.fMask & kGCForeground)
2196 X11::PixelToRGB(gcVals.fForeground, textColor);
2197
2198 CGContextSetRGBFillColor(ctx, textColor[0], textColor[1], textColor[2], textColor[3]);
2199
2200 //Do a simple text layout using CGGlyphs.
2201 //GUI uses non-ascii symbols, and does not care about signed/unsigned - just dump everything
2202 //into a char and be happy. I'm not.
2203 std::vector<UniChar> unichars((unsigned char *)text, (unsigned char *)text + len);
2204 FixAscii(unichars);
2205
2206 Quartz::DrawTextLineNoKerning(ctx, (CTFontRef)gcVals.fFont, unichars, x, X11::LocalYROOTToCocoa(drawable, y));
2207}
2208
2209//______________________________________________________________________________
2211{
2212 //Can be called by ROOT directly, or indirectly by AppKit.
2213 if (!wid)//from TGX11.
2214 return;
2215
2216 assert(!fPimpl->IsRootWindow(wid) && "DrawString, called for root window");
2217 assert(gc > 0 && gc <= fX11Contexts.size() && "DrawString, invalid context index");
2218
2219 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
2220 const GCValues_t &gcVals = fX11Contexts[gc - 1];
2221 assert(gcVals.fMask & kGCFont && "DrawString, font is not set in a context");
2222
2223 if (!drawable.fIsPixmap) {
2224 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(wid).fContentView;
2225
2226 if (ParentRendersToChild(view)) {//Ufff.
2227 if (X11::LockFocus(view)) {
2228
2229 try {
2230 DrawStringAux(view.fID, gcVals, x, y, text, len);
2231 } catch (const std::exception &) {
2232 X11::UnlockFocus(view);
2233 throw;
2234 }
2235
2236 X11::UnlockFocus(view);
2237 return;
2238 }
2239 }
2240
2241 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
2242 if (!view.fContext)
2243 fPimpl->fX11CommandBuffer.AddDrawString(wid, gcVals, x, y, text, len);
2244 else
2245 DrawStringAux(wid, gcVals, x, y, text, len);
2246 }
2247
2248 } else {
2249 if (!IsCocoaDraw())
2250 fPimpl->fX11CommandBuffer.AddDrawString(wid, gcVals, x, y, text, len);
2251 else
2252 DrawStringAux(wid, gcVals, x, y, text, len);
2253 }
2254}
2255
2256//______________________________________________________________________________
2258{
2259 assert(!fPimpl->IsRootWindow(windowID) && "ClearAreaAux, called for root window");
2260
2261 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(windowID).fContentView;
2262 assert(view.fContext != 0 && "ClearAreaAux, view.fContext is null");
2263
2264 //w and h can be 0 (comment from TGX11) - clear the entire window.
2265 if (!w)
2266 w = view.fWidth;
2267 if (!h)
2268 h = view.fHeight;
2269
2270 if (!view.fBackgroundPixmap) {
2271 //Simple solid fill.
2272 CGFloat rgb[3] = {};
2274
2275 const Quartz::CGStateGuard ctxGuard(view.fContext);
2276 CGContextSetRGBFillColor(view.fContext, rgb[0], rgb[1], rgb[2], 1.);//alpha can be also used.
2277 CGContextFillRect(view.fContext, CGRectMake(x, y, w, h));
2278 } else {
2279 const CGRect fillRect = CGRectMake(x, y, w, h);
2280
2281 CGSize patternPhase = {};
2282 if (view.fParentView) {
2283 const NSPoint origin = [view.fParentView convertPoint : view.frame.origin toView : nil];
2284 patternPhase.width = origin.x;
2285 patternPhase.height = origin.y;
2286 }
2287 const Quartz::CGStateGuard ctxGuard(view.fContext);//Will restore context state.
2288
2289 PatternContext patternContext = {Mask_t(), 0, 0, 0, view.fBackgroundPixmap, patternPhase};
2290 SetFillPattern(view.fContext, &patternContext);
2291 CGContextFillRect(view.fContext, fillRect);
2292 }
2293}
2294
2295//______________________________________________________________________________
2297{
2298 //Can be called from drawRect method and also by ROOT's GUI directly.
2299 //Should not be called for pixmap?
2300
2301 //From TGX11:
2302 if (!wid)
2303 return;
2304
2305 assert(!fPimpl->IsRootWindow(wid) && "ClearArea, called for root window");
2306
2307 //If wid is pixmap or image, this will crush.
2308 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(wid).fContentView;
2309
2310 if (ParentRendersToChild(view)) {
2311 if (X11::LockFocus(view)) {
2312 ClearAreaAux(view.fID, x, y, w, h);
2313 X11::UnlockFocus(view);
2314 return;
2315 }
2316 }
2317
2318 if (!view.fIsOverlapped && view.fMapState == kIsViewable) {
2319 if (!view.fContext)
2320 fPimpl->fX11CommandBuffer.AddClearArea(wid, x, y, w, h);
2321 else
2322 ClearAreaAux(wid, x, y, w, h);
2323 }
2324}
2325
2326//______________________________________________________________________________
2328{
2329 //Clears the entire area in the specified window (comment from TGX11).
2330
2331 //From TGX11:
2332 if (!wid)
2333 return;
2334
2335 ClearArea(wid, 0, 0, 0, 0);
2336}
2337
2338#pragma mark - Pixmap management.
2339
2340//______________________________________________________________________________
2342{
2343 //Two stage creation.
2344 NSSize newSize = {};
2345 newSize.width = w;
2346 newSize.height = h;
2347
2348 Util::NSScopeGuard<QuartzPixmap> pixmap([[QuartzPixmap alloc] initWithW : w H : h
2349 scaleFactor : [[NSScreen mainScreen] backingScaleFactor]]);
2350 if (pixmap.Get()) {
2351 pixmap.Get().fID = fPimpl->RegisterDrawable(pixmap.Get());//Can throw.
2352 return (Int_t)pixmap.Get().fID;
2353 } else {
2354 //Detailed error message was issued by QuartzPixmap by this point:
2355 Error("OpenPixmap", "QuartzPixmap initialization failed");
2356 return -1;
2357 }
2358}
2359
2360//______________________________________________________________________________
2362{
2363 assert(!fPimpl->IsRootWindow(wid) && "ResizePixmap, called for root window");
2364
2365 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
2366 assert(drawable.fIsPixmap == YES && "ResizePixmap, invalid drawable");
2367
2368 QuartzPixmap *pixmap = (QuartzPixmap *)drawable;
2369 if (w == pixmap.fWidth && h == pixmap.fHeight)
2370 return 1;
2371
2372 if ([pixmap resizeW : w H : h scaleFactor : [[NSScreen mainScreen] backingScaleFactor]])
2373 return 1;
2374
2375 return -1;
2376}
2377
2378//______________________________________________________________________________
2380{
2381 assert(pixmapID > (Int_t)fPimpl->GetRootWindowID() &&
2382 "SelectPixmap, parameter 'pixmapID' is not a valid id");
2383
2384 fSelectedDrawable = pixmapID;
2385}
2386
2387//______________________________________________________________________________
2389{
2390 assert(pixmapID > (Int_t)fPimpl->GetRootWindowID() &&
2391 "CopyPixmap, parameter 'pixmapID' is not a valid id");
2392 assert(fSelectedDrawable > fPimpl->GetRootWindowID() &&
2393 "CopyPixmap, fSelectedDrawable is not a valid window id");
2394
2395 NSObject<X11Drawable> * const source = fPimpl->GetDrawable(pixmapID);
2396 assert([source isKindOfClass : [QuartzPixmap class]] &&
2397 "CopyPixmap, source is not a pixmap");
2398 QuartzPixmap * const pixmap = (QuartzPixmap *)source;
2399
2400 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(fSelectedDrawable);
2401 NSObject<X11Drawable> * destination = nil;
2402
2403 if (drawable.fIsPixmap) {
2404 destination = drawable;
2405 } else {
2406 NSObject<X11Window> * const window = fPimpl->GetWindow(fSelectedDrawable);
2407 if (window.fBackBuffer) {
2408 destination = window.fBackBuffer;
2409 } else {
2410 Warning("CopyPixmap", "Operation skipped, since destination"
2411 " window is not double buffered");
2412 return;
2413 }
2414 }
2415
2416 const X11::Rectangle copyArea(0, 0, pixmap.fWidth, pixmap.fHeight);
2417 const X11::Point dstPoint(x, y);
2418
2419 [destination copy : pixmap area : copyArea withMask : nil clipOrigin : X11::Point() toPoint : dstPoint];
2420}
2421
2422//______________________________________________________________________________
2424{
2425 // Deletes current pixmap.
2426 assert(fSelectedDrawable > fPimpl->GetRootWindowID() && "ClosePixmap, no drawable selected");
2427 assert(fPimpl->GetDrawable(fSelectedDrawable).fIsPixmap == YES && "ClosePixmap, selected drawable is not a pixmap");
2428
2431}
2432
2433#pragma mark - Different functions to create pixmap from different data sources. Used by GUI.
2434#pragma mark - These functions implement TVirtualX interface, some of them dupilcate others.
2435
2436//______________________________________________________________________________
2438{
2439 //
2440 return OpenPixmap(w, h);
2441}
2442
2443//______________________________________________________________________________
2444Pixmap_t TGCocoa::CreatePixmap(Drawable_t /*wid*/, const char *bitmap, UInt_t width, UInt_t height,
2445 ULong_t foregroundPixel, ULong_t backgroundPixel, Int_t depth)
2446{
2447 //Create QuartzImage, using bitmap and foregroundPixel/backgroundPixel,
2448 //if depth is one - create an image mask instead.
2449
2450 assert(bitmap != 0 && "CreatePixmap, parameter 'bitmap' is null");
2451 assert(width > 0 && "CreatePixmap, parameter 'width' is 0");
2452 assert(height > 0 && "CreatePixmap, parameter 'height' is 0");
2453
2454 std::vector<unsigned char> imageData (depth > 1 ? width * height * 4 : width * height);
2455
2456 X11::FillPixmapBuffer((unsigned char*)bitmap, width, height, foregroundPixel,
2457 backgroundPixel, depth, &imageData[0]);
2458
2459 //Now we can create CGImageRef.
2461
2462 if (depth > 1)
2463 image.Reset([[QuartzImage alloc] initWithW : width H : height data: &imageData[0]]);
2464 else
2465 image.Reset([[QuartzImage alloc] initMaskWithW : width H : height bitmapMask : &imageData[0]]);
2466
2467 if (!image.Get()) {
2468 Error("CreatePixmap", "QuartzImage initialization failed");//More concrete message was issued by QuartzImage.
2469 return kNone;
2470 }
2471
2472 image.Get().fID = fPimpl->RegisterDrawable(image.Get());//This can throw.
2473 return image.Get().fID;
2474}
2475
2476//______________________________________________________________________________
2478{
2479 //Create QuartzImage, using "bits" (data in bgra format).
2480 assert(bits != 0 && "CreatePixmapFromData, data parameter is null");
2481 assert(width != 0 && "CreatePixmapFromData, width parameter is 0");
2482 assert(height != 0 && "CreatePixmapFromData, height parameter is 0");
2483
2484 //I'm not using vector here, since I have to pass this pointer to Obj-C code
2485 //(and Obj-C object will own this memory later).
2486 std::vector<unsigned char> imageData(bits, bits + width * height * 4);
2487
2488 //Convert bgra to rgba.
2489 unsigned char *p = &imageData[0];
2490 for (unsigned i = 0, e = width * height; i < e; ++i, p += 4)
2491 std::swap(p[0], p[2]);
2492
2493 //Now we can create CGImageRef.
2494 Util::NSScopeGuard<QuartzImage> image([[QuartzImage alloc] initWithW : width
2495 H : height data : &imageData[0]]);
2496
2497 if (!image.Get()) {
2498 //Detailed error message was issued by QuartzImage.
2499 Error("CreatePixmapFromData", "QuartzImage initialziation failed");
2500 return kNone;
2501 }
2502
2503 image.Get().fID = fPimpl->RegisterDrawable(image.Get());//This can throw.
2504 return image.Get().fID;
2505}
2506
2507//______________________________________________________________________________
2508Pixmap_t TGCocoa::CreateBitmap(Drawable_t /*wid*/, const char *bitmap, UInt_t width, UInt_t height)
2509{
2510 //Create QuartzImage with image mask.
2511 assert(std::numeric_limits<unsigned char>::digits == 8 && "CreateBitmap, ASImage requires octets");
2512
2513 //I'm not using vector here, since I have to pass this pointer to Obj-C code
2514 //(and Obj-C object will own this memory later).
2515
2516 //TASImage has a bug, it calculates size in pixels (making a with to multiple-of eight and
2517 //allocates memory as each bit occupies one byte, and later packs bits into bytes.
2518
2519 std::vector<unsigned char> imageData(width * height);
2520
2521 //TASImage assumes 8-bit bytes and packs mask bits.
2522 for (unsigned i = 0, j = 0, e = width / 8 * height; i < e; ++i) {
2523 for(unsigned bit = 0; bit < 8; ++bit, ++j) {
2524 if (bitmap[i] & (1 << bit))
2525 imageData[j] = 0;//Opaque.
2526 else
2527 imageData[j] = 255;//Masked out bit.
2528 }
2529 }
2530
2531 //Now we can create CGImageRef.
2532 Util::NSScopeGuard<QuartzImage> image([[QuartzImage alloc] initMaskWithW : width
2533 H : height bitmapMask : &imageData[0]]);
2534 if (!image.Get()) {
2535 //Detailed error message was issued by QuartzImage.
2536 Error("CreateBitmap", "QuartzImage initialization failed");
2537 return kNone;
2538 }
2539
2540 image.Get().fID = fPimpl->RegisterDrawable(image.Get());//This can throw.
2541 return image.Get().fID;
2542}
2543
2544//______________________________________________________________________________
2546{
2547 fPimpl->DeleteDrawable(pixmapID);
2548}
2549
2550//______________________________________________________________________________
2552{
2553 // Explicitely deletes the pixmap resource "pmap".
2554 assert(fPimpl->GetDrawable(pixmapID).fIsPixmap == YES && "DeletePixmap, object is not a pixmap");
2555 fPimpl->fX11CommandBuffer.AddDeletePixmap(pixmapID);
2556}
2557
2558//______________________________________________________________________________
2560{
2561 // Registers a pixmap created by TGLManager as a ROOT pixmap
2562 //
2563 // w, h - the width and height, which define the pixmap size
2564 return 0;
2565}
2566
2567//______________________________________________________________________________
2569{
2570 //Can be also in a window management part, since window is also drawable.
2571 if (fPimpl->IsRootWindow(wid)) {
2572 Warning("GetColorBits", "Called for root window");
2573 } else {
2574 assert(x >= 0 && "GetColorBits, parameter 'x' is negative");
2575 assert(y >= 0 && "GetColorBits, parameter 'y' is negative");
2576 assert(w != 0 && "GetColorBits, parameter 'w' is 0");
2577 assert(h != 0 && "GetColorBits, parameter 'h' is 0");
2578
2579 const X11::Rectangle area(x, y, w, h);
2580 return [fPimpl->GetDrawable(wid) readColorBits : area];//readColorBits can throw std::bad_alloc, no resource will leak.
2581 }
2582
2583 return 0;
2584}
2585
2586#pragma mark - XImage emulation.
2587
2588//______________________________________________________________________________
2590{
2591 // Allocates the memory needed for a drawable.
2592 //
2593 // width - the width of the image, in pixels
2594 // height - the height of the image, in pixels
2595 return OpenPixmap(width, height);
2596}
2597
2598//______________________________________________________________________________
2600{
2601 // Returns the width and height of the image wid
2602 assert(wid > fPimpl->GetRootWindowID() && "GetImageSize, parameter 'wid' is invalid");
2603
2604 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(wid);
2605 width = drawable.fWidth;
2606 height = drawable.fHeight;
2607}
2608
2609//______________________________________________________________________________
2611{
2612 // Overwrites the pixel in the image with the specified pixel value.
2613 // The image must contain the x and y coordinates.
2614 //
2615 // imageID - specifies the image
2616 // x, y - coordinates
2617 // pixel - the new pixel value
2618
2619 assert([fPimpl->GetDrawable(imageID) isKindOfClass : [QuartzPixmap class]] &&
2620 "PutPixel, parameter 'imageID' is a bad pixmap id");
2621 assert(x >= 0 && "PutPixel, parameter 'x' is negative");
2622 assert(y >= 0 && "PutPixel, parameter 'y' is negative");
2623
2624 QuartzPixmap * const pixmap = (QuartzPixmap *)fPimpl->GetDrawable(imageID);
2625
2626 unsigned char rgb[3] = {};
2627 X11::PixelToRGB(pixel, rgb);
2628 [pixmap putPixel : rgb X : x Y : y];
2629}
2630
2631//______________________________________________________________________________
2632void TGCocoa::PutImage(Drawable_t drawableID, GContext_t gc, Drawable_t imageID, Int_t dstX, Int_t dstY,
2633 Int_t srcX, Int_t srcY, UInt_t width, UInt_t height)
2634{
2635 //TGX11 uses ZPixmap in CreateImage ... so background/foreground
2636 //in gc can NEVER be used (and the depth is ALWAYS > 1).
2637 //This means .... I can call CopyArea!
2638
2639 CopyArea(imageID, drawableID, gc, srcX, srcY, width, height, dstX, dstY);
2640}
2641
2642//______________________________________________________________________________
2644{
2645 // Deallocates the memory associated with the image img
2646 assert([fPimpl->GetDrawable(imageID) isKindOfClass : [QuartzPixmap class]] &&
2647 "DeleteImage, imageID parameter is not a valid image id");
2648 DeletePixmap(imageID);
2649}
2650
2651#pragma mark - Mouse related code.
2652
2653//______________________________________________________________________________
2654void TGCocoa::GrabButton(Window_t wid, EMouseButton button, UInt_t keyModifiers, UInt_t eventMask,
2655 Window_t /*confine*/, Cursor_t /*cursor*/, Bool_t grab)
2656{
2657 //Emulate "passive grab" feature of X11 (similar to "implicit grab" in Cocoa
2658 //and implicit grab on X11, the difference is that "implicit grab" works as
2659 //if owner_events parameter for XGrabButton was False, but in ROOT
2660 //owner_events for XGrabButton is _always_ True.
2661 //Confine will never be used - no such feature on MacOSX and
2662 //I'm not going to emulate it..
2663 //This function also does ungrab.
2664
2665 //From TGWin32:
2666 if (!wid)
2667 return;
2668
2669 assert(!fPimpl->IsRootWindow(wid) && "GrabButton, called for 'root' window");
2670
2671 NSObject<X11Window> * const widget = fPimpl->GetWindow(wid);
2672
2673 if (grab) {
2674 widget.fPassiveGrabOwnerEvents = YES; //This is how TGX11 works.
2675 widget.fPassiveGrabButton = button;
2676 widget.fPassiveGrabEventMask = eventMask;
2677 widget.fPassiveGrabKeyModifiers = keyModifiers;
2678 //Set the cursor.
2679 } else {
2680 widget.fPassiveGrabOwnerEvents = NO;
2681 widget.fPassiveGrabButton = -1;//0 is kAnyButton.
2682 widget.fPassiveGrabEventMask = 0;
2683 widget.fPassiveGrabKeyModifiers = 0;
2684 }
2685}
2686
2687//______________________________________________________________________________
2688void TGCocoa::GrabPointer(Window_t wid, UInt_t eventMask, Window_t /*confine*/, Cursor_t /*cursor*/, Bool_t grab, Bool_t ownerEvents)
2689{
2690 //Emulate pointer grab from X11.
2691 //Confine will never be used - no such feature on MacOSX and
2692 //I'm not going to emulate it..
2693 //This function also does ungrab.
2694
2695 if (grab) {
2696 NSView<X11Window> * const view = fPimpl->GetWindow(wid).fContentView;
2697 assert(!fPimpl->IsRootWindow(wid) && "GrabPointer, called for 'root' window");
2698 //set the cursor.
2699 //set active grab.
2700 fPimpl->fX11EventTranslator.SetPointerGrab(view, eventMask, ownerEvents);
2701 } else {
2702 //unset cursor?
2703 //cancel grab.
2704 fPimpl->fX11EventTranslator.CancelPointerGrab();
2705 }
2706}
2707
2708//______________________________________________________________________________
2710{
2711 // Changes the specified dynamic parameters if the pointer is actively
2712 // grabbed by the client and if the specified time is no earlier than the
2713 // last-pointer-grab time and no later than the current X server time.
2714 //Noop.
2715}
2716
2717//______________________________________________________________________________
2719{
2720 // Turns key auto repeat on (kTRUE) or off (kFALSE).
2721 //Noop.
2722}
2723
2724//______________________________________________________________________________
2725void TGCocoa::GrabKey(Window_t wid, Int_t keyCode, UInt_t rootKeyModifiers, Bool_t grab)
2726{
2727 //Comment from TVirtualX:
2728 // Establishes a passive grab on the keyboard. In the future, the
2729 // keyboard is actively grabbed, the last-keyboard-grab time is set
2730 // to the time at which the key was pressed (as transmitted in the
2731 // KeyPress event), and the KeyPress event is reported if all of the
2732 // following conditions are true:
2733 // - the keyboard is not grabbed and the specified key (which can
2734 // itself be a modifier key) is logically pressed when the
2735 // specified modifier keys are logically down, and no other
2736 // modifier keys are logically down;
2737 // - either the grab window "id" is an ancestor of (or is) the focus
2738 // window, or "id" is a descendant of the focus window and contains
2739 // the pointer;
2740 // - a passive grab on the same key combination does not exist on any
2741 // ancestor of grab_window
2742 //
2743 // id - window id
2744 // keycode - specifies the KeyCode or AnyKey
2745 // modifier - specifies the set of keymasks or AnyModifier; the mask is
2746 // the bitwise inclusive OR of the valid keymask bits
2747 // grab - a switch between grab/ungrab key
2748 // grab = kTRUE grab the key and modifier
2749 // grab = kFALSE ungrab the key and modifier
2750 //End of comment.
2751
2752
2753 //Key code already must be Cocoa's key code, this is done by GUI classes,
2754 //they call KeySymToKeyCode.
2755 assert(!fPimpl->IsRootWindow(wid) && "GrabKey, called for root window");
2756
2757 NSView<X11Window> * const view = fPimpl->GetWindow(wid).fContentView;
2758 const NSUInteger cocoaKeyModifiers = X11::GetCocoaKeyModifiersFromROOTKeyModifiers(rootKeyModifiers);
2759
2760 if (grab)
2761 [view addPassiveKeyGrab : keyCode modifiers : cocoaKeyModifiers];
2762 else
2763 [view removePassiveKeyGrab : keyCode modifiers : cocoaKeyModifiers];
2764}
2765
2766//______________________________________________________________________________
2768{
2769 // Converts the "keysym" to the appropriate keycode. For example,
2770 // keysym is a letter and keycode is the matching keyboard key (which
2771 // is dependend on the current keyboard mapping). If the specified
2772 // "keysym" is not defined for any keycode, returns zero.
2773
2774 return X11::MapKeySymToKeyCode(keySym);
2775}
2776
2777//______________________________________________________________________________
2779{
2780 // Returns the window id of the window having the input focus.
2781
2782 return fPimpl->fX11EventTranslator.GetInputFocus();
2783}
2784
2785//______________________________________________________________________________
2787{
2788 // Changes the input focus to specified window "wid".
2789 assert(!fPimpl->IsRootWindow(wid) && "SetInputFocus, called for root window");
2790
2791 if (wid == kNone)
2792 fPimpl->fX11EventTranslator.SetInputFocus(nil);
2793 else
2794 fPimpl->fX11EventTranslator.SetInputFocus(fPimpl->GetWindow(wid).fContentView);
2795}
2796
2797//______________________________________________________________________________
2798void TGCocoa::LookupString(Event_t *event, char *buf, Int_t length, UInt_t &keysym)
2799{
2800 // Converts the keycode from the event structure to a key symbol (according
2801 // to the modifiers specified in the event structure and the current
2802 // keyboard mapping). In "buf" a null terminated ASCII string is returned
2803 // representing the string that is currently mapped to the key code.
2804 //
2805 // event - specifies the event structure to be used
2806 // buf - returns the translated characters
2807 // buflen - the length of the buffer
2808 // keysym - returns the "keysym" computed from the event
2809 // if this argument is not NULL
2810 assert(buf != 0 && "LookupString, parameter 'buf' is null");
2811 assert(length >= 2 && "LookupString, parameter 'length' - not enough memory to return null-terminated ASCII string");
2812
2813 X11::MapUnicharToKeySym(event->fCode, buf, length, keysym);
2814}
2815
2816#pragma mark - Font management.
2817
2818//______________________________________________________________________________
2820{
2821 //fontName is in XLFD format:
2822 //-foundry-family- ..... etc., some components can be omitted and replaced by *.
2823 assert(fontName != 0 && "LoadQueryFont, fontName is null");
2824
2825 X11::XLFDName xlfd;
2826 if (ParseXLFDName(fontName, xlfd)) {
2827 //Make names more flexible: fFamilyName can be empty or '*'.
2828 if (!xlfd.fFamilyName.length() || xlfd.fFamilyName == "*")
2829 xlfd.fFamilyName = "Courier";//Up to me, right?
2830 if (!xlfd.fPixelSize)
2831 xlfd.fPixelSize = 11;//Again, up to me.
2832 return fPimpl->fFontManager.LoadFont(xlfd);
2833 }
2834
2835 return FontStruct_t();
2836}
2837
2838//______________________________________________________________________________
2840{
2841 return (FontH_t)fs;
2842}
2843
2844//______________________________________________________________________________
2846{
2847 fPimpl->fFontManager.UnloadFont(fs);
2848}
2849
2850//______________________________________________________________________________
2852{
2853 // Returns True when TrueType fonts are used
2854 //No, we use Core Text and do not want TTF to calculate metrics.
2855 return kFALSE;
2856}
2857
2858//______________________________________________________________________________
2860{
2861 // Return lenght of the string "s" in pixels. Size depends on font.
2862 return fPimpl->fFontManager.GetTextWidth(font, s, len);
2863}
2864
2865//______________________________________________________________________________
2866void TGCocoa::GetFontProperties(FontStruct_t font, Int_t &maxAscent, Int_t &maxDescent)
2867{
2868 // Returns the font properties.
2869 fPimpl->fFontManager.GetFontProperties(font, maxAscent, maxDescent);
2870}
2871
2872//______________________________________________________________________________
2874{
2875 // Retrieves the associated font structure of the font specified font
2876 // handle "fh".
2877 //
2878 // Free returned FontStruct_t using FreeFontStruct().
2879
2880 return (FontStruct_t)fh;
2881}
2882
2883//______________________________________________________________________________
2885{
2886 // Frees the font structure "fs". The font itself will be freed when
2887 // no other resource references it.
2888 //Noop.
2889}
2890
2891//______________________________________________________________________________
2892char **TGCocoa::ListFonts(const char *fontName, Int_t maxNames, Int_t &count)
2893{
2894 count = 0;
2895
2896 if (fontName && fontName[0]) {
2897 X11::XLFDName xlfd;
2898 if (X11::ParseXLFDName(fontName, xlfd))
2899 return fPimpl->fFontManager.ListFonts(xlfd, maxNames, count);
2900 }
2901
2902 return 0;
2903}
2904
2905//______________________________________________________________________________
2906void TGCocoa::FreeFontNames(char **fontList)
2907{
2908 // Frees the specified the array of strings "fontlist".
2909 if (!fontList)
2910 return;
2911
2912 fPimpl->fFontManager.FreeFontNames(fontList);
2913}
2914
2915#pragma mark - Color management.
2916
2917//______________________________________________________________________________
2918Bool_t TGCocoa::ParseColor(Colormap_t /*cmap*/, const char *colorName, ColorStruct_t &color)
2919{
2920 //"Color" passed as colorName, can be one of the names, defined in X11/rgb.txt,
2921 //or rgb triplet, which looks like: #rgb #rrggbb #rrrgggbbb #rrrrggggbbbb,
2922 //where r, g, and b - are hex digits.
2923 return fPimpl->fX11ColorParser.ParseColor(colorName, color);
2924}
2925
2926//______________________________________________________________________________
2928{
2929 const unsigned red = unsigned(double(color.fRed) / 0xFFFF * 0xFF);
2930 const unsigned green = unsigned(double(color.fGreen) / 0xFFFF * 0xFF);
2931 const unsigned blue = unsigned(double(color.fBlue) / 0xFFFF * 0xFF);
2932 color.fPixel = red << 16 | green << 8 | blue;
2933 return kTRUE;
2934}
2935
2936//______________________________________________________________________________
2938{
2939 // Returns the current RGB value for the pixel in the "color" structure
2940 color.fRed = (color.fPixel >> 16 & 0xFF) * 0xFFFF / 0xFF;
2941 color.fGreen = (color.fPixel >> 8 & 0xFF) * 0xFFFF / 0xFF;
2942 color.fBlue = (color.fPixel & 0xFF) * 0xFFFF / 0xFF;
2943}
2944
2945//______________________________________________________________________________
2946void TGCocoa::FreeColor(Colormap_t /*cmap*/, ULong_t /*pixel*/)
2947{
2948 // Frees color cell with specified pixel value.
2949}
2950
2951//______________________________________________________________________________
2953{
2954 ULong_t pixel = 0;
2955 if (const TColor * const color = gROOT->GetColor(rootColorIndex)) {
2956 Float_t red = 0.f, green = 0.f, blue = 0.f;
2957 color->GetRGB(red, green, blue);
2958 pixel = unsigned(red * 255) << 16;
2959 pixel |= unsigned(green * 255) << 8;
2960 pixel |= unsigned(blue * 255);
2961 }
2962
2963 return pixel;
2964}
2965
2966//______________________________________________________________________________
2968{
2969 //Implemented as NSBitsPerPixelFromDepth([mainScreen depth]);
2970 nPlanes = GetDepth();
2971}
2972
2973//______________________________________________________________________________
2974void TGCocoa::GetRGB(Int_t /*index*/, Float_t &/*r*/, Float_t &/*g*/, Float_t &/*b*/)
2975{
2976 // Returns RGB values for color "index".
2977}
2978
2979//______________________________________________________________________________
2980void TGCocoa::SetRGB(Int_t /*cindex*/, Float_t /*r*/, Float_t /*g*/, Float_t /*b*/)
2981{
2982 // Sets color intensities the specified color index "cindex".
2983 //
2984 // cindex - color index
2985 // r, g, b - the red, green, blue intensities between 0.0 and 1.0
2986}
2987
2988//______________________________________________________________________________
2990{
2991 return Colormap_t();
2992}
2993
2994#pragma mark - Graphical context management.
2995
2996//______________________________________________________________________________
2998{
2999 //Here I have to imitate graphics context that exists in X11.
3000 fX11Contexts.push_back(*gval);
3001 return fX11Contexts.size();
3002}
3003
3004//______________________________________________________________________________
3006{
3007 // Sets the foreground color for the specified GC (shortcut for ChangeGC
3008 // with only foreground mask set).
3009 //
3010 // gc - specifies the GC
3011 // foreground - the foreground you want to set
3012 // (see also the GCValues_t structure)
3013
3014 assert(gc <= fX11Contexts.size() && gc > 0 && "ChangeGC, invalid context id");
3015
3016 GCValues_t &x11Context = fX11Contexts[gc - 1];
3017 x11Context.fMask |= kGCForeground;
3018 x11Context.fForeground = foreground;
3019}
3020
3021//______________________________________________________________________________
3023{
3024 //
3025 assert(gc <= fX11Contexts.size() && gc > 0 && "ChangeGC, invalid context id");
3026 assert(gval != 0 && "ChangeGC, gval parameter is null");
3027
3028 GCValues_t &x11Context = fX11Contexts[gc - 1];
3029 const Mask_t &mask = gval->fMask;
3030 x11Context.fMask |= mask;
3031
3032 //Not all of GCValues_t members are used, but
3033 //all can be copied/set without any problem.
3034
3035 if (mask & kGCFunction)
3036 x11Context.fFunction = gval->fFunction;
3037 if (mask & kGCPlaneMask)
3038 x11Context.fPlaneMask = gval->fPlaneMask;
3039 if (mask & kGCForeground)
3040 x11Context.fForeground = gval->fForeground;
3041 if (mask & kGCBackground)
3042 x11Context.fBackground = gval->fBackground;
3043 if (mask & kGCLineWidth)
3044 x11Context.fLineWidth = gval->fLineWidth;
3045 if (mask & kGCLineStyle)
3046 x11Context.fLineStyle = gval->fLineStyle;
3047 if (mask & kGCCapStyle)//nobody uses
3048 x11Context.fCapStyle = gval->fCapStyle;
3049 if (mask & kGCJoinStyle)//nobody uses
3050 x11Context.fJoinStyle = gval->fJoinStyle;
3051 if (mask & kGCFillRule)//nobody uses
3052 x11Context.fFillRule = gval->fFillRule;
3053 if (mask & kGCArcMode)//nobody uses
3054 x11Context.fArcMode = gval->fArcMode;
3055 if (mask & kGCFillStyle)
3056 x11Context.fFillStyle = gval->fFillStyle;
3057 if (mask & kGCTile)
3058 x11Context.fTile = gval->fTile;
3059 if (mask & kGCStipple)
3060 x11Context.fStipple = gval->fStipple;
3061 if (mask & kGCTileStipXOrigin)
3062 x11Context.fTsXOrigin = gval->fTsXOrigin;
3063 if (mask & kGCTileStipYOrigin)
3064 x11Context.fTsYOrigin = gval->fTsYOrigin;
3065 if (mask & kGCFont)
3066 x11Context.fFont = gval->fFont;
3067 if (mask & kGCSubwindowMode)
3068 x11Context.fSubwindowMode = gval->fSubwindowMode;
3069 if (mask & kGCGraphicsExposures)
3070 x11Context.fGraphicsExposures = gval->fGraphicsExposures;
3071 if (mask & kGCClipXOrigin)
3072 x11Context.fClipXOrigin = gval->fClipXOrigin;
3073 if (mask & kGCClipYOrigin)
3074 x11Context.fClipYOrigin = gval->fClipYOrigin;
3075 if (mask & kGCClipMask)
3076 x11Context.fClipMask = gval->fClipMask;
3077 if (mask & kGCDashOffset)
3078 x11Context.fDashOffset = gval->fDashOffset;
3079 if (mask & kGCDashList) {
3080 const unsigned nDashes = sizeof x11Context.fDashes / sizeof x11Context.fDashes[0];
3081 for (unsigned i = 0; i < nDashes; ++i)
3082 x11Context.fDashes[i] = gval->fDashes[i];
3083 x11Context.fDashLen = gval->fDashLen;
3084 }
3085}
3086
3087//______________________________________________________________________________
3089{
3090 assert(src <= fX11Contexts.size() && src > 0 && "CopyGC, bad source context");
3091 assert(dst <= fX11Contexts.size() && dst > 0 && "CopyGC, bad destination context");
3092
3093 GCValues_t srcContext = fX11Contexts[src - 1];
3094 srcContext.fMask = mask;
3095
3096 ChangeGC(dst, &srcContext);
3097}
3098
3099//______________________________________________________________________________
3101{
3102 // Returns the components specified by the mask in "gval" for the
3103 // specified GC "gc" (see also the GCValues_t structure)
3104 const GCValues_t &gcVal = fX11Contexts[gc - 1];
3105 gval = gcVal;
3106}
3107
3108//______________________________________________________________________________
3110{
3111 // Deletes the specified GC "gc".
3112}
3113
3114#pragma mark - Cursor management.
3115
3116//______________________________________________________________________________
3118{
3119 // Creates the specified cursor. (just return cursor from cursor pool).
3120 // The cursor can be:
3121 //
3122 // kBottomLeft, kBottomRight, kTopLeft, kTopRight,
3123 // kBottomSide, kLeftSide, kTopSide, kRightSide,
3124 // kMove, kCross, kArrowHor, kArrowVer,
3125 // kHand, kRotate, kPointer, kArrowRight,
3126 // kCaret, kWatch
3127
3128 return Cursor_t(cursor + 1);//HAHAHAHAHA!!! CREATED!!!
3129}
3130
3131//______________________________________________________________________________
3133{
3134 // The cursor "cursor" will be used when the pointer is in the
3135 // window "wid".
3136 assert(!fPimpl->IsRootWindow(wid) && "SetCursor, called for root window");
3137
3138 NSView<X11Window> * const view = fPimpl->GetWindow(wid).fContentView;
3139 view.fCurrentCursor = cursor;
3140}
3141
3142//______________________________________________________________________________
3144{
3145 // Sets the cursor "curid" to be used when the pointer is in the
3146 // window "wid".
3147 if (cursorID > 0)
3148 SetCursor(Int_t(wid), ECursor(cursorID - 1));
3149 else
3150 SetCursor(Int_t(wid), kPointer);
3151}
3152
3153//______________________________________________________________________________
3155{
3156 // Returns the pointer position.
3157
3158 //I ignore fSelectedDrawable here. If you have any problems with this, hehe, you can ask me :)
3159 const NSPoint screenPoint = [NSEvent mouseLocation];
3160 x = X11::GlobalXCocoaToROOT(screenPoint.x);
3161 y = X11::GlobalYCocoaToROOT(screenPoint.y);
3162}
3163
3164//______________________________________________________________________________
3165void TGCocoa::QueryPointer(Window_t winID, Window_t &rootWinID, Window_t &childWinID,
3166 Int_t &rootX, Int_t &rootY, Int_t &winX, Int_t &winY, UInt_t &mask)
3167{
3168 //Emulate XQueryPointer.
3169
3170 //From TGX11/TGWin32:
3171 if (!winID)
3172 return;//Neither TGX11, nor TGWin32 set any of out parameters.
3173
3174 //We have only one root window.
3175 rootWinID = fPimpl->GetRootWindowID();
3176 //Find cursor position (screen coordinates).
3177 NSPoint screenPoint = [NSEvent mouseLocation];
3178 screenPoint.x = X11::GlobalXCocoaToROOT(screenPoint.x);
3179 screenPoint.y = X11::GlobalYCocoaToROOT(screenPoint.y);
3180 rootX = screenPoint.x;
3181 rootY = screenPoint.y;
3182
3183 //Convert a screen point to winID's coordinate system.
3184 if (winID > fPimpl->GetRootWindowID()) {
3185 NSObject<X11Window> * const window = fPimpl->GetWindow(winID);
3186 const NSPoint winPoint = X11::TranslateFromScreen(screenPoint, window.fContentView);
3187 winX = winPoint.x;
3188 winY = winPoint.y;
3189 } else {
3190 winX = screenPoint.x;
3191 winY = screenPoint.y;
3192 }
3193
3194 //Find child window in these coordinates (?).
3195 if (QuartzWindow * const childWin = X11::FindWindowInPoint(screenPoint.x, screenPoint.y)) {
3196 childWinID = childWin.fID;
3197 mask = X11::GetModifiers();
3198 } else {
3199 childWinID = 0;
3200 mask = 0;
3201 }
3202}
3203
3204#pragma mark - OpenGL management.
3205
3206//______________________________________________________________________________
3208{
3209 //Scaling factor to let our OpenGL code know, that we probably
3210 //work on a retina display.
3211
3212 return [[NSScreen mainScreen] backingScaleFactor];
3213}
3214
3215//______________________________________________________________________________
3217 const std::vector<std::pair<UInt_t, Int_t> > &formatComponents)
3218{
3219 //ROOT never creates GL widgets with 'root' as a parent (so not top-level gl-windows).
3220 //If this change, assert must be deleted.
3221 typedef std::pair<UInt_t, Int_t> component_type;
3222 typedef std::vector<component_type>::size_type size_type;
3223
3224 //Convert pairs into Cocoa's GL attributes.
3225 std::vector<NSOpenGLPixelFormatAttribute> attribs;
3226 for (size_type i = 0, e = formatComponents.size(); i < e; ++i) {
3227 const component_type &comp = formatComponents[i];
3228
3229 if (comp.first == Rgl::kDoubleBuffer) {
3230 attribs.push_back(NSOpenGLPFADoubleBuffer);
3231 } else if (comp.first == Rgl::kDepth) {
3232 attribs.push_back(NSOpenGLPFADepthSize);
3233 attribs.push_back(comp.second > 0 ? comp.second : 32);
3234 } else if (comp.first == Rgl::kAccum) {
3235 attribs.push_back(NSOpenGLPFAAccumSize);
3236 attribs.push_back(comp.second > 0 ? comp.second : 1);
3237 } else if (comp.first == Rgl::kStencil) {
3238 attribs.push_back(NSOpenGLPFAStencilSize);
3239 attribs.push_back(comp.second > 0 ? comp.second : 8);
3240 } else if (comp.first == Rgl::kMultiSample) {
3241 attribs.push_back(NSOpenGLPFAMultisample);
3242 attribs.push_back(NSOpenGLPFASampleBuffers);
3243 attribs.push_back(1);
3244 attribs.push_back(NSOpenGLPFASamples);
3245 attribs.push_back(comp.second ? comp.second : 8);
3246 }
3247 }
3248
3249 attribs.push_back(0);
3250
3251 NSOpenGLPixelFormat * const pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes : &attribs[0]];
3252 const Util::NSScopeGuard<NSOpenGLPixelFormat> formatGuard(pixelFormat);
3253
3254 NSView<X11Window> *parentView = nil;
3255 if (!fPimpl->IsRootWindow(parentID)) {
3256 parentView = fPimpl->GetWindow(parentID).fContentView;
3257 assert([parentView isKindOfClass : [QuartzView class]] &&
3258 "CreateOpenGLWindow, parent view must be QuartzView");
3259 }
3260
3261 NSRect viewFrame = {};
3262 viewFrame.size.width = width;
3263 viewFrame.size.height = height;
3264
3265 ROOTOpenGLView * const glView = [[ROOTOpenGLView alloc] initWithFrame : viewFrame pixelFormat : pixelFormat];
3266 const Util::NSScopeGuard<ROOTOpenGLView> viewGuard(glView);
3267
3268 Window_t glID = kNone;
3269
3270 if (parentView) {
3271 [parentView addChild : glView];
3272 glID = fPimpl->RegisterDrawable(glView);
3273 glView.fID = glID;
3274 } else {
3275 //"top-level glview".
3276 //Create a window to be parent of this gl-view.
3277 QuartzWindow *parent = [[QuartzWindow alloc] initWithGLView : glView];
3278 const Util::NSScopeGuard<QuartzWindow> winGuard(parent);
3279
3280
3281 if (!parent) {
3282 Error("CreateOpenGLWindow", "QuartzWindow allocation/initialization"
3283 " failed for a top-level GL widget");
3284 return kNone;
3285 }
3286
3287 glID = fPimpl->RegisterDrawable(parent);
3288 parent.fID = glID;
3289 }
3290
3291 return glID;
3292}
3293
3294//______________________________________________________________________________
3296{
3297 assert(!fPimpl->IsRootWindow(windowID) &&
3298 "CreateOpenGLContext, parameter 'windowID' is a root window");
3299 assert([fPimpl->GetWindow(windowID).fContentView isKindOfClass : [ROOTOpenGLView class]] &&
3300 "CreateOpenGLContext, view is not an OpenGL view");
3301
3302 NSOpenGLContext * const sharedContext = fPimpl->GetGLContextForHandle(sharedID);
3303 ROOTOpenGLView * const glView = (ROOTOpenGLView *)fPimpl->GetWindow(windowID);
3304
3306 newContext([[NSOpenGLContext alloc] initWithFormat : glView.pixelFormat shareContext : sharedContext]);
3307 glView.fOpenGLContext = newContext.Get();
3308 const Handle_t ctxID = fPimpl->RegisterGLContext(newContext.Get());
3309
3310 return ctxID;
3311}
3312
3313//______________________________________________________________________________
3315{
3316 // Creates OpenGL context for window "wid"
3317}
3318
3319//______________________________________________________________________________
3321{
3322 using namespace Details;
3323
3324 assert(ctxID > 0 && "MakeOpenGLContextCurrent, invalid context id");
3325
3326 NSOpenGLContext * const glContext = fPimpl->GetGLContextForHandle(ctxID);
3327 if (!glContext) {
3328 Error("MakeOpenGLContextCurrent", "No OpenGL context found for id %d", int(ctxID));
3329
3330 return kFALSE;
3331 }
3332
3333 ROOTOpenGLView * const glView = (ROOTOpenGLView *)fPimpl->GetWindow(windowID).fContentView;
3334
3335 if (OpenGL::GLViewIsValidDrawable(glView)) {
3336 if ([glContext view] != glView)
3337 [glContext setView : glView];
3338
3339 if (glView.fUpdateContext) {
3340 [glContext update];
3341 glView.fUpdateContext = NO;
3342 }
3343
3344 glView.fOpenGLContext = glContext;
3345 [glContext makeCurrentContext];
3346
3347 return kTRUE;
3348 } else {
3349 //Oh, here's the real black magic.
3350 //Our brilliant GL code is sure that MakeCurrent always succeeds.
3351 //But it does not: if view is not visible, context can not be attached,
3352 //gl operations will fail.
3353 //Funny enough, but if you have invisible window with visible view,
3354 //this trick works.
3355
3356 NSView *fakeView = nil;
3357 QuartzWindow *fakeWindow = fPimpl->GetFakeGLWindow();
3358
3359 if (!fakeWindow) {
3360 //We did not find any window. Create a new one.
3361 SetWindowAttributes_t attr = {};
3362 //100 - is just a stupid hardcoded value:
3363 const UInt_t width = std::max(glView.frame.size.width, CGFloat(100));
3364 const UInt_t height = std::max(glView.frame.size.height, CGFloat(100));
3365
3366 NSRect viewFrame = {};
3367 viewFrame.size.width = width;
3368 viewFrame.size.height = height;
3369
3370 const NSUInteger styleMask = kTitledWindowMask | kClosableWindowMask |
3372
3373 //NOTE: defer parameter is 'NO', otherwise this trick will not help.
3374 fakeWindow = [[QuartzWindow alloc] initWithContentRect : viewFrame styleMask : styleMask
3375 backing : NSBackingStoreBuffered defer : NO windowAttributes : &attr];
3376 Util::NSScopeGuard<QuartzWindow> winGuard(fakeWindow);
3377
3378 fakeView = fakeWindow.fContentView;
3379 [fakeView setHidden : NO];//!
3380
3381 fPimpl->SetFakeGLWindow(fakeWindow);//Can throw.
3382 winGuard.Release();
3383 } else {
3384 fakeView = fakeWindow.fContentView;
3385 [fakeView setHidden : NO];
3386 }
3387
3388 glView.fOpenGLContext = nil;
3389 [glContext setView : fakeView];
3390 [glContext makeCurrentContext];
3391 }
3392
3393 return kTRUE;
3394}
3395
3396//______________________________________________________________________________
3398{
3399 NSOpenGLContext * const currentContext = [NSOpenGLContext currentContext];
3400 if (!currentContext) {
3401 Error("GetCurrentOpenGLContext", "The current OpenGL context is null");
3402 return kNone;
3403 }
3404
3405 const Handle_t contextID = fPimpl->GetHandleForGLContext(currentContext);
3406 if (!contextID)
3407 Error("GetCurrentOpenGLContext", "The current OpenGL context was"
3408 " not created/registered by TGCocoa");
3409
3410 return contextID;
3411}
3412
3413//______________________________________________________________________________
3415{
3416 assert(ctxID > 0 && "FlushOpenGLBuffer, invalid context id");
3417
3418 NSOpenGLContext * const glContext = fPimpl->GetGLContextForHandle(ctxID);
3419 assert(glContext != nil && "FlushOpenGLBuffer, bad context id");
3420
3421 if (glContext != [NSOpenGLContext currentContext])//???
3422 return;
3423
3424 glFlush();//???
3425 [glContext flushBuffer];
3426}
3427
3428//______________________________________________________________________________
3430{
3431 //Historically, DeleteOpenGLContext was accepting window id,
3432 //now it's a context id. DeleteOpenGLContext is not used in ROOT,
3433 //only in TGLContext for Cocoa.
3434 NSOpenGLContext * const glContext = fPimpl->GetGLContextForHandle(ctxID);
3435 if (NSView * const v = [glContext view]) {
3436 if ([v isKindOfClass : [ROOTOpenGLView class]])
3437 ((ROOTOpenGLView *)v).fOpenGLContext = nil;
3438
3439 [glContext clearDrawable];
3440 }
3441
3442 if (glContext == [NSOpenGLContext currentContext])
3443 [NSOpenGLContext clearCurrentContext];
3444
3445 fPimpl->DeleteGLContext(ctxID);
3446}
3447
3448#pragma mark - Off-screen rendering for TPad/TCanvas.
3449
3450//______________________________________________________________________________
3452{
3453 //In ROOT, canvas has a "double buffer" - pixmap attached to 'wid'.
3454 assert(windowID > (Int_t)fPimpl->GetRootWindowID() && "SetDoubleBuffer called for root window");
3455
3456 if (windowID == 999) {//Comment in TVirtaulX suggests, that 999 means all windows.
3457 Warning("SetDoubleBuffer", "called with wid == 999");
3458 //Window with id 999 can not exists - this is checked in CocoaPrivate.
3459 } else {
3460 fSelectedDrawable = windowID;
3462 }
3463}
3464
3465//______________________________________________________________________________
3467{
3468 fDirectDraw = true;
3469}
3470
3471//______________________________________________________________________________
3473{
3474 //Attach pixmap to the selected window (view).
3475 fDirectDraw = false;
3476
3477 assert(fSelectedDrawable > fPimpl->GetRootWindowID() &&
3478 "SetDoubleBufferON, called, but no correct window was selected before");
3479
3480 NSObject<X11Window> * const window = fPimpl->GetWindow(fSelectedDrawable);
3481
3482 assert(window.fIsPixmap == NO &&
3483 "SetDoubleBufferON, selected drawable is a pixmap, can not attach pixmap to pixmap");
3484
3485 const unsigned currW = window.fWidth;
3486 const unsigned currH = window.fHeight;
3487
3488 if (QuartzPixmap *const currentPixmap = window.fBackBuffer) {
3489 if (currH == currentPixmap.fHeight && currW == currentPixmap.fWidth)
3490 return;
3491 }
3492
3493 Util::NSScopeGuard<QuartzPixmap> pixmap([[QuartzPixmap alloc] initWithW : currW
3494 H : currH scaleFactor : [[NSScreen mainScreen] backingScaleFactor]]);
3495 if (pixmap.Get())
3496 window.fBackBuffer = pixmap.Get();
3497 else
3498 //Detailed error message was issued by QuartzPixmap.
3499 Error("SetDoubleBufferON", "QuartzPixmap initialization failed");
3500}
3501
3502//______________________________________________________________________________
3504{
3505 // Sets the drawing mode.
3506 //
3507 //EDrawMode{kCopy, kXor};
3508 fDrawMode = mode;
3509}
3510
3511#pragma mark - Event management part.
3512
3513//______________________________________________________________________________
3515{
3516 if (fPimpl->IsRootWindow(wid))//ROOT's GUI can send events to root window.
3517 return;
3518
3519 //From TGX11:
3520 if (!wid || !event)
3521 return;
3522
3523 Event_t newEvent = *event;
3524 newEvent.fWindow = wid;
3525 fPimpl->fX11EventTranslator.fEventQueue.push_back(newEvent);
3526}
3527
3528//______________________________________________________________________________
3530{
3531 assert(fPimpl->fX11EventTranslator.fEventQueue.size() > 0 && "NextEvent, event queue is empty");
3532
3533 event = fPimpl->fX11EventTranslator.fEventQueue.front();
3534 fPimpl->fX11EventTranslator.fEventQueue.pop_front();
3535}
3536
3537//______________________________________________________________________________
3539{
3540 return (Int_t)fPimpl->fX11EventTranslator.fEventQueue.size();
3541}
3542
3543
3544//______________________________________________________________________________
3546{
3547 typedef X11::EventQueue_t::iterator iterator_type;
3548
3549 iterator_type it = fPimpl->fX11EventTranslator.fEventQueue.begin();
3550 iterator_type eIt = fPimpl->fX11EventTranslator.fEventQueue.end();
3551
3552 for (; it != eIt; ++it) {
3553 const Event_t &queuedEvent = *it;
3554 if (queuedEvent.fWindow == windowID && queuedEvent.fType == type) {
3555 event = queuedEvent;
3556 fPimpl->fX11EventTranslator.fEventQueue.erase(it);
3557 return kTRUE;
3558 }
3559 }
3560
3561 return kFALSE;
3562}
3563
3564//______________________________________________________________________________
3566{
3567 //I can not give an access to the native event,
3568 //it even, probably, does not exist already.
3569 return kNone;
3570}
3571
3572#pragma mark - "Drag and drop", "Copy and paste", X11 properties.
3573
3574//______________________________________________________________________________
3575Atom_t TGCocoa::InternAtom(const char *name, Bool_t onlyIfExist)
3576{
3577 //X11 properties emulation.
3578
3579 assert(name != 0 && "InternAtom, parameter 'name' is null");
3580 return FindAtom(name, !onlyIfExist);
3581}
3582
3583//______________________________________________________________________________
3585{
3586 //Comment from TVirtualX:
3587 // Makes the window "wid" the current owner of the primary selection.
3588 // That is the window in which, for example some text is selected.
3589 //End of comment.
3590
3591 //It's not clear, why SetPrimarySelectionOwner and SetSelectionOwner have different return types.
3592
3593 if (!windowID)//From TGWin32.
3594 return;
3595
3596 assert(!fPimpl->IsRootWindow(windowID) &&
3597 "SetPrimarySelectionOwner, windowID parameter is a 'root' window");
3598 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3599 "SetPrimarySelectionOwner, windowID parameter is not a valid window");
3600
3601 const Atom_t primarySelectionAtom = FindAtom("XA_PRIMARY", false);
3602 assert(primarySelectionAtom != kNone &&
3603 "SetPrimarySelectionOwner, predefined XA_PRIMARY atom was not found");
3604
3605 fSelectionOwners[primarySelectionAtom] = windowID;
3606 //No events will be send - I do not have different clients, so nobody to send SelectionClear.
3607}
3608
3609//______________________________________________________________________________
3611{
3612 //Comment from TVirtualX:
3613 // Changes the owner and last-change time for the specified selection.
3614 //End of comment.
3615
3616 //It's not clear, why SetPrimarySelectionOwner and SetSelectionOwner have different return types.
3617
3618 if (!windowID)
3619 return kFALSE;
3620
3621 assert(!fPimpl->IsRootWindow(windowID) &&
3622 "SetSelectionOwner, windowID parameter is a 'root' window'");
3623 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3624 "SetSelectionOwner, windowID parameter is not a valid window");
3625
3626 fSelectionOwners[selection] = windowID;
3627 //No messages, since I do not have different clients.
3628
3629 return kTRUE;
3630}
3631
3632//______________________________________________________________________________
3634{
3635 //Comment from TVirtualX:
3636 // Returns the window id of the current owner of the primary selection.
3637 // That is the window in which, for example some text is selected.
3638 //End of comment.
3639 const Atom_t primarySelectionAtom = FindAtom("XA_PRIMARY", false);
3640 assert(primarySelectionAtom != kNone &&
3641 "GetPrimarySelectionOwner, predefined XA_PRIMARY atom was not found");
3642
3643 return fSelectionOwners[primarySelectionAtom];
3644}
3645
3646//______________________________________________________________________________
3648{
3649 //Comment from TVirtualX:
3650 // Causes a SelectionRequest event to be sent to the current primary
3651 // selection owner. This event specifies the selection property
3652 // (primary selection), the format into which to convert that data before
3653 // storing it (target = XA_STRING), the property in which the owner will
3654 // place the information (sel_property), the window that wants the
3655 // information (id), and the time of the conversion request (when).
3656 // The selection owner responds by sending a SelectionNotify event, which
3657 // confirms the selected atom and type.
3658 //End of comment.
3659
3660 //From TGWin32:
3661 if (!windowID)
3662 return;
3663
3664 assert(!fPimpl->IsRootWindow(windowID) &&
3665 "ConvertPrimarySelection, parameter 'windowID' is root window");
3666 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3667 "ConvertPrimarySelection, parameter windowID parameter is not a window id");
3668
3669 Atom_t primarySelectionAtom = FindAtom("XA_PRIMARY", false);
3670 assert(primarySelectionAtom != kNone &&
3671 "ConvertPrimarySelection, XA_PRIMARY predefined atom not found");
3672
3673 Atom_t stringAtom = FindAtom("XA_STRING", false);
3674 assert(stringAtom != kNone &&
3675 "ConvertPrimarySelection, XA_STRING predefined atom not found");
3676
3677 ConvertSelection(windowID, primarySelectionAtom, stringAtom, clipboard, when);
3678}
3679
3680//______________________________________________________________________________
3681void TGCocoa::ConvertSelection(Window_t windowID, Atom_t &selection, Atom_t &target,
3682 Atom_t &property, Time_t &/*timeStamp*/)
3683{
3684 // Requests that the specified selection be converted to the specified
3685 // target type.
3686
3687 // Requests that the specified selection be converted to the specified
3688 // target type.
3689
3690 if (!windowID)
3691 return;
3692
3693 assert(!fPimpl->IsRootWindow(windowID) &&
3694 "ConvertSelection, parameter 'windowID' is root window'");
3695 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3696 "ConvertSelection, parameter 'windowID' is not a window id");
3697
3698 Event_t newEvent = {};
3699 selection_iterator selIter = fSelectionOwners.find(selection);
3700
3701 if (selIter != fSelectionOwners.end())
3702 newEvent.fType = kSelectionRequest;
3703 else
3704 newEvent.fType = kSelectionNotify;
3705
3706 newEvent.fWindow = windowID;
3707 newEvent.fUser[0] = windowID;//requestor
3708 newEvent.fUser[1] = selection;
3709 newEvent.fUser[2] = target;
3710 newEvent.fUser[3] = property;
3711
3712 SendEvent(windowID, &newEvent);
3713}
3714
3715//______________________________________________________________________________
3717 Atom_t *actualType, Int_t *actualFormat, ULong_t *nItems,
3718 ULong_t *bytesAfterReturn, unsigned char **propertyReturn)
3719{
3720 //Comment from TVirtualX:
3721 // Returns the actual type of the property; the actual format of the property;
3722 // the number of 8-bit, 16-bit, or 32-bit items transferred; the number of
3723 // bytes remaining to be read in the property; and a pointer to the data
3724 // actually returned.
3725 //End of comment.
3726
3727 if (fPimpl->IsRootWindow(windowID))
3728 return 0;
3729
3730 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3731 "GetProperty, parameter 'windowID' is not a valid window id");
3732 assert(propertyID > 0 && propertyID <= fAtomToName.size() &&
3733 "GetProperty, parameter 'propertyID' is not a valid atom");
3734 assert(actualType != 0 && "GetProperty, parameter 'actualType' is null");
3735 assert(actualFormat != 0 && "GetProperty, parameter 'actualFormat' is null");
3736 assert(bytesAfterReturn != 0 && "GetProperty, parameter 'bytesAfterReturn' is null");
3737 assert(propertyReturn != 0 && "GetProperty, parameter 'propertyReturn' is null");
3738
3739 const Util::AutoreleasePool pool;
3740
3741 *bytesAfterReturn = 0;//In TGWin32 the value set to .. nItems?
3742 *propertyReturn = 0;
3743 *nItems = 0;
3744
3745 const std::string &atomName = fAtomToName[propertyID - 1];
3746 NSObject<X11Window> *window = fPimpl->GetWindow(windowID);
3747
3748 if (![window hasProperty : atomName.c_str()]) {
3749 Error("GetProperty", "Unknown property %s requested", atomName.c_str());
3750 return 0;//actually, 0 is ... Success (X11)?
3751 }
3752
3753 unsigned tmpFormat = 0, tmpElements = 0;
3754 *propertyReturn = [window getProperty : atomName.c_str() returnType : actualType
3755 returnFormat : &tmpFormat nElements : &tmpElements];
3756 *actualFormat = (Int_t)tmpFormat;
3757 *nItems = tmpElements;
3758
3759 return *nItems;//Success (X11) is 0?
3760}
3761
3762//______________________________________________________________________________
3764 Int_t &nChars, Bool_t clearBuffer)
3765{
3766 //Comment from TVirtualX:
3767 // Gets contents of the paste buffer "atom" into the string "text".
3768 // (nchar = number of characters) If "del" is true deletes the paste
3769 // buffer afterwards.
3770 //End of comment.
3771
3772 //From TGX11:
3773 if (!windowID)
3774 return;
3775
3776 assert(!fPimpl->IsRootWindow(windowID) &&
3777 "GetPasteBuffer, parameter 'windowID' is root window");
3778 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3779 "GetPasteBuffer, parameter 'windowID' is not a valid window");
3780 assert(propertyID && propertyID <= fAtomToName.size() &&
3781 "GetPasteBuffer, parameter 'propertyID' is not a valid atom");
3782
3783 const Util::AutoreleasePool pool;
3784
3785 const std::string &atomString = fAtomToName[propertyID - 1];
3786 NSObject<X11Window> *window = fPimpl->GetWindow(windowID);
3787
3788 if (![window hasProperty : atomString.c_str()]) {
3789 Error("GetPasteBuffer", "No property %s on a window", atomString.c_str());
3790 return;
3791 }
3792
3793 Atom_t tmpType = 0;
3794 unsigned tmpFormat = 0, nElements = 0;
3795
3797 propertyData((char *)[window getProperty : atomString.c_str()
3798 returnType : &tmpType returnFormat : &tmpFormat
3799 nElements : &nElements]);
3800
3801 assert(tmpFormat == 8 && "GetPasteBuffer, property has wrong format");
3802
3803 text.Insert(0, propertyData.Get(), nElements);
3804 nChars = (Int_t)nElements;
3805
3806 if (clearBuffer) {
3807 //For the moment - just remove the property
3808 //(anyway, ChangeProperty/ChangeProperties will re-create it).
3809 [window removeProperty : atomString.c_str()];
3810 }
3811}
3812
3813//______________________________________________________________________________
3815 UChar_t *data, Int_t len)
3816{
3817 //Comment from TVirtualX:
3818 // Alters the property for the specified window and causes the X server
3819 // to generate a PropertyNotify event on that window.
3820 //
3821 // wid - the window whose property you want to change
3822 // property - specifies the property name
3823 // type - the type of the property; the X server does not
3824 // interpret the type but simply passes it back to
3825 // an application that might ask about the window
3826 // properties
3827 // data - the property data
3828 // len - the length of the specified data format
3829 //End of comment.
3830
3831 //TGX11 always calls XChangeProperty with PropModeReplace.
3832 //I simply reset the property (or create a new one).
3833
3834 if (!windowID) //From TGWin32.
3835 return;
3836
3837 if (!data || !len) //From TGWin32.
3838 return;
3839
3840 assert(!fPimpl->IsRootWindow(windowID) &&
3841 "ChangeProperty, parameter 'windowID' is root window");
3842 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3843 "ChangeProperty, parameter 'windowID' is not a valid window id");
3844 assert(propertyID && propertyID <= fAtomToName.size() &&
3845 "ChangeProperty, parameter 'propertyID' is not a valid atom");
3846
3847 const Util::AutoreleasePool pool;
3848
3849 const std::string &atomString = fAtomToName[propertyID - 1];
3850
3851 NSObject<X11Window> * const window = fPimpl->GetWindow(windowID);
3852 [window setProperty : atomString.c_str() data : data size : len forType : type format : 8];
3853 //ROOT ignores PropertyNotify events.
3854}
3855
3856//______________________________________________________________________________
3858 Int_t format, UChar_t *data, Int_t len)
3859{
3860 //Comment from TVirtualX:
3861 // Alters the property for the specified window and causes the X server
3862 // to generate a PropertyNotify event on that window.
3863 //End of comment.
3864
3865 //TGX11 always calls XChangeProperty with PropModeReplace.
3866 //I simply reset the property (or create a new one).
3867
3868 if (!windowID)//From TGWin32.
3869 return;
3870
3871 if (!data || !len)//From TGWin32.
3872 return;
3873
3874 assert(!fPimpl->IsRootWindow(windowID) &&
3875 "ChangeProperties, parameter 'windowID' is root window");
3876 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3877 "ChangeProperties, parameter 'windowID' is not a valid window id");
3878 assert(propertyID && propertyID <= fAtomToName.size() &&
3879 "ChangeProperties, parameter 'propertyID' is not a valid atom");
3880
3881 const Util::AutoreleasePool pool;
3882
3883 const std::string &atomName = fAtomToName[propertyID - 1];
3884
3885 NSObject<X11Window> * const window = fPimpl->GetWindow(windowID);
3886 [window setProperty : atomName.c_str() data : data
3887 size : len forType : type format : format];
3888 //No property notify, ROOT does not know about this.
3889}
3890
3891//______________________________________________________________________________
3892void TGCocoa::DeleteProperty(Window_t windowID, Atom_t &propertyID)
3893{
3894 //Comment from TVirtualX:
3895 // Deletes the specified property only if the property was defined on the
3896 // specified window and causes the X server to generate a PropertyNotify
3897 // event on the window unless the property does not exist.
3898 //End of comment.
3899
3900 if (!windowID)//Can this happen?
3901 return;
3902
3903 //Strange signature - why propertyID is a reference?
3904 assert(!fPimpl->IsRootWindow(windowID) &&
3905 "DeleteProperty, parameter 'windowID' is root window");
3906 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3907 "DeleteProperty, parameter 'windowID' is not a valid window");
3908 assert(propertyID && propertyID <= fAtomToName.size() &&
3909 "DeleteProperty, parameter 'propertyID' is not a valid atom");
3910
3911 const std::string &atomString = fAtomToName[propertyID - 1];
3912 [fPimpl->GetWindow(windowID) removeProperty : atomString.c_str()];
3913}
3914
3915//______________________________________________________________________________
3916void TGCocoa::SetDNDAware(Window_t windowID, Atom_t *typeList)
3917{
3918 //Comment from TVirtaulX:
3919 // Add XdndAware property and the list of drag and drop types to the
3920 // Window win.
3921 //End of comment.
3922
3923
3924 //TGX11 first replaces XdndAware property for a windowID, and then appends atoms from a typelist.
3925 //I simply put all data for a property into a vector and set the property (either creating
3926 //a new property or replacing the existing).
3927
3928 assert(windowID > fPimpl->GetRootWindowID() &&
3929 "SetDNDAware, parameter 'windowID' is not a valid window id");
3930 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3931 "SetDNDAware, parameter 'windowID' is not a window");
3932
3933 const Util::AutoreleasePool pool;
3934
3935 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(windowID).fContentView;
3936 NSArray * const supportedTypes = [NSArray arrayWithObjects : NSFilenamesPboardType, nil];//In a pool.
3937
3938 //Do this for Cocoa - to make it possible to drag something to a
3939 //ROOT's window (also this will change cursor shape while dragging).
3940 [view registerForDraggedTypes : supportedTypes];
3941 //Declared property - for convenience, not to check atoms/shmatoms or X11 properties.
3942 view.fIsDNDAware = YES;
3943
3944 FindAtom("XdndAware", true);//Add it, if not yet.
3945 const Atom_t xaAtomAtom = FindAtom("XA_ATOM", false);
3946
3947 assert(xaAtomAtom == 4 && "SetDNDAware, XA_ATOM is not defined");//This is a predefined atom.
3948
3949 //ROOT's GUI uses Atom_t, which is unsigned long, and it's 64-bit.
3950 //While calling XChangeProperty, it passes the address of this typelist
3951 //and format is ... 32. I have to pack data into unsigned and force the size:
3952 assert(sizeof(unsigned) == 4 && "SetDNDAware, sizeof(unsigned) must be 4");
3953
3954 std::vector<unsigned> propertyData;
3955 propertyData.push_back(4);//This '4' is from TGX11 (is it XA_ATOM???)
3956
3957 if (typeList) {
3958 for (unsigned i = 0; typeList[i]; ++i)
3959 propertyData.push_back(unsigned(typeList[i]));//hehe.
3960 }
3961
3962 [view setProperty : "XdndAware" data : (unsigned char *)&propertyData[0]
3963 size : propertyData.size() forType : xaAtomAtom format : 32];
3964}
3965
3966//______________________________________________________________________________
3968{
3969 //Checks if the Window is DND aware. typeList is ignored.
3970
3971 if (windowID <= fPimpl->GetRootWindowID())//kNone or root.
3972 return kFALSE;
3973
3974 assert(fPimpl->GetDrawable(windowID).fIsPixmap == NO &&
3975 "IsDNDAware, windowID parameter is not a window");
3976
3977 QuartzView * const view = (QuartzView *)fPimpl->GetWindow(windowID).fContentView;
3978 return view.fIsDNDAware;
3979}
3980
3981//______________________________________________________________________________
3983{
3984 // Add the list of drag and drop types to the Window win.
3985 //It's never called from GUI.
3986 ::Warning("SetTypeList", "Not implemented");
3987}
3988
3989//______________________________________________________________________________
3990Window_t TGCocoa::FindRWindow(Window_t winID, Window_t dragWinID, Window_t inputWinID, int x, int y, int maxDepth)
3991{
3992 //Comment from TVirtualX:
3993
3994 // Recursively search in the children of Window for a Window which is at
3995 // location x, y and is DND aware, with a maximum depth of maxd.
3996 // Ignore dragwin and input (???)
3997 //End of comment from TVirtualX.
3998
3999
4000 //Now my comments. The name of this function, as usually, says nothing about what it does.
4001 //It's searching for some window, probably child of winID, or may be winID itself(?) and
4002 //window must be DND aware. So the name should be FindDNDAwareWindowRecursively or something like this.
4003
4004 //This function is not documented, comments suck as soon as they are simply wrong - the
4005 //first return statement in X11 version contradicts with comments
4006 //about child. Since X11 version is more readable, I'm reproducing X11 version here,
4007 //and ... my code can't be wrong, since there is nothing right about this function.
4008
4009 NSView<X11Window> * const testView = X11::FindDNDAwareViewInPoint(
4010 fPimpl->IsRootWindow(winID) ? nil : fPimpl->GetWindow(winID).fContentView,
4011 dragWinID, inputWinID, x, y, maxDepth);
4012 if (testView)
4013 return testView.fID;
4014
4015 return kNone;
4016}
4017
4018#pragma mark - Noops.
4019
4020//______________________________________________________________________________
4021UInt_t TGCocoa::ExecCommand(TGWin32Command * /*code*/)
4022{
4023 // Executes the command "code" coming from the other threads (Win32)
4024 return 0;
4025}
4026
4027//______________________________________________________________________________
4029{
4030 // Queries the double buffer value for the window "wid".
4031 return 0;
4032}
4033
4034//______________________________________________________________________________
4036{
4037 // Returns character up vector.
4038 chupx = chupy = 0.f;
4039}
4040
4041//______________________________________________________________________________
4042Pixmap_t TGCocoa::ReadGIF(Int_t /*x0*/, Int_t /*y0*/, const char * /*file*/, Window_t /*id*/)
4043{
4044 // If id is NULL - loads the specified gif file at position [x0,y0] in the
4045 // current window. Otherwise creates pixmap from gif file
4046
4047 return kNone;
4048}
4049
4050//______________________________________________________________________________
4051Int_t TGCocoa::RequestLocator(Int_t /*mode*/, Int_t /*ctyp*/, Int_t &/*x*/, Int_t &/*y*/)
4052{
4053 // Requests Locator position.
4054 // x,y - cursor position at moment of button press (output)
4055 // ctyp - cursor type (input)
4056 // ctyp = 1 tracking cross
4057 // ctyp = 2 cross-hair
4058 // ctyp = 3 rubber circle
4059 // ctyp = 4 rubber band
4060 // ctyp = 5 rubber rectangle
4061 //
4062 // mode - input mode
4063 // mode = 0 request
4064 // mode = 1 sample
4065 //
4066 // The returned value is:
4067 // in request mode:
4068 // 1 = left is pressed
4069 // 2 = middle is pressed
4070 // 3 = right is pressed
4071 // in sample mode:
4072 // 11 = left is released
4073 // 12 = middle is released
4074 // 13 = right is released
4075 // -1 = nothing is pressed or released
4076 // -2 = leave the window
4077 // else = keycode (keyboard is pressed)
4078
4079 return 0;
4080}
4081
4082//______________________________________________________________________________
4083Int_t TGCocoa::RequestString(Int_t /*x*/, Int_t /*y*/, char * /*text*/)
4084{
4085 // Requests string: text is displayed and can be edited with Emacs-like
4086 // keybinding. Returns termination code (0 for ESC, 1 for RETURN)
4087 //
4088 // x,y - position where text is displayed
4089 // text - displayed text (as input), edited text (as output)
4090 return 0;
4091}
4092
4093//______________________________________________________________________________
4094void TGCocoa::SetCharacterUp(Float_t /*chupx*/, Float_t /*chupy*/)
4095{
4096 // Sets character up vector.
4097}
4098
4099//______________________________________________________________________________
4101{
4102 // Turns off the clipping for the window "wid".
4103}
4104
4105//______________________________________________________________________________
4106void TGCocoa::SetClipRegion(Int_t /*wid*/, Int_t /*x*/, Int_t /*y*/, UInt_t /*w*/, UInt_t /*h*/)
4107{
4108 // Sets clipping region for the window "wid".
4109 //
4110 // wid - window indentifier
4111 // x, y - origin of clipping rectangle
4112 // w, h - the clipping rectangle dimensions
4113
4114}
4115
4116//______________________________________________________________________________
4118{
4119 // Sets the current text magnification factor to "mgn"
4120}
4121
4122//______________________________________________________________________________
4123void TGCocoa::Sync(Int_t /*mode*/)
4124{
4125 // Set synchronisation on or off.
4126 // mode : synchronisation on/off
4127 // mode=1 on
4128 // mode<>0 off
4129}
4130
4131//______________________________________________________________________________
4133{
4134 // Sets the pointer position.
4135 // ix - new X coordinate of pointer
4136 // iy - new Y coordinate of pointer
4137 // Coordinates are relative to the origin of the window id
4138 // or to the origin of the current window if id == 0.
4139
4140 if (!winID)
4141 return;
4142
4143 NSPoint newCursorPosition = {};
4144 newCursorPosition.x = ix;
4145 newCursorPosition.y = iy;
4146
4147 if (fPimpl->GetRootWindowID() == winID) {
4148 //Suddenly .... top-left - based!
4149 newCursorPosition.x = X11::GlobalXROOTToCocoa(newCursorPosition.x);
4150 } else {
4151 assert(fPimpl->GetDrawable(winID).fIsPixmap == NO &&
4152 "Warp, drawable is not a window");
4153 newCursorPosition = X11::TranslateToScreen(fPimpl->GetWindow(winID).fContentView,
4154 newCursorPosition);
4155 }
4156
4157 CGWarpMouseCursorPosition(NSPointToCGPoint(newCursorPosition));
4158}
4159
4160//______________________________________________________________________________
4161Int_t TGCocoa::WriteGIF(char * /*name*/)
4162{
4163 // Writes the current window into GIF file.
4164 // Returns 1 in case of success, 0 otherwise.
4165
4166 return 0;
4167}
4168
4169//______________________________________________________________________________
4170void TGCocoa::WritePixmap(Int_t /*wid*/, UInt_t /*w*/, UInt_t /*h*/, char * /*pxname*/)
4171{
4172 // Writes the pixmap "wid" in the bitmap file "pxname".
4173 //
4174 // wid - the pixmap address
4175 // w, h - the width and height of the pixmap.
4176 // pxname - the file name
4177}
4178
4179//______________________________________________________________________________
4181{
4182 // Notify the low level GUI layer ROOT requires "tgwindow" to be
4183 // updated
4184 //
4185 // Returns kTRUE if the notification was desirable and it was sent
4186 //
4187 // At the moment only Qt4 layer needs that
4188 //
4189 // One needs explicitly cast the first parameter to TGWindow to make
4190 // it working in the implementation.
4191 //
4192 // One needs to process the notification to confine
4193 // all paint operations within "expose" / "paint" like low level event
4194 // or equivalent
4195
4196 return kFALSE;
4197}
4198
4199//______________________________________________________________________________
4201 const char * /*filename*/,
4202 Pixmap_t &/*pict*/,
4203 Pixmap_t &/*pict_mask*/,
4204 PictureAttributes_t &/*attr*/)
4205{
4206 // Creates a picture pict from data in file "filename". The picture
4207 // attributes "attr" are used for input and output. Returns kTRUE in
4208 // case of success, kFALSE otherwise. If the mask "pict_mask" does not
4209 // exist it is set to kNone.
4210
4211 return kFALSE;
4212}
4213
4214//______________________________________________________________________________
4216 Pixmap_t &/*pict*/,
4217 Pixmap_t &/*pict_mask*/,
4218 PictureAttributes_t & /*attr*/)
4219{
4220 // Creates a picture pict from data in bitmap format. The picture
4221 // attributes "attr" are used for input and output. Returns kTRUE in
4222 // case of success, kFALSE otherwise. If the mask "pict_mask" does not
4223 // exist it is set to kNone.
4224
4225 return kFALSE;
4226}
4227//______________________________________________________________________________
4228Bool_t TGCocoa::ReadPictureDataFromFile(const char * /*filename*/, char *** /*ret_data*/)
4229{
4230 // Reads picture data from file "filename" and store it in "ret_data".
4231 // Returns kTRUE in case of success, kFALSE otherwise.
4232
4233 return kFALSE;
4234}
4235
4236//______________________________________________________________________________
4237void TGCocoa::DeletePictureData(void * /*data*/)
4238{
4239 // Delete picture data created by the function ReadPictureDataFromFile.
4240}
4241
4242//______________________________________________________________________________
4243void TGCocoa::SetDashes(GContext_t /*gc*/, Int_t /*offset*/, const char * /*dash_list*/, Int_t /*n*/)
4244{
4245 // Sets the dash-offset and dash-list attributes for dashed line styles
4246 // in the specified GC. There must be at least one element in the
4247 // specified dash_list. The initial and alternating elements (second,
4248 // fourth, and so on) of the dash_list are the even dashes, and the
4249 // others are the odd dashes. Each element in the "dash_list" array
4250 // specifies the length (in pixels) of a segment of the pattern.
4251 //
4252 // gc - specifies the GC (see GCValues_t structure)
4253 // offset - the phase of the pattern for the dashed line-style you
4254 // want to set for the specified GC.
4255 // dash_list - the dash-list for the dashed line-style you want to set
4256 // for the specified GC
4257 // n - the number of elements in dash_list
4258 // (see also the GCValues_t structure)
4259}
4260
4261//______________________________________________________________________________
4262void TGCocoa::Bell(Int_t /*percent*/)
4263{
4264 // Sets the sound bell. Percent is loudness from -100% .. 100%.
4265}
4266
4267//______________________________________________________________________________
4269{
4270 // Tells WM to send message when window is closed via WM.
4271}
4272
4273//______________________________________________________________________________
4275 Rectangle_t * /*recs*/, Int_t /*n*/)
4276{
4277 // Sets clipping rectangles in graphics context. [x,y] specify the origin
4278 // of the rectangles. "recs" specifies an array of rectangles that define
4279 // the clipping mask and "n" is the number of rectangles.
4280 // (see also the GCValues_t structure)
4281}
4282
4283//______________________________________________________________________________
4285{
4286 // Creates a new empty region.
4287
4288 return 0;
4289}
4290
4291//______________________________________________________________________________
4293{
4294 // Destroys the region "reg".
4295}
4296
4297//______________________________________________________________________________
4299{
4300 // Updates the destination region from a union of the specified rectangle
4301 // and the specified source region.
4302 //
4303 // rect - specifies the rectangle
4304 // src - specifies the source region to be used
4305 // dest - returns the destination region
4306}
4307
4308//______________________________________________________________________________
4309Region_t TGCocoa::PolygonRegion(Point_t * /*points*/, Int_t /*np*/, Bool_t /*winding*/)
4310{
4311 // Returns a region for the polygon defined by the points array.
4312 //
4313 // points - specifies an array of points
4314 // np - specifies the number of points in the polygon
4315 // winding - specifies the winding-rule is set (kTRUE) or not(kFALSE)
4316
4317 return 0;
4318}
4319
4320//______________________________________________________________________________
4321void TGCocoa::UnionRegion(Region_t /*rega*/, Region_t /*regb*/, Region_t /*result*/)
4322{
4323 // Computes the union of two regions.
4324 //
4325 // rega, regb - specify the two regions with which you want to perform
4326 // the computation
4327 // result - returns the result of the computation
4328
4329}
4330
4331//______________________________________________________________________________
4332void TGCocoa::IntersectRegion(Region_t /*rega*/, Region_t /*regb*/, Region_t /*result*/)
4333{
4334 // Computes the intersection of two regions.
4335 //
4336 // rega, regb - specify the two regions with which you want to perform
4337 // the computation
4338 // result - returns the result of the computation
4339}
4340
4341//______________________________________________________________________________
4342void TGCocoa::SubtractRegion(Region_t /*rega*/, Region_t /*regb*/, Region_t /*result*/)
4343{
4344 // Subtracts regb from rega and stores the results in result.
4345}
4346
4347//______________________________________________________________________________
4348void TGCocoa::XorRegion(Region_t /*rega*/, Region_t /*regb*/, Region_t /*result*/)
4349{
4350 // Calculates the difference between the union and intersection of
4351 // two regions.
4352 //
4353 // rega, regb - specify the two regions with which you want to perform
4354 // the computation
4355 // result - returns the result of the computation
4356
4357}
4358
4359//______________________________________________________________________________
4361{
4362 // Returns kTRUE if the region reg is empty.
4363
4364 return kFALSE;
4365}
4366
4367//______________________________________________________________________________
4369{
4370 // Returns kTRUE if the point [x, y] is contained in the region reg.
4371
4372 return kFALSE;
4373}
4374
4375//______________________________________________________________________________
4377{
4378 // Returns kTRUE if the two regions have the same offset, size, and shape.
4379
4380 return kFALSE;
4381}
4382
4383//______________________________________________________________________________
4385{
4386 // Returns smallest enclosing rectangle.
4387}
4388
4389#pragma mark - Details and aux. functions.
4390
4391//______________________________________________________________________________
4393{
4394 return &fPimpl->fX11EventTranslator;
4395}
4396
4397//______________________________________________________________________________
4399{
4400 return &fPimpl->fX11CommandBuffer;
4401}
4402
4403//______________________________________________________________________________
4405{
4406 ++fCocoaDraw;
4407}
4408
4409//______________________________________________________________________________
4411{
4412 assert(fCocoaDraw > 0 && "CocoaDrawOFF, was already off");
4413 --fCocoaDraw;
4414}
4415
4416//______________________________________________________________________________
4418{
4419 return bool(fCocoaDraw);
4420}
4421
4422//______________________________________________________________________________
4424{
4425 NSObject<X11Drawable> * const drawable = fPimpl->GetDrawable(fSelectedDrawable);
4426 if (!drawable.fIsPixmap) {
4427 Error("GetCurrentContext", "TCanvas/TPad's internal error,"
4428 " selected drawable is not a pixmap!");
4429 return 0;
4430 }
4431
4432 return drawable.fContext;
4433}
4434
4435//______________________________________________________________________________
4437{
4438 //We start ROOT in a terminal window, so it's considered as a
4439 //background process. Background process has a lot of problems
4440 //if it tries to create and manage windows.
4441 //So, first time we convert process to foreground, next time
4442 //we make it front.
4443
4444 if (!fForegroundProcess) {
4445 ProcessSerialNumber psn = {0, kCurrentProcess};
4446
4447 const OSStatus res1 = TransformProcessType(&psn, kProcessTransformToForegroundApplication);
4448
4449 //When TGCocoa's functions are called from the python (Apple's system version),
4450 //TransformProcessType fails with paramErr (looks like process is _already_ foreground),
4451 //why is it a paramErr - I've no idea.
4452 if (res1 != noErr && res1 != paramErr) {
4453 Error("MakeProcessForeground", "TransformProcessType failed with code %d", int(res1));
4454 return false;
4455 }
4456#ifdef MAC_OS_X_VERSION_10_9
4457 //Instead of quite transparent Carbon calls we now have another black-box function.
4458 [[NSApplication sharedApplication] activateIgnoringOtherApps : YES];
4459#else
4460 const OSErr res2 = SetFrontProcess(&psn);
4461 if (res2 != noErr) {
4462 Error("MakeProcessForeground", "SetFrontProcess failed with code %d", res2);
4463 return false;
4464 }
4465#endif
4466
4467 fForegroundProcess = true;
4468 } else {
4469#ifdef MAC_OS_X_VERSION_10_9
4470 //Instead of quite transparent Carbon calls we now have another black-box function.
4471 [[NSApplication sharedApplication] activateIgnoringOtherApps : YES];
4472#else
4473 ProcessSerialNumber psn = {};
4474
4475 OSErr res = GetCurrentProcess(&psn);
4476 if (res != noErr) {
4477 Error("MakeProcessForeground", "GetCurrentProcess failed with code %d", res);
4478 return false;
4479 }
4480
4481 res = SetFrontProcess(&psn);
4482 if (res != noErr) {
4483 Error("MapProcessForeground", "SetFrontProcess failed with code %d", res);
4484 return false;
4485 }
4486#endif
4487 }
4488
4489 return true;
4490}
4491
4492//______________________________________________________________________________
4493Atom_t TGCocoa::FindAtom(const std::string &atomName, bool addIfNotFound)
4494{
4495 const std::map<std::string, Atom_t>::const_iterator it = fNameToAtom.find(atomName);
4496
4497 if (it != fNameToAtom.end())
4498 return it->second;
4499 else if (addIfNotFound) {
4500 //Create a new atom.
4501 fAtomToName.push_back(atomName);
4502 fNameToAtom[atomName] = Atom_t(fAtomToName.size());
4503
4504 return Atom_t(fAtomToName.size());
4505 }
4506
4507 return kNone;
4508}
4509
4510//______________________________________________________________________________
4512{
4513 if (gEnv) {
4514 const char * const iconDirectoryPath = gEnv->GetValue("Gui.IconPath",TROOT::GetIconPath());
4515 if (iconDirectoryPath) {
4516 const Util::ScopedArray<char> fileName(gSystem->Which(iconDirectoryPath, "Root6Icon.png", kReadPermission));
4517 if (fileName.Get()) {
4518 const Util::AutoreleasePool pool;
4519 //Aha, ASCII ;) do not install ROOT in ...
4520 NSString *cocoaStr = [NSString stringWithCString : fileName.Get() encoding : NSASCIIStringEncoding];
4521 NSImage *image = [[[NSImage alloc] initWithContentsOfFile : cocoaStr] autorelease];
4522 [NSApp setApplicationIconImage : image];
4523 }
4524 }
4525 }
4526}
SVector< double, 2 > v
Definition: Dict.h:5
const Mask_t kGCCapStyle
Definition: GuiTypes.h:291
const Mask_t kGCArcMode
Definition: GuiTypes.h:307
EGEventType
Definition: GuiTypes.h:58
@ kUnmapNotify
Definition: GuiTypes.h:61
@ kSelectionNotify
Definition: GuiTypes.h:62
@ kDestroyNotify
Definition: GuiTypes.h:61
@ kSelectionRequest
Definition: GuiTypes.h:62
const Mask_t kGCDashOffset
Definition: GuiTypes.h:305
const Mask_t kGCBackground
Definition: GuiTypes.h:288
const Mask_t kGCForeground
Definition: GuiTypes.h:287
const Mask_t kGCLineStyle
Definition: GuiTypes.h:290
const Mask_t kGCSubwindowMode
Definition: GuiTypes.h:300
const Mask_t kGCLineWidth
Definition: GuiTypes.h:289
Handle_t Cursor_t
Definition: GuiTypes.h:33
const Mask_t kGCTile
Definition: GuiTypes.h:295
const Mask_t kGCClipXOrigin
Definition: GuiTypes.h:302
ULong_t Handle_t
Definition: GuiTypes.h:25
Handle_t FontH_t
Definition: GuiTypes.h:34
Handle_t Visual_t
Definition: GuiTypes.h:27
const Mask_t kGCDashList
Definition: GuiTypes.h:306
const Mask_t kGCFillStyle
Definition: GuiTypes.h:293
const Mask_t kGCJoinStyle
Definition: GuiTypes.h:292
Handle_t Display_t
Definition: GuiTypes.h:26
const Mask_t kGCFunction
Definition: GuiTypes.h:285
Handle_t Pixmap_t
Definition: GuiTypes.h:29
ULong_t Time_t
Definition: GuiTypes.h:41
EInitialState
Definition: GuiTypes.h:344
const Mask_t kGCTileStipXOrigin
Definition: GuiTypes.h:297
Handle_t Drawable_t
Definition: GuiTypes.h:30
const Mask_t kGCFont
Definition: GuiTypes.h:299
Handle_t Colormap_t
Definition: GuiTypes.h:32
Handle_t Atom_t
Definition: GuiTypes.h:36
const Handle_t kNone
Definition: GuiTypes.h:87
const Mask_t kStructureNotifyMask
Definition: GuiTypes.h:165
@ kIsViewable
Definition: GuiTypes.h:45
@ kFillOpaqueStippled
Definition: GuiTypes.h:50
@ kLineDoubleDash
Definition: GuiTypes.h:47
@ kFillStippled
Definition: GuiTypes.h:50
@ kLineSolid
Definition: GuiTypes.h:47
@ kLineOnOffDash
Definition: GuiTypes.h:47
@ kFillTiled
Definition: GuiTypes.h:50
const Mask_t kGCFillRule
Definition: GuiTypes.h:294
Handle_t GContext_t
Definition: GuiTypes.h:37
const Mask_t kGCPlaneMask
Definition: GuiTypes.h:286
UInt_t Mask_t
Definition: GuiTypes.h:40
const Mask_t kGCStipple
Definition: GuiTypes.h:296
const Mask_t kGCGraphicsExposures
Definition: GuiTypes.h:301
const Mask_t kGCClipYOrigin
Definition: GuiTypes.h:303
Handle_t Region_t
Definition: GuiTypes.h:31
const Mask_t kGCClipMask
Definition: GuiTypes.h:304
Handle_t FontStruct_t
Definition: GuiTypes.h:38
const Mask_t kGCTileStipYOrigin
Definition: GuiTypes.h:298
EMouseButton
Definition: GuiTypes.h:213
Handle_t Window_t
Definition: GuiTypes.h:28
#define c(i)
Definition: RSha256.hxx:101
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
static const double x2[5]
static const double x1[5]
int Int_t
Definition: RtypesCore.h:41
unsigned char UChar_t
Definition: RtypesCore.h:34
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
short Color_t
Definition: RtypesCore.h:79
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
void Warning(const char *location, const char *msgfmt,...)
#define gClient
Definition: TGClient.h:166
@ kMWMFuncAll
Definition: TGFrame.h:80
@ kMWMFuncResize
Definition: TGFrame.h:81
@ kMWMDecorMaximize
Definition: TGFrame.h:100
@ kMWMDecorMinimize
Definition: TGFrame.h:99
@ kMWMDecorAll
Definition: TGFrame.h:94
int type
Definition: TGX11.cxx:120
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:57
#define gROOT
Definition: TROOT.h:410
@ kReadPermission
Definition: TSystem.h:48
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
#define R__LOCKGUARD(mutex)
#define gVirtualX
Definition: TVirtualX.h:345
ECursor
Definition: TVirtualX.h:44
@ kPointer
Definition: TVirtualX.h:47
DerivedType * Get() const
Definition: CocoaUtils.h:136
void Reset(NSObject *object)
Definition: CocoaUtils.h:141
The color creation and management class.
Definition: TColor.h:19
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
This class implements TVirtualX interface for MacOS X, using Cocoa and Quartz 2D.
Definition: TGCocoa.h:58
virtual void SetClipRectangles(GContext_t gc, Int_t x, Int_t y, Rectangle_t *recs, Int_t n)
Sets clipping rectangles in graphics context.
Definition: TGCocoa.mm:4274
virtual const char * DisplayName(const char *)
Returns hostname on which the display is opened.
Definition: TGCocoa.mm:459
virtual void SetRGB(Int_t cindex, Float_t r, Float_t g, Float_t b)
Sets color intensities the specified color index "cindex".
Definition: TGCocoa.mm:2980
virtual void LowerWindow(Window_t wid)
Lowers the specified window "id" to the bottom of the stack so that it does not obscure any sibling w...
Definition: TGCocoa.mm:1180
virtual void FlushOpenGLBuffer(Handle_t ctxID)
Flushes OpenGL buffer.
Definition: TGCocoa.mm:3414
virtual Window_t GetWindowID(Int_t wid)
Returns the X11 window identifier.
Definition: TGCocoa.mm:614
virtual Int_t GetDoubleBuffer(Int_t wid)
Queries the double buffer value for the window "wid".
Definition: TGCocoa.mm:4028
virtual void GetGeometry(Int_t wid, Int_t &x, Int_t &y, UInt_t &w, UInt_t &h)
Returns position and size of window "wid".
Definition: TGCocoa.mm:656
std::vector< GCValues_t > fX11Contexts
Definition: TGCocoa.h:456
virtual void XorRegion(Region_t rega, Region_t regb, Region_t result)
Calculates the difference between the union and intersection of two regions.
Definition: TGCocoa.mm:4348
void DrawLineAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
Definition: TGCocoa.mm:1646
virtual void GetWindowSize(Drawable_t wid, Int_t &x, Int_t &y, UInt_t &w, UInt_t &h)
Returns the location and the size of window "id".
Definition: TGCocoa.mm:1359
TGCocoa()
Definition: TGCocoa.mm:383
virtual Handle_t CreateOpenGLContext(Window_t windowID, Handle_t sharedContext)
Creates OpenGL context for window "windowID".
Definition: TGCocoa.mm:3295
virtual Pixmap_t ReadGIF(Int_t x0, Int_t y0, const char *file, Window_t wid)
If id is NULL - loads the specified gif file at position [x0,y0] in the current window.
Definition: TGCocoa.mm:4042
virtual UInt_t ScreenWidthMM() const
Returns the width of the screen in millimeters.
Definition: TGCocoa.mm:500
void ReparentTopLevel(Window_t wid, Window_t pid, Int_t x, Int_t y)
Definition: TGCocoa.mm:1038
Bool_t IsCocoaDraw() const
Definition: TGCocoa.mm:4417
void SetApplicationIcon()
Definition: TGCocoa.mm:4511
bool fDisplayShapeChanged
Definition: TGCocoa.h:465
virtual Bool_t EqualRegion(Region_t rega, Region_t regb)
Returns kTRUE if the two regions have the same offset, size, and shape.
Definition: TGCocoa.mm:4376
virtual Pixmap_t CreatePixmap(Drawable_t wid, UInt_t w, UInt_t h)
Creates a pixmap of the specified width and height and returns a pixmap ID that identifies it.
Definition: TGCocoa.mm:2437
virtual void ClosePixmap()
Deletes current pixmap.
Definition: TGCocoa.mm:2423
virtual Region_t PolygonRegion(Point_t *points, Int_t np, Bool_t winding)
Returns a region for the polygon defined by the points array.
Definition: TGCocoa.mm:4309
virtual void GetFontProperties(FontStruct_t font, Int_t &max_ascent, Int_t &max_descent)
Returns the font properties.
Definition: TGCocoa.mm:2866
virtual void MapSubwindows(Window_t wid)
Maps all subwindows for the specified window "id" in top-to-bottom stacking order.
Definition: TGCocoa.mm:1098
virtual Pixmap_t CreatePixmapFromData(unsigned char *bits, UInt_t width, UInt_t height)
create pixmap from RGB data.
Definition: TGCocoa.mm:2477
void FillRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
Definition: TGCocoa.mm:1860
Atom_t FindAtom(const std::string &atomName, bool addIfNotFound)
Definition: TGCocoa.mm:4493
virtual void SetDoubleBufferON()
Turns double buffer mode on.
Definition: TGCocoa.mm:3472
ROOT::MacOSX::X11::CommandBuffer * GetCommandBuffer() const
Definition: TGCocoa.mm:4398
virtual void SubtractRegion(Region_t rega, Region_t regb, Region_t result)
Subtracts regb from rega and stores the results in result.
Definition: TGCocoa.mm:4342
virtual void GetGCValues(GContext_t gc, GCValues_t &gval)
Returns the components specified by the mask in "gval" for the specified GC "gc" (see also the GCValu...
Definition: TGCocoa.mm:3100
void CopyAreaAux(Drawable_t src, Drawable_t dst, const GCValues_t &gc, Int_t srcX, Int_t srcY, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY)
Definition: TGCocoa.mm:2085
bool fForegroundProcess
Definition: TGCocoa.h:455
virtual void GrabPointer(Window_t wid, UInt_t evmask, Window_t confine, Cursor_t cursor, Bool_t grab=kTRUE, Bool_t owner_events=kTRUE)
Establishes an active pointer grab.
Definition: TGCocoa.mm:2688
void DrawRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
Definition: TGCocoa.mm:1784
virtual void GetCharacterUp(Float_t &chupx, Float_t &chupy)
Returns character up vector.
Definition: TGCocoa.mm:4035
virtual void DrawLine(Drawable_t wid, GContext_t gc, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
Uses the components of the specified GC to draw a line between the specified set of points (x1,...
Definition: TGCocoa.mm:1686
virtual FontStruct_t LoadQueryFont(const char *font_name)
Provides the most common way for accessing a font: opens (loads) the specified font and returns a poi...
Definition: TGCocoa.mm:2819
virtual char ** ListFonts(const char *fontname, Int_t max, Int_t &count)
Returns list of font names matching fontname regexp, like "-*-times-*".
Definition: TGCocoa.mm:2892
virtual void CopyPixmap(Int_t wid, Int_t xpos, Int_t ypos)
Copies the pixmap "wid" at the position [xpos,ypos] in the current window.
Definition: TGCocoa.mm:2388
virtual void FreeColor(Colormap_t cmap, ULong_t pixel)
Frees color cell with specified pixel value.
Definition: TGCocoa.mm:2946
virtual void ShapeCombineMask(Window_t wid, Int_t x, Int_t y, Pixmap_t mask)
The Non-rectangular Window Shape Extension adds non-rectangular windows to the System.
Definition: TGCocoa.mm:1500
virtual Int_t TextWidth(FontStruct_t font, const char *s, Int_t len)
Return length of the string "s" in pixels. Size depends on font.
Definition: TGCocoa.mm:2859
std::unique_ptr< ROOT::MacOSX::Details::CocoaPrivate > fPimpl
Definition: TGCocoa.h:444
virtual void SetWMSizeHints(Window_t winID, UInt_t wMin, UInt_t hMin, UInt_t wMax, UInt_t hMax, UInt_t wInc, UInt_t hInc)
Gives the window manager minimum and maximum size hints of the window "id".
Definition: TGCocoa.mm:1586
virtual void QueryColor(Colormap_t cmap, ColorStruct_t &color)
Returns the current RGB value for the pixel in the "color" structure.
Definition: TGCocoa.mm:2937
virtual void SetWMTransientHint(Window_t winID, Window_t mainWinID)
Tells window manager that the window "id" is a transient window of the window "main_id".
Definition: TGCocoa.mm:1608
virtual Int_t EventsPending()
Returns the number of events that have been received from the X server but have not been removed from...
Definition: TGCocoa.mm:3538
void * GetCurrentContext()
Definition: TGCocoa.mm:4423
virtual void ConvertSelection(Window_t, Atom_t &, Atom_t &, Atom_t &, Time_t &)
Requests that the specified selection be converted to the specified target type.
Definition: TGCocoa.mm:3681
virtual Window_t CreateOpenGLWindow(Window_t parentID, UInt_t width, UInt_t height, const std::vector< std::pair< UInt_t, Int_t > > &format)
Create window with special pixel format. Noop everywhere except Cocoa.
Definition: TGCocoa.mm:3216
virtual void TranslateCoordinates(Window_t src, Window_t dest, Int_t src_x, Int_t src_y, Int_t &dest_x, Int_t &dest_y, Window_t &child)
Translates coordinates in one window to the coordinate space of another window.
Definition: TGCocoa.mm:1284
virtual Bool_t Init(void *display)
Initializes the X system.
Definition: TGCocoa.mm:443
virtual void RaiseWindow(Window_t wid)
Raises the specified window to the top of the stack so that no sibling window obscures it.
Definition: TGCocoa.mm:1163
virtual ULong_t GetPixel(Color_t cindex)
Returns pixel value associated to specified ROOT color number "cindex".
Definition: TGCocoa.mm:2952
virtual void SetCharacterUp(Float_t chupx, Float_t chupy)
Sets character up vector.
Definition: TGCocoa.mm:4094
virtual void LookupString(Event_t *event, char *buf, Int_t buflen, UInt_t &keysym)
Converts the keycode from the event structure to a key symbol (according to the modifiers specified i...
Definition: TGCocoa.mm:2798
EDrawMode fDrawMode
Definition: TGCocoa.h:447
virtual Int_t OpenPixmap(UInt_t w, UInt_t h)
Creates a pixmap of the width "w" and height "h" you specified.
Definition: TGCocoa.mm:2341
virtual Int_t GetDepth() const
Returns depth of screen (number of bit planes).
Definition: TGCocoa.mm:510
virtual Drawable_t CreateImage(UInt_t width, UInt_t height)
Allocates the memory needed for an drawable.
Definition: TGCocoa.mm:2589
virtual void UnionRectWithRegion(Rectangle_t *rect, Region_t src, Region_t dest)
Updates the destination region from a union of the specified rectangle and the specified source regio...
Definition: TGCocoa.mm:4298
virtual Bool_t ReadPictureDataFromFile(const char *filename, char ***ret_data)
Reads picture data from file "filename" and store it in "ret_data".
Definition: TGCocoa.mm:4228
void CocoaDrawOFF()
Definition: TGCocoa.mm:4410
virtual void CopyGC(GContext_t org, GContext_t dest, Mask_t mask)
Copies the specified components from the source GC "org" to the destination GC "dest".
Definition: TGCocoa.mm:3088
virtual void DeleteFont(FontStruct_t fs)
Explicitly deletes the font structure "fs" obtained via LoadQueryFont().
Definition: TGCocoa.mm:2845
virtual void PutPixel(Drawable_t wid, Int_t x, Int_t y, ULong_t pixel)
Overwrites the pixel in the image with the specified pixel value.
Definition: TGCocoa.mm:2610
virtual void MoveWindow(Int_t wid, Int_t x, Int_t y)
Moves the window "wid" to the specified x and y coordinates.
Definition: TGCocoa.mm:698
virtual void SetTypeList(Window_t win, Atom_t prop, Atom_t *typelist)
Add the list of drag and drop types to the Window win.
Definition: TGCocoa.mm:3982
virtual Atom_t InternAtom(const char *atom_name, Bool_t only_if_exist)
Returns the atom identifier associated with the specified "atom_name" string.
Definition: TGCocoa.mm:3575
virtual Double_t GetOpenGLScalingFactor()
On a HiDPI resolution it can be > 1., this means glViewport should use scaled width and height.
Definition: TGCocoa.mm:3207
virtual Int_t InitWindow(ULong_t window)
Creates a new window and return window number.
Definition: TGCocoa.mm:589
virtual void FreeFontNames(char **fontlist)
Frees the specified the array of strings "fontlist".
Definition: TGCocoa.mm:2906
std::vector< std::string > fAtomToName
Definition: TGCocoa.h:459
~TGCocoa()
Definition: TGCocoa.mm:434
virtual void CopyArea(Drawable_t src, Drawable_t dst, GContext_t gc, Int_t srcX, Int_t srcY, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY)
Combines the specified rectangle of "src" with the specified rectangle of "dest" according to the "gc...
Definition: TGCocoa.mm:2122
virtual void GetPlanes(Int_t &nplanes)
Returns the maximum number of planes.
Definition: TGCocoa.mm:2967
virtual Bool_t ParseColor(Colormap_t cmap, const char *cname, ColorStruct_t &color)
Looks up the string name of a color "cname" with respect to the screen associated with the specified ...
Definition: TGCocoa.mm:2918
virtual void UpdateWindow(Int_t mode)
Updates or synchronises client and server once (not permanent).
Definition: TGCocoa.mm:743
virtual Int_t RequestLocator(Int_t mode, Int_t ctyp, Int_t &x, Int_t &y)
Requests Locator position.
Definition: TGCocoa.mm:4051
virtual void MapWindow(Window_t wid)
Maps the window "id" and all of its subwindows that have had map requests.
Definition: TGCocoa.mm:1078
virtual void GetWindowAttributes(Window_t wid, WindowAttributes_t &attr)
The WindowAttributes_t structure is set to default.
Definition: TGCocoa.mm:941
virtual void WritePixmap(Int_t wid, UInt_t w, UInt_t h, char *pxname)
Writes the pixmap "wid" in the bitmap file "pxname".
Definition: TGCocoa.mm:4170
virtual Int_t RequestString(Int_t x, Int_t y, char *text)
Requests string: text is displayed and can be edited with Emacs-like keybinding.
Definition: TGCocoa.mm:4083
virtual void DeleteGC(GContext_t gc)
Deletes the specified GC "gc".
Definition: TGCocoa.mm:3109
virtual Pixmap_t CreateBitmap(Drawable_t wid, const char *bitmap, UInt_t width, UInt_t height)
Creates a bitmap (i.e.
Definition: TGCocoa.mm:2508
virtual Visual_t GetVisual() const
Returns handle to visual.
Definition: TGCocoa.mm:486
virtual void SetWindowName(Window_t wid, char *name)
Sets the window name.
Definition: TGCocoa.mm:1466
static Atom_t fgDeleteWindowAtom
Definition: TGCocoa.h:469
virtual void ChangeProperties(Window_t wid, Atom_t property, Atom_t type, Int_t format, UChar_t *data, Int_t len)
Alters the property for the specified window and causes the X server to generate a PropertyNotify eve...
Definition: TGCocoa.mm:3857
virtual Bool_t CheckEvent(Window_t wid, EGEventType type, Event_t &ev)
Check if there is for window "id" an event of type "type".
Definition: TGCocoa.mm:3545
virtual void MapRaised(Window_t wid)
Maps the window "id" and all of its subwindows that have had map requests on the screen and put this ...
Definition: TGCocoa.mm:1112
virtual void SetTextMagnitude(Float_t mgn)
Sets the current text magnification factor to "mgn".
Definition: TGCocoa.mm:4117
virtual Window_t GetInputFocus()
Returns the window id of the window having the input focus.
Definition: TGCocoa.mm:2778
virtual void WMDeleteNotify(Window_t wid)
Tells WM to send message when window is closed via WM.
Definition: TGCocoa.mm:4268
virtual void SetWMState(Window_t winID, EInitialState state)
Sets the initial state of the window "id": either kNormalState or kIconicState.
Definition: TGCocoa.mm:1602
virtual Int_t ResizePixmap(Int_t wid, UInt_t w, UInt_t h)
Resizes the specified pixmap "wid".
Definition: TGCocoa.mm:2361
virtual void NextEvent(Event_t &event)
The "event" is set to default event.
Definition: TGCocoa.mm:3529
virtual Bool_t PointInRegion(Int_t x, Int_t y, Region_t reg)
Returns kTRUE if the point [x, y] is contained in the region reg.
Definition: TGCocoa.mm:4368
virtual void FreeFontStruct(FontStruct_t fs)
Frees the font structure "fs".
Definition: TGCocoa.mm:2884
void DrawStringAux(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, const char *s, Int_t len)
Definition: TGCocoa.mm:2166
virtual Bool_t CreatePictureFromData(Drawable_t wid, char **data, Pixmap_t &pict, Pixmap_t &pict_mask, PictureAttributes_t &attr)
Creates a picture pict from data in bitmap format.
Definition: TGCocoa.mm:4215
virtual void Bell(Int_t percent)
Sets the sound bell. Percent is loudness from -100% to 100%.
Definition: TGCocoa.mm:4262
virtual Int_t GetScreen() const
Returns screen number.
Definition: TGCocoa.mm:493
virtual void SetForeground(GContext_t gc, ULong_t foreground)
Sets the foreground color for the specified GC (shortcut for ChangeGC with only foreground mask set).
Definition: TGCocoa.mm:3005
virtual unsigned char * GetColorBits(Drawable_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
Returns an array of pixels created from a part of drawable (defined by x, y, w, h) in format:
Definition: TGCocoa.mm:2568
virtual Window_t GetParent(Window_t wid) const
Returns the parent of the window "id".
Definition: TGCocoa.mm:1453
virtual void SetCursor(Window_t wid, Cursor_t curid)
Sets the cursor "curid" to be used when the pointer is in the window "id".
Definition: TGCocoa.mm:3143
void ClearAreaAux(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
Definition: TGCocoa.mm:2257
virtual Bool_t IsDNDAware(Window_t win, Atom_t *typelist)
Checks if the Window is DND aware, and knows any of the DND formats passed in argument.
Definition: TGCocoa.mm:3967
void ReconfigureDisplay()
Definition: TGCocoa.mm:544
virtual void SetPrimarySelectionOwner(Window_t wid)
Makes the window "id" the current owner of the primary selection.
Definition: TGCocoa.mm:3584
ROOT::MacOSX::X11::Rectangle GetDisplayGeometry() const
Definition: TGCocoa.mm:550
virtual UInt_t ExecCommand(TGWin32Command *code)
Executes the command "code" coming from the other threads (Win32)
Definition: TGCocoa.mm:4021
virtual void SetDoubleBufferOFF()
Turns double buffer mode off.
Definition: TGCocoa.mm:3466
virtual void SetDrawMode(EDrawMode mode)
Sets the drawing mode.
Definition: TGCocoa.mm:3503
virtual void UnmapWindow(Window_t wid)
Unmaps the specified window "id".
Definition: TGCocoa.mm:1133
virtual Bool_t NeedRedraw(ULong_t tgwindow, Bool_t force)
Notify the low level GUI layer ROOT requires "tgwindow" to be updated.
Definition: TGCocoa.mm:4180
virtual Region_t CreateRegion()
Creates a new empty region.
Definition: TGCocoa.mm:4284
virtual void Sync(Int_t mode)
Set synchronisation on or off.
Definition: TGCocoa.mm:4123
virtual Colormap_t GetColormap() const
Returns handle to colormap.
Definition: TGCocoa.mm:2989
virtual void SetClipOFF(Int_t wid)
Turns off the clipping for the window "wid".
Definition: TGCocoa.mm:4100
virtual void GrabKey(Window_t wid, Int_t keycode, UInt_t modifier, Bool_t grab=kTRUE)
Establishes a passive grab on the keyboard.
Definition: TGCocoa.mm:2725
virtual void SetDNDAware(Window_t, Atom_t *)
Add XdndAware property and the list of drag and drop types to the Window win.
Definition: TGCocoa.mm:3916
virtual void SetClassHints(Window_t wid, char *className, char *resourceName)
Sets the windows class and resource name.
Definition: TGCocoa.mm:1494
virtual FontStruct_t GetFontStruct(FontH_t fh)
Retrieves the associated font structure of the font specified font handle "fh".
Definition: TGCocoa.mm:2873
virtual void FillRectangle(Drawable_t wid, GContext_t gc, Int_t x, Int_t y, UInt_t w, UInt_t h)
Fills the specified rectangle defined by [x,y] [x+w,y] [x+w,y+h] [x,y+h].
Definition: TGCocoa.mm:1924
ROOT::MacOSX::X11::EventTranslator * GetEventTranslator() const
Definition: TGCocoa.mm:4392
virtual void GetRGB(Int_t index, Float_t &r, Float_t &g, Float_t &b)
Returns RGB values for color "index".
Definition: TGCocoa.mm:2974
void ReparentChild(Window_t wid, Window_t pid, Int_t x, Int_t y)
Definition: TGCocoa.mm:991
virtual void MoveResizeWindow(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
Changes the size and location of the specified window "id" without raising it.
Definition: TGCocoa.mm:1215
void DrawSegmentsAux(Drawable_t wid, const GCValues_t &gcVals, const Segment_t *segments, Int_t nSegments)
Definition: TGCocoa.mm:1731
virtual void SetDoubleBuffer(Int_t wid, Int_t mode)
Sets the double buffer on/off on the window "wid".
Definition: TGCocoa.mm:3451
virtual void SetIconPixmap(Window_t wid, Pixmap_t pix)
Sets the icon name pixmap.
Definition: TGCocoa.mm:1488
bool fDirectDraw
Definition: TGCocoa.h:448
virtual void DestroySubwindows(Window_t wid)
The DestroySubwindows function destroys all inferior windows of the specified window,...
Definition: TGCocoa.mm:910
virtual FontH_t GetFontHandle(FontStruct_t fs)
Returns the font handle of the specified font structure "fs".
Definition: TGCocoa.mm:2839
virtual void SetDashes(GContext_t gc, Int_t offset, const char *dash_list, Int_t n)
Sets the dash-offset and dash-list attributes for dashed line styles in the specified GC.
Definition: TGCocoa.mm:4243
virtual void SetWMPosition(Window_t winID, Int_t x, Int_t y)
Tells the window manager the desired position [x,y] of window "id".
Definition: TGCocoa.mm:1574
virtual Window_t GetDefaultRootWindow() const
Returns handle to the default root window created when calling XOpenDisplay().
Definition: TGCocoa.mm:582
virtual Window_t GetCurrentWindow() const
pointer to the current internal window used in canvas graphics
Definition: TGCocoa.mm:782
virtual void ChangeActivePointerGrab(Window_t, UInt_t, Cursor_t)
Changes the specified dynamic parameters if the pointer is actively grabbed by the client and if the ...
Definition: TGCocoa.mm:2709
virtual void ChangeProperty(Window_t wid, Atom_t property, Atom_t type, UChar_t *data, Int_t len)
Alters the property for the specified window and causes the X server to generate a PropertyNotify eve...
Definition: TGCocoa.mm:3814
virtual void IconifyWindow(Window_t wid)
Iconifies the window "id".
Definition: TGCocoa.mm:1257
virtual void ChangeWindowAttributes(Window_t wid, SetWindowAttributes_t *attr)
Changes the attributes of the specified window "id" according the values provided in "attr".
Definition: TGCocoa.mm:955
virtual Window_t CreateWindow(Window_t parent, Int_t x, Int_t y, UInt_t w, UInt_t h, UInt_t border, Int_t depth, UInt_t clss, void *visual, SetWindowAttributes_t *attr, UInt_t wtype)
Creates an unmapped subwindow for a specified parent window and returns the created window.
Definition: TGCocoa.mm:811
virtual void RescaleWindow(Int_t wid, UInt_t w, UInt_t h)
Rescales the window "wid".
Definition: TGCocoa.mm:712
virtual void CloseDisplay()
Closes connection to display server and destroys all windows.
Definition: TGCocoa.mm:473
virtual Bool_t AllocColor(Colormap_t cmap, ColorStruct_t &color)
Allocates a read-only colormap entry corresponding to the closest RGB value supported by the hardware...
Definition: TGCocoa.mm:2927
virtual void DeletePictureData(void *data)
Delete picture data created by the function ReadPictureDataFromFile.
Definition: TGCocoa.mm:4237
virtual Bool_t MakeOpenGLContextCurrent(Handle_t ctx, Window_t windowID)
Makes context ctx current OpenGL context.
Definition: TGCocoa.mm:3320
virtual void ConvertPrimarySelection(Window_t wid, Atom_t clipboard, Time_t when)
Causes a SelectionRequest event to be sent to the current primary selection owner.
Definition: TGCocoa.mm:3647
void DeletePixmapAux(Pixmap_t pixmapID)
Definition: TGCocoa.mm:2545
virtual GContext_t CreateGC(Drawable_t wid, GCValues_t *gval)
Creates a graphics context using the provided GCValues_t *gval structure.
Definition: TGCocoa.mm:2997
virtual void SetClipRegion(Int_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
Sets clipping region for the window "wid".
Definition: TGCocoa.mm:4106
virtual void CloseWindow()
Deletes current window.
Definition: TGCocoa.mm:789
virtual void DeleteImage(Drawable_t img)
Deallocates the memory associated with the image img.
Definition: TGCocoa.mm:2643
virtual Int_t WriteGIF(char *name)
Writes the current window into GIF file.
Definition: TGCocoa.mm:4161
virtual void QueryPointer(Int_t &x, Int_t &y)
Returns the pointer position.
Definition: TGCocoa.mm:3154
virtual void ChangeGC(GContext_t gc, GCValues_t *gval)
Changes the components specified by the mask in gval for the specified GC.
Definition: TGCocoa.mm:3022
virtual void ClearArea(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
Paints a rectangular area in the specified window "id" according to the specified dimensions with the...
Definition: TGCocoa.mm:2296
virtual Int_t AddWindow(ULong_t qwid, UInt_t w, UInt_t h)
Registers a window created by Qt as a ROOT window.
Definition: TGCocoa.mm:795
virtual void DestroyRegion(Region_t reg)
Destroys the region "reg".
Definition: TGCocoa.mm:4292
virtual Handle_t GetNativeEvent() const
Returns the current native event handle.
Definition: TGCocoa.mm:3565
virtual void SetWindowBackgroundPixmap(Window_t wid, Pixmap_t pxm)
Sets the background pixmap of the window "id" to the specified pixmap "pxm".
Definition: TGCocoa.mm:1407
void CocoaDrawON()
Definition: TGCocoa.mm:4404
virtual void SetMWMHints(Window_t winID, UInt_t value, UInt_t decorators, UInt_t inputMode)
Sets decoration style.
Definition: TGCocoa.mm:1534
virtual void SelectInput(Window_t wid, UInt_t evmask)
Defines which input events the window is interested in.
Definition: TGCocoa.mm:971
virtual Window_t FindRWindow(Window_t win, Window_t dragwin, Window_t input, int x, int y, int maxd)
Recursively search in the children of Window for a Window which is at location x, y and is DND aware,...
Definition: TGCocoa.mm:3990
ROOT::MacOSX::X11::name_to_atom_map fNameToAtom
Definition: TGCocoa.h:458
virtual void GetRegionBox(Region_t reg, Rectangle_t *rect)
Returns smallest enclosing rectangle.
Definition: TGCocoa.mm:4384
virtual void Update(Int_t mode)
Flushes (mode = 0, default) or synchronizes (mode = 1) X output buffer.
Definition: TGCocoa.mm:527
virtual void UnionRegion(Region_t rega, Region_t regb, Region_t result)
Computes the union of two regions.
Definition: TGCocoa.mm:4321
virtual Handle_t GetCurrentOpenGLContext()
Asks OpenGL subsystem about the current OpenGL context.
Definition: TGCocoa.mm:3397
virtual void RemoveWindow(ULong_t qwid)
Removes the created by Qt window "qwid".
Definition: TGCocoa.mm:805
virtual void GetPasteBuffer(Window_t wid, Atom_t atom, TString &text, Int_t &nchar, Bool_t del)
Gets contents of the paste buffer "atom" into the string "text".
Definition: TGCocoa.mm:3763
virtual void GrabButton(Window_t wid, EMouseButton button, UInt_t modifier, UInt_t evmask, Window_t confine, Cursor_t cursor, Bool_t grab=kTRUE)
Establishes a passive grab on a certain mouse button.
Definition: TGCocoa.mm:2654
Int_t fCocoaDraw
Definition: TGCocoa.h:445
virtual void SetInputFocus(Window_t wid)
Changes the input focus to specified window "id".
Definition: TGCocoa.mm:2786
virtual void ResizeWindow(Int_t wid)
Resizes the window "wid" if necessary.
Definition: TGCocoa.mm:720
virtual Bool_t HasTTFonts() const
Returns True when TrueType fonts are used.
Definition: TGCocoa.mm:2851
virtual void GetImageSize(Drawable_t wid, UInt_t &width, UInt_t &height)
Returns the width and height of the image id.
Definition: TGCocoa.mm:2599
virtual Int_t OpenDisplay(const char *displayName)
Opens connection to display server (if such a thing exist on the current platform).
Definition: TGCocoa.mm:452
virtual void DeletePixmap(Pixmap_t pixmapID)
Explicitly deletes the pixmap resource "pmap".
Definition: TGCocoa.mm:2551
virtual void SetWMSize(Window_t winID, UInt_t w, UInt_t h)
Tells window manager the desired size of window "id".
Definition: TGCocoa.mm:1580
virtual void SendEvent(Window_t wid, Event_t *ev)
Specifies the event "ev" is to be sent to the window "id".
Definition: TGCocoa.mm:3514
virtual void SetKeyAutoRepeat(Bool_t on=kTRUE)
Turns key auto repeat on (kTRUE) or off (kFALSE).
Definition: TGCocoa.mm:2718
virtual Bool_t EmptyRegion(Region_t reg)
Returns kTRUE if the region reg is empty.
Definition: TGCocoa.mm:4360
bool fSetApp
Definition: TGCocoa.h:464
virtual void FillPolygon(Window_t wid, GContext_t gc, Point_t *polygon, Int_t nPoints)
Fills the region closed by the specified path.
Definition: TGCocoa.mm:2033
virtual void SetWindowBackground(Window_t wid, ULong_t color)
Sets the background of the window "id" to the specified color value "color".
Definition: TGCocoa.mm:1395
virtual Int_t SupportsExtension(const char *extensionName) const
Returns 1 if window system server supports extension given by the argument, returns 0 in case extensi...
Definition: TGCocoa.mm:466
virtual Cursor_t CreateCursor(ECursor cursor)
Creates the specified cursor.
Definition: TGCocoa.mm:3117
virtual void ReparentWindow(Window_t wid, Window_t pid, Int_t x, Int_t y)
If the specified window is mapped, ReparentWindow automatically performs an UnmapWindow request on it...
Definition: TGCocoa.mm:1060
void FillPolygonAux(Window_t wid, const GCValues_t &gcVals, const Point_t *polygon, Int_t nPoints)
Definition: TGCocoa.mm:1962
virtual Int_t AddPixmap(ULong_t pixid, UInt_t w, UInt_t h)
Registers a pixmap created by TGLManager as a ROOT pixmap.
Definition: TGCocoa.mm:2559
virtual void DeleteOpenGLContext(Int_t ctxID)
Deletes OpenGL context for window "wid".
Definition: TGCocoa.mm:3429
bool MakeProcessForeground()
Definition: TGCocoa.mm:4436
virtual void PutImage(Drawable_t wid, GContext_t gc, Drawable_t img, Int_t dx, Int_t dy, Int_t x, Int_t y, UInt_t w, UInt_t h)
Combines an image with a rectangle of the specified drawable.
Definition: TGCocoa.mm:2632
virtual Bool_t SetSelectionOwner(Window_t windowID, Atom_t &selectionID)
Changes the owner and last-change time for the specified selection.
Definition: TGCocoa.mm:3610
std::map< Atom_t, Window_t > fSelectionOwners
Definition: TGCocoa.h:461
virtual Bool_t CreatePictureFromFile(Drawable_t wid, const char *filename, Pixmap_t &pict, Pixmap_t &pict_mask, PictureAttributes_t &attr)
Creates a picture pict from data in file "filename".
Definition: TGCocoa.mm:4200
virtual Int_t GetProperty(Window_t, Atom_t, Long_t, Long_t, Bool_t, Atom_t, Atom_t *, Int_t *, ULong_t *, ULong_t *, unsigned char **)
Returns the actual type of the property; the actual format of the property; the number of 8-bit,...
Definition: TGCocoa.mm:3716
virtual void SelectWindow(Int_t wid)
Selects the window "wid" to which subsequent output is directed.
Definition: TGCocoa.mm:623
virtual void DrawSegments(Drawable_t wid, GContext_t gc, Segment_t *segments, Int_t nSegments)
Draws multiple line segments.
Definition: TGCocoa.mm:1742
virtual void ClearWindow()
Clears the entire area of the current window.
Definition: TGCocoa.mm:630
virtual void SetIconName(Window_t wid, char *name)
Sets the window icon name.
Definition: TGCocoa.mm:1482
Drawable_t fSelectedDrawable
Definition: TGCocoa.h:442
virtual void DestroyWindow(Window_t wid)
Destroys the window "id" as well as all of its subwindows.
Definition: TGCocoa.mm:852
virtual Window_t GetPrimarySelectionOwner()
Returns the window id of the current owner of the primary selection.
Definition: TGCocoa.mm:3633
ROOT::MacOSX::X11::Rectangle fDisplayRect
Definition: TGCocoa.h:466
virtual void DeleteProperty(Window_t, Atom_t &)
Deletes the specified property only if the property was defined on the specified window and causes th...
Definition: TGCocoa.mm:3892
virtual void DrawRectangle(Drawable_t wid, GContext_t gc, Int_t x, Int_t y, UInt_t w, UInt_t h)
Draws rectangle outlines of [x,y] [x+w,y] [x+w,y+h] [x,y+h].
Definition: TGCocoa.mm:1818
virtual void SelectPixmap(Int_t qpixid)
Selects the pixmap "qpixid".
Definition: TGCocoa.mm:2379
virtual void Warp(Int_t ix, Int_t iy, Window_t wid)
Sets the pointer position.
Definition: TGCocoa.mm:4132
std::map< Atom_t, Window_t >::iterator selection_iterator
Definition: TGCocoa.h:462
virtual void IntersectRegion(Region_t rega, Region_t regb, Region_t result)
Computes the intersection of two regions.
Definition: TGCocoa.mm:4332
virtual Display_t GetDisplay() const
Returns handle to display (might be useful in some cases where direct X11 manipulation outside of TVi...
Definition: TGCocoa.mm:479
virtual Int_t KeysymToKeycode(UInt_t keysym)
Converts the "keysym" to the appropriate keycode.
Definition: TGCocoa.mm:2767
virtual void DrawString(Drawable_t wid, GContext_t gc, Int_t x, Int_t y, const char *s, Int_t len)
Each character image, as defined by the font in the GC, is treated as an additional mask for a fill o...
Definition: TGCocoa.mm:2210
void InitializeCocoa()
bool CocoaInitialized() const
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
static const TString & GetIconPath()
Get the icon path in the installation. Static utility function.
Definition: TROOT.cxx:3126
Basic string class.
Definition: TString.h:131
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1536
Semi-Abstract base class defining a generic interface to the underlying, low level,...
Definition: TVirtualX.h:53
TPaveText * pt
TText * text
BOOL fIsStippleMask
Definition: QuartzPixmap.h:90
ROOT::MacOSX::Util::CFScopeGuard< CGImageRef > fImage
Definition: QuartzPixmap.h:96
unsigned fHeight
Definition: QuartzPixmap.h:38
unsigned fWidth
Definition: QuartzPixmap.h:37
BOOL fIsDNDAware
Definition: QuartzWindow.h:174
CGContextRef fContext
Definition: QuartzWindow.h:155
unsigned fWidth()
QuartzView * fParentView
Definition: QuartzWindow.h:165
unsigned fID
Definition: QuartzWindow.h:154
QuartzImage * fBackgroundPixmap
Definition: QuartzWindow.h:181
BOOL fIsOverlapped
Definition: QuartzWindow.h:178
unsigned long fBackgroundPixel
Definition: QuartzWindow.h:161
unsigned fHeight()
NSView< X11Window > * fContentView
Definition: QuartzWindow.h:237
QuartzView * fContentView
Definition: QuartzWindow.h:36
QuartzWindow * fMainWindow
Definition: QuartzWindow.h:33
QuartzImage * fShapeCombineMask
Definition: QuartzWindow.h:38
NSOpenGLContext * fOpenGLContext
NSOpenGLPixelFormat * pixelFormat()
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
#define H(x, y, z)
const NSUInteger kMiniaturizableWindowMask
const NSUInteger kTitledWindowMask
const NSUInteger kResizableWindowMask
const NSUInteger kClosableWindowMask
bool GLViewIsValidDrawable(ROOTOpenGLView *glView)
Int_t MapKeySymToKeyCode(Int_t keySym)
Definition: X11Events.mm:178
bool ViewIsHtmlViewFrame(NSView< X11Window > *view, bool checkParent)
int GlobalYCocoaToROOT(CGFloat yCocoa)
void PixelToRGB(Pixel_t pixelColor, CGFloat *rgb)
Definition: X11Colors.mm:920
void MapUnicharToKeySym(unichar key, char *buf, Int_t len, UInt_t &rootKeySym)
Definition: X11Events.mm:98
void FillPixmapBuffer(const unsigned char *bitmap, unsigned width, unsigned height, ULong_t foregroundPixel, ULong_t backgroundPixel, unsigned depth, unsigned char *imageData)
NSPoint TranslateToScreen(NSView< X11Window > *from, NSPoint point)
NSView< X11Window > * FindDNDAwareViewInPoint(NSView *parentView, Window_t dragWinID, Window_t inputWinID, Int_t x, Int_t y, Int_t maxDepth)
QuartzWindow * FindWindowInPoint(Int_t x, Int_t y)
int GlobalXCocoaToROOT(CGFloat xCocoa)
void WindowLostFocus(Window_t winID)
int LocalYROOTToCocoa(NSView< X11Window > *parentView, CGFloat yROOT)
UInt_t GetModifiers()
Definition: X11Events.mm:300
bool ParseXLFDName(const std::string &xlfdName, XLFDName &dst)
Definition: XLFDParser.mm:260
NSPoint TranslateCoordinates(NSView< X11Window > *fromView, NSView< X11Window > *toView, NSPoint sourcePoint)
QuartzWindow * CreateTopLevelWindow(Int_t x, Int_t y, UInt_t w, UInt_t h, UInt_t border, Int_t depth, UInt_t clss, void *visual, SetWindowAttributes_t *attr, UInt_t)
Definition: QuartzWindow.mm:56
void UnlockFocus(NSView< X11Window > *view)
int GlobalXROOTToCocoa(CGFloat xROOT)
QuartzView * CreateChildView(QuartzView *parent, Int_t x, Int_t y, UInt_t w, UInt_t h, UInt_t border, Int_t depth, UInt_t clss, void *visual, SetWindowAttributes_t *attr, UInt_t wtype)
Definition: QuartzWindow.mm:85
void GetRootWindowAttributes(WindowAttributes_t *attr)
bool ViewIsTextViewFrame(NSView< X11Window > *view, bool checkParent)
NSPoint TranslateFromScreen(NSPoint point, NSView< X11Window > *to)
NSUInteger GetCocoaKeyModifiersFromROOTKeyModifiers(UInt_t rootKeyModifiers)
Definition: X11Events.mm:261
bool LockFocus(NSView< X11Window > *view)
void InitWithPredefinedAtoms(name_to_atom_map &nameToAtom, std::vector< std::string > &atomNames)
Definition: X11Atoms.mm:83
void DrawTextLineNoKerning(CGContextRef ctx, CTFontRef font, const std::vector< UniChar > &text, Int_t x, Int_t y)
Definition: QuartzText.mm:319
void DrawPattern(void *data, CGContextRef ctx)
bool SetFillPattern(CGContextRef ctx, const unsigned *patternIndex)
@ kDepth
Definition: TVirtualGL.h:132
@ kMultiSample
Definition: TVirtualGL.h:136
@ kStencil
Definition: TVirtualGL.h:134
@ kDoubleBuffer
Definition: TVirtualGL.h:131
@ kAccum
Definition: TVirtualGL.h:133
static constexpr double s
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value and is_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:12929
unsigned fID
Definition: X11Drawable.h:37
ULong_t fPixel
Definition: GuiTypes.h:310
UShort_t fRed
Definition: GuiTypes.h:311
UShort_t fGreen
Definition: GuiTypes.h:312
UShort_t fBlue
Definition: GuiTypes.h:313
EGEventType fType
Definition: GuiTypes.h:174
Window_t fWindow
Definition: GuiTypes.h:175
Long_t fUser[5]
Definition: GuiTypes.h:186
UInt_t fCode
Definition: GuiTypes.h:179
ULong_t fBackground
Definition: GuiTypes.h:227
Int_t fFillRule
Definition: GuiTypes.h:235
Pixmap_t fClipMask
Definition: GuiTypes.h:246
Int_t fDashOffset
Definition: GuiTypes.h:247
Int_t fClipYOrigin
Definition: GuiTypes.h:245
Int_t fClipXOrigin
Definition: GuiTypes.h:244
Int_t fLineWidth
Definition: GuiTypes.h:228
Pixmap_t fStipple
Definition: GuiTypes.h:238
Mask_t fMask
Definition: GuiTypes.h:250
Int_t fLineStyle
Definition: GuiTypes.h:229
Pixmap_t fTile
Definition: GuiTypes.h:237
Bool_t fGraphicsExposures
Definition: GuiTypes.h:243
Int_t fJoinStyle
Definition: GuiTypes.h:232
Char_t fDashes[8]
Definition: GuiTypes.h:248
ULong_t fForeground
Definition: GuiTypes.h:226
ULong_t fPlaneMask
Definition: GuiTypes.h:225
Int_t fFillStyle
Definition: GuiTypes.h:233
FontH_t fFont
Definition: GuiTypes.h:241
Int_t fTsXOrigin
Definition: GuiTypes.h:239
EGraphicsFunction fFunction
Definition: GuiTypes.h:224
Int_t fDashLen
Definition: GuiTypes.h:249
Int_t fCapStyle
Definition: GuiTypes.h:230
Int_t fArcMode
Definition: GuiTypes.h:236
Int_t fTsYOrigin
Definition: GuiTypes.h:240
Int_t fSubwindowMode
Definition: GuiTypes.h:242