Changeset 14397 in webkit


Ignore:
Timestamp:
May 15, 2006, 5:04:57 PM (19 years ago)
Author:
tomernic
Message:

JavaScriptCore:

Reviewed by John Sullivan.

Part of <rdar://problem/4466508> Add 64-bit support to the Netscape Plugin API

Added to the Netscape Plugin API the concept of "plugin drawing models". The drawing model
determines the kind of graphics context created by the browser for the plugin, as well as
the Mac types of various Netscape Plugin API data structures.

There is a drawing model to represent the old QuickDraw-based API. It is used by default
if QuickDraw is available on the system, unless the plugin specifies another drawing model.

The big change is the addition of the CoreGraphics drawing model. A plugin may request this
drawing model to obtain access to a CGContextRef for drawing, instead of a QuickDraw CGrafPtr.

  • bindings/npapi.h: Define NP_NO_QUICKDRAW when compiling 64-bit; there is no 64-bit QuickDraw. Added NPNVpluginDrawingModel, NPNVsupportsQuickDrawBool, and NPNVsupportsCoreGraphicsBool variables. Added NPDrawingModel enumeration. Currently the only drawing models are QuickDraw and CoreGraphics. NPRegion's type now depends on the drawing model specified by the plugin. NP_Port is now only defined when QuickDraw is available. Added NP_CGContext, which is the type of the NPWindow's "window" member in CoreGraphics mode.

WebKit:

Reviewed by John Sullivan.

Part of <rdar://problem/4466508> Add 64-bit support to the Netscape Plugin API

Added to the Netscape Plugin API the concept of "plugin drawing models". The drawing model
determines the kind of graphics context created by the browser for the plugin, as well as
the Mac types of various Netscape Plugin API data structures.

There is a drawing model to represent the old QuickDraw-based API. It is used by default
if QuickDraw is available on the system, unless the plugin specifies another drawing model.

The big change is the addition of the CoreGraphics drawing model. A plugin may request this
drawing model to obtain access to a CGContextRef for drawing, instead of a QuickDraw CGrafPtr.

  • Plugins/WebBaseNetscapePluginView.h: Added PluginPort union, which wraps a NP_Port and a NP_CGContext. This is to make access to the nPort and lastSetPort ivars more convenient now that the port type differs based on the drawing model. Changed types of nPort and lastSetPort to PluginPort so they can be used with any drawing model. Added drawingModel ivar.
  • Plugins/WebBaseNetscapePluginView.m: Renamed PortState to PortState_QD. PortState is now an opaque pointer. PortState_QD cannot be used if QuickDraw is unavailable. (-[WebBaseNetscapePluginView fixWindowPort]): Cannot be used if QuickDraw is unavailable. (-[WebBaseNetscapePluginView saveAndSetNewPortStateForUpdate:]): Only fix window port if drawing model is QuickDraw. Re-ordered some code so I could group QuickDraw-specific stuff into switch and if blocks (that's why the diff here is so terrible). Now returns a malloc()'ed PortState that the caller is responsible for freeing. Renamed to better reflect this behavior. Support for the CoreGraphics drawing model -- fill PortState_CG struct, save CGContext state. (-[WebBaseNetscapePluginView restorePortState:]): Switch based on drawing model. Support for the CoreGraphics drawing model -- restore CGContext state saved earlier. (-[WebBaseNetscapePluginView sendEvent:]): Formatting. Don't set save/set port state or set the window in CoreGraphics mode unless the event being sent is an updateEvt. We can't provide the plugin with a CGContext outside of our view display cycle. Don't restore PortState if it's NULL (didn't used to be a pointer). Free when we're done with it. (-[WebBaseNetscapePluginView isNewWindowEqualToOldWindow]): Formatting. Switch how we compare ports based on the drawing model. (-[WebBaseNetscapePluginView updateAndSetWindow]): Fixed for CoreGraphics by triggering a redisplay instead of sending an update event to the plugin outside of the view display cycle. Don't restore PortState if it's NULL (didn't used to be a pointer). Free when we're done with it. (-[WebBaseNetscapePluginView setWindowIfNecessary]): Assert that the window is only set when updating in CoreGraphics mode. Log differently depending on the drawing model. (-[WebBaseNetscapePluginView start]): Fall back on QuickDraw if the plugin does not specify a drawing model. (-[WebBaseNetscapePluginView tellQuickTimeToChill]): Cannot be used if QuickDraw is unavailable. (-[WebBaseNetscapePluginView viewWillMoveToWindow:]): Only call -tellQuickTimeToChill in QuickDraw mode. (-[WebBaseNetscapePluginView viewHasMoved:]): ditto (-[WebBaseNetscapePluginView invalidateRegion:]): NPRegion is a CGPathRef in CoreGraphics mode. (-[WebBaseNetscapePluginView getVariable:value:]): Added support for retriveing the NPNVpluginDrawingModel, NPNVsupportsQuickDrawBool, and NPNVsupportsCoreGraphicsBool browser variables. (-[WebBaseNetscapePluginView setVariable:value:]): Added support for setting the NPNVpluginDrawingModel variable.
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r14359 r14397  
     12006-05-15  Tim Omernick  <[email protected]>
     2
     3        Reviewed by John Sullivan.
     4
     5        Part of <rdar://problem/4466508> Add 64-bit support to the Netscape Plugin API
     6
     7        Added to the Netscape Plugin API the concept of "plugin drawing models".  The drawing model
     8        determines the kind of graphics context created by the browser for the plugin, as well as
     9        the Mac types of various Netscape Plugin API data structures.
     10
     11        There is a drawing model to represent the old QuickDraw-based API.  It is used by default
     12        if QuickDraw is available on the system, unless the plugin specifies another drawing model.
     13
     14        The big change is the addition of the CoreGraphics drawing model.  A plugin may request this
     15        drawing model to obtain access to a CGContextRef for drawing, instead of a QuickDraw CGrafPtr.
     16
     17        * bindings/npapi.h:
     18        Define NP_NO_QUICKDRAW when compiling 64-bit; there is no 64-bit QuickDraw.
     19        Added NPNVpluginDrawingModel, NPNVsupportsQuickDrawBool, and NPNVsupportsCoreGraphicsBool
     20        variables.
     21        Added NPDrawingModel enumeration.  Currently the only drawing models are QuickDraw and
     22        CoreGraphics.
     23        NPRegion's type now depends on the drawing model specified by the plugin.
     24        NP_Port is now only defined when QuickDraw is available.
     25        Added NP_CGContext, which is the type of the NPWindow's "window" member in CoreGraphics mode.
     26
    1272006-05-13  Kevin M. Ollivier  <[email protected]>
    228
  • trunk/JavaScriptCore/bindings/npapi.h

    r14246 r14397  
    9191#endif
    9292
     93#if defined(XP_MACOSX) && defined(__LP64__)
     94    #define NP_NO_QUICKDRAW
     95#endif
    9396
    9497/*----------------------------------------------------------------------*/
     
    333336    /* Get the NPObject wrapper for the plugins DOM element. */
    334337    NPNVPluginElementNPObject                 /* Not implemented in WebKit */
     338
     339#ifdef XP_MACOSX
     340    , NPNVpluginDrawingModel = 1000 /* The NPDrawingModel specified by the plugin */
     341
     342#ifndef NP_NO_QUICKDRAW
     343    , NPNVsupportsQuickDrawBool = 2000 /* TRUE if the browser supports the QuickDraw drawing model */
     344#endif
     345    , NPNVsupportsCoreGraphicsBool = 2001 /* TRUE if the browser supports the CoreGraphics drawing model */
     346#endif /* XP_MACOSX */
    335347} NPNVariable;
    336348
     
    343355    NPWindowTypeDrawable
    344356} NPWindowType;
     357
     358#ifdef XP_MACOSX
     359
     360/*
     361 * The drawing model for a Mac OS X plugin.  These are the possible values for the NPNVpluginDrawingModel variable.
     362 */
     363 
     364typedef enum {
     365#ifndef NP_NO_QUICKDRAW
     366    NPDrawingModelQuickDraw = 0,
     367#endif
     368    NPDrawingModelCoreGraphics = 1
     369} NPDrawingModel;
     370
     371#endif
    345372
    346373typedef struct _NPWindow
     
    400427#endif /* XP_MAC */
    401428
    402 #if defined(XP_MAC) || defined(XP_MACOSX)
     429#if defined(XP_MAC)
    403430typedef RgnHandle NPRegion;
     431#elif defined(XP_MACOSX)
     432/*
     433 * NPRegion's type depends on the drawing model specified by the plugin (see NPNVpluginDrawingModel).
     434 * NPQDRegion represents a QuickDraw RgnHandle, and NPCGRegion represents a CoreGraphics CGPathRef.
     435 */
     436typedef void *NPRegion;
     437#ifndef NP_NO_QUICKDRAW
     438typedef RgnHandle NPQDRegion;
     439#endif
     440typedef CGPathRef NPCGRegion;
    404441#elif defined(XP_WIN)
    405442typedef HRGN NPRegion;
     
    410447#endif /* XP_MAC */
    411448
     449#ifdef XP_MACOSX
     450
     451/*
     452 * NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics
     453 * as its drawing model.
     454 */
     455
     456typedef struct NP_CGContext
     457{
     458    CGContextRef context;
     459    WindowRef window;
     460} NP_CGContext;
     461
     462#endif /* XP_MACOSX */
     463
    412464#if defined(XP_MAC) || defined(XP_MACOSX)
     465
    413466/*
    414467 *  Mac-specific structures and definitions.
    415468 */
    416469
     470#ifndef NP_NO_QUICKDRAW
     471
     472/*
     473 * NP_Port is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelQuickDraw as its
     474 * drawing model, or the plugin does not specify a drawing model.
     475 *
     476 * It is not recommended that new plugins use NPDrawingModelQuickDraw or NP_Port, as QuickDraw has been
     477 * deprecated in Mac OS X 10.5.  CoreGraphics is the preferred drawing API.
     478 *
     479 * NP_Port is not available in 64-bit.
     480 */
     481 
    417482typedef struct NP_Port
    418483{
     
    421486    int32        porty;
    422487} NP_Port;
     488
     489#endif /* NP_NO_QUICKDRAW */
    423490
    424491/*
  • trunk/WebKit/ChangeLog

    r14391 r14397  
     12006-05-15  Tim Omernick  <[email protected]>
     2
     3        Reviewed by John Sullivan.
     4
     5        Part of <rdar://problem/4466508> Add 64-bit support to the Netscape Plugin API
     6
     7        Added to the Netscape Plugin API the concept of "plugin drawing models".  The drawing model
     8        determines the kind of graphics context created by the browser for the plugin, as well as
     9        the Mac types of various Netscape Plugin API data structures.
     10
     11        There is a drawing model to represent the old QuickDraw-based API.  It is used by default
     12        if QuickDraw is available on the system, unless the plugin specifies another drawing model.
     13
     14        The big change is the addition of the CoreGraphics drawing model.  A plugin may request this
     15        drawing model to obtain access to a CGContextRef for drawing, instead of a QuickDraw CGrafPtr.
     16
     17        * Plugins/WebBaseNetscapePluginView.h:
     18        Added PluginPort union, which wraps a NP_Port and a NP_CGContext.  This is to make access to
     19        the nPort and lastSetPort ivars more convenient now that the port type differs based on the
     20        drawing model.
     21        Changed types of nPort and lastSetPort to PluginPort so they can be used with any drawing model.
     22        Added drawingModel ivar.
     23        * Plugins/WebBaseNetscapePluginView.m:
     24        Renamed PortState to PortState_QD.  PortState is now an opaque pointer.  PortState_QD cannot be
     25        used if QuickDraw is unavailable.
     26        (-[WebBaseNetscapePluginView fixWindowPort]):
     27        Cannot be used if QuickDraw is unavailable.
     28        (-[WebBaseNetscapePluginView saveAndSetNewPortStateForUpdate:]):
     29        Only fix window port if drawing model is QuickDraw.
     30        Re-ordered some code so I could group QuickDraw-specific stuff into switch and if blocks (that's
     31        why the diff here is so terrible).
     32        Now returns a malloc()'ed PortState that the caller is responsible for freeing.  Renamed to
     33        better reflect this behavior.
     34        Support for the CoreGraphics drawing model -- fill PortState_CG struct, save CGContext state.
     35        (-[WebBaseNetscapePluginView restorePortState:]):
     36        Switch based on drawing model.
     37        Support for the CoreGraphics drawing model -- restore CGContext state saved earlier.
     38        (-[WebBaseNetscapePluginView sendEvent:]):
     39        Formatting.
     40        Don't set save/set port state or set the window in CoreGraphics mode unless the event being
     41        sent is an updateEvt.  We can't provide the plugin with a CGContext outside of our view display
     42        cycle.
     43        Don't restore PortState if it's NULL (didn't used to be a pointer).  Free when we're done with it.
     44        (-[WebBaseNetscapePluginView isNewWindowEqualToOldWindow]):
     45        Formatting.
     46        Switch how we compare ports based on the drawing model.
     47        (-[WebBaseNetscapePluginView updateAndSetWindow]):
     48        Fixed for CoreGraphics by triggering a redisplay instead of sending an update event to the plugin
     49        outside of the view display cycle.
     50        Don't restore PortState if it's NULL (didn't used to be a pointer).  Free when we're done with it.
     51        (-[WebBaseNetscapePluginView setWindowIfNecessary]):
     52        Assert that the window is only set when updating in CoreGraphics mode.
     53        Log differently depending on the drawing model.
     54        (-[WebBaseNetscapePluginView start]):
     55        Fall back on QuickDraw if the plugin does not specify a drawing model.
     56        (-[WebBaseNetscapePluginView tellQuickTimeToChill]):
     57        Cannot be used if QuickDraw is unavailable.
     58        (-[WebBaseNetscapePluginView viewWillMoveToWindow:]):
     59        Only call -tellQuickTimeToChill in QuickDraw mode.
     60        (-[WebBaseNetscapePluginView viewHasMoved:]):
     61        ditto
     62        (-[WebBaseNetscapePluginView invalidateRegion:]):
     63        NPRegion is a CGPathRef in CoreGraphics mode.
     64        (-[WebBaseNetscapePluginView getVariable:value:]):
     65        Added support for retriveing the NPNVpluginDrawingModel, NPNVsupportsQuickDrawBool, and
     66        NPNVsupportsCoreGraphicsBool browser variables.
     67        (-[WebBaseNetscapePluginView setVariable:value:]):
     68        Added support for setting the NPNVpluginDrawingModel variable.
     69
    1702006-05-15  Tim Omernick  <[email protected]>
    271
  • trunk/WebKit/Plugins/WebBaseNetscapePluginView.h

    r14075 r14397  
    3030
    3131#import <WebKit/npfunctions.h>
     32#import <WebKit/npapi.h>
    3233
    3334@class WebDataSource;
     
    3738@class WebView;
    3839
     40typedef union PluginPort {
     41#ifndef NP_NO_QUICKDRAW
     42    NP_Port qdPort;
     43#endif       
     44    NP_CGContext cgPort;
     45} PluginPort;
    3946
    4047@interface WebBaseNetscapePluginView : NSView
     
    4956       
    5057    NPP instance;
     58    NPP_t instanceStruct;
    5159    NPWindow window;
    5260    NPWindow lastSetWindow;
    53     NP_Port nPort;
    54     NP_Port lastSetPort;
    55     NPP_t instanceStruct;
     61    PluginPort nPort;
     62    PluginPort lastSetPort;
     63    NPDrawingModel drawingModel;
    5664
    5765    BOOL isStarted;
  • trunk/WebKit/Plugins/WebBaseNetscapePluginView.m

    r14262 r14397  
    7070static WebBaseNetscapePluginView *currentPluginView = nil;
    7171
     72typedef struct OpaquePortState* PortState;
     73
     74#ifndef NP_NO_QUICKDRAW
     75
     76// QuickDraw is not available in 64-bit
     77
    7278typedef struct {
    7379    GrafPtr oldPort;
     
    7783    RgnHandle clipRegion;
    7884    BOOL forUpdate;
    79 } PortState;
     85} PortState_QD;
     86
     87#endif /* NP_NO_QUICKDRAW */
     88
     89typedef struct {
     90    CGContextRef context;
     91    BOOL forUpdate;
     92} PortState_CG;
    8093
    8194@interface WebPluginRequest : NSObject
     
    191204}
    192205
     206#ifndef NP_NO_QUICKDRAW
    193207// The WindowRef created by -[NSWindow windowRef] has a QuickDraw GrafPort that covers
    194208// the entire window frame (or structure region to use the Carbon term) rather then just the window content.
     
    196210- (void)fixWindowPort
    197211{
     212    ASSERT(drawingModel == NPDrawingModelQuickDraw);
     213   
    198214    NSWindow *currentWindow = [self currentWindow];
    199215    if ([currentWindow isKindOfClass:objc_getClass("NSCarbonWindow")])
     
    213229    SetPort(oldPort);
    214230}
    215 
    216 - (PortState)saveAndSetPortStateForUpdate:(BOOL)forUpdate
     231#endif
     232
     233- (PortState)saveAndSetNewPortStateForUpdate:(BOOL)forUpdate
    217234{
    218235    ASSERT([self currentWindow] != nil);
    219  
    220     [self fixWindowPort];
    221    
     236
     237    // A CoreGraphics plugin's window may only be set while the plugin view is being updated
     238    ASSERT(drawingModel != NPDrawingModelCoreGraphics || (forUpdate && [NSView focusView] == self));
     239     
     240#ifndef NP_NO_QUICKDRAW
     241    // If drawing with QuickDraw, fix the window port so that it has the same bounds as the NSWindow's
     242    // content view.  This makes it easier to convert between AppKit view and QuickDraw port coordinates.
     243    if (drawingModel == NPDrawingModelQuickDraw)
     244        [self fixWindowPort];
     245#endif
     246   
    222247    WindowRef windowRef = [[self currentWindow] windowRef];
    223     CGrafPtr port = GetWindowPort(windowRef);
    224        
    225     Rect portBounds;
    226     GetPortBounds(port, &portBounds);
    227 
     248    ASSERT(windowRef);
     249   
    228250    // Use AppKit to convert view coordinates to NSWindow coordinates.
    229251    NSRect boundsInWindow = [self convertRect:[self bounds] toView:nil];
     
    235257    visibleRectInWindow.origin.y = borderViewHeight - NSMaxY(visibleRectInWindow);
    236258   
     259#ifndef NP_NO_QUICKDRAW
    237260    // Look at the Carbon port to convert top-left-based window coordinates into top-left-based content coordinates.
    238     PixMap *pix = *GetPortPixMap(port);
    239     boundsInWindow.origin.x += pix->bounds.left - portBounds.left;
    240     boundsInWindow.origin.y += pix->bounds.top - portBounds.top;
    241     visibleRectInWindow.origin.x += pix->bounds.left - portBounds.left;
    242     visibleRectInWindow.origin.y += pix->bounds.top - portBounds.top;
    243    
    244     // Set up NS_Port.
    245     nPort.port = port;
    246     nPort.portx = (int32)-boundsInWindow.origin.x;
    247     nPort.porty = (int32)-boundsInWindow.origin.y;
    248    
    249     // Set up NPWindow.
    250     window.window = &nPort;
     261    if (drawingModel == NPDrawingModelQuickDraw) {
     262        Rect portBounds;
     263        CGrafPtr port = GetWindowPort(windowRef);
     264        GetPortBounds(port, &portBounds);
     265
     266        PixMap *pix = *GetPortPixMap(port);
     267        boundsInWindow.origin.x += pix->bounds.left - portBounds.left;
     268        boundsInWindow.origin.y += pix->bounds.top - portBounds.top;
     269        visibleRectInWindow.origin.x += pix->bounds.left - portBounds.left;
     270        visibleRectInWindow.origin.y += pix->bounds.top - portBounds.top;
     271    }
     272#endif
    251273   
    252274    window.x = (int32)boundsInWindow.origin.x;
     
    293315    window.type = NPWindowTypeWindow;
    294316   
    295     // Save the port state.
     317    // Save the port state, set up the port for entry into the plugin
    296318    PortState portState;
    297    
    298     GetPort(&portState.oldPort);   
    299 
    300     portState.oldOrigin.h = portBounds.left;
    301     portState.oldOrigin.v = portBounds.top;
    302 
    303     portState.oldClipRegion = NewRgn();
    304     GetPortClipRegion(port, portState.oldClipRegion);
    305    
    306     portState.oldVisibleRegion = NewRgn();
    307     GetPortVisibleRegion(port, portState.oldVisibleRegion);
    308    
    309     RgnHandle clipRegion = NewRgn();
    310     portState.clipRegion = clipRegion;
    311    
    312     MacSetRectRgn(clipRegion,
    313         window.clipRect.left + nPort.portx, window.clipRect.top + nPort.porty,
    314         window.clipRect.right + nPort.portx, window.clipRect.bottom + nPort.porty);
    315    
    316     // Clip to dirty region when updating in "windowless" mode (transparent)
    317     if (forUpdate && isTransparent) {
    318         RgnHandle viewClipRegion = NewRgn();
    319        
    320         // Get list of dirty rects from the opaque ancestor -- WebKit does some tricks with invalidation and
    321         // display to enable z-ordering for NSViews; a side-effect of this is that only the WebHTMLView
    322         // knows about the true set of dirty rects.
    323         NSView *opaqueAncestor = [self opaqueAncestor];
    324         const NSRect *dirtyRects;
    325         int dirtyRectCount, dirtyRectIndex;
    326         [opaqueAncestor getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount];
    327 
    328         for (dirtyRectIndex = 0; dirtyRectIndex < dirtyRectCount; dirtyRectIndex++) {
    329             NSRect dirtyRect = [self convertRect:dirtyRects[dirtyRectIndex] fromView:opaqueAncestor];
    330             if (!NSEqualSizes(dirtyRect.size, NSZeroSize)) {
    331                 // Create a region for this dirty rect
    332                 RgnHandle dirtyRectRegion = NewRgn();
    333                 SetRectRgn(dirtyRectRegion, NSMinX(dirtyRect), NSMinY(dirtyRect), NSMaxX(dirtyRect), NSMaxY(dirtyRect));
     319    switch (drawingModel) {
     320#ifndef NP_NO_QUICKDRAW
     321        case NPDrawingModelQuickDraw:
     322        {
     323            // Set up NS_Port.
     324            Rect portBounds;
     325            CGrafPtr port = GetWindowPort(windowRef);
     326            GetPortBounds(port, &portBounds);
     327            nPort.qdPort.port = port;
     328            nPort.qdPort.portx = (int32)-boundsInWindow.origin.x;
     329            nPort.qdPort.porty = (int32)-boundsInWindow.origin.y;
     330            window.window = &nPort;
     331
     332            PortState_QD *qdPortState = malloc(sizeof(PortState_QD));
     333            portState = (PortState)qdPortState;
     334           
     335            GetPort(&qdPortState->oldPort);   
     336
     337            qdPortState->oldOrigin.h = portBounds.left;
     338            qdPortState->oldOrigin.v = portBounds.top;
     339
     340            qdPortState->oldClipRegion = NewRgn();
     341            GetPortClipRegion(port, qdPortState->oldClipRegion);
     342           
     343            qdPortState->oldVisibleRegion = NewRgn();
     344            GetPortVisibleRegion(port, qdPortState->oldVisibleRegion);
     345           
     346            RgnHandle clipRegion = NewRgn();
     347            qdPortState->clipRegion = clipRegion;
     348           
     349            MacSetRectRgn(clipRegion,
     350                window.clipRect.left + nPort.qdPort.portx, window.clipRect.top + nPort.qdPort.porty,
     351                window.clipRect.right + nPort.qdPort.portx, window.clipRect.bottom + nPort.qdPort.porty);
     352           
     353            // Clip to dirty region when updating in "windowless" mode (transparent)
     354            if (forUpdate && isTransparent) {
     355                RgnHandle viewClipRegion = NewRgn();
    334356               
    335                 // Union this dirty rect with the rest of the dirty rects
    336                 UnionRgn(viewClipRegion, dirtyRectRegion, viewClipRegion);
    337                 DisposeRgn(dirtyRectRegion);
     357                // Get list of dirty rects from the opaque ancestor -- WebKit does some tricks with invalidation and
     358                // display to enable z-ordering for NSViews; a side-effect of this is that only the WebHTMLView
     359                // knows about the true set of dirty rects.
     360                NSView *opaqueAncestor = [self opaqueAncestor];
     361                const NSRect *dirtyRects;
     362                int dirtyRectCount, dirtyRectIndex;
     363                [opaqueAncestor getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount];
     364
     365                for (dirtyRectIndex = 0; dirtyRectIndex < dirtyRectCount; dirtyRectIndex++) {
     366                    NSRect dirtyRect = [self convertRect:dirtyRects[dirtyRectIndex] fromView:opaqueAncestor];
     367                    if (!NSEqualSizes(dirtyRect.size, NSZeroSize)) {
     368                        // Create a region for this dirty rect
     369                        RgnHandle dirtyRectRegion = NewRgn();
     370                        SetRectRgn(dirtyRectRegion, NSMinX(dirtyRect), NSMinY(dirtyRect), NSMaxX(dirtyRect), NSMaxY(dirtyRect));
     371                       
     372                        // Union this dirty rect with the rest of the dirty rects
     373                        UnionRgn(viewClipRegion, dirtyRectRegion, viewClipRegion);
     374                        DisposeRgn(dirtyRectRegion);
     375                    }
     376                }
     377           
     378                // Intersect the dirty region with the clip region, so that we only draw over dirty parts
     379                SectRgn(clipRegion, viewClipRegion, clipRegion);
     380                DisposeRgn(viewClipRegion);
    338381            }
    339         }
    340    
    341         // Intersect the dirty region with the clip region, so that we only draw over dirty parts
    342         SectRgn(clipRegion, viewClipRegion, clipRegion);
    343         DisposeRgn(viewClipRegion);
    344     }
    345    
    346     portState.forUpdate = forUpdate;
    347    
    348     // Switch to the port and set it up.
    349     SetPort(port);
    350 
    351     PenNormal();
    352     ForeColor(blackColor);
    353     BackColor(whiteColor);
    354    
    355     SetOrigin(nPort.portx, nPort.porty);
    356 
    357     SetPortClipRegion(nPort.port, clipRegion);
    358 
    359     if (forUpdate) {
    360         // AppKit may have tried to help us by doing a BeginUpdate.
    361         // But the invalid region at that level didn't include AppKit's notion of what was not valid.
    362         // We reset the port's visible region to counteract what BeginUpdate did.
    363         SetPortVisibleRegion(nPort.port, clipRegion);
    364 
    365         // Some plugins do their own BeginUpdate/EndUpdate.
    366         // For those, we must make sure that the update region contains the area we want to draw.
    367         InvalWindowRgn(windowRef, clipRegion);
     382           
     383            qdPortState->forUpdate = forUpdate;
     384           
     385            // Switch to the port and set it up.
     386            SetPort(port);
     387
     388            PenNormal();
     389            ForeColor(blackColor);
     390            BackColor(whiteColor);
     391           
     392            SetOrigin(nPort.qdPort.portx, nPort.qdPort.porty);
     393
     394            SetPortClipRegion(nPort.qdPort.port, clipRegion);
     395
     396            if (forUpdate) {
     397                // AppKit may have tried to help us by doing a BeginUpdate.
     398                // But the invalid region at that level didn't include AppKit's notion of what was not valid.
     399                // We reset the port's visible region to counteract what BeginUpdate did.
     400                SetPortVisibleRegion(nPort.qdPort.port, clipRegion);
     401
     402                // Some plugins do their own BeginUpdate/EndUpdate.
     403                // For those, we must make sure that the update region contains the area we want to draw.
     404                InvalWindowRgn(windowRef, clipRegion);
     405            }
     406        }
     407        break;
     408#endif /* NP_NO_QUICKDRAW */
     409       
     410        case NPDrawingModelCoreGraphics:
     411        {           
     412            ASSERT([NSView focusView] == self);
     413
     414            PortState_CG *cgPortState = (PortState_CG *)malloc(sizeof(PortState_CG));
     415            portState = (PortState)cgPortState;
     416            cgPortState->forUpdate = YES;
     417            cgPortState->context = [[NSGraphicsContext currentContext] graphicsPort];
     418           
     419            // Update the plugin's window/context
     420            nPort.cgPort.window = windowRef;
     421            nPort.cgPort.context = cgPortState->context;
     422            window.window = &nPort.cgPort;
     423
     424            // Save current graphics context's state; will be restored by -restorePortState:
     425            CGContextSaveGState(nPort.cgPort.context);
     426           
     427            // FIXME (4544971): Clip to dirty region when updating in "windowless" mode (transparent), like in the QD case
     428        }
     429        break;
     430       
     431        default:
     432            ASSERT_NOT_REACHED();
     433            portState = NULL;
     434        break;
    368435    }
    369436   
     
    371438}
    372439
    373 - (PortState)saveAndSetPortState
    374 {
    375     return [self saveAndSetPortStateForUpdate:NO];
     440- (PortState)saveAndSetNewPortState
     441{
     442    return [self saveAndSetNewPortStateForUpdate:NO];
    376443}
    377444
     
    379446{
    380447    ASSERT([self currentWindow]);
    381    
    382     WindowRef windowRef = [[self currentWindow] windowRef];
    383     CGrafPtr port = GetWindowPort(windowRef);
    384 
    385     if (portState.forUpdate) {
    386         ValidWindowRgn(windowRef, portState.clipRegion);
    387     }
    388    
    389     SetOrigin(portState.oldOrigin.h, portState.oldOrigin.v);
    390 
    391     SetPortClipRegion(port, portState.oldClipRegion);
    392     if (portState.forUpdate) {
    393         SetPortVisibleRegion(port, portState.oldVisibleRegion);
    394     }
    395 
    396     DisposeRgn(portState.oldClipRegion);
    397     DisposeRgn(portState.oldVisibleRegion);
    398     DisposeRgn(portState.clipRegion);
    399 
    400     SetPort(portState.oldPort);
     448    ASSERT(portState);
     449   
     450    switch (drawingModel) {
     451#ifndef NP_NO_QUICKDRAW
     452        case NPDrawingModelQuickDraw:
     453        {
     454            PortState_QD *qdPortState = (PortState_QD *)portState;
     455            WindowRef windowRef = [[self currentWindow] windowRef];
     456            CGrafPtr port = GetWindowPort(windowRef);
     457            if (qdPortState->forUpdate)
     458                ValidWindowRgn(windowRef, qdPortState->clipRegion);
     459           
     460            SetOrigin(qdPortState->oldOrigin.h, qdPortState->oldOrigin.v);
     461
     462            SetPortClipRegion(port, qdPortState->oldClipRegion);
     463            if (qdPortState->forUpdate)
     464                SetPortVisibleRegion(port, qdPortState->oldVisibleRegion);
     465
     466            DisposeRgn(qdPortState->oldClipRegion);
     467            DisposeRgn(qdPortState->oldVisibleRegion);
     468            DisposeRgn(qdPortState->clipRegion);
     469
     470            SetPort(qdPortState->oldPort);
     471        }
     472        break;
     473#endif /* NP_NO_QUICKDRAW */
     474       
     475        case NPDrawingModelCoreGraphics:
     476        {
     477            PortState_CG *cgPortState = (PortState_CG *)portState;
     478            if (cgPortState->forUpdate) {
     479                ASSERT([NSView focusView] == self);
     480                ASSERT(cgPortState->context == nPort.cgPort.context);
     481                CGContextRestoreGState(nPort.cgPort.context);
     482            }
     483        }
     484        break;
     485       
     486        default:
     487            ASSERT_NOT_REACHED();
     488        break;
     489    }
    401490}
    402491
     
    409498    // currentEventIsUserGesture flag to true. This is important to differentiate legitimate
    410499    // window.open() calls;  we still want to allow those.  See rdar://problem/4010765
    411     if(event->what == mouseDown || event->what == keyDown || event->what == mouseUp || event->what == autoKey) {
     500    if (event->what == mouseDown || event->what == keyDown || event->what == mouseUp || event->what == autoKey)
    412501        currentEventIsUserGesture = YES;
    413     }
    414502   
    415503    suspendKeyUpEvents = NO;
    416504   
    417     if (!isStarted) {
     505    if (!isStarted)
    418506        return NO;
    419     }
    420507
    421508    ASSERT(NPP_HandleEvent);
     
    425512    // protecting only against this one case, which actually comes up when
    426513    // you first install the SVG viewer plug-in.
    427     if (inSetWindow) {
     514    if (inSetWindow)
    428515        return NO;
    429     }
    430516
    431517    BOOL defers = [[self webView] defersCallbacks];
    432     if (!defers) {
     518    if (!defers)
    433519        [[self webView] setDefersCallbacks:YES];
    434     }
    435 
    436     PortState portState = [self saveAndSetPortStateForUpdate:event->what == updateEvt];
    437    
    438     // We may have changed the window, so inform the plug-in.
    439     [self setWindowIfNecessary];
    440 
     520
     521    // Can only send updateEvt to CoreGraphics plugins when actually drawing
     522    ASSERT(drawingModel != NPDrawingModelCoreGraphics || event->what != updateEvt || [NSView focusView] == self);
     523   
     524    BOOL updating = event->what == updateEvt;
     525    BOOL acceptedEvent = NO;
     526    PortState portState;
     527    if (drawingModel != NPDrawingModelCoreGraphics || event->what == updateEvt) {
     528        // Can only save/set port state when updating in CoreGraphics mode.  We can save/set the port state
     529        // at any time in other modes.
     530        portState = [self saveAndSetNewPortStateForUpdate:updating];
     531    } else
     532        portState = NULL;
     533       
     534    if (portState) {
     535        // We may have changed the window, so inform the plug-in.
     536        [self setWindowIfNecessary];
     537       
    441538#ifndef NDEBUG
    442     // Draw green to help debug.
    443     // If we see any green we know something's wrong.
    444     if (!isTransparent && event->what == updateEvt) {
    445         ForeColor(greenColor);
    446         const Rect bigRect = { -10000, -10000, 10000, 10000 };
    447         PaintRect(&bigRect);
    448         ForeColor(blackColor);
    449     }
     539        // Draw green to help debug.
     540        // If we see any green we know something's wrong.
     541        if (!isTransparent && event->what == updateEvt) {
     542            ForeColor(greenColor);
     543            const Rect bigRect = { -10000, -10000, 10000, 10000 };
     544            PaintRect(&bigRect);
     545            ForeColor(blackColor);
     546        }
    450547#endif
    451548   
    452     // Temporarily retain self in case the plug-in view is released while sending an event.
    453     [self retain];
    454 
    455     BOOL acceptedEvent = NPP_HandleEvent(instance, event);
    456 
     549        // Temporarily retain self in case the plug-in view is released while sending an event.
     550        [[self retain] autorelease];
     551
     552        acceptedEvent = NPP_HandleEvent(instance, event);
     553    }
     554   
    457555    currentEventIsUserGesture = NO;
    458556   
    459     if ([self currentWindow]) {
    460         [self restorePortState:portState];
    461     }
    462 
    463     if (!defers) {
     557    if (portState) {
     558        if ([self currentWindow])
     559            [self restorePortState:portState];
     560        free(portState);
     561    }
     562
     563    if (!defers)
    464564        [[self webView] setDefersCallbacks:NO];
    465     }
    466    
    467     [self release];
    468    
     565           
    469566    return acceptedEvent;
    470567}
     
    821918- (BOOL)isNewWindowEqualToOldWindow
    822919{
    823     if (window.x != lastSetWindow.x) {
     920    if (window.x != lastSetWindow.x)
    824921        return NO;
    825     }
    826     if (window.y != lastSetWindow.y) {
     922    if (window.y != lastSetWindow.y)
    827923        return NO;
    828     }
    829     if (window.width != lastSetWindow.width) {
     924    if (window.width != lastSetWindow.width)
    830925        return NO;
    831     }
    832     if (window.height != lastSetWindow.height) {
     926    if (window.height != lastSetWindow.height)
    833927        return NO;
    834     }
    835     if (window.clipRect.top != lastSetWindow.clipRect.top) {
     928    if (window.clipRect.top != lastSetWindow.clipRect.top)
    836929        return NO;
    837     }
    838     if (window.clipRect.left != lastSetWindow.clipRect.left) {
     930    if (window.clipRect.left != lastSetWindow.clipRect.left)
    839931        return NO;
    840     }
    841     if (window.clipRect.bottom  != lastSetWindow.clipRect.bottom ) {
     932    if (window.clipRect.bottom  != lastSetWindow.clipRect.bottom)
    842933        return NO;
    843     }
    844     if (window.clipRect.right != lastSetWindow.clipRect.right) {
     934    if (window.clipRect.right != lastSetWindow.clipRect.right)
    845935        return NO;
    846     }
    847     if (window.type != lastSetWindow.type) {
     936    if (window.type != lastSetWindow.type)
    848937        return NO;
    849     }
    850     if (nPort.portx != lastSetPort.portx) {
    851         return NO;
    852     }
    853     if (nPort.porty != lastSetPort.porty) {
    854         return NO;
    855     }
    856     if (nPort.port != lastSetPort.port) {
    857         return NO;
     938   
     939    switch (drawingModel) {
     940#ifndef NP_NO_QUICKDRAW
     941        case NPDrawingModelQuickDraw:
     942            if (nPort.qdPort.portx != lastSetPort.qdPort.portx)
     943                return NO;
     944            if (nPort.qdPort.porty != lastSetPort.qdPort.porty)
     945                return NO;
     946            if (nPort.qdPort.port != lastSetPort.qdPort.port)
     947                return NO;
     948        break;
     949#endif /* NP_NO_QUICKDRAW */
     950           
     951        case NPDrawingModelCoreGraphics:
     952            if (nPort.cgPort.window != lastSetPort.cgPort.window)
     953                return NO;
     954            if (nPort.cgPort.context != lastSetPort.cgPort.context)
     955                return NO;
     956        break;
     957           
     958        default:
     959            ASSERT_NOT_REACHED();
     960        break;
    858961    }
    859962   
     
    862965
    863966- (void)updateAndSetWindow
    864 {   
    865     PortState portState = [self saveAndSetPortState];
    866     [self setWindowIfNecessary];
    867     [self restorePortState:portState];
     967{
     968    if (drawingModel == NPDrawingModelCoreGraphics) {
     969        // Can only update CoreGraphics plugins while redrawing the plugin view
     970        [self setNeedsDisplay:YES];
     971        return;
     972    }
     973   
     974    // Can't update the plugin if it has not started (or has been stopped)
     975    if (!isStarted)
     976        return;
     977       
     978    PortState portState = [self saveAndSetNewPortState];
     979    if (portState) {
     980        [self setWindowIfNecessary];
     981        [self restorePortState:portState];
     982        free(portState);
     983    }
    868984}
    869985
     
    883999       
    8841000        inSetWindow = YES;
     1001       
     1002        // A CoreGraphics plugin's window may only be set while the plugin is being updated
     1003        ASSERT(drawingModel != NPDrawingModelCoreGraphics || [NSView focusView] == self);
     1004       
    8851005        npErr = NPP_SetWindow(instance, &window);
    8861006        inSetWindow = NO;
    8871007
    888         LOG(Plugins, "NPP_SetWindow: %d, port=0x%08x, window.x:%d window.y:%d",
    889             npErr, (int)nPort.port, (int)window.x, (int)window.y);
     1008#ifndef NDEBUG
     1009        switch (drawingModel) {
     1010#ifndef NP_NO_QUICKDRAW
     1011            case NPDrawingModelQuickDraw:
     1012                LOG(Plugins, "NPP_SetWindow (QuickDraw): %d, port=0x%08x, window.x:%d window.y:%d",
     1013                npErr, (int)nPort.qdPort.port, (int)window.x, (int)window.y);
     1014            break;
     1015#endif /* NP_NO_QUICKDRAW */
     1016           
     1017            case NPDrawingModelCoreGraphics:
     1018                LOG(Plugins, "NPP_SetWindow (CoreGraphics): %d, window=%p, context=%p, window.x:%d window.y:%d",
     1019                npErr, nPort.cgPort.window, nPort.cgPort.context, (int)window.x, (int)window.y);
     1020            break;
     1021           
     1022            default:
     1023                ASSERT_NOT_REACHED();
     1024            break;
     1025        }
     1026#endif /* !defined(NDEBUG) */
    8901027       
    8911028        lastSetWindow = window;
     
    10011138    ASSERT(NPP_New);
    10021139
     1140    // Initialize drawingModel to an invalid value so that we can detect when the plugin does not specify a drawingModel
     1141    drawingModel = -1;
     1142   
    10031143    [[self class] setCurrentPluginView:self];
    10041144    NPError npErr = NPP_New((char *)[MIMEType cString], instance, mode, argsCount, cAttributes, cValues, NULL);
    10051145    [[self class] setCurrentPluginView:nil];
    1006    
     1146
     1147    if (drawingModel == (NPDrawingModel)-1) {
     1148#ifndef NP_NO_QUICKDRAW
     1149        // Default to QuickDraw if the plugin did not specify a drawing model.
     1150        drawingModel = NPDrawingModelQuickDraw;
     1151#else
     1152        // QuickDraw is not available, so we can't default to it.  We could default to CoreGraphics instead, but
     1153        // if the plugin did not specify the CoreGraphics drawing model then it must be one of the old QuickDraw
     1154        // plugins.  Thus, the plugin is unsupported and should not be started.  Destroy it here and bail out.
     1155        LOG(Plugins, "Plugin only supports QuickDraw, but QuickDraw is unavailable: %@", plugin);
     1156        NPP_Destroy(instance, NULL);
     1157        instance->pdata = NULL;
     1158        return NO;
     1159#endif
     1160    }
     1161       
    10071162    LOG(Plugins, "NPP_New: %d", npErr);
    10081163    if (npErr != NPERR_NO_ERROR) {
     
    10101165        return NO;
    10111166    }
    1012 
     1167   
    10131168    isStarted = YES;
    10141169       
     
    12651420}
    12661421
     1422#ifndef NP_NO_QUICKDRAW
    12671423-(void)tellQuickTimeToChill
    12681424{
     1425    ASSERT(drawingModel == NPDrawingModelQuickDraw);
     1426   
    12691427    // Make a call to the secret QuickDraw API that makes QuickTime calm down.
    12701428    WindowRef windowRef = [[self window] windowRef];
     
    12771435        WKCallDrawingNotification(port, &bounds);
    12781436}
     1437#endif /* NP_NO_QUICKDRAW */
    12791438
    12801439- (void)viewWillMoveToWindow:(NSWindow *)newWindow
    12811440{
    1282     [self tellQuickTimeToChill];
     1441#ifndef NP_NO_QUICKDRAW
     1442    if (drawingModel == NPDrawingModelQuickDraw)
     1443        [self tellQuickTimeToChill];
     1444#endif
    12831445
    12841446    // We must remove the tracking rect before we move to the new window.
     
    13521514- (void)viewHasMoved:(NSNotification *)notification
    13531515{
    1354     [self tellQuickTimeToChill];
     1516#ifndef NP_NO_QUICKDRAW
     1517    if (drawingModel == NPDrawingModelQuickDraw)
     1518        [self tellQuickTimeToChill];
     1519#endif
    13551520    [self updateAndSetWindow];
    13561521    [self resetTrackingRect];
     
    18031968}
    18041969
    1805 -(void)invalidateRegion:(NPRegion)invalidRegion
     1970- (void)invalidateRegion:(NPRegion)invalidRegion
    18061971{
    18071972    LOG(Plugins, "NPN_InvalidateRegion");
    1808     Rect invalidRect;
    1809     GetRegionBounds(invalidRegion, &invalidRect);
    1810     [self setNeedsDisplayInRect:NSMakeRect(invalidRect.left, invalidRect.top,
    1811         (float)invalidRect.right - invalidRect.left, (float)invalidRect.bottom - invalidRect.top)];
     1973    NSRect invalidRect;
     1974    switch (drawingModel) {
     1975#ifndef NP_NO_QUICKDRAW
     1976        case NPDrawingModelQuickDraw: {
     1977            Rect qdRect;
     1978            GetRegionBounds(invalidRegion, &qdRect);
     1979            invalidRect = NSMakeRect(qdRect.left, qdRect.top, qdRect.right - qdRect.left, qdRect.bottom - qdRect.top);
     1980        }
     1981        break;
     1982#endif /* NP_NO_QUICKDRAW */
     1983       
     1984        case NPDrawingModelCoreGraphics: {
     1985            CGRect cgRect = CGPathGetBoundingBox((NPCGRegion)invalidRegion);
     1986            invalidRect = *(NSRect *)&cgRect;
     1987        }
     1988        break;
     1989   
     1990        default:
     1991            ASSERT_NOT_REACHED();
     1992        break;
     1993    }
     1994   
     1995    [self setNeedsDisplayInRect:invalidRect];
    18121996}
    18131997
     
    18212005- (NPError)getVariable:(NPNVariable)variable value:(void *)value
    18222006{
    1823     if (variable == NPNVWindowNPObject) {
    1824         NPObject *windowScriptObject = [[[self webFrame] _bridge] windowScriptNPObject];
    1825 
    1826         // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess>
    1827         if (windowScriptObject)
    1828             _NPN_RetainObject(windowScriptObject);
    1829        
    1830         void **v = (void **)value;
    1831         *v = windowScriptObject;
    1832        
    1833         return NPERR_NO_ERROR;
    1834     }
     2007    switch (variable) {
     2008        case NPNVWindowNPObject: {
     2009            NPObject *windowScriptObject = [[[self webFrame] _bridge] windowScriptNPObject];
     2010
     2011            // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess>
     2012            if (windowScriptObject)
     2013                _NPN_RetainObject(windowScriptObject);
     2014           
     2015            void **v = (void **)value;
     2016            *v = windowScriptObject;
     2017
     2018            return NPERR_NO_ERROR;
     2019        }
     2020       
     2021        case NPNVpluginDrawingModel:
     2022        {
     2023            *(NPDrawingModel *)value = drawingModel;
     2024            return NPERR_NO_ERROR;
     2025        }
     2026
     2027#ifndef NP_NO_QUICKDRAW
     2028        case NPNVsupportsQuickDrawBool:
     2029        {
     2030            *(NPBool *)value = TRUE;
     2031            return NPERR_NO_ERROR;
     2032        }
     2033#endif /* NP_NO_QUICKDRAW */
     2034       
     2035        case NPNVsupportsCoreGraphicsBool:
     2036        {
     2037            *(NPBool *)value = TRUE;
     2038            return NPERR_NO_ERROR;
     2039        }
     2040       
     2041        default:
     2042            break;
     2043    }
     2044
    18352045    return NPERR_GENERIC_ERROR;
    18362046}
     
    18502060           
    18512061            return NPERR_NO_ERROR;
     2062        }
     2063       
     2064        case NPNVpluginDrawingModel:
     2065        {
     2066            // Can only set drawing model inside NPP_New()
     2067            if (self != [[self class] currentPluginView])
     2068                return NPERR_GENERIC_ERROR;
     2069           
     2070            // Check for valid, supported drawing model
     2071            NPDrawingModel newDrawingModel = (NPDrawingModel)value;
     2072            switch (newDrawingModel) {
     2073                // Supported drawing models:
     2074#ifndef NP_NO_QUICKDRAW
     2075                case NPDrawingModelQuickDraw:
     2076#endif
     2077                case NPDrawingModelCoreGraphics:
     2078                    drawingModel = newDrawingModel;
     2079                    return NPERR_NO_ERROR;
     2080               
     2081                // Unsupported (or unknown) drawing models:
     2082                default:
     2083                    LOG(Plugins, "Plugin %@ uses unsupported drawing model: %d", plugin, drawingModel);
     2084                    return NPERR_GENERIC_ERROR;
     2085            }
    18522086        }
    18532087       
Note: See TracChangeset for help on using the changeset viewer.