123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ui/base/x/x11_screensaver.h"
- #include <memory>
- #include "base/command_line.h"
- #include "base/no_destructor.h"
- #include "base/notreached.h"
- #include "ui/base/x/x11_util.h"
- #include "ui/gfx/switches.h"
- #include "ui/gfx/x/connection.h"
- #include "ui/gfx/x/event.h"
- #include "ui/gfx/x/property_cache.h"
- #include "ui/gfx/x/screensaver.h"
- #include "ui/gfx/x/x11_atom_cache.h"
- #include "ui/gfx/x/xproto_util.h"
- namespace ui {
- namespace {
- bool IsMitScreensaverActive(x11::ScreenSaver::State state) {
- switch (state) {
- case x11::ScreenSaver::State::Off:
- case x11::ScreenSaver::State::Disabled:
- return false;
- case x11::ScreenSaver::State::On:
- case x11::ScreenSaver::State::Cycle:
- return true;
- }
- NOTREACHED();
- return false;
- }
- class ScreensaverStatusWatcher : public x11::EventObserver {
- public:
- ScreensaverStatusWatcher() {
- auto* connection = x11::Connection::Get();
- x_screensaver_status_ = std::make_unique<x11::PropertyCache>(
- connection, connection->default_root(),
- std::vector<x11::Atom>{x11::GetAtom("_SCREENSAVER_STATUS")});
- // Let the server know the client version before making any requests.
- connection->screensaver().QueryVersion(
- {x11::ScreenSaver::major_version, x11::ScreenSaver::minor_version});
- connection->AddEventObserver(this);
- connection->screensaver().SelectInput(connection->default_root(),
- x11::ScreenSaver::Event::NotifyMask);
- auto reply =
- connection->screensaver().QueryInfo(connection->default_root()).Sync();
- if (reply) {
- mit_screensaver_active_ = IsMitScreensaverActive(
- static_cast<x11::ScreenSaver::State>(reply->state));
- }
- }
- ScreensaverStatusWatcher(const ScreensaverStatusWatcher&) = delete;
- ScreensaverStatusWatcher& operator=(const ScreensaverStatusWatcher&) = delete;
- ~ScreensaverStatusWatcher() override = default;
- bool ScreensaverActive() {
- if (mit_screensaver_active_)
- return true;
- // Ironically, xscreensaver does not use the MIT-SCREENSAVER extension,
- // so add a special check for xscreensaver.
- auto* status = x_screensaver_status_->GetAs<x11::Atom>(
- x11::GetAtom("_SCREENSAVER_STATUS"));
- return status && *status == x11::GetAtom("LOCK");
- }
- private:
- void OnEvent(const x11::Event& event) override {
- if (auto* notify = event.As<x11::ScreenSaver::NotifyEvent>())
- mit_screensaver_active_ = IsMitScreensaverActive(notify->state);
- }
- std::unique_ptr<x11::PropertyCache> x_screensaver_status_;
- bool mit_screensaver_active_ = false;
- };
- } // namespace
- bool IsXScreensaverActive() {
- // Avoid calling into potentially missing X11 APIs in headless mode.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless))
- return false;
- static base::NoDestructor<ScreensaverStatusWatcher> watcher;
- return watcher->ScreensaverActive();
- }
- } // namespace ui
|