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