summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2010-07-08 07:44:30 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2010-07-08 07:44:30 +0200
commit3d75736bb30623c5858fec33ad8c0a3419d35c52 (patch)
tree766f0f5b7db7f175b5578d8c4c79798119d04d3d
Replicate the repo...HEADmaster
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QComponentHost.java149
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QWidgetHost.java128
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java69
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java18
-rw-r--r--com/trolltech/research/qtjambiawtbridge/RedirectContainer.java104
-rw-r--r--com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java67
-rw-r--r--com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java88
-rw-r--r--generatorstep.bat1
-rw-r--r--generatorstep.sh1
-rw-r--r--global.h5
-rw-r--r--pregenerated/qtjambiawtbridge.jarbin0 -> 33912 bytes
-rw-r--r--pregenerated/win32-msvc2005/com_trolltech_research_qtjambiawtbridge_generated.dllbin0 -> 77824 bytes
-rw-r--r--qawt.pro42
-rw-r--r--qcomponenthostnative.cpp47
-rw-r--r--qcomponenthostnative.h33
-rw-r--r--qtjambiawtbridge.cpp54
-rw-r--r--qtwinmigrate/qmfcapp.cpp392
-rw-r--r--qtwinmigrate/qmfcapp.h58
-rw-r--r--qtwinmigrate/qtwinmigrate.pri8
-rw-r--r--qtwinmigrate/qwinhost.cpp308
-rw-r--r--qtwinmigrate/qwinhost.h57
-rw-r--r--qtwinmigrate/qwinwidget.cpp331
-rw-r--r--qtwinmigrate/qwinwidget.h64
-rw-r--r--qwidgethostnative.cpp104
-rw-r--r--qwidgethostnative.h34
-rw-r--r--typesystem_qawt.xml14
26 files changed, 2176 insertions, 0 deletions
diff --git a/com/trolltech/research/qtjambiawtbridge/QComponentHost.java b/com/trolltech/research/qtjambiawtbridge/QComponentHost.java
new file mode 100644
index 0000000..9da0640
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QComponentHost.java
@@ -0,0 +1,149 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.research.qtjambiawtbridge.generated.QComponentHostNative;
+import com.trolltech.qt.gui.*;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.core.QEvent;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class QComponentHost extends QComponentHostNative {
+ static {
+ Toolkit.getDefaultToolkit();
+ javax.swing.UIManager.getDefaults();
+ }
+
+ private Component component;
+ private Frame container;
+ public QComponentHost(final Component hostedComponent, QWidget parent) {
+ super(parent);
+ component = hostedComponent;
+ setFocusPolicy(Qt.FocusPolicy.TabFocus);
+ }
+
+ @Override
+ public void resizeEvent(QResizeEvent e) {
+ if (container == null)
+ return;
+ container.setBounds(0, 0, e.size().width(), e.size().height());
+ }
+
+ @Override
+ public boolean event(QEvent e) {
+ return super.event(e);
+ }
+
+ @Override
+ protected void focusInEvent(QFocusEvent e) {
+ final boolean backwards = (e.reason() == Qt.FocusReason.BacktabFocusReason);
+
+ if (!backwards && e.reason() != Qt.FocusReason.TabFocusReason)
+ return;
+
+ try {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ focusAwt(backwards);
+ }
+ });
+ } catch (Exception f) {
+ f.printStackTrace();
+ }
+ }
+
+ @Override
+ public void showEvent(QShowEvent e) {
+ // By trial and error, the only way to get the window handle is
+ // to put the component inside a Frame (which gets a window handle)
+ // and retrieving this in the paint method. Also, we need to make
+ // sure the Qt window is visible (if you attach prior to this
+ // then showing the window will hang indefinitely) hence we do
+ // this in the showEvent
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ container = RedirectContainer.embedComponent(QComponentHost.this, component);
+ container.setVisible(true);
+ }
+ });
+ } catch (Throwable f) { f.printStackTrace(); }
+ }
+
+ public QComponentHost(Component hostedComponent) {
+ this(hostedComponent, null);
+ }
+
+ @Override
+ protected void closeEvent(QCloseEvent e) {
+ container.setVisible(false);
+ }
+
+ @Override
+ public QSize minimumSizeHint() {
+ if (container == null)
+ return new QSize();
+
+ Dimension dim = container.getMinimumSize();
+ return new QSize(dim.width, dim.height);
+ }
+
+ @Override
+ public QSize sizeHint() {
+ if (container == null)
+ return new QSize();
+
+ Dimension d = component.getPreferredSize();
+ return new QSize((int) d.getWidth(), (int) d.getHeight());
+ }
+
+ private void setFocusInQt(QWidget w, Qt.FocusReason reason) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ w.window().activateWindow();
+ w.setFocus(reason);
+ w.update();
+ }
+
+ private void focusAwt(final boolean backwards) {
+ container.toFront();
+
+ Component c = null;
+ if (component instanceof Container) {
+ c = !backwards
+ ? container.getFocusTraversalPolicy().getFirstComponent((Container) component)
+ : container.getFocusTraversalPolicy().getLastComponent((Container) component);
+ } else {
+ c = component;
+ }
+
+ if (c != null)
+ c.requestFocus();
+
+ }
+
+
+ void focusQt(final boolean backwards) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ QWidget startWidget = backwards ? QtJambiAwtBridge.previousInFocusChain(QComponentHost.this)
+ : nextInFocusChain();
+ QWidget w = startWidget;
+ while (w.focusPolicy() != Qt.FocusPolicy.TabFocus
+ && w.focusPolicy() != Qt.FocusPolicy.StrongFocus) {
+ w = backwards ? QtJambiAwtBridge.previousInFocusChain(w) : w.nextInFocusChain();
+
+ if (w == startWidget)
+ break;
+ }
+
+ if (w.focusPolicy() == Qt.FocusPolicy.TabFocus
+ || w.focusPolicy() == Qt.FocusPolicy.StrongFocus) {
+ w.window().setAttribute(Qt.WidgetAttribute.WA_KeyboardFocusChange, true);
+ setFocusInQt(w, backwards ? Qt.FocusReason.BacktabFocusReason : Qt.FocusReason.TabFocusReason);
+ }
+ }
+ });
+ }
+
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/QWidgetHost.java b/com/trolltech/research/qtjambiawtbridge/QWidgetHost.java
new file mode 100644
index 0000000..421fdb7
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QWidgetHost.java
@@ -0,0 +1,128 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import java.awt.*;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QWidget;
+
+public class QWidgetHost extends Canvas {
+ private static final long serialVersionUID = 1L;
+
+ private void focusQt(final boolean backwards) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ QWidget startWidget = backwards ? QtJambiAwtBridge.previousInFocusChain(QWidgetHost.this.containedWidget)
+ : QWidgetHost.this.containedWidget.nextInFocusChain();
+ QWidget w = startWidget;
+ while (w.focusPolicy() != Qt.FocusPolicy.TabFocus
+ && w.focusPolicy() != Qt.FocusPolicy.StrongFocus) {
+ w = backwards ? QtJambiAwtBridge.previousInFocusChain(w) : w.nextInFocusChain();
+
+ if (w == startWidget)
+ break;
+ }
+
+ if (w.focusPolicy() == Qt.FocusPolicy.TabFocus
+ || w.focusPolicy() == Qt.FocusPolicy.StrongFocus) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ w.window().activateWindow();
+ w.window().setAttribute(Qt.WidgetAttribute.WA_KeyboardFocusChange, true);
+ w.setFocus(backwards ? Qt.FocusReason.BacktabFocusReason : Qt.FocusReason.TabFocusReason);
+ w.update();
+ }
+ }
+ });
+ }
+
+ /**
+ * Constructs a binding layer between AWT and a QWidget.
+ *
+ * @param containedWidget This widget will become a child of the QWidgetHost on the first AWT paint event.
+ */
+ public QWidgetHost(QWidget containedWidget) {
+ QApplication.setQuitOnLastWindowClosed(false);
+ setFocusable(true);
+
+ childWidget = containedWidget;
+ sizeHint = new QSize();
+ minimumSizeHint = new QSize();
+
+ addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ if (e.getOppositeComponent() == null) {
+ return ;
+ }
+
+ Container focusCycleRoot = getFocusCycleRootAncestor();
+ boolean backwards = (e.getOppositeComponent() == focusCycleRoot.getFocusTraversalPolicy().getComponentAfter(focusCycleRoot, QWidgetHost.this));
+ focusQt(backwards);
+ }
+
+ });
+ }
+
+ private QWidget childWidget;
+ private QWidgetWrapper containedWidget;
+
+ @Override
+ public void paint(Graphics g) {
+ if (containedWidget == null) {
+ setVisible(false);
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ containedWidget = new QWidgetWrapper(childWidget, QWidgetHost.this);
+ sizeHint = containedWidget.sizeHint();
+ minimumSizeHint = containedWidget.minimumSizeHint();
+ }
+ });
+ setVisible(true);
+ }
+
+ super.paint(g);
+ }
+
+ @Override
+ public void setBounds(final int x, final int y, final int width, final int height) {
+ if (containedWidget != null) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ containedWidget.move(0, 0);
+ containedWidget.resize(width, height);
+ }
+ });
+ }
+
+ super.setBounds(x, y, width, height);
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ if (containedWidget != null) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ sizeHint = containedWidget.sizeHint();
+ }
+ });
+ }
+ return new Dimension(sizeHint.width(), sizeHint.height());
+ }
+ QSize sizeHint;
+
+ @Override
+ public Dimension getMinimumSize() {
+ if (containedWidget != null) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ minimumSizeHint = containedWidget.minimumSizeHint();
+ }
+ });
+ }
+ return new Dimension(minimumSizeHint.width(), minimumSizeHint.height());
+ }
+ private QSize minimumSizeHint;
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java b/com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java
new file mode 100644
index 0000000..9bcd82d
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java
@@ -0,0 +1,69 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.research.qtjambiawtbridge.generated.QWidgetHostNative;
+import com.trolltech.qt.gui.*;
+import com.trolltech.qt.core.Qt;
+
+import javax.swing.*;
+import java.awt.*;
+
+class QWidgetWrapper extends QWidgetHostNative {
+ private QWidgetHost host;
+
+ public QWidgetWrapper(QWidget child, QWidgetHost host) {
+ super(host);
+
+ // Call this to make sure the widget is connected to a native window
+ winId();
+
+ this.host = host;
+ child.setParent(this);
+
+ // Make sure widget fills entire parent rect
+ QHBoxLayout layout = new QHBoxLayout(this);
+ layout.setMargin(0);
+ layout.setContentsMargins(0, 0, 0, 0);
+ layout.setSpacing(0);
+ layout.addWidget(child);
+
+ setFocusPolicy(Qt.FocusPolicy.TabFocus);
+ setVisible(true);
+ }
+
+ @Override
+ public void closeEvent(QCloseEvent e) {
+ e.setAccepted(false);
+ }
+
+ private void focusAwt(final boolean backwards) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ Container c = host.getFocusCycleRootAncestor();
+
+ if (c != null) {
+ host.requestFocus();
+ Component component = backwards
+ ? c.getFocusTraversalPolicy().getComponentBefore(c, host)
+ : c.getFocusTraversalPolicy().getComponentAfter(c, host);
+
+ component.requestFocus();
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void showEvent(QShowEvent e) {
+ move(0, 0);
+ resize(host.getBounds().width, host.getBounds().height);
+ }
+
+ @Override
+ protected synchronized void focusInEvent(QFocusEvent event) {
+ if (event.reason() == Qt.FocusReason.BacktabFocusReason) {
+ focusAwt(true);
+ } else if (event.reason() == Qt.FocusReason.TabFocusReason) {
+ focusAwt(false);
+ }
+ }
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java b/com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java
new file mode 100644
index 0000000..943f8ff
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java
@@ -0,0 +1,18 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.qt.gui.QWidget;
+
+import java.awt.*;
+
+class QtJambiAwtBridge {
+ public static QWidget previousInFocusChain(QWidget w ) {
+ QWidget prev = null, next = w.nextInFocusChain();
+ while (next != w) {
+ prev = next;
+ next = next.nextInFocusChain();
+ }
+ return prev;
+ }
+
+ static native Frame getEmbeddedFrame(long widgetNativeId);
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/RedirectContainer.java b/com/trolltech/research/qtjambiawtbridge/RedirectContainer.java
new file mode 100644
index 0000000..424c955
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/RedirectContainer.java
@@ -0,0 +1,104 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QApplication;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+
+// sun.awt.x11.embeddedFrame on Linux
+// see text file for osx info
+class RedirectContainer {
+
+ private static class FocusComponent extends Component {
+ private static final long serialVersionUID = 1L;
+ private QComponentHost host;
+
+ public FocusComponent(final boolean isFocusIn, final QComponentHost host) {
+ this.host = host;
+
+ setFocusable(true);
+ setBounds(0, 0, 1, 1);
+
+ addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+
+ if (e.getOppositeComponent() == null) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ return ;
+ }
+
+ if (isFocusIn) {
+ host.focusQt(true);
+ } else {
+ host.focusQt(false);
+ }
+ }
+
+ });
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(1, 1);
+ }
+
+ @Override
+ public Dimension getMaximumSize() {
+ return new Dimension(1, 1);
+ }
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ static Frame embedComponent(QComponentHost parent, Component component) {
+ Frame f = QtJambiAwtBridge.getEmbeddedFrame(parent.nativeId());
+ if (f != null) {
+ // Connect the frame to its window handle, since it's no longer
+ // handled by Swing (for event processing)
+ f.addNotify();
+
+ GridBagLayout layout = new GridBagLayout();
+
+ f.setLayout(layout);
+ f.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
+ f.setFocusTraversalPolicyProvider(true);
+
+ GridBagConstraints focusConstraints = new GridBagConstraints();
+ focusConstraints.ipadx = 0;
+ focusConstraints.ipady = 0;
+ focusConstraints.anchor = GridBagConstraints.CENTER;
+ focusConstraints.fill = GridBagConstraints.NONE;
+ focusConstraints.insets.left = 0;
+ focusConstraints.insets.right = 0;
+ focusConstraints.insets.bottom = 0;
+ focusConstraints.insets.top = 0;
+
+ FocusComponent focusIn = new FocusComponent(true, parent);
+
+ layout.setConstraints(focusIn, focusConstraints);
+ f.add(focusIn);
+
+ {
+ GridBagConstraints constraints = (GridBagConstraints) focusConstraints.clone();
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.weightx = 1;
+ constraints.weighty = 1;
+
+ f.add(component);
+ }
+
+ FocusComponent focusOut = new FocusComponent(false, parent);
+ layout.setConstraints(focusOut, focusConstraints);
+ f.add(focusOut);
+
+ f.pack();
+ }
+
+ return f;
+ }
+
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java b/com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java
new file mode 100644
index 0000000..6a2f2eb
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java
@@ -0,0 +1,67 @@
+package com.trolltech.research.qtjambiawtbridge.examples;
+
+import com.trolltech.qt.gui.*;
+import com.trolltech.research.qtjambiawtbridge.QComponentHost;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class AwtInQt extends QWidget {
+
+ public AwtInQt() {
+ QGridLayout layout = new QGridLayout(this);
+
+ // A few Qt widgets
+ layout.addWidget(new QLabel("First name:"), 0, 0);
+ layout.addWidget(new QLineEdit(), 0, 1);
+ layout.addWidget(new QLabel("Last name:"), 1, 0);
+ layout.addWidget(new QLineEdit(), 1, 1);
+
+ // The AWT part of the GUI
+ {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new GridLayout(1, 2));
+
+ panel.add(new JLabel("Social security number:"));
+ panel.add(new JTextField());
+
+ // Add the AWT panel to Qt's layout
+ layout.addWidget(new QComponentHost(panel), 2, 0, 1, 2);
+ }
+
+ {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new GridLayout(2, 4));
+
+ panel.add(new JLabel("Phone number:"));
+ panel.add(new JTextField());
+
+ panel.add(new JLabel("Address:"));
+ panel.add(new JTextField());
+
+ panel.add(new JLabel("Credit card #:"));
+ panel.add(new JTextField());
+
+ panel.add(new JLabel("Expiration date:"));
+ panel.add(new JTextField());
+
+ // Add the AWT panel to Qt's layout
+ layout.addWidget(new QComponentHost(panel), 4, 0, 1, 2);
+ }
+
+ }
+
+ public static void main(String[] args) {
+ QApplication.initialize(args);
+
+ AwtInQt awtInQt = new AwtInQt();
+ awtInQt.show();
+
+ QApplication.exec();
+
+ System.exit(0);
+ }
+
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java b/com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java
new file mode 100644
index 0000000..bef356e
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java
@@ -0,0 +1,88 @@
+package com.trolltech.research.qtjambiawtbridge.examples;
+
+import java.awt.GridLayout;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QGridLayout;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QLineEdit;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.research.qtjambiawtbridge.QWidgetHost;
+
+public class QtInAwt extends JFrame {
+
+ private static final long serialVersionUID = 1L;
+
+ public QtInAwt() {
+ setLayout(new GridLayout(4, 1));
+
+ {
+ JPanel row = new JPanel();
+ row.setLayout(new GridLayout(1, 2));
+ row.add(new JLabel("First name:"));
+ row.add(new JTextField());
+
+ add(row);
+ }
+
+ {
+ JPanel row = new JPanel();
+ row.setLayout(new GridLayout(1, 2));
+ row.add(new JLabel("Last name:"));
+ row.add(new JTextField());
+
+ add(row);
+ }
+
+ // The Qt part of the GUI
+ {
+ QWidget row = new QWidget();
+ QGridLayout layout = new QGridLayout(row);
+ layout.addWidget(new QLabel("Social security number:"), 0, 0);
+ layout.addWidget(new QLineEdit(), 0, 1);
+
+ // Add the Qt widget to AWT's layout
+ add(new QWidgetHost(row));
+ }
+
+ {
+ QWidget row = new QWidget();
+ QGridLayout layout = new QGridLayout(row);
+ layout.addWidget(new QLabel("Phone number:"), 0, 0);
+ layout.addWidget(new QLineEdit(), 0, 1);
+
+ layout.addWidget(new QLabel("Address:"), 1, 0);
+ layout.addWidget(new QLineEdit(), 1, 1);
+
+ layout.addWidget(new QLabel("Credit card #:"), 0, 2);
+ layout.addWidget(new QLineEdit(), 0, 3);
+
+ layout.addWidget(new QLabel("Expiration date:"), 1, 2);
+ layout.addWidget(new QLineEdit(), 1, 3);
+
+ // Add the Qt widget to AWT's layout
+ add(new QWidgetHost(row));
+ }
+
+ }
+
+ public static void main(String args[]) {
+ // We have to initialize Qt Jambi in order to use its widgets
+ QApplication.initialize(args);
+
+ QtInAwt qtInAwt = new QtInAwt();
+ qtInAwt.setVisible(true);
+ qtInAwt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ qtInAwt.setSize(640, 480);
+
+ // We need to run a Qt Jambi event loop in this thread in order
+ // for its widgets to receive events
+ QApplication.exec();
+ }
+
+}
diff --git a/generatorstep.bat b/generatorstep.bat
new file mode 100644
index 0000000..75cd96c
--- /dev/null
+++ b/generatorstep.bat
@@ -0,0 +1 @@
+%JAMBIDIR%\generator\release\generator --include-paths=%CD%\qtwinmigrate global.h typesystem_qawt.xml
diff --git a/generatorstep.sh b/generatorstep.sh
new file mode 100644
index 0000000..533fc94
--- /dev/null
+++ b/generatorstep.sh
@@ -0,0 +1 @@
+$JAMBIDIR/generator/generator global.h typesystem_qawt.xml
diff --git a/global.h b/global.h
new file mode 100644
index 0000000..7ec5a4c
--- /dev/null
+++ b/global.h
@@ -0,0 +1,5 @@
+#include <QtCore>
+#include <QtGui>
+
+#include "qcomponenthostnative.h"
+#include "qwidgethostnative.h"
diff --git a/pregenerated/qtjambiawtbridge.jar b/pregenerated/qtjambiawtbridge.jar
new file mode 100644
index 0000000..79dbf10
--- /dev/null
+++ b/pregenerated/qtjambiawtbridge.jar
Binary files differ
diff --git a/pregenerated/win32-msvc2005/com_trolltech_research_qtjambiawtbridge_generated.dll b/pregenerated/win32-msvc2005/com_trolltech_research_qtjambiawtbridge_generated.dll
new file mode 100644
index 0000000..79592b0
--- /dev/null
+++ b/pregenerated/win32-msvc2005/com_trolltech_research_qtjambiawtbridge_generated.dll
Binary files differ
diff --git a/qawt.pro b/qawt.pro
new file mode 100644
index 0000000..138bb55
--- /dev/null
+++ b/qawt.pro
@@ -0,0 +1,42 @@
+!exists($(JAVADIR)) {
+ error("Please set your JAVADIR environment variable to point to your local JDK..") ;
+}
+
+TARGET = com_trolltech_research_qtjambiawtbridge_generated
+
+
+QTJAMBI_LOCATION_TMP=$$(JAMBIDIR)
+isEmpty(QTJAMBI_LOCATION_TMP) {
+ error("Please specify the JAMBIDIR environment variable.");
+}
+
+!exists($$(JAMBIDIR)/qtjambi/qtjambi_include.pri) {
+ error("$JAMBIDIR/qtjambi/qtjambi_include.pri was not found!");
+}
+
+
+
+SOURCES += qtjambiawtbridge.cpp qwidgethostnative.cpp qcomponenthostnative.cpp
+HEADERS += qwidgethostnative.h qcomponenthostnative.h
+
+include($$(JAMBIDIR)/qtjambi/qtjambi_include.pri)
+include(cpp/com_trolltech_research_qtjambiawtbridge_generated/com_trolltech_research_qtjambiawtbridge_generated.pri)
+
+
+
+DESTDIR = ./lib
+DLLDESTDIR= ./bin
+
+win*{
+ INCLUDEPATH += $$PWD/qtwinmigrate
+ LIBS += "$$(JAVADIR)/lib/jawt.lib"
+ include(qtwinmigrate/qtwinmigrate.pri)
+} else {
+ INCLUDEPATH += $$PWD/linux
+ LIBPATH += $$JAVADIR/lib
+ LIBS += -ljawt
+}
+
+win32: LIBS += -lgdi32 -luser32
+
+LIBPATH += $$(JAVADIR)/jre/lib/i386
diff --git a/qcomponenthostnative.cpp b/qcomponenthostnative.cpp
new file mode 100644
index 0000000..5b471d3
--- /dev/null
+++ b/qcomponenthostnative.cpp
@@ -0,0 +1,47 @@
+#include "qcomponenthostnative.h"
+
+QComponentHostNative::QComponentHostNative(QWidget *parent)
+ : QCOMPONENTHOSTNATIVE_BASECLASS(parent)
+{
+}
+
+// ### Empty implementations to work around limitation in generator
+void QComponentHostNative::childEvent(QChildEvent *e)
+{
+ QCOMPONENTHOSTNATIVE_BASECLASS::childEvent(e);
+}
+
+bool QComponentHostNative::eventFilter(QObject *o, QEvent *e)
+{
+ return QCOMPONENTHOSTNATIVE_BASECLASS::eventFilter(o, e);
+}
+
+void QComponentHostNative::focusInEvent(QFocusEvent *e)
+{
+ QCOMPONENTHOSTNATIVE_BASECLASS::focusInEvent(e);
+}
+
+void QComponentHostNative::paintEvent(QPaintEvent *e)
+{
+ QCOMPONENTHOSTNATIVE_BASECLASS::paintEvent(e);
+}
+
+void QComponentHostNative::resizeEvent(QResizeEvent *e)
+{
+ QCOMPONENTHOSTNATIVE_BASECLASS::resizeEvent(e);
+}
+
+void QComponentHostNative::showEvent(QShowEvent *e)
+{
+ QCOMPONENTHOSTNATIVE_BASECLASS::showEvent(e);
+}
+
+void QComponentHostNative::hideEvent(QHideEvent *e)
+{
+ QCOMPONENTHOSTNATIVE_BASECLASS::hideEvent(e);
+}
+
+bool QComponentHostNative::event(QEvent *e)
+{
+ return QCOMPONENTHOSTNATIVE_BASECLASS::event(e);
+}
diff --git a/qcomponenthostnative.h b/qcomponenthostnative.h
new file mode 100644
index 0000000..c726f5b
--- /dev/null
+++ b/qcomponenthostnative.h
@@ -0,0 +1,33 @@
+#ifndef QCOMPONENTHOSTNATIVE_H
+#define QCOMPONENTHOSTNATIVE_H
+
+#include <QtGui>
+
+#if defined(QT_JAMBI_RUN)
+# define QCOMPONENTHOSTNATIVE_BASECLASS QWidget
+#elif defined(Q_OS_WIN32)
+# include "qwinhost.h"
+# define QCOMPONENTHOSTNATIVE_BASECLASS QWinHost
+#else
+# include <QtGui/QX11EmbedContainer>
+# define QCOMPONENTHOSTNATIVE_BASECLASS QX11EmbedContainer
+#endif
+
+class QComponentHostNative: public QCOMPONENTHOSTNATIVE_BASECLASS
+{
+public:
+ QComponentHostNative(QWidget *parent = 0);
+
+protected:
+ void childEvent(QChildEvent *e);
+ bool eventFilter(QObject *o, QEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ void paintEvent(QPaintEvent *e);
+ void resizeEvent(QResizeEvent *e);
+ void showEvent(QShowEvent *e);
+ void hideEvent(QHideEvent *e);
+ bool event(QEvent *e);
+
+};
+
+#endif
diff --git a/qtjambiawtbridge.cpp b/qtjambiawtbridge.cpp
new file mode 100644
index 0000000..3f3bb81
--- /dev/null
+++ b/qtjambiawtbridge.cpp
@@ -0,0 +1,54 @@
+#include <qtjambi_core.h>
+
+#include <QtGui/QWidget>
+
+#include <jni.h>
+
+const char *qtjambi_awt_title = "Qt Jambi / AWT";
+
+extern "C" JNIEXPORT jobject JNICALL Java_com_trolltech_research_qtjambiawtbridge_QtJambiAwtBridge_getEmbeddedFrame
+(JNIEnv *env, jclass, jlong widgetNativeId)
+{
+#ifdef Q_OS_WIN32
+ const char *embeddedFramePackageName = "sun/awt/windows/";
+ const char *embeddedFrameClassName = "WEmbeddedFrame";
+#else
+ const char *embeddedFramePackageName = "sun/awt/X11/";
+ const char *embeddedFrameClassName = "XEmbeddedFrame";
+#endif
+
+ QWidget *widget = reinterpret_cast<QWidget *>(qtjambi_from_jlong(widgetNativeId));
+ if (widget == 0) {
+ qWarning("%s [%s:%d]: Component host widget has been deleted\n", qtjambi_awt_title, __FILE__, __LINE__);
+ return 0;
+ }
+
+ jclass embeddedFrameClass = resolveClass(env, embeddedFrameClassName, embeddedFramePackageName);
+ if (embeddedFrameClass == 0) {
+ qWarning("%s [%s:%d]: Embedded frame class '%s%s' not found\n",
+ qtjambi_awt_title, __FILE__, __LINE__, embeddedFramePackageName, embeddedFrameClassName);
+ return 0;
+ }
+
+ jmethodID constructor = resolveMethod(env, "<init>", "(I)V",
+ embeddedFrameClassName,
+ embeddedFramePackageName);
+ // Different constructors on different JREs.
+ if (constructor == 0) {
+ env->ExceptionClear();
+ constructor = resolveMethod(env, "<init>", "(J)V",
+ embeddedFrameClassName,
+ embeddedFramePackageName);
+ }
+
+ if (constructor == 0) {
+ qWarning("%s [%s:%d]: Cannot find constructor in embedded frame class\n", qtjambi_awt_title, __FILE__, __LINE__);
+ return 0;
+ }
+
+ WId windowId = widget->winId();
+
+ return env->NewObject(embeddedFrameClass, constructor, windowId);
+}
+
+
diff --git a/qtwinmigrate/qmfcapp.cpp b/qtwinmigrate/qmfcapp.cpp
new file mode 100644
index 0000000..79d68f2
--- /dev/null
+++ b/qtwinmigrate/qmfcapp.cpp
@@ -0,0 +1,392 @@
+// Implementation of the QMfcApp classes
+
+#ifdef QT3_SUPPORT
+#undef QT3_SUPPORT
+#endif
+
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#include "qmfcapp.h"
+
+#include <QtCore/QEventLoop>
+#include <QtCore/QAbstractEventDispatcher>
+#include <QtGui/QWidget>
+
+#ifdef QTWINMIGRATE_WITHMFC
+#include <afxwin.h>
+#else
+#include <qt_windows.h>
+#endif
+
+#ifdef QTWINMIGRATE_WITHMFC
+CWinApp *QMfcApp::mfc_app = 0;
+char **QMfcApp::mfc_argv = 0;
+int QMfcApp::mfc_argc = 0;
+#endif
+
+/*! \class QMfcApp qmfcapp.h
+ \brief The QMfcApp class provides merging of the MFC and Qt event loops.
+
+ QMfcApp is responsible for driving both the Qt and MFC event loop.
+ It replaces the standard MFC event loop provided by
+ CWinApp::Run(), and is used instead of the QApplication parent
+ class.
+
+ To replace the MFC event loop reimplement the CWinApp::Run()
+ function in the CWinApp subclass usually created by the MFC
+ Application Wizard, and use either the static run() function, or
+ an instance of QMfcApp created earlier through the static
+ instance() function or the constructor.
+
+ The QMfcApp class also provides a static API pluginInstance() that
+ drives the Qt event loop when loaded into an MFC or Win32 application.
+ This is useful for developing Qt based DLLs or plugins, or if the
+ MFC application's event handling can not be modified.
+*/
+
+static int modalLoopCount = 0;
+
+HHOOK hhook;
+LRESULT CALLBACK QtFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ if (qApp) {
+ // don't process deferred-deletes while in a modal loop
+ if (modalLoopCount)
+ qApp->sendPostedEvents();
+ else
+ qApp->sendPostedEvents(0, -1);
+ }
+
+ return CallNextHookEx(hhook, nCode, wParam, lParam);
+}
+
+/*!
+ Inform Qt that a modal loop is about to be entered, and that DeferredDelete
+ events should not be processed. Call this function before calling Win32
+ or MFC functions that enter a modal event loop (i.e. MessageBox).
+
+ This is only required if the Qt UI code hooks into an existing Win32
+ event loop using QMfcApp::pluginInstance.
+
+ \sa exitModalLoop()
+*/
+void QMfcApp::enterModalLoop()
+{
+ ++modalLoopCount;
+}
+
+/*!
+ Inform Qt that a modal loop has been exited, and that DeferredDelete
+ events should not be processed. Call this function after the blocking
+ Win32 or MFC function (i.e. MessageBox) returned.
+
+ This is only required if the Qt UI code hooks into an existing Win32
+ event loop using QMfcApp::pluginInstance.
+
+ \sa enterModalLoop()
+*/
+void QMfcApp::exitModalLoop()
+{
+ --modalLoopCount;
+ Q_ASSERT(modalLoopCount >= 0);
+}
+
+/*!
+ If there is no global QApplication object (i.e. qApp is null) this
+ function creates a QApplication instance and returns true;
+ otherwise it does nothing and returns false.
+
+ The application installs an event filter that drives the Qt event
+ loop while the MFC or Win32 application continues to own the event
+ loop.
+
+ Use this static function if the application event loop code can not be
+ easily modified, or when developing a plugin or DLL that will be loaded
+ into an existing Win32 or MFC application. If \a plugin is non-null then
+ the function loads the respective DLL explicitly to avoid unloading from
+ memory.
+
+ \code
+ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved)
+ {
+ if (dwReason == DLL_PROCESS_ATTACH)
+ QMfcApp::pluginInstance(hInstance);
+
+ return TRUE;
+ }
+ \endcode
+
+ Set \a plugin to 0 when calling this function from within the same executable
+ module.
+
+ If this function is used, call enterModalLoop and exitModalLoop whenever you
+ call a Win32 or MFC function that opens a local event loop.
+
+ \code
+ void Dialog::someSlot()
+ {
+ QMfcApp::enterModalLoop();
+ MessageBox(...);
+ QMfcApp::exitModalLoop();
+ }
+ \endcode
+*/
+bool QMfcApp::pluginInstance(Qt::HANDLE plugin)
+{
+ if (qApp)
+ return FALSE;
+
+ QT_WA({
+ hhook = SetWindowsHookExW(WH_GETMESSAGE, QtFilterProc, 0, GetCurrentThreadId());
+ }, {
+ hhook = SetWindowsHookExA(WH_GETMESSAGE, QtFilterProc, 0, GetCurrentThreadId());
+ });
+
+ int argc = 0;
+ (void)new QApplication(argc, 0);
+
+ if (plugin) {
+ char filename[256];
+ if (GetModuleFileNameA((HINSTANCE)plugin, filename, 255))
+ LoadLibraryA(filename);
+ }
+
+ return TRUE;
+}
+
+#ifdef QTWINMIGRATE_WITHMFC
+/*!
+ Runs the event loop for both Qt and the MFC application object \a
+ mfcApp, and returns the result. This function calls \c instance()
+ if no QApplication object exists and deletes the object it
+ created.
+
+ Calling this static function in a reimplementation of
+ CWinApp::Run() is the simpliest way to use the QMfcApp class:
+
+ \code
+ int MyMfcApp::Run()
+ {
+ return QMfcApp::run(this);
+ }
+ \endcode
+
+ Since a QApplication object must exist before Qt widgets can be
+ created you cannot use this function if you want to use Qt-based
+ user interface elements in, for example, the InitInstance()
+ function of CWinApp. In such cases, create an instance of
+ QApplication explicitly using instance() or the constructor.
+
+ \sa instance()
+*/
+int QMfcApp::run(CWinApp *mfcApp)
+{
+ bool ownInstance = !qApp;
+ if (ownInstance)
+ instance(mfcApp);
+ int result = qApp->exec();
+
+ if (mfcApp) {
+ int mfcRes = mfcApp->ExitInstance();
+ if (mfcRes && !result)
+ result = mfcRes;
+ }
+
+ if (ownInstance)
+ delete qApp;
+
+ return result;
+}
+
+/*!
+ Creates an instance of QApplication, passing the command line of
+ \a mfcApp to the QApplication constructor, and returns the new
+ object. The returned object must be destroyed by the caller.
+
+ Use this static function if you want to perform additional
+ initializations after creating the application object, or if you
+ want to create Qt GUI elements in the InitInstance()
+ reimplementation of CWinApp:
+
+ \code
+ BOOL MyMfcApp::InitInstance()
+ {
+ // standard MFC initialization
+ // ...
+
+ // This sets the global qApp pointer
+ QMfcApp::instance(this);
+
+ // Qt GUI initialization
+ }
+
+ BOOL MyMfcApp::Run()
+ {
+ int result = QMfcApp::run(this);
+ delete qApp;
+ return result;
+ }
+ \endcode
+
+ \sa run()
+*/
+QApplication *QMfcApp::instance(CWinApp *mfcApp)
+{
+ mfc_app = mfcApp;
+ if (mfc_app) {
+#if defined(UNICODE)
+ QString exeName((QChar*)mfc_app->m_pszExeName, wcslen(mfc_app->m_pszExeName));
+ QString cmdLine((QChar*)mfc_app->m_lpCmdLine, wcslen(mfc_app->m_lpCmdLine));
+#else
+ QString exeName = QString::fromLocal8Bit(mfc_app->m_pszExeName);
+ QString cmdLine = QString::fromLocal8Bit(mfc_app->m_lpCmdLine);
+#endif
+ QStringList arglist = QString(exeName + " " + cmdLine).split(' ');
+
+ mfc_argc = arglist.count();
+ mfc_argv = new char*[mfc_argc+1];
+ int a;
+ for (a = 0; a < mfc_argc; ++a) {
+ QString arg = arglist[a];
+ mfc_argv[a] = new char[arg.length()+1];
+ qstrcpy(mfc_argv[a], arg.toLocal8Bit().data());
+ }
+ mfc_argv[a] = 0;
+ }
+
+ return new QMfcApp(mfcApp, mfc_argc, mfc_argv);
+}
+
+
+static bool qmfc_eventFilter(void *message)
+{
+ long result = 0;
+ return static_cast<QMfcApp*>(qApp)->winEventFilter((MSG*)message, &result);
+}
+
+/*!
+ Creates an instance of QMfcApp. \a mfcApp must point to the
+ existing instance of CWinApp. \a argc and \a argv are passed on
+ to the QApplication constructor.
+
+ Use the static function instance() to automatically use the
+ command line passed to the CWinApp.
+
+ \code
+ QMfcApp *qtApp;
+
+ BOOL MyMfcApp::InitInstance()
+ {
+ // standard MFC initialization
+
+ int argc = ...
+ char **argv = ...
+
+ qtApp = new QMfcApp(this, argc, argv);
+
+ // Qt GUI initialization
+ }
+
+ BOOL MyMfcApp::Run()
+ {
+ int result = qtApp->exec();
+ delete qtApp;
+ qtApp = 0;
+
+ return result;
+ }
+ \endcode
+
+ \sa instance() run()
+*/
+QMfcApp::QMfcApp(CWinApp *mfcApp, int &argc, char **argv)
+: QApplication(argc, argv), idleCount(0), doIdle(FALSE)
+{
+ mfc_app = mfcApp;
+ QAbstractEventDispatcher::instance()->setEventFilter(qmfc_eventFilter);
+ setQuitOnLastWindowClosed(false);
+}
+#endif
+
+/*!
+ Destroys the QMfcApp object, freeing all allocated resources.
+*/
+QMfcApp::~QMfcApp()
+{
+ if (hhook) {
+ UnhookWindowsHookEx(hhook);
+ hhook = 0;
+ }
+
+#ifdef QTWINMIGRATE_WITHMFC
+ for (int a = 0; a < mfc_argc; ++a) {
+ char *arg = mfc_argv[a];
+ delete[] arg;
+ }
+ delete []mfc_argv;
+
+ mfc_argc = 0;
+ mfc_argv = 0;
+ mfc_app = 0;
+#endif
+}
+
+/*!
+ \reimp
+*/
+bool QMfcApp::winEventFilter(MSG *msg, long *result)
+{
+ static bool recursion = false;
+ if (recursion)
+ return false;
+
+ recursion = true;
+
+ QWidget *widget = QWidget::find(msg->hwnd);
+ HWND toplevel = 0;
+ if (widget) {
+ HWND parent = widget->winId();
+ while(parent) {
+ toplevel = parent;
+ parent = GetParent(parent);
+ }
+ HMENU menu = toplevel ? GetMenu(toplevel) : 0;
+ if (menu && GetFocus() == msg->hwnd) {
+ if (msg->message == WM_SYSKEYUP && msg->wParam == VK_MENU) {
+ // activate menubar on Alt-up and move focus away
+ SetFocus(toplevel);
+ SendMessage(toplevel, msg->message, msg->wParam, msg->lParam);
+ widget->setFocus();
+ recursion = false;
+ return TRUE;
+ } else if (msg->message == WM_SYSKEYDOWN && msg->wParam != VK_MENU) {
+ SendMessage(toplevel, msg->message, msg->wParam, msg->lParam);
+ SendMessage(toplevel, WM_SYSKEYUP, VK_MENU, msg->lParam);
+ recursion = false;
+ return TRUE;
+ }
+ }
+ }
+#ifdef QTWINMIGRATE_WITHMFC
+ else if (mfc_app) {
+ MSG tmp;
+ while (doIdle && !PeekMessage(&tmp, 0, 0, 0, PM_NOREMOVE)) {
+ if (!mfc_app->OnIdle(idleCount++))
+ doIdle = FALSE;
+ }
+ if (mfc_app->IsIdleMessage(msg)) {
+ doIdle = TRUE;
+ idleCount = 0;
+ }
+ }
+ if (mfc_app && mfc_app->PreTranslateMessage(msg)) {
+ recursion = false;
+ return TRUE;
+ }
+#endif
+
+ recursion = false;
+ return QApplication::winEventFilter(msg, result);
+}
diff --git a/qtwinmigrate/qmfcapp.h b/qtwinmigrate/qmfcapp.h
new file mode 100644
index 0000000..7a3f5ca
--- /dev/null
+++ b/qtwinmigrate/qmfcapp.h
@@ -0,0 +1,58 @@
+
+// Declaration of the QMfcApp classes
+
+#ifndef QMFCAPP_H
+#define QMFCAPP_H
+
+#include <QtGui/QApplication>
+
+#if defined(_AFXDLL) && defined(_MSC_VER)
+#define QTWINMIGRATE_WITHMFC
+class CWinApp;
+#endif
+
+#if defined(Q_WS_WIN)
+# if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
+# define QT_QTWINMIGRATE_EXPORT
+# elif defined(QT_QTWINMIGRATE_IMPORT)
+# if defined(QT_QTWINMIGRATE_EXPORT)
+# undef QT_QTWINMIGRATE_EXPORT
+# endif
+# define QT_QTWINMIGRATE_EXPORT __declspec(dllimport)
+# elif defined(QT_QTWINMIGRATE_EXPORT)
+# undef QT_QTWINMIGRATE_EXPORT
+# define QT_QTWINMIGRATE_EXPORT __declspec(dllexport)
+# endif
+#else
+# define QT_QTWINMIGRATE_EXPORT
+#endif
+
+class QT_QTWINMIGRATE_EXPORT QMfcApp : public QApplication
+{
+public:
+ static bool pluginInstance(Qt::HANDLE plugin = 0);
+
+#ifdef QTWINMIGRATE_WITHMFC
+ static int run(CWinApp *mfcApp);
+ static QApplication *instance(CWinApp *mfcApp);
+ QMfcApp(CWinApp *mfcApp, int &argc, char **argv);
+#endif
+ ~QMfcApp();
+
+ bool winEventFilter(MSG *msg, long *result);
+
+ static void enterModalLoop();
+ static void exitModalLoop();
+
+private:
+#ifdef QTWINMIGRATE_WITHMFC
+ static char ** mfc_argv;
+ static int mfc_argc;
+ static CWinApp *mfc_app;
+#endif
+
+ int idleCount;
+ bool doIdle;
+};
+
+#endif // QMFCAPP_H
diff --git a/qtwinmigrate/qtwinmigrate.pri b/qtwinmigrate/qtwinmigrate.pri
new file mode 100644
index 0000000..b57a866
--- /dev/null
+++ b/qtwinmigrate/qtwinmigrate.pri
@@ -0,0 +1,8 @@
+HEADERS += $$PWD/qwinhost.h \
+ $$PWD/qwinwidget.h \
+ $$PWD/qmfcapp.h
+
+SOURCES += $$PWD/qwinhost.cpp \
+ $$PWD/qwinwidget.cpp \
+ $$PWD/qmfcapp.cpp
+
diff --git a/qtwinmigrate/qwinhost.cpp b/qtwinmigrate/qwinhost.cpp
new file mode 100644
index 0000000..a8028b9
--- /dev/null
+++ b/qtwinmigrate/qwinhost.cpp
@@ -0,0 +1,308 @@
+// Implementation of the QWinHost classes
+
+#ifdef QT3_SUPPORT
+#undef QT3_SUPPORT
+#endif
+
+#include "qwinhost.h"
+
+#include <QtCore/QEvent>
+#include <qt_windows.h>
+
+/*!
+ \class QWinHost qwinhost.h
+ \brief The QWinHost class provides an API to use native Win32
+ windows in Qt applications.
+
+ QWinHost exists to provide a QWidget that can act as a parent for
+ any native Win32 control. Since QWinHost is a proper QWidget, it
+ can be used as a toplevel widget (e.g. 0 parent) or as a child of
+ any other QWidget.
+
+ QWinHost integrates the native control into the Qt user interface,
+ e.g. handles focus switches and laying out.
+
+ Applications moving to Qt may have custom Win32 controls that will
+ take time to rewrite with Qt. Such applications can use these
+ custom controls as children of QWinHost widgets. This allows the
+ application's user interface to be replaced gradually.
+
+ When the QWinHost is destroyed, and the Win32 window hasn't been
+ set with setWindow(), the window will also be destroyed.
+*/
+
+/*!
+ Creates an instance of QWinHost. \a parent and \a f are
+ passed on to the QWidget constructor. The widget has by default
+ no background.
+
+ \warning You cannot change the parent widget of the QWinHost instance
+ after the native window has been created, i.e. do not call
+ QWidget::setParent or move the QWinHost into a different layout.
+*/
+QWinHost::QWinHost(QWidget *parent, Qt::WFlags f)
+: QWidget(parent, f), wndproc(0),own_hwnd(false), hwnd(0), m_hook(0)
+{
+ setAttribute(Qt::WA_NoBackground);
+ setAttribute(Qt::WA_NoSystemBackground);
+}
+
+/*!
+ Destroys the QWinHost object. If the hosted Win32 window has not
+ been set explicitly using setWindow() the window will be
+ destroyed.
+*/
+QWinHost::~QWinHost()
+{
+ if (wndproc) {
+#if defined(GWLP_WNDPROC)
+ QT_WA({
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
+ },{
+ SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
+ })
+#else
+ QT_WA({
+ SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wndproc);
+ },{
+ SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)wndproc);
+ })
+#endif
+ }
+
+ if (hwnd && own_hwnd)
+ DestroyWindow(hwnd);
+}
+
+/*!
+ Reimplement this virtual function to create and return the native
+ Win32 window. \a parent is the handle to this widget, and \a
+ instance is the handle to the application instance. The returned HWND
+ must be a child of the \a parent HWND.
+
+ The default implementation returns null. The window returned by a
+ reimplementation of this function is owned by this QWinHost
+ instance and will be destroyed in the destructor.
+
+ This function is called by the implementation of polish() if no
+ window has been set explicitly using setWindow(). Call polish() to
+ force this function to be called.
+
+ \sa setWindow()
+*/
+HWND QWinHost::createWindow(HWND parent, HINSTANCE instance)
+{
+ Q_UNUSED(parent);
+ Q_UNUSED(instance);
+ return 0;
+}
+
+/*!
+ Ensures that the window provided a child of this widget, unless
+ it is a WS_OVERLAPPED window.
+*/
+void QWinHost::fixParent()
+{
+ if (!hwnd)
+ return;
+ if (!::IsWindow(hwnd)) {
+ hwnd = 0;
+ return;
+ }
+ if (::GetParent(hwnd) == winId())
+ return;
+ long style = GetWindowLong(hwnd, GWL_STYLE);
+ if (style & WS_OVERLAPPED)
+ return;
+ ::SetParent(hwnd, winId());
+}
+
+/*!
+ Sets the native Win32 window to \a window. If \a window is not a child
+ window of this widget, then it is reparented to become one. If \a window
+ is not a child window (i.e. WS_OVERLAPPED is set), then this function does nothing.
+
+ The lifetime of the window handle will be managed by Windows, QWinHost does not
+ call DestroyWindow. To verify that the handle is destroyed when expected, handle
+ WM_DESTROY in the window procedure.
+
+ \sa window(), createWindow()
+*/
+void QWinHost::setWindow(HWND window)
+{
+ if (hwnd && own_hwnd)
+ DestroyWindow(hwnd);
+
+ hwnd = window;
+ fixParent();
+
+ own_hwnd = false;
+}
+
+/*!
+ Returns the handle to the native Win32 window, or null if no
+ window has been set or created yet.
+
+ \sa setWindow(), createWindow()
+*/
+HWND QWinHost::window() const
+{
+ return hwnd;
+}
+
+void *getWindowProc(QWinHost *host)
+{
+ return host ? host->wndproc : 0;
+}
+
+LRESULT CALLBACK WinHostProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ QWinHost *widget = qobject_cast<QWinHost*>(QWidget::find(::GetParent(hwnd)));
+ WNDPROC oldproc = (WNDPROC)getWindowProc(widget);
+ if (widget) {
+ switch(msg) {
+ case WM_LBUTTONDOWN:
+ if (::GetFocus() != hwnd && (widget->focusPolicy() & Qt::ClickFocus)) {
+ widget->setFocus(Qt::MouseFocusReason);
+ }
+ break;
+
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ QT_WA({
+ SendMessage(widget->winId(), msg, wParam, lParam);
+ }, {
+ SendMessageA(widget->winId(), msg, wParam, lParam);
+ })
+ break;
+
+ case WM_KEYDOWN:
+ if (wParam == VK_TAB) {
+ QT_WA({
+ SendMessage(widget->winId(), msg, wParam, lParam);
+ }, {
+ SendMessageA(widget->winId(), msg, wParam, lParam);
+ })
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ QT_WA({
+ if (oldproc)
+ return CallWindowProc(oldproc, hwnd, msg, wParam, lParam);
+ return DefWindowProc(hwnd,msg,wParam,lParam);
+ }, {
+ if (oldproc)
+ return CallWindowProcA(oldproc, hwnd, msg, wParam, lParam);
+ return DefWindowProcA(hwnd,msg,wParam,lParam);
+ })
+}
+
+/*!
+ \reimp
+*/
+bool QWinHost::event(QEvent *e)
+{
+ switch(e->type()) {
+ case QEvent::Polish:
+ if (!hwnd) {
+ hwnd = createWindow(winId(), qWinAppInst());
+ fixParent();
+ own_hwnd = hwnd != 0;
+ }
+ if (hwnd && !wndproc && GetParent(hwnd) == winId()) {
+#if defined(GWLP_WNDPROC)
+ QT_WA({
+ wndproc = (void*)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WinHostProc);
+ }, {
+ wndproc = (void*)GetWindowLongPtrA(hwnd, GWLP_WNDPROC);
+ SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)WinHostProc);
+ })
+#else
+ QT_WA({
+ wndproc = (void*)GetWindowLong(hwnd, GWL_WNDPROC);
+ SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WinHostProc);
+ }, {
+ wndproc = (void*)GetWindowLongA(hwnd, GWL_WNDPROC);
+ SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)WinHostProc);
+ })
+#endif
+
+ LONG style;
+ QT_WA({
+ style = GetWindowLong(hwnd, GWL_STYLE);
+ }, {
+ style = GetWindowLongA(hwnd, GWL_STYLE);
+ })
+ if (style & WS_TABSTOP)
+ setFocusPolicy(Qt::FocusPolicy(focusPolicy() | Qt::StrongFocus));
+ }
+ break;
+ case QEvent::WindowBlocked:
+ if (hwnd)
+ EnableWindow(hwnd, false);
+ break;
+ case QEvent::WindowUnblocked:
+ if (hwnd)
+ EnableWindow(hwnd, true);
+ break;
+ }
+ return QWidget::event(e);
+}
+
+/*!
+ \reimp
+*/
+void QWinHost::showEvent(QShowEvent *e)
+{
+ QWidget::showEvent(e);
+
+ if (hwnd)
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, width(), height(), SWP_SHOWWINDOW);
+}
+
+/*!
+ \reimp
+*/
+void QWinHost::focusInEvent(QFocusEvent *e)
+{
+ QWidget::focusInEvent(e);
+
+ if (hwnd)
+ ::SetFocus(hwnd);
+}
+
+/*!
+ \reimp
+*/
+void QWinHost::resizeEvent(QResizeEvent *e)
+{
+ QWidget::resizeEvent(e);
+
+ if (hwnd)
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, width(), height(), 0);
+}
+
+/*!
+ \reimp
+*/
+bool QWinHost::winEvent(MSG *msg, long *result)
+{
+ switch (msg->message)
+ {
+ case WM_SETFOCUS:
+ if (hwnd) {
+ ::SetFocus(hwnd);
+ return true;
+ }
+ default:
+ break;
+ }
+
+ return QWidget::winEvent(msg, result);
+}
diff --git a/qtwinmigrate/qwinhost.h b/qtwinmigrate/qwinhost.h
new file mode 100644
index 0000000..bf8686e
--- /dev/null
+++ b/qtwinmigrate/qwinhost.h
@@ -0,0 +1,57 @@
+
+// Declaration of the QWinHost classes
+
+#ifndef QWINHOST_H
+#define QWINHOST_H
+
+#include <QtGui/QWidget>
+
+#if defined(Q_WS_WIN)
+# if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
+# define QT_QTWINMIGRATE_EXPORT
+# elif defined(QT_QTWINMIGRATE_IMPORT)
+# if defined(QT_QTWINMIGRATE_EXPORT)
+# undef QT_QTWINMIGRATE_EXPORT
+# endif
+# define QT_QTWINMIGRATE_EXPORT __declspec(dllimport)
+# elif defined(QT_QTWINMIGRATE_EXPORT)
+# undef QT_QTWINMIGRATE_EXPORT
+# define QT_QTWINMIGRATE_EXPORT __declspec(dllexport)
+# endif
+#else
+# define QT_QTWINMIGRATE_EXPORT
+#endif
+
+#include <windows.h>
+
+class QT_QTWINMIGRATE_EXPORT QWinHost : public QWidget
+{
+ Q_OBJECT
+public:
+ QWinHost(QWidget *parent = 0, Qt::WFlags f = 0);
+ ~QWinHost();
+
+ void setWindow(HWND);
+ HWND window() const;
+
+protected:
+ virtual HWND createWindow(HWND parent, HINSTANCE instance);
+
+ bool event(QEvent *e);
+ void showEvent(QShowEvent *);
+ void focusInEvent(QFocusEvent*);
+ void resizeEvent(QResizeEvent*);
+
+ bool winEvent(MSG *msg, long *result);
+
+private:
+ void fixParent();
+ friend void* getWindowProc(QWinHost*);
+
+ void *wndproc;
+ bool own_hwnd;
+ HHOOK m_hook;
+ HWND hwnd;
+};
+
+#endif // QWINHOST_H
diff --git a/qtwinmigrate/qwinwidget.cpp b/qtwinmigrate/qwinwidget.cpp
new file mode 100644
index 0000000..2c0929f
--- /dev/null
+++ b/qtwinmigrate/qwinwidget.cpp
@@ -0,0 +1,331 @@
+// Implementation of the QWinWidget classes
+
+#ifdef QT3_SUPPORT
+#undef QT3_SUPPORT
+#endif
+
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#include "qmfcapp.h"
+
+#ifdef QTWINMIGRATE_WITHMFC
+#include <afxwin.h>
+#endif
+
+#include <qevent.h>
+
+#include "qwinwidget.h"
+
+#include <qt_windows.h>
+
+/*!
+ \class QWinWidget qwinwidget.h
+ \brief The QWinWidget class is a Qt widget that can be child of a
+ native Win32 widget.
+
+ The QWinWidget class is the bridge between an existing application
+ user interface developed using native Win32 APIs or toolkits like
+ MFC, and Qt based GUI elements.
+
+ Using QWinWidget as the parent of QDialogs will ensure that
+ modality, placement and stacking works properly throughout the
+ entire application. If the child widget is a top level window that
+ uses the \c WDestructiveClose flag, QWinWidget will destroy itself
+ when the child window closes down.
+
+ Applications moving to Qt can use QWinWidget to add new
+ functionality, and gradually replace the existing interface.
+*/
+
+/*!
+ Creates an instance of QWinWidget. \a hParentWnd is the handle to
+ the native Win32 parent. If a \a parent is provided the object is
+ owned by that QObject. \a f is passed on to the QWidget constructor.
+*/
+QWinWidget::QWinWidget(HWND hParentWnd, QObject *parent, Qt::WFlags f)
+: QWidget(0, f), hParent(hParentWnd), prevFocus(0), reenable_parent(false)
+{
+ if (parent)
+ QObject::setParent(parent);
+
+ init();
+}
+
+#ifdef QTWINMIGRATE_WITHMFC
+/*!
+ \overload
+
+ Creates an instance of QWinWidget. \a parentWnd is a pointer to an
+ MFC window object. If a \a parent is provided the object is owned
+ by that QObject. \a f is passed on to the QWidget constructor.
+*/
+QWinWidget::QWinWidget(CWnd *parentWnd, QObject *parent, Qt::WFlags f)
+: QWidget(0, f), hParent(parentWnd ? parentWnd->m_hWnd : 0), prevFocus(0), reenable_parent(false)
+{
+ if (parent)
+ QObject::setParent(parent);
+
+ init();
+}
+#endif
+
+
+void QWinWidget::init()
+{
+ Q_ASSERT(hParent);
+
+ if (hParent) {
+ // make the widget window style be WS_CHILD so SetParent will work
+ QT_WA({
+ SetWindowLong(winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ }, {
+ SetWindowLongA(winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ })
+ SetParent(winId(), hParent);
+
+ QEvent e(QEvent::EmbeddingControl);
+ QApplication::sendEvent(this, &e);
+ }
+}
+
+/*!
+ Destroys this object, freeing all allocated resources.
+*/
+QWinWidget::~QWinWidget()
+{
+}
+
+/*!
+ Returns the handle of the native Win32 parent window.
+*/
+HWND QWinWidget::parentWindow() const
+{
+ return hParent;
+}
+
+/*!
+ \reimp
+*/
+void QWinWidget::childEvent(QChildEvent *e)
+{
+ QObject *obj = e->child();
+ if (obj->isWidgetType()) {
+ if (e->added()) {
+ if (obj->isWidgetType()) {
+ obj->installEventFilter(this);
+ }
+ } else if (e->removed() && reenable_parent) {
+ reenable_parent = false;
+ EnableWindow(hParent, true);
+ obj->removeEventFilter(this);
+ }
+ }
+ QWidget::childEvent(e);
+}
+
+/*! \internal */
+void QWinWidget::saveFocus()
+{
+ if (!prevFocus)
+ prevFocus = ::GetFocus();
+ if (!prevFocus)
+ prevFocus = parentWindow();
+}
+
+/*!
+ Shows this widget. Overrides QWidget::show().
+
+ \sa showCentered()
+*/
+void QWinWidget::show()
+{
+ saveFocus();
+ QWidget::show();
+}
+
+/*!
+ Centers this widget over the native parent window. Use this
+ function to have Qt toplevel windows (i.e. dialogs) positioned
+ correctly over their native parent windows.
+
+ \code
+ QWinWidget qwin(hParent);
+ qwin.center();
+
+ QMessageBox::information(&qwin, "Caption", "Information Text");
+ \endcode
+
+ This will center the message box over the client area of hParent.
+*/
+void QWinWidget::center()
+{
+ const QWidget *child = qFindChild<QWidget*>(this);
+ if (child && !child->isWindow()) {
+ qWarning("QWinWidget::center: Call this function only for QWinWidgets with toplevel children");
+ }
+ RECT r;
+ GetWindowRect(hParent, &r);
+ setGeometry((r.right-r.left)/2+r.left, (r.bottom-r.top)/2+r.top,0,0);
+}
+
+/*!
+ \obsolete
+
+ Call center() instead.
+*/
+void QWinWidget::showCentered()
+{
+ center();
+ show();
+}
+
+/*!
+ Sets the focus to the window that had the focus before this widget
+ was shown, or if there was no previous window, sets the focus to
+ the parent window.
+*/
+void QWinWidget::resetFocus()
+{
+ if (prevFocus)
+ ::SetFocus(prevFocus);
+ else
+ ::SetFocus(parentWindow());
+}
+
+/*! \reimp
+*/
+bool QWinWidget::winEvent(MSG *msg, long *)
+{
+ if (msg->message == WM_SETFOCUS) {
+ Qt::FocusReason reason;
+ if (::GetKeyState(VK_SHIFT) < 0)
+ reason = Qt::BacktabFocusReason;
+ else
+ reason = Qt::TabFocusReason;
+ QFocusEvent e(QEvent::FocusIn, reason);
+ QApplication::sendEvent(this, &e);
+ }
+
+ return false;
+}
+
+/*!
+ \reimp
+*/
+bool QWinWidget::eventFilter(QObject *o, QEvent *e)
+{
+ QWidget *w = (QWidget*)o;
+
+ switch (e->type()) {
+ case QEvent::WindowDeactivate:
+ if (w->isModal() && w->isHidden())
+ BringWindowToTop(hParent);
+ break;
+
+ case QEvent::Hide:
+ if (reenable_parent) {
+ EnableWindow(hParent, true);
+ reenable_parent = false;
+ }
+ resetFocus();
+ if (w->testAttribute(Qt::WA_DeleteOnClose) && w->isWindow())
+ deleteLater();
+ break;
+
+ case QEvent::Show:
+ if (w->isWindow()) {
+ saveFocus();
+ hide();
+ if (w->isModal() && !reenable_parent) {
+ EnableWindow(hParent, false);
+ reenable_parent = true;
+ }
+ }
+ break;
+
+ case QEvent::Close:
+ ::SetActiveWindow(hParent);
+ if (w->testAttribute(Qt::WA_DeleteOnClose))
+ deleteLater();
+ break;
+
+ default:
+ break;
+ }
+
+ return QWidget::eventFilter(o, e);
+}
+
+/*! \reimp
+*/
+void QWinWidget::focusInEvent(QFocusEvent *e)
+{
+ QWidget *candidate = this;
+
+ switch (e->reason()) {
+ case Qt::TabFocusReason:
+ case Qt::BacktabFocusReason:
+ while (!(candidate->focusPolicy() & Qt::TabFocus)) {
+ candidate = candidate->nextInFocusChain();
+ if (candidate == this) {
+ candidate = 0;
+ break;
+ }
+ }
+ if (candidate) {
+ candidate->setFocus(e->reason());
+ if (e->reason() == Qt::BacktabFocusReason || e->reason() == Qt::TabFocusReason) {
+ candidate->setAttribute(Qt::WA_KeyboardFocusChange);
+ candidate->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ }
+ if (e->reason() == Qt::BacktabFocusReason)
+ QWidget::focusNextPrevChild(false);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*! \reimp
+*/
+bool QWinWidget::focusNextPrevChild(bool next)
+{
+ QWidget *curFocus = focusWidget();
+ if (!next) {
+ if (!curFocus->isWindow()) {
+ QWidget *nextFocus = curFocus->nextInFocusChain();
+ QWidget *prevFocus = 0;
+ QWidget *topLevel = 0;
+ while (nextFocus != curFocus) {
+ if (nextFocus->focusPolicy() & Qt::TabFocus) {
+ prevFocus = nextFocus;
+ topLevel = 0;
+ } else if (nextFocus->isWindow()) {
+ topLevel = nextFocus;
+ }
+ nextFocus = nextFocus->nextInFocusChain();
+ }
+
+ if (!topLevel) {
+ return QWidget::focusNextPrevChild(false);
+ }
+ }
+ } else {
+ QWidget *nextFocus = curFocus;
+ while (1) {
+ nextFocus = nextFocus->nextInFocusChain();
+ if (nextFocus->isWindow())
+ break;
+ if (nextFocus->focusPolicy() & Qt::TabFocus) {
+ return QWidget::focusNextPrevChild(true);
+ }
+ }
+ }
+
+ ::SetFocus(hParent);
+
+ return true;
+}
diff --git a/qtwinmigrate/qwinwidget.h b/qtwinmigrate/qwinwidget.h
new file mode 100644
index 0000000..59ed7d4
--- /dev/null
+++ b/qtwinmigrate/qwinwidget.h
@@ -0,0 +1,64 @@
+
+// Declaration of the QWinWidget classes
+
+#ifndef QWINWIDGET_H
+#define QWINWIDGET_H
+
+#include <QtGui/QWidget>
+#include "qmfcapp.h"
+
+class CWnd;
+
+#if defined(Q_WS_WIN)
+# if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
+# define QT_QTWINMIGRATE_EXPORT
+# elif defined(QT_QTWINMIGRATE_IMPORT)
+# if defined(QT_QTWINMIGRATE_EXPORT)
+# undef QT_QTWINMIGRATE_EXPORT
+# endif
+# define QT_QTWINMIGRATE_EXPORT __declspec(dllimport)
+# elif defined(QT_QTWINMIGRATE_EXPORT)
+# undef QT_QTWINMIGRATE_EXPORT
+# define QT_QTWINMIGRATE_EXPORT __declspec(dllexport)
+# endif
+#else
+# define QT_QTWINMIGRATE_EXPORT
+#endif
+
+class QT_QTWINMIGRATE_EXPORT QWinWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ QWinWidget( HWND hParentWnd, QObject *parent = 0, Qt::WFlags f = 0 );
+#ifdef QTWINMIGRATE_WITHMFC
+ QWinWidget( CWnd *parnetWnd, QObject *parent = 0, Qt::WFlags f = 0 );
+#endif
+ ~QWinWidget();
+
+ void show();
+ void center();
+ void showCentered();
+
+ HWND parentWindow() const;
+
+protected:
+ void childEvent( QChildEvent *e );
+ bool eventFilter( QObject *o, QEvent *e );
+
+ bool focusNextPrevChild(bool next);
+ void focusInEvent(QFocusEvent *e);
+
+ bool winEvent(MSG *msg, long *result);
+
+private:
+ void init();
+
+ void saveFocus();
+ void resetFocus();
+
+ HWND hParent;
+ HWND prevFocus;
+ bool reenable_parent;
+};
+
+#endif // QWINWIDGET_H
diff --git a/qwidgethostnative.cpp b/qwidgethostnative.cpp
new file mode 100644
index 0000000..a8112a6
--- /dev/null
+++ b/qwidgethostnative.cpp
@@ -0,0 +1,104 @@
+#include "qwidgethostnative.h"
+
+#include "qtjambi_core.h"
+
+#include <jawt.h>
+#include <jawt_md.h>
+
+#include <QtGui/QApplication>
+
+static const char *qtjambi_awt_title = "Qt Jambi / AWT";
+
+QWidgetHostNative::QWidgetHostNative(jobject parentWindow)
+
+#if defined(Q_OS_WIN32)
+ : QWIDGETHOSTNATIVE_BASECLASS(getWindowHandle(parentWindow))
+#else
+ : QWIDGETHOSTNATIVE_BASECLASS(0)
+#endif
+
+{
+#if !defined(Q_OS_WIN32)
+ embedInto(getWindowHandle(parentWindow));
+#endif
+}
+
+WId QWidgetHostNative::getWindowHandle(jobject awtWidget)
+{
+ Q_ASSERT(awtWidget != 0);
+
+ // Call winId() to make sure widget gets a window handle
+ QApplication::setAttribute(Qt::AA_NativeWindows);
+
+ JNIEnv *env = qtjambi_current_environment();
+ Q_ASSERT(env != 0);
+
+ JAWT awt;
+ awt.version = JAWT_VERSION_1_3;
+ if (JAWT_GetAWT(env, &awt) == JNI_FALSE) {
+ qWarning("%s [%s:%d]: Couldn't get JAWT interface\n", qtjambi_awt_title, __FILE__, __LINE__);
+ return false;
+ }
+
+ WId awtWindowId = 0;
+ {
+ JAWT_DrawingSurface *ds;
+ ds = awt.GetDrawingSurface(env, awtWidget);
+ if (ds == 0) {
+ qWarning("%s [%s:%d]: Couldn't get drawing surface\n", qtjambi_awt_title, __FILE__, __LINE__);
+ return false;
+ }
+
+ jint lock = ds->Lock(ds);
+ if (lock & JAWT_LOCK_ERROR) {
+ qWarning("%s [%s:%d]: Couldn't lock drawing surface\n", qtjambi_awt_title, __FILE__, __LINE__);
+ return false;
+ }
+
+ {
+ JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds);
+ if (dsi == 0) {
+ qWarning("%s [%s:%d]: Couldn't get drawing surface info\n", qtjambi_awt_title, __FILE__, __LINE__);
+ return false;
+ }
+
+#if defined(Q_OS_WIN32)
+ awtWindowId = reinterpret_cast<JAWT_Win32DrawingSurfaceInfo *>(dsi->platformInfo)->hwnd;
+#else
+ awtWindowId = reinterpret_cast<JAWT_X11DrawingSurfaceInfo *>(dsi->platformInfo)->drawable;
+#endif
+ ds->FreeDrawingSurfaceInfo(dsi);
+ }
+
+ ds->Unlock(ds);
+ awt.FreeDrawingSurface(ds);
+ }
+
+ return awtWindowId;
+}
+
+/* ### Empty implementations to work around limitation in generator */
+void QWidgetHostNative::childEvent(QChildEvent *e)
+{
+ QWIDGETHOSTNATIVE_BASECLASS::childEvent(e);
+}
+
+bool QWidgetHostNative::eventFilter(QObject *o, QEvent *e)
+{
+ return QWIDGETHOSTNATIVE_BASECLASS::eventFilter(o, e);
+}
+
+void QWidgetHostNative::focusInEvent(QFocusEvent *e)
+{
+ QWIDGETHOSTNATIVE_BASECLASS::focusInEvent(e);
+}
+
+bool QWidgetHostNative::event(QEvent *e)
+{
+ return QWIDGETHOSTNATIVE_BASECLASS::event(e);
+}
+
+void QWidgetHostNative::resizeEvent(QResizeEvent *e)
+{
+ QWIDGETHOSTNATIVE_BASECLASS::resizeEvent(e);
+}
diff --git a/qwidgethostnative.h b/qwidgethostnative.h
new file mode 100644
index 0000000..e753b75
--- /dev/null
+++ b/qwidgethostnative.h
@@ -0,0 +1,34 @@
+#ifndef QWIDGETHOSTNATIVE_H
+#define QWIDGETHOSTNATIVE_H
+
+#include <QtGui>
+
+#if defined(QT_JAMBI_RUN)
+# define QWIDGETHOSTNATIVE_BASECLASS QWidget
+#elif defined(Q_OS_WIN32)
+# include "qwinwidget.h"
+# define QWIDGETHOSTNATIVE_BASECLASS QWinWidget
+#else
+# include <QtGui/QX11EmbedWidget>
+# define QWIDGETHOSTNATIVE_BASECLASS QX11EmbedWidget
+#endif
+
+#include <jni.h>
+
+class QWidgetHostNative: public QWIDGETHOSTNATIVE_BASECLASS
+{
+public:
+ QWidgetHostNative(jobject parentWindow);
+
+protected:
+ void childEvent(QChildEvent *e);
+ bool eventFilter(QObject *o, QEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ bool event(QEvent *);
+ void resizeEvent(QResizeEvent *);
+
+private:
+ WId getWindowHandle(jobject window);
+};
+
+#endif
diff --git a/typesystem_qawt.xml b/typesystem_qawt.xml
new file mode 100644
index 0000000..b0e252b
--- /dev/null
+++ b/typesystem_qawt.xml
@@ -0,0 +1,14 @@
+<typesystem package="com.trolltech.research.qtjambiawtbridge.generated" default-superclass="com.trolltech.qt.QtJambiObject">
+ <load-typesystem name=":/trolltech/generator/typesystem_core.txt" generate="no" />
+ <load-typesystem name=":/trolltech/generator/typesystem_gui.txt" generate="no" />
+
+ <inject-code>
+ com.trolltech.qt.Utilities.Configuration oldConfiguration = com.trolltech.qt.Utilities.configuration;
+ com.trolltech.qt.Utilities.configuration = com.trolltech.qt.Utilities.Configuration.Release;
+ com.trolltech.qt.Utilities.loadLibrary("jawt");
+ com.trolltech.qt.Utilities.configuration = oldConfiguration;
+ </inject-code>
+
+ <object-type name="QComponentHostNative" />
+ <object-type name="QWidgetHostNative" />
+</typesystem>