Merge branch 'wip/otte/win32-fixes' into 'main'

various fixes

See merge request GNOME/gtk!7895
This commit is contained in:
Benjamin Otte
2024-11-05 13:01:56 +00:00
24 changed files with 180 additions and 167 deletions

View File

@@ -2,6 +2,8 @@
#include "gdkcicpparams.h" #include "gdkcicpparams.h"
G_BEGIN_DECLS
typedef struct _GdkCicp GdkCicp; typedef struct _GdkCicp GdkCicp;
struct _GdkCicp struct _GdkCicp
@@ -82,3 +84,5 @@ gdk_cicp_equivalent (const GdkCicp *p1,
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *self); const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *self);
GdkCicpParams * gdk_cicp_params_new_for_cicp (const GdkCicp *cicp); GdkCicpParams * gdk_cicp_params_new_for_cicp (const GdkCicp *cicp);
G_END_DECLS

View File

@@ -120,3 +120,4 @@ guint gdk_parse_debug_var (const char *variable,
const GdkDebugKey *keys, const GdkDebugKey *keys,
guint nkeys); guint nkeys);
G_END_DECLS

View File

@@ -267,9 +267,6 @@ Otherwise it's similar to how the clipboard works. Only the DnD server
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
/* For C-style COM wrapper macros */
#define COBJMACROS
/* for CIDA */ /* for CIDA */
#include <shlobj.h> #include <shlobj.h>

View File

@@ -28,7 +28,6 @@
#include "gdkglversionprivate.h" #include "gdkglversionprivate.h"
/* Used for active language or text service change notifications */ /* Used for active language or text service change notifications */
#define COBJMACROS
#include <msctf.h> #include <msctf.h>
#ifdef HAVE_EGL #ifdef HAVE_EGL

View File

@@ -192,9 +192,6 @@
#define INITGUID #define INITGUID
#endif #endif
/* For C-style COM wrapper macros */
#define COBJMACROS
#include "gdkdrag.h" #include "gdkdrag.h"
#include "gdkprivate-win32.h" #include "gdkprivate-win32.h"
#include "gdkwin32.h" #include "gdkwin32.h"

View File

@@ -36,9 +36,6 @@
#define INITGUID #define INITGUID
#endif #endif
/* For C-style COM wrapper macros */
#define COBJMACROS
#include "gdkdropprivate.h" #include "gdkdropprivate.h"
#include "gdkdrag.h" #include "gdkdrag.h"
@@ -303,8 +300,7 @@ query_object_formats (GdkDisplay *display,
hr = IEnumFORMATETC_Next (pfmt, 1, &fmt, NULL); hr = IEnumFORMATETC_Next (pfmt, 1, &fmt, NULL);
} }
if (pfmt) gdk_win32_com_clear (&pfmt);
IEnumFORMATETC_Release (pfmt);
result_formats = gdk_content_formats_builder_free_to_formats (builder); result_formats = gdk_content_formats_builder_free_to_formats (builder);
@@ -314,8 +310,7 @@ query_object_formats (GdkDisplay *display,
static void static void
set_data_object (LPDATAOBJECT *location, LPDATAOBJECT data_object) set_data_object (LPDATAOBJECT *location, LPDATAOBJECT data_object)
{ {
if (*location != NULL) gdk_win32_com_clear (location);
IDataObject_Release (*location);
*location = data_object; *location = data_object;

View File

@@ -28,7 +28,6 @@
#endif #endif
#define WINVER 0x0603 #define WINVER 0x0603
#define _WIN32_WINNT 0x0603 #define _WIN32_WINNT 0x0603
#define COBJMACROS
#include "config.h" #include "config.h"
#include <gdk/gdk.h> #include <gdk/gdk.h>
@@ -38,6 +37,7 @@
#include "gdkdevice-virtual.h" #include "gdkdevice-virtual.h"
#include "gdkdeviceprivate.h" #include "gdkdeviceprivate.h"
#include "gdkdisplay-win32.h" #include "gdkdisplay-win32.h"
#include "gdkprivate-win32.h"
#include "gdkeventsprivate.h" #include "gdkeventsprivate.h"
#include "gdkseatdefaultprivate.h" #include "gdkseatdefaultprivate.h"
#include "gdkinput-dmanipulation.h" #include "gdkinput-dmanipulation.h"
@@ -360,7 +360,7 @@ reset_viewport (IDirectManipulationViewport *viewport)
HR_CHECK_GOTO (hr, failed); HR_CHECK_GOTO (hr, failed);
failed: failed:
IUnknown_Release (content); gdk_win32_com_clear (&content);
} }
static void static void
@@ -392,8 +392,7 @@ gdk_win32_display_close_dmanip_manager (GdkDisplay *display)
{ {
IDirectManipulationManager *manager = GDK_DISPLAY_GET_DMANIP_MANAGER (display); IDirectManipulationManager *manager = GDK_DISPLAY_GET_DMANIP_MANAGER (display);
if (manager != NULL) gdk_win32_com_clear (&manager);
IUnknown_Release (manager);
g_clear_pointer (&GDK_WIN32_DISPLAY (display)->dmanip_items, g_free); g_clear_pointer (&GDK_WIN32_DISPLAY (display)->dmanip_items, g_free);
} }
@@ -452,8 +451,7 @@ create_viewport (GdkSurface *surface,
return; return;
failed: failed:
if (handler) gdk_win32_com_clear (&handler);
IUnknown_Release (handler);
close_viewport (pViewport); close_viewport (pViewport);
} }

View File

@@ -53,8 +53,6 @@
#define GDK_DEBUG_EVENTS_OR_INPUT (GDK_DEBUG_EVENTS|GDK_DEBUG_INPUT) #define GDK_DEBUG_EVENTS_OR_INPUT (GDK_DEBUG_EVENTS|GDK_DEBUG_INPUT)
#define GDK_DEBUG_MISC_OR_EVENTS (GDK_DEBUG_MISC|GDK_DEBUG_EVENTS) #define GDK_DEBUG_MISC_OR_EVENTS (GDK_DEBUG_MISC|GDK_DEBUG_EVENTS)
GdkWin32Screen *GDK_SURFACE_SCREEN(GObject *win);
/* Use this for hWndInsertAfter (2nd argument to SetWindowPos()) if /* Use this for hWndInsertAfter (2nd argument to SetWindowPos()) if
* SWP_NOZORDER flag is used. Otherwise it's unobvious why a particular * SWP_NOZORDER flag is used. Otherwise it's unobvious why a particular
* argument is used. Using NULL is misleading, because * argument is used. Using NULL is misleading, because
@@ -97,6 +95,29 @@ gboolean _gdk_modal_blocked (GdkSurface *surface);
gboolean gdk_win32_ensure_com (void); gboolean gdk_win32_ensure_com (void);
gboolean gdk_win32_ensure_ole (void); gboolean gdk_win32_ensure_ole (void);
/*
* gdk_win32_com_clear:
* @com_ptr: pointer to a COM object pointer
*
* Clears a reference to a COM object.
*
* `com_ptr` must not be `NULL`.
*
* If the reference is `NULL` then this function does nothing.
* Otherwise, the reference count of the object is decreased
* and the pointer is set to NULL.
*
* Think of this function like g_clear_object() but for COM objects.
*/
#define gdk_win32_com_clear(com_ptr) \
G_STMT_START {\
if (*(com_ptr)) \
{ \
(*(com_ptr))->lpVtbl->Release (*(com_ptr)); \
*(com_ptr) = NULL; \
} \
}G_STMT_END
void _gdk_win32_print_dc (HDC hdc); void _gdk_win32_print_dc (HDC hdc);
char *_gdk_win32_surface_state_to_string (GdkToplevelState state); char *_gdk_win32_surface_state_to_string (GdkToplevelState state);

View File

@@ -19,8 +19,6 @@
#include "config.h" #include "config.h"
#define COBJMACROS
#include "gtkfilechoosernativeprivate.h" #include "gtkfilechoosernativeprivate.h"
#include "gtknativedialogprivate.h" #include "gtknativedialogprivate.h"
@@ -333,10 +331,9 @@ filechooser_win32_thread_data_free (FilechooserWin32ThreadData *data)
g_array_free (data->choices_selections, TRUE); g_array_free (data->choices_selections, TRUE);
data->choices_selections = NULL; data->choices_selections = NULL;
} }
g_object_unref (data->shortcut_files); g_clear_object (&data->shortcut_files);
g_slist_free_full (data->files, g_object_unref); g_slist_free_full (data->files, g_object_unref);
if (data->self) g_clear_object (&data->self);
g_object_unref (data->self);
g_free (data->accept_label); g_free (data->accept_label);
g_free (data->cancel_label); g_free (data->cancel_label);
g_free (data->title); g_free (data->title);

View File

@@ -16,8 +16,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define COBJMACROS
#include "config.h" #include "config.h"
#include <math.h> #include <math.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>

View File

@@ -63,7 +63,8 @@ add_project_arguments('-D_GNU_SOURCE', language: 'c')
if host_machine.system() == 'windows' if host_machine.system() == 'windows'
add_project_arguments(['-DUNICODE', add_project_arguments(['-DUNICODE',
'-D_UNICODE', '-D_UNICODE',
'-D_WIN32_WINNT=_WIN32_WINNT_WIN7'], language: 'c') '-DCOBJMACROS',
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10'], language: 'c')
endif endif
# Use debug/optimization flags to determine whether to enable debug or disable # Use debug/optimization flags to determine whether to enable debug or disable

View File

@@ -219,7 +219,7 @@ gtk_gst_sink_get_caps (GstBaseSink *bsink,
{ {
GdkDmabufFormats *formats = gdk_display_get_dmabuf_formats (self->gdk_display); GdkDmabufFormats *formats = gdk_display_get_dmabuf_formats (self->gdk_display);
if (formats) if (formats && gdk_dmabuf_formats_get_n_formats (formats) > 0)
{ {
tmp = gst_caps_from_string (DMABUF_TEXTURE_CAPS); tmp = gst_caps_from_string (DMABUF_TEXTURE_CAPS);
add_drm_formats_and_modifiers (tmp, formats); add_drm_formats_and_modifiers (tmp, formats);
@@ -415,6 +415,7 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
graphene_rect_t *viewport) graphene_rect_t *viewport)
{ {
GstVideoFrame *frame = g_new (GstVideoFrame, 1); GstVideoFrame *frame = g_new (GstVideoFrame, 1);
GstMemory *mem;
GdkTexture *texture; GdkTexture *texture;
viewport->origin.x = 0; viewport->origin.x = 0;
@@ -422,7 +423,9 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
viewport->size.width = GST_VIDEO_INFO_WIDTH (&self->v_info); viewport->size.width = GST_VIDEO_INFO_WIDTH (&self->v_info);
viewport->size.height = GST_VIDEO_INFO_HEIGHT (&self->v_info); viewport->size.height = GST_VIDEO_INFO_HEIGHT (&self->v_info);
if (gst_is_dmabuf_memory (gst_buffer_peek_memory (buffer, 0))) mem = gst_buffer_peek_memory (buffer, 0);
if (gst_is_dmabuf_memory (mem))
{ {
GdkDmabufTextureBuilder *builder = NULL; GdkDmabufTextureBuilder *builder = NULL;
const GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer); const GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer);
@@ -446,7 +449,6 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
for (i = 0; i < vmeta->n_planes; i++) for (i = 0; i < vmeta->n_planes; i++)
{ {
GstMemory *mem;
guint mem_idx, length; guint mem_idx, length;
gsize skip; gsize skip;
@@ -475,12 +477,15 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
g_object_unref (builder); g_object_unref (builder);
if (!texture) if (!texture)
GST_ERROR_OBJECT (self, "Failed to create dmabuf texture: %s", error->message); {
GST_ERROR_OBJECT (self, "Failed to create dmabuf texture: %s", error->message);
g_error_free (error);
}
*pixel_aspect_ratio = ((double) GST_VIDEO_INFO_PAR_N (&self->v_info) / *pixel_aspect_ratio = ((double) GST_VIDEO_INFO_PAR_N (&self->v_info) /
(double) GST_VIDEO_INFO_PAR_D (&self->v_info)); (double) GST_VIDEO_INFO_PAR_D (&self->v_info));
} }
else if (self->gdk_context && else if (gst_is_gl_memory (mem) &&
gst_video_frame_map (frame, &self->v_info, buffer, GST_MAP_READ | GST_MAP_GL)) gst_video_frame_map (frame, &self->v_info, buffer, GST_MAP_READ | GST_MAP_GL))
{ {
GstGLSyncMeta *sync_meta; GstGLSyncMeta *sync_meta;

View File

@@ -111,7 +111,7 @@ load_ui_file (GFile *file, gboolean generate)
reference_file = test_get_other_file (ui_file, ".nodes"); reference_file = test_get_other_file (ui_file, ".nodes");
diff = diff_with_file (reference_file, output, -1, &error); diff = diff_string_with_file (reference_file, output, -1, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && diff[0]) if (diff && diff[0])

View File

@@ -99,7 +99,7 @@ load_ui_file (GFile *file, gboolean generate)
reference_file = test_get_reference_file (ui_file); reference_file = test_get_reference_file (ui_file);
diff = diff_with_file (reference_file, output, -1, &error); diff = diff_string_with_file (reference_file, output, -1, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && diff[0]) if (diff && diff[0])

View File

@@ -146,7 +146,7 @@ parse_css_file (GFile *file, gboolean generate)
reference_file = test_get_reference_file (css_file); reference_file = test_get_reference_file (css_file);
diff = diff_with_file (reference_file, css, -1, &error); diff = diff_string_with_file (reference_file, css, -1, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && diff[0]) if (diff && diff[0])
@@ -161,7 +161,7 @@ parse_css_file (GFile *file, gboolean generate)
if (errors_file) if (errors_file)
{ {
diff = diff_with_file (errors_file, errors->str, errors->len, &error); diff = diff_string_with_file (errors_file, errors->str, errors->len, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && diff[0]) if (diff && diff[0])

View File

@@ -129,7 +129,7 @@ load_ui_file (GFile *file, gboolean generate)
reference_file = test_get_other_file (ui_file, ".nodes"); reference_file = test_get_other_file (ui_file, ".nodes");
g_assert_nonnull (reference_file); g_assert_nonnull (reference_file);
diff = diff_with_file (reference_file, output, -1, &error); diff = diff_string_with_file (reference_file, output, -1, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && diff[0]) if (diff && diff[0])

View File

@@ -4,7 +4,8 @@ compare_render = executable('compare-render',
c_args: common_cflags + ['-DGTK_COMPILATION'], c_args: common_cflags + ['-DGTK_COMPILATION'],
) )
node_parser = executable('node-parser', 'node-parser.c', node_parser = executable('node-parser',
[ 'node-parser.c', '../testutils.c' ],
dependencies: libgtk_dep, dependencies: libgtk_dep,
c_args: common_cflags, c_args: common_cflags,
) )
@@ -488,7 +489,8 @@ endforeach
# offload does not work outside of linux # offload does not work outside of linux
if os_linux if os_linux
offload = executable('offload', 'offload.c', 'gskrendernodeattach.c', offload = executable('offload',
[ 'offload.c', 'gskrendernodeattach.c', '../testutils.c' ],
dependencies : libgtk_static_dep, dependencies : libgtk_static_dep,
c_args: common_cflags + [ '-DGTK_COMPILATION=1' ], c_args: common_cflags + [ '-DGTK_COMPILATION=1' ],
) )
@@ -568,8 +570,8 @@ internal_tests = [
[ 'boundingbox'], [ 'boundingbox'],
[ 'curve', [ ], [ 'flaky' ]], [ 'curve', [ ], [ 'flaky' ]],
[ 'curve-special-cases' ], [ 'curve-special-cases' ],
[ 'diff' ],
[ 'half-float' ], [ 'half-float' ],
[ 'not-diff' ],
[ 'misc'], [ 'misc'],
[ 'path-private' ], [ 'path-private' ],
[ 'rounded-rect'], [ 'rounded-rect'],

View File

@@ -22,6 +22,8 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "../testutils.h"
static char * static char *
test_get_reference_file (const char *node_file) test_get_reference_file (const char *node_file)
{ {
@@ -64,47 +66,6 @@ test_get_errors_file (const char *node_file)
return g_string_free (file, FALSE); return g_string_free (file, FALSE);
} }
static GBytes *
diff_with_file (const char *file1,
GBytes *input,
GError **error)
{
GSubprocess *process;
GBytes *output;
process = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE
| G_SUBPROCESS_FLAGS_STDOUT_PIPE,
error,
"diff", "-u", file1, "-", NULL);
if (process == NULL)
return NULL;
if (!g_subprocess_communicate (process,
input,
NULL,
&output,
NULL,
error))
{
g_object_unref (process);
return NULL;
}
if (!g_subprocess_get_successful (process) &&
/* this is the condition when the files differ */
!(g_subprocess_get_if_exited (process) && g_subprocess_get_exit_status (process) == 1))
{
g_clear_pointer (&output, g_bytes_unref);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"The `diff' process exited with error status %d",
g_subprocess_get_exit_status (process));
}
g_object_unref (process);
return output;
}
static void static void
append_error_value (GString *string, append_error_value (GString *string,
GType enum_type, GType enum_type,
@@ -162,8 +123,9 @@ parse_node_file (GFile *file, gboolean generate)
char *node_file, *reference_file, *errors_file; char *node_file, *reference_file, *errors_file;
GskRenderNode *node; GskRenderNode *node;
GString *errors; GString *errors;
GBytes *diff, *bytes; GBytes *bytes;
GError *error = NULL; GError *error = NULL;
char *diff;
gboolean result = TRUE; gboolean result = TRUE;
bytes = g_file_load_bytes (file, NULL, NULL, &error); bytes = g_file_load_bytes (file, NULL, NULL, &error);
@@ -193,33 +155,33 @@ parse_node_file (GFile *file, gboolean generate)
node_file = g_file_get_path (file); node_file = g_file_get_path (file);
reference_file = test_get_reference_file (node_file); reference_file = test_get_reference_file (node_file);
diff = diff_with_file (reference_file, bytes, &error); diff = diff_bytes_with_file (reference_file, bytes, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && g_bytes_get_size (diff) > 0) if (diff)
{ {
g_print ("Resulting file doesn't match reference:\n%s\n", g_print ("Resulting file doesn't match reference:\n%s\n",
(const char *) g_bytes_get_data (diff, NULL)); (const char *) diff);
result = FALSE; result = FALSE;
} }
g_free (reference_file); g_free (reference_file);
g_clear_pointer (&diff, g_bytes_unref); g_clear_pointer (&diff, g_free);
errors_file = test_get_errors_file (node_file); errors_file = test_get_errors_file (node_file);
if (errors_file) if (errors_file)
{ {
GBytes *error_bytes = g_string_free_to_bytes (errors); GBytes *error_bytes = g_string_free_to_bytes (errors);
diff = diff_with_file (errors_file, error_bytes, &error); diff = diff_bytes_with_file (errors_file, error_bytes, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && g_bytes_get_size (diff) > 0) if (diff)
{ {
g_print ("Errors don't match expected errors:\n%s\n", g_print ("Errors don't match expected errors:\n%s\n",
(const char *) g_bytes_get_data (diff, NULL)); (const char *) diff);
result = FALSE; result = FALSE;
} }
g_clear_pointer (&diff, g_bytes_unref); g_clear_pointer (&diff, g_free);
g_clear_pointer (&error_bytes, g_bytes_unref); g_clear_pointer (&error_bytes, g_bytes_unref);
} }
else if (errors->str[0]) else if (errors->str[0])

View File

@@ -29,6 +29,8 @@
#include <gsk/gskoffloadprivate.h> #include <gsk/gskoffloadprivate.h>
#include "gskrendernodeattach.h" #include "gskrendernodeattach.h"
#include "../testutils.h"
static char * static char *
test_get_sibling_file (const char *node_file, test_get_sibling_file (const char *node_file,
const char *old_ext, const char *old_ext,
@@ -52,26 +54,6 @@ test_get_sibling_file (const char *node_file,
return g_string_free (file, FALSE); return g_string_free (file, FALSE);
} }
static GBytes *
diff_with_file (const char *file1,
GBytes *input,
GError **error)
{
char *buffer;
gsize len;
static const char msg[] = "The output is not as expected";
g_file_get_contents (file1, &buffer, &len, NULL);
if (strcmp (buffer, (char *) g_bytes_get_data (input, NULL)) == 0)
{
g_free (buffer);
return NULL;
}
g_free (buffer);
return g_bytes_new_static (msg, strlen (msg) + 1);
}
static void static void
append_error_value (GString *string, append_error_value (GString *string,
GType enum_type, GType enum_type,
@@ -225,7 +207,7 @@ collect_offload_info (GdkSurface *surface,
info->was_offloaded ? "was offloaded, " : ""); info->was_offloaded ? "was offloaded, " : "");
} }
bytes = g_bytes_new (s->str, s->len + 1); bytes = g_bytes_new (s->str, s->len);
g_string_free (s, TRUE); g_string_free (s, TRUE);
@@ -364,11 +346,11 @@ parse_node_file (GFile *file, const char *generate)
GdkSubsurface *subsurface; GdkSubsurface *subsurface;
GskOffload *offload; GskOffload *offload;
GskRenderNode *node, *tmp; GskRenderNode *node, *tmp;
GBytes *offload_state, *diff; GBytes *offload_state;
GError *error = NULL; GError *error = NULL;
gboolean result = TRUE; gboolean result = TRUE;
cairo_region_t *clip, *region; cairo_region_t *clip, *region;
char *path; char *path, *diff;
GskRenderNode *node2; GskRenderNode *node2;
const char *generate_values[] = { "offload", "offload2", "diff", NULL }; const char *generate_values[] = { "offload", "offload2", "diff", NULL };
@@ -391,7 +373,7 @@ parse_node_file (GFile *file, const char *generate)
if (gdk_surface_get_scale (surface) != 1.0) if (gdk_surface_get_scale (surface) != 1.0)
{ {
g_print ("Offload tests don't work with fractional scales\n"); g_print ("Offload tests don't work with scale != 1.0\n");
exit (77); exit (77);
} }
@@ -425,20 +407,20 @@ parse_node_file (GFile *file, const char *generate)
if (reference_file == NULL) if (reference_file == NULL)
return FALSE; return FALSE;
diff = diff_with_file (reference_file, offload_state, &error); diff = diff_bytes_with_file (reference_file, offload_state, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && g_bytes_get_size (diff) > 0) if (diff)
{ {
char *basename = g_path_get_basename (reference_file); char *basename = g_path_get_basename (reference_file);
g_print ("Resulting file doesn't match reference (%s):\n%s\n", g_print ("Resulting file doesn't match reference (%s):\n%s\n",
basename, basename,
(const char *) g_bytes_get_data (diff, NULL)); diff);
g_free (basename); g_free (basename);
result = FALSE; result = FALSE;
} }
g_clear_pointer (&offload_state, g_bytes_unref); g_clear_pointer (&offload_state, g_bytes_unref);
g_clear_pointer (&diff, g_bytes_unref); g_clear_pointer (&diff, g_free);
g_clear_pointer (&reference_file, g_free); g_clear_pointer (&reference_file, g_free);
path = test_get_sibling_file (g_file_peek_path (file), ".node", ".node2"); path = test_get_sibling_file (g_file_peek_path (file), ".node", ".node2");
@@ -464,20 +446,20 @@ parse_node_file (GFile *file, const char *generate)
if (reference_file == NULL) if (reference_file == NULL)
return FALSE; return FALSE;
diff = diff_with_file (reference_file, offload_state, &error); diff = diff_bytes_with_file (reference_file, offload_state, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && g_bytes_get_size (diff) > 0) if (diff)
{ {
char *basename = g_path_get_basename (reference_file); char *basename = g_path_get_basename (reference_file);
g_print ("Resulting file doesn't match reference (%s):\n%s\n", g_print ("Resulting file doesn't match reference (%s):\n%s\n",
basename, basename,
(const char *) g_bytes_get_data (diff, NULL)); diff);
g_free (basename); g_free (basename);
result = FALSE; result = FALSE;
} }
g_clear_pointer (&offload_state, g_bytes_unref); g_clear_pointer (&offload_state, g_bytes_unref);
g_clear_pointer (&diff, g_bytes_unref); g_clear_pointer (&diff, g_free);
g_clear_pointer (&reference_file, g_free); g_clear_pointer (&reference_file, g_free);
gsk_render_node_diff (node, node2, &(GskDiffData) { clip, surface }); gsk_render_node_diff (node, node2, &(GskDiffData) { clip, surface });

View File

@@ -107,7 +107,7 @@ compose_table_compare (gconstpointer data)
table = gtk_compose_table_parse (file, NULL); table = gtk_compose_table_parse (file, NULL);
output = gtk_compose_table_print (table); output = gtk_compose_table_print (table);
diff = diff_with_file (expected, output, -1, &error); diff = diff_string_with_file (expected, output, -1, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && diff[0]) if (diff && diff[0])

View File

@@ -256,7 +256,7 @@ load_ui_file (GFile *ui_file,
dir = get_dir_for_file (ref_path); dir = get_dir_for_file (ref_path);
output = generate_focus_chain (window, dir); output = generate_focus_chain (window, dir);
diff = diff_with_file (ref_path, output, -1, &error); diff = diff_string_with_file (ref_path, output, -1, &error);
g_assert_no_error (error); g_assert_no_error (error);
if (diff && diff[0]) if (diff && diff[0])

View File

@@ -19,6 +19,7 @@
#include <glib.h> #include <glib.h>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <gio/gio.h>
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
#include <io.h> #include <io.h>
@@ -28,66 +29,93 @@
#include "testsuite/testutils.h" #include "testsuite/testutils.h"
/*<private>
* diff_bytes_with_file:
* @file1: The filename of the original. This is assumed
* to be the reference to compare against.
* @input: some text contained in a `GBytes` that is
* supposed to match the file's contents
* @error: A return location for an error if diffing could
* not happen
*
* Diffs generated text with a reference file.
*
* If the diffing runs into any error, NULL is returned and
* `error` is set. If diffing succeeds, the error is not set
* and NULL is returned if the file was identical to the
* contents of the file or the actual diff is returned if
* they were not.
*
* Returns: NULL on success or failure, the diff on failure
*/
char * char *
diff_with_file (const char *file1, diff_bytes_with_file (const char *file1,
const char *text, GBytes *input,
gssize len, GError **error)
GError **error)
{ {
char *diff_cmd, *diff, *tmpfile; char *diff_cmd, *diff;
int fd;
diff = NULL; diff = NULL;
diff_cmd = g_find_program_in_path ("diff"); diff_cmd = g_find_program_in_path ("diff");
if (diff_cmd) if (diff_cmd)
{ {
const char *command[] = { diff_cmd, "-u", file1, NULL, NULL }; GSubprocess *process;
GBytes *output;
if (len < 0) process = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE
len = strlen (text); | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
error,
/* write the text buffer to a temporary file */ diff_cmd, "--strip-trailing-cr", "-u", file1, "-", NULL);
fd = g_file_open_tmp (NULL, &tmpfile, error); if (process == NULL)
if (fd < 0)
return NULL; return NULL;
if (write (fd, text, len) != (int) len) if (!g_subprocess_communicate (process,
input,
NULL,
&output,
NULL,
error))
{ {
close (fd); g_object_unref (process);
g_set_error (error, return NULL;
G_FILE_ERROR, G_FILE_ERROR_FAILED,
"Could not write data to temporary file '%s'", tmpfile);
goto done;
} }
close (fd);
command[3] = tmpfile;
/* run diff command */ if (g_subprocess_get_successful (process))
g_spawn_sync (NULL, {
(char **) command, g_clear_pointer (&output, g_bytes_unref);
NULL, }
0, else if (g_subprocess_get_if_exited (process) && g_subprocess_get_exit_status (process) == 1)
NULL, NULL, {
&diff, gsize size;
NULL, NULL,
error);
done: /* this is the condition when the files differ */
g_unlink (tmpfile); diff = g_bytes_unref_to_data (output, &size);
g_free (tmpfile); output = NULL;
g_free (diff_cmd); }
else
{
g_clear_pointer (&output, g_bytes_unref);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"The `diff' process exited with error status %d",
g_subprocess_get_exit_status (process));
}
g_object_unref (process);
} }
else else
{ {
char *buf1; char *buf1;
gsize len1; const char *buf2;
gsize len1, len2;
buf2 = g_bytes_get_data (input, &len2);
if (!g_file_get_contents (file1, &buf1, &len1, error)) if (!g_file_get_contents (file1, &buf1, &len1, error))
return NULL; return NULL;
if ((len != -1 && len != len1) || if ((len2 != len1) ||
strncmp (text, buf1, len1) != 0) strncmp (buf2, buf1, len1) != 0)
diff = g_strdup ("Files differ.\n"); diff = g_strdup ("Files differ.\n");
g_free (buf1); g_free (buf1);
@@ -95,3 +123,24 @@ done:
return diff; return diff;
} }
char *
diff_string_with_file (const char *file1,
const char *text,
gssize len,
GError **error)
{
GBytes *bytes;
char *result;
if (len < 0)
len = strlen (text);
bytes = g_bytes_new_static (text, len);
result = diff_bytes_with_file (file1, bytes, error);
g_bytes_unref (bytes);
return result;
}

View File

@@ -2,8 +2,11 @@
#include <glib.h> #include <glib.h>
char * diff_with_file (const char *file1, char * diff_string_with_file (const char *file1,
const char *text, const char *text,
gssize len, gssize len,
GError **error); GError **error);
char * diff_bytes_with_file (const char *file1,
GBytes *bytes,
GError **error);