diff --git a/src/gui/Gui.h b/src/gui/Gui.h deleted file mode 100644 index e0cd38f..0000000 --- a/src/gui/Gui.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef GUI_H -#define GUI_H - -#include - -#define GUI_EVENT_CLOSE_WINDOW 1u -#define GUI_EVENT_EXPOSE 2u -#define GUI_EVENT_KEY_PRESS 3u -#define GUI_EVENT_KEY_RELEASE 4u -#define GUI_EVENT_BUTTON_PRESS 5u -#define GUI_EVENT_BUTTON_RELEASE 6u - -typedef struct -{ - uint32_t key; - uint8_t mods; -} Gui_KeyEvent; - -typedef struct -{ - uint8_t button; -} Gui_ButtonEvent; - -typedef struct -{ - uint8_t type; - union - { - Gui_KeyEvent key; - Gui_ButtonEvent button; - }; -} Gui_Event; - -bool Gui_Init(); -void * Gui_CreateWindow(); -void Gui_SwapBuffers(void * window); -void Gui_CloseWindow(void * window); -void Gui_WaitForEvent(Gui_Event * event); - -#endif diff --git a/src/gui/Window.cc b/src/gui/Window.cc index 219ead0..a06c4e6 100644 --- a/src/gui/Window.cc +++ b/src/gui/Window.cc @@ -2,7 +2,7 @@ #include "Window.h" #include "Runtime.h" #include "BufferPane.h" -#include "Gui.h" +#include "Jtk.h" #include #include "jes_icon-32x32.h" #include @@ -77,13 +77,13 @@ void Window::set_window_icon() */ bool Window::create(std::shared_ptr buffer) { - if (!Gui_Init()) + if (!Jtk_Init()) { std::cerr << "Error initializing GUI" << std::endl; return false; } - m_window = Gui_CreateWindow(); + m_window = Jtk_CreateWindow(); if (m_window == NULL) { std::cerr << "Error creating window" << std::endl; @@ -437,7 +437,7 @@ void Window::redraw() m_gl->draw_rect(0, m_command_buffer_screen_rows * m_font->get_line_height(), m_width, 1, 0.5, 0.5, 0.5, 1.0); m_command_buffer_pane->draw(); - Gui_SwapBuffers(m_window); + Jtk_SwapBuffers(m_window); } #if 0 diff --git a/src/gui/Gui-X.cc b/src/gui/jtk/Jtk-X.cc similarity index 90% rename from src/gui/Gui-X.cc rename to src/gui/jtk/Jtk-X.cc index 2a7011e..dd9af0b 100644 --- a/src/gui/Gui-X.cc +++ b/src/gui/jtk/Jtk-X.cc @@ -1,6 +1,6 @@ -#ifdef GUI_X +#ifdef JTK_X -#include "Gui.h" +#include "Jtk.h" #include #include @@ -15,11 +15,11 @@ static Bool WaitForNotify(Display * display, XEvent * event, XPointer arg) } /** - * Initialize the Gui subsystem. + * Initialize the Jtk subsystem. * * @return true on success, false on failure */ -bool Gui_Init() +bool Jtk_Init() { static int glx_attribute_list[] = { GLX_RGBA, @@ -60,7 +60,7 @@ bool Gui_Init() return true; } -void * Gui_CreateWindow() +void * Jtk_CreateWindow() { XEvent event; Window window = XCreateWindow(g_display, @@ -79,18 +79,14 @@ void * Gui_CreateWindow() return (void *)window; } -void Gui_SwapBuffers(void * window) +void Jtk_SwapBuffers(void * window) { glXSwapBuffers(g_display, (Window)window); } -void Gui_CloseWindow(void * window) +void Jtk_CloseWindow(void * window) { XDestroyWindow(g_display, (Window)window); } -void Gui_WaitForEvent(Gui_Event * event) -{ -} - #endif diff --git a/src/gui/jtk/Jtk.h b/src/gui/jtk/Jtk.h new file mode 100644 index 0000000..f132677 --- /dev/null +++ b/src/gui/jtk/Jtk.h @@ -0,0 +1,11 @@ +#ifndef JTK_H +#define JTK_H + +#include "Jtk_event.h" +#include "Jtk_time.h" +#include "Jtk_timer.h" +#include "Jtk_window.h" + +bool Jtk_Init(); + +#endif diff --git a/src/gui/jtk/Jtk_event.cc b/src/gui/jtk/Jtk_event.cc new file mode 100644 index 0000000..281c042 --- /dev/null +++ b/src/gui/jtk/Jtk_event.cc @@ -0,0 +1,5 @@ +#include "Jtk.h" + +void Jtk_WaitForEvent(Jtk_Event * event) +{ +} diff --git a/src/gui/jtk/Jtk_event.h b/src/gui/jtk/Jtk_event.h new file mode 100644 index 0000000..3fbedd0 --- /dev/null +++ b/src/gui/jtk/Jtk_event.h @@ -0,0 +1,43 @@ +#ifndef JTK_EVENT_H +#define JTK_EVENT_H + +#include +#include + +#define JTK_EVENT_CLOSE_WINDOW 1u +#define JTK_EVENT_EXPOSE 2u +#define JTK_EVENT_KEY_PRESS 3u +#define JTK_EVENT_KEY_RELEASE 4u +#define JTK_EVENT_BUTTON_PRESS 5u +#define JTK_EVENT_BUTTON_RELEASE 6u + +typedef struct +{ + uint32_t key; + uint8_t mods; +} Jtk_KeyEvent; + +typedef struct +{ + uint8_t button; +} Jtk_ButtonEvent; + +typedef struct +{ + size_t timer_id; +} Jtk_TimerEvent; + +typedef struct +{ + uint8_t type; + union + { + Jtk_KeyEvent key; + Jtk_ButtonEvent button; + Jtk_TimerEvent timer; + }; +} Jtk_Event; + +void Jtk_WaitForEvent(Jtk_Event * event); + +#endif diff --git a/src/gui/jtk/Jtk_time.cc b/src/gui/jtk/Jtk_time.cc new file mode 100644 index 0000000..bd07440 --- /dev/null +++ b/src/gui/jtk/Jtk_time.cc @@ -0,0 +1,9 @@ +#include "Jtk.h" +#include + +uint64_t Jtk_UsTime() +{ + struct timeval tv; + gettimeofday(&tv, nullptr); + return (uint64_t)tv.tv_sec * 1000000u + (uint64_t)tv.tv_usec; +} diff --git a/src/gui/jtk/Jtk_time.h b/src/gui/jtk/Jtk_time.h new file mode 100644 index 0000000..130bf75 --- /dev/null +++ b/src/gui/jtk/Jtk_time.h @@ -0,0 +1,9 @@ +#ifndef JTK_TIME_H +#define JTK_TIME_H + +#include "Jtk_timer.h" + +bool Jtk_Init(); +uint64_t Jtk_UsTime(); + +#endif diff --git a/src/gui/jtk/Jtk_timer.cc b/src/gui/jtk/Jtk_timer.cc new file mode 100644 index 0000000..557bf7e --- /dev/null +++ b/src/gui/jtk/Jtk_timer.cc @@ -0,0 +1,139 @@ +#include "Jtk.h" +#include +#include +#include + +typedef struct +{ + uint64_t next; /**< Time the timer next expires (us). */ + uint64_t interval; /**< Timer interval (us). */ + size_t id; /**< Timer ID. */ +} Timer; + +/** Vector used to allocate timer IDs. */ +static std::vector> g_timers; + +/** Linked list used to traverse all active timers. */ +static std::list> g_active_timers; + +static size_t AllocateTimerID() +{ + for (size_t i = 0; i < g_timers.size(); i++) + { + if (!g_timers[i]) + { + return i; + } + } + g_timers.push_back(nullptr); + return g_timers.size() - 1u; +} + +/** + * Add a timer. + * + * @param delay + * Delay time in milliseconds. + * @param interval + * Interval time in milliseconds. A value of 0 indicates that the timer + * is not periodic. + * + * @return + * Timer ID. + */ +size_t Jtk_AddTimer(uint32_t delay, uint32_t interval) +{ + uint64_t current_system_time = Jtk_UsTime(); + size_t timer_id = AllocateTimerID(); + auto timer = std::make_shared(); + timer->next = current_system_time + (delay * 1000u); + timer->interval = interval * 1000u; + timer->id = timer_id; + g_timers[timer_id] = timer; + g_active_timers.push_back(timer); + return timer_id; +} + +/** + * Remove a timer. + * + * @param timer_id + * The ID of the timer to remove. + */ +void Jtk_RemoveTimer(size_t timer_id) +{ + if (timer_id < g_timers.size()) + { + g_timers[timer_id] = nullptr; + auto timer = g_timers[timer_id]; + g_active_timers.remove(timer); + } +} + +/** + * Determine the amount of time until the next timer expires (in us). + * + * @return + * Time (in us) until the next timer expires. This will be 0 if an active + * timer has already expired, and will be (uint64_t)-1 if there are no + * active timers. + */ +uint64_t Jtk_TimeToNextTimerExpiration() +{ + uint64_t time = (uint64_t)-1; + uint64_t current_system_time = Jtk_UsTime(); + for (auto & timer : g_active_timers) + { + if (timer->next <= current_system_time) + { + return 0; + } + uint64_t time_until_this_timer = timer->next - current_system_time; + if (time_until_this_timer < time) + { + time = time_until_this_timer; + } + } + return time; +} + +/** + * Service a timer. + * + * This will increment the timer's next activation time by its interval, or + * for a timer with an interval of 0, will remove the timer. + * + * @param timer_id + * The ID of the timer to service. + */ +void Jtk_ServiceTimer(size_t timer_id) +{ + auto timer = g_timers[timer_id]; + if (timer->interval == 0u) + { + Jtk_RemoveTimer(timer_id); + } + else + { + timer->next += timer->interval; + } +} + +/** + * Return the ID of an expired timer. + * + * @return + * The ID of an expired timer, or (size_t)-1 if no timer is expired. + */ +size_t Jtk_GetExpiredTimer() +{ + uint64_t current_system_time = Jtk_UsTime(); + for (auto & timer : g_active_timers) + { + if (timer->next <= current_system_time) + { + return timer->id; + } + } + return (size_t)-1; +} diff --git a/src/gui/jtk/Jtk_timer.h b/src/gui/jtk/Jtk_timer.h new file mode 100644 index 0000000..ae6c93d --- /dev/null +++ b/src/gui/jtk/Jtk_timer.h @@ -0,0 +1,13 @@ +#ifndef JTK_TIMER_H +#define JTK_TIMER_H + +#include +#include + +size_t Jtk_AddTimer(uint32_t delay, uint32_t interval); +void Jtk_RemoveTimer(size_t timer_id); +uint64_t Jtk_TimeToNextTimerExpiration(); +void Jtk_ServiceTimer(size_t timer_id); +size_t Jtk_GetExpiredTimer(); + +#endif diff --git a/src/gui/jtk/Jtk_window.h b/src/gui/jtk/Jtk_window.h new file mode 100644 index 0000000..1046c93 --- /dev/null +++ b/src/gui/jtk/Jtk_window.h @@ -0,0 +1,8 @@ +#ifndef JTK_WINDOW_H +#define JTK_WINDOW_H + +void * Jtk_CreateWindow(); +void Jtk_SwapBuffers(void * window); +void Jtk_CloseWindow(void * window); + +#endif diff --git a/wscript b/wscript index 14a418c..c67b05a 100644 --- a/wscript +++ b/wscript @@ -25,11 +25,11 @@ def build(bld): libs = [] if platform.system() == "Linux": defines += ["PLATFORM_LINUX"] - defines += ["GUI_X"] + defines += ["JTK_X"] libs += ["dl", "GL", "X11"] elif platform.system() == "Windows": defines += ["PLATFORM_WINDOWS"] - defines += ["GUI_WINDOWS"] + defines += ["JTK_WINDOWS"] libs += ["opengl32"] defines += ['GLCXX_GL_INCLUDE="gl3w.h"'] sources = bld.path.ant_glob(["src/**/*.cc", "src/**/*.c", "libs/glcxx/src/glcxx/*"])