2019-06-13 09:27:01 +00:00
|
|
|
/********************************************************************
|
|
|
|
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)
|
2019-06-13 09:36:07 +00:00
|
|
|
: AbstractWaylandOutput(backend)
|
2019-06-13 09:27:01 +00:00
|
|
|
, 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());
|
|
|
|
}
|
|
|
|
|
2019-08-27 10:31:42 +00:00
|
|
|
void X11WindowedOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
|
2019-06-13 09:27:01 +00:00
|
|
|
{
|
2019-08-27 10:31:42 +00:00
|
|
|
KWayland::Server::OutputDeviceInterface::Mode mode;
|
|
|
|
mode.id = 0;
|
|
|
|
mode.size = pixelSize;
|
|
|
|
mode.flags = KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
|
|
|
|
mode.refreshRate = 60000; // TODO: get refresh rate via randr
|
2019-08-27 14:52:39 +00:00
|
|
|
|
|
|
|
// Physicial size must be adjusted, such that QPA calculates correct sizes of
|
|
|
|
// internal elements.
|
|
|
|
const QSize physicalSize = pixelSize / 96.0 * 25.4 / scale();
|
2019-08-27 10:31:42 +00:00
|
|
|
AbstractWaylandOutput::initWaylandOutputDevice("model_TODO", "manufacturer_TODO",
|
2019-08-27 14:52:39 +00:00
|
|
|
"UUID_TODO", physicalSize, { mode });
|
2019-08-27 10:31:42 +00:00
|
|
|
|
|
|
|
setEnabled(true);
|
|
|
|
setGeometry(logicalPosition, pixelSize);
|
|
|
|
setScale(m_backend->initialOutputScale());
|
|
|
|
|
2019-06-13 09:27:01 +00:00
|
|
|
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,
|
2019-08-27 10:31:42 +00:00
|
|
|
pixelSize.width(), pixelSize.height(),
|
2019-06-13 09:27:01 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
void X11WindowedOutput::setGeometry(const QPoint &logicalPosition, const QSize &pixelSize)
|
|
|
|
{
|
2019-08-27 14:19:47 +00:00
|
|
|
// TODO: set mode to have updated pixelSize
|
2019-08-28 16:10:24 +00:00
|
|
|
Q_UNUSED(pixelSize);
|
2019-06-13 09:27:01 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|