jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java
changeset 2 90ce3da70b43
child 107 ed0c7cfb3666
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,636 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.awt.X11;
+
+import java.util.Vector;
+import java.awt.*;
+import java.awt.peer.*;
+import java.awt.event.*;
+import sun.awt.im.*;
+import sun.awt.*;
+import java.util.logging.*;
+import java.lang.reflect.Field;
+import java.util.*;
+
+class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
+    private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
+    private static Logger stateLog = Logger.getLogger("sun.awt.X11.states");
+    private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XFramePeer");
+
+    XMenuBarPeer menubarPeer;
+    MenuBar menubar;
+    int state;
+    private Boolean undecorated;
+
+    private static final int MENUBAR_HEIGHT_IF_NO_MENUBAR = 0;
+    private int lastAppliedMenubarHeight = MENUBAR_HEIGHT_IF_NO_MENUBAR;
+
+    XFramePeer(Frame target) {
+        super(target);
+    }
+
+    XFramePeer(XCreateWindowParams params) {
+        super(params);
+    }
+
+    void preInit(XCreateWindowParams params) {
+        super.preInit(params);
+        Frame target = (Frame)(this.target);
+        // set the window attributes for this Frame
+        winAttr.initialState = target.getExtendedState();
+        state = 0;
+        undecorated = Boolean.valueOf(target.isUndecorated());
+        winAttr.nativeDecor = !target.isUndecorated();
+        if (winAttr.nativeDecor) {
+            winAttr.decorations = winAttr.AWT_DECOR_ALL;
+        } else {
+            winAttr.decorations = winAttr.AWT_DECOR_NONE;
+        }
+        winAttr.functions = MWM_FUNC_ALL;
+        winAttr.isResizable = true; // target.isResizable();
+        winAttr.title = target.getTitle();
+        winAttr.initialResizability = target.isResizable();
+        if (log.isLoggable(Level.FINE)) {
+            log.log(Level.FINE, "Frame''s initial attributes: decor {0}, resizable {1}, undecorated {2}, initial state {3}",
+                     new Object[] {Integer.valueOf(winAttr.decorations), Boolean.valueOf(winAttr.initialResizability),
+                                   Boolean.valueOf(!winAttr.nativeDecor), Integer.valueOf(winAttr.initialState)});
+        }
+    }
+
+    void postInit(XCreateWindowParams params) {
+        super.postInit(params);
+        setupState(true);
+    }
+
+    protected Insets guessInsets() {
+        if (isTargetUndecorated()) {
+            return new Insets(0, 0, 0, 0);
+        } else {
+            return super.guessInsets();
+        }
+    }
+
+    private boolean isTargetUndecorated() {
+        if (undecorated != null) {
+            return undecorated.booleanValue();
+        } else {
+            return ((Frame)target).isUndecorated();
+        }
+    }
+
+    void setupState(boolean onInit) {
+        if (onInit) {
+            state = winAttr.initialState;
+        }
+        if ((state & Frame.ICONIFIED) != 0) {
+            setInitialState(IconicState);
+        } else {
+            setInitialState(NormalState);
+        }
+        setExtendedState(state);
+    }
+
+    public void setMenuBar(MenuBar mb) {
+        // state_lock should always be the second after awt_lock
+        XToolkit.awtLock();
+        try {
+            synchronized(getStateLock()) {
+                if (mb == menubar) return;
+                if (mb == null) {
+                    if (menubar != null) {
+                        menubarPeer.xSetVisible(false);
+                        menubar = null;
+                        menubarPeer.dispose();
+                        menubarPeer = null;
+                    }
+                } else {
+                    menubar = mb;
+                    menubarPeer = (XMenuBarPeer) mb.getPeer();
+                    if (menubarPeer != null) {
+                        menubarPeer.init((Frame)target);
+                    }
+                }
+            }
+        } finally {
+            XToolkit.awtUnlock();
+        }
+
+        reshapeMenubarPeer();
+    }
+
+    XMenuBarPeer getMenubarPeer() {
+        return menubarPeer;
+    }
+
+    int getMenuBarHeight() {
+        if (menubarPeer != null) {
+            return menubarPeer.getDesiredHeight();
+        } else {
+            return MENUBAR_HEIGHT_IF_NO_MENUBAR;
+        }
+    }
+
+    void updateChildrenSizes() {
+        super.updateChildrenSizes();
+        // XWindow.reshape calls XBaseWindow.xSetBounds, which acquires
+        // the AWT lock, so we have to acquire the AWT lock here
+        // before getStateLock() to avoid a deadlock with the Toolkit thread
+        // when this method is called on the EDT.
+        XToolkit.awtLock();
+        try {
+            synchronized(getStateLock()) {
+                int width = dimensions.getClientSize().width;
+                if (menubarPeer != null) {
+                    menubarPeer.reshape(0, 0, width, getMenuBarHeight());
+                }
+            }
+        } finally {
+            XToolkit.awtUnlock();
+        }
+    }
+
+    /**
+     * In addition to reshaping menubarPeer (by using 'updateChildrenSizes')
+     * this method also performs some frame reaction on this (i.e. layouts
+     * other frame children, if required)
+     */
+    final void reshapeMenubarPeer() {
+        XToolkit.executeOnEventHandlerThread(
+            target,
+            new Runnable() {
+                public void run() {
+                    updateChildrenSizes();
+                    boolean heightChanged = false;
+
+                    int height = getMenuBarHeight();
+                        // Neither 'XToolkit.awtLock()' nor 'getStateLock()'
+                        // is acquired under this call, and it looks to run
+                        // thread-safely. I currently see no reason to move
+                        // it under following 'synchronized' clause.
+
+                    synchronized(getStateLock()) {
+                        if (height != lastAppliedMenubarHeight) {
+                            lastAppliedMenubarHeight = height;
+                            heightChanged = true;
+                        }
+                    }
+                    if (heightChanged) {
+                        // To make frame contents be re-layout (copied from
+                        // 'XDecoratedPeer.revalidate()'). These are not
+                        // 'synchronized', because can recursively call client
+                        // methods, which are not supposed to be called with locks
+                        // acquired.
+                        target.invalidate();
+                        target.validate();
+                    }
+                }
+            }
+        );
+    }
+
+    public void setMaximizedBounds(Rectangle b) {
+        if (insLog.isLoggable(Level.FINE)) insLog.fine("Setting maximized bounds to " + b);
+        if (b == null) return;
+        maxBounds = new Rectangle(b);
+        XToolkit.awtLock();
+        try {
+            XSizeHints hints = getHints();
+            hints.set_flags(hints.get_flags() | (int)XlibWrapper.PMaxSize);
+            if (b.width != Integer.MAX_VALUE) {
+                hints.set_max_width(b.width);
+            } else {
+                hints.set_max_width((int)XlibWrapper.DisplayWidth(XToolkit.getDisplay(), XlibWrapper.DefaultScreen(XToolkit.getDisplay())));
+            }
+            if (b.height != Integer.MAX_VALUE) {
+                hints.set_max_height(b.height);
+            } else {
+                hints.set_max_height((int)XlibWrapper.DisplayHeight(XToolkit.getDisplay(), XlibWrapper.DefaultScreen(XToolkit.getDisplay())));
+            }
+            if (insLog.isLoggable(Level.FINER)) insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(hints.get_flags()));
+            XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), window, hints.pData);
+        } finally {
+            XToolkit.awtUnlock();
+        }
+    }
+
+    public int getState() { return state; }
+
+    public void setState(int newState) {
+        if (!isShowing()) {
+            stateLog.finer("Frame is not showing");
+            state = newState;
+            return;
+        }
+        changeState(newState);
+    }
+
+    void changeState(int newState) {
+        int changed = state ^ newState;
+        int changeIconic = changed & Frame.ICONIFIED;
+        boolean iconic = (newState & Frame.ICONIFIED) != 0;
+        stateLog.log(Level.FINER, "Changing state, old state {0}, new state {1}(iconic {2})",
+                     new Object[] {Integer.valueOf(state), Integer.valueOf(newState), Boolean.valueOf(iconic)});
+        if (changeIconic != 0 && iconic) {
+            if (stateLog.isLoggable(Level.FINER)) stateLog.finer("Iconifying shell " + getShell() + ", this " + this + ", screen " + getScreenNumber());
+            XToolkit.awtLock();
+            try {
+                int res = XlibWrapper.XIconifyWindow(XToolkit.getDisplay(), getShell(), getScreenNumber());
+                if (stateLog.isLoggable(Level.FINER)) stateLog.finer("XIconifyWindow returned " + res);
+            }
+            finally {
+                XToolkit.awtUnlock();
+            }
+        }
+        if ((changed & ~Frame.ICONIFIED) != 0) {
+            setExtendedState(newState);
+        }
+        if (changeIconic != 0 && !iconic) {
+            if (stateLog.isLoggable(Level.FINER)) stateLog.finer("DeIconifying " + this);
+            xSetVisible(true);
+        }
+    }
+
+    void setExtendedState(int newState) {
+        XWM.getWM().setExtendedState(this, newState);
+    }
+
+    public void handlePropertyNotify(XEvent xev) {
+        super.handlePropertyNotify(xev);
+        XPropertyEvent ev = xev.get_xproperty();
+
+        log.log(Level.FINER, "Property change {0}", new Object[] {ev});
+        /*
+         * Let's see if this is a window state protocol message, and
+         * if it is - decode a new state in terms of java constants.
+         */
+        Integer newState = XWM.getWM().isStateChange(this, ev);
+        if (newState == null) {
+            return;
+        }
+
+        int changed = state ^ newState.intValue();
+        if (changed == 0) {
+            stateLog.finer("State is the same: " + state);
+            return;
+        }
+
+        int old_state = state;
+        state = newState.intValue();
+
+        if ((changed & Frame.ICONIFIED) != 0) {
+            if ((state & Frame.ICONIFIED) != 0) {
+                stateLog.finer("Iconified");
+                handleIconify();
+            } else {
+                stateLog.finer("DeIconified");
+                content.purgeIconifiedExposeEvents();
+                handleDeiconify();
+            }
+        }
+        handleStateChange(old_state, state);
+    }
+
+    // NOTE: This method may be called by privileged threads.
+    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+    public void handleStateChange(int oldState, int newState) {
+        super.handleStateChange(oldState, newState);
+        for (ToplevelStateListener topLevelListenerTmp : toplevelStateListeners) {
+            topLevelListenerTmp.stateChangedJava(oldState, newState);
+        }
+    }
+
+    public void setVisible(boolean vis) {
+        if (vis) {
+            setupState(false);
+        } else {
+            if ((state & Frame.MAXIMIZED_BOTH) != 0) {
+                XWM.getWM().setExtendedState(this, state & ~Frame.MAXIMIZED_BOTH);
+            }
+        }
+        super.setVisible(vis);
+        if (vis && maxBounds != null) {
+            setMaximizedBounds(maxBounds);
+        }
+    }
+
+    void setInitialState(int wm_state) {
+        XToolkit.awtLock();
+        try {
+            XWMHints hints = getWMHints();
+            hints.set_flags((int)XlibWrapper.StateHint | hints.get_flags());
+            hints.set_initial_state(wm_state);
+            if (stateLog.isLoggable(Level.FINE)) stateLog.fine("Setting initial WM state on " + this + " to " + wm_state);
+            XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
+        }
+        finally {
+            XToolkit.awtUnlock();
+        }
+    }
+
+    public void dispose() {
+        if (menubarPeer != null) {
+            menubarPeer.dispose();
+        }
+        super.dispose();
+    }
+
+    boolean isMaximized() {
+        return (state & (Frame.MAXIMIZED_VERT  | Frame.MAXIMIZED_HORIZ)) != 0;
+    }
+
+
+
+
+    static final int CROSSHAIR_INSET = 5;
+
+    static final int BUTTON_Y = CROSSHAIR_INSET + 1;
+    static final int BUTTON_W = 17;
+    static final int BUTTON_H = 17;
+
+    static final int SYS_MENU_X = CROSSHAIR_INSET + 1;
+    static final int SYS_MENU_CONTAINED_X = SYS_MENU_X + 5;
+    static final int SYS_MENU_CONTAINED_Y = BUTTON_Y + 7;
+    static final int SYS_MENU_CONTAINED_W = 8;
+    static final int SYS_MENU_CONTAINED_H = 3;
+
+    static final int MAXIMIZE_X_DIFF = CROSSHAIR_INSET + BUTTON_W;
+    static final int MAXIMIZE_CONTAINED_X_DIFF = MAXIMIZE_X_DIFF - 5;
+    static final int MAXIMIZE_CONTAINED_Y = BUTTON_Y + 5;
+    static final int MAXIMIZE_CONTAINED_W = 8;
+    static final int MAXIMIZE_CONTAINED_H = 8;
+
+    static final int MINIMIZE_X_DIFF = MAXIMIZE_X_DIFF + BUTTON_W;
+    static final int MINIMIZE_CONTAINED_X_DIFF = MINIMIZE_X_DIFF - 7;
+    static final int MINIMIZE_CONTAINED_Y = BUTTON_Y + 7;
+    static final int MINIMIZE_CONTAINED_W = 3;
+    static final int MINIMIZE_CONTAINED_H = 3;
+
+    static final int TITLE_X = SYS_MENU_X + BUTTON_W;
+    static final int TITLE_W_DIFF = BUTTON_W * 3 + CROSSHAIR_INSET * 2 - 1;
+    static final int TITLE_MID_Y = BUTTON_Y + (BUTTON_H / 2);
+
+    static final int MENUBAR_X = CROSSHAIR_INSET + 1;
+    static final int MENUBAR_Y = BUTTON_Y + BUTTON_H;
+
+    static final int HORIZ_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_H;
+    static final int VERT_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_W;
+
+
+    /*
+     * Print the native component by rendering the Motif look ourselves.
+     * We also explicitly print the MenuBar since a MenuBar isn't a subclass
+     * of Component (and thus it has no "print" method which gets called by
+     * default).
+     */
+    public void print(Graphics g) {
+        super.print(g);
+
+        Frame f = (Frame)target;
+        Insets finsets = f.getInsets();
+        Dimension fsize = f.getSize();
+
+        Color bg = f.getBackground();
+        Color fg = f.getForeground();
+        Color highlight = bg.brighter();
+        Color shadow = bg.darker();
+
+        // Well, we could query for the currently running window manager
+        // and base the look on that, or we could just always do dtwm.
+        // aim, tball, and levenson all agree we'll just do dtwm.
+
+        if (hasDecorations(XWindowAttributesData.AWT_DECOR_BORDER)) {
+
+            // top outer -- because we'll most likely be drawing on white paper,
+            // for aesthetic reasons, don't make any part of the outer border
+            // pure white
+            if (highlight.equals(Color.white)) {
+                g.setColor(new Color(230, 230, 230));
+            }
+            else {
+                g.setColor(highlight);
+            }
+            g.drawLine(0, 0, fsize.width, 0);
+            g.drawLine(0, 1, fsize.width - 1, 1);
+
+            // left outer
+            // if (highlight.equals(Color.white)) {
+            //     g.setColor(new Color(230, 230, 230));
+            // }
+            // else {
+            //     g.setColor(highlight);
+            // }
+            g.drawLine(0, 0, 0, fsize.height);
+            g.drawLine(1, 0, 1, fsize.height - 1);
+
+            // bottom cross-hair
+            g.setColor(highlight);
+            g.drawLine(CROSSHAIR_INSET + 1, fsize.height - CROSSHAIR_INSET,
+                       fsize.width - CROSSHAIR_INSET,
+                       fsize.height - CROSSHAIR_INSET);
+
+            // right cross-hair
+            // g.setColor(highlight);
+            g.drawLine(fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET + 1,
+                       fsize.width - CROSSHAIR_INSET,
+                       fsize.height - CROSSHAIR_INSET);
+
+            // bottom outer
+            g.setColor(shadow);
+            g.drawLine(1, fsize.height, fsize.width, fsize.height);
+            g.drawLine(2, fsize.height - 1, fsize.width, fsize.height - 1);
+
+            // right outer
+            // g.setColor(shadow);
+            g.drawLine(fsize.width, 1, fsize.width, fsize.height);
+            g.drawLine(fsize.width - 1, 2, fsize.width - 1, fsize.height);
+
+            // top cross-hair
+            // g.setColor(shadow);
+            g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET,
+                       fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET);
+
+            // left cross-hair
+            // g.setColor(shadow);
+            g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET, CROSSHAIR_INSET,
+                       fsize.height - CROSSHAIR_INSET);
+        }
+
+        if (hasDecorations(XWindowAttributesData.AWT_DECOR_TITLE)) {
+
+            if (hasDecorations(XWindowAttributesData.AWT_DECOR_MENU)) {
+
+                // system menu
+                g.setColor(bg);
+                g.fill3DRect(SYS_MENU_X, BUTTON_Y, BUTTON_W, BUTTON_H, true);
+                g.fill3DRect(SYS_MENU_CONTAINED_X, SYS_MENU_CONTAINED_Y,
+                             SYS_MENU_CONTAINED_W, SYS_MENU_CONTAINED_H, true);
+            }
+
+            // title bar
+            // g.setColor(bg);
+            g.fill3DRect(TITLE_X, BUTTON_Y, fsize.width - TITLE_W_DIFF, BUTTON_H,
+                         true);
+
+            if (hasDecorations(XWindowAttributesData.AWT_DECOR_MINIMIZE)) {
+
+                // minimize button
+                // g.setColor(bg);
+                g.fill3DRect(fsize.width - MINIMIZE_X_DIFF, BUTTON_Y, BUTTON_W,
+                             BUTTON_H, true);
+                g.fill3DRect(fsize.width - MINIMIZE_CONTAINED_X_DIFF,
+                             MINIMIZE_CONTAINED_Y, MINIMIZE_CONTAINED_W,
+                             MINIMIZE_CONTAINED_H, true);
+            }
+
+            if (hasDecorations(XWindowAttributesData.AWT_DECOR_MAXIMIZE)) {
+
+                // maximize button
+                // g.setColor(bg);
+                g.fill3DRect(fsize.width - MAXIMIZE_X_DIFF, BUTTON_Y, BUTTON_W,
+                             BUTTON_H, true);
+                g.fill3DRect(fsize.width - MAXIMIZE_CONTAINED_X_DIFF,
+                             MAXIMIZE_CONTAINED_Y, MAXIMIZE_CONTAINED_W,
+                             MAXIMIZE_CONTAINED_H, true);
+            }
+
+            // title bar text
+            g.setColor(fg);
+            Font sysfont = new Font(Font.SANS_SERIF, Font.PLAIN, 10);
+            g.setFont(sysfont);
+            FontMetrics sysfm = g.getFontMetrics();
+            String ftitle = f.getTitle();
+            g.drawString(ftitle,
+                         ((TITLE_X + TITLE_X + fsize.width - TITLE_W_DIFF) / 2) -
+                         (sysfm.stringWidth(ftitle) / 2),
+                         TITLE_MID_Y + sysfm.getMaxDescent());
+        }
+
+        if (f.isResizable() &&
+            hasDecorations(XWindowAttributesData.AWT_DECOR_RESIZEH)) {
+
+            // add resize cross hairs
+
+            // upper-left horiz (shadow)
+            g.setColor(shadow);
+            g.drawLine(1, HORIZ_RESIZE_INSET, CROSSHAIR_INSET,
+                       HORIZ_RESIZE_INSET);
+            // upper-left vert (shadow)
+            // g.setColor(shadow);
+            g.drawLine(VERT_RESIZE_INSET, 1, VERT_RESIZE_INSET, CROSSHAIR_INSET);
+            // upper-right horiz (shadow)
+            // g.setColor(shadow);
+            g.drawLine(fsize.width - CROSSHAIR_INSET + 1, HORIZ_RESIZE_INSET,
+                       fsize.width, HORIZ_RESIZE_INSET);
+            // upper-right vert (shadow)
+            // g.setColor(shadow);
+            g.drawLine(fsize.width - VERT_RESIZE_INSET - 1, 2,
+                       fsize.width - VERT_RESIZE_INSET - 1, CROSSHAIR_INSET + 1);
+            // lower-left horiz (shadow)
+            // g.setColor(shadow);
+            g.drawLine(1, fsize.height - HORIZ_RESIZE_INSET - 1,
+                       CROSSHAIR_INSET, fsize.height - HORIZ_RESIZE_INSET - 1);
+            // lower-left vert (shadow)
+            // g.setColor(shadow);
+            g.drawLine(VERT_RESIZE_INSET, fsize.height - CROSSHAIR_INSET + 1,
+                       VERT_RESIZE_INSET, fsize.height);
+            // lower-right horiz (shadow)
+            // g.setColor(shadow);
+            g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
+                       fsize.height - HORIZ_RESIZE_INSET - 1, fsize.width,
+                       fsize.height - HORIZ_RESIZE_INSET - 1);
+            // lower-right vert (shadow)
+            // g.setColor(shadow);
+            g.drawLine(fsize.width - VERT_RESIZE_INSET - 1,
+                       fsize.height - CROSSHAIR_INSET + 1,
+                       fsize.width - VERT_RESIZE_INSET - 1, fsize.height);
+
+            // upper-left horiz (highlight)
+            g.setColor(highlight);
+            g.drawLine(2, HORIZ_RESIZE_INSET + 1, CROSSHAIR_INSET,
+                       HORIZ_RESIZE_INSET + 1);
+            // upper-left vert (highlight)
+            // g.setColor(highlight);
+            g.drawLine(VERT_RESIZE_INSET + 1, 2, VERT_RESIZE_INSET + 1,
+                       CROSSHAIR_INSET);
+            // upper-right horiz (highlight)
+            // g.setColor(highlight);
+            g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
+                       HORIZ_RESIZE_INSET + 1, fsize.width - 1,
+                       HORIZ_RESIZE_INSET + 1);
+            // upper-right vert (highlight)
+            // g.setColor(highlight);
+            g.drawLine(fsize.width - VERT_RESIZE_INSET, 2,
+                       fsize.width - VERT_RESIZE_INSET, CROSSHAIR_INSET);
+            // lower-left horiz (highlight)
+            // g.setColor(highlight);
+            g.drawLine(2, fsize.height - HORIZ_RESIZE_INSET, CROSSHAIR_INSET,
+                       fsize.height - HORIZ_RESIZE_INSET);
+            // lower-left vert (highlight)
+            // g.setColor(highlight);
+            g.drawLine(VERT_RESIZE_INSET + 1,
+                       fsize.height - CROSSHAIR_INSET + 1,
+                       VERT_RESIZE_INSET + 1, fsize.height - 1);
+            // lower-right horiz (highlight)
+            // g.setColor(highlight);
+            g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
+                       fsize.height - HORIZ_RESIZE_INSET, fsize.width - 1,
+                       fsize.height - HORIZ_RESIZE_INSET);
+            // lower-right vert (highlight)
+            // g.setColor(highlight);
+            g.drawLine(fsize.width - VERT_RESIZE_INSET,
+                       fsize.height - CROSSHAIR_INSET + 1,
+                       fsize.width - VERT_RESIZE_INSET, fsize.height - 1);
+        }
+
+        XMenuBarPeer peer = menubarPeer;
+        if (peer != null) {
+            Insets insets = getInsets();
+            Graphics ng = g.create();
+            int menubarX = 0;
+            int menubarY = 0;
+            if (hasDecorations(XWindowAttributesData.AWT_DECOR_BORDER)) {
+                menubarX += CROSSHAIR_INSET + 1;
+                    menubarY += CROSSHAIR_INSET + 1;
+            }
+            if (hasDecorations(XWindowAttributesData.AWT_DECOR_TITLE)) {
+                menubarY += BUTTON_H;
+            }
+            try {
+                ng.translate(menubarX, menubarY);
+                peer.print(ng);
+            } finally {
+                ng.dispose();
+            }
+        }
+    }
+
+    public void setBoundsPrivate(int x, int y, int width, int height) {
+        setBounds(x, y, width, height, SET_BOUNDS);
+    }
+
+    public Rectangle getBoundsPrivate() {
+        return getBounds();
+    }
+}