/** * Callback function for the mixer element which is * set in alsaset(). * * @param e mixer element * @param mask event mask * @return 0 on success otherwise a negative error code */ static int alsa_cb(snd_mixer_elem_t *e, unsigned int mask) { /* Test MASK_REMOVE first, according to Alsa documentation */ if (mask == SND_CTL_EVENT_MASK_REMOVE) { return 0; } /* Then check if mixer value changed */ if (mask & SND_CTL_EVENT_MASK_VALUE) { int muted; get_current_levels(); muted = ismuted(); on_volume_has_changed(); if (enable_noti && external_noti) { int vol = getvol(); if (muted) do_notify_volume(vol, FALSE); else do_notify_volume(vol, TRUE); } } return 0; }
/** * Mutes or unmutes playback and sends a notification (if enabled). * * @param notify whether to send notification */ void setmute(gboolean notify) { if (!snd_mixer_selem_has_playback_switch(elem)) return; if (ismuted()) { snd_mixer_selem_set_playback_switch_all(elem, 0); if (enable_noti && notify) do_notify_volume(getvol(), TRUE); } else { snd_mixer_selem_set_playback_switch_all(elem, 1); if (enable_noti && notify) do_notify_volume(getvol(), FALSE); } }
/** * Updates all mute checkboxes and synchronizes them. This includes * mute_check_popup_window and mute_check_popup_menu. Usually called after * volume has been muted or changed. */ void update_mute_checkboxes(void) { /* we only want to update the icons and not emit any signals */ g_signal_handler_block(G_OBJECT(mute_check_popup_menu), mute_check_popup_menu_handler); g_signal_handler_block(G_OBJECT(mute_check_popup_window), mute_check_popup_window_handler); if (ismuted() == 1) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mute_check_popup_window), FALSE); #ifdef WITH_GTK3 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mute_check_popup_menu), FALSE); #else gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(mute_check_popup_menu), FALSE); #endif } else { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mute_check_popup_window), TRUE); #ifdef WITH_GTK3 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mute_check_popup_menu), TRUE); #else gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(mute_check_popup_menu), TRUE); #endif } /* release the signal block */ g_signal_handler_unblock(G_OBJECT(mute_check_popup_menu), mute_check_popup_menu_handler); g_signal_handler_unblock(G_OBJECT(mute_check_popup_window), mute_check_popup_window_handler); }
/** * Updates the tray icon. Usually called after volume has been muted * or changed. */ void update_tray_icon(void) { int muted; int tmpvol = getvol(); char tooltip[60]; gchar *active_card_name = (alsa_get_active_card())->name; const char *active_channel = alsa_get_active_channel(); muted = ismuted(); if (muted == 1) { GdkPixbuf *icon; if (tmpvol == 0) icon = status_icons[VOLUME_OFF]; else if (tmpvol < 33) icon = status_icons[VOLUME_LOW]; else if (tmpvol < 66) icon = status_icons[VOLUME_MEDIUM]; else icon = status_icons[VOLUME_HIGH]; sprintf(tooltip, _("%s (%s)\nVolume: %d %%"), active_card_name, active_channel, tmpvol); if (vol_meter_row) { GdkPixbuf *old_icon = icon_copy; icon_copy = gdk_pixbuf_copy(icon); draw_vol_meter(icon_copy, draw_offset, 5, (tmpvol * vol_div_factor)); if (old_icon) g_object_unref(old_icon); gtk_status_icon_set_from_pixbuf(tray_icon, icon_copy); } else gtk_status_icon_set_from_pixbuf(tray_icon, icon); } else { gtk_status_icon_set_from_pixbuf(tray_icon, status_icons[VOLUME_MUTED]); sprintf(tooltip, _("%s (%s)\nVolume: %d %%\nMuted"), active_card_name, active_channel, tmpvol); } gtk_status_icon_set_tooltip_text(tray_icon, tooltip); }
/** * This function is called before gdk/gtk can respond * to any(!) window event and handles pressed hotkeys. * * @param gdk_xevent the native event to filter * @param event the GDK event to which the X event will be translated * @param data user data set when the filter was installed * @return a GdkFilterReturn value, should be GDK_FILTER_CONTINUE only */ static GdkFilterReturn key_filter(GdkXEvent *gdk_xevent, G_GNUC_UNUSED GdkEvent *event, G_GNUC_UNUSED gpointer data) { int type; guint key, state; XKeyEvent *xevent; //gboolean bResult; xevent = gdk_xevent; type = xevent->type; if (type == KeyPress) { key = ((XKeyEvent *) xevent)->keycode; state = ((XKeyEvent *) xevent)->state; if ((int) key == volMuteKey && checkModKey(state, volMuteMods)) { setmute(enable_noti && hotkey_noti); on_volume_has_changed(); return GDK_FILTER_CONTINUE; } else { int cv = getvol(); if ((int) key == volUpKey && checkModKey(state, volUpMods)) { setvol(cv + volStep, 1, enable_noti && hotkey_noti); } else if ((int) key == volDownKey && checkModKey(state, volDownMods)) { setvol(cv - volStep, -1, enable_noti && hotkey_noti); } // just ignore unknown hotkeys if (ismuted() == 0) setmute(enable_noti && hotkey_noti); on_volume_has_changed(); // this will set the slider value get_current_levels(); } } return GDK_FILTER_CONTINUE; }
/** * Checks whether playback is muted, updates the icon * and returns the result of ismuted(). * * @param set_check whether the GtkCheckButton 'Mute' on the * volume popup_window is updated * @return result of ismuted() */ int get_mute_state(gboolean set_check) { int muted; int tmpvol = getvol(); char tooltip [60]; muted = ismuted(); if( muted == 1 ) { GdkPixbuf *icon; if (set_check) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mute_check), FALSE); if (tmpvol < 33) icon = status_icons[1]; else if (tmpvol < 66) icon = status_icons[2]; else icon = status_icons[3]; sprintf(tooltip, _("Volume: %d %%"), tmpvol); if (vol_meter_row) { GdkPixbuf* old_icon = icon_copy; icon_copy = gdk_pixbuf_copy(icon); draw_vol_meter(icon_copy,draw_offset,5,(tmpvol*vol_div_factor)); if (old_icon) g_object_unref(old_icon); gtk_status_icon_set_from_pixbuf(tray_icon, icon_copy); } else gtk_status_icon_set_from_pixbuf(tray_icon, icon); } else { if (set_check) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mute_check), TRUE); gtk_status_icon_set_from_pixbuf(tray_icon, status_icons[0]); sprintf(tooltip, _("Volume: %d %%\nMuted"), tmpvol); } gtk_status_icon_set_tooltip_text(tray_icon, tooltip); return muted; }