main.c

来自「这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统」· C语言 代码 · 共 2,658 行 · 第 1/5 页

C
2,658
字号
	tmp = name_quote (selection (cpanel)->fname, 1);
    stuff (input_w (cmdline), tmp, 1);
    free (tmp);
}

static void copy_tagged (WPanel *panel)
{
    int i;

    if (!command_prompt)
	return;
    input_disable_update (input_w (cmdline));
    if (panel->marked){
	for (i = 0; i < panel->count; i++)
	    if (panel->dir.list [i].f.marked) {
	    	char *tmp = name_quote (panel->dir.list [i].fname, 1);
		stuff (input_w (cmdline), tmp, 1);
		free (tmp);
	    }
    } else {
    	char *tmp = name_quote (panel->dir.list [panel->selected].fname, 1);
	stuff (input_w (cmdline), tmp, 1);
	free (tmp);
    }
    input_enable_update (input_w (cmdline));
}

static void copy_current_tagged (void)
{
    copy_tagged (cpanel);
}

static void copy_other_tagged (void)
{
    if (get_other_type () != view_listing)
	return;
    copy_tagged (opanel);
}

static void do_suspend_cmd (void)
{
    pre_exec ();

    if (console_flag && !use_subshell)
	restore_console ();

#ifndef OS2_NT
    {
	struct sigaction sigtstp_action;

	/* Make sure that the SIGTSTP below will suspend us directly,
	   without calling ncurses' SIGTSTP handler; we *don't* want
	   ncurses to redraw the screen immediately after the SIGCONT */
	sigaction (SIGTSTP, &startup_handler, &sigtstp_action);

	kill (getpid (), SIGTSTP);

	/* Restore previous SIGTSTP action */
	sigaction (SIGTSTP, &sigtstp_action, NULL);
    }
#endif

    if (console_flag && !use_subshell)
	handle_console (CONSOLE_SAVE);

    edition_post_exec ();
}

void suspend_cmd (void)
{
    save_cwds_stat ();
    do_suspend_cmd ();
    update_panels (UP_OPTIMIZE, UP_KEEPSEL);
    do_refresh ();
}

void init_labels (Widget *paneletc)
{
    define_label (midnight_dlg, paneletc, 1, _("Help"), help_cmd);
    define_label (midnight_dlg, paneletc, 2, _("Menu"), user_menu_cmd);
    define_label (midnight_dlg, paneletc, 9, _("PullDn"), menu_cmd);
    define_label (midnight_dlg, paneletc, 10, _("Quit"), (voidfn) quit_cmd);
}

#ifndef HAVE_XVIEW
static key_map ctl_x_map [] = {
    { XCTRL('c'),   (callfn) quit_cmd },
#ifdef USE_VFS
    { 'a',          reselect_vfs },
#endif
    { 'd',          compare_dirs_cmd },
#ifndef HAVE_GNOME
    { 'p',          copy_current_pathname },
    { XCTRL('p'),   copy_other_pathname },
    { 't',          copy_current_tagged },
    { XCTRL('t'),   copy_other_tagged },
#endif
    { 'c',          chmod_cmd },
#ifndef OS2_NT
    { 'o',          chown_cmd },
    { 'l',          link_cmd },
    { XCTRL('l'),   other_symlink_cmd },
    { 's',          symlink_cmd },
    { XCTRL('s'),   edit_symlink_cmd },
    { 'r',          copy_current_readlink },
    { XCTRL('r'),   copy_other_readlink },
#endif
#ifndef HAVE_GNOME
    { 'i',          info_cmd_no_menu },
    { 'q',          quick_cmd_no_menu },
#endif
    { 'h',          add2hotlist_cmd },
    { '!',          external_panelize },
#ifdef WITH_BACKGROUND
    { 'j',          jobs_cmd },
#endif
#ifdef HAVE_SETSOCKOPT
    { '%',          source_routing },
#endif
    { 0,  0 }
};

static int ctl_x_map_enabled = 0;

static void ctl_x_cmd (int ignore)
{
	ctl_x_map_enabled = 1;
}

static void nothing ()
{
}

static key_map default_map [] = {
#ifndef HAVE_GNOME
    { KEY_F(19),  menu_last_selected_cmd },
    { KEY_F(20),  (key_callback) quiet_quit_cmd },

    /* Copy useful information to the command line */
    { ALT('\n'),  copy_prog_name },
    { ALT('\r'),  copy_prog_name },
    { ALT('a'),   copy_current_pathname },
    { ALT('A'),   copy_other_pathname },

    { ALT('c'),	  quick_cd_cmd },

    /* To access the directory hotlist */
    { XCTRL('\\'), quick_chdir_cmd },

    /* Suspend */
    { XCTRL('z'), suspend_cmd },
#endif
    /* The filtered view command */
    { ALT('!'),   filtered_view_cmd_cpanel },

    /* Find file */
    { ALT('?'),	  find_cmd },

    /* Panel refresh */
    { XCTRL('r'), reread_cmd },

    { ALT('t'),   toggle_listing_cmd },

#ifndef HAVE_X
    /* Swap panels */
    { XCTRL('u'), swap_cmd },

    /* View output */
    { XCTRL('o'), view_other_cmd },
#endif

    /* Control-X keybindings */
    { XCTRL('x'), ctl_x_cmd },

    /* Trap dlg's exit commands */
    { ESC_CHAR,   nothing },
    { XCTRL('c'), nothing },
    { XCTRL('g'), nothing },
    { 0, 0 },
};
#endif

#ifndef HAVE_X
static void setup_sigwinch ()
{
#ifndef OS2_NT
    struct sigaction act, oact;

#   if defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4
#       ifdef SIGWINCH
            act.sa_handler = flag_winch;
            sigemptyset (&act.sa_mask);
	    act.sa_flags = 0;
#           ifdef SA_RESTART
                act.sa_flags |= SA_RESTART;
#           endif
            sigaction (SIGWINCH, &act, &oact);
#       endif
#   endif
#endif
}

static void
setup_pre ()
{
    /* Call all the inits */
#ifndef HAVE_SLANG
    meta (stdscr, eight_bit_clean);
#else
    SLsmg_Display_Eight_Bit = full_eight_bits ? 128 : 160;
#endif
}
#else
#define setup_pre()
#define setup_sigwinch()
#endif

static void
setup_post ()
{
    setup_sigwinch ();

    init_uid_gid_cache ();

#ifndef HAVE_X
    if (baudrate () < 9600 || slow_terminal){
	verbose = 0;
    }
    if (use_mouse_p)
	init_mouse ();
#endif

    midnight_colors [0] = 0;
    midnight_colors [1] = REVERSE_COLOR;     /* FOCUSC */
    midnight_colors [2] = INPUT_COLOR;       /* HOT_NORMALC */
    midnight_colors [3] = NORMAL_COLOR;	     /* HOT_FOCUSC */
}

static void setup_mc (void)
{
    setup_pre ();
    init_menu ();
    create_panels ();

#ifdef HAVE_GNOME
    return;
#endif
    setup_panels ();

#ifdef HAVE_SUBSHELL_SUPPORT
    if (use_subshell)
	add_select_channel (subshell_pty, load_prompt, 0);
#endif

    setup_post ();
}

static void setup_dummy_mc (const char *file)
{
    char d[MC_MAXPATHLEN];

    mc_get_current_wd (d, MC_MAXPATHLEN);
    setup_mc ();
    mc_chdir (d);

    /* Create a fake current_panel, this is needed because the
     * expand_format routine will use current panel.
     */
    strcpy (cpanel->cwd, d);
    cpanel->selected = 0;
    cpanel->count = 1;
    cpanel->dir.list[0].fname = (char *) file;
}

static void done_mc ()
{
    done_menu ();

    /* Setup shutdown
     *
     * We sync the profiles since the hotlist may have changed, while
     * we only change the setup data if we have the auto save feature set
     */
    if (auto_save_setup)
	save_setup ();   /* does also call save_hotlist */
    else
	save_hotlist();
    done_screen ();
    vfs_add_current_stamps ();
    if (xterm_flag && xterm_hintbar)
        set_hintbar(_("Thank you for using GNU Midnight Commander"));
}

/* This should be called after destroy_dlg since panel widgets
 *  save their state on the profiles
 */
static void done_mc_profile ()
{
    if (!auto_save_setup)
	profile_forget_profile (profile_name);
    sync_profiles ();
    done_setup ();
    free_profiles ();
}

/* This routine only handles cpanel, and opanel, it is easy to
 * change to use npanels, just loop over the number of panels
 * and use get_panel_widget (i) and make the test done below
 */
void make_panels_dirty ()
{
    if (cpanel->dirty)
	panel_update_contents (cpanel);

    if ((get_other_type () == view_listing) && opanel->dirty)
	panel_update_contents (opanel);
}

/* In OS/2 and Windows NT people want to actually type the '\' key frequently */
#ifdef OS2_NT
#   define check_key_backslash(x) 0
#else
#   define check_key_backslash(x) ((x) == '\\')
#endif

int midnight_callback (struct Dlg_head *h, int id, int msg)
{
    int i;

    switch (msg){
#ifndef HAVE_XVIEW

	/* Speed up routine: now, we just set the  */
    case DLG_PRE_EVENT:
	make_panels_dirty ();
	return MSG_HANDLED;

    case DLG_KEY:
	if (ctl_x_map_enabled){
		ctl_x_map_enabled = 0;
		for (i = 0; ctl_x_map [i].key_code; i++)
			if (id == ctl_x_map [i].key_code){
				(*ctl_x_map [i].fn)(id);
				return MSG_HANDLED;
			}
	}

	if (id == KEY_F(10) && !the_menubar->active){
	    quit_cmd ();
	    return MSG_HANDLED;
	}

	if (id == '\t')
	    free_completions (input_w (cmdline));

	/* On Linux, we can tell the difference */
	if (id == '\n' && ctrl_pressed ()){
	    copy_prog_name ();
	    return MSG_HANDLED;
	}

	if (id == '\n' && input_w (cmdline)->buffer [0]){
	    send_message_to (h, (Widget *) cmdline, WIDGET_KEY, id);
	    return MSG_HANDLED;
	}

	if ((!alternate_plus_minus || !(console_flag || xterm_flag)) &&
             !quote && !cpanel->searching) {
	    if(!only_leading_plus_minus) {
		/* Special treatement, since the input line will eat them */
		if (id == '+' ) {
		    select_cmd ();
		    return MSG_HANDLED;
		}

		if (check_key_backslash (id) || id == '-'){
		    unselect_cmd ();
		    return MSG_HANDLED;
		}

		if (id == '*') {
		    reverse_selection_cmd ();
		    return MSG_HANDLED;
		}
	    } else if (command_prompt && !strlen (input_w (cmdline)->buffer)) {
		/* Special treatement '+', '-', '\', '*' only when this is
		 * first char on input line
		 */

		if (id == '+') {
		    select_cmd ();
		    return MSG_HANDLED;
		}

		if (check_key_backslash (id) || id == '-') {
		    unselect_cmd ();
		    return MSG_HANDLED;
		}

		if (id == '*') {
		    reverse_selection_cmd ();
		    return MSG_HANDLED;
		}
	    }
	}
	break;

    case DLG_HOTKEY_HANDLED:
	if (get_current_type () == view_listing)
	    cpanel->searching = 0;
	break;

    case DLG_UNHANDLED_KEY:
	if (command_prompt){
	    int v;

	    v = send_message_to (h, (Widget *) cmdline, WIDGET_KEY, id);
	    if (v)
		return v;
	}
	if (ctl_x_map_enabled){
		ctl_x_map_enabled = 0;
		for (i = 0; ctl_x_map [i].key_code; i++)
			if (id == ctl_x_map [i].key_code){
				(*ctl_x_map [i].fn)(id);
				return MSG_HANDLED;
			}
	} else {
		for (i = 0; default_map [i].key_code; i++){
			if (id == default_map [i].key_code){
				(*default_map [i].fn)(id);
				return MSG_HANDLED;
			}
		}
	}
	return MSG_NOT_HANDLED;

#endif
#ifndef HAVE_X
	/* We handle the special case of the output lines */
    case DLG_DRAW:
	attrset (SELECTED_COLOR);
	if (console_flag && output_lines)
	    show_console_contents (output_start_y,
				   LINES-output_lines-keybar_visible-1,
				   LINES-keybar_visible-1);
	break;
#endif

    }
    return default_dlg_callback (h, id, msg);
}

#ifdef HAVE_X
/* This should be rewritten in order to support as many panel containers as
   the user wants */

#ifndef HAVE_GNOME
widget_data containers [2];
int containers_no = 2;

void
xtoolkit_panel_setup ()
{
    containers [0] = x_create_panel_container (0);
    containers [1] = x_create_panel_container (1);
    input_w (cmdline)->widget.wcontainer = containers [0];
    input_w (cmdline)->widget.area = AREA_BOTTOM;
    the_prompt->widget.wcontainer = containers [0];
    the_prompt->widget.area = AREA_BOTTOM;
    the_bar->widget.wcontainer = containers [0];
    the_bar->widget.area = AREA_TOP;
#ifdef HAVE_XVIEW
    the_bar2->widget.wcontainer = containers [1];
    the_bar2->widget.area = AREA_TOP;
#endif
    get_panel_widget (0)->wcontainer = containers [0];
    get_panel_widget (0)->area = AREA_RIGHT;
    get_panel_widget (1)->wcontainer = containers [1];
    get_panel_widget (1)->area = AREA_RIGHT;
    the_menubar->widget.wcontainer = (widget_data) NULL;
}
#else
#    define xtoolkit_panel_setup()
#endif

#else
#    define xtoolkit_panel_setup()
#endif

#ifndef PORT_HAS_LOAD_HINT
void load_hint ()
{
    char *hint;

    if (!the_hint->widget.parent)
	return;

    if (!message_visible && (!xterm_flag || !xterm_hintbar)){
        label_set_text (the_hint, 0);
	return;
    }

    if ((hint = get_random_hint ())){
	if (*hint)
	    set_hintbar (hint);
	free (hint);
    } else {
	set_hintbar ("The Midnight Commander " VERSION
			" (C) 1995-1997 the Free Software Foundation");
    }
}
#endif

static void
setup_panels_and_run_mc ()
{
    int first, second;

    xtoolkit_panel_setup ();
    tk_new_frame (midnight_dlg, "p.");
#ifndef HAVE_X
    add_widget (midnight_dlg, the_hint);
#endif /* HAVE_X */
    load_hint ();
    add_widgetl (midnight_dlg, cmdline, XV_WLAY_RIGHTOF);
    add_widgetl (midnight_dlg, the_prompt, XV_WLAY_DONTCARE);
    tk_end_frame ();
    add_widget (midnight_dlg, the_bar);
#ifdef HAVE_XVIEW
    add_widget (midnight_dlg, the_bar2);
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?