/*****************************************************************************/

/*
 *      handledisc.c -- REALmagic disc (DVD, SVDC, VCD, CDDA) playing primitives
 *
 *      Copyright (C) 2001 Sigma Designs
 *                    written by Pascal Cannenterre <pascal_cannenterre@sdesigns.com>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*****************************************************************************/
#include "define.h"
#include "gtk_callbacks.h"


void StartPlaying_disc(INFO*);
DWORD Event_Notifications_disc (DWORD, DWORD, DWORD);

DWORD getDvdAspectRatio(DWORD *dvd_aspect, DWORD *display_mode)
{
  VIDEO_MODE vm;
  DWORD FMPreturn;
  if(dvd_aspect == NULL && display_mode == NULL)
    return FMPE_ERROR;
  FMPreturn = DVDQueryAttribute(DVDI_VIDEO_MODE, (DWORD)(&vm));
  
  if(FMPreturn == FMPE_OK)
    {
      *dvd_aspect = vm.bAspectRatio;
      *display_mode = vm.bDisplayMode;
    }
  return FMPreturn;
}

DWORD setDvdAspectRatio(DWORD tv_format, BOOL rescale)
{
  DWORD FMPreturn;
  DWORD dvd_aspect;
  DWORD current_display_mode;

  FMPreturn = getDvdAspectRatio(&dvd_aspect, &current_display_mode);
  if(FMPreturn != FMPE_OK)
    return FMPreturn;
  

  if(tv_format == TV_4x3)
    {
      switch(dvd_aspect)
	{
	case ASPECT_RATIO_4_3:
	  FMPreturn = FMPSet(FMPI_VIDEOASPECT, FMPV_VIDEOASPECT_4x3_4x3_NORMAL);
	  break;
	case ASPECT_RATIO_16_9:
	  if(rescale)
	    {
	      if(current_display_mode != DISPLAY_MODE_PAN_SCAN)
		FMPreturn = FMPSet(FMPI_VIDEOASPECT, FMPV_VIDEOASPECT_16x9_4x3_PANSCAN);	
	    }
	  else
	    {
	      if(current_display_mode != DISPLAY_MODE_LETTERBOX)
		FMPreturn = FMPSet(FMPI_VIDEOASPECT, FMPV_VIDEOASPECT_16x9_4x3_LETTERBOX);	
	    }
	  break;
	default:
	  break;
	}
    }
  else /* if(tv_format == TV_16x9) */
    {
      switch(dvd_aspect)
	{
	case ASPECT_RATIO_4_3:
	  if(rescale)
	    {
	      if(current_display_mode != DISPLAY_MODE_ZOOM_ON)
		FMPreturn = FMPSet(FMPI_VIDEOASPECT, FMPV_VIDEOASPECT_4x3_16x9_ZOOM_ON);
	    }
	  else
	    {
	      FMPreturn = FMPSet(FMPI_VIDEOASPECT, FMPV_VIDEOASPECT_4x3_16x9_ZOOM_OFF);
	    }
	  break;
	case ASPECT_RATIO_16_9:
	  FMPreturn = FMPSet(FMPI_VIDEOASPECT, FMPV_VIDEOASPECT_16x9_16x9_NORMAL);
	  break;
	default:
	  break;
	}
    }
  return FMPreturn;
}


DWORD getCurrentPlayingTime(DWORD *currenttotaltime)
{
  if(currenttotaltime == NULL)
    return FMPE_ERROR;

  *currenttotaltime =  FMPGet(FMPI_CURRENT_TIME);

  return FMPE_OK;
}

void refreshTitleChapter(INFO *pInfo)
{
  if(pInfo->playing != CLOSED)
    {
      if(pInfo->bDiscType == FMPC_DVD_VIDEO)
	{
	  pInfo->bTitle = (BYTE) FMPGet(FMPI_CURRENT_TITLE);
	  pInfo->bChapter = (WORD) FMPGet(FMPI_CURRENT_CHAPTER);
	  pInfo->totalTime = (DWORD) FMPGet(FMPI_TOTAL_TITLE_TIME);
	  
	  // G_WARNING("Total time = %ld",pInfo->totalTime);
	  if(pInfo->bTitle == 0xff)
	    pInfo->bTitle = 0;
	  if(pInfo->bChapter == 0xffff)
	    pInfo->bChapter = 0;
	}
      else if(pInfo->bDiscType == FMPC_SVCD ||
	      pInfo->bDiscType == FMPC_VCD)
	{
	  pInfo->bTitle = (BYTE) FMPGet(FMPI_CURRENT_TRACK);
	  pInfo->totalTime = (DWORD) FMPGet(FMPI_TOTAL_TITLE_TIME);
	  
	  // G_WARNING("Total time = %ld",pInfo->totalTime);
	}
    }
  else
    {
      pInfo->bTitle = 0;
      pInfo->bChapter = 0;
    }
}

void handle_Eject_disc(INFO *pInfo)
{
  if (FMPTrayOperation(FMPT_TRAYCHECK) == FMPT_TRAYCLOSE) 
    {
      if(pInfo->playing != CLOSED) 
	{
	  if(pInfo->osdFlag) 
	    {
	      pInfo->osdFlag = 0;
	      // msg = SHOW_TIME;
	    }
	  handle_Stop_Close_disc(pInfo);
	  handle_Stop_Close_disc(pInfo);
	}
      // msg = SHOW_OPEN;
      FMPTrayOperation(FMPT_TRAYOPEN);
      displayMsg(MSG_BOTH, MSG_OPEN, NULL);
    }
  else
    {
      FMPTrayOperation(FMPT_TRAYCLOSE);
    }
}

void handle_Stop_Close_disc(INFO *pInfo)
{
  
  if(pInfo->playing != CLOSED)
    {
      if(pInfo->playing == VCD_WAITING &&
	 (pInfo->bDiscType == FMPC_VCD ||
	  pInfo->bDiscType == FMPC_SVCD)) 
	{
	  DWORD tmp0, tmp1;
	  // WORD tmp2;
	 
	  // msg = SHOW_TIME;
	  // OSPostMessage(pInfo->osdMsgQ, &msg, 1);
	
	  tmp0 = FMPGet(FMPI_SVCD_CURRENT_VOLUME);
	  tmp1 = FMPGet(FMPI_SVCD_VOLUMES_AVAILABLE);
	  FMPStop();
	  FMPClose();
	  pInfo->playing = CLOSED;
	  // stopDiscTimer(pInfo);
	  //Before showing splash screen we return to 720x480 resolution
	  if(tmp0 < tmp1) 
	    {
	      FMPTrayOperation(FMPT_TRAYOPEN);
	      displayMsg(MSG_STATUS_ONLY, 0, "Waiting for media...");
	    }
	}
      else if(pInfo->playing == STOP_FOR_RESUME ||
	      pInfo->playing == STOPPED) 
	{
	  // WORD tmp;
	  VIDEO_MODE vm;
	  
	  // msg = SHOW_TIME;
	  // OSPostMessage(pInfo->osdMsgQ, &msg, 1);

	  if(pInfo->bDiscType == FMPC_DVD_VIDEO)
	    DVDQueryAttribute(DVDI_VIDEO_MODE, (DWORD)(&vm));
	  else
	    vm.bAspectRatio = ASPECT_RATIO_4_3;
	  FMPStop();
	  FMPClose();
	  pInfo->playing = CLOSED;
	  displayMsg(MSG_BOTH, MSG_CLOSE, NULL);
	  if(vm.bAspectRatio != ASPECT_RATIO_4_3 && pInfo->pIHdtv)
	    IHdtv_SetAspectRatio(pInfo->pIHdtv,4,3,5);
	  
	  //Before showing splash screen we return to 720x480 resolution
	  if(pInfo->IHdtv_c)
	    IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params_Init), g_OutputMode);
	  
	    reinitialize_info_structure_disc(pInfo);
	}
      else 
	{
	  if ((pInfo->bDiscType == FMPC_DVD_VIDEO) ||
	      (pInfo->bDiscType == FMPC_VCD) ||
	      (pInfo->bDiscType == FMPC_SVCD)) 
	    {
	      // StopForResume();
	      if(pInfo->playing == TRICK_MODE ||           //!!!
		 pInfo->playing == TRICK_MODE_PAUSED)
		{    //!!!
		  if(((LONG)FMPGet(FMPI_CURRENT_SPEED)) > 0)
		    {
		      //!!!
		      if(pInfo->bDiscType == FMPC_DVD_VIDEO)   //!!!
			ForwardScan(0, pInfo->bFast);          //!!!
		      else                                     //!!!
			FastForward(0);
		    }                        //!!!
		  else
		    {//!!!
		      if(pInfo->bDiscType == FMPC_DVD_VIDEO)   //!!!
			BackwardScan(0, pInfo->bFast);         //!!!
		      else                                     //!!!
			Rewind(0);
		    }                             //!!!
		  pInfo->bFast = 0;                          //!!!
		}

	      // blank the screen
	      switch_overlay_back(&ovl);
                                            //!!!
	      FMPPause();                                  //!!!
	      pInfo->playing = STOP_FOR_RESUME;
	      if(pInfo->bABRepeat) 
		{
		  ClearRepeatAB(); //!!!
		  pInfo->bABRepeat = 0;
		  displayRepeatModeMsg("A->B repeat cleared");
		  usleep(30*TICK);
		}
	      else if(pInfo->bRepeat) 
		{
		  if(pInfo->bRepeat == 1)
		    {
		      RepeatTitle();        
		      displayRepeatModeMsg("Repeat Title");
		    }
		  else                    
		    {
		      RepeatChapter();
		      displayRepeatModeMsg("Repeat Chapter");
		    }
		  //!!!
		  pInfo->bRepeat = 0;
		  
		  usleep(100*TICK);
		}
	      displayMsg(MSG_BOTH, MSG_STOP, NULL);
	    }
	  else if(pInfo->bDiscType == FMPC_CDDA) 
	    {
	      handle_Stop_Close_cdda(pInfo); 
	    }
	}
    }
  else 
    {
      displayMsg(MSG_BOTH, MSG_CLOSE, NULL); 
    }
  
}

void handle_FForward_disc(INFO *pInfo)
{
  char *msg = NULL;

  if(pInfo->playing == STOP_FOR_RESUME)
    resumeDisplayFromStop(&ovl);
  
  if (pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      LONG sp = (LONG)FMPGet(FMPI_CURRENT_SPEED);
      if(sp < 0) 
	{
	  sp = 0;
	  BackwardScan ((WORD)sp, pInfo->bFast);
	}
      sp = (sp + 2) % 10;
      
      if(ForwardScan ((WORD)sp, 1) != DVDE_UNAUTHORIZED) 
	{
	  if(!sp)
	    {
	      pInfo->bFast = 0;
	      pInfo->playing = PLAYING;
	      displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	    }
	  else 
	    {
	      pInfo->playing = TRICK_MODE;
	      pInfo->bFast = 1;
	      msg = g_strdup_printf("%ldX",sp);
	      displayMsg(MSG_BOTH, MSG_FF, msg);
	      g_free(msg); msg = NULL;
	    }
	}
      else 
	{
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL); 
	}
    }
  else if (pInfo->bDiscType == FMPC_VCD || 
	   pInfo->bDiscType == FMPC_SVCD)
    {
      LONG speed;
      G_MESSAGE("VCD FAST FORWARD\n");
      speed = (LONG)FMPGet(FMPI_CURRENT_SPEED);
      if(speed < 0)
	{
	  Rewind(0);
	  speed = 0;
	}
      speed++;
      if(speed == 4)
	speed = 0;
      FastForward((BYTE)speed);
      if(speed)
	{
	  pInfo->playing = TRICK_MODE;
	  pInfo->bFast = 1;
	  msg = g_strdup_printf("%ldX",speed);
	  displayMsg(MSG_BOTH, MSG_FF,msg);
	  g_free(msg); msg = NULL;
	}
      else
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  pInfo->bFast = 0;
	}
    }
  else if(pInfo->bDiscType == FMPC_CDDA)
    {
      handle_FForward_cdda(pInfo);
    }  
}


void handle_FRewind_disc(INFO *pInfo)
{
  char *msg = NULL;
  
  if(pInfo->playing == STOP_FOR_RESUME)
    resumeDisplayFromStop(&ovl);
  
  if (pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      LONG sp = (LONG)FMPGet(FMPI_CURRENT_SPEED);
      if(sp > 0) 
	{
	  sp = 0;
	  ForwardScan ((WORD)sp, pInfo->bFast);
	}
      sp = -sp;
      sp = (sp + 2) % 10;
      
      if(BackwardScan ((WORD)sp, 1) != DVDE_UNAUTHORIZED) 
	{
	  if(!sp) 
	    {
	      pInfo->bFast = 0;
	      pInfo->playing = PLAYING;
	      displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	    }
	  else 
	    {
	      pInfo->playing = TRICK_MODE;
	      pInfo->bFast = 1;
	      msg = g_strdup_printf("%ldX",sp);
	      displayMsg(MSG_BOTH, MSG_FR, msg);
	      g_free(msg); msg = NULL;
	    }
	  
	}
      else 
	{
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);	
	}
    }
  else if ((pInfo->bDiscType == FMPC_VCD) || 
	   (pInfo->bDiscType == FMPC_SVCD))
    {
      LONG speed;
      speed = (LONG)FMPGet(FMPI_CURRENT_SPEED);
      if(speed > 0) 
	{
	  FastForward(0);
	  speed = 0;
	}
      speed--;
      speed = -speed;
      if(speed == 4)
	speed = 0;
      Rewind((BYTE)speed);
      if(speed) 
	{
	  pInfo->playing = TRICK_MODE;
	  pInfo->bFast = 1;
	  msg = g_strdup_printf("%ldX",speed);
	  displayMsg(MSG_BOTH, MSG_FR, msg);
	  g_free(msg); msg = NULL;
	}
      else 
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  pInfo->bFast = 0;
	}
    }
  else if(pInfo->bDiscType == FMPC_CDDA) 
    {
      handle_FRewind_cdda(pInfo); 
      
    }
}


void handle_Prev_Track_disc(INFO *pInfo)
{
  int pl_tmp = pInfo->playing;
  
  if(pInfo->playing == STOP_FOR_RESUME)
    resumeDisplayFromStop(&ovl);
  
  pInfo->playing = UNDETERMINED;

  switch(pInfo->bDiscType) 
    {
    case FMPC_DVD_VIDEO :
      if(pInfo->bABRepeat) 
	{
	  ClearRepeatAB(); //!!!
	  pInfo->bABRepeat = 0;
	  displayRepeatModeMsg("A->B repeat cleared !");
	  usleep(30*TICK);
	}
      if(PrevPGSearch() != DVDE_UNAUTHORIZED)
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_OSD_ONLY, MSG_BACK, NULL);
	}
      else 
	{
	  pInfo->playing = pl_tmp;
	  displayMsg(MSG_STATUS_ONLY, 0, "No Previous Chapter !");
	}
      break;
    case FMPC_VCD :
    case FMPC_SVCD :
      pInfo->playing = PLAYING;
      if(pInfo->bABRepeat) 
	{
	  ClearRepeatAB(); //!!!
	  pInfo->bABRepeat = 0;
	  displayRepeatModeMsg("A->B repeat cleared !");
	  usleep(30*TICK);
	}
      if(PrevPGSearch() == S_OK) 
	{
	 displayMsg(MSG_OSD_ONLY, MSG_BACK, NULL); 
	}
      else 
	{
	  pInfo->playing = pl_tmp;
	  displayMsg(MSG_STATUS_ONLY, 0, "No Previous Chapter !");
	  
	}
      break;
    case FMPC_CDDA :
      handle_Prev_Track_cdda(pInfo);
      break;
    }
}

void handle_Next_Track_disc(INFO *pInfo)
{
  int pl_tmp = pInfo->playing;

  if(pInfo->playing == STOP_FOR_RESUME)
    resumeDisplayFromStop(&ovl);
  
  pInfo->playing = UNDETERMINED;

  switch (pInfo->bDiscType) 
    {
    case FMPC_DVD_VIDEO :
      if(pInfo->bABRepeat) 
	{
	  ClearRepeatAB(); //!!!
	  pInfo->bABRepeat = 0;
	  displayRepeatModeMsg("A->B repeat cleared !");
	  usleep(30*TICK);
	}
      if(NextPGSearch() != DVDE_UNAUTHORIZED)	
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_OSD_ONLY, MSG_NEXT, NULL);  
	}
      else 
	{
	  pInfo->playing = pl_tmp;
	  displayMsg(MSG_STATUS_ONLY, 0, "No Next Chapter !");
	}
      break;
    case FMPC_VCD :
    case FMPC_SVCD :
      pInfo->playing = PLAYING;
      if(pInfo->bABRepeat) 
	{
	  ClearRepeatAB(); //!!!
	  pInfo->bABRepeat = 0;
	  displayRepeatModeMsg("A->B repeat cleared !");
	  usleep(30*TICK);
	}
      if(NextPGSearch() == S_OK) 
	{
	  displayMsg(MSG_OSD_ONLY, MSG_NEXT, NULL);
	}
      else 
	{
	  pInfo->playing = pl_tmp;
	  displayMsg(MSG_STATUS_ONLY, 0, "No Next Track !");
	}
      break;
    case FMPC_CDDA :
      handle_Next_Track_cdda(pInfo);
      break;
    } 
}

void handle_Play_Pause_disc(INFO *pInfo)
{
  int pl_tmp = pInfo->playing;
  WORD reg_tmp = (WORD) FMPGet(FMPI_CURRENT_DOMAIN);
  
  if((FMPGet(FMPI_CURRENT_DOMAIN) & 0x10000) &&
     reg_tmp != VMGM_DOM && reg_tmp != VTSM_DOM) 
    {
      //timer
      pInfo->playing = UNDETERMINED;
      if(StillOff() == DVDE_UNAUTHORIZED) 
	{
	  pInfo->playing = pl_tmp;
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	}
      else 
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	}
      
    }
  else if ((pInfo->playing == STOPPED) || 
	   (pInfo->playing == PAUSED) ||
	   (pInfo->playing == TRICK_MODE_PAUSED)) 
    {
      FMPPlay();
      if(pInfo->playing == TRICK_MODE_PAUSED)
	pInfo->playing = TRICK_MODE;
      else
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	}
    } 
  else if (pInfo->playing == STOP_FOR_RESUME) 
    {
      if ((pInfo->bDiscType == FMPC_DVD_VIDEO) ||
	  (pInfo->bDiscType == FMPC_VCD) ||
	  (pInfo->bDiscType == FMPC_SVCD)) 
	{
	  resumeDisplayFromStop(&ovl);
	  FMPPlay(); 
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL); // !!!
	}
      pInfo->playing = PLAYING;
    }
  else if (pInfo->playing == CLOSED) 
    {
      if(FMPTrayOperation(FMPT_TRAYCHECK) == FMPT_TRAYOPEN) 
	{
	  FMPTrayOperation(FMPT_TRAYCLOSE);
	  displayMsg(MSG_STATUS_ONLY, 0, "Closing Tray");
	}
      StartPlaying_disc(pInfo);
      displayMsg(MSG_BOTH, MSG_PLAY, NULL);
      
      if(pInfo->bDiscType == FMPC_CDDA) 
	{
	 

	}
      else if(pInfo->bDiscType == FMPC_VCD ||
	      pInfo->bDiscType == FMPC_SVCD) 
	{
	  
	  
	}
    }
  else 
    {
      FMPPause();
      displayMsg(MSG_BOTH, MSG_PAUSE, NULL);
      if(pInfo->playing == TRICK_MODE)
	pInfo->playing = TRICK_MODE_PAUSED;
      else
	pInfo->playing = PAUSED;
    }
}


void retrieveInfo_dvd(INFO* pInfo)
{
  TT_SRPTI tt_srpti; /* Titles */
  SPST_ATR spst_atr; /* Subpictures */
  AST_ATR ast_atr; /* Audio */
  DWORD tt, spst, ast;
  int i;
  
  tt = DVDQueryAttribute(DVDI_TT_SRPTI, (DWORD)&tt_srpti);
  spst = DVDQueryAttribute(DVDI_SPST_ATR, (DWORD)&spst_atr);
  ast = DVDQueryAttribute(DVDI_AST_ATR, (DWORD)&ast_atr);
  
  
				       
  if(tt == FMPE_OK && tt_srpti.bTT_SRP_Ns != 0)
    {
      pInfo->bTitleTotal = tt_srpti.bTT_SRP_Ns;
      G_PRINT("\n\nNumber of tt : %d\n\n", pInfo->bTitleTotal);
 
      // G_PRINT("\n\nSizeof : %d\n\n",sizeof(pInfo->titleAngle)); 
      memcpy(pInfo->titleAngle, tt_srpti.bALG_Ns, sizeof(pInfo->titleAngle) );
      memcpy(pInfo->titleChapter, tt_srpti.wPTT_Ns, sizeof(pInfo->titleChapter) );
      
      for(i=0;i<pInfo->bTitleTotal;i++)
	{
	  G_PRINT("%d",pInfo->titleAngle[i]);
	  G_PRINT("\t%d\n",pInfo->titleChapter[i]);  
	}
    }
  else
    {
      pInfo->bTitleTotal = 0;
     
    }
  
  if(spst  == FMPE_OK && spst_atr.bSPST_Ns != 0)
    {
      
      pInfo->bSPStreamTotal = spst_atr.bSPST_Ns;

      memcpy(pInfo->SPStreamLangage, spst_atr.wLanguageCode, 
	     sizeof(pInfo->SPStreamLangage) );
      memcpy(pInfo->SPStreamLangageExt , spst_atr.wLanguageCodeExtension, 
	     sizeof(pInfo->SPStreamLangageExt) );
      memcpy(pInfo->SPStreamAvailable, spst_atr.bAvailable, 
	     sizeof(pInfo->SPStreamAvailable) );

      G_PRINT("\n\nSP number : %d\n",pInfo->bSPStreamTotal);
      for(i=0;i<pInfo->bSPStreamTotal;i++)
	{
	  G_PRINT("%x", pInfo->SPStreamLangage[i]);
	  G_PRINT("\t%d", pInfo->SPStreamLangageExt[i]);
	  G_PRINT("\t%d\n", pInfo->SPStreamAvailable[i]);
	}
    }
  else
    {
      pInfo->bSPStreamTotal = 0; 
     
    }

  if(ast == FMPE_OK && ast_atr.bAST_Ns != 0)
    {
      pInfo->bAudioStreamTotal = ast_atr.bAST_Ns;
      
      memcpy(pInfo->AudioStreamLangage, ast_atr.wLanguageCode, 
	     sizeof(pInfo->AudioStreamLangage) );
      memcpy(pInfo->AudioStreamLangageExt, ast_atr.wLanguageCodeExtension, 
	     sizeof(pInfo->AudioStreamLangageExt) );
      memcpy(pInfo->AudioStreamCodingMode, ast_atr.bAudioCodingMode, 
	     sizeof(pInfo->AudioStreamCodingMode) ); 
      memcpy(pInfo->AudioStreamChannel, ast_atr.bNumberOfAudioChannels, 
	     sizeof(pInfo->AudioStreamChannel) );
      memcpy(pInfo->AudioStreamType, ast_atr.bAudioType, 
	     sizeof(pInfo->AudioStreamType) );
      memcpy(pInfo->AudioStreamAvailable, ast_atr.bAvailable, 
	     sizeof(pInfo->AudioStreamAvailable) );
      
      G_PRINT("\n\nAudio stream : %d\n",pInfo->bAudioStreamTotal);
      G_PRINT("LangC \tLext\tAudioCMode\tChannels\tStreamType\tAvail\n");
      for(i=0;i<pInfo->bAudioStreamTotal;i++)
	{
	  G_PRINT("%x",pInfo->AudioStreamLangage[i]);
	  G_PRINT("\t%d",pInfo->AudioStreamLangageExt[i]);
	  G_PRINT("\t%d",pInfo->AudioStreamCodingMode[i]);
	  G_PRINT("\t%d",pInfo->AudioStreamChannel[i]);
	  G_PRINT("\t%d",pInfo->AudioStreamType[i]);
	  G_PRINT("\t%d\n",pInfo->AudioStreamAvailable[i]);
	}
    }
  else
    {
      pInfo->bAudioStreamTotal = 0;
     
    }
  pInfo->previous_totalTime = pInfo->totalTime;
}


void StartPlaying_disc(INFO* pInfo) 
{
  FMP_OPENSTRUCT FMPOpenStruct;
  DWORD tmp;
  
  if (pInfo->playing == CLOSED)
    { 
      G_MESSAGE("Begin of FMPOpen\n");
      FMPOpenStruct.dwStructSize  = sizeof (FMP_OPENSTRUCT);
      FMPOpenStruct.bDriverNumber	= DRIVE_NUMBER;
      FMPOpenStruct.dwSize        = 32 * 1024;
      FMPOpenStruct.dwCount       = 10;
      FMPOpenStruct.pCallback     = Event_Notifications_disc;
      FMPOpenStruct.dwContext     = (DWORD)pInfo;
      FMPOpenStruct.sFileName     = NULL;
      FMPOpenStruct.dwFlags       = FMPF_DVD;
      FMPOpenStruct.bDiscContent  = FMPC_UNKNOWN;
      FMPOpenStruct.bFileSystem   = 0x00;
      
      pInfo->maddie = 0;
      pInfo->test = 0;
      
      g_Pass = FMPGetProfileWord(RMREG_PASSW_LOW_WORD) |
	(FMPGetProfileWord(RMREG_PASSW_HIGH_WORD) << 16);
      
      tmp = FMPOpenDiscPlayback(&FMPOpenStruct);
      /* To be removed !!! */
      ovl.b_overlay_access = TRUE;
     
      // BYTE msg = SCR_OFF;
      // OSPostMessage(pInfo->osdMsgQ, &msg, 1);
      
      if(tmp != 0) 
	{
	  pInfo->playing = CLOSED;
	  return;
	}

      
      
     
      pInfo->playing = STOPPED;
      pInfo->totalTime = 0;
      pInfo->dwTime = 0;
      G_MESSAGE("End of FMPOpen");

      if(pInfo->pIHdtv) 
	{
	  if((g_OutputMode & FMPV_VIDEOOUT_MODE_MASK) == FMPV_VIDEOOUT_HDTV) 
	    {
	      tmp = (WORD)FMPGetProfileWord(RMREG_HDTV_RES) & 0xff;
	      pInfo->IHdtv_c = tmp + 1;
	      IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params[pInfo->IHdtv_c - 1]), g_OutputMode);
	    }
	  else if((g_OutputMode & FMPV_VIDEOOUT_MODE_MASK) == FMPV_VIDEOOUT_TV) 
	    {
	      pInfo->IHdtv_c = 0;
	    }
	}
      
      
      // spawnDiscTimer(pInfo);
      
      FMPPlay();
      pInfo->bABRepeat = 0;
      pInfo->bRepeat = 0;
      pInfo->bAudioStream = 0;
      pInfo->bAngleNumber = 0;
      pInfo->bSPStream = 0xff;
      pInfo->bDiscType = FMPOpenStruct.bDiscContent;

      if(FMPOpenStruct.bDiscContent == FMPC_CDDA)
	retrieveInfo_cdda(pInfo);
      else if(FMPOpenStruct.bDiscContent == FMPC_DVD_VIDEO)
	retrieveInfo_dvd(pInfo);
      else if(FMPOpenStruct.bDiscContent == FMPC_VCD)
	pInfo->bVCDsubtype = FMPGet(FMPI_DISC_TYPE);
      else
	{

	}
      pInfo->playing = PLAYING;
      G_MESSAGE("End of FMPPlay");
    }
}

void handle_Navigation_disc(INFO * pInfo, DWORD direction)
{
  if (pInfo->bDiscType == FMPC_DVD_VIDEO)
    {
      switch(direction)
	{
	case UP:  
	    UpperButtonSelect();	
	  break;
	case LEFT:   
	    LeftButtonSelect();
	  break;
	case DOWN:
	    LowerButtonSelect();
	  break;
	case RIGHT:
	    RightButtonSelect();
	  break;
	case SEL:
	  if(pInfo->blk) 
	    {
	      /* msg = SEL;
		 if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
	      */
	    }
	  else  
	    {
	      ButtonActivate();
	      pInfo->playing = PLAYING;
	      /* 
		 msg = SCR_OFF;
		 if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
	      */
	    }
	  break;
	default:
	  break;
	}
    }
}

void handle_Subtitle_Change_disc(INFO * pInfo)
{
  if (pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      DWORD currSP = FMPGet(FMPI_CURRENT_SUBPICT_STREAM);
      if(pInfo->bSPStream == 0xff) 
	{
	  if ((currSP + 1) >= FMPGet(FMPI_SUBPICTURE_STREAM_AVAILABLE))
	    if(FMPGet(FMPI_SUBPICTURE_ON))
	      pInfo->bSPStream = 0;
	    else 
	      {
		currSP = 0;
		pInfo->bSPStream = 99;
	      }
	  else if(FMPGet(FMPI_SUBPICTURE_ON))
	    pInfo->bSPStream = (BYTE)currSP + 1;
	  else
	    pInfo->bSPStream = 99;
	}
      else if(pInfo->bSPStream != 99 && pInfo->bSPStream > 1)
	pInfo->bSPStream--;
      else if(pInfo->bSPStream == 1) 
	{
	  currSP = 0;
	  pInfo->bSPStream = 99;
	}
      if(!pInfo->bSPStream) 
	{
	  G_PRINT("DVD SUB-TITLE off\n");
	  if(SubPictureStreamChange((BYTE)currSP, 0) != DVDE_UNAUTHORIZED)
	    {
	      // msg = SHOW_SUBTITLE;
	    }
	  else
	    {
	      // msg = SHOW_ERROR;
	    }
	}
      else
	{
	  if(pInfo->bSPStream == 99)
	    pInfo->bSPStream = (BYTE)currSP;
	  if (pInfo->bSPStream >= FMPGet(FMPI_SUBPICTURE_STREAM_AVAILABLE))
	    {
	      // msg = SHOW_ERROR;
	      pInfo->bSPStream = 0xff;
	      // if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
	      // break;
	    }
	  G_PRINT("DVD SUB-TITLE %d\n", pInfo->bSPStream);
	  if(SubPictureStreamChange(pInfo->bSPStream, 1) != DVDE_UNAUTHORIZED)
	    {
	      // msg = SHOW_SUBTITLE;
	    }
	  else
	    {
	      // msg = SHOW_ERROR;
	    }
	}
      pInfo->bSPStream = 0xff;
      // if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
    }
}

void handle_Angle_Change_disc(INFO * pInfo)
{
  if (pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      if(!pInfo->bAngleNumber) 
	{
	  pInfo->bAngleNumber = (BYTE)FMPGet(FMPI_CURRENT_ANGLE) + 1;
	  if (pInfo->bAngleNumber > FMPGet(FMPI_ANGLES_AVAILABLE))
	    pInfo->bAngleNumber = 1;
	}
      G_PRINT("DVD ANGLE %d\n", pInfo->bAngleNumber);
      if(!AngleChange(pInfo->bAngleNumber)) 
	{
	  // msg = SHOW_ANGLE;
	}
      else 
	{
	  // msg = SHOW_ERROR;
	}
      pInfo->bAngleNumber = 0;
      // if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
    }
}

void handle_Langage_Change_disc(INFO * pInfo)
{
  if (pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      if(!pInfo->bAudioStream) 
	{
	  pInfo->bAudioStream = (BYTE)FMPGet(FMPI_CURRENT_AUDIO_STREAM) + 1;
	  if (pInfo->bAudioStream >= FMPGet(FMPI_AUDIO_STREAMS_AVAILABLE))
	    pInfo->bAudioStream = 0;
	}
      else
	{
	  pInfo->bAudioStream--;
	  if (pInfo->bAudioStream >= FMPGet(FMPI_AUDIO_STREAMS_AVAILABLE)) 
	    {
	      // msg = SHOW_ERROR;
	      pInfo->bAudioStream = 0;
	      // if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
	      // break;
	    }
	}
      G_PRINT("DVD LANGUAGE %d\n", pInfo->bAudioStream);
      if(AudioStreamChange (pInfo->bAudioStream) != DVDE_UNAUTHORIZED) 
	{
	  // RS_REPLY('A','S','T');
	  // msg = SHOW_LANGUAGE;
	}
      else
	{
	  // RS_REPLY_ERR('2','7','8');
	  // msg = SHOW_ERROR;
	}
      pInfo->bAudioStream = 0;
      // if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
    }
  if ((pInfo->bDiscType == FMPC_VCD) || (pInfo->bDiscType == FMPC_SVCD)) 
    {
      AudioStreamChange(0);		
      G_PRINT("VCD LANGUAGE\n");
    }
}

void handle_Resume_disc(INFO * pInfo)
{
  DWORD errtype;
  
  if(pInfo->bDiscType == FMPC_DVD_VIDEO)
    {
      errtype = Resume();
      switch(errtype)
	{
	case DVDE_UNAUTHORIZED:
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  break;
	default:
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  break;
	}
    }
  else if(pInfo->bDiscType == FMPC_SVCD ||
	  pInfo->bDiscType == FMPC_VCD)
    {
      errtype = Resume();
      switch(errtype)
	{
	case FMPE_UNEXPECTED:
	case FMPE_FAILURE:
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  break;
	default:
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL); 
	  pInfo->bRepeat = 0;
	  pInfo->bABRepeat = 0;
	  break;
	}
    }
}


void handle_Menu_Call_disc(INFO * pInfo)
{
  if(pInfo->bDiscType == FMPC_VCD || 
     pInfo->bDiscType == FMPC_SVCD) 
    {
      ReturnPGSearch();
      pInfo->playing = PLAYING;
      // msg = SCR_OFF;
    }
  else if(pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      if(MenuCall(DVD_ROOT_ID) == DVDE_UNAUTHORIZED) 
	{
	  //DVD_ROOT_ID = 3
	  // msg = SHOW_ERROR;
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	}
      else 
	{
	  
	  pInfo->playing = PLAYING;
	  refreshTitleChapter(pInfo);
	  // msg = SCR_OFF;
	}
    }
}

void handle_Title_Call_disc(INFO *pInfo)
{
  if(pInfo->bDiscType == FMPC_VCD || 
     pInfo->bDiscType == FMPC_SVCD) 
    {
      DefaultPGSearch();
      pInfo->playing = PLAYING;
      // msg = SCR_OFF;
    }
  else if(pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      if(MenuCall(DVD_TITLE_ID) == DVDE_UNAUTHORIZED) 
	{ 
	  //DVD_TITLE_ID = 4
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  // msg = SHOW_ERROR;
	}
      else 
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  refreshTitleChapter(pInfo);
	}
    }
}

void handle_SubMenu_Call_dvd(INFO *pInfo, BYTE bMenuID)
{
  if(pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      if(MenuCall(bMenuID) == DVDE_UNAUTHORIZED) 
	{ 
	  //DVD_TITLE_ID = 4
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  // msg = SHOW_ERROR;
	}
      else 
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	}
    }
}

void handle_Direct_Play_disc(INFO *pInfo, WORD play)
{

  DWORD errtype;
  
  if(pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      errtype = ChapterSearch(play);
      
      switch(errtype)
	{
	case DVDE_UNAUTHORIZED:
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  break;
	case DVDE_ARG:
	case DVDE_PTTNUMBER:
	  {
	    gchar *msg = NULL;
	    msg = g_strdup_printf("Chapter %03d does not exist !", play);
	    displayMsg(MSG_STATUS_ONLY, 0, msg);
	    g_free(msg);
	  }
	  break;
	default:
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  break;
	}
    }
  else if( pInfo->bDiscType == FMPC_SVCD ||
	   (pInfo->bDiscType == FMPC_VCD && 
	    pInfo->bVCDsubtype == 2))
    {
      BYTE sel = (BYTE) play;
      errtype = NumericSelections(sel);

      switch(errtype)
	{
	case FMPE_UNEXPECTED:
	case FMPE_DISABLED:
	case FMPE_TIMERACTIVATED:
	case FMPE_FAILURE:
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  break;
	case FMPE_INVALIDARG:
	  displayMsg(MSG_STATUS_ONLY, 0, "Selection is out of range !");
	  break;
	default:
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  break;
	}
    }
  else if((pInfo->bDiscType == FMPC_VCD && 
	    pInfo->bVCDsubtype == 1))
    {
      BYTE sel = (BYTE) play;
      errtype = TitlePlay(sel);
      
      switch(errtype)
	{
	case DVDE_ARG:
	case DVDE_TITLENUMBER:
	  {
	    gchar *msg = NULL;
	    msg = g_strdup_printf("Track %02d does not exist !", sel);
	    displayMsg(MSG_STATUS_ONLY, 0, msg);
	    g_free(msg);
	  }
	  break;
	  break;
	case DVDE_UNAUTHORIZED:
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  break;
	default:
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  break;
	}

    }
  else if(pInfo->bDiscType == FMPC_CDDA)
    {
      DWORD track = (DWORD) play;
      errtype = CDDAPlayTrack(track, 0, 0);
      switch(errtype)
	{
	case FMPE_DRIVER_NOT_OPEN:
	case FMPE_CDDA_FAILURE:
	  displayMsg(MSG_BOTH, MSG_ERROR, NULL);
	  break;
	case FMPE_INVALID_PARAMETER:
	  {
	    gchar *msg = NULL;
	    msg = g_strdup_printf("Track %02ld does not exist !", track);
	    displayMsg(MSG_STATUS_ONLY, 0, msg);
	    g_free(msg);
	  }
	  break;
	default:
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	  break;
	}
    }
}

void handle_RepeatAB_Mode_disc(INFO *pInfo)
{
  int pl_tmp = pInfo->playing;
  
  if(pInfo->bDiscType == FMPC_VCD || 
     pInfo->bDiscType == FMPC_SVCD ||
     pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      if(pl_tmp == PLAYING && 
	 pInfo->bABRepeat == 1)
	pInfo->playing = UNDETERMINED;
     
      if(RepeatAB() != DVDE_UNAUTHORIZED) 
	{
	  switch(pInfo->bABRepeat)
	    {
	    case 0:
	      displayRepeatModeMsg("RepeatAB -> set A");
	      break;
	    case 1:
	      displayRepeatModeMsg("RepeatAB -> set B");
	      break;
	    case 2:
	      ClearRepeatAB();
	      displayRepeatModeMsg("RepeatAB -> Clear !");
	      break;
	    default:
	      break;
	    }
	  pInfo->bABRepeat = (pInfo->bABRepeat + 1) % 3;
	  pInfo->bRepeat = 0;
	}
      else
	{
	  displayRepeatModeMsg("UNAUTHORIZED command"); 
	  // msg = SHOW_ERROR;
	}
      pInfo->playing = pl_tmp;
      // if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
    }

}


void handle_Repeat_Mode_disc(INFO *pInfo)
{
  if(pInfo->bDiscType == FMPC_VCD || 
     pInfo->bDiscType == FMPC_SVCD ||
     pInfo->bDiscType == FMPC_DVD_VIDEO) 
    {
      //  msg = SHOW_REPEAT;
      if(!(pInfo->bRepeat) &&
	 ((pInfo->bDiscType == FMPC_VCD) || 
	  (pInfo->bDiscType == FMPC_SVCD)))
	pInfo->bRepeat++;
      if(pInfo->bRepeat == 0)
	{
	  if(RepeatTitle() == DVDE_UNAUTHORIZED) 
	    {
	      displayRepeatModeMsg("UNAUTHORIZED command");
	      // msg = SHOW_ERROR;
	    }
	  else 
	    {
	      displayRepeatModeMsg("Repeat Title");
	      pInfo->bRepeat = 1;
	      pInfo->bABRepeat = 0;
	    }
	}
      else if(pInfo->bRepeat == 2 || pInfo->bRepeat == 1)
	{
	  if(RepeatChapter() == DVDE_UNAUTHORIZED) //Also stops RepeatTitle or RepeatChapter
	    { 
	      displayRepeatModeMsg("UNAUTHORIZED command");
	      // msg = SHOW_ERROR;
	    }
	  else 
	    {
	      if(pInfo->bRepeat == 1)
		{
		  if(pInfo->bDiscType == FMPC_DVD_VIDEO)
		    displayRepeatModeMsg("Repeat Chapter");
		  else
		    displayRepeatModeMsg("Repeat Title");
		}
	      else if(pInfo->bRepeat == 2)
		{
		  displayRepeatModeMsg("Repeat Mode Clear !");
		}
	      pInfo->bRepeat = 4 - (pInfo->bRepeat << 1);
	      pInfo->bABRepeat = 0;
	    }
	}
      // if(pInfo->osdMsgQ) OSPostMessage(pInfo->osdMsgQ, &msg, 1);
    }
  else if(pInfo->bDiscType == FMPC_CDDA)
    {
      if(pInfo->bRepeat == 0)
	{
	  if(CDDARepeat(CDDA_MODE_REPEAT_DISC) != FMPE_OK)
	    {
	      displayRepeatModeMsg("Failure !");
	    }
	  else
	    {
	      displayRepeatModeMsg("Repeat Disc");
	      pInfo->bRepeat = 1;
	    }
	}
      else if(pInfo->bRepeat == 1)
	{
	  if(CDDARepeat(CDDA_MODE_REPEAT_TRACK) != FMPE_OK)
	    {
	      displayRepeatModeMsg("Failure !");
	    }
	  else
	    {
	      displayRepeatModeMsg("Repeat Track");
	      pInfo->bRepeat = 2;
	    } 
	}
      else
	{
	  if(CDDARepeat(CDDA_MODE_REPEAT_NONE) != FMPE_OK)
	    {
	      displayRepeatModeMsg("Failure !");
	    }
	  else
	    {
	      displayRepeatModeMsg("Repeat Mode Cleared !");
	      pInfo->bRepeat = 0;
	    } 
	}
    }
  else
    {
      
    }
}

void handle_Time_Search_disc(INFO *pInfo)
{
  if(pInfo->playing == STOP_FOR_RESUME)
    resumeDisplayFromStop(&ovl);
  
  if(pInfo->playing != CLOSED)
    {
      DWORD res = FMPE_OK;
      if(pInfo->bDiscType == FMPC_DVD_VIDEO && 
	 pInfo->bDomain == VTSTT_DOM)
	{
	  pInfo->totalTime = (DWORD) FMPGet(FMPI_TOTAL_TITLE_TIME);
	  G_WARNING("handle_Time_Search_disc(): Searching On %ld second(s)", 
		    pInfo->totalTime);

	  if( convertHhMmSstoSeconds(pInfo->dwSearch) >= pInfo->totalTime )
	    {
	           G_WARNING("handle_Time_Search_disc(): Bad Arg (%lx)!",
			     pInfo->dwSearch);
                   res = TimeSearch((TCHAR *) 0x00000000);
	    }
	  else
	    {
	           G_WARNING("handle_Time_Search_disc() : Legitimate search !");
	           res = TimeSearch((TCHAR *)(pInfo->dwSearch & 0xffffff));
	    }
	  
	  if(res != DVDE_UNAUTHORIZED && res != DVDE_ARG) 
	    {
	           G_WARNING("May be the timer needs to be ajusted ...");
		   usleep(10*TICK);
	    }
	  else 
	    {
	          G_WARNING(" TimeSearch() FAILED !");
	    } 
	}
      else if(pInfo->bDiscType == FMPC_CDDA)
	{
	  BYTE mins, secs;
	  DWORD total_secs =  convertHhMmSstoSeconds(pInfo->dwSearch);
	 
	  mins =  total_secs / 60;
	  secs =  (total_secs % 60);
	  
	  if(pInfo->playing == PLAYING && pInfo->dwSearch != 0)
	    res = CDDAPlayTrack(pInfo->CDDAcurrenttrack, mins, secs);
	  
	  if(res != FMPE_OK)
	    G_WARNING("CDDAPlayTime FAILED !");
	  else
	    usleep(20*TICK);
	}
      else if(pInfo->bDiscType == FMPC_SVCD)
	{
	  DWORD secs = convertHhMmSstoSeconds(pInfo->dwSearch);

	  res = TimeSearch((TCHAR *)secs);
	  
	  if(res != FMPE_OK)
	    G_WARNING("SVCD Timesearch Failed !!");
	  else
	    usleep(20*TICK);
	}
      else
	{

	}
      
    }
}



void parental_level_violation_error(INFO *info)
{
  gdk_threads_enter();
  g_error("Parental Level Violation !");
  gdk_threads_leave();
  handle_Eject_disc(info);
  info->maddie = 2;
}

void dvd_region_mismatch_error(INFO *info)
{
  gdk_threads_enter();
  g_error("DVD Region Mismatch !");
  gdk_threads_leave();
  handle_Eject_disc(info);
  info->maddie = 1;
}

DWORD Event_Notifications_disc (DWORD dwContext, DWORD dwMsg, DWORD dwValue)
{
  INFO *a;
  a = (INFO*)dwContext;

  switch (dwMsg)
    {
    case FMPM_ERROR:
      a->maddie = 1;
      break;
    case FMPM_STARVATION:
      a->maddie = 1;
      break;
    case FMPM_EOS:
      a->maddie = 1;
      break;
    case FMPM_REGION_MISMATCH:
      dvd_region_mismatch_error(a);
      // displayMsg("Region Mismatch !!");
      // char msg = EJECT1;
      break;
    case FMPM_DVDROM_NOT_READY:
	 
      // char msg = EJECT1;
			
      break;
    case FMPM_DVD_ANGLE_CHANGE:
      // displayMsg("DVD Angle Change");
      break;
    case FMPM_DVD_ANGLES_BLOCK:
      // displayMsg("DVD Angles Block Change");
      break;
    case FMPM_DVD_AUDIO_STREAM_CHANGE:
      // displayMsg("DVD Audio Stream Change");
      break;
    case FMPM_DVD_BUTTONS_CHANGE:
      // displayMsg("DVD Buttons Change");
      break;
    case FMPM_DVD_BUTTON_CHANGE:
      // displayMsg("DVD Button Change");
      break;
    case FMPM_DVD_PROGRAM_START:
      G_WARNING("Program start");
      break;
    case FMPM_DVD_CURRENT_TIME:
      if(a->playing != PLAYING || a->bABRepeat == 2) 
	{ 
	  a->dwTime = dwValue;
	}
      break;
    case FMPM_DVD_DOMAIN_CHANGE:
      a->bDomain = (BYTE)dwValue;
      G_PRINT("******** New Domain : %x **********\n", a->bDomain);
      if(a->bDomain == STOP_STATE) 
	{
	  handle_Stop_Close_disc(a); 
	}
      break;
    case FMPM_DVD_NO_FP_PGC:
      // displayMsg("DVD No FP PGC");
      break;
    case FMPM_DVD_PARENTAL_LEVEL_CHANGE:
      // displayMsg("DVD Parental Level Change");
      break;
    case FMPM_DVD_PARENTAL_ERROR:
      parental_level_violation_error(a);
      // char msg = EJECT1;
      // OSPostMessage(a->msgQueue, &msg, 1);
      break;
    case FMPM_DVD_PARENTAL_CHECK:
      {
	BYTE msg;
	// displayMsg("DVD Check Password for parental control level change");
	if(g_Pass == 0xffffffff ||
	   FMPGetProfileWord(RMREG_PASSW_STATE) == RM_PASSWORD_OFF)
	  return 0;
	// displayMsg("Checking password...");
	a->blk = 1;
	/* do { */
	/* 		  a->symbol = GetSymbol(a->msgQueue, a); */
	/* 		  ReadLibrary(a); */
	/* 		} while(!(a->test)); */
	msg = a->test >> 1;
	a->test = 0;
	return (DWORD)msg;
      }
    case FMPM_DVD_PLAYBACK_STOPPED:
      G_WARNING("DVD playback stopped !!");
      break;
    case FMPM_DVD_STILL_OFF:
      // displayMsg("DVD Still Off");
      break;
    case FMPM_DVD_STILL_ON:
      // displayMsg("DVD Still On");
      break;
    case FMPM_DVD_SUBPICTURE_STREAM_CHANGE:
      // displayMsg("DVD Subpic Stream Change");
      break;
    case FMPM_DVD_TITLE_CHANGE:
      {
	if(a->bDiscType == FMPC_CDDA) 
	  {
	    a->CDDAcurrenttrack = (BYTE)dwValue;
	    G_WARNING("Current CDDA track number = %d", a->CDDAcurrenttrack);
	    usleep(30*TICK);
	  }
	else if(a->bDiscType == FMPC_VCD || a->bDiscType == FMPC_SVCD)
	  {
	    a->bTitle = (BYTE)dwValue;
	    G_WARNING("Current VCD track number = %d",a->bTitle);
	  }
	else 
	  {
	    a->bTitle = (BYTE)dwValue;
	    G_WARNING("Current DVD title number = %d",a->bTitle);
	  }
	break;
      }
    case FMPM_DVD_CHAPTER_CHANGE:
      {
	if(a->playing == TRICK_MODE && dwValue == 0xffffffff) 
	  {
	    a->playing = PLAYING;
	    a->bFast = 0;    
	  }
	a->bChapter = (BYTE)dwValue;
	G_WARNING("DVD chapter number = %d",a->bChapter);
	break;
      }
    case FMPM_TRICK_MODE_CHANGE:
      {
	if(a->playing == TRICK_MODE && dwValue == 0) 
	  {
	    a->playing = PLAYING;
	    a->bFast = 0;
	  }
	break;
      }
    case FMPM_DVD_VALID_UOPS_CHANGE:
      // displayMsg("DVD VALID UOPS Change");
      break;
    case FMPM_CDDA_PSD_END:
      // displayMsg("CDDA End of the playback");
      handle_Stop_Close_disc(a);
      break;
    case FMPM_SVCD_PSD_END:
      // displayMsg("SVCD End of the playback");
      a->playing = VCD_WAITING;
      handle_Stop_Close_disc(a);
      break;
    default:
      break;
    }
  return 0;
}
