2012-10-03 4 views
1

나는 이걸 가지고 내 머리카락을 꺼내.X11, 해상도 변경 및 창 전체 화면 만들기

나는 프로그래밍 방식으로 다음과 같은 사용하여 화면의 해상도를 변경하고 있습니다 : 이것은 잘 작동

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과 같은 외부 라이브러리를 사용하고 싶지 않습니다.

감사합니다.

+0

XF86VidModeSwitch 또는 XRandr을 사용하여 디스플레이 모드를 전환하지 않는 경우에도 여전히 데스크톱 해상도이며 WM 없음 외장 WM 작성 및 왼쪽 위 모서리에 배치합니다. 데스크톱과 동일한 해상도가 필요할 때 유용합니다. 자유롭게 창을 전환하고이 창 위에 다른 창을 표시 할 수 있지만 완벽한 솔루션은 아닙니다. – keltar

+0

SDL을 사용하지 않으려는 경우에도 SDL 소스를 읽으면 SDL 소스가 어떻게 작동하는지보고 프로젝트의 해당 코드를 복제 할 수 있습니다. –

답변

1

실행중인 문제는 창 관리자가 창을 올바르게 배치해야한다는 것입니다. 불행히도 모든 WM이 XF86VidMode 또는 RandR에 대해 신경 쓰는 것은 아닙니다. 비디오 모드를 변경 한 후 전체 화면 창을 만드는 정식 솔루션은 경계선없는 윈도우를 만들고 "재정의 오버라이드"하여 WM에 의해 관리되지 않도록 설정 한 다음 (0, 0) ~ (vidmode 폭, vidmode 높이).

+0

@HavocP : 요즘에는 XF86VidMode가 RandR보다 훨씬 덜 지원됩니다. 또한 믿거 나 말거나, 그러나 일부 전체 화면 응용 프로그램에서는 게임에서 실제로 다른 프로그램이 단축키를 잡는 것을 막기를 원합니다. (Windows 키 문제를 기억하고 게이머는 키보드에서 키를 빼내려고합니다.) 스태킹 문제는 이상한 방향으로 이동하여 화면 보호기 또는 컴포지션 레이어에서 창을 만들면 해결할 수 있습니다. – datenwolf