如何在未创建SDL_Window的情况下获取SDL2中的wl_display实例?
获取未创建SDL窗口时SDL2的Wayland wl_display*实例
问题
SDL2在SDL_Init()初始化视频子系统时,若采用Wayland后端,会创建并初始化视频设备,其中包含一个所有SDL窗口共享的wl_display*实例。常规方式是通过已创建的SDL_Window结合SDL_SysWMinfo获取这个实例:
SDL_SysWMinfo info; SDL_VERSION(&info.version); SDL_GetWindowWMInfo(window, &info); // window 是 SDL_Window* return info.info.wl.display; // 假设当前使用Wayland驱动,返回wl_display*
但如果需要使用wl_display*时还未创建任何SDL窗口,没有可用的SDL_Window*,是否有办法无需通过SDL窗口直接获取这个共享实例?
可行方案
方案一:利用SDL内部视频设备结构(非公开API)
SDL2没有官方公开的API直接获取该实例,但可以通过访问内部的视频设备结构实现,注意这属于未公开接口,跨版本可能存在兼容性风险:
- 确保已初始化SDL视频子系统:
SDL_Init(SDL_INIT_VIDEO); - 获取主视频设备并提取
wl_display*:
#include <SDL2/SDL.h> #include <SDL2/SDL_video.h> #include <string.h> // 对应SDL2 Wayland后端的内部设备结构 typedef struct SDL_VideoDevice { // 省略SDL内部其他字段 struct { struct wl_display *display; // 省略其他Wayland相关字段 } wl; } SDL_VideoDevice; struct wl_display* get_wayland_display() { if (SDL_GetCurrentVideoDriver() == NULL || strcmp(SDL_GetCurrentVideoDriver(), "wayland") != 0) { return NULL; } // 获取第一个视频设备(SDL2中Wayland仅存在一个视频设备) SDL_VideoDevice* video_device = (SDL_VideoDevice*)SDL_GetVideoDevice(0); return video_device ? video_device->wl.display : NULL; }
方案二:创建临时隐藏窗口(兼容公开API)
如果担心内部接口的兼容性问题,推荐使用此方案:创建一个极小的隐藏SDL窗口,通过SDL_SysWMinfo获取实例后销毁窗口,开销可忽略:
#include <SDL2/SDL.h> struct wl_display* get_wayland_display() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { return NULL; } struct wl_display* display = NULL; // 创建1x1的隐藏窗口 SDL_Window* temp_win = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1, 1, SDL_WINDOW_HIDDEN); if (temp_win != NULL) { SDL_SysWMinfo info; SDL_VERSION(&info.version); if (SDL_GetWindowWMInfo(temp_win, &info) && info.subsystem == SDL_SYSWM_WAYLAND) { display = info.info.wl.display; } SDL_DestroyWindow(temp_win); } // 注意:如果后续还要使用SDL功能,不要调用SDL_Quit() return display; }
注意事项
- 使用内部接口时,需确保SDL版本与结构定义匹配,避免因版本更新导致的崩溃。
- 无论哪种方案,都要先确认当前视频驱动是Wayland,否则会触发未定义行为。
内容的提问来源于stack exchange,提问作者Bernard
相关产品推荐
相关产品推荐

