kwin/plugins/platforms/x11/windowed/x11windowed_output.cpp
Roman Gilg 1a11abc821 [platforms/x11/standalone] Port to AbstractOutput
Summary:
Represent outputs in the X11 session via AbstractOutput. For that we
move all Wayland specific parts of AbstractOutput into a new subclass
AbstractWaylandOutput and let the outputs of our Wayland backends inherit
from there.

This should allow us to get rid of the Screens class later on.

Test Plan: Manually in X session.

Reviewers: #kwin, zzag, davidedmundson

Reviewed By: #kwin, zzag, davidedmundson

Subscribers: ngraham, zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D19208
2019-06-13 11:39:25 +02:00

156 lines
4.5 KiB
C++

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright 2019 Roman Gilg <subdiff@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "x11windowed_output.h"
#include "x11windowed_backend.h"
#include <NETWM>
#if HAVE_X11_XINPUT
#include <X11/extensions/XInput2.h>
#endif
#include <QIcon>
namespace KWin
{
X11WindowedOutput::X11WindowedOutput(X11WindowedBackend *backend)
: AbstractWaylandOutput(backend)
, m_backend(backend)
{
m_window = xcb_generate_id(m_backend->connection());
}
X11WindowedOutput::~X11WindowedOutput()
{
xcb_unmap_window(m_backend->connection(), m_window);
xcb_destroy_window(m_backend->connection(), m_window);
delete m_winInfo;
xcb_flush(m_backend->connection());
}
void X11WindowedOutput::init()
{
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
const uint32_t values[] = {
m_backend->screen()->black_pixel,
XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_POINTER_MOTION |
XCB_EVENT_MASK_ENTER_WINDOW |
XCB_EVENT_MASK_LEAVE_WINDOW |
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XCB_EVENT_MASK_EXPOSURE
};
xcb_create_window(m_backend->connection(),
XCB_COPY_FROM_PARENT,
m_window,
m_backend->screen()->root,
0, 0,
pixelSize().width(), pixelSize().height(),
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT,
mask, values);
// select xinput 2 events
initXInputForWindow();
m_winInfo = new NETWinInfo(m_backend->connection(),
m_window,
m_backend->screen()->root,
NET::WMWindowType, NET::Properties2());
m_winInfo->setWindowType(NET::Normal);
m_winInfo->setPid(QCoreApplication::applicationPid());
QIcon windowIcon = QIcon::fromTheme(QStringLiteral("kwin"));
auto addIcon = [&windowIcon, this] (const QSize &size) {
if (windowIcon.actualSize(size) != size) {
return;
}
NETIcon icon;
icon.data = windowIcon.pixmap(size).toImage().bits();
icon.size.width = size.width();
icon.size.height = size.height();
m_winInfo->setIcon(icon, false);
};
addIcon(QSize(16, 16));
addIcon(QSize(32, 32));
addIcon(QSize(48, 48));
xcb_map_window(m_backend->connection(), m_window);
}
void X11WindowedOutput::initXInputForWindow()
{
if (!m_backend->hasXInput()) {
return;
}
#if HAVE_X11_XINPUT
XIEventMask evmasks[1];
unsigned char mask1[XIMaskLen(XI_LASTEVENT)];
memset(mask1, 0, sizeof(mask1));
XISetMask(mask1, XI_TouchBegin);
XISetMask(mask1, XI_TouchUpdate);
XISetMask(mask1, XI_TouchOwnership);
XISetMask(mask1, XI_TouchEnd);
evmasks[0].deviceid = XIAllMasterDevices;
evmasks[0].mask_len = sizeof(mask1);
evmasks[0].mask = mask1;
XISelectEvents(m_backend->display(), m_window, evmasks, 1);
#else
Q_UNUSED(window)
#endif
}
QSize X11WindowedOutput::pixelSize() const
{
return m_pixelSize;
}
void X11WindowedOutput::setGeometry(const QPoint &logicalPosition, const QSize &pixelSize)
{
m_pixelSize = pixelSize;
// Physicial size must be adjusted, such that QPA calculates correct sizes of
// internal elements.
setRawPhysicalSize(pixelSize / 96.0 * 25.4 / scale());
setGlobalPos(logicalPosition);
}
void X11WindowedOutput::setWindowTitle(const QString &title)
{
m_winInfo->setName(title.toUtf8().constData());
}
QPoint X11WindowedOutput::internalPosition() const
{
return geometry().topLeft();
}
void X11WindowedOutput::setHostPosition(const QPoint &pos)
{
m_hostPosition = pos;
}
}