[PATCH] interface responsiveness



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;


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