Управление режимом работы терминала в Ncurses

3 комментария

В ncurses существуют функции, которые занимаются настройкой режима работы терминала. Это функции raw(), cbreak(), echo(), noecho(), keypad() и halfdelay(). Разберём их подробнее.

Функции raw() и cbreak()

Использование функций raw() и cbreak() позволяет управлять режимом клавиатуры — либо это полный контроль над клавиатурой, либо частичный. При частичном контроле все нажимаемые клавиши, прежде чем попасть в stdin, проходят проверку. Хороший пример такой проверки — сочетание CTRL+C. Это сочетание зарезервировано, и поэтому при нажатии этих клавиш будет вызвано прерывание, которое завершит работу программы. Но в raw-режиме(то есть при полном контроле над клавиатурой), эти символы попадут в программу без генерирования прерывания. Это очень удобно, поскольку позволяет отслеживать все действия пользователя. Функция cbreak() отменяет действие raw().

Пример

Эта программа при нажатии CTRL+C завершит свою работу:

#include <ncurses.h>

int main()
{
    initscr();             
    while ( true ) {    } //Просто работаем бесконечно долго
    endwin();              
    return 0;
}

А эта программа уже не будет реагировать на CTRL+C, поскольку она взяла на себя полный контроль над клавиатурой:

#include <ncurses.h>

int main()
{
    initscr();             
    raw();                 //Берём управление клавиатурой на себя
    while ( true ) {    } //Просто работаем бесконечно долго
    endwin();             
    return 0;
}

Функции echo() и noecho()

Функции echo() и noecho() управляют отображением вводимых символов на экран. Если была вызвана функция noecho(), то при вводе, вводимые символы не будут отображаться на экран. echo() отменяет действие noecho().

Пример

#include <ncurses.h>

int main()
{
    initscr();             
    noecho();              //Выключаем отображение вводимых символов

    char str[100];
    printw("Enter string: ");
    scanw("%s", str);     

    printw("You enter: %s\n", str);
    getch();

    endwin();              
    return 0;
}

Пример выполнения программы: картинка

Функция keypad()

Функция keypad() включает режим простой работы с функциональными клавишами, такими как F1, F2 и т.п.
Принимает два параметра: ncurses-окно(см.ниже) а так же переменную типа bool. Если последняя переменная равна true, то для данного ncurses-окна включается такой режим, если false, то выключается.

Функция halfdelay()

Функция halfdelay() включает half-delay-режим, когда функция getch() может ждать нажатия клавиши не более чем n десятых секунды. Если же нажатия не последовало, то getch() вернёт ERR.

Пример использования keypad() и halfdelay()

#include <ncurses.h>

int main()
{
    initscr();
    keypad(stdscr, true);   //Включаем режим чтения функциональных клавиш
    noecho();               //Выключаем отображение вводимых символов, нужно для getch()
    halfdelay(100);         //Устанавливаем ограничение по времени ожидания getch() в 10 сек

    printw("Press F2 to exit.\n");

    bool ex = false;
    while ( !ex )
    {
        int ch = getch();

        switch ( ch )
        {
        case ERR:
            printw("Please, press any key...\n"); //Если нажатия не было, напоминаем пользователю, что надо нажать клавишу
            break;
        case KEY_F(2): //Выходим из программы, если была нажата F2
            ex = true;
            break;
        default:  //Если всё нормально, выводим код нажатой клавиши
            printw("Code of pressed key is %d\n", ch);
            break;
        }

        refresh(); //Выводим на настоящий экран

    }

    printw("Thank you. Good buy!");
    getch();
    endwin(); 
    return 0;
}

Эта программа показывает код нажатой клавиши. Но если пользователь забыл нажать клавишу, то программа напоминает ему об этом :)

Пример работы программы: example

Немного о ncurses-окнах

Я уже на раз говорил о загадочных ncurses-окнах(далее просто окнах), но не говорил что это такое. И сейчас толком ничего не скажу, а только чуть-чуть коснусь.

Окно — это область на экране терминала, которая имеет все те же возможности, что и обычный экран терминала. То есть внутри него можно менять координаты курсора, цвета, режимы работы т.п. Внутри таких окон тоже можно создавать окна. Кстати, за обычный экран терминала отвечает окно stdscr, которое инициализируется в initscr().

Почти все функции ncurses получают в качестве своего параметра окно, для которого они выполняются. Такие функции имеют приставку w. Например, wprintw(), wscanw(), wgetch(), wrefresh() и т.д. Все функции, которые не получают окно( за исключением initscr() и ей подобных ) на самом деле являются макросами, которые присоединяют stdscr к вызову точно такой же функции, которая получает окно. К примеру, printw("Hello!") замениться на wprintw(stdscr, "Hello!"). Такие вот дела.

Автор статьи: Porshe.

Продолжение: →.

Комментарии к статье: 3

Подождите, загружаются комментарии...

Возможность комментировать эту статью отключена автором. Возможно, во всем виновата её провокационная тематика или большое обилие флейма от предыдущих комментаторов.

Если у вас есть вопросы по содержанию статьи, рекомендуем вам обратиться за помощью на наш форум.