1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/base/gtk/gtk_signal_registrar.h" 6 7 #include <glib-object.h> 8 9 #include "base/logging.h" 10 #include "ui/base/gtk/g_object_destructor_filo.h" 11 12 namespace ui { 13 14 GtkSignalRegistrar::GtkSignalRegistrar() { 15 } 16 17 GtkSignalRegistrar::~GtkSignalRegistrar() { 18 for (HandlerMap::iterator list_iter = handler_lists_.begin(); 19 list_iter != handler_lists_.end(); ++list_iter) { 20 GObject* object = list_iter->first; 21 GObjectDestructorFILO::GetInstance()->Disconnect( 22 object, WeakNotifyThunk, this); 23 24 HandlerList& handlers = list_iter->second; 25 for (HandlerList::iterator ids_iter = handlers.begin(); 26 ids_iter != handlers.end(); ++ids_iter) { 27 g_signal_handler_disconnect(object, *ids_iter); 28 } 29 } 30 } 31 32 glong GtkSignalRegistrar::Connect(gpointer instance, 33 const gchar* detailed_signal, 34 GCallback signal_handler, 35 gpointer data) { 36 return ConnectInternal(instance, detailed_signal, signal_handler, data, 37 false); 38 } 39 40 glong GtkSignalRegistrar::ConnectAfter(gpointer instance, 41 const gchar* detailed_signal, 42 GCallback signal_handler, 43 gpointer data) { 44 return ConnectInternal(instance, detailed_signal, signal_handler, data, true); 45 } 46 47 glong GtkSignalRegistrar::ConnectInternal(gpointer instance, 48 const gchar* detailed_signal, 49 GCallback signal_handler, 50 gpointer data, 51 bool after) { 52 GObject* object = G_OBJECT(instance); 53 54 HandlerMap::iterator iter = handler_lists_.find(object); 55 if (iter == handler_lists_.end()) { 56 GObjectDestructorFILO::GetInstance()->Connect( 57 object, WeakNotifyThunk, this); 58 handler_lists_[object] = HandlerList(); 59 iter = handler_lists_.find(object); 60 } 61 62 glong handler_id = after ? 63 g_signal_connect_after(instance, detailed_signal, signal_handler, data) : 64 g_signal_connect(instance, detailed_signal, signal_handler, data); 65 iter->second.push_back(handler_id); 66 67 return handler_id; 68 } 69 70 void GtkSignalRegistrar::WeakNotify(GObject* where_the_object_was) { 71 HandlerMap::iterator iter = handler_lists_.find(where_the_object_was); 72 if (iter == handler_lists_.end()) { 73 NOTREACHED(); 74 return; 75 } 76 // The signal handlers will be disconnected automatically. Just erase the 77 // handler id list. 78 handler_lists_.erase(iter); 79 } 80 81 void GtkSignalRegistrar::DisconnectAll(gpointer instance) { 82 GObject* object = G_OBJECT(instance); 83 HandlerMap::iterator iter = handler_lists_.find(object); 84 if (iter == handler_lists_.end()) 85 return; 86 87 GObjectDestructorFILO::GetInstance()->Disconnect( 88 object, WeakNotifyThunk, this); 89 HandlerList& handlers = iter->second; 90 for (HandlerList::iterator ids_iter = handlers.begin(); 91 ids_iter != handlers.end(); ++ids_iter) { 92 g_signal_handler_disconnect(object, *ids_iter); 93 } 94 95 handler_lists_.erase(iter); 96 } 97 98 } // namespace ui 99