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