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