summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2017-03-04 12:00:59 +0100
committerDave Davenport <qball@gmpclient.org>2017-03-04 12:00:59 +0100
commit86dc1e14486044c4b5d7838005fbe7960d157026 (patch)
tree6bf2c878a94b7e93ff38fb91f5ca5915fa324e04
parent45c70cbecf980769ec5cda10e1186bf3d7dcb580 (diff)
Detect plugins on startup.
-rw-r--r--include/mode-private.h6
-rw-r--r--include/rofi.h8
-rw-r--r--source/dialogs/combi.c36
-rw-r--r--source/rofi.c205
4 files changed, 138 insertions, 117 deletions
diff --git a/include/mode-private.h b/include/mode-private.h
index 935402e4..67d3ca9d 100644
--- a/include/mode-private.h
+++ b/include/mode-private.h
@@ -1,7 +1,8 @@
#ifndef ROFI_MODE_PRIVATE_H
#define ROFI_MODE_PRIVATE_H
-#define ABI_VERSION 0x00000002
+#include <gmodule.h>
+#define ABI_VERSION 0x00000003
/**
* @param data Pointer to #Mode object.
@@ -149,5 +150,8 @@ struct rofi_mode
_mode_free free;
/** Extra fields for script */
void *ed;
+
+ /** Module */
+ GModule *module;
};
#endif // ROFI_MODE_PRIVATE_H
diff --git a/include/rofi.h b/include/rofi.h
index 87e571e4..ee2d4ccd 100644
--- a/include/rofi.h
+++ b/include/rofi.h
@@ -41,6 +41,7 @@ const Mode * rofi_get_mode ( unsigned int index );
* Queue an error.
*/
void rofi_add_error_message ( GString *str );
+
/**
* @param code the code to return
*
@@ -48,6 +49,13 @@ void rofi_add_error_message ( GString *str );
* This function sets the code that rofi will return on exit.
*/
void rofi_set_return_code ( int code );
+
+/**
+ * @param name Search for mode with this name.
+ *
+ * @return returns Mode * when found, NULL if not.
+ */
+Mode * rofi_collect_modi_search ( const char *name );
/** Reset terminal */
#define color_reset "\033[0m"
/** Set terminal text bold */
diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c
index 33bed0ce..4699f151 100644
--- a/source/dialogs/combi.c
+++ b/source/dialogs/combi.c
@@ -68,48 +68,22 @@ static void combi_mode_parse_switchers ( Mode *sw )
pd->switchers = (CombiMode *) g_realloc ( pd->switchers,
sizeof ( CombiMode ) * ( pd->num_switchers + 1 ) );
- // Window switcher.
- #ifdef WINDOW_MODE
- if ( strcasecmp ( token, "window" ) == 0 ) {
+ Mode *mode = rofi_collect_modi_search ( token );
+ if ( mode ){
pd->switchers[pd->num_switchers].disable = FALSE;
- pd->switchers[pd->num_switchers++].mode = &window_mode;
- }
- else if ( strcasecmp ( token, "windowcd" ) == 0 ) {
- pd->switchers[pd->num_switchers].disable = FALSE;
- pd->switchers[pd->num_switchers++].mode = &window_mode_cd;
- }
- else
- #endif // WINDOW_MODE
- // SSh dialog
- if ( strcasecmp ( token, "ssh" ) == 0 ) {
- pd->switchers[pd->num_switchers].disable = FALSE;
- pd->switchers[pd->num_switchers++].mode = &ssh_mode;
- }
- // Run dialog
- else if ( strcasecmp ( token, "run" ) == 0 ) {
- pd->switchers[pd->num_switchers].disable = FALSE;
- pd->switchers[pd->num_switchers++].mode = &run_mode;
- }
- #ifdef ENABLE_DRUN
- else if ( strcasecmp ( token, "drun" ) == 0 ) {
- pd->switchers[pd->num_switchers].disable = FALSE;
- pd->switchers[pd->num_switchers++].mode = &drun_mode;
- }
-#endif // ENABLE_DRUN
- else {
+ pd->switchers[pd->num_switchers++].mode = mode;
+ } else {
// If not build in, use custom switchers.
Mode *sw = script_switcher_parse_setup ( token );
if ( sw != NULL ) {
pd->switchers[pd->num_switchers].disable = FALSE;
pd->switchers[pd->num_switchers++].mode = sw;
- }
- else{
+ } else {
// Report error, don't continue.
fprintf ( stderr, "Invalid script switcher: %s\n", token );
token = NULL;
}
}
- // Keybinding.
}
// Free string that was modified by strtok_r
g_free ( switcher_str );
diff --git a/source/rofi.c b/source/rofi.c
index c933a742..fe952173 100644
--- a/source/rofi.c
+++ b/source/rofi.c
@@ -81,6 +81,7 @@ const char *cache_dir = NULL;
/** List of error messages.*/
GList *list_of_error_msgs = NULL;
+static void rofi_collect_modi_destroy ( void );
void rofi_add_error_message ( GString *str )
{
list_of_error_msgs = g_list_append ( list_of_error_msgs, str );
@@ -397,6 +398,116 @@ static void cleanup ()
rofi_theme = NULL;
}
TIMINGS_STOP ();
+ rofi_collect_modi_destroy ( );
+}
+
+/**
+ * Collected modi
+ */
+// List of (possibly uninitialized) modi's
+Mode ** available_modi = NULL;
+unsigned int num_available_modi = 0;
+
+/**
+ * @param name Search for mode with this name.
+ *
+ * @return returns Mode * when found, NULL if not.
+ */
+Mode * rofi_collect_modi_search ( const char *name )
+{
+ for ( unsigned int i = 0; i < num_available_modi; i++ ){
+ if ( g_strcmp0 ( name, available_modi[i]->name ) == 0 ) {
+ return available_modi[i];
+ }
+ }
+ return NULL;
+}
+/**
+ * @param mode Add mode to list.
+ *
+ * @returns TRUE when success.
+ */
+static gboolean rofi_collect_modi_add ( Mode *mode )
+{
+ Mode *m = rofi_collect_modi_search ( mode->name );
+ if ( m == NULL ) {
+ available_modi = g_realloc ( available_modi, sizeof(Mode *)*(num_available_modi+1));
+ // Set mode.
+ available_modi[num_available_modi] = mode;
+ num_available_modi++;
+ return TRUE;
+ }
+ return FALSE;
+}
+/**
+ * Find all available modi.
+ */
+static void rofi_collect_modi ( void )
+{
+#ifdef WINDOW_MODE
+ rofi_collect_modi_add ( &window_mode );
+ rofi_collect_modi_add ( &window_mode_cd );
+#endif
+ rofi_collect_modi_add ( &run_mode );
+ rofi_collect_modi_add ( &ssh_mode );
+#ifdef ENABLE_DRUN
+ rofi_collect_modi_add ( &drun_mode );
+#endif
+ rofi_collect_modi_add ( &combi_mode );
+ rofi_collect_modi_add ( &help_keys_mode );
+
+ GDir *dir = g_dir_open ( PLUGIN_PATH, 0, NULL );
+ if ( dir ) {
+ const char *dn = NULL;
+ while ( ( dn = g_dir_read_name ( dir ) ) )
+ {
+ if ( !g_str_has_suffix ( dn, G_MODULE_SUFFIX ) ) {
+ continue;
+ }
+ char *fn = g_build_filename ( PLUGIN_PATH, dn, NULL );
+ GModule *mod = g_module_open ( fn, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL );
+ if ( mod ) {
+ Mode *m = NULL;
+ if ( g_module_symbol ( mod, "mode", (gpointer *)&m) ){
+ 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 {
+ m->module = mod;
+ if ( ! rofi_collect_modi_add ( m ) ) {
+ g_module_close ( mod );
+ }
+ }
+ } else {
+ fprintf(stderr, "Symbol 'mode' not found in module: %s\n", fn);
+ g_module_close ( mod );
+ }
+ }
+ g_free ( fn );
+ }
+ g_dir_close ( dir );
+ }
+}
+
+/**
+ * Setup configuration for config.
+ */
+static void rofi_collect_modi_setup ( void )
+{
+ for ( unsigned int i = 0; i < num_available_modi ; i++ ) {
+ mode_set_config ( available_modi[i] );
+ }
+}
+static void rofi_collect_modi_destroy ( void )
+{
+ for ( unsigned int i = 0; i < num_available_modi ; i++ ) {
+ if ( available_modi[i]->module ) {
+ g_module_close ( available_modi[i]->module );
+ }
+ }
+ g_free ( available_modi );
+ available_modi = NULL;
+ num_available_modi = 0;
}
/**
@@ -412,85 +523,18 @@ static int add_mode ( const char * token )
// Resize and add entry.
modi = (Mode * *) g_realloc ( modi, sizeof ( Mode* ) * ( num_modi + 1 ) );
- // Window switcher.
-#ifdef WINDOW_MODE
- if ( strcasecmp ( token, "window" ) == 0 ) {
- modi[num_modi] = &window_mode;
- num_modi++;
- }
- else if ( strcasecmp ( token, "windowcd" ) == 0 ) {
- modi[num_modi] = &window_mode_cd;
- num_modi++;
- }
- else
-#endif // WINDOW_MODE
- // SSh dialog
- if ( strcasecmp ( token, "ssh" ) == 0 ) {
- modi[num_modi] = &ssh_mode;
- num_modi++;
- }
- else if ( strcasecmp ( token, mode_get_name ( &help_keys_mode ) ) == 0 ) {
- modi[num_modi] = &help_keys_mode;
- num_modi++;
- }
- // Run dialog
- else if ( strcasecmp ( token, "run" ) == 0 ) {
- modi[num_modi] = &run_mode;
- num_modi++;
- }
-#ifdef ENABLE_DRUN
- else if ( strcasecmp ( token, "drun" ) == 0 ) {
- modi[num_modi] = &drun_mode;
+ Mode *mode = rofi_collect_modi_search ( token );
+ if ( mode ) {
+ modi[num_modi] = mode;
num_modi++;
- }
-#endif
- // combi dialog
- else if ( strcasecmp ( token, "combi" ) == 0 ) {
- modi[num_modi] = &combi_mode;
- num_modi++;
- }
- else if ( g_str_has_suffix ( token, G_MODULE_SUFFIX ) )
- {
- gchar *fn;
- if ( token[0] != G_DIR_SEPARATOR) {
- fn = g_build_filename ( PLUGIN_PATH, token, NULL );
- } else {
- fn = g_strdup ( token );
- }
- TICK_N("Loading module");
- // Load module.
- GModule *mod = g_module_open ( fn, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL );
- if ( mod ) {
- 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 );
- }
-
- } else {
- fprintf ( stderr, "Failed to open module: %s\n", token);
- }
- g_free(fn);
- TICK_N("Loading module done");
- }
- else {
+ } else {
// If not build in, use custom modi.
Mode *sw = script_switcher_parse_setup ( token );
if ( sw != NULL ) {
modi[num_modi] = sw;
mode_set_config ( sw );
num_modi++;
- }
- else{
+ } else {
// Report error, don't continue.
fprintf ( stderr, "Invalid script switcher: %s\n", token );
}
@@ -509,19 +553,7 @@ static void setup_modi ( void )
}
// Free string that was modified by strtok_r
g_free ( switcher_str );
- // We cannot do this in main loop, as we create pointer to string,
- // and re-alloc moves that pointer.
- mode_set_config ( &ssh_mode );
- mode_set_config ( &run_mode );
-#ifdef ENABLE_DRUN
- mode_set_config ( &drun_mode );
-#endif
-
-#ifdef WINDOW_MODE
- mode_set_config ( &window_mode );
- mode_set_config ( &window_mode_cd );
-#endif // WINDOW_MODE
- mode_set_config ( &combi_mode );
+ rofi_collect_modi_setup ();
}
/**
@@ -892,7 +924,10 @@ int main ( int argc, char *argv[] )
fprintf ( stderr, "Failed to open display: %s", display_str );
return EXIT_FAILURE;
}
+
TICK_N ( "Open Display" );
+ rofi_collect_modi ();
+ TICK_N ( "Collect MODI" );
xcb->screen = xcb_aux_get_screen ( xcb->connection, xcb->screen_nbr );