1 /* 2 * libjingle 3 * Copyright 2012, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <gtk/gtk.h> 29 30 #include "talk/examples/peerconnection/client/conductor.h" 31 #include "talk/examples/peerconnection/client/flagdefs.h" 32 #include "talk/examples/peerconnection/client/linux/main_wnd.h" 33 #include "talk/examples/peerconnection/client/peer_connection_client.h" 34 35 #include "talk/base/ssladapter.h" 36 #include "talk/base/thread.h" 37 38 class CustomSocketServer : public talk_base::PhysicalSocketServer { 39 public: 40 CustomSocketServer(talk_base::Thread* thread, GtkMainWnd* wnd) 41 : thread_(thread), wnd_(wnd), conductor_(NULL), client_(NULL) {} 42 virtual ~CustomSocketServer() {} 43 44 void set_client(PeerConnectionClient* client) { client_ = client; } 45 void set_conductor(Conductor* conductor) { conductor_ = conductor; } 46 47 // Override so that we can also pump the GTK message loop. 48 virtual bool Wait(int cms, bool process_io) { 49 // Pump GTK events. 50 // TODO: We really should move either the socket server or UI to a 51 // different thread. Alternatively we could look at merging the two loops 52 // by implementing a dispatcher for the socket server and/or use 53 // g_main_context_set_poll_func. 54 while (gtk_events_pending()) 55 gtk_main_iteration(); 56 57 if (!wnd_->IsWindow() && !conductor_->connection_active() && 58 client_ != NULL && !client_->is_connected()) { 59 thread_->Quit(); 60 } 61 return talk_base::PhysicalSocketServer::Wait(0/*cms == -1 ? 1 : cms*/, 62 process_io); 63 } 64 65 protected: 66 talk_base::Thread* thread_; 67 GtkMainWnd* wnd_; 68 Conductor* conductor_; 69 PeerConnectionClient* client_; 70 }; 71 72 int main(int argc, char* argv[]) { 73 gtk_init(&argc, &argv); 74 g_type_init(); 75 g_thread_init(NULL); 76 77 FlagList::SetFlagsFromCommandLine(&argc, argv, true); 78 if (FLAG_help) { 79 FlagList::Print(NULL, false); 80 return 0; 81 } 82 83 // Abort if the user specifies a port that is outside the allowed 84 // range [1, 65535]. 85 if ((FLAG_port < 1) || (FLAG_port > 65535)) { 86 printf("Error: %i is not a valid port.\n", FLAG_port); 87 return -1; 88 } 89 90 GtkMainWnd wnd(FLAG_server, FLAG_port, FLAG_autoconnect, FLAG_autocall); 91 wnd.Create(); 92 93 talk_base::AutoThread auto_thread; 94 talk_base::Thread* thread = talk_base::Thread::Current(); 95 CustomSocketServer socket_server(thread, &wnd); 96 thread->set_socketserver(&socket_server); 97 98 talk_base::InitializeSSL(); 99 // Must be constructed after we set the socketserver. 100 PeerConnectionClient client; 101 talk_base::scoped_refptr<Conductor> conductor( 102 new talk_base::RefCountedObject<Conductor>(&client, &wnd)); 103 socket_server.set_client(&client); 104 socket_server.set_conductor(conductor); 105 106 thread->Run(); 107 108 // gtk_main(); 109 wnd.Destroy(); 110 111 thread->set_socketserver(NULL); 112 // TODO: Run the Gtk main loop to tear down the connection. 113 //while (gtk_events_pending()) { 114 // gtk_main_iteration(); 115 //} 116 talk_base::CleanupSSL(); 117 return 0; 118 } 119 120