我需要在C中编写一个GTK应用程序,该应用程序使用Cairo做一些动画,并将呈现为另一个正在运行的应用程序中存在的GTK小部件。 想法是做与VLC和Mplayer相同的事情。 例如,Mplayer具有-wid选项:
-wid (also see -guiwid) (X11, OpenGL and DirectX only)
This tells MPlayer to attach to an existing window. Useful to embed MPlayer in a browser (e.g. the plugger extension). This option
fills the given window completely, thus aspect scaling, panscan, etc
are no longer handled by MPlayer but must be managed by the
application that created the window.
使用此Mplayer选项,您可以使用GTKImage小部件创建一个GTK应用程序,获取它的Xid,然后使用Mplayer在指定的Xid的GTK应用程序中播放电影。
我正在尝试做相同的事情,除了使用Cairo渲染/绘制到外部窗口中。 有人有建议或更好的代码示例吗?
我认为您无法将任何内容渲染到另一个进程窗口中。 但是,如果Rodrigos解决方案有效,那么Id会很高兴,因为Im当然容易出错;-)
我可以做,因为我以前做过。 编写了一个简单的GTK应用程序,其中包含一个GtkImage小部件。 我能够获取GtkImage小部件Xid并将其传递给Mplayer(一个单独的过程),然后将电影渲染到我的Gtk应用GtkImage中。 这是此类事情的C ++ gtkmm示例。 developer.gnome.org/gtkmm-tutorial/stable/
看一下GtkSocket和GtkPlug类。
主程序将创建一个GtkSocket,而您可以传递给另一个程序的XID将由函数gtk_socket_get_id()返回。 然后其他程序将其用作gtk_plug_new()函数的参数。 所有渲染将在此新GtkPlug对象的子级中完成。
更新:嗯,如果您想...这里是GtkSocket/GtkPlug的一个最小示例。 您没有说是使用GTK + 2还是GTK + 3,因此我假设使用的是版本2。
server.c:
#include
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
", nwnd);
gtk_main();
return 0;
}
client.c:
#include
#include
#include
#include
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;
}
server打印要使用的XID,并且必须将其复制/粘贴为client的参数:
$ ./server
60817441
^Z
[1]+ Stopped ./server
$ bg
$ ./client 60817441
Rodrigo,这似乎是一个答案,但是,我是GTK和Cairo的新手,我似乎无法将所有内容都放在文档中。 您是否有一个小的代码片段演示了Im想要做什么?
@JimNorton-我写了一个非常简单的示例,希望它足以让您入门。