1 /*
   2  * Copyright (c) 2011, 2018, 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 com.sun.javafx.logging.PlatformLogger;
  29 import static com.sun.webkit.network.URLs.newURL;
  30 
  31 import java.net.MalformedURLException;
  32 import java.net.URL;
  33 
  34 import com.sun.webkit.plugin.Plugin;
  35 import com.sun.webkit.plugin.PluginListener;
  36 import com.sun.webkit.plugin.PluginManager;
  37 import com.sun.webkit.graphics.WCGraphicsContext;
  38 import com.sun.webkit.graphics.WCRectangle;
  39 
  40 final class WCPluginWidget extends WCWidget implements PluginListener {
  41 
  42     private final static PlatformLogger log =
  43             PlatformLogger.getLogger(WCPluginWidget.class.getName());
  44 
  45     private final Plugin plugin;
  46     private long pData = 0L;//for native code
  47 
  48     private static native void initIDs();
  49 
  50     static {
  51         initIDs();
  52     };
  53 
  54     private WCPluginWidget(
  55             WebPage webPage,
  56             Plugin plugin,
  57             int width, int height)
  58     {
  59         super(webPage);
  60         this.plugin = plugin;
  61         setBounds(0, 0, width, height);
  62         //webPage.getPageClient().XXX; - implement for native level support
  63         WebPageClient wpc = webPage.getPageClient();
  64         this.plugin.activate(
  65                 null==wpc ? null : wpc.getContainer(),
  66                 this);
  67     }
  68 
  69     @Override
  70     protected void requestFocus() {
  71         plugin.requestFocus();
  72     }
  73 
  74     private static WCPluginWidget create(
  75         final WebPage webPage,
  76         final int width, final int height,
  77         final String urlString,
  78         final String mimeType,
  79         final String[] pNames,
  80         final String[] pValues)
  81     {
  82         URL url = null;
  83         try {
  84             url = newURL(urlString);
  85         } catch (MalformedURLException ex) {
  86             log.fine(null, ex);
  87         }
  88         return new WCPluginWidget(
  89                 webPage,
  90                 PluginManager.createPlugin(url, mimeType, pNames, pValues),
  91                 width, height);
  92     }
  93 
  94     private void fwkSetNativeContainerBounds(
  95             int x,
  96             int y,
  97             int width,
  98             int height)
  99     {
 100         plugin.setNativeContainerBounds(x, y, width, height);
 101     }
 102 
 103     @Override
 104     void setBounds(
 105             //page coordinates!!!
 106             int x,
 107             int y,
 108             int width,
 109             int height)
 110     {
 111         super.setBounds(x, y, width, height);
 112         plugin.setBounds(x, y, width, height);
 113     }
 114 
 115     //TODO: fwk call have to be implemented in WCWidget
 116     //@Override
 117     private void setEnabled(boolean enabled){
 118         plugin.setEnabled(enabled);
 119     }
 120 
 121     @Override
 122     protected void setVisible(boolean visible){
 123         plugin.setVisible(visible);
 124     }
 125 
 126 
 127     @Override
 128     protected void destroy() {
 129         pData = 0L;
 130         plugin.destroy();
 131     }
 132 
 133     private void paint(WCGraphicsContext g,
 134             //page offsets
 135             final int x,
 136             final int y,
 137             final int width,
 138             final int height)
 139     {
 140         WCRectangle bd = getBounds();
 141         WCRectangle clip = bd.intersection( new WCRectangle(x, y, width, height) );
 142         if( !clip.isEmpty() ){
 143             g.translate(bd.getX(), bd.getY());
 144             clip.translate(-bd.getX(), -bd.getY());
 145             g.setClip(clip.getIntX(), clip.getIntY(), clip.getIntWidth(), clip.getIntHeight());
 146             plugin.paint(
 147                     g,
 148                     //client coordinates!!!
 149                     clip.getIntX(),
 150                     clip.getIntY(),
 151                     clip.getIntWidth(),
 152                     clip.getIntHeight());
 153         }
 154     }
 155 
 156     //converts widget coordinates to container
 157     private native WCRectangle twkConvertToPage(WCRectangle rc);
 158 
 159     private native void twkInvalidateWindowlessPluginRect(
 160             //client coordinates!!!
 161             int x,
 162             int y,
 163             int width,
 164             int height);
 165 
 166     private boolean fwkHandleMouseEvent(
 167             String type,
 168             int offsetX,
 169             int offsetY,
 170             int screenX,
 171             int screenY,
 172             int button,
 173             boolean buttonDown,
 174             boolean altKey,
 175             boolean metaKey,
 176             boolean ctrlKey,
 177             boolean shiftKey,
 178             long timeStamp)
 179     {
 180         return plugin.handleMouseEvent(
 181                 type,
 182                 offsetX, offsetY,
 183                 screenX, screenY,
 184                 button, buttonDown,
 185                 altKey, metaKey, ctrlKey, shiftKey, timeStamp);
 186     }
 187 
 188     //PluginListener
 189     public void fwkRedraw(
 190             //client coordinates!!!
 191             final int x,
 192             final int y,
 193             final int width,
 194             final int height,
 195             final boolean eraseBackground)
 196     {
 197         twkInvalidateWindowlessPluginRect(x, y, width, height);
 198     }
 199 
 200     private native void twkSetPlugunFocused(boolean isFocused);
 201 
 202     public String fwkEvent(
 203             final int eventId,
 204             final String name,
 205             final String params)
 206     {
 207         if(Plugin.EVENT_FOCUSCHANGE==eventId && Boolean.parseBoolean(params)){
 208             twkSetPlugunFocused(Boolean.valueOf(params));
 209         }
 210         return "";
 211     }
 212 }
 213