2#include "libmythbase/mythconfig.h"
9#include <xf86drmMode.h>
12#ifndef DRM_MODE_FLAG_INTERLACE
13#define DRM_MODE_FLAG_INTERLACE (1<<4)
17#define LOC QString("MutterDisp: ")
57 Argument.beginStructure();
59 Argument.endStructure();
65 Argument.beginArray(qMetaTypeId<MythMutterOutputOut>());
66 for (
const auto &
output : Outputs)
74 Argument.beginStructure();
76 Argument.endStructure();
82 Argument.beginStructure();
84 Argument.endStructure();
90 Argument.beginStructure();
92 Argument.endStructure();
98 Argument.beginArray(qMetaTypeId<MythMutterCRTCOut>());
99 for (
const auto & crtc : CRTCS)
107 Argument.beginStructure();
108 Argument >> CRTC.
id >> CRTC.
sys_id >> CRTC.
x >> CRTC.
y;
111 Argument.endStructure();
117 Argument.beginArray();
120 while (!Argument.atEnd())
133 Argument.beginStructure();
137 Argument.endStructure();
139 Output.
edid = QByteArray();
144 if (property.first ==
"serial")
145 Output.
serialnumber =
property.second.variant().toString();
146 if (property.first ==
"edid")
147 Output.
edid =
property.second.variant().toByteArray();
148 if (property.first ==
"width-mm")
149 Output.
widthmm =
property.second.variant().toInt();
150 if (property.first ==
"height-mm")
151 Output.
heightmm =
property.second.variant().toInt();
158 Argument.beginArray();
161 while (!Argument.atEnd())
174 Argument.beginStructure();
176 Argument >>
Mode.frequency >>
Mode.flags;
177 Argument.endStructure();
183 Argument.beginArray();
186 while (!Argument.atEnd())
206 static bool s_checked(
false);
207 static bool s_available(
false);
212 qDBusRegisterMetaType<MythMutterCRTCOut>();
213 qDBusRegisterMetaType<MythMutterOutputOut>();
217 if (mutter.isValid())
223 QDBusMessage res = mutter.call(
"GetResources");
224 QList<QVariant>
args = res.arguments();
227 uint serial =
args[0].toUInt() + 100;
230 QDBusArgument crtcsarg;
231 QDBusArgument outarg;
232 QDBusReply<void> reply = mutter.call(QLatin1String(
"ApplyConfiguration"),
234 QVariant::fromValue(crtcsarg << crtcs),
235 QVariant::fromValue(outarg << outputs));
236 if (reply.error().type() == QDBusError::UnknownMethod)
238 LOG(VB_GENERAL, LOG_WARNING,
LOC +
239 "org.gnome.Mutter.DisplayConfig.ApplyConfiguration not implemented");
241 else if (reply.error().type() == QDBusError::AccessDenied)
260 if (result->IsValid())
301 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Monitors changed");
323 for (
auto & mode :
output.modes)
333 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Ignoring interlaced mode %1x%2 %3i")
339 QSize resolution(
static_cast<int32_t
>(mmode.
width),
340 static_cast<int32_t
>(mmode.
height));
343 if (screenmap.find(key) == screenmap.end())
346 screenmap[key].AddRefreshRate(rate);
350 for (
auto & it : screenmap)
376 QDBusMessage reply =
m_interface->call(
"GetResources");
380 QList<QVariant>
args = reply.arguments();
381 if (
args.size() == 6)
387 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to register for MonitorsChanged");
391 LOG(VB_GENERAL, LOG_ERR,
LOC +
"GetResources unexpected reply");
395 LOG(VB_GENERAL, LOG_ERR,
LOC +
"GetResources signature not recognised");
409 auto rate =
static_cast<double>(NAN);
416 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Desired resolution and frame rate not found.");
423 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to find mode");
431 if ((crtc.currentmode < 0) || (crtc.width < 1) || (crtc.height < 1))
435 crtcout.
id = crtc.id;
436 crtcout.
new_mode = crtc.currentmode;
439 crtcout.
transform = crtc.currenttransform;
440 crtcout.
outputs = QList<uint32_t>();
442 crtcs.append(crtcout);
446 QDBusArgument crtcsarg;
447 QDBusArgument outarg;
448 QDBusReply<void> reply =
m_interface->call(QLatin1String(
"ApplyConfiguration"),
450 QVariant::fromValue(crtcsarg << crtcs),
451 QVariant::fromValue(outarg << outputs));
452 if (!reply.isValid())
454 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Error applying new display configuration ('%1: %2')")
455 .arg(reply.error().type()).arg(reply.error().message()));
461 QDBusMessage resources =
m_interface->call(
"GetResources");
462 QList<QVariant>
args = resources.arguments();
465 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Failed to get updated DisplayConfig serial"
466 " - further display changes may fail");
488 QDBusMessage reply =
m_interface->call(
"GetResources");
489 QList<QVariant>
args = reply.arguments();
498 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"CRTC %1/%2: %3x%4+%5+%6 Mode: %7")
499 .arg(crtc.id).arg(crtc.sys_id).arg(crtc.width)
500 .arg(crtc.height).arg(crtc.x).arg(crtc.y).arg(crtc.currentmode));
506 QStringList possiblecrtcs;
507 for (
auto poss : std::as_const(
output.possible_crtcs))
508 possiblecrtcs.append(QString::number(poss));
510 for (
auto mode : std::as_const(
output.modes))
511 modes.append(QString::number(mode));
513 for (
const auto& prop : std::as_const(
output.properties))
514 props.append(QString(
"%1:%2").arg(prop.first, prop.second.variant().toString()));
515 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
516 QString(
"Output %1/%2: CRTC: %3 Possible CRTCs: %4 Name: '%5'")
518 .arg(possiblecrtcs.join(
","),
output.name));
519 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
520 QString(
"Output %1/%2: Modes: %3")
521 .arg(
output.id).arg(
output.sys_id).arg(modes.join(
",")));
522 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
523 QString(
"Output %1/%2: Properties: %3")
524 .arg(
output.id).arg(
output.sys_id).arg(props.join(
",")));
530 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
531 QString(
"Mode %1/%2: %3x%4@%5 Flags: 0x%6")
532 .arg(mode.id).arg(mode.sys_id).arg(mode.width)
533 .arg(mode.height).arg(mode.frequency).arg(mode.flags, 0, 16));
538 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"No connected outputs");
551 auto serial =
m_screen->serialNumber();
552 if (serial.isEmpty())
554 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No serial number to search for - using first output");
563 if (
output.serialnumber == serial)
565 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Matched serial '%1' to device '%2'")
566 .arg(serial,
output.name));
575 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Failed to match display serial - using first device");
587 static_cast<int>(
m_modes[mode].height));
bool GetBoolSetting(const QString &key, bool defaultval=false)
static int FindBestMatch(const MythDisplayModes &Modes, const MythDisplayMode &Mode, double &TargetRate)
static uint64_t CalcKey(QSize Size, double Rate)
A subclass of MythDisplay using the org.gnome.Mutter.DisplayConfig DBUS interface.
void UpdateCurrentMode() override
Retrieve screen details.
const MythDisplayModes & GetVideoModes(void) override
~MythDisplayMutter() override
QMap< uint64_t, uint32_t > m_modeMap
bool UsingVideoModes() override
MythMutterCRTCList m_crtcs
MythMutterOutputList m_outputs
void InitialiseInterface()
bool SwitchToVideoMode(QSize Size, double DesiredRate) override
static MythDisplayMutter * Create()
Create a valid instance.
MythMutterModeList m_modes
QDBusInterface * m_interface
virtual void UpdateCurrentMode()
Retrieve screen details.
MythDisplayModes m_videoModes
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
std::map< uint64_t, MythDisplayMode > DisplayModeMap
std::vector< MythDisplayMode > MythDisplayModes
static QDBusArgument & operator<<(QDBusArgument &Argument, const MythMutterOutputOut &Output)
QList< MythMutterOutputOut > MythMutterOutputOutList
static const QDBusArgument & operator>>(const QDBusArgument &Argument, MythMutterOutputOut &Output)
Q_DECLARE_METATYPE(MythMutterCRTCOut)
#define DRM_MODE_FLAG_INTERLACE
QList< MythMutterCRTCOut > MythMutterCRTCOutList
QList< MythMutterCRTC > MythMutterCRTCList
QList< MythMutterOutput > MythMutterOutputList
QMap< QString, QDBusVariant > MythMutterMap
#define DISP_CONFIG_SERVICE
QList< MythMutterMode > MythMutterModeList
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QList< uint32_t > outputs
MythMutterProperties properties
QList< uint32_t > transforms
uint32_t currenttransform
MythMutterProperties properties
QList< uint32_t > possible_crtcs