Layed the foundation of a
This commit is contained in:
parent
03bc0cd276
commit
130da1ec77
17 changed files with 505 additions and 25 deletions
|
|
@ -1 +0,0 @@
|
|||
/usr/share/automake-1.9/COPYING
|
||||
|
|
@ -1 +0,0 @@
|
|||
/usr/share/automake-1.9/INSTALL
|
||||
|
|
@ -1,16 +1,9 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
## Created by Anjuta
|
||||
|
||||
SUBDIRS = src po
|
||||
|
||||
gtk_lumieradocdir = ${prefix}/doc/gtk-lumiera
|
||||
gtk_lumieradoc_DATA = \
|
||||
README\
|
||||
COPYING\
|
||||
AUTHORS\
|
||||
ChangeLog\
|
||||
INSTALL\
|
||||
NEWS
|
||||
gtk_lumieradoc_DATA =
|
||||
|
||||
EXTRA_DIST = $(gtk_lumieradoc_DATA)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<gtodo>
|
||||
<category title="Personal" place="0"/>
|
||||
<category title="Business" place="1"/>
|
||||
<category title="Unfiled" place="2"/>
|
||||
</gtodo>
|
||||
|
|
@ -140,8 +140,8 @@ do
|
|||
echo "Running autoheader..."
|
||||
autoheader
|
||||
fi
|
||||
echo "Running automake --gnu $am_opt ..."
|
||||
automake --add-missing --gnu $am_opt
|
||||
echo "Running automake --foreign $am_opt ..."
|
||||
automake --add-missing --foreign $am_opt
|
||||
echo "Running autoconf ..."
|
||||
autoconf
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl Created by Anjuta application wizard.
|
||||
|
||||
AC_INIT(gtk-lumiera, 0.1)
|
||||
|
||||
|
|
@ -29,14 +28,48 @@ IT_PROG_INTLTOOL([0.35.0])
|
|||
AM_PROG_LIBTOOL
|
||||
|
||||
|
||||
# ######################################################################
|
||||
# Checks for X11 and XVideo
|
||||
# ######################################################################
|
||||
AC_PATH_X
|
||||
AC_PATH_XTRA
|
||||
# CFLAGS="$CFLAGS $X_CFLAGS"
|
||||
LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS"
|
||||
|
||||
AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h],[],
|
||||
[AC_MSG_ERROR([Xlib.h or Xutil.h not found install xdevel])])
|
||||
|
||||
# OK, this is confusing. The old tests test for the existence of a number
|
||||
# of header files, and add -lXv to the linker flags if they are there.
|
||||
# However, if they are _not_ there, only a warning is issued, but
|
||||
# src/displayer.h includes these unconditionally.
|
||||
# I conclude that -lXv _is_ required. If not, src/displayer.h should be edited,
|
||||
# I think.
|
||||
# This test requires libXv and, therefore, libXext
|
||||
|
||||
AC_CHECK_HEADERS([sys/ipc.h sys/shm.h],,
|
||||
[AC_MSG_ERROR([Required header not found. Please check that it is installed])]
|
||||
)
|
||||
AC_CHECK_HEADERS([X11/extensions/Xvlib.h X11/extensions/XShm.h],,
|
||||
[AC_MSG_ERROR([Required xvideo (Xv) extension to X not found. Please check that it is installed.])],
|
||||
[#include <X11/Xlib.h>]
|
||||
)
|
||||
|
||||
AC_CHECK_LIB(Xext, XInitExtension, ,
|
||||
[AC_MSG_ERROR([Could not link with libXext. Check that you have libXext installed])], -lX11
|
||||
)
|
||||
AC_CHECK_LIB(Xv, XvQueryAdaptors, ,
|
||||
[AC_MSG_ERROR([Could not link with libXv. Check that you have libXv installed])]
|
||||
)
|
||||
|
||||
# ######################################################################
|
||||
# Checks for GTK stuff
|
||||
# ######################################################################
|
||||
PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0])
|
||||
|
||||
AC_SUBST(GTK_LUMIERA_CFLAGS)
|
||||
AC_SUBST(GTK_LUMIERA_LIBS)
|
||||
|
||||
|
||||
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
src/Makefile
|
||||
|
|
|
|||
|
|
@ -38,7 +38,11 @@ gtk_lumiera_SOURCES = \
|
|||
widgets/timeline-widget.cpp \
|
||||
widgets/timeline-widget.hpp \
|
||||
model/project.cpp \
|
||||
model/project.hpp
|
||||
model/project.hpp \
|
||||
output/displayer.cpp \
|
||||
output/displayer.hpp \
|
||||
output/xvdisplayer.cpp \
|
||||
output/xvdisplayer.hpp
|
||||
|
||||
gtk_lumiera_LDFLAGS =
|
||||
|
||||
|
|
|
|||
65
src/gui/src/output/displayer.cpp
Normal file
65
src/gui/src/output/displayer.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
displayer.cpp - Implements the base class for displaying video
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2000, Arne Schirmacher <arne@schirmacher.de>
|
||||
2001-2007, Dan Dennedy <dan@dennedy.org>
|
||||
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
#include "displayer.hpp"
|
||||
|
||||
namespace lumiera {
|
||||
namespace gui {
|
||||
namespace output {
|
||||
|
||||
|
||||
|
||||
DisplayerInput Displayer::format()
|
||||
{
|
||||
return DISPLAY_NONE;
|
||||
}
|
||||
|
||||
int Displayer::preferredWidth()
|
||||
{
|
||||
return imageWidth;
|
||||
}
|
||||
|
||||
int Displayer::preferredHeight()
|
||||
{
|
||||
return imageHeight;
|
||||
}
|
||||
|
||||
void Displayer::put( void *image, int width, int height )
|
||||
{
|
||||
if ( width == preferredWidth() && height == preferredHeight() )
|
||||
{
|
||||
put( image );
|
||||
}
|
||||
else
|
||||
{
|
||||
reformat( format(), format(), image, width, height );
|
||||
put( pixels );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace output
|
||||
} // namespace gui
|
||||
} // namespace lumiera
|
||||
107
src/gui/src/output/displayer.hpp
Normal file
107
src/gui/src/output/displayer.hpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
displayer.hpp - Defines the base class for displaying video
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2000, Arne Schirmacher <arne@schirmacher.de>
|
||||
2001-2007, Dan Dennedy <dan@dennedy.org>
|
||||
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
/** @file displayer.hpp
|
||||
** This file contains the defintion of Displayer; the base class
|
||||
** of all video display implementations
|
||||
** @see displayer.cpp
|
||||
*/
|
||||
|
||||
#ifndef DISPLAYER_HPP
|
||||
#define DISPLAYER_HPP
|
||||
|
||||
namespace lumiera {
|
||||
namespace gui {
|
||||
namespace output {
|
||||
|
||||
/** Supported Displayer formats
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
DISPLAY_NONE,
|
||||
DISPLAY_YUV,
|
||||
DISPLAY_RGB,
|
||||
DISPLAY_BGR,
|
||||
DISPLAY_BGR0,
|
||||
DISPLAY_RGB16
|
||||
}
|
||||
DisplayerInput;
|
||||
|
||||
/** A Displayer is a class which is responsible for rendering an image in some
|
||||
way (ie: Xvideo, GDK, OpenGL etc).
|
||||
|
||||
All Displayer classes must extend the Displayer class and minimally rewrite:
|
||||
|
||||
+ usable() - to indicate if the object can be used,
|
||||
+ format() - to indicate what type of input the put method expects
|
||||
+ put( void * ) - deal with an image of the expected type and size
|
||||
|
||||
By default, all images will be delivered to the put method in a resolution
|
||||
of IMG_WIDTH * IMG_HEIGHT. If another size is required, then the rewrite
|
||||
the methods:
|
||||
|
||||
+ preferredWidth
|
||||
+ preferredHeight
|
||||
|
||||
If the widget being written to doesn't need a fixed size, then rewrite
|
||||
the two other put methods as required.
|
||||
*/
|
||||
class Displayer
|
||||
{
|
||||
public:
|
||||
|
||||
/** Indicates the format required by the abstract put method.
|
||||
*/
|
||||
virtual DisplayerInput format();
|
||||
|
||||
/** Expected width of input to put.
|
||||
*/
|
||||
virtual int preferredWidth();
|
||||
|
||||
/** Expected height of input to put.
|
||||
*/
|
||||
virtual int preferredHeight();
|
||||
|
||||
/** Put an image of a given width and height with the expected input
|
||||
format (as indicated by the format method).
|
||||
|
||||
\param image image of correct format and specified width/height
|
||||
\param width width of image
|
||||
\param height height of image
|
||||
*/
|
||||
virtual void put( void *image, int width, int height );
|
||||
|
||||
virtual bool usable();
|
||||
|
||||
protected:
|
||||
int imageWidth;
|
||||
int imageHeight;
|
||||
|
||||
virtual void put( void * ) = 0;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace gui
|
||||
} // namespace lumiera
|
||||
|
||||
#endif // DISPLAYER_HPP
|
||||
214
src/gui/src/output/xvdisplayer.cpp
Normal file
214
src/gui/src/output/xvdisplayer.cpp
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
displayer.cpp - Implements the base class for displaying video
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2000, Arne Schirmacher <arne@schirmacher.de>
|
||||
2001-2007, Dan Dennedy <dan@dennedy.org>
|
||||
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
#include "xvdisplayer.hpp"
|
||||
|
||||
namespace lumiera {
|
||||
namespace gui {
|
||||
namespace output {
|
||||
|
||||
XvDisplayer::XvDisplayer( GtkWidget *drawingarea, int width, int height, bool isPAL, bool isWidescreen ) :
|
||||
xvImage( NULL )
|
||||
{
|
||||
cerr << ">> Trying XVideo at " << width << "x" << height << endl;
|
||||
|
||||
this->drawingarea = drawingarea;
|
||||
img_width = width;
|
||||
img_height = height;
|
||||
this->isPAL = isPAL;
|
||||
this->isWidescreen = isWidescreen;
|
||||
|
||||
shmInfo.shmaddr = NULL;
|
||||
gotPort = false;
|
||||
|
||||
window = GDK_WINDOW_XID( drawingarea->window );
|
||||
display = GDK_WINDOW_XDISPLAY( drawingarea->window );
|
||||
|
||||
unsigned int count;
|
||||
XvAdaptorInfo *adaptorInfo;
|
||||
|
||||
if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success )
|
||||
{
|
||||
|
||||
cerr << ">>> XvQueryAdaptors count: " << count << endl;
|
||||
for ( unsigned int n = 0; gotPort == false && n < count; ++n )
|
||||
{
|
||||
// Diagnostics
|
||||
cerr << ">>> Xv: " << adaptorInfo[ n ].name
|
||||
<< ": ports " << adaptorInfo[ n ].base_id
|
||||
<< " - " << adaptorInfo[ n ].base_id +
|
||||
adaptorInfo[ n ].num_ports - 1
|
||||
<< endl;
|
||||
|
||||
for ( port = adaptorInfo[ n ].base_id;
|
||||
port < adaptorInfo[ n ].base_id + adaptorInfo[ n ].num_ports;
|
||||
port ++ )
|
||||
{
|
||||
if ( XvGrabPort( display, port, CurrentTime ) == 0 )
|
||||
{
|
||||
|
||||
int formats;
|
||||
XvImageFormatValues *list;
|
||||
|
||||
list = XvListImageFormats( display, port, &formats );
|
||||
|
||||
cerr << ">>> formats supported: " << formats << endl;
|
||||
|
||||
for ( int i = 0; i < formats; i ++ )
|
||||
{
|
||||
fprintf( stderr, ">>> 0x%x (%c%c%c%c) %s\n",
|
||||
list[ i ].id,
|
||||
( list[ i ].id ) & 0xff,
|
||||
( list[ i ].id >> 8 ) & 0xff,
|
||||
( list[ i ].id >> 16 ) & 0xff,
|
||||
( list[ i ].id >> 24 ) & 0xff,
|
||||
( list[ i ].format == XvPacked ) ? "packed" : "planar" );
|
||||
if ( list[ i ].id == 0x32595559 && !gotPort )
|
||||
gotPort = true;
|
||||
}
|
||||
|
||||
if ( !gotPort )
|
||||
{
|
||||
XvUngrabPort( display, port, CurrentTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
grabbedPort = port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( gotPort )
|
||||
{
|
||||
int num;
|
||||
unsigned int unum;
|
||||
XvEncodingInfo *enc;
|
||||
|
||||
XvQueryEncodings( display, grabbedPort, &unum, &enc );
|
||||
for ( unsigned int index = 0; index < unum; index ++ )
|
||||
{
|
||||
fprintf( stderr, ">>> %d: %s, %ldx%ld rate = %d/%d\n", index, enc->name,
|
||||
enc->width, enc->height, enc->rate.numerator,
|
||||
enc->rate.denominator );
|
||||
}
|
||||
|
||||
XvAttribute *xvattr = XvQueryPortAttributes( display, port, &num );
|
||||
for ( int k = 0; k < num; k++ )
|
||||
{
|
||||
if ( xvattr[k].flags & XvSettable )
|
||||
{
|
||||
if ( strcmp( xvattr[k].name, "XV_AUTOPAINT_COLORKEY") == 0 )
|
||||
{
|
||||
Atom val_atom = XInternAtom( display, xvattr[k].name, False );
|
||||
if ( XvSetPortAttribute( display, port, val_atom, 1 ) != Success )
|
||||
fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name);
|
||||
}
|
||||
else if ( strcmp( xvattr[k].name, "XV_COLORKEY") == 0 )
|
||||
{
|
||||
Atom val_atom = XInternAtom( display, xvattr[k].name, False );
|
||||
if ( XvSetPortAttribute( display, port, val_atom, 0x010102 ) != Success )
|
||||
fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( gotPort )
|
||||
{
|
||||
gc = XCreateGC( display, window, 0, &values );
|
||||
|
||||
xvImage = ( XvImage * ) XvShmCreateImage( display, port, 0x32595559, 0, width, height, &shmInfo );
|
||||
|
||||
shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 );
|
||||
if (shmInfo.shmid < 0) {
|
||||
perror("shmget");
|
||||
gotPort = false;
|
||||
} else {
|
||||
shmInfo.shmaddr = ( char * ) shmat( shmInfo.shmid, 0, 0 );
|
||||
xvImage->data = shmInfo.shmaddr;
|
||||
shmInfo.readOnly = 0;
|
||||
if ( !XShmAttach( gdk_display, &shmInfo ) )
|
||||
{
|
||||
gotPort = false;
|
||||
}
|
||||
XSync( display, false );
|
||||
shmctl( shmInfo.shmid, IPC_RMID, 0 );
|
||||
#if 0
|
||||
xvImage = ( XvImage * ) XvCreateImage( display, port, 0x32595559, pix, width , height );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gotPort = false;
|
||||
}
|
||||
}
|
||||
|
||||
XvDisplayer::~XvDisplayer()
|
||||
{
|
||||
cerr << ">> Destroying XV Displayer" << endl;
|
||||
|
||||
if ( gotPort )
|
||||
{
|
||||
XvUngrabPort( display, grabbedPort, CurrentTime );
|
||||
}
|
||||
|
||||
if ( xvImage != NULL )
|
||||
XvStopVideo( display, port, window );
|
||||
|
||||
if ( shmInfo.shmaddr != NULL )
|
||||
{
|
||||
XShmDetach( display, &shmInfo );
|
||||
shmctl( shmInfo.shmid, IPC_RMID, 0 );
|
||||
shmdt( shmInfo.shmaddr );
|
||||
}
|
||||
if ( xvImage != NULL )
|
||||
XFree( xvImage );
|
||||
}
|
||||
|
||||
bool XvDisplayer::usable()
|
||||
{
|
||||
return gotPort;
|
||||
}
|
||||
|
||||
void XvDisplayer::put( void *image )
|
||||
{
|
||||
AspectRatioCalculator calc( ( ( GtkWidget * ) drawingarea ) ->allocation.width,
|
||||
( ( GtkWidget * ) drawingarea ) ->allocation.height,
|
||||
this->preferredWidth(), this->preferredHeight(),
|
||||
isPAL, isWidescreen );
|
||||
|
||||
memcpy( xvImage->data, image, xvImage->data_size );
|
||||
|
||||
XvShmPutImage( display, port, window, gc, xvImage,
|
||||
0, 0, this->preferredWidth(), this->preferredHeight(),
|
||||
calc.x, calc.y, calc.width, calc.height, false );
|
||||
}
|
||||
|
||||
} // namespace output
|
||||
} // namespace gui
|
||||
} // namespace lumiera
|
||||
68
src/gui/src/output/xvdisplayer.hpp
Normal file
68
src/gui/src/output/xvdisplayer.hpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
xcdisplayer.hpp - Defines the base class for XVideo display
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2000, Arne Schirmacher <arne@schirmacher.de>
|
||||
2001-2007, Dan Dennedy <dan@dennedy.org>
|
||||
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
/** @file xvdisplayer.hpp
|
||||
** This file contains the definition of XvDisplayer, the XVideo
|
||||
** video output implementation
|
||||
** @see xvdisplayer.cpp
|
||||
*/
|
||||
|
||||
#include "displayer.hpp"
|
||||
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#ifndef XVDISPLAYER_HPP
|
||||
#define XVDISPLAYER_HPP
|
||||
|
||||
namespace lumiera {
|
||||
namespace gui {
|
||||
namespace output {
|
||||
|
||||
class XvDisplayer
|
||||
{
|
||||
public:
|
||||
XvDisplayer();
|
||||
~XvDisplayer();
|
||||
|
||||
protected:
|
||||
void put( void *image );
|
||||
|
||||
private:
|
||||
bool canuse;
|
||||
int depth;
|
||||
GtkWidget *drawingarea;
|
||||
Display *display;
|
||||
Window window;
|
||||
GC gc;
|
||||
XImage *xImage;
|
||||
XGCValues values;
|
||||
XShmSegmentInfo shmInfo;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace gui
|
||||
} // namespace lumiera
|
||||
|
||||
#endif // XVDISPLAYER_HPP
|
||||
|
|
@ -38,9 +38,13 @@ namespace widgets {
|
|||
VideoDisplayWidget();
|
||||
|
||||
/* ===== Overrides ===== */
|
||||
protected:
|
||||
private:
|
||||
virtual void on_realize();
|
||||
virtual bool on_expose_event(GdkEventExpose* event);
|
||||
|
||||
/* ===== Internals ===== */
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
*/
|
||||
/** @file window-manager.hpp
|
||||
** This file contains the of global UI Manager class
|
||||
** This file contains the defintion of global UI Manager class
|
||||
** user actions.
|
||||
** @see window-manager.cpp
|
||||
** @see gtk-lumiera.hpp
|
||||
|
|
|
|||
Loading…
Reference in a new issue