rpms/newt/devel newt-0.52.6-entry.patch, NONE, 1.1 newt.spec, 1.46, 1.47

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Apr 4 16:06:22 UTC 2007


Author: mlichvar

Update of /cvs/dist/rpms/newt/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv7897

Modified Files:
	newt.spec 
Added Files:
	newt-0.52.6-entry.patch 
Log Message:
- fix entry scrolling (#234829)
- fix multibyte character handling in entry
Resolves: #234829


newt-0.52.6-entry.patch:
 entry.c |  120 +++++++++++++++++++++++++++++++++++-----------------------------
 1 files changed, 67 insertions(+), 53 deletions(-)

--- NEW FILE newt-0.52.6-entry.patch ---
Index: entry.c
===================================================================
RCS file: /usr/local/CVS/newt/entry.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- entry.c	11 Oct 2006 15:19:39 -0000	1.40
+++ entry.c	4 Apr 2007 15:17:51 -0000	1.41
@@ -25,6 +25,8 @@
     void * filterData;
 };
 
+static int previous_char(const char *buf, int pos);
+static int next_char(const char *buf, int pos);
 static void entryDraw(newtComponent co);
 static void entryDestroy(newtComponent co);
 static struct eventResult entryEvent(newtComponent co,
@@ -103,6 +105,11 @@
 	strcpy(en->buf, initialValue);
 	en->bufUsed = strlen(initialValue);
 	en->cursorPosition = en->bufUsed;
+
+	/* move cursor back if entry is full */
+	if (en->cursorPosition && !(en->flags & NEWT_FLAG_SCROLL ||
+		    wstrlen(en->buf, -1) < co->width))
+	    en->cursorPosition = previous_char(en->buf, en->cursorPosition);
     } else {
 	*en->buf = '\0';
 	en->bufUsed = 0;
@@ -112,39 +119,57 @@
     return co;
 }
 
-static int visible_width(const char *str, int start, int end)
-{
-    int width = wstrlen(str + start, end-start);
-    int len, w = 0;
-    wchar_t wc;
-
-    len = mbtowc(&wc, str+end, MB_CUR_MAX);
-    if (len == 0)
-       w = 1;
-    else if (len > 0)
-       w = wcwidth(wc);
-    return width + w;
-}
-
 static void scroll(struct entry *en, int width)
 {
-    wchar_t wc;
-    int len, w;
-    int  newwidth = visible_width(en->buf, en->firstChar, en->cursorPosition);
-
-    while (newwidth > width) {
-        len = mbtowc(&wc, en->buf+en->firstChar, MB_CUR_MAX);
-	if (!len) {
-		en->firstChar++;
-		break;
-	}
-	if (len < 0)
-	   break;
-	w = wcwidth(wc);
-	if (w < 0)
-	   break;
-	en->firstChar += len;
-	newwidth -= w;
+    int r, lv, rv, cntx, cw, cn, nc, pc, ncw, pcw;
+
+    if (width <= 1) {
+	en->firstChar = en->cursorPosition;
+	return;
+    }
+
+    cntx = width / 4;
+    if (cntx > 5)
+	cntx = 5;
+
+    if (en->cursorPosition < en->firstChar)
+	en->firstChar = en->cursorPosition;
+
+    cn = next_char(en->buf, en->cursorPosition);
+    cw = en->cursorPosition >= en->bufUsed ? 1 :
+	wstrlen(en->buf + en->cursorPosition, cn - en->cursorPosition);
+
+    r = wstrlen(en->buf + cn, -1);
+
+    lv = wstrlen(en->buf + en->firstChar, en->cursorPosition - en->firstChar);
+    rv = width - lv - cw;
+
+#define RC (ncw > 0 && (r > rv && lv - ncw >= cntx && rv < cntx))
+#define LC (pcw > 0 && (r + pcw <= rv || (lv < cntx && rv - pcw >= cntx)))
+
+    nc = next_char(en->buf, en->firstChar);
+    ncw = wstrlen(en->buf + en->firstChar, nc - en->firstChar);
+    if (RC) {
+	do {
+	    lv -= ncw;
+	    rv += ncw;
+	    en->firstChar = nc;
+	    nc = next_char(en->buf, en->firstChar);
+	    ncw = wstrlen(en->buf + en->firstChar, nc - en->firstChar);
+	} while (RC);
+	return;
+    }
+
+    pc = previous_char(en->buf, en->firstChar);
+    pcw = wstrlen(en->buf + pc, en->firstChar - pc);
+    if (LC) {
+	do {
+	    lv += pcw;
+	    rv -= pcw;
+	    en->firstChar = pc;
+	    pc = previous_char(en->buf, en->firstChar);
+	    pcw = wstrlen(en->buf + pc, en->firstChar - pc);
+	} while (LC);
     }
 }
 
@@ -171,13 +196,8 @@
 	return;
     }
 
-    if (en->cursorPosition < en->firstChar) {
-	/* scroll to the left */
-	en->firstChar = en->cursorPosition;
-    } else {
-	/* scroll to the right */
-	scroll(en, co->width);
-    }
+    /* scroll if necessary */
+    scroll(en, co->width);
 
     chptr = en->buf + en->firstChar;
 
@@ -317,17 +337,15 @@
 static int next_char(const char *buf, int pos)
 {
     int len = mblen(buf + pos, MB_CUR_MAX);
-    if (len < 0)
+    if (len <= 0)
        return pos;
-    if (len == 0)
-       return ++pos;
     return pos+len;
 }
 
 static struct eventResult entryHandleKey(newtComponent co, int key) {
     struct entry * en = co->data;
     struct eventResult er;
-    char * chptr, * insPoint;
+    char * chptr;
 
     er.result = ER_SWALLOWED;
     switch (key) {
@@ -430,7 +448,7 @@
 		s[i] = SLang_getkey();
 	    }
 
-	    if (!i || !(en->flags & NEWT_FLAG_SCROLL) && wstrlen(en->buf, -1) >= co->width) {
+	    if (!i || (!(en->flags & NEWT_FLAG_SCROLL) && wstrlen(en->buf, -1) + wstrlen(s, i) > co->width)) {
 		/* FIXME this is broken */
 		SLtt_beep();
 		break;
@@ -440,20 +458,12 @@
 		en->bufAlloced += 20;
 		en->buf = realloc(en->buf, en->bufAlloced);
 		if (en->resultPtr) *en->resultPtr = en->buf;
-		memset(en->buf + en->bufUsed + 1, 0, 20);
+		memset(en->buf + en->bufAlloced - 20, 0, 20);
 	    }
 
 	    if (en->cursorPosition != en->bufUsed) {
 		/* insert the new character */
-
-		/* chptr is the last character in the string */
-		chptr = (en->buf + en->bufUsed) - 2 + i;
-		insPoint = en->buf + en->cursorPosition;
-
-		while (chptr >= insPoint) {
-		    *(chptr + i) = *chptr;
-		    chptr--;
-		}
+		memmove(en->buf + en->cursorPosition + i, en->buf + en->cursorPosition, en->bufUsed - en->cursorPosition);
 	    }
 	    en->bufUsed += i;
 	    for (l = 0; l < i; l++)
@@ -462,6 +472,10 @@
 	    er.result = ER_IGNORED;
 	}
     }
+
+    if (en->cursorPosition == en->bufUsed && en->cursorPosition &&
+	    !(en->flags & NEWT_FLAG_SCROLL || wstrlen(en->buf, -1) < co->width))
+	en->cursorPosition = previous_char(en->buf, en->cursorPosition);
 
     entryDraw(co);
 


Index: newt.spec
===================================================================
RCS file: /cvs/dist/rpms/newt/devel/newt.spec,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- newt.spec	2 Mar 2007 13:26:50 -0000	1.46
+++ newt.spec	4 Apr 2007 16:06:20 -0000	1.47
@@ -1,7 +1,7 @@
 Summary: A development library for text mode user interfaces
 Name: newt
 Version: 0.52.6
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: LGPL
 Group: System Environment/Libraries
 # The source for this package was pulled from upstream's vcs.  Use the
@@ -12,6 +12,7 @@
 BuildRequires: python, python-devel, slang-devel
 Provides: snack = %{version}-%{release}
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Patch1: newt-0.52.6-entry.patch
 
 %package devel
 Summary: Newt windowing toolkit development files
@@ -49,6 +50,7 @@
 
 %prep
 %setup -q
+%patch1 -p0 -b .entry
 
 %build
 # gpm support seems to smash the stack w/ we use help in anaconda??
@@ -88,6 +90,10 @@
 %{_libdir}/libnewt.a
 
 %changelog
+* Wed Apr 04 2007 Miroslav Lichvar <mlichvar at redhat.com> - 0.52.6-2
+- fix entry scrolling (#234829)
+- fix multibyte character handling in entry
+
 * Fri Mar 02 2007 Miroslav Lichvar <mlichvar at redhat.com> - 0.52.6-1
 - add newtSetColor() to allow changing individual colors
 - add newtPopWindowNoRefresh() (patch by Forest Bond)




More information about the fedora-cvs-commits mailing list