Logo Search packages:      
Sourcecode: yiff version File versions  Download package

yc.c

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>

#include <gtk/gtk.h>

#include "../include/Y2/Y.h"
#include "../include/Y2/Ylib.h"

#include "guiutils.h"
#include "fb.h"
#include "pstepper.h"

#include "yc.h"
#include "ycmessages.h"

#include "config.h"

#include "images/icon_yiff_48x48.xpm"
#include "images/icon_add_20x20.xpm"
#include "images/icon_redo_20x20.xpm"
#include "images/icon_remove_20x20.xpm"


static void YCCreatePageWelcome(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
);
static void YCCreatePageLocations(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
);
static void YCCreatePageYModes(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
);
static void YCCreatePageTimings(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
);
static void YCCreatePageMIDI(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
);
static void YCCreatePageYSoundPaths(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
);
static void YCCreatePageConferm(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
);


int YCCreate(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps
);
void YCYModesListDeleteAll(yc_struct *yc);
void YCYSoundPathsListDeleteAll(yc_struct *yc);
void YCMap(yc_struct *yc);
void YCUnmap(yc_struct *yc);
void YCDestroy(yc_struct *yc);


#define YC_BTN_WIDTH          (100 + (2 * 3))
#define YC_BTN_HEIGHT         (30 + (2 * 3))


/*
 *    Creates the welcome nariative strip and page on the yc.
 *
 *    The welcome page contains greeting text and a quick list of
 *    prerequisits the user must have.
 *
 *    This function should be called from YCCreate(), all inputs
 *    assumed valid.
 */
static void YCCreatePageWelcome(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
)
{
      GtkWidget *w, *nariative, *page, *parent, *parent2, *pixmap;
      GtkWidget *parent3;
      GdkPixmap *pixmap_gdk;
      GdkBitmap *mask;
      gint width, height;


      /* Create parents for nariative strip and page. */
      w = gtk_table_new(2, 1, FALSE);
      nariative = w;

      w = gtk_vbox_new(FALSE, 0);
      page = w;

      /* Append to ps. */
      PStepperAppend(
          yc->ps,
          page, nariative,
          (gpointer)yc,
          YCPSPageChangeCB
      );


      /* Begin creating nariative strip. */
      parent = nariative;
      gtk_widget_realize(parent);
      gtk_signal_connect(
          GTK_OBJECT(parent), "expose_event",
          GTK_SIGNAL_FUNC(YCWidgetExposeCB), (gpointer)yc
      );

      /* Nariative text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          0, 1,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_WELCOME1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Nariative text 2. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          1, 2,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_WELCOME2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Background. */
      pixmap_gdk = pixmaps->nariative_bg;
      mask = pixmaps->nariative_bg_mask;
      if(pixmap_gdk != NULL)
      {
          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            gtk_table_attach(
                GTK_TABLE(parent), pixmap,
                0, 1,
                0, 2,
                GTK_SHRINK,
                GTK_SHRINK,
                0, 0
            );
            gtk_widget_show(pixmap);
          }
      }


      /* Begin creating page. */
      parent = page;

      /* Title. */
      pixmap_gdk = pixmaps->title;
      mask = pixmaps->title_mask;
      if(pixmap_gdk != NULL)
      {
          /* Title as image. */

          /* Title hbox, fixed, and pixmap. */
          w = gtk_hbox_new(TRUE, 0);
          gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
          gtk_widget_show(w);
          parent3 = w;

          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            /* Set size of parent to match pixmap. */
            gtk_widget_set_usize(parent3, width, height);
            gtk_box_pack_start(GTK_BOX(parent3), pixmap, TRUE, TRUE, 10);
            gtk_widget_show(pixmap);

            if((mask != NULL) && !GTK_WIDGET_NO_WINDOW(parent3))
                gtk_widget_shape_combine_mask(parent3, mask, 0, 0);
          }

          /* Title second line, icon and text. */
          w = gtk_hbox_new(FALSE, 0);
          gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
          gtk_widget_show(w);
          parent2 = w;

          w = gtk_hbox_new(FALSE, 0);
          gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
          gtk_widget_show(w);
          parent2 = w;

          pixmap_gdk = pixmaps->icon_wand_32x32;
          mask = pixmaps->icon_wand_32x32_mask;
          if(pixmap_gdk != NULL)
          {
            w = gtk_fixed_new();
            gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
            gtk_widget_show(w);
            parent3 = w;

            gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
            pixmap = gtk_pixmap_new(pixmap_gdk, mask);
            if(pixmap != NULL)
            {
                /* Set size of fixed to match pixmap. */
                gtk_widget_set_usize(parent3, width, height);

                gtk_fixed_put(GTK_FIXED(parent3), pixmap, 0, 0);
                gtk_widget_show(pixmap);

                if(mask != NULL)
                  gtk_widget_shape_combine_mask(parent3, mask, 0, 0);
            }
          }

          w = gtk_label_new(YC_MESG_WELCOME1);
          gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
          gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
          gtk_widget_set_style(w, styles->heading1_text);
          gtk_widget_show(w);
      }
      else
      {
          /* Alternate mostly text title. */

          w = gtk_hbox_new(FALSE, 0);
          gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
          gtk_widget_show(w);
          parent2 = w;

          pixmap_gdk = pixmaps->icon_wand_32x32;
          mask = pixmaps->icon_wand_32x32_mask;
          if(pixmap_gdk != NULL)
          {
            w = gtk_fixed_new();
            gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
            gtk_widget_show(w);
            parent3 = w;

            gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
            pixmap = gtk_pixmap_new(pixmap_gdk, mask);
            if(pixmap != NULL)
            {
                /* Set size of fixed to match pixmap. */
                gtk_widget_set_usize(parent3, width, height);

                gtk_fixed_put(GTK_FIXED(parent3), pixmap, 0, 0);
                gtk_widget_show(pixmap);

                if(mask != NULL)
                  gtk_widget_shape_combine_mask(parent3, mask, 0, 0);
            }
          }

          w = gtk_label_new(YC_MESG_WELCOME1_ALT);
          gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
          gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
          gtk_widget_set_style(w, styles->heading1_text);
          gtk_widget_show(w);
      }


      /* What this program does. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_WELCOME2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);

      /* Were to learn more. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_WELCOME3);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);


      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_WELCOME4);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_CENTER);
      gtk_widget_show(w);


      /* Get started! */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_WELCOME5);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);


      return;
}

/*
 *      Creates the locations nariative strip and page on the yc.
 *
 *    These contain the paths to DSP and mixer devices along with
 *    the YIFF server configuration file to load for this session,
 *    address to connect to the YIFF server, and YIFF server listening
 *    network port number.
 *
 *      This function should be called from YCCreate(), all inputs
 *      assumed valid.
 */
static void YCCreatePageLocations(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
)
{
      GtkWidget *w, *nariative, *page, *parent, *parent2, *pixmap;
      const char *cstrptr;
      char *strptr;
      char *address_string = NULL, *port_string = NULL;
      GdkPixmap *pixmap_gdk;
      GdkBitmap *mask;
      gint width, height;
      void *vp1, *vp2, *vp3;


      /* Get address and port strings (coppied). */
      cstrptr = (const char *)getenv("RECORDER");
      if(cstrptr == NULL)
      {
          address_string = strdup(YC_DEF_ADDRESS);
      }
      else
      {
          address_string = strdup(cstrptr);
          if(address_string != NULL)
          {
            /* Parse at ':' deliminator. */
            strptr = strchr(address_string, ':');
            if(strptr != NULL)
                (*strptr) = '\0';
          }
      }

      cstrptr = (const char *)getenv("RECORDER");
      if(cstrptr == NULL)
      {
          port_string = strdup(YC_DEF_PORT);
      }
      else
      {
          port_string = strdup(cstrptr);
          if(port_string != NULL)
          {
            /* Parse at ':' deliminator. */
            strptr = strchr(port_string, ':');
            if(strptr != NULL)
            {
                strptr = strdup(strptr + 1);
                free(port_string);
                port_string = strptr;
            }
          }
      }



      /* Create parents for nariative strip and page. */
      w = gtk_table_new(2, 1, FALSE);
      nariative = w;

      w = gtk_vbox_new(FALSE, 0);
      page = w;

      /* Append to ps. */
      PStepperAppend(
          yc->ps,
          page, nariative,
          (gpointer)yc,
          YCPSPageChangeCB
      );


      /* Begin creating nariative strip. */
      parent = nariative;
      gtk_widget_realize(parent);
      gtk_signal_connect(
          GTK_OBJECT(parent), "expose_event",
          GTK_SIGNAL_FUNC(YCWidgetExposeCB), (gpointer)yc
      );

      /* Nariative text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          0, 1,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_LOCATIONS1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Nariative text 2. */ 
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          1, 2,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_LOCATIONS2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT); 
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Background. */
      pixmap_gdk = pixmaps->nariative_bg;
      mask = pixmaps->nariative_bg_mask;
      if(pixmap_gdk != NULL)
      {
          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            gtk_table_attach(
                GTK_TABLE(parent), pixmap,
                0, 1,
                0, 2,
                GTK_SHRINK,
                GTK_SHRINK,
                0, 0
            );
            gtk_widget_show(pixmap);
          }
      }


      /* Begin creating page. */
      parent = page;

      /* Page heading. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);   
      parent2 = w;

      w = gtk_label_new(YC_MESG_LOCATIONS1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->heading2_text);
      gtk_widget_show(w);

      /* Page text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_LOCATIONS2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);


      /* Horizontal separator. */
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* YIFF Sound Server configuration file path prompt. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBarWithBrowse(
          NULL, YC_PROMPT_LABEL_CONFIGURATION_FILE,
          &vp1, &vp2, &vp3,
          yc, YCBrowseConfigurationFileCB
      );
      yc->yiff_configuration_file_entry = (GtkWidget *)vp2;
      yc->yiff_configuration_file_browse = (GtkWidget *)vp3;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, YC_DEF_CONFIG_FILE);
      if(yc->show_tool_tips)
          GUISetWidgetTip(vp2, YC_TIP_MESG_CONFIGURATION_FILE);
      gtk_widget_show(w);

      /* YIFF Sound Server program path prompt. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBarWithBrowse(
          NULL, YC_PROMPT_LABEL_YIFF_PROGRAM,
          &vp1, &vp2, &vp3,
          yc, YCBrowseYIFFProgramCB
      );
      yc->yiff_program_entry = (GtkWidget *)vp2;
      yc->yiff_program_browse = (GtkWidget *)vp3;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, YC_DEF_YIFF_PROGRAM);
      if(yc->show_tool_tips)
          GUISetWidgetTip(vp2, YC_TIP_MESG_YIFF_PROGRAM);
      gtk_widget_show(w);


      /* Horizontal separator. */
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* DSP device path prompt. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBarWithBrowse(
          NULL, YC_PROMPT_LABEL_DSP_DEVICE,
          &vp1, &vp2, &vp3,
          yc, YCBrowseDSPDeviceCB
      );
      yc->dsp_device_entry = (GtkWidget *)vp2;
      yc->dsp_device_browse = (GtkWidget *)vp3;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, YC_DEF_DSP_DEVICE);
      if(yc->show_tool_tips)
          GUISetWidgetTip(vp2, YC_TIP_MESG_DSP_DEVICE);
      gtk_widget_show(w);

      /* Mixer device path prompt. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBarWithBrowse(
          NULL, YC_PROMPT_LABEL_MIXER_DEVICE,
          &vp1, &vp2, &vp3,
          (void *)yc,
          YCBrowseMixerDeviceCB
      );
      yc->mixer_device_entry = (GtkWidget *)vp2;    
      yc->mixer_device_browse = (GtkWidget *)vp3;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, YC_DEF_MIXER_DEVICE);
      if(yc->show_tool_tips)
          GUISetWidgetTip(vp2, YC_TIP_MESG_MIXER_DEVICE);
      gtk_widget_show(w);


      /* Horizontal separator. */
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* Address prompt. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBar(
          NULL, YC_PROMPT_LABEL_ADDRESS,
          &vp1, &vp2
      );
      yc->address_entry = (GtkWidget *)vp2;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, address_string);
      if(yc->show_tool_tips)
          GUISetWidgetTip(vp2, YC_TIP_MESG_ADDRESS);
      gtk_widget_show(w);

      /* Port prompt. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBar(          
          NULL, YC_PROMPT_LABEL_PORT,
          &vp1, &vp2       
      );
      yc->port_entry = (GtkWidget *)vp2;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, port_string);
      if(yc->show_tool_tips)
          GUISetWidgetTip(vp2, YC_TIP_MESG_PORT);
      gtk_widget_show(w);


      /* Horizontal separator. */
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* Start YIFF Sound Server toggle. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);  
      parent2 = w;   

      w = gtk_check_button_new_with_label(
          YC_CHECK_LABEL_YIFF_START
      );
      yc->yiff_start_toggle = w;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_toggle_button_set_active(
          GTK_TOGGLE_BUTTON(w), TRUE
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_YIFF_START);
      gtk_widget_show(w);


      /* Deallocate coppied address and port strings. */
      free(address_string);
      free(port_string);

}

/*
 *      Creates the YModes nariative strip and page on the yc.
 *
 *      Preset Y Audio Modes help Y client applications switch
 *    to Audio parameters more likly to work properly and comform
 *    to standards.
 *
 *      This function should be called from YCCreate(), all inputs
 *      assumed valid.
 */
static void YCCreatePageYModes(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
)
{
      GtkWidget *w, *fw, *nariative, *page, *parent, *parent2, *pixmap;
      GtkWidget *parent3, *parent4, *parent5, *parent6, *scroll_parent;
      GtkWidget *menu;
      GdkPixmap *pixmap_gdk;
      GdkBitmap *mask;
      gint width, height;
      void *vp1;
      GtkCombo *combo;
      GtkEntry *entry;
      GList *glist;
      GSList *gslist;
      GtkAdjustment *adj;
      gchar *heading[1];

      int accel_key;
      void *accel_group;
      unsigned int accel_mods;
      u_int8_t **icon;
      char *label = NULL;
      void *mclient_data;
      void (*func_cb)(GtkWidget *w, void *);


      /* Create parents for nariative strip and page. */
      w = gtk_table_new(3, 1, FALSE);
      nariative = w;

      w = gtk_vbox_new(FALSE, 0);
      page = w;

      /* Append to ps. */
      PStepperAppend(
          yc->ps,
          page, nariative,
          (gpointer)yc,
          YCPSPageChangeCB
      );


      /* Begin creating nariative strip. */
      parent = nariative;
      gtk_widget_realize(parent);
      gtk_signal_connect(
          GTK_OBJECT(parent), "expose_event",
          GTK_SIGNAL_FUNC(YCWidgetExposeCB), (gpointer)yc
      );

      /* Nariative text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          0, 1,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_YMODES1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Nariative text 2. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          1, 2,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_YMODES2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Nariative text 3. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          2, 3,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_YMODES3);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Background. */
      pixmap_gdk = pixmaps->nariative_bg;
      mask = pixmaps->nariative_bg_mask;
      if(pixmap_gdk != NULL)
      {
          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            gtk_table_attach(
                GTK_TABLE(parent), pixmap,
                0, 1,
                0, 3,
                GTK_SHRINK,
                GTK_SHRINK,
                0, 0
            );
            gtk_widget_show(pixmap);
          }
      }


      /* Begin creating page. */
      parent = page;

      /* HBox to hold ymodes clist and the add, edit, remove
       * buttons.
       */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 10);
      gtk_widget_show(w);
      parent2 = w;

      /* YModes clist. */
      w = gtk_scrolled_window_new(NULL, NULL);
      gtk_scrolled_window_set_policy(
          GTK_SCROLLED_WINDOW(w),
          GTK_POLICY_AUTOMATIC,
          GTK_POLICY_AUTOMATIC
      );
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_widget_show(w);
      scroll_parent = w;

      heading[0] = YC_LIST_lABEL_YMODES;
      w = gtk_clist_new_with_titles(1, heading);
      yc->ymodes_clist = w;
      if(!GTK_WIDGET_NO_WINDOW(w))
      {
          /* Tie to button press callback (for mapping menu). */
          gtk_widget_set_events(
            w,
            GDK_BUTTON_PRESS_MASK
          );
          gtk_signal_connect(
            GTK_OBJECT(w), "button_press_event",
            GTK_SIGNAL_FUNC(YCYModesListMenuMapCB),
            (gpointer)yc
          );
      }
      gtk_clist_column_titles_passive(GTK_CLIST(w));
      gtk_clist_set_selection_mode(GTK_CLIST(w), GTK_SELECTION_SINGLE);
      gtk_container_add(GTK_CONTAINER(scroll_parent), w);
      gtk_widget_set_usize(w, 300, 180);
      gtk_clist_set_column_auto_resize(GTK_CLIST(w), 0, TRUE);
      gtk_clist_set_shadow_type(GTK_CLIST(w), GTK_SHADOW_IN);
      gtk_signal_connect(
          GTK_OBJECT(w), "select_row",
          GTK_SIGNAL_FUNC(YCYModesListSelectCB),
          (gpointer)yc
      );
      gtk_widget_show(w);


      /* Create right click menu. */
      menu = (GtkWidget *)GUIMenuCreate();
      yc->ymodes_menu = menu;
      accel_group = NULL;
      mclient_data = (void *)yc;

#define DO_ADD_MENU_ITEM_LABEL  \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_LABEL, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
}
#define DO_ADD_MENU_SEP \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SEPARATOR, NULL, \
  NULL, NULL, 0, 0, NULL, \
  NULL, NULL \
 ); \
}

      icon = (u_int8_t **)icon_add_20x20_xpm;
      label = "Add...";
      accel_key = 0;
      accel_mods = 0;
      func_cb = YCYModesListButtonCB;
      DO_ADD_MENU_ITEM_LABEL
      yc->ymodes_menu_add = fw;

      icon = (u_int8_t **)icon_remove_20x20_xpm;
      label = "Remove";
      accel_key = 0;
      accel_mods = 0;
      func_cb = YCYModesListButtonCB;
      DO_ADD_MENU_ITEM_LABEL
      yc->ymodes_menu_remove = fw;

      DO_ADD_MENU_SEP

      icon = (u_int8_t **)icon_redo_20x20_xpm;
      label = "Properties...";
      accel_key = 0;
      accel_mods = 0;
      func_cb = YCYModesListButtonCB;
      DO_ADD_MENU_ITEM_LABEL
      yc->ymodes_menu_edit = fw;

#undef DO_ADD_MENU_ITEM_LABEL
#undef DO_ADD_MENU_SEP


      /* Vbox to hold buttons. */
      w = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent3 = w;

      /* Add button. */
      w = GUIButtonPixmapLabelH(
          (u_int8_t **)icon_add_20x20_xpm,
          "Add", NULL
      );
      yc->ymode_add_btn = w;
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(w, YC_BTN_WIDTH, YC_BTN_HEIGHT);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",   
          GTK_SIGNAL_FUNC(YCYModesListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);

      /* Edit button. */
      w = GUIButtonPixmapLabelH(
          (u_int8_t **)icon_redo_20x20_xpm,
          "Edit", NULL
      );
      yc->ymode_edit_btn = w;
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(w, YC_BTN_WIDTH, YC_BTN_HEIGHT);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",   
          GTK_SIGNAL_FUNC(YCYModesListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);

      /* Remove button. */
      w = GUIButtonPixmapLabelH(
          (u_int8_t **)icon_remove_20x20_xpm,
          "Remove", NULL
      );
      yc->ymode_remove_btn = w;
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(w, YC_BTN_WIDTH, YC_BTN_HEIGHT);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYModesListButtonCB),
          (gpointer)yc  
      );
      gtk_widget_show(w);


      /* Vbox to hold shift buttons. */
      w = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent4 = w;

      /* Shift up button. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent5 = w;

      w = gtk_button_new();
      yc->ymode_shift_up_btn = w;
      gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(GTK_WIDGET(w), 20, 20);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYModesListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);
      parent6 = w;

      w = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_OUT);
      gtk_container_add(GTK_CONTAINER(parent6), w);
      gtk_widget_show(w);


      /* Shift down button. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent5 = w;

      w = gtk_button_new();
      yc->ymode_shift_down_btn = w;
      gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(GTK_WIDGET(w), 20, 20);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYModesListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);
      parent6 = w;

      w = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
      gtk_container_add(GTK_CONTAINER(parent6), w);
      gtk_widget_show(w);


      /* Table to hold sample rate combo and channel radios. */
      w = gtk_table_new(1, 4, FALSE);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent2 = w;

      /* Sample rate combo. */
      glist = NULL;
      glist = g_list_append(glist, "8000");
      glist = g_list_append(glist, "11025");
      glist = g_list_append(glist, "22050");
      glist = g_list_append(glist, "44100");
      w = GUIComboCreate(
          YC_COMBO_LABEL_SAMPLE_RATE,
          "8000",
          (void *)glist,
          4,
          &vp1,
          (void *)yc, NULL, NULL
      );
      g_list_free(glist);
      glist = NULL;
      yc->ymode_sample_rate_combo = (GtkWidget *)vp1;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          0, 1,
          0, 1,
          GTK_SHRINK,
          GTK_SHRINK,
          10, 2
      );
      combo = (GtkCombo *)vp1;
      entry = (GtkEntry *)combo->entry;
      if(yc->show_tool_tips)
          GUISetWidgetTip(GTK_WIDGET(entry), YC_TIP_MESG_SAMPLE_RATE);
      gtk_widget_show(w);

      /* Channels. */
      w = gtk_label_new("Ch:");
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          1, 2,
          0, 1,
          0,
          0,
          2, 2
      );
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_RIGHT);
      gtk_widget_show(w);
      
      gslist = NULL;
      w = gtk_radio_button_new_with_label(gslist, "1");
      yc->ymode_channels1_radio = w;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          2, 3,
          0, 1,
          0,   
          0,
          2, 2
      );
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE);
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_CHANNELS1);
      gtk_widget_show(w);
      gslist = gtk_radio_button_group(GTK_RADIO_BUTTON(w));

      w = gtk_radio_button_new_with_label(gslist, "2");
      yc->ymode_channels2_radio = w;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          3, 4,
          0, 1,
          0,   
          0,   
          2, 2 
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_CHANNELS2);
      gtk_widget_show(w);


      /* Table to hold fragment size combo and sample size radios. */
      w = gtk_table_new(1, 4, FALSE);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent2 = w;

      /* Fragment size. */
      glist = NULL;
      glist = g_list_append(glist, "256");
      glist = g_list_append(glist, "512");
      glist = g_list_append(glist, "1024");
      glist = g_list_append(glist, "2048");
      glist = g_list_append(glist, "4096");
      glist = g_list_append(glist, "8192");
      glist = g_list_append(glist, "16384");
      w = GUIComboCreate(
          YC_COMBO_LABEL_FRAGMENT_SIZE,
          "256",
          (void *)glist,
          7,
          &vp1,
          (void *)yc, NULL, NULL
      );
      g_list_free(glist);
      glist = NULL;
      yc->ymode_fragment_size_combo = (GtkWidget *)vp1;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          0, 1,
          0, 1,
          GTK_SHRINK,
          GTK_SHRINK,
          10, 2
      );
      combo = (GtkCombo *)vp1;
      entry = (GtkEntry *)combo->entry;
      if(yc->show_tool_tips)
          GUISetWidgetTip(GTK_WIDGET(entry), YC_TIP_MESG_FRAGMENT_SIZE);
      gtk_widget_show(w);

      /* Sample size. */
      w = gtk_label_new("SpSz:");
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          1, 2,
          0, 1,
          0,
          0,
          2, 2
      );
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_RIGHT);
      gtk_widget_show(w);

      gslist = NULL;
      w = gtk_radio_button_new_with_label(gslist, "8");
      yc->ymode_sample_size8_radio = w;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          2, 3,
          0, 1,
          0,
          0,
          2, 2
      );
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE);
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_SAMPLE_SIZE8);
      gtk_widget_show(w);
      gslist = gtk_radio_button_group(GTK_RADIO_BUTTON(w));

      w = gtk_radio_button_new_with_label(gslist, "16");
      yc->ymode_sample_size16_radio = w;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          3, 4,
          0, 1,
          0,
          0,
          2, 2
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_SAMPLE_SIZE16);
      gtk_widget_show(w);


      /* Table to hold cycle spin and calculate button. */
      w = gtk_table_new(1, 2, FALSE);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent2 = w;

      /* Cycle hbox to hold spin and label. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          0, 1,
          0, 1,
          GTK_FILL | GTK_EXPAND,
          0,   
          2, 2 
      );
      gtk_widget_show(w);
      parent3 = w;

      /* Label. */
      w = gtk_label_new(YC_SPIN_LABEL_CYCLE);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* Spin. */
      adj = (GtkAdjustment *)gtk_adjustment_new(
          30000.0,            /* Initial. */
            100.0,            /* Min. */
        1000000.0,            /* Max (one second). */
            100.0,            /* Step inc. */
           5000.0,            /* Page inc. */
           5000.0       /* Page size. */
      );
      w = gtk_spin_button_new(
          adj,
          1.0,    /* Climb rate (0.0 to 1.0). */
            0           /* Digits. */
      );
      yc->ymode_cycle_spin = w;
      gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
      gtk_signal_connect(
          GTK_OBJECT(adj), "value_changed",
          GTK_SIGNAL_FUNC(YCCycleSpinChangeCB),
          (gpointer)yc
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_CYCLE);
      gtk_widget_show(w);

      /* Calculate cycle button. */
      w = gtk_button_new_with_label(YC_BUTTON_LABEL_CALCULATE_CYCLE);
      yc->ymode_calculate_cycle_btn = w;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          1, 2,
          0, 1,
          0,
          0,
          10, 2
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCCycleCalculateCB),
          (gpointer)yc
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_CYCLE_CALCULATE);
      gtk_widget_show(w);


      /* Table to hold apply values to Y server button. */
      w = gtk_table_new(1, 2, FALSE);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent2 = w;

      /* Apply values to Y server button. */
      w = gtk_button_new_with_label(YC_BUTTON_LABEL_APPLY_TO_YIFF);
      yc->ymode_apply_to_yiff_btn = w;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          0, 1,
          0, 1,
          GTK_FILL | GTK_EXPAND,
          0,
          10, 2
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYModeValuesApplyToYCB),
          (gpointer)yc
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_APPLY_TO_YIFF);
      gtk_widget_show(w);

      /* Play sound object. */
      w = gtk_button_new_with_label(YC_BUTTON_LABEL_PLAY);
      yc->ymode_play_btn = w;
      gtk_table_attach(
          GTK_TABLE(parent2), w,
          1, 2,
          0, 1,
          GTK_FILL | GTK_EXPAND,
          0,
          10, 2
      );
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYModePlayCB),
          (gpointer)yc
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_PLAY);
      gtk_widget_show(w);


      return;
}

/*
 *      Creates the timings nariative strip and page on the yc.
 *
 *      This function should be called from YCCreate(), all inputs
 *      assumed valid.
 */
static void YCCreatePageTimings(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
)
{
      GtkWidget *w, *nariative, *page, *parent, *parent2, *pixmap;
      GtkWidget *parent3;
      GdkPixmap *pixmap_gdk;
      GdkBitmap *mask;
      gint width, height;
      GtkAdjustment *adj;


      /* Create parents for nariative strip and page. */
      w = gtk_table_new(1, 1, FALSE);
      nariative = w;

      w = gtk_vbox_new(FALSE, 0);
      page = w;

      /* Append to ps. */
      PStepperAppend(
          yc->ps,
          page, nariative,
          (gpointer)yc,
          YCPSPageChangeCB
      );


      /* Begin creating nariative strip. */
      parent = nariative;
      gtk_widget_realize(parent);
      gtk_signal_connect(
          GTK_OBJECT(parent), "expose_event",
          GTK_SIGNAL_FUNC(YCWidgetExposeCB), (gpointer)yc
      );

      /* Background. */
      pixmap_gdk = pixmaps->nariative_bg;
      mask = pixmaps->nariative_bg_mask;
      if(pixmap_gdk != NULL)
      {
          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            gtk_table_attach(
                GTK_TABLE(parent), pixmap,
                0, 1,
                0, 1,
                GTK_SHRINK,
                GTK_SHRINK,
                0, 0
            );
            gtk_widget_show(pixmap);
          }
      }


      /* Begin creating page. */
      parent = page;

      /* Timings. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_TIMINGS1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->heading2_text);
      gtk_widget_show(w);

      /* Timings and intervals explaination. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_TIMINGS2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);


      /* Horizontal separator. */
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* Refresh interval spin. */
      
      /* Hbox to hold spin and label. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_widget_show(w);
      parent3 = w;

      /* Label. */
      w = gtk_label_new(YC_SPIN_LABEL_REFRESH_INT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* Spin. */
      adj = (GtkAdjustment *)gtk_adjustment_new(
       30000000.0,            /* Initial (30 seconds). */
         100000.0,            /* Min. */
       60000000.0,            /* Max (one second). */
         500000.0,            /* Step inc. */
        1000000.0,            /* Page inc. */
        1000000.0             /* Page size. */
      );
      w = gtk_spin_button_new(
          adj,
          1.0,        /* Climb rate (0.0 to 1.0). */
            0         /* Digits. */
      );
      yc->sound_refresh_spin = w;
      gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
      gtk_signal_connect(
          GTK_OBJECT(adj), "value_changed",
          GTK_SIGNAL_FUNC(YCRefreshIntSpinChangeCB),
          (gpointer)yc
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_REFRESH_INT);
      gtk_widget_show(w);



      return;
}

/*
 *      Creates the MIDI nariative strip and page on the yc.
 *
 *    YIFF uses an external MIDI player to play MIDI on OSS/ALSA
 *    implmentations due to the experimental stage of the MIDI
 *    implmentation on OSS and ALSA.
 *
 *      This function should be called from YCCreate(), all inputs
 *      assumed valid.
 */
static void YCCreatePageMIDI(    
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
)
{
      GtkWidget *w, *nariative, *page, *parent, *parent2, *pixmap;
      GdkPixmap *pixmap_gdk;
      GdkBitmap *mask;
      void *vp1, *vp2, *vp3;
      gint width, height;


      /* Create parents for nariative strip and page. */
      w = gtk_table_new(2, 1, FALSE);
      nariative = w;

      w = gtk_vbox_new(FALSE, 0);
      page = w;

      /* Append to ps. */
      PStepperAppend(
          yc->ps,
          page, nariative,
          (gpointer)yc,
          YCPSPageChangeCB
      );


      /* Begin creating nariative strip. */
      parent = nariative;
      gtk_widget_realize(parent);
      gtk_signal_connect(
          GTK_OBJECT(parent), "expose_event",
          GTK_SIGNAL_FUNC(YCWidgetExposeCB), (gpointer)yc
      );

      /* Nariative text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          0, 1,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_MIDI1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Background. */
      pixmap_gdk = pixmaps->nariative_bg;
      mask = pixmaps->nariative_bg_mask;
      if(pixmap_gdk != NULL)
      {
          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            gtk_table_attach(
                GTK_TABLE(parent), pixmap,
                0, 1,
                0, 2,
                GTK_SHRINK,
                GTK_SHRINK,
                0, 0
            );
            gtk_widget_show(pixmap);
          }
      }


      /* Begin creating page. */
      parent = page;

      /* MIDI. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;   

      w = gtk_label_new(YC_MESG_MIDI1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->heading2_text);
      gtk_widget_show(w);

      /* Remedy for MIDI explaination. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_MIDI2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);

      /* Which MIDI player to use. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_MIDI3);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);


      /* Horizontal separator. */
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
      gtk_widget_show(w);

      /* MIDI player command. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBarWithBrowse(
          NULL, YC_PROMPT_LABEL_MIDI_PLAY_CMD,
          &vp1, &vp2, &vp3,
          (void *)yc,
          YCBrowseMIDIPlayCmdCB
      );
      yc->midi_play_cmd_entry = (GtkWidget *)vp2;
      yc->midi_play_cmd_browse = (GtkWidget *)vp3;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, YC_DEF_MIDI_PLAY_CMD);
      if(yc->show_tool_tips)
          GUISetWidgetTip((GtkWidget *)vp2, YC_TIP_MESG_MIDI_PLAY_CMD);
      gtk_widget_show(w);   


      /* ALSA MIDI device port. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBar(
          NULL, YC_PROMPT_LABEL_ALSA_MIDI_PORT,
          &vp1, &vp2
      );
      yc->alsa_midi_port_entry = (GtkWidget *)vp2;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, YC_DEF_ALSA_MIDI_PORT);
      if(yc->show_tool_tips)
          GUISetWidgetTip((GtkWidget *)vp2, YC_TIP_MESG_ALSA_MIDI_PORT);
      gtk_widget_show(w);


      return;
}

/*
 *      Creates the Y Sound Paths nariative strip and page on the yc.
 *
 *      The Y Sound Paths are a list of paths on the computer the
 *    Y server is running on. These paths are looked for when
 *    a relative path is given to the Y sound server to play
 *    a sound object on.
 *
 *      This function should be called from YCCreate(), all inputs
 *      assumed valid.
 */     
static void YCCreatePageYSoundPaths(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
) 
{       
      GtkWidget *w, *fw, *nariative, *page, *parent, *parent2, *pixmap;
      GtkWidget *parent3, *parent4, *parent5, *parent6, *scroll_parent;
      GtkWidget *menu;
      GdkPixmap *pixmap_gdk;
      GdkBitmap *mask;
      gint width, height;
      gchar *heading[1];

      int accel_key;
      void *accel_group;
      unsigned int accel_mods;
      u_int8_t **icon;
      char *label = NULL;
      void *mclient_data;
      void (*func_cb)(GtkWidget *w, void *);


      /* Create parents for nariative strip and page. */
      w = gtk_table_new(2, 1, FALSE);
      nariative = w;

      w = gtk_vbox_new(FALSE, 0);
      page = w;

      /* Append to ps. */
      PStepperAppend(
          yc->ps,
          page, nariative,
          (gpointer)yc,
          YCPSPageChangeCB
      );


      /* Begin creating nariative strip. */
      parent = nariative;
      gtk_widget_realize(parent);
      gtk_signal_connect(
          GTK_OBJECT(parent), "expose_event",
          GTK_SIGNAL_FUNC(YCWidgetExposeCB), (gpointer)yc
      );

      /* Nariative text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          0, 1,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_YSOUNDPATHS1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Nariative text 2. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          1, 2,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_NAR_YSOUNDPATHS2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Background. */
      pixmap_gdk = pixmaps->nariative_bg;
      mask = pixmaps->nariative_bg_mask;
      if(pixmap_gdk != NULL)
      {
          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            gtk_table_attach(
                GTK_TABLE(parent), pixmap,
                0, 1,
                0, 2,
                GTK_SHRINK,
                GTK_SHRINK,
                0, 0
            );
            gtk_widget_show(pixmap);
          }
      }


      /* Begin creating page. */
      parent = page;

      /* Heading. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;
            
      w = gtk_label_new(YC_MESG_YSOUNDPATHS1);   
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT); 
      gtk_widget_set_style(w, styles->heading2_text);
      gtk_widget_show(w);

      /* Text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_YSOUNDPATHS2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);


      /* HBox to hold ysound paths clist and the add, edit, remove
       * buttons.
       */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 10);
      gtk_widget_show(w);
      parent2 = w;

      /* YSound Paths clist. */
      w = gtk_scrolled_window_new(NULL, NULL);
      gtk_scrolled_window_set_policy(
          GTK_SCROLLED_WINDOW(w),
          GTK_POLICY_AUTOMATIC,
          GTK_POLICY_AUTOMATIC
      );
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_widget_show(w);
      scroll_parent = w;

      heading[0] = "";
      w = gtk_clist_new_with_titles(1, heading);
      yc->ysound_paths_clist = w;
      if(!GTK_WIDGET_NO_WINDOW(w))
      {
          /* Tie to button press callback (for mapping menu). */
          gtk_widget_set_events(
            w,
            GDK_BUTTON_PRESS_MASK
          );
          gtk_signal_connect(
            GTK_OBJECT(w), "button_press_event",
            GTK_SIGNAL_FUNC(YCYSoundPathsMenuMapCB),
            (gpointer)yc
          );
      }
      gtk_clist_column_titles_passive(GTK_CLIST(w));
      gtk_clist_column_titles_hide(GTK_CLIST(w));
      gtk_clist_set_selection_mode(GTK_CLIST(w), GTK_SELECTION_SINGLE);
      gtk_container_add(GTK_CONTAINER(scroll_parent), w);
      gtk_widget_set_usize(w, 300, 180);
      gtk_clist_set_column_auto_resize(GTK_CLIST(w), 0, TRUE);
      gtk_clist_set_shadow_type(GTK_CLIST(w), GTK_SHADOW_IN);
      gtk_signal_connect(
          GTK_OBJECT(w), "select_row",
          GTK_SIGNAL_FUNC(YCYSoundPathsListSelectCB),
          (gpointer)yc
      );
      gtk_widget_show(w);


      /* Create right click menu. */
      menu = (GtkWidget *)GUIMenuCreate();
      yc->ysound_paths_menu = menu;
      accel_group = NULL;
      mclient_data = (void *)yc;

#define DO_ADD_MENU_ITEM_LABEL      \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_LABEL, accel_group, \
  icon, label, accel_key, accel_mods, (void **)&fw, \
  mclient_data, func_cb \
 ); \
}
#define DO_ADD_MENU_SEP \
{ \
 w = GUIMenuItemCreate( \
  menu, GUI_MENU_ITEM_TYPE_SEPARATOR, NULL, \
  NULL, NULL, 0, 0, NULL, \
  NULL, NULL \
 ); \
}

      icon = (u_int8_t **)icon_add_20x20_xpm;
      label = "Add...";
      accel_key = 0;
      accel_mods = 0;
      func_cb = YCYSoundPathsListButtonCB;
      DO_ADD_MENU_ITEM_LABEL
      yc->ysound_paths_menu_add = fw;

      icon = (u_int8_t **)icon_remove_20x20_xpm;
      label = "Remove";
      accel_key = 0;
      accel_mods = 0;
      func_cb = YCYSoundPathsListButtonCB;
      DO_ADD_MENU_ITEM_LABEL
      yc->ysound_paths_menu_remove = fw;

      DO_ADD_MENU_SEP

      icon = (u_int8_t **)icon_redo_20x20_xpm;
      label = "Properties...";
      accel_key = 0;
      accel_mods = 0;
      func_cb = YCYSoundPathsListButtonCB;
      DO_ADD_MENU_ITEM_LABEL
      yc->ysound_paths_menu_edit = fw;

#undef DO_ADD_MENU_ITEM_LABEL
#undef DO_ADD_MENU_SEP


      /* Vbox to hold buttons. */
      w = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent3 = w;

      /* Add button. */
      w = GUIButtonPixmapLabelH(
          (u_int8_t **)icon_add_20x20_xpm,
          "Add", NULL
      );
      yc->ysound_paths_add_btn = w;
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(w, YC_BTN_WIDTH, YC_BTN_HEIGHT);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYSoundPathsListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w); 

      /* Edit button. */
      w = GUIButtonPixmapLabelH(
          (u_int8_t **)icon_redo_20x20_xpm,
          "Edit", NULL
      );
      yc->ysound_paths_edit_btn = w;
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(w, YC_BTN_WIDTH, YC_BTN_HEIGHT);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYSoundPathsListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);

      /* Remove button. */
      w = GUIButtonPixmapLabelH(
          (u_int8_t **)icon_remove_20x20_xpm,
          "Remove", NULL
      );
      yc->ysound_paths_remove_btn = w;
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(w, YC_BTN_WIDTH, YC_BTN_HEIGHT);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYSoundPathsListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);


      /* Vbox to hold shift buttons. */
      w = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent4 = w;

      /* Shift up button. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent5 = w;

      w = gtk_button_new();
      yc->ysound_paths_shift_up_btn = w;
      gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(GTK_WIDGET(w), 20, 20);
      gtk_signal_connect(
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYSoundPathsListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);
      parent6 = w;

      w = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_OUT);
      gtk_container_add(GTK_CONTAINER(parent6), w);
      gtk_widget_show(w);


      /* Shift down button. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
      parent5 = w;

      w = gtk_button_new();
      yc->ysound_paths_shift_down_btn = w;
      gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2);
      gtk_widget_set_usize(GTK_WIDGET(w), 20, 20);
      gtk_signal_connect(   
          GTK_OBJECT(w), "clicked",
          GTK_SIGNAL_FUNC(YCYSoundPathsListButtonCB),
          (gpointer)yc
      );
      gtk_widget_show(w);
      parent6 = w;

      w = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
      gtk_container_add(GTK_CONTAINER(parent6), w);
      gtk_widget_show(w);








      return;
}

/*
 *      Creates the confermation nariative strip and page on the yc.
 *
 *    This page lists the currently set values for confermation and
 *    options to save configurations.
 *
 *      This function should be called from YCCreate(), all inputs
 *      assumed valid.
 */
static void YCCreatePageConferm(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps,
      gint page_num
)
{
      GtkWidget *w, *nariative, *page, *parent, *parent2, *pixmap;
      GtkWidget *scroll_parent;
      GdkPixmap *pixmap_gdk;
      GdkBitmap *mask;
      void *vp1, *vp2, *vp3;
      gint width, height;
      gchar *heading[1];


      /* Create parents for nariative strip and page. */
      w = gtk_table_new(2, 1, FALSE);
      nariative = w;

      w = gtk_vbox_new(FALSE, 0);
      page = w;

      /* Append to ps. */
      PStepperAppend(
          yc->ps,
          page, nariative,
          (gpointer)yc,
          YCPSPageChangeCB
      );


      /* Begin creating nariative strip. */
      parent = nariative;
      gtk_widget_realize(parent);
      gtk_signal_connect(
          GTK_OBJECT(parent), "expose_event",
          GTK_SIGNAL_FUNC(YCWidgetExposeCB), (gpointer)yc
      );

      /* Nariative text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_table_attach(
          GTK_TABLE(parent), w,
          0, 1,
          0, 1,
          GTK_SHRINK | GTK_FILL,
          GTK_SHRINK,
          0, 10
      );
      gtk_widget_show(w);
      parent2 = w;  

      w = gtk_label_new(YC_MESG_NAR_CONFERM1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 5);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->nariative_text);
      gtk_widget_show(w);

      /* Background. */
      pixmap_gdk = pixmaps->nariative_bg;
      mask = pixmaps->nariative_bg_mask;
      if(pixmap_gdk != NULL)
      {
          gdk_window_get_size((GdkWindow *)pixmap_gdk, &width, &height);
          pixmap = gtk_pixmap_new(pixmap_gdk, mask);
          if(pixmap != NULL)
          {
            gtk_table_attach(
                GTK_TABLE(parent), pixmap,
                0, 1,
                0, 2,
                GTK_SHRINK,
                GTK_SHRINK,
                0, 0
            );
            gtk_widget_show(pixmap);
          }
      }


      /* Begin creating page. */
      parent = page;

      /* Heading. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_CONFERMATION1);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_set_style(w, styles->heading2_text);
      gtk_widget_show(w);

      /* Text 1. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_label_new(YC_MESG_CONFERMATION2);
      gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 10);
      gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_widget_show(w);


      /* HBox to hold confermation items clist. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 10);
      gtk_widget_show(w);
      parent2 = w;

      /* Confermation items clist. */
      w = gtk_scrolled_window_new(NULL, NULL);
      gtk_scrolled_window_set_policy(
          GTK_SCROLLED_WINDOW(w),
          GTK_POLICY_AUTOMATIC,
          GTK_POLICY_AUTOMATIC
      );
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_widget_show(w);
      scroll_parent = w;

      heading[0] = "";
      w = gtk_clist_new_with_titles(1, heading);
      yc->conferm_items_clist = w;
      if(!GTK_WIDGET_NO_WINDOW(w))
      {
          /* Tie to button press callback (for mapping menu). */
/*
          gtk_widget_set_events(
            w,
            GDK_BUTTON_PRESS_MASK
          );
          gtk_signal_connect(
            GTK_OBJECT(w), "button_press_event",
            GTK_SIGNAL_FUNC(YCYSoundPathsMenuMapCB),
            (gpointer)yc
          );
 */
      }
      gtk_clist_column_titles_passive(GTK_CLIST(w));
      gtk_clist_column_titles_hide(GTK_CLIST(w));
      gtk_clist_set_selection_mode(GTK_CLIST(w), GTK_SELECTION_SINGLE);
      gtk_container_add(GTK_CONTAINER(scroll_parent), w);
      gtk_widget_set_usize(w, 300, 150);
      gtk_clist_set_column_auto_resize(GTK_CLIST(w), 0, TRUE);
      gtk_clist_set_shadow_type(GTK_CLIST(w), GTK_SHADOW_IN);
      gtk_signal_connect(
          GTK_OBJECT(w), "select_row",
          GTK_SIGNAL_FUNC(YCConfermationListSelectCB),
          (gpointer)yc
      );
      gtk_widget_show(w);

      /* Verbose listing toggle. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = gtk_check_button_new_with_label(
          YC_CHECK_LABEL_CONFERMATION_VERBOSE
      );
      yc->conferm_verbose_toggle = w;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_signal_connect(
          GTK_OBJECT(w), "toggled",
          GTK_SIGNAL_FUNC(YCConfermVerboseToggleCB),
          (gpointer)yc
      );
      gtk_toggle_button_set_active(
          GTK_TOGGLE_BUTTON(w), TRUE
      );
      if(yc->show_tool_tips)
          GUISetWidgetTip(w, YC_TIP_MESG_CONFERMATION_VERBOSE);
      gtk_widget_show(w);


      /* YIFF Sound Server start script. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
      parent2 = w;

      w = GUIPromptBarWithBrowse(
          NULL, YC_PROMPT_LABEL_START_SCRIPT,
          &vp1, &vp2, &vp3,
          (void *)yc,
          YCBrowseStartScriptCB
      );
      yc->start_script_entry = (GtkWidget *)vp2;
      yc->start_script_browse = (GtkWidget *)vp3;
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 10);
      gtk_entry_set_text((GtkEntry *)vp2, YC_DEF_START_SCRIPT);
      if(yc->show_tool_tips)
          GUISetWidgetTip((GtkWidget *)vp2, YC_TIP_MESG_START_SCRIPT);
      gtk_widget_show(w);


      return;
}





/*
 *    Creates a new YIFF Configuration Wizard window structure
 *    with all the widgets set up to default values.
 *
 *    Returns non-zero on error.
 */
int YCCreate(
      yc_struct *yc,
      yc_styles_struct *styles, yc_pixmaps_struct *pixmaps 
)
{
      gint i;
      fb_type_struct *ftype_ptr;
      GtkWidget *w;
      pstepper_struct *ps;


      if((yc == NULL) || (styles == NULL) || (pixmaps == NULL))
          return(-1);

      /* Reset values. */
      yc->initialized = TRUE;
      yc->show_tool_tips = YC_DEF_SHOW_TOOL_TIPS;
      yc->has_changes = FALSE;   

      yc->recorder = NULL;

      yc->selected_ymode = -1;
      yc->selected_ysound_path = -1;


      /* Allocate default file extension types list. */
      yc->total_ftypes = 1;
      yc->ftype = (fb_type_struct **)calloc(
          yc->total_ftypes,
          sizeof(fb_type_struct *)
      );
      if(yc->ftype == NULL)
          yc->total_ftypes = 0;
           
      i = 0;
      if(i < yc->total_ftypes)
      {
          ftype_ptr = (fb_type_struct *)calloc(
            1,
            sizeof(fb_type_struct)
          );
          if(ftype_ptr != NULL)
          {
            ftype_ptr->name = strdup("All files");
            ftype_ptr->ext = strdup("*.*");
          }
          yc->ftype[i] = ftype_ptr;
      }


      /* Create page stepper. */
      ps = PStepperCreate(
          PROG_NAME,
          "<< Back", "Exit",
          "Next >>", "Finish",
          YC_DEF_WIDTH, YC_DEF_HEIGHT,
          (gpointer)yc,
          YCPSExitCB,
          (gpointer)yc,
          YCPSFinishCB
      );
      yc->ps = ps;
      if(ps == NULL)
          return(-1);

      /* Get page stepper toplevel GTK window widget. */
      w = ps->toplevel;
      if(w != NULL)
      {
          /* Set icons. */
          GUISetWMIcon(w->window, (u_int8_t **)icon_yiff_48x48_xpm);
      }

      /* Begin creating widgets for each nariative and page. */

      /* Welcome. */
      YCCreatePageWelcome(yc, styles, pixmaps, YC_PAGE_NUM_WELCOME);

      /* Locations. */
      YCCreatePageLocations(yc, styles, pixmaps, YC_PAGE_NUM_LOCATIONS);

      /* Preset Y Audio Modes. */
      YCCreatePageYModes(yc, styles, pixmaps, YC_PAGE_NUM_YMODES);

      /* Timings. */
      YCCreatePageTimings(yc, styles, pixmaps, YC_PAGE_NUM_TIMINGS);

      /* MIDI. */
      YCCreatePageMIDI(yc, styles, pixmaps, YC_PAGE_NUM_MIDI);

      /* Y Sound Paths. */
      YCCreatePageYSoundPaths(yc, styles, pixmaps, YC_PAGE_NUM_YSOUNDPATHS);

      /* Confermation. */
      YCCreatePageConferm(yc, styles, pixmaps, YC_PAGE_NUM_CONFERM);



      /* Switch to the first page. */
      PStepperChangePage(yc->ps, 0, FALSE);


      /* Did we create the right number of pages? */
      if(ps->total_pages != YC_PAGES_MAX)
      {
/*
          fprintf(
            stderr,
            "YCCreate(): Internal error: Did not create right number of pages.\n"
          );
 */
      }

      return(0);
}


/*
 *    Deletes all Y Audio Modes in the ymodes_clist, this will delete
 *    both the user data containing the ymode and the clist items.
 */
void YCYModesListDeleteAll(yc_struct *yc)
{
      int i;
      GtkCList *clist;
      yc_ymode_data_struct *ymode_ptr;


      if(yc == NULL)
          return;

      clist = (GtkCList *)yc->ymodes_clist;
      if(clist == NULL)
          return;

      /* Mark as no selected item. */
      yc->selected_ymode = -1;

      gtk_clist_freeze(clist);
      /* Go through each row and delete each ymode data. */
      for(i = clist->rows; i >= 0; i--)
      {
          ymode_ptr = (yc_ymode_data_struct *)gtk_clist_get_row_data(
            clist, i
          );
          if(ymode_ptr != NULL)
          {
            /* Free ymode structure and its substructures. */
            free(ymode_ptr->name);
            free(ymode_ptr);
          }
          /* Reset clist row data to NULL. */
          gtk_clist_set_row_data(clist, i, NULL);
      }
      gtk_clist_clear(clist);
      gtk_clist_thaw(clist);

      return;
}

/*
 *      Deletes all Y Sound Paths in the ysound_paths_clist.
 */
void YCYSoundPathsListDeleteAll(yc_struct *yc)
{
      GtkCList *clist;


      if(yc == NULL)
          return;

      clist = (GtkCList *)yc->ysound_paths_clist;
      if(clist == NULL)
          return;

      /* Mark as no selected item. */
      yc->selected_ysound_path = -1;

      gtk_clist_freeze(clist);
      /* No row data to delete for Y Sound Paths. */

      gtk_clist_clear(clist);
      gtk_clist_thaw(clist);

      return;
}

/*
 *    Maps the yc window as needed.
 */
void YCMap(yc_struct *yc)
{
      pstepper_struct *ps;

      if(yc == NULL)
          return;

      ps = yc->ps;
      if(ps == NULL)
          return;

      PStepperMap(ps);

      return;
}

/*
 *      Unmaps the yc window as needed.
 */
void YCUnmap(yc_struct *yc)
{
      pstepper_struct *ps;

      if(yc == NULL)
          return;

      ps = yc->ps;
      if(ps == NULL)
          return;

      PStepperUnmap(ps);
}

/*
 *    Dealloates all resources on the given yc and closes the
 *    connection to the Y server as needed.
 */
void YCDestroy(yc_struct *yc)
{
      if(yc == NULL)
          return;

      /* File extension types. */
      FileBrowserDeleteTypeList(yc->ftype, yc->total_ftypes);        
      yc->ftype = NULL;
      yc->total_ftypes = 0;

      /* Destroy playback of current sound object if any. */
      if(yc->current_sound_play != YIDNULL)
      {
          YDestroyPlaySoundObject(
            yc->recorder,
            yc->current_sound_play
          );
          yc->current_sound_play = YIDNULL;
      }

      /* Close connection to Y server as needed. */
      if(yc->recorder != NULL)
      {
          YCloseConnection(yc->recorder, False);
          yc->recorder = NULL;
      }

      /* Delete all YModes. */
      YCYModesListDeleteAll(yc);


      /* Begin destroying widgets. */

      yc->yiff_configuration_file_entry = NULL;
      yc->yiff_configuration_file_browse = NULL;
      yc->yiff_program_entry = NULL;
      yc->yiff_program_browse = NULL;
      yc->dsp_device_entry = NULL;
      yc->dsp_device_browse = NULL;
      yc->mixer_device_entry = NULL;
      yc->mixer_device_browse = NULL;
      yc->address_entry = NULL;
      yc->port_entry = NULL;
      yc->yiff_start_toggle = NULL;

      yc->ymodes_clist = NULL;
      yc->ymodes_menu = NULL;
      yc->ymodes_menu_add = NULL;
      yc->ymodes_menu_edit = NULL;
      yc->ymodes_menu_remove = NULL;
      yc->ymode_add_btn = NULL;
      yc->ymode_edit_btn = NULL;
      yc->ymode_remove_btn = NULL;
      yc->ymode_shift_up_btn = NULL;
      yc->ymode_shift_down_btn = NULL;
      yc->ymode_sample_rate_combo = NULL;
      yc->ymode_fragment_size_combo = NULL;
      yc->ymode_channels1_radio = NULL;
      yc->ymode_channels2_radio = NULL;
      yc->ymode_sample_size8_radio = NULL;
      yc->ymode_sample_size16_radio = NULL;
      yc->ymode_cycle_spin = NULL;
      yc->ymode_calculate_cycle_btn = NULL;
      yc->ymode_apply_to_yiff_btn = NULL;
      yc->ymode_play_btn = NULL;
      yc->sound_refresh_spin = NULL;

      yc->midi_play_cmd_entry = NULL;
      yc->midi_play_cmd_browse = NULL;
      yc->alsa_midi_port_entry = NULL;

      yc->ysound_paths_clist = NULL;
      yc->ysound_paths_menu = NULL;
      yc->ysound_paths_menu_add = NULL;
      yc->ysound_paths_menu_edit = NULL;
      yc->ysound_paths_menu_remove = NULL;
      yc->ysound_paths_add_btn = NULL;
      yc->ysound_paths_edit_btn = NULL;
      yc->ysound_paths_remove_btn = NULL;
      yc->ysound_paths_shift_up_btn = NULL;
      yc->ysound_paths_shift_down_btn = NULL;

      yc->conferm_items_clist = NULL;
      yc->conferm_verbose_toggle = NULL;
      yc->start_script_entry = NULL;
      yc->start_script_browse = NULL;

      /* Destroy page stepper. */
      PStepperDestroy(yc->ps);

      /* Reset yc structure. */
      memset(yc, 0x00, sizeof(yc_struct));

      return;
}

Generated by  Doxygen 1.6.0   Back to index