将属于我发起的独立过程的X11窗口嵌入到我自己的窗口中?

时间:2014-10-13 08:11:40

标签: window x11 window-management

有一种简单的方法吗?我从来没有见过这个(除了Firefox的Adobe / ...插件),所以我对此表示怀疑......

如果没有,是否有可靠的,hacky方式(例如通过Xlib挂钩该过程&LD_PRELOAD来电?

如果重要,假设外部进程为mplayer,我的编程语言为C。我有一种预感,直接使用Xlib是我最好的选择,但请随意提出其他选择。只有mplayer的解决方案才足够。

1 个答案:

答案 0 :(得分:2)

如果你要嵌入的窗口know window id,你可以将它重新显示到你的窗口(使用XReparentWindow),即使它是由另一个进程创建的。

对于mplayer,有“-wid”命令行选项。如果您将窗口ID传递给它,mplayer会自动创建窗口作为wid的子窗口:

  

-wid(另见-gui-wid)(仅限X11,OpenGL和DirectX)

     

这告诉MPlayer附加到现有窗口。用于在浏览器中嵌入MPlayer(例如插件扩展)。此选项完全填充给定窗口,因此MPlayer不再处理纵横比缩放,panscan等,但必须由创建窗口的应用程序管理。

您可以通过传递'-slave'标志并将commands发送到stdin(或fifo)来控制mplayer

使用node-x11嵌入mplayer的示例:

var x11 = require('x11');
var spawn = require('child_process').spawn;
x11.createClient(function(err, display) {
    var X = display.client;
    var wid = X.AllocID();
    X.CreateWindow(wid, display.screen[0].root, 100, 100, 400, 300, 0, 0, 0, 0, {eventMask: x11.eventMask.SubstructureNotify|x11.eventMask.StructureNotify});
    X.MapWindow(wid);
    var mplayer = spawn('mplayer', ['-wid', wid, './video.mp4']);

    function pause() {
      mplayer.stdin.write('pause\n');
      setTimeout(play, 1000);
    }

    function play() {
      mplayer.stdin.write('play\n');
      setTimeout(pause, 1000);
    }

    pause();


    var mpid;
    X.on('event', function(ev) {
        console.log(ev);
        if (ev.name == 'CreateNotify')
            mpid = ev.wid;
        if (ev.name == 'ConfigureNotify' && ev.wid == wid) {
            X.ResizeWindow(mpid, ev.width, ev.height);
        }

    });
});