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