Index: totem/configure.in
===================================================================
--- totem.orig/configure.in	2005-07-11 14:11:18.000000000 +0200
+++ totem/configure.in	2005-07-12 07:56:12.403330448 +0200
@@ -20,6 +20,7 @@
 GTK_REQS=2.5.6
 GNOMEVFS_REQS=2.9.92
 GNOMEUI_REQS=2.3.3
+GNOMEICON_REQS=2.9.3
 
 # Before making a release, the PLPARSER_LT_VERSION string should be modified.
 # The string is of the form C:R:A.
@@ -136,10 +137,10 @@
 dnl Seems that the order matters because libtool blows
 dnl Also check if we're going to be using GTK+ only
 if test x$ENABLE_GTK = "xno" ; then
-	PKG_CHECK_MODULES(EXTRA_GNOME, glib-2.0 >= $GLIB_REQS gtk+-2.0 >= $GTK_REQS libgnomeui-2.0 >= $GNOMEUI_REQS libglade-2.0 gnome-vfs-2.0 >= $GNOMEVFS_REQS gnome-vfs-module-2.0 >= $GNOMEVFS_REQS gnome-desktop-2.0 >= 2.1.5 iso-codes libmusicbrainz $MM)
+	PKG_CHECK_MODULES(EXTRA_GNOME, glib-2.0 >= $GLIB_REQS gtk+-2.0 >= $GTK_REQS libgnomeui-2.0 >= $GNOMEUI_REQS libglade-2.0 gnome-vfs-2.0 >= $GNOMEVFS_REQS gnome-vfs-module-2.0 >= $GNOMEVFS_REQS gnome-desktop-2.0 >= 2.1.5 gnome-icon-theme >= $GNOMEICON_REQS iso-codes libmusicbrainz $MM)
 	HAVE_GNOME=yes
 else
-	PKG_CHECK_MODULES(EXTRA_GNOME, glib-2.0 >= $GLIB_REQS gtk+-2.0 >= $GTK_REQS libglade-2.0 gnome-vfs-2.0 >= $GNOMEVFS_REQS gnome-vfs-module-2.0 >= $GNOMEVFS_REQS iso-codes libmusicbrainz $MM)
+	PKG_CHECK_MODULES(EXTRA_GNOME, glib-2.0 >= $GLIB_REQS gtk+-2.0 >= $GTK_REQS libglade-2.0 gnome-vfs-2.0 >= $GNOMEVFS_REQS gnome-vfs-module-2.0 >= $GNOMEVFS_REQS gnome-icon-theme >= $GNOMEICON_REQS iso-codes libmusicbrainz $MM)
 	AC_DEFINE(USE_STABLE_LIBGNOMEUI, 1, [defined if we don't have GNOME])
 	AC_DEFINE(HAVE_GTK_ONLY, 1, [defined if GNOME isn't used])
 	HAVE_GNOME=no
Index: totem/data/totem.glade
===================================================================
--- totem.orig/data/totem.glade	2005-07-11 10:44:30.000000000 +0200
+++ totem/data/totem.glade	2005-07-12 08:20:52.293352968 +0200
@@ -2772,31 +2772,6 @@
 		  <property name="spacing">6</property>
 
 		  <child>
-		    <widget class="GtkLabel" id="tmw_title_label">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">&lt;span size=&quot;medium&quot;&gt;&lt;b&gt;No File&lt;/b&gt;&lt;/span&gt;</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">True</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">True</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
 		    <widget class="GtkHBox" id="tmw_seek_hbox">
 		      <property name="visible">True</property>
 		      <property name="homogeneous">False</property>
@@ -2955,89 +2930,6 @@
 		      </child>
 
 		      <child>
-			<widget class="GtkHBox" id="tmw_volume_hbox">
-			  <property name="visible">True</property>
-			  <property name="sensitive">False</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">0</property>
-
-			  <child>
-			    <widget class="GtkButton" id="tmw_volume_mute_button">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="relief">GTK_RELIEF_NONE</property>
-			      <property name="focus_on_click">True</property>
-
-			      <child>
-				<widget class="GtkImage" id="image8">
-				  <property name="visible">True</property>
-				  <property name="pixbuf">rhythmbox-volume-zero.png</property>
-				  <property name="xalign">0.5</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				</widget>
-			      </child>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkHScale" id="tmw_volume_hscale">
-			      <property name="width_request">100</property>
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="draw_value">False</property>
-			      <property name="value_pos">GTK_POS_TOP</property>
-			      <property name="digits">1</property>
-			      <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
-			      <property name="inverted">False</property>
-			      <property name="adjustment">0 0 100 1 10 0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkButton" id="tmw_volume_max_button">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="relief">GTK_RELIEF_NONE</property>
-			      <property name="focus_on_click">True</property>
-
-			      <child>
-				<widget class="GtkImage" id="image9">
-				  <property name="visible">True</property>
-				  <property name="pixbuf">rhythmbox-volume-max.png</property>
-				  <property name="xalign">0.5</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xpad">0</property>
-				  <property name="ypad">0</property>
-				</widget>
-			      </child>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="padding">0</property>
-			  <property name="expand">True</property>
-			  <property name="fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
 			<widget class="GtkToggleButton" id="tmw_sidebar_button">
 			  <property name="visible">True</property>
 			  <property name="can_focus">True</property>
@@ -3114,8 +3006,24 @@
 			  <property name="padding">0</property>
 			  <property name="expand">False</property>
 			  <property name="fill">False</property>
+		          <property name="pack_type">GTK_PACK_END</property>
 			</packing>
 		      </child>
+		      <child>
+		        <widget class="Custom" id="tcw_volume_button">
+		          <property name="visible">True</property>
+		          <property name="creation_function">totem_volume_create</property>
+		          <property name="int1">0</property>
+		          <property name="int2">0</property>
+		          <property name="last_modification_time">Fri, 06 May 2005 09:19:48 GMT</property>
+		        </widget>
+		        <packing>
+		          <property name="padding">0</property>
+		          <property name="expand">False</property>
+		          <property name="fill">False</property>
+		          <property name="pack_type">GTK_PACK_END</property>
+  		        </packing>
+		      </child>
 		    </widget>
 		    <packing>
 		      <property name="padding">0</property>
Index: totem/src/Makefile.am
===================================================================
--- totem.orig/src/Makefile.am	2005-07-11 14:11:18.000000000 +0200
+++ totem/src/Makefile.am	2005-07-12 07:53:33.442496168 +0200
@@ -92,6 +92,7 @@
 	totem-statusbar.c		\
 	totem-statusbar.h		\
 	totem-gromit.c totem-gromit.h	\
+	totem-volume.c totem-volume.h	\
 	ev-sidebar.c ev-sidebar.h
 
 totem_LDADD = \
Index: totem/src/totem-private.h
===================================================================
--- totem.orig/src/totem-private.h	2005-07-11 10:41:19.000000000 +0200
+++ totem/src/totem-private.h	2005-07-12 07:53:33.483489936 +0200
@@ -85,7 +85,6 @@
 
 	/* Volume */
 	GtkWidget *volume;
-	GtkAdjustment *voladj;
 	gboolean vol_lock;
 	gboolean vol_fs_lock;
 	gfloat prev_volume;
Index: totem/src/totem-volume.c
===================================================================
--- totem.orig/src/totem-volume.c	2005-07-12 09:50:33.563591112 +0200
+++ totem/src/totem-volume.c	2005-07-12 08:09:03.158157904 +0200
@@ -0,0 +1,594 @@
+/* Totem Volume Button / popup widget
+ * (c) copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _GNU_SOURCE
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include "totem-volume.h"
+
+#define SCALE_SIZE 100
+#define CLICK_TIMEOUT 250
+
+enum {
+  SIGNAL_VALUE_CHANGED,
+  NUM_SIGNALS
+};
+
+static void	totem_volume_button_class_init	(TotemVolumeButtonClass * klass);
+static void	totem_volume_button_init	(TotemVolumeButton * button);
+static void	totem_volume_button_dispose	(GObject        * object);
+
+static gboolean	totem_volume_button_scroll	(GtkWidget      * widget,
+						 GdkEventScroll * event);
+static gboolean	totem_volume_button_press	(GtkWidget      * widget,
+						 GdkEventButton * event);
+static gboolean cb_dock_press			(GtkWidget      * widget,
+						 GdkEventButton * event,
+						 gpointer         data);
+
+static gboolean cb_button_press			(GtkWidget      * widget,
+						 GdkEventButton * event,
+						 gpointer         data);
+static gboolean cb_button_release		(GtkWidget      * widget,
+						 GdkEventButton * event,
+						 gpointer         data);
+
+/* see below for scale definitions */
+static GtkWidget *totem_volume_scale_new	(TotemVolumeButton * button,
+						 float min, float max,
+						 float step);
+
+static GtkButtonClass *parent_class = NULL;
+static guint signals[NUM_SIGNALS] = { 0 };
+
+GType
+totem_volume_button_get_type (void)
+{
+  static GType totem_volume_button_type = 0;
+
+  if (!totem_volume_button_type) {
+    static const GTypeInfo totem_volume_button_info = {
+      sizeof (TotemVolumeButtonClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) totem_volume_button_class_init,
+      NULL,
+      NULL,
+      sizeof (TotemVolumeButton),
+      0,
+      (GInstanceInitFunc) totem_volume_button_init,
+      NULL
+    };
+
+    totem_volume_button_type =
+	g_type_register_static (GTK_TYPE_BUTTON, 
+				"TotemVolumeButton",
+				&totem_volume_button_info, 0);
+  }
+
+  return totem_volume_button_type;
+}
+
+static void
+totem_volume_button_class_init (TotemVolumeButtonClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
+
+  parent_class = g_type_class_ref (GTK_TYPE_BUTTON);
+
+  /* events */
+  gobject_class->dispose = totem_volume_button_dispose;
+  gtkwidget_class->button_press_event = totem_volume_button_press;
+  gtkwidget_class->scroll_event = totem_volume_button_scroll;
+
+  /* signals */
+  signals[SIGNAL_VALUE_CHANGED] = g_signal_new ("value-changed",
+      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (TotemVolumeButtonClass, value_changed),
+      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+static void
+totem_volume_button_init (TotemVolumeButton *button)
+{
+  button->timeout = FALSE;
+  button->click_id = 0;
+  button->dock = button->scale = NULL;
+#ifndef HAVE_GTK_ONLY
+  button->theme = gtk_icon_theme_get_default ();
+#endif
+}
+
+static void
+totem_volume_button_dispose (GObject *object)
+{
+  TotemVolumeButton *button = TOTEM_VOLUME_BUTTON (object);
+
+  if (button->dock) {
+    gtk_widget_destroy (button->dock);
+    button->dock = NULL;
+  }
+
+  if (button->theme) {
+    g_object_unref (G_OBJECT (button->theme));
+    button->theme = NULL;
+  }
+
+  if (button->click_id != 0) {
+    g_source_remove (button->click_id);
+    button->click_id = 0;
+  }
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+/*
+ * public API.
+ */
+
+GtkWidget *
+totem_volume_button_new (float min, float max,
+			 float step)
+{
+  TotemVolumeButton *button;
+  GtkWidget *frame, *box;
+
+  button = g_object_new (TOTEM_TYPE_VOLUME_BUTTON, NULL);
+  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+
+#ifndef HAVE_GTK_ONLY
+  /* image */
+  button->image = gtk_image_new ();
+  gtk_container_add (GTK_CONTAINER (button), button->image);
+  gtk_widget_show_all (button->image);
+#endif
+
+  /* window */
+  button->dock = gtk_window_new (GTK_WINDOW_POPUP);
+  g_signal_connect (button->dock, "button-press-event",
+		    G_CALLBACK (cb_dock_press), button);
+  gtk_window_set_decorated (GTK_WINDOW (button->dock), FALSE);
+
+  /* frame */
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
+  gtk_container_add (GTK_CONTAINER (button->dock), frame);
+  box = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (frame), box);
+
+  /* + */
+  button->plus = gtk_button_new_with_label (_("+"));
+  gtk_button_set_relief (GTK_BUTTON (button->plus), GTK_RELIEF_NONE);
+  g_signal_connect (button->plus, "button-press-event",
+		    G_CALLBACK (cb_button_press), button);
+  g_signal_connect (button->plus, "button-release-event",
+		    G_CALLBACK (cb_button_release), button);
+  gtk_box_pack_start (GTK_BOX (box), button->plus, TRUE, FALSE, 0);
+
+  /* scale */
+  button->scale = totem_volume_scale_new (button, min, max, step);
+  gtk_widget_set_size_request (button->scale, -1, SCALE_SIZE);
+  gtk_scale_set_draw_value (GTK_SCALE (button->scale), FALSE);
+  gtk_range_set_inverted (GTK_RANGE (button->scale), TRUE);
+  gtk_box_pack_start (GTK_BOX (box), button->scale, TRUE, FALSE, 0);
+
+  /* - */
+  button->min = gtk_button_new_with_label (_("-"));
+  gtk_button_set_relief (GTK_BUTTON (button->min), GTK_RELIEF_NONE);
+  g_signal_connect (button->min, "button-press-event",
+		   G_CALLBACK (cb_button_press), button);
+  g_signal_connect (button->min, "button-release-event",
+		    G_CALLBACK (cb_button_release), button);
+  gtk_box_pack_start (GTK_BOX (box), button->min, TRUE, FALSE, 0);
+
+  return GTK_WIDGET (button);
+}
+
+float
+totem_volume_button_get_value (TotemVolumeButton * button)
+{
+  g_return_val_if_fail (button != NULL, 0);
+
+  return gtk_range_get_value (GTK_RANGE (button->scale));
+}
+
+void
+totem_volume_button_set_value (TotemVolumeButton * button,
+			       float value)
+{
+  g_return_if_fail (button != NULL);
+
+  gtk_range_set_value (GTK_RANGE (button->scale), value);
+}
+
+/*
+ * button callbacks.
+ */
+
+static gboolean
+totem_volume_button_scroll (GtkWidget      * widget,
+			    GdkEventScroll * event)
+{
+  TotemVolumeButton *button = TOTEM_VOLUME_BUTTON (widget);
+  GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (button->scale));
+  float d;
+
+  if (event->type != GDK_SCROLL)
+    return FALSE;
+
+  d = totem_volume_button_get_value (button);
+  if (event->direction == GDK_SCROLL_UP) {
+    d += 5;
+    if (d > adj->upper)
+      d = adj->upper;
+  } else {
+    d -= 5;
+    if (d < adj->lower)
+      d = adj->lower;
+  }
+  totem_volume_button_set_value (button, d);
+
+  return TRUE;
+}
+
+static gboolean
+totem_volume_button_press (GtkWidget      * widget,
+			   GdkEventButton * event)
+{
+  TotemVolumeButton *button = TOTEM_VOLUME_BUTTON (widget);
+  GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (button->scale));
+  gint x, y, m, dx, dy, sx, sy, v, ystartoff;
+  GdkEventButton *e;
+
+  /* position roughly */
+  gdk_window_get_origin (widget->window, &x, &y);
+  gtk_window_move (GTK_WINDOW (button->dock), x, y - 50);
+  gtk_widget_show_all (button->dock);
+  gdk_window_get_origin (button->dock->window, &dx, &dy);
+  dy += button->dock->allocation.y;
+  gdk_window_get_origin (button->scale->window, &sx, &sy);
+  sy += button->scale->allocation.y;
+  ystartoff = sy - dy;
+  button->timeout = TRUE;
+
+  /* position (needs widget to be shown already) */
+  v = lrintf (totem_volume_button_get_value (button));
+  x += widget->allocation.x;
+  x += (widget->allocation.width - button->dock->allocation.width) / 2;
+  y += widget->allocation.y;
+  y -= ystartoff;
+  m = button->scale->allocation.height - widget->allocation.height;
+  y -= m;
+  y += m * v / adj->upper;
+  gtk_window_move (GTK_WINDOW (button->dock), x, y);
+  gdk_window_get_origin (button->scale->window, &sx, &sy);
+
+  GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event);
+
+  /* grab focus */
+  gtk_widget_grab_focus (button->dock);
+  gtk_grab_add (button->dock);
+  gdk_pointer_grab (button->dock->window, TRUE,
+      GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+      GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME);
+  gdk_keyboard_grab (button->dock->window, TRUE, GDK_CURRENT_TIME);
+
+  /* forward event to the slider */
+  e = (GdkEventButton *) gdk_event_copy ((GdkEvent *) event);
+  e->window = button->scale->window;
+  e->x = button->scale->allocation.width / 2;
+  /* FIXME: those magic numbers are numbers in the GtkScaleClass */
+  e->y = ((10 + (80 - v * 0.8)) / SCALE_SIZE) *
+      button->scale->allocation.height;
+  gtk_widget_event (button->scale, (GdkEvent *) e);
+  e->window = event->window;
+  gdk_event_free ((GdkEvent *) e);
+
+  button->pop_time = event->time;
+
+  return TRUE;
+}
+
+/*
+ * +/- button callbacks.
+ */
+
+static gboolean
+cb_button_timeout (gpointer data)
+{
+  TotemVolumeButton *button = TOTEM_VOLUME_BUTTON (data);
+  GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (button->scale));
+  float val;
+  gboolean res = TRUE;
+
+  if (button->click_id == 0)
+    return FALSE;
+
+  val = totem_volume_button_get_value (button);
+  val += button->direction;
+  if (val <= adj->lower) {
+    res = FALSE;
+    val = adj->lower;
+  } else if (val > adj->upper) {
+    res = FALSE;
+    val = adj->upper;
+  }
+  totem_volume_button_set_value (button, val);
+
+  if (!res) {
+    g_source_remove (button->click_id);
+    button->click_id = 0;
+  }
+
+  return res;
+}
+
+static gboolean
+cb_button_press (GtkWidget      * widget,
+		 GdkEventButton * event,
+		 gpointer         data)
+{
+  TotemVolumeButton *button = TOTEM_VOLUME_BUTTON (data);
+  GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (button->scale));
+
+  if (button->click_id != 0)
+    g_source_remove (button->click_id);
+  button->direction = (widget == button->plus) ?
+      abs (adj->page_increment) : - abs (adj->page_increment);
+  button->click_id = g_timeout_add (CLICK_TIMEOUT,
+				    (GSourceFunc) cb_button_timeout, button);
+  cb_button_timeout (button);
+
+  return TRUE;
+}
+
+static gboolean
+cb_button_release (GtkWidget      * widget,
+		   GdkEventButton * event,
+		   gpointer         data)
+{
+  TotemVolumeButton *button = TOTEM_VOLUME_BUTTON (data);
+
+  if (button->click_id != 0) {
+    g_source_remove (button->click_id);
+    button->click_id = 0;
+  }
+
+  return TRUE;
+}
+
+/*
+ * Scale callbacks.
+ */
+
+static void
+totem_volume_release_grab (TotemVolumeButton *button,
+			   GdkEventButton * event)
+{
+  GdkEventButton *e;
+
+  /* ungrab focus */
+  gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+  gdk_pointer_ungrab (GDK_CURRENT_TIME);
+  gtk_grab_remove (button->dock);
+
+  /* hide again */
+  gtk_widget_hide (button->dock);
+  button->timeout = FALSE;
+
+  e = (GdkEventButton *) gdk_event_copy ((GdkEvent *) event);
+  e->window = GTK_WIDGET (button)->window;
+  e->type = GDK_BUTTON_RELEASE;
+  gtk_widget_event (GTK_WIDGET (button), (GdkEvent *) e);
+  e->window = event->window;
+  gdk_event_free ((GdkEvent *) e);
+}
+
+static gboolean
+cb_dock_press (GtkWidget      * widget,
+	       GdkEventButton * event,
+	       gpointer         data)
+{
+  //GtkWidget *ewidget = gtk_get_event_widget ((GdkEvent *) event);
+  TotemVolumeButton *button = TOTEM_VOLUME_BUTTON (data);
+
+  if (/*ewidget == button->dock &&*/ event->type == GDK_BUTTON_PRESS) {
+    totem_volume_release_grab (button, event);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/*
+ * Scale stuff.
+ */
+
+#define TOTEM_TYPE_VOLUME_SCALE \
+  (totem_volume_scale_get_type ())
+#define TOTEM_VOLUME_SCALE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_VOLUME_SCALE, \
+			       TotemVolumeScale))
+
+typedef struct _TotemVolumeScale {
+  GtkVScale parent;
+  TotemVolumeButton *button;
+} TotemVolumeScale;
+
+static GType	totem_volume_scale_get_type	 (void);
+
+static void	totem_volume_scale_class_init    (GtkVScaleClass * klass);
+
+static gboolean	totem_volume_scale_press	 (GtkWidget      * widget,
+						  GdkEventButton * event);
+static gboolean totem_volume_scale_release	 (GtkWidget      * widget,
+						  GdkEventButton * event);
+static void	totem_volume_scale_value_changed (GtkRange      * range);
+
+static GtkVScaleClass *scale_parent_class = NULL;
+
+static GType
+totem_volume_scale_get_type (void)
+{
+  static GType totem_volume_scale_type = 0;
+
+  if (!totem_volume_scale_type) {
+    static const GTypeInfo totem_volume_scale_info = {
+      sizeof (GtkVScaleClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) totem_volume_scale_class_init,
+      NULL,
+      NULL,
+      sizeof (TotemVolumeScale),
+      0,
+      NULL,
+      NULL
+    };
+
+    totem_volume_scale_type =
+        g_type_register_static (GTK_TYPE_VSCALE,
+				"TotemVolumeScale",
+				&totem_volume_scale_info, 0);
+  }
+
+  return totem_volume_scale_type;
+}
+
+static void
+totem_volume_scale_class_init (GtkVScaleClass * klass)
+{
+  GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
+  GtkRangeClass *gtkrange_class = GTK_RANGE_CLASS (klass);
+
+  scale_parent_class = g_type_class_ref (GTK_TYPE_VSCALE);
+
+  gtkwidget_class->button_press_event = totem_volume_scale_press;
+  gtkwidget_class->button_release_event = totem_volume_scale_release;
+  gtkrange_class->value_changed = totem_volume_scale_value_changed;
+}
+
+static GtkWidget *
+totem_volume_scale_new (TotemVolumeButton * button,
+			float min, float max,
+			float step)
+{
+  TotemVolumeScale *scale = g_object_new (TOTEM_TYPE_VOLUME_SCALE, NULL);
+  GtkObject *adj;
+
+  adj = gtk_adjustment_new (min, min, max, step, 10 * step, 0);
+  gtk_range_set_adjustment (GTK_RANGE (scale), GTK_ADJUSTMENT (adj));
+  scale->button = button;
+
+  return GTK_WIDGET (scale);
+}
+
+static gboolean
+totem_volume_scale_press (GtkWidget      * widget,
+			  GdkEventButton * event)
+{
+  TotemVolumeScale *scale = TOTEM_VOLUME_SCALE (widget);
+  TotemVolumeButton *button = scale->button;
+
+  /* the scale will grab input; if we have input grabbed, all goes
+   * horribly wrong, so let's not do that. */
+  gtk_grab_remove (button->dock);
+
+  return GTK_WIDGET_CLASS (scale_parent_class)->button_press_event (widget, event);
+}
+
+static gboolean
+totem_volume_scale_release (GtkWidget      * widget,
+			    GdkEventButton * event)
+{
+  TotemVolumeScale *scale = TOTEM_VOLUME_SCALE (widget);
+  TotemVolumeButton *button = scale->button;
+  gboolean res;
+
+  if (button->timeout) {
+    /* if we did a quick click, leave the window open; else, hide it */
+    if (event->time > button->pop_time + CLICK_TIMEOUT) {
+      totem_volume_release_grab (button, event);
+      GTK_WIDGET_CLASS (scale_parent_class)->button_release_event (widget, event);
+      return TRUE;
+    }
+    button->timeout = FALSE;
+  }
+
+  res = GTK_WIDGET_CLASS (scale_parent_class)->button_release_event (widget, event);
+
+  /* the scale will release input; right after that, we *have to* grab
+   * it back so we can catch out-of-scale clicks and hide the popup,
+   * so I basically want a g_signal_connect_after_always(), but I can't
+   * find that, so we do this complex 'first-call-parent-then-do-actual-
+   * action' thingy... */
+  gtk_grab_add (button->dock);
+
+  return res;
+}
+
+static void
+totem_volume_scale_value_changed (GtkRange * range)
+{
+  TotemVolumeScale *scale = TOTEM_VOLUME_SCALE (range);
+  TotemVolumeButton *button = scale->button;
+  GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (button->scale));
+  int step = adj->upper / 4;
+  float val = gtk_range_get_value (range);
+#ifdef HAVE_GTK_ONLY
+  char *s;
+
+  /* update label */
+  s = g_strdup_printf ("%d", lrintf (val));
+  gtk_button_set_label (GTK_BUTTON (button), s);
+  g_free (s);
+#else
+  const char *s;
+  GdkPixbuf *buf;
+
+  if (val >= 0 && val < step)
+    s = "stock_volume-0";
+  else if (val >= step && val < step * 2)
+    s = "stock_volume-min";
+  else if (val >= step * 2 && val < step * 3)
+    s = "stock_volume-med";
+  else
+    s = "stock_volume-max";
+
+  /* update image */
+  buf = gtk_icon_theme_load_icon (button->theme, s, 16, 0, NULL);
+  gtk_image_set_from_pixbuf (GTK_IMAGE (button->image), buf);
+#endif
+
+  /* signal */
+  g_signal_emit (button, signals[SIGNAL_VALUE_CHANGED], 0);
+}
Index: totem/src/totem-volume.h
===================================================================
--- totem.orig/src/totem-volume.h	2005-07-12 09:50:33.563591112 +0200
+++ totem/src/totem-volume.h	2005-07-12 07:53:33.486489480 +0200
@@ -0,0 +1,68 @@
+/* Totem Volume Button / popup widget
+ * (c) copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ */
+
+#ifndef __BUTTON_H__
+#define __BUTTON_H__
+
+#include <gtk/gtkbutton.h>
+
+G_BEGIN_DECLS
+
+#define TOTEM_TYPE_VOLUME_BUTTON \
+  (totem_volume_button_get_type ())
+#define TOTEM_VOLUME_BUTTON(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_VOLUME_BUTTON, \
+			       TotemVolumeButton))
+
+typedef struct _TotemVolumeButton {
+  GtkButton parent;
+
+  /* popup */
+  GtkWidget *dock, *scale, *image, *plus, *min;
+  gint click_id, direction;
+  gboolean timeout;
+  guint32 pop_time;
+  GtkIconTheme *theme;
+} TotemVolumeButton;
+
+typedef struct _TotemVolumeButtonClass {
+  GtkButtonClass parent_class;
+
+  /* signals */
+  void	(* value_changed)	(TotemVolumeButton * button);
+
+  gpointer __bla[4];
+} TotemVolumeButtonClass;
+
+GType		totem_volume_button_get_type	(void);
+
+GtkWidget *	totem_volume_button_new		(float min, float max,
+						 float step);
+float		totem_volume_button_get_value	(TotemVolumeButton * button);
+void		totem_volume_button_set_value	(TotemVolumeButton * button,
+						 float value);
+
+G_END_DECLS
+
+#endif /* __BUTTON_H__ */
Index: totem/src/totem.c
===================================================================
--- totem.orig/src/totem.c	2005-07-11 10:41:19.000000000 +0200
+++ totem/src/totem.c	2005-07-12 08:21:54.470900544 +0200
@@ -58,6 +58,7 @@
 #include "totem-options.h"
 #include "totem-uri.h"
 #include "totem-interface.h"
+#include "totem-volume.h"
 #include "video-utils.h"
 
 #include "totem.h"
@@ -584,8 +585,6 @@
 
 		widget = glade_xml_get_widget (totem->xml, "tcw_title_label");
 		gtk_label_set_markup (GTK_LABEL (widget), text);
-		widget = glade_xml_get_widget (totem->xml, "tmw_title_label");
-		gtk_label_set_markup (GTK_LABEL (widget), text);
 
 		g_free (text);
 
@@ -605,8 +604,6 @@
 			 _("No File"));
 		widget = glade_xml_get_widget (totem->xml, "tcw_title_label");
 		gtk_label_set_markup (GTK_LABEL (widget), text);
-		widget = glade_xml_get_widget (totem->xml, "tmw_title_label");
-		gtk_label_set_markup (GTK_LABEL (widget), text);
 
 		g_free (text);
 
@@ -649,11 +646,7 @@
 		update_seekable (totem, FALSE);
 
 		/* Volume */
-		widget = glade_xml_get_widget (totem->xml, "tmw_volume_hbox");
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = glade_xml_get_widget (totem->xml, "tmw_volume_up_menu_item");
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = glade_xml_get_widget (totem->xml, "tmw_volume_down_menu_item");
+		widget = glade_xml_get_widget (totem->xml, "tcw_volume_button");
 		gtk_widget_set_sensitive (widget, FALSE);
 		widget = glade_xml_get_widget (totem->xml_popup, "trcm_volume_up");
 		gtk_widget_set_sensitive (widget, FALSE);
@@ -715,11 +708,7 @@
 
 		/* Volume */
 		caps = bacon_video_widget_can_set_volume (totem->bvw);
-		widget = glade_xml_get_widget (totem->xml, "tmw_volume_hbox");
-		gtk_widget_set_sensitive (widget, caps);
-		widget = glade_xml_get_widget (totem->xml, "tmw_volume_up_menu_item");
-		gtk_widget_set_sensitive (widget, caps);
-		widget = glade_xml_get_widget (totem->xml, "tmw_volume_down_menu_item");
+		widget = glade_xml_get_widget (totem->xml, "tcw_volume_button");
 		gtk_widget_set_sensitive (widget, caps);
 		widget = glade_xml_get_widget (totem->xml, "tcw_volume_hbox");
 		gtk_widget_set_sensitive (widget, caps);
@@ -1340,8 +1329,8 @@
 				totem->prev_volume != -1 && volume != -1))
 	{
 		totem->volume_first_time = 0;
-		gtk_adjustment_set_value (totem->voladj,
-				(float) volume);
+		totem_volume_button_set_value (
+			TOTEM_VOLUME_BUTTON (totem->volume), (float) volume);
 		gtk_adjustment_set_value (totem->fs_voladj,
 				(float) volume);
 	}
@@ -1421,17 +1410,16 @@
 				(totem->bvw, (gint) totem->fs_voladj->value);
 
 			/* Update the fullscreen volume adjustment */
-			gtk_adjustment_set_value (totem->voladj, 
-					gtk_adjustment_get_value
-					(totem->fs_voladj));
+			totem_volume_button_set_value (
+				TOTEM_VOLUME_BUTTON (totem->volume),
+				gtk_adjustment_get_value (totem->fs_voladj));
 		} else {
-			bacon_video_widget_set_volume
-				(totem->bvw, (gint) totem->voladj->value);
-			/* Update the volume adjustment */
-			gtk_adjustment_set_value (totem->fs_voladj, 
-					gtk_adjustment_get_value
-					(totem->voladj));
+			int value = totem_volume_button_get_value (
+				TOTEM_VOLUME_BUTTON (totem->volume));
 
+			bacon_video_widget_set_volume (totem->bvw, value);
+			/* Update the volume adjustment */
+			gtk_adjustment_set_value (totem->fs_voladj, value);
 		}
 
 		totem->vol_lock = FALSE;
@@ -2469,8 +2457,6 @@
 
 	item = glade_xml_get_widget (totem->xml, "tcw_hbox");
 	gtk_widget_show_all (item);
-	item = glade_xml_get_widget (totem->xml, "tmw_title_label");
-	gtk_widget_realize (item);
 	gdk_flush ();
 
 	move_popups (totem);
@@ -3035,13 +3021,7 @@
 			G_CALLBACK (on_previous_button_clicked), totem);
 	item = glade_xml_get_widget (totem->xml, "tmw_next_button");
 	g_signal_connect (G_OBJECT (item), "clicked", 
-			G_CALLBACK (on_next_button_clicked), totem);
-	item = glade_xml_get_widget (totem->xml, "tmw_volume_mute_button");
-	g_signal_connect (G_OBJECT (item), "clicked",
-			G_CALLBACK (on_volume_mute_button), totem);
-	item = glade_xml_get_widget (totem->xml, "tmw_volume_max_button");
-	g_signal_connect (G_OBJECT (item), "clicked",
-			G_CALLBACK (on_volume_max_button), totem);
+			  G_CALLBACK (on_next_button_clicked), totem);
 
 	/* Drag'n'Drop */
 	item = glade_xml_get_widget (totem->xml, "tmw_sidebar_button");
@@ -3361,6 +3341,17 @@
 	g_free (url);
 }
 
+GtkWidget *
+totem_volume_create (void)
+{
+	GtkWidget *widget;
+
+	widget = totem_volume_button_new (0, 100, -1);
+	gtk_widget_show (widget);
+
+	return widget;
+}
+
 int
 main (int argc, char **argv)
 {
@@ -3452,8 +3443,7 @@
 	totem->seek = glade_xml_get_widget (totem->xml, "tmw_seek_hscale");
 	totem->seekadj = gtk_range_get_adjustment (GTK_RANGE (totem->seek));
 	g_object_set_data (G_OBJECT (totem->seek), "fs", GINT_TO_POINTER (0));
-	totem->volume = glade_xml_get_widget (totem->xml, "tmw_volume_hscale");
-	totem->voladj = gtk_range_get_adjustment (GTK_RANGE (totem->volume));
+	totem->volume = glade_xml_get_widget (totem->xml, "tcw_volume_button");
 	g_object_set_data (G_OBJECT (totem->volume), "fs", GINT_TO_POINTER (0));
 	totem->exit_popup = glade_xml_get_widget
 		(totem->xml, "totem_exit_fullscreen_window");
