dom/plugins/test/testplugin/nptest_macosx.mm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* ***** BEGIN LICENSE BLOCK *****
     2  * 
     3  * Copyright (c) 2008, Mozilla Corporation
     4  * All rights reserved.
     5  * 
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  * 
     9  * * Redistributions of source code must retain the above copyright notice, this
    10  *   list of conditions and the following disclaimer.
    11  * * Redistributions in binary form must reproduce the above copyright notice,
    12  *   this list of conditions and the following disclaimer in the documentation
    13  *   and/or other materials provided with the distribution.
    14  * * Neither the name of the Mozilla Corporation nor the names of its
    15  *   contributors may be used to endorse or promote products derived from this
    16  *   software without specific prior written permission.
    17  * 
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    21  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
    22  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    25  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28  * 
    29  * Contributor(s):
    30  *   Josh Aas <josh@mozilla.com>
    31  * 
    32  * ***** END LICENSE BLOCK ***** */
    34 #include "nptest_platform.h"
    35 #include "nsAlgorithm.h"
    36 #include <CoreServices/CoreServices.h>
    37 #include <algorithm>
    39 using namespace std;
    41 bool
    42 pluginSupportsWindowMode()
    43 {
    44   return false;
    45 }
    47 bool
    48 pluginSupportsWindowlessMode()
    49 {
    50   return true;
    51 }
    53 bool
    54 pluginSupportsAsyncBitmapDrawing()
    55 {
    56   return false;
    57 }
    59 NPError
    60 pluginInstanceInit(InstanceData* instanceData)
    61 {
    62   NPP npp = instanceData->npp;
    64   NPBool supportsCoreGraphics = false;
    65   if ((NPN_GetValue(npp, NPNVsupportsCoreGraphicsBool, &supportsCoreGraphics) == NPERR_NO_ERROR) &&
    66       supportsCoreGraphics) {
    67     NPN_SetValue(npp, NPPVpluginDrawingModel, (void*)NPDrawingModelCoreGraphics);
    68   } else {
    69     printf("CoreGraphics drawing model not supported, can't create a plugin instance.\n");
    70     return NPERR_INCOMPATIBLE_VERSION_ERROR;
    71   }
    73   NPBool supportsCocoaEvents = false;
    74   if ((NPN_GetValue(npp, NPNVsupportsCocoaBool, &supportsCocoaEvents) == NPERR_NO_ERROR) &&
    75       supportsCocoaEvents) {
    76     NPN_SetValue(npp, NPPVpluginEventModel, (void*)NPEventModelCocoa);
    77     instanceData->eventModel = NPEventModelCocoa;
    78   } else {
    79     printf("Cocoa event model not supported, can't create a plugin instance.\n");
    80     return NPERR_INCOMPATIBLE_VERSION_ERROR;
    81   }
    83   return NPERR_NO_ERROR;
    84 }
    86 void
    87 pluginInstanceShutdown(InstanceData* instanceData)
    88 {
    89 }
    91 static bool
    92 RectEquals(const NPRect& r1, const NPRect& r2)
    93 {
    94   return r1.left == r2.left && r1.top == r2.top &&
    95          r1.right == r2.right && r1.bottom == r2.bottom;
    96 }
    98 void
    99 pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
   100 {
   101   // Ugh. Due to a terrible Gecko bug, we have to ignore position changes
   102   // when the clip rect doesn't change; the position can be wrong
   103   // when set by a path other than nsObjectFrame::FixUpPluginWindow.
   104   int32_t oldX = instanceData->window.x;
   105   int32_t oldY = instanceData->window.y;
   106   bool clipChanged =
   107     !RectEquals(instanceData->window.clipRect, newWindow->clipRect);
   108   instanceData->window = *newWindow;
   109   if (!clipChanged) {
   110     instanceData->window.x = oldX;
   111     instanceData->window.y = oldY;
   112   }
   113 }
   115 void
   116 pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
   117 {
   118   // Should never be called since we don't support window mode
   119 }
   121 static void 
   122 GetColorsFromRGBA(uint32_t rgba, float* r, float* g, float* b, float* a)
   123 {
   124   *b = (rgba & 0xFF) / 255.0;
   125   *g = ((rgba & 0xFF00) >> 8) / 255.0;
   126   *r = ((rgba & 0xFF0000) >> 16) / 255.0;
   127   *a = ((rgba & 0xFF000000) >> 24) / 255.0;
   128 }
   130 static void
   131 pluginDraw(InstanceData* instanceData, NPCocoaEvent* event)
   132 {
   133   if (!instanceData)
   134     return;
   136   notifyDidPaint(instanceData);
   138   NPP npp = instanceData->npp;
   139   if (!npp)
   140     return;
   142   const char* uaString = NPN_UserAgent(npp);
   143   if (!uaString)
   144     return;
   146   NPWindow window = instanceData->window;
   148   CGContextRef cgContext = event->data.draw.context;
   150   float windowWidth = window.width;
   151   float windowHeight = window.height;
   153   switch(instanceData->scriptableObject->drawMode) {
   154   case DM_DEFAULT: {
   155     CFStringRef uaCFString = CFStringCreateWithCString(kCFAllocatorDefault, uaString, kCFStringEncodingASCII);
   156     // save the cgcontext gstate
   157     CGContextSaveGState(cgContext);
   159     // we get a flipped context
   160     CGContextTranslateCTM(cgContext, 0.0, windowHeight);
   161     CGContextScaleCTM(cgContext, 1.0, -1.0);
   163     // draw a gray background for the plugin
   164     CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
   165     CGContextSetGrayFillColor(cgContext, 0.5, 1.0);
   166     CGContextDrawPath(cgContext, kCGPathFill);
   168     // draw a black frame around the plugin
   169     CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
   170     CGContextSetGrayStrokeColor(cgContext, 0.0, 1.0);
   171     CGContextSetLineWidth(cgContext, 6.0);
   172     CGContextStrokePath(cgContext);
   174     // draw the UA string using Core Text
   175     CGContextSetTextMatrix(cgContext, CGAffineTransformIdentity);
   177     // Initialize a rectangular path.
   178     CGMutablePathRef path = CGPathCreateMutable();
   179     CGRect bounds = CGRectMake(10.0, 10.0, std::max(0.0, windowWidth - 20.0),
   180                                std::max(0.0, windowHeight - 20.0));
   181     CGPathAddRect(path, NULL, bounds);
   183     // Initialize an attributed string.
   184     CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
   185     CFAttributedStringReplaceString(attrString, CFRangeMake(0, 0), uaCFString);
   187     // Create a color and add it as an attribute to the string.
   188     CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
   189     CGFloat components[] = { 0.0, 0.0, 0.0, 1.0 };
   190     CGColorRef red = CGColorCreate(rgbColorSpace, components);    
   191     CGColorSpaceRelease(rgbColorSpace);
   192     CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 50), kCTForegroundColorAttributeName, red);
   194     // Create the framesetter with the attributed string.
   195     CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
   196     CFRelease(attrString);
   198     // Create the frame and draw it into the graphics context
   199     CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
   200     CFRelease(framesetter);
   201     if (frame) {
   202       CTFrameDraw(frame, cgContext);
   203       CFRelease(frame);
   204     }
   206     // restore the cgcontext gstate
   207     CGContextRestoreGState(cgContext);
   208     break;
   209   }
   210   case DM_SOLID_COLOR: {
   211     // save the cgcontext gstate
   212     CGContextSaveGState(cgContext);
   214     // we get a flipped context
   215     CGContextTranslateCTM(cgContext, 0.0, windowHeight);
   216     CGContextScaleCTM(cgContext, 1.0, -1.0);
   218     // draw a solid background for the plugin
   219     CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
   221     float r,g,b,a;
   222     GetColorsFromRGBA(instanceData->scriptableObject->drawColor, &r, &g, &b, &a);
   223     CGContextSetRGBFillColor(cgContext, r, g, b, a);
   224     CGContextDrawPath(cgContext, kCGPathFill);
   226     // restore the cgcontext gstate
   227     CGContextRestoreGState(cgContext);
   228     break;
   229   }
   230   }
   231 }
   233 int16_t
   234 pluginHandleEvent(InstanceData* instanceData, void* event)
   235 {
   236   NPCocoaEvent* cocoaEvent = (NPCocoaEvent*)event;
   237   if (!cocoaEvent)
   238     return kNPEventNotHandled;
   240   switch (cocoaEvent->type) {
   241     case NPCocoaEventDrawRect:
   242       pluginDraw(instanceData, cocoaEvent);
   243       break;
   244     case NPCocoaEventMouseDown:
   245     case NPCocoaEventMouseUp:
   246     case NPCocoaEventMouseMoved:
   247       instanceData->lastMouseX = (int32_t)cocoaEvent->data.mouse.pluginX;
   248       instanceData->lastMouseY = (int32_t)cocoaEvent->data.mouse.pluginY;
   249       if (cocoaEvent->type == NPCocoaEventMouseUp) {
   250         instanceData->mouseUpEventCount++;
   251       }
   252       break;
   253     case NPCocoaEventWindowFocusChanged:
   254       instanceData->topLevelWindowActivationState = cocoaEvent->data.focus.hasFocus ?
   255         ACTIVATION_STATE_ACTIVATED : ACTIVATION_STATE_DEACTIVATED;
   256       instanceData->topLevelWindowActivationEventCount = instanceData->topLevelWindowActivationEventCount + 1;
   257       break;
   258     case NPCocoaEventFocusChanged:
   259       instanceData->focusState = cocoaEvent->data.focus.hasFocus ?
   260       ACTIVATION_STATE_ACTIVATED : ACTIVATION_STATE_DEACTIVATED;
   261       instanceData->focusEventCount = instanceData->focusEventCount + 1;
   262       break;
   263     default:
   264       return kNPEventNotHandled;
   265   }
   267   return kNPEventHandled;
   268 }
   270 int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
   271 {
   272   NPWindow* w = &instanceData->window;
   273   switch (edge) {
   274   case EDGE_LEFT:
   275     return w->x;
   276   case EDGE_TOP:
   277     return w->y;
   278   case EDGE_RIGHT:
   279     return w->x + w->width;
   280   case EDGE_BOTTOM:
   281     return w->y + w->height;
   282   }
   283   return NPTEST_INT32_ERROR;
   284 }
   286 int32_t pluginGetClipRegionRectCount(InstanceData* instanceData)
   287 {
   288   return 1;
   289 }
   291 int32_t pluginGetClipRegionRectEdge(InstanceData* instanceData, 
   292     int32_t rectIndex, RectEdge edge)
   293 {
   294   if (rectIndex != 0)
   295     return NPTEST_INT32_ERROR;
   297   // We have to add the Cocoa titlebar height here since the clip rect
   298   // is being returned relative to that
   299   static const int COCOA_TITLEBAR_HEIGHT = 22;
   301   NPWindow* w = &instanceData->window;
   302   switch (edge) {
   303   case EDGE_LEFT:
   304     return w->clipRect.left;
   305   case EDGE_TOP:
   306     return w->clipRect.top + COCOA_TITLEBAR_HEIGHT;
   307   case EDGE_RIGHT:
   308     return w->clipRect.right;
   309   case EDGE_BOTTOM:
   310     return w->clipRect.bottom + COCOA_TITLEBAR_HEIGHT;
   311   }
   312   return NPTEST_INT32_ERROR;
   313 }
   315 void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error)
   316 {
   317 }

mercurial