XV-Display: build new GTK-3 widget framework and controller
- place a `DemoController` instance as direct member into the `ViewerPanel` - create a direct wiring, so that the `DemoController` can push to the `VideoDisplayWidget` - make the `DemoController` directly instantiate a `TickService` and `DummyImageGenerator` - reimplement play control functions by direct invocation - add a new class to the Lumiera CSS stylesheet
This commit is contained in:
parent
0ae96294e8
commit
ac5a2f371d
20 changed files with 366 additions and 310 deletions
|
|
@ -20,94 +20,73 @@
|
|||
|
||||
|
||||
#include "stage/ctrl/demo-controller.hpp"
|
||||
#include "stage/display-service.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "include/logging.h"
|
||||
#include "steam/engine/worker/tick-service.hpp"
|
||||
#include "steam/engine/worker/dummy-image-generator.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace stage {
|
||||
namespace ctrl {
|
||||
|
||||
namespace error = lumiera::error;
|
||||
|
||||
|
||||
|
||||
DemoController::DemoController()
|
||||
: playing_(false)
|
||||
, viewerHandle_(0)
|
||||
{
|
||||
instance = this; ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
|
||||
}
|
||||
|
||||
DemoController::~DemoController()
|
||||
{
|
||||
instance = nullptr; ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
|
||||
}
|
||||
|
||||
|
||||
DemoController* DemoController::instance; ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
|
||||
|
||||
DemoController&
|
||||
DemoController::get() ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
|
||||
{
|
||||
if (not instance)
|
||||
throw error::Logic ("GTK UI is not in running state"
|
||||
, LERR_(LIFECYCLE));
|
||||
|
||||
return *instance;
|
||||
namespace {
|
||||
const uint FPS = 4;
|
||||
}
|
||||
|
||||
using std::make_unique;
|
||||
using steam::node::TickService;
|
||||
using steam::node::DummyImageGenerator;
|
||||
|
||||
|
||||
DemoController::DemoController(FrameSink outputSink)
|
||||
: imageGen_{make_unique<DummyImageGenerator>(FPS)}
|
||||
, tick_{}
|
||||
, output_{std::move (outputSink)}
|
||||
, playing_{false}
|
||||
{ }
|
||||
|
||||
DemoController::~DemoController() { stop(); }
|
||||
|
||||
|
||||
void
|
||||
DemoController::processFrame()
|
||||
{
|
||||
REQUIRE (tick_);
|
||||
REQUIRE (imageGen_);
|
||||
|
||||
if (playing_)
|
||||
output_(imageGen_->next());
|
||||
else
|
||||
output_(imageGen_->current());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DemoController::play()
|
||||
{
|
||||
if (playHandle_)
|
||||
{
|
||||
playHandle_.play(true);
|
||||
playing_ = true;
|
||||
}
|
||||
else if (viewerHandle_)
|
||||
try
|
||||
{
|
||||
playHandle_ = lumiera::DummyPlayer::facade().start (viewerHandle_);
|
||||
playing_ = true;
|
||||
}
|
||||
catch (lumiera::error::State& err)
|
||||
{
|
||||
WARN (stage, "failed to start playback: %s" ,err.what());
|
||||
lumiera_error();
|
||||
playing_ = false;
|
||||
}
|
||||
if (not tick_)
|
||||
tick_.reset (new TickService{[this]{ processFrame(); }});
|
||||
ASSERT (tick_);
|
||||
tick_->activate (FPS);
|
||||
playing_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
DemoController::pause()
|
||||
{
|
||||
if (playHandle_)
|
||||
playHandle_.play(false);
|
||||
if (tick_)
|
||||
tick_->activate(0);
|
||||
playing_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
DemoController::stop()
|
||||
{
|
||||
playHandle_.close();
|
||||
tick_.reset(); // blocks for one cycle to join()
|
||||
playing_ = false;
|
||||
}
|
||||
|
||||
bool
|
||||
DemoController::is_playing()
|
||||
{
|
||||
return playing_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
DemoController::useDisplay (LumieraDisplaySlot display)
|
||||
{
|
||||
viewerHandle_ = display;
|
||||
}
|
||||
|
||||
|
||||
}} // namespace stage::ctrl
|
||||
|
||||
|
|
|
|||
|
|
@ -32,49 +32,45 @@
|
|||
#define DEMO_CONTROLLER_H
|
||||
|
||||
#include "stage/gtk-base.hpp"
|
||||
#include "include/dummy-player-facade.h"
|
||||
#include "include/display-facade.h"
|
||||
#include "lib/nocopy.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
namespace steam {
|
||||
namespace node {
|
||||
class TickService;
|
||||
class DummyImageGenerator;
|
||||
}}
|
||||
|
||||
namespace stage {
|
||||
namespace ctrl {
|
||||
|
||||
using std::unique_ptr;
|
||||
using FrameSink = std::function<void(void* const)>;
|
||||
|
||||
|
||||
/** @deprecated we need a durable design for the playback process */
|
||||
class DemoController
|
||||
: util::NonCopyable
|
||||
{
|
||||
|
||||
volatile bool playing_;
|
||||
|
||||
lumiera::DummyPlayer::Process playHandle_;
|
||||
|
||||
LumieraDisplaySlot viewerHandle_;
|
||||
|
||||
static DemoController* instance; /////////////////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
|
||||
unique_ptr<steam::node::DummyImageGenerator> imageGen_;
|
||||
unique_ptr<steam::node::TickService> tick_;
|
||||
FrameSink output_;
|
||||
bool playing_;
|
||||
|
||||
public:
|
||||
|
||||
DemoController();
|
||||
~DemoController();
|
||||
DemoController(FrameSink);
|
||||
|
||||
static DemoController& get(); /////////////////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
|
||||
bool isPlaying() const { return playing_; }
|
||||
|
||||
void play();
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
bool is_playing();
|
||||
|
||||
void useDisplay (LumieraDisplaySlot display);
|
||||
|
||||
private:
|
||||
|
||||
void on_frame();
|
||||
|
||||
void processFrame();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@
|
|||
.idlabel__icon image {
|
||||
padding-left: 0.5ex;
|
||||
}
|
||||
.videodisplay {
|
||||
background-color: Black;
|
||||
min-width: 320px;
|
||||
min-height: 240px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ---------- Styles for special markup ---------- */
|
||||
|
|
|
|||
|
|
@ -277,6 +277,25 @@ class "gtkmm__CustomObject_TimelineHeaderWidget" style:highest "timeline_header_
|
|||
*/
|
||||
|
||||
|
||||
/* ---------- Styles for Lumiera Widgets ---------- */
|
||||
|
||||
/* ElementBoxWidget and IDLabel within */
|
||||
.idlabel .image-button {
|
||||
min-width: unset;
|
||||
min-height: unset;
|
||||
padding: inherit;
|
||||
}
|
||||
.idlabel__icon image {
|
||||
padding-left: 0.5ex;
|
||||
}
|
||||
.videodisplay {
|
||||
background-color: Black;
|
||||
min-width: 320px;
|
||||
min-height: 240px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ---------- Styles for special markup ---------- */
|
||||
|
||||
.indication-flash,
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
#include "stage/gtk-base.hpp"
|
||||
#include "stage/output/displayer.hpp"
|
||||
#include "stage/output/xv-displayer.hpp"
|
||||
#include "stage/output/gdkdisplayer.hpp"
|
||||
|
||||
namespace stage {
|
||||
namespace output {
|
||||
|
|
@ -46,18 +44,6 @@ namespace output {
|
|||
return DISPLAY_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
Displayer::preferredWidth()
|
||||
{
|
||||
return imageWidth;
|
||||
}
|
||||
|
||||
int
|
||||
Displayer::preferredHeight()
|
||||
{
|
||||
return imageHeight;
|
||||
}
|
||||
|
||||
void
|
||||
Displayer::calculateVideoLayout(
|
||||
int widget_width, int widget_height,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#define STAGE_OUTPUT_DISPLAYER_H
|
||||
|
||||
|
||||
#include "lib/nocopy.hpp"
|
||||
|
||||
namespace stage {
|
||||
namespace output {
|
||||
|
||||
|
|
@ -63,27 +65,29 @@ namespace output {
|
|||
* rewrite the two other put methods as required.
|
||||
*/
|
||||
class Displayer
|
||||
: util::NonCopyable
|
||||
{
|
||||
protected:
|
||||
int imageWidth;
|
||||
int imageHeight;
|
||||
const int videoWidth;
|
||||
const int videoHeight;
|
||||
|
||||
public:
|
||||
virtual ~Displayer() { }
|
||||
|
||||
Displayer(int w, int h)
|
||||
: videoWidth{w}
|
||||
, videoHeight{h}
|
||||
{ }
|
||||
|
||||
|
||||
/** Indicates if this object can be used to render images on the running system. */
|
||||
virtual bool usable();
|
||||
|
||||
/** Indicates the format required by the abstract put method. */
|
||||
/** Indicates the format required by the abstract put method.
|
||||
* @todo this feature was seemingly never used... can it be relevant? can we handle different formats?
|
||||
*/
|
||||
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).
|
||||
|
|
|
|||
|
|
@ -14,44 +14,29 @@
|
|||
|
||||
/** @file null-displayer.hpp
|
||||
** Passive deactivated video displayer.
|
||||
** @deprecated obsolete since GTK-3
|
||||
** @todo WIP as of 5/2025 attempt to accommodate to GTK-3 ////////////////////////////////////////////////TICKET #1403
|
||||
*/
|
||||
|
||||
|
||||
#include "stage/gtk-base.hpp"
|
||||
#include "stage/output/null-displayer.hpp"
|
||||
|
||||
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
#include <gdk/gdkx.h>
|
||||
#endif ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
#include <iostream>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
#include "lib/format-cout.hpp"
|
||||
|
||||
|
||||
namespace stage {
|
||||
namespace output {
|
||||
|
||||
NullDisplayer::NullDisplayer (Gtk::Widget* drawing_area,
|
||||
int width, int height)
|
||||
: drawingArea( drawing_area )
|
||||
int width, int height)
|
||||
: Displayer{width,height}
|
||||
, drawingArea_{drawing_area}
|
||||
{
|
||||
REQUIRE (drawing_area != NULL);
|
||||
REQUIRE (drawing_area);
|
||||
REQUIRE (width > 0);
|
||||
REQUIRE (height > 0);
|
||||
|
||||
imageWidth = width,
|
||||
imageHeight = height;
|
||||
cout << "NullDisplayer("<<drawing_area<<"): "<<width<<" x "<<height<<endl;
|
||||
}
|
||||
|
||||
bool
|
||||
NullDisplayer::usable()
|
||||
{
|
||||
return false; /////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
}
|
||||
|
||||
void
|
||||
NullDisplayer::put (void* const image)
|
||||
{
|
||||
|
|
@ -61,31 +46,14 @@ namespace output {
|
|||
video_height = 0;
|
||||
|
||||
calculateVideoLayout(
|
||||
drawingArea->get_width(),
|
||||
drawingArea->get_height(),
|
||||
preferredWidth(), preferredHeight(),
|
||||
drawingArea_->get_width(),
|
||||
drawingArea_->get_height(),
|
||||
videoWidth, videoHeight,
|
||||
video_x, video_y, video_width, video_height);
|
||||
|
||||
GdkWindow *window = drawingArea->get_window()->gobj();
|
||||
GdkWindow *window = drawingArea_->get_window()->gobj();
|
||||
REQUIRE (window != NULL);
|
||||
|
||||
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
GdkGC *gc = gdk_gc_new( window );
|
||||
REQUIRE(gc != NULL);
|
||||
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8,
|
||||
preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL );
|
||||
REQUIRE(pixbuf != NULL);
|
||||
|
||||
GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, video_width, video_height, GDK_INTERP_NEAREST );
|
||||
REQUIRE(scaled_image != NULL);
|
||||
|
||||
gdk_draw_pixbuf( window, gc, scaled_image, 0, 0, video_x, video_y, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 );
|
||||
|
||||
g_object_unref( scaled_image );
|
||||
g_object_unref( pixbuf );
|
||||
g_object_unref( gc );
|
||||
#endif ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
cout << "put("<<util::showAdr(image)<<")\t x="<<video_x<<" y="<<video_y<<" w:"<<video_width<<" h:"<<video_height<<endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@ namespace output {
|
|||
|
||||
/**
|
||||
* NullDisplayer implements the Displayer interface without any actual display.
|
||||
*
|
||||
* @todo the GdkDisplayer class is not supported anymore in Gtk3.
|
||||
* This is due to Gtk3 only supporting drawing with Cairo
|
||||
* ////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
* @todo WIP as of 5/2025 attempt to accommodate to GTK-3 /////////////////////////////////////////////////TICKET #1403
|
||||
*/
|
||||
class NullDisplayer
|
||||
|
|
@ -46,39 +42,19 @@ class NullDisplayer
|
|||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param[in] drawing_area The widget into which the video image will
|
||||
* be drawn. This value must not be NULL.
|
||||
* @param[in] width The width of the video image in pixels. This value
|
||||
* must be greater than zero.
|
||||
* @param[in] height The height of the video image in pixels. This
|
||||
* value must be greater than zero.
|
||||
*/
|
||||
NullDisplayer (Gtk::Widget* drawing_area, int width, int height );
|
||||
|
||||
/**
|
||||
* Put an image of a given width and height with the expected input
|
||||
* format (as indicated by the format method).
|
||||
* @param[in] image The video image array to draw.
|
||||
*/
|
||||
void put (void* const image);
|
||||
/** NULL-implementation: accept anything, do nothing */
|
||||
void put (void* const image) override;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Indicates if this object can be used to render images on the
|
||||
* running system.
|
||||
*/
|
||||
bool usable();
|
||||
/** NullDisplayer is always „usable“. */
|
||||
bool usable() override { return true; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The widget that video will be drawn into.
|
||||
* @remarks This value must be a valid pointer.
|
||||
*/
|
||||
Gtk::Widget* drawingArea;
|
||||
Gtk::Widget* drawingArea_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,14 +39,12 @@ namespace output {
|
|||
|
||||
GdkDisplayer::GdkDisplayer (Gtk::Widget* drawing_area,
|
||||
int width, int height)
|
||||
: drawingArea( drawing_area )
|
||||
: Displayer{width,height}
|
||||
, drawingArea_{drawing_area}
|
||||
{
|
||||
REQUIRE (drawing_area != NULL);
|
||||
REQUIRE (drawing_area);
|
||||
REQUIRE (width > 0);
|
||||
REQUIRE (height > 0);
|
||||
|
||||
imageWidth = width,
|
||||
imageHeight = height;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -64,12 +62,12 @@ namespace output {
|
|||
video_height = 0;
|
||||
|
||||
calculateVideoLayout(
|
||||
drawingArea->get_width(),
|
||||
drawingArea->get_height(),
|
||||
preferredWidth(), preferredHeight(),
|
||||
drawingArea_->get_width(),
|
||||
drawingArea_->get_height(),
|
||||
videoWidth, videoHeight,
|
||||
video_x, video_y, video_width, video_height);
|
||||
|
||||
GdkWindow *window = drawingArea->get_window()->gobj();
|
||||
GdkWindow *window = drawingArea_->get_window()->gobj();
|
||||
REQUIRE (window != NULL);
|
||||
|
||||
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class GdkDisplayer
|
|||
* The widget that video will be drawn into.
|
||||
* @remarks This value must be a valid pointer.
|
||||
*/
|
||||
Gtk::Widget* drawingArea;
|
||||
Gtk::Widget* drawingArea_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,19 +31,17 @@ namespace output {
|
|||
|
||||
XvDisplayer::XvDisplayer(Gtk::Widget *drawing_area,
|
||||
int width, int height)
|
||||
: gotPort(false)
|
||||
, drawingArea(drawing_area)
|
||||
, xvImage(NULL)
|
||||
: Displayer{width,height}
|
||||
, gotPort{false}
|
||||
, drawingArea_{drawing_area}
|
||||
, xvImage{nullptr}
|
||||
{
|
||||
REQUIRE(drawing_area != NULL);
|
||||
REQUIRE(width > 0);
|
||||
REQUIRE(height > 0);
|
||||
REQUIRE (drawing_area);
|
||||
REQUIRE (width > 0);
|
||||
REQUIRE (height > 0);
|
||||
|
||||
INFO(stage, "Trying XVideo at %d x %d", width, height);
|
||||
|
||||
imageWidth = width;
|
||||
imageHeight = height;
|
||||
|
||||
shmInfo.shmaddr = NULL;
|
||||
|
||||
Glib::RefPtr<Gdk::Window> area_window = drawing_area->get_window();
|
||||
|
|
@ -208,7 +206,7 @@ namespace output {
|
|||
XvDisplayer::put (void* const image)
|
||||
{
|
||||
REQUIRE (image != NULL);
|
||||
REQUIRE (drawingArea != NULL);
|
||||
REQUIRE (drawingArea_ != NULL);
|
||||
|
||||
if (xvImage != NULL)
|
||||
{
|
||||
|
|
@ -216,15 +214,15 @@ namespace output {
|
|||
|
||||
int video_x = 0, video_y = 0, video_width = 0, video_height = 0;
|
||||
calculateVideoLayout(
|
||||
drawingArea->get_width(),
|
||||
drawingArea->get_height(),
|
||||
preferredWidth(), preferredHeight(),
|
||||
drawingArea_->get_width(),
|
||||
drawingArea_->get_height(),
|
||||
videoWidth, videoHeight,
|
||||
video_x, video_y, video_width, video_height );
|
||||
|
||||
memcpy (xvImage->data, image, xvImage->data_size);
|
||||
|
||||
XvShmPutImage (display, grabbedPort, window, gc, xvImage,
|
||||
0, 0, preferredWidth(), preferredHeight(),
|
||||
0, 0, videoWidth, videoHeight,
|
||||
video_x, video_y, video_width, video_height, false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ namespace output {
|
|||
* The widget that video will be drawn into.
|
||||
* @remarks This value must be a valid pointer.
|
||||
*/
|
||||
Gtk::Widget* drawingArea;
|
||||
Gtk::Widget* drawingArea_;
|
||||
|
||||
/**
|
||||
* The display that video will be drawn into.
|
||||
|
|
|
|||
|
|
@ -33,14 +33,12 @@ namespace panel {
|
|||
|
||||
ViewerPanel::ViewerPanel (workspace::PanelManager& panelManager
|
||||
,Gdl::DockItem& dockItem)
|
||||
: Panel(panelManager, dockItem, getTitle(), getStockID())
|
||||
, demoPlayback_{}
|
||||
: Panel{panelManager, dockItem, getTitle(), getStockID()}
|
||||
, display_{}
|
||||
, demoPlayback_{[this](void * const buffer){ display_.pushFrame(buffer); }}
|
||||
{
|
||||
//----- Pack in the Widgets -----//
|
||||
pack_start(display_, PACK_EXPAND_WIDGET);
|
||||
|
||||
FrameDestination outputDestination (sigc::mem_fun(this, &ViewerPanel::on_frame));
|
||||
demoPlayback_.useDisplay (DisplayService::setUp (outputDestination));
|
||||
}
|
||||
|
||||
const char*
|
||||
|
|
@ -55,14 +53,5 @@ namespace panel {
|
|||
return "panel_viewer";
|
||||
}
|
||||
|
||||
void
|
||||
ViewerPanel::on_frame (void* buffer)
|
||||
{
|
||||
Displayer *displayer = display_.getDisplayer();
|
||||
REQUIRE(displayer);
|
||||
|
||||
displayer->put(buffer);
|
||||
}
|
||||
|
||||
|
||||
}}// namespace stage::panel
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ namespace panel {
|
|||
class ViewerPanel
|
||||
: public Panel
|
||||
{
|
||||
widget::VideoDisplayWidget display_;
|
||||
ctrl::DemoController demoPlayback_;
|
||||
|
||||
public:
|
||||
|
|
@ -40,15 +41,6 @@ namespace panel {
|
|||
|
||||
static const char* getTitle();
|
||||
static const gchar* getStockID();
|
||||
|
||||
|
||||
protected:
|
||||
void on_frame(void *buffer);
|
||||
|
||||
protected:
|
||||
|
||||
/** widget to display the video content */
|
||||
widget::VideoDisplayWidget display_;
|
||||
};
|
||||
|
||||
}}// namespace stage::panel
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ namespace stage {
|
|||
|
||||
cuString CLASS_background {"background"}; ///< opaque backdrop
|
||||
|
||||
cuString CLASS_videodisplay {"videodisplay"};
|
||||
|
||||
Literal ICON_placement {"placement"};
|
||||
Literal ICON_arrow_hand_menu {"arrow_hand"};
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ namespace stage {
|
|||
|
||||
extern cuString CLASS_background;
|
||||
|
||||
extern cuString CLASS_videodisplay;
|
||||
|
||||
extern Literal ICON_placement;
|
||||
extern Literal ICON_arrow_hand_menu;
|
||||
|
|
|
|||
|
|
@ -29,21 +29,29 @@
|
|||
namespace stage {
|
||||
namespace widget {
|
||||
|
||||
VideoDisplayWidget::VideoDisplayWidget()
|
||||
: displayer_(NULL)
|
||||
{ }
|
||||
|
||||
|
||||
VideoDisplayWidget::~VideoDisplayWidget()
|
||||
{
|
||||
if (displayer_) delete displayer_;
|
||||
namespace {
|
||||
const uint VIDEO_WIDTH = 320;
|
||||
const uint VIDEO_HEIGHT = 240; ////////////////////////////////////////////////////////////////////////TICKET #1289 : these should not be hard coded, but negotiated with the OutputManager
|
||||
}
|
||||
|
||||
|
||||
Displayer*
|
||||
VideoDisplayWidget::getDisplayer() const
|
||||
using std::make_unique;
|
||||
using stage::output::XvDisplayer;
|
||||
using stage::output::GdkDisplayer;
|
||||
using stage::output::NullDisplayer;
|
||||
|
||||
VideoDisplayWidget::VideoDisplayWidget()
|
||||
{
|
||||
return displayer_;
|
||||
get_style_context()->add_class (CLASS_background); // Style to ensure an opaque backdrop
|
||||
get_style_context()->add_class (CLASS_videodisplay);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VideoDisplayWidget::pushFrame (void* const buffer)
|
||||
{
|
||||
REQUIRE(displayer_);
|
||||
displayer_->put(buffer);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -52,39 +60,26 @@ namespace widget {
|
|||
{
|
||||
// invoke base implementation
|
||||
Gtk::Widget::on_realize ();
|
||||
|
||||
// Set colours
|
||||
//modify_bg (Gtk::STATE_NORMAL, Gdk::Color ("black"));
|
||||
|
||||
if (displayer_) delete displayer_;
|
||||
displayer_ = createDisplayer (this, 320, 240);
|
||||
|
||||
add_events (Gdk::ALL_EVENTS_MASK);
|
||||
setupDisplayer (VIDEO_WIDTH, VIDEO_HEIGHT);
|
||||
}
|
||||
|
||||
|
||||
Displayer*
|
||||
VideoDisplayWidget::createDisplayer (Gtk::Widget *drawingArea, int width, int height)
|
||||
void
|
||||
VideoDisplayWidget::setupDisplayer(uint videoWidth, uint videoHeight)
|
||||
{
|
||||
REQUIRE (drawingArea != NULL);
|
||||
REQUIRE (width > 0 && height > 0);
|
||||
REQUIRE (videoWidth > 0);
|
||||
REQUIRE (videoHeight > 0);
|
||||
/*
|
||||
displayer_ = make_unique<XvDisplayer> (this, videoWidth, videoHeight);
|
||||
if (displayer_->usable())
|
||||
return;
|
||||
|
||||
Displayer *displayer = NULL;
|
||||
|
||||
displayer = new XvDisplayer (drawingArea, width, height);
|
||||
if (!displayer->usable())
|
||||
{
|
||||
delete displayer;
|
||||
displayer = NULL;
|
||||
}
|
||||
|
||||
if (!displayer)
|
||||
{
|
||||
displayer = new GdkDisplayer (drawingArea, width, height);
|
||||
///////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
|
||||
}
|
||||
|
||||
return displayer;
|
||||
displayer_ = make_unique<GdkDisplayer> (this, videoWidth, videoHeight);
|
||||
if (displayer_->usable())
|
||||
return;
|
||||
*/
|
||||
displayer_ = make_unique<NullDisplayer> (this, videoWidth, videoHeight);
|
||||
ENSURE (displayer_->usable());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,12 +26,14 @@
|
|||
#include "stage/gtk-base.hpp"
|
||||
#include "stage/output/displayer.hpp"
|
||||
|
||||
|
||||
using namespace stage::output; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please!
|
||||
#include <memory>
|
||||
|
||||
namespace stage {
|
||||
namespace widget {
|
||||
|
||||
using stage::output::Displayer;
|
||||
|
||||
|
||||
/**
|
||||
* @todo the first UI draft included a video displayer widget library implementation,
|
||||
* Unfortunately, this became defunct with the switch to GTK-3. And a fun fact is,
|
||||
|
|
@ -39,24 +41,22 @@ namespace widget {
|
|||
* as to care for video display ourselves. Someone (TM) need to care for this!
|
||||
*/
|
||||
class VideoDisplayWidget
|
||||
: public Gtk::DrawingArea
|
||||
: public Gtk::Image
|
||||
{
|
||||
Displayer* displayer_;
|
||||
std::unique_ptr<Displayer> displayer_;
|
||||
|
||||
public:
|
||||
VideoDisplayWidget();
|
||||
~VideoDisplayWidget();
|
||||
|
||||
Displayer* getDisplayer() const;
|
||||
void pushFrame (void* const);
|
||||
|
||||
|
||||
private: /* ===== Overrides ===== */
|
||||
private:
|
||||
virtual void on_realize() override;
|
||||
|
||||
|
||||
private: /* ===== Internals ===== */
|
||||
static Displayer*
|
||||
createDisplayer (Gtk::Widget* drawingArea, int width, int height);
|
||||
private:
|
||||
void setupDisplayer(uint videoWidth, uint videoHeight);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -71,9 +71,10 @@ namespace node {
|
|||
~TickService ()
|
||||
{
|
||||
timespan_ = 0;
|
||||
this->join();
|
||||
usleep (200000); // additional delay allowing GTK to dispatch the last output
|
||||
auto res = this->join();
|
||||
WARN_IF (res, steam, "Failure in TickService");
|
||||
|
||||
usleep (200000); // additional delay allowing GTK to dispatch the last output
|
||||
INFO (steam, "TickService shutdown.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129665,8 +129665,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
bedeutet: im Grunde kann man <i>wild jede Funktion aufrufen</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -129704,7 +129703,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746203581424" ID="ID_441476633" MODIFIED="1746230763527" TEXT="Konsequenz: in diesem Rahmen bleiben — Kurzschluß bauen">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1746203581424" ID="ID_441476633" MODIFIED="1746321084489" TEXT="Konsequenz: in diesem Rahmen bleiben — Kurzschluß bauen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1746203611871" ID="ID_1500164071" MODIFIED="1746203618891" TEXT="bedeutet: der Controller ist schon da"/>
|
||||
<node CREATED="1746203623607" ID="ID_1866389672" MODIFIED="1746203637441" TEXT="dieser stellt direkt eine Display-Verbindung her"/>
|
||||
|
|
@ -129712,11 +129711,13 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1746203662933" ID="ID_816585590" MODIFIED="1746203684714" TEXT="der Tick-Service und DummyImageGenerator können direkt verwendet werden">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1746203694670" ID="ID_1794331285" MODIFIED="1746230885543" TEXT="Vorlage: ProcessImpl-ctor (dummy-player-service.cpp)"/>
|
||||
<node CREATED="1746203694670" ID="ID_1794331285" MODIFIED="1746321090634" TEXT="Vorlage: ProcessImpl-ctor (dummy-player-service.cpp)">
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1746231119721" ID="ID_1893495747" MODIFIED="1746237815559" TEXT="Code-Anordnung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1746231119721" ID="ID_1893495747" MODIFIED="1746321120760" TEXT="Code-Anordnung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1746231126835" ID="ID_163411237" MODIFIED="1746231131310" TEXT="der Name?">
|
||||
<node CREATED="1746231133280" ID="ID_1300819912" MODIFIED="1746231141717" TEXT="»PlaybackController«"/>
|
||||
<node CREATED="1746231142471" ID="ID_279124391" MODIFIED="1746231149371" TEXT="»PlayController«">
|
||||
|
|
@ -129729,50 +129730,81 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1746231390297" ID="ID_87527589" MODIFIED="1746237663416" TEXT="Konsequenz: forken und umbenennen">
|
||||
<node COLOR="#435e98" CREATED="1746231390297" ID="ID_87527589" MODIFIED="1746321103385" TEXT="Konsequenz: forken und umbenennen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1746231417906" ID="ID_1653206071" MODIFIED="1746231437026" TEXT="playback-controller ⟼ player-controller"/>
|
||||
<node CREATED="1746231445781" ID="ID_1228761711" MODIFIED="1746231481065" TEXT="++ ⟼ demo-controller"/>
|
||||
<node COLOR="#435e98" CREATED="1746231417906" ID="ID_1653206071" MODIFIED="1746321106400" TEXT="playback-controller ⟼ player-controller"/>
|
||||
<node COLOR="#435e98" CREATED="1746231445781" ID="ID_1228761711" MODIFIED="1746321106399" TEXT="++ ⟼ demo-controller"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237670793" ID="ID_258474163" MODIFIED="1746237738880" TEXT="dann entkernen und kurzschließen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237725210" ID="ID_138416616" MODIFIED="1746237781562" TEXT="entferne lumiera::DummyPlayer::Process playHandle_">
|
||||
<node COLOR="#338800" CREATED="1746237670793" ID="ID_258474163" MODIFIED="1746321119456" TEXT="dann entkernen und kurzschließen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1746237725210" ID="ID_138416616" MODIFIED="1746321111559" TEXT="entferne lumiera::DummyPlayer::Process playHandle_">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237741584" ID="ID_4101489" MODIFIED="1746237781562" TEXT="entferne LumieraDisplaySlot viewerHandle_">
|
||||
<node COLOR="#435e98" CREATED="1746237741584" ID="ID_4101489" MODIFIED="1746321111559" TEXT="entferne LumieraDisplaySlot viewerHandle_">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237759901" ID="ID_331458322" MODIFIED="1746237781562" TEXT="entferne static DemoController* instance">
|
||||
<node COLOR="#435e98" CREATED="1746237759901" ID="ID_331458322" MODIFIED="1746321111558" TEXT="entferne static DemoController* instance">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237799176" ID="ID_1428195458" MODIFIED="1746237807456" TEXT="Lebenszyklus neu aufbauen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1746237799176" ID="ID_1428195458" MODIFIED="1746321116092" TEXT="Lebenszyklus neu aufbauen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237785154" ID="ID_1469394159" MODIFIED="1746237807455" TEXT="direkt einen Tick-Service instantiieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1746321662339" ID="ID_705046124" MODIFIED="1746321673987" TEXT="direkt einen DummyImmageGenerator instantiieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1746237785154" ID="ID_1469394159" MODIFIED="1746321684837" TEXT="einen Tick-Service instantiieren sobald Playback stattfindet">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237836971" ID="ID_349974806" MODIFIED="1746237847634" TEXT="einen Null-Displayer schaffen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1746237836971" ID="ID_349974806" MODIFIED="1746321699135" TEXT="einen Null-Displayer schaffen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237900191" ID="ID_891690513" MODIFIED="1746237941748" TEXT="dieser empfängt zwar einen Datenblock">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1746285283565" ID="ID_1980886210" MODIFIED="1746285291666" TEXT="was für ein Format?">
|
||||
<node CREATED="1746285293070" ID="ID_1654823808" MODIFIED="1746285299797" TEXT="Code-Archäologie..."/>
|
||||
<node CREATED="1746285300603" ID="ID_1713770409" MODIFIED="1746285307663" TEXT="stelle fest: das Format wurde nie verwendet"/>
|
||||
</node>
|
||||
<node CREATED="1746306976033" ID="ID_1750181201" MODIFIED="1746306980116" TEXT="Größe">
|
||||
<node CREATED="1746306981128" ID="ID_322973917" MODIFIED="1746306997011" TEXT="wird mit dem Konstruktor des Displayers festgelegt"/>
|
||||
<node CREATED="1746306997902" ID="ID_949805986" MODIFIED="1746307010754" TEXT="das ist nicht (notwendig) die Größe des Anzeige-Widgets"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237922301" ID="ID_261548220" MODIFIED="1746237941749" TEXT="quitiert aber nur geeignet im Log">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237950796" ID="ID_833924220" MODIFIED="1746237960794" TEXT="ggfs mit gedrosselter Frame-Rate laufen lassen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1746321706423" ID="ID_476605997" MODIFIED="1746321714046" TEXT="versuche mal 4 FPS"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746237851254" ID="ID_991590991" MODIFIED="1746237873586" TEXT="Widget und Controller-Logik mit Null-Displayer neu aufbauen">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237875118" ID="ID_1626821300" MODIFIED="1746237896495" TEXT="Widget soll erst mal schwarzen Hintergrund zeichnen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1746237875118" ID="ID_1626821300" MODIFIED="1746321177564" TEXT="Widget soll erst mal schwarzen Hintergrund zeichnen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1746321143947" ID="ID_302254163" MODIFIED="1746321175715" TEXT="verwende Gtk::Image">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1746321151041" ID="ID_792096752" MODIFIED="1746321175716" TEXT="setze neue Klasse "videodisplay"">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1746321165038" ID="ID_1935368140" MODIFIED="1746321175717" TEXT="definiere für diese im CSS einen schwarzen Hintergrund">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1746321602028" ID="ID_471888500" MODIFIED="1746321627339" TEXT="setze auch mal min-width und min-height (auf 320 x 240px)">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746237886231" ID="ID_81175326" MODIFIED="1746237894236" TEXT="ein paar Buttons einbinden">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746321719549" ID="ID_1181117478" MODIFIED="1746321726590" TEXT="Buttons mit controller verdrahten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746313536301" ID="ID_407425498" MODIFIED="1746313654699" TEXT="Infos zu den Low-Level-Zugriffen">
|
||||
<arrowlink COLOR="#6c7789" DESTINATION="ID_292602658" ENDARROW="Default" ENDINCLINATION="-1126;108;" ID="Arrow_ID_1434687356" STARTARROW="None" STARTINCLINATION="-901;77;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -150890,7 +150922,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<node BACKGROUND_COLOR="#c9d1da" COLOR="#2d2198" CREATED="1439664045448" HGAP="240" ID="ID_21531707" MODIFIED="1557498707237" POSITION="left" TEXT="Info" VSHIFT="-500">
|
||||
<edge COLOR="#b4a9e3"/>
|
||||
<font NAME="SansSerif" SIZE="16"/>
|
||||
<node CREATED="1439664217489" FOLDED="true" ID="ID_104059794" MODIFIED="1557498707237" TEXT="GTK-3">
|
||||
<node CREATED="1439664217489" ID="ID_104059794" MODIFIED="1746287328902" TEXT="GTK-3">
|
||||
<node CREATED="1439664230168" FOLDED="true" ID="ID_235548644" LINK="https://wiki.gnome.org/Projects/GTK%2B/Inspector" MODIFIED="1557498707237" TEXT="GTK+ Inspector">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1439664318604" ID="ID_1327496126" MODIFIED="1557498707237" TEXT="keyboard shortcut">
|
||||
|
|
@ -150923,6 +150955,18 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746287605697" HGAP="29" ID="ID_1605299883" MODIFIED="1746287612557" TEXT="Dokumentation">
|
||||
<node CREATED="1746287995242" ID="ID_445627802" MODIFIED="1746288001360" TEXT="Programming with Gtkmm">
|
||||
<node CREATED="1746288002185" ID="ID_632354219" LINK="https://web.archive.org/web/20200428080214/https://developer.gnome.org/gtkmm-tutorial/stable/index.html.en" MODIFIED="1746289645030" TEXT="Gtkmm-3 (Archive 2020)">
|
||||
<node CREATED="1746288192067" ID="ID_1226751634" LINK="https://download.gnome.org/sources/gtkmm-documentation/3.24/" MODIFIED="1746288198981" TEXT="download"/>
|
||||
</node>
|
||||
<node CREATED="1746288009436" ID="ID_1259724761" LINK="https://gnome.pages.gitlab.gnome.org/gtkmm-documentation/index.html" MODIFIED="1746288033465" TEXT="Gtkmm-4 (current)"/>
|
||||
</node>
|
||||
<node CREATED="1746309394880" ID="ID_1482721663" LINK="https://gtkmm.gnome.org/en/documentation.html" MODIFIED="1746311409207" TEXT="GTKmm-Documentation (current)"/>
|
||||
<node CREATED="1746288640997" ID="ID_865943990" LINK="https://web.archive.org/web/20200508150948/https://developer.gnome.org/references" MODIFIED="1746289246861" TEXT="Developers.gnome.org (Archive 2020)">
|
||||
<node CREATED="1746289110036" ID="ID_910026032" LINK="https://web.archive.org/web/20201112022432/https://developer.gnome.org/gtkmm/stable/" MODIFIED="1746289198485" TEXT="Gtkmm-3"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1534634232557" HGAP="31" ID="ID_1467351006" MODIFIED="1557498707237" TEXT="Konzepte" VSHIFT="-22">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="info"/>
|
||||
|
|
@ -152002,6 +152046,51 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<arrowlink COLOR="#76a5de" DESTINATION="ID_293762905" ENDARROW="Default" ENDINCLINATION="109;127;" ID="Arrow_ID_1149853107" STARTARROW="None" STARTINCLINATION="-391;0;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746311574167" FOLDED="true" ID="ID_348215446" MODIFIED="1746311577938" TEXT="Lowlevel">
|
||||
<node CREATED="1746311579567" ID="ID_595285490" MODIFIED="1746311686884" TEXT="wird zunehmend verborgen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und zwar, weil GTK portabel ist, und man eigentlich nicht auf die unterliegende Window/Grafik-Technologie zugreifen sollte; mit Wayland gibt es nun sogar unter Linux eine zweite Variante, d.h. man kann nicht mehr sicher sein, daß man überhaupt an ein X-Window oder X-Display gebunden ist.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1746311688604" ID="ID_748124734" MODIFIED="1746313520669" TEXT="stattdessen">
|
||||
<linktarget COLOR="#627b8f" DESTINATION="ID_748124734" ENDARROW="Default" ENDINCLINATION="83;412;" ID="Arrow_ID_1511868825" SOURCE="ID_13585943" STARTARROW="None" STARTINCLINATION="342;-494;"/>
|
||||
<node CREATED="1746311692915" ID="ID_1276548378" MODIFIED="1746311710469" TEXT="von Widget ⟶ get_native">
|
||||
<node CREATED="1746311712628" ID="ID_1671886026" MODIFIED="1746311772953">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<u>Interface</u>: dasjenige Widget,
|
||||
</p>
|
||||
<p>
|
||||
das die tatsächliche Realisierung macht
|
||||
</p>
|
||||
<p>
|
||||
(typischerweise ein Gtk::Window)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1746311792870" ID="ID_1171457982" LINK="https://gnome.pages.gitlab.gnome.org/gtkmm/classGtk_1_1Native.html#a72083bb9c428f484af08758ad6cd0e17" MODIFIED="1746311903570" TEXT="Glib::RefPtr< Gdk::Surface > Gtk::Native::get_surface ()">
|
||||
<arrowlink DESTINATION="ID_435101528" ENDARROW="Default" ENDINCLINATION="71;-12;" ID="Arrow_ID_1108289227" STARTARROW="None" STARTINCLINATION="-125;9;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746311873405" ID="ID_435101528" LINK="https://gnome.pages.gitlab.gnome.org/gtkmm/classGdk_1_1Surface.html" MODIFIED="1746311903570" TEXT="Gdk::Surface">
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_435101528" ENDARROW="Default" ENDINCLINATION="71;-12;" ID="Arrow_ID_1108289227" SOURCE="ID_1171457982" STARTARROW="None" STARTINCLINATION="-125;9;"/>
|
||||
<node CREATED="1746311909912" ID="ID_1528013851" MODIFIED="1746311923922" TEXT="eine abstrahierte Zone auf einem Grafik-Display"/>
|
||||
<node CREATED="1746312004492" ID="ID_220756072" MODIFIED="1746312017221" TEXT="kann X-Window sein, aber auch Cairo oder OpenGL"/>
|
||||
<node CREATED="1746312035670" ID="ID_410018707" MODIFIED="1746312045864" TEXT="von dort kommt man auf das Gdk::Display"/>
|
||||
<node CREATED="1746312046709" ID="ID_778386913" MODIFIED="1746312057450" TEXT="und von dort auf Gdk::Monitor"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477523681978" HGAP="14" ID="ID_400257229" MODIFIED="1557498707238" TEXT="Richtlinien" VSHIFT="11">
|
||||
<node CREATED="1477523701544" ID="ID_1802991794" MODIFIED="1557498707238" TEXT="empfohlen">
|
||||
<node CREATED="1477523709342" ID="ID_781118281" MODIFIED="1557498707238" TEXT="Box">
|
||||
|
|
@ -153394,7 +153483,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
/*
|
||||
/*
|
||||
</p>
|
||||
<p>
|
||||
 * Gadgets are 'next-generation widgets' - they combine a CSS node
|
||||
|
|
@ -154442,6 +154531,67 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1504215729848" ID="ID_518260540" MODIFIED="1557498707239" TEXT="howto">
|
||||
<node CREATED="1746313074008" ID="ID_326777030" MODIFIED="1746313077703" TEXT="X-Window">
|
||||
<node CREATED="1746313079527" FOLDED="true" ID="ID_292602658" MODIFIED="1746313654699" TEXT="an das X-Window rankommen">
|
||||
<linktarget COLOR="#6c7789" DESTINATION="ID_292602658" ENDARROW="Default" ENDINCLINATION="-1126;108;" ID="Arrow_ID_1434687356" SOURCE="ID_407425498" STARTARROW="None" STARTINCLINATION="-901;77;"/>
|
||||
<node CREATED="1746313102451" ID="ID_757727277" LINK="https://discourse.gnome.org/t/set-absolut-window-position-in-gtk4/8552/4" MODIFIED="1746313148021" TEXT="Frage im GNOME-Forum">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
es ging darum, an die unterliegenden X-Windows ranzukommen, um sie dann auf dem Bidschirm zu positionierenl
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1746313154700" ID="ID_1881885906" MODIFIED="1746313243780" TEXT="Wir haben entsprechenden Code in unserem XvDisplayer">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<div style="background-color: #eee0b5; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 2px">
|
||||
<div style="color: #202020; background-color: #eee0b5; font-family: Bitstream Vera Sans Mono; font-size: 9pt; white-space: pre">
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#1a1ac4">Window window</font><font color="#3a1f18"> </font><font color="#65533c">=</font><font color="#3a1f18"> </font><font color="#95271a">GDK_WINDOW_XID</font><font color="#3a1f18"> </font><font color="#11123a">(</font><font color="#3a1f18">area_window</font><font color="#874a15"><b>-></b></font><font color="#753737">gobj</font><font color="#11123a">())</font><font color="#65533c">;</font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#1a1ac4">Display* display</font><font color="#3a1f18"> </font><font color="#65533c">=</font><font color="#3a1f18"> </font><font color="#95271a">GDK_WINDOW_XDISPLAY</font><font color="#3a1f18"> </font><font color="#11123a">(</font><font color="#3a1f18">area_window</font><font color="#874a15"><b>-></b></font><font color="#753737">gobj</font><font color="#11123a">())</font><font color="#65533c">;</font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1746313246086" ID="ID_1024347343" MODIFIED="1746313262481" TEXT="dabei expandieren die Macros äquivalent zu dem im Forum Gesagten"/>
|
||||
<node CREATED="1746313268165" ID="ID_1783118756" MODIFIED="1746313278287" TEXT="gdkx11window.h"/>
|
||||
</node>
|
||||
<node CREATED="1746313293476" ID="ID_13585943" MODIFIED="1746313528485">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dieser Code ist anscheinend <i>nicht deprecated</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#627b8f" DESTINATION="ID_748124734" ENDARROW="Default" ENDINCLINATION="83;412;" ID="Arrow_ID_1511868825" STARTARROW="None" STARTINCLINATION="342;-494;"/>
|
||||
<node CREATED="1746313308823" ID="ID_586730227" MODIFIED="1746313316638" TEXT="aber man findet dazu nichts in der Doku"/>
|
||||
<node CREATED="1746313317267" ID="ID_580811889" MODIFIED="1746313423821" TEXT="das heißt, er gehört zur Implementierung, nicht zum Interface">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das GTK-Projekt führt seit Gtk-3 zunehmen weitere Abstraktionen ein, über die alle relevanten Aufgaben erledigt werden können (selbst low-Level-Aufgaben wie das Mapping von Device-Koordinaten). Siehe Gtk::Native, und von dort Gdk::Surface
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1446515847047" FOLDED="true" ID="ID_290915762" MODIFIED="1557498707239" TEXT="GtkCssProvider">
|
||||
<node CREATED="1446515865029" ID="ID_1503616150" MODIFIED="1557498707239" TEXT="parsing errors"/>
|
||||
<node CREATED="1477784584821" ID="ID_1810760662" LINK="https://developer.gnome.org/gtkmm-tutorial/stable/sec-custom-widgets.html.en" MODIFIED="1576282357941" TEXT="Beispiel im GTKmm-Guide (custom widget)">
|
||||
|
|
@ -161649,8 +161799,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
jeder Displayer versucht eine minimale Initialisierung im Konstruktor und signalisiert damit, daß er im Prinzip Video ausgeben könnte
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1746053626501" ID="ID_1505251313" MODIFIED="1746053644326" TEXT="virtual DisplayerInput format()">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -161729,8 +161878,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
Implementierung war <i>extrem einfach</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -161770,8 +161918,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
die Anzeige erscheint nur <i>marginal gebrochen</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1746059010720" ID="ID_431781822" MODIFIED="1746059029328" TEXT="es müßten nur wenige Teile (einfach) nach GTK-3 portiert werden">
|
||||
<node CREATED="1746059031084" ID="ID_752582525" MODIFIED="1746059039703" TEXT="das VideoDisplayWidget"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue