Index: src/backend/bacon-video-widget-gst-0.10.c
===================================================================
--- src/backend/bacon-video-widget-gst-0.10.c	(revision 5087)
+++ src/backend/bacon-video-widget-gst-0.10.c	(working copy)
@@ -3914,6 +3914,32 @@
       }
       break;
     }
+    case MEDIA_TYPE_DVB: {
+      GstElement *element;
+
+      element = gst_element_factory_make ("dvbbasebin", "test_dvb");
+      if (element != NULL) {
+        gchar* filename = g_strdup(g_getenv("GST_DVB_CHANNELS_CONF"));
+        if (filename == NULL) {
+          guint major, minor, micro, nano;
+          gst_version(&major, &minor, &micro, &nano);
+          filename = g_strdup_printf("%s/.gstreamer-%d.%d/dvb-channels.conf",
+            g_get_home_dir(), major, minor);
+        }
+        if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+          res = BVW_CAN_PLAY_SUCCESS;
+        }
+        else {
+          res = BVW_CAN_PLAY_MISSING_CHANNELS;
+        }
+        g_free(filename);
+        g_object_unref (element);
+      }
+      else {
+        res = BVW_CAN_PLAY_MISSING_PLUGINS;
+      }
+      break;
+    }
     case MEDIA_TYPE_CDDA:
     default:
       res = BVW_CAN_PLAY_UNSUPPORTED;
@@ -4009,11 +4035,84 @@
       mrls = (char **) g_ptr_array_free (array, FALSE);
       break;
     }
+    case MEDIA_TYPE_DVB:
+    {
+      gchar* filename;
+      gchar* contents;
+      GPtrArray *array;
+      GstElement *dvbelement;
+      GstBus *dvbbus;
+      GstPipeline * pipeline;
+      gchar adapter_type = 'U' /* unknown */;
+      /* let gstreamer know what adapter to use */
+      g_setenv("GST_DVB_ADAPTER", device, TRUE);
+      /* HACK: find out type of adapter so it filters out the channels
+       * based on the type of adapter.
+       */
+      dvbelement = gst_element_factory_make ("dvbsrc", "test_dvbsrc");
+      g_object_set (G_OBJECT(dvbelement), "adapter", atoi(device), NULL);
+      pipeline = GST_PIPELINE(gst_pipeline_new(""));
+      gst_bin_add(GST_BIN(pipeline), dvbelement);
+      gst_element_set_state (pipeline, GST_STATE_READY);
+      gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
+      dvbbus = gst_pipeline_get_bus (pipeline);
+      while (gst_bus_have_pending (dvbbus)) {
+        GstMessage* msg = gst_bus_pop (dvbbus);
+        if (msg->type == GST_MESSAGE_ELEMENT && msg->src == GST_OBJECT(dvbelement)) {
+          GstStructure *structure = msg->structure;
+          if (strcmp(gst_structure_get_name (structure), "dvb-adapter") == 0) {
+            const GValue* val = gst_structure_get_value (structure, "type");
+            if (val) {
+              if (strcmp(g_value_get_string (val), "DVB-T") == 0) {
+                adapter_type = 'T';
+              }
+              else if (strcmp(g_value_get_string (val), "DVB-S") == 0) {
+                adapter_type = 'S';
+              }
+            }
+            gst_message_unref (msg);
+            break;
+          }
+        }
+        gst_message_unref (msg);
+      }
+      g_object_unref (dvbbus);
+      gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_NULL);
+      g_object_unref (G_OBJECT(pipeline));
+      filename = g_strdup(g_getenv("GST_DVB_CHANNELS_CONF"));
+      if (filename == NULL) {
+        guint major, minor, micro, nano;
+        gst_version(&major, &minor, &micro, &nano);
+        filename = g_strdup_printf("%s/.gstreamer-%d.%d/dvb-channels.conf",
+          g_get_home_dir(), major, minor);
+      }
+      if (g_file_get_contents (filename, &contents, NULL, NULL)) {
+        gchar** lines = g_strsplit (contents, "\n", 0);
+        int i = 0;
+        gchar* line = lines[0];
+        array = g_ptr_array_new ();
 
-    case MEDIA_TYPE_DVB: {
-      //FIXME
+        while (line != NULL) {
+          if (line[0] != '#') {
+            gchar** fields = g_strsplit(line, ":", 0);
+            if ((g_strv_length (fields) == 13 && adapter_type == 'T') ||
+                (g_strv_length (fields) == 8 && adapter_type == 'S')) {
+              g_ptr_array_add (array, g_strdup_printf("dvb://%s", fields[0]));
+            }
+            g_strfreev(fields);
+          }
+          line = lines[++i];
+        }
+        g_strfreev(lines);
+      }
+      else {
+        return NULL;
+      }
+      if (array->len >= 1)
+      	g_ptr_array_add (array, NULL);
+      mrls = (char **) g_ptr_array_free (array, FALSE);
+      break;
     }
-
     default:
       mrls = NULL;
       break;
Index: src/totem-menu.c
===================================================================
--- src/totem-menu.c	(revision 5087)
+++ src/totem-menu.c	(working copy)
@@ -743,6 +743,14 @@
 	totem_action_play_media_device (totem, device_path);
 }
 
+/* Play DVB menu items */
+
+static void
+on_play_dvb_activate (GtkAction *action, Totem *totem)
+{
+	gchar* adapter = g_object_get_data (G_OBJECT (action), "adapter");
+	totem_action_play_media (totem, MEDIA_TYPE_DVB, adapter);
+}
 /* A GnomeVFSDrive and GnomeVFSVolume share many similar methods, but do not
    share a base class other than GObject. */
 static char *
@@ -896,6 +904,33 @@
 		position++;
 		add_device_to_menu (i->data, position, totem);
 	}
+
+	/* check for DVB */
+	{
+	  int i;
+	  for(i=0;i<8;i++) {
+	    gchar* devicenode;
+	    devicenode = g_strdup_printf("/dev/dvb/adapter%d/frontend0", i);
+	    if (g_file_test (devicenode, G_FILE_TEST_EXISTS)) {
+              gchar* label = g_strdup_printf (_("Play DVB Adapter %d"), i);
+              gchar *name = g_strdup_printf (_("dvbdevice%d"), i);
+              GtkAction* action = gtk_action_new (name, label, NULL, NULL);
+	      g_object_set(G_OBJECT(action), "sensitive", TRUE, NULL);
+              gtk_action_group_add_action (totem->devices_action_group, action);
+              g_object_unref (action);
+	      gtk_ui_manager_add_ui (totem->ui_manager, totem->devices_ui_id,
+                  "/tmw-menubar/movie/devices-placeholder", name, name,
+                  GTK_UI_MANAGER_MENUITEM, FALSE);
+              g_object_set_data_full (G_OBJECT (action),
+                  "adapter", g_strdup_printf("%d", i), g_free);
+	      g_signal_connect (G_OBJECT (action), "activate",
+                  G_CALLBACK (on_play_dvb_activate), totem);
+
+            }
+	    g_free(devicenode);
+	  }
+          
+        }
 	gtk_ui_manager_ensure_update (totem->ui_manager);
 
 	g_list_foreach (devices, (GFunc) g_object_unref, NULL);
