//#define __CAPTUREWIN__
/* QuickTime.cpp */


//
// Modifications History
//
//$ LB (22/07/2003) : call DIBsection scol function to create a DIB section from the memory bitmap,
//                    instead of calling ObjBitmap_CreateDIBSection local function (which has been removed),
//                    'cause it crashed the machine while attempting to free the memory
//



#include "Quicktime.h"
#include "bitmap.h"


//#include <windows.h>
//#include "mmemory.h"

/*#include <gl/gl.h>
#include <gl/glu.h>

// Quicktime Includes:
#include "MacTypes.h"
#include "QTML.h"
#include "Movies.h"
#include "TextUtils.h"
*/

#define OBJTYPBITMAP    12

#define pullret(x,y) { for (int n=0;n<x-1;n++) MMpull(m); MMset(m,0,y); return 0; }

void *lpDDsurf=NULL;
void *lpDD=NULL;


#define STRLEN(x) (((strlen(x)+5)>>2)+1)
#define SIZE(x) (((x+5)>>2)+1)

/*extern cbmachine ww;
extern HWND HScol;*/

int QuickTimeObj;
int THREAD_ID;

/* ---------------------------------------------------------------- */
/*                                                                  */
/*    QTInit()                                                      */
/*                                                                  */
/*                                                                  */
/*    Initialize Quicktime                                          */
/*                                                                  */
/*                                                                  */
/*                                                                  */
/* ---------------------------------------------------------------- */

BOOL QTInit()
{
		/* Initialize QuickTime Media Layer */
	if (InitializeQTML(kInitializeQTMLUseGDIFlag) != 0)
//	if (InitializeQTML(0) != 0)
	{
		return (FALSE);
	}

		/* Initialize QuickTime */
	if (EnterMovies() != 0)
	{
		return (FALSE);
	}

/*  QTSetDDObject(lpDD);
  QTSetDDPrimarySurface(lpDDsurf,kDDSurfaceLocked);
  */

	return (TRUE);
}

/* ---------------------------------------------------------------- */
/*                                                                  */
/*    QTCleanUp()                                            */
/*                                                                  */
/*                                                                  */
/*    De-initialize Quicktime                                       */
/*                                                                  */
/*                                                                  */
/*                                                                  */
/* ---------------------------------------------------------------- */

void QTMovie::QTCleanUp()
{
		/* Clean up */
	ExitMovies();
	TerminateQTML();
}




QTMovie::QTMovie() 
{ 
    wnd=0; theMovie=0; theFile=0; 
    strcpy(name,"noname"); 
    framecount=0; lastframecount=0; HBitmap=NULL; hdc=NULL; 
	//newbitmap=false; mythread=NULL; 	
}
  
QTMovie::~QTMovie() 
{ 
	/*if (mythread) 
	{
	    delete (mythread);
	}*/
    if (theMovie) 
    {
      SetMovieDrawingCompleteProc (theMovie,movieDrawingCallWhenChanged,nil,0);
      StopMovie(theMovie);
      DisposeMovie(theMovie);
    }
    if (wnd) DestroyWindow(wnd);
    QTCleanUp(); 
}

int _QTCreateMovieWnd (mmachine m)
{
  int flags,objwin,path,qt;
  HWND hwn=NULL,hwnd;
  PtrObjVoid OB;
  PtrObjWindow Window;
  char pathName[255];                       // Buffer for pathname
  FSSpec fileSpec;                            // File-system specification record
  CGrafPtr windowPort;                          // Window's graphics port
//  OSErr errCode;                             // Result code
  RECT rect;
  QTMovie *movie=NULL;
  

  flags=MMpull(m)>>1;
  objwin=MMpull(m)>>1;
  path=MMpull(m)>>1;

  if (objwin!=NIL) 
  {
    OB = ( PtrObjVoid )MMstart(m,objwin);
    Window = ( ObjWindow *) MMstart(m,OB->Buffer>>1) ;
    hwn=Window->WHandler;
    MMechostr(1,"Good window handler (%x)...\n",hwn);
  }

  if (!hwn || path==NIL) pullret(1,NIL);

  if (!QTInit()) pullret(1,NIL);

  movie=new QTMovie();
  //movie->mythread=new QTThread();



  GetClientRect(hwn,&rect);
  hwnd=CreateWindow("QTScol","QTMovie",WS_CHILD,0,0,rect.right,rect.bottom,hwn,NULL,NULL,movie);
  ShowWindow(hwnd,SW_SHOW);
  UpdateWindow(hwnd);

  if (!hwnd) pullret(1,NIL);

  strcpy(pathName,MMstartstr(m,path));
  StringPtr pst=c2pstr (pathName);                          // Convert to Pascal string
  FSMakeFSSpec (0, 0L, (unsigned char*)pathName, &fileSpec);  // Make specification record

//  CreatePortAssociation (hwnd, nil, 0);
  windowPort = (CGrafPort*)GetNativeWindowPort( hwnd );   // Get window's graphics port
  
  SetGWorld (windowPort, nil);                // Make it the graphics world
        
  OSErr err=OpenMovieFile (&fileSpec, &movie->theFile, fsRdPerm); 
  err=NewMovieFromFile (&movie->theMovie, movie->theFile,             // Get movie from file
                             nil, nil,
                             newMovieActive, nil);


  GetMovieBox (movie->theMovie, &movie->theMovieRect);
  movie->theMovieRect.left=0;
  movie->theMovieRect.right=640;
  movie->theMovieRect.top=0;
  movie->theMovieRect.bottom=480;
  MacOffsetRect (&movie->theMovieRect, -movie->theMovieRect.left, -movie->theMovieRect.top);
  SetMovieBox (movie->theMovie, &movie->theMovieRect);

  StartMovie (movie->theMovie);

  
  qt=MMmalloc(m,1,TYPEBUF);
  if (qt<0) return qt;
  MMstore(m,qt,0,(int)0);
  if (MMpush(m,qt*2+1)) return MERRMEM;
  return OBJcreate(m,QuickTimeObj,(int)0,-1,0);
}


pascal OSErr MyMovieDrawingCompleteProc(Movie theMovie,long refCon)
{
  QTMovie*m;
  m=(QTMovie*) refCon;
  if (theMovie && m)
    m->framecount++;
  return 0;
}

int _QTCreateMovieBmp (mmachine m)
{
  int flags,objbmp,path,qt,k;
  PtrObjVoid OB;
  PtrObjBitmap B;
  char pathName[255];                       // Buffer for pathname
  FSSpec fileSpec;                            // File-system specification record
  GWorldPtr offscreenGWorld;
  OSErr err;
  HDC hdc;//,temphdc;
  QTMovie *movie=NULL;
  Rect MovieRect;


  flags=MMpull(m)>>1;
  objbmp=MMpull(m)>>1;
  path=MMpull(m)>>1;

  if (objbmp==NIL) pullret(1,NIL);

  OB = ( PtrObjVoid ) MMstart(m,objbmp);
  B = ( PtrObjBitmap ) MMstart(m,OB->Buffer>>1);

  //$LB
  if (B->BPP != 24) pullret(1,NIL);
  if (!B->handler) pullret(1,NIL);
  MMechostr(1,"_QTCreateMovieBmp : Good bitmap handler...\n");


  //$ LB (22/07/2003) : call DIBsection scol function to create a DIB section from the memory bitmap
  // stack state : channel 
  if (!B->DIBhandler)
  {
	MMpush (m,objbmp<<1);
	if ((k = MMpush(m, Msearchinsyspak(m, "_DIBbitmap"))) <0)
	{
		MMechostr(0, "\n_QTCreateMovieBmp : error interpreting _DIBbitmap");
		MMset(m, 0, NIL);
		return k;
	}
	// stack state : channel objbitmap "_DIBbitmap"
	Minterpreter(m);
	// stack state : channel objbitmap
	objbmp = MMpull(m)>>1;	
	if (objbmp==NIL) pullret(1,NIL);
	OB = ( PtrObjVoid ) MMstart(m, objbmp);
	B = ( PtrObjBitmap ) MMstart(m, OB->Buffer>>1);
	// stack state : channel 
  }



  if (path==NIL) pullret(1,NIL);
  if (!QTInit()) pullret(1,NIL);

  movie=new QTMovie();
  if (!movie) pullret(1,NIL);


  //movie->mythread=new QTThread();
  //if (!movie->mythread) pullret(1,NIL);

  strcpy(pathName,MMstartstr(m,path));
  StringPtr pst=c2pstr (pathName);                          // Convert to Pascal string
  FSMakeFSSpec (0, 0L, (unsigned char*)pathName, &fileSpec);  // Make specification record

  hdc=(HDC)-1;
/*  temphdc=GetDC(NULL);
  hdc=CreateCompatibleDC(temphdc);
  ReleaseDC(NULL,temphdc);*/

  err=NewGWorldFromHBITMAP
        (&offscreenGWorld, // Returns pointer to GWorld
         NULL,
         NULL,
         0,
         B->DIBhandler,
         hdc);


  SetGWorld (offscreenGWorld, nil);                // Make it the graphics world
  
  movie->HBitmap = B->DIBhandler;
  movie->hdc=hdc;
  movie->offscreenGWorld=offscreenGWorld;
  
  err=OpenMovieFile (&fileSpec, &movie->theFile, fsRdPerm); 
//  SetMovieGWorld(movie->theMovie, offscreenGWorld, GetGWorldDevice(offscreenGWorld));
  err=NewMovieFromFile (&movie->theMovie, movie->theFile,             // Get movie from file
                             nil, nil,
                             newMovieActive, nil);
//  SetMovieGWorld(movie->theMovie, offscreenGWorld, GetGWorldDevice(offscreenGWorld));

  GetMovieBox (movie->theMovie, &movie->theMovieRect);
  GetMovieBox (movie->theMovie, &MovieRect);



  MovieRect.left=0;
  MovieRect.right=B->TailleW;
  MovieRect.top=0;
  MovieRect.bottom=B->TailleH;
  MacOffsetRect (&MovieRect, -MovieRect.left, -MovieRect.top);
  SetMovieBox (movie->theMovie, &MovieRect);
	
  SetMovieDrawingCompleteProc (movie->theMovie,movieDrawingCallWhenChanged,NewMovieDrawingCompleteProc(MyMovieDrawingCompleteProc),(long)movie);

  StartMovie (movie->theMovie);

  
  qt=MMmalloc(m,1,TYPEBUF);
  if (qt<0) return qt;
  MMstore(m,qt,0,(int)movie);
//  MMset(m,0,(int)pDirectSound);
  if (MMpush(m,qt*2+1)) return MERRMEM;
  return OBJcreate(m,QuickTimeObj,(int)movie,OBJTYPBITMAP,objbmp);
}


void MyMoviePrePrerollCompleteProc (Movie theMovie, OSErr prerollErr, void *refcon)
{
  OSErr err;
  MMechostr(1,"************** MyMoviePrePrerollCompleteProc %d\n",prerollErr);
  err=PrerollMovie (theMovie, 0,1);
  MMechostr(1,"Err preroll movie: %d\n",err);
//  StartMovie (movie->theMovie);
  SetMoviePlayHints(theMovie, hintsAllowDynamicResize,hintsAllowDynamicResize);

  GetMovieNextInterestingTime(theMovie,nextTimeMediaSample,0,nil,0,GetMoviePreferredRate(theMovie),nil,nil);
  StartMovie(theMovie);
}

pascal OSErr MyProgressProc (Movie theMovie, short message, short whatOperation, Fixed percentDone, long refcon)
{
  MMechostr(1,"Percent done :%d\n",percentDone);
  return 0;
}

int _QTCreateStreamMovieBmp (mmachine m)
{
  int flags,objbmp,path,qt,k;
  PtrObjVoid OB;
  PtrObjBitmap B;
  char pathName[255];                       // Buffer for pathname
  GWorldPtr offscreenGWorld;
  OSErr err;
  HDC hdc=(HDC)-1;
  HWND hwnd;
  QTMovie *movie=NULL;

  flags=MMpull(m)>>1;
  objbmp=MMpull(m)>>1;
  path=MMpull(m)>>1;

  if (objbmp==NIL) pullret(1,NIL);

  OB = ( PtrObjVoid ) MMstart(m,objbmp);
  B = ( PtrObjBitmap ) MMstart(m,OB->Buffer>>1);
   
  //$LB
  if (B->BPP != 24) pullret(1,NIL);
  if (!B->handler) pullret(1,NIL);
  MMechostr(1,"_QTCreateStreamMovieBmp : Good bitmap handler...\n");

  //$ LB (22/07/2003) : call DIBsection scol function to create a DIB section from the memory bitmap
  // stack state : channel 
  if (!B->DIBhandler)
  {
	MMpush (m,objbmp<<1);
	if ((k = MMpush(m, Msearchinsyspak(m, "_DIBbitmap"))) <0)
	{
		MMechostr(0, "\n_QTCreateMovieBmp : error interpreting _DIBbitmap");
		MMset(m, 0, NIL);
		return k;
	}
	// stack state : channel objbitmap "_DIBbitmap"
	Minterpreter(m);
	// stack state : channel objbitmap
	objbmp = MMpull(m)>>1;	
	if (objbmp==NIL) pullret(1,NIL);
	OB = ( PtrObjVoid ) MMstart(m, objbmp);
	B = ( PtrObjBitmap ) MMstart(m, OB->Buffer>>1);
	// stack state : channel 
  }



  if (path==NIL) pullret(1,NIL);
  if (!QTInit()) pullret(1,NIL);
  movie=new QTMovie();
  //movie->mythread=new QTThread();

  Handle urlDataRef;

  strcpy(pathName,MMstartstr(m,path));
  if  (!( (!strnicmp(pathName,"http://",strlen("http://")))
     ||  (!strnicmp(pathName,"ftp://",strlen("ftp://")))
     ||  (!strnicmp(pathName,"file://",strlen("file://")))
     ||  (!strnicmp(pathName,"rtsp://",strlen("rtsp://"))))
    ) 
  {
    if (movie) 
	{
		delete movie;
	}
	pullret(1,NIL);
  }


  hwnd=NULL;

  SIZE size;
  GetBitmapDimensionEx(B->DIBhandler,&size);
  err=NewGWorldFromHBITMAP
        (&offscreenGWorld, // Returns pointer to GWorld
         NULL,
         NULL,
         0,
         B->DIBhandler,
         hdc);

  SetGWorld (offscreenGWorld, nil);                // Make it the graphics world

  movie->HBitmap=B->DIBhandler;
  movie->hdc=hdc;
  movie->offscreenGWorld=offscreenGWorld;
  
  urlDataRef = NewHandle(strlen(pathName) + 1);
  BlockMoveData(pathName, *urlDataRef, strlen(pathName) + 1);
// ca bloque ici lorsque l'url est http
  err = NewMovieFromDataRef(&movie->theMovie, newMovieActive, nil, urlDataRef, URLDataHandlerSubType);
  
  DisposeHandle(urlDataRef);
  SetMovieGWorld(movie->theMovie, offscreenGWorld, GetGWorldDevice(offscreenGWorld));

  Rect MovieRect;
  GetMovieBox (movie->theMovie, &movie->theMovieRect);
  GetMovieBox (movie->theMovie, &MovieRect);

  MovieRect.left=0;
  MovieRect.right=B->TailleW;
  MovieRect.top=0;
  MovieRect.bottom=B->TailleH;
  MacOffsetRect (&MovieRect, -MovieRect.left, -MovieRect.top);
  SetMovieBox (movie->theMovie, &MovieRect);

  SetMovieDrawingCompleteProc (movie->theMovie,movieDrawingCallWhenChanged,NewMovieDrawingCompleteProc(MyMovieDrawingCompleteProc),(long)movie);
  SetMovieProgressProc(movie->theMovie,NewMovieProgressProc(MyProgressProc),0);

  err=PrePrerollMovie(movie->theMovie, 0, GetMoviePreferredRate(movie->theMovie),NewMoviePrePrerollCompleteProc(MyMoviePrePrerollCompleteProc),(void *)0L);
  MMechostr(1,"Err prepreroll movie: %d\n",err);


   //start the thread for rendering
  //movie->mythread->Start((movie->theMovie),&(movie->newbitmap),(GrafPtr)movie->offscreenGWorld);

  qt=MMmalloc(m,1,TYPEBUF);
  if (qt<0) return qt;
  MMstore(m,qt,0,(int)movie);
  if (MMpush(m,qt*2+1)) return MERRMEM;
  return OBJcreate(m,QuickTimeObj,(int)movie,OBJTYPBITMAP,objbmp);
}




int _QTProcessMovie (mmachine m)
{
  int movie;
  QTMovie* qtmovie;


  movie=MMget(m,0)>>1;
  //MMechostr(1,"Process Movie %d...",movie);
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
//  MMechostr(1,"Process Movie %x...",qtmovie);
  if (!qtmovie) return 0;

  //if ((!qtmovie->theMovie)||(!qtmovie->mythread)) return 0;
  
  if (qtmovie->theMovie) MoviesTask (qtmovie->theMovie, 0);
  
  if ((qtmovie->framecount>qtmovie->lastframecount))// && (qtmovie->newbitmap==true))
  {
    qtmovie->lastframecount=qtmovie->framecount;
    MMset(m,0,2);
  }
  else
    MMset(m,0,0);

  UpdatePort((GrafPtr)qtmovie->offscreenGWorld);
  //qtmovie->newbitmap=false;

  return 0;
}

int _QTStopMovie (mmachine m)
{
  int movie;
  QTMovie* qtmovie;

  movie=MMget(m,0)>>1;
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) StopMovie (qtmovie->theMovie);
  return 0;
}

int _QTPlayMovie (mmachine m)
{
  int movie;
  QTMovie* qtmovie;

  movie=MMget(m,0)>>1;
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
//  if (qtmovie->theMovie) StartMovie (qtmovie->theMovie);
  SetMovieProgressProc(qtmovie->theMovie,NewMovieProgressProc(MyProgressProc),0);
  PrePrerollMovie(qtmovie->theMovie, 0, GetMoviePreferredRate(qtmovie->theMovie),NewMoviePrePrerollCompleteProc(MyMoviePrePrerollCompleteProc),(void *)0L);

  return 0;
}

int _QTIsMovieDone (mmachine m)
{
  int movie;
  QTMovie* qtmovie;

  movie=MMget(m,0)>>1;
  MMset(m,0,NIL);
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) MMset(m,0,IsMovieDone(qtmovie->theMovie)<<1);
  return 0;
}

int _QTSetMovieVolume(mmachine m)
{
  int movie,vol;
  QTMovie* qtmovie;

  vol=MMpull(m)>>1;
  movie=MMget(m,0)>>1;
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) SetMovieVolume(qtmovie->theMovie,(short)(256*((float)vol)/1000.0F));
  return 0;
}

int _QTGetMovieSize(mmachine m)
{
  int movie,size;
  QTMovie* qtmovie;

  movie=MMget(m,0)>>1;
  MMset(m,0,NIL);
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) 
  {
    size=MMmalloc(m,2,TYPETAB);
    if (size<0) return size;
    MMstore(m,size,0,qtmovie->theMovieRect.right*2);
    MMstore(m,size,1,qtmovie->theMovieRect.bottom*2);
    MMset(m,0,size*2+1);
  }
  return 0;
}

int _QTGetMovieDuration(mmachine m)
{
  int movie,dur;
  QTMovie* qtmovie;

  movie=MMget(m,0)>>1;
  MMset(m,0,NIL);
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) 
  {
    dur=MMmalloc(m,2,TYPETAB);
    if (dur<0) return dur;
    MMstore(m,dur,0,GetMovieDuration(qtmovie->theMovie)*2);
    MMstore(m,dur,1,GetMovieTimeScale(qtmovie->theMovie)*2);
    MMset(m,0,dur*2+1);
  }
  return 0;
}

int _QTGetMovieTime(mmachine m)
{
  int movie,dur;
  QTMovie* qtmovie;

  movie=MMget(m,0)>>1;
  MMset(m,0,NIL);
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) 
  {
    dur=MMmalloc(m,2,TYPETAB);
    if (dur<0) return dur;
    MMstore(m,dur,0,GetMovieTime(qtmovie->theMovie,nil)*2);
    MMstore(m,dur,1,GetMovieTimeScale(qtmovie->theMovie)*2);
    MMset(m,0,dur*2+1);
  }
  return 0;
}

int _QTSetMovieTime(mmachine m)
{
  int movie,value;
  QTMovie* qtmovie;

  value=MMpull(m)>>1;
  movie=MMget(m,0)>>1;
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) 
    SetMovieTimeValue(qtmovie->theMovie,value);
  return 0;
}

int _QTForwardOneFrame(mmachine m)
{
  int movie,value;
  long tval;
  QTMovie* qtmovie;

  value=MMpull(m)>>1;
  movie=MMget(m,0)>>1;
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  
  if (qtmovie->theMovie) 
  {
    if (value!=0) value=nextTimeMediaSample;
    else value=nextTimeSyncSample;
    GetMovieNextInterestingTime(qtmovie->theMovie,value,0,nil,GetMovieTime(qtmovie->theMovie,nil),1,&tval,nil);
    SetMovieTimeValue(qtmovie->theMovie,tval);
  }                      
  return 0;
}


#ifdef __CAPTUREWIN__
int _CaptureWindow (mmachine m)
{
  int objbmp,objwin,k;
  PtrObjVoid OB;
  PtrObjBitmap B;
  PtrObjWindow Window;
  HDC hdcScreen,hdcCompatible;
  HWND hwn;

  objwin=MMpull(m)>>1;
  objbmp=MMget(m,0)>>1;

  if (objbmp==NIL) pullret(1,NIL);
  if (objwin==NIL) pullret(1,NIL);

  OB = ( PtrObjVoid ) MMstart(m,objbmp);
  B = ( PtrObjBitmap ) MMstart(m,OB->Buffer>>1);
   
  //$LB
  if (B->BPP != 24) pullret(1,NIL);
  if (!B->handler) pullret(1,NIL);
  MMechostr(1,"_CaptureWindow : Good bitmap handler...\n");


  //$ LB (22/07/2003) : call DIBsection scol function to create a DIB section from the memory bitmap
  // stack state : channel 
  if (!B->DIBhandler)
  {
	MMpush (m,objbmp<<1);
	if ((k = MMpush(m, Msearchinsyspak(m, "_DIBbitmap"))) <0)
	{
		MMechostr(0, "\n_QTCreateMovieBmp : error interpreting _DIBbitmap");
		MMset(m, 0, NIL);
		return k;
	}
	// stack state : channel objbitmap "_DIBbitmap"
	Minterpreter(m);
	// stack state : channel objbitmap
	objbmp = MMpull(m)>>1;	
	if (objbmp==NIL) pullret(1,NIL);
	OB = ( PtrObjVoid ) MMstart(m, objbmp);
	B = ( PtrObjBitmap ) MMstart(m, OB->Buffer>>1);
	// stack state : channel 
  }

  OB = ( PtrObjVoid )MMstart(m,objwin);
  Window = ( ObjWindow *) MMstart(m,OB->Buffer>>1) ;
  hwn=Window->WHandler;
  MMechostr(1,"Good window handler (%x)...\n",hwn);

  // Create a normal DC and a memory DC for the entire screen. The 
  // normal DC provides a "snapshot" of the screen contents. The 
  // memory DC keeps a copy of this "snapshot" in the associated 
  // bitmap. 
 
  hdcScreen = GetDC(hwn); 
  hdcCompatible = CreateCompatibleDC(hdcScreen); 

 
  // Create a compatible bitmap for hdcScreen. 
/* 
  hbmScreen = CreateCompatibleBitmap(hdcScreen, 
                       GetDeviceCaps(hdcScreen, HORZRES), 
                       GetDeviceCaps(hdcScreen, VERTRES)); 
 
  if (hbmScreen == 0) 
      errhandler("hbmScreen", hwnd); */
 
  // Select the bitmaps into the compatible DC. 
 
  if (!SelectObject(hdcCompatible, B->DIBhandler)) MMechostr(1,"Unable to select bitmap ...\n");
 
       //Copy color data for the entire display into a 
       //bitmap that is selected into a compatible DC. 
 
  if (!BitBlt(hdcCompatible, 
         0,0, 
         B->TailleW, B->TailleH, 
         hdcScreen, 
         0,0, 
         SRCCOPY))
         MMechostr(1,"Unable to blit... :-((\n");
 
 
  DeleteDC(hdcCompatible);
  ReleaseDC(hwn,hdcScreen);
  return 0;
}
#endif

LRESULT CALLBACK QTWndProc
        (HWND thisWindow,                       // Handle to window
         UINT msgType,                          // Message type
         WPARAM wParam,                           // Message-dependent parameter
         LPARAM lParam)                           // Message-dependent parameter
{
//  MSG winMsg;                   // Windows message structure
//  EventRecord qtmlEvt;                  // Macintosh event record
//  DWORD msgPos;                   // Mouse coordinates of message
  HDC hdc;
  PAINTSTRUCT PS;
  QTMovie* mov;

  switch ( msgType )
  {   
    case WM_CREATE:
      CreatePortAssociation (thisWindow, NULL, kQTMLHandlePortEvents);
      SetWindowLong(thisWindow,GWL_USERDATA,lParam);
      return 0;
      break;
    case WM_PAINT:
      hdc=BeginPaint(thisWindow,&PS);
      mov=(QTMovie *)GetWindowLong(thisWindow,GWL_USERDATA);
      if (mov)
        if (mov->theMovie) 
          UpdateMovie(mov->theMovie);
      EndPaint(thisWindow,&PS);
      return 0;
    case WM_CLOSE:
      {
      CWindowPtr qtmlPtr;               // Macintosh window pointer
      qtmlPtr = (CGrafPort*)GetHWNDPort(thisWindow);  // Convert to window pointer
      DestroyPortAssociation (qtmlPtr);   // Deregister window
      }
      return 0;
      break;                                      
  } /* end switch ( msgType ) */
  return DefWindowProc(thisWindow,msgType,wParam,lParam);
} /* end WinProc */


int QuickTimeDestroy(mmachine m,int handsys,int objm)
{
  MMechostr(1,"Destroy QuickTime\n");
//  if (mc) DisposeMovieController(mc);
//  mc=NULL;
  QTMovie* movie=(QTMovie*) handsys;
  if (!movie) return 0;
  delete movie;

  MMstore(m,objm>>1,0,0);

  return 0;
}

int _QTDestroyMovie(mmachine m)
{
  int movie;
  QTMovie* qtmovie;

  movie=MMget(m,0)>>1;
  if (movie==NIL) return 0;
  qtmovie=(QTMovie*)MMfetch(m,movie,0);
  if (!qtmovie) return 0;
  

  //return QuickTimeDestroy(m,(long)qtmovie,movie);
  return OBJdelTH(m,QuickTimeObj,(int)qtmovie);
}

#if 0
///////////////////////////////// OPENGL TEST
void DrawQuad()
{
  glBegin( GL_TRIANGLE_STRIP );

  glColor3f( 1.0f, 0.0f, 0.0f ); 
  glVertex3f(  1.0f,  1.0f, 0.0f);
  
  glColor3f( 1.0f, 1.0f, 1.0f ); 
  glVertex3f( -1.0f,  1.0f, 0.0f);

  glColor3f( 0.0f, 1.0f, 0.0f ); 
  glVertex3f( -1.0f, -1.0f, 0.0f);

  glEnd();

  glBegin( GL_TRIANGLE_STRIP );

  glColor3f( 0.0f, 1.0f, 0.0f ); 
  glVertex3f( -1.0f, -1.0f, 0.0f);

  glColor3f( 0.0f, 0.0f, 1.0f ); 
  glVertex3f(  1.0f, -1.0f, 0.0f);
  
  glColor3f( 1.0f, 0.0f, 0.0f ); 
  glVertex3f(  1.0f,  1.0f, 0.0f);
  
  glEnd();
}

void DrawGrid ()
{
  glBegin(GL_LINES);
  for (int i=0;i<11;i++)
  {
    glVertex3d(((double)i-5.0)/10.0,-0.5,0);
    glVertex3d(((double)i-5.0)/10.0,0.5,0);
  }
  for (i=0;i<11;i++)
  {
    glVertex3d(-0.5, ((double)i-5.0)/10.0 ,0);
    glVertex3d(0.5, ((double)i-5.0)/10.0 ,0);
  }
  glEnd();

}

void Resize (int w,int h)
{
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  glViewport(0, 0, w, h);
  gluPerspective(60, (GLdouble) w/ (GLdouble) h, 1, 100000000000000.0);
  glClearDepth(1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glEnable(GL_DEPTH_TEST);
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam )
{
  switch ( message ) 
  {
  case WM_SIZE:
    Resize(LOWORD(lParam),HIWORD(lParam));
    return 0;
  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
  }

}

HWND glwin=NULL;
HDC hDC=NULL;
HGLRC hRC=NULL;

void InitOpenGL(HWND hwnd)
{
  PIXELFORMATDESCRIPTOR pfd;
  int iFormat=0;

  // get the device context (DC)
  hDC = GetDC( hwnd );

  // set the pixel format for the DC
  ZeroMemory( &pfd, sizeof( pfd ) );
  pfd.nSize = sizeof( pfd );
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  pfd.iPixelType = PFD_TYPE_RGBA;
  //$LB
  pfd.cColorBits = 24;
  pfd.cDepthBits = 24;
  pfd.iLayerType = PFD_MAIN_PLANE;


  iFormat = ChoosePixelFormat( hDC, &pfd );

  DescribePixelFormat(hDC,iFormat,sizeof(pfd),&pfd);  

  SetPixelFormat( hDC, iFormat, &pfd );

  // create and enable the render context (RC)
  hRC = wglCreateContext( hDC );
  wglMakeCurrent( hDC, hRC );
}

void InitGL()
{
  WNDCLASS wc;
  int ws=WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;

  // register window class
  wc.style = CS_OWNDC;
  wc.lpfnWndProc = WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = NULL;
  wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
  wc.lpszMenuName = NULL;
  wc.lpszClassName = "ngl";
  RegisterClass( &wc );

  glwin=CreateWindow("ngl", "openGL test", ws, 600,600,640,480, NULL, NULL, NULL, NULL );

  InitOpenGL (glwin);
  Resize (640,480);

  UpdateWindow(glwin);
  ShowWindow(glwin,SW_SHOW);

}

int glTest(mmachine m)
{
  static double rot=0;
  if (!glwin) InitGL();

  MMechostr(1,"Opengl test...\n");
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  
  glClearColor(0,0,1,0);
  glClear(GL_COLOR_BUFFER_BIT);
  glDisable(GL_DEPTH_TEST);

  glPushMatrix();
  glTranslated(0.0,0.0,-2.0);
  glRotated(rot,0,1,0);

  DrawQuad();
  glColor3f(1,1,1);
  DrawGrid();
  
  glPopMatrix();

  SwapBuffers( hDC );
  rot+=0.5;

  return 0;
}

#endif

/////////////////////////////////////////////////////// DEFINITIONS
#define _NQUICKPKG 14

#ifdef __CAPTUREWIN__
#define NQUICKPKG (_NQUICKPKG+1)
#else
#define NQUICKPKG (_NQUICKPKG)
#endif

char * QUICKname [ NQUICKPKG ] = 
{
//  "_QTCreateMovieWnd",       // _QTCreateMovieWnd
  "_QTCreateMovieBmp",       // _QTCreateMovieBmp
  "_QTCreateStreamMovieBmp", // _QTCreateStreamMovieBmp
  "_QTProcessMovie",
  "_QTStopMovie",
  "_QTPlayMovie",
  "_QTIsMovieDone",
  "_QTSetMovieVolume",
  "_QTGetMovieDuration",
  "_QTGetMovieTime",
  "_QTSetMovieTime",
  "_QTGetMovieSize",
  "_QTForwardOneFrame",
  "_QTDestroyMovie",
//  "glTest",
  "QTMovie"                   // QTMovie
#ifdef __CAPTUREWIN__
  ,"_CaptureWindow"
#endif
} ;

char * QUICKtype [ NQUICKPKG ] = 
{
//  "fun [Chn P ObjWin I] QTMovie", // _QTCreateMovieWnd
  "fun [Chn P ObjBitmap I] QTMovie", // _QTCreateMovieBmp
  "fun [Chn S ObjBitmap I] QTMovie", // _QTCreateStreamMovieBmp
  "fun [QTMovie] I",                // _QTProcessMovie
  "fun [QTMovie] QTMovie",          // _QTStopMovie
  "fun [QTMovie] QTMovie",          // _QTPlayMovie
  "fun [QTMovie] I",                // _QTIsMovieDone
  "fun [QTMovie I] QTMovie",        // _QTSetMovieVolume
  "fun [QTMovie] [I I]",            // _QTGetMovieDuration
  "fun [QTMovie] [I I]",            // _QTGetMovieTime
  "fun [QTMovie I] QTMovie",        // _QTSetMovieTime
  "fun [QTMovie] [I I]",            // _QTGetMovieSize
  "fun [QTMovie I] QTMovie",        // _QTForwardOneFrame
  "fun [QTMovie] QTMovie",          // _QTDestroyMovie
//  "fun [I] I",       // QTBidon
  NULL                              // QTMovie,
#ifdef __CAPTUREWIN__
  ,"fun [ObjBitmap ObjWin] ObjBitmap"
#endif
} ;


int QUICKnarg [ NQUICKPKG ] = 
{
//  4,                      // _QTCreateMovieWnd
  4,                      // _QTCreateMovieBmp
  4,                      // _QTCreateStreamMovieBmp
  1,
  1,                      // _QTStopMovie
  1,                      // _QTPlayMovie
  1,                      // _QTIsMovieDone
  2,                      // _QTSetMovieVolume
  1,                      // _QTGetMovieDuration
  1,                      // _QTGetMovieTime
  2,                      // _QTSetMovieTime
  1,                      // _QTGetMovieSize
  2,                      // _QTForwardOneFrame
  1,                      // _QTDestroyMovie
//  1,//QTBidon
  TYPTYPE                 // QTMovie,
#ifdef __CAPTUREWIN__
  ,2
#endif
} ;


int (*QUICKfun[NQUICKPKG])(mmachine m)= 
{
//  _QTCreateMovieWnd,      // _QTCreateMovieWnd
  _QTCreateMovieBmp,      // _QTCreateMovieBmp
  _QTCreateStreamMovieBmp, // _QTCreateStreamMovieBmp
  _QTProcessMovie,
  _QTStopMovie,
  _QTPlayMovie,
  _QTIsMovieDone,
  _QTSetMovieVolume,
  _QTGetMovieDuration,
  _QTGetMovieTime,
  _QTSetMovieTime,
  _QTGetMovieSize,
  _QTForwardOneFrame,
  _QTDestroyMovie,
//  glTest,
  NULL                     // QTMovie,
#ifdef __CAPTUREWIN__
  ,_CaptureWindow
#endif
} ;

//extern "C" __declspec( dllexport ) int SCOLloadQuickTime(mmachine m,cbmachine w)
int SCOLloadQuickTime(mmachine m,cbmachine w)
{
  int k;
  WNDCLASS qtwnd;


  ww=w;
//  k=(ww->PKhardpak(m,"QuickTime.pkg",NPKG,PKGname,PKGfun,PKGnarg,PKGtype));
  k=PKhardpak(m,"QuickTime-1.0.pkg",NQUICKPKG,QUICKname,QUICKfun,QUICKnarg,QUICKtype);
  QuickTimeObj=OBJregister(0,0,QuickTimeDestroy,"QuickTimeObj");
  qtwnd.style=0;
  qtwnd.cbClsExtra=0;
  qtwnd.cbWndExtra=0;
  qtwnd.hbrBackground=0;
  qtwnd.hCursor=LoadCursor(NULL,IDC_ARROW);
  qtwnd.hIcon=NULL;
  qtwnd.hInstance=NULL;
  qtwnd.lpfnWndProc=QTWndProc;
  qtwnd.lpszClassName="QTScol";
  qtwnd.lpszMenuName=NULL;

  RegisterClass(&qtwnd);

  THREAD_ID=0;

  return k;
}

