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