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