summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Kukkonen <jussi.kukkonen@intel.com>2013-03-10 21:36:53 +0200
committerMark Ryan <mark.d.ryan@intel.com>2013-03-18 11:11:07 +0100
commit5d8f94979e86a1d87d86e757f811fa6ea797d60e (patch)
tree19cb9321efb21c06e3f60b746dcc96fb215f8b49
parentdbbaee7797e655b63da353db7a0c7147970f8495 (diff)
downloaddleyna-control-5d8f94979e86a1d87d86e757f811fa6ea797d60e.tar.gz
[Gtk] Upgrade to Gtk+3, GStreamer 1.0 and python-gi
This includes: * Player (manual) drawing changed to use Cairo * GenericModel now directly inherits from TreeModel * lots of syntax changes Fixes #13. Fixes #14. Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
-rwxr-xr-xsrc/dleyna-control.py13
-rw-r--r--src/msd/msd_browse.py6
-rw-r--r--src/msd/msd_generic_model.py111
-rw-r--r--src/msd/msd_main_window.py71
-rw-r--r--src/msd/msd_player.py156
-rw-r--r--src/msd/msd_search.py6
-rw-r--r--src/msd/msd_utils.py8
7 files changed, 196 insertions, 175 deletions
diff --git a/src/dleyna-control.py b/src/dleyna-control.py
index 5ef0973..9b5c4f0 100755
--- a/src/dleyna-control.py
+++ b/src/dleyna-control.py
@@ -20,10 +20,10 @@
# Mark Ryan <mark.d.ryan@intel.com>
#
-import pygtk
-pygtk.require('2.0')
-import gtk
-import glib
+import gi
+gi.require_version('Gtk', '3.0')
+gi.require_version('Gst', '1.0')
+from gi.repository import GObject, Gtk, Gst
import dbus
import dbus.service
import dbus.mainloop.glib
@@ -31,7 +31,8 @@ import dbus.mainloop.glib
from msd.msd_main_window import *
if __name__ == "__main__":
- gtk.gdk.threads_init()
+ GObject.threads_init()
+ Gst.init(None)
try:
del os.environ["http_proxy"];
except Exception, e:
@@ -39,4 +40,4 @@ if __name__ == "__main__":
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
state = State()
main_window = MainWindow(state)
- gtk.main()
+ Gtk.main()
diff --git a/src/msd/msd_browse.py b/src/msd/msd_browse.py
index 2bb1b56..888b8fa 100644
--- a/src/msd/msd_browse.py
+++ b/src/msd/msd_browse.py
@@ -19,9 +19,9 @@
# Jussi Kukkonen <jussi.kukkonen@intel.com>
#
-import pygtk
-pygtk.require('2.0')
-import gtk
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
from msd_generic_model import *
from msd_sort_order import *
diff --git a/src/msd/msd_generic_model.py b/src/msd/msd_generic_model.py
index b13b9d1..eb15933 100644
--- a/src/msd/msd_generic_model.py
+++ b/src/msd/msd_generic_model.py
@@ -24,9 +24,10 @@
# def _fetch_items(self, start, count)
# which needs to make sure _on_reply() or _on_error() is called.
-import pygtk
-pygtk.require('2.0')
-import gtk
+import sys
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import GLib, GObject, Gtk
import dateutil.parser
from msd_upnp import *
@@ -90,7 +91,7 @@ class _ResultArray(dict):
return dict.__len__(self)
-class GenericModel(gtk.GenericTreeModel):
+class GenericModel(GObject.GObject, Gtk.TreeModel):
# columns
COL_DISPLAY_NAME = 0
COL_ARTIST = 1
@@ -203,18 +204,20 @@ class GenericModel(gtk.GenericTreeModel):
return self.__length_is_known
def __on_inserted (self, row):
- path = (row,)
+ path = Gtk.TreePath((row,))
self.row_inserted (path, self.get_iter (path))
def __on_changed (self, row):
- path = (row,)
+ path = Gtk.TreePath((row,))
self.row_changed (path, self.get_iter (path))
def __on_deleted (self, row):
- self.row_deleted ((row,))
+ self.row_deleted (Gtk.TreePath((row,)))
def __init__(self):
- gtk.GenericTreeModel.__init__(self)
+ GObject.GObject.__init__(self)
+
+ self.__stamp = GLib.random_int_range(-2147483648, 2147483647)
empty_array = ["Loading...",None, None, None, None, False]
self.__items = _ResultArray(empty_array,
on_inserted = self.__on_inserted,
@@ -257,57 +260,71 @@ class GenericModel(gtk.GenericTreeModel):
self.__items.set_length(0 + self.__static_items)
self.set_request_range(0, GenericModel.max_items_per_fetch - 1)
- def on_get_flags(self):
- return gtk.TREE_MODEL_LIST_ONLY
+ def do_get_flags(self):
+ return Gtk.TreeModelFlags.LIST_ONLY
- def on_get_n_columns(self):
+ def do_get_n_columns(self):
return len(self.column_types)
- def on_get_column_type(self, n):
+ def do_get_column_type(self, n):
return self.column_types[n]
- def on_get_iter(self, path):
- # return internal row reference (key) for use in on_* methods
- retval = None
+ def do_get_iter(self, path):
+ # return iterator for use in other do_* methods.
+ # user_data is the index of the refered row.
if len(self.__items) > 0 and path[0] < len(self.__items):
- retval = path[0]
- return retval
+ tree_iter = Gtk.TreeIter()
+ tree_iter.stamp = self.__stamp
+ tree_iter.user_data = path[0]
+ return (True, tree_iter)
+ else:
+ return (False, None)
- def on_get_path(self, rowref):
- return (rowref, )
+ def do_get_path(self, tree_iter):
+ if tree_iter.user_data is None:
+ return Gtk.TreePath((None,))
+ return Gtk.TreePath((tree_iter.user_data,))
- def on_get_value(self, rowref, col):
+ def do_get_value(self, tree_iter, col):
try:
- return self.__items[rowref][col]
+ if (col == self.COL_LOADED):
+ return bool(self.__items[tree_iter.user_data][col])
+ elif self.__items[tree_iter.user_data][col] == None:
+ return ""
+ else:
+ return self.__items[tree_iter.user_data][col].encode('utf-8')
except KeyError:
return None
- def on_iter_next(self, rowref):
- retval = None
- if rowref + 1 < len(self.__items):
- retval = rowref + 1
- return retval
-
- def on_iter_children(self, rowref):
- retval = 0
- if rowref:
- retval = None
- return retval
+ def do_iter_next(self, tree_iter):
+ length = len(self.__items)
+ if tree_iter.user_data is None and length > 0:
+ # return iter to first row
+ tree_iter.user_data = 0
+ return (True, tree_iter)
+ elif tree_iter.user_data < length - 1:
+ # return iter to next row
+ tree_iter.user_data += 1
+ return (True, tree_iter)
+ else:
+ return (False, None)
- def on_iter_has_child(self, rowref):
+ def do_iter_has_child(self, tree_iter):
return False
- def on_iter_n_children(self, rowref):
- retval = 0
- if not rowref:
- retval = len(self.__items)
- return retval
-
- def on_iter_nth_child(self, rowref, child):
- retval = None
- if not rowref and child < len(self.__items):
- retval = child
- return retval
-
- def on_iter_parent(self, child):
- return None
+ def do_iter_n_children(self, parent_iter):
+ if parent_iter is None:
+ # special case: return number of top level children
+ return len(self.__items)
+ return 0
+
+ def do_iter_nth_child(self, parent_iter, n):
+ if parent_iter != None or n >= len(self.__items):
+ return (False, None)
+ tree_iter = Gtk.TreeIter()
+ tree_iter.stamp = self.__stamp
+ tree_iter.user_data = n
+ return (True, tree_iter)
+
+ def do_iter_parent(self, child_iter):
+ return (False, None)
diff --git a/src/msd/msd_main_window.py b/src/msd/msd_main_window.py
index 7801672..265d0b3 100644
--- a/src/msd/msd_main_window.py
+++ b/src/msd/msd_main_window.py
@@ -18,10 +18,9 @@
# Mark Ryan <mark.d.ryan@intel.com>
#
-import pygtk
-pygtk.require('2.0')
-import gtk
-import glib
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gdk, GdkPixbuf, Gtk
import dbus
import dbus.service
import dbus.mainloop.glib
@@ -43,17 +42,17 @@ class MainWindow(object):
def destroy(self, widget, data=None):
if self.__overlay:
self.__overlay.cancel_playback()
- gtk.main_quit()
+ Gtk.main_quit()
def __append_server_list_row(self, list_store, key, value):
name, image = value
if image:
image = image.get_pixbuf()
- image = image.scale_simple(32, 32, gtk.gdk.INTERP_BILINEAR)
+ image = image.scale_simple(32, 32, GdkPixbuf.InterpType.BILINEAR)
return list_store.append([image, name, key])
def __create_server_list_store(self):
- list_store = gtk.ListStore(gtk.gdk.Pixbuf, str, str)
+ list_store = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str)
for key, value in self.__state.get_server_list().iteritems():
self.__append_server_list_row(list_store, key, value)
return list_store
@@ -92,16 +91,16 @@ class MainWindow(object):
def __create_server_list(self, table):
liststore = self.__create_server_list_store()
- treeview = gtk.TreeView(liststore)
+ treeview = Gtk.TreeView(liststore)
treeview.set_headers_visible(True)
- column = gtk.TreeViewColumn()
+ column = Gtk.TreeViewColumn()
column.set_title("Servers")
- renderer = gtk.CellRendererPixbuf()
- column.pack_start(renderer, expand=False)
+ renderer = Gtk.CellRendererPixbuf()
+ column.pack_start(renderer, False)
column.add_attribute(renderer, 'pixbuf', 0)
- renderer = gtk.CellRendererText()
- column.pack_start(renderer, expand=False)
+ renderer = Gtk.CellRendererText()
+ column.pack_start(renderer, False)
column.add_attribute(renderer, 'text', 1)
treeview.append_column(column)
@@ -109,8 +108,8 @@ class MainWindow(object):
treeview.get_selection().connect("changed", self.__server_selected)
- scrollwin = gtk.ScrolledWindow()
- scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC);
+ scrollwin = Gtk.ScrolledWindow()
+ scrollwin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
scrollwin.add(treeview)
table.attach(scrollwin, left_attach=0, right_attach=1,
top_attach=0, bottom_attach=1)
@@ -126,7 +125,7 @@ class MainWindow(object):
model.flush()
tv.set_model(model)
- def __cell_data_func(self, column, cell, model, tree_iter):
+ def __cell_data_func(self, column, cell, model, tree_iter, userdata):
path = model.get_path (tree_iter)
requested_range = model.get_request_range()
@@ -152,9 +151,9 @@ class MainWindow(object):
model.set_request_range(max(0, start), end)
def __create_column(self, treeview, name, col, width, sort_by, cell_data_func=None):
- renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(name, renderer)
- column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+ renderer = Gtk.CellRendererText()
+ column = Gtk.TreeViewColumn(name, renderer)
+ column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
column.set_fixed_width(width)
column.add_attribute(renderer, 'text', col)
column.connect("clicked", self.__column_clicked, sort_by)
@@ -202,7 +201,7 @@ class MainWindow(object):
self.__window.add(self.__overlay.get_container())
def __create_common_list(self, store):
- treeview = gtk.TreeView(store)
+ treeview = Gtk.TreeView(store)
treeview.set_headers_visible(True)
treeview.set_fixed_height_mode(True)
@@ -214,20 +213,20 @@ class MainWindow(object):
treeview.set_headers_clickable(True)
treeview.set_rules_hint(True)
- scrollwin = gtk.ScrolledWindow()
- scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC);
+ scrollwin = Gtk.ScrolledWindow()
+ scrollwin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
scrollwin.add(treeview)
return (scrollwin, treeview)
def __create_browse_view(self, notebook):
- tree_store = gtk.TreeStore(str, str, str, str)
+ tree_store = Gtk.TreeStore(str, str, str, str)
scrollwin, treeview = self.__create_common_list(tree_store)
treeview.connect("row-activated", self.__content_clicked)
self.__browse_view = treeview;
- notebook.append_page(scrollwin, gtk.Label("Browse"))
+ notebook.append_page(scrollwin, Gtk.Label(label="Browse"))
def __create_search_list(self, container):
- list_store = gtk.ListStore(str, str, str, str)
+ list_store = Gtk.ListStore(str, str, str, str)
scrollwin, treeview = self.__create_common_list(list_store)
container.pack_start(scrollwin, True, True, 0)
treeview.connect("row-activated", self.__content_clicked)
@@ -238,15 +237,15 @@ class MainWindow(object):
self.__server_selected(self.__server_view.get_selection())
def __create_check_box(self, title, container):
- cb = gtk.CheckButton(title)
+ cb = Gtk.CheckButton(title)
cb.set_active(True)
cb.connect("toggled", self.__search_criteria_changed)
container.pack_start(cb, True, True, MainWindow.container_padding)
return cb
def __create_search_controls(self, container):
- label = gtk.Label("Search: ")
- self.__search_entry = gtk.Entry()
+ label = Gtk.Label(label="Search: ")
+ self.__search_entry = Gtk.Entry()
self.__search_entry.set_text("")
self.__search_entry.connect("activate", self.__search_criteria_changed)
container.pack_start(label, True, True, MainWindow.container_padding)
@@ -257,12 +256,13 @@ class MainWindow(object):
self.__videos = self.__create_check_box("Video", container)
def __create_search_view(self, notebook):
- vbox = gtk.VBox(False, 0)
- hbox = gtk.HBox(True, 0)
+ vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+ hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
+ homogeneous=True)
self.__create_search_list(vbox)
self.__create_search_controls(hbox)
vbox.pack_start(hbox, False, True, MainWindow.container_padding)
- notebook.append_page(vbox, gtk.Label("Search"))
+ notebook.append_page(vbox, Gtk.Label(label="Search"))
def __page_changed(self, notebook, page, page_number):
sel = self.__server_view.get_selection()
@@ -270,7 +270,7 @@ class MainWindow(object):
self.__change_server(page_number, sel)
def __create_notebook(self, table):
- notebook = gtk.Notebook()
+ notebook = Gtk.Notebook()
self.__create_search_view(notebook)
self.__create_browse_view(notebook)
notebook.connect("switch-page", self.__page_changed)
@@ -279,14 +279,14 @@ class MainWindow(object):
self.__notebook = notebook
def __create_widgets(self, window):
- table = gtk.Table(rows=1, columns=4, homogeneous=True)
+ table = Gtk.Table(rows=1, columns=4, homogeneous=True)
self.__create_server_list(table)
self.__create_notebook(table)
window.add(table)
self.__main_view = table
def __create_window(self):
- window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
window.set_title("Media Service Demo")
window.set_resizable(True)
window.set_default_size(640, 480)
@@ -319,6 +319,7 @@ class MainWindow(object):
self.__server_view.set_cursor(liststore.get_path(rowref))
def __init__(self, state):
+ self.__sort_order = SortOrder()
self.__search_path = None
self.__browse_path = None
self.__state = state
@@ -326,8 +327,6 @@ class MainWindow(object):
self.__state.set_found_server_cb(self.__found_server)
self.__create_window()
self.__overlay = None
- self.__sort_order = SortOrder()
-
liststore = self.__server_view.get_model()
rowref = liststore.get_iter_first()
if rowref:
diff --git a/src/msd/msd_player.py b/src/msd/msd_player.py
index 1a3a9e7..5d1ca97 100644
--- a/src/msd/msd_player.py
+++ b/src/msd/msd_player.py
@@ -18,13 +18,18 @@
# Mark Ryan <mark.d.ryan@intel.com>
#
-import pygtk
-pygtk.require('2.0')
-import glib
-import gtk
-import pygst
-pygst.require("0.10")
-import gst
+import gi
+gi.require_version('Gtk', '3.0')
+gi.require_version('Gdk', '3.0')
+gi.require_version('Gst', '1.0')
+from gi.repository import GLib, Gtk, Gst, Gdk, GdkPixbuf
+
+# For window.get_xid()
+from gi.repository import GdkX11
+
+# For xvimagesink.set_window_handle()
+from gi.repository import GstVideo
+
import datetime
from msd_utils import *
@@ -36,10 +41,11 @@ class PlayWindowBase(object):
self.__url = url
self.__close_window = close_window
- self.__container = gtk.VBox(False, 0)
- self.drawing_area = gtk.DrawingArea()
- self.private_area = gtk.VBox(True, 0)
- self.ok_button = gtk.Button("Close")
+ self.__container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+ self.drawing_area = Gtk.DrawingArea()
+ self.private_area = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
+ homogeneous=True)
+ self.ok_button = Gtk.Button("Close")
self.ok_button.connect("clicked", self.quit)
self.__container.pack_start(self.drawing_area, True, True, 0)
self.__container.pack_start(self.private_area, False, False, 0)
@@ -54,10 +60,9 @@ class PlayWindowBase(object):
def cancel_playback(self):
pass
- def draw_image(self, image):
+ def draw_image(self, image, context):
x = 0
y = 0
- gc = self.drawing_area.get_style().fg_gc[gtk.STATE_NORMAL]
rect = self.drawing_area.get_allocation()
width_scale = image.get_width() / float(rect.width)
height_scale = image.get_height() / float(rect.height)
@@ -78,9 +83,9 @@ class PlayWindowBase(object):
scaled_image = image.scale_simple(int(image.get_width() / divisor),
int(image.get_height() / divisor),
- gtk.gdk.INTERP_BILINEAR)
- self.drawing_area.window.draw_pixbuf(gc, scaled_image, 0, 0, x,
- y, -1, -1)
+ GdkPixbuf.InterpType.BILINEAR)
+ Gdk.cairo_set_source_pixbuf (context, scaled_image, x, y)
+ context.paint()
class PlayWindowImage(PlayWindowBase):
@@ -90,14 +95,15 @@ class PlayWindowImage(PlayWindowBase):
try:
image = image_from_file(url)
self.__image = image.get_pixbuf()
- self.drawing_area.connect("expose-event", self.__draw)
+ self.drawing_area.connect("draw", self.__draw)
except Exception:
pass
self.get_container().show_all()
- def __draw(self, area, event):
- self.draw_image(self.__image)
+ def __draw(self, widget, context):
+ if self.__image:
+ self.draw_image(self.__image, context)
return True
class GStreamerWindow(PlayWindowBase):
@@ -105,28 +111,28 @@ class GStreamerWindow(PlayWindowBase):
def __init__(self, name, url, close_window):
PlayWindowBase.__init__(self, name, url, close_window)
- self.player = gst.element_factory_make("playbin2", "player")
+ self.player = Gst.ElementFactory.make("playbin", "player")
gsbus = self.player.get_bus()
gsbus.add_signal_watch()
gsbus.connect("message", self.gs_message_cb)
self.player.set_property("uri", url)
- button_bar = gtk.HBox(False, 6)
-
- align = gtk.Alignment(0.5, 0.5, 0.0, 0.0)
+ button_bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
+ spacing=6)
+ align = Gtk.Alignment.new(0.5, 1.0, 0.0, 0.0)
button_bar.pack_start(align, False, False, 0)
- self.__play_pause_button = gtk.Button()
+ self.__play_pause_button = Gtk.Button()
self.__play_pause_button.connect("clicked", self.__play_pause)
- self.__play_pause_image = gtk.Image()
- self.__play_pause_image.set_from_stock(gtk.STOCK_MEDIA_PAUSE,
- gtk.ICON_SIZE_BUTTON)
+ self.__play_pause_image = Gtk.Image()
+ self.__play_pause_image.set_from_stock(Gtk.STOCK_MEDIA_PAUSE,
+ Gtk.IconSize.BUTTON)
self.__play_pause_button.add(self.__play_pause_image)
align.add(self.__play_pause_button)
- self.__scale = gtk.HScale()
- self.__adjustment = gtk.Adjustment(0, 0, 0,
+ self.__scale = Gtk.HScale()
+ self.__adjustment = Gtk.Adjustment(0, 0, 0,
1.0, 30.0, 1.0)
self.__adjustment.connect("value-changed", self.__adjusted)
self.__scale.set_adjustment(self.__adjustment)
@@ -137,38 +143,35 @@ class GStreamerWindow(PlayWindowBase):
self.get_container().show_all()
self.__update_pos_id = 0
- self.__state = gst.STATE_NULL
- self.player.set_state(gst.STATE_PLAYING)
+ self.__state = Gst.State.NULL
+ self.player.set_state(Gst.State.PLAYING)
def __play_pause(self, button):
- if (self.__state == gst.STATE_PLAYING):
- self.player.set_state(gst.STATE_PAUSED)
+ if (self.__state == Gst.State.PLAYING):
+ self.player.set_state(Gst.State.PAUSED)
else:
- self.player.set_state(gst.STATE_PLAYING)
+ self.player.set_state(Gst.State.PLAYING)
def __update_pos(self, user_data=None):
- try:
- pos = self.player.query_position(gst.FORMAT_TIME, None)[0]
- if pos != -1:
- pos = pos / 1000000000.0
- self.__adjustment.handler_block_by_func(self.__adjusted)
- self.__adjustment.set_value(pos)
- self.__adjustment.handler_unblock_by_func(self.__adjusted)
- except Exception:
- pass
+ success, pos = self.player.query_position(Gst.Format.TIME)
+ if success:
+ pos = pos / 1000000000.0
+ self.__adjustment.handler_block_by_func(self.__adjusted)
+ self.__adjustment.set_value(pos)
+ self.__adjustment.handler_unblock_by_func(self.__adjusted)
return True
def cancel_playback(self):
- self.player.set_state(gst.STATE_NULL)
+ self.player.set_state(Gst.State.NULL)
def quit(self, button):
- self.player.set_state(gst.STATE_NULL)
+ self.player.set_state(Gst.State.NULL)
PlayWindowBase.quit(self, button)
def __seek (self, position):
- self.player.seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH,
- gst.SEEK_TYPE_SET, position,
- gst.SEEK_TYPE_NONE, -1.0)
+ self.player.seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH,
+ Gst.SeekType.SET, position,
+ Gst.SeekType.NONE, -1.0)
def __adjusted(self, adjustment):
self.__seek(adjustment.get_value() * 1000000000.0)
@@ -182,37 +185,34 @@ class GStreamerWindow(PlayWindowBase):
return
self.__state = state
- if (self.__state > gst.STATE_NULL and
+ if (self.__state > Gst.State.NULL and
self.__adjustment.get_upper() == 0.0):
- try:
- duration = self.player.query_duration(gst.FORMAT_TIME, None)
- if duration[0] != -1:
- self.__adjustment.set_upper(duration[0] / 1000000000)
- except Exception:
- pass
-
- if self.__state == gst.STATE_PLAYING:
- self.__play_pause_image.set_from_stock(gtk.STOCK_MEDIA_PAUSE,
- gtk.ICON_SIZE_BUTTON)
+ success, duration = self.player.query_duration(Gst.Format.TIME)
+ if success:
+ self.__adjustment.set_upper(duration / 1000000000)
+
+ if self.__state == Gst.State.PLAYING:
+ self.__play_pause_image.set_from_stock(Gtk.STOCK_MEDIA_PAUSE,
+ Gtk.IconSize.BUTTON)
if self.__update_pos_id == 0:
- self.__update_pos_id = glib.timeout_add(500,
+ self.__update_pos_id = GLib.timeout_add(500,
self.__update_pos,
None)
else:
- self.__play_pause_image.set_from_stock(gtk.STOCK_MEDIA_PLAY,
- gtk.ICON_SIZE_BUTTON)
+ self.__play_pause_image.set_from_stock(Gtk.STOCK_MEDIA_PLAY,
+ Gtk.IconSize.BUTTON)
if self.__update_pos_id != 0:
- glib.source_remove(self.__update_pos_id)
+ GLib.source_remove(self.__update_pos_id)
self.__update_pos_id = 0
def gs_message_cb(self, bus, message):
- if message.type == gst.MESSAGE_EOS or message.type == gst.MESSAGE_ERROR:
+ if message.type == Gst.MessageType.EOS or message.type == Gst.MessageType.ERROR:
self.__seek(0)
- self.player.set_state(gst.STATE_PAUSED)
- elif message.type == gst.MESSAGE_STATE_CHANGED:
+ self.player.set_state(Gst.State.PAUSED)
+ elif message.type == Gst.MessageType.STATE_CHANGED:
(old, state, pending) = message.parse_state_changed()
self.__update_ui (state)
- elif message.type == gst.MESSAGE_ASYNC_DONE:
+ elif message.type == Gst.MessageType.ASYNC_DONE:
self.__update_pos()
class PlayWindowAudio(GStreamerWindow):
@@ -224,28 +224,32 @@ class PlayWindowAudio(GStreamerWindow):
try:
image = image_from_file(album_art_url)
self.__image = image.get_pixbuf()
- self.drawing_area.connect("expose-event", self.__draw)
+ self.drawing_area.connect("draw", self.__draw)
except Exception:
pass
- def __draw(self, area, event):
- self.draw_image(self.__image)
+ def __draw(self, widget, context):
+ if self.__image:
+ self.draw_image(self.__image, context)
return True
class PlayWindowVideo(GStreamerWindow):
+ def __on_realize(self, widget):
+ self.__xid = self.drawing_area.get_property('window').get_xid()
+
def __init__(self, name, url, close_window):
GStreamerWindow.__init__(self, name, url, close_window)
+ # get window XID when widget is realized
+ self.__xid = None
+ self.drawing_area.connect ("realize", self.__on_realize)
+
gsbus = self.player.get_bus()
gsbus.enable_sync_message_emission()
gsbus.connect("sync-message::element", self.gs_sync_message_cb)
-
def gs_sync_message_cb(self, bus, message):
- if message.structure != None and (message.structure.get_name() ==
- "prepare-xwindow-id"):
+ if message.get_structure().get_name() == "prepare-window-handle":
message.src.set_property("force-aspect-ratio", True)
- gtk.gdk.threads_enter()
- message.src.set_xwindow_id(self.drawing_area.window.xid)
- gtk.gdk.threads_leave()
+ message.src.set_window_handle(self.__xid)
diff --git a/src/msd/msd_search.py b/src/msd/msd_search.py
index 82356c6..22a766d 100644
--- a/src/msd/msd_search.py
+++ b/src/msd/msd_search.py
@@ -19,9 +19,9 @@
# Jussi Kukkonen <jussi.kukkonen@intel.com>
#
-import pygtk
-pygtk.require('2.0')
-import gtk
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
import cStringIO
from msd_generic_model import *
diff --git a/src/msd/msd_utils.py b/src/msd/msd_utils.py
index e55d17d..35fd266 100644
--- a/src/msd/msd_utils.py
+++ b/src/msd/msd_utils.py
@@ -19,9 +19,9 @@
#
import tempfile
-import pygtk
-pygtk.require('2.0')
-import gtk
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
import urllib2
import os
@@ -33,7 +33,7 @@ def image_from_file(url):
with tmpfile:
message = urllib2.urlopen(url, None, 15)
tmpfile.write(message.read())
- image = gtk.Image()
+ image = Gtk.Image()
image.set_from_file(tmpfile.name)
finally:
os.unlink(tmpFileName)