home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2526 / setup.c
Encoding:
C/C++ Source or Header  |  1992-11-15  |  28.6 KB  |  1,007 lines

  1. #include <xview/xview.h>
  2. #include <xview/panel.h>
  3. #include <xview/svrimage.h>
  4. #include "workman_ui.h"
  5.  
  6. static char *ident = "@(#)setup.c    1.5 11/15/92";
  7.  
  8. /*
  9.  * Define a few macros to make relative positioning easier.
  10.  */
  11. #define top(item) ((int) xv_get(item, XV_Y))
  12. #define hei(item) ((int) xv_get(item, XV_HEIGHT))
  13. #define bot(item) (top(item) + hei(item))
  14. #define lef(item) ((int) xv_get(item, XV_X))
  15. #define wid(item) ((int) xv_get(item, XV_WIDTH))
  16. #define rig(item) (lef(item) + wid(item))
  17.  
  18. #define put_down(t, s, off) xv_set(t, XV_Y, bot(s) + off, NULL)
  19. #define put_right(t, s, off) xv_set(t, XV_X, rig(s) + off, NULL)
  20. #define center_x(t, s) xv_set(t, XV_X, (lef(s) + rig(s) - wid(t)) / 2, NULL)
  21. #define center_y(t, s) xv_set(t, XV_Y, (top(s) + bot(s) - hei(t)) / 2, NULL)
  22.  
  23. extern void change_track(),
  24.     window1_button2_notify_callback(),
  25.     window1_button3_notify_callback(),
  26.     window1_button4_notify_callback(),
  27.     popup1_buttonpl_notify_callback(),
  28.     popup1_button1_notify_callback(),
  29.     goodies_playnewcds_notify_callback(),
  30.     goodies_abrepeat_notify_callback(),
  31.     plpopup_button7_notify_callback(),
  32.     change_mode(), delete_from_playlist(), playlist_notify(),
  33.     delete_playlist(), rename_playlist(), switch_playlists(),
  34.     slide_balance(), section_start(), section_end(), change_pos(),
  35.     next_stopmode(), set_volume(), next_playmode_default(),
  36.     update_title(), update_trackname(), name_entered(),
  37.     set_which_volume(), set_default_volume(), save_config(),
  38.     cdinfo_reset(), split_track(), delete_track(), index_scan();
  39.  
  40. int    basic_spacing = 0;
  41.  
  42. /*
  43.  * Create the main window and its contents.
  44.  */
  45. window1_objects *
  46. window1_objects_init(ip, owner)
  47.     window1_objects    *ip;
  48.     Xv_opaque        owner;
  49. {
  50.     Xv_opaque    image, image_mask, speaker_image, mode_image0,
  51.             mode_image1, mode_image2, mode_image3, mode_image4,
  52.             mode_image5;
  53.     Panel_item    item;
  54.     int        space;
  55.     static unsigned short bits[] = {
  56. #include "bitmaps/icon"
  57.     }, mask_bits[] = {
  58. #include "bitmaps/iconmask"
  59.     }, speaker_bits[] = {
  60. #include "bitmaps/loud.icon"
  61.     }, mode_bits0[] = {
  62. #include "bitmaps/rew.button"
  63.     }, mode_bits1[] = {
  64. #include "bitmaps/play.button"
  65.     }, mode_bits2[] = {
  66. #include "bitmaps/ff.button"
  67.     }, mode_bits3[] = {
  68. #include "bitmaps/pause.button"
  69.     }, mode_bits4[] = {
  70. #include "bitmaps/stop.button"
  71.     }, mode_bits5[] = {
  72. #include "bitmaps/eject.button"
  73.     };
  74.  
  75.     if ((ip = (window1_objects *) calloc(1,
  76.                 sizeof(window1_objects))) == NULL)
  77.         return (NULL);
  78.  
  79.     image = xv_create(NULL, SERVER_IMAGE, SERVER_IMAGE_DEPTH, 1,
  80.         SERVER_IMAGE_BITS, bits, XV_WIDTH, 64, XV_HEIGHT, 64,
  81.         NULL);
  82.     image_mask = xv_create(NULL, SERVER_IMAGE, SERVER_IMAGE_DEPTH,
  83.         1, SERVER_IMAGE_BITS, mask_bits, XV_WIDTH, 64,
  84.         XV_HEIGHT, 64, NULL);
  85.     ip->window1 = xv_create(owner, FRAME, XV_KEY_DATA, INSTANCE,
  86.         ip, XV_LABEL, "WorkMan", FRAME_SHOW_FOOTER, FALSE,
  87.         FRAME_SHOW_RESIZE_CORNER, FALSE, FRAME_ICON,
  88.         xv_create(NULL, ICON, ICON_IMAGE, image,
  89.         ICON_MASK_IMAGE, image_mask, XV_LABEL, "Wait...",
  90.         NULL), NULL);
  91.  
  92.     ip->controls1 = xv_create(ip->window1, PANEL, XV_KEY_DATA,
  93.         INSTANCE, ip, XV_HELP_DATA, "workman:controls1",
  94.         XV_WIDTH, 1000, XV_HEIGHT, 1000, WIN_BORDER,
  95.         FALSE, NULL);
  96.  
  97.     ip->artist_display = xv_create(ip->controls1, PANEL_MESSAGE,
  98.         XV_HELP_DATA, "workman:artist_display",
  99.         XV_X, 10, XV_Y, 10, PANEL_LABEL_STRING, " ",
  100.         PANEL_LABEL_BOLD, TRUE, NULL);
  101.  
  102.     if (! basic_spacing)
  103.         basic_spacing = hei(ip->artist_display) / 2;
  104.  
  105.     ip->cdname_display = xv_create(ip->controls1, PANEL_MESSAGE,
  106.         XV_HELP_DATA, "workman:cdname_display",
  107.         PANEL_LABEL_STRING, " ", PANEL_LABEL_BOLD, TRUE, XV_X,
  108.         lef(ip->artist_display), NULL);
  109.     put_down(ip->cdname_display, ip->artist_display, basic_spacing);
  110.  
  111.     ip->tracks = xv_create(ip->controls1, PANEL_CHOICE,
  112.         XV_HELP_DATA, "workman:tracks",
  113.         XV_X, lef(ip->cdname_display), /* PANEL_CHOICE_NCOLS, 8, */
  114.         PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_CHOOSE_NONE, FALSE,
  115.         PANEL_NOTIFY_PROC, change_track, NULL);
  116.     put_down(ip->tracks, ip->cdname_display, basic_spacing * 2);
  117.  
  118.     ip->tracktimer = xv_create(ip->controls1, PANEL_MESSAGE,
  119.         XV_HELP_DATA, "workman:tracktimer",
  120.         XV_X, 6, PANEL_LABEL_STRING, "00:00", PANEL_LABEL_BOLD,
  121.         FALSE, NULL);
  122.     put_down(ip->tracktimer, ip->tracks, basic_spacing * 2);
  123.  
  124.     ip->songpos = xv_create(ip->controls1, PANEL_SLIDER,
  125.         XV_HELP_DATA, "workman:songpos",
  126.         PANEL_TICKS, 0,
  127.         PANEL_DIRECTION, PANEL_HORIZONTAL,
  128.         PANEL_SLIDER_END_BOXES, FALSE,
  129.         PANEL_SHOW_RANGE, FALSE,
  130.         PANEL_SHOW_VALUE, FALSE,
  131.         PANEL_MIN_VALUE, 0,
  132.         PANEL_MAX_VALUE, 100,
  133.         PANEL_VALUE, 0,
  134.         PANEL_INACTIVE, TRUE,
  135.         PANEL_NOTIFY_PROC, change_pos,
  136.         NULL);
  137.     xv_set(ip->songpos, XV_Y, top(ip->tracktimer), NULL);
  138.     put_right(ip->songpos, ip->tracktimer, 10);
  139.  
  140.     ip->tracklen = xv_create(ip->controls1, PANEL_MESSAGE,
  141.         XV_HELP_DATA, "workman:tracklen",
  142.         XV_Y, top(ip->tracktimer),
  143.         PANEL_LABEL_STRING, "00:00",
  144.         PANEL_LABEL_BOLD, FALSE,
  145.         NULL);
  146.  
  147.     speaker_image = xv_create(XV_NULL, SERVER_IMAGE,
  148.         SERVER_IMAGE_DEPTH, 1,
  149.         SERVER_IMAGE_BITS, speaker_bits,
  150.         XV_WIDTH, 16,
  151.         XV_HEIGHT, 15,
  152.         NULL);
  153.     ip->speaker = xv_create(ip->controls1, PANEL_MESSAGE,
  154.         XV_HELP_DATA, "workman:speaker",
  155.         XV_X, 12,
  156.         PANEL_LABEL_IMAGE, speaker_image,
  157.         PANEL_LABEL_BOLD, TRUE,
  158.         NULL);
  159.     put_down(ip->speaker, ip->tracktimer, basic_spacing);
  160.  
  161.     ip->volume = xv_create(ip->controls1, PANEL_SLIDER,
  162.         XV_HELP_DATA, "workman:volume",
  163.         XV_X, lef(ip->cdname_display),
  164.         PANEL_TICKS, 0, PANEL_DIRECTION, PANEL_VERTICAL,
  165.         PANEL_SLIDER_END_BOXES, FALSE, PANEL_SHOW_RANGE, FALSE,
  166.         PANEL_SHOW_VALUE, FALSE, PANEL_MIN_VALUE, 0,
  167.         PANEL_MAX_VALUE, 32, PANEL_VALUE, 0,
  168.         PANEL_NOTIFY_PROC, set_volume, NULL);
  169.     put_down(ip->volume, ip->speaker, 3);
  170.  
  171.     mode_image0 = xv_create(XV_NULL, SERVER_IMAGE,
  172.         SERVER_IMAGE_DEPTH, 1,
  173.         SERVER_IMAGE_BITS, mode_bits0,
  174.         XV_WIDTH, 32,
  175.         XV_HEIGHT, 16,
  176.         NULL);
  177.     mode_image1 = xv_create(XV_NULL, SERVER_IMAGE,
  178.         SERVER_IMAGE_DEPTH, 1,
  179.         SERVER_IMAGE_BITS, mode_bits1,
  180.         XV_WIDTH, 32,
  181.         XV_HEIGHT, 16,
  182.         NULL);
  183.     mode_image2 = xv_create(XV_NULL, SERVER_IMAGE,
  184.         SERVER_IMAGE_DEPTH, 1,
  185.         SERVER_IMAGE_BITS, mode_bits2,
  186.         XV_WIDTH, 32,
  187.         XV_HEIGHT, 16,
  188.         NULL);
  189.     mode_image3 = xv_create(XV_NULL, SERVER_IMAGE,
  190.         SERVER_IMAGE_DEPTH, 1,
  191.         SERVER_IMAGE_BITS, mode_bits3,
  192.         XV_WIDTH, 32,
  193.         XV_HEIGHT, 16,
  194.         NULL);
  195.     mode_image4 = xv_create(XV_NULL, SERVER_IMAGE,
  196.         SERVER_IMAGE_DEPTH, 1,
  197.         SERVER_IMAGE_BITS, mode_bits4,
  198.         XV_WIDTH, 32,
  199.         XV_HEIGHT, 16,
  200.         NULL);
  201.     mode_image5 = xv_create(XV_NULL, SERVER_IMAGE,
  202.         SERVER_IMAGE_DEPTH, 1,
  203.         SERVER_IMAGE_BITS, mode_bits5,
  204.         XV_WIDTH, 32,
  205.         XV_HEIGHT, 16,
  206.         NULL);
  207.     ip->mode = xv_create(ip->controls1, PANEL_CHOICE,
  208.         XV_HELP_DATA, "workman:mode",
  209.         PANEL_CHOICE_NROWS, 2,
  210.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  211.         PANEL_CHOOSE_NONE, FALSE,
  212.         PANEL_NOTIFY_PROC, change_mode,
  213.         PANEL_CHOICE_IMAGES,
  214.             mode_image0,
  215.             mode_image1,
  216.             mode_image2,
  217.             mode_image3,
  218.             mode_image4,
  219.             mode_image5,
  220.             NULL,
  221.         PANEL_VALUE, 4,
  222.         NULL);
  223.     put_right(ip->mode, ip->speaker, 8);
  224.     xv_set(ip->mode, XV_Y, (bot(ip->speaker) + top(ip->speaker)) / 2, NULL);
  225.  
  226.     /* Align the volume slider with the mode selector. */
  227.     xv_set(ip->volume, PANEL_SLIDER_WIDTH, bot(ip->mode) - top(ip->volume) -
  228.         10, NULL);
  229.  
  230.     ip->repeat = xv_create(ip->controls1, PANEL_CHOICE,
  231.         PANEL_DISPLAY_LEVEL, PANEL_CURRENT,
  232.         XV_HELP_DATA, "workman:repeat",
  233.         XV_Y, top(ip->mode),
  234.         PANEL_CHOICE_NCOLS, 1,
  235.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  236.         PANEL_NOTIFY_PROC, next_stopmode,
  237.         PANEL_CHOICE_STRINGS,
  238.             "Stop",
  239.             "Repeat",
  240.             "Eject",
  241.             NULL,
  242.         PANEL_DEFAULT_VALUE, 1,
  243.         PANEL_VALUE, 0,
  244.         NULL);
  245.     put_right(ip->repeat, ip->mode, 8);
  246.  
  247.     ip->shuffle = xv_create(ip->controls1, PANEL_CHOICE,
  248.         PANEL_DISPLAY_LEVEL, PANEL_CURRENT,
  249.         XV_HELP_DATA, "workman:shuffle",
  250.         XV_X, lef(ip->repeat),
  251.         PANEL_CHOICE_NCOLS, 1,
  252.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  253.         PANEL_NOTIFY_PROC, next_playmode_default,
  254.         PANEL_CHOICE_STRINGS,
  255.             "Normal",
  256.             "Shuffle",
  257.             NULL,
  258.         PANEL_DEFAULT_VALUE, 0,
  259.         NULL);
  260.     put_down(ip->shuffle, ip->repeat, 0);
  261.  
  262.     ip->button3 = xv_create(ip->controls1, PANEL_BUTTON,
  263.         XV_HELP_DATA, "workman:button3",
  264.         PANEL_LABEL_STRING, "About...",
  265.         PANEL_NOTIFY_PROC, window1_button3_notify_callback,
  266.         NULL);
  267.  
  268.     ip->button2 = xv_create(ip->controls1, PANEL_BUTTON,
  269.         XV_HELP_DATA, "workman:button2",
  270.         PANEL_LABEL_STRING, "CD Info...",
  271.         PANEL_NOTIFY_PROC, window1_button2_notify_callback,
  272.         NULL);
  273.     
  274.     ip->button4 = xv_create(ip->controls1, PANEL_BUTTON,
  275.         XV_HELP_DATA, "workman:button4",
  276.         PANEL_LABEL_STRING, "Goodies...",
  277.         PANEL_NOTIFY_PROC, window1_button4_notify_callback,
  278.         NULL);
  279.  
  280.     /* Now we can figure out how wide the window should be. */
  281.     space = wid(ip->button2) + wid(ip->button3) + wid(ip->button4);
  282.     if (rig(ip->shuffle) > space)
  283.         xv_set(ip->controls1, XV_WIDTH, rig(ip->shuffle) + 7, NULL);
  284.     else
  285.     {
  286.         xv_set(ip->controls1, XV_WIDTH, space + 10, NULL);
  287.         xv_set(ip->shuffle, XV_X, space - wid(ip->shuffle) + 10, NULL);
  288.         xv_set(ip->repeat, XV_X, lef(ip->shuffle), NULL);
  289.         xv_set(ip->mode, XV_X, (lef(ip->shuffle) - rig(ip->volume) -
  290.             wid(ip->mode)) / 2 + rig(ip->volume), NULL);
  291.     }
  292.  
  293.     /* And knowing that, we can position the songpos slider. */
  294.     xv_set(ip->tracklen, XV_X, wid(ip->controls1) - wid(ip->tracklen) -
  295.         10, NULL);
  296.     xv_set(ip->songpos, PANEL_SLIDER_WIDTH, lef(ip->tracklen) -
  297.         lef(ip->songpos) - 20, NULL);
  298.  
  299.     ip->cdtimer = xv_create(ip->controls1, PANEL_MESSAGE,
  300.         XV_HELP_DATA, "workman:cdtimer",
  301.         PANEL_LABEL_STRING, "00:00",
  302.         XV_X, lef(ip->tracktimer), PANEL_LABEL_BOLD, FALSE, NULL);
  303.     put_down(ip->cdtimer, ip->volume, basic_spacing / 2 + 1);
  304.  
  305.     ip->cdlen = xv_create(ip->controls1, PANEL_MESSAGE,
  306.         XV_HELP_DATA, "workman:cdlen",
  307.         XV_Y, top(ip->cdtimer), XV_X, lef(ip->tracklen),
  308.         PANEL_LABEL_BOLD, FALSE,
  309.         NULL);
  310.  
  311.     ip->cdgauge = xv_create(ip->controls1, PANEL_GAUGE,
  312.         XV_HELP_DATA, "workman:cdgauge",
  313.         XV_X, lef(ip->songpos) - 2, XV_Y, top(ip->cdtimer) + 2,
  314.         PANEL_GAUGE_WIDTH, xv_get(ip->songpos, PANEL_SLIDER_WIDTH) - 5,
  315.         PANEL_TICKS, 0,
  316.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  317.         PANEL_DIRECTION, PANEL_HORIZONTAL,
  318.         PANEL_SHOW_RANGE, FALSE,
  319.         PANEL_MIN_VALUE, 0,
  320.         PANEL_MAX_VALUE, 100,
  321.         PANEL_VALUE, 0,
  322.         PANEL_INACTIVE, TRUE,
  323.         NULL);
  324.  
  325.     space = (wid(ip->controls1) - space) / 4;
  326.     xv_set(ip->button3, XV_X, space, XV_Y, bot(ip->cdtimer) +
  327.         basic_spacing, NULL);
  328.     xv_set(ip->button2, XV_X, rig(ip->button3) + space, XV_Y,
  329.         top(ip->button3), NULL);
  330.     xv_set(ip->button4, XV_X, rig(ip->button2) + space, XV_Y,
  331.         top(ip->button3), NULL);
  332.  
  333.     xv_set(ip->controls1, XV_HEIGHT, bot(ip->button2) + 5, NULL);
  334.     window_fit(ip->window1);
  335.  
  336.     PANEL_EACH_ITEM(ip->controls1, item)
  337.         xv_set(item, XV_KEY_DATA, INSTANCE, ip, NULL);
  338.     PANEL_END_EACH;
  339.  
  340.     return (ip);
  341. }
  342.  
  343. /*
  344.  * Set up the CD Info popup.
  345.  */
  346. popup1_objects *
  347. popup1_objects_init(ip, owner)
  348.     popup1_objects    *ip;
  349.     Xv_opaque        owner;
  350. {
  351.     int    space, totwid;
  352.     Panel_item item;
  353.  
  354.     if ((ip = (popup1_objects *) calloc(1,
  355.                 sizeof(window1_objects))) == NULL)
  356.         return (NULL);
  357.  
  358.     ip->popup1 = xv_create(owner, FRAME_CMD,
  359.         XV_KEY_DATA, INSTANCE, ip,
  360.         XV_LABEL, "CD Information",
  361.         XV_SHOW, FALSE,
  362.         FRAME_SHOW_FOOTER, FALSE,
  363.         FRAME_SHOW_RESIZE_CORNER, FALSE,
  364.         FRAME_CMD_PUSHPIN_IN, TRUE,
  365.         NULL);
  366.     xv_set(xv_get(ip->popup1, FRAME_CMD_PANEL), WIN_SHOW, FALSE, NULL);
  367.  
  368.     ip->controls2 = xv_create(ip->popup1, PANEL,
  369.         XV_KEY_DATA, INSTANCE, ip,
  370.         XV_HELP_DATA, "workman:controls2",
  371.         XV_X, 0,
  372.         XV_Y, 0,
  373.         XV_WIDTH, 10000,
  374.         XV_HEIGHT, 10000,
  375.         WIN_BORDER, FALSE,
  376.         NULL);
  377.  
  378.     ip->artist = xv_create(ip->controls2, PANEL_TEXT,
  379.         XV_HELP_DATA, "workman:artist",
  380.         XV_Y, 8,
  381.         PANEL_VALUE_DISPLAY_LENGTH, 30,
  382.         PANEL_VALUE_STORED_LENGTH, 80,
  383.         PANEL_LABEL_STRING, "Artist:",
  384.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  385.         PANEL_READ_ONLY, FALSE,
  386.         PANEL_NOTIFY_PROC, update_title,
  387.         NULL);
  388.  
  389.     ip->cdname = xv_create(ip->controls2, PANEL_TEXT,
  390.         XV_HELP_DATA, "workman:cdname",
  391.         XV_X, 10,
  392.         PANEL_VALUE_DISPLAY_LENGTH, 30,
  393.         PANEL_VALUE_STORED_LENGTH, 80,
  394.         PANEL_LABEL_STRING, "Disc Title:",
  395.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  396.         PANEL_READ_ONLY, FALSE,
  397.         PANEL_NOTIFY_PROC, update_title,
  398.         NULL);
  399.     put_down(ip->cdname, ip->artist, basic_spacing);
  400.  
  401.     xv_set(ip->artist, PANEL_VALUE_X, (int) xv_get(ip->cdname,
  402.         PANEL_VALUE_X), NULL);
  403.  
  404.     ip->tracklist = xv_create(ip->controls2, PANEL_LIST,
  405.         XV_HELP_DATA, "workman:tracklist",
  406.         XV_X, 4,
  407.         PANEL_LIST_DISPLAY_ROWS, 6,
  408.         PANEL_LIST_TITLE, "Tracks",
  409.         PANEL_LAYOUT, PANEL_VERTICAL,
  410.         PANEL_READ_ONLY, TRUE,
  411.         PANEL_CHOOSE_ONE, TRUE,
  412.         PANEL_CHOOSE_NONE, TRUE,
  413.         PANEL_INACTIVE, TRUE,
  414.         PANEL_NOTIFY_PROC, update_trackname,
  415.         NULL);
  416.     put_down(ip->tracklist, ip->cdname, basic_spacing);
  417.  
  418.     ip->trackname = xv_create(ip->controls2, PANEL_TEXT,
  419.         XV_HELP_DATA, "workman:trackname",
  420.         XV_X, 5,
  421.         PANEL_VALUE_DISPLAY_LENGTH, 35,
  422.         PANEL_VALUE_STORED_LENGTH, 500,
  423.         PANEL_LABEL_STRING, "Name:",
  424.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  425.         PANEL_INACTIVE, TRUE,
  426.         PANEL_READ_ONLY, FALSE,
  427.         PANEL_NOTIFY_PROC, name_entered,
  428.         NULL);
  429.     put_down(ip->trackname, ip->tracklist, basic_spacing);
  430.  
  431.     xv_set(ip->tracklist, PANEL_LIST_WIDTH, wid(ip->trackname) + 10, NULL);
  432.  
  433.     ip->trackoptions = xv_create(ip->controls2, PANEL_TOGGLE,
  434.         XV_HELP_DATA, "workman:trackoptions",
  435.         PANEL_CHOICE_NCOLS, 1,
  436.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  437.         PANEL_CHOICE_STRINGS,
  438.             "Continuation of previous track",
  439.             "Don't play this track",
  440.             NULL,
  441.         PANEL_VALUE, 0,
  442.         PANEL_INACTIVE, TRUE,
  443.         NULL);
  444.     put_down(ip->trackoptions, ip->trackname, 5);
  445.  
  446.     ip->whichvolume = xv_create(ip->controls2, PANEL_CHOICE,
  447.         PANEL_DISPLAY_LEVEL, PANEL_CURRENT,
  448.         XV_HELP_DATA, "workman:whichvolume",
  449.         PANEL_CHOICE_NROWS, 1,
  450.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  451.         PANEL_LABEL_STRING, "Default Volume for this",
  452.         PANEL_NOTIFY_PROC, set_which_volume,
  453.         PANEL_CHOICE_STRINGS,
  454.             "Disc",
  455.             "Track",
  456.             NULL,
  457.         PANEL_DEFAULT_VALUE, 0,
  458.         NULL);
  459.     put_down(ip->whichvolume, ip->trackoptions, 5);
  460.  
  461.     ip->defaultvolume = xv_create(ip->controls2, PANEL_SLIDER,
  462.         XV_HELP_DATA, "workman:defaultvolume",
  463.         PANEL_SLIDER_WIDTH, 2,
  464.         PANEL_TICKS, 0,
  465.         PANEL_DIRECTION, PANEL_HORIZONTAL,
  466.         PANEL_SLIDER_END_BOXES, FALSE,
  467.         PANEL_SHOW_RANGE, FALSE,
  468.         PANEL_SHOW_VALUE, FALSE,
  469.         PANEL_MIN_VALUE, 0,
  470.         PANEL_MAX_VALUE, 32,
  471.         PANEL_VALUE, 0,
  472.         PANEL_NOTIFY_PROC, set_default_volume,
  473.         NULL);
  474.  
  475.     ip->defaultspeaker = xv_create(ip->controls2, PANEL_MESSAGE,
  476.         XV_HELP_DATA, "workman:defaultspeaker",
  477.         PANEL_LABEL_STRING, "None",
  478.         PANEL_LABEL_BOLD, FALSE,
  479.         NULL);
  480.  
  481.     space = wid(ip->whichvolume) + wid(ip->defaultspeaker) * 2 +
  482.         wid(ip->defaultvolume) + 20;
  483.     if (space > wid(ip->tracklist))
  484.     {
  485.         xv_set(ip->controls2, XV_WIDTH, space + 10, NULL);
  486.         xv_set(ip->tracklist, PANEL_LIST_WIDTH, space + 3 -
  487.             wid(ip->tracklist) + (int) xv_get(ip->tracklist,
  488.             PANEL_LIST_WIDTH), NULL);
  489.     }
  490.     else
  491.     {
  492.         xv_set(ip->controls2, XV_WIDTH, wid(ip->tracklist) + 7, NULL);
  493.         space += 20;
  494.     }
  495.  
  496.     center_x(ip->trackoptions, ip->controls2);
  497.  
  498.     space = (wid(ip->controls2) - space) / 2;
  499.     xv_set(ip->whichvolume, XV_X, space, NULL);
  500.     xv_set(ip->defaultvolume, XV_X, rig(ip->whichvolume),
  501.         PANEL_SLIDER_WIDTH, wid(ip->defaultspeaker) * 2 - 15,
  502.         XV_Y, (top(ip->whichvolume) + bot(ip->whichvolume) -
  503.         hei(ip->defaultvolume)) / 2 + 2, NULL);
  504.     xv_set(ip->defaultspeaker, XV_X, rig(ip->defaultvolume) + 5,
  505.         XV_Y, top(ip->defaultspeaker) + hei(ip->defaultvolume) / 6,
  506.         NULL);
  507.  
  508.     ip->playmode = xv_create(ip->controls2, PANEL_CHOICE,
  509.         XV_HELP_DATA, "workman:playmode",
  510.         XV_X, lef(ip->whichvolume),
  511.         PANEL_CHOICE_NROWS, 1,
  512.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  513.         PANEL_CHOOSE_NONE, FALSE,
  514.         PANEL_LABEL_STRING, "Default Play Mode",
  515.         PANEL_CHOICE_STRINGS,
  516.             "Normal",
  517.             "Shuffle",
  518.             "From List",
  519.             NULL,
  520.         NULL);
  521.     put_down(ip->playmode, ip->defaultvolume, basic_spacing / 2);
  522.  
  523.     ip->autoplay = xv_create(ip->controls2, PANEL_TOGGLE,
  524.         XV_HELP_DATA, "workman:autoplay",
  525.         PANEL_CHOICE_NCOLS, 1,
  526.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  527.         PANEL_CHOICE_STRING, 0, "Play this CD automatically",
  528.         PANEL_VALUE, 0,
  529.         NULL);
  530.     put_down(ip->autoplay, ip->playmode, basic_spacing / 2);
  531.     center_x(ip->autoplay, ip->controls2);
  532.  
  533.     ip->button1 = xv_create(ip->controls2, PANEL_BUTTON,
  534.         XV_HELP_DATA, "workman:button1",
  535.         PANEL_LABEL_STRING, "Apply",
  536.         PANEL_NOTIFY_PROC, save_config,
  537.         NULL);
  538.     put_down(ip->button1, ip->autoplay, (basic_spacing * 3) / 2);
  539.     xv_set(ip->button1, XV_X, wid(ip->controls2) / 2 - wid(ip->button1) - 5,
  540.         NULL);
  541.  
  542.     ip->button8 = xv_create(ip->controls2, PANEL_BUTTON,
  543.         XV_HELP_DATA, "workman:button8",
  544.         XV_X, rig(ip->button1) + 10,
  545.         XV_Y, top(ip->button1),
  546.         PANEL_LABEL_STRING, "Reset",
  547.         PANEL_NOTIFY_PROC, cdinfo_reset,
  548.         NULL);
  549.  
  550.     ip->buttonpl = xv_create(ip->controls2, PANEL_BUTTON,
  551.         XV_HELP_DATA, "workman:buttonpl",
  552.         XV_Y, top(ip->button1),
  553.         PANEL_LABEL_STRING, "Playlists...",
  554.         PANEL_NOTIFY_PROC, popup1_buttonpl_notify_callback,
  555.         NULL);
  556.     xv_set(ip->buttonpl, XV_X, wid(ip->controls2) - wid(ip->buttonpl) - 10,
  557.         NULL);
  558.  
  559.     xv_set(ip->controls2, XV_HEIGHT, bot(ip->button1) + 5, NULL);
  560.     window_fit(ip->popup1);
  561.  
  562.     PANEL_EACH_ITEM(ip->controls2, item)
  563.         xv_set(item, XV_KEY_DATA, INSTANCE, ip, NULL);
  564.     PANEL_END_EACH;
  565.  
  566.     return (ip);
  567. }
  568.  
  569. /*
  570.  * Create the About window and its contents.
  571.  */
  572. about_objects *
  573. about_objects_init(ip, owner)
  574.     about_objects    *ip;
  575.     Xv_opaque        owner;
  576. {
  577.     Panel_item    item;
  578.     int        space;
  579.     Xv_opaque               sink_image, message7_image;
  580.     static unsigned short   sink_bits[] = {
  581. #include "bitmaps/sink0"
  582.     }, message7_bits[] = {
  583. #include "bitmaps/icon"
  584.     };
  585.  
  586.     if ((ip = (about_objects *) calloc(1,
  587.                 sizeof(about_objects))) == NULL)
  588.         return (NULL);
  589.  
  590.     ip->about = xv_create(owner, FRAME_CMD,
  591.         XV_KEY_DATA, INSTANCE, ip,
  592.         XV_LABEL, "About WorkMan",
  593.         XV_SHOW, FALSE,
  594.         FRAME_SHOW_FOOTER, FALSE,
  595.         FRAME_SHOW_RESIZE_CORNER, FALSE,
  596.         FRAME_CMD_PUSHPIN_IN, TRUE,
  597.         NULL);
  598.     xv_set(xv_get(ip->about, FRAME_CMD_PANEL), WIN_SHOW, FALSE, NULL);
  599.  
  600.     ip->controls3 = xv_create(ip->about, PANEL,
  601.         XV_KEY_DATA, INSTANCE, ip,
  602.         XV_HELP_DATA, "workman:controls3",
  603.         XV_X, 0,
  604.         XV_Y, 0,
  605.         WIN_BORDER, FALSE,
  606.         NULL);
  607.  
  608.     ip->message1 = xv_create(ip->controls3, PANEL_MESSAGE,
  609.         XV_Y, 8,
  610.         PANEL_LABEL_STRING, "WorkMan (Beta 3.0)",
  611.         PANEL_LABEL_BOLD, TRUE, NULL);
  612.     ip->message2 = xv_create(ip->controls3, PANEL_MESSAGE,
  613.         PANEL_LABEL_STRING, "\"The Civilized CD Player\"",
  614.         PANEL_LABEL_BOLD, FALSE, NULL);
  615.  
  616.     message7_image = xv_create(XV_NULL, SERVER_IMAGE,
  617.         SERVER_IMAGE_DEPTH, 1,
  618.         SERVER_IMAGE_BITS, message7_bits,
  619.         XV_WIDTH, 64,
  620.         XV_HEIGHT, 64,
  621.         NULL);
  622.     ip->message7 = xv_create(ip->controls3, PANEL_MESSAGE,
  623.         XV_KEY_DATA, INSTANCE, ip,
  624.         PANEL_LABEL_IMAGE, message7_image,
  625.         PANEL_LABEL_BOLD, TRUE,
  626.         NULL);
  627.  
  628.     sink_image = xv_create(XV_NULL, SERVER_IMAGE,
  629.         SERVER_IMAGE_DEPTH, 1,
  630.         SERVER_IMAGE_BITS, sink_bits,
  631.         XV_WIDTH, 64,
  632.         XV_HEIGHT, 64,
  633.         NULL);
  634.     ip->sink = xv_create(ip->controls3, PANEL_MESSAGE,
  635.         XV_HELP_DATA, "workman:sink",
  636.         PANEL_LABEL_IMAGE, sink_image,
  637.         PANEL_LABEL_BOLD, TRUE,
  638.         NULL);
  639.  
  640.     ip->message3 = xv_create(ip->controls3, PANEL_MESSAGE,
  641.         PANEL_LABEL_STRING, "Written by Steven Grimm",
  642.         PANEL_LABEL_BOLD, TRUE, NULL);
  643.     ip->message4 = xv_create(ip->controls3, PANEL_MESSAGE,
  644.         PANEL_LABEL_STRING, "koreth@Hyperion.COM",
  645.         PANEL_LABEL_BOLD, FALSE, NULL);
  646.     ip->message5 = xv_create(ip->controls3, PANEL_MESSAGE,
  647.         PANEL_LABEL_STRING, "Send mail if you'd like to be",
  648.         PANEL_LABEL_BOLD, FALSE, NULL);
  649.     ip->message6 = xv_create(ip->controls3, PANEL_MESSAGE,
  650.         PANEL_LABEL_STRING, "notified of future revisions!",
  651.         PANEL_LABEL_BOLD, FALSE, NULL);
  652.  
  653.     space = 0;
  654.     PANEL_EACH_ITEM(ip->controls3, item)
  655.         xv_set(item, XV_KEY_DATA, INSTANCE, ip, NULL);
  656.         if (wid(item) > space)
  657.             space = wid(item);
  658.     PANEL_END_EACH;
  659.  
  660.     space += 10;
  661.     xv_set(ip->controls3, XV_WIDTH, space, NULL);
  662.     center_x(ip->message1, ip->controls3);
  663.     center_x(ip->message2, ip->controls3);
  664.     center_x(ip->message3, ip->controls3);
  665.     center_x(ip->message4, ip->controls3);
  666.     center_x(ip->message5, ip->controls3);
  667.     center_x(ip->message6, ip->controls3);
  668.     xv_set(ip->message7, XV_X, space / 2 - wid(ip->message7) - 5, NULL);
  669.  
  670.     put_down(ip->message2, ip->message1, basic_spacing);
  671.     put_down(ip->message7, ip->message2, basic_spacing);
  672.     xv_set(ip->sink, XV_X, space / 2 + 5, XV_Y, top(ip->message7), NULL);
  673.     put_down(ip->message3, ip->sink, basic_spacing);
  674.     put_down(ip->message4, ip->message3, basic_spacing);
  675.     put_down(ip->message5, ip->message4, basic_spacing * 2);
  676.     put_down(ip->message6, ip->message5, basic_spacing);
  677.  
  678.     xv_set(ip->controls3, XV_HEIGHT, bot(ip->message6) + 5, NULL);
  679.     window_fit(ip->about);
  680.  
  681.     return (ip);
  682. }
  683.  
  684. /*
  685.  * Create the Goodies window and its contents.
  686.  */
  687. goodies_objects *
  688. goodies_objects_init(ip, owner)
  689.     goodies_objects    *ip;
  690.     Xv_opaque        owner;
  691. {
  692.     Panel_item    item;
  693.     Xv_opaque    phones_image;
  694.     static unsigned short phones_bits[] = {
  695. #include "bitmaps/phones0"
  696.     };
  697.     int        space;
  698.  
  699.     if ((ip = (goodies_objects *) calloc(1,
  700.                 sizeof(goodies_objects))) == NULL)
  701.         return (NULL);
  702.  
  703.     ip->goodies = xv_create(owner, FRAME_CMD,
  704.         XV_KEY_DATA, INSTANCE, ip,
  705.         XV_LABEL, "Goodies",
  706.         XV_SHOW, FALSE,
  707.         FRAME_SHOW_FOOTER, FALSE,
  708.         FRAME_SHOW_RESIZE_CORNER, FALSE,
  709.         FRAME_CMD_PUSHPIN_IN, TRUE,
  710.         NULL);
  711.     xv_set(xv_get(ip->goodies, FRAME_CMD_PANEL), WIN_SHOW, FALSE, NULL);
  712.  
  713.     ip->controls4 = xv_create(ip->goodies, PANEL,
  714.         XV_KEY_DATA, INSTANCE, ip,
  715.         XV_HELP_DATA, "workman:controls4",
  716.         XV_X, 0,
  717.         XV_Y, 0,
  718.         WIN_BORDER, FALSE,
  719.         NULL);
  720.  
  721.     ip->balance = xv_create(ip->controls4, PANEL_SLIDER,
  722.         XV_HELP_DATA, "workman:balance",
  723.         XV_Y, 6,
  724.         PANEL_SLIDER_WIDTH, basic_spacing * 5,
  725.         PANEL_TICKS, 3,
  726.         PANEL_LABEL_STRING, "Balance:",
  727.         PANEL_DIRECTION, PANEL_HORIZONTAL,
  728.         PANEL_SLIDER_END_BOXES, FALSE,
  729.         PANEL_SHOW_RANGE, FALSE,
  730.         PANEL_SHOW_VALUE, FALSE,
  731.         PANEL_MIN_VALUE, 0,
  732.         PANEL_MAX_VALUE, 20,
  733.         PANEL_VALUE, 10,
  734.         PANEL_NOTIFY_PROC, slide_balance,
  735.         NULL);
  736.  
  737.     phones_image = xv_create(XV_NULL, SERVER_IMAGE,
  738.         SERVER_IMAGE_DEPTH, 1,
  739.         SERVER_IMAGE_BITS, phones_bits,
  740.         XV_WIDTH, 16,
  741.         XV_HEIGHT, 22,
  742.         NULL);
  743.     ip->phones = xv_create(ip->controls4, PANEL_MESSAGE,
  744.         XV_HELP_DATA, "workman:phones",
  745.         XV_Y, 6,
  746.         PANEL_LABEL_IMAGE, phones_image,
  747.         PANEL_LABEL_BOLD, TRUE,
  748.         NULL);
  749.  
  750.     ip->timemode = xv_create(ip->controls4, PANEL_CHOICE,
  751.         XV_HELP_DATA, "workman:timemode",
  752.         PANEL_CHOICE_NROWS, 1,
  753.         PANEL_LAYOUT, PANEL_VERTICAL,
  754.         PANEL_CHOOSE_NONE, FALSE,
  755.         PANEL_LABEL_STRING, "Time display:",
  756.         PANEL_CHOICE_STRINGS,
  757.             "Elapsed",
  758.             "Remaining",
  759.             NULL,
  760.         PANEL_VALUE, 0,
  761.         NULL);
  762.     put_down(ip->timemode, ip->balance, basic_spacing);
  763.  
  764.     ip->playnewcds = xv_create(ip->controls4, PANEL_TOGGLE,
  765.         XV_HELP_DATA, "workman:playnewcds",
  766.         PANEL_CHOICE_NROWS, 1,
  767.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  768.         PANEL_NOTIFY_PROC, goodies_playnewcds_notify_callback,
  769.         PANEL_CHOICE_STRING, 0, "Auto-play unknown CDs",
  770.         PANEL_VALUE, 0,
  771.         NULL);
  772.     put_down(ip->playnewcds, ip->timemode, basic_spacing * 2);
  773.  
  774.     ip->abrepeat = xv_create(ip->controls4, PANEL_TOGGLE,
  775.         XV_HELP_DATA, "workman:abrepeat",
  776.         PANEL_CHOICE_NCOLS, 1,
  777.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  778.         PANEL_NOTIFY_PROC, goodies_abrepeat_notify_callback,
  779.         PANEL_CHOICE_STRING, 0, "Repeat section of CD:",
  780.         PANEL_VALUE, 0,
  781.         NULL);
  782.     put_down(ip->abrepeat, ip->playnewcds, basic_spacing * 2);
  783.  
  784.     ip->a = xv_create(ip->controls4, PANEL_BUTTON,
  785.         XV_HELP_DATA, "workman:a",
  786.         PANEL_LABEL_STRING, "Start",
  787.         PANEL_NOTIFY_PROC, section_start,
  788.         NULL);
  789.     put_down(ip->a, ip->abrepeat, basic_spacing);
  790.  
  791.     ip->alabel = xv_create(ip->controls4, PANEL_MESSAGE,
  792.         XV_HELP_DATA, "workman:alabel",
  793.         PANEL_LABEL_STRING, "Track: 00 Time: 00:00",
  794.         PANEL_LABEL_BOLD, FALSE,
  795.         PANEL_INACTIVE, TRUE,
  796.         NULL);
  797.     center_y(ip->alabel, ip->a);
  798.  
  799.     ip->b = xv_create(ip->controls4, PANEL_BUTTON,
  800.         XV_HELP_DATA, "workman:b",
  801.         PANEL_LABEL_STRING, "End",
  802.         PANEL_NOTIFY_PROC, section_end,
  803.         NULL);
  804.     put_down(ip->b, ip->a, basic_spacing / 2);
  805.  
  806.     ip->blabel = xv_create(ip->controls4, PANEL_MESSAGE,
  807.         XV_HELP_DATA, "workman:alabel", 
  808.         PANEL_LABEL_STRING, "Track: 00 Time: 00:00",
  809.         PANEL_LABEL_BOLD, FALSE, 
  810.         PANEL_INACTIVE, TRUE, 
  811.         NULL); 
  812.     center_y(ip->blabel, ip->b);
  813.  
  814.     ip->split = xv_create(ip->controls4, PANEL_BUTTON,
  815.         XV_HELP_DATA, "workman:splittrk",
  816.         PANEL_LABEL_STRING, "Split",
  817.         PANEL_NOTIFY_PROC, split_track,
  818.         NULL);
  819.     put_down(ip->split, ip->b, basic_spacing);
  820.  
  821.     ip->delete = xv_create(ip->controls4, PANEL_BUTTON,
  822.         XV_HELP_DATA, "workman:deletetrk",
  823.         PANEL_LABEL_STRING, "Delete",
  824.         PANEL_NOTIFY_PROC, delete_track,
  825.         PANEL_INACTIVE, TRUE,
  826.         NULL);
  827.     put_down(ip->delete, ip->b, basic_spacing);
  828.  
  829.     ip->indexscan = xv_create(ip->controls4, PANEL_BUTTON,
  830.         XV_HELP_DATA, "workman:indexscan",
  831.         PANEL_LABEL_STRING, "Scan for index marks",
  832.         PANEL_NOTIFY_PROC, index_scan,
  833.         NULL);
  834.     put_down(ip->indexscan, ip->split, basic_spacing);
  835.  
  836.     space = wid(ip->a) + wid(ip->alabel) + basic_spacing;
  837.     PANEL_EACH_ITEM(ip->controls4, item)
  838.         xv_set(item, XV_KEY_DATA, INSTANCE, ip, NULL);
  839.         if (wid(item) > space)
  840.             space = wid(item);
  841.     PANEL_END_EACH;
  842.  
  843.     space += 10;
  844.     xv_set(ip->controls4, XV_WIDTH, space, XV_HEIGHT,
  845.         bot(ip->indexscan) + 5, NULL);
  846.     window_fit(ip->goodies);
  847.  
  848.     center_x(ip->timemode, ip->controls4);
  849.     center_x(ip->playnewcds, ip->controls4);
  850.     center_x(ip->abrepeat, ip->controls4);
  851.     xv_set(ip->balance, XV_X, space / 2 - (wid(ip->balance) +
  852.         wid(ip->phones) + basic_spacing) / 2, NULL);
  853.     put_right(ip->phones, ip->balance, basic_spacing);
  854.     xv_set(ip->a, XV_X, space / 2 - (wid(ip->a) + wid(ip->alabel) +
  855.         basic_spacing) / 2, NULL);
  856.     put_right(ip->alabel, ip->a, basic_spacing);
  857.     center_x(ip->b, ip->a);
  858.     xv_set(ip->blabel, XV_X, lef(ip->alabel), NULL);
  859.  
  860.     space = wid(ip->split) + wid(ip->delete) + basic_spacing * 3;
  861.     space = (wid(ip->controls4) - space) / 2;
  862.     xv_set(ip->split, XV_X, space, NULL);
  863.     put_right(ip->delete, ip->split, basic_spacing * 2);
  864.  
  865.     center_x(ip->indexscan, ip->controls4);
  866.  
  867.     return (ip);
  868. }
  869.  
  870. /*
  871.  * Create the menu for the Playlists popup.
  872.  */
  873. Xv_opaque
  874. trackmenu_create(ip, owner)
  875.     caddr_t         ip;
  876.     Xv_opaque       owner;
  877. {
  878.     Xv_opaque       obj;
  879.  
  880.     obj = xv_create(XV_NULL, MENU_COMMAND_MENU,
  881.         XV_KEY_DATA, INSTANCE, ip,
  882.         MENU_TITLE_ITEM, owner ? "" : "Tracks",
  883.         MENU_GEN_PIN_WINDOW, owner, "Tracks",
  884.         NULL);
  885.     return obj;
  886. }
  887.  
  888. /*
  889.  * Create the Playlists window and its contents.
  890.  */
  891. plpopup_objects *
  892. plpopup_objects_init(ip, owner)
  893.     plpopup_objects    *ip;
  894.     Xv_opaque        owner;
  895. {
  896.     Panel_item    item;
  897.     int        space;
  898.  
  899.     if ((ip = (plpopup_objects *) calloc(1,
  900.                 sizeof(plpopup_objects))) == NULL)
  901.         return (NULL);
  902.  
  903.     ip->plpopup = xv_create(owner, FRAME_CMD,
  904.         XV_KEY_DATA, INSTANCE, ip,
  905.         XV_LABEL, "Playlists",
  906.         XV_SHOW, FALSE,
  907.         FRAME_SHOW_FOOTER, FALSE,
  908.         FRAME_SHOW_RESIZE_CORNER, FALSE,
  909.         FRAME_CMD_PUSHPIN_IN, FALSE,
  910.         NULL);
  911.     xv_set(xv_get(ip->plpopup, FRAME_CMD_PANEL), WIN_SHOW, FALSE, NULL);
  912.  
  913.     ip->controls5 = xv_create(ip->plpopup, PANEL,
  914.         XV_KEY_DATA, INSTANCE, ip,
  915.         XV_HELP_DATA, "workman:controls5",
  916.         XV_X, 0,
  917.         XV_Y, 0,
  918.         WIN_BORDER, FALSE,
  919.         NULL);
  920.  
  921.     ip->playlists = xv_create(ip->controls5, PANEL_LIST,
  922.         XV_HELP_DATA, "workman:playlists",
  923.         XV_X, 6,
  924.         XV_Y, 8,
  925.         PANEL_LIST_WIDTH, basic_spacing * 22,
  926.         PANEL_LIST_DISPLAY_ROWS, 4,
  927.         PANEL_LIST_TITLE, "Playlists",
  928.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  929.         PANEL_READ_ONLY, TRUE,
  930.         PANEL_CHOOSE_ONE, TRUE,
  931.         PANEL_CHOOSE_NONE, FALSE,
  932.         PANEL_NOTIFY_PROC, switch_playlists,
  933.         NULL);
  934.  
  935.     ip->listname = xv_create(ip->controls5, PANEL_TEXT,
  936.         XV_HELP_DATA, "workman:listname",
  937.         XV_Y, 8 + basic_spacing * 2,
  938.         PANEL_VALUE_DISPLAY_LENGTH, 12,
  939.         PANEL_VALUE_STORED_LENGTH, 20,
  940.         PANEL_LABEL_STRING, "Name:",
  941.         PANEL_LAYOUT, PANEL_HORIZONTAL,
  942.         PANEL_READ_ONLY, FALSE,
  943.         NULL);
  944.     put_right(ip->listname, ip->playlists, basic_spacing);
  945.  
  946.     ip->button7 = xv_create(ip->controls5, PANEL_BUTTON,
  947.         XV_HELP_DATA, "workman:button7",
  948.         PANEL_LABEL_STRING, "Create new list",
  949.         PANEL_NOTIFY_PROC, plpopup_button7_notify_callback,
  950.         NULL);
  951.     put_down(ip->button7, ip->listname, basic_spacing);
  952.     center_x(ip->button7, ip->listname);
  953.  
  954.     ip->button6 = xv_create(ip->controls5, PANEL_BUTTON,
  955.         XV_HELP_DATA, "workman:button6",
  956.         PANEL_LABEL_STRING, "Rename this list",
  957.         PANEL_NOTIFY_PROC, rename_playlist,
  958.         NULL);
  959.     put_down(ip->button6, ip->button7, basic_spacing);
  960.     center_x(ip->button6, ip->listname);
  961.  
  962.     ip->button5 = xv_create(ip->controls5, PANEL_BUTTON,
  963.         XV_HELP_DATA, "workman:button5",
  964.         PANEL_LABEL_STRING, "Delete this list",
  965.         PANEL_NOTIFY_PROC, delete_playlist,
  966.         NULL);
  967.     xv_set(ip->button5, XV_Y, bot(ip->playlists) - hei(ip->button5), NULL);
  968.     center_x(ip->button5, ip->listname);
  969.  
  970.     ip->playlist = xv_create(ip->controls5, PANEL_LIST,
  971.         XV_HELP_DATA, "workman:playlist",
  972.         XV_X, lef(ip->playlists),
  973.         PANEL_LIST_WIDTH, rig(ip->listname) - lef(ip->playlists),
  974.         PANEL_LIST_DISPLAY_ROWS, 5,
  975.         PANEL_LIST_TITLE, "Playlist (add tracks from popup menu)",
  976.         PANEL_LAYOUT, PANEL_VERTICAL,
  977.         PANEL_READ_ONLY, TRUE,
  978.         PANEL_CHOOSE_ONE, TRUE,
  979.         PANEL_CHOOSE_NONE, TRUE,
  980.         PANEL_INACTIVE, TRUE,
  981.         PANEL_ITEM_MENU,
  982.             trackmenu_create((caddr_t) ip, ip->plpopup),
  983.         PANEL_NOTIFY_PROC, playlist_notify,
  984.         NULL);
  985.     put_down(ip->playlist, ip->playlists, basic_spacing);
  986.  
  987.     xv_set(ip->controls5, XV_WIDTH, rig(ip->playlist) + 2, NULL);
  988.  
  989.     ip->delete = xv_create(ip->controls5, PANEL_BUTTON,
  990.         XV_HELP_DATA, "workman:delete",
  991.         PANEL_LABEL_STRING, "Delete track",
  992.         PANEL_INACTIVE, TRUE,
  993.         PANEL_NOTIFY_PROC, delete_from_playlist,
  994.         NULL);
  995.     put_down(ip->delete, ip->playlist, basic_spacing);
  996.     center_x(ip->delete, ip->controls5);
  997.  
  998.     xv_set(ip->controls5, XV_HEIGHT, bot(ip->delete) + 5, NULL);
  999.     window_fit(ip->plpopup);
  1000.  
  1001.     PANEL_EACH_ITEM(ip->controls5, item)
  1002.         xv_set(item, XV_KEY_DATA, INSTANCE, ip, NULL);
  1003.     PANEL_END_EACH;
  1004.  
  1005.     return (ip);
  1006. }
  1007.