#include "util.h" #include "config.h" #include // Workaround to figure out if we have proper OpenGL support. // Otherwise the application would crash after our GtkGlArea is realized // and the context it uses is a legacy OpenGL 1.4 context because // GTK3 calls OpenGL 2.0+ functions on it. bool test_gl_support(void) { gboolean result = false; GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(window, "realize", G_CALLBACK(gl_check_realize), &result); gtk_widget_realize(window); gtk_widget_destroy(window); window = NULL; return result; } // The main function for the OpenGL version check workaround void gl_check_realize(GtkWidget *w, gpointer user_data_ptr) { gboolean *result = (gboolean *) user_data_ptr; GError *error = NULL; GdkWindow *gdk_window = gtk_widget_get_window(w); GdkGLContext *context = gdk_window_create_gl_context(gdk_window, &error); if (error != NULL) { g_warning("Failed to create context: %s", error->message); g_error_free(error); *result = false; } else { gdk_gl_context_make_current(context); int version = epoxy_gl_version(); g_object_run_dispose(G_OBJECT(context)); g_object_unref(context); context = NULL; gdk_gl_context_clear_current(); g_debug("OpenGL version: %d", version); *result = version >= 32; } } void replace_extension(const char *src, size_t length, char *dest, const char *ext) { memcpy(dest, src, length); dest[length] = 0; /* Remove extension */ for (size_t i = length; i--;) { if (dest[i] == '/') break; if (dest[i] == '.') { dest[i] = 0; break; } } /* Add new extension */ strcat(dest, ext); } double clamp_double(double min, double max, double value) { if (value < min) return min; if (value > max) return max; return value; } double max_double(double a, double b) { if (a > b) return a; return b; } double min_double(double a, double b) { if (a < b) return a; return b; } uint32_t convert_color(uint16_t color) { const uint8_t r = ((uint16_t)(color & 0x1F) * 255) / 31; const uint8_t g = ((uint16_t)((color >> 5) & 0x1F) * 255) / 31; const uint8_t b = ((uint16_t)((color >> 10) & 0x1F) * 255) / 31; return (r << 16) | (g << 8) | b; } uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b) { return 0xFF000000 | (r << 16) | (g << 8) | b; } GB_model_t config_get_model_type(GuiData *gui_data) { if (gui_data->cli_options.model != -1) { return gui_data->cli_options.model; } return config_get_model(); } GtkWidget *menubar_to_menu(GtkMenuBar *menubar) { GtkWidget *menu = gtk_menu_new(); g_autoptr(GList) iter = gtk_container_get_children(GTK_CONTAINER(menubar)); while (iter) { GtkWidget *item = GTK_WIDGET(iter->data); gtk_widget_reparent(item, menu); iter = iter->next; } return menu; }