Home | History | Annotate | Download | only in gtk
      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