/tv/linux/plat/screensaver.py

https://github.com/levjj/miro · Python · 166 lines · 91 code · 30 blank · 45 comment · 9 complexity · 82ef3d469fc524f4011c5d8b9ec4898a MD5 · raw file

  1. # Miro - an RSS based video player application
  2. # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
  3. # Participatory Culture Foundation
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. #
  19. # In addition, as a special exception, the copyright holders give
  20. # permission to link the code of portions of this program with the OpenSSL
  21. # library.
  22. #
  23. # You must obey the GNU General Public License in all respects for all of
  24. # the code used other than OpenSSL. If you modify file(s) with this
  25. # exception, you may extend this exception to your version of the file(s),
  26. # but you are not obligated to do so. If you do not wish to do so, delete
  27. # this exception statement from your version. If you delete this exception
  28. # statement from all source files in the program, then also delete it here.
  29. """screensaver.py -- Enable/Disable the screensaver."""
  30. import os
  31. import dbus
  32. import gobject
  33. import subprocess
  34. class Gnome3ScreenSaverManager(object):
  35. """Screen saver manager for Gnome 3.x"""
  36. def __init__(self, toplevel_window):
  37. self.cookie = None
  38. self.toplevel_window = toplevel_window
  39. # keep a bus around for as long as this object is alive. Gnome 3 docs
  40. # say that disconnecting from the bus will uninhibit the screen saver.
  41. self.bus = dbus.SessionBus()
  42. def should_use(self):
  43. # check to see if the DBus object exists
  44. if not self.bus.name_has_owner('org.gnome.SessionManager'):
  45. return False
  46. # check to see if it has the "Inhibit" method"
  47. # We use the Introspect() method to do this which returns an XML
  48. # string. We could parse this, but it seems enough just to check if
  49. # the method name is present anywhere.
  50. obj = self.bus.get_object('org.gnome.SessionManager',
  51. '/org/gnome/SessionManager')
  52. return 'Inhibit' in obj.Introspect()
  53. def _get_session_manager(self):
  54. return self.bus.get_object('org.gnome.SessionManager',
  55. '/org/gnome/SessionManager')
  56. def disable(self):
  57. obj = self._get_session_manager()
  58. prog = "Miro"
  59. toplevel_xid = dbus.UInt32(self.toplevel_window.window.xid)
  60. reason = "Playing a video"
  61. flags = dbus.UInt32(8) # inhibit idle
  62. self.cookie = obj.Inhibit(prog, toplevel_xid, reason, flags)
  63. def enable(self):
  64. if self.cookie is None:
  65. raise AssertionError("disable() must be called before enable()")
  66. obj = self._get_session_manager()
  67. obj.Uninhibit(self.cookie)
  68. self.cookie = None
  69. class Gnome2ScreenSaverManager(object):
  70. """Screen saver manager for Gnome 2.x"""
  71. def __init__(self, toplevel_window):
  72. self.cookie = None
  73. def should_use(self):
  74. bus = dbus.SessionBus()
  75. # first check if the screen saver dbus object exists
  76. if not bus.name_has_owner('org.gnome.ScreenSaver'):
  77. return False
  78. # check to see if it has the "Inhibit" method" (on Gnome 3 it doesn't)
  79. # We use the Introspect() method to do this which returns an XML
  80. # string. We could parse this, but it seems enough just to check if
  81. # the method name is present anywhere.
  82. obj = bus.get_object('org.gnome.ScreenSaver',
  83. '/org/gnome/ScreenSaver')
  84. return 'Inhibit' in obj.Introspect()
  85. def disable(self):
  86. bus = dbus.SessionBus()
  87. obj = bus.get_object('org.gnome.ScreenSaver',
  88. '/org/gnome/ScreenSaver')
  89. prog = "Miro"
  90. reason = "Playing a video"
  91. self.cookie = obj.Inhibit(prog, reason)
  92. def enable(self):
  93. if self.cookie is None:
  94. raise AssertionError("disable() must be called before enable()")
  95. bus = dbus.SessionBus()
  96. obj = bus.get_object('org.gnome.ScreenSaver',
  97. '/org/gnome/ScreenSaver')
  98. obj.UnInhibit(self.cookie)
  99. self.cookie = None
  100. class XScreenSaverManager(object):
  101. def __init__(self, toplevel_window):
  102. self.timer = None
  103. def call_xss(self, command):
  104. rc = None
  105. devnull = open(os.devnull, 'w')
  106. try:
  107. rc = subprocess.call(['xscreensaver-command', command],
  108. stdout=devnull, stderr=devnull)
  109. except OSError:
  110. pass
  111. devnull.close()
  112. return rc == 0
  113. def should_use(self):
  114. return self.call_xss('-time')
  115. def deactivate(self):
  116. return self.call_xss('-deactivate')
  117. def disable(self):
  118. self.timer = gobject.timeout_add(1000, self.deactivate)
  119. def enable(self):
  120. if self.timer is None:
  121. raise AssertionError("disable() must be called before enable()")
  122. gobject.source_remove(self.timer)
  123. self.timer = None
  124. MANAGER_CLASSES = [
  125. Gnome3ScreenSaverManager,
  126. Gnome2ScreenSaverManager,
  127. XScreenSaverManager,
  128. # TODO: make a KDE3 version?
  129. ]
  130. def create_manager(toplevel_window):
  131. """Return an object that can disable/enable the screensaver."""
  132. for klass in MANAGER_CLASSES:
  133. manager = klass(toplevel_window)
  134. if manager.should_use():
  135. return manager
  136. return None