1/*
2 * MoviePlayer.h --
3 *
4 *	Part of QuickTimeTcl.
5 *
6 * Copyright (c) 2000-2008  Mats Bengtsson
7 *
8 * $Id: MoviePlayer.h,v 1.8 2008/02/15 15:23:06 matben Exp $
9 */
10
11#ifndef INCLUDED_MOVIEPLAYER_H
12#define INCLUDED_MOVIEPLAYER_H
13
14#ifdef _WIN32
15#   include "QuickTimeTclWin.h"
16#endif
17
18#include "QuickTimeTcl.h"
19#include "Tfp_Arrays.h"
20
21#define PiNumber                (3.1415926535898)
22#define RadiansToDegrees(x)     ((x) * 180.0 / PiNumber)
23#ifndef Fixed2Int
24#   define Fixed2Int(f)	    ((f) >> 16)
25#   define Int2Fixed(i)	    ((i) << 16)
26#endif
27
28/*
29 * Some notes about movie editing versus track editing. Movie editing has
30 * high level API's, such as select, cut, copy, paste, using the real scrap
31 * (clipboard). Track editing lacks high level support, and is implemented
32 * using the fake track scrap 'TrackScrap' defined below, which only contains
33 * references, never any actual content.
34 *
35 * We make a track selection record for each movie, see below.
36 * Thus, there can only
37 * be one track selection in each movie.
38 * Notes:
39 *      -   A movie selection should invalidate any track selection for that
40 *          movie.
41 *      -   When something is placed on the real scrap, the fake track scrap
42 *	    should be invalidated.
43 *      -   A track selection sets the movie selection to 0 0.
44 *      -   When something is placed on the fake track scrap, the real scrap
45 *	    should be emptied.
46 */
47
48typedef struct TrackSelection {
49    long        trackID;        /* ID of selected track, 0 if no selection. */
50    TimeValue   startTime;      /* Start of track selection, in movie's time
51				 * coordinates. */
52    TimeValue   duration;       /* And the selections duration, in movie's
53				 * time coordinates. */
54} TrackSelection;
55
56/*
57 * Used for disposing of movie at idle time.
58 */
59
60typedef struct TmpMovieRecord {
61    Movie               movie;
62    MovieController     movieController;
63} TmpMovieRecord;
64
65
66/*
67 * A data structure of the following type is kept for each
68 * movie player that currently exists for this process:
69 */
70
71typedef struct MoviePlayer {
72    Tk_Window	    tkwin;	/* Window for MoviePlayer */
73    Display	    *display;	/* Display containting widget */
74    Tcl_Interp	    *interp;	/* Interpreter for widget */
75    Tcl_Command	    widgetCmd;	/* token for button's widget */
76    Tk_OptionTable  optionTable;
77
78    int		    flags;	/* Various status flags. */
79    int		    state;	/* Tells how the movie should be served,
80				 * on display or loading async remotely. */
81    int		    mheight;	/* The natural movie height and width
82				 * without controller. */
83    int		    mwidth;
84    int		    width;	/* Width of widget; defaults to 0, then
85				 * use natural size. */
86    int		    height;	/* Height of widget; only if specifically
87				 * requested. */
88    int		    padx;	/* X padding */
89    int		    pady;	/* Y padding */
90    XColor 		*highlightBgColorPtr;/* Color for drawing traversal highlight
91     * area when highlight is off. */
92    XColor 		*highlightColorPtr;	/* Color for drawing traversal highlight. */
93    int 		highlightWidth;		/* Width in pixels of highlight to draw
94     * around widget when it has the focus.
95     * <= 0 means don't draw a highlight. */
96    int 		inset;				/* Number of pixels on the left and right
97     * sides that are taken up by xpad,
98     * and highlightWidth (if any). */
99    int 		volume;				/* volume control */
100    Movie 		aMovie;				/* Movie pointer */
101    MovieController aController; 	/* The movie controller */
102    int 		wantController;     /* 1 if we want a controller, 0 otherwise */
103    int			controllerHeight;	/* Height of controller bar, if any. */
104    int			resizable;			/* If we want the movie to be resizable via
105     * the controller. */
106    int			custombutton;		/* Custom button in the mc bar? */
107    int         loopstate;          /* Movie loopstate. */
108    int         palindromeloopstate;/* Movie palindrome loopstate. Goes back
109     * and forth. */
110    int         mcEdit;             /* Boolean if selection vie the controller. */
111    Fixed       rate;               /* The play rate. */
112    double      preferredRate;      /* The preferred play rate. */
113    int			isVisual;			/* If something for eyes; needed on Windows
114     * to serve audio only. */
115    char 		*filename;			/* File name to read movie from.
116     * Only pointer to string in 'fileNamePtr' */
117    Tcl_Obj		*fileNamePtr;		/* Corresponding object representation. */
118    char 		*url;				/* Url to fetch movie from. */
119    long        loadState;          /* The load state 'kMovieLoadState...' when
120     * async url.
121     * This is an Apple constant, different
122     * from 'state' above. */
123    char		*loadCommand;		/* Tcl callback procedure that tells the
124     * -url status. */
125    int         loadIntoRam;        /* Boolean if load into ram. */
126    int 		undoCount;			/* undo counter, is the array index of the
127     * next editStates[] to use. */
128    QTVRInstance    qtvrInstance;   /* For QTVR movies we operate on this thing,
129     * and therefore cache it here.
130     * For ordinary movies it should be NULL. */
131    int        	indQTVRQualityStatic; /* Render quality for QTVR, static. */
132    int         indQTVRQualityMotion; /* Render quality for QTVR, motion. */
133    int         swing;              /* For QTVR movies: boolean, makes soft
134     * camera movements. */
135    int         swingSpeed;         /* For QTVR movies: number from 1 to 10
136     * giving the camera speed. */
137    QTVRInterceptUPP funcQTVRIntercept;
138    /* The controller callback intercept
139     * procedure for QTVR. */
140    MovieEditState  *editStates; 	/* Array of movie edit states */
141    int 		editStatesSize;     /* size of above array */
142    TrackSelection  *trackSelect;   /* The track selection record, see above. */
143    short 		resourceNumber;		/* resource number, should be -1 when the
144     * movie is in the data fork. */
145    GWorldPtr   grafPtr;            /* We save the actual graf port so we don't
146     * need to call SetMovieGWorld if not
147     * changed, it costs! */
148    char 		*progressProc;		/* Called by the movie toolbox.
149     * Text string for tcl proc. */
150    int         qtprogress;         /* Boolean; want standard QuickTime
151     * progress or not. */
152    char 		*mcCallbackProc;	/* Called by the movie controller when
153     * processing events. */
154    int         insideMCCommand;    /* Ref count set when enter/exit the
155     * -mccommand tcl proc. */
156    Tcl_HashTable *asyncLoadHashTablePtr; /* Keep a hash table for async
157     * callbacks during async loading. */
158    Tcl_HashTable *callBackHashTablePtr; /* Keep a hash table for registered
159     * callbacks. */
160    TmpMovieRecord  *tmpMovieRecordPtr;/* Used to hold movie and controller for
161     * destruction at idle time. */
162#ifdef _WIN32
163    HWND        hwnd;               /* Cache the Windows win handle.
164     * NULL signals port association */
165    LONG	    winEventProc;       /* Original event procedure (Windows). */
166#endif
167} MoviePlayer;
168
169/*
170 * We keep a global fake clipboard for tracks. Only one global copy!
171 * If empty scrap, the gTrackScrap.movPtr is NULL.
172 */
173
174typedef struct TrackScrap {
175    TrackSelection  trackSelect;
176    MoviePlayer     *movPtr;
177} TrackScrap;
178
179/*
180 * We need a global doubly linked list for our movies since we cant get them
181 * to the Mac native event handler in any other way.
182 */
183
184typedef struct MoviePlayerList {
185    MoviePlayer                 *movPtr;
186    struct MoviePlayerList      *prev;
187    struct MoviePlayerList      *next;
188} MoviePlayerList;
189
190/*
191 * Flag bits for grabber used in 'flags' in MoviePlayer struct:
192 *
193 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler has already been
194 *						queued to redraw this window.
195 * NEWGWORLD:			Non-zero means this widget has a new GWorld, and that we need
196 *						to associate the movie with this GWorld. Need to
197 *						know when displaying.
198 * UPDATEMOVIE:			This flag bit is set when received an Expose (update)
199 *						event in the tcl event procedure. Only applicable for
200 *						movies without a movie.
201 * MOVIE_DELETED:		Non-zero needs that this button has been
202 *						deleted, or is in the process of being deleted.
203 */
204
205#define REDRAW_PENDING 		(1L << 0)
206#define NEWGWORLD 			(1L << 1)
207#define UPDATEMOVIE 		(1L << 2)
208#define NEED_PREROLL 		(1L << 3)
209#define GOT_FOCUS			(1L << 4)
210#define MOVIE_DELETED 		(1L << 5)
211
212#define CONTROLLER_WIDTH	160
213#define UNDO_SIZE 			100		/* Allocate increment for undo stack */
214
215/*
216 * We need some constants for the state member in the MoviePlayer struct.
217 * It is used to determine how a movie should be served.
218 */
219
220enum {
221    kQTTclMovieStateOnDisplay		= 0x0001,
222    kQTTclMovieStateAsyncLoading	= 0x0002,
223    kQTTclMovieStateAsyncHasWorld	= 0x0004      /* For knowing if 'MoviePlayerWorldChanged'
224     * has been called when async loading. */
225};
226
227/*
228 * The ExitHandlerProc is in certain situations called BEFORE the
229 * widgets receive the DestroyNotify event and we must therefore
230 * NEVER do final cleanup before all movies have been properly freed.
231 * We keep a global state variable to keep track of this.
232 */
233
234enum QTTclFreeState {
235    kQTTclExitStateExitHandlerCalled		= 1,
236    kQTTclExitStateAllFreed					= 2
237};
238
239enum {
240    kDoesCodecPixmapDepth                       = 0L,
241    kDoesCodecCompressDepth
242};
243
244enum {
245    kCompressFlagColorDepth                     = (1L << 0),
246    kCompressFlagCompressor                     = (1L << 1),
247    kCompressFlagDialog                         = (1L << 2),
248    kCompressFlagKeyFrameRate                   = (1L << 3),
249    kCompressFlagSpatialQuality                 = (1L << 4),
250    kCompressFlagTemporalQuality                = (1L << 5)
251};
252
253enum {
254    kQTTclNormalLooping		= 0,
255    kQTTclPalindromeLooping	= 1,
256    kQTTclNoLooping			= 2
257};
258
259int 			ProcessTracksObjCmd(ClientData clientData,
260					    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] );
261void 			TracksCommandFree( void );
262int 			LogUndoState( MoviePlayer *movPtr, Tcl_Interp *interp );
263int 			AddImagesToMovie( Tcl_Interp *interp, Media myMedia,
264					 TimeValue duration, int nPhotos, Tk_PhotoHandle *photoList,
265					 int showDialog, CodecType codecType,
266					 CodecQ spatialQuality, CodecQ temporalQuality,
267					 short colorDepth, long keyFrameRate,
268					 TimeValue *sampleTime );
269int             AddImageFileToMovie( Tcl_Interp *interp, Media myMedia,
270				    TimeValue duration, char *fileName, long optFlags,
271				    int showDialog, CodecType codecType, CodecQ spatialQuality,
272				    CodecQ temporalQuality, short colorDepth,
273				    long keyFrameRate, TimeValue *sampleTimePtr );
274void 			MoviePlayerWorldChanged( ClientData clientData );
275
276int				GetMovieStartTimeFromObj( Tcl_Interp *interp, Movie movie,
277							 Tcl_Obj *obj, long *timeValuePtr );
278int				GetMovieDurationFromObj( Tcl_Interp *interp, Movie movie,
279							Tcl_Obj *obj, long movTime, long *durValuePtr );
280
281/*
282 * TimeCode, UserData:
283 */
284
285int	    TimeCodeCmd( Tcl_Interp *interp, MoviePlayer *movPtr,
286		int objc, Tcl_Obj *CONST objv[] );
287int	    GetUserDataListCmd( UserData userData, Tcl_Interp *interp );
288int	    SetUserDataListCmd( UserData userData, Tcl_Interp *interp,
289		int objc, Tcl_Obj *CONST objv[] );
290void	    UserDataHashTablesFree( void );
291
292
293int	    ProcessEffectCmd( Tcl_Interp *interp, MoviePlayer *movPtr,
294		int objc, Tcl_Obj *CONST objv[] );
295int	    ProcessExportCmd( Tcl_Interp *interp, Movie theMovie,
296		int objc, Tcl_Obj *CONST objv[] );
297Boolean	    EffectsHandleDialogEvents( EventRecord *eventPtr,
298		DialogItemIndex itemIndex );
299void	    ExportComponentSettingsFree( void );
300void	    EffectsInit( void );
301void	    EffectsFree( void );
302
303int	    ProcessCallBackCmd( MoviePlayer *movPtr, int objc,
304		Tcl_Obj *CONST objv[] );
305void	    CallBackFree( MoviePlayer *movPtr );
306
307
308/* Non-tk specific routines. */
309
310OSErr	    GetFirstVideoTrackInMovie( Movie theMovie, Track *theTrack );
311void	    ShowControllerButton( MovieController theMC, long theButton );
312void	    HideControllerButton( MovieController theMC, long theButton );
313void	    SetMovieLoopState( Movie theMovie, UInt8 theLoopState );
314void	    SetLoopingState( MovieController theMC,
315		UInt8 theLoopState );
316Boolean	    IsMovieLooping( Movie theMovie );
317void	    MoviePrePrerollCompleteProc( Movie theMovie,
318		OSErr err, void *refConst );
319OSType          GetControllerType( Movie theMovie );
320Boolean         IsQTVRMovie( Movie theMovie );
321short			GetControllerBarHeight( MovieController mc );
322QTVRInstance    GetQTVRInstanceFromController( MovieController mc );
323pascal void     MyQTVRInterceptProc( QTVRInstance qtvrInst,
324				    QTVRInterceptPtr msg, SInt32 refCon, Boolean *cancel );
325int           	TranslateTclListToMatrixRecord( Tcl_Interp *interp,
326					       Tcl_Obj *listObjPtr, MatrixRecord *mr );
327int             TranslateMatrixRecordToTclList( Tcl_Interp *interp,
328					       Tcl_Obj **listObj, MatrixRecord *mr );
329int             DoesCodecSupport( CodecType cType, long what, int value );
330int             IsTrackForEyes( Track myTrack );
331
332
333#endif	// INCLUDED_MOVIEPLAYER_H
334