1 /* 2 * Copyright (c) 1996, 2009, 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.windows; 26 27 import java.awt.*; 28 import java.awt.peer.*; 29 import java.awt.image.VolatileImage; 30 import sun.awt.RepaintArea; 31 import sun.awt.CausedFocusEvent; 32 import sun.awt.image.SunVolatileImage; 33 import sun.awt.image.ToolkitImage; 34 import java.awt.image.BufferedImage; 35 import java.awt.image.ImageProducer; 36 import java.awt.image.ImageObserver; 37 import java.awt.image.ColorModel; 38 import java.awt.event.PaintEvent; 39 import java.awt.event.InvocationEvent; 40 import java.awt.event.KeyEvent; 41 import sun.awt.Win32GraphicsConfig; 42 import sun.awt.Win32GraphicsEnvironment; 43 import sun.java2d.InvalidPipeException; 44 import sun.java2d.SurfaceData; 45 import sun.java2d.ScreenUpdateManager; 46 import sun.java2d.d3d.D3DSurfaceData; 47 import sun.java2d.opengl.OGLSurfaceData; 48 import sun.java2d.pipe.Region; 49 import sun.awt.DisplayChangedListener; 50 import sun.awt.PaintEventDispatcher; 51 import sun.awt.SunToolkit; 52 import sun.awt.event.IgnorePaintEvent; 53 54 import java.awt.dnd.DropTarget; 55 import java.awt.dnd.peer.DropTargetPeer; 56 import sun.awt.ComponentAccessor; 57 58 import java.util.logging.*; 59 60 61 public abstract class WComponentPeer extends WObjectPeer 62 implements ComponentPeer, DropTargetPeer, DisplayChangedListener 63 { 64 /** 65 * Handle to native window 66 */ 67 protected volatile long hwnd; 68 69 private static final Logger log = Logger.getLogger("sun.awt.windows.WComponentPeer"); 70 private static final Logger shapeLog = Logger.getLogger("sun.awt.windows.shape.WComponentPeer"); 71 72 static { 73 wheelInit(); 74 } 75 76 // Only actually does stuff if running on 95 77 native static void wheelInit(); 78 79 // ComponentPeer implementation 80 SurfaceData surfaceData; 81 82 private RepaintArea paintArea; 83 84 protected Win32GraphicsConfig winGraphicsConfig; 85 86 boolean isLayouting = false; 87 boolean paintPending = false; 88 int oldWidth = -1; 89 int oldHeight = -1; 90 private int numBackBuffers = 0; 91 private VolatileImage backBuffer = null; 92 private BufferCapabilities backBufferCaps = null; 93 94 // foreground, background and color are cached to avoid calling back 95 // into the Component. 96 private Color foreground; 97 private Color background; 98 private Font font; 99 100 public native boolean isObscured(); 101 public boolean canDetermineObscurity() { return true; } 102 103 // DropTarget support 104 105 int nDropTargets; 106 long nativeDropTargetContext; // native pointer 107 108 public synchronized native void pShow(); 109 public synchronized native void hide(); 110 public synchronized native void enable(); 111 public synchronized native void disable(); 112 113 public long getHWnd() { 114 return hwnd; 115 } 116 117 /* New 1.1 API */ 118 public native Point getLocationOnScreen(); 119 120 /* New 1.1 API */ 121 public void setVisible(boolean b) { 122 if (b) { 123 show(); 124 } else { 125 hide(); 126 } 127 } 128 129 public void show() { 130 Dimension s = ((Component)target).getSize(); 131 oldHeight = s.height; 132 oldWidth = s.width; 133 pShow(); 134 } 135 136 /* New 1.1 API */ 137 public void setEnabled(boolean b) { 138 if (b) { 139 enable(); 140 } else { 141 disable(); 142 } 143 } 144 145 public int serialNum = 0; 146 147 private native void reshapeNoCheck(int x, int y, int width, int height); 148 149 /* New 1.1 API */ 150 public void setBounds(int x, int y, int width, int height, int op) { 151 // Should set paintPending before reahape to prevent 152 // thread race between paint events 153 // Native components do redraw after resize 154 paintPending = (width != oldWidth) || (height != oldHeight); 155 156 if ( (op & NO_EMBEDDED_CHECK) != 0 ) { 157 reshapeNoCheck(x, y, width, height); 158 } else { 159 reshape(x, y, width, height); 160 } 161 if ((width != oldWidth) || (height != oldHeight)) { 162 // Only recreate surfaceData if this setBounds is called 163 // for a resize; a simple move should not trigger a recreation 164 try { 165 replaceSurfaceData(); 166 } catch (InvalidPipeException e) { 167 // REMIND : what do we do if our surface creation failed? 168 } 169 oldWidth = width; 170 oldHeight = height; 171 } 172 173 serialNum++; 174 } 175 176 /* 177 * Called from native code (on Toolkit thread) in order to 178 * dynamically layout the Container during resizing 179 */ 180 void dynamicallyLayoutContainer() { 181 // If we got the WM_SIZING, this must be a Container, right? 182 // In fact, it must be the top-level Container. 183 if (log.isLoggable(Level.FINE)) { 184 Container parent = WToolkit.getNativeContainer((Component)target); 185 if (parent != null) { 186 log.log(Level.FINE, "Assertion (parent == null) failed"); 187 } 188 } 189 final Container cont = (Container)target; 190 191 WToolkit.executeOnEventHandlerThread(cont, new Runnable() { 192 public void run() { 193 // Discarding old paint events doesn't seem to be necessary. 194 cont.invalidate(); 195 cont.validate(); 196 197 if (surfaceData instanceof D3DSurfaceData.D3DWindowSurfaceData || 198 surfaceData instanceof OGLSurfaceData) 199 { 200 // When OGL or D3D is enabled, it is necessary to 201 // replace the SurfaceData for each dynamic layout 202 // request so that the viewport stays in sync 203 // with the window bounds. 204 try { 205 replaceSurfaceData(); 206 } catch (InvalidPipeException e) { 207 // REMIND: this is unlikely to occur for OGL, but 208 // what do we do if surface creation fails? 209 } 210 } 211 212 // Forcing a paint here doesn't seem to be necessary. 213 // paintDamagedAreaImmediately(); 214 } 215 }); 216 } 217 218 /* 219 * Paints any portion of the component that needs updating 220 * before the call returns (similar to the Win32 API UpdateWindow) 221 */ 222 void paintDamagedAreaImmediately() { 223 // force Windows to send any pending WM_PAINT events so 224 // the damage area is updated on the Java side 225 updateWindow(); 226 // make sure paint events are transferred to main event queue 227 // for coalescing 228 WToolkit.getWToolkit().flushPendingEvents(); 229 // paint the damaged area 230 paintArea.paint(target, shouldClearRectBeforePaint()); 231 } 232 233 native synchronized void updateWindow(); 234 235 public void paint(Graphics g) { 236 ((Component)target).paint(g); 237 } 238 239 public void repaint(long tm, int x, int y, int width, int height) { 240 } 241 242 private static final double BANDING_DIVISOR = 4.0; 243 private native int[] createPrintedPixels(int srcX, int srcY, 244 int srcW, int srcH, 245 int alpha); 246 public void print(Graphics g) { 247 248 Component comp = (Component)target; 249 250 // To conserve memory usage, we will band the image. 251 252 int totalW = comp.getWidth(); 253 int totalH = comp.getHeight(); 254 255 int hInc = (int)(totalH / BANDING_DIVISOR); 256 if (hInc == 0) { 257 hInc = totalH; 258 } 259 260 for (int startY = 0; startY < totalH; startY += hInc) { 261 int endY = startY + hInc - 1; 262 if (endY >= totalH) { 263 endY = totalH - 1; 264 } 265 int h = endY - startY + 1; 266 267 Color bgColor = comp.getBackground(); 268 int[] pix = createPrintedPixels(0, startY, totalW, h, 269 bgColor == null ? 255 : bgColor.getAlpha()); 270 if (pix != null) { 271 BufferedImage bim = new BufferedImage(totalW, h, 272 BufferedImage.TYPE_INT_ARGB); 273 bim.setRGB(0, 0, totalW, h, pix, 0, totalW); 274 g.drawImage(bim, 0, startY, null); 275 bim.flush(); 276 } 277 } 278 279 comp.print(g); 280 } 281 282 public void coalescePaintEvent(PaintEvent e) { 283 Rectangle r = e.getUpdateRect(); 284 if (!(e instanceof IgnorePaintEvent)) { 285 paintArea.add(r, e.getID()); 286 } 287 288 if (log.isLoggable(Level.FINEST)) { 289 switch(e.getID()) { 290 case PaintEvent.UPDATE: 291 log.log(Level.FINEST, "coalescePaintEvent: UPDATE: add: x = " + 292 r.x + ", y = " + r.y + ", width = " + r.width + ", height = " + r.height); 293 return; 294 case PaintEvent.PAINT: 295 log.log(Level.FINEST, "coalescePaintEvent: PAINT: add: x = " + 296 r.x + ", y = " + r.y + ", width = " + r.width + ", height = " + r.height); 297 return; 298 } 299 } 300 } 301 302 public synchronized native void reshape(int x, int y, int width, int height); 303 304 // returns true if the event has been handled and shouldn't be propagated 305 // though handleEvent method chain - e.g. WTextFieldPeer returns true 306 // on handling '\n' to prevent it from being passed to native code 307 public boolean handleJavaKeyEvent(KeyEvent e) { return false; } 308 309 native void nativeHandleEvent(AWTEvent e); 310 311 public void handleEvent(AWTEvent e) { 312 int id = e.getID(); 313 314 if (((Component)target).isEnabled() && (e instanceof KeyEvent) && !((KeyEvent)e).isConsumed()) { 315 if (handleJavaKeyEvent((KeyEvent)e)) { 316 return; 317 } 318 } 319 320 switch(id) { 321 case PaintEvent.PAINT: 322 // Got native painting 323 paintPending = false; 324 // Fallthrough to next statement 325 case PaintEvent.UPDATE: 326 // Skip all painting while layouting and all UPDATEs 327 // while waiting for native paint 328 if (!isLayouting && ! paintPending) { 329 paintArea.paint(target,shouldClearRectBeforePaint()); 330 } 331 return; 332 default: 333 break; 334 } 335 336 // Call the native code 337 nativeHandleEvent(e); 338 } 339 340 public Dimension getMinimumSize() { 341 return ((Component)target).getSize(); 342 } 343 344 public Dimension getPreferredSize() { 345 return getMinimumSize(); 346 } 347 348 // Do nothing for heavyweight implementation 349 public void layout() {} 350 351 public Rectangle getBounds() { 352 return ((Component)target).getBounds(); 353 } 354 355 public boolean isFocusable() { 356 return false; 357 } 358 359 /* 360 * Return the GraphicsConfiguration associated with this peer, either 361 * the locally stored winGraphicsConfig, or that of the target Component. 362 */ 363 public GraphicsConfiguration getGraphicsConfiguration() { 364 if (winGraphicsConfig != null) { 365 return winGraphicsConfig; 366 } 367 else { 368 // we don't need a treelock here, since 369 // Component.getGraphicsConfiguration() gets it itself. 370 return ((Component)target).getGraphicsConfiguration(); 371 } 372 } 373 374 public SurfaceData getSurfaceData() { 375 return surfaceData; 376 } 377 378 /** 379 * Creates new surfaceData object and invalidates the previous 380 * surfaceData object. 381 * Replacing the surface data should never lock on any resources which are 382 * required by other threads which may have them and may require 383 * the tree-lock. 384 * This is a degenerate version of replaceSurfaceData(numBackBuffers), so 385 * just call that version with our current numBackBuffers. 386 */ 387 public void replaceSurfaceData() { 388 replaceSurfaceData(this.numBackBuffers, this.backBufferCaps); 389 } 390 391 /** 392 * Multi-buffer version of replaceSurfaceData. This version is called 393 * by createBuffers(), which needs to acquire the same locks in the same 394 * order, but also needs to perform additional functions inside the 395 * locks. 396 */ 397 public void replaceSurfaceData(int newNumBackBuffers, 398 BufferCapabilities caps) 399 { 400 SurfaceData oldData = null; 401 VolatileImage oldBB = null; 402 synchronized(((Component)target).getTreeLock()) { 403 synchronized(this) { 404 if (pData == 0) { 405 return; 406 } 407 numBackBuffers = newNumBackBuffers; 408 Win32GraphicsConfig gc = 409 (Win32GraphicsConfig)getGraphicsConfiguration(); 410 ScreenUpdateManager mgr = ScreenUpdateManager.getInstance(); 411 oldData = surfaceData; 412 mgr.dropScreenSurface(oldData); 413 surfaceData = 414 mgr.createScreenSurface(gc, this, numBackBuffers, true); 415 if (oldData != null) { 416 oldData.invalidate(); 417 } 418 419 oldBB = backBuffer; 420 if (numBackBuffers > 0) { 421 // set the caps first, they're used when creating the bb 422 backBufferCaps = caps; 423 backBuffer = gc.createBackBuffer(this); 424 } else if (backBuffer != null) { 425 backBufferCaps = null; 426 backBuffer = null; 427 } 428 } 429 } 430 // it would be better to do this before we create new ones, 431 // but then we'd run into deadlock issues 432 if (oldData != null) { 433 oldData.flush(); 434 // null out the old data to make it collected faster 435 oldData = null; 436 } 437 if (oldBB != null) { 438 oldBB.flush(); 439 // null out the old data to make it collected faster 440 oldData = null; 441 } 442 } 443 444 public void replaceSurfaceDataLater() { 445 Runnable r = new Runnable() { 446 public void run() { 447 // Shouldn't do anything if object is disposed in meanwhile 448 // No need for sync as disposeAction in Window is performed 449 // on EDT 450 if (!isDisposed()) { 451 try { 452 replaceSurfaceData(); 453 } catch (InvalidPipeException e) { 454 // REMIND : what do we do if our surface creation failed? 455 } 456 } 457 } 458 }; 459 Component c = (Component)target; 460 // Fix 6255371. 461 if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing(c, r)) { 462 postEvent(new InvocationEvent(c, r)); 463 } 464 } 465 466 /** 467 * From the DisplayChangedListener interface. 468 * 469 * Called after a change in the display mode. This event 470 * triggers replacing the surfaceData object (since that object 471 * reflects the current display depth information, which has 472 * just changed). 473 */ 474 public void displayChanged() { 475 try { 476 replaceSurfaceData(); 477 } catch (InvalidPipeException e) { 478 // REMIND : what do we do if our surface creation failed? 479 } 480 } 481 482 /** 483 * Part of the DisplayChangedListener interface: components 484 * do not need to react to this event 485 */ 486 public void paletteChanged() { 487 } 488 489 //This will return null for Components not yet added to a Container 490 public ColorModel getColorModel() { 491 GraphicsConfiguration gc = getGraphicsConfiguration(); 492 if (gc != null) { 493 return gc.getColorModel(); 494 } 495 else { 496 return null; 497 } 498 } 499 500 //This will return null for Components not yet added to a Container 501 public ColorModel getDeviceColorModel() { 502 Win32GraphicsConfig gc = 503 (Win32GraphicsConfig)getGraphicsConfiguration(); 504 if (gc != null) { 505 return gc.getDeviceColorModel(); 506 } 507 else { 508 return null; 509 } 510 } 511 512 //Returns null for Components not yet added to a Container 513 public ColorModel getColorModel(int transparency) { 514 // return WToolkit.config.getColorModel(transparency); 515 GraphicsConfiguration gc = getGraphicsConfiguration(); 516 if (gc != null) { 517 return gc.getColorModel(transparency); 518 } 519 else { 520 return null; 521 } 522 } 523 public java.awt.Toolkit getToolkit() { 524 return Toolkit.getDefaultToolkit(); 525 } 526 527 // fallback default font object 528 final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); 529 530 public Graphics getGraphics() { 531 SurfaceData surfaceData = this.surfaceData; 532 if (!isDisposed() && surfaceData != null) { 533 /* Fix for bug 4746122. Color and Font shouldn't be null */ 534 Color bgColor = background; 535 if (bgColor == null) { 536 bgColor = SystemColor.window; 537 } 538 Color fgColor = foreground; 539 if (fgColor == null) { 540 fgColor = SystemColor.windowText; 541 } 542 Font font = this.font; 543 if (font == null) { 544 font = defaultFont; 545 } 546 ScreenUpdateManager mgr = 547 ScreenUpdateManager.getInstance(); 548 return mgr.createGraphics(surfaceData, this, fgColor, 549 bgColor, font); 550 } 551 return null; 552 } 553 public FontMetrics getFontMetrics(Font font) { 554 return WFontMetrics.getFontMetrics(font); 555 } 556 557 private synchronized native void _dispose(); 558 protected void disposeImpl() { 559 SurfaceData oldData = surfaceData; 560 surfaceData = null; 561 ScreenUpdateManager.getInstance().dropScreenSurface(oldData); 562 oldData.invalidate(); 563 // remove from updater before calling targetDisposedPeer 564 WToolkit.targetDisposedPeer(target, this); 565 _dispose(); 566 } 567 568 public synchronized void setForeground(Color c) { 569 foreground = c; 570 _setForeground(c.getRGB()); 571 } 572 573 public synchronized void setBackground(Color c) { 574 background = c; 575 _setBackground(c.getRGB()); 576 } 577 578 /** 579 * This method is intentionally not synchronized as it is called while 580 * holding other locks. 581 * 582 * @see sun.java2d.d3d.D3DScreenUpdateManager#validate(D3DWindowSurfaceData) 583 */ 584 public Color getBackgroundNoSync() { 585 return background; 586 } 587 588 public native void _setForeground(int rgb); 589 public native void _setBackground(int rgb); 590 591 public synchronized void setFont(Font f) { 592 font = f; 593 _setFont(f); 594 } 595 public synchronized native void _setFont(Font f); 596 public final void updateCursorImmediately() { 597 WGlobalCursorManager.getCursorManager().updateCursorImmediately(); 598 } 599 600 native static boolean processSynchronousLightweightTransfer(Component heavyweight, Component descendant, 601 boolean temporary, boolean focusedWindowChangeAllowed, 602 long time); 603 public boolean requestFocus 604 (Component lightweightChild, boolean temporary, 605 boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause) { 606 if (processSynchronousLightweightTransfer((Component)target, lightweightChild, temporary, 607 focusedWindowChangeAllowed, time)) { 608 return true; 609 } else { 610 return _requestFocus(lightweightChild, temporary, focusedWindowChangeAllowed, time, cause); 611 } 612 } 613 public native boolean _requestFocus 614 (Component lightweightChild, boolean temporary, 615 boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause); 616 617 public Image createImage(ImageProducer producer) { 618 return new ToolkitImage(producer); 619 } 620 621 public Image createImage(int width, int height) { 622 Win32GraphicsConfig gc = 623 (Win32GraphicsConfig)getGraphicsConfiguration(); 624 return gc.createAcceleratedImage((Component)target, width, height); 625 } 626 627 public VolatileImage createVolatileImage(int width, int height) { 628 return new SunVolatileImage((Component)target, width, height); 629 } 630 631 public boolean prepareImage(Image img, int w, int h, ImageObserver o) { 632 return getToolkit().prepareImage(img, w, h, o); 633 } 634 635 public int checkImage(Image img, int w, int h, ImageObserver o) { 636 return getToolkit().checkImage(img, w, h, o); 637 } 638 639 // Object overrides 640 641 public String toString() { 642 return getClass().getName() + "[" + target + "]"; 643 } 644 645 // Toolkit & peer internals 646 647 private int updateX1, updateY1, updateX2, updateY2; 648 649 WComponentPeer(Component target) { 650 this.target = target; 651 this.paintArea = new RepaintArea(); 652 Container parent = WToolkit.getNativeContainer(target); 653 WComponentPeer parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent); 654 create(parentPeer); 655 // fix for 5088782: check if window object is created successfully 656 checkCreation(); 657 this.winGraphicsConfig = 658 (Win32GraphicsConfig)getGraphicsConfiguration(); 659 ScreenUpdateManager mgr = ScreenUpdateManager.getInstance(); 660 this.surfaceData = mgr.createScreenSurface(winGraphicsConfig, this, 661 numBackBuffers, false); 662 initialize(); 663 start(); // Initialize enable/disable state, turn on callbacks 664 } 665 abstract void create(WComponentPeer parent); 666 667 protected void checkCreation() 668 { 669 if ((hwnd == 0) || (pData == 0)) 670 { 671 if (createError != null) 672 { 673 throw createError; 674 } 675 else 676 { 677 throw new InternalError("couldn't create component peer"); 678 } 679 } 680 } 681 682 synchronized native void start(); 683 684 void initialize() { 685 if (((Component)target).isVisible()) { 686 show(); // the wnd starts hidden 687 } 688 Color fg = ((Component)target).getForeground(); 689 if (fg != null) { 690 setForeground(fg); 691 } 692 // Set background color in C++, to avoid inheriting a parent's color. 693 Font f = ((Component)target).getFont(); 694 if (f != null) { 695 setFont(f); 696 } 697 if (! ((Component)target).isEnabled()) { 698 disable(); 699 } 700 Rectangle r = ((Component)target).getBounds(); 701 setBounds(r.x, r.y, r.width, r.height, SET_BOUNDS); 702 } 703 704 // Callbacks for window-system events to the frame 705 706 // Invoke a update() method call on the target 707 void handleRepaint(int x, int y, int w, int h) { 708 // Repaints are posted from updateClient now... 709 } 710 711 // Invoke a paint() method call on the target, after clearing the 712 // damaged area. 713 void handleExpose(int x, int y, int w, int h) { 714 // Bug ID 4081126 & 4129709 - can't do the clearRect() here, 715 // since it interferes with the java thread working in the 716 // same window on multi-processor NT machines. 717 718 postPaintIfNecessary(x, y, w, h); 719 } 720 721 /* Invoke a paint() method call on the target, without clearing the 722 * damaged area. This is normally called by a native control after 723 * it has painted itself. 724 * 725 * NOTE: This is called on the privileged toolkit thread. Do not 726 * call directly into user code using this thread! 727 */ 728 void handlePaint(int x, int y, int w, int h) { 729 postPaintIfNecessary(x, y, w, h); 730 } 731 732 private void postPaintIfNecessary(int x, int y, int w, int h) { 733 if ( !ComponentAccessor.getIgnoreRepaint( (Component) target) ) { 734 PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher(). 735 createPaintEvent((Component)target, x, y, w, h); 736 if (event != null) { 737 postEvent(event); 738 } 739 } 740 } 741 742 /* 743 * Post an event. Queue it for execution by the callback thread. 744 */ 745 void postEvent(AWTEvent event) { 746 WToolkit.postEvent(WToolkit.targetToAppContext(target), event); 747 } 748 749 // Routines to support deferred window positioning. 750 public void beginLayout() { 751 // Skip all painting till endLayout 752 isLayouting = true; 753 } 754 755 public void endLayout() { 756 if(!paintArea.isEmpty() && !paintPending && 757 !((Component)target).getIgnoreRepaint()) { 758 // if not waiting for native painting repaint damaged area 759 postEvent(new PaintEvent((Component)target, PaintEvent.PAINT, 760 new Rectangle())); 761 } 762 isLayouting = false; 763 } 764 765 public native void beginValidate(); 766 public native void endValidate(); 767 768 /** 769 * DEPRECATED 770 */ 771 public Dimension minimumSize() { 772 return getMinimumSize(); 773 } 774 775 /** 776 * DEPRECATED 777 */ 778 public Dimension preferredSize() { 779 return getPreferredSize(); 780 } 781 782 /** 783 * register a DropTarget with this native peer 784 */ 785 786 public synchronized void addDropTarget(DropTarget dt) { 787 if (nDropTargets == 0) { 788 nativeDropTargetContext = addNativeDropTarget(); 789 } 790 nDropTargets++; 791 } 792 793 /** 794 * unregister a DropTarget with this native peer 795 */ 796 797 public synchronized void removeDropTarget(DropTarget dt) { 798 nDropTargets--; 799 if (nDropTargets == 0) { 800 removeNativeDropTarget(); 801 nativeDropTargetContext = 0; 802 } 803 } 804 805 /** 806 * add the native peer's AwtDropTarget COM object 807 * @return reference to AwtDropTarget object 808 */ 809 810 native long addNativeDropTarget(); 811 812 /** 813 * remove the native peer's AwtDropTarget COM object 814 */ 815 816 native void removeNativeDropTarget(); 817 native boolean nativeHandlesWheelScrolling(); 818 819 public boolean handlesWheelScrolling() { 820 // should this be cached? 821 return nativeHandlesWheelScrolling(); 822 } 823 824 // Returns true if we are inside begin/endLayout and 825 // are waiting for native painting 826 public boolean isPaintPending() { 827 return paintPending && isLayouting; 828 } 829 830 /** 831 * The following multibuffering-related methods delegate to our 832 * associated GraphicsConfig (Win or WGL) to handle the appropriate 833 * native windowing system specific actions. 834 */ 835 836 @Override 837 public void createBuffers(int numBuffers, BufferCapabilities caps) 838 throws AWTException 839 { 840 Win32GraphicsConfig gc = 841 (Win32GraphicsConfig)getGraphicsConfiguration(); 842 gc.assertOperationSupported((Component)target, numBuffers, caps); 843 844 // Re-create the primary surface with the new number of back buffers 845 try { 846 replaceSurfaceData(numBuffers - 1, caps); 847 } catch (InvalidPipeException e) { 848 throw new AWTException(e.getMessage()); 849 } 850 } 851 852 @Override 853 public void destroyBuffers() { 854 replaceSurfaceData(0, null); 855 } 856 857 @Override 858 public void flip(int x1, int y1, int x2, int y2, 859 BufferCapabilities.FlipContents flipAction) 860 { 861 VolatileImage backBuffer = this.backBuffer; 862 if (backBuffer == null) { 863 throw new IllegalStateException("Buffers have not been created"); 864 } 865 Win32GraphicsConfig gc = 866 (Win32GraphicsConfig)getGraphicsConfiguration(); 867 gc.flip(this, (Component)target, backBuffer, x1, y1, x2, y2, flipAction); 868 } 869 870 @Override 871 public synchronized Image getBackBuffer() { 872 Image backBuffer = this.backBuffer; 873 if (backBuffer == null) { 874 throw new IllegalStateException("Buffers have not been created"); 875 } 876 return backBuffer; 877 } 878 public BufferCapabilities getBackBufferCaps() { 879 return backBufferCaps; 880 } 881 public int getBackBuffersNum() { 882 return numBackBuffers; 883 } 884 885 /* override and return false on components that DO NOT require 886 a clearRect() before painting (i.e. native components) */ 887 public boolean shouldClearRectBeforePaint() { 888 return true; 889 } 890 891 native void pSetParent(ComponentPeer newNativeParent); 892 893 /** 894 * @see java.awt.peer.ComponentPeer#reparent 895 */ 896 public void reparent(ContainerPeer newNativeParent) { 897 pSetParent(newNativeParent); 898 } 899 900 /** 901 * @see java.awt.peer.ComponentPeer#isReparentSupported 902 */ 903 public boolean isReparentSupported() { 904 return true; 905 } 906 907 public void setBoundsOperation(int operation) { 908 } 909 910 /** 911 * Returns whether this component is capable of being hw accelerated. 912 * More specifically, whether rendering to this component or a 913 * BufferStrategy's back-buffer for this component can be hw accelerated. 914 * 915 * Conditions which could prevent hw acceleration include the toplevel 916 * window containing this component being 917 * {@link com.sun.awt.AWTUtilities.Translucency#TRANSLUCENT TRANSLUCENT}. 918 * 919 * @return {@code true} if this component is capable of being hw 920 * accelerated, {@code false} otherwise 921 * @see com.sun.awt.AWTUtilities.Translucency#TRANSLUCENT 922 */ 923 public boolean isAccelCapable() { 924 boolean isTranslucent = 925 SunToolkit.isContainingTopLevelTranslucent((Component)target); 926 // D3D/OGL and translucent windows interacted poorly in Windows XP; 927 // these problems are no longer present in Vista 928 return !isTranslucent || Win32GraphicsEnvironment.isVistaOS(); 929 } 930 931 native void setRectangularShape(int lox, int loy, int hix, int hiy, 932 Region region); 933 934 935 // REMIND: Temp workaround for issues with using HW acceleration 936 // in the browser on Vista when DWM is enabled. 937 // @return true if the toplevel container is not an EmbeddedFrame or 938 // if this EmbeddedFrame is acceleration capable, false otherwise 939 private static final boolean isContainingTopLevelAccelCapable(Component c) { 940 while (c != null && !(c instanceof WEmbeddedFrame)) { 941 c = c.getParent(); 942 } 943 if (c == null) { 944 return true; 945 } 946 return ((WEmbeddedFramePeer)c.getPeer()).isAccelCapable(); 947 } 948 949 /** 950 * Applies the shape to the native component window. 951 * @since 1.7 952 */ 953 public void applyShape(Region shape) { 954 if (shapeLog.isLoggable(Level.FINER)) { 955 shapeLog.finer("*** INFO: Setting shape: PEER: " + this 956 + "; TARGET: " + target 957 + "; SHAPE: " + shape); 958 } 959 960 if (shape != null) { 961 setRectangularShape(shape.getLoX(), shape.getLoY(), shape.getHiX(), shape.getHiY(), 962 (shape.isRectangular() ? null : shape)); 963 } else { 964 setRectangularShape(0, 0, 0, 0, null); 965 } 966 } 967 968 }