Holiday coding log :)
[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
33 #include "GHOST_WindowX11.h"
34 #include "GHOST_SystemX11.h"
35 #include "STR_String.h"
36 #include "GHOST_Debug.h"
37
38 #ifdef WITH_XDND
39 #include "GHOST_DropTargetX11.h"
40 #endif
41
42 /* For standard X11 cursors */
43 #include <X11/cursorfont.h>
44 #include <X11/Xatom.h>
45
46 #if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
47 #include <strings.h>
48 #endif
49
50 #include <cstring>
51 #include <cstdio>
52
53 #include <algorithm>
54 #include <string>
55
56 /* For obscure full screen mode stuuf
57  * lifted verbatim from blut. */
58
59 typedef struct {
60         long flags;
61         long functions;
62         long decorations;
63         long input_mode;
64 } MotifWmHints;
65
66 #define MWM_HINTS_DECORATIONS         (1L << 1)
67
68
69 // #define GHOST_X11_GRAB
70
71 /*
72  * A Client can't change the window property, that is
73  * the work of the window manager. In case, we send
74  * a ClientMessage to the RootWindow with the property
75  * and the Action (WM-spec define this):
76  */
77 #define _NET_WM_STATE_REMOVE 0
78 #define _NET_WM_STATE_ADD 1
79 // #define _NET_WM_STATE_TOGGLE 2 // UNUSED
80
81 /*
82    import bpy
83    I = bpy.data.images['blender.png'] # the 48x48 icon
84
85  # Write to a file that can be
86  # used within static unsigned char BLENDER_ICON_48x48x24[] = {...}
87    f = open('/myicon.txt', 'w')
88    for j in xrange(48):
89         for k in xrange(48):
90                 v = I.getPixelI(j,47-k)
91                 v.pop()
92                 for p in v:
93                         f.write(str(hex(p))+',')
94
95         f.write('\n')
96  */
97
98 /* See the python script above to regenerate the 48x48 icon within blender */
99 #define BLENDER_ICON_WIDTH 48
100 #define BLENDER_ICON_HEIGHT 48
101 static unsigned char BLENDER_ICON_48x48x24[] = {
102         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
103         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x4f, 0x2a, 0xd, 0xa7, 0x5b, 0x1f, 0xb8, 0x66, 0x22, 0x6c, 0x3b, 0x14, 0x5, 0x3, 0x1, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
104         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x6f, 0x3a, 0x13, 0xea, 0x7f, 0x2c, 0xee, 0x7e, 0x2b, 0xee, 0x7e, 0x2b, 0xef, 0x85, 0x2e, 0x5f, 0x35, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
105         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x43, 0x22, 0xb, 0xed, 0x7f, 0x2c, 0xed, 0x7c, 0x2b, 0xee, 0x7f, 0x2c, 0xee, 0x80, 0x2c, 0xee, 0x80, 0x2c, 0xa8, 0x5f, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
106         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x2e, 0x16, 0x6, 0xd0, 0x6f, 0x26, 0xed, 0x7b, 0x2a, 0xed, 0x7d, 0x2b, 0xee, 0x7f, 0x2c, 0xee, 0x80, 0x2c, 0xee, 0x82, 0x2d, 0x9a, 0x57, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
107         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x17, 0xb, 0x4, 0xb9, 0x60, 0x21, 0xed, 0x7a, 0x2a, 0xed, 0x7b, 0x2a, 0xed, 0x7e, 0x2b, 0xee, 0x7f, 0x2c, 0xee, 0x7f, 0x2c, 0xee, 0x86, 0x2e, 0x4e, 0x2b, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
108         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x1, 0x0, 0x0, 0x96, 0x4d, 0x19, 0xee, 0x7a, 0x2a, 0xed, 0x79, 0x2a, 0xed, 0x7c, 0x2b, 0xed, 0x7e, 0x2b, 0xed, 0x7e, 0x2b, 0xef, 0x83, 0x2d, 0x98, 0x55, 0x1c, 0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
109         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x20, 0xf, 0x5, 0x4b, 0x27, 0xe, 0x21, 0x11, 0x5, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x67, 0x34, 0x11, 0xed, 0x7b, 0x2a, 0xec, 0x79, 0x29, 0xed, 0x7b, 0x2a, 0xed, 0x7c, 0x2b, 0xed, 0x7d, 0x2b, 0xee, 0x7f, 0x2c, 0xbb, 0x69, 0x24, 0x11, 0x9, 0x3, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
110         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x38, 0x1c, 0x9, 0xc9, 0x6d, 0x2c, 0xf1, 0x86, 0x36, 0xd7, 0x79, 0x2a, 0x22, 0x12, 0x5, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x3b, 0x1d, 0x9, 0xe0, 0x74, 0x27, 0xed, 0x7a, 0x2a, 0xed, 0x7c, 0x2a, 0xed, 0x7d, 0x2b, 0xed, 0x7d, 0x2b, 0xed, 0x7d, 0x2b, 0xdc, 0x7a, 0x2a, 0x1e, 0xf, 0x5, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
111         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xa6, 0x56, 0x23, 0xee, 0x83, 0x3b, 0xed, 0x7d, 0x2c, 0xf0, 0x85, 0x2e, 0x75, 0x43, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x25, 0x12, 0x5, 0xc9, 0x68, 0x24, 0xed, 0x7b, 0x2a, 0xed, 0x7d, 0x2b, 0xed, 0x7e, 0x2b, 0xee, 0x7e, 0x2c, 0xed, 0x7d, 0x2b, 0xe3, 0x7d, 0x2b, 0x3b, 0x1f, 0xa, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
112         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x1c, 0xd, 0x4, 0xd9, 0x74, 0x35, 0xee, 0x83, 0x3a, 0xee, 0x7f, 0x2b, 0xf0, 0x86, 0x2e, 0x83, 0x4d, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xa, 0x5, 0x1, 0xa1, 0x54, 0x1c, 0xee, 0x7e, 0x2c, 0xed, 0x7e, 0x2c, 0xed, 0x7f, 0x2c, 0xed, 0x80, 0x2c, 0xed, 0x7f, 0x2b, 0xec, 0x81, 0x2d, 0x60, 0x33, 0x11, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
113         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x24, 0x11, 0x5, 0xe0, 0x7a, 0x38, 0xee, 0x84, 0x3a, 0xee, 0x82, 0x2c, 0xf0, 0x88, 0x2f, 0x82, 0x4d, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x6f, 0x39, 0x13, 0xef, 0x82, 0x30, 0xed, 0x82, 0x2f, 0xee, 0x82, 0x2e, 0xee, 0x82, 0x2d, 0xee, 0x81, 0x2c, 0xf0, 0x83, 0x2d, 0x88, 0x49, 0x18, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
114         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x24, 0x11, 0x5, 0xe0, 0x7c, 0x3a, 0xee, 0x86, 0x3b, 0xee, 0x84, 0x2d, 0xf1, 0x8b, 0x30, 0x82, 0x4d, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x54, 0x2b, 0xf, 0xe9, 0x80, 0x30, 0xee, 0x87, 0x33, 0xef, 0x88, 0x32, 0xef, 0x88, 0x30, 0xee, 0x85, 0x2f, 0xef, 0x83, 0x2e, 0xae, 0x5f, 0x20, 0x4, 0x2, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
115         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x24, 0x11, 0x5, 0xe0, 0x7e, 0x3d, 0xef, 0x8a, 0x3d, 0xef, 0x88, 0x2e, 0xf1, 0x8d, 0x31, 0x81, 0x4d, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x29, 0x15, 0x7, 0xd2, 0x74, 0x2d, 0xf0, 0x8b, 0x36, 0xf0, 0x8d, 0x35, 0xef, 0x8d, 0x35, 0xef, 0x8b, 0x33, 0xef, 0x88, 0x30, 0xc4, 0x6d, 0x26, 0x18, 0xc, 0x4, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
116         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x24, 0x11, 0x5, 0xe1, 0x80, 0x3f, 0xf0, 0x8d, 0x3f, 0xef, 0x8a, 0x2f, 0xf1, 0x8f, 0x32, 0x81, 0x4e, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x3, 0x0, 0xb1, 0x61, 0x26, 0xf1, 0x8e, 0x3a, 0xf1, 0x90, 0x3a, 0xf0, 0x90, 0x38, 0xf0, 0x90, 0x36, 0xef, 0x8e, 0x35, 0xd3, 0x7a, 0x2c, 0x22, 0x11, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
117         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x24, 0x12, 0x5, 0xe1, 0x83, 0x42, 0xf0, 0x90, 0x42, 0xf0, 0x8d, 0x30, 0xf2, 0x92, 0x33, 0x80, 0x4e, 0x1b, 0x0, 0x0, 0x0, 0x3, 0x2, 0x0, 0x81, 0x45, 0x1b, 0xf1, 0x90, 0x3e, 0xf1, 0x94, 0x3d, 0xf1, 0x95, 0x3c, 0xf0, 0x94, 0x3b, 0xf0, 0x92, 0x39, 0xf0, 0x90, 0x35, 0xd0, 0x7b, 0x2b, 0xc2, 0x6e, 0x26, 0xbe, 0x6c, 0x25, 0x94, 0x54, 0x1c, 0x5b, 0x33, 0x11, 0x1a, 0xe, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
118         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x25, 0x14, 0x6, 0xe2, 0x86, 0x44, 0xf1, 0x94, 0x45, 0xf0, 0x90, 0x31, 0xf2, 0x94, 0x33, 0x80, 0x4e, 0x1b, 0x0, 0x0, 0x0, 0x60, 0x34, 0x14, 0xed, 0x8c, 0x3e, 0xf0, 0x96, 0x42, 0xf1, 0x97, 0x40, 0xf1, 0x95, 0x3f, 0xf0, 0x91, 0x39, 0xef, 0x8e, 0x33, 0xef, 0x8d, 0x31, 0xf0, 0x8d, 0x31, 0xef, 0x8c, 0x30, 0xef, 0x8c, 0x30, 0xf0, 0x8d, 0x31, 0xf1, 0x8e, 0x31, 0xe1, 0x85, 0x2e, 0x92, 0x55, 0x1d, 0x25, 0x14, 0x7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
119         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x26, 0x14, 0x6, 0xe2, 0x89, 0x46, 0xf2, 0x97, 0x47, 0xf1, 0x92, 0x32, 0xf2, 0x96, 0x34, 0x80, 0x4e, 0x1a, 0x32, 0x1a, 0xa, 0xe3, 0x87, 0x3d, 0xf1, 0x97, 0x45, 0xf1, 0x98, 0x44, 0xf1, 0x95, 0x41, 0xf0, 0x90, 0x39, 0xef, 0x8d, 0x30, 0xef, 0x8f, 0x31, 0xf0, 0x90, 0x32, 0xf0, 0x92, 0x33, 0xf1, 0x93, 0x33, 0xf1, 0x94, 0x34, 0xf1, 0x94, 0x34, 0xf0, 0x93, 0x34, 0xf0, 0x91, 0x32, 0xf1, 0x91, 0x33, 0xe2, 0x8a, 0x30, 0x6b, 0x3f, 0x15, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
120         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x26, 0x14, 0x6, 0xe3, 0x8b, 0x49, 0xf2, 0x9a, 0x49, 0xf1, 0x93, 0x32, 0xf2, 0x98, 0x35, 0x8f, 0x57, 0x1d, 0xcf, 0x7c, 0x38, 0xf2, 0x99, 0x48, 0xf1, 0x98, 0x47, 0xf1, 0x96, 0x44, 0xf0, 0x90, 0x39, 0xef, 0x8d, 0x31, 0xf0, 0x90, 0x31, 0xf0, 0x92, 0x33, 0xf1, 0x94, 0x33, 0xf1, 0x96, 0x35, 0xf1, 0x98, 0x35, 0xf1, 0x9a, 0x36, 0xf1, 0x9c, 0x37, 0xf2, 0x9d, 0x37, 0xf2, 0x9c, 0x37, 0xf2, 0x99, 0x36, 0xf0, 0x94, 0x34, 0xf3, 0x97, 0x35, 0x9f, 0x60, 0x21, 0x13, 0xb, 0x3, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
121         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x26, 0x14, 0x6, 0xe3, 0x8d, 0x4b, 0xf2, 0x9b, 0x4c, 0xf1, 0x93, 0x32, 0xf1, 0x97, 0x35, 0xea, 0x98, 0x43, 0xf2, 0x9d, 0x4d, 0xf1, 0x9a, 0x4b, 0xf1, 0x99, 0x49, 0xf0, 0x93, 0x3d, 0xf0, 0x8d, 0x30, 0xf0, 0x90, 0x32, 0xf0, 0x92, 0x32, 0xf0, 0x94, 0x34, 0xf1, 0x96, 0x34, 0xf1, 0x98, 0x36, 0xf1, 0x9a, 0x36, 0xf2, 0x9c, 0x38, 0xf2, 0x9f, 0x38, 0xf2, 0xa2, 0x39, 0xf3, 0xa2, 0x39, 0xf3, 0xa2, 0x39, 0xf2, 0x9f, 0x38, 0xf1, 0x99, 0x35, 0xf2, 0x97, 0x35, 0xba, 0x74, 0x29, 0x13, 0xb, 0x4, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
122         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x26, 0x14, 0x6, 0xe4, 0x8e, 0x4d, 0xf2, 0x9d, 0x4e, 0xf1, 0x93, 0x32, 0xf2, 0x9d, 0x3f, 0xf3, 0xa4, 0x54, 0xf2, 0x9d, 0x50, 0xf1, 0x9b, 0x4d, 0xf2, 0x98, 0x46, 0xef, 0x8d, 0x31, 0xf0, 0x8f, 0x31, 0xf0, 0x91, 0x32, 0xf0, 0x93, 0x32, 0xf1, 0x94, 0x32, 0xf1, 0x95, 0x32, 0xf1, 0x98, 0x34, 0xf1, 0x9b, 0x36, 0xf2, 0x9e, 0x38, 0xf2, 0xa1, 0x39, 0xf2, 0xa4, 0x3a, 0xf3, 0xa6, 0x3b, 0xf4, 0xa8, 0x3c, 0xf3, 0xa7, 0x3c, 0xf3, 0xa4, 0x3a, 0xf2, 0x9c, 0x37, 0xf2, 0x99, 0x36, 0xa9, 0x69, 0x25, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
123         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x26, 0x14, 0x6, 0xe4, 0x90, 0x50, 0xf2, 0x9e, 0x51, 0xf1, 0x95, 0x35, 0xf4, 0xa6, 0x54, 0xf3, 0xa2, 0x55, 0xf2, 0x9e, 0x51, 0xf2, 0x9c, 0x4e, 0xf0, 0x8f, 0x35, 0xf0, 0x8e, 0x31, 0xf0, 0x90, 0x32, 0xf3, 0xa5, 0x56, 0xf7, 0xc4, 0x8e, 0xfa, 0xd8, 0xb6, 0xfb, 0xdf, 0xc2, 0xfa, 0xd8, 0xb2, 0xf7, 0xc4, 0x89, 0xf4, 0xae, 0x59, 0xf2, 0xa1, 0x38, 0xf3, 0xa5, 0x3b, 0xf4, 0xa8, 0x3c, 0xf4, 0xab, 0x3d, 0xf4, 0xac, 0x3e, 0xf4, 0xab, 0x3d, 0xf3, 0xa7, 0x3b, 0xf2, 0x9e, 0x38, 0xf4, 0x9e, 0x38, 0x6f, 0x45, 0x17, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
124         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x19, 0xc, 0x5, 0x63, 0x36, 0x18, 0x3f, 0x20, 0x9, 0x2, 0x1, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x26, 0x14, 0x6, 0xe4, 0x91, 0x52, 0xf3, 0xa2, 0x55, 0xf2, 0x9d, 0x43, 0xf4, 0xa7, 0x5b, 0xf3, 0xa2, 0x57, 0xf3, 0xa0, 0x55, 0xf1, 0x97, 0x43, 0xf0, 0x8d, 0x30, 0xf2, 0x9d, 0x4c, 0xfa, 0xda, 0xbc, 0xfe, 0xfb, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfb, 0xf6, 0xfa, 0xdc, 0xb5, 0xf4, 0xae, 0x4e, 0xf4, 0xa9, 0x3c, 0xf4, 0xac, 0x3d, 0xf4, 0xae, 0x3f, 0xf4, 0xaf, 0x3f, 0xf4, 0xad, 0x3f, 0xf3, 0xa8, 0x3d, 0xf2, 0x9d, 0x38, 0xe2, 0x94, 0x34, 0x23, 0x14, 0x6, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
125         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x11, 0x8, 0x3, 0x9e, 0x62, 0x39, 0xf2, 0x91, 0x4e, 0xe7, 0x79, 0x29, 0x48, 0x25, 0xc, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x27, 0x13, 0x6, 0xe5, 0x93, 0x54, 0xf3, 0xa7, 0x59, 0xf4, 0xa6, 0x56, 0xf4, 0xa7, 0x5d, 0xf3, 0xa4, 0x59, 0xf3, 0xa2, 0x57, 0xf1, 0x90, 0x36, 0xf4, 0xa7, 0x5d, 0xfe, 0xf4, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf2, 0xe3, 0xf6, 0xb8, 0x5f, 0xf4, 0xac, 0x3e, 0xf4, 0xaf, 0x3f, 0xf4, 0xb1, 0x40, 0xf4, 0xb2, 0x40, 0xf5, 0xaf, 0x3f, 0xf3, 0xa6, 0x3c, 0xf3, 0x9f, 0x38, 0x90, 0x5d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
126         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x3d, 0x1f, 0xf, 0xed, 0x9c, 0x6a, 0xef, 0x8b, 0x4a, 0xec, 0x78, 0x29, 0xe4, 0x79, 0x2a, 0x29, 0x15, 0x7, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x28, 0x14, 0x6, 0xe6, 0x97, 0x57, 0xf5, 0xad, 0x63, 0xf5, 0xac, 0x62, 0xf4, 0xa8, 0x5f, 0xf4, 0xa6, 0x5c, 0xf3, 0xa0, 0x53, 0xf4, 0xa9, 0x64, 0xfe, 0xf8, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xf2, 0xf7, 0xfa, 0xed, 0xf4, 0xf8, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf7, 0xed, 0xf5, 0xb5, 0x53, 0xf5, 0xb0, 0x3f, 0xf5, 0xb3, 0x41, 0xf5, 0xb4, 0x42, 0xf5, 0xb3, 0x41, 0xf4, 0xad, 0x3f, 0xf3, 0xa1, 0x39, 0xe4, 0x98, 0x37, 0x1d, 0x11, 0x5, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
127         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x43, 0x23, 0x10, 0xf2, 0xa1, 0x70, 0xf1, 0x99, 0x61, 0xec, 0x78, 0x2a, 0xed, 0x7b, 0x2a, 0xc4, 0x69, 0x23, 0x15, 0xa, 0x3, 0x0, 0x0, 0x0, 0x1d, 0xf, 0x5, 0xe7, 0x9b, 0x5b, 0xf5, 0xb1, 0x68, 0xf5, 0xad, 0x65, 0xf4, 0xaa, 0x62, 0xf4, 0xa8, 0x5f, 0xf3, 0xa4, 0x59, 0xfd, 0xec, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfd, 0xfe, 0xc3, 0xda, 0xe9, 0x5c, 0x9a, 0xc5, 0x2a, 0x7b, 0xb4, 0x17, 0x6f, 0xae, 0x36, 0x81, 0xb8, 0x91, 0xbb, 0xd9, 0xf0, 0xf6, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe7, 0xc7, 0xf5, 0xb2, 0x43, 0xf6, 0xb3, 0x41, 0xf5, 0xb5, 0x43, 0xf5, 0xb6, 0x43, 0xf5, 0xb3, 0x42, 0xf4, 0xa8, 0x3c, 0xf4, 0xa2, 0x3a, 0x66, 0x41, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
128         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x22, 0x10, 0x7, 0xd6, 0x88, 0x5b, 0xf2, 0xa5, 0x76, 0xee, 0x84, 0x3f, 0xed, 0x7a, 0x2a, 0xee, 0x80, 0x2c, 0xa5, 0x59, 0x1e, 0x7, 0x3, 0x1, 0x19, 0xd, 0x4, 0xe7, 0x9e, 0x5e, 0xf6, 0xb2, 0x6b, 0xf5, 0xae, 0x67, 0xf5, 0xac, 0x65, 0xf4, 0xa9, 0x61, 0xf8, 0xcc, 0xa1, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xfe, 0x97, 0xbf, 0xdb, 0x33, 0x83, 0xbb, 0x24, 0x7e, 0xb9, 0x3, 0x6a, 0xae, 0x0, 0x66, 0xab, 0x0, 0x64, 0xa9, 0x1, 0x63, 0xa9, 0x3c, 0x87, 0xbd, 0xee, 0xf5, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xf8, 0xc7, 0x76, 0xf6, 0xb4, 0x41, 0xf5, 0xb7, 0x43, 0xf6, 0xb8, 0x44, 0xf6, 0xb6, 0x43, 0xf5, 0xae, 0x3f, 0xf3, 0xa2, 0x3a, 0xac, 0x71, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
129         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x52, 0x2c, 0x16, 0xf0, 0xa1, 0x71, 0xf2, 0xa2, 0x6f, 0xed, 0x7e, 0x32, 0xed, 0x7e, 0x2b, 0xef, 0x82, 0x2d, 0x8a, 0x49, 0x18, 0x1b, 0xe, 0x4, 0xe7, 0xa2, 0x61, 0xf6, 0xb3, 0x6e, 0xf6, 0xb0, 0x6a, 0xf5, 0xae, 0x67, 0xf5, 0xab, 0x64, 0xfe, 0xf4, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb4, 0xd1, 0xe5, 0x3e, 0x8d, 0xc3, 0x37, 0x8e, 0xc5, 0x16, 0x7a, 0xb9, 0x0, 0x6b, 0xaf, 0x0, 0x68, 0xac, 0x0, 0x65, 0xaa, 0x0, 0x65, 0xab, 0x0, 0x66, 0xac, 0x4d, 0x93, 0xc4, 0xf8, 0xfb, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe7, 0xc5, 0xf6, 0xb3, 0x40, 0xf6, 0xb7, 0x43, 0xf6, 0xb9, 0x44, 0xf6, 0xb8, 0x45, 0xf5, 0xb2, 0x41, 0xf3, 0xa5, 0x3b, 0xe2, 0x98, 0x37, 0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
130         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x86, 0x4e, 0x2e, 0xf3, 0xa6, 0x77, 0xf1, 0x9e, 0x66, 0xed, 0x7e, 0x2d, 0xee, 0x82, 0x2c, 0xf0, 0x85, 0x2d, 0x7e, 0x47, 0x17, 0xe8, 0xa6, 0x64, 0xf6, 0xb5, 0x70, 0xf6, 0xb2, 0x6d, 0xf5, 0xb0, 0x6a, 0xf7, 0xbb, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfb, 0xfd, 0x5b, 0x9c, 0xca, 0x42, 0x96, 0xcb, 0x3c, 0x93, 0xc9, 0x9, 0x73, 0xb6, 0x0, 0x6b, 0xb0, 0x0, 0x69, 0xad, 0x0, 0x66, 0xab, 0x0, 0x66, 0xab, 0x0, 0x67, 0xad, 0x4, 0x6a, 0xaf, 0xbb, 0xd7, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf8, 0xee, 0xf6, 0xb9, 0x4f, 0xf6, 0xb7, 0x44, 0xf6, 0xba, 0x45, 0xf6, 0xba, 0x45, 0xf5, 0xb5, 0x43, 0xf4, 0xa8, 0x3d, 0xf5, 0xa7, 0x3d, 0x1b, 0xf, 0x4, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
131         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x11, 0x8, 0x3, 0xb0, 0x6d, 0x45, 0xf4, 0xaa, 0x7b, 0xf1, 0x9a, 0x5b, 0xee, 0x82, 0x2d, 0xef, 0x86, 0x2e, 0xee, 0x91, 0x36, 0xf5, 0xb5, 0x70, 0xf6, 0xb7, 0x73, 0xf6, 0xb4, 0x70, 0xf5, 0xb1, 0x6c, 0xf9, 0xcc, 0xa1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, 0xe2, 0xef, 0x4b, 0x97, 0xca, 0x47, 0x9a, 0xce, 0x3f, 0x95, 0xcb, 0x3, 0x71, 0xb5, 0x0, 0x6c, 0xb0, 0x0, 0x69, 0xae, 0x0, 0x67, 0xac, 0x0, 0x66, 0xac, 0x0, 0x67, 0xad, 0x0, 0x69, 0xaf, 0x66, 0xa5, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfa, 0xf8, 0xc3, 0x67, 0xf6, 0xb8, 0x44, 0xf6, 0xba, 0x45, 0xf6, 0xbb, 0x46, 0xf6, 0xb7, 0x44, 0xf4, 0xab, 0x3e, 0xf8, 0xab, 0x3f, 0x2a, 0x19, 0x8, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
132         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x2b, 0x15, 0x9, 0xd4, 0x8a, 0x5c, 0xf4, 0xac, 0x7c, 0xf1, 0x98, 0x54, 0xee, 0x85, 0x2e, 0xf1, 0x93, 0x38, 0xf6, 0xba, 0x75, 0xf6, 0xb9, 0x75, 0xf6, 0xb6, 0x72, 0xf6, 0xb3, 0x6f, 0xfa, 0xd5, 0xb1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xcf, 0xe5, 0x51, 0x9e, 0xcf, 0x4b, 0x9d, 0xd0, 0x43, 0x97, 0xcc, 0x3, 0x71, 0xb5, 0x0, 0x6d, 0xb1, 0x0, 0x6a, 0xae, 0x0, 0x67, 0xac, 0x0, 0x67, 0xad, 0x0, 0x68, 0xae, 0x0, 0x6a, 0xb0, 0x3b, 0x8c, 0xc2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf9, 0xc9, 0x77, 0xf6, 0xb8, 0x44, 0xf6, 0xba, 0x45, 0xf6, 0xbc, 0x46, 0xf6, 0xb8, 0x44, 0xf4, 0xad, 0x3f, 0xf8, 0xac, 0x3f, 0x2a, 0x1a, 0x8, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
133         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x47, 0x26, 0x12, 0xee, 0xa3, 0x72, 0xf4, 0xae, 0x7b, 0xf1, 0x97, 0x4e, 0xf1, 0x92, 0x38, 0xf6, 0xbb, 0x78, 0xf6, 0xbb, 0x78, 0xf6, 0xb7, 0x75, 0xf6, 0xb5, 0x71, 0xfa, 0xd6, 0xb2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xcd, 0xe4, 0x54, 0xa0, 0xd1, 0x4e, 0xa0, 0xd1, 0x48, 0x9b, 0xce, 0xb, 0x76, 0xb8, 0x0, 0x6d, 0xb2, 0x0, 0x6a, 0xaf, 0x0, 0x68, 0xad, 0x0, 0x68, 0xad, 0x0, 0x69, 0xae, 0x0, 0x6b, 0xb1, 0x36, 0x89, 0xc1, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xf9, 0xc9, 0x76, 0xf6, 0xb9, 0x44, 0xf6, 0xbb, 0x46, 0xf6, 0xbc, 0x47, 0xf6, 0xb9, 0x44, 0xf4, 0xad, 0x3f, 0xf8, 0xad, 0x40, 0x2a, 0x1a, 0x8, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
134         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x70, 0x42, 0x26, 0xf4, 0xad, 0x7b, 0xf5, 0xb1, 0x7d, 0xf3, 0x9f, 0x50, 0xf7, 0xbc, 0x7b, 0xf7, 0xbc, 0x7b, 0xf6, 0xb9, 0x78, 0xf6, 0xb7, 0x74, 0xf9, 0xd0, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xda, 0xeb, 0x56, 0xa0, 0xd0, 0x51, 0xa1, 0xd2, 0x4a, 0x9c, 0xcf, 0x20, 0x82, 0xbf, 0x0, 0x6e, 0xb2, 0x0, 0x6b, 0xb0, 0x0, 0x68, 0xae, 0x0, 0x68, 0xae, 0x0, 0x69, 0xaf, 0x0, 0x6b, 0xb1, 0x50, 0x98, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf9, 0xf8, 0xc3, 0x66, 0xf6, 0xb9, 0x45, 0xf7, 0xbb, 0x46, 0xf6, 0xbc, 0x47, 0xf6, 0xb8, 0x45, 0xf4, 0xad, 0x3f, 0xf8, 0xac, 0x3f, 0x2a, 0x19, 0x7, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
135         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xc, 0x5, 0x0, 0xa5, 0x67, 0x40, 0xf5, 0xb1, 0x7f, 0xf5, 0xb7, 0x7e, 0xf7, 0xbf, 0x80, 0xf7, 0xbe, 0x7d, 0xf7, 0xbb, 0x7b, 0xf6, 0xb9, 0x78, 0xf8, 0xc2, 0x8b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xee, 0xf5, 0xf9, 0x5b, 0xa0, 0xce, 0x53, 0xa2, 0xd2, 0x4c, 0x9e, 0xd0, 0x3c, 0x93, 0xc8, 0x6, 0x71, 0xb4, 0x0, 0x6c, 0xb0, 0x0, 0x69, 0xae, 0x0, 0x69, 0xae, 0x0, 0x6a, 0xaf, 0x0, 0x6b, 0xb1, 0x9b, 0xc5, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf7, 0xec, 0xf6, 0xba, 0x4e, 0xf6, 0xb9, 0x45, 0xf7, 0xbb, 0x46, 0xf6, 0xbc, 0x47, 0xf5, 0xb7, 0x44, 0xf4, 0xab, 0x3e, 0xf5, 0xa8, 0x3e, 0x18, 0xd, 0x4, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
136         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x1f, 0x10, 0x7, 0xc9, 0x84, 0x56, 0xf5, 0xb5, 0x81, 0xf7, 0xbf, 0x82, 0xf8, 0xc0, 0x80, 0xf7, 0xbd, 0x7d, 0xf7, 0xba, 0x7a, 0xf6, 0xb8, 0x77, 0xfe, 0xf5, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xc2, 0xdf, 0x55, 0x9f, 0xd0, 0x4e, 0x9f, 0xd0, 0x47, 0x99, 0xcc, 0x2a, 0x87, 0xc1, 0x3, 0x6d, 0xb1, 0x0, 0x69, 0xaf, 0x0, 0x6a, 0xaf, 0x0, 0x6a, 0xb0, 0x27, 0x80, 0xbc, 0xec, 0xf4, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe5, 0xbf, 0xf6, 0xb6, 0x42, 0xf6, 0xba, 0x46, 0xf7, 0xbb, 0x46, 0xf7, 0xbb, 0x47, 0xf5, 0xb5, 0x43, 0xf3, 0xa8, 0x3d, 0xdd, 0x97, 0x37, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
137         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x32, 0x1a, 0xb, 0xe4, 0x9d, 0x6a, 0xf7, 0xbd, 0x84, 0xf8, 0xc1, 0x83, 0xf8, 0xbe, 0x80, 0xf7, 0xbd, 0x7d, 0xf7, 0xba, 0x79, 0xfa, 0xd9, 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf6, 0xfa, 0x74, 0xac, 0xd4, 0x4f, 0x9b, 0xcd, 0x48, 0x99, 0xcc, 0x41, 0x94, 0xc8, 0x2c, 0x85, 0xbe, 0xb, 0x70, 0xb3, 0x1, 0x6a, 0xb0, 0xb, 0x6e, 0xb2, 0xbf, 0xd9, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xf8, 0xc8, 0x74, 0xf6, 0xb7, 0x44, 0xf6, 0xba, 0x46, 0xf7, 0xbb, 0x46, 0xf7, 0xb9, 0x46, 0xf6, 0xb2, 0x42, 0xf4, 0xa7, 0x3d, 0xa6, 0x70, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
138         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x4f, 0x2e, 0x18, 0xef, 0xaf, 0x78, 0xf8, 0xc1, 0x85, 0xf8, 0xc0, 0x82, 0xf7, 0xbe, 0x7f, 0xf7, 0xbc, 0x7d, 0xf7, 0xbe, 0x81, 0xfe, 0xf3, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf7, 0xfa, 0x91, 0xbd, 0xdb, 0x4f, 0x97, 0xc8, 0x40, 0x8e, 0xc3, 0x37, 0x8a, 0xc0, 0x34, 0x88, 0xbf, 0x57, 0x9c, 0xca, 0xcc, 0xe1, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe4, 0xbf, 0xf5, 0xb6, 0x45, 0xf6, 0xb8, 0x45, 0xf6, 0xba, 0x46, 0xf7, 0xba, 0x46, 0xf6, 0xb7, 0x45, 0xf5, 0xad, 0x3f, 0xf4, 0xa9, 0x40, 0x5c, 0x3d, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
139         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x85, 0x55, 0x31, 0xf7, 0xbd, 0x84, 0xf8, 0xc2, 0x85, 0xf8, 0xc0, 0x82, 0xf7, 0xbe, 0x80, 0xf7, 0xbc, 0x7d, 0xf9, 0xcb, 0x99, 0xfe, 0xf9, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xfe, 0xe5, 0xef, 0xf6, 0xc1, 0xda, 0xeb, 0xba, 0xd5, 0xe9, 0xd8, 0xe8, 0xf2, 0xf9, 0xfb, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf3, 0xe4, 0xf6, 0xb9, 0x51, 0xf5, 0xb5, 0x43, 0xf6, 0xb8, 0x45, 0xf6, 0xb9, 0x46, 0xf6, 0xb8, 0x46, 0xf6, 0xb3, 0x43, 0xf4, 0xa7, 0x3e, 0xdf, 0x9d, 0x43, 0x17, 0xd, 0x4, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
140         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x14, 0xa, 0x4, 0xb2, 0x7b, 0x4b, 0xf8, 0xc2, 0x88, 0xf8, 0xc1, 0x85, 0xf7, 0xbf, 0x82, 0xf7, 0xbe, 0x80, 0xf7, 0xbd, 0x7d, 0xf9, 0xca, 0x97, 0xfe, 0xf9, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf2, 0xe1, 0xf7, 0xbc, 0x5d, 0xf5, 0xb3, 0x42, 0xf5, 0xb6, 0x44, 0xf5, 0xb7, 0x45, 0xf6, 0xb8, 0x45, 0xf6, 0xb5, 0x44, 0xf5, 0xad, 0x40, 0xf6, 0xae, 0x4c, 0x88, 0x5d, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
141         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x1d, 0x10, 0x6, 0xdb, 0xa0, 0x68, 0xf8, 0xc3, 0x88, 0xf7, 0xc1, 0x85, 0xf7, 0xc0, 0x82, 0xf7, 0xbf, 0x80, 0xf7, 0xbe, 0x7e, 0xf8, 0xc4, 0x88, 0xfc, 0xe6, 0xcc, 0xfe, 0xfb, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfa, 0xf3, 0xfa, 0xda, 0xa9, 0xf5, 0xb3, 0x4a, 0xf5, 0xb2, 0x42, 0xf5, 0xb3, 0x43, 0xf5, 0xb6, 0x44, 0xf5, 0xb7, 0x45, 0xf5, 0xb5, 0x44, 0xf5, 0xb0, 0x42, 0xf5, 0xad, 0x4d, 0xdd, 0x9e, 0x4a, 0x19, 0xf, 0x5, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
142         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x50, 0x33, 0x19, 0xec, 0xb4, 0x7a, 0xf8, 0xc2, 0x87, 0xf7, 0xc1, 0x85, 0xf7, 0xc1, 0x83, 0xf7, 0xc0, 0x80, 0xf7, 0xc0, 0x7f, 0xf7, 0xc0, 0x7c, 0xf7, 0xc2, 0x7e, 0xf8, 0xcc, 0x92, 0xfa, 0xda, 0xb0, 0xfb, 0xdf, 0xb9, 0xfa, 0xd9, 0xad, 0xf7, 0xc8, 0x84, 0xf5, 0xb4, 0x54, 0xf4, 0xad, 0x3f, 0xf4, 0xaf, 0x41, 0xf5, 0xb2, 0x42, 0xf5, 0xb4, 0x43, 0xf5, 0xb5, 0x44, 0xf5, 0xb4, 0x44, 0xf5, 0xb2, 0x46, 0xf5, 0xb2, 0x54, 0xf5, 0xb4, 0x5a, 0x5e, 0x3e, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
143         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x71, 0x4b, 0x29, 0xf8, 0xc0, 0x86, 0xf7, 0xc3, 0x87, 0xf7, 0xc2, 0x85, 0xf7, 0xc1, 0x83, 0xf7, 0xc2, 0x82, 0xf7, 0xc2, 0x7f, 0xf7, 0xc2, 0x7e, 0xf6, 0xc0, 0x76, 0xf4, 0xb4, 0x59, 0xf3, 0xa8, 0x3e, 0xf3, 0xa7, 0x39, 0xf3, 0xa9, 0x3d, 0xf4, 0xab, 0x3e, 0xf4, 0xad, 0x40, 0xf4, 0xb0, 0x41, 0xf4, 0xb2, 0x42, 0xf5, 0xb2, 0x42, 0xf5, 0xb3, 0x45, 0xf6, 0xb7, 0x54, 0xf6, 0xb7, 0x60, 0xf6, 0xb5, 0x5f, 0x9d, 0x6b, 0x31, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
144         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x8b, 0x5f, 0x36, 0xf9, 0xc1, 0x87, 0xf7, 0xc3, 0x88, 0xf8, 0xc3, 0x86, 0xf7, 0xc3, 0x84, 0xf8, 0xc3, 0x81, 0xf7, 0xc4, 0x80, 0xf7, 0xc4, 0x7e, 0xf7, 0xc4, 0x7d, 0xf7, 0xc3, 0x7a, 0xf6, 0xbd, 0x6c, 0xf5, 0xb7, 0x5c, 0xf5, 0xb5, 0x54, 0xf5, 0xb4, 0x50, 0xf5, 0xb6, 0x52, 0xf6, 0xb9, 0x58, 0xf6, 0xbd, 0x62, 0xf7, 0xbf, 0x6a, 0xf6, 0xba, 0x66, 0xf6, 0xb6, 0x63, 0xab, 0x78, 0x39, 0xa, 0x6, 0x2, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
145         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x83, 0x58, 0x32, 0xf0, 0xb9, 0x7f, 0xf7, 0xc3, 0x88, 0xf7, 0xc3, 0x86, 0xf8, 0xc4, 0x84, 0xf7, 0xc5, 0x82, 0xf7, 0xc5, 0x80, 0xf7, 0xc5, 0x7f, 0xf8, 0xc5, 0x7d, 0xf7, 0xc4, 0x7b, 0xf7, 0xc4, 0x79, 0xf7, 0xc4, 0x78, 0xf7, 0xc3, 0x76, 0xf7, 0xc3, 0x74, 0xf7, 0xc2, 0x71, 0xf6, 0xbe, 0x6d, 0xf6, 0xba, 0x6a, 0xf4, 0xb6, 0x65, 0x8a, 0x5e, 0x2c, 0xc, 0x7, 0x3, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
146         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x4f, 0x33, 0x1a, 0xd2, 0x99, 0x60, 0xf8, 0xc4, 0x89, 0xf8, 0xc3, 0x86, 0xf8, 0xc4, 0x84, 0xf7, 0xc5, 0x82, 0xf7, 0xc5, 0x80, 0xf7, 0xc5, 0x7f, 0xf7, 0xc4, 0x7e, 0xf7, 0xc4, 0x7b, 0xf7, 0xc3, 0x79, 0xf7, 0xc2, 0x77, 0xf6, 0xc0, 0x74, 0xf6, 0xbd, 0x71, 0xf6, 0xbb, 0x6e, 0xe1, 0xa4, 0x59, 0x5c, 0x3d, 0x1b, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
147         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xe, 0x6, 0x0, 0x72, 0x4b, 0x28, 0xd0, 0x9a, 0x62, 0xf7, 0xbf, 0x80, 0xf8, 0xc4, 0x85, 0xf7, 0xc3, 0x82, 0xf7, 0xc3, 0x80, 0xf7, 0xc3, 0x7e, 0xf7, 0xc1, 0x7c, 0xf6, 0xc0, 0x7a, 0xf7, 0xbf, 0x78, 0xf8, 0xbc, 0x72, 0xde, 0xa2, 0x5d, 0x80, 0x57, 0x2b, 0x13, 0xb, 0x4, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
148         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x19, 0xe, 0x5, 0x44, 0x2c, 0x15, 0x81, 0x59, 0x32, 0xb2, 0x80, 0x4c, 0xcb, 0x95, 0x5b, 0xd2, 0x9c, 0x5f, 0xcd, 0x97, 0x5a, 0xb9, 0x86, 0x4d, 0x8b, 0x61, 0x34, 0x4a, 0x30, 0x17, 0x15, 0xc, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
149         0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff,
150 };
151
152
153 GLXContext GHOST_WindowX11::s_firstContext = NULL;
154
155 GHOST_WindowX11::
156 GHOST_WindowX11(
157     GHOST_SystemX11 *system,
158     Display *display,
159     const STR_String& title,
160     GHOST_TInt32 left,
161     GHOST_TInt32 top,
162     GHOST_TUns32 width,
163     GHOST_TUns32 height,
164     GHOST_TWindowState state,
165     const GHOST_TEmbedderWindowID parentWindow,
166     GHOST_TDrawingContextType type,
167     const bool stereoVisual,
168     const GHOST_TUns16 numOfAASamples
169     ) :
170         GHOST_Window(width, height, state, type, stereoVisual, numOfAASamples),
171         m_context(NULL),
172         m_display(display),
173         m_normal_state(GHOST_kWindowStateNormal),
174         m_system(system),
175         m_valid_setup(false),
176         m_invalid_window(false),
177         m_empty_cursor(None),
178         m_custom_cursor(None)
179 {
180         
181         /* Set up the minimum atrributes that we require and see if
182          * X can find us a visual matching those requirements. */
183
184         int attributes[40], i, samples;
185         Atom atoms[2];
186         int natom;
187         int glxVersionMajor, glxVersionMinor; /* As in GLX major.minor */
188
189 #ifdef WITH_X11_XINPUT
190         /* initialize incase X11 fails to load */
191         memset(&m_xtablet, 0, sizeof(m_xtablet));
192 #endif
193
194         m_visual = NULL;
195
196         if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
197                 printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
198                 
199                 /* exit if this is the first window */
200                 if (s_firstContext == NULL) {
201                         printf("initial window could not find the GLX extension, exit!\n");
202                         exit(1);
203                 }
204
205                 return;
206         }
207
208         /* Find the display with highest samples, starting at level requested */
209         for (samples = m_numOfAASamples; samples >= 0; samples--) {
210                 i = 0; /* Reusing attributes array, so reset counter */
211
212                 if (m_stereoVisual)
213                         attributes[i++] = GLX_STEREO;
214
215                 attributes[i++] = GLX_RGBA;
216                 attributes[i++] = GLX_DOUBLEBUFFER;
217                 attributes[i++] = GLX_RED_SIZE;   attributes[i++] = 1;
218                 attributes[i++] = GLX_BLUE_SIZE;  attributes[i++] = 1;
219                 attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
220                 attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
221                 /* GLX >= 1.4 required for multi-sample */
222                 if (samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
223                         attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
224                         attributes[i++] = GLX_SAMPLES; attributes[i++] = samples;
225                 }
226                 attributes[i] = None;
227
228                 m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
229
230                 /* Any sample level or even zero, which means oversampling disabled, is good
231                  * but we need a valid visual to continue */
232                 if (m_visual == NULL) {
233                         if (samples == 0) {
234                                 /* All options exhausted, cannot continue */
235                                 printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
236                                 
237                                 if (s_firstContext == NULL) {
238                                         printf("initial window could not find the GLX extension, exit!\n");
239                                         exit(1);
240                                 }
241                                 
242                                 return;
243                         }
244                 }
245                 else {
246                         if (m_numOfAASamples && (m_numOfAASamples > samples)) {
247                                 printf("%s:%d: oversampling requested %i but using %i samples\n",
248                                        __FILE__, __LINE__, m_numOfAASamples, samples);
249                         }
250                         break;
251                 }
252         }
253
254         /* Create a bunch of attributes needed to create an X window. */
255
256
257         /* First create a colormap for the window and visual.
258          * This seems pretty much a legacy feature as we are in rgba mode anyway. */
259
260         XSetWindowAttributes xattributes;
261         memset(&xattributes, 0, sizeof(xattributes));
262
263         xattributes.colormap = XCreateColormap(m_display,
264                                                RootWindow(m_display, m_visual->screen),
265                                                m_visual->visual,
266                                                AllocNone
267                                                );
268
269         xattributes.border_pixel = 0;
270
271         /* Specify which events we are interested in hearing. */
272
273         xattributes.event_mask =
274             ExposureMask | StructureNotifyMask |
275             KeyPressMask | KeyReleaseMask |
276             EnterWindowMask | LeaveWindowMask |
277             ButtonPressMask | ButtonReleaseMask |
278             PointerMotionMask | FocusChangeMask | PropertyChangeMask;
279
280         /* create the window! */
281
282         ;
283         if (parentWindow == 0) {
284                 m_window =  XCreateWindow(m_display,
285                                           RootWindow(m_display, m_visual->screen),
286                                           left,
287                                           top,
288                                           width,
289                                           height,
290                                           0,  /* no border. */
291                                           m_visual->depth,
292                                           InputOutput,
293                                           m_visual->visual,
294                                           CWBorderPixel | CWColormap | CWEventMask,
295                                           &xattributes
296                                           );
297         }
298         else {
299
300                 Window root_return;
301                 int x_return, y_return;
302                 unsigned int w_return, h_return, border_w_return, depth_return;
303                 
304                 XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return,
305                              &w_return, &h_return, &border_w_return, &depth_return);
306
307                 left = 0;
308                 top = 0;
309                 width = w_return;
310                 height = h_return;
311
312
313                 m_window = XCreateWindow(m_display,
314                                          parentWindow,  /* reparent against embedder */
315                                          left,
316                                          top,
317                                          width,
318                                          height,
319                                          0,     /* no border. */
320                                          m_visual->depth,
321                                          InputOutput,
322                                          m_visual->visual,
323                                          CWBorderPixel | CWColormap | CWEventMask,
324                                          &xattributes
325                                          );
326
327                 XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
328                 
329         }       
330
331 #ifdef WITH_XDND
332         /* initialize drop target for newly created window */
333         m_dropTarget = new GHOST_DropTargetX11(this, m_system);
334         GHOST_PRINT("Set drop target\n");
335 #endif
336
337         /*
338          * One of the problem with WM-spec is that can't set a property
339          * to a window that isn't mapped. That is why we can't "just
340          * call setState" here.
341          *
342          * To fix this, we first need know that the window is really
343          * map waiting for the MapNotify event.
344          *
345          * So, m_post_init indicate that we need wait for the MapNotify
346          * event and then set the Window state to the m_post_state.
347          */
348         if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
349                 m_post_init = True;
350                 m_post_state = state;
351         }
352         else {
353                 m_post_init = False;
354                 m_post_state = GHOST_kWindowStateNormal;
355         }
356
357         /* Create some hints for the window manager on how
358          * we want this window treated. */
359
360         XSizeHints *xsizehints = XAllocSizeHints();
361         xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
362         xsizehints->x = left;
363         xsizehints->y = top;
364         xsizehints->width = width;
365         xsizehints->height = height;
366         xsizehints->min_width = 640;     /* size hints, could be made apart of the ghost api */
367         xsizehints->min_height = 480;    /* limits are also arbitrary, but should not allow 1x1 window */
368         xsizehints->max_width = 65535;
369         xsizehints->max_height = 65535;
370         XSetWMNormalHints(m_display, m_window, xsizehints);
371         XFree(xsizehints);
372
373         XClassHint *xclasshint = XAllocClassHint();
374         const int len = title.Length() + 1;
375         char *wmclass = (char *)malloc(sizeof(char) * len);
376         strncpy(wmclass, (const char *)title, sizeof(char) * len);
377         xclasshint->res_name = wmclass;
378         xclasshint->res_class = wmclass;
379         XSetClassHint(m_display, m_window, xclasshint);
380         free(wmclass);
381         XFree(xclasshint);
382
383         /* The basic for a good ICCCM "work" */
384         if (m_system->m_wm_protocols) {
385                 natom = 0;
386
387                 if (m_system->m_delete_window_atom) {
388                         atoms[natom] = m_system->m_delete_window_atom;
389                         natom++;
390                 }
391
392                 if (m_system->m_wm_take_focus) {
393                         atoms[natom] = m_system->m_wm_take_focus;
394                         natom++;
395                 }
396
397                 if (natom) {
398                         /* printf("Register atoms: %d\n", natom); */
399                         XSetWMProtocols(m_display, m_window, atoms, natom);
400                 }
401         }
402
403 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
404         m_xic = NULL;
405 #endif
406
407         /* Set the window icon */
408         XWMHints *xwmhints = XAllocWMHints();
409         XImage *x_image, *mask_image;
410         Pixmap icon_pixmap, mask_pixmap;
411         icon_pixmap = XCreatePixmap(display, m_window, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 24);
412         mask_pixmap = XCreatePixmap(display, m_window, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 1);
413         GC gc_icon = XCreateGC(display, icon_pixmap, 0, NULL);
414         GC gc_mask = XCreateGC(display, mask_pixmap, 0, NULL);
415         
416         x_image = XCreateImage(display, m_visual->visual, 24, ZPixmap, 0, NULL, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 32, 0);
417         mask_image = XCreateImage(display, m_visual->visual, 1, ZPixmap, 0, NULL,  BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 8, 0);
418         
419         x_image->data = (char *)calloc(x_image->bytes_per_line * BLENDER_ICON_HEIGHT, 1);
420         mask_image->data = (char *)calloc(mask_image->bytes_per_line * BLENDER_ICON_HEIGHT, 1);
421         
422         /* copy the BLENDER_ICON_48x48x24 into the XImage */
423         unsigned char *col = BLENDER_ICON_48x48x24;
424         int px, py;
425         for (px = 0; px < BLENDER_ICON_WIDTH; px++) {
426                 for (py = 0; py < BLENDER_ICON_HEIGHT; py++, col += 3) {
427                         /* mask out pink */
428                         if (col[0] == 255 && col[1] == 0 && col[2] == 255) {
429 #if 0
430                                 /* instead, use calloc above */
431                                 XPutPixel(x_image, px, py, 0); /* avoid uninitialized memory, otherwise not needed */
432                                 XPutPixel(mask_image, px, py, 0);
433 #endif
434                         }
435                         else {
436                                 XPutPixel(x_image, px, py, (col[0] << 16) + (col[1] << 8) + col[2]);
437                                 XPutPixel(mask_image, px, py, 1);
438                         }
439                 }
440         }
441         
442         XPutImage(display, icon_pixmap, gc_icon, x_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
443         XPutImage(display, mask_pixmap, gc_mask, mask_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
444         
445         /* Now the pixmap is ok to assign to the window as a hint */
446         xwmhints->icon_pixmap = icon_pixmap;
447         xwmhints->icon_mask = mask_pixmap;
448         XFreeGC(display, gc_icon);
449         XFreeGC(display, gc_mask);
450         XDestroyImage(x_image);   /* frees x_image->data too */
451         XDestroyImage(mask_image);
452         
453         xwmhints->initial_state = NormalState;
454         xwmhints->input = True;
455         xwmhints->flags = InputHint | IconPixmapHint | IconMaskHint | StateHint;
456         XSetWMHints(display, m_window, xwmhints);
457         XFree(xwmhints);
458         /* done setting the icon */
459
460         setTitle(title);
461
462 #ifdef WITH_X11_XINPUT
463         initXInputDevices();
464 #endif
465
466         /* now set up the rendering context. */
467         if (installDrawingContext(type) == GHOST_kSuccess) {
468                 m_valid_setup = true;
469                 GHOST_PRINT("Created window\n");
470         }
471
472         XMapWindow(m_display, m_window);
473         GHOST_PRINT("Mapped window\n");
474
475         XFlush(m_display);
476 }
477
478 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
479 static void destroyICCallback(XIC xic, XPointer ptr, XPointer data)
480 {
481         GHOST_PRINT("XIM input context destroyed\n");
482
483         if (ptr) {
484                 *(XIC *)ptr = NULL;
485         }
486 }
487
488 bool GHOST_WindowX11::createX11_XIC()
489 {
490         XIM xim = m_system->getX11_XIM();
491         if (!xim)
492                 return false;
493
494         XICCallback destroy;
495         destroy.callback = (XICProc)destroyICCallback;
496         destroy.client_data = (XPointer)&m_xic;
497         m_xic = XCreateIC(xim, XNClientWindow, m_window, XNFocusWindow, m_window,
498                           XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
499                           XNResourceName, GHOST_X11_RES_NAME,
500                           XNResourceClass, GHOST_X11_RES_CLASS,
501                           XNDestroyCallback, &destroy,
502                           NULL);
503         if (!m_xic)
504                 return false;
505
506         unsigned long fevent;
507         XGetICValues(m_xic, XNFilterEvents, &fevent, NULL);
508         XSelectInput(m_display, m_window,
509                      ExposureMask | StructureNotifyMask |
510                      KeyPressMask | KeyReleaseMask |
511                      EnterWindowMask | LeaveWindowMask |
512                      ButtonPressMask | ButtonReleaseMask |
513                      PointerMotionMask | FocusChangeMask |
514                      PropertyChangeMask | fevent);
515         return true;
516 }
517 #endif
518
519 #ifdef WITH_X11_XINPUT
520 /* 
521  * Dummy function to get around IO Handler exiting if device invalid
522  * Basically it will not crash blender now if you have a X device that
523  * is configured but not plugged in.
524  */
525 static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
526 {
527         fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
528                 theEvent->error_code, theEvent->request_code);
529
530         /* No exit! - but keep lint happy */
531         return 0;
532 }
533
534 /* These C functions are copied from Wine 1.1.13's wintab.c */
535 #define BOOL int
536 #define TRUE 1
537 #define FALSE 0
538
539 static bool match_token(const char *haystack, const char *needle)
540 {
541         const char *p, *q;
542         for (p = haystack; *p; )
543         {
544                 while (*p && isspace(*p))
545                         p++;
546                 if (!*p)
547                         break;
548
549                 for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
550                         p++;
551                 if (!*q && (isspace(*p) || !*p))
552                         return TRUE;
553
554                 while (*p && !isspace(*p))
555                         p++;
556         }
557         return FALSE;
558 }
559
560
561 /* Determining if an X device is a Tablet style device is an imperfect science.
562  * We rely on common conventions around device names as well as the type reported
563  * by Wacom tablets.  This code will likely need to be expanded for alternate tablet types
564  *
565  * Wintab refers to any device that interacts with the tablet as a cursor,
566  * (stylus, eraser, tablet mouse, airbrush, etc)
567  * this is not to be confused with wacom x11 configuration "cursor" device.
568  * Wacoms x11 config "cursor" refers to its device slot (which we mirror with
569  * our gSysCursors) for puck like devices (tablet mice essentially).
570  */
571 #if 0 // unused
572 static BOOL is_tablet_cursor(const char *name, const char *type)
573 {
574         int i;
575         static const char *tablet_cursor_whitelist[] = {
576                 "wacom",
577                 "wizardpen",
578                 "acecad",
579                 "tablet",
580                 "cursor",
581                 "stylus",
582                 "eraser",
583                 "pad",
584                 NULL
585         };
586
587         for (i = 0; tablet_cursor_whitelist[i] != NULL; i++) {
588                 if (name && match_token(name, tablet_cursor_whitelist[i]))
589                         return TRUE;
590                 if (type && match_token(type, tablet_cursor_whitelist[i]))
591                         return TRUE;
592         }
593         return FALSE;
594 }
595 #endif
596 static BOOL is_stylus(const char *name, const char *type)
597 {
598         int i;
599         static const char *tablet_stylus_whitelist[] = {
600                 "stylus",
601                 "wizardpen",
602                 "acecad",
603                 NULL
604         };
605
606         for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
607                 if (name && match_token(name, tablet_stylus_whitelist[i]))
608                         return TRUE;
609                 if (type && match_token(type, tablet_stylus_whitelist[i]))
610                         return TRUE;
611         }
612
613         return FALSE;
614 }
615
616 static BOOL is_eraser(const char *name, const char *type)
617 {
618         if (name && match_token(name, "eraser"))
619                 return TRUE;
620         if (type && match_token(type, "eraser"))
621                 return TRUE;
622         return FALSE;
623 }
624 #undef BOOL
625 #undef TRUE
626 #undef FALSE
627 /* end code copied from wine */
628
629 void GHOST_WindowX11::initXInputDevices()
630 {
631         static XErrorHandler old_handler = (XErrorHandler) 0;
632         XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
633
634         if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
635                 if (version->present) {
636                         int device_count;
637                         XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
638                         m_xtablet.StylusDevice = NULL;
639                         m_xtablet.EraserDevice = NULL;
640                         m_xtablet.CommonData.Active = GHOST_kTabletModeNone;
641
642                         /* Install our error handler to override Xlib's termination behavior */
643                         old_handler = XSetErrorHandler(ApplicationErrorHandler);
644
645                         for (int i = 0; i < device_count; ++i) {
646                                 char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
647                                 
648 //                              printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
649
650
651                                 if (m_xtablet.StylusDevice == NULL && is_stylus(device_info[i].name, device_type)) {
652 //                                      printf("\tfound stylus\n");
653                                         m_xtablet.StylusID = device_info[i].id;
654                                         m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
655
656                                         if (m_xtablet.StylusDevice != NULL) {
657                                                 /* Find how many pressure levels tablet has */
658                                                 XAnyClassPtr ici = device_info[i].inputclassinfo;
659                                                 for (int j = 0; j < m_xtablet.StylusDevice->num_classes; ++j) {
660                                                         if (ici->c_class == ValuatorClass) {
661 //                                                              printf("\t\tfound ValuatorClass\n");
662                                                                 XValuatorInfo *xvi = (XValuatorInfo *)ici;
663                                                                 m_xtablet.PressureLevels = xvi->axes[2].max_value;
664                                                         
665                                                                 /* this is assuming that the tablet has the same tilt resolution in both
666                                                                  * positive and negative directions. It would be rather weird if it didn't.. */
667                                                                 m_xtablet.XtiltLevels = xvi->axes[3].max_value;
668                                                                 m_xtablet.YtiltLevels = xvi->axes[4].max_value;
669                                                                 break;
670                                                         }
671                                                 
672                                                         ici = (XAnyClassPtr)(((char *)ici) + ici->length);
673                                                 }
674                                         }
675                                         else {
676                                                 m_xtablet.StylusID = 0;
677                                         }
678                                 }
679                                 else if (m_xtablet.EraserDevice == NULL && is_eraser(device_info[i].name, device_type)) {
680 //                                      printf("\tfound eraser\n");
681                                         m_xtablet.EraserID = device_info[i].id;
682                                         m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
683                                         if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID = 0;
684                                 }
685
686                                 if (device_type) {
687                                         XFree((void *)device_type);
688                                 }
689                         }
690
691                         /* Restore handler */
692                         (void) XSetErrorHandler(old_handler);
693
694                         XFreeDeviceList(device_info);
695
696
697                         XEventClass xevents[10], ev;
698                         int dcount = 0;
699
700                         if (m_xtablet.StylusDevice) {
701                                 DeviceMotionNotify(m_xtablet.StylusDevice, m_xtablet.MotionEvent, ev);
702                                 if (ev) xevents[dcount++] = ev;
703                                 ProximityIn(m_xtablet.StylusDevice, m_xtablet.ProxInEvent, ev);
704                                 if (ev) xevents[dcount++] = ev;
705                                 ProximityOut(m_xtablet.StylusDevice, m_xtablet.ProxOutEvent, ev);
706                                 if (ev) xevents[dcount++] = ev;
707                         }
708                         if (m_xtablet.EraserDevice) {
709                                 DeviceMotionNotify(m_xtablet.EraserDevice, m_xtablet.MotionEvent, ev);
710                                 if (ev) xevents[dcount++] = ev;
711                                 ProximityIn(m_xtablet.EraserDevice, m_xtablet.ProxInEvent, ev);
712                                 if (ev) xevents[dcount++] = ev;
713                                 ProximityOut(m_xtablet.EraserDevice, m_xtablet.ProxOutEvent, ev);
714                                 if (ev) xevents[dcount++] = ev;
715                         }
716
717                         XSelectExtensionEvent(m_display, m_window, xevents, dcount);
718                 }
719                 XFree(version);
720         }
721 }
722
723 #endif /* WITH_X11_XINPUT */
724
725 Window
726 GHOST_WindowX11::
727 getXWindow()
728 {
729         return m_window;
730 }
731
732 bool
733 GHOST_WindowX11::
734 getValid() const
735 {
736         return m_valid_setup;
737 }
738
739 void
740 GHOST_WindowX11::
741 setTitle(
742                 const STR_String& title)
743 {
744         Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
745         Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
746         XChangeProperty(m_display, m_window,
747                         name, utf8str, 8, PropModeReplace,
748                         (const unsigned char *) title.ReadPtr(),
749                         title.Length());
750
751         /* This should convert to valid x11 string
752          * and getTitle would need matching change */
753         XStoreName(m_display, m_window, title);
754
755         XFlush(m_display);
756 }
757
758 void
759 GHOST_WindowX11::
760 getTitle(
761                 STR_String& title) const
762 {
763         char *name = NULL;
764         
765         XFetchName(m_display, m_window, &name);
766         title = name ? name : "untitled";
767         XFree(name);
768 }
769         
770 void
771 GHOST_WindowX11::
772 getWindowBounds(
773                 GHOST_Rect& bounds) const
774 {
775         /* Getting the window bounds under X11 is not
776          * really supported (nor should it be desired). */
777         getClientBounds(bounds);
778 }
779
780 void
781 GHOST_WindowX11::
782 getClientBounds(
783                 GHOST_Rect& bounds) const
784 {
785         Window root_return;
786         int x_return, y_return;
787         unsigned int w_return, h_return, border_w_return, depth_return;
788         GHOST_TInt32 screen_x, screen_y;
789         
790         XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
791                      &w_return, &h_return, &border_w_return, &depth_return);
792
793         clientToScreen(0, 0, screen_x, screen_y);
794         
795         bounds.m_l = screen_x;
796         bounds.m_r = bounds.m_l + w_return;
797         bounds.m_t = screen_y;
798         bounds.m_b = bounds.m_t + h_return;
799
800 }
801
802 GHOST_TSuccess
803 GHOST_WindowX11::
804 setClientWidth(
805                 GHOST_TUns32 width)
806 {
807         XWindowChanges values;
808         unsigned int value_mask = CWWidth;
809         values.width = width;
810         XConfigureWindow(m_display, m_window, value_mask, &values);
811
812         return GHOST_kSuccess;
813 }
814
815 GHOST_TSuccess
816 GHOST_WindowX11::
817 setClientHeight(
818                 GHOST_TUns32 height)
819 {
820         XWindowChanges values;
821         unsigned int value_mask = CWHeight;
822         values.height = height;
823         XConfigureWindow(m_display, m_window, value_mask, &values);
824         return GHOST_kSuccess;
825
826 }
827
828 GHOST_TSuccess
829 GHOST_WindowX11::
830 setClientSize(
831                 GHOST_TUns32 width,
832                 GHOST_TUns32 height)
833 {
834         XWindowChanges values;
835         unsigned int value_mask = CWWidth | CWHeight;
836         values.width = width;
837         values.height = height;
838         XConfigureWindow(m_display, m_window, value_mask, &values);
839         return GHOST_kSuccess;
840
841 }       
842
843 void
844 GHOST_WindowX11::
845 screenToClient(
846                 GHOST_TInt32 inX,
847                 GHOST_TInt32 inY,
848                 GHOST_TInt32& outX,
849                 GHOST_TInt32& outY) const
850 {
851         /* This is correct! */
852
853         int ax, ay;
854         Window temp;
855
856         XTranslateCoordinates(m_display,
857                               RootWindow(m_display, m_visual->screen),
858                               m_window,
859                               inX, inY,
860                               &ax, &ay,
861                               &temp);
862         outX = ax;
863         outY = ay;
864 }
865                  
866 void
867 GHOST_WindowX11::
868 clientToScreen(
869                 GHOST_TInt32 inX,
870                 GHOST_TInt32 inY,
871                 GHOST_TInt32& outX,
872                 GHOST_TInt32& outY) const
873 {
874         int ax, ay;
875         Window temp;
876
877         XTranslateCoordinates(
878             m_display,
879             m_window,
880             RootWindow(m_display, m_visual->screen),
881             inX, inY,
882             &ax, &ay,
883             &temp);
884         outX = ax;
885         outY = ay;
886 }
887
888 void GHOST_WindowX11::icccmSetState(int state)
889 {
890         XEvent xev;
891
892         if (state != IconicState)
893                 return;
894
895         xev.xclient.type = ClientMessage;
896         xev.xclient.serial = 0;
897         xev.xclient.send_event = True;
898         xev.xclient.display = m_display;
899         xev.xclient.window = m_window;
900         xev.xclient.format = 32;
901         xev.xclient.message_type = m_system->m_wm_change_state;
902         xev.xclient.data.l[0] = state;
903         XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
904                    False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
905 }
906
907 int GHOST_WindowX11::icccmGetState(void) const
908 {
909         unsigned char *prop_ret;
910         unsigned long bytes_after, num_ret;
911         Atom type_ret;
912         int format_ret, st;
913
914         prop_ret = NULL;
915         st = XGetWindowProperty(m_display, m_window, m_system->m_wm_state, 0,
916                                 0x7fffffff, False, m_system->m_wm_state, &type_ret,
917                                 &format_ret, &num_ret, &bytes_after, &prop_ret);
918
919         if ((st == Success) && (prop_ret) && (num_ret == 2))
920                 st = prop_ret[0];
921         else
922                 st = NormalState;
923
924         if (prop_ret)
925                 XFree(prop_ret);
926         return (st);
927 }
928
929 void GHOST_WindowX11::netwmMaximized(bool set)
930 {
931         XEvent xev;
932
933         xev.xclient.type = ClientMessage;
934         xev.xclient.serial = 0;
935         xev.xclient.send_event = True;
936         xev.xclient.window = m_window;
937         xev.xclient.message_type = m_system->m_net_state;
938         xev.xclient.format = 32;
939
940         if (set == True)
941                 xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
942         else
943                 xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
944
945         xev.xclient.data.l[1] = m_system->m_net_max_horz;
946         xev.xclient.data.l[2] = m_system->m_net_max_vert;
947         xev.xclient.data.l[3] = 0;
948         xev.xclient.data.l[4] = 0;
949         XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
950                    False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
951 }
952
953 bool GHOST_WindowX11::netwmIsMaximized(void) const
954 {
955         unsigned char *prop_ret;
956         unsigned long bytes_after, num_ret, i;
957         Atom type_ret;
958         bool st;
959         int format_ret, ret, count;
960
961         prop_ret = NULL;
962         st = False;
963         ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
964                                  0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
965                                  &num_ret, &bytes_after, &prop_ret);
966         if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
967                 count = 0;
968                 for (i = 0; i < num_ret; i++) {
969                         if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_horz)
970                                 count++;
971                         if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_vert)
972                                 count++;
973                         if (count == 2) {
974                                 st = True;
975                                 break;
976                         }
977                 }
978         }
979
980         if (prop_ret)
981                 XFree(prop_ret);
982         return (st);
983 }
984
985 void GHOST_WindowX11::netwmFullScreen(bool set)
986 {
987         XEvent xev;
988
989         xev.xclient.type = ClientMessage;
990         xev.xclient.serial = 0;
991         xev.xclient.send_event = True;
992         xev.xclient.window = m_window;
993         xev.xclient.message_type = m_system->m_net_state;
994         xev.xclient.format = 32;
995
996         if (set == True)
997                 xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
998         else
999                 xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
1000
1001         xev.xclient.data.l[1] = m_system->m_net_fullscreen;
1002         xev.xclient.data.l[2] = 0;
1003         xev.xclient.data.l[3] = 0;
1004         xev.xclient.data.l[4] = 0;
1005         XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
1006                    False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
1007 }
1008
1009 bool GHOST_WindowX11::netwmIsFullScreen(void) const
1010 {
1011         unsigned char *prop_ret;
1012         unsigned long bytes_after, num_ret, i;
1013         Atom type_ret;
1014         bool st;
1015         int format_ret, ret;
1016
1017         prop_ret = NULL;
1018         st = False;
1019         ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
1020                                  0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
1021                                  &num_ret, &bytes_after, &prop_ret);
1022         if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
1023                 for (i = 0; i < num_ret; i++) {
1024                         if (((unsigned long *) prop_ret)[i] == m_system->m_net_fullscreen) {
1025                                 st = True;
1026                                 break;
1027                         }
1028                 }
1029         }
1030
1031         if (prop_ret)
1032                 XFree(prop_ret);
1033         return (st);
1034 }
1035
1036 void GHOST_WindowX11::motifFullScreen(bool set)
1037 {
1038         MotifWmHints hints;
1039
1040         hints.flags = MWM_HINTS_DECORATIONS;
1041         if (set == True)
1042                 hints.decorations = 0;
1043         else
1044                 hints.decorations = 1;
1045
1046         XChangeProperty(m_display, m_window, m_system->m_motif,
1047                         m_system->m_motif, 32, PropModeReplace,
1048                         (unsigned char *) &hints, 4);
1049 }
1050
1051 bool GHOST_WindowX11::motifIsFullScreen(void) const
1052 {
1053         unsigned char *prop_ret;
1054         unsigned long bytes_after, num_ret;
1055         MotifWmHints *hints;
1056         Atom type_ret;
1057         bool state;
1058         int format_ret, st;
1059
1060         prop_ret = NULL;
1061         state = False;
1062         st = XGetWindowProperty(m_display, m_window, m_system->m_motif, 0,
1063                                 0x7fffffff, False, m_system->m_motif,
1064                                 &type_ret, &format_ret, &num_ret,
1065                                 &bytes_after, &prop_ret);
1066         if ((st == Success) && (prop_ret)) {
1067                 hints = (MotifWmHints *) prop_ret;
1068                 if (hints->flags & MWM_HINTS_DECORATIONS) {
1069                         if (!hints->decorations)
1070                                 state = True;
1071                 }
1072         }
1073
1074         if (prop_ret)
1075                 XFree(prop_ret);
1076         return (state);
1077 }
1078
1079 GHOST_TWindowState GHOST_WindowX11::getState() const
1080 {
1081         GHOST_TWindowState state_ret;
1082         int state;
1083
1084         state_ret = GHOST_kWindowStateNormal;
1085         state = icccmGetState();
1086         /*
1087          * In the Iconic and Withdrawn state, the window
1088          * is unmaped, so only need return a Minimized state.
1089          */
1090         if ((state == IconicState) || (state == WithdrawnState))
1091                 state_ret = GHOST_kWindowStateMinimized;
1092         else if (netwmIsMaximized() == True)
1093                 state_ret = GHOST_kWindowStateMaximized;
1094         else if (netwmIsFullScreen() == True)
1095                 state_ret = GHOST_kWindowStateFullScreen;
1096         else if (motifIsFullScreen() == True)
1097                 state_ret = GHOST_kWindowStateFullScreen;
1098         return (state_ret);
1099 }
1100
1101 GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
1102 {
1103         GHOST_TWindowState cur_state;
1104         bool is_max, is_full, is_motif_full;
1105
1106         cur_state = getState();
1107         if (state == (int)cur_state)
1108                 return GHOST_kSuccess;
1109
1110         if (cur_state != GHOST_kWindowStateMinimized) {
1111                 /*
1112                  * The window don't have this property's
1113                  * if it's not mapped.
1114                  */
1115                 is_max = netwmIsMaximized();
1116                 is_full = netwmIsFullScreen();
1117         }
1118         else {
1119                 is_max = False;
1120                 is_full = False;
1121         }
1122
1123         is_motif_full = motifIsFullScreen();
1124
1125         if (state == GHOST_kWindowStateNormal)
1126                 state = m_normal_state;
1127
1128         if (state == GHOST_kWindowStateNormal) {
1129                 if (is_max == True)
1130                         netwmMaximized(False);
1131                 if (is_full == True)
1132                         netwmFullScreen(False);
1133                 if (is_motif_full == True)
1134                         motifFullScreen(False);
1135                 icccmSetState(NormalState);
1136                 return (GHOST_kSuccess);
1137         }
1138
1139         if (state == GHOST_kWindowStateFullScreen) {
1140                 /*
1141                  * We can't change to full screen if the window
1142                  * isn't mapped.
1143                  */
1144                 if (cur_state == GHOST_kWindowStateMinimized)
1145                         return (GHOST_kFailure);
1146
1147                 m_normal_state = cur_state;
1148
1149                 if (is_max == True)
1150                         netwmMaximized(False);
1151                 if (is_full == False)
1152                         netwmFullScreen(True);
1153                 if (is_motif_full == False)
1154                         motifFullScreen(True);
1155                 return (GHOST_kSuccess);
1156         }
1157
1158         if (state == GHOST_kWindowStateMaximized) {
1159                 /*
1160                  * We can't change to Maximized if the window
1161                  * isn't mapped.
1162                  */
1163                 if (cur_state == GHOST_kWindowStateMinimized)
1164                         return (GHOST_kFailure);
1165
1166                 if (is_full == True)
1167                         netwmFullScreen(False);
1168                 if (is_motif_full == True)
1169                         motifFullScreen(False);
1170                 if (is_max == False)
1171                         netwmMaximized(True);
1172                 return (GHOST_kSuccess);
1173         }
1174
1175         if (state == GHOST_kWindowStateMinimized) {
1176                 /*
1177                  * The window manager need save the current state of
1178                  * the window (maximized, full screen, etc).
1179                  */
1180                 icccmSetState(IconicState);
1181                 return (GHOST_kSuccess);
1182         }
1183
1184         return (GHOST_kFailure);
1185 }
1186
1187 #include <iostream>
1188
1189 GHOST_TSuccess
1190 GHOST_WindowX11::
1191 setOrder(
1192                 GHOST_TWindowOrder order)
1193 {
1194         if (order == GHOST_kWindowOrderTop) {
1195                 XWindowAttributes attr;   
1196                 Atom atom;
1197
1198                 /* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some
1199                  * window managers ignore the former (e.g. kwin from kde) and others
1200                  * don't implement the latter (e.g. fluxbox pre 0.9.9) */
1201
1202                 XRaiseWindow(m_display, m_window);
1203
1204                 atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True);
1205
1206                 if (atom != None) {
1207                         Window root;
1208                         XEvent xev;
1209                         long eventmask;
1210
1211                         xev.xclient.type = ClientMessage;
1212                         xev.xclient.serial = 0;
1213                         xev.xclient.send_event = True;
1214                         xev.xclient.window = m_window;
1215                         xev.xclient.message_type = atom;
1216
1217                         xev.xclient.format = 32;
1218                         xev.xclient.data.l[0] = 1;
1219                         xev.xclient.data.l[1] = CurrentTime;
1220                         xev.xclient.data.l[2] = m_window;
1221                         xev.xclient.data.l[3] = 0;
1222                         xev.xclient.data.l[4] = 0;
1223
1224                         root = RootWindow(m_display, m_visual->screen),
1225                         eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
1226
1227                         XSendEvent(m_display, root, False, eventmask, &xev);
1228                 }
1229
1230                 XGetWindowAttributes(m_display, m_window, &attr);
1231
1232                 /* iconized windows give bad match error */
1233                 if (attr.map_state == IsViewable)
1234                         XSetInputFocus(m_display, m_window, RevertToPointerRoot,
1235                                        CurrentTime);
1236                 XFlush(m_display);
1237         }
1238         else if (order == GHOST_kWindowOrderBottom) {
1239                 XLowerWindow(m_display, m_window);
1240                 XFlush(m_display);
1241         }
1242         else {
1243                 return GHOST_kFailure;
1244         }
1245         
1246         return GHOST_kSuccess;
1247 }
1248
1249 GHOST_TSuccess
1250 GHOST_WindowX11::
1251 swapBuffers()
1252 {
1253         if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
1254                 glXSwapBuffers(m_display, m_window);
1255                 return GHOST_kSuccess;
1256         }
1257         else {
1258                 return GHOST_kFailure;
1259         }
1260 }
1261
1262 GHOST_TSuccess
1263 GHOST_WindowX11::
1264 activateDrawingContext()
1265 {
1266         if (m_context != NULL) {
1267                 glXMakeCurrent(m_display, m_window, m_context);
1268                 /* Disable AA by default */
1269                 if (m_numOfAASamples > 0) {
1270                         glDisable(GL_MULTISAMPLE_ARB);
1271                 }
1272                 return GHOST_kSuccess;
1273         } 
1274         return GHOST_kFailure;
1275 }
1276
1277 GHOST_TSuccess
1278 GHOST_WindowX11::
1279 invalidate()
1280 {
1281         /* So the idea of this function is to generate an expose event
1282          * for the window.
1283          * Unfortunately X does not handle expose events for you and
1284          * it is the client's job to refresh the dirty part of the window.
1285          * We need to queue up invalidate calls and generate GHOST events
1286          * for them in the system.
1287          *
1288          * We implement this by setting a boolean in this class to concatenate
1289          * all such calls into a single event for this window.
1290          *
1291          * At the same time we queue the dirty windows in the system class
1292          * and generate events for them at the next processEvents call. */
1293
1294         if (m_invalid_window == false) {
1295                 m_system->addDirtyWindow(this);
1296                 m_invalid_window = true;
1297         } 
1298  
1299         return GHOST_kSuccess;
1300 }
1301
1302 /**
1303  * called by the X11 system implementation when expose events
1304  * for the window have been pushed onto the GHOST queue
1305  */
1306  
1307 void
1308 GHOST_WindowX11::
1309 validate()
1310 {
1311         m_invalid_window = false;
1312 }       
1313  
1314  
1315 /**
1316  * Destructor.
1317  * Closes the window and disposes resources allocated.
1318  */
1319
1320 GHOST_WindowX11::
1321 ~GHOST_WindowX11()
1322 {
1323         static Atom Primary_atom, Clipboard_atom;
1324         Window p_owner, c_owner;
1325         /*Change the owner of the Atoms to None if we are the owner*/
1326         Primary_atom = XInternAtom(m_display, "PRIMARY", False);
1327         Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
1328         
1329         p_owner = XGetSelectionOwner(m_display, Primary_atom);
1330         c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
1331         
1332         std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
1333         for (; it != m_standard_cursors.end(); ++it) {
1334                 XFreeCursor(m_display, it->second);
1335         }
1336
1337         if (m_empty_cursor) {
1338                 XFreeCursor(m_display, m_empty_cursor);
1339         }
1340         if (m_custom_cursor) {
1341                 XFreeCursor(m_display, m_custom_cursor);
1342         }
1343
1344 #ifdef WITH_X11_XINPUT
1345         /* close tablet devices */
1346         if (m_xtablet.StylusDevice)
1347                 XCloseDevice(m_display, m_xtablet.StylusDevice);
1348         
1349         if (m_xtablet.EraserDevice)
1350                 XCloseDevice(m_display, m_xtablet.EraserDevice);
1351 #endif /* WITH_X11_XINPUT */
1352
1353         if (m_context != s_firstContext) {
1354                 glXDestroyContext(m_display, m_context);
1355         }
1356         
1357         if (p_owner == m_window) {
1358                 XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
1359         }
1360         if (c_owner == m_window) {
1361                 XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
1362         }
1363         
1364 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
1365         if (m_xic) {
1366                 XDestroyIC(m_xic);
1367         }
1368 #endif
1369
1370 #ifdef WITH_XDND
1371         delete m_dropTarget;
1372 #endif
1373
1374         XDestroyWindow(m_display, m_window);
1375         XFree(m_visual);
1376 }
1377
1378
1379
1380
1381 /**
1382  * Tries to install a rendering context in this window.
1383  * \param type  The type of rendering context installed.
1384  * \return Indication as to whether installation has succeeded.
1385  */
1386 GHOST_TSuccess
1387 GHOST_WindowX11::
1388 installDrawingContext(
1389                 GHOST_TDrawingContextType type)
1390 {
1391         /* only support openGL for now. */
1392         GHOST_TSuccess success;
1393         switch (type) {
1394                 case GHOST_kDrawingContextTypeOpenGL:
1395                         m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
1396                         if (m_context != NULL) {
1397                                 if (!s_firstContext) {
1398                                         s_firstContext = m_context;
1399                                 }
1400                                 glXMakeCurrent(m_display, m_window, m_context);
1401                                 glClearColor(0.447, 0.447, 0.447, 0);
1402                                 glClear(GL_COLOR_BUFFER_BIT);
1403                                 success = GHOST_kSuccess;
1404                         }
1405                         else {
1406                                 success = GHOST_kFailure;
1407                         }
1408
1409                         break;
1410
1411                 case GHOST_kDrawingContextTypeNone:
1412                         success = GHOST_kSuccess;
1413                         break;
1414
1415                 default:
1416                         success = GHOST_kFailure;
1417         }
1418         return success;
1419 }
1420
1421
1422
1423 /**
1424  * Removes the current drawing context.
1425  * \return Indication as to whether removal has succeeded.
1426  */
1427 GHOST_TSuccess
1428 GHOST_WindowX11::
1429 removeDrawingContext()
1430 {
1431         GHOST_TSuccess success;
1432
1433         if (m_context != NULL) {
1434                 glXDestroyContext(m_display, m_context);
1435                 success = GHOST_kSuccess;
1436         }
1437         else {
1438                 success = GHOST_kFailure;
1439         }
1440         return success; 
1441 }
1442
1443
1444 Cursor
1445 GHOST_WindowX11::
1446 getStandardCursor(
1447                 GHOST_TStandardCursor g_cursor)
1448 {
1449         unsigned int xcursor_id;
1450
1451 #define GtoX(gcurs, xcurs)  case gcurs: xcursor_id = xcurs
1452         switch (g_cursor) {
1453                 GtoX(GHOST_kStandardCursorRightArrow, XC_arrow); break;
1454                 GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow); break;
1455                 GtoX(GHOST_kStandardCursorInfo, XC_hand1); break;
1456                 GtoX(GHOST_kStandardCursorDestroy, XC_pirate); break;
1457                 GtoX(GHOST_kStandardCursorHelp, XC_question_arrow); break;
1458                 GtoX(GHOST_kStandardCursorCycle, XC_exchange); break;
1459                 GtoX(GHOST_kStandardCursorSpray, XC_spraycan); break;
1460                 GtoX(GHOST_kStandardCursorWait, XC_watch); break;
1461                 GtoX(GHOST_kStandardCursorText, XC_xterm); break;
1462                 GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair); break;
1463                 GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow); break;
1464                 GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow); break;
1465                 GtoX(GHOST_kStandardCursorTopSide, XC_top_side); break;
1466                 GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side); break;
1467                 GtoX(GHOST_kStandardCursorLeftSide, XC_left_side); break;
1468                 GtoX(GHOST_kStandardCursorRightSide, XC_right_side); break;
1469                 GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner); break;
1470                 GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner); break;
1471                 GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner); break;
1472                 GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner); break;
1473                 GtoX(GHOST_kStandardCursorPencil, XC_pencil); break;
1474                 GtoX(GHOST_kStandardCursorCopy, XC_arrow); break;
1475                 default:
1476                         xcursor_id = 0;
1477         }
1478 #undef GtoX
1479
1480         if (xcursor_id) {
1481                 Cursor xcursor = m_standard_cursors[xcursor_id];
1482                 
1483                 if (!xcursor) {
1484                         xcursor = XCreateFontCursor(m_display, xcursor_id);
1485
1486                         m_standard_cursors[xcursor_id] = xcursor;
1487                 }
1488                 
1489                 return xcursor;
1490         }
1491         else {
1492                 return None;
1493         }
1494 }
1495
1496 Cursor
1497 GHOST_WindowX11::
1498 getEmptyCursor(
1499         ) {
1500         if (!m_empty_cursor) {
1501                 Pixmap blank;
1502                 XColor dummy;
1503                 char data[1] = {0};
1504                         
1505                 /* make a blank cursor */
1506                 blank = XCreateBitmapFromData(
1507                     m_display,
1508                     RootWindow(m_display, DefaultScreen(m_display)),
1509                     data, 1, 1
1510                     );
1511
1512                 m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0);
1513                 XFreePixmap(m_display, blank);
1514         }
1515
1516         return m_empty_cursor;
1517 }
1518
1519 GHOST_TSuccess
1520 GHOST_WindowX11::
1521 setWindowCursorVisibility(
1522                 bool visible)
1523 {
1524         Cursor xcursor;
1525         
1526         if (visible) {
1527                 xcursor = getStandardCursor(getCursorShape() );
1528         }
1529         else {
1530                 xcursor = getEmptyCursor();
1531         }
1532
1533         XDefineCursor(m_display, m_window, xcursor);
1534         XFlush(m_display);
1535         
1536         return GHOST_kSuccess;
1537 }
1538
1539 GHOST_TSuccess
1540 GHOST_WindowX11::
1541 setWindowCursorGrab(
1542                 GHOST_TGrabCursorMode mode)
1543 {
1544         if (mode != GHOST_kGrabDisable) {
1545                 if (mode != GHOST_kGrabNormal) {
1546                         m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
1547                         setCursorGrabAccum(0, 0);
1548
1549                         if (mode == GHOST_kGrabHide)
1550                                 setWindowCursorVisibility(false);
1551
1552                 }
1553 #ifdef GHOST_X11_GRAB
1554                 XGrabPointer(m_display, m_window, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
1555                              GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
1556 #endif
1557         }
1558         else {
1559                 if (m_cursorGrab == GHOST_kGrabHide) {
1560                         m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
1561                         setWindowCursorVisibility(true);
1562                 }
1563
1564                 if (m_cursorGrab != GHOST_kGrabNormal) {
1565                         /* use to generate a mouse move event, otherwise the last event
1566                          * blender gets can be outside the screen causing menus not to show
1567                          * properly unless the user moves the mouse */
1568                         XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0);
1569                 }
1570
1571                 /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
1572                 setCursorGrabAccum(0, 0);
1573                 m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
1574 #ifdef GHOST_X11_GRAB
1575                 XUngrabPointer(m_display, CurrentTime);
1576 #endif
1577         }
1578
1579         XFlush(m_display);
1580         
1581         return GHOST_kSuccess;
1582 }
1583
1584 GHOST_TSuccess
1585 GHOST_WindowX11::
1586 setWindowCursorShape(
1587                 GHOST_TStandardCursor shape)
1588 {
1589         Cursor xcursor = getStandardCursor(shape);
1590         
1591         XDefineCursor(m_display, m_window, xcursor);
1592         XFlush(m_display);
1593
1594         return GHOST_kSuccess;
1595 }
1596
1597 GHOST_TSuccess
1598 GHOST_WindowX11::
1599 setWindowCustomCursorShape(
1600                 GHOST_TUns8 bitmap[16][2],
1601                 GHOST_TUns8 mask[16][2],
1602                 int hotX,
1603                 int hotY)
1604 {
1605         setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask,
1606                                    16, 16, hotX, hotY, 0, 1);
1607         return GHOST_kSuccess;
1608 }
1609
1610 GHOST_TSuccess
1611 GHOST_WindowX11::
1612 setWindowCustomCursorShape(     
1613                 GHOST_TUns8 *bitmap,
1614                 GHOST_TUns8 *mask,
1615                 int sizex,
1616                 int sizey,
1617                 int hotX,
1618                 int hotY,
1619                 int fg_color,
1620                 int bg_color)
1621 {
1622         Colormap colormap = DefaultColormap(m_display, DefaultScreen(m_display));
1623         Pixmap bitmap_pix, mask_pix;
1624         XColor fg, bg;
1625         
1626         if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure;
1627         if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure;
1628
1629         if (m_custom_cursor) {
1630                 XFreeCursor(m_display, m_custom_cursor);
1631         }
1632
1633         bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *) bitmap, sizex, sizey);
1634         mask_pix = XCreateBitmapFromData(m_display, m_window, (char *) mask, sizex, sizey);
1635                 
1636         m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
1637         XDefineCursor(m_display, m_window, m_custom_cursor);
1638         XFlush(m_display);
1639         
1640         XFreePixmap(m_display, bitmap_pix);
1641         XFreePixmap(m_display, mask_pix);
1642
1643         XFreeColors(m_display, colormap, &fg.pixel, 1, 0L);
1644         XFreeColors(m_display, colormap, &bg.pixel, 1, 0L);
1645
1646         return GHOST_kSuccess;
1647 }