Skip to content
Snippets Groups Projects
gvl_wrappers.h 22.2 KiB
Newer Older
/*
 * gvl_wrappers.h - Wrapper functions for locking/unlocking the Ruby GVL
 *
 * These are some obscure preprocessor directives that allow to generate
 * drop-in replacement wrapper functions in a declarative manner.
 * These wrapper functions ensure that ruby's GVL is released on each
 * function call and reacquired at the end of the call or in callbacks.
 * This way blocking functions calls don't block concurrent ruby threads.
 *
 * The wrapper of each function is prefixed by "gvl_".
 *
 * Use "gcc -E" to retrieve the generated code.
 */

#ifndef __gvl_wrappers_h
#define __gvl_wrappers_h

extern "C" {
  #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
  extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
  #endif
  #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
  extern "C" void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
          rb_unblock_function_t *ubf, void *data2);
  #endif
}
#define DEFINE_PARAM_LIST1(type, ref, name) \
#define DEFINE_PARAM_LIST2(type, ref, name) \
#define DEFINE_PARAM_LIST3(type, ref, name) \
  , type ref name
#define DEFINE_PARAM_LIST4(type, ref, name) \
  , typename type

#define DEFINE_PARAM_LIST5(type, ref, name) \
  , type

#define DEFINE_PARAM_DECL(type, ref, name) \
  type ref name;

#define DEFINE_GVL_WRAPPER_STRUCT(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
  struct gvl_wrapper_##klass##_##name##_params { \
    struct { \
      firstparamtype firstparamname; \
      FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_DECL) \
    } params; \
    when_non_void( rettype retval; ) \
  };

extern __thread int g_fxrb_thread_has_gvl;

#define DEFINE_GVL_SKELETON(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
  static void * gvl_##klass##_##name##_skeleton( void *data ){ \
    struct gvl_wrapper_##klass##_##name##_params *p = (struct gvl_wrapper_##klass##_##name##_params*)data; \
    g_fxrb_thread_has_gvl = 0; \
    when_non_void( p->retval = ) \
      klass##_##name##_gvl( p->params.firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST2) ); \
    g_fxrb_thread_has_gvl = 1; \
    return NULL; \
  }

#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
  #define DEFINE_GVL_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
    rettype klass##_##name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \
      struct gvl_wrapper_##klass##_##name##_params params = { \
        {firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)}, when_non_void((rettype)0) \
      }; \
      rb_thread_call_without_gvl(gvl_##klass##_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
      when_non_void( return params.retval; ) \
    }
  #define DEFINE_GVL_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
    rettype klass##_##name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \
      return klass##_##name##_gvl(firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)); \
    }
#define DEFINE_GVL_STUB_DECL(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
  rettype klass##_##name( firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3));
#define DEFINE_GVLCB_WRAPPER_STRUCT(name, when_non_void, rettype, firstparamtype, firstparamname, paramcount) \
  template<typename firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST4)> \
        struct gvl_wrapper_##name##_##paramcount##_params { \
    struct { \
      firstparamtype firstparamname; \
      FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_DECL) \
    } params; \
    when_non_void( rettype retval; ) \
  };
#define DEFINE_GVLCB_STUB_DECL(name, when_non_void, rettype, firstparamtype, firstparamname, paramcount) \
  template<typename firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST4)> \
        rettype name( firstparamtype firstparamname FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST3));

#define DEFINE_GVLCB_SKELETON(name, when_non_void, rettype, firstparamtype, firstparamname, paramcount) \
  template<typename firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST4)> \
        static void * gvl_##name##_##paramcount##_skeleton( void *data ){ \
    struct gvl_wrapper_##name##_##paramcount##_params<firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST5)>  *p = \
        (struct gvl_wrapper_##name##_##paramcount##_params<firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST5)>*)data; \
    when_non_void( p->retval = ) \
      name##_gvlcb( p->params.firstparamname FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST2) ); \
    return NULL; \
  }

#if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
  #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, firstparamtype, firstparamname, paramcount) \
    template<typename firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST4)> \
          rettype name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST3)){ \
      if( g_fxrb_thread_has_gvl ){ \
        return name##_gvlcb( firstparamname FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST1) ); \
        struct gvl_wrapper_##name##_##paramcount##_params<firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST5)> params = { \
          {firstparamname FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST1)} \
        rb_thread_call_with_gvl(gvl_##name##_##paramcount##_skeleton<firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST5)>, &params); \
        when_non_void( return params.retval; ) \
      } \
    }
#else
  #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, firstparamtype, firstparamname, paramcount) \
    template<typename firstparamtype FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST4)> \
          rettype name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST3)){ \
      return name##_gvlcb( firstparamname FOR_EACH_PARAM_OF_##name##_##paramcount(DEFINE_PARAM_LIST1) ); \
#define GVL_TYPE_VOID(string)
#define GVL_TYPE_NONVOID(string) string


/*
* Definitions of blocking functions and their parameters
*/

#define FOR_EACH_PARAM_OF_FXImage_loadPixels(param) \
  param(FXStream, &, store)
#define FOR_EACH_PARAM_OF_FXImage_savePixels(param) \
  param(FXStream, &, store)
Lars Kanis's avatar
Lars Kanis committed
/* function( class, name, baseclass, void_or_nonvoid, returntype, firstparamtype, firstparamname ) */
#define FOR_EACH_BLOCKING_FUNCTION(function) \
  function(FXImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXImage *, self) \
  function(FXImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXImage *, self) \
  function(FXBMPImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXBMPImage *, self) \
  function(FXBMPImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXBMPImage *, self) \
  function(FXJPGImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXJPGImage *, self) \
  function(FXJPGImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXJPGImage *, self) \
  function(FXGIFImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXGIFImage *, self) \
  function(FXGIFImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXGIFImage *, self) \
  function(FXICOImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXICOImage *, self) \
  function(FXICOImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXICOImage *, self) \
  function(FXPNGImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPNGImage *, self) \
  function(FXPNGImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPNGImage *, self) \
  function(FXPPMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPPMImage *, self) \
  function(FXPPMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPPMImage *, self) \
  function(FXPCXImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPCXImage *, self) \
  function(FXPCXImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPCXImage *, self) \
  function(FXRGBImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXRGBImage *, self) \
  function(FXRGBImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXRGBImage *, self) \
  function(FXTGAImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTGAImage *, self) \
  function(FXTGAImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTGAImage *, self) \
  function(FXTIFImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTIFImage *, self) \
  function(FXTIFImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTIFImage *, self) \
  function(FXXBMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXBMImage *, self) \
  function(FXXBMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXBMImage *, self) \
  function(FXXPMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXPMImage *, self) \
  function(FXXPMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMImage *, self) \
  function(FXIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXIcon *, self) \
  function(FXIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXIcon *, self) \
  function(FXBMPIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXBMPIcon *, self) \
  function(FXBMPIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXBMPIcon *, self) \
  function(FXJPGIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXJPGIcon *, self) \
  function(FXJPGIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXJPGIcon *, self) \
  function(FXGIFIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXGIFIcon *, self) \
  function(FXGIFIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXGIFIcon *, self) \
  function(FXICOIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXICOIcon *, self) \
  function(FXICOIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXICOIcon *, self) \
  function(FXPNGIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPNGIcon *, self) \
  function(FXPNGIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPNGIcon *, self) \
  function(FXPPMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPPMIcon *, self) \
  function(FXPPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPPMIcon *, self) \
  function(FXPCXIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPCXIcon *, self) \
  function(FXPCXIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPCXIcon *, self) \
  function(FXRGBIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXRGBIcon *, self) \
  function(FXRGBIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXRGBIcon *, self) \
  function(FXTGAIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTGAIcon *, self) \
  function(FXTGAIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTGAIcon *, self) \
  function(FXTIFIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTIFIcon *, self) \
  function(FXTIFIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTIFIcon *, self) \
  function(FXXBMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXBMIcon *, self) \
  function(FXXBMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXBMIcon *, self) \
  function(FXXPMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXPMIcon *, self) \
  function(FXXPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMIcon *, self)


FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL )

/*
 * Definitions of callback functions and their parameters
 */

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_2(param) \
  param(ID, , func)
#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_3(param) \
  param(ID, , func) \
  param(TYPE1, &, arg1)

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3)

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_6(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4)

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_7(param) \
  param(ID, , func) \
  param(TYPE1, &, arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4) \
  param(TYPE5, , arg5)

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_8(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, &, arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4) \
  param(TYPE5, , arg5) \
  param(TYPE6, , arg6)

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_9(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4) \
  param(TYPE5, , arg5) \
  param(TYPE6, , arg6) \
  param(TYPE7, , arg7)

#define FOR_EACH_PARAM_OF_FXRbCallVoidMethod_11(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4) \
  param(TYPE5, , arg5) \
  param(TYPE6, , arg6) \
  param(TYPE7, , arg7) \
  param(TYPE8, , arg8) \
  param(TYPE9, , arg9)

#define FOR_EACH_PARAM_OF_FXRbCallBoolMethod_2(param) \
  param(ID, , func)

#define FOR_EACH_PARAM_OF_FXRbCallBoolMethod_3(param) \
  param(ID, , func) \
  param(TYPE1, &, arg1)

#define FOR_EACH_PARAM_OF_FXRbCallBoolMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

#define FOR_EACH_PARAM_OF_FXRbCallBoolMethod_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3)

#define FOR_EACH_PARAM_OF_FXRbCallBoolMethod_7(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4) \
  param(TYPE5, , arg5)

#define FOR_EACH_PARAM_OF_FXRbCallIntMethod_2(param) \
  param(ID, , func)

#define FOR_EACH_PARAM_OF_FXRbCallIntMethod_3(param) \
  param(ID, , func) \
  param(TYPE1, , arg1)

#define FOR_EACH_PARAM_OF_FXRbCallIntMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

#define FOR_EACH_PARAM_OF_FXRbCallIntMethod_7(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4) \
  param(TYPE5, , arg5)

#define FOR_EACH_PARAM_OF_FXRbCallLongMethod_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3)

#define FOR_EACH_PARAM_OF_FXRbCallUIntMethod_3(param) \
  param(ID, , func) \
  param(TYPE1, , arg1)

#define FOR_EACH_PARAM_OF_FXRbCallGLObjectMethod_2(param) \
  param(ID, , func)

#define FOR_EACH_PARAM_OF_FXRbCallGLObjectMethod_3(param) \
  param(ID, , func) \
  param(TYPE1, , arg1)

#define FOR_EACH_PARAM_OF_FXRbCallGLObjectMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

#define FOR_EACH_PARAM_OF_FXRbCallStringMethod_2(param) \
  param(ID, , func)

#define FOR_EACH_PARAM_OF_FXRbCallCStringMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

#define FOR_EACH_PARAM_OF_FXRbCallCStringMethod_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3)

#define FOR_EACH_PARAM_OF_FXRbCallGLObjectArrayMethod_6(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4)

#define FOR_EACH_PARAM_OF_FXRbCallTableItemMethod_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3)

#define FOR_EACH_PARAM_OF_FXRbCallFileAssocMethod_3(param) \
  param(ID, , func) \
  param(TYPE1, , arg1)

#define FOR_EACH_PARAM_OF_FXRbCallIconMethod_2(param) \
  param(ID, , func)

#define FOR_EACH_PARAM_OF_FXRbCallIconMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, &, arg1) \
  param(TYPE2, &, arg2)

#define FOR_EACH_PARAM_OF_FXRbCallIconMethod_6(param) \
  param(ID, , func) \
  param(TYPE1, &, arg1) \
  param(TYPE2, &, arg2) \
  param(TYPE3, &, arg3) \
  param(TYPE4, &, arg4)

#define FOR_EACH_PARAM_OF_FXRbCallImageMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, &, arg1) \
  param(TYPE2, &, arg2)

#define FOR_EACH_PARAM_OF_FXRbCallImageMethod_6(param) \
  param(ID, , func) \
  param(TYPE1, &, arg1) \
  param(TYPE2, &, arg2) \
  param(TYPE3, &, arg3) \
  param(TYPE4, &, arg4)

#define FOR_EACH_PARAM_OF_FXRbCallWindowMethod_3(param) \
  param(ID, , func) \
  param(TYPE1, , arg1)

#define FOR_EACH_PARAM_OF_FXRbCallColorMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

#define FOR_EACH_PARAM_OF_FXRbCallRangeMethod_2(param) \
  param(ID, , func)

#define FOR_EACH_PARAM_OF_FXRbCallWCharMethod_2(param) \
  param(ID, , func)

#define FOR_EACH_PARAM_OF_FXRbCallSetDashes_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3)

#define FOR_EACH_PARAM_OF_FXRbLookupHandler_2(param) \
  param(ITEMB, , itemb)

#define FOR_EACH_PARAM_OF_FXRbHandleMessage_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3)

#define FOR_EACH_PARAM_OF_FXRbComboBox_sortFunc_2(param) \
  param(ITEMB, , itemb)

#define FOR_EACH_PARAM_OF_FXRbFoldingList_sortFunc_2(param) \
  param(ITEMB, , itemb)

#define FOR_EACH_PARAM_OF_FXRbIconList_sortFunc_2(param) \
  param(ITEMB, , itemb)

#define FOR_EACH_PARAM_OF_FXRbList_sortFunc_2(param) \
  param(ITEMB, , itemb)

#define FOR_EACH_PARAM_OF_FXRbListBox_sortFunc_2(param) \
  param(ITEMB, , itemb)

#define FOR_EACH_PARAM_OF_FXRbTreeList_sortFunc_2(param) \
  param(ITEMB, , itemb)

#define FOR_EACH_PARAM_OF_FXRbCallDCDrawMethod_5(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, &, arg3)

#define FOR_EACH_PARAM_OF_FXRbCallDCDrawMethod_6(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2) \
  param(TYPE3, , arg3) \
  param(TYPE4, , arg4)

#define FOR_EACH_PARAM_OF_FXRbCallTreeItemMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

#define FOR_EACH_PARAM_OF_FXRbCallFoldingItemMethod_4(param) \
  param(ID, , func) \
  param(TYPE1, , arg1) \
  param(TYPE2, , arg2)

/* function( name, void_or_nonvoid, returntype, firstparamtype, firstparamname, paramcount ) */
#define FOR_EACH_CALLBACK_FUNCTION(function) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 2) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 3) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 4) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 5) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 6) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 7) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 8) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 9) \
  function(FXRbCallVoidMethod, GVL_TYPE_VOID, void, RECV, recv, 11) \
  function(FXRbCallBoolMethod, GVL_TYPE_NONVOID, bool, RECV, recv, 2) \
  function(FXRbCallBoolMethod, GVL_TYPE_NONVOID, bool, RECV, recv, 3) \
  function(FXRbCallBoolMethod, GVL_TYPE_NONVOID, bool, RECV, recv, 4) \
  function(FXRbCallBoolMethod, GVL_TYPE_NONVOID, bool, RECV, recv, 5) \
  function(FXRbCallBoolMethod, GVL_TYPE_NONVOID, bool, RECV, recv, 7) \
  function(FXRbCallIntMethod, GVL_TYPE_NONVOID, FXint, RECV, recv, 2) \
  function(FXRbCallIntMethod, GVL_TYPE_NONVOID, FXint, RECV, recv, 3) \
  function(FXRbCallIntMethod, GVL_TYPE_NONVOID, FXint, RECV, recv, 4) \
  function(FXRbCallIntMethod, GVL_TYPE_NONVOID, FXint, RECV, recv, 7) \
  function(FXRbCallLongMethod, GVL_TYPE_NONVOID, FXint, RECV, recv, 5) \
  function(FXRbCallUIntMethod, GVL_TYPE_NONVOID, FXint, RECV, recv, 3) \
  function(FXRbCallGLObjectMethod, GVL_TYPE_NONVOID, FXGLObject*, RECV, recv, 2) \
  function(FXRbCallGLObjectMethod, GVL_TYPE_NONVOID, FXGLObject*, RECV, recv, 3) \
  function(FXRbCallGLObjectMethod, GVL_TYPE_NONVOID, FXGLObject*, RECV, recv, 4) \
  function(FXRbCallStringMethod, GVL_TYPE_NONVOID, FXString, RECV, recv, 2) \
  function(FXRbCallCStringMethod, GVL_TYPE_NONVOID, const FXchar*, RECV, recv, 4) \
  function(FXRbCallCStringMethod, GVL_TYPE_NONVOID, const FXchar*, RECV, recv, 5) \
  function(FXRbCallGLObjectArrayMethod, GVL_TYPE_NONVOID, FXGLObject**, RECV, recv, 6) \
  function(FXRbCallTableItemMethod, GVL_TYPE_NONVOID, FXTableItem*, RECV, recv, 5) \
  function(FXRbCallFileAssocMethod, GVL_TYPE_NONVOID, FXFileAssoc*, RECV, recv, 3) \
  function(FXRbCallIconMethod, GVL_TYPE_NONVOID, FXIcon*, RECV, recv, 2) \
  function(FXRbCallIconMethod, GVL_TYPE_NONVOID, FXIcon*, RECV, recv, 4) \
  function(FXRbCallIconMethod, GVL_TYPE_NONVOID, FXIcon*, RECV, recv, 6) \
  function(FXRbCallImageMethod, GVL_TYPE_NONVOID, FXImage*, RECV, recv, 4) \
  function(FXRbCallImageMethod, GVL_TYPE_NONVOID, FXImage*, RECV, recv, 6) \
  function(FXRbCallWindowMethod, GVL_TYPE_NONVOID, FXWindow*, RECV, recv, 3) \
  function(FXRbCallColorMethod, GVL_TYPE_NONVOID, FXColor, RECV, recv, 4) \
  function(FXRbCallRangeMethod, GVL_TYPE_NONVOID, FXRangef, RECV, recv, 2) \
  function(FXRbCallWCharMethod, GVL_TYPE_NONVOID, FXwchar, RECV, recv, 2) \
  function(FXRbCallSetDashes, GVL_TYPE_VOID, void, RECV, recv, 5) \
  function(FXRbLookupHandler, GVL_TYPE_NONVOID, ID, RECV, recv, 2) \
  function(FXRbHandleMessage, GVL_TYPE_NONVOID, long, RECV, recv, 5) \
  function(FXRbComboBox_sortFunc, GVL_TYPE_NONVOID, FXint, ITEMA, itema, 2) \
  function(FXRbFoldingList_sortFunc, GVL_TYPE_NONVOID, FXint, ITEMA, itema, 2) \
  function(FXRbIconList_sortFunc, GVL_TYPE_NONVOID, FXint, ITEMA, itema, 2) \
  function(FXRbList_sortFunc, GVL_TYPE_NONVOID, FXint, ITEMA, itema, 2) \
  function(FXRbListBox_sortFunc, GVL_TYPE_NONVOID, FXint, ITEMA, itema, 2) \
  function(FXRbTreeList_sortFunc, GVL_TYPE_NONVOID, FXint, ITEMA, itema, 2) \
  function(FXRbCallDCDrawMethod, GVL_TYPE_VOID, void, RECV, recv, 5) \
  function(FXRbCallDCDrawMethod, GVL_TYPE_VOID, void, RECV, recv, 6) \
  function(FXRbCallTreeItemMethod, GVL_TYPE_NONVOID, FXTreeItem*, RECV, recv, 4) \
  function(FXRbCallFoldingItemMethod, GVL_TYPE_NONVOID, FXFoldingItem*, RECV, recv, 4) \
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB_DECL )
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_WRAPPER_STRUCT )
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON )
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB )
#endif /* end __gvl_wrappers_h */