]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/awt/SWT_AWT.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / awt / SWT_AWT.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.awt;
15
16 /* AWT Imports */
17 import java.awt.*;
18 import java.awt.Canvas;
19 import java.awt.event.*;
20 import java.lang.reflect.*;
21
22 /* SWT Imports */
23 import org.eclipse.swt.*;
24 import org.eclipse.swt.graphics.Point;
25 import org.eclipse.swt.graphics.Rectangle;
26 import org.eclipse.swt.internal.*;
27 import org.eclipse.swt.internal.win32.*;
28 import org.eclipse.swt.widgets.*;
29 import org.eclipse.swt.widgets.Composite;
30
31 /**
32  * This class provides a bridge between SWT and AWT, so that it
33  * is possible to embed AWT components in SWT and vice versa.
34  *
35  * @see <a href="http://www.eclipse.org/swt/snippets/#awt">Swing/AWT snippets</a>
36  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
37  *
38  * @since 3.0
39  */
40 public class SWT_AWT {
41
42         /**
43          * The name of the embedded Frame class. The default class name
44          * for the platform will be used if <code>null</code>.
45          */
46         public static String embeddedFrameClass;
47
48         /**
49          * Key for looking up the embedded frame for a Composite using
50          * getData().
51          */
52         static String EMBEDDED_FRAME_KEY = "org.eclipse.swt.awt.SWT_AWT.embeddedFrame";
53
54 static boolean loaded, swingInitialized;
55
56 static native final long getAWTHandle (Canvas canvas);
57 static native final Object initFrame (long handle, String className);
58 static native final void synthesizeWindowActivation (Frame frame, boolean doActivate);
59
60 static synchronized void loadLibrary () {
61         if (loaded) return;
62         loaded = true;
63         Toolkit.getDefaultToolkit();
64         /*
65         * Note that the jawt library is loaded explicitly
66         * because it cannot be found by the library loader.
67         * All exceptions are caught because the library may
68         * have been loaded already.
69         */
70         try {
71                 System.loadLibrary("jawt");
72         } catch (Throwable e) {}
73         Library.loadLibrary("swt-awt");
74 }
75
76 static synchronized void initializeSwing() {
77         if (swingInitialized) return;
78         swingInitialized = true;
79         try {
80                 /* Initialize the default focus traversal policy */
81                 Class<?> clazz = Class.forName("javax.swing.UIManager");
82                 Method method = clazz.getMethod("getDefaults");
83                 if (method != null) method.invoke(clazz);
84         } catch (Throwable e) {}
85 }
86
87 /**
88  * Returns a <code>java.awt.Frame</code> which is the embedded frame
89  * associated with the specified composite.
90  *
91  * @param parent the parent <code>Composite</code> of the <code>java.awt.Frame</code>
92  * @return a <code>java.awt.Frame</code> the embedded frame or <code>null</code>.
93  *
94  * @exception IllegalArgumentException <ul>
95  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
96  * </ul>
97  *
98  * @since 3.2
99  */
100 public static Frame getFrame (Composite parent) {
101         if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
102         if ((parent.getStyle () & SWT.EMBEDDED) == 0) return null;
103         return (Frame)parent.getData(EMBEDDED_FRAME_KEY);
104 }
105
106 /**
107  * Creates a new <code>java.awt.Frame</code>. This frame is the root for
108  * the AWT components that will be embedded within the composite. In order
109  * for the embedding to succeed, the composite must have been created
110  * with the SWT.EMBEDDED style.
111  * <p>
112  * IMPORTANT: As of JDK1.5, the embedded frame does not receive mouse events.
113  * When a lightweight component is added as a child of the embedded frame,
114  * the cursor does not change. In order to work around both these problems, it is
115  * strongly recommended that a heavyweight component such as <code>java.awt.Panel</code>
116  * be added to the frame as the root of all components.
117  * </p>
118  *
119  * @param parent the parent <code>Composite</code> of the new <code>java.awt.Frame</code>
120  * @return a <code>java.awt.Frame</code> to be the parent of the embedded AWT components
121  *
122  * @exception IllegalArgumentException <ul>
123  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
124  *    <li>ERROR_INVALID_ARGUMENT - if the parent Composite does not have the SWT.EMBEDDED style</li>
125  * </ul>
126  *
127  * @since 3.0
128  */
129 public static Frame new_Frame (final Composite parent) {
130         if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
131         if ((parent.getStyle () & SWT.EMBEDDED) == 0) {
132                 SWT.error (SWT.ERROR_INVALID_ARGUMENT);
133         }
134         final long handle = parent.handle;
135         final Frame[] result = new Frame[1];
136         final Throwable[] exception = new Throwable[1];
137         Runnable runnable = () -> {
138                 try {
139                         /*
140                          * Some JREs have implemented the embedded frame constructor to take an integer
141                          * and other JREs take a long.  To handle this binary incompatibility, use
142                          * reflection to create the embedded frame.
143                          */
144                         String className = embeddedFrameClass != null ? embeddedFrameClass : "sun.awt.windows.WEmbeddedFrame";
145                         try {
146                                 if (embeddedFrameClass != null) {
147                                         Class.forName(className);
148                                 }
149                                 loadLibrary();
150                         } catch (ClassNotFoundException cne) {
151                                 SWT.error (SWT.ERROR_NOT_IMPLEMENTED, cne);
152                         } catch (Throwable e) {
153                                 exception[0] = e;
154                                 return;
155                         }
156                         initializeSwing ();
157                         Object value = initFrame(handle, className);
158                         if (value == null || !(value instanceof Frame)) {
159                                 exception [0] = new Throwable("[Error while creating AWT embedded frame]");
160                                 SWT.error (SWT.ERROR_UNSPECIFIED, exception[0]);
161                                 return;
162                         }
163                         result[0] = (Frame) value;
164                 } finally {
165                         synchronized(result) {
166                                 result.notify();
167                         }
168                 }
169         };
170         if (EventQueue.isDispatchThread() || parent.getDisplay().getSyncThread() != null) {
171                 runnable.run();
172         } else {
173                 EventQueue.invokeLater(runnable);
174                 OS.ReplyMessage(0);
175                 boolean interrupted = false;
176                 MSG msg = new MSG ();
177                 int flags = OS.PM_NOREMOVE | OS.PM_NOYIELD | OS.PM_QS_SENDMESSAGE;
178                 while (result[0] == null && exception[0] == null) {
179                         OS.PeekMessage (msg, 0, 0, 0, flags);
180                         try {
181                                 synchronized (result) {
182                                         result.wait(50);
183                                 }
184                         } catch (InterruptedException e) {
185                                 interrupted = true;
186                         }
187                 }
188                 if (interrupted) {
189                         Thread.currentThread().interrupt();
190                 }
191         }
192         if (exception[0] != null) {
193                 SWT.error (SWT.ERROR_NOT_IMPLEMENTED, exception[0]);
194         }
195         final Frame frame = result[0];
196
197         parent.setData(EMBEDDED_FRAME_KEY, frame);
198
199         /* Forward the iconify and deiconify events */
200         final Listener shellListener = e -> {
201                 switch (e.type) {
202                         case SWT.Deiconify:
203                                 EventQueue.invokeLater(() -> frame.dispatchEvent (new WindowEvent (frame, WindowEvent.WINDOW_DEICONIFIED)));
204                                 break;
205                         case SWT.Iconify:
206                                 EventQueue.invokeLater(() -> frame.dispatchEvent (new WindowEvent (frame, WindowEvent.WINDOW_ICONIFIED)));
207                                 break;
208                 }
209         };
210         Shell shell = parent.getShell ();
211         shell.addListener (SWT.Deiconify, shellListener);
212         shell.addListener (SWT.Iconify, shellListener);
213
214         /*
215         * Generate the appropriate events to activate and deactivate
216         * the embedded frame. This is needed in order to make keyboard
217         * focus work properly for lightweights.
218         */
219         Listener listener = e -> {
220                 switch (e.type) {
221                         case SWT.Dispose:
222                                 Shell shell1 = parent.getShell ();
223                                 shell1.removeListener (SWT.Deiconify, shellListener);
224                                 shell1.removeListener (SWT.Iconify, shellListener);
225                                 parent.setVisible(false);
226                                 EventQueue.invokeLater(() -> {
227                                         try {
228                                                 frame.dispose ();
229                                         } catch (Throwable e1) {}
230                                 });
231                                 break;
232                         case SWT.FocusIn:
233                         case SWT.Activate:
234                                 EventQueue.invokeLater(() -> {
235                                         if (frame.isActive()) return;
236                                         try {
237                                                 Class<?> clazz = frame.getClass();
238                                                 Method method = clazz.getMethod("synthesizeWindowActivation", boolean.class);
239                                                 if (method != null) method.invoke(frame, Boolean.TRUE);
240                                         } catch (Throwable e1) {}
241                                 });
242                                 break;
243                         case SWT.Deactivate:
244                                 EventQueue.invokeLater(() -> {
245                                         if (!frame.isActive()) return;
246                                         try {
247                                                 Class<?> clazz = frame.getClass();
248                                                 Method method = clazz.getMethod("synthesizeWindowActivation", boolean.class);
249                                                 if (method != null) method.invoke(frame, Boolean.FALSE);
250                                         } catch (Throwable e1) {}
251                                 });
252                                 break;
253                 }
254         };
255         parent.addListener (SWT.FocusIn, listener);
256         parent.addListener (SWT.Deactivate, listener);
257         parent.addListener (SWT.Dispose, listener);
258
259         parent.getDisplay().asyncExec(() -> {
260                 if (parent.isDisposed()) return;
261                 final Rectangle clientArea = DPIUtil.autoScaleUp(parent.getClientArea()); // To Pixels
262                 EventQueue.invokeLater(() -> {
263                         frame.setSize (clientArea.width, clientArea.height);
264                         frame.validate ();
265                 });
266         });
267         return frame;
268 }
269
270 /**
271  * Creates a new <code>Shell</code>. This Shell is the root for
272  * the SWT widgets that will be embedded within the AWT canvas.
273  *
274  * @param display the display for the new Shell
275  * @param parent the parent <code>java.awt.Canvas</code> of the new Shell
276  * @return a <code>Shell</code> to be the parent of the embedded SWT widgets
277  *
278  * @exception IllegalArgumentException <ul>
279  *    <li>ERROR_NULL_ARGUMENT - if the display is null</li>
280  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
281  *    <li>ERROR_INVALID_ARGUMENT - if the parent's peer is not created</li>
282  * </ul>
283  *
284  * @since 3.0
285  */
286 public static Shell new_Shell (final Display display, final Canvas parent) {
287         if (display == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
288         if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
289         long handle = 0;
290         try {
291                 loadLibrary ();
292                 handle = getAWTHandle (parent);
293         } catch (Throwable e) {
294                 SWT.error (SWT.ERROR_NOT_IMPLEMENTED, e);
295         }
296         if (handle == 0) SWT.error (SWT.ERROR_INVALID_ARGUMENT, null, " [peer not created]");
297
298         final Shell shell = Shell.win32_new (display, handle);
299         final ComponentListener listener = new ComponentAdapter () {
300                 @Override
301                 public void componentResized (ComponentEvent e) {
302                         display.syncExec (() -> {
303                                 if (shell.isDisposed()) return;
304                                 Dimension dim = parent.getSize ();
305                                 shell.setSize(DPIUtil.autoScaleDown(new Point(dim.width, dim.height))); // To Points
306                         });
307                 }
308         };
309         parent.addComponentListener(listener);
310         shell.addListener(SWT.Dispose, event -> parent.removeComponentListener(listener));
311         shell.setVisible (true);
312         return shell;
313 }
314 }