X11 / GLX – 全屏模式?

我正在尝试创build一个Linux应用程序 – 在这种情况下是一个屏幕保护程序 – 而且,要在全屏窗口的简单任务中find相关信息非常困难。 即使是现有的屏幕保护程序的代码,也没有提到他们如何pipe理它,我还没有看到任何明显的function,如XRemoveDecoration()

经过多次摸索之后,我确实创build了一个与桌面大小相同的窗口,其中:

 Window win = DefaultRootWindow(disp); XWindowAttributes getWinAttr; XGetWindowAttributes(disp, win, &getWinAttr); win = XCreateWindow(disp, win, 0, 0, getWinAttr.width, getWinAttr.height, 0, vInfo->depth, InputOutput, vInfo->visual, CWBorderPixel|CWColormap|CWEventMask|CWOverrideRedirect, &winAttr ); 

但是,这并没有做任何事情摆脱标题栏和边界。 我知道很明显有一种方法 – 但是我还没有find任何指向那个不依赖于其他大量图书馆被扔在顶端(现有的屏幕保护程序绝对不使用)的方向。

编辑:请不要从我的post中删除信息。 我有一个很好的理由,我明确指出,现有的屏幕保护程序没有使用可选的库,这是因为我过去大部分时间都在分析源代码。

我select了最直接回答问题的答案,并且适用于一般的应用程序。

如果你发现这个问题研究xscreensavers …同样适用。 是的,xscreensaver有它自己的API–这很复杂,而且实际上涉及到编写更多的代码行(是的,认真的)。 如果你想在你的屏幕保护程序中使用OpenGL,则需要通过另一个 API(xlockmore,一个竞争系统)以及一个将其转换为xscreensaver的兼容层。

但是,xscreensaver能够运行任何可以使用虚拟根窗口(查看vroot.h)作为屏幕保护程序的程序。 所以我的build议就是做到这一点 – 你将拥有更多的控制权,不限制的API和更好的可移植性。 (我看过的一个例子甚至可以编译Linux或Windows,使用相同的文件!)

Solutions Collecting From Web of "X11 / GLX – 全屏模式?"

一种方法是绕过窗口管理器:

 XSetWindowAttributes wa; wa.override_redirect = True; XCreateWindow( ..., &wa ); 

你缺少的信息是,屏幕保护程序不负责全屏。 屏幕保护程序守护进程将管理屏幕保护程序窗口,将其放入专用屏幕保护程序窗口层并使其全屏显示。

所以为了编写一个屏幕保护程序,你是清楚的。 如果你正在编写一个全屏游戏,你必须设置覆盖重定向属性来防止窗口被WM管理并覆盖整个屏幕。

我发现freeglut全屏效果很好,即使在内部托管着色器的opengl应用程序。 这里调用的内部代码(X11分支…)。 HTH

 #define _NET_WM_STATE_TOGGLE 2 static int fghResizeFullscrToggle(void) { XWindowAttributes attributes; if(glutGet(GLUT_FULL_SCREEN)) { /* restore original window size */ SFG_Window *win = fgStructure.CurrentWindow; fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE; fgStructure.CurrentWindow->State.Width = win->State.OldWidth; fgStructure.CurrentWindow->State.Height = win->State.OldHeight; } else { /* resize the window to cover the entire screen */ XGetWindowAttributes(fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, &attributes); /* * The "x" and "y" members of "attributes" are the window's coordinates * relative to its parent, ie to the decoration window. */ XMoveResizeWindow(fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, -attributes.x, -attributes.y, fgDisplay.ScreenWidth, fgDisplay.ScreenHeight); } return 0; } static int fghEwmhFullscrToggle(void) { XEvent xev; long evmask = SubstructureRedirectMask | SubstructureNotifyMask; if(!fgDisplay.State || !fgDisplay.StateFullScreen) { return -1; } xev.type = ClientMessage; xev.xclient.window = fgStructure.CurrentWindow->Window.Handle; xev.xclient.message_type = fgDisplay.State; xev.xclient.format = 32; xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE; xev.xclient.data.l[1] = fgDisplay.StateFullScreen; xev.xclient.data.l[2] = 0; /* no second property to toggle */ xev.xclient.data.l[3] = 1; /* source indication: application */ xev.xclient.data.l[4] = 0; /* unused */ if(!XSendEvent(fgDisplay.Display, fgDisplay.RootWindow, 0, evmask, &xev)) { return -1; } return 0; } static int fghToggleFullscreen(void) { /* first try the EWMH (_NET_WM_STATE) method ... */ if(fghEwmhFullscrToggle() != -1) { return 0; } /* fall back to resizing the window */ if(fghResizeFullscrToggle() != -1) { return 0; } return -1; } #endif /* TARGET_HOST_POSIX_X11 */ 

试着看这个例子:

真正浮油屏保Port to GLX http://rss-glx.sourceforge.net/

看看driver.c中的createWindow()函数。

这绝对不难。 您只需将正确的原子添加到右侧列表中,如此处所述。

最好和更简单的方法来实现它是使用ICCCM规范atom将适用于最新的窗口管理器。 只需使用下面的代码:

 Atom wm_state = XInternAtom (display, "_NET_WM_STATE", true ); Atom wm_fullscreen = XInternAtom (display, "_NET_WM_STATE_FULLSCREEN", true ); XChangeProperty(display, window, wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wm_fullscreen, 1); 

你的窗口可能是透明的,如果是的话,只需要使用XSetBackground()函数,你需要它并完成。