Hello,

Do you remember the WebKit intergration described in
http://www.webtoolkit.eu/wt/wiki/index.php/Ideas_for_Google_SoC ?

Well, the attached patch is an implementation of that. In a very early
stage of development, but it works.

The patch is against current public git. It requires Qt 4 (I've tested
with Qt 4.6 beta1 on Linux but it should work with Qt >= 4.4 on any
platform). Just specify the wtdesktop connector for the examples
(cmake -DEXAMPLES_CONNECTOR=wtdesktop) and run the examples as you
have always done but in port 9000 (hardcoded for now). It will open a
QtWebKit window with the webapp.

There is still a lot of improvement to be done but I was so happy to
get this working with so few effort (a couple of hours), I wanted to
share.

For now, it builds most of the wthttp connector in the wtdesktop
connector again. Koen, Wim, can we split libwthttp.so in two
libraries, libwthttpcommon.so (most of it) and libwthttp.so (very
lightweight, essentially WtHttpRun.C) ?

Tell me what you think.

-- 
Pau Garcia i Quiles
http://www.elpauer.org
(Due to my workload, I may need 10 days to answer)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3b59be3..75f614d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,6 +15,7 @@ SET(WT_SOVERSION 18)
 SET(WTEXT_SOVERSION 12)
 SET(WTHTTP_SOVERSION 7)
 SET(WTFCGI_SOVERSION 7)
+SET(WTDESKTOP_SOVERSION 1)
 
 #
 # Various things that must be configured by the user or packager ...
@@ -83,6 +84,7 @@ SET(WEBUSER apache CACHE STRING "Webserver username (e.g. apache or www)")
 SET(WEBGROUP apache CACHE STRING "Webserver groupname (e.g. apache or www or users)")
 OPTION(CONNECTOR_FCGI "Compile in FCGI connector (libwtfcgi) ?" OFF)
 OPTION(CONNECTOR_HTTP "Compile in stand-alone httpd connector (libwthttp) ?" ON)
+OPTION(CONNECTOR_DESKTOP "Compile in desktop application connector (libwtdesktop)? ON")
 SET(EXAMPLES_CONNECTOR wthttp CACHE STRING "Connector used for examples")
 
 INCLUDE(cmake/WtFindBoost.txt)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 84f4cd1..43c2d2c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -260,7 +260,7 @@ IF(WIN32)
   TARGET_LINK_LIBRARIES(wt winmm wsock32)
 ENDIF(WIN32)
 
-SUBDIRS(fcgi http)
+SUBDIRS(fcgi http desktop)
 
 ADD_LIBRARY(wtext
   Wt/Ext/AbstractButton.C
diff --git a/src/desktop/CMakeLists.txt b/src/desktop/CMakeLists.txt
new file mode 100644
index 0000000..835101a
--- /dev/null
+++ b/src/desktop/CMakeLists.txt
@@ -0,0 +1,80 @@
+IF(CONNECTOR_DESKTOP)
+  MESSAGE("** Enabling WtDesktop .")
+
+  # TODO Future: replace the following three lines with
+  # FIND_PACKAGE( Qt4 4.4.0 COMPONENTS QtCore QtGui QtWebKit REQUIRED )
+  SET( QT_MIN_VERSION 4.4.0 )
+  SET( USE_QTWEBKIT 1 )
+  FIND_PACKAGE( Qt4 REQUIRED )
+
+  IF(NOT QT_FOUND )
+    MESSAGE("** Error finding Wt required library: ")
+    MESSAGE(FATAL_ERROR "** Wt Desktop connector requires Qt4 > 4.4")
+  ENDIF(NOT QT_FOUND)
+
+  INCLUDE_DIRECTORIES( ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR} ${QT_QTWEBKIT_INCLUDE_DIR} ../Wt )
+
+  SET(libwtdesktopsources
+    DesktopServer.C
+    DesktopMainWindow.C
+    DesktopHttpThread.C
+    ../http/Configuration.C
+    ../http/Connection.C
+    ../http/ConnectionManager.C
+    ../http/HTTPRequest.C
+    ../http/HTTPStream.C
+    ../http/MimeTypes.C
+    ../http/Reply.C
+    ../http/Request.C
+    ../http/RequestHandler.C
+    ../http/RequestParser.C
+    ../http/Server.C
+    ../http/SslConnection.C
+    ../http/StaticReply.C
+    ../http/StockReply.C
+    ../http/TcpConnection.C
+    ../http/WServer.C
+    ../http/WtReply.C
+  )
+
+  QT4_WRAP_CPP( libwtdesktopsources_MOC_SRCS DesktopMainWindow.h )
+  
+  IF(NOT BOOST_WTHTTP_FOUND)
+    MESSAGE(FATAL "Could not find all boost libraries required to build the desktop connector (thread, fs, po, dt)")
+  ENDIF(NOT BOOST_WTHTTP_FOUND)
+  IF(NOT ASIO_FOUND)
+    MESSAGE("** Error finding WtDesktop required library: ")
+    MESSAGE(FATAL_ERROR "** WtDesktop requires the asio library (http://asio.sf.net), the boost or non-boost version 0.3.9 or later.")
+  ENDIF(NOT ASIO_FOUND)
+
+  INCLUDE_DIRECTORIES(
+    ${ASIO_INCLUDE_DIRS}
+    ${BOOST_INCLUDE_DIRS}
+    ${CMAKE_CURRENT_SOURCE_DIR}/../web
+    ${CMAKE_CURRENT_SOURCE_DIR}/../wt
+    ${CMAKE_CURRENT_SOURCE_DIR}/../http
+    ${CMAKE_CURRENT_BINARY_DIR}/
+  )
+
+  ADD_DEFINITIONS(${ASIO_DEFINITIONS})
+  
+  ADD_LIBRARY(wtdesktop ${libwtdesktopsources} ${libwtdesktopsources_MOC_SRCS})
+  TARGET_LINK_LIBRARIES(wtdesktop wt ${QT_QTCORE_LIBRARIES} ${QT_QTGUI_LIBRARIES} ${QT_QTWEBKIT_LIBRARIES}     ${MY_SSL_LIBS} ${BOOST_WTHTTP_LIBRARIES}  ${ASIO_LIBRARIES}
+)
+
+  SET_TARGET_PROPERTIES(
+    wtdesktop
+  PROPERTIES
+    VERSION ${VERSION_SERIES}.${VERSION_MAJOR}.${VERSION_MINOR}
+    SOVERSION ${WTDESKTOP_SOVERSION}
+    DEBUG_POSTFIX "d"
+  )
+
+  INSTALL(TARGETS wtdesktop
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+    ARCHIVE DESTINATION ${LIB_INSTALL_DIR})
+ELSE(CONNECTOR_DESKTOP)
+  MESSAGE("** Disabling WtDesktop.")
+ENDIF(CONNECTOR_DESKTOP)
+
diff --git a/src/desktop/DesktopHttpThread.C b/src/desktop/DesktopHttpThread.C
new file mode 100644
index 0000000..cf80a70
--- /dev/null
+++ b/src/desktop/DesktopHttpThread.C
@@ -0,0 +1,92 @@
+// This may look like C code, but it's really -*- C++ -*-
+/*
+ * Copyright (C) 2009 Emweb bvba, Kessel-Lo, Belgium.
+ *
+ * See the LICENSE file for terms of use.
+ */
+
+#include "Wt/WServer"
+#include "Wt/WApplication"
+
+#include <iostream>
+#include <string>
+
+#if !defined(_WIN32)
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <pthread.h>
+#endif // !_WIN32
+
+#ifdef WT_THREADED
+#ifdef BOOST_ASIO
+#include <boost/asio.hpp>
+#include <boost/thread.hpp>
+#else  // BOOST_ASIO
+#include <asio/thread.hpp>
+#endif // BOOST_ASIO
+#endif // WT_THREADED
+
+#include <boost/bind.hpp>
+
+#include "Connection.h"
+#include "Server.h"
+#include "WServerImpl.h"
+#include "Configuration.h"
+#include "../web/Configuration.h"
+#include "WebController.h"
+#include "HTTPStream.h"
+#include "DesktopHttpThread.h"
+
+#ifdef WT_THREADED
+#ifdef BOOST_ASIO
+typedef boost::thread thread_t;
+#else
+typedef asio::thread thread_t;
+#endif
+#endif
+namespace {
+  static std::string getWtConfigXml(int argc, char *argv[])
+  {
+    std::string wt_config_xml;
+    Wt::WLogger stderrLogger;
+    stderrLogger.setStream(std::cerr);
+    
+    http::server::Configuration serverConfiguration(stderrLogger, true);
+    serverConfiguration.setOptions(argc, argv, WTHTTP_CONFIGURATION);
+    
+    return serverConfiguration.configPath();
+  }
+
+}
+
+namespace Wt {
+void DesktopHttpThread::run()
+{
+  try {
+    WServer server(argv_[0], getWtConfigXml(argc_, argv_));
+    try {
+      server.setServerConfiguration(argc_, argv_, WTHTTP_CONFIGURATION);
+      server.addEntryPoint(Application, createApplication_);
+      if (server.start()) {
+	int sig = WServer::waitForShutdown();
+	server.impl()->serverConfiguration_.log("notice")
+	  << "Shutdown (signal = " << sig << ")";
+	server.stop();
+      }
+
+      //return 0;
+    } catch (std::exception& e) {
+      server.impl()->serverConfiguration_.log("fatal") << e.what();
+      //return 1;
+    }
+  } catch (Wt::WServer::Exception& e) {
+    std::cerr << e.what() << std::endl;
+    //return 1;
+  } catch (std::exception& e) {
+    std::cerr << "exception: " << e.what() << std::endl;
+    //return 1;
+  }
+}
+
+}
diff --git a/src/desktop/DesktopHttpThread.h b/src/desktop/DesktopHttpThread.h
new file mode 100644
index 0000000..3de7003
--- /dev/null
+++ b/src/desktop/DesktopHttpThread.h
@@ -0,0 +1,35 @@
+// This may look like C code, but it's really -*- C++ -*-
+/*
+ * Copyright (C) 2009 Emweb bvba, Kessel-Lo, Belgium.
+ *
+ * All rights reserved.
+ */
+
+#ifndef DESKTOP_HTTP_THREAD_HPP
+#define DESKTOP_HTTP_THREAD_HPP
+
+#include <QThread>
+#include <WApplication>
+
+namespace Wt {
+class DesktopHttpThread : public QThread {
+  
+  public:
+    
+  DesktopHttpThread(int argc, char *argv[], ApplicationCreator createApplication) :
+    argc_(argc), argv_(argv), createApplication_(createApplication) { ; };
+    
+  ~DesktopHttpThread() { ; };
+  
+  protected:
+    void run();
+    
+  private:
+    int argc_;
+    char** argv_;
+    ApplicationCreator createApplication_;
+};
+
+}
+
+#endif
diff --git a/src/desktop/DesktopMainWindow.C b/src/desktop/DesktopMainWindow.C
new file mode 100644
index 0000000..7e34f8b
--- /dev/null
+++ b/src/desktop/DesktopMainWindow.C
@@ -0,0 +1,39 @@
+#include <QWebView>
+#include <QUrl>
+#include "DesktopMainWindow.h"
+
+DesktopMainWindow::DesktopMainWindow()
+{
+    progress = 0;
+
+    view = new QWebView(this);
+    view->load(QUrl("http://127.0.0.1:9000";)); // TODO Do not hardcode port
+    connect(view, SIGNAL(loadFinished(bool)), SLOT(adjustLocation()));
+    connect(view, SIGNAL(titleChanged(const QString&)), SLOT(adjustTitle()));
+    connect(view, SIGNAL(loadProgress(int)), SLOT(setProgress(int)));
+    connect(view, SIGNAL(loadFinished(bool)), SLOT(finishLoading(bool)));
+
+    setCentralWidget(view);
+    setUnifiedTitleAndToolBarOnMac(true);
+}
+
+void DesktopMainWindow::adjustTitle()
+{
+    if (progress <= 0 || progress >= 100) {
+        setWindowTitle(view->title());
+    } else {
+        setWindowTitle(QString("%1 (%2%)").arg(view->title()).arg(progress));
+    }
+}
+
+void DesktopMainWindow::setProgress(int p)
+{
+    progress = p;
+    adjustTitle();
+}
+
+void DesktopMainWindow::finishLoading(bool)
+{
+    progress = 100;
+    adjustTitle();
+}
diff --git a/src/desktop/DesktopMainWindow.h b/src/desktop/DesktopMainWindow.h
new file mode 100644
index 0000000..2f43ef2
--- /dev/null
+++ b/src/desktop/DesktopMainWindow.h
@@ -0,0 +1,25 @@
+#include <QMainWindow>
+
+#ifndef DESKTOP_MAIN_WINDOW_HPP
+#define DESKTOP_MAIN_WINDOW_HPP
+
+class QWebView;
+
+class DesktopMainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    DesktopMainWindow();
+
+protected slots:
+    void adjustTitle();
+    void setProgress(int p);
+    void finishLoading(bool);
+
+private:
+    QWebView *view;
+    int progress;
+};
+
+#endif
diff --git a/src/desktop/DesktopServer.C b/src/desktop/DesktopServer.C
new file mode 100644
index 0000000..44d0701
--- /dev/null
+++ b/src/desktop/DesktopServer.C
@@ -0,0 +1,43 @@
+// #ifdef SLOT
+// # undef SLOT
+// # undef signals
+// # undef slots
+// #endif
+
+#include <QApplication>
+#include "DesktopMainWindow.h"
+
+#ifdef SLOT
+# undef SLOT
+# undef signals
+# undef slots
+# undef emit
+#endif
+
+//#include <WApplication>
+#include "DesktopHttpThread.h"
+
+namespace Wt {
+int WRun(int argc, char * argv[], ApplicationCreator createApplication)
+{
+
+    // Start wthttp in a secondary thread
+    DesktopHttpThread* http = new DesktopHttpThread(argc, argv, createApplication);
+    http->start();
+    
+    // Start Qt in the main thread
+    QApplication app(argc, argv);
+    DesktopMainWindow* browser = new DesktopMainWindow;
+    browser->show();
+    
+    int res = app.exec();
+    
+    http->quit();
+    
+    delete http;
+    delete browser;
+    
+    return res;
+}
+
+}
diff --git a/src/http/CMakeLists.txt b/src/http/CMakeLists.txt
index 4c59d13..6dfbc70 100644
--- a/src/http/CMakeLists.txt
+++ b/src/http/CMakeLists.txt
@@ -18,6 +18,7 @@ IF(CONNECTOR_HTTP)
     StockReply.C
     TcpConnection.C
     WServer.C
+    WtHttpRun.C
     WtReply.C
   )
     
diff --git a/src/http/WServer.C b/src/http/WServer.C
index 7d4cee3..d455b99 100644
--- a/src/http/WServer.C
+++ b/src/http/WServer.C
@@ -30,6 +30,7 @@
 
 #include "Connection.h"
 #include "Server.h"
+#include "WServerImpl.h"
 #include "Configuration.h"
 #include "../web/Configuration.h"
 #include "WebController.h"
@@ -42,45 +43,9 @@ typedef boost::thread thread_t;
 typedef asio::thread thread_t;
 #endif
 #endif
-namespace {
-  static std::string getWtConfigXml(int argc, char *argv[])
-  {
-    std::string wt_config_xml;
-    Wt::WLogger stderrLogger;
-    stderrLogger.setStream(std::cerr);
-    
-    http::server::Configuration serverConfiguration(stderrLogger, true);
-    serverConfiguration.setOptions(argc, argv, WTHTTP_CONFIGURATION);
-    
-    return serverConfiguration.configPath();
-  }
-
-}
 
 namespace Wt {
 
-struct WServerImpl {
-  WServerImpl(const std::string& wtApplicationPath,
-	      const std::string& wtConfigurationFile)
-  : wtConfiguration_(wtApplicationPath, wtConfigurationFile,
-		     Wt::Configuration::WtHttpdServer,
-		     "Wt: initializing built-in httpd"),
-    webController_(wtConfiguration_, &stream_),
-    serverConfiguration_(wtConfiguration_.logger()),
-    server_(0)
-  { }
-
-  Configuration wtConfiguration_;
-  HTTPStream    stream_;
-  WebController webController_;
-
-  http::server::Configuration  serverConfiguration_;
-  http::server::Server        *server_;
-#ifdef WT_THREADED
-  thread_t **threads_;
-#endif
-};
-
 WServer::WServer(const std::string& applicationPath,
 		 const std::string& wtConfigurationFile)
   : impl_(new WServerImpl(applicationPath, wtConfigurationFile))
@@ -291,32 +256,4 @@ int WServer::waitForShutdown()
 #endif // WT_THREADED
 }
 
-int WRun(int argc, char *argv[], ApplicationCreator createApplication)
-{
-  try {
-    WServer server(argv[0], getWtConfigXml(argc, argv));
-    try {
-      server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);
-      server.addEntryPoint(Application, createApplication);
-      if (server.start()) {
-	int sig = WServer::waitForShutdown();
-	server.impl()->serverConfiguration_.log("notice")
-	  << "Shutdown (signal = " << sig << ")";
-	server.stop();
-      }
-
-      return 0;
-    } catch (std::exception& e) {
-      server.impl()->serverConfiguration_.log("fatal") << e.what();
-      return 1;
-    }
-  } catch (Wt::WServer::Exception& e) {
-    std::cerr << e.what() << std::endl;
-    return 1;
-  } catch (std::exception& e) {
-    std::cerr << "exception: " << e.what() << std::endl;
-    return 1;
-  }
-}
-
 }
diff --git a/src/http/WServerImpl.h b/src/http/WServerImpl.h
new file mode 100644
index 0000000..dd216a9
--- /dev/null
+++ b/src/http/WServerImpl.h
@@ -0,0 +1,56 @@
+// This may look like C code, but it's really -*- C++ -*-
+/*
+ * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
+ *
+ * See the LICENSE file for terms of use.
+ */
+
+#ifndef HTTP_SERVERIMPL_HPP
+#define HTTP_SERVERIMPL_HPP
+
+#include "Wt/WServer"
+
+#include <string>
+
+#include "Connection.h"
+#include "Server.h"
+#include "Configuration.h"
+#include "../web/Configuration.h"
+#include "WebController.h"
+#include "HTTPStream.h"
+
+#ifdef WT_THREADED
+#ifdef BOOST_ASIO
+typedef boost::thread thread_t;
+#else
+typedef asio::thread thread_t;
+#endif
+#endif
+
+namespace Wt {
+
+struct WServerImpl {
+  WServerImpl(const std::string& wtApplicationPath,
+	      const std::string& wtConfigurationFile)
+  : wtConfiguration_(wtApplicationPath, wtConfigurationFile,
+		     Wt::Configuration::WtHttpdServer,
+		     "Wt: initializing built-in httpd"),
+    webController_(wtConfiguration_, &stream_),
+    serverConfiguration_(wtConfiguration_.logger()),
+    server_(0)
+  { }
+
+  Configuration wtConfiguration_;
+  HTTPStream    stream_;
+  WebController webController_;
+
+  http::server::Configuration  serverConfiguration_;
+  http::server::Server        *server_;
+#ifdef WT_THREADED
+  thread_t **threads_;
+#endif
+};
+
+}
+
+#endif
diff --git a/src/http/WtHttpRun.C b/src/http/WtHttpRun.C
new file mode 100644
index 0000000..6ecb152
--- /dev/null
+++ b/src/http/WtHttpRun.C
@@ -0,0 +1,91 @@
+// This may look like C code, but it's really -*- C++ -*-
+/*
+ * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
+ *
+ * See the LICENSE file for terms of use.
+ */
+
+#include "Wt/WServer"
+#include "Wt/WApplication"
+
+#include <iostream>
+#include <string>
+
+#if !defined(_WIN32)
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <pthread.h>
+#endif // !_WIN32
+
+#ifdef WT_THREADED
+#ifdef BOOST_ASIO
+#include <boost/asio.hpp>
+#include <boost/thread.hpp>
+#else  // BOOST_ASIO
+#include <asio/thread.hpp>
+#endif // BOOST_ASIO
+#endif // WT_THREADED
+
+#include <boost/bind.hpp>
+
+#include "Connection.h"
+#include "Server.h"
+#include "WServerImpl.h"
+#include "Configuration.h"
+#include "../web/Configuration.h"
+#include "WebController.h"
+#include "HTTPStream.h"
+
+#ifdef WT_THREADED
+#ifdef BOOST_ASIO
+typedef boost::thread thread_t;
+#else
+typedef asio::thread thread_t;
+#endif
+#endif
+namespace {
+  static std::string getWtConfigXml(int argc, char *argv[])
+  {
+    std::string wt_config_xml;
+    Wt::WLogger stderrLogger;
+    stderrLogger.setStream(std::cerr);
+    
+    http::server::Configuration serverConfiguration(stderrLogger, true);
+    serverConfiguration.setOptions(argc, argv, WTHTTP_CONFIGURATION);
+    
+    return serverConfiguration.configPath();
+  }
+
+}
+
+namespace Wt {
+int WRun(int argc, char *argv[], ApplicationCreator createApplication)
+{
+  try {
+    WServer server(argv[0], getWtConfigXml(argc, argv));
+    try {
+      server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);
+      server.addEntryPoint(Application, createApplication);
+      if (server.start()) {
+	int sig = WServer::waitForShutdown();
+	server.impl()->serverConfiguration_.log("notice")
+	  << "Shutdown (signal = " << sig << ")";
+	server.stop();
+      }
+
+      return 0;
+    } catch (std::exception& e) {
+      server.impl()->serverConfiguration_.log("fatal") << e.what();
+      return 1;
+    }
+  } catch (Wt::WServer::Exception& e) {
+    std::cerr << e.what() << std::endl;
+    return 1;
+  } catch (std::exception& e) {
+    std::cerr << "exception: " << e.what() << std::endl;
+    return 1;
+  }
+}
+
+}
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
witty-interest mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/witty-interest

Reply via email to