#include #include #include #include #include "types.h" #include "window.h" static void init_glfw(void (*error_callback)(int, const char *)) { log_info("[GLFW] Initializing..."); // set errors handler glfwSetErrorCallback(error_callback); // print current GLFW version log_info("[GLFW] %s", glfwGetVersionString()); // init GLFW if (!glfwInit()) { log_error("[GLFW] Initialization failed"); exit(EXIT_FAILURE); } log_info("[GLFW] Initialized..."); } static GLFWmonitor *get_monitor(unsigned char monitor_index) { int count; GLFWmonitor **monitors; // detect monitors monitors = glfwGetMonitors(&count); // check selected monitor availability if (monitor_index >= count) { log_error("[GLFW] Screen %d is out of range [0-%d]", monitor_index, count - 1); glfwTerminate(); exit(EXIT_FAILURE); } return monitors[monitor_index]; } static GLFWwindow * create_window(GLFWmonitor *monitor, const char *title, Window *shared_context, void (*key_callback)(Window *, int, int, int, int)) { GLFWwindow *window; log_info("[GLFW] Creating window..."); // Window related hints glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE); glfwWindowHint(GLFW_CENTER_CURSOR, GLFW_FALSE); glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE); // Context related hints glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); #ifdef GL_DEBUG glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); #endif glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // create fullscreen window in selected monitor window = glfwCreateWindow(1, 1, title, monitor, shared_context); // handle window creation fail if (window == NULL) { log_error("[GLFW] Window or context creation failed"); glfwTerminate(); exit(EXIT_FAILURE); } // set keyboard handler glfwSetKeyCallback(window, key_callback); // hide cursor glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); log_info("[GLFW] Window created"); return window; } static void use_window(GLFWwindow *window) { glfwMakeContextCurrent(window); } void window_startup(void (*error_callback)(int, const char *)) { init_glfw(error_callback); } void window_terminate() { log_info("[GLFW] Terminating library..."); glfwTerminate(); } Window *window_init(const char *title, unsigned char monitor_index, bool windowed, Window *shared_context, void (*key_callback)(Window *, int, int, int, int)) { GLFWwindow *window; GLFWmonitor *monitor; monitor = windowed ? NULL : get_monitor(monitor_index); window = create_window(monitor, title, shared_context, key_callback); use_window(window); return window; } void window_update_title(Window *window, const char *title) { glfwSetWindowTitle(window, title); } void window_refresh(Window *window) { // swap front and back buffers glfwSwapBuffers(window); } void window_events() { glfwPollEvents(); } double window_get_time() { return glfwGetTime(); } void window_use(Window *window, Context *context) { int width; int height; glfwMakeContextCurrent(window); glfwGetFramebufferSize(window, &width, &height); context->resolution[0] = width; context->resolution[1] = height; if (height > 0) { context->tex_resolution[0] = (int)(context->tex_resolution[1] * width / height); } } void window_close(Window *window) { log_info("[GLFW] Closing window..."); glfwSetWindowShouldClose(window, GLFW_TRUE); } bool window_should_close(Window *window) { return glfwWindowShouldClose(window) == GLFW_TRUE; } bool window_escape_key(int key, int action) { return key == GLFW_KEY_ESCAPE && action == GLFW_PRESS; } unsigned int window_read_key(int key, int action, int mods) { unsigned int result; if (action == GLFW_RELEASE || key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT || key == GLFW_KEY_LEFT_CONTROL || key == GLFW_KEY_RIGHT_CONTROL || key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_RIGHT_ALT) { return 0; } result = 1000 + key; if ((mods & GLFW_MOD_SHIFT) > 0) { result += 10000; } if ((mods & GLFW_MOD_CONTROL) > 0) { result += 100000; } if ((mods & GLFW_MOD_ALT) > 0) { result += 1000000; } return result; }