Работа с терминалом; пример простого проекта

Терминал

Терминал — это устройство ввода и вывода байтов

Управление выводом со стороны приложения, ESC-последовательности

База информации о терминалах Terminfo

Неожиданный бонус Tektronix_4010:

Curses

NCurses — свободная (на сегодняшний день, главная) реализация Curses

Простой пример:

   1 #include <curses.h>
   2 
   3 main ()
   4 {
   5         initscr ();
   6         move (LINES/2 - 1, COLS/2 - 4);
   7         addstr ("Hello, World!");
   8         getch ();
   9         endwin ();
  10 }

Пример с поддержкой русского и окном:

   1 #include <ncurses.h>
   2 #include <locale.h>
   3 
   4 #define DX 7
   5 
   6 void main() {
   7         WINDOW *win;
   8 
   9         setlocale(LC_ALL, "");
  10 
  11         initscr();
  12         noecho();
  13         cbreak();
  14         printw("Окно:");
  15         refresh();
  16 
  17         win = newwin(LINES-2*DX, COLS-2*DX, DX, DX);
  18         keypad(win, TRUE);
  19         scrollok (win, TRUE);
  20         for(int c = wgetch(win); c != 27; c = wgetch(win))
  21                 wprintw(win, "Key: %d, Name: %s\n", c, keyname(c));
  22         delwin(win);
  23         endwin();
  24 }

Пример с рамкой:

   1 #include <curses.h>
   2 #include <locale.h>
   3 
   4 #define DX 7
   5 #define DY 3
   6 
   7 int main(int argc, char *argv[]) {
   8         WINDOW *frame, *win;
   9         int c = 0;
  10 
  11         setlocale(LC_ALL, "");
  12         initscr();
  13         noecho();
  14         cbreak();
  15         printw("Окно:");
  16         refresh();
  17 
  18         frame = newwin(LINES - 2*DY, COLS - 2*DX, DY, DX);
  19         box(frame, 0, 0);
  20         mvwaddstr(frame, 0, (int)((COLS - 2*DX - 5) / 2), "Рамка");
  21         wrefresh(frame);
  22 
  23         win = newwin(LINES - 2*DY - 2, COLS - 2*DX-2, DY+1, DX+1);
  24         keypad(win, TRUE);
  25         scrollok (win, TRUE);
  26         while((c = wgetch(win)) != 27)
  27                 wprintw(win, "%d: %s\n", c, keyname(c));
  28         delwin(win);
  29         delwin(frame);
  30         endwin();
  31         return 0;
  32 }

Примитивный Makefile

Tab hell. Again.

Д/З

Предполагается, что на спецкурс вы записались

  1. Сделать в репозитории подкаталог, совпадающий с именем данной страницы (01_TerminalProject, и поместить в него решение следующей задачи.

  2. С помощью интернета и здравого смысла написать на ncurses программу Show.c, которая постранично просматривает файл (слишком длинные строки усекаются или переносятся — как вам удобнее).

    • Имя файла передавать параметром командной строки.
    • Файл должен показываться в окне, а в первой строке экрана должно содержаться его имя.
    • Весь файл допустимо хранить в памяти, например, одним куском или в виде списка строк.

    • При нажатии пробела файл прокручивается дальше (если есть такая возможность), при нажатии ESC программа завершается.

      • Имеет смысл очищать окно при помощи werase(), а потом всё заново на нём выводить.

    • Многобайтовую кодировку можно не поддерживать
    • Исполняемый файл должен называться Show

  3. Сделать Makefile и добиться работоспособности make (обратите внимание на использование табуляций и/или RECIPEPREFIX

  4. Не забыть опубликовать решение в репозитории!
  5. (!) Дополнительно, для тех, кому стало интересно:

    • При нажатии стрелки вправо выводить строки файла, начиная со следующей колонки (так можно посмотреть урезанные длинные строки; начала строк при этом не видны). Стрелку влево обработать так же.
    • Реализовать обработку PgUp, PgDown и стрелок вверх/вниз — прокрутка на один экран вперёд/назад, на одну строку вперёд-назад, остальные клавиши игнорировать

    • … (далее везде)

Минимальный вариант…

…А потом я сделал поддержку wide characters и цвет)

LecturesCMC/LinuxApplicationDevelopment2024/01_TerminalProject (последним исправлял пользователь FrBrGeorge 2024-09-21 12:21:00)