Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

/*
 * Copyright 1995, Brown University, Providence, RI
 *
 * Permission to use and modify this software and its documentation for
 * any purpose other than its incorporation into a commercial product is
 * hereby granted without fee.  Permission to copy and distribute this
 * software and its documentation only for non-commercial use is also
 * granted without fee, provided, however, that the above copyright notice
 * appear in all copies, that both that copyright notice and this permission
 * notice appear in supporting documentation, that the name of Brown
 * University not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission,
 * and that the person doing the distribution notify Brown University of
 * such distributions outside of his or her organization. Brown University
 * makes no representations about the suitability of this software for
 * any purpose.  It is provided "as is" without express or implied warranty.
 * Brown University requests notification of any modifications to this
 * software or its documentation.
 *
 * Send the following redistribution information:
 *
 *      Name:
 *      Organization:
 *      Address (postal and/or electronic):
 *
 * To:
 *      Software Librarian
 *      Computer Science Department, Box 1910
 *      Brown University
 *      Providence, RI 02912
 *
 *              or
 *
 *      brusd@cs.brown.edu
 *
 * We will acknowledge all electronic notifications.
 */


#include <stdio.h>
#include <iostream.h>
#include "ANIMdisplay.H"

// Constructor for first movie in a series
//
//
ANIMdisplay::ANIMdisplay(ANIMbase *movie, char* displayName,
                         Boolean loopMovie,
                         int allocateFrame, int starty)
        : _movie(movie),
          originalMovie(TRUE),
          frameAllocated(FALSE),
          loop(loopMovie),
          movieEnded(FALSE),
          _displayName(strdup(displayName))
{

//for first instance
           xinfo.hints.x=0;
           xinfo.hints.y=starty;
           xinfo.cmap=0;
           xinfo.gc=0;
           xinfo.depth=24;
           xinfo.ditherType=FULL_COLOR_DITHER;
           xinfo.display=NULL;
           xinfo.visual=NULL;
           xinfo.ExistingWindow=0;
       
         xinfo.hints.width=movie->Width;
         xinfo.hints.height=movie->Height;
         largy=-1;
 
         init(allocateFrame);

         XWindowAttributes winattr;
         Display *display=xinfo.display;

         displayWidth=DisplayWidth(display,XDefaultScreen(display));
         XGetWindowAttributes(display, xinfo.window, &winattr);

         _movie->InitDither(winattr.visual->red_mask,
                             winattr.visual->green_mask,
                             winattr.visual->blue_mask);
}

// Constructor for first movie in a series
//
//
ANIMdisplay::ANIMdisplay(ANIMbase *movie, ANIMdisplay *lastMovie,
                         Boolean loopMovie,
                         int allocateFrame)
   : largy(lastMovie->largy),
     frameAllocated(FALSE),
     displayWidth(lastMovie->displayWidth),
     _displayName(lastMovie->_displayName),
     _movie(movie),
     originalMovie(TRUE),
     loop(loopMovie),
     movieEnded(FALSE)
{
//for n>1 instance
         /* get next X coordinates */
         xinfo.hints.x= lastMovie->xinfo.hints.x+10+ lastMovie->_movie->Width;
         /* Update the largest vertical size of a movie */
         /* If we are off the right side of the screen, cont at left */
         xinfo.hints.y=lastMovie->xinfo.hints.y;
         if (xinfo.hints.x > displayWidth - 80) {
                  xinfo.hints.y+=largy+30;
                  largy=0;
                  xinfo.hints.x=0;
         }
         xinfo.ExistingWindow=0;
         xinfo.display=lastMovie->xinfo.display;
         xinfo.visual=lastMovie->xinfo.visual;
         xinfo.cmap=lastMovie->xinfo.cmap;
         xinfo.gc=lastMovie->xinfo.gc;
         xinfo.ditherType=lastMovie->xinfo.ditherType;
         xinfo.display=lastMovie->xinfo.display;
         xinfo.depth=lastMovie->xinfo.depth;
         xinfo.ditherType=lastMovie->xinfo.ditherType;

         init(allocateFrame);
}

// Destructor
//
//
ANIMdisplay::~ANIMdisplay()
{
        if (frameAllocated) {
           free(xinfo.ximage->data);
           xinfo.ximage->data=NULL;
        }
        if (xinfo.ximage!=NULL) XDestroyImage(xinfo.ximage);
        // Add code re: xinfo.display - reference count
}

// Constructor helper code, also called when we switch movies
//
//
void
ANIMdisplay::init(Boolean allocateFrame)
{
         const char *inputName=_movie->getName();

         if (_movie->Height>largy) {
                 largy=_movie->Height;
         }
         xinfo.hints.width=_movie->Width;
         xinfo.hints.height=_movie->Height;

         xinfo.ximage=NULL;
         xinfo.owncmFlag=FALSE;

         if (inputName==NULL) {
            // Should be....  different
            xinfo.name="Display!";
         } else if ((xinfo.name=strrchr(inputName,'/'))==NULL) {
            xinfo.name=(char *) inputName;
         } else xinfo.name++;

         if (originalMovie) InitColorDisplay((char *) _displayName,&xinfo);
         else {
            XSetStandardProperties (xinfo.display, xinfo.window, xinfo.name,
                                    xinfo.name, None, NULL, 0,
                                    &xinfo.hints);
         }
         init_image(allocateFrame);
}

void
ANIMdisplay::init_image(Boolean allocateFrame) {
        Display *display=xinfo.display;
        Visual *fc_visual;
        int depth, w,h;
        char *where,dummy;

        //XImage has to be on word boundary?
        w = _movie->Width + (_movie->Width % 16);
        h = _movie->Height + (_movie->Height % 16);
        if (w+h==0) {
           xinfo.ximage=NULL;
           return;
        }
        frameAllocated=allocateFrame;

        fc_visual = FindFullColorVisual(display, &depth);
        if (allocateFrame) where=(char *) malloc(w*h*4);
        else where=&dummy;
        xinfo.ximage=XCreateImage(display,fc_visual,depth,ZPixmap,
            0,where,w, h,32,0);
       
#ifdef LITTLE_ENDIAN_ARCHITECTURE
        xinfo.ximage->byte_order = LSBFirst;
        xinfo.ximage->bitmap_bit_order = LSBFirst;
#else
        xinfo.ximage->byte_order = MSBFirst;
        xinfo.ximage->bitmap_bit_order = MSBFirst;
#endif
}

void
ANIMdisplay::newMovie(const char *const newMovieName)
{
        if (xinfo.ximage!=NULL) XDestroyImage(xinfo.ximage);

        if (newMovieName!=NULL) {
           _movie->newMovie(newMovieName);
           _movie->open();
        }

        originalMovie=FALSE;
        init(frameAllocated);

        XResizeWindow(xinfo.display,xinfo.window,
                      _movie->Width,
                      _movie->Height);
        XFlush(xinfo.display);

        movieEnded=FALSE;
}

void
ANIMdisplay::display(char *frame) {
        char *paramFrame, *tmpFrame;
        Boolean moreFrames, newFrame;

        // if frame is:
        //      !NULL - display frame already in xinfo
        //       NULL - get frame and then display it
        if (frame==NULL) {
           if (xinfo.ximage!=NULL) paramFrame=xinfo.ximage->data;
           else paramFrame=NULL;
           moreFrames=_movie->GetFrame(&paramFrame,&newFrame);
           if (newFrame) {
              // if there is no ximage so far, we are starting "anew"
              if (xinfo.ximage==NULL) {
                 frameAllocated=TRUE;  // Don't allocate a frame
                 newMovie(NULL);
              }
              tmpFrame=xinfo.ximage->data;
              xinfo.ximage->data=paramFrame;
           }
        } else newFrame=TRUE;

        if (newFrame) {
           Display *display=xinfo.display;
           if (frame!=NULL) xinfo.ximage->data=frame;
           XPutImage(display, xinfo.window, xinfo.gc, xinfo.ximage,
                  0,0,0,0,
                  (unsigned int) xinfo.ximage->width,
                  (unsigned int) xinfo.ximage->height);
        }

        if (frame==NULL) {
           // Don't copy NULL over new frame if unneeded
           if (newFrame) xinfo.ximage->data=tmpFrame;

           if (!moreFrames ) {
              if (loop) _movie->rewind();
              else movieEnded=TRUE;
           }
        }
}

Boolean ANIMdisplay::movieDone()
{
        return movieEnded;
}