From 447f52502ac9d45f9d92d8e2ddbb4fb4295af42e Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 20 Sep 2017 17:58:48 +0200 Subject: [PATCH] gtk: Add gtk-glsl binary That's supposed to become the command-line compiler. So far all it does is parse and then dump as text again the provided input file(s). --- gsk/gskslnodeprivate.h | 3 + gtk/glsl.c | 184 +++++++++++++++++++++++++++++++++++++++++ gtk/meson.build | 1 + 3 files changed, 188 insertions(+) create mode 100644 gtk/glsl.c diff --git a/gsk/gskslnodeprivate.h b/gsk/gskslnodeprivate.h index e41b3a26bd..6df9bb665e 100644 --- a/gsk/gskslnodeprivate.h +++ b/gsk/gskslnodeprivate.h @@ -41,12 +41,15 @@ struct _GskSlNodeClass { gboolean (* is_constant) (GskSlNode *node); }; +GDK_AVAILABLE_IN_3_92 GskSlNode * gsk_sl_node_new_program (GBytes *source, GError **error); GskSlNode * gsk_sl_node_ref (GskSlNode *node); +GDK_AVAILABLE_IN_3_92 void gsk_sl_node_unref (GskSlNode *node); +GDK_AVAILABLE_IN_3_92 void gsk_sl_node_print (GskSlNode *node, GString *string); GskSlType * gsk_sl_node_get_return_type (GskSlNode *node); diff --git a/gtk/glsl.c b/gtk/glsl.c new file mode 100644 index 0000000000..965944bf1a --- /dev/null +++ b/gtk/glsl.c @@ -0,0 +1,184 @@ +/* GTK - The GIMP Toolkit + * + * Copyright © 2017 Benjamin Otte + * + * GTK+ is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GTK+; see the file COPYING. If not, + * see . + */ + +#include "config.h" + +#include + +#ifdef G_IO_WIN32 +#include +#include +#else +#include +#include +#endif + +#include "gsk/gskslnodeprivate.h" + +static GBytes * +bytes_new_from_file (const char *filename, + GError **error) +{ + gchar *data; + gsize length; + + if (!g_file_get_contents (filename, + &data, &length, + error)) + return FALSE; + + return g_bytes_new_take (data, length); +} + +gboolean +dump (GOutputStream *output, + const char *filename) +{ + GBytes *bytes; + GString *string; + GskSlNode *program; + GError *error = NULL; + + bytes = bytes_new_from_file (filename, &error); + if (bytes == NULL) + { + g_print (error->message); + g_error_free (error); + return FALSE; + } + + program = gsk_sl_node_new_program (bytes, NULL); + if (program == NULL) + return FALSE; + + string = g_string_new (NULL); + gsk_sl_node_print (program, string); + if (!g_output_stream_write_all (output, string->str, string->len, NULL, NULL, &error)) + { + g_print (error->message); + g_error_free (error); + g_string_free (string, TRUE); + gsk_sl_node_unref (program); + return FALSE; + } + + g_string_free (string, TRUE); + gsk_sl_node_unref (program); + + return TRUE; +} + +static void +usage (GOptionContext *ctx) +{ + char *help = g_option_context_get_help (ctx, TRUE, NULL); + + g_print ("%s", help); + g_free (help); + exit (EXIT_FAILURE); +} + +int +main (int argc, char *argv[]) +{ + GOptionContext *ctx; + char **filenames = NULL; + char *output_file = NULL; + const GOptionEntry entries[] = { + { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output_file, "Output filename", "FILE" }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, "List of input files", "FILE [FILE...]" }, + { NULL, } + }; + GError *error = NULL; + GOutputStream *output; + gboolean success = TRUE; + guint i; + + g_set_prgname ("gtk-glsl"); + + gtk_init (); + + ctx = g_option_context_new (NULL); + g_option_context_add_main_entries (ctx, entries, NULL); + + if (!g_option_context_parse (ctx, &argc, &argv, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + exit (1); + } + + if (filenames == NULL) + usage (ctx); + + g_option_context_free (ctx); + + if (output_file == NULL) + { +#ifdef G_IO_WIN32 + HANDLE handle; + handle = GetStdHandle (STD_OUTPUT_HANDLE); + if (handle == NULL) + { + g_printerr ("No standard output. Use -o/--ouput to write to file\n"); + exit (1); + } + output = g_win32_output_stream_new (handle, FALSE); +#else + output = g_unix_output_stream_new (STDOUT_FILENO, FALSE); +#endif + } + else + { + GFile *file = g_file_new_for_path (output_file); + output = G_OUTPUT_STREAM (g_file_replace (file, + NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + NULL, + &error)); + g_object_unref (file); + if (output == NULL) + { + g_printerr ("Error creating output file: %s\n", error->message); + g_error_free (error); + exit (1); + } + } + + for (i = 0; filenames[i] != NULL; i++) + { + if (!dump (output, filenames[i])) + { + success = FALSE; + break; + } + } + + if (!g_output_stream_close (output, NULL, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + success = FALSE; + } + + g_object_unref (output); + g_strfreev (filenames); + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/gtk/meson.build b/gtk/meson.build index da95435a84..62f65b5b01 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -1024,6 +1024,7 @@ gtk_tools = [ ['gtk4-update-icon-cache', ['updateiconcache.c']], ['gtk4-encode-symbolic-svg', ['encodesymbolic.c']], ['gtk4-query-immodules', ['queryimmodules.c', 'gtkutils.c']], + ['gtk4-glsl', ['glsl.c']], ] if os_unix