[webkit-dev] NP API support for DirectFB

Anders Bakken anders.bakken at myriadgroup.com
Wed Apr 14 13:42:26 PDT 2010


I've written a patch that enables the use of NPAPI plugins with QtWebKit
running under Qt/QWS using DirectFB.

The patch and suggestion can be found here:

https://bugs.webkit.org/show_bug.cgi?id=36171

The primary goal of the contribution is to allow set top boxes using
DirectFB to use Flash for the purpose of things like youtube.com/xl.

The patch is written in cooperation with Adobe and similar efforts have
been made with Mozilla. 

I talked to Simon Hausman about it and since it extends the NPAPI spec
he recommended that I bring it up here on the dev list.

I had to make some small changes to npapi.h npruntime_internal.h

They changes do essentially two things.

- If XP_DFB is defined include directfb.h and typedef NPEvent to DFBEvent

- Avoid including X11 headers if XP_DFB is defined. 

The problem is that the headers assume that XP_UNIX means X11. I chose
not to introduce XP_X11 which would the cleaner way to do it because I
didn't want to run the risk of breaking other ports of WebKit. If XP_DFB
is not defined there's no change.

This patch essentially makes up a protocol for NPWindow, NPEvent etc for
DirectFB but the protocol is mostly designed by Adobe (who I believe
likely are the only ones who will use this technology) to fit the needs
of Flash but is general enough that it should work for anything. The
code closely resembles the windowless NPAPI implementation for Qt/X11.

How do people feel about this patch? It's already functional and in use
by atleast two major chip manufacturing companies.

regards
-- 
Anders Bakken
-------------- next part --------------
Index: WebCore/ChangeLog
===================================================================
--- WebCore/ChangeLog	(revision 56196)
+++ WebCore/ChangeLog	(working copy)
@@ -1,3 +1,60 @@
+2010-03-18  Anders Bakken  <Anders Bakken <agbakken at gmail.com>>
+
+        Reviewed by NOBODY (OOPS!).
+
+        https://bugs.webkit.org/show_bug.cgi?id=36171
+
+        This contribution enables windowless NPAPI support for Qt/WebKit when
+        using DirectFB. It's been verified to work on MIPS hardware with
+        Flashlite. 
+
+        The code is largely based on the Qt/X11 implementation of windowless
+        NPAPI. It adds the define XP_DFB when enabled to differentiate between
+        X11 and DirectFB when XP_UNIX is defined. This means that npapi.h will
+        function the same way for X11 builds.
+
+        Since the normal use case for NPAPI on DirectFB is for video on sites
+        like youtube it's important to make sure the plugin gets an updated
+        global geometry if the window moves or resizes. This is due to the
+        fact that the video will be rendered into a different layer rather
+        than actually into the offscreen surface that's being rendered to.
+
+        I have a manual test case that I could help people set up for testing
+        with Qt/QWS DirectFB but I don't know how to make it automated.
+
+        To enable NPAPI for DirectFB the developer needs to make sure
+        qmake.conf contains this line:
+
+        DEFINES += ENABLE_NETSCAPE_PLUGIN_API_DIRECTFB
+
+        Qt must also be configured with the -qt-gfx-directfb option (as
+        opposed to -plugin-gfx-directfb)
+
+        * WebCore.pri:
+        * WebCore.pro:
+        * bridge/npapi.h:
+        * bridge/npruntime_internal.h:
+        * plugins/PluginView.cpp:
+        (WebCore::PluginView::stop):
+        (WebCore::PluginView::PluginView):
+        * plugins/PluginView.h:
+        * plugins/qt/PluginViewQt.cpp:
+        (WebCore::PluginView::updatePluginWidget):
+        (WebCore::PluginView::paint):
+        (WebCore::initDirectFBKeyboardEvent):
+        (WebCore::PluginView::handleKeyboardEvent):
+        (WebCore::initDirectFBMouseEvent):
+        (WebCore::PluginView::handleMouseEvent):
+        (WebCore::PluginView::handleFocusInEvent):
+        (WebCore::PluginView::handleFocusOutEvent):
+        (WebCore::WindowMoveEventFilter::WindowMoveEventFilter):
+        (WebCore::WindowMoveEventFilter::eventFilter):
+        (WebCore::WindowMoveEventFilter::timerEvent):
+        (WebCore::PluginView::setNPWindowIfNeeded):
+        (WebCore::PluginView::platformGetValue):
+        (WebCore::PluginView::platformStart):
+        (WebCore::PluginView::platformDestroy):
+
 2010-03-18  David Hyatt  <hyatt at apple.com>
 
         Reviewed by Oliver Hunt.
Index: WebCore/WebCore.pri
===================================================================
--- WebCore/WebCore.pri	(revision 56189)
+++ WebCore/WebCore.pri	(working copy)
@@ -83,6 +83,10 @@ greaterThan(QT_MINOR_VERSION, 5) {
 !contains(DEFINES, ENABLE_TILED_BACKING_STORE=.): DEFINES += ENABLE_TILED_BACKING_STORE=1
 
 # Nescape plugins support (NPAPI)
+contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API_DIRECTFB) {
+    CONFIG += directfb
+    DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
+}
 !contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=.) {
     unix|win32-*:!embedded:!wince*: {
         DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
Index: WebCore/WebCore.pro
===================================================================
--- WebCore/WebCore.pro	(revision 56189)
+++ WebCore/WebCore.pro	(working copy)
@@ -2154,16 +2154,19 @@ contains(DEFINES, ENABLE_NETSCAPE_PLUGIN
                 INCLUDEPATH += platform/mac
                 # Note: XP_MACOSX is defined in npapi.h
             } else {
-                !embedded {
+                directfb {
+                    DEFINES += XP_DFB
+                    QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB
+                    LIBS += $$QT_LIBS_DIRECTFB
+                } else:!embedded {
                     CONFIG += x11
                     LIBS += -lXrender
+                    SOURCES += plugins/qt/PluginContainerQt.cpp
+                    HEADERS += plugins/qt/PluginContainerQt.h
                 }
                 SOURCES += \
-                    plugins/qt/PluginContainerQt.cpp \
                     plugins/qt/PluginPackageQt.cpp \
                     plugins/qt/PluginViewQt.cpp
-                HEADERS += \
-                    plugins/qt/PluginContainerQt.h
                 DEFINES += XP_UNIX
             }
         }
Index: WebCore/bridge/npapi.h
===================================================================
--- WebCore/bridge/npapi.h	(revision 56189)
+++ WebCore/bridge/npapi.h	(working copy)
@@ -101,7 +101,7 @@
 #endif
 #endif
 
-#ifdef XP_UNIX
+#if defined(XP_UNIX) && !defined(XP_DFB)
     #include <X11/Xlib.h>
     #include <X11/Xutil.h>
     #include <stdio.h>
@@ -247,7 +247,7 @@ typedef struct _NPRect
 } NPRect;
 
 
-#ifdef XP_UNIX
+#if defined(XP_UNIX) && !defined(XP_DFB)
 /*
  * Unix specific structures and definitions
  */
@@ -593,6 +593,9 @@ typedef struct _NPEvent
     uint32   wParam;
     uint32   lParam;
 } NPEvent;
+#elif defined (XP_DFB)
+#include <directfb.h>
+typedef DFBEvent NPEvent;
 #elif defined (XP_UNIX)
 typedef XEvent NPEvent;
 #else
@@ -614,7 +617,7 @@ typedef RgnHandle NPQDRegion;
 typedef CGPathRef NPCGRegion;
 #elif defined(XP_WIN)
 typedef HRGN NPRegion;
-#elif defined(XP_UNIX)
+#elif defined(XP_UNIX) && !defined(XP_DFB)
 typedef Region NPRegion;
 #elif defined(XP_SYMBIAN)
 typedef QRegion* NPRegion;
Index: WebCore/bridge/npruntime_internal.h
===================================================================
--- WebCore/bridge/npruntime_internal.h	(revision 56189)
+++ WebCore/bridge/npruntime_internal.h	(working copy)
@@ -29,7 +29,7 @@
 #include "npfunctions.h"
 #include "npruntime.h"
 
-#ifdef XP_UNIX
+#if defined XP_UNIX && !defined(XP_DFB)
     #include <X11/Xresource.h>
 
     #undef None
Index: WebCore/plugins/PluginView.cpp
===================================================================
--- WebCore/plugins/PluginView.cpp	(revision 56189)
+++ WebCore/plugins/PluginView.cpp	(working copy)
@@ -363,7 +363,7 @@ void PluginView::stop()
         PluginView::setCurrentPluginView(0);
     }
 
-#ifdef XP_UNIX
+#if defined(XP_X11) && !defined(XP_DFB)
     if (m_isWindowed && m_npWindow.ws_info)
            delete (NPSetWindowCallbackStruct *)m_npWindow.ws_info;
     m_npWindow.ws_info = 0;
@@ -826,7 +826,7 @@ PluginView::PluginView(Frame* parentFram
     , m_isTransparent(false)
     , m_haveInitialized(false)
     , m_isWaitingToStart(false)
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) && !defined (XP_DFB)
     , m_needsXEmbed(false)
 #endif
 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
@@ -847,10 +847,18 @@ PluginView::PluginView(Frame* parentFram
 #endif
 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
     , m_hasPendingGeometryChange(true)
+#if !defined XP_DFB
     , m_drawable(0)
     , m_visual(0)
     , m_colormap(0)
     , m_pluginDisplay(0)
+#else
+    , m_eventFilter(0)
+    , m_dfbSurface(0)
+    , m_dfb(0)
+    , m_dfbDisplayLayer(0)
+    , m_dfbWindow(0)
+#endif
 #endif
     , m_loadManually(loadManually)
     , m_manualStream(0)
Index: WebCore/plugins/PluginView.h
===================================================================
--- WebCore/plugins/PluginView.h	(revision 56189)
+++ WebCore/plugins/PluginView.h	(working copy)
@@ -44,6 +44,10 @@
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
+#if defined XP_DFB && PLATFORM(QT)
+#include <QPixmap>
+#include <directfb.h>
+#endif
 
 #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX))
 typedef struct HWND__* HWND;
@@ -312,7 +316,7 @@ namespace WebCore {
         bool m_haveInitialized;
         bool m_isWaitingToStart;
 
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) && !defined(XP_DFB)
         bool m_needsXEmbed;
 #endif
 
@@ -362,12 +366,21 @@ private:
 
 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
         bool m_hasPendingGeometryChange;
+#ifndef XP_DFB
         Pixmap m_drawable;
         Visual* m_visual;
         Colormap m_colormap;
         Display* m_pluginDisplay;
 
         void initXEvent(XEvent* event);
+#else
+        QObject *m_eventFilter;
+        QPixmap m_pixmap;
+        IDirectFBSurface *m_dfbSurface;
+        IDirectFB *m_dfb;
+        IDirectFBDisplayLayer *m_dfbDisplayLayer;
+        IDirectFBWindow *m_dfbWindow;
+#endif
 #endif
 
         IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
Index: WebCore/plugins/qt/PluginViewQt.cpp
===================================================================
--- WebCore/plugins/qt/PluginViewQt.cpp	(revision 56189)
+++ WebCore/plugins/qt/PluginViewQt.cpp	(working copy)
@@ -51,7 +51,6 @@
 #include "Page.h"
 #include "PlatformMouseEvent.h"
 #include "PlatformKeyboardEvent.h"
-#include "PluginContainerQt.h"
 #include "PluginDebug.h"
 #include "PluginPackage.h"
 #include "PluginMainThreadScheduler.h"
@@ -67,6 +66,7 @@
 #include <QKeyEvent>
 #include <QPainter>
 #include <QWidget>
+#ifdef Q_WS_X11
 #include <QX11Info>
 #include <X11/X.h>
 #ifndef QT_NO_XRENDER
@@ -74,6 +74,21 @@
 #define Status int
 #include <X11/extensions/Xrender.h>
 #endif
+#elif defined XP_DFB
+#include <QBasicTimer>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+#include <QGraphicsWebView>
+struct DFBWindowInfo {
+    IDirectFB* dfb;
+    IDirectFBDisplayLayer* layer;
+    IDirectFBWindow* window;
+};
+QT_BEGIN_NAMESPACE
+extern Q_GUI_EXPORT IDirectFBSurface* qt_directfb_surface_for_pixmap(const QPixmap &pixmap);
+QT_END_NAMESPACE
+#endif
+
 #include <runtime/JSLock.h>
 #include <runtime/JSValue.h>
 
@@ -109,6 +124,7 @@ void PluginView::updatePluginWidget()
     if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect)
         return;
 
+#ifndef XP_DFB
     if (!m_isWindowed && m_windowRect.size() != oldWindowRect.size()) {
         if (m_drawable)
             XFreePixmap(QX11Info::display(), m_drawable);
@@ -117,6 +133,7 @@ void PluginView::updatePluginWidget()
                                    ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth);
         QApplication::syncX(); // make sure that the server knows about the Drawable
     }
+#endif
 
     // do not call setNPWindowIfNeeded immediately, will be called on paint()
     m_hasPendingGeometryChange = true;
@@ -166,16 +183,16 @@ void PluginView::paint(GraphicsContext* 
 
     setNPWindowIfNeeded();
 
+#ifndef XP_DFB
     if (m_isWindowed || !m_drawable)
         return;
 
-    const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display();
-
     QPainter* painter = context->platformContext();
     IntRect exposedRect(rect);
     exposedRect.intersect(frameRect());
     exposedRect.move(-frameRect().x(), -frameRect().y());
 
+    const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display();
     QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared);
     const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth;
     ASSERT(drawableDepth == qtDrawable.depth());
@@ -234,6 +251,24 @@ void PluginView::paint(GraphicsContext* 
 
     painter->drawPixmap(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), qtDrawable,
                         exposedRect);
+#else
+    DFBEvent dfbEvent;
+    memset(&dfbEvent, 0, sizeof(DFBEvent));
+    DFBUserEvent& userEvent = dfbEvent.user;
+    userEvent.clazz = DFEC_USER;
+    userEvent.type = 0xdfb;
+    userEvent.data = &m_npWindow;
+    dispatchNPEvent(dfbEvent);
+    QPainter* painter = context->platformContext();
+    IntRect exposedRect(rect);
+    exposedRect.intersect(frameRect());
+    exposedRect.move(-frameRect().x(), -frameRect().y());
+    const QPainter::CompositionMode oldMode = painter->compositionMode();
+    painter->setCompositionMode(QPainter::CompositionMode_Source);
+    painter->drawPixmap(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), m_pixmap,
+                        exposedRect);
+    painter->setCompositionMode(oldMode);
+#endif
 }
 
 // TODO: Unify across ports.
@@ -252,6 +287,7 @@ bool PluginView::dispatchNPEvent(NPEvent
     return accepted;
 }
 
+#ifndef XP_DFB
 void setSharedXEventFields(XEvent* xEvent, QWidget* ownerWidget)
 {
     xEvent->xany.serial = 0; // we are unaware of the last request processed by X Server
@@ -293,6 +329,534 @@ void setXKeyEventSpecificFields(XEvent* 
     xEvent->xkey.x_root = 0;
     xEvent->xkey.y_root = 0;
 }
+#else
+static inline void initDirectFBKeyboardEvent(DFBInputEvent* dfbEvent, const QKeyEvent* qtEvent)
+{
+    dfbEvent->clazz = DFEC_INPUT;
+    dfbEvent->type = (qtEvent->type() == QEvent::KeyPress ? DIET_KEYPRESS : DIET_KEYRELEASE);
+    unsigned int flags = (DIEF_KEYSYMBOL | DIEF_MODIFIERS);
+    if (qtEvent->isAutoRepeat())
+        flags |= DIEF_REPEAT;
+    const Qt::KeyboardModifier modifiers[] = { Qt::ShiftModifier, Qt::ControlModifier, Qt::AltModifier, Qt::MetaModifier };
+    const DFBInputDeviceModifierMask dfbModifiers[] = { DIMM_SHIFT, DIMM_CONTROL, DIMM_ALT, DIMM_META };
+    for (int i = 0; i < 4; ++i) {
+        if (qtEvent->modifiers() & modifiers[i])
+            dfbEvent->modifiers = DFBInputDeviceModifierMask(dfbEvent->modifiers | dfbModifiers[i]);
+    }
+    switch (qtEvent->key()) {
+    case Qt::Key_Backspace:
+        dfbEvent->key_symbol = DIKS_BACKSPACE;
+        dfbEvent->key_id = DIKI_BACKSPACE;
+        break;
+    case Qt::Key_Tab:
+        dfbEvent->key_symbol = DIKS_TAB;
+        dfbEvent->key_id = DIKI_TAB;
+        break;
+    case Qt::Key_Return:
+        dfbEvent->key_symbol = DIKS_RETURN;
+        dfbEvent->key_id = DIKI_KP_ENTER;
+        break;
+    case Qt::Key_Escape:
+        dfbEvent->key_symbol = DIKS_ESCAPE;
+        dfbEvent->key_id = DIKI_ESCAPE;
+        break;
+    case Qt::Key_Delete:
+        dfbEvent->key_symbol = DIKS_DELETE;
+        dfbEvent->key_id = DIKI_DELETE;
+        break;
+    case Qt::Key_Left:
+        dfbEvent->key_symbol = DIKS_CURSOR_LEFT;
+        dfbEvent->key_id = DIKI_LEFT;
+        break;
+    case Qt::Key_Right:
+        dfbEvent->key_symbol = DIKS_CURSOR_RIGHT;
+        dfbEvent->key_id = DIKI_RIGHT;
+        break;
+    case Qt::Key_Up:
+        dfbEvent->key_symbol = DIKS_CURSOR_UP;
+        dfbEvent->key_id = DIKI_UP;
+        break;
+    case Qt::Key_Down:
+        dfbEvent->key_symbol = DIKS_CURSOR_DOWN;
+        dfbEvent->key_id = DIKI_DOWN;
+        break;
+    case Qt::Key_Insert:
+        dfbEvent->key_symbol = DIKS_INSERT;
+        dfbEvent->key_id = DIKI_INSERT;
+        break;
+    case Qt::Key_Home:
+        dfbEvent->key_symbol = DIKS_HOME;
+        dfbEvent->key_id = DIKI_HOME;
+        break;
+    case Qt::Key_End:
+        dfbEvent->key_symbol = DIKS_END;
+        dfbEvent->key_id = DIKI_END;
+        break;
+    case Qt::Key_PageUp:
+        dfbEvent->key_symbol = DIKS_PAGE_UP;
+        dfbEvent->key_id = DIKI_PAGE_UP;
+        break;
+    case Qt::Key_PageDown:
+        dfbEvent->key_symbol = DIKS_PAGE_DOWN;
+        dfbEvent->key_id = DIKI_PAGE_DOWN;
+        break;
+    case Qt::Key_Print:
+        dfbEvent->key_symbol = DIKS_PRINT;
+        break;
+    case Qt::Key_Pause:
+        dfbEvent->key_symbol = DIKS_PAUSE;
+        break;
+    case Qt::Key_Select:
+        dfbEvent->key_symbol = DIKS_SELECT;
+        break;
+    case Qt::Key_OpenUrl:
+        dfbEvent->key_symbol = DIKS_GOTO;
+        break;
+    case Qt::Key_Clear:
+        dfbEvent->key_symbol = DIKS_CLEAR;
+        break;
+    case Qt::Key_Menu:
+        dfbEvent->key_symbol = DIKS_MENU;
+        break;
+    case Qt::Key_Help:
+        dfbEvent->key_symbol = DIKS_HELP;
+        break;
+    case Qt::Key_HomePage:
+        dfbEvent->key_symbol = DIKS_INTERNET;
+        break;
+    case Qt::Key_LaunchMail:
+        dfbEvent->key_symbol = DIKS_MAIL;
+        break;
+    case Qt::Key_Favorites:
+        dfbEvent->key_symbol = DIKS_FAVORITES;
+        break;
+    case Qt::Key_Back:
+        dfbEvent->key_symbol = DIKS_BACK;
+        break;
+    case Qt::Key_Forward:
+        dfbEvent->key_symbol = DIKS_FORWARD;
+        break;
+    case Qt::Key_VolumeUp:
+        dfbEvent->key_symbol = DIKS_VOLUME_UP;
+        break;
+    case Qt::Key_VolumeDown:
+        dfbEvent->key_symbol = DIKS_VOLUME_DOWN;
+        break;
+    case Qt::Key_VolumeMute:
+        dfbEvent->key_symbol = DIKS_MUTE;
+        break;
+    case Qt::Key_MediaPlay:
+        dfbEvent->key_symbol = DIKS_PLAY;
+        break;
+    case Qt::Key_MediaStop:
+        dfbEvent->key_symbol = DIKS_STOP;
+        break;
+    case Qt::Key_MediaRecord:
+        dfbEvent->key_symbol = DIKS_RECORD;
+        break;
+    case Qt::Key_MediaPrevious:
+        dfbEvent->key_symbol = DIKS_PREVIOUS;
+        break;
+    case Qt::Key_MediaNext:
+        dfbEvent->key_symbol = DIKS_NEXT;
+        break;
+    case Qt::Key_F1:
+        dfbEvent->key_symbol = DIKS_F1;
+        dfbEvent->key_id = DIKI_F1;
+        break;
+    case Qt::Key_F2:
+        dfbEvent->key_symbol = DIKS_F2;
+        dfbEvent->key_id = DIKI_F2;
+        break;
+    case Qt::Key_F3:
+        dfbEvent->key_symbol = DIKS_F3;
+        dfbEvent->key_id = DIKI_F3;
+        break;
+    case Qt::Key_F4:
+        dfbEvent->key_symbol = DIKS_F4;
+        dfbEvent->key_id = DIKI_F4;
+        break;
+    case Qt::Key_F5:
+        dfbEvent->key_symbol = DIKS_F5;
+        dfbEvent->key_id = DIKI_F5;
+        break;
+    case Qt::Key_F6:
+        dfbEvent->key_symbol = DIKS_F6;
+        dfbEvent->key_id = DIKI_F6;
+        break;
+    case Qt::Key_F7:
+        dfbEvent->key_symbol = DIKS_F7;
+        dfbEvent->key_id = DIKI_F7;
+        break;
+    case Qt::Key_F8:
+        dfbEvent->key_symbol = DIKS_F8;
+        dfbEvent->key_id = DIKI_F8;
+        break;
+    case Qt::Key_F9:
+        dfbEvent->key_symbol = DIKS_F9;
+        dfbEvent->key_id = DIKI_F9;
+        break;
+    case Qt::Key_F10:
+        dfbEvent->key_symbol = DIKS_F10;
+        dfbEvent->key_id = DIKI_F10;
+        break;
+    case Qt::Key_F11:
+        dfbEvent->key_symbol = DIKS_F11;
+        dfbEvent->key_id = DIKI_F11;
+        break;
+    case Qt::Key_F12:
+        dfbEvent->key_symbol = DIKS_F12;
+        dfbEvent->key_id = DIKI_F12;
+        break;
+    case Qt::Key_Shift:
+        dfbEvent->key_symbol = DIKS_SHIFT;
+        dfbEvent->key_id = DIKI_SHIFT_L;
+        break;
+    case Qt::Key_Control:
+        dfbEvent->key_symbol = DIKS_CONTROL;
+        dfbEvent->key_id = DIKI_CONTROL_L;
+        break;
+    case Qt::Key_Alt:
+        dfbEvent->key_symbol = DIKS_ALT;
+        dfbEvent->key_id = DIKI_ALT_L;
+        break;
+    case Qt::Key_AltGr:
+        dfbEvent->key_symbol = DIKS_ALTGR;
+        break;
+    case Qt::Key_Meta:
+        dfbEvent->key_symbol = DIKS_META;
+        dfbEvent->key_id = DIKI_META_L;
+        break;
+    case Qt::Key_Super_L:
+        dfbEvent->key_symbol = DIKS_SUPER;
+        dfbEvent->key_id = DIKI_SUPER_L;
+        break;
+    case Qt::Key_Hyper_L:
+        dfbEvent->key_symbol = DIKS_HYPER;
+        dfbEvent->key_id = DIKI_HYPER_L;
+        break;
+    case Qt::Key_CapsLock:
+        dfbEvent->key_symbol = DIKS_CAPS_LOCK;
+        dfbEvent->key_id = DIKI_CAPS_LOCK;
+        break;
+    case Qt::Key_NumLock:
+        dfbEvent->key_symbol = DIKS_NUM_LOCK;
+        dfbEvent->key_id = DIKI_NUM_LOCK;
+        break;
+    case Qt::Key_ScrollLock:
+        dfbEvent->key_symbol = DIKS_SCROLL_LOCK;
+        dfbEvent->key_id = DIKI_SCROLL_LOCK;
+        break;
+    case Qt::Key_Dead_Abovedot:
+        dfbEvent->key_symbol = DIKS_DEAD_ABOVEDOT;
+        break;
+    case Qt::Key_Dead_Abovering:
+        dfbEvent->key_symbol = DIKS_DEAD_ABOVERING;
+        break;
+    case Qt::Key_Dead_Acute:
+        dfbEvent->key_symbol = DIKS_DEAD_ACUTE;
+        break;
+    case Qt::Key_Dead_Breve:
+        dfbEvent->key_symbol = DIKS_DEAD_BREVE;
+        break;
+    case Qt::Key_Dead_Caron:
+        dfbEvent->key_symbol = DIKS_DEAD_CARON;
+        break;
+    case Qt::Key_Dead_Cedilla:
+        dfbEvent->key_symbol = DIKS_DEAD_CEDILLA;
+        break;
+    case Qt::Key_Dead_Circumflex:
+        dfbEvent->key_symbol = DIKS_DEAD_CIRCUMFLEX;
+        break;
+    case Qt::Key_Dead_Diaeresis:
+        dfbEvent->key_symbol = DIKS_DEAD_DIAERESIS;
+        break;
+    case Qt::Key_Dead_Doubleacute:
+        dfbEvent->key_symbol = DIKS_DEAD_DOUBLEACUTE;
+        break;
+    case Qt::Key_Dead_Grave:
+        dfbEvent->key_symbol = DIKS_DEAD_GRAVE;
+        break;
+    case Qt::Key_Dead_Iota:
+        dfbEvent->key_symbol = DIKS_DEAD_IOTA;
+        break;
+    case Qt::Key_Dead_Macron:
+        dfbEvent->key_symbol = DIKS_DEAD_MACRON;
+        break;
+    case Qt::Key_Dead_Ogonek:
+        dfbEvent->key_symbol = DIKS_DEAD_OGONEK;
+        break;
+    case Qt::Key_Dead_Semivoiced_Sound:
+        dfbEvent->key_symbol = DIKS_DEAD_SEMIVOICED_SOUND;
+        break;
+    case Qt::Key_Dead_Tilde:
+        dfbEvent->key_symbol = DIKS_DEAD_TILDE;
+        break;
+    case Qt::Key_Dead_Voiced_Sound:
+        dfbEvent->key_symbol = DIKS_DEAD_VOICED_SOUND;
+        break;
+    case Qt::Key_Space:
+        dfbEvent->key_symbol = DIKS_SPACE;
+        dfbEvent->key_id = DIKI_SPACE;
+        break;
+    case Qt::Key_Exclam:
+        dfbEvent->key_symbol = DIKS_EXCLAMATION_MARK;
+        break;
+    case Qt::Key_QuoteDbl:
+        dfbEvent->key_symbol = DIKS_QUOTATION;
+        break;
+    case Qt::Key_NumberSign:
+        dfbEvent->key_symbol = DIKS_NUMBER_SIGN;
+        break;
+    case Qt::Key_Dollar:
+        dfbEvent->key_symbol = DIKS_DOLLAR_SIGN;
+        break;
+    case Qt::Key_Percent:
+        dfbEvent->key_symbol = DIKS_PERCENT_SIGN;
+        break;
+    case Qt::Key_Ampersand:
+        dfbEvent->key_symbol = DIKS_AMPERSAND;
+        break;
+    case Qt::Key_Apostrophe:
+        dfbEvent->key_symbol = DIKS_APOSTROPHE;
+        break;
+    case Qt::Key_ParenLeft:
+        dfbEvent->key_symbol = DIKS_PARENTHESIS_LEFT;
+        break;
+    case Qt::Key_ParenRight:
+        dfbEvent->key_symbol = DIKS_PARENTHESIS_RIGHT;
+        break;
+    case Qt::Key_Asterisk:
+        dfbEvent->key_symbol = DIKS_ASTERISK;
+        break;
+    case Qt::Key_Plus:
+        dfbEvent->key_symbol = DIKS_PLUS_SIGN;
+        if (qtEvent->modifiers() & Qt::KeypadModifier)
+            dfbEvent->key_id = DIKI_KP_PLUS;
+        break;
+    case Qt::Key_Comma:
+        dfbEvent->key_symbol = DIKS_COMMA;
+        dfbEvent->key_id = DIKI_COMMA;
+        break;
+    case Qt::Key_Minus:
+        dfbEvent->key_symbol = DIKS_MINUS_SIGN;
+        dfbEvent->key_id = DIKI_MINUS_SIGN;
+        break;
+    case Qt::Key_Period:
+        dfbEvent->key_symbol = DIKS_PERIOD;
+        dfbEvent->key_id = DIKI_PERIOD;
+        break;
+    case Qt::Key_Slash:
+        dfbEvent->key_symbol = DIKS_SLASH;
+        dfbEvent->key_id = DIKI_SLASH;
+        break;
+    case Qt::Key_0:
+        dfbEvent->key_symbol = DIKS_0;
+        dfbEvent->key_id = DIKI_0;
+        break;
+    case Qt::Key_1:
+        dfbEvent->key_symbol = DIKS_1;
+        dfbEvent->key_id = DIKI_1;
+        break;
+    case Qt::Key_2:
+        dfbEvent->key_symbol = DIKS_2;
+        dfbEvent->key_id = DIKI_2;
+        break;
+    case Qt::Key_3:
+        dfbEvent->key_symbol = DIKS_3;
+        dfbEvent->key_id = DIKI_3;
+        break;
+    case Qt::Key_4:
+        dfbEvent->key_symbol = DIKS_4;
+        dfbEvent->key_id = DIKI_4;
+        break;
+    case Qt::Key_5:
+        dfbEvent->key_symbol = DIKS_5;
+        dfbEvent->key_id = DIKI_5;
+        break;
+    case Qt::Key_6:
+        dfbEvent->key_symbol = DIKS_6;
+        dfbEvent->key_id = DIKI_6;
+        break;
+    case Qt::Key_7:
+        dfbEvent->key_symbol = DIKS_7;
+        dfbEvent->key_id = DIKI_7;
+        break;
+    case Qt::Key_8:
+        dfbEvent->key_symbol = DIKS_8;
+        dfbEvent->key_id = DIKI_8;
+        break;
+    case Qt::Key_9:
+        dfbEvent->key_symbol = DIKS_9;
+        dfbEvent->key_id = DIKI_9;
+        break;
+    case Qt::Key_Colon:
+        dfbEvent->key_symbol = DIKS_COLON;
+        break;
+    case Qt::Key_Semicolon:
+        dfbEvent->key_symbol = DIKS_SEMICOLON;
+        dfbEvent->key_id = DIKI_SEMICOLON;
+        break;
+    case Qt::Key_Less:
+        dfbEvent->key_symbol = DIKS_LESS_THAN_SIGN;
+        dfbEvent->key_id = DIKI_LESS_SIGN;
+        break;
+    case Qt::Key_Equal:
+        dfbEvent->key_symbol = DIKS_EQUALS_SIGN;
+        dfbEvent->key_id = DIKI_EQUALS_SIGN;
+        break;
+    case Qt::Key_Greater:
+        dfbEvent->key_symbol = DIKS_GREATER_THAN_SIGN;
+        break;
+    case Qt::Key_Question:
+        dfbEvent->key_symbol = DIKS_QUESTION_MARK;
+        break;
+    case Qt::Key_At:
+        dfbEvent->key_symbol = DIKS_AT;
+        break;
+    case Qt::Key_A:
+        dfbEvent->key_symbol = DIKS_SMALL_A;
+        dfbEvent->key_id = DIKI_A;
+        break;
+    case Qt::Key_B:
+        dfbEvent->key_symbol = DIKS_SMALL_B;
+        dfbEvent->key_id = DIKI_B;
+        break;
+    case Qt::Key_C:
+        dfbEvent->key_symbol = DIKS_SMALL_C;
+        dfbEvent->key_id = DIKI_C;
+        break;
+    case Qt::Key_D:
+        dfbEvent->key_symbol = DIKS_SMALL_D;
+        dfbEvent->key_id = DIKI_D;
+        break;
+    case Qt::Key_E:
+        dfbEvent->key_symbol = DIKS_SMALL_E;
+        dfbEvent->key_id = DIKI_E;
+        break;
+    case Qt::Key_F:
+        dfbEvent->key_symbol = DIKS_SMALL_F;
+        dfbEvent->key_id = DIKI_F;
+        break;
+    case Qt::Key_G:
+        dfbEvent->key_symbol = DIKS_SMALL_G;
+        dfbEvent->key_id = DIKI_G;
+        break;
+    case Qt::Key_H:
+        dfbEvent->key_symbol = DIKS_SMALL_H;
+        dfbEvent->key_id = DIKI_H;
+        break;
+    case Qt::Key_I:
+        dfbEvent->key_symbol = DIKS_SMALL_I;
+        dfbEvent->key_id = DIKI_I;
+        break;
+    case Qt::Key_J:
+        dfbEvent->key_symbol = DIKS_SMALL_J;
+        dfbEvent->key_id = DIKI_J;
+        break;
+    case Qt::Key_K:
+        dfbEvent->key_symbol = DIKS_SMALL_K;
+        dfbEvent->key_id = DIKI_K;
+        break;
+    case Qt::Key_L:
+        dfbEvent->key_symbol = DIKS_SMALL_L;
+        dfbEvent->key_id = DIKI_L;
+        break;
+    case Qt::Key_M:
+        dfbEvent->key_symbol = DIKS_SMALL_M;
+        dfbEvent->key_id = DIKI_M;
+        break;
+    case Qt::Key_N:
+        dfbEvent->key_symbol = DIKS_SMALL_N;
+        dfbEvent->key_id = DIKI_N;
+        break;
+    case Qt::Key_O:
+        dfbEvent->key_symbol = DIKS_SMALL_O;
+        dfbEvent->key_id = DIKI_O;
+        break;
+    case Qt::Key_P:
+        dfbEvent->key_symbol = DIKS_SMALL_P;
+        dfbEvent->key_id = DIKI_P;
+        break;
+    case Qt::Key_Q:
+        dfbEvent->key_symbol = DIKS_SMALL_Q;
+        dfbEvent->key_id = DIKI_Q;
+        break;
+    case Qt::Key_R:
+        dfbEvent->key_symbol = DIKS_SMALL_R;
+        dfbEvent->key_id = DIKI_R;
+        break;
+    case Qt::Key_S:
+        dfbEvent->key_symbol = DIKS_SMALL_S;
+        dfbEvent->key_id = DIKI_S;
+        break;
+    case Qt::Key_T:
+        dfbEvent->key_symbol = DIKS_SMALL_T;
+        dfbEvent->key_id = DIKI_T;
+        break;
+    case Qt::Key_U:
+        dfbEvent->key_symbol = DIKS_SMALL_U;
+        dfbEvent->key_id = DIKI_U;
+        break;
+    case Qt::Key_V:
+        dfbEvent->key_symbol = DIKS_SMALL_V;
+        dfbEvent->key_id = DIKI_V;
+        break;
+    case Qt::Key_W:
+        dfbEvent->key_symbol = DIKS_SMALL_W;
+        dfbEvent->key_id = DIKI_W;
+        break;
+    case Qt::Key_X:
+        dfbEvent->key_symbol = DIKS_SMALL_X;
+        dfbEvent->key_id = DIKI_X;
+        break;
+    case Qt::Key_Y:
+        dfbEvent->key_symbol = DIKS_SMALL_Y;
+        dfbEvent->key_id = DIKI_Y;
+        break;
+    case Qt::Key_Z:
+        dfbEvent->key_symbol = DIKS_SMALL_Z;
+        dfbEvent->key_id = DIKI_Z;
+        break;
+    case Qt::Key_BracketLeft:
+        dfbEvent->key_symbol = DIKS_SQUARE_BRACKET_LEFT;
+        break;
+    case Qt::Key_Backslash:
+        dfbEvent->key_symbol = DIKS_BACKSLASH;
+        dfbEvent->key_id = DIKI_BACKSLASH;
+        break;
+    case Qt::Key_BracketRight:
+        dfbEvent->key_symbol = DIKS_SQUARE_BRACKET_RIGHT;
+        break;
+    case Qt::Key_AsciiCircum:
+        dfbEvent->key_symbol = DIKS_CIRCUMFLEX_ACCENT;
+        break;
+    case Qt::Key_Underscore:
+        dfbEvent->key_symbol = DIKS_UNDERSCORE;
+        break;
+    case Qt::Key_BraceLeft:
+        dfbEvent->key_symbol = DIKS_CURLY_BRACKET_LEFT;
+        break;
+    case Qt::Key_Bar:
+        dfbEvent->key_symbol = DIKS_VERTICAL_BAR;
+        break;
+    case Qt::Key_BraceRight:
+        dfbEvent->key_symbol = DIKS_CURLY_BRACKET_RIGHT;
+        break;
+    case Qt::Key_AsciiTilde:
+        dfbEvent->key_symbol = DIKS_TILDE;
+        break;
+    }
+    if ((qtEvent->modifiers() & Qt::ShiftModifier) && qtEvent->key() >= Qt::Key_A && qtEvent->key() <= Qt::Key_Z)
+        dfbEvent->key_symbol = DFBInputDeviceKeySymbol((dfbEvent->key_symbol - DIKS_SMALL_A) + DIKS_CAPITAL_A);
+    if (dfbEvent->key_id != DIKI_UNKNOWN) {
+        flags = DFBInputEventFlags(dfbEvent->flags | DIEF_KEYID);
+        if (dfbEvent->key_id >= DIKI_0 && dfbEvent->key_id <= DIKI_9 && qtEvent->modifiers() & Qt::KeypadModifier)
+            dfbEvent->key_id = DFBInputDeviceKeyIdentifier(dfbEvent->key_id - DIKI_0 + DIKI_KP_0);
+    }
+    dfbEvent->flags = DFBInputEventFlags(flags);
+}
+#endif
 
 void PluginView::handleKeyboardEvent(KeyboardEvent* event)
 {
@@ -302,14 +866,21 @@ void PluginView::handleKeyboardEvent(Key
     if (event->type() != eventNames().keydownEvent && event->type() != eventNames().keyupEvent)
         return;
 
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
     setXKeyEventSpecificFields(&npEvent, event);
+#else
+    DFBEvent npEvent;
+    DFBInputEvent& input = npEvent.input;
+    initDirectFBKeyboardEvent(&input, event->keyEvent()->qtEvent());
+#endif
 
     if (!dispatchNPEvent(npEvent))
         event->setDefaultHandled();
 }
 
+#ifndef XP_DFB
 static unsigned int inputEventState(MouseEvent* event)
 {
     unsigned int state = 0;
@@ -384,6 +955,45 @@ static void setXCrossingEventSpecificFie
     xcrossing.same_screen = true;
     xcrossing.focus = false;
 }
+#else
+static inline void initDirectFBMouseEvent(DFBWindowEvent* dfbEvent, const MouseEvent* event)
+{
+    dfbEvent->clazz = DFEC_WINDOW;
+
+    unsigned int modifiers = 0;
+    if (event->ctrlKey())
+        modifiers |= DIMM_CONTROL;
+    if (event->shiftKey())
+        modifiers |= DIMM_SHIFT;
+    if (event->altKey())
+        modifiers |= DIMM_ALT;
+    if (event->metaKey())
+        modifiers |= DIMM_META;
+    dfbEvent->modifiers = DFBInputDeviceModifierMask(modifiers);
+
+    if (event->type() == eventNames().mousedownEvent || event->type() == eventNames().mouseupEvent) {
+        dfbEvent->type = (event->type() == eventNames().mousedownEvent ? DWET_BUTTONDOWN : DWET_BUTTONUP);
+        switch (event->button()) {
+        case LeftButton:
+            dfbEvent->button = DIBI_LEFT;
+            break;
+        case MiddleButton:
+            dfbEvent->button = DIBI_MIDDLE;
+            break;
+        case RightButton:
+            dfbEvent->button = DIBI_RIGHT;
+            break;
+        default:
+            break;
+        }
+        dfbEvent->buttons = DFBInputDeviceButtonMask(0);
+    } else if (event->type() == eventNames().mousemoveEvent) {
+        dfbEvent->type = DWET_MOTION;
+    } else {
+        return;
+    }
+}
+#endif
 
 void PluginView::handleMouseEvent(MouseEvent* event)
 {
@@ -397,11 +1007,11 @@ void PluginView::handleMouseEvent(MouseE
 
         focusPluginElement();
     }
-
+    IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation()));
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
 
-    IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation()));
 
     if (event->type() == eventNames().mousedownEvent || event->type() == eventNames().mouseupEvent)
         setXButtonEventSpecificFields(&npEvent, event, postZoomPos);
@@ -411,13 +1021,40 @@ void PluginView::handleMouseEvent(MouseE
         setXCrossingEventSpecificFields(&npEvent, event, postZoomPos);
     else
         return;
+    if (!dispatchNPEvent(npEvent))
+        event->setDefaultHandled();
 
+#else
+    DFBEvent npEvent;
+    memset(&npEvent, 0, sizeof(DFBEvent));
+
+    if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent) {
+        npEvent.clazz = DFEC_WINDOW;
+        npEvent.window.type = (event->type() == eventNames().mouseoverEvent ? DWET_ENTER : DWET_LEAVE);
+        npEvent.window.x = npEvent.window.cx = postZoomPos.x();
+        npEvent.window.y = npEvent.window.cy = postZoomPos.y();
     if (!dispatchNPEvent(npEvent))
         event->setDefaultHandled();
+        return;
+}
+
+    DFBWindowEvent& window = npEvent.window;
+    m_dfbWindow->GetID(m_dfbWindow, &window.window_id);
+    initDirectFBMouseEvent(&window, event);
+    window.x = postZoomPos.x();
+    window.y = postZoomPos.y();
+    const IntPoint absoluteLocation = event->absoluteLocation();
+    window.cx = absoluteLocation.x();
+    window.cy = absoluteLocation.y();
+
+    if (!dispatchNPEvent(npEvent))
+        event->setDefaultHandled();
+#endif
 }
 
 void PluginView::handleFocusInEvent()
 {
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
 
@@ -425,12 +1062,21 @@ void PluginView::handleFocusInEvent()
     event.type = 9; /* int as Qt unsets FocusIn */
     event.mode = NotifyNormal;
     event.detail = NotifyDetailNone;
+    dispatchNPEvent(npEvent);
 
+#else
+    DFBEvent npEvent;
+    memset(&npEvent, 0, sizeof(DFBEvent));
+    DFBWindowEvent& window = npEvent.window;
+    window.clazz = DFEC_WINDOW;
+    window.type = DWET_GOTFOCUS;
     dispatchNPEvent(npEvent);
+#endif
 }
 
 void PluginView::handleFocusOutEvent()
 {
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
 
@@ -440,6 +1086,15 @@ void PluginView::handleFocusOutEvent()
     event.detail = NotifyDetailNone;
 
     dispatchNPEvent(npEvent);
+#else
+    DFBEvent npEvent;
+    memset(&npEvent, 0, sizeof(DFBEvent));
+    DFBWindowEvent& window = npEvent.window;
+    window.clazz = DFEC_WINDOW;
+    window.type = DWET_LOSTFOCUS;
+    dispatchNPEvent(npEvent);
+#endif
+
 }
 
 void PluginView::setParent(ScrollView* parent)
@@ -456,6 +1111,49 @@ void PluginView::setNPWindowRect(const I
         setNPWindowIfNeeded();
 }
 
+#ifdef XP_DFB
+class WindowMoveEventFilter : public QObject {
+public:
+    WindowMoveEventFilter(bool* g, PluginView* view, QWidget* watched)
+        : QObject(0)
+        , m_hasPendingGeometryChange(g)
+        , m_pluginView(view)
+    {
+        Q_ASSERT(watched);
+        forever {
+            watched->installEventFilter(this);
+            if (watched->isWindow())
+                break;
+            watched = watched->parentWidget();
+            if (!watched)
+                break;
+        }
+    }
+
+    bool eventFilter(QObject *, QEvent* e)
+    {
+        if (e->type() == QEvent::Move || e->type() == QEvent::Resize) {
+            *m_hasPendingGeometryChange = true;
+            m_timer.start(10, this);
+        }
+        return false;
+    }
+
+    void timerEvent(QTimerEvent* e)
+    {
+        if (e->timerId() == m_timer.timerId()) {
+            m_timer.stop();
+            m_pluginView->forceRedraw();
+        }
+    }
+private:
+    bool* m_hasPendingGeometryChange;
+    PluginView* m_pluginView;
+    QBasicTimer m_timer;
+};
+
+#endif
+
 void PluginView::setNPWindowIfNeeded()
 {
     if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow)
@@ -492,6 +1190,7 @@ void PluginView::setNPWindowIfNeeded()
         m_npWindow.clipRect.right = m_clipRect.width();
         m_npWindow.clipRect.bottom = m_clipRect.height();
     } else {
+#ifndef XP_DFB
         m_npWindow.x = 0;
         m_npWindow.y = 0;
 
@@ -499,6 +1198,39 @@ void PluginView::setNPWindowIfNeeded()
         m_npWindow.clipRect.top = 0;
         m_npWindow.clipRect.right = 0;
         m_npWindow.clipRect.bottom = 0;
+#else
+        QPoint pluginViewGlobalPos = windowClipRect().topLeft();
+        QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+        if (QWidget* ownerWidget = client ? client->ownerWidget() : 0) {
+            if (!m_eventFilter)
+                m_eventFilter = new WindowMoveEventFilter(&m_hasPendingGeometryChange, this, ownerWidget);
+            pluginViewGlobalPos = ownerWidget->mapToGlobal(pluginViewGlobalPos);
+            if (const QGraphicsWebView* item = qobject_cast<const QGraphicsWebView*>(client->pluginParent())) {
+                Q_ASSERT(item->scene() && !item->scene()->views().isEmpty());
+                const QGraphicsView* view = item->scene()->views().value(0);
+                const QPoint add = view->mapFromScene(item->pos());
+                pluginViewGlobalPos += add;
+    }
+        }
+
+        if ((QSize)(m_windowRect.size()) != m_pixmap.size()) {
+            m_pixmap = QPixmap(m_windowRect.size());
+            m_pixmap.fill(Qt::transparent);
+        }
+
+        m_npWindow.x = pluginViewGlobalPos.x();
+        m_npWindow.y = pluginViewGlobalPos.y();
+        const IntRect frame = frameRect();
+        m_npWindow.width = frame.width();
+        m_npWindow.height = frame.height();
+        m_npWindow.clipRect.top = m_clipRect.y();
+        m_npWindow.clipRect.left = m_clipRect.x();
+        m_npWindow.clipRect.right = m_clipRect.width() + m_clipRect.x() - 1;
+        m_npWindow.clipRect.bottom = m_clipRect.height() + m_clipRect.y() - 1;
+        m_dfbSurface = QT_PREPEND_NAMESPACE(qt_directfb_surface_for_pixmap(m_pixmap));
+        m_npWindow.window = m_dfbSurface;
+        m_npWindow.type = NPWindowTypeDrawable;
+#endif
     }
 
     // FLASH WORKAROUND: Only set initially. Multiple calls to
@@ -584,15 +1316,12 @@ bool PluginView::platformGetValueStatic(
 bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* result)
 {
     switch (variable) {
+#ifndef XP_DFB
     case NPNVxDisplay:
         *(void **)value = QX11Info::display();
         *result = NPERR_NO_ERROR;
         return true;
 
-    case NPNVxtAppContext:
-        *result = NPERR_GENERIC_ERROR;
-        return true;
-
     case NPNVnetscapeWindow: {
         void* w = reinterpret_cast<void*>(value);
         QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
@@ -600,7 +1329,7 @@ bool PluginView::platformGetValue(NPNVar
         *result = NPERR_NO_ERROR;
         return true;
     }
-
+#endif
     case NPNVToolkit:
         if (m_plugin->quirks().contains(PluginQuirkRequiresGtkToolKit)) {
             *((uint32 *)value) = 2;
@@ -645,6 +1374,7 @@ void PluginView::forceRedraw()
     invalidate();
 }
 
+#ifndef XP_DFB
 static Display *getPluginDisplay()
 {
     // The plugin toolkit might run using a different X connection. At the moment, we only
@@ -710,12 +1440,14 @@ static void getVisualAndColormap(int dep
     if (*visual)
         *colormap = XCreateColormap(QX11Info::display(), QX11Info::appRootWindow(), *visual, AllocNone);
 }
+#endif
 
 bool PluginView::platformStart()
 {
     ASSERT(m_isStarted);
     ASSERT(m_status == PluginStatusLoadedSuccessfully);
 
+#ifndef XP_DFB
     if (m_plugin->pluginFuncs()->getvalue) {
         PluginView::setCurrentPluginView(this);
         JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
@@ -740,12 +1472,71 @@ bool PluginView::platformStart()
         setPlatformWidget(0);
         m_pluginDisplay = getPluginDisplay();
     }
+#else
+    if (m_isWindowed) {
+        notImplemented();
+        m_status = PluginStatusCanNotLoadPlugin;
+        return false;
+    }
+    DFBWindowInfo* wsInfo = 0;
+    QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+    if (!client || !client->ownerWidget()) {
+        notImplemented();
+        m_status = PluginStatusCanNotLoadPlugin;
+        return false;
+    }
+
+    DFBResult result = DirectFBCreate(&m_dfb);
+    if (result != DFB_OK)
+        goto end;
+
+    result = m_dfb->GetDisplayLayer(m_dfb, DLID_PRIMARY, &m_dfbDisplayLayer);
+    if (result != DFB_OK)
+        goto end;
+
+    result = m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,
+                                          static_cast<DFBWindowID>(client->ownerWidget()->property("_q_DirectFBWindowID").toInt()),
+                                          &m_dfbWindow);
+    if (result != DFB_OK)
+        goto end;
+    wsInfo = new DFBWindowInfo;
+    wsInfo->dfb = m_dfb;
+    wsInfo->window = m_dfbWindow;
+    wsInfo->layer = m_dfbDisplayLayer;
+    m_npWindow.ws_info = wsInfo;
+    m_npWindow.type = NPWindowTypeDrawable;
+    m_npWindow.window = 0; // Not used?
+    m_npWindow.x = 0;
+    m_npWindow.y = 0;
+    m_npWindow.width = -1;
+    m_npWindow.height = -1;
+
+end:
+    if (result != DFB_OK) {
+        if (m_dfbWindow) {
+            m_dfbWindow->Release(m_dfbWindow);
+            m_dfbWindow = 0;
+        }
+
+        if (m_dfbDisplayLayer)
+            m_dfbDisplayLayer->Release(m_dfbDisplayLayer);
+
+        if (m_dfb) {
+            m_dfb->Release(m_dfb);
+            m_dfb = 0;
+        }
+        DirectFBError("PluginView::platformStart()", result);
+        notImplemented();
+        m_status = PluginStatusCanNotLoadPlugin;
+        return false;
+    }
+#endif
 
     show();
 
+#ifndef XP_DFB
     NPSetWindowCallbackStruct* wsi = new NPSetWindowCallbackStruct();
     wsi->type = 0;
-
     if (m_isWindowed) {
         const QX11Info* x11Info = &platformPluginWidget()->x11Info();
 
@@ -753,7 +1544,6 @@ bool PluginView::platformStart()
         wsi->visual = (Visual*)x11Info->visual();
         wsi->depth = x11Info->depth();
         wsi->colormap = x11Info->colormap();
-
         m_npWindow.type = NPWindowTypeWindow;
         m_npWindow.window = (void*)platformPluginWidget()->winId();
         m_npWindow.width = -1;
@@ -782,8 +1572,8 @@ bool PluginView::platformStart()
         m_npWindow.width = -1;
         m_npWindow.height = -1;
     }
-
     m_npWindow.ws_info = wsi;
+#endif
 
     if (!(m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall))) {
         updatePluginWidget();
@@ -798,11 +1588,33 @@ void PluginView::platformDestroy()
     if (platformPluginWidget())
         delete platformPluginWidget();
 
+#ifndef XP_DFB
     if (m_drawable)
         XFreePixmap(QX11Info::display(), m_drawable);
 
     if (m_colormap)
         XFreeColormap(QX11Info::display(), m_colormap);
+#else
+    delete m_eventFilter;
+    m_eventFilter = 0;
+    delete static_cast<DFBWindowInfo*>(m_npWindow.ws_info);
+    m_npWindow.ws_info = 0;
+    m_pixmap = QPixmap();
+    if (m_dfbWindow) {
+        m_dfbWindow->Release(m_dfbWindow);
+        m_dfbWindow = 0;
+}
+
+    if (m_dfbDisplayLayer) {
+        m_dfbDisplayLayer->Release(m_dfbDisplayLayer);
+        m_dfbDisplayLayer = 0;
+    }
+
+    if (m_dfb) {
+        m_dfb->Release(m_dfb);
+        m_dfb = 0;
+    }
+#endif
 }
 
 void PluginView::halt()
Index: WebCore/ChangeLog
===================================================================
--- WebCore/ChangeLog	(revision 56196)
+++ WebCore/ChangeLog	(working copy)
@@ -1,3 +1,60 @@
+2010-03-18  Anders Bakken  <Anders Bakken <agbakken at gmail.com>>
+
+        Reviewed by NOBODY (OOPS!).
+
+        https://bugs.webkit.org/show_bug.cgi?id=36171
+
+        This contribution enables windowless NPAPI support for Qt/WebKit when
+        using DirectFB. It's been verified to work on MIPS hardware with
+        Flashlite. 
+
+        The code is largely based on the Qt/X11 implementation of windowless
+        NPAPI. It adds the define XP_DFB when enabled to differentiate between
+        X11 and DirectFB when XP_UNIX is defined. This means that npapi.h will
+        function the same way for X11 builds.
+
+        Since the normal use case for NPAPI on DirectFB is for video on sites
+        like youtube it's important to make sure the plugin gets an updated
+        global geometry if the window moves or resizes. This is due to the
+        fact that the video will be rendered into a different layer rather
+        than actually into the offscreen surface that's being rendered to.
+
+        I have a manual test case that I could help people set up for testing
+        with Qt/QWS DirectFB but I don't know how to make it automated.
+
+        To enable NPAPI for DirectFB the developer needs to make sure
+        qmake.conf contains this line:
+
+        DEFINES += ENABLE_NETSCAPE_PLUGIN_API_DIRECTFB
+
+        Qt must also be configured with the -qt-gfx-directfb option (as
+        opposed to -plugin-gfx-directfb)
+
+        * WebCore.pri:
+        * WebCore.pro:
+        * bridge/npapi.h:
+        * bridge/npruntime_internal.h:
+        * plugins/PluginView.cpp:
+        (WebCore::PluginView::stop):
+        (WebCore::PluginView::PluginView):
+        * plugins/PluginView.h:
+        * plugins/qt/PluginViewQt.cpp:
+        (WebCore::PluginView::updatePluginWidget):
+        (WebCore::PluginView::paint):
+        (WebCore::initDirectFBKeyboardEvent):
+        (WebCore::PluginView::handleKeyboardEvent):
+        (WebCore::initDirectFBMouseEvent):
+        (WebCore::PluginView::handleMouseEvent):
+        (WebCore::PluginView::handleFocusInEvent):
+        (WebCore::PluginView::handleFocusOutEvent):
+        (WebCore::WindowMoveEventFilter::WindowMoveEventFilter):
+        (WebCore::WindowMoveEventFilter::eventFilter):
+        (WebCore::WindowMoveEventFilter::timerEvent):
+        (WebCore::PluginView::setNPWindowIfNeeded):
+        (WebCore::PluginView::platformGetValue):
+        (WebCore::PluginView::platformStart):
+        (WebCore::PluginView::platformDestroy):
+
 2010-03-18  David Hyatt  <hyatt at apple.com>
 
         Reviewed by Oliver Hunt.
Index: WebCore/WebCore.pri
===================================================================
--- WebCore/WebCore.pri	(revision 56189)
+++ WebCore/WebCore.pri	(working copy)
@@ -83,6 +83,10 @@ greaterThan(QT_MINOR_VERSION, 5) {
 !contains(DEFINES, ENABLE_TILED_BACKING_STORE=.): DEFINES += ENABLE_TILED_BACKING_STORE=1
 
 # Nescape plugins support (NPAPI)
+contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API_DIRECTFB) {
+    CONFIG += directfb
+    DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
+}
 !contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=.) {
     unix|win32-*:!embedded:!wince*: {
         DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
Index: WebCore/WebCore.pro
===================================================================
--- WebCore/WebCore.pro	(revision 56189)
+++ WebCore/WebCore.pro	(working copy)
@@ -2154,16 +2154,19 @@ contains(DEFINES, ENABLE_NETSCAPE_PLUGIN
                 INCLUDEPATH += platform/mac
                 # Note: XP_MACOSX is defined in npapi.h
             } else {
-                !embedded {
+                directfb {
+                    DEFINES += XP_DFB
+                    QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB
+                    LIBS += $$QT_LIBS_DIRECTFB
+                } else:!embedded {
                     CONFIG += x11
                     LIBS += -lXrender
+                    SOURCES += plugins/qt/PluginContainerQt.cpp
+                    HEADERS += plugins/qt/PluginContainerQt.h
                 }
                 SOURCES += \
-                    plugins/qt/PluginContainerQt.cpp \
                     plugins/qt/PluginPackageQt.cpp \
                     plugins/qt/PluginViewQt.cpp
-                HEADERS += \
-                    plugins/qt/PluginContainerQt.h
                 DEFINES += XP_UNIX
             }
         }
Index: WebCore/bridge/npapi.h
===================================================================
--- WebCore/bridge/npapi.h	(revision 56189)
+++ WebCore/bridge/npapi.h	(working copy)
@@ -101,7 +101,7 @@
 #endif
 #endif
 
-#ifdef XP_UNIX
+#if defined(XP_UNIX) && !defined(XP_DFB)
     #include <X11/Xlib.h>
     #include <X11/Xutil.h>
     #include <stdio.h>
@@ -247,7 +247,7 @@ typedef struct _NPRect
 } NPRect;
 
 
-#ifdef XP_UNIX
+#if defined(XP_UNIX) && !defined(XP_DFB)
 /*
  * Unix specific structures and definitions
  */
@@ -593,7 +593,10 @@ typedef struct _NPEvent
     uint32   wParam;
     uint32   lParam;
 } NPEvent;
-#elif defined (XP_UNIX)
+#elif defined(XP_DFB)
+#include <directfb.h>
+typedef DFBEvent NPEvent;
+#elif defined(XP_UNIX)
 typedef XEvent NPEvent;
 #else
 typedef void*            NPEvent;
@@ -614,7 +617,7 @@ typedef RgnHandle NPQDRegion;
 typedef CGPathRef NPCGRegion;
 #elif defined(XP_WIN)
 typedef HRGN NPRegion;
-#elif defined(XP_UNIX)
+#elif defined(XP_UNIX) && !defined(XP_DFB)
 typedef Region NPRegion;
 #elif defined(XP_SYMBIAN)
 typedef QRegion* NPRegion;
Index: WebCore/bridge/npruntime_internal.h
===================================================================
--- WebCore/bridge/npruntime_internal.h	(revision 56189)
+++ WebCore/bridge/npruntime_internal.h	(working copy)
@@ -29,7 +29,7 @@
 #include "npfunctions.h"
 #include "npruntime.h"
 
-#ifdef XP_UNIX
+#if defined XP_UNIX && !defined(XP_DFB)
     #include <X11/Xresource.h>
 
     #undef None
Index: WebCore/plugins/PluginView.cpp
===================================================================
--- WebCore/plugins/PluginView.cpp	(revision 56189)
+++ WebCore/plugins/PluginView.cpp	(working copy)
@@ -363,7 +363,7 @@ void PluginView::stop()
         PluginView::setCurrentPluginView(0);
     }
 
-#ifdef XP_UNIX
+#if defined(XP_X11) && !defined(XP_DFB)
     if (m_isWindowed && m_npWindow.ws_info)
            delete (NPSetWindowCallbackStruct *)m_npWindow.ws_info;
     m_npWindow.ws_info = 0;
@@ -826,7 +826,7 @@ PluginView::PluginView(Frame* parentFram
     , m_isTransparent(false)
     , m_haveInitialized(false)
     , m_isWaitingToStart(false)
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) && !defined (XP_DFB)
     , m_needsXEmbed(false)
 #endif
 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
@@ -847,10 +847,18 @@ PluginView::PluginView(Frame* parentFram
 #endif
 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
     , m_hasPendingGeometryChange(true)
+#if !defined XP_DFB
     , m_drawable(0)
     , m_visual(0)
     , m_colormap(0)
     , m_pluginDisplay(0)
+#else
+    , m_eventFilter(0)
+    , m_dfbSurface(0)
+    , m_dfb(0)
+    , m_dfbDisplayLayer(0)
+    , m_dfbWindow(0)
+#endif
 #endif
     , m_loadManually(loadManually)
     , m_manualStream(0)
Index: WebCore/plugins/PluginView.h
===================================================================
--- WebCore/plugins/PluginView.h	(revision 56189)
+++ WebCore/plugins/PluginView.h	(working copy)
@@ -44,6 +44,10 @@
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
+#if defined XP_DFB && PLATFORM(QT)
+#include <QPixmap>
+#include <directfb.h>
+#endif
 
 #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX))
 typedef struct HWND__* HWND;
@@ -312,7 +316,7 @@ namespace WebCore {
         bool m_haveInitialized;
         bool m_isWaitingToStart;
 
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) && !defined(XP_DFB)
         bool m_needsXEmbed;
 #endif
 
@@ -362,12 +366,21 @@ private:
 
 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
         bool m_hasPendingGeometryChange;
+#ifndef XP_DFB
         Pixmap m_drawable;
         Visual* m_visual;
         Colormap m_colormap;
         Display* m_pluginDisplay;
 
         void initXEvent(XEvent* event);
+#else
+        QObject *m_eventFilter;
+        QPixmap m_pixmap;
+        IDirectFBSurface *m_dfbSurface;
+        IDirectFB *m_dfb;
+        IDirectFBDisplayLayer *m_dfbDisplayLayer;
+        IDirectFBWindow *m_dfbWindow;
+#endif
 #endif
 
         IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
Index: WebCore/plugins/qt/PluginViewQt.cpp
===================================================================
--- WebCore/plugins/qt/PluginViewQt.cpp	(revision 56189)
+++ WebCore/plugins/qt/PluginViewQt.cpp	(working copy)
@@ -51,7 +51,6 @@
 #include "Page.h"
 #include "PlatformMouseEvent.h"
 #include "PlatformKeyboardEvent.h"
-#include "PluginContainerQt.h"
 #include "PluginDebug.h"
 #include "PluginPackage.h"
 #include "PluginMainThreadScheduler.h"
@@ -67,6 +66,7 @@
 #include <QKeyEvent>
 #include <QPainter>
 #include <QWidget>
+#ifdef Q_WS_X11
 #include <QX11Info>
 #include <X11/X.h>
 #ifndef QT_NO_XRENDER
@@ -74,6 +74,21 @@
 #define Status int
 #include <X11/extensions/Xrender.h>
 #endif
+#elif defined XP_DFB
+#include <QBasicTimer>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+#include <QGraphicsWebView>
+struct DFBWindowInfo {
+    IDirectFB* dfb;
+    IDirectFBDisplayLayer* layer;
+    IDirectFBWindow* window;
+};
+QT_BEGIN_NAMESPACE
+extern Q_GUI_EXPORT IDirectFBSurface* qt_directfb_surface_for_pixmap(const QPixmap &pixmap);
+QT_END_NAMESPACE
+#endif
+
 #include <runtime/JSLock.h>
 #include <runtime/JSValue.h>
 
@@ -109,6 +124,7 @@ void PluginView::updatePluginWidget()
     if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect)
         return;
 
+#ifndef XP_DFB
     if (!m_isWindowed && m_windowRect.size() != oldWindowRect.size()) {
         if (m_drawable)
             XFreePixmap(QX11Info::display(), m_drawable);
@@ -117,6 +133,7 @@ void PluginView::updatePluginWidget()
                                    ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth);
         QApplication::syncX(); // make sure that the server knows about the Drawable
     }
+#endif
 
     // do not call setNPWindowIfNeeded immediately, will be called on paint()
     m_hasPendingGeometryChange = true;
@@ -166,16 +183,16 @@ void PluginView::paint(GraphicsContext* 
 
     setNPWindowIfNeeded();
 
+#ifndef XP_DFB
     if (m_isWindowed || !m_drawable)
         return;
 
-    const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display();
-
     QPainter* painter = context->platformContext();
     IntRect exposedRect(rect);
     exposedRect.intersect(frameRect());
     exposedRect.move(-frameRect().x(), -frameRect().y());
 
+    const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display();
     QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared);
     const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth;
     ASSERT(drawableDepth == qtDrawable.depth());
@@ -234,6 +251,24 @@ void PluginView::paint(GraphicsContext* 
 
     painter->drawPixmap(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), qtDrawable,
                         exposedRect);
+#else
+    DFBEvent dfbEvent;
+    memset(&dfbEvent, 0, sizeof(DFBEvent));
+    DFBUserEvent& userEvent = dfbEvent.user;
+    userEvent.clazz = DFEC_USER;
+    userEvent.type = 0xdfb;
+    userEvent.data = &m_npWindow;
+    dispatchNPEvent(dfbEvent);
+    QPainter* painter = context->platformContext();
+    IntRect exposedRect(rect);
+    exposedRect.intersect(frameRect());
+    exposedRect.move(-frameRect().x(), -frameRect().y());
+    const QPainter::CompositionMode oldMode = painter->compositionMode();
+    painter->setCompositionMode(QPainter::CompositionMode_Source);
+    painter->drawPixmap(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), m_pixmap,
+                        exposedRect);
+    painter->setCompositionMode(oldMode);
+#endif
 }
 
 // TODO: Unify across ports.
@@ -252,6 +287,7 @@ bool PluginView::dispatchNPEvent(NPEvent
     return accepted;
 }
 
+#ifndef XP_DFB
 void setSharedXEventFields(XEvent* xEvent, QWidget* ownerWidget)
 {
     xEvent->xany.serial = 0; // we are unaware of the last request processed by X Server
@@ -293,6 +329,534 @@ void setXKeyEventSpecificFields(XEvent* 
     xEvent->xkey.x_root = 0;
     xEvent->xkey.y_root = 0;
 }
+#else
+static inline void initDirectFBKeyboardEvent(DFBInputEvent* dfbEvent, const QKeyEvent* qtEvent)
+{
+    dfbEvent->clazz = DFEC_INPUT;
+    dfbEvent->type = (qtEvent->type() == QEvent::KeyPress ? DIET_KEYPRESS : DIET_KEYRELEASE);
+    unsigned int flags = (DIEF_KEYSYMBOL | DIEF_MODIFIERS);
+    if (qtEvent->isAutoRepeat())
+        flags |= DIEF_REPEAT;
+    const Qt::KeyboardModifier modifiers[] = { Qt::ShiftModifier, Qt::ControlModifier, Qt::AltModifier, Qt::MetaModifier };
+    const DFBInputDeviceModifierMask dfbModifiers[] = { DIMM_SHIFT, DIMM_CONTROL, DIMM_ALT, DIMM_META };
+    for (int i = 0; i < 4; ++i) {
+        if (qtEvent->modifiers() & modifiers[i])
+            dfbEvent->modifiers = DFBInputDeviceModifierMask(dfbEvent->modifiers | dfbModifiers[i]);
+    }
+    switch (qtEvent->key()) {
+    case Qt::Key_Backspace:
+        dfbEvent->key_symbol = DIKS_BACKSPACE;
+        dfbEvent->key_id = DIKI_BACKSPACE;
+        break;
+    case Qt::Key_Tab:
+        dfbEvent->key_symbol = DIKS_TAB;
+        dfbEvent->key_id = DIKI_TAB;
+        break;
+    case Qt::Key_Return:
+        dfbEvent->key_symbol = DIKS_RETURN;
+        dfbEvent->key_id = DIKI_KP_ENTER;
+        break;
+    case Qt::Key_Escape:
+        dfbEvent->key_symbol = DIKS_ESCAPE;
+        dfbEvent->key_id = DIKI_ESCAPE;
+        break;
+    case Qt::Key_Delete:
+        dfbEvent->key_symbol = DIKS_DELETE;
+        dfbEvent->key_id = DIKI_DELETE;
+        break;
+    case Qt::Key_Left:
+        dfbEvent->key_symbol = DIKS_CURSOR_LEFT;
+        dfbEvent->key_id = DIKI_LEFT;
+        break;
+    case Qt::Key_Right:
+        dfbEvent->key_symbol = DIKS_CURSOR_RIGHT;
+        dfbEvent->key_id = DIKI_RIGHT;
+        break;
+    case Qt::Key_Up:
+        dfbEvent->key_symbol = DIKS_CURSOR_UP;
+        dfbEvent->key_id = DIKI_UP;
+        break;
+    case Qt::Key_Down:
+        dfbEvent->key_symbol = DIKS_CURSOR_DOWN;
+        dfbEvent->key_id = DIKI_DOWN;
+        break;
+    case Qt::Key_Insert:
+        dfbEvent->key_symbol = DIKS_INSERT;
+        dfbEvent->key_id = DIKI_INSERT;
+        break;
+    case Qt::Key_Home:
+        dfbEvent->key_symbol = DIKS_HOME;
+        dfbEvent->key_id = DIKI_HOME;
+        break;
+    case Qt::Key_End:
+        dfbEvent->key_symbol = DIKS_END;
+        dfbEvent->key_id = DIKI_END;
+        break;
+    case Qt::Key_PageUp:
+        dfbEvent->key_symbol = DIKS_PAGE_UP;
+        dfbEvent->key_id = DIKI_PAGE_UP;
+        break;
+    case Qt::Key_PageDown:
+        dfbEvent->key_symbol = DIKS_PAGE_DOWN;
+        dfbEvent->key_id = DIKI_PAGE_DOWN;
+        break;
+    case Qt::Key_Print:
+        dfbEvent->key_symbol = DIKS_PRINT;
+        break;
+    case Qt::Key_Pause:
+        dfbEvent->key_symbol = DIKS_PAUSE;
+        break;
+    case Qt::Key_Select:
+        dfbEvent->key_symbol = DIKS_SELECT;
+        break;
+    case Qt::Key_OpenUrl:
+        dfbEvent->key_symbol = DIKS_GOTO;
+        break;
+    case Qt::Key_Clear:
+        dfbEvent->key_symbol = DIKS_CLEAR;
+        break;
+    case Qt::Key_Menu:
+        dfbEvent->key_symbol = DIKS_MENU;
+        break;
+    case Qt::Key_Help:
+        dfbEvent->key_symbol = DIKS_HELP;
+        break;
+    case Qt::Key_HomePage:
+        dfbEvent->key_symbol = DIKS_INTERNET;
+        break;
+    case Qt::Key_LaunchMail:
+        dfbEvent->key_symbol = DIKS_MAIL;
+        break;
+    case Qt::Key_Favorites:
+        dfbEvent->key_symbol = DIKS_FAVORITES;
+        break;
+    case Qt::Key_Back:
+        dfbEvent->key_symbol = DIKS_BACK;
+        break;
+    case Qt::Key_Forward:
+        dfbEvent->key_symbol = DIKS_FORWARD;
+        break;
+    case Qt::Key_VolumeUp:
+        dfbEvent->key_symbol = DIKS_VOLUME_UP;
+        break;
+    case Qt::Key_VolumeDown:
+        dfbEvent->key_symbol = DIKS_VOLUME_DOWN;
+        break;
+    case Qt::Key_VolumeMute:
+        dfbEvent->key_symbol = DIKS_MUTE;
+        break;
+    case Qt::Key_MediaPlay:
+        dfbEvent->key_symbol = DIKS_PLAY;
+        break;
+    case Qt::Key_MediaStop:
+        dfbEvent->key_symbol = DIKS_STOP;
+        break;
+    case Qt::Key_MediaRecord:
+        dfbEvent->key_symbol = DIKS_RECORD;
+        break;
+    case Qt::Key_MediaPrevious:
+        dfbEvent->key_symbol = DIKS_PREVIOUS;
+        break;
+    case Qt::Key_MediaNext:
+        dfbEvent->key_symbol = DIKS_NEXT;
+        break;
+    case Qt::Key_F1:
+        dfbEvent->key_symbol = DIKS_F1;
+        dfbEvent->key_id = DIKI_F1;
+        break;
+    case Qt::Key_F2:
+        dfbEvent->key_symbol = DIKS_F2;
+        dfbEvent->key_id = DIKI_F2;
+        break;
+    case Qt::Key_F3:
+        dfbEvent->key_symbol = DIKS_F3;
+        dfbEvent->key_id = DIKI_F3;
+        break;
+    case Qt::Key_F4:
+        dfbEvent->key_symbol = DIKS_F4;
+        dfbEvent->key_id = DIKI_F4;
+        break;
+    case Qt::Key_F5:
+        dfbEvent->key_symbol = DIKS_F5;
+        dfbEvent->key_id = DIKI_F5;
+        break;
+    case Qt::Key_F6:
+        dfbEvent->key_symbol = DIKS_F6;
+        dfbEvent->key_id = DIKI_F6;
+        break;
+    case Qt::Key_F7:
+        dfbEvent->key_symbol = DIKS_F7;
+        dfbEvent->key_id = DIKI_F7;
+        break;
+    case Qt::Key_F8:
+        dfbEvent->key_symbol = DIKS_F8;
+        dfbEvent->key_id = DIKI_F8;
+        break;
+    case Qt::Key_F9:
+        dfbEvent->key_symbol = DIKS_F9;
+        dfbEvent->key_id = DIKI_F9;
+        break;
+    case Qt::Key_F10:
+        dfbEvent->key_symbol = DIKS_F10;
+        dfbEvent->key_id = DIKI_F10;
+        break;
+    case Qt::Key_F11:
+        dfbEvent->key_symbol = DIKS_F11;
+        dfbEvent->key_id = DIKI_F11;
+        break;
+    case Qt::Key_F12:
+        dfbEvent->key_symbol = DIKS_F12;
+        dfbEvent->key_id = DIKI_F12;
+        break;
+    case Qt::Key_Shift:
+        dfbEvent->key_symbol = DIKS_SHIFT;
+        dfbEvent->key_id = DIKI_SHIFT_L;
+        break;
+    case Qt::Key_Control:
+        dfbEvent->key_symbol = DIKS_CONTROL;
+        dfbEvent->key_id = DIKI_CONTROL_L;
+        break;
+    case Qt::Key_Alt:
+        dfbEvent->key_symbol = DIKS_ALT;
+        dfbEvent->key_id = DIKI_ALT_L;
+        break;
+    case Qt::Key_AltGr:
+        dfbEvent->key_symbol = DIKS_ALTGR;
+        break;
+    case Qt::Key_Meta:
+        dfbEvent->key_symbol = DIKS_META;
+        dfbEvent->key_id = DIKI_META_L;
+        break;
+    case Qt::Key_Super_L:
+        dfbEvent->key_symbol = DIKS_SUPER;
+        dfbEvent->key_id = DIKI_SUPER_L;
+        break;
+    case Qt::Key_Hyper_L:
+        dfbEvent->key_symbol = DIKS_HYPER;
+        dfbEvent->key_id = DIKI_HYPER_L;
+        break;
+    case Qt::Key_CapsLock:
+        dfbEvent->key_symbol = DIKS_CAPS_LOCK;
+        dfbEvent->key_id = DIKI_CAPS_LOCK;
+        break;
+    case Qt::Key_NumLock:
+        dfbEvent->key_symbol = DIKS_NUM_LOCK;
+        dfbEvent->key_id = DIKI_NUM_LOCK;
+        break;
+    case Qt::Key_ScrollLock:
+        dfbEvent->key_symbol = DIKS_SCROLL_LOCK;
+        dfbEvent->key_id = DIKI_SCROLL_LOCK;
+        break;
+    case Qt::Key_Dead_Abovedot:
+        dfbEvent->key_symbol = DIKS_DEAD_ABOVEDOT;
+        break;
+    case Qt::Key_Dead_Abovering:
+        dfbEvent->key_symbol = DIKS_DEAD_ABOVERING;
+        break;
+    case Qt::Key_Dead_Acute:
+        dfbEvent->key_symbol = DIKS_DEAD_ACUTE;
+        break;
+    case Qt::Key_Dead_Breve:
+        dfbEvent->key_symbol = DIKS_DEAD_BREVE;
+        break;
+    case Qt::Key_Dead_Caron:
+        dfbEvent->key_symbol = DIKS_DEAD_CARON;
+        break;
+    case Qt::Key_Dead_Cedilla:
+        dfbEvent->key_symbol = DIKS_DEAD_CEDILLA;
+        break;
+    case Qt::Key_Dead_Circumflex:
+        dfbEvent->key_symbol = DIKS_DEAD_CIRCUMFLEX;
+        break;
+    case Qt::Key_Dead_Diaeresis:
+        dfbEvent->key_symbol = DIKS_DEAD_DIAERESIS;
+        break;
+    case Qt::Key_Dead_Doubleacute:
+        dfbEvent->key_symbol = DIKS_DEAD_DOUBLEACUTE;
+        break;
+    case Qt::Key_Dead_Grave:
+        dfbEvent->key_symbol = DIKS_DEAD_GRAVE;
+        break;
+    case Qt::Key_Dead_Iota:
+        dfbEvent->key_symbol = DIKS_DEAD_IOTA;
+        break;
+    case Qt::Key_Dead_Macron:
+        dfbEvent->key_symbol = DIKS_DEAD_MACRON;
+        break;
+    case Qt::Key_Dead_Ogonek:
+        dfbEvent->key_symbol = DIKS_DEAD_OGONEK;
+        break;
+    case Qt::Key_Dead_Semivoiced_Sound:
+        dfbEvent->key_symbol = DIKS_DEAD_SEMIVOICED_SOUND;
+        break;
+    case Qt::Key_Dead_Tilde:
+        dfbEvent->key_symbol = DIKS_DEAD_TILDE;
+        break;
+    case Qt::Key_Dead_Voiced_Sound:
+        dfbEvent->key_symbol = DIKS_DEAD_VOICED_SOUND;
+        break;
+    case Qt::Key_Space:
+        dfbEvent->key_symbol = DIKS_SPACE;
+        dfbEvent->key_id = DIKI_SPACE;
+        break;
+    case Qt::Key_Exclam:
+        dfbEvent->key_symbol = DIKS_EXCLAMATION_MARK;
+        break;
+    case Qt::Key_QuoteDbl:
+        dfbEvent->key_symbol = DIKS_QUOTATION;
+        break;
+    case Qt::Key_NumberSign:
+        dfbEvent->key_symbol = DIKS_NUMBER_SIGN;
+        break;
+    case Qt::Key_Dollar:
+        dfbEvent->key_symbol = DIKS_DOLLAR_SIGN;
+        break;
+    case Qt::Key_Percent:
+        dfbEvent->key_symbol = DIKS_PERCENT_SIGN;
+        break;
+    case Qt::Key_Ampersand:
+        dfbEvent->key_symbol = DIKS_AMPERSAND;
+        break;
+    case Qt::Key_Apostrophe:
+        dfbEvent->key_symbol = DIKS_APOSTROPHE;
+        break;
+    case Qt::Key_ParenLeft:
+        dfbEvent->key_symbol = DIKS_PARENTHESIS_LEFT;
+        break;
+    case Qt::Key_ParenRight:
+        dfbEvent->key_symbol = DIKS_PARENTHESIS_RIGHT;
+        break;
+    case Qt::Key_Asterisk:
+        dfbEvent->key_symbol = DIKS_ASTERISK;
+        break;
+    case Qt::Key_Plus:
+        dfbEvent->key_symbol = DIKS_PLUS_SIGN;
+        if (qtEvent->modifiers() & Qt::KeypadModifier)
+            dfbEvent->key_id = DIKI_KP_PLUS;
+        break;
+    case Qt::Key_Comma:
+        dfbEvent->key_symbol = DIKS_COMMA;
+        dfbEvent->key_id = DIKI_COMMA;
+        break;
+    case Qt::Key_Minus:
+        dfbEvent->key_symbol = DIKS_MINUS_SIGN;
+        dfbEvent->key_id = DIKI_MINUS_SIGN;
+        break;
+    case Qt::Key_Period:
+        dfbEvent->key_symbol = DIKS_PERIOD;
+        dfbEvent->key_id = DIKI_PERIOD;
+        break;
+    case Qt::Key_Slash:
+        dfbEvent->key_symbol = DIKS_SLASH;
+        dfbEvent->key_id = DIKI_SLASH;
+        break;
+    case Qt::Key_0:
+        dfbEvent->key_symbol = DIKS_0;
+        dfbEvent->key_id = DIKI_0;
+        break;
+    case Qt::Key_1:
+        dfbEvent->key_symbol = DIKS_1;
+        dfbEvent->key_id = DIKI_1;
+        break;
+    case Qt::Key_2:
+        dfbEvent->key_symbol = DIKS_2;
+        dfbEvent->key_id = DIKI_2;
+        break;
+    case Qt::Key_3:
+        dfbEvent->key_symbol = DIKS_3;
+        dfbEvent->key_id = DIKI_3;
+        break;
+    case Qt::Key_4:
+        dfbEvent->key_symbol = DIKS_4;
+        dfbEvent->key_id = DIKI_4;
+        break;
+    case Qt::Key_5:
+        dfbEvent->key_symbol = DIKS_5;
+        dfbEvent->key_id = DIKI_5;
+        break;
+    case Qt::Key_6:
+        dfbEvent->key_symbol = DIKS_6;
+        dfbEvent->key_id = DIKI_6;
+        break;
+    case Qt::Key_7:
+        dfbEvent->key_symbol = DIKS_7;
+        dfbEvent->key_id = DIKI_7;
+        break;
+    case Qt::Key_8:
+        dfbEvent->key_symbol = DIKS_8;
+        dfbEvent->key_id = DIKI_8;
+        break;
+    case Qt::Key_9:
+        dfbEvent->key_symbol = DIKS_9;
+        dfbEvent->key_id = DIKI_9;
+        break;
+    case Qt::Key_Colon:
+        dfbEvent->key_symbol = DIKS_COLON;
+        break;
+    case Qt::Key_Semicolon:
+        dfbEvent->key_symbol = DIKS_SEMICOLON;
+        dfbEvent->key_id = DIKI_SEMICOLON;
+        break;
+    case Qt::Key_Less:
+        dfbEvent->key_symbol = DIKS_LESS_THAN_SIGN;
+        dfbEvent->key_id = DIKI_LESS_SIGN;
+        break;
+    case Qt::Key_Equal:
+        dfbEvent->key_symbol = DIKS_EQUALS_SIGN;
+        dfbEvent->key_id = DIKI_EQUALS_SIGN;
+        break;
+    case Qt::Key_Greater:
+        dfbEvent->key_symbol = DIKS_GREATER_THAN_SIGN;
+        break;
+    case Qt::Key_Question:
+        dfbEvent->key_symbol = DIKS_QUESTION_MARK;
+        break;
+    case Qt::Key_At:
+        dfbEvent->key_symbol = DIKS_AT;
+        break;
+    case Qt::Key_A:
+        dfbEvent->key_symbol = DIKS_SMALL_A;
+        dfbEvent->key_id = DIKI_A;
+        break;
+    case Qt::Key_B:
+        dfbEvent->key_symbol = DIKS_SMALL_B;
+        dfbEvent->key_id = DIKI_B;
+        break;
+    case Qt::Key_C:
+        dfbEvent->key_symbol = DIKS_SMALL_C;
+        dfbEvent->key_id = DIKI_C;
+        break;
+    case Qt::Key_D:
+        dfbEvent->key_symbol = DIKS_SMALL_D;
+        dfbEvent->key_id = DIKI_D;
+        break;
+    case Qt::Key_E:
+        dfbEvent->key_symbol = DIKS_SMALL_E;
+        dfbEvent->key_id = DIKI_E;
+        break;
+    case Qt::Key_F:
+        dfbEvent->key_symbol = DIKS_SMALL_F;
+        dfbEvent->key_id = DIKI_F;
+        break;
+    case Qt::Key_G:
+        dfbEvent->key_symbol = DIKS_SMALL_G;
+        dfbEvent->key_id = DIKI_G;
+        break;
+    case Qt::Key_H:
+        dfbEvent->key_symbol = DIKS_SMALL_H;
+        dfbEvent->key_id = DIKI_H;
+        break;
+    case Qt::Key_I:
+        dfbEvent->key_symbol = DIKS_SMALL_I;
+        dfbEvent->key_id = DIKI_I;
+        break;
+    case Qt::Key_J:
+        dfbEvent->key_symbol = DIKS_SMALL_J;
+        dfbEvent->key_id = DIKI_J;
+        break;
+    case Qt::Key_K:
+        dfbEvent->key_symbol = DIKS_SMALL_K;
+        dfbEvent->key_id = DIKI_K;
+        break;
+    case Qt::Key_L:
+        dfbEvent->key_symbol = DIKS_SMALL_L;
+        dfbEvent->key_id = DIKI_L;
+        break;
+    case Qt::Key_M:
+        dfbEvent->key_symbol = DIKS_SMALL_M;
+        dfbEvent->key_id = DIKI_M;
+        break;
+    case Qt::Key_N:
+        dfbEvent->key_symbol = DIKS_SMALL_N;
+        dfbEvent->key_id = DIKI_N;
+        break;
+    case Qt::Key_O:
+        dfbEvent->key_symbol = DIKS_SMALL_O;
+        dfbEvent->key_id = DIKI_O;
+        break;
+    case Qt::Key_P:
+        dfbEvent->key_symbol = DIKS_SMALL_P;
+        dfbEvent->key_id = DIKI_P;
+        break;
+    case Qt::Key_Q:
+        dfbEvent->key_symbol = DIKS_SMALL_Q;
+        dfbEvent->key_id = DIKI_Q;
+        break;
+    case Qt::Key_R:
+        dfbEvent->key_symbol = DIKS_SMALL_R;
+        dfbEvent->key_id = DIKI_R;
+        break;
+    case Qt::Key_S:
+        dfbEvent->key_symbol = DIKS_SMALL_S;
+        dfbEvent->key_id = DIKI_S;
+        break;
+    case Qt::Key_T:
+        dfbEvent->key_symbol = DIKS_SMALL_T;
+        dfbEvent->key_id = DIKI_T;
+        break;
+    case Qt::Key_U:
+        dfbEvent->key_symbol = DIKS_SMALL_U;
+        dfbEvent->key_id = DIKI_U;
+        break;
+    case Qt::Key_V:
+        dfbEvent->key_symbol = DIKS_SMALL_V;
+        dfbEvent->key_id = DIKI_V;
+        break;
+    case Qt::Key_W:
+        dfbEvent->key_symbol = DIKS_SMALL_W;
+        dfbEvent->key_id = DIKI_W;
+        break;
+    case Qt::Key_X:
+        dfbEvent->key_symbol = DIKS_SMALL_X;
+        dfbEvent->key_id = DIKI_X;
+        break;
+    case Qt::Key_Y:
+        dfbEvent->key_symbol = DIKS_SMALL_Y;
+        dfbEvent->key_id = DIKI_Y;
+        break;
+    case Qt::Key_Z:
+        dfbEvent->key_symbol = DIKS_SMALL_Z;
+        dfbEvent->key_id = DIKI_Z;
+        break;
+    case Qt::Key_BracketLeft:
+        dfbEvent->key_symbol = DIKS_SQUARE_BRACKET_LEFT;
+        break;
+    case Qt::Key_Backslash:
+        dfbEvent->key_symbol = DIKS_BACKSLASH;
+        dfbEvent->key_id = DIKI_BACKSLASH;
+        break;
+    case Qt::Key_BracketRight:
+        dfbEvent->key_symbol = DIKS_SQUARE_BRACKET_RIGHT;
+        break;
+    case Qt::Key_AsciiCircum:
+        dfbEvent->key_symbol = DIKS_CIRCUMFLEX_ACCENT;
+        break;
+    case Qt::Key_Underscore:
+        dfbEvent->key_symbol = DIKS_UNDERSCORE;
+        break;
+    case Qt::Key_BraceLeft:
+        dfbEvent->key_symbol = DIKS_CURLY_BRACKET_LEFT;
+        break;
+    case Qt::Key_Bar:
+        dfbEvent->key_symbol = DIKS_VERTICAL_BAR;
+        break;
+    case Qt::Key_BraceRight:
+        dfbEvent->key_symbol = DIKS_CURLY_BRACKET_RIGHT;
+        break;
+    case Qt::Key_AsciiTilde:
+        dfbEvent->key_symbol = DIKS_TILDE;
+        break;
+    }
+    if ((qtEvent->modifiers() & Qt::ShiftModifier) && qtEvent->key() >= Qt::Key_A && qtEvent->key() <= Qt::Key_Z)
+        dfbEvent->key_symbol = DFBInputDeviceKeySymbol((dfbEvent->key_symbol - DIKS_SMALL_A) + DIKS_CAPITAL_A);
+    if (dfbEvent->key_id != DIKI_UNKNOWN) {
+        flags = DFBInputEventFlags(dfbEvent->flags | DIEF_KEYID);
+        if (dfbEvent->key_id >= DIKI_0 && dfbEvent->key_id <= DIKI_9 && qtEvent->modifiers() & Qt::KeypadModifier)
+            dfbEvent->key_id = DFBInputDeviceKeyIdentifier(dfbEvent->key_id - DIKI_0 + DIKI_KP_0);
+    }
+    dfbEvent->flags = DFBInputEventFlags(flags);
+}
+#endif
 
 void PluginView::handleKeyboardEvent(KeyboardEvent* event)
 {
@@ -302,14 +866,21 @@ void PluginView::handleKeyboardEvent(Key
     if (event->type() != eventNames().keydownEvent && event->type() != eventNames().keyupEvent)
         return;
 
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
     setXKeyEventSpecificFields(&npEvent, event);
+#else
+    DFBEvent npEvent;
+    DFBInputEvent& input = npEvent.input;
+    initDirectFBKeyboardEvent(&input, event->keyEvent()->qtEvent());
+#endif
 
     if (!dispatchNPEvent(npEvent))
         event->setDefaultHandled();
 }
 
+#ifndef XP_DFB
 static unsigned int inputEventState(MouseEvent* event)
 {
     unsigned int state = 0;
@@ -384,6 +955,45 @@ static void setXCrossingEventSpecificFie
     xcrossing.same_screen = true;
     xcrossing.focus = false;
 }
+#else
+static inline void initDirectFBMouseEvent(DFBWindowEvent* dfbEvent, const MouseEvent* event)
+{
+    dfbEvent->clazz = DFEC_WINDOW;
+
+    unsigned int modifiers = 0;
+    if (event->ctrlKey())
+        modifiers |= DIMM_CONTROL;
+    if (event->shiftKey())
+        modifiers |= DIMM_SHIFT;
+    if (event->altKey())
+        modifiers |= DIMM_ALT;
+    if (event->metaKey())
+        modifiers |= DIMM_META;
+    dfbEvent->modifiers = DFBInputDeviceModifierMask(modifiers);
+
+    if (event->type() == eventNames().mousedownEvent || event->type() == eventNames().mouseupEvent) {
+        dfbEvent->type = (event->type() == eventNames().mousedownEvent ? DWET_BUTTONDOWN : DWET_BUTTONUP);
+        switch (event->button()) {
+        case LeftButton:
+            dfbEvent->button = DIBI_LEFT;
+            break;
+        case MiddleButton:
+            dfbEvent->button = DIBI_MIDDLE;
+            break;
+        case RightButton:
+            dfbEvent->button = DIBI_RIGHT;
+            break;
+        default:
+            break;
+        }
+        dfbEvent->buttons = DFBInputDeviceButtonMask(0);
+    } else if (event->type() == eventNames().mousemoveEvent) {
+        dfbEvent->type = DWET_MOTION;
+    } else {
+        return;
+    }
+}
+#endif
 
 void PluginView::handleMouseEvent(MouseEvent* event)
 {
@@ -397,11 +1007,11 @@ void PluginView::handleMouseEvent(MouseE
 
         focusPluginElement();
     }
-
+    IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation()));
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
 
-    IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation()));
 
     if (event->type() == eventNames().mousedownEvent || event->type() == eventNames().mouseupEvent)
         setXButtonEventSpecificFields(&npEvent, event, postZoomPos);
@@ -411,13 +1021,40 @@ void PluginView::handleMouseEvent(MouseE
         setXCrossingEventSpecificFields(&npEvent, event, postZoomPos);
     else
         return;
+    if (!dispatchNPEvent(npEvent))
+        event->setDefaultHandled();
 
+#else
+    DFBEvent npEvent;
+    memset(&npEvent, 0, sizeof(DFBEvent));
+
+    if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent) {
+        npEvent.clazz = DFEC_WINDOW;
+        npEvent.window.type = (event->type() == eventNames().mouseoverEvent ? DWET_ENTER : DWET_LEAVE);
+        npEvent.window.x = npEvent.window.cx = postZoomPos.x();
+        npEvent.window.y = npEvent.window.cy = postZoomPos.y();
     if (!dispatchNPEvent(npEvent))
         event->setDefaultHandled();
+        return;
+}
+
+    DFBWindowEvent& window = npEvent.window;
+    m_dfbWindow->GetID(m_dfbWindow, &window.window_id);
+    initDirectFBMouseEvent(&window, event);
+    window.x = postZoomPos.x();
+    window.y = postZoomPos.y();
+    const IntPoint absoluteLocation = event->absoluteLocation();
+    window.cx = absoluteLocation.x();
+    window.cy = absoluteLocation.y();
+
+    if (!dispatchNPEvent(npEvent))
+        event->setDefaultHandled();
+#endif
 }
 
 void PluginView::handleFocusInEvent()
 {
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
 
@@ -425,12 +1062,21 @@ void PluginView::handleFocusInEvent()
     event.type = 9; /* int as Qt unsets FocusIn */
     event.mode = NotifyNormal;
     event.detail = NotifyDetailNone;
+    dispatchNPEvent(npEvent);
 
+#else
+    DFBEvent npEvent;
+    memset(&npEvent, 0, sizeof(DFBEvent));
+    DFBWindowEvent& window = npEvent.window;
+    window.clazz = DFEC_WINDOW;
+    window.type = DWET_GOTFOCUS;
     dispatchNPEvent(npEvent);
+#endif
 }
 
 void PluginView::handleFocusOutEvent()
 {
+#ifndef XP_DFB
     XEvent npEvent;
     initXEvent(&npEvent);
 
@@ -440,6 +1086,15 @@ void PluginView::handleFocusOutEvent()
     event.detail = NotifyDetailNone;
 
     dispatchNPEvent(npEvent);
+#else
+    DFBEvent npEvent;
+    memset(&npEvent, 0, sizeof(DFBEvent));
+    DFBWindowEvent& window = npEvent.window;
+    window.clazz = DFEC_WINDOW;
+    window.type = DWET_LOSTFOCUS;
+    dispatchNPEvent(npEvent);
+#endif
+
 }
 
 void PluginView::setParent(ScrollView* parent)
@@ -456,6 +1111,49 @@ void PluginView::setNPWindowRect(const I
         setNPWindowIfNeeded();
 }
 
+#ifdef XP_DFB
+class WindowMoveEventFilter : public QObject {
+public:
+    WindowMoveEventFilter(bool* g, PluginView* view, QWidget* watched)
+        : QObject(0)
+        , m_hasPendingGeometryChange(g)
+        , m_pluginView(view)
+    {
+        Q_ASSERT(watched);
+        forever {
+            watched->installEventFilter(this);
+            if (watched->isWindow())
+                break;
+            watched = watched->parentWidget();
+            if (!watched)
+                break;
+        }
+    }
+
+    bool eventFilter(QObject *, QEvent* e)
+    {
+        if (e->type() == QEvent::Move || e->type() == QEvent::Resize) {
+            *m_hasPendingGeometryChange = true;
+            m_timer.start(10, this);
+        }
+        return false;
+    }
+
+    void timerEvent(QTimerEvent* e)
+    {
+        if (e->timerId() == m_timer.timerId()) {
+            m_timer.stop();
+            m_pluginView->forceRedraw();
+        }
+    }
+private:
+    bool* m_hasPendingGeometryChange;
+    PluginView* m_pluginView;
+    QBasicTimer m_timer;
+};
+
+#endif
+
 void PluginView::setNPWindowIfNeeded()
 {
     if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow)
@@ -492,6 +1190,7 @@ void PluginView::setNPWindowIfNeeded()
         m_npWindow.clipRect.right = m_clipRect.width();
         m_npWindow.clipRect.bottom = m_clipRect.height();
     } else {
+#ifndef XP_DFB
         m_npWindow.x = 0;
         m_npWindow.y = 0;
 
@@ -499,6 +1198,39 @@ void PluginView::setNPWindowIfNeeded()
         m_npWindow.clipRect.top = 0;
         m_npWindow.clipRect.right = 0;
         m_npWindow.clipRect.bottom = 0;
+#else
+        QPoint pluginViewGlobalPos = windowClipRect().topLeft();
+        QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+        if (QWidget* ownerWidget = client ? client->ownerWidget() : 0) {
+            if (!m_eventFilter)
+                m_eventFilter = new WindowMoveEventFilter(&m_hasPendingGeometryChange, this, ownerWidget);
+            pluginViewGlobalPos = ownerWidget->mapToGlobal(pluginViewGlobalPos);
+            if (const QGraphicsWebView* item = qobject_cast<const QGraphicsWebView*>(client->pluginParent())) {
+                Q_ASSERT(item->scene() && !item->scene()->views().isEmpty());
+                const QGraphicsView* view = item->scene()->views().value(0);
+                const QPoint add = view->mapFromScene(item->pos());
+                pluginViewGlobalPos += add;
+    }
+        }
+
+        if ((QSize)(m_windowRect.size()) != m_pixmap.size()) {
+            m_pixmap = QPixmap(m_windowRect.size());
+            m_pixmap.fill(Qt::transparent);
+        }
+
+        m_npWindow.x = pluginViewGlobalPos.x();
+        m_npWindow.y = pluginViewGlobalPos.y();
+        const IntRect frame = frameRect();
+        m_npWindow.width = frame.width();
+        m_npWindow.height = frame.height();
+        m_npWindow.clipRect.top = m_clipRect.y();
+        m_npWindow.clipRect.left = m_clipRect.x();
+        m_npWindow.clipRect.right = m_clipRect.width() + m_clipRect.x() - 1;
+        m_npWindow.clipRect.bottom = m_clipRect.height() + m_clipRect.y() - 1;
+        m_dfbSurface = QT_PREPEND_NAMESPACE(qt_directfb_surface_for_pixmap(m_pixmap));
+        m_npWindow.window = m_dfbSurface;
+        m_npWindow.type = NPWindowTypeDrawable;
+#endif
     }
 
     // FLASH WORKAROUND: Only set initially. Multiple calls to
@@ -584,15 +1316,12 @@ bool PluginView::platformGetValueStatic(
 bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* result)
 {
     switch (variable) {
+#ifndef XP_DFB
     case NPNVxDisplay:
         *(void **)value = QX11Info::display();
         *result = NPERR_NO_ERROR;
         return true;
 
-    case NPNVxtAppContext:
-        *result = NPERR_GENERIC_ERROR;
-        return true;
-
     case NPNVnetscapeWindow: {
         void* w = reinterpret_cast<void*>(value);
         QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
@@ -600,7 +1329,7 @@ bool PluginView::platformGetValue(NPNVar
         *result = NPERR_NO_ERROR;
         return true;
     }
-
+#endif
     case NPNVToolkit:
         if (m_plugin->quirks().contains(PluginQuirkRequiresGtkToolKit)) {
             *((uint32 *)value) = 2;
@@ -645,6 +1374,7 @@ void PluginView::forceRedraw()
     invalidate();
 }
 
+#ifndef XP_DFB
 static Display *getPluginDisplay()
 {
     // The plugin toolkit might run using a different X connection. At the moment, we only
@@ -710,12 +1440,14 @@ static void getVisualAndColormap(int dep
     if (*visual)
         *colormap = XCreateColormap(QX11Info::display(), QX11Info::appRootWindow(), *visual, AllocNone);
 }
+#endif
 
 bool PluginView::platformStart()
 {
     ASSERT(m_isStarted);
     ASSERT(m_status == PluginStatusLoadedSuccessfully);
 
+#ifndef XP_DFB
     if (m_plugin->pluginFuncs()->getvalue) {
         PluginView::setCurrentPluginView(this);
         JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
@@ -740,12 +1472,71 @@ bool PluginView::platformStart()
         setPlatformWidget(0);
         m_pluginDisplay = getPluginDisplay();
     }
+#else
+    if (m_isWindowed) {
+        notImplemented();
+        m_status = PluginStatusCanNotLoadPlugin;
+        return false;
+    }
+    DFBWindowInfo* wsInfo = 0;
+    QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+    if (!client || !client->ownerWidget()) {
+        notImplemented();
+        m_status = PluginStatusCanNotLoadPlugin;
+        return false;
+    }
+
+    DFBResult result = DirectFBCreate(&m_dfb);
+    if (result != DFB_OK)
+        goto end;
+
+    result = m_dfb->GetDisplayLayer(m_dfb, DLID_PRIMARY, &m_dfbDisplayLayer);
+    if (result != DFB_OK)
+        goto end;
+
+    result = m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,
+                                          static_cast<DFBWindowID>(client->ownerWidget()->property("_q_DirectFBWindowID").toInt()),
+                                          &m_dfbWindow);
+    if (result != DFB_OK)
+        goto end;
+    wsInfo = new DFBWindowInfo;
+    wsInfo->dfb = m_dfb;
+    wsInfo->window = m_dfbWindow;
+    wsInfo->layer = m_dfbDisplayLayer;
+    m_npWindow.ws_info = wsInfo;
+    m_npWindow.type = NPWindowTypeDrawable;
+    m_npWindow.window = 0; // Not used?
+    m_npWindow.x = 0;
+    m_npWindow.y = 0;
+    m_npWindow.width = -1;
+    m_npWindow.height = -1;
+
+end:
+    if (result != DFB_OK) {
+        if (m_dfbWindow) {
+            m_dfbWindow->Release(m_dfbWindow);
+            m_dfbWindow = 0;
+        }
+
+        if (m_dfbDisplayLayer)
+            m_dfbDisplayLayer->Release(m_dfbDisplayLayer);
+
+        if (m_dfb) {
+            m_dfb->Release(m_dfb);
+            m_dfb = 0;
+        }
+        DirectFBError("PluginView::platformStart()", result);
+        notImplemented();
+        m_status = PluginStatusCanNotLoadPlugin;
+        return false;
+    }
+#endif
 
     show();
 
+#ifndef XP_DFB
     NPSetWindowCallbackStruct* wsi = new NPSetWindowCallbackStruct();
     wsi->type = 0;
-
     if (m_isWindowed) {
         const QX11Info* x11Info = &platformPluginWidget()->x11Info();
 
@@ -753,7 +1544,6 @@ bool PluginView::platformStart()
         wsi->visual = (Visual*)x11Info->visual();
         wsi->depth = x11Info->depth();
         wsi->colormap = x11Info->colormap();
-
         m_npWindow.type = NPWindowTypeWindow;
         m_npWindow.window = (void*)platformPluginWidget()->winId();
         m_npWindow.width = -1;
@@ -782,8 +1572,8 @@ bool PluginView::platformStart()
         m_npWindow.width = -1;
         m_npWindow.height = -1;
     }
-
     m_npWindow.ws_info = wsi;
+#endif
 
     if (!(m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall))) {
         updatePluginWidget();
@@ -798,11 +1588,33 @@ void PluginView::platformDestroy()
     if (platformPluginWidget())
         delete platformPluginWidget();
 
+#ifndef XP_DFB
     if (m_drawable)
         XFreePixmap(QX11Info::display(), m_drawable);
 
     if (m_colormap)
         XFreeColormap(QX11Info::display(), m_colormap);
+#else
+    delete m_eventFilter;
+    m_eventFilter = 0;
+    delete static_cast<DFBWindowInfo*>(m_npWindow.ws_info);
+    m_npWindow.ws_info = 0;
+    m_pixmap = QPixmap();
+    if (m_dfbWindow) {
+        m_dfbWindow->Release(m_dfbWindow);
+        m_dfbWindow = 0;
+}
+
+    if (m_dfbDisplayLayer) {
+        m_dfbDisplayLayer->Release(m_dfbDisplayLayer);
+        m_dfbDisplayLayer = 0;
+    }
+
+    if (m_dfb) {
+        m_dfb->Release(m_dfb);
+        m_dfb = 0;
+    }
+#endif
 }
 
 void PluginView::halt()


More information about the webkit-dev mailing list