Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Богатырев А. Весь текст 1009.15 Kb

Хрестоматия по программированию на Си в Unix

Предыдущая страница Следующая страница
1 ... 62 63 64 65 66 67 68  69 70 71 72 73 74 75 ... 87
    #include                /* time structure */

    void setsigs(), drawItem(), drawTitle(), prSelects(), printTime();

А. Богатырев, 1992-95                  - 360 -                              Си в UNIX

    /* Работа с описанием терминала TERMCAP ---------------------------------*/
    extern char *getenv ();         /* получить переменную окружения         */
    extern char *tgetstr ();        /* получить строчный описатель /termcap/ */
    extern char *tgoto ();          /* подставить %-параметры      /termcap/ */

    static char Tbuf[2048],         /* буфер для описания терминала, обычно 1024 */
      /* Tbuf[] можно сделать локальной автоматической переменной
       * в функции tinit(), чтобы не занимать место */
                Strings[256],       /* буфер для расшифрованных описателей */
               *p;                  /* вспомогательная перем.              */
    char   *tname;                  /* название типа терминала             */
    int     COLS,                   /* число колонок экрана                */
            LINES;                  /* число строк экрана                  */
    char   *CM;                     /* описатель: cursor motion            */
    char   *CL;                     /* описатель: clear screen             */
    char   *CE;                     /* описатель: clear end of line        */
    char   *SO,
           *SE;                     /* описатели: standout Start и End     */
    char   *BOLD,
           *NORM;                   /* описатели: boldface and NoStandout  */
    int    BSflag;                  /* можно использовать back space '\b'  */

    void tinit () {      /* Функция настройки на систему команд дисплея */
        p = Strings;
        /* Прочесть описание терминала в Tbuf */
        switch (tgetent (Tbuf, tname = getenv ("TERM"))) {
             case -1:
                printf ("Нет файла TERMCAP (/etc/termcap).\n");
                exit (1);
            case 0:
                printf ("Терминал %s не описан.\n", tname);
                exit (2);
            case 1:
                break;              /* OK */
        }
        COLS =  tgetnum ("co");     /* Прочесть числовые описатели. */
        LINES = tgetnum ("li");

        CM = tgetstr ("cm", &p);    /* Прочесть строчные описатели.      */
        CL = tgetstr ("cl", &p);    /* Описатель дешифруется и заносится */
        CE = tgetstr ("ce", &p);    /* в массив по адресу p. Затем       */
        SO = tgetstr ("so", &p);    /* указатель p продвигается на       */
        SE = tgetstr ("se", &p);    /* свободное место, а адрес расшиф-  */
        BOLD = tgetstr ("md", &p);  /* рованной строки выдается из ф-ции */
        NORM = tgetstr ("me", &p);

        BSflag = tgetflag( "bs" );  /* Узнать значение флажка:
                 1 - есть, 0 - нет   */
    }

А. Богатырев, 1992-95                  - 361 -                              Си в UNIX

    /* Макрос, внесенный в функцию.
       Дело в том, что tputs в качестве третьего аргумента
       требует имя функции, которую она вызывает в цикле: (*f)(c);
       Если подать на вход макрос, вроде putchar,
       а не адрес входа в функцию, мы
       и не достигнем желанного эффекта,
       и получим ругань от компилятора.
    */
    void put (c) char c;
    {   putchar (c);  }

    /* очистить экран */
    void clearScreen () {
        if (CL == NULL)      /* Функция tputs() дорасшифровывает описатель */
            return;          /* (обрабатывая задержки) и выдает его        */
        tputs (CL, 1, put);  /* посимвольно ф-цией put(c) 1 раз            */
        /* Можно выдать команду не 1 раз, а несколько: например если это   */
        /* команда сдвига курсора на 1 позицию влево '\b'                  */
    }

    /* очистить конец строки, курсор остается на месте */
    void clearEOL () {  /* clear to the end of line */
        if (CE == NULL)
            return;
        tputs (CE, 1, put);
    }

    /* позиционировать курсор */
    void gotoXY (x, y) {  /* y - по вертикали СВЕРХУ-ВНИЗ. */
        if (x < 0 || y < 0 || x >= COLS || y >= LINES) {
            printf ("Точка (%d,%d) вне экрана\n", x, y);
            return;
        }
        /* CM - описатель, содержащий 2 параметра. Подстановку параметров
         * делает функция tgoto() */
        tputs (tgoto (CM, x, y), 1, put);
    }

    /* включить выделение */
    void standout () {
        if (SO) tputs (SO, 1, put);
    }

    /* выключить выделение */
    void standend () {
        if (SE) tputs (SE, 1, put);
        /* else normal(); */
    }

    /* включить жирный шрифт */
    void bold () {
        if (BOLD) tputs (BOLD, 1, put);
    }

А. Богатырев, 1992-95                  - 362 -                              Си в UNIX

    /* выключить любой необычный шрифт */
    void normal () {
        if (NORM) tputs (NORM, 1, put);
        else      standend();
    }

    /* Управление драйвером терминала --------------------------------- */

    #define ESC '\033'
    #define ctrl(c)         ((c) & 037 )

    int     curMode = 0;
    int     inited = 0;

    struct termio   old,
                    new;
    int     fdtty;

    void ttinit () {
     /* открыть терминал в режиме "чтение без ожидания" */
        fdtty = open ("/dev/tty", O_RDWR | O_NDELAY);

     /* узнать текущие режимы драйвера */
        ioctl (fdtty, TCGETA, &old);

        new = old;

     /* input flags */
     /* отменить преобразование кода '\r' в '\n' на вводе              */
        new.c_iflag &= ~ICRNL;
        if ((old.c_cflag & CSIZE) == CS8)  /* 8-битный код             */
             new.c_iflag &= ~ISTRIP;       /* отменить & 0177 на вводе */

     /* output flags */
     /* отменить TAB3 - замену табуляций '\t' на пробелы               */
     /* отменить ONLCR - замену '\n' на пару '\r\n' на выводе          */
        new.c_oflag &= ~(TAB3 | ONLCR);

     /* local flags */
     /* выключить режим ICANON, включить CBREAK                        */
     /* выключить эхоотображение набираемых символов                   */
        new.c_lflag &= ~(ICANON | ECHO);

     /* control chars */      /* при вводе с клавиш ждать не более ... */
        new.c_cc[VMIN]  = 1;  /* 1 символа и */
        new.c_cc[VTIME] = 0;  /* 0 секунд    */
        /* Это соответствует режиму CBREAK */

      /* Символы, нажатие которых заставляет драйвер терминала послать сигнал
       * либо отредактировать набранную строку. Значение 0 означает,
       * что соответствующего символа не будет */
        new.c_cc[VINTR]  = ctrl ('C'); /* символ, генерящий SIGINT         */
        new.c_cc[VQUIT]  = '\0';       /* символ, генерящий SIGQUIT        */
        new.c_cc[VERASE] = '\0';       /* забой (отмена последнего символа)*/
        new.c_cc[VKILL]  = '\0';       /* символ отмены строки             */
      /* По умолчанию эти кнопки равны: DEL, CTRL/\, BACKSPACE, CTRL/U     */

        setsigs ();
        inited = 1;                   /* уже инициализировано */
    }

А. Богатырев, 1992-95                  - 363 -                              Си в UNIX

    void openVisual () {      /* open visual mode (включить "экранный" режим) */
        if (!inited)
            ttinit ();
        if (curMode == 1)
            return;

        /* установить моды драйвера из структуры new */
        ioctl (fdtty, TCSETAW, &new);
        curMode = 1;        /* экранный режим */
    }

    void closeVisual () {        /* canon mode (включить канонический режим) */
        if (!inited)
            ttinit ();
        if (curMode == 0)
            return;

        ioctl (fdtty, TCSETAW, &old);
        curMode = 0;        /* канонический режим */
    }

    /* завершить процесс */
    void die (nsig) {
        normal();
        closeVisual (); /* При завершении программы (в том числе по
           * сигналу) мы должны восстановить прежние режимы драйвера,
           * чтобы терминал оказался в корректном состоянии. */
        gotoXY (0, LINES - 1);
        putchar ('\n');
        if (nsig)
            printf ("Пришел сигнал #%d\n", nsig);
        exit (nsig);
    }

    void setsigs () {
        register    ns;

        /* Перехватывать все сигналы; завершаться по ним. */
        /* UNIX имеет 15 стандартных сигналов. */
        for (ns = 1; ns <= 15; ns++)
            signal (ns, die);
    }

А. Богатырев, 1992-95                  - 364 -                              Си в UNIX

    /* Работа с меню -------------------------------------------- */

    struct menu {
        char   *m_text;             /* выдаваемая строка */
        int     m_label;            /* помечена ли она ? */
    }           menuText[] = {
            /* названия песен Beatles */
        {       "Across the Universe", 0            } ,
        {       "All I've got to do",  0            } ,
        {       "All my loving",       0            } ,
        {       "All together now",    0            } ,
        {       "All You need is love",0            } ,
        {       "And I love her",      0            } ,
        {       "And your bird can sing", 0         } ,
        {       "Another girl",        0            } ,
        {       "Any time at all",     0            } ,
        {       "Ask me why",          0            } ,
        {       NULL,                  0            }
    };

    #define Y_TOP 6
    int     nitems;                 /* количество строк в меню */
    int     nselected = 0;          /* количество выбранных строк */

    char    title[] =
            "ПРОБЕЛ - вниз, ЗАБОЙ - вверх, ESC - выход, \
    ENTER - выбрать, TAB - отменить";

    # define TIMELINE 1

    void main (ac, av) char **av; {
        char  **line;
        register    i;
        int     c;
        int     n;                  /* текущая строка */
        extern char readkey ();     /* forward */

        extern char *ttyname ();    /* имя терминала */
        char   *mytty;

        extern char *getlogin ();   /* имя пользователя */
        char   *userName = getlogin ();

        srand (getpid () + getuid ());      /* инициализировать
                                             * датчик случайных чисел */
        /* считаем строки меню */
        for (nitems = 0; menuText[nitems].m_text != NULL; nitems++);

        /* инициализируем терминал */
        tinit (); ttinit();
        mytty = ttyname(fdtty);
        openVisual ();

А. Богатырев, 1992-95                  - 365 -                              Си в UNIX

    again:
        clearScreen ();
        if (mytty != NULL && userName != NULL) {
            gotoXY (0, TIMELINE);
            bold ();
            printf ("%s", userName);
            normal ();
            printf (" at %s (%s)", mytty, tname);
        }

        drawTitle ("",    Y_TOP - 4);
        drawTitle (title, Y_TOP - 3);
        drawTitle ("",    Y_TOP - 2);

     /* рисуем меню */
        for (i = 0; i < nitems; i++) {
            drawItem (i, 20, Y_TOP + i, 0);
        }

        /* цикл перемещений по меню */
        for (n=0; ; ) {
            printTime ();   /* выдаем текущее время */
            drawItem (n, 20, Y_TOP + n, 1);

            c = getcharacter ();

            drawItem (n, 20, Y_TOP + n, 0);

            switch (c) {
                case ' ':
            go_down:
                    n++;
                    if (n == nitems)
                        n = 0;
                    break;

                case '\b': case 0177:
                    n--;
                    if (n < 0)
                        n = nitems - 1;
                    break;

                case ESC:
                    goto out;

                case '\t':          /* Unselect item */
Предыдущая страница Следующая страница
1 ... 62 63 64 65 66 67 68  69 70 71 72 73 74 75 ... 87
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама