From c440b8127e6f9f8b7cb8af0c1c11ac35c863faaf Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 20:34:26 -0400 Subject: [PATCH] Bugfix for GUI hanging when gamepad config window is closed while waiting a button press. --- src/drivers/sdl/gui.cpp | 58 +++++++++++++++++++++++++++------------ src/drivers/sdl/input.cpp | 14 ++++++++-- src/drivers/sdl/input.h | 2 +- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index c4abaa09..daa1f08d 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -72,11 +72,12 @@ GtkWidget *MainWindow = NULL; GtkWidget *evbox = NULL; GtkWidget *padNoCombo = NULL; GtkWidget *configNoCombo = NULL; -GtkWidget *buttonMappings[10]; +GtkWidget *buttonMappings[10] = { NULL }; static GtkWidget *Menubar = NULL; static GtkRadioMenuItem *stateSlot[10] = { NULL }; bool gtkIsStarted = false; bool menuTogglingEnabled = false; +static int buttonConfigStatus = 0; static char useCairoDraw = 0; static int drawAreaGL = 0; @@ -145,11 +146,13 @@ int configGamepadButton (GtkButton * button, gpointer p) if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) return 0; + buttonConfigStatus = 2; + ButtonConfigBegin (); snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo); prefix = buf; - DWaitButton (NULL, &GamePadConfig[padNo][x], configNo); + DWaitButton (NULL, &GamePadConfig[padNo][x], configNo, &buttonConfigStatus ); g_config->setOption (prefix + GamePadNames[x], GamePadConfig[padNo][x].ButtonNum[configNo]); @@ -171,10 +174,16 @@ int configGamepadButton (GtkButton * button, gpointer p) snprintf (buf, sizeof (buf), "%s", ButtonName (&GamePadConfig[padNo][x], configNo)); - gtk_label_set_markup (GTK_LABEL (buttonMappings[x]), buf); + + if ( buttonMappings[x] != NULL ) + { + gtk_label_set_markup (GTK_LABEL (buttonMappings[x]), buf); + } ButtonConfigEnd (); + buttonConfigStatus = 1; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); return 0; @@ -686,6 +695,11 @@ void updateGamepadConfig (GtkWidget * w, gpointer p) { int i; char strBuf[128]; + + if ( (padNoCombo == NULL) || (configNoCombo == NULL) ) + { + return; + } int padNo = atoi (gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (padNoCombo))) - 1; @@ -696,8 +710,7 @@ void updateGamepadConfig (GtkWidget * w, gpointer p) for (i = 0; i < 10; i++) { GtkWidget *mappedKey = buttonMappings[i]; - if (GamePadConfig[padNo][i].ButtType[configNo] == - BUTTC_KEYBOARD) + if (GamePadConfig[padNo][i].ButtType[configNo] == BUTTC_KEYBOARD) { snprintf (strBuf, sizeof (strBuf), "%s", SDL_GetKeyName (GamePadConfig[padNo][i]. @@ -706,22 +719,31 @@ void updateGamepadConfig (GtkWidget * w, gpointer p) else sprintf (strBuf, "%s", ButtonName( &GamePadConfig[padNo][i], configNo ) ); - gtk_label_set_text (GTK_LABEL (mappedKey), strBuf); - gtk_label_set_use_markup (GTK_LABEL (mappedKey), TRUE); + if ( mappedKey != NULL ) + { + gtk_label_set_text (GTK_LABEL (mappedKey), strBuf); + gtk_label_set_use_markup (GTK_LABEL (mappedKey), TRUE); + } } } +static void closeGamepadConfig (GtkWidget * w, GdkEvent * e, gpointer p) +{ + gtk_widget_destroy (w); + + padNoCombo = NULL; + configNoCombo = NULL; + + for (int i = 0; i < 10; i++) + { + buttonMappings[i] = NULL; + } + buttonConfigStatus = 0; +} + // creates and opens the gamepad config window (requires GTK 2.24) void openGamepadConfig (void) { - // GTK 2.24 required for this dialog - if (checkGTKVersion (2, 24) == false) - { - // TODO: present this in a GTK MessageBox? - printf (" Warning: GTK >= 2.24 required for this dialog.\nTo configure the gamepads, use \"--inputcfg\" from the command line (ie: \"fceux --inputcfg gamepad1\").\n"); - return; - } - GtkWidget *win; GtkWidget *vbox; GtkWidget *hboxPadNo; @@ -861,8 +883,8 @@ void openGamepadConfig (void) gtk_box_pack_start (GTK_BOX (vbox), buttonFrame, TRUE, TRUE, 5); - g_signal_connect (win, "delete-event", G_CALLBACK (closeDialog), NULL); - g_signal_connect (win, "response", G_CALLBACK (closeDialog), NULL); + g_signal_connect (win, "delete-event", G_CALLBACK (closeGamepadConfig), NULL); + g_signal_connect (win, "response", G_CALLBACK (closeGamepadConfig), NULL); gtk_widget_show_all (win); @@ -871,6 +893,8 @@ void openGamepadConfig (void) g_signal_connect (G_OBJECT (win), "key-release-event", G_CALLBACK (convertKeypress), NULL); + buttonConfigStatus = 1; + return; } diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 666725c7..897508af 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -1651,7 +1651,7 @@ const char * ButtonName (const ButtConfig * bc, int which) * Waits for a button input and returns the information as to which * button was pressed. Used in button configuration. */ -int DWaitButton (const uint8 * text, ButtConfig * bc, int wb) +int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigStatus ) { SDL_Event event; static int32 LastAx[64][64]; @@ -1742,6 +1742,16 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb) } if (done) break; + + // If the button config window is Closed, + // get out of loop. + if ( buttonConfigStatus != NULL ) + { + if ( *buttonConfigStatus == 0 ) + { + break; + } + } } return (0); @@ -1763,7 +1773,7 @@ ConfigButton (char *text, ButtConfig * bc) for (wc = 0; wc < MAXBUTTCONFIG; wc++) { sprintf ((char *) buf, "%s (%d)", text, wc + 1); - DWaitButton (buf, bc, wc); + DWaitButton (buf, bc, wc, NULL); if (wc && bc->ButtType[wc] == bc->ButtType[wc - 1] && diff --git a/src/drivers/sdl/input.h b/src/drivers/sdl/input.h index 331d2795..2a1a2d85 100644 --- a/src/drivers/sdl/input.h +++ b/src/drivers/sdl/input.h @@ -24,7 +24,7 @@ int getKeyState( int k ); int ButtonConfigBegin(); void ButtonConfigEnd(); void ConfigButton(char *text, ButtConfig *bc); -int DWaitButton(const uint8 *text, ButtConfig *bc, int wb); +int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL); #define BUTTC_KEYBOARD 0x00 #define BUTTC_JOYSTICK 0x01