Package org.jdesktop.wonderland.modules.xremwin.client

Source Code of org.jdesktop.wonderland.modules.xremwin.client.WindowXrw

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.modules.xremwin.client;

import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.math.BigInteger;
import org.jdesktop.wonderland.common.ExperimentalAPI;
import org.jdesktop.wonderland.modules.appbase.client.App2D;
import org.jdesktop.wonderland.modules.appbase.client.Window2D;
import org.jdesktop.wonderland.modules.appbase.client.WindowConventional;
import org.jdesktop.wonderland.common.cell.CellTransform;
import org.jdesktop.wonderland.modules.appbase.client.view.View2D;
import org.jdesktop.wonderland.modules.appbase.client.ControlArb;
import org.jdesktop.wonderland.common.InternalAPI;
import javax.swing.SwingUtilities;

/**
* The Xremwin window class.
*
* @author deronj
*/
@ExperimentalAPI
public class WindowXrw extends WindowConventional {

    /** The WID value for an invalid WID. */
    public static final int INVALID_WID = 0;

    /** The X11 window ID */
    private int wid;
    /**
     * Non-zero indicates that the window is a transient window and the value is the window it is
     * transient for. TODO: write code that uses this.
     */
    private WindowXrw winTransientFor;
    /** The screen position of this window */
    private Point scrPos = new Point(0, 0);

    /**
     * Create a new WindowXrw instance and its "World" view.
     *
     * @param app The application to which this window belongs.
     * @param x The X11 x coordinate of the top-left corner window.
     * @param y The X11 y coordinate of the top-left corner window.
     * @param borderWidth The X11 border width.
     * @param decorated Whether the window is decorated with a frame.
     * @param pixelScale The size of the window pixels.
     * @param wid The X11 window ID.
     * @throws Instantiation if the window cannot be created.
     */
    WindowXrw(App2D app, int x, int y, int width, int height, int borderWidth,
            boolean decorated, Vector2f pixelScale, int wid)
            throws InstantiationException {

        super(app, width, height, decorated, borderWidth, pixelScale,
                "WindowXrw " + wid + " for app " + app.getName());

        this.wid = wid;

        // Determine whether this window is transient for another
        // TODO: not yet implemented
        int transientForWid = ((AppXrw)app).getTransientForWid(wid);
        if (transientForWid != 0) {
            winTransientFor = ((AppXrw)app).getWindowForWid(transientForWid);
        }

        setScreenPosition(x, y);

        // TODO: disable resize corner until bugs are fixed
        setUserResizable(true);
    }

    /**
     * Clean up resources.
     */
    @Override
    public void cleanup() {
        super.cleanup();
        winTransientFor = null;
    }

    /**
     * Returns the window's wid.
     */
    public int getWid() {
        return wid;
    }

    /**
     * Specify the absolute screen position of this window for this client only.
     */
    public void setScreenPosition (int x, int y) {
        scrPos = new Point(x, y);
        updateOffset();
    }

    /**
     * Returns the X screen position of this window.
     */
    public int getScreenPositionX () {
        return scrPos.x;
    }

    /**
     * Returns the Y screen position of this window.
     */
    public int getScreenPositionY () {
        return scrPos.y;
    }

    /** {@inheritDoc} */
    @Override
    public void setType (Type type) throws IllegalStateException {
        super.setType(type);
        updateOffset();
    }

    /** {@inheritDoc} */
    @Override
    public void setType (Type type, boolean okayToDemotePrimary) throws IllegalStateException {
        super.setType(type, okayToDemotePrimary);
        updateOffset();
    }

    /** {@inheritDoc} */
    @Override
    public void setParent(Window2D parent) {
        super.setParent(parent);
        updateOffset();
    }

    /**
     * Convert the screen position of this window into a parent-relative offset.
     */
    private void updateOffset() {
       
        // Make sure that this window is fully initialized before updating the offset
        if (scrPos == null) return;

        WindowXrw parent = (WindowXrw) getParent();
        if (getType() == Type.PRIMARY || parent == null) {
            setPixelOffset(0, 0);
        } else {
            if (parent.scrPos != null) {
                setPixelOffset(scrPos.x - parent.scrPos.x, scrPos.y - parent.scrPos.y);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void closeUser () {
        closeUser(false);
    }

    /**
     * {@inheritDoc}
     */
    @InternalAPI
    @Override
    public void closeUser (boolean forceClose) {
        if (!forceClose) {
            if (app == null || app.getControlArb() == null) return;

            // User must have control in order to close the window
            if (!app.getControlArb().hasControl()) {
                // TODO: bring up swing option window: "You cannot close this window
                // because you do not have control"
                // Danger: can't do this in SAS!
                AppXrw.logger.warning("You cannot close this window because you do not " +
                               "have control");
                return;
            }
        }

        // Notify the Xremwin server and other clients
        if (app == null || ((AppXrw) app).getClient() == null) return;
        ((AppXrw) app).getClient().windowCloseUser(this);

        // now clean up the window.
        super.closeUser(forceClose);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void restackToTop () {
        super.restackToTop();

        // Notify the Xremwin server and other clients
        ((AppXrw) app).getClient().windowToFront(this);
    }

    /**
     * Change the visibility of the window
     *
     * @param visible Whether the window should be visible.
     * @param winTransientFor If non-null, the window whose visibility is being changed
     * is a transient window for winTransientFor.
     */
    public void setVisibleApp(boolean visible, boolean isPopup) {
        synchronized (this) {
            if (isVisibleApp() == visible) {
                return;
            }

            if (isPopup || !isDecorated()) {
                setType(Type.POPUP);

                // We assign the popup parent when the popup is first made visible
                // TODO: This is a kludge. Eventually replace with winTransientFor
                if (getParent() == null) {
                    setParent(determineParentForPopup());
            }
            } else {
                // If type hasn't been determined at this point, make window a secondary
                if (visible && getType() == Type.UNKNOWN) {
                    setType(Type.SECONDARY);
                }
            }

            setVisibleAppPart1(visible);

            performFirstVisibleInitialization();

            ((AppXrw)app).trackWindowVisibility(this);

            // If this is still a secondary assign a parent if necessary
            if (getType() == Type.SECONDARY && getParent() == null) {
                setParent(app.getPrimaryWindow());
            }

            setVisibleAppPart2();
        }

        updateFrames();
    }

    // TODO: This is a kludge. Eventually replace with winTransientFor
    private WindowXrw determineParentForPopup() {
        WindowXrw parent = null;
        AppXrw appx = (AppXrw) app;

        if (appx.isMaster()) {
            WindowXrw currentPointerWin = appx.getCurrentPointerWindow();
            if (currentPointerWin != this) {
                parent = currentPointerWin;
            }
            if (parent == null) {
                parent = (WindowXrw) app.getPrimaryWindow();
            }
            ((AppXrwMaster) appx).setPopupParentForSlaves(this, parent);
        } else {
            // On the slave the current pointer window may be
            // completely different than the master. Therefore
            // we cannot rely on it. Instead, just stick the popup
            // somewhere reasonable for now. First try to attach
            // it to the primary window and then just leave the parent
            // null (this will attach it directly to the cell). It doesn't
            // matter exactly where we put it for now because an
            // SetPopupParent request will be forthcoming from the
            // master, which will put the popup in the correct place.
            parent = (WindowXrw) app.getPrimaryWindow();
        }

        return parent;
    }

    /**
     * Returns the window for which this window is a transient.
     */
    public WindowXrw getTransientFor() {
        return winTransientFor;
    }

    /**
     * Specify the user who is now controlling the application to which this window belongs.
     *
     * @param userName The controlling user.
     */
    public void setControllingUser(final String userName) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run () {
                ((ControlArbXrw) app.getControlArb()).setController(userName);
            }
        });
    }

    /**
     * Returns the name of the controlling user.
     */
    public String getControllingUser() {
        ControlArb controlArb = app.getControlArb();
        if (controlArb instanceof ControlArbNull) return null;
        return ((ControlArbXrw) controlArb).getController();
    }

    /**
     * Used only by App Base Master during a new slave connection.
     * Sends the pixels of the entire window to the given slave.
     *
     * @param slaveID The slave to which to send the window pixels.
     */
    public void syncSlavePixels(BigInteger slaveID) {
        byte[] tmpPixelBytes = new byte[getWidth() * getHeight() * 4];

        // Get pixels in a byte array
        getPixelBytes(tmpPixelBytes, 0, 0, getWidth(), getHeight());

        ClientXrw client = ((AppXrw) app).getClient();
        ((ClientXrwMaster) client).writeSyncSlavePixels(slaveID, tmpPixelBytes);
    }

    /** {@inheritDoc} */
    @Override
    public void deliverEvent(MouseEvent event) {

        // TODO: temporary: until winTransientFor: used to determine parents of popups
        // Always record this regardless of the specific mouse event type
        if (!isDecorated()) {
            ((AppXrw) app).setCurrentPointerWindow(this);
        }

        super.deliverEvent(event);
    }

    /**
     * Notifies other clients that the user has changed the user cell transform in a view
     * of this window.
     * @param transform The new transform.
     * @param changingView The view the user manipulated to change the transform.
     */
    @Override
    public void notifyUserTransformCell (CellTransform transform, View2D changingView) {
        synchronized (this) {
            // TODO: someday: this is currently only used for planar moves of secondary windows.
            // Since we cannot currently rotate secondaries, we can just extract the translation and
            // use the client method windowSetUserDisplacement.
            Vector3f userTranslation = transform.getTranslation(null);
            ClientXrw client = ((AppXrw) app).getClient();
            client.windowSetUserDisplacement(this, userTranslation);
        }

        super.notifyUserTransformCell(transform, changingView);
    }

    /** {@inheritDoc} */
    @Override
    public String toString () {
        return getName();
    }

    public synchronized void userSetSize(int width, int height) {
        ClientXrw client = ((AppXrw) app).getClient();
        client.windowSetSize(this, width, height);
        setSize(width, height);
    }
}
TOP

Related Classes of org.jdesktop.wonderland.modules.xremwin.client.WindowXrw

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.