C语言 Linux终端中鼠标滚轮滚动的检测

kxe2p93d  于 2023-03-28  发布在  Linux
关注(0)|答案(2)|浏览(271)

问题

我想要一个函数来检测用户是向前还是向后滚动鼠标滚轮。就像在vim中一样,当你向上滚动时,你会得到5行。

为了解决这个问题,我学习和测试了哪些东西

我跟踪了很多东西,首先,我注意到在dev/input/event中,你可以读到用户正在向上或向下滚动,但这个地方需要root访问权限,在程序中使用这个是不符合逻辑的。
我还看到了ncursesX11SDL2的使用,它们要么产生图形屏幕,要么根本不识别鼠标滚轮的方向。

  • 任何帮助我都感激不尽 *
xt0899hw

xt0899hw1#

要在C++中检测终端中的鼠标滚轮滚动,可以使用termios库来操纵终端的输入模式,并解释用户滚动鼠标滚轮时终端发送的转义序列。
下面是一个检测鼠标滚轮事件并返回用户是向上滚动还是向下滚动的示例函数:

#include <iostream>
#include <termios.h>
#include <unistd.h>

using namespace std;

string detect_scroll() {
    // switch to non-canonical mode to read input one character at a time
    termios orig_settings;
    tcgetattr(STDIN_FILENO, &orig_settings);
    termios new_settings = orig_settings;
    new_settings.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &new_settings);

    try {
        int count = 0;
        while (true) {
            // read one character from the input stream
            char c;
            if (read(STDIN_FILENO, &c, 1) < 0) {
                return "";
            }

            // if it's a mouse scroll event...
            if (c == 27 && read(STDIN_FILENO, &c, 1) == 0 && read(STDIN_FILENO, &c, 1) == 96) {
                char scroll_direction;
                if (read(STDIN_FILENO, &scroll_direction, 1) < 0) {
                    return "";
                }

                if (scroll_direction == 27 &&
                    read(STDIN_FILENO, &scroll_direction, 1) == 0 &&
                    read(STDIN_FILENO, &scroll_direction, 1) == 65)
                {
                    // if the next character is also an escape, this is a scroll-up event
                    return "up";
                } else if (scroll_direction == 53 &&
                           read(STDIN_FILENO, &scroll_direction, 1) == 126) {
                    // if the next character is '5' and '~', this is a scroll-down event
                    return "down";
                }
            }
        }
    } finally {
        // restore original terminal settings
        tcsetattr(STDIN_FILENO, TCSANOW, &orig_settings);
    }
}

此函数使用与Python示例相同的方法,当用户向上或向下滚动鼠标滚轮时,侦听终端发送的转义序列。它将终端切换到非规范模式,一次读取输入的一个字符,并查找以^[(转义字符)并以^[[A(对于向上滚动事件))或^[[5~(对于向下滚动事件)结束。
要使终端在用户向上滚动时模拟vim的滚动行为,可以调用ncurses库中的tputs函数,将适当的转义序列发送回终端。例如,要向上滚动5行,可以使用以下代码:

#include <ncurses.h>

void scroll_up() {
    tputs(tgoto(tgetstr("SF", nullptr), 0, 5), 1, putchar);
}

这将向终端发送带有5行参数的SF(向前滚动)序列,使其将屏幕向上滚动5行。
注意,ncurses需要在程序开始和结束时分别调用特殊的初始化(使用initscr())和清理(使用endwin())函数,并且还应该检查tputs、tgoto等返回的错误。

zzlelutf

zzlelutf2#

例如:evdev

相关问题