~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/unix/displayx11.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/unix/displayx11.cpp
 
3
// Purpose:     Unix/X11 implementation of wxDisplay class
 
4
// Author:      Brian Victor, Vadim Zeitlin
 
5
// Modified by:
 
6
// Created:     12/05/02
 
7
// Copyright:   (c) wxWidgets team
 
8
// Licence:     wxWindows licence
 
9
/////////////////////////////////////////////////////////////////////////////
 
10
 
 
11
// ============================================================================
 
12
// declarations
 
13
// ============================================================================
 
14
 
 
15
// ----------------------------------------------------------------------------
 
16
// headers
 
17
// ----------------------------------------------------------------------------
 
18
 
 
19
// For compilers that support precompilation, includes "wx.h".
 
20
#include "wx/wxprec.h"
 
21
 
 
22
#ifdef __BORLANDC__
 
23
    #pragma hdrstop
 
24
#endif
 
25
 
 
26
#if wxUSE_DISPLAY
 
27
 
 
28
#include "wx/display.h"
 
29
 
 
30
#ifndef WX_PRECOMP
 
31
    #include "wx/dynarray.h"
 
32
    #include "wx/gdicmn.h"
 
33
    #include "wx/string.h"
 
34
    #include "wx/utils.h"
 
35
    #include "wx/intl.h"
 
36
    #include "wx/log.h"
 
37
#endif /* WX_PRECOMP */
 
38
 
 
39
#include "wx/display_impl.h"
 
40
 
 
41
#ifdef __WXGTK20__
 
42
    #include <gdk/gdk.h>
 
43
    #include <gdk/gdkx.h>
 
44
 
 
45
    // define the struct with the same fields as XineramaScreenInfo (except for
 
46
    // screen number which we don't need) but which we can use without
 
47
    // including Xinerama headers
 
48
    struct ScreenInfo
 
49
    {
 
50
       short x_org;
 
51
       short y_org;
 
52
       short width;
 
53
       short height;
 
54
    };
 
55
#else // use raw Xinerama functions
 
56
    /* These must be included after the wx files.  Otherwise the Data macro in
 
57
     * Xlibint.h conflicts with a function declaration in wx/list.h.  */
 
58
    extern "C"
 
59
    {
 
60
        #include <X11/Xlib.h>
 
61
        #include <X11/Xlibint.h>
 
62
 
 
63
        #include <X11/extensions/Xinerama.h>
 
64
    }
 
65
 
 
66
    typedef XineramaScreenInfo ScreenInfo;
 
67
#endif // GTK+/Xinerama
 
68
 
 
69
// ----------------------------------------------------------------------------
 
70
// helper class storing information about all screens
 
71
// ----------------------------------------------------------------------------
 
72
 
 
73
// the base class provides access to ScreenInfo array, derived class
 
74
// initializes it using either GTK+ or Xinerama functions
 
75
class ScreensInfoBase
 
76
{
 
77
public:
 
78
    operator const ScreenInfo *() const { return m_screens; }
 
79
 
 
80
    unsigned GetCount() const { return static_cast<unsigned>(m_num); }
 
81
 
 
82
protected:
 
83
    ScreenInfo *m_screens;
 
84
    int m_num;
 
85
};
 
86
 
 
87
#ifdef __WXGTK20__
 
88
 
 
89
class ScreensInfo : public ScreensInfoBase
 
90
{
 
91
public:
 
92
    ScreensInfo()
 
93
    {
 
94
        GdkScreen * const screen = gdk_screen_get_default();
 
95
 
 
96
        m_num = gdk_screen_get_n_monitors(screen);
 
97
        m_screens = new ScreenInfo[m_num];
 
98
        for ( int i = 0; i < m_num; i++ )
 
99
        {
 
100
            GdkRectangle rect;
 
101
            gdk_screen_get_monitor_geometry(screen, i, &rect);
 
102
            m_screens[i].x_org = rect.x;
 
103
            m_screens[i].y_org = rect.y;
 
104
            m_screens[i].width = rect.width;
 
105
            m_screens[i].height = rect.height;
 
106
        }
 
107
    }
 
108
 
 
109
    ~ScreensInfo()
 
110
    {
 
111
        delete [] m_screens;
 
112
    }
 
113
};
 
114
 
 
115
#else // Xinerama
 
116
 
 
117
class ScreensInfo : public ScreensInfoBase
 
118
{
 
119
public:
 
120
    ScreensInfo()
 
121
    {
 
122
        m_screens = XineramaQueryScreens((Display *)wxGetDisplay(), &m_num);
 
123
    }
 
124
 
 
125
    ~ScreensInfo()
 
126
    {
 
127
        XFree(m_screens);
 
128
    }
 
129
};
 
130
 
 
131
#endif // GTK+/Xinerama
 
132
 
 
133
// ----------------------------------------------------------------------------
 
134
// display and display factory classes
 
135
// ----------------------------------------------------------------------------
 
136
 
 
137
class WXDLLEXPORT wxDisplayImplX11 : public wxDisplayImpl
 
138
{
 
139
public:
 
140
    wxDisplayImplX11(unsigned n, const ScreenInfo& info)
 
141
        : wxDisplayImpl(n),
 
142
          m_rect(info.x_org, info.y_org, info.width, info.height)
 
143
    {
 
144
    }
 
145
 
 
146
    virtual wxRect GetGeometry() const { return m_rect; }
 
147
    virtual wxRect GetClientArea() const
 
148
    {
 
149
        // we intentionally don't cache the result here because the client
 
150
        // display area may change (e.g. the user resized or hid a panel) and
 
151
        // we don't currently react to its changes
 
152
        return IsPrimary() ? wxGetClientDisplayRect() : m_rect;
 
153
    }
 
154
 
 
155
    virtual wxString GetName() const { return wxString(); }
 
156
 
 
157
    virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
 
158
    virtual wxVideoMode GetCurrentMode() const;
 
159
    virtual bool ChangeMode(const wxVideoMode& mode);
 
160
 
 
161
private:
 
162
    wxRect m_rect;
 
163
    int m_depth;
 
164
 
 
165
    wxDECLARE_NO_COPY_CLASS(wxDisplayImplX11);
 
166
};
 
167
 
 
168
class wxDisplayFactoryX11 : public wxDisplayFactory
 
169
{
 
170
public:
 
171
    wxDisplayFactoryX11() { }
 
172
 
 
173
    virtual wxDisplayImpl *CreateDisplay(unsigned n);
 
174
    virtual unsigned GetCount();
 
175
    virtual int GetFromPoint(const wxPoint& pt);
 
176
 
 
177
protected:
 
178
    wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryX11);
 
179
};
 
180
 
 
181
// ============================================================================
 
182
// wxDisplayFactoryX11 implementation
 
183
// ============================================================================
 
184
 
 
185
unsigned wxDisplayFactoryX11::GetCount()
 
186
{
 
187
    return ScreensInfo().GetCount();
 
188
}
 
189
 
 
190
int wxDisplayFactoryX11::GetFromPoint(const wxPoint& p)
 
191
{
 
192
    ScreensInfo screens;
 
193
 
 
194
    const unsigned numscreens(screens.GetCount());
 
195
    for ( unsigned i = 0; i < numscreens; ++i )
 
196
    {
 
197
        const ScreenInfo& s = screens[i];
 
198
        if ( p.x >= s.x_org && p.x < s.x_org + s.width &&
 
199
                p.y >= s.y_org && p.y < s.y_org + s.height )
 
200
        {
 
201
            return i;
 
202
        }
 
203
    }
 
204
 
 
205
    return wxNOT_FOUND;
 
206
}
 
207
 
 
208
wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(unsigned n)
 
209
{
 
210
    ScreensInfo screens;
 
211
 
 
212
    return n < screens.GetCount() ? new wxDisplayImplX11(n, screens[n]) : NULL;
 
213
}
 
214
 
 
215
// ============================================================================
 
216
// wxDisplayImplX11 implementation
 
217
// ============================================================================
 
218
 
 
219
#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
 
220
 
 
221
#include <X11/extensions/xf86vmode.h>
 
222
 
 
223
//
 
224
//  See (http://www.xfree86.org/4.2.0/XF86VidModeDeleteModeLine.3.html) for more
 
225
//  info about xf86 video mode extensions
 
226
//
 
227
 
 
228
//free private data common to x (usually s3) servers
 
229
#define wxClearXVM(vm)  if(vm.privsize) XFree(vm.c_private)
 
230
 
 
231
// Correct res rate from GLFW
 
232
#define wxCRR2(v,dc) (int) (((1000.0f * (float) dc) /*PIXELS PER SECOND */) / ((float) v.htotal * v.vtotal /*PIXELS PER FRAME*/) + 0.5f)
 
233
#define wxCRR(v) wxCRR2(v,v.dotclock)
 
234
#define wxCVM2(v, dc) wxVideoMode(v.hdisplay, v.vdisplay, DefaultDepth((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay())), wxCRR2(v,dc))
 
235
#define wxCVM(v) wxCVM2(v, v.dotclock)
 
236
 
 
237
wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const
 
238
{
 
239
    //Convenience...
 
240
    Display* pDisplay = (Display*) wxGetDisplay(); //default display
 
241
    int nScreen = DefaultScreen(pDisplay); //default screen of (default) display...
 
242
 
 
243
    //Some variables..
 
244
    XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :))
 
245
    int nNumModes; //Number of modes enumerated....
 
246
 
 
247
    wxArrayVideoModes Modes; //modes to return...
 
248
 
 
249
    if (XF86VidModeGetAllModeLines(pDisplay, nScreen, &nNumModes, &ppXModes) == TRUE)
 
250
    {
 
251
        for (int i = 0; i < nNumModes; ++i)
 
252
        {
 
253
            if (mode == wxDefaultVideoMode || //According to display.h All modes valid if dafault mode...
 
254
                mode.Matches(wxCVM((*ppXModes[i]))) ) //...?
 
255
            {
 
256
                Modes.Add(wxCVM((*ppXModes[i])));
 
257
            }
 
258
            wxClearXVM((*ppXModes[i]));
 
259
        //  XFree(ppXModes[i]); //supposed to free?
 
260
        }
 
261
        XFree(ppXModes);
 
262
    }
 
263
    else //OOPS!
 
264
    {
 
265
        wxLogSysError(_("Failed to enumerate video modes"));
 
266
    }
 
267
 
 
268
    return Modes;
 
269
}
 
270
 
 
271
wxVideoMode wxDisplayImplX11::GetCurrentMode() const
 
272
{
 
273
  XF86VidModeModeLine VM;
 
274
  int nDotClock;
 
275
  XF86VidModeGetModeLine((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
 
276
                         &nDotClock, &VM);
 
277
  wxClearXVM(VM);
 
278
  return wxCVM2(VM, nDotClock);
 
279
}
 
280
 
 
281
bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode)
 
282
{
 
283
    XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :))
 
284
    int nNumModes; //Number of modes enumerated....
 
285
 
 
286
    if( !XF86VidModeGetAllModeLines((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()), &nNumModes, &ppXModes) )
 
287
    {
 
288
        wxLogSysError(_("Failed to change video mode"));
 
289
        return false;
 
290
    }
 
291
 
 
292
    bool bRet = false;
 
293
    if (mode == wxDefaultVideoMode)
 
294
    {
 
295
        bRet = XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
 
296
                     ppXModes[0]) == TRUE;
 
297
 
 
298
        for (int i = 0; i < nNumModes; ++i)
 
299
        {
 
300
            wxClearXVM((*ppXModes[i]));
 
301
        //  XFree(ppXModes[i]); //supposed to free?
 
302
        }
 
303
    }
 
304
    else
 
305
    {
 
306
        for (int i = 0; i < nNumModes; ++i)
 
307
        {
 
308
            if (!bRet &&
 
309
                ppXModes[i]->hdisplay == mode.GetWidth() &&
 
310
                ppXModes[i]->vdisplay == mode.GetHeight() &&
 
311
                wxCRR((*ppXModes[i])) == mode.GetRefresh())
 
312
            {
 
313
                //switch!
 
314
                bRet = XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
 
315
                         ppXModes[i]) == TRUE;
 
316
            }
 
317
            wxClearXVM((*ppXModes[i]));
 
318
        //  XFree(ppXModes[i]); //supposed to free?
 
319
        }
 
320
    }
 
321
 
 
322
    XFree(ppXModes);
 
323
 
 
324
    return bRet;
 
325
}
 
326
 
 
327
 
 
328
#else // !HAVE_X11_EXTENSIONS_XF86VMODE_H
 
329
 
 
330
wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& modeMatch) const
 
331
{
 
332
    int count_return;
 
333
    int* depths = XListDepths((Display*)wxGetDisplay(), 0, &count_return);
 
334
    wxArrayVideoModes modes;
 
335
    if ( depths )
 
336
    {
 
337
        for ( int x = 0; x < count_return; ++x )
 
338
        {
 
339
            wxVideoMode mode(m_rect.GetWidth(), m_rect.GetHeight(), depths[x]);
 
340
            if ( mode.Matches(modeMatch) )
 
341
            {
 
342
                modes.Add(modeMatch);
 
343
            }
 
344
        }
 
345
 
 
346
        XFree(depths);
 
347
    }
 
348
    return modes;
 
349
}
 
350
 
 
351
wxVideoMode wxDisplayImplX11::GetCurrentMode() const
 
352
{
 
353
    // Not implemented
 
354
    return wxVideoMode();
 
355
}
 
356
 
 
357
bool wxDisplayImplX11::ChangeMode(const wxVideoMode& WXUNUSED(mode))
 
358
{
 
359
    // Not implemented
 
360
    return false;
 
361
}
 
362
 
 
363
#endif // !HAVE_X11_EXTENSIONS_XF86VMODE_H
 
364
 
 
365
// ============================================================================
 
366
// wxDisplay::CreateFactory()
 
367
// ============================================================================
 
368
 
 
369
/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
 
370
{
 
371
    // GTK+ screen functions are always available, no need to check for them
 
372
#ifndef __WXGTK20__
 
373
    if ( !XineramaIsActive((Display*)wxGetDisplay()) )
 
374
        return new wxDisplayFactorySingle;
 
375
#endif
 
376
 
 
377
    return new wxDisplayFactoryX11;
 
378
}
 
379
 
 
380
#endif /* wxUSE_DISPLAY */
 
381
 
 
382
#include "wx/utils.h"
 
383
 
 
384
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 || !defined(GDK_WINDOWING_X11)
 
385
 
 
386
void wxClientDisplayRect(int *x, int *y, int *width, int *height)
 
387
{
 
388
    // TODO: don't hardcode display size
 
389
    if ( x )
 
390
        *x = 0;
 
391
    if ( y )
 
392
        *y = 0;
 
393
    if ( width )
 
394
        *width = 672;
 
395
    if ( height )
 
396
        *height = 396;
 
397
}
 
398
 
 
399
#else // !wxUSE_LIBHILDON || !wxUSE_LIBHILDON2
 
400
 
 
401
#include "wx/log.h"
 
402
 
 
403
#include <X11/Xlib.h>
 
404
#include <X11/Xatom.h>
 
405
 
 
406
// TODO: make this a full-fledged class and move to a public header
 
407
class wxX11Ptr
 
408
{
 
409
public:
 
410
    wxX11Ptr(void *ptr = NULL) : m_ptr(ptr) { }
 
411
    ~wxX11Ptr() { if ( m_ptr ) XFree(m_ptr); }
 
412
 
 
413
private:
 
414
    void *m_ptr;
 
415
 
 
416
    wxDECLARE_NO_COPY_CLASS(wxX11Ptr);
 
417
};
 
418
 
 
419
// NB: this function is implemented using X11 and not GDK calls as it's shared
 
420
//     by wxGTK[12], wxX11 and wxMotif ports
 
421
void wxClientDisplayRect(int *x, int *y, int *width, int *height)
 
422
{
 
423
    Display * const dpy = wxGetX11Display();
 
424
    wxCHECK_RET( dpy, wxT("can't be called before initializing the GUI") );
 
425
 
 
426
    wxRect rectClient;
 
427
 
 
428
    const Atom atomWorkArea = XInternAtom(dpy, "_NET_WORKAREA", True);
 
429
    if ( atomWorkArea )
 
430
    {
 
431
        long *workareas = NULL;
 
432
        unsigned long numItems;
 
433
        unsigned long bytesRemaining;
 
434
        Atom actualType;
 
435
        int format;
 
436
 
 
437
        if ( XGetWindowProperty
 
438
             (
 
439
                dpy,
 
440
                XDefaultRootWindow(dpy),
 
441
                atomWorkArea,
 
442
                0,                          // offset of data to retrieve
 
443
                4,                          // number of items to retrieve
 
444
                False,                      // don't delete property
 
445
                XA_CARDINAL,                // type of the items to get
 
446
                &actualType,
 
447
                &format,
 
448
                &numItems,
 
449
                &bytesRemaining,
 
450
                (unsigned char **)&workareas
 
451
             ) == Success && workareas )
 
452
        {
 
453
            wxX11Ptr x11ptr(workareas); // ensure it will be freed
 
454
 
 
455
            // check that we retrieved the property of the expected type and
 
456
            // that we did get back 4 longs (32 is the format for long), as
 
457
            // requested
 
458
            if ( actualType != XA_CARDINAL ||
 
459
                    format != 32 ||
 
460
                        numItems != 4 )
 
461
            {
 
462
                wxLogDebug(wxT("XGetWindowProperty(\"_NET_WORKAREA\") failed"));
 
463
            }
 
464
            else
 
465
            {
 
466
                rectClient = wxRect(workareas[0], workareas[1],
 
467
                                    workareas[2], workareas[3]);
 
468
            }
 
469
        }
 
470
    }
 
471
 
 
472
    // Although _NET_WORKAREA is supposed to return the client size of the
 
473
    // screen, not all implementations are conforming, apparently, see #14419,
 
474
    // so make sure we return a subset of the primary display.
 
475
    wxRect rectFull;
 
476
#if wxUSE_DISPLAY
 
477
    ScreensInfo screens;
 
478
    const ScreenInfo& info = screens[0];
 
479
    rectFull = wxRect(info.x_org, info.y_org, info.width, info.height);
 
480
#else
 
481
    wxDisplaySize(&rectFull.width, &rectFull.height);
 
482
#endif
 
483
 
 
484
    if ( !rectClient.width || !rectClient.height )
 
485
    {
 
486
        // _NET_WORKAREA not available or didn't work, fall back to the total
 
487
        // display size.
 
488
        rectClient = rectFull;
 
489
    }
 
490
    else
 
491
    {
 
492
        rectClient = rectClient.Intersect(rectFull);
 
493
    }
 
494
 
 
495
    if ( x )
 
496
        *x = rectClient.x;
 
497
    if ( y )
 
498
        *y = rectClient.y;
 
499
    if ( width )
 
500
        *width = rectClient.width;
 
501
    if ( height )
 
502
        *height = rectClient.height;
 
503
}
 
504
 
 
505
#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON