Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / ui / base / gtk / gtk_signal_registrar.cc
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