libgimp: Output CLI messages to the parent console like Linux and macOS

Closes: #15192 and #7413.

Maybe helps with #3603 too.

Loosely based on https://github.com/endlessm/rufus/blob/master/src/rufus.c

The input is right now clunky, needs to use proper API to halt input and
get CTRL+C in the future, but output on terminal is a big plus that pays off.

(cherry picked from commit 9e795acba7)
This commit is contained in:
Bruno Lopes 2025-10-31 13:25:43 -03:00
parent 720647f8e2
commit ccde514bdb
No known key found for this signature in database
6 changed files with 40 additions and 44 deletions

View file

@ -25,6 +25,8 @@
* So we call instead a separate program, then exit.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -34,6 +36,9 @@
#include <gio/gio.h>
#include <glib.h>
#include <glib/gi18n.h>
#ifdef G_OS_WIN32
#include <windows.h>
#endif
#include <gtk/gtk.h>
@ -56,10 +61,19 @@ main (int argc,
gchar *error;
GtkWidget *dialog;
#ifdef G_OS_WIN32
if (AttachConsole (ATTACH_PARENT_PROCESS) != 0)
{
freopen ("CONOUT$", "w", stdout);
freopen ("CONOUT$", "w", stderr);
_flushall ();
}
#endif
if (argc != 6 && argc != 8)
{
g_print ("Usage: gimp-debug-tool-2.0 [PROGRAM] [PID] [REASON] [MESSAGE] [BT_FILE] "
"([LAST_VERSION] [RELEASE_TIMESTAMP])\n");
g_print ("Usage: gimp-debug-tool-%s [PROGRAM] [PID] [REASON] [MESSAGE] [BT_FILE] "
"([LAST_VERSION] [RELEASE_TIMESTAMP])\n", GIMP_APP_VERSION);
exit (EXIT_FAILURE);
}

View file

@ -19,6 +19,7 @@ gimp_debug_tool = executable('gimp-debug-tool' + exec_ver,
libappwidgets,
libgimpbase,
],
win_subsystem: 'windows',
install: true,
install_dir: gimp_debug_tool_dir
)

View file

@ -116,9 +116,9 @@ static void gimp_init_i18n (void);
static void gimp_init_malloc (void);
#if defined (G_OS_WIN32) && !defined (GIMP_CONSOLE_COMPILATION)
static void gimp_open_console_window (void);
static void gimp_attach_console_window (void);
#else
#define gimp_open_console_window() /* as nothing */
#define gimp_attach_console_window() /* as nothing */
#endif
static const gchar *system_gimprc = NULL;
@ -562,9 +562,7 @@ main (int argc,
gint retval;
gint i;
#ifdef ENABLE_WIN32_DEBUG_CONSOLE
gimp_open_console_window ();
#endif
gimp_attach_console_window ();
#if defined(ENABLE_RELOCATABLE_RESOURCES) && defined(__APPLE__)
/* remove MacOS session identifier from the command line args */
@ -748,7 +746,7 @@ main (int argc,
(strcmp (arg, "-?") == 0) ||
(strncmp (arg, "--help-", 7) == 0))
{
gimp_open_console_window ();
gimp_attach_console_window ();
}
#endif
}
@ -780,7 +778,7 @@ main (int argc,
{
if (error)
{
gimp_open_console_window ();
gimp_attach_console_window ();
g_print ("%s\n", error->message);
g_error_free (error);
}
@ -844,7 +842,7 @@ main (int argc,
#endif
if (no_interface || be_verbose || console_messages || batch_commands != NULL)
gimp_open_console_window ();
gimp_attach_console_window ();
if (no_interface)
new_instance = TRUE;
@ -943,29 +941,17 @@ WinMain (struct HINSTANCE__ *hInstance,
static void
wait_console_window (void)
{
FILE *console = g_fopen ("CONOUT$", "w");
SetConsoleTitleW (g_utf8_to_utf16 (_("GIMP output. Type any character to close this window."), -1, NULL, NULL, NULL));
fprintf (console, _("(Type any character to close this window)\n"));
fflush (console);
_getch ();
g_print (_ ("(Type any character to close this window)\n"));
}
static void
gimp_open_console_window (void)
gimp_attach_console_window (void)
{
if (((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE ||
(HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) && AllocConsole ())
if (AttachConsole (ATTACH_PARENT_PROCESS) != 0)
{
if ((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE)
freopen ("CONOUT$", "w", stdout);
if ((HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE)
freopen ("CONOUT$", "w", stderr);
SetConsoleTitleW (g_utf8_to_utf16 (_("GIMP output. You can minimize "
"this window, but don't close "
"it."), -1, NULL, NULL, NULL));
freopen ("CONOUT$", "w", stdout);
freopen ("CONOUT$", "w", stderr);
_flushall ();
atexit (wait_console_window);
}
@ -1035,7 +1021,7 @@ gimp_option_dump_gimprc (const gchar *option_name,
{
GimpConfigDumpFormat format = GIMP_CONFIG_DUMP_NONE;
gimp_open_console_window ();
gimp_attach_console_window ();
if (strcmp (option_name, "--dump-gimprc") == 0)
format = GIMP_CONFIG_DUMP_GIMPRC;
@ -1107,7 +1093,7 @@ gimp_option_dump_pdb_procedures_deprecated (const gchar *option_name,
static void
gimp_show_version_and_exit (void)
{
gimp_open_console_window ();
gimp_attach_console_window ();
gimp_version_show (be_verbose);
app_exit (EXIT_SUCCESS);
@ -1116,7 +1102,7 @@ gimp_show_version_and_exit (void)
static void
gimp_show_license_and_exit (void)
{
gimp_open_console_window ();
gimp_attach_console_window ();
gimp_version_show (be_verbose);
g_print ("\n%s\n\n", GIMP_LICENSE);

View file

@ -200,6 +200,14 @@ gimp_main (GType plug_in_type,
gint i, j, k;
/* Make plugins output available on console */
if (AttachConsole (ATTACH_PARENT_PROCESS) != 0)
{
freopen ("CONOUT$", "w", stdout);
freopen ("CONOUT$", "w", stderr);
_flushall ();
}
/* Reduce risks */
SetDllDirectoryW (L"");

View file

@ -620,18 +620,6 @@ appstream = dependency('appstream', version: '>='+appstream_minver)
libarchive = dependency('libarchive')
################################################################################
# Check for debug console (Win32)
if platform_windows
enable_win32_debug_console = get_option('win32-debug-console').enabled() or \
(get_option('win32-debug-console').auto() and (not stable or not release))
conf.set('ENABLE_WIN32_DEBUG_CONSOLE', enable_win32_debug_console)
# When we'll depend on meson >= 1.1.0, we can just use:
# conf.set('ENABLE_WIN32_DEBUG_CONSOLE', get_option('win32-debug-console').enable_auto_if(not stable or not release).enabled())
endif
################################################################################
# Check for 32-bit DLLs (Win32 64-bit)

View file

@ -1,7 +1,6 @@
# Build properties
option('ansi', type: 'boolean', value: false, description: 'Turn on strict ansi')
option('enable-console-bin',type: 'boolean', value: true, description: 'Build a console-only binary which does not link GTK')
option('win32-debug-console',type:'feature', value: 'auto', description: 'Open a console when starting the program')
option('enable-multiproc', type: 'boolean', value: true, description: 'Support for multiple processors')
option('profiling', type: 'boolean', value: false, description: 'Enable profiling')
option('windows-installer', type: 'boolean', value: false, description: 'Generate files needed for the Inno Windows installer')