Blame src/canberra-gtk-module.c

Packit 3ae693
/*-*- Mode: C; c-basic-offset: 8 -*-*/
Packit 3ae693
Packit 3ae693
/***
Packit 3ae693
  This file is part of libcanberra.
Packit 3ae693
Packit 3ae693
  Copyright 2008 Lennart Poettering
Packit 3ae693
Packit 3ae693
  libcanberra is free software; you can redistribute it and/or modify
Packit 3ae693
  it under the terms of the GNU Lesser General Public License as
Packit 3ae693
  published by the Free Software Foundation, either version 2.1 of the
Packit 3ae693
  License, or (at your option) any later version.
Packit 3ae693
Packit 3ae693
  libcanberra is distributed in the hope that it will be useful, but
Packit 3ae693
  WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 3ae693
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Packit 3ae693
  Lesser General Public License for more details.
Packit 3ae693
Packit 3ae693
  You should have received a copy of the GNU Lesser General Public
Packit 3ae693
  License along with libcanberra. If not, see
Packit 3ae693
  <http://www.gnu.org/licenses/>.
Packit 3ae693
***/
Packit 3ae693
Packit 3ae693
#ifdef HAVE_CONFIG_H
Packit 3ae693
#include <config.h>
Packit 3ae693
#endif
Packit 3ae693
Packit 3ae693
#include <gtk/gtk.h>
Packit 3ae693
#include <gdk/gdkx.h>
Packit 3ae693
#include <X11/Xatom.h>
Packit 3ae693
Packit 3ae693
#include "canberra-gtk.h"
Packit 3ae693
Packit 3ae693
typedef struct {
Packit 3ae693
        guint signal_id;
Packit 3ae693
        gboolean arg1_is_set;
Packit 3ae693
        GObject *object;
Packit 3ae693
        GValue arg1;
Packit 3ae693
        GdkEvent *event;
Packit 3ae693
} SoundEventData;
Packit 3ae693
Packit 3ae693
/*
Packit 3ae693
   We generate these sounds:
Packit 3ae693
Packit 3ae693
   dialog-error
Packit 3ae693
   dialog-warning
Packit 3ae693
   dialog-information
Packit 3ae693
   dialog-question
Packit 3ae693
   window-new
Packit 3ae693
   window-close
Packit 3ae693
   window-minimized
Packit 3ae693
   window-unminimized
Packit 3ae693
   window-maximized
Packit 3ae693
   window-unmaximized
Packit 3ae693
   notebook-tab-changed
Packit 3ae693
   dialog-ok
Packit 3ae693
   dialog-cancel
Packit 3ae693
   item-selected
Packit 3ae693
   link-pressed
Packit 3ae693
   link-released
Packit 3ae693
   button-pressed
Packit 3ae693
   button-released
Packit 3ae693
   menu-click
Packit 3ae693
   button-toggle-on
Packit 3ae693
   button-toggle-off
Packit 3ae693
   menu-popup
Packit 3ae693
   menu-popdown
Packit 3ae693
   menu-replace
Packit 3ae693
   tooltip-popup
Packit 3ae693
   tooltip-popdown
Packit 3ae693
   drag-start
Packit 3ae693
   drag-accept
Packit 3ae693
   drag-fail
Packit 3ae693
   expander-toggle-on
Packit 3ae693
   expander-toggle-off
Packit 3ae693
Packit 3ae693
   TODO:
Packit 3ae693
   scroll-xxx
Packit 3ae693
   window-switch
Packit 3ae693
   window-resize-xxx
Packit 3ae693
   window-move-xxx
Packit 3ae693
Packit 3ae693
*/
Packit 3ae693
Packit 3ae693
static gboolean disabled = FALSE;
Packit 3ae693
Packit 3ae693
static GQueue sound_event_queue = G_QUEUE_INIT;
Packit 3ae693
Packit 3ae693
static guint idle_id = 0;
Packit 3ae693
Packit 3ae693
static guint
Packit 3ae693
        signal_id_dialog_response,
Packit 3ae693
        signal_id_widget_show,
Packit 3ae693
        signal_id_widget_hide,
Packit 3ae693
        signal_id_check_menu_item_toggled,
Packit 3ae693
        signal_id_menu_item_activate,
Packit 3ae693
        signal_id_toggle_button_toggled,
Packit 3ae693
        signal_id_button_pressed,
Packit 3ae693
        signal_id_button_released,
Packit 3ae693
        signal_id_widget_window_state_event,
Packit 3ae693
        signal_id_notebook_switch_page,
Packit 3ae693
        signal_id_tree_view_cursor_changed,
Packit 3ae693
        signal_id_icon_view_selection_changed,
Packit 3ae693
        signal_id_widget_drag_begin,
Packit 3ae693
        signal_id_widget_drag_failed,
Packit 3ae693
        signal_id_widget_drag_drop,
Packit 3ae693
        signal_id_expander_activate;
Packit 3ae693
Packit 3ae693
static GQuark
Packit 3ae693
        disable_sound_quark,
Packit 3ae693
        was_iconized_quark,
Packit 3ae693
        is_xembed_quark;
Packit 3ae693
Packit 3ae693
/* Make sure GCC doesn't warn us about a missing prototype for this
Packit 3ae693
 * exported function */
Packit 3ae693
void gtk_module_init(gint *argc, gchar ***argv[]);
Packit 3ae693
Packit 3ae693
static const char *translate_message_tye(GtkMessageType mt) {
Packit 3ae693
        static const char *const message_type_table[] = {
Packit 3ae693
                [GTK_MESSAGE_INFO] = "dialog-information",
Packit 3ae693
                [GTK_MESSAGE_WARNING] = "dialog-warning",
Packit 3ae693
                [GTK_MESSAGE_QUESTION] = "dialog-question",
Packit 3ae693
                [GTK_MESSAGE_ERROR] = "dialog-error",
Packit 3ae693
                [GTK_MESSAGE_OTHER] = NULL
Packit 3ae693
        };
Packit 3ae693
Packit 3ae693
        if (mt >= G_N_ELEMENTS(message_type_table))
Packit 3ae693
                return NULL;
Packit 3ae693
Packit 3ae693
        return message_type_table[mt];
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static const char *translate_response(int response) {
Packit 3ae693
        static const char *const response_table[] = {
Packit 3ae693
                [-GTK_RESPONSE_NONE] = NULL,
Packit 3ae693
                [-GTK_RESPONSE_REJECT] = "dialog-cancel",
Packit 3ae693
                [-GTK_RESPONSE_DELETE_EVENT] = "dialog-cancel",
Packit 3ae693
                [-GTK_RESPONSE_ACCEPT] = "dialog-ok",
Packit 3ae693
                [-GTK_RESPONSE_OK] = "dialog-ok",
Packit 3ae693
                [-GTK_RESPONSE_CANCEL] = "dialog-cancel",
Packit 3ae693
                [-GTK_RESPONSE_CLOSE] = "dialog-ok",
Packit 3ae693
                [-GTK_RESPONSE_YES] = "dialog-ok",
Packit 3ae693
                [-GTK_RESPONSE_NO] = "dialog-cancel",
Packit 3ae693
                [-GTK_RESPONSE_APPLY] = "dialog-ok",
Packit 3ae693
                [-GTK_RESPONSE_HELP] = NULL,
Packit 3ae693
        };
Packit 3ae693
Packit 3ae693
        if (response >= 0)
Packit 3ae693
                return NULL;
Packit 3ae693
Packit 3ae693
        if ((unsigned) -response >= G_N_ELEMENTS(response_table))
Packit 3ae693
                return NULL;
Packit 3ae693
Packit 3ae693
        return response_table[-response];
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static gboolean is_child_of_combo_box(GtkWidget *w) {
Packit 3ae693
Packit 3ae693
        while (w) {
Packit 3ae693
Packit 3ae693
                if (GTK_IS_COMBO_BOX(w))
Packit 3ae693
                        return TRUE;
Packit 3ae693
Packit 3ae693
                w = gtk_widget_get_parent(w);
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        return FALSE;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static GtkDialog* find_parent_dialog(GtkWidget *w) {
Packit 3ae693
Packit 3ae693
        while (w) {
Packit 3ae693
Packit 3ae693
                if (GTK_IS_DIALOG(w))
Packit 3ae693
                        return GTK_DIALOG(w);
Packit 3ae693
Packit 3ae693
                w = gtk_widget_get_parent(w);
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        return NULL;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void free_sound_event(SoundEventData *d) {
Packit 3ae693
Packit 3ae693
        g_object_unref(d->object);
Packit 3ae693
Packit 3ae693
        if (d->arg1_is_set)
Packit 3ae693
                g_value_unset(&d->arg1);
Packit 3ae693
Packit 3ae693
        if (d->event)
Packit 3ae693
                gdk_event_free(d->event);
Packit 3ae693
Packit 3ae693
        g_slice_free(SoundEventData, d);
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static gboolean is_menu_hint(GdkWindowTypeHint hint) {
Packit 3ae693
        return
Packit 3ae693
                hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
Packit 3ae693
                hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
Packit 3ae693
                hint == GDK_WINDOW_TYPE_HINT_MENU;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static SoundEventData* filter_sound_event(SoundEventData *d) {
Packit 3ae693
        GList *i, *n;
Packit 3ae693
Packit 3ae693
        do {
Packit 3ae693
Packit 3ae693
                for (i = sound_event_queue.head; i; i = n) {
Packit 3ae693
                        SoundEventData *j;
Packit 3ae693
Packit 3ae693
                        j = i->data;
Packit 3ae693
                        n = i->next;
Packit 3ae693
Packit 3ae693
                        if (d->object == j->object) {
Packit 3ae693
Packit 3ae693
                                /* Let's drop a show event immediately followed by a
Packit 3ae693
                                 * hide event */
Packit 3ae693
Packit 3ae693
                                if (d->signal_id == signal_id_widget_show &&
Packit 3ae693
                                    j->signal_id == signal_id_widget_hide) {
Packit 3ae693
Packit 3ae693
                                        free_sound_event(d);
Packit 3ae693
                                        free_sound_event(j);
Packit 3ae693
                                        g_queue_delete_link(&sound_event_queue, i);
Packit 3ae693
Packit 3ae693
                                        return NULL;
Packit 3ae693
                                }
Packit 3ae693
Packit 3ae693
                                /* Let's drop widget hide events in favour of dialog
Packit 3ae693
                                 * response.
Packit 3ae693
                                 *
Packit 3ae693
                                 * Let's drop widget window state events in favour of
Packit 3ae693
                                 * widget hide/show.
Packit 3ae693
                                 *
Packit 3ae693
                                 * Let's drop double events */
Packit 3ae693
Packit 3ae693
                                if ((d->signal_id == signal_id_widget_hide &&
Packit 3ae693
                                     j->signal_id == signal_id_dialog_response) ||
Packit 3ae693
Packit 3ae693
                                    (d->signal_id == signal_id_widget_window_state_event &&
Packit 3ae693
                                     j->signal_id == signal_id_widget_hide) ||
Packit 3ae693
Packit 3ae693
                                    (d->signal_id == signal_id_widget_window_state_event &&
Packit 3ae693
                                     j->signal_id == signal_id_widget_show)) {
Packit 3ae693
Packit 3ae693
                                        free_sound_event(d);
Packit 3ae693
                                        d = j;
Packit 3ae693
                                        g_queue_delete_link(&sound_event_queue, i);
Packit 3ae693
                                        break;
Packit 3ae693
                                }
Packit 3ae693
Packit 3ae693
                                if ((d->signal_id == signal_id_dialog_response &&
Packit 3ae693
                                     j->signal_id == signal_id_widget_hide) ||
Packit 3ae693
Packit 3ae693
                                    (d->signal_id == signal_id_widget_show &&
Packit 3ae693
                                     j->signal_id == signal_id_widget_window_state_event) ||
Packit 3ae693
Packit 3ae693
                                    (d->signal_id == signal_id_widget_hide &&
Packit 3ae693
                                     j->signal_id == signal_id_widget_window_state_event) ||
Packit 3ae693
Packit 3ae693
                                    (d->signal_id == j->signal_id)) {
Packit 3ae693
Packit 3ae693
                                        free_sound_event(j);
Packit 3ae693
                                        g_queue_delete_link(&sound_event_queue, i);
Packit 3ae693
                                }
Packit 3ae693
Packit 3ae693
                        } else if (GTK_IS_WINDOW(d->object) && GTK_IS_WINDOW(j->object)) {
Packit 3ae693
Packit 3ae693
                                GdkWindowTypeHint dhint, jhint;
Packit 3ae693
Packit 3ae693
                                dhint = gtk_window_get_type_hint(GTK_WINDOW(d->object));
Packit 3ae693
                                jhint = gtk_window_get_type_hint(GTK_WINDOW(j->object));
Packit 3ae693
Packit 3ae693
                                if (is_menu_hint(dhint) && is_menu_hint(jhint)) {
Packit 3ae693
Packit 3ae693
                                        if (d->signal_id == signal_id_widget_hide &&
Packit 3ae693
                                            j->signal_id == signal_id_widget_show) {
Packit 3ae693
                                                free_sound_event(d);
Packit 3ae693
                                                d = j;
Packit 3ae693
                                                g_queue_delete_link(&sound_event_queue, i);
Packit 3ae693
                                                break;
Packit 3ae693
                                        }
Packit 3ae693
Packit 3ae693
                                        if (d->signal_id == signal_id_widget_show &&
Packit 3ae693
                                            j->signal_id == signal_id_widget_hide) {
Packit 3ae693
Packit 3ae693
                                                free_sound_event(j);
Packit 3ae693
                                                g_queue_delete_link(&sound_event_queue, i);
Packit 3ae693
                                        }
Packit 3ae693
                                }
Packit 3ae693
                        }
Packit 3ae693
                }
Packit 3ae693
Packit 3ae693
                /* If we exited the iteration early, let's retry. */
Packit 3ae693
Packit 3ae693
        } while (i);
Packit 3ae693
Packit 3ae693
        /* FIXME: Filter menu hide on menu show */
Packit 3ae693
Packit 3ae693
        return d;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static gint window_get_desktop(GdkDisplay *d, GdkWindow *w) {
Packit 3ae693
        Atom type_return;
Packit 3ae693
        gint format_return;
Packit 3ae693
        gulong nitems_return;
Packit 3ae693
        gulong bytes_after_return;
Packit 3ae693
        guchar *data = NULL;
Packit 3ae693
        gint ret = -1;
Packit 3ae693
Packit 3ae693
        if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w),
Packit 3ae693
                               gdk_x11_get_xatom_by_name_for_display(d, "_NET_WM_DESKTOP"),
Packit 3ae693
                               0, G_MAXLONG, False, XA_CARDINAL, &type_return,
Packit 3ae693
                               &format_return, &nitems_return, &bytes_after_return,
Packit 3ae693
                               &data) != Success)
Packit 3ae693
                return -1;
Packit 3ae693
Packit 3ae693
        if (type_return == XA_CARDINAL && format_return == 32 && data) {
Packit 3ae693
                guint32 desktop = *(guint32*) data;
Packit 3ae693
Packit 3ae693
                if (desktop != 0xFFFFFFFF)
Packit 3ae693
                        ret = (gint) desktop;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (type_return != None && data != NULL)
Packit 3ae693
                XFree(data);
Packit 3ae693
Packit 3ae693
        return ret;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static gint display_get_desktop(GdkDisplay *d) {
Packit 3ae693
        Atom type_return;
Packit 3ae693
        gint format_return;
Packit 3ae693
        gulong nitems_return;
Packit 3ae693
        gulong bytes_after_return;
Packit 3ae693
        guchar *data = NULL;
Packit 3ae693
        gint ret = -1;
Packit 3ae693
Packit 3ae693
        if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), DefaultRootWindow(GDK_DISPLAY_XDISPLAY(d)),
Packit 3ae693
                               gdk_x11_get_xatom_by_name_for_display(d, "_NET_CURRENT_DESKTOP"),
Packit 3ae693
                               0, G_MAXLONG, False, XA_CARDINAL, &type_return,
Packit 3ae693
                               &format_return, &nitems_return, &bytes_after_return,
Packit 3ae693
                               &data) != Success)
Packit 3ae693
                return -1;
Packit 3ae693
Packit 3ae693
        if (type_return == XA_CARDINAL && format_return == 32 && data) {
Packit 3ae693
Packit 3ae693
                guint32 desktop = *(guint32*) data;
Packit 3ae693
Packit 3ae693
                if (desktop != 0xFFFFFFFF)
Packit 3ae693
                        ret = (gint) desktop;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (type_return != None && data != NULL)
Packit 3ae693
                XFree(data);
Packit 3ae693
Packit 3ae693
        return ret;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static gboolean window_is_xembed(GdkDisplay *d, GdkWindow *w) {
Packit 3ae693
        Atom type_return;
Packit 3ae693
        gint format_return;
Packit 3ae693
        gulong nitems_return;
Packit 3ae693
        gulong bytes_after_return;
Packit 3ae693
        guchar *data = NULL;
Packit 3ae693
        gboolean ret = FALSE;
Packit 3ae693
        Atom xembed;
Packit 3ae693
Packit 3ae693
        /* Gnome Panel applets are XEMBED windows. We need to make sure we
Packit 3ae693
         * ignore them */
Packit 3ae693
Packit 3ae693
        xembed = gdk_x11_get_xatom_by_name_for_display(d, "_XEMBED_INFO");
Packit 3ae693
Packit 3ae693
        /* be robust against not existing XIDs (LP: #834403) */
Packit 3ae693
        gdk_error_trap_push();
Packit 3ae693
        if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w),
Packit 3ae693
                               xembed,
Packit 3ae693
                               0, 2, False, xembed, &type_return,
Packit 3ae693
                               &format_return, &nitems_return, &bytes_after_return,
Packit 3ae693
                               &data) != Success) {
Packit 3ae693
                return FALSE;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
#if GTK_CHECK_VERSION(3,0,0)
Packit 3ae693
        gdk_error_trap_pop_ignored();
Packit 3ae693
#else
Packit 3ae693
        gdk_flush();
Packit 3ae693
        gdk_error_trap_pop();
Packit 3ae693
#endif
Packit 3ae693
Packit 3ae693
        if (type_return == xembed && format_return == 32 && data)
Packit 3ae693
                ret = TRUE;
Packit 3ae693
Packit 3ae693
        if (type_return != None && data != NULL)
Packit 3ae693
                XFree(data);
Packit 3ae693
Packit 3ae693
        return ret;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void dispatch_sound_event(SoundEventData *d) {
Packit 3ae693
        int ret = CA_SUCCESS;
Packit 3ae693
        static gboolean menu_is_popped_up = FALSE;
Packit 3ae693
Packit 3ae693
        if (g_object_get_qdata(d->object, disable_sound_quark))
Packit 3ae693
                return;
Packit 3ae693
Packit 3ae693
        /* The GdkWindow of the the widget might have changed while this
Packit 3ae693
         * event was queued for us. Make sure to update it from the
Packit 3ae693
         * current one if necessary. */
Packit 3ae693
        if (d->event && d->event->any.window) {
Packit 3ae693
                GdkWindow *window;
Packit 3ae693
Packit 3ae693
                g_object_unref(G_OBJECT(d->event->any.window));
Packit 3ae693
Packit 3ae693
                if ((window = gtk_widget_get_window(GTK_WIDGET(d->object))))
Packit 3ae693
                        d->event->any.window = GDK_WINDOW(g_object_ref(G_OBJECT(window)));
Packit 3ae693
                else
Packit 3ae693
                        d->event->any.window = NULL;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (d->signal_id == signal_id_widget_show) {
Packit 3ae693
                GdkWindowTypeHint hint;
Packit 3ae693
Packit 3ae693
                /* Show/hide signals for non-windows have already been filtered out
Packit 3ae693
                 * by the emission hook! */
Packit 3ae693
Packit 3ae693
                hint = gtk_window_get_type_hint(GTK_WINDOW(d->object));
Packit 3ae693
Packit 3ae693
                if (is_menu_hint(hint)) {
Packit 3ae693
Packit 3ae693
                        if (!menu_is_popped_up) {
Packit 3ae693
Packit 3ae693
                                ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                             CA_PROP_EVENT_ID, "menu-popup",
Packit 3ae693
                                                             CA_PROP_EVENT_DESCRIPTION, "Menu popped up",
Packit 3ae693
                                                             CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                             NULL);
Packit 3ae693
                        } else {
Packit 3ae693
                                ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                             CA_PROP_EVENT_ID, "menu-replace",
Packit 3ae693
                                                             CA_PROP_EVENT_DESCRIPTION, "Menu replaced",
Packit 3ae693
                                                             CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                             NULL);
Packit 3ae693
                        }
Packit 3ae693
Packit 3ae693
                        menu_is_popped_up = TRUE;
Packit 3ae693
Packit 3ae693
                } else if (hint == GDK_WINDOW_TYPE_HINT_TOOLTIP) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, "tooltip-popup",
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Tooltip popped up",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
Packit 3ae693
                } else if (hint == GDK_WINDOW_TYPE_HINT_NORMAL ||
Packit 3ae693
                           hint == GDK_WINDOW_TYPE_HINT_DIALOG) {
Packit 3ae693
Packit 3ae693
                        gboolean played_sound = FALSE;
Packit 3ae693
                        gboolean is_xembed;
Packit 3ae693
Packit 3ae693
                        is_xembed =
Packit 3ae693
                                gtk_widget_get_realized(GTK_WIDGET(d->object)) &&
Packit 3ae693
                                window_is_xembed(
Packit 3ae693
                                                gtk_widget_get_display(GTK_WIDGET(d->object)),
Packit 3ae693
                                                gtk_widget_get_window(GTK_WIDGET(d->object)));
Packit 3ae693
Packit 3ae693
                        g_object_set_qdata(d->object, is_xembed_quark, GINT_TO_POINTER(is_xembed));
Packit 3ae693
Packit 3ae693
                        if (GTK_IS_MESSAGE_DIALOG(d->object)) {
Packit 3ae693
                                GtkMessageType mt;
Packit 3ae693
                                const char *id;
Packit 3ae693
Packit 3ae693
                                g_object_get(d->object, "message_type", &mt, NULL);
Packit 3ae693
Packit 3ae693
                                if ((id = translate_message_tye(mt))) {
Packit 3ae693
Packit 3ae693
                                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                                     CA_PROP_EVENT_ID, id,
Packit 3ae693
                                                                     CA_PROP_EVENT_DESCRIPTION, "Message dialog shown",
Packit 3ae693
                                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                                     NULL);
Packit 3ae693
                                        played_sound = TRUE;
Packit 3ae693
                                }
Packit 3ae693
Packit 3ae693
                        }
Packit 3ae693
Packit 3ae693
                        if (!played_sound &&
Packit 3ae693
                            !is_xembed &&
Packit 3ae693
                            gtk_window_get_decorated(GTK_WINDOW(d->object))) {
Packit 3ae693
Packit 3ae693
                                ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                             CA_PROP_EVENT_ID, "window-new",
Packit 3ae693
                                                             CA_PROP_EVENT_DESCRIPTION, "Window shown",
Packit 3ae693
                                                             CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                             NULL);
Packit 3ae693
Packit 3ae693
                        }
Packit 3ae693
                }
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_DIALOG(d->object) && d->signal_id == signal_id_dialog_response) {
Packit 3ae693
Packit 3ae693
                int response;
Packit 3ae693
                const char *id;
Packit 3ae693
Packit 3ae693
                response = g_value_get_int(&d->arg1);
Packit 3ae693
Packit 3ae693
                if ((id = translate_response(response))) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, id,
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Dialog closed",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
                } else {
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, "window-close",
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Window closed",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
                }
Packit 3ae693
Packit 3ae693
        } else if (d->signal_id == signal_id_widget_hide) {
Packit 3ae693
                GdkWindowTypeHint hint;
Packit 3ae693
Packit 3ae693
                hint = gtk_window_get_type_hint(GTK_WINDOW(d->object));
Packit 3ae693
Packit 3ae693
                if (is_menu_hint(hint)) {
Packit 3ae693
Packit 3ae693
                        if (GTK_IS_MENU(gtk_bin_get_child(GTK_BIN(d->object)))) {
Packit 3ae693
Packit 3ae693
                                ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                             CA_PROP_EVENT_ID, "menu-popdown",
Packit 3ae693
                                                             CA_PROP_EVENT_DESCRIPTION, "Menu popped down",
Packit 3ae693
                                                             CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                             NULL);
Packit 3ae693
                        }
Packit 3ae693
Packit 3ae693
                        menu_is_popped_up = FALSE;
Packit 3ae693
Packit 3ae693
                } else if (hint == GDK_WINDOW_TYPE_HINT_TOOLTIP) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, "tooltip-popdown",
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Tooltip popped down",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
Packit 3ae693
                } else if ((hint == GDK_WINDOW_TYPE_HINT_NORMAL ||
Packit 3ae693
                            hint == GDK_WINDOW_TYPE_HINT_DIALOG)) {
Packit 3ae693
Packit 3ae693
                        gboolean is_xembed;
Packit 3ae693
Packit 3ae693
                        is_xembed = !!g_object_get_qdata(d->object, is_xembed_quark);
Packit 3ae693
Packit 3ae693
                        if (!is_xembed &&
Packit 3ae693
                            gtk_window_get_decorated(GTK_WINDOW(d->object)))
Packit 3ae693
                                ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                             CA_PROP_EVENT_ID, "window-close",
Packit 3ae693
                                                             CA_PROP_EVENT_DESCRIPTION, "Window closed",
Packit 3ae693
                                                             CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                             NULL);
Packit 3ae693
                }
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_WINDOW(d->object) && d->signal_id == signal_id_widget_window_state_event) {
Packit 3ae693
                GdkEventWindowState *e;
Packit 3ae693
                gint w_desktop = -1, c_desktop = -1;
Packit 3ae693
Packit 3ae693
                e = (GdkEventWindowState*) d->event;
Packit 3ae693
Packit 3ae693
                /* Unfortunately GDK_WINDOW_STATE_ICONIFIED is used both for
Packit 3ae693
                 * proper minimizing and when a window becomes invisible
Packit 3ae693
                 * because the desktop was switched. To handle this we check
Packit 3ae693
                 * if the window becoming invisible is actually on the current
Packit 3ae693
                 * desktop, and only if that's the case we assume it is being
Packit 3ae693
                 * minimized. We then store this information, so that we know
Packit 3ae693
                 * later on when the window is unminimized again. */
Packit 3ae693
Packit 3ae693
                if (gtk_widget_get_realized(GTK_WIDGET(d->object))) {
Packit 3ae693
                        GdkDisplay *display;
Packit 3ae693
Packit 3ae693
                        display = gtk_widget_get_display(GTK_WIDGET(d->object));
Packit 3ae693
                        w_desktop = window_get_desktop(display, gtk_widget_get_window(GTK_WIDGET(d->object)));
Packit 3ae693
                        c_desktop = display_get_desktop(display);
Packit 3ae693
                }
Packit 3ae693
Packit 3ae693
                if ((e->changed_mask & GDK_WINDOW_STATE_ICONIFIED) &&
Packit 3ae693
                    (e->new_window_state & GDK_WINDOW_STATE_ICONIFIED) &&
Packit 3ae693
                    (w_desktop == c_desktop || w_desktop < 0)) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, "window-minimized",
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Window minimized",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
Packit 3ae693
                        g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(1));
Packit 3ae693
Packit 3ae693
                } else if ((e->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) &&
Packit 3ae693
                           (e->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN))) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, "window-maximized",
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Window maximized",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
Packit 3ae693
                        g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(0));
Packit 3ae693
Packit 3ae693
                } else if ((e->changed_mask & GDK_WINDOW_STATE_ICONIFIED) &&
Packit 3ae693
                           !(e->new_window_state & GDK_WINDOW_STATE_ICONIFIED) &&
Packit 3ae693
                           g_object_get_qdata(d->object, was_iconized_quark)) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, "window-unminimized",
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Window unminimized",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
Packit 3ae693
                        g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(0));
Packit 3ae693
Packit 3ae693
                } else if ((e->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) &&
Packit 3ae693
                           !(e->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN))) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0,
Packit 3ae693
                                                     CA_PROP_EVENT_ID, "window-unmaximized",
Packit 3ae693
                                                     CA_PROP_EVENT_DESCRIPTION, "Window unmaximized",
Packit 3ae693
                                                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                     NULL);
Packit 3ae693
                }
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_CHECK_MENU_ITEM(d->object) && d->signal_id == signal_id_check_menu_item_toggled) {
Packit 3ae693
Packit 3ae693
                if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(d->object)))
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "button-toggle-on",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Check menu item checked",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
                else
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "button-toggle-off",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Check menu item unchecked",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
Packit 3ae693
        } else if (GTK_IS_MENU_ITEM(d->object) && d->signal_id == signal_id_menu_item_activate) {
Packit 3ae693
Packit 3ae693
                if (!gtk_menu_item_get_submenu(GTK_MENU_ITEM(d->object)))
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "menu-click",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Menu item clicked",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_TOGGLE_BUTTON(d->object)) {
Packit 3ae693
Packit 3ae693
                if (d->signal_id == signal_id_toggle_button_toggled) {
Packit 3ae693
Packit 3ae693
                        if (!is_child_of_combo_box(GTK_WIDGET(d->object))) {
Packit 3ae693
Packit 3ae693
                                /* We don't want to play this sound if this is a toggle
Packit 3ae693
                                 * button belonging to combo box. */
Packit 3ae693
Packit 3ae693
                                if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d->object)))
Packit 3ae693
                                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                                    CA_PROP_EVENT_ID, "button-toggle-on",
Packit 3ae693
                                                                    CA_PROP_EVENT_DESCRIPTION, "Toggle button checked",
Packit 3ae693
                                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                                    NULL);
Packit 3ae693
                                else
Packit 3ae693
                                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                                    CA_PROP_EVENT_ID, "button-toggle-off",
Packit 3ae693
                                                                    CA_PROP_EVENT_DESCRIPTION, "Toggle button unchecked",
Packit 3ae693
                                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                                    NULL);
Packit 3ae693
                        }
Packit 3ae693
                }
Packit 3ae693
Packit 3ae693
        } else if (GTK_IS_LINK_BUTTON(d->object)) {
Packit 3ae693
Packit 3ae693
                if (d->signal_id == signal_id_button_pressed) {
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "link-pressed",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Link pressed",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
Packit 3ae693
                } else if (d->signal_id == signal_id_button_released) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "link-released",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Link released",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
                }
Packit 3ae693
Packit 3ae693
        } else if (GTK_IS_BUTTON(d->object) && !GTK_IS_TOGGLE_BUTTON(d->object)) {
Packit 3ae693
Packit 3ae693
                if (d->signal_id == signal_id_button_pressed) {
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "button-pressed",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Button pressed",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
Packit 3ae693
                } else if (d->signal_id == signal_id_button_released) {
Packit 3ae693
                        GtkDialog *dialog;
Packit 3ae693
                        gboolean dont_play = FALSE;
Packit 3ae693
Packit 3ae693
                        if ((dialog = find_parent_dialog(GTK_WIDGET(d->object)))) {
Packit 3ae693
                                int response;
Packit 3ae693
Packit 3ae693
                                /* Don't play the click sound if this is a response widget
Packit 3ae693
                                 * we will generate a dialog-xxx event sound anyway. */
Packit 3ae693
Packit 3ae693
                                response = gtk_dialog_get_response_for_widget(dialog, GTK_WIDGET(d->object));
Packit 3ae693
                                dont_play = !!translate_response(response);
Packit 3ae693
                        }
Packit 3ae693
Packit 3ae693
                        if (!dont_play)
Packit 3ae693
                                ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                            CA_PROP_EVENT_ID, "button-released",
Packit 3ae693
                                                            CA_PROP_EVENT_DESCRIPTION, "Button released",
Packit 3ae693
                                                            CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                            NULL);
Packit 3ae693
                }
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_NOTEBOOK(d->object) && d->signal_id == signal_id_notebook_switch_page) {
Packit 3ae693
                ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                            CA_PROP_EVENT_ID, "notebook-tab-changed",
Packit 3ae693
                                            CA_PROP_EVENT_DESCRIPTION, "Tab changed",
Packit 3ae693
                                            CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                            NULL);
Packit 3ae693
                goto finish;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_TREE_VIEW(d->object) && d->signal_id == signal_id_tree_view_cursor_changed) {
Packit 3ae693
                ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                            CA_PROP_EVENT_ID, "item-selected",
Packit 3ae693
                                            CA_PROP_EVENT_DESCRIPTION, "Item selected",
Packit 3ae693
                                            CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                            NULL);
Packit 3ae693
                goto finish;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_ICON_VIEW(d->object) && d->signal_id == signal_id_icon_view_selection_changed) {
Packit 3ae693
                ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                            CA_PROP_EVENT_ID, "item-selected",
Packit 3ae693
                                            CA_PROP_EVENT_DESCRIPTION, "Item selected",
Packit 3ae693
                                            CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                            NULL);
Packit 3ae693
                goto finish;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_EXPANDER(d->object) && d->signal_id == signal_id_expander_activate) {
Packit 3ae693
Packit 3ae693
                if (gtk_expander_get_expanded(GTK_EXPANDER(d->object)))
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "expander-toggle-on",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Expander expanded",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
                else
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "expander-toggle-off",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Expander unexpanded",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
Packit 3ae693
                goto finish;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        if (GTK_IS_WIDGET(d->object)) {
Packit 3ae693
Packit 3ae693
                if (d->signal_id == signal_id_widget_drag_begin) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "drag-start",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Drag started",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
                        goto finish;
Packit 3ae693
Packit 3ae693
                } else if (d->signal_id == signal_id_widget_drag_drop) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "drag-accept",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Drag accepted",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
                        goto finish;
Packit 3ae693
Packit 3ae693
                } else if (d->signal_id == signal_id_widget_drag_failed) {
Packit 3ae693
Packit 3ae693
                        ret = ca_gtk_play_for_event(d->event, 0,
Packit 3ae693
                                                    CA_PROP_EVENT_ID, "drag-fail",
Packit 3ae693
                                                    CA_PROP_EVENT_DESCRIPTION, "Drag failed",
Packit 3ae693
                                                    CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
Packit 3ae693
                                                    NULL);
Packit 3ae693
                        goto finish;
Packit 3ae693
                }
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
finish:
Packit 3ae693
Packit 3ae693
        ;
Packit 3ae693
        /* if (ret != CA_SUCCESS) */
Packit 3ae693
        /*     g_warning("Failed to play event sound: %s", ca_strerror(ret)); */
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void dispatch_queue(void) {
Packit 3ae693
        SoundEventData *d;
Packit 3ae693
Packit 3ae693
        while ((d = g_queue_pop_head(&sound_event_queue))) {
Packit 3ae693
Packit 3ae693
                if (!(d = filter_sound_event(d)))
Packit 3ae693
                        continue;
Packit 3ae693
Packit 3ae693
                dispatch_sound_event(d);
Packit 3ae693
                free_sound_event(d);
Packit 3ae693
        }
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static gboolean idle_cb(void *userdata) {
Packit 3ae693
        idle_id = 0;
Packit 3ae693
Packit 3ae693
        dispatch_queue();
Packit 3ae693
Packit 3ae693
        return FALSE;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void connect_settings(void);
Packit 3ae693
Packit 3ae693
static gboolean emission_hook_cb(GSignalInvocationHint *hint, guint n_param_values, const GValue *param_values, gpointer data) {
Packit 3ae693
        static SoundEventData *d = NULL;
Packit 3ae693
        GdkEvent *e;
Packit 3ae693
        GObject *object;
Packit 3ae693
Packit 3ae693
        connect_settings();
Packit 3ae693
Packit 3ae693
        if (disabled)
Packit 3ae693
                return TRUE;
Packit 3ae693
Packit 3ae693
        object = g_value_get_object(&param_values[0]);
Packit 3ae693
Packit 3ae693
        /* g_message("signal '%s' on object of type '%s' with name '%s'", */
Packit 3ae693
        /*           g_signal_name(hint->signal_id), */
Packit 3ae693
        /*           G_OBJECT_TYPE_NAME(object), */
Packit 3ae693
        /*           gtk_widget_get_name(GTK_WIDGET(object))); */
Packit 3ae693
Packit 3ae693
        /* if (GTK_IS_WINDOW(object)) */
Packit 3ae693
        /*     g_message("window role='%s' title='%s' type='%u'", */
Packit 3ae693
        /*               gtk_window_get_role(GTK_WINDOW(object)), */
Packit 3ae693
        /*               gtk_window_get_title(GTK_WINDOW(object)), */
Packit 3ae693
        /*               gtk_window_get_type_hint(GTK_WINDOW(object))); */
Packit 3ae693
Packit 3ae693
        /* Filter a few very often occuring signals as quickly as possible */
Packit 3ae693
        if ((hint->signal_id == signal_id_widget_hide ||
Packit 3ae693
             hint->signal_id == signal_id_widget_show ||
Packit 3ae693
             hint->signal_id == signal_id_widget_window_state_event) &&
Packit 3ae693
            !GTK_IS_WINDOW(object))
Packit 3ae693
                return TRUE;
Packit 3ae693
Packit 3ae693
        if (hint->signal_id != signal_id_widget_hide &&
Packit 3ae693
            hint->signal_id != signal_id_dialog_response &&
Packit 3ae693
            !gtk_widget_is_drawable(GTK_WIDGET (object)))
Packit 3ae693
                return TRUE;
Packit 3ae693
Packit 3ae693
        d = g_slice_new0(SoundEventData);
Packit 3ae693
Packit 3ae693
        d->object = g_object_ref(object);
Packit 3ae693
Packit 3ae693
        d->signal_id = hint->signal_id;
Packit 3ae693
Packit 3ae693
        if (d->signal_id == signal_id_widget_window_state_event) {
Packit 3ae693
                d->event = gdk_event_copy(g_value_peek_pointer(&param_values[1]));
Packit 3ae693
        } else if ((e = gtk_get_current_event()))
Packit 3ae693
                d->event = gdk_event_copy(e);
Packit 3ae693
Packit 3ae693
        if (n_param_values > 1) {
Packit 3ae693
                g_value_init(&d->arg1, G_VALUE_TYPE(&param_values[1]));
Packit 3ae693
                g_value_copy(&param_values[1], &d->arg1);
Packit 3ae693
                d->arg1_is_set = TRUE;
Packit 3ae693
        }
Packit 3ae693
Packit 3ae693
        g_queue_push_tail(&sound_event_queue, d);
Packit 3ae693
Packit 3ae693
        if (idle_id == 0)
Packit 3ae693
                idle_id = gdk_threads_add_idle_full(GDK_PRIORITY_REDRAW-1, (GSourceFunc) idle_cb, NULL, NULL);
Packit 3ae693
Packit 3ae693
        return TRUE;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void install_hook(GType type, const char *sig, guint *sn) {
Packit 3ae693
        GTypeClass *type_class;
Packit 3ae693
Packit 3ae693
        type_class = g_type_class_ref(type);
Packit 3ae693
Packit 3ae693
        *sn = g_signal_lookup(sig, type);
Packit 3ae693
        g_signal_add_emission_hook(*sn, 0, emission_hook_cb, NULL, NULL);
Packit 3ae693
Packit 3ae693
        g_type_class_unref(type_class);
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void read_enable_input_feedback_sounds(GtkSettings *s) {
Packit 3ae693
        gboolean enabled = !disabled;
Packit 3ae693
Packit 3ae693
        if (g_getenv("CANBERRA_FORCE_INPUT_FEEDBACK_SOUNDS"))
Packit 3ae693
                disabled = FALSE;
Packit 3ae693
        else {
Packit 3ae693
                g_object_get(G_OBJECT(s), "gtk-enable-input-feedback-sounds", &enabled, NULL);
Packit 3ae693
                disabled = !enabled;
Packit 3ae693
        }
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void enable_input_feedback_sounds_changed(GtkSettings *s, GParamSpec *arg1, gpointer userdata) {
Packit 3ae693
        read_enable_input_feedback_sounds(s);
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
static void connect_settings(void) {
Packit 3ae693
        GtkSettings *s;
Packit 3ae693
        static gboolean connected = FALSE;
Packit 3ae693
Packit 3ae693
        if (connected)
Packit 3ae693
                return;
Packit 3ae693
Packit 3ae693
        if (!(s = gtk_settings_get_default()))
Packit 3ae693
                return;
Packit 3ae693
Packit 3ae693
        if (g_object_class_find_property(G_OBJECT_GET_CLASS(s), "gtk-enable-input-feedback-sounds")) {
Packit 3ae693
                g_signal_connect(G_OBJECT(s), "notify::gtk-enable-input-feedback-sounds", G_CALLBACK(enable_input_feedback_sounds_changed), NULL);
Packit 3ae693
                read_enable_input_feedback_sounds(s);
Packit 3ae693
        } else
Packit 3ae693
                g_debug("This Gtk+ version doesn't have the GtkSettings::gtk-enable-input-feedback-sounds property.");
Packit 3ae693
Packit 3ae693
        connected = TRUE;
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
#if GTK_CHECK_VERSION(3,0,0)
Packit 3ae693
#warning "We really need a quit handler in Gtk 3.0, https://bugzilla.gnome.org/show_bug.cgi?id=639770"
Packit 3ae693
#else
Packit 3ae693
static gboolean quit_handler(gpointer data) {
Packit 3ae693
        dispatch_queue();
Packit 3ae693
        return FALSE;
Packit 3ae693
}
Packit 3ae693
#endif
Packit 3ae693
Packit 3ae693
G_MODULE_EXPORT void gtk_module_init(gint *argc, gchar ***argv[]) {
Packit 3ae693
Packit 3ae693
        /* This is the same quark libgnomeui uses! */
Packit 3ae693
        disable_sound_quark = g_quark_from_string("gnome_disable_sound_events");
Packit 3ae693
        was_iconized_quark = g_quark_from_string("canberra_was_iconized");
Packit 3ae693
        is_xembed_quark = g_quark_from_string("canberra_is_xembed");
Packit 3ae693
Packit 3ae693
        /* Hook up the gtk setting */
Packit 3ae693
        connect_settings();
Packit 3ae693
Packit 3ae693
        install_hook(GTK_TYPE_WINDOW, "show", &signal_id_widget_show);
Packit 3ae693
        install_hook(GTK_TYPE_WINDOW, "hide", &signal_id_widget_hide);
Packit 3ae693
        install_hook(GTK_TYPE_DIALOG, "response", &signal_id_dialog_response);
Packit 3ae693
        install_hook(GTK_TYPE_MENU_ITEM, "activate", &signal_id_menu_item_activate);
Packit 3ae693
        install_hook(GTK_TYPE_CHECK_MENU_ITEM, "toggled", &signal_id_check_menu_item_toggled);
Packit 3ae693
        install_hook(GTK_TYPE_TOGGLE_BUTTON, "toggled", &signal_id_toggle_button_toggled);
Packit 3ae693
        install_hook(GTK_TYPE_BUTTON, "pressed", &signal_id_button_pressed);
Packit 3ae693
        install_hook(GTK_TYPE_BUTTON, "released", &signal_id_button_released);
Packit 3ae693
        install_hook(GTK_TYPE_WIDGET, "window-state-event", &signal_id_widget_window_state_event);
Packit 3ae693
        install_hook(GTK_TYPE_NOTEBOOK, "switch-page", &signal_id_notebook_switch_page);
Packit 3ae693
        install_hook(GTK_TYPE_TREE_VIEW, "cursor-changed", &signal_id_tree_view_cursor_changed);
Packit 3ae693
        install_hook(GTK_TYPE_ICON_VIEW, "selection-changed", &signal_id_icon_view_selection_changed);
Packit 3ae693
        install_hook(GTK_TYPE_WIDGET, "drag-begin", &signal_id_widget_drag_begin);
Packit 3ae693
        install_hook(GTK_TYPE_WIDGET, "drag-drop", &signal_id_widget_drag_drop);
Packit 3ae693
        install_hook(GTK_TYPE_WIDGET, "drag-failed", &signal_id_widget_drag_failed);
Packit 3ae693
        install_hook(GTK_TYPE_EXPANDER, "activate", &signal_id_expander_activate);
Packit 3ae693
Packit 3ae693
#if !GTK_CHECK_VERSION(3,0,0)
Packit 3ae693
        gtk_quit_add(1, quit_handler, NULL);
Packit 3ae693
#endif
Packit 3ae693
}
Packit 3ae693
Packit 3ae693
G_MODULE_EXPORT gchar* g_module_check_init(GModule *module);
Packit 3ae693
Packit 3ae693
G_MODULE_EXPORT gchar* g_module_check_init(GModule *module) {
Packit 3ae693
        g_module_make_resident(module);
Packit 3ae693
        return NULL;
Packit 3ae693
}