diff --git a/.gitignore b/.gitignore index c4f75b5..cfd208f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /Debug /.settings +/.vscode .project .cproject diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 73179f5..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(xfree) -#include_directories(/home/alexander/repositories/iup/include) -include_directories(/root/iup/include) -set(SOURCE_EXE - address.c - arguments.c - concat.c - db.c - gui.c - images.c - monitor.c - node_settings.c - rxrandr_broker.c - rxrandr.c - settings.c - xfreerdp.c - xrdp.c -) -add_executable(xfree ${SOURCE_EXE}) -#target_link_libraries(xfree iup X11 Xrandr m /home/alexander/programming/c/iup/sqlite3.a) -target_link_libraries(xfree - gtk-3 - gdk-3 - pangocairo-1.0 - pango-1.0 - atk-1.0 - cairo-gobject - cairo - gdk_pixbuf-2.0 - gio-2.0 - gobject-2.0 - glib-2.0 - X11 - Xrandr - m - - dl - pthread - - /root/iup/lib/Linux515/libiup.a - /root/SQLite/sqlite3.a -) -#target_link_libraries(xfree iup X11 Xrandr m sqlite3 -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lX11 -lXrandr -lm) diff --git a/FreeRDP_X11_path_config/CMakeLists.txt b/FreeRDP_X11_path_config/CMakeLists.txt deleted file mode 100644 index 1ab8209..0000000 --- a/FreeRDP_X11_path_config/CMakeLists.txt +++ /dev/null @@ -1,253 +0,0 @@ -# FreeRDP: A Remote Desktop Protocol Implementation -# FreeRDP X11 Client -# -# Copyright 2012 Marc-Andre Moreau -# Copyright 2013 Corey Clayton -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set(MODULE_NAME "xfreerdp-client") -set(MODULE_PREFIX "FREERDP_CLIENT_X11_CONTROL") - -include(FindDocBookXSL) -include_directories(${X11_INCLUDE_DIRS}) -include_directories(${OPENSSL_INCLUDE_DIR}) - -include_directories(iup PRIVATE /root/iup/iup/source/include) - -set(${MODULE_PREFIX}_SRCS - xf_gdi.c - xf_gdi.h - xf_gfx.c - xf_gfx.h - xf_rail.c - xf_rail.h - xf_input.c - xf_input.h - xf_event.c - xf_event.h - xf_floatbar.c - xf_floatbar.h - xf_input.c - xf_input.h - xf_channels.c - xf_channels.h - xf_cliprdr.c - xf_cliprdr.h - xf_monitor.c - xf_monitor.h - xf_disp.c - xf_disp.h - xf_graphics.c - xf_graphics.h - xf_keyboard.c - xf_keyboard.h - xf_video.c - xf_video.h - xf_window.c - xf_window.h - xf_client.c - xf_client.h) - -if (CHANNEL_TSMF_CLIENT) - set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} - xf_tsmf.c - xf_tsmf.h) -endif() - -if(WITH_CLIENT_INTERFACE) - if(CLIENT_INTERFACE_SHARED) - add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS}) - if (WITH_LIBRARY_VERSIONING) - set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) - endif() - else() - add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) - endif() - -else() - set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/xfreerdp.c cli/images.c xfreerdp.h cli/arguments.c cli/concat.c cli/gui.c cli/node_settings.c cli/rxrandr_broker cli/rxrandr.c cli/settings.c cli/db.c cli/address.c cli/monitor.c cli/xrdp.c) - add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) - set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp") - include_directories(..) -endif() - -set(${MODULE_PREFIX}_LIBS - ${X11_LIBRARIES}) - -if(WITH_MANPAGES) - find_program(XSLTPROC_EXECUTABLE NAMES xsltproc) - - if(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE) - - # We need the variable ${MAN_TODAY} to contain the current date in ISO - # format to replace it in the configure_file step. - include(today) - - TODAY(MAN_TODAY) - - configure_file(xfreerdp.1.xml.in xfreerdp.1.xml @ONLY IMMEDIATE) - - # Compile the helper tool with default compiler settings. - # We need the include paths though. - get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) - set(GENERATE_INCLUDES "") - foreach(dir ${dirs}) - set(GENERATE_INCLUDES ${GENERATE_INCLUDES} -I${dir}) - endforeach(dir) - - add_custom_command(OUTPUT xfreerdp.1 - COMMAND ${CMAKE_C_COMPILER} ${GENERATE_INCLUDES} - ${CMAKE_CURRENT_SOURCE_DIR}/generate_argument_docbook.c - -o ${CMAKE_CURRENT_BINARY_DIR}/generate_argument_docbook - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/generate_argument_docbook - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-envvar.1.xml ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS - ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml - ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml - ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml - ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-envvar.1.xml) - - add_custom_target(xfreerdp.manpage ALL - DEPENDS xfreerdp.1) - - install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 1) - else() - message(WARNING "WITH_MANPAGES was set, but xsltproc was not found. man-pages will not be installed") - endif() -endif(WITH_MANPAGES) - -set(XSHM_FEATURE_TYPE "REQUIRED") -set(XSHM_FEATURE_PURPOSE "X11 shared memory") -set(XSHM_FEATURE_DESCRIPTION "X11 shared memory extension") - -set(XINERAMA_FEATURE_TYPE "RECOMMENDED") -set(XINERAMA_FEATURE_PURPOSE "multi-monitor") -set(XINERAMA_FEATURE_DESCRIPTION "X11 multi-monitor extension") - -set(XEXT_FEATURE_TYPE "RECOMMENDED") -set(XEXT_FEATURE_PURPOSE "X11 extension") -set(XEXT_FEATURE_DESCRIPTION "X11 core extensions") - -set(XCURSOR_FEATURE_TYPE "RECOMMENDED") -set(XCURSOR_FEATURE_PURPOSE "cursor") -set(XCURSOR_FEATURE_DESCRIPTION "X11 cursor extension") - -set(XV_FEATURE_TYPE "RECOMMENDED") -set(XV_FEATURE_PURPOSE "video") -set(XV_FEATURE_DESCRIPTION "X11 video extension") - -set(XI_FEATURE_TYPE "RECOMMENDED") -set(XI_FEATURE_PURPOSE "input") -set(XI_FEATURE_DESCRIPTION "X11 input extension") - -set(XRENDER_FEATURE_TYPE "RECOMMENDED") -set(XRENDER_FEATURE_PURPOSE "rendering") -set(XRENDER_FEATURE_DESCRIPTION "X11 render extension") - -set(XRANDR_FEATURE_TYPE "RECOMMENDED") -set(XRANDR_FEATURE_PURPOSE "tracking output configuration") -set(XRANDR_FEATURE_DESCRIPTION "X11 randr extension") - -set(XFIXES_FEATURE_TYPE "RECOMMENDED") -set(XFIXES_FEATURE_PURPOSE "X11 xfixes extension") -set(XFIXES_FEATURE_DESCRIPTION "Useful additions to the X11 core protocol") - -find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION}) -find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION}) -find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION}) -find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION}) -find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION}) -find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION}) -find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION}) -find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION}) -find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION}) - -if(WITH_XINERAMA) - add_definitions(-DWITH_XINERAMA) - include_directories(${XINERAMA_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XINERAMA_LIBRARIES}) -endif() - -if(WITH_XEXT) - add_definitions(-DWITH_XEXT) - include_directories(${XEXT_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XEXT_LIBRARIES}) -endif() - -if(WITH_XCURSOR) - add_definitions(-DWITH_XCURSOR) - include_directories(${XCURSOR_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XCURSOR_LIBRARIES}) -endif() - -if(WITH_XV) - add_definitions(-DWITH_XV) - include_directories(${XV_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XV_LIBRARIES}) -endif() - -if(WITH_XI) - add_definitions(-DWITH_XI) - include_directories(${XI_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XI_LIBRARIES}) -endif() - -if(WITH_XRENDER) - add_definitions(-DWITH_XRENDER) - include_directories(${XRENDER_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES}) -endif() - -if(WITH_XRANDR) - add_definitions(-DWITH_XRANDR) - include_directories(${XRANDR_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRANDR_LIBRARIES}) -endif() - -if(WITH_XFIXES) - add_definitions(-DWITH_XFIXES) - include_directories(${XFIXES_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XFIXES_LIBRARIES}) -endif() - -include_directories(${CMAKE_SOURCE_DIR}/resources) - -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client freerdp m) -if (NOT APPLE) - list(APPEND ${MODULE_PREFIX}_LIBS rt) -endif() -#target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${${MODULE_PREFIX}_LIBS} iup /root/xfreerdp/source/client/X11/sqlite3.a) -target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${${MODULE_PREFIX}_LIBS} iup sqlite3) -#target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${${MODULE_PREFIX}_LIBS} iup Xrandr -L/home/alexander/programming/c/FreeRDP/client/X11/cli/sqlite3.a -lsqlite3) - -if(WITH_IPP) - target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${IPP_LIBRARY_LIST}) -endif() - -if(WITH_CLIENT_INTERFACE) - install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries) - add_subdirectory(cli) -else() - install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) -endif() - -set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/X11") - diff --git a/FreeRDP_X11_path_config/README.md b/FreeRDP_X11_path_config/README.md deleted file mode 100644 index ca84a3f..0000000 --- a/FreeRDP_X11_path_config/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# CMake-файлы для FreeRDP - -Файлы основаны на [FreeRDP 2.8.0](https://github.com/FreeRDP/FreeRDP) - -Необходимо поместить в каталог проекта `./client/X11`. diff --git a/FreeRDP_X11_path_config/cli/.gitignore b/FreeRDP_X11_path_config/cli/.gitignore deleted file mode 100644 index 6ddebc6..0000000 --- a/FreeRDP_X11_path_config/cli/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -xfreerdp - diff --git a/FreeRDP_X11_path_config/cli/CMakeLists.txt b/FreeRDP_X11_path_config/cli/CMakeLists.txt deleted file mode 100644 index a2ce9e1..0000000 --- a/FreeRDP_X11_path_config/cli/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# FreeRDP: A Remote Desktop Protocol Implementation -# FreeRDP X11 cmake build script -# -# Copyright 2012 Marc-Andre Moreau -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set(MODULE_NAME "xfreerdp-cli") -set(MODULE_PREFIX "FREERDP_CLIENT_X11") - -set(${MODULE_PREFIX}_SRCS - xfreerdp.c - images.c, - arguments.c, - concat.c, - gui.c, - node_settings.c, - rxrandr_broker.c, - rxrandr.c, - settings.c, - db.c, - address.c, - monitor.c, - xrdp.c - ) - -add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) -set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp" RUNTIME_OUTPUT_DIRECTORY "..") - -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} xfreerdp-client freerdp-client) - -if(OPENBSD) - target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS} ossaudio) -else() - target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -endif() - -install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) - -set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/X11") - diff --git a/README.md b/README.md index 6c2f80f..e37459e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,83 @@ # GUI для FreeRDP -Надстройка для FreeRDP на основе библиотеки [`IUP`](https://www.tecgraf.puc-rio.br/iup/). - -## Основное окно +- Основано на базе [FreeRDP 2.10.0](https://github.com/FreeRDP/FreeRDP) ([локальная версия](http://git.belpig.ru/forks/FreeRDP)) +- Надстройка для FreeRDP на основе библиотеки [`IUP`](https://www.tecgraf.puc-rio.br/iup/). ![main.png](img/main.png) - -## Окно настроек - ![settings.png](img/settings.png) + +## Сборка программы + +- [xrandr.patch](xrandr.patch) - исправления поиска библиотеки `Xrandr` +- [gui.patch](gui.patch) - включение использования GUI в оригинальный проект `freerdp` + +### Подготовка + +Скопировать файлы из [freerdp](freerdp/) в оригинальный проект `(2.10.0)`: + +```sh +cp -r GUI-FreeRDP/freerdp/* freerdp-2.10.0/ +``` + +Перейти в оригинальный каталог: + +```sh +cd freerdp-2.10.0 +``` + +Применить патчи: + +```sh +git apply ../GUI-FreeRDP/gui.patch +git apply ../GUI-FreeRDP/xrandr.patch +``` + +## Сборка + +Параметры сборки: + +- `IUP_WITH_COLOR_BUTTONS` - поддержка цветных кнопок (по умолчанию `OFF`) +- `IUP_WITH_SOUND_CHECKBOX` - поддержка параметров звука (по умолчанию `OFF`) +- `IUP_DESCRIPTION_ABOUT_ARCH_X32` - в описании "О прогамме" отобразить пометку для x32 архитектур (по умолчанию `OFF`) +- `IUP_WITH_LANGUAGE_KEYBOARD_ICON` - поддержка отображения раскладки клавиатуры (по умолчанию `OFF`) +- `IUP_DESCRIPTION_ABOUT_MIRATORG` - в описании "О прогамме" отобразить рабочие контактные данные (по умолчанию `OFF`) + +Создать отдельный каталог `build`: + +```sh +mkdir build +cd build +``` + +и выполнить в нём сборку: + +```sh +cmake -B . -S ../freerdp-2.10.0 \ + -DWITH_WAYLAND=OFF \ + -DWITH_OSS=OFF \ + -DWITH_ALSA=OFF \ + -DWITH_PULSE=OFF \ + -DWITH_CUPS=OFF \ + -DWITH_PCSC=OFF \ + -DWITH_FFMPEG=OFF \ + -DWITH_OPENSSL=ON \ + -DWITH_XV=OFF \ + -DWITH_FUSE=OFF \ + -DWITH_SWSCALE=OFF \ + -DWITH_CAIRO=OFF \ + -DWITH_DSP_FFMPEG=OFF \ + -DWITH_FAAC=OFF \ + -DWITH_SSE2=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DIUP_WITH_COLOR_BUTTONS=ON \ + -DIUP_WITH_SOUND_CHECKBOX=OFF \ + -DIUP_DESCRIPTION_ABOUT_ARCH_X32=OFF \ + -DIUP_WITH_LANGUAGE_KEYBOARD_ICON=ON \ + -DIUP_DESCRIPTION_ABOUT_MIRATORG=ON +``` + +и компиляцию программы: + +```sh +make -j16 +``` diff --git a/freerdp.db b/freerdp.db index 7c0f798..416201a 100644 Binary files a/freerdp.db and b/freerdp.db differ diff --git a/freerdp/client/X11/cli/about.c b/freerdp/client/X11/cli/about.c new file mode 100644 index 0000000..5c91ae9 --- /dev/null +++ b/freerdp/client/X11/cli/about.c @@ -0,0 +1,32 @@ +/* + * about.c + * + * Created on: 16 февр. 2023 г. + * Author: alexander + */ + +#include "about.h" + +char* getAbout() +{ + char *about = + "GUI FreeRDP v1.2.0\n" + "Собрано на основе FreeRDP v2.10.0\n" +#ifdef IUP_DESCRIPTION_ABOUT_ARCH_X32 + "Для тонкого клиента архитектуры x32\n" +#else + "Для тонкого клиента архитектуры x64\n" +#endif + "Все вопросы оставлять по адресу:\n" +#ifdef IUP_DESCRIPTION_ABOUT_MIRATORG + "http://git.belpig.ru/a.zhirov/GUI-FreeRDP/issues\n" + "Электронная почта: a.zhirov@agrohold.ru\n" + "© Александр Жиров" +#else + "https://git.zhirov.kz/alexander/GUI-FreeRDP\n" + "Электронная почта: alexander@zhirov.kz\n" + "© Александр Жиров" +#endif + ; + return about; +} diff --git a/freerdp/client/X11/cli/about.h b/freerdp/client/X11/cli/about.h new file mode 100644 index 0000000..ffe8f10 --- /dev/null +++ b/freerdp/client/X11/cli/about.h @@ -0,0 +1,13 @@ +/* + * about.h + * + * Created on: 16 февр. 2023 г. + * Author: alexander + */ + +#ifndef CLIENT_X11_CLI_ABOUT_H_ +#define CLIENT_X11_CLI_ABOUT_H_ + +char* getAbout(); + +#endif /* CLIENT_X11_CLI_ABOUT_H_ */ diff --git a/address.c b/freerdp/client/X11/cli/address.c similarity index 100% rename from address.c rename to freerdp/client/X11/cli/address.c diff --git a/address.h b/freerdp/client/X11/cli/address.h similarity index 100% rename from address.h rename to freerdp/client/X11/cli/address.h diff --git a/arguments.c b/freerdp/client/X11/cli/arguments.c similarity index 100% rename from arguments.c rename to freerdp/client/X11/cli/arguments.c diff --git a/arguments.h b/freerdp/client/X11/cli/arguments.h similarity index 100% rename from arguments.h rename to freerdp/client/X11/cli/arguments.h diff --git a/concat.c b/freerdp/client/X11/cli/concat.c similarity index 100% rename from concat.c rename to freerdp/client/X11/cli/concat.c diff --git a/concat.h b/freerdp/client/X11/cli/concat.h similarity index 100% rename from concat.h rename to freerdp/client/X11/cli/concat.h diff --git a/db.c b/freerdp/client/X11/cli/db.c similarity index 100% rename from db.c rename to freerdp/client/X11/cli/db.c diff --git a/db.h b/freerdp/client/X11/cli/db.h similarity index 100% rename from db.h rename to freerdp/client/X11/cli/db.h diff --git a/gui.c b/freerdp/client/X11/cli/gui.c similarity index 59% rename from gui.c rename to freerdp/client/X11/cli/gui.c index a8612c0..689a335 100644 --- a/gui.c +++ b/freerdp/client/X11/cli/gui.c @@ -15,24 +15,59 @@ #include "images.h" #include "arguments.h" #include "address.h" +#include "keylang.h" #include "db.h" #include "xrdp.h" -//#include "../xfreerdp.h" +#include "../xfreerdp.h" static int guiExit(Ihandle *self) { return IUP_CLOSE; } +int isEmptyFieldServerUser(Ihandle *self) +{ + char *name = IupGetAttribute(self, "NAME"); + if (!strcmp(name, "SERVER")) + return !strcmp(IupGetAttribute(IupGetDialogChild(self, "USER"), "LINEVALUE"), "\0"); + else + return !strcmp(IupGetAttribute(IupGetDialogChild(self, "SERVER"), "VALUE"), "\0"); +} + +static int activeBtnConnect(Ihandle *self, int c, char *value) +{ + if (!strcmp(value, "\0") || isEmptyFieldServerUser(self)) + { + IupSetInt(IupGetDialogChild(self, "CONNECT"), "ACTIVE", 0); +#ifdef IUP_WITH_COLOR_BUTTONS + IupSetAttribute(IupGetDialogChild(self, "CONNECT"), "BGCOLOR", "49 54 61"); + IupSetAttribute(IupGetDialogChild(self, "CONNECT"), "FGCOLOR", "238 238 238"); +#endif + } + else + { + IupSetInt(IupGetDialogChild(self, "CONNECT"), "ACTIVE", 1); +#ifdef IUP_WITH_COLOR_BUTTONS + IupSetAttribute(IupGetDialogChild(self, "CONNECT"), "BGCOLOR", "0 179 0"); + IupSetAttribute(IupGetDialogChild(self, "CONNECT"), "FGCOLOR", "255 255 255"); +#endif + } + return IUP_DEFAULT; +} + static int guiConnect(Ihandle *self) { char *host = IupGetAttribute(IupGetDialogChild(self, "SERVER"), "VALUE"); - char *login = IupGetAttribute(IupGetDialogChild(self, "USER"), "LINEVALUE"); char *result = getHostIP(host); if (!result) - return IUP_DEFAULT; + return IUP_IGNORE; + + char *login = IupGetAttribute(IupGetDialogChild(self, "USER"), "LINEVALUE"); + + if (!strcmp(login, "\0")) + return IUP_IGNORE; setParameterValue(PARAMETER_SERVER, VALUE_SERVER, result); setParameterValue(PARAMETER_USERNAME, VALUE_USERNAME, login); @@ -45,23 +80,28 @@ static int guiConnect(Ihandle *self) printf("%s\n", args.argv[i]); } -// if (free_rdp_connect(args.argc, args.argv) != XF_EXIT_DNS_NAME_NOT_FOUND) -// { + // Добавление в историю любой попытки подключиться к удаленному серверу + dbInsertHistory(login, host); + + enum XF_EXIT_CODE xCode = free_rdp_connect(args.argc, args.argv); + + if (!(xCode == XF_EXIT_DNS_NAME_NOT_FOUND || xCode == XF_EXIT_CONNECT_FAILED || xCode == XF_EXIT_TLS_CONNECT_FAILED)) + { + IupSetAttribute(IupGetDialogChild(self, "PASSWORD"), "VALUE", ""); + if (!dbAddServer(result, host)) { IupSetAttribute(IupGetDialogChild(self, "SERVER"), "APPENDITEM", host); } - - dbInsertHistory(login, host); dbSetUserNameCurrent(login); -// } + } freeArguments(&args); return IUP_DEFAULT; } -static void createHostsList(Ihandle *iupList) +static char* createHostsList(Ihandle *iupList) { Hosts *hosts = dbGetHostsList(); char *indexItem = NULL; @@ -82,8 +122,27 @@ static void createHostsList(Ihandle *iupList) IupSetAttribute(iupList, "VALUE", serverName); } dbFreeHosts(hosts); + + return serverName; } +#ifdef IUP_WITH_LANGUAGE_KEYBOARD_ICON +static int k_any(Ihandle *self, int key) +{ + int langcode = getKeyboardLanguage(); + if (langcode) + { + if (langcode == 1) + IupSetAttribute(IupGetDialogChild(self, "KEYBOARD"), "IMAGE", "keyboardUs"); + else if (langcode == 2) + IupSetAttribute(IupGetDialogChild(self, "KEYBOARD"), "IMAGE", "keyboardRu"); + else + IupSetAttribute(IupGetDialogChild(self, "KEYBOARD"), "IMAGE", "keyboardEmpty"); + } + return IUP_DEFAULT; +} +#endif + Ihandle* guiStart() { Ihandle *dlg; @@ -110,11 +169,13 @@ Ihandle* guiStart() inputServer = IupList(NULL); IupSetAttribute(inputServer, "NAME", "SERVER"); - IupSetAttribute(inputServer, "TIP", "IP-адрес или имя удаленного сервера (обязательно)"); - createHostsList(inputServer); + IupSetAttribute(inputServer, "TIP", "IP-адрес или имя удаленного сервера\n(обязательное для заполнения поле)"); + char *hostname = createHostsList(inputServer); IupSetAttribute(inputServer, "SIZE", "100"); IupSetAttribute(inputServer, "EDITBOX", "YES"); IupSetAttribute(inputServer, "DROPDOWN", "YES"); + IupSetAttribute(inputServer, "MASK", "[A-Za-z0-9/./-]*"); + IupSetCallback(inputServer, "EDIT_CB", (Icallback) activeBtnConnect); hBoxServer = IupHbox(labelServer, inputServer, NULL); IupSetAttribute(hBoxServer, "MARGIN", "10x10"); @@ -124,9 +185,12 @@ Ihandle* guiStart() IupSetAttribute(labelUser, "PADDING", "5"); inputUser = IupText(NULL); IupSetAttribute(inputUser, "NAME", "USER"); - IupSetAttribute(inputUser, "TIP", "<домен>\\<имя пользователя> (обязательно)"); - IupSetAttribute(inputUser, "VALUE", getSetValueCurrent(PARAMETER_USERNAME)); + IupSetAttribute(inputUser, "TIP", "<домен>\\<имя пользователя>\n<имя пользователя>@<домен>\n(обязательное для заполнения поле)"); + char *username = getSetValueCurrent(PARAMETER_USERNAME); + IupSetAttribute(inputUser, "VALUE", username); IupSetAttribute(inputUser, "SIZE", "100"); + IupSetAttribute(inputUser, "MASK", "(/w|[/./\\/@/-])*"); + IupSetCallback(inputUser, "ACTION", (Icallback) activeBtnConnect); hBoxUser = IupHbox(labelUser, inputUser, NULL); IupSetAttribute(hBoxUser, "MARGIN", "10x0"); @@ -143,32 +207,62 @@ Ihandle* guiStart() hBoxPassword = IupHbox(labelPassword, inputPassword, NULL); IupSetAttribute(hBoxPassword, "MARGIN", "10x10"); +#ifdef IUP_WITH_LANGUAGE_KEYBOARD_ICON + Ihandle *keyboardRu, *keyboardUs, *keyboardEmpty, *iconLang; + keyboardEmpty = IupImageRGBA(32, 32, empty_keyboard); + IupSetHandle("keyboardEmpty", keyboardEmpty); + keyboardRu = IupImageRGBA(32, 32, ru_keyboard); + IupSetHandle("keyboardRu", keyboardRu); + keyboardUs = IupImageRGBA(32, 32, us_keyboard); + IupSetHandle("keyboardUs", keyboardUs); + iconLang = IupLabel(NULL); + IupSetAttribute(iconLang, "NAME", "KEYBOARD"); + IupSetAttribute(iconLang, "IMAGE", "keyboardRu"); + IupSetAttribute(iconLang, "FLOATING", "YES"); + IupSetAttribute(iconLang, "POSITION", "13,222"); + IupSetAttribute(iconLang, "TIP", "Текущая раскладка клавиатуры (Alt+Shift)"); +#endif + btnConnect = IupButton("Подключение", NULL); IupSetHandle("CONNECT", btnConnect); IupSetAttribute(btnConnect, "NAME", "CONNECT"); IupSetAttribute(btnConnect, "TIP", "Выполнить подключение"); + if (username && hostname) + IupSetAttribute(btnConnect, "ACTIVE", "YES"); + else + IupSetAttribute(btnConnect, "ACTIVE", "NO"); +#ifdef IUP_WITH_COLOR_BUTTONS IupSetAttribute(btnConnect, "BGCOLOR", "0 179 0"); IupSetAttribute(btnConnect, "FGCOLOR", "255 255 255"); +#endif btnClose = IupButton("Закрыть", NULL); IupSetHandle("CLOSE", btnClose); IupSetAttribute(btnClose, "NAME", "CLOSE"); IupSetAttribute(btnClose, "TIP", "Закрыть FreeRDP"); +#ifdef IUP_WITH_COLOR_BUTTONS IupSetAttribute(btnClose, "BGCOLOR", "204 0 0"); IupSetAttribute(btnClose, "FGCOLOR", "255 255 255"); +#endif btnSettings = IupButton("Настройки", NULL); IupSetAttribute(btnSettings, "NAME", "SETTINGS"); IupSetAttribute(btnSettings, "TIP", "Перейти в настройки"); +#ifdef IUP_WITH_COLOR_BUTTONS IupSetAttribute(btnSettings, "BGCOLOR", "0 136 204"); IupSetAttribute(btnSettings, "FGCOLOR", "255 255 255"); +#endif hBoxButtons = IupHbox(IupFill(), btnSettings, btnConnect, btnClose, IupFill(), NULL); IupSetAttribute(hBoxButtons, "ALIGNMENT", "ACENTER:ACENTER"); IupSetAttribute(hBoxButtons, "GAP", "10"); IupSetAttribute(hBoxButtons, "MARGIN", "10x10"); - vBoxMain = IupVbox(labelImage, hBoxServer, hBoxUser, hBoxPassword, hBoxButtons, NULL); + vBoxMain = IupVbox( +#ifdef IUP_WITH_LANGUAGE_KEYBOARD_ICON + iconLang, +#endif + labelImage, hBoxServer, hBoxUser, hBoxPassword, hBoxButtons, NULL); IupSetCallback(btnConnect, "ACTION", (Icallback) guiConnect); IupSetCallback(btnClose, "ACTION", (Icallback) guiExit); @@ -182,6 +276,10 @@ Ihandle* guiStart() IupSetAttribute(dlg, "PARENTDIALOG", "MAIN_WINDOW"); IupSetAttribute(dlg, "DEFAULTENTER", "CONNECT"); IupSetAttribute(dlg, "DEFAULTESC", "CLOSE"); +#ifdef IUP_WITH_LANGUAGE_KEYBOARD_ICON + IupSetCallback(dlg, "iup_XkeyAlt(K_LSHIFT)", (Icallback) k_any); + IupSetCallback(dlg, "GETFOCUS_CB", (Icallback) k_any); +#endif return dlg; } diff --git a/gui.h b/freerdp/client/X11/cli/gui.h similarity index 100% rename from gui.h rename to freerdp/client/X11/cli/gui.h diff --git a/images.c b/freerdp/client/X11/cli/images.c similarity index 93% rename from images.c rename to freerdp/client/X11/cli/images.c index 45b3b18..d919419 100644 --- a/images.c +++ b/freerdp/client/X11/cli/images.c @@ -1,5 +1,398 @@ #include "images.h" +const unsigned char empty_keyboard[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 37, 0, 0, 0, 116, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 116, 0, 0, 0, 36, + 0, 0, 0, 219, 0, 0, 0, 130, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 131, 0, 0, 0, 218, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, + 0, 0, 0, 218, 0, 0, 0, 131, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 131, 0, 0, 0, 218, + 0, 0, 0, 36, 0, 0, 0, 115, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +const unsigned char ru_keyboard[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 18, 30, 36, 83, 34, 43, 48, 201, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, + 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, + 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, + 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 30, 39, 45, 228, 34, 43, 48, 201, 18, 30, 36, 83, 0, 0, 0, 3, + 26, 33, 38, 107, 60, 67, 72, 244, 185, 188, 190, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, + 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, + 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, + 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 211, 213, 214, 255, 185, 188, 190, 255, 60, 67, 72, 244, 26, 33, 38, 107, + 33, 42, 47, 224, 208, 209, 211, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 208, 209, 211, 255, 33, 42, 47, 224, + 18, 27, 33, 255, 248, 248, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 248, 248, 248, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 248, 248, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 248, 248, 248, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 248, 248, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 248, 248, 248, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 248, 248, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 248, 248, 248, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, + 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, + 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, + 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 22, 31, 37, 253, 18, 27, 33, 255, + 18, 27, 33, 255, 16, 56, 144, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, + 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, + 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, + 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 56, 144, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 16, 58, 151, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 58, 151, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 16, 58, 151, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 58, 151, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 16, 58, 151, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 58, 151, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 16, 58, 151, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, + 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 59, 155, 255, 16, 58, 151, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 16, 56, 144, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, + 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, + 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 57, 147, 255, + 16, 57, 147, 255, 16, 58, 153, 255, 16, 59, 155, 255, 16, 58, 150, 255, 16, 57, 147, 255, 16, 57, 147, 255, 16, 56, 144, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, + 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, + 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, + 21, 27, 34, 253, 82, 31, 51, 227, 176, 38, 76, 194, 35, 28, 37, 247, 21, 27, 34, 253, 21, 27, 34, 253, 21, 27, 34, 253, 18, 27, 33, 255, + 18, 27, 33, 255, 230, 31, 51, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 230, 31, 51, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 230, 31, 51, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 230, 31, 51, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 230, 31, 51, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 230, 31, 51, 255, 18, 27, 33, 255, + 18, 27, 33, 255, 230, 31, 51, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 230, 31, 51, 255, 18, 27, 33, 255, + 31, 27, 34, 224, 193, 30, 48, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, + 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 237, 31, 52, 255, 193, 30, 48, 255, 31, 27, 34, 224, + 26, 26, 33, 107, 56, 28, 37, 244, 173, 30, 46, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, + 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, + 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, + 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 197, 30, 48, 255, 173, 30, 46, 255, 56, 28, 37, 244, 26, 26, 33, 107, + 0, 0, 0, 3, 18, 30, 36, 83, 34, 27, 34, 201, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, + 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, + 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, + 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 30, 27, 34, 228, 34, 27, 34, 201, 18, 30, 36, 83, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + +const unsigned char us_keyboard[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 37, 0, 0, 0, 116, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 116, 0, 0, 0, 36, + 13, 8, 15, 248, 31, 31, 70, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, + 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, 43, 45, 85, 255, + 5, 3, 4, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, + 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 122, 53, 59, 255, 110, 48, 53, 253, 12, 6, 6, 230, + 6, 4, 8, 254, 63, 63, 143, 255, 36, 38, 72, 255, 80, 85, 160, 255, 80, 85, 160, 255, 36, 38, 72, 255, 80, 85, 160, 255, 80, 85, 160, 255, + 36, 38, 72, 255, 80, 85, 160, 255, 80, 85, 160, 255, 36, 38, 72, 255, 80, 85, 160, 255, 80, 85, 160, 255, 36, 38, 72, 255, 80, 85, 160, 255, + 10, 6, 8, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, + 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 8, 3, 4, 247, + 6, 4, 8, 254, 63, 63, 143, 255, 74, 79, 148, 255, 57, 60, 114, 255, 60, 63, 119, 255, 74, 79, 148, 255, 57, 61, 114, 255, 59, 63, 118, 255, + 74, 79, 148, 255, 57, 61, 114, 255, 59, 63, 118, 255, 74, 79, 148, 255, 58, 62, 116, 255, 58, 62, 117, 255, 74, 79, 148, 255, 80, 85, 160, 255, + 7, 4, 6, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, + 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 176, 93, 100, 255, 183, 97, 105, 255, 92, 49, 53, 255, 3, 2, 2, 252, + 6, 4, 8, 254, 63, 63, 143, 255, 36, 39, 73, 255, 77, 81, 153, 255, 77, 82, 154, 255, 36, 39, 73, 255, 77, 82, 154, 255, 77, 82, 154, 255, + 36, 39, 73, 255, 77, 82, 154, 255, 77, 82, 154, 255, 36, 39, 73, 255, 77, 82, 154, 255, 77, 82, 154, 255, 36, 39, 73, 255, 80, 85, 160, 255, + 8, 7, 9, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, + 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 219, 219, 223, 255, 223, 223, 227, 255, 161, 161, 164, 255, 8, 7, 7, 253, + 6, 4, 8, 254, 63, 63, 143, 255, 74, 79, 148, 255, 57, 60, 114, 255, 60, 63, 119, 255, 74, 79, 148, 255, 57, 61, 115, 255, 59, 63, 118, 255, + 74, 79, 148, 255, 57, 61, 115, 255, 59, 63, 118, 255, 74, 79, 148, 255, 58, 62, 116, 255, 58, 62, 117, 255, 74, 79, 148, 255, 80, 85, 160, 255, + 10, 8, 11, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, + 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 12, 10, 10, 251, + 6, 4, 8, 254, 63, 63, 143, 255, 37, 39, 73, 255, 77, 81, 153, 255, 77, 82, 154, 255, 36, 39, 73, 255, 77, 81, 153, 255, 77, 82, 154, 255, + 37, 39, 73, 255, 77, 81, 153, 255, 77, 82, 154, 255, 36, 39, 73, 255, 77, 82, 154, 255, 77, 82, 154, 255, 36, 39, 73, 255, 80, 85, 160, 255, + 6, 5, 6, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, + 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 3, 2, 2, 254, + 6, 4, 8, 254, 63, 63, 143, 255, 74, 78, 147, 255, 57, 61, 114, 255, 60, 63, 119, 255, 74, 78, 147, 255, 57, 61, 115, 255, 59, 63, 119, 255, + 74, 78, 147, 255, 57, 61, 115, 255, 59, 63, 119, 255, 74, 78, 147, 255, 58, 62, 116, 255, 59, 62, 117, 255, 74, 78, 147, 255, 80, 85, 160, 255, + 8, 5, 7, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, + 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 6, 3, 3, 249, + 6, 4, 8, 254, 63, 63, 143, 255, 37, 39, 74, 255, 76, 81, 152, 255, 77, 82, 154, 255, 37, 39, 73, 255, 77, 81, 153, 255, 77, 82, 154, 255, + 37, 39, 74, 255, 77, 81, 153, 255, 77, 82, 154, 255, 37, 39, 73, 255, 77, 81, 153, 255, 77, 82, 154, 255, 37, 39, 73, 255, 80, 85, 160, 255, + 10, 6, 8, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, + 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 8, 3, 4, 247, + 6, 4, 8, 254, 63, 63, 143, 255, 73, 78, 147, 255, 57, 61, 114, 255, 60, 64, 120, 255, 73, 78, 146, 255, 57, 61, 115, 255, 59, 63, 119, 255, + 73, 78, 147, 255, 57, 61, 115, 255, 59, 63, 119, 255, 73, 78, 146, 255, 58, 62, 117, 255, 59, 62, 117, 255, 73, 78, 146, 255, 80, 85, 160, 255, + 6, 4, 6, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, + 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 1, 1, 1, 254, + 6, 4, 8, 254, 63, 63, 143, 255, 37, 40, 75, 255, 76, 81, 152, 255, 77, 82, 154, 255, 37, 39, 74, 255, 77, 81, 153, 255, 77, 82, 154, 255, + 37, 40, 75, 255, 77, 81, 153, 255, 77, 82, 154, 255, 37, 39, 74, 255, 77, 81, 153, 255, 77, 81, 153, 255, 37, 39, 74, 255, 80, 85, 160, 255, + 9, 9, 11, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, + 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 11, 9, 9, 252, + 5, 4, 8, 254, 59, 59, 133, 255, 69, 72, 136, 255, 75, 79, 149, 255, 75, 79, 149, 255, 69, 72, 136, 255, 75, 79, 149, 255, 75, 79, 149, 255, + 69, 72, 136, 255, 75, 79, 149, 255, 75, 79, 149, 255, 69, 72, 136, 255, 75, 79, 149, 255, 75, 79, 149, 255, 69, 72, 136, 255, 75, 79, 149, 255, + 9, 8, 11, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, + 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 226, 226, 230, 255, 11, 9, 9, 252, + 1, 1, 1, 255, 17, 9, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, + 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, 23, 13, 17, 255, + 27, 16, 19, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, + 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 31, 21, 22, 255, 1, 1, 1, 254, + 11, 4, 5, 251, 219, 71, 86, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, + 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, + 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, + 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 229, 100, 110, 255, 8, 3, 4, 247, + 9, 3, 4, 252, 175, 57, 69, 255, 199, 87, 96, 255, 229, 100, 110, 255, 197, 86, 94, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, + 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, + 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, + 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 183, 80, 88, 255, 6, 3, 3, 249, + 3, 3, 3, 255, 61, 58, 59, 255, 91, 76, 79, 255, 238, 201, 207, 255, 81, 69, 71, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, + 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, + 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, + 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 63, 54, 55, 255, 3, 2, 2, 254, + 14, 12, 13, 254, 226, 226, 231, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, + 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, + 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, + 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 242, 242, 246, 255, 12, 10, 10, 251, + 9, 8, 9, 254, 150, 150, 153, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, + 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, + 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, + 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 161, 161, 164, 255, 8, 7, 7, 253, + 4, 2, 2, 254, 89, 46, 51, 255, 91, 45, 49, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, + 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, + 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, + 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 92, 49, 53, 255, 3, 2, 2, 252, + 11, 4, 5, 251, 219, 70, 85, 255, 219, 70, 85, 255, 221, 78, 91, 255, 224, 85, 97, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, + 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, + 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, + 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 224, 86, 99, 255, 9, 4, 4, 249, + 19, 8, 9, 238, 107, 35, 42, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, + 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, + 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, + 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 117, 37, 45, 255, 107, 35, 42, 255, 19, 8, 9, 238, + 0, 0, 0, 36, 0, 0, 0, 115, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, + 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + const unsigned char idata_icon[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 191, 191, 4, 69, 144, 162, 88, 67, 143, 160, 189, 67, 142, 160, 234, 67, 142, 160, 226, 68, 142, 160, 122, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 146, 165, 40, 67, 143, 160, 196, 67, 142, 160, 254, 67, 142, 160, 255, 67, 142, 160, 255, 67, 142, 160, 255, 67, 142, 160, 253, 71, 142, 163, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 142, 163, 75, 67, 142, 160, 238, 67, 142, 160, 255, 67, 142, 160, 255, 67, 142, 160, 255, 67, 142, 160, 255, 67, 142, 160, 255, 67, 142, 160, 255, 70, 143, 162, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/images.h b/freerdp/client/X11/cli/images.h similarity index 63% rename from images.h rename to freerdp/client/X11/cli/images.h index 8b686c9..0285cbe 100644 --- a/images.h +++ b/freerdp/client/X11/cli/images.h @@ -8,6 +8,9 @@ #ifndef IMAGE_H_ #define IMAGE_H_ +extern const unsigned char empty_keyboard[]; +extern const unsigned char ru_keyboard[]; +extern const unsigned char us_keyboard[]; extern const unsigned char idata_head[]; extern const unsigned char idata_icon[]; diff --git a/freerdp/client/X11/cli/keylang.c b/freerdp/client/X11/cli/keylang.c new file mode 100644 index 0000000..9d4369c --- /dev/null +++ b/freerdp/client/X11/cli/keylang.c @@ -0,0 +1,53 @@ +/* + * keylang.c + * + * Created on: 17 февр. 2023 г. + * Author: alexander + */ + +#include "keylang.h" + +#include +#include +#include + +#include +#include + +/* + * 0 - unknown + * 1 - us + * 2 - ru + */ + +int getKeyboardLanguage() +{ + Display *dpy = XOpenDisplay(NULL); + + XkbStateRec state; + XkbGetState(dpy, XkbUseCoreKbd, &state); + + XkbRF_VarDefsRec vd; + XkbRF_GetNamesProp(dpy, NULL, &vd); + + int length = strlen(vd.layout) + 1; + char *current = (char *)malloc(sizeof(char) * length); + strncpy(current, vd.layout, length); + current[length] = '\0'; + + XCloseDisplay(dpy); + + char *lang = strtok(current, ","); + + for (int i = 0; i < state.group; i++) + lang = strtok(NULL, ","); + + int langcode = 0; + + if (!strcmp(lang, "us")) langcode = 1; + if (!strcmp(lang, "ru")) langcode = 2; + + free(current); + + return langcode; +} diff --git a/freerdp/client/X11/cli/keylang.h b/freerdp/client/X11/cli/keylang.h new file mode 100644 index 0000000..e37cf14 --- /dev/null +++ b/freerdp/client/X11/cli/keylang.h @@ -0,0 +1,13 @@ +/* + * keylang.h + * + * Created on: 17 февр. 2023 г. + * Author: alexander + */ + +#ifndef CLIENT_X11_CLI_KEYLANG_H_ +#define CLIENT_X11_CLI_KEYLANG_H_ + +int getKeyboardLanguage(); + +#endif /* CLIENT_X11_CLI_KEYLANG_H_ */ diff --git a/monitor.c b/freerdp/client/X11/cli/monitor.c similarity index 100% rename from monitor.c rename to freerdp/client/X11/cli/monitor.c diff --git a/monitor.h b/freerdp/client/X11/cli/monitor.h similarity index 100% rename from monitor.h rename to freerdp/client/X11/cli/monitor.h diff --git a/node_settings.c b/freerdp/client/X11/cli/node_settings.c similarity index 100% rename from node_settings.c rename to freerdp/client/X11/cli/node_settings.c diff --git a/node_settings.h b/freerdp/client/X11/cli/node_settings.h similarity index 100% rename from node_settings.h rename to freerdp/client/X11/cli/node_settings.h diff --git a/parameter.h b/freerdp/client/X11/cli/parameter.h similarity index 93% rename from parameter.h rename to freerdp/client/X11/cli/parameter.h index b78f3dc..203683f 100644 --- a/parameter.h +++ b/freerdp/client/X11/cli/parameter.h @@ -27,7 +27,8 @@ typedef enum PARAMETER_AUTHENTICATION, PARAMETER_SECURITY, PARAMETER_BITSPERPIXEL, - PARAMETER_USB + PARAMETER_USB, + PARAMETER_DECORATIONS } Parameter; #endif /* PARAMETERS_H_ */ diff --git a/rxrandr.c b/freerdp/client/X11/cli/rxrandr.c similarity index 100% rename from rxrandr.c rename to freerdp/client/X11/cli/rxrandr.c diff --git a/rxrandr.h b/freerdp/client/X11/cli/rxrandr.h similarity index 100% rename from rxrandr.h rename to freerdp/client/X11/cli/rxrandr.h diff --git a/rxrandr_broker.c b/freerdp/client/X11/cli/rxrandr_broker.c similarity index 100% rename from rxrandr_broker.c rename to freerdp/client/X11/cli/rxrandr_broker.c diff --git a/settings.c b/freerdp/client/X11/cli/settings.c similarity index 68% rename from settings.c rename to freerdp/client/X11/cli/settings.c index 2286f84..7cf7b24 100644 --- a/settings.c +++ b/freerdp/client/X11/cli/settings.c @@ -16,6 +16,7 @@ #include "settings.h" #include "arguments.h" #include "node_settings.h" +#include "about.h" void toggleActive(Ihandle *self, char *name) { @@ -63,6 +64,12 @@ static int settingsTglWallpaper(Ihandle *self) return IUP_DEFAULT; } +static int settingsTglDecorations(Ihandle *self) +{ + changeParameter(PARAMETER_DECORATIONS); + return IUP_DEFAULT; +} + static int settingsTglSound(Ihandle *self) { changeParameter(PARAMETER_SOUND); @@ -204,12 +211,13 @@ static int settingsTglFullscreen(Ihandle *self) */ static Ihandle* settingsBoxCheckbox() { - Ihandle *tglAuthentication, *tglCertIgnore, *tglThemes, *tglWallpaper, *tglSound, *tglFonts, *tglEncryption, *tglCompression; + Ihandle *tglAuthentication, *tglCertIgnore, *tglThemes, *tglWallpaper, *tglDecorations, *tglSound, *tglFonts, *tglEncryption, *tglCompression; tglAuthentication = IupToggle("Аутентификация", NULL); tglCertIgnore = IupToggle("Игнорировать сертификат", NULL); tglThemes = IupToggle("Отключить темы", NULL); tglWallpaper = IupToggle("Отключить обои", NULL); + tglDecorations = IupToggle("Отключить оформление окон", NULL); tglSound = IupToggle("Поддержка звука", NULL); tglFonts = IupToggle("Отключить прорисовку шрифтов", NULL); @@ -220,31 +228,30 @@ static Ihandle* settingsBoxCheckbox() IupSetInt(tglCertIgnore, "VALUE", getSetParameter(PARAMETER_CERTIGNORE)); IupSetInt(tglThemes, "VALUE", getSetParameter(PARAMETER_THEMES)); IupSetInt(tglWallpaper, "VALUE", getSetParameter(PARAMETER_WALLPAPER)); + IupSetInt(tglDecorations, "VALUE", getSetParameter(PARAMETER_DECORATIONS)); IupSetInt(tglSound, "VALUE", getSetParameter(PARAMETER_SOUND)); IupSetInt(tglFonts, "VALUE", getSetParameter(PARAMETER_FONTS)); IupSetInt(tglEncryption, "VALUE", getSetParameter(PARAMETER_ENCRYPTION)); IupSetInt(tglCompression, "VALUE", getSetParameter(PARAMETER_COMPRESSION)); return IupSetAttributes( - IupFrame( - IupVbox( - IupSetCallbacks(IupSetAttributes(tglAuthentication, "NAME=SETTINGS_TGL_AUTHENTICATION, TIP=\"Получить окно входа авторизации\""), "ACTION", - (Icallback) settingsTglAuthentication, NULL), - IupSetCallbacks(IupSetAttributes(tglCertIgnore, "NAME=SETTINGS_TGL_AUTHENTICATION, TIP=\"Игнорировать подтверждение принятия сертификата\""), "ACTION", - (Icallback) settingsTglCertIgnore, NULL), - IupSetCallbacks(IupSetAttributes(tglThemes, "NAME=SETTINGS_TGL_THEMES, TIP=\"Отключить поддержку тем оформления (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglThemes, - NULL), - IupSetCallbacks(IupSetAttributes(tglWallpaper, "NAME=SETTINGS_TGL_WALLPAPER, TIP=\"Отключить поддержку обои рабочего стола (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglWallpaper, - NULL), IupSetCallbacks(IupSetAttributes(tglSound, "NAME=SETTINGS_TGL_SOUND, TIP=\"Включить поддержку звука с удаленного сервера\""), "ACTION", (Icallback) settingsTglSound, - NULL), IupSetCallbacks(IupSetAttributes(tglFonts, "NAME=SETTINGS_TGL_FONTS, TIP=\"Отключить прорисовку шрифтов (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglFonts, - NULL), - IupSetCallbacks(IupSetAttributes(tglEncryption, "NAME=SETTINGS_TGL_ENCRYPTION, TIP=\"Отключить шифрование данных\""), "ACTION", - (Icallback) settingsTglEncryption, - NULL), - IupSetCallbacks(IupSetAttributes(tglCompression, "NAME=SETTINGS_TGL_COMPRESSION, TIP=\"Включить сжатие данных (улучшает скорость соединения)\""), "ACTION", - (Icallback) settingsTglCompression, - NULL), - NULL)), "TITLE=\"Общие\", MARGIN=10x10"); + IupFrame( + IupVbox( + IupSetCallbacks(IupSetAttributes(tglAuthentication, "NAME=SETTINGS_TGL_AUTHENTICATION, TIP=\"Получить окно входа авторизации\""), "ACTION", (Icallback) settingsTglAuthentication, NULL), + IupSetCallbacks(IupSetAttributes(tglCertIgnore, "NAME=SETTINGS_TGL_AUTHENTICATION, TIP=\"Игнорировать подтверждение принятия сертификата\""), "ACTION", (Icallback) settingsTglCertIgnore, NULL), + IupSetCallbacks(IupSetAttributes(tglThemes, "NAME=SETTINGS_TGL_THEMES, TIP=\"Отключить поддержку тем оформления (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglThemes, NULL), + IupSetCallbacks(IupSetAttributes(tglWallpaper, "NAME=SETTINGS_TGL_WALLPAPER, TIP=\"Отключить поддержку обоев рабочего стола (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglWallpaper, NULL), + IupSetCallbacks(IupSetAttributes(tglDecorations, "NAME=SETTINGS_TGL_DECORATIONS, TIP=\"Отключить поддержку оформления окон (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglDecorations, NULL), +#ifdef IUP_WITH_SOUND_CHECKBOX + IupSetCallbacks(IupSetAttributes(tglSound, "NAME=SETTINGS_TGL_SOUND, TIP=\"Включить поддержку звука с удаленного сервера\""), "ACTION", (Icallback) settingsTglSound, NULL), +#endif + IupSetCallbacks(IupSetAttributes(tglFonts, "NAME=SETTINGS_TGL_FONTS, TIP=\"Отключить прорисовку шрифтов (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglFonts, NULL), + IupSetCallbacks(IupSetAttributes(tglEncryption, "NAME=SETTINGS_TGL_ENCRYPTION, TIP=\"Отключить шифрование данных\""), "ACTION", (Icallback) settingsTglEncryption, NULL), + IupSetCallbacks(IupSetAttributes(tglCompression, "NAME=SETTINGS_TGL_COMPRESSION, TIP=\"Включить сжатие данных (улучшает скорость соединения)\""), "ACTION", (Icallback) settingsTglCompression, NULL), + NULL + ) + ), "TITLE=\"Общие\", MARGIN=10x10" + ); } static Ihandle* settingsBoxSecurity() @@ -341,21 +348,79 @@ static Ihandle* settingsBoxMonitor() IupSetInt(ddMonitor, "ACTIVE", getSetParameter(PARAMETER_FULLSCREEN) && !getSetParameter(PARAMETER_MULTIMONITOR)); return IupSetAttributes( - IupFrame( + IupFrame( + IupVbox( + IupSetAttributes( IupVbox( - IupSetCallbacks(IupSetAttributes(tglFullscreen, "NAME=SETTINGS_TGL_FULLSCREEN, EXPAND=YES, TIP=\"Выполнить подключение на весь экран\""), "ACTION", - (Icallback) settingsTglFullscreen, NULL), - IupSetCallbacks(IupSetAttributes(tglMultimonitor, "NAME=SETTINGS_TGL_MULTIMONITOR, TIP=\"Задействовать все подключенные мониторы\""), "ACTION", - (Icallback) settingsTglMultimonitor, NULL), - IupSetCallbacks(IupSetAttributes(ddMonitor, "NAME=MONITORS, DROPDOWN=YES, EXPAND=YES, TIP=\"Выбрать конкретный монитор для подключения\""), "ACTION", - (Icallback) settingsChooseMonitor, NULL), - NULL)), "TITLE=\"Монитор\", MARGIN=10x10, CGAP=5"); + IupSetCallbacks(IupSetAttributes(tglFullscreen, "NAME=SETTINGS_TGL_FULLSCREEN, EXPAND=YES, TIP=\"Выполнить подключение на весь экран\""), "ACTION", (Icallback) settingsTglFullscreen, NULL), + IupSetCallbacks(IupSetAttributes(tglMultimonitor, "NAME=SETTINGS_TGL_MULTIMONITOR, TIP=\"Задействовать все подключенные мониторы\""), "ACTION", (Icallback) settingsTglMultimonitor, NULL), + NULL + ), "MARGIN=0x0, GAP=0x0"), + IupSetCallbacks(IupSetAttributes(ddMonitor, "NAME=MONITORS, DROPDOWN=YES, EXPAND=YES, TIP=\"Выбрать конкретный монитор для подключения\""), "ACTION", (Icallback) settingsChooseMonitor, NULL), + NULL) + ), "TITLE=\"Монитор\", MARGIN=15x10, GAP=15x0"); +} + +static Ihandle* settingsBoxAbout() +{ + Ihandle *inputAbout, *formattag; + + inputAbout = IupText(NULL); + + formattag = IupUser(); + IupSetAttribute(formattag, "FONTSIZE", "8"); + IupSetAttribute(formattag, "ALIGNMENT", "CENTER"); + IupSetAttribute(formattag, "SELECTION", "1,1:7,50"); + IupSetAttribute(inputAbout, "ADDFORMATTAG_HANDLE", (char*)formattag); + + formattag = IupUser(); + IupSetAttribute(formattag, "WEIGHT", "BOLD"); + IupSetAttribute(formattag, "SELECTION", "1,1:1,20"); + IupSetAttribute(inputAbout, "ADDFORMATTAG_HANDLE", (char*)formattag); + + formattag = IupUser(); + IupSetAttribute(formattag, "FONTSIZE", "9"); + IupSetAttribute(formattag, "SELECTION", "1,1:1,20"); + IupSetAttribute(inputAbout, "ADDFORMATTAG_HANDLE", (char*)formattag); + + formattag = IupUser(); + IupSetAttribute(formattag, "FGCOLOR", "0 0 255"); + IupSetAttribute(formattag, "SELECTION", "5,1:5,100"); + IupSetAttribute(inputAbout, "ADDFORMATTAG_HANDLE", (char*)formattag); + + formattag = IupUser(); + IupSetAttribute(formattag, "WEIGHT", "BOLD"); + IupSetAttribute(formattag, "SELECTION", "6,20:6,100"); + IupSetAttribute(inputAbout, "ADDFORMATTAG_HANDLE", (char*)formattag); + + IupSetAttribute(inputAbout, "READONLY", "YES"); + IupSetAttribute(inputAbout, "MULTILINE", "YES"); + IupSetAttribute(inputAbout, "SIZE", "160"); + IupSetAttribute(inputAbout, "VISIBLELINES", "6"); + IupSetAttribute(inputAbout, "PADDING", "5"); + IupSetAttribute(inputAbout, "FORMATTING", "YES"); + IupSetAttribute(inputAbout, "EXPAND", "YES"); + IupSetAttribute(inputAbout, "VALUE", getAbout()); + + return IupSetAttributes(IupFrame(IupHbox(inputAbout, NULL)), "TITLE=\"О программе\", MARGIN=5x5"); } static Ihandle* settingsHorizontalBox() { return IupSetAttributes( - IupHbox(IupVbox(settingsBoxCheckbox(), settingsBoxMonitor(), NULL), settingsBoxSecurity(), settingsBoxBitsPerPixel(), NULL), "MARGIN=5x5"); + IupHbox( + IupSetAttributes( + IupVbox(settingsBoxCheckbox(), settingsBoxMonitor(), NULL), + "NMARGIN=0x0" + ), + IupSetAttributes( + IupVbox( + IupSetAttributes(IupHbox(settingsBoxSecurity(), settingsBoxBitsPerPixel(), NULL), "GAP=10x0"), + settingsBoxAbout(), + NULL), + "MARGIN=0x0"), + NULL), "NMARGIN=10x0, NGAP=10x0" + ); } /* @@ -368,14 +433,18 @@ static Ihandle* settingsHorizontalBoxButtons() btnSave = IupButton("Сохранить", NULL); IupSetAttribute(btnSave, "NAME", "SETTIGS_BTN_SAVE"); IupSetAttribute(btnSave, "TIP", "Сохранить настройки"); +#ifdef IUP_WITH_COLOR_BUTTONS IupSetAttribute(btnSave, "BGCOLOR", "0 179 0"); IupSetAttribute(btnSave, "FGCOLOR", "255 255 255"); +#endif btnClose = IupButton("Закрыть", NULL); IupSetAttribute(btnClose, "NAME", "SETTIGS_BTN_CLOSE"); IupSetAttribute(btnClose, "TIP", "Отменить изменения"); +#ifdef IUP_WITH_COLOR_BUTTONS IupSetAttribute(btnClose, "BGCOLOR", "204 0 0"); IupSetAttribute(btnClose, "FGCOLOR", "255 255 255"); +#endif IupSetHandle("btnClosePointer", btnClose); diff --git a/settings.h b/freerdp/client/X11/cli/settings.h similarity index 100% rename from settings.h rename to freerdp/client/X11/cli/settings.h diff --git a/value.h b/freerdp/client/X11/cli/value.h similarity index 100% rename from value.h rename to freerdp/client/X11/cli/value.h diff --git a/freerdp/client/X11/cli/xrdp.c b/freerdp/client/X11/cli/xrdp.c new file mode 100644 index 0000000..7e2ef1f --- /dev/null +++ b/freerdp/client/X11/cli/xrdp.c @@ -0,0 +1,71 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include + +#include "../xf_client.h" +#include "../xfreerdp.h" + +#include +#include +#include +#include + +#include "xrdp.h" + +int free_rdp_connect(int argc, char **argv) +{ + int rc = 1; + int status; + HANDLE thread; + xfContext *xfc; + DWORD dwExitCode; + rdpContext *context; + rdpSettings *settings; + RDP_CLIENT_ENTRY_POINTS clientEntryPoints; + + ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS)); + clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS); + clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION; + + RdpClientEntry(&clientEntryPoints); + + context = freerdp_client_context_new(&clientEntryPoints); + if (!context) + return 1; + + settings = context->settings; + xfc = (xfContext*) context; + + status = freerdp_client_settings_parse_command_line(context->settings, argc, argv, FALSE); + if (status) + { + rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); + + if (settings->ListMonitors) + xf_list_monitors(xfc); + + goto out; + } + + if (freerdp_client_start(context) != 0) + goto out; + + thread = freerdp_client_get_thread(context); + + WaitForSingleObject(thread, INFINITE); + GetExitCodeThread(thread, &dwExitCode); + rc = xf_exit_code_from_disconnect_reason(dwExitCode); + + freerdp_client_stop(context); + + out: freerdp_client_context_free(context); + + return rc; +} diff --git a/xrdp.h b/freerdp/client/X11/cli/xrdp.h similarity index 100% rename from xrdp.h rename to freerdp/client/X11/cli/xrdp.h diff --git a/freerdp/cmake/FindIUP.cmake b/freerdp/cmake/FindIUP.cmake new file mode 100644 index 0000000..aee8af9 --- /dev/null +++ b/freerdp/cmake/FindIUP.cmake @@ -0,0 +1,19 @@ +find_path(IUP_INCLUDE_DIR NAMES iup.h + PATHS /home/alexander/repositories/iup/include + DOC "The IUP include directory" +) + +find_library(IUP_LIBRARY NAMES iup + PATHS /home/alexander/repositories/iup + DOC "The IUP library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(IUP DEFAULT_MSG IUP_LIBRARY IUP_INCLUDE_DIR) + +if(IUP_FOUND) + set( IUP_LIBRARIES ${IUP_LIBRARY} ) + set( IUP_INCLUDE_DIRS ${IUP_INCLUDE_DIR} ) +endif() + +mark_as_advanced(IUP_INCLUDE_DIR IUP_LIBRARY) diff --git a/freerdp/cmake/FindSQLite.cmake b/freerdp/cmake/FindSQLite.cmake new file mode 100644 index 0000000..f0907a3 --- /dev/null +++ b/freerdp/cmake/FindSQLite.cmake @@ -0,0 +1,19 @@ +find_path(SQLITE_INCLUDE_DIR NAMES sqlite3.h + PATHS /usr/include + DOC "The SQLITE include directory" +) + +find_library(SQLITE_LIBRARY NAMES sqlite3 + PATHS /usr/lib64 + DOC "The SQLITE library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLite DEFAULT_MSG SQLITE_LIBRARY SQLITE_INCLUDE_DIR) + +if(SQLITE_FOUND) + set( SQLITE_LIBRARIES ${SQLITE_LIBRARY} ) + set( SQLITE_INCLUDE_DIRS ${SQLITE_INCLUDE_DIR} ) +endif() + +mark_as_advanced(SQLITE_INCLUDE_DIR SQLITE_LIBRARY) diff --git a/gui.patch b/gui.patch new file mode 100644 index 0000000..9eccada --- /dev/null +++ b/gui.patch @@ -0,0 +1,193 @@ +diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt +index 869652c..ab6fe67 100644 +--- a/client/X11/CMakeLists.txt ++++ b/client/X11/CMakeLists.txt +@@ -57,6 +57,39 @@ set(${MODULE_PREFIX}_SRCS + xf_client.c + xf_client.h) + ++set(${GUI_IUP}_SRCS ++ cli/xfreerdp.c ++ cli/images.c ++ xfreerdp.h ++ cli/xrdp.h ++ cli/arguments.c ++ cli/concat.c ++ cli/gui.c ++ cli/node_settings.c ++ cli/rxrandr_broker.c ++ cli/rxrandr.c ++ cli/settings.c ++ cli/db.c ++ cli/address.c ++ cli/monitor.c ++ cli/about.c ++ cli/keylang.c ++ cli/xrdp.c) ++ ++set(IUP_FEATURE_TYPE "REQUIRED") ++set(IUP_FEATURE_PURPOSE "IUP extension") ++set(IUP_FEATURE_DESCRIPTION "Multi-platform toolkit") ++ ++include_directories(${IUP_INCLUDE_DIRS}) ++find_feature(IUP ${IUP_FEATURE_TYPE} ${IUP_FEATURE_PURPOSE} ${IUP_FEATURE_DESCRIPTION}) ++ ++set(SQLITE_FEATURE_TYPE "REQUIRED") ++set(SQLITE_FEATURE_PURPOSE "SQLite extension") ++set(SQLITE_FEATURE_DESCRIPTION "C-language library SQL database engine") ++ ++include_directories(${SQLITE_INCLUDE_DIRS}) ++find_feature(SQLite ${SQLITE_FEATURE_TYPE} ${SQLITE_FEATURE_PURPOSE} ${SQLITE_FEATURE_DESCRIPTION}) ++ + if (CHANNEL_TSMF_CLIENT) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} + xf_tsmf.c +@@ -74,7 +107,7 @@ if(WITH_CLIENT_INTERFACE) + endif() + + else() +- set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/xfreerdp.c xfreerdp.h) ++ set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${GUI_IUP}_SRCS}) + add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp") + include_directories(..) +@@ -226,13 +259,33 @@ if(WITH_XFIXES) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XFIXES_LIBRARIES}) + endif() + ++if(IUP_WITH_COLOR_BUTTONS) ++ add_definitions(-DIUP_WITH_COLOR_BUTTONS) ++endif() ++ ++if(IUP_WITH_SOUND_CHECKBOX) ++ add_definitions(-DIUP_WITH_SOUND_CHECKBOX) ++endif() ++ ++if(IUP_DESCRIPTION_ABOUT_ARCH_X32) ++ add_definitions(-DIUP_DESCRIPTION_ABOUT_ARCH_X32) ++endif() ++ ++if(IUP_DESCRIPTION_ABOUT_MIRATORG) ++ add_definitions(-DIUP_DESCRIPTION_ABOUT_MIRATORG) ++endif() ++ ++if(IUP_WITH_LANGUAGE_KEYBOARD_ICON) ++ add_definitions(-DIUP_WITH_LANGUAGE_KEYBOARD_ICON) ++endif() ++ + include_directories(${CMAKE_SOURCE_DIR}/resources) + + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client freerdp m) + if (NOT APPLE) + list(APPEND ${MODULE_PREFIX}_LIBS rt) + endif() +-target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${${MODULE_PREFIX}_LIBS}) ++target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${${MODULE_PREFIX}_LIBS} ${IUP_LIBRARIES} ${SQLITE_LIBRARIES}) + + if(WITH_IPP) + target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${IPP_LIBRARY_LIST}) +diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c +index 8db4d39..abdf3ca 100644 +--- a/client/X11/cli/xfreerdp.c ++++ b/client/X11/cli/xfreerdp.c +@@ -1,85 +1,24 @@ +-/** +- * FreeRDP: A Remote Desktop Protocol Implementation +- * X11 Client +- * +- * Copyright 2011 Marc-Andre Moreau +- * Copyright 2012 HP Development Company, LLC +- * +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ ++#include ++#include "gui.h" ++#include "arguments.h" + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif ++#include + +-#include +-#include +-#include +- +-#include +-#include +- +-#include "../xf_client.h" +-#include "../xfreerdp.h" +- +-int main(int argc, char* argv[]) ++int main(int argc, char **argv) + { +- int rc = 1; +- int status; +- HANDLE thread; +- xfContext* xfc; +- DWORD dwExitCode; +- rdpContext* context; +- rdpSettings* settings; +- RDP_CLIENT_ENTRY_POINTS clientEntryPoints; +- +- ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS)); +- clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS); +- clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION; +- +- RdpClientEntry(&clientEntryPoints); +- +- context = freerdp_client_context_new(&clientEntryPoints); +- if (!context) +- return 1; +- +- settings = context->settings; +- xfc = (xfContext*)context; +- +- status = freerdp_client_settings_parse_command_line(context->settings, argc, argv, FALSE); +- if (status) +- { +- rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); +- +- if (settings->ListMonitors) +- xf_list_monitors(xfc); +- +- goto out; +- } +- +- if (freerdp_client_start(context) != 0) +- goto out; ++ if (argc > 1) ++ settingsLoad(argv[1]); ++ else ++ settingsLoad("/etc/freerdp/freerdp.db"); + +- thread = freerdp_client_get_thread(context); ++ IupOpen(&argc, &argv); + +- WaitForSingleObject(thread, INFINITE); +- GetExitCodeThread(thread, &dwExitCode); +- rc = xf_exit_code_from_disconnect_reason(dwExitCode); ++ IupShowXY(guiStart(), IUP_CENTER, IUP_CENTER); ++ IupMainLoop(); + +- freerdp_client_stop(context); ++ IupClose(); + +-out: +- freerdp_client_context_free(context); ++ settingsFree(); + +- return rc; ++ return EXIT_SUCCESS; + } diff --git a/img/main.png b/img/main.png index d1637e1..2e975ec 100644 Binary files a/img/main.png and b/img/main.png differ diff --git a/img/settings.png b/img/settings.png index 1b96d7a..74d0539 100644 Binary files a/img/settings.png and b/img/settings.png differ diff --git a/parameters.txt b/parameters.txt new file mode 100644 index 0000000..22b30ec --- /dev/null +++ b/parameters.txt @@ -0,0 +1,201 @@ +/flag (enables flag) +/option: (specifies option with value) ++toggle -toggle (enables or disables toggle, where '/' is a synonym of '+') + +/a:[,] Addin +/action-script: Action script +/admin Admin (or console) session ++aero Enable desktop composition +/app: or || Remote application program +/app-cmd: Remote application command-line parameters +/app-file: File to open with remote application +/app-guid: Remote application GUID +/app-icon: Remote application icon for user interface +/app-name: Remote application name for user interface +/app-workdir: Remote application workspace path +/assistance: Remote assistance password +/auto-request-control Automatically request remote assistance input control ++async-channels Enable Asynchronous channels (experimental) ++async-input Enable Asynchronous input ++async-update Enable Asynchronous update +/audio-mode: Audio output mode ++auth-only Enable Authenticate only +-authentication Disable Authentication (experimental) ++auto-reconnect Enable Automatic reconnection +/auto-reconnect-max-retries: + Automatic reconnection maximum retries, 0 for unlimited [0,1000] ++bitmap-cache Enable bitmap cache +/bpp: Session bpp (color depth) +/buildconfig Print the build configuration +/cert:[deny,ignore,name:,tofu,fingerprint:: + [,fingerprint::]] + Certificate accept options. Use with care! + * deny ... Automatically abort connection if the certificate does not match, no user interaction. + * ignore ... Ignore the certificate checks altogether (overrules all other options) + * name ... Use the alternate instead of the certificate subject to match locally stored certificates + * tofu ... Accept certificate unconditionally on first connect and deny on subsequent connections if the certificate does not match + * fingerprints ... A list of certificate hashes that are accepted unconditionally for a connection +/cert-deny [deprecated, use /cert:deny] Automatically abort connection for any certificate that can not be validated. +/cert-ignore [deprecated, use /cert:ignore] Ignore certificate +/cert-name: [deprecated, use /cert:name:] Certificate name +/cert-tofu [deprecated, use /cert:tofu] Automatically accept certificate on first connect +/client-build-number: Client Build Number sent to server (influences smartcard behaviour, see [MS-RDPESC]) +/client-hostname: Client Hostname to send to server +-clipboard[:[use-selection:]] + Disable Redirect clipboard. + * use-selection: ... (X11) Specify which X selection to access. Default is CLIPBOARD. PRIMARY is the X-style middle-click selection. +/codec-cache:[rfx|nsc|jpeg] Bitmap codec cache +-compression Disable compression +/compression-level: Compression level (0,1,2) ++credentials-delegation Enable credentials delegation +/d: Domain +-decorations Disable Window decorations +/disp Display control +/drive:, Redirect directory as named share . Hotplug support is enabled with /drive:hotplug,*. This argument provides the same function as "Drives that I plug in later" option in MSTSC. ++drives Enable Redirect all mount points as shares +/dvc:[,] Dynamic virtual channel +/dynamic-resolution Send resolution updates when the window is resized +/echo Echo channel +-encryption Disable Encryption (experimental) +/encryption-methods:[40,][56,][128,][FIPS] + RDP standard security encryption methods +/f Fullscreen mode (++ toggles fullscreen) +-fast-path Disable fast-path input/output ++fipsmode Enable FIPS mode +/floatbar[:sticky:[on|off],default:[visible|hidden],show: + [always|fullscreen||window]] + floatbar is disabled by default (when enabled defaults to sticky in fullscreen mode) +-fonts Disable smooth fonts (ClearType) +/frame-ack: Number of frame acknowledgement +/from-stdin[:force] Read credentials from stdin. With the prompt is done before connection, otherwise on server request. +/g:[:] Gateway Hostname +/gateway-usage-method:[direct|detect] + Gateway usage method +/gd: Gateway domain +/gdi:sw|hw GDI rendering +/geometry Geometry tracking channel ++gestures Enable Consume multitouch input locally +/gfx[:RFX] RDP8 graphics pipeline ++gfx-progressive Enable RDP8 graphics pipeline using progressive codec ++gfx-small-cache Enable RDP8 graphics pipeline using small cache mode ++gfx-thin-client Enable RDP8 graphics pipeline using thin client mode ++glyph-cache Enable Glyph cache (experimental) +/gp: Gateway password +-grab-keyboard Disable Grab keyboard +/gt:[rpc|http[,no-websockets]|auto[,no-websockets]] + Gateway transport type +/gu:[[\]|[@]] + Gateway username +/gat: Gateway Access Token +/h: Height +-heartbeat Disable Support heartbeat PDUs +/help Print help ++home-drive Enable Redirect user home as share +/ipv6 Prefer IPv6 AAA record over IPv4 A record +/kbd:0x or Keyboard layout +/kbd-lang:0x Keyboard active language identifier +/kbd-fn-key: Function key value +/kbd-list List keyboard layouts +/kbd-lang-list List keyboard languages +/kbd-remap:List of =,... pairs to remap scancodes + Keyboard scancode remapping +/kbd-subtype: Keyboard subtype +/kbd-type: Keyboard type +/load-balance-info: Load balance info +/log-filters::[,:[,...]] + Set logger filters, see wLog(7) for details +/log-level:[OFF|FATAL|ERROR|WARN|INFO|DEBUG|TRACE] + Set the default log level, see wLog(7) for details +/max-fast-path-size: Specify maximum fast-path update size +/max-loop-time: