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 final public 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 final static 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 final public 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 #getPeer 684 * @see java.awt.peer.ComponentPeer#getFontMetrics(Font) 685 * @see Toolkit#getFontMetrics(Font) 686 * @since 1.0 687 */ 688 public FontMetrics getFontMetrics(Font font) { 689 if (fontLog.isLoggable(PlatformLogger.Level.FINE)) { 690 fontLog.fine("Getting font metrics for " + font); 691 } 692 return sun.font.FontDesignMetrics.getMetrics(font); 693 } 694 695 @Override 696 public void setFont(Font f) { 697 if (f == null) { 698 f = XWindow.getDefaultFont(); 699 } 700 synchronized (getStateLock()) { 701 if (f.equals(font)) { 702 return; 703 } 704 font = f; 705 } 706 // as it stands currently we don't need to do layout since 707 // layout is done in the Component upon setFont. 708 //layout(); 709 repaint(); 710 } 711 712 public Font getFont() { 713 return font; 714 } 715 716 public void updateCursorImmediately() { 717 XGlobalCursorManager.getCursorManager().updateCursorImmediately(); 718 } 719 720 public final void pSetCursor(Cursor cursor) { 721 this.pSetCursor(cursor, true); 722 } 723 724 /* 725 * The method changes the cursor. 726 * @param cursor - a new cursor to change to. 727 * @param ignoreSubComponents - if {@code true} is passed then 728 * the new cursor will be installed on window. 729 * if {@code false} is passed then 730 * subsequent components will try to handle 731 * this request and install their cursor. 732 */ 733 //ignoreSubComponents not used here 734 public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) { 735 XToolkit.awtLock(); 736 try { 737 long xcursor = XGlobalCursorManager.getCursor(cursor); 738 739 XSetWindowAttributes xwa = new XSetWindowAttributes(); 740 xwa.set_cursor(xcursor); 741 742 long valuemask = XConstants.CWCursor; 743 744 XlibWrapper.XChangeWindowAttributes(XToolkit.getDisplay(),getWindow(),valuemask,xwa.pData); 745 XlibWrapper.XFlush(XToolkit.getDisplay()); 746 xwa.dispose(); 747 } finally { 748 XToolkit.awtUnlock(); 749 } 750 } 751 752 public Image createImage(ImageProducer producer) { 753 return new ToolkitImage(producer); 754 } 755 756 public Image createImage(int width, int height) { 757 return graphicsConfig.createAcceleratedImage(target, width, height); 758 } 759 760 public VolatileImage createVolatileImage(int width, int height) { 761 return new SunVolatileImage(target, width, height); 762 } 763 764 public boolean prepareImage(Image img, int w, int h, ImageObserver o) { 765 return Toolkit.getDefaultToolkit().prepareImage(img, w, h, o); 766 } 767 768 public int checkImage(Image img, int w, int h, ImageObserver o) { 769 return Toolkit.getDefaultToolkit().checkImage(img, w, h, o); 770 } 771 772 public Dimension preferredSize() { 773 return getPreferredSize(); 774 } 775 776 public Dimension minimumSize() { 777 return getMinimumSize(); 778 } 779 780 public Insets getInsets() { 781 return new Insets(0, 0, 0, 0); 782 } 783 784 public void beginValidate() { 785 } 786 787 public void endValidate() { 788 } 789 790 791 /** 792 * DEPRECATED: Replaced by getInsets(). 793 */ 794 795 public Insets insets() { 796 return getInsets(); 797 } 798 799 // Returns true if we are inside begin/endLayout and 800 // are waiting for native painting 801 public boolean isPaintPending() { 802 return paintPending && isLayouting; 803 } 804 805 public boolean handlesWheelScrolling() { 806 return false; 807 } 808 809 public void beginLayout() { 810 // Skip all painting till endLayout 811 isLayouting = true; 812 813 } 814 815 public void endLayout() { 816 if (!paintPending && !paintArea.isEmpty() 817 && !AWTAccessor.getComponentAccessor().getIgnoreRepaint(target)) 818 { 819 // if not waiting for native painting repaint damaged area 820 postEvent(new PaintEvent(target, PaintEvent.PAINT, 821 new Rectangle())); 822 } 823 isLayouting = false; 824 } 825 826 public Color getWinBackground() { 827 return getPeerBackground(); 828 } 829 830 static int[] getRGBvals(Color c) { 831 832 int rgbvals[] = new int[3]; 833 834 rgbvals[0] = c.getRed(); 835 rgbvals[1] = c.getGreen(); 836 rgbvals[2] = c.getBlue(); 837 838 return rgbvals; 839 } 840 841 static final int BACKGROUND_COLOR = 0; 842 static final int HIGHLIGHT_COLOR = 1; 843 static final int SHADOW_COLOR = 2; 844 static final int FOREGROUND_COLOR = 3; 845 846 public Color[] getGUIcolors() { 847 Color c[] = new Color[4]; 848 float backb, highb, shadowb, hue, saturation; 849 c[BACKGROUND_COLOR] = getWinBackground(); 850 if (c[BACKGROUND_COLOR] == null) { 851 c[BACKGROUND_COLOR] = super.getWinBackground(); 852 } 853 if (c[BACKGROUND_COLOR] == null) { 854 c[BACKGROUND_COLOR] = Color.lightGray; 855 } 856 857 int[] rgb = getRGBvals(c[BACKGROUND_COLOR]); 858 859 float[] hsb = Color.RGBtoHSB(rgb[0],rgb[1],rgb[2],null); 860 861 hue = hsb[0]; 862 saturation = hsb[1]; 863 backb = hsb[2]; 864 865 866 /* Calculate Highlight Brightness */ 867 868 highb = backb + 0.2f; 869 shadowb = backb - 0.4f; 870 if ((highb > 1.0) ) { 871 if ((1.0 - backb) < 0.05) { 872 highb = shadowb + 0.25f; 873 } else { 874 highb = 1.0f; 875 } 876 } else { 877 if (shadowb < 0.0) { 878 if ((backb - 0.0) < 0.25) { 879 highb = backb + 0.75f; 880 shadowb = highb - 0.2f; 881 } else { 882 shadowb = 0.0f; 883 } 884 } 885 } 886 c[HIGHLIGHT_COLOR] = Color.getHSBColor(hue,saturation,highb); 887 c[SHADOW_COLOR] = Color.getHSBColor(hue,saturation,shadowb); 888 889 890 /* 891 c[SHADOW_COLOR] = c[BACKGROUND_COLOR].darker(); 892 int r2 = c[SHADOW_COLOR].getRed(); 893 int g2 = c[SHADOW_COLOR].getGreen(); 894 int b2 = c[SHADOW_COLOR].getBlue(); 895 */ 896 897 c[FOREGROUND_COLOR] = getPeerForeground(); 898 if (c[FOREGROUND_COLOR] == null) { 899 c[FOREGROUND_COLOR] = Color.black; 900 } 901 /* 902 if ((c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR])) 903 && (c[BACKGROUND_COLOR].equals(c[SHADOW_COLOR]))) { 904 c[SHADOW_COLOR] = new Color(c[BACKGROUND_COLOR].getRed() + 75, 905 c[BACKGROUND_COLOR].getGreen() + 75, 906 c[BACKGROUND_COLOR].getBlue() + 75); 907 c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR].brighter(); 908 } else if (c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR])) { 909 c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR]; 910 c[SHADOW_COLOR] = c[SHADOW_COLOR].darker(); 911 } 912 */ 913 if (! isEnabled()) { 914 c[BACKGROUND_COLOR] = c[BACKGROUND_COLOR].darker(); 915 // Reduce the contrast 916 // Calculate the NTSC gray (NB: REC709 L* might be better!) 917 // for foreground and background; then multiply the foreground 918 // by the average lightness 919 920 921 Color tc = c[BACKGROUND_COLOR]; 922 int bg = tc.getRed() * 30 + tc.getGreen() * 59 + tc.getBlue() * 11; 923 924 tc = c[FOREGROUND_COLOR]; 925 int fg = tc.getRed() * 30 + tc.getGreen() * 59 + tc.getBlue() * 11; 926 927 float ave = (float) ((fg + bg) / 51000.0); 928 // 255 * 100 * 2 929 930 Color newForeground = new Color((int) (tc.getRed() * ave), 931 (int) (tc.getGreen() * ave), 932 (int) (tc.getBlue() * ave)); 933 934 if (newForeground.equals(c[FOREGROUND_COLOR])) { 935 // This probably means the foreground color is black or white 936 newForeground = new Color(ave, ave, ave); 937 } 938 c[FOREGROUND_COLOR] = newForeground; 939 940 } 941 942 943 return c; 944 } 945 946 /** 947 * Returns an array of Colors similar to getGUIcolors(), but using the 948 * System colors. This is useful if pieces of a Component (such as 949 * the integrated scrollbars of a List) should retain the System color 950 * instead of the background color set by Component.setBackground(). 951 */ 952 static Color[] getSystemColors() { 953 if (systemColors == null) { 954 systemColors = new Color[4]; 955 systemColors[BACKGROUND_COLOR] = SystemColor.window; 956 systemColors[HIGHLIGHT_COLOR] = SystemColor.controlLtHighlight; 957 systemColors[SHADOW_COLOR] = SystemColor.controlShadow; 958 systemColors[FOREGROUND_COLOR] = SystemColor.windowText; 959 } 960 return systemColors; 961 } 962 963 /** 964 * Draw a 3D oval. 965 */ 966 public void draw3DOval(Graphics g, Color colors[], 967 int x, int y, int w, int h, boolean raised) 968 { 969 Color c = g.getColor(); 970 g.setColor(raised ? colors[HIGHLIGHT_COLOR] : colors[SHADOW_COLOR]); 971 g.drawArc(x, y, w, h, 45, 180); 972 g.setColor(raised ? colors[SHADOW_COLOR] : colors[HIGHLIGHT_COLOR]); 973 g.drawArc(x, y, w, h, 225, 180); 974 g.setColor(c); 975 } 976 977 public void draw3DRect(Graphics g, Color colors[], 978 int x, int y, int width, int height, boolean raised) 979 { 980 Color c = g.getColor(); 981 g.setColor(raised ? colors[HIGHLIGHT_COLOR] : colors[SHADOW_COLOR]); 982 g.drawLine(x, y, x, y + height); 983 g.drawLine(x + 1, y, x + width - 1, y); 984 g.setColor(raised ? colors[SHADOW_COLOR] : colors[HIGHLIGHT_COLOR]); 985 g.drawLine(x + 1, y + height, x + width, y + height); 986 g.drawLine(x + width, y, x + width, y + height - 1); 987 g.setColor(c); 988 } 989 990 /* 991 * drawXXX() methods are used to print the native components by 992 * rendering the Motif look ourselves. 993 * ToDo(aim): needs to query native motif for more accurate color 994 * information. 995 */ 996 void draw3DOval(Graphics g, Color bg, 997 int x, int y, int w, int h, boolean raised) 998 { 999 Color c = g.getColor(); 1000 Color shadow = bg.darker(); 1001 Color highlight = bg.brighter(); 1002 1003 g.setColor(raised ? highlight : shadow); 1004 g.drawArc(x, y, w, h, 45, 180); 1005 g.setColor(raised ? shadow : highlight); 1006 g.drawArc(x, y, w, h, 225, 180); 1007 g.setColor(c); 1008 } 1009 1010 void draw3DRect(Graphics g, Color bg, 1011 int x, int y, int width, int height, 1012 boolean raised) { 1013 Color c = g.getColor(); 1014 Color shadow = bg.darker(); 1015 Color highlight = bg.brighter(); 1016 1017 g.setColor(raised ? highlight : shadow); 1018 g.drawLine(x, y, x, y + height); 1019 g.drawLine(x + 1, y, x + width - 1, y); 1020 g.setColor(raised ? shadow : highlight); 1021 g.drawLine(x + 1, y + height, x + width, y + height); 1022 g.drawLine(x + width, y, x + width, y + height - 1); 1023 g.setColor(c); 1024 } 1025 1026 void drawScrollbar(Graphics g, Color bg, int thickness, int length, 1027 int min, int max, int val, int vis, boolean horizontal) { 1028 Color c = g.getColor(); 1029 double f = (double)(length - 2*(thickness-1)) / Math.max(1, ((max - min) + vis)); 1030 int v1 = thickness + (int)(f * (val - min)); 1031 int v2 = (int)(f * vis); 1032 int w2 = thickness-4; 1033 int tpts_x[] = new int[3]; 1034 int tpts_y[] = new int[3]; 1035 1036 if (length < 3*w2 ) { 1037 v1 = v2 = 0; 1038 if (length < 2*w2 + 2) { 1039 w2 = (length-2)/2; 1040 } 1041 } else if (v2 < 7) { 1042 // enforce a minimum handle size 1043 v1 = Math.max(0, v1 - ((7 - v2)>>1)); 1044 v2 = 7; 1045 } 1046 1047 int ctr = thickness/2; 1048 int sbmin = ctr - w2/2; 1049 int sbmax = ctr + w2/2; 1050 1051 // paint the background slightly darker 1052 { 1053 Color d = new Color((int) (bg.getRed() * 0.85), 1054 (int) (bg.getGreen() * 0.85), 1055 (int) (bg.getBlue() * 0.85)); 1056 1057 g.setColor(d); 1058 if (horizontal) { 1059 g.fillRect(0, 0, length, thickness); 1060 } else { 1061 g.fillRect(0, 0, thickness, length); 1062 } 1063 } 1064 1065 // paint the thumb and arrows in the normal background color 1066 g.setColor(bg); 1067 if (v1 > 0) { 1068 if (horizontal) { 1069 g.fillRect(v1, 3, v2, thickness-3); 1070 } else { 1071 g.fillRect(3, v1, thickness-3, v2); 1072 } 1073 } 1074 1075 tpts_x[0] = ctr; tpts_y[0] = 2; 1076 tpts_x[1] = sbmin; tpts_y[1] = w2; 1077 tpts_x[2] = sbmax; tpts_y[2] = 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 tpts_y[0] = length-2; 1085 tpts_y[1] = length-w2; 1086 tpts_y[2] = length-w2; 1087 if (horizontal) { 1088 g.fillPolygon(tpts_y, tpts_x, 3); 1089 } else { 1090 g.fillPolygon(tpts_x, tpts_y, 3); 1091 } 1092 1093 Color highlight = bg.brighter(); 1094 1095 // // // // draw the "highlighted" edges 1096 g.setColor(highlight); 1097 1098 // outline & arrows 1099 if (horizontal) { 1100 g.drawLine(1, thickness, length - 1, thickness); 1101 g.drawLine(length - 1, 1, length - 1, thickness); 1102 1103 // arrows 1104 g.drawLine(1, ctr, w2, sbmin); 1105 g.drawLine(length - w2, sbmin, length - w2, sbmax); 1106 g.drawLine(length - w2, sbmin, length - 2, ctr); 1107 1108 } else { 1109 g.drawLine(thickness, 1, thickness, length - 1); 1110 g.drawLine(1, length - 1, thickness, length - 1); 1111 1112 // arrows 1113 g.drawLine(ctr, 1, sbmin, w2); 1114 g.drawLine(sbmin, length - w2, sbmax, length - w2); 1115 g.drawLine(sbmin, length - w2, ctr, length - 2); 1116 } 1117 1118 // thumb 1119 if (v1 > 0) { 1120 if (horizontal) { 1121 g.drawLine(v1, 2, v1 + v2, 2); 1122 g.drawLine(v1, 2, v1, thickness-3); 1123 } else { 1124 g.drawLine(2, v1, 2, v1 + v2); 1125 g.drawLine(2, v1, thickness-3, v1); 1126 } 1127 } 1128 1129 Color shadow = bg.darker(); 1130 1131 // // // // draw the "shadowed" edges 1132 g.setColor(shadow); 1133 1134 // outline && arrows 1135 if (horizontal) { 1136 g.drawLine(0, 0, 0, thickness); 1137 g.drawLine(0, 0, length - 1, 0); 1138 1139 // arrows 1140 g.drawLine(w2, sbmin, w2, sbmax); 1141 g.drawLine(w2, sbmax, 1, ctr); 1142 g.drawLine(length-2, ctr, length-w2, sbmax); 1143 1144 } else { 1145 g.drawLine(0, 0, thickness, 0); 1146 g.drawLine(0, 0, 0, length - 1); 1147 1148 // arrows 1149 g.drawLine(sbmin, w2, sbmax, w2); 1150 g.drawLine(sbmax, w2, ctr, 1); 1151 g.drawLine(ctr, length-2, sbmax, length-w2); 1152 } 1153 1154 // thumb 1155 if (v1 > 0) { 1156 if (horizontal) { 1157 g.drawLine(v1 + v2, 2, v1 + v2, thickness-2); 1158 g.drawLine(v1, thickness-2, v1 + v2, thickness-2); 1159 } else { 1160 g.drawLine(2, v1 + v2, thickness-2, v1 + v2); 1161 g.drawLine(thickness-2, v1, thickness-2, v1 + v2); 1162 } 1163 } 1164 g.setColor(c); 1165 } 1166 1167 /** 1168 * The following multibuffering-related methods delegate to our 1169 * associated GraphicsConfig (X11 or GLX) to handle the appropriate 1170 * native windowing system specific actions. 1171 */ 1172 1173 private BufferCapabilities backBufferCaps; 1174 1175 public void createBuffers(int numBuffers, BufferCapabilities caps) 1176 throws AWTException 1177 { 1178 if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) { 1179 buffersLog.fine("createBuffers(" + numBuffers + ", " + caps + ")"); 1180 } 1181 // set the caps first, they're used when creating the bb 1182 backBufferCaps = caps; 1183 backBuffer = graphicsConfig.createBackBuffer(this, numBuffers, caps); 1184 xBackBuffer = graphicsConfig.createBackBufferImage(target, 1185 backBuffer); 1186 } 1187 1188 @Override 1189 public BufferCapabilities getBackBufferCaps() { 1190 return backBufferCaps; 1191 } 1192 1193 public void flip(int x1, int y1, int x2, int y2, 1194 BufferCapabilities.FlipContents flipAction) 1195 { 1196 if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) { 1197 buffersLog.fine("flip(" + flipAction + ")"); 1198 } 1199 if (backBuffer == 0) { 1200 throw new IllegalStateException("Buffers have not been created"); 1201 } 1202 graphicsConfig.flip(this, target, xBackBuffer, 1203 x1, y1, x2, y2, flipAction); 1204 } 1205 1206 public Image getBackBuffer() { 1207 if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) { 1208 buffersLog.fine("getBackBuffer()"); 1209 } 1210 if (backBuffer == 0) { 1211 throw new IllegalStateException("Buffers have not been created"); 1212 } 1213 return xBackBuffer; 1214 } 1215 1216 public void destroyBuffers() { 1217 if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) { 1218 buffersLog.fine("destroyBuffers()"); 1219 } 1220 graphicsConfig.destroyBackBuffer(backBuffer); 1221 backBuffer = 0; 1222 xBackBuffer = null; 1223 } 1224 1225 // End of multi-buffering 1226 1227 public void notifyTextComponentChange(boolean add){ 1228 Container parent = AWTAccessor.getComponentAccessor().getParent(target); 1229 while(!(parent == null || 1230 parent instanceof java.awt.Frame || 1231 parent instanceof java.awt.Dialog)) { 1232 parent = AWTAccessor.getComponentAccessor().getParent(parent); 1233 } 1234 1235 /* FIX ME - FIX ME need to implement InputMethods 1236 if (parent instanceof java.awt.Frame || 1237 parent instanceof java.awt.Dialog) { 1238 if (add) 1239 ((MInputMethodControl)parent.getPeer()).addTextComponent((MComponentPeer)this); 1240 else 1241 ((MInputMethodControl)parent.getPeer()).removeTextComponent((MComponentPeer)this); 1242 } 1243 */ 1244 } 1245 1246 /** 1247 * Returns true if this event is disabled and shouldn't be processed by window 1248 * Currently if target component is disabled the following event will be disabled on window: 1249 * ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify 1250 */ 1251 protected boolean isEventDisabled(XEvent e) { 1252 if (enableLog.isLoggable(PlatformLogger.Level.FINEST)) { 1253 enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable")); 1254 } 1255 if (!isEnabled()) { 1256 switch (e.get_type()) { 1257 case XConstants.ButtonPress: 1258 case XConstants.ButtonRelease: 1259 case XConstants.KeyPress: 1260 case XConstants.KeyRelease: 1261 case XConstants.EnterNotify: 1262 case XConstants.LeaveNotify: 1263 case XConstants.MotionNotify: 1264 if (enableLog.isLoggable(PlatformLogger.Level.FINER)) { 1265 enableLog.finer("Event {0} is disable", e); 1266 } 1267 return true; 1268 } 1269 } 1270 switch(e.get_type()) { 1271 case XConstants.MapNotify: 1272 case XConstants.UnmapNotify: 1273 return true; 1274 } 1275 return super.isEventDisabled(e); 1276 } 1277 1278 Color getPeerBackground() { 1279 return background; 1280 } 1281 1282 Color getPeerForeground() { 1283 return foreground; 1284 } 1285 1286 Font getPeerFont() { 1287 return font; 1288 } 1289 1290 Dimension getPeerSize() { 1291 return new Dimension(width,height); 1292 } 1293 1294 public void setBoundsOperation(int operation) { 1295 synchronized(getStateLock()) { 1296 if (boundsOperation == DEFAULT_OPERATION) { 1297 boundsOperation = operation; 1298 } else if (operation == RESET_OPERATION) { 1299 boundsOperation = DEFAULT_OPERATION; 1300 } 1301 } 1302 } 1303 1304 static String operationToString(int operation) { 1305 switch (operation) { 1306 case SET_LOCATION: 1307 return "SET_LOCATION"; 1308 case SET_SIZE: 1309 return "SET_SIZE"; 1310 case SET_CLIENT_SIZE: 1311 return "SET_CLIENT_SIZE"; 1312 default: 1313 case SET_BOUNDS: 1314 return "SET_BOUNDS"; 1315 } 1316 } 1317 1318 /** 1319 * Lowers this component at the bottom of the above HW peer. If the above parameter 1320 * is null then the method places this component at the top of the Z-order. 1321 */ 1322 public void setZOrder(ComponentPeer above) { 1323 long aboveWindow = (above != null) ? ((XComponentPeer)above).getWindow() : 0; 1324 1325 XToolkit.awtLock(); 1326 try{ 1327 XlibWrapper.SetZOrder(XToolkit.getDisplay(), getWindow(), aboveWindow); 1328 }finally{ 1329 XToolkit.awtUnlock(); 1330 } 1331 } 1332 1333 private void addTree(Collection<Long> order, Set<Long> set, Container cont) { 1334 for (int i = 0; i < cont.getComponentCount(); i++) { 1335 Component comp = cont.getComponent(i); 1336 Object peer = AWTAccessor.getComponentAccessor().getPeer(comp); 1337 if (peer instanceof XComponentPeer) { 1338 Long window = Long.valueOf(((XComponentPeer)peer).getWindow()); 1339 if (!set.contains(window)) { 1340 set.add(window); 1341 order.add(window); 1342 } 1343 } else if (comp instanceof Container) { 1344 // It is lightweight container, it might contain heavyweight components attached to this 1345 // peer 1346 addTree(order, set, (Container)comp); 1347 } 1348 } 1349 } 1350 1351 /****** DropTargetPeer implementation ********************/ 1352 1353 public void addDropTarget(DropTarget dt) { 1354 Component comp = target; 1355 while(!(comp == null || comp instanceof Window)) { 1356 comp = comp.getParent(); 1357 } 1358 1359 if (comp instanceof Window) { 1360 XWindowPeer wpeer = AWTAccessor.getComponentAccessor().getPeer(comp); 1361 if (wpeer != null) { 1362 wpeer.addDropTarget(); 1363 } 1364 } 1365 } 1366 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 = AWTAccessor.getComponentAccessor() 1375 .getPeer(comp); 1376 if (wpeer != null) { 1377 wpeer.removeDropTarget(); 1378 } 1379 } 1380 } 1381 1382 /** 1383 * Applies the shape to the X-window. 1384 * @since 1.7 1385 */ 1386 public void applyShape(Region shape) { 1387 if (XlibUtil.isShapingSupported()) { 1388 if (shapeLog.isLoggable(PlatformLogger.Level.FINER)) { 1389 shapeLog.finer( 1390 "*** INFO: Setting shape: PEER: " + this 1391 + "; WINDOW: " + getWindow() 1392 + "; TARGET: " + target 1393 + "; SHAPE: " + shape); 1394 } 1395 XToolkit.awtLock(); 1396 try { 1397 if (shape != null) { 1398 XlibWrapper.SetRectangularShape( 1399 XToolkit.getDisplay(), 1400 getWindow(), 1401 shape.getLoX(), shape.getLoY(), 1402 shape.getHiX(), shape.getHiY(), 1403 (shape.isRectangular() ? null : shape) 1404 ); 1405 } else { 1406 XlibWrapper.SetRectangularShape( 1407 XToolkit.getDisplay(), 1408 getWindow(), 1409 0, 0, 1410 0, 0, 1411 null 1412 ); 1413 } 1414 } finally { 1415 XToolkit.awtUnlock(); 1416 } 1417 } else { 1418 if (shapeLog.isLoggable(PlatformLogger.Level.FINER)) { 1419 shapeLog.finer("*** WARNING: Shaping is NOT supported!"); 1420 } 1421 } 1422 } 1423 1424 public boolean updateGraphicsData(GraphicsConfiguration gc) { 1425 int oldVisual = -1, newVisual = -1; 1426 1427 if (graphicsConfig != null) { 1428 oldVisual = graphicsConfig.getVisual(); 1429 } 1430 if (gc != null && gc instanceof X11GraphicsConfig) { 1431 newVisual = ((X11GraphicsConfig)gc).getVisual(); 1432 } 1433 1434 // If the new visual differs from the old one, the peer must be 1435 // recreated because X11 does not allow changing the visual on the fly. 1436 // So we even skip the initGraphicsConfiguration() call. 1437 // The initial assignment should happen though, hence the != -1 thing. 1438 if (oldVisual != -1 && oldVisual != newVisual) { 1439 return true; 1440 } 1441 1442 initGraphicsConfiguration(); 1443 doValidateSurface(); 1444 return false; 1445 } 1446 }