Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:24

0001 /*
0002  * GLEQ - A basic event queue for GLFW 3
0003  * Copyright © Camilla Löwy <elmindreda@glfw.org>
0004  *
0005  * This software is provided 'as-is', without any express or implied
0006  * warranty. In no event will the authors be held liable for any damages
0007  * arising from the use of this software.
0008  *
0009  * Permission is granted to anyone to use this software for any purpose,
0010  * including commercial applications, and to alter it and redistribute it
0011  * freely, subject to the following restrictions:
0012  *
0013  * 1. The origin of this software must not be misrepresented; you must not
0014  *    claim that you wrote the original software. If you use this software
0015  *    in a product, an acknowledgment in the product documentation would
0016  *    be appreciated but is not required.
0017  *
0018  * 2. Altered source versions must be plainly marked as such, and must not
0019  *    be misrepresented as being the original software.
0020  *
0021  * 3. This notice may not be removed or altered from any source
0022  *    distribution.
0023  */
0024 
0025 #ifndef GLEQ_HEADER_FILE
0026 #define GLEQ_HEADER_FILE
0027 
0028 #include <GLFW/glfw3.h>
0029 
0030 #ifdef GLEQ_STATIC
0031     #define GLEQDEF static
0032 #else
0033     #define GLEQDEF extern
0034 #endif
0035 
0036 #ifdef __cplusplus
0037 extern "C" {
0038 #endif
0039 
0040 typedef enum
0041 {
0042     GLEQ_NONE,
0043     GLEQ_WINDOW_MOVED,
0044     GLEQ_WINDOW_RESIZED,
0045     GLEQ_WINDOW_CLOSED,
0046     GLEQ_WINDOW_REFRESH,
0047     GLEQ_WINDOW_FOCUSED,
0048     GLEQ_WINDOW_DEFOCUSED,
0049     GLEQ_WINDOW_ICONIFIED,
0050     GLEQ_WINDOW_UNICONIFIED,
0051     GLEQ_FRAMEBUFFER_RESIZED,
0052     GLEQ_BUTTON_PRESSED,
0053     GLEQ_BUTTON_RELEASED,
0054     GLEQ_CURSOR_MOVED,
0055     GLEQ_CURSOR_ENTERED,
0056     GLEQ_CURSOR_LEFT,
0057     GLEQ_SCROLLED,
0058     GLEQ_KEY_PRESSED,
0059     GLEQ_KEY_REPEATED,
0060     GLEQ_KEY_RELEASED,
0061     GLEQ_CODEPOINT_INPUT,
0062     GLEQ_MONITOR_CONNECTED,
0063     GLEQ_MONITOR_DISCONNECTED,
0064 #if GLFW_VERSION_MINOR >= 1
0065     GLEQ_FILE_DROPPED,
0066 #endif
0067 #if GLFW_VERSION_MINOR >= 2
0068     GLEQ_JOYSTICK_CONNECTED,
0069     GLEQ_JOYSTICK_DISCONNECTED,
0070 #endif
0071 #if GLFW_VERSION_MINOR >= 3
0072     GLEQ_WINDOW_MAXIMIZED,
0073     GLEQ_WINDOW_UNMAXIMIZED,
0074     GLEQ_WINDOW_SCALE_CHANGED,
0075 #endif
0076 } GLEQtype;
0077 
0078 typedef struct GLEQevent
0079 {
0080     GLEQtype type;
0081     union {
0082         GLFWwindow* window;
0083         GLFWmonitor* monitor;
0084         int joystick;
0085     };
0086     union {
0087         struct {
0088             int x;
0089             int y;
0090         } pos;
0091         struct {
0092             int width;
0093             int height;
0094         } size;
0095         struct {
0096             double x;
0097             double y;
0098         } scroll;
0099         struct {
0100             int key;
0101             int scancode;
0102             int mods;
0103         } keyboard;
0104         struct {
0105             int button;
0106             int mods;
0107         } mouse;
0108         unsigned int codepoint;
0109 #if GLFW_VERSION_MINOR >= 1
0110         struct {
0111             char** paths;
0112             int count;
0113         } file;
0114 #endif
0115 #if GLFW_VERSION_MINOR >= 3
0116         struct {
0117             float x;
0118             float y;
0119         } scale;
0120 #endif
0121     };
0122 } GLEQevent;
0123 
0124 GLEQDEF void gleqInit(void);
0125 GLEQDEF void gleqTrackWindow(GLFWwindow* window);
0126 
0127 GLEQDEF int gleqNextEvent(GLEQevent* event);
0128 GLEQDEF void gleqFreeEvent(GLEQevent* event);
0129 
0130 #ifdef __cplusplus
0131 }
0132 #endif
0133 
0134 #ifdef GLEQ_IMPLEMENTATION
0135 
0136 #include <stdlib.h>
0137 #include <string.h>
0138 #include <assert.h>
0139 
0140 #ifndef GLEQ_CAPACITY
0141     #define GLEQ_CAPACITY 1024
0142 #endif
0143 
0144 static struct
0145 {
0146     GLEQevent events[GLEQ_CAPACITY];
0147     size_t head;
0148     size_t tail;
0149 } gleq_queue = { {}, 0, 0 };
0150 
0151 static char* gleq_strdup(const char* string)
0152 {
0153     const size_t size = strlen(string) + 1;
0154     char* result = (char*) malloc(size);
0155     memcpy(result, string, size);
0156     return result;
0157 }
0158 
0159 static GLEQevent* gleq_new_event(void)
0160 {
0161     GLEQevent* event = gleq_queue.events + gleq_queue.head;
0162     gleq_queue.head = (gleq_queue.head + 1) % GLEQ_CAPACITY;
0163     assert(gleq_queue.head != gleq_queue.tail);
0164     memset(event, 0, sizeof(GLEQevent));
0165     return event;
0166 }
0167 
0168 static void gleq_window_pos_callback(GLFWwindow* window, int x, int y)
0169 {
0170     GLEQevent* event = gleq_new_event();
0171     event->type = GLEQ_WINDOW_MOVED;
0172     event->window = window;
0173     event->pos.x = x;
0174     event->pos.y = y;
0175 }
0176 
0177 static void gleq_window_size_callback(GLFWwindow* window, int width, int height)
0178 {
0179     GLEQevent* event = gleq_new_event();
0180     event->type = GLEQ_WINDOW_RESIZED;
0181     event->window = window;
0182     event->size.width = width;
0183     event->size.height = height;
0184 }
0185 
0186 static void gleq_window_close_callback(GLFWwindow* window)
0187 {
0188     GLEQevent* event = gleq_new_event();
0189     event->type = GLEQ_WINDOW_CLOSED;
0190     event->window = window;
0191 }
0192 
0193 static void gleq_window_refresh_callback(GLFWwindow* window)
0194 {
0195     GLEQevent* event = gleq_new_event();
0196     event->type = GLEQ_WINDOW_REFRESH;
0197     event->window = window;
0198 }
0199 
0200 static void gleq_window_focus_callback(GLFWwindow* window, int focused)
0201 {
0202     GLEQevent* event = gleq_new_event();
0203     event->window = window;
0204 
0205     if (focused)
0206         event->type = GLEQ_WINDOW_FOCUSED;
0207     else
0208         event->type = GLEQ_WINDOW_DEFOCUSED;
0209 }
0210 
0211 static void gleq_window_iconify_callback(GLFWwindow* window, int iconified)
0212 {
0213     GLEQevent* event = gleq_new_event();
0214     event->window = window;
0215 
0216     if (iconified)
0217         event->type = GLEQ_WINDOW_ICONIFIED;
0218     else
0219         event->type = GLEQ_WINDOW_UNICONIFIED;
0220 }
0221 
0222 static void gleq_framebuffer_size_callback(GLFWwindow* window, int width, int height)
0223 {
0224     GLEQevent* event = gleq_new_event();
0225     event->type = GLEQ_FRAMEBUFFER_RESIZED;
0226     event->window = window;
0227     event->size.width = width;
0228     event->size.height = height;
0229 }
0230 
0231 static void gleq_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
0232 {
0233     GLEQevent* event = gleq_new_event();
0234     event->window = window;
0235     event->mouse.button = button;
0236     event->mouse.mods = mods;
0237 
0238     if (action == GLFW_PRESS)
0239         event->type = GLEQ_BUTTON_PRESSED;
0240     else if (action == GLFW_RELEASE)
0241         event->type = GLEQ_BUTTON_RELEASED;
0242 }
0243 
0244 static void gleq_cursor_pos_callback(GLFWwindow* window, double x, double y)
0245 {
0246     GLEQevent* event = gleq_new_event();
0247     event->type = GLEQ_CURSOR_MOVED;
0248     event->window = window;
0249     event->pos.x = (int) x;
0250     event->pos.y = (int) y;
0251 }
0252 
0253 static void gleq_cursor_enter_callback(GLFWwindow* window, int entered)
0254 {
0255     GLEQevent* event = gleq_new_event();
0256     event->window = window;
0257 
0258     if (entered)
0259         event->type = GLEQ_CURSOR_ENTERED;
0260     else
0261         event->type = GLEQ_CURSOR_LEFT;
0262 }
0263 
0264 static void gleq_scroll_callback(GLFWwindow* window, double x, double y)
0265 {
0266     GLEQevent* event = gleq_new_event();
0267     event->type = GLEQ_SCROLLED;
0268     event->window = window;
0269     event->scroll.x = x;
0270     event->scroll.y = y;
0271 }
0272 
0273 static void gleq_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
0274 {
0275     GLEQevent* event = gleq_new_event();
0276     event->window = window;
0277     event->keyboard.key = key;
0278     event->keyboard.scancode = scancode;
0279     event->keyboard.mods = mods;
0280 
0281     if (action == GLFW_PRESS)
0282         event->type = GLEQ_KEY_PRESSED;
0283     else if (action == GLFW_RELEASE)
0284         event->type = GLEQ_KEY_RELEASED;
0285     else if (action == GLFW_REPEAT)
0286         event->type = GLEQ_KEY_REPEATED;
0287 }
0288 
0289 static void gleq_char_callback(GLFWwindow* window, unsigned int codepoint)
0290 {
0291     GLEQevent* event = gleq_new_event();
0292     event->type = GLEQ_CODEPOINT_INPUT;
0293     event->window = window;
0294     event->codepoint = codepoint;
0295 }
0296 
0297 static void gleq_monitor_callback(GLFWmonitor* monitor, int action)
0298 {
0299     GLEQevent* event = gleq_new_event();
0300     event->monitor = monitor;
0301 
0302     if (action == GLFW_CONNECTED)
0303         event->type = GLEQ_MONITOR_CONNECTED;
0304     else if (action == GLFW_DISCONNECTED)
0305         event->type = GLEQ_MONITOR_DISCONNECTED;
0306 }
0307 
0308 #if GLFW_VERSION_MINOR >= 1
0309 static void gleq_file_drop_callback(GLFWwindow* window, int count, const char** paths)
0310 {
0311     GLEQevent* event = gleq_new_event();
0312     event->type = GLEQ_FILE_DROPPED;
0313     event->window = window;
0314     event->file.paths = (char**) malloc(count * sizeof(char*));
0315     event->file.count = count;
0316 
0317     while (count--)
0318         event->file.paths[count] = gleq_strdup(paths[count]);
0319 }
0320 #endif
0321 
0322 #if GLFW_VERSION_MINOR >= 2
0323 static void gleq_joystick_callback(int jid, int action)
0324 {
0325     GLEQevent* event = gleq_new_event();
0326     event->joystick = jid;
0327 
0328     if (action == GLFW_CONNECTED)
0329         event->type = GLEQ_JOYSTICK_CONNECTED;
0330     else if (action == GLFW_DISCONNECTED)
0331         event->type = GLEQ_JOYSTICK_DISCONNECTED;
0332 }
0333 #endif
0334 
0335 #if GLFW_VERSION_MINOR >= 3
0336 static void gleq_window_maximize_callback(GLFWwindow* window, int maximized)
0337 {
0338     GLEQevent* event = gleq_new_event();
0339     event->window = window;
0340 
0341     if (maximized)
0342         event->type = GLEQ_WINDOW_MAXIMIZED;
0343     else
0344         event->type = GLEQ_WINDOW_UNMAXIMIZED;
0345 }
0346 
0347 static void gleq_window_content_scale_callback(GLFWwindow* window, float xscale, float yscale)
0348 {
0349     GLEQevent* event = gleq_new_event();
0350     event->window = window;
0351     event->type = GLEQ_WINDOW_SCALE_CHANGED;
0352     event->scale.x = xscale;
0353     event->scale.y = yscale;
0354 }
0355 #endif
0356 
0357 GLEQDEF void gleqInit(void)
0358 {
0359     glfwSetMonitorCallback(gleq_monitor_callback);
0360 #if GLFW_VERSION_MINOR >= 2
0361     //glfwSetJoystickCallback(gleq_joystick_callback);
0362 #endif
0363 }
0364 
0365 GLEQDEF void gleqTrackWindow(GLFWwindow* window)
0366 {
0367     glfwSetWindowPosCallback(window, gleq_window_pos_callback);
0368     glfwSetWindowSizeCallback(window, gleq_window_size_callback);
0369     glfwSetWindowCloseCallback(window, gleq_window_close_callback);
0370     glfwSetWindowRefreshCallback(window, gleq_window_refresh_callback);
0371     glfwSetWindowFocusCallback(window, gleq_window_focus_callback);
0372     glfwSetWindowIconifyCallback(window, gleq_window_iconify_callback);
0373     glfwSetFramebufferSizeCallback(window, gleq_framebuffer_size_callback);
0374     glfwSetMouseButtonCallback(window, gleq_mouse_button_callback);
0375     glfwSetCursorPosCallback(window, gleq_cursor_pos_callback);
0376     glfwSetCursorEnterCallback(window, gleq_cursor_enter_callback);
0377     glfwSetScrollCallback(window, gleq_scroll_callback);
0378     glfwSetKeyCallback(window, gleq_key_callback);
0379     glfwSetCharCallback(window, gleq_char_callback);
0380 #if GLFW_VERSION_MINOR >= 1
0381     glfwSetDropCallback(window, gleq_file_drop_callback);
0382 #endif
0383 #if GLFW_VERSION_MINOR >= 3
0384     glfwSetWindowMaximizeCallback(window, gleq_window_maximize_callback);
0385     glfwSetWindowContentScaleCallback(window, gleq_window_content_scale_callback);
0386 #endif
0387 }
0388 
0389 GLEQDEF int gleqNextEvent(GLEQevent* event)
0390 {
0391     memset(event, 0, sizeof(GLEQevent));
0392 
0393     if (gleq_queue.head != gleq_queue.tail)
0394     {
0395         *event = gleq_queue.events[gleq_queue.tail];
0396         gleq_queue.tail = (gleq_queue.tail + 1) % GLEQ_CAPACITY;
0397     }
0398 
0399     return event->type != GLEQ_NONE;
0400 }
0401 
0402 GLEQDEF void gleqFreeEvent(GLEQevent* event)
0403 {
0404 #if GLFW_VERSION_MINOR >= 1
0405     if (event->type == GLEQ_FILE_DROPPED)
0406     {
0407         while (event->file.count--)
0408             free(event->file.paths[event->file.count]);
0409 
0410         free(event->file.paths);
0411     }
0412 #endif
0413 
0414     memset(event, 0, sizeof(GLEQevent));
0415 }
0416 
0417 #endif /* GLEQ_IMPLEMENTATION */
0418 
0419 #endif /* GLEQ_HEADER_FILE */
0420