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