1 /*
   2  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.webkit;
  27 
  28 import static com.sun.webkit.network.URLs.newURL;
  29 
  30 import java.net.MalformedURLException;
  31 import java.net.URL;
  32 import java.util.logging.Level;
  33 import java.util.logging.Logger;
  34 
  35 import com.sun.webkit.plugin.Plugin;
  36 import com.sun.webkit.plugin.PluginListener;
  37 import com.sun.webkit.plugin.PluginManager;
  38 import com.sun.webkit.graphics.WCGraphicsContext;
  39 import com.sun.webkit.graphics.WCRectangle;
  40 
  41 final class WCPluginWidget extends WCWidget implements PluginListener {
  42 
  43     private final static Logger log =
  44         Logger.getLogger(WCPluginWidget.class.getName());
  45 
  46     private final Plugin plugin;
  47     private long pData = 0L;//for native code
  48 
  49     private static native void initIDs();
  50 
  51     static {
  52         initIDs();
  53     };
  54 
  55     private WCPluginWidget(
  56             WebPage webPage,
  57             Plugin plugin,
  58             int width, int height)
  59     {
  60         super(webPage);
  61         this.plugin = plugin;
  62         setBounds(0, 0, width, height);
  63         //webPage.getPageClient().XXX; - implement for native level support
  64         WebPageClient wpc = webPage.getPageClient();
  65         this.plugin.activate(
  66                 null==wpc ? null : wpc.getContainer(),
  67                 this);
  68     }
  69 
  70     @Override
  71     protected void requestFocus() {
  72         plugin.requestFocus();
  73     }
  74 
  75     private static WCPluginWidget create(
  76         final WebPage webPage,
  77         final int width, final int height,
  78         final String urlString,
  79         final String mimeType,
  80         final String[] pNames,
  81         final String[] pValues)
  82     {
  83         URL url = null;
  84         try {
  85             url = newURL(urlString);
  86         } catch (MalformedURLException ex) {
  87             log.log(Level.FINE, null, ex);
  88         }
  89         return new WCPluginWidget(
  90                 webPage,
  91                 PluginManager.createPlugin(url, mimeType, pNames, pValues),
  92                 width, height);
  93     }
  94 
  95     private void fwkSetNativeContainerBounds(
  96             int x,
  97             int y,
  98             int width,
  99             int height)
 100     {
 101         plugin.setNativeContainerBounds(x, y, width, height);
 102     }
 103 
 104     @Override
 105     void setBounds(
 106             //page coordinates!!!
 107             int x,
 108             int y,
 109             int width,
 110             int height)
 111     {
 112         super.setBounds(x, y, width, height);
 113         plugin.setBounds(x, y, width, height);
 114     }
 115 
 116     //TODO: fwk call have to be implemented in WCWidget
 117     //@Override
 118     private void setEnabled(boolean enabled){
 119         plugin.setEnabled(enabled);
 120     }
 121 
 122     @Override
 123     protected void setVisible(boolean visible){
 124         plugin.setVisible(visible);
 125     }
 126 
 127 
 128     @Override
 129     protected void destroy() {
 130         pData = 0L;
 131         plugin.destroy();
 132     }
 133 
 134     private void paint(WCGraphicsContext g,
 135             //page offsets
 136             final int x,
 137             final int y,
 138             final int width,
 139             final int height)
 140     {
 141         WCRectangle bd = getBounds();
 142         WCRectangle clip = bd.intersection( new WCRectangle(x, y, width, height) );
 143         if( !clip.isEmpty() ){
 144             g.translate(bd.getX(), bd.getY());
 145             clip.translate(-bd.getX(), -bd.getY());
 146             g.setClip(clip.getIntX(), clip.getIntY(), clip.getIntWidth(), clip.getIntHeight());
 147             plugin.paint(
 148                     g,
 149                     //client coordinates!!!
 150                     clip.getIntX(),
 151                     clip.getIntY(),
 152                     clip.getIntWidth(),
 153                     clip.getIntHeight());
 154         }
 155     }
 156 
 157     //converts widget coordinates to container
 158     private native WCRectangle twkConvertToPage(WCRectangle rc);
 159 
 160     private native void twkInvalidateWindowlessPluginRect(
 161             //client coordinates!!!
 162             int x,
 163             int y,
 164             int width,
 165             int height);
 166 
 167     private boolean fwkHandleMouseEvent(
 168             String type,
 169             int offsetX,
 170             int offsetY,
 171             int screenX,
 172             int screenY,
 173             int button,
 174             boolean buttonDown,
 175             boolean altKey,
 176             boolean metaKey,
 177             boolean ctrlKey,
 178             boolean shiftKey,
 179             long timeStamp)
 180     {
 181         return plugin.handleMouseEvent(
 182                 type,
 183                 offsetX, offsetY,
 184                 screenX, screenY,
 185                 button, buttonDown,
 186                 altKey, metaKey, ctrlKey, shiftKey, timeStamp);
 187     }
 188 
 189     //PluginListener
 190     public void fwkRedraw(
 191             //client coordinates!!!
 192             final int x,
 193             final int y,
 194             final int width,
 195             final int height,
 196             final boolean eraseBackground)
 197     {
 198         twkInvalidateWindowlessPluginRect(x, y, width, height);
 199     }
 200 
 201     private native void twkSetPlugunFocused(boolean isFocused);
 202 
 203     public String fwkEvent(
 204             final int eventId,
 205             final String name,
 206             final String params)
 207     {
 208         if(Plugin.EVENT_FOCUSCHANGE==eventId && Boolean.parseBoolean(params)){
 209             twkSetPlugunFocused(Boolean.valueOf(params));
 210         }
 211         return "";
 212     }
 213 }
 214