LINUX.ORG.RU

[C] перехват курсорных клавиш


0

0

Можно ли сделать перехват курсорных клавиш средствами стандартных библиотек С? Если конкретно, то нужно чтобы консольная прога запоминала команды и при нажатии клавиши "вверх" выдавала последнюю введенную команду. Так сделано в bash, но просматривая его исходники что-то пока не удается выловить идею.

Если нельзя с помощью голого С, то как сделать это по-другому?

Re: [C] перехват курсорных клавиш

ncurses нужна, потому что все терминалы работают по-разному, это слой переносимости, который никто в здравом уме не захочет переделывать (linux-консоль по alt+f1, xterm и gnome-terminal - это всё "разные терминалы"). libreadline - это реализация непосредственно того, что нужно ("как в bash"). Естественно, она использует ncurses.

Кроме того, ncurses нужна не просто для того, чтобы перехватывать нажатия на курсор. Для того, чтобы удержать курсор ввода на строке и надёжно затереть уже введенный текст, тоже нужна ncurses. Think about it.

anonymous ()
Ответ на: Re: [C] перехват курсорных клавиш от Rarruga

Re: [C] перехват курсорных клавиш

Можно вручную обрабатывать нажатые клавиши например так:

#include <termios.h> 
#include <assert.h> 

int getch(void) {
      int c = 0;

      struct termios org_opts, new_opts;
      int res = 0;
          //-----  store old settings -----------
      res = tcgetattr(STDIN_FILENO, &org_opts);
      assert(res==0);
          //---- set new terminal parms --------
      memcpy(&new_opts, &org_opts, sizeof(new_opts));

      new_opts.c_lflag &= ~(ICANON | ECHO);
      new_opts.c_cc[VTIME] = 0;
      new_opts.c_cc[VMIN] = 1;

      tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
      c = getchar();
          //------  restore old settings ---------
      res = tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
      assert(res==0);
      return(c);
}

    int ch = 0;
    while(1)
        {
            ch = getch();
            if(ch != 27) putchar(ch);
            else
                {
                 // обработка функциональных клавиш
                }
         } 

Кривовато, но работать должно :)

koTuk ()
Ответ на: Re: [C] перехват курсорных клавиш от Valeriy_Onuchin

Re: [C] перехват курсорных клавиш

> тоже нужна ncurses. Think about it.

возможно, говорим о разных readline
То, что я юзаю обрабатывает ограниченное число клавиш,
которые есть во всех клавах. Вот коммент из сорца:


************************** End-User Interface ***************************

Entering printable keys generally inserts new text into the buffer (unless
in overwrite mode, see below). Other special keys can be used to modify
the text in the buffer. In the description of the keys below, ^n means
Control-n, or holding the CONTROL key down while pressing "n". M-B means
Meta-B (or Alt-B). Errors will ring the terminal bell.

^A/^E : Move cursor to beginning/end of the line.
^F/^B : Move cursor forward/backward one character.
^D : Delete the character under the cursor.
^H, DEL : Delete the character to the left of the cursor.
^K : Kill from the cursor to the end of line.
^L : Redraw current line.
^O : Toggle overwrite/insert mode. Initially in insert mode. Text
added in overwrite mode (including yanks) overwrite
existing text, while insert mode does not overwrite.
^P/^N : Move to previous/next item on history list.
^R/^S : Perform incremental reverse/forward search for string on
the history list. Typing normal characters adds to the current
search string and searches for a match. Typing ^R/^S marks
the start of a new search, and moves on to the next match.
Typing ^H or DEL deletes the last character from the search
string, and searches from the starting location of the last search.
Therefore, repeated DEL's appear to unwind to the match nearest
the point at which the last ^R or ^S was typed. If DEL is
repeated until the search string is empty the search location
begins from the start of the history list. Typing ESC or
any other editing character accepts the current match and
loads it into the buffer, terminating the search.
^T : Toggle the characters under and to the left of the cursor.
^U : Kill from beginning to the end of the line.
^Y : Yank previously killed text back at current location. Note that
this will overwrite or insert, depending on the current mode.
M-F/M-B : Move cursor forward/backward one word.
M-D : Delete the word under the cursor.
^SPC : Set mark.
^W : Kill from mark to point.
^X : Exchange mark and point.
TAB : By default adds spaces to buffer to get to next TAB stop
(just after every 8th column), although this may be rebound by the
programmer, as described below.
NL, CR : returns current buffer to the program.

DOS and ANSI terminal arrow key sequences are recognized, and act like:

up : same as ^P
down : same as ^N
left : same as ^B
right : same as ^F

Valeriy_Onuchin ★★ ()
Ответ на: Re: [C] перехват курсорных клавиш от koTuk

Re: [C] перехват курсорных клавиш

> Можно вручную обрабатывать нажатые клавиши например так:

Попытался использовать этот вариант. Пока не получается сделать так, как мне нужно. Судя по манам на этот termios у меня ничего и не получится.

Rarruga ()
Ответ на: Re: [C] перехват курсорных клавиш от Rarruga

Re: [C] перехват курсорных клавиш

>Расследование показывает, что bash использует libreadline, которая, в свою очередь, использует ncurses.

>Будем копать дальше..

А у кого-то на линуксе нету ncurses?

Absurd ★★★ ()

Re: [C] перехват курсорных клавиш

Посмотри termcap.
Я как-то давно юзал, по-моему это то, что тебе нужно...

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