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