#include "main_window.h" #include "gb_screen.h" #include "main_menu.h" struct _MainWindow { GtkApplicationWindowClass parent_class; GtkBox *container; GbScreen *screen; bool force_software_renderer; MainMenu *main_menu; }; G_DEFINE_TYPE(MainWindow, main_window, GTK_TYPE_APPLICATION_WINDOW); typedef enum { PROP_FORCE_SOFTWARE_RENDERER = 1, N_PROPERTIES } MainWindowProperty; static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; static void main_window_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { MainWindow *self = (MainWindow *) object; switch ((MainWindowProperty) property_id) { case PROP_FORCE_SOFTWARE_RENDERER: self->force_software_renderer = g_value_get_boolean(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); } } static void main_window_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { MainWindow *self = (MainWindow *) object; switch ((MainWindowProperty) property_id) { case PROP_FORCE_SOFTWARE_RENDERER: g_value_set_boolean(value, self->force_software_renderer); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); } } static void main_window_constructed(GObject *object) { MainWindow *self = (MainWindow *) object; self->screen = gb_screen_new(self->force_software_renderer); gtk_box_pack_end(GTK_BOX(self->container), GTK_WIDGET(self->screen), true, true, 0); } static void main_window_init(MainWindow *self) { gtk_widget_init_template(GTK_WIDGET(self)); gtk_window_set_title(GTK_WINDOW(self), "SameBoy"); gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(self), false); g_signal_new( "break-debugger-keyboard", // signal name G_TYPE_FROM_INSTANCE(self), // itype G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_ACTION, // signal_flags 0, // class_offset NULL, // accumulator NULL, // accumulator_data NULL, // c_marshaller, G_TYPE_NONE, // return_type 0 // n_params ); // Connect signal handlers gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_PRESS_MASK); gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_RELEASE_MASK); GtkAccelGroup *accelGroup = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(self), accelGroup); gtk_widget_add_accelerator(GTK_WIDGET(self), "break-debugger-keyboard", accelGroup, GDK_KEY_C, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); } static void main_window_class_init(MainWindowClass *class) { gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/main_window.ui"); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, container); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, main_menu); obj_properties[PROP_FORCE_SOFTWARE_RENDERER] = g_param_spec_boolean( "force_software_renderer", "Software Renderer", "Forces the use of software rendering via Cairo", false, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE ); G_OBJECT_CLASS(class)->set_property = main_window_set_property; G_OBJECT_CLASS(class)->get_property = main_window_get_property; G_OBJECT_CLASS(class)->constructed = main_window_constructed; g_object_class_install_properties(G_OBJECT_CLASS(class), N_PROPERTIES, obj_properties); } MainWindow *main_window_new(GApplication *application, bool force_software_renderer) { return g_object_new(MAIN_WINDOW_TYPE, "application", application, "force_software_renderer", force_software_renderer, NULL); } void main_window_fullscreen(MainWindow *self, bool make_fullscreen) { if (make_fullscreen) { gtk_window_unfullscreen(GTK_WINDOW(self)); } else { gtk_window_fullscreen(GTK_WINDOW(self)); } } void main_window_setup_menu(MainWindow *self, char *model_string) { main_menu_setup(self->main_menu, model_string); } // GbScreen wrappers void main_window_clear(MainWindow *self) { return gb_screen_clear(self->screen); } uint32_t *main_window_get_pixels(MainWindow *self) { return gb_screen_get_pixels(self->screen); } uint32_t *main_window_get_current_buffer(MainWindow *self) { return gb_screen_get_current_buffer(self->screen); } uint32_t *main_window_get_previous_buffer(MainWindow *self) { return gb_screen_get_previous_buffer(self->screen); } void main_window_flip(MainWindow *self) { return gb_screen_flip(self->screen); } void main_window_set_resolution(MainWindow *self, unsigned width, unsigned height) { return gb_screen_set_resolution(self->screen, width, height); } void main_window_set_blending_mode(MainWindow *self, GB_frame_blending_mode_t mode) { return gb_screen_set_blending_mode(self->screen, mode); } void main_window_set_shader(MainWindow *self, const char *shader_name) { return gb_screen_set_shader(self->screen, shader_name); } void main_window_queue_render(MainWindow *self) { return gb_screen_queue_render(self->screen); }