Я начал узнавать о escape-последовательностях ANSI онлайн через магию c Google. Это хорошая возможность позиционировать курсор \e[row;colH
на экране и устанавливать цвета выходов (ie: \e[31m
).
Далее я хотел бы попытаться увидеть, как мышь способна быть захваченным в виртуальном терминале. Я понимаю, что этот код не переносим, и я знаю, что могу использовать ncurses или какую-либо другую библиотеку curses, но цель здесь - узнать, как это работает, а не писать производственный код с ним.
Я пробовал \e[?1003h
и он начинает заполнять экран событиями мыши. (Довольно круто!) Однако, как мне запечатлеть их в программе C или C ++?
Я видел пример того, что я хотел бы сделать в PHP: { ссылка }
Однако, когда я пытаюсь перенести код на что-то в C, он просто блокируется, пока l oop. (Протестировано с помощью GDB, чтобы выяснить это.)
#include <stdio.h> //bring in printf and fread
int main()
{
system("stty -echo"); //make the terminal not output mouse events
system("stty -icanon"); //put stdin in raw mode
printf("\e[?1003h\e[?1015h\e[?1006h"); //start getting mouse events
char* buffer[255];
while(fread(buffer, 16, 1, stdin)) // <-- suppose to read in the mouse events
{
printf("here"); //Did you actually work?!
}
printf("\e[?1000l"); //Turn off mouse events
system("stty echo"); //Turn echoing of the display back on
return 0; //end the program in a successful state
}
Я также пытался scanf
, и он просто зависал, пока я не нажал enter, и я не уверен, что видит события мыши.
Редактировать
Теперь у меня есть некоторый рабочий код, который выплевывает события мыши.
Вот обновленный код от применения принятого ответа на этот вопрос :
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main()
{
system("stty -echo"); //don't show mouse events on screen
system("stty -icanon");
fprintf(stderr, "\e[?1003h\e[?1015h\e[?1006h"); //use stderr since not buffered turn on mouse event capture
char buffer[16] = " ";
char previousBuffer[16] = " ";
//Make standard in not be blocking
int flags = fcntl(stdin->_fileno, F_GETFL, 0);
fcntl(stdin->_fileno, F_SETFL, flags | O_NONBLOCK);
for (int hunSeconds = 0; hunSeconds < 500; hunSeconds++) //Run for 50 seconds
{
read(fileno(stdin), buffer, 16); //read mouse input
if (strcmp(buffer, previousBuffer) != 0) //only show event if it is different
{
fprintf(stderr, "%s", buffer);
strncpy(previousBuffer, buffer, 16);
}
usleep(100); // sleep for .1 seconds
}
printf("\e[?1000l"); //turn off mouse events
system("stty echo"); //turn on screen echo again
return 0;
}