16 #ifdef DEBUG_ROOT_COCOA
28 #include <Availability.h>
35 #include "RConfigure.h"
48 #pragma mark - Create a window or a view.
57 winRect.size.width =
w;
58 winRect.size.height =
h;
60 const NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
61 NSMiniaturizableWindowMask | NSResizableWindowMask;
65 backing : NSBackingStoreBuffered
67 windowAttributes : attr];
69 throw std::runtime_error(
"CreateTopLevelWindow failed");
82 viewRect.origin.x =
x;
83 viewRect.origin.y =
y;
84 viewRect.size.width =
w;
85 viewRect.size.height =
h;
89 throw std::runtime_error(
"CreateChildView failed");
94 #pragma mark - root window (does not really exist, it's our desktop built of all screens).
100 assert(attr != 0 &&
"GetRootWindowAttributes, parameter 'attr' is null");
103 NSArray *
const screens = [NSScreen screens];
104 assert(screens != nil &&
"screens array is nil");
105 NSScreen *
const mainScreen = [screens objectAtIndex : 0];
106 assert(mainScreen != nil &&
"screen with index 0 is nil");
111 "GetRootWindowAttributes, gVirtualX is either null or has a wrong type");
125 attr->
fDepth = NSBitsPerPixelFromDepth([mainScreen depth]);
131 #pragma mark - Coordinate conversions.
136 assert(window != nil &&
"ConvertPointFromBaseToScreen, parameter 'window' is nil");
142 tmpRect.origin = windowPoint;
143 tmpRect.size = NSMakeSize(1., 1.);
144 tmpRect = [window convertRectToScreen : tmpRect];
146 return tmpRect.origin;
152 assert(window != nil &&
"ConvertPointFromScreenToBase, parameter 'window' is nil");
158 tmpRect.origin = screenPoint;
159 tmpRect.size = NSMakeSize(1., 1.);
160 tmpRect = [window convertRectFromScreen : tmpRect];
162 return tmpRect.origin;
173 "GlobalYCocoaToROOT, gVirtualX is either nul or has a wrong type");
177 return int(frame.
fHeight - (yCocoa - frame.
fY));
184 "GlobalXCocoaToROOT, gVirtualX is either nul or has a wrong type");
187 return int(xCocoa - frame.
fX);
194 "GlobalYROOTToCocoa, gVirtualX is either nul or has a wrong type");
197 return int(frame.
fY + (frame.
fHeight - yROOT));
204 "GlobalXROOTToCocoa, gVirtualX is either nul or has a wrong type");
207 return int(frame.
fX + xROOT);
213 assert(parentView != nil &&
"LocalYCocoaToROOT, parent view is nil");
215 return int(parentView.frame.size.height - yCocoa);
222 assert(parentView != nil &&
"LocalYROOTToCocoa, parent view is nil");
224 return int(parentView.frame.size.height - yROOT);
232 assert(drawable != nil &&
"LocalYROOTToCocoa, drawable is nil");
234 return int(drawable.fHeight - yROOT);
240 assert(from != nil &&
"TranslateToScreen, parameter 'from' is nil");
242 const NSPoint winPoint = [from convertPoint : point toView : nil];
254 assert(to != nil &&
"TranslateFromScreen, parameter 'to' is nil");
260 return [to convertPoint : point fromView : nil];
267 assert(from != nil &&
"TranslateCoordinates, parameter 'from' is nil");
268 assert(to != nil &&
"TranslateCoordinates, parameter 'to' is nil");
270 if ([from window] == [to window]) {
272 return [to convertPoint : sourcePoint fromView : from];
280 const NSPoint win1Point = [from convertPoint : sourcePoint toView : nil];
284 return [to convertPoint : win2Point fromView : nil];
291 assert(view != nil &&
"ScreenPointIsInView, parameter 'view' is nil");
294 point.x =
x, point.y =
y;
296 const NSRect viewFrame = view.frame;
298 if (point.x < 0 || point.x > viewFrame.size.width)
300 if (point.y < 0 || point.y > viewFrame.size.height)
306 #pragma mark - Different FindView/Window functions iterating on the ROOT's windows/views.
314 NSArray *
const orderedWindows = [NSApp orderedWindows];
315 for (NSWindow *window in orderedWindows) {
318 QuartzWindow *
const qw = (QuartzWindow *)window;
333 assert(children != nil &&
"FindDNDAwareViewInPoint, parameter 'children' is nil");
338 NSEnumerator *
const reverseEnumerator = [children reverseObjectEnumerator];
339 for (NSView<X11Window> *child in reverseEnumerator) {
342 if (child.fIsDNDAware && child.fID != dragWinID && child.fID != inputWinID)
346 inputWinID, x, y, maxDepth - 1);
365 NSArray *
const orderedWindows = [NSApp orderedWindows];
366 for (NSWindow *window in orderedWindows) {
369 QuartzWindow *
const qw = (QuartzWindow *)window;
382 if (testView.fIsDNDAware && testView.fID != dragWinID && testView.fID != inputWinID)
386 NSArray *
const children = [testView subviews];
405 NSArray *
const orderedWindows = [NSApp orderedWindows];
406 for (NSWindow *nsWindow in orderedWindows) {
410 QuartzWindow *
const qWindow = (QuartzWindow *)nsWindow;
418 const NSPoint mousePosition = [qWindow mouseLocationOutsideOfEventStream];
419 const NSSize windowSize = qWindow.frame.size;
420 if (mousePosition.x >= 0 && mousePosition.x <= windowSize.width &&
421 mousePosition.y >= 0 && mousePosition.y <= windowSize.height)
435 const NSPoint mousePosition = [topLevel mouseLocationOutsideOfEventStream];
436 return (NSView<X11Window> *)[[topLevel contentView] hitTest : mousePosition];
449 assert(pointerEvent != nil &&
450 "FindWindowForPointerEvent, parameter 'pointerEvent' is nil");
454 NSArray *
const orderedWindows = [NSApp orderedWindows];
455 for (NSWindow *nsWindow in orderedWindows) {
459 QuartzWindow *
const qWindow = (QuartzWindow *)nsWindow;
468 NSPoint mousePosition = [pointerEvent locationInWindow];
471 if ([pointerEvent window]) {
481 const NSSize windowSize = qWindow.frame.size;
482 if (mousePosition.x >= 0 && mousePosition.x <= windowSize.width &&
483 mousePosition.y >= 0 && mousePosition.y <= windowSize.height)
496 assert(pointerEvent != nil &&
497 "FindViewForPointerEvent, parameter 'pointerEvent' is nil");
502 NSPoint mousePosition = [pointerEvent locationInWindow];
503 if ([pointerEvent window])
510 return (NSView<X11Window> *)[[topLevel contentView] hitTest : mousePosition];
516 #pragma mark - Downscale image ("reading color bits" on retina macs).
521 assert(w != 0 && h != 0 &&
"DownscaledImageData, invalid geometry");
522 assert(image !=
nullptr &&
"DonwscaledImageData, invalid parameter 'image'");
524 std::vector<unsigned char>
result;
526 result.resize(w * h * 4);
527 }
catch (
const std::bad_alloc &) {
529 NSLog(
@"DownscaledImageData, memory allocation failed");
535 if (!colorSpace.
Get()) {
536 NSLog(
@"DownscaledImageData, CGColorSpaceCreateDeviceRGB failed");
541 w * 4, colorSpace.
Get(),
542 kCGImageAlphaPremultipliedLast,
NULL, 0));
544 NSLog(
@"DownscaledImageData, CGBitmapContextCreateWithData failed");
548 CGContextDrawImage(ctx.
Get(), CGRectMake(0, 0, w, h),
image);
553 #pragma mark - "Focus management" - just make another window key window.
559 if (![NSApp isActive])
564 NSArray *
const orderedWindows = [NSApp orderedWindows];
565 for (NSWindow *nsWindow in orderedWindows) {
569 QuartzWindow *
const qWindow = (QuartzWindow *)nsWindow;
577 [qWindow makeKeyAndOrderFront : qWindow];
582 #pragma mark - 'shape mask' - to create a window with arbitrary (probably non-rectangle) shape.
587 assert(view != nil &&
"ClipToShapeMask, parameter 'view' is nil");
588 assert(ctx != 0 &&
"ClipToShapeMask, parameter 'ctx' is null");
592 "ClipToShapeMask, fShapeCombineMask is nil on a top-level window");
594 "ClipToShapeMask, shape mask is null");
600 if (!view.fParentView) {
606 NSRect clipRect = view.frame;
608 clipRect.origin = [view.fParentView convertPoint : clipRect.origin
609 toView : [view window].contentView];
611 clipRect.origin.y + clipRect.size.height);
616 NSRectToCGRect(clipRect)));
617 clipRect.origin = NSPoint();
618 CGContextClipToMask(ctx, NSRectToCGRect(clipRect), clipImageGuard.
Get());
622 CGContextClipToRect(ctx, rect);
627 #pragma mark - Window's geometry and attributes.
632 assert(attr != 0 &&
"SetWindowAttributes, parameter 'attr' is null");
633 assert(window != nil &&
"SetWindowAttributes, parameter 'window' is nil");
654 if ([(NSObject *)window isKindOfClass : [
QuartzWindow class]]) {
655 QuartzWindow *
const qw = (QuartzWindow *)window;
656 [qw setStyleMask : NSBorderlessWindowMask];
657 [qw setAlphaValue : 0.95];
660 window.fOverrideRedirect = YES;
667 assert(win != nil &&
"GetWindowGeometry, parameter 'win' is nil");
668 assert(dst != 0 &&
"GetWindowGeometry, parameter 'dst' is null");
680 assert(window != nil &&
"GetWindowAttributes, parameter 'window' is nil");
681 assert(dst != 0 &&
"GetWindowAttributes, parameter 'attr' is null");
690 dst->
fDepth = window.fDepth;
695 dst->
fClass = window.fClass;
729 #pragma mark - Comparators (I need them when changing a window's z-order).
733 #ifdef MAC_OS_X_VERSION_10_11
734 NSComparisonResult
CompareViewsToLower(__kindof NSView *view1, __kindof NSView *view2,
void *context)
739 id topView = (
id)context;
740 if (view1 == topView)
741 return NSOrderedAscending;
742 if (view2 == topView)
743 return NSOrderedDescending;
745 return NSOrderedSame;
750 #ifdef MAC_OS_X_VERSION_10_11
751 NSComparisonResult
CompareViewsToRaise(__kindof NSView *view1, __kindof NSView *view2,
void *context)
756 id topView = (
id)context;
757 if (view1 == topView)
758 return NSOrderedDescending;
759 if (view2 == topView)
760 return NSOrderedAscending;
762 return NSOrderedSame;
765 #pragma mark - Cursor's area.
770 assert(image != nil &&
"CursroHotSpot, parameter 'image' is nil");
772 const NSSize imageSize = image.size;
775 return NSMakePoint(imageSize.width, imageSize.height / 2);
777 return NSMakePoint(imageSize.width / 2, imageSize.height / 2);
784 const char *pngFileName = 0;
786 switch (currentCursor) {
788 pngFileName =
"move_cursor.png";
791 pngFileName =
"hor_arrow_cursor.png";
794 pngFileName =
"ver_arrow_cursor.png";
797 pngFileName =
"right_arrow_cursor.png";
800 pngFileName =
"rotate.png";
804 pngFileName =
"top_right_cursor.png";
808 pngFileName =
"top_left_cursor.png";
821 if (!path || path[0] == 0) {
826 NSString *nsPath = [NSString stringWithFormat : @"%s", path];
827 NSImage *
const cursorImage = [[NSImage alloc] initWithContentsOfFile : nsPath];
833 NSCursor *
const customCursor = [[[NSCursor alloc] initWithImage : cursorImage
834 hotSpot : hotSpot] autorelease];
836 [cursorImage release];
856 NSCursor *cursor = nil;
857 switch (currentCursor) {
859 cursor = [NSCursor crosshairCursor];
862 cursor = [NSCursor arrowCursor];
865 cursor = [NSCursor openHandCursor];
868 cursor = [NSCursor resizeLeftCursor];
871 cursor = [NSCursor resizeRightCursor];
874 cursor = [NSCursor resizeUpCursor];
877 cursor = [NSCursor resizeDownCursor];
880 cursor = [NSCursor IBeamCursor];
902 #pragma mark - Workarounds for a text view and its descendants.
916 assert(view != nil &&
"ViewIsTextView, parameter 'view' is nil");
924 assert(view != nil &&
"ViewIsTextViewFrame, parameter 'view' is nil");
936 if (!view.fParentView)
954 assert(view != nil &&
"ViewIsHtmlView, parameter 'view' is nil");
963 assert(view != nil &&
"ViewIsHtmlViewFrame, parameter 'view' is nil");
975 if (!view.fParentView)
984 assert(textView != nil &&
"FrameForTextView, parameter 'textView' is nil");
986 for (NSView<X11Window> *child in [textView subviews]) {
997 assert(htmlView != nil &&
"FrameForHtmlView, parameter 'htmlView' is nil");
999 for (NSView<X11Window> *child in [htmlView subviews]) {
1007 #pragma mark - Workarounds for 'paint out of paint events'.
1012 assert(view != nil &&
"LockFocus, parameter 'view' is nil");
1014 "LockFocus, QuartzView is expected");
1016 if ([view lockFocusIfCanDraw]) {
1017 NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
1018 assert(nsContext != nil &&
"LockFocus, currentContext is nil");
1019 CGContextRef currContext = (CGContextRef)[nsContext graphicsPort];
1020 assert(currContext != 0 &&
"LockFocus, graphicsPort is null");
1033 assert(view != nil &&
"UnlockFocus, parameter 'view' is nil");
1035 "UnlockFocus, QuartzView is expected");
1045 namespace Quartz = ROOT::Quartz;
1046 namespace Util = ROOT::MacOSX::Util;
1047 namespace X11 = ROOT::MacOSX::X11;
1049 #ifdef DEBUG_ROOT_COCOA
1051 #pragma mark - 'loggers'.
1061 static std::ofstream logfile(
"win_attr.txt");
1065 logfile<<
"win "<<winID<<
": BackPixmap\n";
1067 logfile<<
"win "<<winID<<
": BackPixel\n";
1069 logfile<<
"win "<<winID<<
": BorderPixmap\n";
1071 logfile<<
"win "<<winID<<
": BorderPixel\n";
1073 logfile<<
"win "<<winID<<
": BorderWidth\n";
1075 logfile<<
"win "<<winID<<
": BitGravity\n";
1077 logfile<<
"win "<<winID<<
": WinGravity\n";
1079 logfile<<
"win "<<winID<<
": BackingStore\n";
1081 logfile<<
"win "<<winID<<
": BackingPlanes\n";
1083 logfile<<
"win "<<winID<<
": BackingPixel\n";
1085 logfile<<
"win "<<winID<<
": OverrideRedirect\n";
1087 logfile<<
"win "<<winID<<
": SaveUnder\n";
1089 logfile<<
"win "<<winID<<
": EventMask\n";
1091 logfile<<
"win "<<winID<<
": DontPropagate\n";
1093 logfile<<
"win "<<winID<<
": Colormap\n";
1095 logfile<<
"win "<<winID<<
": Cursor\n";
1099 void print_mask_info(
ULong_t mask)
1102 NSLog(
@"button press mask");
1104 NSLog(
@"button release mask");
1105 if (mask & kExposureMask)
1106 NSLog(
@"exposure mask");
1108 NSLog(
@"pointer motion mask");
1110 NSLog(
@"button motion mask");
1112 NSLog(
@"enter notify mask");
1114 NSLog(
@"leave notify mask");
1126 #pragma mark - QuartzWindow's life cycle.
1129 - (
id) initWithContentRect : (NSRect) contentRect styleMask : (NSUInteger) windowStyle
1130 backing : (NSBackingStoreType) bufferingType defer : (BOOL) deferCreation
1133 self = [
super initWithContentRect : contentRect styleMask : windowStyle
1134 backing : bufferingType defer : deferCreation];
1138 [
self setAllowsConcurrentViewDrawing : NO];
1140 self.delegate =
self;
1142 NSRect contentViewRect = contentRect;
1143 contentViewRect.origin.x = 0.f;
1144 contentViewRect.origin.y = 0.f;
1150 [
self setContentView : fContentView];
1168 assert(glView != nil &&
"-initWithGLView, parameter 'glView' is nil");
1170 const NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
1171 NSMiniaturizableWindowMask | NSResizableWindowMask;
1173 NSRect contentRect = glView.frame;
1174 contentRect.origin = NSPoint();
1176 self = [
super initWithContentRect : contentRect styleMask : styleMask
1177 backing : NSBackingStoreBuffered defer : NO];
1181 [
self setAllowsConcurrentViewDrawing : NO];
1182 self.delegate =
self;
1184 [
self setContentView : fContentView];
1207 - (
void) setContentView:(NSView *)cv
1209 [
super setContentView:cv];
1217 - (
void) setFIsDeleted : (BOOL) deleted
1222 #pragma mark - Forwaring: I want to forward a lot of property setters/getters to the content view.
1225 - (
void) forwardInvocation : (NSInvocation *) anInvocation
1230 if ([
fContentView respondsToSelector : [anInvocation selector]]) {
1231 [anInvocation invokeWithTarget : fContentView];
1233 [
super forwardInvocation : anInvocation];
1238 - (NSMethodSignature*) methodSignatureForSelector : (
SEL) selector
1240 NSMethodSignature *signature = [
super methodSignatureForSelector : selector];
1244 signature = [
fContentView methodSignatureForSelector : selector];
1259 assert(window != nil &&
"-addTransientWindow:, parameter 'window' is nil");
1268 [
self addChildWindow : window ordered : NSWindowAbove];
1274 - (
void) makeKeyAndOrderFront : (
id) sender
1276 #pragma unused(sender)
1281 #ifdef MAC_OS_X_VERSION_10_9
1282 [
self setCollectionBehavior : NSWindowCollectionBehaviorMoveToActiveSpace];
1284 [
self setCollectionBehavior : NSWindowCollectionBehaviorCanJoinAllSpaces];
1287 [
super makeKeyAndOrderFront : self];
1289 [
self setCollectionBehavior : NSWindowCollectionBehaviorDefault];
1293 - (
void) setFDelayedTransient : (BOOL) d
1308 [fShapeCombineMask release];
1317 #pragma mark - X11Drawable's protocol.
1348 return self.frame.size.width;
1363 - (
void) setDrawableSize : (NSSize) newSize
1366 assert(!(newSize.width < 0) &&
"-setDrawableSize:, width is negative");
1367 assert(!(newSize.height < 0) &&
"-setDrawableSize:, height is negative");
1369 NSRect frame =
self.frame;
1373 frame.origin.y = frame.origin.y + frame.size.height - newSize.height - dY;
1374 frame.size = newSize;
1375 frame.size.height += dY;
1376 [
self setFrame : frame display : YES];
1380 - (
void) setX : (
int) x Y : (
int) y width : (
unsigned) w height : (
unsigned) h
1382 NSSize newSize = {};
1385 [
self setContentSize : newSize];
1388 NSPoint topLeft = {};
1392 [
self setFrameTopLeftPoint : topLeft];
1396 - (
void) setX : (
int) x Y : (
int) y
1398 NSPoint topLeft = {};
1402 [
self setFrameTopLeftPoint : topLeft];
1407 clipOrigin : (X11::Point) clipXY toPoint : (X11::Point) dstPoint
1412 [
fContentView copy : src area : area withMask : mask clipOrigin : clipXY toPoint : dstPoint];
1416 - (
unsigned char *) readColorBits : (X11::Rectangle) area
1424 #pragma mark - X11Window protocol's implementation.
1435 #pragma unused(parent)
1453 - (
void) setFBackgroundPixel : (
unsigned long) backgroundColor
1459 CGFloat rgba[] = {0., 0., 0., 1.};
1462 [
self setBackgroundColor : [NSColor colorWithColorSpace : [NSColorSpace deviceRGBColorSpace] components : rgba count : 4]];
1493 assert(child != nil &&
"-addChild:, parameter 'child' is nil");
1498 "-addChild: gl view in a top-level window as content view is not supported");
1501 [
self setContentView : child];
1513 assert(attr &&
"-getAttributes:, parameter 'attr' is nil");
1521 assert(attr != 0 &&
"-setAttributes:, parameter 'attr' is null");
1523 #ifdef DEBUG_ROOT_COCOA
1524 log_attributes(attr,
self.
fID);
1536 const Util::AutoreleasePool pool;
1539 [
self makeKeyAndOrderFront : self];
1544 [
fMainWindow addChildWindow : self ordered : NSWindowAbove];
1554 const Util::AutoreleasePool pool;
1557 [
self makeKeyAndOrderFront : self];
1562 [
fMainWindow addChildWindow : self ordered : NSWindowAbove];
1572 const Util::AutoreleasePool pool;
1585 [
self orderOut : self];
1593 #pragma mark - Events.
1596 - (
void) sendEvent : (NSEvent *) theEvent
1605 if (theEvent.type == NSLeftMouseDown || theEvent.type == NSRightMouseDown) {
1606 bool generateFakeRelease =
false;
1608 const NSPoint windowPoint = [theEvent locationInWindow];
1610 if (windowPoint.x <= 4 || windowPoint.x >=
self.fWidth - 4)
1611 generateFakeRelease =
true;
1613 if (windowPoint.y <= 4 || windowPoint.y >=
self.fHeight - 4)
1614 generateFakeRelease =
true;
1616 const NSPoint viewPoint = [fContentView convertPoint : windowPoint fromView : nil];
1618 if (viewPoint.y <= 0 && windowPoint.y >= 0)
1619 generateFakeRelease =
true;
1622 "-sendEvent:, gVirtualX is either null or not of TGCocoa type");
1627 theEvent.type == NSLeftMouseDown ?
1636 [
super sendEvent : theEvent];
1639 #pragma mark - NSWindowDelegate's methods.
1642 - (BOOL) windowShouldClose : (
id) sender
1644 #pragma unused(sender)
1653 if ([[
self childWindows] count])
1665 "-windowShouldClose:, gVirtualX is either null or has a type different from TGCocoa");
1674 - (
void) windowDidBecomeKey : (NSNotification *) aNotification
1676 #pragma unused(aNotification)
1685 "-windowDidBecomeKey:, gVirtualX is null or not of TGCocoa type");
1693 - (
void) windowDidResignKey : (NSNotification *) aNotification
1695 #pragma unused(aNotification)
1701 #pragma mark - Passive key grab info.
1706 - (
id) initWithKey : (unichar) keyCode modifiers : (NSUInteger) modifiers
1708 if (
self = [super
init]) {
1717 - (BOOL) matchKey : (unichar) keyCode modifiers : (NSUInteger) modifiers
1723 - (BOOL) matchKey : (unichar) keyCode
1742 #pragma mark - X11 property emulation.
1744 @interface QuartzWindowProperty : NSObject {
1745 NSData *fPropertyData;
1754 @implementation QuartzWindowProperty
1759 - (
id) initWithData : (
unsigned char *) data size : (
unsigned) dataSize type : (
Atom_t) type format : (
unsigned) format
1761 if (
self = [super
init]) {
1763 fPropertyData = nil;
1767 [
self resetPropertyData : data size : dataSize type : type format : format];
1776 [fPropertyData release];
1782 - (
void) resetPropertyData : (
unsigned char *) data size : (
unsigned) dataSize
1783 type : (
Atom_t) type format : (
unsigned) format
1785 [fPropertyData release];
1790 else if (format == 32)
1793 fPropertyData = [[NSData dataWithBytes : data length : dataSize] retain];
1799 - (NSData *) fPropertyData
1801 return fPropertyData;
1805 - (unsigned) fFormat
1812 #pragma mark - QuartzView.
1845 #pragma mark - Lifetime.
1850 if (
self = [super initWithFrame : frame]) {
1862 [
self setCanDrawConcurrently : NO];
1864 [
self setHidden : YES];
1884 [fBackBuffer release];
1885 [fPassiveKeyGrabs release];
1886 [fX11Properties release];
1887 [fBackgroundPixmap release];
1891 #pragma mark - Tracking area.
1896 - (
void) updateTrackingAreas
1898 [
super updateTrackingAreas];
1903 const Util::AutoreleasePool pool;
1905 if (NSArray *trackingArray = [
self trackingAreas]) {
1906 const NSUInteger size = [trackingArray count];
1907 for (NSUInteger i = 0; i < size; ++i) {
1908 NSTrackingArea *
const t = [trackingArray objectAtIndex : i];
1909 [
self removeTrackingArea : t];
1913 const NSUInteger trackerOptions = NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited |
1914 NSTrackingActiveInActiveApp | NSTrackingInVisibleRect |
1915 NSTrackingEnabledDuringMouseDrag | NSTrackingCursorUpdate;
1918 frame.size.width =
self.fWidth;
1919 frame.size.height =
self.fHeight;
1921 NSTrackingArea *
const tracker = [[NSTrackingArea alloc] initWithRect : frame
1922 options : trackerOptions owner : self userInfo : nil];
1923 [
self addTrackingArea : tracker];
1928 - (
void) updateTrackingAreasAfterRaise
1930 [
self updateTrackingAreas];
1932 for (
QuartzView *childView in [
self subviews])
1933 [childView updateTrackingAreasAfterRaise];
1936 #pragma mark - X11Drawable protocol.
1953 return self.frame.origin.x;
1959 return self.frame.origin.y;
1965 return self.frame.size.width;
1971 return self.frame.size.height;
1975 - (
void) setDrawableSize : (NSSize) newSize
1977 assert(!(newSize.width < 0) &&
"-setDrawableSize, width is negative");
1978 assert(!(newSize.height < 0) &&
"-setDrawableSize, height is negative");
1984 NSRect frame =
self.frame;
1985 frame.size = newSize;
1991 - (
void) setX : (
int) x Y : (
int) y width : (
unsigned) w height : (
unsigned) h
1993 NSRect newFrame = {};
1994 newFrame.origin.x =
x;
1995 newFrame.origin.y =
y;
1996 newFrame.size.width =
w;
1997 newFrame.size.height =
h;
1999 self.frame = newFrame;
2003 - (
void) setX : (
int) x Y : (
int) y
2005 NSRect newFrame =
self.frame;
2006 newFrame.origin.x =
x;
2007 newFrame.origin.y =
y;
2009 self.frame = newFrame;
2013 - (
void) copyImage : (
QuartzImage *) srcImage area : (X11::Rectangle) area
2014 withMask : (
QuartzImage *) mask clipOrigin : (X11::Point) clipXY
2015 toPoint : (X11::Point) dstPoint
2018 assert(srcImage != nil &&
2019 "-copyImage:area:withMask:clipOrigin:toPoint:, parameter 'srcImage' is nil");
2021 "-copyImage:area:withMask:clipOrigin:toPoint:, srcImage.fImage is nil");
2025 "-copyImage:area:withMask:clipOrigin:toPoint:, self.fContext is null");
2028 NSLog(
@"QuartzView: -copyImage:area:withMask:clipOrigin:toPoint:,"
2029 " srcRect and copyRect do not intersect");
2035 CGImageRef subImage = 0;
2036 bool needSubImage =
false;
2037 if (area.fX || area.fY || area.fWidth != srcImage.
fWidth || area.fHeight != srcImage.
fHeight) {
2038 needSubImage =
true;
2041 NSLog(
@"QuartzView: -copyImage:area:withMask:clipOrigin:toPoint:,"
2042 " subimage creation failed");
2046 subImage = srcImage.
fImage;
2053 CGContextScaleCTM(
self.
fContext, 1., -1.);
2058 "-copyImage:area:withMask:clipOrigin:toPoint:, mask.fImage is nil");
2060 "-copyImage:area:withMask:clipOrigin:toPoint:, mask.fImage is not a mask");
2064 const CGRect clipRect = CGRectMake(clipXY.fX, clipY, mask.
fWidth, mask.
fHeight);
2072 const CGRect imageRect = CGRectMake(dstPoint.fX, dstY, area.fWidth, area.fHeight);
2073 CGContextDrawImage(
self.
fContext, imageRect, subImage);
2076 CGImageRelease(subImage);
2080 - (
void) copyView : (
QuartzView *) srcView area : (X11::Rectangle) area toPoint : (X11::Point) dstPoint
2087 assert(srcView != nil &&
"-copyView:area:toPoint:, parameter 'srcView' is nil");
2089 const NSRect frame = [srcView frame];
2091 NSBitmapImageRep *
const imageRep = [srcView bitmapImageRepForCachingDisplayInRect : frame];
2093 NSLog(
@"QuartzView: -copyView:area:toPoint failed");
2097 assert(srcView != nil &&
"-copyView:area:toPoint:, parameter 'srcView' is nil");
2098 assert(
self.
fContext != 0 &&
"-copyView:area:toPoint, self.fContext is null");
2103 CGContextRef ctx = srcView.
fContext;
2105 [srcView cacheDisplayInRect : frame toBitmapImageRep : imageRep];
2109 const CGRect subImageRect = CGRectMake(area.fX, area.fY, area.fWidth, area.fHeight);
2110 const Util::CFScopeGuard<CGImageRef> subImage(CGImageCreateWithImageInRect(imageRep.CGImage, subImageRect));
2112 if (!subImage.Get()) {
2113 NSLog(
@"QuartzView: -copyView:area:toPoint, CGImageCreateWithImageInRect failed");
2118 const CGRect imageRect = CGRectMake(dstPoint.fX,
2119 [
self visibleRect].size.height - (CGFloat(dstPoint.fY) + area.fHeight),
2120 area.fWidth, area.fHeight);
2122 CGContextTranslateCTM(
self.
fContext, 0., [
self visibleRect].size.height);
2123 CGContextScaleCTM(
self.
fContext, 1., -1.);
2125 CGContextDrawImage(
self.
fContext, imageRect, subImage.Get());
2129 - (
void) copyPixmap : (
QuartzPixmap *) srcPixmap area : (X11::Rectangle) area
2130 withMask : (
QuartzImage *) mask clipOrigin : (X11::Point) clipXY toPoint : (X11::Point) dstPoint
2133 assert(srcPixmap != nil &&
"-copyPixmap:area:withMask:clipOrigin:toPoint:, parameter 'srcPixmap' is nil");
2136 NSLog(
@"QuartzView: -copyPixmap:area:withMask:clipOrigin:toPoint,"
2137 " no intersection between pixmap rectangle and cropArea");
2143 "-copyPixmap:area:withMask:clipOrigin:toPoint:, self.fContext is null");
2148 CGContextTranslateCTM(
self.
fContext, 0.,
self.frame.size.height);
2149 CGContextScaleCTM(
self.
fContext, 1., -1.);
2151 const Util::CFScopeGuard<CGImageRef> imageFromPixmap([srcPixmap createImageFromPixmap]);
2152 assert(imageFromPixmap.Get() != 0 &&
2153 "-copyPixmap:area:withMask:clipOrigin:toPoint:, createImageFromPixmap failed");
2155 CGImageRef subImage = 0;
2156 bool needSubImage =
false;
2157 if (area.fX || area.fY || area.fWidth != srcPixmap.
fWidth || area.fHeight != srcPixmap.
fHeight) {
2158 needSubImage =
true;
2159 const CGRect subImageRect = CGRectMake(area.fX, area.fY, area.fHeight, area.fWidth);
2160 subImage = CGImageCreateWithImageInRect(imageFromPixmap.Get(), subImageRect);
2162 NSLog(
@"QuartzView: -copyImage:area:withMask:clipOrigin:toPoint:,"
2163 " subimage creation failed");
2167 subImage = imageFromPixmap.Get();
2171 "-copyPixmap:area:withMask:clipOrigin:toPoint:, mask.fImage is nil");
2173 "-copyPixmap:area:withMask:clipOrigin:toPoint:, mask.fImage is not a mask");
2178 const CGRect clipRect = CGRectMake(clipXY.fX, clipY, mask.
fWidth, mask.
fHeight);
2184 const CGRect imageRect = CGRectMake(dstPoint.fX, dstY, area.fWidth, area.fHeight);
2185 CGContextDrawImage(
self.
fContext, imageRect, imageFromPixmap.Get());
2188 CGImageRelease(subImage);
2193 - (
void) copyImage : (
QuartzImage *) srcImage area : (X11::Rectangle) area
2194 toPoint : (X11::Point) dstPoint
2196 assert(srcImage != nil &&
"-copyImage:area:toPoint:, parameter 'srcImage' is nil");
2197 assert(srcImage.
fImage != nil &&
"-copyImage:area:toPoint:, srcImage.fImage is nil");
2198 assert(
self.
fContext != 0 &&
"-copyImage:area:toPoint:, fContext is null");
2201 NSLog(
@"QuartzView: -copyImage:area:toPoint, image and copy area do not intersect");
2205 CGImageRef subImage = 0;
2206 bool needSubImage =
false;
2207 if (area.fX || area.fY || area.fWidth != srcImage.
fWidth || area.fHeight != srcImage.
fHeight) {
2208 needSubImage =
true;
2211 NSLog(
@"QuartzView: -copyImage:area:toPoint:, subimage creation failed");
2215 subImage = srcImage.
fImage;
2220 CGContextScaleCTM(
self.
fContext, 1., -1.);
2225 const CGRect imageRect = CGRectMake(dstPoint.fX, dstY, area.fWidth, area.fHeight);
2226 CGContextDrawImage(
self.
fContext, imageRect, subImage);
2229 CGImageRelease(subImage);
2234 withMask : (
QuartzImage *)mask clipOrigin : (X11::Point) clipXY toPoint : (X11::Point) dstPoint
2236 assert(src != nil &&
"-copy:area:withMask:clipOrigin:toPoint:, parameter 'src' is nil");
2237 assert(area.fWidth && area.fHeight &&
"-copy:area:withMask:clipOrigin:toPoint:, area to copy is empty");
2241 QuartzWindow *
const qw = (QuartzWindow *)src;
2243 [
self copyView : (QuartzView *)qw.fContentView area : area toPoint : dstPoint];
2244 }
else if ([src isKindOfClass : [
QuartzView class]]) {
2246 [
self copyView : (QuartzView *)src area : area toPoint : dstPoint];
2247 }
else if ([src isKindOfClass : [
QuartzPixmap class]]) {
2248 [
self copyPixmap : (QuartzPixmap *)src area : area withMask : mask clipOrigin : clipXY toPoint : dstPoint];
2249 }
else if ([src isKindOfClass : [
QuartzImage class]]) {
2250 [
self copyImage : (QuartzImage *)src area : area withMask : mask clipOrigin : clipXY toPoint : dstPoint];
2252 assert(0 &&
"-copy:area:withMask:clipOrigin:toPoint:, src is of unknown type");
2257 - (
unsigned char *) readColorBits : (X11::Rectangle) area
2263 assert(area.fWidth && area.fHeight &&
"-readColorBits:, area to copy is empty");
2266 const NSRect visRect = [
self visibleRect];
2267 const X11::Rectangle srcRect(
int(visRect.origin.x),
int(visRect.origin.y),
2268 unsigned(visRect.size.width),
unsigned(visRect.size.height));
2271 NSLog(
@"QuartzView: -readColorBits:, visible rect of view and copy area do not intersect");
2276 NSBitmapImageRep *
const imageRep = [
self bitmapImageRepForCachingDisplayInRect : visRect];
2278 NSLog(
@"QuartzView: -readColorBits:, bitmapImageRepForCachingDisplayInRect failed");
2282 CGContextRef ctx =
self.fContext;
2283 [
self cacheDisplayInRect : visRect toBitmapImageRep : imageRep];
2284 self.fContext = ctx;
2286 const NSInteger bitsPerPixel = [imageRep bitsPerPixel];
2288 assert(bitsPerPixel == 32 &&
"-readColorBits:, no alpha channel???");
2289 const NSInteger bytesPerRow = [imageRep bytesPerRow];
2290 unsigned dataWidth = bytesPerRow / (bitsPerPixel / 8);
2292 unsigned char *srcData =
nullptr;
2293 std::vector<unsigned char> downscaled;
2294 if ([[NSScreen mainScreen] backingScaleFactor] > 1 && imageRep.CGImage) {
2296 if (downscaled.size())
2297 srcData = &downscaled[0];
2298 dataWidth = area.fWidth;
2300 srcData = [imageRep bitmapData];
2303 NSLog(
@"QuartzView: -readColorBits:, failed to obtain backing store contents");
2308 unsigned char *data =
nullptr;
2311 data =
new unsigned char[area.fWidth * area.fHeight * 4];
2312 }
catch (
const std::bad_alloc &) {
2313 NSLog(
@"QuartzView: -readColorBits:, memory allocation failed");
2317 unsigned char *dstPixel = data;
2318 const unsigned char *
line = srcData + area.fY * dataWidth * 4;
2319 const unsigned char *srcPixel = line + area.fX * 4;
2321 for (
unsigned i = 0; i < area.fHeight; ++i) {
2322 for (
unsigned j = 0; j < area.fWidth; ++j, srcPixel += 4, dstPixel += 4) {
2323 dstPixel[0] = srcPixel[2];
2324 dstPixel[1] = srcPixel[1];
2325 dstPixel[2] = srcPixel[0];
2326 dstPixel[3] = srcPixel[3];
2329 line += dataWidth * 4;
2330 srcPixel = line + area.fX * 4;
2340 [fBackgroundPixmap release];
2359 if ([
self isHidden])
2363 if ([parent isHidden])
2381 - (
void) setFHasFocus : (BOOL) focus
2383 #pragma unused(focus)
2400 [fBackBuffer release];
2434 - (
void) activateGrab : (
unsigned) eventMask ownerEvents : (BOOL) ownerEvents
2450 - (BOOL) acceptsCrossingEvents : (
unsigned) eventMask
2471 assert(child != nil &&
"-addChild:, parameter 'child' is nil");
2473 [
self addSubview : child];
2480 assert(attr != 0 &&
"-getAttributes:, parameter 'attr' is null");
2488 assert(attr != 0 &&
"-setAttributes:, parameter 'attr' is null");
2490 #ifdef DEBUG_ROOT_COCOA
2491 log_attributes(attr,
fID);
2502 [
self removeFromSuperview];
2503 [parent addSubview : self];
2504 [
self setHidden : NO];
2510 [
self setHidden : NO];
2523 [
self setHidden : YES];
2533 - (
void) setOverlapped : (BOOL) overlap
2536 for (NSView<X11Window> *child in [
self subviews])
2537 [child setOverlapped : overlap];
2554 using namespace X11;
2557 if (
self == sibling)
2559 if ([sibling isHidden])
2562 if (NSEqualRects(sibling.frame,
self.frame)) {
2563 [sibling setOverlapped : YES];
2564 [sibling setHidden : YES];
2570 [
self setHidden : NO];
2572 [
fParentView sortSubviewsUsingFunction : CompareViewsToRaise context : (void *)self];
2574 [
self updateTrackingAreasAfterRaise];
2576 [
self setNeedsDisplay : YES];
2584 using namespace X11;
2586 NSEnumerator *
const reverseEnumerator = [[
fParentView subviews] reverseObjectEnumerator];
2587 for (
QuartzView *sibling in reverseEnumerator) {
2588 if (sibling ==
self)
2592 if (NSEqualRects(sibling.frame,
self.frame)) {
2593 [sibling setOverlapped : NO];
2595 [sibling setHidden : NO];
2597 [sibling setNeedsDisplay : YES];
2600 [
self setHidden : YES];
2606 [
fParentView sortSubviewsUsingFunction : CompareViewsToLower context : (void*)self];
2623 "-configureNotifyTree, gVirtualX is either null or has type different from TGCocoa");
2628 for (NSView<X11Window> *
v in [
self subviews])
2629 [v configureNotifyTree];
2633 #pragma mark - Key grabs.
2636 - (
void) addPassiveKeyGrab : (unichar) keyCode modifiers : (NSUInteger) modifiers
2638 [
self removePassiveKeyGrab : keyCode modifiers : modifiers];
2640 modifiers : modifiers];
2646 - (
void) removePassiveKeyGrab : (unichar) keyCode modifiers : (NSUInteger) modifiers
2649 for (NSUInteger i = 0; i < count; ++i) {
2651 if ([grab matchKey : keyCode modifiers : modifiers]) {
2659 - (
PassiveKeyGrab *) findPassiveKeyGrab : (unichar) keyCode modifiers : (NSUInteger) modifiers
2663 if ([grab matchKey : keyCode modifiers : modifiers])
2676 if ([grab matchKey : keyCode])
2683 #pragma mark - Painting mechanics.
2686 - (
void) drawRect : (NSRect) dirtyRect
2688 #pragma unused(dirtyRect)
2690 using namespace X11;
2698 NSGraphicsContext *
const nsContext = [NSGraphicsContext currentContext];
2699 assert(nsContext != nil &&
"-drawRect:, currentContext returned nil");
2704 fContext = (CGContextRef)[nsContext graphicsPort];
2705 assert(
fContext != 0 &&
"-drawRect:, graphicsPort returned null");
2736 gClient->CancelRedraw(window);
2744 [
self copy : fBackBuffer area : copyArea withMask : nil
2745 clipOrigin : X11::Point() toPoint : X11::Point()];
2749 #ifdef DEBUG_ROOT_COCOA
2750 CGContextSetRGBStrokeColor(
fContext, 1., 0., 0., 1.);
2751 CGContextStrokeRect(
fContext, dirtyRect);
2756 #ifdef DEBUG_ROOT_COCOA
2757 NSLog(
@"QuartzView: -drawRect: method, no window for id %u was found",
fID);
2763 #pragma mark - Geometry.
2766 - (
void) setFrame : (NSRect) newFrame
2771 if (NSEqualRects(newFrame,
self.frame))
2774 [
super setFrame : newFrame];
2778 - (
void) setFrameSize : (NSSize) newSize
2782 [
super setFrameSize : newSize];
2786 "setFrameSize:, gVirtualX is either null or has a type, different from TGCocoa");
2791 [
self setNeedsDisplay : YES];
2794 #pragma mark - Event handling.
2797 - (
void) mouseDown : (NSEvent *) theEvent
2799 assert(
fID != 0 &&
"-mouseDown:, fID is 0");
2802 "-mouseDown:, gVirtualX is either null or has a type, different from TGCocoa");
2808 - (
void) scrollWheel : (NSEvent*) theEvent
2810 assert(
fID != 0 &&
"-scrollWheel:, fID is 0");
2814 "-scrollWheel:, gVirtualX is either null or has a type, different from TGCocoa");
2817 const CGFloat deltaY = [theEvent deltaY];
2821 }
else if (deltaY > 0) {
2827 #ifdef DEBUG_ROOT_COCOA
2829 - (
void) printViewInformation
2831 assert(
fID != 0 &&
"-printWindowInformation, fID is 0");
2833 assert(window != 0 &&
"printWindowInformation, window not found");
2835 NSLog(
@"-----------------View %u info:---------------------",
fID);
2836 NSLog(
@"ROOT's window class is %s", window->IsA()->
GetName());
2837 NSLog(
@"event mask is:");
2839 NSLog(
@"grab mask is:");
2841 NSLog(
@"view's geometry: x == %g, y == %g, w == %g, h == %g",
self.frame.origin.x,
2842 self.frame.origin.y,
self.frame.size.width,
self.frame.size.height);
2843 NSLog(
@"----------------End of view info------------------");
2848 - (
void) rightMouseDown : (NSEvent *) theEvent
2850 assert(
fID != 0 &&
"-rightMouseDown:, fID is 0");
2852 #ifdef DEBUG_ROOT_COCOA
2853 [
self printViewInformation];
2857 "-rightMouseDown:, gVirtualX is either null or has type different from TGCocoa");
2863 - (
void) otherMouseDown : (NSEvent *) theEvent
2865 assert(
fID != 0 &&
"-otherMouseDown:, fID is 0");
2869 if ([theEvent buttonNumber] == 2) {
2873 "-otherMouseDown:, gVirtualX is either null or has type different from TGCocoa");
2880 - (
void) mouseUp : (NSEvent *) theEvent
2882 assert(
fID != 0 &&
"-mouseUp:, fID is 0");
2885 "-mouseUp:, gVirtualX is either null or has type different from TGCocoa");
2891 - (
void) rightMouseUp : (NSEvent *) theEvent
2894 assert(
fID != 0 &&
"-rightMouseUp:, fID is 0");
2897 "-rightMouseUp:, gVirtualX is either null or has type different from TGCocoa");
2904 - (
void) otherMouseUp : (NSEvent *) theEvent
2906 assert(
fID != 0 &&
"-otherMouseUp:, fID is 0");
2910 "-otherMouseUp:, gVirtualX is either null or has type different from TGCocoa");
2916 - (
void) mouseEntered : (NSEvent *) theEvent
2918 assert(
fID != 0 &&
"-mouseEntered:, fID is 0");
2920 "-mouseEntered:, gVirtualX is null or not of TGCocoa type");
2927 - (
void) mouseExited : (NSEvent *) theEvent
2929 assert(
fID != 0 &&
"-mouseExited:, fID is 0");
2932 "-mouseExited:, gVirtualX is null or not of TGCocoa type");
2939 - (
void) mouseMoved : (NSEvent *) theEvent
2941 assert(
fID != 0 &&
"-mouseMoved:, fID is 0");
2947 "-mouseMoved:, gVirtualX is null or not of TGCocoa type");
2954 - (
void) mouseDragged : (NSEvent *) theEvent
2956 assert(
fID != 0 &&
"-mouseDragged:, fID is 0");
2959 assert(vx != 0 &&
"-mouseDragged:, gVirtualX is null or not of TGCocoa type");
2965 - (
void) rightMouseDragged : (NSEvent *) theEvent
2967 assert(
fID != 0 &&
"-rightMouseDragged:, fID is 0");
2970 "-rightMouseDragged:, gVirtualX is null or not of TGCocoa type");
2977 - (
void) otherMouseDragged : (NSEvent *) theEvent
2979 assert(
fID != 0 &&
"-otherMouseDragged:, fID is 0");
2981 if ([theEvent buttonNumber] == 2) {
2983 "-otherMouseDragged:, gVirtualX is null or not of TGCocoa type");
2990 - (
void) keyDown : (NSEvent *) theEvent
2992 assert(
fID != 0 &&
"-keyDown:, fID is 0");
2995 "-keyDown:, gVirtualX is null or not of TGCocoa type");
2997 NSView<X11Window> *eventView =
self;
2999 eventView = pointerView;
3006 - (
void) keyUp : (NSEvent *) theEvent
3008 assert(
fID != 0 &&
"-keyUp:, fID is 0");
3011 "-keyUp:, gVirtualX is null or not of TGCocoa type");
3014 NSView<X11Window> *eventView =
self;
3016 eventView = pointerView;
3021 #pragma mark - First responder stuff.
3024 - (BOOL) acceptsFirstMouse : (NSEvent *) theEvent
3026 #pragma unused(theEvent)
3031 - (BOOL) acceptsFirstResponder
3036 #pragma mark - Cursors.
3043 [
self.fQuartzWindow invalidateCursorRectsForView : self];
3048 - (NSCursor *) createCustomCursor
3050 const char *pngFileName = 0;
3054 pngFileName =
"move_cursor.png";
3057 pngFileName =
"hor_arrow_cursor.png";
3060 pngFileName =
"ver_arrow_cursor.png";
3063 pngFileName =
"right_arrow_cursor.png";
3066 pngFileName =
"rotate.png";
3070 pngFileName =
"top_right_cursor.png";
3074 pngFileName =
"top_left_cursor.png";
3085 const Util::ScopedArray<const char> arrayGuard(path);
3087 if (!path || path[0] == 0) {
3092 NSString *nsPath = [NSString stringWithFormat : @"%s", path];
3093 NSImage *
const cursorImage = [[NSImage alloc] initWithContentsOfFile : nsPath];
3099 NSCursor *
const customCursor = [[[NSCursor alloc] initWithImage : cursorImage
3100 hotSpot : hotSpot] autorelease];
3102 [cursorImage release];
3104 return customCursor;
3111 - (
void) resetCursorRects
3114 [
self addCursorRect : self.visibleRect cursor : cursor];
3118 - (
void) cursorUpdate
3128 - (
void) cursorUpdate : (NSEvent *) event
3130 #pragma unused(event)
3142 [
self performSelector : @selector(cursorUpdate) withObject : nil afterDelay : 0.05f];
3145 #pragma mark - Emulated X11 properties.
3148 - (
void) setProperty : (const
char *) propName data : (
unsigned char *) propData
3149 size : (
unsigned) dataSize forType : (
Atom_t) dataType format : (
unsigned) format
3151 assert(propName != 0 &&
"-setProperty:data:size:forType:, parameter 'propName' is null");
3152 assert(propData != 0 &&
"-setProperty:data:size:forType:, parameter 'propData' is null");
3153 assert(dataSize != 0 &&
"-setProperty:data:size:forType:, parameter 'dataSize' is 0");
3155 NSString *
const key = [NSString stringWithCString : propName encoding : NSASCIIStringEncoding];
3156 QuartzWindowProperty *
property = (QuartzWindowProperty *)[
fX11Properties valueForKey : key];
3160 [property resetPropertyData : propData size : dataSize type : dataType format : format];
3163 property = [[QuartzWindowProperty alloc] initWithData : propData size : dataSize
3164 type : dataType format : format];
3171 - (BOOL) hasProperty : (const
char *) propName
3173 assert(propName != 0 &&
"-hasProperty:, propName parameter is null");
3175 NSString *
const key = [NSString stringWithCString : propName encoding : NSASCIIStringEncoding];
3176 QuartzWindowProperty *
const property = (QuartzWindowProperty *)[
fX11Properties valueForKey : key];
3178 return property != nil;
3182 - (
unsigned char *) getProperty : (const
char *) propName returnType : (
Atom_t *) type
3183 returnFormat : (
unsigned *) format nElements : (
unsigned *) nElements
3186 "-getProperty:returnType:returnFormat:nElements:, parameter 'propName' is null");
3188 "-getProperty:returnType:returnFormat:nElements:, parameter 'type' is null");
3190 "-getProperty:returnType:returnFormat:nElements:, parameter 'format' is null");
3192 "-getProperty:returnType:returnFormat:nElements:, parameter 'nElements' is null");
3194 NSString *
const key = [NSString stringWithCString : propName encoding : NSASCIIStringEncoding];
3195 QuartzWindowProperty *
const property = (QuartzWindowProperty *)[
fX11Properties valueForKey : key];
3197 "-getProperty:returnType:returnFormat:nElements, property not found");
3199 NSData *
const propData =
property.fPropertyData;
3201 const NSUInteger dataSize = [propData length];
3202 unsigned char *buff = 0;
3204 buff =
new unsigned char[dataSize]();
3205 }
catch (
const std::bad_alloc &) {
3207 NSLog(
@"QuartzWindow: -getProperty:returnType:returnFormat:nElements:,"
3208 " memory allocation failed");
3212 [propData getBytes : buff length : dataSize];
3213 *format =
property.fFormat;
3215 *nElements = dataSize;
3218 *nElements= dataSize / 2;
3219 else if (*format == 32)
3220 *nElements = dataSize / 4;
3222 *type =
property.fType;
3228 - (
void) removeProperty : (const
char *) propName
3230 assert(propName != 0 &&
"-removeProperty:, parameter 'propName' is null");
3232 NSString *
const key = [NSString stringWithCString : propName
3233 encoding : NSASCIIStringEncoding];
3239 - (NSDragOperation) draggingEntered : (
id<NSDraggingInfo>) sender
3241 NSPasteboard *
const pasteBoard = [sender draggingPasteboard];
3242 const NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
3244 if ([[pasteBoard types] containsObject : NSFilenamesPboardType] && (sourceDragMask & NSDragOperationCopy))
3245 return NSDragOperationCopy;
3247 return NSDragOperationNone;
3251 - (BOOL) performDragOperation : (
id<NSDraggingInfo>) sender
3262 NSPasteboard *
const pasteBoard = [sender draggingPasteboard];
3263 const NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
3265 if ([[pasteBoard types] containsObject : NSFilenamesPboardType] && (sourceDragMask & NSDragOperationCopy)) {
3271 NSArray *
const files = [pasteBoard propertyListForType : NSFilenamesPboardType];
3272 for (NSString *path in files) {
3274 NSString *
const item = [@"file://" stringByAppendingString : path];
3276 const NSUInteger len = [item lengthOfBytesUsingEncoding : NSASCIIStringEncoding] + 1;
3278 std::vector<unsigned char> propertyData(len);
3279 [item getCString : (char *)&propertyData[0] maxLength : propertyData.size()
3280 encoding : NSASCIIStringEncoding];
3282 NSView<X11Window> *
const targetView =
self.fQuartzWindow.fContentView;
3283 [targetView setProperty : "_XC_DND_DATA" data : &propertyData[0]
3284 size : propertyData.size() forType : textUriAtom format : 8];
3285 }
catch (
const std::bad_alloc &) {
3287 NSLog(
@"QuartzView: -performDragOperation:, memory allocation failed");
3303 event1.
fUser[2] = textUriAtom;
3313 event2.
fUser[2] = 0;
3314 NSPoint dropPoint = [sender draggingLocation];
3317 dropPoint = [
self convertPoint : dropPoint fromView : nil];
std::vector< unsigned char > DownscaledImageData(unsigned w, unsigned h, CGImageRef image)
int GlobalXCocoaToROOT(CGFloat xCocoa)
void GenerateConfigureNotifyEvent(NSView< X11Window > *view, const NSRect &newFrame)
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)
NSView< X11Window > * FindViewForPointerEvent(NSEvent *pointerEvent)
virtual const char * GetName() const
Return unique name, used in SavePrimitive methods.
void GetRootWindowAttributes(WindowAttributes_t *attr)
unsigned long fBackgroundPixel
void GeneratePointerMotionEvent(NSEvent *theEvent)
void configureNotifyTree()
unsigned fPassiveGrabEventMask
bool LockFocus(NSView< X11Window > *view)
ROOT::MacOSX::Util::CFScopeGuard< CGImageRef > fImage
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
void GetWindowAttributes(NSObject< X11Window > *window, WindowAttributes_t *dst)
QuartzWindow * fQuartzWindow
QuartzWindow * FindWindowInPoint(Int_t x, Int_t y)
void GenerateKeyReleaseEvent(NSView< X11Window > *eventView, NSEvent *theEvent)
const Mask_t kButtonMotionMask
NSView< X11Window > * FindDNDAwareViewInPoint(NSView *parentView, Window_t dragWinID, Window_t inputWinID, Int_t x, Int_t y, Int_t maxDepth)
bool AdjustCropArea(const Rectangle &srcRect, Rectangle &cropArea)
const Mask_t kLeaveWindowMask
const Mask_t kWABackPixmap
const Mask_t kWABorderPixel
ROOT::MacOSX::X11::CommandBuffer * GetCommandBuffer() const
const Mask_t kWABitGravity
bool ViewIsTextView(NSView< X11Window > *view)
int LocalYCocoaToROOT(NSView< X11Window > *parentView, CGFloat yCocoa)
QuartzView * fContentView
QuartzImage * fShapeCombineMask
const Mask_t kWABackingStore
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
NSView< X11Window > * fContentView
unsigned char * readColorBits:(ROOT::MacOSX::X11::Rectangle area)
QuartzPixmap * fBackBuffer
static std::string format(double x, double y, int digits, int width)
NSCursor * CreateCustomCursor(ECursor currentCursor)
int GlobalYROOTToCocoa(CGFloat yROOT)
void GenerateButtonPressEvent(NSView< X11Window > *eventView, NSEvent *theEvent, EMouseButton btn)
const Mask_t kWABorderPixmap
const Mask_t kPointerMotionMask
void addChild:(NSView< X11Window > *child)
void SetWindowAttributes(const SetWindowAttributes_t *attr, NSObject< X11Window > *window)
NSMutableDictionary * fX11Properties
NSPoint GetCursorHotStop(NSImage *image, ECursor cursor)
NSPoint TranslateCoordinates(NSView< X11Window > *fromView, NSView< X11Window > *toView, NSPoint sourcePoint)
QuartzImage * fBackgroundPixmap
NSPoint ConvertPointFromBaseToScreen(NSWindow *window, NSPoint windowPoint)
QuartzWindow * FindWindowForPointerEvent(NSEvent *pointerEvent)
ROOT::MacOSX::X11::PointerGrab fCurrentGrabType
QuartzWindow * fQuartzWindow
CGImageRef CreateSubImage(QuartzImage *image, const Rectangle &area)
TClass * fClass
pointer to the foreign object
NSPoint TranslateFromScreen(NSPoint point, NSView< X11Window > *to)
NSPoint ConvertPointFromScreenToBase(NSPoint screenPoint, NSWindow *window)
const Mask_t kWABackingPlanes
int GlobalXROOTToCocoa(CGFloat xROOT)
const Mask_t kButtonPressMask
NSView< X11Window > * FindViewUnderPointer()
NSPoint TranslateToScreen(NSView< X11Window > *from, NSPoint point)
NSView< X11Window > * FrameForTextView(NSView< X11Window > *textView)
ROOT::MacOSX::X11::Rectangle GetDisplayGeometry() const
int GlobalYCocoaToROOT(CGFloat yCocoa)
bool ViewIsHtmlViewFrame(NSView< X11Window > *view, bool checkParent)
void activatePassiveGrab()
void GenerateExposeEvent(NSView< X11Window > *view, const NSRect &exposedRect)
void setOverlapped:(BOOL overlap)
const Mask_t kWAEventMask
R__EXTERN TSystem * gSystem
const Mask_t kWASaveUnder
static Atom_t fgDeleteWindowAtom
QuartzWindow * FindWindowUnderPointer()
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)
void UnlockFocus(NSView< X11Window > *view)
void PixelToRGB(Pixel_t pixelColor, CGFloat *rgb)
int LocalYROOTToCocoa(NSView< X11Window > *parentView, CGFloat yROOT)
bool ViewIsTextView(unsigned viewID)
const Mask_t kEnterWindowMask
BOOL fPassiveGrabOwnerEvents
QuartzWindow * fMainWindow
bool ViewIsHtmlView(unsigned viewID)
NSView< X11Window > * FrameForHtmlView(NSView< X11Window > *htmlView)
bool ScreenPointIsInView(NSView< X11Window > *view, Int_t x, Int_t y)
const Mask_t kButtonReleaseMask
const Mask_t kWAOverrideRedirect
void GenerateCrossingEvent(NSEvent *theEvent)
const Mask_t kWAWinGravity
void WindowLostFocus(Window_t winID)
void ClipToShapeMask(NSView< X11Window > *view, CGContextRef ctx)
NSCursor * CreateCursor(ECursor currentCursor)
bool ViewIsHtmlView(NSView< X11Window > *view)
unsigned long fBackgroundPixel
unsigned fPassiveGrabKeyModifiers
typedef void((*Func_t)())
This class implements TVirtualX interface for MacOS X, using Cocoa and Quartz 2D. ...
NSComparisonResult CompareViewsToLower(id view1, id view2, void *context)
const Mask_t kWABorderWidth
void GenerateKeyPressEvent(NSView< X11Window > *eventView, NSEvent *theEvent)
NSComparisonResult CompareViewsToRaise(id view1, id view2, void *context)
BOOL fActiveGrabOwnerEvents
const Mask_t kWABackPixel
const Mask_t kWABackingPixel
const Mask_t kWADontPropagate
ROOT::MacOSX::X11::EventTranslator * GetEventTranslator() const
bool ViewIsTextViewFrame(NSView< X11Window > *view, bool checkParent)
unsigned fActiveGrabEventMask
bool HasPointerGrab() const
void GenerateFocusChangeEvent(NSView< X11Window > *eventView)
void GetWindowGeometry(NSObject< X11Window > *win, WindowAttributes_t *dst)
NSMutableArray * fPassiveKeyGrabs
void activateImplicitGrab()
const char Int_t const char * image
void GenerateButtonReleaseEvent(NSView< X11Window > *eventView, NSEvent *theEvent, EMouseButton btn)