#!/usr/bin/python -Wall import dbus import dbus.mainloop.glib import gtk import gtk.glade import gobject import sys import os import subprocess import platform from optparse import OptionParser SM_DBUS_NAME = "org.gnome.SessionManager" SM_DBUS_PATH = "/org/gnome/SessionManager" SM_DBUS_INTERFACE = "org.gnome.SessionManager" SM_CLIENT_DBUS_INTERFACE = "org.gnome.SessionManager.ClientPrivate" APP_ID = "debathena-branding" GLADE_FILE="/usr/share/debathena-branding/debathena-branding.glade" DEBATHENA_LOGO_FILES=["/usr/share/pixmaps/debathena.png", "/usr/share/pixmaps/debathena1.png", "/usr/share/pixmaps/debathena2.png", "/usr/share/pixmaps/debathena3.png", "/usr/share/pixmaps/debathena4.png", "/usr/share/pixmaps/debathena5.png", "/usr/share/pixmaps/debathena6.png", "/usr/share/pixmaps/debathena7.png", "/usr/share/pixmaps/debathena8.png"] class Branding: animation_loop_frames = 150 def __init__(self, options): self.debug = options.debug self.sessionEnding = False self.sessionBus = dbus.SessionBus() try: self.register_with_sm() self.init_sm_client() except: print "Warning: Cannot register with session manager." try: self.xml = gtk.glade.XML(options.gladefile) except: print "Could not load Glade XML: %s" % (options.gladefile) sys.exit(1) self.winWelcome = self.xml.get_widget('winWelcome') self.winWelcome.set_property('can_focus', False) # Multiple monitor support. Use the primary monitor. defaultScreen = gtk.gdk.screen_get_default() self.monitorGeometry = defaultScreen.get_monitor_geometry(defaultScreen.get_primary_monitor()) moveY = self.monitorGeometry.y + 200 logoScale = 0.60 if (self.monitorGeometry.height - self.monitorGeometry.y) <= 900: moveY = self.monitorGeometry.y + 10 logoScale = 0.40 moveX = self.monitorGeometry.x + ((self.monitorGeometry.width - self.winWelcome.get_size()[0]) / 2) self.winWelcome.move(moveX, moveY) self.imgDebathena = self.xml.get_widget('imgDebathena') self.imgDebathena.set_property('can_focus', False) self.animate = self.setup_owl(logoScale) self.winBranding = self.xml.get_widget('winBranding') self.winBranding.set_property('can_focus', False) self.lblBranding = self.xml.get_widget('lblBranding') self.lblBranding.set_property('can_focus', False) try: metapackage = subprocess.Popen(["machtype", "-L"], stdout=subprocess.PIPE).communicate()[0].rstrip() except OSError: metapackage = '(error)' try: baseos = subprocess.Popen(["machtype", "-E"], stdout=subprocess.PIPE).communicate()[0].rstrip() except OSError: baseos = '(error)' arch = platform.machine() if arch != "x86_64": arch = "" + arch + "" self.lblBranding.set_markup(metapackage + "\n" + baseos + "\n" + arch) self.winBranding.set_gravity(gtk.gdk.GRAVITY_SOUTH_EAST) width, height = self.winBranding.get_size() self.winBranding.move(self.monitorGeometry.x + (self.monitorGeometry.width - width), self.monitorGeometry.y + (self.monitorGeometry.height - height)) # Connect to the session manager, and register our client. def register_with_sm(self): proxy = self.sessionBus.get_object(SM_DBUS_NAME, SM_DBUS_PATH) sm = dbus.Interface(proxy, SM_DBUS_INTERFACE) autostart_id = os.getenv("DESKTOP_AUTOSTART_ID", default="") self.smClientId = sm.RegisterClient(APP_ID, autostart_id) # Set up to handle signals from the session manager. def init_sm_client(self): proxy = self.sessionBus.get_object(SM_DBUS_NAME, self.smClientId) self.smClient = dbus.Interface(proxy, SM_CLIENT_DBUS_INTERFACE) self.smClient.connect_to_signal("QueryEndSession", self.sm_on_QueryEndSession) self.smClient.connect_to_signal("EndSession", self.sm_on_EndSession) self.smClient.connect_to_signal("CancelEndSession", self.sm_on_CancelEndSession) self.smClient.connect_to_signal("Stop", self.sm_on_Stop) # Load the Debathena owl image and generate self.logo_pixbufs, the list of # animation frames. Returns True if successful, False otherwise. def setup_owl(self, logoScale): self.logo_pixbufs = [] num_pixbufs = 0 try: # Eyes go closed. for img in DEBATHENA_LOGO_FILES: pixbuf = gtk.gdk.pixbuf_new_from_file(img) self.logo_pixbufs.append(pixbuf.scale_simple(int(pixbuf.get_width() * logoScale), int(pixbuf.get_height() * logoScale), gtk.gdk.INTERP_BILINEAR)) num_pixbufs += 1 except: # Just don't display the image if it's missing return False # Eyes come open. for pixbuf in self.logo_pixbufs[::-1]: self.logo_pixbufs.append(pixbuf) num_pixbufs += 1 # Eyes stay open. self.logo_pixbufs.extend([None] * (self.animation_loop_frames - num_pixbufs)) # Set it to the first image so that the window can size itself # accordingly self.imgDebathena.set_from_pixbuf(self.logo_pixbufs[0]) self.img_idx = -1 return True # Update the Debathena owl image. def update_owl(self): if not self.animate: return False self.img_idx = (self.img_idx + 1) % self.animation_loop_frames pixbuf = self.logo_pixbufs[self.img_idx] if pixbuf is not None: self.imgDebathena.set_from_pixbuf(pixbuf) return True # Here on a QueryEndSession signal from the session manager. def sm_on_QueryEndSession(self, flags): self.sessionEnding = True # Response args: is_ok, reason. self.smClient.EndSessionResponse(True, "") # Here on an EndSession signal from the session manager. def sm_on_EndSession(self, flags): self.sessionEnding = True # Response args: is_ok, reason. self.smClient.EndSessionResponse(True, "") # Here on a CancelEndSession signal from the session manager. def sm_on_CancelEndSession(self): self.sessionEnding = False # Here on a Stop signal from the session manager. def sm_on_Stop(self): subprocess.call(["/usr/bin/pkill", "-f", "gnome-settings-daemon"]) gtk.main_quit() def main(options): dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) branding = Branding(options) gobject.timeout_add(50, branding.update_owl) gtk.main() if __name__ == '__main__': parser = OptionParser() parser.set_defaults(debug=False, guitest=False) parser.add_option("--test", action="store_true", dest="debug") parser.add_option("--glade", action="store", type="string", default=GLADE_FILE, dest="gladefile") (options, args) = parser.parse_args() main(options)