diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index 7418655..2f1f4ae 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -227,7 +227,7 @@ namespace Aquamarine { class IDRMImplementation { public: virtual bool commit(Hyprutils::Memory::CSharedPointer connector, const SDRMConnectorCommitData& data) = 0; - virtual bool reset(Hyprutils::Memory::CSharedPointer connector) = 0; + virtual bool reset(Hyprutils::Memory::CSharedPointer connector) = 0; }; class CDRMBackend : public IBackendImplementation { @@ -265,6 +265,7 @@ namespace Aquamarine { Hyprutils::Memory::CSharedPointer gpu; Hyprutils::Memory::CSharedPointer impl; Hyprutils::Memory::CWeakPointer primary; + std::string gpuName; Hyprutils::Memory::CWeakPointer backend; @@ -281,6 +282,8 @@ namespace Aquamarine { struct { Hyprutils::Signal::CHyprSignalListener sessionActivate; + Hyprutils::Signal::CHyprSignalListener gpuChange; + Hyprutils::Signal::CHyprSignalListener gpuRemove; } listeners; friend class CBackend; diff --git a/src/backend/Session.cpp b/src/backend/Session.cpp index 69239bd..cea677c 100644 --- a/src/backend/Session.cpp +++ b/src/backend/Session.cpp @@ -208,11 +208,34 @@ void Aquamarine::CSession::dispatchUdevEvents() { if (action == std::string{"change"}) { backend->log(AQ_LOG_DEBUG, std::format("udev: DRM device {} changed", sysname ? sysname : "unknown")); - backend->log(AQ_LOG_ERROR, "udev: FIXME: change event is a STUB"); + + CSessionDevice::SChangeEvent event; + + auto prop = udev_device_get_property_value(device, "HOTPLUG"); + if (prop && prop == std::string{"1"}) { + event.type = CSessionDevice::AQ_SESSION_EVENT_CHANGE_HOTPLUG; + + prop = udev_device_get_property_value(device, "CONNECTOR"); + if (prop) + event.hotplug.connectorID = std::stoull(prop); + + prop = udev_device_get_property_value(device, "PROPERTY"); + if (prop) + event.hotplug.propID = std::stoull(prop); + } else if (prop = udev_device_get_property_value(device, "LEASE"); prop && prop == std::string{"1"}) { + event.type = CSessionDevice::AQ_SESSION_EVENT_CHANGE_LEASE; + } else { + backend->log(AQ_LOG_DEBUG, std::format("udev: DRM device {} change event unrecognized", sysname ? sysname : "unknown")); + break; + } + + d->events.change.emit(event); } else if (action == std::string{"remove"}) { backend->log(AQ_LOG_DEBUG, std::format("udev: DRM device {} removed", sysname ? sysname : "unknown")); - backend->log(AQ_LOG_ERROR, "udev: FIXME: remove event is a STUB"); + d->events.remove.emit(); } + + break; } } diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 92a9ffb..7eafd5f 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -214,6 +214,10 @@ bool Aquamarine::CDRMBackend::sessionActive() { void Aquamarine::CDRMBackend::restoreAfterVT() { backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch"); + scanConnectors(); + + backend->log(AQ_LOG_DEBUG, "drm: Rescanned connectors"); + for (auto& c : connectors) { if (!c->crtc) continue; @@ -387,11 +391,22 @@ bool Aquamarine::CDRMBackend::registerGPU(SP gpu_, SPfd); auto drmVer = drmGetVersion(gpu->fd); + gpuName = drmName; + backend->log(AQ_LOG_DEBUG, std::format("drm: Starting backend for {}, with driver {}", drmName ? drmName : "unknown", drmVer->name ? drmVer->name : "unknown")); drmFreeVersion(drmVer); - // FIXME: listen to change and remove events from session + listeners.gpuChange = gpu->events.change.registerListener([this](std::any d) { + auto E = std::any_cast(d); + if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_HOTPLUG) { + backend->log(AQ_LOG_DEBUG, std::format("drm: Got a hotplug event for {}", gpuName)); + scanConnectors(); + } + }); + + listeners.gpuRemove = gpu->events.remove.registerListener( + [this](std::any d) { backend->log(AQ_LOG_ERROR, std::format("drm: !!!!FIXME: Got a remove event for {}, this is not handled properly!!!!!", gpuName)); }); return true; }