[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