Wayland入门9:第一个窗口

本文介绍了如何在Wayland环境中成功连接服务器,使用SHM绘制窗口,展示支持的像素格式,并创建和修改窗口内容。重点涉及wl_surface和wl_buffer的使用,以及如何实现窗口的基本绘制和像素操作。

前面已经可以成功的连接服务器了。本文介绍如何显示一个窗口。

Wayland窗口绘制有两种方法:1) 共享内存方式(SHM)、2)EGL。

要想使用EGL,你得会EGL,还得先会OpenGL,这两个哪一个工程量都不小。本文使用方式1绘制窗口(第二种方法等OpenGL开发系列和EGL开发系列更新完再说)。

窗口

先将上一篇的代码拿过来,当然不需要输出所有的registry信息。

所以将

printf("Got a registry event for %s id %d\n", interface, id);

删除。

改动之后最好编译一下,以确保每一步都正确。

在添加注册函数中添加一个shm部分的处理

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);
	}
}

可以看到共享内存中有回调函数shm_listener,我们要实现它:

struct wl_shm_listener shm_listener={
   
   
	.format=shm_format
};

和之前一样

struct wl_shm_listener shm_listener={
   
   
	shm_format
};

这样也可以,具体声明在wayland-client-protocol.h

此函数的作用是

struct wl_shm_listener {
   
   
	/**
	 * pixel format description
	 *
	 * Informs the client about a valid pixel format that can be used
	 * for buffers. Known formats include argb8888 and xrgb8888.
	 * @param format buffer pixel format
	 */
	void (*format)(void *data,
		       struct wl_shm *wl_shm,
		       uint32_t format
<think> 我们正在讨论Wayland编程,用户想要创建一个简单的可输出内容的Wayland窗口。根据之前的对话,我们已经了解了提交表面的时机,现在用户希望了解创建窗口的基本步骤。 参考引用[4]提到了"Wayland入门9第一个窗口",这应该是创建窗口的关键资源。引用[1]提到了获取wayland表面(WlSurface)和创建事件队列,引用[3]则强调了wl_display作为所有对象基础的重要性。 因此,我将分解创建Wayland窗口的步骤: 1. 连接Wayland显示服务器(wl_display) 2. 创建wl_registry对象以获取全局对象 3. 绑定必要的全局接口(特别是wl_compositor和wl_shell/shell/xdg_shell) 4. 创建表面(wl_surface)和shell表面(wl_shell_surface) 5. 为表面附加缓冲区并绘制内容 6. 提交表面(wl_surface_commit) 注意:现代Wayland程序推荐使用xdg_shell替代旧的wl_shell,因为xdg_shell提供了更标准的桌面窗口功能。 由于用户要求"简单",我将展示最基础的可运行代码框架(伪代码风格),并解释关键步骤。实际代码会更复杂,需要错误处理等。 我将使用C语言示例,因为Wayland API是C的。但概念适用于其他语言绑定。 </think> ### Wayland创建简单窗口的方法 要使用Wayland创建一个可输出内容的简单窗口,需遵循以下关键步骤(基于C语言示例): #### 1. **建立显示连接** 连接到Wayland显示服务器,获取核心对象: ```c struct wl_display *display = wl_display_connect(NULL); // 连接到默认显示[^1][^3] struct wl_registry *registry = wl_display_get_registry(display); wl_registry_add_listener(registry, &registry_listener, NULL); // 设置监听器 wl_display_roundtrip(display); // 同步获取全局对象 ``` #### 2. **获取必需接口** 通过注册表获取合成器和Shell接口: ```c // 在registry_listener回调中处理全局对象 static void registry_handler(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { if (strcmp(interface, "wl_compositor") == 0) { compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_shell") == 0) { shell = wl_registry_bind(registry, id, &wl_shell_interface, 1); // 推荐使用xdg_shell替代[^2] } } ``` #### 3. **创建表面和窗口** ```c // 创建基础绘制表面 struct wl_surface *surface = wl_compositor_create_surface(compositor); // 创建窗口对象(以wl_shell为例) struct wl_shell_surface *shell_surface = wl_shell_get_shell_surface(shell, surface); wl_shell_surface_set_toplevel(shell_surface); // 设置为顶层窗口 ``` #### 4. **绘制内容并提交** ```c // 创建共享内存缓冲区(以ARGB格式为例) struct wl_buffer *buffer = create_buffer(320, 240, WL_SHM_FORMAT_ARGB8888); // 格式见[^4] // 填充缓冲区内容(示例:红色背景) uint32_t *pixels = shm_data; for (int i = 0; i < 320 * 240; i++) pixels[i] = 0xFFFF0000; // ARGB格式:红色 // 附加缓冲区到表面 wl_surface_attach(surface, buffer, 0, 0); wl_surface_damage(surface, 0, 0, 320, 240); // 标记更新区域 wl_surface_commit(surface); // 提交表面更新[^1] ``` #### 5. **事件循环处理** ```c while (wl_display_dispatch(display) != -1) { // 窗口事件处理(如重绘请求) } ``` #### 关键说明: 1. **缓冲区创建**:需通过`wl_shm`创建共享内存,映射后填充像素数据(完整实现约50行代码) 2. **现代协议**:推荐使用`xdg_shell`替代`wl_shell`(更标准化) 3. **渲染优化**:实际应用应使用EGL/Vulkan进行GPU加速渲染[^2] 4. **错误处理**:所有Wayland调用都需检查返回值和错误事件 > 完整示例可参考Wayland教程[^4]:包含窗口创建、事件处理及OpenGL集成。
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

幽迷狂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值