LINUX.ORG.RU

ncurses & getch


0

0

getch() возвращает -1.

Вот так делаю:
int ch;

initscr();  - проходит
noecho();
cbreak();

while((ch = getch) != 'q') {
   switch(ch) {
     case 'a':
.......................
.......................
     default: printw("%d", ch); = -1
Что делать ?
anonymous

Ответ на: комментарий от anonymous

а как тебе это:

man getch:

In no-delay mode, if no input is waiting, the value ERR is returned.

man cbreak:

The cbreak routine disables line buffering and erase/kill character - processing (interrupt and flow control characters are unaffected), making characters typed by the user immediately available to the program.

cvv ★★★★★
()

> while((ch = getch) != 'q') {

Что, правда так написано?

anonymous
()
Ответ на: комментарий от cvv

> а как тебе это:

Мне это нормально :) читал

А как врубить delay mode ? Нужно чтоб на getch() стопорилось все и ожидало ввода символа, а после ввода чтоб не нуженн был Enter, а сразу символ читался.

anonymous
()
Ответ на: комментарий от cvv

> а ещё надо обратить внимание на
> int nodelay(WINDOW *win, bool bf); 

Обратил :)

nocbreak();
nodelay(win, FALSE); 

getch()  (пробовал и wgetch(win))

не тормозится - начинает гнать букву 'a' почему-то ...

anonymous
()
Ответ на: комментарий от anonymous

>nodelay(win, FALSE);

окно то?

>не тормозится - начинает гнать букву 'a' почему-то ...

хм

а если ещё дёргнуть timeout(-1); ?????

cvv ★★★★★
()
Ответ на: комментарий от anonymous

Еще один момент:
getch() я вызываю в процессе, полученном forc->exec
Может в этом загвоздка ?

в родителе сделал wait(0); - ждет. Вроде мешать не как не должен ?
Если запускать процесс из коммандной строки - то вроде ... заработало!!!

Значит дело в forc->exec ? Вроде бы не должно.

anonymous
()
Ответ на: комментарий от anonymous

>Значит дело в forc->exec ? Вроде бы не должно.

оно самое

не связывайся в родительском процессе с curses вообще. всё в доченрнем.

как заставить curses пережить fork я не знаю.

cvv ★★★★★
()
Ответ на: комментарий от cvv

а вообще в том месте где два процесса лезут на один терминал расположена такая куча граблей что если вам плятят менее 500$ то пусть разгребают её сами.

cvv ★★★★★
()
Ответ на: комментарий от cvv

> не связывайся в родительском процессе с curses вообще. всё в 
> доченрнем.

Так я curses в дочернем и вызываю. Родительский ждет по wait(0);

anonymous
()
Ответ на: комментарий от anonymous

>Так я curses в дочернем и вызываю. Родительский ждет по wait(0);

а шо ты тогда делаеш??

мож ты с setsid() связался?

а может с setpgid() или setpgrp() ?

тоесть если при непосредственном запуске работает а через форк - нет, особенно если в паренте не трогаеш curses.

ты уверен что не трогаеш stdio вообще? мож тебе надо непосредственно перед форком сделать fflush(NULL)?

cvv ★★★★★
()
Ответ на: комментарий от cvv

> мож ты с setsid() связался?

Пробовал и сним :) Экспериментировал. Сейчас не использую.

> ты уверен что не трогаеш stdio вообще?

В дочернем убил как класс... В паренте - есть.

> мож тебе надо непосредственно перед форком сделать fflush(NULL)?

попробую...

anonymous
()
Ответ на: комментарий от anonymous

> попробую...

Попробовал... Болт...
Не понятно, ведь вывод на экран всякими curses'кими printw, waddstr 
и т.д. есть, все нормально...

anonymous
()
Ответ на: комментарий от anonymous

Попробуй сделать простую тестовую программку с форком, если работает, то причины нужно искать где-то в твоем родительском процессе.
У меня вот такой примерчик завалялся (все работает):

#include <sys/types.h> // fork(2)
#include <unistd.h> // fork(2)

#include <sys/types.h> // wait(2)
#include <sys/wait.h> // wait(2)

//#include <stdlib.h>
#include <string.h> // strerror(3)
#include <stdio.h> // sprintf(3), printf(3)
#include <errno.h> // errno
#include <curses.h> // CURSES routines

#define PROMPT_STRING "press ESC to exit or any key to view key code> "

int main (int argc, char** argv)
{
switch (fork () )
{
case -1: printf ("Fork error: %s\n", strerror (errno) );
return 1;
case 0: break;
default:
wait(0);
printf ("Child terminated.\n");
return 0;
}

/* Init curses library
*/
initscr ();
cbreak ();
noecho ();
nonl ();
keypad (stdscr, TRUE);
meta (stdscr, TRUE);

/* clear and flush screen
*/
clear ();

int ch = 0;
char str [256];

do
{
if (ch > 0)
{
if (ch <= ' ' || (ch > 'Z' && ch > 'z'))
sprintf (str, " symbol is BLANK or SPEC, code is (%d) ", ch);
else
sprintf (str, " symbol is '%c', code is (%d) ", ch, ch);

move (LINES / 2 + 2, (COLS - strlen (str)) / 2);
addstr (str);
}

move (LINES - 1, 0);
addstr (PROMPT_STRING);

} while ((ch = getch ()) != 27);

endwin ();

return 0;
}

romanSA
()
Ответ на: комментарий от romanSA

Это похоже я тормоз :) У меня в паренте read(0,...) был, вот он все
и портил. Как мне ща его влияние ликвидировать, как-то через dup2
по-моему. Подскажите, а то башка уже не варит совсем.

anonymous
()
Ответ на: комментарий от anonymous

А зачем dup2()?
Если тебе всн равно какой будет дескриптор, то можно пользовать dup():

Т.е. в родительском процессе:

newfd = dup(0);
...
read(newfd, ...);

romanSA
()
Ответ на: комментарий от anonymous

Проблема может бать в следующем:

aaa < file - это запуск парента
В нем

read(0, buff, SIZE);

Так вот - я точно не знаю размер данных, поэтому SIZE - максимально 
возможный, например 100 байт, а получил 50. Вот наверное это и забивает
мне стандартный ввод. Как его очистить ?

anonymous
()
Ответ на: комментарий от anonymous

>Это похоже я тормоз :) У меня в паренте read(0,...) был, вот он все и портил.

>Как мне ща его влияние ликвидировать,

всё чтение завершить ДО fork-a. никаких read(0,...) после форка. воообще. до завершения child

>как-то через dup2 по-моему.

это не поможет никаким боком

cvv ★★★★★
()
Ответ на: комментарий от anonymous

>Проблема может бать в следующем:

>aaa < file - это запуск парента

>В нем

>read(0, buff, SIZE);

приехали. при таких шутках у вас вообще никто никогда не заработает.

читаем маны и мануалы на curses и не занимаемся ерундой

cvv ★★★★★
()
Ответ на: комментарий от cvv

> всё чтение завершить ДО fork-a. никаких read(0,...) после форка. 
> воообще. до завершения child

Вот втом-то и дело, что read(0,...) я делаю до fork'a, но запрошенное
количество данных на чтение превышает реально полученное кол-во.
Т.е. read читает данных сколько получил и бежит дальше, а запрос еще
наверное остается. Вот он и мешает вводу в дочернем...

anonymous
()
Ответ на: комментарий от anonymous

>Вот втом-то и дело, что read(0,...) я делаю до fork'a, но запрошенное количество данных на чтение превышает реально полученное кол-во.

ну и что?

>Т.е. read читает данных сколько получил и бежит дальше,

ну и кто бежит дальше??

>а запрос еще наверное остается. Вот он и мешает вводу в дочернем...

вы что aio пользуете или влом доки на curses читать????

ps: curses не понимает пайпы, которые вы ей суёте

cvv ★★★★★
()
Ответ на: комментарий от cvv

> вы что aio пользуете или влом доки на curses читать????

Да нет, curses к пайпам отношения не имел. Это парент брал по пайпу
инфу, а уж потом запускал процесс с curses. Но всеравно этот пайп
мешал curses. Ща пайп убил и все хорошо. Я блин просто про этот пайп
забыл совсем. Но зато выяснилось, что fork и exec не мешают curses.
Всем спасибо, особенно cvv :)

anonymous
()
Ответ на: комментарий от anonymous

>Да нет, curses к пайпам отношения не имел.

имел, иначе бы при его ликвидации глюки остались на месте

а вообще-то вам бы стивенса почитать

>Это парент брал по пайпу инфу, а уж потом запускал процесс с curses.

>Но всеравно этот пайп мешал curses. Ща пайп убил и все хорошо.

cvv ★★★★★
()
Ответ на: комментарий от cvv

> а вообще-то вам бы стивенса почитать

А в электронном виде есть он ? Если можно - ссылочку...

anonymous
()
Ответ на: комментарий от anonymous

уильям ричард стивенс "unix:взаимодействие процессов"
уильям ричард стивенс "unix:разработка сетевых приложений"
w.richard stevens "advanced programing in unix environment"

cvv ★★★★★
()
Ответ на: комментарий от cvv

Спасибо.
А какую б вы книгу посоветовали о linux(unix) не программирование, а
в общем, как об ОС. Настройка, прибамбасы всякие и т.д. в общем для
пользователя.

anonymous
()
Ответ на: комментарий от cvv

Спасибо.
А какую б вы книгу посоветовали о linux(unix) не программирование, а
в общем, как об ОС. Настройка, прибамбасы всякие и т.д. в общем для
пользователя.

anonymous
()
Ответ на: комментарий от anonymous

эт вопрос не ко мне.

здесь решающим фактором наверное является доступная сумма денег.

ну ещё в толках спроси

cvv ★★★★★
()
Ответ на: комментарий от cvv

Насчер пайпа:
если пайп ассоциирован со стандартным вводом, то и возникнет такая проблема, т.к. curses работает только с _терминалами_ , а у вас там м.б. что угодно.
Если хотите запускать программу как 
   prog < fff
И чтобы она корректно запускала дочерний процесс, читающий с терминала, то нужно сделать следующее:

int newfd = dup(0);
close(0);
open('/dev/tty', O_RDONLY);
/* далее родительский процесс должен читать из newfd */
...
/* далее запускаем дочерний процесс и используем в нем curses */
fork();
...

romanSA
()
Ответ на: комментарий от romanSA

> т.к. curses работает только с _терминалами_ 

не знаю на сколько это соотносится с наукой, но curses прекрасно читал
данные из этого файла. Если в read(0, buf, SIZE) я ставил SIZE меньше,
чем данных в файле, то getch в curses вычитывал данные из файла.
Если же SIZE больше, чем данных, то getch выдавал -1.
Curses всетаки,наверное, работает со стандартным вводом, просто есть
какие-то ограничения. Т.е. read c большим SIZE как-то забил стандартный
ввод. Тут я физику процесса не очень понимаю, может объяснит кто ???

anonymous
()
Ответ на: комментарий от anonymous

Может getch() и читал, но это скорее "фича" конкретной реализации, а создавался curses именно как средство управления терминалом.
И ести стандартный ввод (или вывод) не терминал, то многие функции curses будут давать непредсказуемый результат или просто ошибку как getch().
Ну скажите, что значит для файла "установить курсор в пятую колонку на третьей строке" или что значит "ширина экрана"?

romanSA
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.