Initial work on Skia backend (WIP)

This commit is contained in:
David Capello 2015-03-16 15:05:13 -03:00
parent a67c7bb1b2
commit 0350ac4bbe
31 changed files with 1602 additions and 185 deletions

View File

@ -1,5 +1,5 @@
# Aseprite
# Copyright (C) 2001-2014 David Capello
# Copyright (C) 2001-2015 David Capello
#
# Parts of this file come from the Allegro 4.4 CMakeLists.txt
@ -44,6 +44,8 @@ option(USE_SHARED_TINYXML "Use your installed copy of tinyxml" off)
option(USE_SHARED_GTEST "Use your installed copy of gtest" off)
option(USE_SHARED_PIXMAN "Use your installed copy of pixman" off)
option(USE_SHARED_ALLEGRO4 "Use shared Allegro 4 library (without resize support)" off)
option(USE_ALLEG4_BACKEND "Use Allegro 4 backend" on)
option(USE_SKIA_BACKEND "Use Skia backend" off)
option(ENABLE_MEMLEAK "Enable memory-leaks detector (only for developers)" off)
option(ENABLE_UPDATER "Enable automatic check for updates" on)
option(ENABLE_WEBSERVER "Enable support to run a webserver (for HTML5 gamedev)" off)
@ -58,8 +60,7 @@ list(APPEND CMAKE_BUILD_TYPES Profile)
mark_as_advanced(
CMAKE_C_FLAGS_PROFILE
CMAKE_CXX_FLAGS_PROFILE
CMAKE_EXE_LINKER_FLAGS_PROFILE
)
CMAKE_EXE_LINKER_FLAGS_PROFILE)
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS_PROFILE "-pg"
@ -112,12 +113,6 @@ set(SIMPLEINI_DIR ${CMAKE_SOURCE_DIR}/third_party/simpleini)
set(TINYXML_DIR ${CMAKE_SOURCE_DIR}/third_party/tinyxml)
set(ZLIB_DIR ${CMAKE_SOURCE_DIR}/third_party/zlib)
# Allegro header files
if(NOT USE_SHARED_ALLEGRO4)
include_directories(${CMAKE_SOURCE_DIR}/src/allegro/include)
include_directories(${CMAKE_BINARY_DIR}/include)
endif()
# Zlib generated zconf.h file
include_directories(${CMAKE_BINARY_DIR}/third_party/zlib)
@ -138,9 +133,6 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
# Do not use MMX optimizations in PNG code
add_definitions(-DPNG_NO_MMX_CODE)
# Static Allegro (the code of Allegro library is embedded).
add_definitions(-DALLEGRO_STATICLINK)
# Debug C/C++ flags
if(CMAKE_BUILD_TYPE STREQUAL Debug)
add_definitions(-DDEBUGMODE -D_DEBUG)
@ -148,10 +140,6 @@ else()
add_definitions(-DNDEBUG)
endif()
if(ENABLE_MEMLEAK)
add_definitions(-DMEMLEAK)
endif()
# Fix to compile gtest with VC11 (2012)
if(NOT USE_SHARED_GTEST)
if (MSVC_VERSION EQUAL 1700)
@ -159,6 +147,38 @@ if(NOT USE_SHARED_GTEST)
endif()
endif()
######################################################################
# Allegro 4 backend
if(USE_ALLEG4_BACKEND)
if(USE_SHARED_ALLEGRO4)
# Find the shared Allegro 4 library
find_library(LIBALLEGRO4_LIBRARY alleg)
find_path(LIBALLEGRO4_INCLUDE_DIR allegro.h)
if(NOT LIBALLEGRO4_LIBRARY)
message(FATAL_ERROR "Allegro 4 not found")
endif()
# Get flags to link programs using allegro-config program
execute_process(COMMAND allegro-config --libs --shared
OUTPUT_VARIABLE LIBALLEGRO4_LINK_FLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LIBALLEGRO4_LINK_FLAGS ${LIBALLEGRO4_LINK_FLAGS} ${PLATFORM_LIBS})
include_directories(${LIBALLEGRO4_INCLUDE_DIR})
else()
include_directories(${CMAKE_SOURCE_DIR}/src/allegro/include)
include_directories(${CMAKE_BINARY_DIR}/include)
add_definitions(-DALLEGRO4_WITH_RESIZE_PATCH)
add_definitions(-DALLEGRO4_WITH_EXTRA_CURSORS)
# Static Allegro (the code of Allegro library is embedded).
add_definitions(-DALLEGRO_STATICLINK)
endif()
endif()
######################################################################
# Platform specific stuff
@ -212,38 +232,26 @@ endif()
# -- Windows --
if(WIN32)
find_package(DXGuid)
if(USE_ALLEG4_BACKEND)
find_package(DXGuid)
if(NOT DXGUID_FOUND)
if(MSVC)
message(FATAL_ERROR
"DirectX required for Windows port. You might need to add DirectX include and lib directories to your INCLUDE and LIB environment variables.")
elseif(MINGW)
message(FATAL_ERROR
"DirectX required for Windows port. Get it from the Allegro web site (dx80_mgw.zip).")
else()
message(FATAL_ERROR "DirectX required for Windows port.")
if(NOT DXGUID_FOUND)
if(MSVC)
message(FATAL_ERROR "DirectX required for Windows port. You might need to add DirectX include and lib directories to your INCLUDE and LIB environment variables.")
else()
message(FATAL_ERROR "DirectX required for Windows port.")
endif()
endif()
include_directories(SYSTEM ${DXGUID_INCLUDE_DIR})
else()
set(DXGUID_LIBRARIES)
endif()
include_directories(SYSTEM
${DXGUID_INCLUDE_DIR}
)
list(APPEND PLATFORM_LIBS
kernel32
user32
gdi32
comdlg32
ole32
${DXGUID_LIBRARIES}
winmm
shlwapi
psapi
wininet
comctl32
dbghelp
)
kernel32 user32 gdi32 comdlg32 ole32 winmm
shlwapi psapi wininet comctl32 dbghelp
${DXGUID_LIBRARIES})
# Windows XP is the minimum supported platform.
add_definitions(-D_WIN32_WINNT=0x0501 -DWINVER=0x0501)
@ -274,8 +282,7 @@ if(APPLE)
${COREAUDIO_LIBRARY}
${AUDIOUNIT_LIBRARY}
${AUDIOTOOLBOX_LIBRARY}
${QUICKTIME_LIBRARY}
)
${QUICKTIME_LIBRARY})
# Hack to deal with Mac OS X 10.6. NSQuickDrawView is not defined by
# NSQuickDrawView.h when compiling in 64-bit mode, and 64-bit mode is the

View File

@ -1,8 +1,15 @@
# Aseprite
# Copyright (C) 2001-2015 David Capello
######################################################################
# Common definitions for all Aseprite libraries/projects
add_definitions(-DHAVE_CONFIG_H)
if(ENABLE_MEMLEAK)
add_definitions(-DMEMLEAK)
endif()
######################################################################
# Compiler-specific flags
@ -42,32 +49,20 @@ set(aseprite_libraries
# Directories where .h files can be found
include_directories(. .. ../third_party)
# Third-party libraries
if(USE_SHARED_ALLEGRO4)
# Find the shared Allegro 4 library
find_library(LIBALLEGRO4_LIBRARY alleg)
find_path(LIBALLEGRO4_INCLUDE_DIR allegro.h)
######################################################################
# Allegro 4 backend
if(NOT LIBALLEGRO4_LIBRARY)
message(FATAL_ERROR "Allegro 4 not found")
if(USE_ALLEG4_BACKEND)
if(NOT USE_SHARED_ALLEGRO4)
# Use patched version of Allegro 4 (with window resize support).
add_subdirectory(allegro)
set(libs3rdparty ${libs3rdparty} allegro)
endif()
# Get flags to link programs using allegro-config program
execute_process(COMMAND allegro-config --libs --shared
OUTPUT_VARIABLE LIBALLEGRO4_LINK_FLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LIBALLEGRO4_LINK_FLAGS ${LIBALLEGRO4_LINK_FLAGS} ${PLATFORM_LIBS})
include_directories(${LIBALLEGRO4_INCLUDE_DIR})
else()
add_definitions(-DALLEGRO4_WITH_RESIZE_PATCH)
add_definitions(-DALLEGRO4_WITH_EXTRA_CURSORS)
# Use patched version of Allegro 4 (with window resize support).
add_subdirectory(allegro)
set(libs3rdparty ${libs3rdparty} allegro)
endif()
######################################################################
# Other third party libraries
if(USE_SHARED_JPEGLIB)
find_package(JPEG)
if(JPEG_FOUND)
@ -123,15 +118,17 @@ else()
include_directories(${TINYXML_DIR})
endif()
if(USE_SHARED_LIBLOADPNG)
find_library(LIBLOADPNG_LIBRARY NAMES loadpng)
find_path(LIBLOADPNG_INCLUDE_DIR NAMES loadpng.h)
if(USE_ALLEG4_BACKEND)
if(USE_SHARED_LIBLOADPNG)
find_library(LIBLOADPNG_LIBRARY NAMES loadpng)
find_path(LIBLOADPNG_INCLUDE_DIR NAMES loadpng.h)
set(libs3rdparty ${libs3rdparty} ${LIBLOADPNG_LIBRARY})
include_directories(${LIBLOADPNG_INCLUDE_DIR})
else()
set(libs3rdparty loadpng ${libs3rdparty})
include_directories(${LOADPNG_DIR})
set(libs3rdparty ${libs3rdparty} ${LIBLOADPNG_LIBRARY})
include_directories(${LIBLOADPNG_INCLUDE_DIR})
else()
set(libs3rdparty loadpng ${libs3rdparty})
include_directories(${LOADPNG_DIR})
endif()
endif()
if(USE_SHARED_PIXMAN)
@ -206,6 +203,7 @@ endif()
add_subdirectory(base)
include_directories(${BASE_INCLUDE_DIR})
list(APPEND libs3rdparty ${BASE_EXTRA_LIBRARIES})
add_subdirectory(cfg)
add_subdirectory(css)
@ -232,13 +230,18 @@ endif()
add_subdirectory(app)
if(V8_FOUND)
list(APPEND libs3rdparty ${V8_LIBRARIES})
list(APPEND libs3rdparty ${V8_LIBRARIES})
endif()
if(USE_SKIA_BACKEND)
list(APPEND sys_libs ${PLATFORM_LIBS})
list(APPEND libs3rdparty ${SKIA_LIBRARIES})
endif()
# All libraries for .exe files
set(all_libs ${aseprite_libraries} ${libs3rdparty} ${sys_libs})
if(LIBALLEGRO4_LINK_FLAGS)
if(USE_ALLEG4_BACKEND AND LIBALLEGRO4_LINK_FLAGS)
set(all_libs ${all_libs} ${LIBALLEGRO4_LINK_FLAGS})
endif()
@ -262,11 +265,11 @@ add_custom_target(copy_data DEPENDS ${out_data_files})
if(WIN32)
set(win32_resources main/resources_win32.rc)
endif(WIN32)
endif()
if(UNIX)
if(UNIX AND NOT APPLE AND USE_ALLEG4_BACKEND)
set(x11_resources main/xpm_icon.c)
endif(UNIX)
endif()
add_executable(aseprite WIN32
main/main.cpp
@ -311,7 +314,7 @@ function(find_tests dir dependencies)
endif()
target_link_libraries(${testname} gtest ${ARGV})
if(LIBALLEGRO4_LINK_FLAGS)
if(USE_ALLEG4_BACKEND AND LIBALLEGRO4_LINK_FLAGS)
target_link_libraries(${testname} ${LIBALLEGRO4_LINK_FLAGS})
endif()

View File

@ -305,7 +305,7 @@ static void reload_default_font()
skin_theme->reload_fonts();
// Set all widgets fonts
setFontOfAllWidgets(theme->default_font);
setFontOfAllWidgets(theme->getDefaultFont());
}
void load_window_pos(Widget* window, const char *section)

View File

@ -146,7 +146,8 @@ SkinTheme::SkinTheme()
{
this->name = "Skin Theme";
m_selected_skin = get_config_string("Skin", "Selected", "default");
m_minifont = she::instance()->defaultFont();
m_defaultFont = nullptr;
m_miniFont = nullptr;
// Initialize all graphics in NULL (these bitmaps are loaded from the skin)
m_sheet = NULL;
@ -309,8 +310,8 @@ SkinTheme::~SkinTheme()
sheet_mapping.clear();
// Destroy the minifont
if (m_minifont)
m_minifont->dispose();
if (m_miniFont)
m_miniFont->dispose();
}
// Call Theme::regenerate() after this.
@ -339,14 +340,11 @@ void SkinTheme::reload_skin()
void SkinTheme::reload_fonts()
{
if (default_font)
default_font->dispose();
if (m_defaultFont) m_defaultFont->dispose();
if (m_miniFont) m_miniFont->dispose();
if (m_minifont)
m_minifont->dispose();
default_font = loadFont("UserFont", "skins/" + m_selected_skin + "/font.png");
m_minifont = loadFont("UserMiniFont", "skins/" + m_selected_skin + "/minifont.png");
m_defaultFont = loadFont("UserFont", "skins/" + m_selected_skin + "/font.png");
m_miniFont = loadFont("UserMiniFont", "skins/" + m_selected_skin + "/minifont.png");
}
gfx::Size SkinTheme::get_part_size(int part_i) const

View File

@ -47,7 +47,8 @@ namespace app {
SkinTheme();
~SkinTheme();
she::Font* getMiniFont() const { return m_minifont; }
she::Font* getDefaultFont() const { return m_defaultFont; }
she::Font* getMiniFont() const { return m_miniFont; }
void reload_skin();
void reload_fonts();
@ -149,7 +150,8 @@ namespace app {
std::map<std::string, int> m_dimensions_by_id;
std::vector<ui::Cursor*> m_cursors;
StyleSheet m_stylesheet;
she::Font* m_minifont;
she::Font* m_defaultFont;
she::Font* m_miniFont;
};
inline SkinPartPtr get_part_by_id(const std::string& id) {

View File

@ -3,6 +3,7 @@
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
include(CheckCSourceRuns)
check_c_source_compiles("
#include <stdint.h>
@ -35,8 +36,16 @@ configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.cmakein
${CMAKE_CURRENT_BINARY_DIR}/base/config.h @ONLY)
set(BASE_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}
CACHE STRING "Extra include directory for base lib")
mark_as_advanced(${BASE_INCLUDE_DIR})
CACHE INTERNAL "Extra include directory for base lib")
if(WIN32)
set(EXTRA_LIBS dbghelp shlwapi)
else()
set(EXTRA_LIBS)
endif()
set(BASE_EXTRA_LIBRARIES ${EXTRA_LIBS}
CACHE INTERNAL "Extra libraries needed by base lib")
include_directories(${BASE_INCLUDE_DIR})
set(BASE_SOURCES

View File

@ -1,13 +1,86 @@
# SHE
# Copyright (C) 2012-2015 David Capello
set(SHE_SOURCES
alleg4/clock.cpp
alleg4/close_button.cpp
alleg4/fontbmp.cpp
alleg4/key_poller.cpp
alleg4/mouse_poller.cpp
alleg4/she.cpp)
set(SHE_SOURCES)
if(USE_ALLEG4_BACKEND)
list(APPEND SHE_SOURCES
alleg4/clock.cpp
alleg4/close_button.cpp
alleg4/fontbmp.cpp
alleg4/key_poller.cpp
alleg4/mouse_poller.cpp
alleg4/she.cpp)
if(APPLE)
if(NOT USE_SHARED_ALLEGRO4)
list(APPEND SHE_SOURCES alleg4/app.mm)
endif()
endif()
endif()
if(USE_SKIA_BACKEND)
set(SKIA_BUILD_DIR "" CACHE PATH "Skia build directory")
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(SKIA_BUILD_OUT_DIR "${SKIA_BUILD_DIR}/out/Debug")
else()
set(SKIA_BUILD_OUT_DIR "${SKIA_BUILD_DIR}/out/Release")
endif()
find_library(SKIA_CORE_LIBRARY skia_core PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_EFFECTS_LIBRARY skia_effects PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_IMAGES_LIBRARY skia_images PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_OPTS_LIBRARY skia_opts PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_OPTS_SSE41_LIBRARY skia_opts_sse41 PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_OPTS_SSSE3_LIBRARY skia_opts_ssse3 PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_PORTS_LIBRARY skia_ports PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_SFNT_LIBRARY skia_sfnt PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_GPU_LIBRARY skia_skgpu PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_UTILS_LIBRARY skia_utils PATH "${SKIA_BUILD_OUT_DIR}")
if(WIN32)
find_library(ETC1_LIBRARY libetc1 PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
find_library(LIBSKKTX_LIBRARY libSkKTX PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
find_library(OPENGL32_LIBRARY opengl32)
else()
set(ETC1_LIBRARY)
set(LIBSKKTX_LIBRARY)
# find_library(OPENGL32_LIBRARY glapi)
set(OPENGL32_LIBRARY)
endif()
find_path(SKIA_CONFIG_INCLUDE_DIR SkUserConfig.h HINTS "${SKIA_BUILD_DIR}/include/config")
find_path(SKIA_CORE_INCLUDE_DIR SkCanvas.h HINTS "${SKIA_BUILD_DIR}/include/core")
find_path(SKIA_EFFECTS_INCLUDE_DIR SkBitmapSource.h HINTS "${SKIA_BUILD_DIR}/include/effects")
find_path(SKIA_GPU_INCLUDE_DIR SkGr.h HINTS "${SKIA_BUILD_DIR}/include/gpu")
find_path(SKIA_UTILS_INCLUDE_DIR SkRandom.h HINTS "${SKIA_BUILD_DIR}/include/utils")
include_directories(
${SKIA_CONFIG_INCLUDE_DIR}
${SKIA_CORE_INCLUDE_DIR}
${SKIA_GPU_INCLUDE_DIR}
${SKIA_PORTS_INCLUDE_DIR}
${SKIA_UTILS_INCLUDE_DIR})
set(SKIA_LIBRARIES
${ETC1_LIBRARY}
${LIBSKKTX_LIBRARY}
${OPENGL32_LIBRARY}
${SKIA_CORE_LIBRARY}
${SKIA_EFFECTS_LIBRARY}
${SKIA_GPU_LIBRARY}
${SKIA_IMAGES_LIBRARY}
${SKIA_OPTS_LIBRARY}
${SKIA_OPTS_SSE41_LIBRARY}
${SKIA_OPTS_SSSE3_LIBRARY}
${SKIA_PORTS_LIBRARY}
${SKIA_UTILS_LIBRARY}
CACHE INTERNAL "Skia libraries")
list(APPEND SHE_SOURCES
skia/she.cpp)
endif()
if(WIN32)
list(APPEND SHE_SOURCES
@ -16,11 +89,8 @@ if(WIN32)
endif()
if(APPLE)
if(NOT USE_SHARED_ALLEGRO4)
list(APPEND SHE_SOURCES alleg4/app.mm)
endif()
list(APPEND SHE_SOURCES osx/logger.mm)
list(APPEND SHE_SOURCES
osx/logger.mm)
endif()
add_library(she ${SHE_SOURCES})

View File

@ -14,6 +14,7 @@
#include "base/string.h"
#include "she/alleg4/font.h"
#include "she/alleg4/surface.h"
#include "she/common/system.h"
#include "she/logger.h"
#include <allegro.h>
@ -51,13 +52,6 @@
#endif
#ifdef _WIN32
#include "she/win/clipboard.h"
#include "she/win/native_dialogs.h"
#else
#include "she/clipboard_simple.h"
#endif
#include "loadpng.h"
#include <cassert>
@ -104,10 +98,6 @@ static void resize_callback(RESIZE_DISPLAY_EVENT* ev)
namespace she {
#ifdef __APPLE__
Logger* getOsxLogger();
#endif
class Alleg4EventQueue : public EventQueue {
public:
Alleg4EventQueue() {
@ -123,12 +113,13 @@ public:
#endif
}
void dispose() {
~Alleg4EventQueue() {
clock_exit();
delete this;
}
void getEvent(Event& event) {
void getEvent(Event& event, bool canWait) override {
(void)canWait; // Ignore this parameter
close_button_generate_events();
#ifdef USE_KEY_POLLER
@ -708,11 +699,10 @@ private:
Alleg4EventQueue* m_queue;
};
class Alleg4System : public System {
class Alleg4System : public CommonSystem {
public:
Alleg4System()
: m_font(font, Alleg4Font::None) // Default Allegro font
, m_nativeDialogs(nullptr)
{
if (allegro_init() < 0)
throw std::runtime_error("Cannot initialize Allegro library");
@ -738,22 +728,6 @@ public:
return (Capabilities)(kCanResizeDisplayCapability);
}
Logger* logger() override {
#ifdef __APPLE__
return getOsxLogger();
#else
return nullptr;
#endif
}
NativeDialogs* nativeDialogs() override {
#ifdef _WIN32
if (!m_nativeDialogs)
m_nativeDialogs = new NativeDialogsWin32();
#endif
return m_nativeDialogs;
}
Display* defaultDisplay() override {
return unique_display;
}
@ -792,17 +766,8 @@ public:
return sur;
}
Clipboard* createClipboard() override {
#ifdef _WIN32
return new ClipboardWin32();
#else
return new ClipboardImpl();
#endif
}
private:
Alleg4Font m_font;
NativeDialogs* m_nativeDialogs;
};
static System* g_instance;

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -8,6 +8,8 @@
#define SHE_CLIPBOARD_H_INCLUDED
#pragma once
#include "she/display_handle.h"
#include <string>
namespace she {
@ -16,8 +18,8 @@ namespace she {
public:
virtual ~Clipboard() { }
virtual void dispose() = 0;
virtual std::string getText() = 0;
virtual void setText(const std::string& text) = 0;
virtual std::string getText(DisplayHandle hwnd) = 0;
virtual void setText(DisplayHandle hwnd, const std::string& text) = 0;
};
} // namespace she

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -21,11 +21,11 @@ namespace she {
delete this;
}
std::string getText() override {
std::string getText(DisplayHandle) override {
return m_text;
}
void setText(const std::string& text) {
void setText(DisplayHandle, const std::string& text) {
m_text = text;
}

62
src/she/common/system.h Normal file
View File

@ -0,0 +1,62 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef _WIN32
#include "she/win/clipboard.h"
#include "she/win/native_dialogs.h"
#else
#include "she/clipboard_simple.h"
#endif
namespace she {
#ifdef __APPLE__
Logger* getOsxLogger();
#endif
class CommonSystem : public System {
public:
CommonSystem()
: m_nativeDialogs(nullptr) {
}
~CommonSystem() {
delete m_nativeDialogs;
}
void dispose() override {
delete this;
}
Logger* logger() override {
#ifdef __APPLE__
return getOsxLogger();
#else
return nullptr;
#endif
}
NativeDialogs* nativeDialogs() override {
#ifdef _WIN32
if (!m_nativeDialogs)
m_nativeDialogs = new NativeDialogsWin32();
#endif
return m_nativeDialogs;
}
Clipboard* createClipboard() override {
#ifdef _WIN32
return new ClipboardWin32();
#else
return new ClipboardImpl();
#endif
}
private:
NativeDialogs* m_nativeDialogs;
};
} // namespace she

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2013 David Capello
// Copyright (C) 2012-2015 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
@ -15,8 +15,7 @@ namespace she {
class EventQueue {
public:
virtual ~EventQueue() { }
virtual void dispose() = 0;
virtual void getEvent(Event& ev) = 0;
virtual void getEvent(Event& ev, bool canWait) = 0;
};
} // namespace she

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -13,6 +13,7 @@
#include "she/error.h"
#include "she/event.h"
#include "she/event_queue.h"
#include "she/font.h"
#include "she/locked_surface.h"
#include "she/scoped_handle.h"
#include "she/scoped_surface_lock.h"

107
src/she/skia/she.cpp Normal file
View File

@ -0,0 +1,107 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gfx/rect.h"
#include "gfx/size.h"
#include "she/she.h"
#include "she/common/system.h"
#ifdef _WIN32
#include <windows.h>
#include "she/win/window.h"
#else
#error There is no Window implementation
#endif
// #include "SkApplication.h"
// #include "SkCanvas.h"
// #include "SkEvent.h"
// #include "SkGradientShader.h"
#include "SkBitmap.h"
// #include "SkGraphics.h"
#include "SkImageInfo.h"
// #include "SkGr.h"
#include <queue>
#include "she/skia/skia_surface.h"
#include "she/skia/skia_event_queue.h"
#include "she/skia/skia_window.h"
#include "she/skia/skia_display.h"
#include "she/skia/skia_font.h"
#include "she/skia/skia_system.h"
namespace she {
static System* g_instance;
System* create_system() {
return g_instance = new SkiaSystem();
}
System* instance()
{
return g_instance;
}
void error_message(const char* msg)
{
// TODO
}
bool is_key_pressed(KeyScancode scancode)
{
// TODO
return false;
}
void clear_keyboard_buffer()
{
// Do nothing
}
int clock_value()
{
// TODO
return 0; // clock_var;
}
Font* load_bitmap_font(const char* filename, int scale)
{
// TODO
return new SkiaFont(SkiaFont::DeleteThis);
}
} // namespace she
extern int app_main(int argc, char* argv[]);
#if _WIN32
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
int argc = 1;
char* argv[] = { "" };
#else
int main(int argc, char* argv[])
{
#endif
// SkGraphics::Init();
// SkEvent::Init();
int res = app_main(argc, argv);
// SkEvent::Term();
// SkGraphics::Term();
return res;
}

104
src/she/skia/skia_display.h Normal file
View File

@ -0,0 +1,104 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
namespace she {
class SkiaDisplay : public Display {
public:
SkiaDisplay(int width, int height, int scale)
: m_window(&m_queue, this)
, m_scale(scale) {
m_surface.create(width, height);
m_window.setVisible(true);
}
void dispose() override {
delete this;
}
// Returns the real and current display's size (without scale applied).
int width() const override {
return m_window.clientSize().w;
}
int height() const override {
return m_window.clientSize().h;
}
// Returns the display when it was not maximized.
int originalWidth() const override {
return m_window.restoredSize().w;
}
int originalHeight() const override {
return m_window.restoredSize().h;
}
void setScale(int scale) override {
m_scale = scale;
}
int scale() const override {
return m_scale;
}
// Returns the main surface to draw into this display.
// You must not dispose this surface.
NonDisposableSurface* getSurface() override {
return static_cast<NonDisposableSurface*>(&m_surface);
}
// Flips all graphics in the surface to the real display. Returns
// false if the flip couldn't be done because the display was
// resized.
bool flip() override {
return true;
}
void maximize() override {
m_window.maximize();
}
bool isMaximized() const override {
return m_window.isMaximized();
}
void setTitleBar(const std::string& title) override {
m_window.setText(title);
}
EventQueue* getEventQueue() override {
return &m_queue;
}
bool setNativeMouseCursor(NativeCursor cursor) override {
return true;
}
void setMousePosition(const gfx::Point& position) override {
}
void captureMouse() override {
m_window.captureMouse();
}
void releaseMouse() override {
m_window.releaseMouse();
}
// Returns the HWND on Windows.
DisplayHandle nativeHandle() override {
return (DisplayHandle)m_window.handle();
}
private:
SkiaEventQueue m_queue;
SkiaWindow m_window;
SkiaSurface m_surface;
int m_scale;
};
} // namespace she

View File

@ -0,0 +1,56 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
namespace she {
class SkiaEventQueue : public EventQueue {
public:
SkiaEventQueue() : m_stop(false) {
}
void getEvent(Event& ev, bool canWait) override {
MSG msg;
while (!m_stop && m_events.empty()) {
BOOL res;
if (canWait) {
res = GetMessage(&msg, nullptr, 0, 0);
}
else {
res = PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE);
}
if (res) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if (!canWait)
break;
}
if (m_events.empty()) {
ev.setType(Event::None);
}
else {
ev = m_events.front();
m_events.pop();
}
}
void queueEvent(Event& ev) {
if (ev.type() == Event::CloseDisplay)
m_stop = true;
m_events.push(ev);
}
private:
std::queue<Event> m_events;
bool m_stop;
};
} // namespace she

51
src/she/skia/skia_font.h Normal file
View File

@ -0,0 +1,51 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
namespace she {
class SkiaFont : public Font {
public:
enum DestroyFlag {
None = 0,
DeleteThis = 1,
};
SkiaFont(DestroyFlag flag) : m_flag(flag) {
}
void dispose() override {
if (m_flag & DeleteThis)
delete this;
}
int height() const override {
return 8;
}
int charWidth(int chr) const override {
return 8;
}
int textLength(const char* chr) const override {
return 8;
}
bool isScalable() const override {
return false;
}
void setSize(int size) override {
}
void* nativeHandle() override {
return nullptr;
}
private:
DestroyFlag m_flag;
};
} // namespace she

135
src/she/skia/skia_surface.h Normal file
View File

@ -0,0 +1,135 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
namespace she {
class SkiaSurface : public NonDisposableSurface
, public LockedSurface {
public:
SkiaSurface() {
}
void create(int width, int height) {
m_bitmap.tryAllocPixels(
SkImageInfo::MakeUnknown(width, height));
}
void createRgba(int width, int height) {
m_bitmap.tryAllocPixels(
SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType));
}
// Surface impl
void dispose() override {
delete this;
}
int width() const override {
return m_bitmap.width();
}
int height() const override {
return m_bitmap.height();
}
bool isDirectToScreen() const override {
return false;
}
gfx::Rect getClipBounds() override {
return gfx::Rect();
}
void setClipBounds(const gfx::Rect& rc) override {
}
bool intersectClipRect(const gfx::Rect& rc) override {
return true;
}
void setDrawMode(DrawMode mode, int param) {
}
LockedSurface* lock() override {
m_bitmap.lockPixels();
return this;
}
void applyScale(int scaleFactor) override {
}
void* nativeHandle() override {
return (void*)this;
}
// LockedSurface impl
void unlock() override {
m_bitmap.unlockPixels();
}
void clear() override {
}
uint8_t* getData(int x, int y) override {
return (uint8_t*)m_bitmap.getAddr(x, y);
}
void getFormat(SurfaceFormatData* formatData) override {
}
gfx::Color getPixel(int x, int y) override {
SkColor c = m_bitmap.getColor(x, y);
return gfx::rgba(
SkColorGetR(c),
SkColorGetG(c),
SkColorGetB(c),
SkColorGetA(c));
}
void putPixel(gfx::Color color, int x, int y) override {
}
void drawHLine(gfx::Color color, int x, int y, int w) override {
}
void drawVLine(gfx::Color color, int x, int y, int h) override {
}
void drawLine(gfx::Color color, const gfx::Point& a, const gfx::Point& b) override {
}
void drawRect(gfx::Color color, const gfx::Rect& rc) override {
}
void fillRect(gfx::Color color, const gfx::Rect& rc) override {
}
void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const override {
}
void drawSurface(const LockedSurface* src, int dstx, int dsty) override {
}
void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) override {
}
void drawChar(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, int chr) override {
}
void drawString(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, const std::string& str) override {
}
SkBitmap& bitmap() {
return m_bitmap;
}
private:
SkBitmap m_bitmap;
};
} // namespace she

View File

@ -0,0 +1,74 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
namespace she {
class SkiaSystem : public CommonSystem {
public:
SkiaSystem()
: m_font(SkiaFont::None)
, m_defaultDisplay(nullptr) {
}
~SkiaSystem() {
}
void dispose() override {
delete this;
}
Capabilities capabilities() const override {
return Capabilities(
int(kMultipleDisplaysCapability) |
int(kCanResizeDisplayCapability) |
int(kDisplayScaleCapability));
}
Display* defaultDisplay() override {
return m_defaultDisplay;
}
Font* defaultFont() override {
return &m_font;
}
Display* createDisplay(int width, int height, int scale) override {
SkiaDisplay* display = new SkiaDisplay(width, height, scale);
if (!m_defaultDisplay)
m_defaultDisplay = display;
return display;
}
Surface* createSurface(int width, int height) override {
SkiaSurface* sur = new SkiaSurface;
sur->create(width, height);
return sur;
}
Surface* createRgbaSurface(int width, int height) override {
SkiaSurface* sur = new SkiaSurface;
sur->createRgba(width, height);
return sur;
}
Surface* loadSurface(const char* filename) override {
SkiaSurface* sur = new SkiaSurface;
sur->create(32, 32);
return sur;
}
Surface* loadRgbaSurface(const char* filename) override {
SkiaSurface* sur = new SkiaSurface;
sur->create(32, 32);
return sur;
}
private:
SkiaFont m_font;
SkiaDisplay* m_defaultDisplay;
};
} // namespace she

View File

@ -0,0 +1,54 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
namespace she {
class SkiaWindow : public Window<SkiaWindow> {
public:
SkiaWindow(SkiaEventQueue* queue, Display* display)
: m_queue(queue)
, m_display(display) {
}
void queueEventImpl(Event& ev) {
ev.setDisplay(m_display);
m_queue->queueEvent(ev);
}
void paintImpl(HDC hdc) {
SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
const SkBitmap& bitmap = surface->bitmap();
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = bitmap.width();
bmi.bmiHeader.biHeight = -bitmap.height();
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
ASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
bitmap.lockPixels();
int ret = SetDIBitsToDevice(hdc,
0, 0,
bitmap.width(), bitmap.height(),
0, 0,
0, bitmap.height(),
bitmap.getPixels(),
&bmi,
DIB_RGB_COLORS);
(void)ret;
bitmap.unlockPixels();
}
private:
SkiaEventQueue* m_queue;
Display* m_display;
};
} // namespace she

View File

@ -11,8 +11,22 @@
#include "base/string.h"
#include "she/win/clipboard.h"
#include <allegro.h>
#include <winalleg.h>
#include <windows.h>
namespace {
bool open_clipboard(HWND hwnd)
{
for (int i=0; i<5; ++i) {
if (OpenClipboard(hwnd))
return true;
Sleep(100);
}
return false;
}
}
namespace she {
@ -21,12 +35,12 @@ void ClipboardWin32::dispose()
delete this;
}
std::string ClipboardWin32::getText()
std::string ClipboardWin32::getText(DisplayHandle hwnd)
{
std::string text;
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
if (OpenClipboard(win_get_window())) {
if (open_clipboard((HWND)hwnd)) {
HGLOBAL hglobal = GetClipboardData(CF_UNICODETEXT);
if (hglobal != NULL) {
LPWSTR lpstr = static_cast<LPWSTR>(GlobalLock(hglobal));
@ -42,10 +56,10 @@ std::string ClipboardWin32::getText()
return text;
}
void ClipboardWin32::setText(const std::string& text)
void ClipboardWin32::setText(DisplayHandle hwnd, const std::string& text)
{
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
if (OpenClipboard(win_get_window())) {
if (open_clipboard((HWND)hwnd)) {
EmptyClipboard();
if (!text.empty()) {

View File

@ -16,8 +16,8 @@ namespace she {
class ClipboardWin32 : public Clipboard {
public:
void dispose() override;
std::string getText() override;
void setText(const std::string& text) override;
std::string getText(DisplayHandle hwnd) override;
void setText(DisplayHandle hwnd, const std::string& text) override;
private:
std::string m_text;

696
src/she/win/window.h Normal file
View File

@ -0,0 +1,696 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_WIN_WINDOW_H_INCLUDED
#define SHE_WIN_WINDOW_H_INCLUDED
#pragma once
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "she/keys.h"
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif
namespace she {
static KeyScancode vkToScancode(int vk) {
static KeyScancode keymap[0xFF] = {
// 0x00
kKeyNil,
kKeyNil, // 0x01 - VK_LBUTTON
kKeyNil, // 0x02 - VK_RBUTTON
kKeyNil, // 0x03 - VK_CANCEL
kKeyNil, // 0x04 - VK_MBUTTON
kKeyNil, // 0x05 - VK_XBUTTON1
kKeyNil, // 0x06 - VK_XBUTTON2
kKeyNil, // 0x07 - Unassigned
kKeyBackspace, // 0x08 - VK_BACK
kKeyTab, // 0x09 - VK_TAB
kKeyNil, // 0x0A - Reserved
kKeyNil, // 0x0B - Reserved
kKeyNil, // 0x0C - VK_CLEAR
kKeyEnter, // 0x0D - VK_RETURN
kKeyNil, // 0x0E - Undefined
kKeyNil, // 0x0F - Undefined
// 0x10
kKeyLShift, // 0x10 - VK_SHIFT
kKeyLControl, // 0x11 - VK_CONTROL
kKeyMenu, // 0x12 - VK_MENU
kKeyPause, // 0x13 - VK_PAUSE
kKeyCapsLock, // 0x14 - VK_CAPITAL
kKeyNil, // 0x15 - VK_KANA
kKeyNil, // 0x17 - VK_JUNJA
kKeyNil, // 0x18 - VK_FINAL
kKeyKanji, // 0x19 - VK_KANJI
kKeyNil, // 0x1A - Unknown
kKeyEsc, // 0x1B - VK_ESCAPE
kKeyConvert, // 0x1C - VK_CONVERT
kKeyNoconvert, // 0x1D - VK_NONCONVERT
kKeyNil, // 0x1E - VK_ACCEPT
kKeyNil, // 0x1F - VK_MODECHANGE
// 0x20
kKeySpace, // 0x20 - VK_SPACE
kKeyPageUp, // 0x21 - VK_PRIOR
kKeyPageDown, // 0x22 - VK_NEXT
kKeyEnd, // 0x23 - VK_END
kKeyHome, // 0x24 - VK_HOME
kKeyLeft, // 0x25 - VK_LEFT
kKeyUp, // 0x26 - VK_UP
kKeyRight, // 0x27 - VK_RIGHT
kKeyDown, // 0x28 - VK_DOWN
kKeyNil, // 0x29 - VK_SELECT
kKeyPrtscr, // 0x2A - VK_PRINT
kKeyNil, // 0x2B - VK_EXECUTE
kKeyNil, // 0x2C - VK_SNAPSHOT
kKeyInsert, // 0x2D - VK_INSERT
kKeyDel, // 0x2E - VK_DELETE
kKeyNil, // 0x2F - VK_HELP
// 0x30
kKey0, // 0x30 - VK_0
kKey1, // 0x31 - VK_1
kKey2, // 0x32 - VK_2
kKey3, // 0x33 - VK_3
kKey4, // 0x34 - VK_4
kKey5, // 0x35 - VK_5
kKey6, // 0x36 - VK_6
kKey7, // 0x37 - VK_7
kKey8, // 0x38 - VK_8
kKey9, // 0x39 - VK_9
// 0x40
kKeyNil, // 0x40 - Unassigned
kKeyA, // 0x41 - VK_A
kKeyB, // 0x42 - VK_B
kKeyC, // 0x43 - VK_C
kKeyD, // 0x44 - VK_D
kKeyE, // 0x45 - VK_E
kKeyF, // 0x46 - VK_F
kKeyG, // 0x47 - VK_G
kKeyH, // 0x48 - VK_H
kKeyI, // 0x49 - VK_I
kKeyJ, // 0x4A - VK_J
kKeyK, // 0x4B - VK_K
kKeyL, // 0x4C - VK_L
kKeyM, // 0x4D - VK_M
kKeyN, // 0x4E - VK_N
kKeyO, // 0x4F - VK_O
// 0x50
kKeyP, // 0x50 - VK_P
kKeyQ, // 0x51 - VK_Q
kKeyR, // 0x52 - VK_R
kKeyS, // 0x53 - VK_S
kKeyT, // 0x54 - VK_T
kKeyU, // 0x55 - VK_U
kKeyV, // 0x56 - VK_V
kKeyW, // 0x57 - VK_W
kKeyX, // 0x58 - VK_X
kKeyY, // 0x59 - VK_Y
kKeyZ, // 0x5A - VK_Z
kKeyLWin, // 0x5B - VK_LWIN
kKeyRWin, // 0x5C - VK_RWIN
kKeyNil, // 0x5D - VK_APPS
kKeyNil, // 0x5E - Reserved
kKeyNil, // 0x5F - VK_SLEEP
// 0x60
kKey0Pad, // 0x60 - VK_NUMPAD0
kKey1Pad, // 0x61 - VK_NUMPAD1
kKey2Pad, // 0x62 - VK_NUMPAD2
kKey3Pad, // 0x63 - VK_NUMPAD3
kKey4Pad, // 0x64 - VK_NUMPAD4
kKey5Pad, // 0x65 - VK_NUMPAD5
kKey6Pad, // 0x66 - VK_NUMPAD6
kKey7Pad, // 0x67 - VK_NUMPAD7
kKey8Pad, // 0x68 - VK_NUMPAD8
kKey9Pad, // 0x69 - VK_NUMPAD9
kKeyAsterisk, // 0x6A - VK_MULTIPLY
kKeyPlusPad, // 0x6B - VK_ADD
kKeyNil, // 0x6C - VK_SEPARATOR
kKeyMinusPad, // 0x6D - VK_SUBTRACT
kKeyNil, // 0x6E - VK_DECIMAL
kKeyNil, // 0x6F - VK_DIVIDE
// 0x70
kKeyNil, // 0x70 - VK_F1
kKeyNil, // 0x71 - VK_F2
kKeyNil, // 0x72 - VK_F3
kKeyNil, // 0x73 - VK_F4
kKeyNil, // 0x74 - VK_F5
kKeyNil, // 0x75 - VK_F6
kKeyNil, // 0x76 - VK_F7
kKeyNil, // 0x77 - VK_F8
kKeyNil, // 0x78 - VK_F9
kKeyNil, // 0x79 - VK_F10
kKeyNil, // 0x7A - VK_F11
kKeyNil, // 0x7B - VK_F12
kKeyNil, // 0x7C - VK_F13
kKeyNil, // 0x7D - VK_F14
kKeyNil, // 0x7E - VK_F15
kKeyNil, // 0x7F - VK_F16
// 0x80
kKeyNil, // 0x80 - VK_F17
kKeyNil, // 0x81 - VK_F18
kKeyNil, // 0x82 - VK_F19
kKeyNil, // 0x83 - VK_F20
kKeyNil, // 0x84 - VK_F21
kKeyNil, // 0x85 - VK_F22
kKeyNil, // 0x86 - VK_F23
kKeyNil, // 0x87 - VK_F24
kKeyNil, // 0x88 - Unassigned
kKeyNil, // 0x89 - Unassigned
kKeyNil, // 0x8A - Unassigned
kKeyNil, // 0x8B - Unassigned
kKeyNil, // 0x8C - Unassigned
kKeyNil, // 0x8D - Unassigned
kKeyNil, // 0x8E - Unassigned
kKeyNil, // 0x8F - Unassigned
// 0x90
kKeyNil, // 0x90 - VK_NUMLOCK
kKeyNil, // 0x91 - VK_SCROLL
kKeyEqualsPad, // 0x92 - VK_OEM_NEC_EQUAL / VK_OEM_FJ_JISHO
kKeyNil, // 0x93- VK_OEM_FJ_MASSHOU
kKeyNil, // 0x94- VK_OEM_FJ_TOUROKU
kKeyNil, // 0x95 - VK_OEM_FJ_LOYA
kKeyNil, // 0x96 - VK_OEM_FJ_ROYA
kKeyNil, // 0x97 - Unassigned
kKeyNil, // 0x98 - Unassigned
kKeyNil, // 0x99 - Unassigned
kKeyNil, // 0x9A - Unassigned
kKeyNil, // 0x9B - Unassigned
kKeyNil, // 0x9C - Unassigned
kKeyNil, // 0x9D - Unassigned
kKeyNil, // 0x9E - Unassigned
kKeyNil, // 0x9F - Unassigned
// 0xA0
kKeyNil, // 0xA0 - VK_LSHIFT
kKeyNil, // 0xA1 - VK_RSHIFT
kKeyNil, // 0xA2 - VK_LCONTROL
kKeyNil, // 0xA3 - VK_RCONTROL
kKeyNil, // 0xA4 - VK_LMENU
kKeyNil, // 0xA5 - VK_RMENU
kKeyNil, // 0xA6 - VK_BROWSER_BACK
kKeyNil, // 0xA7 - VK_BROWSER_FORWARD
kKeyNil, // 0xA8 - VK_BROWSER_REFRESH
kKeyNil, // 0xA9 - VK_BROWSER_STOP
kKeyNil, // 0xAA - VK_BROWSER_SEARCH
kKeyNil, // 0xAB - VK_BROWSER_FAVORITES
kKeyNil, // 0xAC - VK_BROWSER_HOME
kKeyNil, // 0xAD - VK_VOLUME_MUTE
kKeyNil, // 0xAE - VK_VOLUME_DOWN
kKeyNil, // 0xAF - VK_VOLUME_UP
// 0xB0
kKeyNil, // 0xB0 - VK_MEDIA_NEXT_TRACK
kKeyNil, // 0xB1 - VK_MEDIA_PREV_TRACK
kKeyNil, // 0xB2 - VK_MEDIA_STOP
kKeyNil, // 0xB3 - VK_MEDIA_PLAY_PAUSE
kKeyNil, // 0xB4 - VK_LAUNCH_MAIL
kKeyNil, // 0xB5- VK_LAUNCH_MEDIA_SELECT
kKeyNil, // 0xB6 - VK_LAUNCH_APP1
kKeyNil, // 0xB7 - VK_LAUNCH_APP2
kKeyNil, // 0xB8 - Reserved
kKeyNil, // 0xB9 - Reserved
kKeyNil, // 0xBA - VK_OEM_1
kKeyNil, // 0xBB - VK_OEM_PLUS
kKeyNil, // 0xBC - VK_OEM_COMMA
kKeyNil, // 0xBD - VK_OEM_MINUS
kKeyNil, // 0xBE - VK_OEM_PERIOD
kKeyNil, // 0xBF - VK_OEM_2
// 0xC0
kKeyNil, // 0xC0 - VK_OEM_3
kKeyNil, // 0xC1 - Reserved
kKeyNil, // 0xC2 - Reserved
kKeyNil, // 0xC3 - Reserved
kKeyNil, // 0xC4 - Reserved
kKeyNil, // 0xC5 - Reserved
kKeyNil, // 0xC6 - Reserved
kKeyNil, // 0xC7 - Reserved
kKeyNil, // 0xC8 - Reserved
kKeyNil, // 0xC9 - Reserved
kKeyNil, // 0xCA - Reserved
kKeyNil, // 0xCB - Reserved
kKeyNil, // 0xCC - Reserved
kKeyNil, // 0xCD - Reserved
kKeyNil, // 0xCE - Reserved
kKeyNil, // 0xCF - Reserved
// 0xD0
kKeyNil, // 0xD0 - Reserved
kKeyNil, // 0xD1 - Reserved
kKeyNil, // 0xD2 - Reserved
kKeyNil, // 0xD3 - Reserved
kKeyNil, // 0xD4 - Reserved
kKeyNil, // 0xD5 - Reserved
kKeyNil, // 0xD6 - Reserved
kKeyNil, // 0xD7 - Reserved
kKeyNil, // 0xD8 - Unassigned
kKeyNil, // 0xD9 - Unassigned
kKeyNil, // 0xDA - Unassigned
kKeyNil, // 0xDB - VK_OEM_4
kKeyNil, // 0xDC - VK_OEM_5
kKeyNil, // 0xDD - VK_OEM_6
kKeyNil, // 0xDE - VK_OEM_7
kKeyNil, // 0xDF - VK_OEM_8
// 0xE0
kKeyNil, // 0xE0 - Reserved
kKeyNil, // 0xE1 - VK_OEM_AX
kKeyNil, // 0xE2 - VK_OEM_102
kKeyNil, // 0xE3 - VK_ICO_HELP
kKeyNil, // 0xE4 - VK_ICO_00
kKeyNil, // 0xE5 - VK_PROCESSKEY
kKeyNil, // 0xE6 - VK_ICO_CLEAR
kKeyNil, // 0xE7 - VK_PACKET
kKeyNil, // 0xE8 - Unassigned
kKeyNil, // 0xE9 - VK_OEM_RESET
kKeyNil, // 0xEA - VK_OEM_JUMP
kKeyNil, // 0xEB - VK_OEM_PA1
kKeyNil, // 0xEC - VK_OEM_PA2
kKeyNil, // 0xED - VK_OEM_PA3
kKeyNil, // 0xEE - VK_OEM_WSCTRL
kKeyNil, // 0xEF - VK_OEM_CUSEL
// 0xF0
kKeyNil, // 0xF0 - VK_OEM_ATTN
kKeyNil, // 0xF1 - VK_OEM_FINISH
kKeyNil, // 0xF2 - VK_OEM_COPY
kKeyNil, // 0xF3 - VK_OEM_AUTO
kKeyNil, // 0xF4 - VK_OEM_ENLW
kKeyNil, // 0xF5 - VK_OEM_BACKTAB
kKeyNil, // 0xF6 - VK_ATTN
kKeyNil, // 0xF7 - VK_CRSEL
kKeyNil, // 0xF8 - VK_EXSEL
kKeyNil, // 0xF9 - VK_EREOF
kKeyNil, // 0xFA - VK_PLAY
kKeyNil, // 0xFB - VK_ZOOM
kKeyNil, // 0xFC - VK_NONAME
kKeyNil, // 0xFD - VK_PA1
kKeyNil, // 0xFE - VK_OEM_CLEAR
kKeyNil, // 0xFF - Reserved
};
if (vk < 0 || vk > 255)
vk = kKeyNil;
return keymap[vk];
}
#define SHE_WND_CLASS_NAME L"Aseprite.Window"
template<typename T>
class Window {
public:
Window() {
registerClass();
m_hwnd = createHwnd(this);
m_hasMouse = false;
m_captureMouse = false;
m_scale = 1;
}
void queueEvent(Event& ev) {
static_cast<T*>(this)->queueEventImpl(ev);
}
void setScale(int scale) {
m_scale = scale;
}
void setVisible(bool visible) {
if (visible) {
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
DrawMenuBar(m_hwnd);
}
else
ShowWindow(m_hwnd, SW_HIDE);
}
void maximize() {
ShowWindow(m_hwnd, SW_MAXIMIZE);
}
bool isMaximized() const {
return (IsZoomed(m_hwnd) ? true: false);
}
gfx::Size clientSize() const {
return m_clientSize;
}
gfx::Size restoredSize() const {
return m_restoredSize;
}
void setText(const std::string& text) {
SetWindowText(m_hwnd, base::from_utf8(text).c_str());
}
void captureMouse() {
m_captureMouse = true;
}
void releaseMouse() {
m_captureMouse = false;
}
HWND handle() {
return m_hwnd;
}
private:
LRESULT wndProc(UINT msg, WPARAM wparam, LPARAM lparam) {
switch (msg) {
case WM_CLOSE: {
Event ev;
ev.setType(Event::CloseDisplay);
queueEvent(ev);
break;
}
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(m_hwnd, &ps);
static_cast<T*>(this)->paintImpl(hdc);
EndPaint(m_hwnd, &ps);
return true;
}
case WM_SIZE: {
switch (wparam) {
case SIZE_MAXIMIZED:
case SIZE_RESTORED:
m_clientSize.w = GET_X_LPARAM(lparam);
m_clientSize.h = GET_Y_LPARAM(lparam);
break;
}
WINDOWPLACEMENT pl;
pl.length = sizeof(pl);
if (GetWindowPlacement(m_hwnd, &pl)) {
m_restoredSize = gfx::Size(
pl.rcNormalPosition.right - pl.rcNormalPosition.left,
pl.rcNormalPosition.bottom - pl.rcNormalPosition.top);
}
break;
}
case WM_MOUSEMOVE: {
// Adjust capture
if (m_captureMouse) {
if (GetCapture() != m_hwnd)
SetCapture(m_hwnd);
}
else {
if (GetCapture() == m_hwnd)
ReleaseCapture();
}
Event ev;
ev.setPosition(gfx::Point(
GET_X_LPARAM(lparam) / m_scale,
GET_Y_LPARAM(lparam) / m_scale));
if (!m_hasMouse) {
m_hasMouse = true;
ev.setType(Event::MouseEnter);
queueEvent(ev);
// Track mouse to receive WM_MOUSELEAVE message.
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hwnd;
_TrackMouseEvent(&tme);
}
ev.setType(Event::MouseMove);
queueEvent(ev);
break;
}
case WM_NCMOUSEMOVE:
case WM_MOUSELEAVE:
if (m_hasMouse) {
m_hasMouse = false;
Event ev;
ev.setType(Event::MouseLeave);
queueEvent(ev);
}
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN: {
Event ev;
ev.setType(Event::MouseDown);
ev.setPosition(gfx::Point(
GET_X_LPARAM(lparam) / m_scale,
GET_Y_LPARAM(lparam) / m_scale));
ev.setButton(
msg == WM_LBUTTONDOWN ? Event::LeftButton:
msg == WM_RBUTTONDOWN ? Event::RightButton:
msg == WM_MBUTTONDOWN ? Event::MiddleButton: Event::NoneButton);
queueEvent(ev);
break;
}
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP: {
Event ev;
ev.setType(Event::MouseUp);
ev.setPosition(gfx::Point(
GET_X_LPARAM(lparam) / m_scale,
GET_Y_LPARAM(lparam) / m_scale));
ev.setButton(
msg == WM_LBUTTONUP ? Event::LeftButton:
msg == WM_RBUTTONUP ? Event::RightButton:
msg == WM_MBUTTONUP ? Event::MiddleButton: Event::NoneButton);
queueEvent(ev);
// Avoid popup menu for scrollbars
if (msg == WM_RBUTTONUP)
return 0;
break;
}
case WM_LBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_RBUTTONDBLCLK: {
Event ev;
ev.setType(Event::MouseDoubleClick);
ev.setPosition(gfx::Point(
GET_X_LPARAM(lparam) / m_scale,
GET_Y_LPARAM(lparam) / m_scale));
ev.setButton(
msg == WM_LBUTTONDBLCLK ? Event::LeftButton:
msg == WM_RBUTTONDBLCLK ? Event::RightButton:
msg == WM_MBUTTONDBLCLK ? Event::MiddleButton: Event::NoneButton);
queueEvent(ev);
break;
}
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL: {
RECT rc;
::GetWindowRect(m_hwnd, &rc);
Event ev;
ev.setType(Event::MouseWheel);
ev.setPosition((gfx::Point(
GET_X_LPARAM(lparam),
GET_Y_LPARAM(lparam)) - gfx::Point(rc.left, rc.top))
/ m_scale);
int z = ((short)HIWORD(wparam)) / WHEEL_DELTA;
gfx::Point delta(
(msg == WM_MOUSEHWHEEL ? z: 0),
(msg == WM_MOUSEWHEEL ? -z: 0));
ev.setWheelDelta(delta);
//PRINTF("WHEEL: %d %d\n", delta.x, delta.y);
queueEvent(ev);
break;
}
case WM_HSCROLL:
case WM_VSCROLL: {
RECT rc;
::GetWindowRect(m_hwnd, &rc);
POINT pos;
::GetCursorPos(&pos);
Event ev;
ev.setType(Event::MouseWheel);
ev.setPosition((gfx::Point(pos.x, pos.y) - gfx::Point(rc.left, rc.top))
/ m_scale);
int bar = (msg == WM_HSCROLL ? SB_HORZ: SB_VERT);
int z = GetScrollPos(m_hwnd, bar);
switch (LOWORD(wparam)) {
case SB_LEFT:
case SB_LINELEFT:
--z;
break;
case SB_PAGELEFT:
z -= 2;
break;
case SB_RIGHT:
case SB_LINERIGHT:
++z;
break;
case SB_PAGERIGHT:
z += 2;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
case SB_ENDSCROLL:
// Do nothing
break;
}
gfx::Point delta(
(msg == WM_HSCROLL ? (z-50): 0),
(msg == WM_VSCROLL ? (z-50): 0));
ev.setWheelDelta(delta);
//PRINTF("SCROLL: %d %d\n", delta.x, delta.y);
SetScrollPos(m_hwnd, bar, 50, FALSE);
queueEvent(ev);
break;
}
case WM_KEYDOWN: {
Event ev;
ev.setType(Event::KeyDown);
ev.setScancode(vkToScancode(wparam));
ev.setUnicodeChar(0); // TODO
ev.setRepeat(lparam & 15);
queueEvent(ev);
break;
}
case WM_KEYUP: {
Event ev;
ev.setType(Event::KeyUp);
ev.setScancode(vkToScancode(wparam));
ev.setUnicodeChar(0); // TODO
ev.setRepeat(lparam & 15);
queueEvent(ev);
break;
}
case WM_UNICHAR: {
Event ev;
ev.setType(Event::KeyUp);
ev.setScancode(kKeyNil); // TODO
ev.setUnicodeChar(wparam);
ev.setRepeat(lparam & 15);
queueEvent(ev);
break;
}
case WM_DROPFILES: {
HDROP hdrop = (HDROP)(wparam);
Event::Files files;
int count = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
for (int index=0; index<count; ++index) {
int length = DragQueryFile(hdrop, index, NULL, 0);
if (length > 0) {
std::vector<TCHAR> str(length+1);
DragQueryFile(hdrop, index, &str[0], str.size());
files.push_back(base::to_utf8(&str[0]));
}
}
DragFinish(hdrop);
Event ev;
ev.setType(Event::DropFiles);
ev.setFiles(files);
queueEvent(ev);
break;
}
}
return DefWindowProc(m_hwnd, msg, wparam, lparam);
}
static void registerClass() {
HMODULE instance = GetModuleHandle(nullptr);
WNDCLASSEX wcex;
if (GetClassInfoEx(instance, SHE_WND_CLASS_NAME, &wcex))
return; // Already registered
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = &Window::staticWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = instance;
wcex.hIcon = nullptr;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = SHE_WND_CLASS_NAME;
wcex.hIconSm = nullptr;
if (RegisterClassEx(&wcex) == 0)
throw std::runtime_error("Error registering window class");
}
static HWND createHwnd(Window* self) {
HWND hwnd = CreateWindowEx(
WS_EX_APPWINDOW | WS_EX_ACCEPTFILES,
SHE_WND_CLASS_NAME,
L"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
nullptr,
nullptr,
GetModuleHandle(nullptr),
LPVOID(self));
if (!hwnd)
return nullptr;
SetWindowLongPtr(hwnd, GWLP_USERDATA, LONG_PTR(self));
return hwnd;
}
static LRESULT CALLBACK staticWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
Window* wnd;
if (msg == WM_CREATE)
wnd = (Window*)lparam;
else
wnd = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (wnd)
return wnd->wndProc(msg, wparam, lparam);
else
return DefWindowProc(hwnd, msg, wparam, lparam);
}
mutable HWND m_hwnd;
gfx::Size m_clientSize;
gfx::Size m_restoredSize;
int m_scale;
bool m_hasMouse;
bool m_captureMouse;
};
} // namespace she
#endif

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013 David Capello
// Copyright (C) 2001-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -11,6 +11,7 @@
#include "ui/clipboard.h"
#include "she/clipboard.h"
#include "she/display.h"
#include "ui/manager.h"
#include <string>
@ -22,14 +23,19 @@ namespace clipboard {
const char* get_text()
{
clipboard_text = Manager::getDefault()->getClipboard()->getText();
Manager* manager = Manager::getDefault();
clipboard_text = manager->getClipboard()->getText(
manager->getDisplay()->nativeHandle());
return clipboard_text.c_str();
}
void set_text(const char* text)
{
clipboard_text = text ? text: "";
Manager::getDefault()->getClipboard()->setText(clipboard_text);
Manager* manager = Manager::getDefault();
clipboard_text = (text ? text: "");
manager->getClipboard()->setText(
manager->getDisplay()->nativeHandle(),
clipboard_text);
}
} // namespace clipboard

View File

@ -348,7 +348,7 @@ gfx::Size Graphics::doUIStringAlgorithm(const std::string& str, gfx::Color fg, g
ScreenGraphics::ScreenGraphics()
: Graphics(she::instance()->defaultDisplay()->getSurface(), 0, 0)
{
setFont(CurrentTheme::get()->default_font);
setFont(CurrentTheme::get()->getDefaultFont());
}
ScreenGraphics::~ScreenGraphics()

View File

@ -242,7 +242,10 @@ void Manager::generateMessagesFromSheEvents()
// Events from "she" layer.
she::Event sheEvent;
for (;;) {
m_eventQueue->getEvent(sheEvent);
// bool canWait = (msg_queue.empty());
bool canWait = false;
m_eventQueue->getEvent(sheEvent, canWait);
if (sheEvent.type() == she::Event::None)
break;

View File

@ -29,15 +29,11 @@ Theme::Theme()
: m_guiscale(1)
{
this->name = "Theme";
this->default_font = she::instance()->defaultFont();
this->scrollbar_size = 0;
}
Theme::~Theme()
{
if (default_font)
default_font->dispose();
if (current_theme == this)
CurrentTheme::set(NULL);
}

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013 David Capello
// Copyright (C) 2001-2013, 2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -28,7 +28,6 @@ namespace ui {
class Theme {
public:
const char* name;
she::Font* default_font;
int scrollbar_size;
Theme();
@ -39,6 +38,8 @@ namespace ui {
int guiscale() const { return m_guiscale; }
void setScale(int value) { m_guiscale = value; }
virtual she::Font* getDefaultFont() const = 0;
virtual Cursor* getCursor(CursorType type) = 0;
virtual void initWidget(Widget* widget) = 0;
virtual void getWindowMask(Widget* widget, gfx::Region& region) = 0;

View File

@ -80,7 +80,7 @@ Widget::Widget(WidgetType type)
this->m_theme = CurrentTheme::get();
this->m_align = 0;
this->m_font = (this->m_theme ? this->m_theme->default_font: NULL);
this->m_font = (this->m_theme ? this->m_theme->getDefaultFont(): nullptr);
this->m_bgColor = gfx::ColorNone;
m_preferredSize = NULL;
@ -187,7 +187,7 @@ void Widget::setTheme(Theme* theme)
m_theme = theme;
// TODO maybe some Style in Widget should be great
setFont(m_theme ? m_theme->default_font: NULL);
setFont(m_theme ? m_theme->getDefaultFont(): nullptr);
}
// ===============================================================

View File

@ -1,5 +1,5 @@
# ASEPRITE
# Copyright (C) 2001-2013 David Capello
# Copyright (C) 2001-2015 David Capello
include_directories(.)
@ -37,8 +37,8 @@ if(ENABLE_UPDATER AND NOT USE_SHARED_CURL)
add_subdirectory(curl)
endif()
if(NOT USE_SHARED_LIBLOADPNG)
add_subdirectory(loadpng)
if(USE_ALLEG4_BACKEND AND NOT USE_SHARED_LIBLOADPNG)
add_subdirectory(loadpng)
endif()
if(ENABLE_WEBSERVER)

View File

@ -1,5 +1,7 @@
# ASEPRITE
# Copyright (C) 2001-2013 David Capello
# Copyright (C) 2001-2015 David Capello
include(CheckIncludeFiles)
include_directories(
lib