root/src/filemanager/layout.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. max
  2. check_split
  3. update_split
  4. b_left_right_cback
  5. bplus_cback
  6. bminus_cback
  7. layout_callback
  8. layout_dlg_create
  9. panel_do_cols
  10. restore_into_right_dir_panel
  11. layout_change
  12. layout_box
  13. panel_update_cols
  14. setup_panels
  15. panels_split_equal
  16. panels_split_more
  17. panels_split_less
  18. setup_cmdline
  19. use_dash
  20. set_hintbar
  21. rotate_dash
  22. get_nth_panel_name
  23. create_panel
  24. swap_panels
  25. get_panel_type
  26. get_panel_widget
  27. get_current_index
  28. get_other_index
  29. get_other_panel
  30. get_current_type
  31. get_other_type
  32. save_panel_dir
  33. get_panel_dir_for
  34. do_load_prompt
  35. load_prompt
  36. title_path_prepare
  37. update_xterm_title_path

   1 /*
   2    Panel layout module for the Midnight Commander
   3 
   4    Copyright (C) 1995-2019
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Janne Kukonlehto, 1995
   9    Miguel de Icaza, 1995
  10    Andrew Borodin <aborodin@vmail.ru>, 2011, 2012, 2013
  11    Slava Zanko <slavazanko@gmail.com>, 2013
  12    Avi Kelman <patcherton.fixesthings@gmail.com>, 2013
  13 
  14    This file is part of the Midnight Commander.
  15 
  16    The Midnight Commander is free software: you can redistribute it
  17    and/or modify it under the terms of the GNU General Public License as
  18    published by the Free Software Foundation, either version 3 of the License,
  19    or (at your option) any later version.
  20 
  21    The Midnight Commander is distributed in the hope that it will be useful,
  22    but WITHOUT ANY WARRANTY; without even the implied warranty of
  23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24    GNU General Public License for more details.
  25 
  26    You should have received a copy of the GNU General Public License
  27    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  28  */
  29 
  30 /** \file layout.c
  31  *  \brief Source: panel layout module
  32  */
  33 
  34 #include <config.h>
  35 
  36 #include <pwd.h>                /* for username in xterm title */
  37 #include <stdlib.h>
  38 #include <stdio.h>
  39 #include <string.h>
  40 #include <sys/types.h>
  41 #include <unistd.h>
  42 
  43 #include "lib/global.h"
  44 #include "lib/tty/tty.h"
  45 #include "lib/skin.h"
  46 #include "lib/tty/key.h"
  47 #include "lib/tty/mouse.h"
  48 #include "lib/mcconfig.h"
  49 #include "lib/vfs/vfs.h"        /* For _vfs_get_cwd () */
  50 #include "lib/strutil.h"
  51 #include "lib/widget.h"
  52 #include "lib/event.h"
  53 
  54 #include "src/consaver/cons.saver.h"
  55 #include "src/viewer/mcviewer.h"        /* The view widget */
  56 #include "src/setup.h"
  57 #ifdef ENABLE_SUBSHELL
  58 #include "src/subshell/subshell.h"
  59 #endif
  60 
  61 #include "command.h"
  62 #include "midnight.h"
  63 #include "tree.h"
  64 /* Needed for the extern declarations of integer parameters */
  65 #include "dir.h"
  66 #include "layout.h"
  67 #include "info.h"               /* The Info widget */
  68 
  69 /*** global variables ****************************************************************************/
  70 
  71 panels_layout_t panels_layout = {
  72     /* Set if the panels are split horizontally */
  73     .horizontal_split = 0,
  74 
  75     /* vertical split */
  76     .vertical_equal = 1,
  77     .left_panel_size = 0,
  78 
  79     /* horizontal split */
  80     .horizontal_equal = 1,
  81     .top_panel_size = 0
  82 };
  83 
  84 /* Controls the display of the rotating dash on the verbose mode */
  85 gboolean nice_rotating_dash = TRUE;
  86 
  87 /* The number of output lines shown (if available) */
  88 int output_lines = 0;
  89 
  90 /* Set if the command prompt is to be displayed */
  91 gboolean command_prompt = TRUE;
  92 
  93 /* Set if the main menu is visible */
  94 int menubar_visible = 1;
  95 
  96 /* Set to show current working dir in xterm window title */
  97 gboolean xterm_title = TRUE;
  98 
  99 /* Set to show free space on device assigned to current directory */
 100 int free_space = 1;
 101 
 102 /* The starting line for the output of the subprogram */
 103 int output_start_y = 0;
 104 
 105 int ok_to_refresh = 1;
 106 
 107 /*** file scope macro definitions ****************************************************************/
 108 
 109 /* The maximum number of views managed by the create_panel routine */
 110 /* Must be at least two (for current and other).  Please note that until */
 111 /* Janne gets around this, we will only manage two of them :-) */
 112 #define MAX_VIEWS 2
 113 
 114 /* Width 12 for a wee Quick (Hex) View */
 115 #define MINWIDTH 12
 116 #define MINHEIGHT 5
 117 
 118 #define B_2LEFT B_USER
 119 #define B_2RIGHT (B_USER + 1)
 120 #define B_PLUS (B_USER + 2)
 121 #define B_MINUS (B_USER + 3)
 122 
 123 #define LAYOUT_OPTIONS_COUNT  G_N_ELEMENTS (check_options)
 124 
 125 /*** file scope type declarations ****************************************************************/
 126 
 127 /*** file scope variables ************************************************************************/
 128 
 129 static struct
 130 {
 131     panel_view_mode_t type;
 132     Widget *widget;
 133     char *last_saved_dir;       /* last view_list working directory */
 134 } panels[MAX_VIEWS] =
 135 {
 136     /* *INDENT-OFF* */
 137     /* init MAX_VIEWS items */
 138     { view_listing, NULL, NULL},
 139     { view_listing, NULL, NULL}
 140     /* *INDENT-ON* */
 141 };
 142 
 143 /* These variables are used to avoid updating the information unless */
 144 /* we need it */
 145 static panels_layout_t old_layout;
 146 static int old_output_lines;
 147 
 148 /* Internal variables */
 149 static int equal_split;
 150 static int _output_lines;
 151 
 152 static int height;
 153 
 154 static WRadio *radio_widget;
 155 
 156 static struct
 157 {
 158     const char *text;
 159     int *variable;
 160     WCheck *widget;
 161 } check_options[] =
 162 {
 163     /* *INDENT-OFF* */
 164     { N_("&Equal split"), &equal_split, NULL },
 165     { N_("&Menubar visible"), &menubar_visible, NULL },
 166     { N_("Command &prompt"), &command_prompt, NULL },
 167     { N_("&Keybar visible"), &mc_global.keybar_visible, NULL },
 168     { N_("H&intbar visible"), &mc_global.message_visible, NULL },
 169     { N_("&XTerm window title"), &xterm_title, NULL },
 170     { N_("&Show free space"), &free_space, NULL }
 171     /* *INDENT-ON* */
 172 };
 173 
 174 static const char *output_lines_label = NULL;
 175 static int output_lines_label_len;
 176 
 177 static WButton *bleft_widget, *bright_widget;
 178 
 179 /*** file scope functions ************************************************************************/
 180 /* --------------------------------------------------------------------------------------------- */
 181 
 182 /* don't use max() macro to avoid double call of str_term_width1() in widget width calculation */
 183 #undef max
 184 
 185 static int
 186 max (int a, int b)
     /* [previous][next][first][last][top][bottom][index][help]  */
 187 {
 188     return a > b ? a : b;
 189 }
 190 
 191 /* --------------------------------------------------------------------------------------------- */
 192 
 193 static void
 194 check_split (panels_layout_t * layout)
     /* [previous][next][first][last][top][bottom][index][help]  */
 195 {
 196     if (layout->horizontal_split)
 197     {
 198         if (layout->horizontal_equal)
 199             layout->top_panel_size = height / 2;
 200         else if (layout->top_panel_size < MINHEIGHT)
 201             layout->top_panel_size = MINHEIGHT;
 202         else if (layout->top_panel_size > height - MINHEIGHT)
 203             layout->top_panel_size = height - MINHEIGHT;
 204     }
 205     else
 206     {
 207         if (layout->vertical_equal)
 208             layout->left_panel_size = COLS / 2;
 209         else if (layout->left_panel_size < MINWIDTH)
 210             layout->left_panel_size = MINWIDTH;
 211         else if (layout->left_panel_size > COLS - MINWIDTH)
 212             layout->left_panel_size = COLS - MINWIDTH;
 213     }
 214 }
 215 
 216 /* --------------------------------------------------------------------------------------------- */
 217 
 218 static void
 219 update_split (const WDialog * h)
     /* [previous][next][first][last][top][bottom][index][help]  */
 220 {
 221     /* Check split has to be done before testing if it changed, since
 222        it can change due to calling check_split() as well */
 223     check_split (&panels_layout);
 224 
 225     if (panels_layout.horizontal_split)
 226         check_options[0].widget->state = panels_layout.horizontal_equal ? 1 : 0;
 227     else
 228         check_options[0].widget->state = panels_layout.vertical_equal ? 1 : 0;
 229     widget_redraw (WIDGET (check_options[0].widget));
 230 
 231     tty_setcolor (check_options[0].widget->state ? DISABLED_COLOR : COLOR_NORMAL);
 232 
 233     widget_move (h, 6, 5);
 234     if (panels_layout.horizontal_split)
 235         tty_printf ("%03d", panels_layout.top_panel_size);
 236     else
 237         tty_printf ("%03d", panels_layout.left_panel_size);
 238 
 239     widget_move (h, 6, 17);
 240     if (panels_layout.horizontal_split)
 241         tty_printf ("%03d", height - panels_layout.top_panel_size);
 242     else
 243         tty_printf ("%03d", COLS - panels_layout.left_panel_size);
 244 
 245     widget_move (h, 6, 12);
 246     tty_print_char ('=');
 247 }
 248 
 249 /* --------------------------------------------------------------------------------------------- */
 250 
 251 static int
 252 b_left_right_cback (WButton * button, int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 253 {
 254     (void) action;
 255 
 256     if (button == bright_widget)
 257     {
 258         if (panels_layout.horizontal_split)
 259             panels_layout.top_panel_size++;
 260         else
 261             panels_layout.left_panel_size++;
 262     }
 263     else
 264     {
 265         if (panels_layout.horizontal_split)
 266             panels_layout.top_panel_size--;
 267         else
 268             panels_layout.left_panel_size--;
 269     }
 270 
 271     update_split (WIDGET (button)->owner);
 272     layout_change ();
 273     do_refresh ();
 274     return 0;
 275 }
 276 
 277 /* --------------------------------------------------------------------------------------------- */
 278 
 279 static int
 280 bplus_cback (WButton * button, int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 281 {
 282     (void) button;
 283     (void) action;
 284 
 285     if (_output_lines < 99)
 286         _output_lines++;
 287     return 0;
 288 }
 289 
 290 /* --------------------------------------------------------------------------------------------- */
 291 
 292 static int
 293 bminus_cback (WButton * button, int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 294 {
 295     (void) button;
 296     (void) action;
 297 
 298     if (_output_lines > 0)
 299         _output_lines--;
 300     return 0;
 301 }
 302 
 303 /* --------------------------------------------------------------------------------------------- */
 304 
 305 static cb_ret_t
 306 layout_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 307 {
 308     WDialog *h = DIALOG (w);
 309 
 310     switch (msg)
 311     {
 312     case MSG_DRAW:
 313         /* When repainting the whole dialog (e.g. with C-l) we have to
 314            update everything */
 315         dlg_default_repaint (h);
 316 
 317         old_output_lines = -1;
 318 
 319         update_split (h);
 320 
 321         if (old_output_lines != _output_lines)
 322         {
 323             old_output_lines = _output_lines;
 324             tty_setcolor (mc_global.tty.console_flag != '\0' ? COLOR_NORMAL : DISABLED_COLOR);
 325             widget_move (h, 9, 5);
 326             tty_print_string (output_lines_label);
 327             widget_move (h, 9, 5 + 3 + output_lines_label_len);
 328             tty_printf ("%02d", _output_lines);
 329         }
 330         return MSG_HANDLED;
 331 
 332     case MSG_POST_KEY:
 333         {
 334             int _menubar_visible, _command_prompt, _keybar_visible, _message_visible;
 335 
 336             _menubar_visible = check_options[1].widget->state;
 337             _command_prompt = check_options[2].widget->state;
 338             _keybar_visible = check_options[3].widget->state;
 339             _message_visible = check_options[4].widget->state;
 340 
 341             if (mc_global.tty.console_flag != '\0')
 342             {
 343                 int minimum;
 344 
 345                 if (_output_lines < 0)
 346                     _output_lines = 0;
 347                 height =
 348                     LINES - _keybar_visible - _command_prompt - _menubar_visible - _output_lines -
 349                     _message_visible;
 350                 minimum = MINHEIGHT * (1 + panels_layout.horizontal_split);
 351                 if (height < minimum)
 352                 {
 353                     _output_lines -= minimum - height;
 354                     height = minimum;
 355                 }
 356             }
 357             else
 358                 height =
 359                     LINES - _keybar_visible - _command_prompt - _menubar_visible - _output_lines -
 360                     _message_visible;
 361 
 362             if (old_output_lines != _output_lines)
 363             {
 364                 old_output_lines = _output_lines;
 365                 tty_setcolor (mc_global.tty.console_flag != '\0' ? COLOR_NORMAL : DISABLED_COLOR);
 366                 widget_move (h, 9, 5 + 3 + output_lines_label_len);
 367                 tty_printf ("%02d", _output_lines);
 368             }
 369         }
 370         return MSG_HANDLED;
 371 
 372     case MSG_NOTIFY:
 373         if (sender == WIDGET (radio_widget))
 374         {
 375             if (panels_layout.horizontal_split != radio_widget->sel)
 376             {
 377                 int eq;
 378 
 379                 panels_layout.horizontal_split = radio_widget->sel;
 380 
 381                 if (panels_layout.horizontal_split)
 382                 {
 383                     eq = panels_layout.horizontal_equal;
 384                     if (eq)
 385                         panels_layout.top_panel_size = height / 2;
 386                 }
 387                 else
 388                 {
 389                     eq = panels_layout.vertical_equal;
 390                     if (eq)
 391                         panels_layout.left_panel_size = COLS / 2;
 392                 }
 393 
 394                 widget_disable (WIDGET (bleft_widget), eq);
 395                 widget_disable (WIDGET (bright_widget), eq);
 396 
 397                 update_split (h);
 398                 layout_change ();
 399                 do_refresh ();
 400             }
 401             else
 402                 update_split (h);
 403 
 404             return MSG_HANDLED;
 405         }
 406 
 407         if (sender == WIDGET (check_options[0].widget))
 408         {
 409             int eq;
 410 
 411             if (panels_layout.horizontal_split)
 412             {
 413                 panels_layout.horizontal_equal = check_options[0].widget->state;
 414                 eq = panels_layout.horizontal_equal;
 415             }
 416             else
 417             {
 418                 panels_layout.vertical_equal = check_options[0].widget->state;
 419                 eq = panels_layout.vertical_equal;
 420             }
 421 
 422             widget_disable (WIDGET (bleft_widget), eq);
 423             widget_disable (WIDGET (bright_widget), eq);
 424 
 425             update_split (h);
 426             layout_change ();
 427             do_refresh ();
 428 
 429             return MSG_HANDLED;
 430         }
 431 
 432         return MSG_NOT_HANDLED;
 433 
 434     default:
 435         return dlg_default_callback (w, sender, msg, parm, data);
 436     }
 437 }
 438 
 439 /* --------------------------------------------------------------------------------------------- */
 440 
 441 static WDialog *
 442 layout_dlg_create (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 443 {
 444     WDialog *layout_dlg;
 445     int l1 = 0, width;
 446     int b1, b2, b;
 447     size_t i;
 448 
 449     const char *title1 = N_("Panel split");
 450     const char *title2 = N_("Console output");
 451     const char *title3 = N_("Other options");
 452 
 453     const char *s_split_direction[2] = {
 454         N_("&Vertical"),
 455         N_("&Horizontal")
 456     };
 457 
 458     const char *ok_button = N_("&OK");
 459     const char *cancel_button = N_("&Cancel");
 460 
 461     output_lines_label = _("Output lines:");
 462 
 463     /* save old params */
 464     old_output_lines = -1;
 465     _output_lines = output_lines;
 466 
 467 #ifdef ENABLE_NLS
 468     {
 469         static gboolean i18n = FALSE;
 470 
 471         title1 = _(title1);
 472         title2 = _(title2);
 473         title3 = _(title3);
 474 
 475         i = G_N_ELEMENTS (s_split_direction);
 476         while (i-- != 0)
 477             s_split_direction[i] = _(s_split_direction[i]);
 478 
 479         if (!i18n)
 480         {
 481             for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
 482                 check_options[i].text = _(check_options[i].text);
 483             i18n = TRUE;
 484         }
 485 
 486         ok_button = _(ok_button);
 487         cancel_button = _(cancel_button);
 488     }
 489 #endif
 490 
 491     /* radiobuttons */
 492     i = G_N_ELEMENTS (s_split_direction);
 493     while (i-- != 0)
 494         l1 = max (l1, str_term_width1 (s_split_direction[i]) + 7);
 495     /* checkboxes */
 496     for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
 497         l1 = max (l1, str_term_width1 (check_options[i].text) + 7);
 498     /* groupboxes */
 499     l1 = max (l1, str_term_width1 (title1) + 4);
 500     l1 = max (l1, str_term_width1 (title2) + 4);
 501     l1 = max (l1, str_term_width1 (title3) + 4);
 502     /* label + "+"/"-" buttons */
 503     output_lines_label_len = str_term_width1 (output_lines_label);
 504     l1 = max (l1, output_lines_label_len + 12);
 505     /* buttons */
 506     b1 = str_term_width1 (ok_button) + 5;       /* default button */
 507     b2 = str_term_width1 (cancel_button) + 3;
 508     b = b1 + b2 + 1;
 509     /* dialog width */
 510     width = max (l1 * 2 + 7, b);
 511 
 512     layout_dlg =
 513         dlg_create (TRUE, 0, 0, 15, width, WPOS_CENTER, FALSE, dialog_colors, layout_callback, NULL,
 514                     "[Layout]", _("Layout"));
 515 
 516 #define XTRACT(i) (*check_options[i].variable != 0), check_options[i].text
 517 
 518     /* "Panel split" groupbox */
 519     add_widget (layout_dlg, groupbox_new (2, 3, 6, l1, title1));
 520 
 521     radio_widget = radio_new (3, 5, 2, s_split_direction);
 522     radio_widget->sel = panels_layout.horizontal_split;
 523     add_widget (layout_dlg, radio_widget);
 524 
 525     check_options[0].widget = check_new (5, 5, XTRACT (0));
 526     add_widget (layout_dlg, check_options[0].widget);
 527 
 528     equal_split = panels_layout.horizontal_split ?
 529         panels_layout.horizontal_equal : panels_layout.vertical_equal;
 530 
 531     bleft_widget = button_new (6, 8, B_2LEFT, NARROW_BUTTON, "&<", b_left_right_cback);
 532     widget_disable (WIDGET (bleft_widget), equal_split);
 533     add_widget (layout_dlg, bleft_widget);
 534 
 535     bright_widget = button_new (6, 14, B_2RIGHT, NARROW_BUTTON, "&>", b_left_right_cback);
 536     widget_disable (WIDGET (bright_widget), equal_split);
 537     add_widget (layout_dlg, bright_widget);
 538 
 539     /* "Console output" groupbox */
 540     {
 541         widget_state_t disabled;
 542         Widget *w;
 543 
 544         disabled = mc_global.tty.console_flag != '\0' ? 0 : WST_DISABLED;
 545 
 546         w = WIDGET (groupbox_new (8, 3, 3, l1, title2));
 547         w->state |= disabled;
 548         add_widget (layout_dlg, w);
 549 
 550         w = WIDGET (button_new (9, output_lines_label_len + 5, B_PLUS,
 551                                 NARROW_BUTTON, "&+", bplus_cback));
 552         w->state |= disabled;
 553         add_widget (layout_dlg, w);
 554 
 555         w = WIDGET (button_new (9, output_lines_label_len + 5 + 5, B_MINUS,
 556                                 NARROW_BUTTON, "&-", bminus_cback));
 557         w->state |= disabled;
 558         add_widget (layout_dlg, w);
 559     }
 560 
 561     /* "Other options" groupbox */
 562     add_widget (layout_dlg, groupbox_new (2, 4 + l1, 9, l1, title3));
 563 
 564     for (i = 1; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
 565     {
 566         check_options[i].widget = check_new (i + 2, 6 + l1, XTRACT (i));
 567         add_widget (layout_dlg, check_options[i].widget);
 568     }
 569 
 570 #undef XTRACT
 571 
 572     add_widget (layout_dlg, hline_new (11, -1, -1));
 573     /* buttons */
 574     add_widget (layout_dlg,
 575                 button_new (12, (width - b) / 2, B_ENTER, DEFPUSH_BUTTON, ok_button, 0));
 576     add_widget (layout_dlg,
 577                 button_new (12, (width - b) / 2 + b1 + 1, B_CANCEL, NORMAL_BUTTON,
 578                             cancel_button, 0));
 579 
 580     widget_select (WIDGET (radio_widget));
 581 
 582     return layout_dlg;
 583 }
 584 
 585 /* --------------------------------------------------------------------------------------------- */
 586 
 587 static void
 588 panel_do_cols (int idx)
     /* [previous][next][first][last][top][bottom][index][help]  */
 589 {
 590     if (get_panel_type (idx) == view_listing)
 591         set_panel_formats (PANEL (panels[idx].widget));
 592     else
 593         panel_update_cols (panels[idx].widget, frame_half);
 594 }
 595 
 596 /* --------------------------------------------------------------------------------------------- */
 597 /** Save current list_view widget directory into panel */
 598 
 599 static Widget *
 600 restore_into_right_dir_panel (int idx, gboolean last_was_panel, int y, int x, int lines, int cols)
     /* [previous][next][first][last][top][bottom][index][help]  */
 601 {
 602     WPanel *new_widget;
 603     const char *p_name;
 604 
 605     p_name = get_nth_panel_name (idx);
 606 
 607     if (last_was_panel)
 608     {
 609         vfs_path_t *saved_dir_vpath;
 610 
 611         saved_dir_vpath = vfs_path_from_str (panels[idx].last_saved_dir);
 612         new_widget = panel_sized_with_dir_new (p_name, y, x, lines, cols, saved_dir_vpath);
 613         vfs_path_free (saved_dir_vpath);
 614     }
 615     else
 616         new_widget = panel_sized_new (p_name, y, x, lines, cols);
 617 
 618     return WIDGET (new_widget);
 619 }
 620 
 621 /* --------------------------------------------------------------------------------------------- */
 622 /*** public functions ****************************************************************************/
 623 /* --------------------------------------------------------------------------------------------- */
 624 
 625 void
 626 layout_change (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 627 {
 628     setup_panels ();
 629     /* update the main menu, because perhaps there was a change in the way
 630        how the panel are split (horizontal/vertical),
 631        and a change of menu visibility. */
 632     update_menu ();
 633     load_hint (TRUE);
 634 }
 635 
 636 /* --------------------------------------------------------------------------------------------- */
 637 
 638 void
 639 layout_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 640 {
 641     WDialog *layout_dlg;
 642 
 643     old_layout = panels_layout;
 644     old_output_lines = output_lines;
 645     layout_dlg = layout_dlg_create ();
 646 
 647     if (dlg_run (layout_dlg) == B_ENTER)
 648     {
 649         size_t i;
 650 
 651         for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
 652             if (check_options[i].widget != NULL)
 653                 *check_options[i].variable = check_options[i].widget->state;
 654 
 655         output_lines = _output_lines;
 656     }
 657     else
 658     {
 659         /* restore layout */
 660         panels_layout = old_layout;
 661         output_lines = old_output_lines;
 662         check_split (&panels_layout);   /* FIXME: is it really needed? */
 663     }
 664 
 665     dlg_destroy (layout_dlg);
 666     layout_change ();
 667     do_refresh ();
 668 }
 669 
 670 /* --------------------------------------------------------------------------------------------- */
 671 
 672 void
 673 panel_update_cols (Widget * widget, panel_display_t frame_size)
     /* [previous][next][first][last][top][bottom][index][help]  */
 674 {
 675     int cols, origin;
 676 
 677     /* don't touch panel if it is not in dialog yet */
 678     /* if panel is not in dialog it is not in widgets list
 679        and cannot be compared with get_panel_widget() result */
 680     if (widget->owner == NULL)
 681         return;
 682 
 683     if (panels_layout.horizontal_split)
 684     {
 685         widget->cols = COLS;
 686         return;
 687     }
 688 
 689     if (frame_size == frame_full)
 690     {
 691         cols = COLS;
 692         origin = 0;
 693     }
 694     else if (widget == get_panel_widget (0))
 695     {
 696         cols = panels_layout.left_panel_size;
 697         origin = 0;
 698     }
 699     else
 700     {
 701         cols = COLS - panels_layout.left_panel_size;
 702         origin = panels_layout.left_panel_size;
 703     }
 704 
 705     widget->cols = cols;
 706     widget->x = origin;
 707 }
 708 
 709 /* --------------------------------------------------------------------------------------------- */
 710 
 711 void
 712 setup_panels (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 713 {
 714     int start_y;
 715 
 716     if (mc_global.tty.console_flag != '\0')
 717     {
 718         int minimum;
 719 
 720         if (output_lines < 0)
 721             output_lines = 0;
 722         height =
 723             LINES - mc_global.keybar_visible - (command_prompt ? 1 : 0) - menubar_visible -
 724             output_lines - mc_global.message_visible;
 725         minimum = MINHEIGHT * (1 + panels_layout.horizontal_split);
 726         if (height < minimum)
 727         {
 728             output_lines -= minimum - height;
 729             height = minimum;
 730         }
 731     }
 732     else
 733     {
 734         height =
 735             LINES - menubar_visible - (command_prompt ? 1 : 0) - mc_global.keybar_visible -
 736             mc_global.message_visible;
 737     }
 738 
 739     check_split (&panels_layout);
 740     start_y = menubar_visible;
 741 
 742     /* update columns first... */
 743     panel_do_cols (0);
 744     panel_do_cols (1);
 745 
 746     /* ...then rows and origin */
 747     if (panels_layout.horizontal_split)
 748     {
 749         widget_set_size (panels[0].widget, start_y, 0, panels_layout.top_panel_size,
 750                          panels[0].widget->cols);
 751         widget_set_size (panels[1].widget, start_y + panels_layout.top_panel_size, 0,
 752                          height - panels_layout.top_panel_size, panels[1].widget->cols);
 753     }
 754     else
 755     {
 756         widget_set_size (panels[0].widget, start_y, 0, height, panels[0].widget->cols);
 757         widget_set_size (panels[1].widget, start_y, panels[1].widget->x, height,
 758                          panels[1].widget->cols);
 759     }
 760 
 761     widget_set_size (WIDGET (the_menubar), 0, 0, 1, COLS);
 762 
 763     if (command_prompt)
 764     {
 765 #ifdef ENABLE_SUBSHELL
 766         if (!mc_global.tty.use_subshell || !do_load_prompt ())
 767 #endif
 768             setup_cmdline ();
 769     }
 770     else
 771     {
 772         widget_set_size (WIDGET (cmdline), 0, 0, 0, 0);
 773         widget_set_size (WIDGET (the_prompt), LINES, COLS, 0, 0);
 774     }
 775 
 776     widget_set_size (WIDGET (the_bar), LINES - 1, 0, mc_global.keybar_visible, COLS);
 777     buttonbar_set_visible (the_bar, mc_global.keybar_visible);
 778 
 779     /* Output window */
 780     if (mc_global.tty.console_flag != '\0' && output_lines)
 781     {
 782         output_start_y = LINES - (command_prompt ? 1 : 0) - mc_global.keybar_visible - output_lines;
 783         show_console_contents (output_start_y,
 784                                LINES - output_lines - mc_global.keybar_visible - 1,
 785                                LINES - mc_global.keybar_visible - 1);
 786     }
 787 
 788     if (mc_global.message_visible)
 789         widget_set_size (WIDGET (the_hint), height + start_y, 0, 1, COLS);
 790     else
 791         widget_set_size (WIDGET (the_hint), 0, 0, 0, 0);
 792 
 793     update_xterm_title_path ();
 794 }
 795 
 796 /* --------------------------------------------------------------------------------------------- */
 797 
 798 void
 799 panels_split_equal (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 800 {
 801     if (panels_layout.horizontal_split)
 802         panels_layout.horizontal_equal = TRUE;
 803     else
 804         panels_layout.vertical_equal = TRUE;
 805 
 806     layout_change ();
 807     do_refresh ();
 808 }
 809 
 810 /* --------------------------------------------------------------------------------------------- */
 811 
 812 void
 813 panels_split_more (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 814 {
 815     if (panels_layout.horizontal_split)
 816     {
 817         panels_layout.horizontal_equal = FALSE;
 818         panels_layout.top_panel_size++;
 819     }
 820     else
 821     {
 822         panels_layout.vertical_equal = FALSE;
 823         panels_layout.left_panel_size++;
 824     }
 825 
 826     layout_change ();
 827 }
 828 
 829 /* --------------------------------------------------------------------------------------------- */
 830 
 831 void
 832 panels_split_less (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 833 {
 834     if (panels_layout.horizontal_split)
 835     {
 836         panels_layout.horizontal_equal = FALSE;
 837         panels_layout.top_panel_size--;
 838     }
 839     else
 840     {
 841         panels_layout.vertical_equal = FALSE;
 842         panels_layout.left_panel_size--;
 843     }
 844 
 845     layout_change ();
 846 }
 847 
 848 /* --------------------------------------------------------------------------------------------- */
 849 
 850 
 851 void
 852 setup_cmdline (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 853 {
 854     int prompt_width;
 855     int y;
 856     char *tmp_prompt = (char *) mc_prompt;
 857 
 858 #ifdef ENABLE_SUBSHELL
 859     if (mc_global.tty.use_subshell)
 860     {
 861         tmp_prompt = g_string_free (subshell_prompt, FALSE);
 862         (void) strip_ctrl_codes (tmp_prompt);
 863     }
 864 #endif
 865 
 866     prompt_width = str_term_width1 (tmp_prompt);
 867 
 868     /* Check for prompts too big */
 869     if (COLS > 8 && prompt_width > COLS - 8)
 870     {
 871         int prompt_len;
 872 
 873         prompt_width = COLS - 8;
 874         prompt_len = str_offset_to_pos (tmp_prompt, prompt_width);
 875         tmp_prompt[prompt_len] = '\0';
 876     }
 877 
 878 #ifdef ENABLE_SUBSHELL
 879     if (mc_global.tty.use_subshell)
 880     {
 881         subshell_prompt = g_string_new (tmp_prompt);
 882         g_free (tmp_prompt);
 883         mc_prompt = subshell_prompt->str;
 884     }
 885 #endif
 886 
 887     y = LINES - 1 - mc_global.keybar_visible;
 888 
 889     widget_set_size (WIDGET (the_prompt), y, 0, 1, prompt_width);
 890     label_set_text (the_prompt, mc_prompt);
 891     widget_set_size (WIDGET (cmdline), y, prompt_width, 1, COLS - prompt_width);
 892 }
 893 
 894 /* --------------------------------------------------------------------------------------------- */
 895 
 896 void
 897 use_dash (gboolean flag)
     /* [previous][next][first][last][top][bottom][index][help]  */
 898 {
 899     if (flag)
 900         ok_to_refresh++;
 901     else
 902         ok_to_refresh--;
 903 }
 904 
 905 /* --------------------------------------------------------------------------------------------- */
 906 
 907 void
 908 set_hintbar (const char *str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 909 {
 910     label_set_text (the_hint, str);
 911     if (ok_to_refresh > 0)
 912         mc_refresh ();
 913 }
 914 
 915 /* --------------------------------------------------------------------------------------------- */
 916 
 917 void
 918 rotate_dash (gboolean show)
     /* [previous][next][first][last][top][bottom][index][help]  */
 919 {
 920     Widget *w = WIDGET (midnight_dlg);
 921 
 922     if (!nice_rotating_dash || (ok_to_refresh <= 0))
 923         return;
 924 
 925     widget_move (w, (menubar_visible != 0) ? 1 : 0, w->cols - 1);
 926     tty_setcolor (NORMAL_COLOR);
 927 
 928     if (!show)
 929         tty_print_alt_char (ACS_URCORNER, FALSE);
 930     else
 931     {
 932         static const char rotating_dash[4] = "|/-\\";
 933         static size_t pos = 0;
 934 
 935         tty_print_char (rotating_dash[pos]);
 936         pos = (pos + 1) % sizeof (rotating_dash);
 937     }
 938 
 939     mc_refresh ();
 940 }
 941 
 942 /* --------------------------------------------------------------------------------------------- */
 943 
 944 const char *
 945 get_nth_panel_name (int num)
     /* [previous][next][first][last][top][bottom][index][help]  */
 946 {
 947     if (!num)
 948         return "New Left Panel";
 949     else if (num == 1)
 950         return "New Right Panel";
 951     else
 952     {
 953         static char buffer[BUF_SMALL];
 954 
 955         g_snprintf (buffer, sizeof (buffer), "%ith Panel", num);
 956         return buffer;
 957     }
 958 }
 959 
 960 /* --------------------------------------------------------------------------------------------- */
 961 /* I wonder if I should start to use the folding mode than Dugan uses */
 962 /*                                                                     */
 963 /* This is the centralized managing of the panel display types         */
 964 /* This routine takes care of destroying and creating new widgets      */
 965 /* Please note that it could manage MAX_VIEWS, not just left and right */
 966 /* Currently nothing in the code takes advantage of this and has hard- */
 967 /* coded values for two panels only                                    */
 968 
 969 /* Set the num-th panel to the view type: type */
 970 /* This routine also keeps at least one WPanel object in the screen */
 971 /* since a lot of routines depend on the current_panel variable */
 972 
 973 void
 974 create_panel (int num, panel_view_mode_t type)
     /* [previous][next][first][last][top][bottom][index][help]  */
 975 {
 976     int x = 0, y = 0, cols = 0, lines = 0;
 977     unsigned int the_other = 0; /* Index to the other panel */
 978     const char *file_name = NULL;       /* For Quick view */
 979     Widget *new_widget = NULL, *old_widget = NULL;
 980     panel_view_mode_t old_type = view_listing;
 981     WPanel *the_other_panel = NULL;
 982 
 983     if (num >= MAX_VIEWS)
 984     {
 985         fprintf (stderr, "Cannot allocate more that %d views\n", MAX_VIEWS);
 986         abort ();
 987     }
 988     /* Check that we will have a WPanel * at least */
 989     if (type != view_listing)
 990     {
 991         the_other = num == 0 ? 1 : 0;
 992 
 993         if (panels[the_other].type != view_listing)
 994             return;
 995     }
 996 
 997     /* Get rid of it */
 998     if (panels[num].widget != NULL)
 999     {
1000         Widget *w = panels[num].widget;
1001         WPanel *panel = PANEL (w);
1002 
1003         x = w->x;
1004         y = w->y;
1005         cols = w->cols;
1006         lines = w->lines;
1007         old_widget = w;
1008         old_type = panels[num].type;
1009 
1010         if (old_type == view_listing && panel->frame_size == frame_full && type != view_listing)
1011         {
1012             if (panels_layout.horizontal_split)
1013             {
1014                 cols = COLS;
1015                 x = 0;
1016             }
1017             else
1018             {
1019                 cols = COLS - panels_layout.left_panel_size;
1020                 if (num == 1)
1021                     x = panels_layout.left_panel_size;
1022             }
1023         }
1024     }
1025 
1026     /* Restoring saved path from panels.ini for nonlist panel */
1027     /* when it's first creation (for example view_info) */
1028     if (old_widget == NULL && type != view_listing)
1029         panels[num].last_saved_dir = _vfs_get_cwd ();
1030 
1031     switch (type)
1032     {
1033     case view_nothing:
1034     case view_listing:
1035         {
1036             gboolean last_was_panel;
1037 
1038             last_was_panel = old_widget != NULL && get_panel_type (num) != view_listing;
1039             new_widget = restore_into_right_dir_panel (num, last_was_panel, y, x, lines, cols);
1040             break;
1041         }
1042 
1043     case view_info:
1044         new_widget = WIDGET (info_new (y, x, lines, cols));
1045         break;
1046 
1047     case view_tree:
1048         new_widget = WIDGET (tree_new (y, x, lines, cols, TRUE));
1049         break;
1050 
1051     case view_quick:
1052         new_widget = WIDGET (mcview_new (y, x, lines, cols, TRUE));
1053         the_other_panel = PANEL (panels[the_other].widget);
1054         if (the_other_panel != NULL)
1055             file_name = the_other_panel->dir.list[the_other_panel->selected].fname;
1056         else
1057             file_name = "";
1058 
1059         mcview_load ((WView *) new_widget, 0, file_name, 0, 0, 0);
1060         break;
1061 
1062     default:
1063         break;
1064     }
1065 
1066     if (type != view_listing)
1067         /* Must save dir, for restoring after change type to */
1068         /* view_listing */
1069         save_panel_dir (num);
1070 
1071     panels[num].type = type;
1072     panels[num].widget = new_widget;
1073 
1074     /* We use replace to keep the circular list of the dialog in the */
1075     /* same state.  Maybe we could just kill it and then replace it  */
1076     if ((midnight_dlg != NULL) && (old_widget != NULL))
1077     {
1078         if (old_type == view_listing)
1079         {
1080             /* save and write directory history of panel
1081              * ... and other histories of midnight_dlg  */
1082             dlg_save_history (midnight_dlg);
1083         }
1084 
1085         widget_replace (old_widget, new_widget);
1086     }
1087 
1088     if (type == view_listing)
1089     {
1090         WPanel *panel = PANEL (new_widget);
1091 
1092         /* if existing panel changed type to view_listing, then load history */
1093         if (old_widget != NULL)
1094         {
1095             ev_history_load_save_t event_data = { NULL, new_widget };
1096 
1097             mc_event_raise (midnight_dlg->event_group, MCEVENT_HISTORY_LOAD, &event_data);
1098         }
1099 
1100         if (num == 0)
1101             left_panel = panel;
1102         else
1103             right_panel = panel;
1104 
1105         /* forced update format after set new sizes */
1106         set_panel_formats (panel);
1107     }
1108 
1109     if (type == view_tree)
1110         the_tree = (WTree *) new_widget;
1111 
1112     /* Prevent current_panel's value from becoming invalid.
1113      * It's just a quick hack to prevent segfaults. Comment out and
1114      * try following:
1115      * - select left panel
1116      * - invoke menue left/tree
1117      * - as long as you stay in the left panel almost everything that uses
1118      *   current_panel causes segfault, e.g. C-Enter, C-x c, ...
1119      */
1120     if ((type != view_listing) && (current_panel == PANEL (old_widget)))
1121         current_panel = num == 0 ? right_panel : left_panel;
1122 
1123     g_free (old_widget);
1124 }
1125 
1126 /* --------------------------------------------------------------------------------------------- */
1127 /** This routine is deeply sticked to the two panels idea.
1128    What should it do in more panels. ANSWER - don't use it
1129    in any multiple panels environment. */
1130 
1131 void
1132 swap_panels (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1133 {
1134     WPanel *panel1, *panel2;
1135     Widget *tmp_widget;
1136 
1137     panel1 = PANEL (panels[0].widget);
1138     panel2 = PANEL (panels[1].widget);
1139 
1140     if (panels[0].type == view_listing && panels[1].type == view_listing &&
1141         !mc_config_get_bool (mc_global.main_config, CONFIG_PANELS_SECTION, "simple_swap", FALSE))
1142     {
1143         WPanel panel;
1144 
1145 #define panelswap(x) panel.x = panel1->x; panel1->x = panel2->x; panel2->x = panel.x;
1146         /* Change content and related stuff */
1147         panelswap (dir);
1148         panelswap (active);
1149         panelswap (cwd_vpath);
1150         panelswap (lwd_vpath);
1151         panelswap (marked);
1152         panelswap (dirs_marked);
1153         panelswap (total);
1154         panelswap (top_file);
1155         panelswap (selected);
1156         panelswap (is_panelized);
1157         panelswap (dir_stat);
1158 #undef panelswap
1159 
1160         panel1->searching = FALSE;
1161         panel2->searching = FALSE;
1162 
1163         if (current_panel == panel1)
1164             current_panel = panel2;
1165         else
1166             current_panel = panel1;
1167 
1168         /* if sort options are different -> resort panels */
1169         if (memcmp (&panel1->sort_info, &panel2->sort_info, sizeof (dir_sort_options_t)) != 0)
1170         {
1171             panel_re_sort (other_panel);
1172             panel_re_sort (current_panel);
1173         }
1174 
1175         if (widget_is_active (panels[0].widget))
1176             widget_select (panels[1].widget);
1177         else if (widget_is_active (panels[1].widget))
1178             widget_select (panels[0].widget);
1179     }
1180     else
1181     {
1182         WPanel *tmp_panel;
1183         int x, y, cols, lines;
1184         int tmp_type;
1185 
1186         tmp_panel = right_panel;
1187         right_panel = left_panel;
1188         left_panel = tmp_panel;
1189 
1190         if (panels[0].type == view_listing)
1191         {
1192             if (strcmp (panel1->panel_name, get_nth_panel_name (0)) == 0)
1193             {
1194                 g_free (panel1->panel_name);
1195                 panel1->panel_name = g_strdup (get_nth_panel_name (1));
1196             }
1197         }
1198         if (panels[1].type == view_listing)
1199         {
1200             if (strcmp (panel2->panel_name, get_nth_panel_name (1)) == 0)
1201             {
1202                 g_free (panel2->panel_name);
1203                 panel2->panel_name = g_strdup (get_nth_panel_name (0));
1204             }
1205         }
1206 
1207         x = panels[0].widget->x;
1208         y = panels[0].widget->y;
1209         cols = panels[0].widget->cols;
1210         lines = panels[0].widget->lines;
1211 
1212         panels[0].widget->x = panels[1].widget->x;
1213         panels[0].widget->y = panels[1].widget->y;
1214         panels[0].widget->cols = panels[1].widget->cols;
1215         panels[0].widget->lines = panels[1].widget->lines;
1216 
1217         panels[1].widget->x = x;
1218         panels[1].widget->y = y;
1219         panels[1].widget->cols = cols;
1220         panels[1].widget->lines = lines;
1221 
1222         tmp_widget = panels[0].widget;
1223         panels[0].widget = panels[1].widget;
1224         panels[1].widget = tmp_widget;
1225         tmp_type = panels[0].type;
1226         panels[0].type = panels[1].type;
1227         panels[1].type = tmp_type;
1228 
1229         /* force update formats because of possible changed sizes */
1230         if (panels[0].type == view_listing)
1231             set_panel_formats (PANEL (panels[0].widget));
1232         if (panels[1].type == view_listing)
1233             set_panel_formats (PANEL (panels[1].widget));
1234     }
1235 }
1236 
1237 /* --------------------------------------------------------------------------------------------- */
1238 
1239 panel_view_mode_t
1240 get_panel_type (int idx)
     /* [previous][next][first][last][top][bottom][index][help]  */
1241 {
1242     return panels[idx].type;
1243 }
1244 
1245 /* --------------------------------------------------------------------------------------------- */
1246 
1247 Widget *
1248 get_panel_widget (int idx)
     /* [previous][next][first][last][top][bottom][index][help]  */
1249 {
1250     return panels[idx].widget;
1251 }
1252 
1253 /* --------------------------------------------------------------------------------------------- */
1254 
1255 int
1256 get_current_index (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1257 {
1258     if (panels[0].widget == WIDGET (current_panel))
1259         return 0;
1260     else
1261         return 1;
1262 }
1263 
1264 /* --------------------------------------------------------------------------------------------- */
1265 
1266 int
1267 get_other_index (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1268 {
1269     return !get_current_index ();
1270 }
1271 
1272 /* --------------------------------------------------------------------------------------------- */
1273 
1274 WPanel *
1275 get_other_panel (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1276 {
1277     return PANEL (get_panel_widget (get_other_index ()));
1278 }
1279 
1280 /* --------------------------------------------------------------------------------------------- */
1281 /** Returns the view type for the current panel/view */
1282 
1283 panel_view_mode_t
1284 get_current_type (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1285 {
1286     if (panels[0].widget == WIDGET (current_panel))
1287         return panels[0].type;
1288     else
1289         return panels[1].type;
1290 }
1291 
1292 /* --------------------------------------------------------------------------------------------- */
1293 /** Returns the view type of the unselected panel */
1294 
1295 panel_view_mode_t
1296 get_other_type (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1297 {
1298     if (panels[0].widget == WIDGET (current_panel))
1299         return panels[1].type;
1300     else
1301         return panels[0].type;
1302 }
1303 
1304 /* --------------------------------------------------------------------------------------------- */
1305 /** Save current list_view widget directory into panel */
1306 
1307 void
1308 save_panel_dir (int idx)
     /* [previous][next][first][last][top][bottom][index][help]  */
1309 {
1310     panel_view_mode_t type = get_panel_type (idx);
1311     Widget *widget = get_panel_widget (idx);
1312 
1313     if ((type == view_listing) && (widget != NULL))
1314     {
1315         WPanel *w = PANEL (widget);
1316 
1317         g_free (panels[idx].last_saved_dir);    /* last path no needed */
1318         /* Because path can be nonlocal */
1319         panels[idx].last_saved_dir = g_strdup (vfs_path_as_str (w->cwd_vpath));
1320     }
1321 }
1322 
1323 /* --------------------------------------------------------------------------------------------- */
1324 /** Return working dir, if it's view_listing - cwd,
1325    but for other types - last_saved_dir */
1326 
1327 char *
1328 get_panel_dir_for (const WPanel * widget)
     /* [previous][next][first][last][top][bottom][index][help]  */
1329 {
1330     int i;
1331 
1332     for (i = 0; i < MAX_VIEWS; i++)
1333         if (PANEL (get_panel_widget (i)) == widget)
1334             break;
1335 
1336     if (i >= MAX_VIEWS)
1337         return g_strdup (".");
1338 
1339     if (get_panel_type (i) == view_listing)
1340     {
1341         vfs_path_t *cwd_vpath;
1342 
1343         cwd_vpath = PANEL (get_panel_widget (i))->cwd_vpath;
1344         return g_strdup (vfs_path_as_str (cwd_vpath));
1345     }
1346 
1347     return g_strdup (panels[i].last_saved_dir);
1348 }
1349 
1350 /* --------------------------------------------------------------------------------------------- */
1351 
1352 #ifdef ENABLE_SUBSHELL
1353 gboolean
1354 do_load_prompt (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1355 {
1356     gboolean ret = FALSE;
1357 
1358     if (!read_subshell_prompt ())
1359         return ret;
1360 
1361     /* Don't actually change the prompt if it's invisible */
1362     if (top_dlg != NULL && DIALOG (top_dlg->data) == midnight_dlg && command_prompt)
1363     {
1364         setup_cmdline ();
1365 
1366         /* since the prompt has changed, and we are called from one of the
1367          * tty_get_event channels, the prompt updating does not take place
1368          * automatically: force a cursor update and a screen refresh
1369          */
1370         update_cursor (midnight_dlg);
1371         mc_refresh ();
1372         ret = TRUE;
1373     }
1374     update_subshell_prompt = TRUE;
1375     return ret;
1376 }
1377 
1378 /* --------------------------------------------------------------------------------------------- */
1379 
1380 int
1381 load_prompt (int fd, void *unused)
     /* [previous][next][first][last][top][bottom][index][help]  */
1382 {
1383     (void) fd;
1384     (void) unused;
1385 
1386     do_load_prompt ();
1387     return 0;
1388 }
1389 #endif /* ENABLE_SUBSHELL */
1390 
1391 /* --------------------------------------------------------------------------------------------- */
1392 
1393 void
1394 title_path_prepare (char **path, char **login)
     /* [previous][next][first][last][top][bottom][index][help]  */
1395 {
1396     char host[BUF_TINY];
1397     struct passwd *pw = NULL;
1398     int res = 0;
1399 
1400     *path =
1401         vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
1402 
1403     res = gethostname (host, sizeof (host));
1404     if (res != 0)
1405         host[0] = '\0';
1406     else
1407         host[sizeof (host) - 1] = '\0';
1408 
1409     pw = getpwuid (getuid ());
1410     if (pw != NULL)
1411         *login = g_strdup_printf ("%s@%s", pw->pw_name, host);
1412     else
1413         *login = g_strdup (host);
1414 }
1415 
1416 /* --------------------------------------------------------------------------------------------- */
1417 
1418 /** Show current directory in the xterm title */
1419 void
1420 update_xterm_title_path (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1421 {
1422     if (mc_global.tty.xterm_flag && xterm_title)
1423     {
1424         char *p;
1425         char *path;
1426         char *login;
1427 
1428         title_path_prepare (&path, &login);
1429 
1430         p = g_strdup_printf ("mc [%s]:%s", login, path);
1431         g_free (login);
1432         g_free (path);
1433 
1434         fprintf (stdout, "\33]0;%s\7", str_term_form (p));
1435         g_free (p);
1436 
1437         if (!mc_global.tty.alternate_plus_minus)
1438             numeric_keypad_mode ();
1439         (void) fflush (stdout);
1440     }
1441 }
1442 
1443 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */