Exemplo n.º 1
0
/* void notify(in nsITimer timer); */
NS_IMETHODIMP imgContainer::Notify(nsITimer *timer)
{
  // Note that as long as the image is animated, it will not be discarded, 
  // so this should never happen...
  nsresult rv = RestoreDiscardedData();
  NS_ENSURE_SUCCESS(rv, rv);

  // This should never happen since the timer is only set up in StartAnimation()
  // after mAnim is checked to exist.
  NS_ENSURE_TRUE(mAnim, NS_ERROR_UNEXPECTED);
  NS_ASSERTION(mAnim->timer == timer,
               "imgContainer::Notify() called with incorrect timer");

  if (!mAnim->animating || !mAnim->timer)
    return NS_OK;

  nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
  if (!observer) {
    // the imgRequest that owns us is dead, we should die now too.
    StopAnimation();
    return NS_OK;
  }

  if (mNumFrames == 0)
    return NS_OK;
  
  gfxIImageFrame *nextFrame = nsnull;
  PRInt32 previousFrameIndex = mAnim->currentAnimationFrameIndex;
  PRInt32 nextFrameIndex = mAnim->currentAnimationFrameIndex + 1;
  PRInt32 timeout = 0;

  // If we're done decoding the next frame, go ahead and display it now and
  // reinit the timer with the next frame's delay time.
  // currentDecodingFrameIndex is not set until the second frame has
  // finished decoding (see EndFrameDecode)
  if (mAnim->doneDecoding || 
      (nextFrameIndex < mAnim->currentDecodingFrameIndex)) {
    if (mNumFrames == nextFrameIndex) {
      // End of Animation

      // If animation mode is "loop once", it's time to stop animating
      if (mAnimationMode == kLoopOnceAnimMode || mLoopCount == 0) {
        StopAnimation();
        return NS_OK;
      } else {
        // We may have used compositingFrame to build a frame, and then copied
        // it back into mFrames[..].  If so, delete composite to save memory
        if (mAnim->compositingFrame && mAnim->lastCompositedFrameIndex == -1)
          mAnim->compositingFrame = nsnull;
      }

      nextFrameIndex = 0;
      if (mLoopCount > 0)
        mLoopCount--;
    }

    if (!(nextFrame = mFrames[nextFrameIndex])) {
      // something wrong with the next frame, skip it
      mAnim->currentAnimationFrameIndex = nextFrameIndex;
      mAnim->timer->SetDelay(100);
      return NS_OK;
    }
    nextFrame->GetTimeout(&timeout);

  } else if (nextFrameIndex == mAnim->currentDecodingFrameIndex) {
    // Uh oh, the frame we want to show is currently being decoded (partial)
    // Wait a bit and try again
    mAnim->timer->SetDelay(100);
    return NS_OK;
  } else { //  (nextFrameIndex > currentDecodingFrameIndex)
    // We shouldn't get here. However, if we are requesting a frame
    // that hasn't been decoded yet, go back to the last frame decoded
    NS_WARNING("imgContainer::Notify()  Frame is passed decoded frame");
    nextFrameIndex = mAnim->currentDecodingFrameIndex;
    if (!(nextFrame = mFrames[nextFrameIndex])) {
      // something wrong with the next frame, skip it
      mAnim->currentAnimationFrameIndex = nextFrameIndex;
      mAnim->timer->SetDelay(100);
      return NS_OK;
    }
    nextFrame->GetTimeout(&timeout);
  }

  if (timeout > 0)
    mAnim->timer->SetDelay(timeout);
  else
    StopAnimation();

  nsIntRect dirtyRect;
  gfxIImageFrame *frameToUse = nsnull;

  if (nextFrameIndex == 0) {
    frameToUse = nextFrame;
    dirtyRect = mAnim->firstFrameRefreshArea;
  } else {
    gfxIImageFrame *prevFrame = mFrames[previousFrameIndex];
    if (!prevFrame)
      return NS_OK;

    // Change frame and announce it
    if (NS_FAILED(DoComposite(&frameToUse, &dirtyRect, prevFrame,
                              nextFrame, nextFrameIndex))) {
      // something went wrong, move on to next
      NS_WARNING("imgContainer::Notify(): Composing Frame Failed\n");
      mAnim->currentAnimationFrameIndex = nextFrameIndex;
      return NS_OK;
    }
  }
  // Set currentAnimationFrameIndex at the last possible moment
  mAnim->currentAnimationFrameIndex = nextFrameIndex;
  // Refreshes the screen
  observer->FrameChanged(this, frameToUse, &dirtyRect);
  
  return NS_OK;
}
Exemplo n.º 2
0
EFFECTEXEC(frame,tags,PPTBase,EffectBase)
{
    ULONG sig, rc, *args;
    BOOL quit = FALSE, reallyrexx = FALSE;
    FRAME *newframe = NULL, *with = NULL;
    struct gFixRectMessage gfr = {0};
    ULONG fc, wc;
    struct Values *av;

    D(bug(MYNAME": Exec()\n"));

    /*
     *  Defaults
     */
    v.ratio = 128;
    v.method = Direct;
    v.bounds.Top = v.bounds.Left = ~0;
    v.bounds.Width = 200; v.bounds.Height = 100;
    v.tile = FALSE;

    if( av = GetOptions(MYNAME) ) {
        v = *av;
    }

    /*
     *  Copy to local variables
     */

    BGUIBase        = PPTBase->lb_BGUI;
    IntuitionBase   = (struct IntuitionBase *)PPTBase->lb_Intuition;
    DOSBase         = PPTBase->lb_DOS;
    SysBase         = PPTBase->lb_Sys;

    /*
     *  Parse AREXX message, which has to exist.
     *  BUG: If necessary, should wait for D&D from the main window.
     *  BUG: Should make sanity checks!
     */

    args = (ULONG *) TagData( PPTX_RexxArgs, tags );

    if( args ) {

        /* WITH */
        if( args[0] ) {
            with = FindFrame( (ID) PEEKL(args[0]) );
            if(!with) {
                SetErrorMsg(frame,"Unknown frame ID for WITH parameter");
                return NULL;
            }
        }

        /* TOP */
        if( args[1] ) {
            gfr.y = (WORD) PEEKL(args[1]);
            reallyrexx = TRUE;
        }

        /* LEFT */
        if( args[2] ) {
            gfr.x = (WORD) PEEKL(args[2]);
            reallyrexx = TRUE;
        }

        /* METHOD */
        if( args[3] ) {
            int i;

            for( i = 0; method_labels[i]; i++ ) {
                if(stricmp( method_labels[i], (char *)args[3] ) == 0 ) {
                    v.method = i;
                    reallyrexx = TRUE;
                    break;
                }
            }
        }

        /* RATIO */
        if( v.method == Mix ) {
            if( args[4] ) {
                v.ratio = PEEKL( args[4] );
            } else {
                SetErrorCode(frame,PERR_INVALIDARGS);
            }
        }

        /* TILE */
        if( args[5] ) {
            v.tile = TRUE;
        } else {
            v.tile = FALSE;
        }

    } else {
        SetErrorMsg(frame,"Image compositing can be used with Drag&Drop (or REXX) only");
        return NULL;
    }

    /*
     *  Make some sanity checks
     */

    if( frame->pix->width < with->pix->width ||
        frame->pix->height < with->pix->height ) {
            SetErrorMsg(frame,"You cannot composite a larger picture on a smaller one!");
            return NULL;
        }

    fc = frame->pix->colorspace;
    wc = with->pix->colorspace;

    if( ! (wc == fc || (fc == CS_ARGB && wc == CS_RGB) || (fc == CS_RGB && wc == CS_ARGB ))) {
        SetErrorMsg(frame, "Only images of the same color space can be composited");
        return NULL;
    }

    gfr.dim.Left   = 0;
    gfr.dim.Top    = 0;
    gfr.dim.Height = with->pix->height;
    gfr.dim.Width  = with->pix->width;

    /*
     *  Open window and start parsing
     */

    if( reallyrexx == FALSE ) {
        if( GimmeWindow(frame, with, PPTBase) ) {
            ULONG sigmask, gimask = 0L;

            GetAttr( WINDOW_SigMask, Win, &sigmask );

            StartInput(frame, GINP_FIXED_RECT, (struct PPTMessage *) &gfr);

            gimask = (1 << PPTBase->mport->mp_SigBit);

            while( !quit ) {
                sig = Wait( sigmask|gimask|SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_F );

                if( sig & SIGBREAKF_CTRL_C ) {
                    D(bug("BREAK!\n"));
                    SetErrorCode( frame, PERR_BREAK );
                    quit = TRUE;
                    break;
                }

                if( sig & SIGBREAKF_CTRL_F ) {
                    WindowToFront(win);
                    ActivateWindow(win);
                }

                if( sig & gimask ) {
                    struct gFixRectMessage *pmsg;

                    if(pmsg = (struct gFixRectMessage *)GetMsg( PPTBase->mport )) {
                        if( pmsg->msg.code == PPTMSG_FIXED_RECT ) {
                            D(bug("User picked a point @ (%d,%d)\n",pmsg->x, pmsg->y));
                            gfr.x = pmsg->x; gfr.y = pmsg->y;
                            // SetGadgetAttrs( ( struct Gadget *)OKButton, win, NULL, GA_Disabled, FALSE );
                        }
                        ReplyMsg( (struct Message *)pmsg );
                    }
                }

                if( sig & sigmask ) {
                    while( (rc = HandleEvent( Win )) != WMHI_NOMORE ) {
                        ULONG t;

                        switch(rc) {
                            case GID_OK:
                                GetAttr( CYC_Active, Method, (ULONG *)&v.method );
                                GetAttr( SLIDER_Level, Ratio, &v.ratio );

                                /*
                                 *  Save the window attributes for later retrieval.
                                 */

                                GetAttr( WINDOW_Bounds, Win, (ULONG *) &v.bounds );
                                GetAttr( GA_Selected, Tile, &t );

                                StopInput( frame );
                                v.tile = (BOOL) t;

                                WindowClose(Win);
                                newframe = DoComposite( frame, with, &gfr, v.method,
                                                        (WORD) v.ratio, v.tile, PPTBase );
                                quit = TRUE;
                                break;

                            case GID_CANCEL:
                                quit = TRUE;
                                StopInput( frame );
                                break;
                        }
                    }
                }
            }
        }
    } else {
        /* gfr is already set up */
        newframe = DoComposite( frame, with, &gfr,
                                v.method, (WORD) v.ratio, v.tile,
                                PPTBase );
    }

    if(Win) DisposeObject(Win);

    if( newframe ) {
        PutOptions( MYNAME, &v, sizeof(struct Values) );
    }

    D(bug("Returning %08X...\n",newframe));
    return newframe;
}