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"
G_BEGIN_DECLS
typedef struct _GdkCicp GdkCicp;
struct _GdkCicp
@@ -82,3 +84,5 @@ gdk_cicp_equivalent (const GdkCicp *p1,
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *self);
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,
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 <stdlib.h>
/* For C-style COM wrapper macros */
#define COBJMACROS
/* for CIDA */
#include <shlobj.h>

View File

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

View File

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

View File

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

View File

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

View File

@@ -53,8 +53,6 @@
#define GDK_DEBUG_EVENTS_OR_INPUT (GDK_DEBUG_EVENTS|GDK_DEBUG_INPUT)
#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
* SWP_NOZORDER flag is used. Otherwise it's unobvious why a particular
* 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_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);
char *_gdk_win32_surface_state_to_string (GdkToplevelState state);

View File

@@ -19,8 +19,6 @@
#include "config.h"
#define COBJMACROS
#include "gtkfilechoosernativeprivate.h"
#include "gtknativedialogprivate.h"
@@ -333,10 +331,9 @@ filechooser_win32_thread_data_free (FilechooserWin32ThreadData *data)
g_array_free (data->choices_selections, TRUE);
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);
if (data->self)
g_object_unref (data->self);
g_clear_object (&data->self);
g_free (data->accept_label);
g_free (data->cancel_label);
g_free (data->title);

View File

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

View File

@@ -63,7 +63,8 @@ add_project_arguments('-D_GNU_SOURCE', language: 'c')
if host_machine.system() == 'windows'
add_project_arguments(['-DUNICODE',
'-D_UNICODE',
'-D_WIN32_WINNT=_WIN32_WINNT_WIN7'], language: 'c')
'-DCOBJMACROS',
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10'], language: 'c')
endif
# 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);
if (formats)
if (formats && gdk_dmabuf_formats_get_n_formats (formats) > 0)
{
tmp = gst_caps_from_string (DMABUF_TEXTURE_CAPS);
add_drm_formats_and_modifiers (tmp, formats);
@@ -415,6 +415,7 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
graphene_rect_t *viewport)
{
GstVideoFrame *frame = g_new (GstVideoFrame, 1);
GstMemory *mem;
GdkTexture *texture;
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.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;
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++)
{
GstMemory *mem;
guint mem_idx, length;
gsize skip;
@@ -475,12 +477,15 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
g_object_unref (builder);
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) /
(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))
{
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");
diff = diff_with_file (reference_file, output, -1, &error);
diff = diff_string_with_file (reference_file, output, -1, &error);
g_assert_no_error (error);
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);
diff = diff_with_file (reference_file, output, -1, &error);
diff = diff_string_with_file (reference_file, output, -1, &error);
g_assert_no_error (error);
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);
diff = diff_with_file (reference_file, css, -1, &error);
diff = diff_string_with_file (reference_file, css, -1, &error);
g_assert_no_error (error);
if (diff && diff[0])
@@ -161,7 +161,7 @@ parse_css_file (GFile *file, gboolean generate)
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);
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");
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);
if (diff && diff[0])

View File

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

View File

@@ -22,6 +22,8 @@
#include <gtk/gtk.h>
#include "../testutils.h"
static char *
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);
}
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
append_error_value (GString *string,
GType enum_type,
@@ -162,8 +123,9 @@ parse_node_file (GFile *file, gboolean generate)
char *node_file, *reference_file, *errors_file;
GskRenderNode *node;
GString *errors;
GBytes *diff, *bytes;
GBytes *bytes;
GError *error = NULL;
char *diff;
gboolean result = TRUE;
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);
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);
if (diff && g_bytes_get_size (diff) > 0)
if (diff)
{
g_print ("Resulting file doesn't match reference:\n%s\n",
(const char *) g_bytes_get_data (diff, NULL));
(const char *) diff);
result = FALSE;
}
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);
if (errors_file)
{
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);
if (diff && g_bytes_get_size (diff) > 0)
if (diff)
{
g_print ("Errors don't match expected errors:\n%s\n",
(const char *) g_bytes_get_data (diff, NULL));
(const char *) diff);
result = FALSE;
}
g_clear_pointer (&diff, g_bytes_unref);
g_clear_pointer (&diff, g_free);
g_clear_pointer (&error_bytes, g_bytes_unref);
}
else if (errors->str[0])

View File

@@ -29,6 +29,8 @@
#include <gsk/gskoffloadprivate.h>
#include "gskrendernodeattach.h"
#include "../testutils.h"
static char *
test_get_sibling_file (const char *node_file,
const char *old_ext,
@@ -52,26 +54,6 @@ test_get_sibling_file (const char *node_file,
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
append_error_value (GString *string,
GType enum_type,
@@ -225,7 +207,7 @@ collect_offload_info (GdkSurface *surface,
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);
@@ -364,11 +346,11 @@ parse_node_file (GFile *file, const char *generate)
GdkSubsurface *subsurface;
GskOffload *offload;
GskRenderNode *node, *tmp;
GBytes *offload_state, *diff;
GBytes *offload_state;
GError *error = NULL;
gboolean result = TRUE;
cairo_region_t *clip, *region;
char *path;
char *path, *diff;
GskRenderNode *node2;
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)
{
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);
}
@@ -425,20 +407,20 @@ parse_node_file (GFile *file, const char *generate)
if (reference_file == NULL)
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);
if (diff && g_bytes_get_size (diff) > 0)
if (diff)
{
char *basename = g_path_get_basename (reference_file);
g_print ("Resulting file doesn't match reference (%s):\n%s\n",
basename,
(const char *) g_bytes_get_data (diff, NULL));
diff);
g_free (basename);
result = FALSE;
}
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);
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)
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);
if (diff && g_bytes_get_size (diff) > 0)
if (diff)
{
char *basename = g_path_get_basename (reference_file);
g_print ("Resulting file doesn't match reference (%s):\n%s\n",
basename,
(const char *) g_bytes_get_data (diff, NULL));
diff);
g_free (basename);
result = FALSE;
}
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);
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);
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);
if (diff && diff[0])

View File

@@ -256,7 +256,7 @@ load_ui_file (GFile *ui_file,
dir = get_dir_for_file (ref_path);
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);
if (diff && diff[0])

View File

@@ -19,6 +19,7 @@
#include <glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#ifdef G_OS_WIN32
#include <io.h>
@@ -28,66 +29,93 @@
#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 *
diff_with_file (const char *file1,
const char *text,
gssize len,
GError **error)
diff_bytes_with_file (const char *file1,
GBytes *input,
GError **error)
{
char *diff_cmd, *diff, *tmpfile;
int fd;
char *diff_cmd, *diff;
diff = NULL;
diff_cmd = g_find_program_in_path ("diff");
if (diff_cmd)
{
const char *command[] = { diff_cmd, "-u", file1, NULL, NULL };
GSubprocess *process;
GBytes *output;
if (len < 0)
len = strlen (text);
/* write the text buffer to a temporary file */
fd = g_file_open_tmp (NULL, &tmpfile, error);
if (fd < 0)
process = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE
| G_SUBPROCESS_FLAGS_STDOUT_PIPE,
error,
diff_cmd, "--strip-trailing-cr", "-u", file1, "-", NULL);
if (process == NULL)
return NULL;
if (write (fd, text, len) != (int) len)
if (!g_subprocess_communicate (process,
input,
NULL,
&output,
NULL,
error))
{
close (fd);
g_set_error (error,
G_FILE_ERROR, G_FILE_ERROR_FAILED,
"Could not write data to temporary file '%s'", tmpfile);
goto done;
g_object_unref (process);
return NULL;
}
close (fd);
command[3] = tmpfile;
/* run diff command */
g_spawn_sync (NULL,
(char **) command,
NULL,
0,
NULL, NULL,
&diff,
NULL, NULL,
error);
if (g_subprocess_get_successful (process))
{
g_clear_pointer (&output, g_bytes_unref);
}
else if (g_subprocess_get_if_exited (process) && g_subprocess_get_exit_status (process) == 1)
{
gsize size;
done:
g_unlink (tmpfile);
g_free (tmpfile);
g_free (diff_cmd);
/* this is the condition when the files differ */
diff = g_bytes_unref_to_data (output, &size);
output = NULL;
}
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
{
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))
return NULL;
if ((len != -1 && len != len1) ||
strncmp (text, buf1, len1) != 0)
if ((len2 != len1) ||
strncmp (buf2, buf1, len1) != 0)
diff = g_strdup ("Files differ.\n");
g_free (buf1);
@@ -95,3 +123,24 @@ done:
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>
char * diff_with_file (const char *file1,
const char *text,
gssize len,
GError **error);
char * diff_string_with_file (const char *file1,
const char *text,
gssize len,
GError **error);
char * diff_bytes_with_file (const char *file1,
GBytes *bytes,
GError **error);