TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ofx/OfxhInteract.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License :
00003  *
00004  * Copyright (c) 2007-2009, The Open Effects Association Ltd. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  * Redistributions of source code must retain the above copyright notice,
00010  *    this list of conditions and the following disclaimer.
00011  * Redistributions in binary form must reproduce the above copyright notice,
00012  *    this list of conditions and the following disclaimer in the documentation
00013  *    and/or other materials provided with the distribution.
00014  * Neither the name The Open Effects Association Ltd, nor the names of its
00015  *    contributors may be used to endorse or promote products derived from this
00016  *    software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00021  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
00022  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00024  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00025  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 // ofx host
00031 #include "OfxhBinary.hpp"
00032 #include "OfxhMemory.hpp"
00033 #include "OfxhImageEffectNode.hpp"
00034 #include "OfxhInteract.hpp"
00035 #include "property/OfxhSet.hpp"
00036 #include "attribute/OfxhClip.hpp"
00037 #include "attribute/OfxhParam.hpp"
00038 
00039 // ofx
00040 #include <ofxKeySyms.h>
00041 #include <ofxCore.h>
00042 #include <ofxImageEffect.h>
00043 
00044 #include <tuttle/host/exceptions.hpp>
00045 
00046 namespace tuttle {
00047 namespace host {
00048 namespace ofx {
00049 namespace interact {
00050 
00051 
00052 OfxhInteractBase::~OfxhInteractBase()
00053 {}
00054 
00055 //
00056 // descriptor
00057 //
00058 static property::OfxhPropSpec interactDescriptorStuffs[] = {
00059         { kOfxInteractPropHasAlpha, property::ePropTypeInt, 1, true, "0" },
00060         { kOfxInteractPropBitDepth, property::ePropTypeInt, 1, true, "0" },
00061         { 0 },
00062 };
00063 
00064 OfxhInteractDescriptor::OfxhInteractDescriptor()
00065         : _properties( interactDescriptorStuffs )
00066         , _state( eUninitialised )
00067         , _entryPoint( NULL )
00068 {}
00069 
00070 OfxhInteractDescriptor::~OfxhInteractDescriptor()
00071 {}
00072 
00073 /// call describe on this descriptor
00074 bool OfxhInteractDescriptor::describe( int bitDepthPerComponent, bool hasAlpha )
00075 {
00076         if( _state == eUninitialised )
00077         {
00078                 _properties.setIntProperty( kOfxInteractPropBitDepth, bitDepthPerComponent );
00079                 _properties.setIntProperty( kOfxInteractPropHasAlpha, (int)( hasAlpha ) );
00080 
00081                 OfxStatus stat = callEntry( kOfxActionDescribe, getHandle(), NULL, NULL );
00082                 if( stat == kOfxStatOK || stat == kOfxStatReplyDefault )
00083                 {
00084                         _state = eDescribed;
00085                 }
00086                 else
00087                 {
00088                         _state = eFailed;
00089                 }
00090         }
00091         return _state == eDescribed;
00092 }
00093 
00094 // call the interactive entry point
00095 OfxStatus OfxhInteractDescriptor::callEntry( const char*          action,
00096                                              void*                handle,
00097                                              OfxPropertySetHandle inArgs,
00098                                              OfxPropertySetHandle outArgs ) const
00099 {
00100         if( ! _entryPoint )
00101         {
00102                 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue )
00103                         << exception::dev() + "Plugin entry point is not initialized." );
00104         }
00105         if( _state == eFailed )
00106         {
00107                 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue )
00108                         << exception::dev() + "Previous call to plugin lead to a failure state." );
00109         }
00110         return _entryPoint( action, handle, inArgs, outArgs );
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////////////////
00114 static property::OfxhPropSpec interactInstanceStuffs[] = {
00115         { kOfxPropEffectInstance, property::ePropTypePointer, 1, true, NULL },
00116         { kOfxPropInstanceData, property::ePropTypePointer, 1, false, NULL },
00117         { kOfxInteractPropPixelScale, property::ePropTypeDouble, 2, true, "1.0" },
00118         { kOfxInteractPropBackgroundColour, property::ePropTypeDouble, 3, true, "0.0" },
00119         { kOfxInteractPropViewportSize, property::ePropTypeInt, 2, true, "0" },
00120         { kOfxInteractPropSlaveToParam, property::ePropTypeString, 0, false, "" },
00121         { 0 },
00122 };
00123 
00124 static property::OfxhPropSpec interactArgsStuffs[] = {
00125         { kOfxPropEffectInstance, property::ePropTypePointer, 1, false, NULL },
00126         { kOfxPropInstanceData, property::ePropTypePointer, 1, false, NULL },
00127         { kOfxPropTime, property::ePropTypeDouble, 1, false, "0.0" },
00128         { kOfxImageEffectPropRenderScale, property::ePropTypeDouble, 2, false, "0.0" },
00129         { kOfxInteractPropBackgroundColour, property::ePropTypeDouble, 3, false, "0.0" },
00130         { kOfxInteractPropViewportSize, property::ePropTypeInt, 2, false, "0" },
00131         { kOfxInteractPropPixelScale, property::ePropTypeDouble, 2, false, "1.0" },
00132         { kOfxInteractPropPenPosition, property::ePropTypeDouble, 2, false, "0.0" },
00133         #ifdef kOfxInteractPropPenViewportPosition
00134         { kOfxInteractPropPenViewportPosition, property::ePropTypeInt, 2, false, "0" },
00135         #endif
00136         { kOfxInteractPropPenPressure, property::ePropTypeDouble, 1, false, "0.0" },
00137         { kOfxPropKeyString, property::ePropTypeString, 1, false, "" },
00138         { kOfxPropKeySym, property::ePropTypeInt, 1, false, "0" },
00139         { 0 },
00140 };
00141 
00142 // instance
00143 
00144 OfxhInteract::OfxhInteract( const OfxhInteractDescriptor& desc, void* effectInstance )
00145         : _descriptor( desc )
00146         , _properties( interactInstanceStuffs )
00147         , _state( desc.getState() )
00148         , _effectInstance( effectInstance )
00149         , _argProperties( interactArgsStuffs )
00150 {
00151         _properties.setPointerProperty( kOfxPropEffectInstance, effectInstance );
00152         _properties.setChainedSet( &desc.getProperties() ); /// chain it into the descriptor props
00153 }
00154 
00155 OfxhInteract::~OfxhInteract()
00156 {
00157         /// call it directly incase CI failed and we should always tidy up after create instance
00158         OfxStatus status = callEntry( kOfxActionDestroyInstance,  NULL );
00159         if( status != kOfxStatOK &&
00160                 status != kOfxStatReplyDefault )
00161         {
00162                 TUTTLE_LOG_TRACE( "OFXh: Failed to destroy the effect instance. Status is " << mapStatusToString(status) << "." );
00163         }
00164 }
00165 
00166 /// call the entry point in the descriptor with action and the given args
00167 OfxStatus OfxhInteract::callEntry( const char* action, property::OfxhSet* inArgs )
00168 {
00169         if( _state == eFailed )
00170                 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue ) );
00171         
00172         OfxPropertySetHandle inHandle = inArgs ? inArgs->getHandle() : NULL;
00173         return _descriptor.callEntry( action, getHandle(), inHandle, NULL );
00174 }
00175 
00176 // do nothing function
00177 void OfxhInteract::reset( const std::string& name ) OFX_EXCEPTION_SPEC
00178 {
00179         // no-op
00180 }
00181 
00182 void OfxhInteract::getSlaveToParam( std::vector<std::string>& params ) const
00183 {
00184         int nSlaveParams = _properties.getDimension( kOfxInteractPropSlaveToParam );
00185 
00186         for( int i = 0; i < nSlaveParams; i++ )
00187         {
00188                 std::string param = _properties.getStringProperty( kOfxInteractPropSlaveToParam, i );
00189                 params.push_back( param );
00190         }
00191 }
00192 
00193 /// initialise the argument properties
00194 void OfxhInteract::initArgProp( OfxTime          time,
00195                                 const OfxPointD& renderScale )
00196 {
00197         _argProperties.setPointerProperty( kOfxPropEffectInstance, _effectInstance );
00198         _argProperties.setPointerProperty( kOfxPropInstanceData, _properties.getPointerProperty( kOfxPropInstanceData ) );
00199         _argProperties.setDoubleProperty( kOfxPropTime, time );
00200         
00201         double pixelScale[2] = {1., 1.};
00202         getPixelScale( pixelScale[0], pixelScale[1] );
00203         _argProperties.setDoublePropertyN( kOfxInteractPropPixelScale, pixelScale, 2 ); // the scale factor to convert cannonical pixels to screen pixels
00204         _argProperties.setDoublePropertyN( kOfxImageEffectPropRenderScale, &renderScale.x, 2 );
00205         
00206         int viewportSize[2] = {0, 0};
00207         getViewportSize( viewportSize[0], viewportSize[1] );
00208         _argProperties.setIntPropertyN( kOfxInteractPropViewportSize, viewportSize, 2 ); // the openGL viewport size for the instance
00209         
00210         double backgroundColor[3] = {0, 0, 0};
00211         getBackgroundColour( backgroundColor[0], backgroundColor[1], backgroundColor[2] );
00212         _argProperties.setDoublePropertyN( kOfxInteractPropBackgroundColour, backgroundColor, 3 ); // the background colour of the application behind the current view
00213 }
00214 
00215 void OfxhInteract::setPenArgProps( const OfxPointD& penPos,
00216                                    const OfxPointI& penPosViewport,
00217                                    double           pressure )
00218 {
00219         _argProperties.setDoublePropertyN( kOfxInteractPropPenPosition, &penPos.x, 2 );
00220         #ifdef kOfxInteractPropPenViewportPosition
00221         _argProperties.setIntPropertyN( kOfxInteractPropPenViewportPosition, &penPosViewport.x, 2 );
00222         #endif
00223         _argProperties.setDoubleProperty( kOfxInteractPropPenPressure, pressure );
00224 }
00225 
00226 void OfxhInteract::setKeyArgProps( int   key,
00227                                    char* keyString )
00228 {
00229         _argProperties.setIntProperty( kOfxPropKeySym, key );
00230         _argProperties.setStringProperty( kOfxPropKeyString, keyString );
00231 }
00232 
00233 void OfxhInteract::createInstanceAction() OFX_EXCEPTION_SPEC
00234 {
00235         OfxStatus status = callEntry( kOfxActionCreateInstance, NULL );
00236 
00237         if( status == kOfxStatOK || status == kOfxStatReplyDefault )
00238         {
00239                 _state = eCreated;
00240         }
00241         else
00242         {
00243                 _state = eFailed;
00244                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00245         }
00246 }
00247 
00248 void OfxhInteract::drawAction( OfxTime          time,
00249                                const OfxPointD& renderScale ) OFX_EXCEPTION_SPEC
00250 {
00251         initArgProp( time, renderScale );
00252         OfxStatus status = callEntry( kOfxInteractActionDraw, &_argProperties );
00253         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00254                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00255 }
00256 
00257 void OfxhInteract::penMotionAction( OfxTime          time,
00258                                     const OfxPointD& renderScale,
00259                                     const OfxPointD& penPos,
00260                                     const OfxPointI& penPosViewport,
00261                                     double           pressure ) OFX_EXCEPTION_SPEC
00262 {
00263         initArgProp( time, renderScale );
00264         setPenArgProps( penPos, penPosViewport, pressure );
00265         OfxStatus status = callEntry( kOfxInteractActionPenMotion, &_argProperties );
00266         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00267                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00268 }
00269 
00270 void OfxhInteract::penUpAction( OfxTime          time,
00271                                 const OfxPointD& renderScale,
00272                                 const OfxPointD& penPos,
00273                                 const OfxPointI& penPosViewport,
00274                                 double           pressure ) OFX_EXCEPTION_SPEC
00275 {
00276         initArgProp( time, renderScale );
00277         setPenArgProps( penPos, penPosViewport, pressure );
00278         OfxStatus status = callEntry( kOfxInteractActionPenUp, &_argProperties );
00279         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00280                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00281 }
00282 
00283 void OfxhInteract::penDownAction( OfxTime          time,
00284                                   const OfxPointD& renderScale,
00285                                   const OfxPointD& penPos,
00286                                   const OfxPointI& penPosViewport,
00287                                   double           pressure ) OFX_EXCEPTION_SPEC
00288 {
00289         initArgProp( time, renderScale );
00290         setPenArgProps( penPos, penPosViewport, pressure );
00291         OfxStatus status = callEntry( kOfxInteractActionPenDown, &_argProperties );
00292         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00293                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00294 }
00295 
00296 void OfxhInteract::keyDownAction( OfxTime          time,
00297                                   const OfxPointD& renderScale,
00298                                   int              key,
00299                                   char*            keyString ) OFX_EXCEPTION_SPEC
00300 {
00301         initArgProp( time, renderScale );
00302         setKeyArgProps( key, keyString );
00303         OfxStatus status = callEntry( kOfxInteractActionKeyDown, &_argProperties );
00304         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00305                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00306 }
00307 
00308 void OfxhInteract::keyUpAction( OfxTime          time,
00309                                 const OfxPointD& renderScale,
00310                                 int              key,
00311                                 char*            keyString ) OFX_EXCEPTION_SPEC
00312 {
00313         initArgProp( time, renderScale );
00314         setKeyArgProps( key, keyString );
00315         OfxStatus status = callEntry( kOfxInteractActionKeyUp, &_argProperties );
00316         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00317                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00318 }
00319 
00320 void OfxhInteract::keyRepeatAction( OfxTime          time,
00321                                     const OfxPointD& renderScale,
00322                                     int              key,
00323                                     char*            keyString ) OFX_EXCEPTION_SPEC
00324 {
00325         initArgProp( time, renderScale );
00326         setKeyArgProps( key, keyString );
00327         OfxStatus status = callEntry( kOfxInteractActionKeyRepeat, &_argProperties );
00328         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00329                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00330 }
00331 
00332 void OfxhInteract::gainFocusAction( OfxTime          time,
00333                                     const OfxPointD& renderScale ) OFX_EXCEPTION_SPEC
00334 {
00335         initArgProp( time, renderScale );
00336         OfxStatus status = callEntry( kOfxInteractActionGainFocus, &_argProperties );
00337         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00338                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00339 }
00340 
00341 void OfxhInteract::loseFocusAction( OfxTime          time,
00342                                     const OfxPointD& renderScale ) OFX_EXCEPTION_SPEC
00343 {
00344         initArgProp( time, renderScale );
00345         OfxStatus status = callEntry( kOfxInteractActionLoseFocus, &_argProperties );
00346         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00347                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00348 }
00349 
00350 }
00351 }
00352 }
00353 }