XV-Display: partial success with the fallback / pixbuf display

The new solution is to (still) use a Gdk::Pixbuf,
because in GTK-3 the more modern alternatives are not yet provided.
But we can pass this Pixbuf directly to Gtk::Image, instead of trying
to do low-level drawing on the X-Window.

Other than that, I more or less transformed the old C-style code
into the corresponding calls in Gdkmm.

__SUCCESS__: we get **some display**
__TODO__ : the displayed image is Garbage, which means that the pixel layout is not correct
This commit is contained in:
Fischlurch 2025-05-07 18:39:11 +02:00
parent 93a62af39e
commit 7fd3e71936
8 changed files with 81 additions and 44 deletions

View file

@ -26,15 +26,14 @@
namespace stage {
namespace output {
NullDisplayer::NullDisplayer (Gtk::Widget* drawing_area,
NullDisplayer::NullDisplayer (Gtk::Widget& drawing_area,
int width, int height)
: Displayer{width,height}
, drawingArea_{drawing_area}
{
REQUIRE (drawing_area);
REQUIRE (width > 0);
REQUIRE (height > 0);
cout << "NullDisplayer("<<drawing_area<<"): "<<width<<" x "<<height<<endl;
cout << "NullDisplayer("<<&drawing_area<<"): "<<width<<" x "<<height<<endl;
}
void
@ -46,12 +45,12 @@ namespace output {
video_height = 0;
calculateVideoLayout(
drawingArea_->get_width(),
drawingArea_->get_height(),
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);
cout << "put("<<util::showAdr(image)<<")\t x="<<video_x<<" y="<<video_y<<" w:"<<video_width<<" h:"<<video_height<<endl;
}

View file

@ -42,7 +42,7 @@ class NullDisplayer
{
public:
NullDisplayer (Gtk::Widget* drawing_area, int width, int height );
NullDisplayer (Gtk::Widget& drawing_area, int width, int height );
/** NULL-implementation: accept anything, do nothing */
void put (void* const image) override;
@ -54,7 +54,7 @@ class NullDisplayer
private:
Gtk::Widget* drawingArea_;
Gtk::Widget& drawingArea_;
};

View file

@ -35,14 +35,15 @@
namespace stage {
namespace output {
PixbufDisplayer::PixbufDisplayer (Gtk::Image* drawing_area,
PixbufDisplayer::PixbufDisplayer (Gtk::Image& drawing_area,
int width, int height)
: Displayer{width,height}
, drawingArea_{drawing_area}
{
REQUIRE (drawing_area);
REQUIRE (width > 0);
REQUIRE (height > 0);
auto iconSet = Gtk::IconSet::lookup_default (Gtk::StockID("panel_play"));
drawingArea_.set(iconSet, Gtk::IconSize(Gtk::ICON_SIZE_DIALOG));
cout << "USING PixbufDisplayer" <<endl;
}
@ -57,28 +58,18 @@ namespace output {
{
int video_x = 0,
video_y = 0,
video_width = 0,
video_height = 0;
destWidth = 0,
destHeight = 0;
calculateVideoLayout(
drawingArea_->get_width(),
drawingArea_->get_height(),
drawingArea_.get_width(),
drawingArea_.get_height(),
videoWidth, videoHeight,
video_x, video_y, video_width, video_height);
video_x, video_y, destWidth, destHeight);
GdkWindow *window = drawingArea_->get_window()->gobj();
GdkWindow *window = drawingArea_.get_window()->gobj();
REQUIRE (window != NULL);
if (not init_)
{
auto iconSet = Gtk::IconSet::lookup_default (Gtk::StockID("panel_play"));
drawingArea_->set(iconSet, Gtk::IconSize(Gtk::ICON_SIZE_DIALOG));
init_ = true;
cout << "INIT Pixbuf"<< iconSet.get() <<endl;
}
drawingArea_->queue_draw();
int pixSiz = drawingArea_->property_pixel_size();
cout << "bong.."<<pixSiz<<endl;
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
GdkGC *gc = gdk_gc_new( window );
REQUIRE(gc != NULL);
@ -87,7 +78,7 @@ namespace output {
preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL );
REQUIRE(pixbuf != NULL);
GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, video_width, video_height, GDK_INTERP_NEAREST );
GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, destWidth, destHeight, 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 );
@ -96,6 +87,20 @@ namespace output {
g_object_unref( pixbuf );
g_object_unref( gc );
#endif ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display
auto* imageData = static_cast<const guint8*> (image);
auto rawBuf = Gdk::Pixbuf::create_from_data (imageData
,Gdk::COLORSPACE_RGB
,false // has_alpha
,8 // bits_per_sample
,videoWidth
,videoHeight
,0 // rowstride (can be used to round up to even powers of two per row)
);
ASSERT (rawBuf);
auto scaledBuf = rawBuf->scale_simple (destWidth, destHeight, Gdk::INTERP_NEAREST);
drawingArea_.set (scaledBuf);
drawingArea_.queue_draw();
cout << "bong.."<<scaledBuf.get()<<endl;
}

View file

@ -44,7 +44,7 @@ namespace output {
class PixbufDisplayer
: public Displayer
{
Gtk::Image* drawingArea_;
Gtk::Image& drawingArea_;
public:
@ -57,7 +57,7 @@ class PixbufDisplayer
* @param[in] height The height of the video image in pixels. This
* value must be greater than zero.
*/
PixbufDisplayer (Gtk::Image* drawing_area, int width, int height );
PixbufDisplayer (Gtk::Image& drawing_area, int width, int height );
/**
* Put an image of a given width and height with the expected input
@ -70,7 +70,6 @@ class PixbufDisplayer
bool usable() override;
private:
bool init_{false};
};

View file

@ -29,14 +29,13 @@
namespace stage {
namespace output {
XvDisplayer::XvDisplayer(Gtk::Widget *drawing_area,
int width, int height)
XvDisplayer::XvDisplayer(Gtk::Widget& drawing_area
,int width, int height)
: Displayer{width,height}
, gotPort{false}
, drawingArea_{drawing_area}
, xvImage{nullptr}
{
REQUIRE (drawing_area);
REQUIRE (width > 0);
REQUIRE (height > 0);
@ -44,7 +43,7 @@ namespace output {
shmInfo.shmaddr = NULL;
Glib::RefPtr<Gdk::Window> area_window = drawing_area->get_window();
Glib::RefPtr<Gdk::Window> area_window = drawing_area.get_window();
window = GDK_WINDOW_XID (area_window->gobj());
display = GDK_WINDOW_XDISPLAY (area_window->gobj());
@ -206,7 +205,6 @@ namespace output {
XvDisplayer::put (void* const image)
{
REQUIRE (image != NULL);
REQUIRE (drawingArea_ != NULL);
if (xvImage != NULL)
{
@ -214,8 +212,8 @@ namespace output {
int video_x = 0, video_y = 0, video_width = 0, video_height = 0;
calculateVideoLayout(
drawingArea_->get_width(),
drawingArea_->get_height(),
drawingArea_.get_width(),
drawingArea_.get_height(),
videoWidth, videoHeight,
video_x, video_y, video_width, video_height );

View file

@ -59,7 +59,7 @@ namespace output {
* @param height The height of the video image in pixels. This value
* must be greater than zero.
*/
XvDisplayer (Gtk::Widget* drawing_area, int width, int height);
XvDisplayer (Gtk::Widget& drawing_area, int width, int height);
~XvDisplayer();
@ -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.

View file

@ -71,15 +71,15 @@ namespace widget {
REQUIRE (videoWidth > 0);
REQUIRE (videoHeight > 0);
/*
displayer_ = make_unique<XvDisplayer> (this, videoWidth, videoHeight);
displayer_ = make_unique<XvDisplayer> (*this, videoWidth, videoHeight);
if (displayer_->usable())
return;
*/
displayer_ = make_unique<PixbufDisplayer> (this, videoWidth, videoHeight);
displayer_ = make_unique<PixbufDisplayer> (*this, videoWidth, videoHeight);
if (displayer_->usable())
return;
displayer_ = make_unique<NullDisplayer> (this, videoWidth, videoHeight);
displayer_ = make_unique<NullDisplayer> (*this, videoWidth, videoHeight);
ENSURE (displayer_->usable());
}

View file

@ -129990,12 +129990,48 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746542764270" ID="ID_1879098999" MODIFIED="1746542827394" TEXT="Experiment: die Fallback-Anzeige (pixbuff) portieren">
<icon BUILTIN="full-1"/>
<node CREATED="1746630398020" ID="ID_1520924993" MODIFIED="1746632466497" TEXT="mit GTK-3 m&#xfc;ssen wir einen Pixbuf verwenden">
<node COLOR="#435e98" CREATED="1746630398020" ID="ID_1520924993" MODIFIED="1746635759884" TEXT="mit GTK-3 m&#xfc;ssen wir einen Pixbuf verwenden">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1746630418070" ID="ID_396250251" MODIFIED="1746630427582" TEXT="die neueren Alternativen wurden erst mit GTK-4 eingef&#xfc;hrt"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1746632432347" ID="ID_110870446" MODIFIED="1746632460790" TEXT="k&#xf6;nne aber versuchen, den in ein Gtk::Image einzubinden">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1746632432347" ID="ID_110870446" MODIFIED="1746635776370" TEXT="den in ein Gtk::Image einbinden">
<icon BUILTIN="idea"/>
<node COLOR="#435e98" CREATED="1746634011595" ID="ID_637524869" MODIFIED="1746634070068" TEXT="mal versuchsweise mit einem Stock-Iconset f&#xfc;llen"/>
<node COLOR="#435e98" CREATED="1746634026920" ID="ID_1276591207" MODIFIED="1746634070096" TEXT="unser UiStyle erzeugt einige Stock-Iconsets">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1746634037518" ID="ID_1438708277" MODIFIED="1746634061326" TEXT="Erfolg: verwende StockID(&quot;panel_play&quot;) mit ICON_SIZE_DIALOG">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1746633912948" ID="ID_909409546" MODIFIED="1746635752594" TEXT="passenden Pixbuf erzeugen">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1746633922734" ID="ID_877262015" MODIFIED="1746635757088" TEXT="hangle mich an der Doku in der verwendeten Lib-Version (Gtkmm 3.24) entlang">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#435e98" CREATED="1746633984432" ID="ID_610899228" MODIFIED="1746635757087" TEXT="die create_from_data()-Funktionen sehen vielversprechend aus">
<node CREATED="1746634167740" ID="ID_814656388" MODIFIED="1746634185273" TEXT="HA! der alte Code verwendete die C-Variante dieser Funktionen"/>
<node CREATED="1746635669035" ID="ID_315206220" MODIFIED="1746635676774" TEXT="dann eigentlich sinngem&#xe4;&#xdf;"/>
</node>
</node>
<node COLOR="#338800" CREATED="1746635683569" ID="ID_1223394798" MODIFIED="1746635750815" TEXT="aber nun diesen direkt an das Gtk::Image geben">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1746635693567" ID="ID_315751256" MODIFIED="1746635747623" STYLE="fork">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Erfolg-1 : es wird <b>irgendwas angezeigt</b>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="full-1"/>
<node CREATED="1746635712253" ID="ID_1901638448" MODIFIED="1746635741949" TEXT="da pa&#xdf;t wohl das Pixel-Layout nicht"/>
<node CREATED="1746635726454" ID="ID_1915597327" MODIFIED="1746635741949" TEXT="aber man sieht den Frame-Takt"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746542785647" ID="ID_1968916517" MODIFIED="1746542843774" TEXT="Experiment: den XV-Code aktivieren">