zsh-workers
 help / color / mirror / code / Atom feed
* [PATCH] Zcurses sub-command "resize_term"
@ 2017-03-04 15:53 Sebastian Gniazdowski
  2017-03-04 18:35 ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Sebastian Gniazdowski @ 2017-03-04 15:53 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]

Hello,
thought I need that, turned out it isn't exactly needed. "zcurses end;
zcurses refresh;" accomplishes the same goal. More, 5 system
configurations confirmed that endwin() before resize_term(); is needed,
otherwise moves start to be inaccurate (randomly ignore x position). I
think it's a bug in ncurses. Tested OS X ncurses 5.4, Homebrew ncursesw
6.0-2, Arch Linux ncursesw 6.0, Ubuntu 14.04 ncurses 5.9, FreeBSD
ncursesw.so.8.

So why a new sub-command? For versatility. Some edge situations, future
ncurses versions, PDCurses, etc. The sub-command will secure edge cases
and new situations.

If it has "endwin" third param, it does the needed endwin() and refresh.
If "nosave" is used, curses terminal state will not be re-read into
internal variable. I can imagine some edge case for that.
"endwin_nosave" can be used for both effects.

To test resize_term extension availability, 0 for height and width can
be given, $? == 0 or $? == 2 are possible results.

-- 
  Sebastian Gniazdowski
  psprint3@fastmail.com

[-- Attachment #2: zcurses_resize_term.diff --]
[-- Type: text/plain, Size: 5751 bytes --]

diff --git a/Doc/Zsh/mod_curses.yo b/Doc/Zsh/mod_curses.yo
index 72dc409..82103e4 100644
--- a/Doc/Zsh/mod_curses.yo
+++ b/Doc/Zsh/mod_curses.yo
@@ -27,7 +27,8 @@ xitem(tt(zcurses) tt(scroll) var(targetwin) [ tt(on) | tt(off) | [tt(+)|tt(-)]va
 xitem(tt(zcurses) tt(input) var(targetwin) [ var(param) [ var(kparam) [ var(mparam) ] ] ])
 xitem(tt(zcurses) tt(mouse) [ tt(delay) var(num) | [tt(+)|tt(-)]tt(motion) ])
 xitem(tt(zcurses) tt(timeout) var(targetwin) var(intval))
-item(tt(zcurses) tt(querychar) var(targetwin) [ var(param) ])(
+xitem(tt(zcurses) tt(querychar) var(targetwin) [ var(param) ])
+item(tt(zcurses) tt(resize_term) var(height) var(width) [ tt(endwin) | tt(nosave) | tt(endwin_nosave) ])(
 Manipulate curses windows.  All uses of this command should be
 bracketed by `tt(zcurses init)' to initialise use of curses, and
 `tt(zcurses end)' to end it; omitting `tt(zcurses end)' can cause
@@ -211,6 +212,21 @@ second is the color pair in the usual var(fg_col)tt(/)var(bg_col)
 notation, or tt(0) if color is not supported.  Any attributes other than
 color that apply to the character, as set with the subcommand tt(attr),
 appear as additional elements.
+
+The subcommand tt(resize_term) resizes tt(stdscr) and all windows to
+given dimensions (windows that stick out from the new dimensions are
+resized down). The underlying curses extension (tt(resize_term call))
+can be unavailable. To verify, zeroes can be used for var(height) and
+var(width). If the result of the subcommand is tt(0), resize_term is
+available (tt(2) otherwise). Tests show that resizing can be normally
+accomplished by calling tt(zcurses end) and tt(zcurses refresh). The
+tt(resize_term) subcommand is provided for versatility. Multiple
+system configurations have been checked and tt(zcurses end) and
+tt(zcurses refresh) are still needed for correct terminal state after
+resize. To invoke them with tt(resize_term), use var(endwin) argument.
+Using var(nosave) argument will cause new terminal state to not be
+saved internally by tt(zcurses). This is also provided for versatility
+and should normally be not needed.
 )
 enditem()
 
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c
index d9c19bd..dcb7ed2 100644
--- a/Src/Modules/curses.c
+++ b/Src/Modules/curses.c
@@ -1490,6 +1490,74 @@ zccmd_touch(const char *nam, char **args)
     return ret;
 }
 
+static int
+zccmd_resize_term(const char *nam, char **args)
+{
+#ifdef HAVE_RESIZE_TERM
+    int y, x, do_endwin=0, do_save=1;
+    LinkNode stdscr_win = zcurses_getwindowbyname("stdscr");
+
+    if (stdscr_win) {
+        y = atoi(args[0]);
+        x = atoi(args[1]);
+        if (args[2]) {
+            if (0 == strcmp(args[2], "endwin")) {
+                do_endwin=1;
+            } else if (0 == strcmp(args[2], "endwin_nosave")) {
+                do_endwin=1;
+                do_save=0;
+            } else if (0 == strcmp(args[2], "nosave")) {
+                do_save=0;
+            } else {
+                zwarnnam(nam, "`resize_term' expects `endwin', `nosave' or `endwin_nosave' for third argument, if given");
+            }
+        }
+
+        if (y == 0 && x == 0 && args[2] == NULL) {
+            // Special case to just test that curses has resize_term. #ifdef
+            // HAVE_RESIZE_TERM will result in return value 2 if resize_term
+            // is not available.
+            return 0;
+        } else {
+            // Without this call some window moves are innacurate. Tested on
+            // OS X ncurses 5.4, Homebrew ncursesw 6.0-2, Arch Linux ncursesw
+            // 6.0, Ubuntu 14.04 ncurses 5.9, FreeBSD ncursesw.so.8
+            //
+            // On the other hand, the whole resize goal can be (from tests)
+            // accomplished by calling endwin and refresh. But to secure any
+            // future problems, resize_term is provided, and it is featured
+            // with endwin, so that users have multiple options.
+            if (do_endwin) {
+                endwin();
+            }
+
+            if( resize_term( y, x ) == OK ) {
+                // Things work without this, but we need to get out from
+                // endwin (i.e. call refresh), and in theory store new
+                // curses state (the resize might have changed it), which
+                // should be presented to terminal only after refresh.
+                if (do_endwin || do_save) {
+                    ZCWin w;
+                    w = (ZCWin)getdata(stdscr_win);
+                    wnoutrefresh(w->win);
+                    doupdate();
+                }
+
+                if (do_save) {
+                    gettyinfo(&curses_tty_state);
+                }
+                return 0;
+            } else {
+                return 1;
+            }
+        }
+    } else {
+        return 1;
+    }
+#else
+    return 2;
+#endif
+}
 
 /*********************
   Main builtin handler
@@ -1523,6 +1591,7 @@ bin_zcurses(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	{"mouse", zccmd_mouse, 0, -1},
 	{"querychar", zccmd_querychar, 1, 2},
 	{"touch", zccmd_touch, 1, -1},
+	{"resize_term", zccmd_resize_term, 2, 3},
 	{NULL, (zccmd_t)0, 0, 0}
     };
 
diff --git a/configure.ac b/configure.ac
index 0551a69..911cc45 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1309,7 +1309,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
 	       putenv getenv setenv unsetenv xw\
 	       brk sbrk \
 	       pathconf sysconf \
-	       tgetent tigetflag tigetnum tigetstr setupterm initscr \
+	       tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \
 	       getcchar setcchar waddwstr wget_wch win_wch use_default_colors \
 	       pcre_compile pcre_study pcre_exec \
 	       nl_langinfo \

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Zcurses sub-command "resize_term"
  2017-03-04 15:53 [PATCH] Zcurses sub-command "resize_term" Sebastian Gniazdowski
@ 2017-03-04 18:35 ` Bart Schaefer
  2017-03-04 19:19   ` Sebastian Gniazdowski
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2017-03-04 18:35 UTC (permalink / raw)
  To: zsh-workers

On Mar 4,  7:53am, Sebastian Gniazdowski wrote:
} Subject: [PATCH] Zcurses sub-command "resize_term"
}
} So why a new sub-command? For versatility. Some edge situations, future
} ncurses versions, PDCurses, etc. The sub-command will secure edge cases
} and new situations.

Minor quibble:  Is there anything other than the terminal that you would
ever resize?  If not, why is the command not "zcurses resize" to match
all the other subcommands, which are always a single word with no
underscores?


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Zcurses sub-command "resize_term"
  2017-03-04 18:35 ` Bart Schaefer
@ 2017-03-04 19:19   ` Sebastian Gniazdowski
  0 siblings, 0 replies; 3+ messages in thread
From: Sebastian Gniazdowski @ 2017-03-04 19:19 UTC (permalink / raw)
  To: Bart Schaefer, zsh-workers

[-- Attachment #1: Type: text/plain, Size: 815 bytes --]

On Sat, Mar 4, 2017, at 10:35 AM, Bart Schaefer wrote:
> Minor quibble:  Is there anything other than the terminal that you would
> ever resize?  If not, why is the command not "zcurses resize" to match
> all the other subcommands, which are always a single word with no
> underscores?

Wanted to be strict. For example I've found the way to resize with
current zcurses (end+refresh) by accident because before I was testing
end+init – names suggested that. Plus one has to be aware that endwin()
is just hiding of curses from terminal, not a shutdown. However the own
names that zcurses have are indeed nice, and submitted documentation
states that it's resize_term that's called, so I've updated the patch
renaming sub-command to "resize".

-- 
  Sebastian Gniazdowski
  psprint3@fastmail.com

[-- Attachment #2: zcurses_resize_term2.diff --]
[-- Type: text/plain, Size: 5712 bytes --]

diff --git a/Doc/Zsh/mod_curses.yo b/Doc/Zsh/mod_curses.yo
index 72dc409..6e4831a 100644
--- a/Doc/Zsh/mod_curses.yo
+++ b/Doc/Zsh/mod_curses.yo
@@ -27,7 +27,8 @@ xitem(tt(zcurses) tt(scroll) var(targetwin) [ tt(on) | tt(off) | [tt(+)|tt(-)]va
 xitem(tt(zcurses) tt(input) var(targetwin) [ var(param) [ var(kparam) [ var(mparam) ] ] ])
 xitem(tt(zcurses) tt(mouse) [ tt(delay) var(num) | [tt(+)|tt(-)]tt(motion) ])
 xitem(tt(zcurses) tt(timeout) var(targetwin) var(intval))
-item(tt(zcurses) tt(querychar) var(targetwin) [ var(param) ])(
+xitem(tt(zcurses) tt(querychar) var(targetwin) [ var(param) ])
+item(tt(zcurses) tt(resize) var(height) var(width) [ tt(endwin) | tt(nosave) | tt(endwin_nosave) ])(
 Manipulate curses windows.  All uses of this command should be
 bracketed by `tt(zcurses init)' to initialise use of curses, and
 `tt(zcurses end)' to end it; omitting `tt(zcurses end)' can cause
@@ -211,6 +212,21 @@ second is the color pair in the usual var(fg_col)tt(/)var(bg_col)
 notation, or tt(0) if color is not supported.  Any attributes other than
 color that apply to the character, as set with the subcommand tt(attr),
 appear as additional elements.
+
+The subcommand tt(resize) resizes tt(stdscr) and all windows to given
+dimensions (windows that stick out from the new dimensions are resized
+down). The underlying curses extension (tt(resize_term call)) can be
+unavailable. To verify, zeroes can be used for var(height) and
+var(width). If the result of the subcommand is tt(0), resize_term is
+available (tt(2) otherwise). Tests show that resizing can be normally
+accomplished by calling tt(zcurses end) and tt(zcurses refresh). The
+tt(resize) subcommand is provided for versatility. Multiple system
+configurations have been checked and tt(zcurses end) and tt(zcurses
+refresh) are still needed for correct terminal state after resize. To
+invoke them with tt(resize), use var(endwin) argument.  Using
+var(nosave) argument will cause new terminal state to not be saved
+internally by tt(zcurses). This is also provided for versatility and
+should normally be not needed.
 )
 enditem()
 
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c
index d9c19bd..a60dfcb 100644
--- a/Src/Modules/curses.c
+++ b/Src/Modules/curses.c
@@ -1490,6 +1490,74 @@ zccmd_touch(const char *nam, char **args)
     return ret;
 }
 
+static int
+zccmd_resize(const char *nam, char **args)
+{
+#ifdef HAVE_RESIZE_TERM
+    int y, x, do_endwin=0, do_save=1;
+    LinkNode stdscr_win = zcurses_getwindowbyname("stdscr");
+
+    if (stdscr_win) {
+        y = atoi(args[0]);
+        x = atoi(args[1]);
+        if (args[2]) {
+            if (0 == strcmp(args[2], "endwin")) {
+                do_endwin=1;
+            } else if (0 == strcmp(args[2], "endwin_nosave")) {
+                do_endwin=1;
+                do_save=0;
+            } else if (0 == strcmp(args[2], "nosave")) {
+                do_save=0;
+            } else {
+                zwarnnam(nam, "`resize' expects `endwin', `nosave' or `endwin_nosave' for third argument, if given");
+            }
+        }
+
+        if (y == 0 && x == 0 && args[2] == NULL) {
+            // Special case to just test that curses has resize_term. #ifdef
+            // HAVE_RESIZE_TERM will result in return value 2 if resize_term
+            // is not available.
+            return 0;
+        } else {
+            // Without this call some window moves are innacurate. Tested on
+            // OS X ncurses 5.4, Homebrew ncursesw 6.0-2, Arch Linux ncursesw
+            // 6.0, Ubuntu 14.04 ncurses 5.9, FreeBSD ncursesw.so.8
+            //
+            // On the other hand, the whole resize goal can be (from tests)
+            // accomplished by calling endwin and refresh. But to secure any
+            // future problems, resize_term is provided, and it is featured
+            // with endwin, so that users have multiple options.
+            if (do_endwin) {
+                endwin();
+            }
+
+            if( resize_term( y, x ) == OK ) {
+                // Things work without this, but we need to get out from
+                // endwin (i.e. call refresh), and in theory store new
+                // curses state (the resize might have changed it), which
+                // should be presented to terminal only after refresh.
+                if (do_endwin || do_save) {
+                    ZCWin w;
+                    w = (ZCWin)getdata(stdscr_win);
+                    wnoutrefresh(w->win);
+                    doupdate();
+                }
+
+                if (do_save) {
+                    gettyinfo(&curses_tty_state);
+                }
+                return 0;
+            } else {
+                return 1;
+            }
+        }
+    } else {
+        return 1;
+    }
+#else
+    return 2;
+#endif
+}
 
 /*********************
   Main builtin handler
@@ -1523,6 +1591,7 @@ bin_zcurses(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	{"mouse", zccmd_mouse, 0, -1},
 	{"querychar", zccmd_querychar, 1, 2},
 	{"touch", zccmd_touch, 1, -1},
+	{"resize", zccmd_resize, 2, 3},
 	{NULL, (zccmd_t)0, 0, 0}
     };
 
diff --git a/configure.ac b/configure.ac
index 0551a69..911cc45 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1309,7 +1309,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
 	       putenv getenv setenv unsetenv xw\
 	       brk sbrk \
 	       pathconf sysconf \
-	       tgetent tigetflag tigetnum tigetstr setupterm initscr \
+	       tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \
 	       getcchar setcchar waddwstr wget_wch win_wch use_default_colors \
 	       pcre_compile pcre_study pcre_exec \
 	       nl_langinfo \

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-03-04 19:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-04 15:53 [PATCH] Zcurses sub-command "resize_term" Sebastian Gniazdowski
2017-03-04 18:35 ` Bart Schaefer
2017-03-04 19:19   ` Sebastian Gniazdowski

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).