BGE: alpha on frame buffer and precedence of MSAA over swap.
[blender.git] / intern / ghost / intern / GHOST_WindowX11.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file ghost/intern/GHOST_WindowX11.cpp
29  *  \ingroup GHOST
30  */
31
32 /* For standard X11 cursors */
33 #include <X11/cursorfont.h>
34 #include <X11/Xatom.h>
35 #include <X11/Xutil.h>
36 #ifdef WITH_X11_ALPHA
37 #include <X11/extensions/Xrender.h>
38 #endif
39 #include "GHOST_WindowX11.h"
40 #include "GHOST_SystemX11.h"
41 #include "STR_String.h"
42 #include "GHOST_Debug.h"
43
44 #ifdef WITH_XDND
45 #  include "GHOST_DropTargetX11.h"
46 #endif
47
48 #if defined(WITH_GL_EGL)
49 #  include "GHOST_ContextEGL.h"
50 #else
51 #  include "GHOST_ContextGLX.h"
52 #endif
53
54 #if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
55 #  include <strings.h>
56 #endif
57
58 #include <cstring>
59 #include <cstdio>
60
61 /* gethostname */
62 #include <unistd.h>
63
64 #include <algorithm>
65 #include <string>
66
67 /* For obscure full screen mode stuff
68  * lifted verbatim from blut. */
69
70 typedef struct {
71         long flags;
72         long functions;
73         long decorations;
74         long input_mode;
75 } MotifWmHints;
76
77 #define MWM_HINTS_DECORATIONS         (1L << 1)
78
79 #ifndef HOST_NAME_MAX
80 #  define HOST_NAME_MAX 64
81 #endif
82
83 // #define GHOST_X11_GRAB
84
85 /*
86  * A Client can't change the window property, that is
87  * the work of the window manager. In case, we send
88  * a ClientMessage to the RootWindow with the property
89  * and the Action (WM-spec define this):
90  */
91 #define _NET_WM_STATE_REMOVE 0
92 #define _NET_WM_STATE_ADD 1
93 // #define _NET_WM_STATE_TOGGLE 2 // UNUSED
94
95 /*
96  * import bpy
97  * ima = bpy.data.images["blender.png"]
98  * w, h = ima.size
99  * print("%d,%d," % (w, h))
100  * for y in range(h - 1, -1, -1):
101  *     px = []
102  *     for x in range(w):
103  *         p = ((y * w) + x) * 4
104  *         rgba = ima.pixels[p : p + 4]
105  *         rgba = rgba[2], rgba[1], rgba[0], rgba[3]
106  *         px.append(sum((int(p * 255) << (8 * i)) for i, p in enumerate(rgba)))
107  *     print(", ".join([str(p) for p in px]), end=",\n")
108  */
109
110 /**
111  * See the python script above to regenerate the 48x48 icon within blender
112  *
113  * \note Using 'unsigned' to avoid `-Wnarrowing` warning.
114  */
115 static const unsigned long BLENDER_ICON_48x48x32[] = {
116         48,48,
117         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
118         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
119         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
120         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 131820800, 1305304320, 2547014912, 1808620800, 432823296, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
121         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 3218103552, 4074070530, 4276450320, 4124995601, 4090518785, 1624202496, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
122         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 1053710848, 4140916224, 4294348072, 4294483011, 4294483268, 4294153273, 4107626765, 2765053184, 146759680, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
123         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 282025984, 4124007680, 4293884685, 4294482752, 4294483785, 4294483785, 4294417734, 4141905692, 3671088640, 600596224, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
124         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 1573804544, 4124073472, 4293555207, 4294416700, 4294484558, 4294484558, 4294484558, 4260005935, 4073807875, 1355766784, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
125         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 936140032, 3973012736, 4192300034, 4294415154, 4294485331, 4294485074, 4294485074, 4294088514, 4107560459, 2463128832, 79642624, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
126         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 399726848, 3452984576, 4107887616, 4294281765, 4294485590, 4294485591, 4294485590, 4294418767, 4124931612, 3469762048, 449730560, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
127         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 97281536, 2597412096, 4107427584, 4293951767, 4294485590, 4294551642, 4294486105, 4294485847, 4226320176, 4023344642, 1120754944, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
128         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 1389190400, 2949668096, 4073741568, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4291714048, 4158482693, 4294484301, 4294552415, 4294552157, 4294551899, 4294486105, 4293957442, 4124206089, 2144427008, 33488896, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
129         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 1171217408, 4107361792, 4293425685, 4294218035, 4294482753, 4294483268, 4294483783, 4294484043, 4294484558, 4294484817, 4294485331, 4294485591, 4294486105, 4294551899, 4294552157, 4294552415, 4294552672, 4294552673, 4294552930, 4294552674, 4294552674, 4294553188, 4294553190, 4294552932, 4294552674, 4294552415, 4294552156, 4294551642, 4294287696, 4124733464, 3234946560, 315970816, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
130         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 3838860800, 4293620999, 4294416700, 4294482753, 4294483269, 4294483784, 4294484300, 4294484816, 4294485331, 4294485591, 4294551642, 4294552157, 4294552672, 4294552931, 4294553446, 4294553704, 4294553962, 4294554220, 4294554221, 4294554221, 4294554220, 4294554220, 4294553962, 4294553704, 4294553190, 4294552931, 4294552416, 4294552157, 4294551642, 4294485590, 4192502315, 3939458305, 919624192, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
131         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 3838860800, 4293751810, 4294415669, 4294482753, 4294483268, 4294483784, 4294484300, 4294484816, 4294485331, 4294485591, 4294551642, 4294552157, 4294552932, 4294553447, 4294553962, 4294554220, 4294554479, 4294554737, 4294554994, 4294554994, 4294554994, 4294554737, 4294554479, 4294554220, 4294553705, 4294553446, 4294552931, 4294552416, 4294552156, 4294486105, 4294485589, 4293824827, 4124140038, 1741708800, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
132         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 2463128832, 4191905024, 4294145792, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294345234, 4294553447, 4294554221, 4294554736, 4294620787, 4294621045, 4294621047, 4294621303, 4294621047, 4294621045, 4294554995, 4294554737, 4294554220, 4294553705, 4294553190, 4294552930, 4294552414, 4294551899, 4294485847, 4294485590, 4294155594, 4141050128, 1573936384, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
133         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 248011520, 2983288320, 4191116288, 4174405120, 4174405120, 4174405120, 4174405120, 4174405120, 4174405120, 4174405120, 4174405120, 4207959552, 4294214422, 4294554220, 4294554736, 4294620787, 4294621046, 4294621562, 4294621820, 4294690967, 4294761660, 4294830292, 4294899180, 4294966780, 4294898406, 4294829002, 4294759597, 4294621304, 4294552416, 4294551900, 4294485848, 4294485332, 4294485590, 4294221646, 4140984079, 1204641024, 4671303, 4671303, 4671303, 4671303, 4671303,
134         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 79642624, 282025984, 282025984, 282025984, 282025984, 282025984, 282025984, 1540316160, 4124007680, 4226185237, 4294552156, 4294554221, 4294554737, 4294620789, 4294621561, 4294623367, 4294829774, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294966778, 4294759856, 4294552674, 4294486105, 4294485589, 4294484817, 4294551127, 4294089804, 4090651658, 885939456, 4671303, 4671303, 4671303, 4671303,
135         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 97281536, 2513394688, 4124139264, 4293888040, 4294552931, 4294553705, 4294554478, 4294554737, 4294621045, 4294692513, 4294900470, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294898922, 4294621046, 4294485589, 4294484817, 4294484558, 4294551383, 4293891393, 4023344385, 432823296, 4671303, 4671303, 4671303,
136         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 583752192, 3604045056, 4124796420, 4294285115, 4294552672, 4294553189, 4294553704, 4294554220, 4294554736, 4294623367, 4294769142, 4294835709, 4294835709, 4294835709, 4293192946, 4289446870, 4287803851, 4286620866, 4287738058, 4289446871, 4293850103, 4294901502, 4294901502, 4294901502, 4294898406, 4294552157, 4294484816, 4294484301, 4294484299, 4294486105, 4192502057, 2530172416, 4671303, 4671303, 4671303,
137         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 1473075968, 4090518784, 4259673101, 4294484042, 4294551899, 4294552415, 4294552931, 4294553447, 4294553962, 4294554995, 4294700770, 4294704123, 4294704123, 4294769916, 4290169563, 4286555330, 4286423745, 4286292416, 4286095038, 4285897917, 4285635259, 4285766844, 4291155427, 4294769916, 4294769916, 4294769916, 4294628011, 4294278923, 4294278408, 4294278149, 4294279181, 4294149404, 4140784896, 365846784, 4671303, 4671303,
138         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 163992832, 2731564288, 4124205057, 4293952286, 4294484816, 4294485590, 4294551642, 4294552157, 4294552673, 4294553188, 4294553704, 4294561702, 4294572537, 4294572537, 4294638330, 4291023841, 4286226623, 4286226623, 4286160831, 4286029502, 4285832381, 4285700795, 4284977846, 4282414755, 4280706199, 4290629597, 4294572537, 4294572537, 4294572537, 4294350393, 4294277376, 4294277376, 4294277633, 4294413864, 4158482692, 1875663872, 4671303, 4671303,
139         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 718166784, 3738197248, 4141705477, 4294283568, 4294484815, 4294484816, 4294485332, 4294485848, 4294551899, 4294552158, 4294552673, 4294553188, 4294500036, 4294440951, 4294506744, 4294243830, 4286292159, 4285963709, 4285898173, 4285832381, 4285766588, 4285372345, 4282349219, 4279391885, 4279063179, 4279063179, 4281954719, 4294375158, 4294375158, 4294375158, 4294357617, 4294277376, 4294277376, 4294277376, 4294346781, 4293557270, 3218103552, 4671303, 4671303,
140         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 1691311104, 4124007936, 4276647182, 4294416701, 4294483784, 4294484043, 4294484558, 4294485073, 4294485332, 4294485848, 4294551899, 4294552158, 4294552672, 4294372579, 4294375158, 4294375158, 4291943654, 4285569467, 4285635003, 4285569467, 4285503674, 4282875047, 4279654800, 4279063179, 4279063179, 4279063179, 4279063179, 4279128971, 4292732137, 4294177779, 4294177779, 4294233511, 4294277376, 4294277376, 4294277376, 4294344717, 4294217516, 4140784640, 50298880, 4671303,
141         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 232284672, 2949668096, 4107559426, 4294017820, 4294416960, 4294482753, 4294483268, 4294416959, 4294413348, 4294347296, 4294417474, 4294485332, 4294485848, 4294551642, 4294487137, 4294177779, 4294243572, 4294243572, 4290958047, 4285306552, 4285306553, 4284583603, 4280509077, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4291417567, 4293980400, 4294046193, 4294107085, 4294277376, 4294277376, 4294277376, 4294277376, 4294416185, 4207959811, 232284672, 4671303,
142         4671303, 4671303, 4671303, 4671303, 4671303, 852253696, 3855638016, 4158614278, 4294348586, 4294416701, 4294416443, 4294416958, 4294415411, 4294280731, 4108283403, 4243290129, 4294414638, 4294484817, 4294485331, 4294485590, 4294485848, 4294174941, 4294111986, 4294111986, 4292206309, 4284977846, 4283137961, 4279457678, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279457422, 4293454571, 4293848814, 4293848814, 4294035617, 4294277376, 4294277376, 4294277376, 4294277376, 4294416443, 4140916998, 365846784, 4671303,
143         4671303, 4671303, 4671303, 4671303, 1909480704, 4124073472, 4293490704, 4294415154, 4294415669, 4294415669, 4294416184, 4294414123, 4294083611, 4090914310, 4040055808, 4293161999, 4294414379, 4294484557, 4294484815, 4294485074, 4294485331, 4294104247, 4293914607, 4293914607, 4293783279, 4283334569, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4284057260, 4293585642, 4293651435, 4293651435, 4293962857, 4294277376, 4294277376, 4294277376, 4294277376, 4294416959, 4124205832, 499800064, 4671303,
144         4671303, 4671303, 298998272, 3150929152, 4107690755, 4294018076, 4294415410, 4294414636, 4294414638, 4294415153, 4294413606, 4293886234, 4124205059, 2110675968, 2060409856, 4225921807, 4294414895, 4294483785, 4294484043, 4294484557, 4294484815, 4294164622, 4293783021, 4293717228, 4293388263, 4290299602, 4279326093, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4280245907, 4292205535, 4293454056, 4293454056, 4293454056, 4294086704, 4294277376, 4294277376, 4294277376, 4294277891, 4294417992, 4207894017, 97281536, 4671303,
145         4671303, 50298880, 3503250688, 4192169224, 4294282278, 4294414381, 4294347813, 4294413865, 4294414122, 4294348070, 4259937303, 4090519041, 1305304320, 4671303, 1238260480, 4024002053, 4294415926, 4294483269, 4294483527, 4294483784, 4294484043, 4294419022, 4293712069, 4293190884, 4293059298, 4293059298, 4289905102, 4281297305, 4279063179, 4279063179, 4279063179, 4279063179, 4279063179, 4282677154, 4291351001, 4293256677, 4293256677, 4293256677, 4293639310, 4294277376, 4294277376, 4294277376, 4294277376, 4294345490, 4294022463, 3671088640, 4671303, 4671303,
146         4671303, 2077187328, 4107822598, 4294348586, 4294347555, 4294347039, 4294347554, 4294348069, 4294348327, 4175590163, 3872349440, 718166784, 4671303, 4671303, 449730560, 4124073472, 4294414379, 4294417217, 4294483010, 4294483268, 4294483269, 4294415927, 4294084898, 4292925905, 4292861919, 4292861919, 4292927712, 4292533470, 4288656582, 4286094006, 4284517036, 4286685370, 4289379531, 4292927713, 4293059298, 4293059298, 4293059298, 4293251260, 4294212873, 4294277376, 4294277376, 4294277376, 4294277376, 4294414896, 4259939884, 2681167104, 4671303, 4671303,
147         97281536, 4191116288, 4294084386, 4294413347, 4294346265, 4294346780, 4294413091, 4294282281, 4124732172, 3335609856, 315970816, 4671303, 4671303, 4671303, 16777216, 3452853504, 4293624609, 4294415670, 4294416702, 4294416959, 4294414121, 4294277634, 4294277376, 4293825597, 4292793547, 4292664540, 4292730333, 4292730333, 4292730333, 4292730333, 4292796126, 4292796126, 4292796126, 4292796126, 4292861919, 4292861919, 4293120190, 4294085156, 4294277376, 4294277376, 4294277376, 4294277376, 4294278149, 4294485332, 4074071305, 969825792, 4671303, 4671303,
148         198270208, 4224605184, 4294282535, 4294413347, 4294346524, 4294348070, 4294085417, 4107559687, 2563792384, 79642624, 4671303, 4671303, 83886080, 184549376, 268435456, 1605258752, 4074137355, 4294416185, 4294346522, 4294278666, 4294277376, 4294277376, 4294277376, 4294277376, 4294213647, 4293243263, 4292532696, 4292532954, 4292532954, 4292598747, 4292598747, 4292598747, 4292598747, 4292664540, 4292794579, 4293568616, 4294212357, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294414895, 4293890877, 3570425344, 4671303, 4671303, 4671303,
149         4671303, 3352387072, 4192301839, 4294282279, 4294019626, 4192302873, 4124139523, 1708088576, 4671303, 4671303, 67108864, 184549376, 285212672, 385875968, 486539264, 638387968, 3888864256, 4276847393, 4294414896, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4293954086, 4293502050, 4293179274, 4292855728, 4292662218, 4292920489, 4293243778, 4293501275, 4294083608, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294345491, 4294420571, 4107626251, 1322146816, 4671303, 4671303, 4671303,
150         4671303, 382819584, 3134217472, 4191116288, 3939458560, 2211470592, 533617152, 4671303, 4671303, 117440512, 218103808, 335544320, 436207616, 553648128, 654311424, 771751936, 1534079488, 4157496833, 4294219326, 4294346523, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294278150, 4294485590, 4175527207, 2932497152, 117440512, 4671303, 4671303, 4671303,
151         4671303, 4671303, 4671303, 50298880, 33488896, 4671303, 4671303, 4671303, 83886080, 201326592, 318767104, 436207616, 553648128, 671088640, 788529152, 889192448, 1006632960, 2493203712, 4157958415, 4294352457, 4294347039, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294278924, 4294486105, 4260073533, 3872218112, 525476096, 218103808, 100663296, 4671303, 4671303,
152         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 16777216, 134217728, 251658240, 369098752, 486539264, 603979776, 721420288, 855638016, 973078528, 1090519040, 1207959552, 2930002688, 4174604044, 4294221386, 4294414637, 4294277634, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294346522, 4294552931, 4226189107, 3888929792, 997536768, 385875968, 251658240, 150994944, 16777216, 4671303,
153         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 16777216, 134217728, 251658240, 369098752, 486539264, 603979776, 721420288, 855638016, 956301312, 1073741824, 1191182336, 1325400064, 2693873664, 4191117319, 4293891393, 4294485073, 4294347296, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294344717, 4294484299, 4294421863, 4208884260, 3687340544, 910958848, 503316480, 385875968, 251658240, 134217728, 16777216, 4671303,
154         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 83886080, 201326592, 318767104, 436207616, 536870912, 671088640, 771751936, 889192448, 989855744, 1107296256, 1207959552, 1325400064, 2187996928, 3972487680, 4191711513, 4294156111, 4294485591, 4294415926, 4294346007, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294277376, 4294278408, 4294414379, 4294484817, 4294554221, 4259941691, 4157628420, 2746568960, 807735296, 553648128, 436207616, 318767104, 218103808, 83886080, 4671303, 4671303,
155         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 100663296, 218103808, 318767104, 436207616, 536870912, 637534208, 754974720, 855638016, 956301312, 1040187392, 1140850688, 1224736768, 1342833408, 2677293568, 4174142464, 4157959447, 4276718648, 4294288986, 4294554220, 4294552415, 4294485074, 4294484300, 4294551641, 4294553705, 4294554738, 4294025043, 4175528237, 4174405895, 3384956928, 1264790528, 654311424, 553648128, 436207616, 335544320, 218103808, 117440512, 4671303, 4671303, 4671303,
156         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 50331648, 167772160, 268435456, 385875968, 469762048, 553648128, 654311424, 738197504, 822083584, 905969664, 973078528, 1023410176, 1090519040, 1208878848, 2054632960, 3165868032, 4123810816, 4224671493, 4157762069, 4124604196, 4141644844, 4124471839, 4174538769, 4241448451, 3586611712, 2275493888, 1078731776, 671088640, 570425344, 486539264, 385875968, 285212672, 184549376, 67108864, 4671303, 4671303, 4671303, 4671303,
157         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 67108864, 167772160, 251658240, 335544320, 419430400, 503316480, 570425344, 637534208, 704643072, 738197504, 788529152, 822083584, 855638016, 872415232, 889192448, 1042616320, 1365125376, 1702770688, 1821064448, 1467299072, 1095443200, 738985472, 637534208, 587202560, 503316480, 436207616, 352321536, 268435456, 184549376, 67108864, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
158         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 16777216, 67108864, 150994944, 234881024, 301989888, 352321536, 402653184, 452984832, 486539264, 520093696, 536870912, 553648128, 570425344, 570425344, 553648128, 536870912, 520093696, 486539264, 452984832, 402653184, 352321536, 301989888, 234881024, 167772160, 67108864, 16777216, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
159         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 50331648, 83886080, 134217728, 167772160, 201326592, 218103808, 234881024, 251658240, 251658240, 234881024, 218103808, 201326592, 167772160, 134217728, 83886080, 50331648, 16777216, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
160         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
161         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
162         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
163         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
164         4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
165 };
166
167 static XVisualInfo *x11_visualinfo_from_glx(
168         Display *display,
169         bool stereoVisual,
170         GHOST_TUns16 *r_numOfAASamples,
171         bool needAlpha,
172         GLXFBConfig *fbconfig)
173 {
174         XVisualInfo *visual = NULL;
175         GHOST_TUns16 numOfAASamples = *r_numOfAASamples;
176         int glx_major, glx_minor, glx_version; /* GLX version: major.minor */
177         GHOST_TUns16 actualSamples;
178         int glx_attribs[64];
179
180         *fbconfig = NULL;
181
182         /* Set up the minimum attributes that we require and see if
183          * X can find us a visual matching those requirements. */
184
185         if (!glXQueryVersion(display, &glx_major, &glx_minor)) {
186                 fprintf(stderr,
187                         "%s:%d: X11 glXQueryVersion() failed, "
188                         "verify working openGL system!\n",
189                         __FILE__, __LINE__);
190
191                 return NULL;
192         }
193         glx_version = glx_major*100 + glx_minor;
194
195         if (glx_version >= 104) {
196                 actualSamples = numOfAASamples;
197         }
198         else {
199                 numOfAASamples = 0;
200                 actualSamples = 0;
201         }
202         
203 #ifdef WITH_X11_ALPHA
204         if (   needAlpha
205             && glx_version >= 103
206             && (glXChooseFBConfig ||
207                 (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXChooseFBConfig")) != NULL)
208             && (glXGetVisualFromFBConfig ||
209                 (glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXGetVisualFromFBConfig")) != NULL)
210             ) {
211                 GLXFBConfig *fbconfigs;
212                 int nbfbconfig;
213                 int i;
214
215                 for (;;) {
216
217                         GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, true);
218
219                         fbconfigs = glXChooseFBConfig(display, DefaultScreen(display), glx_attribs, &nbfbconfig);
220
221                         /* Any sample level or even zero, which means oversampling disabled, is good
222                          * but we need a valid visual to continue */
223                         if (nbfbconfig > 0) {
224                                 /* take a frame buffer config that has alpha cap */
225                                 for (i=0 ;i<nbfbconfig; i++) {
226                                         visual = (XVisualInfo*)glXGetVisualFromFBConfig(display, fbconfigs[i]);
227                                         if (!visual)
228                                                 continue;
229                                         /* if we don't need a alpha background, the first config will do, otherwise
230                                          * test the alphaMask as it won't necessarily be present */
231                                         if (needAlpha) {
232                                                 XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual);
233                                                 if (!pict_format)
234                                                         continue;
235                                                 if (pict_format->direct.alphaMask <= 0)
236                                                         continue;
237                                         }
238                                         *fbconfig = fbconfigs[i];
239                                         break;
240                                 }
241                                 XFree(fbconfigs);
242                                 if (i<nbfbconfig) {
243                                         if (actualSamples < numOfAASamples) {
244                                                 fprintf(stderr,
245                                                         "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
246                                                         "Substituting one that uses %d samples.\n",
247                                                         numOfAASamples, actualSamples);
248                                         }
249                                         break;
250                                 }
251                                 visual = NULL;
252                         }
253
254                         if (actualSamples == 0) {
255                                 /* All options exhausted, cannot continue */
256                                 fprintf(stderr,
257                                         "%s:%d: X11 glXChooseVisual() failed, "
258                                         "verify working openGL system!\n",
259                                         __FILE__, __LINE__);
260
261                                 return NULL;
262                         }
263                         else {
264                                 --actualSamples;
265                         }
266                 }
267         }
268         else
269 #endif
270         {
271                 /* legacy, don't use extension */
272                 for (;;) {
273                         GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, false);
274                         
275                         visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs);
276
277                         /* Any sample level or even zero, which means oversampling disabled, is good
278                          * but we need a valid visual to continue */
279                         if (visual != NULL) {
280                                 if (actualSamples < numOfAASamples) {
281                                         fprintf(stderr,
282                                                 "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
283                                                 "Substituting one that uses %d samples.\n",
284                                                 numOfAASamples, actualSamples);
285                                 }
286                                 break;
287                         }
288
289                         if (actualSamples == 0) {
290                                 /* All options exhausted, cannot continue */
291                                 fprintf(stderr,
292                                         "%s:%d: X11 glXChooseVisual() failed, "
293                                         "verify working openGL system!\n",
294                                         __FILE__, __LINE__);
295
296                                 return NULL;
297                         }
298                         else {
299                                 --actualSamples;
300                         }
301                 }
302         }
303         *r_numOfAASamples = actualSamples;
304         return visual;
305 }
306
307 GHOST_WindowX11::
308 GHOST_WindowX11(GHOST_SystemX11 *system,
309         Display *display,
310         const STR_String &title,
311         GHOST_TInt32 left,
312         GHOST_TInt32 top,
313         GHOST_TUns32 width,
314         GHOST_TUns32 height,
315         GHOST_TWindowState state,
316         const GHOST_TEmbedderWindowID parentWindow,
317         GHOST_TDrawingContextType type,
318         const bool stereoVisual,
319         const bool exclusive,
320         const bool alphaBackground,
321         const GHOST_TUns16 numOfAASamples, const bool is_debug)
322     : GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples),
323       m_display(display),
324       m_visualInfo(NULL),
325       m_fbconfig(NULL),
326       m_normal_state(GHOST_kWindowStateNormal),
327       m_system(system),
328       m_invalid_window(false),
329       m_empty_cursor(None),
330       m_custom_cursor(None),
331       m_visible_cursor(None),
332 #ifdef WITH_XDND
333       m_dropTarget(NULL),
334 #endif
335 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
336       m_xic(NULL),
337 #endif
338       m_valid_setup(false),
339       m_is_debug_context(is_debug)
340 {
341         if (type == GHOST_kDrawingContextTypeOpenGL) {
342                 m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples, alphaBackground, (GLXFBConfig*)&m_fbconfig);
343         }
344         else {
345                 XVisualInfo tmp = {0};
346                 int n;
347                 m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n);
348         }
349
350         /* caller needs to check 'getValid()' */
351         if (m_visualInfo == NULL) {
352                 fprintf(stderr, "initial window could not find the GLX extension\n");
353                 return;
354         }
355
356         unsigned int xattributes_valuemask = 0;
357
358         XSetWindowAttributes xattributes;
359         memset(&xattributes, 0, sizeof(xattributes));
360
361         xattributes_valuemask |= CWBorderPixel;
362         xattributes.border_pixel = 0;
363
364         /* Specify which events we are interested in hearing. */
365
366         xattributes_valuemask |= CWEventMask;
367         xattributes.event_mask =
368                 ExposureMask | StructureNotifyMask |
369                 KeyPressMask | KeyReleaseMask |
370                 EnterWindowMask | LeaveWindowMask |
371                 ButtonPressMask | ButtonReleaseMask |
372                 PointerMotionMask | FocusChangeMask |
373                 PropertyChangeMask | KeymapStateMask;
374
375         if (exclusive) {
376                 xattributes_valuemask |= CWOverrideRedirect;
377                 xattributes.override_redirect = True;
378         }
379
380         xattributes_valuemask |= CWColormap;
381         xattributes.colormap = XCreateColormap(
382                 m_display,
383                 RootWindow(m_display, m_visualInfo->screen),
384                 m_visualInfo->visual,
385                 AllocNone
386                 );
387
388         /* create the window! */
389         if (parentWindow == 0) {
390                 m_window =  XCreateWindow(
391                         m_display,
392                         RootWindow(m_display, m_visualInfo->screen),
393                         left, top, width, height,
394                         0, /* no border. */
395                         m_visualInfo->depth,
396                         InputOutput,
397                         m_visualInfo->visual,
398                         xattributes_valuemask,
399                         &xattributes);
400         }
401         else {
402                 Window root_return;
403                 int x_return, y_return;
404                 unsigned int w_return, h_return, border_w_return, depth_return;
405                 
406                 XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return,
407                              &w_return, &h_return, &border_w_return, &depth_return);
408
409                 left = 0;
410                 top = 0;
411                 width = w_return;
412                 height = h_return;
413
414
415                 m_window = XCreateWindow(
416                         m_display,
417                         parentWindow, /* reparent against embedder */
418                         left, top, width, height,
419                         0, /* no border. */
420                         m_visualInfo->depth,
421                         InputOutput,
422                         m_visualInfo->visual,
423                         xattributes_valuemask,
424                         &xattributes);
425
426                 XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
427                 
428         }       
429
430 #ifdef WITH_XDND
431         /* initialize drop target for newly created window */
432         m_dropTarget = new GHOST_DropTargetX11(this, m_system);
433         GHOST_PRINT("Set drop target\n");
434 #endif
435
436         if (state == GHOST_kWindowStateMaximized || state == GHOST_kWindowStateFullScreen) {
437                 Atom atoms[2];
438                 int count = 0;
439                 if (state == GHOST_kWindowStateMaximized) {
440                         atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
441                         atoms[count++] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
442                 }
443                 else {
444                         atoms[count++] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
445                 }
446
447                 XChangeProperty(m_display, m_window, m_system->m_atom._NET_WM_STATE, XA_ATOM, 32,
448                                 PropModeReplace, (unsigned char *)atoms, count);
449                 m_post_init = False;
450         }
451         /*
452          * One of the problem with WM-spec is that can't set a property
453          * to a window that isn't mapped. That is why we can't "just
454          * call setState" here.
455          *
456          * To fix this, we first need know that the window is really
457          * map waiting for the MapNotify event.
458          *
459          * So, m_post_init indicate that we need wait for the MapNotify
460          * event and then set the Window state to the m_post_state.
461          */
462         else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
463                 m_post_init = True;
464                 m_post_state = state;
465         }
466         else {
467                 m_post_init = False;
468                 m_post_state = GHOST_kWindowStateNormal;
469         }
470
471
472         /* Create some hints for the window manager on how
473          * we want this window treated. */
474         {
475                 XSizeHints *xsizehints = XAllocSizeHints();
476                 xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
477                 xsizehints->x = left;
478                 xsizehints->y = top;
479                 xsizehints->width = width;
480                 xsizehints->height = height;
481                 xsizehints->min_width = 320;     /* size hints, could be made apart of the ghost api */
482                 xsizehints->min_height = 240;    /* limits are also arbitrary, but should not allow 1x1 window */
483                 xsizehints->max_width = 65535;
484                 xsizehints->max_height = 65535;
485                 XSetWMNormalHints(m_display, m_window, xsizehints);
486                 XFree(xsizehints);
487         }
488
489
490         /* XClassHint, title */
491         {
492                 XClassHint *xclasshint = XAllocClassHint();
493                 const int len = title.Length() + 1;
494                 char *wmclass = (char *)malloc(sizeof(char) * len);
495                 memcpy(wmclass, title.ReadPtr(), len * sizeof(char));
496                 xclasshint->res_name = wmclass;
497                 xclasshint->res_class = wmclass;
498                 XSetClassHint(m_display, m_window, xclasshint);
499                 free(wmclass);
500                 XFree(xclasshint);
501         }
502
503
504         /* The basic for a good ICCCM "work" */
505         if (m_system->m_atom.WM_PROTOCOLS) {
506                 Atom atoms[2];
507                 int natom = 0;
508
509                 if (m_system->m_atom.WM_DELETE_WINDOW) {
510                         atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW;
511                         natom++;
512                 }
513
514                 if (m_system->m_atom.WM_TAKE_FOCUS) {
515                         atoms[natom] = m_system->m_atom.WM_TAKE_FOCUS;
516                         natom++;
517                 }
518
519                 if (natom) {
520                         /* printf("Register atoms: %d\n", natom); */
521                         XSetWMProtocols(m_display, m_window, atoms, natom);
522                 }
523         }
524
525         /* Set the window hints */
526         {
527                 XWMHints *xwmhints = XAllocWMHints();
528                 xwmhints->initial_state = NormalState;
529                 xwmhints->input = True;
530                 xwmhints->flags = InputHint | StateHint;
531                 XSetWMHints(display, m_window, xwmhints);
532                 XFree(xwmhints);
533         }
534
535
536         /* set the icon */
537         {
538                 Atom _NET_WM_ICON     = XInternAtom(m_display, "_NET_WM_ICON", False);
539                 XChangeProperty(m_display, m_window, _NET_WM_ICON, XA_CARDINAL,
540                                 32, PropModeReplace, (unsigned char *)BLENDER_ICON_48x48x32,
541                                 BLENDER_ICON_48x48x32[0] * BLENDER_ICON_48x48x32[1] + 2);
542         }
543
544         /* set the process ID (_NET_WM_PID) */
545         {
546                 Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False);
547                 pid_t pid = getpid();
548                 XChangeProperty(m_display, m_window, _NET_WM_PID, XA_CARDINAL,
549                                 32, PropModeReplace, (unsigned char *)&pid, 1);
550         }
551
552
553         /* set the hostname (WM_CLIENT_MACHINE) */
554         {
555                 char  hostname[HOST_NAME_MAX];
556                 char *text_array[1];
557                 XTextProperty text_prop;
558
559                 gethostname(hostname, sizeof(hostname));
560                 hostname[sizeof(hostname) - 1] = '\0';
561                 text_array[0] = hostname;
562
563                 XStringListToTextProperty(text_array, 1, &text_prop);
564                 XSetWMClientMachine(m_display, m_window, &text_prop);
565                 XFree(text_prop.value);
566         }
567
568 #ifdef WITH_X11_XINPUT
569         initXInputDevices();
570
571         m_tabletData.Active = GHOST_kTabletModeNone;
572 #endif
573
574
575         /* now set up the rendering context. */
576         if (setDrawingContextType(type) == GHOST_kSuccess) {
577                 m_valid_setup = true;
578                 GHOST_PRINT("Created window\n");
579         }
580
581         setTitle(title);
582
583         if (exclusive) {
584                 XMapRaised(m_display, m_window);
585         }
586         else {
587                 XMapWindow(m_display, m_window);
588         }
589         GHOST_PRINT("Mapped window\n");
590
591         XFlush(m_display);
592 }
593
594 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
595 static void destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/)
596 {
597         GHOST_PRINT("XIM input context destroyed\n");
598
599         if (ptr) {
600                 *(XIC *)ptr = NULL;
601         }
602 }
603
604 bool GHOST_WindowX11::createX11_XIC()
605 {
606         XIM xim = m_system->getX11_XIM();
607         if (!xim)
608                 return false;
609
610         XICCallback destroy;
611         destroy.callback = (XICProc)destroyICCallback;
612         destroy.client_data = (XPointer)&m_xic;
613         m_xic = XCreateIC(xim, XNClientWindow, m_window, XNFocusWindow, m_window,
614                           XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
615                           XNResourceName, GHOST_X11_RES_NAME,
616                           XNResourceClass, GHOST_X11_RES_CLASS,
617                           XNDestroyCallback, &destroy,
618                           NULL);
619         if (!m_xic)
620                 return false;
621
622         unsigned long fevent;
623         XGetICValues(m_xic, XNFilterEvents, &fevent, NULL);
624         XSelectInput(m_display, m_window,
625                      ExposureMask | StructureNotifyMask |
626                      KeyPressMask | KeyReleaseMask |
627                      EnterWindowMask | LeaveWindowMask |
628                      ButtonPressMask | ButtonReleaseMask |
629                      PointerMotionMask | FocusChangeMask |
630                      PropertyChangeMask | KeymapStateMask | fevent);
631         return true;
632 }
633 #endif
634
635 #ifdef WITH_X11_XINPUT
636 void GHOST_WindowX11::initXInputDevices()
637 {
638         XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
639
640         if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
641                 if (version->present) {
642                         GHOST_SystemX11::GHOST_TabletX11 &xtablet = m_system->GetXTablet();
643                         XEventClass xevents[8], ev;
644                         int dcount = 0;
645
646                         /* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
647                          * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
648                          * otherwise we do not get any tablet motion event once pen is pressed... See T43367.
649                          */
650
651                         if (xtablet.StylusDevice) {
652                                 DeviceMotionNotify(xtablet.StylusDevice, xtablet.MotionEvent, ev);
653                                 if (ev) xevents[dcount++] = ev;
654                                 DeviceButtonPress(xtablet.StylusDevice, xtablet.PressEvent, ev);
655                                 if (ev) xevents[dcount++] = ev;
656                                 ProximityIn(xtablet.StylusDevice, xtablet.ProxInEvent, ev);
657                                 if (ev) xevents[dcount++] = ev;
658                                 ProximityOut(xtablet.StylusDevice, xtablet.ProxOutEvent, ev);
659                                 if (ev) xevents[dcount++] = ev;
660                         }
661                         if (xtablet.EraserDevice) {
662                                 DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEventEraser, ev);
663                                 if (ev) xevents[dcount++] = ev;
664                                 DeviceButtonPress(xtablet.EraserDevice, xtablet.PressEventEraser, ev);
665                                 if (ev) xevents[dcount++] = ev;
666                                 ProximityIn(xtablet.EraserDevice, xtablet.ProxInEventEraser, ev);
667                                 if (ev) xevents[dcount++] = ev;
668                                 ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEventEraser, ev);
669                                 if (ev) xevents[dcount++] = ev;
670                         }
671
672                         XSelectExtensionEvent(m_display, m_window, xevents, dcount);
673                 }
674                 XFree(version);
675         }
676 }
677
678 #endif /* WITH_X11_XINPUT */
679
680 Window
681 GHOST_WindowX11::
682 getXWindow()
683 {
684         return m_window;
685 }
686
687 bool
688 GHOST_WindowX11::
689 getValid() const
690 {
691         return GHOST_Window::getValid() && m_valid_setup;
692 }
693
694 void
695 GHOST_WindowX11::
696 setTitle(
697                 const STR_String& title)
698 {
699         Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
700         Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
701         XChangeProperty(m_display, m_window,
702                         name, utf8str, 8, PropModeReplace,
703                         (const unsigned char *) title.ReadPtr(),
704                         title.Length());
705
706         /* This should convert to valid x11 string
707          * and getTitle would need matching change */
708         XStoreName(m_display, m_window, title);
709
710         XFlush(m_display);
711 }
712
713 void
714 GHOST_WindowX11::
715 getTitle(
716                 STR_String& title) const
717 {
718         char *name = NULL;
719         
720         XFetchName(m_display, m_window, &name);
721         title = name ? name : "untitled";
722         XFree(name);
723 }
724         
725 void
726 GHOST_WindowX11::
727 getWindowBounds(
728                 GHOST_Rect& bounds) const
729 {
730         /* Getting the window bounds under X11 is not
731          * really supported (nor should it be desired). */
732         getClientBounds(bounds);
733 }
734
735 void
736 GHOST_WindowX11::
737 getClientBounds(
738                 GHOST_Rect& bounds) const
739 {
740         Window root_return;
741         int x_return, y_return;
742         unsigned int w_return, h_return, border_w_return, depth_return;
743         GHOST_TInt32 screen_x, screen_y;
744         
745         XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
746                      &w_return, &h_return, &border_w_return, &depth_return);
747
748         clientToScreen(0, 0, screen_x, screen_y);
749         
750         bounds.m_l = screen_x;
751         bounds.m_r = bounds.m_l + w_return;
752         bounds.m_t = screen_y;
753         bounds.m_b = bounds.m_t + h_return;
754
755 }
756
757 GHOST_TSuccess
758 GHOST_WindowX11::
759 setClientWidth(
760                 GHOST_TUns32 width)
761 {
762         XWindowChanges values;
763         unsigned int value_mask = CWWidth;
764         values.width = width;
765         XConfigureWindow(m_display, m_window, value_mask, &values);
766
767         return GHOST_kSuccess;
768 }
769
770 GHOST_TSuccess
771 GHOST_WindowX11::
772 setClientHeight(
773                 GHOST_TUns32 height)
774 {
775         XWindowChanges values;
776         unsigned int value_mask = CWHeight;
777         values.height = height;
778         XConfigureWindow(m_display, m_window, value_mask, &values);
779         return GHOST_kSuccess;
780
781 }
782
783 GHOST_TSuccess
784 GHOST_WindowX11::
785 setClientSize(
786                 GHOST_TUns32 width,
787                 GHOST_TUns32 height)
788 {
789         XWindowChanges values;
790         unsigned int value_mask = CWWidth | CWHeight;
791         values.width = width;
792         values.height = height;
793         XConfigureWindow(m_display, m_window, value_mask, &values);
794         return GHOST_kSuccess;
795
796 }       
797
798 void
799 GHOST_WindowX11::
800 screenToClient(
801                 GHOST_TInt32 inX,
802                 GHOST_TInt32 inY,
803                 GHOST_TInt32& outX,
804                 GHOST_TInt32& outY) const
805 {
806         /* This is correct! */
807
808         int ax, ay;
809         Window temp;
810
811         XTranslateCoordinates(m_display,
812                               RootWindow(m_display, m_visualInfo->screen),
813                               m_window,
814                               inX, inY,
815                               &ax, &ay,
816                               &temp);
817         outX = ax;
818         outY = ay;
819 }
820                  
821 void
822 GHOST_WindowX11::
823 clientToScreen(
824                 GHOST_TInt32 inX,
825                 GHOST_TInt32 inY,
826                 GHOST_TInt32& outX,
827                 GHOST_TInt32& outY) const
828 {
829         int ax, ay;
830         Window temp;
831
832         XTranslateCoordinates(
833             m_display,
834             m_window,
835             RootWindow(m_display, m_visualInfo->screen),
836             inX, inY,
837             &ax, &ay,
838             &temp);
839         outX = ax;
840         outY = ay;
841 }
842
843 void GHOST_WindowX11::icccmSetState(int state)
844 {
845         XEvent xev;
846
847         if (state != IconicState)
848                 return;
849
850         xev.xclient.type = ClientMessage;
851         xev.xclient.serial = 0;
852         xev.xclient.send_event = True;
853         xev.xclient.display = m_display;
854         xev.xclient.window = m_window;
855         xev.xclient.format = 32;
856         xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE;
857         xev.xclient.data.l[0] = state;
858         XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
859                    False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
860 }
861
862 int GHOST_WindowX11::icccmGetState(void) const
863 {
864         Atom *prop_ret;
865         unsigned long bytes_after, num_ret;
866         Atom type_ret;
867         int format_ret, st;
868
869         prop_ret = NULL;
870         st = XGetWindowProperty(
871                 m_display, m_window, m_system->m_atom.WM_STATE, 0, 2,
872                 False, m_system->m_atom.WM_STATE, &type_ret,
873                 &format_ret, &num_ret, &bytes_after, ((unsigned char **)&prop_ret));
874         if ((st == Success) && (prop_ret) && (num_ret == 2))
875                 st = prop_ret[0];
876         else
877                 st = NormalState;
878
879         if (prop_ret)
880                 XFree(prop_ret);
881         return (st);
882 }
883
884 void GHOST_WindowX11::netwmMaximized(bool set)
885 {
886         XEvent xev;
887
888         xev.xclient.type = ClientMessage;
889         xev.xclient.serial = 0;
890         xev.xclient.send_event = True;
891         xev.xclient.window = m_window;
892         xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
893         xev.xclient.format = 32;
894
895         if (set == True)
896                 xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
897         else
898                 xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
899
900         xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
901         xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
902         xev.xclient.data.l[3] = 0;
903         xev.xclient.data.l[4] = 0;
904         XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
905                    False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
906 }
907
908 bool GHOST_WindowX11::netwmIsMaximized(void) const
909 {
910         Atom *prop_ret;
911         unsigned long bytes_after, num_ret, i;
912         Atom type_ret;
913         bool st;
914         int format_ret, ret, count;
915
916         prop_ret = NULL;
917         st = False;
918         ret = XGetWindowProperty(
919                 m_display, m_window, m_system->m_atom._NET_WM_STATE, 0, INT_MAX,
920                 False, XA_ATOM, &type_ret, &format_ret,
921                 &num_ret, &bytes_after, (unsigned char **)&prop_ret);
922         if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
923                 count = 0;
924                 for (i = 0; i < num_ret; i++) {
925                         if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ) {
926                                 count++;
927                         }
928                         if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT) {
929                                 count++;
930                         }
931                         if (count == 2) {
932                                 st = True;
933                                 break;
934                         }
935                 }
936         }
937
938         if (prop_ret)
939                 XFree(prop_ret);
940         return (st);
941 }
942
943 void GHOST_WindowX11::netwmFullScreen(bool set)
944 {
945         XEvent xev;
946
947         xev.xclient.type = ClientMessage;
948         xev.xclient.serial = 0;
949         xev.xclient.send_event = True;
950         xev.xclient.window = m_window;
951         xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
952         xev.xclient.format = 32;
953
954         if (set == True)
955                 xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
956         else
957                 xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
958
959         xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
960         xev.xclient.data.l[2] = 0;
961         xev.xclient.data.l[3] = 0;
962         xev.xclient.data.l[4] = 0;
963         XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
964                    False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
965 }
966
967 bool GHOST_WindowX11::netwmIsFullScreen(void) const
968 {
969         Atom *prop_ret;
970         unsigned long bytes_after, num_ret, i;
971         Atom type_ret;
972         bool st;
973         int format_ret, ret;
974
975         prop_ret = NULL;
976         st = False;
977         ret = XGetWindowProperty(
978                 m_display, m_window, m_system->m_atom._NET_WM_STATE, 0, INT_MAX,
979                 False, XA_ATOM, &type_ret, &format_ret,
980                 &num_ret, &bytes_after, (unsigned char **)&prop_ret);
981         if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
982                 for (i = 0; i < num_ret; i++) {
983                         if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) {
984                                 st = True;
985                                 break;
986                         }
987                 }
988         }
989
990         if (prop_ret)
991                 XFree(prop_ret);
992         return (st);
993 }
994
995 void GHOST_WindowX11::motifFullScreen(bool set)
996 {
997         MotifWmHints hints;
998
999         hints.flags = MWM_HINTS_DECORATIONS;
1000         if (set == True)
1001                 hints.decorations = 0;
1002         else
1003                 hints.decorations = 1;
1004
1005         XChangeProperty(m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS,
1006                         m_system->m_atom._MOTIF_WM_HINTS, 32, PropModeReplace,
1007                         (unsigned char *) &hints, 4);
1008 }
1009
1010 bool GHOST_WindowX11::motifIsFullScreen(void) const
1011 {
1012         MotifWmHints *prop_ret;
1013         unsigned long bytes_after, num_ret;
1014         Atom type_ret;
1015         bool state;
1016         int format_ret, st;
1017
1018         prop_ret = NULL;
1019         state = False;
1020         st = XGetWindowProperty(
1021                 m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS, 0, INT_MAX,
1022                 False, m_system->m_atom._MOTIF_WM_HINTS,
1023                 &type_ret, &format_ret, &num_ret,
1024                 &bytes_after, (unsigned char **)&prop_ret);
1025         if ((st == Success) && prop_ret) {
1026                 if (prop_ret->flags & MWM_HINTS_DECORATIONS) {
1027                         if (!prop_ret->decorations)
1028                                 state = True;
1029                 }
1030         }
1031
1032         if (prop_ret)
1033                 XFree(prop_ret);
1034         return (state);
1035 }
1036
1037 GHOST_TWindowState GHOST_WindowX11::getState() const
1038 {
1039         GHOST_TWindowState state_ret;
1040         int state;
1041
1042         state_ret = GHOST_kWindowStateNormal;
1043         state = icccmGetState();
1044         /*
1045          * In the Iconic and Withdrawn state, the window
1046          * is unmaped, so only need return a Minimized state.
1047          */
1048         if ((state == IconicState) || (state == WithdrawnState))
1049                 state_ret = GHOST_kWindowStateMinimized;
1050         else if (netwmIsFullScreen() == True)
1051                 state_ret = GHOST_kWindowStateFullScreen;
1052         else if (motifIsFullScreen() == True)
1053                 state_ret = GHOST_kWindowStateFullScreen;
1054         else if (netwmIsMaximized() == True)
1055                 state_ret = GHOST_kWindowStateMaximized;
1056         return (state_ret);
1057 }
1058
1059 GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
1060 {
1061         GHOST_TWindowState cur_state;
1062         bool is_max, is_full, is_motif_full;
1063
1064         cur_state = getState();
1065         if (state == (int)cur_state)
1066                 return GHOST_kSuccess;
1067
1068         if (cur_state != GHOST_kWindowStateMinimized) {
1069                 /*
1070                  * The window don't have this property's
1071                  * if it's not mapped.
1072                  */
1073                 is_max = netwmIsMaximized();
1074                 is_full = netwmIsFullScreen();
1075         }
1076         else {
1077                 is_max = False;
1078                 is_full = False;
1079         }
1080
1081         is_motif_full = motifIsFullScreen();
1082
1083         if (state == GHOST_kWindowStateNormal)
1084                 state = m_normal_state;
1085
1086         if (state == GHOST_kWindowStateNormal) {
1087                 if (is_max == True)
1088                         netwmMaximized(False);
1089                 if (is_full == True)
1090                         netwmFullScreen(False);
1091                 if (is_motif_full == True)
1092                         motifFullScreen(False);
1093                 icccmSetState(NormalState);
1094                 return (GHOST_kSuccess);
1095         }
1096
1097         if (state == GHOST_kWindowStateFullScreen) {
1098                 /*
1099                  * We can't change to full screen if the window
1100                  * isn't mapped.
1101                  */
1102                 if (cur_state == GHOST_kWindowStateMinimized)
1103                         return (GHOST_kFailure);
1104
1105                 m_normal_state = cur_state;
1106
1107                 if (is_max == True)
1108                         netwmMaximized(False);
1109                 if (is_full == False)
1110                         netwmFullScreen(True);
1111                 if (is_motif_full == False)
1112                         motifFullScreen(True);
1113                 return (GHOST_kSuccess);
1114         }
1115
1116         if (state == GHOST_kWindowStateMaximized) {
1117                 /*
1118                  * We can't change to Maximized if the window
1119                  * isn't mapped.
1120                  */
1121                 if (cur_state == GHOST_kWindowStateMinimized)
1122                         return (GHOST_kFailure);
1123
1124                 if (is_full == True)
1125                         netwmFullScreen(False);
1126                 if (is_motif_full == True)
1127                         motifFullScreen(False);
1128                 if (is_max == False)
1129                         netwmMaximized(True);
1130                 return (GHOST_kSuccess);
1131         }
1132
1133         if (state == GHOST_kWindowStateMinimized) {
1134                 /*
1135                  * The window manager need save the current state of
1136                  * the window (maximized, full screen, etc).
1137                  */
1138                 icccmSetState(IconicState);
1139                 return (GHOST_kSuccess);
1140         }
1141
1142         return (GHOST_kFailure);
1143 }
1144
1145 #include <iostream>
1146
1147 GHOST_TSuccess
1148 GHOST_WindowX11::
1149 setOrder(
1150                 GHOST_TWindowOrder order)
1151 {
1152         if (order == GHOST_kWindowOrderTop) {
1153                 XWindowAttributes attr;   
1154                 Atom atom;
1155
1156                 /* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some
1157                  * window managers ignore the former (e.g. kwin from kde) and others
1158                  * don't implement the latter (e.g. fluxbox pre 0.9.9) */
1159
1160                 XRaiseWindow(m_display, m_window);
1161
1162                 atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True);
1163
1164                 if (atom != None) {
1165                         Window root;
1166                         XEvent xev;
1167                         long eventmask;
1168
1169                         xev.xclient.type = ClientMessage;
1170                         xev.xclient.serial = 0;
1171                         xev.xclient.send_event = True;
1172                         xev.xclient.window = m_window;
1173                         xev.xclient.message_type = atom;
1174
1175                         xev.xclient.format = 32;
1176                         xev.xclient.data.l[0] = 1;
1177                         xev.xclient.data.l[1] = CurrentTime;
1178                         xev.xclient.data.l[2] = m_window;
1179                         xev.xclient.data.l[3] = 0;
1180                         xev.xclient.data.l[4] = 0;
1181
1182                         root = RootWindow(m_display, m_visualInfo->screen);
1183                         eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
1184
1185                         XSendEvent(m_display, root, False, eventmask, &xev);
1186                 }
1187
1188                 XGetWindowAttributes(m_display, m_window, &attr);
1189
1190                 /* iconized windows give bad match error */
1191                 if (attr.map_state == IsViewable)
1192                         XSetInputFocus(m_display, m_window, RevertToPointerRoot,
1193                                        CurrentTime);
1194                 XFlush(m_display);
1195         }
1196         else if (order == GHOST_kWindowOrderBottom) {
1197                 XLowerWindow(m_display, m_window);
1198                 XFlush(m_display);
1199         }
1200         else {
1201                 return GHOST_kFailure;
1202         }
1203         
1204         return GHOST_kSuccess;
1205 }
1206
1207 GHOST_TSuccess
1208 GHOST_WindowX11::
1209 invalidate()
1210 {
1211         /* So the idea of this function is to generate an expose event
1212          * for the window.
1213          * Unfortunately X does not handle expose events for you and
1214          * it is the client's job to refresh the dirty part of the window.
1215          * We need to queue up invalidate calls and generate GHOST events
1216          * for them in the system.
1217          *
1218          * We implement this by setting a boolean in this class to concatenate
1219          * all such calls into a single event for this window.
1220          *
1221          * At the same time we queue the dirty windows in the system class
1222          * and generate events for them at the next processEvents call. */
1223
1224         if (m_invalid_window == false) {
1225                 m_system->addDirtyWindow(this);
1226                 m_invalid_window = true;
1227         } 
1228  
1229         return GHOST_kSuccess;
1230 }
1231
1232 /**
1233  * called by the X11 system implementation when expose events
1234  * for the window have been pushed onto the GHOST queue
1235  */
1236  
1237 void
1238 GHOST_WindowX11::
1239 validate()
1240 {
1241         m_invalid_window = false;
1242 }       
1243  
1244  
1245 /**
1246  * Destructor.
1247  * Closes the window and disposes resources allocated.
1248  */
1249
1250 GHOST_WindowX11::
1251 ~GHOST_WindowX11()
1252 {
1253         std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
1254         for (; it != m_standard_cursors.end(); ++it) {
1255                 XFreeCursor(m_display, it->second);
1256         }
1257
1258         if (m_empty_cursor) {
1259                 XFreeCursor(m_display, m_empty_cursor);
1260         }
1261         if (m_custom_cursor) {
1262                 XFreeCursor(m_display, m_custom_cursor);
1263         }
1264
1265         if (m_valid_setup) {
1266                 static Atom Primary_atom, Clipboard_atom;
1267                 Window p_owner, c_owner;
1268                 /*Change the owner of the Atoms to None if we are the owner*/
1269                 Primary_atom = XInternAtom(m_display, "PRIMARY", False);
1270                 Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
1271
1272
1273                 p_owner = XGetSelectionOwner(m_display, Primary_atom);
1274                 c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
1275
1276                 if (p_owner == m_window) {
1277                         XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
1278                 }
1279                 if (c_owner == m_window) {
1280                         XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
1281                 }
1282         }
1283         
1284         if (m_visualInfo) {
1285                 XFree(m_visualInfo);
1286         }
1287
1288 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
1289         if (m_xic) {
1290                 XDestroyIC(m_xic);
1291         }
1292 #endif
1293
1294 #ifdef WITH_XDND
1295         delete m_dropTarget;
1296 #endif
1297
1298         releaseNativeHandles();
1299
1300         if (m_valid_setup) {
1301                 XDestroyWindow(m_display, m_window);
1302         }
1303 }
1304
1305
1306 GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
1307 {
1308         if (type == GHOST_kDrawingContextTypeOpenGL) {
1309 #if !defined(WITH_GL_EGL)
1310
1311 #if defined(WITH_GL_PROFILE_CORE)
1312                 GHOST_Context *context = new GHOST_ContextGLX(
1313                         m_wantStereoVisual,
1314                         m_wantNumOfAASamples,
1315                         m_window,
1316                         m_display,
1317                         m_visualInfo,
1318                         (GLXFBConfig)m_fbconfig,
1319                         GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
1320                         3, 2,
1321                         GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
1322                         GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
1323 #elif defined(WITH_GL_PROFILE_ES20)
1324                 GHOST_Context *context = new GHOST_ContextGLX(
1325                         m_wantStereoVisual,
1326                         m_wantNumOfAASamples,
1327                         m_window,
1328                         m_display,
1329                         m_visualInfo,
1330                         (GLXFBConfig)m_fbconfig,
1331                         GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
1332                         2, 0,
1333                         GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
1334                         GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
1335 #elif defined(WITH_GL_PROFILE_COMPAT)
1336                 GHOST_Context *context = new GHOST_ContextGLX(
1337                         m_wantStereoVisual,
1338                         m_wantNumOfAASamples,
1339                         m_window,
1340                         m_display,
1341                         m_visualInfo,
1342                         (GLXFBConfig)m_fbconfig,
1343                         0, // profile bit
1344                         0, 0,
1345                         GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
1346                         GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
1347 #else
1348 #  error
1349 #endif
1350
1351 #else
1352
1353 #if defined(WITH_GL_PROFILE_CORE)
1354                 GHOST_Context *context = new GHOST_ContextEGL(
1355                         m_wantStereoVisual,
1356                         m_wantNumOfAASamples,
1357                         m_window,
1358                         m_display,
1359                         EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
1360                         3, 2,
1361                         GHOST_OPENGL_EGL_CONTEXT_FLAGS,
1362                         GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
1363                         EGL_OPENGL_API);
1364 #elif defined(WITH_GL_PROFILE_ES20)
1365                 GHOST_Context *context = new GHOST_ContextEGL(
1366                         m_wantStereoVisual,
1367                         m_wantNumOfAASamples,
1368                         m_window,
1369                         m_display,
1370                         0, // profile bit
1371                         2, 0,
1372                         GHOST_OPENGL_EGL_CONTEXT_FLAGS,
1373                         GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
1374                         EGL_OPENGL_ES_API);
1375 #elif defined(WITH_GL_PROFILE_COMPAT)
1376                 GHOST_Context *context = new GHOST_ContextEGL(
1377                         m_wantStereoVisual,
1378                         m_wantNumOfAASamples,
1379                         m_window,
1380                         m_display,
1381                         0, // profile bit
1382                         0, 0,
1383                         GHOST_OPENGL_EGL_CONTEXT_FLAGS,
1384                         GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
1385                         EGL_OPENGL_API);
1386 #else
1387 #  error
1388 #endif
1389
1390 #endif
1391                 if (context->initializeDrawingContext())
1392                         return context;
1393                 else
1394                         delete context;
1395         }
1396
1397         return NULL;
1398 }
1399
1400
1401 Cursor
1402 GHOST_WindowX11::
1403 getStandardCursor(
1404                 GHOST_TStandardCursor g_cursor)
1405 {
1406         unsigned int xcursor_id;
1407
1408 #define GtoX(gcurs, xcurs)  case gcurs: xcursor_id = xcurs
1409         switch (g_cursor) {
1410                 GtoX(GHOST_kStandardCursorRightArrow, XC_arrow); break;
1411                 GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow); break;
1412                 GtoX(GHOST_kStandardCursorInfo, XC_hand1); break;
1413                 GtoX(GHOST_kStandardCursorDestroy, XC_pirate); break;
1414                 GtoX(GHOST_kStandardCursorHelp, XC_question_arrow); break;
1415                 GtoX(GHOST_kStandardCursorCycle, XC_exchange); break;
1416                 GtoX(GHOST_kStandardCursorSpray, XC_spraycan); break;
1417                 GtoX(GHOST_kStandardCursorWait, XC_watch); break;
1418                 GtoX(GHOST_kStandardCursorText, XC_xterm); break;
1419                 GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair); break;
1420                 GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow); break;
1421                 GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow); break;
1422                 GtoX(GHOST_kStandardCursorTopSide, XC_top_side); break;
1423                 GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side); break;
1424                 GtoX(GHOST_kStandardCursorLeftSide, XC_left_side); break;
1425                 GtoX(GHOST_kStandardCursorRightSide, XC_right_side); break;
1426                 GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner); break;
1427                 GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner); break;
1428                 GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner); break;
1429                 GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner); break;
1430                 GtoX(GHOST_kStandardCursorPencil, XC_pencil); break;
1431                 GtoX(GHOST_kStandardCursorCopy, XC_arrow); break;
1432                 default:
1433                         xcursor_id = 0;
1434         }
1435 #undef GtoX
1436
1437         if (xcursor_id) {
1438                 Cursor xcursor = m_standard_cursors[xcursor_id];
1439                 
1440                 if (!xcursor) {
1441                         xcursor = XCreateFontCursor(m_display, xcursor_id);
1442
1443                         m_standard_cursors[xcursor_id] = xcursor;
1444                 }
1445                 
1446                 return xcursor;
1447         }
1448         else {
1449                 return None;
1450         }
1451 }
1452
1453 Cursor
1454 GHOST_WindowX11::
1455 getEmptyCursor(
1456         ) {
1457         if (!m_empty_cursor) {
1458                 Pixmap blank;
1459                 XColor dummy = {0};
1460                 char data[1] = {0};
1461                         
1462                 /* make a blank cursor */
1463                 blank = XCreateBitmapFromData(
1464                     m_display,
1465                     RootWindow(m_display, m_visualInfo->screen),
1466                     data, 1, 1
1467                     );
1468
1469                 m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0);
1470                 XFreePixmap(m_display, blank);
1471         }
1472
1473         return m_empty_cursor;
1474 }
1475
1476 GHOST_TSuccess
1477 GHOST_WindowX11::
1478 setWindowCursorVisibility(
1479                 bool visible)
1480 {
1481         Cursor xcursor;
1482         
1483         if (visible) {
1484                 if (m_visible_cursor)
1485                         xcursor = m_visible_cursor;
1486                 else
1487                         xcursor = getStandardCursor(getCursorShape() );
1488         }
1489         else {
1490                 xcursor = getEmptyCursor();
1491         }
1492
1493         XDefineCursor(m_display, m_window, xcursor);
1494         XFlush(m_display);
1495         
1496         return GHOST_kSuccess;
1497 }
1498
1499 GHOST_TSuccess
1500 GHOST_WindowX11::
1501 setWindowCursorGrab(
1502                 GHOST_TGrabCursorMode mode)
1503 {
1504         if (mode != GHOST_kGrabDisable) {
1505                 if (mode != GHOST_kGrabNormal) {
1506                         m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
1507                         setCursorGrabAccum(0, 0);
1508
1509                         if (mode == GHOST_kGrabHide)
1510                                 setWindowCursorVisibility(false);
1511
1512                 }
1513 #ifdef GHOST_X11_GRAB
1514                 XGrabPointer(m_display, m_window, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
1515                              GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
1516 #endif
1517         }
1518         else {
1519                 if (m_cursorGrab == GHOST_kGrabHide) {
1520                         m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
1521                         setWindowCursorVisibility(true);
1522                 }
1523
1524                 if (m_cursorGrab != GHOST_kGrabNormal) {
1525                         /* use to generate a mouse move event, otherwise the last event
1526                          * blender gets can be outside the screen causing menus not to show
1527                          * properly unless the user moves the mouse */
1528                         XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0);
1529                 }
1530
1531                 /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
1532                 setCursorGrabAccum(0, 0);
1533                 m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
1534 #ifdef GHOST_X11_GRAB
1535                 XUngrabPointer(m_display, CurrentTime);
1536 #endif
1537         }
1538
1539         XFlush(m_display);
1540         
1541         return GHOST_kSuccess;
1542 }
1543
1544 GHOST_TSuccess
1545 GHOST_WindowX11::
1546 setWindowCursorShape(
1547                 GHOST_TStandardCursor shape)
1548 {
1549         Cursor xcursor = getStandardCursor(shape);
1550
1551         m_visible_cursor = xcursor;
1552         
1553         XDefineCursor(m_display, m_window, xcursor);
1554         XFlush(m_display);
1555
1556         return GHOST_kSuccess;
1557 }
1558
1559 GHOST_TSuccess
1560 GHOST_WindowX11::
1561 setWindowCustomCursorShape(
1562                 GHOST_TUns8 bitmap[16][2],
1563                 GHOST_TUns8 mask[16][2],
1564                 int hotX,
1565                 int hotY)
1566 {
1567         setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask,
1568                                    16, 16, hotX, hotY, 0, 1);
1569         return GHOST_kSuccess;
1570 }
1571
1572 GHOST_TSuccess
1573 GHOST_WindowX11::
1574 setWindowCustomCursorShape(     
1575                 GHOST_TUns8 *bitmap,
1576                 GHOST_TUns8 *mask,
1577                 int sizex,
1578                 int sizey,
1579                 int hotX,
1580                 int hotY,
1581                 int /*fg_color*/,
1582                 int /*bg_color*/)
1583 {
1584         Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen);
1585         Pixmap bitmap_pix, mask_pix;
1586         XColor fg, bg;
1587         
1588         if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure;
1589         if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure;
1590
1591         if (m_custom_cursor) {
1592                 XFreeCursor(m_display, m_custom_cursor);
1593         }
1594
1595         bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *) bitmap, sizex, sizey);
1596         mask_pix = XCreateBitmapFromData(m_display, m_window, (char *) mask, sizex, sizey);
1597                 
1598         m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
1599         XDefineCursor(m_display, m_window, m_custom_cursor);
1600         XFlush(m_display);
1601
1602         m_visible_cursor = m_custom_cursor;
1603         
1604         XFreePixmap(m_display, bitmap_pix);
1605         XFreePixmap(m_display, mask_pix);
1606
1607         XFreeColors(m_display, colormap, &fg.pixel, 1, 0L);
1608         XFreeColors(m_display, colormap, &bg.pixel, 1, 0L);
1609
1610         return GHOST_kSuccess;
1611 }
1612
1613
1614 GHOST_TSuccess
1615 GHOST_WindowX11::
1616 beginFullScreen() const
1617 {
1618         {
1619                 Window root_return;
1620                 int x_return, y_return;
1621                 unsigned int w_return, h_return, border_w_return, depth_return;
1622
1623                 XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
1624                              &w_return, &h_return, &border_w_return, &depth_return);
1625
1626                 m_system->setCursorPosition(w_return / 2, h_return / 2);
1627         }
1628
1629
1630         /* Grab Keyboard & Mouse */
1631         int err;
1632
1633         err = XGrabKeyboard(m_display, m_window, False,
1634                             GrabModeAsync, GrabModeAsync, CurrentTime);
1635         if (err != GrabSuccess) printf("XGrabKeyboard failed %d\n", err);
1636
1637         err = XGrabPointer(m_display, m_window, False,  PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
1638                            GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
1639         if (err != GrabSuccess) printf("XGrabPointer failed %d\n", err);
1640
1641         return GHOST_kSuccess;
1642 }
1643
1644 GHOST_TSuccess
1645 GHOST_WindowX11::
1646 endFullScreen() const
1647 {
1648         XUngrabKeyboard(m_display, CurrentTime);
1649         XUngrabPointer(m_display, CurrentTime);
1650
1651         return GHOST_kSuccess;
1652 }