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