• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h"
6 
7 #include <glib-object.h>
8 
9 #include "base/logging.h"
10 #include "chrome/browser/ui/libgtk2ui/g_object_destructor_filo.h"
11 
12 namespace libgtk2ui {
13 
Gtk2SignalRegistrar()14 Gtk2SignalRegistrar::Gtk2SignalRegistrar() {
15 }
16 
~Gtk2SignalRegistrar()17 Gtk2SignalRegistrar::~Gtk2SignalRegistrar() {
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 
Connect(gpointer instance,const gchar * detailed_signal,GCallback signal_handler,gpointer data)32 glong Gtk2SignalRegistrar::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 
ConnectAfter(gpointer instance,const gchar * detailed_signal,GCallback signal_handler,gpointer data)40 glong Gtk2SignalRegistrar::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 
ConnectInternal(gpointer instance,const gchar * detailed_signal,GCallback signal_handler,gpointer data,bool after)47 glong Gtk2SignalRegistrar::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 
WeakNotify(GObject * where_the_object_was)70 void Gtk2SignalRegistrar::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 
DisconnectAll(gpointer instance)81 void Gtk2SignalRegistrar::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 libgtk2ui
99