From f04882c76d0d23a35942e736e89ef19268f541b5 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 7 Feb 2009 20:00:26 -0500 Subject: Copyright for 2009 --- src/layer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index a2fd74a..487e45e 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) -- cgit v1.2.1 From d610852510d22b848546adbf56fbb3b7f9d1d6b6 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 23 Sep 2009 13:28:38 -0400 Subject: Add __noreturn__ attribute to some functions. Setting the __noreturn__ attribute to a function helps analyzers such as clang-analyzer to not report false positives. --- src/layer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index 487e45e..a3ffb3e 100644 --- a/src/layer.c +++ b/src/layer.c @@ -879,11 +879,11 @@ int isblank; void /*VARARGS2*/ #if defined(USEVARARGS) && defined(__STDC__) -LMsg(int err, char *fmt, VA_DOTS) +LMsg(int err, const char *fmt, VA_DOTS) #else LMsg(err, fmt, VA_DOTS) int err; -char *fmt; +const char *fmt; VA_DECL #endif { -- cgit v1.2.1 From 2199ead34441dd5291ffecb737b9ff4e7ae47f0d Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 5 Dec 2009 21:53:52 -0500 Subject: Revamp the display list. Revamp the display list (in works). The future changes are expected to add full mouse control, and perhaps some other utility functions (e.g. detaching a display, changing permissions perhaps? etc.) --- src/layer.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index a3ffb3e..8b94b99 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1115,3 +1115,27 @@ ExitOverlayPage() LayRestore(); LaySetCursor(); } + +int +LayProcessMouse(struct layer *l, unsigned char ch) +{ + /* XXX: Make sure the layer accepts mouse events */ + int len; + + if (l->l_mouseevent.len >= sizeof(l->l_mouseevent.buffer)) + return -1; + + len = l->l_mouseevent.len++; + l->l_mouseevent.buffer[len] = (len > 0 ? ch - 33 : ch); + return (l->l_mouseevent.len == sizeof(l->l_mouseevent.buffer)); +} + +int +LayProcessMouseSwitch(struct layer *l, int s) +{ + if ((l->l_mouseevent.start = s)) + { + l->l_mouseevent.len = 0; + } +} + -- cgit v1.2.1 From e8d36bf10b784da5d7ba9a503c77e2e4688c6cda Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 7 Dec 2009 22:01:08 -0500 Subject: Refresh cleverly to improve scrolling speed. This should fix a lot of complaints about slow scrolling in vertical splits. The idea is to update the display once at the end of a screen write, rather than a lot of time during the write, which was the root of the slowness. It is possible that LayPauseUpdateRegion needs to be called in a few more places, but this works for now for the tests I have done. --- src/layer.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index 8b94b99..2543527 100644 --- a/src/layer.c +++ b/src/layer.c @@ -96,6 +96,9 @@ int x, y; struct viewport *vp; int x2, y2; + if (l->l_pause.d) + return; + #ifdef HAVE_BRAILLE if (bd.bd_refreshing) return; @@ -143,6 +146,11 @@ struct mline *ol; if (n == 0) return; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -194,6 +202,11 @@ int bce; int ys2, ye2, xs2, xe2; if (n == 0) return; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, 0, l->l_width - 1, ys, ye); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -257,6 +270,11 @@ struct mline *ol; struct mchar *c2, cc; struct mline *rol; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, l->l_width - 1, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -314,6 +332,13 @@ int x, y; return; } #endif + + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, x, y, y); + return; + } + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) { display = cv->c_display; @@ -355,6 +380,12 @@ int x, y; return; } #endif + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, x + n - 1, y, y); + return; + } + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -415,6 +446,11 @@ int x, y; return; } #endif + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, x + n - 1, y, y); + return; + } len = strlen(s); if (len > n) len = n; @@ -467,6 +503,11 @@ struct mline *ol; xs = l->l_width - 1; if (xe >= l->l_width) xe = l->l_width - 1; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -511,6 +552,11 @@ int uself; xs = l->l_width - 1; if (xe >= l->l_width) xe = l->l_width - 1; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, ys, ye); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) { display = cv->c_display; @@ -580,6 +626,11 @@ int isblank; return; } #endif + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) { display = cv->c_display; @@ -656,6 +707,13 @@ int ins; int yy, y2, yy2, top2, bot2; int bce; + if (l->l_pause.d) + { + /* XXX: 'y'? */ + LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot); + return; + } + #ifdef COLOR bce = rend_getbg(c); #else @@ -1139,3 +1197,93 @@ LayProcessMouseSwitch(struct layer *l, int s) } } +void LayPause(layer, pause) +struct layer *layer; +int pause; +{ + struct canvas *cv; + struct display *olddisplay = display; + + pause = !!pause; + + if (layer->l_pause.d == pause) + return; + + if ((layer->l_pause.d = pause)) + { + /* Start pausing */ + layer->l_pause.top = layer->l_pause.bottom = + layer->l_pause.left = layer->l_pause.right = -1; + return; + } + + /* Unpause. So refresh the regions in the displays! */ + if (layer->l_pause.top == -1 && + layer->l_pause.bottom == -1 && + layer->l_pause.left == -1 && + layer->l_pause.right == -1) + return; + + for (cv = layer->l_cvlist; cv; cv = cv->c_lnext) + { + struct viewport *vp; + + display = cv->c_display; + + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + int xs = layer->l_pause.left + vp->v_xoff; + int xe = layer->l_pause.right + vp->v_xoff; + int ys = layer->l_pause.top + vp->v_yoff; + int ye = layer->l_pause.bottom + vp->v_yoff; + + if (xs < vp->v_xs) xs = vp->v_xs; + if (xe > vp->v_xe) xe = vp->v_xe; + if (ys < vp->v_ys) ys = vp->v_ys; + if (ye > vp->v_ye) ye = vp->v_ye; + + if (xs <= xe && ys <= ye) + RefreshArea(xs, ys, xe, ye, 0); + } + + if (cv == D_forecv) + { + int cx = layer->l_x + cv->c_xoff; + int cy = layer->l_y + cv->c_yoff; + + if (cx < cv->c_xs) cx = cv->c_xs; + if (cy < cv->c_ys) cy = cv->c_ys; + if (cx > cv->c_xe) cx = cv->c_xe; + if (cy > cv->c_ye) cy = cv->c_ye; + + GotoPos(cx, cy); + } + } + + olddisplay = display; +} + +void +LayPauseUpdateRegion(layer, xs, xe, ys, ye) +struct layer *layer; +int xs, xe; +int ys, ye; +{ + if (!layer->l_pause.d) + return; + + if (ye >= layer->l_height) + ye = layer->l_height - 1; + if (xe >= layer->l_width) + xe = layer->l_width - 1; + + if (layer->l_pause.top == -1 || layer->l_pause.top > ys) + layer->l_pause.top = ys; + if (layer->l_pause.bottom < ye) + layer->l_pause.bottom = ye; + if (layer->l_pause.left == -1 || layer->l_pause.left > xs) + layer->l_pause.left = xs; + if (layer->l_pause.right < xe) + layer->l_pause.right = xe; +} + -- cgit v1.2.1 From acd9b12b446f8baa673d928b4421948e07b7265e Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 8 Dec 2009 07:01:06 -0500 Subject: Remember to update the region containing the cursor. --- src/layer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index 2543527..067d2ef 100644 --- a/src/layer.c +++ b/src/layer.c @@ -97,7 +97,10 @@ int x, y; int x2, y2; if (l->l_pause.d) - return; + { + LayPauseUpdateRegion(l, x, x, y, y); + return; + } #ifdef HAVE_BRAILLE if (bd.bd_refreshing) -- cgit v1.2.1 From a6eea7b4d6dd3e4385919b4a50a58688f9a6b52b Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 24 Dec 2009 15:28:51 -0500 Subject: Re-optimize screen updates. In only the top line and the bottom line had to be updated, we were updating the entire region in between as well! This clearly is bad. So instead of doing that, just update the lines that need changing. Thanks to Chris Jones for reporting the bug. --- src/layer.c | 80 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 23 deletions(-) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index 067d2ef..c71c731 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1172,6 +1172,7 @@ ExitOverlayPage() ocv->c_lnext = cv; } oldlay->l_cvlist = 0; + LayerCleanupMemory(oldlay); free((char *)oldlay); LayRestore(); LaySetCursor(); @@ -1206,6 +1207,7 @@ int pause; { struct canvas *cv; struct display *olddisplay = display; + int line; pause = !!pause; @@ -1215,16 +1217,13 @@ int pause; if ((layer->l_pause.d = pause)) { /* Start pausing */ - layer->l_pause.top = layer->l_pause.bottom = - layer->l_pause.left = layer->l_pause.right = -1; + layer->l_pause.top = layer->l_pause.bottom = -1; return; } /* Unpause. So refresh the regions in the displays! */ if (layer->l_pause.top == -1 && - layer->l_pause.bottom == -1 && - layer->l_pause.left == -1 && - layer->l_pause.right == -1) + layer->l_pause.bottom == -1) return; for (cv = layer->l_cvlist; cv; cv = cv->c_lnext) @@ -1235,18 +1234,24 @@ int pause; for (vp = cv->c_vplist; vp; vp = vp->v_next) { - int xs = layer->l_pause.left + vp->v_xoff; - int xe = layer->l_pause.right + vp->v_xoff; - int ys = layer->l_pause.top + vp->v_yoff; - int ye = layer->l_pause.bottom + vp->v_yoff; - - if (xs < vp->v_xs) xs = vp->v_xs; - if (xe > vp->v_xe) xe = vp->v_xe; - if (ys < vp->v_ys) ys = vp->v_ys; - if (ye > vp->v_ye) ye = vp->v_ye; - - if (xs <= xe && ys <= ye) - RefreshArea(xs, ys, xe, ye, 0); + for (line = layer->l_pause.top; line <= layer->l_pause.bottom; line++) + { + int xs, xe; + + if (line + vp->v_yoff >= vp->v_ys && line + vp->v_yoff <= vp->v_ye && + ((xs = layer->l_pause.left[line]) >= 0) && + ((xe = layer->l_pause.right[line]) >= 0)) + { + xs += vp->v_xoff; + xe += vp->v_xoff; + + if (xs < vp->v_xs) xs = vp->v_xs; + if (xe > vp->v_xe) xe = vp->v_xe; + + if (xs <= xe) + RefreshLine(line + vp->v_yoff, xs, xe, 0); + } + } } if (cv == D_forecv) @@ -1263,6 +1268,8 @@ int pause; } } + for (line = layer->l_pause.top; line <= layer->l_pause.bottom; line++) + layer->l_pause.left[line] = layer->l_pause.right[line] = -1; olddisplay = display; } @@ -1274,7 +1281,6 @@ int ys, ye; { if (!layer->l_pause.d) return; - if (ye >= layer->l_height) ye = layer->l_height - 1; if (xe >= layer->l_width) @@ -1283,10 +1289,38 @@ int ys, ye; if (layer->l_pause.top == -1 || layer->l_pause.top > ys) layer->l_pause.top = ys; if (layer->l_pause.bottom < ye) - layer->l_pause.bottom = ye; - if (layer->l_pause.left == -1 || layer->l_pause.left > xs) - layer->l_pause.left = xs; - if (layer->l_pause.right < xe) - layer->l_pause.right = xe; + { + layer->l_pause.bottom = ye; + if (layer->l_pause.lines <= ye) + { + int o = layer->l_pause.lines; + layer->l_pause.lines = ye + 32; + layer->l_pause.left = realloc(layer->l_pause.left, sizeof(int) * layer->l_pause.lines); + layer->l_pause.right = realloc(layer->l_pause.right, sizeof(int) * layer->l_pause.lines); + while (o < layer->l_pause.lines) + { + layer->l_pause.left[o] = layer->l_pause.right[o] = -1; + o++; + } + } + } + + while (ys <= ye) + { + if (layer->l_pause.left[ys] == -1 || layer->l_pause.left[ys] > xs) + layer->l_pause.left[ys] = xs; + if (layer->l_pause.right[ys] < xe) + layer->l_pause.right[ys] = xe; + ys++; + } } +void +LayerCleanupMemory(layer) +struct layer *layer; +{ + if (layer->l_pause.left) + free(layer->l_pause.left); + if (layer->l_pause.right) + free(layer->l_pause.right); +} -- cgit v1.2.1 From 4f28ba8c8fd9032763eac42ed3591a6b2751f84c Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 26 Feb 2010 11:31:19 -0500 Subject: Some more fixes for the list management. Make sure the allocated memory is always freed. Also, do not reference freed memory. Thank you valgrind. --- src/layer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index c71c731..88d7360 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1121,7 +1121,11 @@ ExitOverlayPage() debug1("Exiting layer %#x\n", (unsigned int)flayer); oldlay = flayer; if (oldlay->l_data) - free(oldlay->l_data); + { + if (oldlay->l_layfn->lf_LayFree) + LayFree(oldlay->l_data); + free(oldlay->l_data); + } p = Layer2Window(flayer); -- cgit v1.2.1 From da8e87d6505fb33ed131144a33af88c6d0dc96fd Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 3 Mar 2010 11:18:55 -0500 Subject: Sanity check line numbers for non-negative value. It looks like 'ys' can be negative at times, which results in invalid memory reads, and possibly writes. Valgrind log from Friedrich Delgado Friedrichs in savannah bug #29050. --- src/layer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index 88d7360..9c1fe34 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1285,6 +1285,8 @@ int ys, ye; { if (!layer->l_pause.d) return; + if (ys < 0) + ys = 0; if (ye >= layer->l_height) ye = layer->l_height - 1; if (xe >= layer->l_width) -- cgit v1.2.1 From 30be3fc3a160a0a8c7c1d7190dbc0177f2d9e34f Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 4 Mar 2010 15:39:51 -0500 Subject: Use intelligent screen refresh only in split regions. When there are no splits, pausing output on a layer isn't necessary, since it doesn't hit the performance. But we do want to continue to pause output when there are splits to improve scrolling performance. Fixes savannah bug #29055. Thanks to Kazuo Teramoto for reporting the bug and testing the fix. --- src/layer.c | 100 ++++++++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 56 deletions(-) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index 9c1fe34..34cd6a3 100644 --- a/src/layer.c +++ b/src/layer.c @@ -86,6 +86,12 @@ int off; # define RECODE_MLINE(ml) (ml) #endif +#define FOR_EACH_UNPAUSED_CANVAS(l, fn) for (cv = (l)->l_cvlist; cv; cv = cv->c_lnext) \ + { \ + if ((l)->l_pause.d && cv->c_slorient) \ + continue; \ + fn \ + } void LGotoPos(l, x, y) @@ -97,16 +103,13 @@ int x, y; int x2, y2; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x, y, y); - return; - } + LayPauseUpdateRegion(l, x, x, y, y); #ifdef HAVE_BRAILLE if (bd.bd_refreshing) return; #endif - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -134,6 +137,7 @@ int x, y; break; } } + ); } void @@ -150,11 +154,8 @@ struct mline *ol; if (n == 0) return; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, xs, xe, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, xs, xe, y, y); + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -191,6 +192,7 @@ struct mline *ol; if (xs2 <= xe2) RefreshArea(xs2, y2, xe2, y2, 1); } + ); } void @@ -206,11 +208,8 @@ int bce; if (n == 0) return; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, 0, l->l_width - 1, ys, ye); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, 0, l->l_width - 1, ys, ye); + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { xs2 = vp->v_xoff; @@ -258,6 +257,7 @@ int bce; if (ys2 <= ye2) RefreshArea(xs2, ys2, xe2, ye2, 1); } + ); } void @@ -274,11 +274,8 @@ struct mline *ol; struct mline *rol; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, l->l_width - 1, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, x, l->l_width - 1, y, y); + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -317,6 +314,7 @@ struct mline *ol; if (f) RefreshArea(xs2, y2, xs2, y2, 1); } + ); } void @@ -337,12 +335,9 @@ int x, y; #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x, y, y); - return; - } + LayPauseUpdateRegion(l, x, x, y, y); - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -359,6 +354,7 @@ int x, y; break; } } + ); } void @@ -384,12 +380,9 @@ int x, y; } #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x + n - 1, y, y); - return; - } + LayPauseUpdateRegion(l, x, x + n - 1, y, y); - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -425,6 +418,7 @@ int x, y; while (xs2++ <= xe2) PUTCHARLP(*s2++); } + ); } void @@ -450,14 +444,11 @@ int x, y; } #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x + n - 1, y, y); - return; - } + LayPauseUpdateRegion(l, x, x + n - 1, y, y); len = strlen(s); if (len > n) len = n; - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -489,6 +480,7 @@ int x, y; while (xs2++ <= xe2) PUTCHARLP(' '); } + ); } void @@ -507,11 +499,8 @@ struct mline *ol; if (xe >= l->l_width) xe = l->l_width - 1; if (l->l_pause.d) - { LayPauseUpdateRegion(l, xs, xe, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { xs2 = xs + vp->v_xoff; @@ -530,6 +519,7 @@ struct mline *ol; continue; ClearLine(ol ? mloff(RECODE_MLINE(ol), -vp->v_xoff) : (struct mline *)0, y2, xs2, xe2, bce); } + ); } void @@ -556,11 +546,8 @@ int uself; if (xe >= l->l_width) xe = l->l_width - 1; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, xs, xe, ys, ye); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, xs, xe, ys, ye); + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -610,6 +597,7 @@ int uself; #endif } } + ); } void @@ -630,11 +618,8 @@ int isblank; } #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, xs, xe, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, xs, xe, y, y); + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -658,6 +643,7 @@ int isblank; DisplayLine(isblank ? &mline_blank : &mline_null, mloff(RECODE_MLINE(ml), -vp->v_xoff), y2, xs2, xe2); } } + ); } void @@ -711,11 +697,8 @@ int ins; int bce; if (l->l_pause.d) - { - /* XXX: 'y'? */ - LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot); - return; - } + /* XXX: 'y'? */ + LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot); #ifdef COLOR bce = rend_getbg(c); @@ -729,7 +712,7 @@ int ins; /* cursor after wrapping */ yy = y == l->l_height - 1 ? y : y + 1; - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { y2 = 0; /* gcc -Wall */ display = cv->c_display; @@ -769,12 +752,13 @@ int ins; WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, y2, vp->v_xoff, -1, vp->v_xoff + l->l_width - 1, -1, ins); } } + ); } else { /* hard case: scroll up*/ - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -822,6 +806,7 @@ int ins; WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, bot2, vp->v_xoff, top2, vp->v_xoff + l->l_width - 1, bot2, ins); } } + ); } } @@ -1234,6 +1219,9 @@ int pause; { struct viewport *vp; + if (!cv->c_slorient) + continue; /* Wasn't split, so already updated. */ + display = cv->c_display; for (vp = cv->c_vplist; vp; vp = vp->v_next) -- cgit v1.2.1 From eb4cea75f23df90ac955e001fc5c3e54062d97cb Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 8 Mar 2010 10:01:26 -0500 Subject: Fix refresh when double-cell characters end a line Double cell characters that end a line are not properly displayed when there are split regions. Takeshi Banse detected the problem and a fix for it in Savannag bug #29106. A better fix for this was applied in the unicode++ branch, but that won't work in 'master'. This is approximately the same fix, in a slightly different way. --- src/layer.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/layer.c') diff --git a/src/layer.c b/src/layer.c index 34cd6a3..b7cea6a 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1197,6 +1197,7 @@ int pause; struct canvas *cv; struct display *olddisplay = display; int line; + struct win *win; pause = !!pause; @@ -1215,6 +1216,11 @@ int pause; layer->l_pause.bottom == -1) return; + if (layer->l_layfn == &WinLf) /* Currently, this will always be the case! */ + win = layer->l_data; + else + win = NULL; + for (cv = layer->l_cvlist; cv; cv = cv->c_lnext) { struct viewport *vp; @@ -1240,6 +1246,15 @@ int pause; if (xs < vp->v_xs) xs = vp->v_xs; if (xe > vp->v_xe) xe = vp->v_xe; +#if defined(DW_CHARS) && defined(UTF8) + if (layer->l_encoding == UTF8 && xe < vp->v_xe && win) + { + struct mline *ml = win->w_mlines + line; + if (dw_left(ml, xe, UTF8)) + xe++; + } +#endif + if (xs <= xe) RefreshLine(line + vp->v_yoff, xs, xe, 0); } -- cgit v1.2.1