diff --git a/include/mode-private.h b/include/mode-private.h index fc6d6077..a4b06c74 100644 --- a/include/mode-private.h +++ b/include/mode-private.h @@ -1,6 +1,8 @@ #ifndef ROFI_MODE_PRIVATE_H #define ROFI_MODE_PRIVATE_H +#define ABI_VERSION 0x00000001 + /** * @param data Pointer to #Mode object. * @@ -98,6 +100,8 @@ typedef char* ( *_mode_preprocess_input )( Mode *sw, const char *input ); */ struct rofi_mode { + /** Used for external plugins. */ + unsigned int abi_version; /** Name (max 31 char long) */ char name[32]; char cfg_name_key[128]; diff --git a/source/rofi.c b/source/rofi.c index 3019853d..97ce848c 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -48,6 +48,7 @@ #include + #include "xcb-internal.h" #include "xkb-internal.h" @@ -69,6 +70,10 @@ #include "timings.h" +// Plugin abi version. +// TODO: move this check to mode.c +#include "mode-private.h" + // Pidfile. char *pidfile = NULL; const char *cache_dir = NULL; @@ -450,10 +455,16 @@ static int add_mode ( const char * token ) // Load module. GModule *mod = g_module_open ( token, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL ); if ( mod ) { - gpointer m = NULL; - if ( g_module_symbol ( mod, "mode", &m) ){ - modi[num_modi] = m; - num_modi++; + Mode *m = NULL; + if ( g_module_symbol ( mod, "mode", (gpointer *)&m) ){ + // Simple abi check. + if ( m->abi_version != ABI_VERSION ){ + fprintf(stderr, "ABI version of plugin does not match: %08X expecting: %08X\n", m->abi_version, ABI_VERSION); + g_module_close ( mod ); + } else { + modi[num_modi] = m; + num_modi++; + } } else { fprintf(stderr, "Symbol 'mode' not found in module: %s\n", token); g_module_close ( mod );