From e4bb2ec45b5eece368dd07f1b666530961555605 Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 4 Apr 2016 10:17:14 -0300 Subject: [PATCH] Initial commit for a new Skia/X11 port --- src/she/CMakeLists.txt | 49 +++++++++++----- src/she/event.h | 5 ++ src/she/skia/she.cpp | 7 +++ src/she/skia/skia_system.h | 9 ++- src/she/skia/skia_window.h | 4 +- src/she/skia/skia_window_x11.cpp | 96 ++++++++++++++++++++++++++++++++ src/she/skia/skia_window_x11.h | 58 +++++++++++++++++++ src/she/x11/event_queue.h | 51 +++++++++++++++++ src/she/x11/keys.cpp | 20 +++++++ src/she/x11/window.h | 74 ++++++++++++++++++++++++ src/she/x11/x11.cpp | 24 ++++++++ src/she/x11/x11.h | 40 +++++++++++++ 12 files changed, 419 insertions(+), 18 deletions(-) create mode 100644 src/she/skia/skia_window_x11.cpp create mode 100644 src/she/skia/skia_window_x11.h create mode 100644 src/she/x11/event_queue.h create mode 100644 src/she/x11/keys.cpp create mode 100644 src/she/x11/window.h create mode 100644 src/she/x11/x11.cpp create mode 100644 src/she/x11/x11.h diff --git a/src/she/CMakeLists.txt b/src/she/CMakeLists.txt index 81c02fbbd..d771d5142 100644 --- a/src/she/CMakeLists.txt +++ b/src/she/CMakeLists.txt @@ -61,6 +61,8 @@ if(USE_SKIA_BACKEND) # Use Automatic Reference Counting add_definitions(-fobjc-arc) + else() + add_definitions(-DSK_SAMPLES_FOR_X) endif() if(CMAKE_BUILD_TYPE STREQUAL Debug) @@ -75,7 +77,9 @@ if(USE_SKIA_BACKEND) 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_AVX_LIBRARY skia_opts_avx PATH "${SKIA_BUILD_OUT_DIR}") + find_library(SKIA_OPTS_AVX2_LIBRARY skia_opts_avx2 PATH "${SKIA_BUILD_OUT_DIR}") find_library(SKIA_OPTS_SSE41_LIBRARY skia_opts_sse41 PATH "${SKIA_BUILD_OUT_DIR}") + find_library(SKIA_OPTS_SSE42_LIBRARY skia_opts_sse42 PATH "${SKIA_BUILD_OUT_DIR}") find_library(SKIA_OPTS_SSSE3_LIBRARY skia_opts_ssse3 PATH "${SKIA_BUILD_OUT_DIR}") find_library(SKIA_OPTS_AVX_LIBRARY skia_opts_avx PATH "${SKIA_BUILD_OUT_DIR}") find_library(SKIA_PORTS_LIBRARY skia_ports PATH "${SKIA_BUILD_OUT_DIR}") @@ -89,9 +93,14 @@ if(USE_SKIA_BACKEND) set(SKIA_GPU_LIBRARY "") endif() + find_library(SKIA_ETC1_LIBRARY etc1 PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp") + find_library(SKIA_FLAGS_LIBRARY flags PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp") + if(NOT SKIA_FLAGS_LIBRARY_FOUND) + set(SKIA_FLAGS_LIBRARY "") + endif() + + find_library(SKIA_LIBSKKTX_LIBRARY SkKTX PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp") if(WIN32) - find_library(SKIA_ETC1_LIBRARY libetc1 PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp") - find_library(SKIA_LIBSKKTX_LIBRARY libSkKTX PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp") if(SKIA_GPU_LIBRARY_FOUND) find_library(SKIA_OPENGL_LIBRARY opengl32) find_library(SKIA_LIBEGL_LIBRARY libEGL.dll PATH "${SKIA_BUILD_OUT_DIR}") @@ -100,8 +109,6 @@ if(USE_SKIA_BACKEND) endif() endif() else() - find_library(SKIA_ETC1_LIBRARY etc1 PATH "${SKIA_BUILD_OUT_DIR}") - find_library(SKIA_LIBSKKTX_LIBRARY SkKTX PATH "${SKIA_BUILD_OUT_DIR}") if(SKIA_GPU_LIBRARY_FOUND) find_library(SKIA_OPENGL_LIBRARY opengl) endif() @@ -141,22 +148,27 @@ if(USE_SKIA_BACKEND) set(SKIA_LIBRARIES ${SKIA_ETC1_LIBRARY} + ${SKIA_FLAGS_LIBRARY} ${SKIA_LIBSKKTX_LIBRARY} - ${SKIA_OPENGL_LIBRARY} - ${SKIA_LIBEGL_LIBRARY} ${SKIA_CORE_LIBRARY} - ${SKIA_EFFECTS_LIBRARY} - ${SKIA_GPU_LIBRARY} ${SKIA_IMAGES_LIBRARY} ${SKIA_OPTS_LIBRARY} - ${SKIA_OPTS_AVX_LIBRARY} - ${SKIA_OPTS_SSE41_LIBRARY} ${SKIA_OPTS_SSSE3_LIBRARY} + ${SKIA_OPTS_SSE41_LIBRARY} + ${SKIA_OPTS_SSE42_LIBRARY} ${SKIA_OPTS_AVX_LIBRARY} + ${SKIA_OPTS_AVX2_LIBRARY} ${SKIA_PORTS_LIBRARY} - ${SKIA_SFNT_LIBRARY} - ${SKIA_UTILS_LIBRARY} + ${SKIA_EFFECTS_LIBRARY} + # We've to include two times skia_core as a dependency as it looks + # like Skia libraries depends one each other (core+ports+effects) + ${SKIA_CORE_LIBRARY} ${SKIA_MISSING_FILES} + ${SKIA_UTILS_LIBRARY} + ${SKIA_SFNT_LIBRARY} + ${SKIA_OPENGL_LIBRARY} + ${SKIA_LIBEGL_LIBRARY} + ${SKIA_GPU_LIBRARY} CACHE INTERNAL "Skia libraries") list(APPEND SHE_SOURCES @@ -168,9 +180,7 @@ if(USE_SKIA_BACKEND) skia/skia_window_win.cpp win/vk.cpp win/window_dde.cpp) - endif() - - if(APPLE) + elseif(APPLE) list(APPEND SHE_SOURCES osx/app.mm osx/app_delegate.mm @@ -179,6 +189,11 @@ if(USE_SKIA_BACKEND) osx/vk.mm osx/window.mm skia/skia_window_osx.mm) + else() + list(APPEND SHE_SOURCES + skia/skia_window_x11.cpp + x11/keys.cpp + x11/x11.cpp) endif() endif() @@ -222,6 +237,10 @@ endif() if(USE_SKIA_BACKEND) target_link_libraries(she ${SKIA_LIBRARIES}) + + if(UNIX AND NOT APPLE) + target_link_libraries(she fontconfig) + endif() endif() if(WITH_GTK_FILE_DIALOG_SUPPORT) diff --git a/src/she/event.h b/src/she/event.h index 1b50bb313..b894a2a1d 100644 --- a/src/she/event.h +++ b/src/she/event.h @@ -15,6 +15,9 @@ #include #include +#pragma push_macro("None") +#undef None // Undefine the X11 None macro + namespace she { class Display; @@ -101,4 +104,6 @@ namespace she { } // namespace she +#pragma pop_macro("None") + #endif diff --git a/src/she/skia/she.cpp b/src/she/skia/she.cpp index 94c03b07e..de5674b31 100644 --- a/src/she/skia/she.cpp +++ b/src/she/skia/she.cpp @@ -20,6 +20,8 @@ #if __APPLE__ #include "she/osx/app.h" #include +#elif !defined(_WIN32) + #include "she/x11/x11.h" #endif namespace she { @@ -76,6 +78,11 @@ int main(int argc, char* argv[]) she::OSXApp app; return app.run(argc, argv); #else + +#ifndef _WIN32 + she::X11 x11; +#endif + return app_main(argc, argv); #endif } diff --git a/src/she/skia/skia_system.h b/src/she/skia/skia_system.h index 1ff2c27d8..fcee2c9fb 100644 --- a/src/she/skia/skia_system.h +++ b/src/she/skia/skia_system.h @@ -23,7 +23,7 @@ #elif __APPLE__ #include "she/osx/event_queue.h" #else - #error There is no EventQueue implementation for your platform + #include "she/x11/event_queue.h" #endif namespace she { @@ -35,6 +35,13 @@ public: SkiaSystem() : m_defaultDisplay(nullptr) , m_gpuAcceleration(false) { +#if !defined(__APPLE__) && !defined(_WIN32) + // Create one decoder on Linux to load .png files with + // libpng. Without this, SkImageDecoder::Factory() returns null + // for .png files. + SkAutoTDelete decoder( + CreatePNGImageDecoder()); +#endif } ~SkiaSystem() { diff --git a/src/she/skia/skia_window.h b/src/she/skia/skia_window.h index fc06882fe..7d0074ce4 100644 --- a/src/she/skia/skia_window.h +++ b/src/she/skia/skia_window.h @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2012-2015 David Capello +// Copyright (C) 2012-2016 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -13,7 +13,7 @@ #elif __APPLE__ #include "she/skia/skia_window_osx.h" #else - #error There is no SkiaWindow implementation for your platform + #include "she/skia/skia_window_x11.h" #endif #endif diff --git a/src/she/skia/skia_window_x11.cpp b/src/she/skia/skia_window_x11.cpp new file mode 100644 index 000000000..908e5b144 --- /dev/null +++ b/src/she/skia/skia_window_x11.cpp @@ -0,0 +1,96 @@ +// SHE library +// Copyright (C) 2016 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 "she/skia/skia_window_x11.h" + +#include "gfx/size.h" +#include "she/x11/x11.h" + +#include "SkBitmap.h" + + +namespace she { + +SkiaWindow::SkiaWindow(EventQueue* queue, SkiaDisplay* display, + int width, int height, int scale) + : X11Window(X11::instance()->display(), width, height) + , m_clientSize(width, height) + , m_scale(scale) +{ +} + +SkiaWindow::~SkiaWindow() +{ +} + +int SkiaWindow::scale() const +{ + return m_scale; +} + +void SkiaWindow::setScale(int scale) +{ + m_scale = scale; +} + +void SkiaWindow::setVisible(bool visible) +{ +} + +void SkiaWindow::maximize() +{ +} + +bool SkiaWindow::isMaximized() const +{ + return false; +} + +bool SkiaWindow::isMinimized() const +{ + return false; +} + +gfx::Size SkiaWindow::clientSize() const +{ + return m_clientSize; +} + +gfx::Size SkiaWindow::restoredSize() const +{ + return m_clientSize; +} + +void SkiaWindow::captureMouse() +{ +} + +void SkiaWindow::releaseMouse() +{ +} + +void SkiaWindow::setMousePosition(const gfx::Point& position) +{ +} + +bool SkiaWindow::setNativeMouseCursor(NativeCursor cursor) +{ + return false; +} + +void SkiaWindow::updateWindow(const gfx::Rect& bounds) +{ +} + +void SkiaWindow::onExpose() +{ +} + +} // namespace she diff --git a/src/she/skia/skia_window_x11.h b/src/she/skia/skia_window_x11.h new file mode 100644 index 000000000..18e34cd97 --- /dev/null +++ b/src/she/skia/skia_window_x11.h @@ -0,0 +1,58 @@ +// SHE library +// Copyright (C) 2016 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SHE_SKIA_SKIA_WINDOW_X11_INCLUDED +#define SHE_SKIA_SKIA_WINDOW_X11_INCLUDED +#pragma once + +#include "base/disable_copying.h" +#include "gfx/size.h" +#include "she/native_cursor.h" +#include "she/x11/window.h" + +#include + +namespace she { + +class EventQueue; +class SkiaDisplay; + +class SkiaWindow : public X11Window { +public: + enum class Backend { NONE, GL }; + + SkiaWindow(EventQueue* queue, SkiaDisplay* display, + int width, int height, int scale); + ~SkiaWindow(); + + int scale() const; + void setScale(int scale); + void setVisible(bool visible); + void maximize(); + bool isMaximized() const; + bool isMinimized() const; + gfx::Size clientSize() const; + gfx::Size restoredSize() const; + void captureMouse(); + void releaseMouse(); + void setMousePosition(const gfx::Point& position); + bool setNativeMouseCursor(NativeCursor cursor); + void updateWindow(const gfx::Rect& bounds); + std::string getLayout() { return ""; } + void setLayout(const std::string& layout) { } + +private: + void onExpose() override; + + gfx::Size m_clientSize; + int m_scale; + + DISABLE_COPYING(SkiaWindow); +}; + +} // namespace she + +#endif diff --git a/src/she/x11/event_queue.h b/src/she/x11/event_queue.h new file mode 100644 index 000000000..850228ca3 --- /dev/null +++ b/src/she/x11/event_queue.h @@ -0,0 +1,51 @@ +// SHE library +// Copyright (C) 2016 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SHE_X11_EVENT_QUEUE_INCLUDED +#define SHE_X11_EVENT_QUEUE_INCLUDED +#pragma once + +#include "she/event.h" +#include "she/event_queue.h" +#include "she/x11/x11.h" + +#include + +#pragma push_macro("None") +#undef None // Undefine the X11 None macro + +namespace she { + +class X11EventQueue : public EventQueue { +public: + void getEvent(Event& ev, bool canWait) override { + XEvent event; + XNextEvent(X11::instance()->display(), &event); + + if (m_events.empty()) { + ev.setType(Event::None); + } + else { + ev = m_events.front(); + m_events.pop(); + } + } + + void queueEvent(const Event& ev) override { + m_events.push(ev); + } + +private: + std::queue m_events; +}; + +typedef X11EventQueue EventQueueImpl; + +} // namespace she + +#pragma pop_macro("None") + +#endif diff --git a/src/she/x11/keys.cpp b/src/she/x11/keys.cpp new file mode 100644 index 000000000..303072fcc --- /dev/null +++ b/src/she/x11/keys.cpp @@ -0,0 +1,20 @@ +// SHE library +// Copyright (C) 2016 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 "she/keys.h" + +namespace she { + +bool is_key_pressed(KeyScancode scancode) +{ + return false; // TODO +} + +} // namespace she diff --git a/src/she/x11/window.h b/src/she/x11/window.h new file mode 100644 index 000000000..e608fe15c --- /dev/null +++ b/src/she/x11/window.h @@ -0,0 +1,74 @@ +// SHE library +// Copyright (C) 2016 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SHE_X11_WINDOW_INCLUDED +#define SHE_X11_WINDOW_INCLUDED +#pragma once + +#include +#include +#include + +#include + +namespace she { + +class X11Window { +public: + X11Window(::Display* display, int width, int height) + : m_display(display) { + ::Window root = XDefaultRootWindow(m_display); + + XSetWindowAttributes swa; + swa.event_mask = (StructureNotifyMask | ExposureMask | PropertyChangeMask | + EnterWindowMask | LeaveWindowMask | FocusChangeMask | + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | + KeyPressMask | KeyReleaseMask); + + m_window = XCreateWindow( + m_display, root, + 0, 0, width, height, 0, + CopyFromParent, + InputOutput, + CopyFromParent, + CWEventMask, + &swa); + + XMapWindow(m_display, m_window); + XSelectInput(m_display, m_window, StructureNotifyMask); + + m_gc = XCreateGC(m_display, m_window, 0, nullptr); + } + + ~X11Window() { + XFreeGC(m_display, m_gc); + XDestroyWindow(m_display, m_window); + } + + void setTitle(const std::string& title) { + XTextProperty prop; + prop.value = (unsigned char*)title.c_str(); + prop.encoding = XA_STRING; + prop.format = 8; + prop.nitems = std::strlen((char*)title.c_str()); + XSetWMName(m_display, m_window, &prop); + } + + virtual void onExpose() = 0; + + ::Display* display() const { return m_display; } + ::Window handle() const { return m_window; } + ::GC gc() const { return m_gc; } + +private: + ::Display* m_display; + ::Window m_window; + ::GC m_gc; +}; + +} // namespace she + +#endif diff --git a/src/she/x11/x11.cpp b/src/she/x11/x11.cpp new file mode 100644 index 000000000..3c1b6dbf6 --- /dev/null +++ b/src/she/x11/x11.cpp @@ -0,0 +1,24 @@ +// SHE library +// Copyright (C) 2016 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 "she/x11/x11.h" + +namespace she { + +X11* X11::m_instance = nullptr; + +// static +X11* X11::instance() +{ + ASSERT(m_instance); + return m_instance; +} + +} // namespace she diff --git a/src/she/x11/x11.h b/src/she/x11/x11.h new file mode 100644 index 000000000..967594614 --- /dev/null +++ b/src/she/x11/x11.h @@ -0,0 +1,40 @@ +// SHE library +// Copyright (C) 2016 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SHE_X11_X11_INCLUDED +#define SHE_X11_X11_INCLUDED +#pragma once + +#include + +namespace she { + +class X11 { + static X11* m_instance; +public: + static X11* instance(); + + X11() { + ASSERT(m_instance == nullptr); + m_instance = this; + m_display = XOpenDisplay(nullptr); + } + + ~X11() { + ASSERT(m_instance == this); + XCloseDisplay(m_display); + m_instance = nullptr; + } + + ::Display* display() const { return m_display; } + +private: + ::Display* m_display; +}; + +} // namespace she + +#endif