1 /*
2 OFX Support Library, a library that skins the OFX plug-in API with C++ classes.
3 Copyright (C) 2004-2005 The Open Effects Association Ltd
4 Author Bruno Nicoletti bruno@thefoundry.co.uk
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 * Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
14 * Neither the name The Open Effects Association Ltd, nor the names of its
15 contributors may be used to endorse or promote products derived from this
16 software without specific prior written permission.
17 
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 The Open Effects Association Ltd
30 1 Wardour St
31 London W1D 6PA
32 England
33 
34 
35 */
36 
37 /** @brief This file contains code that skins the ofx interact suite (for image effects) */
38 
39 
40 #include "ofxsSupportPrivate.h"
41 #include <algorithm> // for find
42 
43 /** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries.
44 */
45 namespace OFX {
46 
47   /** @brief fetch a pixel scale out of the property set */
getPixelScale(const PropertySet & props)48   static OfxPointD getPixelScale(const PropertySet &props)
49   {
50     OfxPointD pixelScale = {1., 1.};
51     props.propGetDoubleN(kOfxInteractPropPixelScale, &pixelScale.x, 2);
52 
53     return pixelScale;
54   }
55 
56   /** @brief fetch a render scale out of the property set */
getRenderScale(const PropertySet & props)57   static OfxPointD getRenderScale(const PropertySet &props)
58   {
59     OfxPointD v = {1., 1.};
60     props.propGetDoubleN(kOfxImageEffectPropRenderScale, &v.x, 2);
61 
62     return v;
63   }
64 
65   /** @brief fetch a background colour out of the property set */
getBackgroundColour(const PropertySet & props)66   static OfxRGBColourD getBackgroundColour(const PropertySet &props)
67   {
68     OfxRGBColourD backGroundColour = {0., 0., 0.};
69     props.propGetDoubleN(kOfxInteractPropBackgroundColour, &backGroundColour.r, 3);
70 
71     return backGroundColour;
72   }
73 
74   /** @brief retrieves the image effect pointer from the interact handle */
retrieveEffectFromInteractHandle(OfxInteractHandle handle)75   static ImageEffect *retrieveEffectFromInteractHandle(OfxInteractHandle handle)
76   {
77     // get the properties set on this handle
78     OfxPropertySetHandle propHandle;
79     OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
80     throwSuiteStatusException(stat);
81     PropertySet interactProperties(propHandle);
82 
83     // get the effect handle from this handle
84     OfxImageEffectHandle effectHandle = (OfxImageEffectHandle) interactProperties.propGetPointer(kOfxPropEffectInstance);
85 
86     // get the effect properties
87     return OFX::Private::retrieveImageEffectPointer(effectHandle);
88   }
89 
90   /** @brief ctor */
Interact(OfxInteractHandle handle)91   Interact::Interact(OfxInteractHandle handle)
92     : _interactHandle(handle)
93     , _effect(NULL)
94   {
95     // get the properties set on this handle
96     OfxPropertySetHandle propHandle;
97     OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
98     throwSuiteStatusException(stat);
99     _interactProperties.propSetHandle(propHandle);
100 
101     // set othe instance data on the property handle to point to this interact
102     _interactProperties.propSetPointer(kOfxPropInstanceData, (void *)this);
103 
104     // get the effect handle from this handle
105     _effect = retrieveEffectFromInteractHandle(handle);
106   }
107 
108   /** @brief virtual destructor */
~Interact()109   Interact::~Interact()
110   {
111     // fetched clips and params are owned and deleted by the ImageEffect and its ParamSet
112   }
113 
114   /** @brief The bitdepth of each component in the openGL frame buffer */
115   int
getBitDepth(void) const116     Interact::getBitDepth(void) const
117   {
118     return _interactProperties.propGetInt(kOfxInteractPropBitDepth);
119   }
120 
121   /** @brief Does the openGL frame buffer have an alpha */
122   bool
hasAlpha(void) const123     Interact::hasAlpha(void) const
124   {
125     return _interactProperties.propGetInt(kOfxInteractPropHasAlpha) != 0;
126   }
127 
128   /** @brief Returns the size of a real screen pixel under the interact's cannonical projection */
129   OfxPointD
getPixelScale(void) const130     Interact::getPixelScale(void) const
131   {
132     return ::OFX::getPixelScale(_interactProperties);
133   }
134 
135   /** @brief The suggested colour to draw a widget in an interact */
136   bool
getSuggestedColour(OfxRGBColourD & c) const137     Interact::getSuggestedColour(OfxRGBColourD &c) const
138   {
139     // OFX 1.2/1.3 specs say that the host should return kOfxStatReplyDefault if there is no suggested color
140     int dim;
141     OfxStatus stat = OFX::Private::gPropSuite->propGetDimension(_interactProperties.propSetHandle(), kOfxInteractPropSuggestedColour, &dim);
142     // host may indicate that there is no suggested color either by returning kOfxStatReplyDefault or by returning dim=0
143     if (stat == kOfxStatReplyDefault || (stat == kOfxStatOK && dim < 3) ) {
144       return false;
145     }
146     if (stat == kOfxStatOK) {
147       stat = OFX::Private::gPropSuite->propGetDoubleN(_interactProperties.propSetHandle(), kOfxInteractPropSuggestedColour, 3, &c.r);
148     }
149 #ifdef OFX_EXTENSIONS_NUKE
150     if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
151       stat = OFX::Private::gPropSuite->propGetDoubleN(_interactProperties.propSetHandle(), kOfxPropOverlayColour, 3, &c.r);
152     }
153 #endif
154     if (stat != kOfxStatOK) {
155       return false; // host gave no suggestion (replied kOfxStatReplyDefault or property is unknown to host)
156     }
157     return true;
158   }
159 
160 #ifdef OFX_EXTENSIONS_NATRON
161   /** @brief Sets wether the interact uses an additional colour picking value in the inArgs of its actions. */
162   void
setColourPicking(bool useColourPicking)163     Interact::setColourPicking(bool useColourPicking)
164   {
165     _interactProperties.propSetInt(kNatronOfxInteractColourPicking, (int)useColourPicking, 0, false);
166   }
167 #endif
168 
169   /** @brief Request a redraw */
170   void
requestRedraw(void) const171     Interact::requestRedraw(void) const
172   {
173     OfxStatus stat = OFX::Private::gInteractSuite->interactRedraw(_interactHandle);
174     throwSuiteStatusException(stat);
175   }
176 
177   /** @brief Swap a buffer in the case of a double bufferred interact, this is possibly a silly one */
178   void
swapBuffers(void) const179     Interact::swapBuffers(void) const
180   {
181     OfxStatus stat = OFX::Private::gInteractSuite->interactSwapBuffers(_interactHandle);
182     throwSuiteStatusException(stat);
183   }
184 
185   /** @brief Set a param that the interact should be redrawn on if its value changes */
186   void
addParamToSlaveTo(Param * p)187     Interact::addParamToSlaveTo(Param *p)
188   {
189     // do we have it already ?
190     std::list<Param *>::iterator i;
191     i = std::find(_slaveParams.begin(), _slaveParams.end(), p);
192     if(i == _slaveParams.end()) {
193       // we have a new one to add in here
194       _slaveParams.push_back(p);
195 
196       // and set the property
197       int n = _interactProperties.propGetDimension(kOfxInteractPropSlaveToParam);
198       _interactProperties.propSetString(kOfxInteractPropSlaveToParam, p->getName(), n);
199     }
200 
201   }
202 
203   /** @brief Remova a param that the interact should be redrawn on if its value changes */
204   void
removeParamToSlaveTo(Param * p)205     Interact::removeParamToSlaveTo(Param *p)
206   {
207     // do we have it already ?
208     std::list<Param *>::iterator i;
209     i = std::find(_slaveParams.begin(), _slaveParams.end(), p);
210     if(i != _slaveParams.end()) {
211       // clobber it from the list
212       _slaveParams.erase(i);
213 
214       // reset the property to remove our dead one
215       _interactProperties.propReset(kOfxInteractPropSlaveToParam);
216 
217       // and add them all in again
218       int n = 0;
219       for(i = _slaveParams.begin(); i != _slaveParams.end(); ++i, ++n) {
220         _interactProperties.propSetString(kOfxInteractPropSlaveToParam, (*i)->getName(), n);
221       }
222     }
223   }
224 
225   /** @brief the background colour */
getBackgroundColour(void) const226   OfxRGBColourD Interact::getBackgroundColour(void) const
227   {
228     return OFX::getBackgroundColour(_interactProperties);
229   }
230 
231   /** @brief the function called to draw in the interact */
232   bool
draw(const DrawArgs &)233     Interact::draw(const DrawArgs &/*args*/)
234   {
235     return false;
236   }
237 
238   /** @brief the function called to handle pen motion in the interact
239 
240   returns true if the interact trapped the action in some sense. This will block the action being passed to
241   any other interact that may share the viewer.
242   */
243   bool
penMotion(const PenArgs &)244     Interact::penMotion(const PenArgs &/*args*/)
245   {
246     return false;
247   }
248 
249   /** @brief the function called to handle pen down events in the interact
250 
251   returns true if the interact trapped the action in some sense. This will block the action being passed to
252   any other interact that may share the viewer.
253   */
254   bool
penDown(const PenArgs &)255     Interact::penDown(const PenArgs &/*args*/)
256   {
257     return false;
258   }
259 
260   /** @brief the function called to handle pen up events in the interact
261 
262   returns true if the interact trapped the action in some sense. This will block the action being passed to
263   any other interact that may share the viewer.
264   */
265   bool
penUp(const PenArgs &)266     Interact::penUp(const PenArgs &/*args*/)
267   {
268     return false;
269   }
270 
271   /** @brief the function called to handle key down events in the interact
272 
273   returns true if the interact trapped the action in some sense. This will block the action being passed to
274   any other interact that may share the viewer.
275   */
276   bool
keyDown(const KeyArgs &)277     Interact::keyDown(const KeyArgs &/*args*/)
278   {
279     return false;
280   }
281 
282   /** @brief the function called to handle key up events in the interact
283 
284   returns true if the interact trapped the action in some sense. This will block the action being passed to
285   any other interact that may share the viewer.
286   */
287   bool
keyUp(const KeyArgs &)288     Interact::keyUp(const KeyArgs &/*args*/)
289   {
290     return false;
291   }
292 
293   /** @brief the function called to handle key down repeat events in the interact
294 
295   returns true if the interact trapped the action in some sense. This will block the action being passed to
296   any other interact that may share the viewer.
297   */
298   bool
keyRepeat(const KeyArgs &)299     Interact::keyRepeat(const KeyArgs &/*args*/)
300   {
301     return false;
302   }
303 
304   /** @brief Called when the interact is given input focus */
305   void
gainFocus(const FocusArgs &)306     Interact::gainFocus(const FocusArgs &/*args*/)
307   {
308   }
309 
310   /** @brief Called when the interact is loses input focus */
311   void
loseFocus(const FocusArgs &)312     Interact::loseFocus(const FocusArgs &/*args*/)
313   {
314   }
315 
316   ////////////////////////////////////////////////////////////////////////////////
317   // overlay interact guff
318 
319   /** @brief ctor */
OverlayInteract(OfxInteractHandle handle)320   OverlayInteract::OverlayInteract(OfxInteractHandle handle)
321     : Interact(handle)
322   {
323     // add this interact into the list of overlays that the effect knows about
324     if(_effect)
325       _effect->addOverlayInteract(this);
326   }
327 
328   /** @brief ctor */
~OverlayInteract()329   OverlayInteract::~OverlayInteract()
330   {
331     // add this interact into the list of overlays that the effect knows about
332     if(_effect)
333       _effect->removeOverlayInteract(this);
334   }
335 
336   ////////////////////////////////////////////////////////////////////////////////
337   /** @brief ctor */
InteractArgs(const PropertySet & props)338   InteractArgs::InteractArgs(const PropertySet &props)
339   {
340     time          = props.propGetDouble(kOfxPropTime);
341     renderScale   = getRenderScale(props);
342 #ifdef OFX_EXTENSIONS_NUKE
343     view          = props.propGetInt(kFnOfxImageEffectPropView, 0, false);
344 #endif
345 #ifdef OFX_EXTENSIONS_NATRON
346     pickerColour.r = pickerColour.g = pickerColour.b = pickerColour.a = -1.;
347     if ( !props.propExists(kNatronOfxPropPickerColour) ) {
348       hasPickerColour = false;
349     } else {
350       props.propGetDoubleN(kNatronOfxPropPickerColour, &pickerColour.r, 4, false);
351       hasPickerColour = (pickerColour.r != -1. || pickerColour.g != -1. || pickerColour.b != -1. || pickerColour.a != -1.);
352     }
353     screenPixelRatio = 1.;
354     screenPixelRatio = props.propGetDouble(kOfxInteractPropScreenPixelRatio, 0, false);
355 #endif
356   }
357 
358   /** @brief ctor */
DrawArgs(const PropertySet & props)359   DrawArgs::DrawArgs(const PropertySet &props)
360     : InteractArgs(props)
361   {
362 #ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
363     viewportSize.x = viewportSize.y = 0.;
364     props.propGetDoubleN(kOfxInteractPropViewportSize, &viewportSize.x, 2, false);
365 #endif
366     backGroundColour = getBackgroundColour(props);
367     pixelScale       = getPixelScale(props);
368   }
369 
370   /** @brief ctor */
PenArgs(const PropertySet & props)371   PenArgs::PenArgs(const PropertySet &props)
372     : InteractArgs(props)
373   {
374 #ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
375     viewportSize.x = viewportSize.y = 0.;
376     props.propGetDoubleN(kOfxInteractPropViewportSize, &viewportSize.x, 2, false);
377 #endif
378     pixelScale    = getPixelScale(props);
379     backGroundColour = getBackgroundColour(props);
380     penPosition.x = penPosition.y = 0;
381     props.propGetDoubleN(kOfxInteractPropPenPosition, &penPosition.x, 2);
382     // Introduced in OFX 1.2. Return (-1,-1) if not available
383     OfxPointI pen = {-1, -1};
384     props.propGetIntN(kOfxInteractPropPenViewportPosition, &pen.x, 2);
385     penViewportPosition.x = pen.x;
386     penViewportPosition.y = pen.y;
387     penPressure   = props.propGetDouble(kOfxInteractPropPenPressure);
388   }
389 
390   /** @brief ctor */
KeyArgs(const PropertySet & props)391   KeyArgs::KeyArgs(const PropertySet &props)
392     : InteractArgs(props)
393   {
394     time          = props.propGetDouble(kOfxPropTime);
395     renderScale   = getRenderScale(props);
396     keyString     = props.propGetString(kOfxPropKeyString);
397     keySymbol     = props.propGetInt(kOfxPropKeySym);
398   }
399 
400   /** @brief ctor */
FocusArgs(const PropertySet & props)401   FocusArgs::FocusArgs(const PropertySet &props)
402     : InteractArgs(props)
403   {
404 #ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
405     viewportSize.x = viewportSize.y = 0.;
406     props.propGetDoubleN(kOfxInteractPropViewportSize, &viewportSize.x, 2, false);
407 #endif
408     pixelScale       = getPixelScale(props);
409     backGroundColour = getBackgroundColour(props);
410   }
411 
getHasAlpha() const412   bool InteractDescriptor::getHasAlpha() const
413   {
414     return _props->propGetInt(kOfxInteractPropHasAlpha, 0, false);
415   }
416 
getBitDepth() const417   int InteractDescriptor::getBitDepth() const
418   {
419     return _props->propGetInt(kOfxInteractPropBitDepth, 0, false);
420   }
421 
422 #ifdef OFX_EXTENSIONS_NATRON
423   /** @brief Sets wether the interact uses an additional colour picking value in the inArgs of its actions. */
setColourPicking(bool useColourPicking)424   void InteractDescriptor::setColourPicking(bool useColourPicking)
425   {
426     _props->propSetInt(kNatronOfxInteractColourPicking, (int)useColourPicking, 0, false);
427   }
428 #endif
429 
setInteractSizeAspect(double asp)430   void ParamInteractDescriptor::setInteractSizeAspect(double asp)
431   {
432     _props->propSetDouble(kOfxParamPropInteractSizeAspect , asp);
433   }
434 
setInteractMinimumSize(int x,int y)435   void ParamInteractDescriptor::setInteractMinimumSize(int x, int y)
436   {
437     double s[2] = {(double)x, (double)y};
438     _props->propSetDoubleN(kOfxParamPropInteractMinimumSize, s, 2);
439   }
440 
setInteractPreferredSize(int x,int y)441   void ParamInteractDescriptor::setInteractPreferredSize(int x, int y)
442   {
443     int s[2] = {x, y};
444     _props->propSetIntN(kOfxParamPropInteractPreferedSize, s, 2);
445   }
446 
ParamInteract(OfxInteractHandle handle,ImageEffect * effect)447   ParamInteract::ParamInteract(OfxInteractHandle handle, ImageEffect* effect):Interact(handle), _effect(effect)
448   {}
449 
getInteractSize() const450   OfxPointI ParamInteract::getInteractSize() const
451   {
452     OfxPointI ret = {0, 0};
453     _interactProperties.propGetIntN(kOfxParamPropInteractSize, &ret.x, 2);
454 
455     return ret;
456   }
457 
458   namespace Private {
459     /** @brief fetches our pointer out of the props on the handle */
460     static
retrieveInteractPointer(OfxInteractHandle handle)461     Interact *retrieveInteractPointer(OfxInteractHandle handle)
462     {
463       Interact *instance;
464 
465       // get the prop set on the handle
466       OfxPropertySetHandle propHandle;
467       OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
468       throwSuiteStatusException(stat);
469 
470       // make our wrapper object
471       PropertySet props(propHandle);
472 
473       // fetch the instance data out of the properties
474       instance = (Interact *) props.propGetPointer(kOfxPropInstanceData);
475 
476       OFX::Log::error(instance == 0, "Instance data handle in effect instance properties is NULL!");
477 
478       // need to throw something here
479       if (!instance) {
480         throwSuiteStatusException(kOfxStatErrBadHandle);
481       }
482 
483       // and dance to the music
484       return instance;
485     }
486 
487     /** @brief The common entry point used by all interacts */
488     static
489     OfxStatus
interactMainEntry(const std::string & action,OfxInteractHandle handle,PropertySet inArgs,PropertySet)490       interactMainEntry(const std::string     &action,
491       OfxInteractHandle      handle,
492       PropertySet              inArgs,
493       PropertySet              /*outArgs*/)
494     {
495       OfxStatus stat = kOfxStatReplyDefault;
496 
497       // get the interact pointer
498       Interact *interact = retrieveInteractPointer(handle);
499 
500       // if one was not made, return and do nothing
501       if(!interact)
502         return stat;
503 
504       if(action == kOfxActionDestroyInstance) {
505         delete interact;
506         stat = kOfxStatOK;
507       }
508       else if(action ==   kOfxInteractActionDraw) {
509         // make the draw args
510         DrawArgs drawArgs(inArgs);
511         if(interact->draw(drawArgs))
512           stat = kOfxStatOK;
513       }
514       else if(action ==   kOfxInteractActionPenMotion) {
515 
516         // make the draw args
517         PenArgs args(inArgs);
518         if(interact->penMotion(args))
519           stat = kOfxStatOK;
520       }
521       else if(action ==   kOfxInteractActionPenDown) {
522         // make the draw args
523         PenArgs args(inArgs);
524         if(interact->penDown(args))
525           stat = kOfxStatOK;
526       }
527       else if(action ==   kOfxInteractActionPenUp) {
528         // make the draw args
529         PenArgs args(inArgs);
530         if(interact->penUp(args))
531           stat = kOfxStatOK;
532       }
533       else if(action ==   kOfxInteractActionKeyDown) {
534         // make the draw args
535         KeyArgs args(inArgs);
536         if(interact->keyDown(args))
537           stat = kOfxStatOK;
538       }
539       else if(action ==   kOfxInteractActionKeyUp) {
540         // make the draw args
541         KeyArgs args(inArgs);
542         if(interact->keyUp(args))
543           stat = kOfxStatOK;
544       }
545       else if(action ==   kOfxInteractActionKeyRepeat) {
546         // make the draw args
547         KeyArgs args(inArgs);
548         if(interact->keyRepeat(args))
549           stat = kOfxStatOK;
550       }
551       else if(action ==   kOfxInteractActionGainFocus) {
552         // make the draw args
553         FocusArgs args(inArgs);
554         interact->gainFocus(args);
555       }
556       else if(action ==   kOfxInteractActionLoseFocus) {
557         // make the draw args
558         FocusArgs args(inArgs);
559         interact->loseFocus(args);
560       }
561 
562       return stat;
563     }
564 
565     /** @brief The main entry for image effect overlays */
interactMainEntry(const char * actionRaw,const void * handleRaw,OfxPropertySetHandle inArgsRaw,OfxPropertySetHandle outArgsRaw,InteractDescriptor & desc)566     OfxStatus interactMainEntry(const char             *actionRaw,
567       const void             *handleRaw,
568       OfxPropertySetHandle    inArgsRaw,
569       OfxPropertySetHandle    outArgsRaw,
570       InteractDescriptor& desc)
571     {
572       OFX::Log::print("********************************************************************************");
573       OFX::Log::print("START overlayInteractMainEntry (%s)", actionRaw);
574       OFX::Log::indent();
575       OfxStatus stat = kOfxStatReplyDefault;
576 
577       try {
578         // Cast the raw handle to be an image effect handle, because that is what it is
579         OfxInteractHandle handle = (OfxInteractHandle) handleRaw;
580 
581         // Turn the arguments into wrapper objects to make our lives easier
582         OFX::PropertySet inArgs(inArgsRaw);
583         OFX::PropertySet outArgs(outArgsRaw);
584 
585         // turn the action into a std::string
586         std::string action(actionRaw);
587 
588         // figure the actions
589         if (action == kOfxActionDescribe) {
590           OfxPropertySetHandle propHandle;
591           OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
592           throwSuiteStatusException(stat);
593           PropertySet interactProperties(propHandle);
594           desc.setPropertySet(&interactProperties);
595           desc.describe();
596         }
597         else if (action == kOfxActionCreateInstance)
598         {
599           // fetch the image effect we are being made for out of the interact's property handle
600           ImageEffect *effect = retrieveEffectFromInteractHandle(handle);
601           OFX::Interact* interact = desc.createInstance(handle, effect);
602           (void)interact;
603           // and all was well
604           stat = kOfxStatOK;
605         }
606         else {
607           stat = interactMainEntry(action, handle, inArgs, outArgs);
608         }
609 
610       }
611       catch(...)
612       {
613         stat = kOfxStatFailed;
614       }
615 
616       OFX::Log::outdent();
617       OFX::Log::print("STOP overlayInteractMainEntry (%s)", actionRaw);
618       return stat;
619     }
620 
621   }; // end namespace private
622 
623   // methods in ImageEffect which depends on ofxsInteract
624 
625   /** @brief force all overlays on this interact to be redrawn */
redrawOverlays(void)626   void ImageEffect::redrawOverlays(void)
627   {
628     // find it
629     std::list<OverlayInteract *>::iterator i;
630     for(i = _overlayInteracts.begin(); i != _overlayInteracts.end(); ++i) {
631       (*i)->requestRedraw();
632     }
633   }
634 
635 }; // end of namespace
636