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