File indexing completed on 2024-04-28 16:49:42

0001 /*
0002  * SPDX-FileCopyrightText: 2015 Daniel Vrátil <dvratil@redhat.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  *
0006  */
0007 #include "xrandrcrtc.h"
0008 
0009 #include "xrandr.h"
0010 #include "xrandrconfig.h"
0011 
0012 #include "../xcbwrapper.h"
0013 
0014 XRandRCrtc::XRandRCrtc(xcb_randr_crtc_t crtc, XRandRConfig *config)
0015     : QObject(config)
0016     , m_crtc(crtc)
0017     , m_mode(0)
0018     , m_rotation(XCB_RANDR_ROTATION_ROTATE_0)
0019     , m_timestamp(XCB_CURRENT_TIME)
0020     , m_configTimestamp(XCB_CURRENT_TIME)
0021 {
0022     update();
0023 }
0024 
0025 xcb_randr_crtc_t XRandRCrtc::crtc() const
0026 {
0027     return m_crtc;
0028 }
0029 
0030 xcb_randr_mode_t XRandRCrtc::mode() const
0031 {
0032     return m_mode;
0033 }
0034 
0035 QRect XRandRCrtc::geometry() const
0036 {
0037     return m_geometry;
0038 }
0039 
0040 xcb_randr_rotation_t XRandRCrtc::rotation() const
0041 {
0042     return m_rotation;
0043 }
0044 
0045 QVector<xcb_randr_output_t> XRandRCrtc::possibleOutputs()
0046 {
0047     return m_possibleOutputs;
0048 }
0049 
0050 QVector<xcb_randr_output_t> XRandRCrtc::outputs() const
0051 {
0052     return m_outputs;
0053 }
0054 
0055 bool XRandRCrtc::connectOutput(xcb_randr_output_t output)
0056 {
0057     update();
0058     qCDebug(KSCREEN_XRANDR) << "Connected output" << output << "to CRTC" << m_crtc;
0059 
0060     if (!m_possibleOutputs.contains(output)) {
0061         qCDebug(KSCREEN_XRANDR) << "Output" << output << "is not an allowed output for CRTC" << m_crtc;
0062         return false;
0063     }
0064 
0065     if (!m_outputs.contains(output)) {
0066         m_outputs.append(output);
0067     }
0068     return true;
0069 }
0070 
0071 void XRandRCrtc::disconectOutput(xcb_randr_output_t output)
0072 {
0073     update();
0074     qCDebug(KSCREEN_XRANDR) << "Disconnected output" << output << "from CRTC" << m_crtc;
0075 
0076     const int index = m_outputs.indexOf(output);
0077     if (index > -1) {
0078         m_outputs.remove(index);
0079     }
0080 }
0081 
0082 bool XRandRCrtc::isFree() const
0083 {
0084     return m_outputs.isEmpty();
0085 }
0086 
0087 void XRandRCrtc::update()
0088 {
0089     XCB::CRTCInfo crtcInfo(m_crtc, XCB_TIME_CURRENT_TIME);
0090     m_mode = crtcInfo->mode;
0091 
0092     m_geometry = QRect(crtcInfo->x, crtcInfo->y, crtcInfo->width, crtcInfo->height);
0093     m_rotation = (xcb_randr_rotation_t)crtcInfo->rotation;
0094 
0095     m_possibleOutputs.clear();
0096     m_possibleOutputs.reserve(crtcInfo->num_possible_outputs);
0097 
0098     xcb_randr_output_t *possible = xcb_randr_get_crtc_info_possible(crtcInfo);
0099     for (int i = 0; i < crtcInfo->num_possible_outputs; ++i) {
0100         m_possibleOutputs.append(possible[i]);
0101     }
0102 
0103     m_outputs.clear();
0104     xcb_randr_output_t *outputs = xcb_randr_get_crtc_info_outputs(crtcInfo);
0105     for (int i = 0; i < crtcInfo->num_outputs; ++i) {
0106         m_outputs.append(outputs[i]);
0107     }
0108 }
0109 
0110 void XRandRCrtc::update(xcb_randr_mode_t mode, xcb_randr_rotation_t rotation, const QRect &geom)
0111 {
0112     m_mode = mode;
0113     m_geometry = geom;
0114     m_rotation = rotation;
0115 }
0116 
0117 void XRandRCrtc::updateTimestamp(const xcb_timestamp_t tmstamp)
0118 {
0119     if (tmstamp > m_timestamp) {
0120         qCDebug(KSCREEN_XRANDR) << "XRandRCrtc " << m_crtc << " m_timestamp update " << m_timestamp << " => " << tmstamp;
0121         m_timestamp = tmstamp;
0122     }
0123 }
0124 
0125 void XRandRCrtc::updateConfigTimestamp(const xcb_timestamp_t tmstamp)
0126 {
0127     if (tmstamp > m_configTimestamp) {
0128         qCDebug(KSCREEN_XRANDR) << "XRandRCrtc " << m_crtc << " m_configTimestamp update" << m_configTimestamp << " => " << tmstamp;
0129         m_configTimestamp = tmstamp;
0130     }
0131 }
0132 
0133 bool XRandRCrtc::isChangedFromOutside() const
0134 {
0135     return m_configTimestamp > m_timestamp;
0136 }