1 /////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/unix/displayx11.cpp 
   3 // Purpose:     Unix/X11 implementation of wxDisplay class 
   4 // Author:      Brian Victor, Vadim Zeitlin 
   8 // Copyright:   (c) wxWidgets team 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  29 #include "wx/display.h" 
  32     #include "wx/dynarray.h" 
  33     #include "wx/gdicmn.h" 
  34     #include "wx/string.h" 
  38 #endif /* WX_PRECOMP */ 
  40 #include "wx/display_impl.h" 
  42 /* These must be included after the wx files.  Otherwise the Data macro in 
  43  * Xlibint.h conflicts with a function declaration in wx/list.h.  */ 
  47     #include <X11/Xlibint.h> 
  49     #include <X11/extensions/Xinerama.h> 
  50     #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H 
  51         #include <X11/extensions/xf86vmode.h> 
  55 // ---------------------------------------------------------------------------- 
  56 // helper class to automatically free XineramaQueryScreens() return value 
  57 // ---------------------------------------------------------------------------- 
  64         m_screens 
= XineramaQueryScreens((Display 
*)wxGetDisplay(), &m_num
); 
  72     operator const XineramaScreenInfo 
*() const { return m_screens
; } 
  74     size_t GetCount() const { return wx_static_cast(size_t, m_num
); } 
  77     XineramaScreenInfo 
*m_screens
; 
  81 // ---------------------------------------------------------------------------- 
  82 // display and display factory classes 
  83 // ---------------------------------------------------------------------------- 
  85 class WXDLLEXPORT wxDisplayImplX11 
: public wxDisplayImpl
 
  88     wxDisplayImplX11(size_t n
, const XineramaScreenInfo
& info
) 
  90           m_rect(info
.x_org
, info
.y_org
, info
.width
, info
.height
) 
  94     virtual wxRect 
GetGeometry() const { return m_rect
; } 
  95     virtual wxString 
GetName() const { return wxString(); } 
  97     virtual wxArrayVideoModes 
GetModes(const wxVideoMode
& mode
) const; 
  98     virtual wxVideoMode 
GetCurrentMode() const; 
  99     virtual bool ChangeMode(const wxVideoMode
& mode
); 
 105     DECLARE_NO_COPY_CLASS(wxDisplayImplX11
) 
 108 class wxDisplayFactoryX11 
: public wxDisplayFactory
 
 111     wxDisplayFactoryX11() { } 
 113     virtual wxDisplayImpl 
*CreateDisplay(size_t n
); 
 114     virtual size_t GetCount(); 
 115     virtual int GetFromPoint(const wxPoint
& pt
); 
 118     DECLARE_NO_COPY_CLASS(wxDisplayFactoryX11
) 
 121 // ============================================================================ 
 122 // wxDisplayFactoryX11 implementation 
 123 // ============================================================================ 
 125 size_t wxDisplayFactoryX11::GetCount() 
 127     return ScreensInfo().GetCount(); 
 130 int wxDisplayFactoryX11::GetFromPoint(const wxPoint
& p
) 
 134     const size_t numscreens(screens
.GetCount()); 
 135     for ( size_t i 
= 0; i 
< numscreens
; ++i 
) 
 137         const XineramaScreenInfo
& s 
= screens
[i
]; 
 138         if ( p
.x 
>= s
.x_org 
&& p
.x 
< s
.x_org 
+ s
.width 
&& 
 139                 p
.y 
>= s
.y_org 
&& p
.y 
< s
.y_org 
+ s
.height 
) 
 148 wxDisplayImpl 
*wxDisplayFactoryX11::CreateDisplay(size_t n
) 
 152     return n 
< screens
.GetCount() ? new wxDisplayImplX11(n
, screens
[n
]) : NULL
; 
 155 // ============================================================================ 
 156 // wxDisplayImplX11 implementation 
 157 // ============================================================================ 
 159 #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H 
 162 //  See (http://www.xfree86.org/4.2.0/XF86VidModeDeleteModeLine.3.html) for more 
 163 //  info about xf86 video mode extensions 
 166 //free private data common to x (usually s3) servers 
 167 #define wxClearXVM(vm)  if(vm.privsize) XFree(vm.c_private) 
 169 // Correct res rate from GLFW 
 170 #define wxCRR2(v,dc) (int) (((1000.0f * (float) dc) /*PIXELS PER SECOND */) / ((float) v.htotal * v.vtotal /*PIXELS PER FRAME*/) + 0.5f) 
 171 #define wxCRR(v) wxCRR2(v,v.dotclock) 
 172 #define wxCVM2(v, dc) wxVideoMode(v.hdisplay, v.vdisplay, DefaultDepth((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay())), wxCRR2(v,dc)) 
 173 #define wxCVM(v) wxCVM2(v, v.dotclock) 
 175 wxArrayVideoModes 
wxDisplayImplX11::GetModes(const wxVideoMode
& mode
) const 
 178     Display
* pDisplay 
= (Display
*) wxGetDisplay(); //default display 
 179     int nScreen 
= DefaultScreen(pDisplay
); //default screen of (default) display... 
 182     XF86VidModeModeInfo
** ppXModes
; //Enumerated Modes (Don't forget XFree() :)) 
 183     int nNumModes
; //Number of modes enumerated.... 
 185     wxArrayVideoModes Modes
; //modes to return... 
 187     if (XF86VidModeGetAllModeLines(pDisplay
, nScreen
, &nNumModes
, &ppXModes
) == TRUE
) 
 189         for (int i 
= 0; i 
< nNumModes
; ++i
) 
 191             if (mode 
== wxDefaultVideoMode 
|| //According to display.h All modes valid if dafault mode... 
 192                 mode
.Matches(wxCVM((*ppXModes
[i
]))) ) //...? 
 194                 Modes
.Add(wxCVM((*ppXModes
[i
]))); 
 196             wxClearXVM((*ppXModes
[i
])); 
 197         //  XFree(ppXModes[i]); //supposed to free? 
 203         wxLogSysError(_("Failed to enumerate video modes")); 
 209 wxVideoMode 
wxDisplayImplX11::GetCurrentMode() const 
 211   XF86VidModeModeLine VM
; 
 213   XF86VidModeGetModeLine((Display
*)wxGetDisplay(), DefaultScreen((Display
*)wxGetDisplay()), 
 216   return wxCVM2(VM
, nDotClock
); 
 219 bool wxDisplayImplX11::ChangeMode(const wxVideoMode
& mode
) 
 221     XF86VidModeModeInfo
** ppXModes
; //Enumerated Modes (Don't forget XFree() :)) 
 222     int nNumModes
; //Number of modes enumerated.... 
 224     if( !XF86VidModeGetAllModeLines((Display
*)wxGetDisplay(), DefaultScreen((Display
*)wxGetDisplay()), &nNumModes
, &ppXModes
) ) 
 226         wxLogSysError(_("Failed to change video mode")); 
 231     if (mode 
== wxDefaultVideoMode
) 
 233         bRet 
= XF86VidModeSwitchToMode((Display
*)wxGetDisplay(), DefaultScreen((Display
*)wxGetDisplay()), 
 234                      ppXModes
[0]) == TRUE
; 
 236         for (int i 
= 0; i 
< nNumModes
; ++i
) 
 238             wxClearXVM((*ppXModes
[i
])); 
 239         //  XFree(ppXModes[i]); //supposed to free? 
 244         for (int i 
= 0; i 
< nNumModes
; ++i
) 
 247                 ppXModes
[i
]->hdisplay 
== mode
.w 
&& 
 248                 ppXModes
[i
]->vdisplay 
== mode
.h 
&& 
 249                 wxCRR((*ppXModes
[i
])) == mode
.refresh
) 
 252                 bRet 
= XF86VidModeSwitchToMode((Display
*)wxGetDisplay(), DefaultScreen((Display
*)wxGetDisplay()), 
 253                          ppXModes
[i
]) == TRUE
; 
 255             wxClearXVM((*ppXModes
[i
])); 
 256         //  XFree(ppXModes[i]); //supposed to free? 
 266 #else // !HAVE_X11_EXTENSIONS_XF86VMODE_H 
 268 wxArrayVideoModes 
wxDisplayImplX11::GetModes(const wxVideoMode
& mode
) const 
 271     int* depths 
= XListDepths((Display
*)wxGetDisplay(), 0, &count_return
); 
 272     wxArrayVideoModes modes
; 
 275         for ( int x 
= 0; x 
< count_return
; ++x 
) 
 277             modes
.Add(wxVideoMode(m_rect
.GetWidth(), m_rect
.GetHeight(), depths
[x
])); 
 285 wxVideoMode 
wxDisplayImplX11::GetCurrentMode() const 
 288     return wxVideoMode(); 
 291 bool wxDisplayImplX11::ChangeMode(const wxVideoMode
& mode
) 
 297 #endif // !HAVE_X11_EXTENSIONS_XF86VMODE_H 
 299 // ============================================================================ 
 300 // wxDisplay::CreateFactory() 
 301 // ============================================================================ 
 303 /* static */ wxDisplayFactory 
*wxDisplay::CreateFactory() 
 305     if ( XineramaIsActive((Display
*)wxGetDisplay()) ) 
 307         return new wxDisplayFactoryX11
; 
 310     return new wxDisplayFactorySingle
; 
 313 #endif /* wxUSE_DISPLAY */