summaryrefslogtreecommitdiff
path: root/voss_devctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'voss_devctl.c')
-rw-r--r--voss_devctl.c573
1 files changed, 0 insertions, 573 deletions
diff --git a/voss_devctl.c b/voss_devctl.c
deleted file mode 100644
index 1739b19..0000000
--- a/voss_devctl.c
+++ /dev/null
@@ -1,573 +0,0 @@
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-#include <sys/sysctl.h>
-
-#include <Xm/Xm.h>
-#include <Xm/Form.h>
-#include <Xm/Label.h>
-#include <Xm/ComboBox.h>
-#include <Xm/TextF.h>
-#include <Xm/List.h>
-#include <Xm/MessageB.h>
-#include <Xm/ToggleB.h>
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <string.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#include "virtual_oss.h"
-
-#define OSS_DEV "/dev/dsp0"
-#define VOSS_DEV "/dev/dsp.ctl"
-
-#define XM_ROW_HEIGHT 50
-#define XM_BG_COLOR 0xF0F0F0
-#define XM_MSGBUF_LEN 256
-
-#define OSS_DESCR_SIZE (OSS_DEVNODE_SIZE + OSS_LONGNAME_SIZE + 4)
-
-struct oss_dev {
- int devnum;
- char devnode[OSS_DEVNODE_SIZE];
- char descr[OSS_DESCR_SIZE];
- int caps;
-};
-
-struct oss_devlist {
- int len;
- int ct;
- struct oss_dev *devs;
-};
-
-/* global variables */
-static int oss_dsp_fd, voss_dsp_fd;
-
-struct oss_devlist devs_play, devs_rec;
-
-static struct oss_sysinfo si;
-static struct virtual_oss_system_info vsi;
-
-
-/* dynamic list functions */
-void oss_devlist_init(struct oss_devlist *list)
-{
- list->len = 10;
- list->ct = 0;
- list->devs = (struct oss_dev *)calloc(
- list->len, sizeof(struct oss_dev)
- );
-}
-
-void oss_devlist_add(struct oss_devlist *list, struct oss_audioinfo *ai)
-{
- assert((list->ct < list->len) && (list->devs != NULL));
-
- struct oss_dev *dev = &(list->devs[list->ct]);
-
- char descrbuf[OSS_DESCR_SIZE];
- snprintf(descrbuf, OSS_DESCR_SIZE, "%s: %s",
- ai->devnode, ai->name);
- dev->caps = ai->caps;
- dev->devnum = ai->dev;
- strncpy(dev->devnode, ai->devnode, OSS_DEVNODE_SIZE);
- strncpy(dev->descr, descrbuf, OSS_DESCR_SIZE);
-
- list->ct++;
-
- /* extend the list if needed */
- if ((list->len - list->ct) <= 1) {
- list->len += 10;
- list->devs = (struct oss_dev *)realloc(
- list->devs, list->len * sizeof(struct oss_dev)
- );
- }
-}
-
-void oss_devlist_free(struct oss_devlist *list)
-{
- if (list->devs != NULL) {
- free(list->devs);
- }
-}
-
-
-/* lookup functions */
-char *oss_devnode_from_descr(const char *descr, struct oss_devlist *list)
-{
- for (int i = 0; i < list->ct; i++) {
- if (strncmp(descr, list->devs[i].descr, OSS_DESCR_SIZE) == 0) {
- return list->devs[i].devnode;
- }
- }
- __builtin_unreachable();
- return NULL;
-}
-
-int oss_devnum_from_descr(const char *descr, struct oss_devlist *list)
-{
- for (int i = 0; i < list->ct; i++) {
- if (strncmp(descr, list->devs[i].descr, OSS_DESCR_SIZE) == 0) {
- return list->devs[i].devnum;
- }
- }
- __builtin_unreachable();
- return 0;
-}
-
-char *oss_descr_from_devnode(const char *devnode, struct oss_devlist *list)
-{
- for (int i = 0; i < list->ct; i++) {
- if (strncmp(devnode, list->devs[i].devnode, OSS_DEVNODE_SIZE) == 0) {
- return list->devs[i].descr;
- }
- }
- return NULL;
-}
-
-/* populate list of devices */
-void oss_enum_devs(int fd, int oss_numaudios)
-{
- devs_play.ct = devs_rec.ct = 0;
-
- for (int i = 0; i < oss_numaudios; i++) {
- struct oss_audioinfo ai = { .dev = i };
-
- if (ioctl(fd, SNDCTL_AUDIOINFO, &ai) < 0) {
- printf("OSS: could not get device %d info: %s\n",
- i, strerror(errno));
- continue;
- }
-
- if (!ai.enabled) {
- continue;
- }
-
- printf("%d: %s, %s\n", i, ai.name, ai.devnode);
-
- if (ai.caps & (PCM_CAP_OUTPUT | PCM_CAP_VIRTUAL)) {
- oss_devlist_add(&devs_play, &ai);
- }
- if (ai.caps & PCM_CAP_INPUT) {
- oss_devlist_add(&devs_rec, &ai);
- }
- }
-}
-
-/* query device capabilities */
-int oss_get_caps(const char *path)
-{
- int fd, dev_caps;
-
- if ((fd = open(path, O_WRONLY)) == -1) {
- printf("Failed to open device %s: %s\n",
- path, strerror(errno));
- return 0;
- }
-
- if (ioctl(fd, SNDCTL_DSP_GETCAPS, &dev_caps) == -1) {
- printf("Could not query capabilities for %s: %s\n",
- path, strerror(errno));
- close(fd);
- return 0;
- }
-
- close(fd);
- return dev_caps;
-}
-
-/* center an Xt widget on the current display */
-void xt_move_to_center(Widget widget)
-{
- Display *display = XtDisplay(widget);
- int screen_number = 0;
- for (int i = 0; i < ScreenCount(display); i++) {
- if (ScreenOfDisplay(display, i) == XtScreen(widget)) {
- screen_number = i;
- break;
- }
- }
-
- Position screen_width = DisplayWidth(display, screen_number);
- Position screen_height = DisplayHeight(display, screen_number);
-
- Dimension window_width, window_height;
- XtVaGetValues(widget, XmNwidth, &window_width, XmNheight, &window_height, NULL);
-
- Position pos_x = (screen_width - window_width) / 2;
- Position pos_y = (screen_height - window_height) / 2;
-
- XtVaSetValues(widget, XmNx, pos_x, XmNy, pos_y, NULL);
-}
-
-void xm_show_dialog(Widget caller, char *message)
-{
- Widget dialog;
-
- dialog = XmCreateInformationDialog(caller, "Message", NULL, 0);
-
- XmString xm_msg_str = XmStringCreateLocalized(message);
- XtVaSetValues(
- dialog, XmNmessageString, xm_msg_str,
- XmNbackground, XM_BG_COLOR,
- XmNwidth, 400, XmNheight, 200, NULL
- );
-
- XtVaSetValues(XtParent(dialog), XmNtitle, "Message", NULL);
-
- XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
- XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
-
- xt_move_to_center(dialog);
-
- XtManageChild(dialog);
-
- XmStringFree(xm_msg_str);
-}
-
-/* simply print out the current ComboBox selection */
-void xm_dev_select_callback(Widget caller,
- XtPointer client_data __attribute__ ((unused)),
- XtPointer call_data)
-{
- XmComboBoxCallbackStruct *cb = (XmComboBoxCallbackStruct *)call_data;
-
- const char *caller_name = XtName(caller);
- char *choice = (char *)XmStringUnparse(
- cb->item_or_text,
- XmFONTLIST_DEFAULT_TAG,
- XmCHARSET_TEXT, XmCHARSET_TEXT,
- NULL, 0, XmOUTPUT_ALL
- );
-
- char msg[XM_MSGBUF_LEN], options[VIRTUAL_OSS_OPTIONS_MAX];
- char flag;
- char *devnode_name;
-
- int devnum_sel = 0;
- size_t len = sizeof(int);
-
- if (strncmp(caller_name, "menu_rec", 8) == 0) {
- flag = 'R';
- devnode_name = oss_devnode_from_descr(choice, &devs_rec);
- } else {
- flag = 'P';
- devnode_name = oss_devnode_from_descr(choice, &devs_play);
- devnum_sel = oss_devnum_from_descr(choice, &devs_play);
- sysctlbyname("hw.snd.default_unit", NULL, &len, &devnum_sel, len);
- }
-
- if (cb->event != NULL) {
- snprintf(options, VIRTUAL_OSS_OPTIONS_MAX,
- "-%c %s", flag, devnode_name);
- if (ioctl(voss_dsp_fd, VIRTUAL_OSS_ADD_OPTIONS, &options) < 0) {
- snprintf(msg, XM_MSGBUF_LEN,
- "Cannot set Virtual OSS device: %s",
- strerror(errno));
- xm_show_dialog(caller, msg);
- }
- }
-
- XtFree(choice);
-}
-
-/* enable or disable the widget, toggle VOSS device to /dev/null */
-void xm_toggle_menu_callback(Widget caller,
- XtPointer client_data,
- XtPointer call_data)
-{
- Widget target_widget = (Widget)client_data;
-
- XmToggleButtonCallbackStruct *toggle_data = \
- (XmToggleButtonCallbackStruct *)call_data;
-
- const char *caller_name = XtName(caller);
-
- char flag = strncmp(caller_name, "toggle_rec", 10) ? 'P' : 'R';
-
- char msg[XM_MSGBUF_LEN], options[VIRTUAL_OSS_OPTIONS_MAX];
- char *devnode_name;
-
- if (toggle_data->set) {
- XtSetSensitive(target_widget, False);
- devnode_name = "/dev/null";
- } else {
- XtSetSensitive(target_widget, True);
-
- Widget menu_text_field = XtNameToWidget(target_widget, "*Text");
- char *menu_text = XmTextFieldGetString(menu_text_field);
-
- if (strncmp(caller_name, "menu_rec", 10) == 0) {
- devnode_name = oss_devnode_from_descr(menu_text, &devs_rec);
- } else {
- devnode_name = oss_devnode_from_descr(menu_text, &devs_play);
- }
-
- XtFree(menu_text);
- }
-
- /* pass the new device options to virtual OSS */
- snprintf(options, VIRTUAL_OSS_OPTIONS_MAX,
- "-%c %s", flag, devnode_name);
- if (ioctl(voss_dsp_fd, VIRTUAL_OSS_ADD_OPTIONS, &options) < 0) {
- snprintf(msg, XM_MSGBUF_LEN,
- "Cannot set Virtual OSS device: %s",
- strerror(errno));
- xm_show_dialog(caller, msg);
- }
-}
-
-void xm_gui_init(Widget toplevel)
-{
- Widget container;
- Widget label_rec, label_play;
- Widget menu_rec, menu_play;
- Widget toggle_rec, toggle_play;
- XmStringTable str_list;
- int i;
-
- XtVaSetValues(toplevel, XmNtitle, "Virtual OSS Device Selector", NULL);
-
- /* top-level container */
- container = XtVaCreateManagedWidget(
- "container", xmFormWidgetClass, toplevel,
- XmNmarginWidth, 20, XmNmarginHeight, 20,
- XmNbackground, XM_BG_COLOR, NULL
- );
-
- /* label for output selection */
- label_play = XtVaCreateManagedWidget(
- "label_play", xmLabelWidgetClass, container,
- XmNlabelString, XmStringCreateLocalized("Playback Device"),
- XmNheight, 50, XmNbackground, XM_BG_COLOR,
- XmNtopAttachment, XmATTACH_FORM,
- XmNleftAttachment, XmATTACH_FORM, NULL
- );
-
- /* populate list of output devices, if any found */
- str_list = (XmStringTable)XtMalloc(devs_play.ct * sizeof(XmString *));
- if (devs_play.ct) {
- for (i = 0; i < devs_play.ct; i++) {
- str_list[i] = XmStringCreateLocalized(devs_play.devs[i].descr);
- }
- }
-
-
- /* output device selection menu */
- menu_play = XtVaCreateManagedWidget(
- "menu_play", xmComboBoxWidgetClass, container,
- XmNcomboBoxType, XmDROP_DOWN_LIST,
- XmNheight, 50, XmNwidth, 600, XmNbackground, XM_BG_COLOR,
- XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, label_play,
- XmNleftAttachment, XmATTACH_FORM,
- XmNitemCount, devs_play.ct, XmNvisibleItemCount, devs_play.ct,
- XmNitems, str_list, NULL
- );
- XtAddCallback(
- menu_play, XmNselectionCallback,
- xm_dev_select_callback, NULL
- );
-
- /* output device toggle */
- toggle_play = XtVaCreateManagedWidget(
- "toggle_play", xmToggleButtonWidgetClass, container,
- XmNlabelString, XmStringCreateLocalized("Disabled"),
- XmNheight, 50, XmNbackground, XM_BG_COLOR,
- XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, label_play,
- XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, menu_play,
- XmNleftOffset, 10, NULL
- );
- XtAddCallback(
- toggle_play, XmNvalueChangedCallback,
- xm_toggle_menu_callback, (XtPointer)menu_play
- );
-
- /* combo box clean up */
- if (devs_play.ct) {
- for (i = 0; i < devs_play.ct; i++) {
- XmStringFree(str_list[i]);
- }
- } else {
- XtSetSensitive(menu_play, False);
- XtSetSensitive(toggle_play, False);
- }
- XtFree((XtPointer)str_list);
-
- /* label for input device section */
- label_rec = XtVaCreateManagedWidget(
- "label_rec", xmLabelWidgetClass, container,
- XmNlabelString, XmStringCreateLocalized("Recording Device"),
- XmNheight, 50, XmNbackground, XM_BG_COLOR,
- XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, menu_play,
- XmNtopOffset, 20,
- XmNleftAttachment, XmATTACH_FORM, NULL
- );
-
- /* populate list of input devices, if any found */
- str_list = (XmStringTable)XtMalloc(devs_rec.ct * sizeof(XmString *));
- if (devs_rec.ct) {
- for (i = 0; i < devs_rec.ct; i++) {
- str_list[i] = XmStringCreateLocalized(devs_rec.devs[i].descr);
- }
- }
-
- /* input device selection menu */
- menu_rec = XtVaCreateManagedWidget(
- "menu_rec", xmComboBoxWidgetClass, container,
- XmNcomboBoxType, XmDROP_DOWN_LIST,
- XmNheight, 50, XmNwidth, 600, XmNbackground, XM_BG_COLOR,
- XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, label_rec,
- XmNleftAttachment, XmATTACH_FORM,
- XmNitemCount, devs_rec.ct, XmNvisibleItemCount, devs_rec.ct,
- XmNitems, str_list, NULL
- );
- XtAddCallback(
- menu_rec, XmNselectionCallback,
- xm_dev_select_callback, NULL
- );
-
- /* input device toggle */
- toggle_rec = XtVaCreateManagedWidget(
- "toggle_rec", xmToggleButtonWidgetClass, container,
- XmNlabelString, XmStringCreateLocalized("Disabled"),
- XmNheight, 50, XmNbackground, XM_BG_COLOR,
- XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, label_rec,
- XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, menu_rec,
- XmNleftOffset, 10, NULL
- );
- XtAddCallback(
- toggle_rec, XmNvalueChangedCallback,
- xm_toggle_menu_callback, (XtPointer)menu_rec
- );
-
- /* combo box clean up */
- if (devs_rec.ct) {
- for (i = 0; i < devs_rec.ct; i++) {
- XmStringFree(str_list[i]);
- }
- } else {
- XtSetSensitive(menu_rec, False);
- XtSetSensitive(toggle_rec, False);
- }
- XtFree((XtPointer)str_list);
-
- /* pre-select the Virtual OSS playback device */
- if (strncmp("/dev/null", vsi.tx_device_name, 64) != 0) {
- if ((oss_get_caps(vsi.tx_device_name) & (PCM_CAP_OUTPUT | PCM_CAP_VIRTUAL))
- && (oss_descr_from_devnode(vsi.tx_device_name, &devs_play) != NULL)) {
- XmString opt_string = XmStringCreateLocalized(
- oss_descr_from_devnode(vsi.tx_device_name, &devs_play)
- );
- XmComboBoxSelectItem(menu_play, opt_string);
- XmStringFree(opt_string);
- } else {
- Widget menu_text_field = XtNameToWidget(menu_play, "*Text");
- char *menu_text = XmTextFieldGetString(menu_text_field);
-
- char options[VIRTUAL_OSS_OPTIONS_MAX];
- snprintf(options, VIRTUAL_OSS_OPTIONS_MAX,
- "-P %s", oss_devnode_from_descr(menu_text, &devs_play));
- ioctl(voss_dsp_fd, VIRTUAL_OSS_ADD_OPTIONS, &options);
-
- XtFree(menu_text);
- }
- } else {
- XmToggleButtonSetState(toggle_play, True, False);
- XtSetSensitive(menu_play, False);
- }
-
- /* pre-select the Virtual OSS recording device */
- if (strncmp("/dev/null", vsi.rx_device_name, 64) != 0) {
- if ((oss_get_caps(vsi.rx_device_name) & (PCM_CAP_INPUT | PCM_CAP_VIRTUAL))
- && (oss_descr_from_devnode(vsi.tx_device_name, &devs_rec) != NULL)) {
- XmString opt_string = XmStringCreateLocalized(
- oss_descr_from_devnode(vsi.rx_device_name, &devs_rec)
- );
- XmComboBoxSelectItem(menu_rec, opt_string);
- XmStringFree(opt_string);
- } else {
- Widget menu_text_field = XtNameToWidget(menu_rec, "*Text");
- char *menu_text = XmTextFieldGetString(menu_text_field);
-
- char options[VIRTUAL_OSS_OPTIONS_MAX];
- snprintf(options, VIRTUAL_OSS_OPTIONS_MAX, "-R %s",
- oss_devnode_from_descr(menu_text, &devs_rec));
- ioctl(voss_dsp_fd, VIRTUAL_OSS_ADD_OPTIONS, &options);
-
- XtFree(menu_text);
- }
- } else {
- XmToggleButtonSetState(toggle_rec, True, False);
- XtSetSensitive(menu_rec, False);
- }
-
- XtRealizeWidget(toplevel);
- xt_move_to_center(toplevel);
-}
-
-int main(int argc, char **argv)
-{
- XtAppContext app;
- Widget toplevel;
-
- /* initialize oss global information */
- if ((oss_dsp_fd = open(OSS_DEV, O_WRONLY)) == -1) {
- printf("Failed to open device %s: %s\n",
- OSS_DEV, strerror(errno));
- return -1;
- }
- if (ioctl(oss_dsp_fd, SNDCTL_SYSINFO, &si) < 0) {
- printf("Cannot get OSS system info: %s\n",
- strerror(errno));
- return -1;
- }
-
- /* the same for Virtual OSS */
- if ((voss_dsp_fd = open(VOSS_DEV, O_WRONLY)) == -1) {
- printf("Failed to open device %s: %s\n",
- VOSS_DEV, strerror(errno));
- return -1;
- }
- if (ioctl(voss_dsp_fd, VIRTUAL_OSS_GET_SYSTEM_INFO, &vsi) < 0) {
- printf("Cannot get Virtual OSS system info: %s\n",
- strerror(errno));
- return -1;
- }
-
- printf("OSS: Using %s version %s\n", si.product, si.version);
- printf("OSS: %d device(s) available\n", si.numaudios - 1);
-
- oss_devlist_init(&devs_play);
- oss_devlist_init(&devs_rec);
-
- oss_enum_devs(oss_dsp_fd, si.numaudios);
-
- XtSetLanguageProc(NULL, NULL, NULL);
-
- toplevel = XtVaOpenApplication(
- &app, "Virtual OSS Device Selector",
- NULL, 0, &argc, argv, NULL, sessionShellWidgetClass,
- XmNwidth, 800, XmNheight, 280, NULL
- );
-
- xm_gui_init(toplevel);
-
- xt_move_to_center(toplevel);
-
- XtAppMainLoop(app);
-
- oss_devlist_free(&devs_play);
- oss_devlist_free(&devs_rec);
-
- close(voss_dsp_fd);
- close(oss_dsp_fd);
-
- return 0;
-}