XV-Display: the old XVideo display code indeed still works
''it basically works...'' TODO - the image is updated only when moving the mouse over the widget - calculation of window decoration is not correct - a strange transparent zone appears in the UI directly above the widget
This commit is contained in:
parent
7fd3e71936
commit
5d3710fca8
9 changed files with 83 additions and 66 deletions
|
|
@ -18,26 +18,23 @@
|
|||
** Implementation of a displayer object, intended for creating
|
||||
** a video display in the UI. This class was created as part of
|
||||
** an initial draft of the user interface.
|
||||
** @warning as of 2016 it is not clear, if this code will be
|
||||
** @todo as of 2016 it is not clear, if this code will be
|
||||
** evolved into the actual display facility, or be
|
||||
** replaced and rewritten, when we're about to
|
||||
** replaced and rewritten, when we're about to
|
||||
** create a functional video display connected
|
||||
** to the render engine.
|
||||
** to the render engine.
|
||||
** @todo 5/2025 used in an experiment for video output
|
||||
*/
|
||||
|
||||
|
||||
#include "stage/gtk-base.hpp"
|
||||
#include "stage/output/displayer.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace stage {
|
||||
namespace output {
|
||||
|
||||
bool
|
||||
Displayer::usable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DisplayerInput
|
||||
Displayer::format()
|
||||
{
|
||||
|
|
@ -46,28 +43,26 @@ namespace output {
|
|||
|
||||
void
|
||||
Displayer::calculateVideoLayout(
|
||||
int widget_width, int widget_height,
|
||||
int image_width, int image_height,
|
||||
int &video_x, int &video_y, int &video_width, int &video_height )
|
||||
int widgetWidth, int widgetHeight,
|
||||
int &imgOrg_x, int &imgOrg_y, int &imgWidth, int &imgHeight )
|
||||
{
|
||||
REQUIRE (widget_width >= 0);
|
||||
REQUIRE (widget_height >= 0);
|
||||
REQUIRE (image_width >= 0);
|
||||
REQUIRE (image_height >= 0);
|
||||
REQUIRE (0 < widgetWidth );
|
||||
REQUIRE (0 < widgetHeight);
|
||||
REQUIRE (0 < videoWidth );
|
||||
REQUIRE (0 < videoHeight );
|
||||
|
||||
double ratio_width = ( double ) widget_width / ( double ) image_width;
|
||||
double ratio_height = ( double ) widget_height / ( double ) image_height;
|
||||
double ratio_constant = ratio_height < ratio_width ?
|
||||
ratio_height : ratio_width;
|
||||
video_width = ( int ) ( image_width * ratio_constant + 0.5 );
|
||||
video_height = ( int ) ( image_height * ratio_constant + 0.5 );
|
||||
video_x = ( widget_width - video_width ) / 2;
|
||||
video_y = ( widget_height - video_height ) / 2;
|
||||
auto ratioW = double(widgetWidth ) / videoWidth;
|
||||
auto ratioH = double(widgetHeight) / videoHeight;
|
||||
auto scale = std::min (ratioW, ratioH);
|
||||
imgWidth = std::lround (scale * videoWidth);
|
||||
imgHeight = std::lround (scale * videoHeight);
|
||||
imgOrg_x = (widgetWidth - imgWidth) / 2;
|
||||
imgOrg_y = (widgetHeight - imgHeight) / 2;
|
||||
|
||||
ENSURE (video_x >= 0 && video_x < widget_width);
|
||||
ENSURE (video_y >= 0 && video_y < widget_height);
|
||||
ENSURE (video_width <= widget_width);
|
||||
ENSURE (video_width <= widget_width);
|
||||
ENSURE (imgWidth <= widgetWidth);
|
||||
ENSURE (imgWidth <= widgetWidth);
|
||||
ENSURE (0 <= imgOrg_x and imgOrg_x < widgetWidth);
|
||||
ENSURE (0 <= imgOrg_y and imgOrg_y < widgetHeight);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -68,20 +68,20 @@ namespace output {
|
|||
: util::NonCopyable
|
||||
{
|
||||
protected:
|
||||
const int videoWidth;
|
||||
const int videoHeight;
|
||||
const uint videoWidth;
|
||||
const uint videoHeight;
|
||||
|
||||
public:
|
||||
virtual ~Displayer() { }
|
||||
|
||||
Displayer(int w, int h)
|
||||
Displayer(uint w, uint h)
|
||||
: videoWidth{w}
|
||||
, videoHeight{h}
|
||||
{ }
|
||||
|
||||
|
||||
/** Indicates if this object can be used to render images on the running system. */
|
||||
virtual bool usable();
|
||||
virtual bool usable() =0;
|
||||
|
||||
/** 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?
|
||||
|
|
@ -99,21 +99,21 @@ namespace output {
|
|||
/**
|
||||
* Calculates the coordinates for placing a video image inside a widget
|
||||
*
|
||||
* @param[in] widget_width The width of the display widget.
|
||||
* @param[in] widget_height The height of the display widget.
|
||||
* @param[in] image_width The width of the video image.
|
||||
* @param[in] image_height The height of the video image.
|
||||
* @param[out] video_x The x-coordinate of the top left
|
||||
* corner of the scaled video image.
|
||||
* @param[out] video_y The y-coordinate of the top left
|
||||
* corner of the scaled video image.
|
||||
* @param[out] video_width The width of the scale video image.
|
||||
* @param[out] video_height The height of the scale video image.
|
||||
* @param[in] widgetWidth available width for display in the widget.
|
||||
* @param[in] widgetHeight available height for display in the widget.
|
||||
* @param[out] imgOrg_x x-coordinate of the top left corner of the
|
||||
* scaled video image to display.
|
||||
* @param[out] imgOrg_y y-coordinate of the top left corner.
|
||||
* @param[out] imgWidth width of the scale video image to display.
|
||||
* @param[out] imgHeight height of the scale video image.
|
||||
*/
|
||||
static void calculateVideoLayout(
|
||||
int widget_width, int widget_height,
|
||||
int image_width, int image_height,
|
||||
int &video_x, int &video_y, int &video_width, int &video_height );
|
||||
void calculateVideoLayout(int widgetWidth
|
||||
,int widgetHeight
|
||||
,int& imgOrg_x
|
||||
,int& imgOrg_y
|
||||
,int& imgWidth
|
||||
,int& imgHeight
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace stage {
|
|||
namespace output {
|
||||
|
||||
NullDisplayer::NullDisplayer (Gtk::Widget& drawing_area,
|
||||
int width, int height)
|
||||
uint width, uint height)
|
||||
: Displayer{width,height}
|
||||
, drawingArea_{drawing_area}
|
||||
{
|
||||
|
|
@ -47,7 +47,6 @@ namespace output {
|
|||
calculateVideoLayout(
|
||||
drawingArea_.get_width(),
|
||||
drawingArea_.get_height(),
|
||||
videoWidth, videoHeight,
|
||||
video_x, video_y, video_width, video_height);
|
||||
|
||||
GdkWindow *window = drawingArea_.get_window()->gobj();
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class NullDisplayer
|
|||
{
|
||||
public:
|
||||
|
||||
NullDisplayer (Gtk::Widget& drawing_area, int width, int height );
|
||||
NullDisplayer (Gtk::Widget& drawing_area, uint width, uint height );
|
||||
|
||||
/** NULL-implementation: accept anything, do nothing */
|
||||
void put (void* const image) override;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace stage {
|
|||
namespace output {
|
||||
|
||||
PixbufDisplayer::PixbufDisplayer (Gtk::Image& drawing_area,
|
||||
int width, int height)
|
||||
uint width, uint height)
|
||||
: Displayer{width,height}
|
||||
, drawingArea_{drawing_area}
|
||||
{
|
||||
|
|
@ -56,16 +56,15 @@ namespace output {
|
|||
void
|
||||
PixbufDisplayer::put (void* const image)
|
||||
{
|
||||
int video_x = 0,
|
||||
video_y = 0,
|
||||
int orgX = 0,
|
||||
orgY = 0,
|
||||
destWidth = 0,
|
||||
destHeight = 0;
|
||||
|
||||
calculateVideoLayout(
|
||||
drawingArea_.get_width(),
|
||||
drawingArea_.get_height(),
|
||||
videoWidth, videoHeight,
|
||||
video_x, video_y, destWidth, destHeight);
|
||||
orgX, orgY, destWidth, destHeight);
|
||||
|
||||
GdkWindow *window = drawingArea_.get_window()->gobj();
|
||||
REQUIRE (window != NULL);
|
||||
|
|
@ -81,7 +80,7 @@ namespace output {
|
|||
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 );
|
||||
gdk_draw_pixbuf( window, gc, scaled_image, 0, 0, orgX, orgY, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 );
|
||||
|
||||
g_object_unref( scaled_image );
|
||||
g_object_unref( pixbuf );
|
||||
|
|
|
|||
|
|
@ -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, uint width, uint height );
|
||||
|
||||
/**
|
||||
* Put an image of a given width and height with the expected input
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@ namespace output {
|
|||
{
|
||||
gotPort = false;
|
||||
}
|
||||
if (not gotPort)
|
||||
ERROR (stage, "unable to use XVideo for display.");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -210,18 +212,17 @@ namespace output {
|
|||
{
|
||||
REQUIRE(display != NULL);
|
||||
|
||||
int video_x = 0, video_y = 0, video_width = 0, video_height = 0;
|
||||
int org_x = 0, org_y = 0, destW = 0, destH = 0;
|
||||
calculateVideoLayout(
|
||||
drawingArea_.get_width(),
|
||||
drawingArea_.get_height(),
|
||||
videoWidth, videoHeight,
|
||||
video_x, video_y, video_width, video_height );
|
||||
org_x, org_y, destW, destH );
|
||||
|
||||
memcpy (xvImage->data, image, xvImage->data_size);
|
||||
|
||||
XvShmPutImage (display, grabbedPort, window, gc, xvImage,
|
||||
0, 0, videoWidth, videoHeight,
|
||||
video_x, video_y, video_width, video_height, false);
|
||||
org_x, org_y, destW, destH, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,11 +70,11 @@ namespace widget {
|
|||
{
|
||||
REQUIRE (videoWidth > 0);
|
||||
REQUIRE (videoHeight > 0);
|
||||
/*
|
||||
|
||||
displayer_ = make_unique<XvDisplayer> (*this, videoWidth, videoHeight);
|
||||
if (displayer_->usable())
|
||||
return;
|
||||
*/
|
||||
|
||||
displayer_ = make_unique<PixbufDisplayer> (*this, videoWidth, videoHeight);
|
||||
if (displayer_->usable())
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -130027,15 +130027,38 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
Erfolg-1 : es wird <b>irgendwas angezeigt</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="full-1"/>
|
||||
<node CREATED="1746635712253" ID="ID_1901638448" MODIFIED="1746635741949" TEXT="da paßt wohl das Pixel-Layout nicht"/>
|
||||
<node CREATED="1746635726454" ID="ID_1915597327" MODIFIED="1746635741949" TEXT="aber man sieht den Frame-Takt"/>
|
||||
<node CREATED="1746635726454" ID="ID_1915597327" MODIFIED="1746710193073" TEXT="man sieht den Frame-Takt"/>
|
||||
<node CREATED="1746710178642" ID="ID_136906548" MODIFIED="1746710186933" TEXT="aber die Anzeige ist »sonderbar«">
|
||||
<node CREATED="1746635712253" ID="ID_1901638448" MODIFIED="1746710176681" TEXT="da paßt wohl das Pixel-Layout nicht"/>
|
||||
<node CREATED="1746710197119" ID="ID_154063098" MODIFIED="1746710231128" TEXT="das Image im Displayer wird vergrößert...">
|
||||
<node CREATED="1746710231811" ID="ID_1505139667" MODIFIED="1746710240582" TEXT="auf 744 × 558 pixels"/>
|
||||
<node CREATED="1746710241433" ID="ID_581911863" MODIFIED="1746710261314" TEXT="und zwar in dem Moment, wo der PixBuff zum ersten Mal gesetzt wird"/>
|
||||
<node CREATED="1746710300930" ID="ID_1739522299" MODIFIED="1746710317071" TEXT="trotzdem vestehe ich die Maße nicht: 320px mal 2 wäre 640"/>
|
||||
<node CREATED="1746710330318" ID="ID_1347613953" MODIFIED="1746710350055" TEXT="das Display-Panel läßt sich interaktiv nicht verkleinern (nur vergrößern)"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1746713519060" ID="ID_1373646714" MODIFIED="1746713539641" TEXT="doch erstmal: den XV-Code untersuchen und (re)aktivieren">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746542785647" ID="ID_1968916517" MODIFIED="1746542843774" TEXT="Experiment: den XV-Code aktivieren">
|
||||
<icon BUILTIN="full-2"/>
|
||||
<node CREATED="1746718064358" ID="ID_1201089630" MODIFIED="1746718080146" TEXT="erst mal sinngemäß mit den neuen Widget-Parametern verdrahtet"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1746718080949" ID="ID_1374647638" MODIFIED="1746718100295" TEXT="Erfolg-2 : die XV-Anzeige funktioniert grundsätzlich">
|
||||
<icon BUILTIN="full-2"/>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1746718103627" ID="ID_1187659462" MODIFIED="1746718152643" TEXT="...aber nur, wenn man die Maus über dem Widget bewegt">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1746718116512" ID="ID_415171245" MODIFIED="1746718148895" TEXT="und die Höhe der Dekoration ist auch nicht korrekt eingerechnet">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1746718129879" ID="ID_1760604400" MODIFIED="1746718147158" TEXT="und eine sonderbare durchsichtige Zone ist im GUI">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue