gr-fosphor: Add WX 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:06:04 +02:00
parent b056fcc1a8
commit e3732c0609
11 changed files with 382 additions and 1 deletions

View File

@ -17,5 +17,7 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
fosphor_glfw_sink_c.xml DESTINATION share/gnuradio/grc/blocks
fosphor_glfw_sink_c.xml
fosphor_wx_sink_c.xml
DESTINATION share/gnuradio/grc/blocks
)

43
grc/fosphor_wx_sink_c.xml Normal file
View File

@ -0,0 +1,43 @@
<?xml version="1.0"?>
<block>
<name>WX fosphor sink</name>
<key>fosphor_wx_sink_c</key>
<category>Instrumentation/WX</category>
<import>from gnuradio import fosphor</import>
<make>#set $parent = $notebook() and 'self.%s.GetPage(%s)'%$notebook() or 'self'
fosphor.wx_sink_c(
$(parent).GetWin()
#if $win_size()
size=$win_size,
#end if
)
#if not $grid_pos()
$(parent).Add(self.$(id).win)
#else
$(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
#end if</make>
<param>
<name>Window Size</name>
<key>win_size</key>
<value></value>
<type>int_vector</type>
<hide>#if $win_size() then 'none' else 'part'#</hide>
</param>
<param>
<name>Grid Position</name>
<key>grid_pos</key>
<value></value>
<type>grid_pos</type>
</param>
<param>
<name>Notebook</name>
<key>notebook</key>
<value></value>
<type>notebook</type>
</param>
<check>not $win_size or len($win_size) == 2</check>
<sink>
<name>in</name>
<type>complex</type>
</sink>
</block>

View File

@ -24,5 +24,6 @@ install(FILES
api.h
base_sink_c.h
glfw_sink_c.h
wx_core_sink_c.h
DESTINATION include/gnuradio/fosphor
)

View File

@ -0,0 +1,59 @@
/* -*- 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_WX_CORE_SINK_C_H
#define INCLUDED_GR_FOSPHOR_WX_CORE_SINK_C_H
#include <gnuradio/fosphor/api.h>
#include <gnuradio/fosphor/base_sink_c.h>
#include <gnuradio/sync_block.h>
namespace gr {
namespace fosphor {
/*!
* \brief WX version of fosphor sink (core)
* \ingroup fosphor
*/
class GR_FOSPHOR_API wx_core_sink_c : virtual public base_sink_c
{
public:
typedef boost::shared_ptr<wx_core_sink_c> sptr;
/*!
* \brief Return a shared_ptr to a new instance of fosphor::wx_core_sink_c.
*
* To avoid accidental use of raw pointers, fosphor::wx_core_sink_c's
* constructor is in a private implementation
* class. fosphor::wx_core_sink_c::make is the public interface for
* creating new instances.
*/
static sptr make(PyObject *cb_init, PyObject *cb_fini, PyObject *cb_swap);
virtual void pycb_reshape(int width, int height) = 0;
};
} // namespace fosphor
} // namespace gr
#endif /* INCLUDED_GR_FOSPHOR_WX_CORE_SINK_C_H */

View File

@ -23,6 +23,7 @@
include(GrPlatform) #define LIB_SUFFIX
include(GrMiscUtils)
find_package(PythonLibs 2)
find_package(PythonInterp 2)
add_custom_command(
@ -39,6 +40,7 @@ include_directories(
${OPENCL_INCLUDE_DIRS}
${FREETYPE2_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
${PYTHON_INCLUDE_DIRS}
)
link_directories(
${OPENGL_LIBRARY_DIRS}
@ -60,6 +62,7 @@ list(APPEND fosphor_sources
fifo.cc
base_sink_c_impl.cc
glfw_sink_c_impl.cc
wx_core_sink_c_impl.cc
)
add_library(gnuradio-fosphor SHARED ${fosphor_sources})

110
lib/wx_core_sink_c_impl.cc Normal file
View File

@ -0,0 +1,110 @@
/* -*- 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 "wx_core_sink_c_impl.h"
namespace gr {
namespace fosphor {
wx_core_sink_c::sptr
wx_core_sink_c::make(PyObject *cb_init, PyObject *cb_fini, PyObject *cb_swap)
{
return gnuradio::get_initial_sptr(new wx_core_sink_c_impl(cb_init, cb_fini, cb_swap));
}
wx_core_sink_c_impl::wx_core_sink_c_impl(PyObject *cb_init, PyObject *cb_fini, PyObject *cb_swap)
: base_sink_c("wx_core_sink_c"),
d_cb_init(cb_init), d_cb_fini(cb_fini), d_cb_swap(cb_swap)
{
/* Make sure we keep reference to callbacks */
Py_INCREF(this->d_cb_init);
Py_INCREF(this->d_cb_fini);
Py_INCREF(this->d_cb_swap);
}
wx_core_sink_c_impl::~wx_core_sink_c_impl()
{
/* Release callbacks */
Py_DECREF(this->d_cb_init);
Py_DECREF(this->d_cb_fini);
Py_DECREF(this->d_cb_swap);
}
void
wx_core_sink_c_impl::pycall(PyObject *cb)
{
PyObject *arglist;
PyObject *result;
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
arglist = Py_BuildValue("()");
result = PyEval_CallObject(cb, arglist);
Py_DECREF(arglist);
if (result != NULL)
Py_DECREF(result);
PyGILState_Release(gstate);
}
void
wx_core_sink_c_impl::glctx_init()
{
this->pycall(this->d_cb_init);
}
void
wx_core_sink_c_impl::glctx_swap()
{
this->pycall(this->d_cb_swap);
}
void
wx_core_sink_c_impl::glctx_poll()
{
/* Nothing to do */
}
void
wx_core_sink_c_impl::glctx_fini()
{
this->pycall(this->d_cb_fini);
}
void
wx_core_sink_c_impl::pycb_reshape(int width, int height)
{
this->cb_reshape(width, height);
}
} /* namespace fosphor */
} /* namespace gr */

64
lib/wx_core_sink_c_impl.h Normal file
View File

@ -0,0 +1,64 @@
/* -*- 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_WX_CORE_SINK_C_IMPL_H
#define INCLUDED_GR_FOSPHOR_WX_CORE_SINK_C_IMPL_H
#include <gnuradio/fosphor/wx_core_sink_c.h>
#include "base_sink_c_impl.h"
namespace gr {
namespace fosphor {
/*!
* \brief WX version of fosphor sink (core implementation)
* \ingroup fosphor
*/
class wx_core_sink_c_impl : public wx_core_sink_c, public base_sink_c_impl
{
private:
/* Delegation to python */
void pycall(PyObject *cb);
PyObject *d_cb_init;
PyObject *d_cb_fini;
PyObject *d_cb_swap;
protected:
/* Delegated implementation of GL context management */
void glctx_init();
void glctx_swap();
void glctx_poll();
void glctx_fini();
public:
wx_core_sink_c_impl(PyObject *cb_init, PyObject *cb_fini, PyObject *cb_swap);
~wx_core_sink_c_impl();
void pycb_reshape(int width, int height);
};
} // namespace fosphor
} // namespace gr
#endif /* INCLUDED_GR_FOSPHOR_WX_CORE_SINK_C_IMPL_H */

View File

@ -31,6 +31,7 @@ endif()
GR_PYTHON_INSTALL(
FILES
__init__.py
wx_sink_c.py
DESTINATION ${GR_PYTHON_DIR}/gnuradio/fosphor
)

View File

@ -45,6 +45,7 @@ if _RTLD_GLOBAL != 0:
from fosphor_swig import *
# import any pure python here
from wx_sink_c import wx_sink_c
#
# ----------------------------------------------------------------

93
python/wx_sink_c.py Normal file
View File

@ -0,0 +1,93 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# 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.
#
import numpy
import wx
import wx.glcanvas
from OpenGL import GL
from gnuradio import gr
from fosphor_swig import base_sink_c, wx_core_sink_c
import threading
class wx_sink_c(gr.hier_block2):
def __init__(self, parent, size=(600,600)):
gr.hier_block2.__init__(
self,
"wx_sink_c",
gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(0, 0, 0),
)
# Create the GL Canvas (without context for now)
attribList = (wx.glcanvas.WX_GL_DOUBLEBUFFER, wx.glcanvas.WX_GL_RGBA)
self.win = wx.glcanvas.GLCanvas(parent, wx.ID_ANY,
attribList=attribList,
size=size,
style=wx.WANTS_CHARS
)
self.win.Bind(wx.EVT_SIZE, self._evt_size)
self.win.Bind(wx.EVT_KEY_DOWN, self._evt_key_down)
self.win.SetFocus()
self._gl_ctx = None
# Create the underlying WX sink core
self.sink = wx_core_sink_c(self._glctx_init, self._glctx_fini, self._glctx_swap)
self.connect(self, self.sink)
def _evt_size(self, evt):
self.sink.pycb_reshape(*evt.GetSize())
def _evt_key_down(self, evt):
k = evt.GetKeyCode()
if k == wx.WXK_UP:
self.sink.execute_ui_action(base_sink_c.REF_DOWN)
elif k == wx.WXK_DOWN:
self.sink.execute_ui_action(base_sink_c.REF_UP)
elif k == wx.WXK_LEFT:
self.sink.execute_ui_action(base_sink_c.DB_PER_DIV_DOWN)
elif k == wx.WXK_RIGHT:
self.sink.execute_ui_action(base_sink_c.DB_PER_DIV_UP)
else:
evt.Skip()
def _glctx_init(self):
if self._gl_ctx is None:
self._gl_ctx = wx.glcanvas.GLContext(self.win)
self.win.SetCurrent(self._gl_ctx)
def _glctx_fini(self):
self._gl_ctx = None
def _glctx_swap(self):
self.win.SwapBuffers()
def __getattr__(self, attr):
try:
return gr.hier_block2.__getattr__(self, attr)
except:
return getattr(self.sink, attr)

View File

@ -9,6 +9,7 @@
%{
#include "gnuradio/fosphor/glfw_sink_c.h"
#include "gnuradio/fosphor/wx_core_sink_c.h"
%}
@ -17,3 +18,6 @@
%nodefaultctor gr::fosphor::glfw_sink_c; // bug workaround
%include "gnuradio/fosphor/glfw_sink_c.h"
GR_SWIG_BLOCK_MAGIC2(fosphor, glfw_sink_c);
%include "gnuradio/fosphor/wx_core_sink_c.h"
GR_SWIG_BLOCK_MAGIC2(fosphor, wx_core_sink_c);