[kwin_wayland] Start Xwayland through socket file descriptor

Creates a socketpair in WaylandServer and creates a ClientConnection for
Xwayland. The created file descriptor is passed to Xwayland through the
WAYLAND_SOCKET env variable.
This commit is contained in:
Martin Gräßlin 2015-02-25 14:15:32 +01:00
parent 9dcd123438
commit 69a13a779d
3 changed files with 40 additions and 4 deletions

View file

@ -56,7 +56,7 @@ static void sighandler(int)
QApplication::exit();
}
static int startXServer(const QByteArray &waylandSocket, int wmFd);
static int startXServer(int waylandSocket, int wmFd);
static void readDisplay(int pipe);
//************************************
@ -115,8 +115,15 @@ void ApplicationWayland::continueStartupWithScreens()
return;
}
const int fd = waylandServer()->createXWaylandConnection();
if (fd == -1) {
std::cerr << "FATAL ERROR: failed to open socket for Xwayland" << std::endl;
exit(1);
return;
}
m_xcbConnectionFd = sx[0];
const int xDisplayPipe = startXServer(WaylandServer::self()->display()->socketName().toUtf8(), sx[1]);
const int xDisplayPipe = startXServer(fd, sx[1]);
QFutureWatcher<void> *watcher = new QFutureWatcher<void>(this);
QObject::connect(watcher, &QFutureWatcher<void>::finished, this, &ApplicationWayland::continueStartupWithX, Qt::QueuedConnection);
QObject::connect(watcher, &QFutureWatcher<void>::finished, watcher, &QFutureWatcher<void>::deleteLater, Qt::QueuedConnection);
@ -214,7 +221,7 @@ void ApplicationWayland::createX11Connection()
* Starts the Xwayland-Server.
* The new process is started by forking into it.
**/
static int startXServer(const QByteArray &waylandSocket, int wmFd)
static int startXServer(int waylandSocket, int wmFd)
{
int pipeFds[2];
if (pipe(pipeFds) != 0) {
@ -237,7 +244,14 @@ static int startXServer(const QByteArray &waylandSocket, int wmFd)
return -1;
}
sprintf(wmfdbuf, "%d", fd);
qputenv("WAYLAND_DISPLAY", waylandSocket.isEmpty() ? QByteArrayLiteral("wayland-0") : waylandSocket);
int wlfd = dup(waylandSocket);
if (wlfd < 0) {
std::cerr << "FATAL ERROR: failed to open socket for Xwayland" << std::endl;
exit(20);
return -1;
}
qputenv("WAYLAND_SOCKET", QByteArray::number(wlfd));
execlp("Xwayland", "Xwayland", "-displayfd", fdbuf, "-rootless", "-wm", wmfdbuf, (char *)0);
close(pipeFds[1]);
exit(20);

View file

@ -28,6 +28,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Server/seat_interface.h>
#include <KWayland/Server/shell_interface.h>
// system
#include <sys/types.h>
#include <sys/socket.h>
using namespace KWayland::Server;
namespace KWin
@ -87,4 +91,15 @@ void WaylandServer::initOutputs()
}
}
int WaylandServer::createXWaylandConnection()
{
int sx[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sx) < 0) {
qCWarning(KWIN_CORE) << "Could not create socket";
return -1;
}
m_xwaylandConnection = m_display->createClient(sx[0]);
return sx[1];
}
}

View file

@ -28,6 +28,7 @@ namespace KWayland
{
namespace Server
{
class ClientConnection;
class CompositorInterface;
class Display;
class ShellInterface;
@ -60,11 +61,17 @@ public:
return m_shell;
}
/**
* @returns file descriptor for Xwayland to connect to.
**/
int createXWaylandConnection();
private:
KWayland::Server::Display *m_display = nullptr;
KWayland::Server::CompositorInterface *m_compositor = nullptr;
KWayland::Server::SeatInterface *m_seat = nullptr;
KWayland::Server::ShellInterface *m_shell = nullptr;
KWayland::Server::ClientConnection *m_xwaylandConnection = nullptr;
KWIN_SINGLETON(WaylandServer)
};