[PATCH] interface responsiveness take 2



Hello,

here is a better version of the previous patch, fixed and separated.

1) copy.patch - fixes the event handling in copy file dialog
2) findfile.patch - adds additional event checking into the grepping function to make the dialog react during grepping inside a file (I agree this is a bit hackish but seems to work and without threads it's hard to make a better solution) 3) vfsopen.patch - makes it possible to interrupt file load operation on vfs (typically slow ftp & accidentally pressing f3 on a large file) 4) viewintr.patch - Ctrl-G during file load without MMAP reverts to growing view (test - eg. NTFS partition); get_bottom_first in growing view can be interrupted (test - M-! ls -lR on root and pressing End); search can be interrupted 5) viewsearch.patch - block_search modified to use a lookup table to lower comparison count

Regards,

--
Jindrich Makovicka

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	Tue Sep 24 19:14:44 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/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	Tue Sep 24 19:16:40 2002
@@ -833,6 +833,9 @@
 		(*h->callback) (h, 0, DLG_IDLE);
 	    }
 	}
+	
+	/* to allow terminating the dlg from idle handler */
+	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/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	Tue Sep 24 19:29:11 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,11 @@
 static int is_start;		/* Status of the start/stop toggle button */
 static char *old_dir;
 
+/* Where did we stop */
+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 */
@@ -420,27 +426,31 @@
  *
  * Search the global (FIXME) regexp compiled content_pattern string in the
  * DIRECTORY/FILE.  It will add the found entries to the find listbox.
+ * 
+ * returns 0 if do_search should look for another file
+ *         1 if do_search should exit and proceed to the event handler
  */
-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 +467,15 @@
 	int has_newline;
 	char *p;
 	int found = 0;
+	Gpm_Event event;
+	int c;
+
+	if (resuming) {
+	    /* We've been previously suspended, start from the previous position */
+	    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 +491,37 @@
 		found = 0;
 	    }
 	    g_free (p);
+ 
+	    /* check for events */
+ 	    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) {
+			/* closing events */
+ 			stop_idle (h);
+ 			ret_val = 1;
+ 			break;
+ 		    }
+ 		    if (!h->send_idle_msg) {
+			/* suspended */
+ 			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 +617,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 +866,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/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	Tue Sep 24 19:14:44 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/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	Tue Sep 24 19:14:44 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;
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	Tue Sep 24 20:02:32 2002
@@ -207,6 +207,23 @@
 	delete_hook (&select_file_hook, view_hook);
 }
 
+/* check if the event is an interrupt key
+ * unfortunately we cannot enable SIGINT because then CTRL-C can
+ * stop the page reading in the middle and viewer gets confused
+ */
+static int int_key() 
+{
+    Gpm_Event event;
+    int c;
+
+    c = get_event (&event, 0, 0);
+    if (c == XCTRL('g') || c == ESC_CHAR || c == KEY_F(10) || c == XCTRL('c')) {
+	return 1;
+    }
+    return 0;
+}
+
+
 static int
 get_byte (WView *view, unsigned int byte_index)
 {
@@ -241,7 +258,7 @@
 			view->last_byte = view->first + view->bytes_read;
 		}
 		/* To force loading the next page */
-		if (n == VIEW_PAGE_SIZE && view->reading_pipe){
+		if (n == VIEW_PAGE_SIZE && (view->reading_pipe || view->partial)){
 		    view->last_byte++;
 		}
 	    }
@@ -424,6 +441,7 @@
 {
     view->growing_buffer = 0;
     view->reading_pipe   = 0;
+    view->partial        = 0;
     view->first = 0;
     view->last_byte = 0;
     if (msg){
@@ -433,6 +451,45 @@
     return 0;
 }
 
+/* read a file into memory, can be interrupted */
+#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;
+
+    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 (int_key ()) break;
+	if (verbose) {
+	    view_percent (view, total, w, TRUE);
+	    mc_refresh ();
+	}
+	buf += to_read;
+	count -= to_read;
+    }
+    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)
@@ -473,6 +530,8 @@
 */
 static char *load_view_file (WView *view, int fd)
 {
+    int intr_flag = 0;
+    
     view->file = fd;
 
     if (view->s.st_size == 0){
@@ -500,12 +559,17 @@
     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){
+	|| (intr_flag = mc_read_interruptible(view) != view->s.st_size)){
         if (view->data != NULL)
 	    g_free (view->data);
 	close_view_file (view);
+	if (intr_flag) {
+	    view->partial = 1;
+	    view->s.st_size = 0;
+	}
 	return init_growing_view (view, 0, view->filename);
     }
+
     view->first = 0;
     view->bytes_read = view->s.st_size;
     return NULL;
@@ -528,6 +592,7 @@
     view->data = NULL;
     view->growing_buffer = 0;
     view->reading_pipe = 0;
+    view->partial = 0;
     view->mmapping = 0;
     view->blocks = 0;
     view->block_ptr = 0;
@@ -721,7 +786,9 @@
         }
 	if (w > 70){
 	    printw (" ");
-	    if (view->growing_buffer)
+	    if (view->growing_buffer && view->growing_loading)
+		addstr (_("  [loading]"));
+	    else if (view->growing_buffer)
 		addstr (_("  [grow]"));
 	}
         if (w > 26) {
@@ -1252,11 +1319,27 @@
     if (view->growing_buffer){
 	int old_last_byte;
 
+	view->growing_loading = 1;
 	old_last_byte = -1;
 	while (old_last_byte != view->last_byte){
 	    old_last_byte = view->last_byte;
+	    if (verbose) {
+		view_status(view, TRUE);
+		mc_refresh ();
+	    }
+	    attrset (NORMAL_COLOR);
+
 	    get_byte (view, view->last_byte+VIEW_PAGE_SIZE);
+	    if (int_key()) break;
 	}
+	view->growing_loading = 0;
+
+	if (verbose) {
+	    view_status(view, TRUE);
+	    mc_refresh ();
+	}
+	attrset (NORMAL_COLOR);
+
     }
 
     bottom_first = move_backward2 (view, view->last_byte, vheight - 1);
@@ -1265,7 +1348,7 @@
     	bottom_first = (bottom_first + view->bytes_per_line - 1)
 	    / view->bytes_per_line * view->bytes_per_line;
     view->bottom_first = bottom_first;
-    
+
     return view->bottom_first;
 }
 
@@ -1475,8 +1558,6 @@
     long forward_line_start;
     long reverse_line_start;
     long t;
-    /* Clear interrupt status */
-    got_interrupt ();
 
     if (verbose){
 	d = message (D_INSERT, _(" Search "), _("Searching %s"), text);
@@ -1504,14 +1585,11 @@
 		view_percent (view, p, w, TRUE);
 		mc_refresh ();
 	    }
-	    if (got_interrupt ())
-		break;
+	    if (int_key()) 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;
@@ -1552,7 +1630,6 @@
 	g_free (s);
 	break;
     }
-    disable_interrupt_key ();
     if (verbose) {
 	dlg_run_done (d);
 	destroy_dlg (d);
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	Tue Sep 24 19:37:36 2002
@@ -28,6 +28,8 @@
     int file;			/* File descriptor (for mmap and munmap) */
     FILE *stdfile;		/* Stdio struct for reading file in parts */
     int reading_pipe;		/* Flag: Reading from pipe(use popen/pclose) */
+    int partial;                /* Flag: File reading was interrupted,
+				   reverted to growing view */
     unsigned long bytes_read;   /* How much of file is read */
     int mmapping;		/* Did we use mmap on the file? */
 
@@ -60,6 +62,7 @@
     
     /* Growing buffers information */
     int growing_buffer;		/* Use the growing buffers? */
+    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/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	Tue Sep 24 19:51:40 2002
@@ -1571,40 +1651,51 @@
     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 */
-    got_interrupt ();
-    enable_interrupt_key ();
     e = view->found_len ? view->search_start + 1 : view->search_start;
 
     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){
 		view_percent (view, e, w, TRUE);
 		mc_refresh ();
 	    }
-	    if (got_interrupt ())
-		break;
+	    if (int_key()) 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) {
+	    /* possible match, need to compare whole string */
 	    d = buffer;
+	    while (1) {
+	        b = get_byte (view, e++);
+		if (*d != b) break;
+		d++;
+		if (d - buffer == len) {
+		    /* match */
+		    return e - len;
+		}
+	    }
+	    step = 1;
 	}
+	e += step;
     }
-    disable_interrupt_key ();
     return -1;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]