1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CAST_STANDALONE_RECEIVER_SDL_GLUE_H_ 6 #define CAST_STANDALONE_RECEIVER_SDL_GLUE_H_ 7 8 #include <stdint.h> 9 10 #pragma GCC diagnostic push 11 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" 12 #include <SDL2/SDL.h> 13 #pragma GCC diagnostic pop 14 15 #include <functional> 16 #include <memory> 17 #include <utility> 18 #include <vector> 19 20 #include "util/alarm.h" 21 22 namespace openscreen { 23 24 class TaskRunner; 25 26 namespace cast { 27 28 template <uint32_t subsystem> 29 class ScopedSDLSubSystem { 30 public: ScopedSDLSubSystem()31 ScopedSDLSubSystem() { SDL_InitSubSystem(subsystem); } ~ScopedSDLSubSystem()32 ~ScopedSDLSubSystem() { SDL_QuitSubSystem(subsystem); } 33 }; 34 35 // Macro that, for an SDL_Foo, generates code for: 36 // 37 // using SDLFooUniquePtr = std::unique_ptr<SDL_Foo, SDLFooDestroyer>; 38 // SDLFooUniquePtr MakeUniqueSDLFoo(...args...); 39 #define DEFINE_SDL_UNIQUE_PTR(name) \ 40 struct SDL##name##Destroyer { \ 41 void operator()(SDL_##name* obj) const { \ 42 if (obj) { \ 43 SDL_Destroy##name(obj); \ 44 } \ 45 } \ 46 }; \ 47 using SDL##name##UniquePtr = \ 48 std::unique_ptr<SDL_##name, SDL##name##Destroyer>; \ 49 template <typename... Args> \ 50 SDL##name##UniquePtr MakeUniqueSDL##name(Args&&... args) { \ 51 return SDL##name##UniquePtr( \ 52 SDL_Create##name(std::forward<Args>(args)...)); \ 53 } 54 55 DEFINE_SDL_UNIQUE_PTR(Window); 56 DEFINE_SDL_UNIQUE_PTR(Renderer); 57 DEFINE_SDL_UNIQUE_PTR(Texture); 58 59 #undef DEFINE_SDL_UNIQUE_PTR 60 61 // A looping mechanism that runs the SDL event loop by scheduling periodic tasks 62 // to the given TaskRunner. Looping continues indefinitely, until the instance 63 // is destroyed. A client-provided quit callback is invoked whenever a SDL_QUIT 64 // event is received. 65 class SDLEventLoopProcessor { 66 public: 67 SDLEventLoopProcessor(TaskRunner* task_runner, 68 std::function<void()> quit_callback); 69 ~SDLEventLoopProcessor(); 70 71 using KeyboardEventCallback = std::function<void(const SDL_KeyboardEvent&)>; 72 void RegisterForKeyboardEvent(KeyboardEventCallback cb); 73 74 private: 75 void ProcessPendingEvents(); 76 77 Alarm alarm_; 78 std::function<void()> quit_callback_; 79 std::vector<KeyboardEventCallback> keyboard_callbacks_; 80 }; 81 82 } // namespace cast 83 } // namespace openscreen 84 85 #endif // CAST_STANDALONE_RECEIVER_SDL_GLUE_H_ 86