[Telepathy-commits] [mingle/master] Add minimal Gtk+ UI and remove some dead code

Sjoerd Simons sjoerd at luon.net
Sat Nov 8 14:22:51 PST 2008


---
 mingle-client.py |  122 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/mingle-client.py b/mingle-client.py
index 18bd31b..18d6296 100644
--- a/mingle-client.py
+++ b/mingle-client.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 
 import sys
 
@@ -14,6 +15,102 @@ import util
 from client import create_client
 from jingle import make_sid
 import farsight
+import threading
+
+try:
+    import pygtk
+    pygtk.require("2.0")
+
+    import gtk, gtk.glade, gobject, gtk.gdk
+    import gobject
+except ImportError, e:
+    raise SystemExit("PyGTK couldn't be found ! (%s)" % (e[0]))
+
+try:
+    import pygst
+    pygst.require('0.10')
+
+    import gst
+except ImportError, e:
+    raise SystemExit("Gst-Python couldn't be found! (%s)" % (e[0]))
+
+
+class VideoSink(gtk.DrawingArea):
+    def __init__(self, pipeline):
+        gtk.DrawingArea.__init__(self)
+        self.set_size_request (320, 240)
+        self.sink = gst.element_factory_make("xvimagesink")
+        self.sink.set_property("force-aspect-ratio", True)
+        bus = pipeline.get_bus()
+        bus.enable_sync_message_emission()
+        bus.connect("sync-message", self.sync_handler)
+
+        self.exposedc = threading.Condition()
+        self.exposed = False
+
+        self.connect ("expose-event", self.expose_event)
+
+    def expose_event(self, *args):
+        if not self.exposed:
+            self.exposedc.acquire()
+            self.exposed = True
+            self.exposedc.notify()
+            self.exposedc.release()
+
+    def sync_handler(self, bus, message):
+        if message.src == self.sink and \
+            message.type == gst.MESSAGE_ELEMENT and \
+            message.structure.has_name("prepare-xwindow-id"):
+
+
+            self.exposedc.acquire()
+            while not self.exposed:
+                self.exposedc.wait()
+            gtk.gdk.threads_enter()
+            self.sink.set_xwindow_id (self.window.xid)
+            gtk.gdk.threads_leave()
+            self.exposedc.release()
+
+            return gst.BUS_DROP
+
+        return gst.BUS_PASS
+
+
+class UI(gtk.Window):
+    def __init__(self, jid, conference):
+        gtk.Window.__init__(self)
+        self.connect('destroy', lambda x: reactor.stop())
+        #self.set_size_request(320, 240)
+        self.hbox = gtk.HBox()
+        self.add(self.hbox)
+
+        self.label = gtk.Label("Waiting for video streams...")
+        self.hbox.add(self.label)
+        self.conference = conference
+        self.set_title(jid.userhost())
+
+        self.show_all()
+
+    def add_video_output(self, label, pad):
+        gtk.gdk.threads_enter()
+        if self.label:
+            self.hbox.remove(self.label)
+            self.label = None
+
+        frame = gtk.Frame(label)
+        frame.set_border_width(3)
+        vsink = VideoSink(self.conference)
+
+        self.hbox.add(frame)
+        frame.add(vsink)
+        frame.show_all()
+
+        vsink.sink.set_state(gst.STATE_PLAYING)
+        self.conference.add(vsink.sink)
+        vsink.sink.set_state(gst.STATE_PLAYING)
+        pad.link(vsink.sink.get_pad("sink"))
+
+        gtk.gdk.threads_leave()
 
 class Muc:
     PREPARING = 0
@@ -42,6 +139,9 @@ class Muc:
 
         client.send_presence()
 
+        self.conference.streamAdded.addCallback(False, self.new_stream)
+        self.ui = UI(client.jid, self.conference)
+
         client.add_iq_handler('set', ns.JINGLE, 'jingle',
             self.jingle_iq_received)
 
@@ -55,6 +155,14 @@ class Muc:
         return session.handle_session_initiate (iq,
             self.client.get_contact (JID(iq['from'])))
 
+    def new_stream(self, participant, stream):
+        if stream.session.type == farsight.MEDIA_TYPE_VIDEO:
+            stream.src_pad_hook  = lambda stream, fsstream, pad, codec: \
+                self.new_video_output(participant, stream, pad, codec)
+
+    def new_video_output(self, participant, stream, pad, codec):
+        self.ui.add_video_output(participant.cname, pad)
+
     def join(self):
         self.state = Muc.JOINING
         self.client.stream.addObserver('/presence', self.presence)
@@ -69,16 +177,6 @@ class Muc:
 
         self.mingle_presences[from_jid] = stanza
 
-        # Store others mingle descriptions, we can't send disco request untill
-        # after joining the muc
-
-        #print "initiating session with %s" % from_
-        #from_jid = JID(from_)
-        #contact = self.client.contacts[from_jid.userhost()][from_jid.resource]
-
-        #d = contact.get_capabilities()
-        #d.addCallback(self.got_caps, contact, stanza)
-
     def update_presence(self, mingle = None):
         join = domish.Element((None, 'presence'))
         join['to'] = self.my_jid.full()
@@ -136,7 +234,6 @@ class Muc:
             contact = self.client.get_contact (jid)
             session.initiate(contact)
 
-
     def participant_got_stream (self, stream, session, description):
         payloads = xpath.queryForNodes(
             '/description/payload-type', description)
@@ -236,5 +333,8 @@ def main(argv):
     return 0
 
 if __name__ == '__main__':
+    gobject.threads_init()
+    gtk.gdk.threads_init()
+
     sys.exit(main(sys.argv))
 
-- 
1.5.6.5




More information about the Telepathy-commits mailing list