mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-25 13:55:34 -05:00
Detect plugins on startup.
This commit is contained in:
parent
45c70cbecf
commit
86dc1e1448
4 changed files with 138 additions and 117 deletions
|
@ -1,7 +1,8 @@
|
||||||
#ifndef ROFI_MODE_PRIVATE_H
|
#ifndef ROFI_MODE_PRIVATE_H
|
||||||
#define 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.
|
* @param data Pointer to #Mode object.
|
||||||
|
@ -149,5 +150,8 @@ struct rofi_mode
|
||||||
_mode_free free;
|
_mode_free free;
|
||||||
/** Extra fields for script */
|
/** Extra fields for script */
|
||||||
void *ed;
|
void *ed;
|
||||||
|
|
||||||
|
/** Module */
|
||||||
|
GModule *module;
|
||||||
};
|
};
|
||||||
#endif // ROFI_MODE_PRIVATE_H
|
#endif // ROFI_MODE_PRIVATE_H
|
||||||
|
|
|
@ -41,6 +41,7 @@ const Mode * rofi_get_mode ( unsigned int index );
|
||||||
* Queue an error.
|
* Queue an error.
|
||||||
*/
|
*/
|
||||||
void rofi_add_error_message ( GString *str );
|
void rofi_add_error_message ( GString *str );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param code the code to return
|
* @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.
|
* This function sets the code that rofi will return on exit.
|
||||||
*/
|
*/
|
||||||
void rofi_set_return_code ( int code );
|
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 */
|
/** Reset terminal */
|
||||||
#define color_reset "\033[0m"
|
#define color_reset "\033[0m"
|
||||||
/** Set terminal text bold */
|
/** Set terminal text bold */
|
||||||
|
|
|
@ -68,48 +68,22 @@ static void combi_mode_parse_switchers ( Mode *sw )
|
||||||
pd->switchers = (CombiMode *) g_realloc ( pd->switchers,
|
pd->switchers = (CombiMode *) g_realloc ( pd->switchers,
|
||||||
sizeof ( CombiMode ) * ( pd->num_switchers + 1 ) );
|
sizeof ( CombiMode ) * ( pd->num_switchers + 1 ) );
|
||||||
|
|
||||||
// Window switcher.
|
Mode *mode = rofi_collect_modi_search ( token );
|
||||||
#ifdef WINDOW_MODE
|
if ( mode ){
|
||||||
if ( strcasecmp ( token, "window" ) == 0 ) {
|
|
||||||
pd->switchers[pd->num_switchers].disable = FALSE;
|
pd->switchers[pd->num_switchers].disable = FALSE;
|
||||||
pd->switchers[pd->num_switchers++].mode = &window_mode;
|
pd->switchers[pd->num_switchers++].mode = mode;
|
||||||
}
|
} else {
|
||||||
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 {
|
|
||||||
// If not build in, use custom switchers.
|
// If not build in, use custom switchers.
|
||||||
Mode *sw = script_switcher_parse_setup ( token );
|
Mode *sw = script_switcher_parse_setup ( token );
|
||||||
if ( sw != NULL ) {
|
if ( sw != NULL ) {
|
||||||
pd->switchers[pd->num_switchers].disable = FALSE;
|
pd->switchers[pd->num_switchers].disable = FALSE;
|
||||||
pd->switchers[pd->num_switchers++].mode = sw;
|
pd->switchers[pd->num_switchers++].mode = sw;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
// Report error, don't continue.
|
// Report error, don't continue.
|
||||||
fprintf ( stderr, "Invalid script switcher: %s\n", token );
|
fprintf ( stderr, "Invalid script switcher: %s\n", token );
|
||||||
token = NULL;
|
token = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Keybinding.
|
|
||||||
}
|
}
|
||||||
// Free string that was modified by strtok_r
|
// Free string that was modified by strtok_r
|
||||||
g_free ( switcher_str );
|
g_free ( switcher_str );
|
||||||
|
|
203
source/rofi.c
203
source/rofi.c
|
@ -81,6 +81,7 @@ const char *cache_dir = NULL;
|
||||||
/** List of error messages.*/
|
/** List of error messages.*/
|
||||||
GList *list_of_error_msgs = NULL;
|
GList *list_of_error_msgs = NULL;
|
||||||
|
|
||||||
|
static void rofi_collect_modi_destroy ( void );
|
||||||
void rofi_add_error_message ( GString *str )
|
void rofi_add_error_message ( GString *str )
|
||||||
{
|
{
|
||||||
list_of_error_msgs = g_list_append ( list_of_error_msgs, str );
|
list_of_error_msgs = g_list_append ( list_of_error_msgs, str );
|
||||||
|
@ -397,6 +398,116 @@ static void cleanup ()
|
||||||
rofi_theme = NULL;
|
rofi_theme = NULL;
|
||||||
}
|
}
|
||||||
TIMINGS_STOP ();
|
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.
|
// Resize and add entry.
|
||||||
modi = (Mode * *) g_realloc ( modi, sizeof ( Mode* ) * ( num_modi + 1 ) );
|
modi = (Mode * *) g_realloc ( modi, sizeof ( Mode* ) * ( num_modi + 1 ) );
|
||||||
|
|
||||||
// Window switcher.
|
Mode *mode = rofi_collect_modi_search ( token );
|
||||||
#ifdef WINDOW_MODE
|
if ( mode ) {
|
||||||
if ( strcasecmp ( token, "window" ) == 0 ) {
|
modi[num_modi] = mode;
|
||||||
modi[num_modi] = &window_mode;
|
|
||||||
num_modi++;
|
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;
|
|
||||||
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 {
|
} 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 {
|
|
||||||
// If not build in, use custom modi.
|
// If not build in, use custom modi.
|
||||||
Mode *sw = script_switcher_parse_setup ( token );
|
Mode *sw = script_switcher_parse_setup ( token );
|
||||||
if ( sw != NULL ) {
|
if ( sw != NULL ) {
|
||||||
modi[num_modi] = sw;
|
modi[num_modi] = sw;
|
||||||
mode_set_config ( sw );
|
mode_set_config ( sw );
|
||||||
num_modi++;
|
num_modi++;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
// Report error, don't continue.
|
// Report error, don't continue.
|
||||||
fprintf ( stderr, "Invalid script switcher: %s\n", token );
|
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
|
// Free string that was modified by strtok_r
|
||||||
g_free ( switcher_str );
|
g_free ( switcher_str );
|
||||||
// We cannot do this in main loop, as we create pointer to string,
|
rofi_collect_modi_setup ();
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -892,7 +924,10 @@ int main ( int argc, char *argv[] )
|
||||||
fprintf ( stderr, "Failed to open display: %s", display_str );
|
fprintf ( stderr, "Failed to open display: %s", display_str );
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TICK_N ( "Open Display" );
|
TICK_N ( "Open Display" );
|
||||||
|
rofi_collect_modi ();
|
||||||
|
TICK_N ( "Collect MODI" );
|
||||||
|
|
||||||
xcb->screen = xcb_aux_get_screen ( xcb->connection, xcb->screen_nbr );
|
xcb->screen = xcb_aux_get_screen ( xcb->connection, xcb->screen_nbr );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue