[totem] Bug 595684 — Convert D-Bus plugin to use MPRIS API



commit b8b835d197551d3272c1c071c5aa6b26da82d9de
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Sep 27 20:33:23 2009 +0100

    Bug 595684 â?? Convert D-Bus plugin to use MPRIS API

 bindings/python/totem.defs                         |   77 ++++
 bindings/python/totem.override                     |   16 +-
 src/plugins/dbus-service/dbus-service.py           |  372 ++++++++++++--------
 .../dbus-service/dbus-service.totem-plugin.in      |   24 +--
 src/totem-object.c                                 |   75 ++++-
 src/totem.h                                        |    8 +
 6 files changed, 392 insertions(+), 180 deletions(-)
---
diff --git a/bindings/python/totem.defs b/bindings/python/totem.defs
index 059b400..4203052 100644
--- a/bindings/python/totem.defs
+++ b/bindings/python/totem.defs
@@ -93,6 +93,16 @@
   )
 )
 
+(define-enum RemoteSetting
+  (in-module "Totem")
+  (c-name "TotemRemoteSetting")
+  (gtype-id "TOTEM_TYPE_REMOTE_SETTING")
+  (values
+    '("shuffle" "TOTEM_REMOTE_SETTING_SHUFFLE")
+    '("repeat" "TOTEM_REMOTE_SETTING_REPEAT")
+  )
+)
+
 ;; From totem-plugin.h
 
 (define-function totem_plugin_error_quark
@@ -269,6 +279,21 @@
   )
 )
 
+(define-method get_volume
+  (of-object "TotemObject")
+  (c-name "totem_get_volume")
+  (return-type "gfloat")
+)
+
+(define-method action_volume
+  (of-object "TotemObject")
+  (c-name "totem_action_volume")
+  (return-type "none")
+  (parameters
+    '("gfloat" "volume")
+  )
+)
+
 (define-method action_volume_relative
   (of-object "TotemObject")
   (c-name "totem_action_volume_relative")
@@ -355,6 +380,12 @@
   (return-type "gboolean")
 )
 
+(define-method is_paused
+  (of-object "TotemObject")
+  (c-name "totem_is_paused")
+  (return-type "gboolean")
+)
+
 (define-method is_seekable
   (of-object "TotemObject")
   (c-name "totem_is_seekable")
@@ -385,6 +416,33 @@
   (return-type "char*")
 )
 
+(define-method get_version
+  (of-object "TotemObject")
+  (c-name "totem_get_version")
+  (return-type "char*")
+)
+
+(define-method get_playlist_length
+  (of-object "TotemObject")
+  (c-name "totem_get_playlist_length")
+  (return-type "guint")
+)
+
+(define-method get_playlist_pos
+  (of-object "TotemObject")
+  (c-name "totem_get_playlist_pos")
+  (return-type "int")
+)
+
+(define-method get_title_at_playlist_pos
+  (of-object "TotemObject")
+  (c-name "totem_get_title_at_playlist_pos")
+  (parameters
+    '("guint" "playlist_index")
+  )
+  (return-type "char*")
+)
+
 (define-method get_current_time
   (of-object "TotemObject")
   (c-name "totem_get_current_time")
@@ -447,6 +505,25 @@
   )
 )
 
+(define-method action_remote_set_setting
+  (of-object "TotemObject")
+  (c-name "totem_action_remote_set_setting")
+  (return-type "none")
+  (parameters
+    '("TotemRemoteSetting" "setting")
+    '("gboolean" "value")
+  )
+)
+
+(define-method action_remote_get_setting
+  (of-object "TotemObject")
+  (c-name "totem_action_remote_get_setting")
+  (return-type "gboolean")
+  (parameters
+    '("TotemRemoteSetting" "setting")
+  )
+)
+
 
 ;; From ../../src/totem-cell-renderer-video.h
 
diff --git a/bindings/python/totem.override b/bindings/python/totem.override
index 05987b0..610e3e2 100644
--- a/bindings/python/totem.override
+++ b/bindings/python/totem.override
@@ -108,5 +108,19 @@ _wrap_totem_plugin_load_interface (PyGObject *self, PyObject *args, PyObject *kw
     
 	builder = totem_plugin_load_interface (TOTEM_PLUGIN (self->obj), name, fatal, parent, user_data);
     
-	return pygobject_new((GObject *)builder);
+	return pygobject_new ((GObject *)builder);
+}
+%%
+override totem_get_version noargs
+static PyObject *
+_wrap_totem_get_version (PyGObject *self)
+{
+	PyObject *py_string;
+	char *version;
+
+	version = totem_get_version ();
+	py_string = PyString_FromString (version);
+	g_free (version);
+
+	return py_string;
 }
diff --git a/src/plugins/dbus-service/dbus-service.py b/src/plugins/dbus-service/dbus-service.py
index d632063..f32b1e6 100644
--- a/src/plugins/dbus-service/dbus-service.py
+++ b/src/plugins/dbus-service/dbus-service.py
@@ -1,5 +1,6 @@
 ## Totem D-Bus plugin
 ## Copyright (C) 2009 Lucky <lucky1 data gmail com>
+## Copyright (C) 2009 Philip Withnall <philip tecnocode co uk>
 ##
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -29,200 +30,259 @@ class dbusservice(totem.Plugin):
 		totem.Plugin.__init__(self)
 
 	def activate(self, totem):
-		DBusGMainLoop(set_as_default=True)
-		self.notification = Notification("/org/gnome/Totem")
-		self.title = ""
-		self.artist = ""
-		self.album = ""
-		self.duration = 0 # may be usable in future
-		totem.connect("metadata-updated", self.do_update_metadata)
-		totem.connect("notify::playing", self.do_notify)
+		DBusGMainLoop(set_as_default = True)
 
-	def deactivate(self, totem):
-		self.notification.playingStopped()
-		self.notification.disconnect() # ensure we don't leak our path on the bus
-
-	def do_update_metadata(self, totem, title, artist, album, num):
-		self.title = title
-		self.artist = artist
-		self.album = album
-		if not self.title:
-			self.title = ""
-		if not self.artist:
-			self.artist = ""
-		if not self.album:
-			self.album = ""
+		name = dbus.service.BusName ('org.mpris.Totem', bus = dbus.SessionBus ())
+		self.root = Root (name, totem)
+		self.player = Player (name, totem)
+		self.track_list = TrackList (name, totem)
 
-	def do_notify(self, totem, status):
-		if totem.is_playing():
-			self.notification.playingStarted(self.title, self.album, self.artist, self.duration)
-		else:
-			self.notification.playingStopped()
+	def deactivate(self, totem):
+		self.root.disconnect() # ensure we don't leak our paths on the bus
+		self.player.disconnect()
+		self.track_list.disconnect()
 
-class Notification(dbus.service.Object):
-	def __init__(self, path):
-		dbus.service.Object.__init__(self, dbus.SessionBus(), path)
+class Root (dbus.service.Object):
+	def __init__(self, name, totem):
+		dbus.service.Object.__init__ (self, name, '/')
+		self.totem = totem
 
 	def disconnect(self):
 		self.remove_from_connection(None, None)
 
-	@dbus.service.signal(dbus_interface="org.gnome.Totem", signature="sssu")
-	def playingStarted(self, title, album, artist, duration):
-		pass
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='s')
+	def Identity(self):
+		return self.totem.get_version()
 
-	@dbus.service.signal(dbus_interface="org.gnome.Totem", signature="")
-	def playingStopped(self):
-                pass
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='')
+	def Quit(self):
+		self.totem.action_exit()
 
-## Totem D-Bus plugin
-## Copyright (C) 2009 Lucky <lucky1 data gmail com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor,
-## Boston, MA 02110-1301  USA.
-##
-## Sunday 13th May 2007: Bastien Nocera: Add exception clause.
-## See license_change file for details.
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='(qq)')
+	def MprisVersion(self):
+		return dbus.Struct((dbus.UInt16(1), dbus.UInt16(0)), signature='(qq)')
 
-import totem
-import gobject, gtk
-import dbus, dbus.service
-from dbus.mainloop.glib import DBusGMainLoop
+class Player(dbus.service.Object):
+	def __init__(self, name, totem):
+		dbus.service.Object.__init__(self, name, '/Player')
+		self.totem = totem
 
-class dbusservice(totem.Plugin):
-	def __init__(self):
-		totem.Plugin.__init__(self)
+		self.null_metadata = {"year" : "", "tracknumber" : "", "location" : "",
+			"title" : "", "album" : "", "time" : "", "genre" : "", "artist" : ""}
+		self.old_metadata = self.null_metadata.copy()
+		self.current_metadata = self.null_metadata.copy()
+		self.old_caps = 64 # at startup, we can only support a playlist
+		self.old_status = (2, 0, 0, 0) # startup state
 
-	def activate(self, totem):
-		DBusGMainLoop(set_as_default=True)
-		self.notification = Notification("/org/gnome/Totem")
-		self.title = ""
-		self.artist = ""
-		self.album = ""
-		self.duration = 0 # may be usable in future
 		totem.connect("metadata-updated", self.do_update_metadata)
 		totem.connect("notify::playing", self.do_notify)
+		totem.connect("notify::seekable", self.do_notify)
+		totem.connect("notify::current-mrl", self.do_notify)
+
+	def do_update_metadata(self, totem, artist, title, album, num):
+		self.current_metadata = self.null_metadata.copy()
+		if title:
+			self.current_metadata["title"] = title
+		if artist:
+			self.current_metadata["artist"] = artist
+		if album:
+			self.current_metadata["album"] = album
+		if num:
+			self.current_metadata["tracknumber"] = num
 
-	def deactivate(self, totem):
-		self.notification.playingStopped()
-		self.notification.disconnect() # ensure we don't leak our path on the bus
-
-	def do_update_metadata(self, totem, title, artist, album, num):
-		self.title = title
-		self.artist = artist
-		self.album = album
-		if not self.title:
-			self.title = ""
-		if not self.artist:
-			self.artist = ""
-		if not self.album:
-			self.album = ""
+		if totem.is_playing():
+			self.track_change(self.current_metadata)
 
 	def do_notify(self, totem, status):
 		if totem.is_playing():
-			self.notification.playingStarted(self.title, self.album, self.artist, self.duration)
+			self.track_change(self.current_metadata)
 		else:
-			self.notification.playingStopped()
+			self.track_change(self.null_metadata)
+
+		status = self.calculate_status()
+		if status != self.old_status:
+			self.status_change(status)
 
-class Notification(dbus.service.Object):
-	def __init__(self, path):
-		dbus.service.Object.__init__(self, dbus.SessionBus(), path)
+		caps = self.calculate_caps()
+		if caps != self.old_caps:
+			self.caps_change(caps)
+
+	def calculate_status(self):
+		if self.totem.is_playing():
+			playing_status = 0
+		elif self.totem.is_paused():
+			playing_status = 1
+		else:
+			playing_status = 2
+
+		if self.totem.action_remote_get_setting(totem.REMOTE_SETTING_SHUFFLE):
+			shuffle_status = 1
+		else:
+			shuffle_status = 0
+
+		if self.totem.action_remote_get_setting(totem.REMOTE_SETTING_REPEAT):
+			repeat_status = 1
+		else:
+			repeat_status = 0
+
+		return (
+			dbus.Int32(playing_status), # 0 = Playing, 1 = Paused, 2 = Stopped
+			dbus.Int32(self.totem.action_remote_get_setting(totem.REMOTE_SETTING_SHUFFLE)), # 0 = Playing linearly , 1 = Playing randomly
+			dbus.Int32(0), # 0 = Go to the next element once the current has finished playing , 1 = Repeat the current element 
+			dbus.Int32(self.totem.action_remote_get_setting(totem.REMOTE_SETTING_REPEAT)) # 0 = Stop playing once the last element has been played, 1 = Never give up playing 
+		)
+
+	def calculate_caps(self):
+		caps = 64 # we can always have a playlist
+		playlist_length = self.totem.get_playlist_length()
+		playlist_pos = self.totem.get_playlist_pos()
+
+		if playlist_pos < playlist_length - 1:
+			caps |= 1 << 0 # go next
+		if playlist_pos > 0:
+			caps |= 1 << 1 # go previous
+		if playlist_length > 0:
+			caps |= 1 << 2 # pause
+			caps |= 1 << 3 # play
+		if self.totem.is_seekable():
+			caps |= 1 << 4 # seek
+		if self.current_metadata != self.null_metadata:
+			caps |= 1 << 5 # get metadata
+
+		return caps
+
+	def track_change(self, metadata):
+		if self.old_metadata != metadata:
+			self.old_metadata = metadata.copy()
+			self.TrackChange(metadata)
+
+	def status_change(self, status):
+		if self.old_status != status:
+			self.old_status = status
+			self.StatusChange(status)
+
+	def caps_change(self, caps):
+		if self.old_caps != caps:
+			self.old_caps = caps
+			self.CapsChange(caps)
 
 	def disconnect(self):
+		self.TrackChange(self.null_metadata)
 		self.remove_from_connection(None, None)
 
-	@dbus.service.signal(dbus_interface="org.gnome.Totem", signature="sssu")
-	def playingStarted(self, title, album, artist, duration):
+	@dbus.service.signal(dbus_interface = "org.freedesktop.MediaPlayer", signature='a{sv}')
+	def TrackChange(self, metadata):
 		pass
 
-	@dbus.service.signal(dbus_interface="org.gnome.Totem", signature="")
-	def playingStopped(self):
-                pass
+	@dbus.service.signal(dbus_interface = "org.freedesktop.MediaPlayer", signature='(iiii)')
+	def StatusChange(self, status):
+		pass
 
-## Totem D-Bus plugin
-## Copyright (C) 2009 Lucky <lucky1 data gmail com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor,
-## Boston, MA 02110-1301  USA.
-##
-## Sunday 13th May 2007: Bastien Nocera: Add exception clause.
-## See license_change file for details.
+	@dbus.service.signal(dbus_interface = "org.freedesktop.MediaPlayer", signature='i')
+	def CapsChange(self, caps):
+		pass
 
-import totem
-import gobject, gtk
-import dbus, dbus.service
-from dbus.mainloop.glib import DBusGMainLoop
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='')
+	def Next(self):
+		self.totem.action_next()
 
-class dbusservice(totem.Plugin):
-	def __init__(self):
-		totem.Plugin.__init__(self)
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='')
+	def Prev(self):
+		self.totem.action_previous()
 
-	def activate(self, totem):
-		DBusGMainLoop(set_as_default=True)
-		self.notification = Notification("/org/gnome/Totem")
-		self.title = ""
-		self.artist = ""
-		self.album = ""
-		self.duration = 0 # may be usable in future
-		totem.connect("metadata-updated", self.do_update_metadata)
-		totem.connect("notify::playing", self.do_notify)
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='')
+	def Pause(self):
+		self.totem.action_play_pause()
 
-	def deactivate(self, totem):
-		self.notification.playingStopped()
-		self.notification.disconnect() # ensure we don't leak our path on the bus
-
-	def do_update_metadata(self, totem, title, artist, album, num):
-		self.title = title
-		self.artist = artist
-		self.album = album
-		if not self.title:
-			self.title = ""
-		if not self.artist:
-			self.artist = ""
-		if not self.album:
-			self.album = ""
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='')
+	def Stop(self):
+		self.totem.action_stop()
 
-	def do_notify(self, totem, status):
-		if totem.is_playing():
-			self.notification.playingStarted(self.title, self.album, self.artist, self.duration)
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='')
+	def Play(self):
+		# If playing : rewind to the beginning of current track, else : start playing. 
+		if self.totem.is_playing():
+			self.totem.action_seek_time(0)
 		else:
-			self.notification.playingStopped()
+			self.totem.action_play()
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='b', out_signature='')
+	def Repeat(self, value):
+		pass # we don't support repeating individual tracks
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='(iiii)')
+	def GetStatus(self):
+		status = self.calculate_status()
+		self.old_status = status
+		return dbus.Struct(status, signature='(iiii)')
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='a{sv}')
+	def GetMetadata(self):
+		return self.current_metadata
 
-class Notification(dbus.service.Object):
-	def __init__(self, path):
-		dbus.service.Object.__init__(self, dbus.SessionBus(), path)
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='i')
+	def GetCaps(self):
+		caps = self.calculate_caps()
+		self.old_caps = caps
+		return caps
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='i', out_signature='')
+	def VolumeSet(self, volume):
+		self.totem.action_volume(volume / 100.0)
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='i')
+	def VolumeGet(self):
+		return dbus.Int32(self.totem.get_volume() * 100)
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='i', out_signature='')
+	def PositionSet(self, position):
+		self.totem.action_seek_time(position)
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='i')
+	def PositionGet(self):
+		return dbus.Int32(self.totem.props.current_time)
+
+class TrackList(dbus.service.Object):
+	def __init__(self, name, totem):
+		dbus.service.Object.__init__(self, name, '/TrackList')
+		self.totem = totem
 
 	def disconnect(self):
 		self.remove_from_connection(None, None)
 
-	@dbus.service.signal(dbus_interface="org.gnome.Totem", signature="sssu")
-	def playingStarted(self, title, album, artist, duration):
+	@dbus.service.signal(dbus_interface = "org.freedesktop.MediaPlayer", signature='i')
+	def TrackListChange(self, length):
+		# TODO: we can't implement this until TotemPlaylist is exposed in the Python API
+		pass
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='i', out_signature='a{sv}')
+	def GetMetadata(self, pos):
+		# Since the API doesn't currently exist in Totem to get the rest of the metadata, we can only return the title
+		return { "title" : self.totem.get_title_at_playlist_pos(pos) }
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='i')
+	def GetCurrentTrack(self):
+		return self.totem.get_playlist_pos()
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='', out_signature='i')
+	def GetLength(self):
+		return self.totem.get_playlist_length()
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='sb', out_signature='i')
+	def AddTrack(self, uri, play_immediately):
+		# We can't currently support !play_immediately
+		self.totem.add_to_playlist_and_play(uri, '', True)
+		return 0
+
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='i', out_signature='')
+	def DelTrack(self, pos):
+		# TODO: we need TotemPlaylist exposed by the Python API for this
 		pass
 
-	@dbus.service.signal(dbus_interface="org.gnome.Totem", signature="")
-	def playingStopped(self):
-                pass
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='b', out_signature='')
+	def SetLoop(self, loop):
+		self.totem.action_remote_set_setting(totem.REMOTE_SETTING_REPEAT, loop)
 
+	@dbus.service.method(dbus_interface='org.freedesktop.MediaPlayer', in_signature='b', out_signature='')
+	def SetRandom(self, random):
+		self.totem.action_remote_set_setting(totem.REMOTE_SETTING_SHUFFLE, random)
diff --git a/src/plugins/dbus-service/dbus-service.totem-plugin.in b/src/plugins/dbus-service/dbus-service.totem-plugin.in
index 7d54d5a..f7b4b21 100644
--- a/src/plugins/dbus-service/dbus-service.totem-plugin.in
+++ b/src/plugins/dbus-service/dbus-service.totem-plugin.in
@@ -3,25 +3,7 @@ Loader=python
 Module=dbus-service
 IAge=1
 _Name=D-Bus Service
-_Description=Plugin for sending notifications of currently-playing movies to the D-Bus subsystem.
-Authors=Lucky <lucky1 data gmail com>
-Copyright=Copyright © 2009 Lucky
-Website=http://projects.gnome.org/totem/
-[Totem Plugin]
-Loader=python
-Module=dbus-service
-IAge=1
-_Name=D-Bus Service
-_Description=Plugin for sending notifications of currently-playing movies to the D-Bus subsystem.
-Authors=Lucky <lucky1 data gmail com>
-Copyright=Copyright © 2009 Lucky
-Website=http://projects.gnome.org/totem/
-[Totem Plugin]
-Loader=python
-Module=dbus-service
-IAge=1
-_Name=D-Bus Service
-_Description=Plugin for sending notifications of currently-playing movies to the D-Bus subsystem.
-Authors=Lucky <lucky1 data gmail com>
-Copyright=Copyright © 2009 Lucky
+_Description=Plugin for sending notifications of currently playing movies to the D-Bus subsystem.
+Authors=Lucky <lucky1 data gmail com>, Philip Withnall <philip tecnocode co uk>
+Copyright=Copyright © 2009 Lucky, Philip Withnall
 Website=http://projects.gnome.org/totem/
diff --git a/src/totem-object.c b/src/totem-object.c
index 57c0b13..9260ef3 100644
--- a/src/totem-object.c
+++ b/src/totem-object.c
@@ -422,6 +422,19 @@ totem_get_video_widget_backend_name (Totem *totem)
 }
 
 /**
+ * totem_get_version:
+ *
+ * Gets the application name and version (e.g. "Totem 2.28.0").
+ *
+ * Return value: a newly-allocated string of the name and version of the application
+ **/
+char *
+totem_get_version (void)
+{
+	return g_strdup_printf (_("Totem %s"), VERSION);
+}
+
+/**
  * totem_get_current_time:
  * @totem: a #TotemObject
  *
@@ -727,6 +740,34 @@ totem_remote_command_get_type (void)
 }
 
 GQuark
+totem_remote_setting_quark (void)
+{
+	static GQuark quark = 0;
+	if (!quark)
+		quark = g_quark_from_static_string ("totem_remote_setting");
+
+	return quark;
+}
+
+GType
+totem_remote_setting_get_type (void)
+{
+	static GType etype = 0;
+
+	if (etype == 0) {
+		static const GEnumValue values[] = {
+			ENUM_ENTRY (TOTEM_REMOTE_SETTING_SHUFFLE, "Shuffle"),
+			ENUM_ENTRY (TOTEM_REMOTE_SETTING_REPEAT, "Repeat"),
+			{ 0, NULL, NULL }
+		};
+
+		etype = g_enum_register_static ("TotemRemoteSetting", values);
+	}
+
+	return etype;
+}
+
+GQuark
 totem_disc_media_type_quark (void)
 {
 	static GQuark quark = 0;
@@ -1991,12 +2032,42 @@ totem_action_zoom_reset (Totem *totem)
 }
 
 /**
+ * totem_action_get_volume:
+ * @totem: a #TotemObject
+ *
+ * Gets the current volume level, as a value between %0.0 and %1.0.
+ *
+ * Return value: the volume level
+ **/
+double
+totem_get_volume (Totem *totem)
+{
+	return bacon_video_widget_get_volume (totem->bvw);
+}
+
+/**
+ * totem_action_volume:
+ * @totem: a #TotemObject
+ * @volume: the new absolute volume value
+ *
+ * Sets the volume, with %1.0 being the maximum, and %0.0 being the minimum level.
+ **/
+void
+totem_action_volume (Totem *totem, double volume)
+{
+	if (bacon_video_widget_can_set_volume (totem->bvw) == FALSE)
+		return;
+
+	bacon_video_widget_set_volume (totem->bvw, volume);
+}
+
+/**
  * totem_action_volume_relative:
  * @totem: a #TotemObject
  * @off_pct: the value by which to increase or decrease the volume
  *
- * Sets the volume relative to its current level, with 1.0 being the
- * maximum, and 0.0 being the minimum level.
+ * Sets the volume relative to its current level, with %1.0 being the
+ * maximum, and %0.0 being the minimum level.
  **/
 void
 totem_action_volume_relative (Totem *totem, double off_pct)
diff --git a/src/totem.h b/src/totem.h
index e6a84b9..d7ce5c9 100644
--- a/src/totem.h
+++ b/src/totem.h
@@ -125,6 +125,11 @@ GQuark totem_remote_command_quark	(void);
 #define TOTEM_TYPE_REMOTE_COMMAND	(totem_remote_command_get_type())
 #define TOTEM_REMOTE_COMMAND		totem_remote_command_quark ()
 
+GType totem_remote_setting_get_type	(void);
+GQuark totem_remote_setting_quark	(void);
+#define TOTEM_TYPE_REMOTE_SETTING	(totem_remote_setting_get_type())
+#define TOTEM_REMOTE_SETTING		totem_remote_setting_quark ()
+
 GType totem_disc_media_type_get_type	(void);
 GQuark totem_disc_media_type_quark	(void);
 #define TOTEM_TYPE_DISC_MEDIA_TYPE	(totem_disc_media_type_get_type())
@@ -197,6 +202,8 @@ void	totem_action_next			(Totem *totem);
 void	totem_action_previous			(Totem *totem);
 void	totem_action_seek_time			(Totem *totem, gint64 sec);
 void	totem_action_seek_relative		(Totem *totem, gint64 offset);
+double	totem_get_volume			(Totem *totem);
+void	totem_action_volume			(Totem *totem, double volume);
 void	totem_action_volume_relative		(Totem *totem, double off_pct);
 void	totem_action_volume_toggle_mute		(Totem *totem);
 gboolean totem_action_set_mrl			(Totem *totem,
@@ -236,6 +243,7 @@ GtkWindow *totem_get_main_window		(Totem *totem);
 GtkUIManager *totem_get_ui_manager		(Totem *totem);
 GtkWidget *totem_get_video_widget		(Totem *totem);
 char *totem_get_video_widget_backend_name	(Totem *totem);
+char *totem_get_version				(void);
 
 /* Current media information */
 char *	totem_get_short_title			(Totem *totem);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]