|
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(¶m_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(¶m_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(¶m_values[1]));
|
|
Packit |
3ae693 |
g_value_copy(¶m_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 |
}
|