1603 lines
79 KiB
C++
1603 lines
79 KiB
C++
/*
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
*/
|
|
|
|
/** \file ghost/intern/GHOST_WindowX11.cpp
|
|
* \ingroup GHOST
|
|
*/
|
|
|
|
|
|
#include "GHOST_WindowX11.h"
|
|
#include "GHOST_SystemX11.h"
|
|
#include "STR_String.h"
|
|
#include "GHOST_Debug.h"
|
|
|
|
#ifdef WITH_XDND
|
|
#include "GHOST_DropTargetX11.h"
|
|
#endif
|
|
|
|
// For standard X11 cursors
|
|
#include <X11/cursorfont.h>
|
|
#include <X11/Xatom.h>
|
|
|
|
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
|
|
#include <strings.h>
|
|
#endif
|
|
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
|
|
#include <algorithm>
|
|
#include <string>
|
|
|
|
// For obscure full screen mode stuuf
|
|
// lifted verbatim from blut.
|
|
|
|
typedef struct {
|
|
long flags;
|
|
long functions;
|
|
long decorations;
|
|
long input_mode;
|
|
} MotifWmHints;
|
|
|
|
#define MWM_HINTS_DECORATIONS (1L << 1)
|
|
|
|
|
|
// #define GHOST_X11_GRAB
|
|
|
|
/*
|
|
* A Client can't change the window property, that is
|
|
* the work of the window manager. In case, we send
|
|
* a ClientMessage to the RootWindow with the property
|
|
* and the Action (WM-spec define this):
|
|
*/
|
|
#define _NET_WM_STATE_REMOVE 0
|
|
#define _NET_WM_STATE_ADD 1
|
|
#define _NET_WM_STATE_TOGGLE 2
|
|
|
|
/*
|
|
import bpy
|
|
I = bpy.data.images['blender.png'] # the 48x48 icon
|
|
|
|
# Write to a file that can be
|
|
# used within static unsigned char BLENDER_ICON_48x48x24[] = {...}
|
|
f = open('/myicon.txt', 'w')
|
|
for j in xrange(48):
|
|
for k in xrange(48):
|
|
v = I.getPixelI(j,47-k)
|
|
v.pop()
|
|
for p in v:
|
|
f.write(str(hex(p))+',')
|
|
|
|
f.write('\n')
|
|
*/
|
|
|
|
// See the python script above to regenerate the 48x48 icon within blender
|
|
#define BLENDER_ICON_WIDTH 48
|
|
#define BLENDER_ICON_HEIGHT 48
|
|
static unsigned char BLENDER_ICON_48x48x24[] = {
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0xff, 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,
|
|
};
|
|
|
|
|
|
GLXContext GHOST_WindowX11::s_firstContext = NULL;
|
|
|
|
GHOST_WindowX11::
|
|
GHOST_WindowX11(
|
|
GHOST_SystemX11 *system,
|
|
Display *display,
|
|
const STR_String& title,
|
|
GHOST_TInt32 left,
|
|
GHOST_TInt32 top,
|
|
GHOST_TUns32 width,
|
|
GHOST_TUns32 height,
|
|
GHOST_TWindowState state,
|
|
const GHOST_TEmbedderWindowID parentWindow,
|
|
GHOST_TDrawingContextType type,
|
|
const bool stereoVisual,
|
|
const GHOST_TUns16 numOfAASamples
|
|
) :
|
|
GHOST_Window(width, height, state, type, stereoVisual, numOfAASamples),
|
|
m_context(NULL),
|
|
m_display(display),
|
|
m_normal_state(GHOST_kWindowStateNormal),
|
|
m_system(system),
|
|
m_valid_setup(false),
|
|
m_invalid_window(false),
|
|
m_empty_cursor(None),
|
|
m_custom_cursor(None)
|
|
{
|
|
|
|
// Set up the minimum atrributes that we require and see if
|
|
// X can find us a visual matching those requirements.
|
|
|
|
int attributes[40], i, samples;
|
|
Atom atoms[2];
|
|
int natom;
|
|
int glxVersionMajor, glxVersionMinor; // As in GLX major.minor
|
|
|
|
#ifdef WITH_X11_XINPUT
|
|
/* initialize incase X11 fails to load */
|
|
memset(&m_xtablet, 0, sizeof(m_xtablet));
|
|
#endif
|
|
|
|
m_visual = NULL;
|
|
|
|
if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
|
|
printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
|
|
|
/* exit if this is the first window */
|
|
if (s_firstContext == NULL) {
|
|
printf("initial window could not find the GLX extension, exit!\n");
|
|
exit(1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/* Find the display with highest samples, starting at level requested */
|
|
for (samples = m_numOfAASamples; samples >= 0; samples--) {
|
|
i = 0; /* Reusing attributes array, so reset counter */
|
|
|
|
if (m_stereoVisual)
|
|
attributes[i++] = GLX_STEREO;
|
|
|
|
attributes[i++] = GLX_RGBA;
|
|
attributes[i++] = GLX_DOUBLEBUFFER;
|
|
attributes[i++] = GLX_RED_SIZE; attributes[i++] = 1;
|
|
attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
|
|
attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
|
|
attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
|
|
/* GLX >= 1.4 required for multi-sample */
|
|
if (samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
|
|
attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
|
|
attributes[i++] = GLX_SAMPLES; attributes[i++] = samples;
|
|
}
|
|
attributes[i] = None;
|
|
|
|
m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
|
|
|
|
/* Any sample level or even zero, which means oversampling disabled, is good
|
|
but we need a valid visual to continue */
|
|
if (m_visual == NULL) {
|
|
if (samples == 0) {
|
|
/* All options exhausted, cannot continue */
|
|
printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
|
|
|
if (s_firstContext == NULL) {
|
|
printf("initial window could not find the GLX extension, exit!\n");
|
|
exit(1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
if (m_numOfAASamples && (m_numOfAASamples > samples)) {
|
|
printf("%s:%d: oversampling requested %i but using %i samples\n",
|
|
__FILE__, __LINE__, m_numOfAASamples, samples);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Create a bunch of attributes needed to create an X window.
|
|
|
|
|
|
// First create a colormap for the window and visual.
|
|
// This seems pretty much a legacy feature as we are in rgba mode anyway.
|
|
|
|
XSetWindowAttributes xattributes;
|
|
memset(&xattributes, 0, sizeof(xattributes));
|
|
|
|
xattributes.colormap = XCreateColormap(m_display,
|
|
RootWindow(m_display, m_visual->screen),
|
|
m_visual->visual,
|
|
AllocNone
|
|
);
|
|
|
|
xattributes.border_pixel = 0;
|
|
|
|
// Specify which events we are interested in hearing.
|
|
|
|
xattributes.event_mask =
|
|
ExposureMask | StructureNotifyMask |
|
|
KeyPressMask | KeyReleaseMask |
|
|
EnterWindowMask | LeaveWindowMask |
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
PointerMotionMask | FocusChangeMask | PropertyChangeMask;
|
|
|
|
// create the window!
|
|
|
|
;
|
|
if (parentWindow == 0) {
|
|
m_window = XCreateWindow(m_display,
|
|
RootWindow(m_display, m_visual->screen),
|
|
left,
|
|
top,
|
|
width,
|
|
height,
|
|
0, // no border.
|
|
m_visual->depth,
|
|
InputOutput,
|
|
m_visual->visual,
|
|
CWBorderPixel | CWColormap | CWEventMask,
|
|
&xattributes
|
|
);
|
|
}
|
|
else {
|
|
|
|
Window root_return;
|
|
int x_return, y_return;
|
|
unsigned int w_return, h_return, border_w_return, depth_return;
|
|
|
|
XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return,
|
|
&w_return, &h_return, &border_w_return, &depth_return);
|
|
|
|
left = 0;
|
|
top = 0;
|
|
width = w_return;
|
|
height = h_return;
|
|
|
|
|
|
m_window = XCreateWindow(m_display,
|
|
parentWindow, // reparent against embedder
|
|
left,
|
|
top,
|
|
width,
|
|
height,
|
|
0, // no border.
|
|
m_visual->depth,
|
|
InputOutput,
|
|
m_visual->visual,
|
|
CWBorderPixel | CWColormap | CWEventMask,
|
|
&xattributes
|
|
);
|
|
|
|
XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
|
|
|
|
}
|
|
|
|
#ifdef WITH_XDND
|
|
/* initialize drop target for newly created window */
|
|
m_dropTarget = new GHOST_DropTargetX11(this, m_system);
|
|
GHOST_PRINT("Set drop target\n");
|
|
#endif
|
|
|
|
/*
|
|
* One of the problem with WM-spec is that can't set a property
|
|
* to a window that isn't mapped. That is why we can't "just
|
|
* call setState" here.
|
|
*
|
|
* To fix this, we first need know that the window is really
|
|
* map waiting for the MapNotify event.
|
|
*
|
|
* So, m_post_init indicate that we need wait for the MapNotify
|
|
* event and then set the Window state to the m_post_state.
|
|
*/
|
|
if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
|
|
m_post_init = True;
|
|
m_post_state = state;
|
|
}
|
|
else {
|
|
m_post_init = False;
|
|
m_post_state = GHOST_kWindowStateNormal;
|
|
}
|
|
|
|
// Create some hints for the window manager on how
|
|
// we want this window treated.
|
|
|
|
XSizeHints *xsizehints = XAllocSizeHints();
|
|
xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
|
|
xsizehints->x = left;
|
|
xsizehints->y = top;
|
|
xsizehints->width = width;
|
|
xsizehints->height = height;
|
|
xsizehints->min_width = 320; // size hints, could be made apart of the ghost api
|
|
xsizehints->min_height = 240; // limits are also arbitrary, but should not allow 1x1 window
|
|
xsizehints->max_width = 65535;
|
|
xsizehints->max_height = 65535;
|
|
XSetWMNormalHints(m_display, m_window, xsizehints);
|
|
XFree(xsizehints);
|
|
|
|
XClassHint *xclasshint = XAllocClassHint();
|
|
const int len = title.Length() + 1;
|
|
char *wmclass = (char *)malloc(sizeof(char) * len);
|
|
strncpy(wmclass, (const char *)title, sizeof(char) * len);
|
|
xclasshint->res_name = wmclass;
|
|
xclasshint->res_class = wmclass;
|
|
XSetClassHint(m_display, m_window, xclasshint);
|
|
free(wmclass);
|
|
XFree(xclasshint);
|
|
|
|
/* The basic for a good ICCCM "work" */
|
|
if (m_system->m_wm_protocols) {
|
|
natom = 0;
|
|
|
|
if (m_system->m_delete_window_atom) {
|
|
atoms[natom] = m_system->m_delete_window_atom;
|
|
natom++;
|
|
}
|
|
|
|
if (m_system->m_wm_take_focus) {
|
|
atoms[natom] = m_system->m_wm_take_focus;
|
|
natom++;
|
|
}
|
|
|
|
if (natom) {
|
|
/* printf("Register atoms: %d\n", natom); */
|
|
XSetWMProtocols(m_display, m_window, atoms, natom);
|
|
}
|
|
}
|
|
|
|
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
|
|
m_xic = XCreateIC(m_system->getX11_XIM(), XNClientWindow, m_window, XNFocusWindow, m_window,
|
|
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
|
XNResourceName, GHOST_X11_RES_NAME, XNResourceClass,
|
|
GHOST_X11_RES_CLASS, NULL);
|
|
#endif
|
|
|
|
// Set the window icon
|
|
XWMHints *xwmhints = XAllocWMHints();
|
|
XImage *x_image, *mask_image;
|
|
Pixmap icon_pixmap, mask_pixmap;
|
|
icon_pixmap = XCreatePixmap(display, m_window, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 24);
|
|
mask_pixmap = XCreatePixmap(display, m_window, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 1);
|
|
GC gc_icon = XCreateGC(display, icon_pixmap, 0, NULL);
|
|
GC gc_mask = XCreateGC(display, mask_pixmap, 0, NULL);
|
|
|
|
x_image = XCreateImage(display, m_visual->visual, 24, ZPixmap, 0, NULL, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 32, 0);
|
|
mask_image = XCreateImage(display, m_visual->visual, 1, ZPixmap, 0, NULL, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 8, 0);
|
|
|
|
x_image->data = (char *)malloc(x_image->bytes_per_line * BLENDER_ICON_HEIGHT);
|
|
mask_image->data = (char *)malloc(mask_image->bytes_per_line * BLENDER_ICON_HEIGHT);
|
|
|
|
/* copy the BLENDER_ICON_48x48x24 into the XImage */
|
|
unsigned char *col = BLENDER_ICON_48x48x24;
|
|
int px, py;
|
|
for (px = 0; px < BLENDER_ICON_WIDTH; px++) {
|
|
for (py = 0; py < BLENDER_ICON_HEIGHT; py++, col += 3) {
|
|
/* mask out pink */
|
|
if (col[0] == 255 && col[1] == 0 && col[2] == 255) {
|
|
XPutPixel(mask_image, px, py, 0);
|
|
}
|
|
else {
|
|
XPutPixel(x_image, px, py, (col[0] << 16) + (col[1] << 8) + col[2]);
|
|
XPutPixel(mask_image, px, py, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
XPutImage(display, icon_pixmap, gc_icon, x_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
|
|
XPutImage(display, mask_pixmap, gc_mask, mask_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
|
|
|
|
// Now the pixmap is ok to assign to the window as a hint
|
|
xwmhints->icon_pixmap = icon_pixmap;
|
|
xwmhints->icon_mask = mask_pixmap;
|
|
XFreeGC(display, gc_icon);
|
|
XFreeGC(display, gc_mask);
|
|
XDestroyImage(x_image); /* frees x_image->data too */
|
|
XDestroyImage(mask_image);
|
|
|
|
xwmhints->initial_state = NormalState;
|
|
xwmhints->input = True;
|
|
xwmhints->flags = InputHint | IconPixmapHint | IconMaskHint | StateHint;
|
|
XSetWMHints(display, m_window, xwmhints);
|
|
XFree(xwmhints);
|
|
// done setting the icon
|
|
|
|
setTitle(title);
|
|
|
|
#ifdef WITH_X11_XINPUT
|
|
initXInputDevices();
|
|
#endif
|
|
|
|
// now set up the rendering context.
|
|
if (installDrawingContext(type) == GHOST_kSuccess) {
|
|
m_valid_setup = true;
|
|
GHOST_PRINT("Created window\n");
|
|
}
|
|
|
|
XMapWindow(m_display, m_window);
|
|
GHOST_PRINT("Mapped window\n");
|
|
|
|
XFlush(m_display);
|
|
}
|
|
|
|
#ifdef WITH_X11_XINPUT
|
|
/*
|
|
* Dummy function to get around IO Handler exiting if device invalid
|
|
* Basically it will not crash blender now if you have a X device that
|
|
* is configured but not plugged in.
|
|
*/
|
|
static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
|
|
{
|
|
fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
|
|
theEvent->error_code, theEvent->request_code);
|
|
|
|
/* No exit! - but keep lint happy */
|
|
return 0;
|
|
}
|
|
|
|
/* These C functions are copied from Wine 1.1.13's wintab.c */
|
|
#define BOOL int
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
|
|
static bool match_token(const char *haystack, const char *needle)
|
|
{
|
|
const char *p, *q;
|
|
for (p = haystack; *p; )
|
|
{
|
|
while (*p && isspace(*p))
|
|
p++;
|
|
if (!*p)
|
|
break;
|
|
|
|
for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
|
|
p++;
|
|
if (!*q && (isspace(*p) || !*p))
|
|
return TRUE;
|
|
|
|
while (*p && !isspace(*p))
|
|
p++;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* Determining if an X device is a Tablet style device is an imperfect science.
|
|
* We rely on common conventions around device names as well as the type reported
|
|
* by Wacom tablets. This code will likely need to be expanded for alternate tablet types
|
|
*
|
|
* Wintab refers to any device that interacts with the tablet as a cursor,
|
|
* (stylus, eraser, tablet mouse, airbrush, etc)
|
|
* this is not to be confused with wacom x11 configuration "cursor" device.
|
|
* Wacoms x11 config "cursor" refers to its device slot (which we mirror with
|
|
* our gSysCursors) for puck like devices (tablet mice essentially).
|
|
*/
|
|
#if 0 // unused
|
|
static BOOL is_tablet_cursor(const char *name, const char *type)
|
|
{
|
|
int i;
|
|
static const char *tablet_cursor_whitelist[] = {
|
|
"wacom",
|
|
"wizardpen",
|
|
"acecad",
|
|
"tablet",
|
|
"cursor",
|
|
"stylus",
|
|
"eraser",
|
|
"pad",
|
|
NULL
|
|
};
|
|
|
|
for (i = 0; tablet_cursor_whitelist[i] != NULL; i++) {
|
|
if (name && match_token(name, tablet_cursor_whitelist[i]))
|
|
return TRUE;
|
|
if (type && match_token(type, tablet_cursor_whitelist[i]))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
static BOOL is_stylus(const char *name, const char *type)
|
|
{
|
|
int i;
|
|
static const char *tablet_stylus_whitelist[] = {
|
|
"stylus",
|
|
"wizardpen",
|
|
"acecad",
|
|
NULL
|
|
};
|
|
|
|
for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
|
|
if (name && match_token(name, tablet_stylus_whitelist[i]))
|
|
return TRUE;
|
|
if (type && match_token(type, tablet_stylus_whitelist[i]))
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static BOOL is_eraser(const char *name, const char *type)
|
|
{
|
|
if (name && match_token(name, "eraser"))
|
|
return TRUE;
|
|
if (type && match_token(type, "eraser"))
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
#undef BOOL
|
|
#undef TRUE
|
|
#undef FALSE
|
|
/* end code copied from wine */
|
|
|
|
void GHOST_WindowX11::initXInputDevices()
|
|
{
|
|
static XErrorHandler old_handler = (XErrorHandler) 0;
|
|
XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
|
|
|
|
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
|
|
if (version->present) {
|
|
int device_count;
|
|
XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
|
|
m_xtablet.StylusDevice = NULL;
|
|
m_xtablet.EraserDevice = NULL;
|
|
m_xtablet.CommonData.Active = GHOST_kTabletModeNone;
|
|
|
|
/* Install our error handler to override Xlib's termination behavior */
|
|
old_handler = XSetErrorHandler(ApplicationErrorHandler);
|
|
|
|
for (int i = 0; i < device_count; ++i) {
|
|
char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
|
|
|
|
// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
|
|
|
|
|
|
if (m_xtablet.StylusDevice == NULL && is_stylus(device_info[i].name, device_type)) {
|
|
// printf("\tfound stylus\n");
|
|
m_xtablet.StylusID = device_info[i].id;
|
|
m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
|
|
|
|
if (m_xtablet.StylusDevice != NULL) {
|
|
/* Find how many pressure levels tablet has */
|
|
XAnyClassPtr ici = device_info[i].inputclassinfo;
|
|
for (int j = 0; j < m_xtablet.StylusDevice->num_classes; ++j) {
|
|
if (ici->c_class == ValuatorClass) {
|
|
// printf("\t\tfound ValuatorClass\n");
|
|
XValuatorInfo *xvi = (XValuatorInfo *)ici;
|
|
m_xtablet.PressureLevels = xvi->axes[2].max_value;
|
|
|
|
/* this is assuming that the tablet has the same tilt resolution in both
|
|
* positive and negative directions. It would be rather weird if it didn't.. */
|
|
m_xtablet.XtiltLevels = xvi->axes[3].max_value;
|
|
m_xtablet.YtiltLevels = xvi->axes[4].max_value;
|
|
break;
|
|
}
|
|
|
|
ici = (XAnyClassPtr)(((char *)ici) + ici->length);
|
|
}
|
|
}
|
|
else {
|
|
m_xtablet.StylusID = 0;
|
|
}
|
|
}
|
|
else if (m_xtablet.EraserDevice == NULL && is_eraser(device_info[i].name, device_type)) {
|
|
// printf("\tfound eraser\n");
|
|
m_xtablet.EraserID = device_info[i].id;
|
|
m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
|
|
if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID = 0;
|
|
}
|
|
|
|
if (device_type) {
|
|
XFree((void *)device_type);
|
|
}
|
|
}
|
|
|
|
/* Restore handler */
|
|
(void) XSetErrorHandler(old_handler);
|
|
|
|
XFreeDeviceList(device_info);
|
|
|
|
|
|
XEventClass xevents[10], ev;
|
|
int dcount = 0;
|
|
|
|
if (m_xtablet.StylusDevice) {
|
|
DeviceMotionNotify(m_xtablet.StylusDevice, m_xtablet.MotionEvent, ev);
|
|
if (ev) xevents[dcount++] = ev;
|
|
ProximityIn(m_xtablet.StylusDevice, m_xtablet.ProxInEvent, ev);
|
|
if (ev) xevents[dcount++] = ev;
|
|
ProximityOut(m_xtablet.StylusDevice, m_xtablet.ProxOutEvent, ev);
|
|
if (ev) xevents[dcount++] = ev;
|
|
}
|
|
if (m_xtablet.EraserDevice) {
|
|
DeviceMotionNotify(m_xtablet.EraserDevice, m_xtablet.MotionEvent, ev);
|
|
if (ev) xevents[dcount++] = ev;
|
|
ProximityIn(m_xtablet.EraserDevice, m_xtablet.ProxInEvent, ev);
|
|
if (ev) xevents[dcount++] = ev;
|
|
ProximityOut(m_xtablet.EraserDevice, m_xtablet.ProxOutEvent, ev);
|
|
if (ev) xevents[dcount++] = ev;
|
|
}
|
|
|
|
XSelectExtensionEvent(m_display, m_window, xevents, dcount);
|
|
}
|
|
XFree(version);
|
|
}
|
|
}
|
|
|
|
#endif /* WITH_X11_XINPUT */
|
|
|
|
Window
|
|
GHOST_WindowX11::
|
|
getXWindow()
|
|
{
|
|
return m_window;
|
|
}
|
|
|
|
bool
|
|
GHOST_WindowX11::
|
|
getValid() const
|
|
{
|
|
return m_valid_setup;
|
|
}
|
|
|
|
void
|
|
GHOST_WindowX11::
|
|
setTitle(
|
|
const STR_String& title)
|
|
{
|
|
Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
|
|
Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
|
|
XChangeProperty(m_display, m_window,
|
|
name, utf8str, 8, PropModeReplace,
|
|
(const unsigned char *) title.ReadPtr(),
|
|
title.Length());
|
|
|
|
// This should convert to valid x11 string
|
|
// and getTitle would need matching change
|
|
XStoreName(m_display, m_window, title);
|
|
|
|
XFlush(m_display);
|
|
}
|
|
|
|
void
|
|
GHOST_WindowX11::
|
|
getTitle(
|
|
STR_String& title) const
|
|
{
|
|
char *name = NULL;
|
|
|
|
XFetchName(m_display, m_window, &name);
|
|
title = name ? name : "untitled";
|
|
XFree(name);
|
|
}
|
|
|
|
void
|
|
GHOST_WindowX11::
|
|
getWindowBounds(
|
|
GHOST_Rect& bounds) const
|
|
{
|
|
// Getting the window bounds under X11 is not
|
|
// really supported (nor should it be desired).
|
|
getClientBounds(bounds);
|
|
}
|
|
|
|
void
|
|
GHOST_WindowX11::
|
|
getClientBounds(
|
|
GHOST_Rect& bounds) const
|
|
{
|
|
Window root_return;
|
|
int x_return, y_return;
|
|
unsigned int w_return, h_return, border_w_return, depth_return;
|
|
GHOST_TInt32 screen_x, screen_y;
|
|
|
|
XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
|
|
&w_return, &h_return, &border_w_return, &depth_return);
|
|
|
|
clientToScreen(0, 0, screen_x, screen_y);
|
|
|
|
bounds.m_l = screen_x;
|
|
bounds.m_r = bounds.m_l + w_return;
|
|
bounds.m_t = screen_y;
|
|
bounds.m_b = bounds.m_t + h_return;
|
|
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setClientWidth(
|
|
GHOST_TUns32 width)
|
|
{
|
|
XWindowChanges values;
|
|
unsigned int value_mask = CWWidth;
|
|
values.width = width;
|
|
XConfigureWindow(m_display, m_window, value_mask, &values);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setClientHeight(
|
|
GHOST_TUns32 height)
|
|
{
|
|
XWindowChanges values;
|
|
unsigned int value_mask = CWHeight;
|
|
values.height = height;
|
|
XConfigureWindow(m_display, m_window, value_mask, &values);
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setClientSize(
|
|
GHOST_TUns32 width,
|
|
GHOST_TUns32 height)
|
|
{
|
|
XWindowChanges values;
|
|
unsigned int value_mask = CWWidth | CWHeight;
|
|
values.width = width;
|
|
values.height = height;
|
|
XConfigureWindow(m_display, m_window, value_mask, &values);
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
void
|
|
GHOST_WindowX11::
|
|
screenToClient(
|
|
GHOST_TInt32 inX,
|
|
GHOST_TInt32 inY,
|
|
GHOST_TInt32& outX,
|
|
GHOST_TInt32& outY) const
|
|
{
|
|
// This is correct!
|
|
|
|
int ax, ay;
|
|
Window temp;
|
|
|
|
XTranslateCoordinates(m_display,
|
|
RootWindow(m_display, m_visual->screen),
|
|
m_window,
|
|
inX, inY,
|
|
&ax, &ay,
|
|
&temp);
|
|
outX = ax;
|
|
outY = ay;
|
|
}
|
|
|
|
void
|
|
GHOST_WindowX11::
|
|
clientToScreen(
|
|
GHOST_TInt32 inX,
|
|
GHOST_TInt32 inY,
|
|
GHOST_TInt32& outX,
|
|
GHOST_TInt32& outY) const
|
|
{
|
|
int ax, ay;
|
|
Window temp;
|
|
|
|
XTranslateCoordinates(
|
|
m_display,
|
|
m_window,
|
|
RootWindow(m_display, m_visual->screen),
|
|
inX, inY,
|
|
&ax, &ay,
|
|
&temp);
|
|
outX = ax;
|
|
outY = ay;
|
|
}
|
|
|
|
void GHOST_WindowX11::icccmSetState(int state)
|
|
{
|
|
XEvent xev;
|
|
|
|
if (state != IconicState)
|
|
return;
|
|
|
|
xev.xclient.type = ClientMessage;
|
|
xev.xclient.serial = 0;
|
|
xev.xclient.send_event = True;
|
|
xev.xclient.display = m_display;
|
|
xev.xclient.window = m_window;
|
|
xev.xclient.format = 32;
|
|
xev.xclient.message_type = m_system->m_wm_change_state;
|
|
xev.xclient.data.l[0] = state;
|
|
XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
|
|
False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
|
|
}
|
|
|
|
int GHOST_WindowX11::icccmGetState(void) const
|
|
{
|
|
unsigned char *prop_ret;
|
|
unsigned long bytes_after, num_ret;
|
|
Atom type_ret;
|
|
int format_ret, st;
|
|
|
|
prop_ret = NULL;
|
|
st = XGetWindowProperty(m_display, m_window, m_system->m_wm_state, 0,
|
|
0x7fffffff, False, m_system->m_wm_state, &type_ret,
|
|
&format_ret, &num_ret, &bytes_after, &prop_ret);
|
|
|
|
if ((st == Success) && (prop_ret) && (num_ret == 2))
|
|
st = prop_ret[0];
|
|
else
|
|
st = NormalState;
|
|
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
return (st);
|
|
}
|
|
|
|
void GHOST_WindowX11::netwmMaximized(bool set)
|
|
{
|
|
XEvent xev;
|
|
|
|
xev.xclient.type = ClientMessage;
|
|
xev.xclient.serial = 0;
|
|
xev.xclient.send_event = True;
|
|
xev.xclient.window = m_window;
|
|
xev.xclient.message_type = m_system->m_net_state;
|
|
xev.xclient.format = 32;
|
|
|
|
if (set == True)
|
|
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
|
|
else
|
|
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
|
|
|
|
xev.xclient.data.l[1] = m_system->m_net_max_horz;
|
|
xev.xclient.data.l[2] = m_system->m_net_max_vert;
|
|
xev.xclient.data.l[3] = 0;
|
|
xev.xclient.data.l[4] = 0;
|
|
XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
|
|
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
|
}
|
|
|
|
bool GHOST_WindowX11::netwmIsMaximized(void) const
|
|
{
|
|
unsigned char *prop_ret;
|
|
unsigned long bytes_after, num_ret, i;
|
|
Atom type_ret;
|
|
bool st;
|
|
int format_ret, ret, count;
|
|
|
|
prop_ret = NULL;
|
|
st = False;
|
|
ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
|
|
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
|
|
&num_ret, &bytes_after, &prop_ret);
|
|
if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
|
|
count = 0;
|
|
for (i = 0; i < num_ret; i++) {
|
|
if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_horz)
|
|
count++;
|
|
if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_vert)
|
|
count++;
|
|
if (count == 2) {
|
|
st = True;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
return (st);
|
|
}
|
|
|
|
void GHOST_WindowX11::netwmFullScreen(bool set)
|
|
{
|
|
XEvent xev;
|
|
|
|
xev.xclient.type = ClientMessage;
|
|
xev.xclient.serial = 0;
|
|
xev.xclient.send_event = True;
|
|
xev.xclient.window = m_window;
|
|
xev.xclient.message_type = m_system->m_net_state;
|
|
xev.xclient.format = 32;
|
|
|
|
if (set == True)
|
|
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
|
|
else
|
|
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
|
|
|
|
xev.xclient.data.l[1] = m_system->m_net_fullscreen;
|
|
xev.xclient.data.l[2] = 0;
|
|
xev.xclient.data.l[3] = 0;
|
|
xev.xclient.data.l[4] = 0;
|
|
XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
|
|
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
|
}
|
|
|
|
bool GHOST_WindowX11::netwmIsFullScreen(void) const
|
|
{
|
|
unsigned char *prop_ret;
|
|
unsigned long bytes_after, num_ret, i;
|
|
Atom type_ret;
|
|
bool st;
|
|
int format_ret, ret;
|
|
|
|
prop_ret = NULL;
|
|
st = False;
|
|
ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
|
|
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
|
|
&num_ret, &bytes_after, &prop_ret);
|
|
if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
|
|
for (i = 0; i < num_ret; i++) {
|
|
if (((unsigned long *) prop_ret)[i] == m_system->m_net_fullscreen) {
|
|
st = True;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
return (st);
|
|
}
|
|
|
|
void GHOST_WindowX11::motifFullScreen(bool set)
|
|
{
|
|
MotifWmHints hints;
|
|
|
|
hints.flags = MWM_HINTS_DECORATIONS;
|
|
if (set == True)
|
|
hints.decorations = 0;
|
|
else
|
|
hints.decorations = 1;
|
|
|
|
XChangeProperty(m_display, m_window, m_system->m_motif,
|
|
m_system->m_motif, 32, PropModeReplace,
|
|
(unsigned char *) &hints, 4);
|
|
}
|
|
|
|
bool GHOST_WindowX11::motifIsFullScreen(void) const
|
|
{
|
|
unsigned char *prop_ret;
|
|
unsigned long bytes_after, num_ret;
|
|
MotifWmHints *hints;
|
|
Atom type_ret;
|
|
bool state;
|
|
int format_ret, st;
|
|
|
|
prop_ret = NULL;
|
|
state = False;
|
|
st = XGetWindowProperty(m_display, m_window, m_system->m_motif, 0,
|
|
0x7fffffff, False, m_system->m_motif,
|
|
&type_ret, &format_ret, &num_ret,
|
|
&bytes_after, &prop_ret);
|
|
if ((st == Success) && (prop_ret)) {
|
|
hints = (MotifWmHints *) prop_ret;
|
|
if (hints->flags & MWM_HINTS_DECORATIONS) {
|
|
if (!hints->decorations)
|
|
state = True;
|
|
}
|
|
}
|
|
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
return (state);
|
|
}
|
|
|
|
GHOST_TWindowState GHOST_WindowX11::getState() const
|
|
{
|
|
GHOST_TWindowState state_ret;
|
|
int state;
|
|
|
|
state_ret = GHOST_kWindowStateNormal;
|
|
state = icccmGetState();
|
|
/*
|
|
* In the Iconic and Withdrawn state, the window
|
|
* is unmaped, so only need return a Minimized state.
|
|
*/
|
|
if ((state == IconicState) || (state == WithdrawnState))
|
|
state_ret = GHOST_kWindowStateMinimized;
|
|
else if (netwmIsMaximized() == True)
|
|
state_ret = GHOST_kWindowStateMaximized;
|
|
else if (netwmIsFullScreen() == True)
|
|
state_ret = GHOST_kWindowStateFullScreen;
|
|
else if (motifIsFullScreen() == True)
|
|
state_ret = GHOST_kWindowStateFullScreen;
|
|
return (state_ret);
|
|
}
|
|
|
|
GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
|
|
{
|
|
GHOST_TWindowState cur_state;
|
|
bool is_max, is_full, is_motif_full;
|
|
|
|
cur_state = getState();
|
|
if (state == (int)cur_state)
|
|
return GHOST_kSuccess;
|
|
|
|
if (cur_state != GHOST_kWindowStateMinimized) {
|
|
/*
|
|
* The window don't have this property's
|
|
* if it's not mapped.
|
|
*/
|
|
is_max = netwmIsMaximized();
|
|
is_full = netwmIsFullScreen();
|
|
}
|
|
else {
|
|
is_max = False;
|
|
is_full = False;
|
|
}
|
|
|
|
is_motif_full = motifIsFullScreen();
|
|
|
|
if (state == GHOST_kWindowStateNormal)
|
|
state = m_normal_state;
|
|
|
|
if (state == GHOST_kWindowStateNormal) {
|
|
if (is_max == True)
|
|
netwmMaximized(False);
|
|
if (is_full == True)
|
|
netwmFullScreen(False);
|
|
if (is_motif_full == True)
|
|
motifFullScreen(False);
|
|
icccmSetState(NormalState);
|
|
return (GHOST_kSuccess);
|
|
}
|
|
|
|
if (state == GHOST_kWindowStateFullScreen) {
|
|
/*
|
|
* We can't change to full screen if the window
|
|
* isn't mapped.
|
|
*/
|
|
if (cur_state == GHOST_kWindowStateMinimized)
|
|
return (GHOST_kFailure);
|
|
|
|
m_normal_state = cur_state;
|
|
|
|
if (is_max == True)
|
|
netwmMaximized(False);
|
|
if (is_full == False)
|
|
netwmFullScreen(True);
|
|
if (is_motif_full == False)
|
|
motifFullScreen(True);
|
|
return (GHOST_kSuccess);
|
|
}
|
|
|
|
if (state == GHOST_kWindowStateMaximized) {
|
|
/*
|
|
* We can't change to Maximized if the window
|
|
* isn't mapped.
|
|
*/
|
|
if (cur_state == GHOST_kWindowStateMinimized)
|
|
return (GHOST_kFailure);
|
|
|
|
if (is_full == True)
|
|
netwmFullScreen(False);
|
|
if (is_motif_full == True)
|
|
motifFullScreen(False);
|
|
if (is_max == False)
|
|
netwmMaximized(True);
|
|
return (GHOST_kSuccess);
|
|
}
|
|
|
|
if (state == GHOST_kWindowStateMinimized) {
|
|
/*
|
|
* The window manager need save the current state of
|
|
* the window (maximized, full screen, etc).
|
|
*/
|
|
icccmSetState(IconicState);
|
|
return (GHOST_kSuccess);
|
|
}
|
|
|
|
return (GHOST_kFailure);
|
|
}
|
|
|
|
#include <iostream>
|
|
using namespace std;
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setOrder(
|
|
GHOST_TWindowOrder order)
|
|
{
|
|
if (order == GHOST_kWindowOrderTop) {
|
|
XWindowAttributes attr;
|
|
Atom atom;
|
|
|
|
/* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some
|
|
window managers ignore the former (e.g. kwin from kde) and others
|
|
don't implement the latter (e.g. fluxbox pre 0.9.9) */
|
|
|
|
XRaiseWindow(m_display, m_window);
|
|
|
|
atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True);
|
|
|
|
if (atom != None) {
|
|
Window root;
|
|
XEvent xev;
|
|
long eventmask;
|
|
|
|
xev.xclient.type = ClientMessage;
|
|
xev.xclient.serial = 0;
|
|
xev.xclient.send_event = True;
|
|
xev.xclient.window = m_window;
|
|
xev.xclient.message_type = atom;
|
|
|
|
xev.xclient.format = 32;
|
|
xev.xclient.data.l[0] = 1;
|
|
xev.xclient.data.l[1] = CurrentTime;
|
|
xev.xclient.data.l[2] = m_window;
|
|
xev.xclient.data.l[3] = 0;
|
|
xev.xclient.data.l[4] = 0;
|
|
|
|
root = RootWindow(m_display, m_visual->screen),
|
|
eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
|
|
|
|
XSendEvent(m_display, root, False, eventmask, &xev);
|
|
}
|
|
|
|
XGetWindowAttributes(m_display, m_window, &attr);
|
|
|
|
/* iconized windows give bad match error */
|
|
if (attr.map_state == IsViewable)
|
|
XSetInputFocus(m_display, m_window, RevertToPointerRoot,
|
|
CurrentTime);
|
|
XFlush(m_display);
|
|
}
|
|
else if (order == GHOST_kWindowOrderBottom) {
|
|
XLowerWindow(m_display, m_window);
|
|
XFlush(m_display);
|
|
}
|
|
else {
|
|
return GHOST_kFailure;
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
swapBuffers()
|
|
{
|
|
if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
|
|
glXSwapBuffers(m_display, m_window);
|
|
return GHOST_kSuccess;
|
|
}
|
|
else {
|
|
return GHOST_kFailure;
|
|
}
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
activateDrawingContext()
|
|
{
|
|
if (m_context != NULL) {
|
|
glXMakeCurrent(m_display, m_window, m_context);
|
|
return GHOST_kSuccess;
|
|
}
|
|
return GHOST_kFailure;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
invalidate()
|
|
{
|
|
// So the idea of this function is to generate an expose event
|
|
// for the window.
|
|
// Unfortunately X does not handle expose events for you and
|
|
// it is the client's job to refresh the dirty part of the window.
|
|
// We need to queue up invalidate calls and generate GHOST events
|
|
// for them in the system.
|
|
|
|
// We implement this by setting a boolean in this class to concatenate
|
|
// all such calls into a single event for this window.
|
|
|
|
// At the same time we queue the dirty windows in the system class
|
|
// and generate events for them at the next processEvents call.
|
|
|
|
if (m_invalid_window == false) {
|
|
m_system->addDirtyWindow(this);
|
|
m_invalid_window = true;
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
/**
|
|
* called by the X11 system implementation when expose events
|
|
* for the window have been pushed onto the GHOST queue
|
|
*/
|
|
|
|
void
|
|
GHOST_WindowX11::
|
|
validate()
|
|
{
|
|
m_invalid_window = false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Destructor.
|
|
* Closes the window and disposes resources allocated.
|
|
*/
|
|
|
|
GHOST_WindowX11::
|
|
~GHOST_WindowX11(
|
|
){
|
|
static Atom Primary_atom, Clipboard_atom;
|
|
Window p_owner, c_owner;
|
|
/*Change the owner of the Atoms to None if we are the owner*/
|
|
Primary_atom = XInternAtom(m_display, "PRIMARY", False);
|
|
Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
|
|
|
|
p_owner = XGetSelectionOwner(m_display, Primary_atom);
|
|
c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
|
|
|
|
std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
|
|
for (; it != m_standard_cursors.end(); it++) {
|
|
XFreeCursor(m_display, it->second);
|
|
}
|
|
|
|
if (m_empty_cursor) {
|
|
XFreeCursor(m_display, m_empty_cursor);
|
|
}
|
|
if (m_custom_cursor) {
|
|
XFreeCursor(m_display, m_custom_cursor);
|
|
}
|
|
|
|
#ifdef WITH_X11_XINPUT
|
|
/* close tablet devices */
|
|
if (m_xtablet.StylusDevice)
|
|
XCloseDevice(m_display, m_xtablet.StylusDevice);
|
|
|
|
if (m_xtablet.EraserDevice)
|
|
XCloseDevice(m_display, m_xtablet.EraserDevice);
|
|
#endif /* WITH_X11_XINPUT */
|
|
|
|
if (m_context != s_firstContext) {
|
|
glXDestroyContext(m_display, m_context);
|
|
}
|
|
|
|
if (p_owner == m_window) {
|
|
XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
|
|
}
|
|
if (c_owner == m_window) {
|
|
XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
|
|
}
|
|
|
|
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
|
|
if (m_xic) {
|
|
XDestroyIC(m_xic);
|
|
}
|
|
#endif
|
|
|
|
#ifdef WITH_XDND
|
|
delete m_dropTarget;
|
|
#endif
|
|
|
|
XDestroyWindow(m_display, m_window);
|
|
XFree(m_visual);
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Tries to install a rendering context in this window.
|
|
* @param type The type of rendering context installed.
|
|
* @return Indication as to whether installation has succeeded.
|
|
*/
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
installDrawingContext(
|
|
GHOST_TDrawingContextType type)
|
|
{
|
|
// only support openGL for now.
|
|
GHOST_TSuccess success;
|
|
switch (type) {
|
|
case GHOST_kDrawingContextTypeOpenGL:
|
|
m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
|
|
if (m_context != NULL) {
|
|
if (!s_firstContext) {
|
|
s_firstContext = m_context;
|
|
}
|
|
glXMakeCurrent(m_display, m_window, m_context);
|
|
glClearColor(0.447, 0.447, 0.447, 0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
success = GHOST_kSuccess;
|
|
}
|
|
else {
|
|
success = GHOST_kFailure;
|
|
}
|
|
|
|
break;
|
|
|
|
case GHOST_kDrawingContextTypeNone:
|
|
success = GHOST_kSuccess;
|
|
break;
|
|
|
|
default:
|
|
success = GHOST_kFailure;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Removes the current drawing context.
|
|
* @return Indication as to whether removal has succeeded.
|
|
*/
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
removeDrawingContext()
|
|
{
|
|
GHOST_TSuccess success;
|
|
|
|
if (m_context != NULL) {
|
|
glXDestroyContext(m_display, m_context);
|
|
success = GHOST_kSuccess;
|
|
}
|
|
else {
|
|
success = GHOST_kFailure;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
|
|
Cursor
|
|
GHOST_WindowX11::
|
|
getStandardCursor(
|
|
GHOST_TStandardCursor g_cursor)
|
|
{
|
|
unsigned int xcursor_id;
|
|
|
|
#define GtoX(gcurs, xcurs) case gcurs: xcursor_id = xcurs
|
|
switch (g_cursor) {
|
|
GtoX(GHOST_kStandardCursorRightArrow, XC_arrow); break;
|
|
GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow); break;
|
|
GtoX(GHOST_kStandardCursorInfo, XC_hand1); break;
|
|
GtoX(GHOST_kStandardCursorDestroy, XC_pirate); break;
|
|
GtoX(GHOST_kStandardCursorHelp, XC_question_arrow); break;
|
|
GtoX(GHOST_kStandardCursorCycle, XC_exchange); break;
|
|
GtoX(GHOST_kStandardCursorSpray, XC_spraycan); break;
|
|
GtoX(GHOST_kStandardCursorWait, XC_watch); break;
|
|
GtoX(GHOST_kStandardCursorText, XC_xterm); break;
|
|
GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair); break;
|
|
GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow); break;
|
|
GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow); break;
|
|
GtoX(GHOST_kStandardCursorTopSide, XC_top_side); break;
|
|
GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side); break;
|
|
GtoX(GHOST_kStandardCursorLeftSide, XC_left_side); break;
|
|
GtoX(GHOST_kStandardCursorRightSide, XC_right_side); break;
|
|
GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner); break;
|
|
GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner); break;
|
|
GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner); break;
|
|
GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner); break;
|
|
GtoX(GHOST_kStandardCursorPencil, XC_pencil); break;
|
|
GtoX(GHOST_kStandardCursorCopy, XC_arrow); break;
|
|
default:
|
|
xcursor_id = 0;
|
|
}
|
|
#undef GtoX
|
|
|
|
if (xcursor_id) {
|
|
Cursor xcursor = m_standard_cursors[xcursor_id];
|
|
|
|
if (!xcursor) {
|
|
xcursor = XCreateFontCursor(m_display, xcursor_id);
|
|
|
|
m_standard_cursors[xcursor_id] = xcursor;
|
|
}
|
|
|
|
return xcursor;
|
|
}
|
|
else {
|
|
return None;
|
|
}
|
|
}
|
|
|
|
Cursor
|
|
GHOST_WindowX11::
|
|
getEmptyCursor(
|
|
) {
|
|
if (!m_empty_cursor) {
|
|
Pixmap blank;
|
|
XColor dummy;
|
|
char data[1] = {0};
|
|
|
|
/* make a blank cursor */
|
|
blank = XCreateBitmapFromData(
|
|
m_display,
|
|
RootWindow(m_display, DefaultScreen(m_display)),
|
|
data, 1, 1
|
|
);
|
|
|
|
m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0);
|
|
XFreePixmap(m_display, blank);
|
|
}
|
|
|
|
return m_empty_cursor;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setWindowCursorVisibility(
|
|
bool visible)
|
|
{
|
|
Cursor xcursor;
|
|
|
|
if (visible) {
|
|
xcursor = getStandardCursor(getCursorShape() );
|
|
}
|
|
else {
|
|
xcursor = getEmptyCursor();
|
|
}
|
|
|
|
XDefineCursor(m_display, m_window, xcursor);
|
|
XFlush(m_display);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setWindowCursorGrab(
|
|
GHOST_TGrabCursorMode mode)
|
|
{
|
|
if (mode != GHOST_kGrabDisable) {
|
|
if (mode != GHOST_kGrabNormal) {
|
|
m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
|
|
setCursorGrabAccum(0, 0);
|
|
|
|
if (mode == GHOST_kGrabHide)
|
|
setWindowCursorVisibility(false);
|
|
|
|
}
|
|
#ifdef GHOST_X11_GRAB
|
|
XGrabPointer(m_display, m_window, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
|
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
#endif
|
|
}
|
|
else {
|
|
if (m_cursorGrab == GHOST_kGrabHide) {
|
|
m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
|
|
setWindowCursorVisibility(true);
|
|
}
|
|
|
|
if (m_cursorGrab != GHOST_kGrabNormal) {
|
|
/* use to generate a mouse move event, otherwise the last event
|
|
* blender gets can be outside the screen causing menus not to show
|
|
* properly unless the user moves the mouse */
|
|
XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0);
|
|
}
|
|
|
|
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
|
|
setCursorGrabAccum(0, 0);
|
|
m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
|
|
#ifdef GHOST_X11_GRAB
|
|
XUngrabPointer(m_display, CurrentTime);
|
|
#endif
|
|
}
|
|
|
|
XFlush(m_display);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setWindowCursorShape(
|
|
GHOST_TStandardCursor shape)
|
|
{
|
|
Cursor xcursor = getStandardCursor(shape);
|
|
|
|
XDefineCursor(m_display, m_window, xcursor);
|
|
XFlush(m_display);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setWindowCustomCursorShape(
|
|
GHOST_TUns8 bitmap[16][2],
|
|
GHOST_TUns8 mask[16][2],
|
|
int hotX,
|
|
int hotY)
|
|
{
|
|
setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask,
|
|
16, 16, hotX, hotY, 0, 1);
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess
|
|
GHOST_WindowX11::
|
|
setWindowCustomCursorShape(
|
|
GHOST_TUns8 *bitmap,
|
|
GHOST_TUns8 *mask,
|
|
int sizex,
|
|
int sizey,
|
|
int hotX,
|
|
int hotY,
|
|
int fg_color,
|
|
int bg_color)
|
|
{
|
|
Colormap colormap = DefaultColormap(m_display, DefaultScreen(m_display));
|
|
Pixmap bitmap_pix, mask_pix;
|
|
XColor fg, bg;
|
|
|
|
if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure;
|
|
if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure;
|
|
|
|
if (m_custom_cursor) {
|
|
XFreeCursor(m_display, m_custom_cursor);
|
|
}
|
|
|
|
bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *) bitmap, sizex, sizey);
|
|
mask_pix = XCreateBitmapFromData(m_display, m_window, (char *) mask, sizex, sizey);
|
|
|
|
m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
|
|
XDefineCursor(m_display, m_window, m_custom_cursor);
|
|
XFlush(m_display);
|
|
|
|
XFreePixmap(m_display, bitmap_pix);
|
|
XFreePixmap(m_display, mask_pix);
|
|
|
|
XFreeColors(m_display, colormap, &fg.pixel, 1, 0L);
|
|
XFreeColors(m_display, colormap, &bg.pixel, 1, 0L);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|