[vlc-commits] Add XCB windowless

Ludovic Fauvet git at videolan.org
Fri Dec 21 19:39:25 CET 2012


npapi-vlc | branch: master | Ludovic Fauvet <etix at videolan.org> | Thu Dec 20 21:11:58 2012 +0100| [8e2e1b17a6b13d570cd85b52fb252ec301c40ff1] | committer: Ludovic Fauvet

Add XCB windowless

> http://git.videolan.org/gitweb.cgi/npapi-vlc.git/?a=commit;h=8e2e1b17a6b13d570cd85b52fb252ec301c40ff1
---

 configure.ac                |    6 +-
 npapi/Makefile.am           |   17 +++--
 npapi/vlcplugin.h           |    7 ++
 npapi/vlcwindowless_xcb.cpp |  148 +++++++++++++++++++++++++++++++++++++++++++
 npapi/vlcwindowless_xcb.h   |   49 ++++++++++++++
 5 files changed, 222 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 58cb7bd..385e8fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,20 +243,24 @@ dnl GTK+ for linux toolbar
 AC_ARG_WITH([gtk], AS_HELP_STRING([--with-gtk], [Build the GTK+ toolbars in NPAPI plugin [default=auto]]),, [with_gtk=yes])
 gtk_found=no
 AS_IF([ test "${SYS}" != "mingw32" -a "${SYS}" != "darwin" ], [
+  PKG_CHECK_MODULES(XCB, [xcb xcb-image],[xcb_found=yes])
   AS_IF([ test "x$with_gtk" != "xno" ],
     [
        PKG_CHECK_MODULES(GTK, [gtk+-2.0], [gtk_found=yes])
     ])
   AS_IF([ test "x$gtk_found" == "xno" ],
     [
-      PKG_CHECK_MODULES(XCB, [xcb],, [
+      AS_IF([ test "x$xcb_found" == "xno"], [
         AC_MSG_ERROR([Please install the libxcb development files, or re-run configure with --with-gtk])
       ])
     ])
 ])
 AS_IF([ test "x$gtk_found" = "xyes" ],
     AC_DEFINE([USE_GTK], [1], [Define to 1 if using GTK+]))
+AS_IF([ test "x$xcb_found" = "xyes" ],
+    AC_DEFINE([USE_XCB], [1], [Define to 1 if using XCB]))
 AM_CONDITIONAL(WITH_GTK, [ test "x$gtk_found" = "xyes" ])
+AM_CONDITIONAL(HAVE_XCB, [ test "x$xcb_found" = "xyes" ])
 
 dnl
 dnl final flags for ActiveX
diff --git a/npapi/Makefile.am b/npapi/Makefile.am
index 0435fb9..1cfb732 100644
--- a/npapi/Makefile.am
+++ b/npapi/Makefile.am
@@ -61,22 +61,31 @@ endif
 AM_CPPFLAGS += -DXP_UNIX -DDATA_PATH=\"$(pkgdatadir)\"
 libvlcplugin_la_LIBADD += $(MOZILLA_LIBS)
 
+SOURCES_support = \
+	support/npunix.cpp
+
 if WITH_GTK
 AM_CPPFLAGS += $(GTK_CFLAGS)
 libvlcplugin_la_LIBADD += $(GTK_LIBS) $(X_LIBS) $(X_PRE_LIBS) -lX11
-SOURCES_support = \
-	support/npunix.cpp \
+SOURCES_support += \
 	vlcplugin_gtk.cpp \
 	vlcplugin_gtk.h
 else # !WITH_GTK
 AM_CPPFLAGS += $(XCB_CFLAGS)
 libvlcplugin_la_LIBADD += $(XCB_LIBS)
-SOURCES_support = \
-	support/npunix.cpp \
+SOURCES_support += \
 	vlcplugin_xcb.cpp \
 	vlcplugin_xcb.h
 endif # !USE_GTK
 
+if HAVE_XCB
+AM_CPPFLAGS += $(XCB_CFLAGS)
+libvlcplugin_la_LIBADD += $(XCB_LIBS)
+SOURCES_support += \
+	vlcwindowless_xcb.cpp \
+	vlcwindowless_xcb.h
+endif # !HAVE_XCB
+
 else # Win32
 
 # Under Win32|Mac, Mozilla plugins need to be named NP******.DLL, but under Unix
diff --git a/npapi/vlcplugin.h b/npapi/vlcplugin.h
index f74514f..1bcc58a 100644
--- a/npapi/vlcplugin.h
+++ b/npapi/vlcplugin.h
@@ -33,7 +33,14 @@
 # include "config.h"
 #endif
 
+#include "common.h"
+
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
+#   if defined(USE_XCB)
+#       define WINDOWLESS
+#       include "vlcwindowless_xcb.h"
+        typedef VlcWindowlessXCB VlcWindowless;
+#   endif
 #   if defined(USE_GTK)
 #       include "vlcplugin_gtk.h"
         typedef class VlcPluginGtk VlcPlugin;
diff --git a/npapi/vlcwindowless_xcb.cpp b/npapi/vlcwindowless_xcb.cpp
new file mode 100644
index 0000000..f454d50
--- /dev/null
+++ b/npapi/vlcwindowless_xcb.cpp
@@ -0,0 +1,148 @@
+/*****************************************************************************
+ * vlcwindowless_XCB.cpp: a VLC plugin for Mozilla (XCB windowless)
+ *****************************************************************************
+ * Copyright © 2012 VideoLAN
+ * $Id$
+ *
+ * Authors: Ludovic Fauvet <etix at videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "vlcwindowless_xcb.h"
+
+#include <X11/Xlib-xcb.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_image.h>
+
+#include <cstring>
+#include <cstdlib>
+
+VlcWindowlessXCB::VlcWindowlessXCB(NPP instance, NPuint16_t mode) :
+    VlcWindowlessBase(instance, mode), m_conn(0), m_screen(0)
+{
+    //FIXME Avoid using XOpenDisplay in an XCB context
+    Display *display = XOpenDisplay(NULL);
+    if (!(m_conn = XGetXCBConnection(display)))
+    {
+        fprintf(stderr, "Can't connect to XCB\n");
+        return;
+    }
+
+    /* Retrieve the setup */
+    const xcb_setup_t *setup;
+    if (!(setup = xcb_get_setup(m_conn)))
+    {
+        fprintf(stderr, "Can't get the XCB setup\n");
+        return;
+    }
+
+    /* Get the first screen */
+    m_screen = xcb_setup_roots_iterator(setup).data;
+}
+
+VlcWindowlessXCB::~VlcWindowlessXCB()
+{
+    xcb_disconnect(m_conn);
+}
+
+void VlcWindowlessXCB::drawBackground(xcb_drawable_t drawable)
+{
+    /* Obtain the background color */
+    xcb_colormap_t colormap = m_screen->default_colormap;
+    unsigned r = 0, g = 0, b = 0;
+    HTMLColor2RGB(get_options().get_bg_color().c_str(), &r, &g, &b);
+    xcb_alloc_color_reply_t *reply = xcb_alloc_color_reply(m_conn,
+            xcb_alloc_color(m_conn, colormap,
+                            (uint16_t) r << 8,
+                            (uint16_t) g << 8,
+                            (uint16_t) b << 8), NULL);
+    uint32_t colorpixel = reply->pixel;
+    free(reply);
+
+    /* Prepare to fill the background */
+    xcb_gcontext_t background = xcb_generate_id(m_conn);
+    uint32_t        mask       = XCB_GC_BACKGROUND | XCB_GC_GRAPHICS_EXPOSURES;
+    uint32_t        values[2]  = {0, colorpixel};
+    xcb_create_gc(m_conn, background, drawable, mask, values);
+    xcb_rectangle_t rect;
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = npwindow.width;
+    rect.height = npwindow.height;
+
+    /* Fill the background */
+    xcb_poly_fill_rectangle(m_conn, drawable, background, 1, &rect);
+    xcb_free_gc(m_conn, background);
+}
+
+bool VlcWindowlessXCB::handle_event(void *event)
+{
+    XEvent *xevent = static_cast<XEvent *>(event);
+    switch (xevent->type) {
+    case GraphicsExpose:
+
+        XGraphicsExposeEvent *xgeevent = reinterpret_cast<XGraphicsExposeEvent *>(xevent);
+
+        /* Something went wrong during initialization */
+        if (!m_conn || !m_screen)
+            break;
+
+        drawBackground(xgeevent->drawable);
+
+        /* Validate video size */
+        if (m_media_width == 0 || m_media_height == 0)
+            break;
+
+        /* Create our X11 image */
+        xcb_image_t *image = xcb_image_create_native(
+                            m_conn,
+                            m_media_width,
+                            m_media_height,
+                            XCB_IMAGE_FORMAT_Z_PIXMAP,
+                            24,
+                            &m_frame_buf[0],
+                            m_frame_buf.size(),
+                            NULL
+                    );
+
+        /* Compute the position of the video */
+        int left = (npwindow.width  - m_media_width)  / 2;
+        int top  = (npwindow.height - m_media_height) / 2;
+
+        /* TODO Expose:
+
+        xcb_pixmap_t pmap = xcb_generate_id(m_conn);
+        xcb_create_pixmap(m_conn, 24, pmap, xgeevent->drawable, m_media_width, m_media_height);
+
+        gc = xcb_generate_id(m_conn);
+        xcb_create_gc(m_conn, gc, xgeevent->drawable, 0, NULL);
+        xcb_image_put(m_conn, pmap, gc, image, left, top, 0);
+        xcb_copy_area(m_conn, pmap, xgeevent->drawable, gc, 0, 0, 0, 0, m_media_width, m_media_height);
+        */
+
+        /* Push the frame in X11 */
+        xcb_gcontext_t  gc = xcb_generate_id(m_conn);
+        xcb_create_gc(m_conn, gc, xgeevent->drawable, 0, NULL);
+
+        //FIXME xcb_put_image_checked is more efficient than xcb_image_*
+        xcb_image_put(m_conn, xgeevent->drawable, gc, image, left, top, 0);
+
+        /* Flush the the connection */
+        xcb_flush(m_conn);
+        xcb_free_gc(m_conn, gc);
+    }
+    return VlcWindowlessBase::handle_event(event);
+}
diff --git a/npapi/vlcwindowless_xcb.h b/npapi/vlcwindowless_xcb.h
new file mode 100644
index 0000000..94227ab
--- /dev/null
+++ b/npapi/vlcwindowless_xcb.h
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * vlcwindowless_XCB.h: a VLC plugin for Mozilla (XCB windowless)
+ *****************************************************************************
+ * Copyright © 2012 VideoLAN
+ * $Id$
+ *
+ * Authors: Ludovic Fauvet <etix at videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef __VLCWINDOWLESS_XCB_H__
+#define __VLCWINDOWLESS_XCB_H__
+
+#define WINDOWLESS
+#include "vlcplugin_base.h"
+
+#include <X11/Xlib-xcb.h>
+
+class VlcWindowlessXCB : public VlcWindowlessBase
+{
+public:
+    VlcWindowlessXCB(NPP instance, NPuint16_t mode);
+    virtual ~VlcWindowlessXCB();
+
+    bool handle_event(void *event);
+
+protected:
+    void drawBackground(xcb_drawable_t drawable);
+
+private:
+    xcb_connection_t *m_conn;
+    xcb_screen_t *m_screen;
+};
+
+
+#endif /* __VLCWINDOWLESS_XCB_H__ */



More information about the vlc-commits mailing list