Reputation: 57
I'm making a program with ncurses that splits the screen into two windows. The top screen can accept input, and by pressing '#' it will move all the text down the the bottom window and wipe the top window. In my code I'm trying to use copywin() to replace the bottom window, but it will not paste the wording in the second window. This is what I have...
#include <ncurses.h>
int main(int argc, char *argv[])
{
// Declare variables for windows and sizes
WINDOW *top_win, *bottom_win;
int maxx, maxy, halfy, flag = 0, ch;
// Start curses
initscr();
noecho();
refresh();
// get the max x's and y's
getmaxyx(stdscr, maxy, maxx);
halfy = maxy >> 1;
// Start color
start_color();
init_pair(1, COLOR_BLACK, COLOR_WHITE);
init_pair(2, COLOR_WHITE, COLOR_CYAN);
init_pair(3, COLOR_RED, COLOR_WHITE);
// Make windows
top_win = newwin(halfy, maxx, 0, 0);
wbkgd(top_win, COLOR_PAIR(1));
wrefresh(top_win);
bottom_win = newwin(halfy, maxx, halfy, 0);
wbkgd(bottom_win, COLOR_PAIR(2));
wrefresh(bottom_win);
// Allow functions keys
keypad(top_win, TRUE);
keypad(bottom_win, TRUE);
// while loop to get input
while((ch = getch()) != '`')
{
if(ch == '@')
{
if(flag == 1)
{
flag = 0;
}
else
{
flag = 1;
}
}
else if(ch == '#')
{
//waddstr(bottom_win, "testing");
copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE);
//overwrite(top_win, bottom_win);
//werase(top_win);
}
else if(flag != 1)
{
waddch(top_win, ch | COLOR_PAIR(1));
}
else if(flag == 1)
{
waddch(top_win, ch | COLOR_PAIR(3));
}
wrefresh(top_win);
wrefresh(bottom_win);
}
// end curses
delwin(top_win);
delwin(bottom_win);
endwin();
return 0;
}
I know I can print to the window using the '#' character because of my commented out, testing statement. I've also just tried using overwrite(), but that didn't work either. Am I simply getting the arguments mixed up, or is it something else? Any Ideas? Thank you in advance!
Upvotes: 2
Views: 444
Reputation: 54515
copywin
checks the given rows/columns, and decides that your destination rectangle doesn't lie completely within the destination window. Here's a quick fix for your program:
--- foo.c.orig 2017-02-13 16:13:12.000000000 -0500
+++ foo.c 2017-02-13 16:30:18.037987489 -0500
@@ -51,7 +51,7 @@
else if(ch == '#')
{
//waddstr(bottom_win, "testing");
- copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE);
+ copywin(top_win, bottom_win, 0, 0, 0, 0, halfy - 1, maxx - 1, TRUE);
//overwrite(top_win, bottom_win);
//werase(top_win);
}
@@ -73,4 +73,3 @@
endwin();
return 0;
}
Rows and columns are numbered from zero through the last row/column (which is one less than the window size), so I subtracted one from the dmaxrow and dmaxcol parameters. The fifth parameter dminrow was past the bottom of the window.
ncurses checks the parameters. Regarding compatibility and portability, running the same program with Solaris curses (changing "ncurses.h" to "curses.h") dumps core.
The manual page could be improved, but it's clear enough regarding colors:
only text where the two windows overlap is copied
Upvotes: 3
Reputation: 753785
I don't have a good explanation for why it works, but as long as xoff
and yoff
are at least 1
in the code below, the data from the upper window is copied to the lower window OK (and cleared from the upper window). The colour isn't copied. If either offset is 0, the data is not copied. The string testing
is added at the top-left of the lower window — it can be omitted and the copied material is still OK.
#include <ncurses.h>
int main(void)
{
// Declare variables for windows and sizes
WINDOW *top_win, *bottom_win;
int maxx, maxy, halfy, flag = 0, ch;
// Start curses
initscr();
noecho();
refresh();
// get the max x's and y's
getmaxyx(stdscr, maxy, maxx);
halfy = maxy >> 1;
// Start color
start_color();
init_pair(1, COLOR_BLACK, COLOR_WHITE);
init_pair(2, COLOR_WHITE, COLOR_CYAN);
init_pair(3, COLOR_RED, COLOR_WHITE);
// Make windows
top_win = newwin(halfy, maxx, 0, 0);
wbkgd(top_win, COLOR_PAIR(1));
wrefresh(top_win);
bottom_win = newwin(halfy, maxx, halfy, 0);
wbkgd(bottom_win, COLOR_PAIR(2));
wrefresh(bottom_win);
// Allow functions keys
// keypad(top_win, TRUE);
// keypad(bottom_win, TRUE);
// while loop to get input
int xoff = 1;
int yoff = 1;
while ((ch = getch()) != '`')
{
if (ch == '@')
{
if (flag == 1)
{
flag = 0;
}
else
{
flag = 1;
}
}
else if (ch == '#')
{
waddstr(bottom_win, "testing");
// copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE);
copywin(top_win, bottom_win, 0, 0, yoff, xoff, halfy-yoff, maxx-xoff, TRUE);
// overwrite(top_win, bottom_win);
werase(top_win);
}
else if (flag != 1)
{
waddch(top_win, ch | COLOR_PAIR(1));
}
else if (flag == 1)
{
waddch(top_win, ch | COLOR_PAIR(3));
}
wrefresh(top_win);
wrefresh(bottom_win);
}
// end curses
delwin(top_win);
delwin(bottom_win);
endwin();
return 0;
}
Testing on Mac running macOS Sierra 10.12.3 with GCC 6.3.0, using the local -lncurses
library.
Upvotes: 1