36 #define ICON_MIN_SIZE 16 62 gchar *pathname = NULL;
64 if (!filename || !filename[0])
70 WARN(
"Couldn't find pixmap file '%s'", filename);
74 DEBUG(
"Loading PNMixer icon '%s' from '%s'", filename, pathname);
76 pixbuf = gdk_pixbuf_new_from_file(pathname, &error);
78 WARN(
"Could not create pixbuf from file '%s': %s",
79 pathname, error->message);
98 static GtkIconTheme *icon_theme = NULL;
100 GtkIconInfo *info = NULL;
101 GdkPixbuf *pixbuf = NULL;
103 if (icon_theme == NULL)
104 icon_theme = gtk_icon_theme_get_default();
106 info = gtk_icon_theme_lookup_icon(icon_theme, icon_name, size, 0);
108 WARN(
"Unable to lookup icon '%s'", icon_name);
112 DEBUG(
"Loading stock icon '%s' from '%s'", icon_name,
113 gtk_icon_info_get_filename(info));
115 pixbuf = gtk_icon_info_load_icon(info, &err);
116 if (pixbuf == NULL) {
117 WARN(
"Unable to load icon '%s': %s", icon_name, err->message);
122 g_object_unref(info);
124 gtk_icon_info_free(info);
140 g_object_unref(pixbufs[i]);
152 DEBUG(
"Building pixbuf array (requesting size %d)", size);
177 return g_memdup(pixbufs,
sizeof pixbufs);
216 gboolean vol_meter_enabled;
217 gdouble *vol_meter_clrs;
220 if (vol_meter_enabled == FALSE)
232 g_free(vol_meter_clrs);
244 int icon_width, icon_height;
245 int vm_width, vm_height;
251 g_assert(gdk_pixbuf_get_colorspace(
pixbuf) == GDK_COLORSPACE_RGB);
252 g_assert(gdk_pixbuf_get_bits_per_sample(
pixbuf) == 8);
253 g_assert(gdk_pixbuf_get_has_alpha(
pixbuf));
254 g_assert(gdk_pixbuf_get_n_channels(
pixbuf) == 4);
256 icon_width = gdk_pixbuf_get_width(
pixbuf);
257 icon_height = gdk_pixbuf_get_height(
pixbuf);
265 vm_width = icon_width / 6;
267 g_assert(x >= 0 && x + vm_width <= icon_width);
270 vm_height = (icon_height - (y * 2)) * (volume / 100.0);
271 g_assert(y >= 0 && y + vm_height <= icon_height);
283 DEBUG(
"Allocating vol meter row (width %d)", vm_width);
284 vol_meter->
row = g_malloc(vm_width *
sizeof(guchar) * 4);
285 for (i = 0; i < vm_width; i++) {
297 rowstride = gdk_pixbuf_get_rowstride(
pixbuf);
298 pixels = gdk_pixbuf_get_pixels(
pixbuf);
300 for (i = 0; i < vm_height; i++) {
302 guint row_offset, col_offset;
306 p = pixels + (row_offset * rowstride) + col_offset;
320 gdouble volume, gboolean muted)
327 else if (volume < 33)
329 else if (volume < 66)
340 gtk_status_icon_set_from_pixbuf(status_icon,
pixbuf);
346 const gchar *card,
const gchar *channel,
347 gdouble volume, gboolean has_mute, gboolean muted)
354 card_info = g_strdup_printf(
"%s (%s)", card, channel);
355 volume_info = g_strdup_printf(
"%s: %ld %%",
_(
"Volume"), lround(volume));
356 if (has_mute == FALSE)
357 mute_info = g_strdup_printf(
_(
"No mute switch"));
359 mute_info = g_strdup_printf(
_(
"Muted"));
363 info = g_strjoin(
"\n", card_info, volume_info, mute_info, NULL);
365 gtk_status_icon_set_tooltip_text(status_icon, info);
410 guint activate_time, G_GNUC_UNUSED
TrayIcon *icon)
412 do_show_popup_menu(gtk_status_icon_position_menu, status_icon, button, activate_time);
427 GdkEventButton *event, G_GNUC_UNUSED
TrayIcon *icon)
429 int middle_click_action;
431 if (event->button != 2)
436 switch (middle_click_action) {
470 if (event->direction == GDK_SCROLL_UP)
472 else if (event->direction == GDK_SCROLL_DOWN)
491 DEBUG(
"Tray icon size is now %d", size);
499 DEBUG(
"Forcing size to the minimum value %d", size);
538 const gchar *card, *channel;
586 DEBUG(
"Creating tray icon");
604 g_signal_connect(icon->
status_icon,
"button-release-event",
607 g_signal_connect(icon->
status_icon,
"scroll_event",
610 g_signal_connect(icon->
status_icon,
"size-changed",
618 gtk_status_icon_set_visible(icon->
status_icon, TRUE);
Internationalization support.
void audio_raise_volume(Audio *audio, AudioUser user)
GtkStatusIcon * status_icon
static void on_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, G_GNUC_UNUSED TrayIcon *icon)
const char * audio_get_card(Audio *audio)
static GdkPixbuf * pixbuf_new_from_stock(const gchar *icon_name, gint size)
static GdkPixbuf * vol_meter_draw(VolMeter *vol_meter, GdkPixbuf *pixbuf, int volume)
static void vol_meter_free(VolMeter *vol_meter)
static void on_activate(G_GNUC_UNUSED GtkStatusIcon *status_icon, G_GNUC_UNUSED TrayIcon *icon)
void audio_signals_disconnect(Audio *audio, AudioCallback callback, gpointer data)
gboolean audio_has_mute(Audio *audio)
void audio_toggle_mute(Audio *audio, AudioUser user)
void audio_signals_connect(Audio *audio, AudioCallback callback, gpointer data)
gboolean audio_is_muted(Audio *audio)
static gboolean on_size_changed(G_GNUC_UNUSED GtkStatusIcon *status_icon, gint size, TrayIcon *icon)
gdouble * prefs_get_double_list(const gchar *key, gsize *n)
gboolean prefs_get_boolean(const gchar *key, gboolean def)
void tray_icon_destroy(TrayIcon *icon)
static GdkPixbuf ** pixbuf_array_new(int size)
const char * audio_get_channel(Audio *audio)
static GdkPixbuf * pixbuf_new_from_file(const gchar *filename)
gchar * get_pixmap_file(const gchar *filename)
void run_mixer_command(void)
static gboolean on_scroll_event(G_GNUC_UNUSED GtkStatusIcon *status_icon, GdkEventScroll *event, TrayIcon *icon)
void run_custom_command(void)
static void update_status_icon_pixbuf(GtkStatusIcon *status_icon, GdkPixbuf **pixbufs, VolMeter *vol_meter, gdouble volume, gboolean muted)
void do_show_popup_menu(GtkMenuPositionFunc func, gpointer data, guint button, guint activate_time)
static void update_status_icon_tooltip(GtkStatusIcon *status_icon, const gchar *card, const gchar *channel, gdouble volume, gboolean has_mute, gboolean muted)
gdouble audio_get_volume(Audio *audio)
void run_prefs_dialog(void)
gint prefs_get_integer(const gchar *key, gint def)
static VolMeter * vol_meter_new(void)
static void pixbuf_array_free(GdkPixbuf **pixbufs)
void tray_icon_reload(TrayIcon *icon)
static void on_audio_changed(G_GNUC_UNUSED Audio *audio, AudioEvent *event, gpointer data)
TrayIcon * tray_icon_create(Audio *audio)
void audio_lower_volume(Audio *audio, AudioUser user)
static gboolean on_button_release_event(G_GNUC_UNUSED GtkStatusIcon *status_icon, GdkEventButton *event, G_GNUC_UNUSED TrayIcon *icon)
Header for ui-tray-icon.c.
void do_toggle_popup_window(void)