【问题标题】:How to draw / render to a widget using the widgets Xid in GTK/Cairo in 'C'如何在“C”中使用 GTK/Cairo 中的小部件 Xid 绘制/渲染到小部件
【发布时间】:2012-06-21 16:23:14
【问题描述】:

我需要在C 中编写一个GTK 应用程序,该应用程序使用Cairo 执行一些动画,该动画将呈现到另一个正在运行的应用程序中存在的GTK 小部件中。我们的想法是用VLCMplayer 做同样的事情。例如Mplayer-wid 选项:

-wid(另见 -guiwid)(仅限 X11、OpenGL 和 DirectX) 这告诉 MPlayer 附加到现有窗口。用于在浏览器中嵌入 MPlayer(例如插件扩展)。这个选项 完全填充给定的窗口,从而进行纵横比缩放、全景扫描等 不再由 MPlayer 处理,但必须由 创建窗口的应用程序。

使用此Mplayer 选项,您可以使用 GTKImage 小部件创建 GTK 应用程序,获取它的 Xid,然后使用 Mplayer 并指定 Xid 在GTK 应用程序中播放电影。

除了使用Cairo 渲染/绘制到外部窗口之外,我正在尝试做同样的事情。任何人有建议或更好的小代码示例?

【问题讨论】:

  • 我认为您不能将任何内容渲染到另一个进程的窗口中。但是,如果罗德里戈的解决方案有效,我会很高兴,因为我当然愿意犯错 ;-)
  • 可以做到,因为我以前做过。编写了一个简单的 GTK 应用程序,其中包含一个 GtkImage 小部件。我能够获得 GtkImage 小部件 Xid 并将其传递给 Mplayer(一个单独的进程),然后将电影渲染到我的 Gtk 应用程序 GtkImage 中。这是此类事情的 C++ gtkmm 示例。 developer.gnome.org/gtkmm-tutorial/stable/…

标签: c linux gtk x11 cairo


【解决方案1】:

看看GtkSocketGtkPlug 类。

主程序将创建一个GtkSocket,而您可以传递给其他程序的XID 将由函数gtk_socket_get_id() 返回。然后另一个程序将使用它作为gtk_plug_new() 函数的参数。所有的渲染都将在这个新的GtkPlug 对象的子对象中完成。

更新:好吧,如果你愿意...这里是GtkSocket/GtkPlug 的最小示例。你没有说你使用的是 GTK+2 还是 GTK+3,所以我假设是版本 2。

server.c:

#include <gtk/gtk.h>

int main(int argc, char **argv)
{
    gtk_init(&argc, &argv);

    GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *sck = gtk_socket_new();
    gtk_container_add(GTK_CONTAINER(wnd), sck);
    gtk_window_set_default_size(GTK_WINDOW(wnd), 400, 300);
    gtk_widget_show_all(wnd);

    GdkNativeWindow nwnd = gtk_socket_get_id(GTK_SOCKET(sck));
    g_print("%lu\n", nwnd);

    gtk_main();
    return 0;
}

client.c:

#include <stdlib.h>
#include <gtk/gtk.h>
#include <cairo/cairo.h>
#include <math.h>

gboolean OnDraw(GtkWidget *w, GdkEvent *ev, gpointer data)
{
    GtkAllocation size;
    gtk_widget_get_allocation(w, &size);

    cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(w));
    cairo_set_source_rgb(cr, 1, 0, 0);
    cairo_arc(cr, size.width/2, size.height/2, size.height/2, 0, 2*M_PI);
    cairo_fill(cr);
    cairo_destroy(cr);
    return TRUE;
}

int main(int argc, char **argv)
{
    gtk_init(&argc, &argv);

    GdkNativeWindow nwnd = strtoul(argv[1], NULL, 10);

    GtkWidget *plug = gtk_plug_new(nwnd);
    GtkWidget *canvas = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(plug), canvas);
    g_signal_connect(canvas, "expose-event", (GCallback)OnDraw, NULL);
    gtk_widget_show_all(plug);

    gtk_main();
    return 0;
}

要使用的 XID 由 server 打印,并且必须作为参数复制/粘贴到 client

$ ./server
60817441
^Z
[1]+  Stopped                 ./server
$ bg
$ ./client 60817441

【讨论】:

  • Rodrigo,感觉这可能是一个答案,但是,我是 GTK 和 Cairo 的新手,我似乎无法将所有内容放在一起查看文档。你有一个小代码 sn-p 来演示我正在尝试做的事情吗?
  • @JimNorton - 我写了一个非常简单的例子,希望它足以让你开始。
猜你喜欢
  • 2015-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多