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