1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/generic/nsPluginUtilsOSX.mm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,207 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +// vim:set ts=2 sts=2 sw=2 et cin: 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsPluginUtilsOSX.h" 1.11 + 1.12 +#import <Cocoa/Cocoa.h> 1.13 +#import <QuartzCore/QuartzCore.h> 1.14 +#include "nsObjCExceptions.h" 1.15 + 1.16 +#ifndef __LP64__ 1.17 +void NS_NPAPI_CarbonWindowFrame(WindowRef aWindow, nsRect& outRect) 1.18 +{ 1.19 + if (!aWindow) 1.20 + return; 1.21 + 1.22 + Rect windowRect; 1.23 + ::GetWindowBounds(aWindow, kWindowStructureRgn, &windowRect); 1.24 + outRect.x = windowRect.left; 1.25 + outRect.y = windowRect.top; 1.26 + outRect.width = windowRect.right - windowRect.left; 1.27 + outRect.height = windowRect.bottom - windowRect.top; 1.28 +} 1.29 +#endif 1.30 + 1.31 +void NS_NPAPI_CocoaWindowFrame(void* aWindow, nsRect& outRect) 1.32 +{ 1.33 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK; 1.34 + 1.35 + if (!aWindow) 1.36 + return; 1.37 + 1.38 + NSWindow* window = (NSWindow*)aWindow; 1.39 + 1.40 + float menubarScreenHeight; 1.41 + NSArray* allScreens = [NSScreen screens]; 1.42 + if ([allScreens count]) 1.43 + menubarScreenHeight = [[allScreens objectAtIndex:0] frame].size.height; 1.44 + else 1.45 + return; // If there are no screens, there's not much we can say. 1.46 + 1.47 + NSRect frame = [window frame]; 1.48 + outRect.x = (nscoord)frame.origin.x; 1.49 + outRect.y = (nscoord)(menubarScreenHeight - (frame.origin.y + frame.size.height)); 1.50 + outRect.width = (nscoord)frame.size.width; 1.51 + outRect.height = (nscoord)frame.size.height; 1.52 + 1.53 + NS_OBJC_END_TRY_ABORT_BLOCK; 1.54 +} 1.55 + 1.56 +bool NS_NPAPI_CocoaWindowIsMain(void* aWindow) 1.57 +{ 1.58 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; 1.59 + 1.60 + if (!aWindow) 1.61 + return true; 1.62 + 1.63 + NSWindow* window = (NSWindow*)aWindow; 1.64 + 1.65 + return (bool)[window isMainWindow]; 1.66 + 1.67 + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(true); 1.68 +} 1.69 + 1.70 +NPError NS_NPAPI_ShowCocoaContextMenu(void* menu, nsIWidget* widget, NPCocoaEvent* event) 1.71 +{ 1.72 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; 1.73 + 1.74 + if (!menu || !widget || !event) 1.75 + return NPERR_GENERIC_ERROR; 1.76 + 1.77 + NSMenu* cocoaMenu = (NSMenu*)menu; 1.78 + NSView* cocoaView = (NSView*)widget->GetNativeData(NS_NATIVE_WIDGET); 1.79 + 1.80 + NSEventType cocoaEventType = NSRightMouseDown; 1.81 + unsigned int cocoaModifierFlags = 0; 1.82 + double x = 0.0; // Coordinates for the context menu in plugin terms, top-left origin. 1.83 + double y = 0.0; 1.84 + 1.85 + NPCocoaEventType eventType = event->type; 1.86 + if (eventType == NPCocoaEventMouseDown || 1.87 + eventType == NPCocoaEventMouseUp || 1.88 + eventType == NPCocoaEventMouseMoved || 1.89 + eventType == NPCocoaEventMouseEntered || 1.90 + eventType == NPCocoaEventMouseExited || 1.91 + eventType == NPCocoaEventMouseDragged) { 1.92 + x = event->data.mouse.pluginX; 1.93 + y = event->data.mouse.pluginY; 1.94 + if ((x < 0.0) || (y < 0.0)) 1.95 + return NPERR_GENERIC_ERROR; 1.96 + } 1.97 + 1.98 + // Flip the coords to bottom-left origin. 1.99 + NSRect viewFrame = [cocoaView frame]; 1.100 + double shiftedX = x; 1.101 + double shiftedY = viewFrame.size.height - y; 1.102 + // Shift to window coords. 1.103 + shiftedX += viewFrame.origin.x; 1.104 + shiftedY += [cocoaView convertPoint:NSMakePoint(0,0) toView:nil].y - viewFrame.size.height; 1.105 + 1.106 + // Create an NSEvent we can use to show the context menu. Only the location 1.107 + // is important here so just simulate a right mouse down. The coordinates 1.108 + // must be in top-level window terms. 1.109 + NSEvent* cocoaEvent = [NSEvent mouseEventWithType:cocoaEventType 1.110 + location:NSMakePoint(shiftedX, shiftedY) 1.111 + modifierFlags:cocoaModifierFlags 1.112 + timestamp:0 1.113 + windowNumber:[[cocoaView window] windowNumber] 1.114 + context:nil 1.115 + eventNumber:0 1.116 + clickCount:1 1.117 + pressure:0.0]; 1.118 + 1.119 + [NSMenu popUpContextMenu:cocoaMenu withEvent:cocoaEvent forView:cocoaView]; 1.120 + 1.121 + return NPERR_NO_ERROR; 1.122 + 1.123 + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NPERR_GENERIC_ERROR); 1.124 +} 1.125 + 1.126 +NPBool NS_NPAPI_ConvertPointCocoa(void* inView, 1.127 + double sourceX, double sourceY, NPCoordinateSpace sourceSpace, 1.128 + double *destX, double *destY, NPCoordinateSpace destSpace) 1.129 +{ 1.130 + // Plugins don't always have a view/frame. It would be odd to ask for a point conversion 1.131 + // without a view, so we'll warn about it, but it's technically OK. 1.132 + if (!inView) { 1.133 + NS_WARNING("Must have a native view to convert coordinates."); 1.134 + return false; 1.135 + } 1.136 + 1.137 + // Caller has to want a result. 1.138 + if (!destX && !destY) 1.139 + return false; 1.140 + 1.141 + if (sourceSpace == destSpace) { 1.142 + if (destX) 1.143 + *destX = sourceX; 1.144 + if (destY) 1.145 + *destY = sourceY; 1.146 + return true; 1.147 + } 1.148 + 1.149 + NSView* view = (NSView*)inView; 1.150 + NSWindow* window = [view window]; 1.151 + NSPoint sourcePoint = NSMakePoint(sourceX, sourceY); 1.152 + 1.153 + // Convert to screen space. 1.154 + NSPoint screenPoint; 1.155 + switch (sourceSpace) { 1.156 + case NPCoordinateSpacePlugin: 1.157 + screenPoint = [view convertPoint:sourcePoint toView:nil]; 1.158 + screenPoint = [window convertBaseToScreen:screenPoint]; 1.159 + break; 1.160 + case NPCoordinateSpaceWindow: 1.161 + screenPoint = [window convertBaseToScreen:sourcePoint]; 1.162 + break; 1.163 + case NPCoordinateSpaceFlippedWindow: 1.164 + sourcePoint.y = [window frame].size.height - sourcePoint.y; 1.165 + screenPoint = [window convertBaseToScreen:sourcePoint]; 1.166 + break; 1.167 + case NPCoordinateSpaceScreen: 1.168 + screenPoint = sourcePoint; 1.169 + break; 1.170 + case NPCoordinateSpaceFlippedScreen: 1.171 + sourcePoint.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - sourcePoint.y; 1.172 + screenPoint = sourcePoint; 1.173 + break; 1.174 + default: 1.175 + return false; 1.176 + } 1.177 + 1.178 + // Convert from screen to dest space. 1.179 + NSPoint destPoint; 1.180 + switch (destSpace) { 1.181 + case NPCoordinateSpacePlugin: 1.182 + destPoint = [window convertScreenToBase:screenPoint]; 1.183 + destPoint = [view convertPoint:destPoint fromView:nil]; 1.184 + break; 1.185 + case NPCoordinateSpaceWindow: 1.186 + destPoint = [window convertScreenToBase:screenPoint]; 1.187 + break; 1.188 + case NPCoordinateSpaceFlippedWindow: 1.189 + destPoint = [window convertScreenToBase:screenPoint]; 1.190 + destPoint.y = [window frame].size.height - destPoint.y; 1.191 + break; 1.192 + case NPCoordinateSpaceScreen: 1.193 + destPoint = screenPoint; 1.194 + break; 1.195 + case NPCoordinateSpaceFlippedScreen: 1.196 + destPoint = screenPoint; 1.197 + destPoint.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - destPoint.y; 1.198 + break; 1.199 + default: 1.200 + return false; 1.201 + } 1.202 + 1.203 + if (destX) 1.204 + *destX = destPoint.x; 1.205 + if (destY) 1.206 + *destY = destPoint.y; 1.207 + 1.208 + return true; 1.209 +} 1.210 +