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;

Reply via email to