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