Compare commits
46 Commits
oklab-supp
...
gdk-win32-
Author | SHA1 | Date | |
---|---|---|---|
|
e4aa58b4c0 | ||
|
be2adb1838 | ||
|
0113fdc8d5 | ||
|
53cbc64f41 | ||
|
83387608ee | ||
|
a5b4d2b500 | ||
|
1b83d87cf5 | ||
|
6c2eb08b07 | ||
|
ab1c85830c | ||
|
d154decbb5 | ||
|
c7705f156a | ||
|
20bdb0d7d5 | ||
|
f840ae1337 | ||
|
02feba87f2 | ||
|
220d7a3d5e | ||
|
39686daa23 | ||
|
b6269a3234 | ||
|
2879f6a99b | ||
|
03a86b4667 | ||
|
7eb96c39c5 | ||
|
b4c5a7af69 | ||
|
d120aaf6ee | ||
|
004d787cb2 | ||
|
7b554240f3 | ||
|
7837f342e9 | ||
|
236139c78a | ||
|
789bb83b5a | ||
|
0a65221721 | ||
|
b37947ff20 | ||
|
0d4f827de8 | ||
|
1f52048e77 | ||
|
7600d44995 | ||
|
8bb806cd85 | ||
|
28aacf3db4 | ||
|
95ad05181c | ||
|
b4a54bb9cb | ||
|
12dd5be649 | ||
|
c86e45c432 | ||
|
1ad5943cd8 | ||
|
34c69b2868 | ||
|
28817b4bb2 | ||
|
b0acf2a7a8 | ||
|
32d03a548e | ||
|
fecadae80c | ||
|
2d1367ccdc | ||
|
3a8e1c55e1 |
@@ -198,11 +198,11 @@ fedora-mingw64:
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
|
||||
msys2-mingw64:
|
||||
msys2-ucrt64:
|
||||
extends: .mingw-defaults
|
||||
needs: []
|
||||
variables:
|
||||
MSYSTEM: "MINGW64"
|
||||
MSYSTEM: "UCRT64"
|
||||
CHERE_INVOKING: "yes"
|
||||
artifacts:
|
||||
when: always
|
||||
|
@@ -2,12 +2,6 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$MSYSTEM" == "MINGW32" ]]; then
|
||||
export MSYS2_ARCH="i686"
|
||||
else
|
||||
export MSYS2_ARCH="x86_64"
|
||||
fi
|
||||
|
||||
# Update everything
|
||||
pacman --noconfirm -Suy
|
||||
|
||||
@@ -15,27 +9,27 @@ pacman --noconfirm -Suy
|
||||
pacman --noconfirm -S --needed \
|
||||
base-devel \
|
||||
git \
|
||||
mingw-w64-$MSYS2_ARCH-cc \
|
||||
mingw-w64-$MSYS2_ARCH-ccache \
|
||||
mingw-w64-$MSYS2_ARCH-pkgconf \
|
||||
mingw-w64-$MSYS2_ARCH-gobject-introspection \
|
||||
mingw-w64-$MSYS2_ARCH-meson \
|
||||
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
|
||||
mingw-w64-$MSYS2_ARCH-atk \
|
||||
mingw-w64-$MSYS2_ARCH-cairo \
|
||||
mingw-w64-$MSYS2_ARCH-gdk-pixbuf2 \
|
||||
mingw-w64-$MSYS2_ARCH-glib2 \
|
||||
mingw-w64-$MSYS2_ARCH-graphene \
|
||||
mingw-w64-$MSYS2_ARCH-json-glib \
|
||||
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject \
|
||||
mingw-w64-$MSYS2_ARCH-shaderc \
|
||||
mingw-w64-$MSYS2_ARCH-vulkan \
|
||||
mingw-w64-$MSYS2_ARCH-vulkan-headers
|
||||
${MINGW_PACKAGE_PREFIX}-cc \
|
||||
${MINGW_PACKAGE_PREFIX}-ccache \
|
||||
${MINGW_PACKAGE_PREFIX}-pkgconf \
|
||||
${MINGW_PACKAGE_PREFIX}-gobject-introspection \
|
||||
${MINGW_PACKAGE_PREFIX}-meson \
|
||||
${MINGW_PACKAGE_PREFIX}-adwaita-icon-theme \
|
||||
${MINGW_PACKAGE_PREFIX}-atk \
|
||||
${MINGW_PACKAGE_PREFIX}-cairo \
|
||||
${MINGW_PACKAGE_PREFIX}-gdk-pixbuf2 \
|
||||
${MINGW_PACKAGE_PREFIX}-glib2 \
|
||||
${MINGW_PACKAGE_PREFIX}-graphene \
|
||||
${MINGW_PACKAGE_PREFIX}-json-glib \
|
||||
${MINGW_PACKAGE_PREFIX}-libepoxy \
|
||||
${MINGW_PACKAGE_PREFIX}-pango \
|
||||
${MINGW_PACKAGE_PREFIX}-fribidi \
|
||||
${MINGW_PACKAGE_PREFIX}-gst-plugins-bad-libs \
|
||||
${MINGW_PACKAGE_PREFIX}-shared-mime-info \
|
||||
${MINGW_PACKAGE_PREFIX}-python-gobject \
|
||||
${MINGW_PACKAGE_PREFIX}-shaderc \
|
||||
${MINGW_PACKAGE_PREFIX}-vulkan \
|
||||
${MINGW_PACKAGE_PREFIX}-vulkan-headers
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
|
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor-application.h"
|
||||
#include "constraint-editor-window.h"
|
||||
|
||||
struct _ConstraintEditorApplication
|
||||
{
|
||||
GtkApplication parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditorApplication, constraint_editor_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
constraint_editor_application_init (ConstraintEditorApplication *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (data));
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
constraint_editor_application_startup (GApplication *app)
|
||||
{
|
||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
const char *open_accels[2] = { "<Ctrl>O", NULL };
|
||||
GtkCssProvider *provider;
|
||||
|
||||
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_activate (GApplication *app)
|
||||
{
|
||||
ConstraintEditorWindow *win;
|
||||
|
||||
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_open (GApplication *app,
|
||||
GFile **files,
|
||||
int n_files,
|
||||
const char *hint)
|
||||
{
|
||||
ConstraintEditorWindow *win;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_files; i++)
|
||||
{
|
||||
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||
constraint_editor_window_load (win, files[i]);
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
|
||||
{
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
||||
|
||||
application_class->startup = constraint_editor_application_startup;
|
||||
application_class->activate = constraint_editor_application_activate;
|
||||
application_class->open = constraint_editor_application_open;
|
||||
}
|
||||
|
||||
ConstraintEditorApplication *
|
||||
constraint_editor_application_new (void)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
|
||||
"application-id", "org.gtk.gtk4.ConstraintEditor",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
@@ -1,652 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor-window.h"
|
||||
#include "constraint-view.h"
|
||||
#include "constraint-editor.h"
|
||||
#include "guide-editor.h"
|
||||
|
||||
struct _ConstraintEditorWindow
|
||||
{
|
||||
GtkApplicationWindow parent_instance;
|
||||
|
||||
GtkWidget *paned;
|
||||
GtkWidget *view;
|
||||
GtkWidget *list;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static GtkConstraintTarget *
|
||||
find_target (GListModel *model,
|
||||
GtkConstraintTarget *orig)
|
||||
{
|
||||
const char *name;
|
||||
const char *model_name;
|
||||
gpointer item;
|
||||
int i;
|
||||
|
||||
if (orig == NULL)
|
||||
return NULL;
|
||||
|
||||
if (GTK_IS_LABEL (orig))
|
||||
name = gtk_label_get_label (GTK_LABEL (orig));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (orig))
|
||||
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (orig));
|
||||
else
|
||||
{
|
||||
g_warning ("Don't know how to handle %s targets", G_OBJECT_TYPE_NAME (orig));
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
item = g_list_model_get_item (model, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_WIDGET (item))
|
||||
model_name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||
else
|
||||
model_name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||
|
||||
if (strcmp (name, model_name) == 0)
|
||||
return GTK_CONSTRAINT_TARGET (item);
|
||||
}
|
||||
g_warning ("Failed to find target '%s'", name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||
GFile *file)
|
||||
{
|
||||
char *path;
|
||||
GtkBuilder *builder;
|
||||
GError *error = NULL;
|
||||
GtkWidget *view;
|
||||
GtkLayoutManager *layout;
|
||||
GtkWidget *child;
|
||||
const char *name;
|
||||
gpointer item;
|
||||
int i;
|
||||
GListModel *list;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
if (!gtk_builder_add_from_file (builder, path, &error))
|
||||
{
|
||||
g_print ("Could not load %s: %s", path, error->message);
|
||||
g_error_free (error);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
|
||||
if (!GTK_IS_BOX (view))
|
||||
{
|
||||
g_print ("Could not load %s: No GtkBox named 'view'", path);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
layout = gtk_widget_get_layout_manager (view);
|
||||
if (!GTK_IS_CONSTRAINT_LAYOUT (layout))
|
||||
{
|
||||
g_print ("Could not load %s: Widget 'view' does not use GtkConstraintLayout", path);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (child = gtk_widget_get_first_child (view);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!GTK_IS_LABEL (child))
|
||||
{
|
||||
g_print ("Skipping non-GtkLabel child\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
name = gtk_label_get_label (GTK_LABEL (child));
|
||||
constraint_view_add_child (CONSTRAINT_VIEW (self->view), name);
|
||||
}
|
||||
|
||||
list = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (layout));
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
GtkConstraintGuide *guide, *clone;
|
||||
int w, h;
|
||||
|
||||
item = g_list_model_get_item (list, i);
|
||||
guide = GTK_CONSTRAINT_GUIDE (item);
|
||||
|
||||
/* need to clone here, to attach to the right targets */
|
||||
clone = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (clone, gtk_constraint_guide_get_name (guide));
|
||||
gtk_constraint_guide_set_strength (clone, gtk_constraint_guide_get_strength (guide));
|
||||
gtk_constraint_guide_get_min_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_min_size (clone, w, h);
|
||||
gtk_constraint_guide_get_nat_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_nat_size (clone, w, h);
|
||||
gtk_constraint_guide_get_max_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_max_size (clone, w, h);
|
||||
constraint_view_add_guide (CONSTRAINT_VIEW (self->view), clone);
|
||||
g_object_unref (guide);
|
||||
g_object_unref (clone);
|
||||
}
|
||||
g_object_unref (list);
|
||||
|
||||
list = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (layout));
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
GtkConstraint *constraint;
|
||||
GtkConstraint *clone;
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintTarget *source;
|
||||
GtkConstraintAttribute source_attr;
|
||||
|
||||
item = g_list_model_get_item (list, i);
|
||||
constraint = GTK_CONSTRAINT (item);
|
||||
|
||||
target = gtk_constraint_get_target (constraint);
|
||||
source = gtk_constraint_get_source (constraint);
|
||||
source_attr = gtk_constraint_get_source_attribute (constraint);
|
||||
|
||||
if (source == NULL && source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)
|
||||
clone = gtk_constraint_new_constant (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
|
||||
gtk_constraint_get_target_attribute (constraint),
|
||||
gtk_constraint_get_relation (constraint),
|
||||
gtk_constraint_get_constant (constraint),
|
||||
gtk_constraint_get_strength (constraint));
|
||||
else
|
||||
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
|
||||
gtk_constraint_get_target_attribute (constraint),
|
||||
gtk_constraint_get_relation (constraint),
|
||||
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
|
||||
source_attr,
|
||||
gtk_constraint_get_multiplier (constraint),
|
||||
gtk_constraint_get_constant (constraint),
|
||||
gtk_constraint_get_strength (constraint));
|
||||
|
||||
constraint_view_add_constraint (CONSTRAINT_VIEW (self->view), clone);
|
||||
|
||||
g_object_unref (constraint);
|
||||
g_object_unref (clone);
|
||||
}
|
||||
g_object_unref (list);
|
||||
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
open_response_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *user_data)
|
||||
{
|
||||
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
|
||||
ConstraintEditorWindow *self = user_data;
|
||||
GFile *file;
|
||||
|
||||
file = gtk_file_dialog_open_finish (dialog, result, NULL);
|
||||
if (file)
|
||||
{
|
||||
constraint_editor_window_load (self, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
open_cb (GtkWidget *button,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
GtkFileDialog *dialog;
|
||||
GFile *cwd;
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "Open file");
|
||||
cwd = g_file_new_for_path (".");
|
||||
gtk_file_dialog_set_initial_folder (dialog, cwd);
|
||||
g_object_unref (cwd);
|
||||
gtk_file_dialog_open (dialog, GTK_WINDOW (self), NULL, open_response_cb, self);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_child (GString *str,
|
||||
int indent,
|
||||
GtkWidget *child)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = gtk_widget_get_name (child);
|
||||
g_string_append_printf (str, "%*s<child>\n", indent, "");
|
||||
g_string_append_printf (str, "%*s <object class=\"GtkLabel\" id=\"%s\">\n", indent, "", name);
|
||||
g_string_append_printf (str, "%*s <property name=\"label\">%s</property>\n", indent, "", name);
|
||||
g_string_append_printf (str, "%*s </object>\n", indent, "");
|
||||
g_string_append_printf (str, "%*s</child>\n", indent, "");
|
||||
}
|
||||
|
||||
static char *
|
||||
serialize_model (GListModel *list)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
int i;
|
||||
|
||||
g_string_append (str, "<interface>\n");
|
||||
g_string_append (str, " <object class=\"GtkBox\" id=\"view\">\n");
|
||||
g_string_append (str, " <property name=\"layout-manager\">\n");
|
||||
g_string_append (str, " <object class=\"GtkConstraintLayout\">\n");
|
||||
g_string_append (str, " <constraints>\n");
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (list, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
constraint_editor_serialize_constraint (str, 10, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
guide_editor_serialize_guide (str, 10, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
g_string_append (str, " </constraints>\n");
|
||||
g_string_append (str, " </object>\n");
|
||||
g_string_append (str, " </property>\n");
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (list, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_WIDGET (item))
|
||||
serialize_child (str, 4, GTK_WIDGET (item));
|
||||
}
|
||||
g_string_append (str, " </object>\n");
|
||||
g_string_append (str, "</interface>\n");
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
save_response_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *user_data)
|
||||
{
|
||||
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
|
||||
ConstraintEditorWindow *self = user_data;
|
||||
GFile *file;
|
||||
|
||||
file = gtk_file_dialog_save_finish (dialog, result, NULL);
|
||||
if (file)
|
||||
{
|
||||
GListModel *model;
|
||||
char *text;
|
||||
GError *error = NULL;
|
||||
|
||||
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
|
||||
text = serialize_model (model);
|
||||
g_file_replace_contents (file, text, strlen (text),
|
||||
NULL, FALSE,
|
||||
G_FILE_CREATE_NONE,
|
||||
NULL,
|
||||
NULL,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
GtkAlertDialog *alert;
|
||||
|
||||
alert = gtk_alert_dialog_new ("Saving failed");
|
||||
gtk_alert_dialog_set_detail (alert, error->message);
|
||||
gtk_alert_dialog_show (alert,
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))));
|
||||
g_object_unref (alert);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (text);
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
save_cb (GtkWidget *button,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
GtkFileDialog *dialog;
|
||||
GFile *cwd;
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "Save constraints");
|
||||
cwd = g_file_new_for_path (".");
|
||||
gtk_file_dialog_set_initial_folder (dialog, cwd);
|
||||
g_object_unref (cwd);
|
||||
gtk_file_dialog_save (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
NULL,
|
||||
save_response_cb, self);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_WINDOW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static int child_counter;
|
||||
static int guide_counter;
|
||||
|
||||
static void
|
||||
add_child (ConstraintEditorWindow *win)
|
||||
{
|
||||
char *name;
|
||||
|
||||
child_counter++;
|
||||
name = g_strdup_printf ("Child %d", child_counter);
|
||||
constraint_view_add_child (CONSTRAINT_VIEW (win->view), name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
add_guide (ConstraintEditorWindow *win)
|
||||
{
|
||||
char *name;
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
guide_counter++;
|
||||
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||
guide = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (guide, name);
|
||||
g_free (name);
|
||||
|
||||
constraint_view_add_guide (CONSTRAINT_VIEW (win->view), guide);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_done (ConstraintEditor *editor,
|
||||
GtkConstraint *constraint,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkConstraint *old_constraint;
|
||||
|
||||
g_object_get (editor, "constraint", &old_constraint, NULL);
|
||||
|
||||
if (old_constraint)
|
||||
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view), old_constraint);
|
||||
|
||||
constraint_view_add_constraint (CONSTRAINT_VIEW (win->view), constraint);
|
||||
|
||||
g_clear_object (&old_constraint);
|
||||
|
||||
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW)));
|
||||
}
|
||||
|
||||
static void
|
||||
edit_constraint (ConstraintEditorWindow *win,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkWidget *window;
|
||||
ConstraintEditor *editor;
|
||||
GListModel *model;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
if (constraint)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Edit Constraint");
|
||||
else
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Create Constraint");
|
||||
|
||||
model = constraint_view_get_model (CONSTRAINT_VIEW (win->view));
|
||||
|
||||
editor = constraint_editor_new (model, constraint);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
static void
|
||||
add_constraint (ConstraintEditorWindow *win)
|
||||
{
|
||||
edit_constraint (win, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_done (GuideEditor *editor,
|
||||
GtkConstraintGuide *guide,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW)));
|
||||
}
|
||||
|
||||
static void
|
||||
edit_guide (ConstraintEditorWindow *win,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GuideEditor *editor;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Edit Guide");
|
||||
|
||||
editor = guide_editor_new (guide);
|
||||
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
static void
|
||||
row_activated (GtkListBox *list,
|
||||
GtkListBoxRow *row,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GObject *item;
|
||||
|
||||
item = G_OBJECT (g_object_get_data (G_OBJECT (row), "item"));
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
g_type_ensure (CONSTRAINT_VIEW_TYPE);
|
||||
|
||||
object_class->dispose = constraint_editor_window_dispose;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, paned);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, save_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_child);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_guide);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
|
||||
gtk_widget_class_bind_template_callback (widget_class, row_activated);
|
||||
}
|
||||
|
||||
static void
|
||||
row_edit (GtkButton *button,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkWidget *row;
|
||||
GObject *item;
|
||||
|
||||
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
|
||||
static void
|
||||
mark_constraints_invalid (ConstraintEditorWindow *win,
|
||||
gpointer removed)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GObject *item;
|
||||
|
||||
for (child = gtk_widget_get_first_child (win->list);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (child), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
{
|
||||
GtkConstraint *constraint = GTK_CONSTRAINT (item);
|
||||
|
||||
if (gtk_constraint_get_target (constraint) == (GtkConstraintTarget *)removed ||
|
||||
gtk_constraint_get_source (constraint) == (GtkConstraintTarget *)removed)
|
||||
{
|
||||
GtkWidget *button;
|
||||
button = (GtkWidget *)g_object_get_data (G_OBJECT (child), "edit");
|
||||
gtk_button_set_icon_name (GTK_BUTTON (button), "dialog-warning-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Constraint is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
row_delete (GtkButton *button,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkWidget *row;
|
||||
GObject *item;
|
||||
|
||||
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view),
|
||||
GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
mark_constraints_invalid (win, item);
|
||||
constraint_view_remove_guide (CONSTRAINT_VIEW (win->view),
|
||||
GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
mark_constraints_invalid (win, item);
|
||||
constraint_view_remove_child (CONSTRAINT_VIEW (win->view),
|
||||
GTK_WIDGET (item));
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_widget_func (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
ConstraintEditorWindow *win = user_data;
|
||||
const char *name;
|
||||
char *freeme = NULL;
|
||||
GtkWidget *row, *box, *label, *button;
|
||||
|
||||
if (GTK_IS_WIDGET (item))
|
||||
name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||
else if (GTK_IS_CONSTRAINT (item))
|
||||
name = freeme = constraint_editor_constraint_to_string (GTK_CONSTRAINT (item));
|
||||
else
|
||||
name = "";
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
label = gtk_label_new (name);
|
||||
if (GTK_IS_WIDGET (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
g_object_bind_property (item, "name",
|
||||
label, "label",
|
||||
G_BINDING_DEFAULT);
|
||||
gtk_widget_set_margin_start (label, 10);
|
||||
gtk_widget_set_margin_end (label, 10);
|
||||
gtk_widget_set_margin_top (label, 10);
|
||||
gtk_widget_set_margin_bottom (label, 10);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("document-edit-symbolic");
|
||||
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
|
||||
g_object_set_data (G_OBJECT (row), "edit", button);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
}
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
}
|
||||
|
||||
g_free (freeme);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_init (ConstraintEditorWindow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (self->list),
|
||||
constraint_view_get_model (CONSTRAINT_VIEW (self->view)),
|
||||
create_widget_func,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
ConstraintEditorWindow *
|
||||
constraint_editor_window_new (ConstraintEditorApplication *application)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_WINDOW_TYPE,
|
||||
"application", application,
|
||||
NULL);
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "constraint-editor-application.h"
|
||||
|
||||
|
||||
#define CONSTRAINT_EDITOR_WINDOW_TYPE (constraint_editor_window_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditorWindow, constraint_editor_window, CONSTRAINT, EDITOR_WINDOW, GtkApplicationWindow)
|
||||
|
||||
ConstraintEditorWindow * constraint_editor_window_new (ConstraintEditorApplication *application);
|
||||
|
||||
gboolean constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||
GFile *file);
|
@@ -1,77 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
|
||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
<property name="tooltip-text">Open ui file</property>
|
||||
<signal name="clicked" handler="open_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-save-symbolic</property>
|
||||
<property name="tooltip-text">Save to ui file</property>
|
||||
<signal name="clicked" handler="save_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned" id="paned">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Child</property>
|
||||
<signal name="clicked" handler="add_child" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Guide</property>
|
||||
<signal name="clicked" handler="add_guide" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Constraint</property>
|
||||
<signal name="clicked" handler="add_constraint" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="list">
|
||||
<property name="show-separators">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="ConstraintView" id="view">
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@@ -1,716 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor.h"
|
||||
#include "constraint-view.h"
|
||||
|
||||
struct _ConstraintEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *grid;
|
||||
GtkWidget *target;
|
||||
GtkWidget *target_attr;
|
||||
GtkWidget *relation;
|
||||
GtkWidget *source;
|
||||
GtkWidget *source_attr;
|
||||
GtkWidget *multiplier;
|
||||
GtkWidget *constant;
|
||||
GtkWidget *strength;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *button;
|
||||
|
||||
GtkConstraint *constraint;
|
||||
GListModel *model;
|
||||
|
||||
gboolean constructed;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_MODEL = 1,
|
||||
PROP_CONSTRAINT,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *pspecs[LAST_PROP];
|
||||
|
||||
enum {
|
||||
DONE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditor, constraint_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static const char *
|
||||
get_target_name (GtkConstraintTarget *target)
|
||||
{
|
||||
if (target == NULL)
|
||||
return "Super";
|
||||
else if (GTK_IS_WIDGET (target))
|
||||
return gtk_widget_get_name (GTK_WIDGET (target));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (target))
|
||||
return gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (target));
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_target_combo (GListModel *model,
|
||||
GtkWidget *combo,
|
||||
gboolean is_source)
|
||||
{
|
||||
GtkStringList *targets;
|
||||
int i;
|
||||
|
||||
targets = gtk_string_list_new (NULL);
|
||||
|
||||
gtk_string_list_append (targets, "Super");
|
||||
|
||||
if (model)
|
||||
{
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GObject *item = g_list_model_get_object (model, i);
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
continue;
|
||||
|
||||
gtk_string_list_append (targets, get_target_name (GTK_CONSTRAINT_TARGET (item)));
|
||||
g_object_unref (item);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (combo), G_LIST_MODEL (targets));
|
||||
g_object_unref (targets);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
get_target (GListModel *model,
|
||||
const char *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (id == NULL)
|
||||
return NULL;
|
||||
|
||||
if (strcmp ("Super", id) == 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GObject *item = g_list_model_get_object (model, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
continue;
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
if (strcmp (id, gtk_widget_get_name (GTK_WIDGET (item))) == 0)
|
||||
return item;
|
||||
}
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
if (strcmp (id, gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item))) == 0)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
select_target (GtkDropDown *combo,
|
||||
const char *target_name)
|
||||
{
|
||||
GListModel *model = gtk_drop_down_get_model (combo);
|
||||
|
||||
for (unsigned int i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GtkStringObject *s = g_list_model_get_item (model, i);
|
||||
|
||||
g_object_unref (s);
|
||||
if (strcmp (target_name, gtk_string_object_get_string (s)) == 0)
|
||||
{
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GtkConstraintAttribute
|
||||
get_attr (unsigned int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
case 1: return GTK_CONSTRAINT_ATTRIBUTE_LEFT;
|
||||
case 2: return GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
|
||||
case 3: return GTK_CONSTRAINT_ATTRIBUTE_TOP;
|
||||
case 4: return GTK_CONSTRAINT_ATTRIBUTE_BOTTOM;
|
||||
case 5: return GTK_CONSTRAINT_ATTRIBUTE_START;
|
||||
case 6: return GTK_CONSTRAINT_ATTRIBUTE_END;
|
||||
case 7: return GTK_CONSTRAINT_ATTRIBUTE_WIDTH;
|
||||
case 8: return GTK_CONSTRAINT_ATTRIBUTE_HEIGHT;
|
||||
case 9: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_X;
|
||||
case 10: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y;
|
||||
case 11: return GTK_CONSTRAINT_ATTRIBUTE_BASELINE;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_attr_id (GtkConstraintAttribute attr)
|
||||
{
|
||||
switch (attr)
|
||||
{
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_NONE: return 0;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_LEFT: return 1;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_RIGHT: return 2;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_TOP: return 3;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_BOTTOM: return 4;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_START: return 5;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_END: return 6;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_WIDTH: return 7;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_HEIGHT: return 8;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_X: return 9;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y: return 10;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_BASELINE: return 11;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_attr_nick (GtkConstraintAttribute attr)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||
GEnumValue *value = g_enum_get_value (class, attr);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
static GtkConstraintRelation
|
||||
get_relation (unsigned int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_RELATION_LE;
|
||||
case 1: return GTK_CONSTRAINT_RELATION_EQ;
|
||||
case 2: return GTK_CONSTRAINT_RELATION_GE;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_relation_id (GtkConstraintRelation relation)
|
||||
{
|
||||
switch (relation)
|
||||
{
|
||||
case GTK_CONSTRAINT_RELATION_LE: return 0;
|
||||
case GTK_CONSTRAINT_RELATION_EQ: return 1;
|
||||
case GTK_CONSTRAINT_RELATION_GE: return 2;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_relation_nick (GtkConstraintRelation relation)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||
GEnumValue *value = g_enum_get_value (class, relation);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_relation_display_name (GtkConstraintRelation relation)
|
||||
{
|
||||
switch (relation)
|
||||
{
|
||||
case GTK_CONSTRAINT_RELATION_LE:
|
||||
return "≤";
|
||||
case GTK_CONSTRAINT_RELATION_EQ:
|
||||
return "=";
|
||||
case GTK_CONSTRAINT_RELATION_GE:
|
||||
return "≥";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (unsigned int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
|
||||
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
|
||||
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
|
||||
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_strength_id (GtkConstraintStrength strength)
|
||||
{
|
||||
switch (strength)
|
||||
{
|
||||
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
|
||||
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
|
||||
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
|
||||
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_strength_nick (GtkConstraintStrength strength)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value (class, strength);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
void
|
||||
constraint_editor_serialize_constraint (GString *str,
|
||||
int indent,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
const char *target;
|
||||
const char *target_attr;
|
||||
const char *relation;
|
||||
const char *source;
|
||||
const char *source_attr;
|
||||
double multiplier;
|
||||
double constant;
|
||||
const char *strength;
|
||||
|
||||
target = get_target_name (gtk_constraint_get_target (constraint));
|
||||
target_attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||
source = get_target_name (gtk_constraint_get_source (constraint));
|
||||
source_attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||
multiplier = gtk_constraint_get_multiplier (constraint);
|
||||
constant = gtk_constraint_get_constant (constraint);
|
||||
strength = get_strength_nick (gtk_constraint_get_strength (constraint));
|
||||
|
||||
g_string_append_printf (str, "%*s<constraint target=\"%s\" target-attribute=\"%s\"\n", indent, "", target, target_attr);
|
||||
g_string_append_printf (str, "%*s relation=\"%s\"\n", indent, "", relation);
|
||||
if (strcmp (source_attr, "none") != 0)
|
||||
{
|
||||
g_string_append_printf (str, "%*s source=\"%s\" source-attribute=\"%s\"\n", indent, "", source, source_attr);
|
||||
g_string_append_printf (str, "%*s multiplier=\"%g\"\n", indent, "", multiplier);
|
||||
}
|
||||
g_string_append_printf (str, "%*s constant=\"%g\"\n", indent, "", constant);
|
||||
g_string_append_printf (str, "%*s strength=\"%s\" />\n", indent, "", strength);
|
||||
}
|
||||
|
||||
static void
|
||||
create_constraint (GtkButton *button,
|
||||
ConstraintEditor *editor)
|
||||
{
|
||||
gpointer obj;
|
||||
gpointer target;
|
||||
GtkConstraintAttribute target_attr;
|
||||
gpointer source;
|
||||
GtkConstraintAttribute source_attr;
|
||||
GtkConstraintRelation relation;
|
||||
double multiplier;
|
||||
double constant;
|
||||
int strength;
|
||||
GtkConstraint *constraint;
|
||||
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
|
||||
if (obj)
|
||||
target = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
|
||||
else
|
||||
target = NULL;
|
||||
target_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->target_attr)));
|
||||
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
|
||||
if (obj)
|
||||
source = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
|
||||
else
|
||||
source = NULL;
|
||||
source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN(editor->source_attr)));
|
||||
|
||||
relation = get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation)));
|
||||
|
||||
multiplier = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->multiplier)), NULL);
|
||||
|
||||
constant = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->constant)), NULL);
|
||||
|
||||
strength = get_strength (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength)));
|
||||
|
||||
constraint = gtk_constraint_new (target, target_attr,
|
||||
relation,
|
||||
source, source_attr,
|
||||
multiplier,
|
||||
constant,
|
||||
strength);
|
||||
g_signal_emit (editor, signals[DONE], 0, constraint);
|
||||
g_object_unref (constraint);
|
||||
}
|
||||
|
||||
static void
|
||||
source_attr_changed (ConstraintEditor *editor)
|
||||
{
|
||||
if (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))) == GTK_CONSTRAINT_ATTRIBUTE_NONE)
|
||||
{
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source), GTK_INVALID_LIST_POSITION);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "");
|
||||
gtk_widget_set_sensitive (editor->source, FALSE);
|
||||
gtk_widget_set_sensitive (editor->multiplier, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_sensitive (editor->source, TRUE);
|
||||
gtk_widget_set_sensitive (editor->multiplier, TRUE);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1");
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
constraint_editor_constraint_to_string (GtkConstraint *constraint)
|
||||
{
|
||||
GString *str;
|
||||
const char *name;
|
||||
const char *attr;
|
||||
const char *relation;
|
||||
double c, m;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
name = get_target_name (gtk_constraint_get_target (constraint));
|
||||
attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||
relation = get_relation_display_name (gtk_constraint_get_relation (constraint));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||
|
||||
c = gtk_constraint_get_constant (constraint);
|
||||
|
||||
attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = get_target_name (gtk_constraint_get_source (constraint));
|
||||
m = gtk_constraint_get_multiplier (constraint);
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s", name, attr);
|
||||
|
||||
if (m != 1.0)
|
||||
g_string_append_printf (str, " × %g", m);
|
||||
|
||||
if (c > 0.0)
|
||||
g_string_append_printf (str, " + %g", c);
|
||||
else if (c < 0.0)
|
||||
g_string_append_printf (str, " - %g", -c);
|
||||
}
|
||||
else
|
||||
g_string_append_printf (str, "%g", c);
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_preview (ConstraintEditor *editor)
|
||||
{
|
||||
GString *str;
|
||||
const char *name;
|
||||
const char *attr;
|
||||
const char *relation;
|
||||
const char *multiplier;
|
||||
const char *constant;
|
||||
double c, m;
|
||||
|
||||
if (!editor->constructed)
|
||||
return;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target))));
|
||||
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected ((GTK_DROP_DOWN (editor->target_attr)))));
|
||||
relation = get_relation_nick (get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation))));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||
|
||||
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
|
||||
c = g_ascii_strtod (constant, NULL);
|
||||
|
||||
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source))));
|
||||
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
|
||||
m = g_ascii_strtod (multiplier, NULL);
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s", name, attr);
|
||||
|
||||
if (m != 1.0)
|
||||
g_string_append_printf (str, " × %g", m);
|
||||
|
||||
if (c > 0.0)
|
||||
g_string_append_printf (str, " + %g", c);
|
||||
else if (c < 0.0)
|
||||
g_string_append_printf (str, " - %g", -c);
|
||||
}
|
||||
else
|
||||
g_string_append_printf (str, "%g", c);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (editor->preview), str->str);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_button (ConstraintEditor *editor)
|
||||
{
|
||||
gpointer obj;
|
||||
const char *target;
|
||||
const char *source;
|
||||
GtkConstraintAttribute source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr)));
|
||||
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
|
||||
target = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
|
||||
|
||||
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
|
||||
source = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
|
||||
|
||||
if (target && (source || (source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)))
|
||||
gtk_widget_set_sensitive (editor->button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (editor->button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_init (ConstraintEditor *editor)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_constructed (GObject *object)
|
||||
{
|
||||
ConstraintEditor *editor = CONSTRAINT_EDITOR (object);
|
||||
|
||||
constraint_target_combo (editor->model, editor->target, FALSE);
|
||||
constraint_target_combo (editor->model, editor->source, TRUE);
|
||||
|
||||
if (editor->constraint)
|
||||
{
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintAttribute attr;
|
||||
GtkConstraintRelation relation;
|
||||
GtkConstraintStrength strength;
|
||||
char *val;
|
||||
double multiplier;
|
||||
double constant;
|
||||
|
||||
target = gtk_constraint_get_target (editor->constraint);
|
||||
select_target (GTK_DROP_DOWN (editor->target), get_target_name (target));
|
||||
|
||||
attr = gtk_constraint_get_target_attribute (editor->constraint);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (attr));
|
||||
|
||||
target = gtk_constraint_get_source (editor->constraint);
|
||||
select_target (GTK_DROP_DOWN (editor->source), get_target_name (target));
|
||||
|
||||
attr = gtk_constraint_get_source_attribute (editor->constraint);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (attr));
|
||||
|
||||
relation = gtk_constraint_get_relation (editor->constraint);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (relation));
|
||||
|
||||
multiplier = gtk_constraint_get_multiplier (editor->constraint);
|
||||
val = g_strdup_printf ("%g", multiplier);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), val);
|
||||
g_free (val);
|
||||
|
||||
constant = gtk_constraint_get_constant (editor->constraint);
|
||||
val = g_strdup_printf ("%g", constant);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->constant), val);
|
||||
g_free (val);
|
||||
|
||||
strength = gtk_constraint_get_strength (editor->constraint);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (GTK_CONSTRAINT_RELATION_EQ));
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1.0");
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->constant), "0.0");
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||
}
|
||||
|
||||
editor->constructed = TRUE;
|
||||
update_preview (editor);
|
||||
update_button (editor);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
self->model = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_CONSTRAINT:
|
||||
self->constraint = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
g_value_set_object (value, self->model);
|
||||
break;
|
||||
|
||||
case PROP_CONSTRAINT:
|
||||
g_value_set_object (value, self->constraint);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_dispose (GObject *object)
|
||||
{
|
||||
ConstraintEditor *self = (ConstraintEditor *)object;
|
||||
|
||||
g_clear_object (&self->model);
|
||||
g_clear_object (&self->constraint);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_class_init (ConstraintEditorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->constructed = constraint_editor_constructed;
|
||||
object_class->dispose = constraint_editor_dispose;
|
||||
object_class->set_property = constraint_editor_set_property;
|
||||
object_class->get_property = constraint_editor_get_property;
|
||||
|
||||
pspecs[PROP_CONSTRAINT] =
|
||||
g_param_spec_object ("constraint", "constraint", "constraint",
|
||||
GTK_TYPE_CONSTRAINT,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
pspecs[PROP_MODEL] =
|
||||
g_param_spec_object ("model", "model", "model",
|
||||
G_TYPE_LIST_MODEL,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||
|
||||
signals[DONE] =
|
||||
g_signal_new ("done",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/constraint-editor.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, grid);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target_attr);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, relation);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source_attr);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, multiplier);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, constant);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, strength);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_preview);
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_button);
|
||||
gtk_widget_class_bind_template_callback (widget_class, create_constraint);
|
||||
gtk_widget_class_bind_template_callback (widget_class, source_attr_changed);
|
||||
}
|
||||
|
||||
ConstraintEditor *
|
||||
constraint_editor_new (GListModel *model,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_TYPE,
|
||||
"model", model,
|
||||
"constraint", constraint,
|
||||
NULL);
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
constraintview {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
constraintview .child {
|
||||
background: red;
|
||||
}
|
||||
|
||||
constraintview .guide {
|
||||
background: blue;
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/gtk4/constraint-editor">
|
||||
<file preprocess="xml-stripblanks">constraint-editor-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">constraint-editor.ui</file>
|
||||
<file preprocess="xml-stripblanks">guide-editor.ui</file>
|
||||
<file>constraint-editor.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_EDITOR_TYPE (constraint_editor_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, GtkWidget)
|
||||
|
||||
ConstraintEditor * constraint_editor_new (GListModel *model,
|
||||
GtkConstraint *constraint);
|
||||
|
||||
void constraint_editor_serialize_constraint (GString *str,
|
||||
int indent,
|
||||
GtkConstraint *constraint);
|
||||
char *constraint_editor_constraint_to_string (GtkConstraint *constraint);
|
@@ -1,204 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkStringList" id="targets">
|
||||
<items>
|
||||
<item>None</item>
|
||||
<item>Left</item>
|
||||
<item>Right</item>
|
||||
<item>Top</item>
|
||||
<item>Bottom</item>
|
||||
<item>Start</item>
|
||||
<item>End</item>
|
||||
<item>Width</item>
|
||||
<item>Height</item>
|
||||
<item>Center X</item>
|
||||
<item>Center Y</item>
|
||||
<item>Baseline</item>
|
||||
</items>
|
||||
</object>
|
||||
<template class="ConstraintEditor" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<property name="margin-start">20</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Target</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="target">
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="target_attr">
|
||||
<property name="model">targets</property>
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Relation</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="relation">
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>≤</item>
|
||||
<item>=</item>
|
||||
<item>≥</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Source</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="source">
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="source_attr">
|
||||
<property name="model">targets</property>
|
||||
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="source_attr_changed" swapped="yes"/>
|
||||
<signal name="notify::selected" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Multiplier</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="multiplier">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Constant</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="constant">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Strength</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="strength">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Weak</item>
|
||||
<item>Medium</item>
|
||||
<item>Strong</item>
|
||||
<item>Required</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="preview">
|
||||
<property name="xalign">0</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">7</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
<attributes>
|
||||
<attribute name="scale" value="1.44"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="label">Create</property>
|
||||
<signal name="clicked" handler="create_constraint"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "constraint-view-child.h"
|
||||
|
||||
struct _ConstraintViewChild
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_NAME = 1,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec props[LAST_PROP];
|
||||
|
||||
G_DEFINE_TYPE (ConstraintViewChild, constraint_view_child, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
constraint_view_child_init (ConstraintViewChild *child)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_child_finalize (GObject *object)
|
||||
{
|
||||
ConstraintViewChild *child = CONSTRAINT_VIEW_CHILD (object);
|
||||
|
||||
g_free (child->name);
|
||||
|
||||
G_OBJECT_CLASS (constraint_view_child_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_child_set_property (GObject *object,
|
||||
|
||||
static void
|
||||
constraint_view_child_class_init (ConstraintViewChildClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = constraint_view_child_finalize;
|
||||
object_class->get_property = constraint_view_child_get_property;
|
||||
object_class->set_property = constraint_view_child_set_property;
|
||||
|
||||
props[PROP_NAME] =
|
||||
g_param_spec_string ("name", "name", "name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||
}
|
||||
|
||||
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||
|
||||
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||
|
||||
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_constraint_new (void);
|
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||
|
||||
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||
|
||||
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_constraint_new (void);
|
@@ -1,345 +0,0 @@
|
||||
/* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library 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.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "constraint-view.h"
|
||||
|
||||
struct _ConstraintView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GListModel *model;
|
||||
|
||||
GtkWidget *drag_widget;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ConstraintView, constraint_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
constraint_view_dispose (GObject *object)
|
||||
{
|
||||
ConstraintView *view = CONSTRAINT_VIEW (object);
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
g_clear_object (&view->model);
|
||||
|
||||
G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_class_init (ConstraintViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = constraint_view_dispose;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "constraintview");
|
||||
}
|
||||
|
||||
static void
|
||||
update_weak_position (ConstraintView *self,
|
||||
GtkWidget *child,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
GtkConstraint *constraint;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "x-constraint");
|
||||
if (constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
|
||||
}
|
||||
if (x != -100)
|
||||
{
|
||||
constraint = gtk_constraint_new_constant (child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
x,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
|
||||
}
|
||||
|
||||
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
|
||||
if (constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
|
||||
}
|
||||
if (y != -100)
|
||||
{
|
||||
constraint = gtk_constraint_new_constant (child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
y,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkGestureDrag *drag,
|
||||
double start_x,
|
||||
double start_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
|
||||
|
||||
if (GTK_IS_LABEL (widget))
|
||||
{
|
||||
widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
|
||||
if (widget &&
|
||||
gtk_widget_get_parent (widget) == (GtkWidget *)self)
|
||||
{
|
||||
self->drag_widget = widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
if (!self->drag_widget)
|
||||
return;
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
||||
update_weak_position (self, self->drag_widget, x + offset_x, y + offset_y);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
self->drag_widget = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
omit_internal (gpointer item, gpointer user_data)
|
||||
{
|
||||
if (g_object_get_data (G_OBJECT (item), "internal"))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_init (ConstraintView *self)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
GtkEventController *controller;
|
||||
GListStore *list;
|
||||
GListModel *all_children;
|
||||
GListModel *all_constraints;
|
||||
GListModel *guides;
|
||||
GListModel *children;
|
||||
GListModel *constraints;
|
||||
GtkFilter *filter;
|
||||
|
||||
manager = gtk_constraint_layout_new ();
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
|
||||
|
||||
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
|
||||
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
|
||||
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, filter);
|
||||
|
||||
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
|
||||
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
|
||||
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
|
||||
|
||||
list = g_list_store_new (G_TYPE_LIST_MODEL);
|
||||
g_list_store_append (list, children);
|
||||
g_list_store_append (list, guides);
|
||||
g_list_store_append (list, constraints);
|
||||
g_object_unref (children);
|
||||
g_object_unref (guides);
|
||||
g_object_unref (constraints);
|
||||
|
||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
|
||||
|
||||
controller = (GtkEventController *)gtk_gesture_drag_new ();
|
||||
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
|
||||
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
|
||||
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
ConstraintView *
|
||||
constraint_view_new (void)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_VIEW_TYPE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_child (ConstraintView *view,
|
||||
const char *name)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (name);
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_add_css_class (frame, "child");
|
||||
gtk_widget_set_name (frame, name);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), label);
|
||||
gtk_widget_set_parent (frame, GTK_WIDGET (view));
|
||||
|
||||
update_weak_position (view, frame, 100, 100);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_child (ConstraintView *view,
|
||||
GtkWidget *child)
|
||||
{
|
||||
update_weak_position (view, child, -100, -100);
|
||||
gtk_widget_unparent (child);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintLayout *layout;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *label;
|
||||
const char *name;
|
||||
GtkConstraint *constraint;
|
||||
struct {
|
||||
const char *name;
|
||||
GtkConstraintAttribute attr;
|
||||
} names[] = {
|
||||
{ "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT },
|
||||
{ "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP },
|
||||
{ "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH },
|
||||
{ "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT },
|
||||
};
|
||||
int i;
|
||||
|
||||
name = gtk_constraint_guide_get_name (guide);
|
||||
label = gtk_label_new (name);
|
||||
g_object_bind_property (guide, "name",
|
||||
label, "label",
|
||||
G_BINDING_DEFAULT);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_add_css_class (frame, "guide");
|
||||
g_object_set_data (G_OBJECT (frame), "internal", (char *)"yes");
|
||||
gtk_frame_set_child (GTK_FRAME (frame), label);
|
||||
gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (guide), "frame", frame);
|
||||
|
||||
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||
gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
constraint = gtk_constraint_new (frame,
|
||||
names[i].attr,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
guide,
|
||||
names[i].attr,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
|
||||
gtk_constraint_layout_add_constraint (layout, constraint);
|
||||
g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
|
||||
}
|
||||
|
||||
update_weak_position (view, frame, 150, 150);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintLayout *layout;
|
||||
GtkWidget *frame;
|
||||
GtkConstraint *constraint;
|
||||
const char *names[] = {
|
||||
"left-constraint",
|
||||
"top-constraint",
|
||||
"width-constraint",
|
||||
"height-constraint"
|
||||
};
|
||||
int i;
|
||||
|
||||
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]);
|
||||
gtk_constraint_layout_remove_constraint (layout, constraint);
|
||||
}
|
||||
|
||||
frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
|
||||
update_weak_position (view, frame, -100, -100);
|
||||
gtk_widget_unparent (frame);
|
||||
|
||||
gtk_constraint_layout_remove_guide (layout, guide);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
g_object_ref (constraint));
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
}
|
||||
|
||||
GListModel *
|
||||
constraint_view_get_model (ConstraintView *view)
|
||||
{
|
||||
return view->model;
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_MODULE_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
|
||||
|
||||
ConstraintView * constraint_view_new (void);
|
||||
|
||||
void constraint_view_add_child (ConstraintView *view,
|
||||
const char *name);
|
||||
void constraint_view_remove_child (ConstraintView *view,
|
||||
GtkWidget *child);
|
||||
void constraint_view_add_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_remove_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_guide_changed (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_add_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint);
|
||||
void constraint_view_remove_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint);
|
||||
GListModel * constraint_view_get_model (ConstraintView *view);
|
@@ -1,355 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "guide-editor.h"
|
||||
|
||||
struct _GuideEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *grid;
|
||||
GtkWidget *name;
|
||||
GtkWidget *min_width;
|
||||
GtkWidget *min_height;
|
||||
GtkWidget *nat_width;
|
||||
GtkWidget *nat_height;
|
||||
GtkWidget *max_width;
|
||||
GtkWidget *max_height;
|
||||
GtkWidget *strength;
|
||||
GtkWidget *button;
|
||||
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
gboolean constructed;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_GUIDE = 1,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *pspecs[LAST_PROP];
|
||||
|
||||
enum {
|
||||
DONE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (unsigned int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
|
||||
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
|
||||
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
|
||||
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_strength_id (GtkConstraintStrength strength)
|
||||
{
|
||||
switch (strength)
|
||||
{
|
||||
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
|
||||
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
|
||||
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
|
||||
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_strength_nick (GtkConstraintStrength strength)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value (class, strength);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
void
|
||||
guide_editor_serialize_guide (GString *str,
|
||||
int indent,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
int min_width, min_height;
|
||||
int nat_width, nat_height;
|
||||
int max_width, max_height;
|
||||
const char *name;
|
||||
const char *strength;
|
||||
|
||||
gtk_constraint_guide_get_min_size (guide, &min_width, &min_height);
|
||||
gtk_constraint_guide_get_nat_size (guide, &nat_width, &nat_height);
|
||||
gtk_constraint_guide_get_max_size (guide, &max_width, &max_height);
|
||||
name = gtk_constraint_guide_get_name (guide);
|
||||
strength = get_strength_nick (gtk_constraint_guide_get_strength (guide));
|
||||
|
||||
g_string_append_printf (str, "%*s<guide min-width=\"%d\" min-height=\"%d\"\n", indent, "", min_width, min_height);
|
||||
g_string_append_printf (str, "%*s nat-width=\"%d\" nat-height=\"%d\"\n", indent, "", nat_width, nat_height);
|
||||
g_string_append_printf (str, "%*s max-width=\"%d\" max-height=\"%d\"\n", indent, "", max_width, max_height);
|
||||
g_string_append_printf (str, "%*s name=\"%s\" strength=\"%s\" />\n", indent, "", name, strength);
|
||||
}
|
||||
|
||||
static void
|
||||
create_guide (GtkButton *button,
|
||||
GuideEditor *editor)
|
||||
{
|
||||
int strength;
|
||||
const char *name;
|
||||
int w, h;
|
||||
GtkConstraintGuide *guide;
|
||||
unsigned int id;
|
||||
|
||||
if (editor->guide)
|
||||
guide = g_object_ref (editor->guide);
|
||||
else
|
||||
guide = gtk_constraint_guide_new ();
|
||||
|
||||
name = gtk_editable_get_text (GTK_EDITABLE (editor->name));
|
||||
gtk_constraint_guide_set_name (guide, name);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_height));
|
||||
gtk_constraint_guide_set_min_size (guide, w, h);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_height));
|
||||
gtk_constraint_guide_set_nat_size (guide, w, h);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
|
||||
gtk_constraint_guide_set_max_size (guide, w, h);
|
||||
|
||||
id = gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength));
|
||||
strength = get_strength (id);
|
||||
gtk_constraint_guide_set_strength (guide, strength);
|
||||
|
||||
g_signal_emit (editor, signals[DONE], 0, guide);
|
||||
g_object_unref (guide);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_init (GuideEditor *editor)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||
}
|
||||
|
||||
static int guide_counter;
|
||||
|
||||
static int
|
||||
min_input (GtkSpinButton *spin_button,
|
||||
double *new_val)
|
||||
{
|
||||
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||
{
|
||||
*new_val = 0.0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
max_input (GtkSpinButton *spin_button,
|
||||
double *new_val)
|
||||
{
|
||||
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||
{
|
||||
*new_val = G_MAXINT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_constructed (GObject *object)
|
||||
{
|
||||
GuideEditor *editor = GUIDE_EDITOR (object);
|
||||
|
||||
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
|
||||
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
|
||||
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
|
||||
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
|
||||
|
||||
if (editor->guide)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
const char *nick;
|
||||
int w, h;
|
||||
|
||||
nick = gtk_constraint_guide_get_name (editor->guide);
|
||||
if (nick)
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
|
||||
|
||||
gtk_constraint_guide_get_min_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), h);
|
||||
|
||||
gtk_constraint_guide_get_nat_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), h);
|
||||
|
||||
gtk_constraint_guide_get_max_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
|
||||
|
||||
strength = gtk_constraint_guide_get_strength (editor->guide);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *name;
|
||||
|
||||
guide_counter++;
|
||||
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->name), name);
|
||||
g_free (name);
|
||||
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
|
||||
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_MEDIUM));
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||
}
|
||||
|
||||
editor->constructed = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GuideEditor *self = GUIDE_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GUIDE:
|
||||
self->guide = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GuideEditor *self = GUIDE_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GUIDE:
|
||||
g_value_set_object (value, self->guide);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_dispose (GObject *object)
|
||||
{
|
||||
GuideEditor *self = (GuideEditor *)object;
|
||||
|
||||
g_clear_object (&self->guide);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), GUIDE_EDITOR_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_class_init (GuideEditorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->constructed = guide_editor_constructed;
|
||||
object_class->dispose = guide_editor_dispose;
|
||||
object_class->set_property = guide_editor_set_property;
|
||||
object_class->get_property = guide_editor_get_property;
|
||||
|
||||
pspecs[PROP_GUIDE] =
|
||||
g_param_spec_object ("guide", "guide", "guide",
|
||||
GTK_TYPE_CONSTRAINT_GUIDE,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||
|
||||
signals[DONE] =
|
||||
g_signal_new ("done",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT_GUIDE);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/guide-editor.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, grid);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, name);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, strength);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, create_guide);
|
||||
}
|
||||
|
||||
GuideEditor *
|
||||
guide_editor_new (GtkConstraintGuide *guide)
|
||||
{
|
||||
return g_object_new (GUIDE_EDITOR_TYPE,
|
||||
"guide", guide,
|
||||
NULL);
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GUIDE_EDITOR_TYPE (guide_editor_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
|
||||
|
||||
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
|
||||
|
||||
void guide_editor_serialize_guide (GString *str,
|
||||
int indent,
|
||||
GtkConstraintGuide *guide);
|
@@ -1,201 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="min_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="min_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="nat_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="nat_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="max_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="max_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<template class="GuideEditor" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<property name="margin-start">20</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Name</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="name">
|
||||
<property name="max-width-chars">20</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Min Size</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="min_width">
|
||||
<property name="adjustment">min_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="min_height">
|
||||
<property name="adjustment">min_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Nat Size</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="nat_width">
|
||||
<property name="adjustment">nat_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="nat_height">
|
||||
<property name="adjustment">nat_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Max Size</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="max_width">
|
||||
<property name="adjustment">max_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="max_height">
|
||||
<property name="adjustment">max_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Strength</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="strength">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Weak</item>
|
||||
<item>Medium</item>
|
||||
<item>Strong</item>
|
||||
<item>Required</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="label">Create</property>
|
||||
<signal name="clicked" handler="create_guide"/>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <constraint-editor-application.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return g_application_run (G_APPLICATION (constraint_editor_application_new ()), argc, argv);
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
constraint_editor_sources = [
|
||||
'main.c',
|
||||
'constraint-editor-application.c',
|
||||
'constraint-editor-window.c',
|
||||
'constraint-view.c',
|
||||
'constraint-editor.c',
|
||||
'guide-editor.c',
|
||||
]
|
||||
|
||||
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||
'constraint-editor.gresource.xml',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-constraint-editor',
|
||||
sources: [ constraint_editor_sources, constraint_editor_resources, ],
|
||||
c_args: common_cflags,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false,
|
||||
)
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 5.2 KiB |
@@ -1,136 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="org.gtk.IconBrowser4-symbolic.svg"
|
||||
height="16.03125"
|
||||
id="svg7384"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
version="1.1"
|
||||
width="16">
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
inkscape:bbox-paths="true"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
inkscape:current-layer="layer9"
|
||||
inkscape:cx="-2.5662459"
|
||||
inkscape:cy="11.558672"
|
||||
gridtolerance="10"
|
||||
inkscape:guide-bbox="true"
|
||||
guidetolerance="10"
|
||||
id="namedview88"
|
||||
inkscape:object-nodes="false"
|
||||
inkscape:object-paths="false"
|
||||
objecttolerance="10"
|
||||
pagecolor="#555753"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
showborder="true"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-bbox-midpoints="false"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-grids="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:snap-to-guides="true"
|
||||
inkscape:window-height="1375"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:zoom="1">
|
||||
<inkscape:grid
|
||||
empspacing="2"
|
||||
enabled="true"
|
||||
id="grid4866"
|
||||
originx="-203"
|
||||
originy="-251.96875"
|
||||
snapvisiblegridlinesonly="true"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
type="xygrid"
|
||||
visible="true" />
|
||||
</sodipodi:namedview>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
id="linearGradient7212"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
id="stop7214"
|
||||
offset="0"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer9"
|
||||
inkscape:label="apps"
|
||||
style="display:inline"
|
||||
transform="translate(-444.0002,35)">
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
d="m 457.9846,-27.96875 v -3 h 1 l -3,-3 -3,3 h 1 v 3 z"
|
||||
id="path2809"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
d="m 451.9846,-23.96875 v 2 h 1 l 2,2 v -6 l -2,2 z"
|
||||
id="path2811"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
d="m 455.9846,-24.96875 v 4 c 0,0 1,-1 1,-2 0,-1.31515 -1,-2 -1,-2 z"
|
||||
id="path2813"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
d="m 457.9846,-25.96875 v 6 c 0,0 1,-1.94591 1,-3 0,-1.05409 -1,-3 -1,-3 z"
|
||||
id="path2815"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;enable-background:new"
|
||||
d="m 450.53751,-25.96846 c 0.24647,0 0.44708,0.19694 0.44708,0.44708 v 0.0289 c -0.008,3.05189 -2.48438,5.5237 -5.53812,5.5237 h -0.0148 c -0.25145,0 -0.44711,-0.20581 -0.44711,-0.4615 v -0.46152 -0.92302 c 0,-0.25567 0.20581,-0.4615 0.4615,-0.4615 h 0.92302 c 0.25569,0 0.46152,0.20581 0.46152,0.4615 v 0.21634 c 1.18002,-0.41715 2.10674,-1.34386 2.52389,-2.52388 h -0.21635 c -0.25566,0 -0.4615,-0.20581 -0.4615,-0.46152 v -0.92302 c 0,-0.25567 0.20581,-0.4615 0.4615,-0.4615 h 0.46152 0.4615 0.44709 0.0148 0.0148 z"
|
||||
id="rect5922-7-3" />
|
||||
<g
|
||||
id="g904-6"
|
||||
transform="matrix(0.26785369,0,0,0.26785369,436.44908,-87.00581)"
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke-width:3.73338151;enable-background:new">
|
||||
<path
|
||||
sodipodi:nodetypes="csscccssssccccccsccsssssccccccsssss"
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.46676302;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 37,198.00759 c -2.76142,0 -5,2.23858 -5,5 0,2.76142 2.23858,5 5,5 0.89216,0 1.71236,-0.27804 2.4375,-0.6875 l 3.9375,3.6875 -3.9375,3.6875 c -0.72514,-0.40946 -1.54534,-0.6875 -2.4375,-0.6875 -2.76142,0 -5,2.23858 -5,5 0,2.76142 2.23858,5 5,5 2.76142,0 5,-2.23858 5,-5 0,-0.45832 -0.072,-0.89082 -0.1874,-1.3125 l 4.25,-4.125 8.9374,8.4375 h 3 v -2 l -16.1875,-15.6875 c 0.1156,-0.42168 0.1874,-0.85418 0.1874,-1.3125 0,-2.76142 -2.23858,-5 -5,-5 z m 0,3 c 1.10456,0 2,0.89544 2,2 0,1.10456 -0.89544,2 -2,2 -1.10456,0 -2,-0.89544 -2,-2 0,-1.10456 0.89544,-2 2,-2 z m 18,-1 -7.875,7.4375 2.625,2.5625 8.25,-8 v -2 z m -18,17 c 1.10456,0 2,0.89544 2,2 0,1.10456 -0.89544,2 -2,2 -1.10456,0 -2,-0.89544 -2,-2 0,-1.10456 0.89544,-2 2,-2 z"
|
||||
id="path1079-7" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 7.1 KiB |
@@ -3,9 +3,7 @@
|
||||
appdata_config = configuration_data()
|
||||
appdata_config.set('BUILD_VERSION', meson.project_version())
|
||||
|
||||
subdir('constraint-editor')
|
||||
subdir('gtk-demo')
|
||||
subdir('icon-browser')
|
||||
subdir('node-editor')
|
||||
subdir('widget-factory')
|
||||
subdir('print-editor')
|
||||
|
@@ -1,32 +0,0 @@
|
||||
.. _gtk4-icon-browser(1):
|
||||
|
||||
=================
|
||||
gtk4-icon-browser
|
||||
=================
|
||||
|
||||
-----------------
|
||||
List themed icons
|
||||
-----------------
|
||||
|
||||
:Version: GTK
|
||||
:Manual section: 1
|
||||
:Manual group: GTK commands
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
| **gtk4-icon-browser** [OPTIONS...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
``gtk4-icon-browser`` is a utility to explore the icons in the current icon
|
||||
theme. It shows icons in various sizes, their symbolic variants where available,
|
||||
as well as a description of the icon and its context.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
``-h, --help``
|
||||
|
||||
Show the application help.
|
@@ -98,7 +98,6 @@ if get_option('build-demos')
|
||||
[ 'gtk4-demo', '1', ],
|
||||
[ 'gtk4-demo-application', '1', ],
|
||||
[ 'gtk4-widget-factory', '1', ],
|
||||
[ 'gtk4-icon-browser', '1', ],
|
||||
[ 'gtk4-node-editor', '1', ],
|
||||
]
|
||||
endif
|
||||
|
@@ -474,6 +474,8 @@ disable certain optimizations of the "ngl" and "vulkan" renderer.
|
||||
`occlusion`
|
||||
: Disable occlusion culling via opacity tracking
|
||||
|
||||
`repeat`
|
||||
: Repeat drawing operations instead of using offscreen and GL_REPEAT
|
||||
|
||||
The special value `all` can be used to turn on all values. The special
|
||||
value `help` can be used to obtain a list of all supported values.
|
||||
|
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkclipboard-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
|
||||
#include "gdkdebugprivate.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
@@ -62,7 +63,7 @@ gdk_win32_clipboard_request_contentformats (GdkWin32Clipboard *cb)
|
||||
UINT w32_formats_allocated;
|
||||
gsize i;
|
||||
GArray *formatpairs;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (cb));
|
||||
DWORD error_code;
|
||||
|
||||
SetLastError (0);
|
||||
@@ -94,7 +95,7 @@ gdk_win32_clipboard_request_contentformats (GdkWin32Clipboard *cb)
|
||||
MIN (w32_formats_len, w32_formats_allocated));
|
||||
|
||||
for (i = 0; i < MIN (w32_formats_len, w32_formats_allocated); i++)
|
||||
_gdk_win32_add_w32format_to_pairs (w32_formats[i], formatpairs, NULL);
|
||||
gdk_win32_clipdrop_add_win32_format_to_pairs (clipdrop, w32_formats[i], formatpairs, NULL);
|
||||
|
||||
g_free (w32_formats);
|
||||
|
||||
@@ -164,7 +165,7 @@ gdk_win32_clipboard_claim (GdkClipboard *clipboard,
|
||||
GdkContentProvider *content)
|
||||
{
|
||||
if (local)
|
||||
_gdk_win32_advertise_clipboard_contentformats (NULL, content ? formats : NULL);
|
||||
_gdk_win32_advertise_clipboard_contentformats (clipboard, NULL, content ? formats : NULL);
|
||||
|
||||
return GDK_CLIPBOARD_CLASS (gdk_win32_clipboard_parent_class)->claim (clipboard, formats, local, content);
|
||||
}
|
||||
@@ -232,7 +233,7 @@ gdk_win32_clipboard_read_async (GdkClipboard *clipboard,
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_win32_clipboard_read_async);
|
||||
|
||||
_gdk_win32_retrieve_clipboard_contentformats (task, contentformats);
|
||||
_gdk_win32_retrieve_clipboard_contentformats (clipboard, task, contentformats);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -296,3 +297,8 @@ gdk_win32_clipboard_new (GdkDisplay *display)
|
||||
return GDK_CLIPBOARD (cb);
|
||||
}
|
||||
|
||||
GdkWin32Clipdrop *
|
||||
gdk_win32_clipboard_get_clipdrop (GdkClipboard *cb)
|
||||
{
|
||||
return gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)));
|
||||
}
|
@@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdk/gdkclipboard.h"
|
||||
#include "gdkprivate-win32.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -33,5 +34,7 @@ GdkClipboard * gdk_win32_clipboard_new (GdkDisplay *dis
|
||||
|
||||
void gdk_win32_clipboard_claim_remote (GdkWin32Clipboard *cb);
|
||||
|
||||
GdkWin32Clipdrop * gdk_win32_clipboard_get_clipdrop (GdkClipboard *cb);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -279,6 +279,7 @@ Otherwise it's similar to how the clipboard works. Only the DnD server
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkclipboard-win32.h"
|
||||
#include "gdkclipdrop-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkhdataoutputstream-win32.h"
|
||||
#include "gdkwin32dnd.h"
|
||||
#include "gdkwin32dnd-private.h"
|
||||
@@ -300,15 +301,6 @@ Otherwise it's similar to how the clipboard works. Only the DnD server
|
||||
*/
|
||||
#define CLIPBOARD_RENDER_TIMEOUT (G_USEC_PER_SEC * 29)
|
||||
|
||||
gboolean _gdk_win32_transmute_windows_data (UINT from_w32format,
|
||||
const char *to_contentformat,
|
||||
HANDLE hdata,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length);
|
||||
|
||||
/* Just to avoid calling RegisterWindowMessage() every time */
|
||||
static UINT thread_wakeup_message;
|
||||
|
||||
typedef enum _GdkWin32ClipboardThreadQueueItemType GdkWin32ClipboardThreadQueueItemType;
|
||||
|
||||
enum _GdkWin32ClipboardThreadQueueItemType
|
||||
@@ -437,11 +429,6 @@ struct _GdkWin32ClipboardThread
|
||||
gboolean ignore_destroy_clipboard;
|
||||
};
|
||||
|
||||
/* The code is much more secure if we don't rely on the OS to keep
|
||||
* this around for us.
|
||||
*/
|
||||
static GdkWin32ClipboardThread *clipboard_thread_data = NULL;
|
||||
|
||||
typedef struct _GdkWin32ClipboardThreadResponse GdkWin32ClipboardThreadResponse;
|
||||
|
||||
struct _GdkWin32ClipboardThreadResponse
|
||||
@@ -485,7 +472,7 @@ _gdk_win32_format_uses_hdata (UINT w32format)
|
||||
static gboolean
|
||||
clipboard_hwnd_created (gpointer user_data)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_display_get_default ());
|
||||
|
||||
clipdrop->clipboard_hwnd = (HWND) user_data;
|
||||
|
||||
@@ -518,7 +505,7 @@ clipboard_render_hdata_ready (GObject *clipboard,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkWin32ClipboardRenderAndStream render_and_stream = *(GdkWin32ClipboardRenderAndStream *) user_data;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (clipboard));
|
||||
|
||||
g_free (user_data);
|
||||
|
||||
@@ -553,11 +540,11 @@ static gboolean
|
||||
clipboard_render (gpointer user_data)
|
||||
{
|
||||
GdkWin32ClipboardThreadRender *render = (GdkWin32ClipboardThreadRender *) user_data;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (display);
|
||||
GdkClipboard *clipboard = gdk_display_get_clipboard (display);
|
||||
GError *error = NULL;
|
||||
GOutputStream *stream = gdk_win32_hdata_output_stream_new (&render->pair, &error);
|
||||
GOutputStream *stream = gdk_win32_hdata_output_stream_new (clipdrop, &render->pair, &error);
|
||||
GdkWin32ClipboardRenderAndStream *render_and_stream;
|
||||
|
||||
if (stream == NULL)
|
||||
@@ -684,28 +671,32 @@ send_input_stream (GdkWin32ClipboardThreadQueueItemType request_type,
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_thread_response, response, NULL);
|
||||
}
|
||||
|
||||
#define CLIPDROP_CB_THREAD_MEMBER(c,m) ((GdkWin32ClipboardThread *)(c->clipboard_thread_items))->m
|
||||
|
||||
static DWORD
|
||||
try_open_clipboard (HWND hwnd)
|
||||
try_open_clipboard (GdkWin32Clipdrop *clipdrop,
|
||||
HWND hwnd)
|
||||
{
|
||||
if (clipboard_thread_data->clipboard_opened_for == hwnd)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == hwnd)
|
||||
return NO_ERROR;
|
||||
|
||||
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
API_CALL (CloseClipboard, ());
|
||||
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!OpenClipboard (hwnd))
|
||||
return GetLastError ();
|
||||
|
||||
clipboard_thread_data->clipboard_opened_for = hwnd;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = hwnd;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ClipboardThreadAdvertise *adv)
|
||||
{
|
||||
DWORD error_code;
|
||||
int i;
|
||||
@@ -720,7 +711,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->owner_change_time > adv->parent.start_time)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > adv->parent.start_time)
|
||||
{
|
||||
GDK_NOTE (CLIPBOARD, g_printerr ("An advertise task timed out due to ownership change\n"));
|
||||
send_response (adv->parent.item_type,
|
||||
@@ -730,7 +721,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
error_code = try_open_clipboard (adv->unset ? NULL : clipboard_thread_data->clipboard_hwnd);
|
||||
error_code = try_open_clipboard (clipdrop, adv->unset ? NULL : CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -744,10 +735,10 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
clipboard_thread_data->ignore_destroy_clipboard = TRUE;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = TRUE;
|
||||
if (!EmptyClipboard ())
|
||||
{
|
||||
clipboard_thread_data->ignore_destroy_clipboard = FALSE;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = FALSE;
|
||||
error_code = GetLastError ();
|
||||
send_response (adv->parent.item_type,
|
||||
adv->parent.opaque_task,
|
||||
@@ -756,7 +747,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
clipboard_thread_data->ignore_destroy_clipboard = FALSE;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = FALSE;
|
||||
|
||||
if (adv->unset)
|
||||
return FALSE;
|
||||
@@ -768,10 +759,10 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
SetClipboardData (pair->w32format, NULL);
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->cached_advertisement)
|
||||
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement))
|
||||
g_array_free (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), TRUE);
|
||||
|
||||
clipboard_thread_data->cached_advertisement = adv->pairs;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) = adv->pairs;
|
||||
|
||||
/* To enure that we don't free it later on */
|
||||
adv->pairs = NULL;
|
||||
@@ -784,7 +775,8 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_store (GdkWin32ClipboardThreadStore *store)
|
||||
process_store (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ClipboardThreadStore *store)
|
||||
{
|
||||
DWORD error_code;
|
||||
int i;
|
||||
@@ -799,7 +791,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->owner_change_time > store->parent.start_time)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > store->parent.start_time)
|
||||
{
|
||||
GDK_NOTE (CLIPBOARD, g_printerr ("A store task timed out due to ownership change\n"));
|
||||
send_response (store->parent.item_type,
|
||||
@@ -809,7 +801,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
|
||||
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -831,7 +823,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
|
||||
* that we already own, otherwise we're just killing stuff that some other
|
||||
* process put in there, which is not nice.
|
||||
*/
|
||||
if (GetClipboardOwner () != clipboard_thread_data->clipboard_hwnd)
|
||||
if (GetClipboardOwner () != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
|
||||
{
|
||||
send_response (store->parent.item_type,
|
||||
store->parent.opaque_task,
|
||||
@@ -910,7 +902,8 @@ grab_data_from_hdata (GdkWin32ClipboardThreadRetrieve *retr,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
|
||||
process_retrieve (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ClipboardThreadRetrieve *retr)
|
||||
{
|
||||
DWORD error_code;
|
||||
int i;
|
||||
@@ -931,7 +924,7 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->owner_change_time > retr->parent.start_time)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > retr->parent.start_time)
|
||||
{
|
||||
GDK_NOTE (CLIPBOARD, g_printerr ("A retrieve task timed out due to ownership change\n"));
|
||||
send_response (retr->parent.item_type,
|
||||
@@ -951,10 +944,10 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == INVALID_HANDLE_VALUE)
|
||||
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
else
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_opened_for);
|
||||
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for));
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -1021,7 +1014,7 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_win32_transmute_windows_data (pair->w32format, pair->contentformat, hdata, &data, &data_len);
|
||||
gdk_win32_clipdrop_transmute_windows_data (clipdrop, pair->w32format, pair->contentformat, hdata, &data, &data_len);
|
||||
|
||||
if (data == NULL)
|
||||
return FALSE;
|
||||
@@ -1040,14 +1033,14 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_clipboard_queue ()
|
||||
process_clipboard_queue (GdkWin32Clipdrop *clipdrop)
|
||||
{
|
||||
GdkWin32ClipboardThreadQueueItem *placeholder;
|
||||
GList *p;
|
||||
gboolean try_again;
|
||||
GList *p_next;
|
||||
|
||||
for (p = clipboard_thread_data->dequeued_items, p_next = NULL; p; p = p_next)
|
||||
for (p = CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), p_next = NULL; p; p = p_next)
|
||||
{
|
||||
placeholder = (GdkWin32ClipboardThreadQueueItem *) p->data;
|
||||
p_next = p->next;
|
||||
@@ -1055,35 +1048,35 @@ process_clipboard_queue ()
|
||||
switch (placeholder->item_type)
|
||||
{
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE:
|
||||
try_again = process_advertise ((GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
try_again = process_advertise (clipdrop, (GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE:
|
||||
try_again = process_retrieve ((GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
try_again = process_retrieve (clipdrop, (GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_STORE:
|
||||
try_again = process_store ((GdkWin32ClipboardThreadStore *) placeholder);
|
||||
try_again = process_store (clipdrop, (GdkWin32ClipboardThreadStore *) placeholder);
|
||||
break;
|
||||
}
|
||||
|
||||
if (try_again)
|
||||
return FALSE;
|
||||
|
||||
clipboard_thread_data->dequeued_items = g_list_delete_link (clipboard_thread_data->dequeued_items, p);
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items) = g_list_delete_link (CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), p);
|
||||
free_queue_item (placeholder);
|
||||
}
|
||||
|
||||
while ((placeholder = g_async_queue_try_pop (clipboard_thread_data->input_queue)) != NULL)
|
||||
while ((placeholder = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, input_queue))) != NULL)
|
||||
{
|
||||
switch (placeholder->item_type)
|
||||
{
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE:
|
||||
try_again = process_advertise ((GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
try_again = process_advertise (clipdrop, (GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE:
|
||||
try_again = process_retrieve ((GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
try_again = process_retrieve (clipdrop, (GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_STORE:
|
||||
try_again = process_store ((GdkWin32ClipboardThreadStore *) placeholder);
|
||||
try_again = process_store (clipdrop, (GdkWin32ClipboardThreadStore *) placeholder);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1093,7 +1086,7 @@ process_clipboard_queue ()
|
||||
continue;
|
||||
}
|
||||
|
||||
clipboard_thread_data->dequeued_items = g_list_append (clipboard_thread_data->dequeued_items, placeholder);
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items) = g_list_append (CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), placeholder);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1124,23 +1117,37 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
{
|
||||
if (message == thread_wakeup_message ||
|
||||
GdkWin32Clipdrop *clipdrop = NULL;
|
||||
|
||||
if (message == WM_NCCREATE)
|
||||
{
|
||||
CREATESTRUCT *cs = (CREATESTRUCT *)lparam;
|
||||
clipdrop = (GdkWin32Clipdrop *) cs->lpCreateParams;
|
||||
SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) clipdrop);
|
||||
return TRUE;
|
||||
}
|
||||
else if (message == WM_CREATE)
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
else
|
||||
clipdrop = (GdkWin32Clipdrop *) GetWindowLongPtr (hwnd, GWLP_USERDATA);
|
||||
|
||||
if (message == clipdrop->thread_wakeup_message ||
|
||||
message == WM_TIMER)
|
||||
{
|
||||
gboolean queue_is_empty = FALSE;
|
||||
|
||||
if (clipboard_thread_data == NULL)
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
queue_is_empty = process_clipboard_queue ();
|
||||
queue_is_empty = process_clipboard_queue (clipdrop);
|
||||
|
||||
if (queue_is_empty && clipboard_thread_data->wakeup_timer)
|
||||
if (queue_is_empty && CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer))
|
||||
{
|
||||
API_CALL (KillTimer, (clipboard_thread_data->clipboard_hwnd, clipboard_thread_data->wakeup_timer));
|
||||
clipboard_thread_data->wakeup_timer = 0;
|
||||
API_CALL (KillTimer, (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer)));
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) = 0;
|
||||
}
|
||||
|
||||
/* Close the clipboard after each queue run, if it's open.
|
||||
@@ -1149,21 +1156,21 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
* queue_is_empty == FALSE implies that the clipboard
|
||||
* is closed already, but it's better to be sure.
|
||||
*/
|
||||
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
API_CALL (CloseClipboard, ());
|
||||
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (queue_is_empty ||
|
||||
clipboard_thread_data->wakeup_timer != 0)
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) != 0)
|
||||
return 0;
|
||||
|
||||
if (SetTimer (clipboard_thread_data->clipboard_hwnd, 1, 1000, NULL))
|
||||
clipboard_thread_data->wakeup_timer = 1;
|
||||
if (SetTimer (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), 1, 1000, NULL))
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) = 1;
|
||||
else
|
||||
g_critical ("Failed to set a timer for the clipboard HWND 0x%p: %lu",
|
||||
clipboard_thread_data->clipboard_hwnd,
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd),
|
||||
GetLastError ());
|
||||
}
|
||||
|
||||
@@ -1171,7 +1178,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
{
|
||||
case WM_DESTROY: /* unregister the clipboard listener */
|
||||
{
|
||||
if (clipboard_thread_data == NULL)
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
@@ -1192,7 +1199,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
/*
|
||||
GdkEvent *event;
|
||||
*/
|
||||
if (clipboard_thread_data == NULL)
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
@@ -1210,7 +1217,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
/* FIXME: grab and print clipboard formats without opening the clipboard
|
||||
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE ||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE ||
|
||||
OpenClipboard (hwnd))
|
||||
{
|
||||
UINT nFormat = 0;
|
||||
@@ -1218,7 +1225,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
while ((nFormat = EnumClipboardFormats (nFormat)) != 0)
|
||||
g_print ("%s ", _gdk_win32_cf_to_string (nFormat));
|
||||
|
||||
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == INVALID_HANDLE_VALUE)
|
||||
CloseClipboard ();
|
||||
}
|
||||
else
|
||||
@@ -1230,22 +1237,22 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
|
||||
GDK_NOTE (DND, g_print (" \n"));
|
||||
|
||||
if (clipboard_thread_data->stored_hwnd_owner != hwnd_owner)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, stored_hwnd_owner) != hwnd_owner)
|
||||
{
|
||||
clipboard_thread_data->stored_hwnd_owner = hwnd_owner;
|
||||
clipboard_thread_data->owner_change_time = g_get_monotonic_time ();
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, stored_hwnd_owner) = hwnd_owner;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) = g_get_monotonic_time ();
|
||||
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
|
||||
if (hwnd_owner != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
|
||||
{
|
||||
if (clipboard_thread_data->cached_advertisement)
|
||||
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement))
|
||||
g_array_free (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), TRUE);
|
||||
|
||||
clipboard_thread_data->cached_advertisement = NULL;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) = NULL;
|
||||
}
|
||||
|
||||
API_CALL (PostMessage, (clipboard_thread_data->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), clipdrop->thread_wakeup_message, 0, 0));
|
||||
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
|
||||
if (hwnd_owner != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_owner_changed, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1256,13 +1263,13 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
}
|
||||
case WM_RENDERALLFORMATS:
|
||||
{
|
||||
if (clipboard_thread_data == NULL)
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->cached_advertisement == NULL)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement == NULL))
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
|
||||
if (API_CALL (OpenClipboard, (hwnd)))
|
||||
@@ -1271,10 +1278,10 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
GdkWin32ContentFormatPair *pair;
|
||||
|
||||
for (pair = NULL, i = 0;
|
||||
i < clipboard_thread_data->cached_advertisement->len;
|
||||
i < CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement)->len;
|
||||
i++)
|
||||
{
|
||||
pair = &g_array_index (clipboard_thread_data->cached_advertisement, GdkWin32ContentFormatPair, i);
|
||||
pair = &g_array_index (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), GdkWin32ContentFormatPair, i);
|
||||
|
||||
if (pair->w32format != 0)
|
||||
SendMessage (hwnd, WM_RENDERFORMAT, pair->w32format, 0);
|
||||
@@ -1295,20 +1302,20 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
|
||||
GDK_NOTE (EVENTS, g_print (" %s", _gdk_win32_cf_to_string (wparam)));
|
||||
|
||||
if (clipboard_thread_data == NULL)
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->cached_advertisement == NULL)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) == NULL)
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
|
||||
for (pair = NULL, i = 0;
|
||||
i < clipboard_thread_data->cached_advertisement->len;
|
||||
i < CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement)->len;
|
||||
i++)
|
||||
{
|
||||
pair = &g_array_index (clipboard_thread_data->cached_advertisement, GdkWin32ContentFormatPair, i);
|
||||
pair = &g_array_index (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), GdkWin32ContentFormatPair, i);
|
||||
|
||||
if (pair->w32format == wparam)
|
||||
break;
|
||||
@@ -1323,13 +1330,13 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
}
|
||||
|
||||
/* Clear the queue */
|
||||
while ((render = g_async_queue_try_pop (clipboard_thread_data->render_queue)) != NULL)
|
||||
while ((render = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue))) != NULL)
|
||||
discard_render (render, FALSE);
|
||||
|
||||
render = g_new0 (GdkWin32ClipboardThreadRender, 1);
|
||||
render->pair = *pair;
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_render, render, NULL);
|
||||
returned_render = g_async_queue_timeout_pop (clipboard_thread_data->render_queue, CLIPBOARD_RENDER_TIMEOUT);
|
||||
returned_render = g_async_queue_timeout_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue), CLIPBOARD_RENDER_TIMEOUT);
|
||||
|
||||
/* We should get back the same pointer, ignore everything else. */
|
||||
while (returned_render != NULL && returned_render != render)
|
||||
@@ -1343,7 +1350,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
* If you get many "Clipboard rendering timed out" warnings,
|
||||
* this is probably why.
|
||||
*/
|
||||
returned_render = g_async_queue_try_pop (clipboard_thread_data->render_queue);
|
||||
returned_render = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue));
|
||||
}
|
||||
|
||||
/* Just in case */
|
||||
@@ -1403,7 +1410,7 @@ _clipboard_hwnd_procedure (HWND hwnd,
|
||||
* Creates a hidden HWND and add a clipboard listener
|
||||
*/
|
||||
static gboolean
|
||||
register_clipboard_notification ()
|
||||
register_clipboard_notification (GdkWin32Clipdrop *clipdrop)
|
||||
{
|
||||
WNDCLASS wclass = { 0, };
|
||||
ATOM klass;
|
||||
@@ -1417,23 +1424,24 @@ register_clipboard_notification ()
|
||||
if (!klass)
|
||||
return FALSE;
|
||||
|
||||
clipboard_thread_data->clipboard_hwnd = CreateWindow (MAKEINTRESOURCE (klass),
|
||||
NULL, WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL,
|
||||
this_module (), NULL);
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd) =
|
||||
CreateWindow (MAKEINTRESOURCE (klass),
|
||||
NULL, WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL,
|
||||
this_module (), clipdrop);
|
||||
|
||||
if (clipboard_thread_data->clipboard_hwnd == NULL)
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd) == NULL)
|
||||
goto failed;
|
||||
|
||||
SetLastError (0);
|
||||
|
||||
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_hwnd) == FALSE)
|
||||
if (AddClipboardFormatListener (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd)) == FALSE)
|
||||
{
|
||||
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
|
||||
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) clipboard_thread_data->clipboard_hwnd, NULL);
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), NULL);
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -1447,20 +1455,21 @@ static gpointer
|
||||
_gdk_win32_clipboard_thread_main (gpointer data)
|
||||
{
|
||||
MSG msg;
|
||||
GAsyncQueue *queue = (GAsyncQueue *) data;
|
||||
clipdrop_thread_items *items = (clipdrop_thread_items*) data;
|
||||
GAsyncQueue *queue = items->queue;
|
||||
GAsyncQueue *render_queue = (GAsyncQueue *) g_async_queue_pop (queue);
|
||||
|
||||
g_assert (clipboard_thread_data == NULL);
|
||||
g_assert (items->clipdrop->clipboard_thread_items == NULL);
|
||||
|
||||
clipboard_thread_data = g_new0 (GdkWin32ClipboardThread, 1);
|
||||
clipboard_thread_data->input_queue = queue;
|
||||
clipboard_thread_data->render_queue = render_queue;
|
||||
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
|
||||
items->clipdrop->clipboard_thread_items = g_new0 (GdkWin32ClipboardThread, 1);
|
||||
CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, input_queue) = queue;
|
||||
CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, render_queue) = render_queue;
|
||||
CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (!register_clipboard_notification ())
|
||||
if (!register_clipboard_notification (items->clipdrop))
|
||||
{
|
||||
g_async_queue_unref (queue);
|
||||
g_clear_pointer (&clipboard_thread_data, g_free);
|
||||
g_clear_pointer (&items->clipdrop->clipboard_thread_items, g_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1472,10 +1481,10 @@ _gdk_win32_clipboard_thread_main (gpointer data)
|
||||
}
|
||||
|
||||
/* Just in case, as this should only happen when we shut down */
|
||||
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
|
||||
CloseHandle (clipboard_thread_data->clipboard_hwnd);
|
||||
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_hwnd));
|
||||
CloseHandle (CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_hwnd));
|
||||
g_async_queue_unref (queue);
|
||||
g_clear_pointer (&clipboard_thread_data, g_free);
|
||||
g_clear_pointer (&items->clipdrop->clipboard_thread_items, g_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1483,15 +1492,22 @@ _gdk_win32_clipboard_thread_main (gpointer data)
|
||||
G_DEFINE_TYPE (GdkWin32Clipdrop, gdk_win32_clipdrop, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_win32_clipdrop_class_init (GdkWin32ClipdropClass *klass)
|
||||
gdk_win32_clipdrop_finalize (GObject *object)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = GDK_WIN32_CLIPDROP (object);
|
||||
|
||||
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
CloseHandle (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
g_clear_pointer (&clipdrop->dnd_thread_items, g_free);
|
||||
g_clear_pointer (&clipdrop->clipboard_thread_items, g_free);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_clipdrop_init (void)
|
||||
static void
|
||||
gdk_win32_clipdrop_class_init (GdkWin32ClipdropClass *klass)
|
||||
{
|
||||
_win32_main_thread = g_thread_self ();
|
||||
_win32_clipdrop = GDK_WIN32_CLIPDROP (g_object_new (GDK_TYPE_WIN32_CLIPDROP, NULL));
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_win32_clipdrop_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1505,8 +1521,9 @@ gdk_win32_clipdrop_init (GdkWin32Clipdrop *win32_clipdrop)
|
||||
GArray *comp;
|
||||
GdkWin32ContentFormatPair fmt;
|
||||
HMODULE user32;
|
||||
clipdrop_thread_items cb_items, dnd_items;
|
||||
|
||||
thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
|
||||
win32_clipdrop->thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
|
||||
|
||||
user32 = LoadLibrary (L"user32.dll");
|
||||
win32_clipdrop->GetUpdatedClipboardFormats = (GetUpdatedClipboardFormatsFunc) GetProcAddress (user32, "GetUpdatedClipboardFormats");
|
||||
@@ -1798,14 +1815,17 @@ gdk_win32_clipdrop_init (GdkWin32Clipdrop *win32_clipdrop)
|
||||
* pointers and then passing *that* to the thread.
|
||||
*/
|
||||
g_async_queue_push (win32_clipdrop->clipboard_open_thread_queue, g_async_queue_ref (win32_clipdrop->clipboard_render_queue));
|
||||
cb_items.clipdrop = dnd_items.clipdrop = win32_clipdrop;
|
||||
cb_items.queue = g_async_queue_ref (win32_clipdrop->clipboard_open_thread_queue);
|
||||
win32_clipdrop->clipboard_open_thread = g_thread_new ("GDK Win32 Clipboard Thread",
|
||||
_gdk_win32_clipboard_thread_main,
|
||||
g_async_queue_ref (win32_clipdrop->clipboard_open_thread_queue));
|
||||
&cb_items);
|
||||
|
||||
win32_clipdrop->dnd_queue = g_async_queue_new ();
|
||||
dnd_items.queue = g_async_queue_ref (win32_clipdrop->dnd_queue);
|
||||
win32_clipdrop->dnd_thread = g_thread_new ("GDK Win32 DnD Thread",
|
||||
_gdk_win32_dnd_thread_main,
|
||||
g_async_queue_ref (win32_clipdrop->dnd_queue));
|
||||
&dnd_items);
|
||||
win32_clipdrop->dnd_thread_id = GPOINTER_TO_UINT (g_async_queue_pop (win32_clipdrop->dnd_queue));
|
||||
}
|
||||
|
||||
@@ -1927,11 +1947,11 @@ _gdk_win32_get_clipboard_format_name_as_interned_mimetype (char *w32format_name)
|
||||
}
|
||||
|
||||
static GArray *
|
||||
get_compatibility_w32formats_for_contentformat (const char *contentformat)
|
||||
get_compatibility_w32formats_for_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
const char *contentformat)
|
||||
{
|
||||
GArray *result = NULL;
|
||||
int i;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
result = g_hash_table_lookup (clipdrop->compatibility_w32formats, contentformat);
|
||||
|
||||
@@ -1945,7 +1965,7 @@ get_compatibility_w32formats_for_contentformat (const char *contentformat)
|
||||
|
||||
/* Any format known to gdk-pixbuf can be presented as PNG or BMP */
|
||||
result = g_hash_table_lookup (clipdrop->compatibility_w32formats,
|
||||
_gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_PNG));
|
||||
_gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_PNG));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1953,10 +1973,10 @@ get_compatibility_w32formats_for_contentformat (const char *contentformat)
|
||||
}
|
||||
|
||||
static GArray *
|
||||
_gdk_win32_get_compatibility_contentformats_for_w32format (UINT w32format)
|
||||
_gdk_win32_get_compatibility_contentformats_for_w32format (GdkWin32Clipdrop *clipdrop,
|
||||
UINT w32format)
|
||||
{
|
||||
GArray *result = NULL;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
result = g_hash_table_lookup (clipdrop->compatibility_contentformats, GINT_TO_POINTER (w32format));
|
||||
|
||||
@@ -1983,9 +2003,10 @@ _gdk_win32_get_compatibility_contentformats_for_w32format (UINT w32format)
|
||||
* (builder already takes care of that for itself).
|
||||
*/
|
||||
void
|
||||
_gdk_win32_add_w32format_to_pairs (UINT w32format,
|
||||
GArray *pairs,
|
||||
GdkContentFormatsBuilder *builder)
|
||||
gdk_win32_clipdrop_add_win32_format_to_pairs (GdkWin32Clipdrop *clipdrop,
|
||||
UINT w32format,
|
||||
GArray *pairs,
|
||||
GdkContentFormatsBuilder *builder)
|
||||
{
|
||||
gboolean predef;
|
||||
char *w32format_name = _gdk_win32_get_clipboard_format_name (w32format, &predef);
|
||||
@@ -2017,7 +2038,7 @@ _gdk_win32_add_w32format_to_pairs (UINT w32format,
|
||||
gdk_content_formats_builder_add_mime_type (builder, interned_w32format_name);
|
||||
}
|
||||
|
||||
comp_pairs = _gdk_win32_get_compatibility_contentformats_for_w32format (w32format);
|
||||
comp_pairs = _gdk_win32_get_compatibility_contentformats_for_w32format (clipdrop, w32format);
|
||||
|
||||
if (pairs != NULL && comp_pairs != NULL)
|
||||
for (i = 0; i < comp_pairs->len; i++)
|
||||
@@ -2548,11 +2569,12 @@ transmute_image_bmp_to_cf_dib (const guchar *data,
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_win32_transmute_windows_data (UINT from_w32format,
|
||||
const char *to_contentformat,
|
||||
HANDLE hdata,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length)
|
||||
gdk_win32_clipdrop_transmute_windows_data (GdkWin32Clipdrop *clipdrop,
|
||||
UINT from_w32format,
|
||||
const char *to_contentformat,
|
||||
HANDLE hdata,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length)
|
||||
{
|
||||
const guchar *data;
|
||||
SIZE_T hdata_length;
|
||||
@@ -2572,37 +2594,37 @@ _gdk_win32_transmute_windows_data (UINT from_w32format,
|
||||
|
||||
length = (gsize) hdata_length;
|
||||
|
||||
if ((to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_PNG)) ||
|
||||
(to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_JFIF)) ||
|
||||
(to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_GIF) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_GIF)))
|
||||
if ((to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_PNG)) ||
|
||||
(to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_JFIF)) ||
|
||||
(to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_GIF) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_GIF)))
|
||||
{
|
||||
/* No transmutation needed */
|
||||
*set_data = g_memdup2 (data, length);
|
||||
*set_data_length = length;
|
||||
}
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
from_w32format == CF_UNICODETEXT)
|
||||
{
|
||||
transmute_cf_unicodetext_to_utf8_string (data, length, set_data, set_data_length, NULL);
|
||||
res = TRUE;
|
||||
}
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
from_w32format == CF_TEXT)
|
||||
{
|
||||
transmute_cf_text_to_utf8_string (data, length, set_data, set_data_length, NULL);
|
||||
res = TRUE;
|
||||
}
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
(from_w32format == CF_DIB || from_w32format == CF_DIBV5))
|
||||
{
|
||||
transmute_cf_dib_to_image_bmp (data, length, set_data, set_data_length, NULL);
|
||||
res = TRUE;
|
||||
}
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
|
||||
{
|
||||
transmute_cf_shell_id_list_to_text_uri_list (data, length, set_data, set_data_length, NULL);
|
||||
res = TRUE;
|
||||
@@ -2621,47 +2643,48 @@ out:
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_win32_transmute_contentformat (const char *from_contentformat,
|
||||
UINT to_w32format,
|
||||
const guchar *data,
|
||||
gsize length,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length)
|
||||
gdk_win32_clipdrop_transmute_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
const char *from_contentformat,
|
||||
UINT to_w32format,
|
||||
const guchar *data,
|
||||
gsize length,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length)
|
||||
{
|
||||
if ((from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_PNG)) ||
|
||||
(from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_JFIF)) ||
|
||||
(from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_GIF) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_GIF)))
|
||||
if ((from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_PNG)) ||
|
||||
(from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_JFIF)) ||
|
||||
(from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_GIF) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_GIF)))
|
||||
{
|
||||
/* No conversion needed */
|
||||
*set_data = g_memdup2 (data, length);
|
||||
*set_data_length = length;
|
||||
}
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
to_w32format == CF_UNICODETEXT)
|
||||
{
|
||||
transmute_utf8_string_to_cf_unicodetext (data, length, set_data, set_data_length, NULL);
|
||||
}
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
to_w32format == CF_TEXT)
|
||||
{
|
||||
transmute_utf8_string_to_cf_text (data, length, set_data, set_data_length, NULL);
|
||||
}
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
to_w32format == CF_DIB)
|
||||
{
|
||||
transmute_image_bmp_to_cf_dib (data, length, set_data, set_data_length, NULL);
|
||||
}
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
to_w32format == CF_DIBV5)
|
||||
{
|
||||
transmute_image_bmp_to_cf_dib (data, length, set_data, set_data_length, NULL);
|
||||
}
|
||||
/*
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
|
||||
{
|
||||
transmute_text_uri_list_to_shell_id_list (data, length, set_data, set_data_length, NULL);
|
||||
}
|
||||
@@ -2677,8 +2700,9 @@ _gdk_win32_transmute_contentformat (const char *from_contentformat,
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_win32_add_contentformat_to_pairs (const char *contentformat,
|
||||
GArray *array)
|
||||
_gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
|
||||
const char *contentformat,
|
||||
GArray *array)
|
||||
{
|
||||
int added_count = 0;
|
||||
wchar_t *contentformat_w;
|
||||
@@ -2723,7 +2747,7 @@ _gdk_win32_add_contentformat_to_pairs (const char *contentformat,
|
||||
g_array_append_val (array, fmt);
|
||||
added_count += 1;
|
||||
|
||||
comp_pairs = get_compatibility_w32formats_for_contentformat (contentformat);
|
||||
comp_pairs = get_compatibility_w32formats_for_contentformat (clip_drop, contentformat);
|
||||
for (i = 0; comp_pairs != NULL && i < comp_pairs->len; i++)
|
||||
{
|
||||
int j;
|
||||
@@ -2747,10 +2771,11 @@ _gdk_win32_add_contentformat_to_pairs (const char *contentformat,
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_advertise_clipboard_contentformats (GTask *task,
|
||||
_gdk_win32_advertise_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
GdkContentFormats *contentformats)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
|
||||
GdkWin32ClipboardThreadAdvertise *adv = g_new0 (GdkWin32ClipboardThreadAdvertise, 1);
|
||||
const char * const *mime_types;
|
||||
gsize mime_types_len;
|
||||
@@ -2775,20 +2800,21 @@ _gdk_win32_advertise_clipboard_contentformats (GTask *task,
|
||||
mime_types = gdk_content_formats_get_mime_types (contentformats, &mime_types_len);
|
||||
|
||||
for (i = 0; i < mime_types_len; i++)
|
||||
_gdk_win32_add_contentformat_to_pairs (mime_types[i], adv->pairs);
|
||||
_gdk_win32_add_contentformat_to_pairs (clipdrop, mime_types[i], adv->pairs);
|
||||
}
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, adv);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_retrieve_clipboard_contentformats (GTask *task,
|
||||
_gdk_win32_retrieve_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
GdkContentFormats *contentformats)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
|
||||
GdkWin32ClipboardThreadRetrieve *retr = g_new0 (GdkWin32ClipboardThreadRetrieve, 1);
|
||||
const char * const *mime_types;
|
||||
gsize mime_types_len;
|
||||
@@ -2806,10 +2832,10 @@ _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
|
||||
mime_types = gdk_content_formats_get_mime_types (contentformats, &mime_types_len);
|
||||
|
||||
for (i = 0; i < mime_types_len; i++)
|
||||
_gdk_win32_add_contentformat_to_pairs (mime_types[i], retr->pairs);
|
||||
_gdk_win32_add_contentformat_to_pairs (clipdrop, mime_types[i], retr->pairs);
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, retr);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -2879,7 +2905,7 @@ clipboard_store_hdata_ready (GObject *clipboard,
|
||||
if (!no_other_streams)
|
||||
return;
|
||||
|
||||
clipdrop = _gdk_win32_clipdrop_get ();
|
||||
clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (clipboard));
|
||||
|
||||
store = g_new0 (GdkWin32ClipboardThreadStore, 1);
|
||||
|
||||
@@ -2890,7 +2916,7 @@ clipboard_store_hdata_ready (GObject *clipboard,
|
||||
store->elements = prep->elements;
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, store);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
|
||||
|
||||
g_free (prep);
|
||||
}
|
||||
@@ -2904,7 +2930,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
gsize i;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
|
||||
GdkWin32ClipboardStorePrep *prep;
|
||||
|
||||
g_assert (clipdrop->clipboard_hwnd != NULL);
|
||||
@@ -2917,7 +2943,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
|
||||
n_mime_types);
|
||||
|
||||
for (i = 0; i < n_mime_types; i++)
|
||||
_gdk_win32_add_contentformat_to_pairs (mime_types[i], pairs);
|
||||
_gdk_win32_add_contentformat_to_pairs (clipdrop, mime_types[i], pairs);
|
||||
|
||||
if (pairs->len <= 0)
|
||||
{
|
||||
@@ -2935,7 +2961,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
|
||||
GdkWin32ClipboardStorePrepElement el;
|
||||
GdkWin32ContentFormatPair *pair = &g_array_index (pairs, GdkWin32ContentFormatPair, i);
|
||||
|
||||
el.stream = gdk_win32_hdata_output_stream_new (pair, NULL);
|
||||
el.stream = gdk_win32_hdata_output_stream_new (clipdrop, pair, NULL);
|
||||
|
||||
if (!el.stream)
|
||||
continue;
|
||||
|
@@ -22,11 +22,10 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define _gdk_win32_clipdrop_get() (_win32_clipdrop)
|
||||
#define _gdk_atom_array_index(a, i) (g_array_index (a, const char *, i))
|
||||
#define _gdk_win32_clipdrop_atom(i) (_gdk_atom_array_index (_gdk_win32_clipdrop_get ()->known_atoms, i))
|
||||
#define _gdk_win32_clipdrop_atom(c, i) (_gdk_atom_array_index (c->known_atoms, i))
|
||||
#define _gdk_cf_array_index(a, i) (g_array_index (a, UINT, i))
|
||||
#define _gdk_win32_clipdrop_cf(i) (_gdk_cf_array_index (_gdk_win32_clipdrop_get ()->known_clipboard_formats, i))
|
||||
#define _gdk_win32_clipdrop_cf(c,i) (_gdk_cf_array_index (c->known_clipboard_formats, i))
|
||||
|
||||
/* Maps GDK contentformats to w32formats or vice versa, depending on the
|
||||
* semantics of the array that holds these.
|
||||
@@ -114,6 +113,15 @@ typedef enum _GdkWin32CFIndex GdkWin32CFIndex;
|
||||
typedef struct _GdkWin32Clipdrop GdkWin32Clipdrop;
|
||||
typedef struct _GdkWin32ClipdropClass GdkWin32ClipdropClass;
|
||||
|
||||
/* this is shared with gdkdrag-win32.c as well */
|
||||
struct _clipdrop_thread_items
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop;
|
||||
GAsyncQueue *queue;
|
||||
};
|
||||
|
||||
typedef struct _clipdrop_thread_items clipdrop_thread_items;
|
||||
|
||||
typedef BOOL (WINAPI * GetUpdatedClipboardFormatsFunc)(
|
||||
_Out_ PUINT lpuiFormats,
|
||||
_In_ UINT cFormats,
|
||||
@@ -224,6 +232,15 @@ struct _GdkWin32Clipdrop
|
||||
* dnd thread is not active.
|
||||
*/
|
||||
GHashTable *active_source_drags;
|
||||
|
||||
/* our custom MSG UINT that we register once to prcoess DND/Clipbord actions */
|
||||
UINT thread_wakeup_message;
|
||||
|
||||
/* this is a GdkWin32ClipboardThread structure */
|
||||
void *clipboard_thread_items;
|
||||
|
||||
/* this is a GdkWin32DndThread structure */
|
||||
void *dnd_thread_items;
|
||||
};
|
||||
|
||||
struct _GdkWin32ClipdropClass
|
||||
@@ -233,44 +250,46 @@ struct _GdkWin32ClipdropClass
|
||||
|
||||
GType gdk_win32_clipdrop_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _gdk_win32_clipdrop_init (void);
|
||||
|
||||
gboolean _gdk_win32_format_uses_hdata (UINT w32format);
|
||||
|
||||
char * _gdk_win32_get_clipboard_format_name (UINT fmt,
|
||||
gboolean *is_predefined);
|
||||
void _gdk_win32_add_w32format_to_pairs (UINT format,
|
||||
GArray *array,
|
||||
GdkContentFormatsBuilder *builder);
|
||||
int _gdk_win32_add_contentformat_to_pairs (const char *target,
|
||||
int _gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
|
||||
const char *target,
|
||||
GArray *array);
|
||||
|
||||
void _gdk_win32_clipboard_default_output_done (GObject *clipboard,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data);
|
||||
gboolean _gdk_win32_transmute_contentformat (const char *from_contentformat,
|
||||
gboolean gdk_win32_clipdrop_transmute_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
const char *from_contentformat,
|
||||
UINT to_w32format,
|
||||
const guchar *data,
|
||||
gsize length,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length);
|
||||
|
||||
gboolean _gdk_win32_transmute_windows_data (UINT from_w32format,
|
||||
const char *to_contentformat,
|
||||
HANDLE hdata,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length);
|
||||
gboolean gdk_win32_clipdrop_transmute_windows_data (GdkWin32Clipdrop *clipdrop,
|
||||
UINT from_w32format,
|
||||
const char *to_contentformat,
|
||||
HANDLE hdata,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length);
|
||||
|
||||
|
||||
gboolean _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
GdkContentFormats *contentformats);
|
||||
|
||||
void _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
|
||||
void _gdk_win32_retrieve_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
GdkContentFormats *contentformats);
|
||||
|
||||
void _gdk_win32_advertise_clipboard_contentformats (GTask *task,
|
||||
void _gdk_win32_advertise_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
GdkContentFormats *contentformats);
|
||||
|
||||
|
||||
|
||||
void gdk_win32_clipdrop_add_win32_format_to_pairs (GdkWin32Clipdrop *clipdrop,
|
||||
UINT format,
|
||||
GArray *array,
|
||||
GdkContentFormatsBuilder *builder);
|
||||
|
@@ -75,6 +75,7 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
POINT point;
|
||||
HWND hwnd, hwndc;
|
||||
int scale;
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
if (surface)
|
||||
{
|
||||
@@ -83,13 +84,11 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
scale = GDK_WIN32_DISPLAY (display)->surface_scale;
|
||||
hwnd = NULL;
|
||||
}
|
||||
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
_gdk_win32_get_cursor_pos (display, &point);
|
||||
|
||||
if (hwnd)
|
||||
ScreenToClient (hwnd, &point);
|
||||
@@ -105,7 +104,7 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
*child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc);
|
||||
else
|
||||
*child_surface = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
@@ -167,8 +166,9 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
|
||||
POINT screen_pt, client_pt;
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
if (!_gdk_win32_get_cursor_pos (&screen_pt))
|
||||
if (!_gdk_win32_get_cursor_pos (display, &screen_pt))
|
||||
return NULL;
|
||||
|
||||
/* Use WindowFromPoint instead of ChildWindowFromPoint(Ex).
|
||||
@@ -183,7 +183,7 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
|
||||
if (!PtInRect (&rect, client_pt))
|
||||
hwnd = NULL;
|
||||
|
||||
surface = gdk_win32_handle_table_lookup_ (hwnd);
|
||||
surface = gdk_win32_display_handle_table_lookup_ (display, hwnd);
|
||||
|
||||
if (surface && (win_x || win_y))
|
||||
{
|
||||
|
@@ -65,6 +65,7 @@ gdk_device_winpointer_query_state (GdkDevice *device,
|
||||
POINT point;
|
||||
HWND hwnd, hwndc;
|
||||
int scale;
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
device_winpointer = GDK_DEVICE_WINPOINTER (device);
|
||||
if (surface)
|
||||
@@ -74,13 +75,11 @@ gdk_device_winpointer_query_state (GdkDevice *device,
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
scale = GDK_WIN32_DISPLAY (display)->surface_scale;
|
||||
hwnd = NULL;
|
||||
}
|
||||
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
_gdk_win32_get_cursor_pos (display, &point);
|
||||
|
||||
if (hwnd)
|
||||
ScreenToClient (hwnd, &point);
|
||||
@@ -96,7 +95,7 @@ gdk_device_winpointer_query_state (GdkDevice *device,
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
*child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc);
|
||||
else
|
||||
*child_surface = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
@@ -144,8 +143,9 @@ gdk_device_winpointer_surface_at_position (GdkDevice *device,
|
||||
POINT screen_pt, client_pt;
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
if (!_gdk_win32_get_cursor_pos (&screen_pt))
|
||||
if (!_gdk_win32_get_cursor_pos (display, &screen_pt))
|
||||
return NULL;
|
||||
|
||||
/* Use WindowFromPoint instead of ChildWindowFromPoint(Ex).
|
||||
@@ -160,7 +160,7 @@ gdk_device_winpointer_surface_at_position (GdkDevice *device,
|
||||
if (!PtInRect (&rect, client_pt))
|
||||
hwnd = NULL;
|
||||
|
||||
surface = gdk_win32_handle_table_lookup_ (hwnd);
|
||||
surface = gdk_win32_display_handle_table_lookup_ (display, hwnd);
|
||||
|
||||
if (surface && (win_x || win_y))
|
||||
{
|
||||
|
@@ -73,6 +73,7 @@ gdk_device_wintab_query_state (GdkDevice *device,
|
||||
POINT point;
|
||||
HWND hwnd, hwndc;
|
||||
int scale;
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
device_wintab = GDK_DEVICE_WINTAB (device);
|
||||
if (surface)
|
||||
@@ -82,13 +83,11 @@ gdk_device_wintab_query_state (GdkDevice *device,
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
scale = GDK_WIN32_DISPLAY (display)->surface_scale;
|
||||
hwnd = NULL;
|
||||
}
|
||||
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
_gdk_win32_get_cursor_pos (display, &point);
|
||||
|
||||
if (hwnd)
|
||||
ScreenToClient (hwnd, &point);
|
||||
@@ -104,7 +103,7 @@ gdk_device_wintab_query_state (GdkDevice *device,
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
*child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc);
|
||||
else
|
||||
*child_surface = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
|
@@ -45,11 +45,6 @@
|
||||
#define DEBUG_WINTAB 1 /* Verbose debug messages enabled */
|
||||
#define TWOPI (2 * G_PI)
|
||||
|
||||
/* TODO: get rid of these global variables */
|
||||
static GList *wintab_contexts = NULL;
|
||||
static GdkSurface *wintab_surface = NULL;
|
||||
extern int _gdk_input_ignore_core;
|
||||
|
||||
typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
|
||||
typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
|
||||
typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
|
||||
@@ -60,22 +55,39 @@ typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
|
||||
typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
|
||||
typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
|
||||
|
||||
static t_WTInfoA p_WTInfoA;
|
||||
static t_WTInfoW p_WTInfoW;
|
||||
static t_WTEnable p_WTEnable;
|
||||
static t_WTOpenA p_WTOpenA;
|
||||
static t_WTGetA p_WTGetA;
|
||||
static t_WTSetA p_WTSetA;
|
||||
static t_WTOverlap p_WTOverlap;
|
||||
static t_WTPacket p_WTPacket;
|
||||
struct _wintab_items
|
||||
{
|
||||
GList *wintab_contexts;
|
||||
GdkSurface *wintab_surface;
|
||||
HMODULE wintab32;
|
||||
|
||||
t_WTInfoA p_WTInfoA;
|
||||
t_WTInfoW p_WTInfoW;
|
||||
t_WTEnable p_WTEnable;
|
||||
t_WTOpenA p_WTOpenA;
|
||||
t_WTGetA p_WTGetA;
|
||||
t_WTSetA p_WTSetA;
|
||||
t_WTOverlap p_WTOverlap;
|
||||
t_WTPacket p_WTPacket;
|
||||
t_WTQueueSizeSet p_WTQueueSizeSet;
|
||||
};
|
||||
|
||||
static t_WTQueueSizeSet p_WTQueueSizeSet;
|
||||
|
||||
static gboolean default_display_opened = FALSE;
|
||||
|
||||
G_DEFINE_TYPE (GdkDeviceManagerWin32, gdk_device_manager_win32, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DISPLAY,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *device_manager_props[LAST_PROP] = { NULL, };
|
||||
|
||||
static GdkDevice *
|
||||
create_pointer (GdkDeviceManagerWin32 *device_manager,
|
||||
create_pointer (GdkDisplay *display,
|
||||
GType g_type,
|
||||
const char *name,
|
||||
gboolean has_cursor)
|
||||
@@ -84,12 +96,12 @@ create_pointer (GdkDeviceManagerWin32 *device_manager,
|
||||
"name", name,
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", has_cursor,
|
||||
"display", _gdk_display,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_keyboard (GdkDeviceManagerWin32 *device_manager,
|
||||
create_keyboard (GdkDisplay *display,
|
||||
GType g_type,
|
||||
const char *name)
|
||||
{
|
||||
@@ -97,7 +109,7 @@ create_keyboard (GdkDeviceManagerWin32 *device_manager,
|
||||
"name", name,
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", FALSE,
|
||||
"display", _gdk_display,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -113,6 +125,38 @@ gdk_device_manager_win32_finalize (GObject *object)
|
||||
|
||||
device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (object);
|
||||
|
||||
if (device_manager_win32->ignored_interactions != NULL)
|
||||
{
|
||||
g_ptr_array_free (device_manager_win32->ignored_interactions, FALSE);
|
||||
device_manager_win32->ignored_interactions = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&device_manager_win32->winpointer_funcs, g_free);
|
||||
|
||||
/* Sadly, no g_clear_pointer() on DestroyWindow() as it is __stdcall */
|
||||
if (device_manager_win32->winpointer_notification_hwnd != NULL)
|
||||
{
|
||||
DestroyWindow (device_manager_win32->winpointer_notification_hwnd);
|
||||
device_manager_win32->winpointer_notification_hwnd = NULL;
|
||||
}
|
||||
|
||||
if (device_manager_win32->wintab_items)
|
||||
{
|
||||
if (device_manager_win32->wintab_items->wintab_contexts)
|
||||
{
|
||||
g_list_free_full (device_manager_win32->wintab_items->wintab_contexts, g_free);
|
||||
device_manager_win32->wintab_items->wintab_contexts = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&device_manager_win32->wintab_items->wintab_surface, g_object_unref);
|
||||
if (device_manager_win32->wintab_items->wintab32 != NULL)
|
||||
{
|
||||
FreeLibrary (device_manager_win32->wintab_items->wintab32);
|
||||
device_manager_win32->wintab_items->wintab32 = NULL;
|
||||
}
|
||||
g_clear_pointer (&device_manager_win32->wintab_items, g_free);
|
||||
}
|
||||
|
||||
g_object_unref (device_manager_win32->core_pointer);
|
||||
g_object_unref (device_manager_win32->core_keyboard);
|
||||
|
||||
@@ -215,8 +259,13 @@ print_lc(LOGCONTEXTA *lc)
|
||||
lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
|
||||
}
|
||||
|
||||
#define WINTAB_API_CHECK(device_manager,f)\
|
||||
((device_manager->wintab_items->p_##f = (t_##f) GetProcAddress (device_manager->wintab_items->wintab32, "##f##")) != NULL)
|
||||
#define WINTAB_API_CALL(device_manager,f) device_manager->wintab_items->p_##f
|
||||
|
||||
static void
|
||||
print_cursor (int index)
|
||||
print_cursor (GdkDeviceManagerWin32 *device_manager,
|
||||
int index)
|
||||
{
|
||||
int size;
|
||||
int i;
|
||||
@@ -241,13 +290,13 @@ print_cursor (int index)
|
||||
UINT minbuttons;
|
||||
UINT capabilities;
|
||||
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
|
||||
name = g_malloc (size + 1);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
|
||||
g_print ("NAME: %s\n", name);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
|
||||
g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
|
||||
g_print ("PKTDATA: %#x:", (guint) wtpkt);
|
||||
#define BIT(x) if (wtpkt & PK_##x) g_print (" " #x)
|
||||
BIT (CONTEXT);
|
||||
@@ -265,16 +314,16 @@ print_cursor (int index)
|
||||
BIT (ROTATION);
|
||||
#undef BIT
|
||||
g_print ("\n");
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
|
||||
g_print ("BUTTONS: %d\n", buttons);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
|
||||
g_print ("BUTTONBITS: %d\n", buttonbits);
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
|
||||
g_print ("BTNNAMES:");
|
||||
if (size > 0)
|
||||
{
|
||||
btnnames = g_malloc (size + 1);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
|
||||
p = btnnames;
|
||||
while (*p)
|
||||
{
|
||||
@@ -283,47 +332,47 @@ print_cursor (int index)
|
||||
}
|
||||
}
|
||||
g_print ("\n");
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
|
||||
g_print ("BUTTONMAP:");
|
||||
for (i = 0; i < buttons; i++)
|
||||
g_print (" %d", buttonmap[i]);
|
||||
g_print ("\n");
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
|
||||
g_print ("SYSBTNMAP:");
|
||||
for (i = 0; i < buttons; i++)
|
||||
g_print (" %d", sysbtnmap[i]);
|
||||
g_print ("\n");
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
|
||||
g_print ("NPBUTTON: %d\n", npbutton);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
|
||||
g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
|
||||
g_print ("NPRESPONSE:");
|
||||
if (size > 0)
|
||||
{
|
||||
npresponse = g_malloc (size);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
|
||||
for (i = 0; i < size / sizeof (UINT); i++)
|
||||
g_print (" %d", npresponse[i]);
|
||||
}
|
||||
g_print ("\n");
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
|
||||
g_print ("TPBUTTON: %d\n", tpbutton);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
|
||||
g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
|
||||
g_print ("TPRESPONSE:");
|
||||
if (size > 0)
|
||||
{
|
||||
tpresponse = g_malloc (size);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
|
||||
for (i = 0; i < size / sizeof (UINT); i++)
|
||||
g_print (" %d", tpresponse[i]);
|
||||
}
|
||||
g_print ("\n");
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
|
||||
g_print ("PHYSID: %#x\n", (guint) physid);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
|
||||
g_print ("CAPABILITIES: %#x:", capabilities);
|
||||
#define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
|
||||
BIT (MULTIMODE);
|
||||
@@ -333,14 +382,14 @@ print_cursor (int index)
|
||||
g_print ("\n");
|
||||
if (capabilities & CRC_MULTIMODE)
|
||||
{
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
|
||||
g_print ("MODE: %d\n", mode);
|
||||
}
|
||||
if (capabilities & CRC_AGGREGATE)
|
||||
{
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
|
||||
g_print ("MINPKTDATA: %d\n", minpktdata);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
|
||||
g_print ("MINBUTTONS: %d\n", minbuttons);
|
||||
}
|
||||
}
|
||||
@@ -373,7 +422,8 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
|
||||
wintab_initialized = TRUE;
|
||||
|
||||
wintab_contexts = NULL;
|
||||
device_manager->wintab_items = g_new0 (wintab_items, 1);
|
||||
device_manager->wintab_items->wintab_contexts = NULL;
|
||||
|
||||
n = GetSystemDirectoryA (&dummy, 0);
|
||||
|
||||
@@ -396,41 +446,35 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
if ((wintab32 = LoadLibraryA (wintab32_dll_path)) == NULL)
|
||||
return;
|
||||
|
||||
if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
|
||||
return;
|
||||
if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
|
||||
return;
|
||||
if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
|
||||
return;
|
||||
if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
|
||||
return;
|
||||
if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
|
||||
return;
|
||||
if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
|
||||
return;
|
||||
if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
|
||||
return;
|
||||
if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
|
||||
return;
|
||||
if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
|
||||
device_manager->wintab_items->wintab32 = wintab32;
|
||||
|
||||
if (!WINTAB_API_CHECK (device_manager, WTInfoA) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTInfoW) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTEnable) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTOpenA) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTGetA) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTSetA) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTOverlap) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTPacket) ||
|
||||
!WINTAB_API_CHECK (device_manager, WTQueueSizeSet))
|
||||
return;
|
||||
|
||||
if (!(*p_WTInfoA) (0, 0, NULL))
|
||||
if (!WINTAB_API_CALL (device_manager, WTInfoA) (0, 0, NULL))
|
||||
return;
|
||||
|
||||
(*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
|
||||
GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
|
||||
HIBYTE (specversion), LOBYTE (specversion)));
|
||||
(*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
|
||||
(*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
|
||||
#if DEBUG_WINTAB
|
||||
GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
|
||||
ndevices, ncursors));
|
||||
#endif
|
||||
/* Create a dummy surface to receive wintab events */
|
||||
wintab_surface = gdk_win32_drag_surface_new (display);
|
||||
device_manager->wintab_items->wintab_surface = gdk_win32_drag_surface_new (display);
|
||||
|
||||
g_object_ref (wintab_surface);
|
||||
g_object_ref (device_manager->wintab_items->wintab_surface);
|
||||
|
||||
for (devix = 0; devix < ndevices; devix++)
|
||||
{
|
||||
@@ -442,25 +486,25 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
* cursor. This seems much more natural.
|
||||
*/
|
||||
|
||||
(*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
|
||||
WINTAB_API_CALL (device_manager, WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
|
||||
devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
|
||||
#ifdef DEBUG_WINTAB
|
||||
GDK_NOTE (INPUT, (g_print("Device %u: %s\n", devix, devname_utf8)));
|
||||
#endif
|
||||
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
|
||||
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
|
||||
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
|
||||
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
|
||||
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
|
||||
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
|
||||
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
|
||||
|
||||
defcontext_done = FALSE;
|
||||
if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
|
||||
{
|
||||
/* Try to get device-specific default context */
|
||||
/* Some drivers, e.g. Aiptek, don't provide this info */
|
||||
if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
|
||||
if (WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
|
||||
defcontext_done = TRUE;
|
||||
#if DEBUG_WINTAB
|
||||
if (defcontext_done)
|
||||
@@ -471,7 +515,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
}
|
||||
|
||||
if (!defcontext_done)
|
||||
(*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
|
||||
#if DEBUG_WINTAB
|
||||
GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
|
||||
#endif
|
||||
@@ -493,7 +537,10 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
print_lc(&lc)));
|
||||
#endif
|
||||
hctx = g_new (HCTX, 1);
|
||||
if ((*hctx = (*p_WTOpenA) (GDK_SURFACE_HWND (wintab_surface), &lc, TRUE)) == NULL)
|
||||
if ((*hctx =
|
||||
WINTAB_API_CALL (device_manager, WTOpenA) (GDK_SURFACE_HWND (device_manager->wintab_items->wintab_surface),
|
||||
&lc,
|
||||
TRUE)) == NULL)
|
||||
{
|
||||
g_warning ("gdk_input_wintab_init: WTOpen failed");
|
||||
return;
|
||||
@@ -501,11 +548,12 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
GDK_NOTE (INPUT, g_print ("opened Wintab device %u %p\n",
|
||||
devix, *hctx));
|
||||
|
||||
wintab_contexts = g_list_append (wintab_contexts, hctx);
|
||||
device_manager->wintab_items->wintab_contexts =
|
||||
g_list_append (device_manager->wintab_items->wintab_contexts, hctx);
|
||||
#if 0
|
||||
(*p_WTEnable) (*hctx, TRUE);
|
||||
WINTAB_API_CALL (device_manager, WTEnable) (*hctx, TRUE);
|
||||
#endif
|
||||
(*p_WTOverlap) (*hctx, TRUE);
|
||||
WINTAB_API_CALL (device_manager, WTOverlap) (*hctx, TRUE);
|
||||
|
||||
#if DEBUG_WINTAB
|
||||
GDK_NOTE (INPUT, (g_print("context for device %u after WTOpen:\n", devix),
|
||||
@@ -518,7 +566,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
|
||||
for (i = 128; i >= 1; i >>= 1)
|
||||
{
|
||||
if ((*p_WTQueueSizeSet) (*hctx, i))
|
||||
if (WINTAB_API_CALL (device_manager, WTQueueSizeSet) (*hctx, i))
|
||||
{
|
||||
GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
|
||||
break;
|
||||
@@ -529,10 +577,10 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
|
||||
{
|
||||
#ifdef DEBUG_WINTAB
|
||||
GDK_NOTE (INPUT, (g_print("Cursor %u:\n", cursorix), print_cursor (cursorix)));
|
||||
GDK_NOTE (INPUT, (g_print("Cursor %u:\n", cursorix), print_cursor (device_manager, cursorix)));
|
||||
#endif
|
||||
active = FALSE;
|
||||
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
|
||||
if (!active)
|
||||
continue;
|
||||
|
||||
@@ -544,11 +592,11 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
* second instances of the styluses report physid zero. So
|
||||
* at least for Wacom, skip cursors with physid zero.
|
||||
*/
|
||||
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
|
||||
if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
|
||||
continue;
|
||||
|
||||
(*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
|
||||
WINTAB_API_CALL (device_manager, WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
|
||||
csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
|
||||
device_name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);
|
||||
|
||||
@@ -570,7 +618,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
|
||||
device->hctx = *hctx;
|
||||
device->cursor = cursorix;
|
||||
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
|
||||
|
||||
if (device->pktdata & PK_X)
|
||||
{
|
||||
@@ -670,7 +718,7 @@ wintab_default_display_notify_cb (GdkDisplayManager *display_manager)
|
||||
|
||||
g_assert (display != NULL);
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
|
||||
device_manager = GDK_WIN32_DISPLAY (display)->device_manager;
|
||||
g_assert (display_manager != NULL);
|
||||
|
||||
default_display_opened = TRUE;
|
||||
@@ -687,16 +735,16 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
const char *api_preference = NULL;
|
||||
gboolean have_api_preference = TRUE;
|
||||
|
||||
display_win32 = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
|
||||
display_win32 = GDK_WIN32_DISPLAY (device_manager->display);
|
||||
|
||||
device_manager->core_pointer =
|
||||
create_pointer (device_manager,
|
||||
create_pointer (device_manager->display,
|
||||
GDK_TYPE_DEVICE_VIRTUAL,
|
||||
"Virtual Core Pointer",
|
||||
TRUE);
|
||||
device_manager->system_pointer =
|
||||
create_pointer (device_manager,
|
||||
create_pointer (device_manager->display,
|
||||
GDK_TYPE_DEVICE_WIN32,
|
||||
"System Aggregated Pointer",
|
||||
FALSE);
|
||||
@@ -706,11 +754,11 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
_gdk_device_add_physical_device (device_manager->core_pointer, device_manager->system_pointer);
|
||||
|
||||
device_manager->core_keyboard =
|
||||
create_keyboard (device_manager,
|
||||
create_keyboard (device_manager->display,
|
||||
GDK_TYPE_DEVICE_VIRTUAL,
|
||||
"Virtual Core Keyboard");
|
||||
device_manager->system_keyboard =
|
||||
create_keyboard (device_manager,
|
||||
create_keyboard (device_manager->display,
|
||||
GDK_TYPE_DEVICE_WIN32,
|
||||
"System Aggregated Keyboard");
|
||||
_gdk_device_virtual_set_active (device_manager->core_keyboard,
|
||||
@@ -723,12 +771,12 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
|
||||
seat = gdk_seat_default_new_for_logical_pair (device_manager->core_pointer,
|
||||
device_manager->core_keyboard);
|
||||
gdk_display_add_seat (_gdk_display, seat);
|
||||
gdk_display_add_seat (device_manager->display, seat);
|
||||
gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), device_manager->system_pointer);
|
||||
gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), device_manager->system_keyboard);
|
||||
g_object_unref (seat);
|
||||
|
||||
_gdk_device_manager = device_manager;
|
||||
display_win32->device_manager = device_manager;
|
||||
|
||||
api_preference = g_getenv ("GDK_WIN32_TABLET_INPUT_API");
|
||||
if (g_strcmp0 (api_preference, "none") == 0)
|
||||
@@ -754,7 +802,7 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
|
||||
if (display_win32->tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
|
||||
{
|
||||
gboolean init_successful = gdk_winpointer_initialize ();
|
||||
gboolean init_successful = gdk_winpointer_initialize (device_manager);
|
||||
|
||||
if (!init_successful && !have_api_preference)
|
||||
{
|
||||
@@ -783,6 +831,44 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_win32_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceManagerWin32 *device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, device_manager->display);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_win32_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceManagerWin32 *device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
device_manager->display = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_win32_class_init (GdkDeviceManagerWin32Class *klass)
|
||||
{
|
||||
@@ -790,10 +876,19 @@ gdk_device_manager_win32_class_init (GdkDeviceManagerWin32Class *klass)
|
||||
|
||||
object_class->finalize = gdk_device_manager_win32_finalize;
|
||||
object_class->constructed = gdk_device_manager_win32_constructed;
|
||||
object_class->set_property = gdk_device_manager_win32_set_property;
|
||||
object_class->get_property = gdk_device_manager_win32_get_property;
|
||||
|
||||
device_manager_props[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display", NULL, NULL,
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, device_manager_props);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wintab_set_tablet_active (void)
|
||||
_gdk_wintab_set_tablet_active (GdkDeviceManagerWin32 *device_manager)
|
||||
{
|
||||
GList *tmp_list;
|
||||
HCTX *hctx;
|
||||
@@ -801,18 +896,18 @@ _gdk_wintab_set_tablet_active (void)
|
||||
/* Bring the contexts to the top of the overlap order when one of the
|
||||
* application's HWNDs is activated */
|
||||
|
||||
if (!wintab_contexts)
|
||||
if (!device_manager->wintab_items->wintab_contexts)
|
||||
return; /* No tablet devices found, or Wintab not initialized yet */
|
||||
|
||||
GDK_NOTE (INPUT, g_print ("_gdk_wintab_set_tablet_active: "
|
||||
"Bringing Wintab contexts to the top of the overlap order\n"));
|
||||
|
||||
tmp_list = wintab_contexts;
|
||||
tmp_list = device_manager->wintab_items->wintab_contexts;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
hctx = (HCTX *) (tmp_list->data);
|
||||
(*p_WTOverlap) (*hctx, TRUE);
|
||||
WINTAB_API_CALL (device_manager, WTOverlap) (*hctx, TRUE);
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
@@ -933,13 +1028,13 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
*/
|
||||
static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
|
||||
|
||||
if (surface != wintab_surface)
|
||||
device_manager = GDK_WIN32_DISPLAY (display)->device_manager;
|
||||
if (surface != device_manager->wintab_items->wintab_surface)
|
||||
{
|
||||
g_warning ("gdk_wintab_make_event: not wintab_surface?");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
|
||||
surface = gdk_device_get_surface_at_position (device_manager->core_pointer, &x, &y);
|
||||
|
||||
if (surface)
|
||||
@@ -951,7 +1046,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
|
||||
if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
|
||||
{
|
||||
if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
|
||||
if (!WINTAB_API_CALL (device_manager, WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -976,12 +1071,12 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
{
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
GDK_DEVICE (source_device));
|
||||
_gdk_input_ignore_core += 1;
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core += 1;
|
||||
}
|
||||
}
|
||||
else if (source_device != NULL &&
|
||||
source_device->sends_core &&
|
||||
_gdk_input_ignore_core == 0)
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core == 0)
|
||||
{
|
||||
/* A fallback for cases when two devices (disabled and enabled)
|
||||
* were in proximity simultaneously.
|
||||
@@ -997,7 +1092,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
*/
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
GDK_DEVICE (source_device));
|
||||
_gdk_input_ignore_core += 1;
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core += 1;
|
||||
}
|
||||
|
||||
if (source_device == NULL)
|
||||
@@ -1006,7 +1101,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
/* Don't produce any button or motion events while a surface is being
|
||||
* moved or resized, see bug #151090.
|
||||
*/
|
||||
if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
|
||||
if (GDK_WIN32_DISPLAY (display)->display_surface_record->modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
|
||||
{
|
||||
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
|
||||
return NULL;
|
||||
@@ -1160,7 +1255,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
{
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
GDK_DEVICE (source_device));
|
||||
_gdk_input_ignore_core += 1;
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core += 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1168,11 +1263,11 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
case WT_PROXIMITY:
|
||||
if (LOWORD (msg->lParam) == 0)
|
||||
{
|
||||
if (_gdk_input_ignore_core > 0)
|
||||
if (GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core > 0)
|
||||
{
|
||||
_gdk_input_ignore_core -= 1;
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core -= 1;
|
||||
|
||||
if (_gdk_input_ignore_core == 0)
|
||||
if (GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core == 0)
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
device_manager->system_pointer);
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkDeviceManagerWin32 GdkDeviceManagerWin32;
|
||||
typedef struct _GdkDeviceManagerWin32Class GdkDeviceManagerWin32Class;
|
||||
typedef struct _wintab_items wintab_items;
|
||||
|
||||
struct _GdkDeviceManagerWin32
|
||||
{
|
||||
@@ -43,11 +44,23 @@ struct _GdkDeviceManagerWin32
|
||||
GList *winpointer_devices;
|
||||
GList *wintab_devices;
|
||||
|
||||
|
||||
/* Bumped up every time a wintab device enters the proximity
|
||||
* of our context (WT_PROXIMITY). Bumped down when we either
|
||||
* receive a WT_PACKET, or a WT_CSRCHANGE.
|
||||
*/
|
||||
int dev_entered_proximity;
|
||||
|
||||
/* used for wintab support */
|
||||
wintab_items *wintab_items;
|
||||
|
||||
/* used for winpointer support, etc */
|
||||
HWND winpointer_notification_hwnd;
|
||||
GPtrArray *ignored_interactions;
|
||||
void *winpointer_funcs; /* GdkDeviceManagerWin32WinpointerFuncs */
|
||||
gboolean pen_touch_input;
|
||||
POINT latest_pen_touch_position;
|
||||
LONG last_digitizer_time;
|
||||
};
|
||||
|
||||
struct _GdkDeviceManagerWin32Class
|
||||
@@ -57,10 +70,10 @@ struct _GdkDeviceManagerWin32Class
|
||||
|
||||
GType gdk_device_manager_win32_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _gdk_wintab_set_tablet_active (void);
|
||||
GdkEvent * gdk_wintab_make_event (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
GdkSurface *surface);
|
||||
void _gdk_wintab_set_tablet_active (GdkDeviceManagerWin32 *device_manager);
|
||||
GdkEvent *gdk_wintab_make_event (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
GdkSurface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkdevicemanager-win32.h"
|
||||
#include "gdkglcontext-win32.h"
|
||||
#include "gdkinput-dmanipulation.h"
|
||||
#include "gdksurface-win32.h"
|
||||
#include "gdkwin32display.h"
|
||||
#include "gdkwin32screen.h"
|
||||
@@ -38,7 +39,6 @@
|
||||
|
||||
#include <dwmapi.h>
|
||||
|
||||
#include "gdkwin32langnotification.h"
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
@@ -47,8 +47,6 @@
|
||||
# define IMAGE_FILE_MACHINE_ARM64 0xAA64
|
||||
#endif
|
||||
|
||||
static int debug_indent = 0;
|
||||
|
||||
/**
|
||||
* gdk_win32_display_add_filter:
|
||||
* @display: a `GdkWin32Display`
|
||||
@@ -439,7 +437,7 @@ inner_display_change_hwnd_procedure (HWND hwnd,
|
||||
}
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (GetWindowLongPtr (hwnd, GWLP_USERDATA));
|
||||
|
||||
_gdk_win32_screen_on_displaychange_event (GDK_WIN32_SCREEN (win32_display->screen));
|
||||
return 0;
|
||||
@@ -458,16 +456,37 @@ display_change_hwnd_procedure (HWND hwnd,
|
||||
LPARAM lparam)
|
||||
{
|
||||
LRESULT retval;
|
||||
GdkDisplay *display;
|
||||
|
||||
GDK_NOTE (EVENTS, g_print ("%s%*s%s %p",
|
||||
(debug_indent > 0 ? "\n" : ""),
|
||||
debug_indent, "",
|
||||
_gdk_win32_message_to_string (message), hwnd));
|
||||
debug_indent += 2;
|
||||
retval = inner_display_change_hwnd_procedure (hwnd, message, wparam, lparam);
|
||||
debug_indent -= 2;
|
||||
if (message == WM_NCCREATE)
|
||||
{
|
||||
CREATESTRUCT *cs = (CREATESTRUCT *)lparam;
|
||||
display = (GdkDisplay *)cs->lpCreateParams;
|
||||
|
||||
GDK_NOTE (EVENTS, g_print (" => %" G_GINT64_FORMAT "%s", (gint64) retval, (debug_indent == 0 ? "\n" : "")));
|
||||
SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) display);
|
||||
retval = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int debug_indent;
|
||||
|
||||
display = GDK_DISPLAY (GetWindowLongPtr (hwnd, GWLP_USERDATA));
|
||||
|
||||
debug_indent = GDK_WIN32_DISPLAY (display)->event_record->debug_indent_displaychange;
|
||||
GDK_NOTE (EVENTS, g_print ("%s%*s%s %p",
|
||||
(debug_indent > 0 ? "\n" : ""),
|
||||
debug_indent, "",
|
||||
_gdk_win32_message_to_string (message), hwnd));
|
||||
|
||||
GDK_WIN32_DISPLAY (display)->event_record->debug_indent_displaychange += 2;
|
||||
|
||||
retval = inner_display_change_hwnd_procedure (hwnd, message, wparam, lparam);
|
||||
|
||||
GDK_WIN32_DISPLAY (display)->event_record->debug_indent_displaychange -= 2;
|
||||
SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) display);
|
||||
debug_indent = GDK_WIN32_DISPLAY (display)->event_record->debug_indent_displaychange;
|
||||
GDK_NOTE (EVENTS, g_print (" => %" G_GINT64_FORMAT "%s", (gint64) retval, (debug_indent == 0 ? "\n" : "")));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -491,7 +510,7 @@ register_display_change_notification (GdkDisplay *display)
|
||||
display_win32->hwnd = CreateWindow (MAKEINTRESOURCE (klass),
|
||||
NULL, WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL,
|
||||
this_module (), NULL);
|
||||
this_module (), display);
|
||||
if (!display_win32->hwnd)
|
||||
{
|
||||
UnregisterClass (MAKEINTRESOURCE (klass), this_module ());
|
||||
@@ -502,58 +521,66 @@ register_display_change_notification (GdkDisplay *display)
|
||||
GdkDisplay *
|
||||
_gdk_win32_display_open (const char *display_name)
|
||||
{
|
||||
static gsize display_inited = 0;
|
||||
static GdkDisplay *display = NULL;
|
||||
GdkWin32Display *win32_display;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_display_open: %s\n", (display_name ? display_name : "NULL")));
|
||||
|
||||
if (display_name == NULL ||
|
||||
g_ascii_strcasecmp (display_name,
|
||||
gdk_display_get_name (_gdk_display)) == 0)
|
||||
if (display_name == NULL || g_ascii_strcasecmp (display_name, gdk_display_get_name (display)) == 0)
|
||||
{
|
||||
if (_gdk_display != NULL)
|
||||
{
|
||||
GDK_NOTE (MISC, g_print ("... return _gdk_display\n"));
|
||||
return _gdk_display;
|
||||
}
|
||||
if (display != NULL)
|
||||
{
|
||||
GDK_NOTE (MISC, g_print ("... return existing gdkdisplay\n"));
|
||||
return display;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we don't really support multiple GdkDisplay's on Windows at this point */
|
||||
GDK_NOTE (MISC, g_print ("... return NULL\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_gdk_display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
|
||||
win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
if (g_once_init_enter (&display_inited))
|
||||
{
|
||||
display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
|
||||
|
||||
win32_display->screen = g_object_new (GDK_TYPE_WIN32_SCREEN, NULL);
|
||||
win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
_gdk_events_init (_gdk_display);
|
||||
win32_display->screen = g_object_new (GDK_TYPE_WIN32_SCREEN,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
_gdk_input_ignore_core = 0;
|
||||
_gdk_events_init (display);
|
||||
|
||||
_gdk_device_manager = g_object_new (GDK_TYPE_DEVICE_MANAGER_WIN32,
|
||||
NULL);
|
||||
_gdk_device_manager->display = _gdk_display;
|
||||
win32_display->device_manager = g_object_new (GDK_TYPE_DEVICE_MANAGER_WIN32,
|
||||
"display", display,
|
||||
NULL);
|
||||
gdk_dmanipulation_initialize (win32_display);
|
||||
|
||||
_gdk_win32_lang_notification_init ();
|
||||
_gdk_drag_init ();
|
||||
gdk_win32_display_lang_notification_init (win32_display);
|
||||
_gdk_drag_init ();
|
||||
|
||||
_gdk_display->clipboard = gdk_win32_clipboard_new (_gdk_display);
|
||||
_gdk_display->primary_clipboard = gdk_clipboard_new (_gdk_display);
|
||||
display->clipboard = gdk_win32_clipboard_new (display);
|
||||
display->primary_clipboard = gdk_clipboard_new (display);
|
||||
|
||||
/* Precalculate display name */
|
||||
(void) gdk_display_get_name (_gdk_display);
|
||||
/* Precalculate display name */
|
||||
gdk_display_get_name (display);
|
||||
|
||||
register_display_change_notification (_gdk_display);
|
||||
register_display_change_notification (display);
|
||||
|
||||
g_signal_emit_by_name (_gdk_display, "opened");
|
||||
g_signal_emit_by_name (display, "opened");
|
||||
|
||||
/* Precalculate keymap, see #6203 */
|
||||
(void) _gdk_win32_display_get_keymap (_gdk_display);
|
||||
/* Precalculate keymap, see #6203 */
|
||||
gdk_display_get_keymap (display);
|
||||
|
||||
GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n"));
|
||||
GDK_NOTE (MISC, g_print ("... gdk_display now set up\n"));
|
||||
|
||||
return _gdk_display;
|
||||
g_once_init_leave (&display_inited, 1);
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32Display, gdk_win32_display, GDK_TYPE_DISPLAY)
|
||||
@@ -639,7 +666,7 @@ gdk_win32_display_beep (GdkDisplay *display)
|
||||
static void
|
||||
gdk_win32_display_flush (GdkDisplay * display)
|
||||
{
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
g_return_if_fail (display == gdk_display_get_default());
|
||||
|
||||
GdiFlush ();
|
||||
}
|
||||
@@ -647,7 +674,7 @@ gdk_win32_display_flush (GdkDisplay * display)
|
||||
static void
|
||||
gdk_win32_display_sync (GdkDisplay * display)
|
||||
{
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
g_return_if_fail (display == gdk_display_get_default());
|
||||
|
||||
GdiFlush ();
|
||||
}
|
||||
@@ -687,9 +714,22 @@ gdk_win32_display_finalize (GObject *object)
|
||||
{
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object);
|
||||
|
||||
g_free (display_win32->event_record);
|
||||
if (display_win32->display_surface_record->modal_timer != 0)
|
||||
{
|
||||
KillTimer (NULL, display_win32->display_surface_record->modal_timer);
|
||||
display_win32->display_surface_record->modal_timer = 0;
|
||||
}
|
||||
g_slist_free_full (display_win32->display_surface_record->modal_surface_stack, g_object_unref);
|
||||
g_hash_table_destroy (display_win32->display_surface_record->handle_ht);
|
||||
g_free (display_win32->display_surface_record);
|
||||
_gdk_win32_display_finalize_cursors (display_win32);
|
||||
gdk_win32_display_close_dmanip_manager (GDK_DISPLAY (display_win32));
|
||||
_gdk_win32_dnd_exit ();
|
||||
_gdk_win32_lang_notification_exit ();
|
||||
gdk_win32_display_lang_notification_exit (display_win32);
|
||||
g_free (display_win32->pointer_device_items);
|
||||
g_object_unref (display_win32->cb_dnd_items->clipdrop);
|
||||
g_free (display_win32->cb_dnd_items);
|
||||
|
||||
g_list_store_remove_all (G_LIST_STORE (display_win32->monitors));
|
||||
g_object_unref (display_win32->monitors);
|
||||
@@ -1024,13 +1064,45 @@ _gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type)
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gdk_handle_hash (HANDLE *handle)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return ((guint *) handle)[0] ^ ((guint *) handle)[1];
|
||||
#else
|
||||
return (guint) *handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_handle_equal (HANDLE *a,
|
||||
HANDLE *b)
|
||||
{
|
||||
return (*a == *b);
|
||||
}
|
||||
|
||||
/* facts of life, DestroyWindow() is a __stdcall function */
|
||||
static void
|
||||
gdk_destroy_surface_hwnd (gpointer hwnd)
|
||||
{
|
||||
DestroyWindow ((HWND)hwnd);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_display_init (GdkWin32Display *display_win32)
|
||||
{
|
||||
const char *scale_str = g_getenv ("GDK_SCALE");
|
||||
|
||||
display_win32->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR));
|
||||
display_win32->pointer_device_items = g_new0 (GdkWin32PointerDeviceItems, 1);
|
||||
display_win32->cb_dnd_items = g_new0 (GdkWin32CbDnDItems, 1);
|
||||
display_win32->cb_dnd_items->display_main_thread = g_thread_self ();
|
||||
display_win32->cb_dnd_items->clipdrop = GDK_WIN32_CLIPDROP (g_object_new (GDK_TYPE_WIN32_CLIPDROP, NULL));
|
||||
display_win32->display_surface_record = g_new0 (surface_records, 1);
|
||||
display_win32->display_surface_record->handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash,
|
||||
(GEqualFunc) gdk_handle_equal);
|
||||
|
||||
display_win32->event_record = g_new0 (event_records, 1);
|
||||
_gdk_win32_enable_hidpi (display_win32);
|
||||
display_win32->running_on_arm64 = _gdk_win32_check_processor (GDK_WIN32_ARM64);
|
||||
|
||||
@@ -1175,17 +1247,6 @@ gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_display_get_setting (GdkDisplay *display,
|
||||
const char *name,
|
||||
GValue *value)
|
||||
{
|
||||
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_DEFAULT_SETTINGS)
|
||||
return FALSE;
|
||||
|
||||
return _gdk_win32_get_setting (name, value);
|
||||
}
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#endif
|
||||
@@ -1271,6 +1332,22 @@ gdk_win32_display_get_egl_display (GdkDisplay *display)
|
||||
return gdk_display_get_egl_display (display);
|
||||
}
|
||||
|
||||
GdkWin32Clipdrop *
|
||||
gdk_win32_display_get_clipdrop (GdkDisplay *display)
|
||||
{
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
return display_win32->cb_dnd_items->clipdrop;
|
||||
}
|
||||
|
||||
static GdkKeymap*
|
||||
_gdk_win32_display_get_keymap (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
||||
|
||||
return gdk_win32_display_get_default_keymap (GDK_WIN32_DISPLAY (display));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
{
|
||||
@@ -1308,6 +1385,4 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
display_class->get_setting = gdk_win32_display_get_setting;
|
||||
display_class->set_cursor_theme = gdk_win32_display_set_cursor_theme;
|
||||
display_class->init_gl = gdk_win32_display_init_gl;
|
||||
|
||||
_gdk_win32_surfaceing_init ();
|
||||
}
|
||||
|
@@ -23,13 +23,37 @@
|
||||
|
||||
#include "gdkwin32screen.h"
|
||||
#include "gdkwin32cursor.h"
|
||||
#include "gdkprivate-win32.h"
|
||||
|
||||
#include "gdkglversionprivate.h"
|
||||
|
||||
/* Used for active language or text service change notifications */
|
||||
#define COBJMACROS
|
||||
#include <msctf.h>
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
struct _GdkWin32PointerDeviceItems
|
||||
{
|
||||
/* Input Core items */
|
||||
int input_ignore_core;
|
||||
};
|
||||
|
||||
typedef struct _GdkWin32PointerDeviceItems GdkWin32PointerDeviceItems;
|
||||
|
||||
typedef struct _GdkWin32InputLocaleItems GdkWin32InputLocaleItems;
|
||||
|
||||
struct _GdkWin32CbDnDItems
|
||||
{
|
||||
/* used to identify the main thread for this GdkWin32Display */
|
||||
GThread *display_main_thread;
|
||||
|
||||
GdkWin32Clipdrop *clipdrop;
|
||||
};
|
||||
typedef struct _GdkWin32CbDnDItems GdkWin32CbDnDItems;
|
||||
|
||||
/* Define values used to set DPI-awareness */
|
||||
typedef enum _GdkWin32ProcessDpiAwareness {
|
||||
PROCESS_DPI_UNAWARE = 0,
|
||||
@@ -113,6 +137,52 @@ typedef struct
|
||||
HGLRC hglrc;
|
||||
} GdkWin32GLDummyContextWGL;
|
||||
|
||||
/* for Direct Manipulation support */
|
||||
typedef struct
|
||||
{
|
||||
/* this is an IDirectManipulationManager object */
|
||||
void *manager;
|
||||
|
||||
/* GetPointerType (UINT32 pointerId, POINTER_INPUT_TYPE *pointerType) function pointer */
|
||||
void *getPointerType;
|
||||
} dmanip_items;
|
||||
|
||||
/* for surface tracking items (modal, HWNDs used, etc) */
|
||||
typedef struct
|
||||
{
|
||||
GHashTable *handle_ht;
|
||||
GSList *modal_surface_stack;
|
||||
HWND modal_move_resize_hwnd;
|
||||
|
||||
/* Non-zero while a modal sizing, moving, or dnd operation is in progress */
|
||||
GdkWin32ModalOpKind modal_operation_in_progress;
|
||||
UINT modal_timer;
|
||||
} surface_records;
|
||||
|
||||
/* for tracking various events that go on */
|
||||
typedef struct
|
||||
{
|
||||
/* for tracking various mouse/wintab/winpointer events */
|
||||
GdkSurface *mouse_surface;
|
||||
GdkSurface *mouse_surface_ignored_leave;
|
||||
int current_root_x;
|
||||
int current_root_y;
|
||||
|
||||
int debug_indent_displaychange;
|
||||
int debug_indent_surface_events;
|
||||
|
||||
/* for tracking whether we are using IME */
|
||||
guint in_ime_composition : 1;
|
||||
|
||||
/* to store keycodes for shift keys */
|
||||
int both_shift_pressed[2];
|
||||
|
||||
/* AeroSnap emulation event handling */
|
||||
/* low-level keyboard hook handle */
|
||||
HHOOK aerosnap_keyboard_hook;
|
||||
UINT aerosnap_message;
|
||||
} event_records;
|
||||
|
||||
struct _GdkWin32Display
|
||||
{
|
||||
GdkDisplay display;
|
||||
@@ -125,17 +195,28 @@ struct _GdkWin32Display
|
||||
|
||||
HWND hwnd;
|
||||
|
||||
GListModel *monitors;
|
||||
GdkWin32InputLocaleItems *input_locale_items;
|
||||
GdkWin32PointerDeviceItems *pointer_device_items;
|
||||
GdkWin32CbDnDItems *cb_dnd_items;
|
||||
GdkDeviceManagerWin32 *device_manager;
|
||||
surface_records *display_surface_record;
|
||||
event_records *event_record;
|
||||
|
||||
dmanip_items *dmanip_items;
|
||||
|
||||
/* WGL/OpenGL Items */
|
||||
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
||||
|
||||
GListModel *monitors;
|
||||
|
||||
guint hasWglARBCreateContext : 1;
|
||||
guint hasWglEXTSwapControl : 1;
|
||||
guint hasWglOMLSyncControl : 1;
|
||||
guint hasWglARBPixelFormat : 1;
|
||||
guint hasGlWINSwapHint : 1;
|
||||
guint wgl_support_gdi : 1;
|
||||
|
||||
struct wgl_quirks {
|
||||
guint force_gdi_compatibility : 1;
|
||||
guint disallow_swap_exchange : 1;
|
||||
} *wgl_quirks;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
guint hasEglKHRCreateContext : 1;
|
||||
@@ -184,9 +265,11 @@ GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
|
||||
|
||||
void gdk_win32_display_check_composited (GdkWin32Display *display);
|
||||
|
||||
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
GdkSurface *surface,
|
||||
HMONITOR hmonitor);
|
||||
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
GdkSurface *surface,
|
||||
HMONITOR hmonitor);
|
||||
|
||||
GdkWin32Clipdrop *gdk_win32_display_get_clipdrop (GdkDisplay *display);
|
||||
|
||||
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
|
||||
|
||||
|
@@ -217,8 +217,8 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
/* Just to avoid calling RegisterWindowMessage() every time */
|
||||
static UINT thread_wakeup_message;
|
||||
/* accessors to thread data structs in GdkWin32Clipdrop/GdkWin32Drag */
|
||||
#define OBJECT_DND_THREAD_MEMBER(o,m) ((GdkWin32DnDThread *)(o->dnd_thread_items))->m
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -362,27 +362,22 @@ struct _GdkWin32DnDThread
|
||||
data_object *src_object;
|
||||
};
|
||||
|
||||
/* The code is much more secure if we don't rely on the OS to keep
|
||||
* this around for us.
|
||||
*/
|
||||
static GdkWin32DnDThread *dnd_thread_data = NULL;
|
||||
|
||||
static gboolean
|
||||
dnd_queue_is_empty ()
|
||||
dnd_queue_is_empty (GdkDisplay *display)
|
||||
{
|
||||
return g_atomic_int_get (&_win32_clipdrop->dnd_queue_counter) == 0;
|
||||
return g_atomic_int_get (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter)) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
decrement_dnd_queue_counter ()
|
||||
decrement_dnd_queue_counter (GdkDisplay *display)
|
||||
{
|
||||
g_atomic_int_dec_and_test (&_win32_clipdrop->dnd_queue_counter);
|
||||
g_atomic_int_dec_and_test (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter));
|
||||
}
|
||||
|
||||
static void
|
||||
increment_dnd_queue_counter ()
|
||||
increment_dnd_queue_counter (GdkDisplay *display)
|
||||
{
|
||||
g_atomic_int_inc (&_win32_clipdrop->dnd_queue_counter);
|
||||
g_atomic_int_inc (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -427,13 +422,15 @@ free_queue_item (GdkWin32DnDThreadQueueItem *item)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_dnd_queue (gboolean timed,
|
||||
process_dnd_queue (GdkDrag *drag,
|
||||
gboolean timed,
|
||||
guint64 end_time,
|
||||
GdkWin32DnDThreadGetData *getdata_check)
|
||||
{
|
||||
GdkWin32DnDThreadQueueItem *item;
|
||||
GdkWin32DnDThreadUpdateDragState *updatestate;
|
||||
GdkWin32DnDThreadDoDragDrop *ddd;
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
@@ -444,17 +441,17 @@ process_dnd_queue (gboolean timed,
|
||||
if (current_time >= end_time)
|
||||
break;
|
||||
|
||||
item = g_async_queue_timeout_pop (dnd_thread_data->input_queue, end_time - current_time);
|
||||
item = g_async_queue_timeout_pop (OBJECT_DND_THREAD_MEMBER (drag_win32, input_queue), end_time - current_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
item = g_async_queue_try_pop (dnd_thread_data->input_queue);
|
||||
item = g_async_queue_try_pop (OBJECT_DND_THREAD_MEMBER (drag_win32, input_queue));
|
||||
}
|
||||
|
||||
if (item == NULL)
|
||||
break;
|
||||
|
||||
decrement_dnd_queue_counter ();
|
||||
decrement_dnd_queue_counter (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
|
||||
switch (item->item_type)
|
||||
{
|
||||
@@ -490,7 +487,7 @@ do_drag_drop_response (gpointer user_data)
|
||||
HRESULT hr = ddd->received_result;
|
||||
GdkDrag *drag = GDK_DRAG (ddd->base.opaque_context);
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
gpointer table_value = g_hash_table_lookup (clipdrop->active_source_drags, drag);
|
||||
|
||||
if (ddd == table_value)
|
||||
@@ -546,7 +543,7 @@ received_drag_context_data (GObject *drag,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkWin32DnDThreadGetData *getdata = (GdkWin32DnDThreadGetData *) user_data;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
|
||||
|
||||
if (!gdk_drag_write_finish (GDK_DRAG (drag), result, &error))
|
||||
{
|
||||
@@ -571,17 +568,17 @@ received_drag_context_data (GObject *drag,
|
||||
}
|
||||
|
||||
g_clear_object (&getdata->stream);
|
||||
increment_dnd_queue_counter ();
|
||||
increment_dnd_queue_counter (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
|
||||
g_async_queue_push (clipdrop->dnd_queue, getdata);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_data_response (gpointer user_data)
|
||||
{
|
||||
GdkWin32DnDThreadGetData *getdata = (GdkWin32DnDThreadGetData *) user_data;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkDrag *drag = GDK_DRAG (getdata->base.opaque_context);
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (getdata->base.opaque_context)->drag_surface));
|
||||
gpointer ddd = g_hash_table_lookup (clipdrop->active_source_drags, drag);
|
||||
|
||||
GDK_NOTE (DND, g_print ("idataobject_getdata will request target 0x%p (%s)",
|
||||
@@ -593,7 +590,7 @@ get_data_response (gpointer user_data)
|
||||
if (ddd)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GOutputStream *stream = gdk_win32_hdata_output_stream_new (&getdata->pair, &error);
|
||||
GOutputStream *stream = gdk_win32_hdata_output_stream_new (clipdrop, &getdata->pair, &error);
|
||||
|
||||
if (stream)
|
||||
{
|
||||
@@ -610,9 +607,9 @@ get_data_response (gpointer user_data)
|
||||
}
|
||||
}
|
||||
|
||||
increment_dnd_queue_counter ();
|
||||
increment_dnd_queue_counter (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
|
||||
g_async_queue_push (clipdrop->dnd_queue, getdata);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -622,11 +619,13 @@ do_drag_drop (GdkWin32DnDThreadDoDragDrop *ddd)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
dnd_thread_data->src_object = ddd->src_object;
|
||||
dnd_thread_data->src_context = ddd->src_context;
|
||||
GdkWin32Drag *drag = ddd->base.opaque_context;
|
||||
|
||||
hr = DoDragDrop (&dnd_thread_data->src_object->ido,
|
||||
&dnd_thread_data->src_context->ids,
|
||||
OBJECT_DND_THREAD_MEMBER (drag, src_object) = ddd->src_object;
|
||||
OBJECT_DND_THREAD_MEMBER (drag, src_context) = ddd->src_context;
|
||||
|
||||
hr = DoDragDrop (&OBJECT_DND_THREAD_MEMBER (drag, src_object->ido),
|
||||
&OBJECT_DND_THREAD_MEMBER (drag, src_context->ids),
|
||||
ddd->allowed_drop_effects,
|
||||
&ddd->received_drop_effect);
|
||||
|
||||
@@ -638,15 +637,18 @@ do_drag_drop (GdkWin32DnDThreadDoDragDrop *ddd)
|
||||
gpointer
|
||||
_gdk_win32_dnd_thread_main (gpointer data)
|
||||
{
|
||||
GAsyncQueue *queue = (GAsyncQueue *) data;
|
||||
|
||||
clipdrop_thread_items *clipdrop_items = (clipdrop_thread_items *) data;
|
||||
GAsyncQueue *queue = clipdrop_items->queue;
|
||||
GdkWin32Clipdrop *clipdrop = clipdrop_items->clipdrop;
|
||||
GdkWin32DnDThreadQueueItem *item;
|
||||
MSG msg;
|
||||
HRESULT hr;
|
||||
|
||||
g_assert (dnd_thread_data == NULL);
|
||||
g_assert (clipdrop->dnd_thread_items == NULL);
|
||||
|
||||
dnd_thread_data = g_new0 (GdkWin32DnDThread, 1);
|
||||
dnd_thread_data->input_queue = queue;
|
||||
clipdrop->dnd_thread_items = g_new0 (GdkWin32DnDThread, 1);
|
||||
OBJECT_DND_THREAD_MEMBER (clipdrop, input_queue) = queue;
|
||||
|
||||
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
@@ -658,8 +660,6 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
/* Create a message queue */
|
||||
PeekMessage (&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
|
||||
|
||||
thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
|
||||
|
||||
/* Signal the main thread that we're ready.
|
||||
* This is the only time the queue works in reverse.
|
||||
*/
|
||||
@@ -667,11 +667,13 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
|
||||
while (GetMessage (&msg, NULL, 0, 0))
|
||||
{
|
||||
if (!dnd_queue_is_empty ())
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
|
||||
if (!dnd_queue_is_empty (display))
|
||||
{
|
||||
while ((item = g_async_queue_try_pop (queue)) != NULL)
|
||||
{
|
||||
decrement_dnd_queue_counter ();
|
||||
decrement_dnd_queue_counter (display);
|
||||
|
||||
if (item->item_type != GDK_WIN32_DND_THREAD_QUEUE_ITEM_DO_DRAG_DROP)
|
||||
{
|
||||
@@ -680,7 +682,7 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
}
|
||||
|
||||
do_drag_drop ((GdkWin32DnDThreadDoDragDrop *) item);
|
||||
API_CALL (PostThreadMessage, (GetCurrentThreadId (), thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (GetCurrentThreadId (), clipdrop->thread_wakeup_message, 0, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -691,7 +693,8 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
}
|
||||
|
||||
g_async_queue_unref (queue);
|
||||
g_clear_pointer (&dnd_thread_data, g_free);
|
||||
|
||||
g_clear_pointer (&clipdrop->dnd_thread_items, g_free);
|
||||
|
||||
OleUninitialize ();
|
||||
CoUninitialize ();
|
||||
@@ -703,6 +706,25 @@ static gboolean drag_context_grab (GdkDrag *drag);
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32Drag, gdk_win32_drag, GDK_TYPE_DRAG)
|
||||
|
||||
static gboolean
|
||||
check_drag_display_thread_status (GdkDrag *drag,
|
||||
gboolean is_self)
|
||||
{
|
||||
GdkDisplay *display = gdk_drag_get_display (drag);
|
||||
GThread *current_thread, *display_thread;
|
||||
|
||||
if (display == NULL)
|
||||
return TRUE;
|
||||
|
||||
current_thread = g_thread_self ();
|
||||
display_thread = GDK_WIN32_DISPLAY (display)->cb_dnd_items->display_main_thread;
|
||||
|
||||
if (display_thread == NULL)
|
||||
return TRUE;
|
||||
|
||||
return is_self ? display_thread == current_thread : display_thread != current_thread;
|
||||
}
|
||||
|
||||
static void
|
||||
move_drag_surface (GdkDrag *drag,
|
||||
guint x_root,
|
||||
@@ -710,8 +732,7 @@ move_drag_surface (GdkDrag *drag,
|
||||
{
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
g_assert (check_drag_display_thread_status (drag, TRUE));
|
||||
|
||||
gdk_win32_surface_move (drag_win32->drag_surface,
|
||||
x_root - drag_win32->hot_x,
|
||||
@@ -722,8 +743,7 @@ move_drag_surface (GdkDrag *drag,
|
||||
static void
|
||||
gdk_win32_drag_init (GdkWin32Drag *drag)
|
||||
{
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
g_assert (check_drag_display_thread_status (GDK_DRAG (drag), TRUE));
|
||||
|
||||
drag->handle_events = TRUE;
|
||||
drag->dest_hwnd = INVALID_HANDLE_VALUE;
|
||||
@@ -738,14 +758,14 @@ gdk_win32_drag_finalize (GObject *object)
|
||||
GdkWin32Drag *drag_win32;
|
||||
GdkSurface *drag_surface;
|
||||
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
|
||||
GDK_NOTE (DND, g_print ("gdk_win32_drag_finalize %p\n", object));
|
||||
|
||||
g_return_if_fail (GDK_IS_WIN32_DRAG (object));
|
||||
|
||||
drag = GDK_DRAG (object);
|
||||
|
||||
g_assert (check_drag_display_thread_status (drag, TRUE));
|
||||
|
||||
drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
|
||||
gdk_drag_set_cursor (drag, NULL);
|
||||
@@ -786,6 +806,8 @@ gdk_drag_new (GdkDisplay *display,
|
||||
else
|
||||
drag_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
|
||||
drag_win32->dnd_thread_items = display_win32->cb_dnd_items->clipdrop->dnd_thread_items;
|
||||
|
||||
return drag;
|
||||
}
|
||||
|
||||
@@ -810,17 +832,17 @@ static enum_formats *enum_formats_new (GArray *formats);
|
||||
* Does not give a reference.
|
||||
*/
|
||||
GdkDrag *
|
||||
_gdk_win32_find_drag_for_dest_hwnd (HWND dest_hwnd)
|
||||
gdk_win32_find_drag_for_dest_surface (GdkSurface *surface)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GdkWin32Drag *drag_win32;
|
||||
GdkWin32DnDThreadDoDragDrop *ddd;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (surface));
|
||||
|
||||
g_hash_table_iter_init (&iter, clipdrop->active_source_drags);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &drag_win32, (gpointer *) &ddd))
|
||||
if (ddd->src_context->dest_window_handle == dest_hwnd)
|
||||
if (ddd->src_context->dest_window_handle == GDK_SURFACE_HWND (surface))
|
||||
return GDK_DRAG (drag_win32);
|
||||
|
||||
return NULL;
|
||||
@@ -897,8 +919,8 @@ idropsourcenotify_dragentertarget (IDropSourceNotify *This,
|
||||
source_drag_context *ctx = (source_drag_context *) (((char *) This) - G_STRUCT_OFFSET (source_drag_context, idsn));
|
||||
GdkWin32DnDEnterLeaveNotify *notify;
|
||||
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsourcenotify_dragentertarget %p (SDC %p) 0x%p\n", This, ctx, hwndTarget));
|
||||
|
||||
@@ -918,8 +940,8 @@ idropsourcenotify_dragleavetarget (IDropSourceNotify *This)
|
||||
source_drag_context *ctx = (source_drag_context *) (((char *) This) - G_STRUCT_OFFSET (source_drag_context, idsn));
|
||||
GdkWin32DnDEnterLeaveNotify *notify;
|
||||
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsourcenotify_dragleavetarget %p (SDC %p) 0x%p\n", This, ctx, ctx->dest_window_handle));
|
||||
|
||||
@@ -1020,8 +1042,8 @@ idropsource_querycontinuedrag (LPDROPSOURCE This,
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag %p esc=%d keystate=0x%lx with state %d\n", This, fEscapePressed, grfKeyState, ctx->util_data.state));
|
||||
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag state %d\n", ctx->util_data.state));
|
||||
|
||||
@@ -1057,14 +1079,13 @@ static gboolean
|
||||
give_feedback (gpointer user_data)
|
||||
{
|
||||
GdkWin32DnDThreadGiveFeedback *feedback = (GdkWin32DnDThreadGiveFeedback *) user_data;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkDrag *drag = GDK_DRAG (feedback->base.opaque_context);
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
gpointer ddd = g_hash_table_lookup (clipdrop->active_source_drags, feedback->base.opaque_context);
|
||||
|
||||
if (ddd)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (feedback->base.opaque_context);
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
|
||||
GDK_NOTE (DND, g_print ("gdk_dnd_handle_drag_status: 0x%p\n",
|
||||
drag));
|
||||
|
||||
@@ -1085,8 +1106,8 @@ idropsource_givefeedback (LPDROPSOURCE This,
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsource_givefeedback %p with drop effect %lu S_OK\n", This, dwEffect));
|
||||
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
|
||||
feedback = g_new0 (GdkWin32DnDThreadGiveFeedback, 1);
|
||||
feedback->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_GIVE_FEEDBACK;
|
||||
@@ -1224,8 +1245,8 @@ idataobject_getdata (LPDATAOBJECT This,
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
|
||||
getdata = g_new0 (GdkWin32DnDThreadGetData, 1);
|
||||
getdata->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_GET_DATA;
|
||||
@@ -1233,7 +1254,7 @@ idataobject_getdata (LPDATAOBJECT This,
|
||||
getdata->pair = *pair;
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, get_data_response, getdata, NULL);
|
||||
|
||||
if (!process_dnd_queue (TRUE, g_get_monotonic_time () + G_USEC_PER_SEC * 30, getdata))
|
||||
if (!process_dnd_queue (ctx->drag, TRUE, g_get_monotonic_time () + G_USEC_PER_SEC * 30, getdata))
|
||||
return E_FAIL;
|
||||
|
||||
if (getdata->produced_data_medium.tymed == TYMED_NULL)
|
||||
@@ -1269,8 +1290,9 @@ idataobject_querygetdata (LPDATAOBJECT This,
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread != g_thread_self ());
|
||||
data_object *ctx = (data_object *) This;
|
||||
|
||||
g_assert (check_drag_display_thread_status (ctx->drag, FALSE));
|
||||
|
||||
hr = query (This, pFormatEtc, NULL);
|
||||
|
||||
@@ -1309,8 +1331,9 @@ idataobject_enumformatetc (LPDATAOBJECT This,
|
||||
DWORD dwDirection,
|
||||
LPENUMFORMATETC *ppEnumFormatEtc)
|
||||
{
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread != g_thread_self ());
|
||||
data_object *ctx = (data_object *) This;
|
||||
|
||||
g_assert (check_drag_display_thread_status (ctx->drag, FALSE));
|
||||
|
||||
if (dwDirection != DATADIR_GET)
|
||||
{
|
||||
@@ -1598,7 +1621,9 @@ data_object_new (GdkDrag *drag)
|
||||
|
||||
GDK_NOTE (DND, g_print ("DataObject supports contentformat 0x%p (%s)\n", mime_types[i], mime_types[i]));
|
||||
|
||||
added_count = _gdk_win32_add_contentformat_to_pairs (mime_types[i], result->formats);
|
||||
added_count = _gdk_win32_add_contentformat_to_pairs (gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface)),
|
||||
mime_types[i],
|
||||
result->formats);
|
||||
|
||||
for (j = 0; j < added_count && result->formats->len - 1 - j >= 0; j++)
|
||||
GDK_NOTE (DND, g_print ("DataObject will support w32format 0x%x\n", g_array_index (result->formats, GdkWin32ContentFormatPair, j).w32format));
|
||||
@@ -1654,7 +1679,7 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
|
||||
{
|
||||
GdkDrag *drag;
|
||||
GdkWin32Drag *drag_win32;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (surface));
|
||||
double px, py;
|
||||
int x_root, y_root;
|
||||
GdkWin32DnDThreadDoDragDrop *ddd;
|
||||
@@ -1709,9 +1734,9 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
|
||||
ddd->allowed_drop_effects |= DROPEFFECT_LINK;
|
||||
|
||||
g_hash_table_replace (clipdrop->active_source_drags, g_object_ref (drag), ddd);
|
||||
increment_dnd_queue_counter ();
|
||||
increment_dnd_queue_counter (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
g_async_queue_push (clipdrop->dnd_queue, ddd);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
|
||||
drag_win32->util_data.state = GDK_WIN32_DND_PENDING;
|
||||
|
||||
@@ -1750,9 +1775,9 @@ send_source_state_update (GdkWin32Clipdrop *clipdrop,
|
||||
status->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_UPDATE_DRAG_STATE;
|
||||
status->opaque_ddd = ddd;
|
||||
status->produced_util_data = drag_win32->util_data;
|
||||
increment_dnd_queue_counter ();
|
||||
increment_dnd_queue_counter (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
g_async_queue_push (clipdrop->dnd_queue, status);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1760,11 +1785,10 @@ gdk_win32_drag_drop (GdkDrag *drag,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
gpointer ddd;
|
||||
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
g_assert (check_drag_display_thread_status (drag, TRUE));
|
||||
|
||||
g_return_if_fail (drag != NULL);
|
||||
|
||||
@@ -1876,7 +1900,7 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
|
||||
/* FIXME: This is temporary, until the code is fixed to ensure that
|
||||
* gdk_drag_finish () is called by GTK.
|
||||
*/
|
||||
clipdrop = _gdk_win32_clipdrop_get ();
|
||||
clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
ddd = g_hash_table_lookup (clipdrop->active_source_drags, drag);
|
||||
|
||||
if (success)
|
||||
@@ -2034,7 +2058,7 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
|
||||
key_state = manufacture_keystate_from_GMT (state);
|
||||
|
||||
clipdrop = _gdk_win32_clipdrop_get ();
|
||||
clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (event->surface));
|
||||
|
||||
GDK_NOTE (DND, g_print ("Post WM_MOUSEMOVE keystate=%lu\n", key_state));
|
||||
|
||||
|
@@ -269,7 +269,8 @@ idroptarget_release (LPDROPTARGET This)
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
query_object_formats (LPDATAOBJECT pDataObj,
|
||||
query_object_formats (GdkDisplay *display,
|
||||
LPDATAOBJECT pDataObj,
|
||||
GArray *w32format_contentformat_map)
|
||||
{
|
||||
IEnumFORMATETC *pfmt = NULL;
|
||||
@@ -298,7 +299,7 @@ query_object_formats (LPDATAOBJECT pDataObj,
|
||||
GDK_NOTE (DND, g_print ("supported unnamed? source format 0x%x\n", fmt.cfFormat));
|
||||
|
||||
g_free (registered_name);
|
||||
_gdk_win32_add_w32format_to_pairs (fmt.cfFormat, w32format_contentformat_map, builder);
|
||||
gdk_win32_clipdrop_add_win32_format_to_pairs (gdk_win32_display_get_clipdrop (display), fmt.cfFormat, w32format_contentformat_map, builder);
|
||||
hr = IEnumFORMATETC_Next (pfmt, 1, &fmt, NULL);
|
||||
}
|
||||
|
||||
@@ -490,12 +491,12 @@ idroptarget_dragenter (LPDROPTARGET This,
|
||||
drag = NULL;
|
||||
|
||||
if (ctx->surface)
|
||||
drag = _gdk_win32_find_drag_for_dest_hwnd (GDK_SURFACE_HWND (ctx->surface));
|
||||
drag = gdk_win32_find_drag_for_dest_surface (ctx->surface);
|
||||
|
||||
display = gdk_surface_get_display (ctx->surface);
|
||||
|
||||
droptarget_w32format_contentformat_map = g_array_new (FALSE, FALSE, sizeof (GdkWin32ContentFormatPair));
|
||||
formats = query_object_formats (pDataObj, droptarget_w32format_contentformat_map);
|
||||
formats = query_object_formats (display, pDataObj, droptarget_w32format_contentformat_map);
|
||||
drop = gdk_drop_new (display,
|
||||
gdk_seat_get_pointer (gdk_display_get_default_seat (display)),
|
||||
drag,
|
||||
@@ -1110,7 +1111,12 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_win32_transmute_windows_data (pair->w32format, pair->contentformat, storage.hGlobal, &data, &data_len);
|
||||
GdkDisplay *display = gdk_drop_get_display (drop);
|
||||
gdk_win32_clipdrop_transmute_windows_data (gdk_win32_display_get_clipdrop (display),
|
||||
pair->w32format, pair->contentformat,
|
||||
storage.hGlobal,
|
||||
&data,
|
||||
&data_len);
|
||||
}
|
||||
|
||||
ReleaseStgMedium (&storage);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -270,17 +270,20 @@ attribs_fini (attribs_t *attribs)
|
||||
#define attribs_add_static_array(attribs, array) \
|
||||
do attribs_add_bulk (attribs, array, G_N_ELEMENTS (array)); while (0)
|
||||
|
||||
static int
|
||||
find_pixel_format_with_defined_swap_flag (HDC hdc,
|
||||
int formats[],
|
||||
UINT count)
|
||||
static bool
|
||||
find_pixel_format_with_defined_swap_method (HDC hdc,
|
||||
int formats[],
|
||||
UINT count,
|
||||
UINT *index,
|
||||
int *swap_method)
|
||||
{
|
||||
SetLastError (0);
|
||||
|
||||
for (UINT i = 0; i < count; i++)
|
||||
{
|
||||
int query = WGL_SWAP_METHOD_ARB;
|
||||
int value = WGL_SWAP_UNDEFINED_ARB;
|
||||
|
||||
SetLastError (0);
|
||||
if (!wglGetPixelFormatAttribivARB (hdc, formats[i], 0, 1, &query, &value))
|
||||
{
|
||||
WIN32_API_FAILED ("wglGetPixelFormatAttribivARB");
|
||||
@@ -288,10 +291,15 @@ find_pixel_format_with_defined_swap_flag (HDC hdc,
|
||||
}
|
||||
|
||||
if (value != WGL_SWAP_UNDEFINED_ARB)
|
||||
return formats[i];
|
||||
{
|
||||
*index = i;
|
||||
*swap_method = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -337,6 +345,8 @@ choose_pixel_format_arb_attribs (GdkWin32Display *display_win32,
|
||||
UINT count = 0;
|
||||
int format = 0;
|
||||
int saved = 0;
|
||||
UINT index = 0;
|
||||
int swap_method = WGL_SWAP_UNDEFINED_ARB;
|
||||
|
||||
#define EXT_CALL(api, args) \
|
||||
do { \
|
||||
@@ -357,7 +367,7 @@ choose_pixel_format_arb_attribs (GdkWin32Display *display_win32,
|
||||
|
||||
attribs_add_static_array (&attribs, attribs_base);
|
||||
|
||||
if (display_win32->wgl_support_gdi)
|
||||
if (display_win32->wgl_quirks->force_gdi_compatibility)
|
||||
attribs_add (&attribs, WGL_SUPPORT_GDI_ARB, GL_TRUE);
|
||||
|
||||
attribs_commit (&attribs);
|
||||
@@ -383,26 +393,40 @@ choose_pixel_format_arb_attribs (GdkWin32Display *display_win32,
|
||||
|
||||
/* Do we have a defined swap method? */
|
||||
|
||||
format = find_pixel_format_with_defined_swap_flag (hdc, formats, count);
|
||||
if (format > 0)
|
||||
goto done;
|
||||
if (find_pixel_format_with_defined_swap_method (hdc, formats, count, &index, &swap_method))
|
||||
{
|
||||
if (!display_win32->wgl_quirks->disallow_swap_exchange || swap_method != WGL_SWAP_EXCHANGE_ARB)
|
||||
{
|
||||
format = formats[index];
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nope, but we can try to ask for it explicitly */
|
||||
|
||||
const int swap_methods[] = {
|
||||
WGL_SWAP_EXCHANGE_ARB,
|
||||
const int swap_methods[] =
|
||||
{
|
||||
(display_win32->wgl_quirks->disallow_swap_exchange) ? 0 : WGL_SWAP_EXCHANGE_ARB,
|
||||
WGL_SWAP_COPY_ARB,
|
||||
};
|
||||
for (size_t i = 0; i < G_N_ELEMENTS (swap_methods); i++)
|
||||
{
|
||||
if (swap_methods[i] == 0)
|
||||
continue;
|
||||
|
||||
attribs_add (&attribs, WGL_SWAP_METHOD_ARB, swap_methods[i]);
|
||||
|
||||
EXT_CALL (wglChoosePixelFormatARB, (hdc, attribs_data (&attribs), NULL,
|
||||
G_N_ELEMENTS (formats), formats,
|
||||
&count));
|
||||
format = find_pixel_format_with_defined_swap_flag (hdc, formats, count);
|
||||
if (format > 0)
|
||||
goto done;
|
||||
if (find_pixel_format_with_defined_swap_method (hdc, formats, count, &index, &swap_method))
|
||||
{
|
||||
if (!display_win32->wgl_quirks->disallow_swap_exchange || swap_method != WGL_SWAP_EXCHANGE_ARB)
|
||||
{
|
||||
format = formats[index];
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
attribs_reset (&attribs);
|
||||
}
|
||||
@@ -420,10 +444,9 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
get_distance (PIXELFORMATDESCRIPTOR *pfd)
|
||||
get_distance (PIXELFORMATDESCRIPTOR *pfd,
|
||||
DWORD swap_flags)
|
||||
{
|
||||
const DWORD swap_flags = PFD_SWAP_COPY | PFD_SWAP_EXCHANGE;
|
||||
|
||||
int is_double_buffered = (pfd->dwFlags & PFD_DOUBLEBUFFER) != 0;
|
||||
int is_swap_defined = (pfd->dwFlags & swap_flags) != 0;
|
||||
int is_mono = (pfd->dwFlags & PFD_STEREO) == 0;
|
||||
@@ -438,7 +461,7 @@ get_distance (PIXELFORMATDESCRIPTOR *pfd)
|
||||
memory_distance;
|
||||
}
|
||||
|
||||
/* ChoosePixelFormat ignored some fields and flags, which makes it
|
||||
/* ChoosePixelFormat ignores some fields and flags, which makes it
|
||||
* less useful for GTK. In particular, it ignores the PFD_SWAP flags,
|
||||
* which are very important for GUI toolkits. Here we implement an
|
||||
* analog function which is tied to the needs of GTK.
|
||||
@@ -455,7 +478,9 @@ choose_pixel_format_opengl32 (GdkWin32Display *display_win32,
|
||||
PFD_GENERIC_ACCELERATED;
|
||||
const DWORD required_flags = PFD_DRAW_TO_WINDOW |
|
||||
PFD_SUPPORT_OPENGL |
|
||||
(display_win32->wgl_support_gdi ? PFD_SUPPORT_GDI : 0);
|
||||
(display_win32->wgl_quirks->force_gdi_compatibility ? PFD_SUPPORT_GDI : 0);
|
||||
const DWORD best_swap_flags = PFD_SWAP_COPY |
|
||||
(display_win32->wgl_quirks->disallow_swap_exchange ? 0 : PFD_SWAP_EXCHANGE);
|
||||
|
||||
struct {
|
||||
int index;
|
||||
@@ -481,7 +506,7 @@ choose_pixel_format_opengl32 (GdkWin32Display *display_win32,
|
||||
pfd.cBlueBits != 8 || pfd.cAlphaBits != 8))
|
||||
continue;
|
||||
|
||||
current.distance = get_distance (&pfd);
|
||||
current.distance = get_distance (&pfd, best_swap_flags);
|
||||
|
||||
if (best.index == 0 || current.distance < best.distance)
|
||||
best = current;
|
||||
@@ -606,6 +631,14 @@ check_driver_is_d3d12 (void)
|
||||
g_ascii_strncasecmp (renderer, "D3D12", strlen ("D3D12")) == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_vendor_is_nvidia (void)
|
||||
{
|
||||
const char *vendor = (const char *) glGetString (GL_VENDOR);
|
||||
|
||||
return g_ascii_strncasecmp (vendor, "NVIDIA", strlen ("NVIDIA")) == 0;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GError **error)
|
||||
@@ -618,6 +651,9 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
|
||||
return NULL;
|
||||
|
||||
g_assert (display_win32->wgl_quirks == NULL);
|
||||
display_win32->wgl_quirks = g_new0 (struct wgl_quirks, 1);
|
||||
|
||||
/* acquire and cache dummy Window (HWND & HDC) and
|
||||
* dummy GL Context, it is used to query functions
|
||||
* and used for other stuff as well
|
||||
@@ -658,7 +694,8 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
display_win32->hasGlWINSwapHint =
|
||||
epoxy_has_gl_extension ("GL_WIN_swap_hint");
|
||||
|
||||
display_win32->wgl_support_gdi = check_driver_is_d3d12();
|
||||
display_win32->wgl_quirks->force_gdi_compatibility = check_driver_is_d3d12 ();
|
||||
display_win32->wgl_quirks->disallow_swap_exchange = check_vendor_is_nvidia ();
|
||||
|
||||
context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
|
||||
"display", display,
|
||||
@@ -677,7 +714,8 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GDK_NOTE (OPENGL, g_print ("WGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
" - Renderer: %s\n"
|
||||
" - GDI compatibility required: %s\n"
|
||||
" - Quirks / force GDI compatiblity: %s\n"
|
||||
" - Quirks / disallow swap exchange: %s\n"
|
||||
" - Checked extensions:\n"
|
||||
"\t* WGL_ARB_pixel_format: %s\n"
|
||||
"\t* WGL_ARB_create_context: %s\n"
|
||||
@@ -687,7 +725,8 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
major, minor,
|
||||
glGetString (GL_VENDOR),
|
||||
glGetString (GL_RENDERER),
|
||||
display_win32->wgl_support_gdi ? "yes" : "no",
|
||||
display_win32->wgl_quirks->force_gdi_compatibility ? "enabled" : "disabled",
|
||||
display_win32->wgl_quirks->disallow_swap_exchange ? "enabled" : "disabled",
|
||||
display_win32->hasWglARBPixelFormat ? "yes" : "no",
|
||||
display_win32->hasWglARBCreateContext ? "yes" : "no",
|
||||
display_win32->hasWglEXTSwapControl ? "yes" : "no",
|
||||
@@ -1095,16 +1134,15 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
{
|
||||
context_wgl->double_buffered = (query_values[0] == GL_TRUE);
|
||||
|
||||
context_wgl->swap_method = SWAP_METHOD_UNDEFINED;
|
||||
switch (query_values[1])
|
||||
{
|
||||
case WGL_SWAP_COPY_ARB:
|
||||
context_wgl->swap_method = SWAP_METHOD_COPY;
|
||||
break;
|
||||
case WGL_SWAP_EXCHANGE_ARB:
|
||||
context_wgl->swap_method = SWAP_METHOD_EXCHANGE;
|
||||
break;
|
||||
default:
|
||||
context_wgl->swap_method = SWAP_METHOD_UNDEFINED;
|
||||
if (!display_win32->wgl_quirks->disallow_swap_exchange)
|
||||
context_wgl->swap_method = SWAP_METHOD_EXCHANGE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1119,7 +1157,7 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
|
||||
if (pfd.dwFlags & PFD_SWAP_COPY)
|
||||
context_wgl->swap_method = SWAP_METHOD_COPY;
|
||||
else if (pfd.dwFlags & PFD_SWAP_EXCHANGE)
|
||||
else if ((pfd.dwFlags & PFD_SWAP_EXCHANGE) && !display_win32->wgl_quirks->disallow_swap_exchange)
|
||||
context_wgl->swap_method = SWAP_METHOD_EXCHANGE;
|
||||
else
|
||||
context_wgl->swap_method = SWAP_METHOD_UNDEFINED;
|
||||
|
@@ -1,44 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 1998-2002 Tor Lillqvist
|
||||
*
|
||||
* This library 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.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gdktypes.h"
|
||||
#include "gdkprivate-win32.h"
|
||||
|
||||
GdkDisplay *_gdk_display = NULL;
|
||||
GdkDeviceManagerWin32 *_gdk_device_manager = NULL;
|
||||
|
||||
int _gdk_input_ignore_core;
|
||||
|
||||
HKL _gdk_input_locale;
|
||||
gboolean _gdk_input_locale_is_ime = FALSE;
|
||||
|
||||
GdkWin32ModalOpKind _modal_operation_in_progress = GDK_WIN32_MODAL_OP_NONE;
|
||||
HWND _modal_move_resize_hwnd = NULL;
|
||||
|
||||
/* The singleton clipdrop object pointer */
|
||||
GdkWin32Clipdrop *_win32_clipdrop = NULL;
|
||||
|
||||
GThread *_win32_main_thread = NULL;
|
@@ -37,6 +37,7 @@ typedef struct _GdkWin32HDataOutputStreamPrivate GdkWin32HDataOutputStreamPriva
|
||||
struct _GdkWin32HDataOutputStreamPrivate
|
||||
{
|
||||
HANDLE handle;
|
||||
GdkWin32Clipdrop *clipdrop;
|
||||
guchar *data;
|
||||
gsize data_allocated_size;
|
||||
gsize data_length;
|
||||
@@ -204,12 +205,13 @@ gdk_win32_hdata_output_stream_close (GOutputStream *output_stream,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gdk_win32_transmute_contentformat (priv->pair.contentformat,
|
||||
priv->pair.w32format,
|
||||
priv->data,
|
||||
priv->data_length,
|
||||
&transmuted_data,
|
||||
&transmuted_data_length))
|
||||
if (!gdk_win32_clipdrop_transmute_contentformat (priv->clipdrop,
|
||||
priv->pair.contentformat,
|
||||
priv->pair.w32format,
|
||||
priv->data,
|
||||
priv->data_length,
|
||||
&transmuted_data,
|
||||
&transmuted_data_length))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("Failed to transmute %zu bytes of data from %s to %u"),
|
||||
@@ -343,7 +345,8 @@ gdk_win32_hdata_output_stream_init (GdkWin32HDataOutputStream *stream)
|
||||
}
|
||||
|
||||
GOutputStream *
|
||||
gdk_win32_hdata_output_stream_new (GdkWin32ContentFormatPair *pair,
|
||||
gdk_win32_hdata_output_stream_new (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ContentFormatPair *pair,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32HDataOutputStream *stream;
|
||||
@@ -369,6 +372,7 @@ gdk_win32_hdata_output_stream_new (GdkWin32ContentFormatPair *pair,
|
||||
|
||||
stream = g_object_new (GDK_TYPE_WIN32_HDATA_OUTPUT_STREAM, NULL);
|
||||
priv = gdk_win32_hdata_output_stream_get_instance_private (stream);
|
||||
priv->clipdrop = clipdrop;
|
||||
priv->pair = *pair;
|
||||
|
||||
if (hmem)
|
||||
|
@@ -51,7 +51,8 @@ struct GdkWin32HDataOutputStreamClass
|
||||
|
||||
GType gdk_win32_hdata_output_stream_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GOutputStream *gdk_win32_hdata_output_stream_new (GdkWin32ContentFormatPair *pair,
|
||||
GOutputStream *gdk_win32_hdata_output_stream_new (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ContentFormatPair *pair,
|
||||
GError **error);
|
||||
|
||||
HANDLE gdk_win32_hdata_output_stream_get_handle (GdkWin32HDataOutputStream *stream,
|
||||
|
@@ -37,7 +37,7 @@
|
||||
#include "gdkdevicemanager-win32.h"
|
||||
#include "gdkdevice-virtual.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
#include "gdkinput-dmanipulation.h"
|
||||
@@ -48,9 +48,6 @@
|
||||
|
||||
typedef BOOL
|
||||
(WINAPI *getPointerType_t)(UINT32 pointerId, POINTER_INPUT_TYPE *pointerType);
|
||||
static getPointerType_t getPointerType;
|
||||
|
||||
static IDirectManipulationManager *dmanipulation_manager;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -203,12 +200,13 @@ DManipEventHandler_OnContentUpdated (IDirectManipulationViewportEventHandler *se
|
||||
POINT cursor = {0, 0};
|
||||
float scale;
|
||||
GdkEvent *event;
|
||||
GdkDisplay *display = gdk_surface_get_display (self->surface);
|
||||
|
||||
scale = transform[0];
|
||||
|
||||
state = util_get_modifier_state ();
|
||||
time = (uint32_t) GetMessageTime ();
|
||||
_gdk_win32_get_cursor_pos (&cursor);
|
||||
_gdk_win32_get_cursor_pos (display, &cursor);
|
||||
|
||||
ScreenToClient (GDK_SURFACE_HWND (self->surface), &cursor);
|
||||
|
||||
@@ -266,13 +264,14 @@ DManipEventHandler_OnViewportStatusChanged (IDirectManipulationViewportEventHand
|
||||
uint32_t time;
|
||||
POINT cursor = {0, 0};
|
||||
GdkEvent *event;
|
||||
GdkDisplay *display = gdk_surface_get_display (self->surface);
|
||||
|
||||
if (self->phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN)
|
||||
break;
|
||||
|
||||
state = util_get_modifier_state ();
|
||||
time = (uint32_t) GetMessageTime ();
|
||||
_gdk_win32_get_cursor_pos (&cursor);
|
||||
_gdk_win32_get_cursor_pos (display, &cursor);
|
||||
|
||||
ScreenToClient (GDK_SURFACE_HWND (self->surface), &cursor);
|
||||
|
||||
@@ -327,7 +326,7 @@ dmanip_event_handler_new (GdkSurface *surface,
|
||||
handler->gesture = gesture;
|
||||
|
||||
handler->surface = surface;
|
||||
handler->device = _gdk_device_manager->core_pointer;
|
||||
handler->device = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface))->device_manager->core_pointer;
|
||||
|
||||
dmanip_event_handler_running_state_clear (handler);
|
||||
|
||||
@@ -378,6 +377,28 @@ close_viewport (IDirectManipulationViewport **p_viewport)
|
||||
}
|
||||
}
|
||||
|
||||
#define GDK_DISPLAY_GET_DMANIP_MANAGER(d) GDK_WIN32_DISPLAY(d)->dmanip_items != NULL ? \
|
||||
(IDirectManipulationManager *) ((dmanip_items *)(GDK_WIN32_DISPLAY(d)->dmanip_items)->manager) : \
|
||||
NULL
|
||||
|
||||
#define GDK_DISPLAY_GET_GET_POINTER_TYPE(d) GDK_WIN32_DISPLAY(d)->dmanip_items != NULL ? \
|
||||
(getPointerType_t) ((dmanip_items *)(GDK_WIN32_DISPLAY(d)->dmanip_items)->getPointerType) : \
|
||||
NULL
|
||||
|
||||
void
|
||||
gdk_win32_display_close_dmanip_manager (GdkDisplay *display)
|
||||
{
|
||||
if (GDK_WIN32_DISPLAY (display)->dmanip_items != NULL)
|
||||
{
|
||||
IDirectManipulationManager *manager = GDK_DISPLAY_GET_DMANIP_MANAGER (display);
|
||||
|
||||
if (manager != NULL)
|
||||
IUnknown_Release (manager);
|
||||
|
||||
g_clear_pointer (&GDK_WIN32_DISPLAY (display)->dmanip_items, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_viewport (GdkSurface *surface,
|
||||
int gesture,
|
||||
@@ -388,6 +409,7 @@ create_viewport (GdkSurface *surface,
|
||||
IDirectManipulationViewportEventHandler *handler = NULL;
|
||||
DWORD cookie = 0;
|
||||
HRESULT hr;
|
||||
IDirectManipulationManager *dmanipulation_manager = GDK_DISPLAY_GET_DMANIP_MANAGER (gdk_surface_get_display (surface));
|
||||
|
||||
hr = IDirectManipulationManager_CreateViewport (dmanipulation_manager, NULL, hwnd,
|
||||
&IID_IDirectManipulationViewport,
|
||||
@@ -441,11 +463,14 @@ failed:
|
||||
/* {{{ Public */
|
||||
|
||||
|
||||
void gdk_dmanipulation_initialize (void)
|
||||
void gdk_dmanipulation_initialize (GdkWin32Display *display)
|
||||
{
|
||||
if (!getPointerType)
|
||||
if (display->dmanip_items == NULL)
|
||||
{
|
||||
IDirectManipulationManager *dmanipulation_manager;
|
||||
getPointerType_t getPointerType;
|
||||
HMODULE user32_mod;
|
||||
HRESULT hr;
|
||||
|
||||
user32_mod = LoadLibraryW (L"user32.dll");
|
||||
if (!user32_mod)
|
||||
@@ -459,20 +484,22 @@ void gdk_dmanipulation_initialize (void)
|
||||
|
||||
if (!getPointerType)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gdk_win32_ensure_com ())
|
||||
if (!gdk_win32_ensure_com ())
|
||||
return;
|
||||
|
||||
if (dmanipulation_manager == NULL)
|
||||
{
|
||||
HRESULT hr;
|
||||
display->dmanip_items = g_new0 (dmanip_items, 1);
|
||||
display->dmanip_items->getPointerType = getPointerType;
|
||||
|
||||
hr = CoCreateInstance (&CLSID_DirectManipulationManager,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IDirectManipulationManager,
|
||||
(LPVOID*)&dmanipulation_manager);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
display->dmanip_items->manager = dmanipulation_manager;
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
if (hr == REGDB_E_CLASSNOTREG || hr == E_NOINTERFACE);
|
||||
@@ -487,6 +514,7 @@ void gdk_dmanipulation_initialize_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkWin32Surface *surface_win32;
|
||||
HRESULT hr;
|
||||
IDirectManipulationManager *dmanipulation_manager = GDK_DISPLAY_GET_DMANIP_MANAGER (gdk_surface_get_display (surface));
|
||||
|
||||
if (!dmanipulation_manager)
|
||||
return;
|
||||
@@ -508,6 +536,8 @@ void gdk_dmanipulation_finalize_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkWin32Surface *surface_win32 = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
IDirectManipulationManager_Deactivate (GDK_DISPLAY_GET_DMANIP_MANAGER (gdk_surface_get_display (surface)),
|
||||
GDK_SURFACE_HWND (surface));
|
||||
close_viewport (&surface_win32->dmanipulation_viewport_zoom);
|
||||
close_viewport (&surface_win32->dmanipulation_viewport_pan);
|
||||
}
|
||||
@@ -517,6 +547,9 @@ void gdk_dmanipulation_maybe_add_contact (GdkSurface *surface,
|
||||
{
|
||||
POINTER_INPUT_TYPE type = PT_POINTER;
|
||||
UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
IDirectManipulationManager *dmanipulation_manager = GDK_DISPLAY_GET_DMANIP_MANAGER (display);
|
||||
getPointerType_t getPointerType = GDK_DISPLAY_GET_GET_POINTER_TYPE (display);
|
||||
|
||||
if (!dmanipulation_manager)
|
||||
return;
|
||||
|
@@ -20,7 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void gdk_dmanipulation_initialize (void);
|
||||
void gdk_dmanipulation_initialize (GdkWin32Display *display);
|
||||
void gdk_win32_display_close_dmanip_manager (GdkDisplay *display);
|
||||
|
||||
void gdk_dmanipulation_initialize_surface (GdkSurface *surface);
|
||||
void gdk_dmanipulation_finalize_surface (GdkSurface *surface);
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include "gdkdevice-winpointer.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicetoolprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
|
||||
@@ -65,40 +65,44 @@ typedef BOOL
|
||||
typedef BOOL
|
||||
(WINAPI *setWindowFeedbackSetting_t)(HWND hwnd, FEEDBACK_TYPE feedback, DWORD dwFlags, UINT32 size, const VOID *configuration);
|
||||
|
||||
static registerPointerDeviceNotifications_t registerPointerDeviceNotifications;
|
||||
static getPointerDevices_t getPointerDevices;
|
||||
static getPointerDeviceCursors_t getPointerDeviceCursors;
|
||||
static getPointerDeviceRects_t getPointerDeviceRects;
|
||||
static getPointerType_t getPointerType;
|
||||
static getPointerCursorId_t getPointerCursorId;
|
||||
static getPointerPenInfo_t getPointerPenInfo;
|
||||
static getPointerTouchInfo_t getPointerTouchInfo;
|
||||
static getPointerPenInfoHistory_t getPointerPenInfoHistory;
|
||||
static getPointerTouchInfoHistory_t getPointerTouchInfoHistory;
|
||||
static setGestureConfig_t setGestureConfig;
|
||||
static setWindowFeedbackSetting_t setWindowFeedbackSetting;
|
||||
struct _GdkDeviceManagerWin32WinpointerFuncs
|
||||
{
|
||||
registerPointerDeviceNotifications_t registerPointerDeviceNotifications;
|
||||
getPointerDevices_t getPointerDevices;
|
||||
getPointerDeviceCursors_t getPointerDeviceCursors;
|
||||
getPointerDeviceRects_t getPointerDeviceRects;
|
||||
getPointerType_t getPointerType;
|
||||
getPointerCursorId_t getPointerCursorId;
|
||||
getPointerPenInfo_t getPointerPenInfo;
|
||||
getPointerTouchInfo_t getPointerTouchInfo;
|
||||
getPointerPenInfoHistory_t getPointerPenInfoHistory;
|
||||
getPointerTouchInfoHistory_t getPointerTouchInfoHistory;
|
||||
setGestureConfig_t setGestureConfig;
|
||||
setWindowFeedbackSetting_t setWindowFeedbackSetting;
|
||||
};
|
||||
typedef struct _GdkDeviceManagerWin32WinpointerFuncs GdkDeviceManagerWin32WinpointerFuncs;
|
||||
|
||||
static ATOM notifications_window_class;
|
||||
static HWND notifications_window_handle;
|
||||
|
||||
static GPtrArray *ignored_interactions;
|
||||
#define WINPOINTER_API(dm,f) ((GdkDeviceManagerWin32WinpointerFuncs *)dm->winpointer_funcs)->f
|
||||
|
||||
static inline void
|
||||
winpointer_ignore_interaction (UINT32 pointer_id)
|
||||
winpointer_ignore_interaction (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT32 pointer_id)
|
||||
{
|
||||
g_ptr_array_add (ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
g_ptr_array_add (device_manager->ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
}
|
||||
|
||||
static inline void
|
||||
winpointer_remove_ignored_interaction (UINT32 pointer_id)
|
||||
winpointer_remove_ignored_interaction (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT32 pointer_id)
|
||||
{
|
||||
g_ptr_array_remove_fast (ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
g_ptr_array_remove_fast (device_manager->ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
winpointer_should_ignore_interaction (UINT32 pointer_id)
|
||||
winpointer_should_ignore_interaction (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT32 pointer_id)
|
||||
{
|
||||
return g_ptr_array_find (ignored_interactions, GUINT_TO_POINTER (pointer_id), NULL);
|
||||
return g_ptr_array_find (device_manager->ignored_interactions, GUINT_TO_POINTER (pointer_id), NULL);
|
||||
}
|
||||
|
||||
static inline guint32
|
||||
@@ -136,11 +140,12 @@ copy_axes (double *axes)
|
||||
}
|
||||
|
||||
static GdkDeviceWinpointer*
|
||||
winpointer_find_device_with_source (HANDLE device_handle,
|
||||
UINT32 cursor_id,
|
||||
GdkInputSource input_source)
|
||||
winpointer_find_device_with_source (GdkDeviceManagerWin32 *device_manager,
|
||||
HANDLE device_handle,
|
||||
UINT32 cursor_id,
|
||||
GdkInputSource input_source)
|
||||
{
|
||||
for (GList *l = _gdk_device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
for (GList *l = device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
{
|
||||
GdkDeviceWinpointer *device = (GdkDeviceWinpointer*) l->data;
|
||||
|
||||
@@ -157,9 +162,10 @@ winpointer_find_device_with_source (HANDLE device_handle,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_get_event_type (MSG *msg,
|
||||
POINTER_INFO *info,
|
||||
GdkEventType *evt_type)
|
||||
winpointer_get_event_type (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg,
|
||||
POINTER_INFO *info,
|
||||
GdkEventType *evt_type)
|
||||
{
|
||||
switch (info->pointerType)
|
||||
{
|
||||
@@ -189,7 +195,7 @@ winpointer_get_event_type (MSG *msg,
|
||||
if (IS_POINTER_CANCELED_WPARAM (msg->wParam) ||
|
||||
!HAS_POINTER_CONFIDENCE_WPARAM (msg->wParam))
|
||||
{
|
||||
winpointer_ignore_interaction (GET_POINTERID_WPARAM (msg->wParam));
|
||||
winpointer_ignore_interaction (device_manager, GET_POINTERID_WPARAM (msg->wParam));
|
||||
|
||||
if (((info->pointerFlags & POINTER_FLAG_INCONTACT) &&
|
||||
(info->pointerFlags & POINTER_FLAG_UPDATE)) ||
|
||||
@@ -249,10 +255,11 @@ winpointer_make_event (GdkDeviceWinpointer *device,
|
||||
GdkEventType evt_type;
|
||||
GdkEvent *evt = NULL;
|
||||
GdkDevice *core_device = NULL;
|
||||
GdkDeviceManagerWin32 *device_manager = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface))->device_manager;
|
||||
|
||||
core_device = _gdk_device_manager->core_pointer;
|
||||
core_device = device_manager->core_pointer;
|
||||
|
||||
if (!winpointer_get_event_type (msg, info, &evt_type))
|
||||
if (!winpointer_get_event_type (device_manager, msg, info, &evt_type))
|
||||
return;
|
||||
|
||||
time = winpointer_get_time (msg, info);
|
||||
@@ -399,14 +406,16 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
|
||||
POINTER_INPUT_TYPE type = PT_POINTER;
|
||||
UINT32 cursor_id = 0;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkDeviceManagerWin32 *device_manager = display_win32->device_manager;
|
||||
|
||||
if (!getPointerType (pointer_id, &type))
|
||||
if (!WINPOINTER_API (device_manager, getPointerType) (pointer_id, &type))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getPointerCursorId (pointer_id, &cursor_id))
|
||||
if (!WINPOINTER_API (device_manager, getPointerCursorId) (pointer_id, &cursor_id))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerCursorId");
|
||||
return;
|
||||
@@ -415,7 +424,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
if (winpointer_should_filter_message (msg, type))
|
||||
return;
|
||||
|
||||
if (winpointer_should_ignore_interaction (pointer_id))
|
||||
if (winpointer_should_ignore_interaction (device_manager, pointer_id))
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
@@ -431,7 +440,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
do
|
||||
{
|
||||
infos = g_new0 (POINTER_PEN_INFO, history_count);
|
||||
if (!getPointerPenInfoHistory (pointer_id, &history_count, infos))
|
||||
if (!WINPOINTER_API (device_manager, getPointerPenInfoHistory) (pointer_id, &history_count, infos))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerPenInfoHistory");
|
||||
g_free (infos);
|
||||
@@ -443,7 +452,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
if (G_UNLIKELY (history_count == 0))
|
||||
return;
|
||||
|
||||
device = winpointer_find_device_with_source (infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
device = winpointer_find_device_with_source (device_manager, infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
if (G_UNLIKELY (!device))
|
||||
{
|
||||
g_free (infos);
|
||||
@@ -484,7 +493,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
do
|
||||
{
|
||||
infos = g_new0 (POINTER_TOUCH_INFO, history_count);
|
||||
if (!getPointerTouchInfoHistory (pointer_id, &history_count, infos))
|
||||
if (!WINPOINTER_API (device_manager, getPointerTouchInfoHistory) (pointer_id, &history_count, infos))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerTouchInfoHistory");
|
||||
g_free (infos);
|
||||
@@ -496,7 +505,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
if (G_UNLIKELY (history_count == 0))
|
||||
return;
|
||||
|
||||
device = winpointer_find_device_with_source (infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_TOUCHSCREEN);
|
||||
device = winpointer_find_device_with_source (device_manager, infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_TOUCHSCREEN);
|
||||
if (G_UNLIKELY (!device))
|
||||
{
|
||||
g_free (infos);
|
||||
@@ -524,21 +533,23 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
guint32 *time)
|
||||
gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
GdkWin32Display *display_win32,
|
||||
guint32 *time)
|
||||
{
|
||||
UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
|
||||
POINTER_INPUT_TYPE type = PT_POINTER;
|
||||
UINT32 cursor_id = 0;
|
||||
GdkDeviceManagerWin32 *device_manager = display_win32->device_manager;
|
||||
|
||||
if (!getPointerType (pointer_id, &type))
|
||||
if (!WINPOINTER_API (device_manager, getPointerType) (pointer_id, &type))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!getPointerCursorId (pointer_id, &cursor_id))
|
||||
if (!WINPOINTER_API (device_manager, getPointerCursorId) (pointer_id, &cursor_id))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerCursorId");
|
||||
return FALSE;
|
||||
@@ -550,13 +561,13 @@ gdk_winpointer_get_message_info (MSG *msg,
|
||||
{
|
||||
POINTER_PEN_INFO pen_info;
|
||||
|
||||
if (!getPointerPenInfo (pointer_id, &pen_info))
|
||||
if (!WINPOINTER_API (device_manager, getPointerPenInfo) (pointer_id, &pen_info))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerPenInfo");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*device = (GdkDevice*) winpointer_find_device_with_source (pen_info.pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
*device = (GdkDevice*) winpointer_find_device_with_source (device_manager, pen_info.pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
*time = winpointer_get_time (msg, &pen_info.pointerInfo);
|
||||
}
|
||||
break;
|
||||
@@ -564,13 +575,14 @@ gdk_winpointer_get_message_info (MSG *msg,
|
||||
{
|
||||
POINTER_TOUCH_INFO touch_info;
|
||||
|
||||
if (!getPointerTouchInfo (pointer_id, &touch_info))
|
||||
if (!WINPOINTER_API (device_manager, getPointerTouchInfo) (pointer_id, &touch_info))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerTouchInfo");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*device = GDK_DEVICE (winpointer_find_device_with_source (touch_info.pointerInfo.sourceDevice,
|
||||
*device = GDK_DEVICE (winpointer_find_device_with_source (device_manager,
|
||||
touch_info.pointerInfo.sourceDevice,
|
||||
cursor_id,
|
||||
GDK_SOURCE_TOUCHSCREEN));
|
||||
|
||||
@@ -587,12 +599,13 @@ gdk_winpointer_get_message_info (MSG *msg,
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_winpointer_should_forward_message (MSG *msg)
|
||||
gdk_winpointer_should_forward_message (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg)
|
||||
{
|
||||
UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
|
||||
POINTER_INPUT_TYPE type = PT_POINTER;
|
||||
|
||||
if (!getPointerType (pointer_id, &type))
|
||||
if (!WINPOINTER_API (device_manager, getPointerType) (pointer_id, &type))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
|
||||
return TRUE;
|
||||
@@ -602,9 +615,10 @@ gdk_winpointer_should_forward_message (MSG *msg)
|
||||
}
|
||||
|
||||
void
|
||||
gdk_winpointer_interaction_ended (MSG *msg)
|
||||
gdk_winpointer_interaction_ended (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg)
|
||||
{
|
||||
winpointer_remove_ignored_interaction (GET_POINTERID_WPARAM (msg->wParam));
|
||||
winpointer_remove_ignored_interaction (device_manager, GET_POINTERID_WPARAM (msg->wParam));
|
||||
}
|
||||
|
||||
static inline double
|
||||
@@ -626,12 +640,13 @@ utils_rect_is_degenerate (RECT *rect)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_device_update_scale_factors (GdkDeviceWinpointer *device)
|
||||
winpointer_device_update_scale_factors (GdkDeviceWinpointer *device,
|
||||
GdkDeviceManagerWin32 *device_manager)
|
||||
{
|
||||
RECT device_rect;
|
||||
RECT display_rect;
|
||||
|
||||
if (!getPointerDeviceRects (device->device_handle, &device_rect, &display_rect))
|
||||
if (!WINPOINTER_API (device_manager, getPointerDeviceRects) (device->device_handle, &device_rect, &display_rect))
|
||||
{
|
||||
WIN32_API_FAILED ("GetPointerDeviceRects");
|
||||
return FALSE;
|
||||
@@ -716,8 +731,9 @@ winpointer_get_device_details (HANDLE device,
|
||||
}
|
||||
|
||||
static void
|
||||
winpointer_create_device (POINTER_DEVICE_INFO *info,
|
||||
GdkInputSource source)
|
||||
winpointer_create_device (GdkDeviceManagerWin32 *device_manager,
|
||||
POINTER_DEVICE_INFO *info,
|
||||
GdkInputSource source)
|
||||
{
|
||||
GdkDeviceWinpointer *device = NULL;
|
||||
GdkSeat *seat = NULL;
|
||||
@@ -731,12 +747,12 @@ winpointer_create_device (POINTER_DEVICE_INFO *info,
|
||||
UINT32 num_cursors = 0;
|
||||
GdkAxisFlags axes_flags = 0;
|
||||
|
||||
seat = gdk_display_get_default_seat (_gdk_display);
|
||||
seat = gdk_display_get_default_seat (device_manager->display);
|
||||
|
||||
memset (pid, 0, VID_PID_CHARS + 1);
|
||||
memset (vid, 0, VID_PID_CHARS + 1);
|
||||
|
||||
if (!getPointerDeviceCursors (info->device, &num_cursors, NULL))
|
||||
if (!WINPOINTER_API (device_manager, getPointerDeviceCursors) (info->device, &num_cursors, NULL))
|
||||
{
|
||||
WIN32_API_FAILED ("GetPointerDeviceCursors");
|
||||
return;
|
||||
@@ -780,7 +796,7 @@ winpointer_create_device (POINTER_DEVICE_INFO *info,
|
||||
}
|
||||
|
||||
device = g_object_new (GDK_TYPE_DEVICE_WINPOINTER,
|
||||
"display", _gdk_display,
|
||||
"display", device_manager->display,
|
||||
"seat", seat,
|
||||
"has-cursor", TRUE,
|
||||
"source", source,
|
||||
@@ -820,7 +836,7 @@ winpointer_create_device (POINTER_DEVICE_INFO *info,
|
||||
device->start_cursor_id = info->startingCursorId;
|
||||
device->end_cursor_id = info->startingCursorId + num_cursors - 1;
|
||||
|
||||
if (!winpointer_device_update_scale_factors (device))
|
||||
if (!winpointer_device_update_scale_factors (device, device_manager))
|
||||
{
|
||||
g_set_object (&device, NULL);
|
||||
goto cleanup;
|
||||
@@ -844,10 +860,10 @@ winpointer_create_device (POINTER_DEVICE_INFO *info,
|
||||
break;
|
||||
}
|
||||
|
||||
_gdk_device_manager->winpointer_devices = g_list_append (_gdk_device_manager->winpointer_devices, device);
|
||||
device_manager->winpointer_devices = g_list_append (device_manager->winpointer_devices, device);
|
||||
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (device), _gdk_device_manager->core_pointer);
|
||||
_gdk_device_add_physical_device (_gdk_device_manager->core_pointer, GDK_DEVICE (device));
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (device), device_manager->core_pointer);
|
||||
_gdk_device_add_physical_device (device_manager->core_pointer, GDK_DEVICE (device));
|
||||
|
||||
gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), GDK_DEVICE (device));
|
||||
|
||||
@@ -859,16 +875,17 @@ cleanup:
|
||||
}
|
||||
|
||||
static void
|
||||
winpointer_create_devices (POINTER_DEVICE_INFO *info)
|
||||
winpointer_create_devices (GdkDeviceManagerWin32 *device_manager,
|
||||
POINTER_DEVICE_INFO *info)
|
||||
{
|
||||
switch (info->pointerDeviceType)
|
||||
{
|
||||
case POINTER_DEVICE_TYPE_INTEGRATED_PEN:
|
||||
case POINTER_DEVICE_TYPE_EXTERNAL_PEN:
|
||||
winpointer_create_device (info, GDK_SOURCE_PEN);
|
||||
winpointer_create_device (device_manager, info, GDK_SOURCE_PEN);
|
||||
break;
|
||||
case POINTER_DEVICE_TYPE_TOUCH:
|
||||
winpointer_create_device (info, GDK_SOURCE_TOUCHSCREEN);
|
||||
winpointer_create_device (device_manager, info, GDK_SOURCE_TOUCHSCREEN);
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
@@ -894,9 +911,10 @@ winpointer_find_device_in_system_list (GdkDeviceWinpointer *device,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_find_system_device_in_device_manager (POINTER_DEVICE_INFO *info)
|
||||
winpointer_find_system_device_in_device_manager (GdkDeviceManagerWin32 *device_manager,
|
||||
POINTER_DEVICE_INFO *info)
|
||||
{
|
||||
for (GList *l = _gdk_device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
for (GList *l = device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
{
|
||||
GdkDeviceWinpointer *device = GDK_DEVICE_WINPOINTER (l->data);
|
||||
|
||||
@@ -911,7 +929,7 @@ winpointer_find_system_device_in_device_manager (POINTER_DEVICE_INFO *info)
|
||||
}
|
||||
|
||||
static void
|
||||
winpointer_enumerate_devices (void)
|
||||
winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
{
|
||||
POINTER_DEVICE_INFO *infos = NULL;
|
||||
UINT32 infos_count = 0;
|
||||
@@ -921,7 +939,7 @@ winpointer_enumerate_devices (void)
|
||||
do
|
||||
{
|
||||
infos = g_new0 (POINTER_DEVICE_INFO, infos_count);
|
||||
if (!getPointerDevices (&infos_count, infos))
|
||||
if (!WINPOINTER_API (device_manager, getPointerDevices) (&infos_count, infos))
|
||||
{
|
||||
WIN32_API_FAILED ("GetPointerDevices");
|
||||
g_free (infos);
|
||||
@@ -930,7 +948,7 @@ winpointer_enumerate_devices (void)
|
||||
}
|
||||
while (infos_count > 0 && !infos);
|
||||
|
||||
current = _gdk_device_manager->winpointer_devices;
|
||||
current = device_manager->winpointer_devices;
|
||||
|
||||
while (current != NULL)
|
||||
{
|
||||
@@ -941,7 +959,7 @@ winpointer_enumerate_devices (void)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (device));
|
||||
|
||||
_gdk_device_manager->winpointer_devices = g_list_delete_link (_gdk_device_manager->winpointer_devices,
|
||||
device_manager->winpointer_devices = g_list_delete_link (device_manager->winpointer_devices,
|
||||
current);
|
||||
|
||||
gdk_device_update_tool (GDK_DEVICE (device), NULL);
|
||||
@@ -953,7 +971,7 @@ winpointer_enumerate_devices (void)
|
||||
gdk_seat_default_remove_tool (GDK_SEAT_DEFAULT (seat), device->tool_eraser);
|
||||
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (device), NULL);
|
||||
_gdk_device_remove_physical_device (_gdk_device_manager->core_pointer, GDK_DEVICE (device));
|
||||
_gdk_device_remove_physical_device (device_manager->core_pointer, GDK_DEVICE (device));
|
||||
|
||||
gdk_seat_default_remove_physical_device (GDK_SEAT_DEFAULT (seat), GDK_DEVICE (device));
|
||||
|
||||
@@ -961,7 +979,7 @@ winpointer_enumerate_devices (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
winpointer_device_update_scale_factors (device);
|
||||
winpointer_device_update_scale_factors (device, device_manager);
|
||||
}
|
||||
|
||||
current = next;
|
||||
@@ -970,9 +988,9 @@ winpointer_enumerate_devices (void)
|
||||
/* create new gdk devices */
|
||||
for (i = 0; i < infos_count; i++)
|
||||
{
|
||||
if (!winpointer_find_system_device_in_device_manager (&infos[i]))
|
||||
if (!winpointer_find_system_device_in_device_manager (device_manager, &infos[i]))
|
||||
{
|
||||
winpointer_create_devices (&infos[i]);
|
||||
winpointer_create_devices (device_manager, &infos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -985,20 +1003,31 @@ winpointer_notifications_window_procedure (HWND hWnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
GdkDeviceManagerWin32 *device_manager;
|
||||
CREATESTRUCT *cs = NULL;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_NCCREATE:
|
||||
cs = (CREATESTRUCT *)lParam;
|
||||
device_manager = cs->lpCreateParams;
|
||||
SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)device_manager);
|
||||
return TRUE;
|
||||
case WM_POINTERDEVICECHANGE:
|
||||
winpointer_enumerate_devices ();
|
||||
device_manager = (GdkDeviceManagerWin32 *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
|
||||
winpointer_enumerate_devices (device_manager);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProcW (hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_notif_window_create (void)
|
||||
static HWND
|
||||
winpointer_notif_window_create (GdkDeviceManagerWin32 *device_manager)
|
||||
{
|
||||
WNDCLASSEXW wndclassex;
|
||||
ATOM notifications_window_class;
|
||||
HWND notification_window_hwnd = NULL;
|
||||
|
||||
memset (&wndclassex, 0, sizeof (wndclassex));
|
||||
wndclassex.cbSize = sizeof (wndclassex);
|
||||
@@ -1006,100 +1035,111 @@ winpointer_notif_window_create (void)
|
||||
wndclassex.lpfnWndProc = winpointer_notifications_window_procedure;
|
||||
wndclassex.hInstance = this_module ();
|
||||
|
||||
if ((notifications_window_class = RegisterClassExW (&wndclassex)) == 0)
|
||||
{
|
||||
WIN32_API_FAILED ("RegisterClassExW");
|
||||
return FALSE;
|
||||
}
|
||||
notifications_window_class = RegisterClassExW (&wndclassex);
|
||||
|
||||
if (!(notifications_window_handle = CreateWindowExW (0,
|
||||
(LPCWSTR)(guintptr)notifications_window_class,
|
||||
L"GdkWin32 Winpointer Notifications",
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
HWND_MESSAGE,
|
||||
NULL,
|
||||
this_module (),
|
||||
NULL)))
|
||||
if (notifications_window_class != 0)
|
||||
{
|
||||
WIN32_API_FAILED ("CreateWindowExW");
|
||||
return FALSE;
|
||||
}
|
||||
notification_window_hwnd = CreateWindowExW (0,
|
||||
(LPCWSTR)(guintptr)notifications_window_class,
|
||||
L"GdkWin32 Winpointer Notifications",
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
HWND_MESSAGE,
|
||||
NULL,
|
||||
this_module (),
|
||||
device_manager);
|
||||
|
||||
return TRUE;
|
||||
if (notification_window_hwnd == NULL)
|
||||
WIN32_API_FAILED ("CreateWindowExW");
|
||||
}
|
||||
else
|
||||
WIN32_API_FAILED ("RegisterClassExW");
|
||||
|
||||
return notification_window_hwnd;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_ensure_procedures (void)
|
||||
winpointer_ensure_procedures (GdkDeviceManagerWin32 *device_manager)
|
||||
{
|
||||
static HMODULE user32_dll = NULL;
|
||||
GdkDeviceManagerWin32WinpointerFuncs *funcs = NULL;
|
||||
static gsize user32_dll_checked = 0;
|
||||
|
||||
if (!user32_dll)
|
||||
if (g_once_init_enter (&user32_dll_checked))
|
||||
{
|
||||
user32_dll = LoadLibraryW (L"user32.dll");
|
||||
if (!user32_dll)
|
||||
{
|
||||
WIN32_API_FAILED ("LoadLibraryW");
|
||||
return FALSE;
|
||||
}
|
||||
HMODULE user32_dll = NULL;
|
||||
|
||||
registerPointerDeviceNotifications = (registerPointerDeviceNotifications_t)
|
||||
GetProcAddress (user32_dll, "RegisterPointerDeviceNotifications");
|
||||
getPointerDevices = (getPointerDevices_t)
|
||||
GetProcAddress (user32_dll, "GetPointerDevices");
|
||||
getPointerDeviceCursors = (getPointerDeviceCursors_t)
|
||||
GetProcAddress (user32_dll, "GetPointerDeviceCursors");
|
||||
getPointerDeviceRects = (getPointerDeviceRects_t)
|
||||
GetProcAddress (user32_dll, "GetPointerDeviceRects");
|
||||
getPointerType = (getPointerType_t)
|
||||
GetProcAddress (user32_dll, "GetPointerType");
|
||||
getPointerCursorId = (getPointerCursorId_t)
|
||||
GetProcAddress (user32_dll, "GetPointerCursorId");
|
||||
getPointerPenInfo = (getPointerPenInfo_t)
|
||||
GetProcAddress (user32_dll, "GetPointerPenInfo");
|
||||
getPointerTouchInfo = (getPointerTouchInfo_t)
|
||||
GetProcAddress (user32_dll, "GetPointerTouchInfo");
|
||||
getPointerPenInfoHistory = (getPointerPenInfoHistory_t)
|
||||
GetProcAddress (user32_dll, "GetPointerPenInfoHistory");
|
||||
getPointerTouchInfoHistory = (getPointerTouchInfoHistory_t)
|
||||
GetProcAddress (user32_dll, "GetPointerTouchInfoHistory");
|
||||
setGestureConfig = (setGestureConfig_t)
|
||||
GetProcAddress (user32_dll, "SetGestureConfig");
|
||||
setWindowFeedbackSetting = (setWindowFeedbackSetting_t)
|
||||
GetProcAddress (user32_dll, "SetWindowFeedbackSetting");
|
||||
user32_dll = LoadLibraryW (L"user32.dll");
|
||||
if (user32_dll)
|
||||
{
|
||||
funcs = g_new0 (GdkDeviceManagerWin32WinpointerFuncs, 1);
|
||||
|
||||
funcs->registerPointerDeviceNotifications = (registerPointerDeviceNotifications_t)
|
||||
GetProcAddress (user32_dll, "RegisterPointerDeviceNotifications");
|
||||
funcs->getPointerDevices = (getPointerDevices_t)
|
||||
GetProcAddress (user32_dll, "GetPointerDevices");
|
||||
funcs->getPointerDeviceCursors = (getPointerDeviceCursors_t)
|
||||
GetProcAddress (user32_dll, "GetPointerDeviceCursors");
|
||||
funcs->getPointerDeviceRects = (getPointerDeviceRects_t)
|
||||
GetProcAddress (user32_dll, "GetPointerDeviceRects");
|
||||
funcs->getPointerType = (getPointerType_t)
|
||||
GetProcAddress (user32_dll, "GetPointerType");
|
||||
funcs->getPointerCursorId = (getPointerCursorId_t)
|
||||
GetProcAddress (user32_dll, "GetPointerCursorId");
|
||||
funcs->getPointerPenInfo = (getPointerPenInfo_t)
|
||||
GetProcAddress (user32_dll, "GetPointerPenInfo");
|
||||
funcs->getPointerTouchInfo = (getPointerTouchInfo_t)
|
||||
GetProcAddress (user32_dll, "GetPointerTouchInfo");
|
||||
funcs->getPointerPenInfoHistory = (getPointerPenInfoHistory_t)
|
||||
GetProcAddress (user32_dll, "GetPointerPenInfoHistory");
|
||||
funcs->getPointerTouchInfoHistory = (getPointerTouchInfoHistory_t)
|
||||
GetProcAddress (user32_dll, "GetPointerTouchInfoHistory");
|
||||
funcs->setGestureConfig = (setGestureConfig_t)
|
||||
GetProcAddress (user32_dll, "SetGestureConfig");
|
||||
funcs->setWindowFeedbackSetting = (setWindowFeedbackSetting_t)
|
||||
GetProcAddress (user32_dll, "SetWindowFeedbackSetting");
|
||||
|
||||
if (funcs->registerPointerDeviceNotifications &&
|
||||
funcs->getPointerDevices &&
|
||||
funcs->getPointerDeviceCursors &&
|
||||
funcs->getPointerDeviceRects &&
|
||||
funcs->getPointerType &&
|
||||
funcs->getPointerCursorId &&
|
||||
funcs->getPointerPenInfo &&
|
||||
funcs->getPointerTouchInfo &&
|
||||
funcs->getPointerPenInfoHistory &&
|
||||
funcs->getPointerTouchInfoHistory)
|
||||
device_manager->winpointer_funcs = funcs;
|
||||
}
|
||||
else
|
||||
WIN32_API_FAILED ("LoadLibraryW");
|
||||
|
||||
g_once_init_leave (&user32_dll_checked, 1);
|
||||
}
|
||||
|
||||
return registerPointerDeviceNotifications &&
|
||||
getPointerDevices &&
|
||||
getPointerDeviceCursors &&
|
||||
getPointerDeviceRects &&
|
||||
getPointerType &&
|
||||
getPointerCursorId &&
|
||||
getPointerPenInfo &&
|
||||
getPointerTouchInfo &&
|
||||
getPointerPenInfoHistory &&
|
||||
getPointerTouchInfoHistory &&
|
||||
setGestureConfig;
|
||||
return (device_manager->winpointer_funcs != NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_winpointer_initialize (void)
|
||||
gdk_winpointer_initialize (GdkDeviceManagerWin32 *device_manager)
|
||||
{
|
||||
if (!winpointer_ensure_procedures ())
|
||||
HWND notification_hwnd = NULL;
|
||||
if (!winpointer_ensure_procedures (device_manager))
|
||||
return FALSE;
|
||||
|
||||
if (!winpointer_notif_window_create ())
|
||||
notification_hwnd = winpointer_notif_window_create (device_manager);
|
||||
if (notification_hwnd == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!registerPointerDeviceNotifications (notifications_window_handle, FALSE))
|
||||
if (!WINPOINTER_API (device_manager, registerPointerDeviceNotifications) (notification_hwnd, FALSE))
|
||||
{
|
||||
WIN32_API_FAILED ("RegisterPointerDeviceNotifications");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ignored_interactions = g_ptr_array_new ();
|
||||
device_manager->winpointer_notification_hwnd = notification_hwnd;
|
||||
device_manager->ignored_interactions = g_ptr_array_new ();
|
||||
|
||||
winpointer_enumerate_devices ();
|
||||
winpointer_enumerate_devices (device_manager);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1120,13 +1160,14 @@ gdk_winpointer_initialize_surface (GdkSurface *surface)
|
||||
TABLET_DISABLE_FLICKS |
|
||||
TABLET_DISABLE_FLICKFALLBACKKEYS);
|
||||
|
||||
winpointer_ensure_procedures ();
|
||||
GdkDeviceManagerWin32 *device_manager = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface))->device_manager;
|
||||
winpointer_ensure_procedures (device_manager);
|
||||
|
||||
key = GlobalAddAtom (MICROSOFT_TABLETPENSERVICE_PROPERTY);
|
||||
API_CALL (SetPropW, (hwnd, (LPCWSTR)(guintptr)key, val));
|
||||
GlobalDeleteAtom (key);
|
||||
|
||||
if (setGestureConfig != NULL)
|
||||
if (WINPOINTER_API (device_manager, setGestureConfig) != NULL)
|
||||
{
|
||||
GESTURECONFIG gesture_config;
|
||||
memset (&gesture_config, 0, sizeof (gesture_config));
|
||||
@@ -1135,10 +1176,10 @@ gdk_winpointer_initialize_surface (GdkSurface *surface)
|
||||
gesture_config.dwWant = 0;
|
||||
gesture_config.dwBlock = GC_ALLGESTURES;
|
||||
|
||||
API_CALL (setGestureConfig, (hwnd, 0, 1, &gesture_config, sizeof (gesture_config)));
|
||||
API_CALL (WINPOINTER_API (device_manager,setGestureConfig), (hwnd, 0, 1, &gesture_config, sizeof (gesture_config)));
|
||||
}
|
||||
|
||||
if (setWindowFeedbackSetting != NULL)
|
||||
if (WINPOINTER_API (device_manager, setWindowFeedbackSetting) != NULL)
|
||||
{
|
||||
FEEDBACK_TYPE feedbacks[] = {
|
||||
FEEDBACK_TOUCH_CONTACTVISUALIZATION,
|
||||
@@ -1159,7 +1200,7 @@ gdk_winpointer_initialize_surface (GdkSurface *surface)
|
||||
{
|
||||
BOOL setting = FALSE;
|
||||
|
||||
API_CALL (setWindowFeedbackSetting, (hwnd, feedbacks[i], 0, sizeof (BOOL), &setting));
|
||||
API_CALL (WINPOINTER_API (device_manager, setWindowFeedbackSetting), (hwnd, feedbacks[i], 0, sizeof (BOOL), &setting));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "winpointer.h"
|
||||
|
||||
gboolean gdk_winpointer_initialize (void);
|
||||
gboolean gdk_winpointer_initialize (GdkDeviceManagerWin32 *device_manager);
|
||||
|
||||
void gdk_winpointer_initialize_surface (GdkSurface *surface);
|
||||
void gdk_winpointer_finalize_surface (GdkSurface *surface);
|
||||
@@ -30,12 +30,15 @@ typedef void
|
||||
POINT *screen_pt,
|
||||
guint32 time_);
|
||||
|
||||
gboolean gdk_winpointer_should_forward_message (MSG *msg);
|
||||
gboolean gdk_winpointer_should_forward_message (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg);
|
||||
void gdk_winpointer_input_events (GdkSurface *surface,
|
||||
crossing_cb_t crossing_cb,
|
||||
MSG *msg);
|
||||
gboolean gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
guint32 *time_);
|
||||
void gdk_winpointer_interaction_ended (MSG *msg);
|
||||
gboolean gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
GdkWin32Display *display_win32,
|
||||
guint32 *time_);
|
||||
void gdk_winpointer_interaction_ended (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg);
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "gdkprivate-win32.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkkeys-win32.h"
|
||||
@@ -77,9 +77,7 @@ struct _GdkWin32Keymap
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32Keymap, gdk_win32_keymap, GDK_TYPE_KEYMAP)
|
||||
|
||||
guint _gdk_keymap_serial = 0;
|
||||
static GdkKeymap *default_keymap = NULL;
|
||||
|
||||
/* forward declarations */
|
||||
static void update_keymap (GdkWin32Keymap *gdk_keymap);
|
||||
static void clear_keyboard_layout_info (gpointer data);
|
||||
|
||||
@@ -107,7 +105,14 @@ gdk_win32_keymap_init (GdkWin32Keymap *keymap)
|
||||
if (_gdk_win32_check_processor (GDK_WIN32_WOW64))
|
||||
keymap->gdkwin32_keymap_impl = &gdkwin32_keymap_impl_wow64;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_keymap_constructed (GObject *object)
|
||||
{
|
||||
GdkWin32Keymap *keymap;
|
||||
|
||||
keymap = GDK_WIN32_KEYMAP (object);
|
||||
update_keymap (keymap);
|
||||
}
|
||||
|
||||
@@ -583,8 +588,10 @@ update_keymap (GdkWin32Keymap *keymap)
|
||||
BOOL changed = FALSE;
|
||||
int n_layouts;
|
||||
int i;
|
||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (GDK_KEYMAP (keymap)->display);
|
||||
|
||||
if (keymap->current_serial == _gdk_keymap_serial &&
|
||||
|
||||
if (keymap->current_serial == gdk_win32_display_get_keymap_serial (display) &&
|
||||
keymap->layout_handles->len > 0)
|
||||
{
|
||||
return;
|
||||
@@ -643,7 +650,7 @@ update_keymap (GdkWin32Keymap *keymap)
|
||||
if (changed)
|
||||
ActivateKeyboardLayout (current_layout, 0);
|
||||
|
||||
keymap->current_serial = _gdk_keymap_serial;
|
||||
keymap->current_serial = gdk_win32_display_get_keymap_serial (display);
|
||||
}
|
||||
|
||||
guint8
|
||||
@@ -677,17 +684,6 @@ _gdk_win32_keymap_get_active_group (GdkWin32Keymap *keymap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GdkKeymap*
|
||||
_gdk_win32_display_get_keymap (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
||||
|
||||
if (default_keymap == NULL)
|
||||
default_keymap = g_object_new (gdk_win32_keymap_get_type (), NULL);
|
||||
|
||||
return default_keymap;
|
||||
}
|
||||
|
||||
GdkModifierType
|
||||
_gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap)
|
||||
{
|
||||
@@ -1071,6 +1067,7 @@ gdk_win32_keymap_class_init (GdkWin32KeymapClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
|
||||
|
||||
object_class->constructed = gdk_win32_keymap_constructed;
|
||||
object_class->finalize = gdk_win32_keymap_finalize;
|
||||
|
||||
keymap_class->get_direction = gdk_win32_keymap_get_direction;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <io.h>
|
||||
|
||||
#include "gdk.h"
|
||||
#include "gdkmain-win32.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
@@ -39,24 +40,15 @@
|
||||
#include <wintab.h>
|
||||
#include <imm.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Whether GDK initialized COM */
|
||||
static gboolean co_initialized = FALSE;
|
||||
|
||||
/* Whether GDK initialized OLE */
|
||||
static gboolean ole_initialized = FALSE;
|
||||
|
||||
void
|
||||
_gdk_win32_surfaceing_init (void)
|
||||
{
|
||||
_gdk_win32_clipdrop_init ();
|
||||
|
||||
gdk_dmanipulation_initialize ();
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_win32_ensure_com (void)
|
||||
{
|
||||
if (!co_initialized)
|
||||
static gsize co_initialized = 0;
|
||||
|
||||
if (g_once_init_enter (&co_initialized))
|
||||
{
|
||||
/* UI thread should only use STA model. See
|
||||
* -> https://devblogs.microsoft.com/oldnewthing/20080424-00/?p=22603
|
||||
@@ -64,11 +56,12 @@ gdk_win32_ensure_com (void)
|
||||
*/
|
||||
const DWORD flags = COINIT_APARTMENTTHREADED |
|
||||
COINIT_DISABLE_OLE1DDE;
|
||||
gboolean init_result = FALSE;
|
||||
HRESULT hr;
|
||||
|
||||
hr = CoInitializeEx (NULL, flags);
|
||||
if (SUCCEEDED (hr))
|
||||
co_initialized = TRUE;
|
||||
init_result = TRUE;
|
||||
else switch (hr)
|
||||
{
|
||||
case RPC_E_CHANGED_MODE:
|
||||
@@ -79,19 +72,26 @@ gdk_win32_ensure_com (void)
|
||||
HR_LOG (hr);
|
||||
break;
|
||||
}
|
||||
|
||||
g_once_init_leave (&co_initialized, init_result);
|
||||
}
|
||||
|
||||
return co_initialized;
|
||||
}
|
||||
|
||||
/* Whether GDK initialized OLE */
|
||||
gboolean
|
||||
gdk_win32_ensure_ole (void)
|
||||
{
|
||||
if (!ole_initialized)
|
||||
static gsize ole_initialized = 0;
|
||||
|
||||
if (g_once_init_enter (&ole_initialized))
|
||||
{
|
||||
gboolean init_result = FALSE;
|
||||
HRESULT hr = OleInitialize (NULL);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
ole_initialized = TRUE;
|
||||
init_result = TRUE;
|
||||
else switch (hr)
|
||||
{
|
||||
case RPC_E_CHANGED_MODE:
|
||||
@@ -102,11 +102,117 @@ gdk_win32_ensure_ole (void)
|
||||
HR_LOG (hr);
|
||||
break;
|
||||
}
|
||||
|
||||
g_once_init_leave (&ole_initialized, init_result);
|
||||
}
|
||||
|
||||
return ole_initialized;
|
||||
}
|
||||
|
||||
/** gdk_win32_check_app_container:
|
||||
*
|
||||
* Check if running sandboxed in an app container
|
||||
*/
|
||||
bool
|
||||
gdk_win32_check_app_container (void)
|
||||
{
|
||||
HANDLE token_handle = NULL;
|
||||
DWORD is_app_container = 0;
|
||||
DWORD size = sizeof (is_app_container);
|
||||
bool result = false;
|
||||
|
||||
/* Since Windows 8: use GetCurrentProcessToken() and remove the call to CloseHandle() */
|
||||
|
||||
if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token_handle))
|
||||
{
|
||||
WIN32_API_FAILED ("OpenProcessToken");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetTokenInformation (token_handle, TokenIsAppContainer, &is_app_container, size, &size))
|
||||
WIN32_API_FAILED ("GetTokenInformation");
|
||||
else if (size > 0)
|
||||
result = !!is_app_container;
|
||||
|
||||
CloseHandle (token_handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** gdk_win32_check_high_integrity:
|
||||
*
|
||||
* Check if the app is running with high integrity
|
||||
*
|
||||
* Code based on:
|
||||
* https://devblogs.microsoft.com/oldnewthing/20221017-00/?p=107291
|
||||
* https://github.com/microsoft/WindowsAppSDK/blob/main/dev/Common/Security.IntegrityLevel.h
|
||||
*/
|
||||
bool
|
||||
gdk_win32_check_high_integrity (void)
|
||||
{
|
||||
HANDLE token_handle = NULL;
|
||||
TOKEN_MANDATORY_LABEL integrity_level;
|
||||
DWORD size = sizeof (integrity_level);
|
||||
bool result = false;
|
||||
|
||||
/* Since Windows 8: use GetCurrentProcessToken() and remove the call to CloseHandle() */
|
||||
|
||||
if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token_handle))
|
||||
{
|
||||
WIN32_API_FAILED ("OpenProcessToken");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset (&integrity_level, 0, sizeof (integrity_level));
|
||||
|
||||
if (!GetTokenInformation (token_handle, TokenIntegrityLevel, &integrity_level, size, &size))
|
||||
WIN32_API_FAILED ("GetTokenInformation");
|
||||
else if (size > 0 && IsValidSid (integrity_level.Label.Sid))
|
||||
{
|
||||
UCHAR subauthority_count = *GetSidSubAuthorityCount (integrity_level.Label.Sid);
|
||||
if (subauthority_count > 0)
|
||||
{
|
||||
DWORD level = *GetSidSubAuthority (integrity_level.Label.Sid, subauthority_count - 1);
|
||||
result = (level >= SECURITY_MANDATORY_HIGH_RID);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle (token_handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** gdk_win32_check_manually_elevated:
|
||||
*
|
||||
* Code based on:
|
||||
* https://devblogs.microsoft.com/oldnewthing/20241003-00/?p=110336
|
||||
*/
|
||||
bool
|
||||
gdk_win32_check_manually_elevated (void)
|
||||
{
|
||||
HANDLE token_handle = NULL;
|
||||
TOKEN_ELEVATION_TYPE elevation_type = TokenElevationTypeDefault;
|
||||
DWORD size = sizeof (elevation_type);
|
||||
bool result = false;
|
||||
|
||||
/* Since Windows 8: use GetCurrentProcessToken() and remove the call to CloseHandle() */
|
||||
|
||||
if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token_handle))
|
||||
{
|
||||
WIN32_API_FAILED ("OpenProcessToken");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetTokenInformation (token_handle, TokenElevationType, &elevation_type, size, &size))
|
||||
WIN32_API_FAILED ("GetTokenInformation");
|
||||
else if (size > 0)
|
||||
result = (elevation_type == TokenElevationTypeFull);
|
||||
|
||||
CloseHandle (token_handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_api_failed (const char *where,
|
||||
const char *api)
|
||||
|
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright (C) 2024 the GTK team
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -13,16 +14,24 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define CONSTRAINT_EDITOR_APPLICATION_TYPE (constraint_editor_application_get_type ())
|
||||
typedef enum {
|
||||
OSVersionWindows7,
|
||||
OSVersionWindows8,
|
||||
OSVersionWindows8_1,
|
||||
OSVersionWindows10,
|
||||
OSVersionWindows11,
|
||||
} OSVersion;
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditorApplication, constraint_editor_application, CONSTRAINT, EDITOR_APPLICATION, GtkApplication)
|
||||
bool gdk_win32_check_app_container (void);
|
||||
|
||||
ConstraintEditorApplication *constraint_editor_application_new (void);
|
||||
bool gdk_win32_check_high_integrity (void);
|
||||
|
||||
bool gdk_win32_check_manually_elevated (void);
|
||||
|
||||
OSVersion gdk_win32_get_os_version (void);
|
@@ -70,15 +70,20 @@ typedef enum
|
||||
} GdkDragProtocol;
|
||||
|
||||
gulong _gdk_win32_get_next_tick (gulong suggested_tick);
|
||||
BOOL _gdk_win32_get_cursor_pos (LPPOINT lpPoint);
|
||||
BOOL _gdk_win32_get_cursor_pos (GdkDisplay *display,
|
||||
LPPOINT lpPoint);
|
||||
|
||||
gboolean _gdk_win32_surface_enable_transparency (GdkSurface *surface);
|
||||
|
||||
void _gdk_win32_dnd_exit (void);
|
||||
|
||||
void gdk_win32_handle_table_insert (HANDLE *handle,
|
||||
gpointer data);
|
||||
void gdk_win32_handle_table_remove (HANDLE handle);
|
||||
void gdk_win32_display_handle_table_insert (GdkDisplay *display,
|
||||
HANDLE *handle,
|
||||
gpointer data);
|
||||
void gdk_win32_display_handle_table_remove (GdkDisplay *display,
|
||||
HANDLE handle);
|
||||
gpointer gdk_win32_display_handle_table_lookup_ (GdkDisplay *display,
|
||||
HWND handle);
|
||||
|
||||
cairo_region_t *_gdk_win32_hrgn_to_region (HRGN hrgn,
|
||||
guint scale);
|
||||
@@ -135,25 +140,9 @@ void _gdk_other_api_failed (const char *where,
|
||||
|
||||
extern LRESULT CALLBACK _gdk_win32_surface_procedure (HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
extern GdkDisplay *_gdk_display;
|
||||
|
||||
extern GdkDeviceManagerWin32 *_gdk_device_manager;
|
||||
|
||||
extern int _gdk_input_ignore_core;
|
||||
|
||||
/* These are thread specific, but GDK/win32 works OK only when invoked
|
||||
* from a single thread anyway.
|
||||
*/
|
||||
extern HKL _gdk_input_locale;
|
||||
extern gboolean _gdk_input_locale_is_ime;
|
||||
|
||||
extern guint _gdk_keymap_serial;
|
||||
|
||||
/* The singleton clipdrop object pointer */
|
||||
extern GdkWin32Clipdrop *_win32_clipdrop;
|
||||
|
||||
/* Used to identify the main thread */
|
||||
extern GThread *_win32_main_thread;
|
||||
|
||||
typedef enum {
|
||||
GDK_WIN32_MODAL_OP_NONE = 0x0,
|
||||
@@ -165,14 +154,6 @@ typedef enum {
|
||||
|
||||
#define GDK_WIN32_MODAL_OP_SIZEMOVE_MASK (GDK_WIN32_MODAL_OP_SIZE | GDK_WIN32_MODAL_OP_MOVE)
|
||||
|
||||
/* Non-zero while a modal sizing, moving, or dnd operation is in progress */
|
||||
extern GdkWin32ModalOpKind _modal_operation_in_progress;
|
||||
|
||||
extern HWND _modal_move_resize_hwnd;
|
||||
|
||||
void _gdk_win32_begin_modal_call (GdkWin32ModalOpKind kind);
|
||||
void _gdk_win32_end_modal_call (GdkWin32ModalOpKind kind);
|
||||
|
||||
void _gdk_win32_display_init_cursors (GdkWin32Display *display);
|
||||
void _gdk_win32_display_finalize_cursors (GdkWin32Display *display);
|
||||
void _gdk_win32_display_update_cursors (GdkWin32Display *display);
|
||||
@@ -223,8 +204,6 @@ void _gdk_win32_keymap_set_active_layout (GdkWin32Keymap *keymap,
|
||||
HKL hkl);
|
||||
GdkModifierType _gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap);
|
||||
|
||||
GdkKeymap *_gdk_win32_display_get_keymap (GdkDisplay *display);
|
||||
|
||||
/* stray GdkSurfaceImplWin32 members */
|
||||
void _gdk_win32_surface_register_dnd (GdkSurface *surface);
|
||||
void _gdk_win32_surface_unregister_dnd (GdkSurface *surface);
|
||||
@@ -236,8 +215,20 @@ GdkDrag *_gdk_win32_surface_drag_begin (GdkSurface *surface,
|
||||
double x_root,
|
||||
double y_root);
|
||||
|
||||
/* miscellaneous items (property setup, language notification, keymap serial) */
|
||||
gboolean gdk_win32_display_get_setting (GdkDisplay *display,
|
||||
const char *name,
|
||||
GValue *value);
|
||||
void gdk_win32_display_lang_notification_init (GdkWin32Display *display);
|
||||
void gdk_win32_display_lang_notification_exit (GdkWin32Display *display);
|
||||
void gdk_win32_display_set_input_locale (GdkWin32Display *display,
|
||||
HKL input_locale);
|
||||
gboolean gdk_win32_display_input_locale_is_ime (GdkWin32Display *display);
|
||||
GdkKeymap *gdk_win32_display_get_default_keymap (GdkWin32Display *display);
|
||||
void gdk_win32_display_increment_keymap_serial (GdkWin32Display *display);
|
||||
guint gdk_win32_display_get_keymap_serial (GdkWin32Display *display);
|
||||
|
||||
/* Stray GdkWin32Screen members */
|
||||
gboolean _gdk_win32_get_setting (const char *name, GValue *value);
|
||||
void _gdk_win32_screen_on_displaychange_event (GdkWin32Screen *screen);
|
||||
|
||||
/* Distributed display manager implementation */
|
||||
@@ -290,8 +281,6 @@ GdkPixbuf *gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
double *y_hot);
|
||||
void gdk_win32_set_modal_dialog_libgtk_only (HWND hwnd);
|
||||
|
||||
gpointer gdk_win32_handle_table_lookup_ (HWND handle);
|
||||
|
||||
extern IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
static inline HMODULE
|
||||
|
@@ -29,6 +29,7 @@
|
||||
struct _GdkWin32Screen
|
||||
{
|
||||
GObject parent_instance;
|
||||
GdkDisplay *display;
|
||||
|
||||
int width, height;
|
||||
int surface_scale;
|
||||
@@ -41,12 +42,20 @@ struct _GdkWin32ScreenClass
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32Screen, gdk_win32_screen, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DISPLAY,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *screen_props[LAST_PROP] = { NULL, };
|
||||
|
||||
static void
|
||||
init_root_window_size (GdkWin32Screen *screen)
|
||||
{
|
||||
GdkRectangle result = { 0, };
|
||||
int i;
|
||||
GdkDisplay *display = _gdk_display;
|
||||
GdkDisplay *display = screen->display;
|
||||
GListModel *monitors;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
@@ -73,7 +82,7 @@ init_root_window (GdkWin32Screen *screen_win32)
|
||||
|
||||
init_root_window_size (screen_win32);
|
||||
|
||||
win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
win32_display = GDK_WIN32_DISPLAY (screen_win32->display);
|
||||
|
||||
if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
|
||||
screen_win32->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||
@@ -86,14 +95,21 @@ init_root_window (GdkWin32Screen *screen_win32)
|
||||
static void
|
||||
gdk_win32_screen_init (GdkWin32Screen *win32_screen)
|
||||
{
|
||||
_gdk_win32_display_init_monitors (GDK_WIN32_DISPLAY (_gdk_display));
|
||||
init_root_window (win32_screen);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_screen_constructed (GObject *object)
|
||||
{
|
||||
GdkWin32Screen *screen = GDK_WIN32_SCREEN (object);
|
||||
|
||||
_gdk_win32_display_init_monitors (GDK_WIN32_DISPLAY (screen->display));
|
||||
init_root_window (screen);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_screen_on_displaychange_event (GdkWin32Screen *screen)
|
||||
{
|
||||
_gdk_win32_display_init_monitors (GDK_WIN32_DISPLAY (_gdk_display));
|
||||
_gdk_win32_display_init_monitors (GDK_WIN32_DISPLAY (screen->display));
|
||||
init_root_window_size (screen);
|
||||
}
|
||||
|
||||
@@ -103,10 +119,58 @@ gdk_win32_screen_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gdk_win32_screen_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_screen_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkWin32Screen *screen = GDK_WIN32_SCREEN (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, screen->display);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_screen_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkWin32Screen *screen = GDK_WIN32_SCREEN (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
screen->display = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_screen_class_init (GdkWin32ScreenClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = gdk_win32_screen_constructed;
|
||||
object_class->set_property = gdk_win32_screen_set_property;
|
||||
object_class->get_property = gdk_win32_screen_get_property;
|
||||
object_class->finalize = gdk_win32_screen_finalize;
|
||||
|
||||
screen_props[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display", NULL, NULL,
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, screen_props);
|
||||
}
|
||||
|
@@ -75,10 +75,6 @@ static void gdk_win32_surface_maximize (GdkSurface *surface);
|
||||
static void gdk_win32_surface_unmaximize (GdkSurface *surface);
|
||||
static void gdk_win32_surface_minimize (GdkSurface *surface);
|
||||
|
||||
/* TODO: get rid of these global variables */
|
||||
static gpointer parent_class = NULL;
|
||||
static GSList *modal_surface_stack = NULL;
|
||||
|
||||
typedef struct _FullscreenInfo FullscreenInfo;
|
||||
|
||||
struct _FullscreenInfo
|
||||
@@ -171,7 +167,7 @@ gdk_surface_win32_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&surface->cursor);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
G_OBJECT_CLASS (gdk_win32_surface_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +182,8 @@ gdk_surface_win32_finalize (GObject *object)
|
||||
|
||||
if (!GDK_SURFACE_DESTROYED (surface))
|
||||
{
|
||||
gdk_win32_handle_table_remove (surface->handle);
|
||||
gdk_win32_display_handle_table_remove (gdk_surface_get_display (GDK_SURFACE (surface)),
|
||||
surface->handle);
|
||||
}
|
||||
|
||||
g_clear_pointer (&surface->snap_stash, g_free);
|
||||
@@ -209,7 +206,7 @@ gdk_surface_win32_finalize (GObject *object)
|
||||
g_assert (surface->transient_owner == NULL);
|
||||
g_assert (surface->transient_children == NULL);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gdk_win32_surface_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -518,7 +515,7 @@ gdk_win32_surface_constructed (GObject *object)
|
||||
* on the bitness of the OS. That pointer is still unique,
|
||||
* so this works out in the end.
|
||||
*/
|
||||
gdk_win32_handle_table_insert (&GDK_SURFACE_HWND (impl), impl);
|
||||
gdk_win32_display_handle_table_insert (display, &GDK_SURFACE_HWND (impl), impl);
|
||||
|
||||
g_free (wtitle);
|
||||
|
||||
@@ -544,7 +541,7 @@ gdk_win32_surface_constructed (GObject *object)
|
||||
impl->hdc = GetDC (impl->handle);
|
||||
impl->inhibit_configure = TRUE;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
G_OBJECT_CLASS (gdk_win32_surface_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -606,7 +603,8 @@ gdk_win32_surface_destroy_notify (GdkSurface *surface)
|
||||
_gdk_surface_destroy (surface, TRUE);
|
||||
}
|
||||
|
||||
gdk_win32_handle_table_remove (GDK_SURFACE_HWND (surface));
|
||||
gdk_win32_display_handle_table_remove (gdk_surface_get_display (surface),
|
||||
GDK_SURFACE_HWND (surface));
|
||||
g_object_unref (surface);
|
||||
}
|
||||
|
||||
@@ -989,7 +987,7 @@ gdk_win32_surface_move_resize_internal (GdkSurface *surface,
|
||||
{
|
||||
/* We ignore changes to the surface being moved or resized by the
|
||||
user, as we don't want to fight the user */
|
||||
if (GDK_SURFACE_HWND (surface) == _modal_move_resize_hwnd)
|
||||
if (GDK_SURFACE_HWND (surface) == GDK_WIN32_DISPLAY (gdk_surface_get_display (surface))->display_surface_record->modal_move_resize_hwnd)
|
||||
goto out;
|
||||
|
||||
if (with_move && (width < 0 && height < 0))
|
||||
@@ -1400,10 +1398,12 @@ gdk_win32_surface_set_transient_for (GdkSurface *surface,
|
||||
WIN32_API_FAILED ("SetWindowLongPtr");
|
||||
}
|
||||
|
||||
#define MODAL_SURFACE_STACK(s) GDK_WIN32_DISPLAY (gdk_surface_get_display (s))->display_surface_record->modal_surface_stack
|
||||
|
||||
static void
|
||||
gdk_win32_push_modal_surface (GdkSurface *surface)
|
||||
{
|
||||
modal_surface_stack = g_slist_prepend (modal_surface_stack, surface);
|
||||
MODAL_SURFACE_STACK (surface) = g_slist_prepend (MODAL_SURFACE_STACK (surface), surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1415,15 +1415,15 @@ gdk_win32_remove_modal_surface (GdkSurface *surface)
|
||||
|
||||
/* It's possible to be NULL here if someone sets the modal hint of the surface
|
||||
* to FALSE before a modal surface stack has ever been created. */
|
||||
if (modal_surface_stack == NULL)
|
||||
if (MODAL_SURFACE_STACK (surface) == NULL)
|
||||
return;
|
||||
|
||||
/* Find the requested surface in the stack and remove it. Yeah, I realize this
|
||||
* means we're not a 'real stack', strictly speaking. Sue me. :) */
|
||||
tmp = g_slist_find (modal_surface_stack, surface);
|
||||
tmp = g_slist_find (MODAL_SURFACE_STACK (surface), surface);
|
||||
if (tmp != NULL)
|
||||
{
|
||||
modal_surface_stack = g_slist_delete_link (modal_surface_stack, tmp);
|
||||
MODAL_SURFACE_STACK (surface) = g_slist_delete_link (MODAL_SURFACE_STACK (surface), tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1433,7 +1433,7 @@ _gdk_modal_blocked (GdkSurface *surface)
|
||||
GSList *l;
|
||||
gboolean found_any = FALSE;
|
||||
|
||||
for (l = modal_surface_stack; l != NULL; l = l->next)
|
||||
for (l = MODAL_SURFACE_STACK (surface); l != NULL; l = l->next)
|
||||
{
|
||||
GdkSurface *modal = l->data;
|
||||
|
||||
@@ -1451,8 +1451,11 @@ GdkSurface *
|
||||
_gdk_modal_current (void)
|
||||
{
|
||||
GSList *l;
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
|
||||
for (l = modal_surface_stack; l != NULL; l = l->next)
|
||||
for (l = GDK_WIN32_DISPLAY (display)->display_surface_record->modal_surface_stack;
|
||||
l != NULL;
|
||||
l = l->next)
|
||||
{
|
||||
GdkSurface *modal = l->data;
|
||||
|
||||
@@ -4134,7 +4137,7 @@ gdk_win32_surface_lookup_for_display (GdkDisplay *display,
|
||||
{
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
||||
|
||||
return (GdkSurface*) gdk_win32_handle_table_lookup_ (anid);
|
||||
return (GdkSurface*) gdk_win32_display_handle_table_lookup_ (display, anid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4519,8 +4522,6 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->constructed = gdk_win32_surface_constructed;
|
||||
object_class->dispose = gdk_surface_win32_dispose;
|
||||
object_class->finalize = gdk_surface_win32_finalize;
|
||||
|
@@ -83,6 +83,9 @@ struct _GdkWin32Drag
|
||||
guint drag_status : 4; /* Current status of drag */
|
||||
guint drop_failed : 1; /* Whether the drop was unsuccessful */
|
||||
guint handle_events : 1; /* Whether handle_event() should do anything */
|
||||
|
||||
/* keep track of thread data for the DnD op, kept in the GdkDisplay that we create, a GdkWin32DndThread structure */
|
||||
void *dnd_thread_items;
|
||||
};
|
||||
|
||||
struct _GdkWin32DragClass
|
||||
@@ -91,9 +94,9 @@ struct _GdkWin32DragClass
|
||||
};
|
||||
|
||||
|
||||
gpointer _gdk_win32_dnd_thread_main (gpointer data);
|
||||
gpointer _gdk_win32_dnd_thread_main (gpointer data);
|
||||
|
||||
GdkDrag *_gdk_win32_find_drag_for_dest_hwnd (HWND dest_hwnd);
|
||||
GdkDrag *gdk_win32_find_drag_for_dest_surface (GdkSurface *surface);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -1,87 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library 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.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkprivate-win32.h"
|
||||
|
||||
static GHashTable *handle_ht = NULL;
|
||||
|
||||
static guint
|
||||
gdk_handle_hash (HANDLE *handle)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return ((guint *) handle)[0] ^ ((guint *) handle)[1];
|
||||
#else
|
||||
return (guint) *handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_handle_equal (HANDLE *a,
|
||||
HANDLE *b)
|
||||
{
|
||||
return (*a == *b);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_handle_table_insert (HANDLE *handle,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_if_fail (handle != NULL);
|
||||
|
||||
if (!handle_ht)
|
||||
handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash,
|
||||
(GEqualFunc) gdk_handle_equal);
|
||||
|
||||
g_hash_table_insert (handle_ht, handle, data);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_handle_table_remove (HANDLE handle)
|
||||
{
|
||||
if (!handle_ht)
|
||||
handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash,
|
||||
(GEqualFunc) gdk_handle_equal);
|
||||
|
||||
g_hash_table_remove (handle_ht, &handle);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gdk_win32_handle_table_lookup_ (HWND handle)
|
||||
{
|
||||
gpointer data = NULL;
|
||||
|
||||
if (handle_ht)
|
||||
data = g_hash_table_lookup (handle_ht, &handle);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gdk_win32_handle_table_lookup (HWND handle)
|
||||
{
|
||||
return gdk_win32_handle_table_lookup_ (handle);
|
||||
}
|
@@ -1,172 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2019 Руслан Ижбулатов <lrn1986@gmail.com>
|
||||
*
|
||||
* This library 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.
|
||||
*
|
||||
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define COBJMACROS
|
||||
#include <msctf.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkprivate-win32.h"
|
||||
|
||||
struct _GdkWin32ALPNSink
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink itf_alpn_sink;
|
||||
|
||||
int ref_count;
|
||||
};
|
||||
|
||||
typedef struct _GdkWin32ALPNSink GdkWin32ALPNSink;
|
||||
|
||||
static GdkWin32ALPNSink *actlangchangenotify = NULL;
|
||||
static ITfSource *itf_source = NULL;
|
||||
static DWORD actlangchangenotify_id = 0;
|
||||
|
||||
static ULONG STDMETHODCALLTYPE
|
||||
alpn_sink_addref (ITfActiveLanguageProfileNotifySink *This)
|
||||
{
|
||||
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
|
||||
int ref_count = ++alpn_sink->ref_count;
|
||||
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE
|
||||
alpn_sink_queryinterface (ITfActiveLanguageProfileNotifySink *This,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObject)
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
|
||||
if (IsEqualGUID (riid, &IID_IUnknown))
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink_AddRef (This);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualGUID (riid, &IID_ITfActiveLanguageProfileNotifySink))
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink_AddRef (This);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE
|
||||
alpn_sink_release (ITfActiveLanguageProfileNotifySink *This)
|
||||
{
|
||||
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
|
||||
int ref_count = --alpn_sink->ref_count;
|
||||
|
||||
if (ref_count == 0)
|
||||
{
|
||||
g_free (This);
|
||||
}
|
||||
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE
|
||||
alpn_sink_on_activated (ITfActiveLanguageProfileNotifySink *This,
|
||||
REFCLSID clsid,
|
||||
REFGUID guidProfile,
|
||||
BOOL fActivated)
|
||||
{
|
||||
_gdk_input_locale_is_ime = fActivated;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ITfActiveLanguageProfileNotifySinkVtbl alpn_sink_vtbl = {
|
||||
alpn_sink_queryinterface,
|
||||
alpn_sink_addref,
|
||||
alpn_sink_release,
|
||||
alpn_sink_on_activated,
|
||||
};
|
||||
|
||||
static GdkWin32ALPNSink *
|
||||
alpn_sink_new ()
|
||||
{
|
||||
GdkWin32ALPNSink *result;
|
||||
|
||||
result = g_new0 (GdkWin32ALPNSink, 1);
|
||||
result->itf_alpn_sink.lpVtbl = &alpn_sink_vtbl;
|
||||
result->ref_count = 0;
|
||||
|
||||
ITfActiveLanguageProfileNotifySink_AddRef (&result->itf_alpn_sink);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gdk_win32_lang_notification_init ()
|
||||
{
|
||||
HRESULT hr;
|
||||
ITfThreadMgr *itf_threadmgr;
|
||||
|
||||
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
if (actlangchangenotify != NULL)
|
||||
return;
|
||||
|
||||
hr = CoCreateInstance (&CLSID_TF_ThreadMgr,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_ITfThreadMgr,
|
||||
(LPVOID *) &itf_threadmgr);
|
||||
|
||||
if (!SUCCEEDED (hr))
|
||||
return;
|
||||
|
||||
hr = ITfThreadMgr_QueryInterface (itf_threadmgr, &IID_ITfSource, (VOID **) &itf_source);
|
||||
ITfThreadMgr_Release (itf_threadmgr);
|
||||
|
||||
if (!SUCCEEDED (hr))
|
||||
return;
|
||||
|
||||
actlangchangenotify = alpn_sink_new ();
|
||||
|
||||
hr = ITfSource_AdviseSink (itf_source,
|
||||
&IID_ITfActiveLanguageProfileNotifySink,
|
||||
(IUnknown *) actlangchangenotify,
|
||||
&actlangchangenotify_id);
|
||||
|
||||
if (!SUCCEEDED (hr))
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink_Release (&actlangchangenotify->itf_alpn_sink);
|
||||
actlangchangenotify = NULL;
|
||||
ITfSource_Release (itf_source);
|
||||
itf_source = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_lang_notification_exit ()
|
||||
{
|
||||
if (actlangchangenotify != NULL && itf_source != NULL)
|
||||
{
|
||||
ITfSource_UnadviseSink (itf_source, actlangchangenotify_id);
|
||||
ITfSource_Release (itf_source);
|
||||
ITfActiveLanguageProfileNotifySink_Release (&actlangchangenotify->itf_alpn_sink);
|
||||
}
|
||||
|
||||
CoUninitialize ();
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* gdkwin32langnotification.h
|
||||
*
|
||||
* Copyright 2019 Руслан Ижбулатов <lrn1986@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void _gdk_win32_lang_notification_init (void);
|
||||
void _gdk_win32_lang_notification_exit (void);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 1998-2002 Tor Lillqvist
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -24,15 +23,273 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <pango/pangowin32.h>
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkprivate-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkwin32.h"
|
||||
|
||||
#include <pango/pangowin32.h>
|
||||
|
||||
struct _GdkWin32ALPNSink
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink itf_alpn_sink;
|
||||
|
||||
int ref_count;
|
||||
guint input_locale_is_ime : 1;
|
||||
};
|
||||
|
||||
typedef struct _GdkWin32ALPNSink GdkWin32ALPNSink;
|
||||
|
||||
struct _GdkWin32InputLocaleItems
|
||||
{
|
||||
/* Input locale items */
|
||||
HKL input_locale;
|
||||
|
||||
/* COM objects to receive language or text service change notifcations in GdkWin32 */
|
||||
GdkWin32ALPNSink *notification_sink;
|
||||
ITfSource *itf_source;
|
||||
DWORD actlangchangenotify_id;
|
||||
|
||||
/* keymap items */
|
||||
GdkKeymap *default_keymap;
|
||||
guint keymap_serial;
|
||||
};
|
||||
|
||||
static guint
|
||||
gdk_handle_hash (HANDLE *handle)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return ((guint *) handle)[0] ^ ((guint *) handle)[1];
|
||||
#else
|
||||
return (guint) *handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_handle_equal (HANDLE *a,
|
||||
HANDLE *b)
|
||||
{
|
||||
return (*a == *b);
|
||||
}
|
||||
|
||||
#define GDK_DISPLAY_HANDLE_HT(d) GDK_WIN32_DISPLAY(d)->display_surface_record->handle_ht
|
||||
|
||||
void
|
||||
gdk_win32_display_handle_table_insert (GdkDisplay *display,
|
||||
HANDLE *handle,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_if_fail (handle != NULL);
|
||||
|
||||
g_hash_table_insert (GDK_DISPLAY_HANDLE_HT (display), handle, data);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_display_handle_table_remove (GdkDisplay *display,
|
||||
HANDLE handle)
|
||||
{
|
||||
g_hash_table_remove (GDK_DISPLAY_HANDLE_HT (display), &handle);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gdk_win32_display_handle_table_lookup_ (GdkDisplay *display,
|
||||
HWND handle)
|
||||
{
|
||||
gpointer data = NULL;
|
||||
if (display == NULL)
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
data = g_hash_table_lookup (GDK_DISPLAY_HANDLE_HT (display), &handle);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gdk_win32_handle_table_lookup (HWND handle)
|
||||
{
|
||||
return gdk_win32_display_handle_table_lookup_ (NULL, handle);
|
||||
}
|
||||
|
||||
/* set up input language or text service change notification for our GdkDisplay */
|
||||
|
||||
/* COM implementation for receiving notifications when input language or text service has changed in GDK */
|
||||
static ULONG STDMETHODCALLTYPE
|
||||
alpn_sink_addref (ITfActiveLanguageProfileNotifySink *This)
|
||||
{
|
||||
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
|
||||
int ref_count = ++alpn_sink->ref_count;
|
||||
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE
|
||||
alpn_sink_queryinterface (ITfActiveLanguageProfileNotifySink *This,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObject)
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
|
||||
if (IsEqualGUID (riid, &IID_IUnknown))
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink_AddRef (This);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualGUID (riid, &IID_ITfActiveLanguageProfileNotifySink))
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink_AddRef (This);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE
|
||||
alpn_sink_release (ITfActiveLanguageProfileNotifySink *This)
|
||||
{
|
||||
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
|
||||
int ref_count = --alpn_sink->ref_count;
|
||||
|
||||
if (ref_count == 0)
|
||||
{
|
||||
g_free (This);
|
||||
}
|
||||
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE
|
||||
alpn_sink_on_activated (ITfActiveLanguageProfileNotifySink *This,
|
||||
REFCLSID clsid,
|
||||
REFGUID guidProfile,
|
||||
BOOL fActivated)
|
||||
{
|
||||
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
|
||||
|
||||
alpn_sink->input_locale_is_ime = fActivated;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const ITfActiveLanguageProfileNotifySinkVtbl alpn_sink_vtbl = {
|
||||
alpn_sink_queryinterface,
|
||||
alpn_sink_addref,
|
||||
alpn_sink_release,
|
||||
alpn_sink_on_activated,
|
||||
};
|
||||
|
||||
void
|
||||
gdk_win32_display_lang_notification_init (GdkWin32Display *display)
|
||||
{
|
||||
HRESULT hr;
|
||||
ITfThreadMgr *itf_threadmgr;
|
||||
|
||||
if (display->input_locale_items == NULL)
|
||||
display->input_locale_items = g_new0 (GdkWin32InputLocaleItems, 1);
|
||||
|
||||
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
if (display->input_locale_items->notification_sink != NULL)
|
||||
return;
|
||||
|
||||
hr = CoCreateInstance (&CLSID_TF_ThreadMgr,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_ITfThreadMgr,
|
||||
(LPVOID *) &itf_threadmgr);
|
||||
|
||||
if (!SUCCEEDED (hr))
|
||||
return;
|
||||
|
||||
hr = ITfThreadMgr_QueryInterface (itf_threadmgr, &IID_ITfSource, (VOID **) &display->input_locale_items->itf_source);
|
||||
ITfThreadMgr_Release (itf_threadmgr);
|
||||
|
||||
if (!SUCCEEDED (hr))
|
||||
return;
|
||||
|
||||
display->input_locale_items->notification_sink = g_new0 (GdkWin32ALPNSink, 1);
|
||||
display->input_locale_items->notification_sink->itf_alpn_sink.lpVtbl = &alpn_sink_vtbl;
|
||||
display->input_locale_items->notification_sink->ref_count = 0;
|
||||
ITfActiveLanguageProfileNotifySink_AddRef (&display->input_locale_items->notification_sink->itf_alpn_sink);
|
||||
|
||||
hr = ITfSource_AdviseSink (display->input_locale_items->itf_source,
|
||||
&IID_ITfActiveLanguageProfileNotifySink,
|
||||
(IUnknown *) display->input_locale_items->notification_sink,
|
||||
&display->input_locale_items->actlangchangenotify_id);
|
||||
|
||||
if (!SUCCEEDED (hr))
|
||||
{
|
||||
ITfActiveLanguageProfileNotifySink_Release (&display->input_locale_items->notification_sink->itf_alpn_sink);
|
||||
display->input_locale_items->notification_sink = NULL;
|
||||
ITfSource_Release (display->input_locale_items->itf_source);
|
||||
display->input_locale_items->itf_source = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_display_lang_notification_exit (GdkWin32Display *display)
|
||||
{
|
||||
if (display->input_locale_items->notification_sink != NULL && display->input_locale_items->itf_source != NULL)
|
||||
{
|
||||
ITfSource_UnadviseSink (display->input_locale_items->itf_source, display->input_locale_items->actlangchangenotify_id);
|
||||
ITfSource_Release (display->input_locale_items->itf_source);
|
||||
ITfActiveLanguageProfileNotifySink_Release (&display->input_locale_items->notification_sink->itf_alpn_sink);
|
||||
}
|
||||
|
||||
CoUninitialize ();
|
||||
|
||||
g_clear_pointer (&display->input_locale_items->default_keymap, g_object_unref);
|
||||
g_free (display->input_locale_items->notification_sink);
|
||||
g_free (display->input_locale_items);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_display_set_input_locale (GdkWin32Display *display,
|
||||
HKL input_locale)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_WIN32_DISPLAY (display));
|
||||
display->input_locale_items->input_locale = input_locale;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_win32_display_input_locale_is_ime (GdkWin32Display *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), FALSE);
|
||||
|
||||
return display->input_locale_items->notification_sink->input_locale_is_ime;
|
||||
}
|
||||
|
||||
GdkKeymap *
|
||||
gdk_win32_display_get_default_keymap (GdkWin32Display *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), NULL);
|
||||
|
||||
if (display->input_locale_items->default_keymap == NULL)
|
||||
{
|
||||
display->input_locale_items->default_keymap =
|
||||
g_object_new (GDK_TYPE_WIN32_KEYMAP,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return display->input_locale_items->default_keymap;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_display_increment_keymap_serial (GdkWin32Display *display)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_WIN32_DISPLAY (display));
|
||||
|
||||
display->input_locale_items->keymap_serial++;
|
||||
}
|
||||
|
||||
guint
|
||||
gdk_win32_display_get_keymap_serial (GdkWin32Display *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), 0);
|
||||
|
||||
return display->input_locale_items->keymap_serial;
|
||||
}
|
||||
|
||||
static char *
|
||||
_get_system_font_name (HDC hdc)
|
||||
@@ -61,9 +318,13 @@ _get_system_font_name (HDC hdc)
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_win32_get_setting (const char *name,
|
||||
GValue *value)
|
||||
gdk_win32_display_get_setting (GdkDisplay *display,
|
||||
const char *name,
|
||||
GValue *value)
|
||||
{
|
||||
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_DEFAULT_SETTINGS)
|
||||
return FALSE;
|
||||
|
||||
if (strcmp ("gtk-alternative-button-order", name) == 0)
|
||||
{
|
||||
GDK_NOTE(MISC, g_print("gdk_display_get_setting(\"%s\") : TRUE\n", name));
|
||||
@@ -145,7 +406,7 @@ _gdk_win32_get_setting (const char *name,
|
||||
}
|
||||
else if (strcmp ("gtk-im-module", name) == 0)
|
||||
{
|
||||
const char *im_module = _gdk_input_locale_is_ime ? "ime" : "";
|
||||
const char *im_module = GDK_WIN32_DISPLAY (display)->input_locale_items->notification_sink->input_locale_is_ime ? "ime" : "";
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, im_module));
|
||||
g_value_set_static_string (value, im_module);
|
||||
return TRUE;
|
||||
@@ -203,10 +464,10 @@ _gdk_win32_get_setting (const char *name,
|
||||
}
|
||||
else if (strcmp ("gtk-xft-dpi", name) == 0)
|
||||
{
|
||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
if (display->dpi_aware_type == PROCESS_SYSTEM_DPI_AWARE &&
|
||||
!display->has_fixed_scale)
|
||||
if (display_win32->dpi_aware_type == PROCESS_SYSTEM_DPI_AWARE &&
|
||||
!display_win32->has_fixed_scale)
|
||||
{
|
||||
HDC hdc = GetDC (NULL);
|
||||
|
||||
@@ -217,7 +478,7 @@ _gdk_win32_get_setting (const char *name,
|
||||
|
||||
if (dpi >= 96)
|
||||
{
|
||||
int xft_dpi = 1024 * dpi / display->surface_scale;
|
||||
int xft_dpi = 1024 * dpi / display_win32->surface_scale;
|
||||
GDK_NOTE(MISC, g_print ("gdk_screen_get_setting(\"%s\") : %d\n", name, xft_dpi));
|
||||
g_value_set_int (value, xft_dpi);
|
||||
return TRUE;
|
||||
@@ -258,3 +519,4 @@ _gdk_win32_get_setting (const char *name,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ gdk_win32_public_sources = files([
|
||||
'gdkdrag-win32.c',
|
||||
'gdkglcontext-win32.c',
|
||||
'gdkglcontext-win32-wgl.c',
|
||||
'gdkwin32id.c',
|
||||
'gdkwin32misc.c',
|
||||
'gdksurface-win32.c',
|
||||
'gdkevents-win32.c',
|
||||
'gdkmonitor-win32.c',
|
||||
@@ -22,7 +22,6 @@ gdk_win32_sources = gdk_win32_public_sources + files([
|
||||
'gdkdevice-winpointer.c',
|
||||
'gdkdevice-wintab.c',
|
||||
'gdkdrop-win32.c',
|
||||
'gdkglobals-win32.c',
|
||||
'gdkglcontext-win32-wgl-private.c',
|
||||
'gdkhdataoutputstream-win32.c',
|
||||
'gdkinput-dmanipulation.c',
|
||||
@@ -30,9 +29,7 @@ gdk_win32_sources = gdk_win32_public_sources + files([
|
||||
'gdkkeys-win32.c',
|
||||
'gdkkeys-win32-impl.c',
|
||||
'gdkkeys-win32-impl-wow64.c',
|
||||
'gdkwin32langnotification.c',
|
||||
'gdkmain-win32.c',
|
||||
'gdkproperty-win32.c',
|
||||
'gdkvulkancontext-win32.c',
|
||||
'gdkwin32cursor.h',
|
||||
'gdkwin32display.h',
|
||||
|
@@ -3225,8 +3225,7 @@ gsk_gpu_node_processor_repeat_tile (GskGpuNodeProcessor *self,
|
||||
- y * child_bounds->size.height));
|
||||
if (!gsk_rect_intersection (&offset_rect, child_bounds, &clipped_child_bounds))
|
||||
{
|
||||
/* The math has gone wrong probably, someone should look at this. */
|
||||
g_warn_if_reached ();
|
||||
/* rounding error hits again */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -68,8 +68,8 @@ gtk_accessible_text_default_get_default_attributes (GtkAccessibleText *self,
|
||||
char ***attribute_names,
|
||||
char ***attribute_values)
|
||||
{
|
||||
*attribute_names = NULL;
|
||||
*attribute_values = NULL;
|
||||
*attribute_names = g_new0 (char *, 1);
|
||||
*attribute_values = g_new0 (char *, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -289,10 +289,7 @@ gtk_accessible_text_get_attributes (GtkAccessibleText *self,
|
||||
* - a name, typically in the form of a reverse DNS identifier
|
||||
* - a value
|
||||
*
|
||||
* If this function returns true, `n_attributes` will be set to a value
|
||||
* greater than or equal to one, @ranges will be set to a newly
|
||||
* allocated array of [struct#Gtk.AccessibleTextRange] which should
|
||||
* be freed with g_free(), @attribute_names and @attribute_values
|
||||
* If this function returns true, @attribute_names and @attribute_values
|
||||
* will be set to string arrays that should be freed with g_strfreev().
|
||||
*
|
||||
* Since: 4.14
|
||||
|
@@ -160,7 +160,7 @@ GType gtk_application_impl_quartz_get_type (void);
|
||||
GtkApplicationImpl * gtk_application_impl_new (GtkApplication *application,
|
||||
GdkDisplay *display);
|
||||
void gtk_application_impl_startup (GtkApplicationImpl *impl,
|
||||
gboolean register_sesion);
|
||||
gboolean register_session);
|
||||
void gtk_application_impl_shutdown (GtkApplicationImpl *impl);
|
||||
void gtk_application_impl_before_emit (GtkApplicationImpl *impl,
|
||||
GVariant *platform_data);
|
||||
|
@@ -1267,9 +1267,9 @@ gtk_css_provider_load_internal (GtkCssProvider *self,
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
const char *uri G_GNUC_UNUSED;
|
||||
uri = file ? g_file_peek_path (file) : NULL;
|
||||
gdk_profiler_end_mark (before, "CSS theme load", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -191,10 +191,12 @@ gtk_list_factory_widget_update (GtkListItemBase *base,
|
||||
|
||||
if (priv->object)
|
||||
{
|
||||
gpointer old_item = gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self));
|
||||
|
||||
gtk_list_item_factory_update (priv->factory,
|
||||
priv->object,
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
item != NULL,
|
||||
item != old_item && old_item != NULL,
|
||||
item != old_item && item != NULL,
|
||||
gtk_list_factory_widget_update_func,
|
||||
&update);
|
||||
}
|
||||
|
@@ -875,6 +875,8 @@ gtk_picture_set_paintable (GtkPicture *self,
|
||||
|
||||
if (size_changed)
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
else
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PAINTABLE]);
|
||||
|
||||
|
158
po/sl.po
158
po/sl.po
@@ -11,8 +11,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gtk+ master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
|
||||
"POT-Creation-Date: 2024-09-17 05:42+0000\n"
|
||||
"PO-Revision-Date: 2024-09-17 17:21+0200\n"
|
||||
"POT-Creation-Date: 2024-10-05 13:38+0000\n"
|
||||
"PO-Revision-Date: 2024-10-05 20:36+0200\n"
|
||||
"Last-Translator: Martin Srebotnjak <miles@filmsi.net>\n"
|
||||
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
|
||||
"Language: sl_SI\n"
|
||||
@@ -72,35 +72,35 @@ msgstr "Ni mogoče določiti vsebine kot »%s«."
|
||||
msgid "Cannot provide contents as %s"
|
||||
msgstr "Ni mogoče določiti vsebine kot %s."
|
||||
|
||||
#: gdk/gdkdisplay.c:176 gdk/gdkglcontext.c:472
|
||||
#: gdk/gdkdisplay.c:176 gdk/gdkglcontext.c:469
|
||||
msgid "The current backend does not support OpenGL"
|
||||
msgstr "Trenutno zagnan ozadnji program ne podpira OpenGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1315 gdk/gdkvulkancontext.c:1668
|
||||
#: gdk/gdkdisplay.c:1317 gdk/gdkvulkancontext.c:1634
|
||||
msgid "Vulkan support disabled via GDK_DISABLE"
|
||||
msgstr "Podpora Vulkan je onemogočena z GDK_DISABLE"
|
||||
|
||||
#: gdk/gdkdisplay.c:1369
|
||||
#: gdk/gdkdisplay.c:1371
|
||||
msgid "OpenGL support disabled via GDK_DISABLE"
|
||||
msgstr "Podpora OpenGL je onemogočena z GDK_DISABLE"
|
||||
|
||||
#: gdk/gdkdisplay.c:1683
|
||||
#: gdk/gdkdisplay.c:1685
|
||||
msgid "No EGL configuration available"
|
||||
msgstr "Nastavitve EGL niso na voljo"
|
||||
|
||||
#: gdk/gdkdisplay.c:1691
|
||||
#: gdk/gdkdisplay.c:1693
|
||||
msgid "Failed to get EGL configurations"
|
||||
msgstr "Pridobivanje nastavitev EGL je sodletelo"
|
||||
|
||||
#: gdk/gdkdisplay.c:1721
|
||||
#: gdk/gdkdisplay.c:1723
|
||||
msgid "No EGL configuration with required features found"
|
||||
msgstr "Ni mogoče najti nastavitev EGL za zahtevane možnosti"
|
||||
|
||||
#: gdk/gdkdisplay.c:1728
|
||||
#: gdk/gdkdisplay.c:1730
|
||||
msgid "No perfect EGL configuration found"
|
||||
msgstr "Nastavitve EGL ni mogoče najti"
|
||||
|
||||
#: gdk/gdkdisplay.c:1770
|
||||
#: gdk/gdkdisplay.c:1772
|
||||
#, c-format
|
||||
msgid "EGL implementation is missing extension %s"
|
||||
msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
|
||||
@@ -109,23 +109,23 @@ msgstr[1] "Vstavku EGL manjka %2$d razširitev: %1$s"
|
||||
msgstr[2] "Vstavku EGL manjkata %2$d razširitvi: %1$s"
|
||||
msgstr[3] "Vstavku EGL manjkajo %2$d razširitve: %1$s"
|
||||
|
||||
#: gdk/gdkdisplay.c:1819
|
||||
#: gdk/gdkdisplay.c:1821
|
||||
msgid "libEGL not available in this sandbox"
|
||||
msgstr "Sandbox ne podpira knjižnice libEGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1820
|
||||
#: gdk/gdkdisplay.c:1822
|
||||
msgid "libEGL not available"
|
||||
msgstr "Knjižnica libEL ni na voljo"
|
||||
|
||||
#: gdk/gdkdisplay.c:1830
|
||||
#: gdk/gdkdisplay.c:1832
|
||||
msgid "Failed to create EGL display"
|
||||
msgstr "Ustvarjanje zaslona EGL je sodletelo"
|
||||
|
||||
#: gdk/gdkdisplay.c:1839
|
||||
#: gdk/gdkdisplay.c:1841
|
||||
msgid "Could not initialize EGL display"
|
||||
msgstr "Ni mogoče začeti zaslona EGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1849
|
||||
#: gdk/gdkdisplay.c:1851
|
||||
#, c-format
|
||||
msgid "EGL version %d.%d is too old. GTK requires %d.%d"
|
||||
msgstr "Različica EGL %d.%d je prestara, Oklje GTK zahteva različico %d.%d"
|
||||
@@ -138,25 +138,25 @@ msgstr "Funkcija Poteg/Spust iz drugih programov ni podprta."
|
||||
msgid "No compatible formats to transfer contents."
|
||||
msgstr "Ni skladnih zapisov za prenos vsebine."
|
||||
|
||||
#: gdk/gdkglcontext.c:432 gdk/x11/gdkglcontext-glx.c:651
|
||||
#: gdk/gdkglcontext.c:429 gdk/x11/gdkglcontext-glx.c:651
|
||||
msgid "No GL API allowed."
|
||||
msgstr "API GL ni dovoljen."
|
||||
|
||||
#: gdk/gdkglcontext.c:455 gdk/win32/gdkglcontext-win32-wgl.c:723
|
||||
#: gdk/gdkglcontext.c:452 gdk/win32/gdkglcontext-win32-wgl.c:723
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:866
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:910 gdk/x11/gdkglcontext-glx.c:697
|
||||
msgid "Unable to create a GL context"
|
||||
msgstr "Ni mogoče ustvariti vsebine GL"
|
||||
|
||||
#: gdk/gdkglcontext.c:1340
|
||||
#: gdk/gdkglcontext.c:1330
|
||||
msgid "OpenGL ES API disabled via GDK_DISABLE"
|
||||
msgstr "Podpora OpenGL ES API je onemogočena z GDK_DISABLE"
|
||||
|
||||
#: gdk/gdkglcontext.c:1352
|
||||
#: gdk/gdkglcontext.c:1342
|
||||
msgid "OpenGL API disabled via GDK_DISABLE"
|
||||
msgstr "Podpora OpenGL API je onemogočena z GDK_DISABLE"
|
||||
|
||||
#: gdk/gdkglcontext.c:1363
|
||||
#: gdk/gdkglcontext.c:1353
|
||||
#, c-format
|
||||
msgid "Application does not support %s API"
|
||||
msgstr "Program ne podpira vmesnika API %s"
|
||||
@@ -164,12 +164,12 @@ msgstr "Program ne podpira vmesnika API %s"
|
||||
#. translators: This is about OpenGL backend names, like
|
||||
#. * "Trying to use X11 GLX, but EGL is already in use"
|
||||
#.
|
||||
#: gdk/gdkglcontext.c:2175
|
||||
#: gdk/gdkglcontext.c:2132
|
||||
#, c-format
|
||||
msgid "Trying to use %s, but %s is already in use"
|
||||
msgstr "Podana je zahteva za uporabo %s, a je %s že v uporabi."
|
||||
|
||||
#: gdk/gdkglcontext.c:2186
|
||||
#: gdk/gdkglcontext.c:2143
|
||||
#, c-format
|
||||
msgid "Trying to use %s, but it is disabled via GDK_DISABLE"
|
||||
msgstr "Poskus uporabe %s, vendar je onemogočeno prek GDK_DISABLE"
|
||||
@@ -603,8 +603,8 @@ msgstr "Ni mogoče naložiti podatkov slike TIFF"
|
||||
msgid "Reading data failed at row %d"
|
||||
msgstr "Ni mogoče pridobiti podatkov v vrstici %d"
|
||||
|
||||
#: gdk/macos/gdkmacospasteboard.c:211 gdk/wayland/gdkclipboard-wayland.c:238
|
||||
#: gdk/wayland/gdkdrop-wayland.c:205 gdk/wayland/gdkprimary-wayland.c:337
|
||||
#: gdk/macos/gdkmacospasteboard.c:211 gdk/wayland/gdkclipboard-wayland.c:244
|
||||
#: gdk/wayland/gdkdrop-wayland.c:205 gdk/wayland/gdkprimary-wayland.c:343
|
||||
#: gdk/win32/gdkdrop-win32.c:1018 gdk/win32/gdkdrop-win32.c:1067
|
||||
#: gdk/x11/gdkclipboard-x11.c:799 gdk/x11/gdkdrop-x11.c:235
|
||||
msgid "No compatible transfer format found"
|
||||
@@ -886,17 +886,12 @@ msgstr "Neveljavni zapisi pri sestavljeni pretvorbi besedila."
|
||||
msgid "Unsupported encoding “%s”"
|
||||
msgstr "Nepodprto kodiranje »%s«."
|
||||
|
||||
#: gsk/gl/gskglrenderer.c:215
|
||||
#, c-format
|
||||
msgid "This GLES %d.%d implementation does not support half-float vertex data"
|
||||
msgstr "Sistem GLES %d.%d ne podpira pol-plavajočih podatkov"
|
||||
|
||||
#: gsk/gpu/gskgldevice.c:252
|
||||
#: gsk/gpu/gskgldevice.c:253
|
||||
#, c-format
|
||||
msgid "OpenGL ES 3.0 is not supported by this renderer."
|
||||
msgstr "Izrisovalnik ne podpira OpenGL ES 3.0"
|
||||
|
||||
#: gsk/gpu/gsknglrenderer.c:68
|
||||
#: gsk/gpu/gsknglrenderer.c:66
|
||||
msgid "OpenGL 3.3 required"
|
||||
msgstr "Potrebujete OpenGL 3.3"
|
||||
|
||||
@@ -2398,7 +2393,7 @@ msgid "If you delete an item, it will be permanently lost."
|
||||
msgstr "V primeru, da predmet izbrišete, bo trajno izgubljen."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1213 gtk/gtkfilechooserwidget.c:1815
|
||||
#: gtk/gtklabel.c:5883 gtk/gtktext.c:6334 gtk/gtktextview.c:9237
|
||||
#: gtk/gtklabel.c:5888 gtk/gtktext.c:6334 gtk/gtktextview.c:9237
|
||||
msgid "_Delete"
|
||||
msgstr "_Izbriši"
|
||||
|
||||
@@ -2737,31 +2732,31 @@ msgstr "Zapri"
|
||||
msgid "Close the infobar"
|
||||
msgstr "Zapri vrstico podrobnosti"
|
||||
|
||||
#: gtk/gtklabel.c:5880 gtk/gtktext.c:6322 gtk/gtktextview.c:9225
|
||||
#: gtk/gtklabel.c:5885 gtk/gtktext.c:6322 gtk/gtktextview.c:9225
|
||||
msgid "Cu_t"
|
||||
msgstr "Iz_reži"
|
||||
|
||||
#: gtk/gtklabel.c:5881 gtk/gtktext.c:6326 gtk/gtktextview.c:9229
|
||||
#: gtk/gtklabel.c:5886 gtk/gtktext.c:6326 gtk/gtktextview.c:9229
|
||||
msgid "_Copy"
|
||||
msgstr "_Kopiraj"
|
||||
|
||||
#: gtk/gtklabel.c:5882 gtk/gtktext.c:6330 gtk/gtktextview.c:9233
|
||||
#: gtk/gtklabel.c:5887 gtk/gtktext.c:6330 gtk/gtktextview.c:9233
|
||||
msgid "_Paste"
|
||||
msgstr "Pr_ilepi"
|
||||
|
||||
#: gtk/gtklabel.c:5888 gtk/gtktext.c:6343 gtk/gtktextview.c:9258
|
||||
#: gtk/gtklabel.c:5893 gtk/gtktext.c:6343 gtk/gtktextview.c:9258
|
||||
msgid "Select _All"
|
||||
msgstr "Izberi _vse"
|
||||
|
||||
#: gtk/gtklabel.c:5893
|
||||
#: gtk/gtklabel.c:5898
|
||||
msgid "_Open Link"
|
||||
msgstr "_Odpri povezavo"
|
||||
|
||||
#: gtk/gtklabel.c:5897
|
||||
#: gtk/gtklabel.c:5902
|
||||
msgid "Copy _Link Address"
|
||||
msgstr "Kopiraj _naslov povezave"
|
||||
|
||||
#: gtk/gtklabel.c:5941 gtk/gtktext.c:2851 gtk/gtktextview.c:9307
|
||||
#: gtk/gtklabel.c:5946 gtk/gtktext.c:2851 gtk/gtktextview.c:9307
|
||||
msgid "Context menu"
|
||||
msgstr "Vsebinski meni"
|
||||
|
||||
@@ -3357,89 +3352,89 @@ msgstr "Ni na voljo"
|
||||
#. * jobs. %s gets replaced by the application name, %d gets replaced
|
||||
#. * by the job number.
|
||||
#.
|
||||
#: gtk/print/gtkprintoperation.c:252
|
||||
#: gtk/print/gtkprintoperation.c:255
|
||||
#, c-format
|
||||
msgid "%s job #%d"
|
||||
msgstr "%s - posel št. %d"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1699
|
||||
#: gtk/print/gtkprintoperation.c:1702
|
||||
msgctxt "print operation status"
|
||||
msgid "Initial state"
|
||||
msgstr "Začetno stanje"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1700
|
||||
#: gtk/print/gtkprintoperation.c:1703
|
||||
msgctxt "print operation status"
|
||||
msgid "Preparing to print"
|
||||
msgstr "Priprava na tiskanje"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1701
|
||||
#: gtk/print/gtkprintoperation.c:1704
|
||||
msgctxt "print operation status"
|
||||
msgid "Generating data"
|
||||
msgstr "Ustvarjanje podatkov"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1702
|
||||
#: gtk/print/gtkprintoperation.c:1705
|
||||
msgctxt "print operation status"
|
||||
msgid "Sending data"
|
||||
msgstr "Pošiljanje podatkov"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1703
|
||||
#: gtk/print/gtkprintoperation.c:1706
|
||||
msgctxt "print operation status"
|
||||
msgid "Waiting"
|
||||
msgstr "Čakanje"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1704
|
||||
#: gtk/print/gtkprintoperation.c:1707
|
||||
msgctxt "print operation status"
|
||||
msgid "Blocking on issue"
|
||||
msgstr "Blokirano zaradi napake"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1705
|
||||
#: gtk/print/gtkprintoperation.c:1708
|
||||
msgctxt "print operation status"
|
||||
msgid "Printing"
|
||||
msgstr "Tiskanje"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1706
|
||||
#: gtk/print/gtkprintoperation.c:1709
|
||||
msgctxt "print operation status"
|
||||
msgid "Finished"
|
||||
msgstr "Končano"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:1707
|
||||
#: gtk/print/gtkprintoperation.c:1710
|
||||
msgctxt "print operation status"
|
||||
msgid "Finished with error"
|
||||
msgstr "Končano z napako"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:2250
|
||||
#: gtk/print/gtkprintoperation.c:2254
|
||||
#, c-format
|
||||
msgid "Preparing %d"
|
||||
msgstr "Pripravljanje %d"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:2252 gtk/print/gtkprintoperation.c:2871
|
||||
#: gtk/print/gtkprintoperation.c:2256 gtk/print/gtkprintoperation.c:2875
|
||||
#, c-format
|
||||
msgid "Preparing"
|
||||
msgstr "Pripravljanje"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:2255
|
||||
#: gtk/print/gtkprintoperation.c:2259
|
||||
#, c-format
|
||||
msgid "Printing %d"
|
||||
msgstr "Tiskanje %d"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:2904
|
||||
#: gtk/print/gtkprintoperation.c:2908
|
||||
#, c-format
|
||||
msgid "Error creating print preview"
|
||||
msgstr "Napaka med ustvarjanjem predogleda tiskanja"
|
||||
|
||||
#: gtk/print/gtkprintoperation.c:2907
|
||||
#: gtk/print/gtkprintoperation.c:2911
|
||||
#, c-format
|
||||
msgid "The most probable reason is that a temporary file could not be created."
|
||||
msgstr "Najverjetnejši razlog je, da začasne datoteke ni mogoče ustvariti"
|
||||
|
||||
#. window
|
||||
#: gtk/print/gtkprintoperation-portal.c:264
|
||||
#: gtk/print/gtkprintoperation-portal.c:594
|
||||
#: gtk/print/gtkprintoperation-portal.c:663 gtk/print/gtkprintunixdialog.c:3015
|
||||
#: gtk/print/gtkprintoperation-portal.c:273
|
||||
#: gtk/print/gtkprintoperation-portal.c:603
|
||||
#: gtk/print/gtkprintoperation-portal.c:672 gtk/print/gtkprintunixdialog.c:3015
|
||||
msgid "Print"
|
||||
msgstr "Natisni"
|
||||
|
||||
#: gtk/print/gtkprintoperation-unix.c:481
|
||||
#: gtk/print/gtkprintoperation-unix.c:490
|
||||
#: gtk/print/gtkprintoperation-win32.c:1505
|
||||
msgid "Application"
|
||||
msgstr "Program"
|
||||
@@ -3695,7 +3690,7 @@ msgstr "Ni zadetkov"
|
||||
msgid "Try a different search"
|
||||
msgstr "Poskusite drugačno iskanje"
|
||||
|
||||
#: gtk/gtkstacksidebar.c:154
|
||||
#: gtk/gtkstacksidebar.c:155
|
||||
msgctxt "accessibility"
|
||||
msgid "Sidebar"
|
||||
msgstr "Stranska vrstica"
|
||||
@@ -3812,17 +3807,17 @@ msgstr "Pokaži"
|
||||
msgid "Hover to load"
|
||||
msgstr "Naloži ob prehodu"
|
||||
|
||||
#: gtk/inspector/clipboard.c:278
|
||||
#: gtk/inspector/clipboard.c:286
|
||||
msgctxt "clipboard"
|
||||
msgid "empty"
|
||||
msgstr "prazno"
|
||||
|
||||
#: gtk/inspector/clipboard.c:283 gtk/inspector/clipboard.c:325
|
||||
#: gtk/inspector/clipboard.c:291 gtk/inspector/clipboard.c:344
|
||||
msgctxt "clipboard"
|
||||
msgid "local"
|
||||
msgstr "krajevno"
|
||||
|
||||
#: gtk/inspector/clipboard.c:285 gtk/inspector/clipboard.c:327
|
||||
#: gtk/inspector/clipboard.c:293 gtk/inspector/clipboard.c:346
|
||||
msgctxt "clipboard"
|
||||
msgid "remote"
|
||||
msgstr "oddaljeno"
|
||||
@@ -4253,7 +4248,7 @@ msgstr "Vir:"
|
||||
msgid "Defined At"
|
||||
msgstr "Določeno pri"
|
||||
|
||||
#: gtk/inspector/recorder.c:2021
|
||||
#: gtk/inspector/recorder.c:2022
|
||||
#, c-format
|
||||
msgid "Saving RenderNode failed"
|
||||
msgstr "Shranjevanje izrisovanja vozlišča je spodletelo"
|
||||
@@ -4306,7 +4301,7 @@ msgstr "Ime:"
|
||||
msgid "Type:"
|
||||
msgstr "Vrsta:"
|
||||
|
||||
#: gtk/inspector/resource-list.ui:164 tools/gtk-image-tool-info.c:54
|
||||
#: gtk/inspector/resource-list.ui:164 tools/gtk-image-tool-info.c:56
|
||||
msgid "Size:"
|
||||
msgstr "Velikost:"
|
||||
|
||||
@@ -7163,35 +7158,35 @@ msgctxt "printer option value"
|
||||
msgid "Unavailable"
|
||||
msgstr "Ni na voljo"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:238
|
||||
#: modules/printbackends/gtkprintbackendfile.c:263
|
||||
msgid "output"
|
||||
msgstr "odvod"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:510
|
||||
#: modules/printbackends/gtkprintbackendfile.c:543
|
||||
msgid "Print to File"
|
||||
msgstr "Natisni v datoteko"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:636
|
||||
#: modules/printbackends/gtkprintbackendfile.c:675
|
||||
msgid "PDF"
|
||||
msgstr "PDF"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:636
|
||||
#: modules/printbackends/gtkprintbackendfile.c:675
|
||||
msgid "PostScript"
|
||||
msgstr "PostScript"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:636
|
||||
#: modules/printbackends/gtkprintbackendfile.c:675
|
||||
msgid "SVG"
|
||||
msgstr "SVG"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:649
|
||||
#: modules/printbackends/gtkprintbackendfile.c:688
|
||||
msgid "Pages per _sheet:"
|
||||
msgstr "Strani na _list:"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:709
|
||||
#: modules/printbackends/gtkprintbackendfile.c:758
|
||||
msgid "File"
|
||||
msgstr "Datoteka"
|
||||
|
||||
#: modules/printbackends/gtkprintbackendfile.c:719
|
||||
#: modules/printbackends/gtkprintbackendfile.c:768
|
||||
msgid "_Output format"
|
||||
msgstr "_Izhodni zapis"
|
||||
|
||||
@@ -7273,7 +7268,7 @@ msgstr ""
|
||||
#: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179
|
||||
#: tools/gtk-builder-tool-preview.c:180 tools/gtk-builder-tool-screenshot.c:360
|
||||
#: tools/gtk-builder-tool-simplify.c:2623 tools/gtk-builder-tool-validate.c:261
|
||||
#: tools/gtk-image-tool-compare.c:43 tools/gtk-image-tool-info.c:68
|
||||
#: tools/gtk-image-tool-compare.c:43 tools/gtk-image-tool-info.c:79
|
||||
#: tools/gtk-path-tool-render.c:121 tools/gtk-rendernode-tool-compare.c:67
|
||||
#: tools/gtk-rendernode-tool-extract.c:294 tools/gtk-rendernode-tool-info.c:226
|
||||
#: tools/gtk-rendernode-tool-show.c:116
|
||||
@@ -7526,7 +7521,7 @@ msgid "Compare two images"
|
||||
msgstr "Primerjaj sliki"
|
||||
|
||||
#: tools/gtk-image-tool-compare.c:70 tools/gtk-image-tool-convert.c:113
|
||||
#: tools/gtk-image-tool-info.c:90 tools/gtk-image-tool-relabel.c:109
|
||||
#: tools/gtk-image-tool-info.c:101 tools/gtk-image-tool-relabel.c:109
|
||||
#: tools/gtk-image-tool-show.c:141
|
||||
#, c-format
|
||||
msgid "No image file specified\n"
|
||||
@@ -7627,19 +7622,24 @@ msgstr "Ni mogoče hkrati določiti --color-state in --cicp\n"
|
||||
msgid "Not a supported cicp tuple: %s\n"
|
||||
msgstr "Ni podprti n-terec cicp: %s\n"
|
||||
|
||||
#: tools/gtk-image-tool-info.c:55
|
||||
#: tools/gtk-image-tool-info.c:57
|
||||
msgid "Format:"
|
||||
msgstr "Oblika zapisa:"
|
||||
|
||||
#: tools/gtk-image-tool-info.c:56
|
||||
#: tools/gtk-image-tool-info.c:63 tools/gtk-image-tool-info.c:65
|
||||
#: tools/gtk-image-tool-info.c:67
|
||||
msgid "Color state:"
|
||||
msgstr "Barvno stanje:"
|
||||
|
||||
#: tools/gtk-image-tool-info.c:77
|
||||
#: tools/gtk-image-tool-info.c:67
|
||||
msgid "unknown"
|
||||
msgstr "neznano"
|
||||
|
||||
#: tools/gtk-image-tool-info.c:88
|
||||
msgid "Provide information about the image."
|
||||
msgstr "Navedite podatke o sliki."
|
||||
|
||||
#: tools/gtk-image-tool-info.c:96
|
||||
#: tools/gtk-image-tool-info.c:107
|
||||
#, c-format
|
||||
msgid "Can only accept a single image file\n"
|
||||
msgstr "Lahko sprejme samo eno slikovno datoteko\n"
|
||||
@@ -7665,7 +7665,7 @@ msgstr "Ne dodaj vrstice naziva"
|
||||
msgid "Show one or more images."
|
||||
msgstr "Prikažite eno ali več slik."
|
||||
|
||||
#: tools/gtk-image-tool-utils.c:234
|
||||
#: tools/gtk-image-tool-utils.c:255
|
||||
#, c-format
|
||||
msgid "cicp must be 4 numbers, separated by /\n"
|
||||
msgstr "CICP mora biti sestavljen iz 4 števk, ločenih z /\n"
|
||||
|
8
testsuite/tools/simplify-data-3to4/separator.expected
Normal file
8
testsuite/tools/simplify-data-3to4/separator.expected
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<object class="GtkSeparator">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<object class="GtkSeparator"/>
|
||||
</interface>
|
9
testsuite/tools/simplify-data-3to4/separator.ui
Normal file
9
testsuite/tools/simplify-data-3to4/separator.ui
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkVSeparator">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<object class="GtkHSeparator">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</interface>
|
@@ -1935,6 +1935,36 @@ rewrite_scale (Element *element,
|
||||
}
|
||||
}
|
||||
|
||||
static Element *
|
||||
write_separator_prop (Element *element,
|
||||
Element *parent,
|
||||
const char *name,
|
||||
const char *value)
|
||||
{
|
||||
|
||||
if (element)
|
||||
g_free (element->data);
|
||||
else
|
||||
{
|
||||
element = add_element (parent, "property");
|
||||
set_attribute_value (element, "name", name);
|
||||
}
|
||||
element->data = g_strdup (value);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
static void
|
||||
rewrite_separator (Element *element,
|
||||
MyParserData *data)
|
||||
{
|
||||
if (g_str_equal (get_class_name (element), "GtkVSeparator"))
|
||||
write_separator_prop (NULL, element, "orientation", "vertical");
|
||||
|
||||
if (!g_str_equal (get_class_name (element), "GtkSeparator"))
|
||||
set_attribute_value (element, "class", "GtkSeparator");
|
||||
}
|
||||
|
||||
static void
|
||||
rewrite_requires (Element *element,
|
||||
MyParserData *data)
|
||||
@@ -2287,6 +2317,11 @@ rewrite_element_3to4 (Element *element,
|
||||
g_str_equal (get_class_name (element), "GtkScale"))
|
||||
rewrite_scale (element, data);
|
||||
|
||||
if (element_is_object_or_template (element) &&
|
||||
(g_str_equal (get_class_name (element), "GtkHSeparator") ||
|
||||
g_str_equal (get_class_name (element), "GtkVSeparator")))
|
||||
rewrite_separator(element, data);
|
||||
|
||||
if (g_str_equal (element->element_name, "property"))
|
||||
maybe_rename_property (element, data);
|
||||
|
||||
|
@@ -48,12 +48,23 @@ static void
|
||||
file_info (const char *filename)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
char *name;
|
||||
char *cicp;
|
||||
|
||||
texture = load_image_file (filename);
|
||||
|
||||
g_print ("%s %dx%d\n", _("Size:"), gdk_texture_get_width (texture), gdk_texture_get_height (texture));
|
||||
g_print ("%s %s\n", _("Format:"), get_format_name (gdk_texture_get_format (texture)));
|
||||
g_print ("%s %s\n", _("Color state:"), get_color_state_name (gdk_texture_get_color_state (texture)));
|
||||
|
||||
name = get_color_state_name (gdk_texture_get_color_state (texture));
|
||||
cicp = get_color_state_cicp (gdk_texture_get_color_state (texture));
|
||||
|
||||
if (name && cicp)
|
||||
g_print ("%s %s (cicp %s)\n", _("Color state:"), name, cicp);
|
||||
else if (cicp)
|
||||
g_print ("%s cicp %s\n", _("Color state:"), cicp);
|
||||
else
|
||||
g_print ("%s %s\n", _("Color state:"), _("unknown"));
|
||||
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
@@ -188,6 +188,27 @@ get_color_state_names (void)
|
||||
return g_strdupv ((char **) names);
|
||||
}
|
||||
|
||||
char *
|
||||
get_color_state_cicp (GdkColorState *color_state)
|
||||
{
|
||||
GdkCicpParams *params;
|
||||
char *str = NULL;
|
||||
|
||||
params = gdk_color_state_create_cicp_params (color_state);
|
||||
|
||||
if (params)
|
||||
{
|
||||
str = g_strdup_printf ("%u/%u/%u/%u",
|
||||
gdk_cicp_params_get_color_primaries (params),
|
||||
gdk_cicp_params_get_transfer_function (params),
|
||||
gdk_cicp_params_get_matrix_coefficients (params),
|
||||
gdk_cicp_params_get_range (params));
|
||||
g_object_unref (params);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *
|
||||
get_color_state_name (GdkColorState *color_state)
|
||||
{
|
||||
|
@@ -18,6 +18,7 @@ GdkColorState * find_color_state_by_name (const char *name);
|
||||
|
||||
char ** get_color_state_names (void);
|
||||
char * get_color_state_name (GdkColorState *color_state);
|
||||
char * get_color_state_cicp (GdkColorState *color_state);
|
||||
|
||||
GdkColorState *parse_cicp_tuple (const char *cicp_tuple,
|
||||
GError **error);
|
||||
|
@@ -11,7 +11,7 @@ if win32_enabled
|
||||
# compile_resources doesn't like to consume targets with multiple outputs,
|
||||
# and the xxx.exe.manifest and xxx.rc are tied together
|
||||
uac_rc = custom_target(
|
||||
'tools/@0@.rc'.format(uac_exe_name),
|
||||
'@0@-rc'.format(uac_exe_name),
|
||||
output: ['@0@.rc'.format(uac_exe_name)],
|
||||
command: [gen_uac_manifest,
|
||||
'-p=@0@'.format(uac_exe_pkg),
|
||||
|
Reference in New Issue
Block a user