Подтвердить что ты не робот

X11/GLX - полноэкранный режим?

Я пытаюсь создать приложение Linux - скринсейвер, в данном случае - и очень сложно найти информацию о простой задаче создания окна в полноэкранном режиме. Даже код существующих заставок не упоминает о том, как они его управляют, и я еще не вижу никакой очевидной функции, такой как XRemoveDecoration().

После долгих перерывов мне удалось создать окно того же размера, что и рабочий стол, с этим:

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

Но это не делает ничего, чтобы избавиться от заголовка и границ. Я знаю, что есть способ, очевидно - но мне еще нужно найти что-либо, даже указывающее в этом направлении, которое не полагается на какую-то другую массивную библиотеку, которая бросается сверху (существующие существующие заставки определенно не используются).

РЕДАКТИРОВАТЬ: Пожалуйста, не удаляйте информацию из моих сообщений. Существует очень веская причина, по которой я явно указал, что существующие заставки не используют дополнительные библиотеки, и это потому, что я анализировал исходный код большую часть прошедшего дня.

Я выбрал ответ, который наиболее непосредственно отвечает на вопрос и относится к приложениям вообще.

Если вы нашли этот вопрос, исследуя xscreensavers... то же самое все же применяется. Да, xscreensaver имеет свой собственный API - это сложный процесс и на самом деле включает в себя запись большего количества строк кода (да, серьезно). Если вы хотите OpenGL в вашем скринсейвере, вам нужно будет пройти через другой API (xlockmore, конкурирующую систему) и уровень совместимости, который переводит его на xscreensaver.

Однако xscreensaver способен запускать любую программу, которая может использовать виртуальные корневые окна (смотреть в vroot.h) в качестве заставки. Поэтому мой совет состоит в том, чтобы просто сделать это: у вас будет больше контроля, нет ограничения API и большая мобильность. (Один пример, на который я смотрел, может даже компилироваться для Linux или Windows с тем же файлом!)

4b9b3361

Ответ 1

Один из способов - обойти диспетчера окон:

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

Ответ 2

У вас нет информации о том, что заставки не отвечают за полноэкранный режим. Демон скринсейвера управляет окном заставки, помещает его в выделенный слой окна заставки и делает его полноэкранным.

Итак, для написания заставки вы поняли. Если бы вы писали полноэкранную игру, вам нужно установить атрибут Override Redirect, чтобы предотвратить управление окном WM и сделать его закрытым для всего экрана.

Ответ 3

Я обнаружил, что полноэкранный режим freeglut работает хорошо, даже когда вы используете приложение forend, основанное на шейдере. Здесь внутренний код, который вызывается (ветвь X11...). НТН

#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 coordinates
         * relative to its parent, i.e. 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 */

Ответ 4

Попробуйте посмотреть на пример:

На самом деле Slick Screensavers Port to GLX http://rss-glx.sourceforge.net/

Посмотрите на функцию createWindow() в файле driver.c.

Ответ 5

Это абсолютно не сложно. Вам просто нужно добавить правый атом в правый список, как описано здесь.

Ответ 6

Лучший и простой способ добиться этого - использовать спецификацию 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(), где вам это нужно, и это было сделано.