summaryrefslogtreecommitdiffstats
path: root/examples/opengl/overlay_x11/main.cpp
blob: 10ff6fc5920ac812890a2223b0c234c27f8e1f9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/****************************************************************************
**
** Example application showing how to use Qt and Qt OpenGL Extension on an 
** X11 overlay visual 
**
** Copyright (C) 1999-2008 Trolltech ASA.  All rights reserved.
**
** This file is part of an example program for Qt.  This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/

#include <qapplication.h>
#include "gearwidget.h"
#include "rubberbandwidget.h"

#if defined(Q_WS_X11)
#include <X11/Xlib.h>
#endif

QColor findOverlayTransparentColor()
{
    QColor invalidColor;

#if defined(Q_WS_X11)

    Display* appDisplay;
    Visual* appVisual;

    // The static methods are called 'App' in Qt 2.x
#if QT_VERSION < 200
    appDisplay = QPaintDevice::x__Display();
    appVisual = (Visual*)QPaintDevice::x11Visual();
#else
    appDisplay = QPaintDevice::x11AppDisplay();
    appVisual = (Visual*)QPaintDevice::x11AppVisual();
#endif

    qDebug( "Default Visual ID: 0x%x", (int)XVisualIDFromVisual(appVisual) );

    typedef struct OverlayProp {
	long  visual;
	long  type;
	long  value;
	long  layer;
    } OverlayProp;

    QWidget* rootWin = QApplication::desktop();
    if ( !rootWin )
	return invalidColor; // Should not happen

    Atom overlayVisualsAtom = XInternAtom( appDisplay, 
					   "SERVER_OVERLAY_VISUALS", True );
    if ( overlayVisualsAtom == None ) {
	warning( "Server has no overlay visuals" );
	return invalidColor;
    }

    Atom actualType;
    int actualFormat;
    ulong nItems;
    ulong bytesAfter;
    OverlayProp* overlayProp;
    int res = XGetWindowProperty( appDisplay, QApplication::desktop()->winId(),
				  overlayVisualsAtom, 0, 10000, False, 
				  overlayVisualsAtom, &actualType, 
				  &actualFormat, &nItems, &bytesAfter,
				  (uchar**)&overlayProp );

    if ( res != Success || actualType != overlayVisualsAtom 
	 || actualFormat != 32 || nItems < 4 ) {
	warning( "Failed to get overlay visual property from server" );
	return invalidColor;
    }


    for ( uint i = 0; i < nItems/4; i++ ) {
	if ( (VisualID)overlayProp[i].visual == XVisualIDFromVisual(appVisual)
	     && overlayProp[i].type == 1 )
	    return QColor( qRgb( 1, 2, 3 ), overlayProp[i].value );
    }

    qWarning( "Default visual is not in overlay plane" );
    return invalidColor;

#else // defined(Q_WS_X11)
    qWarning( "Wrong window system - Only X11 has overlay support." );
    return invalidColor;
#endif
}


int main( int argc, char **argv )
{
    QApplication::setColorSpec( QApplication::CustomColor );
    QApplication a( argc, argv );

    if ( !QGLFormat::hasOpenGL() ) {
	qWarning( "This system has no OpenGL support. Exiting." );
	return -1;
    }

    QColor transparentColor = findOverlayTransparentColor();
    if ( !transparentColor.isValid() ) {
	qWarning( "Failed to get transparent color for overlay. Exiting." );
	return -1;
    }

    QWidget top;
    a.setMainWidget( &top );
    top.setGeometry( 50, 50, 600, 400 );

    // Make an OpenGL widget. It will use the deepest visual available
    // (typically a TrueColor visual), which typically is in the normal layer.
    GearWidget g( &top );
    g.setGeometry( 20, 20, 560, 360 );

    // Put the rubberband widget (which uses the default, i.e. overlay visual)
    // on top of the OpenGL widget:
    RubberbandWidget r( transparentColor, &top );
    r.setGeometry( 20, 20, 560, 360 );

    top.show();
    return a.exec();
}