diff options
Diffstat (limited to 'client/x11')
30 files changed, 0 insertions, 10287 deletions
diff --git a/client/x11/.gitignore b/client/x11/.gitignore deleted file mode 100644 index 2f08d7eb..00000000 --- a/client/x11/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.la -*.lo -*.loT -*.o -.deps -.dirstamp -.libs -Makefile -Makefile.in -setup -spicec diff --git a/client/x11/atomic_count.h b/client/x11/atomic_count.h deleted file mode 100644 index 02bb08d4..00000000 --- a/client/x11/atomic_count.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_ATOMIC_COUNT -#define _H_ATOMIC_COUNT - -#include <stdint.h> - -class AtomicCount { -public: - AtomicCount(uint32_t count = 0) : _count (count) {} - - uint32_t operator ++ () - { - return __sync_add_and_fetch(&_count, 1); - } - - uint32_t operator -- () - { - return __sync_sub_and_fetch(&_count, 1); - } - - operator uint32_t () { return _count;} - -private: - uint32_t _count; -}; - -#endif diff --git a/client/x11/event_sources_p.cpp b/client/x11/event_sources_p.cpp deleted file mode 100644 index 5f9f4523..00000000 --- a/client/x11/event_sources_p.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/select.h> -#include <sys/fcntl.h> - -#include "event_sources.h" -#include "debug.h" -#include "utils.h" - -static void set_non_blocking(int fd) -{ - int flags; - if ((flags = ::fcntl(fd, F_GETFL)) == -1) { - THROW("failed to set socket non block: %s", strerror(errno)); - } - - if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { - THROW("failed to set socket non block: %s", strerror(errno)); - } -} - -static void set_blocking(int fd) -{ - int flags; - if ((flags = ::fcntl(fd, F_GETFL)) == -1) { - THROW("failed to clear socket non block: %s", strerror(errno)); - } - - if (::fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1) { - THROW("failed to clear socket non block: %s", strerror(errno)); - } -} - -EventSources::EventSources() -{ -} - -EventSources::~EventSources() -{ -} - -void EventSources_p::add_event(int fd, EventSource* source) -{ - int size = _events.size(); - _events.resize(size + 1); - _fds.resize(size + 1); - _events[size] = source; - _fds[size] = fd; -} - -void EventSources_p::remove_event(EventSource* source) -{ - int size = _events.size(); - for (int i = 0; i < size; i++) { - if (_events[i] == source) { - for (i++; i < size; i++) { - _events[i - 1] = _events[i]; - _fds[i - 1] = _fds[i]; - } - _events.resize(size - 1); - _fds.resize(size - 1); - return; - } - } - THROW("event not found"); -} - -bool EventSources::wait_events(int timeout_msec) -{ - int maxfd = 0; - fd_set rfds; - struct timeval tv; - struct timeval *tvp; - int ready; - - FD_ZERO(&rfds); - - int size = _events.size(); - for (int i = 0; i < size; i++) { - maxfd = MAX(maxfd, _fds[i]); - FD_SET(_fds[i], &rfds); - } - - if (timeout_msec == INFINITE) { - tvp = NULL; - } else { - tv.tv_sec = timeout_msec / 1000; - tv.tv_usec = (timeout_msec % 1000) * 1000; - tvp = &tv; - } - - /* Right now we only use read polling in spice */ - ready = ::select(maxfd+1, &rfds, NULL, NULL, tvp); - - if (ready == -1) { - if (errno == EINTR) { - return false; - } - THROW("wait error select failed"); - } else if (ready == 0) { - return false; - } - - for (unsigned int i = 0; i < _events.size(); i++) { - if (FD_ISSET(_fds[i], &rfds)) { - _events[i]->action(); - /* The action may have removed / added event sources changing - our array, so leave the loop and handle other events the next - time we are called */ - return false; - } - } - return false; -} - -void EventSources::add_trigger(Trigger& trigger) -{ - add_event(trigger.get_fd(), &trigger); -} - -void EventSources::remove_trigger(Trigger& trigger) -{ - remove_event(&trigger); -} - -EventSources::Trigger::Trigger() -{ - int fd[2]; - if (::pipe(fd) == -1) { - THROW("create pipe failed"); - } - _event_fd = fd[0]; - _event_write_fd = fd[1]; - set_non_blocking(_event_fd); -} - -EventSources::Trigger::~Trigger() -{ - close(_event_fd); - close(_event_write_fd); -} - -void EventSources::Trigger::trigger() -{ - Lock lock(_lock); - if (_pending_int) { - return; - } - _pending_int = true; - const uint8_t val = 1; - if (::write(_event_write_fd, &val, sizeof(val)) != sizeof(val)) { - THROW("write event failed"); - } -} - -bool Trigger_p::reset_event() -{ - Lock lock(_lock); - if (!_pending_int) { - return false; - } - uint8_t val; - if (::read(_event_fd, &val, sizeof(val)) != sizeof(val)) { - THROW("event read error"); - } - _pending_int = false; - return true; -} - -void EventSources::Trigger::reset() -{ - reset_event(); -} - -void EventSources::Trigger::action() -{ - if (reset_event()) { - on_event(); - } -} - -void EventSources::add_socket(Socket& socket) -{ - add_event(socket.get_socket(), &socket); - set_non_blocking(socket.get_socket()); -} - -void EventSources::remove_socket(Socket& socket) -{ - remove_event(&socket); - int fd = socket.get_socket(); - set_blocking(fd); -} - -void EventSources::add_file(File& file) -{ - add_event(file.get_fd(), &file); -} - -void EventSources::remove_file(File& file) -{ - remove_event(&file); -} - -void EventSources::add_handle(Handle& file) -{ -} - -void EventSources::remove_handle(Handle& file) -{ -} diff --git a/client/x11/event_sources_p.h b/client/x11/event_sources_p.h deleted file mode 100644 index 4b826bb8..00000000 --- a/client/x11/event_sources_p.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_EVENT_SOURCES_P -#define _H_EVENT_SOURCES_P - -#include "common.h" -#include "threads.h" - -#define INFINITE -1 - -class EventSource; - -class EventSources_p { -protected: - void add_event(int fd, EventSource* source); - void remove_event(EventSource* source); - -public: - std::vector<EventSource*> _events; - std::vector<int> _fds; -}; - -class Trigger_p { -public: - Trigger_p() : _pending_int (false) {} - int get_fd() { return _event_fd;} - bool reset_event(); - -public: - int _event_fd; - int _event_write_fd; - bool _pending_int; - Mutex _lock; -}; - -class Handle_p { -}; - -#endif diff --git a/client/x11/images/alt_image.c b/client/x11/images/alt_image.c deleted file mode 100644 index cf5d6cb8..00000000 --- a/client/x11/images/alt_image.c +++ /dev/null @@ -1,735 +0,0 @@ -static const struct { - int width; - int height; - uint8_t pixel_data[17496]; -} _alt_image = { 81, 54, { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x16,0x16,0x16,0x2d,0x39,0x39,0x39,0x70,0x48,0x48,0x48,0x8e,0x58,0x58,0x58,0xae,0x68,0x68,0x68,0xcd, - 0x78,0x78,0x78,0xec,0x82,0x82,0x82,0xff,0x81,0x81,0x81,0xfe,0x80,0x80,0x80,0xfd,0x80,0x80,0x80,0xfc,0x7f,0x7f,0x7f,0xfb, - 0x7f,0x7f,0x7f,0xfa,0x7e,0x7e,0x7e,0xf9,0x7e,0x7e,0x7e,0xf8,0x7e,0x7e,0x7e,0xf8,0x7d,0x7d,0x7d,0xf7,0x7d,0x7d,0x7d,0xf6, - 0x7c,0x7c,0x7c,0xf5,0x7c,0x7c,0x7c,0xf4,0x7b,0x7b,0x7b,0xf3,0x7b,0x7b,0x7b,0xf2,0x7a,0x7a,0x7a,0xf1,0x7a,0x7a,0x7a,0xf0, - 0x79,0x79,0x79,0xef,0x79,0x79,0x79,0xee,0x78,0x78,0x78,0xed,0x78,0x78,0x78,0xec,0x77,0x77,0x77,0xeb,0x77,0x77,0x77,0xea, - 0x76,0x76,0x76,0xe9,0x76,0x76,0x76,0xe8,0x75,0x75,0x75,0xe7,0x75,0x75,0x75,0xe6,0x74,0x74,0x74,0xe5,0x74,0x74,0x74,0xe4, - 0x74,0x74,0x74,0xe4,0x73,0x73,0x73,0xe3,0x73,0x73,0x73,0xe2,0x72,0x72,0x72,0xe1,0x72,0x72,0x72,0xe0,0x71,0x71,0x71,0xdf, - 0x71,0x71,0x71,0xde,0x70,0x70,0x70,0xdd,0x70,0x70,0x70,0xdc,0x6f,0x6f,0x6f,0xdb,0x6f,0x6f,0x6f,0xda,0x6e,0x6e,0x6e,0xd9, - 0x6e,0x6e,0x6e,0xd8,0x6d,0x6d,0x6d,0xd7,0x6d,0x6d,0x6d,0xd6,0x6c,0x6c,0x6c,0xd5,0x6c,0x6c,0x6c,0xd4,0x6b,0x6b,0x6b,0xd3, - 0x6b,0x6b,0x6b,0xd2,0x6a,0x6a,0x6a,0xd1,0x6a,0x6a,0x6a,0xd1,0x69,0x69,0x69,0xcf,0x61,0x61,0x61,0xc0,0x60,0x60,0x60,0xca, - 0x64,0x64,0x64,0xe2,0x5b,0x5b,0x5b,0xd3,0x52,0x52,0x52,0xc2,0x47,0x47,0x47,0xad,0x33,0x33,0x33,0x87,0x19,0x19,0x19,0x55, - 0x0b,0x0b,0x0b,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x11,0x11,0x23,0x53,0x53,0x53,0xa4,0x80,0x80,0x80,0xfd,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x79,0x79,0x79,0xff,0x64,0x64,0x64,0xff,0x3f,0x3f,0x3f,0xc4,0x1c,0x1c,0x1c,0x5d, - 0x02,0x02,0x02,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x0a,0x0a,0x15,0x4c,0x4c,0x4c,0x96,0x7f,0x7f,0x7f,0xfa, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x81,0x81,0x81,0xff,0x70,0x70,0x70,0xff,0x4d,0x4d,0x4d,0xf1,0x2c,0x2c,0x2c,0x95,0x03,0x03,0x03,0x0a, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02, - 0x62,0x62,0x62,0xc2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x7b,0x7b,0x7b,0xff,0x54,0x54,0x54,0xff,0x3b,0x3b,0x3b,0xc5,0x04,0x04,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x3e,0x3e,0x7b,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x83,0x7f,0x80,0xee,0x88,0x7d,0x7e,0xce,0x88,0x7c,0x7c,0xc2,0x8a,0x7a,0x7c,0xb7, - 0x8c,0x7a,0x7b,0xac,0x8d,0x79,0x7a,0xa5,0x8c,0x79,0x7a,0xa5,0x8d,0x79,0x7b,0xa6,0x8c,0x79,0x7b,0xa6,0x8c,0x79,0x7b,0xa6, - 0x8c,0x79,0x7b,0xa7,0x8c,0x79,0x7b,0xa7,0x8c,0x79,0x7a,0xa7,0x8c,0x79,0x7a,0xa7,0x8c,0x79,0x7b,0xa8,0x8c,0x79,0x7b,0xa8, - 0x8d,0x79,0x7b,0xa9,0x8c,0x79,0x7b,0xa9,0x8c,0x79,0x7b,0xa9,0x8c,0x7a,0x7b,0xaa,0x8c,0x79,0x7b,0xaa,0x8c,0x79,0x7b,0xaa, - 0x8c,0x7a,0x7b,0xab,0x8c,0x79,0x7b,0xab,0x8c,0x79,0x7b,0xab,0x8c,0x7a,0x7b,0xac,0x8c,0x79,0x7b,0xac,0x8b,0x79,0x7b,0xac, - 0x8c,0x7a,0x7b,0xad,0x8b,0x79,0x7b,0xad,0x8b,0x79,0x7b,0xad,0x8b,0x7a,0x7b,0xae,0x8b,0x79,0x7b,0xae,0x8c,0x7a,0x7c,0xaf, - 0x8c,0x7a,0x7b,0xaf,0x8c,0x7a,0x7b,0xaf,0x8b,0x7a,0x7b,0xaf,0x8c,0x7a,0x7c,0xb0,0x8b,0x7a,0x7b,0xb0,0x8b,0x7a,0x7b,0xb0, - 0x8c,0x7a,0x7c,0xb1,0x8b,0x7a,0x7b,0xb1,0x8b,0x7a,0x7b,0xb1,0x8b,0x7a,0x7c,0xb2,0x8b,0x7a,0x7c,0xb2,0x8a,0x7a,0x7b,0xb2, - 0x8b,0x7a,0x7c,0xb3,0x8a,0x7a,0x7c,0xb3,0x8a,0x7a,0x7b,0xb3,0x8b,0x7a,0x7c,0xb4,0x8b,0x7a,0x7c,0xb4,0x8b,0x7a,0x7c,0xb5, - 0x8b,0x7a,0x7c,0xb5,0x8b,0x7a,0x7c,0xb5,0x8b,0x7a,0x7c,0xb6,0x8a,0x7a,0x7c,0xb6,0x8a,0x7b,0x7c,0xbc,0x8c,0x7e,0x80,0xcc, - 0x8d,0x80,0x82,0xd8,0x8c,0x82,0x83,0xe0,0x8c,0x83,0x84,0xe7,0x89,0x83,0x84,0xf1,0x82,0x82,0x82,0xfe,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x7b,0x7b,0x7b,0xff,0x4f,0x4f,0x4f,0xff, - 0x3a,0x3a,0x3a,0xc3,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0x1b,0x1b,0x36,0x7f,0x7f,0x7f,0xfb, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x83,0x80,0x80,0xf3,0x89,0x7c,0x7d,0xc5,0x8c,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8c,0x79,0x7b,0xac,0x87,0x7d,0x7e,0xcd,0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x69,0x69,0x69,0xff,0x4d,0x4d,0x4d,0xff,0x1c,0x1c,0x1c,0x5f,0x00,0x00,0x00,0x00, - 0x02,0x02,0x02,0x04,0x6f,0x6f,0x6f,0xdb,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x83,0x81,0x81,0xf7, - 0x8c,0x7a,0x7b,0xad,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8c,0x79,0x7b,0xa7,0x86,0x7f,0x7f,0xe1,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x81,0x81,0x81,0xff, - 0x50,0x50,0x50,0xff,0x44,0x44,0x44,0xe4,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x81,0x81,0x81,0xfe,0x89,0x7b,0x7c,0xbc,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8c,0x79,0x7b,0xa9,0x83,0x81,0x81,0xf6, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x5c,0x5c,0x5c,0xff,0x4d,0x4d,0x4d,0xff,0x0b,0x0b,0x0b,0x26, - 0x33,0x33,0x33,0x65,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x85,0x7f,0x7f,0xe2,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x86,0x7e,0x7f,0xda,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x68,0x68,0x68,0xff,0x4d,0x4d,0x4d,0xff,0x1d,0x1d,0x1d,0x61,0x4f,0x4f,0x4f,0x9b,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x87,0x7d,0x7e,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x7a,0x69,0x6b,0xb0,0x4c,0x40,0x42,0xcf,0x4c,0x40,0x42,0xcf,0x4c,0x40,0x42,0xcf, - 0x4c,0x40,0x42,0xcf,0x4c,0x40,0x42,0xcf,0x4c,0x40,0x42,0xcf,0x82,0x6f,0x71,0xac,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x88,0x7b,0x7d,0xc4, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x75,0x75,0x75,0xff,0x4d,0x4d,0x4d,0xff,0x2f,0x2f,0x2f,0x9d, - 0x6a,0x6a,0x6a,0xd0,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8a,0x7b,0x7d,0xbc,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x75,0x64,0x67,0xb4,0x6f,0x5f,0x60,0xb8,0x6f,0x5f,0x60,0xb8,0x6f,0x5f,0x60,0xb8, - 0x6f,0x5f,0x60,0xb8,0x6f,0x5f,0x60,0xb8,0x6f,0x5f,0x60,0xb8,0x6f,0x5f,0x60,0xb8,0x7c,0x6a,0x6c,0xb0,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x95,0x92,0x95,0xf4,0x95,0x92,0x95,0xf4,0x95,0x92,0x95,0xf4,0x95,0x92,0x95,0xf4,0x95,0x92,0x95,0xf4, - 0xb2,0xab,0xad,0xe1,0x9f,0x90,0x92,0xbd,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8c,0x7a,0x7b,0xaf,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x80,0x80,0x80,0xff,0x4e,0x4e,0x4e,0xff,0x41,0x41,0x41,0xd9,0x7f,0x7f,0x7f,0xfb,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8c,0x7a,0x7b,0xaa,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x89,0x75,0x77,0xa7,0x32,0x2a,0x2b,0xdf, - 0x51,0x4c,0x4e,0xe8,0x6b,0x68,0x69,0xed,0x6b,0x68,0x69,0xed,0x6b,0x68,0x69,0xed,0x6b,0x68,0x69,0xed,0x6b,0x68,0x69,0xed, - 0x6b,0x68,0x69,0xed,0x78,0x73,0x74,0xe4,0xa3,0x96,0x98,0xc3,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x80,0x6e,0x70,0xac,0x80,0x6e,0x70,0xac, - 0x80,0x6e,0x70,0xac,0x80,0x6e,0x70,0xac,0x80,0x6e,0x70,0xac,0x80,0x6e,0x70,0xac,0x87,0x74,0x76,0xa8,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x80,0xf5,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x53,0x53,0x53,0xff,0x4d,0x4d,0x4d,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x6f,0x60,0x61,0xb7,0x2e,0x27,0x28,0xe1,0x87,0x83,0x86,0xf2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb7,0xb1,0xb3,0xe3, - 0x93,0x80,0x82,0xac,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x4d,0x48,0x48,0xe7,0x57,0x53,0x54,0xe9,0x57,0x53,0x54,0xe9,0x57,0x53,0x54,0xe9, - 0x57,0x53,0x54,0xe9,0x81,0x76,0x78,0xcf,0x99,0x88,0x8a,0xb5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x80,0xf1,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4d,0x4d,0x4d,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x53,0x48,0x48,0xca,0x3b,0x35,0x36,0xe4, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xae,0xa9,0xab,0xe9,0xa0,0x91,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x80,0xf1,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4d,0x4d,0x4d,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8c,0x78,0x7a,0xa5,0x37,0x2f,0x30,0xdc,0x5d,0x58,0x59,0xea,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa4,0xa1,0xa4,0xef, - 0xae,0xa4,0xa6,0xd1,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x80,0xf1,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4d,0x4d,0x4d,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x78,0x67,0x69,0xb2,0x2e,0x27,0x28,0xe1,0x7e,0x7a,0x7d,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x9a,0x9b,0xf4,0xb9,0xb2,0xb4,0xe1,0x8e,0x7b,0x7e,0xa8,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4d,0x4d,0x4d,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x5b,0x4e,0x4f,0xc4,0x33,0x2d,0x2e,0xe2,0x98,0x96,0x98,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb0,0xab,0xad,0xe7,0x9b,0x8c,0x8e,0xb9,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfe,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x3e,0x35,0x36,0xd7,0x52,0x4e,0x4f,0xe8,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa7,0xa3,0xa6,0xee,0xaa,0x9f,0xa0,0xcc,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfe, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x80,0x6d,0x6f,0xad, - 0x2e,0x27,0x28,0xe1,0x75,0x71,0x72,0xee,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9f,0x9d,0x9f,0xf3,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9e,0x9b,0x9d,0xf3,0xb6,0xaf,0xb2,0xdd,0x8d,0x79,0x7b,0xa6,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x89,0x75,0x77,0xa7,0x7a,0x69,0x6b,0xb0,0x7a,0x69,0x6b,0xb0, - 0x7a,0x68,0x6a,0xb1,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xaa,0xa5,0xa8,0xec,0xa2,0x98,0x9b,0xd5,0x7a,0x69,0x6b,0xb0,0x7a,0x69,0x6b,0xb0,0x7a,0x69,0x6b,0xb0, - 0x7a,0x69,0x6b,0xb0,0x7a,0x69,0x6b,0xb0,0x8b,0x78,0x7a,0xa6,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfe,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x63,0x55,0x56,0xbf,0x2f,0x29,0x29,0xe2,0x94,0x91,0x94,0xf4,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xaf,0xab,0xac,0xe8,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb3,0xae,0xaf,0xe6,0x98,0x87,0x8a,0xb4, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x7a,0x68,0x6a,0xb1,0x2e,0x27,0x28,0xe1,0x5b,0x56,0x56,0xe9,0x5e,0x59,0x59,0xea,0x5e,0x59,0x59,0xea,0x8d,0x8a,0x8c,0xf3, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x88,0x84,0x87,0xf2, - 0x5e,0x59,0x59,0xea,0x5e,0x59,0x59,0xea,0x5e,0x59,0x59,0xea,0x5e,0x59,0x59,0xea,0x5e,0x59,0x59,0xea,0x9c,0x8f,0x90,0xc3, - 0x94,0x82,0x83,0xae,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfe, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x46,0x3c,0x3d,0xd2, - 0x4a,0x45,0x45,0xe6,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa2,0x9e,0xa1,0xf1, - 0xba,0xb3,0xb6,0xe2,0x4f,0x4a,0x4a,0xe4,0x93,0x90,0x92,0xf4,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xaa,0xa5,0xa8,0xec,0xa7,0x9a,0x9c,0xc7,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x7a,0x68,0x6a,0xb1,0x2e,0x27,0x28,0xe1,0x95,0x92,0x95,0xf4, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb8,0xb2,0xb4,0xe3,0x9c,0x8d,0x8e,0xb9,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfd,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x87,0x73,0x75,0xa9,0x30,0x29,0x2a,0xe0,0x6a,0x67,0x69,0xed,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xeb,0xb8,0xb0,0xb4,0xdf,0x4d,0x42,0x43,0xd0,0x75,0x71,0x72,0xee, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa0,0x9d,0x9f,0xf2,0xb4,0xab,0xae,0xd9, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x7a,0x68,0x6a,0xb1,0x2e,0x27,0x28,0xe1,0x95,0x92,0x95,0xf4,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb8,0xb2,0xb4,0xe3, - 0x9c,0x8d,0x8e,0xb9,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfd, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x6b,0x5c,0x5e,0xba,0x2e,0x27,0x28,0xe1, - 0x8d,0x8a,0x8c,0xf3,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb4,0xae,0xb0,0xe6, - 0xac,0xa2,0xa3,0xcf,0x66,0x57,0x59,0xbe,0x55,0x51,0x52,0xe9,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb5,0xb0,0xb2,0xe4,0x93,0x82,0x84,0xaf,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x7a,0x68,0x6a,0xb1,0x2e,0x27,0x28,0xe1,0x95,0x92,0x95,0xf4, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb8,0xb2,0xb4,0xe3,0x9c,0x8d,0x8e,0xb9,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x81,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfd,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x4e,0x43,0x44,0xcd,0x40,0x3a,0x3c,0xe5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9d,0x9b,0x9d,0xf4,0xba,0xb4,0xb6,0xe1,0x9e,0x8f,0x93,0xbd,0x80,0x6e,0x70,0xad,0x38,0x31,0x31,0xe3, - 0x9a,0x97,0x9a,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xac,0xa7,0xaa,0xea, - 0xa2,0x95,0x98,0xc2,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x7a,0x68,0x6a,0xb1,0x2e,0x27,0x28,0xe1,0x95,0x92,0x95,0xf4,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb8,0xb2,0xb4,0xe3, - 0x9c,0x8d,0x8e,0xb9,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x82,0x80,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfd, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x77,0x79,0xa6,0x33,0x2c,0x2c,0xde,0x61,0x5d,0x5f,0xeb, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa6,0xa2,0xa4,0xee,0xba,0xb4,0xb6,0xe1, - 0x92,0x7f,0x81,0xac,0x8d,0x79,0x7a,0xa5,0x3c,0x33,0x34,0xd9,0x85,0x82,0x84,0xf1,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa2,0xa0,0xa1,0xf0,0xb0,0xa7,0xa9,0xd4,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x86,0x73,0x74,0xaa,0x66,0x57,0x59,0xbe,0xa9,0xa3,0xa6,0xe7, - 0xad,0xa9,0xaa,0xe9,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xa6,0xa2,0xa4,0xee,0xad,0xa9,0xaa,0xe9,0xad,0xa9,0xaa,0xe9,0xad,0xa9,0xaa,0xe9,0xad,0xa9,0xaa,0xe9, - 0xad,0xa9,0xaa,0xe9,0xad,0xa9,0xaa,0xe9,0xb9,0xb3,0xb5,0xe2,0x9c,0x8d,0x8e,0xb9,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x82,0x80,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfc,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x73,0x63,0x64,0xb5,0x2e,0x27,0x28,0xe1,0x83,0x7f,0x82,0xf1,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xae,0xaa,0xac,0xe8,0xb2,0xa9,0xac,0xd8,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x57,0x4a,0x4b,0xc7, - 0x66,0x62,0x64,0xec,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9c,0x99,0x9c,0xf5, - 0xb8,0xb2,0xb4,0xe2,0x91,0x7e,0x80,0xaa,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x93,0x80,0x83,0xae,0x92,0x81,0x83,0xaf,0x3f,0x39,0x3a,0xe5,0x84,0x81,0x83,0xf1, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xae,0xa4,0xa6,0xd1, - 0x94,0x82,0x84,0xaf,0x94,0x82,0x84,0xaf,0x94,0x82,0x84,0xaf,0x94,0x82,0x84,0xaf,0x94,0x82,0x84,0xaf,0x94,0x82,0x84,0xaf, - 0x8e,0x7b,0x7d,0xa8,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x82,0x80,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfc, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x56,0x49,0x4b,0xc8,0x38,0x32,0x32,0xe3,0x9a,0x97,0x9a,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb7,0xb1,0xb3,0xe3,0xa7,0x9a,0x9b,0xc7, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x72,0x62,0x63,0xb6,0x48,0x42,0x44,0xe6,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xae,0xaa,0xac,0xe8,0x9e,0x8f,0x91,0xbc,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x82,0x80,0x81,0xf2,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfc,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x3a,0x31,0x32,0xda,0x59,0x54,0x55,0xe9,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xa1,0x9e,0xa0,0xf1,0xba,0xb4,0xb6,0xe1,0x99,0x88,0x8a,0xb5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x89,0x75,0x77,0xa7, - 0x32,0x2b,0x2c,0xe0,0x95,0x92,0x95,0xf4,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xa6,0xa2,0xa4,0xee,0xac,0xa1,0xa4,0xcf,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x81,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4c,0x4c,0x4c,0xfc, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x7a,0x69,0x6b,0xb0,0x2e,0x27,0x28,0xe1,0x7a,0x77,0x78,0xef,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xec,0xb8,0xb1,0xb4,0xdf,0x8e,0x7b,0x7c,0xa7, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x48,0x3e,0x3f,0xd0,0x78,0x75,0x76,0xef,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9c,0x9b,0x9c,0xf4,0xb8,0xb1,0xb4,0xe0,0x8e,0x7b,0x7d,0xa7, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x81,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfb,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x5e,0x51,0x52,0xc3, - 0x32,0x2c,0x2c,0xe2,0x97,0x95,0x97,0xf4,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb3,0xae,0xaf,0xe6,0xac,0xa2,0xa4,0xcf,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x63,0x55,0x56,0xbf,0x58,0x53,0x54,0xe9,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xb2,0xad,0xaf,0xe7,0x9a,0x89,0x8c,0xb7,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x81,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfb, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x41,0x38,0x39,0xd5,0x4f,0x4a,0x4c,0xe7,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9d,0x9b,0x9d,0xf4,0xba,0xb3,0xb6,0xe2,0x9f,0x91,0x93,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x7e,0x6c,0x6e,0xaf,0x39,0x33,0x34,0xe3,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa8,0xa4,0xa6,0xed,0xa8,0x9c,0x9f,0xca, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x81,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfb,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x70,0x72,0xab,0x2e,0x28,0x28,0xe1, - 0x71,0x6d,0x6e,0xed,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9c,0x9b,0x9c,0xf4, - 0xa3,0xa0,0xa2,0xf0,0x54,0x4b,0x4c,0xd4,0x48,0x3e,0x3f,0xd0,0x48,0x3e,0x3f,0xd0,0x48,0x3e,0x3f,0xd0,0x48,0x3e,0x3f,0xd0, - 0x48,0x3e,0x3f,0xd0,0x2e,0x28,0x28,0xe1,0x88,0x85,0x86,0xf2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9f,0x9c,0x9e,0xf3,0xb6,0xae,0xb0,0xdc,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfb, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x67,0x58,0x59,0xbd,0x2f,0x28,0x29,0xe1,0x90,0x8d,0x90,0xf3,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x97,0x95,0x97,0xf5,0x97,0x95,0x97,0xf5, - 0x97,0x95,0x97,0xf5,0x97,0x95,0x97,0xf5,0x97,0x95,0x97,0xf5,0x97,0x95,0x97,0xf5,0x97,0x95,0x97,0xf5,0x9a,0x97,0x9a,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb4,0xae,0xb0,0xe5, - 0x96,0x85,0x88,0xb2,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfa,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x49,0x3e,0x40,0xd0,0x47,0x40,0x42,0xe6, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xeb,0xa5,0x98,0x99,0xc5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8b,0x78,0x7a,0xa6,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfa, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x88,0x75,0x77,0xa7,0x31,0x2a,0x2b,0xe0,0x67,0x63,0x64,0xec,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa1,0x9e,0xa0,0xf1, - 0xb3,0xaa,0xac,0xd7,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8c,0x78,0x7a,0xa5,0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xad,0xa8,0xaa,0xea,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfa,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x6e,0x5e,0x5f,0xb8,0x2e,0x27,0x28,0xe1,0x89,0x86,0x88,0xf2, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe3,0x93,0x80,0x82,0xad,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x34,0x2d,0x2d,0xdd,0x7f,0x7c,0x7d,0xf0, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa7,0xa3,0xa5,0xed,0xad,0xa3,0xa5,0xd0, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfa, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x51,0x46,0x47,0xcb,0x3c,0x37,0x37,0xe4,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xad,0xa9,0xaa,0xe9,0xa1,0x92,0x94,0xbf,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x3d,0x35,0x35,0xd7,0x74,0x70,0x73,0xee,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9f,0x9c,0x9f,0xf2,0xb6,0xaf,0xb1,0xdd,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xfa,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8c,0x78,0x7a,0xa5,0x35,0x2d,0x2e,0xdd,0x5e,0x59,0x5b,0xea,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9e,0x9b,0x9d,0xf3,0xb0,0xab,0xad,0xe8,0xb0,0xab,0xad,0xe8, - 0xb0,0xab,0xad,0xe8,0xb0,0xab,0xad,0xe8,0xb0,0xab,0xad,0xe8,0xb0,0xab,0xad,0xe8,0xb0,0xab,0xad,0xe8,0xb0,0xab,0xad,0xe8, - 0xb0,0xab,0xad,0xe8,0xb0,0xab,0xad,0xe8,0xaf,0xa9,0xac,0xe9,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa4,0xa0,0xa3,0xef,0xb0,0xa5,0xa8,0xd2,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x48,0x3d,0x3e,0xd1,0x6a,0x65,0x67,0xec, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa1,0x9e,0xa0,0xf1, - 0x6d,0x61,0x64,0xce,0x6b,0x5c,0x5e,0xba,0x6c,0x5d,0x5e,0xba,0x6c,0x5d,0x5e,0xba,0x7c,0x6a,0x6d,0xb0,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xf9, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x76,0x65,0x67,0xb3, - 0x2e,0x27,0x28,0xe1,0x80,0x7d,0x7f,0xf0,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xa6,0xa2,0xa5,0xee,0xba,0xb4,0xb6,0xe1,0x93,0x81,0x83,0xae,0x8f,0x7c,0x7e,0xa9,0x8f,0x7c,0x7e,0xa9,0x8f,0x7c,0x7e,0xa9, - 0x8f,0x7c,0x7e,0xa9,0x8f,0x7c,0x7e,0xa9,0x8f,0x7c,0x7e,0xa9,0x8f,0x7c,0x7e,0xa9,0x8f,0x7c,0x7e,0xa9,0x8f,0x7c,0x7e,0xa9, - 0x42,0x3a,0x3a,0xda,0x85,0x82,0x85,0xf2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9c,0x99,0x9c,0xf5,0xb8,0xb1,0xb4,0xe1,0x8f,0x7c,0x7e,0xa9,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x53,0x47,0x48,0xca,0x5e,0x59,0x5c,0xea,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x8b,0x88,0x8a,0xf2,0x71,0x6e,0x70,0xee, - 0x6f,0x6b,0x6b,0xed,0x8b,0x84,0x84,0xdc,0xa2,0x94,0x96,0xc1,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x80,0x80,0xf3,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xf9,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x5a,0x4c,0x4e,0xc6,0x35,0x2f,0x2f,0xe3,0x99,0x97,0x99,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xae,0xaa,0xac,0xe8,0xb1,0xa9,0xac,0xd7,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x57,0x4a,0x4b,0xc7,0x66,0x62,0x64,0xec,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb0,0xab,0xad,0xe8,0x9d,0x8e,0x91,0xbb, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x75,0x64,0x66,0xb4,0x4d,0x48,0x4a,0xe7, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xec,0xb0,0xa7,0xa9,0xd4, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x81,0x81,0xf4,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xf9, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x3c,0x34,0x35,0xd8, - 0x55,0x50,0x51,0xe8,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb8,0xb2,0xb4,0xe3,0xa4,0x98,0x9a,0xc5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x72,0x62,0x63,0xb6,0x47,0x41,0x43,0xe6,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xa6,0xa2,0xa5,0xee,0xac,0xa0,0xa3,0xcd,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x41,0x38,0x39,0xd6,0x8d,0x8b,0x8d,0xf3,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xec,0xb0,0xa7,0xa9,0xd4,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x81,0x81,0xf4,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4b,0x4b,0x4b,0xf9,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x7e,0x6c,0x6e,0xae,0x2e,0x27,0x28,0xe1,0x76,0x72,0x75,0xee,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xa2,0x9e,0xa1,0xf1,0xba,0xb4,0xb6,0xe1,0x98,0x87,0x8a,0xb4,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8a,0x76,0x78,0xa7,0x32,0x2b,0x2b,0xe0,0x94,0x91,0x94,0xf4, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9d,0x9b,0x9d,0xf4,0xb8,0xb0,0xb2,0xde, - 0x8e,0x7a,0x7c,0xa6,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6,0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x77,0x66,0x68,0xb3, - 0x64,0x5e,0x60,0xe5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xec,0xb0,0xa7,0xa9,0xd4, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x83,0x81,0x81,0xf4,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x54,0x54,0x54,0xff,0x4a,0x4a,0x4a,0xf8, - 0x7e,0x7e,0x7e,0xf9,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8c,0x7a,0x7b,0xaa,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x62,0x54,0x55,0xc1,0x30,0x2a,0x2b,0xe2, - 0x96,0x93,0x95,0xf4,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xeb, - 0xb8,0xb0,0xb3,0xde,0x8e,0x7a,0x7c,0xa6,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x49,0x3e,0x40,0xd0,0x76,0x73,0x75,0xef,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0xb2,0xad,0xaf,0xe6,0x99,0x88,0x8a,0xb5,0x8d,0x79,0x7a,0xa5,0x73,0x63,0x64,0xb6, - 0x2e,0x28,0x28,0xe2,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0xb6,0xb0,0xb2,0xe5,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x87,0x74,0x76,0xaa,0x7f,0x77,0x7b,0xdc,0x9e,0x9b,0x9d,0xf3, - 0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5,0x9b,0x98,0x9b,0xf5, - 0x9b,0x98,0x9b,0xf5,0xaa,0xa6,0xa8,0xec,0xb0,0xa7,0xa9,0xd4,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x83,0x81,0x81,0xf6,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x53,0x53,0x53,0xff,0x4a,0x4a,0x4a,0xf8,0x66,0x66,0x66,0xc9,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x89,0x7b,0x7c,0xbb,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x7e,0x6c,0x6e,0xaf,0x85,0x78,0x7a,0xc2,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6, - 0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb8,0xb2,0xb4,0xe3,0xac,0xa1,0xa3,0xce,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x80,0x6d,0x6f,0xad,0x8d,0x80,0x82,0xc7, - 0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb6,0xb0,0xb2,0xe3, - 0xa6,0x99,0x9d,0xc8,0x8d,0x79,0x7a,0xa5,0x87,0x73,0x75,0xa9,0x75,0x64,0x66,0xb5,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6, - 0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb9,0xb3,0xb5,0xe2,0xa0,0x92,0x94,0xbe,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x97,0x86,0x88,0xb2,0xa6,0x9a,0x9d,0xcb,0xa6,0x9d,0xa1,0xd7,0xac,0xa5,0xa7,0xe1, - 0xb1,0xac,0xae,0xe6,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb2,0xad,0xaf,0xe6,0xb6,0xb1,0xb2,0xe4,0xb0,0xa7,0xa9,0xd4, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8c,0x79,0x7b,0xa9, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x81,0x81,0x81,0xff,0x4e,0x4e,0x4e,0xff,0x4a,0x4a,0x4a,0xf8, - 0x4b,0x4b,0x4b,0x94,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x8a,0x7f,0x80,0xd8,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8a,0x7a,0x7c,0xb7,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x79,0x79,0x79,0xff,0x4d,0x4d,0x4d,0xff,0x4a,0x4a,0x4a,0xf8,0x48,0x48,0x48,0xae,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x83,0x82,0x82,0xfb,0x8c,0x79,0x7b,0xab,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x86,0x7f,0x7f,0xde, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x71,0x71,0x71,0xff,0x4d,0x4d,0x4d,0xff,0x46,0x46,0x46,0xe8, - 0x25,0x25,0x25,0x6a,0x80,0x80,0x80,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x84,0x7f,0x7f,0xe7, - 0x8b,0x7a,0x7b,0xb0,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5,0x8d,0x79,0x7a,0xa5, - 0x8b,0x7a,0x7b,0xaf,0x85,0x7e,0x7f,0xdb,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x68,0x68,0x68,0xff,0x4d,0x4d,0x4d,0xff,0x39,0x39,0x39,0xc0,0x0a,0x0a,0x0a,0x23,0x66,0x66,0x66,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x81,0x80,0x81,0xfb,0x85,0x7f,0x80,0xe5,0x86,0x7d,0x7e,0xd7, - 0x88,0x7c,0x7d,0xca,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7, - 0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x89,0x7c,0x7d,0xc7,0x88,0x7c,0x7d,0xc6,0x88,0x7c,0x7d,0xc8, - 0x87,0x7d,0x7e,0xce,0x86,0x7d,0x7e,0xd4,0x85,0x7f,0x80,0xe6,0x81,0x81,0x81,0xfe,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x7b,0x7b,0x7b,0xff,0x51,0x51,0x51,0xff,0x4d,0x4d,0x4d,0xff,0x2d,0x2d,0x2d,0x98, - 0x00,0x00,0x00,0x00,0x46,0x46,0x46,0xe7,0x79,0x79,0x79,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x7d,0x7d,0x7d,0xff,0x54,0x54,0x54,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x21,0x21,0x21,0x70,0x00,0x00,0x00,0x00,0x1c,0x1c,0x1c,0x5e,0x55,0x55,0x55,0xff, - 0x75,0x75,0x75,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x7f,0x7f,0x7f,0xff,0x57,0x57,0x57,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x48,0x48,0x48,0xf1,0x0c,0x0c,0x0c,0x28, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x39,0x39,0xbd,0x4d,0x4d,0x4d,0xff,0x60,0x60,0x60,0xff,0x7d,0x7d,0x7d,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff,0x82,0x82,0x82,0xff, - 0x82,0x82,0x82,0xff,0x76,0x76,0x76,0xff,0x62,0x62,0x62,0xff,0x50,0x50,0x50,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4a,0x4a,0x4a,0xf8,0x13,0x13,0x13,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x0b,0x0b,0x27, - 0x45,0x45,0x45,0xe6,0x4d,0x4d,0x4d,0xff,0x4e,0x4e,0x4e,0xff,0x57,0x57,0x57,0xff,0x5e,0x5e,0x5e,0xff,0x66,0x66,0x66,0xff, - 0x6d,0x6d,0x6d,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff, - 0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6e,0x6e,0x6e,0xff,0x6c,0x6c,0x6c,0xff, - 0x68,0x68,0x68,0xff,0x65,0x65,0x65,0xff,0x61,0x61,0x61,0xff,0x54,0x54,0x54,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4c,0x4c,0x4c,0xfc,0x18,0x18,0x18,0x51,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x0c,0x29,0x29,0x29,0x89,0x4b,0x4b,0x4b,0xf9, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4c,0x4c,0x4c,0xfc,0x36,0x36,0x36,0xb4,0x15,0x15,0x15,0x46, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x0b,0x0b,0x25,0x25,0x25,0x25,0x7b,0x30,0x30,0x30,0xa1,0x3c,0x3c,0x3c,0xc8, - 0x47,0x47,0x47,0xee,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff,0x4d,0x4d,0x4d,0xff, - 0x4c,0x4c,0x4c,0xfd,0x47,0x47,0x47,0xec,0x42,0x42,0x42,0xdd,0x3e,0x3e,0x3e,0xce,0x38,0x38,0x38,0xbc,0x23,0x23,0x23,0x75, - 0x07,0x07,0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} -}; diff --git a/client/x11/images/red_icon.c b/client/x11/images/red_icon.c deleted file mode 100644 index 143d4e2d..00000000 --- a/client/x11/images/red_icon.c +++ /dev/null @@ -1,275 +0,0 @@ -static const struct { - int width; - int height; - uint8_t pixmap[4096]; - uint8_t mask[128]; -} _red_icon = { 32, 32, { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xd3,0xd3,0xd3,0x00,0x1a,0x1a,0x1a,0x07,0x1a,0x1a,0x1a,0x49, - 0x1a,0x1a,0x1a,0x98,0x1f,0x1f,0x1f,0xc2,0x2d,0x2d,0x2d,0xdd,0x34,0x34,0x34,0xf4, - 0x3c,0x3c,0x3c,0xf5,0x45,0x45,0x45,0xe0,0x4f,0x4f,0x4f,0xcc,0x5b,0x5b,0x5b,0xac, - 0x83,0x83,0x83,0x6d,0xe7,0xe7,0xe7,0x36,0xff,0xff,0xff,0x2c,0xff,0xff,0xff,0x27, - 0xff,0xff,0xff,0x1f,0xff,0xff,0xff,0x16,0xff,0xff,0xff,0x0a,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0xd3,0xd3,0x00, - 0x1a,0x1a,0x1a,0x19,0x1a,0x1a,0x1a,0x97,0x1a,0x1a,0x1a,0xf2,0x1a,0x1a,0x1a,0xff, - 0x26,0x26,0x26,0xff,0x32,0x32,0x32,0xff,0x3d,0x3d,0x3d,0xff,0x47,0x47,0x47,0xff, - 0x4f,0x4f,0x4f,0xff,0x55,0x55,0x55,0xff,0x5a,0x5a,0x5a,0xff,0x5c,0x5c,0x5c,0xff, - 0x5c,0x5c,0x5c,0xff,0x5d,0x5d,0x5d,0xf6,0x71,0x71,0x71,0xb3,0xc9,0xc9,0xc9,0x51, - 0xff,0xff,0xff,0x35,0xff,0xff,0xff,0x2b,0xff,0xff,0xff,0x20,0xff,0xff,0xff,0x13, - 0xff,0xff,0xff,0x03,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x08,0x1a,0x1a,0x1a,0x84, - 0x1a,0x1a,0x1a,0xf5,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x28,0x28,0x28,0xff, - 0x37,0x37,0x37,0xff,0x43,0x43,0x43,0xff,0x4f,0x4f,0x4f,0xff,0x5a,0x5a,0x5a,0xff, - 0x63,0x63,0x63,0xff,0x6a,0x6a,0x6a,0xff,0x6f,0x6f,0x6f,0xff,0x72,0x72,0x72,0xff, - 0x72,0x72,0x72,0xff,0x70,0x70,0x70,0xff,0x6c,0x6c,0x6c,0xff,0x67,0x67,0x67,0xf8, - 0x80,0x80,0x80,0xa8,0xeb,0xeb,0xeb,0x46,0xff,0xff,0xff,0x33,0xff,0xff,0xff,0x25, - 0xff,0xff,0xff,0x16,0xff,0xff,0xff,0x04,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x18,0x1a,0x1a,0x1a,0xc8,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x27,0x27,0x27,0xff,0x37,0x37,0x37,0xff, - 0x45,0x45,0x45,0xff,0x53,0x53,0x53,0xff,0x60,0x60,0x60,0xff,0x6c,0x6c,0x6c,0xff, - 0x76,0x76,0x76,0xff,0x7f,0x7f,0x7f,0xff,0x84,0x84,0x84,0xff,0x88,0x88,0x88,0xff, - 0x88,0x88,0x88,0xff,0x86,0x86,0x86,0xff,0x80,0x80,0x80,0xff,0x79,0x79,0x79,0xff, - 0x6f,0x6f,0x6f,0xff,0x71,0x71,0x71,0xda,0xd1,0xd1,0xd1,0x57,0xff,0xff,0xff,0x36, - 0xff,0xff,0xff,0x26,0xff,0xff,0xff,0x15,0xff,0xff,0xff,0x02,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1a,0x1a,0x1a,0x2d,0x1a,0x1a,0x1a,0xe3,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x21,0x21,0x21,0xff,0x32,0x32,0x32,0xff,0x42,0x42,0x42,0xff, - 0x53,0x53,0x53,0xff,0x62,0x62,0x62,0xff,0x6f,0x6f,0x6f,0xff,0x7d,0x7d,0x7d,0xff, - 0x88,0x88,0x88,0xff,0x92,0x92,0x92,0xff,0x9a,0x9a,0x9a,0xff,0x9d,0x9d,0x9d,0xff, - 0x9e,0x9e,0x9e,0xff,0x9b,0x9b,0x9b,0xff,0x95,0x95,0x95,0xff,0x8c,0x8c,0x8c,0xff, - 0x81,0x81,0x81,0xff,0x75,0x75,0x75,0xff,0x6c,0x6c,0x6c,0xec,0xb5,0xb5,0xb5,0x66, - 0xff,0xff,0xff,0x34,0xff,0xff,0xff,0x22,0xff,0xff,0xff,0x10,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x18, - 0x1a,0x1a,0x1a,0xe3,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x2a,0x2a,0x2a,0xff,0x3c,0x3c,0x3c,0xff,0x4d,0x4d,0x4d,0xff, - 0x5d,0x5d,0x5d,0xff,0x6e,0x6e,0x6e,0xff,0x7e,0x7e,0x7e,0xff,0x8c,0x8c,0x8c,0xff, - 0x9a,0x9a,0x9a,0xff,0xa5,0xa5,0xa5,0xff,0xae,0xae,0xae,0xff,0xb3,0xb3,0xb3,0xff, - 0xb4,0xb4,0xb4,0xff,0xb0,0xb0,0xb0,0xff,0xa9,0xa9,0xa9,0xff,0x9e,0x9e,0x9e,0xff, - 0x91,0x91,0x91,0xff,0x83,0x83,0x83,0xff,0x74,0x74,0x74,0xff,0x6a,0x6a,0x6a,0xec, - 0xcd,0xcd,0xcd,0x52,0xff,0xff,0xff,0x2d,0xff,0xff,0xff,0x1a,0xff,0xff,0xff,0x05, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x08,0x1a,0x1a,0x1a,0xc8, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1e,0x1e,0x1e,0xff,0x31,0x31,0x31,0xff,0x43,0x43,0x43,0xff,0x55,0x55,0x55,0xff, - 0x66,0x66,0x66,0xff,0x77,0x77,0x77,0xff,0x88,0x88,0x88,0xff,0x99,0x99,0x99,0xff, - 0xa9,0xa9,0xa9,0xff,0xb6,0xb6,0xb6,0xff,0xc1,0xc1,0xc1,0xff,0xc8,0xc8,0xc8,0xff, - 0xca,0xca,0xca,0xff,0xc5,0xc5,0xc5,0xff,0xbb,0xbb,0xbb,0xff,0xae,0xae,0xae,0xff, - 0x9f,0x9f,0x9f,0xff,0x8f,0x8f,0x8f,0xff,0x7e,0x7e,0x7e,0xff,0x6d,0x6d,0x6d,0xff, - 0x67,0x67,0x67,0xd8,0xe7,0xe7,0xe7,0x3b,0xff,0xff,0xff,0x21,0xff,0xff,0xff,0x0d, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x84,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x23,0x23,0x23,0xff,0x36,0x36,0x36,0xff,0x48,0x48,0x48,0xff,0x5b,0x5b,0x5b,0xff, - 0x6d,0x6d,0x6d,0xff,0x7f,0x7f,0x7f,0xff,0x91,0x91,0x91,0xff,0xa3,0xa3,0xa3,0xff, - 0xb4,0xb4,0xb4,0xff,0xc4,0xc4,0xc4,0xff,0xd3,0xd3,0xd3,0xff,0xde,0xde,0xde,0xff, - 0xe0,0xe0,0xe0,0xff,0xd7,0xd7,0xd7,0xff,0xca,0xca,0xca,0xff,0xba,0xba,0xba,0xff, - 0xa9,0xa9,0xa9,0xff,0x98,0x98,0x98,0xff,0x86,0x86,0x86,0xff,0x73,0x73,0x73,0xff, - 0x61,0x61,0x61,0xff,0x6e,0x6e,0x6e,0xa0,0xff,0xff,0xff,0x27,0xff,0xff,0xff,0x12, - 0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x19,0x1a,0x1a,0x1a,0xf5,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x26,0x26,0x26,0xff,0x3e,0x3e,0x41,0xff,0x5f,0x5f,0x65,0xff,0x5d,0x5d,0x5d,0xff, - 0x6f,0x6f,0x6f,0xff,0x82,0x82,0x82,0xff,0x9b,0x9f,0x9b,0xff,0xad,0xae,0xad,0xff, - 0xba,0xba,0xba,0xff,0xcc,0xcc,0xcc,0xff,0xdf,0xdf,0xdf,0xff,0xf0,0xf0,0xf0,0xff, - 0xf6,0xf6,0xf6,0xff,0xe5,0xe5,0xe5,0xff,0xd3,0xd3,0xd3,0xff,0xc1,0xc1,0xc1,0xff, - 0xae,0xae,0xae,0xff,0x9b,0x9b,0x9b,0xff,0x89,0x89,0x89,0xff,0x76,0x76,0x76,0xff, - 0x65,0x65,0x65,0xff,0x53,0x53,0x53,0xf7,0xb1,0xb1,0xb1,0x3e,0xff,0xff,0xff,0x14, - 0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x97,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x25,0x25,0x25,0xff,0x6a,0x6a,0x86,0xff,0xa7,0xa7,0xc0,0xff,0x5e,0x5e,0x5f,0xff, - 0x6f,0x6f,0x6f,0xff,0x82,0x82,0x82,0xff,0xb0,0xc4,0xb0,0xff,0xcc,0xd5,0xcc,0xff, - 0xb9,0xb9,0xb9,0xff,0xcc,0xcc,0xcc,0xff,0xdd,0xdd,0xdd,0xff,0xf1,0xf0,0xf0,0xff, - 0xfe,0xfb,0xfb,0xff,0xe6,0xe5,0xe5,0xff,0xd2,0xd2,0xd2,0xff,0xc0,0xc0,0xc0,0xff, - 0xae,0xae,0xae,0xff,0x9b,0x9b,0x9b,0xff,0x88,0x88,0x88,0xff,0x76,0x76,0x76,0xff, - 0x64,0x64,0x64,0xff,0x52,0x52,0x52,0xff,0x52,0x52,0x52,0xa8,0xff,0xff,0xff,0x14, - 0x1a,0x1a,0x1a,0x07,0x1a,0x1a,0x1a,0xf2,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x27,0x27,0x2f,0xff,0x9a,0x9a,0xe3,0xff,0xca,0xca,0xff,0xff,0x84,0x84,0x8f,0xff, - 0x6c,0x6c,0x6c,0xff,0x7f,0x8a,0x7f,0xff,0xc1,0xf6,0xc1,0xff,0xe2,0xfe,0xe2,0xff, - 0xc0,0xc3,0xc0,0xff,0xc2,0xc2,0xc2,0xff,0xd0,0xd0,0xd0,0xff,0xf2,0xe8,0xe8,0xff, - 0xff,0xf4,0xf4,0xff,0xee,0xe8,0xe8,0xff,0xc8,0xc8,0xc8,0xff,0xb8,0xb8,0xb8,0xff, - 0xa8,0xa8,0xa8,0xff,0x96,0x96,0x96,0xff,0x85,0x85,0x85,0xff,0x73,0x73,0x73,0xff, - 0x61,0x61,0x61,0xff,0x4e,0x4e,0x4e,0xff,0x3e,0x3e,0x3e,0xf4,0xbf,0xbf,0xbf,0x18, - 0x1a,0x1a,0x1a,0x49,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x3e,0x3e,0x7a,0xff,0x9b,0x9b,0xff,0xff,0xbb,0xbb,0xff,0xff,0xc2,0xc2,0xe5,0xff, - 0x6f,0x6f,0x72,0xff,0x7e,0xb6,0x7e,0xff,0xb4,0xff,0xb4,0xff,0xd3,0xff,0xd3,0xff, - 0xda,0xe8,0xda,0xff,0xb5,0xb5,0xb5,0xff,0xce,0xc4,0xc4,0xff,0xff,0xe3,0xe3,0xff, - 0xff,0xe9,0xe9,0xff,0xff,0xed,0xed,0xff,0xcb,0xc6,0xc6,0xff,0xab,0xab,0xab,0xff, - 0x9d,0x9d,0x9d,0xff,0x8d,0x8d,0x8d,0xff,0x7d,0x7d,0x7d,0xff,0x6c,0x6c,0x6c,0xff, - 0x5b,0x5b,0x5b,0xff,0x49,0x49,0x49,0xff,0x37,0x37,0x37,0xff,0x3b,0x3b,0x3b,0x51, - 0x1a,0x1a,0x1a,0x98,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x2a,0xff, - 0x5a,0x5a,0xe5,0xff,0x88,0x88,0xff,0xff,0xaa,0xaa,0xff,0xff,0xc7,0xc7,0xff,0xff, - 0x9b,0xa1,0xac,0xff,0x73,0xf5,0x73,0xff,0x9e,0xff,0x9e,0xff,0xc0,0xff,0xc0,0xff, - 0xdd,0xff,0xdd,0xff,0xc0,0xc6,0xc0,0xff,0xe4,0xbc,0xbc,0xff,0xff,0xd2,0xd2,0xff, - 0xff,0xda,0xda,0xff,0xff,0xe1,0xe1,0xff,0xee,0xdb,0xdb,0xff,0xa0,0x9e,0x9e,0xff, - 0x8f,0x8f,0x8f,0xff,0x81,0x81,0x81,0xff,0x72,0x72,0x72,0xff,0x62,0x62,0x62,0xff, - 0x52,0x52,0x52,0xff,0x41,0x41,0x41,0xff,0x30,0x30,0x30,0xff,0x1f,0x1f,0x1f,0x99, - 0x1a,0x1a,0x1a,0xc1,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x22,0x22,0x7d,0xff, - 0x53,0x53,0xff,0xff,0x72,0x72,0xff,0xff,0x96,0x96,0xff,0xff,0xb7,0xb7,0xff,0xff, - 0xd0,0xd0,0xfc,0xff,0x74,0xd2,0x7c,0xff,0x84,0xff,0x84,0xff,0xaa,0xff,0xaa,0xff, - 0xca,0xff,0xca,0xff,0xde,0xf5,0xdd,0xff,0xec,0xb4,0xb2,0xff,0xff,0xbe,0xbe,0xff, - 0xff,0xc8,0xc8,0xff,0xff,0xd1,0xd1,0xff,0xff,0xda,0xda,0xff,0xbe,0xb1,0xb1,0xff, - 0x7f,0x7f,0x7f,0xff,0x72,0x72,0x72,0xff,0x65,0x65,0x65,0xff,0x56,0x56,0x56,0xff, - 0x47,0x47,0x47,0xff,0x37,0x37,0x37,0xff,0x26,0x26,0x26,0xff,0x1a,0x1a,0x1a,0xc1, - 0x1a,0x1a,0x1a,0xda,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x15,0x15,0x2c,0xff,0x24,0x24,0xe9,0xff, - 0x42,0x42,0xff,0xff,0x5f,0x5f,0xff,0xff,0x81,0x81,0xff,0xff,0xa3,0xa3,0xff,0xff, - 0xc1,0xc1,0xff,0xff,0xb1,0xc6,0xcb,0xff,0x67,0xf1,0x68,0xff,0x8e,0xff,0x8e,0xff, - 0xb2,0xff,0xb2,0xff,0xd1,0xff,0xd1,0xff,0xda,0xd0,0xc3,0xff,0xfc,0xa4,0xa4,0xff, - 0xff,0xb3,0xb3,0xff,0xff,0xbe,0xbe,0xff,0xff,0xc9,0xc9,0xff,0xfa,0xd2,0xd2,0xff, - 0x82,0x7d,0x7d,0xff,0x62,0x62,0x62,0xff,0x55,0x55,0x55,0xff,0x48,0x48,0x48,0xff, - 0x3a,0x3a,0x3a,0xff,0x2b,0x2b,0x2b,0xff,0x1b,0x1b,0x1b,0xff,0x1a,0x1a,0x1a,0xda, - 0x1a,0x1a,0x1a,0xf3,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x08,0x08,0x82,0xff,0x16,0x16,0xff,0xff, - 0x32,0x32,0xff,0xff,0x4e,0x4e,0xff,0xff,0x6a,0x6a,0xff,0xff,0x8c,0x8c,0xff,0xff, - 0xad,0xad,0xff,0xff,0xc9,0xc9,0xff,0xff,0x7c,0xc3,0x8a,0xff,0x6e,0xff,0x6e,0xff, - 0x96,0xff,0x96,0xff,0xba,0xff,0xba,0xff,0xda,0xff,0xda,0xff,0xd8,0xa2,0x9b,0xff, - 0xff,0x99,0x99,0xff,0xff,0xa7,0xa7,0xff,0xff,0xb5,0xb5,0xff,0xff,0xc2,0xc2,0xff, - 0xc7,0xa7,0xa7,0xff,0x52,0x52,0x52,0xff,0x45,0x45,0x45,0xff,0x39,0x39,0x39,0xff, - 0x2c,0x2c,0x2c,0xff,0x1c,0x1c,0x1c,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xf3, - 0x1a,0x1a,0x1a,0xf3,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x13,0x13,0x2e,0xff,0x01,0x01,0xee,0xff,0x05,0x05,0xff,0xff, - 0x21,0x21,0xff,0xff,0x3d,0x3d,0xff,0xff,0x59,0x59,0xff,0xff,0x75,0x75,0xff,0xff, - 0x96,0x96,0xff,0xff,0xb6,0xb6,0xff,0xff,0xc1,0xc6,0xea,0xff,0x57,0xd9,0x5c,0xff, - 0x75,0xff,0x75,0xff,0x9d,0xff,0x9d,0xff,0xc2,0xff,0xc2,0xff,0xd5,0xde,0xc9,0xff, - 0xec,0x7f,0x7d,0xff,0xff,0x8d,0x8d,0xff,0xff,0x9d,0x9d,0xff,0xff,0xac,0xac,0xff, - 0xff,0xbc,0xbc,0xff,0x7b,0x6a,0x6a,0xff,0x34,0x34,0x34,0xff,0x28,0x28,0x28,0xff, - 0x1b,0x1b,0x1b,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xf3, - 0x1a,0x1a,0x1a,0xda,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x08,0x08,0x87,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff, - 0x10,0x10,0xff,0xff,0x2d,0x2d,0xff,0xff,0x49,0x49,0xff,0xff,0x65,0x65,0xff,0xff, - 0x81,0x81,0xff,0xff,0x9e,0x9e,0xff,0xff,0xbd,0xbd,0xff,0xff,0x88,0xb6,0xa1,0xff, - 0x4d,0xfc,0x4d,0xff,0x7c,0xff,0x7c,0xff,0xa5,0xff,0xa5,0xff,0xcc,0xff,0xcc,0xff, - 0xc6,0x9d,0x90,0xff,0xff,0x70,0x70,0xff,0xff,0x82,0x82,0xff,0xff,0x93,0x93,0xff, - 0xff,0xa5,0xa5,0xff,0xe0,0xa3,0xa3,0xff,0x2e,0x2a,0x2a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xda, - 0x1a,0x1a,0x1a,0xc1,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x13,0x13,0x32,0xff,0x00,0x00,0xf0,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff, - 0x00,0x00,0xff,0xff,0x1c,0x1c,0xff,0xff,0x38,0x38,0xff,0xff,0x54,0x54,0xff,0xff, - 0x70,0x70,0xff,0xff,0x8d,0x8d,0xff,0xff,0xa9,0xa9,0xff,0xff,0xc4,0xc4,0xfe,0xff, - 0x4c,0xbc,0x59,0xff,0x55,0xff,0x55,0xff,0x83,0xff,0x83,0xff,0xaf,0xff,0xaf,0xff, - 0xd2,0xf5,0xd1,0xff,0xd1,0x61,0x5d,0xff,0xff,0x63,0x63,0xff,0xff,0x75,0x75,0xff, - 0xff,0x8a,0x8a,0xff,0xff,0xa0,0xa0,0xff,0x8c,0x67,0x67,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xc1, - 0x1a,0x1a,0x1a,0x98,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x08,0x08,0x8c,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff, - 0x00,0x00,0xff,0xff,0x0b,0x0b,0xff,0xff,0x27,0x27,0xff,0xff,0x44,0x44,0xff,0xff, - 0x60,0x60,0xff,0xff,0x7c,0x7c,0xff,0xff,0x98,0x98,0xff,0xff,0xb4,0xb4,0xff,0xff, - 0xa5,0xb8,0xc9,0xff,0x34,0xe3,0x37,0xff,0x60,0xff,0x60,0xff,0x8e,0xff,0x8e,0xff, - 0xbd,0xff,0xbd,0xff,0xbc,0xb0,0x98,0xff,0xf5,0x44,0x44,0xff,0xff,0x5e,0x5e,0xff, - 0xff,0x76,0x76,0xff,0xff,0x8e,0x8e,0xff,0xfd,0xa5,0xa5,0xff,0x46,0x38,0x38,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0x98, - 0x1a,0x1a,0x1a,0x49,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x12,0x12,0x34,0xff, - 0x00,0x00,0xdd,0xff,0x00,0x00,0xe9,0xff,0x00,0x00,0xe9,0xff,0x00,0x00,0xea,0xff, - 0x00,0x00,0xea,0xff,0x00,0x00,0xeb,0xff,0x15,0x15,0xeb,0xff,0x2f,0x2f,0xec,0xff, - 0x49,0x49,0xed,0xff,0x63,0x63,0xed,0xff,0x7e,0x7e,0xee,0xff,0x98,0x98,0xee,0xff, - 0xb4,0xb4,0xef,0xff,0x5f,0xa4,0x72,0xff,0x45,0xfd,0x45,0xff,0x75,0xfe,0x75,0xff, - 0xa3,0xfe,0xa3,0xff,0xd2,0xff,0xd2,0xff,0xa9,0x67,0x5b,0xff,0xd5,0x40,0x40,0xff, - 0xd5,0x54,0x54,0xff,0xd7,0x69,0x69,0xff,0xd9,0x7e,0x7e,0xff,0x9d,0x6c,0x6c,0xff, - 0x1d,0x1c,0x1c,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0x49, - 0x1a,0x1a,0x1a,0x07,0x1a,0x1a,0x1a,0xf2,0x1a,0x1a,0x1a,0xff,0x19,0x19,0x19,0xff, - 0x18,0x18,0x18,0xff,0x17,0x17,0x18,0xff,0x17,0x17,0x18,0xff,0x17,0x17,0x19,0xff, - 0x14,0x1a,0x16,0xff,0x12,0x1e,0x15,0xff,0x12,0x1f,0x15,0xff,0x13,0x1e,0x16,0xff, - 0x13,0x20,0x16,0xff,0x13,0x1f,0x15,0xff,0x14,0x21,0x16,0xff,0x14,0x22,0x16,0xff, - 0x14,0x22,0x16,0xff,0x14,0x22,0x15,0xff,0x16,0x24,0x16,0xff,0x1a,0x25,0x1a,0xff, - 0x1d,0x25,0x1d,0xff,0x20,0x25,0x20,0xff,0x1f,0x21,0x1f,0xff,0x19,0x19,0x19,0xff, - 0x19,0x19,0x19,0xff,0x19,0x19,0x19,0xff,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0xff, - 0x19,0x19,0x19,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xf2,0x1a,0x1a,0x1a,0x07, - 0x00,0x00,0x6e,0x00,0x1a,0x1a,0x1a,0x97,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0x97,0xd3,0xd3,0xd3,0x00, - 0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x19,0x1a,0x1a,0x1a,0xf5,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xf5,0x1a,0x1a,0x1a,0x19,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x00,0x1a,0x1a,0x1a,0x84,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0x84,0xd3,0xd3,0xd3,0x00,0x98,0x88,0x88,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x1a,0x1a,0x1a,0x08,0x1a,0x1a,0x1a,0xc8, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xc8,0x1a,0x1a,0x1a,0x08,0xa4,0x6d,0x6d,0x00,0x73,0x58,0x58,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x18, - 0x1a,0x1a,0x1a,0xe3,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xe3, - 0x1a,0x1a,0x1a,0x18,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1a,0x1a,0x1a,0x2d,0x1a,0x1a,0x1a,0xe3,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xe3,0x1a,0x1a,0x1a,0x2d, - 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x18,0x1a,0x1a,0x1a,0xc8,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xc8,0x1a,0x1a,0x1a,0x18,0xff,0xff,0xff,0x00, - 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x08,0x1a,0x1a,0x1a,0x84, - 0x1a,0x1a,0x1a,0xf5,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xf5, - 0x1a,0x1a,0x1a,0x84,0x1a,0x1a,0x1a,0x08,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, - 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1a,0x1a,0x1a,0x19,0x1a,0x1a,0x1a,0x97,0x1a,0x1a,0x1a,0xf2,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xff, - 0x1a,0x1a,0x1a,0xff,0x1a,0x1a,0x1a,0xf2,0x1a,0x1a,0x1a,0x97,0x1a,0x1a,0x1a,0x19, - 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x1a,0x1a,0x07,0x1a,0x1a,0x1a,0x49, - 0x1a,0x1a,0x1a,0x98,0x1a,0x1a,0x1a,0xc1,0x1a,0x1a,0x1a,0xda,0x1a,0x1a,0x1a,0xf3, - 0x1a,0x1a,0x1a,0xf3,0x1a,0x1a,0x1a,0xda,0x1a,0x1a,0x1a,0xc1,0x1a,0x1a,0x1a,0x98, - 0x1a,0x1a,0x1a,0x49,0x1a,0x1a,0x1a,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - - {0x00,0x0f,0xf0,0x00,0x00,0x7f,0xfe,0x00,0x01,0xff,0xff,0x80, - 0x03,0xff,0xff,0xc0,0x07,0xff,0xff,0xe0,0x0f,0xff,0xff,0xf0, - 0x1f,0xff,0xff,0xf8,0x3f,0xff,0xff,0xfc,0x3f,0xff,0xff,0xfc, - 0x7f,0xff,0xff,0xfe,0x7f,0xff,0xff,0xfe,0x7f,0xff,0xff,0xfe, - 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,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xfe, - 0x7f,0xff,0xff,0xfe,0x7f,0xff,0xff,0xfe,0x3f,0xff,0xff,0xfc, - 0x3f,0xff,0xff,0xfc,0x1f,0xff,0xff,0xf8,0x0f,0xff,0xff,0xf0, - 0x07,0xff,0xff,0xe0,0x03,0xff,0xff,0xc0,0x01,0xff,0xff,0x80, - 0x00,0x7f,0xfe,0x00,0x00,0x0f,0xf0,0x00} -}; diff --git a/client/x11/main.cpp b/client/x11/main.cpp deleted file mode 100644 index f95b3a21..00000000 --- a/client/x11/main.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "application.h" - -static void cleanup() -{ - spice_log_cleanup(); -} - -const char * version_str = VERSION; - -int main(int argc, char** argv) -{ - int exit_val; - - atexit(cleanup); - try { - exit_val = Application::main(argc, argv, version_str); - LOG_INFO("Spice client terminated (exitcode = %d)", exit_val); - } catch (Exception& e) { - LOG_ERROR("unhandled exception: %s", e.what()); - exit_val = e.get_error_code(); - } catch (std::exception& e) { - LOG_ERROR("unhandled exception: %s", e.what()); - exit_val = SPICEC_ERROR_CODE_ERROR; - } catch (...) { - LOG_ERROR("unhandled exception"); - exit_val = SPICEC_ERROR_CODE_ERROR; - } - - return exit_val; -} diff --git a/client/x11/named_pipe.cpp b/client/x11/named_pipe.cpp deleted file mode 100644 index ad6b2e5c..00000000 --- a/client/x11/named_pipe.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include "named_pipe.h" -#include "utils.h" -#include "debug.h" - -Session::Session(int fd, ProcessLoop& events_loop) - : _fd_client(fd) - , _events_loop(events_loop) -{ -} - -void Session::on_event() -{ - _conn_interface->on_data(); -} - -void Session::bind(NamedPipe::ConnectionInterface* conn_interface) -{ - _conn_interface = conn_interface; - _events_loop.add_socket(*this); -} - -Session::~Session() -{ - _events_loop.remove_socket(*this); - close(_fd_client); -} - -int32_t Session::write(const uint8_t *buf, int32_t size) -{ - const uint8_t *pos = buf; - - while (size) { - int now; - if ((now = send(_fd_client, (char *)pos, size, 0)) == -1) { - if (errno == EAGAIN) { - break; - } - if (errno == EINTR) { - continue; - } - DBG(0, "send error errno=%d, %s", errno, strerror(errno)); - return -1; - } - size -= now; - pos += now; - } - return (pos - buf); -} - -int32_t Session::read(uint8_t *buf, int32_t size) -{ - uint8_t *pos = buf; - while (size) { - int now; - if ((now = recv(_fd_client, (char *)pos, size, 0)) <= 0) { - if (now == 0) { - DBG(0, "read error, connection shutdown"); - return -1; - } - if (errno == EAGAIN) { - break; - } - if (errno == EINTR) { - continue; - } - DBG(0, "read error errno=%d, %s", errno, strerror(errno)); - return -1; - } - size -= now; - pos += now; - } - return (pos - buf); -} - -int LinuxListener::create_socket(const char *socket_name) -{ - int listen_socket; - struct sockaddr_un local; - - if ((listen_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - DBG(0, "create socket error, errno=%d, %s", errno, strerror(errno)); - return -1; - } - - _name = socket_name; - - local.sun_family = AF_UNIX; - strcpy(local.sun_path, socket_name); - unlink(local.sun_path); - if (bind(listen_socket, (struct sockaddr *)&local, - strlen(local.sun_path) + sizeof(local.sun_family)) == -1) { - DBG(0, "bind error, errno=%d, %s", errno, strerror(errno)); - return -1; - } - if (listen(listen_socket, 10) == -1) { - DBG(0, "listen error, errno=%d, %s", errno, strerror(errno)); - return -1; - } - return listen_socket; -} - -LinuxListener::LinuxListener(const char *name, NamedPipe::ListenerInterface &listener_interface, - ProcessLoop& events_loop) - : _listener_interface (listener_interface) - , _events_loop (events_loop) -{ - _listen_socket = create_socket(name); - if (_listen_socket <= 0) { - THROW("Listener creation failed %d", _listen_socket); - } - _events_loop.add_socket(*this); - - DBG(0, "listening socket - %s, added to events_loop", name); -} - -LinuxListener::~LinuxListener() -{ - _events_loop.remove_socket(*this); - close(_listen_socket); - unlink(_name.c_str()); -} - -void LinuxListener::on_event() -{ - for (;;) { - int fd_client; - Session *conn; - struct sockaddr_un remote; - socklen_t len = sizeof(remote); - - if ((fd_client = accept(_listen_socket, (struct sockaddr *)&remote, &len)) == -1) { - if (errno == EAGAIN) { - break; - } - if (errno == EINTR) { - continue; - } - THROW("errno=%d, %s", errno, strerror(errno)); - } - - conn = new Session(fd_client, _events_loop); - DBG(0, "New connection created, fd: %d", fd_client); - NamedPipe::ConnectionInterface &conn_interface = _listener_interface.create(); - conn->bind(&conn_interface); - conn_interface.bind((NamedPipe::ConnectionRef)conn); - } -} diff --git a/client/x11/named_pipe.h b/client/x11/named_pipe.h deleted file mode 100644 index 379cbffe..00000000 --- a/client/x11/named_pipe.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_NAMED_PIPE -#define _H_NAMED_PIPE - -#include "platform.h" -#include "x_platform.h" -#include "process_loop.h" - -class Session: public EventSources::Socket { -public: - Session(int fd, ProcessLoop& events_loop); - virtual ~Session(); - void bind(NamedPipe::ConnectionInterface* conn_interface); - -public: - virtual void on_event(); - virtual int get_socket() {return _fd_client;} - int32_t write(const uint8_t *buf, int32_t size); - int32_t read(uint8_t *buf, int32_t size); - -private: - NamedPipe::ConnectionInterface *_conn_interface; - int _fd_client; - ProcessLoop &_events_loop; -}; - -class LinuxListener: public EventSources::Socket { -public: - LinuxListener(const char *name, NamedPipe::ListenerInterface &listener_interface, - ProcessLoop& events_loop); - virtual ~LinuxListener(); - void on_event(); - virtual int get_socket() {return _listen_socket;} - -private: - int create_socket(const char *socket_name); - -private: - NamedPipe::ListenerInterface &_listener_interface; - int _listen_socket; - std::string _name; - ProcessLoop &_events_loop; -}; - -#endif diff --git a/client/x11/pixels_source.cpp b/client/x11/pixels_source.cpp deleted file mode 100644 index 71ea9ff4..00000000 --- a/client/x11/pixels_source.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "x_platform.h" -#include "pixels_source.h" -#include "pixels_source_p.h" -#include "utils.h" -#include "debug.h" -#include "res.h" - - -static void create_pixmap(const PixmapHeader* pixmap, PixelsSource_p& pixels_source, - pixman_format_code_t format) -{ - pixman_image_t *pixman_image; - - pixman_image = pixman_image_create_bits(format, - pixmap->width, pixmap->height, - (uint32_t *)pixmap->data, - pixmap->stride); - if (pixman_image == NULL) { - THROW("surf create failed"); - } - - pixels_source.type = PIXELS_SOURCE_TYPE_PIXMAP; - pixels_source.pixmap.pixman_image = pixman_image; - pixels_source.pixmap.x_image = NULL; - pixels_source.pixmap.shminfo = NULL; - if (format == PIXMAN_a8r8g8b8) { - pixels_source.pixmap.format = RedDrawable::ARGB32; - } else { - pixels_source.pixmap.format = RedDrawable::RGB32; - } -} - -PixelsSource::PixelsSource() -{ - _origin.x = _origin.y = 0; - memset(_opaque, 0, sizeof(_opaque)); -} - -PixelsSource::~PixelsSource() -{ -} - -ImageFromRes::ImageFromRes(int res_id) -{ - const PixmapHeader* pixmap = res_get_image(res_id); - if (!pixmap) { - THROW("no image %d", res_id); - } - create_pixmap(pixmap, *(PixelsSource_p*)get_opaque(), PIXMAN_x8r8g8b8); -} - -ImageFromRes::~ImageFromRes() -{ - pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image); -} - -SpicePoint ImageFromRes::get_size() -{ - pixman_image_t *image = ((PixelsSource_p*)get_opaque())->pixmap.pixman_image; - SpicePoint pt; - pt.x = pixman_image_get_width(image); - pt.y = pixman_image_get_height(image); - return pt; -} - -AlphaImageFromRes::AlphaImageFromRes(int res_id) -{ - const PixmapHeader* pixmap = res_get_image(res_id); - if (!pixmap) { - THROW("no image %d", res_id); - } - create_pixmap(pixmap, *(PixelsSource_p*)get_opaque(), PIXMAN_a8r8g8b8); -} - -AlphaImageFromRes::~AlphaImageFromRes() -{ - pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image); -} - -SpicePoint AlphaImageFromRes::get_size() -{ - pixman_image_t *image = ((PixelsSource_p*)get_opaque())->pixmap.pixman_image; - SpicePoint pt; - pt.x = pixman_image_get_width(image); - pt.y = pixman_image_get_height(image); - return pt; -} diff --git a/client/x11/pixels_source_p.h b/client/x11/pixels_source_p.h deleted file mode 100644 index 84311211..00000000 --- a/client/x11/pixels_source_p.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_PIXELE_SOURSR_P -#define _H_PIXELE_SOURSR_P - -#include <X11/X.h> -#ifdef USE_OPENGL -#include <GL/glu.h> -#endif // USE_OPENGL -#include <X11/Xdefs.h> -#include <X11/Xutil.h> // required by Xshm.h, but not included by it -#include <X11/extensions/XShm.h> -#include "red_window.h" -#ifdef USE_OPENGL -#include "red_pixmap_gl.h" -#endif // USE_OPENGL - -#include "common/pixman_utils.h" - -enum { - PIXELS_SOURCE_TYPE_INVALID, - PIXELS_SOURCE_TYPE_X_DRAWABLE, - PIXELS_SOURCE_TYPE_PIXMAP, -#ifdef USE_OPENGL - PIXELS_SOURCE_TYPE_GL_TEXTURE, - PIXELS_SOURCE_TYPE_GL_DRAWABLE, -#endif // USE_OPENGL -}; - -struct PixelsSource_p { - int type; - union { - struct { - XImage* x_image; - XShmSegmentInfo *shminfo; - pixman_image_t* pixman_image; - RedDrawable::Format format; - } pixmap; - - struct { - Drawable drawable; - int screen; - GC gc; - int width, height; -#ifdef USE_OPENGL - RenderType rendertype; - union { - GLXPbuffer pbuff; - GLuint fbo; - }; - RedGlContext context; -#endif // USE_OPENGL - } x_drawable; - -#ifdef USE_OPENGL - struct { - RenderType rendertype; - Win win; - GLuint tex; - GLuint stencil_tex; - GLuint rbo; - int width, height; - int width_powed, height_powed; - union { - GLXPbuffer pbuff; - GLuint fbo; - }; - RedGlContext context; - } gl; -#endif // USE_OPENGL - }; -}; - -struct RedDrawable_p { - PixelsSource_p source; -}; - -#endif diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp deleted file mode 100644 index 6a374835..00000000 --- a/client/x11/platform.cpp +++ /dev/null @@ -1,3815 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xatom.h> -#include <X11/XKBlib.h> -#include <X11/Xresource.h> -#include <X11/cursorfont.h> -#include <X11/extensions/Xrandr.h> -#include <X11/extensions/render.h> -#include <X11/extensions/XKB.h> -#include <X11/extensions/Xrender.h> -#include <X11/extensions/XShm.h> -#include <X11/extensions/Xfixes.h> -#include <unistd.h> -#include <sys/socket.h> -#include <sys/resource.h> -#include <sys/types.h> -#include <sys/syscall.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <set> -#include <values.h> -#include <signal.h> -#include <sys/shm.h> -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#include <spice/vd_agent.h> -#include "common/rect.h" - -#include "platform.h" -#include "application.h" -#include "utils.h" -#include "x_platform.h" -#include "debug.h" -#include "monitor.h" -#include "record.h" -#include "playback.h" -#include "resource.h" -#include "res.h" -#include "cursor.h" -#include "process_loop.h" - -#define DWORD uint32_t -#define BOOL bool -#include "named_pipe.h" - -//#define X_DEBUG_SYNC(display) do { XLockDisplay(display); XSync(display, False); XUnlockDisplay(display); } while(0) -#define X_DEBUG_SYNC(display) -#ifdef HAVE_XRANDR12 -#define USE_XRANDR_1_2 -#endif - -#ifdef HAVE_XINERAMA -#include <X11/extensions/Xinerama.h> -#define USE_XINERAMA_1_0 -#endif - -static Display* x_display = NULL; -static bool x_shm_avail = false; -static XVisualInfo **vinfo = NULL; -static RedDrawable::Format *screen_format = NULL; -#ifdef USE_OPENGL -static GLXFBConfig **fb_config = NULL; -#endif // USE_OPENGL -static XIM x_input_method = NULL; -static XIC x_input_context = NULL; - -static Window platform_win = 0; -static XContext win_proc_context; -static ProcessLoop* main_loop = NULL; -static int focus_count = 0; - -static bool using_xrandr_1_0 = false; -#ifdef USE_XRANDR_1_2 -static bool using_xrandr_1_2 = false; -#endif - -static int xrandr_event_base; -static int xrandr_error_base; -static int xrandr_major = 0; -static int xrandr_minor = 0; - -static bool using_xrender_0_5 = false; - -static bool using_xfixes_1_0 = false; - -static int xfixes_event_base; -static int xfixes_error_base; - -#ifdef USE_XINERAMA_1_0 -static bool using_xinerama_1_0 = false; -#endif - -static unsigned int caps_lock_mask = 0; -static unsigned int num_lock_mask = 0; - -//FIXME: nicify -struct clipboard_format_info { - uint32_t type; - const char *atom_names[16]; - Atom atoms[16]; - int atom_count; -}; - -static struct clipboard_format_info clipboard_formats[] = { - { VD_AGENT_CLIPBOARD_UTF8_TEXT, { "UTF8_STRING", - "text/plain;charset=UTF-8", "text/plain;charset=utf-8", NULL }, { 0 }, 0}, - { VD_AGENT_CLIPBOARD_IMAGE_PNG, { "image/png", NULL }, { 0 }, 0}, - { VD_AGENT_CLIPBOARD_IMAGE_BMP, { "image/bmp", "image/x-bmp", - "image/x-MS-bmp", "image/x-win-bitmap", NULL }, { 0 }, 0}, - { VD_AGENT_CLIPBOARD_IMAGE_TIFF, { "image/tiff", NULL }, { 0 }, 0}, - { VD_AGENT_CLIPBOARD_IMAGE_JPG, { "image/jpeg", NULL }, { 0 }, 0}, -}; - -#define clipboard_format_count ((int)(sizeof(clipboard_formats)/sizeof(clipboard_formats[0]))) - -struct selection_request { - XEvent event; - selection_request *next; -}; - -static int expected_targets_notifies = 0; -static bool waiting_for_property_notify = false; -static uint8_t* clipboard_data = NULL; -static uint32_t clipboard_data_size = 0; -static uint32_t clipboard_data_space = 0; -static Atom clipboard_request_target = None; -static selection_request *next_selection_request = NULL; -static int clipboard_type_count = 0; -static uint32_t clipboard_agent_types[256]; -static Atom clipboard_x11_targets[256]; -static Mutex clipboard_lock; -static Atom clipboard_prop; -static Atom incr_atom; -static Atom targets_atom; -static Atom multiple_atom; -static Bool handle_x_error = false; -static int x_error_code; - -static void handle_selection_request(); - -class DefaultEventListener: public Platform::EventListener { -public: - virtual void on_app_activated() {} - virtual void on_app_deactivated() {} - virtual void on_monitors_change() {} -}; - -static DefaultEventListener default_event_listener; -static Platform::EventListener* event_listener = &default_event_listener; - -class DefaultDisplayModeListener: public Platform::DisplayModeListener { -public: - void on_display_mode_change() {} -}; - -static DefaultDisplayModeListener default_display_mode_listener; -static Platform::DisplayModeListener* display_mode_listener = &default_display_mode_listener; - -class DefaultClipboardListener: public Platform::ClipboardListener { -public: - void on_clipboard_grab(uint32_t *types, uint32_t type_count) {} - void on_clipboard_request(uint32_t type) {} - void on_clipboard_notify(uint32_t type, uint8_t* data, int32_t size) {} - void on_clipboard_release() {} -}; - -static DefaultClipboardListener default_clipboard_listener; -static Platform::ClipboardListener* clipboard_listener = &default_clipboard_listener; - -static void handle_x_errors_start(void) -{ - handle_x_error = True; - x_error_code = 0; -} - -static int handle_x_errors_stop(void) -{ - handle_x_error = False; - return x_error_code; -} - -static const char *atom_name(Atom atom) -{ - const char *name; - - if (atom == None) - return "None"; - - XLockDisplay(x_display); - handle_x_errors_start(); - name = XGetAtomName(x_display, atom); - if (handle_x_errors_stop()) { - name = "Bad Atom"; - } - XUnlockDisplay(x_display); - - return name; -} - -static uint32_t get_clipboard_type(Atom target) { - int i, j; - - if (target == None) - return VD_AGENT_CLIPBOARD_NONE; - - for (i = 0; i < clipboard_format_count; i++) { - for (j = 0; j < clipboard_formats[i].atom_count; i++) { - if (clipboard_formats[i].atoms[j] == target) { - return clipboard_formats[i].type; - } - } - } - - LOG_WARN("unexpected selection type %s", atom_name(target)); - return VD_AGENT_CLIPBOARD_NONE; -} - -static Atom get_clipboard_target(uint32_t type) { - int i; - - for (i = 0; i < clipboard_type_count; i++) - if (clipboard_agent_types[i] == type) - return clipboard_x11_targets[i]; - - LOG_WARN("client requested unavailable type %u", type); - return None; -} - -NamedPipe::ListenerRef NamedPipe::create(const char *name, ListenerInterface& listener_interface) -{ - ASSERT(main_loop && main_loop->is_same_thread(pthread_self())); - return (ListenerRef)(new LinuxListener(name, listener_interface, *main_loop)); -} - -void NamedPipe::destroy(ListenerRef listener_ref) -{ - ASSERT(main_loop && main_loop->is_same_thread(pthread_self())); - delete (LinuxListener *)listener_ref; -} - -void NamedPipe::destroy_connection(ConnectionRef conn_ref) -{ - ASSERT(main_loop && main_loop->is_same_thread(pthread_self())); - delete (Session *)conn_ref; -} - -int32_t NamedPipe::read(ConnectionRef conn_ref, uint8_t* buf, int32_t size) -{ - if (((Session *)conn_ref) != NULL) { - return ((Session *)conn_ref)->read(buf, size); - } - return -1; -} - -int32_t NamedPipe::write(ConnectionRef conn_ref, const uint8_t* buf, int32_t size) -{ - if (((Session *)conn_ref) != NULL) { - return ((Session *)conn_ref)->write(buf, size); - } - return -1; -} - -class XEventHandler: public EventSources::File { -public: - XEventHandler(Display& x_display, XContext& win_proc_context); - virtual void on_event(); - virtual int get_fd() {return _x_fd;} - -private: - Display& _x_display; - XContext& _win_proc_context; - int _x_fd; -}; - -XEventHandler::XEventHandler(Display& x_display, XContext& win_proc_context) - : _x_display (x_display) - , _win_proc_context (win_proc_context) -{ - if ((_x_fd = ConnectionNumber(&x_display)) == -1) { - THROW("get x fd failed"); - } -} - -void XEventHandler::on_event() -{ - XLockDisplay(x_display); - while (XPending(&_x_display)) { - XPointer proc_pointer; - XEvent event; - - XNextEvent(&_x_display, &event); - if (event.xany.window == None) { - continue; - } - - if (XFilterEvent(&event, None)) { - continue; - } - - if (XFindContext(&_x_display, event.xany.window, _win_proc_context, &proc_pointer)) { - /* When XIM + ibus is in use XIM creates an invisible window for - its own purposes, we sometimes get a _GTK_LOAD_ICONTHEMES - ClientMessage event on this window -> skip logging. */ - if (event.type != ClientMessage) { - LOG_WARN( - "Event on window without a win proc, type: %d, window: %u", - event.type, (unsigned int)event.xany.window); - } - continue; - } - XUnlockDisplay(x_display); - ((XPlatform::win_proc_t)proc_pointer)(event); - XLockDisplay(x_display); - } - XUnlockDisplay(x_display); -} - -Display* XPlatform::get_display() -{ - return x_display; -} - -bool XPlatform::is_x_shm_avail() -{ - return x_shm_avail; -} - -XImage *XPlatform::create_x_shm_image(RedDrawable::Format format, - int width, int height, int depth, - Visual *visual, - XShmSegmentInfo **shminfo_out) -{ - XImage *image; - XShmSegmentInfo *shminfo; - - /* We need to lock the display early, and force any pending requests to - be processed, to make sure that any errors reported by - handle_x_errors_stop() are actually ours */ - XLockDisplay(XPlatform::get_display()); - XSync(XPlatform::get_display(), False); - - shminfo = new XShmSegmentInfo; - shminfo->shmid = -1; - shminfo->shmaddr = NULL; - - image = XShmCreateImage(XPlatform::get_display(), - format == RedDrawable::A1 ? NULL : visual, - format == RedDrawable::A1 ? 1 : depth, - format == RedDrawable::A1 ? XYBitmap : ZPixmap, - NULL, shminfo, width, height); - if (image == NULL) { - x_shm_avail = false; - goto err1; - } - - shminfo->shmid = shmget(IPC_PRIVATE, height * image->bytes_per_line, - IPC_CREAT | 0777); - if (shminfo->shmid < 0) { - /* EINVAL indicates, most likely, that the segment we asked for - * is bigger than SHMMAX, so we don't treat it as a permanent - * error. ENOSPC and ENOMEM may also indicate this, but - * more likely are permanent errors. - */ - if (errno != EINVAL) { - x_shm_avail = false; - } - goto err2; - } - - shminfo->shmaddr = (char *)shmat(shminfo->shmid, 0, 0); - if (!shminfo->shmaddr) { - /* Failure in shmat is almost certainly permanent. Most likely error is - * EMFILE, which would mean that we've exceeded the per-process - * Shm segment limit. - */ - x_shm_avail = false; - - goto err2; - } - - shminfo->readOnly = False; - if (!XShmAttach(XPlatform::get_display(), shminfo)) { - x_shm_avail = false; - goto err2; - } - - handle_x_errors_start(); - - /* Ensure the xserver has attached the xshm segment */ - XSync (XPlatform::get_display(), False); - - if (handle_x_errors_stop()) { - x_shm_avail = false; - goto err2; - } - - /* Mark segment as released so that it will be destroyed when - the xserver releases the segment. This way we won't leak - the segment if the client crashes. */ - shmctl(shminfo->shmid, IPC_RMID, 0); - - XUnlockDisplay(XPlatform::get_display()); - - image->data = (char *)shminfo->shmaddr; - - *shminfo_out = shminfo; - return image; - -err2: - XDestroyImage(image); - if (shminfo->shmaddr != NULL) { - shmdt(shminfo->shmaddr); - } - if (shminfo->shmid != -1) { - shmctl(shminfo->shmid, IPC_RMID, 0); - } - -err1: - XUnlockDisplay(XPlatform::get_display()); - delete shminfo; - return NULL; -} - -XImage *XPlatform::create_x_image(RedDrawable::Format format, - int width, int height, int depth, - Visual *visual, - XShmSegmentInfo **shminfo_out) -{ - XImage *image = NULL; - uint8_t *data; - size_t stride; - - *shminfo_out = NULL; - - if (XPlatform::is_x_shm_avail()) { - image = XPlatform::create_x_shm_image(format, width, height, - depth, visual, - shminfo_out); - } - - if (image != NULL) { - return image; - } - - stride = SPICE_ALIGN(width * RedDrawable::format_to_bpp (format), 32) / 8; - /* Must use malloc here, not new, because XDestroyImage will free() it */ - data = (uint8_t *)malloc(height * stride); - if (data == NULL) { - THROW("Out of memory"); - } - - XLockDisplay(XPlatform::get_display()); - if (format == RedDrawable::A1) { - image = XCreateImage(XPlatform::get_display(), - NULL, 1, XYBitmap, - 0, (char *)data, width, height, 32, stride); - } else { - image = XCreateImage(XPlatform::get_display(), - visual, depth, ZPixmap, - 0, (char *)data, width, height, 32, stride); - } - XUnlockDisplay(XPlatform::get_display()); - - return image; -} - - -void XPlatform::free_x_image(XImage *image, - XShmSegmentInfo *shminfo) -{ - if (shminfo) { - XLockDisplay(XPlatform::get_display()); - XShmDetach(XPlatform::get_display(), shminfo); - } - if (image) { - XDestroyImage(image); - } - if (shminfo) { - XSync(XPlatform::get_display(), False); - shmdt(shminfo->shmaddr); - XUnlockDisplay(XPlatform::get_display()); - delete shminfo; - } -} - - -XVisualInfo** XPlatform::get_vinfo() -{ - return vinfo; -} - -RedDrawable::Format XPlatform::get_screen_format(int screen) -{ - return screen_format[screen]; -} - -#ifdef USE_OPENGL -GLXFBConfig** XPlatform::get_fbconfig() -{ - return fb_config; -} -#endif // USE_OPENGL - -XIC XPlatform::get_input_context() -{ - return x_input_context; -} - -void XPlatform::set_win_proc(Window win, win_proc_t proc) -{ - int res; - - XLockDisplay(x_display); - res = XSaveContext(x_display, win, win_proc_context, (XPointer)proc); - XUnlockDisplay(x_display); - if (res) { - THROW("set win proc failed"); - } -} - -void XPlatform::cleare_win_proc(Window win) -{ - XLockDisplay(x_display); - XDeleteContext(x_display, win, win_proc_context); - XUnlockDisplay(x_display); -} - -void Platform::send_quit_request() -{ - ASSERT(main_loop); - main_loop->quit(0); -} - -uint64_t Platform::get_monolithic_time() -{ -#ifdef HAVE_CLOCK_GETTIME - struct timespec time_space; - clock_gettime(CLOCK_MONOTONIC, &time_space); - return uint64_t(time_space.tv_sec) * 1000 * 1000 * 1000 + uint64_t(time_space.tv_nsec); -#else - struct timeval tv; - gettimeofday(&tv, NULL); - return uint64_t(tv.tv_sec) * 1000 * 1000 * 1000 + uint64_t(tv.tv_usec) * 1000; -#endif -} - -void Platform::get_temp_dir(std::string& path) -{ - path = "/tmp/"; -} - -uint64_t Platform::get_process_id() -{ - static uint64_t pid = uint64_t(getpid()); - return pid; -} - -uint64_t Platform::get_thread_id() -{ - return uint64_t(syscall(SYS_gettid)); -} - -void Platform::error_beep() -{ - if (!x_display) { - return; - } - - XBell(x_display, 0); - XFlush(x_display); -} - -void Platform::msleep(unsigned int millisec) -{ - usleep(millisec * 1000); -} - -void Platform::yield() -{ - POSIX_YIELD_FUNC; -} - -void Platform::term_printf(const char* format, ...) -{ - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); -} - -void Platform::set_thread_priority(void* thread, Platform::ThreadPriority in_priority) -{ - ASSERT(thread == NULL); - int priority; - - switch (in_priority) { - case PRIORITY_TIME_CRITICAL: - priority = -20; - break; - case PRIORITY_HIGH: - priority = -2; - break; - case PRIORITY_ABOVE_NORMAL: - priority = -1; - break; - case PRIORITY_NORMAL: - priority = 0; - break; - case PRIORITY_BELOW_NORMAL: - priority = 1; - break; - case PRIORITY_LOW: - priority = 2; - break; - case PRIORITY_IDLE: - priority = 19; - break; - default: - THROW("invalid priority %d", in_priority); - } - - pid_t tid = syscall(SYS_gettid); - if (setpriority(PRIO_PROCESS, tid, priority) == -1) { - DBG(0, "setpriority failed %s", strerror(errno)); - } -} - -void Platform::set_event_listener(EventListener* listener) -{ - event_listener = listener ? listener : &default_event_listener; -} - -void Platform::set_display_mode_listner(DisplayModeListener* listener) -{ - display_mode_listener = listener ? listener : &default_display_mode_listener; -} - -#ifdef USE_XRANDR_1_2 -class FreeScreenResources { -public: - void operator () (XRRScreenResources* res) { XRRFreeScreenResources(res);} -}; -typedef _AutoRes<XRRScreenResources, FreeScreenResources> AutoScreenRes; - -class FreeOutputInfo { -public: - void operator () (XRROutputInfo* output_info) { XRRFreeOutputInfo(output_info);} -}; - -typedef _AutoRes<XRROutputInfo, FreeOutputInfo> AutoOutputInfo; - -class FreeCrtcInfo { -public: - void operator () (XRRCrtcInfo* crtc_info) { XRRFreeCrtcInfo(crtc_info);} -}; -typedef _AutoRes<XRRCrtcInfo, FreeCrtcInfo> AutoCrtcInfo; - -static XRRModeInfo* find_mod(XRRScreenResources* res, RRMode mode) -{ - for (int i = 0; i < res->nmode; i++) { - if (res->modes[i].id == mode) { - return &res->modes[i]; - } - } - return NULL; -} - -#endif - -//#define SHOW_SCREEN_INFO -#ifdef SHOW_SCREEN_INFO - -static float mode_refresh(XRRModeInfo *mode_info) -{ - if (!mode_info->hTotal || !mode_info->vTotal) { - return 0; - } - - return ((float)mode_info->dotClock / ((float)mode_info->hTotal * (float)mode_info->vTotal)); -} - -static void show_scren_info() -{ - int screen = DefaultScreen(x_display); - Window root_window = RootWindow(x_display, screen); - - int minWidth; - int minHeight; - int maxWidth; - int maxHeight; - - XLockDisplay(x_display); - AutoScreenRes res(XRRGetScreenResources(x_display, root_window)); - XUnlockDisplay(x_display); - - if (!res.valid()) { - throw Exception(fmt("%s: get screen resources failed") % __FUNCTION__); - } - - XLockDisplay(x_display); - XRRGetScreenSizeRange(x_display, root_window, &minWidth, &minHeight, - &maxWidth, &maxHeight); - printf("screen: min %dx%d max %dx%d\n", minWidth, minHeight, - maxWidth, maxHeight); - - int i, j; - - for (i = 0; i < res->noutput; i++) { - AutoOutputInfo output_info(XRRGetOutputInfo(x_display, res.get(), res->outputs[i])); - - printf("output %s", output_info->name); - if (output_info->crtc == None) { - printf(" crtc None"); - } else { - printf(" crtc 0x%lx", output_info->crtc); - } - switch (output_info->connection) { - case RR_Connected: - printf(" Connected"); - break; - case RR_Disconnected: - printf(" Disconnected"); - break; - case RR_UnknownConnection: - printf(" UnknownConnection"); - break; - } - printf(" ncrtc %u nclone %u nmode %u\n", - output_info->ncrtc, - output_info->nclone, - output_info->nmode); - for (j = 0; j < output_info->nmode; j++) { - XRRModeInfo* mode = find_mod(res.get(), output_info->modes[j]); - printf("\t%lu:", output_info->modes[j]); - if (!mode) { - printf(" ???\n"); - continue; - } - printf(" %s %ux%u %f\n", mode->name, mode->width, mode->height, mode_refresh(mode)); - } - } - - for (i = 0; i < res->ncrtc; i++) { - AutoCrtcInfo crtc_info(XRRGetCrtcInfo(x_display, res.get(), res->crtcs[i])); - printf("crtc: 0x%lx x %d y %d width %u height %u mode %lu\n", - res->crtcs[i], - crtc_info->x, crtc_info->y, - crtc_info->width, crtc_info->height, crtc_info->mode); - } - XUnlockDisplay(x_display); -} - -#endif - -enum RedScreenRotation { - RED_SCREEN_ROTATION_0, - RED_SCREEN_ROTATION_90, - RED_SCREEN_ROTATION_180, - RED_SCREEN_ROTATION_270, -}; - -enum RedSubpixelOrder { - RED_SUBPIXEL_ORDER_UNKNOWN, - RED_SUBPIXEL_ORDER_H_RGB, - RED_SUBPIXEL_ORDER_H_BGR, - RED_SUBPIXEL_ORDER_V_RGB, - RED_SUBPIXEL_ORDER_V_BGR, - RED_SUBPIXEL_ORDER_NONE, -}; - -static void root_win_proc(XEvent& event); -static void process_monitor_configure_events(Window root); - -class XMonitor; -typedef std::list<XMonitor*> XMonitorsList; - -class XScreen { -public: - XScreen(Display* display, int screen); - virtual ~XScreen() {} - - virtual void publish_monitors(MonitorsList& monitors) = 0; - - Display* get_display() {return _display;} - int get_screen() {return _screen;} - - void set_broken() {_broken = true;} - bool is_broken() const {return _broken;} - int get_width() const {return _width;} - void set_width(int width) {_width = width;} - int get_height() const { return _height;} - void set_height(int height) {_height = height;} - SpicePoint get_position() const {return _position;} - -private: - Display* _display; - int _screen; - SpicePoint _position; - int _width; - int _height; - bool _broken; -}; - -XScreen::XScreen(Display* display, int screen) - : _display (display) - , _screen (screen) - , _broken (false) -{ - int root = RootWindow(display, screen); - - XWindowAttributes attrib; - - XLockDisplay(display); - XGetWindowAttributes(display, root, &attrib); - XUnlockDisplay(display); - - _position.x = attrib.x; - _position.y = attrib.y; - _width = attrib.width; - _height = attrib.height; -} - -class StaticScreen: public XScreen, public Monitor { -public: - StaticScreen(Display* display, int screen, int& next_mon_id) - : XScreen(display, screen) - , Monitor(next_mon_id++) - , _out_of_sync (false) - { - } - - virtual void publish_monitors(MonitorsList& monitors) - { - monitors.push_back(this); - } - - virtual int get_depth() { return XPlatform::get_vinfo()[0]->depth;} - virtual SpicePoint get_position() { return XScreen::get_position();} - virtual SpicePoint get_size() const { SpicePoint pt = {get_width(), get_height()}; return pt;} - virtual bool is_out_of_sync() { return _out_of_sync;} - virtual int get_screen_id() { return get_screen();} - -protected: - virtual void do_set_mode(int width, int height) - { - _out_of_sync = width > get_width() || height > get_height(); - } - - virtual void do_restore() {} - -private: - bool _out_of_sync; -}; - -class DynamicScreen: public XScreen, public Monitor { -public: - DynamicScreen(Display* display, int screen, int& next_mon_id); - virtual ~DynamicScreen(); - - void publish_monitors(MonitorsList& monitors); - virtual int get_depth() { return XPlatform::get_vinfo()[0]->depth;} - virtual SpicePoint get_position() { return XScreen::get_position();} - virtual SpicePoint get_size() const { SpicePoint pt = {get_width(), get_height()}; return pt;} - virtual bool is_out_of_sync() { return _out_of_sync;} - virtual int get_screen_id() { return get_screen();} - -protected: - virtual void do_set_mode(int width, int height); - virtual void do_restore(); - -private: - bool set_screen_size(int size_index); - -private: - int _saved_width; - int _saved_height; - bool _out_of_sync; -}; - -static void intern_clipboard_atoms() -{ - int i, j; - static bool interned = false; - if (interned) return; - - XLockDisplay(x_display); - clipboard_prop = XInternAtom(x_display, "CLIPBOARD", False); - incr_atom = XInternAtom(x_display, "INCR", False); - multiple_atom = XInternAtom(x_display, "MULTIPLE", False); - targets_atom = XInternAtom(x_display, "TARGETS", False); - for(i = 0; i < clipboard_format_count; i++) { - for(j = 0; clipboard_formats[i].atom_names[j]; j++) { - clipboard_formats[i].atoms[j] = - XInternAtom(x_display, clipboard_formats[i].atom_names[j], - False); - } - clipboard_formats[i].atom_count = j; - } - - XUnlockDisplay(x_display); - - interned = true; -} - -DynamicScreen::DynamicScreen(Display* display, int screen, int& next_mon_id) - : XScreen(display, screen) - , Monitor(next_mon_id++) - , _saved_width (get_width()) - , _saved_height (get_height()) - , _out_of_sync (false) -{ - if (platform_win != 0) - return; - - X_DEBUG_SYNC(display); - //FIXME: replace RootWindow() in other refs as well? - XLockDisplay(display); - platform_win = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 1, 1, 0, 0, 0); - XUnlockDisplay(display); - - LOG_INFO("platform_win: %u", (unsigned int)platform_win); - intern_clipboard_atoms(); - XSelectInput(display, platform_win, StructureNotifyMask); - XRRSelectInput(display, platform_win, RRScreenChangeNotifyMask); - if (using_xfixes_1_0) { - XFixesSelectSelectionInput(display, platform_win, clipboard_prop, - XFixesSetSelectionOwnerNotifyMask| - XFixesSelectionWindowDestroyNotifyMask| - XFixesSelectionClientCloseNotifyMask); - } - - Monitor::self_monitors_change++; - process_monitor_configure_events(platform_win); - Monitor::self_monitors_change--; - - XPlatform::set_win_proc(platform_win, root_win_proc); - X_DEBUG_SYNC(display); -} - -DynamicScreen::~DynamicScreen() -{ - restore(); -} - -void DynamicScreen::publish_monitors(MonitorsList& monitors) -{ - monitors.push_back(this); -} - -class SizeInfo { -public: - SizeInfo(int int_index, XRRScreenSize* in_size) : index (int_index), size (in_size) {} - - int index; - XRRScreenSize* size; -}; - -class SizeCompare { -public: - bool operator () (const SizeInfo& size1, const SizeInfo& size2) const - { - int area1 = size1.size->width * size1.size->height; - int area2 = size2.size->width * size2.size->height; - return area1 < area2 || (area1 == area2 && size1.index < size2.index); - } -}; - -void DynamicScreen::do_set_mode(int width, int height) -{ - int num_sizes; - - X_DEBUG_SYNC(get_display()); - - XLockDisplay(get_display()); - XRRScreenSize* sizes = XRRSizes(get_display(), get_screen(), &num_sizes); - XUnlockDisplay(get_display()); - - typedef std::set<SizeInfo, SizeCompare> SizesSet; - SizesSet sizes_set; - - for (int i = 0; i < num_sizes; i++) { - if (sizes[i].width >= width && sizes[i].height >= height) { - sizes_set.insert(SizeInfo(i, &sizes[i])); - } - } - _out_of_sync = true; - if (!sizes_set.empty() && set_screen_size((*sizes_set.begin()).index)) { - _out_of_sync = false; - } - X_DEBUG_SYNC(get_display()); -} - -void DynamicScreen::do_restore() -{ - X_DEBUG_SYNC(get_display()); - if (is_broken() || (get_width() == _saved_width && get_height() == _saved_height)) { - return; - } - int num_sizes; - - XLockDisplay(get_display()); - XRRScreenSize* sizes = XRRSizes(get_display(), get_screen(), &num_sizes); - XUnlockDisplay(get_display()); - - for (int i = 0; i < num_sizes; i++) { - if (sizes[i].width == _saved_width && sizes[i].height == _saved_height) { - set_screen_size(i); - return; - } - } - X_DEBUG_SYNC(get_display()); - LOG_WARN("can't find startup mode"); -} - -bool DynamicScreen::set_screen_size(int size_index) -{ - X_DEBUG_SYNC(get_display()); - Window root_window = RootWindow(get_display(), get_screen()); - XRRScreenConfiguration* config; - - XLockDisplay(get_display()); - config = XRRGetScreenInfo(get_display(), root_window); - XUnlockDisplay(get_display()); - - if (!config) { - LOG_WARN("get screen info failed"); - return false; - } - Rotation rotation; - XRRConfigCurrentConfiguration(config, &rotation); - - Monitor::self_monitors_change++; - XLockDisplay(get_display()); - /*what status*/ - XRRSetScreenConfig(get_display(), config, root_window, size_index, rotation, CurrentTime); - XUnlockDisplay(get_display()); - process_monitor_configure_events(platform_win); - Monitor::self_monitors_change--; - XRRFreeScreenConfigInfo(config); - X_DEBUG_SYNC(get_display()); - - int num_sizes; - - XLockDisplay(get_display()); - XRRScreenSize* sizes = XRRSizes(get_display(), get_screen(), &num_sizes); - XUnlockDisplay(get_display()); - - if (num_sizes <= size_index) { - THROW("invalid sizes size"); - } - set_width(sizes[size_index].width); - set_height(sizes[size_index].height); - return true; -} - -#ifdef USE_XINERAMA_1_0 - -class XineramaMonitor; -typedef std::list<XineramaMonitor*> XineramaMonitorsList; - -class XineramaScreen : public XScreen { -public: - XineramaScreen(Display* display, int screen, int& next_mon_id, XineramaScreenInfo* xin_screens, - int num_xin_screens); - virtual ~XineramaScreen(); - - void publish_monitors(MonitorsList& monitors); - -private: - XineramaMonitorsList _monitors; -}; - -class XineramaMonitor : public Monitor { -public: - XineramaMonitor(int id, XineramaScreenInfo& xin_screen); - - virtual void do_set_mode(int width, int height); - virtual void do_restore() {} - virtual int get_depth() { return 32;} - virtual SpicePoint get_position() { return _position;} - virtual SpicePoint get_size() const { return _size;} - virtual bool is_out_of_sync() { return _out_of_sync;} - virtual int get_screen_id() { return 0;} - -private: - SpicePoint _position; - SpicePoint _size; - bool _out_of_sync; -}; - -XineramaScreen::XineramaScreen(Display* display, int screen, int& next_mon_id, - XineramaScreenInfo* xin_screens, int num_xin_screens) - : XScreen(display, screen) -{ - X_DEBUG_SYNC(display); - for (int i = 0; i < num_xin_screens; i++) { - _monitors.push_back(new XineramaMonitor(next_mon_id++, xin_screens[i])); - } - Window root_window = RootWindow(display, screen); - XSelectInput(display, root_window, StructureNotifyMask); - XRRSelectInput(display, root_window, RRScreenChangeNotifyMask); // TODO: this fails if we don't have RR extension (but do have XINERAMA) - XPlatform::set_win_proc(root_window, root_win_proc); // Xlib: extension "RANDR" missing on display ":3.0". - X_DEBUG_SYNC(display); -} - -XineramaScreen::~XineramaScreen() -{ - while (!_monitors.empty()) { - XineramaMonitor* monitor = _monitors.front(); - _monitors.pop_front(); - delete monitor; - } -} - -void XineramaScreen::publish_monitors(MonitorsList& monitors) -{ - XineramaMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - monitors.push_back(*iter); - } -} - -XineramaMonitor::XineramaMonitor(int id, XineramaScreenInfo& screen_info) - : Monitor(id) - , _out_of_sync (false) -{ - _position.x = screen_info.x_org; - _position.y = screen_info.y_org; - _size.x = screen_info.width; - _size.y = screen_info.height; -} - - -void XineramaMonitor::do_set_mode(int width, int height) -{ - _out_of_sync = width > _size.x || height > _size.y; -} - -#endif - -#ifdef USE_XRANDR_1_2 - -class MultyMonScreen: public XScreen { -public: - MultyMonScreen(Display* display, int screen, int& next_mon_id); - virtual ~MultyMonScreen(); - - virtual void publish_monitors(MonitorsList& monitors); - - void disable(); - void enable(); - void restore(); - - bool set_monitor_mode(XMonitor& monitor, const XRRModeInfo& mode_info); - -private: - void set_size(int width, int height); - void get_trans_size(int& width, int& hight); - SpicePoint get_trans_top_left(); - SpicePoint get_trans_bottom_right(); - bool changed(); - - XMonitor* crtc_overlap_test(int x, int y, int width, int height); - void monitors_cleanup(); - -private: - int _min_width; - int _min_height; - int _max_width; - int _max_height; - int _saved_width; - int _saved_height; - int _saved_width_mm; - int _saved_height_mm; - XMonitorsList _monitors; -}; - -#define MAX_TRANS_DEPTH 3 - -class XMonitor: public Monitor { -public: - XMonitor(MultyMonScreen& container, int id, RRCrtc crtc); - virtual ~XMonitor(); - - virtual int get_depth(); - virtual SpicePoint get_position(); - virtual SpicePoint get_size() const; - virtual bool is_out_of_sync(); - virtual int get_screen_id() { return _container.get_screen();} - - void add_clone(XMonitor *clone); - void revert(); - void disable(); - void enable(); - - void set_mode(const XRRModeInfo& mode); - const SpiceRect& get_prev_area(); - SpiceRect& get_trans_area(); - void pin() { _pin_count++;} - void unpin() { ASSERT(_pin_count > 0); _pin_count--;} - bool is_pinned() {return !!_pin_count;} - void commit_trans_position(); - void set_pusher(XMonitor& pusher) { _pusher = &pusher;} - XMonitor* get_pusher() { return _pusher;} - void push_trans(); - void begin_trans(); - bool mode_changed(); - bool position_changed(); - - static void inc_change_ref() { Monitor::self_monitors_change++;} - static void dec_change_ref() { Monitor::self_monitors_change--;} - -protected: - virtual void do_set_mode(int width, int height); - virtual void do_restore(); - -private: - void update_position(); - bool find_mode_in_outputs(RRMode mode, int start_index, XRRScreenResources* res); - bool find_mode_in_clones(RRMode mode, XRRScreenResources* res); - XRRModeInfo* find_mode(unsigned int width, unsigned int height, XRRScreenResources* res); - -private: - MultyMonScreen& _container; - RRCrtc _crtc; - XMonitorsList _clones; - SpicePoint _position; - SpicePoint _size; - RRMode _mode; - Rotation _rotation; - int _noutput; - RROutput* _outputs; - - SpicePoint _saved_position; - SpicePoint _saved_size; - RRMode _saved_mode; - Rotation _saved_rotation; - - bool _out_of_sync; - RedScreenRotation _red_rotation; - RedSubpixelOrder _subpixel_order; - - int _trans_depth; - SpiceRect _trans_area[MAX_TRANS_DEPTH]; - int _pin_count; - XMonitor* _pusher; -}; - -MultyMonScreen::MultyMonScreen(Display* display, int screen, int& next_mon_id) - : XScreen(display, screen) - , _saved_width (get_width()) - , _saved_height (get_height()) - , _saved_width_mm (DisplayWidthMM(display, screen)) - , _saved_height_mm (DisplayHeightMM(display, screen)) -{ - X_DEBUG_SYNC(get_display()); - Window root_window = RootWindow(display, screen); - - XLockDisplay(display); - XRRGetScreenSizeRange(display, root_window, &_min_width, &_min_height, - &_max_width, &_max_height); - AutoScreenRes res(XRRGetScreenResources(display, root_window)); - XUnlockDisplay(display); - - if (!res.valid()) { - THROW("get screen resources failed"); - } - -#ifdef SHOW_SCREEN_INFO - show_scren_info(); -#endif - XLockDisplay(display); - try { - for (int i = 0; i < res->ncrtc; i++) { - AutoCrtcInfo crtc_info(XRRGetCrtcInfo(display, res.get(), res->crtcs[i])); - - if (!crtc_info.valid()) { - THROW("get crtc info failed"); - } - - if (crtc_info->mode == None) { - continue; - } - - ASSERT(crtc_info->noutput); - - XMonitor* clone_mon = crtc_overlap_test(crtc_info->x, crtc_info->y, - crtc_info->width, crtc_info->height); - - if (clone_mon) { - clone_mon->add_clone(new XMonitor(*this, next_mon_id++, res->crtcs[i])); - continue; - } - - _monitors.push_back(new XMonitor(*this, next_mon_id++, res->crtcs[i])); - } - XUnlockDisplay(display); - } catch (...) { - XUnlockDisplay(display); - monitors_cleanup(); - throw; - } - - if (platform_win != 0) - return; - - XLockDisplay(display); - platform_win = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 1, 1, 0, 0, 0); - XUnlockDisplay(display); - - LOG_INFO("platform_win: %u", (unsigned int)platform_win); - intern_clipboard_atoms(); - XSelectInput(display, platform_win, StructureNotifyMask); - X_DEBUG_SYNC(get_display()); - XRRSelectInput(display, platform_win, RRScreenChangeNotifyMask); - X_DEBUG_SYNC(get_display()); - if (using_xfixes_1_0) { - XFixesSelectSelectionInput(display, platform_win, clipboard_prop, - XFixesSetSelectionOwnerNotifyMask| - XFixesSelectionWindowDestroyNotifyMask| - XFixesSelectionClientCloseNotifyMask); - } - - XMonitor::inc_change_ref(); - process_monitor_configure_events(platform_win); - XMonitor::dec_change_ref(); - - XPlatform::set_win_proc(platform_win, root_win_proc); - X_DEBUG_SYNC(get_display()); -} - -MultyMonScreen::~MultyMonScreen() -{ - restore(); - monitors_cleanup(); -} - -XMonitor* MultyMonScreen::crtc_overlap_test(int x, int y, int width, int height) -{ - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - XMonitor* mon = *iter; - - SpicePoint pos = mon->get_position(); - SpicePoint size = mon->get_size(); - - if (x == pos.x && y == pos.y && width == size.x && height == size.y) { - return mon; - } - - if (x < pos.x + size.x && x + width > pos.x && y < pos.y + size.y && y + height > pos.y) { - THROW("unsupported partial overlap"); - } - } - return NULL; -} - -void MultyMonScreen::publish_monitors(MonitorsList& monitors) -{ - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - monitors.push_back(*iter); - } -} - -void MultyMonScreen::monitors_cleanup() -{ - while (!_monitors.empty()) { - XMonitor* monitor = _monitors.front(); - _monitors.pop_front(); - delete monitor; - } -} - -void MultyMonScreen::disable() -{ - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - (*iter)->disable(); - } -} - -void MultyMonScreen::enable() -{ - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - (*iter)->enable(); - } -} - -void MultyMonScreen::set_size(int width, int height) -{ - X_DEBUG_SYNC(get_display()); - Window root_window = RootWindow(get_display(), get_screen()); - set_width(width); - int width_mm = (int)((double)_saved_width_mm / _saved_width * width); - set_height(height); - int height_mm = (int)((double)_saved_height_mm / _saved_height * height); - XLockDisplay(get_display()); - XRRSetScreenSize(get_display(), root_window, width, height, width_mm, height_mm); - XUnlockDisplay(get_display()); - X_DEBUG_SYNC(get_display()); -} - -bool MultyMonScreen::changed() -{ - if (get_width() != _saved_width || get_height() != _saved_height) { - return true; - } - - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - if ((*iter)->mode_changed() || (*iter)->position_changed()) { - return true; - } - } - return false; -} - -void MultyMonScreen::restore() -{ - if (is_broken() || !changed()) { - return; - } - X_DEBUG_SYNC(get_display()); - XMonitor::inc_change_ref(); - disable(); - set_size(_saved_width, _saved_height); - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - (*iter)->revert(); - } - enable(); - process_monitor_configure_events(platform_win); - XMonitor::dec_change_ref(); - X_DEBUG_SYNC(get_display()); -} - -SpicePoint MultyMonScreen::get_trans_top_left() -{ - SpicePoint position; - position.y = position.x = MAXINT; - - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - SpiceRect& area = (*iter)->get_trans_area(); - position.x = MIN(position.x, area.left); - position.y = MIN(position.y, area.top); - } - return position; -} - -SpicePoint MultyMonScreen::get_trans_bottom_right() -{ - SpicePoint position; - position.y = position.x = MININT; - - XMonitorsList::iterator iter = _monitors.begin(); - for (; iter != _monitors.end(); iter++) { - SpiceRect& area = (*iter)->get_trans_area(); - position.x = MAX(position.x, area.right); - position.y = MAX(position.y, area.bottom); - } - return position; -} - -void MultyMonScreen::get_trans_size(int& width, int& height) -{ - ASSERT(get_trans_top_left().x == 0 && get_trans_top_left().y == 0); - SpicePoint bottom_right = get_trans_bottom_right(); - ASSERT(bottom_right.x > 0 && bottom_right.y > 0); - width = bottom_right.x; - height = bottom_right.y; -} - -#endif - -/*class Variant { - static void get_area_in_front(const SpiceRect& base, int size, SpiceRect& area) - static int get_push_distance(const SpiceRect& fix_area, const SpiceRect& other) - static int get_head(const SpiceRect& area) - static int get_tail(const SpiceRect& area) - static void move_head(SpiceRect& area, int delta) - static int get_pull_distance(const SpiceRect& fix_area, const SpiceRect& other) - static void offset(SpiceRect& area, int delta) - static void shrink(SpiceRect& area, int delta) - static int get_distance(const SpiceRect& area, const SpiceRect& other_area) - static bool is_on_tail(const SpiceRect& area, const SpiceRect& other_area) - static bool is_on_perpendiculars(const SpiceRect& area, const SpiceRect& other_area) -}*/ - -#ifdef USE_XRANDR_1_2 - -class SortRightToLeft { -public: - bool operator () (XMonitor* mon1, XMonitor* mon2) const - { - return mon1->get_trans_area().right > mon2->get_trans_area().right; - } -}; - -typedef std::multiset<XMonitor*, SortRightToLeft> PushLeftSet; - -class LeftVariant { -public: - - static void get_area_in_front(const SpiceRect& base, int size, SpiceRect& area) - { - area.right = base.left; - area.left = area.right - size; - area.bottom = base.bottom; - area.top = base.top; - } - - static int get_push_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return other.right - fix_area.left; - } - - static int get_head(const SpiceRect& area) - { - return area.left; - } - - static int get_tail(const SpiceRect& area) - { - return area.right; - } - - static void move_head(SpiceRect& area, int delta) - { - area.left -= delta; - ASSERT(area.right >= area.left); - } - - static int get_pull_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return other.left - fix_area.right; - } - - static void offset(SpiceRect& area, int delta) - { - rect_offset(area, -delta, 0); - } - - static void shrink(SpiceRect& area, int delta) - { - area.right -= delta; - ASSERT(area.right > area.left); - } - - static int get_distance(const SpiceRect& area, const SpiceRect& other_area) - { - return other_area.left - area.left; - } - - static bool is_on_tail(const SpiceRect& area, const SpiceRect& other_area) - { - return area.right == other_area.left && other_area.top < area.bottom && - other_area.bottom > area.top; - } - - static bool is_on_perpendiculars(const SpiceRect& area, const SpiceRect& other_area) - { - return (other_area.bottom == area.top || other_area.top == area.bottom) && - other_area.left < area.right && other_area.right > area.left; - } -}; - -class SortLeftToRight { -public: - bool operator () (XMonitor* mon1, XMonitor* mon2) const - { - return mon1->get_trans_area().left < mon2->get_trans_area().left; - } -}; - -typedef std::multiset<XMonitor*, SortLeftToRight> PushRightSet; - -class RightVariant { -public: - - static void get_area_in_front(const SpiceRect& base, int size, SpiceRect& area) - { - area.left = base.right; - area.right = area.left + size; - area.top = base.top; - area.bottom = base.bottom; - } - - static int get_push_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return fix_area.right - other.left; - } - - static int get_head(const SpiceRect& area) - { - return area.right; - } - - static int get_tail(const SpiceRect& area) - { - return area.left; - } - - static void move_head(SpiceRect& area, int delta) - { - area.right += delta; - ASSERT(area.right >= area.left); - } - - static int get_pull_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return fix_area.left - other.right; - } - - static void offset(SpiceRect& area, int delta) - { - rect_offset(area, delta, 0); - } - - static bool is_on_tail(const SpiceRect& area, const SpiceRect& other_area) - { - return other_area.right == area.left && other_area.top < area.bottom && - other_area.bottom > area.top; - } - - static bool is_on_perpendiculars(const SpiceRect& area, const SpiceRect& other_area) - { - return (other_area.bottom == area.top || other_area.top == area.bottom) && - other_area.left < area.right && other_area.right > area.left; - } -}; - -class SortBottomToTop { -public: - bool operator () (XMonitor* mon1, XMonitor* mon2) const - { - return mon1->get_trans_area().bottom > mon2->get_trans_area().bottom; - } -}; - -typedef std::multiset<XMonitor*, SortBottomToTop> PushTopSet; - -class TopVariant { -public: - static void get_area_in_front(const SpiceRect& base, int size, SpiceRect& area) - { - area.left = base.left; - area.right = base.right; - area.bottom = base.top; - area.top = area.bottom - size; - } - - static int get_push_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return other.bottom - fix_area.top; - } - - static int get_head(const SpiceRect& area) - { - return area.top; - } - - static int get_tail(const SpiceRect& area) - { - return area.bottom; - } - - static void move_head(SpiceRect& area, int delta) - { - area.top -= delta; - ASSERT(area.bottom >= area.top); - } - - static int get_pull_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return other.top - fix_area.bottom; - } - - static void offset(SpiceRect& area, int delta) - { - rect_offset(area, 0, -delta); - } - - static void shrink(SpiceRect& area, int delta) - { - area.bottom -= delta; - ASSERT(area.bottom > area.top); - } - - static int get_distance(const SpiceRect& area, const SpiceRect& other_area) - { - return other_area.top - area.top; - } - - static bool is_on_tail(const SpiceRect& area, const SpiceRect& other_area) - { - return area.bottom == other_area.top && other_area.left < area.right && - other_area.right > area.left; - } - - static bool is_on_perpendiculars(const SpiceRect& area, const SpiceRect& other_area) - { - return (other_area.right == area.left || other_area.left == area.right) && - other_area.top < area.bottom && other_area.bottom > area.top; - } -}; - -class SortTopToBottom { -public: - bool operator () (XMonitor* mon1, XMonitor* mon2) const - { - return mon1->get_trans_area().top < mon2->get_trans_area().top; - } -}; - -typedef std::multiset<XMonitor*, SortTopToBottom> PushBottomSet; - -class BottomVariant { -public: - - static void get_area_in_front(const SpiceRect& base, int size, SpiceRect& area) - { - area.left = base.left; - area.right = base.right; - area.top = base.bottom; - area.bottom = area.top + size; - } - - static int get_push_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return fix_area.bottom - other.top; - } - - static int get_head(const SpiceRect& area) - { - return area.bottom; - } - - static int get_tail(const SpiceRect& area) - { - return area.top; - } - - static void move_head(SpiceRect& area, int delta) - { - area.bottom += delta; - ASSERT(area.bottom >= area.top); - } - - static int get_pull_distance(const SpiceRect& fix_area, const SpiceRect& other) - { - return fix_area.top - other.bottom; - } - - static void offset(SpiceRect& area, int delta) - { - rect_offset(area, 0, delta); - } - - static bool is_on_tail(const SpiceRect& area, const SpiceRect& other_area) - { - return other_area.bottom == area.top && other_area.left < area.right && - other_area.right > area.left; - } - - static bool is_on_perpendiculars(const SpiceRect& area, const SpiceRect& other_area) - { - return (other_area.right == area.left || other_area.left == area.right) && - other_area.top < area.bottom && other_area.bottom > area.top; - } -}; - -volatile int wait_for_me = false; - -template <class Variant> -static void bounce_back(XMonitor& monitor, const XMonitorsList& monitors, int head, int distance) -{ - ASSERT(distance > 0); - while (wait_for_me); - - for (XMonitorsList::const_iterator iter = monitors.begin(); iter != monitors.end(); iter++) { - SpiceRect& area = (*iter)->get_trans_area(); - if (Variant::get_tail(area) == head && (*iter)->get_pusher() == &monitor) { - Variant::offset(area, -distance); - bounce_back<Variant>(**iter, monitors, Variant::get_head(area) + distance, distance); - //todo: pull_back monitors on perpendiculars - } - } -} - -template <class Variant, class SortList, class SortListIter> -static int push(XMonitor& pusher, XMonitor& monitor, const XMonitorsList& monitors, int delta) -{ - monitor.pin(); - monitor.set_pusher(pusher); - - SortList sort; - XMonitorsList::const_iterator iter = monitors.begin(); - for (; iter != monitors.end(); iter++) { - if (*iter == &monitor) { - continue; - } - sort.insert(*iter); - } - - SpiceRect area_to_clear; - Variant::get_area_in_front(monitor.get_trans_area(), delta, area_to_clear); - - SortListIter sort_iter = sort.begin(); - - for (; sort_iter != sort.end(); sort_iter++) { - const SpiceRect& other_area = (*sort_iter)->get_trans_area(); - - if (rect_intersects(area_to_clear, other_area)) { - int distance = Variant::get_push_distance(area_to_clear, other_area); - ASSERT(distance > 0); - if (!(*sort_iter)->is_pinned()) { - distance = distance - push<Variant, SortList, SortListIter>(monitor, **sort_iter, - monitors, distance); - } - - if (distance) { - delta -= distance; - bounce_back<Variant>(monitor, monitors, Variant::get_head(area_to_clear), distance); - Variant::move_head(area_to_clear, -distance); - } - } - } - Variant::offset(monitor.get_trans_area(), delta); - - const SpiceRect& area = monitor.get_prev_area(); - for (iter = monitors.begin(); iter != monitors.end(); iter++) { - if ((*iter)->is_pinned()) { - continue; - } - - const SpiceRect& other_area = (*iter)->get_prev_area(); - if (Variant::is_on_perpendiculars(area, other_area)) { - int current_distance = Variant::get_pull_distance(monitor.get_trans_area(), - (*iter)->get_trans_area()); - int base_distance = Variant::get_pull_distance(area, other_area); - int distance = current_distance - base_distance; - if (distance > 0) { - push<Variant, SortList, SortListIter>(monitor, **iter, monitors, distance); - } - } else if (Variant::is_on_tail(area, other_area)) { - int distance = Variant::get_pull_distance(monitor.get_trans_area(), - (*iter)->get_trans_area()); - ASSERT(distance >= 0); - push<Variant, SortList, SortListIter>(monitor, **iter, monitors, distance); - } - } - return delta; -} - -template <class Variant> -static void pin(XMonitor& monitor, const XMonitorsList& monitors) -{ - const SpiceRect& area = monitor.get_trans_area(); - - for (XMonitorsList::const_iterator iter = monitors.begin(); iter != monitors.end(); iter++) { - const SpiceRect& other_area = (*iter)->get_trans_area(); - if ((*iter)->is_pinned()) { - continue; - } - if (Variant::is_on_tail(other_area, area) || - Variant::is_on_perpendiculars(area, other_area)) { - (*iter)->pin(); - pin<Variant>(**iter, monitors); - } - } -} - -template <class Variant, class SortList, class SortListIter> -static void shrink(XMonitor& monitor, const XMonitorsList& monitors, int delta) -{ - monitor.pin(); - pin<Variant>(monitor, monitors); - ASSERT(delta > 0); - - SortList sort; - XMonitorsList::const_iterator iter = monitors.begin(); - for (; iter != monitors.end(); iter++) { - if (*iter == &monitor) { - continue; - } - sort.insert(*iter); - } - - const SpiceRect area = monitor.get_trans_area(); - Variant::shrink(monitor.get_trans_area(), delta); - for (SortListIter sort_iter = sort.begin(); sort_iter != sort.end(); sort_iter++) { - const SpiceRect& other_area = (*sort_iter)->get_trans_area(); - if (Variant::is_on_perpendiculars(area, other_area)) { - int distance = Variant::get_distance(area, other_area); - if (distance > 0) { - distance = MIN(distance, delta); - push<Variant, SortList, SortListIter>(monitor, **sort_iter, monitors, distance); - } - } else if (Variant::is_on_tail(area, other_area)) { - push<Variant, SortList, SortListIter>(monitor, **sort_iter, monitors, delta); - } - } -} - -template <class Variant, class SortList, class SortListIter> -static void expand(XMonitor& monitor, const XMonitorsList& monitors, int delta) -{ - monitor.pin(); - ASSERT(delta > 0); - - SortList sort; - XMonitorsList::const_iterator iter = monitors.begin(); - for (; iter != monitors.end(); iter++) { - if (*iter == &monitor) { - continue; - } - sort.insert(*iter); - } - - SpiceRect area_to_clear; - Variant::get_area_in_front(monitor.get_trans_area(), delta, area_to_clear); - - for (SortListIter sort_iter = sort.begin(); sort_iter != sort.end(); sort_iter++) { - const SpiceRect& other_area = (*sort_iter)->get_trans_area(); - - if (rect_intersects(area_to_clear, other_area)) { - int distance = Variant::get_push_distance(area_to_clear, other_area); - ASSERT(distance > 0); - ASSERT(!(*sort_iter)->is_pinned()); -#ifdef RED_DEBUG - int actual = -#endif - push<Variant, SortList, SortListIter>(monitor, **sort_iter, monitors, distance); - ASSERT(actual == distance); - } - } - Variant::move_head(monitor.get_trans_area(), delta); -} - -bool MultyMonScreen::set_monitor_mode(XMonitor& monitor, const XRRModeInfo& mode_info) -{ - if (is_broken()) { - return false; - } - - SpicePoint size = monitor.get_size(); - int dx = mode_info.width - size.x; - int dy = mode_info.height - size.y; - - XMonitorsList::iterator iter = _monitors.begin(); - - for (; iter != _monitors.end(); iter++) { - (*iter)->begin_trans(); - } - - if (dx > 0) { - expand<RightVariant, PushRightSet, PushRightSet::iterator>(monitor, _monitors, dx); - } else if (dx < 0) { - shrink<LeftVariant, PushLeftSet, PushLeftSet::iterator>(monitor, _monitors, -dx); - } - - for (iter = _monitors.begin(); iter != _monitors.end(); iter++) { - (*iter)->push_trans(); - } - - if (dy > 0) { - expand<BottomVariant, PushBottomSet, PushBottomSet::iterator>(monitor, _monitors, dy); - } else if (dy < 0) { - shrink<TopVariant, PushTopSet, PushTopSet::iterator>(monitor, _monitors, -dy); - } - - int screen_width; - int screen_height; - - get_trans_size(screen_width, screen_height); - - if (screen_width > _max_width || screen_height > _max_height) { - return false; - } - - screen_width = MAX(screen_width, _min_width); - screen_height = MAX(screen_height, _min_height); - - XMonitor::inc_change_ref(); - disable(); - for (iter = _monitors.begin(); iter != _monitors.end(); iter++) { - (*iter)->commit_trans_position(); - } - X_DEBUG_SYNC(get_display()); - monitor.set_mode(mode_info); - set_size(screen_width, screen_height); - enable(); - process_monitor_configure_events(platform_win); - XMonitor::dec_change_ref(); - X_DEBUG_SYNC(get_display()); - return true; -} - -XMonitor::XMonitor(MultyMonScreen& container, int id, RRCrtc crtc) - : Monitor(id) - , _container (container) - , _crtc (crtc) - , _out_of_sync (false) -{ - update_position(); - _saved_position = _position; - _saved_size = _size; - _saved_mode = _mode; - _saved_rotation = _rotation; -} - -XMonitor::~XMonitor() -{ - while (!_clones.empty()) { - XMonitor* clone = _clones.front(); - _clones.pop_front(); - delete clone; - } - delete[] _outputs; -} - -void XMonitor::update_position() -{ - Display* display = _container.get_display(); - X_DEBUG_SYNC(display); - Window root_window = RootWindow(display, _container.get_screen()); - - XLockDisplay(display); - AutoScreenRes res(XRRGetScreenResources(display, root_window)); - XUnlockDisplay(display); - - if (!res.valid()) { - THROW("get screen resources failed"); - } - - XLockDisplay(display); - AutoCrtcInfo crtc_info(XRRGetCrtcInfo(display, res.get(), _crtc)); - XUnlockDisplay(display); - - ASSERT(crtc_info->noutput); - - _position.x = crtc_info->x; - _position.y = crtc_info->y; - _size.x = crtc_info->width; - _size.y = crtc_info->height; - - switch (crtc_info->rotation & 0xf) { - case RR_Rotate_0: - _red_rotation = RED_SCREEN_ROTATION_0; - break; - case RR_Rotate_90: - _red_rotation = RED_SCREEN_ROTATION_90; - break; - case RR_Rotate_180: - _red_rotation = RED_SCREEN_ROTATION_180; - break; - case RR_Rotate_270: - _red_rotation = RED_SCREEN_ROTATION_270; - break; - default: - THROW("invalid rotation"); - } - - if (crtc_info->noutput > 1) { - //todo: set valid subpixel order in case all outputs share the same type - _subpixel_order = RED_SUBPIXEL_ORDER_UNKNOWN; - } else { - XLockDisplay(display); - AutoOutputInfo output_info(XRRGetOutputInfo(display, res.get(), crtc_info->outputs[0])); - XUnlockDisplay(display); - - switch (output_info->subpixel_order) { - case SubPixelUnknown: - _subpixel_order = RED_SUBPIXEL_ORDER_UNKNOWN; - break; - case SubPixelHorizontalRGB: - _subpixel_order = RED_SUBPIXEL_ORDER_H_RGB; - break; - case SubPixelHorizontalBGR: - _subpixel_order = RED_SUBPIXEL_ORDER_H_BGR; - break; - case SubPixelVerticalRGB: - _subpixel_order = RED_SUBPIXEL_ORDER_V_RGB; - break; - case SubPixelVerticalBGR: - _subpixel_order = RED_SUBPIXEL_ORDER_V_BGR; - break; - case SubPixelNone: - _subpixel_order = RED_SUBPIXEL_ORDER_NONE; - break; - default: - THROW("invalid subpixel order"); - } - } - - _mode = crtc_info->mode; - _rotation = crtc_info->rotation; - _noutput = crtc_info->noutput; - _outputs = new RROutput[_noutput]; - memcpy(_outputs, crtc_info->outputs, _noutput * sizeof(RROutput)); - X_DEBUG_SYNC(display); -} - -bool XMonitor::find_mode_in_outputs(RRMode mode, int start_index, XRRScreenResources* res) -{ - int i, j; - bool retval = true; - - X_DEBUG_SYNC(_container.get_display()); - XLockDisplay(_container.get_display()); - for (i = start_index; i < _noutput; i++) { - AutoOutputInfo output_info(XRRGetOutputInfo(_container.get_display(), res, _outputs[i])); - for (j = 0; j < output_info->nmode; j++) { - if (output_info->modes[j] == mode) { - break; - } - } - if (j == output_info->nmode) { - retval = false; - break; - } - } - XUnlockDisplay(_container.get_display()); - X_DEBUG_SYNC(_container.get_display()); - return retval; -} - -bool XMonitor::find_mode_in_clones(RRMode mode, XRRScreenResources* res) -{ - XMonitorsList::iterator iter = _clones.begin(); - for (; iter != _clones.end(); iter++) { - if (!(*iter)->find_mode_in_outputs(mode, 0, res)) { - return false; - } - } - return true; -} - -class ModeInfo { -public: - ModeInfo(int int_index, XRRModeInfo* in_info) : index (int_index), info (in_info) {} - - int index; - XRRModeInfo* info; -}; - -class ModeCompare { -public: - bool operator () (const ModeInfo& mode1, const ModeInfo& mode2) const - { - int area1 = mode1.info->width * mode1.info->height; - int area2 = mode2.info->width * mode2.info->height; - return area1 < area2 || (area1 == area2 && mode1.index < mode2.index); - } -}; - -XRRModeInfo* XMonitor::find_mode(unsigned int width, unsigned int height, XRRScreenResources* res) -{ - typedef std::set<ModeInfo, ModeCompare> ModesSet; - ModesSet modes_set; - X_DEBUG_SYNC(_container.get_display()); - - XLockDisplay(_container.get_display()); - AutoOutputInfo output_info(XRRGetOutputInfo(_container.get_display(), res, _outputs[0])); - XUnlockDisplay(_container.get_display()); - - for (int i = 0; i < output_info->nmode; i++) { - XRRModeInfo* mode_inf = find_mod(res, output_info->modes[i]); - if (mode_inf->width >= width && mode_inf->height >= height) { - modes_set.insert(ModeInfo(i, mode_inf)); - } - } - - while (!modes_set.empty()) { - ModesSet::iterator iter = modes_set.begin(); - - if (!find_mode_in_outputs((*iter).info->id, 1, res)) { - modes_set.erase(iter); - continue; - } - - if (!find_mode_in_clones((*iter).info->id, res)) { - modes_set.erase(iter); - continue; - } - return (*iter).info; - } - X_DEBUG_SYNC(_container.get_display()); - return NULL; -} - -void XMonitor::do_set_mode(int width, int height) -{ - if (width == _size.x && height == _size.y) { - _out_of_sync = false; - return; - } - Display* display = _container.get_display(); - X_DEBUG_SYNC(display); - Window root_window = RootWindow(display, _container.get_screen()); - - XLockDisplay(display); - AutoScreenRes res(XRRGetScreenResources(display, root_window)); - XUnlockDisplay(display); - - if (!res.valid()) { - THROW("get screen resource failed"); - } - XRRModeInfo* mode_info = find_mode(width, height, res.get()); - - if (!mode_info || !_container.set_monitor_mode(*this, *mode_info)) { - _out_of_sync = true; - X_DEBUG_SYNC(display); - return; - } - _out_of_sync = false; -} - -void XMonitor::revert() -{ - _position = _saved_position; - _size = _saved_size; - _mode = _saved_mode; - _rotation = _saved_rotation; - XMonitorsList::iterator iter = _clones.begin(); - for (; iter != _clones.end(); iter++) { - (*iter)->revert(); - } -} - -void XMonitor::disable() -{ - Display* display = _container.get_display(); - X_DEBUG_SYNC(display); - Window root_window = RootWindow(display, _container.get_screen()); - - XLockDisplay(display); - AutoScreenRes res(XRRGetScreenResources(display, root_window)); - XUnlockDisplay(display); - - if (!res.valid()) { - THROW("get screen resources failed"); - } - XLockDisplay(display); - XRRSetCrtcConfig(display, res.get(), _crtc, CurrentTime, - 0, 0, None, RR_Rotate_0, NULL, 0); - XUnlockDisplay(display); - - XMonitorsList::iterator iter = _clones.begin(); - for (; iter != _clones.end(); iter++) { - (*iter)->disable(); - } - XFlush(x_display); - X_DEBUG_SYNC(display); -} - -void XMonitor::enable() -{ - Display* display = _container.get_display(); - X_DEBUG_SYNC(display); - Window root_window = RootWindow(display, _container.get_screen()); - - XLockDisplay(display); - AutoScreenRes res(XRRGetScreenResources(display, root_window)); - XUnlockDisplay(display); - - if (!res.valid()) { - THROW("get screen resources failed"); - } - XLockDisplay(display); - XRRSetCrtcConfig(display, res.get(), _crtc, CurrentTime, - _position.x, _position.y, - _mode, _rotation, - _outputs, _noutput); - XUnlockDisplay(display); - - XMonitorsList::iterator iter = _clones.begin(); - for (; iter != _clones.end(); iter++) { - (*iter)->enable(); - } - XFlush(x_display); - X_DEBUG_SYNC(display); -} - -bool XMonitor::mode_changed() -{ - return _size.x != _saved_size.x || _size.y != _saved_size.y || - _mode != _saved_mode || _rotation != _saved_rotation; -} - -bool XMonitor::position_changed() -{ - return _position.x != _saved_position.x || _position.y != _saved_position.y; -} - -void XMonitor::do_restore() -{ - if (!mode_changed()) { - return; - } - _container.restore(); -} - -int XMonitor::get_depth() -{ - return XPlatform::get_vinfo()[0]->depth; -} - -SpicePoint XMonitor::get_position() -{ - return _position; -} - -SpicePoint XMonitor::get_size() const -{ - return _size; -} - -bool XMonitor::is_out_of_sync() -{ - return _out_of_sync; -} - -void XMonitor::add_clone(XMonitor *clone) -{ - _clones.push_back(clone); -} - -const SpiceRect& XMonitor::get_prev_area() -{ - return _trans_area[_trans_depth - 1]; -} - -SpiceRect& XMonitor::get_trans_area() -{ - return _trans_area[_trans_depth]; -} - -void XMonitor::push_trans() -{ - _trans_depth++; - ASSERT(_trans_depth < MAX_TRANS_DEPTH); - _trans_area[_trans_depth] = _trans_area[_trans_depth - 1]; - _pin_count = 0; - _pusher = NULL; -} - -void XMonitor::begin_trans() -{ - _trans_area[0].left = _position.x; - _trans_area[0].right = _trans_area[0].left + _size.x; - _trans_area[0].top = _position.y; - _trans_area[0].bottom = _trans_area[0].top + _size.y; - _trans_area[1] = _trans_area[0]; - _trans_depth = 1; - _pin_count = 0; - _pusher = NULL; -} - -void XMonitor::commit_trans_position() -{ - _position.x = _trans_area[_trans_depth].left; - _position.y = _trans_area[_trans_depth].top; - XMonitorsList::iterator iter = _clones.begin(); - for (; iter != _clones.end(); iter++) { - (*iter)->_position = _position; - } -} - -void XMonitor::set_mode(const XRRModeInfo& mode) -{ - _mode = mode.id; - _size.x = mode.width; - _size.y = mode.height; - XMonitorsList::iterator iter = _clones.begin(); - for (; iter != _clones.end(); iter++) { - (*iter)->set_mode(mode); - } -} - -#endif - -#ifdef USE_XINERAMA_1_0 - -static XineramaScreenInfo* init_xinerama_screens(int* num_xin_screens) -{ - XineramaScreenInfo* xin_screens = NULL; - - if (using_xinerama_1_0 && ScreenCount(x_display) == 1) { - int ncrtc = 0; -#ifdef USE_XRANDR_1_2 - if (using_xrandr_1_2) { - AutoScreenRes res(XRRGetScreenResources(x_display, RootWindow(x_display, 0))); - if (res.valid()) { - ncrtc = res->ncrtc; - } - } -#endif - if (ncrtc < 2) { - xin_screens = XineramaQueryScreens(x_display, num_xin_screens); - } - } - if (xin_screens && *num_xin_screens < 2) { - XFree(xin_screens); - return NULL; - } - return xin_screens; -} - -#endif - -static MonitorsList monitors; -static Monitor* primary_monitor = NULL; - -typedef std::list<XScreen*> ScreenList; -static ScreenList screens; - -const MonitorsList& Platform::init_monitors() -{ - int next_mon_id = 0; - ASSERT(screens.empty()); - -#ifdef USE_XINERAMA_1_0 - int num_xin_screens; - XineramaScreenInfo* xin_screens = init_xinerama_screens(&num_xin_screens); - if (xin_screens) { - screens.push_back(new XineramaScreen(x_display, 0, next_mon_id, xin_screens, num_xin_screens)); - XFree(xin_screens); - } else -#endif -#ifdef USE_XRANDR_1_2 - if (using_xrandr_1_2) { - for (int i = 0; i < ScreenCount(x_display); i++) { - screens.push_back(new MultyMonScreen(x_display, i, next_mon_id)); - } - } else -#endif - if (using_xrandr_1_0) { - for (int i = 0; i < ScreenCount(x_display); i++) { - screens.push_back(new DynamicScreen(x_display, i, next_mon_id)); - } - } else { - for (int i = 0; i < ScreenCount(x_display); i++) { - screens.push_back(new StaticScreen(x_display, i, next_mon_id)); - } - } - - ASSERT(monitors.empty()); - ScreenList::iterator iter = screens.begin(); - for (; iter != screens.end(); iter++) { - (*iter)->publish_monitors(monitors); - } - MonitorsList::iterator mon_iter = monitors.begin(); - for (; mon_iter != monitors.end(); mon_iter++) { - Monitor *mon = *mon_iter; - if (mon->get_id() == 0) { - primary_monitor = mon; - break; - } - } - return monitors; -} - -void Platform::destroy_monitors() -{ - primary_monitor = NULL; - monitors.clear(); - while (!screens.empty()) { - XScreen* screen = screens.front(); - screens.pop_front(); - delete screen; - } -} - -bool Platform::is_monitors_pos_valid() -{ - return (ScreenCount(x_display) == 1); -} - -void Platform::get_app_data_dir(std::string& path, const std::string& app_name) -{ - const char* home_dir = getenv("HOME"); - - if (!home_dir || strlen(home_dir) == 0) { - throw Exception("get home dir failed"); - } - - path = home_dir; - std::string::iterator end = path.end(); - - while (end != path.begin() && *(end - 1) == '/') { - path.erase(--end); - } - - path += "/."; - path += app_name; - - if (mkdir(path.c_str(), 0700) == -1 && errno != EEXIST) { - throw Exception("create appdata dir failed"); - } -} - -void Platform::path_append(std::string& path, const std::string& partial_path) -{ - path += "/"; - path += partial_path; -} - -static void ensure_clipboard_data_space(uint32_t size) -{ - if (size > clipboard_data_space) { - free(clipboard_data); - clipboard_data = (uint8_t *)malloc(size); - assert(clipboard_data); - clipboard_data_space = size; - } -} - -static void send_selection_notify(Atom prop, int process_next_req) -{ - XEvent res, *event = &next_selection_request->event; - selection_request *old_request; - - res.xselection.property = prop; - res.xselection.type = SelectionNotify; - res.xselection.display = event->xselectionrequest.display; - res.xselection.requestor = event->xselectionrequest.requestor; - res.xselection.selection = event->xselectionrequest.selection; - res.xselection.target = event->xselectionrequest.target; - res.xselection.time = event->xselectionrequest.time; - XSendEvent(x_display, event->xselectionrequest.requestor, 0, 0, &res); - XFlush(x_display); - - old_request = next_selection_request; - next_selection_request = next_selection_request->next; - delete old_request; - - if (process_next_req) - handle_selection_request(); -} - -static void print_targets(const char *action, Atom *atoms, int c) -{ - int i; - - LOG_INFO("%s %d targets:", action, c); - for (i = 0; i < c; i++) - LOG_INFO("%s", atom_name(atoms[i])); -} - -static void send_targets(XEvent& request_event) -{ - Atom targets[256] = { targets_atom, }; - int i, j, k, target_count = 1; - - for (i = 0; i < clipboard_type_count; i++) { - for (j = 0; j < clipboard_format_count; j++) { - if (clipboard_formats[j].type != clipboard_agent_types[i]) { - continue; - } - for (k = 0; k < clipboard_formats[j].atom_count; k++) { - targets[target_count] = clipboard_formats[j].atoms[k]; - target_count++; - if (target_count == sizeof(targets)/sizeof(Atom)) { - LOG_WARN("sendtargets: too many targets"); - goto exit_loop; - } - } - } - } -exit_loop: - - Window requestor_win = request_event.xselectionrequest.requestor; - Atom prop = request_event.xselectionrequest.property; - if (prop == None) - prop = request_event.xselectionrequest.target; - - XChangeProperty(x_display, requestor_win, prop, XA_ATOM, 32, - PropModeReplace, (unsigned char *)&targets, - target_count); - print_targets("sent", targets, target_count); - send_selection_notify(prop, 1); -} - -static int get_selection(XEvent &event, Atom type, Atom prop, int format, - unsigned char **data_ret, bool incr) -{ - Bool del = incr ? True: False; - Atom type_ret; - int res, format_ret, ret_val = -1; - unsigned long len, remain; - unsigned char *data = NULL; - - if (incr) { - if (event.xproperty.atom != prop) { - LOG_WARN("PropertyNotify parameters mismatch"); - goto exit; - } - } else { - if (event.xselection.property == None) { - LOG_INFO("XConvertSelection refused by clipboard owner"); - goto exit; - } - - if (event.xselection.requestor != platform_win || - event.xselection.selection != clipboard_prop || - event.xselection.property != prop) { - LOG_WARN("SelectionNotify parameters mismatch"); - goto exit; - } - } - - /* Warning we are running with the clipboard_lock held!! That is ok, as - there is no code holding XLockDisplay which calls code taking - the clipboard_lock!! */ - XLockDisplay(x_display); - res = XGetWindowProperty(x_display, platform_win, prop, 0, - LONG_MAX, del, type, &type_ret, &format_ret, &len, - &remain, &data); - XUnlockDisplay(x_display); - if (res != Success) { - LOG_WARN("XGetWindowProperty failed"); - goto exit; - } - - if (!incr) { - if (type_ret == incr_atom) { - if (waiting_for_property_notify) { - LOG_WARN("received an incr property notify while still reading another incr property"); - goto exit; - } - XSelectInput(x_display, platform_win, PropertyChangeMask); - XDeleteProperty(x_display, platform_win, prop); - XFlush(x_display); - waiting_for_property_notify = true; - ensure_clipboard_data_space(*(uint32_t*)data); - XFree(data); - return 0; /* Wait for more data */ - } - XDeleteProperty(x_display, platform_win, prop); - XFlush(x_display); - } - - if (type_ret != type) { - LOG_WARN("expected property type: %s, got: %s", atom_name(type), - atom_name(type_ret)); - goto exit; - } - - if (format_ret != format) { - LOG_WARN("expected %d bit format, got %d bits", format, format_ret); - goto exit; - } - - /* Convert len to bytes */ - switch(format) { - case 8: - break; - case 16: - len *= sizeof(short); - break; - case 32: - len *= sizeof(long); - break; - } - - if (incr) { - if (len) { - if (clipboard_data_size + len > clipboard_data_space) { - clipboard_data_space = clipboard_data_size + len; - clipboard_data = (uint8_t *)realloc(clipboard_data, clipboard_data_space); - assert(clipboard_data); - } - memcpy(clipboard_data + clipboard_data_size, data, len); - clipboard_data_size += len; - LOG_INFO("Appended %d bytes to buffer", len); - XFree(data); - return 0; /* Wait for more data */ - } - len = clipboard_data_size; - *data_ret = clipboard_data; - } else { - if (len > 0) - *data_ret = data; - else - *data_ret = NULL; - } - - if (len > 0) - ret_val = len; - else - LOG_WARN("property contains no data (zero length)"); - -exit: - if ((incr || ret_val == -1) && data) - XFree(data); - - if (incr) { - clipboard_data_size = 0; - waiting_for_property_notify = false; - } - - return ret_val; -} - -static void get_selection_free(unsigned char *data, bool incr) -{ - if (incr) { - /* If the clipboard was large return the memory to the system */ - if (clipboard_data_space > 512 * 1024) { - free(clipboard_data); - clipboard_data = NULL; - clipboard_data_space = 0; - } - } else if (data) - XFree(data); -} - -static Atom atom_lists_overlap(Atom *atoms1, Atom *atoms2, int l1, int l2) -{ - int i, j; - - for (i = 0; i < l1; i++) - for (j = 0; j < l2; j++) - if (atoms1[i] == atoms2[j]) - return atoms1[i]; - - return 0; -} - -static void handle_targets_notify(XEvent& event, bool incr) -{ - int i, len; - Lock lock(clipboard_lock); - Atom atom, *atoms = NULL; - - if (!expected_targets_notifies) { - LOG_WARN("unexpected selection notify TARGETS"); - return; - } - expected_targets_notifies--; - - /* If we have more targets_notifies pending, ignore this one, we - are only interested in the targets list of the current owner - (which is the last one we've requested a targets list from) */ - if (expected_targets_notifies) - return; - - len = get_selection(event, XA_ATOM, targets_atom, 32, - (unsigned char **)&atoms, incr); - if (len == 0 || len == -1) /* waiting for more data or error? */ - return; - - /* bytes -> atoms */ - len /= sizeof(Atom); - print_targets("received", atoms, len); - - clipboard_type_count = 0; - for (i = 0; i < clipboard_format_count; i++) { - atom = atom_lists_overlap(clipboard_formats[i].atoms, atoms, - clipboard_formats[i].atom_count, len); - if (atom) { - clipboard_agent_types[clipboard_type_count] = - clipboard_formats[i].type; - clipboard_x11_targets[clipboard_type_count] = atom; - clipboard_type_count++; - if (clipboard_type_count == - sizeof(clipboard_agent_types)/sizeof(uint32_t)) { - LOG_WARN("handle_targets_notify: too many matching types"); - break; - } - } - } - - if (clipboard_type_count) - clipboard_listener->on_clipboard_grab(clipboard_agent_types, - clipboard_type_count); - - get_selection_free((unsigned char *)atoms, incr); -} - -static void handle_selection_notify(XEvent& event, bool incr) -{ - int len = -1; - uint32_t type = get_clipboard_type(clipboard_request_target); - unsigned char *data = NULL; - - if (clipboard_request_target == None) - LOG_INFO("SelectionNotify received without a target"); - else if (!incr && - event.xselection.target != clipboard_request_target && - event.xselection.target != incr_atom) - LOG_WARN("Requested %s target got %s", - atom_name(clipboard_request_target), - atom_name(event.xselection.target)); - else - len = get_selection(event, clipboard_request_target, clipboard_prop, - 8, &data, incr); - - if (len == 0) /* waiting for more data? */ - return; - if (len == -1) { - type = VD_AGENT_CLIPBOARD_NONE; - len = 0; - } - - clipboard_listener->on_clipboard_notify(type, data, len); - clipboard_request_target = None; - get_selection_free(data, incr); -} - -static void handle_selection_request() -{ - XEvent *event; - uint32_t type = VD_AGENT_CLIPBOARD_NONE; - - if (!next_selection_request) - return; - - event = &next_selection_request->event; - - if (Platform::get_clipboard_owner() != Platform::owner_guest) { - LOG_INFO("received selection request event for target %s, " - "while clipboard not owned by guest", - atom_name(event->xselectionrequest.target)); - send_selection_notify(None, 1); - return; - } - - if (event->xselectionrequest.target == multiple_atom) { - LOG_WARN("multiple target not supported"); - send_selection_notify(None, 1); - return; - } - - if (event->xselectionrequest.target == targets_atom) { - send_targets(*event); - return; - } - - type = get_clipboard_type(event->xselectionrequest.target); - if (type == VD_AGENT_CLIPBOARD_NONE) { - send_selection_notify(None, 1); - return; - } - - clipboard_listener->on_clipboard_request(type); -} - -static void root_win_proc(XEvent& event) -{ - -#ifdef USE_XRANDR_1_2 - ASSERT(using_xrandr_1_0 || using_xrandr_1_2); -#else - ASSERT(using_xrandr_1_0); -#endif - if (event.type == ConfigureNotify || event.type - xrandr_event_base == RRScreenChangeNotify) { - XRRUpdateConfiguration(&event); - if (event.type - xrandr_event_base == RRScreenChangeNotify) { - display_mode_listener->on_display_mode_change(); - } - - if (Monitor::is_self_change()) { - return; - } - - ScreenList::iterator iter = screens.begin(); - for (; iter != screens.end(); iter++) { - (*iter)->set_broken(); - } - event_listener->on_monitors_change(); - return; - } - if (event.type == XFixesSelectionNotify + xfixes_event_base) { - XFixesSelectionNotifyEvent* selection_event = (XFixesSelectionNotifyEvent *)&event; - switch (selection_event->subtype) { - case XFixesSetSelectionOwnerNotify: - break; - /* Treat ... as a SelectionOwnerNotify None */ - case XFixesSelectionWindowDestroyNotify: - case XFixesSelectionClientCloseNotify: - selection_event->owner = None; - break; - default: - LOG_INFO("Unsupported selection event %u", selection_event->subtype); - return; - } - LOG_INFO("XFixesSetSelectionOwnerNotify %u", - (unsigned int)selection_event->owner); - - /* Ignore becoming the owner ourselves */ - if (selection_event->owner == platform_win) - return; - - /* If the clipboard owner is changed we no longer own it */ - Platform::set_clipboard_owner(Platform::owner_none); - if (selection_event->owner == None) - return; - - /* Request the supported targets from the new owner */ - XConvertSelection(x_display, clipboard_prop, targets_atom, - targets_atom, platform_win, CurrentTime); - XFlush(x_display); - expected_targets_notifies++; - return; - } - switch (event.type) { - case SelectionRequest: { - Lock lock(clipboard_lock); - struct selection_request *req, *new_req; - - new_req = new selection_request; - assert(new_req); - - new_req->event = event; - new_req->next = NULL; - - if (!next_selection_request) { - next_selection_request = new_req; - handle_selection_request(); - break; - } - - /* maybe we should limit the selection_request stack depth ? */ - req = next_selection_request; - while (req->next) - req = req->next; - - req->next = new_req; - break; - } - case SelectionClear: - /* Do nothing the clipboard ownership will get updated through - the XFixesSetSelectionOwnerNotify event */ - break; - case SelectionNotify: - if (event.xselection.target == targets_atom) - handle_targets_notify(event, false); - else - handle_selection_notify(event, false); - break; - case PropertyNotify: - if (!waiting_for_property_notify || event.xproperty.state != PropertyNewValue) { - break; - } - if (event.xproperty.atom == targets_atom) - handle_targets_notify(event, true); - else - handle_selection_notify(event, true); - break; - default: - return; - } -} - -static void process_monitor_configure_events(Window root) -{ - XEvent event; - - XLockDisplay(x_display); - XSync(x_display, False); - - while (XCheckTypedWindowEvent(x_display, root, ConfigureNotify, &event)) { - XUnlockDisplay(x_display); - root_win_proc(event); - XLockDisplay(x_display); - } - - while (XCheckTypedWindowEvent(x_display, root, xrandr_event_base + RRScreenChangeNotify, - &event)) { - XUnlockDisplay(x_display); - root_win_proc(event); - XLockDisplay(x_display); - } - - XUnlockDisplay(x_display); -} - -static void cleanup(void) -{ - int i; - - DBG(0, ""); - if (!Monitor::is_self_change()) { - Platform::destroy_monitors(); - } - if (vinfo) { - for (i = 0; i < ScreenCount(x_display); ++i) { - XFree(vinfo[i]); - } - delete[] vinfo; - vinfo = NULL; - } -#ifdef USE_OPENGL - if (fb_config) { - for (i = 0; i < ScreenCount(x_display); ++i) { - if (fb_config[i]) { - XFree(fb_config[i]); - } - } - delete fb_config; - fb_config = NULL; - } -#endif // USE_OPENGL -} - -static void quit_handler(int sig) -{ - LOG_INFO("signal %d", sig); - Platform::send_quit_request(); -} - -static void abort_handler(int sig) -{ - LOG_INFO("signal %d", sig); - Platform::destroy_monitors(); -} - -static void init_xrandr() -{ - Bool xrandr_ext = XRRQueryExtension(x_display, &xrandr_event_base, &xrandr_error_base); - if (xrandr_ext) { - XRRQueryVersion(x_display, &xrandr_major, &xrandr_minor); - if (xrandr_major < 1) { - return; - } -#ifdef USE_XRANDR_1_2 - if (xrandr_major == 1 && xrandr_minor < 2) { - using_xrandr_1_0 = true; - return; - } - using_xrandr_1_2 = true; -#else - using_xrandr_1_0 = true; -#endif - } -} - -static void init_xrender() -{ - int event_base; - int error_base; - int major; - int minor; - - using_xrender_0_5 = XRenderQueryExtension(x_display, &event_base, &error_base) && - XRenderQueryVersion(x_display, &major, &minor) && (major > 0 || minor >= 5); -} - -static void init_xinerama() -{ -#ifdef USE_XINERAMA_1_0 - int event_base; - int error_base; - int major; - int minor; - - using_xinerama_1_0 = XineramaQueryExtension(x_display, &event_base, &error_base) && - XineramaQueryVersion(x_display, &major, &minor) && major >= 1 && minor >= 0 && - XineramaIsActive(x_display); -#endif -} - -static void init_xfixes() -{ - int major; - int minor; - - using_xfixes_1_0 = XFixesQueryExtension(x_display, &xfixes_event_base, &xfixes_error_base) && - XFixesQueryVersion(x_display, &major, &minor) && major >= 1; -} - -static void init_kbd() -{ - int xkb_major = XkbMajorVersion; - int xkb_minor = XkbMinorVersion; - int opcode; - int event; - int error; - - if (!XkbLibraryVersion(&xkb_major, &xkb_minor) || - !XkbQueryExtension(x_display, &opcode, &event, &error, &xkb_major, &xkb_minor)) { - return; - } - caps_lock_mask = XkbKeysymToModifiers(x_display, XK_Caps_Lock); - num_lock_mask = XkbKeysymToModifiers(x_display, XK_Num_Lock); -} - -static void init_XIM() -{ - char app_name[20]; - strcpy(app_name, "spicec"); - - XSetLocaleModifiers(""); - x_input_method = XOpenIM(x_display, NULL, app_name, app_name); - - if (!x_input_method) { - return; - } - - x_input_context = XCreateIC(x_input_method, XNInputStyle, XIMPreeditNone | XIMStatusNone, NULL); - - if (!x_input_context) { - THROW("create IC failed"); - } -} - -static int x_error_handler(Display* display, XErrorEvent* error_event) -{ - char error_str[256]; - char request_str[256]; - char number_str[32]; - - if (handle_x_error) { - if (error_event->error_code) { - x_error_code = error_event->error_code; - } - return 0; - } - - char* display_name = XDisplayString(display); - XGetErrorText(display, error_event->error_code, error_str, sizeof(error_str)); - - if (error_event->request_code < 128) { - snprintf(number_str, sizeof(number_str), "%d", error_event->request_code); - XGetErrorDatabaseText(display, "XRequest", number_str, "", - request_str, sizeof(request_str)); - } else { - snprintf(request_str, sizeof(request_str), "%d", error_event->request_code); - } - - LOG_ERROR("x error on display %s error %s minor %u request %s", - display_name, - error_str, - (uint32_t)error_event->minor_code, - request_str); - _exit(-1); - return 0; -} - -static SPICE_GNUC_NORETURN int x_io_error_handler(Display* display) -{ - LOG_ERROR("x io error on %s", XDisplayString(display)); - _exit(-1); -} - -static XVisualInfo* get_x_vis_info(int screen) -{ - XVisualInfo vtemplate; - int count; - - Visual* visual = DefaultVisualOfScreen(ScreenOfDisplay(x_display, screen)); - vtemplate.screen = screen; - vtemplate.visualid = XVisualIDFromVisual(visual); - return XGetVisualInfo(x_display, VisualIDMask | VisualScreenMask, &vtemplate, &count); -} - -void Platform::init() -{ -#ifdef USE_OPENGL - int err, ev; - int threads_enable; -#endif // USE_OPENGL - int major, minor; - Bool pixmaps; - - DBG(0, ""); - - setlocale(LC_ALL, ""); - -#ifdef USE_OPENGL - threads_enable = XInitThreads(); -#else - XInitThreads(); -#endif - - if (!(x_display = XOpenDisplay(NULL))) { - THROW("open X display failed"); - } - - if (XShmQueryExtension (x_display) && - XShmQueryVersion (x_display, &major, &minor, &pixmaps)) { - x_shm_avail = true; - } - - vinfo = new XVisualInfo *[ScreenCount(x_display)]; - memset(vinfo, 0, sizeof(XVisualInfo *) * ScreenCount(x_display)); - screen_format = new RedDrawable::Format[ScreenCount(x_display)]; - memset(screen_format, 0, sizeof(RedDrawable::Format) * ScreenCount(x_display)); -#ifdef USE_OPENGL - fb_config = new GLXFBConfig *[ScreenCount(x_display)]; - memset(fb_config, 0, sizeof(GLXFBConfig *) * ScreenCount(x_display)); - - if (threads_enable && glXQueryExtension(x_display, &err, &ev)) { - int num_configs; - int attrlist[] = { - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DOUBLEBUFFER, True, - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_STENCIL_SIZE, 0, - GLX_DEPTH_SIZE, 0, - None - }; - - for (int i = 0; i < ScreenCount(x_display); ++i) { - fb_config[i] = glXChooseFBConfig(x_display, i, attrlist, &num_configs); - if (fb_config[i] != NULL) { - ASSERT(num_configs > 0); - vinfo[i] = glXGetVisualFromFBConfig(x_display, fb_config[i][0]); - } - - if (vinfo[i] == NULL) { - if (fb_config[i]) { - XFree(fb_config[i]); - fb_config[i] = NULL; - } - vinfo[i] = get_x_vis_info(i); - } - } - } else -#else // !USE_OPENGL - { - for (int i = 0; i < ScreenCount(x_display); ++i) { - vinfo[i] = get_x_vis_info(i); - } - } -#endif // USE_OPENGL - - for (int i = 0; i < ScreenCount(x_display); ++i) { - if (vinfo[i] == NULL) { - THROW("Unable to find a visual for screen"); - } - if ((vinfo[i]->depth == 32 || vinfo[i]->depth == 24) && - vinfo[i]->red_mask == 0xff0000 && - vinfo[i]->green_mask == 0x00ff00 && - vinfo[i]->blue_mask == 0x0000ff) { - screen_format[i] = RedDrawable::RGB32; - } else if (vinfo[i]->depth == 16 && - vinfo[i]->red_mask == 0xf800 && - vinfo[i]->green_mask == 0x7e0 && - vinfo[i]->blue_mask == 0x1f) { - screen_format[i] = RedDrawable::RGB16_565; - } else if (vinfo[i]->depth == 15 && - vinfo[i]->red_mask == 0x7c00 && - vinfo[i]->green_mask == 0x3e0 && - vinfo[i]->blue_mask == 0x1f) { - screen_format[i] = RedDrawable::RGB16_555; - } else { - THROW("Unsupported visual for screen"); - } - } - - XSetErrorHandler(x_error_handler); - XSetIOErrorHandler(x_io_error_handler); - - win_proc_context = XUniqueContext(); - - init_kbd(); - init_xrandr(); - init_xrender(); - init_xfixes(); - init_XIM(); - init_xinerama(); - - struct sigaction act; - memset(&act, 0, sizeof(act)); - sigfillset(&act.sa_mask); - - act.sa_handler = quit_handler; - sigaction(SIGINT, &act, NULL); - sigaction(SIGHUP, &act, NULL); - sigaction(SIGTERM, &act, NULL); - sigaction(SIGQUIT, &act, NULL); - - act.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &act, NULL); - - act.sa_flags = SA_RESETHAND; - act.sa_handler = abort_handler; - sigaction(SIGABRT, &act, NULL); - sigaction(SIGILL, &act, NULL); - sigaction(SIGSEGV, &act, NULL); - sigaction(SIGFPE, &act, NULL); - - atexit(cleanup); -} - -void Platform::set_process_loop(ProcessLoop& main_process_loop) -{ - main_loop = &main_process_loop; - XEventHandler *x_event_handler; - x_event_handler = new XEventHandler(*x_display, win_proc_context); - main_loop->add_file(*x_event_handler); -} - -uint32_t Platform::get_keyboard_lock_modifiers() -{ - XKeyboardState keyboard_state; - uint32_t modifiers = 0; - - XLockDisplay(x_display); - XGetKeyboardControl(x_display, &keyboard_state); - XUnlockDisplay(x_display); - - if (keyboard_state.led_mask & 0x01) { - modifiers |= CAPS_LOCK_MODIFIER; - } - if (keyboard_state.led_mask & 0x02) { - modifiers |= NUM_LOCK_MODIFIER; - } - if (keyboard_state.led_mask & 0x04) { - modifiers |= SCROLL_LOCK_MODIFIER; - } - return modifiers; -} - -enum XLed { - X11_CAPS_LOCK_LED = 1, - X11_NUM_LOCK_LED, - X11_SCROLL_LOCK_LED, -}; - -static void set_keyboard_led(XLed led, int set) -{ - switch (led) { - case X11_CAPS_LOCK_LED: - if (caps_lock_mask) { - XkbLockModifiers(x_display, XkbUseCoreKbd, caps_lock_mask, set ? caps_lock_mask : 0); - XFlush(x_display); - } - return; - case X11_NUM_LOCK_LED: - if (num_lock_mask) { - XkbLockModifiers(x_display, XkbUseCoreKbd, num_lock_mask, set ? num_lock_mask : 0); - XFlush(x_display); - } - return; - case X11_SCROLL_LOCK_LED: - XKeyboardControl keyboard_control; - keyboard_control.led_mode = set ? LedModeOn : LedModeOff; - keyboard_control.led = led; - XChangeKeyboardControl(x_display, KBLed | KBLedMode, &keyboard_control); - XFlush(x_display); - return; - } -} - -void Platform::set_keyboard_lock_modifiers(uint32_t modifiers) -{ - uint32_t now = get_keyboard_lock_modifiers(); - - if ((now & CAPS_LOCK_MODIFIER) != (modifiers & CAPS_LOCK_MODIFIER)) { - set_keyboard_led(X11_CAPS_LOCK_LED, !!(modifiers & CAPS_LOCK_MODIFIER)); - } - if ((now & NUM_LOCK_MODIFIER) != (modifiers & NUM_LOCK_MODIFIER)) { - set_keyboard_led(X11_NUM_LOCK_LED, !!(modifiers & NUM_LOCK_MODIFIER)); - } - if ((now & SCROLL_LOCK_MODIFIER) != (modifiers & SCROLL_LOCK_MODIFIER)) { - set_keyboard_led(X11_SCROLL_LOCK_LED, !!(modifiers & SCROLL_LOCK_MODIFIER)); - } -} - -static uint32_t key_bit(char* keymap, int key, uint32_t bit) -{ - KeyCode key_code = XKeysymToKeycode(x_display, key); - return (((keymap[key_code >> 3] >> (key_code & 7)) & 1) ? bit : 0); -} - -uint32_t Platform::get_keyboard_modifiers() -{ - char keymap[32]; - uint32_t mods; - - XLockDisplay(x_display); - XQueryKeymap(x_display, keymap); - mods = key_bit(keymap, XK_Shift_L, L_SHIFT_MODIFIER) | - key_bit(keymap, XK_Shift_R, R_SHIFT_MODIFIER) | - key_bit(keymap, XK_Control_L, L_CTRL_MODIFIER) | - key_bit(keymap, XK_Control_R, R_CTRL_MODIFIER) | - key_bit(keymap, XK_Alt_L, L_ALT_MODIFIER) | - key_bit(keymap, XK_Alt_R, R_ALT_MODIFIER); - XUnlockDisplay(x_display); - - return mods; -} - -void Platform::reset_cursor_pos() -{ - if (!primary_monitor) { - return; - } - SpicePoint pos = primary_monitor->get_position(); - SpicePoint size = primary_monitor->get_size(); - Window root_window = RootWindow(x_display, DefaultScreen(x_display)); - XWarpPointer(x_display, None, root_window, 0, 0, 0, 0, pos.x + size.x / 2, pos.y + size.y / 2); - XFlush(x_display); -} - -WaveRecordAbstract* Platform::create_recorder(RecordClient& client, - uint32_t samples_per_sec, - uint32_t bits_per_sample, - uint32_t channels, - uint32_t frame_size) -{ - return new WaveRecorder(client, samples_per_sec, bits_per_sample, channels, frame_size); -} - -WavePlaybackAbstract* Platform::create_player(uint32_t samples_per_sec, - uint32_t bits_per_sample, - uint32_t channels, - uint32_t frame_size) -{ - return new WavePlayer(samples_per_sec, bits_per_sample, channels, frame_size); -} - -void XPlatform::on_focus_in() -{ - if (focus_count++ == 0) { - event_listener->on_app_activated(); - } -} - -void XPlatform::on_focus_out() -{ - ASSERT(focus_count > 0); - if (--focus_count == 0) { - event_listener->on_app_deactivated(); - } -} - -class XBaseLocalCursor: public LocalCursor { -public: - XBaseLocalCursor() : _handle (0) {} - ~XBaseLocalCursor(); - void set(Window window); - -protected: - Cursor _handle; -}; - -void XBaseLocalCursor::set(Window window) -{ - if (_handle) { - XDefineCursor(x_display, window, _handle); - XFlush(x_display); - } -} - -XBaseLocalCursor::~XBaseLocalCursor() -{ - if (_handle) { - XFreeCursor(x_display, _handle); - } -} - -class XLocalCursor: public XBaseLocalCursor { -public: - XLocalCursor(CursorData* cursor_data); -}; - -static inline uint8_t get_pix_mask(const uint8_t* data, int offset, int pix_index) -{ - return data[offset + (pix_index >> 3)] & (0x80 >> (pix_index % 8)); -} - -static inline uint32_t get_pix_hack(int pix_index, int width) -{ - return (((pix_index % width) ^ (pix_index / width)) & 1) ? 0xc0303030 : 0x30505050; -} - -XLocalCursor::XLocalCursor(CursorData* cursor_data) -{ - const SpiceCursorHeader& header = cursor_data->header(); - const uint8_t* data = cursor_data->data(); - int cur_size = header.width * header.height; - uint8_t pix_mask; - uint32_t pix; - uint16_t i; - int size; - - if (!get_size_bits(header, size)) { - THROW("invalid cursor type"); - } - - uint32_t* cur_data = new uint32_t[cur_size]; - - switch (header.type) { - case SPICE_CURSOR_TYPE_ALPHA: - break; - case SPICE_CURSOR_TYPE_COLOR32: - memcpy(cur_data, data, cur_size * sizeof(uint32_t)); - for (i = 0; i < cur_size; i++) { - pix_mask = get_pix_mask(data, size, i); - if (pix_mask && *((uint32_t*)data + i) == 0xffffff) { - cur_data[i] = get_pix_hack(i, header.width); - } else { - cur_data[i] |= (pix_mask ? 0 : 0xff000000); - } - } - break; - case SPICE_CURSOR_TYPE_COLOR16: - for (i = 0; i < cur_size; i++) { - pix_mask = get_pix_mask(data, size, i); - pix = *((uint16_t*)data + i); - if (pix_mask && pix == 0x7fff) { - cur_data[i] = get_pix_hack(i, header.width); - } else { - cur_data[i] = ((pix & 0x1f) << 3) | ((pix & 0x3e0) << 6) | ((pix & 0x7c00) << 9) | - (pix_mask ? 0 : 0xff000000); - } - } - break; - case SPICE_CURSOR_TYPE_MONO: - for (i = 0; i < cur_size; i++) { - pix_mask = get_pix_mask(data, 0, i); - pix = get_pix_mask(data, size, i); - if (pix_mask && pix) { - cur_data[i] = get_pix_hack(i, header.width); - } else { - cur_data[i] = (pix ? 0xffffff : 0) | (pix_mask ? 0 : 0xff000000); - } - } - break; - case SPICE_CURSOR_TYPE_COLOR4: - for (i = 0; i < cur_size; i++) { - pix_mask = get_pix_mask(data, size + (sizeof(uint32_t) << 4), i); - int idx = (i & 1) ? (data[i >> 1] & 0x0f) : ((data[i >> 1] & 0xf0) >> 4); - pix = *((uint32_t*)(data + size) + idx); - if (pix_mask && pix == 0xffffff) { - cur_data[i] = get_pix_hack(i, header.width); - } else { - cur_data[i] = pix | (pix_mask ? 0 : 0xff000000); - } - } - break; - case SPICE_CURSOR_TYPE_COLOR24: - case SPICE_CURSOR_TYPE_COLOR8: - default: - LOG_WARN("unsupported cursor type %d", header.type); - XLockDisplay(x_display); - _handle = XCreateFontCursor(x_display, XC_arrow); - XUnlockDisplay(x_display); - delete[] cur_data; - return; - } - - XImage image; - memset(&image, 0, sizeof(image)); - image.width = header.width; - image.height = header.height; - image.data = (header.type == SPICE_CURSOR_TYPE_ALPHA ? (char*)data : (char*)cur_data); - image.byte_order = LSBFirst; - image.bitmap_unit = 32; - image.bitmap_bit_order = LSBFirst; - image.bitmap_pad = 8; - image.bytes_per_line = header.width << 2; - image.depth = 32; - image.format = ZPixmap; - image.bits_per_pixel = 32; - image.red_mask = 0x00ff0000; - image.green_mask = 0x0000ff00; - image.blue_mask = 0x000000ff; - if (!XInitImage(&image)) { - THROW("init image failed"); - } - - Window root_window = RootWindow(x_display, DefaultScreen(x_display)); - XGCValues gc_vals; - gc_vals.function = GXcopy; - gc_vals.foreground = ~0; - gc_vals.background = 0; - gc_vals.plane_mask = AllPlanes; - - XLockDisplay(x_display); - Pixmap pixmap = XCreatePixmap(x_display, root_window, header.width, header.height, 32); - GC gc = XCreateGC(x_display, pixmap, GCFunction | GCForeground | GCBackground | GCPlaneMask, - &gc_vals); - - XPutImage(x_display, pixmap, gc, &image, 0, 0, 0, 0, header.width, header.height); - XFreeGC(x_display, gc); - - XRenderPictFormat *xformat = XRenderFindStandardFormat(x_display, PictStandardARGB32); - Picture picture = XRenderCreatePicture(x_display, pixmap, xformat, 0, NULL); - _handle = XRenderCreateCursor(x_display, picture, header.hot_spot_x, header.hot_spot_y); - XUnlockDisplay(x_display); - - XRenderFreePicture(x_display, picture); - XFreePixmap(x_display, pixmap); - delete[] cur_data; -} - -LocalCursor* Platform::create_local_cursor(CursorData* cursor_data) -{ - ASSERT(using_xrender_0_5); - return new XLocalCursor(cursor_data); -} - -class XInactiveCursor: public XBaseLocalCursor { -public: - XInactiveCursor() { _handle = XCreateFontCursor(x_display, XC_X_cursor);} -}; - -LocalCursor* Platform::create_inactive_cursor() -{ - return new XInactiveCursor(); -} - -class XDefaultCursor: public XBaseLocalCursor { -public: - XDefaultCursor() - { - XLockDisplay(x_display); - _handle = XCreateFontCursor(x_display, XC_top_left_arrow); - XUnlockDisplay(x_display); - } -}; - -LocalCursor* Platform::create_default_cursor() -{ - return new XDefaultCursor(); -} - -bool Platform::on_clipboard_grab(uint32_t *types, uint32_t type_count) -{ - Lock lock(clipboard_lock); - - if (type_count > sizeof(clipboard_agent_types)/sizeof(uint32_t)) { - LOG_WARN("on_clipboard_grab: too many types"); - type_count = sizeof(clipboard_agent_types)/sizeof(uint32_t); - } - - memcpy(clipboard_agent_types, types, type_count * sizeof(uint32_t)); - clipboard_type_count = type_count; - - XSetSelectionOwner(x_display, clipboard_prop, platform_win, CurrentTime); - XFlush(x_display); - - set_clipboard_owner_unlocked(owner_guest); - return true; -} - -int Platform::_clipboard_owner = Platform::owner_none; - -void Platform::set_clipboard_owner(int new_owner) -{ - Lock lock(clipboard_lock); - set_clipboard_owner_unlocked(new_owner); -} - -void Platform::set_clipboard_owner_unlocked(int new_owner) -{ - const char * const owner_str[] = { "none", "guest", "client" }; - - /* Clear pending requests and clipboard data */ - { - if (next_selection_request) { - LOG_INFO("selection requests pending upon clipboard owner change, clearing"); - while (next_selection_request) - send_selection_notify(None, 0); - } - - clipboard_data_size = 0; - clipboard_request_target = None; - waiting_for_property_notify = false; - - /* Clear cached clipboard type info when there is no new owner - (otherwise the new owner will already have set new type info) */ - if (new_owner == owner_none) - clipboard_type_count = 0; - } - if (new_owner == owner_none) - clipboard_listener->on_clipboard_release(); - - _clipboard_owner = new_owner; - LOG_INFO("new clipboard owner: %s", owner_str[new_owner]); -} - -void Platform::set_clipboard_listener(ClipboardListener* listener) -{ - clipboard_listener = listener ? listener : &default_clipboard_listener; -} - -bool Platform::on_clipboard_notify(uint32_t type, const uint8_t* data, int32_t size) -{ - Lock lock(clipboard_lock); - Atom prop; - XEvent *event; - uint32_t type_from_event; - - if (!next_selection_request) { - LOG_INFO("received clipboard data without an outstanding" - "selection request, ignoring"); - return true; - } - - if (type == VD_AGENT_CLIPBOARD_NONE) { - send_selection_notify(None, 1); - return true; - } - - event = &next_selection_request->event; - type_from_event = get_clipboard_type(event->xselectionrequest.target); - if (type_from_event != type) { - LOG_WARN("expecting type %u clipboard data got %u", - type_from_event, type); - send_selection_notify(None, 1); - return false; - } - - prop = event->xselectionrequest.property; - if (prop == None) - prop = event->xselectionrequest.target; - /* FIXME: use INCR for large data transfers */ - XChangeProperty(x_display, event->xselectionrequest.requestor, prop, - event->xselectionrequest.target, 8, PropModeReplace, - data, size); - send_selection_notify(prop, 1); - return true; -} - -bool Platform::on_clipboard_request(uint32_t type) -{ - Window owner; - Lock lock(clipboard_lock); - Atom target = get_clipboard_target(type); - - if (target == None) - return false; - - XLockDisplay(x_display); - owner = XGetSelectionOwner(x_display, clipboard_prop); - XUnlockDisplay(x_display); - if (owner == None) { - LOG_INFO("No owner for the selection"); - return false; - } - - if (clipboard_request_target) { - LOG_INFO("XConvertSelection request is already pending"); - return false; - } - clipboard_request_target = target; - XConvertSelection(x_display, clipboard_prop, target, clipboard_prop, platform_win, CurrentTime); - XFlush(x_display); - return true; -} - -void Platform::on_clipboard_release() -{ - XEvent event; - Window owner; - - XLockDisplay(x_display); - owner = XGetSelectionOwner(x_display, clipboard_prop); - XUnlockDisplay(x_display); - if (owner != platform_win) { - LOG_INFO("Platform::on_clipboard_release() called while not selection owner"); - return; - } - /* Note there is a small race window here where another x11 app could - acquire selection ownership and we kick it off again, nothing we - can do about that :( */ - XSetSelectionOwner(x_display, clipboard_prop, None, CurrentTime); - - /* Make sure we process the XFixesSetSelectionOwnerNotify event caused - by this, so we don't end up changing the clipboard owner to none, after - it has already been re-owned because this event is still pending. */ - XLockDisplay(x_display); - XSync(x_display, False); - while (XCheckTypedEvent(x_display, - XFixesSelectionNotify + xfixes_event_base, - &event)) { - XUnlockDisplay(x_display); - root_win_proc(event); - XLockDisplay(x_display); - } - XUnlockDisplay(x_display); - - /* Note no need to do a set_clipboard_owner(owner_none) here, as that is - already done by processing the XFixesSetSelectionOwnerNotify event. */ -} diff --git a/client/x11/platform_utils.cpp b/client/x11/platform_utils.cpp deleted file mode 100644 index 6ae30a46..00000000 --- a/client/x11/platform_utils.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdarg.h> -#include "utils.h" - -void string_vprintf(std::string& str, const char* format, va_list ap) -{ - va_list ap_test; - va_copy(ap_test, ap); - int len = vsnprintf(NULL, 0, format, ap_test) + 1; - va_end(ap_test); - AutoArray<char> buf(new char[len]); - vsnprintf(buf.get(), len, format, ap); - str = buf.get(); -} diff --git a/client/x11/platform_utils.h b/client/x11/platform_utils.h deleted file mode 100644 index 03a24892..00000000 --- a/client/x11/platform_utils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_PLATFORM_UTILS -#define _H_PLATFORM_UTILS - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netinet/tcp.h> -#include <netdb.h> - -typedef int SOCKET; - -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define closesocket(sock) ::close(sock) -#define SHUTDOWN_ERR EPIPE -#define INTERRUPTED_ERR EINTR -#define WOULDBLOCK_ERR EAGAIN -#define sock_error() errno -#define sock_err_message(err) strerror(err) - -#endif diff --git a/client/x11/playback.cpp b/client/x11/playback.cpp deleted file mode 100644 index 83946aac..00000000 --- a/client/x11/playback.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "playback.h" -#include "utils.h" -#include "debug.h" - -#define REING_SIZE_MS 300 - -WavePlayer::WavePlayer(uint32_t samples_per_sec, uint32_t bits_per_sample, uint32_t channels, uint32_t frame_size) - : _pcm (NULL) - , _hw_params (NULL) - , _sw_params (NULL) -{ - if (!init(samples_per_sec, bits_per_sample, channels, frame_size)) { - cleanup(); - THROW("failed"); - } -} - -void WavePlayer::cleanup() -{ - if (_pcm) { - snd_pcm_close(_pcm); - } - - if (_hw_params) { - snd_pcm_hw_params_free(_hw_params); - } - - if (_sw_params) { - snd_pcm_sw_params_free(_sw_params); - } -} - -WavePlayer::~WavePlayer() -{ - cleanup(); -} - -bool WavePlayer::init(uint32_t samples_per_sec, - uint32_t bits_per_sample, - uint32_t channels, - uint32_t frame_size) -{ - const char* pcm_device = "default"; - snd_pcm_format_t format; - int err; - - switch (bits_per_sample) { - case 8: - format = SND_PCM_FORMAT_S8; - break; - case 16: - format = SND_PCM_FORMAT_S16_LE; - break; - default: - return false; - } - _samples_per_ms = samples_per_sec / 1000; - _frame_size = frame_size; - - if ((err = snd_pcm_open(&_pcm, pcm_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { - LOG_ERROR("cannot open audio playback device %s %s", pcm_device, snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_malloc(&_hw_params)) < 0) { - LOG_ERROR("cannot allocate hardware parameter structure %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_sw_params_malloc(&_sw_params)) < 0) { - LOG_ERROR("cannot allocate software parameter structure %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_any(_pcm, _hw_params)) < 0) { - LOG_ERROR("cannot initialize hardware parameter structure %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_rate_resample(_pcm, _hw_params, 1)) < 0) { - LOG_ERROR("cannot set rate resample %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_access(_pcm, _hw_params, - SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { - LOG_ERROR("cannot set access type %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_rate(_pcm, _hw_params, samples_per_sec, 0)) < 0) { - LOG_ERROR("cannot set sample rate %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_channels(_pcm, _hw_params, channels)) < 0) { - LOG_ERROR("cannot set channel count %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_format(_pcm, _hw_params, format)) < 0) { - LOG_ERROR("cannot set sample format %s", snd_strerror(err)); - return false; - } - - snd_pcm_uframes_t buffer_size; - buffer_size = (samples_per_sec * REING_SIZE_MS / 1000) / frame_size * frame_size; - - if ((err = snd_pcm_hw_params_set_buffer_size_near(_pcm, _hw_params, &buffer_size)) < 0) { - LOG_ERROR("cannot set buffer size %s", snd_strerror(err)); - return false; - } - - int direction = 1; - snd_pcm_uframes_t period_size = (samples_per_sec * 20 / 1000) / frame_size * frame_size; - if ((err = snd_pcm_hw_params_set_period_size_near(_pcm, _hw_params, &period_size, - &direction)) < 0) { - LOG_ERROR("cannot set period size %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params(_pcm, _hw_params)) < 0) { - LOG_ERROR("cannot set parameters %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_sw_params_current(_pcm, _sw_params)) < 0) { - LOG_ERROR("cannot obtain sw parameters %s", snd_strerror(err)); - return false; - } - - err = snd_pcm_hw_params_get_buffer_size(_hw_params, &buffer_size); - if (err < 0) { - LOG_ERROR("unable to get buffer size for playback: %s", snd_strerror(err)); - return false; - } - - direction = 0; - err = snd_pcm_hw_params_get_period_size(_hw_params, &period_size, &direction); - if (err < 0) { - LOG_ERROR("unable to get period size for playback: %s", snd_strerror(err)); - return false; - } - - err = snd_pcm_sw_params_set_start_threshold(_pcm, _sw_params, - (buffer_size / period_size) * period_size); - if (err < 0) { - LOG_ERROR("unable to set start threshold mode for playback: %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_sw_params(_pcm, _sw_params)) < 0) { - LOG_ERROR("cannot set software parameters %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_prepare(_pcm)) < 0) { - LOG_ERROR("cannot prepare pcm device %s", snd_strerror(err)); - return false; - } - - return true; -} - -bool WavePlayer::write(uint8_t* frame) -{ - snd_pcm_sframes_t ret = snd_pcm_writei(_pcm, frame, _frame_size); - if (ret < 0) { - if (ret == -EAGAIN) { - return false; - } - DBG(0, "err %s", snd_strerror(-ret)); - if (snd_pcm_recover(_pcm, ret, 1) == 0) { - snd_pcm_writei(_pcm, frame, _frame_size); - } - } - return true; -} - -void WavePlayer::stop() -{ - snd_pcm_drain(_pcm); - snd_pcm_prepare(_pcm); -} - -bool WavePlayer::abort() -{ - return true; -} - -uint32_t WavePlayer::get_delay_ms() -{ - ASSERT(_pcm); - - snd_pcm_sframes_t delay; - - if (snd_pcm_delay(_pcm, &delay) < 0) { - return 0; - } - return delay / _samples_per_ms; -} diff --git a/client/x11/playback.h b/client/x11/playback.h deleted file mode 100644 index c0b8c52e..00000000 --- a/client/x11/playback.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_LINUX_PLAYBACK -#define _H_LINUX_PLAYBACK - -#include <alsa/asoundlib.h> - -#include "common.h" -#include "audio_devices.h" - -class WavePlayer: public WavePlaybackAbstract { -public: - WavePlayer(uint32_t samples_per_sec, uint32_t bits_per_sample, uint32_t channels, uint32_t frame_size); - virtual ~WavePlayer(); - - virtual bool write(uint8_t* frame); - virtual bool abort(); - virtual void stop(); - virtual uint32_t get_delay_ms(); - -private: - bool init(uint32_t samples_per_sec, uint32_t bits_per_sample, uint32_t channel, uint32_t frame_size); - void cleanup(); - -private: - snd_pcm_t* _pcm; - snd_pcm_hw_params_t* _hw_params; - snd_pcm_sw_params_t* _sw_params; - uint32_t _samples_per_ms; - uint32_t _frame_size; -}; - -#endif diff --git a/client/x11/record.cpp b/client/x11/record.cpp deleted file mode 100644 index 6bc9f604..00000000 --- a/client/x11/record.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "record.h" -#include "utils.h" -#include "debug.h" - - -class WaveRecorder::EventTrigger: public EventSources::File { -public: - EventTrigger(WaveRecorder& recorder, int fd); - virtual void on_event(); - virtual int get_fd() { return _fd;} - -private: - WaveRecorder& _recorder; - int _fd; -}; - -WaveRecorder::EventTrigger::EventTrigger(WaveRecorder& recorder, int fd) - : _recorder (recorder) - , _fd (fd) -{ -} - -void WaveRecorder::EventTrigger::on_event() -{ - _recorder.on_event(); -} - -WaveRecorder::WaveRecorder(Platform::RecordClient& client, - uint32_t samples_per_sec, - uint32_t bits_per_sample, - uint32_t channels, - uint32_t frame_size) - : _client (client) - , _pcm (NULL) - , _hw_params (NULL) - , _sw_params (NULL) - , _sample_bytes (bits_per_sample * channels / 8) - , _frame (new uint8_t[_sample_bytes * frame_size]) - , _frame_pos (_frame) - , _frame_end (_frame + _sample_bytes * frame_size) - , _event_trigger (NULL) -{ - if (!init(samples_per_sec, bits_per_sample, channels, frame_size)) { - cleanup(); - THROW("failed"); - } -} - -WaveRecorder::~WaveRecorder() -{ - cleanup(); - delete[] _frame; -} - -void WaveRecorder::cleanup() -{ - if (_event_trigger) { - _client.remove_event_source(*_event_trigger); - delete _event_trigger; - } - - if (_sw_params) { - snd_pcm_sw_params_free(_sw_params); - } - - if (_hw_params) { - snd_pcm_hw_params_free(_hw_params); - } - - if (_pcm) { - snd_pcm_close(_pcm); - } -} - -bool WaveRecorder::init(uint32_t samples_per_sec, - uint32_t bits_per_sample, - uint32_t channels, - uint32_t frame_size) -{ - const char* pcm_device = "default"; - snd_pcm_format_t format; - int err; - - _frame_size = frame_size; - - switch (bits_per_sample) { - case 8: - format = SND_PCM_FORMAT_S8; - break; - case 16: - format = SND_PCM_FORMAT_S16_LE; - break; - default: - return false; - } - - if ((err = snd_pcm_open(&_pcm, pcm_device, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { - LOG_ERROR("cannot open audio record device %s %s", pcm_device, snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_malloc(&_hw_params)) < 0) { - LOG_ERROR("cannot allocate hardware parameter structure %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_sw_params_malloc(&_sw_params)) < 0) { - LOG_ERROR("cannot allocate software parameter structure %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_any(_pcm, _hw_params)) < 0) { - LOG_ERROR("cannot initialize hardware parameter structure %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_rate_resample(_pcm, _hw_params, 1)) < 0) { - LOG_ERROR("cannot set rate resample %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_access(_pcm, _hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { - LOG_ERROR("cannot set access type %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_rate(_pcm, _hw_params, samples_per_sec, 0)) < 0) { - LOG_ERROR("cannot set sample rate %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_channels(_pcm, _hw_params, channels)) < 0) { - LOG_ERROR("cannot set channel count %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params_set_format(_pcm, _hw_params, format)) < 0) { - LOG_ERROR("cannot set sample format %s", snd_strerror(err)); - return false; - } - - int direction = 0; - snd_pcm_uframes_t buffer_size = (samples_per_sec * 160 / 1000) / frame_size * frame_size; - - if ((err = snd_pcm_hw_params_set_buffer_size_near(_pcm, _hw_params, &buffer_size)) < 0) { - LOG_ERROR("cannot set buffer size %s", snd_strerror(err)); - return false; - } - - snd_pcm_uframes_t period_size = frame_size; - if ((err = snd_pcm_hw_params_set_period_size_near(_pcm, _hw_params, &period_size, - &direction)) < 0) { - LOG_ERROR("cannot set period size near %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_hw_params(_pcm, _hw_params)) < 0) { - LOG_ERROR("cannot set parameters %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_sw_params_current(_pcm, _sw_params)) < 0) { - LOG_ERROR("cannot get current sw parameters %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_sw_params_set_start_threshold(_pcm, _sw_params, frame_size)) < 0) { - LOG_ERROR("cannot set start threshold %s", snd_strerror(err)); - return false; - } - - if ((err = snd_pcm_sw_params(_pcm, _sw_params)) < 0) { - LOG_ERROR("cannot set sw parameters %s", snd_strerror(err)); - return false; - } - - struct pollfd pfd; - if ((err = snd_pcm_poll_descriptors(_pcm, &pfd, 1)) < 0) { - LOG_ERROR("cannot get poll ID %s", snd_strerror(err)); - return false; - } - _event_trigger = new WaveRecorder::EventTrigger(*this, pfd.fd); - _client.add_event_source(*_event_trigger); - return true; -} - -void WaveRecorder::start() -{ - _frame_pos = _frame; - snd_pcm_prepare(_pcm); - snd_pcm_start(_pcm); - snd_pcm_nonblock(_pcm, 1); -} - -void WaveRecorder::stop() -{ - snd_pcm_drop(_pcm); - snd_pcm_prepare(_pcm); -} - -bool WaveRecorder::abort() -{ - return true; -} - -void WaveRecorder::on_event() -{ - for (;;) { - snd_pcm_sframes_t size = (_frame_end - _frame_pos) / _sample_bytes; - size = snd_pcm_readi(_pcm, _frame_pos, size); - if (size < 0) { - if (snd_pcm_recover(_pcm, size, 1) == 0) { - continue; - } - return; - } - _frame_pos += size * _sample_bytes; - if (_frame_pos == _frame_end) { - _client.push_frame(_frame); - _frame_pos = _frame; - } - } -} diff --git a/client/x11/record.h b/client/x11/record.h deleted file mode 100644 index fc46948b..00000000 --- a/client/x11/record.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_LINUX_RECORD -#define _H_LINUX_RECORD - -#include <alsa/asoundlib.h> - -#include "common.h" -#include "audio_devices.h" -#include "platform.h" - -class WaveRecorder: public WaveRecordAbstract { -public: - WaveRecorder(Platform::RecordClient& client, - uint32_t samples_per_sec, - uint32_t bits_per_sample, - uint32_t channels, - uint32_t frame_size); - virtual ~WaveRecorder(); - - virtual void start(); - virtual void stop(); - virtual bool abort(); - -private: - bool init(uint32_t samples_per_sec, - uint32_t bits_per_sample, - uint32_t channels, - uint32_t frame_size); - void cleanup(); - void on_event(); - -private: - Platform::RecordClient& _client; - snd_pcm_t* _pcm; - snd_pcm_hw_params_t* _hw_params; - snd_pcm_sw_params_t* _sw_params; - uint32_t _sample_bytes; - uint32_t _frame_size; - uint8_t* _frame; - uint8_t* _frame_pos; - uint8_t* _frame_end; - class EventTrigger; - EventTrigger* _event_trigger; -}; - -#endif diff --git a/client/x11/red_drawable.cpp b/client/x11/red_drawable.cpp deleted file mode 100644 index 19532c74..00000000 --- a/client/x11/red_drawable.cpp +++ /dev/null @@ -1,796 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "red_drawable.h" -#include "pixels_source_p.h" -#include "debug.h" -#include "x_platform.h" -#include "utils.h" - -#ifdef USE_OPENGL -#include "common/gl_utils.h" -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glext.h> - -static inline void copy_to_gldrawable_from_gltexture(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - float text_x1, text_x2; - float text_y1, text_y2; - int vertex_x1, vertex_x2; - int vertex_y1, vertex_y2; - GLXPbuffer pbuffer; - GLXContext context; - RenderType rendertype; - Window win; - - text_x1 = (float)src_x / source->gl.width_powed; - text_x2 = text_x1 + (float)(area.right - area.left) / source->gl.width_powed; - - text_y1 = ((float)source->gl.height - (area.bottom - area.top) - src_y) / - source->gl.height_powed; - text_y2 = text_y1 + (float)(area.bottom - area.top) / source->gl.height_powed; - - vertex_x1 = area.left + offset.x; - vertex_y1 = dest->source.x_drawable.height - (area.top + offset.y) - (area.bottom - area.top); - vertex_x2 = vertex_x1 + (area.right - area.left); - vertex_y2 = vertex_y1 + (area.bottom - area.top); - - glEnable(GL_TEXTURE_2D); - - rendertype = source->gl.rendertype; - if (rendertype == RENDER_TYPE_FBO) { - glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); - } else { - win = source->gl.win; - context = source->gl.context; - glXMakeCurrent(XPlatform::get_display(), win, context); - } - - glBindTexture(GL_TEXTURE_2D, source->gl.tex); - - glBegin(GL_QUADS); - glTexCoord2f(text_x1, text_y1); - glVertex2i(vertex_x1, vertex_y1); - glTexCoord2f(text_x1, text_y2); - glVertex2i(vertex_x1, vertex_y2); - glTexCoord2f(text_x2, text_y2); - glVertex2i(vertex_x2, vertex_y2); - glTexCoord2f(text_x2, text_y1); - glVertex2i(vertex_x2, vertex_y1); - glEnd(); - - if (rendertype == RENDER_TYPE_FBO) { - GLuint fbo; - - glFlush(); - fbo = source->gl.fbo; - glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); - } else { - pbuffer = source->gl.pbuff; - glXMakeCurrent(XPlatform::get_display(), pbuffer, context); - } -} - -static inline void copy_to_gldrawable_from_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - uint8_t *addr; - GLXContext context = NULL; - GLXPbuffer pbuffer; - RenderType rendertype; - Window win; - - rendertype = dest->source.x_drawable.rendertype; - if (rendertype == RENDER_TYPE_FBO) { - glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } else { - context = dest->source.x_drawable.context; - win = dest->source.x_drawable.drawable; - glXMakeCurrent(XPlatform::get_display(), win, context); - glDisable(GL_TEXTURE_2D); - } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, pixman_image_get_stride(source->pixmap.pixman_image) / 4); - - glPixelZoom(1, -1); - addr = (uint8_t *)pixman_image_get_data(source->pixmap.pixman_image); - addr += (src_x * 4 + src_y * pixman_image_get_stride(source->pixmap.pixman_image)); - glWindowPos2i(area.left + offset.x, dest->source.x_drawable.height - - (area.top + offset.y)); //+ (area.bottom - area.top))); - glDrawPixels(area.right - area.left, area.bottom - area.top, - GL_BGRA, GL_UNSIGNED_BYTE, addr); - - if (rendertype == RENDER_TYPE_FBO) { - GLuint fbo; - - fbo = dest->source.x_drawable.fbo; - glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); - } else { - pbuffer = dest->source.x_drawable.pbuff; - glXMakeCurrent(XPlatform::get_display(), pbuffer, context); - } -} -#endif // USE_OPENGL - -static inline void copy_to_drawable_from_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - XGCValues gc_vals; - gc_vals.function = GXcopy; - - XChangeGC(XPlatform::get_display(), dest->source.x_drawable.gc, GCFunction, &gc_vals); - XCopyArea(XPlatform::get_display(), source->x_drawable.drawable, - dest->source.x_drawable.drawable, dest->source.x_drawable.gc, - src_x, src_y, - area.right - area.left, area.bottom - area.top, - area.left + offset.x, area.top + offset.y); -} - -static XImage *create_temp_image(int screen, int width, int height, - pixman_image_t **pixman_image_out, - XShmSegmentInfo **shminfo_out) -{ - XImage *image; - XShmSegmentInfo *shminfo; - RedDrawable::Format format; - pixman_image_t *pixman_image; - XVisualInfo *vinfo; - - image = NULL; - shminfo = NULL; - - vinfo = XPlatform::get_vinfo()[screen]; - format = XPlatform::get_screen_format(screen); - - image = XPlatform::create_x_image(format, width, height, vinfo->depth, - vinfo->visual, &shminfo); - - pixman_image = pixman_image_create_bits(RedDrawable::format_to_pixman(format), - width, height, - (uint32_t *)image->data, image->bytes_per_line); - if (pixman_image == NULL) { - THROW("surf create failed"); - } - *pixman_image_out = pixman_image; - *shminfo_out = shminfo; - return image; -} - -static void free_temp_image(XImage *image, XShmSegmentInfo *shminfo, pixman_image_t *pixman_image) -{ - XPlatform::free_x_image(image, shminfo); - pixman_image_unref(pixman_image); -} - - -static inline void copy_to_drawable_from_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - pixman_image_t *src_surface = source->pixmap.pixman_image; - XGCValues gc_vals; - gc_vals.function = GXcopy; - RedDrawable::Format screen_format; - XImage *image; - XShmSegmentInfo *shminfo; - pixman_image_t *pixman_image; - int screen; - - screen = dest->source.x_drawable.screen; - screen_format = XPlatform::get_screen_format(screen); - - XChangeGC(XPlatform::get_display(), dest->source.x_drawable.gc, GCFunction, &gc_vals); - - if (source->pixmap.x_image != NULL && - RedDrawable::format_copy_compatible(source->pixmap.format, screen_format)) { - if (source->pixmap.shminfo) { - XShmPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable, - dest->source.x_drawable.gc, source->pixmap.x_image, - src_x, src_y, area.left + offset.x, area.top + offset.y, - area.right - area.left, area.bottom - area.top, false); - } else { - XPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable, - dest->source.x_drawable.gc, source->pixmap.x_image, src_x, - src_y, area.left + offset.x, area.top + offset.y, - area.right - area.left, area.bottom - area.top); - } - } else { - image = create_temp_image(screen, - area.right - area.left, area.bottom - area.top, - &pixman_image, &shminfo); - - pixman_image_composite32(PIXMAN_OP_SRC, - src_surface, NULL, pixman_image, - src_x + offset.x, - src_y + offset.y, - 0, 0, - 0, 0, - area.right - area.left, - area.bottom - area.top); - - if (shminfo) { - XShmPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable, - dest->source.x_drawable.gc, image, - 0, 0, area.left + offset.x, area.top + offset.y, - area.right - area.left, area.bottom - area.top, false); - } else { - XPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable, - dest->source.x_drawable.gc, image, - 0, 0, area.left + offset.x, area.top + offset.y, - area.right - area.left, area.bottom - area.top); - } - - free_temp_image(image, shminfo, pixman_image); - } - XFlush(XPlatform::get_display()); -} - -static inline void copy_to_x_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - switch (source->type) { - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - copy_to_drawable_from_drawable(dest, area, offset, source, src_x, src_y); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - copy_to_drawable_from_pixmap(dest, area, offset, source, src_x, src_y); - break; - default: - THROW("invalid source type %d", source->type); - } -} - -#ifdef USE_OPENGL -static inline void copy_to_gl_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - switch (source->type) { - case PIXELS_SOURCE_TYPE_GL_TEXTURE: - copy_to_gldrawable_from_gltexture(dest, area, offset, source, src_x, src_y); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - copy_to_gldrawable_from_pixmap(dest, area, offset, source, src_x, src_y); - break; - default: - THROW("invalid source type %d", source->type); - } -} -#endif // USE_OPENGL - -static inline void copy_to_pixmap_from_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - LOG_WARN("not implemented"); -} - -static inline void copy_to_pixmap_from_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; - pixman_image_t *src_surface = source->pixmap.pixman_image; - - pixman_image_composite32(PIXMAN_OP_SRC, - src_surface, NULL, dest_surface, - src_x + offset.x, - src_y + offset.y, - 0, 0, - area.left + offset.x, - area.top + offset.y, - area.right - area.left, - area.bottom - area.top); -} - -#ifdef USE_OPENGL -static inline void copy_to_pixmap_from_gltexture(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - int y, height; - GLXContext context = NULL; - GLXPbuffer pbuffer; - Window win; - RenderType rendertype; - - y = source->gl.height - src_y; - height = area.bottom - area.top; - - rendertype = source->gl.rendertype; - if (rendertype == RENDER_TYPE_FBO) { - glBindFramebuffer(GL_FRAMEBUFFER_EXT, source->gl.fbo); - glBindTexture(GL_TEXTURE_2D, 0); - } else { - context = source->gl.context; - pbuffer = source->gl.pbuff; - glXMakeCurrent(XPlatform::get_display(), pbuffer, context); - glDisable(GL_TEXTURE_2D); - } - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - glPixelStorei(GL_PACK_ROW_LENGTH, - pixman_image_get_stride(dest->source.pixmap.pixman_image) / 4); - - while (height > 0) { - glReadPixels(src_x, y - height, area.right - area.left, 1, - GL_BGRA, GL_UNSIGNED_BYTE, - (uint8_t *)pixman_image_get_data(dest->source.pixmap.pixman_image) + - (area.left + offset.x) * 4 + - (area.top + offset.y + height - 1) * - pixman_image_get_stride(dest->source.pixmap.pixman_image)); - height--; - } - if (rendertype != RENDER_TYPE_FBO) { - win = source->gl.win; - glXMakeCurrent(XPlatform::get_display(), win, context); - } -} -#endif // USE_OPENGL - -static inline void copy_to_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - switch (source->type) { -#ifdef USE_OPENGL - case PIXELS_SOURCE_TYPE_GL_TEXTURE: - copy_to_pixmap_from_gltexture(dest, area, offset, source, src_x, src_y); - break; -#endif // USE_OPENGL - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - copy_to_pixmap_from_drawable(dest, area, offset, source, src_x, src_y); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - copy_to_pixmap_from_pixmap(dest, area, offset, source, src_x, src_y); - break; - default: - THROW("invalid source type %d", source->type); - } -} - -void RedDrawable::copy_pixels(const PixelsSource& src, int src_x, int src_y, const SpiceRect& area) -{ - PixelsSource_p* source = (PixelsSource_p*)src.get_opaque(); - RedDrawable_p* dest = (RedDrawable_p*)get_opaque(); - switch (dest->source.type) { -#ifdef USE_OPENGL - case PIXELS_SOURCE_TYPE_GL_DRAWABLE: - copy_to_gl_drawable(dest, area, _origin, source, src_x + src._origin.x, - src_y + src._origin.y); - break; -#endif // USE_OPENGL - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - copy_to_x_drawable(dest, area, _origin, source, src_x + src._origin.x, - src_y + src._origin.y); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - copy_to_pixmap(dest, area, _origin, source, src_x + src._origin.x, src_y + src._origin.y); - break; - default: - THROW("invalid dest type %d", dest->source.type); - } -} - -static inline void blend_to_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - LOG_WARN("not implemented"); -} - -static inline void blend_to_pixmap_from_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - LOG_WARN("not implemented"); -} - -static inline void blend_to_pixmap_from_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; - pixman_image_t *src_surface = source->pixmap.pixman_image; - - pixman_image_composite32 (PIXMAN_OP_ATOP, - src_surface, NULL, dest_surface, - src_x + offset.x, - src_y + offset.y, - 0, 0, - area.left + offset.x, - area.top + offset.y, - area.right - area.left, - area.bottom - area.top); -} - -static inline void blend_to_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y) -{ - switch (source->type) { - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - blend_to_pixmap_from_drawable(dest, area, offset, source, src_x, src_y); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - blend_to_pixmap_from_pixmap(dest, area, offset, source, src_x, src_y); - break; - default: - THROW("invalid source type %d", source->type); - } -} - -void RedDrawable::blend_pixels(const PixelsSource& src, int src_x, int src_y, const SpiceRect& area) -{ - PixelsSource_p* source = (PixelsSource_p*)src.get_opaque(); - RedDrawable_p* dest = (RedDrawable_p*)get_opaque(); - switch (dest->source.type) { - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - blend_to_drawable(dest, area, _origin, source, src_x + src._origin.x, - src_y + src._origin.y); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - blend_to_pixmap(dest, area, _origin, source, src_x + src._origin.x, src_y + src._origin.y); - break; - default: - THROW("invalid dest type %d", dest->source.type); - } -} - -static inline void combine_to_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y, - RedDrawable::CombineOP op) -{ - LOG_WARN("not implemented"); -} - -static inline void combine_to_pixmap_from_drawable(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y, - RedDrawable::CombineOP op) -{ - LOG_WARN("not implemented"); -} - -static inline void combine_to_pixmap_from_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y, - RedDrawable::CombineOP op) -{ - pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; - pixman_image_t *src_surface = source->pixmap.pixman_image; - - SpiceROP rop; - switch (op) { - case RedDrawable::OP_COPY: - rop = SPICE_ROP_COPY; - break; - case RedDrawable::OP_AND: - rop = SPICE_ROP_AND; - break; - case RedDrawable::OP_XOR: - rop = SPICE_ROP_XOR; - break; - default: - THROW("invalid op %d", op); - } - - - if (pixman_image_get_depth (src_surface) == 1) { - pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff }; - pixman_image_t *solid; - pixman_image_t *temp; - - /* Create a temporary rgb32 image that is black where mask is 0 - and white where mask is 1 */ - temp = pixman_image_create_bits(pixman_image_get_depth(dest_surface) == 24 ? - PIXMAN_x8r8g8b8 : PIXMAN_a8r8g8b8, - area.right - area.left, - area.bottom - area.top, NULL, 0); - solid = pixman_image_create_solid_fill(&white); - pixman_image_composite32(PIXMAN_OP_SRC, - solid, src_surface, temp, - 0, 0, - src_x + offset.x, - src_y + offset.y, - 0, 0, - area.right - area.left, - area.bottom - area.top); - pixman_image_unref(solid); - - /* ROP the temp image on the destination */ - spice_pixman_blit_rop(dest_surface, - temp, - 0, - 0, - area.left + offset.x, - area.top + offset.y, - area.right - area.left, - area.bottom - area.top, - rop); - pixman_image_unref(temp); - - } else { - spice_pixman_blit_rop(dest_surface, - src_surface, - src_x + offset.x, - src_y + offset.y, - area.left + offset.x, - area.top + offset.y, - area.right - area.left, - area.bottom - area.top, - rop); - } -} - -static inline void combine_to_pixmap(const RedDrawable_p* dest, - const SpiceRect& area, - const SpicePoint& offset, - const PixelsSource_p* source, - int src_x, int src_y, - RedDrawable::CombineOP op) -{ - switch (source->type) { - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - combine_to_pixmap_from_drawable(dest, area, offset, source, src_x, src_y, op); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - combine_to_pixmap_from_pixmap(dest, area, offset, source, src_x, src_y, op); - break; - default: - THROW("invalid source type %d", source->type); - } -} - -void RedDrawable::combine_pixels(const PixelsSource& src, int src_x, int src_y, const SpiceRect& area, - CombineOP op) -{ - PixelsSource_p* source = (PixelsSource_p*)src.get_opaque(); - RedDrawable_p* dest = (RedDrawable_p*)get_opaque(); - switch (dest->source.type) { - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - combine_to_drawable(dest, area, _origin, source, src_x + src._origin.x, - src_y + src._origin.y, op); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - combine_to_pixmap(dest, area, _origin, source, src_x + src._origin.x, - src_y + src._origin.y, op); - break; - default: - THROW("invalid dest type %d", dest->source.type); - } -} - -void RedDrawable::erase_rect(const SpiceRect& area, rgb32_t color) -{ - LOG_WARN("not implemented"); -} - -static inline void fill_drawable(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color, - const SpicePoint& offset) -{ - Drawable drawable = dest->source.x_drawable.drawable; - GC gc = dest->source.x_drawable.gc; - - XLockDisplay(XPlatform::get_display()); - Colormap color_map = DefaultColormap(XPlatform::get_display(), - DefaultScreen(XPlatform::get_display())); - XColor x_color; - x_color.red = (uint16_t)rgb32_get_red(color) << 8; - x_color.green = (uint16_t)rgb32_get_green(color) << 8; - x_color.blue = (uint16_t)rgb32_get_blue(color) << 8; - x_color.flags = DoRed | DoGreen | DoBlue; - //todo: optimize color map - if (!XAllocColor(XPlatform::get_display(), color_map, &x_color)) { - LOG_WARN("color map failed"); - } - XUnlockDisplay(XPlatform::get_display()); - - XGCValues gc_vals; - gc_vals.foreground = x_color.pixel; - gc_vals.function = GXcopy; - gc_vals.fill_style = FillSolid; - XChangeGC(XPlatform::get_display(), gc, GCFunction | GCForeground | GCFillStyle, &gc_vals); - XFillRectangle(XPlatform::get_display(), drawable, - gc, area.left + offset.x, area.top + offset.y, - area.right - area.left, area.bottom - area.top); -} - -#ifdef USE_OPENGL -static inline void fill_gl_drawable(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color, - const SpicePoint& offset) -{ - int vertex_x1, vertex_x2; - int vertex_y1, vertex_y2; - GLXContext context; - - context = glXGetCurrentContext(); - if (!context) { - return; - } - - vertex_x1 = area.left + offset.x; - vertex_y1 = dest->source.x_drawable.height - (area.top + offset.y) - (area.bottom - area.top); - - vertex_x2 = vertex_x1 + (area.right - area.left); - vertex_y2 = vertex_y1 + (area.bottom - area.top); - - glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); - - glColor3f(rgb32_get_red(color), rgb32_get_green(color), - rgb32_get_blue(color)); - - glBegin(GL_QUADS); - glVertex2i(vertex_x1, vertex_y1); - glVertex2i(vertex_x1, vertex_y2); - glVertex2i(vertex_x2, vertex_y2); - glVertex2i(vertex_x2, vertex_y1); - glEnd(); - glFlush(); - - glColor3f(1, 1, 1); -} -#endif // USE_OPENGL - -static inline void fill_pixmap(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color, - const SpicePoint& offset) -{ - pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; - - spice_pixman_fill_rect(dest_surface, - area.left + offset.x, area.top + offset.y, - area.right - area.left, - area.bottom - area.top, - color); -} - -void RedDrawable::fill_rect(const SpiceRect& area, rgb32_t color) -{ - RedDrawable_p* dest = (RedDrawable_p*)get_opaque(); - switch (dest->source.type) { -#ifdef USE_OPENGL - case PIXELS_SOURCE_TYPE_GL_DRAWABLE: - fill_gl_drawable(dest, area, color, _origin); - break; -#endif // USE_OPENGL - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - fill_drawable(dest, area, color, _origin); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - fill_pixmap(dest, area, color, _origin); - break; - default: - THROW("invalid dest type %d", dest->source.type); - } -} - -static inline void frame_drawable(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color, - const SpicePoint& offset) -{ - Drawable drawable = dest->source.x_drawable.drawable; - GC gc = dest->source.x_drawable.gc; - - XLockDisplay(XPlatform::get_display()); - Colormap color_map = DefaultColormap(XPlatform::get_display(), - DefaultScreen(XPlatform::get_display())); - XColor x_color; - x_color.red = (uint16_t)rgb32_get_red(color) << 8; - x_color.green = (uint16_t)rgb32_get_green(color) << 8; - x_color.blue = (uint16_t)rgb32_get_blue(color) << 8; - x_color.flags = DoRed | DoGreen | DoBlue; - //todo: optimize color map - if (!XAllocColor(XPlatform::get_display(), color_map, &x_color)) { - LOG_WARN("color map failed"); - } - XUnlockDisplay(XPlatform::get_display()); - - XGCValues gc_vals; - gc_vals.foreground = x_color.pixel; - gc_vals.function = GXcopy; - gc_vals.fill_style = FillSolid; - XChangeGC(XPlatform::get_display(), gc, GCFunction | GCForeground | GCFillStyle, &gc_vals); - XFillRectangle(XPlatform::get_display(), drawable, - gc, area.left + offset.x, area.top + offset.y, - area.right - area.left, area.bottom - area.top); -} - -static inline void frame_pixmap(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color, - const SpicePoint& offset) -{ - pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; - - spice_pixman_fill_rect(dest_surface, - area.left + offset.x, area.top + offset.y, - area.right - area.left, - 1, - color); - spice_pixman_fill_rect(dest_surface, - area.left + offset.x, area.bottom + offset.y, - area.right - area.left, - 1, - color); - spice_pixman_fill_rect(dest_surface, - area.left + offset.x, area.top + offset.y, - 1, - area.bottom - area.top, - color); - spice_pixman_fill_rect(dest_surface, - area.right + offset.x, area.top + offset.y, - 1, - area.bottom - area.top, - color); -} - -void RedDrawable::frame_rect(const SpiceRect& area, rgb32_t color) -{ - RedDrawable_p* dest = (RedDrawable_p*)get_opaque(); - switch (dest->source.type) { - case PIXELS_SOURCE_TYPE_X_DRAWABLE: - frame_drawable(dest, area, color, _origin); - break; - case PIXELS_SOURCE_TYPE_PIXMAP: - frame_pixmap(dest, area, color, _origin); - break; - default: - THROW("invalid dest type %d", dest->source.type); - } -} diff --git a/client/x11/red_pixmap.cpp b/client/x11/red_pixmap.cpp deleted file mode 100644 index af30f526..00000000 --- a/client/x11/red_pixmap.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "red_pixmap.h" -#include "debug.h" -#include "utils.h" - -RedPixmap::RedPixmap(int width, int height, RedPixmap::Format format, - bool top_bottom) - : _format (format) - , _width (width) - , _height (height) - , _stride (SPICE_ALIGN(width * format_to_bpp(format), 32) / 8) - , _top_bottom (top_bottom) - , _data (NULL) -{ -} - -RedPixmap::~RedPixmap() -{ -} - -bool RedPixmap::is_big_endian_bits() -{ - return false; -} diff --git a/client/x11/red_pixmap_gl.cpp b/client/x11/red_pixmap_gl.cpp deleted file mode 100644 index 7978a40b..00000000 --- a/client/x11/red_pixmap_gl.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glext.h> -#include <X11/Xlib.h> -#include "common/gl_utils.h" - -#include "common.h" -#include "red_pixmap_gl.h" -#include "debug.h" -#include "utils.h" -#include "pixels_source_p.h" -#include "x_platform.h" -#include "red_window_p.h" - - -RedPixmapGL::RedPixmapGL(int width, int height, RedDrawable::Format format, - bool top_bottom, RedWindow *win, - RenderType rendertype) - : RedPixmap(width, height, format, top_bottom) -{ - GLuint fbo = 0; - GLuint tex = 0; - GLuint stencil_tex = 0; - GLuint rbo = 0; - Win xwin; - //GLint max_texture_size; - - ASSERT(format == RedDrawable::ARGB32 || format == RedDrawable::RGB32 || format == RedDrawable::A1); - ASSERT(sizeof(RedDrawable_p) <= PIXELES_SOURCE_OPAQUE_SIZE); - - ((PixelsSource_p*)get_opaque())->type = PIXELS_SOURCE_TYPE_GL_TEXTURE; - - _glcont = win->create_context_gl(); - if (!_glcont) { - THROW("glXCreateContext failed"); - } - - win->set_gl_context(_glcont); - - xwin = ((RedWindow_p*)win)->get_window(); - - /*glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - if (width > max_texture_size || height > max_texture_size) { - throw Exception(fmt("%s: unsuported max %|| width %|| height %||") - % __FUNCTION__ - % max_texture_size - % width - % height); - }*/ - - if (rendertype == RENDER_TYPE_FBO) { - int w = gl_get_to_power_two(width); - int h = gl_get_to_power_two(height); - - glXMakeCurrent(XPlatform::get_display(), xwin, _glcont); - if (!gluCheckExtension((GLubyte *)"GL_EXT_framebuffer_object", - glGetString(GL_EXTENSIONS))) { - glXMakeCurrent(XPlatform::get_display(), 0, 0); - glXDestroyContext(XPlatform::get_display(), _glcont); - THROW("no GL_EXT_framebuffer_object extension"); - } - - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, 0); - - glGenRenderbuffers(1, &rbo); - glBindRenderbuffer(GL_RENDERBUFFER, rbo); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) - THROW("bad fbo status: %d\n", status); - - ((PixelsSource_p*)get_opaque())->gl.fbo = fbo; - win->set_render_fbo(fbo); - - } else if (rendertype == RENDER_TYPE_PBUFF) { - GLXPbuffer pbuff; - - pbuff = win->create_pbuff(gl_get_to_power_two(width), - gl_get_to_power_two(height)); - if (!pbuff) { - glXDestroyContext(XPlatform::get_display(), _glcont); - THROW("pbuff creation failed"); - } - glXMakeCurrent(XPlatform::get_display(), pbuff, _glcont); - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - - glTexImage2D(GL_TEXTURE_2D, 0, 4, gl_get_to_power_two(width), - gl_get_to_power_two(height), 0, GL_BGRA, GL_UNSIGNED_BYTE, - NULL); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glBindTexture(GL_TEXTURE_2D, 0); - ((PixelsSource_p*)get_opaque())->gl.pbuff = pbuff; - win->set_render_pbuff(pbuff); - } else { - abort(); - } - - ((PixelsSource_p*)get_opaque())->gl.stencil_tex = stencil_tex; - ((PixelsSource_p*)get_opaque())->gl.tex = tex; - ((PixelsSource_p*)get_opaque())->gl.width = width; - ((PixelsSource_p*)get_opaque())->gl.height = height; - ((PixelsSource_p*)get_opaque())->gl.width_powed = gl_get_to_power_two(width); - ((PixelsSource_p*)get_opaque())->gl.height_powed = gl_get_to_power_two(height); - ((PixelsSource_p*)get_opaque())->gl.win = xwin; - ((PixelsSource_p*)get_opaque())->gl.rendertype = rendertype; - ((PixelsSource_p*)get_opaque())->gl.context = _glcont; - - _textures_lost = false; - - GLC_ERROR_TEST_FINISH; -} - -void RedPixmapGL::textures_lost() -{ - _textures_lost = true; -} - -void RedPixmapGL::touch_context() -{ - Win win; - GLXPbuffer pbuff; - RenderType rendertype; - - rendertype = ((PixelsSource_p*)get_opaque())->gl.rendertype; - if (rendertype == RENDER_TYPE_FBO) { - win = ((PixelsSource_p*)get_opaque())->gl.win; - if (_glcont) { - glXMakeCurrent(XPlatform::get_display(), win, _glcont); - } - } else { - pbuff = ((PixelsSource_p*)get_opaque())->gl.pbuff; - glXMakeCurrent(XPlatform::get_display(), pbuff, _glcont); - } - GLC_ERROR_TEST_FLUSH; -} - -void RedPixmapGL::update_texture(const SpiceRect *bbox) -{ - RenderType rendertype; - GLuint tex; - int height; - - rendertype = ((PixelsSource_p*)get_opaque())->gl.rendertype; - - if (rendertype == RENDER_TYPE_PBUFF) { - int tex_x, tex_y; - int vertex_x1, vertex_x2; - int vertex_y1, vertex_y2; - int is_enabled; - GLint prev_tex; - - height = ((PixelsSource_p*)get_opaque())->gl.height; - - tex = ((PixelsSource_p*)get_opaque())->gl.tex; - - tex_x = bbox->left; - tex_y = height - bbox->bottom; - vertex_x1 = bbox->left; - vertex_y1 = height - bbox->bottom; - vertex_x2 = vertex_x1 + (bbox->right - bbox->left); - vertex_y2 = vertex_y1 + (bbox->bottom - bbox->top); - - is_enabled = glIsEnabled(GL_TEXTURE_2D); - if (!is_enabled) { - glEnable(GL_TEXTURE_2D); - } else { - glGetIntegerv(GL_TEXTURE_BINDING_2D, &prev_tex); - } - glBindTexture(GL_TEXTURE_2D, tex); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, tex_x, tex_y, vertex_x1, - vertex_y1, vertex_x2 - vertex_x1, - vertex_y2 - vertex_y1); - if (!is_enabled) { - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); - } else { - glBindTexture(GL_TEXTURE_2D, prev_tex); - } - } - GLC_ERROR_TEST_FLUSH; -} - -void RedPixmapGL::pre_copy() -{ - glFlush(); - - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TEXTURE_BIT | - GL_TRANSFORM_BIT); - - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, ((PixelsSource_p*)get_opaque())->gl.width, 0, - ((PixelsSource_p*)get_opaque())->gl.height); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glViewport(0, 0, ((PixelsSource_p*)get_opaque())->gl.width, - ((PixelsSource_p*)get_opaque())->gl.height); - - - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glDisable(GL_COLOR_LOGIC_OP); - glDisable(GL_STENCIL_TEST); - - glColor3f(1, 1, 1); -} - -void RedPixmapGL::past_copy() -{ - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_TEXTURE); - glPopMatrix(); - - glPopAttrib(); - glFlush(); -} - -RedPixmapGL::~RedPixmapGL() -{ - GLXPbuffer pbuff; - GLuint fbo, rbo; - RenderType rendertype; - GLuint tex; - GLuint stencil_tex; - - rendertype = ((PixelsSource_p*)get_opaque())->gl.rendertype; - if (rendertype == RENDER_TYPE_FBO) { - fbo = ((PixelsSource_p*)get_opaque())->gl.fbo; - rbo = ((PixelsSource_p*)get_opaque())->gl.rbo; - spice_debug("deletefbo %u", fbo); - if (fbo) { - glDeleteFramebuffers(1, &fbo); - } - if (rbo) { - glDeleteRenderbuffers(1, &rbo); - } - } else { - pbuff = ((PixelsSource_p*)get_opaque())->gl.pbuff; - glXDestroyPbuffer(XPlatform::get_display(), pbuff); - } - - /* - * GL textures might be destroyed by res change. - */ - if (!_textures_lost) { - tex = ((PixelsSource_p*)get_opaque())->gl.tex; - stencil_tex = ((PixelsSource_p*)get_opaque())->gl.stencil_tex; - if (tex) { - glDeleteTextures(1, &tex); - } - if (stencil_tex) { - glDeleteTextures(1, &stencil_tex); - } - if (_glcont) { - glXDestroyContext(XPlatform::get_display(), _glcont); - } - } - - /* - * Both tex and stenctil_tex are textures and therefore they are destroyed - * when the context is gone, so we dont free them here as they might have - * already been destroyed. - */ - GLC_ERROR_TEST_FINISH; -} diff --git a/client/x11/red_pixmap_sw.cpp b/client/x11/red_pixmap_sw.cpp deleted file mode 100644 index 3fd86778..00000000 --- a/client/x11/red_pixmap_sw.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "red_pixmap_sw.h" -#include "debug.h" -#include "utils.h" -#include "pixels_source_p.h" -#include "x_platform.h" - -RedPixmapSw::RedPixmapSw(int width, int height, RedDrawable::Format format, - bool top_bottom, RedWindow *win) - : RedPixmap(width, height, format, top_bottom) -{ - ASSERT(format == RedDrawable::ARGB32 || format == RedDrawable::RGB32 || - format == RedDrawable::RGB16_555 || format == RedDrawable::RGB16_565 || - format == RedDrawable::A1); - ASSERT(sizeof(RedDrawable_p) <= PIXELES_SOURCE_OPAQUE_SIZE); - pixman_image_t *pixman_image; - XImage *image; - XShmSegmentInfo *shminfo; - _data = NULL; - XVisualInfo *vinfo; - int screen_num; - RedDrawable::Format screen_format; - - screen_num = win ? win->get_screen_num() : 0; - vinfo = XPlatform::get_vinfo()[screen_num]; - screen_format = XPlatform::get_screen_format(screen_num); - - image = NULL; - shminfo = NULL; - - /* Only create XImage if same format as screen (needs re-verifying at - draw time!) */ - if (RedDrawable::format_copy_compatible(format, screen_format) || - format == A1) { - image = XPlatform::create_x_image(format, width, height, - vinfo->depth, vinfo->visual, - &shminfo); - _stride = image->bytes_per_line; - _data = (uint8_t *)image->data; - } else { - _data = new uint8_t[height * _stride]; - } - - pixman_image = pixman_image_create_bits(RedDrawable::format_to_pixman(format), - _width, _height, - (uint32_t *)_data, _stride); - if (pixman_image == NULL) { - THROW("surf create failed"); - } - - ((PixelsSource_p*)get_opaque())->type = PIXELS_SOURCE_TYPE_PIXMAP; - ((PixelsSource_p*)get_opaque())->pixmap.shminfo = shminfo; - ((PixelsSource_p*)get_opaque())->pixmap.x_image = image; - ((PixelsSource_p*)get_opaque())->pixmap.pixman_image = pixman_image; - ((PixelsSource_p*)get_opaque())->pixmap.format = format; -} - -RedPixmapSw::~RedPixmapSw() -{ - ASSERT(((PixelsSource_p*)get_opaque())->type == PIXELS_SOURCE_TYPE_PIXMAP); - - XShmSegmentInfo *shminfo = ((PixelsSource_p*)get_opaque())->pixmap.shminfo; - XImage *image = ((PixelsSource_p*)get_opaque())->pixmap.x_image; - - pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image); - - if (image) { - XPlatform::free_x_image(image, shminfo); - } else { - delete[] _data; - } -} diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp deleted file mode 100644 index 7e16fcd2..00000000 --- a/client/x11/red_window.cpp +++ /dev/null @@ -1,2251 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include <X11/Xlib.h> -#include <X11/Xresource.h> -#include <X11/keysymdef.h> -#include <X11/Xatom.h> -#include <X11/XKBlib.h> - -#ifdef USE_OPENGL -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glx.h> -#include <GL/glext.h> -#endif // USE_OPENGL -#include <stdio.h> - -#include <spice/protocol.h> -#include "common/region.h" - -#ifdef USE_OPENGL -#include "common/gl_utils.h" -#include "red_pixmap_gl.h" -#endif // USE_OPENGL - -#include "red_window.h" -#include "utils.h" -#include "debug.h" -#include "platform.h" -#include "x_platform.h" -#include "pixels_source_p.h" -#include "x_icon.h" - -#define X_RETRIES 10 -#define X_RETRY_DELAY_MICRO (1000 * 100) -#define RAISE_RETRIES X_RETRIES -#define Z_POSITION_RETRIES X_RETRIES -#define GET_POSITION_RETRIES X_RETRIES -#define GET_VIS_REGION_RETRIES X_RETRIES -#define MOUSE_GRAB_RETRIES X_RETRIES - -static Display* x_display = NULL; -static XContext user_data_context; -static bool using_evdev = false; -static XIC x_input_context = NULL; - -static Atom wm_protocol_atom; -static Atom wm_delete_window_atom; - -static Atom wm_desktop; -static Atom wm_current_desktop; - -static Atom wm_state; -static Atom wm_state_above; -static Atom wm_state_fullscreen; - -static Atom wm_user_time; - -static RedWindow* focus_window; -static unsigned long focus_serial = 0; - -#define USE_X11_KEYCODE - -#ifdef USE_X11_KEYCODE - -enum EvdevKeyCode { - EVDEV_KEYCODE_ESCAPE = 9, - EVDEV_KEYCODE_1, - EVDEV_KEYCODE_2, - EVDEV_KEYCODE_3, - EVDEV_KEYCODE_4, - EVDEV_KEYCODE_5, - EVDEV_KEYCODE_6, - EVDEV_KEYCODE_7, - EVDEV_KEYCODE_8, - EVDEV_KEYCODE_9, - EVDEV_KEYCODE_0, - EVDEV_KEYCODE_MINUS, - EVDEV_KEYCODE_EQUAL, - EVDEV_KEYCODE_BACK_SPACE, - EVDEV_KEYCODE_TAB, - EVDEV_KEYCODE_Q, - EVDEV_KEYCODE_W, - EVDEV_KEYCODE_E, - EVDEV_KEYCODE_R, - EVDEV_KEYCODE_T, - EVDEV_KEYCODE_Y, - EVDEV_KEYCODE_U, - EVDEV_KEYCODE_I, - EVDEV_KEYCODE_O, - EVDEV_KEYCODE_P, - EVDEV_KEYCODE_L_BRACKET, - EVDEV_KEYCODE_R_BRACKET, - EVDEV_KEYCODE_RETURN, - EVDEV_KEYCODE_L_CONTROL, - EVDEV_KEYCODE_A, - EVDEV_KEYCODE_S, - EVDEV_KEYCODE_D, - EVDEV_KEYCODE_F, - EVDEV_KEYCODE_G, - EVDEV_KEYCODE_H, - EVDEV_KEYCODE_J, - EVDEV_KEYCODE_K, - EVDEV_KEYCODE_L, - EVDEV_KEYCODE_SEMICOLON, - EVDEV_KEYCODE_APOSTROPH, - EVDEV_KEYCODE_BACKQUAT, - EVDEV_KEYCODE_L_SHIFT, - EVDEV_KEYCODE_BACKSLASH, - EVDEV_KEYCODE_Z, - EVDEV_KEYCODE_X, - EVDEV_KEYCODE_C, - EVDEV_KEYCODE_V, - EVDEV_KEYCODE_B, - EVDEV_KEYCODE_N, - EVDEV_KEYCODE_M, - EVDEV_KEYCODE_COMMA, - EVDEV_KEYCODE_PERIOD, - EVDEV_KEYCODE_SLASH, - EVDEV_KEYCODE_R_SHIFT, - EVDEV_KEYCODE_PAD_MULTIPLY, - EVDEV_KEYCODE_L_ALT, - EVDEV_KEYCODE_SPACE, - EVDEV_KEYCODE_CAPS_LOCK, - EVDEV_KEYCODE_F1, - EVDEV_KEYCODE_F2, - EVDEV_KEYCODE_F3, - EVDEV_KEYCODE_F4, - EVDEV_KEYCODE_F5, - EVDEV_KEYCODE_F6, - EVDEV_KEYCODE_F7, - EVDEV_KEYCODE_F8, - EVDEV_KEYCODE_F9, - EVDEV_KEYCODE_F10, - EVDEV_KEYCODE_NUM_LOCK, - EVDEV_KEYCODE_SCROLL_LOCK, - EVDEV_KEYCODE_PAD_7, - EVDEV_KEYCODE_PAD_8, - EVDEV_KEYCODE_PAD_9, - EVDEV_KEYCODE_PAD_SUBTRACT, - EVDEV_KEYCODE_PAD_4, - EVDEV_KEYCODE_PAD_5, - EVDEV_KEYCODE_PAD_6, - EVDEV_KEYCODE_PAD_ADD, - EVDEV_KEYCODE_PAD_1, - EVDEV_KEYCODE_PAD_2, - EVDEV_KEYCODE_PAD_3, - EVDEV_KEYCODE_PAD_0, - EVDEV_KEYCODE_PAD_DEL, - EVDEV_KEYCODE_EUROPEAN = 94, - EVDEV_KEYCODE_F11, - EVDEV_KEYCODE_F12, - EVDEV_KEYCODE_JAPANESE_BACKSLASH, - EVDEV_KEYCODE_JAPANESE_HENKAN = 100, - EVDEV_KEYCODE_JAPANESE_HIRAGANA_KATAKANA, - EVDEV_KEYCODE_JAPANESE_MUHENKAN, - EVDEV_KEYCODE_PAD_ENTER = 104, - EVDEV_KEYCODE_R_CONTROL, - EVDEV_KEYCODE_PAD_DEVIDE, - EVDEV_KEYCODE_PRINT, - EVDEV_KEYCODE_R_ALT, - EVDEV_KEYCODE_HOME = 110, - EVDEV_KEYCODE_UP, - EVDEV_KEYCODE_PAGE_UP, - EVDEV_KEYCODE_LEFT, - EVDEV_KEYCODE_RIGHT, - EVDEV_KEYCODE_END, - EVDEV_KEYCODE_DOWN, - EVDEV_KEYCODE_PAGE_DOWN, - EVDEV_KEYCODE_INSERT, - EVDEV_KEYCODE_DELETE, - EVDEV_KEYCODE_MUTE = 121, - EVDEV_KEYCODE_VOLUME_DOWN = 122, - EVDEV_KEYCODE_VOLUME_UP = 123, - EVDEV_KEYCODE_PAUSE = 127, - EVDEV_KEYCODE_HANGUL = 130, - EVDEV_KEYCODE_HANGUL_HANJA, - EVDEV_KEYCODE_YEN, - EVDEV_KEYCODE_L_COMMAND, - EVDEV_KEYCODE_R_COMMAND, - EVDEV_KEYCODE_MENU, -}; - -enum KbdKeyCode { - KBD_KEYCODE_ESCAPE = 9, - KBD_KEYCODE_1, - KBD_KEYCODE_2, - KBD_KEYCODE_3, - KBD_KEYCODE_4, - KBD_KEYCODE_5, - KBD_KEYCODE_6, - KBD_KEYCODE_7, - KBD_KEYCODE_8, - KBD_KEYCODE_9, - KBD_KEYCODE_0, - KBD_KEYCODE_MINUS, - KBD_KEYCODE_EQUAL, - KBD_KEYCODE_BACK_SPACE, - KBD_KEYCODE_TAB, - KBD_KEYCODE_Q, - KBD_KEYCODE_W, - KBD_KEYCODE_E, - KBD_KEYCODE_R, - KBD_KEYCODE_T, - KBD_KEYCODE_Y, - KBD_KEYCODE_U, - KBD_KEYCODE_I, - KBD_KEYCODE_O, - KBD_KEYCODE_P, - KBD_KEYCODE_L_BRACKET, - KBD_KEYCODE_R_BRACKET, - KBD_KEYCODE_RETURN, - KBD_KEYCODE_L_CONTROL, - KBD_KEYCODE_A, - KBD_KEYCODE_S, - KBD_KEYCODE_D, - KBD_KEYCODE_F, - KBD_KEYCODE_G, - KBD_KEYCODE_H, - KBD_KEYCODE_J, - KBD_KEYCODE_K, - KBD_KEYCODE_L, - KBD_KEYCODE_SEMICOLON, - KBD_KEYCODE_APOSTROPH, - KBD_KEYCODE_BACKQUAT, - KBD_KEYCODE_L_SHIFT, - KBD_KEYCODE_BACKSLASH, - KBD_KEYCODE_Z, - KBD_KEYCODE_X, - KBD_KEYCODE_C, - KBD_KEYCODE_V, - KBD_KEYCODE_B, - KBD_KEYCODE_N, - KBD_KEYCODE_M, - KBD_KEYCODE_COMMA, - KBD_KEYCODE_PERIOD, - KBD_KEYCODE_SLASH, - KBD_KEYCODE_R_SHIFT, - KBD_KEYCODE_PAD_MULTIPLY, - KBD_KEYCODE_L_ALT, - KBD_KEYCODE_SPACE, - KBD_KEYCODE_CAPS_LOCK, - KBD_KEYCODE_F1, - KBD_KEYCODE_F2, - KBD_KEYCODE_F3, - KBD_KEYCODE_F4, - KBD_KEYCODE_F5, - KBD_KEYCODE_F6, - KBD_KEYCODE_F7, - KBD_KEYCODE_F8, - KBD_KEYCODE_F9, - KBD_KEYCODE_F10, - KBD_KEYCODE_NUM_LOCK, - KBD_KEYCODE_SCROLL_LOCK, - KBD_KEYCODE_PAD_7, - KBD_KEYCODE_PAD_8, - KBD_KEYCODE_PAD_9, - KBD_KEYCODE_PAD_SUBTRACT, - KBD_KEYCODE_PAD_4, - KBD_KEYCODE_PAD_5, - KBD_KEYCODE_PAD_6, - KBD_KEYCODE_PAD_ADD, - KBD_KEYCODE_PAD_1, - KBD_KEYCODE_PAD_2, - KBD_KEYCODE_PAD_3, - KBD_KEYCODE_PAD_0, - KBD_KEYCODE_PAD_DEL, - KBD_KEYCODE_EUROPEAN = 94, - KBD_KEYCODE_F11, - KBD_KEYCODE_F12, - KBD_KEYCODE_HOME, - KBD_KEYCODE_UP, - KBD_KEYCODE_PAGE_UP, - KBD_KEYCODE_LEFT, - KBD_KEYCODE_RIGHT = 102, - KBD_KEYCODE_END, - KBD_KEYCODE_DOWN, - KBD_KEYCODE_PAGE_DOWN, - KBD_KEYCODE_INSERT, - KBD_KEYCODE_DELETE, - KBD_KEYCODE_PAD_ENTER, - KBD_KEYCODE_R_CONTROL, - KBD_KEYCODE_PAUSE, - KBD_KEYCODE_PRINT, - KBD_KEYCODE_PAD_DEVIDE, - KBD_KEYCODE_R_ALT, - KBD_KEYCODE_L_COMMAND = 115, - KBD_KEYCODE_R_COMMAND, - KBD_KEYCODE_MENU, - KBD_KEYCODE_JAPANESE_HENKAN = 129, - KBD_KEYCODE_JAPANESE_MUHENKAN = 131, - KBD_KEYCODE_YEN = 133, - KBD_KEYCODE_JAPANESE_HIRAGANA_KATAKANA = 208, - KBD_KEYCODE_HANGUL_HANJA, - KBD_KEYCODE_HANGUL, - KBD_KEYCODE_JAPANESE_BACKSLASH, -}; - -static void query_keyboard() -{ - XLockDisplay(x_display); - XkbDescPtr kbd_desk = XkbGetKeyboard(x_display, XkbAllComponentsMask, XkbUseCoreKbd); - XUnlockDisplay(x_display); - if (!kbd_desk) { - LOG_WARN("get keyboard failed"); - return; - } - - XLockDisplay(x_display); - char* keycodes = XGetAtomName(x_display, kbd_desk->names->keycodes); - XUnlockDisplay(x_display); - - if (keycodes) { - if (strstr(keycodes, "evdev")) { - using_evdev = true; - } - XFree(keycodes); - } else { - LOG_WARN("get name failed"); - } - XkbFreeClientMap(kbd_desk, XkbAllComponentsMask, True); -} - -static RedKey keycode_map[256]; - -#define INIT_MAP \ - KEYMAP(KEYCODE_ESCAPE, REDKEY_ESCAPE); \ - KEYMAP(KEYCODE_1, REDKEY_1); \ - KEYMAP(KEYCODE_2, REDKEY_2); \ - KEYMAP(KEYCODE_3, REDKEY_3); \ - KEYMAP(KEYCODE_4, REDKEY_4); \ - KEYMAP(KEYCODE_5, REDKEY_5); \ - KEYMAP(KEYCODE_6, REDKEY_6); \ - KEYMAP(KEYCODE_7, REDKEY_7); \ - KEYMAP(KEYCODE_8, REDKEY_8); \ - KEYMAP(KEYCODE_9, REDKEY_9); \ - KEYMAP(KEYCODE_0, REDKEY_0); \ - KEYMAP(KEYCODE_MINUS, REDKEY_MINUS); \ - KEYMAP(KEYCODE_EQUAL, REDKEY_EQUALS); \ - KEYMAP(KEYCODE_BACK_SPACE, REDKEY_BACKSPACE); \ - KEYMAP(KEYCODE_TAB, REDKEY_TAB); \ - KEYMAP(KEYCODE_Q, REDKEY_Q); \ - KEYMAP(KEYCODE_W, REDKEY_W); \ - KEYMAP(KEYCODE_E, REDKEY_E); \ - KEYMAP(KEYCODE_R, REDKEY_R); \ - KEYMAP(KEYCODE_T, REDKEY_T); \ - KEYMAP(KEYCODE_Y, REDKEY_Y); \ - KEYMAP(KEYCODE_U, REDKEY_U); \ - KEYMAP(KEYCODE_I, REDKEY_I); \ - KEYMAP(KEYCODE_O, REDKEY_O); \ - KEYMAP(KEYCODE_P, REDKEY_P); \ - KEYMAP(KEYCODE_L_BRACKET, REDKEY_L_BRACKET); \ - KEYMAP(KEYCODE_R_BRACKET, REDKEY_R_BRACKET); \ - KEYMAP(KEYCODE_RETURN, REDKEY_ENTER); \ - KEYMAP(KEYCODE_L_CONTROL, REDKEY_L_CTRL); \ - KEYMAP(KEYCODE_A, REDKEY_A); \ - KEYMAP(KEYCODE_S, REDKEY_S); \ - KEYMAP(KEYCODE_D, REDKEY_D); \ - KEYMAP(KEYCODE_F, REDKEY_F); \ - KEYMAP(KEYCODE_G, REDKEY_G); \ - KEYMAP(KEYCODE_H, REDKEY_H); \ - KEYMAP(KEYCODE_J, REDKEY_J); \ - KEYMAP(KEYCODE_K, REDKEY_K); \ - KEYMAP(KEYCODE_L, REDKEY_L); \ - KEYMAP(KEYCODE_SEMICOLON, REDKEY_SEMICOLON); \ - KEYMAP(KEYCODE_APOSTROPH, REDKEY_QUOTE); \ - KEYMAP(KEYCODE_BACKQUAT, REDKEY_BACK_QUOTE); \ - KEYMAP(KEYCODE_L_SHIFT, REDKEY_L_SHIFT); \ - KEYMAP(KEYCODE_BACKSLASH, REDKEY_BACK_SLASH); \ - KEYMAP(KEYCODE_Z, REDKEY_Z); \ - KEYMAP(KEYCODE_X, REDKEY_X); \ - KEYMAP(KEYCODE_C, REDKEY_C); \ - KEYMAP(KEYCODE_V, REDKEY_V); \ - KEYMAP(KEYCODE_B, REDKEY_B); \ - KEYMAP(KEYCODE_N, REDKEY_N); \ - KEYMAP(KEYCODE_M, REDKEY_M); \ - KEYMAP(KEYCODE_COMMA, REDKEY_COMMA); \ - KEYMAP(KEYCODE_PERIOD, REDKEY_PERIOD); \ - KEYMAP(KEYCODE_SLASH, REDKEY_SLASH); \ - KEYMAP(KEYCODE_R_SHIFT, REDKEY_R_SHIFT); \ - KEYMAP(KEYCODE_PAD_MULTIPLY, REDKEY_PAD_MULTIPLY); \ - KEYMAP(KEYCODE_L_ALT, REDKEY_L_ALT); \ - KEYMAP(KEYCODE_SPACE, REDKEY_SPACE); \ - KEYMAP(KEYCODE_CAPS_LOCK, REDKEY_CAPS_LOCK); \ - KEYMAP(KEYCODE_F1, REDKEY_F1); \ - KEYMAP(KEYCODE_F2, REDKEY_F2); \ - KEYMAP(KEYCODE_F3, REDKEY_F3); \ - KEYMAP(KEYCODE_F4, REDKEY_F4); \ - KEYMAP(KEYCODE_F5, REDKEY_F5); \ - KEYMAP(KEYCODE_F6, REDKEY_F6); \ - KEYMAP(KEYCODE_F7, REDKEY_F7); \ - KEYMAP(KEYCODE_F8, REDKEY_F8); \ - KEYMAP(KEYCODE_F9, REDKEY_F9); \ - KEYMAP(KEYCODE_F10, REDKEY_F10); \ - KEYMAP(KEYCODE_NUM_LOCK, REDKEY_NUM_LOCK); \ - KEYMAP(KEYCODE_SCROLL_LOCK, REDKEY_SCROLL_LOCK); \ - KEYMAP(KEYCODE_PAD_7, REDKEY_PAD_7); \ - KEYMAP(KEYCODE_PAD_8, REDKEY_PAD_8); \ - KEYMAP(KEYCODE_PAD_9, REDKEY_PAD_9); \ - KEYMAP(KEYCODE_PAD_SUBTRACT, REDKEY_PAD_MINUS); \ - KEYMAP(KEYCODE_PAD_4, REDKEY_PAD_4); \ - KEYMAP(KEYCODE_PAD_5, REDKEY_PAD_5); \ - KEYMAP(KEYCODE_PAD_6, REDKEY_PAD_6); \ - KEYMAP(KEYCODE_PAD_ADD, REDKEY_PAD_PLUS); \ - KEYMAP(KEYCODE_PAD_1, REDKEY_PAD_1); \ - KEYMAP(KEYCODE_PAD_2, REDKEY_PAD_2); \ - KEYMAP(KEYCODE_PAD_3, REDKEY_PAD_3); \ - KEYMAP(KEYCODE_PAD_0, REDKEY_PAD_0); \ - KEYMAP(KEYCODE_PAD_DEL, REDKEY_PAD_POINT); \ - KEYMAP(KEYCODE_EUROPEAN, REDKEY_EUROPEAN); \ - KEYMAP(KEYCODE_F11, REDKEY_F11); \ - KEYMAP(KEYCODE_F12, REDKEY_F12); \ - KEYMAP(KEYCODE_JAPANESE_BACKSLASH, REDKEY_JAPANESE_BACKSLASH); \ - KEYMAP(KEYCODE_JAPANESE_HENKAN, REDKEY_JAPANESE_HENKAN); \ - KEYMAP(KEYCODE_JAPANESE_HIRAGANA_KATAKANA, REDKEY_JAPANESE_HIRAGANA_KATAKANA); \ - KEYMAP(KEYCODE_JAPANESE_MUHENKAN, REDKEY_JAPANESE_MUHENKAN); \ - KEYMAP(KEYCODE_PAD_ENTER, REDKEY_PAD_ENTER); \ - KEYMAP(KEYCODE_R_CONTROL, REDKEY_R_CTRL); \ - KEYMAP(KEYCODE_PAD_DEVIDE, REDKEY_PAD_DIVIDE); \ - KEYMAP(KEYCODE_PRINT, REDKEY_CTRL_PRINT_SCREEN); \ - KEYMAP(KEYCODE_R_ALT, REDKEY_R_ALT); \ - KEYMAP(KEYCODE_HOME, REDKEY_HOME); \ - KEYMAP(KEYCODE_UP, REDKEY_UP); \ - KEYMAP(KEYCODE_PAGE_UP, REDKEY_PAGEUP); \ - KEYMAP(KEYCODE_LEFT, REDKEY_LEFT); \ - KEYMAP(KEYCODE_RIGHT, REDKEY_RIGHT); \ - KEYMAP(KEYCODE_END, REDKEY_END); \ - KEYMAP(KEYCODE_DOWN, REDKEY_DOWN); \ - KEYMAP(KEYCODE_PAGE_DOWN, REDKEY_PAGEDOWN); \ - KEYMAP(KEYCODE_INSERT, REDKEY_INSERT); \ - KEYMAP(KEYCODE_DELETE, REDKEY_DELETE); \ - KEYMAP(KEYCODE_PAUSE, REDKEY_PAUSE); \ - \ - KEYMAP(KEYCODE_YEN, REDKEY_JAPANESE_YEN); \ - KEYMAP(KEYCODE_L_COMMAND, REDKEY_LEFT_CMD); \ - KEYMAP(KEYCODE_R_COMMAND, REDKEY_RIGHT_CMD); \ - KEYMAP(KEYCODE_MENU, REDKEY_MENU); \ - KEYMAP(KEYCODE_HANGUL, REDKEY_KOREAN_HANGUL); \ - KEYMAP(KEYCODE_HANGUL_HANJA, REDKEY_KOREAN_HANGUL_HANJA); - -static void init_evdev_map() -{ - #define KEYMAP(key_code, red_key) keycode_map[EVDEV_##key_code] = red_key - INIT_MAP; - KEYMAP(KEYCODE_MUTE, REDKEY_MUTE); - KEYMAP(KEYCODE_VOLUME_DOWN, REDKEY_VOLUME_DOWN); - KEYMAP(KEYCODE_VOLUME_UP, REDKEY_VOLUME_UP); - #undef KEYMAP -} - -static void init_kbd_map() -{ - #define KEYMAP(key_code, red_key) keycode_map[KBD_##key_code] = red_key - INIT_MAP; - #undef KEYMAP -} - -static void init_key_map() -{ - query_keyboard(); - memset(keycode_map, 0, sizeof(keycode_map)); - if (using_evdev) { - LOG_INFO("using evdev mapping"); - init_evdev_map(); - } else { - LOG_INFO("using kbd mapping"); - init_kbd_map(); - } -} - -static inline RedKey to_red_key_code(unsigned int keycode) -{ - if (keycode > 255) { - return REDKEY_INVALID; - } - return keycode_map[keycode]; -} - -#else - -static RedKey key_table_0xff[256]; //miscellany - -static RedKey key_table_0x00[256]; //Latin 1 - -static RedKey key_table_0xfe[256]; //Keyboard (XKB) Extension - -#define INIT_KEY(x, red) key_table_0xff[x & 0xff] = red; - -static void init_key_table_0xff() -{ - for (int i = 0; i < sizeof(key_table_0xff) / sizeof(key_table_0xff[0]); i++) { - key_table_0xff[i] = REDKEY_INVALID; - } - - INIT_KEY(XK_Escape, REDKEY_ESCAPE); - INIT_KEY(XK_BackSpace, REDKEY_BACKSPACE); - INIT_KEY(XK_Tab, REDKEY_TAB); - INIT_KEY(XK_Return, REDKEY_ENTER); - INIT_KEY(XK_Control_L, REDKEY_L_CTRL); - INIT_KEY(XK_Shift_L, REDKEY_L_SHIFT); - INIT_KEY(XK_Shift_R, REDKEY_R_SHIFT); - INIT_KEY(XK_KP_Multiply, REDKEY_PAD_MULTIPLY); - INIT_KEY(XK_Alt_L, REDKEY_L_ALT); - INIT_KEY(XK_Caps_Lock, REDKEY_CAPS_LOCK); - INIT_KEY(XK_F1, REDKEY_F1); - INIT_KEY(XK_F2, REDKEY_F2); - INIT_KEY(XK_F3, REDKEY_F3); - INIT_KEY(XK_F4, REDKEY_F4); - INIT_KEY(XK_F5, REDKEY_F5); - INIT_KEY(XK_F6, REDKEY_F6); - INIT_KEY(XK_F7, REDKEY_F7); - INIT_KEY(XK_F8, REDKEY_F8); - INIT_KEY(XK_F9, REDKEY_F9); - INIT_KEY(XK_F10, REDKEY_F10); - - INIT_KEY(XK_Num_Lock, REDKEY_NUM_LOCK); - INIT_KEY(XK_Scroll_Lock, REDKEY_SCROLL_LOCK); - INIT_KEY(XK_KP_7, REDKEY_PAD_7); - INIT_KEY(XK_KP_Home, REDKEY_PAD_7); - INIT_KEY(XK_KP_8, REDKEY_PAD_8); - INIT_KEY(XK_KP_Up, REDKEY_PAD_8); - INIT_KEY(XK_KP_9, REDKEY_PAD_9); - INIT_KEY(XK_KP_Page_Up, REDKEY_PAD_9); - INIT_KEY(XK_KP_Subtract, REDKEY_PAD_MINUS); - INIT_KEY(XK_KP_4, REDKEY_PAD_4); - INIT_KEY(XK_KP_Left, REDKEY_PAD_4); - INIT_KEY(XK_KP_5, REDKEY_PAD_5); - INIT_KEY(XK_KP_Begin, REDKEY_PAD_5); - INIT_KEY(XK_KP_6, REDKEY_PAD_6); - INIT_KEY(XK_KP_Right, REDKEY_PAD_6); - INIT_KEY(XK_KP_Add, REDKEY_PAD_PLUS); - INIT_KEY(XK_KP_1, REDKEY_PAD_1); - INIT_KEY(XK_KP_End, REDKEY_PAD_1); - INIT_KEY(XK_KP_2, REDKEY_PAD_2); - INIT_KEY(XK_KP_Down, REDKEY_PAD_2); - INIT_KEY(XK_KP_3, REDKEY_PAD_3); - INIT_KEY(XK_KP_Page_Down, REDKEY_PAD_3); - INIT_KEY(XK_KP_0, REDKEY_PAD_0); - INIT_KEY(XK_KP_Insert, REDKEY_PAD_0); - INIT_KEY(XK_KP_Decimal, REDKEY_PAD_POINT); - INIT_KEY(XK_KP_Delete, REDKEY_PAD_POINT); - INIT_KEY(XK_F11, REDKEY_F11); - INIT_KEY(XK_F12, REDKEY_F12); - - INIT_KEY(XK_KP_Enter, REDKEY_PAD_ENTER); - INIT_KEY(XK_Control_R, REDKEY_R_CTRL); - INIT_KEY(XK_KP_Divide, REDKEY_PAD_DIVIDE); - INIT_KEY(XK_Print, REDKEY_CTRL_PRINT_SCREEN); - - INIT_KEY(XK_Home, REDKEY_HOME); - INIT_KEY(XK_Up, REDKEY_UP); - INIT_KEY(XK_Page_Up, REDKEY_PAGEUP); - INIT_KEY(XK_Left, REDKEY_LEFT); - INIT_KEY(XK_Right, REDKEY_RIGHT); - INIT_KEY(XK_End, REDKEY_END); - - INIT_KEY(XK_Down, REDKEY_DOWN); - INIT_KEY(XK_Page_Down, REDKEY_PAGEDOWN); - INIT_KEY(XK_Insert, REDKEY_INSERT); - INIT_KEY(XK_Delete, REDKEY_DELETE); - INIT_KEY(XK_Super_L, REDKEY_LEFT_CMD); - INIT_KEY(XK_Super_R, REDKEY_RIGHT_CMD); - INIT_KEY(XK_Menu, REDKEY_MENU); - INIT_KEY(XK_Pause, REDKEY_CTRL_BREAK); -} - -#undef INIT_KEY -#define INIT_KEY(x, red) key_table_0x00[x & 0xff] = red; - -static void init_key_table_0x00() -{ - for (int i = 0; i < sizeof(key_table_0x00) / sizeof(key_table_0x00[0]); i++) { - key_table_0x00[i] = REDKEY_INVALID; - } - - INIT_KEY(XK_1, REDKEY_1); - INIT_KEY(XK_2, REDKEY_2); - INIT_KEY(XK_3, REDKEY_3); - INIT_KEY(XK_4, REDKEY_4); - INIT_KEY(XK_5, REDKEY_5); - INIT_KEY(XK_6, REDKEY_6); - INIT_KEY(XK_7, REDKEY_7); - INIT_KEY(XK_8, REDKEY_8); - INIT_KEY(XK_9, REDKEY_9); - INIT_KEY(XK_0, REDKEY_0); - INIT_KEY(XK_minus, REDKEY_MINUS); - INIT_KEY(XK_equal, REDKEY_EQUALS); - INIT_KEY(XK_q, REDKEY_Q); - INIT_KEY(XK_w, REDKEY_W); - INIT_KEY(XK_e, REDKEY_E); - INIT_KEY(XK_r, REDKEY_R); - INIT_KEY(XK_t, REDKEY_T); - INIT_KEY(XK_y, REDKEY_Y); - INIT_KEY(XK_u, REDKEY_U); - INIT_KEY(XK_i, REDKEY_I); - INIT_KEY(XK_o, REDKEY_O); - INIT_KEY(XK_p, REDKEY_P); - INIT_KEY(XK_bracketleft, REDKEY_L_BRACKET); - INIT_KEY(XK_bracketright, REDKEY_R_BRACKET); - INIT_KEY(XK_a, REDKEY_A); - INIT_KEY(XK_s, REDKEY_S); - INIT_KEY(XK_e, REDKEY_E); - INIT_KEY(XK_d, REDKEY_D); - INIT_KEY(XK_f, REDKEY_F); - INIT_KEY(XK_g, REDKEY_G); - INIT_KEY(XK_h, REDKEY_H); - INIT_KEY(XK_j, REDKEY_J); - INIT_KEY(XK_k, REDKEY_K); - INIT_KEY(XK_l, REDKEY_L); - INIT_KEY(XK_semicolon, REDKEY_SEMICOLON); - INIT_KEY(XK_quoteright, REDKEY_QUOTE); - INIT_KEY(XK_quoteleft, REDKEY_BACK_QUOTE); - INIT_KEY(XK_backslash, REDKEY_BACK_SLASH); - INIT_KEY(XK_z, REDKEY_Z); - INIT_KEY(XK_x, REDKEY_X); - INIT_KEY(XK_c, REDKEY_C); - INIT_KEY(XK_v, REDKEY_V); - INIT_KEY(XK_b, REDKEY_B); - INIT_KEY(XK_n, REDKEY_N); - INIT_KEY(XK_m, REDKEY_M); - INIT_KEY(XK_comma, REDKEY_COMMA); - INIT_KEY(XK_period, REDKEY_PERIOD); - INIT_KEY(XK_slash, REDKEY_SLASH); - INIT_KEY(XK_space, REDKEY_SPACE); -} - -#undef INIT_KEY -#define INIT_KEY(x, red) key_table_0xfe[x & 0xff] = red; - -static void init_key_table_0xfe() -{ - for (int i = 0; i < sizeof(key_table_0xfe) / sizeof(key_table_0xfe[0]); i++) { - key_table_0xfe[i] = REDKEY_INVALID; - } - - INIT_KEY(XK_ISO_Level3_Shift, REDKEY_R_ALT); -} - -static inline RedKey to_red_key_code(unsigned int keycode) -{ - XLockDisplay(x_display); - KeySym sym = XKeycodeToKeysym(x_display, keycode, 0); - XUnlockDisplay(x_display); - RedKey red_key; - - if (sym == NoSymbol) { - DBG(0, "no symbol for %d", keycode); - } - - switch (sym >> 8) { - case 0x00: - red_key = key_table_0x00[sym & 0xff]; - break; - case 0xff: - red_key = key_table_0xff[sym & 0xff]; - break; - case 0xfe: - red_key = key_table_0xfe[sym & 0xff]; - break; - default: - DBG(0, "unsupported key set %lu", (sym >> 8)); - return REDKEY_INVALID; - } - - if (red_key == REDKEY_INVALID) { - DBG(0, "no valid key mapping for keycode %u", keycode); - } - return red_key; -} - -#endif - -static inline int to_red_buttons_state(unsigned int state) -{ - return ((state & Button1Mask) ? SPICE_MOUSE_BUTTON_MASK_LEFT : 0) | - ((state & Button2Mask) ? SPICE_MOUSE_BUTTON_MASK_MIDDLE : 0) | - ((state & Button3Mask) ? SPICE_MOUSE_BUTTON_MASK_RIGHT : 0); -} - -static inline SpiceMouseButton to_red_button(unsigned int botton, unsigned int& state, bool press) -{ - unsigned int mask = 0; - SpiceMouseButton ret; - - switch (botton) { - case Button1: - mask = SPICE_MOUSE_BUTTON_MASK_LEFT; - ret = SPICE_MOUSE_BUTTON_LEFT; - break; - case Button2: - mask = SPICE_MOUSE_BUTTON_MASK_MIDDLE; - ret = SPICE_MOUSE_BUTTON_MIDDLE; - break; - case Button3: - mask = SPICE_MOUSE_BUTTON_MASK_RIGHT; - ret = SPICE_MOUSE_BUTTON_RIGHT; - break; - case Button4: - ret = SPICE_MOUSE_BUTTON_UP; - break; - case Button5: - ret = SPICE_MOUSE_BUTTON_DOWN; - break; - default: - ret = SPICE_MOUSE_BUTTON_INVALID; - } - if (press) { - state |= mask; - } else { - state &= ~mask; - } - return ret; -} - -void RedWindow_p::handle_key_press_event(RedWindow& window, XKeyEvent* event) -{ - static int buf_size = 0; - static wchar_t* utf32_buf = NULL; - - KeySym key_sym; - Status status; - int len; - - window.get_listener().on_key_press(to_red_key_code(event->keycode)); - - if (x_input_context != NULL) { - for (;;) { - XLockDisplay(x_display); - len = XwcLookupString(x_input_context, event, utf32_buf, buf_size, &key_sym, &status); - XUnlockDisplay(x_display); - if (status != XBufferOverflow) { - break; - } - - if (utf32_buf) { - delete [] utf32_buf; - } - utf32_buf = new wchar_t[len]; - buf_size = len; - } - - switch (status) { - case XLookupChars: - case XLookupBoth: { - uint32_t* now = (uint32_t*)utf32_buf; - uint32_t* end = now + len; - - for (; now < end; now++) { - window.get_listener().on_char(*now); - } - break; - } - - case XLookupNone: - case XLookupKeySym: - break; - default: - THROW("unexpected status %d", status); - } - } else { /* no XIM */ - unsigned char buffer[16]; - int i; - - XLockDisplay(x_display); - len = XLookupString(event, (char *)buffer, sizeof(buffer), NULL, NULL); - XUnlockDisplay(x_display); - for (i = 0; i < len; i++) { - window.get_listener().on_char((uint32_t)buffer[i]); - } - } -} - -void RedWindow_p::win_proc(XEvent& event) -{ - XPointer window_pointer; - RedWindow* red_window; - int res; - - XLockDisplay(x_display); - res = XFindContext(x_display, event.xany.window, user_data_context, &window_pointer); - XUnlockDisplay(x_display); - if (res) { - THROW("no user data"); - } - red_window = (RedWindow*)window_pointer; - switch (event.type) { - case MotionNotify: { - SpicePoint size = red_window->get_size(); - if (event.xmotion.x >= 0 && event.xmotion.y >= 0 && - event.xmotion.x < size.x && event.xmotion.y < size.y) { - SpicePoint origin = red_window->get_origin(); - red_window->get_listener().on_pointer_motion(event.xmotion.x - origin.x, - event.xmotion.y - origin.y, - to_red_buttons_state(event.xmotion.state)); - } - break; - } - case KeyPress: - red_window->handle_key_press_event(*red_window, &event.xkey); - red_window->_last_event_time = event.xkey.time; - XChangeProperty(x_display, red_window->_win, wm_user_time, - XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)&event.xkey.time, 1); - break; - case KeyRelease: { - RedKey key = to_red_key_code(event.xkey.keycode); - XEvent next_event; - XLockDisplay(x_display); - Bool check = XCheckWindowEvent(x_display, red_window->_win, ~long(0), &next_event); - XUnlockDisplay(x_display); - if (check) { - XPutBackEvent(x_display, &next_event); - if ((next_event.type == KeyPress) && - (event.xkey.keycode == next_event.xkey.keycode) && - (event.xkey.time == next_event.xkey.time)) { - break; - } - } - if (key != REDKEY_KOREAN_HANGUL && key != REDKEY_KOREAN_HANGUL_HANJA) { - red_window->get_listener().on_key_release(key); - } - break; - } - case ButtonPress: { - unsigned int state = to_red_buttons_state(event.xbutton.state); - SpiceMouseButton button = to_red_button(event.xbutton.button, state, true); - if (button == SPICE_MOUSE_BUTTON_INVALID) { - DBG(0, "ButtonPress: invalid button %u", event.xbutton.button); - break; - } - red_window->get_listener().on_mouse_button_press(button, state); - red_window->_last_event_time = event.xkey.time; - XChangeProperty(x_display, red_window->_win, wm_user_time, - XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)&event.xbutton.time, 1); - break; - } - case ButtonRelease: { - unsigned int state = to_red_buttons_state(event.xbutton.state); - SpiceMouseButton button = to_red_button(event.xbutton.button, state, false); - if (button == SPICE_MOUSE_BUTTON_INVALID) { - DBG(0, "ButtonRelease: invalid button %u", event.xbutton.button); - break; - } - red_window->get_listener().on_mouse_button_release(button, state); - break; - } - case Expose: { - SpicePoint origin; - SpiceRect area; - - origin = red_window->get_origin(); - area.left = event.xexpose.x - origin.x; - area.right = area.left + event.xexpose.width; - area.top = event.xexpose.y - origin.y; - area.bottom = area.top + event.xexpose.height; - red_window->get_listener().on_exposed_rect(area); - break; - } - case FocusIn: - /* Ignore focus events caused by grabbed (hotkeys) */ - if (event.xfocus.mode == NotifyWhileGrabbed) { - break; - } - - if (event.xany.serial < focus_serial) { - DBG(0, "Ignored FocusIn win=%p (serial=%d, Last foucs serial=%d)", - red_window, event.xany.serial, focus_serial); - break; - } - - if (!red_window->_ignore_foucs) { - RedWindow* prev_focus_window = focus_window; - focus_window = red_window; - focus_serial = event.xany.serial; - if (prev_focus_window && (red_window != prev_focus_window)) { - prev_focus_window->on_focus_out(); - } - red_window->on_focus_in(); - } else { - red_window->_shadow_foucs_state = true; - memcpy(&red_window->_shadow_focus_event, &event, sizeof(XEvent)); - } - break; - case FocusOut: - /* Ignore focus events caused by grabbed (hotkeys) */ - if (event.xfocus.mode == NotifyWhileGrabbed) { - break; - } - - if (event.xany.serial <= focus_serial) { - DBG(0, "Ignored FocusOut win=%p (serial=%d, Last foucs serial=%d)", - red_window, event.xany.serial, focus_serial); - break; - } - - if (!red_window->_ignore_foucs) { - focus_serial = event.xany.serial; - if (red_window != focus_window) { - break; - } - focus_window = NULL; - red_window->on_focus_out(); - } else { - red_window->_shadow_foucs_state = false; - memcpy(&red_window->_shadow_focus_event, &event, sizeof(XEvent)); - } - break; - case ConfigureNotify: - break; - case ClientMessage: - if (event.xclient.message_type == wm_protocol_atom) { - ASSERT(event.xclient.format == 32); - if ((Atom)event.xclient.data.l[0] == wm_delete_window_atom) { - DBG(0, "wm_delete_window"); - Platform::send_quit_request(); - } - } - break; - case DestroyNotify: - break; - case MapNotify: - red_window->set_visibale(true); - break; - case UnmapNotify: - red_window->set_visibale(false); - break; - case EnterNotify: - if (!red_window->_ignore_pointer) { - SpicePoint origin = red_window->get_origin(); - red_window->on_pointer_enter(event.xcrossing.x - origin.x, event.xcrossing.y - origin.y, - to_red_buttons_state(event.xcrossing.state)); - } else { - red_window->_shadow_pointer_state = true; - memcpy(&red_window->_shadow_pointer_event, &event, sizeof(XEvent)); - } - break; - case LeaveNotify: - if (!red_window->_ignore_pointer) { - red_window->on_pointer_leave(); - } else { - red_window->_shadow_pointer_state = false; - memcpy(&red_window->_shadow_pointer_event, &event, sizeof(XEvent)); - } - break; - } -} - -void RedWindow_p::sync(bool shadowed) -{ - XEvent event; - - if (shadowed) { - _ignore_foucs = true; - _ignore_pointer = true; - _shadow_foucs_state = _focused; - _shadow_pointer_state = _pointer_in_window; - _shadow_focus_event.xany.serial = 0; - } - - XLockDisplay(x_display); - XSync(x_display, False); - while (XCheckWindowEvent(x_display, _win, ~long(0), &event)) { - XUnlockDisplay(x_display); - win_proc(event); - XLockDisplay(x_display); - } - XUnlockDisplay(x_display); - - if (!shadowed) { - return; - } - _ignore_foucs = false; - _ignore_pointer = false; - if (_shadow_foucs_state != _focused) { - DBG(0, "put back shadowed focus event"); - XPutBackEvent(x_display, &_shadow_focus_event); - } else if (_shadow_focus_event.xany.serial > 0) { - focus_serial = _shadow_focus_event.xany.serial; - } - if (_shadow_pointer_state != _pointer_in_window) { - DBG(0, "put back shadowed pointer event"); - XPutBackEvent(x_display, &_shadow_pointer_event); - } -} - -void RedWindow_p::wait_for_reparent() -{ - XEvent event; - for (int i = 0; i < 50; i++) { - XLockDisplay(x_display); - bool check = XCheckTypedWindowEvent(x_display, _win, ReparentNotify, &event); - XUnlockDisplay(x_display); - if (check) { - return; - } - usleep(20 * 1000); - // HDG: why?? this makes no sense - XLockDisplay(x_display); - XSync(x_display, False); - XUnlockDisplay(x_display); - } - DBG(0, "failed"); -} - -void RedWindow_p::wait_for_map() -{ - bool wait_parent = _expect_parent; - while (!_visibale) { - XEvent event; - XLockDisplay(x_display); - XWindowEvent(x_display, _win, ~0, &event); - XUnlockDisplay(x_display); - switch (event.type) { - case ReparentNotify: - wait_parent = false; - break; - case MapNotify: - _visibale = true; - break; - default: - //todo: post state messages to app message queue instead of - // calling win_proc - win_proc(event); - } - } - - if (wait_parent) { - wait_for_reparent(); - } -} - -void RedWindow_p::wait_for_unmap() -{ - bool wait_parent = _expect_parent; - while (_visibale) { - XEvent event; - XLockDisplay(x_display); - XWindowEvent(x_display, _win, ~0, &event); - XUnlockDisplay(x_display); - switch (event.type) { - case ReparentNotify: - wait_parent = false; - break; - case UnmapNotify: - _visibale = false; - break; - //default: - // win_proc(event); - } - } - - if (wait_parent) { - wait_for_reparent(); - } -} - -void RedWindow_p::set_minmax(PixelsSource_p& pix_source) -{ - //todo: auto res - XSizeHints* size_hints = XAllocSizeHints(); - ASSERT(size_hints); - size_hints->flags = PMinSize | PMaxSize; - if (_red_window->_type == RedWindow::TYPE_FULLSCREEN) { - /* Some window managers won't allow full screen mode with a fixed - width / height */ - size_hints->min_width = 1; - size_hints->max_width = 65535; - size_hints->min_height = 1; - size_hints->max_height = 65535; - } else { - size_hints->min_width = size_hints->max_width = _width; - size_hints->min_height = size_hints->max_height = _height; - } - XSetWMNormalHints(x_display, _win, size_hints); - XFree(size_hints); - pix_source.x_drawable.height = _height; - pix_source.x_drawable.width = _width; -} - -Cursor RedWindow_p::create_invisible_cursor(Window window) -{ - XColor color; - char data[1] = {0}; - Window root_window = RootWindow(x_display, DefaultScreen(x_display)); - XLockDisplay(x_display); - Pixmap blank = XCreateBitmapFromData(x_display, root_window, data, 1, 1); - Cursor cursor = XCreatePixmapCursor(x_display, blank, blank, &color, &color, 0, 0); - XUnlockDisplay(x_display); - XFreePixmap(x_display, blank); - return cursor; -} - -RedWindow_p::RedWindow_p() - : _win (None) - , _show_pos_valid (false) - , _icon (NULL) - , _focused (false) - , _ignore_foucs (false) - , _pointer_in_window (false) - , _ignore_pointer (false) - ,_width (200) - ,_height (200) - ,_last_event_time (0) -{ -} - -void RedWindow_p::destroy(RedWindow& red_window, PixelsSource_p& pix_source) -{ - XEvent event; - - if (_win == None) { - return; - } - - if (focus_window == &red_window) { - focus_window = NULL; - red_window.on_focus_out(); - } - - XPlatform::cleare_win_proc(_win); - XSelectInput(x_display, _win, 0); - - XLockDisplay(x_display); - XSync(x_display, False); - while (XCheckWindowEvent(x_display, _win, ~long(0), &event)); - XUnlockDisplay(x_display); - - Window window = _win; - _win = None; - XFreeCursor(x_display, _invisible_cursor); - _invisible_cursor = None; - XDeleteContext(x_display, window, user_data_context); - XDestroyWindow(x_display, window); - XFreeColormap(x_display, _colormap); - XFreeGC(x_display, pix_source.x_drawable.gc); - pix_source.x_drawable.gc = NULL; - pix_source.x_drawable.drawable = None; - if (_icon) { - _icon->unref(); - } -} - -void RedWindow_p::create(RedWindow& red_window, PixelsSource_p& pix_source, - int x, int y, int in_screen) -{ - Window window = None; - Cursor cursor = None; - GC gc = NULL; - - Window root_window = RootWindow(x_display, in_screen); - XSetWindowAttributes win_attributes; - - unsigned long mask = CWBorderPixel | CWEventMask; - win_attributes.border_pixel = 1; - win_attributes.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | - KeyPressMask | KeyReleaseMask | ButtonPressMask | - ButtonReleaseMask | PointerMotionMask | FocusChangeMask | - EnterWindowMask | LeaveWindowMask; - - XLockDisplay(x_display); - _colormap = XCreateColormap(x_display, root_window, XPlatform::get_vinfo()[in_screen]->visual, - AllocNone); - win_attributes.colormap = _colormap; - mask |= CWColormap; - window = XCreateWindow(x_display, root_window, x, y, - _width, _height, 0, XPlatform::get_vinfo()[in_screen]->depth, - InputOutput, XPlatform::get_vinfo()[in_screen]->visual, mask, - &win_attributes); - XUnlockDisplay(x_display); - - if (!window) { - THROW("create X window failed"); - } - - try { - int res; - XClassHint *class_hint; - - XLockDisplay(x_display); - res = XSaveContext(x_display, window, user_data_context, (XPointer)&red_window); - XUnlockDisplay(x_display); - if (res) { - THROW("set win usr data failed"); - } - - XSetWMProtocols(x_display, window, &wm_delete_window_atom, 1); - class_hint = XAllocClassHint(); - if (!class_hint) { - THROW("allocating class hint failed"); - } - class_hint->res_name = (char *)"spicec"; - class_hint->res_class = (char *)"spicec"; - XSetClassHint(x_display, window, class_hint); - XFree(class_hint); - - XGCValues gc_vals; - XLockDisplay(x_display); - gc = XCreateGC(x_display, window, 0, &gc_vals); - XUnlockDisplay(x_display); - if (!gc) { - THROW("create gc failed"); - } - - cursor = create_invisible_cursor(window); - if (!cursor) { - THROW("create invisible cursor failed"); - } - - XPlatform::set_win_proc(window, win_proc); - } catch (...) { - if (gc) { - XFreeGC(x_display, gc); - } - - XDeleteContext(x_display, window, user_data_context); - XDestroyWindow(x_display, window); - if (cursor != None) { - XFreeCursor(x_display, cursor); - } - - throw; - } - _screen = in_screen; - _win = window; - _invisible_cursor = cursor; - _show_pos.x = x; - _show_pos.y = y; - _visibale = false; - _expect_parent = false; - _red_window = &red_window; - pix_source.type = PIXELS_SOURCE_TYPE_X_DRAWABLE; - pix_source.x_drawable.drawable = window; - pix_source.x_drawable.screen = _screen; - pix_source.x_drawable.gc = gc; - set_minmax(pix_source); - sync(); -} - -void RedWindow_p::migrate(RedWindow& red_window, PixelsSource_p& pix_source, int to_screen) -{ - if (to_screen == _screen) { - return; - } - XTextProperty text_pro; - XLockDisplay(x_display); - bool valid_title = XGetWMName(x_display, _win, &text_pro) && text_pro.value; - XUnlockDisplay(x_display); - destroy(red_window, pix_source); - create(red_window, pix_source, _show_pos.x, _show_pos.y, to_screen); - if (valid_title) { - XSetWMName(x_display, _win, &text_pro); - XFree(text_pro.value); //??? - } - if (_icon) { - AutoRef<Icon> red(_icon->ref()); - red_window.set_icon(_icon); - } -} - -void RedWindow_p::move_to_current_desktop() -{ - Window root = RootWindow(x_display, _screen); - Atom actual_type_return; - int actual_format_return; - unsigned long bytes_after_return; - unsigned long nitems_return; - unsigned char *prop_return; - long desktop = ~long(0); - int status; - - XLockDisplay(x_display); - status = XGetWindowProperty(x_display, root, wm_current_desktop, 0, 1, False, AnyPropertyType, - &actual_type_return, &actual_format_return, &nitems_return, - &bytes_after_return, &prop_return); - if ((status == Success) && (actual_type_return != None) && (actual_format_return == 32)) { - desktop = *(uint32_t *)prop_return; - } else { - DBG(0, "get current desktop failed"); - } - if (status == Success) - XFree(prop_return); - XUnlockDisplay(x_display); - - XEvent xevent; - xevent.type = ClientMessage; - xevent.xclient.window = _win; - xevent.xclient.message_type = wm_desktop; - xevent.xclient.format = 32; - xevent.xclient.data.l[0] = desktop; - xevent.xclient.data.l[1] = 0; - xevent.xclient.data.l[2] = 0; - xevent.xclient.data.l[3] = 0; - xevent.xclient.data.l[4] = 0; - if (!XSendEvent(x_display, root, False, SubstructureNotifyMask | SubstructureRedirectMask, - &xevent)) { - DBG(0, "failed"); - } -} - -RedWindow::RedWindow(RedWindow::Listener& listener, int screen) - : _listener (listener) - , _type (TYPE_NORMAL) - , _local_cursor (NULL) - , _cursor_visible (true) - , _trace_key_interception (false) - , _key_interception_on (false) - , _menu (NULL) -{ - ASSERT(x_display); - create(*this, *(PixelsSource_p*)get_opaque(), 0, 0, - (screen == DEFAULT_SCREEN) ? DefaultScreen(x_display) : screen); -} - -RedWindow::~RedWindow() -{ - destroy(*this, *(PixelsSource_p*)get_opaque()); - if (_local_cursor) { - _local_cursor->unref(); - } -} - -void RedWindow::set_title(std::string& title) -{ - XTextProperty text_prop; - char *name = const_cast<char *>(title.c_str()); - int r; - if (_win) { - XLockDisplay(x_display); - r = Xutf8TextListToTextProperty(x_display, &name, 1, XUTF8StringStyle, &text_prop); - XUnlockDisplay(x_display); - if (r == Success) { - XSetWMName(x_display, _win, &text_prop); - XFree(text_prop.value); - } else { - LOG_WARN("XwcTextListToTextProperty Error %d", r); - } - } -} - -void RedWindow::set_icon(Icon* icon) -{ - if (_icon) { - _icon->unref(); - _icon = NULL; - } - if (!icon) { - return; - } - _icon = icon->ref(); - - XWMHints* wm_hints; - if (_win == None || !(wm_hints = XAllocWMHints())) { - return; - } - - try { - XIcon* xicon = (XIcon*)icon; - xicon->get_pixmaps(_screen, wm_hints->icon_pixmap, wm_hints->icon_mask); - wm_hints->flags = IconPixmapHint | IconMaskHint; - XSetWMHints(x_display, _win, wm_hints); - } catch (...) { - } - XFree(wm_hints); -} - -static XErrorHandler old_error_handler = NULL; -static unsigned char x_error = Success; - -static int x_error_handler(Display* display, XErrorEvent* error_event) -{ - x_error = error_event->error_code; - if (error_event->error_code == BadWindow) { - return 0; - } - ASSERT(old_error_handler); - XSetErrorHandler(old_error_handler); - old_error_handler(display, error_event); - old_error_handler = NULL; - return 0; -} - -class AutoXErrorHandler { -public: - AutoXErrorHandler() - { - ASSERT(old_error_handler == NULL); - XLockDisplay(x_display); - XSync(x_display, False); - x_error = Success; - old_error_handler = XSetErrorHandler(x_error_handler); - XUnlockDisplay(x_display); - } - - ~AutoXErrorHandler() - { - if (old_error_handler) { - XLockDisplay(x_display); - XSetErrorHandler(old_error_handler); - XUnlockDisplay(x_display); - old_error_handler = NULL; - } - } -}; - -static Window get_window_for_reposition(Window window) -{ - for (;;) { - Window root; - Window parent; - Window* childrens; - unsigned int num_childrens; - int res; - - XLockDisplay(x_display); - res = XQueryTree(x_display, window, &root, &parent, &childrens, &num_childrens); - XUnlockDisplay(x_display); - if (!res) { - return None; - } - - if (childrens) { - XFree(childrens); - } - - if (parent == root) { - break; - } - window = parent; - } - return window; -} - -void RedWindow::raise() -{ - AutoXErrorHandler auto_error_handler; - int raise_retries = RAISE_RETRIES; - for (;; --raise_retries) { - Window window = get_window_for_reposition(_win); - if (window != None) { - x_error = Success; - XRaiseWindow(x_display, window); - if (x_error == Success) { - break; - } - if (x_error != BadWindow) { - THROW("XRaiseWindow failed"); - } - } - - if (!raise_retries) { - THROW("failed"); - } - usleep(X_RETRY_DELAY_MICRO); - } - if (raise_retries < RAISE_RETRIES) { - DBG(0, "retries %d", (RAISE_RETRIES - raise_retries)); - } - sync(); -} - -void RedWindow::position_after(RedWindow *after) -{ - if (!after || after->_screen != _screen) { - raise(); - return; - } - - AutoXErrorHandler auto_error_handler; - int position_retries = Z_POSITION_RETRIES; - for (;; --position_retries) { - Window sibling = get_window_for_reposition(after->get_window()); - Window self = get_window_for_reposition(_win); - if (sibling != None && self != None) { - XWindowChanges changes; - changes.sibling = sibling; - changes.stack_mode = Below; - x_error = Success; - XConfigureWindow(x_display, self, CWSibling | CWStackMode, &changes); - if (x_error == Success) { - break; - } - if (x_error != BadWindow) { - THROW("XConfigureWindow failed"); - } - } - - if (!position_retries) { - THROW("failed"); - } - usleep(X_RETRY_DELAY_MICRO); - } - if (position_retries < Z_POSITION_RETRIES) { - DBG(0, "retries %d", (Z_POSITION_RETRIES - position_retries)); - } -} - -void RedWindow::show(int screen_id) -{ - if (_visibale) { - return; - } - - bool wait_parent; - - if (screen_id != _screen) { - _listener.pre_migrate(); - migrate(*this, *(PixelsSource_p*)get_opaque(), screen_id); - _listener.post_migrate(); - } - - /* We must update min/max for fullscreen / normal switching */ - set_minmax(*(PixelsSource_p*)get_opaque()); - - if (_type == TYPE_FULLSCREEN) { - Atom state[2]; - state[0] = wm_state_above; - state[1] = wm_state_fullscreen; - XChangeProperty(x_display, _win, wm_state, XA_ATOM, 32, PropModeReplace, - (unsigned char*)state, 2); - wait_parent = false; - } else { - XDeleteProperty(x_display, _win, wm_state); - wait_parent = true; - } - if (_last_event_time != 0) - XChangeProperty(x_display, _win, wm_user_time, XA_CARDINAL, 32, - PropModeReplace, (unsigned char *)&_last_event_time, 1); - XMapWindow(x_display, _win); - move_to_current_desktop(); - _expect_parent = wait_parent; - wait_for_map(); - if (_show_pos_valid) { - move(_show_pos.x, _show_pos.y); - } -} - -static bool get_prop_32(Window win, Atom prop, uint32_t &val) -{ - Atom actual_type_return; - int actual_format_return; - unsigned long bytes_after_return; - unsigned long nitems_return; - unsigned char *prop_return; - bool retval = false; - - XLockDisplay(x_display); - if (XGetWindowProperty(x_display, win, prop, 0, 1, False, AnyPropertyType, - &actual_type_return, &actual_format_return, - &nitems_return, &bytes_after_return, &prop_return) == Success && - nitems_return == 1 && - actual_type_return != None && - actual_format_return == 32) { - val = *(uint32_t *)prop_return; - retval = true; - } - XUnlockDisplay(x_display); - - return retval; -} - -void RedWindow::external_show() -{ - Atom atom; - - DBG(0, ""); - show(_screen); - raise(); - activate(); - - XLockDisplay(x_display); - atom = XInternAtom(x_display, "_NET_ACTIVE_WINDOW", true); - XUnlockDisplay(x_display); - 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 = _win; - xev.xclient.message_type = atom; - - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - - uint32_t user_time; - if (get_prop_32(_win, wm_user_time, user_time)) { - xev.xclient.data.l[1] = user_time; - } else { - xev.xclient.data.l[1] = 0; - } - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - - root = RootWindow(x_display, _screen), - eventmask = SubstructureRedirectMask | SubstructureNotifyMask; - - XSendEvent(x_display, root, False, eventmask, &xev); - } -} - -void RedWindow::hide() -{ - if (!_visibale) { - return; - } - on_pointer_leave(); - on_focus_out(); - XUnmapWindow(x_display, _win); - _show_pos = get_position(); - _show_pos_valid = true; - wait_for_unmap(); - ASSERT(!_focused); - ASSERT(!_pointer_in_window); - _expect_parent = false; -} - -static void send_expose(Window window, int width, int height) -{ - XExposeEvent event; - event.type = Expose; - event.display = x_display; - event.window = window; - event.x = 0; - event.y = 0; - event.width = width; - event.height = height; - event.count = 0; - XSendEvent(x_display, window, False, ExposureMask, (XEvent *)&event); -} - -void RedWindow::move_and_resize(int x, int y, int width, int height) -{ - _width = width; - _height = height; - set_minmax(*(PixelsSource_p*)get_opaque()); - XMoveResizeWindow(x_display, _win, x, y, width, height); - _show_pos.x = x; - _show_pos.y = y; - _show_pos_valid = true; - if (_visibale) { - send_expose(_win, width, height); - } -} - -void RedWindow::move(int x, int y) -{ - XMoveWindow(x_display, _win, x, y); - _show_pos.x = x; - _show_pos.y = y; - _show_pos_valid = true; -} - -void RedWindow::resize(int width, int height) -{ - _width = width; - _height = height; - set_minmax(*(PixelsSource_p*)get_opaque()); - XResizeWindow(x_display, _win, width, height); - if (_visibale) { - send_expose(_win, width, height); - } -} - -void RedWindow::activate() -{ - //todo: use _NET_ACTIVE_WINDOW - XSetInputFocus(x_display, _win, RevertToParent, CurrentTime); - /* kwin won't raise on focus */ - XRaiseWindow(x_display, _win); -} - -void RedWindow::minimize() -{ - XIconifyWindow(x_display, _win, _screen); - sync(); -} - -static bool __get_position(Window window, SpicePoint& pos) -{ - pos.x = pos.y = 0; - for (;;) { - XWindowAttributes attrib; - Window root; - Window parent; - Window* childrens; - unsigned int num_childrens; - int res; - - XLockDisplay(x_display); - res = XGetWindowAttributes(x_display, window, &attrib); - XUnlockDisplay(x_display); - if (!res) { - return false; - } - pos.x += attrib.x; - pos.y += attrib.y; - - XLockDisplay(x_display); - res = XQueryTree(x_display, window, &root, &parent, &childrens, &num_childrens); - XUnlockDisplay(x_display); - if (!res) { - return false; - } - - if (childrens) { - XFree(childrens); - } - - if (parent == None) { - break; - } - window = parent; - } - return true; -} - -SpicePoint RedWindow::get_position() -{ - SpicePoint pos; - - AutoXErrorHandler auto_error_handler; - int get_position_retries = GET_POSITION_RETRIES; - for (;; --get_position_retries) { - if (__get_position(_win, pos)) { - break; - } - if (!get_position_retries) { - THROW("failed"); - } - usleep(X_RETRY_DELAY_MICRO); - } - - if (get_position_retries < GET_POSITION_RETRIES) { - DBG(0, "retries %d", (GET_POSITION_RETRIES - get_position_retries)); - } - return pos; -} - -void RedWindow::do_start_key_interception() -{ - // Working with KDE: XGrabKeyboard generate focusout and focusin events - // while we have the focus. This behavior trigger infinite recursive. for - // that reason we temporary disable focus event handling. Same happens - // LeaveNotify and EnterNotify. - - if (getenv("SPICE_NOGRAB")) - return; - - ASSERT(_focused); - XLockDisplay(x_display); - XGrabKeyboard(x_display, _win, True, GrabModeAsync, GrabModeAsync, CurrentTime); - - XUnlockDisplay(x_display); - sync(true); - _listener.on_start_key_interception(); - _key_interception_on = true; -} - -void RedWindow::do_stop_key_interception() -{ - XLockDisplay(x_display); - XUngrabKeyboard(x_display, CurrentTime); - XUnlockDisplay(x_display); - sync(true); - _key_interception_on = false; - _listener.on_stop_key_interception(); -} - -void RedWindow::start_key_interception() -{ - if (_trace_key_interception) { - return; - } - _trace_key_interception = true; - if (_pointer_in_window && _focused) { - do_start_key_interception(); - } -} - -void RedWindow::stop_key_interception() -{ - if (!_trace_key_interception) { - return; - } - _trace_key_interception = false; - if (_key_interception_on) { - do_stop_key_interception(); - } -} - -void RedWindow::set_cursor(LocalCursor* local_cursor) -{ - ASSERT(local_cursor); - if (_local_cursor) { - _local_cursor->unref(); - } - _local_cursor = local_cursor->ref(); - _local_cursor->set(_win); - _cursor_visible = true; -} - -void RedWindow::show_cursor() -{ - if (!_cursor_visible) { - if (_local_cursor) { - _local_cursor->set(_win); - } - _cursor_visible = true; - } -} - -void RedWindow::hide_cursor() -{ - if (_cursor_visible) { - XDefineCursor(x_display, _win, _invisible_cursor); - _cursor_visible = false; - } -} - -void RedWindow::release_mouse() -{ - XLockDisplay(x_display); - XUngrabPointer(x_display, CurrentTime); - XUnlockDisplay(x_display); - sync(true); -} - -void RedWindow::capture_mouse() -{ - if (getenv("SPICE_NOGRAB")) - return; - - int grab_retries = MOUSE_GRAB_RETRIES; - XLockDisplay(x_display); - XSync(x_display, False); - XUnlockDisplay(x_display); - for (;; --grab_retries) { - XLockDisplay(x_display); - int result = XGrabPointer(x_display, _win, True, 0, - GrabModeAsync, GrabModeAsync, - _win, None, CurrentTime); - XUnlockDisplay(x_display); - if (result == GrabSuccess) { - break; - } - - if (!grab_retries) { - THROW("grab pointer failed (%d)", result); - } - usleep(X_RETRY_DELAY_MICRO); - DBG(0, "grab failed result=%d", result); - } - sync(); -} - -void RedWindow::set_mouse_position(int x, int y) -{ - XWarpPointer(x_display, None, _win, 0, 0, 0, 0, x + get_origin().x, y + get_origin().y); -} - -SpicePoint RedWindow::get_size() -{ - XWindowAttributes attrib; - XLockDisplay(x_display); - XGetWindowAttributes(x_display, _win, &attrib); - XUnlockDisplay(x_display); - SpicePoint size; - size.x = attrib.width; - size.y = attrib.height; - return size; -} - -static void window_area_from_attributes(SpiceRect& area, XWindowAttributes& attrib) -{ - area.left = attrib.x; - area.right = area.left + attrib.width; - area.top = attrib.y; - area.bottom = area.top + attrib.height; -} - -#define FAIL_ON_BAD_WINDOW(error, format, ...) \ - if (error) { \ - if ((x_error) == BadWindow) { \ - return NULL; \ - } \ - THROW(format, ## __VA_ARGS__); \ - } - - -static QRegion *get_visibale_region(Window window) -{ - QRegion* region = new QRegion; - region_init(region); - XWindowAttributes attrib; - int res; - - XLockDisplay(x_display); - res = XGetWindowAttributes(x_display, window, &attrib); - XUnlockDisplay(x_display); - if (!res) { - return NULL; - } - - if (attrib.map_state != IsViewable) { - DBG(0, "not viewable"); - return region; - } - - SpiceRect window_area; - window_area_from_attributes(window_area, attrib); - window_area.right -= window_area.left; - window_area.bottom -= window_area.top; - window_area.top = window_area.left = 0; - region_add(region, &window_area); - Window prev = None; - Window root; - Window parent; - Window* childrens; - unsigned int num_childrens; - - AutoXErrorHandler auto_error_handler; - for (;;) { - int res; - - XLockDisplay(x_display); - res = XQueryTree(x_display, window, &root, &parent, &childrens, - &num_childrens); - XUnlockDisplay(x_display); - FAIL_ON_BAD_WINDOW(!res, - "%s: query X tree failed", __FUNCTION__); - for (int i = num_childrens - 1; i >= 0 && childrens[i] != prev; i--) { - - XLockDisplay(x_display); - res = XGetWindowAttributes(x_display, childrens[i], &attrib); - XUnlockDisplay(x_display); - FAIL_ON_BAD_WINDOW(!res, - "%s: get win attributes failed", __FUNCTION__); - - if (attrib.map_state == IsViewable) { - window_area_from_attributes(window_area, attrib); - window_area.left -= attrib.border_width; - window_area.right += attrib.border_width; - window_area.top -= attrib.border_width; - window_area.bottom += attrib.border_width; - region_remove(region, &window_area); - } - } - - if (childrens) { - XFree(childrens); - } - - XLockDisplay(x_display); - res = XGetWindowAttributes(x_display, window, &attrib); - XUnlockDisplay(x_display); - FAIL_ON_BAD_WINDOW(!res, - "%s: get win attributes failed", __FUNCTION__); - window_area_from_attributes(window_area, attrib); - region_offset(region, window_area.left, window_area.top); - - if (parent == None) { - break; - } - - XLockDisplay(x_display); - res = XGetWindowAttributes(x_display, parent, &attrib); - XUnlockDisplay(x_display); - FAIL_ON_BAD_WINDOW(!res, - "%s: get win attributes failed", __FUNCTION__); - window_area_from_attributes(window_area, attrib); - window_area.right -= window_area.left; - window_area.bottom -= window_area.top; - window_area.top = window_area.left = 0; - - QRegion parent_region; - region_init(&parent_region); - region_add(&parent_region, &window_area); - region_and(region, &parent_region); - region_destroy(&parent_region); - - prev = window; - window = parent; - } - - //todo: intersect with monitors - return region; -} - -class Region_p { -public: - Region_p(QRegion* region) : _region (region) {} - ~Region_p() { delete _region;} - - void get_bbox(SpiceRect& bbox) const - { - if (region_is_empty(_region)) { - bbox.left = bbox.right = bbox.top = bbox.bottom = 0; - } else { - bbox.left = _region->extents.x1; - bbox.top = _region->extents.y1; - bbox.right = _region->extents.x2; - bbox.bottom = _region->extents.y2; - } - } - - bool contains_point(int x, int y) const - { - return region_contains_point(_region, x, y); - } - -private: - QRegion* _region; -}; - -bool RedWindow::get_mouse_anchor_point(SpicePoint& pt) -{ - QRegion* vis_region; - int vis_region_retries = GET_VIS_REGION_RETRIES; - - while (!(vis_region = get_visibale_region(_win))) { - if (!vis_region_retries) { - THROW("get visible region failed"); - } - --vis_region_retries; - usleep(X_RETRY_DELAY_MICRO); - } - - if (vis_region_retries < GET_VIS_REGION_RETRIES) { - DBG(0, "retries %d", (GET_VIS_REGION_RETRIES - vis_region_retries)); - } - - Region_p region(vis_region); - if (!find_anchor_point(region, pt)) { - return false; - } - SpicePoint position = get_position(); - pt.x -= (position.x + get_origin().x); - pt.y -= (position.y + get_origin().y); - return true; -} - -#ifdef USE_OPENGL -RedGlContext RedWindow::create_context_gl() -{ - if (XPlatform::get_fbconfig()[_screen]) { - XLockDisplay(x_display); - RedGlContext context = glXCreateContext(x_display, XPlatform::get_vinfo()[_screen], NULL, GL_TRUE); - XUnlockDisplay(x_display); - return context; - } - return NULL; -} - -RedPbuffer RedWindow::create_pbuff(int width, int height) -{ - GLXPbuffer pbuff; - GLXFBConfig** fb_config; - - int pbuf_attr[] = { GLX_PRESERVED_CONTENTS, True, - GLX_PBUFFER_WIDTH, width, - GLX_PBUFFER_HEIGHT, height, - GLX_LARGEST_PBUFFER, False, - 0, 0 }; - - fb_config = XPlatform::get_fbconfig(); - XLockDisplay(XPlatform::get_display()); - pbuff = glXCreatePbuffer(XPlatform::get_display(), fb_config[_screen][0], - pbuf_attr); - XUnlockDisplay(XPlatform::get_display()); - - return pbuff; -} - -void RedWindow::untouch_context() -{ - glXMakeCurrent(x_display, 0, 0); -} - -void RedWindow::swap_gl() -{ - PixelsSource_p *pix_source = (PixelsSource_p*)get_opaque(); - RedGlContext context = pix_source->x_drawable.context; - - if (!context) - return; - - glXMakeCurrent(x_display, get_window(), context); - glXSwapBuffers(x_display, get_window()); -} - -void RedWindow::set_type_gl() -{ - PixelsSource_p *pix_source = (PixelsSource_p*)get_opaque(); - - pix_source->type = PIXELS_SOURCE_TYPE_GL_DRAWABLE; -} - -void RedWindow::unset_type_gl() -{ - PixelsSource_p *pix_source = (PixelsSource_p*)get_opaque(); - - pix_source->type = PIXELS_SOURCE_TYPE_X_DRAWABLE; -} - -void RedWindow::set_gl_context(RedGlContext context) -{ - PixelsSource_p *pix_source = (PixelsSource_p*)get_opaque(); - - pix_source->x_drawable.context = context; -} - -void RedWindow::set_render_pbuff(RedPbuffer pbuff) -{ - PixelsSource_p *pix_source = (PixelsSource_p*)get_opaque(); - - pix_source->x_drawable.rendertype = RENDER_TYPE_PBUFF; - pix_source->x_drawable.pbuff = pbuff; -} - -void RedWindow::set_render_fbo(GLuint fbo) -{ - PixelsSource_p *pix_source = (PixelsSource_p*)get_opaque(); - - pix_source->x_drawable.rendertype = RENDER_TYPE_FBO; - pix_source->x_drawable.fbo = fbo; -} -#endif // USE_OPENGL - -int RedWindow::get_screen_num() -{ - return _screen; -} - -RedDrawable::Format RedWindow::get_format() -{ - return XPlatform::get_screen_format(_screen); -} - -void RedWindow::on_focus_in() -{ - if (_focused) { - return; - } - _focused = true; - if (x_input_context) { - XLockDisplay(x_display); - XwcResetIC(x_input_context); - XUnlockDisplay(x_display); - } - XPlatform::on_focus_in(); - get_listener().on_activate(); - if (_trace_key_interception && _pointer_in_window) { - do_start_key_interception(); - } -} - -void RedWindow::on_focus_out() -{ - if (!_focused) { - return; - } - _focused = false; - if (_key_interception_on) { - do_stop_key_interception(); - } - get_listener().on_deactivate(); - XPlatform::on_focus_out(); -} - -void RedWindow::on_pointer_enter(int x, int y, unsigned int buttons_state) -{ - if (_pointer_in_window) { - return; - } - _pointer_in_window = true; - _listener.on_pointer_enter(x, y, buttons_state); - if (_focused && _trace_key_interception) { - do_start_key_interception(); - } -} - -void RedWindow::on_pointer_leave() -{ - if (!_pointer_in_window) { - return; - } - _pointer_in_window = false; - _listener.on_pointer_leave(); - if (_key_interception_on) { - do_stop_key_interception(); - } -} - -int RedWindow::set_menu(Menu* menu) -{ - return 0; -} - -void RedWindow::init() -{ - x_display = XPlatform::get_display(); - x_input_context = XPlatform::get_input_context(); - ASSERT(x_display); - user_data_context = XUniqueContext(); - - wm_protocol_atom = XInternAtom(x_display, "WM_PROTOCOLS", False); - wm_delete_window_atom = XInternAtom(x_display, "WM_DELETE_WINDOW", False); - - wm_desktop = XInternAtom(x_display, "_NET_WM_DESKTOP", False); - wm_current_desktop = XInternAtom(x_display, "_NET_CURRENT_DESKTOP", False); - - wm_state = XInternAtom(x_display, "_NET_WM_STATE", False); - wm_state_above = XInternAtom(x_display, "_NET_WM_STATE_ABOVE", False); - wm_state_fullscreen = XInternAtom(x_display, "_NET_WM_STATE_FULLSCREEN", False); - - wm_user_time = XInternAtom(x_display, "_NET_WM_USER_TIME", False); - -#ifdef USE_X11_KEYCODE - init_key_map(); -#else - init_key_table_0xff(); - init_key_table_0x00(); - init_key_table_0xfe(); -#endif -} - -void RedWindow::cleanup() -{ -} diff --git a/client/x11/red_window_p.h b/client/x11/red_window_p.h deleted file mode 100644 index 4856be05..00000000 --- a/client/x11/red_window_p.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_RED_WINDOW_P -#define _H_RED_WINDOW_P - -#ifdef USE_OPENGL -#include <GL/glx.h> -#endif // USE_OPENGL -#include <X11/Xdefs.h> -#include <X11/Xlib.h> - -typedef Window Win; -#ifdef USE_OPENGL -typedef GLXContext RedGlContext; -typedef GLXPbuffer RedPbuffer; -#endif // USE_OPENGL - -class RedWindow; -class Icon; -struct PixelsSource_p; - -class RedWindow_p { -public: - RedWindow_p(); - - void migrate(RedWindow& red_window, PixelsSource_p& pix_source, int dest_screen); - void create(RedWindow& red_window, PixelsSource_p& pix_source, - int x, int y, int in_screen); - void destroy(RedWindow& red_window, PixelsSource_p& pix_source); - void set_minmax(PixelsSource_p& pix_source); - void wait_for_reparent(); - void wait_for_map(); - void wait_for_unmap(); - void sync(bool shadowed = false); - void set_visibale(bool vis) { _visibale = vis;} - void move_to_current_desktop(); - Window get_window() {return _win;} - - static void win_proc(XEvent& event); - static Cursor create_invisible_cursor(Window window); - -#ifdef USE_OPENGL - void set_glx(int width, int height); -#endif // USE_OPENGL - static void handle_key_press_event(RedWindow& red_window, XKeyEvent* event); - -protected: - int _screen; - Window _win; - Cursor _invisible_cursor; - bool _visibale; - bool _expect_parent; - SpicePoint _show_pos; - bool _show_pos_valid; - Icon* _icon; - bool _focused; - bool _ignore_foucs; - bool _shadow_foucs_state; - XEvent _shadow_focus_event; - bool _pointer_in_window; - bool _ignore_pointer; - bool _shadow_pointer_state; - XEvent _shadow_pointer_event; - Colormap _colormap; - RedWindow *_red_window; - int _width; - int _height; - Time _last_event_time; -}; - -#endif diff --git a/client/x11/res.cpp b/client/x11/res.cpp deleted file mode 100644 index efbd8de1..00000000 --- a/client/x11/res.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "resource.h" - -#include "images/alt_image.c" - -static const PixmapHeader alt_image = { - (uint8_t *)_alt_image.pixel_data, - _alt_image.width, - _alt_image.height, - _alt_image.width * 4, -}; - -typedef struct ResImage { - int id; - const PixmapHeader* image; -} ResImage; - -static const ResImage res_image_map[] = { - { ALT_IMAGE_RES_ID, &alt_image}, - {0, NULL}, -}; - -const PixmapHeader *res_get_image(int id) -{ - const ResImage *now = res_image_map; - for (; now->image; now++) { - if (now->id == id) { - return now->image; - } - } - return NULL; -} - -#include "images/red_icon.c" - -static const IconHeader red_icon = { - _red_icon.width, - _red_icon.height, - (uint8_t *)_red_icon.pixmap, - (uint8_t *)_red_icon.mask, -}; - -typedef struct ResIcon { - int id; - const IconHeader* icon; -} ResIcon; - -static const ResIcon res_icon_map[] = { - { RED_ICON_RES_ID, &red_icon}, - {0, NULL}, -}; - -const IconHeader *res_get_icon(int id) -{ - const ResIcon *now = res_icon_map; - for (; now->icon; now++) { - if (now->id == id) { - return now->icon; - } - } - return NULL; -} diff --git a/client/x11/res.h b/client/x11/res.h deleted file mode 100644 index 8320e9b6..00000000 --- a/client/x11/res.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_RES -#define _H_RES - -const PixmapHeader *res_get_image(int id); -const IconHeader *res_get_icon(int id); - -#endif diff --git a/client/x11/resource.h b/client/x11/resource.h deleted file mode 100644 index 562b9b98..00000000 --- a/client/x11/resource.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_RED_RESOURCES -#define _H_RED_RESOURCES - -#define RED_ICON_RES_ID 3 -#define ALT_IMAGE_RES_ID 4 - -#endif diff --git a/client/x11/x_icon.cpp b/client/x11/x_icon.cpp deleted file mode 100644 index edd983f1..00000000 --- a/client/x11/x_icon.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "x_icon.h" -#include "platform.h" -#include "x_platform.h" -#include "res.h" -#include "utils.h" -#include "debug.h" - -typedef std::map<int, XIcon*> IconsMap; -static IconsMap res_icons; - -XIcon::XIcon(int id, const IconHeader *icon) - : _id (id) - , _raw_icon (icon) -{ - res_icons[id] = this; -} - -XIcon::~XIcon() -{ - Display* x_display = XPlatform::get_display(); - while (!_screen_icons.empty()) { - std::map<int, ScreenIcon>::iterator iter = _screen_icons.begin(); - XFreePixmap(x_display, (*iter).second.pixmap); - XFreePixmap(x_display, (*iter).second.mask); - _screen_icons.erase(iter); - } - IconsMap::iterator iter = res_icons.find(_id); - res_icons.erase(iter); -} - -void XIcon::get_pixmaps(int screen, Pixmap& out_pixmap, Pixmap& out_mask) -{ - std::map<int, ScreenIcon>::iterator iter = _screen_icons.find(screen); - if (iter != _screen_icons.end()) { - out_pixmap = (*iter).second.pixmap; - out_mask = (*iter).second.mask; - return; - } - - Display* x_display = XPlatform::get_display(); - Window root_window = RootWindow(x_display, screen); - - Pixmap pixmap = None; - Pixmap mask = None; - GC gc = NULL; - try { - XLockDisplay(x_display); - pixmap = XCreatePixmap(x_display, root_window, _raw_icon->width, _raw_icon->height, 24); - XUnlockDisplay(x_display); - if (pixmap == None) { - THROW("create pixmap failed"); - } - - XWindowAttributes attr; - - XLockDisplay(x_display); - XGetWindowAttributes(x_display, root_window, &attr); - XUnlockDisplay(x_display); - - XImage image; - memset(&image, 0, sizeof(image)); - image.width = _raw_icon->width; - image.height = _raw_icon->height; - image.data = (char*)_raw_icon->pixmap; - image.byte_order = LSBFirst; - image.bitmap_unit = 32; - image.bitmap_bit_order = LSBFirst; - image.bitmap_pad = 32; - image.bytes_per_line = _raw_icon->width * 4; - image.depth = 24; - image.format = ZPixmap; - image.bits_per_pixel = 32; - image.red_mask = 0x00ff0000; - image.green_mask = 0x0000ff00; - image.blue_mask = 0x000000ff; - - if (!XInitImage(&image)) { - THROW("init image failed"); - } - - XGCValues gc_vals; - gc_vals.function = GXcopy; - gc_vals.foreground = ~0; - gc_vals.background = 0; - gc_vals.plane_mask = AllPlanes; - - XLockDisplay(x_display); - gc = XCreateGC(x_display, pixmap, GCFunction | GCForeground | GCBackground | GCPlaneMask, - &gc_vals); - XPutImage(x_display, pixmap, gc, &image, 0, 0, 0, 0, image.width, image.height); - // HDG: why ?? XFlush should suffice - XSync(x_display, False); - XFreeGC(x_display, gc); - gc = NULL; - - mask = XCreatePixmap(x_display, root_window, _raw_icon->width, _raw_icon->height, 1); - XUnlockDisplay(x_display); - if (mask == None) { - THROW("create mask failed"); - } - - memset(&image, 0, sizeof(image)); - image.width = _raw_icon->width; - image.height = _raw_icon->height; - image.data = (char*)_raw_icon->mask; - image.byte_order = LSBFirst; - image.bitmap_unit = 8; - image.bitmap_bit_order = MSBFirst; - image.bitmap_pad = 8; - image.bytes_per_line = _raw_icon->width / 8; - image.depth = 1; - image.format = XYBitmap; - if (!XInitImage(&image)) { - THROW("init image failed"); - } - - XLockDisplay(x_display); - gc = XCreateGC(x_display, mask, GCFunction | GCForeground | GCBackground | GCPlaneMask, - &gc_vals); - XPutImage(x_display, mask, gc, &image, 0, 0, 0, 0, image.width, image.height); - // HDG: why ?? XFlush should suffice - XSync(x_display, False); - XUnlockDisplay(x_display); - XFreeGC(x_display, gc); - } catch (...) { - if (gc) { - XFreeGC(x_display, gc); - } - if (mask) { - XFreePixmap(x_display, mask); - } - if (pixmap) { - XFreePixmap(x_display, pixmap); - } - throw; - } - _screen_icons[screen] = ScreenIcon(pixmap, mask); - out_pixmap = pixmap; - out_mask = mask; -} - -Icon* Platform::load_icon(int id) -{ - IconsMap::iterator iter = res_icons.find(id); - if (iter != res_icons.end()) { - return (*iter).second->ref(); - } - - const IconHeader *icon = res_get_icon(id); - if (!icon) { - return NULL; - } - XIcon *xicon = new XIcon(id, icon); - return xicon->ref(); -} diff --git a/client/x11/x_icon.h b/client/x11/x_icon.h deleted file mode 100644 index b8b5e96d..00000000 --- a/client/x11/x_icon.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_X_ICON -#define _H_X_ICON - -#include <X11/Xlib.h> -#include <map> - -#include "common.h" - -#include "icon.h" - -class XIcon: public Icon { -public: - XIcon(int id, const IconHeader *icon); - - void get_pixmaps(int screen, Pixmap& pixmap, Pixmap& mask); - -protected: - virtual ~XIcon(); - -private: - int _id; - const IconHeader* _raw_icon; - - class ScreenIcon { - public: - ScreenIcon(Pixmap in_pixmap, Pixmap in_mask) : pixmap (in_pixmap), mask (in_mask) {} - ScreenIcon() : pixmap (None), mask (None) {} - - Pixmap pixmap; - Pixmap mask; - }; - std::map<int, ScreenIcon> _screen_icons; -}; - -#endif diff --git a/client/x11/x_platform.h b/client/x11/x_platform.h deleted file mode 100644 index 39a2d1c3..00000000 --- a/client/x11/x_platform.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H_XPLATFORM -#define _H_XPLATFORM - -#include "red_drawable.h" -#include <X11/Xdefs.h> -#include <X11/Xutil.h> -#include <X11/extensions/XShm.h> - -class XPlatform { -public: - static Display* get_display(); - static XVisualInfo** get_vinfo(); - static RedDrawable::Format get_screen_format(int screen); - static XIC get_input_context(); -#ifdef USE_OPENGL - static GLXFBConfig** get_fbconfig(); -#endif // USE_OPENGL - - typedef void (*win_proc_t)(XEvent& event); - static void set_win_proc(Window win, win_proc_t proc); - static void cleare_win_proc(Window win); - - static void on_focus_in(); - static void on_focus_out(); - - static bool is_x_shm_avail(); - static XImage *create_x_shm_image(RedDrawable::Format format, - int width, int height, int depth, - Visual *visual, - XShmSegmentInfo **shminfo_out); - static XImage *create_x_image(RedDrawable::Format format, - int width, int height, int depth, - Visual *visual, - XShmSegmentInfo **shminfo_out); - static void free_x_image(XImage *image, - XShmSegmentInfo *shminfo); -}; - -#endif |