1 /*
   2  * Copyright (c) 2010, 2013, 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.javafx.tk.quantum;
  27 
  28 import java.security.AccessControlContext;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.util.List;
  32 
  33 import com.sun.javafx.embed.AbstractEvents;
  34 import com.sun.javafx.embed.EmbeddedStageInterface;
  35 import com.sun.javafx.embed.HostInterface;
  36 import com.sun.javafx.tk.TKScene;
  37 import com.sun.javafx.tk.Toolkit;
  38 import com.sun.javafx.accessible.providers.AccessibleProvider;
  39 import com.sun.javafx.accessible.providers.AccessibleStageProvider;
  40 import javafx.application.Platform;
  41 
  42 final class EmbeddedStage extends GlassStage implements EmbeddedStageInterface {
  43 
  44     private HostInterface host;
  45 
  46     public EmbeddedStage(HostInterface host) {
  47         this.host = host;
  48     }
  49 
  50     // TKStage methods
  51 
  52     @Override
  53     public TKScene createTKScene(boolean depthBuffer, boolean antiAliasing, AccessControlContext acc) {
  54         EmbeddedScene scene = new EmbeddedScene(host, depthBuffer, antiAliasing);
  55         scene.setSecurityContext(acc);
  56         return scene;
  57     }
  58 
  59     @Override
  60     public void setScene(TKScene scene) {
  61         if (scene != null) {
  62             assert scene instanceof EmbeddedScene;
  63         }
  64         super.setScene(scene);
  65     }
  66 
  67     @Override
  68     public void setBounds(float x, float y, boolean xSet, boolean ySet,
  69                           float w, float h, float cw, float ch,
  70                           float xGravity, float yGravity)
  71     {
  72         if (QuantumToolkit.verbose) {
  73             System.err.println("EmbeddedStage.setBounds: x=" + x + " y=" + y + " xSet=" + xSet + " ySet=" + ySet +
  74                                " w=" + w + " h=" + " cw=" + cw + " ch=" + ch);
  75         }
  76         float newW = w > 0 ? w : cw;
  77         float newH = h > 0 ? h : ch;
  78         if ((newW > 0) && (newH > 0)) {
  79             host.setPreferredSize((int)newW, (int)newH);
  80         }
  81     }
  82 
  83     @Override public void setMinimumSize(int minWidth, int minHeight) {
  84         // This is a no-op for embedded stages
  85     }
  86 
  87     @Override public void setMaximumSize(int maxWidth, int maxHeight) {
  88         // This is a no-op for embedded stages
  89     }
  90 
  91     @Override
  92     protected void setPlatformEnabled(boolean enabled) {
  93         super.setPlatformEnabled(enabled);
  94         host.setEnabled(enabled);
  95     }
  96 
  97     @Override
  98     public void setIcons(List icons) {
  99         if (QuantumToolkit.verbose) {
 100             System.err.println("EmbeddedStage.setIcons");
 101         }
 102     }
 103 
 104     @Override
 105     public void setTitle(String title) {
 106         if (QuantumToolkit.verbose) {
 107             System.err.println("EmbeddedStage.setTitle " + title);
 108         }
 109     }
 110 
 111     @Override
 112     public void setVisible(boolean visible) {
 113         host.setEmbeddedStage(visible ? this : null);
 114         super.setVisible(visible);
 115     }
 116 
 117     @Override
 118     public void setOpacity(float opacity) {
 119 //        host.setOpacity(opacity);
 120     }
 121 
 122     @Override
 123     public void setIconified(boolean iconified) {
 124         if (QuantumToolkit.verbose) {
 125             System.err.println("EmbeddedScene.setIconified " + iconified);
 126         }
 127     }
 128 
 129     @Override
 130     public void setMaximized(boolean maximized) {
 131         if (QuantumToolkit.verbose) {
 132             System.err.println("EmbeddedScene.setMaximized " + maximized);
 133         }
 134     }
 135 
 136     @Override
 137     public void setResizable(boolean resizable) {
 138         if (QuantumToolkit.verbose) {
 139             System.err.println("EmbeddedStage.setResizable " + resizable);
 140         }
 141     }
 142 
 143     @Override
 144     public void setFullScreen(boolean fullScreen) {
 145         if (QuantumToolkit.verbose) {
 146             System.err.println("EmbeddedStage.setFullScreen " + fullScreen);
 147         }
 148     }
 149 
 150     @Override
 151     public void setUpdatesCursor(boolean updatesCursor) {
 152         if (QuantumToolkit.verbose) {
 153             // Not implemented
 154             System.err.println("EmbeddedStage.setUpdatesCursor " + updatesCursor);
 155         }
 156     }
 157 
 158     @Override
 159     public void requestFocus() {
 160         if (!host.requestFocus()) {
 161             return;
 162         }
 163         super.requestFocus();
 164     }
 165 
 166     @Override
 167     public void toBack() {
 168         if (QuantumToolkit.verbose) {
 169             System.err.println("EmbeddedStage.toBack");
 170         }
 171     }
 172 
 173     @Override
 174     public void toFront() {
 175         if (QuantumToolkit.verbose) {
 176             System.err.println("EmbeddedStage.toFront");
 177         }
 178     }
 179 
 180     @Override public boolean grabFocus() {
 181         return host.grabFocus();
 182     }
 183 
 184     @Override public void ungrabFocus() {
 185         host.ungrabFocus();
 186     }
 187 
 188     private void notifyStageListener(final Runnable r) {
 189         AccessControlContext acc = getAccessControlContext();
 190         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 191             @Override
 192             public Void run() {
 193                 r.run();
 194                 return null;
 195             }
 196         }, acc);
 197     }
 198     private void notifyStageListenerLater(final Runnable r) {
 199         Platform.runLater(new Runnable() {
 200             @Override
 201             public void run() {
 202                 notifyStageListener(r);
 203             }
 204         });
 205     }
 206 
 207     // EmbeddedStageInterface methods
 208 
 209     @Override
 210     public void setLocation(final int x, final int y) {
 211         Runnable r = new Runnable() {
 212             @Override
 213             public void run() {
 214                 if (stageListener != null) {
 215                     stageListener.changedLocation(x, y);
 216                 }
 217             }
 218         };
 219         // setLocation() can be called on both FX and Swing/SWT/etc threads
 220         if (Toolkit.getToolkit().isFxUserThread()) {
 221             notifyStageListener(r);
 222         } else {
 223             notifyStageListenerLater(r);
 224         }
 225     }
 226 
 227     @Override
 228     public void setSize(final int width, final int height) {
 229         Runnable r = new Runnable() {
 230             @Override
 231             public void run() {
 232                 if (stageListener != null) {
 233                     stageListener.changedSize(width, height);
 234                 }
 235             }
 236         };
 237         // setSize() can be called on both FX and Swing/SWT/etc threads
 238         if (Toolkit.getToolkit().isFxUserThread()) {
 239             notifyStageListener(r);
 240         } else {
 241             notifyStageListenerLater(r);
 242         }
 243     }
 244 
 245     @Override
 246     public void setFocused(final boolean focused, final int focusCause) {
 247         Runnable r = new Runnable() {
 248             @Override
 249             public void run() {
 250                 if (stageListener != null) {
 251                     stageListener.changedFocused(focused,
 252                             AbstractEvents.focusCauseToPeerFocusCause(focusCause));
 253                 }
 254             }
 255         };
 256         // setFocused() can be called on both FX and Swing/SWT/etc threads
 257         if (Toolkit.getToolkit().isFxUserThread()) {
 258             notifyStageListener(r);
 259         } else {
 260             notifyStageListenerLater(r);
 261         }
 262     }
 263     
 264     @Override
 265     public void focusUngrab() {
 266         Runnable r = new Runnable() {
 267             @Override
 268             public void run() {
 269                 if (stageListener != null) {
 270                     stageListener.focusUngrab();
 271                 }
 272             }
 273         };
 274         if (Toolkit.getToolkit().isFxUserThread()) {
 275             notifyStageListener(r);
 276         } else {
 277             notifyStageListenerLater(r);
 278         }
 279     }
 280 
 281     @Override
 282     public void requestInput(String text, int type, double width, double height, 
 283                                 double Mxx, double Mxy, double Mxz, double Mxt,
 284                                 double Myx, double Myy, double Myz, double Myt, 
 285                                 double Mzx, double Mzy, double Mzz, double Mzt) {
 286         throw new UnsupportedOperationException("Not supported yet.");
 287     }
 288 
 289     @Override
 290     public void releaseInput() {
 291         throw new UnsupportedOperationException("Not supported yet.");
 292     }
 293 
 294     @Override public void setRTL(boolean b) {
 295     }
 296 
 297     /**
 298      * 
 299      * Accessibility glue for native
 300      * 
 301      */
 302     
 303     /**
 304      * Initialize Accessibility
 305      * 
 306      * @param ac    the Glass accessible root object.
 307      */
 308     @Override public void setAccessibilityInitIsComplete(Object ac) {
 309         // TODO: not yet supported, RT-28492
 310     } 
 311 
 312     /**
 313      * Create accessible Glass object corresponding to stage
 314      * 
 315      * @param ac    the FX accessible root/stage node.
 316      * 
 317      * @return the Glass AccessibleRoot object.
 318      */
 319     @Override public Object accessibleCreateStageProvider(AccessibleStageProvider ac) {
 320         // TODO: not yet supported, RT-28492
 321         return null ;
 322     }
 323 
 324     /**
 325      * Create Glass accessible object corresponding to controls
 326      * 
 327      * @param ac    the FX accessible node
 328      *
 329      * @return the Glass accessible Object
 330      */
 331     @Override public Object accessibleCreateBasicProvider(AccessibleProvider ac) {
 332         // TODO: not yet supported, RT-28492
 333         return null;
 334     }
 335 
 336     /**
 337      * Delete Glass accessible object corresponding to controls
 338      * 
 339      * @param glassAcc the Glass accessible
 340      */
 341     @Override public void accessibleDestroyBasicProvider(Object glassAcc) {
 342         // TODO: not yet supported, RT-28492
 343     }
 344 
 345     /**
 346      * Fire accessible event
 347      * 
 348      * @param glassAcc  the Glass accessible
 349      */
 350     @Override public void accessibleFireEvent(Object glassAcc, int eventID) {
 351         // TODO: not yet supported, RT-28492
 352     }
 353     
 354     /**
 355      * Fire accessible property change event when an int property has changed
 356      *
 357      * @param glassAcc      the Glass accessible 
 358      * @param propertyId    identifies the property
 359      * @param oldProperty   the old value of the property
 360      * @param newProperty   the new value of the property
 361      */
 362     @Override public void accessibleFirePropertyChange( Object glassAcc, int propertyId,
 363                                                         int oldProperty, int newProperty ) {
 364         // TODO: not yet supported, RT-28492
 365     }
 366     
 367     /**
 368      * Fire accessible property change event when a boolean property has changed 
 369      *
 370      * @param glassAcc      the Glass accessible
 371      * @param propertyId    identifies the property
 372      * @param oldProperty   the old value of the property
 373      * @param newProperty   the new value of the property
 374      */
 375     @Override public void accessibleFirePropertyChange( Object glassAcc, int propertyId,
 376                                                         boolean oldProperty,
 377                                                         boolean newProperty ) {
 378         // TODO: not yet supported, RT-28492
 379     }
 380     
 381 }