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