Wayland入门13:鼠标操作

之前文章中我们创建了一个空白窗口,接下来我们处理一下窗口上的鼠标操作。

先把新建窗口的代码复制过来。然后把seat的部分代码复制过来,在注册函数中添加seat处理部分。

Wayland只提供了wl_pointer_listener,要想获取鼠标相关的消息需要首先设置监听器。

wl_pointer的消息有:

  • enter 进入窗口范围
  • leave 离开窗口范围
  • motion 鼠标移动
  • button 鼠标点击,鼠标按键id定义位于文件<linux/input.h>中,例如BTN_LEFT表示鼠标左键。
static void
global_registry_handler(void *data, struct wl_registry *registry,
						uint32_t id, const char *interface, uint32_t version)
{
	if (strcmp(interface, "wl_compositor") == 0)
	{
		BIND_WL_REG(registry, compositor, id, &wl_compositor_interface, 1);
	}else if (strcmp(interface, "wl_shell") == 0){
		BIND_WL_REG(registry, shell, id, &wl_shell_interface, 1);
	}else if (strcmp(interface, "wl_shm") == 0){
		BIND_WL_REG(registry, shm, id, &wl_shm_interface, 1);
		wl_shm_add_listener(shm, &shm_listener, NULL);
	}else if(strcmp(interface, "wl_seat")==0){
		BIND_WL_REG(registry, seat, id, &wl_seat_interface, 1);
		wl_seat_add_listener(seat,&seat_listener,NULL);
	}
}

添加一个seat_listener结构体

static const struct wl_seat_listener seat_listener = {
    seat_handle_capabilities,
};

添加seat_listener的回调函数

static void
seat_handle_capabilities(void *data, struct wl_seat *seat,
                         enum wl_seat_capability caps)
{
    if ((caps & WL_SEAT_CAPABILITY_POINTER) && !pointer)
    {
        pointer = wl_seat_get_pointer(seat);
        wl_pointer_add_listener(pointer, &pointer_listener, NULL);
    }else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && pointer){
        wl_pointer_destroy(pointer);
        pointer = NULL;
    }
}

分两种情况,第一种是输入设备是鼠标并且指针不为空那么就表示当前状态有效,第二种是输入设备为鼠标但是指针为空表示鼠标已经离开窗口了。

添加pointer_listener函数。

static const struct wl_pointer_listener pointer_listener = {
    pointer_handle_enter,
    pointer_handle_leave,
    pointer_handle_motion,
    pointer_handle_button,
    pointer_handle_axis,
};

有四种情况:进入、离开、移动、点击、坐标系。四种情况对应的函数为:

static void
pointer_handle_enter(void *data, struct wl_pointer *pointer,
                     uint32_t serial, struct wl_surface *surface,
                     wl_fixed_t sx, wl_fixed_t sy)
{
    fprintf(stderr, "Pointer entered surface %p at %d %d\n", surface, sx, sy);
}

static void
pointer_handle_leave(void *data, struct wl_pointer *pointer,
                     uint32_t serial, struct wl_surface *surface)
{
    fprintf(stderr, "Pointer left surface %p\n", surface);
}

static void
pointer_handle_motion(void *data, struct wl_pointer *pointer,
                      uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
{
    printf("Pointer moved at %d %d\n", sx, sy);
}

static void
pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
                      uint32_t serial, uint32_t time, uint32_t button,
                      uint32_t state)
{
    printf("Pointer button\n");
    if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED)
        wl_shell_surface_move(shell_surface, seat, serial);
}

static void
pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
                    uint32_t time, uint32_t axis, wl_fixed_t value)
{
    printf("Pointer handle axis\n");
}

效果为:

result

可以看到坐标点的数据不对劲,坐标数据类型为int32_t wl_fixed_t,根据wayland-util.h描述其为带一个有符号位的24.8有符号定点数、带8位十进制的23位整型数。wayland提供了函数用于转换。

效果为:

double

这样看起来就正常了。

EGL版本只是替换了窗口显示部分,其他的代码一样。

完整代码在Wayland_Frashman中的13.pointer下。

本文首发于:Wayland入门13:鼠标操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幽迷狂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值