1 /* 2 * Copyright (c) 2002, 2011, 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.AWTEvent; 28 import java.awt.AWTException; 29 import java.awt.BufferCapabilities; 30 import java.awt.Color; 31 import java.awt.Component; 32 import java.awt.Container; 33 import java.awt.Cursor; 34 import java.awt.Dimension; 35 import java.awt.Font; 36 import java.awt.FontMetrics; 37 import java.awt.Graphics; 38 import java.awt.GraphicsConfiguration; 39 import java.awt.Image; 40 import java.awt.Insets; 41 import java.awt.Rectangle; 42 import java.awt.SystemColor; 43 import java.awt.Toolkit; 44 import java.awt.Window; 45 import java.awt.dnd.DropTarget; 46 import java.awt.dnd.peer.DropTargetPeer; 47 import java.awt.event.FocusEvent; 48 import java.awt.event.InputEvent; 49 import java.awt.event.InputMethodEvent; 50 import java.awt.event.KeyEvent; 51 import java.awt.event.MouseEvent; 52 import java.awt.event.MouseWheelEvent; 53 import java.awt.event.PaintEvent; 54 import java.awt.event.WindowEvent; 55 import java.awt.event.InvocationEvent; 56 import java.awt.image.ImageObserver; 57 import java.awt.image.ImageProducer; 58 import java.awt.image.VolatileImage; 59 import java.awt.peer.ComponentPeer; 60 import java.awt.peer.ContainerPeer; 61 import java.lang.reflect.*; 62 import java.security.*; 63 import java.util.Collection; 64 import java.util.Set; 65 import sun.util.logging.PlatformLogger; 66 import sun.awt.*; 67 import sun.awt.event.IgnorePaintEvent; 68 import sun.awt.image.SunVolatileImage; 69 import sun.awt.image.ToolkitImage; 70 import sun.java2d.BackBufferCapsProvider; 71 import sun.java2d.pipe.Region; 72 73 public class XComponentPeer extends XWindow implements ComponentPeer, DropTargetPeer, 74 BackBufferCapsProvider 75 { 76 private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XComponentPeer"); 77 private static final PlatformLogger buffersLog = PlatformLogger.getLogger("sun.awt.X11.XComponentPeer.multibuffer"); 78 private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XComponentPeer"); 79 private static final PlatformLogger fontLog = PlatformLogger.getLogger("sun.awt.X11.font.XComponentPeer"); 80 private static final PlatformLogger enableLog = PlatformLogger.getLogger("sun.awt.X11.enable.XComponentPeer"); 81 private static final PlatformLogger shapeLog = PlatformLogger.getLogger("sun.awt.X11.shape.XComponentPeer"); 82 83 boolean paintPending = false; 84 boolean isLayouting = false; 85 boolean enabled; 86 87 // Actually used only by XDecoratedPeer 88 protected int boundsOperation; 89 90 Color foreground; 91 Color background; 92 93 // Colors calculated as on Motif using MotifColorUtilties. 94 // If you use these, call updateMotifColors() in the peer's Constructor and 95 // setBackground(). Examples are XCheckboxPeer and XButtonPeer. 96 Color darkShadow; 97 Color lightShadow; 98 Color selectColor; 99 100 Font font; 101 private long backBuffer = 0; 102 private VolatileImage xBackBuffer = null; 103 104 static Color[] systemColors; 105 106 XComponentPeer() { 107 } 108 109 XComponentPeer (XCreateWindowParams params) { 110 super(params); 111 } 112 113 XComponentPeer(Component target, long parentWindow, Rectangle bounds) { 114 super(target, parentWindow, bounds); 115 } 116 117 /** 118 * Standard peer constructor, with corresponding Component 119 */ 120 XComponentPeer(Component target) { 121 super(target); 122 } 123 124 125 void preInit(XCreateWindowParams params) { 126 super.preInit(params); 127 boundsOperation = DEFAULT_OPERATION; 128 } 129 void postInit(XCreateWindowParams params) { 130 super.postInit(params); 131 Color c; 132 Font f; 133 Cursor cursor; 134 135 pSetCursor(target.getCursor()); 136 137 foreground = target.getForeground(); 138 background = target.getBackground(); 139 font = target.getFont(); 140 141 if (isInitialReshape()) { 142 Rectangle r = target.getBounds(); 143 reshape(r.x, r.y, r.width, r.height); 144 } 145 146 enabled = target.isEnabled(); 147 148 // If any of our heavyweight ancestors are disable, we should be too 149 // See 6176875 for more information 150 Component comp = target; 151 while( !(comp == null || comp instanceof Window) ) { 152 comp = comp.getParent(); 153 if( comp != null && !comp.isEnabled() && !comp.isLightweight() ){ 154 setEnabled(false); 155 break; 156 } 157 } 158 enableLog.fine("Initial enable state: {0}", Boolean.valueOf(enabled)); 159 160 if (target.isVisible()) { 161 setVisible(true); 162 } 163 } 164 165 protected boolean isInitialReshape() { 166 return true; 167 } 168 169 public void reparent(ContainerPeer newNativeParent) { 170 XComponentPeer newPeer = (XComponentPeer)newNativeParent; 171 XToolkit.awtLock(); 172 try { 173 XlibWrapper.XReparentWindow(XToolkit.getDisplay(), getWindow(), newPeer.getContentWindow(), x, y); 174 parentWindow = newPeer; 175 } finally { 176 XToolkit.awtUnlock(); 177 } 178 } 179 public boolean isReparentSupported() { 180 return System.getProperty("sun.awt.X11.XComponentPeer.reparentNotSupported", "false").equals("false"); 181 } 182 183 public boolean isObscured() { 184 Container container = (target instanceof Container) ? 185 (Container)target : target.getParent(); 186 187 if (container == null) { 188 return true; 189 } 190 191 Container parent; 192 while ((parent = container.getParent()) != null) { 193 container = parent; 194 } 195 196 if (container instanceof Window) { 197 XWindowPeer wpeer = (XWindowPeer)(container.getPeer()); 198 if (wpeer != null) { 199 return (wpeer.winAttr.visibilityState != 200 wpeer.winAttr.AWT_UNOBSCURED); 201 } 202 } 203 return true; 204 } 205 206 public boolean canDetermineObscurity() { 207 return true; 208 } 209 210 /************************************************* 211 * FOCUS STUFF 212 *************************************************/ 213 214 /** 215 * Keeps the track of focused state of the _NATIVE_ window 216 */ 217 boolean bHasFocus = false; 218 219 /** 220 * Descendants should use this method to determine whether or not native window 221 * has focus. 222 */ 223 final public boolean hasFocus() { 224 return bHasFocus; 225 } 226 227 /** 228 * Called when component receives focus 229 */ 230 public void focusGained(FocusEvent e) { 231 focusLog.fine("{0}", e); 232 bHasFocus = true; 233 } 234 235 /** 236 * Called when component loses focus 237 */ 238 public void focusLost(FocusEvent e) { 239 focusLog.fine("{0}", e); 240 bHasFocus = false; 241 } 242 243 public boolean isFocusable() { 244 /* should be implemented by other sub-classes */ 245 return false; 246 } 247 248 private static Class seClass; 249 private static Constructor seCtor; 250 251 final static AWTEvent wrapInSequenced(AWTEvent event) { 252 try { 253 if (seClass == null) { 254 seClass = Class.forName("java.awt.SequencedEvent"); 255 } 256 257 if (seCtor == null) { 258 seCtor = (Constructor) AccessController.doPrivileged(new PrivilegedExceptionAction() { 259 public Object run() throws Exception { 260 Constructor ctor = seClass.getConstructor(new Class[] { AWTEvent.class }); 261 ctor.setAccessible(true); 262 return ctor; 263 } 264 }); 265 } 266 267 return (AWTEvent) seCtor.newInstance(new Object[] { event }); 268 } 269 catch (ClassNotFoundException e) { 270 throw new NoClassDefFoundError("java.awt.SequencedEvent."); 271 } 272 catch (PrivilegedActionException ex) { 273 throw new NoClassDefFoundError("java.awt.SequencedEvent."); 274 } 275 catch (InstantiationException e) { 276 assert false; 277 } 278 catch (IllegalAccessException e) { 279 assert false; 280 } 281 catch (InvocationTargetException e) { 282 assert false; 283 } 284 285 return null; 286 } 287 288 // TODO: consider moving it to KeyboardFocusManagerPeerImpl 289 final public boolean requestFocus(Component lightweightChild, boolean temporary, 290 boolean focusedWindowChangeAllowed, long time, 291 CausedFocusEvent.Cause cause) 292 { 293 if (XKeyboardFocusManagerPeer. 294 processSynchronousLightweightTransfer(target, lightweightChild, temporary, 295 focusedWindowChangeAllowed, time)) 296 { 297 return true; 298 } 299 300 int result = XKeyboardFocusManagerPeer. 301 shouldNativelyFocusHeavyweight(target, lightweightChild, 302 temporary, focusedWindowChangeAllowed, 303 time, cause); 304 305 switch (result) { 306 case XKeyboardFocusManagerPeer.SNFH_FAILURE: 307 return false; 308 case XKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED: 309 // Currently we just generate focus events like we deal with lightweight instead of calling 310 // XSetInputFocus on native window 311 if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Proceeding with request to " + 312 lightweightChild + " in " + target); 313 /** 314 * The problems with requests in non-focused window arise because shouldNativelyFocusHeavyweight 315 * checks that native window is focused while appropriate WINDOW_GAINED_FOCUS has not yet 316 * been processed - it is in EventQueue. Thus, SNFH allows native request and stores request record 317 * in requests list - and it breaks our requests sequence as first record on WGF should be the last 318 * focus owner which had focus before WLF. So, we should not add request record for such requests 319 * but store this component in mostRecent - and return true as before for compatibility. 320 */ 321 Window parentWindow = SunToolkit.getContainingWindow(target); 322 if (parentWindow == null) { 323 return rejectFocusRequestHelper("WARNING: Parent window is null"); 324 } 325 XWindowPeer wpeer = (XWindowPeer)parentWindow.getPeer(); 326 if (wpeer == null) { 327 return rejectFocusRequestHelper("WARNING: Parent window's peer is null"); 328 } 329 /* 330 * Passing null 'actualFocusedWindow' as we don't want to restore focus on it 331 * when a component inside a Frame is requesting focus. 332 * See 6314575 for details. 333 */ 334 boolean res = wpeer.requestWindowFocus(null); 335 336 if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Requested window focus: " + res); 337 // If parent window can be made focused and has been made focused(synchronously) 338 // then we can proceed with children, otherwise we retreat. 339 if (!(res && parentWindow.isFocused())) { 340 return rejectFocusRequestHelper("Waiting for asynchronous processing of the request"); 341 } 342 return XKeyboardFocusManagerPeer.deliverFocus(lightweightChild, 343 (Component)target, 344 temporary, 345 focusedWindowChangeAllowed, 346 time, cause); 347 // Motif compatibility code 348 case XKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED: 349 // Either lightweight or excessive request - all events are generated. 350 return true; 351 } 352 return false; 353 } 354 355 private boolean rejectFocusRequestHelper(String logMsg) { 356 if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer(logMsg); 357 XKeyboardFocusManagerPeer.removeLastFocusRequest(target); 358 return false; 359 } 360 361 void handleJavaFocusEvent(AWTEvent e) { 362 if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer(e.toString()); 363 if (e.getID() == FocusEvent.FOCUS_GAINED) { 364 focusGained((FocusEvent)e); 365 } else { 366 focusLost((FocusEvent)e); 367 } 368 } 369 370 void handleJavaWindowFocusEvent(AWTEvent e) { 371 } 372 373 /************************************************* 374 * END OF FOCUS STUFF 375 *************************************************/ 376 377 378 379 public void setVisible(boolean b) { 380 xSetVisible(b); 381 } 382 383 public void hide() { 384 setVisible(false); 385 } 386 387 388 /** 389 * @see java.awt.peer.ComponentPeer 390 */ 391 public void setEnabled(boolean value) { 392 enableLog.fine("{0}ing {1}", (value?"Enabl":"Disabl"), this); 393 boolean repaintNeeded = (enabled != value); 394 enabled = value; 395 if (target instanceof Container) { 396 Component list[] = ((Container)target).getComponents(); 397 for (int i = 0; i < list.length; ++i) { 398 boolean childEnabled = list[i].isEnabled(); 399 ComponentPeer p = list[i].getPeer(); 400 if ( p != null ) { 401 p.setEnabled(value && childEnabled); 402 } 403 } 404 } 405 if (repaintNeeded) { 406 repaint(); 407 } 408 } 409 410 // 411 // public so aw/Window can call it 412 // 413 public boolean isEnabled() { 414 return enabled; 415 } 416 417 418 419 public void enable() { 420 setEnabled(true); 421 } 422 423 public void disable() { 424 setEnabled(false); 425 } 426 @Override 427 public void paint(final Graphics g) { 428 super.paint(g); 429 // allow target to change the picture 430 target.paint(g); 431 } 432 433 public Graphics getGraphics() { 434 return getGraphics(surfaceData, getPeerForeground(), getPeerBackground(), getPeerFont()); 435 } 436 public void print(Graphics g) { 437 // clear rect here to emulate X clears rect before Expose 438 g.setColor(target.getBackground()); 439 g.fillRect(0, 0, target.getWidth(), target.getHeight()); 440 g.setColor(target.getForeground()); 441 // paint peer 442 paintPeer(g); 443 // allow target to change the picture 444 target.print(g); 445 } 446 447 public void setBounds(int x, int y, int width, int height, int op) { 448 this.x = x; 449 this.y = y; 450 this.width = width; 451 this.height = height; 452 xSetBounds(x,y,width,height); 453 validateSurface(); 454 layout(); 455 } 456 457 public void reshape(int x, int y, int width, int height) { 458 setBounds(x, y, width, height, SET_BOUNDS); 459 } 460 461 public void coalescePaintEvent(PaintEvent e) { 462 Rectangle r = e.getUpdateRect(); 463 if (!(e instanceof IgnorePaintEvent)) { 464 paintArea.add(r, e.getID()); 465 } 466 if (true) { 467 switch(e.getID()) { 468 case PaintEvent.UPDATE: 469 if (log.isLoggable(PlatformLogger.FINER)) { 470 log.finer("XCP coalescePaintEvent : UPDATE : add : x = " + 471 r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height); 472 } 473 return; 474 case PaintEvent.PAINT: 475 if (log.isLoggable(PlatformLogger.FINER)) { 476 log.finer("XCP coalescePaintEvent : PAINT : add : x = " + 477 r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height); 478 } 479 return; 480 } 481 } 482 } 483 484 XWindowPeer getParentTopLevel() { 485 AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); 486 Container parent = (target instanceof Container) ? ((Container)target) : (compAccessor.getParent(target)); 487 // Search for parent window 488 while (parent != null && !(parent instanceof Window)) { 489 parent = compAccessor.getParent(parent); 490 } 491 if (parent != null) { 492 return (XWindowPeer)compAccessor.getPeer(parent); 493 } else { 494 return null; 495 } 496 } 497 498 /* This method is intended to be over-ridden by peers to perform user interaction */ 499 void handleJavaMouseEvent(MouseEvent e) { 500 switch (e.getID()) { 501 case MouseEvent.MOUSE_PRESSED: 502 if (target == e.getSource() && 503 !target.isFocusOwner() && 504 XKeyboardFocusManagerPeer.shouldFocusOnClick(target)) 505 { 506 XWindowPeer parentXWindow = getParentTopLevel(); 507 Window parentWindow = ((Window)parentXWindow.getTarget()); 508 // Simple windows are non-focusable in X terms but focusable in Java terms. 509 // As X-non-focusable they don't receive any focus events - we should generate them 510 // by ourselfves. 511 // if (parentXWindow.isFocusableWindow() /*&& parentXWindow.isSimpleWindow()*/ && 512 // !(getCurrentNativeFocusedWindow() == parentWindow)) 513 // { 514 // setCurrentNativeFocusedWindow(parentWindow); 515 // WindowEvent wfg = new WindowEvent(parentWindow, WindowEvent.WINDOW_GAINED_FOCUS); 516 // parentWindow.dispatchEvent(wfg); 517 // } 518 XKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT); 519 } 520 break; 521 } 522 } 523 524 /* This method is intended to be over-ridden by peers to perform user interaction */ 525 void handleJavaKeyEvent(KeyEvent e) { 526 } 527 528 /* This method is intended to be over-ridden by peers to perform user interaction */ 529 void handleJavaMouseWheelEvent(MouseWheelEvent e) { 530 } 531 532 533 /* This method is intended to be over-ridden by peers to perform user interaction */ 534 void handleJavaInputMethodEvent(InputMethodEvent e) { 535 } 536 537 void handleF10JavaKeyEvent(KeyEvent e) { 538 if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_F10) { 539 XWindowPeer winPeer = this.getToplevelXWindow(); 540 if (winPeer instanceof XFramePeer) { 541 XMenuBarPeer mPeer = ((XFramePeer)winPeer).getMenubarPeer(); 542 if (mPeer != null) { 543 mPeer.handleF10KeyPress(e); 544 } 545 } 546 } 547 } 548 549 public void handleEvent(java.awt.AWTEvent e) { 550 if ((e instanceof InputEvent) && !((InputEvent)e).isConsumed() && target.isEnabled()) { 551 if (e instanceof MouseEvent) { 552 if (e instanceof MouseWheelEvent) { 553 handleJavaMouseWheelEvent((MouseWheelEvent) e); 554 } 555 else 556 handleJavaMouseEvent((MouseEvent) e); 557 } 558 else if (e instanceof KeyEvent) { 559 handleF10JavaKeyEvent((KeyEvent)e); 560 handleJavaKeyEvent((KeyEvent)e); 561 } 562 } 563 else if (e instanceof KeyEvent && !((InputEvent)e).isConsumed()) { 564 // even if target is disabled. 565 handleF10JavaKeyEvent((KeyEvent)e); 566 } 567 else if (e instanceof InputMethodEvent) { 568 handleJavaInputMethodEvent((InputMethodEvent) e); 569 } 570 571 int id = e.getID(); 572 573 switch(id) { 574 case PaintEvent.PAINT: 575 // Got native painting 576 paintPending = false; 577 // Fallthrough to next statement 578 case PaintEvent.UPDATE: 579 // Skip all painting while layouting and all UPDATEs 580 // while waiting for native paint 581 if (!isLayouting && !paintPending) { 582 paintArea.paint(target,false); 583 } 584 return; 585 case FocusEvent.FOCUS_LOST: 586 case FocusEvent.FOCUS_GAINED: 587 handleJavaFocusEvent(e); 588 break; 589 case WindowEvent.WINDOW_LOST_FOCUS: 590 case WindowEvent.WINDOW_GAINED_FOCUS: 591 handleJavaWindowFocusEvent(e); 592 break; 593 default: 594 break; 595 } 596 597 } 598 599 public void handleButtonPressRelease(XEvent xev) { 600 /* 601 * Fix for 6385277. 602 * We request focus on simple Window by click in order 603 * to make it behave like Frame/Dialog in this case and also to unify 604 * the behaviour with what we have on MS Windows. 605 * handleJavaMouseEvent() would be more suitable place to do this 606 * but we want Swing to have this functionality also. 607 */ 608 if (xev.get_type() == XConstants.ButtonPress) { 609 final XWindowPeer parentXWindow = getParentTopLevel(); 610 Window parentWindow = (Window)parentXWindow.getTarget(); 611 if (parentXWindow.isFocusableWindow() && parentXWindow.isSimpleWindow() && 612 XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() != parentWindow) 613 { 614 postEvent(new InvocationEvent(parentWindow, new Runnable() { 615 public void run() { 616 // Request focus on the EDT of 'parentWindow' because 617 // XDecoratedPeer.requestWindowFocus() calls client code. 618 parentXWindow.requestXFocus(); 619 } 620 })); 621 } 622 } 623 super.handleButtonPressRelease(xev); 624 } 625 626 public Dimension getMinimumSize() { 627 return target.getSize(); 628 } 629 630 public Dimension getPreferredSize() { 631 return getMinimumSize(); 632 } 633 634 public void layout() {} 635 636 public java.awt.Toolkit getToolkit() { 637 return Toolkit.getDefaultToolkit(); 638 } 639 640 void updateMotifColors(Color bg) { 641 int red = bg.getRed(); 642 int green = bg.getGreen(); 643 int blue = bg.getBlue(); 644 645 darkShadow = new Color(MotifColorUtilities.calculateBottomShadowFromBackground(red,green,blue)); 646 lightShadow = new Color(MotifColorUtilities.calculateTopShadowFromBackground(red,green,blue)); 647 selectColor= new Color(MotifColorUtilities.calculateSelectFromBackground(red,green,blue)); 648 } 649 650 /* 651 * Draw a 3D rectangle using the Motif colors. 652 * "Normal" rectangles have shadows on the bottom. 653 * "Depressed" rectangles (such as pressed buttons) have shadows on the top, 654 * in which case true should be passed for topShadow. 655 */ 656 public void drawMotif3DRect(Graphics g, 657 int x, int y, int width, int height, 658 boolean topShadow) { 659 g.setColor(topShadow ? darkShadow : lightShadow); 660 g.drawLine(x, y, x+width, y); // top 661 g.drawLine(x, y+height, x, y); // left 662 663 g.setColor(topShadow ? lightShadow : darkShadow ); 664 g.drawLine(x+1, y+height, x+width, y+height); // bottom 665 g.drawLine(x+width, y+height, x+width, y+1); // right 666 } 667 668 public void setBackground(Color c) { 669 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Set background to " + c); 670 synchronized (getStateLock()) { 671 background = c; 672 } 673 super.setBackground(c); 674 repaint(); 675 } 676 677 public void setForeground(Color c) { 678 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Set foreground to " + c); 679 synchronized (getStateLock()) { 680 foreground = c; 681 } 682 repaint(); 683 } 684 685 /** 686 * Gets the font metrics for the specified font. 687 * @param font the font for which font metrics is to be 688 * obtained 689 * @return the font metrics for <code>font</code> 690 * @see #getFont 691 * @see #getPeer 692 * @see java.awt.peer.ComponentPeer#getFontMetrics(Font) 693 * @see Toolkit#getFontMetrics(Font) 694 * @since JDK1.0 695 */ 696 public FontMetrics getFontMetrics(Font font) { 697 if (fontLog.isLoggable(PlatformLogger.FINE)) fontLog.fine("Getting font metrics for " + font); 698 return sun.font.FontDesignMetrics.getMetrics(font); 699 } 700 701 public void setFont(Font f) { 702 synchronized (getStateLock()) { 703 if (f == null) { 704 f = XWindow.getDefaultFont(); 705 } 706 font = f; 707 } 708 // as it stands currently we dont need to do layout or repaint since 709 // layout is done in the Component upon setFont. 710 //layout(); 711 // target.repaint(); 712 //repaint()? 713 } 714 715 public Font getFont() { 716 return font; 717 } 718 719 public void updateCursorImmediately() { 720 XGlobalCursorManager.getCursorManager().updateCursorImmediately(); 721 } 722 723 public final void pSetCursor(Cursor cursor) { 724 this.pSetCursor(cursor, true); 725 } 726 727 /* 728 * The method changes the cursor. 729 * @param cursor - a new cursor to change to. 730 * @param ignoreSubComponents - if {@code true} is passed then 731 * the new cursor will be installed on window. 732 * if {@code false} is passed then 733 * subsequent components will try to handle 734 * this request and install their cursor. 735 */ 736 //ignoreSubComponents not used here 737 public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) { 738 XToolkit.awtLock(); 739 try { 740 long xcursor = XGlobalCursorManager.getCursor(cursor); 741 742 XSetWindowAttributes xwa = new XSetWindowAttributes(); 743 xwa.set_cursor(xcursor); 744 745 long valuemask = XConstants.CWCursor; 746 747 XlibWrapper.XChangeWindowAttributes(XToolkit.getDisplay(),getWindow(),valuemask,xwa.pData); 748 XlibWrapper.XFlush(XToolkit.getDisplay()); 749 xwa.dispose(); 750 } finally { 751 XToolkit.awtUnlock(); 752 } 753 } 754 755 public Image createImage(ImageProducer producer) { 756 return new ToolkitImage(producer); 757 } 758 759 public Image createImage(int width, int height) { 760 return graphicsConfig.createAcceleratedImage(target, width, height); 761 } 762 763 public VolatileImage createVolatileImage(int width, int height) { 764 return new SunVolatileImage(target, width, height); 765 } 766 767 public boolean prepareImage(Image img, int w, int h, ImageObserver o) { 768 return getToolkit().prepareImage(img, w, h, o); 769 } 770 771 public int checkImage(Image img, int w, int h, ImageObserver o) { 772 return getToolkit().checkImage(img, w, h, o); 773 } 774 775 public Dimension preferredSize() { 776 return getPreferredSize(); 777 } 778 779 public Dimension minimumSize() { 780 return getMinimumSize(); 781 } 782 783 public Insets getInsets() { 784 return new Insets(0, 0, 0, 0); 785 } 786 787 public void beginValidate() { 788 } 789 790 public void endValidate() { 791 } 792 793 794 /** 795 * DEPRECATED: Replaced by getInsets(). 796 */ 797 798 public Insets insets() { 799 return getInsets(); 800 } 801 802 // Returns true if we are inside begin/endLayout and 803 // are waiting for native painting 804 public boolean isPaintPending() { 805 return paintPending && isLayouting; 806 } 807 808 public boolean handlesWheelScrolling() { 809 return false; 810 } 811 812 public void beginLayout() { 813 // Skip all painting till endLayout 814 isLayouting = true; 815 816 } 817 818 public void endLayout() { 819 if (!paintPending && !paintArea.isEmpty() 820 && !AWTAccessor.getComponentAccessor().getIgnoreRepaint(target)) 821 { 822 // if not waiting for native painting repaint damaged area 823 postEvent(new PaintEvent(target, PaintEvent.PAINT, 824 new Rectangle())); 825 } 826 isLayouting = false; 827 } 828 829 public Color getWinBackground() { 830 return getPeerBackground(); 831 } 832 833 static int[] getRGBvals(Color c) { 834 835 int rgbvals[] = new int[3]; 836 837 rgbvals[0] = c.getRed(); 838 rgbvals[1] = c.getGreen(); 839 rgbvals[2] = c.getBlue(); 840 841 return rgbvals; 842 } 843 844 static final int BACKGROUND_COLOR = 0; 845 static final int HIGHLIGHT_COLOR = 1; 846 static final int SHADOW_COLOR = 2; 847 static final int FOREGROUND_COLOR = 3; 848 849 public Color[] getGUIcolors() { 850 Color c[] = new Color[4]; 851 float backb, highb, shadowb, hue, saturation; 852 c[BACKGROUND_COLOR] = getWinBackground(); 853 if (c[BACKGROUND_COLOR] == null) { 854 c[BACKGROUND_COLOR] = super.getWinBackground(); 855 } 856 if (c[BACKGROUND_COLOR] == null) { 857 c[BACKGROUND_COLOR] = Color.lightGray; 858 } 859 860 int[] rgb = getRGBvals(c[BACKGROUND_COLOR]); 861 862 float[] hsb = Color.RGBtoHSB(rgb[0],rgb[1],rgb[2],null); 863 864 hue = hsb[0]; 865 saturation = hsb[1]; 866 backb = hsb[2]; 867 868 869 /* Calculate Highlight Brightness */ 870 871 highb = backb + 0.2f; 872 shadowb = backb - 0.4f; 873 if ((highb > 1.0) ) { 874 if ((1.0 - backb) < 0.05) { 875 highb = shadowb + 0.25f; 876 } else { 877 highb = 1.0f; 878 } 879 } else { 880 if (shadowb < 0.0) { 881 if ((backb - 0.0) < 0.25) { 882 highb = backb + 0.75f; 883 shadowb = highb - 0.2f; 884 } else { 885 shadowb = 0.0f; 886 } 887 } 888 } 889 c[HIGHLIGHT_COLOR] = Color.getHSBColor(hue,saturation,highb); 890 c[SHADOW_COLOR] = Color.getHSBColor(hue,saturation,shadowb); 891 892 893 /* 894 c[SHADOW_COLOR] = c[BACKGROUND_COLOR].darker(); 895 int r2 = c[SHADOW_COLOR].getRed(); 896 int g2 = c[SHADOW_COLOR].getGreen(); 897 int b2 = c[SHADOW_COLOR].getBlue(); 898 */ 899 900 c[FOREGROUND_COLOR] = getPeerForeground(); 901 if (c[FOREGROUND_COLOR] == null) { 902 c[FOREGROUND_COLOR] = Color.black; 903 } 904 /* 905 if ((c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR])) 906 && (c[BACKGROUND_COLOR].equals(c[SHADOW_COLOR]))) { 907 c[SHADOW_COLOR] = new Color(c[BACKGROUND_COLOR].getRed() + 75, 908 c[BACKGROUND_COLOR].getGreen() + 75, 909 c[BACKGROUND_COLOR].getBlue() + 75); 910 c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR].brighter(); 911 } else if (c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR])) { 912 c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR]; 913 c[SHADOW_COLOR] = c[SHADOW_COLOR].darker(); 914 } 915 */ 916 if (! isEnabled()) { 917 c[BACKGROUND_COLOR] = c[BACKGROUND_COLOR].darker(); 918 // Reduce the contrast 919 // Calculate the NTSC gray (NB: REC709 L* might be better!) 920 // for foreground and background; then multiply the foreground 921 // by the average lightness 922 923 924 Color tc = c[BACKGROUND_COLOR]; 925 int bg = tc.getRed() * 30 + tc.getGreen() * 59 + tc.getBlue() * 11; 926 927 tc = c[FOREGROUND_COLOR]; 928 int fg = tc.getRed() * 30 + tc.getGreen() * 59 + tc.getBlue() * 11; 929 930 float ave = (float) ((fg + bg) / 51000.0); 931 // 255 * 100 * 2 932 933 Color newForeground = new Color((int) (tc.getRed() * ave), 934 (int) (tc.getGreen() * ave), 935 (int) (tc.getBlue() * ave)); 936 937 if (newForeground.equals(c[FOREGROUND_COLOR])) { 938 // This probably means the foreground color is black or white 939 newForeground = new Color(ave, ave, ave); 940 } 941 c[FOREGROUND_COLOR] = newForeground; 942 943 } 944 945 946 return c; 947 } 948 949 /** 950 * Returns an array of Colors similar to getGUIcolors(), but using the 951 * System colors. This is useful if pieces of a Component (such as 952 * the integrated scrollbars of a List) should retain the System color 953 * instead of the background color set by Component.setBackground(). 954 */ 955 static Color[] getSystemColors() { 956 if (systemColors == null) { 957 systemColors = new Color[4]; 958 systemColors[BACKGROUND_COLOR] = SystemColor.window; 959 systemColors[HIGHLIGHT_COLOR] = SystemColor.controlLtHighlight; 960 systemColors[SHADOW_COLOR] = SystemColor.controlShadow; 961 systemColors[FOREGROUND_COLOR] = SystemColor.windowText; 962 } 963 return systemColors; 964 } 965 966 /** 967 * Draw a 3D oval. 968 */ 969 public void draw3DOval(Graphics g, Color colors[], 970 int x, int y, int w, int h, boolean raised) 971 { 972 Color c = g.getColor(); 973 g.setColor(raised ? colors[HIGHLIGHT_COLOR] : colors[SHADOW_COLOR]); 974 g.drawArc(x, y, w, h, 45, 180); 975 g.setColor(raised ? colors[SHADOW_COLOR] : colors[HIGHLIGHT_COLOR]); 976 g.drawArc(x, y, w, h, 225, 180); 977 g.setColor(c); 978 } 979 980 public void draw3DRect(Graphics g, Color colors[], 981 int x, int y, int width, int height, boolean raised) 982 { 983 Color c = g.getColor(); 984 g.setColor(raised ? colors[HIGHLIGHT_COLOR] : colors[SHADOW_COLOR]); 985 g.drawLine(x, y, x, y + height); 986 g.drawLine(x + 1, y, x + width - 1, y); 987 g.setColor(raised ? colors[SHADOW_COLOR] : colors[HIGHLIGHT_COLOR]); 988 g.drawLine(x + 1, y + height, x + width, y + height); 989 g.drawLine(x + width, y, x + width, y + height - 1); 990 g.setColor(c); 991 } 992 993 /* 994 * drawXXX() methods are used to print the native components by 995 * rendering the Motif look ourselves. 996 * ToDo(aim): needs to query native motif for more accurate color 997 * information. 998 */ 999 void draw3DOval(Graphics g, Color bg, 1000 int x, int y, int w, int h, boolean raised) 1001 { 1002 Color c = g.getColor(); 1003 Color shadow = bg.darker(); 1004 Color highlight = bg.brighter(); 1005 1006 g.setColor(raised ? highlight : shadow); 1007 g.drawArc(x, y, w, h, 45, 180); 1008 g.setColor(raised ? shadow : highlight); 1009 g.drawArc(x, y, w, h, 225, 180); 1010 g.setColor(c); 1011 } 1012 1013 void draw3DRect(Graphics g, Color bg, 1014 int x, int y, int width, int height, 1015 boolean raised) { 1016 Color c = g.getColor(); 1017 Color shadow = bg.darker(); 1018 Color highlight = bg.brighter(); 1019 1020 g.setColor(raised ? highlight : shadow); 1021 g.drawLine(x, y, x, y + height); 1022 g.drawLine(x + 1, y, x + width - 1, y); 1023 g.setColor(raised ? shadow : highlight); 1024 g.drawLine(x + 1, y + height, x + width, y + height); 1025 g.drawLine(x + width, y, x + width, y + height - 1); 1026 g.setColor(c); 1027 } 1028 1029 void drawScrollbar(Graphics g, Color bg, int thickness, int length, 1030 int min, int max, int val, int vis, boolean horizontal) { 1031 Color c = g.getColor(); 1032 double f = (double)(length - 2*(thickness-1)) / Math.max(1, ((max - min) + vis)); 1033 int v1 = thickness + (int)(f * (val - min)); 1034 int v2 = (int)(f * vis); 1035 int w2 = thickness-4; 1036 int tpts_x[] = new int[3]; 1037 int tpts_y[] = new int[3]; 1038 1039 if (length < 3*w2 ) { 1040 v1 = v2 = 0; 1041 if (length < 2*w2 + 2) { 1042 w2 = (length-2)/2; 1043 } 1044 } else if (v2 < 7) { 1045 // enforce a minimum handle size 1046 v1 = Math.max(0, v1 - ((7 - v2)>>1)); 1047 v2 = 7; 1048 } 1049 1050 int ctr = thickness/2; 1051 int sbmin = ctr - w2/2; 1052 int sbmax = ctr + w2/2; 1053 1054 // paint the background slightly darker 1055 { 1056 Color d = new Color((int) (bg.getRed() * 0.85), 1057 (int) (bg.getGreen() * 0.85), 1058 (int) (bg.getBlue() * 0.85)); 1059 1060 g.setColor(d); 1061 if (horizontal) { 1062 g.fillRect(0, 0, length, thickness); 1063 } else { 1064 g.fillRect(0, 0, thickness, length); 1065 } 1066 } 1067 1068 // paint the thumb and arrows in the normal background color 1069 g.setColor(bg); 1070 if (v1 > 0) { 1071 if (horizontal) { 1072 g.fillRect(v1, 3, v2, thickness-3); 1073 } else { 1074 g.fillRect(3, v1, thickness-3, v2); 1075 } 1076 } 1077 1078 tpts_x[0] = ctr; tpts_y[0] = 2; 1079 tpts_x[1] = sbmin; tpts_y[1] = w2; 1080 tpts_x[2] = sbmax; tpts_y[2] = w2; 1081 if (horizontal) { 1082 g.fillPolygon(tpts_y, tpts_x, 3); 1083 } else { 1084 g.fillPolygon(tpts_x, tpts_y, 3); 1085 } 1086 1087 tpts_y[0] = length-2; 1088 tpts_y[1] = length-w2; 1089 tpts_y[2] = length-w2; 1090 if (horizontal) { 1091 g.fillPolygon(tpts_y, tpts_x, 3); 1092 } else { 1093 g.fillPolygon(tpts_x, tpts_y, 3); 1094 } 1095 1096 Color highlight = bg.brighter(); 1097 1098 // // // // draw the "highlighted" edges 1099 g.setColor(highlight); 1100 1101 // outline & arrows 1102 if (horizontal) { 1103 g.drawLine(1, thickness, length - 1, thickness); 1104 g.drawLine(length - 1, 1, length - 1, thickness); 1105 1106 // arrows 1107 g.drawLine(1, ctr, w2, sbmin); 1108 g.drawLine(length - w2, sbmin, length - w2, sbmax); 1109 g.drawLine(length - w2, sbmin, length - 2, ctr); 1110 1111 } else { 1112 g.drawLine(thickness, 1, thickness, length - 1); 1113 g.drawLine(1, length - 1, thickness, length - 1); 1114 1115 // arrows 1116 g.drawLine(ctr, 1, sbmin, w2); 1117 g.drawLine(sbmin, length - w2, sbmax, length - w2); 1118 g.drawLine(sbmin, length - w2, ctr, length - 2); 1119 } 1120 1121 // thumb 1122 if (v1 > 0) { 1123 if (horizontal) { 1124 g.drawLine(v1, 2, v1 + v2, 2); 1125 g.drawLine(v1, 2, v1, thickness-3); 1126 } else { 1127 g.drawLine(2, v1, 2, v1 + v2); 1128 g.drawLine(2, v1, thickness-3, v1); 1129 } 1130 } 1131 1132 Color shadow = bg.darker(); 1133 1134 // // // // draw the "shadowed" edges 1135 g.setColor(shadow); 1136 1137 // outline && arrows 1138 if (horizontal) { 1139 g.drawLine(0, 0, 0, thickness); 1140 g.drawLine(0, 0, length - 1, 0); 1141 1142 // arrows 1143 g.drawLine(w2, sbmin, w2, sbmax); 1144 g.drawLine(w2, sbmax, 1, ctr); 1145 g.drawLine(length-2, ctr, length-w2, sbmax); 1146 1147 } else { 1148 g.drawLine(0, 0, thickness, 0); 1149 g.drawLine(0, 0, 0, length - 1); 1150 1151 // arrows 1152 g.drawLine(sbmin, w2, sbmax, w2); 1153 g.drawLine(sbmax, w2, ctr, 1); 1154 g.drawLine(ctr, length-2, sbmax, length-w2); 1155 } 1156 1157 // thumb 1158 if (v1 > 0) { 1159 if (horizontal) { 1160 g.drawLine(v1 + v2, 2, v1 + v2, thickness-2); 1161 g.drawLine(v1, thickness-2, v1 + v2, thickness-2); 1162 } else { 1163 g.drawLine(2, v1 + v2, thickness-2, v1 + v2); 1164 g.drawLine(thickness-2, v1, thickness-2, v1 + v2); 1165 } 1166 } 1167 g.setColor(c); 1168 } 1169 1170 /** 1171 * The following multibuffering-related methods delegate to our 1172 * associated GraphicsConfig (X11 or GLX) to handle the appropriate 1173 * native windowing system specific actions. 1174 */ 1175 1176 private BufferCapabilities backBufferCaps; 1177 1178 public void createBuffers(int numBuffers, BufferCapabilities caps) 1179 throws AWTException 1180 { 1181 if (buffersLog.isLoggable(PlatformLogger.FINE)) { 1182 buffersLog.fine("createBuffers(" + numBuffers + ", " + caps + ")"); 1183 } 1184 // set the caps first, they're used when creating the bb 1185 backBufferCaps = caps; 1186 backBuffer = graphicsConfig.createBackBuffer(this, numBuffers, caps); 1187 xBackBuffer = graphicsConfig.createBackBufferImage(target, 1188 backBuffer); 1189 } 1190 1191 @Override 1192 public BufferCapabilities getBackBufferCaps() { 1193 return backBufferCaps; 1194 } 1195 1196 public void flip(int x1, int y1, int x2, int y2, 1197 BufferCapabilities.FlipContents flipAction) 1198 { 1199 if (buffersLog.isLoggable(PlatformLogger.FINE)) { 1200 buffersLog.fine("flip(" + flipAction + ")"); 1201 } 1202 if (backBuffer == 0) { 1203 throw new IllegalStateException("Buffers have not been created"); 1204 } 1205 graphicsConfig.flip(this, target, xBackBuffer, 1206 x1, y1, x2, y2, flipAction); 1207 } 1208 1209 public Image getBackBuffer() { 1210 if (buffersLog.isLoggable(PlatformLogger.FINE)) { 1211 buffersLog.fine("getBackBuffer()"); 1212 } 1213 if (backBuffer == 0) { 1214 throw new IllegalStateException("Buffers have not been created"); 1215 } 1216 return xBackBuffer; 1217 } 1218 1219 public void destroyBuffers() { 1220 if (buffersLog.isLoggable(PlatformLogger.FINE)) { 1221 buffersLog.fine("destroyBuffers()"); 1222 } 1223 graphicsConfig.destroyBackBuffer(backBuffer); 1224 backBuffer = 0; 1225 xBackBuffer = null; 1226 } 1227 1228 // End of multi-buffering 1229 1230 public void notifyTextComponentChange(boolean add){ 1231 Container parent = AWTAccessor.getComponentAccessor().getParent(target); 1232 while(!(parent == null || 1233 parent instanceof java.awt.Frame || 1234 parent instanceof java.awt.Dialog)) { 1235 parent = AWTAccessor.getComponentAccessor().getParent(parent); 1236 } 1237 1238 /* FIX ME - FIX ME need to implement InputMethods 1239 if (parent instanceof java.awt.Frame || 1240 parent instanceof java.awt.Dialog) { 1241 if (add) 1242 ((MInputMethodControl)parent.getPeer()).addTextComponent((MComponentPeer)this); 1243 else 1244 ((MInputMethodControl)parent.getPeer()).removeTextComponent((MComponentPeer)this); 1245 } 1246 */ 1247 } 1248 1249 /** 1250 * Returns true if this event is disabled and shouldn't be processed by window 1251 * Currently if target component is disabled the following event will be disabled on window: 1252 * ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify 1253 */ 1254 protected boolean isEventDisabled(XEvent e) { 1255 if (enableLog.isLoggable(PlatformLogger.FINEST)) { 1256 enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable")); 1257 } 1258 if (!isEnabled()) { 1259 switch (e.get_type()) { 1260 case XConstants.ButtonPress: 1261 case XConstants.ButtonRelease: 1262 case XConstants.KeyPress: 1263 case XConstants.KeyRelease: 1264 case XConstants.EnterNotify: 1265 case XConstants.LeaveNotify: 1266 case XConstants.MotionNotify: 1267 if (enableLog.isLoggable(PlatformLogger.FINER)) { 1268 enableLog.finer("Event {0} is disable", e); 1269 } 1270 return true; 1271 } 1272 } 1273 switch(e.get_type()) { 1274 case XConstants.MapNotify: 1275 case XConstants.UnmapNotify: 1276 return true; 1277 } 1278 return super.isEventDisabled(e); 1279 } 1280 1281 Color getPeerBackground() { 1282 return background; 1283 } 1284 1285 Color getPeerForeground() { 1286 return foreground; 1287 } 1288 1289 Font getPeerFont() { 1290 return font; 1291 } 1292 1293 Dimension getPeerSize() { 1294 return new Dimension(width,height); 1295 } 1296 1297 public void setBoundsOperation(int operation) { 1298 synchronized(getStateLock()) { 1299 if (boundsOperation == DEFAULT_OPERATION) { 1300 boundsOperation = operation; 1301 } else if (operation == RESET_OPERATION) { 1302 boundsOperation = DEFAULT_OPERATION; 1303 } 1304 } 1305 } 1306 1307 static String operationToString(int operation) { 1308 switch (operation) { 1309 case SET_LOCATION: 1310 return "SET_LOCATION"; 1311 case SET_SIZE: 1312 return "SET_SIZE"; 1313 case SET_CLIENT_SIZE: 1314 return "SET_CLIENT_SIZE"; 1315 default: 1316 case SET_BOUNDS: 1317 return "SET_BOUNDS"; 1318 } 1319 } 1320 1321 /** 1322 * Lowers this component at the bottom of the above HW peer. If the above parameter 1323 * is null then the method places this component at the top of the Z-order. 1324 */ 1325 public void setZOrder(ComponentPeer above) { 1326 long aboveWindow = (above != null) ? ((XComponentPeer)above).getWindow() : 0; 1327 1328 XToolkit.awtLock(); 1329 try{ 1330 XlibWrapper.SetZOrder(XToolkit.getDisplay(), getWindow(), aboveWindow); 1331 }finally{ 1332 XToolkit.awtUnlock(); 1333 } 1334 } 1335 1336 private void addTree(Collection order, Set set, Container cont) { 1337 for (int i = 0; i < cont.getComponentCount(); i++) { 1338 Component comp = cont.getComponent(i); 1339 ComponentPeer peer = comp.getPeer(); 1340 if (peer instanceof XComponentPeer) { 1341 Long window = Long.valueOf(((XComponentPeer)peer).getWindow()); 1342 if (!set.contains(window)) { 1343 set.add(window); 1344 order.add(window); 1345 } 1346 } else if (comp instanceof Container) { 1347 // It is lightweight container, it might contain heavyweight components attached to this 1348 // peer 1349 addTree(order, set, (Container)comp); 1350 } 1351 } 1352 } 1353 1354 /****** DropTargetPeer implementation ********************/ 1355 1356 public void addDropTarget(DropTarget dt) { 1357 Component comp = target; 1358 while(!(comp == null || comp instanceof Window)) { 1359 comp = comp.getParent(); 1360 } 1361 1362 if (comp instanceof Window) { 1363 XWindowPeer wpeer = (XWindowPeer)(comp.getPeer()); 1364 if (wpeer != null) { 1365 wpeer.addDropTarget(); 1366 } 1367 } 1368 } 1369 1370 public void removeDropTarget(DropTarget dt) { 1371 Component comp = target; 1372 while(!(comp == null || comp instanceof Window)) { 1373 comp = comp.getParent(); 1374 } 1375 1376 if (comp instanceof Window) { 1377 XWindowPeer wpeer = (XWindowPeer)(comp.getPeer()); 1378 if (wpeer != null) { 1379 wpeer.removeDropTarget(); 1380 } 1381 } 1382 } 1383 1384 /** 1385 * Applies the shape to the X-window. 1386 * @since 1.7 1387 */ 1388 public void applyShape(Region shape) { 1389 if (XlibUtil.isShapingSupported()) { 1390 if (shapeLog.isLoggable(PlatformLogger.FINER)) { 1391 shapeLog.finer( 1392 "*** INFO: Setting shape: PEER: " + this 1393 + "; WINDOW: " + getWindow() 1394 + "; TARGET: " + target 1395 + "; SHAPE: " + shape); 1396 } 1397 XToolkit.awtLock(); 1398 try { 1399 if (shape != null) { 1400 XlibWrapper.SetRectangularShape( 1401 XToolkit.getDisplay(), 1402 getWindow(), 1403 shape.getLoX(), shape.getLoY(), 1404 shape.getHiX(), shape.getHiY(), 1405 (shape.isRectangular() ? null : shape) 1406 ); 1407 } else { 1408 XlibWrapper.SetRectangularShape( 1409 XToolkit.getDisplay(), 1410 getWindow(), 1411 0, 0, 1412 0, 0, 1413 null 1414 ); 1415 } 1416 } finally { 1417 XToolkit.awtUnlock(); 1418 } 1419 } else { 1420 if (shapeLog.isLoggable(PlatformLogger.FINER)) { 1421 shapeLog.finer("*** WARNING: Shaping is NOT supported!"); 1422 } 1423 } 1424 } 1425 1426 public boolean updateGraphicsData(GraphicsConfiguration gc) { 1427 int oldVisual = -1, newVisual = -1; 1428 1429 if (graphicsConfig != null) { 1430 oldVisual = graphicsConfig.getVisual(); 1431 } 1432 if (gc != null && gc instanceof X11GraphicsConfig) { 1433 newVisual = ((X11GraphicsConfig)gc).getVisual(); 1434 } 1435 1436 // If the new visual differs from the old one, the peer must be 1437 // recreated because X11 does not allow changing the visual on the fly. 1438 // So we even skip the initGraphicsConfiguration() call. 1439 // The initial assignment should happen though, hence the != -1 thing. 1440 if (oldVisual != -1 && oldVisual != newVisual) { 1441 return true; 1442 } 1443 1444 initGraphicsConfiguration(); 1445 doValidateSurface(); 1446 return false; 1447 } 1448 }