Bug 464966 - Add NPAPI Plugin support for Mozilla Qt. r=karlt
authorOleg Romashin <romaxa@gmail.com>
Tue, 20 Apr 2010 21:49:34 +0300
changeset 41059 beebc4d09baa8f20e9e828ec591b4918e6c0c418
parent 41058 5896d4f94aee0ceb07c2a877b26a498855f4cb77
child 41060 86d416f2dbb2e7e61a792dcea54039bf2158231e
push idunknown
push userunknown
push dateunknown
reviewerskarlt
bugs464966
milestone1.9.3a5pre
Bug 464966 - Add NPAPI Plugin support for Mozilla Qt. r=karlt
gfx/thebes/public/gfxQtNativeRenderer.h
gfx/thebes/src/gfxQtNativeRenderer.cpp
layout/generic/nsObjectFrame.cpp
modules/plugin/base/src/Makefile.in
modules/plugin/base/src/nsNPAPIPlugin.cpp
modules/plugin/base/src/nsPluginNativeWindowQt.cpp
modules/plugin/test/testplugin/Makefile.in
modules/plugin/test/testplugin/nptest_qt.cpp
widget/src/qt/nsWindow.cpp
--- a/gfx/thebes/public/gfxQtNativeRenderer.h
+++ b/gfx/thebes/public/gfxQtNativeRenderer.h
@@ -36,37 +36,38 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFXQTNATIVERENDER_H_
 #define GFXQTNATIVERENDER_H_
 
 #include "gfxColor.h"
 #include "gfxASurface.h"
 #include "gfxContext.h"
+#include "gfxXlibSurface.h"
 
-class QWidget;
 class QRect;
 
 /**
- * This class lets us take code that draws into an Qt drawable and lets us
+ * This class lets us take code that draws into an Xlib surface drawable and lets us
  * use it to draw into any Thebes context. The user should subclass this class,
  * override NativeDraw, and then call Draw(). The drawing will be subjected
  * to all Thebes transformations, clipping etc.
  */
 class THEBES_API gfxQtNativeRenderer {
 public:
     /**
      * Perform the native drawing.
      * @param offsetX draw at this offset into the given drawable
      * @param offsetY draw at this offset into the given drawable
      * @param clipRects an array of rects; clip to the union
      * @param numClipRects the number of rects in the array, or zero if
      * no clipping is required
      */
-    virtual nsresult NativeDraw(QWidget * drawable, short offsetX, 
+    virtual nsresult NativeDraw(gfxXlibSurface *xsurf,
+            Colormap colormap, short offsetX,
             short offsetY, QRect * clipRects, PRUint32 numClipRects) = 0;
   
     enum {
         // If set, then Draw() is opaque, i.e., every pixel in the intersection
         // of the clipRect and (offset.x,offset.y,bounds.width,bounds.height)
         // will be set and there is no dependence on what the existing pixels
         // in the drawable are set to.
         DRAW_IS_OPAQUE = 0x01,
--- a/gfx/thebes/src/gfxQtNativeRenderer.cpp
+++ b/gfx/thebes/src/gfxQtNativeRenderer.cpp
@@ -30,107 +30,68 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include <QWidget>
+#include <QX11Info>
 
 #include "gfxQtNativeRenderer.h"
 #include "gfxContext.h"
-
-#include "gfxQtPlatform.h"
-
-#include "cairo.h"
-
-typedef struct {
-    gfxQtNativeRenderer* mRenderer;
-    nsresult               mRV;
-} NativeRenderingClosure;
-
-
-static cairo_bool_t
-NativeRendering(void *closure,
-                QWidget * drawable,
-                short offset_x, short offset_y,
-                QRect * rectangles, unsigned int num_rects)
-{
-    NativeRenderingClosure* cl = (NativeRenderingClosure*)closure;
-    nsresult rv = cl->mRenderer->
-        NativeDraw(drawable, offset_x, offset_y,
-                   rectangles, num_rects);
-    cl->mRV = rv;
-    return NS_SUCCEEDED(rv);
-}
-
+#include "gfxXlibSurface.h"
 
 nsresult
 gfxQtNativeRenderer::Draw(gfxContext* ctx, int width, int height,
                           PRUint32 flags, DrawOutput* output)
 {
-    NativeRenderingClosure closure = { this, NS_OK };
-
-    if (output) {
-        output->mSurface = NULL;
-        output->mUniformAlpha = PR_FALSE;
-        output->mUniformColor = PR_FALSE;
-    }
-
-#if 0 // FIXME
-
-    cairo_gdk_drawing_result_t result;
-    // Make sure result.surface is null to start with; we rely on it
-    // being non-null meaning that a surface actually got allocated.
-    result.surface = NULL;
+    Display *dpy = QX11Info().display();
+    PRBool isOpaque = (flags & DRAW_IS_OPAQUE) ? PR_TRUE : PR_FALSE;
+    int screen = QX11Info().screen();
+    int depth = QX11Info().depth();
+    Visual *visual = static_cast<Visual*>(QX11Info().visual());
+    Colormap colormap = QX11Info().colormap();
+    PRBool allocColormap = PR_FALSE;
 
-    int cairoFlags = 0;
-    if (flags & DRAW_SUPPORTS_OFFSET) {
-        cairoFlags |= CAIRO_GDK_DRAWING_SUPPORTS_OFFSET;
-    }
-    if (flags & DRAW_SUPPORTS_CLIP_RECT) {
-        cairoFlags |= CAIRO_GDK_DRAWING_SUPPORTS_CLIP_RECT;
-    }
-    if (flags & DRAW_SUPPORTS_CLIP_LIST) {
-        cairoFlags |= CAIRO_GDK_DRAWING_SUPPORTS_CLIP_LIST;
-    }
-    if (flags & DRAW_SUPPORTS_ALTERNATE_SCREEN) {
-        cairoFlags |= CAIRO_GDK_DRAWING_SUPPORTS_ALTERNATE_SCREEN;
-    }
-    if (flags & DRAW_SUPPORTS_NONDEFAULT_VISUAL) {
-        cairoFlags |= CAIRO_GDK_DRAWING_SUPPORTS_NONDEFAULT_VISUAL;
+    if (!isOpaque) {
+        depth = 32;
+        XVisualInfo vinfo;
+        int foundVisual = XMatchVisualInfo(dpy, screen,
+                                           depth, TrueColor,
+                                           &vinfo);
+        if (!foundVisual)
+            return NS_ERROR_FAILURE;
+
+        if (visual != vinfo.visual) {
+            allocColormap = PR_TRUE;
+            visual = vinfo.visual;
+            colormap = XCreateColormap(dpy,
+                                       RootWindow(dpy, screen),
+                                       visual, AllocNone);
+        }
     }
 
-    cairo_draw_with_gdk(ctx->GetCairo(),
-                        gfxPlatformGtk::GetPlatform()->GetGdkDrawable(ctx->OriginalSurface()),
-                        NativeRendering, 
-                        &closure, width, height,
-                        (flags & DRAW_IS_OPAQUE) ? CAIRO_GDK_DRAWING_OPAQUE : CAIRO_GDK_DRAWING_TRANSPARENT,
-                        (cairo_gdk_drawing_support_t)cairoFlags,
-                        output ? &result : NULL);
+    nsRefPtr<gfxXlibSurface> xsurf =
+        new gfxXlibSurface(dpy, visual,
+                           gfxIntSize(width, height),
+                           depth);
 
-    if (NS_FAILED(closure.mRV)) {
-        if (result.surface) {
-            NS_ASSERTION(output, "How did that happen?");
-            cairo_surface_destroy (result.surface);
-        }
-        return closure.mRV;
+    if (!isOpaque) {
+        nsRefPtr<gfxContext> tempCtx = new gfxContext(xsurf);
+        tempCtx->SetOperator(gfxContext::OPERATOR_CLEAR);
+        tempCtx->Paint();
     }
 
-    if (output) {
-        if (result.surface) {
-            output->mSurface = gfxASurface::Wrap(result.surface);
-            if (!output->mSurface) {
-                cairo_surface_destroy (result.surface);
-                return NS_ERROR_OUT_OF_MEMORY;
-            }
-        }
+    nsresult rv = NativeDraw(xsurf.get(), colormap, 0, 0, NULL, 0);
+
+    if (!allocColormap)
+        XFreeColormap(dpy, colormap);
 
-        output->mUniformAlpha = result.uniform_alpha;
-        output->mUniformColor = result.uniform_color;
-        output->mColor = gfxRGBA(result.r, result.g, result.b, result.alpha);
-    }
-#endif
+    if (NS_FAILED(rv))
+        return rv;
 
-    return NS_OK;
+    ctx->SetSource(xsurf);
+    ctx->Paint();
+
+    return rv;
 }
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -41,19 +41,19 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* rendering objects for replaced elements implemented by a plugin */
 
-#ifdef MOZ_X11
 #ifdef MOZ_WIDGET_QT
 #include <QWidget>
+#ifdef MOZ_X11
 #include <QX11Info>
 #endif
 #endif
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
@@ -164,16 +164,17 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 #ifdef XP_MACOSX
 #include "gfxQuartzNativeDrawing.h"
 #include "nsPluginUtilsOSX.h"
 #include "nsCoreAnimationSupport.h"
 #endif
 
 #ifdef MOZ_X11
 #include <X11/Xlib.h>
+#include <cairo-xlib.h>
 /* X headers suck */
 enum { XKeyPress = KeyPress };
 #ifdef KeyPress
 #undef KeyPress
 #endif
 
 #if (MOZ_PLATFORM_MAEMO == 5) && defined(MOZ_WIDGET_GTK2)
 #define MOZ_COMPOSITED_PLUGINS 1
@@ -190,20 +191,24 @@ enum { XKeyPress = KeyPress };
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 #endif
 #endif
 
 #ifdef MOZ_WIDGET_GTK2
 #include "gfxGdkNativeRenderer.h"
+#define DISPLAY GDK_DISPLAY
 #endif
 
 #ifdef MOZ_WIDGET_QT
 #include "gfxQtNativeRenderer.h"
+#ifdef MOZ_X11
+#define DISPLAY QX11Info::display
+#endif
 #endif
 
 #ifdef XP_WIN
 #include <wtypes.h>
 #include <winuser.h>
 #ifdef MOZ_IPC
 #define NS_OOPP_DOUBLEPASS_MSGID TEXT("MozDoublePassMsg")
 #endif
@@ -503,18 +508,19 @@ private:
 #elif defined(MOZ_WIDGET_QT)
   class Renderer : public gfxQtNativeRenderer {
   public:
     Renderer(NPWindow* aWindow, nsIPluginInstance* aInstance,
              const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect)
       : mWindow(aWindow), mInstance(aInstance),
         mPluginSize(aPluginSize), mDirtyRect(aDirtyRect)
     {}
-    virtual nsresult NativeDraw(QWidget * drawable, short offsetX, 
-            short offsetY, QRect * clipRects, PRUint32 numClipRects);
+    virtual nsresult NativeDraw(gfxXlibSurface* xsurface, Colormap colormap,
+                                short offsetX, short offsetY,
+                                QRect * clipRects, PRUint32 numClipRects);
   private:
     NPWindow* mWindow;
     nsIPluginInstance* mInstance;
     const nsIntSize& mPluginSize;
     const nsIntRect& mDirtyRect;
   };
 #endif
 
@@ -2895,18 +2901,19 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   nsIWidget* win = mObjectFrame->GetWindow();
   if (!win)
     return NS_ERROR_FAILURE;
   QWidget* widget = static_cast<QWidget*>(win->GetNativeData(NS_NATIVE_WINDOW));
   if (!widget)
     return NS_ERROR_FAILURE;
 #ifdef MOZ_X11
   *static_cast<Window*>(value) = widget->handle();
+  return NS_OK;
 #endif
-  return NS_OK;
+  return NS_ERROR_FAILURE;
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(PRInt32 eventModel)
 {
 #ifdef XP_MACOSX
@@ -4061,28 +4068,31 @@ static unsigned int XInputEventState(con
 
 #ifdef MOZ_COMPOSITED_PLUGINS
 static void find_dest_id(XID top, XID *root, XID *dest, int target_x, int target_y)
 {
   XID target_id = top;
   XID parent;
   XID *children;
   unsigned int nchildren;
+
+  Display *display = DISPLAY();
+
   while (1) {
 loop:
     //printf("searching %x\n", target_id);
-    if (!XQueryTree(GDK_DISPLAY(), target_id, root, &parent, &children, &nchildren) ||
+    if (!XQueryTree(display, target_id, root, &parent, &children, &nchildren) ||
         !nchildren)
       break;
     for (unsigned int i=0; i<nchildren; i++) {
       Window root;
       int x, y;
       unsigned int width, height;
       unsigned int border_width, depth;
-      XGetGeometry(GDK_DISPLAY(), children[i], &root, &x, &y,
+      XGetGeometry(display, children[i], &root, &x, &y,
           &width, &height, &border_width,
           &depth);
       //printf("target: %d %d\n", target_x, target_y);
       //printf("geom: %dx%x @ %dx%d\n", width, height, x, y);
       // XXX: we may need to be more careful here, i.e. if
       // this condition matches more than one child
       if (target_x >= x && target_y >= y &&
           target_x <= x + int(width) &&
@@ -4137,18 +4147,20 @@ nsEventStatus nsPluginInstanceOwner::Pro
         const nsMouseEvent& mouseEvent =
           static_cast<const nsMouseEvent&>(anEvent);
         // Get reference point relative to screen:
         nsIntPoint rootPoint(-1,-1);
         if (widget)
           rootPoint = anEvent.refPoint + widget->WidgetToScreenOffset();
 #ifdef MOZ_WIDGET_GTK2
         Window root = GDK_ROOT_WINDOW();
+#elif defined(MOZ_WIDGET_QT)
+        Window root = QX11Info::appRootWindow();
 #else
-        Window root = None; // Could XQueryTree, but this is not important.
+        Window root = None;
 #endif
 
         switch (anEvent.message)
           {
           case NS_MOUSE_ENTER_SYNTH:
           case NS_MOUSE_EXIT_SYNTH:
             {
               XCrossingEvent& event = pluginEvent.xcrossing;
@@ -4226,20 +4238,20 @@ nsEventStatus nsPluginInstanceOwner::Pro
               be.xbutton =  event;
               XID target;
               XID root;
               int wx, wy;
               unsigned int width, height, border_width, depth;
 
               //printf("xbutton: %d %d %d\n", anEvent.message, be.xbutton.x, be.xbutton.y);
               XID w = (XID)mPluginWindow->window;
-              XGetGeometry(GDK_DISPLAY(), w, &root, &wx, &wy, &width, &height, &border_width, &depth);
+              XGetGeometry(DISPLAY(), w, &root, &wx, &wy, &width, &height, &border_width, &depth);
               find_dest_id(w, &root, &target, pluginPoint.x + wx, pluginPoint.y + wy);
               be.xbutton.window = target;
-              XSendEvent (GDK_DISPLAY(), target,
+              XSendEvent (DISPLAY(), target,
                   FALSE, event.type == ButtonPress ? ButtonPressMask : ButtonReleaseMask, &be);
 
             }
             break;
           }
       }
       break;
 
@@ -4284,20 +4296,20 @@ nsEventStatus nsPluginInstanceOwner::Pro
           be.xkey =  event;
           XID target;
           XID root;
           int wx, wy;
           unsigned int width, height, border_width, depth;
 
           //printf("xkey: %d %d %d\n", anEvent.message, be.xkey.keycode, be.xkey.state);
           XID w = (XID)mPluginWindow->window;
-          XGetGeometry(GDK_DISPLAY(), w, &root, &wx, &wy, &width, &height, &border_width, &depth);
+          XGetGeometry(DISPLAY(), w, &root, &wx, &wy, &width, &height, &border_width, &depth);
           find_dest_id(w, &root, &target, mLastPoint.x + wx, mLastPoint.y + wy);
           be.xkey.window = target;
-          XSendEvent (GDK_DISPLAY(), target,
+          XSendEvent (DISPLAY(), target,
               FALSE, event.type == XKeyPress ? KeyPressMask : KeyReleaseMask, &be);
 
 
         }
       else
         {
           // If we need to send synthesized key events, then
           // DOMKeyCodeToGdkKeyCode(keyEvent.keyCode) and
@@ -4649,16 +4661,18 @@ nsEventStatus nsPluginInstanceOwner::Pro
         const nsMouseEvent& mouseEvent =
           static_cast<const nsMouseEvent&>(anEvent);
         // Get reference point relative to screen:
         nsIntPoint rootPoint(-1,-1);
         if (widget)
           rootPoint = anEvent.refPoint + widget->WidgetToScreenOffset();
 #ifdef MOZ_WIDGET_GTK2
         Window root = GDK_ROOT_WINDOW();
+#elif defined(MOZ_WIDGET_QT)
+        Window root = QX11Info::appRootWindow();
 #else
         Window root = None; // Could XQueryTree, but this is not important.
 #endif
 
         switch (anEvent.message)
           {
           case NS_MOUSE_ENTER_SYNTH:
           case NS_MOUSE_EXIT_SYNTH:
@@ -5390,26 +5404,25 @@ nsPluginInstanceOwner::Renderer::NativeD
 {
 #ifdef MOZ_X11
   Visual * visual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(drawable));
   Colormap colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(drawable));
   Screen * screen = GDK_SCREEN_XSCREEN (gdk_drawable_get_screen(drawable));
 #endif
 #elif defined(MOZ_WIDGET_QT)
 nsresult
-nsPluginInstanceOwner::Renderer::NativeDraw(QWidget * drawable,
+nsPluginInstanceOwner::Renderer::NativeDraw(gfxXlibSurface * xsurface,
+                                            Colormap colormap,
                                             short offsetX, short offsetY,
                                             QRect * clipRects,
                                             PRUint32 numClipRects)
 {
 #ifdef MOZ_X11
-  QX11Info xinfo = drawable->x11Info();
-  Visual * visual = (Visual*) xinfo.visual();
-  Colormap colormap = xinfo.colormap();
-  Screen * screen = (Screen*) xinfo.screen();
+  Visual * visual = cairo_xlib_surface_get_visual(xsurface->CairoSurface());
+  Screen *screen = cairo_xlib_surface_get_screen(xsurface->CairoSurface());
 #endif
 #endif
   // See if the plugin must be notified of new window parameters.
   PRBool doupdatewindow = PR_FALSE;
 
   if (mWindow->x != offsetX || mWindow->y != offsetY) {
     mWindow->x = offsetX;
     mWindow->y = offsetY;
@@ -5501,17 +5514,17 @@ nsPluginInstanceOwner::Renderer::NativeD
     XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
     // set the drawing info
     exposeEvent.type = GraphicsExpose;
     exposeEvent.display = DisplayOfScreen(screen);
     exposeEvent.drawable =
 #if defined(MOZ_WIDGET_GTK2)
       GDK_DRAWABLE_XID(drawable);
 #elif defined(MOZ_WIDGET_QT)
-      drawable->x11PictureHandle();
+      xsurface->XDrawable();
 #endif
     exposeEvent.x = dirtyRect.x;
     exposeEvent.y = dirtyRect.y;
     exposeEvent.width  = dirtyRect.width;
     exposeEvent.height = dirtyRect.height;
     exposeEvent.count = 0;
     // information not set:
     exposeEvent.serial = 0;
@@ -5747,22 +5760,20 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
           // Fill in the display field.
           nsIWidget* win = mObjectFrame->GetWindow();
           NPSetWindowCallbackStruct* ws_info = 
             static_cast<NPSetWindowCallbackStruct*>(mPluginWindow->ws_info);
           if (win) {
             ws_info->display =
               static_cast<Display*>(win->GetNativeData(NS_NATIVE_DISPLAY));
           }
-#ifdef MOZ_WIDGET_GTK2
           else {
-            ws_info->display = GDK_DISPLAY();
+            ws_info->display = DISPLAY();
           }
 #endif
-#endif
         } else if (mWidget) {
           mWidget->Resize(mPluginWindow->width, mPluginWindow->height,
                           PR_FALSE);
 
           // mPluginWindow->type is used in |GetPluginPort| so it must
           // be initialized first
           mPluginWindow->type = NPWindowTypeWindow;
           mPluginWindow->window = GetPluginPortFromWidget();
--- a/modules/plugin/base/src/Makefile.in
+++ b/modules/plugin/base/src/Makefile.in
@@ -79,27 +79,30 @@ else
 ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
 	CPPSRCS += nsPluginsDirOS2.cpp
 	CPPSRCS += nsPluginNativeWindowOS2.cpp
 else
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 	CPPSRCS += nsPluginsDirDarwin.cpp
 	CPPSRCS += nsPluginNativeWindow.cpp
 else
+	CPPSRCS += nsPluginsDirUnix.cpp
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-	CPPSRCS += nsPluginsDirUnix.cpp
 	CPPSRCS += nsPluginNativeWindowGtk2.cpp
 else
-	CPPSRCS += nsPluginsDirUnix.cpp
+ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
+	CPPSRCS += nsPluginNativeWindowQt.cpp
+else
 	CPPSRCS += nsPluginNativeWindow.cpp
 endif
 endif
 endif
 endif
 endif
+endif
 
 ifneq (,$(filter WINNT Darwin,$(OS_ARCH)))
 EXTRA_DSO_LIBS	+= gkgfx
 endif
 
 EXTRA_DSO_LDOPTS = \
 		$(LIBS_DIR) \
 		$(EXTRA_DSO_LIBS) \
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -31,16 +31,20 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifdef MOZ_WIDGET_QT
+#include <QX11Info>
+#endif
+
 #ifdef MOZ_IPC
 #include "base/basictypes.h"
 #endif 
 
 #include "prtypes.h"
 #include "prmem.h"
 #include "prenv.h"
 #include "prclist.h"
@@ -1834,17 +1838,17 @@ NPError NP_CALLBACK
 
   nsresult res;
 
   PluginDestructionGuard guard(npp);
 
   switch(variable) {
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
   case NPNVxDisplay : {
-#ifdef MOZ_WIDGET_GTK2
+#if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)
     if (npp) {
       nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
       PRBool windowless = PR_FALSE;
       inst->IsWindowless(&windowless);
       NPBool needXEmbed = PR_FALSE;
       if (!windowless) {
         inst->GetValueFromPlugin(NPPVpluginNeedsXEmbed, &needXEmbed);
       }
@@ -1852,36 +1856,39 @@ NPError NP_CALLBACK
 #ifdef MOZ_WIDGET_GTK2
         (*(Display **)result) = GDK_DISPLAY();
 #else
         (*(Display **)result) = QX11Info::display();
 #endif
         return NPERR_NO_ERROR;
       }
     }
+#ifdef MOZ_WIDGET_GTK2
     // adobe nppdf calls XtGetApplicationNameAndClass(display,
     // &instance, &class) we have to init Xt toolkit before get
     // XtDisplay just call gtk_xtbin_new(w,0) once
     static GtkWidget *gtkXtBinHolder = 0;
     if (!gtkXtBinHolder) {
       gtkXtBinHolder = gtk_xtbin_new(gdk_get_default_root_window(),0);
       // it crashes on destroy, let it leak
       // gtk_widget_destroy(gtkXtBinHolder);
     }
     (*(Display **)result) =  GTK_XTBIN(gtkXtBinHolder)->xtdisplay;
     return NPERR_NO_ERROR;
 #endif
+#endif
     return NPERR_GENERIC_ERROR;
   }
 
   case NPNVxtAppContext:
     return NPERR_GENERIC_ERROR;
 #endif
 
-#if defined(XP_WIN) || defined(XP_OS2) || defined(MOZ_WIDGET_GTK2)
+#if defined(XP_WIN) || defined(XP_OS2) || defined(MOZ_WIDGET_GTK2) \
+ || defined(MOZ_WIDGET_QT)
   case NPNVnetscapeWindow: {
     if (!npp || !npp->ndata)
       return NPERR_INVALID_INSTANCE_ERROR;
 
     nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
 
     nsCOMPtr<nsIPluginInstanceOwner> owner;
     inst->GetOwner(getter_AddRefs(owner));
@@ -1923,16 +1930,20 @@ NPError NP_CALLBACK
     return NPERR_NO_ERROR;
   }
 
   case NPNVToolkit: {
 #ifdef MOZ_WIDGET_GTK2
     *((NPNToolkitType*)result) = NPNVGtk2;
 #endif
 
+#ifdef MOZ_WIDGET_QT
+    /* Fake toolkit so flash plugin works */
+    *((NPNToolkitType*)result) = NPNVGtk2;
+#endif
     if (*(NPNToolkitType*)result)
         return NPERR_NO_ERROR;
 
     return NPERR_GENERIC_ERROR;
   }
 
   case NPNVSupportsXEmbedBool: {
 #ifdef MOZ_WIDGET_GTK2
@@ -1951,17 +1962,18 @@ NPError NP_CALLBACK
 
   case NPNVPluginElementNPObject: {
     *(NPObject **)result = _getpluginelement(npp);
 
     return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
   }
 
   case NPNVSupportsWindowless: {
-#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2))
+#if defined(XP_WIN) || defined(XP_MACOSX) || \
+    (defined(MOZ_X11) && (defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)))
     *(NPBool*)result = PR_TRUE;
 #else
     *(NPBool*)result = PR_FALSE;
 #endif
     return NPERR_NO_ERROR;
   }
 
   case NPNVprivateModeBool: {
new file mode 100644
--- /dev/null
+++ b/modules/plugin/base/src/nsPluginNativeWindowQt.cpp
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Robin Lu <robin.lu@sun.com>
+ *   Miika Jarvinen <mjarvin@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *  This file is the Qt implementation of plugin native window.
+ */
+
+#include "nsDebug.h"
+#include "nsPluginNativeWindow.h"
+#include "npapi.h"
+
+/**
+ * Qt implementation of plugin window
+ */
+class nsPluginNativeWindowQt : public nsPluginNativeWindow
+{
+public:
+  nsPluginNativeWindowQt();
+  virtual ~nsPluginNativeWindowQt();
+
+  virtual nsresult CallSetWindow(nsCOMPtr<nsIPluginInstance> &aPluginInstance);
+private:
+
+  NPSetWindowCallbackStruct mWsInfo;
+};
+
+nsPluginNativeWindowQt::nsPluginNativeWindowQt() : nsPluginNativeWindow()
+{
+  //Initialize member variables
+#ifdef DEBUG
+  fprintf(stderr,"\n\n\nCreating plugin native window %p\n\n\n", (void *) this);
+#endif
+  window = nsnull;
+  x = 0;
+  y = 0;
+  width = 0;
+  height = 0;
+  memset(&clipRect, 0, sizeof(clipRect));
+  ws_info = &mWsInfo;
+  type = NPWindowTypeWindow;
+  mWsInfo.type = 0;
+  mWsInfo.display = nsnull;
+  mWsInfo.visual = nsnull;
+  mWsInfo.colormap = 0;
+  mWsInfo.depth = 0;
+}
+
+nsPluginNativeWindowQt::~nsPluginNativeWindowQt()
+{
+#ifdef DEBUG
+  fprintf(stderr,"\n\n\nDestoying plugin native window %p\n\n\n", (void *) this);
+#endif
+}
+
+nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow **aPluginNativeWindow)
+{
+  NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
+  *aPluginNativeWindow = new nsPluginNativeWindowQt();
+  return *aPluginNativeWindow ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
+{
+  NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
+  nsPluginNativeWindowQt *p = (nsPluginNativeWindowQt *)aPluginNativeWindow;
+  delete p;
+  return NS_OK;
+}
+
+nsresult nsPluginNativeWindowQt::CallSetWindow(nsCOMPtr<nsIPluginInstance> &aPluginInstance)
+{
+  if (aPluginInstance) {
+    if (type == NPWindowTypeWindow) {
+      return NS_ERROR_FAILURE;
+    } // NPWindowTypeWindow
+    aPluginInstance->SetWindow(this);
+  }
+  else if (mPluginInstance)
+    mPluginInstance->SetWindow(nsnull);
+
+  SetPluginInstance(aPluginInstance);
+  return NS_OK;
+}
--- a/modules/plugin/test/testplugin/Makefile.in
+++ b/modules/plugin/test/testplugin/Makefile.in
@@ -67,16 +67,23 @@ CPPSRCS += nptest_gtk2.cpp
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
 CPPSRCS += nptest_os2.cpp
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
 CPPSRCS += nptest_qt.cpp
+include $(topsrcdir)/config/config.mk
+CXXFLAGS        += $(MOZ_QT_CFLAGS)
+CFLAGS          += $(MOZ_QT_CFLAGS)
+EXTRA_DSO_LDOPTS = \
+                $(MOZ_QT_LIBS) \
+                $(XLDFLAGS) \
+                $(XLIBS)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 CPPSRCS  += nptest_windows.cpp
 RCFILE    = nptest.rc
 RESFILE   = nptest.res
 DEFFILE   = $(win_srcdir)/nptest.def
 OS_LIBS  += $(call EXPAND_LIBNAME,msimg32)
--- a/modules/plugin/test/testplugin/nptest_qt.cpp
+++ b/modules/plugin/test/testplugin/nptest_qt.cpp
@@ -25,19 +25,29 @@
  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * 
  * Contributor(s):
  *   Josh Aas <josh@mozilla.com>
  * 
  * ***** END LICENSE BLOCK ***** */
+#include <QWidget>
+#include <QPainter>
 
 #include "nptest_platform.h"
+#include "npapi.h"
 
+struct _PlatformData {
+#ifdef MOZ_X11
+  Display* display;
+  Visual* visual;
+  Colormap colormap;
+#endif
+};
  using namespace std;
 
 bool
 pluginSupportsWindowMode()
 {
   return false;
 }
 
@@ -45,38 +55,142 @@ bool
 pluginSupportsWindowlessMode()
 {
   return true;
 }
 
 NPError
 pluginInstanceInit(InstanceData* instanceData)
 {
+#ifdef MOZ_X11
+  instanceData->platformData = static_cast<PlatformData*>
+    (NPN_MemAlloc(sizeof(PlatformData)));
+  if (!instanceData->platformData){
+    //printf("NPERR_OUT_OF_MEMORY_ERROR\n");
+    return NPERR_OUT_OF_MEMORY_ERROR;
+  }
+
+  instanceData->platformData->display = NULL;
+  instanceData->platformData->visual = NULL;
+  instanceData->platformData->colormap = None;
+
+  return NPERR_NO_ERROR;
+#else
+  printf("NPERR_INCOMPATIBLE_VERSION_ERROR\n");
+  return NPERR_INCOMPATIBLE_VERSION_ERROR;
+#endif
   return NPERR_NO_ERROR;
 }
 
 void
 pluginInstanceShutdown(InstanceData* instanceData)
 {
+  NPN_MemFree(instanceData->platformData);
+  instanceData->platformData = 0;
 }
 
 void
 pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
 {
   instanceData->window = *newWindow;
 }
 
 void
 pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
 {
+  // XXX nothing here yet since we don't support windowed plugins
+}
+
+static void
+pluginDrawWindow(InstanceData* instanceData, void* event)
+{
+  NPWindow& window = instanceData->window;
+  // When we have a widget, window.x/y are meaningless since our
+  // widget is always positioned correctly and we just draw into it at 0,0
+  int x = instanceData->hasWidget ? 0 : window.x;
+  int y = instanceData->hasWidget ? 0 : window.y;
+  int width = window.width;
+  int height = window.height;
+
+  XEvent* nsEvent = (XEvent*)event;
+  const XGraphicsExposeEvent& expose = nsEvent->xgraphicsexpose;
+
+  QColor drawColor((QColor)instanceData->scriptableObject->drawColor);//QRgb qRgba ( int r, int g, int b, int a )
+  QPixmap pixmap = QPixmap::fromX11Pixmap(expose.drawable, QPixmap::ExplicitlyShared);
+
+  QRect exposeRect(expose.x, expose.y, expose.width, expose.height);
+  if (instanceData->scriptableObject->drawMode == DM_SOLID_COLOR) {
+    //printf("Drawing Solid\n");
+    // drawing a solid color for reftests
+    QPainter painter(&pixmap);
+    painter.fillRect(exposeRect, drawColor);
+    notifyDidPaint(instanceData);
+    return;
+
+  }
+
+  NPP npp = instanceData->npp;
+  if (!npp)
+    return;
+
+  QString text (NPN_UserAgent(npp));
+  if (text.isEmpty())
+    return;
+
+  //printf("Drawing Default\n");
+  // drawing a solid color for reftests
+  QColor color;
+  QPainter painter(&pixmap);
+  QRect theRect(x, y, width, height);
+  QRect clipRect(QPoint(window.clipRect.left, window.clipRect.top),
+                 QPoint(window.clipRect.right, window.clipRect.bottom));
+  painter.setClipRect(clipRect);
+  painter.fillRect(theRect, QColor(128,128,128,255));
+  painter.drawRect(theRect);
+  painter.drawText(QRect(theRect), Qt::AlignCenter, text);
+  notifyDidPaint(instanceData);
+  return;
 }
 
 int16_t
 pluginHandleEvent(InstanceData* instanceData, void* event)
 {
+#ifdef MOZ_X11
+  XEvent* nsEvent = (XEvent*)event;
+  //printf("\nEvent Type %d\n", nsEvent->type);
+  switch (nsEvent->type) {
+  case GraphicsExpose: {
+    //printf("GraphicsExpose\n");
+
+    pluginDrawWindow(instanceData, event);
+    break;
+  }
+  case MotionNotify: {
+    //printf("MotionNotify\n");
+    XMotionEvent* motion = &nsEvent->xmotion;
+    instanceData->lastMouseX = motion->x;
+    instanceData->lastMouseY = motion->y;
+    break;
+  }
+  case ButtonPress:{
+    ////printf("ButtonPress\n");
+    break;
+  }
+  case ButtonRelease: {
+    //printf("ButtonRelease\n");
+    XButtonEvent* button = &nsEvent->xbutton;
+    instanceData->lastMouseX = button->x;
+    instanceData->lastMouseY = button->y;
+    break;
+  }
+  default:
+    break;
+  }
+#endif
+
   return 0;
 }
 
 int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
 {
   // XXX nothing here yet since we don't support windowed plugins
   return NPTEST_INT32_ERROR;
 }
--- a/widget/src/qt/nsWindow.cpp
+++ b/widget/src/qt/nsWindow.cpp
@@ -1896,21 +1896,17 @@ void
 nsWindow::GetToplevelWidget(MozQWidget **aWidget)
 {
     *aWidget = mWidget;
 }
 
 void *
 nsWindow::SetupPluginPort(void)
 {
-    if (!mWidget)
-        return nsnull;
-
-    qDebug("FIXME:>>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
-
+    NS_WARNING("Not implemented");
     return nsnull;
 }
 
 nsresult
 nsWindow::SetWindowIconList(const nsTArray<nsCString> &aIconList)
 {
     QIcon icon;