pkg://mpeg_wdgt2.0b.tar.gz:88693/mpeg.c
downloads
#include "mpegP.h"
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
int ditherType;
int loopFlag = 0;
int quietFlag = 0;
int shmemFlag = 0;
int noDisplayFlag = 0;
static FILE *input;
static int EOF_flag = 0;
/* jump_buf not used, but is used in standalone mpeg_play */
jmp_buf env;
/* if we don't allow LUM_RANGE to vary, need only one copy
* of the following structures
*/
extern int LUM_RANGE; /* in gdith.c */
extern int CR_RANGE;
extern int CB_RANGE;
extern int *lum_values;
extern int *cr_values;
extern int *cb_values;
/******** external fnctions used ******/
#ifdef _NO_PROTO
extern VidStream *NewVidStream ();
extern void SetWindowVbls ()
extern void GetWindowVbls ();
extern void InitDisplay ();
extern int mpegVidRsrc ();
extern void DestroyVidStream ();
extern int mpegInitVidRsrc ();
#else
extern VidStream *NewVidStream (int bufLength);
extern void SetWindowVbls (Display *_display,
Window _window,
Colormap _cmap,
XImage *_ximage,
GC _gc);
extern void GetWindowVbls (Colormap *_cmap,
XImage **_ximage,
GC *_gc);
extern void InitDisplay (int ditherType, char *name);
extern int mpegVidRsrc (TimeStamp time_stamp, VidStream *vid_stream);
extern void DestroyVidStream (VidStream *astream);
extern int mpegInitVidRsrc (void);
#endif /* _NO_PROTO */
#define BUF_LENGTH 40000
/******** Static Function Declarations ********/
#ifdef _NO_PROTO
static void ClassInitialize() ;
static void ClassPartInitialize() ;
static void SetSize() ;
static void Initialize() ;
static void Realize();
static XtGeometryResult QueryGeometry() ;
static void Destroy() ;
static void Redisplay() ;
static Boolean SetValues() ;
#ifdef MPEG_IS_MOTIF_WIDGET
static void Enter() ;
static void Leave() ;
static void Help() ;
#endif
#else
static void ClassInitialize( void ) ;
static void ClassPartInitialize(
WidgetClass c) ;
static void SetSize(
Widget wid) ;
static void Initialize(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static void Realize (
Widget wid,
XtValueMask *value_mask,
XSetWindowAttributes *attibutes) ;
static XtGeometryResult QueryGeometry(
Widget wid,
XtWidgetGeometry *intended,
XtWidgetGeometry *reply) ;
static void Destroy(
Widget w) ;
static void Redisplay(
Widget wid,
XEvent *event,
Region region) ;
static Boolean SetValues(
Widget cw,
Widget rw,
Widget nw,
ArgList args,
Cardinal *num_args) ;
#ifdef MPEG_IS_MOTIF_WIDGET
static void Enter(
Widget wid,
XEvent *event,
String *params,
Cardinal *num_params) ;
static void Leave(
Widget wid,
XEvent *event,
String *params,
Cardinal *num_params) ;
static void Help(
Widget wid,
XEvent *event,
String *params,
Cardinal *num_params) ;
#endif /* MPEG_IS_MOTIF */
#endif /* _NO_PROTO */
/******** End Static Function Declarations ********/
/* default translations and action recs */
static XtTranslations default_parsed;
#define defaultTranslations _Xmpeg_defaultTranslations
static XtActionsRec ActionsList[] = {
#ifdef MPEG_IS_MOTIF_WIDGET
{"Enter", Enter},
{"Leave", Leave},
{"Help", Help},
#endif
};
/* these names must match the constants in video.h */
static String MpegDitherNames [] =
{ "hybrid", "hybrid2", "fs4",
"fs2", "fs2fast", "2x2", "gray",
"color", "none", "ordered", "mono", "threshold",
"ordered2", "mbordered", "mono2", "halftone"
};
/* here are the resources that this widget adds */
#define XtRDither "Dither"
static XtResource resources[] =
{
#ifdef MPEG_IS_MOTIF_WIDGET
{
XmNtraversalOn,
XmCTraversalOn,
XmRBoolean,
sizeof (Boolean),
XtOffsetOf( struct _XmPrimitiveRec, primitive.traversal_on),
XmRImmediate,
(XtPointer) False
},
#endif
{
XtNdither,
XtCDither,
XtRDither,
sizeof (int),
XtOffsetOf (struct _XmpegRec, mpeg.ditherType),
XtRImmediate,
(XtPointer) ORDERED_DITHER
},
{
XtNsource,
XtCSource,
XtRString,
sizeof (String),
XtOffsetOf (struct _XmpegRec, mpeg.source),
XtRString,
(XtPointer) NULL
},
{
XtNshowCount,
XtCShowCount,
XtRInt,
sizeof (int),
XtOffsetOf (struct _XmpegRec, mpeg.showCount),
XtRImmediate,
(XtPointer) MPEG_PLAY_TO_END
},
{
XtNmovieStoppedCallback,
XtCCallback,
XtRCallback,
sizeof (XtCallbackList),
XtOffsetOf (struct _XmpegRec, mpeg.movie_stopped_callback),
XtRPointer,
(XtPointer) NULL
},
};
/* Definition for resources that need special processing in get values */
/*
static XmSyntheticResource syn_resources[] =
{
};
*/
externaldef ( xmmpegclassrec) XmpegClassRec xmpegClassRec = {
{
#ifdef MPEG_IS_MOTIF_WIDGET
/* superclass */ (WidgetClass) &xmPrimitiveClassRec,
#else
/* superclass */ (WidgetClass) &widgetClassRec,
#endif
/* class_name */ "Xmpeg",
/* widget_size */ sizeof(XmpegRec),
/* class_initialize */ ClassInitialize,
/* chained class init */ ClassPartInitialize,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize hook */ NULL,
/* realize */ Realize,
/* actions */ ActionsList,
/* num_actions */ XtNumber(ActionsList),
/* resources */ resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ XtExposeCompressMaximal,
/* compress enter/exit*/ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ SetSize,
/* expose */ Redisplay,
/* set_values */ SetValues,
/* set values hook */ NULL,
/* set values almost */ XtInheritSetValuesAlmost,
/* get values hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback offsetlst */ NULL,
/* default trans */ NULL,
/* query geo proc */ QueryGeometry,
/* display accelerator*/ NULL,
/* extension record */ NULL,
},
#ifdef MPEG_IS_MOTIF_WIDGET
/* Motif 1.1 doesn't have this: */
#ifndef XmInheritBorderHighlight
#define XmInheritBorderHighlight ((XtWidgetProc) _XtInherit)
#endif
{ /* Xmprimitive */
XmInheritBorderHighlight, /* border_highlight */
XmInheritBorderUnhighlight, /* border_unhighlight */
XtInheritTranslations, /* translations */
NULL, /* arm_and_activate */
NULL, /* syn resources */
0, /* num syn_resources */
NULL, /* extension */
},
#endif
{ /* Xmpeg */
0, /* foo */
}
};
externaldef( xmmpegwidgetclass) WidgetClass xmpegWidgetClass =
(WidgetClass) &xmpegClassRec;
/*
*--------------------------------------------------------------
*
* get_more_data --
*
* Called by correct_underflow in bit parsing utilities to
* read in more data.
*
* Results:
* Input buffer updated, buffer length updated.
* Returns 1 if data read, 0 if EOF, -1 if error.
*
* Side effects:
* None.
*
* NB:
* This function is copied from main.c, and uses static "input"
*
*--------------------------------------------------------------
*/
#ifdef _NO_PROTO
int
get_more_data(buf_start, max_length, length_ptr, buf_ptr)
unsigned int *buf_start;
int max_length;
int *length_ptr;
unsigned int **buf_ptr;
#else
int
get_more_data(
unsigned int *buf_start,
int max_length,
int *length_ptr,
unsigned int **buf_ptr)
#endif
{
int length, num_read, i, request;
unsigned char *buffer, *mark;
unsigned int *lmark;
if (EOF_flag) return 0;
length = *length_ptr;
buffer = (unsigned char *) *buf_ptr;
if (length > 0) {
memcpy((unsigned char *) buf_start, buffer, (length*4));
mark = ((unsigned char *) (buf_start + length));
}
else {
mark = (unsigned char *) buf_start;
length = 0;
}
request = (max_length-length)*4;
num_read = fread( mark, 1, request, input);
/* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
{
int num_read_rounded;
unsigned char *index;
num_read_rounded = 4*(num_read/4);
/* this can happen only if num_read<request; i.e. end of file reached */
if( num_read_rounded < num_read )
{
num_read_rounded = 4*( num_read/4+1 );
/* fill in with zeros */
for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
/* advance to the next 4-byte boundary */
num_read = num_read_rounded;
}
}
if (num_read < 0) {
return -1;
}
else if (num_read == 0) {
*buf_ptr = buf_start;
/* Make 32 bits after end equal to 0 and 32
bits after that equal to seq end code
in order to prevent messy data from infinite
recursion.
*/
*(buf_start + length) = 0x0;
*(buf_start + length+1) = SEQ_END_CODE;
EOF_flag = 1;
return 0;
}
lmark = (unsigned int *) mark;
num_read = num_read/4;
for (i=0; i<num_read; i++) {
*lmark = htonl(*lmark);
lmark++;
}
*buf_ptr = buf_start;
*length_ptr = length + num_read;
return 1;
}
/*********************************************************************
*
* ToLower
* convert a string to lower case
*
*
********************************************************************/
#ifdef _NO_PROTO
static void
ToLower (src, dst)
char *src;
char *dst;
#else
static void
ToLower (char *src, char *dst)
#endif
{
while (*src != '\0')
*dst++ = tolower (*src++);
*dst = '\0';
}
/*********************************************************************
*
* XmpegCvtStringToDither
* convert a string to dither type
*
*
********************************************************************/
#ifdef _NO_PROTO
static Boolean
XmpegCvtStringToDither (display, args, *num_args, from, to, destructor_data)
Display *display;
XrmValuePtr args;
Cardinal *num_args;
XrmValuePtr from;
XrmValuePtr to;
XtPointer destructor_data;
#else
static Boolean
XmpegCvtStringToDither (
Display *display,
XrmValuePtr args,
Cardinal *num_args,
XrmValuePtr from,
XrmValuePtr to,
XtPointer *destructor_data)
#endif
{
#define DITHER_LEN 30
char lower [DITHER_LEN];
static short int i;
if (strlen(from->addr) >= DITHER_LEN)
{
XtDisplayStringConversionWarning (display,
from->addr, XtRDither);
return False;
}
ToLower ((char *)from->addr, lower);
for (i = 0; i < XtNumber (MpegDitherNames); i++)
if (strcmp (lower, MpegDitherNames [i]) == 0)
{ if (to->addr != NULL)
{ if (to->size < sizeof (short))
{ to->size = sizeof (short);
return False;
}
* (short *) (to->addr) = i;
to->size = sizeof (short);
}
else
{
to->addr = (caddr_t) &i;
}
return True;
}
XtDisplayStringConversionWarning (display, from->addr, XtRDither);
return False;
#undef DITHER_LEN
}
/*********************************************************************
*
* ClassInitialize
* This is the class initialization routine. It is called only
* the first time a widget of this class is initialized.
*
********************************************************************/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
ClassInitialize()
#else
ClassInitialize( void )
#endif /* _NO_PROTO */
{
/* add the string to dither converter */
XtSetTypeConverter (XtRString, XtRDither,
XmpegCvtStringToDither,
NULL, 0,
XtCacheNone, NULL);
LUM_RANGE = 8;
CR_RANGE = CB_RANGE = 4;
lum_values = (int *) malloc(LUM_RANGE*sizeof(int));
cr_values = (int *) malloc(CR_RANGE*sizeof(int));
cb_values = (int *) malloc(CB_RANGE*sizeof(int));
init_tables ();
}
/*********************************************************************
*
* ClassPartInitialize
* Processes the class fields which need to be inherited.
*
************************************************************************/
static void
#ifdef _NO_PROTO
ClassPartInitialize( c )
WidgetClass c ;
#else
ClassPartInitialize(
WidgetClass c )
#endif /* _NO_PROTO */
{
register XmpegWidgetClass wc = (XmpegWidgetClass) c ;
XmpegWidgetClass super = (XmpegWidgetClass)wc->core_class.superclass;
/* old code
if (wc->core_class.resize == XmInheritResize)
wc->core_class.resize = super->core_class.resize;
if (wc->core_class.realize == XmInheritRealize)
wc->core_class.realize = super->core_class.realize;
*/
#ifdef MPEG_IS_MOTIF_WIDGET
_XmFastSubclassInit (wc, XmPRIMITIVE_BIT);
#endif
}
/*********************************************************************
*
* Realize
* Processes the class fields which need to be inherited.
*
************************************************************************/
static void
#ifdef _NO_PROTO
Realize ()
Widget wid;
XtValueMask *value_mask;
XSetWindowAttributes *attributes;
#else
Realize (
Widget wid,
XtValueMask *value_mask,
XSetWindowAttributes *attributes)
#endif /* _NO_PROTO */
{
int ncolors = LUM_RANGE * CB_RANGE * CR_RANGE;
XColor xcolor;
int i, lum_num, cr_num, cb_num;
unsigned char r, g, b;
Colormap dcmap;
XmpegWidget mw = (XmpegWidget) wid ;
XtCreateWindow (wid, InputOutput, CopyFromParent, *value_mask, attributes);
SetWindowVbls(XtDisplay(mw), XtWindow(mw), mw->mpeg.cmap, mw->mpeg.ximage, mw->mpeg.gc);
InitDisplay(mw->mpeg.ditherType, NULL);
GetWindowVbls(&(mw->mpeg.cmap), &(mw->mpeg.ximage), &(mw->mpeg.gc));
}
/************************************************************************
*
* SetSize
* Sets new width, new height, and new mpeg.TextRect
* appropriately. This routine is called by Initialize and
* SetValues.
*
************************************************************************/
static void
#ifdef _NO_PROTO
SetSize( wid )
Widget wid ;
#else
SetSize(
Widget wid )
#endif /* _NO_PROTO */
{
XmpegWidget newlw = (XmpegWidget) wid ;
XmpegPart *mp;
mp = &(newlw->mpeg);
/* Has a width been specified? */
if (newlw->core.width == 0)
newlw->core.width = (Dimension) mp->window_width;;
/* Has a height been specified? */
if (newlw->core.height == 0)
newlw->core.height = (Dimension) mp->window_height;
}
/************************************************************
*
* Initialize
* This is the widget's instance initialize routine. It is
* called once for each widget
*
************************************************************/
static void
#ifdef _NO_PROTO
Initialize( req, new_w, args, num_args )
Widget req ;
Widget new_w ;
ArgList args ;
Cardinal *num_args ;
#else
Initialize(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args )
#endif /* _NO_PROTO */
{
XmpegWidget mw = (XmpegWidget) new_w;
Arg m_args[1];
int n;
int i;
Display *display = XtDisplay (mw);
int screen = DefaultScreen (display);
XVisualInfo vinfo;
/* set some of the widget fields */
mw->mpeg.EOF_flag = EOF_flag = 0;
if (mw->mpeg.source != NULL)
mw->mpeg.source = XtNewString (mw->mpeg.source);
/*
Check that ditherType requested can be supported
*/
ditherType = mw->mpeg.ditherType;
if (ditherType == FULL_COLOR_DITHER &&
!XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo))
{
XtWarning ("Full color not supported, trying 8 bit color");
ditherType = mw->mpeg.ditherType = ORDERED_DITHER;
}
if ((ditherType == HYBRID_DITHER ||
ditherType == HYBRID2_DITHER ||
ditherType == FS4_DITHER ||
ditherType == FS2_DITHER ||
ditherType == FS2FAST_DITHER ||
ditherType == Twox2_DITHER ||
ditherType == ORDERED_DITHER ||
ditherType == ORDERED2_DITHER ||
ditherType == MBORDERED_DITHER) &&
!XMatchVisualInfo (display, screen, 8, PseudoColor, &vinfo))
{
XtWarning ("Color not supported, trying grayscale");
ditherType = mw->mpeg.ditherType = GRAY_DITHER;
}
if (ditherType == GRAY_DITHER &&
!XMatchVisualInfo (display, screen, 8, GrayScale, &vinfo))
{
XtWarning ("Grayscale not supported, using black and white");
ditherType = mw->mpeg.ditherType = MONO_DITHER;
}
/* If zero width and height was requested by the application, */
/* reset new_w's width and height to zero to allow SetSize() */
/* to operate properly. */
if (req->core.width == 0)
mw->core.width = 0;
if (req->core.height == 0)
mw->core.height = 0;
/*
_XmCalcMpegDimensions(new_w);
*/
/* get the image file */
if (mw->mpeg.source == NULL)
input =stdin;
else if ((input = fopen (mw -> mpeg.source, "r")) == NULL)
XtError ("Can't open image file");
mw->mpeg.input = input;
ditherType = mw -> mpeg.ditherType;
mw->mpeg.movieStatus = XmpegMOVIE_NOT_STARTED;
InitDitherType (mw->mpeg.ditherType);
mw->mpeg.theStream = NewVidStream (BUF_LENGTH);
mw->mpeg.ximage = NULL;
mpegVidRsrc (0, mw->mpeg.theStream);
if (ditherType == Twox2_DITHER) i = 2;
else if (ditherType == HALFTONE_DITHER) i = 4;
else i = 1;
/* find and set widget size */
mw -> mpeg.window_width = curVidStream -> h_size * i;
mw -> mpeg.window_height = curVidStream -> v_size * i;
(* (mw->core.widget_class->core_class.resize)) ((Widget) mw);
}
/************************************************************************
*
* QueryGeometry
*
************************************************************************/
static XtGeometryResult
#ifdef _NO_PROTO
QueryGeometry( widget, intended, desired )
Widget widget ;
XtWidgetGeometry *intended ;
XtWidgetGeometry *desired ;
#else
QueryGeometry(
Widget widget,
XtWidgetGeometry *intended,
XtWidgetGeometry *desired )
#endif /* _NO_PROTO */
{
XmpegWidget mw = (XmpegWidget) widget ;
#define Set(bit) (intended->request_mode & bit)
desired->width = mw->mpeg.window_width;
desired->height = mw->mpeg.window_height;
desired->request_mode = CWWidth | CWHeight;
if (Set(CWWidth) & intended->width == desired->width &&
Set(CWHeight) & intended->height == desired->height)
return XtGeometryYes;
if (desired->width == mw->core.width &&
desired->height == mw->core.height)
return XtGeometryNo;
return XtGeometryAlmost;
#undef Set
}
/************************************************************************
*
* Destroy
* Free up the mpeg gadget allocated space. This includes
* the mpeg, and GC's.
*
************************************************************************/
static void
#ifdef _NO_PROTO
Destroy( w )
Widget w ;
#else
Destroy(
Widget w )
#endif /* _NO_PROTO */
{
XmpegWidget lw = (XmpegWidget) w;
/*
Garbage collect in here
*/
}
/************************************************************************
*
* CallMpegVidRsrc
* interface to mpegVidRsrc that sets globals too
*
************************************************************************/
static int
CallMpegVidRsrc(timestamp, theStream, inp,
disp, win, cmap,
ximage, gc)
TimeStamp timestamp;
VidStream *theStream;
FILE *inp;
Display *disp;
Window win;
Colormap *cmap;
XImage **ximage;
GC *gc;
{
int ret;
SetWindowVbls(disp, win, *cmap,
*ximage, *gc);
input = inp;
ret = mpegVidRsrc (0, theStream);
GetWindowVbls(cmap, ximage, gc);
return ret;
}
/***********************************************************************
*
* Rewind
*
**********************************************************************/
static void
Rewind (w)
Widget w;
{
XmpegWidget mw = (XmpegWidget) w;
mpegInitVidRsrc ();
rewind(input);
mw->mpeg.showCount = 0;
mw->mpeg.movieStatus = XmpegMOVIE_NOT_STARTED;
mw->mpeg.EOF_flag = EOF_flag = 0;
curBits = 0;
bitOffset = 0;
bufLength = 0;
bitBuffer = NULL;
totNumFrames = 0;
#ifdef ANALYSIS
init_stats();
#endif
mw->mpeg.theStream = NewVidStream (BUF_LENGTH);
ditherType = mw->mpeg.ditherType;
SetWindowVbls(XtDisplay(mw), XtWindow(mw), mw->mpeg.cmap,
mw->mpeg.ximage, mw->mpeg.gc);
mpegVidRsrc (0, mw->mpeg.theStream);
}
/***********************************************************************
*
* ShowPicture
*
**********************************************************************/
static void ShowPicture (client_data, id)
XtPointer client_data;
XtIntervalId *id;
{
Widget w = (Widget) client_data;
XmpegWidget mw = (XmpegWidget) client_data;
XmpegCallbackStruct cbs;
/* restore all the globals needed by these routines */
input = mw->mpeg.input;
EOF_flag = mw->mpeg.EOF_flag;
ditherType = mw->mpeg.ditherType;
if (mw->mpeg.showCount == 0)
{ /* never started, or just pausing */
if (mw->mpeg.movieStatus == XmpegMOVIE_RUNNING)
{ XmpegCallbackStruct cbs;
cbs.source = mw->mpeg.source;
cbs.reason = XmpegMOVIE_PAUSED;
mw->mpeg.movieStatus = XmpegMOVIE_PAUSED;
XtCallCallbackList (w,
mw->mpeg.movie_stopped_callback,
&cbs);
}
return;
}
/* still running */
if (CallMpegVidRsrc(0, mw->mpeg.theStream, mw->mpeg.input,
XtDisplay(mw), XtWindow(mw), &(mw->mpeg.cmap),
&(mw->mpeg.ximage), &(mw->mpeg.gc)))
{
mw->mpeg.timerID =
XtAppAddTimeOut (XtWidgetToApplicationContext (w), 0,
ShowPicture, client_data);
if (mw->mpeg.showCount > 0)
mw->mpeg.showCount--;
return;
}
/* end of picture - wrap? */
if (mw->mpeg.showCount == MPEG_PLAY_FOREVER)
{
Rewind (mw);
XtVaSetValues (w, XtNshowCount, (XtArgVal) MPEG_PLAY_FOREVER, NULL);
return;
}
/* no, stop */
mw->mpeg.movieStatus = XmpegMOVIE_FINISHED;
cbs.source = mw->mpeg.source;
cbs.reason = XmpegMOVIE_FINISHED;
XtCallCallbackList (w,
mw->mpeg.movie_stopped_callback,
&cbs);
}
/************************************************************************
*
* Redisplay
*
***********************************************************************/
static void
#ifdef _NO_PROTO
Redisplay( wid, event, region )
Widget wid ;
XEvent *event ;
Region region ;
#else
Redisplay(
Widget wid,
XEvent *event,
Region region )
#endif /* _NO_PROTO */
{
XmpegWidget mw = (XmpegWidget) wid ;
GC gc;
XmpegPart *lp;
Dimension availW, availH, needed_width, needed_height;
if (mw->mpeg.movieStatus != XmpegMOVIE_NOT_STARTED)
/* show current frame - wrong code for shmem, though */
XPutImage (XtDisplay (mw), XtWindow (mw),
mw->mpeg.gc, mw->mpeg.ximage,
0, 0, 0, 0,
(mw->mpeg.ximage)->width,
(mw->mpeg.ximage)->height);
else if (mw->mpeg.showCount)
{ /* start movie */
mw->mpeg.movieStatus = XmpegMOVIE_RUNNING;
mw->mpeg.timerID =
XtAppAddTimeOut (XtWidgetToApplicationContext (wid),
0, ShowPicture, wid);
}
}
/* MOTIF stuff from Primitive */
#ifdef MPEG_IS_MOTIF_WIDGET
/**********************************************************************
*
* Enter
*
*********************************************************************/
static void
#ifdef _NO_PROTO
Enter( wid, event, params, num_params )
Widget wid ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
#else
Enter(
Widget wid,
XEvent *event,
String *params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmpegWidget w = (XmpegWidget) wid ;
if (w->primitive.highlight_on_enter)
_XmPrimitiveEnter (wid, event, params, num_params);
}
/**********************************************************************
*
* Leave
*
*********************************************************************/
static void
#ifdef _NO_PROTO
Leave( wid, event, params, num_params )
Widget wid ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
#else
Leave(
Widget wid,
XEvent *event,
String *params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmpegWidget w = (XmpegWidget) wid ;
if (w->primitive.highlight_on_enter)
_XmPrimitiveLeave ((Widget) w, event, params, num_params);
}
#endif /* MOTIF Primitive stuff */
/************************************************************************
*
* SetValues
* This routine will take care of any changes that have been made
*
************************************************************************/
static Boolean
#ifdef _NO_PROTO
SetValues( cw, rw, nw, args, num_args )
Widget cw ;
Widget rw ;
Widget nw ;
ArgList args ;
Cardinal *num_args ;
#else
SetValues(
Widget cw,
Widget rw,
Widget nw,
ArgList args,
Cardinal *num_args )
#endif /* _NO_PROTO */
{
XmpegWidget current = (XmpegWidget) cw ;
XmpegWidget req = (XmpegWidget) rw ;
XmpegWidget new_w = (XmpegWidget) nw ;
XmpegPart *newmp, *curmp, *reqmp;
Boolean flag;
/* Get pointers to the mpeg parts */
newmp = &(new_w->mpeg);
curmp = &(current->mpeg);
reqmp = &(req->mpeg);
flag = False;
if (newmp->showCount != curmp->showCount)
{ switch (curmp->movieStatus)
{
case XmpegMOVIE_RUNNING:
case XmpegMOVIE_FINISHED:
/* nothing to do - either no frames to show,
or showing the next frame will catch new value */
break;
case XmpegMOVIE_PAUSED:
case XmpegMOVIE_NOT_STARTED:
newmp->movieStatus = XmpegMOVIE_RUNNING;
newmp->timerID =
XtAppAddTimeOut (XtWidgetToApplicationContext(nw),
0, ShowPicture, new_w);
break;
}
}
if (newmp->ditherType != curmp->ditherType)
/* don't allow change in dither type yet */
newmp->ditherType = curmp->ditherType;
if (newmp->source != curmp->source)
{ int i;
if ((input = fopen (newmp->source, "r")) == NULL)
{ XtWarning ("Cannot open new source");
input = curmp->input;
rewind (input);
}
else
{ fclose (newmp->input);
newmp->input = input;
}
/* stream is already destroyed if movie finished */
if (curmp->movieStatus != XmpegMOVIE_FINISHED)
DestroyVidStream (newmp->theStream);
newmp->movieStatus = XmpegMOVIE_NOT_STARTED;
newmp->EOF_flag = EOF_flag = 0;
curBits = 0;
bitOffset = 0;
bufLength = 0;
bitBuffer = NULL;
totNumFrames = 0;
ditherType = newmp->ditherType;
newmp->theStream = NewVidStream (BUF_LENGTH);
mpegInitVidRsrc ();
newmp->ximage = NULL;
CallMpegVidRsrc(0, newmp->theStream, newmp->input,
XtDisplay(nw), XtWindow(nw), &(newmp->cmap),
&(newmp->ximage), &(newmp->gc));
if (ditherType == Twox2_DITHER) i = 2;
else if (ditherType == HALFTONE_DITHER) i = 4;
else i = 1;
/* find and set widget size */
newmp->window_width = curVidStream -> h_size * i;
newmp->window_height = curVidStream -> v_size * i;
if (newmp->window_width != curmp->window_width ||
newmp->window_height != curmp->window_height)
{
nw->core.width = newmp->window_width;
nw->core.height = newmp->window_height;
}
}
return(flag);
}
/* MOTIF specific stuff */
#ifdef MPEG_IS_MOTIF_WIDGET
/************************************************************************
*
* Help
* This routine is called if the user made a help selection
* on the widget.
*
************************************************************************/
static void
#ifdef _NO_PROTO
Help( w, event, params, num_params )
Widget w ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
#else
Help(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmpegWidget lw = (XmpegWidget) w;
Widget parent = XtParent(lw);
_XmPrimitiveHelp( (Widget) w, event, params, num_params);
}
/************************************************************************
*
* XmCreateMpegWidget
* Externally accessable function for creating a mpeg gadget.
*
************************************************************************/
Widget
#ifdef _NO_PROTO
XmCreateMpeg( parent, name, arglist, argCount )
Widget parent ;
char *name ;
Arg *arglist ;
Cardinal argCount ;
#else
XmCreateMpeg(
Widget parent,
char *name,
Arg *arglist,
Cardinal argCount )
#endif /* _NO_PROTO */
{
return (XtCreateWidget(name,xmpegWidgetClass,parent,arglist,argCount));
}
#endif /* MPEG_IS_MOTIF_WIDGET */
/************************************************************************
*
* XmpegPlayMovie
* Start the movie going
*
************************************************************************/
void
XmpegPlayMovie (w, count)
Widget w;
int count;
{
XmpegWidget mw = (XmpegWidget) w;
mw->mpeg.showCount = count;
if (count != 0)
{
mw->mpeg.movieStatus = XmpegMOVIE_RUNNING;
mw->mpeg.timerID =
XtAppAddTimeOut (XtWidgetToApplicationContext (w), 0,
ShowPicture, w);
}
}
/************************************************************************
*
* XmpegRewindMovie
* Reset to the beginning
*
************************************************************************/
void
XmpegRewindMovie (w)
Widget w;
{
Rewind (w);
}
/************************************************************************
*
* XmpegStopMovie
* Pause the movie
*
************************************************************************/
void
XmpegStopMovie (w)
Widget w;
{
XmpegWidget mw = (XmpegWidget) w;
XtVaSetValues (w, XtNshowCount, (XtArgVal) 0, NULL);
}
/************************************************************************
*
* XmpegMovieStatus
* where is the movie?
*
************************************************************************/
int
XmpegMovieStatus (w)
Widget w;
{
XmpegWidget mw = (XmpegWidget) w;
return (mw->mpeg.movieStatus);
}