Fix platform issues regarding charsets
* IMPORTANT: A new dependency is required, boost_locale, comes with boost 1.50.0 or later * Copying and pasting special characters should now work * Running otclient from filepaths with special characters should work now too
This commit is contained in:
parent
b52c52cd36
commit
fdcad184f9
|
@ -143,18 +143,18 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# gcc compile flags
|
# gcc compile flags
|
||||||
set(WARNS_FLAGS "-Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-unused-variable")
|
set(WARNS_FLAGS "-Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-result")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNS_FLAGS} ${ARCH_FLAGS} ${CPP2011_FLAGS} -pipe")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNS_FLAGS} ${ARCH_FLAGS} ${CPP2011_FLAGS} -pipe")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
|
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-omit-frame-pointer")
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-omit-frame-pointer")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||||
set(CMAKE_CXX_FLAGS_PERFORMANCE "-Ofast -mmmx -msse -msse2")
|
|
||||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
|
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
|
||||||
|
set(CMAKE_CXX_FLAGS_PERFORMANCE "-Ofast -mmmx -msse -msse2")
|
||||||
|
|
||||||
# process options
|
# process options
|
||||||
if(USE_STATIC_LIBS)
|
if(USE_STATIC_LIBS)
|
||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
set(CMAKE_CXX_LINK_FLAGS "-static-libgcc -static-libstdc++")
|
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -static-libgcc -static-libstdc++")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Link to static libraries: ON")
|
message(STATUS "Link to static libraries: ON")
|
||||||
else()
|
else()
|
||||||
|
@ -169,7 +169,7 @@ message(STATUS "Build revision: ${BUILD_REVISION}")
|
||||||
add_definitions(-D"BUILD_REVISION=\\\"${BUILD_REVISION}\\\"")
|
add_definitions(-D"BUILD_REVISION=\\\"${BUILD_REVISION}\\\"")
|
||||||
|
|
||||||
# find boost
|
# find boost
|
||||||
set(REQUIRED_BOOST_COMPONENTS system filesystem)
|
set(REQUIRED_BOOST_COMPONENTS system filesystem regex locale)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(Boost_THREADAPI win32)
|
set(Boost_THREADAPI win32)
|
||||||
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DBOOST_THREAD_USE_LIB) # fix boost thread linkage
|
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DBOOST_THREAD_USE_LIB) # fix boost thread linkage
|
||||||
|
@ -177,7 +177,7 @@ if(WIN32)
|
||||||
endif()
|
endif()
|
||||||
set(Boost_USE_MULTITHREADED ON)
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
set(Boost_USE_STATIC_LIBS ${USE_STATIC_LIBS})
|
set(Boost_USE_STATIC_LIBS ${USE_STATIC_LIBS})
|
||||||
find_package(Boost 1.46.0 COMPONENTS ${REQUIRED_BOOST_COMPONENTS} REQUIRED)
|
find_package(Boost 1.50.0 COMPONENTS ${REQUIRED_BOOST_COMPONENTS} REQUIRED)
|
||||||
|
|
||||||
#find lua
|
#find lua
|
||||||
if(LUAJIT)
|
if(LUAJIT)
|
||||||
|
@ -232,12 +232,15 @@ if(WIN32)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthreads")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthreads")
|
||||||
set(framework_DEFINITIONS ${framework_DEFINITIONS} -D_WIN32_WINNT=0x0501)
|
set(framework_DEFINITIONS ${framework_DEFINITIONS} -D_WIN32_WINNT=0x0501)
|
||||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--large-address-aware") # strip all debug information
|
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--large-address-aware") # strip all debug information
|
||||||
|
set(SYSTEM_LIBRARIES "")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
set(framework_DEFINITIONS ${framework_DEFINITIONS} -D_REENTRANT) # enable thread safe code
|
set(framework_DEFINITIONS ${framework_DEFINITIONS} -D_REENTRANT) # enable thread safe code
|
||||||
|
set(SYSTEM_LIBRARIES "")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -rdynamic") # rdynamic is needed by backtrace.h used in crash handler
|
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -rdynamic -Wl,-rpath,./libs") # rdynamic is needed by backtrace.h used in crash handler
|
||||||
set(framework_LIBRARIES ${framework_LIBRARIES} dl)
|
set(SYSTEM_LIBRARIES dl)
|
||||||
|
set(framework_LIBRARIES ${framework_LIBRARIES} ${SYSTEM_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FRAMEWORK_GRAPHICS)
|
if(FRAMEWORK_GRAPHICS)
|
||||||
|
@ -375,6 +378,10 @@ if(FRAMEWORK_GRAPHICS)
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.h
|
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp
|
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.h
|
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platform/win32platform.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platform/unixplatform.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platform/platform.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platform/platform.h
|
||||||
|
|
||||||
# window input
|
# window input
|
||||||
${CMAKE_CURRENT_LIST_DIR}/input/mouse.cpp
|
${CMAKE_CURRENT_LIST_DIR}/input/mouse.cpp
|
||||||
|
@ -430,8 +437,12 @@ endif()
|
||||||
|
|
||||||
if(FRAMEWORK_NET)
|
if(FRAMEWORK_NET)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(framework_LIBRARIES ${framework_LIBRARIES} ws2_32 mswsock)
|
set(NET_LIBRARIES ws2_32 mswsock)
|
||||||
|
else()
|
||||||
|
set(NET_LIBRARIES "")
|
||||||
endif()
|
endif()
|
||||||
|
set(framework_LIBRARIES ${framework_LIBRARIES} ${NET_LIBRARIES})
|
||||||
|
|
||||||
set(framework_SOURCES ${framework_SOURCES}
|
set(framework_SOURCES ${framework_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/net/connection.cpp
|
${CMAKE_CURRENT_LIST_DIR}/net/connection.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/net/connection.h
|
${CMAKE_CURRENT_LIST_DIR}/net/connection.h
|
||||||
|
|
|
@ -29,26 +29,24 @@
|
||||||
#include <framework/core/configmanager.h>
|
#include <framework/core/configmanager.h>
|
||||||
#include <framework/luaengine/luainterface.h>
|
#include <framework/luaengine/luainterface.h>
|
||||||
#include <framework/platform/crashhandler.h>
|
#include <framework/platform/crashhandler.h>
|
||||||
|
#include <framework/platform/platform.h>
|
||||||
|
|
||||||
|
#include <boost/locale.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
#ifdef FW_NET
|
#ifdef FW_NET
|
||||||
#include <framework/net/connection.h>
|
#include <framework/net/connection.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Ugly hack but works. */
|
|
||||||
#if defined __APPLE__ && defined CRASH_HANDLER
|
|
||||||
/* UNIX Crash handler for some reason did not go as expected on a Mac system
|
|
||||||
* TODO: RTFM it.
|
|
||||||
*/
|
|
||||||
#undef CRASH_HANDLER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void exitSignalHandler(int sig)
|
void exitSignalHandler(int sig)
|
||||||
{
|
{
|
||||||
static bool signaled = false;
|
static bool signaled = false;
|
||||||
switch(sig) {
|
switch(sig) {
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
if(!signaled) {
|
if(!signaled && !g_app.isStopping() && !g_app.isTerminated()) {
|
||||||
signaled = true;
|
signaled = true;
|
||||||
g_dispatcher.addEvent(std::bind(&Application::close, &g_app));
|
g_dispatcher.addEvent(std::bind(&Application::close, &g_app));
|
||||||
}
|
}
|
||||||
|
@ -65,7 +63,7 @@ Application::Application()
|
||||||
m_stopping = false;
|
m_stopping = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::init(const std::vector<std::string>& args)
|
void Application::init(std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
// capture exit signals
|
// capture exit signals
|
||||||
signal(SIGTERM, exitSignalHandler);
|
signal(SIGTERM, exitSignalHandler);
|
||||||
|
@ -75,6 +73,15 @@ void Application::init(const std::vector<std::string>& args)
|
||||||
installCrashHandler();
|
installCrashHandler();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// setup locale
|
||||||
|
boost::locale::generator locgen;
|
||||||
|
std::locale::global(locgen.generate(""));
|
||||||
|
std::locale utf8Loc = locgen.generate("en_US.UTF-8");
|
||||||
|
boost::filesystem::path::imbue(utf8Loc);
|
||||||
|
|
||||||
|
// process args encoding
|
||||||
|
g_platform.processArgs(args);
|
||||||
|
|
||||||
std::string startupOptions;
|
std::string startupOptions;
|
||||||
for(uint i=1;i<args.size();++i) {
|
for(uint i=1;i<args.size();++i) {
|
||||||
const std::string& arg = args[i];
|
const std::string& arg = args[i];
|
||||||
|
@ -129,6 +136,9 @@ void Application::terminate()
|
||||||
g_lua.terminate();
|
g_lua.terminate();
|
||||||
|
|
||||||
m_terminated = true;
|
m_terminated = true;
|
||||||
|
|
||||||
|
signal(SIGTERM, SIG_DFL);
|
||||||
|
signal(SIGINT, SIG_DFL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::poll()
|
void Application::poll()
|
||||||
|
@ -142,8 +152,8 @@ void Application::poll()
|
||||||
|
|
||||||
void Application::exit()
|
void Application::exit()
|
||||||
{
|
{
|
||||||
g_logger.info("Exiting application..");
|
|
||||||
m_stopping = true;
|
m_stopping = true;
|
||||||
|
g_logger.info("Exiting application..");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::close()
|
void Application::close()
|
||||||
|
@ -158,8 +168,10 @@ std::string Application::getOs()
|
||||||
return "windows";
|
return "windows";
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
return "mac";
|
return "mac";
|
||||||
#else
|
#elif __linux
|
||||||
return "linux";
|
return "linux";
|
||||||
|
#else
|
||||||
|
return "unknown";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
Application();
|
Application();
|
||||||
virtual ~Application() {}
|
virtual ~Application() {}
|
||||||
|
|
||||||
virtual void init(const std::vector<std::string>& args);
|
virtual void init(std::vector<std::string>& args);
|
||||||
virtual void deinit();
|
virtual void deinit();
|
||||||
virtual void terminate();
|
virtual void terminate();
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <framework/ui/uimanager.h>
|
#include <framework/ui/uimanager.h>
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
#include <framework/graphics/particlemanager.h>
|
#include <framework/graphics/particlemanager.h>
|
||||||
|
#include <framework/graphics/texturemanager.h>
|
||||||
#include <framework/graphics/painter.h>
|
#include <framework/graphics/painter.h>
|
||||||
|
|
||||||
#ifdef FW_SOUND
|
#ifdef FW_SOUND
|
||||||
|
@ -36,7 +37,7 @@
|
||||||
|
|
||||||
GraphicalApplication g_app;
|
GraphicalApplication g_app;
|
||||||
|
|
||||||
void GraphicalApplication::init(const std::vector<std::string>& args)
|
void GraphicalApplication::init(std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
Application::init(args);
|
Application::init(args);
|
||||||
|
|
||||||
|
@ -78,14 +79,14 @@ void GraphicalApplication::terminate()
|
||||||
// destroy any remaining widget
|
// destroy any remaining widget
|
||||||
g_ui.terminate();
|
g_ui.terminate();
|
||||||
|
|
||||||
|
Application::terminate();
|
||||||
|
m_terminated = false;
|
||||||
|
|
||||||
#ifdef FW_SOUND
|
#ifdef FW_SOUND
|
||||||
// terminate sound
|
// terminate sound
|
||||||
g_sounds.terminate();
|
g_sounds.terminate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Application::terminate();
|
|
||||||
m_terminated = false;
|
|
||||||
|
|
||||||
// terminate graphics
|
// terminate graphics
|
||||||
m_foreground = nullptr;
|
m_foreground = nullptr;
|
||||||
g_graphics.terminate();
|
g_graphics.terminate();
|
||||||
|
@ -106,16 +107,21 @@ void GraphicalApplication::run()
|
||||||
poll();
|
poll();
|
||||||
g_clock.update();
|
g_clock.update();
|
||||||
|
|
||||||
g_lua.callGlobalField("g_app", "onRun");
|
// show window
|
||||||
|
|
||||||
g_window.show();
|
g_window.show();
|
||||||
|
|
||||||
|
// run the second poll
|
||||||
|
poll();
|
||||||
|
g_clock.update();
|
||||||
|
|
||||||
|
g_lua.callGlobalField("g_app", "onRun");
|
||||||
|
|
||||||
while(!m_stopping) {
|
while(!m_stopping) {
|
||||||
// poll all events before rendering
|
// poll all events before rendering
|
||||||
poll();
|
poll();
|
||||||
|
|
||||||
if(g_window.isVisible()) {
|
if(g_window.isVisible()) {
|
||||||
// the otclient's screen consists of two panes
|
// the screen consists of two panes
|
||||||
// background pane - high updated and animated pane (where the game are stuff happens)
|
// background pane - high updated and animated pane (where the game are stuff happens)
|
||||||
// foreground pane - steady pane with few animated stuff (UI)
|
// foreground pane - steady pane with few animated stuff (UI)
|
||||||
bool redraw = false;
|
bool redraw = false;
|
||||||
|
|
|
@ -35,7 +35,7 @@ class GraphicalApplication : public Application
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init(const std::vector< std::string >& args);
|
void init(std::vector<std::string>& args);
|
||||||
void deinit();
|
void deinit();
|
||||||
void terminate();
|
void terminate();
|
||||||
void run();
|
void run();
|
||||||
|
|
|
@ -23,8 +23,12 @@
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "eventdispatcher.h"
|
#include "eventdispatcher.h"
|
||||||
|
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
#include <framework/core/resourcemanager.h>
|
||||||
|
|
||||||
#ifdef FW_GRAPHICS
|
#ifdef FW_GRAPHICS
|
||||||
#include <framework/platform/platformwindow.h>
|
#include <framework/platform/platformwindow.h>
|
||||||
|
#include <framework/luaengine/luainterface.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Logger g_logger;
|
Logger g_logger;
|
||||||
|
@ -43,6 +47,21 @@ void Logger::log(Fw::LogLevel level, const std::string& message)
|
||||||
const static std::string logPrefixes[] = { "", "", "WARNING: ", "ERROR: ", "FATAL ERROR: " };
|
const static std::string logPrefixes[] = { "", "", "WARNING: ", "ERROR: ", "FATAL ERROR: " };
|
||||||
|
|
||||||
std::string outmsg = logPrefixes[level] + message;
|
std::string outmsg = logPrefixes[level] + message;
|
||||||
|
|
||||||
|
#if !defined(NDEBUG) && !defined(WIN32)
|
||||||
|
// replace paths for improved debug with vim
|
||||||
|
std::stringstream tmp;
|
||||||
|
boost::smatch m;
|
||||||
|
boost::regex e ("/[^ :]+");
|
||||||
|
while(boost::regex_search(outmsg,m,e)) {
|
||||||
|
tmp << m.prefix().str();
|
||||||
|
tmp << g_resources.getRealDir(m.str()) << m.str();
|
||||||
|
outmsg = m.suffix().str();
|
||||||
|
}
|
||||||
|
if(!tmp.str().empty())
|
||||||
|
outmsg = tmp.str();
|
||||||
|
#endif
|
||||||
|
|
||||||
std::cout << outmsg << std::endl;
|
std::cout << outmsg << std::endl;
|
||||||
|
|
||||||
if(m_outFile.good()) {
|
if(m_outFile.good()) {
|
||||||
|
@ -74,16 +93,21 @@ void Logger::log(Fw::LogLevel level, const std::string& message)
|
||||||
|
|
||||||
void Logger::logFunc(Fw::LogLevel level, const std::string& message, std::string prettyFunction)
|
void Logger::logFunc(Fw::LogLevel level, const std::string& message, std::string prettyFunction)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
|
||||||
prettyFunction = prettyFunction.substr(0, prettyFunction.find_first_of('('));
|
prettyFunction = prettyFunction.substr(0, prettyFunction.find_first_of('('));
|
||||||
if(prettyFunction.find_last_of(' ') != std::string::npos)
|
if(prettyFunction.find_last_of(' ') != std::string::npos)
|
||||||
prettyFunction = prettyFunction.substr(prettyFunction.find_last_of(' ') + 1);
|
prettyFunction = prettyFunction.substr(prettyFunction.find_last_of(' ') + 1);
|
||||||
|
|
||||||
if(!prettyFunction.empty())
|
|
||||||
ss << "[" << prettyFunction << "] ";
|
|
||||||
|
|
||||||
ss << message;
|
std::string out = message;
|
||||||
log(level, ss.str());
|
|
||||||
|
if(!prettyFunction.empty()) {
|
||||||
|
if(g_lua.isInCppCallback())
|
||||||
|
out = g_lua.traceback(out, 1);
|
||||||
|
else
|
||||||
|
out += "\nat:\t[C++]: " + prettyFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(level, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::fireOldMessages()
|
void Logger::fireOldMessages()
|
||||||
|
|
|
@ -35,7 +35,7 @@ void LuaException::generateLuaErrorMessage(const std::string& error, int traceLe
|
||||||
if(traceLevel >= 0)
|
if(traceLevel >= 0)
|
||||||
m_what = stdext::format("LUA ERROR: %s", g_lua.traceback(error, traceLevel));
|
m_what = stdext::format("LUA ERROR: %s", g_lua.traceback(error, traceLevel));
|
||||||
else
|
else
|
||||||
m_what = stdext::format("LUA ERROR: %s", error);
|
m_what = stdext::format("LUA ERROR:\n%s", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaBadNumberOfArgumentsException::LuaBadNumberOfArgumentsException(int expected, int got)
|
LuaBadNumberOfArgumentsException::LuaBadNumberOfArgumentsException(int expected, int got)
|
||||||
|
|
|
@ -23,9 +23,8 @@
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
#include "win32window.h"
|
#include "win32window.h"
|
||||||
|
#include <framework/graphics/image.h>
|
||||||
#include <framework/core/application.h>
|
#include <framework/core/application.h>
|
||||||
#include <framework/graphics/apngloader.h>
|
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
|
|
||||||
#define HSB_BIT_SET(p, n) (p[(n)/8] |= (128 >>((n)%8)))
|
#define HSB_BIT_SET(p, n) (p[(n)/8] |= (128 >>((n)%8)))
|
||||||
|
@ -767,37 +766,33 @@ void WIN32Window::hideMouse()
|
||||||
|
|
||||||
void WIN32Window::displayFatalError(const std::string& message)
|
void WIN32Window::displayFatalError(const std::string& message)
|
||||||
{
|
{
|
||||||
MessageBoxA(m_window, message.c_str(), "FATAL ERROR", MB_OK | MB_ICONERROR);
|
MessageBoxW(m_window, stdext::latin1_to_utf16(message).c_str(), L"FATAL ERROR", MB_OK | MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
void WIN32Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
{
|
{
|
||||||
std::stringstream fin;
|
ImagePtr image = Image::load(file);
|
||||||
g_resources.loadFile(file, fin);
|
|
||||||
|
|
||||||
apng_data apng;
|
if(!image) {
|
||||||
if(load_apng(fin, &apng) != 0) {
|
g_logger.traceError(stdext::format("unable to load cursor image file %s", file));
|
||||||
g_logger.traceError(stdext::format("unable to load png file %s", file));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(apng.bpp != 4) {
|
if(image->getBpp() != 4) {
|
||||||
g_logger.error("the cursor png must have 4 channels");
|
g_logger.error("the cursor image must have 4 channels");
|
||||||
free_apng(&apng);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(apng.width != 32|| apng.height != 32) {
|
if(image->getWidth() != 32 || image->getHeight() != 32) {
|
||||||
g_logger.error("the cursor png must have 32x32 dimension");
|
g_logger.error("the cursor image must have 32x32 dimension");
|
||||||
free_apng(&apng);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_cursor != NULL)
|
if(m_cursor != NULL)
|
||||||
DestroyCursor(m_cursor);
|
DestroyCursor(m_cursor);
|
||||||
|
|
||||||
int width = apng.width;
|
int width = image->getWidth();
|
||||||
int height = apng.height;
|
int height = image->getHeight();
|
||||||
int numbits = width * height;
|
int numbits = width * height;
|
||||||
int numbytes = (width * height)/8;
|
int numbytes = (width * height)/8;
|
||||||
|
|
||||||
|
@ -805,14 +800,13 @@ void WIN32Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
std::vector<uchar> xorMask(numbytes, 0);
|
std::vector<uchar> xorMask(numbytes, 0);
|
||||||
|
|
||||||
for(int i=0;i<numbits;++i) {
|
for(int i=0;i<numbits;++i) {
|
||||||
uint32 rgba = stdext::readLE32(apng.pdata + i*4);
|
uint32 rgba = stdext::readLE32(image->getPixelData() + i*4);
|
||||||
if(rgba == 0xffffffff) { //white
|
if(rgba == 0xffffffff) { //white
|
||||||
HSB_BIT_SET(xorMask, i);
|
HSB_BIT_SET(xorMask, i);
|
||||||
} else if(rgba == 0x00000000) { //alpha
|
} else if(rgba == 0x00000000) { //alpha
|
||||||
HSB_BIT_SET(andMask, i);
|
HSB_BIT_SET(andMask, i);
|
||||||
} // otherwise 0xff000000 => black
|
} // otherwise 0xff000000 => black
|
||||||
}
|
}
|
||||||
free_apng(&apng);
|
|
||||||
|
|
||||||
m_cursor = CreateCursor(m_instance, hotSpot.x, hotSpot.y, width, height, &andMask[0], &xorMask[0]);
|
m_cursor = CreateCursor(m_instance, hotSpot.x, hotSpot.y, width, height, &andMask[0], &xorMask[0]);
|
||||||
SetCursor(m_cursor);
|
SetCursor(m_cursor);
|
||||||
|
@ -820,7 +814,7 @@ void WIN32Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
|
|
||||||
void WIN32Window::setTitle(const std::string& title)
|
void WIN32Window::setTitle(const std::string& title)
|
||||||
{
|
{
|
||||||
SetWindowTextA(m_window, title.c_str());
|
SetWindowTextW(m_window, stdext::latin1_to_utf16(title).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::setMinimumSize(const Size& minimumSize)
|
void WIN32Window::setMinimumSize(const Size& minimumSize)
|
||||||
|
@ -868,29 +862,32 @@ void WIN32Window::setVerticalSync(bool enable)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::setIcon(const std::string& pngIcon)
|
void WIN32Window::setIcon(const std::string& file)
|
||||||
{
|
{
|
||||||
apng_data apng;
|
ImagePtr image = Image::load(file);
|
||||||
std::stringstream fin;
|
|
||||||
g_resources.loadFile(pngIcon, fin);
|
if(!image) {
|
||||||
if(load_apng(fin, &apng) == 0) {
|
g_logger.traceError(stdext::format("unable to load icon file %s", file));
|
||||||
if(apng.bpp != 4) {
|
return;
|
||||||
g_logger.error("could not set app icon, icon image must have 4 channels");
|
|
||||||
free_apng(&apng);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = apng.width * apng.height;
|
if(image->getBpp() != 4) {
|
||||||
|
g_logger.error("the app icon must have 4 channels");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = image->getWidth() * image->getHeight();
|
||||||
std::vector<uint32> iconData(n);
|
std::vector<uint32> iconData(n);
|
||||||
for(int i=0; i < n;++i) {
|
for(int i=0; i < n;++i) {
|
||||||
uint8 *pixel = (uint8*)&iconData[i];
|
uint8 *pixel = (uint8*)&iconData[i];
|
||||||
pixel[2] = *(apng.pdata + (i * 4) + 0);
|
pixel[2] = *(image->getPixelData() + (i * 4) + 0);
|
||||||
pixel[1] = *(apng.pdata + (i * 4) + 1);
|
pixel[1] = *(image->getPixelData() + (i * 4) + 1);
|
||||||
pixel[0] = *(apng.pdata + (i * 4) + 2);
|
pixel[0] = *(image->getPixelData() + (i * 4) + 2);
|
||||||
pixel[3] = *(apng.pdata + (i * 4) + 3);
|
pixel[3] = *(image->getPixelData() + (i * 4) + 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP hbmColor = CreateBitmap(apng.width, apng.height, 1, 32, &iconData[0]);
|
HBITMAP hbmColor = CreateBitmap(image->getWidth(), image->getHeight(), 1, 32, &iconData[0]);
|
||||||
HBITMAP hbmMask = CreateCompatibleBitmap(GetDC(NULL), apng.width, apng.height);
|
HBITMAP hbmMask = CreateCompatibleBitmap(GetDC(NULL), image->getWidth(), image->getHeight());
|
||||||
|
|
||||||
ICONINFO ii;
|
ICONINFO ii;
|
||||||
ii.fIcon = TRUE;
|
ii.fIcon = TRUE;
|
||||||
|
@ -905,10 +902,6 @@ void WIN32Window::setIcon(const std::string& pngIcon)
|
||||||
|
|
||||||
SendMessage(m_window, WM_SETICON, ICON_SMALL, (LPARAM)icon);
|
SendMessage(m_window, WM_SETICON, ICON_SMALL, (LPARAM)icon);
|
||||||
SendMessage(m_window, WM_SETICON, ICON_BIG, (LPARAM)icon);
|
SendMessage(m_window, WM_SETICON, ICON_BIG, (LPARAM)icon);
|
||||||
|
|
||||||
free_apng(&apng);
|
|
||||||
} else
|
|
||||||
g_logger.error("could not load app icon");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::setClipboardText(const std::string& text)
|
void WIN32Window::setClipboardText(const std::string& text)
|
||||||
|
@ -916,17 +909,19 @@ void WIN32Window::setClipboardText(const std::string& text)
|
||||||
if(!OpenClipboard(m_window))
|
if(!OpenClipboard(m_window))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
HGLOBAL hglb = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(TCHAR));
|
HGLOBAL hglb = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(WCHAR));
|
||||||
if(!hglb)
|
if(!hglb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LPTSTR lptstr = (LPTSTR)GlobalLock(hglb);
|
std::wstring wtext = stdext::latin1_to_utf16(text);
|
||||||
memcpy(lptstr, &text[0], text.length() * sizeof(TCHAR));
|
|
||||||
lptstr[text.length()] = (TCHAR)0;
|
LPWSTR lpwstr = (LPWSTR)GlobalLock(hglb);
|
||||||
|
memcpy(lpwstr, (char*)&wtext[0], wtext.length() * sizeof(WCHAR));
|
||||||
|
lpwstr[text.length()] = (WCHAR)0;
|
||||||
GlobalUnlock(hglb);
|
GlobalUnlock(hglb);
|
||||||
|
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
SetClipboardData(CF_TEXT, hglb);
|
SetClipboardData(CF_UNICODETEXT, hglb);
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,11 +937,11 @@ std::string WIN32Window::getClipboardText()
|
||||||
if(!OpenClipboard(m_window))
|
if(!OpenClipboard(m_window))
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
HGLOBAL hglb = GetClipboardData(CF_TEXT);
|
HGLOBAL hglb = GetClipboardData(CF_UNICODETEXT);
|
||||||
if(hglb) {
|
if(hglb) {
|
||||||
LPTSTR lptstr = (LPTSTR)GlobalLock(hglb);
|
LPWSTR lpwstr = (LPWSTR)GlobalLock(hglb);
|
||||||
if(lptstr) {
|
if(lpwstr) {
|
||||||
text = stdext::utf8_to_latin1(lptstr);
|
text = stdext::utf16_to_latin1(lpwstr);
|
||||||
GlobalUnlock(hglb);
|
GlobalUnlock(hglb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -954,16 +949,16 @@ std::string WIN32Window::getClipboardText()
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string WIN32Window::getPlatformType()
|
std::string WIN32Window::getPlatformType()
|
||||||
{
|
{
|
||||||
#ifdef OPENGL_ES
|
#ifndef OPENGL_ES
|
||||||
return "WIN32-WGL";
|
return "WIN32-WGL";
|
||||||
#else
|
#else
|
||||||
return "WIN32-EGL";
|
return "WIN32-EGL";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rect WIN32Window::getClientRect()
|
Rect WIN32Window::getClientRect()
|
||||||
{
|
{
|
||||||
if(m_window) {
|
if(m_window) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
void setMinimumSize(const Size& minimumSize);
|
void setMinimumSize(const Size& minimumSize);
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
void setVerticalSync(bool enable);
|
void setVerticalSync(bool enable);
|
||||||
void setIcon(const std::string& iconFile);
|
void setIcon(const std::string& file);
|
||||||
void setClipboardText(const std::string& text);
|
void setClipboardText(const std::string& text);
|
||||||
|
|
||||||
Size getDisplaySize();
|
Size getDisplaySize();
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined __linux || defined __APPLE__
|
#ifdef __linux
|
||||||
|
|
||||||
#include "x11window.h"
|
#include "x11window.h"
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <framework/graphics/apngloader.h>
|
#include <framework/graphics/image.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8)))
|
#define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8)))
|
||||||
|
|
||||||
|
@ -320,13 +321,6 @@ void X11Window::internalCreateWindow()
|
||||||
|
|
||||||
bool X11Window::internalSetupWindowInput()
|
bool X11Window::internalSetupWindowInput()
|
||||||
{
|
{
|
||||||
// try to set a latin1 locales, otherwise fallback to standard C locale
|
|
||||||
static char locales[4][32] = { "en_US.iso88591", "iso88591", "en_US", "C" };
|
|
||||||
for(int i=0;i<4;++i) {
|
|
||||||
if(setlocale(LC_ALL, locales[i]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create input context (to have better key input handling)
|
// create input context (to have better key input handling)
|
||||||
if(!XSupportsLocale()) {
|
if(!XSupportsLocale()) {
|
||||||
g_logger.error("X11 doesn't support the current locale");
|
g_logger.error("X11 doesn't support the current locale");
|
||||||
|
@ -515,8 +509,10 @@ bool X11Window::isExtensionSupported(const char *ext)
|
||||||
void X11Window::move(const Point& pos)
|
void X11Window::move(const Point& pos)
|
||||||
{
|
{
|
||||||
m_position = pos;
|
m_position = pos;
|
||||||
if(m_visible)
|
if(m_visible) {
|
||||||
XMoveWindow(m_display, m_window, m_position.x, m_position.y);
|
XMoveWindow(m_display, m_window, m_position.x, m_position.y);
|
||||||
|
XFlush(m_display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::resize(const Size& size)
|
void X11Window::resize(const Size& size)
|
||||||
|
@ -524,6 +520,7 @@ void X11Window::resize(const Size& size)
|
||||||
if(size.width() < m_minimumSize.width() || size.height() < m_minimumSize.height())
|
if(size.width() < m_minimumSize.width() || size.height() < m_minimumSize.height())
|
||||||
return;
|
return;
|
||||||
XResizeWindow(m_display, m_window, size.width(), size.height());
|
XResizeWindow(m_display, m_window, size.width(), size.height());
|
||||||
|
XFlush(m_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::show()
|
void X11Window::show()
|
||||||
|
@ -678,6 +675,7 @@ void X11Window::poll()
|
||||||
Atom typeList[] = { XInternAtom(m_display, "UTF8_STRING", False),
|
Atom typeList[] = { XInternAtom(m_display, "UTF8_STRING", False),
|
||||||
XInternAtom(m_display, "TEXT", False),
|
XInternAtom(m_display, "TEXT", False),
|
||||||
XInternAtom(m_display, "STRING", False),
|
XInternAtom(m_display, "STRING", False),
|
||||||
|
XInternAtom(m_display, "text/plain;charset=UTF-8", False),
|
||||||
XInternAtom(m_display, "text/plain", False),
|
XInternAtom(m_display, "text/plain", False),
|
||||||
XInternAtom(m_display, "COMPOUND_TEXT", False),
|
XInternAtom(m_display, "COMPOUND_TEXT", False),
|
||||||
XA_STRING };
|
XA_STRING };
|
||||||
|
@ -689,13 +687,14 @@ void X11Window::poll()
|
||||||
sizeof(typeList));
|
sizeof(typeList));
|
||||||
respond.xselection.property = req->property;
|
respond.xselection.property = req->property;
|
||||||
} else {
|
} else {
|
||||||
|
std::string clipboardText = stdext::latin1_to_utf8(m_clipboardText);
|
||||||
XChangeProperty(m_display,
|
XChangeProperty(m_display,
|
||||||
req->requestor,
|
req->requestor,
|
||||||
req->property, req->target,
|
req->property, req->target,
|
||||||
8,
|
8,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
(uchar *)m_clipboardText.c_str(),
|
(uchar *)clipboardText.c_str(),
|
||||||
m_clipboardText.length());
|
clipboardText.length());
|
||||||
respond.xselection.property = req->property;
|
respond.xselection.property = req->property;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,14 +765,16 @@ void X11Window::poll()
|
||||||
m_inputEvent.type = Fw::MouseWheelInputEvent;
|
m_inputEvent.type = Fw::MouseWheelInputEvent;
|
||||||
m_inputEvent.mouseButton = Fw::MouseMidButton;
|
m_inputEvent.mouseButton = Fw::MouseMidButton;
|
||||||
m_inputEvent.wheelDirection = Fw::MouseWheelUp;
|
m_inputEvent.wheelDirection = Fw::MouseWheelUp;
|
||||||
}
|
} else
|
||||||
|
m_inputEvent.type = Fw::NoInputEvent;
|
||||||
break;
|
break;
|
||||||
case Button5:
|
case Button5:
|
||||||
if(event.type == ButtonPress) {
|
if(event.type == ButtonPress) {
|
||||||
m_inputEvent.type = Fw::MouseWheelInputEvent;
|
m_inputEvent.type = Fw::MouseWheelInputEvent;
|
||||||
m_inputEvent.mouseButton = Fw::MouseMidButton;
|
m_inputEvent.mouseButton = Fw::MouseMidButton;
|
||||||
m_inputEvent.wheelDirection = Fw::MouseWheelDown;
|
m_inputEvent.wheelDirection = Fw::MouseWheelDown;
|
||||||
}
|
} else
|
||||||
|
m_inputEvent.type = Fw::NoInputEvent;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_inputEvent.type = Fw::NoInputEvent;
|
m_inputEvent.type = Fw::NoInputEvent;
|
||||||
|
@ -862,32 +863,28 @@ void X11Window::restoreMouseCursor()
|
||||||
|
|
||||||
void X11Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
void X11Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
{
|
{
|
||||||
std::stringstream fin;
|
ImagePtr image = Image::load(file);
|
||||||
g_resources.loadFile(file, fin);
|
|
||||||
|
|
||||||
apng_data apng;
|
if(!image) {
|
||||||
if(load_apng(fin, &apng) != 0) {
|
g_logger.traceError(stdext::format("unable to load image file %s", file));
|
||||||
g_logger.traceError(stdext::format("unable to load png file %s", file));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(apng.bpp != 4) {
|
if(image->getBpp() != 4) {
|
||||||
g_logger.error("the cursor png must have 4 channels");
|
g_logger.error("the cursor image must have 4 channels");
|
||||||
free_apng(&apng);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(apng.width != 32|| apng.height != 32) {
|
if(image->getWidth() != 32 || image->getHeight() != 32) {
|
||||||
g_logger.error("the cursor png must have 32x32 dimension");
|
g_logger.error("the cursor image must have 32x32 dimension");
|
||||||
free_apng(&apng);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_cursor != None)
|
if(m_cursor != None)
|
||||||
restoreMouseCursor();
|
restoreMouseCursor();
|
||||||
|
|
||||||
int width = apng.width;
|
int width = image->getWidth();
|
||||||
int height = apng.height;
|
int height = image->getHeight();
|
||||||
int numbits = width * height;
|
int numbits = width * height;
|
||||||
int numbytes = (width * height)/8;
|
int numbytes = (width * height)/8;
|
||||||
|
|
||||||
|
@ -903,7 +900,7 @@ void X11Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
std::vector<uchar> maskBits(numbytes, 0);
|
std::vector<uchar> maskBits(numbytes, 0);
|
||||||
|
|
||||||
for(int i=0;i<numbits;++i) {
|
for(int i=0;i<numbits;++i) {
|
||||||
uint32 rgba = stdext::readLE32(apng.pdata + i*4);
|
uint32 rgba = stdext::readLE32(image->getPixelData() + i*4);
|
||||||
if(rgba == 0xffffffff) { //white, background
|
if(rgba == 0xffffffff) { //white, background
|
||||||
LSB_BIT_SET(maskBits, i);
|
LSB_BIT_SET(maskBits, i);
|
||||||
} else if(rgba == 0xff000000) { //black, foreground
|
} else if(rgba == 0xff000000) { //black, foreground
|
||||||
|
@ -911,7 +908,6 @@ void X11Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
LSB_BIT_SET(maskBits, i);
|
LSB_BIT_SET(maskBits, i);
|
||||||
} //otherwise 0x00000000 => alpha
|
} //otherwise 0x00000000 => alpha
|
||||||
}
|
}
|
||||||
free_apng(&apng);
|
|
||||||
|
|
||||||
Pixmap cp = XCreateBitmapFromData(m_display, m_window, (char*)&mapBits[0], width, height);
|
Pixmap cp = XCreateBitmapFromData(m_display, m_window, (char*)&mapBits[0], width, height);
|
||||||
Pixmap mp = XCreateBitmapFromData(m_display, m_window, (char*)&maskBits[0], width, height);
|
Pixmap mp = XCreateBitmapFromData(m_display, m_window, (char*)&maskBits[0], width, height);
|
||||||
|
@ -978,40 +974,35 @@ void X11Window::setVerticalSync(bool enable)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::setIcon(const std::string& iconFile)
|
void X11Window::setIcon(const std::string& file)
|
||||||
{
|
{
|
||||||
std::stringstream fin;
|
ImagePtr image = Image::load(file);
|
||||||
g_resources.loadFile(iconFile, fin);
|
|
||||||
|
|
||||||
apng_data apng;
|
if(!image) {
|
||||||
if(load_apng(fin, &apng) != 0) {
|
g_logger.traceError(stdext::format("unable to load icon file %s", file));
|
||||||
g_logger.error("Unable to load window icon");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(apng.bpp != 4) {
|
if(image->getBpp() != 4) {
|
||||||
g_logger.error("Could not set window icon, icon image must have 4 channels");
|
g_logger.error("the app icon must have 4 channels");
|
||||||
free_apng(&apng);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = apng.width * apng.height;
|
int n = image->getWidth() * image->getHeight();
|
||||||
std::vector<unsigned long int> iconData(n + 2);
|
std::vector<unsigned long int> iconData(n + 2);
|
||||||
iconData[0] = apng.width;
|
iconData[0] = image->getWidth();
|
||||||
iconData[1] = apng.height;
|
iconData[1] = image->getHeight();
|
||||||
for(int i=0; i < n;++i) {
|
for(int i=0; i < n;++i) {
|
||||||
uint8 *pixel = (uint8*)&iconData[2 + i];
|
uint8 *pixel = (uint8*)&iconData[2 + i];
|
||||||
pixel[2] = *(apng.pdata + (i * 4) + 0);
|
pixel[2] = *(image->getPixelData() + (i * 4) + 0);
|
||||||
pixel[1] = *(apng.pdata + (i * 4) + 1);
|
pixel[1] = *(image->getPixelData() + (i * 4) + 1);
|
||||||
pixel[0] = *(apng.pdata + (i * 4) + 2);
|
pixel[0] = *(image->getPixelData() + (i * 4) + 2);
|
||||||
pixel[3] = *(apng.pdata + (i * 4) + 3);
|
pixel[3] = *(image->getPixelData() + (i * 4) + 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Atom property = XInternAtom(m_display, "_NET_WM_ICON", 0);
|
Atom property = XInternAtom(m_display, "_NET_WM_ICON", 0);
|
||||||
if(!XChangeProperty(m_display, m_window, property, XA_CARDINAL, 32, PropModeReplace, (const unsigned char*)&iconData[0], iconData.size()))
|
if(!XChangeProperty(m_display, m_window, property, XA_CARDINAL, 32, PropModeReplace, (const unsigned char*)&iconData[0], iconData.size()))
|
||||||
g_logger.error("Couldn't set app icon");
|
g_logger.error("Couldn't set app icon");
|
||||||
|
|
||||||
free_apng(&apng);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::setClipboardText(const std::string& text)
|
void X11Window::setClipboardText(const std::string& text)
|
||||||
|
@ -1047,16 +1038,19 @@ std::string X11Window::getClipboardText()
|
||||||
Atom type;
|
Atom type;
|
||||||
int format;
|
int format;
|
||||||
ulong len, bytesLeft;
|
ulong len, bytesLeft;
|
||||||
uchar *data;
|
char *data;
|
||||||
XGetWindowProperty(m_display, ownerWindow,
|
XGetWindowProperty(m_display, ownerWindow,
|
||||||
XA_PRIMARY, 0, 10000000L, 0, XA_STRING,
|
XA_PRIMARY, 0, 10000000L, 0, XA_STRING,
|
||||||
&type,
|
&type,
|
||||||
&format,
|
&format,
|
||||||
&len,
|
&len,
|
||||||
&bytesLeft,
|
&bytesLeft,
|
||||||
&data);
|
(uchar**)&data);
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
clipboardText = stdext::utf8_to_latin1((char*)data);
|
if(stdext::is_valid_utf8(data))
|
||||||
|
clipboardText = stdext::utf8_to_latin1(data);
|
||||||
|
else
|
||||||
|
clipboardText = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,15 +72,13 @@ public:
|
||||||
void setMinimumSize(const Size& minimumSize);
|
void setMinimumSize(const Size& minimumSize);
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
void setVerticalSync(bool enable);
|
void setVerticalSync(bool enable);
|
||||||
void setIcon(const std::string& iconFile);
|
void setIcon(const std::string& file);
|
||||||
void setClipboardText(const std::string& text);
|
void setClipboardText(const std::string& text);
|
||||||
|
|
||||||
Size getDisplaySize();
|
Size getDisplaySize();
|
||||||
std::string getClipboardText();
|
std::string getClipboardText();
|
||||||
std::string getPlatformType();
|
std::string getPlatformType();
|
||||||
|
|
||||||
bool isMaximized();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Display *m_display;
|
Display *m_display;
|
||||||
XVisualInfo *m_visual;
|
XVisualInfo *m_visual;
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <physfs.h>
|
||||||
|
#include <boost/locale.hpp>
|
||||||
|
|
||||||
namespace stdext {
|
namespace stdext {
|
||||||
|
|
||||||
|
@ -67,36 +69,44 @@ uint64_t hex_to_dec(const std::string& str)
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_valid_utf8(const std::string& src)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
boost::locale::conv::from_utf(src, "ISO-8859-1", boost::locale::conv::stop);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string utf8_to_latin1(const std::string& src)
|
std::string utf8_to_latin1(const std::string& src)
|
||||||
{
|
{
|
||||||
auto utf8CharToLatin1 = [](const uchar *utf8, int *read) -> char {
|
return boost::locale::conv::from_utf(src, "ISO-8859-1");
|
||||||
char c = '?';
|
|
||||||
uchar opt1 = utf8[0];
|
|
||||||
*read = 1;
|
|
||||||
if(opt1 == 0xc3) {
|
|
||||||
*read = 2;
|
|
||||||
uchar opt2 = utf8[1];
|
|
||||||
c = 64 + opt2;
|
|
||||||
} else if(opt1 == 0xc2) {
|
|
||||||
*read = 2;
|
|
||||||
uchar opt2 = utf8[1];
|
|
||||||
if(opt2 > 0xa1 && opt2 < 0xbb)
|
|
||||||
c = opt2;
|
|
||||||
} else if(opt1 < 0xc2) {
|
|
||||||
c = opt1;
|
|
||||||
}
|
}
|
||||||
return c;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string out;
|
std::wstring utf8_to_utf16(const std::string& src)
|
||||||
int len = src.length();
|
{
|
||||||
for(int i=0; i<len;) {
|
return boost::locale::conv::utf_to_utf<wchar_t>(src);
|
||||||
int read = 0;
|
|
||||||
uchar *utf8char = (uchar*)&src[i];
|
|
||||||
out += utf8CharToLatin1(utf8char, &read);
|
|
||||||
i += read;
|
|
||||||
}
|
}
|
||||||
return out;
|
|
||||||
|
std::string utf16_to_utf8(const std::wstring& src)
|
||||||
|
{
|
||||||
|
return boost::locale::conv::utf_to_utf<char>(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string utf16_to_latin1(const std::wstring& src)
|
||||||
|
{
|
||||||
|
return boost::locale::conv::from_utf(src, "ISO-8859-1");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string latin1_to_utf8(const std::string& src)
|
||||||
|
{
|
||||||
|
return boost::locale::conv::to_utf<char>(src, "ISO-8859-1");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring latin1_to_utf16(const std::string& src)
|
||||||
|
{
|
||||||
|
return boost::locale::conv::to_utf<wchar_t>(src, "ISO-8859-1");
|
||||||
}
|
}
|
||||||
|
|
||||||
void tolower(std::string& str)
|
void tolower(std::string& str)
|
||||||
|
|
|
@ -42,7 +42,6 @@ std::string date_time_string();
|
||||||
|
|
||||||
std::string dec_to_hex(uint64_t num);
|
std::string dec_to_hex(uint64_t num);
|
||||||
uint64_t hex_to_dec(const std::string& str);
|
uint64_t hex_to_dec(const std::string& str);
|
||||||
std::string utf8_to_latin1(const std::string& src);
|
|
||||||
void tolower(std::string& str);
|
void tolower(std::string& str);
|
||||||
void toupper(std::string& str);
|
void toupper(std::string& str);
|
||||||
void trim(std::string& str);
|
void trim(std::string& str);
|
||||||
|
@ -53,6 +52,14 @@ bool ends_with(const std::string& str, const std::string& test);
|
||||||
bool starts_with(const std::string& str, const std::string& test);
|
bool starts_with(const std::string& str, const std::string& test);
|
||||||
void replace_all(std::string& str, const std::string& search, const std::string& replacement);
|
void replace_all(std::string& str, const std::string& search, const std::string& replacement);
|
||||||
|
|
||||||
|
bool is_valid_utf8(const std::string& src);
|
||||||
|
std::string utf8_to_latin1(const std::string& src);
|
||||||
|
std::wstring utf8_to_utf16(const std::string& src);
|
||||||
|
std::string utf16_to_utf8(const std::wstring& src);
|
||||||
|
std::string utf16_to_latin1(const std::wstring& src);
|
||||||
|
std::string latin1_to_utf8(const std::string& src);
|
||||||
|
std::wstring latin1_to_utf16(const std::string& src);
|
||||||
|
|
||||||
std::vector<std::string> split(const std::string& str, const std::string& separators = " ");
|
std::vector<std::string> split(const std::string& str, const std::string& separators = " ");
|
||||||
template<typename T> std::vector<T> split(const std::string& str, const std::string& separators = " ") {
|
template<typename T> std::vector<T> split(const std::string& str, const std::string& separators = " ") {
|
||||||
std::vector<std::string> splitted = split(str, separators);
|
std::vector<std::string> splitted = split(str, separators);
|
||||||
|
|
Loading…
Reference in New Issue