mirror of
https://github.com/raphnet/gc_n64_usb-v3
synced 2025-02-07 02:30:14 -05:00
Work in progress on GUI (firmware update)
This commit is contained in:
parent
bfa73890d4
commit
a103350625
@ -8,7 +8,7 @@ PREFIX=/usr/local
|
|||||||
|
|
||||||
PROG=gcn64ctl_gui
|
PROG=gcn64ctl_gui
|
||||||
|
|
||||||
OBJS=main.o ../gcn64.o ../mempak.o ../gcn64lib.o ../hexdump.o
|
OBJS=main.o ../gcn64.o ../mempak.o ../gcn64lib.o ../hexdump.o ../ihex.o
|
||||||
|
|
||||||
.PHONY : clean install
|
.PHONY : clean install
|
||||||
|
|
||||||
|
@ -579,7 +579,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<signal name="clicked" handler="gtk_widget_show" object="hexfile_chooser" swapped="yes"/>
|
<signal name="clicked" handler="update_usbadapter_firmware" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
@ -655,35 +655,30 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkFileChooserDialog" id="hexfile_chooser">
|
<object class="GtkDialog" id="firmware_update_dialog">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="title" translatable="yes">Select firmware file...</property>
|
<property name="title" translatable="yes">Firmware update</property>
|
||||||
|
<property name="resizable">False</property>
|
||||||
<property name="modal">True</property>
|
<property name="modal">True</property>
|
||||||
<property name="type_hint">dialog</property>
|
<property name="type_hint">dialog</property>
|
||||||
<property name="attached_to">mainWindow</property>
|
<property name="transient_for">mainWindow</property>
|
||||||
<property name="filter">hexfilter</property>
|
|
||||||
<property name="local_only">False</property>
|
|
||||||
<property name="preview_widget_active">False</property>
|
|
||||||
<property name="use_preview_label">False</property>
|
|
||||||
<child internal-child="vbox">
|
<child internal-child="vbox">
|
||||||
<object class="GtkBox" id="filechooserdialog-vbox1">
|
<object class="GtkBox" id="dialog-vbox1">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="spacing">2</property>
|
<property name="spacing">2</property>
|
||||||
<child internal-child="action_area">
|
<child internal-child="action_area">
|
||||||
<object class="GtkButtonBox" id="filechooserdialog-action_area1">
|
<object class="GtkButtonBox" id="update_dialog_btnBox">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="layout_style">end</property>
|
<property name="layout_style">end</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button5">
|
<object class="GtkButton" id="update_cancel_button">
|
||||||
<property name="label">gtk-cancel</property>
|
<property name="label">gtk-cancel</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="relief">none</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
<signal name="clicked" handler="gtk_widget_hide" object="hexfile_chooser" swapped="yes"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
@ -692,14 +687,13 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button6">
|
<object class="GtkButton" id="update_start_btn">
|
||||||
<property name="label">gtk-open</property>
|
<property name="label" translatable="yes">Start update</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="use_stock">True</property>
|
|
||||||
<property name="yalign">0.46000000834465027</property>
|
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
|
<signal name="clicked" handler="updatestart_btn_clicked_cb" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
@ -715,42 +709,51 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<object class="GtkBox" id="box6">
|
||||||
</child>
|
<property name="visible">True</property>
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<object class="GtkMessageDialog" id="internalError">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="title" translatable="yes">Error</property>
|
|
||||||
<property name="modal">True</property>
|
|
||||||
<property name="icon_name">dialog-error</property>
|
|
||||||
<property name="type_hint">normal</property>
|
|
||||||
<property name="transient_for">mainWindow</property>
|
|
||||||
<property name="message_type">question</property>
|
|
||||||
<property name="text" translatable="yes">Internal error</property>
|
|
||||||
<child internal-child="vbox">
|
|
||||||
<object class="GtkBox" id="messagedialog-vbox">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="spacing">2</property>
|
|
||||||
<child internal-child="action_area">
|
|
||||||
<object class="GtkButtonBox" id="messagedialog-action_area">
|
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="homogeneous">True</property>
|
<property name="valign">center</property>
|
||||||
<property name="layout_style">end</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<object class="GtkBox" id="box7">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label10">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Firmware file:</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="lbl_firmware_filename">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">filename.hex</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="internalErrorDialog">
|
<object class="GtkProgressBar" id="updateProgress">
|
||||||
<property name="label">gtk-close</property>
|
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="show_text">True</property>
|
||||||
<property name="use_stock">True</property>
|
|
||||||
<property name="yalign">0.47999998927116394</property>
|
|
||||||
<signal name="clicked" handler="gtk_main_quit" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
@ -758,14 +761,29 @@
|
|||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="updateStatus">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Ready</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">True</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">0</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<action-widgets>
|
||||||
|
<action-widget response="1">update_cancel_button</action-widget>
|
||||||
|
</action-widgets>
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
139
tool/gtk/main.c
139
tool/gtk/main.c
@ -1,18 +1,150 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include "../gcn64.h"
|
#include "../gcn64.h"
|
||||||
#include "../gcn64lib.h"
|
#include "../gcn64lib.h"
|
||||||
#include "../../requests.h"
|
#include "../../requests.h"
|
||||||
|
#include "../ihex.h"
|
||||||
|
|
||||||
#define GET_ELEMENT(TYPE, ELEMENT) (TYPE *)gtk_builder_get_object(app->builder, #ELEMENT)
|
#define GET_ELEMENT(TYPE, ELEMENT) (TYPE *)gtk_builder_get_object(app->builder, #ELEMENT)
|
||||||
#define GET_UI_ELEMENT(TYPE, ELEMENT) TYPE *ELEMENT = GET_ELEMENT(TYPE, ELEMENT)
|
#define GET_UI_ELEMENT(TYPE, ELEMENT) TYPE *ELEMENT = GET_ELEMENT(TYPE, ELEMENT)
|
||||||
|
|
||||||
struct application {
|
struct application {
|
||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
|
GtkWindow *mainwindow;
|
||||||
gcn64_hdl_t current_adapter_handle;
|
gcn64_hdl_t current_adapter_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
G_MODULE_EXPORT void updatestart_btn_clicked_cb(GtkWidget *w, gpointer data)
|
||||||
|
{
|
||||||
|
struct application *app = data;
|
||||||
|
GET_UI_ELEMENT(GtkProgressBar, updateProgress);
|
||||||
|
GET_UI_ELEMENT(GtkDialog, firmware_update_dialog);
|
||||||
|
GET_UI_ELEMENT(GtkButtonBox, update_dialog_btnBox);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
gtk_widget_set_sensitive(GTK_WIDGET(update_dialog_btnBox), FALSE);
|
||||||
|
|
||||||
|
for (i=0; i<100; i++) {
|
||||||
|
gtk_progress_bar_set_fraction(updateProgress, i/100.0);
|
||||||
|
usleep(50000);
|
||||||
|
gtk_main_iteration_do(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_dialog_response(firmware_update_dialog, GTK_RESPONSE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infoPopop(struct application *app, const char *message)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new(app->mainwindow,
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_INFO,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
message);
|
||||||
|
|
||||||
|
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void errorPopop(struct application *app, const char *message)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new(app->mainwindow,
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
message);
|
||||||
|
|
||||||
|
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IHEX_MAX_FILE_SIZE 0x20000
|
||||||
|
char check_ihex_for_signature(const char *filename, const char *signature)
|
||||||
|
{
|
||||||
|
unsigned char *buf;
|
||||||
|
int max_address;
|
||||||
|
|
||||||
|
buf = malloc(IHEX_MAX_FILE_SIZE);
|
||||||
|
if (!buf) {
|
||||||
|
perror("malloc");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_address= load_ihex(filename, buf, IHEX_MAX_FILE_SIZE);
|
||||||
|
|
||||||
|
if (max_address > 0) {
|
||||||
|
if (!memmem(buf, max_address + 1, signature, strlen(signature))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_MODULE_EXPORT void update_usbadapter_firmware(GtkWidget *w, gpointer data)
|
||||||
|
{
|
||||||
|
struct application *app = data;
|
||||||
|
gint res;
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
|
||||||
|
GET_UI_ELEMENT(GtkFileFilter, hexfilter);
|
||||||
|
GET_UI_ELEMENT(GtkDialog, firmware_update_dialog);
|
||||||
|
GET_UI_ELEMENT(GtkLabel, lbl_firmware_filename);
|
||||||
|
GET_UI_ELEMENT(GtkButtonBox, update_dialog_btnBox);
|
||||||
|
|
||||||
|
dialog = gtk_file_chooser_dialog_new("Open .hex file",
|
||||||
|
app->mainwindow,
|
||||||
|
action,
|
||||||
|
"_Cancel",
|
||||||
|
GTK_RESPONSE_CANCEL,
|
||||||
|
"_Open",
|
||||||
|
GTK_RESPONSE_ACCEPT,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), hexfilter);
|
||||||
|
|
||||||
|
res = gtk_dialog_run (GTK_DIALOG(dialog));
|
||||||
|
if (res == GTK_RESPONSE_ACCEPT) {
|
||||||
|
char *filename, *basename;
|
||||||
|
GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
|
||||||
|
|
||||||
|
filename = gtk_file_chooser_get_filename(chooser);
|
||||||
|
basename = g_path_get_basename(filename);
|
||||||
|
|
||||||
|
printf("File selected: %s\n", filename);
|
||||||
|
|
||||||
|
if (!check_ihex_for_signature(filename, "9c3ea8b8-753f-11e5-a0dc-001bfca3c593")) {
|
||||||
|
errorPopop(app, "Signature not found - This file is invalid or not meant for this adapter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare the update dialog widgets... */
|
||||||
|
gtk_label_set_text(lbl_firmware_filename, basename);
|
||||||
|
gtk_widget_set_sensitive(GTK_WIDGET(update_dialog_btnBox), TRUE);
|
||||||
|
|
||||||
|
/* Run the dialog */
|
||||||
|
res = gtk_dialog_run(firmware_update_dialog);
|
||||||
|
gtk_widget_hide( GTK_WIDGET(firmware_update_dialog));
|
||||||
|
|
||||||
|
if (res == GTK_RESPONSE_OK) {
|
||||||
|
infoPopop(app, "Update succeeded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(filename);
|
||||||
|
g_free(basename);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
static void updateGuiFromAdapter(struct application *app, struct gcn64_info *info)
|
static void updateGuiFromAdapter(struct application *app, struct gcn64_info *info)
|
||||||
{
|
{
|
||||||
unsigned char buf[32];
|
unsigned char buf[32];
|
||||||
@ -197,7 +329,7 @@ int
|
|||||||
main( int argc,
|
main( int argc,
|
||||||
char **argv )
|
char **argv )
|
||||||
{
|
{
|
||||||
GtkWidget *window;
|
GtkWindow *window;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
struct application app = { };
|
struct application app = { };
|
||||||
|
|
||||||
@ -216,7 +348,8 @@ main( int argc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get main window pointer from UI */
|
/* Get main window pointer from UI */
|
||||||
window = GTK_WIDGET( gtk_builder_get_object( app.builder, "mainWindow" ) );
|
window = GTK_WINDOW( gtk_builder_get_object( app.builder, "mainWindow" ) );
|
||||||
|
app.mainwindow = window;
|
||||||
|
|
||||||
/* Connect signals */
|
/* Connect signals */
|
||||||
gtk_builder_connect_signals( app.builder, &app );
|
gtk_builder_connect_signals( app.builder, &app );
|
||||||
@ -225,7 +358,7 @@ main( int argc,
|
|||||||
// g_object_unref( G_OBJECT( builder ) );
|
// g_object_unref( G_OBJECT( builder ) );
|
||||||
|
|
||||||
/* Show window. All other widgets are automatically shown by GtkBuilder */
|
/* Show window. All other widgets are automatically shown by GtkBuilder */
|
||||||
gtk_widget_show( window );
|
gtk_widget_show( GTK_WIDGET(window) );
|
||||||
|
|
||||||
/* Start main loop */
|
/* Start main loop */
|
||||||
gtk_main();
|
gtk_main();
|
||||||
|
Loading…
Reference in New Issue
Block a user