void menu_info_subitem_clicked(GtkWidget* item, GdkEvent* event, menu_info_item_t* mii) { #ifdef DEBUG g_message("move %s %s to %s %s", menu_info_type_name(mii->menu_info->parent->menu_info->type), mii->menu_info->parent->desc, menu_info_type_name(mii->menu_info->type), mii->desc); #endif switch(mii->menu_info->type) { case MENU_SERVER: break; case MENU_SINK: pulseaudio_move_input_to_sink(mii->menu_info->parent, mii); break; case MENU_SOURCE: pulseaudio_move_output_to_source(mii->menu_info->parent, mii); break; case MENU_INPUT: case MENU_OUTPUT: break; } }
void menu_info_item_update(menu_info_t* mi, uint32_t index, const char* name, const char* desc, const pa_cvolume* vol, int mute, char* tooltip, const char* icon, const char* address, uint32_t target) { menu_info_item_t* item; if(mi->type == MENU_SERVER) item = menu_info_item_get_by_name(mi, name); else item = menu_info_item_get(mi, index); if(item == NULL) { menu_info_item_add(mi, index, name, desc, vol, mute, tooltip, icon, address, target); return; } g_debug("[menu_info] updating %s %u %s (target: %d)", menu_info_type_name(item->menu_info->type), index, desc, (int)target); g_free(item->name); item->name = g_strdup(name); g_free(item->desc); item->desc = g_strdup(desc); g_free(item->volume); item->volume = g_memdup(vol, sizeof(pa_cvolume)); item->mute = mute; item->target = target; g_free(item->address); item->address = g_strdup(address); menu_type_t submenu_type = menu_info_submenu_type(mi->type); menu_info_t* submenu = &mi->menu_infos->menu_info[submenu_type]; gtk_menu_item_set_label(GTK_MENU_ITEM(item->widget), desc); systray_set_tooltip(GTK_WIDGET(item->widget), tooltip); switch(mi->type) { case MENU_SERVER: case MENU_MODULE: g_debug("[menu_info] *** unhandled %s update! (index: %u, desc: %s)", menu_info_type_name(mi->type), index, desc); break; case MENU_SINK: case MENU_SOURCE: systray_update_item_in_all_submenus(item, submenu); break; case MENU_INPUT: case MENU_OUTPUT: systray_update_all_items_in_submenu(submenu, item); break; } /* if this is the default sink, update status icon acording to volume */ if(mi->type == MENU_SINK && item == menu_info_item_get_by_name(mi, mi->default_name)) ui_update_systray_icon(item); }
void pulseaudio_rename(menu_info_item_t* mii, const char* name) { g_debug("rename %s '%s' to '%s'", menu_info_type_name(mii->menu_info->type), mii->desc, name); char *key = g_markup_printf_escaped("%s:%s", menu_info_type_name(mii->menu_info->type), mii->name); pa_operation* o; if(!(o = pa_ext_device_manager_set_device_description(context, key, name, pulseaudio_rename_success_cb, mii))) { g_warning("pa_ext_device_manager_set_device_description(context, %s, %s) failed", key, name); return; } pa_operation_unref(o); }
void menu_info_item_rename_dialog(menu_info_item_t* mii) { gtk_menu_popdown(GTK_MENU(mii->menu_info->menu_infos->menu)); char* title = g_strdup_printf("Rename %s %s", menu_info_type_name(mii->menu_info->type), mii->desc); char* text = g_strdup_printf("%s to:", title); GtkDialog* dialog = ui_renamedialog(); gtk_window_set_title(GTK_WINDOW(dialog), title); gtk_label_set_text(ui_renamedialog_label(), text); gtk_entry_set_text(ui_renamedialog_entry(), mii->desc); g_free(text); g_free(title); gtk_widget_show_all(GTK_WIDGET(dialog)); if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { const char* entry = gtk_entry_get_text(GTK_ENTRY(ui_renamedialog_entry())); char* name = g_strstrip(g_strdup(entry)); if(!g_str_equal(name, mii->desc)) pulseaudio_rename(mii, name); g_free(name); } gtk_widget_hide(GTK_WIDGET(dialog)); }
void pulseaudio_toggle_mute_success_cb(pa_context *c, int success, void *userdata) { menu_info_item_t* mii = userdata; if(!success) g_warning("failed to toggle mute for %s \"%s\"!\n", menu_info_type_name(mii->menu_info->type), mii->name); }
void menu_info_item_remove_by_name(menu_info_t* mi, const char* name) { menu_info_item_t* mii = menu_info_item_get_by_name(mi, name); if(!mii) { g_warning("failed to remove %s '%s': item not found!", menu_info_type_name(mi->type), name); return; } g_debug("[menu_info] removing %s %s (by name: '%s')", menu_info_type_name(mi->type), mii->desc, name); systray_remove_item(mii); g_hash_table_foreach_remove(mi->items, name_equal, mii->name); }
void menu_info_item_rename_error(menu_info_item_t* mii) { gchar* title = g_strdup_printf("Failed to rename %s", menu_info_type_name(mii->menu_info->type)); GtkDialog* dialog = ui_errordialog(title, "Is the module-device-manager loaded?"); g_free(title); gtk_dialog_run(dialog); gtk_widget_destroy(GTK_WIDGET(dialog)); }
void pulseaudio_set_default_success_cb(pa_context *c, int success, void *userdata) { menu_info_item_t* mii = userdata; if(success) { if(mii->menu_info->type == MENU_SINK) ui_update_systray_icon(mii); } else g_warning("failed to set default to %s \"%s\"!\n", menu_info_type_name(mii->menu_info->type), mii->name); }
void pulseaudio_move_success_cb(pa_context *c, int success, void *userdata) { menu_info_item_t* mii = userdata; if(!success) { g_warning("failed to move %s '%s'!\n", menu_info_type_name(mii->menu_info->type), mii->desc); menu_info_t* mi = mii->menu_info; menu_info_item_update(mi, mii->index, mii->name, mii->desc, mii->volume, mii->mute, NULL, mii->icon, mii->address, mii->target); } }
void menu_info_item_remove(menu_info_t* mi, uint32_t index) { menu_info_item_t* mii = menu_info_item_get(mi, index); if(!mii) return; g_debug("[menu_info] removing %s %u", menu_info_type_name(mi->type), index); systray_remove_item(mii); g_hash_table_remove(mi->items, GUINT_TO_POINTER(index)); }
void pulseaudio_move_all(menu_info_item_t* mii) { menu_infos_t* mis = mii->menu_info->menu_infos; menu_type_t target_type = mii->menu_info->type; menu_type_t source_type = (target_type == MENU_SINK) ? MENU_INPUT : MENU_OUTPUT; g_debug("[pulseaudio_action] move all %s to %s %s", menu_info_type_name(source_type), menu_info_type_name(target_type), mii->desc); GHashTableIter iter; gpointer key; gpointer value; g_hash_table_iter_init(&iter, mis->menu_info[MENU_INPUT].items); while (g_hash_table_iter_next(&iter, &key, &value)) { if (target_type == MENU_SINK) pulseaudio_move_input_to_sink(value, mii); else if (target_type == MENU_SOURCE) pulseaudio_move_output_to_source(value, mii); } }
void pulseaudio_update_volume_notification(menu_info_item_t* mii) { gchar* label = menu_info_item_label(mii); gchar* msg = g_strdup_printf("%s %s", menu_info_type_name(mii->menu_info->type), label); g_free(label); gint volume = (mii->volume->values[0]*100+PA_VOLUME_NORM/2)/PA_VOLUME_NORM; if(!mii->notify) mii->notify = notify(msg, NULL, mii->icon, volume); else notify_update(mii->notify, msg, NULL, mii->icon, volume); g_free(msg); }
void menu_info_subitem_update(menu_info_t* mi, uint32_t index, const char* name, const char* desc, char* tooltip, const char* icon) { menu_info_item_t* item = menu_info_item_get(mi, index); if(item == NULL) g_error("[menu_info] subitem not found!"); gboolean active = mi->parent->target == index; g_debug("[menu_info] updating subitem %s %u '%s' %s", menu_info_type_name(mi->type), index, desc, active ? " (active)" : ""); if(!g_str_equal(item->desc, desc)) gtk_menu_item_set_label(GTK_MENU_ITEM(item->widget), desc); if(active) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item->widget), TRUE); }
void pulseaudio_set_volume_success_cb(pa_context *c, int success, void *userdata) { menu_info_item_t* mii = userdata; if(!success) { g_warning("failed to set volume for %s \"%s\"!\n", menu_info_type_name(mii->menu_info->type), mii->name); return; } menu_infos_t* mis = mii->menu_info->menu_infos; /* update sink icon */ if(mii->menu_info->type == MENU_SINK || mii->menu_info->type == MENU_SOURCE) ui_set_volume_icon(mii); if(mis->settings.notify != NOTIFY_NEVER) { pulseaudio_update_volume_notification(mii); } }
void menu_info_subitem_add(menu_info_t* mi, uint32_t index, const char* name, const char* desc, char* tooltip, const char* icon) { menu_info_item_t* subitem = g_new(menu_info_item_t, 1); menu_info_item_init(subitem); subitem->index = index; subitem->name = g_strdup(name); subitem->desc = g_strdup(desc); subitem->menu_info = mi; subitem->widget = systray_add_radio_item(mi, desc, tooltip); gboolean active = mi->parent->target == index; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem->widget), active); g_debug("[menu_info] adding subitem %s %u '%s' %s", menu_info_type_name(mi->type), index, desc, active ? " (active)" : ""); g_hash_table_insert(mi->items, GUINT_TO_POINTER(index), subitem); g_signal_connect(subitem->widget, "button-press-event", G_CALLBACK(menu_info_subitem_clicked), subitem); }
void menu_info_item_add(menu_info_t* mi, uint32_t index, const char* name, const char* desc, const pa_cvolume* vol, int mute, char* tooltip, const char* icon, const char* address, uint32_t target) { menu_infos_t* mis = mi->menu_infos; menu_info_item_t* item = g_new(menu_info_item_t, 1); menu_info_item_init(item); item->menu_info = mi; g_debug("[menu_info] adding %s %u %s (target: %d)", menu_info_type_name(mi->type), index, desc, (int)target); item->index = index; item->name = g_strdup(name); item->desc = g_strdup(desc); item->volume = g_memdup(vol, sizeof(pa_cvolume)); item->target = target; item->mute = mute; item->icon = g_strdup(icon); item->address = g_strdup(address); menu_type_t submenu_type = menu_info_submenu_type(mi->type); menu_info_t* submenu = &mis->menu_info[submenu_type]; switch(item->menu_info->type) { case MENU_INPUT: case MENU_OUTPUT: item->submenu = menu_info_create(mis, submenu_type); item->submenu->parent = item; break; default: break; } switch(mi->type) { case MENU_SERVER: item->widget = systray_add_radio_item(mi, desc, tooltip); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item->widget), (item->address == mi->default_name) || (item->address && mi->default_name && g_str_equal(mi->default_name, item->address))); break; case MENU_SINK: case MENU_SOURCE: item->context = menu_info_item_context_menu(item); item->widget = systray_add_radio_item(mi, desc, tooltip); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item->widget), g_str_equal(mi->default_name, item->name)); systray_add_item_to_all_submenus(item, submenu); break; case MENU_INPUT: case MENU_OUTPUT: item->widget = systray_menu_add_submenu(mi->menu, item->submenu, desc, tooltip, icon); systray_add_all_items_to_submenu(submenu, item); break; case MENU_MODULE: item->context = menu_info_item_context_menu(item); item->widget = systray_add_menu_item(mi, desc, tooltip, icon); break; } g_signal_connect(item->widget, "button-press-event", G_CALLBACK(menu_info_item_clicked), item); gtk_widget_add_events(item->widget, GDK_SCROLL_MASK); g_signal_connect(item->widget, "scroll-event", G_CALLBACK(menu_info_item_scrolled), item); if(mi->type == MENU_SERVER) g_hash_table_insert(mi->items, item->name, item); else g_hash_table_insert(mi->items, GUINT_TO_POINTER(index), item); /* if this is the default sink, update status icon acording to volume */ if(mi->type == MENU_SINK && item == menu_info_item_get_by_name(mi, mi->default_name)) ui_update_systray_icon(item); }
void menu_info_item_update(menu_info_t* mi, uint32_t index, const char* name, const char* desc, const pa_cvolume* vol, int mute, char* tooltip, const char* icon, const char* address) { menu_info_item_t* mii; if(mi->type == MENU_SERVER) mii = menu_info_item_get_by_name(mi, name); else mii = menu_info_item_get(mi, index); if(mii == NULL) return menu_info_item_add(mi, index, name, desc, vol, mute, tooltip, icon, address); #ifdef DEBUG g_message("[menu_info] updating %s %u %s", menu_info_type_name(mii->menu_info->type), index, desc); #endif g_free(mii->name); mii->name = g_strdup(name); g_free(mii->desc); mii->desc = g_strdup(desc); g_free(mii->volume); mii->volume = g_memdup(vol, sizeof(pa_cvolume)); mii->mute = mute; g_free(mii->address); mii->address = g_strdup(address); switch(mi->type) { case MENU_SERVER: case MENU_SINK: case MENU_SOURCE: gtk_menu_item_set_label(GTK_MENU_ITEM(mii->widget), desc); systray_set_tooltip(GTK_WIDGET(mii->widget), tooltip); // submenu to update (if any) menu_info_t* submenu = NULL; switch(mi->type) { case MENU_SINK: submenu = &mi->menu_infos->menu_info[MENU_INPUT]; break; case MENU_SOURCE: submenu = &mi->menu_infos->menu_info[MENU_OUTPUT]; break; default: break; } // change labels in stream submenus if(submenu) { GHashTableIter iter; gpointer key; menu_info_item_t* item; menu_info_item_t* subitem; g_hash_table_iter_init(&iter, submenu->items); while(g_hash_table_iter_next(&iter, &key, (gpointer*)&item)) if((subitem = g_hash_table_lookup(item->submenu->items, GUINT_TO_POINTER(mii->index)))) if(!g_str_equal(subitem->desc, desc)) gtk_menu_item_set_label( GTK_MENU_ITEM(subitem->widget), desc); } break; case MENU_INPUT: case MENU_OUTPUT: gtk_menu_item_set_label(GTK_MENU_ITEM(mii->widget), desc); systray_set_tooltip(GTK_WIDGET(mii->widget), tooltip); break; } /* if this is the default sink, update status icon acording to volume */ if(mi->type == MENU_SINK && mii == menu_info_item_get_by_name(mi, mi->default_name)) ui_update_statusicon(mii); }