| 1 | This page documents the current status, code overview of (netscape) plugins on Qt/WebKit. Feel free to substitute 'plugins' with 'flash' when reading this document (since it's the main plugin we test with). |
| 2 | |
| 3 | = Overview = |
| 4 | Qt/WebKit supports loading of netscape plugins. To enable loading of plugins, you must enable QWebSettings::PluginsEnabled. |
| 5 | |
| 6 | = Hacking = |
| 7 | The NPAPI does not have very clear documentation but the following links will help you started |
| 8 | * https://developer.mozilla.org/en/Plugins |
| 9 | * https://developer.mozilla.org/en/Gecko_Plugin_API_Reference |
| 10 | |
| 11 | Netscape plugins operate in two modes: |
| 12 | * Windowed mode - The plugin has a native window handle of it's own. This means that the plugin has complete control over mouse, keyboard, paint events. It can do whatever it wants, whenever it wants. |
| 13 | * Windowless mode - The plugin does not have a native window. Instead it relies on the browser to tell it where to paint and expects the browser to provide it with keyboard/mouse events. See [https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Drawing_and_Event_Handling mozilla site] for more information. |
| 14 | |
| 15 | Flash has a wmode parameter that triggers the above modes. The default is Windowed mode. When wmode is 'transparent' or 'opaque', flash requests windowless mode. Note that the mode used ultimately resides with the plugin (i.e the browser cannot force a mode). |
| 16 | |
| 17 | = WebKit Plugins = |
| 18 | Most of the code resides under WebCore/plugins. The Qt specific stuff under WebCore/plugins/qt. Here's a high level overview of the classes: |
| 19 | * PluginsQuirkSet.h - Plugins are buggy. WebKit has special code to workaround various bugs/features of plugins. You will find these 'quirks' listed here. |
| 20 | * PluginPackage.cpp - Represents the plugin library file (i.e .so or .dll). Loads the plugin, determines the mimetype and sets appropriate quirks |
| 21 | * PluginView.cpp - Represents an instance of the plugin. It is a Widget. When loading a page, this widget pointer is inside a RenderWidget. |
| 22 | * PluginStream.cpp - The plugin and browser communicate with each other using NPStreams. For example, the source file (src) is pushed to the plugin by the browser using a PluginStream. |
| 23 | * PluginDatabase.cpp - Takes care of locating the plugin library file. Provides PluginPackage(s). |
| 24 | |
| 25 | QWebPageClient - We require access to the QWidget (QGraphicsView/QWebView) or the parent (QGraphicsWebView/QWebView). To provide this and keep the plugin code working in both cases, the chrome (hostwindow) provides a platformPageClient() that helps us get information about the client of the QWebPage. Both QWebView and QGraphicsWebView provide objects that implement the virtuals in QWebPageClient. |
| 26 | |
| 27 | = Platform Specific = |
| 28 | == X11 == |
| 29 | [http://multimedia.cx/diamondx/ Diamondx] is a good start to understand how netscape plugins are written. You can clone the source from [http://git.forwardbias.in/?p=diamondx.git git://git.forwardbias.in/diamondx.git]. |
| 30 | |
| 31 | PluginViewQt.cpp contains Qt specific view code for plugins. |
| 32 | |
| 33 | === Windowed mode === |
| 34 | |
| 35 | Windowed mode is implemented using XEmbed (other technique that uses Xt is not implemented). The spec is [https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins here]. |
| 36 | |
| 37 | Qt port uses QX11EmbedContainer to host the plugin. PluginView creates PluginContainerQt (which is a QX11EmbedContainer). |
| 38 | |
| 39 | This mode works well in QWebView. It works in QGraphicsWebView as long as there is no transformation on the QGraphicsView or the item. To make it work with transformations, we are trying out an approach based on XComposite/XDamage (like in fennec) |
| 40 | |
| 41 | === Windowless mode === |
| 42 | |
| 43 | Windowless mode is implemented by drawing to a X Drawable. Conceptually, it's very simple, however mixing toolkits and flash bugs make it quite complex. |
| 44 | * Flash uses gdk. Gdk uses a different X connection from Qt. This means that we have to flush the gdk display periodically. If you find your scrolling jittery, this is the case of that. In the ideal work, flash is supposed to use the Display provided using the npapi, but it doesn't. |
| 45 | * Flash cannot paint on argb32 pixmaps since it does not use the visual provided using the npapi (it uses gdk_default_system_visual instead). This makes it very hard to implement transparency. For QWebView, we grab contents from the backing store to implement transparency. For all other cases, transparency is turned off (except when the default system visual is 32-bit). |
| 46 | |
| 47 | Transformation, opacity of item QGraphicsWebView in QGraphicsView is supported. Windowless mode is not supported when using QWebView inside QGraphicsView. We will need XComposite/XDamage support for that. |
| 48 | |
| 49 | === Testing === |
| 50 | |
| 51 | Depending on your WebKit codebase knowledge, hacking on plugins inside WebKit can be a case of having too many unknowns. We have developed npploader, a simple Qt program that can load Flash in a QWidget. You can get it by cloning from [http://git.forwardbias.in/?p=npploader.git git://git.forwardbias.in/npploader.git]. |
| 52 | |
| 53 | Usage: |
| 54 | * Works only in X11 (as of now) |
| 55 | * Modify PLUGIN_* in main.cpp to the correct paths. |
| 56 | * By default, loads in windowed mode. Pass '-windowless' to command line for windowless mode. |
| 57 | * The pixmap32 branch implements windowless mode painting of plugins into a 32-bit pixmap (i.e if flash was fixed). You can test it with the diamondx's pixmap32 branch (http://git.forwardbias.in/?p=diamondx.git). |
| 58 | * The flashtransparecyhack branch overrides the gdk_default_visual to make it return a 32-bit visual. Flash can now paint to 32-bit pixmaps. Note that this approach was not considered for WebKit because of -Bsymbolic-functions. |
| 59 | |
| 60 | == Windows == |
| 61 | TODO |
| 62 | |
| 63 | == Symbian == |
| 64 | TODO |
| 65 | |
| 66 | == Mac == |
| 67 | TODO |
| 68 | |
| 69 | = TODO List = |
| 70 | * Share code among all ports. Currently, there is a lot of code duplicaton amongst symbian, Qt ports. Gtk is still to come and will presumably require very similar code. |
| 71 | * X11 - Implement XComposite/XDamage in QX11EmbedContainer. Status: work in progress. |
| 72 | * X11 - Context menus not working in windowless mode. Status: no solution in sight. |
| 73 | * X11 - Windowed mode doesn't work when the same page is switched between views. In general, we need a clean way for the plugin to track changes in ownerWidget(). |
| 74 | |
| 75 | = Testing = |
| 76 | Use the [http://www.communitymx.com/content/source/E5141/wmodetrans.htm communityx site] for testing various modes. |
| 77 | |
| 78 | = Open bugs = |
| 79 | Use this [https://bugs.webkit.org/buglist.cgi?short_desc_type=allwordssubstr&short_desc=&product=WebKit&component=Plug-ins&long_desc_type=allwordssubstr&long_desc=&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&keywords_type=allwords&keywords=Qt&order=Importance filter]. |
| 80 | |
| 81 | -- Girish (girish@forwardbias.in) |