/* * xmmix - Motif(tm) Audio Mixer * * Copyright (C) 1994-1996 Ti Kan * E-mail: ti@amb.org * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef LINT static char *_widget_c_ident_ = "@(#)widget.c 3.3 96/07/14"; #endif #include "appenv.h" #include "widget.h" #include "mixer.h" #include "xmmix.xbm" extern appdata_t app_data; extern widgets_t widgets; extern int maxdevs; #define CTL_DISTANCE 48 #define PD_FILE_LOAD 0 #define PD_FILE_SAVE 1 #define PD_FILE_SEP 2 #define PD_FILE_EXIT 3 STATIC btinfo_t file_btinfo[] = { { NULL, "Load...", "loadButton", "l", "L" }, { NULL, "Save...", "saveButton", "s", "S" }, { NULL, NULL, "fileSeparator", NULL, NULL }, { NULL, "Exit", "exitButton", "x", "x" }, { NULL, NULL, NULL, NULL, NULL }, }; #define PD_OPTS_RESET 0 STATIC btinfo_t options_btinfo[] = { { NULL, "Reset", "resetButton", "r", "R" }, { NULL, NULL, NULL, NULL, NULL }, }; #define PD_HELP_MANPG 0 #define PD_HELP_ABOUT 1 STATIC btinfo_t help_btinfo[] = { { NULL, "Man page...", "manPageButton", "m", "M" }, { NULL, "About...", "aboutButton", "a", "A" }, { NULL, NULL, NULL, NULL, NULL }, }; STATIC pdinfo_t file_pd = { NULL, "File", "file", "f", "F", file_btinfo }; STATIC pdinfo_t opts_pd = { NULL, "Options", "options", "o", "O", options_btinfo }; STATIC pdinfo_t help_pd = { NULL, "Help", "help", "h", "H", help_btinfo }; STATIC slinfo_t slinfo[] = { { /* 0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Master", "master", CTL_OUTPUT, 17, TRUE, FALSE }, { /* 1 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Bass", "bass", CTL_MISC, 10, TRUE, FALSE }, { /* 2 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Treble", "treble", CTL_MISC, 11, TRUE, FALSE }, { /* 3 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Synth", "synth", CTL_INPUT, 1, TRUE, TRUE }, { /* 4 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "PCM", "pcm", CTL_INPUT, 2, TRUE, TRUE }, { /* 5 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Speaker", "speaker", CTL_OUTPUT, 16, TRUE, FALSE }, { /* 6 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Line", "line", CTL_INPUT, 4, TRUE, TRUE }, { /* 7 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Mic", "mic", CTL_INPUT, 8, TRUE, TRUE }, { /* 8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "CD", "cd", CTL_INPUT, 9, TRUE, TRUE }, { /* 9 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Rec Mon", "recmon", CTL_OUTPUT, 12, TRUE, FALSE }, { /* 10 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Alt PCM", "altpcm", CTL_INPUT, 3, TRUE, TRUE }, { /* 11 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Rec Out", "recout", CTL_OUTPUT, 13, TRUE, FALSE }, { /* 12 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "In Gain", "igain", CTL_MISC, 14, TRUE, FALSE }, { /* 13 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Out Gain", "ogain", CTL_MISC, 15, TRUE, FALSE }, { /* 14 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Line-1", "line1", CTL_INPUT, 5, TRUE, TRUE }, { /* 15 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Line-2", "line2", CTL_INPUT, 6, TRUE, TRUE }, { /* 16 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Line-3", "line3", CTL_INPUT, 7, TRUE, TRUE }, { /* 17 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 18 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 19 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 20 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 21 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 22 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 23 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 24 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 25 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 26 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 27 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 28 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 29 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 30 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE }, { /* 31 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, FALSE, FALSE } }; STATIC XmString xs_lock, xs_rec, xs_left, xs_right; STATIC Atom delw; /*********************** * internal routines * ***********************/ /* * Widget-related functions */ /* * create_pdmnu * Create a pulldown menu * * Args: * parent - The parent widget * pd - The pulldown menu info structure * * Return: * The menu widget */ STATIC Widget create_pdmnu(Widget parent, pdinfo_t *pd) { int i, n; Arg arg[10]; XmString xs; XmString xs_acc; char wname[STR_BUF_SZ]; Widget ret_widget; /* Create File pulldown menu */ sprintf(wname, "%sMenu", pd->name); ret_widget = XmCreatePulldownMenu(parent, wname, NULL, 0); for (i = 0; pd->btip[i].name != NULL; i++) { n = 0; if (pd->btip[i].label == NULL) { /* Separator */ pd->btip[i].widget = XmCreateSeparator( ret_widget, pd->btip[i].name, NULL, 0 ); XtManageChild(pd->btip[i].widget); } else { /* Button */ if (pd->btip[i].label != NULL) { xs = XmStringCreateSimple(pd->btip[i].label); XtSetArg(arg[n], XmNlabelString, xs); n++; } if (pd->btip[i].acc != NULL) { xs_acc = XmStringCreateSimple(pd->btip[i].acc); XtSetArg(arg[n], XmNaccelerator, xs_acc); n++; } if (pd->btip[i].mne != NULL) { XtSetArg(arg[n], XmNmnemonic, XStringToKeysym(pd->btip[i].mne)); n++; } pd->btip[i].widget = XmCreatePushButton( ret_widget, pd->btip[i].name, arg, n ); XtManageChild(pd->btip[i].widget); if (pd->btip[i].label != NULL) XmStringFree(xs); if (pd->btip[i].acc != NULL) XmStringFree(xs_acc); } } /* Create cascade button as menu activator */ sprintf(wname, "%sButton", pd->name); n = 0; if (pd->label != NULL) { xs = XmStringCreateSimple(pd->label); XtSetArg(arg[n], XmNlabelString, xs); n++; } if (pd->acc != NULL) { xs_acc = XmStringCreateSimple(pd->acc); XtSetArg(arg[n], XmNaccelerator, xs_acc); n++; } if (pd->mne != NULL) { XtSetArg(arg[n], XmNmnemonic, XStringToKeysym(pd->mne)); n++; } XtSetArg(arg[n], XmNsubMenuId, ret_widget); n++; pd->widget = XmCreateCascadeButton(parent, wname, arg, n); XtManageChild(pd->widget); if (pd->label != NULL) XmStringFree(xs); if (pd->acc != NULL) XmStringFree(xs_acc); return (ret_widget); } /* * create_vert_controls * Create a group of mixer controls including the vertical slider * and associated toggle buttons and labels. * * Args: * m - Pointer to the main widgets structure * dev - The mixer control device index * y1 - The top reference position (percent) * y2 - The bottom reference position (percent) * pos - The display position number * tot - Total number of controls to be displayed * * Return: * Nothing */ STATIC void create_vert_controls(widgets_t *m, int dev, int y1, int y2, int pos, int tot) { int x, n; Arg arg[20]; char wname[STR_BUF_SZ]; XmString xs; x = CTL_DISTANCE * pos; /* Right slider */ sprintf(wname, "%sRightScale", slinfo[dev].name); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNleftOffset, x); n++; XtSetArg(arg[n], XmNtopPosition, y1); n++; XtSetArg(arg[n], XmNbottomPosition, y2); n++; XtSetArg(arg[n], XmNshowValue, False); n++; XtSetArg(arg[n], XmNorientation, XmVERTICAL); n++; XtSetArg(arg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++; XtSetArg(arg[n], XmNminimum, 0); n++; XtSetArg(arg[n], XmNmaximum, 100); n++; XtSetArg(arg[n], XmNhighlightOnEnter, True); n++; slinfo[dev].widget_r = XmCreateScale(m->form, wname, arg, n); XtManageChild(slinfo[dev].widget_r); /* Left slider */ sprintf(wname, "%sLeftScale", slinfo[dev].name); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++; XtSetArg(arg[n], XmNtopPosition, y1); n++; XtSetArg(arg[n], XmNbottomPosition, y2); n++; XtSetArg(arg[n], XmNshowValue, False); n++; XtSetArg(arg[n], XmNorientation, XmVERTICAL); n++; XtSetArg(arg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++; XtSetArg(arg[n], XmNminimum, 0); n++; XtSetArg(arg[n], XmNmaximum, 100); n++; XtSetArg(arg[n], XmNhighlightOnEnter, True); n++; slinfo[dev].widget_l = XmCreateScale(m->form, wname, arg, n); XtManageChild(slinfo[dev].widget_l); /* Left label */ sprintf(wname, "%sLeftLabel", slinfo[dev].name); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++; XtSetArg(arg[n], XmNtopPosition, y1 - 4); n++; XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_l); n++; XtSetArg(arg[n], XmNlabelString, xs_left); n++; slinfo[dev].widget_lbl_l = XmCreateLabel( m->form, wname, arg, n ); XtManageChild(slinfo[dev].widget_lbl_l); /* Right label */ sprintf(wname, "%sRightLabel", slinfo[dev].name); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++; XtSetArg(arg[n], XmNtopPosition, y1 - 4); n++; XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_r); n++; XtSetArg(arg[n], XmNlabelString, xs_right); n++; slinfo[dev].widget_lbl_r = XmCreateLabel( m->form, wname, arg, n ); XtManageChild(slinfo[dev].widget_lbl_r); /* Slider label */ sprintf(wname, "%sLabel", slinfo[dev].name); xs = XmStringCreateSimple(slinfo[dev].label); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_lbl_l); n++; XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_lbl_r); n++; XtSetArg(arg[n], XmNleftOffset, -4); n++; XtSetArg(arg[n], XmNrightOffset, -4); n++; XtSetArg(arg[n], XmNtopWidget, m->menu_bar); n++; XtSetArg(arg[n], XmNtopOffset, 3); n++; XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_lbl_l); n++; XtSetArg(arg[n], XmNlabelString, xs); n++; slinfo[dev].widget_lbl = XmCreateLabel( m->form, slinfo[dev].name, arg, n ); XtManageChild(slinfo[dev].widget_lbl); XmStringFree(xs); /* Lock button */ sprintf(wname, "%sLockButton", slinfo[dev].name); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++; XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++; XtSetArg(arg[n], XmNtopWidget, slinfo[dev].widget_l); n++; XtSetArg(arg[n], XmNlabelString, xs_lock); n++; slinfo[dev].widget_lock_btn = XmCreateToggleButton( m->form, wname, arg, n ); XtManageChild(slinfo[dev].widget_lock_btn); /* Record selector buttons */ if (slinfo[dev].recsupp) { sprintf(wname, "%sRecButton", slinfo[dev].name); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++; XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++; XtSetArg(arg[n], XmNtopWidget, slinfo[dev].widget_lock_btn); n++; XtSetArg(arg[n], XmNlabelString, xs_rec); n++; slinfo[dev].widget_rec_btn = XmCreateToggleButton( m->form, wname, arg, n ); XtManageChild(slinfo[dev].widget_rec_btn); } } /* * bm_to_px * Convert a bitmap into a pixmap. * * Args: * w - A widget the pixmap should be associated with * bits - Pointer to the raw bitmap data * width, height - The resultant pixmap dimensions * * Return: * The pixmap ID, or NULL if failure. */ Pixmap bm_to_px(Widget w, void *bits, int width, int height, int depth) { Display *display = XtDisplay(w); Window window = XtWindow(w); int screen = DefaultScreen(display); Pixmap ret_pixmap; Pixel fg, bg; /* Allocate colors for pixmap if on color screen */ if (DisplayCells(display, screen) > 2 && depth > 1) { XtVaGetValues(w, XmNforeground, &fg, XmNbackground, &bg, NULL ); } else { fg = BlackPixel(display, screen); bg = WhitePixel(display, screen); } ret_pixmap = XCreatePixmapFromBitmapData( display, window, (char *) bits, width, height, fg, bg, depth ); if (ret_pixmap == (Pixmap) NULL) return ((Pixmap) NULL); return (ret_pixmap); } /*********************** * public routines * ***********************/ /* * widget_init * Initialize widget-related structures. * * Args: * m - Pointer to the main widgets structure * * Return: * Nothing */ void widget_init(widgets_t *m) { /* Initialize structures */ m->sl = slinfo; m->file_pd = &file_pd; m->opts_pd = &opts_pd; m->help_pd = &help_pd; } /* * create_widgets * Top-level function to create all widgets. * * Args: * m - Pointer to the main widgets structure * * Return: * Nothing */ void create_widgets(widgets_t *m) { int i, j, k, n, ctls, form_width; Arg arg[20]; char wname[STR_BUF_SZ], str[STR_BUF_SZ]; XmString xs; /* Count the number of slider controls we will display */ for (i = 0, ctls = 0; i < maxdevs; i++) { if (slinfo[i].supp) ctls++; } /* Create compound strings that will be used repetitively */ xs_left = XmStringCreateSimple("L"); xs_right = XmStringCreateSimple("R"); xs_lock = XmStringCreateSimple("lock"); xs_rec = XmStringCreateSimple("rec"); /* Create form widget as container */ if ((form_width = (ctls + 1) * CTL_DISTANCE) < 300) form_width = 300; n = 0; XtSetArg(arg[n], XmNwidth, form_width); n++; XtSetArg(arg[n], XmNheight, 320); n++; XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++; m->form = XmCreateForm(m->toplevel, "mainForm", arg, n); XtManageChild(m->form); /* Create logo label */ n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNleftOffset, (form_width/2) - (xmmix_width/2)); n++; XtSetArg(arg[n], XmNtopPosition, 88); n++; XtSetArg(arg[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(arg[n], XmNmarginHeight, 0); n++; XtSetArg(arg[n], XmNmarginWidth, 0); n++; XtSetArg(arg[n], XmNhighlightThickness, 0); n++; XtSetArg(arg[n], XmNwidth, xmmix_width); n++; XtSetArg(arg[n], XmNheight, xmmix_height); n++; m->logolbl = XmCreateLabel(m->form, "logoLabel", arg, n); XtManageChild(m->logolbl); /* Create menu bar */ n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; m->menu_bar = XmCreateMenuBar(m->form, "menuBar", arg, n); XtManageChild(m->menu_bar); /* Create File pulldown menu */ m->file_mnu = create_pdmnu(m->menu_bar, &file_pd); /* Create Options pulldown menu */ m->options_mnu = create_pdmnu(m->menu_bar, &opts_pd); /* Create Help pulldown menu */ m->help_mnu = create_pdmnu(m->menu_bar, &help_pd); XtVaSetValues(m->menu_bar, XmNmenuHelpWidget, help_pd.widget, NULL ); /* Create all sliders and associated labels and buttons */ for (j = 1, k = 0; j <= MAXDEVS; j++) { for (i = 0; i < maxdevs; i++) { if (j == slinfo[i].order && slinfo[i].supp) { create_vert_controls(m, i, 22, 70, ++k, ctls); } } } /* Horizontal separator */ n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNtopPosition, 84); n++; XtSetArg(arg[n], XmNleftOffset, 1); n++; XtSetArg(arg[n], XmNrightOffset, 1); n++; XtSetArg(arg[n], XmNorientation, XmHORIZONTAL); n++; m->hsep = XmCreateSeparator(m->form, "horizontalSeparator", arg, n); XtManageChild(m->hsep); /* * Flat button */ if (slinfo[SOUND_MIXER_BASS].supp || slinfo[SOUND_MIXER_TREBLE].supp) { xs = XmStringCreateSimple("Flat"); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; if (slinfo[SOUND_MIXER_BASS].supp) { XtSetArg(arg[n], XmNleftWidget, m->sl[SOUND_MIXER_BASS].widget_l); n++; XtSetArg(arg[n], XmNtopWidget, m->sl[SOUND_MIXER_BASS].widget_lock_btn); n++; } else { XtSetArg(arg[n], XmNleftWidget, m->sl[SOUND_MIXER_TREBLE].widget_l); n++; XtSetArg(arg[n], XmNtopWidget, m->sl[SOUND_MIXER_TREBLE].widget_lock_btn); n++; } if (slinfo[SOUND_MIXER_TREBLE].supp) { XtSetArg(arg[n], XmNrightWidget, m->sl[SOUND_MIXER_TREBLE].widget_r); n++; XtSetArg(arg[n], XmNtopWidget, m->sl[SOUND_MIXER_TREBLE].widget_lock_btn); n++; } else { XtSetArg(arg[n], XmNrightWidget, m->sl[SOUND_MIXER_BASS].widget_r); n++; XtSetArg(arg[n], XmNtopWidget, m->sl[SOUND_MIXER_BASS].widget_lock_btn); n++; } XtSetArg(arg[n], XmNlabelString, xs); n++; m->flat_btn = XmCreatePushButton(m->form, "flatButton", arg, n); XtManageChild(m->flat_btn); XmStringFree(xs); } /* * Mute button */ if (m->mute_supp) { xs = XmStringCreateSimple("Mute"); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNleftOffset, form_width - 100); n++; XtSetArg(arg[n], XmNtopPosition, 87); n++; XtSetArg(arg[n], XmNbottomPosition, 92); n++; XtSetArg(arg[n], XmNwidth, 66); n++; XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(arg[n], XmNlabelString, xs); n++; m->mute_btn = XmCreateToggleButton( m->form, "muteButton", arg, n ); XtManageChild(m->mute_btn); XmStringFree(xs); } /* * Loudness button */ if (m->loud_supp) { xs = XmStringCreateSimple("Loudness"); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNleftOffset, form_width - 100); n++; XtSetArg(arg[n], XmNtopPosition, 92); n++; XtSetArg(arg[n], XmNbottomPosition, 97); n++; XtSetArg(arg[n], XmNwidth, 66); n++; XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(arg[n], XmNlabelString, xs); n++; m->loud_btn = XmCreateToggleButton( m->form, "loudnessButton", arg, n ); XtManageChild(m->loud_btn); XmStringFree(xs); } /* * Enhance option menu */ if (m->enh_supp) { m->enh_mnu = XmCreatePulldownMenu( m->form, "enhancePulldownMenu", NULL, 0 ); for (i = 0; i < NENHANCE; i++) { sprintf(wname, "enhanceButton%d", i); sprintf(str, "%d", i); xs = XmStringCreateSimple(str); n = 0; XtSetArg(arg[n], XmNlabelString, xs); n++; m->enh_btn[i] = XmCreatePushButton( m->enh_mnu, wname, arg, n ); XtManageChild(m->enh_btn[i]); XmStringFree(xs); } xs = XmStringCreateSimple("Enhance"); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNleftOffset, 28); n++; XtSetArg(arg[n], XmNtopPosition, 88); n++; XtSetArg(arg[n], XmNsubMenuId, m->enh_mnu); n++; m->enh_opt = XmCreateOptionMenu( m->form, "enhanceOptionMenu", arg, n ); XtVaSetValues( XmOptionLabelGadget(m->enh_opt), XmNlabelString, xs, NULL ); XtManageChild(m->enh_opt); XmStringFree(xs); } /* * File selection box form */ n = 0; XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++; XtSetArg(arg[n], XmNautoUnmanage, False); n++; XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++; XtSetArg(arg[n], XmNwidth, 330); n++; XtSetArg(arg[n], XmNheight, 370); n++; m->fsform = XmCreateFormDialog( m->toplevel, "fileSelectionForm", arg, n ); /* * File selection box */ xs = XmStringCreateSimple("*.mxr"); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNmustMatch, False); n++; XtSetArg(arg[n], XmNpattern, xs); n++; m->fsbox = XmCreateFileSelectionBox( m->fsform, "fileSelectionBox", arg, n ); XtUnmanageChild( XmFileSelectionBoxGetChild(m->fsbox, XmDIALOG_HELP_BUTTON) ); XtManageChild(m->fsbox); XmStringFree(xs); XmStringFree(xs_left); XmStringFree(xs_right); XmStringFree(xs_lock); XmStringFree(xs_rec); /* * Man page window widgets */ /* Create form widget as container */ xs = XmStringCreateSimple("Xmmix Help"); n = 0; XtSetArg(arg[n], XmNdialogTitle, xs); n++; XtSetArg(arg[n], XmNautoUnmanage, True); n++; XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++; XtSetArg(arg[n], XmNwidth, 460); n++; XtSetArg(arg[n], XmNheight, 340); n++; m->helpform = XmCreateFormDialog(m->form, "helpForm", arg, n); XmStringFree(xs); /* Create text widget as help text viewer */ n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNleftPosition, 2); n++; XtSetArg(arg[n], XmNrightPosition, 98); n++; XtSetArg(arg[n], XmNtopPosition, 4); n++; XtSetArg(arg[n], XmNbottomPosition, 81); n++; XtSetArg(arg[n], XmNeditable, False); n++; XtSetArg(arg[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(arg[n], XmNcursorPositionVisible, False); n++; XtSetArg(arg[n], XmNcursorPosition, 0); n++; m->helptxt = XmCreateScrolledText(m->helpform, "helpText", arg, n); XtManageChild(m->helptxt); /* Create separator bar widget */ n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNleftOffset, 2); n++; XtSetArg(arg[n], XmNrightOffset, 2); n++; XtSetArg(arg[n], XmNtopPosition, 84); n++; m->helpsep = XmCreateSeparator(m->helpform, "helpSeparator", arg, n); XtManageChild(m->helpsep); /* Create pushbutton widget as OK button */ xs = XmStringCreateSimple("OK"); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(arg[n], XmNleftPosition, 44); n++; XtSetArg(arg[n], XmNrightPosition, 56); n++; XtSetArg(arg[n], XmNtopPosition, 89); n++; XtSetArg(arg[n], XmNlabelString, xs); n++; m->helpok_btn = XmCreatePushButton( m->helpform, "helpOkButton", arg, n ); XtManageChild(m->helpok_btn); XmStringFree(xs); /* * Info dialog widget for the About popup */ xs = XmStringCreateSimple("About"); n = 0; XtSetArg(arg[n], XmNdialogTitle, xs); n++; XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_MODELESS); n++; m->about = XmCreateInformationDialog( m->toplevel, "aboutDialog", arg, n ); XtUnmanageChild( XmMessageBoxGetChild(m->about, XmDIALOG_HELP_BUTTON) ); XtUnmanageChild( XmMessageBoxGetChild(m->about, XmDIALOG_CANCEL_BUTTON) ); XmStringFree(xs); /* * Info dialog widget for warning popups */ xs = XmStringCreateSimple("Warning"); n = 0; XtSetArg(arg[n], XmNdialogTitle, xs); n++; XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++; m->warning = XmCreateWarningDialog( m->toplevel, "warningDialog", arg, n ); XtUnmanageChild( XmMessageBoxGetChild(m->warning, XmDIALOG_HELP_BUTTON) ); XtUnmanageChild( XmMessageBoxGetChild(m->warning, XmDIALOG_CANCEL_BUTTON) ); XmStringFree(xs); } /* * post_realize_config * Top-level function to perform set-up and initialization tasks * after realizing all widgets. * * Args: * m - Pointer to the main widgets structure * * Return: * Nothing */ void post_realize_config(widgets_t *m) { int i, n; Display *display = XtDisplay(m->toplevel); Pixmap px; char title[STR_BUF_SZ], *p; /* Set main window title bar string */ if (app_data.demo) strcpy(title, "Motif Audio Mixer (Demo)"); else { n = 0; if ((i = strlen(app_data.device)) > 0) { /* Find mixer device number */ p = app_data.device + i; while (p > app_data.device) { if (!isdigit(*(p - 1))) break; p--; } if (isdigit(*p)) n = atoi(p); } sprintf(title, "Motif Audio Mixer %d", n); } XStoreName(display, XtWindow(m->toplevel), title); /* * Create logo pixmap */ px = bm_to_px(m->logolbl, xmmix_bits, xmmix_width, xmmix_height, 1); XtVaSetValues(m->toplevel, XmNiconPixmap, px, NULL); px = bm_to_px(m->logolbl, xmmix_bits, xmmix_width, xmmix_height, DefaultDepth(display, DefaultScreen(display))); XtVaSetValues(m->logolbl, XmNlabelPixmap, px, NULL); XtVaSetValues(m->about, XmNsymbolPixmap, px, NULL); /* Get WM_DELETE_WINDOW atom */ delw = XmInternAtom(display, "WM_DELETE_WINDOW", False); } /* * register_callbacks * Top-level function to register all callback routines. * * Args: * m - Pointer to the main widgets structure * * Return: * Nothing */ void register_callbacks(widgets_t *m) { int i; /* * Main window callbacks */ /* Callbacks for each control group */ for (i = 0; i < maxdevs; i++) { if (!slinfo[i].supp) continue; /* Left Slider callbacks */ XtAddCallback(slinfo[i].widget_l, XmNvalueChangedCallback, (XtCallbackProc) mx_slider_l, (XtPointer) i ); XtAddCallback(slinfo[i].widget_l, XmNdragCallback, (XtCallbackProc) mx_slider_l, (XtPointer) i ); /* Right Slider callbacks */ XtAddCallback(slinfo[i].widget_r, XmNvalueChangedCallback, (XtCallbackProc) mx_slider_r, (XtPointer) i ); XtAddCallback(slinfo[i].widget_r, XmNdragCallback, (XtCallbackProc) mx_slider_r, (XtPointer) i ); /* Lock button callback */ XtAddCallback(slinfo[i].widget_lock_btn, XmNvalueChangedCallback, (XtCallbackProc) mx_lock_btn, (XtPointer) i ); /* Rec button callback */ if (slinfo[i].recsupp) { XtAddCallback(slinfo[i].widget_rec_btn, XmNvalueChangedCallback, (XtCallbackProc) mx_rec_btn, (XtPointer) i ); } } /* Flat button callback */ if (slinfo[SOUND_MIXER_BASS].supp || slinfo[SOUND_MIXER_TREBLE].supp) { XtAddCallback(m->flat_btn, XmNactivateCallback, (XtCallbackProc) mx_flat_btn, NULL ); } /* Mute button callback */ if (m->mute_supp) { XtAddCallback(m->mute_btn, XmNvalueChangedCallback, (XtCallbackProc) mx_mute_btn, NULL ); } /* Loudness button callback */ if (m->loud_supp) { XtAddCallback(m->loud_btn, XmNvalueChangedCallback, (XtCallbackProc) mx_loud_btn, NULL ); } /* Stereo enhance button callbacks */ if (m->enh_supp) { for (i = 0; i < NENHANCE; i++) { XtAddCallback(m->enh_btn[i], XmNactivateCallback, (XtCallbackProc) mx_enhance_btn, (XtPointer) i ); } } /* Load button callback */ XtAddCallback(file_pd.btip[PD_FILE_LOAD].widget, XmNactivateCallback, (XtCallbackProc) mx_load, NULL ); /* Save button callback */ XtAddCallback(file_pd.btip[PD_FILE_SAVE].widget, XmNactivateCallback, (XtCallbackProc) mx_save, NULL ); /* Exit button callback */ XtAddCallback(file_pd.btip[PD_FILE_EXIT].widget, XmNactivateCallback, (XtCallbackProc) mx_exit, NULL ); /* Reset button callback */ XtAddCallback(opts_pd.btip[PD_OPTS_RESET].widget, XmNactivateCallback, (XtCallbackProc) mx_reset, NULL ); /* Man Page button callback */ XtAddCallback(help_pd.btip[PD_HELP_MANPG].widget, XmNactivateCallback, (XtCallbackProc) mx_manpg, NULL ); /* About button callback */ XtAddCallback(help_pd.btip[PD_HELP_ABOUT].widget, XmNactivateCallback, (XtCallbackProc) mx_about, NULL ); /* * File Selection Box callbacks */ /* OK button callback */ XtAddCallback(m->fsbox, XmNokCallback, (XtCallbackProc) mx_fsok_btn, NULL ); /* Cancel button callback */ XtAddCallback(m->fsbox, XmNcancelCallback, (XtCallbackProc) mx_fscancel_btn, NULL ); /* * Focus change callback */ XtAddCallback(m->form, XmNfocusCallback, (XtCallbackProc) mx_focuschg, (XtPointer) m->form ); /* * Install WM_DELETE_WINDOW handler */ XmAddWMProtocolCallback( m->toplevel, delw, (XtCallbackProc) mx_exit, (XtPointer) NULL ); }