home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / cdedit / cdedit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  16.8 KB  |  477 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/collab/cdEdit/RCS/cdEdit.c,v 2.11 92/05/14 16:40:54 drapeau Exp $ */
  25. /* $Log:    cdEdit.c,v $
  26.  * Revision 2.11  92/05/14  16:40:54  drapeau
  27.  * * Removed code that modifies size of the cdEdit remote control panel.
  28.  *   This code was a workaround for an error in OpenWindows 2.0, which has
  29.  *   since been fixed.
  30.  * * Made slight formatting changes to better conform to coding standards.
  31.  * 
  32.  * Revision 2.10  92/01/03  17:47:27  drapeau
  33.  * Modified cdInit() so that call to Browse() uses "0" instead of "NULL",
  34.  * to accommodate new ANSI-C definition of NULL as (void*)0.
  35.  * 
  36.  * Revision 2.0  91/10/06  21:01:02  chua
  37.  * Update to version 2.0
  38.  * 
  39.  * Revision 1.37  91/09/18  17:26:18  chua
  40.  * Removed the hard path for the include files.
  41.  * 
  42.  * Revision 1.36  91/09/17  11:41:12  chua
  43.  * In InitializeCD, do not stop the cd player when initializing.  Reset the
  44.  * volume only if the device is being opened for the first time.
  45.  * 
  46.  * Revision 1.35  91/09/16  14:19:52  chua
  47.  * In CheckChanges, initialize result to NOTICE_NO, so that if there were no changes,
  48.  * NOTICE_NO will be returned as the return value.
  49.  * 
  50.  * Revision 1.34  91/09/10  13:33:52  chua
  51.  * Changed the AlertMessage a little in InitializeCD.
  52.  * 
  53.  * Revision 1.33  91/09/04  11:34:26  chua
  54.  * In main(), use strcpy to assign senderPort.hostName instead of just using "=".
  55.  * 
  56.  * In QuitNotify, check that the CD device is open before attempting to stop the CD or eject
  57.  * it.
  58.  * 
  59.  * 
  60.  * Revision 1.32  91/09/03  15:33:48  chua
  61.  * Include the getopt.h file from the collab directory.
  62.  * 
  63.  * Revision 1.31  91/09/03  13:45:45  chua
  64.  * In main(), call ConnectPortManager to make a connection with the port manager.
  65.  * In QuitNotify, check that there is a valid sender before attempting to perform
  66.  * a DestroyReceiver.
  67.  * A new function, InitializeCD, which will try to open the CD device (if necessary),
  68.  * and check if there is a disc inserted.  If so, it will initialize the variables
  69.  * connected with the CD (such as total tracks etc).
  70.  * 
  71.  * Removed the options pop-up window, which is replaced by a menu button.
  72.  * 
  73.  * A new function, UpdateHeader, which will update the header of the edit popup 
  74.  * window to indicate which file is currently being edited and its status (whether
  75.  * modified or not).
  76.  * 
  77.  * A new function, AlertMessage, which puts up a notice prompt displaying the
  78.  * messages passed in as the parameters.
  79.  * 
  80.  * Revision 1.3  91/08/13  17:43:47  chua
  81.  * *** empty log message ***
  82.  * 
  83.  * Revision 1.2  91/07/10  11:32:06  chua
  84.  * Added a QuitNotify interpose function which will be called when the
  85.  * user hits the Quit button or when the frame's quit menu is chosen.
  86.  * This interpose function will stop the player and eject the disc, as well
  87.  * as unregister the application from the Port Manager.
  88.  * 
  89.  * Revision 1.1  91/07/09  16:45:12  chua
  90.  * In the main program, after the xv_main_loop line, check that the quit button has been
  91.  * pressed.  If not, this means that the user has quit using the frame quit button.
  92.  * In that case, call the quit procedure to eject the disc and deregister from the
  93.  * Port Manager.
  94.  * 
  95.  * Revision 1.0  91/07/08  13:45:28  chua
  96.  * Initial revision
  97.  *  */
  98.  
  99. static char cdEditrcsid[] = "$Header: /Source/Media/collab/cdEdit/RCS/cdEdit.c,v 2.11 92/05/14 16:40:54 drapeau Exp $";
  100.  
  101. #include "main.h"
  102. #include <getopt.h>
  103. #include <xview/rect.h>
  104. #include <Browse.h>
  105.  
  106. char *startFilename;
  107. int editnum;                                /* current edit */
  108. int lines;                                /* number of lines in the edit list */
  109. int change;                                /* indicates if unsaved changes exist in the edit list */
  110. char *cdfilename;                            /* Stores the full path name of the file currently being edited */
  111. int offset;                                /* Keeps track of the offset into the current edit to be played */
  112. Msf offsetStart;                            /* Starting time of the offset */
  113. int playerState;                            /* current state of the cdEdit player */
  114. int discInPlayer;                            /* Indicates whether there is a disc in the player */
  115. Sender* sender;                                /* Sender and receiver to send and receive messages to other applications */
  116. Receiver* receiver;
  117. Port senderPort;
  118. int ReceiverPortNumber;                            /* Port number for the cdEdit to listen on */
  119.  
  120. static struct itimerval timer;                        /* Timer to update the playing time display */
  121. static char deviceOpen = 0;                        /* Flag to indicate if the cd device is open */
  122.  
  123. /*
  124.  * Instance XV_KEY_DATA key.  An instance is a set of related
  125.  * user interface objects.  A pointer to an object's instance
  126.  * is stored under this key in every object.  This must be a
  127.  * global variable.
  128.  */
  129. Attr_attribute    INSTANCE;
  130.  
  131. void main(argc, argv)
  132.      int        argc;
  133.      char        **argv;
  134. {
  135.   static DispatchTable  DT = 
  136.   {
  137.     OpenDoc,
  138.     GetDoc,
  139.     GetSelection,
  140.     SetSelection,
  141.     PerformSelection,
  142.     NULL,
  143.     NULL,
  144.     NULL,
  145.     NULL,
  146.     NULL,
  147.     NULL,
  148.     HaltSelection,
  149.     PauseSelection,
  150.     ResumeSelection,
  151.     HideApplication,
  152.     ShowApplication,
  153.     GetAppIcon,
  154.     };
  155.   
  156.   xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0);            /* Initialize XView */
  157.   INSTANCE = xv_unique_key();
  158.  
  159.   sender = NULL;
  160.   receiver = NULL;
  161.   senderPort.hostName = (char *) malloc(MAXPATHLEN);
  162.   strcpy(senderPort.hostName, "localhost");                /* Set the default values for hostname and port number and then */
  163.   senderPort.portNumber = PortMgrPortNumber;
  164.   ReceiverPortNumber = AnyPort;                        /* Check command line to see if user has specified any of these */
  165.   cdfilename = (char *) malloc(MAXPATHLEN);                /* Allocate space for the full path name of the file */
  166.   strcpy(cdfilename, "untitled");
  167.   CheckOptions(argc, argv);
  168.   BuildDispatchTable (&DT);
  169.   cdInit();                                /* Initialize the variables and cd player */
  170.   xv_set(cdEdit_PortManagerPopup->NewPortManagerText
  171.      , PANEL_VALUE, senderPort.hostName, NULL);
  172.   strcpy(senderPort.hostName, "(None)");                /* Reset to (None) */
  173.   ConnectPortManager(cdEdit_PortManagerPopup->ConnectPortManagerButton,
  174.              NULL);
  175.   (void) notify_enable_rpc_svc (TRUE);
  176.   
  177.   timer.it_value.tv_sec = 1;                        /* Start the timer for managing the playing time display */
  178.   timer.it_value.tv_usec = 0;
  179.   timer.it_interval.tv_sec = 1;
  180.   timer.it_interval.tv_usec = 0;
  181.   notify_set_itimer_func(cdEdit_window1->window1, TimerNotify, 
  182.              ITIMER_REAL, &timer, NULL);
  183.   xv_main_loop(cdEdit_window1->window1);                /* Turn control over to Xview */
  184.   exit(0);
  185. }
  186.  
  187. /* 
  188.  * This is the interpose function for the frame destroy procedure.  It is called when the quit button is pressed, or when the frame's "Quit"
  189.  * menu selection is chosen.
  190.  * The frame destroying process happens in two phases (meaning this function will be called twice).  The first time it is called, status =
  191.  * DESTROY_CHECKING (this is done automatically by XView).  At this point, the interpose function can choose to veto the destruction, or 
  192.  * let it proceed to phase two, where the actual destruction occurs.
  193.  * If destruction is to proceed, the CD player will be stopped and any CD in it will be ejected.  The CD device is then closed, and the
  194.  * application unregisters itself from the port manager.
  195.  */
  196. Notify_value QuitNotify(client, status)
  197.      Notify_client client;
  198.      Destroy_status status;
  199. {
  200.   if (status == DESTROY_CHECKING)                    /* Check to see if we really want to destroy the frame */
  201.   {
  202.     if (CheckChanges(QuitcdEdit) == NOTICE_YES)                /* check if unsaved changes exist */
  203.     {
  204.       return notify_veto_destroy(client);
  205.     }
  206.   }
  207.   else                                    /* Second phase. Proceed to destroy */
  208.   {
  209.     notify_set_itimer_func(cdEdit_window1->window1, NOTIFY_FUNC_NULL, /* Turn off the timer */
  210.                ITIMER_REAL, NULL, NULL);
  211.     if (deviceOpen == 1) 
  212.     {
  213.       if (discInPlayer == 1)
  214.       {
  215.     cdrom_stop(fd);        
  216.     cdrom_eject (fd);
  217.       }
  218.       close(fd);
  219.     }
  220.     if (sender && receiver)                        /* Destroy sender and receiver, and disconnect from port manager */
  221.     {
  222.       DestroyReceiver(sender, receiver);
  223.     }
  224.     return notify_next_destroy_func(client, status);
  225.   }
  226.   return NOTIFY_DONE;
  227.  
  228. /*
  229.  * This function will initialize the CD-ROM player by trying to open the device (if it is not already open), and then checking if there is a CD
  230.  * inserted.
  231.  */
  232. int InitializeCD()
  233. {
  234.   if (deviceOpen == 0) 
  235.   {
  236.     if ((fd = open("/dev/rsr0", O_RDONLY | O_EXCL)) == -1)       
  237.     {                                    /* Initialization failed */
  238.       xv_set(cdEdit_window1->window1, 
  239.          FRAME_RIGHT_FOOTER, "Failed to initialize player",
  240.          NULL);
  241.       return Error;
  242.     }    
  243.     cdrom_volume(fd, 185, 185);                        /* Set the CD volume level */
  244.   }
  245.   deviceOpen = 1;
  246.   if ((toc = (Toc) ReadDiscToc()) == (Toc)NULL)             /* Read the table of contents */
  247.   {
  248.     return Error;
  249.   }
  250.   if (editTotalTracks != 0 && 
  251.       (editTotalTracks != toc->size || editmin != toc->total_msf->min || editsec != toc->total_msf->sec))
  252.   {                                    /* Check if the disc matches the currently loaded edit document (if any) */
  253.     AlertMessage("This disc is not compatible with the current document.",
  254.          "Please try another disc, or close the current document first.");
  255.     Eject(NULL, NULL);
  256.     return Error;
  257.   }
  258.   numTracks = toc->size;
  259.   startTrack = 1;
  260.   endTrack = toc->size;
  261.   playerState = StopMode;
  262.   UpdateTime(Whole);                            /* update the time field to the total disc time */
  263.   discInPlayer = 1;
  264.   DimButtons(FALSE);
  265.   xv_set(cdEdit_window1->window1, 
  266.      FRAME_RIGHT_FOOTER, "",
  267.      NULL);
  268.   return OK;
  269. }
  270.  
  271. /* 
  272.  * This function initializes all the global variables used, the position of the popup windows and also the CD-ROM player itself.
  273.  */
  274. void cdInit() 
  275. {
  276.   Rect rect;
  277.   
  278.   cdEdit_window1 = cdEdit_window1_objects_initialize(NULL, NULL);   /* Initialize all the windows */
  279.   cdEdit_EditPopup = cdEdit_EditPopup_objects_initialize(NULL, cdEdit_window1->window1);
  280.   cdEdit_PreviewPopup = cdEdit_PreviewPopup_objects_initialize(NULL, cdEdit_window1->window1);
  281.   cdEdit_InfoPopup = cdEdit_InfoPopup_objects_initialize(NULL, cdEdit_window1->window1);
  282.   cdEdit_PortManagerPopup = ConnectPortManager_PortManagerPopup_objects_initialize(NULL, cdEdit_window1->window1);
  283.   notify_interpose_destroy_func(cdEdit_window1->window1, QuitNotify); /* Interpose the destroy function */
  284.   CreateBrowse(OpenHandler, SaveHandler, cdEdit_window1->window1);
  285.   frame_get_rect(cdEdit_window1->window1, &rect);        
  286.   rect.r_left = 100;                            /* Set the position of the main frame (remote controller) */
  287.   rect.r_top = 250;
  288.   frame_set_rect(cdEdit_window1->window1, &rect);        
  289.   xv_set(cdEdit_EditPopup->EditPopup,                    /* Set the position of the edit popup window */
  290.      XV_X, 350,
  291.      XV_Y, 250,
  292.      FRAME_DONE_PROC, EditDone,
  293.      NULL);
  294.   xv_set(cdEdit_PreviewPopup->PreviewPopup,                /* Set the position of the preview popup window */
  295.      XV_X, 850,
  296.      XV_Y, 525,
  297.      NULL);
  298.   xv_set(cdEdit_InfoPopup->InfoPopup,                    /* Set the position of the info popup window */
  299.      XV_X, 250,
  300.      XV_Y, 250,
  301.      NULL);
  302.   xv_set(cdEdit_PortManagerPopup->PortManagerPopup,            /* Set the position of the info popup window */
  303.      XV_X, 250,
  304.      XV_Y, 250,
  305.      NULL);
  306.   xv_set(cdEdit_window1->VolumeSlider,                    /* Set the value of the volume slider so that it is in the middle */
  307.      PANEL_NOTIFY_LEVEL, PANEL_ALL, 
  308.      PANEL_VALUE, 180, 
  309.      NULL);
  310.   xv_set(cdEdit_window1->BalanceSlider, PANEL_NOTIFY_LEVEL, PANEL_ALL, NULL);
  311.   xv_set(cdEdit_window1->DurationSlider, PANEL_NOTIFY_LEVEL, PANEL_ALL, NULL);
  312.   xv_set(cdEdit_PreviewPopup->PreviewTimeText, PANEL_VALUE, 4, NULL);
  313.  
  314.   xv_set(cdEdit_EditPopup->ModifyButton,                /* Set the modify, delete buttons to inactive */
  315.      PANEL_INACTIVE, TRUE, NULL);
  316.   xv_set(cdEdit_EditPopup->DeleteButton,
  317.      PANEL_INACTIVE, TRUE, NULL);
  318.   font = (Xv_font *) xv_find(cdEdit_EditPopup->EditPopup, FONT,        /* Set the font for the panel list */
  319.                  FONT_FAMILY, FONT_FAMILY_LUCIDA_FIXEDWIDTH,
  320.                  FONT_STYLE,  FONT_STYLE_NORMAL,
  321.                  FONT_SIZE, 12, NULL);
  322.   xv_set(cdEdit_window1->window1, 
  323.      FRAME_RIGHT_FOOTER, "No disc in player",
  324.      NULL);
  325.   discInPlayer = 0;
  326.   DimButtons(TRUE);
  327.   playerState = Nothing;
  328.   InitializeCD();
  329.   editmin = 0;
  330.   editsec = 0;
  331.   editTotalTracks = 0;
  332.   lines = 0;
  333.   editnum = -1;
  334.   displayType = Relative;
  335.   offset = 0;
  336.   UpdateHeader(0);
  337.   if (strcmp(cdfilename, "untitled") != 0)                /* Check if a file is to be loaded */
  338.   {
  339.     Browse(cdfilename, BrowseCheckOpen, 0, "#CD Edit Document#", "cdEdit");
  340.   }
  341. }
  342.  
  343. /* 
  344.  * This function parses the command line and retrieves all the known options and their arguments.
  345.  * Currently, the two options are hostname and portnumber.
  346.  * After parsing the options, the variable optind will point to the start of those non-option arguments.  In this case, it will be the filename to be
  347.  * loaded.  At present, only one filename will be handled.  So if there are multiple filenames typed, the last one will be loaded.
  348.  */
  349. void CheckOptions(argc, argv)
  350.      int     argc;
  351.      char     **argv;
  352. {
  353.   int optionChar;  
  354.   int option_index = 0;
  355.   static struct option long_options[] =
  356.   {
  357.     {"hostname", 1, 0, 'h'},        
  358.     {"portnumber", 1, 0, 'p'},
  359.     {0, 0, 0, 0}
  360.   };
  361.  
  362.   while (1)                                /* Start parsing all known options */
  363.   {
  364.     optionChar = getopt_long_only (argc, argv, "h:p:",
  365.                   long_options, &option_index);
  366.     if (optionChar == EOF)                        /* Done with all known options */
  367.     {
  368.       break;
  369.     }
  370.     switch (optionChar)
  371.     {
  372.      case 'h':
  373.       if (optarg) 
  374.       {
  375.     strcpy (senderPort.hostName, optarg);
  376.       }
  377.       break;
  378.      case 'p':
  379.       if (optarg) 
  380.       {
  381.     ReceiverPortNumber = atoi(optarg);
  382.       }
  383.       break;
  384.      default:
  385.       break;
  386.     }
  387.   }
  388.   if (optind < argc)                            /* Check if a filename has been specified */
  389.   {
  390.     strcpy (cdfilename, argv[optind]);
  391.   }
  392. }
  393.  
  394. /*
  395.  * Checks if there are any unsaved changes to the current cdEdit document.  If so, it warns the user by using a notice prompt, and
  396.  * gives the user the choice of either going ahead with the operation or cancelling the operation.
  397.  */
  398. int CheckChanges (optype)
  399.      int     optype;
  400. {
  401.   int     result;
  402.   char     buf[100], buf1[100];
  403.  
  404.   result = NOTICE_NO;
  405.   if (change)                                /* Perform the following only if there are unsaved changes */
  406.   {  
  407.     switch (optype) 
  408.     {
  409.      case LoadFile :                            /* Loading a new document */
  410.       sprintf (buf, "Loading a file will cause all changes to be lost.");
  411.       sprintf (buf1, "Go ahead and load the file?");
  412.       break;
  413.      case DeleteAll :                            /* Clearing the edit list */
  414.       sprintf (buf, "This clear all operation will cause all changes to be lost.");
  415.       sprintf (buf1, "Go ahead and clear the cdEdit edit list");
  416.       break;
  417.      case QuitcdEdit :                            /* Quit the cdEdit application */
  418.       sprintf (buf, "Quiting the cdEdit application will cause all changes to be lost.");
  419.       sprintf (buf1, "Go ahead and quit?");
  420.       break;
  421.      case CloseFile :                            /* Closing a file */
  422.       sprintf (buf, "Closing the file will cause unsaved changes to be lost.");
  423.       sprintf (buf1, "Go ahead and quit?");
  424.       break;
  425.      default : 
  426.       break;
  427.     }
  428.     result = notice_prompt(cdEdit_window1->window1, NULL,
  429.                NOTICE_MESSAGE_STRINGS,
  430.                "Unsaved changes exist in the current cdEdit edit list.",
  431.                buf, buf1, NULL,
  432.                NOTICE_BUTTON_NO,       "Yes",
  433.                NOTICE_BUTTON_YES,      "No",
  434.                NULL);
  435.   }
  436.   return (result);
  437. }
  438.  
  439. /*
  440.  * This function will update the header of the cdEdit Edit Popup window to either the current document name, or untitled.
  441.  * It will also specify the status of the file, if it has been modified.
  442.  */
  443. void UpdateHeader(modified)
  444.      int modified;
  445. {
  446.   char label[100];
  447.   
  448.   if (modified) 
  449.   {
  450.     sprintf(label, "CD Edit Document :  \"%s\" (modified)", cdfilename);
  451.   }
  452.   else 
  453.   {
  454.     sprintf(label, "CD Edit Document :  \"%s\" ", cdfilename);
  455.   }
  456.   xv_set(cdEdit_EditPopup->EditPopup,                    /* Set the edit popup header */
  457.      XV_LABEL, label,
  458.      NULL);
  459. }
  460.  
  461. /*
  462.  * This function will displace a notice prompt, which is used to alert the user that something is wrong.
  463.  */
  464. void AlertMessage(msg1, msg2)
  465.      char *msg1;
  466.      char *msg2;
  467. {
  468.   notice_prompt(cdEdit_window1->window1, NULL,
  469.         NOTICE_MESSAGE_STRINGS,
  470.         msg1, msg2,
  471.         NULL,
  472.         NOTICE_BUTTON, "OK", 100,
  473.         NULL);
  474.   
  475. }
  476.