aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2013-10-26 21:07:14 +0200
committerSylvain Munaut <tnt@246tNt.com>2013-10-26 21:07:14 +0200
commit6183eefc9affd61c775b1aba51ad5a3c4719468f (patch)
tree7c2f642defe2ad3d9bda81f1c2e5cf58bf2dce35
parente3732c0609fd25e3da3e9bcf25d6aaece88373fb (diff)
gr-fosphor: Add Qt widget version of the fosphor sink
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--CMakeLists.txt3
-rw-r--r--cmake/Modules/GrSetupQt4.cmake156
-rw-r--r--grc/CMakeLists.txt1
-rw-r--r--grc/fosphor_qt_sink_c.xml29
-rw-r--r--include/gnuradio/fosphor/CMakeLists.txt1
-rw-r--r--include/gnuradio/fosphor/qt_sink_c.h68
-rw-r--r--lib/CMakeLists.txt6
-rw-r--r--lib/QGLSurface.cc81
-rw-r--r--lib/QGLSurface.h49
-rw-r--r--lib/qt_sink_c_impl.cc97
-rw-r--r--lib/qt_sink_c_impl.h66
-rw-r--r--swig/fosphor_swig.i4
12 files changed, 561 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f716957..35debec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -112,6 +112,9 @@ if(NOT FREETYPE2_FOUND)
message(FATAL_ERROR "freetype2 required to compile gr-fosphor")
endif()
+find_package(Qt4 4.2.0 COMPONENTS QtCore QtGui QtOpenGL)
+include(GrSetupQt4)
+
########################################################################
# Find gnuradio build dependencies
diff --git a/cmake/Modules/GrSetupQt4.cmake b/cmake/Modules/GrSetupQt4.cmake
new file mode 100644
index 0000000..312b415
--- /dev/null
+++ b/cmake/Modules/GrSetupQt4.cmake
@@ -0,0 +1,156 @@
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+if(DEFINED __INCLUDED_GR_USEQT4_CMAKE)
+ return()
+endif()
+set(__INCLUDED_GR_USEQT4_CMAKE TRUE)
+
+# This file is derived from the default "UseQt4" file provided by
+# CMake. This version sets the variables "QT_INCLUDE_DIRS",
+# "QT_LIBRARIES", and "QT_LIBRARIES_PLUGINS" depending on those
+# requested during the "find_package(Qt4 ...)" function call, but
+# without actually adding them to the include or library search
+# directories ("include_directories" or "link_directories"). The
+# adding in is done by the CMakeLists.txt build scripts in the using
+# project.
+
+# Copyright from the original file, as required by the license.
+################################################################
+# CMake - Cross Platform Makefile Generator
+# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the names of Kitware, Inc., the Insight Software Consortium,
+# nor the names of their contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 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.
+################################################################
+
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG QT_DEBUG)
+SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)
+SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG)
+SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG)
+IF(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
+ SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS QT_NO_DEBUG)
+ENDIF()
+
+SET(QT_INCLUDE_DIRS ${QT_INCLUDE_DIR})
+SET(QT_LIBRARIES "")
+SET(QT_LIBRARIES_PLUGINS "")
+
+IF (QT_USE_QTMAIN)
+ IF (Q_WS_WIN)
+ SET(QT_LIBRARIES ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY})
+ ENDIF (Q_WS_WIN)
+ENDIF (QT_USE_QTMAIN)
+
+IF(QT_DONT_USE_QTGUI)
+ SET(QT_USE_QTGUI 0)
+ELSE(QT_DONT_USE_QTGUI)
+ SET(QT_USE_QTGUI 1)
+ENDIF(QT_DONT_USE_QTGUI)
+
+IF(QT_DONT_USE_QTCORE)
+ SET(QT_USE_QTCORE 0)
+ELSE(QT_DONT_USE_QTCORE)
+ SET(QT_USE_QTCORE 1)
+ENDIF(QT_DONT_USE_QTCORE)
+
+IF (QT_USE_QT3SUPPORT)
+ ADD_DEFINITIONS(-DQT3_SUPPORT)
+ENDIF (QT_USE_QT3SUPPORT)
+
+# list dependent modules, so dependent libraries are added
+SET(QT_QT3SUPPORT_MODULE_DEPENDS QTGUI QTSQL QTXML QTNETWORK QTCORE)
+SET(QT_QTSVG_MODULE_DEPENDS QTGUI QTXML QTCORE)
+SET(QT_QTUITOOLS_MODULE_DEPENDS QTGUI QTXML QTCORE)
+SET(QT_QTHELP_MODULE_DEPENDS QTGUI QTSQL QTXML QTNETWORK QTCORE)
+IF(QT_QTDBUS_FOUND)
+ SET(QT_PHONON_MODULE_DEPENDS QTGUI QTDBUS QTCORE)
+ELSE(QT_QTDBUS_FOUND)
+ SET(QT_PHONON_MODULE_DEPENDS QTGUI QTCORE)
+ENDIF(QT_QTDBUS_FOUND)
+SET(QT_QTDBUS_MODULE_DEPENDS QTXML QTCORE)
+SET(QT_QTXMLPATTERNS_MODULE_DEPENDS QTNETWORK QTCORE)
+SET(QT_QAXCONTAINER_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QAXSERVER_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTSCRIPTTOOLS_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTWEBKIT_MODULE_DEPENDS QTXMLPATTERNS QTGUI QTCORE)
+SET(QT_QTDECLARATIVE_MODULE_DEPENDS QTSCRIPT QTSVG QTSQL QTXMLPATTERNS QTGUI QTCORE)
+SET(QT_QTMULTIMEDIA_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTOPENGL_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTSCRIPT_MODULE_DEPENDS QTCORE)
+SET(QT_QTGUI_MODULE_DEPENDS QTCORE)
+SET(QT_QTTEST_MODULE_DEPENDS QTCORE)
+SET(QT_QTXML_MODULE_DEPENDS QTCORE)
+SET(QT_QTSQL_MODULE_DEPENDS QTCORE)
+SET(QT_QTNETWORK_MODULE_DEPENDS QTCORE)
+
+# Qt modules (in order of dependence)
+FOREACH(module QT3SUPPORT QTOPENGL QTASSISTANT QTDESIGNER QTMOTIF QTNSPLUGIN
+ QAXSERVER QAXCONTAINER QTDECLARATIVE QTSCRIPT QTSVG QTUITOOLS QTHELP
+ QTWEBKIT PHONON QTSCRIPTTOOLS QTMULTIMEDIA QTXMLPATTERNS QTGUI QTTEST
+ QTDBUS QTXML QTSQL QTNETWORK QTCORE)
+
+ IF (QT_USE_${module} OR QT_USE_${module}_DEPENDS)
+ IF (QT_${module}_FOUND)
+ IF(QT_USE_${module})
+ STRING(REPLACE "QT" "" qt_module_def "${module}")
+ ADD_DEFINITIONS(-DQT_${qt_module_def}_LIB)
+ SET(QT_INCLUDE_DIRS ${QT_INCLUDE_DIRS} ${QT_${module}_INCLUDE_DIR})
+ ENDIF(QT_USE_${module})
+ SET(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIBRARY})
+ SET(QT_LIBRARIES_PLUGINS ${QT_LIBRARIES_PLUGINS} ${QT_${module}_PLUGINS})
+ IF(QT_IS_STATIC)
+ SET(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIB_DEPENDENCIES})
+ ENDIF(QT_IS_STATIC)
+ FOREACH(depend_module ${QT_${module}_MODULE_DEPENDS})
+ SET(QT_USE_${depend_module}_DEPENDS 1)
+ ENDFOREACH(depend_module ${QT_${module}_MODULE_DEPENDS})
+ ELSE (QT_${module}_FOUND)
+ MESSAGE("Qt ${module} library not found.")
+ ENDIF (QT_${module}_FOUND)
+ ENDIF (QT_USE_${module} OR QT_USE_${module}_DEPENDS)
+
+ENDFOREACH(module)
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index 3445fa0..94a5986 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -18,6 +18,7 @@
# Boston, MA 02110-1301, USA.
install(FILES
fosphor_glfw_sink_c.xml
+ fosphor_qt_sink_c.xml
fosphor_wx_sink_c.xml
DESTINATION share/gnuradio/grc/blocks
)
diff --git a/grc/fosphor_qt_sink_c.xml b/grc/fosphor_qt_sink_c.xml
new file mode 100644
index 0000000..d6c99f4
--- /dev/null
+++ b/grc/fosphor_qt_sink_c.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<block>
+ <name>QT fosphor sink</name>
+ <key>fosphor_qt_sink_c</key>
+ <category>Instrumentation/QT</category>
+ <import>from PyQt4 import Qt</import>
+ <import>import sip</import>
+ <import>from gnuradio import fosphor</import>
+ <make>#set $win = 'self._%s_win'%$id
+fosphor.qt_sink_c()
+self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
+$(gui_hint()($win))</make>
+ <param>
+ <name>GUI Hint</name>
+ <key>gui_hint</key>
+ <value></value>
+ <type>gui_hint</type>
+ <hide>part</hide>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <doc>
+The GUI hint can be used to position the widget within the application. \
+The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
+Both the tab specification and the grid position are optional.
+ </doc>
+</block>
diff --git a/include/gnuradio/fosphor/CMakeLists.txt b/include/gnuradio/fosphor/CMakeLists.txt
index eb38aa8..1d6f9b9 100644
--- a/include/gnuradio/fosphor/CMakeLists.txt
+++ b/include/gnuradio/fosphor/CMakeLists.txt
@@ -24,6 +24,7 @@ install(FILES
api.h
base_sink_c.h
glfw_sink_c.h
+ qt_sink_c.h
wx_core_sink_c.h
DESTINATION include/gnuradio/fosphor
)
diff --git a/include/gnuradio/fosphor/qt_sink_c.h b/include/gnuradio/fosphor/qt_sink_c.h
new file mode 100644
index 0000000..67fb87d
--- /dev/null
+++ b/include/gnuradio/fosphor/qt_sink_c.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This 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 3, or (at your option)
+ * any later version.
+ *
+ * This software 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 software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_FOSPHOR_QT_SINK_C_H
+#define INCLUDED_GR_FOSPHOR_QT_SINK_C_H
+
+#include <gnuradio/fosphor/api.h>
+#include <gnuradio/fosphor/base_sink_c.h>
+
+#include <gnuradio/sync_block.h>
+
+class QApplication;
+class QWidget;
+
+namespace gr {
+ namespace fosphor {
+
+ /*!
+ * \brief Qt version of fosphor sink
+ * \ingroup fosphor
+ */
+ class GR_FOSPHOR_API qt_sink_c : virtual public base_sink_c
+ {
+ public:
+ typedef boost::shared_ptr<qt_sink_c> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of fosphor::qt_sink_c.
+ *
+ * To avoid accidental use of raw pointers, fosphor::qt_sink_c's
+ * constructor is in a private implementation
+ * class. fosphor::qt_sink_c::make is the public interface for
+ * creating new instances.
+ */
+ static sptr make(QWidget *parent=NULL);
+
+#if defined(PY_VERSION) || defined(SWIGPYTHON)
+ virtual PyObject* pyqwidget() = 0;
+#else
+ virtual void* pyqwidget() = 0;
+#endif
+
+ QApplication *d_qApplication;
+ };
+
+ } // namespace fosphor
+} // namespace gr
+
+#endif /* INCLUDED_GR_FOSPHOR_QT_SINK_C_H */
+
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index f095de2..29e55ae 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -41,6 +41,7 @@ include_directories(
${FREETYPE2_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
${PYTHON_INCLUDE_DIRS}
+ ${QT_INCLUDE_DIRS}
)
link_directories(
${OPENGL_LIBRARY_DIRS}
@@ -50,6 +51,8 @@ link_directories(
${Boost_LIBRARY_DIRS}
)
+set(CMAKE_AUTOMOC ON)
+
list(APPEND fosphor_sources
fosphor/cl.c
fosphor/fosphor.c
@@ -60,8 +63,10 @@ list(APPEND fosphor_sources
fosphor/resource.c
fosphor/resource_data.c
fifo.cc
+ QGLSurface.cc
base_sink_c_impl.cc
glfw_sink_c_impl.cc
+ qt_sink_c_impl.cc
wx_core_sink_c_impl.cc
)
@@ -73,6 +78,7 @@ target_link_libraries(gnuradio-fosphor
${FREETYPE2_LIBRARIES}
${Boost_LIBRARIES}
${GNURADIO_RUNTIME_LIBRARIES}
+ ${QT_LIBRARIES}
)
set_target_properties(gnuradio-fosphor PROPERTIES DEFINE_SYMBOL "gnuradio_fosphor_EXPORTS")
diff --git a/lib/QGLSurface.cc b/lib/QGLSurface.cc
new file mode 100644
index 0000000..83b73ac
--- /dev/null
+++ b/lib/QGLSurface.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This 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 3, or (at your option)
+ * any later version.
+ *
+ * This software 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 software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <QtEvents>
+#include "QGLSurface.h"
+#include "qt_sink_c_impl.h"
+
+#include <stdio.h>
+
+namespace gr {
+ namespace fosphor {
+
+QGLSurface::QGLSurface(QWidget *parent, qt_sink_c_impl *block)
+ : QGLWidget(parent), d_block(block)
+{
+ this->doneCurrent();
+ this->setFocusPolicy(Qt::StrongFocus);
+}
+
+void
+QGLSurface::paintEvent(QPaintEvent *pe)
+{
+ /* Don't do anything */
+
+ /*
+ * The default implementation calls makeCurrent but here we want
+ * _other_ threads to be current, so we need a dummy empty impl
+ * for the paintEvent
+ */
+}
+
+void
+QGLSurface::resizeEvent(QResizeEvent *re)
+{
+ /*
+ * The default implementation calls makeCurrent but here we want
+ * _other_ threads to be current, so don't do that !
+ */
+
+ /* Call back to main block */
+ this->d_block->cb_reshape(re->size().width(), re->size().height());
+}
+
+void
+QGLSurface::keyPressEvent(QKeyEvent *ke)
+{
+ switch (ke->key()) {
+ case Qt::Key_Up:
+ this->d_block->execute_ui_action(qt_sink_c_impl::REF_DOWN);
+ break;
+ case Qt::Key_Down:
+ this->d_block->execute_ui_action(qt_sink_c_impl::REF_UP);
+ break;
+ case Qt::Key_Left:
+ this->d_block->execute_ui_action(qt_sink_c_impl::DB_PER_DIV_DOWN);
+ break;
+ case Qt::Key_Right:
+ this->d_block->execute_ui_action(qt_sink_c_impl::DB_PER_DIV_UP);
+ break;
+ }
+}
+
+ } /* namespace fosphor */
+} /* namespace gr */
diff --git a/lib/QGLSurface.h b/lib/QGLSurface.h
new file mode 100644
index 0000000..88a9dbc
--- /dev/null
+++ b/lib/QGLSurface.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This 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 3, or (at your option)
+ * any later version.
+ *
+ * This software 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 software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FOSPHOR_QGLSURFACE_H
+#define INCLUDED_GR_FOSPHOR_QGLSURFACE_H
+
+#include <QGLWidget>
+
+namespace gr {
+ namespace fosphor {
+
+ class qt_sink_c_impl;
+
+ class QGLSurface : public ::QGLWidget
+ {
+ Q_OBJECT
+
+ qt_sink_c_impl *d_block;
+
+ protected:
+ void paintEvent(QPaintEvent *pe);
+ void resizeEvent(QResizeEvent *re);
+ void keyPressEvent(QKeyEvent *ke);
+
+ public:
+ QGLSurface(QWidget *parent, qt_sink_c_impl *d_block);
+ };
+
+ } // namespace fosphor
+} // namespace gr
+
+#endif /* INCLUDED_GR_FOSPHOR_QGLSURFACE_H */
diff --git a/lib/qt_sink_c_impl.cc b/lib/qt_sink_c_impl.cc
new file mode 100644
index 0000000..d53feec
--- /dev/null
+++ b/lib/qt_sink_c_impl.cc
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This 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 3, or (at your option)
+ * any later version.
+ *
+ * This software 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 software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <Python.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "qt_sink_c_impl.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QGLWidget>
+
+#include "QGLSurface.h"
+
+
+namespace gr {
+ namespace fosphor {
+
+qt_sink_c::sptr
+qt_sink_c::make(QWidget *parent)
+{
+ return gnuradio::get_initial_sptr(new qt_sink_c_impl(parent));
+}
+
+qt_sink_c_impl::qt_sink_c_impl(QWidget *parent)
+ : base_sink_c("glfw_sink_c")
+{
+ /* QT stuff */
+ if(qApp != NULL) {
+ d_qApplication = qApp;
+ }
+ else {
+ int argc=0;
+ char **argv = NULL;
+ d_qApplication = new QApplication(argc, argv);
+ }
+
+ this->d_gui = new QGLSurface(parent, this);
+}
+
+
+void
+qt_sink_c_impl::glctx_init()
+{
+ this->d_gui->makeCurrent();
+ this->d_gui->setFocus();
+}
+
+void
+qt_sink_c_impl::glctx_swap()
+{
+ this->d_gui->swapBuffers();
+}
+
+void
+qt_sink_c_impl::glctx_poll()
+{
+ /* Nothing to do */
+}
+
+void
+qt_sink_c_impl::glctx_fini()
+{
+ this->d_gui->doneCurrent();
+}
+
+
+PyObject*
+qt_sink_c_impl::pyqwidget()
+{
+ PyObject *w = PyLong_FromVoidPtr((void*)dynamic_cast<QWidget*>(this->d_gui));
+ PyObject *retarg = Py_BuildValue("N", w);
+ return retarg;
+}
+
+ } /* namespace fosphor */
+} /* namespace gr */
diff --git a/lib/qt_sink_c_impl.h b/lib/qt_sink_c_impl.h
new file mode 100644
index 0000000..b3fb0b6
--- /dev/null
+++ b/lib/qt_sink_c_impl.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This 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 3, or (at your option)
+ * any later version.
+ *
+ * This software 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 software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_FOSPHOR_QT_SINK_C_IMPL_H
+#define INCLUDED_GR_FOSPHOR_QT_SINK_C_IMPL_H
+
+#include <gnuradio/fosphor/qt_sink_c.h>
+
+#include "base_sink_c_impl.h"
+
+class QGLWidget;
+
+namespace gr {
+ namespace fosphor {
+
+ /*!
+ * \brief Qt version of fosphor sink (implementation)
+ * \ingroup fosphor
+ */
+ class qt_sink_c_impl : public qt_sink_c, public base_sink_c_impl
+ {
+ friend class QGLSurface;
+
+ private:
+ QGLWidget *d_gui;
+
+ protected:
+ /* Delegated implementation of GL context management */
+ void glctx_init();
+ void glctx_swap();
+ void glctx_poll();
+ void glctx_fini();
+
+ public:
+ qt_sink_c_impl(QWidget *parent=NULL);
+
+#if defined(PY_VERSION) || defined(SWIGPYTHON)
+ PyObject* pyqwidget();
+#else
+ void* pyqwidget();
+#endif
+ };
+
+ } // namespace fosphor
+} // namespace gr
+
+#endif /* INCLUDED_GR_FOSPHOR_QT_SINK_C_IMPL_H */
+
diff --git a/swig/fosphor_swig.i b/swig/fosphor_swig.i
index 1812de5..342dda1 100644
--- a/swig/fosphor_swig.i
+++ b/swig/fosphor_swig.i
@@ -9,6 +9,7 @@
%{
#include "gnuradio/fosphor/glfw_sink_c.h"
+#include "gnuradio/fosphor/qt_sink_c.h"
#include "gnuradio/fosphor/wx_core_sink_c.h"
%}
@@ -19,5 +20,8 @@
%include "gnuradio/fosphor/glfw_sink_c.h"
GR_SWIG_BLOCK_MAGIC2(fosphor, glfw_sink_c);
+%include "gnuradio/fosphor/qt_sink_c.h"
+GR_SWIG_BLOCK_MAGIC2(fosphor, qt_sink_c);
+
%include "gnuradio/fosphor/wx_core_sink_c.h"
GR_SWIG_BLOCK_MAGIC2(fosphor, wx_core_sink_c);