1 /*
2  * Copyright (c) 2002, 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 package sun.awt.X11;
26 
27 import java.awt.Color;
28 import java.awt.Dimension;
29 import java.awt.Font;
30 import java.awt.FontMetrics;
31 import java.awt.Frame;
32 import java.awt.Graphics;
33 import java.awt.Insets;
34 import java.awt.MenuBar;
35 import java.awt.Rectangle;
36 import java.awt.peer.FramePeer;
37 import sun.util.logging.PlatformLogger;
38 import sun.awt.AWTAccessor;
39 
40 class XFramePeer extends XDecoratedPeer implements FramePeer {
41     private static PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XFramePeer");
42     private static PlatformLogger stateLog = PlatformLogger.getLogger("sun.awt.X11.states");
43     private static PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XFramePeer");
44 
45     XMenuBarPeer menubarPeer;
46     MenuBar menubar;
47     int state;
48     private Boolean undecorated;
49 
50     private static final int MENUBAR_HEIGHT_IF_NO_MENUBAR = 0;
51     private int lastAppliedMenubarHeight = MENUBAR_HEIGHT_IF_NO_MENUBAR;
52 
XFramePeer(Frame target)53     XFramePeer(Frame target) {
54         super(target);
55     }
56 
XFramePeer(XCreateWindowParams params)57     XFramePeer(XCreateWindowParams params) {
58         super(params);
59     }
60 
preInit(XCreateWindowParams params)61     void preInit(XCreateWindowParams params) {
62         super.preInit(params);
63         Frame target = (Frame)(this.target);
64         // set the window attributes for this Frame
65         winAttr.initialState = target.getExtendedState();
66         state = 0;
67         undecorated = Boolean.valueOf(target.isUndecorated());
68         winAttr.nativeDecor = !target.isUndecorated();
69         if (winAttr.nativeDecor) {
70             winAttr.decorations = winAttr.AWT_DECOR_ALL;
71         } else {
72             winAttr.decorations = winAttr.AWT_DECOR_NONE;
73         }
74         winAttr.functions = MWMConstants.MWM_FUNC_ALL;
75         winAttr.isResizable = true; // target.isResizable();
76         winAttr.title = target.getTitle();
77         winAttr.initialResizability = target.isResizable();
78         if (log.isLoggable(PlatformLogger.Level.FINE)) {
79             log.fine("Frame''s initial attributes: decor {0}, resizable {1}, undecorated {2}, initial state {3}",
80                      Integer.valueOf(winAttr.decorations), Boolean.valueOf(winAttr.initialResizability),
81                      Boolean.valueOf(!winAttr.nativeDecor), Integer.valueOf(winAttr.initialState));
82         }
83     }
84 
postInit(XCreateWindowParams params)85     void postInit(XCreateWindowParams params) {
86         super.postInit(params);
87         setupState(true);
88     }
89 
90     @Override
isTargetUndecorated()91     boolean isTargetUndecorated() {
92         if (undecorated != null) {
93             return undecorated.booleanValue();
94         } else {
95             return ((Frame)target).isUndecorated();
96         }
97     }
98 
setupState(boolean onInit)99     void setupState(boolean onInit) {
100         if (onInit) {
101             state = winAttr.initialState;
102         }
103         if ((state & Frame.ICONIFIED) != 0) {
104             setInitialState(XUtilConstants.IconicState);
105         } else {
106             setInitialState(XUtilConstants.NormalState);
107         }
108         setExtendedState(state);
109     }
110 
setMenuBar(MenuBar mb)111     public void setMenuBar(MenuBar mb) {
112         // state_lock should always be the second after awt_lock
113         XToolkit.awtLock();
114         try {
115             synchronized(getStateLock()) {
116                 if (mb == menubar) return;
117                 if (mb == null) {
118                     if (menubar != null) {
119                         menubarPeer.xSetVisible(false);
120                         menubar = null;
121                         menubarPeer.dispose();
122                         menubarPeer = null;
123                     }
124                 } else {
125                     menubar = mb;
126                     menubarPeer = (XMenuBarPeer) mb.getPeer();
127                     if (menubarPeer != null) {
128                         menubarPeer.init((Frame)target);
129                     }
130                 }
131             }
132         } finally {
133             XToolkit.awtUnlock();
134         }
135 
136         reshapeMenubarPeer();
137     }
138 
getMenubarPeer()139     XMenuBarPeer getMenubarPeer() {
140         return menubarPeer;
141     }
142 
getMenuBarHeight()143     int getMenuBarHeight() {
144         if (menubarPeer != null) {
145             return menubarPeer.getDesiredHeight();
146         } else {
147             return MENUBAR_HEIGHT_IF_NO_MENUBAR;
148         }
149     }
150 
updateChildrenSizes()151     void updateChildrenSizes() {
152         super.updateChildrenSizes();
153         int height = getMenuBarHeight();
154 
155         // XWindow.reshape calls XBaseWindow.xSetBounds, which acquires
156         // the AWT lock, so we have to acquire the AWT lock here
157         // before getStateLock() to avoid a deadlock with the Toolkit thread
158         // when this method is called on the EDT.
159         XToolkit.awtLock();
160         try {
161             synchronized(getStateLock()) {
162                 int width = dimensions.getClientSize().width;
163                 if (menubarPeer != null) {
164                     menubarPeer.reshape(0, 0, width, height);
165                 }
166             }
167         } finally {
168             XToolkit.awtUnlock();
169         }
170     }
171 
172     /**
173      * In addition to reshaping menubarPeer (by using 'updateChildrenSizes')
174      * this method also performs some frame reaction on this (i.e. layouts
175      * other frame children, if required)
176      */
reshapeMenubarPeer()177     final void reshapeMenubarPeer() {
178         XToolkit.executeOnEventHandlerThread(
179             target,
180             new Runnable() {
181                 public void run() {
182                     updateChildrenSizes();
183                     boolean heightChanged = false;
184 
185                     int height = getMenuBarHeight();
186                         // Neither 'XToolkit.awtLock()' nor 'getStateLock()'
187                         // is acquired under this call, and it looks to run
188                         // thread-safely. I currently see no reason to move
189                         // it under following 'synchronized' clause.
190 
191                     synchronized(getStateLock()) {
192                         if (height != lastAppliedMenubarHeight) {
193                             lastAppliedMenubarHeight = height;
194                             heightChanged = true;
195                         }
196                     }
197                     if (heightChanged) {
198                         // To make frame contents be re-layout (copied from
199                         // 'XDecoratedPeer.revalidate()'). These are not
200                         // 'synchronized', because can recursively call client
201                         // methods, which are not supposed to be called with locks
202                         // acquired.
203                         target.invalidate();
204                         target.validate();
205                     }
206                 }
207             }
208         );
209     }
210 
setMaximizedBounds(Rectangle b)211     public void setMaximizedBounds(Rectangle b) {
212         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
213             insLog.fine("Setting maximized bounds to " + b);
214         }
215         if (b == null) return;
216         maxBounds = new Rectangle(b);
217         XToolkit.awtLock();
218         try {
219             XSizeHints hints = getHints();
220             hints.set_flags(hints.get_flags() | (int)XUtilConstants.PMaxSize);
221             if (b.width != Integer.MAX_VALUE) {
222                 hints.set_max_width(b.width);
223             } else {
224                 hints.set_max_width((int)XlibWrapper.DisplayWidth(XToolkit.getDisplay(), XlibWrapper.DefaultScreen(XToolkit.getDisplay())));
225             }
226             if (b.height != Integer.MAX_VALUE) {
227                 hints.set_max_height(b.height);
228             } else {
229                 hints.set_max_height((int)XlibWrapper.DisplayHeight(XToolkit.getDisplay(), XlibWrapper.DefaultScreen(XToolkit.getDisplay())));
230             }
231             if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
232                 insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(hints.get_flags()));
233             }
234             XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), window, hints.pData);
235         } finally {
236             XToolkit.awtUnlock();
237         }
238     }
239 
getState()240     public int getState() {
241         synchronized(getStateLock()) {
242             return state;
243         }
244     }
245 
setState(int newState)246     public void setState(int newState) {
247         synchronized(getStateLock()) {
248             if (!isShowing()) {
249                 stateLog.finer("Frame is not showing");
250                 state = newState;
251                 return;
252             }
253         }
254         changeState(newState);
255     }
256 
changeState(int newState)257     void changeState(int newState) {
258         int changed = state ^ newState;
259         int changeIconic = changed & Frame.ICONIFIED;
260         boolean iconic = (newState & Frame.ICONIFIED) != 0;
261         if (stateLog.isLoggable(PlatformLogger.Level.FINER)) {
262             stateLog.finer("Changing state, old state {0}, new state {1}(iconic {2})",
263                        Integer.valueOf(state), Integer.valueOf(newState), Boolean.valueOf(iconic));
264         }
265         if (changeIconic != 0 && iconic) {
266             if (stateLog.isLoggable(PlatformLogger.Level.FINER)) {
267                 stateLog.finer("Iconifying shell " + getShell() + ", this " + this + ", screen " + getScreenNumber());
268             }
269             XToolkit.awtLock();
270             try {
271                 int res = XlibWrapper.XIconifyWindow(XToolkit.getDisplay(), getShell(), getScreenNumber());
272                 if (stateLog.isLoggable(PlatformLogger.Level.FINER)) {
273                     stateLog.finer("XIconifyWindow returned " + res);
274                 }
275             }
276             finally {
277                 XToolkit.awtUnlock();
278             }
279         }
280         if ((changed & ~Frame.ICONIFIED) != 0) {
281             setExtendedState(newState);
282         }
283         if (changeIconic != 0 && !iconic) {
284             if (stateLog.isLoggable(PlatformLogger.Level.FINER)) {
285                 stateLog.finer("DeIconifying " + this);
286             }
287 
288             XNETProtocol net_protocol = XWM.getWM().getNETProtocol();
289             if (net_protocol != null) {
290                 net_protocol.setActiveWindow(this);
291             }
292             xSetVisible(true);
293         }
294     }
295 
setExtendedState(int newState)296     void setExtendedState(int newState) {
297         XWM.getWM().setExtendedState(this, newState);
298     }
299 
handlePropertyNotify(XEvent xev)300     public void handlePropertyNotify(XEvent xev) {
301         super.handlePropertyNotify(xev);
302         XPropertyEvent ev = xev.get_xproperty();
303 
304         if (log.isLoggable(PlatformLogger.Level.FINER)) {
305             log.finer("Property change {0}", ev);
306         }
307         /*
308          * Let's see if this is a window state protocol message, and
309          * if it is - decode a new state in terms of java constants.
310          */
311         if (!XWM.getWM().isStateChange(this, ev)) {
312             stateLog.finer("either not a state atom or state has not been changed");
313             return;
314         }
315 
316         final int newState = XWM.getWM().getState(this);
317         int changed = state ^ newState;
318         if (changed == 0) {
319             if (stateLog.isLoggable(PlatformLogger.Level.FINER)) {
320                 stateLog.finer("State is the same: " + state);
321             }
322             return;
323         }
324 
325         int old_state = state;
326         state = newState;
327 
328         // sync target with peer
329         AWTAccessor.getFrameAccessor().setExtendedState((Frame)target, state);
330 
331         if ((changed & Frame.ICONIFIED) != 0) {
332             if ((state & Frame.ICONIFIED) != 0) {
333                 stateLog.finer("Iconified");
334                 handleIconify();
335             } else {
336                 stateLog.finer("DeIconified");
337                 content.purgeIconifiedExposeEvents();
338                 handleDeiconify();
339             }
340         }
341         handleStateChange(old_state, state);
342 
343         // RepaintManager does not repaint iconified windows. Window needs to be
344         // repainted explicitly, when it is deiconified.
345         if (((changed & Frame.ICONIFIED) != 0) &&
346             ((state & Frame.ICONIFIED) == 0)) {
347             repaint();
348         }
349     }
350 
351     // NOTE: This method may be called by privileged threads.
352     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
handleStateChange(int oldState, int newState)353     public void handleStateChange(int oldState, int newState) {
354         super.handleStateChange(oldState, newState);
355         for (ToplevelStateListener topLevelListenerTmp : toplevelStateListeners) {
356             topLevelListenerTmp.stateChangedJava(oldState, newState);
357         }
358     }
359 
setVisible(boolean vis)360     public void setVisible(boolean vis) {
361         if (vis) {
362             setupState(false);
363         } else {
364             if ((state & Frame.MAXIMIZED_BOTH) != 0) {
365                 XWM.getWM().setExtendedState(this, state & ~Frame.MAXIMIZED_BOTH);
366             }
367         }
368         super.setVisible(vis);
369         if (vis && maxBounds != null) {
370             setMaximizedBounds(maxBounds);
371         }
372     }
373 
setInitialState(int wm_state)374     void setInitialState(int wm_state) {
375         XToolkit.awtLock();
376         try {
377             XWMHints hints = getWMHints();
378             hints.set_flags((int)XUtilConstants.StateHint | hints.get_flags());
379             hints.set_initial_state(wm_state);
380             if (stateLog.isLoggable(PlatformLogger.Level.FINE)) {
381                 stateLog.fine("Setting initial WM state on " + this + " to " + wm_state);
382             }
383             XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
384         }
385         finally {
386             XToolkit.awtUnlock();
387         }
388     }
389 
dispose()390     public void dispose() {
391         if (menubarPeer != null) {
392             menubarPeer.dispose();
393         }
394         super.dispose();
395     }
396 
isMaximized()397     boolean isMaximized() {
398         return (state & (Frame.MAXIMIZED_VERT  | Frame.MAXIMIZED_HORIZ)) != 0;
399     }
400 
401 
402 
403 
404     static final int CROSSHAIR_INSET = 5;
405 
406     static final int BUTTON_Y = CROSSHAIR_INSET + 1;
407     static final int BUTTON_W = 17;
408     static final int BUTTON_H = 17;
409 
410     static final int SYS_MENU_X = CROSSHAIR_INSET + 1;
411     static final int SYS_MENU_CONTAINED_X = SYS_MENU_X + 5;
412     static final int SYS_MENU_CONTAINED_Y = BUTTON_Y + 7;
413     static final int SYS_MENU_CONTAINED_W = 8;
414     static final int SYS_MENU_CONTAINED_H = 3;
415 
416     static final int MAXIMIZE_X_DIFF = CROSSHAIR_INSET + BUTTON_W;
417     static final int MAXIMIZE_CONTAINED_X_DIFF = MAXIMIZE_X_DIFF - 5;
418     static final int MAXIMIZE_CONTAINED_Y = BUTTON_Y + 5;
419     static final int MAXIMIZE_CONTAINED_W = 8;
420     static final int MAXIMIZE_CONTAINED_H = 8;
421 
422     static final int MINIMIZE_X_DIFF = MAXIMIZE_X_DIFF + BUTTON_W;
423     static final int MINIMIZE_CONTAINED_X_DIFF = MINIMIZE_X_DIFF - 7;
424     static final int MINIMIZE_CONTAINED_Y = BUTTON_Y + 7;
425     static final int MINIMIZE_CONTAINED_W = 3;
426     static final int MINIMIZE_CONTAINED_H = 3;
427 
428     static final int TITLE_X = SYS_MENU_X + BUTTON_W;
429     static final int TITLE_W_DIFF = BUTTON_W * 3 + CROSSHAIR_INSET * 2 - 1;
430     static final int TITLE_MID_Y = BUTTON_Y + (BUTTON_H / 2);
431 
432     static final int MENUBAR_X = CROSSHAIR_INSET + 1;
433     static final int MENUBAR_Y = BUTTON_Y + BUTTON_H;
434 
435     static final int HORIZ_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_H;
436     static final int VERT_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_W;
437 
438 
439     /*
440      * Print the native component by rendering the Motif look ourselves.
441      * We also explicitly print the MenuBar since a MenuBar isn't a subclass
442      * of Component (and thus it has no "print" method which gets called by
443      * default).
444      */
print(Graphics g)445     public void print(Graphics g) {
446         super.print(g);
447 
448         Frame f = (Frame)target;
449         Insets finsets = f.getInsets();
450         Dimension fsize = f.getSize();
451 
452         Color bg = f.getBackground();
453         Color fg = f.getForeground();
454         Color highlight = bg.brighter();
455         Color shadow = bg.darker();
456 
457         // Well, we could query for the currently running window manager
458         // and base the look on that, or we could just always do dtwm.
459         // aim, tball, and levenson all agree we'll just do dtwm.
460 
461         if (hasDecorations(XWindowAttributesData.AWT_DECOR_BORDER)) {
462 
463             // top outer -- because we'll most likely be drawing on white paper,
464             // for aesthetic reasons, don't make any part of the outer border
465             // pure white
466             if (highlight.equals(Color.white)) {
467                 g.setColor(new Color(230, 230, 230));
468             }
469             else {
470                 g.setColor(highlight);
471             }
472             g.drawLine(0, 0, fsize.width, 0);
473             g.drawLine(0, 1, fsize.width - 1, 1);
474 
475             // left outer
476             // if (highlight.equals(Color.white)) {
477             //     g.setColor(new Color(230, 230, 230));
478             // }
479             // else {
480             //     g.setColor(highlight);
481             // }
482             g.drawLine(0, 0, 0, fsize.height);
483             g.drawLine(1, 0, 1, fsize.height - 1);
484 
485             // bottom cross-hair
486             g.setColor(highlight);
487             g.drawLine(CROSSHAIR_INSET + 1, fsize.height - CROSSHAIR_INSET,
488                        fsize.width - CROSSHAIR_INSET,
489                        fsize.height - CROSSHAIR_INSET);
490 
491             // right cross-hair
492             // g.setColor(highlight);
493             g.drawLine(fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET + 1,
494                        fsize.width - CROSSHAIR_INSET,
495                        fsize.height - CROSSHAIR_INSET);
496 
497             // bottom outer
498             g.setColor(shadow);
499             g.drawLine(1, fsize.height, fsize.width, fsize.height);
500             g.drawLine(2, fsize.height - 1, fsize.width, fsize.height - 1);
501 
502             // right outer
503             // g.setColor(shadow);
504             g.drawLine(fsize.width, 1, fsize.width, fsize.height);
505             g.drawLine(fsize.width - 1, 2, fsize.width - 1, fsize.height);
506 
507             // top cross-hair
508             // g.setColor(shadow);
509             g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET,
510                        fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET);
511 
512             // left cross-hair
513             // g.setColor(shadow);
514             g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET, CROSSHAIR_INSET,
515                        fsize.height - CROSSHAIR_INSET);
516         }
517 
518         if (hasDecorations(XWindowAttributesData.AWT_DECOR_TITLE)) {
519 
520             if (hasDecorations(XWindowAttributesData.AWT_DECOR_MENU)) {
521 
522                 // system menu
523                 g.setColor(bg);
524                 g.fill3DRect(SYS_MENU_X, BUTTON_Y, BUTTON_W, BUTTON_H, true);
525                 g.fill3DRect(SYS_MENU_CONTAINED_X, SYS_MENU_CONTAINED_Y,
526                              SYS_MENU_CONTAINED_W, SYS_MENU_CONTAINED_H, true);
527             }
528 
529             // title bar
530             // g.setColor(bg);
531             g.fill3DRect(TITLE_X, BUTTON_Y, fsize.width - TITLE_W_DIFF, BUTTON_H,
532                          true);
533 
534             if (hasDecorations(XWindowAttributesData.AWT_DECOR_MINIMIZE)) {
535 
536                 // minimize button
537                 // g.setColor(bg);
538                 g.fill3DRect(fsize.width - MINIMIZE_X_DIFF, BUTTON_Y, BUTTON_W,
539                              BUTTON_H, true);
540                 g.fill3DRect(fsize.width - MINIMIZE_CONTAINED_X_DIFF,
541                              MINIMIZE_CONTAINED_Y, MINIMIZE_CONTAINED_W,
542                              MINIMIZE_CONTAINED_H, true);
543             }
544 
545             if (hasDecorations(XWindowAttributesData.AWT_DECOR_MAXIMIZE)) {
546 
547                 // maximize button
548                 // g.setColor(bg);
549                 g.fill3DRect(fsize.width - MAXIMIZE_X_DIFF, BUTTON_Y, BUTTON_W,
550                              BUTTON_H, true);
551                 g.fill3DRect(fsize.width - MAXIMIZE_CONTAINED_X_DIFF,
552                              MAXIMIZE_CONTAINED_Y, MAXIMIZE_CONTAINED_W,
553                              MAXIMIZE_CONTAINED_H, true);
554             }
555 
556             // title bar text
557             g.setColor(fg);
558             Font sysfont = new Font(Font.SANS_SERIF, Font.PLAIN, 10);
559             g.setFont(sysfont);
560             FontMetrics sysfm = g.getFontMetrics();
561             String ftitle = f.getTitle();
562             g.drawString(ftitle,
563                          ((TITLE_X + TITLE_X + fsize.width - TITLE_W_DIFF) / 2) -
564                          (sysfm.stringWidth(ftitle) / 2),
565                          TITLE_MID_Y + sysfm.getMaxDescent());
566         }
567 
568         if (f.isResizable() &&
569             hasDecorations(XWindowAttributesData.AWT_DECOR_RESIZEH)) {
570 
571             // add resize cross hairs
572 
573             // upper-left horiz (shadow)
574             g.setColor(shadow);
575             g.drawLine(1, HORIZ_RESIZE_INSET, CROSSHAIR_INSET,
576                        HORIZ_RESIZE_INSET);
577             // upper-left vert (shadow)
578             // g.setColor(shadow);
579             g.drawLine(VERT_RESIZE_INSET, 1, VERT_RESIZE_INSET, CROSSHAIR_INSET);
580             // upper-right horiz (shadow)
581             // g.setColor(shadow);
582             g.drawLine(fsize.width - CROSSHAIR_INSET + 1, HORIZ_RESIZE_INSET,
583                        fsize.width, HORIZ_RESIZE_INSET);
584             // upper-right vert (shadow)
585             // g.setColor(shadow);
586             g.drawLine(fsize.width - VERT_RESIZE_INSET - 1, 2,
587                        fsize.width - VERT_RESIZE_INSET - 1, CROSSHAIR_INSET + 1);
588             // lower-left horiz (shadow)
589             // g.setColor(shadow);
590             g.drawLine(1, fsize.height - HORIZ_RESIZE_INSET - 1,
591                        CROSSHAIR_INSET, fsize.height - HORIZ_RESIZE_INSET - 1);
592             // lower-left vert (shadow)
593             // g.setColor(shadow);
594             g.drawLine(VERT_RESIZE_INSET, fsize.height - CROSSHAIR_INSET + 1,
595                        VERT_RESIZE_INSET, fsize.height);
596             // lower-right horiz (shadow)
597             // g.setColor(shadow);
598             g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
599                        fsize.height - HORIZ_RESIZE_INSET - 1, fsize.width,
600                        fsize.height - HORIZ_RESIZE_INSET - 1);
601             // lower-right vert (shadow)
602             // g.setColor(shadow);
603             g.drawLine(fsize.width - VERT_RESIZE_INSET - 1,
604                        fsize.height - CROSSHAIR_INSET + 1,
605                        fsize.width - VERT_RESIZE_INSET - 1, fsize.height);
606 
607             // upper-left horiz (highlight)
608             g.setColor(highlight);
609             g.drawLine(2, HORIZ_RESIZE_INSET + 1, CROSSHAIR_INSET,
610                        HORIZ_RESIZE_INSET + 1);
611             // upper-left vert (highlight)
612             // g.setColor(highlight);
613             g.drawLine(VERT_RESIZE_INSET + 1, 2, VERT_RESIZE_INSET + 1,
614                        CROSSHAIR_INSET);
615             // upper-right horiz (highlight)
616             // g.setColor(highlight);
617             g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
618                        HORIZ_RESIZE_INSET + 1, fsize.width - 1,
619                        HORIZ_RESIZE_INSET + 1);
620             // upper-right vert (highlight)
621             // g.setColor(highlight);
622             g.drawLine(fsize.width - VERT_RESIZE_INSET, 2,
623                        fsize.width - VERT_RESIZE_INSET, CROSSHAIR_INSET);
624             // lower-left horiz (highlight)
625             // g.setColor(highlight);
626             g.drawLine(2, fsize.height - HORIZ_RESIZE_INSET, CROSSHAIR_INSET,
627                        fsize.height - HORIZ_RESIZE_INSET);
628             // lower-left vert (highlight)
629             // g.setColor(highlight);
630             g.drawLine(VERT_RESIZE_INSET + 1,
631                        fsize.height - CROSSHAIR_INSET + 1,
632                        VERT_RESIZE_INSET + 1, fsize.height - 1);
633             // lower-right horiz (highlight)
634             // g.setColor(highlight);
635             g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
636                        fsize.height - HORIZ_RESIZE_INSET, fsize.width - 1,
637                        fsize.height - HORIZ_RESIZE_INSET);
638             // lower-right vert (highlight)
639             // g.setColor(highlight);
640             g.drawLine(fsize.width - VERT_RESIZE_INSET,
641                        fsize.height - CROSSHAIR_INSET + 1,
642                        fsize.width - VERT_RESIZE_INSET, fsize.height - 1);
643         }
644 
645         XMenuBarPeer peer = menubarPeer;
646         if (peer != null) {
647             Insets insets = getInsets();
648             Graphics ng = g.create();
649             int menubarX = 0;
650             int menubarY = 0;
651             if (hasDecorations(XWindowAttributesData.AWT_DECOR_BORDER)) {
652                 menubarX += CROSSHAIR_INSET + 1;
653                     menubarY += CROSSHAIR_INSET + 1;
654             }
655             if (hasDecorations(XWindowAttributesData.AWT_DECOR_TITLE)) {
656                 menubarY += BUTTON_H;
657             }
658             try {
659                 ng.translate(menubarX, menubarY);
660                 peer.print(ng);
661             } finally {
662                 ng.dispose();
663             }
664         }
665     }
666 
setBoundsPrivate(int x, int y, int width, int height)667     public void setBoundsPrivate(int x, int y, int width, int height) {
668         setBounds(x, y, width, height, SET_BOUNDS);
669     }
670 
getBoundsPrivate()671     public Rectangle getBoundsPrivate() {
672         return getBounds();
673     }
674 
emulateActivation(boolean doActivate)675     public void emulateActivation(boolean doActivate) {
676         if (doActivate) {
677             handleWindowFocusIn(0);
678         } else {
679             handleWindowFocusOut(null, 0);
680         }
681     }
682 }
683