TuttleOFX  1
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         callEntry( kOfxActionDestroyInstance,  NULL );
00159 }
00160 
00161 /// call the entry point in the descriptor with action and the given args
00162 OfxStatus OfxhInteract::callEntry( const char* action, property::OfxhSet* inArgs )
00163 {
00164         if( _state == eFailed )
00165                 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue ) );
00166         
00167         OfxPropertySetHandle inHandle = inArgs ? inArgs->getHandle() : NULL ;
00168         return _descriptor.callEntry( action, getHandle(), inHandle, NULL );
00169 }
00170 
00171 // do nothing function
00172 void OfxhInteract::reset( const std::string& name ) OFX_EXCEPTION_SPEC
00173 {
00174         // no-op
00175 }
00176 
00177 void OfxhInteract::getSlaveToParam( std::vector<std::string>& params ) const
00178 {
00179         int nSlaveParams = _properties.getDimension( kOfxInteractPropSlaveToParam );
00180 
00181         for( int i = 0; i < nSlaveParams; i++ )
00182         {
00183                 std::string param = _properties.getStringProperty( kOfxInteractPropSlaveToParam, i );
00184                 params.push_back( param );
00185         }
00186 }
00187 
00188 /// initialise the argument properties
00189 void OfxhInteract::initArgProp( OfxTime          time,
00190                                 const OfxPointD& renderScale )
00191 {
00192         _argProperties.setPointerProperty( kOfxPropEffectInstance, _effectInstance );
00193         _argProperties.setPointerProperty( kOfxPropInstanceData, _properties.getPointerProperty( kOfxPropInstanceData ) );
00194         _argProperties.setDoubleProperty( kOfxPropTime, time );
00195         
00196         double pixelScale[2] = {1., 1.};
00197         getPixelScale( pixelScale[0], pixelScale[1] );
00198         _argProperties.setDoublePropertyN( kOfxInteractPropPixelScale, pixelScale, 2 ); // the scale factor to convert cannonical pixels to screen pixels
00199         _argProperties.setDoublePropertyN( kOfxImageEffectPropRenderScale, &renderScale.x, 2 );
00200         
00201         int viewportSize[2] = {0, 0};
00202         getViewportSize( viewportSize[0], viewportSize[1] );
00203         _argProperties.setIntPropertyN( kOfxInteractPropViewportSize, viewportSize, 2 ); // the openGL viewport size for the instance
00204         
00205         double backgroundColor[3] = {0, 0, 0};
00206         getBackgroundColour( backgroundColor[0], backgroundColor[1], backgroundColor[2] );
00207         _argProperties.setDoublePropertyN( kOfxInteractPropBackgroundColour, backgroundColor, 3 ); // the background colour of the application behind the current view
00208 }
00209 
00210 void OfxhInteract::setPenArgProps( const OfxPointD& penPos,
00211                                    const OfxPointI& penPosViewport,
00212                                    double           pressure )
00213 {
00214         _argProperties.setDoublePropertyN( kOfxInteractPropPenPosition, &penPos.x, 2 );
00215         #ifdef kOfxInteractPropPenViewportPosition
00216         _argProperties.setIntPropertyN( kOfxInteractPropPenViewportPosition, &penPosViewport.x, 2 );
00217         #endif
00218         _argProperties.setDoubleProperty( kOfxInteractPropPenPressure, pressure );
00219 }
00220 
00221 void OfxhInteract::setKeyArgProps( int   key,
00222                                    char* keyString )
00223 {
00224         _argProperties.setIntProperty( kOfxPropKeySym, key );
00225         _argProperties.setStringProperty( kOfxPropKeyString, keyString );
00226 }
00227 
00228 void OfxhInteract::createInstanceAction() OFX_EXCEPTION_SPEC
00229 {
00230         OfxStatus status = callEntry( kOfxActionCreateInstance, NULL );
00231 
00232         if( status == kOfxStatOK || status == kOfxStatReplyDefault )
00233         {
00234                 _state = eCreated;
00235         }
00236         else
00237         {
00238                 _state = eFailed;
00239                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00240         }
00241 }
00242 
00243 void OfxhInteract::drawAction( OfxTime          time,
00244                                const OfxPointD& renderScale ) OFX_EXCEPTION_SPEC
00245 {
00246         initArgProp( time, renderScale );
00247         OfxStatus status = callEntry( kOfxInteractActionDraw, &_argProperties );
00248         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00249                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00250 }
00251 
00252 void OfxhInteract::penMotionAction( OfxTime          time,
00253                                     const OfxPointD& renderScale,
00254                                     const OfxPointD& penPos,
00255                                     const OfxPointI& penPosViewport,
00256                                     double           pressure ) OFX_EXCEPTION_SPEC
00257 {
00258         initArgProp( time, renderScale );
00259         setPenArgProps( penPos, penPosViewport, pressure );
00260         OfxStatus status = callEntry( kOfxInteractActionPenMotion, &_argProperties );
00261         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00262                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00263 }
00264 
00265 void OfxhInteract::penUpAction( OfxTime          time,
00266                                 const OfxPointD& renderScale,
00267                                 const OfxPointD& penPos,
00268                                 const OfxPointI& penPosViewport,
00269                                 double           pressure ) OFX_EXCEPTION_SPEC
00270 {
00271         initArgProp( time, renderScale );
00272         setPenArgProps( penPos, penPosViewport, pressure );
00273         OfxStatus status = callEntry( kOfxInteractActionPenUp, &_argProperties );
00274         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00275                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00276 }
00277 
00278 void OfxhInteract::penDownAction( OfxTime          time,
00279                                   const OfxPointD& renderScale,
00280                                   const OfxPointD& penPos,
00281                                   const OfxPointI& penPosViewport,
00282                                   double           pressure ) OFX_EXCEPTION_SPEC
00283 {
00284         initArgProp( time, renderScale );
00285         setPenArgProps( penPos, penPosViewport, pressure );
00286         OfxStatus status = callEntry( kOfxInteractActionPenDown, &_argProperties );
00287         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00288                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00289 }
00290 
00291 void OfxhInteract::keyDownAction( OfxTime          time,
00292                                   const OfxPointD& renderScale,
00293                                   int              key,
00294                                   char*            keyString ) OFX_EXCEPTION_SPEC
00295 {
00296         initArgProp( time, renderScale );
00297         setKeyArgProps( key, keyString );
00298         OfxStatus status = callEntry( kOfxInteractActionKeyDown, &_argProperties );
00299         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00300                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00301 }
00302 
00303 void OfxhInteract::keyUpAction( OfxTime          time,
00304                                 const OfxPointD& renderScale,
00305                                 int              key,
00306                                 char*            keyString ) OFX_EXCEPTION_SPEC
00307 {
00308         initArgProp( time, renderScale );
00309         setKeyArgProps( key, keyString );
00310         OfxStatus status = callEntry( kOfxInteractActionKeyUp, &_argProperties );
00311         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00312                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00313 }
00314 
00315 void OfxhInteract::keyRepeatAction( OfxTime          time,
00316                                     const OfxPointD& renderScale,
00317                                     int              key,
00318                                     char*            keyString ) OFX_EXCEPTION_SPEC
00319 {
00320         initArgProp( time, renderScale );
00321         setKeyArgProps( key, keyString );
00322         OfxStatus status = callEntry( kOfxInteractActionKeyRepeat, &_argProperties );
00323         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00324                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00325 }
00326 
00327 void OfxhInteract::gainFocusAction( OfxTime          time,
00328                                     const OfxPointD& renderScale ) OFX_EXCEPTION_SPEC
00329 {
00330         initArgProp( time, renderScale );
00331         OfxStatus status = callEntry( kOfxInteractActionGainFocus, &_argProperties );
00332         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00333                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00334 }
00335 
00336 void OfxhInteract::loseFocusAction( OfxTime          time,
00337                                     const OfxPointD& renderScale ) OFX_EXCEPTION_SPEC
00338 {
00339         initArgProp( time, renderScale );
00340         OfxStatus status = callEntry( kOfxInteractActionLoseFocus, &_argProperties );
00341         if( status != kOfxStatOK && status != kOfxStatReplyDefault )
00342                 BOOST_THROW_EXCEPTION( OfxhException( status ) );
00343 }
00344 
00345 }
00346 }
00347 }
00348 }