diff --git a/src/she/display.h b/src/she/display.h index abd4a566e..b3101529d 100644 --- a/src/she/display.h +++ b/src/she/display.h @@ -9,8 +9,9 @@ namespace she { - class Surface; + class EventQueue; class NotDisposableSurface; + class Surface; // A display or window to show graphics. class Display { @@ -43,6 +44,8 @@ namespace she { virtual void maximize() = 0; virtual bool isMaximized() const = 0; + virtual EventQueue* getEventQueue() = 0; + // Returns the HWND on Windows. virtual void* nativeHandle() = 0; }; diff --git a/src/she/event.h b/src/she/event.h new file mode 100644 index 000000000..4d3d1e5a2 --- /dev/null +++ b/src/she/event.h @@ -0,0 +1,29 @@ +// SHE library +// Copyright (C) 2012-2014 David Capello +// +// This source file is ditributed under a BSD-like license, please +// read LICENSE.txt for more information. + +#ifndef SHE_EVENT_H_INCLUDED +#define SHE_EVENT_H_INCLUDED + +namespace she { + + class Event { + public: + enum Type { + None, + }; + + Event() : m_type(None) { } + + int type() const { return m_type; } + void setType(Type type) { m_type = type; } + + private: + Type m_type; + }; + +} // namespace she + +#endif diff --git a/src/she/event_loop.h b/src/she/event_queue.h similarity index 59% rename from src/she/event_loop.h rename to src/she/event_queue.h index fb5aeb398..ee3bcfeae 100644 --- a/src/she/event_loop.h +++ b/src/she/event_queue.h @@ -4,15 +4,18 @@ // This source file is ditributed under a BSD-like license, please // read LICENSE.txt for more information. -#ifndef SHE_EVENT_LOOP_H_INCLUDED -#define SHE_EVENT_LOOP_H_INCLUDED +#ifndef SHE_EVENT_QUEUE_H_INCLUDED +#define SHE_EVENT_QUEUE_H_INCLUDED namespace she { - class EventLoop { + class Event; + + class EventQueue { public: - virtual ~EventLoop() { } + virtual ~EventQueue() { } virtual void dispose() = 0; + virtual void getEvent(Event& ev) = 0; }; } // namespace she diff --git a/src/she/she.h b/src/she/she.h index c829255c4..3a1096ac7 100644 --- a/src/she/she.h +++ b/src/she/she.h @@ -8,7 +8,8 @@ #define SHE_H_INCLUDED #include "she/display.h" -#include "she/event_loop.h" +#include "she/event.h" +#include "she/event_queue.h" #include "she/locked_surface.h" #include "she/scoped_handle.h" #include "she/scoped_surface_lock.h" diff --git a/src/she/she_alleg4.cpp b/src/she/she_alleg4.cpp index 06f3f50a5..fa1a6373e 100644 --- a/src/she/she_alleg4.cpp +++ b/src/she/she_alleg4.cpp @@ -12,12 +12,21 @@ #include #include -#ifdef ALLEGRO_WINDOWS + +#ifdef WIN32 #include + + #if defined STRICT || defined __GNUC__ + typedef WNDPROC wndproc_t; + #else + typedef FARPROC wndproc_t; + #endif #endif + #include "loadpng.h" #include +#include #define DISPLAY_FLAG_FULL_REFRESH 1 #define DISPLAY_FLAG_WINDOW_RESIZE 2 @@ -125,6 +134,60 @@ private: DestroyFlag m_destroy; }; +class Alleg4EventQueue : public EventQueue { +public: + Alleg4EventQueue() { + } + + void dispose() { + delete this; + } + + void getEvent(Event& event) { + if (m_events.size() > 0) { + event = m_events[0]; + m_events.erase(m_events.begin()); + } + else + event.setType(Event::None); + } + + void queueEvent(const Event& event) { + m_events.push_back(event); + } + +private: + std::vector m_events; +}; + +#if WIN32 +namespace { + +Display* g_display = NULL; +wndproc_t base_wndproc = NULL; + +static LRESULT CALLBACK wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + // TODO + // switch (msg) { + // } + return ::CallWindowProc(base_wndproc, hwnd, msg, wparam, lparam); +} + +void subclass_hwnd(HWND hwnd) +{ + base_wndproc = (wndproc_t)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc); +} + +void unsubclass_hwnd(HWND hwnd) +{ + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)base_wndproc); + base_wndproc = NULL; +} + +} +#endif + class Alleg4Display : public Display { public: Alleg4Display(int width, int height, int scale) @@ -150,6 +213,8 @@ public: setScale(scale); + m_queue = new Alleg4EventQueue(); + // Add a hook to display-switch so when the user returns to the // screen it's completelly refreshed/redrawn. LOCK_VARIABLE(display_flags); @@ -160,9 +225,19 @@ public: // Setup the handler for window-resize events set_resize_callback(resize_callback); #endif + +#if WIN32 + subclass_hwnd((HWND)nativeHandle()); +#endif WIN32 } ~Alleg4Display() { + delete m_queue; + +#if WIN32 + unsubclass_hwnd((HWND)nativeHandle()); +#endif WIN32 + m_surface->dispose(); set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); } @@ -246,6 +321,10 @@ public: #endif } + EventQueue* getEventQueue() { + return m_queue; + } + void* nativeHandle() { #ifdef WIN32 return reinterpret_cast(win_get_window()); @@ -257,16 +336,7 @@ public: private: Surface* m_surface; int m_scale; -}; - -class Alleg4EventLoop : public EventLoop { -public: - Alleg4EventLoop() { - } - - void dispose() { - delete this; - } + Alleg4EventQueue* m_queue; }; class Alleg4System : public System { @@ -307,10 +377,6 @@ public: Alleg4Surface::AutoDestroy); } - EventLoop* createEventLoop() { - return new Alleg4EventLoop(); - } - }; static System* g_instance; diff --git a/src/she/system.h b/src/she/system.h index ebf8e9287..90b83918b 100644 --- a/src/she/system.h +++ b/src/she/system.h @@ -30,7 +30,6 @@ namespace she { virtual Display* createDisplay(int width, int height, int scale) = 0; virtual Surface* createSurface(int width, int height) = 0; virtual Surface* createSurfaceFromNativeHandle(void* nativeHandle) = 0; - virtual EventLoop* createEventLoop() = 0; }; System* CreateSystem(); diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp index 50896b4c3..fa797de01 100644 --- a/src/ui/manager.cpp +++ b/src/ui/manager.cpp @@ -13,6 +13,9 @@ #include "ui/manager.h" +#include "she/display.h" +#include "she/event.h" +#include "she/event_queue.h" #include "ui/intern.h" #include "ui/ui.h" @@ -106,6 +109,8 @@ static void allegro_window_close_hook() Manager::Manager() : Widget(kManagerWidget) + , m_display(NULL) + , m_eventQueue(NULL) { if (!m_defaultManager) { // Hook the window close message @@ -173,6 +178,12 @@ Manager::~Manager() } } +void Manager::setDisplay(she::Display* display) +{ + m_display = display; + m_eventQueue = m_display->getEventQueue(); +} + void Manager::run() { MessageLoop loop(this); @@ -442,6 +453,18 @@ bool Manager::generateMessages() } } + // Events from "she" layer. + she::Event sheEvent; + for (;;) { + m_eventQueue->getEvent(sheEvent); + if (sheEvent.type() == she::Event::None) + break; + + // TODO + // switch (sheEvent.type()) { + // } + } + // Generate messages for timers Timer::pollTimers(); diff --git a/src/ui/manager.h b/src/ui/manager.h index e0bee7a96..0045854d5 100644 --- a/src/ui/manager.h +++ b/src/ui/manager.h @@ -12,7 +12,10 @@ #include "ui/mouse_buttons.h" #include "ui/widget.h" -namespace she { class Display; } +namespace she { + class Display; + class EventQueue; +} namespace ui { @@ -31,7 +34,7 @@ namespace ui { ~Manager(); she::Display* getDisplay() { return m_display; } - void setDisplay(she::Display* display) { m_display = display; } + void setDisplay(she::Display* display); void run(); @@ -99,6 +102,7 @@ namespace ui { WidgetsList m_garbage; she::Display* m_display; + she::EventQueue* m_eventQueue; }; } // namespace ui