3

私はこれで髪を引っ張っています。

以下を使用して、プログラムで画面の解像度を変更しています。

int FindBestVideoMode(int screen, unsigned int &width, unsigned int &height)
{
    int modeCount;
    XF86VidModeModeInfo** modes;

    if (XF86VidModeGetAllModeLines(display, screen, &modeCount, &modes))
    {
        int bestMode  = -1;
        int bestMatch = INT_MAX;
        for(int i = 0; i < modeCount; i ++)
        {
            int match = (width  - modes[i]->hdisplay) *
                        (width  - modes[i]->hdisplay) +
                        (height - modes[i]->vdisplay) *
                        (height - modes[i]->vdisplay);

            if(match < bestMatch)
            {
                bestMatch = match;
                bestMode  = i;
            }
        }

        width  = modes[bestMode]->hdisplay;
        height = modes[bestMode]->vdisplay;

        XFree(modes);

        return bestMode;
    }

    return -1;
}

void SwitchVideoMode(int screen, int mode)
{
    if (mode >= 0)
    {
        int modeCount;
        XF86VidModeModeInfo** modes;

        if (XF86VidModeGetAllModeLines(display, screen, &modeCount, &modes))
        {
            if (mode < modeCount)
            {
                XF86VidModeSwitchToMode(display, screen, modes[mode]);
                XF86VidModeSetViewPort(display, screen, 0, 0);


                XFlush(display);
            }

            XFree(modes);
        }
    }
}

void SwitchToBestVideoMode(int screen, unsigned int &width, unsigned int &height)
{
    SwitchVideoMode(screen, FindBestVideoMode(screen, width, height));
}

void RestoreVideoMode(int screen)
{
    auto iVideoMode = DefaultVideoModes.Find(screen);
    if (iVideoMode != nullptr)
    {
        XF86VidModeSwitchToMode(display, screen, &iVideoMode->value);
        XF86VidModeSetViewPort(display, screen, 0, 0);

        XFlush(display);
    }
}

これはうまくいっています。次に、次のようにウィンドウをフルスクリーン モードにします。

XEvent e;
e.xclient.type         = ClientMessage;
e.xclient.window       = window;
e.xclient.message_type = _NET_WM_STATE;
e.xclient.format = 32;
e.xclient.data.l[0] = 2;    // _NET_WM_STATE_TOGGLE
e.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", True);
e.xclient.data.l[2] = 0;    // no second property to toggle
e.xclient.data.l[3] = 1;
e.xclient.data.l[4] = 0;

XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &e);
XMoveResizeWindow(display, window, 0, 0, width, height);

ここでの問題は、プログラムによる解像度の変更を行うときに、ウィンドウのサイズが新しい解像度セットではなく、デスクトップの解像度に合わせられることです。私が期待していたのは、実際に私が求めているのは、ウィンドウを新しい解像度のサイズに合わせることです。

ここで単純なことを誤解しているだけだと思いますが、これに関するアイデアは大歓迎です。ここでは、SDL などの外部ライブラリを使用したくありません。

ありがとう!

4

1 に答える 1

3

あなたが遭遇している問題は、あなたがあなたのウィンドウを適切に配置するためにウィンドウマネージャーに依存しているということです。残念ながら、すべてのWMがXF86VidModeまたはRandRを気にするわけではありません。ビデオモードの変更後にフルスクリーンウィンドウを作成するための標準的な解決策は、ウィンドウをフチなしの「オーバーライドリダイレクト」として作成し、WMによって管理されないようにしてから、(0、 0)から(vidmode幅、vidmode高さ)。

于 2012-10-03T13:30:06.957 に答える