是否有宏可以识别我使用的是 Wayland 还是 X11?

问题描述 投票:0回答:1

我目前正在开发一个项目,为了学习,我想用特定于平台的代码自己编写窗口系统。

因此,我使用预处理器在编译时知道我所在的平台,但我不知道如何识别 Linux 上的窗口系统。我真的需要这个,因为 X11 和 Wayland 应用程序不兼容;因此,我必须编写不同的文件。

这是我在此站点上找到的带有预处理器选项的文件:

// Windows OS
#if defined(_WIN32) || defined(_WIN64)
  #define PLATFORM_WINDOWS 1
// Linux OS
#elif defined(__linux__)
  #define PLATFORM_LINUX 1
  #if defined(WAYLAND)
    #define LINUX_ON_WAYLAND
  #elif defined(X11)
    #define LINUX_ON_X11
  #endif
// Unix OS
#elif defined(__unix) || defined(__unix__)
  #define PLATFORM_UNIX 1
// Mac OS
#elif defined(__APPLE__) || defined(__MACH__)
  #define PLATFORM_MACOS
// Unknown OS
#else
  #error "Unknown platform."
#endif

如您所见,我已经为 WAYLAND 和 X11 添加了占位符,但是有没有办法让这样的系统正常工作?

c
1个回答
0
投票

我想我找到了两个足够好的解决方案。

第一个在编译时工作:只需手动放置一个像

-DBUILDING_WITH_X11
-DBUILDING_WITH_WAYLAND
这样的标志,然后检查在编译时是否只定义了一个标志。我之前的代码示例(经过更改):

[...]
// Linux OS
#elif defined(__linux__)
  #define PLATFORM_LINUX 1
  #if defined(BUILDING_WITH_X11) && defined(BUILDING_WITH_WAYLAND)
    #error "You can't build for x11 and Wayland at the same time."
  #elif !defined(BUILDING_WITH_X11) && !defined(BUILDING_WITH_WAYLAND)
    #error "You need to define at least one windowing protocol to use."
  #endif
[...]

第二个在运行时工作。它使用来自

secure_getenv()
(带有
stdlib.h
扩展名)的命令
_GNU_SOURCE
,以字符串形式检索环境变量的值。因此,我可以有条件地使用它来选择我使用的功能:

if (strcmp(secure_getenv("XDG_SESSION_TYPE"), "wayland") == 0) {
    printf("We're on wayland.\n");
} else if (strcmp(secure_getenv("XDG_SESSION_TYPE"), "x11") == 0) {
    printf("We're on X11.\n");
} else {
    printf("wtf ?\n");
}

(注意:在对此发表任何评论之前,我更喜欢明确地写出我们想要获得的值,当它不是简单的 true false 时,这里,就像在很多 std 库中一样,0 相当于 true,这很烦人)

我真的不知道哪一个最好。直觉上,第一个似乎是最简单的,我看到大型程序(例如glfw)对于x11和wayland有不同的构建(现在,从glfw3.4开始,没有glfw-x11或glfw-wayland,它只是同一个包)所以我不必因为没有做有史以来最大的跨平台完美事情而感到羞耻。

无论如何,如果人们有意见,我会很乐意改变主意,相反,我会将其标记为我的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.