1 /*************************************************************************** 2 * Copyright (C) 2010~2012 by CSSlayer * 3 * wengxt@gmail.com * 4 * Copyright (C) 2012~2013 by Yichao Yu * 5 * yyc1992@gmail.com * 6 * * 7 * This program is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU General Public License as published by * 9 * the Free Software Foundation; either version 2 of the License, or * 10 * (at your option) any later version. * 11 * * 12 * This program is distributed in the hope that it will be useful, * 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 15 * GNU General Public License for more details. * 16 * * 17 * You should have received a copy of the GNU General Public License * 18 * along with this program; if not, write to the * 19 * Free Software Foundation, Inc., * 20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * 21 ***************************************************************************/ 22 23 /** 24 * @addtogroup Fcitx 25 * @{ 26 */ 27 28 #ifndef _FCITX_MODULE_H 29 #define _FCITX_MODULE_H 30 #include <fcitx-config/fcitx-config.h> 31 #include <fcitx-utils/utarray.h> 32 #include <fcitx-utils/utils.h> 33 #include <fcitx/addon.h> 34 #include <fcitx/fcitx.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 struct _FcitxInstance; 41 42 /** 43 * A misc module in Fcitx, it can register hook, or add it's own event 44 * to Fcitx main loop. 45 **/ 46 typedef struct _FcitxModule { 47 /** 48 * construction function 49 */ 50 void* (*Create)(struct _FcitxInstance* instance); 51 /** 52 * set main loop watch fd, no need to implement 53 */ 54 void (*SetFD)(void*); 55 /** 56 * main loop event handle, no need to implement 57 */ 58 void (*ProcessEvent)(void*); 59 /** 60 * destruct function 61 */ 62 void (*Destroy)(void*); 63 /** 64 * reload config, no need to implement 65 */ 66 void (*ReloadConfig)(void*); 67 } FcitxModule; 68 69 /** 70 * the argument to invoke module function 71 **/ 72 typedef struct _FcitxModuleFunctionArg { 73 /** 74 * arguments 75 **/ 76 void* args[10]; 77 } FcitxModuleFunctionArg; 78 typedef void *(*FcitxModuleFunction)(void *self, FcitxModuleFunctionArg); 79 80 /** 81 * load all modules 82 * 83 * @param instance fcitx instance 84 * @return void 85 **/ 86 void FcitxModuleLoad(struct _FcitxInstance* instance); 87 88 /** 89 * Find a exported function of a addon. 90 * 91 * @param addon addon 92 * @param functionId function index 93 * @return FcitxModuleFunction 94 **/ 95 FcitxModuleFunction FcitxModuleFindFunction(FcitxAddon *addon, 96 int func_id); 97 98 void *FcitxModuleInvokeOnAddon(FcitxAddon *addon, FcitxModuleFunction func, 99 FcitxModuleFunctionArg *args); 100 /** 101 * invode inter module function with addon pointer, returns NULL when fails (the function itself can also return NULL) 102 * 103 * @param addon addon 104 * @param functionId function index 105 * @param args arguments 106 * @return void* 107 **/ 108 FCITX_DEPRECATED 109 void* FcitxModuleInvokeFunction(FcitxAddon* addon, int functionId, 110 FcitxModuleFunctionArg args); 111 #define FcitxModuleInvokeVaArgs(addon, functionId, ARGV...) \ 112 (FcitxModuleInvokeFunction(addon, functionId, \ 113 (FcitxModuleFunctionArg){ {ARGV} })) 114 115 /** 116 * invoke inter module function with addon name, returns NULL when fails (the function itself can also return NULL) 117 * 118 * @param instance fcitx instance 119 * @param name addon name 120 * @param functionId function index 121 * @param args arguments 122 * @return void* 123 **/ 124 FCITX_DEPRECATED 125 void* FcitxModuleInvokeFunctionByName(struct _FcitxInstance* instance, const char* name, int functionId, FcitxModuleFunctionArg args); 126 #define FcitxModuleInvokeVaArgsByName(instance, name, functionId, ARGV...) \ 127 (FcitxModuleInvokeFunctionByName(instance, name, functionId, \ 128 (FcitxModuleFunctionArg){ {ARGV} })) 129 130 /** call a function provides by other addon */ 131 #define InvokeFunction(INST, MODULE, FUNC, ARG) \ 132 ((MODULE##_##FUNC##_RETURNTYPE)FcitxModuleInvokeFunctionByName(INST, MODULE##_NAME, MODULE##_##FUNC, ARG)) 133 134 #define InvokeVaArgs(INST, MODULE, FUNC, ARGV...) \ 135 ((MODULE##_##FUNC##_RETURNTYPE)FcitxModuleInvokeFunctionByName( \ 136 INST, MODULE##_NAME, MODULE##_##FUNC, \ 137 (FcitxModuleFunctionArg){ {ARGV} })) 138 139 /** add a function to a addon */ 140 #define AddFunction(ADDON, Realname) \ 141 do { \ 142 FCITX_DEPRECATED void *(AddonFunction) = (void*)Realname; \ 143 utarray_push_back(&ADDON->functionList, &(AddonFunction)); \ 144 } while(0) 145 146 /** 147 * add a function to a addon 148 * 149 * @param addon 150 * @param func 151 **/ 152 void FcitxModuleAddFunction(FcitxAddon *addon, FcitxModuleFunction func); 153 154 #ifdef __cplusplus 155 #define DECLARE_ADDFUNCTIONS(prefix) \ 156 extern "C" { \ 157 static inline FcitxAddon* \ 158 Fcitx_##prefix##_GetAddon(FcitxInstance *instance); \ 159 static void Fcitx##prefix##AddFunctions(FcitxInstance *instance); \ 160 } 161 #else 162 #define DECLARE_ADDFUNCTIONS(prefix) \ 163 static inline FcitxAddon* \ 164 Fcitx_##prefix##_GetAddon(FcitxInstance *instance); \ 165 static void Fcitx##prefix##AddFunctions(FcitxInstance *instance); 166 #endif 167 168 // Well won't work if there are multiple instances, but that will also break 169 // lots of other things anyway. 170 #define DEFINE_GET_ADDON(name, prefix) \ 171 static inline FcitxAddon* \ 172 Fcitx##prefix##GetAddon(FcitxInstance *instance) \ 173 { \ 174 static FcitxAddon *addon = NULL; \ 175 static FcitxInstance *_instance = NULL; \ 176 if (fcitx_unlikely(_instance != instance)) { \ 177 _instance = instance; \ 178 addon = FcitxAddonsGetAddonByName( \ 179 FcitxInstanceGetAddons(instance), name); \ 180 } \ 181 return addon; \ 182 } 183 184 #define DEFINE_GET_AND_INVOKE_FUNC(prefix, suffix, id) \ 185 DEFINE_GET_AND_INVOKE_FUNC_WITH_ERROR(prefix, suffix, id, NULL) 186 #define DEFINE_GET_AND_INVOKE_FUNC_WITH_ERROR(prefix, suffix, id, err_ret) \ 187 DEFINE_GET_AND_INVOKE_FUNC_WITH_TYPE_AND_ERROR(prefix, suffix, id, \ 188 intptr_t, (intptr_t)err_ret) 189 190 #define DEFINE_GET_AND_INVOKE_FUNC_WITH_TYPE_AND_ERROR(prefix, suffix, \ 191 id, type, err_ret) \ 192 static inline FcitxModuleFunction \ 193 Fcitx##prefix##Find##suffix(FcitxAddon *addon) \ 194 { \ 195 static FcitxAddon *_addon = NULL; \ 196 static FcitxModuleFunction func = NULL; \ 197 if (fcitx_unlikely(addon != _addon)) { \ 198 _addon = addon; \ 199 func = FcitxModuleFindFunction(addon, id); \ 200 } \ 201 return func; \ 202 } \ 203 static inline void* \ 204 Fcitx##prefix##Invoke##suffix(FcitxInstance *instance, \ 205 FcitxModuleFunctionArg args) \ 206 { \ 207 static type _on_err = (err_ret); \ 208 FCITX_DEF_CAST_TO_PTR(on_err, type, _on_err); \ 209 FcitxAddon *addon = Fcitx##prefix##GetAddon(instance); \ 210 if (fcitx_unlikely(!addon)) \ 211 return on_err; \ 212 FcitxModuleFunction func = Fcitx##prefix##Find##suffix(addon); \ 213 if (fcitx_unlikely(!func)) \ 214 return on_err; \ 215 return FcitxModuleInvokeOnAddon(addon, func, &args); \ 216 } 217 218 #define FCITX_DEF_MODULE_ARGS(var, ARGV...) \ 219 FcitxModuleFunctionArg var = { {ARGV} } 220 221 #define FCITX_DEF_MODULE_ARGS_LONG(var, arg0, arg1, arg2, arg3, arg4, \ 222 arg5, arg6, arg7, ARGV...) \ 223 const void *__fcitx_def_mod_arg_long_##var##_extras[] = {ARGV}; \ 224 const size_t __fcitx_def_mod_arg_long_##var##_n = \ 225 sizeof(__fcitx_def_mod_arg_long_##var##_extras) / sizeof(void*); \ 226 FcitxModuleFunctionArg var = \ 227 { {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, \ 228 fcitx_utils_size_to_ptr(__fcitx_def_mod_arg_long_##var##_n), \ 229 (void*)(intptr_t)(__fcitx_def_mod_arg_long_##var##_extras)} } 230 231 #define FCITX_MODULE_FUNCTION_ARGS void *arg, FcitxModuleFunctionArg args 232 #define FCITX_MODULE_SELF(NAME, TYPE) TYPE *NAME = (TYPE*)arg 233 #define FCITX_MODULE_ARG(NAME, TYPE, INDEX) \ 234 FCITX_DEF_CAST_FROM_PTR(TYPE, NAME, args.args[(INDEX)]) 235 236 #ifdef __cplusplus 237 } 238 #endif 239 240 #endif 241 /** 242 * @} 243 */ 244 // kate: indent-mode cstyle; space-indent on; indent-width 0; 245