gkrellm-volume-2.1.13/0000755000175000017500000000000010111204200015313 5ustar sjoerdsjoerd00000000000000gkrellm-volume-2.1.13/Changelog0000644000175000017500000000442010111204177017142 0ustar sjoerdsjoerd000000000000002.1.13: * Brown paper bag bug in alsa backend introduced in the previous version. 2.1.12: * Fix mousewheel scrolling in the balance slider (pointed out by Philip Lafleur ) * es translatoion by YoaR * Backend support for switches, not available in the frontend yet 2.1.11: * Added alsa support ! 2.1.10: * Updated french translation by Jérôme UZEL * Fixed some spelling errors in the info thanks to A Costa * React on horizontal scrolling correctly 2.1.9: * Better explanation of the options in the info tab * Updated german translation by Steffen Weise * Updated polish translation by Mariusz Jedrzejewski * Updated dutch translation by Michiel Sikkes * Updated russian translation by Grigory Batalov 2.1.8: * Right click on the plugin causes a configurable command to be run. Patch by Tomas Styblo 2.1.7: * Resolve symlinks on mixer detection based on a patch by Jérôme UZEL 2.1.6: * French translation by Jérôme UZEL * German translation by Steffen Weise 2.1.5: * Patch by Grigory Batalov for i18n * Russian translation by Grigory Batalov * Dutch translation by Michiel Sikkes 2.1.4: * Patch for FreeBSD from Hajimu UMEMOTO 2.1.3: * Don't mix g_free/free calls with g_malloc/malloc * incorperated win32 update from Bill Nalens * Posibilty to theme the sliders, see the THEMING file 2.1.2: * The sliders go back to the right position after a theme change * Don't crash when changing a theme with a balance slider on 2.1.1: * Fixed a bug which caused the balance to be fully to the left after muting 2.1.0: * Possibility to add a balance control to the mixer krells * Possibility to save mixer volume and balans and reset it on startup * Middle mouse button let's you mute some stuff * Various other tweaks 2.0.1: * incorperated win32 update from Bill Nalens * Limit scrolling the mouse wheel down 2.0: * Complete rewrite for gtk 2 and gkrellm 2 gkrellm-volume-2.1.13/Makefile0000644000175000017500000000201610111204177016767 0ustar sjoerdsjoerd00000000000000# Makefile for GKrellM volume plugin PACKAGE ?= gkrellm-volume LOCALEDIR ?= /usr/local/share/locale FLAGS += -DPACKAGE="\"$(PACKAGE)\"" export PACKAGE LOCALEDIR GTK_CONFIG = pkg-config gtk+-2.0 PLUGIN_DIR ?= /usr/local/lib/gkrellm2/plugins GKRELLM_INCLUDE = -I/usr/local/include GTK_CFLAGS = `$(GTK_CONFIG) --cflags` GTK_LIB = `$(GTK_CONFIG) --libs` FLAGS = -O2 -Wall -fPIC $(GTK_CFLAGS) $(GKRELLM_INCLUDE) LIBS = $(GTK_LIB) LFLAGS = -shared OBJS = volume.o mixer.o oss_mixer.o ifeq ($(enable_alsa),1) FLAGS += -DALSA LIBS += -lasound OBJS += alsa_mixer.o endif ifeq ($(enable_nls),1) FLAGS += -DENABLE_NLS -DLOCALEDIR=\"$(LOCALEDIR)\" export enable_nls endif CC = gcc $(CFLAGS) $(FLAGS) INSTALL = install -c INSTALL_PROGRAM = $(INSTALL) -s all: volume.so (cd po && ${MAKE} all ) volume.so: $(OBJS) $(CC) $(OBJS) -o volume.so $(LIBS) $(LFLAGS) clean: rm -f *.o core *.so* *.bak *~ (cd po && ${MAKE} clean) install: (cd po && ${MAKE} install) $(INSTALL_PROGRAM) volume.so $(PLUGIN_DIR) %.c.o: %.c gkrellm-volume-2.1.13/README0000644000175000017500000000154510111204177016215 0ustar sjoerdsjoerd00000000000000A plugin for gkrellm 2.0 , that let's you control your mixer.. Compiling: =========== The plugin will need at least version 2.0.1 of gtk and version 2.0 of gkrellm alsa: ===== Compile with: make enable_alsa=1 The plugin will prefer alsa and fall back to oss when there is no alsa support. i18n: ===== Compile with: make enable_nls=1 And install with make enable_nls=1 install Installing: =========== Running 'make install' will place the plugin under /usr/local/lib/gkrellm2/plugins ugins.. You can also manually place the resulting volume.so under ~/.gkrellm/plugins.. After restarting gkrellm, you should be able to enable it in the gkrellm plugins configuration menu.. Theming: ======== This plugins supports gkrellm's plugin theming possibilities, it's even included in the default gkrellm theme :))... The keyword of the plugin is "volume". gkrellm-volume-2.1.13/volume.c0000644000175000017500000011233110111204177017004 0ustar sjoerdsjoerd00000000000000#include #include #if !defined(WIN32) #include #endif #include "volume.h" #include "mixer.h" #define VOLUME_STYLE style_id static gint style_id; static GkrellmMonitor *monitor; static GtkWidget *pluginbox; static Mixer *Mixerz; static int global_flags = 0; static int config_global_flags = 0; static GtkWidget *right_click_entry; static char right_click_cmd[1024]; /* functions for the bookkeeping of open mixers and sliders */ /* retuns the added mixer or and existing one with the same id */ static Mixer *add_mixer_by_id(char *id) { Mixer *result,**m; mixer_t *mixer; if (Mixerz == NULL) m = &Mixerz; else { result = Mixerz; do { if (!strcmp(id,result->id)) return result; } while (result->next != NULL && (result = result->next)); m = &(result->next); } if ((mixer = mixer_open(id)) == NULL) return NULL; result = malloc(sizeof(Mixer)); result->id = strdup(id); result->mixer = mixer; result->next = NULL; result->Sliderz = NULL; /* add The Mixer to the end */ *m = result; return result; } static void remove_mixer(Mixer *m) { Slider *s,*s1; Mixer *tmp; for (s = m->Sliderz ; s != NULL ;s = s1) { gkrellm_panel_destroy(s->panel); if (s->bal) gkrellm_panel_destroy(s->bal->panel); s1 = s->next; free(s->bal); free(s); } mixer_close(m->mixer); free(m->id); if (Mixerz == m) Mixerz = m->next; else { for (tmp = Mixerz; tmp->next != m; tmp = tmp->next); /* tmp->next == m */ tmp->next = m->next; } } static void remove_all_mixers() { while(Mixerz != NULL) remove_mixer(Mixerz); } static Slider *add_slider(Mixer *m, int dev) { Slider *result,*s; if (dev < 0 || dev >= mixer_get_nr_devices(m->mixer)) return NULL; result = malloc(sizeof(Slider)); result->mixer = m->mixer; result->parent = m; result->dev = dev; result->flags = 0; result->next = NULL; result->krell = NULL; result->panel = NULL; result->balance = 0; result->pleft = result->pright = -1; result->bal = NULL; if (m->Sliderz == NULL) m->Sliderz = result; else { for (s = m->Sliderz ; s->next != NULL; s = s->next); s->next = result; } return result; } /*---*/ static gint bvolume_expose_event(GtkWidget *widget, GdkEventExpose *event,gpointer slide) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], ((Bslider *)slide)->panel->pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return TRUE; } static gint volume_expose_event(GtkWidget *widget, GdkEventExpose *event,gpointer slide) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], ((Slider *)slide)->panel->pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return TRUE; } static gint volume_get_volume(Slider *s) { gint left,right; mixer_get_device_volume(s->mixer,s->dev,&left,&right); return left > right ? left : right; } static void volume_show_volume(Slider *s) { if (s->krell != NULL) gkrellm_update_krell(s->panel,s->krell,volume_get_volume(s)); gkrellm_draw_panel_layers(s->panel); gkrellm_config_modified(); } static void volume_set_volume(Slider *s,gint volume) { gint left,right; if (GET_FLAG(s->flags,MUTED)) return; volume = volume < 0 ? 0 : volume; if (volume < 0) volume = 0; else if (volume > mixer_get_device_fullscale(s->mixer,s->dev)) volume = mixer_get_device_fullscale(s->mixer,s->dev); if (s->balance == 0 && !GET_FLAG(s->flags,BALANCE)) left = right = volume; else if (s->balance > 0) { right = volume; left = ((100 - s->balance)* volume) / 100; } else { /* balance < 0 */ left = volume; right = ((100 + s->balance)* volume) / 100; } mixer_set_device_volume(s->mixer,s->dev,left,right); s->pleft = left; s->pright = right; volume_show_volume(s); } static void volume_show_balance(Slider *s) { gchar *buf; gchar *buf_utf8 = NULL, *buf_locale = NULL; if (s->bal == NULL) return; if (s->balance == 0) buf = g_strdup(_("Centered")); else buf = g_strdup_printf("%3d%% %s",abs(s->balance), s->balance > 0 ? _("Right") : _("Left")); gkrellm_locale_dup_string(&buf_utf8, buf, &buf_locale); gkrellm_draw_decal_text(s->bal->panel,s->bal->decal,buf_locale,-1); gkrellm_update_krell(s->bal->panel,s->bal->krell,s->balance + 100 ); gkrellm_draw_panel_layers(s->bal->panel); g_free(buf); g_free(buf_locale); g_free(buf_utf8); } static void volume_set_balance(Slider *s,gint amount) { if (amount < -100) amount = -100; else if (amount > 100) amount = 100; if (abs(amount) <= 3) amount = 0; s->balance = amount; volume_set_volume(s,volume_get_volume(s)); volume_show_balance(s); } static void volume_mute_mixer(Mixer *m) { Slider *s; for (s = m->Sliderz ; s != NULL ; s = s->next) { mixer_set_device_volume(s->mixer,s->dev,0,0); volume_show_volume(s); SET_FLAG(s->flags,MUTED); } } static void volume_unmute_mixer(Mixer *m) { Slider *s; for (s = m->Sliderz ; s != NULL ; s = s->next) { DEL_FLAG(s->flags,MUTED); mixer_set_device_volume(s->mixer,s->dev,s->pleft,s->pright); volume_show_volume(s); } } static void volume_toggle_mute(Slider *s) { Mixer *m; if (GET_FLAG(s->flags,MUTED)) { if (GET_FLAG(global_flags,MUTEALL)) { for (m = Mixerz ; m != NULL; m = m->next) volume_unmute_mixer(m); } else volume_unmute_mixer(s->parent); } else { if (GET_FLAG(global_flags,MUTEALL)) { for (m = Mixerz ; m != NULL; m = m->next) volume_mute_mixer(m); } else volume_mute_mixer(s->parent); } } static gint bvolume_cb_scroll(GtkWidget *widget, GdkEventScroll *event,Bslider *s) { int amount = 0; switch (event->direction) { case GDK_SCROLL_UP: case GDK_SCROLL_RIGHT: amount = 5; break; case GDK_SCROLL_DOWN: case GDK_SCROLL_LEFT: amount = -5; break; } volume_set_balance(s->slider,s->slider->balance + amount); return TRUE; } static gint volume_cb_scroll(GtkWidget *widget, GdkEventScroll *event,Slider *s) { gint amount; amount = volume_get_volume(s); switch (event->direction) { case GDK_SCROLL_UP: case GDK_SCROLL_RIGHT: amount += 5; break; case GDK_SCROLL_DOWN: case GDK_SCROLL_LEFT: amount -= 5; break; } volume_set_volume(s,amount); return TRUE; } static void run_right_click_cmd() { if (right_click_cmd) { g_spawn_command_line_async(right_click_cmd,NULL); } } static void bvolume_button_press(GtkWidget *widget, GdkEventButton *ev,Bslider *s) { long location; if (ev->button == 1) { SET_FLAG(s->flags,IS_PRESSED); location = ev->x - s->krell->x0 ; location = location >= 0 ? location : 0; location = (location * 200) / s->krell->w_scale; volume_set_balance(s->slider,location - 100); } else if (ev->button == 3) { run_right_click_cmd(); } } static void volume_button_press(GtkWidget *widget,GdkEventButton *ev,Slider *s) { long location; if (ev->button == 1) { SET_FLAG(s->flags,IS_PRESSED); location = ev->x - s->krell->x0 ; location = location >= 0 ? location : 0; location = (location * mixer_get_device_fullscale(s->mixer,s->dev)) / s->krell->w_scale; volume_set_volume(s,location); } else if (ev->button == 3) { run_right_click_cmd(); } } static void bvolume_button_release(GtkWidget *widget,GdkEventButton *ev,Bslider *s) { if (ev->button == 1) DEL_FLAG(s->flags,IS_PRESSED); if (ev->button == 2) volume_toggle_mute(s->slider); } static void volume_button_release(GtkWidget *widget,GdkEventButton *ev,Slider *s) { if (ev->button == 1) DEL_FLAG(s->flags,IS_PRESSED); if (ev->button == 2) volume_toggle_mute(s); } static void bvolume_motion(GtkWidget *widget,GdkEventMotion *ev,Bslider *s) { gdouble location; if (!(GET_FLAG(s->flags,IS_PRESSED))) return; if (!(ev->state & GDK_BUTTON1_MASK)) { /* just to be sure */ DEL_FLAG(s->flags,IS_PRESSED); return ; } location = ev->x - s->krell->x0 ; location = location >= 0 ? location : 0; location = (location * 200) / s->krell->w_scale; volume_set_balance(s->slider,location - 100); } static void volume_motion(GtkWidget *widget,GdkEventMotion *ev,Slider *s) { gdouble location; if (!GET_FLAG(s->flags,IS_PRESSED)) return; if (!(ev->state & GDK_BUTTON1_MASK)) { /* just to be sure */ DEL_FLAG(s->flags,IS_PRESSED); return ; } location = ev->x - s->krell->x0 ; location = location >= 0 ? location : 0; location = (location * mixer_get_device_fullscale(s->mixer,s->dev)) / s->krell->w_scale; volume_set_volume(s,location); } static void create_bslider(Slider *slide,int first_create) { GkrellmStyle *panel_style = gkrellm_meter_style(VOLUME_STYLE); GkrellmStyle *slider_style = //gkrellm_krell_slider_style(); gkrellm_copy_style(gkrellm_meter_style_by_name("volume.balance_slider")); GkrellmTextstyle *ts = gkrellm_meter_textstyle(VOLUME_STYLE); GkrellmPiximage *krell_image; Bslider *result; gkrellm_set_style_slider_values_default(slider_style,0,0,0); if (first_create) { result = malloc(sizeof(Bslider)); result->panel = gkrellm_panel_new0(); slide->bal = result; result->slider = slide; } else result = slide->bal; krell_image = gkrellm_krell_slider_piximage(); result->krell = gkrellm_create_krell(result->panel,krell_image,slider_style); /* [-100..+100] */ gkrellm_set_krell_full_scale(result->krell,200, 1); gkrellm_monotonic_krell_values(result->krell, FALSE); result->decal = gkrellm_create_decal_text(result->panel,_("Centered"), ts,panel_style,-1,-1,-1); gkrellm_draw_decal_text(result->panel,result->decal,_("Centered"),-1); gkrellm_panel_configure(result->panel,NULL, panel_style); gkrellm_panel_create(pluginbox, monitor, result->panel); if (!gkrellm_style_is_themed(slider_style,GKRELLMSTYLE_KRELL_YOFF)) gkrellm_move_krell_yoff(result->panel, result->krell,(result->panel->h - result->krell->h_frame) / 2); if (first_create) { g_signal_connect(GTK_OBJECT(result->panel->drawing_area), "expose_event", G_CALLBACK(bvolume_expose_event),result); g_signal_connect(G_OBJECT(result->panel->drawing_area), "scroll_event", G_CALLBACK(bvolume_cb_scroll), result); g_signal_connect(G_OBJECT(result->panel->drawing_area),"button_press_event", G_CALLBACK(bvolume_button_press),result); g_signal_connect(GTK_OBJECT(result->panel->drawing_area), "button_release_event", G_CALLBACK(bvolume_button_release),result); g_signal_connect(GTK_OBJECT(result->panel->drawing_area), "motion_notify_event", G_CALLBACK(bvolume_motion),result); } volume_show_balance(slide); } void toggle_button_press(GkrellmDecalbutton *button, Slider *s) { int l,r ; mixer_get_device_volume(s->mixer, s->dev, &l, &r); mixer_set_device_volume(s->mixer, s->dev, ++l % 2, ++r % 2); } static void create_slider(Slider *s,int first_create) { GkrellmStyle *panel_style = gkrellm_meter_style(VOLUME_STYLE); GkrellmStyle *slider_style = gkrellm_copy_style(gkrellm_meter_style_by_name("volume.level_slider")); GkrellmPiximage *krell_image; /* Switches not supported yet ! */ if (mixer_get_device_fullscale(s->mixer, s->dev) == 1) return; gkrellm_set_style_slider_values_default(slider_style,0,0,0); if (first_create) s->panel = gkrellm_panel_new0(); gkrellm_panel_configure(s->panel, mixer_get_device_name(s->mixer,s->dev), panel_style); gkrellm_panel_create(pluginbox, monitor, s->panel); /* center the krell if the style is not themed */ if (mixer_get_device_fullscale(s->mixer, s->dev) != 1) { krell_image = gkrellm_krell_slider_piximage(); s->krell = gkrellm_create_krell(s->panel,krell_image,slider_style); gkrellm_set_krell_full_scale(s->krell, mixer_get_device_fullscale(s->mixer,s->dev), 1); gkrellm_monotonic_krell_values(s->krell, FALSE); if (!gkrellm_style_is_themed(slider_style,GKRELLMSTYLE_KRELL_YOFF)) gkrellm_move_krell_yoff(s->panel, s->krell,(s->panel->h - s->krell->h_frame) / 2); if (first_create) { g_signal_connect(G_OBJECT(s->panel->drawing_area), "scroll_event", G_CALLBACK(volume_cb_scroll), s); g_signal_connect(G_OBJECT(s->panel->drawing_area), "button_press_event", G_CALLBACK(volume_button_press),s); g_signal_connect(GTK_OBJECT(s->panel->drawing_area), "button_release_event", G_CALLBACK(volume_button_release),s); g_signal_connect(GTK_OBJECT(s->panel->drawing_area), "motion_notify_event", G_CALLBACK(volume_motion),s); } } else { g_assert_not_reached(); s->button = gkrellm_make_scaled_button(s->panel, NULL, toggle_button_press, s, FALSE, FALSE, 0, 0, 0, gkrellm_chart_width() - 15, 0, 10, 0 ); } if (first_create) { g_signal_connect(GTK_OBJECT(s->panel->drawing_area), "expose_event", G_CALLBACK(volume_expose_event),s); } volume_show_volume(s); if (GET_FLAG(s->flags,BALANCE)) create_bslider(s,first_create); } static void create_volume_plugin(GtkWidget *vbox,gint first_create) { Mixer *m; Slider *s; pluginbox = vbox; for (m = Mixerz ; m != NULL; m = m->next) for (s = m->Sliderz; s != NULL ; s = s->next) { create_slider(s,first_create); } } static void update_volume_plugin(void) { Slider *s; Mixer *m; for (m = Mixerz; m != NULL; m = m->next) for (s = m->Sliderz ; s != NULL; s = s->next) { int left,right; mixer_get_device_volume(s->mixer,s->dev,&left,&right); /* calculate the balance and show volume if needed */ if (s->pleft!=left || s->pright!=right) { if (GET_FLAG(s->flags,BALANCE)) { if (left < right) { s->balance = 100 - (gint) rint(((gdouble)left/right) * 100); } else if (left > right) { s->balance = (gint) rint(((gdouble)right/left) * 100) - 100; } else if (left == right && left != 0) s->balance = 0; volume_show_balance(s); } if (!GET_FLAG(s->flags,MUTED)) { s->pleft = left; s->pright = right; } volume_show_volume(s); } } } static void save_volume_plugin_config(FILE *f) { Mixer *m; Slider *s; if (GET_FLAG(global_flags,MUTEALL)) fprintf(f,"%s MUTEALL\n",CONFIG_KEYWORD); if (right_click_cmd) { fprintf(f, "%s RIGHT_CLICK_CMD %s\n", CONFIG_KEYWORD, right_click_cmd); } for (m = Mixerz ; m != NULL ; m = m->next) { fprintf(f,"%s ADDMIXER %s\n",CONFIG_KEYWORD,m->id); for(s = m->Sliderz; s != NULL; s = s->next) { fprintf(f,"%s ADDDEV %d\n",CONFIG_KEYWORD,s->dev); if (strcmp(mixer_get_device_name(s->mixer,s->dev), mixer_get_device_real_name(s->mixer,s->dev))) { fprintf(f,"%s SETDEVNAME %s\n",CONFIG_KEYWORD, mixer_get_device_name(s->mixer,s->dev)); } if (GET_FLAG(s->flags,BALANCE)) fprintf(f,"%s SHOWBALANCE\n",CONFIG_KEYWORD); if (GET_FLAG(s->flags,SAVE_VOLUME)) { int left,right; mixer_get_device_volume(s->mixer,s->dev,&left,&right); fprintf(f,"%s SETVOLUME %d %d\n",CONFIG_KEYWORD,left,right); } } } } static void load_volume_plugin_config(gchar *command) { static Mixer *m = NULL; static Slider *s = NULL; gchar *arg; /* gkrellm doesn't care if we fsck the string it gives us */ for (arg = command; !isspace(*arg); arg++); *arg = '\0'; arg++; if (!strcmp("MUTEALL",command)) SET_FLAG(global_flags,MUTEALL); else if (!strcmp("ADDMIXER",command)) { m = add_mixer_by_id(arg); } else if (!strcmp("RIGHT_CLICK_CMD",command)) { g_strlcpy(right_click_cmd, arg, sizeof(right_click_cmd)); } else if (!strcmp("ADDDEV",command)) { if (m != NULL) s = add_slider(m,atoi(arg)); } else if (!strcmp("SETDEVNAME",command)) { if (s != NULL) mixer_set_device_name(s->mixer,s->dev,arg); } else if (!strcmp("SHOWBALANCE",command)) { if (s != NULL) SET_FLAG(s->flags,BALANCE); } else if (!strcmp("SETVOLUME",command)) { if (s != NULL) { char *next; int left,right; left = strtol(arg,&next,10); right = strtol(next,NULL,10); mixer_set_device_volume(s->mixer,s->dev,left,right); SET_FLAG(s->flags,SAVE_VOLUME); } } } /* configuration code */ enum { ID_COLUMN = 0, NAME_COLUMN, C_MODEL_COLUMN, C_NB_COLUMN, N_COLUMNS }; enum { C_ENABLED_COLUMN = 0, C_VOLUME_COLUMN, C_BALANCE_COLUMN, C_NAME_COLUMN, C_SNAME_COLUMN, C_DEVNR_COLUMN, C_N_COLUMNS }; GtkListStore *model; GtkWidget *config_notebook; /* Used to only update the sliderz if needed. So there isn't any unnecessary * flickering */ gboolean mixer_config_changed = FALSE; static void toggle_item(gchar *path_str,gpointer data,gint column) { GtkTreePath *path = gtk_tree_path_new_from_string(path_str); GtkTreeIter iter; gboolean item; gtk_tree_model_get_iter(GTK_TREE_MODEL(data),&iter,path); gtk_tree_model_get(GTK_TREE_MODEL(data),&iter,column,&item,-1); gtk_list_store_set(GTK_LIST_STORE(data),&iter,column,!item,-1); mixer_config_changed = TRUE; gtk_tree_path_free(path); } static void toggle_enabled(GtkCellRendererToggle *cell,gchar *path_str,gpointer data) { toggle_item(path_str,data,C_ENABLED_COLUMN); } static void toggle_volume(GtkCellRendererToggle *cell,gchar *path_str,gpointer data) { toggle_item(path_str,data,C_VOLUME_COLUMN); } static void toggle_balance(GtkCellRendererToggle *cell,gchar *path_str,gpointer data) { toggle_item(path_str,data,C_BALANCE_COLUMN); } static void device_name_edited(GtkCellRendererText *text, gchar *pathstr,gchar *value,gpointer user_data) { GtkTreePath *path = gtk_tree_path_new_from_string(pathstr); GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(user_data),&iter,path); gtk_list_store_set(GTK_LIST_STORE(user_data),&iter,C_SNAME_COLUMN,value,-1); mixer_config_changed = TRUE; } static void up_clicked(GtkWidget *widget,gpointer user_data) { GtkTreeIter selected,up,new; GtkTreeView *view = GTK_TREE_VIEW(user_data); GtkTreeSelection *selection; GtkTreeModel *model; GtkTreePath *path; gchar *name,*id; gpointer *child_model,*nb; selection = gtk_tree_view_get_selection(view); if (!gtk_tree_selection_get_selected(selection,&model,&selected)) return; gtk_tree_model_get(model,&selected, ID_COLUMN,&id, NAME_COLUMN,&name, C_MODEL_COLUMN,&child_model, C_NB_COLUMN,&nb, -1); path = gtk_tree_model_get_path(model,&selected); if (!gtk_tree_path_prev(path)) return; if (!gtk_tree_model_get_iter(model,&up,path)) return; gtk_list_store_remove(GTK_LIST_STORE(model),&selected); gtk_list_store_insert_before(GTK_LIST_STORE(model),&new,&up); gtk_list_store_set(GTK_LIST_STORE(model),&new, ID_COLUMN,id, NAME_COLUMN,name, C_MODEL_COLUMN,child_model, C_NB_COLUMN,nb, -1); mixer_config_changed = TRUE; } static void down_clicked(GtkWidget *widget,gpointer user_data) { GtkTreeIter selected,down,new; GtkTreeView *view = GTK_TREE_VIEW(user_data); GtkTreeSelection *selection; GtkTreeModel *model; GtkTreePath *path; gchar *name,*id; gpointer *child_model,*nb; selection = gtk_tree_view_get_selection(view); if (!gtk_tree_selection_get_selected(selection,&model,&selected)) return; gtk_tree_model_get(model,&selected, ID_COLUMN,&id, NAME_COLUMN,&name, C_MODEL_COLUMN,&child_model, C_NB_COLUMN,&nb, -1); path = gtk_tree_model_get_path(model,&selected); gtk_tree_path_next(path); if (!gtk_tree_model_get_iter(model,&down,path)) return; gtk_list_store_insert_after(GTK_LIST_STORE(model),&new,&down); gtk_list_store_set(GTK_LIST_STORE(model),&new, ID_COLUMN,id, NAME_COLUMN,name, C_MODEL_COLUMN,child_model, C_NB_COLUMN,nb, -1); mixer_config_changed = TRUE; gtk_list_store_remove(GTK_LIST_STORE(model),&selected); } static GtkWidget * create_device_notebook(GtkListStore *store, char *name) { GtkWidget *treeview; GtkCellRenderer *renderer; GtkWidget *scrolledwindow; GtkWidget *label; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *widget; GtkWidget *topvbox; topvbox = gtk_vbox_new(FALSE,0); gtk_container_set_border_width(GTK_CONTAINER(topvbox), 0); label = gtk_label_new(name); /* put the notebook at the end */ gtk_notebook_insert_page(GTK_NOTEBOOK(config_notebook), topvbox, label, gtk_notebook_get_n_pages(GTK_NOTEBOOK(config_notebook)) - 3); vbox = gkrellm_gtk_framed_vbox(topvbox,NULL,2,TRUE,0,2); treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview),TRUE); gtk_tree_selection_set_mode( gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_SINGLE); /* causes it to be destroyed when the treeview is destroyed */ g_object_unref(G_OBJECT(store)); renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_enabled),store); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, _("Enabled"),renderer, "active",C_ENABLED_COLUMN, NULL); renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_volume),store); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, _("Save volume"),renderer, "active",C_VOLUME_COLUMN, "activatable",C_ENABLED_COLUMN, NULL); #if !defined(WIN32) renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_balance),store); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, _("Balance"),renderer, "active",C_BALANCE_COLUMN, "activatable",C_ENABLED_COLUMN, NULL); #endif renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, _("Name"),renderer, "text", C_NAME_COLUMN, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, _("Shown Name"),renderer, "text",C_SNAME_COLUMN, "editable",C_ENABLED_COLUMN, NULL); g_signal_connect(G_OBJECT(renderer),"edited", G_CALLBACK(device_name_edited),store); scrolledwindow = gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); hbox = gtk_hbox_new(FALSE, 3); widget = gtk_button_new_from_stock(GTK_STOCK_GO_UP); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(up_clicked),treeview); gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,3); widget = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(down_clicked),treeview); gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,3); gtk_box_pack_start(GTK_BOX(vbox),scrolledwindow,TRUE,TRUE,3); gtk_container_add(GTK_CONTAINER(scrolledwindow),treeview); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); gtk_widget_show_all(topvbox); return topvbox; } static void add_mixer_to_model(char *id, mixer_t *mixer, Slider *s) { GtkTreeIter iter; GtkListStore *child_model; gboolean enabled,save_volume,balance; GtkWidget *notebook; int i; child_model = gtk_list_store_new(C_N_COLUMNS, G_TYPE_BOOLEAN, /* enabled or not */ G_TYPE_BOOLEAN, /* save volume or not */ G_TYPE_BOOLEAN, /* show balance or not */ G_TYPE_STRING, /* real name */ G_TYPE_STRING, /* set name */ G_TYPE_INT /* device number */ ); for(i = 0; i < mixer_get_nr_devices(mixer); i++) { if (mixer_get_device_fullscale(mixer, i) == 1) { /*Switch not supported yet */ continue; } if (s != NULL && s->dev == i) { enabled = TRUE; save_volume = GET_FLAG(s->flags,SAVE_VOLUME); balance = GET_FLAG(s->flags,BALANCE); s = s->next; } else { enabled = save_volume = balance = FALSE; } gtk_list_store_append(child_model,&iter); gtk_list_store_set(child_model,&iter, C_ENABLED_COLUMN,enabled, C_VOLUME_COLUMN,save_volume, C_BALANCE_COLUMN,balance, C_NAME_COLUMN,mixer_get_device_real_name(mixer,i), C_SNAME_COLUMN,mixer_get_device_name(mixer,i), C_DEVNR_COLUMN,i, -1); } notebook = create_device_notebook(child_model,mixer_get_name(mixer)); gtk_list_store_append(model,&iter); gtk_list_store_set(model,&iter, ID_COLUMN,id, NAME_COLUMN,mixer_get_name(mixer), C_MODEL_COLUMN,child_model, C_NB_COLUMN,notebook, -1); return; } static gboolean findid(GtkTreeModel *m,GtkTreePath *path, GtkTreeIter *iter,gpointer data) { char *item; char **arg = (char **) data; gtk_tree_model_get(m,iter,ID_COLUMN,&item,-1); if (!strcmp(item,*arg)) { *arg = NULL; return TRUE; } return FALSE; } static void add_mixerid_to_model(char *id,gboolean gui) { char **arg = &id; char *name; mixer_t *mixer; gtk_tree_model_foreach(GTK_TREE_MODEL(model),findid,arg); if (id == NULL) { if (gui) gkrellm_message_window(_("Error"),_("Id already in list"),NULL); return; } if ((mixer = mixer_open(id)) == NULL) { if (gui) { name = g_strdup_printf(_("Couldn't open %s or %s isn't a mixer device"),id,id); gkrellm_message_window(_("Error"),name,NULL); g_free(name); } return; } add_mixer_to_model(id,mixer, NULL); mixer_close(mixer); return; } #ifndef WIN32 static void file_choosen(GtkWidget *w,gpointer selector) { char *id; id = (char *) gtk_file_selection_get_filename(GTK_FILE_SELECTION(selector)); add_mixerid_to_model(id,TRUE); } static void select_file(GtkWidget *widget,gpointer user_data) { GtkWidget *selector; selector = gtk_file_selection_new(_("Please select a mixer device")); gtk_file_selection_set_filename(GTK_FILE_SELECTION(selector),"/dev/"); g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(selector)->ok_button), "clicked", G_CALLBACK(file_choosen), selector); g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(selector)->ok_button), "clicked", G_CALLBACK (gtk_widget_destroy), (gpointer) selector); g_signal_connect_swapped( GTK_OBJECT(GTK_FILE_SELECTION(selector)->cancel_button), "clicked", G_CALLBACK (gtk_widget_destroy), (gpointer) selector); gtk_widget_show(selector); } #endif static void create_volume_model(void) { Mixer *m; mixer_idz_t *idz,*t; model = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, /* id */ G_TYPE_STRING, /* name */ G_TYPE_POINTER, /* pointer to the child store */ G_TYPE_POINTER /* pointer to the child NB */ ); for (m = Mixerz; m != NULL; m = m->next) { add_mixer_to_model(m->id,m->mixer,m->Sliderz); } idz = mixer_get_id_list(); for (t = idz; t != NULL; t = t->next) { add_mixerid_to_model(t->id,FALSE); } mixer_free_idz(idz); } static void create_volume_plugin_mixer_tabs(void) { GtkWidget *treeview; GtkWidget *widget,*hbox,*vbox; GtkWidget *scrolledwindow; GtkWidget *notebook; GtkCellRenderer *renderer; notebook = gkrellm_gtk_framed_notebook_page(config_notebook,_("Available mixers")); /* Ugly hack to put the gkrellm created notebook at the start */ gtk_notebook_reorder_child(GTK_NOTEBOOK(config_notebook), gtk_notebook_get_nth_page(GTK_NOTEBOOK(config_notebook), -1), 0); vbox = gtk_vbox_new(FALSE,3); gtk_container_add(GTK_CONTAINER(notebook),vbox); create_volume_model(); /* creating the treeview */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview),TRUE); gtk_tree_selection_set_mode( gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_SINGLE); /* causes it to be destroyed when the treeview is destroyed */ g_object_unref(G_OBJECT(model)); renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_enabled),model); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, _("Id"),renderer, "text", ID_COLUMN, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, _("Mixer Name"),renderer, "text",NAME_COLUMN, NULL); scrolledwindow = gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_box_pack_start(GTK_BOX(vbox),scrolledwindow,TRUE,TRUE,3); gtk_container_add(GTK_CONTAINER(scrolledwindow),treeview); hbox = gtk_hbox_new(FALSE,3); widget = gtk_button_new_from_stock(GTK_STOCK_GO_UP); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(up_clicked),treeview); gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,3); widget = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(down_clicked),treeview); gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,3); #ifndef WIN32 widget = gtk_button_new_from_stock(GTK_STOCK_ADD); gtk_box_pack_end(GTK_BOX(hbox),widget,FALSE,FALSE,3); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(select_file),model); #endif gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,3); gtk_widget_show_all(notebook); } static void option_toggle(GtkWidget *widget,gpointer data) { if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) SET_FLAG(config_global_flags,GPOINTER_TO_INT(data)); else DEL_FLAG(config_global_flags,GPOINTER_TO_INT(data)); } static void create_volume_plugin_config(GtkWidget *tab) { GtkWidget *label,*text,*page,*toggle,*right_click_hbox,*right_click_label; gchar *info_text[] = { N_("Gkrellm Volume Plugin\n\n"), N_("This plugin allows you to control your mixers with gkrellm\n\n"), N_("User Interface:\n"), N_("\tDragging the krells around or turning your mousewheel above a panel\n" \ "\twill change the volume of the device.\n" \ "\tMiddle mouse button will (un)mute the mixer\n\n"), N_(" Configuration:\n"), N_( "\tThe available mixers tab shows the detected mixers. The order of the\n" \ "\tmixers is the same as they will be in the main window\n" \ "\n" \ "\tEach mixer gets its own tab. You can adjust each device separately:\n" \ "\t * Enabled: will cause the device to show up in the main window.\n" \ "\t * Save volume: will cause the volume and balance to be saved on exit\n" \ "\t and reset on startup.\n"), #if !defined(WIN32) N_( "\t * Balance: Gives you a panel below the device to control" \ " its balance\n"), #endif N_("\t * Name: The 'official' name of the device.\n" \ "\t * Shown name: can be edited and is the name shown in the main window.\n"\ "\n"), N_("Options:\n"), N_("\t* Mute all mixers at the same time: Mutes all devices on a middle\n"\ "\t mouse button click instead of only the one the slider belongs to.\n"\ "\t* Right-click command: The command to run when the right mouse\n"\ "\t button is clicked on the plugin\n") }; gint i; gchar *plugin_about_text = g_strdup_printf( _("Volumeplugin %d.%d.%d\n" \ "GKrellM volume Plugin\n\n" \ "Copyright (C) 2000 Sjoerd Simons\n" \ "sjoerd@luon.net\n" \ "http://gkrellm.luon.net \n\n" \ "Released under the GNU Public Licence"), VOLUME_MAJOR_VERSION,VOLUME_MINOR_VERSION,VOLUME_EXTRA_VERSION); config_global_flags= global_flags; config_notebook = gtk_notebook_new(); gtk_notebook_set_scrollable(GTK_NOTEBOOK(config_notebook),TRUE); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(config_notebook), GTK_POS_TOP); gtk_box_pack_start(GTK_BOX(tab), config_notebook, TRUE, TRUE, 0); /* global options tab */ page = gkrellm_gtk_framed_notebook_page(config_notebook,_("Options")); /* option - mute all mixers at the same time */ toggle = gtk_check_button_new_with_label(_("Mute all mixers at the same time")); g_signal_connect(GTK_OBJECT(toggle),"toggled", G_CALLBACK(option_toggle),GINT_TO_POINTER(MUTEALL)); gtk_box_pack_start(GTK_BOX(page),toggle,FALSE,FALSE,3); /* option - right-click command */ right_click_hbox = gtk_hbox_new(FALSE, 0); right_click_label = gtk_label_new(_("Right-click command: ")); gtk_box_pack_start(GTK_BOX(right_click_hbox),right_click_label,FALSE,FALSE,0); right_click_entry = gtk_entry_new(); if (right_click_cmd) gtk_entry_set_text((GtkEntry*)right_click_entry, right_click_cmd); gtk_box_pack_start(GTK_BOX(right_click_hbox),right_click_entry,TRUE,TRUE,8); gtk_box_pack_start(GTK_BOX(page),right_click_hbox,FALSE,FALSE,3); /* info tab */ page = gkrellm_gtk_notebook_page(config_notebook,_("Info")); text = gkrellm_gtk_scrolled_text_view(page,NULL, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); for (i=0; i < sizeof(info_text)/sizeof(gchar *); ++i) gkrellm_gtk_text_view_append(text,_(info_text[i])); /* about tab */ text = gtk_label_new(plugin_about_text); label = gtk_label_new(_("About")); gtk_notebook_append_page(GTK_NOTEBOOK(config_notebook),text,label); g_free(plugin_about_text); /* mixer tabs */ create_volume_plugin_mixer_tabs(); gtk_widget_show_all(config_notebook); } static gboolean add_configed_mixer_device(GtkTreeModel *m, GtkTreePath *path, GtkTreeIter *iter,gpointer data) { gboolean enabled; gboolean save_volume; gboolean balance; gint nr; Slider *s; gchar *rname,*name; gchar *id = (gchar *) data; Mixer *mixer; gtk_tree_model_get(m,iter,C_ENABLED_COLUMN,&enabled,-1); if (enabled) { mixer = add_mixer_by_id(id); gtk_tree_model_get(m,iter, C_DEVNR_COLUMN,&nr, C_VOLUME_COLUMN,&save_volume, C_BALANCE_COLUMN,&balance, C_NAME_COLUMN,&rname, C_SNAME_COLUMN,&name, -1); if (strcmp(name,rname)) mixer_set_device_name(mixer->mixer,nr,name); s = add_slider(mixer,nr); if (save_volume) SET_FLAG(s->flags,SAVE_VOLUME); else DEL_FLAG(s->flags,SAVE_VOLUME); if (balance) SET_FLAG(s->flags,BALANCE); else DEL_FLAG(s->flags,BALANCE); create_slider(s,1); } return FALSE; } static gboolean add_configed_mixer(GtkTreeModel *m,GtkTreePath *path, GtkTreeIter *iter,gpointer data) { GtkListStore *store; gchar *id; gtk_tree_model_get(m,iter,ID_COLUMN,&id,C_MODEL_COLUMN,&store,-1); gtk_tree_model_foreach(GTK_TREE_MODEL(store),add_configed_mixer_device,id); return FALSE; } void apply_volume_plugin_config(void) { if (mixer_config_changed) { remove_all_mixers(); gtk_tree_model_foreach(GTK_TREE_MODEL(model),add_configed_mixer,NULL); mixer_config_changed = FALSE; } global_flags = config_global_flags; if (right_click_entry) { g_strlcpy(right_click_cmd, gtk_entry_get_text((GtkEntry *)right_click_entry), sizeof(right_click_cmd)); } } /* end of configuration code */ static GkrellmMonitor plugin_mon = { "Volume Plugin", /* Name, for config tab. */ 0, /* Id, 0 if a plugin */ create_volume_plugin, /* The create function */ update_volume_plugin, /* The update function */ create_volume_plugin_config, /* The config tab create function */ apply_volume_plugin_config, /* Apply the config function */ save_volume_plugin_config, /* Save user config */ load_volume_plugin_config, /* Load user config */ CONFIG_KEYWORD, /* config keyword */ NULL, /* Undefined 2 */ NULL, /* Undefined 1 */ NULL, /* Undefined 0 */ LOCATION, NULL, /* Handle if a plugin, filled in by GKrellM */ NULL /* path if a plugin, filled in by GKrellM */ }; #if defined(WIN32) __declspec(dllexport) GkrellmMonitor * gkrellm_init_plugin(win32_plugin_callbacks* calls) #else GkrellmMonitor * gkrellm_init_plugin(void) #endif { #if defined(WIN32) callbacks = calls; #endif #ifdef ENABLE_NLS bind_textdomain_codeset(PACKAGE, "UTF-8"); #endif /* ENABLE_NLS */ style_id = gkrellm_add_meter_style(&plugin_mon,"volume"); init_mixer(); Mixerz = NULL; monitor = &plugin_mon; return monitor; } gkrellm-volume-2.1.13/mixer.c0000644000175000017500000000761710111204177016633 0ustar sjoerdsjoerd00000000000000/* GKrellM Volume plugin | Copyright (C) 1999-2000 Sjoerd Simons | | Author: Sjoerd Simons sjoerd@luon.net | | This program is free software which I release under the GNU General Public | License. You may redistribute and/or modify this program under the terms | of that license as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | To get a copy of the GNU General Puplic License, write to the | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "mixer.h" #ifdef WIN32 #include "win32_mixer.h" #else #ifdef ALSA #include "alsa_mixer.h" #endif #include "oss_mixer.h" #endif #ifdef WIN32 mixer_ops_t *win32_mixer; #else mixer_ops_t *oss_mixer; #endif #ifdef ALSA mixer_ops_t *alsa_mixer; #endif void init_mixer(void) { #ifdef WIN32 win32_mixer = init_win32_mixer(); #else oss_mixer = init_oss_mixer(); #endif #ifdef ALSA alsa_mixer = init_alsa_mixer(); #endif } /* tries to open a mixer device, returns NULL on error or otherwise an mixer_t * struct */ mixer_t *mixer_open(char *id) { mixer_t *result = NULL; #ifdef WIN32 result = win32_mixer->mixer_open(id); #else #ifdef ALSA result = alsa_mixer->mixer_open(id); #endif /* either no alsa mixer or alsa mixer failed */ if (result == NULL) { result = oss_mixer->mixer_open(id); } #endif return result; } void mixer_close(mixer_t *mixer) { mixer->ops->mixer_close(mixer); } /* Returns a pointer to the name of the mixer */ /* Shouldn't be freed */ char * mixer_get_name(mixer_t *mixer) { return mixer->name; } /* Returns the number of devices a mixer has */ int mixer_get_nr_devices(mixer_t *mixer) { return mixer->nrdevices; } /* devid is the number of a device in a mixer */ /* 0 <= devid < mixer_get_nr_devices(mixer) */ /* get the real name of a device */ char * mixer_get_device_real_name(mixer_t *mixer,int devid) { return mixer->dev_realnames[devid]; } /* get and set the user specified name of a device */ char * mixer_get_device_name(mixer_t *mixer, int devid) { return mixer->dev_names[devid] != NULL ? mixer->dev_names[devid] : mixer->dev_realnames[devid]; } void mixer_set_device_name(mixer_t *mixer, int devid, char *name) { g_free(mixer->dev_names[devid]); mixer->dev_names[devid] = g_strdup(name); } /* get the full scale of a device and get/set the volume */ long mixer_get_device_fullscale(mixer_t *mixer, int devid) { return mixer->ops->mixer_device_get_fullscale(mixer, devid); } void mixer_get_device_volume(mixer_t *mixer, int devid, int *left, int *right) { mixer->ops->mixer_device_get_volume(mixer, devid, left, right); } void mixer_set_device_volume(mixer_t *mixer, int devid,int left,int right) { mixer->ops->mixer_device_set_volume(mixer, devid, left, right); } /* get an linked list of usable mixer devices */ mixer_idz_t * mixer_get_id_list(void) { mixer_idz_t *result = NULL; #ifdef WIN32 result = win32_mixer->mixer_get_id_list(); #else #ifdef ALSA result = alsa_mixer->mixer_get_id_list(); #endif if (result == NULL) { result = oss_mixer->mixer_get_id_list(); } #endif return result; } /* adds an id to the mixer list */ mixer_idz_t * mixer_id_list_add(char *id, mixer_idz_t *list) { mixer_idz_t *new = g_new(mixer_idz_t,1); mixer_idz_t *n; new->id = g_strdup(id); new->next = NULL; if (list == NULL) return new; for (n = list; n->next != NULL; n = n->next); n->next = new; return list; } void mixer_free_idz(mixer_idz_t *idz) { mixer_idz_t *tmp; mixer_idz_t *next = idz; while (next != NULL) { tmp = next; next = next->next; g_free(tmp->id); g_free(tmp); } } gkrellm-volume-2.1.13/alsa_mixer.c0000644000175000017500000002403410111204177017623 0ustar sjoerdsjoerd00000000000000#include #include #include #include #include #include "mixer.h" #include "alsa_mixer.h" #define ALSAMIXER(x) ((alsa_mixer_t *)x->priv) static mixer_ops_t *get_mixer_ops(void); enum { CTL_PLAYBACK = 0, CTL_CAPTURE, CTL_PLAYBACK_SWITCH }; static void error(const char *fmt, ...) { va_list va; va_start(va, fmt); fprintf(stderr, "gkrellm-volume amixer: "); vfprintf(stderr, fmt, va); fprintf(stderr, "\n"); va_end(va); } static int mixer_event(snd_mixer_t * m, unsigned int mask, snd_mixer_elem_t * elem) { mixer_t *mixer = (mixer_t *) snd_mixer_get_callback_private(m); ALSAMIXER(mixer)->changed_state = 1; return 0; } static mixer_t * alsa_mixer_open(char *card) { mixer_t *result; alsa_mixer_t *alsaresult; int err; snd_mixer_t *handle; snd_mixer_selem_id_t *sid; snd_mixer_elem_t *elem; snd_ctl_card_info_t *hw_info; snd_ctl_t *ctl_handle; int count, i; snd_mixer_selem_id_alloca(&sid); snd_ctl_card_info_alloca(&hw_info); if ((err = snd_ctl_open(&ctl_handle, card, 0)) < 0) { error("Control info %s error: %s", card, snd_strerror(err)); // snd_ctl_close(ctl_handle); return NULL; } if ((err = snd_ctl_card_info(ctl_handle, hw_info)) < 0) { error("Control info %s error: %s", card, snd_strerror(err)); snd_ctl_close(ctl_handle); return NULL; } snd_ctl_close(ctl_handle); if ((err = snd_mixer_open(&handle, 0)) < 0) { error("Mixer %s open error: %s", card, snd_strerror(err)); return NULL; } if ((err = snd_mixer_attach(handle, card)) < 0) { error("Mixer attach %s error: %s", card, snd_strerror(err)); snd_mixer_close(handle); return NULL; } if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { error("Mixer register error: %s", snd_strerror(err)); snd_mixer_close(handle); return NULL; } err = snd_mixer_load(handle); if (err < 0) { error("Mixer %s load error: %s", card, snd_strerror(err)); snd_mixer_close(handle); return NULL; } count = 0; for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; if (snd_mixer_selem_has_playback_volume(elem)) { count++; } if (snd_mixer_selem_has_playback_switch(elem)) { count++; } if (snd_mixer_selem_has_capture_volume(elem)) { count++; } } result = (mixer_t *) malloc(sizeof(mixer_t)); alsaresult = (alsa_mixer_t *)malloc(sizeof(mixer_t)); result->priv = (void *)alsaresult; result->ops = get_mixer_ops(); result->name = g_strdup_printf("%s", snd_ctl_card_info_get_name(hw_info)); result->nrdevices = count; result->dev_names = (char **) malloc(sizeof(char *) * count); result->dev_realnames = (char **) malloc(sizeof(char *) * count); alsaresult->handle = handle; alsaresult->sids = (snd_mixer_selem_id_t **) malloc(sizeof(snd_mixer_selem_id_t *) * count); alsaresult->ctltype = (int *) malloc(sizeof(int) * count); for (elem = snd_mixer_first_elem(handle), i = 0; elem; elem = snd_mixer_elem_next(elem)) { snd_mixer_selem_get_id(elem, sid); if (!snd_mixer_selem_is_active(elem)) continue; if (snd_mixer_selem_has_playback_volume(elem)) { result->dev_realnames[i] = strdup(snd_mixer_selem_id_get_name(sid)); result->dev_names[i] = g_strdup_printf("%s %s", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_has_capture_volume(elem) ? "playback" : ""); alsaresult->ctltype[i] = CTL_PLAYBACK; snd_mixer_selem_id_malloc(&alsaresult->sids[i]); snd_mixer_selem_get_id(elem, alsaresult->sids[i]); i++; } if (snd_mixer_selem_has_capture_volume(elem)) { result->dev_realnames[i] = strdup(snd_mixer_selem_id_get_name(sid)); result->dev_names[i] = g_strdup_printf("%s %s", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_has_playback_volume(elem) ? "capture" : ""); alsaresult->ctltype[i] = CTL_CAPTURE; snd_mixer_selem_id_malloc(&alsaresult->sids[i]); snd_mixer_selem_get_id(elem, alsaresult->sids[i]); i++; } if (snd_mixer_selem_has_playback_switch(elem)) { result->dev_realnames[i] = strdup(snd_mixer_selem_id_get_name(sid)); result->dev_names[i] = g_strdup_printf("%s", snd_mixer_selem_id_get_name(sid)); alsaresult->ctltype[i] = CTL_PLAYBACK_SWITCH; snd_mixer_selem_id_malloc(&alsaresult->sids[i]); snd_mixer_selem_get_id(elem, alsaresult->sids[i]); i++; } } snd_mixer_set_callback(handle, mixer_event); snd_mixer_set_callback_private(handle, result); return result; } static void alsa_mixer_close(mixer_t * mixer) { int i; snd_mixer_close(ALSAMIXER(mixer)->handle); for (i = 0; i < mixer->nrdevices; i++) { free(mixer->dev_names[i]); free(mixer->dev_realnames[i]); snd_mixer_selem_id_free(ALSAMIXER(mixer)->sids[i]); } free(mixer->dev_names); free(mixer->dev_realnames); free(ALSAMIXER(mixer)->ctltype); free(ALSAMIXER(mixer)->sids); free(mixer->priv); free(mixer); } /* get the full scale of a device and get/set the volume */ static long alsa_mixer_device_get_fullscale(mixer_t * mixer, int devid) { if (ALSAMIXER(mixer)->ctltype[devid] == CTL_PLAYBACK_SWITCH) { return 1; } return 100; } /* Fuction to convert from volume to percentage. val = volume */ static int convert_prange(int val, int min, int max) { int range = max - min; int tmp; if (range == 0) return 0; val -= min; tmp = rint((double) val / (double) range * 100); return tmp; } /* Function to convert from percentage to volume. val = percentage */ static int convert_prange1(int val, int min, int max) { int range = max - min; int tmp; if (range == 0) return 0; tmp = rint((double) range * ((double) val * .01)) + min; return tmp; } void alsa_mixer_device_get_volume(mixer_t * mixer, int devid, int *left, int *right) { long min, max, lvol, rvol; int sw; int err; alsa_mixer_t *alsamixer = ALSAMIXER(mixer); snd_mixer_elem_t *elem; snd_mixer_handle_events(alsamixer->handle); if (alsamixer->changed_state) { snd_mixer_free(alsamixer->handle); err = snd_mixer_load(alsamixer->handle); if (err < 0) { error("Mixer load error: %s", snd_strerror(err)); snd_mixer_close(alsamixer->handle); return; } alsamixer->changed_state = 0; } elem = snd_mixer_find_selem(alsamixer->handle, alsamixer->sids[devid]); switch (alsamixer->ctltype[devid]) { case CTL_PLAYBACK: snd_mixer_selem_get_playback_volume_range(elem, &min, &max); snd_mixer_selem_get_playback_volume(elem, 0, &lvol); if (snd_mixer_selem_is_playback_mono(elem)) { rvol = lvol; } else { snd_mixer_selem_get_playback_volume(elem, 1, &rvol); } break; case CTL_CAPTURE: snd_mixer_selem_get_capture_volume_range(elem, &min, &max); snd_mixer_selem_get_capture_volume(elem, 0, &lvol); if (snd_mixer_selem_is_capture_mono(elem)) { rvol = lvol; } else { snd_mixer_selem_get_capture_volume(elem, 1, &rvol); } break; case CTL_PLAYBACK_SWITCH: snd_mixer_selem_get_playback_switch(elem, 0, &sw); *left = sw; *right = sw; return; break; default: g_assert_not_reached(); break; } *left = convert_prange(lvol, min, max); *right = convert_prange(rvol, min, max); } static void alsa_mixer_device_set_volume(mixer_t * mixer, int devid, int left, int right) { long min, max, lvol, rvol; alsa_mixer_t *alsamixer = ALSAMIXER(mixer); snd_mixer_elem_t *elem; elem = snd_mixer_find_selem(alsamixer->handle, alsamixer->sids[devid]); switch (alsamixer->ctltype[devid]) { case CTL_PLAYBACK: snd_mixer_selem_get_playback_volume_range(elem, &min, &max); lvol = convert_prange1(left, min, max); rvol = convert_prange1(right, min, max); snd_mixer_selem_set_playback_volume(elem, 0, lvol); if (left == 0) snd_mixer_selem_set_playback_switch(elem, 0, 0); else snd_mixer_selem_set_playback_switch(elem, 0, 1); snd_mixer_selem_set_playback_volume(elem, 1, rvol); if (right == 0) snd_mixer_selem_set_playback_switch(elem, 1, 0); else snd_mixer_selem_set_playback_switch(elem, 1, 1); break; case CTL_CAPTURE: snd_mixer_selem_get_capture_volume_range(elem, &min, &max); lvol = convert_prange1(left, min, max); rvol = convert_prange1(right, min, max); snd_mixer_selem_set_capture_volume(elem, 0, lvol); if (left == 0) snd_mixer_selem_set_capture_switch(elem, 0, 0); else snd_mixer_selem_set_capture_switch(elem, 0, 1); snd_mixer_selem_set_capture_volume(elem, 1, rvol); if (right == 0) snd_mixer_selem_set_capture_switch(elem, 1, 0); else snd_mixer_selem_set_capture_switch(elem, 1, 1); break; case CTL_PLAYBACK_SWITCH: snd_mixer_selem_set_playback_switch(elem, 0, left); break; default: g_assert_not_reached(); break; } } mixer_idz_t * alsa_mixer_get_id_list(void) { mixer_idz_t *result = NULL; snd_mixer_t *handle; int err; char name[64]; int i; if ((err = snd_mixer_open(&handle, 0)) < 0) { return NULL; } for (i = 0; i < 64; i++) { sprintf(name, "hw:%d", i); if ((err = snd_mixer_attach(handle, name)) < 0) { break; snd_mixer_close(handle); } if ((err = snd_mixer_detach(handle, name)) < 0) { snd_mixer_close(handle); break; } result = mixer_id_list_add(name, result); } return result; } static mixer_ops_t alsa_mixer_ops = { .mixer_get_id_list = alsa_mixer_get_id_list, .mixer_open = alsa_mixer_open, .mixer_close = alsa_mixer_close, .mixer_device_get_fullscale = alsa_mixer_device_get_fullscale, .mixer_device_get_volume = alsa_mixer_device_get_volume, .mixer_device_set_volume = alsa_mixer_device_set_volume }; static mixer_ops_t * get_mixer_ops(void) { return &alsa_mixer_ops; } mixer_ops_t * init_alsa_mixer(void) { return get_mixer_ops(); } gkrellm-volume-2.1.13/mixer.h0000644000175000017500000000563610111204177016637 0ustar sjoerdsjoerd00000000000000#ifndef VOLUME_MIXER_H #define VOLUME_MIXER_H /* GKrellM Volume plugin | Copyright (C) 1999-2000 Sjoerd Simons | | Author: Sjoerd Simons sjoerd@luon.net | | This program is free software which I release under the GNU General Public | License. You may redistribute and/or modify this program under the terms | of that license as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | To get a copy of the GNU General Puplic License, write to the | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include typedef struct _mixer_idz_t mixer_idz_t; struct _mixer_idz_t { char *id; mixer_idz_t *next; }; typedef struct _mixer_t mixer_t; typedef struct { mixer_idz_t *(*mixer_get_id_list)(void); mixer_t *(*mixer_open)(char *id); void (*mixer_close)(mixer_t *mixer); long (*mixer_device_get_fullscale)(mixer_t *mixer, int devid); void (*mixer_device_get_volume)(mixer_t *mixer, int devid, int *left, int *right); void (*mixer_device_set_volume)(mixer_t *mixer, int devid, int left, int right); } mixer_ops_t; struct _mixer_t { /* mixer name */ gchar *name; /* nr of device in this mixer */ int nrdevices; /* table with devid to names of the device mapping */ gchar **dev_names; gchar **dev_realnames; mixer_ops_t *ops; void *priv; }; void init_mixer(void); /* tries to open a mixer device, returns NULL on error or otherwise an mixer_t * struct */ mixer_t *mixer_open(char *id); void mixer_close(mixer_t *mixer); /* Returns a pointer to the name of the mixer */ /* Shouldn't be freed */ char *mixer_get_name(mixer_t *mixer); /* Returns the number of devices a mixer has */ int mixer_get_nr_devices(mixer_t *mixer); /* devid is the number of a device in a mixer */ /* 0 <= devid < mixer_get_nr_devices(mixer) */ /* get the real name of a device */ char *mixer_get_device_real_name(mixer_t *mixer,int devid); /* get and set the user specified name of a device */ char *mixer_get_device_name(mixer_t *mixer,int devid); void mixer_set_device_name(mixer_t *mixer,int devid,char *name); /* get the full scale of a device and get/set the volume */ long mixer_get_device_fullscale(mixer_t *mixer,int devid); void mixer_get_device_volume(mixer_t *mixer, int devid,int *left,int *right); void mixer_set_device_volume(mixer_t *mixer, int devid,int left,int right); /* get an linked list of usable mixer devices */ mixer_idz_t *mixer_get_id_list(); mixer_idz_t *mixer_id_list_add(char *id,mixer_idz_t *list); void mixer_free_idz(mixer_idz_t *idz); #endif /* VOLUME_MIXER_H */ gkrellm-volume-2.1.13/oss_mixer.c0000644000175000017500000001102710111204177017505 0ustar sjoerdsjoerd00000000000000/* GKrellM Volume plugin | Copyright (C) 1999-2000 Sjoerd Simons | | Author: Sjoerd Simons sjoerd@luon.net | | This program is free software which I release under the GNU General Public | License. You may redistribute and/or modify this program under the terms | of that license as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | To get a copy of the GNU General Puplic License, write to the | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #if defined(__FreeBSD__) && __FreeBSD_version < 500000 #include #else #include #endif #include "mixer.h" #include "oss_mixer.h" #define OSSMIXER(x) ((oss_mixer_t *)x->priv) static mixer_ops_t * get_mixer_ops(void); /* tries to open a mixer device, returns NULL on error or otherwise an mixer_t * struct */ static mixer_t * oss_mixer_open(char *id) { mixer_t *result; oss_mixer_t *ossresult; int fd,devices,nr,i; #ifdef SOUND_MIXER_INFO mixer_info minfo; #endif char *sound_labels[] = SOUND_DEVICE_LABELS; if ((fd = open(id,O_RDWR)) == -1) return NULL; if ( (ioctl(fd,SOUND_MIXER_READ_DEVMASK,&devices) < 0)) { close(fd); return NULL; } #ifdef SOUND_MIXER_INFO if ((ioctl(fd,SOUND_MIXER_INFO,&minfo) < 0)) { close(fd); return NULL; } #endif result = malloc(sizeof(mixer_t)); #ifdef SOUND_MIXER_INFO result->name = strdup(minfo.name); #else result->name = strdup(id); #endif /* get the nr of devices */ nr = 0; for (i = 0 ; i < SOUND_MIXER_NRDEVICES; i++) { if (devices & (1<nrdevices = nr; result->dev_realnames = malloc(nr * sizeof(char *)); result->dev_names = malloc(nr * sizeof(char*)); memset(result->dev_names,0,nr * sizeof(char *)); ossresult = malloc(sizeof(oss_mixer_t)); ossresult->fd = fd; ossresult->table = malloc(nr * sizeof(int)); result->priv = ossresult; result->ops = get_mixer_ops(); nr = 0; for (i = 0 ; i < SOUND_MIXER_NRDEVICES; i++) if (devices & (1<table[nr] = i; result->dev_realnames[nr] = strdup(sound_labels[i]); nr++; } return result; } static void oss_mixer_close(mixer_t *mixer) { int i; close(OSSMIXER(mixer)->fd); for (i=0;i < mixer->nrdevices ; i++) { free(mixer->dev_names[i]); free(mixer->dev_realnames[i]); } free(mixer->dev_names); free(mixer->dev_realnames); free(OSSMIXER(mixer)->table); free(mixer->priv); free(mixer); } /* get the full scale of a device and get/set the volume */ static long oss_mixer_device_get_fullscale(mixer_t *mixer,int devid) { return 100; } static void oss_mixer_device_get_volume(mixer_t *mixer, int devid,int *left,int *right) { long amount; ioctl(OSSMIXER(mixer)->fd,MIXER_READ(OSSMIXER(mixer)->table[devid]),&amount); *left = amount & 0xff; *right = amount >> 8; } static void oss_mixer_device_set_volume(mixer_t *mixer, int devid,int left,int right) { long amount = (right << 8) + (left & 0xff); ioctl(OSSMIXER(mixer)->fd,MIXER_WRITE(OSSMIXER(mixer)->table[devid]),&amount); } static mixer_idz_t * oss_mixer_get_id_list(void) { mixer_idz_t *result = NULL; char *device[] = { "/dev/mixer*","/dev/sound/mixer*"}; glob_t pglob; int i,n; for (n = 0; n < (sizeof(device)/sizeof(char *)); n++) { if (glob(device[n],0,NULL,&pglob) == 0) { for (i = 0; i < pglob.gl_pathc; i++) { char *rc,buffer[PATH_MAX]; rc = realpath(pglob.gl_pathv[i],buffer); if (rc == NULL) continue; result = mixer_id_list_add(rc,result); } globfree(&pglob); } } return result; } static mixer_ops_t oss_mixer_ops = { .mixer_get_id_list = oss_mixer_get_id_list, .mixer_open = oss_mixer_open, .mixer_close = oss_mixer_close, .mixer_device_get_fullscale = oss_mixer_device_get_fullscale, .mixer_device_get_volume = oss_mixer_device_get_volume, .mixer_device_set_volume = oss_mixer_device_set_volume }; static mixer_ops_t * get_mixer_ops(void) { return &oss_mixer_ops; } mixer_ops_t * init_oss_mixer(void) { return get_mixer_ops(); } gkrellm-volume-2.1.13/oss_mixer.h0000644000175000017500000000173510111204177017517 0ustar sjoerdsjoerd00000000000000/* GKrellM Volume plugin | Copyright (C) 1999-2000 Sjoerd Simons | | Author: Sjoerd Simons sjoerd@luon.net | | This program is free software which I release under the GNU General Public | License. You may redistribute and/or modify this program under the terms | of that license as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | To get a copy of the GNU General Puplic License, write to the | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "mixer.h" typedef struct { /* mixer file descriptor */ int fd; /* devid to oss number */ int *table; } oss_mixer_t; mixer_ops_t *init_oss_mixer(void); gkrellm-volume-2.1.13/volume.h0000644000175000017500000000365410111204177017020 0ustar sjoerdsjoerd00000000000000/* GKrellM Volume plugin | Copyright (C) 1999-2000 Sjoerd Simons | | Author: Sjoerd Simons sjoerd@luon.net | | This program is free software which I release under the GNU General Public | License. You may redistribute and/or modify this program under the terms | of that license as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | To get a copy of the GNU General Puplic License, write to the | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "mixer.h" #define VOLUME_MAJOR_VERSION 2 #define VOLUME_MINOR_VERSION 1 #define VOLUME_EXTRA_VERSION 12 #define CONFIG_KEYWORD "volume_plugin_config" #define LOCATION MON_APM /* The location of the plugin, choose between : |* MON_CLOCK, MON_CPU, MON_PROC, MON_DISK, |* MON_INET, MON_NET, MON_FS, MON_MAIL, |* MON_APM, or MON_UPTIME */ /* per slider flags */ enum { IS_PRESSED =0, SAVE_VOLUME, BALANCE, MUTED }; /* global flags */ enum { MUTEALL =0 }; /* flags macro's */ #define SET_FLAG(s,x) (s |= (1 << x)) #define DEL_FLAG(s,x) (s = s & ~(1< # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=volume - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "volume.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "volume.mak" CFG="volume - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "volume - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "volume - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "volume - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VOLUME_EXPORTS" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VOLUME_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib glib-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib gobject-2.0.lib gdk_pixbuf-2.0.lib gthread-2.0.lib gmodule-2.0.lib winmm.lib /nologo /dll /machine:I386 !ELSEIF "$(CFG)" == "volume - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VOLUME_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VOLUME_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib glib-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib gobject-2.0.lib gdk_pixbuf-2.0.lib gthread-2.0.lib gmodule-2.0.lib winmm.lib /nologo /dll /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "volume - Win32 Release" # Name "volume - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\volume.c # End Source File # Begin Source File SOURCE="..\..\gkrellm\src\sysdeps\win32-plugin.c" # End Source File # Begin Source File SOURCE=.\win32_mixer.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\mixer.h # End Source File # Begin Source File SOURCE=.\volume.h # End Source File # Begin Source File SOURCE="..\..\gkrellm\src\win32-plugin.h" # End Source File # Begin Source File SOURCE=.\win32_mixer.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project gkrellm-volume-2.1.13/volume.dsw0000644000175000017500000000103110111204177017351 0ustar sjoerdsjoerd00000000000000Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "volume"=".\volume.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### gkrellm-volume-2.1.13/win32_mixer.c0000644000175000017500000002463010111204177017647 0ustar sjoerdsjoerd00000000000000/* win32 port by Bill Nalen bill@nalens.com */ // based on // VolumeControl.cpp: implementation of the CVolumeControl class. // // Author: Bill Oatman // Version: 1.0 // http://www.netacc.net/~waterbry/BillsApps.htm // ////////////////////////////////////////////////////////////////////// /* GKrellM Volume plugin | Copyright (C) 1999-2000 Sjoerd Simons | | Author: Sjoerd Simons sjoerd@luon.net | | This program is free software which I release under the GNU General Public | License. You may redistribute and/or modify this program under the terms | of that license as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | To get a copy of the GNU General Puplic License, write to the | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "mixer.h" #include "win32_mixer.h" #define WIN32MIXER(x) ((win32_mixer_t *)x->priv) static mixer_ops_t * get_mixer_ops(void); void fixName(char* name) { unsigned int i; for (i = 0; i < strlen(name); i++) { if (name[i] == ' ') name[i] = '_'; } } /* tries to open a mixer device, returns NULL on error or otherwise an mixer_t * struct */ static mixer_t * win32_mixer_open(char *id) { mixer_t *result = NULL; win32_mixer_t *win32result = NULL; int nr; MIXERCAPS mxCaps; int numMixers; MIXERLINE mxl; MIXERCONTROL mxc; MIXERLINECONTROLS mxlc; HMIXER hMixer; int j, numConn; fixName(id); numMixers = mixerGetNumDevs(); if (numMixers != 0) { hMixer = NULL; ZeroMemory(&mxCaps, sizeof(MIXERCAPS)); if (mixerOpen(&hMixer, 0, 0, 0, MIXER_OBJECTF_MIXER) != MMSYSERR_NOERROR) { return NULL; } if (mixerGetDevCaps((UINT)hMixer, &mxCaps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR) { return NULL; } // get dwLineID mxl.cbStruct = sizeof(MIXERLINE); mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; if (strcmp(id, "Master") != 0) { mxl.dwDestination = 0; mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_DESTINATION); numConn = mxl.cConnections; for (j = 0; j < numConn; j++) { // ...get info upon that source line mxl.cbStruct = sizeof(MIXERLINE); mxl.dwDestination = 0; mxl.dwSource = j; mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE); fixName(mxl.szShortName); if (strcmp(mxl.szShortName, id) == 0) { result = malloc(sizeof(mixer_t)); win32result = malloc(sizeof(win32_mixer_t)); result->name = g_strdup("Master"); result->hMixer = hMixer; result->priv = win32result; break; } } } else { if(mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR) return NULL; result = malloc(sizeof(mixer_t)); win32result = malloc(sizeof(win32_mixer_t)); result->name = g_strdup("Master"); result->hMixer = hMixer; result->priv = win32result; } if (result == NULL) return NULL; nr = -1; // now retrieve the devices result->ops = get_mixer_ops(); result->dev_realnames = malloc(sizeof(char *) * 3); result->dev_names = malloc(sizeof(char *) * 3); // Volume control mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mxc; if(mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR) { // save record dwControlID ++nr; win32result->minimum[nr] = mxc.Bounds.dwMinimum; win32result->maximum[nr] = mxc.Bounds.dwMaximum; win32result->controlID[nr] = mxc.dwControlID; result->dev_realnames[nr] = g_strdup("Vol"); result->dev_names[nr] = g_strdup("Vol"); } // Bass control mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_BASS; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mxc; if(mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR) { ++nr; win32result->minimum[nr] = mxc.Bounds.dwMinimum; win32result->maximum[nr] = mxc.Bounds.dwMaximum; win32result->controlID[nr] = mxc.dwControlID; result->dev_rnames[nr] = g_strdup("Bass"); result->dev_names[nr] = g_strdup("Bass"); } // treble control mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_TREBLE; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mxc; if(mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR) { ++nr; win32result->minimum[nr] = mxc.Bounds.dwMinimum; win32result->maximum[nr] = mxc.Bounds.dwMaximum; win32result->controlID[nr] = mxc.dwControlID; result->dev_rnames[nr] = g_strdup("Treb"); result->dev_names[nr] = g_strdup("Treb"); } } else return NULL; result->nrdevices = nr + 1; return result; } static void win32_mixer_close(mixer_t *mixer) { int i; if (WIN32MIXER(mixer)->hMixer != NULL) { mixerClose(WIN32MIXER(mixer)->hMixer); } for (i=0;i < mixer->nrdevices; i++) { WIN32MIXER(mixer)->controlID[i] = 0; g_free(mixer->dev_names[i]); g_free(mixer->dev_realnames[i]); } g_free(mixer->name); g_free(mixer->dev_names); g_free(mixer->dev_realnames); g_free(mixer->priv); g_free(mixer); return; } /* get the full scale of a device and get/set the volume */ long win32_mixer_device_get_fullscale(mixer_t *mixer,int devid) { return WIN32MIXER(mixer)->maximum[devid] - WIN32MIXER(mixer)->minimum[devid]; } void win32_mixer_device_get_volume(mixer_t *mixer, int devid,int *left,int *right) { MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; MIXERCONTROLDETAILS mxcd; if (WIN32MIXER(mixer)->hMixer == NULL) { *left = 0; *right = 0; return; } mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = mixer->controlID[devid]; mxcd.cChannels = 1; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mxcd.paDetails = &mxcdVolume; if (mixerGetControlDetails((HMIXEROBJ) WIN32MIXER(mixer)->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) { *left = 0; *right = 0; return; } *left = mxcdVolume.dwValue - WIN32MIXER(mixer)->minimum[devid]; *right = mxcdVolume.dwValue - WIN32MIXER(mixer)->minimum[devid]; //return mxcdVolume.dwValue - mixer->minimum[devid]; } static void win32_mixer_device_set_volume(mixer_t *mixer, int devid,int left,int right) { MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; MIXERCONTROLDETAILS mxcd; if (WIN32MIXER(mixer)->hMixer == NULL) return; if (left >= right) mxcdVolume.dwValue = left + WIN32MIXER(mixer)->minimum[devid]; else mxcdVolume.dwValue = right + WIN32MIXER(mixer)->minimum[devid]; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = WIN32MIXER(mixer)->controlID[devid]; mxcd.cChannels = 1; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mxcd.paDetails = &mxcdVolume; if (mixerSetControlDetails((HMIXEROBJ)WIN32MIXER(mixer)->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) return; } mixer_idz_t * win32_mixer_get_id_list(void) { MIXERLINE mxl; HMIXER hMixer; MIXERCAPS mxCaps; int numMixers; mixer_idz_t *result = NULL; int j, numConn; result = mixer_id_list_add("Master", result); numMixers = mixerGetNumDevs(); if (numMixers != 0) { hMixer = NULL; ZeroMemory(&mxCaps, sizeof(MIXERCAPS)); if (mixerOpen(&hMixer, 0, 0, 0, MIXER_OBJECTF_MIXER) != MMSYSERR_NOERROR) { return NULL; } if (mixerGetDevCaps((UINT)hMixer, &mxCaps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR) { return NULL; } // get dwLineID mxl.cbStruct = sizeof(MIXERLINE); mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; mxl.dwDestination = 0; mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_DESTINATION); numConn = mxl.cConnections; for (j = 0; j < numConn; j++) { // ...get info upon that source line mxl.cbStruct = sizeof(MIXERLINE); mxl.dwDestination = 0; mxl.dwSource = j; mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE); fixName(mxl.szShortName); result = mixer_id_list_add(mxl.szShortName, result); } } return result; } double rint(double arg) { int iarg = (int) arg; if (arg - iarg < 0.5) return floor(arg); else return ceil(arg); } static mixer_ops_t win32_mixer_ops = { .mixer_get_id_list = win32_mixer_get_id_list, .mixer_open = win32_mixer_open, .mixer_close = win32_mixer_close, .mixer_device_get_fullscale = win32_mixer_device_get_fullscale, .mixer_device_get_volume = win32_mixer_device_get_volume, .mixer_device_set_volume = win32_mixer_device_set_volume }; static mixer_ops_t * get_mixer_ops(void) { return &win32_mixer_ops; } mixer_ops_t * init_win32_mixer(void) { return get_mixer_ops(); } gkrellm-volume-2.1.13/.#volume.c.1.100000644000175000017500000010111710111204177017503 0ustar sjoerdsjoerd00000000000000#include #include #if !defined(WIN32) #include #endif #include "volume.h" #include "mixer.h" #define VOLUME_STYLE style_id static gint style_id; static GkrellmMonitor *monitor; static GtkWidget *pluginbox; static Mixer *Mixerz; static int global_flags = 0; static int config_global_flags = 0; /* functions for the bookkeeping of open mixers and sliders */ /* retuns the added mixer or and existing one with the same id */ static Mixer *add_mixer_by_id(char *id) { Mixer *result,**m; mixer_t *mixer; if (Mixerz == NULL) m = &Mixerz; else { result = Mixerz; do { if (!strcmp(id,result->id)) return result; } while (result->next != NULL && (result = result->next)); m = &(result->next); } if ((mixer = mixer_open(id)) == NULL) return NULL; result = malloc(sizeof(Mixer)); result->id = strdup(id); result->mixer = mixer; result->next = NULL; result->Sliderz = NULL; /* add The Mixer to the end */ *m = result; return result; } static void remove_mixer(Mixer *m) { Slider *s,*s1; Mixer *tmp; for (s = m->Sliderz ; s != NULL ;s = s1) { gkrellm_panel_destroy(s->panel); if (s->bal) gkrellm_panel_destroy(s->bal->panel); s1 = s->next; free(s->bal); free(s); } mixer_close(m->mixer); free(m->id); if (Mixerz == m) Mixerz = m->next; else { for (tmp = Mixerz; tmp->next != m; tmp = tmp->next); /* tmp->next == m */ tmp->next = m->next; } } static void remove_all_mixers() { while(Mixerz != NULL) remove_mixer(Mixerz); } static Slider *add_slider(Mixer *m, int dev) { Slider *result,*s; if (dev < 0 || dev >= mixer_get_nr_devices(m->mixer)) return NULL; result = malloc(sizeof(Slider)); result->mixer = m->mixer; result->parent = m; result->dev = dev; result->flags = 0; result->next = NULL; result->krell = NULL; result->panel = NULL; result->balance = 0; result->pleft = result->pright = -1; result->bal = NULL; if (m->Sliderz == NULL) m->Sliderz = result; else { for (s = m->Sliderz ; s->next != NULL; s = s->next); s->next = result; } return result; } /*---*/ static gint bvolume_expose_event(GtkWidget *widget, GdkEventExpose *event,gpointer slide) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], ((Bslider *)slide)->panel->pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return TRUE; } static gint volume_expose_event(GtkWidget *widget, GdkEventExpose *event,gpointer slide) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], ((Slider *)slide)->panel->pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return TRUE; } static gint volume_get_volume(Slider *s) { gint left,right; mixer_get_device_volume(s->mixer,s->dev,&left,&right); return left > right ? left : right; } static void volume_show_volume(Slider *s) { gkrellm_update_krell(s->panel,s->krell,volume_get_volume(s)); gkrellm_draw_panel_layers(s->panel); gkrellm_config_modified(); } static void volume_set_volume(Slider *s,gint volume) { gint left,right; if (GET_FLAG(s->flags,MUTED)) return; volume = volume < 0 ? 0 : volume; if (volume < 0) volume = 0; else if (volume > mixer_get_device_fullscale(s->mixer,s->dev)) volume = mixer_get_device_fullscale(s->mixer,s->dev); if (s->balance == 0 && !GET_FLAG(s->flags,BALANCE)) left = right = volume; else if (s->balance > 0) { right = volume; left = ((100 - s->balance)* volume) / 100; } else { /* balance < 0 */ left = volume; right = ((100 + s->balance)* volume) / 100; } mixer_set_device_volume(s->mixer,s->dev,left,right); s->pleft = left; s->pright = right; volume_show_volume(s); } static void volume_show_balance(Slider *s) { gchar *buf; if (s->bal == NULL) return; if (s->balance == 0) buf = g_strdup("Centered"); else buf = g_strdup_printf("%3d%% %s",abs(s->balance), s->balance > 0 ? "Right" : "Left"); gkrellm_draw_decal_text(s->bal->panel,s->bal->decal,buf,-1); gkrellm_update_krell(s->bal->panel,s->bal->krell,s->balance + 100 ); gkrellm_draw_panel_layers(s->bal->panel); g_free(buf); } static void volume_set_balance(Slider *s,gint amount) { if (amount < -100) amount = -100; else if (amount > 100) amount = 100; if (abs(amount) <= 3) amount = 0; s->balance = amount; volume_set_volume(s,volume_get_volume(s)); volume_show_balance(s); } static void volume_mute_mixer(Mixer *m) { Slider *s; for (s = m->Sliderz ; s != NULL ; s = s->next) { mixer_set_device_volume(s->mixer,s->dev,0,0); volume_show_volume(s); SET_FLAG(s->flags,MUTED); } } static void volume_unmute_mixer(Mixer *m) { Slider *s; for (s = m->Sliderz ; s != NULL ; s = s->next) { DEL_FLAG(s->flags,MUTED); mixer_set_device_volume(s->mixer,s->dev,s->pleft,s->pright); volume_show_volume(s); } } static void volume_toggle_mute(Slider *s) { Mixer *m; if (GET_FLAG(s->flags,MUTED)) { if (GET_FLAG(global_flags,MUTEALL)) { for (m = Mixerz ; m != NULL; m = m->next) volume_unmute_mixer(m); } else volume_unmute_mixer(s->parent); } else { if (GET_FLAG(global_flags,MUTEALL)) { for (m = Mixerz ; m != NULL; m = m->next) volume_mute_mixer(m); } else volume_mute_mixer(s->parent); } } static gint bvolume_cb_scroll(GtkWidget *widget, GdkEventScroll *event,Bslider *s) { int amount; amount = event->direction == GDK_SCROLL_UP ? 5 : -5; volume_set_balance(s->slider,s->slider->balance + amount); return TRUE; } static gint volume_cb_scroll(GtkWidget *widget, GdkEventScroll *event,Slider *s) { gint amount; amount = volume_get_volume(s); amount += event->direction == GDK_SCROLL_UP ? 5 : -5; volume_set_volume(s,amount); return TRUE; } static void bvolume_button_press(GtkWidget *widget, GdkEventButton *ev,Bslider *s) { long location; if (ev->button == 1) { SET_FLAG(s->flags,IS_PRESSED); location = ev->x >= 0 ? ev->x : 0; location = (location * 200) / gkrellm_chart_width(); volume_set_balance(s->slider,location - 100); } } static void volume_button_press(GtkWidget *widget,GdkEventButton *ev,Slider *s) { long location; if (ev->button == 1) { SET_FLAG(s->flags,IS_PRESSED); location = ev->x >= 0 ? ev->x : 0; location = (location * mixer_get_device_fullscale(s->mixer,s->dev)) / gkrellm_chart_width(); volume_set_volume(s,location); } } static void bvolume_button_release(GtkWidget *widget,GdkEventButton *ev,Bslider *s) { if (ev->button == 1) DEL_FLAG(s->flags,IS_PRESSED); if (ev->button == 2) volume_toggle_mute(s->slider); } static void volume_button_release(GtkWidget *widget,GdkEventButton *ev,Slider *s) { if (ev->button == 1) DEL_FLAG(s->flags,IS_PRESSED); if (ev->button == 2) volume_toggle_mute(s); } static void bvolume_motion(GtkWidget *widget,GdkEventMotion *ev,Bslider *s) { gdouble location; if (!(GET_FLAG(s->flags,IS_PRESSED))) return; if (!(ev->state & GDK_BUTTON1_MASK)) { /* just to be sure */ DEL_FLAG(s->flags,IS_PRESSED); return ; } location = ev->x >= 0 ? ev->x : 0; location = (location * 200) / gkrellm_chart_width(); if (location > 200) location = 200 ; volume_set_balance(s->slider,location - 100); } static void volume_motion(GtkWidget *widget,GdkEventMotion *ev,Slider *s) { gdouble location; if (!GET_FLAG(s->flags,IS_PRESSED)) return; if (!(ev->state & GDK_BUTTON1_MASK)) { /* just to be sure */ DEL_FLAG(s->flags,IS_PRESSED); return ; } location = ev->x >= 0 ? ev->x : 0; location = (location * mixer_get_device_fullscale(s->mixer,s->dev)) / gkrellm_chart_width(); volume_set_volume(s,location); } static void create_bslider(Slider *slide,int first_create) { GkrellmStyle *panel_style = gkrellm_meter_style(VOLUME_STYLE); GkrellmMargin *m = gkrellm_get_style_margins(panel_style); GkrellmStyle *slider_style = gkrellm_krell_slider_style(); GkrellmTextstyle *ts = gkrellm_meter_textstyle(VOLUME_STYLE); GkrellmPiximage *krell_image; Bslider *result; if (first_create) { result = malloc(sizeof(Bslider)); result->panel = gkrellm_panel_new0(); slide->bal = result; result->slider = slide; } else result = slide->bal; krell_image = gkrellm_krell_slider_piximage(); gkrellm_set_style_slider_values_default(slider_style, panel_style->krell_yoff, m->left, m->right); result->krell = gkrellm_create_krell(result->panel,krell_image,slider_style); /* [-100..+100] */ gkrellm_set_krell_full_scale(result->krell,200, 1); gkrellm_monotonic_krell_values(result->krell, FALSE); result->decal = gkrellm_create_decal_text(result->panel,"Centered", ts,panel_style,-1,-1,-1); gkrellm_draw_decal_text(result->panel,result->decal,"Centered",-1); gkrellm_panel_configure(result->panel, NULL, panel_style); gkrellm_panel_create(pluginbox, monitor, result->panel); if (first_create) { g_signal_connect(GTK_OBJECT(result->panel->drawing_area), "expose_event", G_CALLBACK(bvolume_expose_event),result); g_signal_connect(G_OBJECT(result->panel->drawing_area), "scroll_event", G_CALLBACK(bvolume_cb_scroll), result); g_signal_connect(G_OBJECT(result->panel->drawing_area),"button_press_event", G_CALLBACK(bvolume_button_press),result); g_signal_connect(GTK_OBJECT(result->panel->drawing_area), "button_release_event", G_CALLBACK(bvolume_button_release),result); g_signal_connect(GTK_OBJECT(result->panel->drawing_area), "motion_notify_event", G_CALLBACK(bvolume_motion),result); } volume_show_balance(slide); } static void create_slider(Slider *s,int first_create) { GkrellmStyle *style = gkrellm_meter_style(VOLUME_STYLE); GkrellmStyle *slider_style = gkrellm_krell_slider_style(); GkrellmPiximage *krell_image; if (first_create) s->panel = gkrellm_panel_new0(); gkrellm_panel_configure(s->panel, mixer_get_device_name(s->mixer,s->dev), style); gkrellm_panel_create(pluginbox, monitor, s->panel); krell_image = gkrellm_krell_slider_piximage(); s->krell = gkrellm_create_krell(s->panel,krell_image,slider_style); gkrellm_set_krell_full_scale(s->krell, mixer_get_device_fullscale(s->mixer,s->dev), 1); gkrellm_monotonic_krell_values(s->krell, FALSE); if (first_create) { g_signal_connect(GTK_OBJECT(s->panel->drawing_area), "expose_event", G_CALLBACK(volume_expose_event),s); g_signal_connect(G_OBJECT(s->panel->drawing_area), "scroll_event", G_CALLBACK(volume_cb_scroll), s); g_signal_connect(G_OBJECT(s->panel->drawing_area), "button_press_event", G_CALLBACK(volume_button_press),s); g_signal_connect(GTK_OBJECT(s->panel->drawing_area),"button_release_event", G_CALLBACK(volume_button_release),s); g_signal_connect(GTK_OBJECT(s->panel->drawing_area),"motion_notify_event", G_CALLBACK(volume_motion),s); } volume_show_volume(s); if (GET_FLAG(s->flags,BALANCE)) create_bslider(s,first_create); } static void create_volume_plugin(GtkWidget *vbox,gint first_create) { Mixer *m; Slider *s; pluginbox = vbox; for (m = Mixerz ; m != NULL; m = m->next) for (s = m->Sliderz; s != NULL ; s = s->next) { create_slider(s,first_create); } } static void update_volume_plugin(void) { Slider *s; Mixer *m; for (m = Mixerz; m != NULL; m = m->next) for (s = m->Sliderz ; s != NULL; s = s->next) { int left,right; mixer_get_device_volume(s->mixer,s->dev,&left,&right); /* calculate the balance and show volume if needed */ if (s->pleft!=left || s->pright!=right) { if (GET_FLAG(s->flags,BALANCE)) { if (left < right) { s->balance = 100 - (gint) rint(((gdouble)left/right) * 100); } else if (left > right) { s->balance = (gint) rint(((gdouble)right/left) * 100) - 100; } else if (left == right && left != 0) s->balance = 0; volume_show_balance(s); } if (!GET_FLAG(s->flags,MUTED)) { s->pleft = left; s->pright = right; } volume_show_volume(s); } } } static void save_volume_plugin_config(FILE *f) { Mixer *m; Slider *s; if (GET_FLAG(global_flags,MUTEALL)) fprintf(f,"%s MUTEALL\n",CONFIG_KEYWORD); for (m = Mixerz ; m != NULL ; m = m->next) { fprintf(f,"%s ADDMIXER %s\n",CONFIG_KEYWORD,m->id); for(s = m->Sliderz; s != NULL; s = s->next) { fprintf(f,"%s ADDDEV %d\n",CONFIG_KEYWORD,s->dev); if (strcmp(mixer_get_device_name(s->mixer,s->dev), mixer_get_device_real_name(s->mixer,s->dev))) { fprintf(f,"%s SETDEVNAME %s\n",CONFIG_KEYWORD, mixer_get_device_name(s->mixer,s->dev)); } if (GET_FLAG(s->flags,BALANCE)) fprintf(f,"%s SHOWBALANCE\n",CONFIG_KEYWORD); if (GET_FLAG(s->flags,SAVE_VOLUME)) { int left,right; mixer_get_device_volume(s->mixer,s->dev,&left,&right); fprintf(f,"%s SETVOLUME %d %d\n",CONFIG_KEYWORD,left,right); } } } } static void load_volume_plugin_config(gchar *command) { static Mixer *m = NULL; static Slider *s = NULL; gchar *arg; /* gkrellm doesn't care if we fsck the string it gives us */ for (arg = command; !isspace(*arg); arg++); *arg = '\0'; arg++; if (!strcmp("MUTEALL",command)) SET_FLAG(global_flags,MUTEALL); else if (!strcmp("ADDMIXER",command)) { m = add_mixer_by_id(arg); } else if (!strcmp("ADDDEV",command)) { if (m != NULL) s = add_slider(m,atoi(arg)); } else if (!strcmp("SETDEVNAME",command)) { if (s != NULL) mixer_set_device_name(s->mixer,s->dev,arg); } else if (!strcmp("SHOWBALANCE",command)) { if (s != NULL) SET_FLAG(s->flags,BALANCE); } else if (!strcmp("SETVOLUME",command)) { if (s != NULL) { char *next; int left,right; left = strtol(arg,&next,10); right = strtol(next,NULL,10); mixer_set_device_volume(s->mixer,s->dev,left,right); SET_FLAG(s->flags,SAVE_VOLUME); } } } /* configuration code */ enum { ID_COLUMN = 0, NAME_COLUMN, C_MODEL_COLUMN, C_NB_COLUMN, N_COLUMNS }; enum { C_ENABLED_COLUMN = 0, C_VOLUME_COLUMN, C_BALANCE_COLUMN, C_NAME_COLUMN, C_SNAME_COLUMN, C_DEVNR_COLUMN, C_N_COLUMNS }; GtkListStore *model; GtkWidget *config_notebook; /* Used to only update the sliderz if needed. So there isn't any unnecessary * flickering */ gboolean mixer_config_changed = FALSE; static void toggle_item(gchar *path_str,gpointer data,gint column) { GtkTreePath *path = gtk_tree_path_new_from_string(path_str); GtkTreeIter iter; gboolean item; gtk_tree_model_get_iter(GTK_TREE_MODEL(data),&iter,path); gtk_tree_model_get(GTK_TREE_MODEL(data),&iter,column,&item,-1); gtk_list_store_set(GTK_LIST_STORE(data),&iter,column,!item,-1); mixer_config_changed = TRUE; gtk_tree_path_free(path); } static void toggle_enabled(GtkCellRendererToggle *cell,gchar *path_str,gpointer data) { toggle_item(path_str,data,C_ENABLED_COLUMN); } static void toggle_volume(GtkCellRendererToggle *cell,gchar *path_str,gpointer data) { toggle_item(path_str,data,C_VOLUME_COLUMN); } static void toggle_balance(GtkCellRendererToggle *cell,gchar *path_str,gpointer data) { toggle_item(path_str,data,C_BALANCE_COLUMN); } static void device_name_edited(GtkCellRendererText *text, gchar *pathstr,gchar *value,gpointer user_data) { GtkTreePath *path = gtk_tree_path_new_from_string(pathstr); GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(user_data),&iter,path); gtk_list_store_set(GTK_LIST_STORE(user_data),&iter,C_SNAME_COLUMN,value,-1); mixer_config_changed = TRUE; } static GtkWidget * create_device_notebook(GtkListStore *store, char *name) { GtkWidget *treeview; GtkCellRenderer *renderer; GtkWidget *scrolledwindow; GtkWidget *label; GtkWidget *vbox = gtk_vbox_new(FALSE,3); vbox = gtk_vbox_new(FALSE,0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); label = gtk_label_new(name); gtk_notebook_insert_page(GTK_NOTEBOOK(config_notebook), vbox, label,1); vbox = gkrellm_gtk_framed_vbox(vbox,NULL,2,TRUE,0,2); treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview),TRUE); gtk_tree_selection_set_mode( gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_SINGLE); /* causes it to be destroyed when the treeview is destroyed */ g_object_unref(G_OBJECT(store)); renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_enabled),store); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Enabled",renderer, "active",C_ENABLED_COLUMN, NULL); renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_volume),store); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Save volume",renderer, "active",C_VOLUME_COLUMN, "activatable",C_ENABLED_COLUMN, NULL); #if !defined(WIN32) renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_balance),store); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Balance",renderer, "active",C_BALANCE_COLUMN, "activatable",C_ENABLED_COLUMN, NULL); #endif renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Name",renderer, "text", C_NAME_COLUMN, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Shown Name",renderer, "text",C_SNAME_COLUMN, "editable",C_ENABLED_COLUMN, NULL); g_signal_connect(G_OBJECT(renderer),"edited", G_CALLBACK(device_name_edited),store); scrolledwindow = gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_box_pack_start(GTK_BOX(vbox),scrolledwindow,TRUE,TRUE,3); gtk_container_add(GTK_CONTAINER(scrolledwindow),treeview); gtk_widget_show_all(vbox); return vbox; } static void add_mixer_to_model(char *id, mixer_t *mixer, Slider *s) { GtkTreeIter iter; GtkListStore *child_model; gboolean enabled,save_volume,balance; GtkWidget *notebook; int i; child_model = gtk_list_store_new(C_N_COLUMNS, G_TYPE_BOOLEAN, /* enabled or not */ G_TYPE_BOOLEAN, /* save volume or not */ G_TYPE_BOOLEAN, /* show balance or not */ G_TYPE_STRING, /* real name */ G_TYPE_STRING, /* set name */ G_TYPE_INT /* device number */ ); for(i = 0; i < mixer_get_nr_devices(mixer); i++) { if (s != NULL && s->dev == i) { enabled = TRUE; save_volume = GET_FLAG(s->flags,SAVE_VOLUME); balance = GET_FLAG(s->flags,BALANCE); s = s->next; } else { enabled = save_volume = balance = FALSE; } gtk_list_store_append(child_model,&iter); gtk_list_store_set(child_model,&iter, C_ENABLED_COLUMN,enabled, C_VOLUME_COLUMN,save_volume, C_BALANCE_COLUMN,balance, C_NAME_COLUMN,mixer_get_device_real_name(mixer,i), C_SNAME_COLUMN,mixer_get_device_name(mixer,i), C_DEVNR_COLUMN,i, -1); } notebook = create_device_notebook(child_model,mixer_get_name(mixer)); gtk_list_store_append(model,&iter); gtk_list_store_set(model,&iter, ID_COLUMN,id, NAME_COLUMN,mixer_get_name(mixer), C_MODEL_COLUMN,child_model, C_NB_COLUMN,notebook, -1); return; } static gboolean findid(GtkTreeModel *m,GtkTreePath *path, GtkTreeIter *iter,gpointer data) { char *item; char **arg = (char **) data; gtk_tree_model_get(m,iter,ID_COLUMN,&item,-1); if (!strcmp(item,*arg)) { *arg = NULL; return TRUE; } return FALSE; } static void add_mixerid_to_model(char *id,gboolean gui) { char **arg = &id; char *name; mixer_t *mixer; gtk_tree_model_foreach(GTK_TREE_MODEL(model),findid,arg); if (id == NULL) { if (gui) gkrellm_message_window("Error","Id already in list",NULL); return; } if ((mixer = mixer_open(id)) == NULL) { if (gui) { name = g_strdup_printf("Couldn't open %s or %s isn't a mixer device",id,id); gkrellm_message_window("Error",name,NULL); g_free(name); } return; } add_mixer_to_model(id,mixer, NULL); mixer_close(mixer); return; } static void up_clicked(GtkWidget *widget,gpointer user_data) { GtkTreeIter selected,up,new; GtkTreeView *view = GTK_TREE_VIEW(user_data); GtkTreeSelection *selection; GtkTreeModel *model; GtkTreePath *path; gchar *name,*id; gpointer *child_model,*nb; selection = gtk_tree_view_get_selection(view); if (!gtk_tree_selection_get_selected(selection,&model,&selected)) return; gtk_tree_model_get(model,&selected, ID_COLUMN,&id, NAME_COLUMN,&name, C_MODEL_COLUMN,&child_model, C_NB_COLUMN,&nb, -1); path = gtk_tree_model_get_path(model,&selected); if (!gtk_tree_path_prev(path)) return; if (!gtk_tree_model_get_iter(model,&up,path)) return; gtk_list_store_remove(GTK_LIST_STORE(model),&selected); gtk_list_store_insert_before(GTK_LIST_STORE(model),&new,&up); gtk_list_store_set(GTK_LIST_STORE(model),&new, ID_COLUMN,id, NAME_COLUMN,name, C_MODEL_COLUMN,child_model, C_NB_COLUMN,nb, -1); mixer_config_changed = TRUE; } static void down_clicked(GtkWidget *widget,gpointer user_data) { GtkTreeIter selected,down,new; GtkTreeView *view = GTK_TREE_VIEW(user_data); GtkTreeSelection *selection; GtkTreeModel *model; GtkTreePath *path; gchar *name,*id; gpointer *child_model,*nb; selection = gtk_tree_view_get_selection(view); if (!gtk_tree_selection_get_selected(selection,&model,&selected)) return; gtk_tree_model_get(model,&selected, ID_COLUMN,&id, NAME_COLUMN,&name, C_MODEL_COLUMN,&child_model, C_NB_COLUMN,&nb, -1); path = gtk_tree_model_get_path(model,&selected); gtk_tree_path_next(path); if (!gtk_tree_model_get_iter(model,&down,path)) return; gtk_list_store_insert_after(GTK_LIST_STORE(model),&new,&down); gtk_list_store_set(GTK_LIST_STORE(model),&new, ID_COLUMN,id, NAME_COLUMN,name, C_MODEL_COLUMN,child_model, C_NB_COLUMN,nb, -1); mixer_config_changed = TRUE; gtk_list_store_remove(GTK_LIST_STORE(model),&selected); } #ifndef WIN32 static void file_choosen(GtkWidget *w,gpointer selector) { char *id; id = (char *) gtk_file_selection_get_filename(GTK_FILE_SELECTION(selector)); add_mixerid_to_model(id,TRUE); } static void select_file(GtkWidget *widget,gpointer user_data) { GtkWidget *selector; selector = gtk_file_selection_new("Please select a mixer device"); gtk_file_selection_set_filename(GTK_FILE_SELECTION(selector),"/dev/"); g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(selector)->ok_button), "clicked", G_CALLBACK(file_choosen), selector); g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(selector)->ok_button), "clicked", G_CALLBACK (gtk_widget_destroy), (gpointer) selector); g_signal_connect_swapped( GTK_OBJECT(GTK_FILE_SELECTION(selector)->cancel_button), "clicked", G_CALLBACK (gtk_widget_destroy), (gpointer) selector); gtk_widget_show(selector); } #endif static void create_volume_model(void) { Mixer *m; mixer_idz_t *idz,*t; model = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, /* id */ G_TYPE_STRING, /* name */ G_TYPE_POINTER, /* pointer to the child store */ G_TYPE_POINTER /* pointer to the child NB */ ); for (m = Mixerz; m != NULL; m = m->next) { add_mixer_to_model(m->id,m->mixer,m->Sliderz); } idz = mixer_get_id_list(); for (t = idz; t != NULL; t = t->next) { add_mixerid_to_model(t->id,FALSE); } mixer_free_idz(idz); } static void create_volume_plugin_mixer_tabs(void) { GtkWidget *treeview; GtkWidget *widget,*hbox,*vbox; GtkWidget *scrolledwindow; GtkWidget *notebook; GtkCellRenderer *renderer; notebook = gkrellm_gtk_framed_notebook_page(config_notebook,"Available mixers"); vbox = gtk_vbox_new(FALSE,3); gtk_container_add(GTK_CONTAINER(notebook),vbox); create_volume_model(); /* creating the treeview */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview),TRUE); gtk_tree_selection_set_mode( gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_SINGLE); /* causes it to be destroyed when the treeview is destroyed */ g_object_unref(G_OBJECT(model)); renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(G_OBJECT(renderer),"toggled", G_CALLBACK(toggle_enabled),model); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Id",renderer, "text", ID_COLUMN, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Mixer Name",renderer, "text",NAME_COLUMN, NULL); scrolledwindow = gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_box_pack_start(GTK_BOX(vbox),scrolledwindow,TRUE,TRUE,3); gtk_container_add(GTK_CONTAINER(scrolledwindow),treeview); hbox = gtk_hbox_new(FALSE,3); widget = gtk_button_new_from_stock(GTK_STOCK_GO_UP); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(up_clicked),treeview); gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,3); widget = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(down_clicked),treeview); gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,3); #ifndef WIN32 widget = gtk_button_new_from_stock(GTK_STOCK_ADD); gtk_box_pack_end(GTK_BOX(hbox),widget,FALSE,FALSE,3); g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(select_file),model); #endif gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,3); gtk_widget_show_all(notebook); } static void option_toggle(GtkWidget *widget,gpointer data) { if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) SET_FLAG(config_global_flags,GPOINTER_TO_INT(data)); else DEL_FLAG(config_global_flags,GPOINTER_TO_INT(data)); } static void create_volume_plugin_config(GtkWidget *tab) { GtkWidget *label,*text,*page,*toggle; gchar *info_text[] = { "Gkrellm Volume Plugin\n\n", "This plugin allows you to control your mixers with gkrellm\n\n", "User Interface:\n", "\tDragging the krells around or turning your mousewheel above a panel\n", "\twill change the volume of the device.\n", "\tMiddle mouse button will (un)mute the mixer\n\n", " Configuration:\n", "\tThe available mixers tab shows the detected mixers. The order of the\n", "\tmixers is the same as they will be in the main window\n", "\n", "\tEach mixers gets it's own tab. You can adjust each device seperatly:\n", "\t * Enabled: will cause the device to show up in the main window.\n", "\t * Save volume: will cause the volume and balance to be saved on exit\n", "\t and reset on startup.\n", #if !defined(WIN32) "\t * Balance: Gives you a panel below the device to control it's balance\n", #endif "\t * Name: The 'official' name of the device.\n", "\t * Shown name: can be edited and is the name shown in the main window.\n", "\n", "\t Options: Currently only one option, which should explain itself\n", "\n" }; gchar *plugin_about_text = g_strdup_printf( "Volumeplugin %d.%d.%d\n" \ "GKrellM volume Plugin\n\n" \ "Copyright (C) 2000 Sjoerd Simons\n" \ "sjoerd@luon.net\n" \ "http://gkrellm.luon.net \n\n" \ "Released under the GNU Public Licence", VOLUME_MAJOR_VERSION,VOLUME_MINOR_VERSION,VOLUME_EXTRA_VERSION); config_global_flags= global_flags; config_notebook = gtk_notebook_new(); gtk_notebook_set_scrollable(GTK_NOTEBOOK(config_notebook),TRUE); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(config_notebook), GTK_POS_TOP); gtk_box_pack_start(GTK_BOX(tab), config_notebook, TRUE, TRUE, 0); /* mixer tabs */ create_volume_plugin_mixer_tabs(); /* global options tab */ page = gkrellm_gtk_framed_notebook_page(config_notebook,"Options"); toggle = gtk_check_button_new_with_label("Mute all mixers at the same time"); g_signal_connect(GTK_OBJECT(toggle),"toggled", G_CALLBACK(option_toggle),GINT_TO_POINTER(MUTEALL)); gtk_box_pack_start(GTK_BOX(page),toggle,FALSE,FALSE,3); /* info tab */ page = gkrellm_gtk_notebook_page(config_notebook,"Info"); text = gkrellm_gtk_scrolled_text_view(page,NULL, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gkrellm_gtk_text_view_append_strings(text,info_text, sizeof(info_text)/sizeof(gchar *)); /* about tab */ text = gtk_label_new(plugin_about_text); label = gtk_label_new("About"); gtk_notebook_append_page(GTK_NOTEBOOK(config_notebook),text,label); g_free(plugin_about_text); gtk_widget_show_all(config_notebook); } static gboolean add_configed_mixer_device(GtkTreeModel *m, GtkTreePath *path, GtkTreeIter *iter,gpointer data) { gboolean enabled; gboolean save_volume; gboolean balance; gint nr; Slider *s; gchar *rname,*name; gchar *id = (gchar *) data; Mixer *mixer; gtk_tree_model_get(m,iter,C_ENABLED_COLUMN,&enabled,-1); if (enabled) { mixer = add_mixer_by_id(id); gtk_tree_model_get(m,iter, C_DEVNR_COLUMN,&nr, C_VOLUME_COLUMN,&save_volume, C_BALANCE_COLUMN,&balance, C_NAME_COLUMN,&rname, C_SNAME_COLUMN,&name, -1); if (strcmp(name,rname)) mixer_set_device_name(mixer->mixer,nr,name); s = add_slider(mixer,nr); if (save_volume) SET_FLAG(s->flags,SAVE_VOLUME); else DEL_FLAG(s->flags,SAVE_VOLUME); if (balance) SET_FLAG(s->flags,BALANCE); else DEL_FLAG(s->flags,BALANCE); create_slider(s,1); } return FALSE; } static gboolean add_configed_mixer(GtkTreeModel *m,GtkTreePath *path, GtkTreeIter *iter,gpointer data) { GtkListStore *store; gchar *id; gtk_tree_model_get(m,iter,ID_COLUMN,&id,C_MODEL_COLUMN,&store,-1); gtk_tree_model_foreach(GTK_TREE_MODEL(store),add_configed_mixer_device,id); return FALSE; } void apply_volume_plugin_config(void) { if (mixer_config_changed) { remove_all_mixers(); gtk_tree_model_foreach(GTK_TREE_MODEL(model),add_configed_mixer,NULL); mixer_config_changed = FALSE; } global_flags = config_global_flags; } /* end of configuration code */ static GkrellmMonitor plugin_mon = { "Volume Plugin", /* Name, for config tab. */ 0, /* Id, 0 if a plugin */ create_volume_plugin, /* The create function */ update_volume_plugin, /* The update function */ create_volume_plugin_config, /* The config tab create function */ apply_volume_plugin_config, /* Apply the config function */ save_volume_plugin_config, /* Save user config */ load_volume_plugin_config, /* Load user config */ CONFIG_KEYWORD, /* config keyword */ NULL, /* Undefined 2 */ NULL, /* Undefined 1 */ NULL, /* Undefined 0 */ LOCATION, NULL, /* Handle if a plugin, filled in by GKrellM */ NULL /* path if a plugin, filled in by GKrellM */ }; #if defined(WIN32) __declspec(dllexport) GkrellmMonitor * gkrellm_init_plugin(win32_plugin_callbacks* calls) #else GkrellmMonitor * gkrellm_init_plugin(void) #endif { #if defined(WIN32) callbacks = calls; #endif style_id = gkrellm_add_meter_style(&plugin_mon,"volume"); Mixerz = NULL; monitor = &plugin_mon; return monitor; } gkrellm-volume-2.1.13/po/0000755000175000017500000000000010111204177015746 5ustar sjoerdsjoerd00000000000000gkrellm-volume-2.1.13/po/README0000644000175000017500000000470710111204177016636 0ustar sjoerdsjoerd00000000000000 Adding a translation to gkrellm-volume -------------------------------------- 0) History ---------- This document is taken from the gkrellm source tree and adapted for gkrellm-volume 1) Extract the strings from the source -------------------------------------- In the gkrellm-volume top level directory, create the .po template (.pot): xgettext -k_ -kN_ src/*.c -o po/gkrellm-volume.pot 2) Update or create .po files ----------------------------- If there are any existing translations, XX.po files, then merge them: cd po msgmerge XX.po gkrellm-volume.pot > XX.po.new mv XX.po.new XX.po Or, if this is a new translation, copy the template: cd po cp gkrellm-volume.pot XX.po 3) Add translations ------------------- Edit XX.po to add translations for new strings, fix broken translations, and touch up fuzzy translations. 4) Make and install gkrellm-volume with i18n enabled ---------------------------------------------------- If make is run from this directory instead of the top level dir, you must explicitely enable i18n in all the below examples by adding enable_nls=1 to the make command: make enable_nls=1 And for the install step: make install enable_nls=1 i18n will be automatically enabled when make is run from the top level dir. In either case, a make install will for each XX.po file create a XX.mo file and copy it to: $LOCALEDIR/XX/LC_MESSAGES/gkrellm-volume.mo If there is no LOCALEDIR environment variable, then the default install will be to: /usr/share/locale/XX/LC_MESSAGES/gkrellm-volume.mo But, if you want a different explicit install directory, do for example: make install LOCALEDIR=/usr/local/share/locale or (for bash) export LOCALEDIR=/usr/local/share/locale make install Other export lines: sh: export LOCALEDIR; LOCALEDIR=/usr/local/share/locale csh: setenv LOCALEDIR /usr/local/share/locale You can also specify the textdomain package name. From bash: make install PACKAGE=gkrellm-volume2 ============================================================================ Using a translation ------------------- A user must have localizations enabled for a translation to be used. To enable a localization, the LANG environment variable should be set via the command line or the shell login startup files. For example, to see the French translation, a user should be able to: From bash: export LANG=fr_FR or from csh setenv LANG fr_FR If fr_FR does not work, try fr_FR.ISO_8859-1 gkrellm-volume-2.1.13/po/Makefile0000644000175000017500000000100010111204177017375 0ustar sjoerdsjoerd00000000000000MSGFMT = msgfmt SUB_DIRS = FILES_PO:=$(wildcard *.po) FILES_MO:=$(FILES_PO:.po=.mo) LOCALEDIR ?= /usr/share/locale PACKAGE ?= gkrellm-volume ifeq ($(enable_nls),1) all: mo-files mo-files: $(FILES_MO) install: $(MAKE) all for f in *.mo ; do mkdir -p \ $(INSTALL_PREFIX)$(LOCALEDIR)/`basename $$f .mo`/LC_MESSAGES ; \ cp $$f $(INSTALL_PREFIX)$(LOCALEDIR)/`basename $$f .mo`/LC_MESSAGES/$(PACKAGE).mo ; done %.mo: %.po $(MSGFMT) -f -v -o $@ $< else all: install: endif clean: $(RM) $(FILES_MO) gkrellm-volume-2.1.13/po/ru.po0000644000175000017500000001120510111204177016733 0ustar sjoerdsjoerd00000000000000# Russian Translation of GKrellM Volume plugin. # Grigory Batalov , 2002-2003. msgid "" msgstr "" "Project-Id-Version: gkrellm-volume 2.1.9\n" "POT-Creation-Date: 2003-08-25 19:53+0400\n" "PO-Revision-Date: 2003-08-25 20:13+0400\n" "Last-Translator: Grigory Batalov \n" "Language-Team: none\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=KOI8-R\n" "Content-Transfer-Encoding: 8bit\n" #: volume.c:162 volume.c:343 volume.c:345 msgid "Centered" msgstr "ÐÏ ÃÅÎÔÒÕ" #: volume.c:164 msgid "Right" msgstr "×ÐÒÁ×Ï" #: volume.c:164 msgid "Left" msgstr "×ÌÅ×Ï" #: volume.c:609 msgid "Enabled" msgstr "ðÏËÁÚÁÔØ" #: volume.c:617 msgid "Save volume" msgstr "úÁÐÏÍÉÎÁÔØ" #: volume.c:627 msgid "Balance" msgstr "âÁÌÁÎÓ" #: volume.c:635 msgid "Name" msgstr "éÍÑ" #: volume.c:641 msgid "Shown Name" msgstr "ðÏÄÐÉÓØ" #: volume.c:729 volume.c:736 msgid "Error" msgstr "ïÛÉÂËÁ" #: volume.c:729 msgid "Id already in list" msgstr "Id ÕÖÅ ÅÓÔØ × ÓÐÉÓËÅ" #: volume.c:735 #, c-format msgid "Couldn't open %s or %s isn't a mixer device" msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s, ÉÌÉ %s - ÎÅ ÍÉËÛÅÒ" #: volume.c:824 msgid "Please select a mixer device" msgstr "÷ÙÂÅÒÉÔÅ ÕÓÔÒÏÊÓÔ×Ï ÍÉËÛÅÒÁ" #: volume.c:871 msgid "Available mixers" msgstr "äÏÓÔÕÐÎÙÅ ÍÉËÛÅÒÙ" #: volume.c:895 msgid "Id" msgstr "" #: volume.c:901 msgid "Mixer Name" msgstr "éÍÑ ÍÉËÛÅÒÁ" #: volume.c:948 msgid "" "Gkrellm Volume Plugin\n" "\n" msgstr "" #: volume.c:949 msgid "" "This plugin allows you to control your mixers with gkrellm\n" "\n" msgstr "" "üÔÏÔ ÐÌÁÇÉÎ ÐÏÚ×ÏÌÑÅÔ ×ÁÍ ÒÅÇÕÌÉÒÏ×ÁÔØ ÍÉËÛÅÒÙ ÉÚ gkrellm\n" "\n" #: volume.c:950 msgid "User Interface:\n" msgstr "ðÏÌØÚÏ×ÁÔÅÌØÓËÉÊ ÉÎÔÅÒÆÅÊÓ:\n" #: volume.c:951 msgid "" "\tDragging the krells around or turning your mousewheel above a panel\n" "\twill change the volume of the device.\n" "\tMiddle mouse button will (un)mute the mixer\n" "\n" msgstr "" "\tðÅÒÅÍÅÝÁÑ ËÒÅÌÌÙ ÉÌÉ ÐÏ×ÏÒÁÞÉ×ÁÑ ËÏÌÅÓÏ ÍÙÛÉ ÎÁÄ ÐÁÎÅÌØÀ ÐÌÁÇÉÎÁ,\n" "\t×Ù ÍÏÖÅÔÅ ÉÚÍÅÎÑÔØ ÇÒÏÍËÏÓÔØ ÕÓÔÒÏÊÓÔ×.\n" "\tóÒÅÄÎÑÑ ËÎÏÐËÁ ×ËÌÀÞÁÅÔ/×ÙËÌÀÞÁÅÔ ÕÓÔÒÏÊÓÔ×Ï.\n" #: volume.c:954 msgid " Configuration:\n" msgstr " îÁÓÔÒÏÊËÁ:\n" #: volume.c:956 msgid "" "\tThe available mixers tab shows the detected mixers. The order of the\n" "\tmixers is the same as they will be in the main window\n" "\n" "\tEach mixer gets its own tab. You can adjust each device separately:\n" "\t * Enabled: will cause the device to show up in the main window.\n" "\t * Save volume: will cause the volume and balance to be saved on exit\n" "\t and reset on startup.\n" msgstr "" "\t÷ËÌÁÄËÁ \"äÏÓÔÕÐÎÙÅ ÍÉËÛÅÒÙ\" ÓÏÄÅÒÖÉÔ ÏÂÎÁÒÕÖÅÎÎÙÅ ÕÓÔÒÏÊÓÔ×Á.\n" "\tðÏÒÑÄÏË ÍÉËÛÅÒÏ× ÔÁËÏÊ ÖÅ, ËÁË ÏÎ ÂÕÄÅÔ × ÏËÎÅ gkrellm.\n" "\n" "\tëÁÖÄÏÅ ÕÓÔÒÏÊÓÔ×Ï ÎÁÓÔÒÁÉ×ÁÅÔÓÑ × ÓÏÂÓÔ×ÅÎÎÏÊ ×ËÌÁÄËÅ:\n" "\t * ðÏËÁÚÁÔØ: ÕÓÔÒÏÊÓÔ×Ï ÐÏÑ×ÌÑÅÔÓÑ × ÇÌÁ×ÎÏÍ ÏËÎÅ.\n" "\t * úÁÐÏÍÉÎÁÔØ: ÇÒÏÍËÏÓÔØ É ÂÁÌÁÎÓ ÂÕÄÕÔ ÚÁÐÉÓÁÎÙ ÐÒÉ ×ÙÈÏÄÅ\n" "\t É ×ÏÓÓÔÁÎÏ×ÌÅÎÙ ÐÒÉ ÚÁÐÕÓËÅ.\n" #: volume.c:965 msgid "" "\t * Balance: Gives you a panel below the device to control its balance\n" msgstr "\t * âÁÌÁÎÓ: ×Ù×ÏÄÉÔ ÄÏÐÏÌÎÉÔÅÌØÎÕÀ ÐÁÎÅÌØ ÄÌÑ ÎÁÓÔÒÏÊËÉ ÂÁÌÁÎÓÁ.\n" #: volume.c:968 msgid "" "\t * Name: The 'official' name of the device.\n" "\t * Shown name: can be edited and is the name shown in the main window.\n" "\n" msgstr "" "\t * éÍÑ: 'ÏÆÉÃÉÁÌØÎÏÅ' ÉÍÑ ÕÓÔÒÏÊÓÔ×Á.\n" "\t * ðÏÄÐÉÓØ: ÉÍÑ, ÏÔÏÂÒÁÖÁÅÍÏÅ × ÇÌÁ×ÎÏÍ ÏËÎÅ (ÍÏÖÎÏ ÍÅÎÑÔØ).\n" "\n" #: volume.c:971 msgid "Options:\n" msgstr "ïÐÃÉÉ:\n" #: volume.c:972 msgid "" "\t* Mute all mixers at the same time: Mutes all devices on a middle\n" "\t mouse button click instead of only the one the slider belongs to.\n" "\t* Right-click command: The command to run when the right mouse\n" "\t button is clicked on the plugin\n" msgstr "" "\t* ÷ÙËÌÀÞÁÔØ ×ÓÅ ÕÓÔÒÏÊÓÔ×Á ÏÄÎÏ×ÒÅÍÅÎÎÏ: ×ÙËÌÀÞÁÅÔ ÝÅÌÞËÏÍ ÓÒÅÄÎÅÊ\n" "\t ËÎÏÐËÉ ÍÙÛÉ ×ÓÅ ÕÓÔÒÏÊÓÔ×Á, Á ÎÅ ÔÏÌØËÏ ÔÏ, ÞÅÊ ÐÏÌÚÕÎÏË.\n" "\t* ëÏÍÁÎÄÁ ÄÌÑ ÚÁÐÕÓËÁ: ËÏÍÁÎÄÁ, ×ÙÐÏÌÎÑÅÍÁÑ ÐÒÉ ÝÅÌÞËÅ ÐÒÁ×ÏÊ\n" "\t ËÎÏÐËÏÊ ÍÙÛÉ\n" #: volume.c:981 #, c-format msgid "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" msgstr "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "òÁÓÐÒÏÓÔÒÁÎÑÅÔÓÑ ÐÏÄ GNU Public Licence" #: volume.c:1001 msgid "Options" msgstr "ïÐÃÉÉ" #: volume.c:1004 msgid "Mute all mixers at the same time" msgstr "÷ÙËÌÀÞÁÔØ ×ÓÅ ÕÓÔÒÏÊÓÔ×Á ÏÄÎÏ×ÒÅÍÅÎÎÏ" #: volume.c:1011 msgid "Right-click command: " msgstr "ëÏÍÁÎÄÁ ÄÌÑ ÚÁÐÕÓËÁ: " #: volume.c:1019 msgid "Info" msgstr "éÎÆÏ" #: volume.c:1028 msgid "About" msgstr "ï ÐÒÏÇÒÁÍÍÅ" gkrellm-volume-2.1.13/po/nl.po0000644000175000017500000001202610111204177016720 0ustar sjoerdsjoerd00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: gkrellm-volume 2.1.9\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2003-08-26 09:33+0200\n" "PO-Revision-Date: 2002-11-2 19:49+0100\n" "Last-Translator: Michiel Sikkes \n" "Language-Team: Nederlands \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-15\n" "Content-Transfer-Encoding: 8bit\n" #: volume.c:162 volume.c:343 volume.c:345 msgid "Centered" msgstr "Gecentreerd" #: volume.c:164 msgid "Right" msgstr "Rechts" #: volume.c:164 msgid "Left" msgstr "Links" #: volume.c:609 msgid "Enabled" msgstr "Zichtbaar" #: volume.c:617 msgid "Save volume" msgstr "Volume instellingen opslaan" #: volume.c:627 msgid "Balance" msgstr "Balans" #: volume.c:635 msgid "Name" msgstr "Naam" #: volume.c:641 msgid "Shown Name" msgstr "Weergeven Naam" #: volume.c:729 volume.c:736 msgid "Error" msgstr "Fout" #: volume.c:729 msgid "Id already in list" msgstr "Id bestaat al in de lijst" #: volume.c:735 #, c-format msgid "Couldn't open %s or %s isn't a mixer device" msgstr "Kon %s niet openen of %s is geen mixer device" #: volume.c:824 msgid "Please select a mixer device" msgstr "Selecteer een mixer device" #: volume.c:871 msgid "Available mixers" msgstr "Beschikbare mixers" #: volume.c:895 msgid "Id" msgstr "Id" #: volume.c:901 msgid "Mixer Name" msgstr "Mixer Naam" #: volume.c:948 msgid "" "Gkrellm Volume Plugin\n" "\n" msgstr "" "Gkrellm Volume Plugin\n" "\n" #: volume.c:949 msgid "" "This plugin allows you to control your mixers with gkrellm\n" "\n" msgstr "" "Deze plugin laat u uw mixers besturen met gkrellm\n" "\n" #: volume.c:950 msgid "User Interface:\n" msgstr "Gebruikers Interface:\n" #: volume.c:951 msgid "" "\tDragging the krells around or turning your mousewheel above a panel\n" "\twill change the volume of the device.\n" "\tMiddle mouse button will (un)mute the mixer\n" "\n" msgstr "" "\tDoor de krells te slepen of uw muiswiel draaien boven een paneel\n" "\tzal het volume van het device veranderen\n" "\tDe middelste muisknop zal de mixer (ont)dempen\n" "\n" #: volume.c:954 msgid " Configuration:\n" msgstr " Configuratie:\n" #: volume.c:956 msgid "" "\tThe available mixers tab shows the detected mixers. The order of the\n" "\tmixers is the same as they will be in the main window\n" "\n" "\tEach mixer gets its own tab. You can adjust each device separately:\n" "\t * Enabled: will cause the device to show up in the main window.\n" "\t * Save volume: will cause the volume and balance to be saved on exit\n" "\t and reset on startup.\n" msgstr "" "\tDe beschikbare mixers tab laat de gedetecteerde mixers zien. De volgorde\n" "\tvan de mixers is dezelfde als ze zullen zijn in het main window\n" "\n" "\tElke mixer krijgt zijn eigen tab. U kunt de instellingen van elk device\n" "\tapart instellen:\n" "\t * Zichtbaar: zal het device in het main window laten verschijnen.\n" "\t * Volume opslaan: zal de volume en balans instellingen opslaan bij het\n" "\t afsluiten en herstellen bij opstarten.\n" #: volume.c:965 msgid "" "\t * Balance: Gives you a panel below the device to control its balance\n" msgstr "" "\t * Balans: Geeft u een paneel onder het device om de balans te wijzigen\n" #: volume.c:968 #, fuzzy msgid "" "\t * Name: The 'official' name of the device.\n" "\t * Shown name: can be edited and is the name shown in the main window.\n" "\n" msgstr "" "\t * Naam: De 'officiële' naam van het device.\n" "\t * Weergeven naam: kan gewijzigd worden en is de naam weergeven in het\n" "\t main window.\n" "\n" #: volume.c:971 #, fuzzy msgid "Options:\n" msgstr "Opties:\n" #: volume.c:972 msgid "" "\t* Mute all mixers at the same time: Mutes all devices on a middle\n" "\t mouse button click instead of only the one the slider belongs to.\n" "\t* Right-click command: The command to run when the right mouse\n" "\t button is clicked on the plugin\n" msgstr "" "\t* Alle mixers tegelijk dempen: Dempt alle devices op een middelste\n" "\t muisknop klik behalve degene waar de slider bijhoort waar op geklikt is.\n" "\t* Rechter-muisknop: Het commando wat uitgevoert moet worden als er met de\n" "\t rechter-muisknop op geklikt wordt\n" #: volume.c:981 #, c-format msgid "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" msgstr "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Onder the GNU Public Licence uitgebracht." #: volume.c:1001 msgid "Options" msgstr "Opties" #: volume.c:1004 msgid "Mute all mixers at the same time" msgstr "Alle mixers tegelijk dempen" #: volume.c:1011 msgid "Right-click command: " msgstr "" #: volume.c:1019 msgid "Info" msgstr "Info" #: volume.c:1028 msgid "About" msgstr "Over" gkrellm-volume-2.1.13/po/pl.po0000644000175000017500000001170010111204177016720 0ustar sjoerdsjoerd00000000000000# Polish translation of GKrellM Volume plugin. # Copyright (C) 2002 Free Software Foundation, Inc. # Mariusz Jedrzejewski , 2003. # msgid "" msgstr "" "Project-Id-Version: gkrellm-volume 2.1.8\n" "POT-Creation-Date: 2003-08-26 15:17+0200\n" "PO-Revision-Date: 2003-08-26 15:34+0200\n" "Last-Translator: Mariusz Jedrzejewski \n" "Language-Team: none \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-2\n" "Content-Transfer-Encoding: 8bit\n" #: volume.c:162 volume.c:343 volume.c:345 msgid "Centered" msgstr "¦rodek" #: volume.c:164 msgid "Right" msgstr "Prawa" #: volume.c:164 msgid "Left" msgstr "Lewa" #: volume.c:609 msgid "Enabled" msgstr "W³±czony" #: volume.c:617 msgid "Save volume" msgstr "Pamiêtaj poziom" #: volume.c:627 msgid "Balance" msgstr "Balans" #: volume.c:635 msgid "Name" msgstr "Nazwa" #: volume.c:641 msgid "Shown Name" msgstr "Pokazywana nazwa" #: volume.c:729 volume.c:736 msgid "Error" msgstr "B³±d" #: volume.c:729 msgid "Id already in list" msgstr "Id jest ju¿ na li¶cie" #: volume.c:735 #, c-format msgid "Couldn't open %s or %s isn't a mixer device" msgstr "Nie mogê otworzyæ %s lub %s nie jest urz±dzeniem miksera" #: volume.c:824 msgid "Please select a mixer device" msgstr "Wybierz urz±dzenie miksera" #: volume.c:871 msgid "Available mixers" msgstr "Dostêpne miksery" #: volume.c:895 msgid "Id" msgstr "Id" #: volume.c:901 msgid "Mixer Name" msgstr "Nazwa miksera" #: volume.c:948 msgid "" "Gkrellm Volume Plugin\n" "\n" msgstr "" "Wtyczka miksera do Gkrellm\n" "\n" #: volume.c:949 msgid "" "This plugin allows you to control your mixers with gkrellm\n" "\n" msgstr "" "Ta wtyczka pozwala ci na sterowanie twoimi mikserami z poziomu GKrellm-a\n" "\n" #: volume.c:950 msgid "User Interface:\n" msgstr "Interfejs u¿ytkownika\n" #: volume.c:951 msgid "" "\tDragging the krells around or turning your mousewheel above a panel\n" "\twill change the volume of the device.\n" "\tMiddle mouse button will (un)mute the mixer\n" "\n" msgstr "" "\tPrzesuwanie krellami lub u¿ywanie kó³ka myszy nad panelem\n" "\tzmienia poziom d¼wiêku danego urz±dzenia.\n" "\t¦rodkowy przycisk myszy wycisza lub przywraca d¼wiêk w mikserze\n" "\n" #: volume.c:954 msgid " Configuration:\n" msgstr "Konfiguracja:\n" #: volume.c:956 msgid "" "\tThe available mixers tab shows the detected mixers. The order of the\n" "\tmixers is the same as they will be in the main window\n" "\n" "\tEach mixer gets its own tab. You can adjust each device separately:\n" "\t * Enabled: will cause the device to show up in the main window.\n" "\t * Save volume: will cause the volume and balance to be saved on exit\n" "\t and reset on startup.\n" msgstr "" "\tZak³adka dostêpnych mikserów pokazuje wykryte miksery. Kolejno¶æ mikserów\n" "\tjest taka, jaka bêdzie w g³ównym oknie\n" "\n" "\tKa¿dy mikser posiada w³asn± zak³adkê. Mo¿esz modyfikowaæ ustawienia " "ka¿dego\n" "\turz±dzenia niezale¿nie:\n" "\t * W³±czony: spowoduje pojawienie siê urz±dzenia w g³ównym oknie.\n" "\t * Pamiêtaj poziom: poziom dzwiêku i balans zostanie zapisany przy " "wyj¶ciu\n" "\t i odtworzony przy starcie.\n" #: volume.c:965 msgid "" "\t * Balance: Gives you a panel below the device to control its balance\n" msgstr "" "\t * Balans: Udostêpnia panel poni¿ej urz±dzenia kontroluj±cy balans " "dzwiêku\n" #: volume.c:968 msgid "" "\t * Name: The 'official' name of the device.\n" "\t * Shown name: can be edited and is the name shown in the main window.\n" "\n" msgstr "" "\t * Nazwa: 'Oficjalna' nazwa urz±dzenia.\n" "\t * Pokazywana nazwa: mo¿esz j± edytowaæ i taka sama bêdzie w g³ównym " "oknie.\n" "\n" #: volume.c:971 msgid "Options:\n" msgstr "Opcje:\n" #: volume.c:972 msgid "" "\t* Mute all mixers at the same time: Mutes all devices on a middle\n" "\t mouse button click instead of only the one the slider belongs to.\n" "\t* Right-click command: The command to run when the right mouse\n" "\t button is clicked on the plugin\n" msgstr "" "\t* Wycisz wszystkie miksery na raz: ¦rodkowy przycisk myszy wycisza\n" "\t wszystkie urz±dzenia w zamiast jednego, kontrolowanego przez suwak.\n" "\t* Polecenie miksera: Polecenie, które zostanie uruchomione po naci¶niêciu\n" "\t na wtyczce prawym przyciskiem myszy\n" #: volume.c:981 #, c-format msgid "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" msgstr "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" #: volume.c:1001 msgid "Options" msgstr "Opcje" #: volume.c:1004 msgid "Mute all mixers at the same time" msgstr "Wycisz wszystkie miksery na raz" #: volume.c:1011 msgid "Right-click command: " msgstr "Polecenie miksera: " #: volume.c:1019 msgid "Info" msgstr "Informacje" #: volume.c:1028 msgid "About" msgstr "O" gkrellm-volume-2.1.13/po/de.po0000644000175000017500000001207710111204177016705 0ustar sjoerdsjoerd00000000000000# German Translation of GKrellM Volume plugin. # Copyright (C) 2002 Free Software Foundation, Inc. # Steffen Weise , 2002. # msgid "" msgstr "" "Project-Id-Version: gkrellm-volume 2.1.9 prerelease\n" "POT-Creation-Date: 2003-08-29 07:34+0200\n" "PO-Revision-Date: 2003-08-29 10:54--100\n" "Last-Translator: Steffen Weise \n" "Language-Team: none \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #: volume.c:162 #: volume.c:343 #: volume.c:345 msgid "Centered" msgstr "Zentriert" #: volume.c:164 msgid "Right" msgstr "Rechts" #: volume.c:164 msgid "Left" msgstr "Links" #: volume.c:609 msgid "Enabled" msgstr "Aktiviert" #: volume.c:617 msgid "Save volume" msgstr "Lautstärke speichern" #: volume.c:627 msgid "Balance" msgstr "Balance" #: volume.c:635 msgid "Name" msgstr "Name" #: volume.c:641 msgid "Shown Name" msgstr "Angezeigter Name" #: volume.c:729 #: volume.c:736 msgid "Error" msgstr "Fehler" #: volume.c:729 msgid "Id already in list" msgstr "Id existiert bereits in der Liste" #: volume.c:735 #, c-format msgid "Couldn't open %s or %s isn't a mixer device" msgstr "%s konnte nicht geöffnet werden oder %s ist kein Mischgerät" #: volume.c:824 msgid "Please select a mixer device" msgstr "Bitte ein Mischgerät auswählen" #: volume.c:871 msgid "Available mixers" msgstr "Vorhandene Mischpulte" #: volume.c:895 msgid "Id" msgstr "Id" #: volume.c:901 msgid "Mixer Name" msgstr "Name des Mischpultes" #: volume.c:948 msgid "Gkrellm Volume Plugin\n" "\n" msgstr "GKrellM Volume Plugin\n" "\n" #: volume.c:949 msgid "This plugin allows you to control your mixers with gkrellm\n" "\n" msgstr "Diese Erweiterung erlaubt es, Mischpute mit GKrellM zu steuern\n" "\n" #: volume.c:950 msgid "User Interface:\n" msgstr "Benutzeroberfläche:\n" #: volume.c:951 msgid "" "\tDragging the krells around or turning your mousewheel above a panel\n" "\twill change the volume of the device.\n" "\tMiddle mouse button will (un)mute the mixer\n" "\n" msgstr "" "\tDas Umherziehen der Krells oder das Drehen des Mausrades über einem\n" "\tBedienfeld ändert die Lautstärke des Gerätes.\n" "\tDie mittlere Maustaste schaltet die Mischpulte laut/stumm\n" "\n" #: volume.c:954 msgid " Configuration:\n" msgstr " Konfiguration:\n" #: volume.c:956 msgid "" "\tThe available mixers tab shows the detected mixers. The order of the\n" "\tmixers is the same as they will be in the main window\n" "\n" "\tEach mixer gets its own tab. You can adjust each device separately:\n" "\t * Enabled: will cause the device to show up in the main window.\n" "\t * Save volume: will cause the volume and balance to be saved on exit\n" "\t and reset on startup.\n" msgstr "" "\tDie Sektion 'Vorhandene Mischpulte' zeigt die erkannten Mischpulte an.\n" "\tDie Reihenfolge der Mischpulte ist dieselbe wie im Hauptfenster.\n" "\n" "\tJedes Mischpult erhält seine eigene Sektion. Die Geräte können separat\n" "\tabgestimmt werden:\n" "\t * Aktiv: bewirkt, dass das Gerät im Hauptfenster erscheint.\n" "\t * Lautstärke speichern: bewirkt, dass Lautstärke und Balance beim\n" "\t Ausstieg gespeichert und bei Neustart wiederhergestellt werden.\n" #: volume.c:965 msgid "\t * Balance: Gives you a panel below the device to control its balance\n" msgstr "\t * Balance: Erzeugt ein Bedienfeld unter dem Gerät, um dessen Balance zu steuern\n" #: volume.c:968 msgid "" "\t * Name: The 'official' name of the device.\n" "\t * Shown name: can be edited and is the name shown in the main window.\n" "\n" msgstr "" "\t * Name: Der 'offizielle' Name des Gerätes.\n" "\t * Angezeigter Name: kann bearbeitet werden und ist der angezeigte Name im Hauptfenster.\n" "\n" #: volume.c:971 msgid "Options:\n" msgstr "Optionen:\n" #: volume.c:972 msgid "" "\t* Mute all mixers at the same time: Mutes all devices on a middle\n" "\t mouse button click instead of only the one the slider belongs to.\n" "\t* Right-click command: The command to run when the right mouse\n" "\t button is clicked on the plugin\n" msgstr "" "\t* Alle Mischpulte gleichzeitig stumm schalten: schaltet alle\n" "\t Geräte anstatt nur das dem entsprechenden Regler zugehörige\n" "\t Gerät mit Klick auf die mittlere Maustaste stumm.\n" "\t* Rechtsklick-Befehl: Der zu startende Befehl wenn die rechte\n" "\t Maustaste auf dem Plugin betätigt wird\n" #: volume.c:981 #, c-format msgid "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" msgstr "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" #: volume.c:1001 msgid "Options" msgstr "Optionen" #: volume.c:1004 msgid "Mute all mixers at the same time" msgstr "Alle Mischpulte gleichzeitig stumm schalten" #: volume.c:1011 msgid "Right-click command: " msgstr "Rechtsklick-Befehl:" #: volume.c:1019 msgid "Info" msgstr "Information" #: volume.c:1028 msgid "About" msgstr "Über" gkrellm-volume-2.1.13/po/fr.po0000644000175000017500000001206610111204177016722 0ustar sjoerdsjoerd00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: gkrellm-volume 2.1.9\n" "PO-Revision-Date: 2003-09-02 23:14+0200\n" "Last-Translator: Jérôme UZEL \n" "Language-Team: none \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-15\n" "Content-Transfer-Encoding: 8bit\n" #: volume.c:162 volume.c:343 volume.c:345 msgid "Centered" msgstr "Centré" #: volume.c:164 msgid "Right" msgstr "Droit" #: volume.c:164 msgid "Left" msgstr "Gauche" #: volume.c:609 msgid "Enabled" msgstr "Activé" #: volume.c:617 msgid "Save volume" msgstr "Enregistrer le volume" #: volume.c:627 msgid "Balance" msgstr "Balance" #: volume.c:635 msgid "Name" msgstr "Nom" #: volume.c:641 msgid "Shown Name" msgstr "Nom affiché" #: volume.c:729 volume.c:736 msgid "Error" msgstr "Erreur" #: volume.c:729 msgid "Id already in list" msgstr "Id déjà présent dans la liste" #: volume.c:735 #, c-format msgid "Couldn't open %s or %s isn't a mixer device" msgstr "" "Impossible d'ouvrir %s ou bien %s n'est pas un périphérique de mixage (mixer)" #: volume.c:824 msgid "Please select a mixer device" msgstr "Sélectionnez un périphérique de mixage (mixer)" #: volume.c:871 msgid "Available mixers" msgstr "Périphériques existants" #: volume.c:895 msgid "Id" msgstr "Id" #: volume.c:901 msgid "Mixer Name" msgstr "Nom du mixeur" #: volume.c:948 msgid "" "Gkrellm Volume Plugin\n" "\n" msgstr "" "Plugin GKrellm de Volume\n" "\n" #: volume.c:949 msgid "" "This plugin allows you to control your mixers with gkrellm\n" "\n" msgstr "" "Ce plugin vous permet de contrôler le mixage depuis gkrellm\n" "\n" #: volume.c:950 msgid "User Interface:\n" msgstr "Interface utilisateur:\n" #: volume.c:951 msgid "" "\tDragging the krells around or turning your mousewheel above a panel\n" "\twill change the volume of the device.\n" "\tMiddle mouse button will (un)mute the mixer\n" "\n" msgstr "" "\tDéplacer les afficheurs ou actionner la roulette de la souris\n" "\tau dessus d'un panneau modifie le volume du périphérique.\n" "\tLe bouton du milieu coupe ou restaure le son\n" "\n" #: volume.c:954 msgid " Configuration:\n" msgstr "Configuration:\n" #: volume.c:956 msgid "" "\tThe available mixers tab shows the detected mixers. The order of the\n" "\tmixers is the same as they will be in the main window\n" "\n" "\tEach mixer gets its own tab. You can adjust each device separately:\n" "\t * Enabled: will cause the device to show up in the main window.\n" "\t * Save volume: will cause the volume and balance to be saved on exit\n" "\t and reset on startup.\n" msgstr "" "\tLe panneau des périphériques existant liste les périphériques\n" "\tdétectés. L'ordre des périphériques est le même que celui qui\n" "\tsera utilisé dans la fenêtre principale.\n" "\n" "\tChaque périphérique dispose de son propre panneau. Vous pouvez\n" "\tajuster chaque ligne indépendamment:\n" "\t* Activé: La ligne apparaît dans la fenêtre principale.\n" "\t* Enregistrer le volume: active la sauvegarde du volume à\n" "\tl'extinction de gkrellm et la restauration au démarrage.\n" #: volume.c:965 msgid "" "\t * Balance: Gives you a panel below the device to control its balance\n" msgstr "" "\t* Balance: Affiche un panneau en dessous de la ligne pour controler la " "balance droite/gauche\n" #: volume.c:968 msgid "" "\t * Name: The 'official' name of the device.\n" "\t * Shown name: can be edited and is the name shown in the main window.\n" "\n" msgstr "" "\t* Nom: le nom 'officiel' de la ligne.\n" "\t* Nom affiché: Ce nom éditable est celui qui est affiché dans la fenêtre principale.\n" "\n" #: volume.c:971 msgid "Options:\n" msgstr "Options:\n" #: volume.c:972 msgid "\t* Mute all mixers at the same time: Mutes all devices on a middle\n" msgstr "\t* Couper toutes les lignes en même temps: coupe tous les périphériques\n" #: volume.c:973 msgid "" "\t mouse button click instead of only the one the slider belongs to.\n" "\t* Right-click command: The command to run when the right mouse\n" "\t button is clicked on the plugin\n" msgstr "" "\t sur un click de la souris avec le bouton du milieu au lieu du seul\n" "\t auquel le potentiomètre est associé.\n" "\t* Click droit: la commande a exécuter lorsque le bouton droit de la\n" "\t souris est pressé sur le panneau\n" #: volume.c:981 #, c-format msgid "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" msgstr "" "Volumeplugin %d.%d.%d\n" "Volume de plugin GKrellM\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net\n" "\n" "Released under the GNU Public Licence" #: volume.c:1001 msgid "Options" msgstr "Options" #: volume.c:1004 msgid "Mute all mixers at the same time" msgstr "Couper toutes les lignes en même temps" #: volume.c:1011 msgid "Right-click command: " msgstr "Click Droit:" #: volume.c:1019 msgid "Info" msgstr "Info" #: volume.c:1028 msgid "About" msgstr "A propos" gkrellm-volume-2.1.13/po/es.po0000644000175000017500000001222510111204177016717 0ustar sjoerdsjoerd00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2004-07-21 12:53+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: YoaR \n" "Language-Team: none \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #: volume.c:162 volume.c:361 volume.c:363 msgid "Centered" msgstr "Centrado" #: volume.c:164 msgid "Right" msgstr "Derecha" #: volume.c:164 msgid "Left" msgstr "Izquierda" #: volume.c:631 msgid "Enabled" msgstr "Activado" #: volume.c:639 msgid "Save volume" msgstr "Guardar volumen" #: volume.c:649 msgid "Balance" msgstr "Balance" #: volume.c:657 msgid "Name" msgstr "Nombre" #: volume.c:663 msgid "Shown Name" msgstr "Nombre mostrado" #: volume.c:751 volume.c:758 msgid "Error" msgstr "Error" #: volume.c:751 msgid "Id already in list" msgstr "Id ya en lista" #: volume.c:757 #, c-format msgid "Couldn't open %s or %s isn't a mixer device" msgstr "No se puede abrir %s o %s no es un dispositivo mezclador" #: volume.c:846 msgid "Please select a mixer device" msgstr "Seleccione un dispositivo mezclador" #: volume.c:893 msgid "Available mixers" msgstr "Mezcladores disponibles" #: volume.c:921 msgid "Id" msgstr "Id" #: volume.c:927 msgid "Mixer Name" msgstr "Nombre del mezclador" #: volume.c:974 msgid "" "Gkrellm Volume Plugin\n" "\n" msgstr "" "Plugin de volumen para Gkrellm\n" "\n" #: volume.c:975 msgid "" "This plugin allows you to control your mixers with gkrellm\n" "\n" msgstr "" "Este plugin te permite controlar tus mezcladores desde gkrellm\n" #: volume.c:976 msgid "User Interface:\n" msgstr "Interfaz de usuario:\n" #: volume.c:977 msgid "" "\tDragging the krells around or turning your mousewheel above a panel\n" "\twill change the volume of the device.\n" "\tMiddle mouse button will (un)mute the mixer\n" "\n" msgstr "" "\tMoviendo el indicador de los krells o usando la rueda del ratón sobre\n" "\tun panel hará cambiar el volumen del dispositivo.\n" "\tPulsar el botón central del ratón silenciará o restaurará el sonido\n" #: volume.c:980 msgid " Configuration:\n" msgstr " Configuración:\n" #: volume.c:982 msgid "" "\tThe available mixers tab shows the detected mixers. The order of the\n" "\tmixers is the same as they will be in the main window\n" "\n" "\tEach mixer gets its own tab. You can adjust each device separately:\n" "\t * Enabled: will cause the device to show up in the main window.\n" "\t * Save volume: will cause the volume and balance to be saved on exit\n" "\t and reset on startup.\n" msgstr "" "\tLa pestaña de mezcladores disponibles muestra los mezcladores detectados.\n" "\tEl orden de los mezcladores es el mismo que el que aparecerá en la pantalla\n" "\tprincipal\n" "\n" "\tCada mezclador tiene su propia pestaña. Puedes configurar cada dispositivo\n" "\tindividualmente:\n" "\t * Activado: mostrará el dispositivo en la pantalla principal.\n" "\t * Guardar volumen: guardará el volumen y el balance al cerrar el gkrellm\n" "\t y lo restaurará al iniciarse.\n" #: volume.c:991 msgid "" "\t * Balance: Gives you a panel below the device to control its balance\n" msgstr "" "\t * Balance: te proporciona un panel donde puedes controlar el balance\n" #: volume.c:994 msgid "" "\t * Name: The 'official' name of the device.\n" "\t * Shown name: can be edited and is the name shown in the main window.\n" "\n" msgstr "" "\t * Nombre: el nombre 'oficial' del dispositivo.\n" "\t * Nombre mostrado: es el nombre mostrado en la pantalla principal (puede ser editado).\n" "\n" #: volume.c:997 msgid "Options:\n" msgstr "Opciones:\n" #: volume.c:998 msgid "" "\t* Mute all mixers at the same time: Mutes all devices on a middle\n" "\t mouse button click instead of only the one the slider belongs to.\n" "\t* Right-click command: The command to run when the right mouse\n" "\t button is clicked on the plugin\n" msgstr "" "\t* Silenciar todos los mezcladores al mismo tiempo: silencia todos los\n" "\t mezcladores al pulsar el botón central del ratón, en lugar de silenciar\n" "\t sólo el mezclador sobre el que está el ratón.\n" "\t* Comando de botón derecho: comando a ejecutar cuando se pulsa el botón\n" "\t derecho del ratón sobre el panel del plugin.\n" #: volume.c:1007 #, c-format msgid "" "Volumeplugin %d.%d.%d\n" "GKrellM volume Plugin\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Released under the GNU Public Licence" msgstr "" "Volumeplugin %d.%d.%d\n" "Plugin de volumen para GKrellM\n" "\n" "Copyright (C) 2000 Sjoerd Simons\n" "sjoerd@luon.net\n" "http://gkrellm.luon.net \n" "\n" "Publicado bajo licencia GNU" #: volume.c:1024 msgid "Options" msgstr "Opciones" #: volume.c:1027 msgid "Mute all mixers at the same time" msgstr "Silenciar todos los mezcladores al mismo tiempo" #: volume.c:1034 msgid "Right-click command: " msgstr "Comando con click derecho: " #: volume.c:1044 msgid "Info" msgstr "Info" #: volume.c:1053 msgid "About" msgstr "Acerca de" gkrellm-volume-2.1.13/THEMING0000644000175000017500000000051710111204177016351 0ustar sjoerdsjoerd00000000000000Theming the volume plugin: Using the "volume" plugin keyword you can theme like you would all the other meters (see the theme documentation). The slider krells have the same behaviour as 'normal krells' Using "volume.level_slider" or "volume.balance_slider", you can theme the krells of the level and balance seperately gkrellm-volume-2.1.13/alsa_mixer.h0000644000175000017500000000043110111204177017623 0ustar sjoerdsjoerd00000000000000#ifndef VOLUME_ALSA_MIXER_H #define VOLUME_ALSA_MIXER_H #include #include "mixer.h" typedef struct { snd_mixer_t *handle; snd_mixer_selem_id_t **sids; int *ctltype; int changed_state; } alsa_mixer_t; mixer_ops_t *init_alsa_mixer(void); #endif gkrellm-volume-2.1.13/COPYRIGHT0000644000175000017500000004311010111204177016622 0ustar sjoerdsjoerd00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gkrellm-volume-2.1.13/win32_mixer.h0000644000175000017500000000235410111204177017653 0ustar sjoerdsjoerd00000000000000#if !defined(WIN32_MIXER_H) #define WIN32_MIXER_H /* win32 port by Bill Nalen bill@nalens.com */ /* GKrellM Volume plugin | Copyright (C) 1999-2000 Sjoerd Simons | | Author: Sjoerd Simons sjoerd@luon.net | | This program is free software which I release under the GNU General Public | License. You may redistribute and/or modify this program under the terms | of that license as published by the Free Software Foundation; either | version 2 of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | To get a copy of the GNU General Puplic License, write to the | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "mixer.h" #include #include #include typedef struct { HMIXER hMixer; DWORD controlID[3]; DWORD minimum[3]; DWORD maximum[3]; } win32_mixer_t; double rint(double arg); mixer_ops_t *init_win32_mixer(void); #endif