gr-fosphor: Add Qt widget version of the fosphor sink

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
Sylvain Munaut 2013-10-26 21:07:14 +02:00
parent e3732c0609
commit 6183eefc9a
12 changed files with 561 additions and 0 deletions

View File

@ -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

View File

@ -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)

View File

@ -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
)

29
grc/fosphor_qt_sink_c.xml Normal file
View File

@ -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>

View File

@ -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
)

View File

@ -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 */

View File

@ -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")

81
lib/QGLSurface.cc Normal file
View File

@ -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 */

49
lib/QGLSurface.h Normal file
View File

@ -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 */

97
lib/qt_sink_c_impl.cc Normal file
View File

@ -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 */

66
lib/qt_sink_c_impl.h Normal file
View File

@ -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 */

View File

@ -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);