/* The Uglist Code in the World (tm) */
/* Xmitsumi 0.75 Liem Bahneman */
/* roland@cac.washington.edu */
#include <Xm/RowColumn.h>
#include <Xm/LabelG.h>
#include <Xm/Label.h>
#include <Xm/PushBG.h>
#include <Xm/Separator.h>
#include <Xm/SeparatoG.h>
#include <Xm/DrawnB.h>
#include <Xm/Frame.h>
#include <Xm/MessageB.h>
#include <Xm/Form.h>
#include <Xm/Xm.h>
#include <Xm/CascadeBG.h>
#include <Xm/CascadeB.h>
#include <Xm/MainW.h>
#include <Xm/DialogS.h>
#include <Xm/Text.h>

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/types.h>
#include <fcntl.h>     
#include <unistd.h>
#include <mntent.h>
#include <string.h>
#include <errno.h>
#include <linux/cdrom.h>

/* all the button icons */
#include "bitmaps.h"

/* your CDrom device */
const char cdrom[]="/dev/mcd";

Arg args[0];
Arg menuargs[1];

int current_track = 1;

XmString status, track_number, time;

int i,f, start_track, cdid;
int repeat_stat = 1;
int shuffle_stat = 0;
int shuffling = 0;

unsigned long toggles_set;
struct cdrom_tochdr tochdr;
struct cdrom_tocentry tocentry;
struct cdrom_ti ti;
struct cdrom_subchnl subchnl;
struct mntent *mnt;

Widget status_indicator;
Widget track_indicator;
Widget rowcol1, buttonform;
int read_cdrom();
int set_status();

Pixel fg, bg;
Pixmap playbutton, stopbutton, rewindbutton, pausebutton, fastforwardbutton;
Pixmap exitbutton, xcd_icon, repeatybutton, repeatnbutton, shuffleybutton;
Pixmap shufflenbutton;

FILE *fp;

int main(int argc, char *argv[])
{

/* Declare all the widgets */
  XtAppContext app;

  XtWorkProcId work_id2;

/* general widgets */
  Widget toplevel, rew, play, stop, ff, pause, repeat, shuffle; 
  Widget separator1, separator2;
  Widget topform, track_indicator_label, rowcol3;
  Widget status_indicator_label;

/* menu widgets */
  Widget main_window, menubar, filepulldown;
  Widget filemenu, filemenu_separator, exit_choice;
  Widget about_choice;

/* declare function */
  void do_play(),do_stop(),do_rew(),do_ff(),do_pause(),do_update();
  void do_repeat(), do_shuffle();
  void do_about(), do_exit();
  int get_track(), get_status();

  int set_status();
  extern int read_cdrom();


/* put a blank string in the status location */
  XmString status = XmStringCreateSimple("             ");
  XmString track_number = XmStringCreateSimple("             ");
  XmString filemenu_label;

/* check if it's playing on startup */
  subchnl.cdsc_format=CDROM_MSF;
  subchnl.cdsc_audiostatus=CDROM_LEADOUT;
  subchnl.cdsc_trk=CDROM_LEADOUT;

  f=open(cdrom,O_RDONLY);

  if ((ioctl(f,CDROMSUBCHNL,&subchnl))==-1) {
    perror("ioctl(CDROMSUBCHNL)");
  } else { 
    if ( subchnl.cdsc_audiostatus == 17 ) {
      current_track = subchnl.cdsc_trk;
    } else if ( subchnl.cdsc_audiostatus == 18 ) {
      current_track = subchnl.cdsc_trk;
    } else if ( subchnl.cdsc_audiostatus == 21 ) {
      current_track = 1;
    } else {
      current_track = 1;
    }
  }

  read_cdrom(); /* read thje cdrom for tracks, etc */

  srand(getpid());

/* initialize all widgets */

  toplevel = XtVaAppInitialize(&app, "Xmitsumi", NULL, 0, &argc, argv, NULL, 
     NULL);

  xcd_icon = XCreatePixmapFromBitmapData(XtDisplay(toplevel),
     RootWindowOfScreen(XtScreen(toplevel)), xcdplayer_bits, xcdplayer_width,
     xcdplayer_height, 1, 0, 1);

  XtVaSetValues(toplevel, XmNiconPixmap, xcd_icon, XmNiconic, True, NULL);

  /* menu bar */  
  main_window = XtVaCreateManagedWidget("main_window", xmMainWindowWidgetClass,
     toplevel, NULL);


  XtSetArg(menuargs[0], XmNmarginWidth, 0);
  XtSetArg(menuargs[1], XmNmarginHeight, 0);

  menubar = XmCreateMenuBar(main_window, "menubar", menuargs, 2);

  filepulldown = XmCreatePulldownMenu(menubar, "filepulldown", NULL, 0);

  filemenu_label = XmStringCreateSimple("File");

  filemenu = XtVaCreateManagedWidget("File", xmCascadeButtonWidgetClass, 
     menubar, XmNlabelString, filemenu_label, XmNmnemonic, 'F',
     XmNsubMenuId, filepulldown, NULL);
  
  XmStringFree(filemenu_label);

/* File menu options */

  about_choice = XtVaCreateManagedWidget("About",
     xmPushButtonGadgetClass, filepulldown, XmNmnemonic, 'A', NULL);

  filemenu_separator = XtVaCreateManagedWidget("filemenu_separator",
     xmSeparatorGadgetClass, filepulldown, NULL);

  exit_choice = XtVaCreateManagedWidget("Exit", xmPushButtonGadgetClass, 
     filepulldown, XmNmnemonic, 'x', NULL);

  XtAddCallback(about_choice, XmNactivateCallback, do_about, NULL);
  XtAddCallback(exit_choice, XmNactivateCallback, do_exit, NULL);

/* main window widgets */
  rowcol1 = XtVaCreateManagedWidget("rowcolumn1", xmRowColumnWidgetClass, 
     main_window, XmNnumColumns, 3, XmNorientation, XmVERTICAL, NULL);

  topform = XtVaCreateManagedWidget("topform", xmFormWidgetClass, rowcol1,
     XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, rowcol1,
     NULL);

/*  label = XtVaCreateManagedWidget("X CD-player version 0.60", 
     xmLabelWidgetClass, 
     topform, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, 
     XmATTACH_FORM, XmNalignment, XmALIGNMENT_CENTER, NULL);*/

  separator2 = XtVaCreateManagedWidget("separator2", xmSeparatorWidgetClass,
     topform, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment,
     XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM,
     XmNseparatorType, XmSHADOW_ETCHED_IN, NULL);

  buttonform = XtVaCreateManagedWidget("buttonform", xmFormWidgetClass, 
     topform, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment,
     XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, 
     XmNtopWidget, separator2,
     XmNfractionBase, 212, NULL);

/* pixmap stuff */
  XtVaGetValues(rowcol1, XmNforeground, &fg, XmNbackground, &bg, NULL);

  playbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform), 
     RootWindowOfScreen(XtScreen(buttonform)), play_bits, play_width,
     play_height, fg, bg, DefaultDepthOfScreen(XtScreen(buttonform)));
  stopbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), stop_bits, stop_width,
     stop_height, fg, bg, DefaultDepthOfScreen(XtScreen(buttonform)));
  fastforwardbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), fastforward_bits, 
     fastforward_width,
     fastforward_height, fg, bg, DefaultDepthOfScreen(XtScreen(buttonform)));
  pausebutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), pause_bits, pause_width,
     pause_height, fg, bg, DefaultDepthOfScreen(XtScreen(buttonform)));
  rewindbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), rewind_bits, rewind_width,
     rewind_height, fg, bg, DefaultDepthOfScreen(XtScreen(buttonform)));
/*  exitbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), exit_bits, exit_width,
     exit_height, fg, bg, DefaultDepthOfScreen(XtScreen(buttonform)));*/
  repeatybutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), repeatyes_bits, 
     repeatyes_width, repeatyes_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));
  repeatnbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), repeatno_bits, 
     repeatno_width, repeatno_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));
  shuffleybutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), yesshuffle_bits, 
     yesshuffle_width, yesshuffle_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));
  shufflenbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), noshuffle_bits, 
     noshuffle_width, noshuffle_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));  

  separator1 = XtVaCreateManagedWidget("separator1", xmSeparatorWidgetClass,
     topform, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, 
     XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget,buttonform,
     XmNseparatorType, XmSHADOW_ETCHED_IN, NULL);

  rowcol3 = XtVaCreateManagedWidget("rowcol3", xmFormWidgetClass,
     topform, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment,
     XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET,
     XmNtopWidget, separator1,
     XmNfractionBase, 100, NULL);

/* the status indicator widgets */

  track_indicator_label = XtVaCreateManagedWidget("Track:",
     xmLabelWidgetClass, rowcol3,
     XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 3,
     NULL);

  track_indicator = XtVaCreateManagedWidget("track_indicator",
     xmLabelWidgetClass, rowcol3, XmNlabelString, track_number,
     XmNwidth, 20, 
     XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, track_indicator_label,
     NULL);

  status_indicator_label = XtVaCreateManagedWidget("Status:",
     xmLabelWidgetClass, rowcol3,
     XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 40,
     NULL);

  status_indicator = XtVaCreateManagedWidget("track_indicator",
     xmLabelWidgetClass, rowcol3, XmNlabelString, status, XmNwidth, 20,
     XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, status_indicator_label,
     NULL);

  work_id2 = XtAppAddWorkProc(app, get_track, track_indicator);

/* all the main cd-control buttons */

  rew = XtVaCreateManagedWidget("REW", xmPushButtonGadgetClass, buttonform,
      XmNlabelType, XmPIXMAP, XmNlabelPixmap, rewindbutton, 
      XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, 1,
      XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 1,
      XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 25,
      NULL);
  XtAddCallback(rew, XmNactivateCallback, do_rew, status_indicator);

  pause = XtVaCreateManagedWidget("PAUSE", xmPushButtonGadgetClass, buttonform,
      XmNlabelType, XmPIXMAP, XmNlabelPixmap, pausebutton, 
      XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, 1, 
      XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 27,
      XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 52,
      NULL);
  XtAddCallback(pause, XmNactivateCallback, do_pause, status_indicator);

  play =  XtVaCreateManagedWidget("PLAY", xmPushButtonGadgetClass, buttonform,
      XmNlabelType, XmPIXMAP, XmNlabelPixmap, playbutton, 
      XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, 1,
      XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 55,
      XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 90,
      NULL);
  XtAddCallback(play, XmNactivateCallback, do_play, status_indicator);
 
  stop =  XtVaCreateManagedWidget("STOP", xmPushButtonGadgetClass, buttonform,
      XmNlabelType, XmPIXMAP, XmNlabelPixmap, stopbutton, 
      XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, 1,
      XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 92,
      XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 128,
      NULL);
  XtAddCallback(stop, XmNactivateCallback, do_stop, status_indicator);

  ff =  XtVaCreateManagedWidget("FF", xmPushButtonGadgetClass, buttonform, 
      XmNlabelType, XmPIXMAP, XmNlabelPixmap, fastforwardbutton, 
      XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, 1,
      XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 130,
      XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 155,
      NULL);
  XtAddCallback(ff, XmNactivateCallback, do_ff, status_indicator);

  repeat = XtVaCreateManagedWidget("REPEAT", xmPushButtonGadgetClass, 
      buttonform, XmNlabelType, XmPIXMAP, XmNlabelPixmap, repeatybutton, 
      XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, 1,
      XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 157,
      XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 182,
      NULL);
  XtAddCallback(repeat, XmNactivateCallback, do_repeat, repeat);

  shuffle = XtVaCreateManagedWidget("SHUFFLE", xmPushButtonGadgetClass, 
      buttonform, XmNlabelType, XmPIXMAP, XmNlabelPixmap, shufflenbutton, 
      XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, 1,
      XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 184,
      XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 211,
      NULL);
  XtAddCallback(shuffle, XmNactivateCallback, do_shuffle, shuffle);

  get_track(track_indicator);
  set_status(track_indicator);

  XtManageChild(menubar);
  XtRealizeWidget(toplevel);
  XtAppMainLoop(app);
  
}     

/* I'm sure I could garbage collect down here and make a check_cd function
   instead of including the cd mount/open/readable in ALL the functions but
   I don't really know how */


/* play function */
void do_play(w, status_indicator)
Widget w;
Widget status_indicator;
{
  extern int read_cdrom();
  extern Widget track_indicator;

  read_cdrom();
  
  /* read TOC */

  ioctl(f,CDROMREADTOCHDR,&tochdr);
 
  subchnl.cdsc_format=CDROM_MSF;
  subchnl.cdsc_trk=CDROM_LEADOUT;

  if ((ioctl(f,CDROMSUBCHNL,&subchnl))==-1) {
    perror("ioctl(CDROMSUBCHNL)");
  } 

  /* check if paused, playing or not */ 

  if ( subchnl.cdsc_audiostatus == 18) {
    ioctl(f,CDROMRESUME);
    set_status(track_indicator);
    return;
  } else if ( subchnl.cdsc_audiostatus  == 17 ) {
    i = i;
  } else {
    /* organize tracks */
    
    ti.cdti_trk0=current_track;
    ti.cdti_ind0=1;
    ti.cdti_trk1=tochdr.cdth_trk1;
    ti.cdti_ind1=1;

    ioctl(f,CDROMPLAYTRKIND,&ti);
    current_track = ti.cdti_trk0;
  }
  set_status(track_indicator);
}

/* stop function */
void do_stop(w, status_indicator)
Widget w;
Widget status_indicator;
{
  extern Widget track_indicator;
  read_cdrom();

  if ((ioctl(f,CDROMSTOP))==-1) {
    perror("ioctl(CDROMSTOP)");
  }
  set_status(track_indicator);
}

/* rewind functions */
void do_rew(w, status_indicator)
Widget w;
Widget status_indicator;
{

  extern int read_cdrom();
  extern Widget track_indicator;
  read_cdrom();

   ioctl(f,CDROMREADTOCHDR,&tochdr);


  /* check for status (playing or not) and current track */

  subchnl.cdsc_format=CDROM_MSF;
  subchnl.cdsc_trk=CDROM_LEADOUT;
  
  if ((ioctl(f,CDROMSUBCHNL,&subchnl))==-1) {
    perror("ioctl(CDROMSUBCHNL)");
  }

  /* check if paused, playing or not */
  if ( subchnl.cdsc_audiostatus == 21) {
    if ( current_track > 1 ) {
      if ( shuffle_stat == 0 ) {
	current_track = current_track - 1;
      } else {
	if ( repeat_stat == 0 ) {
	  current_track = 1;
	} else { 
	  current_track = current_track - 1;
	}
      }
    } else {
      int foo = rand() % tochdr.cdth_trk1 - 1;
      current_track = foo;
    }
  } else {
    if ( current_track > 1 ) {
      if ( shuffle_stat == 0 ) {
	current_track = subchnl.cdsc_trk - 1;
      } else {
	int foo = rand() % tochdr.cdth_trk1 - 1;
	current_track = foo;
      }
    } else { 
      if ( repeat_stat == 0 ) { 
	current_track = 1;
	return;
      } else {
	current_track = tochdr.cdth_trk1;
      }
    }
  }
  
  
  /* do it */ 
  ti.cdti_trk0=current_track;
  ti.cdti_ind0=1;
  ti.cdti_trk1=tochdr.cdth_trk1;
  ti.cdti_ind1=1;

  ioctl(f,CDROMPLAYTRKIND,&ti);
  current_track = ti.cdti_trk0;
  set_status(track_indicator);
  return;

}

/* fast forward */
void do_ff(w, status_indicator)
Widget w;
Widget status_indicator;
{
  
  extern int read_cdrom();
  extern Widget track_indicator;
  read_cdrom();
  
  /* read TOC */

  ioctl(f,CDROMREADTOCHDR,&tochdr);


  /* check for status (if playing) and current track */
  subchnl.cdsc_format=CDROM_MSF;
  subchnl.cdsc_trk=CDROM_LEADOUT;
  
  if ((ioctl(f,CDROMSUBCHNL,&subchnl))==-1) {
    perror("ioctl(CDROMSUBCHNL)");    
  }
 
  if ( subchnl.cdsc_audiostatus == 21) {
    if ( current_track < tochdr.cdth_trk1 ) {
      if ( shuffle_stat == 0 ) {
	current_track = current_track + 1;
      } else {
	if ( repeat_stat == 0 ) {
	  current_track = 1;
	} else { 
	  current_track = tochdr.cdth_trk1;
	}
      }
    } else {
      int foo = rand() % tochdr.cdth_trk1 - 1;
      current_track = foo;
    }
  } else {
    if ( current_track < tochdr.cdth_trk1 ) {
      if ( shuffle_stat == 0 ) {
	current_track = subchnl.cdsc_trk + 1;
      } else {
	int foo = rand() % tochdr.cdth_trk1 - 1;
	current_track = foo;
      }
     } else { 
      if ( repeat_stat == 0 ) { 
	current_track = tochdr.cdth_trk1;
	return;
      } else {
	current_track = 1;
      }
    }
  }

  /* do it */
  ti.cdti_trk0=current_track;
  ti.cdti_ind0=1;
  ti.cdti_trk1=tochdr.cdth_trk1;
  ti.cdti_ind1=1;

  ioctl(f,CDROMPLAYTRKIND,&ti);
  current_track = ti.cdti_trk0;
  set_status(track_indicator);
  return;
}

/* pause function */
void do_pause(w, status_indicator)
Widget w;
Widget status_indicator;
{
  extern int read_cdrom();
  extern Widget track_indicator;
  read_cdrom();

  if ((ioctl(f,CDROMPAUSE))==-1) {
    ioctl(f,CDROMRESUME);
  } else {
  ioctl(f,CDROMPAUSE);
  }
  set_status(track_indicator);
}

/* quit dialog */
void do_exit(Widget w)
{
  Widget parent;
  Widget dialog;
  Arg args[1];
  XmString text;
  extern void do_exit2();
  text = XmStringCreateSimple("Are you sure?");
  XtSetArg(args[0], XmNautoUnmanage, False);
  dialog = XmCreateQuestionDialog(parent, "foo", args, 1);

  XtAddCallback(dialog, XmNokCallback, do_exit2, "foo");
  XtAddCallback(dialog, XmNcancelCallback, do_exit2, "foo");

  XtVaSetValues(dialog, XmNmessageString, text, XmNdefaultButtonType, 
     XmDIALOG_CANCEL_BUTTON, NULL);
  XmStringFree(text);

  XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));

  XtManageChild(dialog);
  XtPopup(XtParent(dialog), XtGrabNone);

}

/* execute the quit choice */
void do_exit2(w, client_data, cbs)
Widget w;
XtPointer client_data;
XmAnyCallbackStruct *cbs;
{
  char *button;
  switch (cbs->reason) {
  case XmCR_OK : button = "OK"; exit(1);
  case XmCR_CANCEL : button = "Cancel"; break;
  }
  XtPopdown(XtParent(w));
}

/* my first real working sub function */
/* it reads the drive for the actual, currently playing */
/* track and displays */

int get_track(Widget track_indicator)
{

  int rantrack;

  usleep(250000);           /* so it doesn't spam the cpu */
  read_cdrom();

  subchnl.cdsc_format=CDROM_MSF;
  subchnl.cdsc_audiostatus=CDROM_LEADOUT;
  subchnl.cdsc_trk=CDROM_LEADOUT; 

  if ((ioctl(f,CDROMSUBCHNL,&subchnl))==-1) {
    return False;
  }

  if ( current_track == subchnl.cdsc_trk ) {
    return False;
  }

  /* if it is 'in limbo' shuffle it */


  printf("current_track: %d\nshuffle_stat: %d\nshuffling: %d\nsubchnl: %d\n", current_track, shuffle_stat, shuffling, subchnl.cdsc_trk);
  
  /* ok, here's some nasty code...trying to get it to shuffle randomly during
     normal playback. I'm sort of tricking it now... */

  if ((shuffle_stat == 1) && (subchnl.cdsc_trk == (1 + current_track) ) ){
    rantrack = rand() % tochdr.cdth_trk1 - 1;
    ti.cdti_trk0=rantrack;
    ti.cdti_ind0=1;
    ti.cdti_trk1=tochdr.cdth_trk1;
    ti.cdti_ind1=1;
    ioctl(f,CDROMPLAYTRKIND,&ti);
    puts("foo");
    return False;
  }

  if ((shuffle_stat == 1) && (shuffling == 100 )) {
    rantrack = rand() % tochdr.cdth_trk1 - 1;
    ti.cdti_trk0=rantrack;
    ti.cdti_ind0=1;
    ti.cdti_trk1=tochdr.cdth_trk1;
    ti.cdti_ind1=1;
    ioctl(f,CDROMPLAYTRKIND,&ti);
    puts("bar");
    return False;
  }

  set_status(track_indicator);
}

int set_status(Widget track_indicator)
{
  char char_current_track[BUFSIZ];
  XmString str_current_track;

  extern Widget status_indicator;

  subchnl.cdsc_format=CDROM_MSF;
  subchnl.cdsc_audiostatus=CDROM_LEADOUT;
  subchnl.cdsc_trk=CDROM_LEADOUT;

  if ((ioctl(f,CDROMSUBCHNL,&subchnl))==-1) {
    return False;
  }

  current_track = subchnl.cdsc_trk;
  sprintf(char_current_track,"%d",current_track);
  str_current_track = XmStringCreateSimple(char_current_track);
  XtVaSetValues(track_indicator, XmNlabelString, str_current_track, NULL);
  XmStringFree(str_current_track);
  get_status(status_indicator);
  return False;
  
}

int get_status(Widget status_indicator)
{

/*  extern Widget status_indicator;*/
  XmString str_current_status;
  char char_current_status[BUFSIZ];
  int current_status;
  
  subchnl.cdsc_format=CDROM_MSF;
  subchnl.cdsc_audiostatus=CDROM_LEADOUT;
  subchnl.cdsc_trk=CDROM_LEADOUT;

  if ((ioctl(f,CDROMSUBCHNL,&subchnl))==-1) {
    perror("ioctl(CDROMSUBCHNL)");
  }
  if (( subchnl.cdsc_audiostatus == 17 ) && ( current_status != 17 )) {
    strcpy(char_current_status,"Playing...");
  } else if (( subchnl.cdsc_audiostatus == 18 ) && ( current_status != 18)) {
    strcpy(char_current_status,"Paused.");
  } else if  (( subchnl.cdsc_audiostatus == 21 ) && ( current_status != 21 )) {
    strcpy(char_current_status,"Stopped.");
  } else {
    return False;
  }
  
  current_status = subchnl.cdsc_audiostatus;
  str_current_status = XmStringCreateSimple(char_current_status);
  XtVaSetValues(status_indicator, XmNlabelString, str_current_status, NULL);
  XmStringFree(str_current_status);
  return 0;

}

void do_about()
{
  Widget parent;
  Widget about_dialog, text_w;
  char about_text[BUFSIZ];
  Arg args[1];
  XmString text;
  extern void closedialog();

  text = XmStringCreateSimple("About X-mitsumi");
  strcat(about_text,"X-mitsumi is written by Liem Bahneman\nroland@cac.washington.edu\n\nInittialy started as an experiment,\nI've released it so other Mitsumi owners\ncould take advantage of it too.\nTHIS IS PURELY A BETA VERSION\nThere may or may not be more fixes/features.\n\nI'd appreciate any feedback you have!");

  XtSetArg(args[0], XmNautoUnmanage, False);
  about_dialog = XmCreateMessageDialog(parent, "foo", args, 1);

  XtAddCallback(about_dialog, XmNokCallback, closedialog, about_dialog);

  XtVaSetValues(about_dialog, XmNmessageString, text, NULL);
  XmStringFree(text);
  XtUnmanageChild(XmMessageBoxGetChild(about_dialog, XmDIALOG_HELP_BUTTON));
  XtUnmanageChild(XmMessageBoxGetChild(about_dialog, XmDIALOG_CANCEL_BUTTON));

  text_w = XtVaCreateManagedWidget("text_w", xmTextWidgetClass, about_dialog, 
     XmNvalue, about_text, XmNeditable, False, 
     XmNeditMode, XmMULTI_LINE_EDIT, XmNrows, 8, XmNcolumns, 60,
     XmNcursorPositionVisible, False, 
     NULL);

  XtManageChild(about_dialog);
  XtPopup(XtParent(about_dialog), XtGrabNone);

}

void closedialog(dialog)
Widget dialog;
{
  XtPopdown(XtParent(dialog));
}

/* Generic scan of the driv eunit for status */

int read_cdrom()
{

 /* check if drive is mounted */

  if ((fp=setmntent(MOUNTED,"r"))==NULL) {
    fprintf(stderr,"Couldn't open %s: %s\n",MOUNTED,strerror(errno));
  }
  while ((mnt=getmntent(fp))!=NULL) {
    if (strcmp(mnt->mnt_type,"iso9660")==0) {
      fputs("CDROM already mounted. Operation aborted.n",stderr);
      endmntent(fp);
    }
  }
  endmntent(fp);

  ioctl(f,CDROMREADTOCHDR,&tochdr);

}

void do_repeat(Widget w)
{

  extern Widget rowcol1, buttonform;

  XtVaGetValues(rowcol1, XmNforeground, &fg, XmNbackground, &bg, NULL);

  repeatybutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), repeatyes_bits, 
     repeatyes_width, repeatyes_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));
  repeatnbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), repeatno_bits, 
     repeatno_width, repeatno_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));

  if (repeat_stat == 1) {
    repeat_stat = 0;
    XtVaSetValues(w, XmNlabelType, XmPIXMAP, XmNlabelPixmap, repeatnbutton,
       NULL);   
  } else {
    repeat_stat = 1;
    XtVaSetValues(w, XmNlabelType, XmPIXMAP, XmNlabelPixmap, repeatybutton,
       NULL);
  }
  
  return;
}

void do_shuffle(Widget w)
{

  extern Widget rowcol1, buttonform;

  XtVaGetValues(rowcol1, XmNforeground, &fg, XmNbackground, &bg, NULL);

  shuffleybutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), yesshuffle_bits, 
     yesshuffle_width, yesshuffle_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));
  shufflenbutton = XCreatePixmapFromBitmapData(XtDisplay(buttonform),
     RootWindowOfScreen(XtScreen(buttonform)), noshuffle_bits, 
     noshuffle_width, noshuffle_height, fg, bg, 
     DefaultDepthOfScreen(XtScreen(buttonform)));

  if (shuffle_stat == 1) {
    shuffle_stat = 0;
    XtVaSetValues(w, XmNlabelType, XmPIXMAP, XmNlabelPixmap, shufflenbutton,
       NULL);   
  } else {
    shuffle_stat = 1;
    XtVaSetValues(w, XmNlabelType, XmPIXMAP, XmNlabelPixmap, shuffleybutton,
       NULL);
  }
  
  return;
}










