static int combi_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { CombiModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); mode_set_private_data ( sw, (void *) pd ); combi_mode_parse_switchers ( sw ); pd->starts = g_malloc0 ( sizeof ( int ) * pd->num_switchers ); pd->lengths = g_malloc0 ( sizeof ( int ) * pd->num_switchers ); for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { if ( !mode_init ( pd->switchers[i] ) ) { return FALSE; } } if ( pd->cmd_list_length == 0 ) { pd->cmd_list_length = 0; for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { unsigned int length = mode_get_num_entries ( pd->switchers[i] ); pd->starts[i] = pd->cmd_list_length; pd->lengths[i] = length; pd->cmd_list_length += length; } } } return TRUE; }
/** * @param sw Object handle to the SSH Mode object * @param mretv The menu return value. * @param input Pointer to the user input string. * @param selected_line the line selected by the user. * * Acts on the user interaction. * * @returns the next #ModeMode. */ static ModeMode ssh_mode_result ( Mode *sw, int mretv, char **input, unsigned int selected_line ) { ModeMode retv = MODE_EXIT; SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw ); if ( mretv & MENU_NEXT ) { retv = NEXT_DIALOG; } else if ( mretv & MENU_PREVIOUS ) { retv = PREVIOUS_DIALOG; } else if ( mretv & MENU_QUICK_SWITCH ) { retv = ( mretv & MENU_LOWER_MASK ); } else if ( ( mretv & MENU_OK ) && rmpd->hosts_list[selected_line] != NULL ) { exec_ssh ( rmpd->hosts_list[selected_line] ); } else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) { exec_ssh ( *input ); } else if ( ( mretv & MENU_ENTRY_DELETE ) && rmpd->hosts_list[selected_line] ) { delete_ssh ( rmpd->hosts_list[selected_line] ); g_strfreev ( rmpd->hosts_list ); rmpd->hosts_list_length = 0; rmpd->hosts_list = NULL; // Stay retv = RELOAD_DIALOG; } return retv; }
static ModeMode drun_mode_result ( Mode *sw, int mretv, char **input, unsigned int selected_line ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( sw ); ModeMode retv = MODE_EXIT; gboolean run_in_term = ( ( mretv & MENU_CUSTOM_ACTION ) == MENU_CUSTOM_ACTION ); if ( mretv & MENU_NEXT ) { retv = NEXT_DIALOG; } else if ( mretv & MENU_PREVIOUS ) { retv = PREVIOUS_DIALOG; } else if ( mretv & MENU_QUICK_SWITCH ) { retv = ( mretv & MENU_LOWER_MASK ); } else if ( ( mretv & MENU_OK ) ) { exec_cmd_entry ( &( rmpd->entry_list[selected_line] ) ); } else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) { helper_execute_command ( NULL, *input, run_in_term ); } else if ( ( mretv & MENU_ENTRY_DELETE ) && selected_line < rmpd->cmd_list_length ) { if ( selected_line < rmpd->history_length ) { delete_entry_history ( &( rmpd->entry_list[selected_line] ) ); drun_entry_clear ( &( rmpd->entry_list[selected_line] ) ); memmove ( &( rmpd->entry_list[selected_line] ), &rmpd->entry_list[selected_line + 1], sizeof ( DRunModeEntry ) * ( rmpd->cmd_list_length - selected_line - 1 ) ); rmpd->cmd_list_length--; } retv = RELOAD_DIALOG; } return retv; }
static ModeMode combi_mode_result ( Mode *sw, int mretv, char **input, unsigned int selected_line ) { CombiModePrivateData *pd = mode_get_private_data ( sw ); if ( *input[0] == '!' ) { int switcher = -1; for ( unsigned i = 0; switcher == -1 && i < pd->num_switchers; i++ ) { if ( ( *input )[1] == mode_get_name ( pd->switchers[i] )[0] ) { switcher = i; } } if ( switcher >= 0 ) { char *n = strchr ( *input, ' ' ); // skip whitespace if ( n != NULL ) { n++; return mode_result ( pd->switchers[switcher], mretv, &n, selected_line - pd->starts[switcher] ); } return MODE_EXIT; } } for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) { return mode_result ( pd->switchers[i], mretv, input, selected_line - pd->starts[i] ); } } return MODE_EXIT; }
static int combi_mode_match ( const Mode *sw, char **tokens, int not_ascii, int case_sensitive, unsigned int index ) { CombiModePrivateData *pd = mode_get_private_data ( sw ); if ( config.regex || config.glob ) { // Bang support only works in text mode. for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) { return mode_token_match ( pd->switchers[i], tokens, not_ascii, case_sensitive, index - pd->starts[i] ); } } } else { for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) { if ( tokens && tokens[0][0] == '!' ) { if ( tokens[0][1] == mode_get_name ( pd->switchers[i] )[0] ) { return mode_token_match ( pd->switchers[i], &tokens[1], not_ascii, case_sensitive, index - pd->starts[i] ); } return 0; } else { return mode_token_match ( pd->switchers[i], tokens, not_ascii, case_sensitive, index - pd->starts[i] ); } } } } abort (); return 0; }
static int drun_token_match ( const Mode *data, char **tokens, int not_ascii, int case_sensitive, unsigned int index ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( data ); int match = 1; if ( tokens ) { for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) { int test = 0; char *ftokens[2] = { tokens[j], NULL }; if ( !test && rmpd->entry_list[index].name && token_match ( ftokens, rmpd->entry_list[index].name, not_ascii, case_sensitive ) ) { test = 1; } if ( !test && rmpd->entry_list[index].generic_name && token_match ( ftokens, rmpd->entry_list[index].generic_name, not_ascii, case_sensitive ) ) { test = 1; } if ( !test && token_match ( ftokens, rmpd->entry_list[index].exec, not_ascii, case_sensitive ) ) { test = 1; } if ( test == 0 ) { match = 0; } } } return match; }
static char *get_display_data ( const Mode *data, unsigned int index, int *state, int get_entry ) { Mode *sw = (Mode *) data; DmenuModePrivateData *pd = (DmenuModePrivateData *) mode_get_private_data ( sw ); char **retv = (char * *) pd->cmd_list; for ( unsigned int i = 0; i < pd->num_active_list; i++ ) { if ( index >= pd->active_list[i].start && index <= pd->active_list[i].stop ) { *state |= ACTIVE; } } for ( unsigned int i = 0; i < pd->num_urgent_list; i++ ) { if ( index >= pd->urgent_list[i].start && index <= pd->urgent_list[i].stop ) { *state |= URGENT; } } for ( unsigned int i = 0; i < pd->num_selected_list; i++ ) { if ( index >= pd->selected_list[i].start && index <= pd->selected_list[i].stop ) { *state |= SELECTED; } } if ( pd->do_markup ) { *state |= MARKUP; } return get_entry ? g_strdup ( retv[index] ) : NULL; }
static int drun_is_not_ascii ( const Mode *sw, unsigned int index ) { DRunModePrivateData *pd = (DRunModePrivateData *) mode_get_private_data ( sw ); if ( pd->entry_list[index].generic_name ) { return !g_str_is_ascii ( pd->entry_list[index].name ) || !g_str_is_ascii ( pd->entry_list[index].generic_name ); } return !g_str_is_ascii ( pd->entry_list[index].name ); }
/** * @param sw Object handle to the SSH Mode object * * Cleanup the SSH Mode. Free all allocated memory and NULL the private data pointer. */ static void ssh_mode_destroy ( Mode *sw ) { SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw ); if ( rmpd != NULL ) { g_strfreev ( rmpd->hosts_list ); g_free ( rmpd ); mode_set_private_data ( sw, NULL ); } }
static int drun_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); mode_set_private_data ( sw, (void *) pd ); get_apps ( pd ); } return TRUE; }
/** * @param sw Object handle to the SSH Mode object * * Initializes the SSH Mode private data object and * loads the relevant ssh information. */ static int ssh_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { SSHModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); mode_set_private_data ( sw, (void *) pd ); pd->hosts_list = get_ssh ( &( pd->hosts_list_length ) ); } return TRUE; }
static int drun_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); pd->disabled_entries = g_hash_table_new_full ( g_str_hash, g_str_equal, g_free, NULL ); mode_set_private_data ( sw, (void *) pd ); get_apps ( pd ); } return TRUE; }
static int combi_is_not_ascii ( const Mode *sw, unsigned int index ) { CombiModePrivateData *pd = mode_get_private_data ( sw ); for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) { return mode_is_not_ascii ( pd->switchers[i], index - pd->starts[i] ); } } return FALSE; }
static void drun_mode_destroy ( Mode *sw ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( sw ); if ( rmpd != NULL ) { for ( size_t i = 0; i < rmpd->cmd_list_length; i++ ) { drun_entry_clear ( &( rmpd->entry_list[i] ) ); } g_free ( rmpd->entry_list ); g_free ( rmpd ); mode_set_private_data ( sw, NULL ); } }
static char * combi_get_completion ( const Mode *sw, unsigned int index ) { CombiModePrivateData *pd = mode_get_private_data ( sw ); for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) { return mode_get_completion ( pd->switchers[i], index - pd->starts[i] ); } } // Should never get here. g_error ( "Failure, could not resolve sub-switcher." ); return NULL; }
static void dmenu_mode_free ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { return; } DmenuModePrivateData *pd = (DmenuModePrivateData *) mode_get_private_data ( sw ); if ( pd != NULL ) { for ( size_t i = 0; i < pd->cmd_list_length; i++ ) { if ( pd->cmd_list[i] ) { free ( pd->cmd_list[i] ); } } g_free ( pd->cmd_list ); g_free ( pd->urgent_list ); g_free ( pd->active_list ); g_free ( pd->selected_list ); g_free ( pd ); mode_set_private_data ( sw, NULL ); } }
static char *drun_get_completion ( const Mode *sw, unsigned int index ) { DRunModePrivateData *pd = (DRunModePrivateData *) mode_get_private_data ( sw ); /* Free temp storage. */ DRunModeEntry *dr = &( pd->entry_list[index] ); if ( dr->generic_name == NULL ) { return g_strdup ( dr->name ); } else { return g_strdup_printf ( "%s", dr->name ); } }
static void combi_mode_parse_switchers ( Mode *sw ) { CombiModePrivateData *pd = mode_get_private_data ( sw ); char *savept = NULL; // Make a copy, as strtok will modify it. char *switcher_str = g_strdup ( config.combi_modi ); const char * const sep = ","; // Split token on ','. This modifies switcher_str. for ( char *token = strtok_r ( switcher_str, sep, &savept ); token != NULL; token = strtok_r ( NULL, sep, &savept ) ) { // Resize and add entry. pd->switchers = (Mode * *) g_realloc ( pd->switchers, sizeof ( Mode* ) * ( pd->num_switchers + 1 ) ); // Window switcher. #ifdef WINDOW_MODE if ( strcasecmp ( token, "window" ) == 0 ) { pd->switchers[pd->num_switchers++] = &window_mode; } else if ( strcasecmp ( token, "windowcd" ) == 0 ) { pd->switchers[pd->num_switchers++] = &window_mode_cd; } else #endif // WINDOW_MODE // SSh dialog if ( strcasecmp ( token, "ssh" ) == 0 ) { pd->switchers[pd->num_switchers++] = &ssh_mode; } // Run dialog else if ( strcasecmp ( token, "run" ) == 0 ) { pd->switchers[pd->num_switchers++] = &run_mode; } else if ( strcasecmp ( token, "drun" ) == 0 ) { pd->switchers[pd->num_switchers++] = &drun_mode; } else { // If not build in, use custom switchers. Mode *sw = script_switcher_parse_setup ( token ); if ( sw != NULL ) { pd->switchers[pd->num_switchers++] = sw; } 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 ); }
static void combi_mode_destroy ( Mode *sw ) { CombiModePrivateData *pd = (CombiModePrivateData *) mode_get_private_data ( sw ); if ( pd != NULL ) { g_free ( pd->starts ); g_free ( pd->lengths ); // Cleanup switchers. for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { mode_destroy ( pd->switchers[i] ); } g_free ( pd->switchers ); g_free ( pd ); mode_set_private_data ( sw, NULL ); } }
static int drun_token_match ( const Mode *data, GRegex **tokens, unsigned int index ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( data ); int match = 1; if ( tokens ) { for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) { int test = 0; GRegex *ftokens[2] = { tokens[j], NULL }; // Match name if ( rmpd->entry_list[index].name && helper_token_match ( ftokens, rmpd->entry_list[index].name ) ) { test = 1; } // Match generic name if ( !test && rmpd->entry_list[index].generic_name && helper_token_match ( ftokens, rmpd->entry_list[index].generic_name ) ) { test = 1; } // Match executable name. if ( !test && helper_token_match ( ftokens, rmpd->entry_list[index].exec ) ) { test = 1; } // Match against category. if ( !test ) { #ifdef GET_CAT_PARSE_TIME gchar **list = rmpd->entry_list[index].categories; for ( int iter = 0; !test && list && list[iter]; iter++ ) { test = helper_token_match ( ftokens, list[iter] ); } #else gchar **list = g_key_file_get_locale_string_list ( rmpd->entry_list[index].key_file, "Desktop Entry", "Categories", NULL, NULL, NULL ); for ( int iter = 0; !test && list && list[iter]; iter++ ) { test = helper_token_match ( ftokens, list[iter] ); } g_strfreev ( list ); #endif } if ( test == 0 ) { match = 0; } } } return match; }
static char *_get_display_value ( const Mode *sw, unsigned int selected_line, int *state, G_GNUC_UNUSED GList **list, int get_entry ) { DRunModePrivateData *pd = (DRunModePrivateData *) mode_get_private_data ( sw ); *state |= MARKUP; if ( !get_entry ) { return NULL; } if ( pd->entry_list == NULL ) { // Should never get here. return g_strdup ( "Failed" ); } /* Free temp storage. */ DRunModeEntry *dr = &( pd->entry_list[selected_line] ); if ( dr->generic_name == NULL ) { return g_markup_escape_text ( dr->name, -1 ); } else { return g_markup_printf_escaped ( "%s <span weight='light' size='small'><i>(%s)</i></span>", dr->name, dr->generic_name ); } }
static int drun_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { static const gchar * const drun_icon_fallback_themes[] = { "Adwaita", "gnome", NULL }; const gchar *themes[2] = { config.drun_icon_theme, NULL }; DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); pd->disabled_entries = g_hash_table_new_full ( g_str_hash, g_str_equal, g_free, NULL ); mode_set_private_data ( sw, (void *) pd ); pd->xdg_context = nk_xdg_theme_context_new ( drun_icon_fallback_themes, NULL ); nk_xdg_theme_preload_themes_icon ( pd->xdg_context, themes ); get_apps ( pd ); } return TRUE; }
static char * combi_mgrv ( const Mode *sw, unsigned int selected_line, int *state, int get_entry ) { CombiModePrivateData *pd = mode_get_private_data ( sw ); if ( !get_entry ) { for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) { mode_get_display_value ( pd->switchers[i], selected_line - pd->starts[i], state, FALSE ); return NULL; } } return NULL; } for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) { char * str = mode_get_display_value ( pd->switchers[i], selected_line - pd->starts[i], state, TRUE ); char * retv = g_strdup_printf ( "%s %s", mode_get_display_name ( pd->switchers[i] ), str ); g_free ( str ); return retv; } } return NULL; }
static ModeMode drun_mode_result ( Mode *sw, int mretv, char **input, unsigned int selected_line ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( sw ); ModeMode retv = MODE_EXIT; gboolean run_in_term = ( ( mretv & MENU_CUSTOM_ACTION ) == MENU_CUSTOM_ACTION ); if ( mretv & MENU_NEXT ) { retv = NEXT_DIALOG; } else if ( mretv & MENU_PREVIOUS ) { retv = PREVIOUS_DIALOG; } else if ( mretv & MENU_QUICK_SWITCH ) { retv = ( mretv & MENU_LOWER_MASK ); } else if ( ( mretv & MENU_OK ) ) { exec_cmd_entry ( &( rmpd->entry_list[selected_line] ) ); } else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) { RofiHelperExecuteContext context = { .name = NULL }; // FIXME: We assume startup notification in terminals, not in others helper_execute_command ( NULL, *input, run_in_term, run_in_term ? &context : NULL ); }
/** * @param sw Object handle to the SSH Mode object * * Get the number of SSH entries. * * @returns the number of ssh entries. */ static unsigned int ssh_mode_get_num_entries ( const Mode *sw ) { const SSHModePrivateData *rmpd = (const SSHModePrivateData *) mode_get_private_data ( sw ); return rmpd->hosts_list_length; }
static unsigned int combi_mode_get_num_entries ( const Mode *sw ) { const CombiModePrivateData *pd = (const CombiModePrivateData *) mode_get_private_data ( sw ); return pd->cmd_list_length; }
static int dmenu_is_not_ascii ( const Mode *sw, unsigned int index ) { DmenuModePrivateData *rmpd = (DmenuModePrivateData *) mode_get_private_data ( sw ); return !g_str_is_ascii ( rmpd->cmd_list[index] ); }
/** * @param sw Object handle to the SSH Mode object * @param index The index of the entry to match * * Check if the selected entry contains non-ascii symbols. * * @returns TRUE if string contains non-ascii symbols */ static int ssh_is_not_ascii ( const Mode *sw, unsigned int index ) { SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw ); return !g_str_is_ascii ( rmpd->hosts_list[index] ); }
/** * @param sw Object handle to the SSH Mode object * @param tokens The set of tokens to match against * @param not_ascii If the entry is pure-ascii * @param case_sensitive If the entry should be matched case sensitive * @param index The index of the entry to match * * Match entry against the set of tokens. * * @returns TRUE if matches */ static int ssh_token_match ( const Mode *sw, char **tokens, int not_ascii, int case_sensitive, unsigned int index ) { SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw ); return token_match ( tokens, rmpd->hosts_list[index], not_ascii, case_sensitive ); }
/** * @param sw Object handle to the SSH Mode object * @param selected_line The line to view * @param state The state of the entry [out] * @param get_entry * * Gets the string as it should be displayed and the display state. * If get_entry is FALSE only the state is set. * * @return the string as it should be displayed and the display state. */ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_GNUC_UNUSED int *state, int get_entry ) { SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw ); return get_entry ? g_strdup ( rmpd->hosts_list[selected_line] ) : NULL; }