1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/idle.h"
6
7#include <gdk/gdk.h>
8#include <gdk/gdkx.h>
9
10#include <vector>
11
12#include "base/basictypes.h"
13#include "chrome/browser/sync/engine/idle_query_linux.h"
14#include "chrome/browser/ui/gtk/gtk_util.h"
15#include "ui/base/x/x11_util.h"
16
17namespace {
18
19class ScreensaverWindowFinder : public ui::EnumerateWindowsDelegate {
20 public:
21  ScreensaverWindowFinder()
22      : exists_(false) {}
23
24  bool exists() const { return exists_; }
25
26 protected:
27  virtual bool ShouldStopIterating(XID window) {
28    if (!ui::IsWindowVisible(window) || !IsScreensaverWindow(window))
29      return false;
30    exists_ = true;
31    return true;
32  }
33
34 private:
35  bool IsScreensaverWindow(XID window) const {
36    // It should occupy the full screen.
37    if (!ui::IsX11WindowFullScreen(window))
38      return false;
39
40    // For xscreensaver, the window should have _SCREENSAVER_VERSION property.
41    if (ui::PropertyExists(window, "_SCREENSAVER_VERSION"))
42      return true;
43
44    // For all others, like gnome-screensaver, the window's WM_CLASS property
45    // should contain "screensaver".
46    std::string value;
47    if (!ui::GetStringProperty(window, "WM_CLASS", &value))
48      return false;
49
50    return value.find("screensaver") != std::string::npos;
51  }
52
53  bool exists_;
54
55  DISALLOW_COPY_AND_ASSIGN(ScreensaverWindowFinder);
56};
57
58bool ScreensaverWindowExists() {
59  ScreensaverWindowFinder finder;
60  gtk_util::EnumerateTopLevelWindows(&finder);
61  return finder.exists();
62}
63
64}
65
66IdleState CalculateIdleState(unsigned int idle_threshold) {
67  // Usually the screensaver is used to lock the screen, so we do not need to
68  // check if the workstation is locked.
69  gdk_error_trap_push();
70  bool result = ScreensaverWindowExists();
71  bool got_error = gdk_error_trap_pop();
72  if (result && !got_error)
73    return IDLE_STATE_LOCKED;
74
75  browser_sync::IdleQueryLinux idle_query;
76  unsigned int idle_time = idle_query.IdleTime();
77  if (idle_time >= idle_threshold)
78    return IDLE_STATE_IDLE;
79  return IDLE_STATE_ACTIVE;
80}
81