/* mixerwindow_delete */ void mixerwindow_delete(MixerWindow * mixer) { if(mixer->mixer != NULL) mixer_delete(mixer->mixer); if(mixer->about != NULL) gtk_widget_destroy(mixer->about); if(mixer->window != NULL) gtk_widget_destroy(mixer->window); object_delete(mixer); }
Mixer * mixer_new(GtkWidget * window, String const * device, MixerLayout layout) { Mixer * mixer; GtkSizeGroup * hgroup; GtkSizeGroup * vgroup; GtkWidget * scrolled = NULL; GtkWidget * label; GtkWidget * widget; GtkWidget * hvbox = NULL; GtkWidget * hbox; MixerControl * control; MixerControl2 * q; int i; #ifdef AUDIO_MIXER_DEVINFO mixer_devinfo_t md; mixer_devinfo_t md2; MixerClass * p; size_t u; GtkWidget * vbox2; char * name; #else int value; char const * labels[] = SOUND_DEVICE_LABELS; char const * names[] = SOUND_DEVICE_NAMES; #endif if((mixer = malloc(sizeof(*mixer))) == NULL) return NULL; if(device == NULL) device = MIXER_DEFAULT_DEVICE; mixer->device = string_new(device); mixer->fd = open(device, O_RDWR); mixer->window = window; mixer->properties = NULL; mixer->bold = NULL; #ifdef AUDIO_MIXER_DEVINFO mixer->classes = NULL; mixer->classes_cnt = 0; #endif mixer->controls = NULL; mixer->controls_cnt = 0; mixer->source = 0; if(mixer->device == NULL || mixer->fd < 0) { _mixer_error(NULL, device, 0); mixer_delete(mixer); return NULL; } hgroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); vgroup = gtk_size_group_new(GTK_SIZE_GROUP_VERTICAL); /* widgets */ mixer->bold = pango_font_description_new(); pango_font_description_set_weight(mixer->bold, PANGO_WEIGHT_BOLD); /* classes */ mixer->notebook = NULL; if(layout == ML_TABBED) mixer->notebook = gtk_notebook_new(); else { scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, (layout == ML_VERTICAL) ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER); hvbox = gtk_box_new((layout == ML_VERTICAL) ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, 4); gtk_container_set_border_width(GTK_CONTAINER(hvbox), 2); if(layout == ML_VERTICAL) gtk_box_set_homogeneous(GTK_BOX(hvbox), TRUE); _mixer_scrolled_window_add(scrolled, hvbox); } for(i = 0;; i++) { #ifdef AUDIO_MIXER_DEVINFO md.index = i; if(ioctl(mixer->fd, AUDIO_MIXER_DEVINFO, &md) < 0) break; if(md.type != AUDIO_MIXER_CLASS) continue; if((p = realloc(mixer->classes, sizeof(*p) * (mixer->classes_cnt + 1))) == NULL) { _mixer_error(NULL, "realloc", 1); mixer_delete(mixer); return NULL; } mixer->classes = p; p = &mixer->classes[mixer->classes_cnt++]; p->mixer_class = md.mixer_class; memcpy(&p->label, &md.label, sizeof(md.label)); p->hbox = NULL; p->page = -1; #else hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); if(mixer->notebook != NULL) { label = _new_frame_label(NULL, _("All"), NULL); gtk_widget_show_all(label); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW( scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); _mixer_scrolled_window_add(scrolled, hbox); gtk_notebook_append_page(GTK_NOTEBOOK(mixer->notebook), scrolled, label); } else gtk_box_pack_start(GTK_BOX(hvbox), hbox, FALSE, TRUE, 0); break; #endif } /* controls */ for(i = 0;; i++) { #ifdef AUDIO_MIXER_DEVINFO md.index = i; if(ioctl(mixer->fd, AUDIO_MIXER_DEVINFO, &md) < 0) break; if(md.type == AUDIO_MIXER_CLASS) continue; for(u = 0; u < mixer->classes_cnt; u++) if(mixer->classes[u].mixer_class == md.mixer_class) break; if(u == mixer->classes_cnt) continue; hbox = mixer->classes[u].hbox; control = NULL; switch(md.type) { case AUDIO_MIXER_ENUM: control = _new_enum(mixer, i, &md.un.e, md.label.name, _mixer_get_icon(md.label.name), md.label.name); break; case AUDIO_MIXER_SET: control = _new_set(mixer, i, &md.un.s, md.label.name, _mixer_get_icon(md.label.name), md.label.name); break; case AUDIO_MIXER_VALUE: control = _new_value(mixer, i, vgroup, md.label.name, _mixer_get_icon(md.label.name), md.label.name); break; } if(control == NULL) continue; if((q = realloc(mixer->controls, sizeof(*q) * (mixer->controls_cnt + 1))) == NULL) { mixercontrol_delete(control); /* FIXME report error */ continue; } mixer->controls = q; q = &mixer->controls[mixer->controls_cnt++]; q->index = md.index; q->type = md.type; q->control = control; widget = mixercontrol_get_widget(control); vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); gtk_box_pack_start(GTK_BOX(vbox2), widget, TRUE, TRUE, 0); gtk_size_group_add_widget(hgroup, widget); if(hbox == NULL) { p = &mixer->classes[u]; p->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); hbox = p->hbox; gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); if(mixer->notebook != NULL) { if((name = strdup(mixer->classes[u].label.name)) != NULL) name[0] = toupper( (unsigned char)name[0]); label = _new_frame_label(NULL, mixer->classes[u].label.name, name); free(name); gtk_widget_show_all(label); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); _mixer_scrolled_window_add(scrolled, p->hbox); p->page = gtk_notebook_append_page( GTK_NOTEBOOK(mixer->notebook), scrolled, label); } else if(hvbox != NULL) gtk_box_pack_start(GTK_BOX(hvbox), p->hbox, FALSE, TRUE, 0); } gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, TRUE, 0); /* add a mute button if relevant */ if(md.type != AUDIO_MIXER_VALUE) continue; md2.index = md.index + 1; if(ioctl(mixer->fd, AUDIO_MIXER_DEVINFO, &md2) < 0) break; if(md2.type == AUDIO_MIXER_CLASS) continue; for(u = 0; u < mixer->classes_cnt; u++) if(mixer->classes[u].mixer_class == md2.mixer_class) break; if(u == mixer->classes_cnt) continue; u = strlen(md.label.name); if(md2.type != AUDIO_MIXER_ENUM || strncmp(md.label.name, md2.label.name, u) != 0 || (u = strlen(md2.label.name)) < 6 || strcmp(&md2.label.name[u - 5], ".mute") != 0) continue; /* XXX may fail */ mixercontrol_set(control, "show-mute", TRUE, NULL); i++; #else if(i == SOUND_MIXER_NONE) break; if(ioctl(mixer->fd, MIXER_READ(i), &value) != 0) continue; if((q = realloc(mixer->controls, sizeof(*q) * (mixer->controls_cnt + 1))) == NULL) /* FIXME report error */ continue; mixer->controls = q; q = &mixer->controls[mixer->controls_cnt]; if((control = _new_value(mixer, i, vgroup, names[i], _mixer_get_icon(names[i]), labels[i])) == NULL) continue; q->index = i; q->type = 0; q->control = control; mixer->controls_cnt++; widget = mixercontrol_get_widget(control); gtk_size_group_add_widget(hgroup, widget); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); #endif } mixer->widget = (mixer->notebook != NULL) ? mixer->notebook : scrolled; #ifdef AUDIO_MIXER_DEVINFO mixer_show_class(mixer, AudioCoutputs); #endif gtk_widget_show_all(mixer->widget); mixer->source = g_timeout_add(500, _new_on_refresh, mixer); return mixer; }