Skip to content

Mouse_Watcher

SweerItTer edited this page Feb 21, 2026 · 5 revisions

MouseWatcher API 文档

概述

MouseWatcher 是 utilsCore Mouse 模块的核心类,提供 Linux 输入设备的鼠标事件监控功能,支持屏幕坐标映射。

职责

  • 监控鼠标输入设备
  • 捕获鼠标移动和按键事件
  • 支持屏幕分辨率映射
  • 回调机制通知事件

适用场景

  • 鼠标交互
  • UI 交互
  • 鼠标事件处理
  • 输入设备监控

依赖关系

  • 依赖: Linux input 子系统
  • 被依赖: DisplayManager, UI 模块等

类分析

MouseWatcher 类

职责与用途

MouseWatcher 是鼠标事件监控的封装类,提供:

  • 鼠标设备打开和监控
  • 鼠标事件回调
  • 屏幕分辨率映射
  • 事件类型过滤

设计模式

  • PImpl 惯用法: 隐藏实现细节
  • 观察者模式: 回调机制通知事件

MouseEventType 枚举

枚举定义

enum class MouseEventType : uint16_t {
    AxisX = 0x00,           // X轴相对移动
    AxisY = 0x01,           // Y轴相对移动
    WheelVertical = 0x08,   // 垂直滚轮
    WheelHorizontal = 0x06, // 水平滚轮
    ButtonLeft = 0x110,     // 左键
    ButtonRight = 0x111,    // 右键
    ButtonMiddle = 0x112,   // 中键
    ButtonSide = 0x113,     // 侧后键
    ButtonExtra = 0x114,    // 侧前键
    Unknown = 0xFFFF        // 未知事件
};

说明

事件类型 说明
AxisX X轴相对移动
AxisY Y轴相对移动
WheelVertical 垂直滚轮
WheelHorizontal 水平滚轮
ButtonLeft 左键
ButtonRight 右键
ButtonMiddle 中键
ButtonSide 侧后键
ButtonExtra 侧前键
Unknown 未知事件

类型定义

EventCallback - 事件回调

using EventCallback = std::function<void(MouseEventType, uint8_t)>;

参数:

  • MouseEventType: 事件类型
  • uint8_t: 值(按键状态或滚轮增量)

PositionCallback - 位置回调

using PositionCallback = std::function<void(int32_t, int32_t)>;

参数:

  • int32_t: X 坐标
  • int32_t: Y 坐标

公共 API 方法

构造函数

explicit MouseWatcher();
~MouseWatcher();

参数说明: 无

返回值: 无

所有权归属:

  • MouseWatcher 拥有内部资源的所有权

注意事项:

  1. 构造时不打开设备
  2. 调用 start() 时才打开设备
  3. 禁止拷贝和移动

start() - 启动监控

void start();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 打开输入设备
  2. 启动监控线程
  3. 开始接收鼠标事件

使用例程:

MouseWatcher watcher;
watcher.start();

stop() - 停止监控

void stop();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 停止监控线程
  2. 关闭输入设备
  3. 等待线程退出

pause() - 暂停监控

void pause();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 暂停接收鼠标事件
  2. 可以通过 resume() 恢复

resume() - 恢复监控

void resume();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 恢复接收鼠标事件
  2. 需要先调用 pause()

setScreenSize() - 设置屏幕分辨率

void setScreenSize(int width, int height);

参数说明:

  • width (输入): 屏幕宽度
  • height (输入): 屏幕高度

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 用于坐标映射
  2. 需要先设置才能使用 getMappedPosition()

使用例程:

watcher.setScreenSize(1920, 1080);
watcher.setTargetSize(1280, 720);

// 坐标会从 1920x1080 映射到 1280x720

setTargetSize() - 设置目标分辨率

void setTargetSize(int width, int height);

参数说明:

  • width (输入): 目标宽度
  • height (输入): 目标高度

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 用于坐标映射
  2. 需要先设置 screen size

getRawPosition() - 获取原始坐标

bool getRawPosition(int& x, int& y);

参数说明:

  • x (输出): X 坐标
  • y (输出): Y 坐标

返回值:

  • true: 成功
  • false: 失败

所有权归属:

  • 无所有权转移

注意事项:

  1. 返回原始屏幕坐标
  2. 不经过分辨率映射

使用例程:

int x, y;
if (watcher.getRawPosition(x, y)) {
    printf("Raw position: (%d, %d)\n", x, y);
}

getMappedPosition() - 获取映射坐标

bool getMappedPosition(int& x, int& y);

参数说明:

  • x (输出): 映射后的 X 坐标
  • y (输出): 映射后的 Y 坐标

返回值:

  • true: 成功
  • false: 失败

所有权归属:

  • 无所有权转移

注意事项:

  1. 返回映射到目标分辨率的坐标
  2. 需要先调用 setScreenSize() 和 setTargetSize()

使用例程:

watcher.setScreenSize(1920, 1080);
watcher.setTargetSize(1280, 720);

int x, y;
if (watcher.getMappedPosition(x, y)) {
    printf("Mapped position: (%d, %d)\n", x, y);
}

getPosition() - 获取坐标(兼容接口)

bool getPosition(int& x, int& y);

参数说明:

  • x (输出): X 坐标
  • y (输出): Y 坐标

返回值:

  • true: 成功
  • false: 失败

所有权归属:

  • 无所有权转移

注意事项:

  1. 兼容旧接口
  2. 返回映射后的坐标(如果设置了目标分辨率)

getKeyState() - 获取按键状态

bool getKeyState(MouseEventType key, uint8_t& value);

参数说明:

  • key (输入): 按键类型
  • value (输出): 按键状态

返回值:

  • true: 成功
  • false: 失败

所有权归属:

  • 无所有权转移

注意事项:

  1. key 必须是按键类型(ButtonLeft, ButtonRight 等)
  2. value 表示按键状态

使用例程:

uint8_t value;
if (watcher.getKeyState(MouseEventType::ButtonLeft, value)) {
    if (value) {
        printf("Left button is pressed\n");
    } else {
        printf("Left button is released\n");
    }
}

registerHandler() - 注册事件回调

void registerHandler(const std::vector<MouseEventType>& eventTypes, EventCallback cb);

参数说明:

  • eventTypes (输入): 事件类型列表
  • cb (输入): 回调函数

返回值: 无

所有权归属:

  • MouseWatcher 持有回调函数的所有权

注意事项:

  1. eventTypes 指定要监听的事件类型
  2. 只监听指定类型的事件
  3. 回调在监控线程中调用

使用例程:

// 监听按键事件
watcher.registerHandler(
    {MouseEventType::ButtonLeft, MouseEventType::ButtonRight},
    [](MouseEventType type, uint8_t value) {
        if (type == MouseEventType::ButtonLeft) {
            printf("Left button: %d\n", value);
        } else if (type == MouseEventType::ButtonRight) {
            printf("Right button: %d\n", value);
        }
    }
);

// 监听移动事件
watcher.registerHandler(
    {MouseEventType::AxisX, MouseEventType::AxisY},
    [](MouseEventType type, uint8_t value) {
        printf("Move: type=%d, value=%d\n", (int)type, value);
    }
);

registerRawPositionCallback() - 注册原始位置回调

void registerRawPositionCallback(PositionCallback cb);

参数说明:

  • cb (输入): 位置回调函数

返回值: 无

所有权归属:

  • MouseWatcher 持有回调函数的所有权

注意事项:

  1. 回调在鼠标移动时调用
  2. 返回原始屏幕坐标
  3. 回调在监控线程中调用

使用例程:

watcher.registerRawPositionCallback([](int32_t x, int32_t y) {
    printf("Raw position: (%d, %d)\n", x, y);
});

registerMappedPositionCallback() - 注册映射位置回调

void registerMappedPositionCallback(PositionCallback cb);

参数说明:

  • cb (输入): 位置回调函数

返回值: 无

所有权归属:

  • MouseWatcher 持有回调函数的所有权

注意事项:

  1. 回调在鼠标移动时调用
  2. 返回映射后的坐标
  3. 需要先调用 setScreenSize() 和 setTargetSize()
  4. 回调在监控线程中调用

使用例程:

watcher.setScreenSize(1920, 1080);
watcher.setTargetSize(1280, 720);

watcher.registerMappedPositionCallback([](int32_t x, int32_t y) {
    printf("Mapped position: (%d, %d)\n", x, y);
});

线程安全说明

同步机制

  • PImpl 惯用法: 隐藏实现细节
  • 监控线程: 使用独立线程接收输入事件
  • 回调调用: 回调在监控线程中调用

线程安全建议

  • 回调函数应该是线程安全的
  • 不要在回调中阻塞
  • 使用队列传递事件到其他线程

典型使用场景

场景 1: 基本使用

MouseWatcher watcher;

// 注册按键回调
watcher.registerHandler(
    {MouseEventType::ButtonLeft, MouseEventType::ButtonRight},
    [](MouseEventType type, uint8_t value) {
        if (type == MouseEventType::ButtonLeft) {
            printf("Left button: %d\n", value);
        } else if (type == MouseEventType::ButtonRight) {
            printf("Right button: %d\n", value);
        }
    }
);

watcher.start();

场景 2: 位置监控

MouseWatcher watcher;

watcher.registerRawPositionCallback([](int32_t x, int32_t y) {
    printf("Position: (%d, %d)\n", x, y);
});

watcher.start();

场景 3: 分辨率映射

MouseWatcher watcher;

// 设置屏幕分辨率和目标分辨率
watcher.setScreenSize(1920, 1080);
watcher.setTargetSize(1280, 720);

// 注册映射位置回调
watcher.registerMappedPositionCallback([](int32_t x, int32_t y) {
    printf("Mapped: (%d, %d)\n", x, y);
});

watcher.start();

场景 4: 暂停和恢复

MouseWatcher watcher;

watcher.registerHandler(
    {MouseEventType::ButtonLeft},
    [](MouseEventType type, uint8_t value) {
        printf("Left button: %d\n", value);
    }
);

watcher.start();

// 暂停监控
watcher.pause();

// 恢复监控
watcher.resume();

场景 5: 主动获取位置

MouseWatcher watcher;

watcher.start();

// 获取原始坐标
int raw_x, raw_y;
if (watcher.getRawPosition(raw_x, raw_y)) {
    printf("Raw: (%d, %d)\n", raw_x, raw_y);
}

// 获取映射坐标
int mapped_x, mapped_y;
if (watcher.getMappedPosition(mapped_x, mapped_y)) {
    printf("Mapped: (%d, %d)\n", mapped_x, mapped_y);
}

注意事项

  1. 设备权限: 确保有访问输入设备的权限
  2. 回调线程: 回调在监控线程中调用,不要阻塞
  3. 线程安全: 回调函数应该是线程安全的
  4. 分辨率映射: 使用映射功能需要先设置分辨率
  5. 事件类型: 只有注册的事件类型才会触发回调
  6. 暂停恢复: pause() 后需要 resume() 才能继续监控
  7. 禁止拷贝和移动: 只能通过引用访问
  8. PImpl: 使用 PImpl 惯用法隐藏实现细节

相关文档


参考资料

主页

API 文档

DMA 模块

DRM 模块

NET 模块

V4L2 模块

V4L2Param 模块

RGA 模块

MPP 模块

Sys 模块

Mouse 模块

Utils 模块

Clone this wiki locally