8#include <QtCore/QJsonDocument>
9#include <QtCore/QJsonObject>
10#include <QtCore/QJsonArray>
11#include <QtCore/QFile>
12#include <QtCore/QLoggingCategory>
16#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
37 for (
int i = 0;
i < connector->count_encoders;
i++) {
38 drmModeEncoderPtr encoder = drmModeGetEncoder(
m_dri_fd, connector->encoders[
i]);
44 quint32 encoderId = encoder->encoder_id;
45 quint32 crtcId = encoder->crtc_id;
46 quint32 possibleCrtcs = encoder->possible_crtcs;
47 drmModeFreeEncoder(encoder);
49 for (
int j = 0;
j < resources->count_crtcs;
j++) {
50 bool isPossible = possibleCrtcs & (1 <<
j);
55 bool isBestChoice = (!connector->encoder_id ||
56 (connector->encoder_id == encoderId &&
57 resources->crtcs[
j] == crtcId));
59 if (isPossible && isAvailable && isBestChoice) {
61 }
else if (isPossible && isAvailable) {
108 mode->type = DRM_MODE_TYPE_USERDEF;
114 if (sscanf(
text.
constData(),
"%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
123 &
mode->vtotal, hsync, vsync) != 11)
126 mode->clock = fclock * 1000;
128 if (strcmp(hsync,
"+hsync") == 0)
129 mode->flags |= DRM_MODE_FLAG_PHSYNC;
130 else if (strcmp(hsync,
"-hsync") == 0)
131 mode->flags |= DRM_MODE_FLAG_NHSYNC;
135 if (strcmp(vsync,
"+vsync") == 0)
136 mode->flags |= DRM_MODE_FLAG_PVSYNC;
137 else if (strcmp(vsync,
"-vsync") == 0)
138 mode->flags |= DRM_MODE_FLAG_NVSYNC;
148 output->eglfs_plane->activeCrtcId = 0;
151 output->eglfs_plane = plane;
155 drmModeConnectorPtr connector,
163 qWarning() <<
"No usable crtc/encoder pair for connector" << connectorName;
168 QSize configurationSize;
169 int configurationRefresh = 0;
170 drmModeModeInfo configurationModeline;
179 }
else if (
mode ==
"preferred") {
181 }
else if (
mode ==
"current") {
183 }
else if (
mode ==
"skip") {
185 }
else if (sscanf(
mode.constData(),
"%dx%d@%d", &configurationSize.
rwidth(), &configurationSize.
rheight(),
186 &configurationRefresh) == 3)
189 }
else if (sscanf(
mode.constData(),
"%dx%d", &configurationSize.
rwidth(), &configurationSize.
rheight()) == 2) {
203 if (vposComp.size() == 2)
209 const uint32_t crtc_id = resources->crtcs[crtc];
212 qCDebug(qLcKmsDebug) <<
"Turning off output" << connectorName;
213 drmModeSetCrtc(
m_dri_fd, crtc_id, 0, 0, 0, 0, 0,
nullptr);
219 qCDebug(qLcKmsDebug) <<
"Skipping disconnected output" << connectorName;
224 qCDebug(qLcKmsDebug) <<
"Skipping output" << connectorName;
229 drmModeModeInfo crtc_mode;
230 memset(&crtc_mode, 0,
sizeof crtc_mode);
231 if (drmModeEncoderPtr encoder = drmModeGetEncoder(
m_dri_fd, connector->encoder_id)) {
232 drmModeCrtcPtr crtc = drmModeGetCrtc(
m_dri_fd, encoder->crtc_id);
233 drmModeFreeEncoder(encoder);
238 if (crtc->mode_valid)
239 crtc_mode = crtc->mode;
241 drmModeFreeCrtc(crtc);
245 modes.
reserve(connector->count_modes);
246 qCDebug(qLcKmsDebug) << connectorName <<
"mode count:" << connector->count_modes
247 <<
"crtc index:" << crtc <<
"crtc id:" << crtc_id;
248 for (
int i = 0;
i < connector->count_modes;
i++) {
249 const drmModeModeInfo &
mode = connector->modes[
i];
250 qCDebug(qLcKmsDebug) <<
"mode" <<
i <<
mode.hdisplay <<
"x" <<
mode.vdisplay
251 <<
'@' <<
mode.vrefresh <<
"hz";
252 modes << connector->modes[
i];
260 for (
int i = modes.
size() - 1;
i >= 0;
i--) {
261 const drmModeModeInfo &
m = modes.
at(
i);
264 &&
m.hdisplay == configurationSize.
width()
265 &&
m.vdisplay == configurationSize.
height()
266 && (!configurationRefresh ||
m.vrefresh == uint32_t(configurationRefresh)))
271 if (!memcmp(&crtc_mode, &
m,
sizeof m))
274 if (
m.type & DRM_MODE_TYPE_PREFERRED)
281 modes << configurationModeline;
282 configured = modes.
size() - 1;
285 if (current < 0 && crtc_mode.clock != 0) {
287 current = modes.
size() - 1;
291 configured = current;
293 int selected_mode = -1;
296 selected_mode = configured;
297 else if (preferred >= 0)
298 selected_mode = preferred;
299 else if (current >= 0)
300 selected_mode = current;
302 selected_mode = best;
304 if (selected_mode < 0) {
305 qWarning() <<
"No modes available for output" << connectorName;
308 int width = modes[selected_mode].hdisplay;
309 int height = modes[selected_mode].vdisplay;
310 int refresh = modes[selected_mode].vrefresh;
311 qCDebug(qLcKmsDebug) <<
"Selected mode" << selected_mode <<
":" <<
width <<
"x" <<
height
312 <<
'@' << refresh <<
"hz for output" << connectorName;
322 QSizeF physSize(pwidth, pheight);
327 physSize.
setWidth(connector->mmWidth);
331 qCDebug(qLcKmsDebug) <<
"Physical size is" << physSize <<
"mm" <<
"for output" << connectorName;
336 bool drmFormatExplicit =
true;
338 drmFormat = DRM_FORMAT_XRGB8888;
339 drmFormatExplicit =
false;
340 }
else if (formatStr ==
"xrgb8888") {
341 drmFormat = DRM_FORMAT_XRGB8888;
342 }
else if (formatStr ==
"xbgr8888") {
343 drmFormat = DRM_FORMAT_XBGR8888;
344 }
else if (formatStr ==
"argb8888") {
345 drmFormat = DRM_FORMAT_ARGB8888;
346 }
else if (formatStr ==
"abgr8888") {
348 }
else if (formatStr ==
"rgb565") {
350 }
else if (formatStr ==
"bgr565") {
351 drmFormat = DRM_FORMAT_BGR565;
352 }
else if (formatStr ==
"xrgb2101010") {
353 drmFormat = DRM_FORMAT_XRGB2101010;
354 }
else if (formatStr ==
"xbgr2101010") {
355 drmFormat = DRM_FORMAT_XBGR2101010;
356 }
else if (formatStr ==
"argb2101010") {
357 drmFormat = DRM_FORMAT_ARGB2101010;
358 }
else if (formatStr ==
"abgr2101010") {
359 drmFormat = DRM_FORMAT_ABGR2101010;
362 drmFormat = DRM_FORMAT_XRGB8888;
363 drmFormatExplicit =
false;
365 qCDebug(qLcKmsDebug) <<
"Format is" <<
Qt::hex << drmFormat <<
Qt::dec <<
"requested_by_user =" << drmFormatExplicit
366 <<
"for output" << connectorName;
370 qCDebug(qLcKmsDebug) <<
"Output" << connectorName <<
" clones output " << cloneSource;
372 QSize framebufferSize;
373 bool framebufferSizeSet =
false;
377#if QT_CONFIG(drm_atomic)
379 framebufferSizeSet =
true;
381 if (!framebufferSizeSet)
382 qWarning(
"Setting framebuffer size is only available with DRM atomic API");
387 if (!framebufferSizeSet) {
388 framebufferSize.
setWidth(modes[selected_mode].hdisplay);
389 framebufferSize.
setHeight(modes[selected_mode].vdisplay);
392 qCDebug(qLcKmsDebug) <<
"Output" << connectorName <<
"framebuffer size is " << framebufferSize;
396 output.connector_id = connector->connector_id;
399 output.physical_size = physSize;
400 output.preferred_mode = preferred >= 0 ? preferred : selected_mode;
401 output.mode = selected_mode;
405 output.subpixel = connector->subpixel;
408 output.wants_forced_plane =
false;
409 output.forced_plane_id = 0;
410 output.forced_plane_set =
false;
411 output.drm_format = drmFormat;
412 output.drm_format_requested_by_user = drmFormatExplicit;
413 output.clone_source = cloneSource;
414 output.size = framebufferSize;
416#if QT_CONFIG(drm_atomic)
417 if (drmModeCreatePropertyBlob(
m_dri_fd, &modes[selected_mode],
sizeof(drmModeModeInfo),
418 &
output.mode_blob_id) != 0) {
419 qCDebug(qLcKmsDebug) <<
"Failed to create mode blob for mode" << selected_mode;
428 if (plane.possibleCrtcs & (1 <<
output.crtc_index)) {
429 output.available_planes.append(plane);
431 planeListStr.
append(u
' ');
439 qCDebug(qLcKmsDebug,
"Output %s can use %d planes: %s",
448 drmModePlaneRes *planeResources = drmModeGetPlaneResources(
m_dri_fd);
449 if (planeResources) {
450 if (idx >= 0 && idx <
int(planeResources->count_planes)) {
451 drmModePlane *plane = drmModeGetPlane(
m_dri_fd, planeResources->planes[idx]);
453 output.wants_forced_plane =
true;
454 output.forced_plane_id = plane->plane_id;
455 qCDebug(qLcKmsDebug,
"Forcing plane index %d, plane id %u (belongs to crtc id %u)",
456 idx, plane->plane_id, plane->crtc_id);
459 if (kmsplane.id ==
output.forced_plane_id) {
465 drmModeFreePlane(plane);
468 qWarning(
"Invalid plane index %d, must be between 0 and %u", idx, planeResources->count_planes - 1);
479 for (
const QString &crtcPlanePair : crtcPlanePairs) {
484 if (kmsplane.id == planeId) {
494 qCDebug(qLcKmsDebug,
"Chose plane %u for output %s (crtc id %u) (may not be applicable)",
498#if QT_CONFIG(drm_atomic)
500 qCDebug(qLcKmsDebug,
"No plane associated with output %s (crtc id %u) and atomic modesetting is enabled. This is bad.",
514 drmModePropertyPtr prop;
516 for (
int i = 0;
i < connector->count_props;
i++) {
517 prop = drmModeGetProperty(
m_dri_fd, connector->props[
i]);
520 if (strcmp(prop->name,
name.constData()) == 0)
522 drmModeFreeProperty(prop);
530 drmModePropertyPtr prop;
531 drmModePropertyBlobPtr blob =
nullptr;
533 for (
int i = 0;
i < connector->count_props && !blob;
i++) {
534 prop = drmModeGetProperty(
m_dri_fd, connector->props[
i]);
537 if ((prop->flags & DRM_MODE_PROP_BLOB) && (strcmp(prop->name,
name.constData()) == 0))
538 blob = drmModeGetPropertyBlob(
m_dri_fd, connector->prop_values[
i]);
539 drmModeFreeProperty(prop);
546 : m_screenConfig(screenConfig)
549 , m_has_atomic_support(
false)
550 , m_crtc_allocator(0)
556 qFatal(
"No DRM device given");
564#if QT_CONFIG(drm_atomic)
565 threadLocalAtomicReset();
581 dbg.nospace() <<
"OrderedScreen(QPlatformScreen=" <<
s.screen <<
" (" <<
s.screen->name() <<
") : "
582 <<
s.vinfo.virtualIndex
583 <<
" / " <<
s.vinfo.virtualPos
584 <<
" / primary: " <<
s.vinfo.isPrimary
591 return a.vinfo.virtualIndex <
b.vinfo.virtualIndex;
601 qCDebug(qLcKmsDebug,
"Headless mode enabled");
605 qWarning(
"QKmsDevice: Requested headless mode without support in the backend. Request is ignored.");
611#if QT_CONFIG(drm_atomic)
615 qCDebug(qLcKmsDebug,
"Atomic reported as supported");
617 qCDebug(qLcKmsDebug,
"Atomic enabled");
619 qCDebug(qLcKmsDebug,
"Atomic disabled");
625 drmModeResPtr resources = drmModeGetResources(
m_dri_fd);
635 int wantedConnectorIndex = -1;
639 if (idx >= 0 && idx < resources->count_connectors)
640 wantedConnectorIndex = idx;
642 qWarning(
"Invalid connector index %d, must be between 0 and %u", idx, resources->count_connectors - 1);
645 for (
int i = 0;
i < resources->count_connectors;
i++) {
646 if (wantedConnectorIndex >= 0 &&
i != wantedConnectorIndex)
649 drmModeConnectorPtr connector = drmModeGetConnector(
m_dri_fd, resources->connectors[
i]);
658 drmModeFreeConnector(connector);
661 drmModeFreeResources(resources);
666 qCDebug(qLcKmsDebug) <<
"Sorted screen list:" << screens;
673 if (
s.vinfo.output.clone_source == orderedScreen.vinfo.output.name)
674 screensCloningThisScreen.
append(
s.screen);
677 if (!orderedScreen.vinfo.output.clone_source.isEmpty()) {
679 if (
s.vinfo.output.name == orderedScreen.vinfo.output.clone_source) {
680 screenThisScreenClones =
s.
screen;
685 if (screenThisScreenClones)
686 qCDebug(qLcKmsDebug) << orderedScreen.screen->name() <<
"clones" << screenThisScreenClones;
687 if (!screensCloningThisScreen.
isEmpty())
688 qCDebug(qLcKmsDebug) << orderedScreen.screen->name() <<
"is cloned by" << screensCloningThisScreen;
697 int primarySiblingIdx = -1;
703 if (orderedScreen.vinfo.virtualPos.isNull()) {
706 pos.ry() +=
s->geometry().height();
708 pos.rx() +=
s->geometry().width();
710 virtualPos = orderedScreen.vinfo.virtualPos;
712 qCDebug(qLcKmsDebug) <<
"Adding QPlatformScreen" <<
s <<
"(" <<
s->name() <<
")"
713 <<
"to QPA with geometry" <<
s->geometry()
714 <<
"and isPrimary=" << orderedScreen.vinfo.isPrimary;
720 virtualPositions.
append(virtualPos);
721 if (orderedScreen.vinfo.isPrimary)
722 primarySiblingIdx = siblings.
size() - 1;
730 for (
int i = 0;
i < siblings.
size(); ++
i)
731 registerScreen(siblings[
i],
i == primarySiblingIdx, virtualPositions[
i], siblings);
756 return prop->flags &
type;
761 for (uint32_t propIdx = 0; propIdx < objProps->count_props; ++propIdx) {
762 drmModePropertyPtr prop = drmModeGetProperty(
m_dri_fd, objProps->props[propIdx]);
767 qCDebug(qLcKmsDebug,
" property %d: id = %u name = '%s'", propIdx, prop->prop_id, prop->name);
770 qCDebug(qLcKmsDebug,
" type is SIGNED_RANGE, value is %lld, possible values are:",
qint64(
value));
771 for (
int i = 0;
i < prop->count_values; ++
i)
773 }
else if (
propTypeIs(prop, DRM_MODE_PROP_RANGE)) {
774 qCDebug(qLcKmsDebug,
" type is RANGE, value is %llu, possible values are:",
value);
775 for (
int i = 0;
i < prop->count_values; ++
i)
777 }
else if (
propTypeIs(prop, DRM_MODE_PROP_ENUM)) {
778 qCDebug(qLcKmsDebug,
" type is ENUM, value is %llu, possible values are:",
value);
779 for (
int i = 0;
i < prop->count_enums; ++
i)
780 qCDebug(qLcKmsDebug,
" enum %d: %s - %llu",
i, prop->enums[
i].name,
quint64(prop->enums[
i].value));
781 }
else if (
propTypeIs(prop, DRM_MODE_PROP_BITMASK)) {
782 qCDebug(qLcKmsDebug,
" type is BITMASK, value is %llu, possible bits are:",
value);
783 for (
int i = 0;
i < prop->count_enums; ++
i)
784 qCDebug(qLcKmsDebug,
" bitmask %d: %s - %u",
i, prop->enums[
i].name, 1 << prop->enums[
i].value);
785 }
else if (
propTypeIs(prop, DRM_MODE_PROP_BLOB)) {
786 qCDebug(qLcKmsDebug,
" type is BLOB");
788 qCDebug(qLcKmsDebug,
" type is OBJECT");
791 callback(prop,
value);
793 drmModeFreeProperty(prop);
801 drmModePlaneResPtr planeResources = drmModeGetPlaneResources(
m_dri_fd);
805 const int countPlanes = planeResources->count_planes;
806 qCDebug(qLcKmsDebug,
"Found %d planes", countPlanes);
807 for (
int planeIdx = 0; planeIdx < countPlanes; ++planeIdx) {
808 drmModePlanePtr drmplane = drmModeGetPlane(
m_dri_fd, planeResources->planes[planeIdx]);
810 qCDebug(qLcKmsDebug,
"Failed to query plane %d, ignoring", planeIdx);
815 plane.
id = drmplane->plane_id;
818 const int countFormats = drmplane->count_formats;
820 for (
int i = 0;
i < countFormats; ++
i) {
821 uint32_t
f = drmplane->formats[
i];
826 qCDebug(qLcKmsDebug,
"plane %d: id = %u countFormats = %d possibleCrtcs = 0x%x supported formats = %s",
829 drmModeFreePlane(drmplane);
831 drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(
m_dri_fd, plane.
id, DRM_MODE_OBJECT_PLANE);
833 qCDebug(qLcKmsDebug,
"Failed to query plane %d object properties, ignoring", planeIdx);
838 if (!strcmp(prop->name,
"type")) {
839 plane.type = QKmsPlane::Type(value);
840 }
else if (!strcmp(prop->name,
"rotation")) {
841 plane.initialRotation = QKmsPlane::Rotations(int(value));
842 plane.availableRotations = { };
843 if (
propTypeIs(prop, DRM_MODE_PROP_BITMASK)) {
844 for (
int i = 0;
i < prop->count_enums; ++
i)
848 }
else if (!strcasecmp(prop->name,
"crtc_id")) {
850 }
else if (!strcasecmp(prop->name,
"fb_id")) {
852 }
else if (!strcasecmp(prop->name,
"src_w")) {
854 }
else if (!strcasecmp(prop->name,
"src_h")) {
856 }
else if (!strcasecmp(prop->name,
"crtc_w")) {
858 }
else if (!strcasecmp(prop->name,
"crtc_h")) {
860 }
else if (!strcasecmp(prop->name,
"src_x")) {
862 }
else if (!strcasecmp(prop->name,
"src_y")) {
864 }
else if (!strcasecmp(prop->name,
"crtc_x")) {
866 }
else if (!strcasecmp(prop->name,
"crtc_y")) {
868 }
else if (!strcasecmp(prop->name,
"zpos")) {
870 }
else if (!strcasecmp(prop->name,
"blend_op")) {
877 drmModeFreeObjectProperties(objProps);
880 drmModeFreePlaneResources(planeResources);
904#if QT_CONFIG(drm_atomic)
905drmModeAtomicReq *QKmsDevice::threadLocalAtomicRequest()
910 AtomicReqs &
a(m_atomicReqs.localData());
912 a.request = drmModeAtomicAlloc();
917bool QKmsDevice::threadLocalAtomicCommit(
void *
user_data)
922 AtomicReqs &
a(m_atomicReqs.localData());
927 DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_ALLOW_MODESET,
931 qWarning(
"Failed to commit atomic request (code=%d)",
ret);
935 a.previous_request =
a.request;
941void QKmsDevice::threadLocalAtomicReset()
946 AtomicReqs &
a(m_atomicReqs.localData());
947 if (
a.previous_request) {
948 drmModeAtomicFree(
a.previous_request);
949 a.previous_request =
nullptr;
956 drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(
m_dri_fd, connectorId, DRM_MODE_OBJECT_CONNECTOR);
958 qCDebug(qLcKmsDebug,
"Failed to query connector %d object properties", connectorId);
964 if (!strcasecmp(prop->name,
"crtc_id"))
965 output->crtcIdPropertyId = prop->prop_id;
968 drmModeFreeObjectProperties(objProps);
973 drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(
m_dri_fd, crtcId, DRM_MODE_OBJECT_CRTC);
975 qCDebug(qLcKmsDebug,
"Failed to query crtc %d object properties", crtcId);
981 if (!strcasecmp(prop->name,
"mode_id"))
982 output->modeIdPropertyId = prop->prop_id;
983 else if (!strcasecmp(prop->name,
"active"))
984 output->activePropertyId = prop->prop_id;
987 drmModeFreeObjectProperties(objProps);
998 , m_separateScreens(
false)
1000 , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal)
1008 json =
qgetenv(
"QT_QPA_KMS_CONFIG");
1013 qCDebug(qLcKmsDebug) <<
"Loading KMS setup from" << json;
1017 qCWarning(qLcKmsDebug) <<
"Could not open config file"
1018 << json <<
"for reading";
1024 qCWarning(qLcKmsDebug) <<
"Invalid config file" << json
1025 <<
"- no top-level JSON object";
1031 const QString headlessStr =
object.value(
"headless"_L1).toString();
1046 const QString vdOriString =
object.value(
"virtualDesktopLayout"_L1).toString();
1048 if (vdOriString ==
"horizontal"_L1)
1050 else if (vdOriString ==
"vertical"_L1)
1053 qCWarning(qLcKmsDebug) <<
"Unknown virtualDesktopOrientation value" << vdOriString;
1056 const QJsonArray outputs =
object.value(
"outputs"_L1).toArray();
1057 for (
int i = 0;
i < outputs.
size();
i++) {
1064 qCDebug(qLcKmsDebug) <<
"Output" <<
name <<
"configured multiple times!";
1071 qCDebug(qLcKmsDebug) <<
"Requested configuration (some settings may be ignored):\n"
1083 drmModeSetCrtc(
device->fd(),
1117 case DRM_MODE_SUBPIXEL_UNKNOWN:
1118 case DRM_MODE_SUBPIXEL_NONE:
1120 case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
1122 case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
1124 case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
1126 case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
IOBluetoothDevice * device
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
QByteArray toLower() const &
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
\inmodule QtCore\reentrant
qsizetype size() const
Returns the number of values stored in the array.
QJsonValue at(qsizetype i) const
Returns a QJsonValue representing the value for index i.
\inmodule QtCore\reentrant
QJsonObject object() const
Returns the QJsonObject contained in the document.
bool isObject() const
Returns true if the document contains an object.
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
Parses json as a UTF-8 encoded JSON document, and creates a QJsonDocument from it.
\inmodule QtCore\reentrant
QVariantMap toVariantMap() const
Converts this object to a QVariantMap.
QJsonObject toObject() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void enumerateProperties(drmModeObjectPropertiesPtr objProps, PropCallback callback)
QList< QKmsPlane > m_planes
drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name)
void parseCrtcProperties(uint32_t crtcId, QKmsOutput *output)
QKmsScreenConfig * screenConfig() const
virtual QPlatformScreen * createHeadlessScreen()
QKmsScreenConfig * m_screenConfig
virtual QPlatformScreen * createScreen(const QKmsOutput &output)=0
int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector)
std::function< void(drmModePropertyPtr, quint64)> PropCallback
void parseConnectorProperties(uint32_t connectorId, QKmsOutput *output)
QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path=QString())
QString devicePath() const
QPlatformScreen * createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, ScreenInfo *vinfo)
virtual void registerScreen(QPlatformScreen *screen, bool isPrimary, const QPoint &virtualPos, const QList< QPlatformScreen * > &virtualSiblings)=0
bool m_has_atomic_support
drmModePropertyBlobPtr connectorPropertyBlob(drmModeConnectorPtr connector, const QByteArray &name)
virtual void registerScreenCloning(QPlatformScreen *screen, QPlatformScreen *screenThisScreenClones, const QList< QPlatformScreen * > &screensCloningThisScreen)
QSize headlessSize() const
QMap< QString, QVariantMap > m_outputSettings
bool separateScreens() const
VirtualDesktopLayout virtualDesktopLayout() const
virtual void loadConfig()
@ VirtualDesktopLayoutVertical
@ VirtualDesktopLayoutHorizontal
VirtualDesktopLayout m_virtualDesktopLayout
QMap< QString, QVariantMap > outputSettings() const
QString devicePath() const
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
T value(const Key &key, const T &defaultValue=T()) const
bool contains(const Key &key) const
\inmodule QtCore\reentrant
constexpr void setHeight(qreal h) noexcept
Sets the height to the given finite height.
constexpr void setWidth(qreal w) noexcept
Sets the width to the given finite width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr int & rheight() noexcept
Returns a reference to the height.
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
constexpr int & rwidth() noexcept
Returns a reference to the width.
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
\macro QT_RESTRICTED_CAST_FROM_ASCII
const QChar * constData() const
Returns a pointer to the data stored in the QString.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString & append(QChar c)
QByteArray toUtf8() const &
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
QTextStream & dec(QTextStream &stream)
Calls QTextStream::setIntegerBase(10) on stream and returns stream.
#define QByteArrayLiteral(str)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void * user_data
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define DRM_FORMAT_RGB565
#define DRM_FORMAT_ABGR8888
static const char *const connector_type_names[]
static void assignPlane(QKmsOutput *output, QKmsPlane *plane)
static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b)
static bool propTypeIs(drmModePropertyPtr prop, uint32_t type)
static QByteArray nameForConnector(const drmModeConnectorPtr connector)
QDebug operator<<(QDebug dbg, const OrderedScreen &s)
static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode)
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES
#define DRM_CLIENT_CAP_ATOMIC
#define DRM_MODE_PROP_SIGNED_RANGE
#define DRM_MODE_PROP_EXTENDED_TYPE
#define DRM_MODE_PROP_OBJECT
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLsizei const GLchar *const * path
#define qPrintable(string)
#define QStringLiteral(str)
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
unsigned long long quint64
static int toInt(const QChar &qc, int R)
QT_BEGIN_NAMESPACE typedef uchar * output
if(qFloatDistance(a, b)<(1<< 7))
[0]
QKmsDevice::ScreenInfo vinfo
OrderedScreen(QPlatformScreen *screen, const QKmsDevice::ScreenInfo &vinfo)
void restoreMode(QKmsDevice *device)
drmModePropertyPtr dpms_prop
void setPowerState(QKmsDevice *device, QPlatformScreen::PowerState state)
drmModeCrtcPtr saved_crtc
drmModePropertyBlobPtr edid_blob
QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const
void cleanup(QKmsDevice *device)
uint32_t srcheightPropertyId
uint32_t framebufferPropertyId
uint32_t crtcwidthPropertyId
uint32_t rotationPropertyId
QList< uint32_t > supportedFormats
uint32_t crtcheightPropertyId
uint32_t srcwidthPropertyId
uint32_t blendOpPropertyId
Rotations availableRotations
QT_BEGIN_NAMESPACE bool toBool(const QString &str)