int dmenu_switcher_dialog ( void ) { mode_init ( &dmenu_mode ); MenuFlags menu_flags = MENU_NORMAL; DmenuModePrivateData *pd = (DmenuModePrivateData *) dmenu_mode.private_data; char *input = NULL; unsigned int cmd_list_length = pd->cmd_list_length; char **cmd_list = pd->cmd_list; pd->only_selected = FALSE; if ( find_arg ( "-markup-rows" ) >= 0 ) { pd->do_markup = TRUE; } if ( find_arg ( "-only-match" ) >= 0 || find_arg ( "-no-custom" ) >= 0 ) { pd->only_selected = TRUE; if ( cmd_list_length == 0 ) { return TRUE; } } if ( config.auto_select && cmd_list_length == 1 ) { dmenu_output_formatted_line ( pd->format, cmd_list[0], 0, config.filter ); return TRUE; } if ( find_arg ( "-password" ) >= 0 ) { menu_flags |= MENU_PASSWORD; } /* copy filter string */ input = g_strdup ( config.filter ); char *select = NULL; find_arg_str ( "-select", &select ); if ( select != NULL ) { char **tokens = tokenize ( select, config.case_sensitive ); unsigned int i = 0; for ( i = 0; i < cmd_list_length; i++ ) { if ( token_match ( tokens, cmd_list[i], !g_str_is_ascii ( cmd_list[i] ), config.case_sensitive ) ) { pd->selected_line = i; break; } } g_strfreev ( tokens ); } if ( find_arg ( "-dump" ) >= 0 ) { char **tokens = tokenize ( config.filter ? config.filter : "", config.case_sensitive ); unsigned int i = 0; for ( i = 0; i < cmd_list_length; i++ ) { if ( token_match ( tokens, cmd_list[i], !g_str_is_ascii ( cmd_list[i] ), config.case_sensitive ) ) { dmenu_output_formatted_line ( pd->format, cmd_list[i], i, config.filter ); } } g_strfreev ( tokens ); return TRUE; } // TODO remove RofiViewState *state = rofi_view_create ( &dmenu_mode, input, pd->prompt, pd->message, menu_flags, dmenu_finalize ); rofi_view_set_selected_line ( state, pd->selected_line ); rofi_view_set_active ( state ); return FALSE; }
/** * Parse an option from the commandline vector. */ static void config_parse_cmd_option ( XrmOption *option ) { // Prepend a - to the option name. char *key = g_strdup_printf ( "-%s", option->name ); switch ( option->type ) { case xrm_Number: if ( find_arg_uint ( key, option->value.num ) == TRUE ) { option->source = CONFIG_CMDLINE; } break; case xrm_SNumber: if ( find_arg_int ( key, option->value.snum ) == TRUE ) { option->source = CONFIG_CMDLINE; } break; case xrm_String: if ( find_arg_str ( key, option->value.str ) == TRUE ) { if ( option->mem != NULL ) { g_free ( option->mem ); option->mem = NULL; } option->source = CONFIG_CMDLINE; } break; case xrm_Boolean: if ( find_arg ( key ) >= 0 ) { *( option->value.num ) = TRUE; option->source = CONFIG_CMDLINE; } else { g_free ( key ); key = g_strdup_printf ( "-no-%s", option->name ); if ( find_arg ( key ) >= 0 ) { *( option->value.num ) = FALSE; option->source = CONFIG_CMDLINE; } } break; case xrm_Char: if ( find_arg_char ( key, option->value.charc ) == TRUE ) { option->source = CONFIG_CMDLINE; } break; default: break; } g_free ( key ); }
int main ( int argc, char *argv[] ) { TIMINGS_START (); cmd_set_arguments ( argc, argv ); // Version if ( find_arg ( "-v" ) >= 0 || find_arg ( "-version" ) >= 0 ) { #ifdef GIT_VERSION fprintf ( stdout, "Version: "GIT_VERSION "\n" ); #else fprintf ( stdout, "Version: "VERSION "\n" ); #endif exit ( EXIT_SUCCESS ); } // Detect if we are in dmenu mode. // This has two possible causes. // 1 the user specifies it on the command-line. if ( find_arg ( "-dmenu" ) >= 0 ) { dmenu_mode = TRUE; } // 2 the binary that executed is called dmenu (e.g. symlink to rofi) else{ // Get the base name of the executable called. char *base_name = g_path_get_basename ( argv[0] ); const char * const dmenu_str = "dmenu"; dmenu_mode = ( strcmp ( base_name, dmenu_str ) == 0 ); // Free the basename for dmenu detection. g_free ( base_name ); } TICK (); // Get the path to the cache dir. cache_dir = g_get_user_cache_dir (); // Create pid file path. const char *path = g_get_user_runtime_dir (); if ( path ) { pidfile = g_build_filename ( path, "rofi.pid", NULL ); } config_parser_add_option ( xrm_String, "pid", (void * *) &pidfile, "Pidfile location" ); if ( find_arg ( "-config" ) < 0 ) { const char *cpath = g_get_user_config_dir (); if ( cpath ) { config_path = g_build_filename ( cpath, "rofi", "config", NULL ); } } else { char *c = NULL; find_arg_str ( "-config", &c ); config_path = rofi_expand_path ( c ); } TICK (); // Register cleanup function. atexit ( cleanup ); TICK (); // Get DISPLAY, first env, then argument. char *display_str = getenv ( "DISPLAY" ); find_arg_str ( "-display", &display_str ); if ( setlocale ( LC_ALL, "" ) == NULL ) { fprintf ( stderr, "Failed to set locale.\n" ); return EXIT_FAILURE; } xcb->connection = xcb_connect ( display_str, &xcb->screen_nbr ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Failed to open display: %s", display_str ); return EXIT_FAILURE; } TICK_N ( "Open Display" ); xcb->screen = xcb_aux_get_screen ( xcb->connection, xcb->screen_nbr ); xcb_intern_atom_cookie_t *ac = xcb_ewmh_init_atoms ( xcb->connection, &xcb->ewmh ); xcb_generic_error_t *errors = NULL; xcb_ewmh_init_atoms_replies ( &xcb->ewmh, ac, &errors ); if ( errors ) { fprintf ( stderr, "Failed to create EWMH atoms\n" ); free ( errors ); } if ( xkb_x11_setup_xkb_extension ( xcb->connection, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, NULL, NULL, &xkb.first_event, NULL ) < 0 ) { fprintf ( stderr, "cannot setup XKB extension!\n" ); return EXIT_FAILURE; } xkb.context = xkb_context_new ( XKB_CONTEXT_NO_FLAGS ); if ( xkb.context == NULL ) { fprintf ( stderr, "cannot create XKB context!\n" ); return EXIT_FAILURE; } xkb.xcb_connection = xcb->connection; xkb.device_id = xkb_x11_get_core_keyboard_device_id ( xcb->connection ); enum { required_events = ( XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY ), required_nkn_details = ( XCB_XKB_NKN_DETAIL_KEYCODES ), required_map_parts = ( XCB_XKB_MAP_PART_KEY_TYPES | XCB_XKB_MAP_PART_KEY_SYMS | XCB_XKB_MAP_PART_MODIFIER_MAP | XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | XCB_XKB_MAP_PART_KEY_ACTIONS | XCB_XKB_MAP_PART_VIRTUAL_MODS | XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP ), required_state_details = ( XCB_XKB_STATE_PART_MODIFIER_BASE | XCB_XKB_STATE_PART_MODIFIER_LATCH | XCB_XKB_STATE_PART_MODIFIER_LOCK | XCB_XKB_STATE_PART_GROUP_BASE | XCB_XKB_STATE_PART_GROUP_LATCH | XCB_XKB_STATE_PART_GROUP_LOCK ), }; static const xcb_xkb_select_events_details_t details = { .affectNewKeyboard = required_nkn_details, .newKeyboardDetails = required_nkn_details, .affectState = required_state_details, .stateDetails = required_state_details, }; xcb_xkb_select_events ( xcb->connection, xkb.device_id, required_events, /* affectWhich */ 0, /* clear */ required_events, /* selectAll */ required_map_parts, /* affectMap */ required_map_parts, /* map */ &details ); xkb.keymap = xkb_x11_keymap_new_from_device ( xkb.context, xcb->connection, xkb.device_id, XKB_KEYMAP_COMPILE_NO_FLAGS ); if ( xkb.keymap == NULL ) { fprintf ( stderr, "Failed to get Keymap for current keyboard device.\n" ); return EXIT_FAILURE; } xkb.state = xkb_x11_state_new_from_device ( xkb.keymap, xcb->connection, xkb.device_id ); if ( xkb.state == NULL ) { fprintf ( stderr, "Failed to get state object for current keyboard device.\n" ); return EXIT_FAILURE; } xkb.compose.table = xkb_compose_table_new_from_locale ( xkb.context, setlocale ( LC_CTYPE, NULL ), 0 ); if ( xkb.compose.table != NULL ) { xkb.compose.state = xkb_compose_state_new ( xkb.compose.table, 0 ); } else { fprintf ( stderr, "Failed to get keyboard compose table. Trying to limp on.\n" ); } if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } x11_setup ( &xkb ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } const xcb_query_extension_reply_t *er = xcb_get_extension_data ( xcb->connection, &xcb_xinerama_id ); if ( er ) { if ( er->present ) { xcb_xinerama_is_active_cookie_t is_active_req = xcb_xinerama_is_active ( xcb->connection ); xcb_xinerama_is_active_reply_t *is_active = xcb_xinerama_is_active_reply ( xcb->connection, is_active_req, NULL ); xcb->has_xinerama = is_active->state; free ( is_active ); } } main_loop = g_main_loop_new ( NULL, FALSE ); TICK_N ( "Setup mainloop" ); // startup not. xcb->sndisplay = sn_xcb_display_new ( xcb->connection, error_trap_push, error_trap_pop ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } if ( xcb->sndisplay != NULL ) { xcb->sncontext = sn_launchee_context_new_from_environment ( xcb->sndisplay, xcb->screen_nbr ); } if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } TICK_N ( "Startup Notification" ); // Initialize Xresources subsystem. config_parse_xresource_init (); TICK_N ( "Initialize Xresources system" ); // Setup keybinding setup_abe (); TICK_N ( "Setup abe" ); if ( find_arg ( "-no-config" ) < 0 ) { load_configuration ( ); } if ( !dmenu_mode ) { // setup_modi setup_modi (); } if ( find_arg ( "-no-config" ) < 0 ) { // Reload for dynamic part. load_configuration_dynamic ( ); } // Dump. // catch help request if ( find_arg ( "-h" ) >= 0 || find_arg ( "-help" ) >= 0 || find_arg ( "--help" ) >= 0 ) { help ( argc, argv ); exit ( EXIT_SUCCESS ); } if ( find_arg ( "-dump-xresources" ) >= 0 ) { config_parse_xresource_dump (); exit ( EXIT_SUCCESS ); } if ( find_arg ( "-dump-xresources-theme" ) >= 0 ) { config_parse_xresources_theme_dump (); exit ( EXIT_SUCCESS ); } main_loop_source = g_water_xcb_source_new_for_connection ( NULL, xcb->connection, main_loop_x11_event_handler, NULL, NULL ); TICK_N ( "X11 Setup " ); rofi_view_workers_initialize (); // Setup signal handling sources. // SIGINT g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL ); g_idle_add ( startup, NULL ); // Start mainloop. g_main_loop_run ( main_loop ); return return_code; }
static gboolean startup ( G_GNUC_UNUSED gpointer data ) { TICK_N ( "Startup" ); // flags to run immediately and exit char *sname = NULL; char *msg = NULL; // // Sanity check if ( config_sanity_check ( ) ) { return G_SOURCE_REMOVE; } TICK_N ( "Config sanity check" ); // Parse the keybindings. if ( !parse_keys_abe () ) { // Error dialog return G_SOURCE_REMOVE; } TICK_N ( "Parse ABE" ); // Dmenu mode. if ( dmenu_mode == TRUE ) { // force off sidebar mode: config.sidebar_mode = FALSE; int retv = run_dmenu (); if ( retv ) { rofi_set_return_code ( EXIT_SUCCESS ); // Directly exit. g_main_loop_quit ( main_loop ); } } else if ( find_arg_str ( "-e", &( msg ) ) ) { int markup = FALSE; if ( find_arg ( "-markup" ) >= 0 ) { markup = TRUE; } if ( !show_error_message ( msg, markup ) ) { g_main_loop_quit ( main_loop ); } } else if ( find_arg_str ( "-show", &sname ) == TRUE ) { int index = switcher_get ( sname ); if ( index < 0 ) { // Add it to the list index = add_mode ( sname ); // Complain if ( index >= 0 ) { fprintf ( stdout, "Mode %s not enabled. Please add it to the list of enabled modi: %s\n", sname, config.modi ); fprintf ( stdout, "Adding mode: %s\n", sname ); } // Run it anyway if found. } if ( index >= 0 ) { run_switcher ( index ); } else { fprintf ( stderr, "The %s switcher has not been enabled\n", sname ); return G_SOURCE_REMOVE; } } else{ // Daemon mode fprintf ( stderr, "Rofi daemon mode is now removed.\n" ); fprintf ( stderr, "Please use your window manager binding functionality or xbindkeys to replace it.\n" ); g_main_loop_quit ( main_loop ); } return G_SOURCE_REMOVE; }
int dmenu_switcher_dialog ( char **input ) { char *dmenu_prompt = "dmenu "; int selected_line = -1; int retv = FALSE; int length = 0; char **list = get_dmenu ( &length ); int restart = FALSE; char *message = NULL; menu_match_cb filter = token_match; find_arg_str ( "-mesg", &message ); // By default we print the unescaped line back. char *format = "s"; // This is here for compatibility reason. // Use -format 'i' instead. if ( find_arg ( "-i" ) >= 0 ) { format = "i"; } // Allow user to override the output format. find_arg_str ( "-format", &format ); // Check prompt find_arg_str ( "-p", &dmenu_prompt ); find_arg_int ( "-l", &selected_line ); // Urgent. char *str = NULL; find_arg_str ( "-u", &str ); if ( str != NULL ) { parse_ranges ( str, &urgent_list, &num_urgent_list ); } // Active str = NULL; find_arg_str ( "-a", &str ); if ( str != NULL ) { parse_ranges ( str, &active_list, &num_active_list ); } int only_selected = FALSE; if ( find_arg ( "-only-match" ) >= 0 || find_arg ( "-no-custom" ) >= 0 ) { only_selected = TRUE; if ( length == 0 ) { return TRUE; } } find_arg_str_alloc ( "-filter", input ); if ( find_arg ( "-z" ) >= 0 ) { filter = fuzzy_token_match; } char *select = NULL; find_arg_str ( "-select", &select ); if ( select != NULL ) { char **tokens = tokenize ( select, config.case_sensitive ); int i = 0; for ( i = 0; i < length; i++ ) { if ( token_match ( tokens, list[i], config.case_sensitive, 0, NULL ) ) { selected_line = i; break; } } g_strfreev ( tokens ); } do { int next_pos = selected_line; int mretv = menu ( list, length, input, dmenu_prompt, filter, NULL, &selected_line, config.levenshtein_sort, get_display_data, list, &next_pos, message ); // Special behavior. if ( only_selected ) { /** * Select item mode. */ restart = ( find_arg ( "-only-match" ) >= 0 ); if ( ( mretv & ( MENU_OK | MENU_QUICK_SWITCH ) ) && list[selected_line] != NULL ) { dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input ); retv = TRUE; if ( ( mretv & MENU_QUICK_SWITCH ) ) { retv = 10 + ( mretv & MENU_LOWER_MASK ); } return retv; } selected_line = next_pos - 1; continue; } // We normally do not want to restart the loop. restart = FALSE; // Normal mode if ( ( mretv & MENU_OK ) && list[selected_line] != NULL ) { dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input ); if ( ( mretv & MENU_SHIFT ) ) { restart = TRUE; // Move to next line. selected_line = MIN ( next_pos, length - 1 ); } retv = TRUE; } // Custom input else if ( ( mretv & ( MENU_CUSTOM_INPUT ) ) ) { dmenu_output_formatted_line ( format, *input, -1, *input ); if ( ( mretv & MENU_SHIFT ) ) { restart = TRUE; // Move to next line. selected_line = MIN ( next_pos, length - 1 ); } retv = TRUE; } // Quick switch with entry selected. else if ( ( mretv & MENU_QUICK_SWITCH ) && selected_line >= 0 ) { dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input ); restart = FALSE; retv = 10 + ( mretv & MENU_LOWER_MASK ); } // Quick switch without entry selected. else if ( ( mretv & MENU_QUICK_SWITCH ) && selected_line == -1 ) { dmenu_output_formatted_line ( format, *input, -1, *input ); restart = FALSE; retv = 10 + ( mretv & MENU_LOWER_MASK ); } } while ( restart ); g_strfreev ( list ); g_free ( urgent_list ); g_free ( active_list ); return retv; }
static int dmenu_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) != NULL ) { return TRUE; } mode_set_private_data ( sw, g_malloc0 ( sizeof ( DmenuModePrivateData ) ) ); DmenuModePrivateData *pd = (DmenuModePrivateData *) mode_get_private_data ( sw ); pd->prompt = "dmenu "; pd->separator = '\n'; pd->selected_line = UINT32_MAX; find_arg_str ( "-mesg", &( pd->message ) ); // Input data separator. find_arg_char ( "-sep", &( pd->separator ) ); // Check prompt find_arg_str ( "-p", &( pd->prompt ) ); find_arg_uint ( "-selected-row", &( pd->selected_line ) ); // By default we print the unescaped line back. pd->format = "s"; // Allow user to override the output format. find_arg_str ( "-format", &( pd->format ) ); // Urgent. char *str = NULL; find_arg_str ( "-u", &str ); if ( str != NULL ) { parse_ranges ( str, &( pd->urgent_list ), &( pd->num_urgent_list ) ); } // Active str = NULL; find_arg_str ( "-a", &str ); if ( str != NULL ) { parse_ranges ( str, &( pd->active_list ), &( pd->num_active_list ) ); } // DMENU COMPATIBILITY find_arg_uint ( "-l", &( config.menu_lines ) ); /** * Dmenu compatibility. * `-b` put on bottom. */ if ( find_arg ( "-b" ) >= 0 ) { config.location = 6; } /* -i case insensitive */ config.case_sensitive = TRUE; if ( find_arg ( "-i" ) >= 0 ) { config.case_sensitive = FALSE; } FILE *fd = NULL; str = NULL; if ( find_arg_str ( "-input", &str ) ) { char *estr = rofi_expand_path ( str ); fd = fopen ( str, "r" ); if ( fd == NULL ) { char *msg = g_markup_printf_escaped ( "Failed to open file: <b>%s</b>:\n\t<i>%s</i>", estr, strerror ( errno ) ); rofi_view_error_dialog ( msg, TRUE ); g_free ( msg ); g_free ( estr ); return TRUE; } g_free ( estr ); } pd->cmd_list = get_dmenu ( pd, fd == NULL ? stdin : fd, &( pd->cmd_list_length ) ); if ( fd != NULL ) { fclose ( fd ); } return TRUE; }
int main ( int argc, char **argv ) { g_type_init(); Display *display; // catch help request if ( find_arg( argc, argv, "-help" ) >= 0 || find_arg( argc, argv, "--help" ) >= 0 || find_arg( argc, argv, "-h" ) >= 0 ) { help(); return EXIT_SUCCESS; } // Get DISPLAY const char *display_str= getenv( "DISPLAY" ); if ( !( display = XOpenDisplay( display_str ) ) ) { fprintf( stderr, "cannot open display!\n" ); return EXIT_FAILURE; } // Setup error handler. XSync( display, False ); xerror = XSetErrorHandler( X11_oops ); XSync( display, False ); // Initialize renderer renderer_init( display ); // Get monitor layout. (xinerama aware) MMB_Screen *mmb_screen = mmb_screen_create( display ); // Check input file. char *image_file = NULL; find_arg_str( argc, argv, "-input", &image_file ); if ( image_file ) { int clip = ( find_arg( argc, argv, "-clip" ) >= 0 ); GdkPixbuf *pb = renderer_create_empty_background( mmb_screen ); if ( renderer_overlay_wallpaper( pb, image_file, mmb_screen,clip ) ) { char *output_file = NULL; find_arg_str( argc, argv, "-output", &output_file ); if ( output_file ) { renderer_store_image( pb, output_file ); } else { renderer_update_X11_background( display, pb ); } } g_object_unref( pb ); } // Print layout if ( find_arg( argc, argv, "-print" ) >= 0 ) { mmb_screen_print( mmb_screen ); } // Cleanup mmb_screen_free( &mmb_screen ); XCloseDisplay( display ); }