20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.lwawt;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import java.awt.image.BufferedImage;
31 import java.awt.peer.*;
32 import java.util.List;
33
34 import javax.swing.*;
35
36 import sun.awt.*;
37 import sun.java2d.*;
38 import sun.java2d.loops.Blit;
39 import sun.java2d.loops.CompositeType;
40 import sun.util.logging.PlatformLogger;
41
42 public class LWWindowPeer
43 extends LWContainerPeer<Window, JComponent>
44 implements WindowPeer, FramePeer, DialogPeer, FullScreenCapable
45 {
46 public static enum PeerType {
47 SIMPLEWINDOW,
48 FRAME,
49 DIALOG,
50 EMBEDDEDFRAME
51 }
52
53 private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
54
55 private PlatformWindow platformWindow;
56
57 // Window bounds reported by the native system (as opposed to
58 // regular bounds inherited from LWComponentPeer which are
59 // requested by user and may haven't been applied yet because
92 // find the component under cursor
93 private static volatile LWComponentPeer lastMouseEventPeer = null;
94
95 // Peers where all dragged/released events should come to,
96 // depending on what mouse button is being dragged according to Cocoa
97 private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
98
99 // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events
100 // on MOUSE_RELEASE. Click events are only generated if there were no drag
101 // events between MOUSE_PRESSED and MOUSE_RELEASED for particular button
102 private static int mouseClickButtons = 0;
103
104 private volatile boolean isOpaque = true;
105
106 private static final Font DEFAULT_FONT = new Font("Lucida Grande", Font.PLAIN, 13);
107
108 private static LWWindowPeer grabbingWindow;
109
110 private volatile boolean skipNextFocusChange;
111
112 /**
113 * Current modal blocker or null.
114 *
115 * Synchronization: peerTreeLock.
116 */
117 private LWWindowPeer blocker;
118
119 public LWWindowPeer(Window target, PlatformComponent platformComponent,
120 PlatformWindow platformWindow)
121 {
122 super(target, platformComponent);
123 this.platformWindow = platformWindow;
124
125 Window owner = target.getOwner();
126 LWWindowPeer ownerPeer = (owner != null) ? (LWWindowPeer)owner.getPeer() : null;
127 PlatformWindow ownerDelegate = (ownerPeer != null) ? ownerPeer.getPlatformWindow() : null;
128
129 // The delegate.initialize() needs a non-null GC on X11.
130 GraphicsConfiguration gc = getTarget().getGraphicsConfiguration();
131 synchronized (getStateLock()) {
152 // we should not call setForeground because it will call a repaint
153 // which the peer may not be ready to do yet.
154 }
155
156 platformWindow.initialize(target, this, ownerDelegate);
157 }
158
159 @Override
160 void initializeImpl() {
161 super.initializeImpl();
162 if (getTarget() instanceof Frame) {
163 setTitle(((Frame) getTarget()).getTitle());
164 setState(((Frame) getTarget()).getExtendedState());
165 } else if (getTarget() instanceof Dialog) {
166 setTitle(((Dialog) getTarget()).getTitle());
167 }
168
169 setAlwaysOnTop(getTarget().isAlwaysOnTop());
170 updateMinimumSize();
171
172 final float opacity = getTarget().getOpacity();
173 if (opacity < 1.0f) {
174 setOpacity(opacity);
175 }
176
177 setOpaque(getTarget().isOpaque());
178
179 updateInsets(platformWindow.getInsets());
180 if (getSurfaceData() == null) {
181 replaceSurfaceData();
182 }
183 }
184
185 // Just a helper method
186 public PlatformWindow getPlatformWindow() {
187 return platformWindow;
188 }
189
190 @Override
191 protected LWWindowPeer getWindowPeerOrSelf() {
192 return this;
193 }
194
195 @Override
196 protected void initializeContainerPeer() {
197 // No-op as LWWindowPeer doesn't have any containerPeer
198 }
199
200 // ---- PEER METHODS ---- //
201
277 if (bg == null) {
278 bg = SystemColor.window;
279 }
280 if (f == null) {
281 f = DEFAULT_FONT;
282 }
283 return platformWindow.transformGraphics(new SunGraphics2D(getSurfaceData(), fg, bg, f));
284 }
285
286 @Override
287 public void createBuffers(int numBuffers, BufferCapabilities caps)
288 throws AWTException
289 {
290 try {
291 // Assume this method is never called with numBuffers <= 1, as 0 is
292 // unsupported, and 1 corresponds to a SingleBufferStrategy which
293 // doesn't depend on the peer. Screen is considered as a separate
294 // "buffer", that's why numBuffers - 1
295 assert numBuffers > 1;
296
297 replaceSurfaceData(numBuffers - 1, caps);
298 } catch (InvalidPipeException z) {
299 throw new AWTException(z.toString());
300 }
301 }
302
303 @Override
304 public final Image getBackBuffer() {
305 synchronized (getStateLock()) {
306 return backBuffer;
307 }
308 }
309
310 @Override
311 public void flip(int x1, int y1, int x2, int y2,
312 BufferCapabilities.FlipContents flipAction)
313 {
314 platformWindow.flip(x1, y1, x2, y2, flipAction);
315 }
316
317 @Override
417 d = new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT);
418 }
419 platformWindow.setMinimumSize(d.width, d.height);
420 }
421
422 @Override
423 public void updateIconImages() {
424 getPlatformWindow().updateIconImages();
425 }
426
427 @Override
428 public void setOpacity(float opacity) {
429 getPlatformWindow().setOpacity(opacity);
430 repaintPeer();
431 }
432
433 @Override
434 public final void setOpaque(final boolean isOpaque) {
435 if (this.isOpaque != isOpaque) {
436 this.isOpaque = isOpaque;
437 getPlatformWindow().setOpaque(isOpaque);
438 replaceSurfaceData();
439 repaintPeer();
440 }
441 }
442
443 public final boolean isOpaque() {
444 return isOpaque;
445 }
446
447 @Override
448 public void updateWindow() {
449 flushOffscreenGraphics();
450 }
451
452 @Override
453 public void repositionSecurityWarning() {
454 throw new RuntimeException("not implemented");
455 }
456
457 // ---- FRAME PEER METHODS ---- //
458
459 @Override // FramePeer and DialogPeer
460 public void setTitle(String title) {
461 platformWindow.setTitle(title == null ? "" : title);
462 }
463
464 @Override
465 public void setMenuBar(MenuBar mb) {
466 platformWindow.setMenuBar(mb);
467 }
468
469 @Override // FramePeer and DialogPeer
535 }
536 }
537
538 public void notifyZoom(boolean isZoomed) {
539 int newWindowState = isZoomed ? Frame.MAXIMIZED_BOTH : Frame.NORMAL;
540 postWindowStateChangedEvent(newWindowState);
541 }
542
543 /**
544 * Called by the delegate when any part of the window should be repainted.
545 */
546 public void notifyExpose(final int x, final int y, final int w, final int h) {
547 // TODO: there's a serious problem with Swing here: it handles
548 // the exposition internally, so SwingPaintEventDispatcher always
549 // return null from createPaintEvent(). However, we flush the
550 // back buffer here unconditionally, so some flickering may appear.
551 // A possible solution is to split postPaintEvent() into two parts,
552 // and override that part which is only called after if
553 // createPaintEvent() returned non-null value and flush the buffer
554 // from the overridden method
555 flushOnscreenGraphics();
556 repaintPeer(new Rectangle(x, y, w, h));
557 }
558
559 /**
560 * Called by the delegate when this window is moved/resized by user.
561 * There's no notifyReshape() in LWComponentPeer as the only
562 * components which could be resized by user are top-level windows.
563 */
564 public final void notifyReshape(int x, int y, int w, int h) {
565 boolean moved = false;
566 boolean resized = false;
567 synchronized (getStateLock()) {
568 moved = (x != sysX) || (y != sysY);
569 resized = (w != sysW) || (h != sysH);
570 sysX = x;
571 sysY = y;
572 sysW = w;
573 sysH = h;
574 }
575
580 // First, update peer's bounds
581 setBounds(x, y, w, h, SET_BOUNDS, false, false);
582
583 // Second, update the graphics config and surface data
584 checkIfOnNewScreen();
585 if (resized) {
586 replaceSurfaceData();
587 flushOnscreenGraphics();
588 }
589
590 // Third, COMPONENT_MOVED/COMPONENT_RESIZED events
591 if (moved) {
592 handleMove(x, y, true);
593 }
594 if (resized) {
595 handleResize(w, h,true);
596 }
597 }
598
599 private void clearBackground(final int w, final int h) {
600 final Graphics g = getOnscreenGraphics(getForeground(), getBackground(),
601 getFont());
602 if (g != null) {
603 try {
604 g.clearRect(0, 0, w, h);
605 } finally {
606 g.dispose();
607 }
608 }
609 }
610
611 public void notifyUpdateCursor() {
612 getLWToolkit().getCursorManager().updateCursorLater(this);
613 }
614
615 public void notifyActivation(boolean activation) {
616 changeFocusedWindow(activation);
617 }
618
619 // MouseDown in non-client area
620 public void notifyNCMouseDown() {
621 // Ungrab except for a click on a Dialog with the grabbing owner
622 if (grabbingWindow != null &&
623 grabbingWindow != getOwnerFrameDialog(this))
891 GraphicsDevice newGraphicsDevice = platformWindow.getGraphicsDevice();
892 synchronized (getStateLock()) {
893 if (graphicsDevice == newGraphicsDevice) {
894 return;
895 }
896 graphicsDevice = newGraphicsDevice;
897 }
898
899 // TODO: DisplayChangedListener stuff
900 final GraphicsConfiguration newGC = newGraphicsDevice.getDefaultConfiguration();
901
902 if (!setGraphicsConfig(newGC)) return;
903
904 SunToolkit.executeOnEventHandlerThread(getTarget(), new Runnable() {
905 public void run() {
906 AWTAccessor.getComponentAccessor().setGraphicsConfiguration(getTarget(), newGC);
907 }
908 });
909 }
910
911 /**
912 * This method returns a back buffer Graphics to render all the
913 * peers to. After the peer is painted, the back buffer contents
914 * should be flushed to the screen. All the target painting
915 * (Component.paint() method) should be done directly to the screen.
916 */
917 protected final Graphics getOffscreenGraphics(Color fg, Color bg, Font f) {
918 final Image bb = getBackBuffer();
919 if (bb == null) {
920 return null;
921 }
922 if (fg == null) {
923 fg = SystemColor.windowText;
924 }
925 if (bg == null) {
926 bg = SystemColor.window;
927 }
928 if (f == null) {
929 f = DEFAULT_FONT;
930 }
931 final Graphics2D g = (Graphics2D) bb.getGraphics();
932 if (g != null) {
933 g.setColor(fg);
934 g.setBackground(bg);
935 g.setFont(f);
936 }
937 return g;
938 }
939
940 /*
941 * May be called by delegate to provide SD to Java2D code.
942 */
943 public SurfaceData getSurfaceData() {
944 synchronized (surfaceDataLock) {
945 return surfaceData;
946 }
947 }
948
949 private void replaceSurfaceData() {
950 replaceSurfaceData(backBufferCount, backBufferCaps);
951 }
952
953 private void replaceSurfaceData(int newBackBufferCount,
954 BufferCapabilities newBackBufferCaps) {
955 synchronized (surfaceDataLock) {
956 final SurfaceData oldData = getSurfaceData();
957 surfaceData = platformWindow.replaceSurfaceData();
958 // TODO: volatile image
959 // VolatileImage oldBB = backBuffer;
960 BufferedImage oldBB = backBuffer;
961 backBufferCount = newBackBufferCount;
962 backBufferCaps = newBackBufferCaps;
963 final Rectangle size = getSize();
964 if (getSurfaceData() != null && oldData != getSurfaceData()) {
965 clearBackground(size.width, size.height);
966 }
967 blitSurfaceData(oldData, getSurfaceData());
968
969 if (oldData != null && oldData != getSurfaceData()) {
970 // TODO: drop oldData for D3D/WGL pipelines
971 // This can only happen when this peer is being created
972 oldData.flush();
973 }
974
975 // TODO: volatile image
976 // backBuffer = (VolatileImage)delegate.createBackBuffer();
977 backBuffer = (BufferedImage) platformWindow.createBackBuffer();
978 if (backBuffer != null) {
979 Graphics g = backBuffer.getGraphics();
980 try {
981 Rectangle r = getBounds();
982 g.setColor(getForeground());
983 ((Graphics2D) g).setBackground(getBackground());
984 g.clearRect(0, 0, r.width, r.height);
985 if (oldBB != null) {
986 // Draw the old back buffer to the new one
987 g.drawImage(oldBB, 0, 0, null);
988 oldBB.flush();
989 }
990 } finally {
991 g.dispose();
992 }
993 }
994 }
995 }
996
997 private void blitSurfaceData(final SurfaceData src, final SurfaceData dst) {
998 //TODO blit. proof-of-concept
999 if (src != dst && src != null && dst != null
1000 && !(dst instanceof NullSurfaceData)
1001 && !(src instanceof NullSurfaceData)
1002 && src.getSurfaceType().equals(dst.getSurfaceType())) {
1003 final Rectangle size = getSize();
1004 final Blit blit = Blit.locate(src.getSurfaceType(),
1005 CompositeType.Src,
1006 dst.getSurfaceType());
1007 if (blit != null) {
1008 blit.Blit(src, dst, ((Graphics2D) getGraphics()).getComposite(),
1009 getRegion(), 0, 0, 0, 0, size.width, size.height);
1010 }
1011 }
|
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.lwawt;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import java.awt.image.BufferedImage;
31 import java.awt.peer.*;
32 import java.util.List;
33
34 import javax.swing.*;
35
36 import sun.awt.*;
37 import sun.java2d.*;
38 import sun.java2d.loops.Blit;
39 import sun.java2d.loops.CompositeType;
40 import sun.java2d.pipe.Region;
41 import sun.util.logging.PlatformLogger;
42
43 public class LWWindowPeer
44 extends LWContainerPeer<Window, JComponent>
45 implements WindowPeer, FramePeer, DialogPeer, FullScreenCapable
46 {
47 public static enum PeerType {
48 SIMPLEWINDOW,
49 FRAME,
50 DIALOG,
51 EMBEDDEDFRAME
52 }
53
54 private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
55
56 private PlatformWindow platformWindow;
57
58 // Window bounds reported by the native system (as opposed to
59 // regular bounds inherited from LWComponentPeer which are
60 // requested by user and may haven't been applied yet because
93 // find the component under cursor
94 private static volatile LWComponentPeer lastMouseEventPeer = null;
95
96 // Peers where all dragged/released events should come to,
97 // depending on what mouse button is being dragged according to Cocoa
98 private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
99
100 // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events
101 // on MOUSE_RELEASE. Click events are only generated if there were no drag
102 // events between MOUSE_PRESSED and MOUSE_RELEASED for particular button
103 private static int mouseClickButtons = 0;
104
105 private volatile boolean isOpaque = true;
106
107 private static final Font DEFAULT_FONT = new Font("Lucida Grande", Font.PLAIN, 13);
108
109 private static LWWindowPeer grabbingWindow;
110
111 private volatile boolean skipNextFocusChange;
112
113 private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0);
114
115 /**
116 * Current modal blocker or null.
117 *
118 * Synchronization: peerTreeLock.
119 */
120 private LWWindowPeer blocker;
121
122 public LWWindowPeer(Window target, PlatformComponent platformComponent,
123 PlatformWindow platformWindow)
124 {
125 super(target, platformComponent);
126 this.platformWindow = platformWindow;
127
128 Window owner = target.getOwner();
129 LWWindowPeer ownerPeer = (owner != null) ? (LWWindowPeer)owner.getPeer() : null;
130 PlatformWindow ownerDelegate = (ownerPeer != null) ? ownerPeer.getPlatformWindow() : null;
131
132 // The delegate.initialize() needs a non-null GC on X11.
133 GraphicsConfiguration gc = getTarget().getGraphicsConfiguration();
134 synchronized (getStateLock()) {
155 // we should not call setForeground because it will call a repaint
156 // which the peer may not be ready to do yet.
157 }
158
159 platformWindow.initialize(target, this, ownerDelegate);
160 }
161
162 @Override
163 void initializeImpl() {
164 super.initializeImpl();
165 if (getTarget() instanceof Frame) {
166 setTitle(((Frame) getTarget()).getTitle());
167 setState(((Frame) getTarget()).getExtendedState());
168 } else if (getTarget() instanceof Dialog) {
169 setTitle(((Dialog) getTarget()).getTitle());
170 }
171
172 setAlwaysOnTop(getTarget().isAlwaysOnTop());
173 updateMinimumSize();
174
175 final Shape shape = getTarget().getShape();
176 if (shape != null) {
177 applyShape(Region.getInstance(shape, null));
178 }
179
180 final float opacity = getTarget().getOpacity();
181 if (opacity < 1.0f) {
182 setOpacity(opacity);
183 }
184
185 setOpaque(getTarget().isOpaque());
186
187 updateInsets(platformWindow.getInsets());
188 if (getSurfaceData() == null) {
189 replaceSurfaceData(false);
190 }
191 }
192
193 // Just a helper method
194 public PlatformWindow getPlatformWindow() {
195 return platformWindow;
196 }
197
198 @Override
199 protected LWWindowPeer getWindowPeerOrSelf() {
200 return this;
201 }
202
203 @Override
204 protected void initializeContainerPeer() {
205 // No-op as LWWindowPeer doesn't have any containerPeer
206 }
207
208 // ---- PEER METHODS ---- //
209
285 if (bg == null) {
286 bg = SystemColor.window;
287 }
288 if (f == null) {
289 f = DEFAULT_FONT;
290 }
291 return platformWindow.transformGraphics(new SunGraphics2D(getSurfaceData(), fg, bg, f));
292 }
293
294 @Override
295 public void createBuffers(int numBuffers, BufferCapabilities caps)
296 throws AWTException
297 {
298 try {
299 // Assume this method is never called with numBuffers <= 1, as 0 is
300 // unsupported, and 1 corresponds to a SingleBufferStrategy which
301 // doesn't depend on the peer. Screen is considered as a separate
302 // "buffer", that's why numBuffers - 1
303 assert numBuffers > 1;
304
305 replaceSurfaceData(numBuffers - 1, caps, false);
306 } catch (InvalidPipeException z) {
307 throw new AWTException(z.toString());
308 }
309 }
310
311 @Override
312 public final Image getBackBuffer() {
313 synchronized (getStateLock()) {
314 return backBuffer;
315 }
316 }
317
318 @Override
319 public void flip(int x1, int y1, int x2, int y2,
320 BufferCapabilities.FlipContents flipAction)
321 {
322 platformWindow.flip(x1, y1, x2, y2, flipAction);
323 }
324
325 @Override
425 d = new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT);
426 }
427 platformWindow.setMinimumSize(d.width, d.height);
428 }
429
430 @Override
431 public void updateIconImages() {
432 getPlatformWindow().updateIconImages();
433 }
434
435 @Override
436 public void setOpacity(float opacity) {
437 getPlatformWindow().setOpacity(opacity);
438 repaintPeer();
439 }
440
441 @Override
442 public final void setOpaque(final boolean isOpaque) {
443 if (this.isOpaque != isOpaque) {
444 this.isOpaque = isOpaque;
445 updateOpaque();
446 }
447 }
448
449 public final boolean isOpaque() {
450 return isOpaque;
451 }
452
453 private void updateOpaque() {
454 getPlatformWindow().setOpaque(!isTranslucent());
455 replaceSurfaceData(false);
456 repaintPeer();
457 }
458
459 @Override
460 public void updateWindow() {
461 }
462
463 public final boolean isTranslucent() {
464 return !isOpaque() || isShaped();
465 }
466
467 @Override
468 final void applyShapeImpl(final Region shape) {
469 super.applyShapeImpl(shape);
470 updateOpaque();
471 }
472
473 @Override
474 public void repositionSecurityWarning() {
475 throw new RuntimeException("not implemented");
476 }
477
478 // ---- FRAME PEER METHODS ---- //
479
480 @Override // FramePeer and DialogPeer
481 public void setTitle(String title) {
482 platformWindow.setTitle(title == null ? "" : title);
483 }
484
485 @Override
486 public void setMenuBar(MenuBar mb) {
487 platformWindow.setMenuBar(mb);
488 }
489
490 @Override // FramePeer and DialogPeer
556 }
557 }
558
559 public void notifyZoom(boolean isZoomed) {
560 int newWindowState = isZoomed ? Frame.MAXIMIZED_BOTH : Frame.NORMAL;
561 postWindowStateChangedEvent(newWindowState);
562 }
563
564 /**
565 * Called by the delegate when any part of the window should be repainted.
566 */
567 public void notifyExpose(final int x, final int y, final int w, final int h) {
568 // TODO: there's a serious problem with Swing here: it handles
569 // the exposition internally, so SwingPaintEventDispatcher always
570 // return null from createPaintEvent(). However, we flush the
571 // back buffer here unconditionally, so some flickering may appear.
572 // A possible solution is to split postPaintEvent() into two parts,
573 // and override that part which is only called after if
574 // createPaintEvent() returned non-null value and flush the buffer
575 // from the overridden method
576 //flushOnscreenGraphics();
577 repaintPeer(new Rectangle(x, y, w, h));
578 }
579
580 /**
581 * Called by the delegate when this window is moved/resized by user.
582 * There's no notifyReshape() in LWComponentPeer as the only
583 * components which could be resized by user are top-level windows.
584 */
585 public final void notifyReshape(int x, int y, int w, int h) {
586 boolean moved = false;
587 boolean resized = false;
588 synchronized (getStateLock()) {
589 moved = (x != sysX) || (y != sysY);
590 resized = (w != sysW) || (h != sysH);
591 sysX = x;
592 sysY = y;
593 sysW = w;
594 sysH = h;
595 }
596
601 // First, update peer's bounds
602 setBounds(x, y, w, h, SET_BOUNDS, false, false);
603
604 // Second, update the graphics config and surface data
605 checkIfOnNewScreen();
606 if (resized) {
607 replaceSurfaceData();
608 flushOnscreenGraphics();
609 }
610
611 // Third, COMPONENT_MOVED/COMPONENT_RESIZED events
612 if (moved) {
613 handleMove(x, y, true);
614 }
615 if (resized) {
616 handleResize(w, h,true);
617 }
618 }
619
620 private void clearBackground(final int w, final int h) {
621 final Graphics2D g = (Graphics2D) getOnscreenGraphics(getForeground(),
622 getBackground(),
623 getFont());
624 if (g != null) {
625 try {
626 if (isTranslucent()) {
627 g.setBackground(nonOpaqueBackground);
628 g.clearRect(0, 0, w, h);
629 }
630 SG2DConstraint((SunGraphics2D) g, getRegion());
631 g.setBackground(getBackground());
632 g.clearRect(0, 0, w, h);
633 } finally {
634 g.dispose();
635 }
636 }
637 }
638
639 public void notifyUpdateCursor() {
640 getLWToolkit().getCursorManager().updateCursorLater(this);
641 }
642
643 public void notifyActivation(boolean activation) {
644 changeFocusedWindow(activation);
645 }
646
647 // MouseDown in non-client area
648 public void notifyNCMouseDown() {
649 // Ungrab except for a click on a Dialog with the grabbing owner
650 if (grabbingWindow != null &&
651 grabbingWindow != getOwnerFrameDialog(this))
919 GraphicsDevice newGraphicsDevice = platformWindow.getGraphicsDevice();
920 synchronized (getStateLock()) {
921 if (graphicsDevice == newGraphicsDevice) {
922 return;
923 }
924 graphicsDevice = newGraphicsDevice;
925 }
926
927 // TODO: DisplayChangedListener stuff
928 final GraphicsConfiguration newGC = newGraphicsDevice.getDefaultConfiguration();
929
930 if (!setGraphicsConfig(newGC)) return;
931
932 SunToolkit.executeOnEventHandlerThread(getTarget(), new Runnable() {
933 public void run() {
934 AWTAccessor.getComponentAccessor().setGraphicsConfiguration(getTarget(), newGC);
935 }
936 });
937 }
938
939 /*
940 * May be called by delegate to provide SD to Java2D code.
941 */
942 public SurfaceData getSurfaceData() {
943 synchronized (surfaceDataLock) {
944 return surfaceData;
945 }
946 }
947
948 private void replaceSurfaceData() {
949 replaceSurfaceData(true);
950 }
951
952 private void replaceSurfaceData(boolean blit) {
953 replaceSurfaceData(backBufferCount, backBufferCaps, blit);
954 }
955
956 private void replaceSurfaceData(int newBackBufferCount,
957 BufferCapabilities newBackBufferCaps,
958 boolean blit) {
959 synchronized (surfaceDataLock) {
960 final SurfaceData oldData = getSurfaceData();
961 surfaceData = platformWindow.replaceSurfaceData();
962 // TODO: volatile image
963 // VolatileImage oldBB = backBuffer;
964 BufferedImage oldBB = backBuffer;
965 backBufferCount = newBackBufferCount;
966 backBufferCaps = newBackBufferCaps;
967 final Rectangle size = getSize();
968 if (getSurfaceData() != null && oldData != getSurfaceData()) {
969 clearBackground(size.width, size.height);
970 }
971
972 if (blit) {
973 blitSurfaceData(oldData, getSurfaceData());
974 }
975
976 if (oldData != null && oldData != getSurfaceData()) {
977 // TODO: drop oldData for D3D/WGL pipelines
978 // This can only happen when this peer is being created
979 oldData.flush();
980 }
981
982 // TODO: volatile image
983 //backBuffer = (VolatileImage)delegate.createBackBuffer();
984 if (oldBB != null) {
985 backBuffer = (BufferedImage) platformWindow.createBackBuffer();
986 if (backBuffer != null) {
987 Graphics2D g = (Graphics2D) backBuffer.getGraphics();
988 try {
989 Rectangle r = getBounds();
990 g.setBackground(nonOpaqueBackground);
991 g.clearRect(0, 0, r.width, r.height);
992 SG2DConstraint((SunGraphics2D) g, getRegion());
993 if (oldBB != null) {
994 // Draw the old back buffer to the new one
995 g.drawImage(oldBB, 0, 0, null);
996 oldBB.flush();
997 }
998 } finally {
999 g.dispose();
1000 }
1001 }
1002 }
1003 }
1004 }
1005
1006 private void blitSurfaceData(final SurfaceData src, final SurfaceData dst) {
1007 //TODO blit. proof-of-concept
1008 if (src != dst && src != null && dst != null
1009 && !(dst instanceof NullSurfaceData)
1010 && !(src instanceof NullSurfaceData)
1011 && src.getSurfaceType().equals(dst.getSurfaceType())) {
1012 final Rectangle size = getSize();
1013 final Blit blit = Blit.locate(src.getSurfaceType(),
1014 CompositeType.Src,
1015 dst.getSurfaceType());
1016 if (blit != null) {
1017 blit.Blit(src, dst, ((Graphics2D) getGraphics()).getComposite(),
1018 getRegion(), 0, 0, 0, 0, size.width, size.height);
1019 }
1020 }
|