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 requestFocus() {
 152         if (!host.requestFocus()) {
 153             return;
 154         }
 155         super.requestFocus();
 156     }
 157 
 158     @Override
 159     public void toBack() {
 160         if (QuantumToolkit.verbose) {
 161             System.err.println("EmbeddedStage.toBack");
 162         }
 163     }
 164 
 165     @Override
 166     public void toFront() {
 167         if (QuantumToolkit.verbose) {
 168             System.err.println("EmbeddedStage.toFront");
 169         }
 170     }
 171 
 172     @Override public boolean grabFocus() {
 173         return host.grabFocus();
 174     }
 175 
 176     @Override public void ungrabFocus() {
 177         host.ungrabFocus();
 178     }
 179 
 180     private void notifyStageListener(final Runnable r) {
 181         AccessControlContext acc = getAccessControlContext();
 182         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 183             @Override
 184             public Void run() {
 185                 r.run();
 186                 return null;
 187             }
 188         }, acc);
 189     }
 190     private void notifyStageListenerLater(final Runnable r) {
 191         Platform.runLater(new Runnable() {
 192             @Override
 193             public void run() {
 194                 notifyStageListener(r);
 195             }
 196         });
 197     }
 198 
 199     // EmbeddedStageInterface methods
 200 
 201     @Override
 202     public void setLocation(final int x, final int y) {
 203         Runnable r = new Runnable() {
 204             @Override
 205             public void run() {
 206                 if (stageListener != null) {
 207                     stageListener.changedLocation(x, y);
 208                 }
 209             }
 210         };
 211         // setLocation() can be called on both FX and Swing/SWT/etc threads
 212         if (Toolkit.getToolkit().isFxUserThread()) {
 213             notifyStageListener(r);
 214         } else {
 215             notifyStageListenerLater(r);
 216         }
 217     }
 218 
 219     @Override
 220     public void setSize(final int width, final int height) {
 221         Runnable r = new Runnable() {
 222             @Override
 223             public void run() {
 224                 if (stageListener != null) {
 225                     stageListener.changedSize(width, height);
 226                 }
 227             }
 228         };
 229         // setSize() can be called on both FX and Swing/SWT/etc threads
 230         if (Toolkit.getToolkit().isFxUserThread()) {
 231             notifyStageListener(r);
 232         } else {
 233             notifyStageListenerLater(r);
 234         }
 235     }
 236 
 237     @Override
 238     public void setFocused(final boolean focused, final int focusCause) {
 239         Runnable r = new Runnable() {
 240             @Override
 241             public void run() {
 242                 if (stageListener != null) {
 243                     stageListener.changedFocused(focused,
 244                             AbstractEvents.focusCauseToPeerFocusCause(focusCause));
 245                 }
 246             }
 247         };
 248         // setFocused() can be called on both FX and Swing/SWT/etc threads
 249         if (Toolkit.getToolkit().isFxUserThread()) {
 250             notifyStageListener(r);
 251         } else {
 252             notifyStageListenerLater(r);
 253         }
 254     }
 255     
 256     @Override
 257     public void focusUngrab() {
 258         Runnable r = new Runnable() {
 259             @Override
 260             public void run() {
 261                 if (stageListener != null) {
 262                     stageListener.focusUngrab();
 263                 }
 264             }
 265         };
 266         if (Toolkit.getToolkit().isFxUserThread()) {
 267             notifyStageListener(r);
 268         } else {
 269             notifyStageListenerLater(r);
 270         }
 271     }
 272 
 273     @Override
 274     public void requestInput(String text, int type, double width, double height, 
 275                                 double Mxx, double Mxy, double Mxz, double Mxt,
 276                                 double Myx, double Myy, double Myz, double Myt, 
 277                                 double Mzx, double Mzy, double Mzz, double Mzt) {
 278         throw new UnsupportedOperationException("Not supported yet.");
 279     }
 280 
 281     @Override
 282     public void releaseInput() {
 283         throw new UnsupportedOperationException("Not supported yet.");
 284     }
 285 
 286     @Override public void setRTL(boolean b) {
 287     }
 288 
 289     /**
 290      * 
 291      * Accessibility glue for native
 292      * 
 293      */
 294     
 295     /**
 296      * Initialize Accessibility
 297      * 
 298      * @param ac    the Glass accessible root object.
 299      */
 300     @Override public void setAccessibilityInitIsComplete(Object ac) {
 301         // TODO: not yet supported, RT-28492
 302     } 
 303 
 304     /**
 305      * Create accessible Glass object corresponding to stage
 306      * 
 307      * @param ac    the FX accessible root/stage node.
 308      * 
 309      * @return the Glass AccessibleRoot object.
 310      */
 311     @Override public Object accessibleCreateStageProvider(AccessibleStageProvider ac) {
 312         // TODO: not yet supported, RT-28492
 313         return null ;
 314     }
 315 
 316     /**
 317      * Create Glass accessible object corresponding to controls
 318      * 
 319      * @param ac    the FX accessible node
 320      *
 321      * @return the Glass accessible Object
 322      */
 323     @Override public Object accessibleCreateBasicProvider(AccessibleProvider ac) {
 324         // TODO: not yet supported, RT-28492
 325         return null;
 326     }
 327 
 328     /**
 329      * Delete Glass accessible object corresponding to controls
 330      * 
 331      * @param glassAcc the Glass accessible
 332      */
 333     @Override public void accessibleDestroyBasicProvider(Object glassAcc) {
 334         // TODO: not yet supported, RT-28492
 335     }
 336 
 337     /**
 338      * Fire accessible event
 339      * 
 340      * @param glassAcc  the Glass accessible
 341      */
 342     @Override public void accessibleFireEvent(Object glassAcc, int eventID) {
 343         // TODO: not yet supported, RT-28492
 344     }
 345     
 346     /**
 347      * Fire accessible property change event when an int property has changed
 348      *
 349      * @param glassAcc      the Glass accessible 
 350      * @param propertyId    identifies the property
 351      * @param oldProperty   the old value of the property
 352      * @param newProperty   the new value of the property
 353      */
 354     @Override public void accessibleFirePropertyChange( Object glassAcc, int propertyId,
 355                                                         int oldProperty, int newProperty ) {
 356         // TODO: not yet supported, RT-28492
 357     }
 358     
 359     /**
 360      * Fire accessible property change event when a boolean property has changed 
 361      *
 362      * @param glassAcc      the Glass accessible
 363      * @param propertyId    identifies the property
 364      * @param oldProperty   the old value of the property
 365      * @param newProperty   the new value of the property
 366      */
 367     @Override public void accessibleFirePropertyChange( Object glassAcc, int propertyId,
 368                                                         boolean oldProperty,
 369                                                         boolean newProperty ) {
 370         // TODO: not yet supported, RT-28492
 371     }
 372     
 373 }