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

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