/* * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.awt.windows; import java.awt.*; import java.awt.peer.*; import java.awt.image.VolatileImage; import sun.awt.RepaintArea; import sun.awt.CausedFocusEvent; import sun.awt.image.SunVolatileImage; import sun.awt.image.ToolkitImage; import java.awt.image.BufferedImage; import java.awt.image.ImageProducer; import java.awt.image.ImageObserver; import java.awt.image.ColorModel; import java.awt.event.PaintEvent; import java.awt.event.InvocationEvent; import java.awt.event.KeyEvent; import java.awt.event.FocusEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.InputEvent; import sun.awt.Win32GraphicsConfig; import sun.awt.Win32GraphicsEnvironment; import sun.java2d.InvalidPipeException; import sun.java2d.SurfaceData; import sun.java2d.ScreenUpdateManager; import sun.java2d.d3d.D3DSurfaceData; import sun.java2d.opengl.OGLSurfaceData; import sun.java2d.pipe.Region; import sun.awt.DisplayChangedListener; import sun.awt.PaintEventDispatcher; import sun.awt.SunToolkit; import sun.awt.event.IgnorePaintEvent; import java.awt.dnd.DropTarget; import java.awt.dnd.peer.DropTargetPeer; import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; public abstract class WComponentPeer extends WObjectPeer implements ComponentPeer, DropTargetPeer { /** * Handle to native window */ protected volatile long hwnd; private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.windows.WComponentPeer"); private static final PlatformLogger shapeLog = PlatformLogger.getLogger("sun.awt.windows.shape.WComponentPeer"); private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.windows.focus.WComponentPeer"); // ComponentPeer implementation SurfaceData surfaceData; private RepaintArea paintArea; protected Win32GraphicsConfig winGraphicsConfig; boolean isLayouting = false; boolean paintPending = false; int oldWidth = -1; int oldHeight = -1; private int numBackBuffers = 0; private VolatileImage backBuffer = null; private BufferCapabilities backBufferCaps = null; // foreground, background and color are cached to avoid calling back // into the Component. private Color foreground; private Color background; private Font font; public native boolean isObscured(); public boolean canDetermineObscurity() { return true; } // DropTarget support int nDropTargets; long nativeDropTargetContext; // native pointer public synchronized native void pShow(); public synchronized native void hide(); public synchronized native void enable(); public synchronized native void disable(); public long getHWnd() { return hwnd; } /* New 1.1 API */ public native Point getLocationOnScreen(); /* New 1.1 API */ public void setVisible(boolean b) { if (b) { show(); } else { hide(); } } public void show() { Dimension s = ((Component)target).getSize(); oldHeight = s.height; oldWidth = s.width; pShow(); } /* New 1.1 API */ public void setEnabled(boolean b) { if (b) { enable(); } else { disable(); } } public int serialNum = 0; private native void reshapeNoCheck(int x, int y, int width, int height); /* New 1.1 API */ public void setBounds(int x, int y, int width, int height, int op) { // Should set paintPending before reahape to prevent // thread race between paint events // Native components do redraw after resize paintPending = (width != oldWidth) || (height != oldHeight); if ( (op & NO_EMBEDDED_CHECK) != 0 ) { reshapeNoCheck(x, y, width, height); } else { reshape(x, y, width, height); } if ((width != oldWidth) || (height != oldHeight)) { // Only recreate surfaceData if this setBounds is called // for a resize; a simple move should not trigger a recreation try { replaceSurfaceData(); } catch (InvalidPipeException e) { // REMIND : what do we do if our surface creation failed? } oldWidth = width; oldHeight = height; } serialNum++; } /* * Called from native code (on Toolkit thread) in order to * dynamically layout the Container during resizing */ void dynamicallyLayoutContainer() { // If we got the WM_SIZING, this must be a Container, right? // In fact, it must be the top-level Container. if (log.isLoggable(PlatformLogger.FINE)) { Container parent = WToolkit.getNativeContainer((Component)target); if (parent != null) { log.fine("Assertion (parent == null) failed"); } } final Container cont = (Container)target; WToolkit.executeOnEventHandlerThread(cont, new Runnable() { public void run() { // Discarding old paint events doesn't seem to be necessary. cont.invalidate(); cont.validate(); if (surfaceData instanceof D3DSurfaceData.D3DWindowSurfaceData || surfaceData instanceof OGLSurfaceData) { // When OGL or D3D is enabled, it is necessary to // replace the SurfaceData for each dynamic layout // request so that the viewport stays in sync // with the window bounds. try { replaceSurfaceData(); } catch (InvalidPipeException e) { // REMIND: this is unlikely to occur for OGL, but // what do we do if surface creation fails? } } // Forcing a paint here doesn't seem to be necessary. // paintDamagedAreaImmediately(); } }); } /* * Paints any portion of the component that needs updating * before the call returns (similar to the Win32 API UpdateWindow) */ void paintDamagedAreaImmediately() { // force Windows to send any pending WM_PAINT events so // the damage area is updated on the Java side updateWindow(); // make sure paint events are transferred to main event queue // for coalescing WToolkit.getWToolkit().flushPendingEvents(); // paint the damaged area paintArea.paint(target, shouldClearRectBeforePaint()); } native synchronized void updateWindow(); public void paint(Graphics g) { ((Component)target).paint(g); } public void repaint(long tm, int x, int y, int width, int height) { } private static final double BANDING_DIVISOR = 4.0; private native int[] createPrintedPixels(int srcX, int srcY, int srcW, int srcH, int alpha); public void print(Graphics g) { Component comp = (Component)target; // To conserve memory usage, we will band the image. int totalW = comp.getWidth(); int totalH = comp.getHeight(); int hInc = (int)(totalH / BANDING_DIVISOR); if (hInc == 0) { hInc = totalH; } for (int startY = 0; startY < totalH; startY += hInc) { int endY = startY + hInc - 1; if (endY >= totalH) { endY = totalH - 1; } int h = endY - startY + 1; Color bgColor = comp.getBackground(); int[] pix = createPrintedPixels(0, startY, totalW, h, bgColor == null ? 255 : bgColor.getAlpha()); if (pix != null) { BufferedImage bim = new BufferedImage(totalW, h, BufferedImage.TYPE_INT_ARGB); bim.setRGB(0, 0, totalW, h, pix, 0, totalW); g.drawImage(bim, 0, startY, null); bim.flush(); } } comp.print(g); } public void coalescePaintEvent(PaintEvent e) { Rectangle r = e.getUpdateRect(); if (!(e instanceof IgnorePaintEvent)) { paintArea.add(r, e.getID()); } if (log.isLoggable(PlatformLogger.FINEST)) { switch(e.getID()) { case PaintEvent.UPDATE: log.finest("coalescePaintEvent: UPDATE: add: x = " + r.x + ", y = " + r.y + ", width = " + r.width + ", height = " + r.height); return; case PaintEvent.PAINT: log.finest("coalescePaintEvent: PAINT: add: x = " + r.x + ", y = " + r.y + ", width = " + r.width + ", height = " + r.height); return; } } } public synchronized native void reshape(int x, int y, int width, int height); // returns true if the event has been handled and shouldn't be propagated // though handleEvent method chain - e.g. WTextFieldPeer returns true // on handling '\n' to prevent it from being passed to native code public boolean handleJavaKeyEvent(KeyEvent e) { return false; } public void handleJavaMouseEvent(MouseEvent e) { switch (e.getID()) { case MouseEvent.MOUSE_PRESSED: // Note that Swing requests focus in its own mouse event handler. if (target == e.getSource() && !((Component)target).isFocusOwner() && WKeyboardFocusManagerPeer.shouldFocusOnClick((Component)target)) { WKeyboardFocusManagerPeer.requestFocusFor((Component)target, CausedFocusEvent.Cause.MOUSE_EVENT); } break; } } native void nativeHandleEvent(AWTEvent e); public void handleEvent(AWTEvent e) { int id = e.getID(); if ((e instanceof InputEvent) && !((InputEvent)e).isConsumed() && ((Component)target).isEnabled()) { if (e instanceof MouseEvent && !(e instanceof MouseWheelEvent)) { handleJavaMouseEvent((MouseEvent) e); } else if (e instanceof KeyEvent) { if (handleJavaKeyEvent((KeyEvent)e)) { return; } } } switch(id) { case PaintEvent.PAINT: // Got native painting paintPending = false; // Fallthrough to next statement case PaintEvent.UPDATE: // Skip all painting while layouting and all UPDATEs // while waiting for native paint if (!isLayouting && ! paintPending) { paintArea.paint(target,shouldClearRectBeforePaint()); } return; case FocusEvent.FOCUS_LOST: case FocusEvent.FOCUS_GAINED: handleJavaFocusEvent((FocusEvent)e); default: break; } // Call the native code nativeHandleEvent(e); } void handleJavaFocusEvent(FocusEvent fe) { if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer(fe.toString()); setFocus(fe.getID() == FocusEvent.FOCUS_GAINED); } native void setFocus(boolean doSetFocus); public Dimension getMinimumSize() { return ((Component)target).getSize(); } public Dimension getPreferredSize() { return getMinimumSize(); } // Do nothing for heavyweight implementation public void layout() {} public Rectangle getBounds() { return ((Component)target).getBounds(); } public boolean isFocusable() { return false; } /* * Return the GraphicsConfiguration associated with this peer, either * the locally stored winGraphicsConfig, or that of the target Component. */ public GraphicsConfiguration getGraphicsConfiguration() { if (winGraphicsConfig != null) { return winGraphicsConfig; } else { // we don't need a treelock here, since // Component.getGraphicsConfiguration() gets it itself. return ((Component)target).getGraphicsConfiguration(); } } public SurfaceData getSurfaceData() { return surfaceData; } /** * Creates new surfaceData object and invalidates the previous * surfaceData object. * Replacing the surface data should never lock on any resources which are * required by other threads which may have them and may require * the tree-lock. * This is a degenerate version of replaceSurfaceData(numBackBuffers), so * just call that version with our current numBackBuffers. */ public void replaceSurfaceData() { replaceSurfaceData(this.numBackBuffers, this.backBufferCaps); } public void createScreenSurface(boolean isResize) { Win32GraphicsConfig gc = (Win32GraphicsConfig)getGraphicsConfiguration(); ScreenUpdateManager mgr = ScreenUpdateManager.getInstance(); surfaceData = mgr.createScreenSurface(gc, this, numBackBuffers, isResize); } /** * Multi-buffer version of replaceSurfaceData. This version is called * by createBuffers(), which needs to acquire the same locks in the same * order, but also needs to perform additional functions inside the * locks. */ public void replaceSurfaceData(int newNumBackBuffers, BufferCapabilities caps) { SurfaceData oldData = null; VolatileImage oldBB = null; synchronized(((Component)target).getTreeLock()) { synchronized(this) { if (pData == 0) { return; } numBackBuffers = newNumBackBuffers; ScreenUpdateManager mgr = ScreenUpdateManager.getInstance(); oldData = surfaceData; mgr.dropScreenSurface(oldData); createScreenSurface(true); if (oldData != null) { oldData.invalidate(); } oldBB = backBuffer; if (numBackBuffers > 0) { // set the caps first, they're used when creating the bb backBufferCaps = caps; Win32GraphicsConfig gc = (Win32GraphicsConfig)getGraphicsConfiguration(); backBuffer = gc.createBackBuffer(this); } else if (backBuffer != null) { backBufferCaps = null; backBuffer = null; } } } // it would be better to do this before we create new ones, // but then we'd run into deadlock issues if (oldData != null) { oldData.flush(); // null out the old data to make it collected faster oldData = null; } if (oldBB != null) { oldBB.flush(); // null out the old data to make it collected faster oldData = null; } } public void replaceSurfaceDataLater() { Runnable r = new Runnable() { public void run() { // Shouldn't do anything if object is disposed in meanwhile // No need for sync as disposeAction in Window is performed // on EDT if (!isDisposed()) { try { replaceSurfaceData(); } catch (InvalidPipeException e) { // REMIND : what do we do if our surface creation failed? } } } }; // Fix 6255371. if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing((Component)target, r)) { postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), r)); } } public boolean updateGraphicsData(GraphicsConfiguration gc) { winGraphicsConfig = (Win32GraphicsConfig)gc; try { replaceSurfaceData(); } catch (InvalidPipeException e) { // REMIND : what do we do if our surface creation failed? } return false; } //This will return null for Components not yet added to a Container public ColorModel getColorModel() { GraphicsConfiguration gc = getGraphicsConfiguration(); if (gc != null) { return gc.getColorModel(); } else { return null; } } //This will return null for Components not yet added to a Container public ColorModel getDeviceColorModel() { Win32GraphicsConfig gc = (Win32GraphicsConfig)getGraphicsConfiguration(); if (gc != null) { return gc.getDeviceColorModel(); } else { return null; } } //Returns null for Components not yet added to a Container public ColorModel getColorModel(int transparency) { // return WToolkit.config.getColorModel(transparency); GraphicsConfiguration gc = getGraphicsConfiguration(); if (gc != null) { return gc.getColorModel(transparency); } else { return null; } } public java.awt.Toolkit getToolkit() { return Toolkit.getDefaultToolkit(); } // fallback default font object final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); public Graphics getGraphics() { if (isDisposed()) { return null; } Component target = (Component)getTarget(); Window window = SunToolkit.getContainingWindow(target); if (window != null) { Graphics g = ((WWindowPeer)window.getPeer()).getTranslucentGraphics(); // getTranslucentGraphics() returns non-null value for non-opaque windows only if (g != null) { // Non-opaque windows do not support heavyweight children. // Redirect all painting to the Window's Graphics instead. // The caller is responsible for calling the // WindowPeer.updateWindow() after painting has finished. int x = 0, y = 0; for (Component c = target; c != window; c = c.getParent()) { x += c.getX(); y += c.getY(); } g.translate(x, y); g.clipRect(0, 0, target.getWidth(), target.getHeight()); return g; } } SurfaceData surfaceData = this.surfaceData; if (surfaceData != null) { /* Fix for bug 4746122. Color and Font shouldn't be null */ Color bgColor = background; if (bgColor == null) { bgColor = SystemColor.window; } Color fgColor = foreground; if (fgColor == null) { fgColor = SystemColor.windowText; } Font font = this.font; if (font == null) { font = defaultFont; } ScreenUpdateManager mgr = ScreenUpdateManager.getInstance(); return mgr.createGraphics(surfaceData, this, fgColor, bgColor, font); } return null; } public FontMetrics getFontMetrics(Font font) { return WFontMetrics.getFontMetrics(font); } private synchronized native void _dispose(); protected void disposeImpl() { SurfaceData oldData = surfaceData; surfaceData = null; ScreenUpdateManager.getInstance().dropScreenSurface(oldData); oldData.invalidate(); // remove from updater before calling targetDisposedPeer WToolkit.targetDisposedPeer(target, this); _dispose(); } public synchronized void setForeground(Color c) { foreground = c; _setForeground(c.getRGB()); } public synchronized void setBackground(Color c) { background = c; _setBackground(c.getRGB()); } /** * This method is intentionally not synchronized as it is called while * holding other locks. * * @see sun.java2d.d3d.D3DScreenUpdateManager#validate(D3DWindowSurfaceData) */ public Color getBackgroundNoSync() { return background; } public native void _setForeground(int rgb); public native void _setBackground(int rgb); public synchronized void setFont(Font f) { font = f; _setFont(f); } public synchronized native void _setFont(Font f); public final void updateCursorImmediately() { WGlobalCursorManager.getCursorManager().updateCursorImmediately(); } // TODO: consider moving it to KeyboardFocusManagerPeerImpl public boolean requestFocus(Component lightweightChild, boolean temporary, boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause) { if (WKeyboardFocusManagerPeer. processSynchronousLightweightTransfer((Component)target, lightweightChild, temporary, focusedWindowChangeAllowed, time)) { return true; } int result = WKeyboardFocusManagerPeer .shouldNativelyFocusHeavyweight((Component)target, lightweightChild, temporary, focusedWindowChangeAllowed, time, cause); switch (result) { case WKeyboardFocusManagerPeer.SNFH_FAILURE: return false; case WKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED: if (focusLog.isLoggable(PlatformLogger.FINER)) { focusLog.finer("Proceeding with request to " + lightweightChild + " in " + target); } Window parentWindow = SunToolkit.getContainingWindow((Component)target); if (parentWindow == null) { return rejectFocusRequestHelper("WARNING: Parent window is null"); } WWindowPeer wpeer = (WWindowPeer)parentWindow.getPeer(); if (wpeer == null) { return rejectFocusRequestHelper("WARNING: Parent window's peer is null"); } boolean res = wpeer.requestWindowFocus(cause); if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Requested window focus: " + res); // If parent window can be made focused and has been made focused(synchronously) // then we can proceed with children, otherwise we retreat. if (!(res && parentWindow.isFocused())) { return rejectFocusRequestHelper("Waiting for asynchronous processing of the request"); } return WKeyboardFocusManagerPeer.deliverFocus(lightweightChild, (Component)target, temporary, focusedWindowChangeAllowed, time, cause); case WKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED: // Either lightweight or excessive request - all events are generated. return true; } return false; } private boolean rejectFocusRequestHelper(String logMsg) { if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer(logMsg); WKeyboardFocusManagerPeer.removeLastFocusRequest((Component)target); return false; } public Image createImage(ImageProducer producer) { return new ToolkitImage(producer); } public Image createImage(int width, int height) { Win32GraphicsConfig gc = (Win32GraphicsConfig)getGraphicsConfiguration(); return gc.createAcceleratedImage((Component)target, width, height); } public VolatileImage createVolatileImage(int width, int height) { return new SunVolatileImage((Component)target, width, height); } public boolean prepareImage(Image img, int w, int h, ImageObserver o) { return getToolkit().prepareImage(img, w, h, o); } public int checkImage(Image img, int w, int h, ImageObserver o) { return getToolkit().checkImage(img, w, h, o); } // Object overrides public String toString() { return getClass().getName() + "[" + target + "]"; } // Toolkit & peer internals private int updateX1, updateY1, updateX2, updateY2; WComponentPeer(Component target) { this.target = target; this.paintArea = new RepaintArea(); Container parent = WToolkit.getNativeContainer(target); WComponentPeer parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent); create(parentPeer); // fix for 5088782: check if window object is created successfully checkCreation(); createScreenSurface(false); initialize(); start(); // Initialize enable/disable state, turn on callbacks } abstract void create(WComponentPeer parent); protected void checkCreation() { if ((hwnd == 0) || (pData == 0)) { if (createError != null) { throw createError; } else { throw new InternalError("couldn't create component peer"); } } } synchronized native void start(); void initialize() { if (((Component)target).isVisible()) { show(); // the wnd starts hidden } Color fg = ((Component)target).getForeground(); if (fg != null) { setForeground(fg); } // Set background color in C++, to avoid inheriting a parent's color. Font f = ((Component)target).getFont(); if (f != null) { setFont(f); } if (! ((Component)target).isEnabled()) { disable(); } Rectangle r = ((Component)target).getBounds(); setBounds(r.x, r.y, r.width, r.height, SET_BOUNDS); } // Callbacks for window-system events to the frame // Invoke a update() method call on the target void handleRepaint(int x, int y, int w, int h) { // Repaints are posted from updateClient now... } // Invoke a paint() method call on the target, after clearing the // damaged area. void handleExpose(int x, int y, int w, int h) { // Bug ID 4081126 & 4129709 - can't do the clearRect() here, // since it interferes with the java thread working in the // same window on multi-processor NT machines. postPaintIfNecessary(x, y, w, h); } /* Invoke a paint() method call on the target, without clearing the * damaged area. This is normally called by a native control after * it has painted itself. * * NOTE: This is called on the privileged toolkit thread. Do not * call directly into user code using this thread! */ public void handlePaint(int x, int y, int w, int h) { postPaintIfNecessary(x, y, w, h); } private void postPaintIfNecessary(int x, int y, int w, int h) { if ( !AWTAccessor.getComponentAccessor().getIgnoreRepaint( (Component) target) ) { PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher(). createPaintEvent((Component)target, x, y, w, h); if (event != null) { postEvent(event); } } } /* * Post an event. Queue it for execution by the callback thread. */ void postEvent(AWTEvent event) { preprocessPostEvent(event); WToolkit.postEvent(WToolkit.targetToAppContext(target), event); } void preprocessPostEvent(AWTEvent event) {} // Routines to support deferred window positioning. public void beginLayout() { // Skip all painting till endLayout isLayouting = true; } public void endLayout() { if(!paintArea.isEmpty() && !paintPending && !((Component)target).getIgnoreRepaint()) { // if not waiting for native painting repaint damaged area postEvent(new PaintEvent((Component)target, PaintEvent.PAINT, new Rectangle())); } isLayouting = false; } public native void beginValidate(); public native void endValidate(); /** * DEPRECATED */ public Dimension minimumSize() { return getMinimumSize(); } /** * DEPRECATED */ public Dimension preferredSize() { return getPreferredSize(); } /** * register a DropTarget with this native peer */ public synchronized void addDropTarget(DropTarget dt) { if (nDropTargets == 0) { nativeDropTargetContext = addNativeDropTarget(); } nDropTargets++; } /** * unregister a DropTarget with this native peer */ public synchronized void removeDropTarget(DropTarget dt) { nDropTargets--; if (nDropTargets == 0) { removeNativeDropTarget(); nativeDropTargetContext = 0; } } /** * add the native peer's AwtDropTarget COM object * @return reference to AwtDropTarget object */ native long addNativeDropTarget(); /** * remove the native peer's AwtDropTarget COM object */ native void removeNativeDropTarget(); native boolean nativeHandlesWheelScrolling(); public boolean handlesWheelScrolling() { // should this be cached? return nativeHandlesWheelScrolling(); } // Returns true if we are inside begin/endLayout and // are waiting for native painting public boolean isPaintPending() { return paintPending && isLayouting; } /** * The following multibuffering-related methods delegate to our * associated GraphicsConfig (Win or WGL) to handle the appropriate * native windowing system specific actions. */ @Override public void createBuffers(int numBuffers, BufferCapabilities caps) throws AWTException { Win32GraphicsConfig gc = (Win32GraphicsConfig)getGraphicsConfiguration(); gc.assertOperationSupported((Component)target, numBuffers, caps); // Re-create the primary surface with the new number of back buffers try { replaceSurfaceData(numBuffers - 1, caps); } catch (InvalidPipeException e) { throw new AWTException(e.getMessage()); } } @Override public void destroyBuffers() { replaceSurfaceData(0, null); } @Override public void flip(int x1, int y1, int x2, int y2, BufferCapabilities.FlipContents flipAction) { VolatileImage backBuffer = this.backBuffer; if (backBuffer == null) { throw new IllegalStateException("Buffers have not been created"); } Win32GraphicsConfig gc = (Win32GraphicsConfig)getGraphicsConfiguration(); gc.flip(this, (Component)target, backBuffer, x1, y1, x2, y2, flipAction); } @Override public synchronized Image getBackBuffer() { Image backBuffer = this.backBuffer; if (backBuffer == null) { throw new IllegalStateException("Buffers have not been created"); } return backBuffer; } public BufferCapabilities getBackBufferCaps() { return backBufferCaps; } public int getBackBuffersNum() { return numBackBuffers; } /* override and return false on components that DO NOT require a clearRect() before painting (i.e. native components) */ public boolean shouldClearRectBeforePaint() { return true; } native void pSetParent(ComponentPeer newNativeParent); /** * @see java.awt.peer.ComponentPeer#reparent */ public void reparent(ContainerPeer newNativeParent) { pSetParent(newNativeParent); } /** * @see java.awt.peer.ComponentPeer#isReparentSupported */ public boolean isReparentSupported() { return true; } public void setBoundsOperation(int operation) { } /** * Returns whether this component is capable of being hw accelerated. * More specifically, whether rendering to this component or a * BufferStrategy's back-buffer for this component can be hw accelerated. * * Conditions which could prevent hw acceleration include the toplevel * window containing this component being * {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT * PERPIXEL_TRANSLUCENT}. * * @return {@code true} if this component is capable of being hw * accelerated, {@code false} otherwise * @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT */ public boolean isAccelCapable() { boolean isTranslucent = SunToolkit.isContainingTopLevelTranslucent((Component)target); // D3D/OGL and translucent windows interacted poorly in Windows XP; // these problems are no longer present in Vista return !isTranslucent || Win32GraphicsEnvironment.isVistaOS(); } native void setRectangularShape(int lox, int loy, int hix, int hiy, Region region); // REMIND: Temp workaround for issues with using HW acceleration // in the browser on Vista when DWM is enabled. // @return true if the toplevel container is not an EmbeddedFrame or // if this EmbeddedFrame is acceleration capable, false otherwise private static final boolean isContainingTopLevelAccelCapable(Component c) { while (c != null && !(c instanceof WEmbeddedFrame)) { c = c.getParent(); } if (c == null) { return true; } return ((WEmbeddedFramePeer)c.getPeer()).isAccelCapable(); } /** * Applies the shape to the native component window. * @since 1.7 */ public void applyShape(Region shape) { if (shapeLog.isLoggable(PlatformLogger.FINER)) { shapeLog.finer( "*** INFO: Setting shape: PEER: " + this + "; TARGET: " + target + "; SHAPE: " + shape); } if (shape != null) { setRectangularShape(shape.getLoX(), shape.getLoY(), shape.getHiX(), shape.getHiY(), (shape.isRectangular() ? null : shape)); } else { setRectangularShape(0, 0, 0, 0, null); } } /** * Lowers this component at the bottom of the above component. If the above parameter * is null then the method places this component at the top of the Z-order. */ public void setZOrder(ComponentPeer above) { long aboveHWND = (above != null) ? ((WComponentPeer)above).getHWnd() : 0; setZOrder(aboveHWND); } private native void setZOrder(long above); }