Hello, the attached patch (against 4.6.0-pre1) fixes the following issues with mc:
- buttons in file copy dialog now work, previously the event handling was wrong and half of the events were dropped causing an erratic behavior - ftp transfer (eg. when pressing F3 on a file on ftpfs) can now be aborted by Ctrl-C - find file dialog responds even during searching inside a file - when mmap fails, a file read operation can be aborted - loading of a remaining portion of a growing file can be aborted by Ctrl-C - search and hex-search can be aborted - hex search uses a lookup table and is a bit faster Regards, -- Jindrich Makovicka
diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/dlg.c mc-4.6.0-pre1/src/dlg.c --- vanilla/mc-4.6.0-pre1/src/dlg.c Fri Aug 2 06:36:04 2002 +++ mc-4.6.0-pre1/src/dlg.c Sun Sep 22 12:02:35 2002 @@ -833,6 +833,8 @@ (*h->callback) (h, 0, DLG_IDLE); } } + + if (!h->running) break; update_cursor (h); (*h->callback)(h, 0, DLG_PRE_EVENT); diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/ext.c mc-4.6.0-pre1/src/ext.c --- vanilla/mc-4.6.0-pre1/src/ext.c Tue Aug 20 04:57:25 2002 +++ mc-4.6.0-pre1/src/ext.c Sun Sep 22 13:07:52 2002 @@ -482,7 +482,9 @@ content_string [hasread] = 0; } mc_close (remotehandle); - } + } else { + ret = 1; + } #endif /* _OS_NT */ } asked_file = 1; diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/file.c mc-4.6.0-pre1/src/file.c --- vanilla/mc-4.6.0-pre1/src/file.c Fri Jul 5 06:04:41 2002 +++ mc-4.6.0-pre1/src/file.c Sun Sep 22 12:02:35 2002 @@ -733,7 +733,11 @@ } file_progress_set_stalled_label (ctx, stalled_msg); - file_progress_show_bytes (ctx, *progress_bytes + n_read_total, ctx->progress_bytes); + return_status = file_progress_show_bytes (ctx, *progress_bytes + +n_read_total, ctx->progress_bytes); + if (return_status != FILE_CONT) { + mc_refresh (); + goto ret; + } return_status = file_progress_show (ctx, n_read_total, file_size); mc_refresh (); if (return_status != FILE_CONT) diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/find.c mc-4.6.0-pre1/src/find.c --- vanilla/mc-4.6.0-pre1/src/find.c Wed Aug 21 09:31:20 2002 +++ mc-4.6.0-pre1/src/find.c Sun Sep 22 12:05:51 2002 @@ -44,6 +44,7 @@ #include "wtools.h" #include "cmd.h" /* view_file_at_line */ #include "boxes.h" +#include "key.h" #include "../vfs/vfs.h" /* Size of the find parameters window */ @@ -79,6 +80,10 @@ static int is_start; /* Status of the start/stop toggle button */ static char *old_dir; +static int resuming; +static int last_line; +static int last_pos; + static Dlg_head *find_dlg; /* The dialog */ static WButton *stop_button; /* pointer to the stop button */ @@ -421,26 +426,27 @@ * Search the global (FIXME) regexp compiled content_pattern string in the * DIRECTORY/FILE. It will add the found entries to the find listbox. */ -static void +static int search_content (Dlg_head *h, char *directory, char *filename) { struct stat s; char buffer [BUF_SMALL]; char *fname; int file_fd; + int ret_val = 0; fname = concat_dir_and_file (directory, filename); if (mc_stat (fname, &s) != 0 || !S_ISREG (s.st_mode)){ g_free (fname); - return; + return 0; } file_fd = mc_open (fname, O_RDONLY); g_free (fname); if (file_fd == -1) - return; + return 0; g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), name_trunc (filename, FIND2_X_USE)); @@ -457,6 +463,14 @@ int has_newline; char *p; int found = 0; + Gpm_Event event; + int c; + + if (resuming) { + resuming = 0; + line = last_line; + pos = last_pos; + } while ((p = get_line_at (file_fd, buffer, &pos, &n_read, sizeof (buffer), &has_newline))){ if (found == 0){ /* Search in binary line once */ @@ -472,10 +486,34 @@ found = 0; } g_free (p); + + if ((line & 0x3f) == 0) { + c = get_event (&event, h->mouse_status == MOU_REPEAT, 0); + if (c != EV_NONE) { + dlg_process_event (h, c, &event); + if (h->ret_value == B_ENTER + || h->ret_value == B_CANCEL + || h->ret_value == B_AGAIN + || h->ret_value == B_PANELIZE) { + stop_idle (h); + ret_val = 1; + break; + } + if (!h->send_idle_msg) { + resuming = 1; + last_line = line; + last_pos = pos; + ret_val = 1; + break; + } + } + } + } } disable_interrupt_key (); mc_close (file_fd); + return ret_val; } static int @@ -571,9 +609,12 @@ } if (regexp_match (find_pattern, dp->d_name, match_file)){ - if (content_pattern) - search_content (h, directory, dp->d_name); - else + if (content_pattern) { + if (search_content (h, directory, dp->d_name)) { + g_free (tmp_name); + return 1; + } + } else find_add_match (h, directory, dp->d_name); } @@ -817,6 +858,7 @@ static int run_process (void) { + resuming = 0; set_idle_proc (find_dlg, 1); run_dlg (find_dlg); return find_dlg->ret_value; diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/view.c mc-4.6.0-pre1/src/view.c --- vanilla/mc-4.6.0-pre1/src/view.c Wed Aug 21 09:31:29 2002 +++ mc-4.6.0-pre1/src/view.c Sun Sep 22 18:45:04 2002 @@ -215,12 +215,25 @@ int i, n; if (view->growing_buffer){ - if (page > view->blocks){ + if (page > view->blocks && !view->growing_stopped){ + + view->dont_update = 1; + view->growing_loading = 1; + if (verbose) { + view_status(view, TRUE); + mc_refresh (); + } + attrset (NORMAL_COLOR); + + got_interrupt(); + enable_interrupt_key (); + view->block_ptr = g_realloc (view->block_ptr, sizeof (block_ptr_t) * page); for (i = view->blocks; i < page; i++){ char *p = g_malloc (VIEW_PAGE_SIZE); view->block_ptr [i].data = p; + view->blocks++; if (!p) return '\n'; if (view->stdfile != NULL) @@ -240,16 +253,33 @@ if (view->reading_pipe) view->last_byte = view->first + view->bytes_read; } + /* To force loading the next page */ if (n == VIEW_PAGE_SIZE && view->reading_pipe){ view->last_byte++; } + + if (got_interrupt()) { + view->growing_stopped = 1; + view->s.st_size = view->bytes_read; + view->last_byte = view->bytes_read; + if (view->reading_pipe) + view->last_byte = view->first + view->bytes_read; + break; + } + } - view->blocks = page; + disable_interrupt_key (); + view->growing_loading = 0; + view->dont_update = 0; } - if (byte_index > view->bytes_read){ + if (byte_index >= view->bytes_read) return -1; - } else + else return view->block_ptr [page-1].data [offset]; } else { if (byte_index >= view->last_byte) @@ -433,11 +463,65 @@ return 0; } +#define READ_PAGE_SIZE 32768 +ssize_t +mc_read_interruptible (WView *view) +{ + int w = view->widget.cols - view->have_frame + 1; + int fd = view->file; + void *buf = view->data; + size_t count = view->s.st_size; + ssize_t to_read, res; + ssize_t total = 0; + Dlg_head *d = 0; + Gpm_Event event; + int c; + + got_interrupt (); + enable_interrupt_key (); + + if (verbose) { + d = message (D_INSERT, _(" View "), _("Reading %s"), view->filename); + mc_refresh (); + } + + while (count) { + to_read = count > READ_PAGE_SIZE ? READ_PAGE_SIZE : count; + res = mc_read(fd, buf, to_read); + total += res; + if (res != to_read) + break; + if (got_interrupt ()) + break; + event.x = -1; + if (verbose) { + view_percent (view, total, w, TRUE); + mc_refresh (); + c = get_event (&event, 0, 0); + if (got_interrupt ()) break; + if (c != EV_NONE) { + dlg_process_event (d, c, &event); + if (d->ret_value == B_CANCEL) + break; + } + } + buf += to_read; + count -= to_read; + } + disable_interrupt_key (); + if (verbose) { + dlg_run_done (d); + destroy_dlg (d); + } + return total; +} + /* return values: NULL for success, else points to error message */ static char * init_growing_view (WView *view, char *name, char *filename) { view->growing_buffer = 1; + view->growing_stopped = 0; if (name){ view->reading_pipe = 1; @@ -500,12 +584,14 @@ view->data = (unsigned char*) g_malloc (view->s.st_size); if (view->data == NULL || mc_lseek(view->file, 0, SEEK_SET) != 0 - || mc_read(view->file, view->data, view->s.st_size) != view->s.st_size){ + || mc_read_interruptible(view) != view->s.st_size){ +// || mc_read(view->file, view->data, view->s.st_size) != view->s.st_size){ if (view->data != NULL) g_free (view->data); close_view_file (view); return init_growing_view (view, 0, view->filename); } + view->first = 0; view->bytes_read = view->s.st_size; return NULL; @@ -536,6 +622,7 @@ view->filename = g_strdup (_file); view->localcopy = 0; view->command = 0; + view->dont_update = 0; view->last = view->first + ((LINES-2) * view->bytes_per_line); /* Clear the markers */ @@ -721,7 +808,11 @@ } if (w > 70){ printw (" "); - if (view->growing_buffer) + if (view->growing_buffer && view->growing_loading) + addstr (_(" [loading]")); + else if (view->growing_buffer && view->growing_stopped) + addstr (_(" [!grow]")); + else if (view->growing_buffer) addstr (_(" [grow]")); } if (w > 26) { @@ -1051,6 +1142,8 @@ { static int dirt_limit = 1; + if (view->dont_update) return; + if (view->dirty > dirt_limit){ /* Too many updates skipped -> force a update */ display (view); @@ -1468,6 +1561,8 @@ int found_len, search_start; int search_status; Dlg_head *d = 0; + Gpm_Event event; + int c; /* Used to keep track of where the line starts, when looking forward */ /* is the index before transfering the line; the reverse case uses */ @@ -1475,8 +1570,10 @@ long forward_line_start; long reverse_line_start; long t; + /* Clear interrupt status */ got_interrupt (); + enable_interrupt_key (); if (verbose){ d = message (D_INSERT, _(" Search "), _("Searching %s"), text); @@ -1506,12 +1603,19 @@ } if (got_interrupt ()) break; + if (verbose) { + event.x = -1; + c = get_event (&event, 0, 0); + if (c != EV_NONE) { + dlg_process_event (d, c, &event); + if (d->ret_value == B_CANCEL) + break; + } + } } forward_line_start = p; - disable_interrupt_key (); s = get_line_at (view, &p, &t); reverse_line_start = p; - enable_interrupt_key (); if (!s) break; @@ -1571,6 +1675,8 @@ int w = view->widget.cols - view->have_frame + 1; char *d = buffer, b; + int lookup[256]; + int i, step; unsigned long e; /* clear interrupt status */ @@ -1580,8 +1686,15 @@ search_update_steps (view); update_activate = 0; + + for (i = 0; i < 256; i++) + lookup[i] = len; + for (i = len-1; i >= 0; i--, d++) + lookup[(unsigned char)*d] = i; + + d = buffer; - while (e < view->last_byte){ + while (e+len-1 < view->last_byte){ if (e >= update_activate){ update_activate += update_steps; if (verbose){ @@ -1591,18 +1704,24 @@ if (got_interrupt ()) break; } - b = get_byte (view, e++); - - if (*d == b){ - d++; - if (d - buffer == len){ - disable_interrupt_key (); - return e - len; - } - } else { - e -= d - buffer; + + b = get_byte(view, e+len-1); + step = lookup[(unsigned char)b]; + + if (step == 0) { d = buffer; + while (1) { + b = get_byte (view, e++); + if (*d != b) break; + d++; + if (d - buffer == len) { + disable_interrupt_key (); + return e - len; + } + } + step = 1; } + e += step; } disable_interrupt_key (); return -1; @@ -2429,6 +2548,8 @@ WView *view = (WView *) v; WPanel *panel; + if (view->dont_update) return; + /* If the user is busy typing, wait until he finishes to update the screen */ if (!is_idle ()){ @@ -2456,6 +2577,8 @@ { int i; + if ((msg == WIDGET_DRAW || msg == WIDGET_IDLE) && view->dont_update) return 1; + switch (msg){ case WIDGET_INIT: if (view->have_frame) diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/view.h mc-4.6.0-pre1/src/view.h --- vanilla/mc-4.6.0-pre1/src/view.h Sat Jul 20 04:54:52 2002 +++ mc-4.6.0-pre1/src/view.h Sun Sep 22 18:46:09 2002 @@ -51,6 +51,7 @@ int dirty; /* Number of skipped updates */ int wrap_mode; /* wrap_mode */ + int dont_update; /* Do not update to avoid infinite loop */ /* Mode variables */ int hex_mode; /* Hexadecimal mode flag */ @@ -60,6 +61,8 @@ /* Growing buffers information */ int growing_buffer; /* Use the growing buffers? */ + int growing_stopped; /* Growing view stopped using CTRL-C */ + int growing_loading; /* Loading additional blocks NOW */ block_ptr_t *block_ptr; /* Pointer to the block pointers */ int blocks; /* The number of blocks in *block_ptr */ diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/vfs/direntry.c mc-4.6.0-pre1/vfs/direntry.c --- vanilla/mc-4.6.0-pre1/vfs/direntry.c Tue Aug 20 04:57:26 2002 +++ mc-4.6.0-pre1/vfs/direntry.c Sun Sep 22 13:09:13 2002 @@ -949,7 +949,9 @@ goto error_3; /* Clear the interrupt status */ - + got_interrupt(); + enable_interrupt_key(); + while ((n = MEDATA->linear_read (me, &fh, buffer, sizeof(buffer)))) { if (n < 0) @@ -957,6 +959,9 @@ total += n; vfs_print_stats (me->name, _("Getting file"), ino->ent->name, total, stat_size); + + if (got_interrupt()) + goto error_1; if (write(handle, buffer, n) < 0) { me->verrno = errno;