128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/* 2a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis * Copyright 2012 The WebRTC Project Authors. All rights reserved. 328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 4a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis * Use of this source code is governed by a BSD-style license 5a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis * that can be found in the LICENSE file in the root of the source 6a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis * tree. An additional intellectual property rights grant can be found 7a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis * in the file PATENTS. All contributing project authors may 8a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis * be found in the AUTHORS file in the root of the source tree. 928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 11a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis#include "webrtc/examples/peerconnection/client/linux/main_wnd.h" 1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <gdk/gdkkeysyms.h> 1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <gtk/gtk.h> 1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <stddef.h> 1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 17a8736448970fedd82f051c6b2cc89185b755ddf3Donald E Curtis#include "webrtc/examples/peerconnection/client/defaults.h" 18d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/common.h" 19d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/logging.h" 20d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/stringutils.h" 2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgusing rtc::sprintfn; 2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace { 2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// 2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Simple static functions that simply forward the callback to the 2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// GtkMainWnd instance. 2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// 3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orggboolean OnDestroyedCallback(GtkWidget* widget, GdkEvent* event, 3228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gpointer data) { 3328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org reinterpret_cast<GtkMainWnd*>(data)->OnDestroyed(widget, event); 3428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return FALSE; 3528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 3628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid OnClickedCallback(GtkWidget* widget, gpointer data) { 3828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org reinterpret_cast<GtkMainWnd*>(data)->OnClicked(widget); 3928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 4028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orggboolean SimulateButtonClick(gpointer button) { 4228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_signal_emit_by_name(button, "clicked"); 4328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 4428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 4528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orggboolean OnKeyPressCallback(GtkWidget* widget, GdkEventKey* key, 4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gpointer data) { 4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org reinterpret_cast<GtkMainWnd*>(data)->OnKeyPress(widget, key); 4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid OnRowActivatedCallback(GtkTreeView* tree_view, GtkTreePath* path, 5328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeViewColumn* column, gpointer data) { 5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org reinterpret_cast<GtkMainWnd*>(data)->OnRowActivated(tree_view, path, column); 5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orggboolean SimulateLastRowActivated(gpointer data) { 5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeView* tree_view = reinterpret_cast<GtkTreeView*>(data); 5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeModel* model = gtk_tree_view_get_model(tree_view); 6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // "if iter is NULL, then the number of toplevel nodes is returned." 6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int rows = gtk_tree_model_iter_n_children(model, NULL); 6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreePath* lastpath = gtk_tree_path_new_from_indices(rows - 1, -1); 6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Select the last item in the list 6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeSelection* selection = gtk_tree_view_get_selection(tree_view); 6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_selection_select_path(selection, lastpath); 6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Our TreeView only has one column, so it is column 0. 7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeViewColumn* column = gtk_tree_view_get_column(tree_view, 0); 7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_view_row_activated(tree_view, lastpath, column); 7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_path_free(lastpath); 7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Creates a tree view, that we use to display the list of peers. 7928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid InitializeList(GtkWidget* list) { 8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); 8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( 8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org "List Items", renderer, "text", 0, NULL); 8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); 8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); 8528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(store)); 8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_object_unref(store); 8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Adds an entry to a tree view. 9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid AddToList(GtkWidget* list, const gchar* str, int value) { 9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkListStore* store = GTK_LIST_STORE( 9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_view_get_model(GTK_TREE_VIEW(list))); 9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeIter iter; 9528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_list_store_append(store, &iter); 9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_list_store_set(store, &iter, 0, str, 1, value, -1); 9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstruct UIThreadCallbackData { 10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org explicit UIThreadCallbackData(MainWndCallback* cb, int id, void* d) 10128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : callback(cb), msg_id(id), data(d) {} 10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MainWndCallback* callback; 10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int msg_id; 10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org void* data; 10528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 10628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 10728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orggboolean HandleUIThreadCallback(gpointer data) { 10828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org UIThreadCallbackData* cb_data = reinterpret_cast<UIThreadCallbackData*>(data); 10928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cb_data->callback->UIThreadCallback(cb_data->msg_id, cb_data->data); 11028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org delete cb_data; 11128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 11228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 11328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 11428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orggboolean Redraw(gpointer data) { 11528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkMainWnd* wnd = reinterpret_cast<GtkMainWnd*>(data); 11628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org wnd->OnRedraw(); 11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 11828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 11970625e5bf3c91c57bf704d380bcc9df86575f08ajbauch 12070625e5bf3c91c57bf704d380bcc9df86575f08ajbauch} // namespace 12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// 12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// GtkMainWnd implementation. 12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// 12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgGtkMainWnd::GtkMainWnd(const char* server, int port, bool autoconnect, 12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool autocall) 12828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : window_(NULL), draw_area_(NULL), vbox_(NULL), server_edit_(NULL), 12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org port_edit_(NULL), peer_list_(NULL), callback_(NULL), 13028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org server_(server), autoconnect_(autoconnect), autocall_(autocall) { 13128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org char buffer[10]; 13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org sprintfn(buffer, sizeof(buffer), "%i", port); 13328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org port_ = buffer; 13428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 13528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 13628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgGtkMainWnd::~GtkMainWnd() { 13728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(!IsWindow()); 13828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 13928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 14028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::RegisterObserver(MainWndCallback* callback) { 14128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org callback_ = callback; 14228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 14328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 14428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool GtkMainWnd::IsWindow() { 14528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return window_ != NULL && GTK_IS_WINDOW(window_); 14628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 14728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 14828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::MessageBox(const char* caption, const char* text, 14928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool is_error) { 15028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(window_), 15128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GTK_DIALOG_DESTROY_WITH_PARENT, 15228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org is_error ? GTK_MESSAGE_ERROR : GTK_MESSAGE_INFO, 15328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GTK_BUTTONS_CLOSE, "%s", text); 15428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_window_set_title(GTK_WINDOW(dialog), caption); 15528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_dialog_run(GTK_DIALOG(dialog)); 15628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_destroy(dialog); 15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgMainWindow::UI GtkMainWnd::current_ui() { 16028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (vbox_) 16128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return CONNECT_TO_SERVER; 16228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (peer_list_) 16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return LIST_PEERS; 16528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return STREAMING; 16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::StartLocalRenderer(webrtc::VideoTrackInterface* local_video) { 17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org local_renderer_.reset(new VideoRenderer(this, local_video)); 17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 17328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 17428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::StopLocalRenderer() { 17528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org local_renderer_.reset(); 17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 17870625e5bf3c91c57bf704d380bcc9df86575f08ajbauchvoid GtkMainWnd::StartRemoteRenderer( 17970625e5bf3c91c57bf704d380bcc9df86575f08ajbauch webrtc::VideoTrackInterface* remote_video) { 18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org remote_renderer_.reset(new VideoRenderer(this, remote_video)); 18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::StopRemoteRenderer() { 18428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org remote_renderer_.reset(); 18528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 18628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 18728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::QueueUIThreadCallback(int msg_id, void* data) { 18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_idle_add(HandleUIThreadCallback, 18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org new UIThreadCallbackData(callback_, msg_id, data)); 19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool GtkMainWnd::Create() { 19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(window_ == NULL); 19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); 19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (window_) { 19728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_window_set_position(GTK_WINDOW(window_), GTK_WIN_POS_CENTER); 19828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_window_set_default_size(GTK_WINDOW(window_), 640, 480); 19928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_window_set_title(GTK_WINDOW(window_), "PeerConnection client"); 20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_signal_connect(G_OBJECT(window_), "delete-event", 20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org G_CALLBACK(&OnDestroyedCallback), this); 20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_signal_connect(window_, "key-press-event", G_CALLBACK(OnKeyPressCallback), 20328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org this); 20428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 20528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SwitchToConnectUI(); 20628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return window_ != NULL; 20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool GtkMainWnd::Destroy() { 21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!IsWindow()) 21328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 21428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 21528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_destroy(window_); 21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org window_ = NULL; 21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 21928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 22028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::SwitchToConnectUI() { 22228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(INFO) << __FUNCTION__; 22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(IsWindow()); 22528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(vbox_ == NULL); 22628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_set_border_width(GTK_CONTAINER(window_), 10); 22828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (peer_list_) { 23028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_destroy(peer_list_); 23128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org peer_list_ = NULL; 23228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 23328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 23428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org vbox_ = gtk_vbox_new(FALSE, 5); 23528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkWidget* valign = gtk_alignment_new(0, 1, 0, 0); 23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(vbox_), valign); 23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(window_), vbox_); 23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 23928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkWidget* hbox = gtk_hbox_new(FALSE, 5); 24028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkWidget* label = gtk_label_new("Server"); 24228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(hbox), label); 24328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org server_edit_ = gtk_entry_new(); 24528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_entry_set_text(GTK_ENTRY(server_edit_), server_.c_str()); 24628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_set_size_request(server_edit_, 400, 30); 24728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(hbox), server_edit_); 24828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org port_edit_ = gtk_entry_new(); 25028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_entry_set_text(GTK_ENTRY(port_edit_), port_.c_str()); 25128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_set_size_request(port_edit_, 70, 30); 25228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(hbox), port_edit_); 25328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 25428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkWidget* button = gtk_button_new_with_label("Connect"); 25528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_set_size_request(button, 70, 30); 25628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_signal_connect(button, "clicked", G_CALLBACK(OnClickedCallback), this); 25728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(hbox), button); 25828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 25928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkWidget* halign = gtk_alignment_new(1, 0, 0, 0); 26028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(halign), hbox); 26128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_box_pack_start(GTK_BOX(vbox_), halign, FALSE, FALSE, 0); 26228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 26328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_show_all(window_); 26428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 26528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (autoconnect_) 26628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_idle_add(SimulateButtonClick, button); 26728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 26828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 26928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::SwitchToPeerList(const Peers& peers) { 27028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(INFO) << __FUNCTION__; 27128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 27228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!peer_list_) { 27328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_set_border_width(GTK_CONTAINER(window_), 0); 27428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (vbox_) { 27528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_destroy(vbox_); 27628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org vbox_ = NULL; 27728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org server_edit_ = NULL; 27828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org port_edit_ = NULL; 27928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (draw_area_) { 28028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_destroy(draw_area_); 28128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_area_ = NULL; 28228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_buffer_.reset(); 28328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 28428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 28528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org peer_list_ = gtk_tree_view_new(); 28628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_signal_connect(peer_list_, "row-activated", 28728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org G_CALLBACK(OnRowActivatedCallback), this); 28828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(peer_list_), FALSE); 28928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org InitializeList(peer_list_); 29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(window_), peer_list_); 29128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_show_all(window_); 29228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 29328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkListStore* store = 29428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(peer_list_))); 29528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_list_store_clear(store); 29628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 29728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 29828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org AddToList(peer_list_, "List of currently connected peers:", -1); 29928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (Peers::const_iterator i = peers.begin(); i != peers.end(); ++i) 30028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org AddToList(peer_list_, i->second.c_str(), i->first); 30128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 30228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (autocall_ && peers.begin() != peers.end()) 30328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_idle_add(SimulateLastRowActivated, peer_list_); 30428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 30528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 30628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::SwitchToStreamingUI() { 30728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(INFO) << __FUNCTION__; 30828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 30928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(draw_area_ == NULL); 31028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 31128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_set_border_width(GTK_CONTAINER(window_), 0); 31228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (peer_list_) { 31328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_destroy(peer_list_); 31428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org peer_list_ = NULL; 31528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 31628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 31728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_area_ = gtk_drawing_area_new(); 31828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_container_add(GTK_CONTAINER(window_), draw_area_); 31928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 32028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_show_all(window_); 32128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 32228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 32328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::OnDestroyed(GtkWidget* widget, GdkEvent* event) { 32428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org callback_->Close(); 32528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org window_ = NULL; 32628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_area_ = NULL; 32728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org vbox_ = NULL; 32828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org server_edit_ = NULL; 32928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org port_edit_ = NULL; 33028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org peer_list_ = NULL; 33128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 33228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 33328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::OnClicked(GtkWidget* widget) { 33428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Make the connect button insensitive, so that it cannot be clicked more than 33528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // once. Now that the connection includes auto-retry, it should not be 33628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // necessary to click it more than once. 33728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_set_sensitive(widget, false); 33828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org server_ = gtk_entry_get_text(GTK_ENTRY(server_edit_)); 33928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org port_ = gtk_entry_get_text(GTK_ENTRY(port_edit_)); 34028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int port = port_.length() ? atoi(port_.c_str()) : 0; 34128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org callback_->StartLogin(server_, port); 34228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 34328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 34428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::OnKeyPress(GtkWidget* widget, GdkEventKey* key) { 34528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (key->type == GDK_KEY_PRESS) { 34628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org switch (key->keyval) { 34728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case GDK_Escape: 34828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (draw_area_) { 34928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org callback_->DisconnectFromCurrentPeer(); 35028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (peer_list_) { 35128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org callback_->DisconnectFromServer(); 35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 35328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 35428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 35528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case GDK_KP_Enter: 35628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case GDK_Return: 35728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (vbox_) { 35828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org OnClicked(NULL); 35928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (peer_list_) { 36028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // OnRowActivated will be called automatically when the user 36128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // presses enter. 36228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 36328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 36428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 36528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org default: 36628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 36728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 36828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 36928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 37028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 37128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::OnRowActivated(GtkTreeView* tree_view, GtkTreePath* path, 37228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeViewColumn* column) { 37328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(peer_list_ != NULL); 37428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeIter iter; 37528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeModel* model; 37628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkTreeSelection* selection = 37728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); 37828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (gtk_tree_selection_get_selected(selection, &model, &iter)) { 37928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org char* text; 38028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int id = -1; 38128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_tree_model_get(model, &iter, 0, &text, 1, &id, -1); 38228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (id != -1) 38328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org callback_->ConnectToPeer(id); 38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_free(text); 38528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 38628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 38728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 38828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::OnRedraw() { 38928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gdk_threads_enter(); 39028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 39128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org VideoRenderer* remote_renderer = remote_renderer_.get(); 39228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (remote_renderer && remote_renderer->image() != NULL && 39328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_area_ != NULL) { 39428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int width = remote_renderer->width(); 39528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int height = remote_renderer->height(); 39628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 39728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!draw_buffer_.get()) { 39828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_buffer_size_ = (width * height * 4) * 4; 3990c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström draw_buffer_.reset(new uint8_t[draw_buffer_size_]); 40028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gtk_widget_set_size_request(draw_area_, width * 2, height * 2); 40128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 40228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4030c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström const uint32_t* image = 4040c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström reinterpret_cast<const uint32_t*>(remote_renderer->image()); 4050c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t* scaled = reinterpret_cast<uint32_t*>(draw_buffer_.get()); 40628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (int r = 0; r < height; ++r) { 40728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (int c = 0; c < width; ++c) { 40828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int x = c * 2; 40928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled[x] = scaled[x + 1] = image[c]; 41028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 41128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4120c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t* prev_line = scaled; 41328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled += width * 2; 41428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org memcpy(scaled, prev_line, (width * 2) * 4); 41528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 41628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org image += width; 41728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled += width * 2; 41828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 41928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 42028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org VideoRenderer* local_renderer = local_renderer_.get(); 42128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (local_renderer && local_renderer->image()) { 4220c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström image = reinterpret_cast<const uint32_t*>(local_renderer->image()); 4230c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström scaled = reinterpret_cast<uint32_t*>(draw_buffer_.get()); 42428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Position the local preview on the right side. 42528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled += (width * 2) - (local_renderer->width() / 2); 42628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // right margin... 42728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled -= 10; 42828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // ... towards the bottom. 42928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled += (height * width * 4) - 43028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ((local_renderer->height() / 2) * 43128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (local_renderer->width() / 2) * 4); 43228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // bottom margin... 43328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled -= (width * 2) * 5; 43428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (int r = 0; r < local_renderer->height(); r += 2) { 43528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (int c = 0; c < local_renderer->width(); c += 2) { 43628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled[c / 2] = image[c + r * local_renderer->width()]; 43728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 43828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org scaled += width * 2; 43928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 44028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 44128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 44228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gdk_draw_rgb_32_image(draw_area_->window, 44328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_area_->style->fg_gc[GTK_STATE_NORMAL], 44428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 0, 44528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 0, 44628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org width * 2, 44728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org height * 2, 44828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GDK_RGB_DITHER_MAX, 44928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org draw_buffer_.get(), 45028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (width * 2) * 4); 45128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 45228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 45328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gdk_threads_leave(); 45428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 45528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 45628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgGtkMainWnd::VideoRenderer::VideoRenderer( 45728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GtkMainWnd* main_wnd, 45828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc::VideoTrackInterface* track_to_render) 45928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : width_(0), 46028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org height_(0), 46128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org main_wnd_(main_wnd), 46228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org rendered_track_(track_to_render) { 46328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org rendered_track_->AddRenderer(this); 46428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 46528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 46628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgGtkMainWnd::VideoRenderer::~VideoRenderer() { 46728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org rendered_track_->RemoveRenderer(this); 46828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 46928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 47028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid GtkMainWnd::VideoRenderer::SetSize(int width, int height) { 47128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gdk_threads_enter(); 47200c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org 47300c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org if (width_ == width && height_ == height) { 47400c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org return; 47500c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org } 47600c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org 47728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org width_ = width; 47828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org height_ = height; 4790c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström image_.reset(new uint8_t[width * height * 4]); 48028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gdk_threads_leave(); 48128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 48228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 48300c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.orgvoid GtkMainWnd::VideoRenderer::RenderFrame( 48400c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org const cricket::VideoFrame* video_frame) { 48528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gdk_threads_enter(); 48628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 48700c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org const cricket::VideoFrame* frame = video_frame->GetCopyWithRotationApplied(); 48800c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org 48900c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org SetSize(static_cast<int>(frame->GetWidth()), 49000c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org static_cast<int>(frame->GetHeight())); 49100c509ad1c94805b3332f2ce876c04705abf8ef5guoweis@webrtc.org 49228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int size = width_ * height_ * 4; 49370625e5bf3c91c57bf704d380bcc9df86575f08ajbauch // TODO(henrike): Convert directly to RGBA 49428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org frame->ConvertToRgbBuffer(cricket::FOURCC_ARGB, 49528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org image_.get(), 49628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org size, 49728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org width_ * 4); 49828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Convert the B,G,R,A frame to R,G,B,A, which is accepted by GTK. 49928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // The 'A' is just padding for GTK, so we can use it as temp. 5000c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t* pix = image_.get(); 5010c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t* end = image_.get() + size; 50228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org while (pix < end) { 50328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pix[3] = pix[0]; // Save B to A. 50428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pix[0] = pix[2]; // Set Red. 50528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pix[2] = pix[3]; // Set Blue. 50628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pix[3] = 0xFF; // Fixed Alpha. 50728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pix += 4; 50828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 50928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 51028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org gdk_threads_leave(); 51128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 51228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org g_idle_add(Redraw, main_wnd_); 51328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 51428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 51528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 516