--- /dev/null
+/*
+ * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef ANBOX_PLATFORM_SDL_PLATFORM_H_
+#define ANBOX_PLATFORM_SDL_PLATFORM_H_
+
+#include "anbox/platform/sdl/window.h"
+#include "anbox/platform/sdl/sdl_wrapper.h"
+#include "anbox/platform/base_platform.h"
+#include "anbox/graphics/emugl/DisplayManager.h"
+#include "anbox/input/device.h"
+
+#include <map>
+#include <thread>
+
+class Renderer;
+
+namespace anbox {
+namespace input {
+class Device;
+class Manager;
+} // namespace input
+namespace wm {
+class Manager;
+} // namespace wm
+namespace platform {
+namespace sdl {
+class Platform : public std::enable_shared_from_this<Platform>,
+ public platform::BasePlatform,
+ public Window::Observer {
+ public:
+ Platform(const std::shared_ptr<input::Manager> &input_manager,
+ const Configuration &config);
+ ~Platform();
+
+ std::shared_ptr<wm::Window> create_window(
+ const anbox::wm::Task::Id &task,
+ const anbox::graphics::Rect &frame,
+ const std::string &title) override;
+
+ void window_deleted(const Window::Id &id) override;
+ void window_wants_focus(const Window::Id &id) override;
+ void window_moved(const Window::Id &id, const std::int32_t &x,
+ const std::int32_t &y) override;
+ void window_resized(const Window::Id &id, const std::int32_t &width,
+ const std::int32_t &height) override;
+
+ void set_renderer(const std::shared_ptr<Renderer> &renderer) override;
+ void set_window_manager(const std::shared_ptr<wm::Manager> &window_manager) override;
+
+ void set_clipboard_data(const ClipboardData &data) override;
+ ClipboardData get_clipboard_data() override;
+
+ std::shared_ptr<audio::Sink> create_audio_sink() override;
+ std::shared_ptr<audio::Source> create_audio_source() override;
+
+ bool supports_multi_window() const override;
+
+ private:
+ void process_events();
+ void process_input_event(const SDL_Event &event);
+
+ bool adjust_coordinates(std::int32_t &x, std::int32_t &y);
+ bool adjust_coordinates(SDL_Window *window, std::int32_t &x, std::int32_t &y);
+ bool calculate_touch_coordinates(const SDL_Event &event, std::int32_t &x,
+ std::int32_t &y);
+
+ static Window::Id next_window_id();
+ static constexpr std::uint32_t emulated_touch_id_ = 0;
+
+ std::shared_ptr<Renderer> renderer_;
+ std::shared_ptr<input::Manager> input_manager_;
+ std::shared_ptr<wm::Manager> window_manager_;
+ // We don't own the windows anymore after the got created by us so we
+ // need to be careful once we try to use them again.
+ std::map<Window::Id, std::weak_ptr<Window>> windows_;
+ std::shared_ptr<Window> current_window_;
+ std::thread event_thread_;
+ bool event_thread_running_;
+ std::shared_ptr<input::Device> pointer_;
+ std::shared_ptr<input::Device> keyboard_;
+ std::shared_ptr<input::Device> touch_;
+ graphics::Rect display_frame_;
+ bool window_size_immutable_ = false;
+ std::uint32_t focused_sdl_window_id_ = 0;
+ Configuration config_;
+
+ static const int MAX_FINGERS = 10;
+ static const int MAX_TRACKING_ID = 10;
+ int touch_slots[MAX_FINGERS];
+ int last_slot = -1;
+
+ int find_touch_slot(int id);
+ void push_slot(std::vector<input::Event> &touch_events, int slot);
+ void push_finger_down(int x, int y, int finger_id, std::vector<input::Event> &touch_events);
+ void push_finger_up(int finger_id, std::vector<input::Event> &touch_events);
+ void push_finger_motion(int x, int y, int finger_id, std::vector<input::Event> &touch_events);
+};
+} // namespace sdl
+} // namespace platform
+} // namespace anbox
+
+#endif