Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d14a5acd4e |
@@ -1,4 +1,2 @@
|
||||
/subprojects/*/
|
||||
.flatpak-builder/
|
||||
.vscode/
|
||||
subprojects/*.wrap
|
||||
|
||||
+24
-2
@@ -198,11 +198,11 @@ fedora-mingw64:
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
|
||||
msys2-ucrt64:
|
||||
msys2-mingw64:
|
||||
extends: .mingw-defaults
|
||||
needs: []
|
||||
variables:
|
||||
MSYSTEM: "UCRT64"
|
||||
MSYSTEM: "MINGW64"
|
||||
CHERE_INVOKING: "yes"
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -327,6 +327,20 @@ flatpak:widget-factory:aarch64:
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
|
||||
flatpak:icon-browser:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
|
||||
flatpak:icon-browser:aarch64:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
tags:
|
||||
- flatpak-aarch64
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
|
||||
flatpak:node-editor:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
@@ -360,6 +374,14 @@ nightly factory aarch64:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:widget-factory:aarch64']
|
||||
|
||||
nightly icon-browser:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:icon-browser']
|
||||
|
||||
nightly icon-browser aarch64:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:icon-browser:aarch64']
|
||||
|
||||
nightly node-editor:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:node-editor']
|
||||
|
||||
@@ -5,7 +5,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
@echo on
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson~=1.2 || goto :error
|
||||
pip3 install --upgrade --user meson~=0.64 || goto :error
|
||||
meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled -Dvulkan=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
|
||||
+27
-21
@@ -2,6 +2,12 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$MSYSTEM" == "MINGW32" ]]; then
|
||||
export MSYS2_ARCH="i686"
|
||||
else
|
||||
export MSYS2_ARCH="x86_64"
|
||||
fi
|
||||
|
||||
# Update everything
|
||||
pacman --noconfirm -Suy
|
||||
|
||||
@@ -9,27 +15,27 @@ pacman --noconfirm -Suy
|
||||
pacman --noconfirm -S --needed \
|
||||
base-devel \
|
||||
git \
|
||||
${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
|
||||
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
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
|
||||
@@ -196,5 +196,10 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"GSK_RENDERER" : "opengl"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||
"GSK_RENDERER" : "opengl",
|
||||
"G_ENABLE_DEBUG" : "true"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||
"GSK_RENDERER" : "opengl",
|
||||
"G_ENABLE_DEBUG" : "true"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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_APPLICATION_TYPE (constraint_editor_application_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditorApplication, constraint_editor_application, CONSTRAINT, EDITOR_APPLICATION, GtkApplication)
|
||||
|
||||
ConstraintEditorApplication *constraint_editor_application_new (void);
|
||||
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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);
|
||||
@@ -0,0 +1,77 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,716 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
constraintview {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
constraintview .child {
|
||||
background: red;
|
||||
}
|
||||
|
||||
constraintview .guide {
|
||||
background: blue;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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);
|
||||
@@ -0,0 +1,204 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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);
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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);
|
||||
@@ -0,0 +1,345 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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);
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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);
|
||||
@@ -0,0 +1,201 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
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,
|
||||
)
|
||||
@@ -1869,4 +1869,4 @@ do_font_features (GtkWidget *do_widget)
|
||||
return window;
|
||||
}
|
||||
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -165,6 +165,10 @@ activate_about (GSimpleAction *action,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkApplication *app = user_data;
|
||||
const char *authors[] = {
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
char *version;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
@@ -202,11 +206,11 @@ activate_about (GSimpleAction *action,
|
||||
? "GTK Demo (Development)"
|
||||
: "GTK Demo",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2024 The GTK Team",
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK widgets",
|
||||
"authors", (const char *[]) { "The GTK Team", NULL },
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.Demo4",
|
||||
"title", "About GTK Demo",
|
||||
"system-information", s->str,
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.2 KiB |
@@ -0,0 +1,136 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 7.1 KiB |
@@ -0,0 +1,517 @@
|
||||
[volume]
|
||||
Name=Volume
|
||||
Description=Icons related to audio input and output volume
|
||||
|
||||
audio-volume-high=The icon used to indicate high audio volume
|
||||
audio-volume-low=The icon used to indicate low audio volume
|
||||
audio-volume-medium=The icon used to indicate medium audio volume
|
||||
audio-volume-muted=The icon used to indicate the muted state for audio playback
|
||||
microphone-sensitivity-high=The icon used to indicate high microphone sensitivity
|
||||
microphone-sensitivity-low=The icon used to indicate low microphone sensitivity
|
||||
microphone-sensitivity-medium=The icon used to indicate medium microphone sensitivity
|
||||
microphone-sensitivity-muted=The icon used to indicate that a microphone is muted
|
||||
|
||||
[multimedia]
|
||||
Name=Multimedia
|
||||
Description=Icons related to playback of media
|
||||
|
||||
media-playlist-repeat=The icon for the repeat mode of a media player
|
||||
media-playlist-repeat-song=The icon for repeating a song in a media player
|
||||
media-playlist-shuffle=The icon for the shuffle mode of a media player
|
||||
media-playlist-consecutive=The icon for consecutive mode of a media player
|
||||
media-skip-backward=The icon for the skip backward action of a media player
|
||||
media-seek-backward=The icon for the seek backward action of a media player
|
||||
media-playback-start=The icon for the start playback action of a media player
|
||||
media-seek-forward=The icon for the seek forward action of a media player
|
||||
media-skip-forward=The icon for the skip forward action of a media player
|
||||
media-playback-stop=The icon for the stop action of a media player
|
||||
media-playback-pause=The icon for the pause action of a media player
|
||||
media-eject=The icon for the eject action of a media player or file manager
|
||||
media-record=The icon for the record action of a media application
|
||||
media-view-subtitles=The icon used to show subtitles in a media player
|
||||
|
||||
[network]
|
||||
Name=Network
|
||||
Description=Icons related to network status
|
||||
|
||||
network-transmit-receive=The icon used data is being both transmitted and received simultaneously, while the computing device is connected to a network
|
||||
network-transmit=The icon used when data is being transmitted, while the computing device is connected to a network
|
||||
network-receive=The icon used when data is being received, while the computing device is connected to a network
|
||||
network-idle=The icon used when no data is being transmitted or received, while the computing device is connected to a network
|
||||
network-error=The icon used when an error occurs trying to initialize the network connection of the computing device
|
||||
network-offline=The icon used when the computing device is disconnected from the network
|
||||
|
||||
[weather]
|
||||
Name=Weather
|
||||
Description=Icons about weather conditions
|
||||
|
||||
weather-clear=The icon used while the weather for a region is “clear skies”
|
||||
weather-clear-night=The icon used while the weather for a region is “clear skies” during the night
|
||||
weather-few-clouds=The icon used while the weather for a region is “partly cloudy”
|
||||
weather-few-clouds-night=The icon used while the weather for a region is “partly cloudy” during the night
|
||||
weather-fog=The icon used while the weather for a region is “foggy”
|
||||
weather-overcast=The icon used while the weather for a region is “overcast”
|
||||
weather-severe-alert=The icon used while a sever weather alert is in effect for a region
|
||||
weather-showers=The icon used while rain showers are occurring in a region
|
||||
weather-showers-scattered=The icon used while scattered rain showers are occurring in a region
|
||||
weather-snow=The icon used while snow showers are occurring in a region
|
||||
weather-storm=The icon used while storms are occurring in a region
|
||||
weather-windy=The icon used while the weather is windy
|
||||
|
||||
[navigation]
|
||||
Name=Navigation
|
||||
Description=Icons for navigation in the user interface of a program
|
||||
|
||||
go-first=The icon for the go to the first item in a list
|
||||
go-previous=The icon for the go to the previous item in a list
|
||||
go-next=The icon for the go to the next item in a list
|
||||
go-last=The icon for the go to the last item in a list
|
||||
go-bottom=The icon for the go to bottom of a list
|
||||
go-down=The icon for the go down in a list
|
||||
go-up=The icon for the go up in a list
|
||||
go-top=The icon for the go to the top of a list
|
||||
go-home=The icon for the go to home location
|
||||
go-jump=The icon for the jump to action
|
||||
|
||||
[editing]
|
||||
Name=Editing
|
||||
Description=Icons related to editing a document
|
||||
format-indent-less=The icon for the decrease indent formatting action
|
||||
format-indent-more=The icon for the increase indent formatting action
|
||||
format-justify-center=The icon for the center justification formatting action
|
||||
format-justify-fill=The icon for the fill justification formatting action
|
||||
format-justify-left=The icon for the left justification formatting action
|
||||
format-justify-right=The icon for the right justification action
|
||||
format-text-direction-ltr=The icon for the left-to-right text formatting action
|
||||
format-text-direction-rtl=The icon for the right-to-left formatting action
|
||||
format-text-bold=The icon for the bold text formatting action
|
||||
format-text-italic=The icon for the italic text formatting action
|
||||
format-text-underline=The icon for the underlined text formatting action
|
||||
format-text-strikethrough=The icon for the strikethrough text formatting action
|
||||
edit-clear=The icon for the clear action
|
||||
edit-clear-all=
|
||||
edit-copy=The icon for the copy action
|
||||
edit-cut=The icon for the cut action
|
||||
edit-delete=The icon for the delete action
|
||||
edit-find-replace=The icon for the find and replace action
|
||||
edit-paste=The icon for the paste action
|
||||
edit-redo=The icon for the redo action
|
||||
edit-select-all=The icon for the select all action
|
||||
edit-select=
|
||||
edit-undo=The icon for the undo action
|
||||
error-correct=
|
||||
document-properties=The icon for the action to view the properties of a document in an application
|
||||
document-new=The icon used for the action to create a new document
|
||||
document-open=The icon used for the action to open a document
|
||||
document-open-recent=The icon used for the action to open a document that was recently opened
|
||||
document-save=The icon for the save action. Should be an arrow pointing down and toward a hard disk
|
||||
document-save-as=The icon for the save as action
|
||||
document-send=The icon for the send action. Should be an arrow pointing up and away from a hard disk
|
||||
document-page-setup=The icon for the page setup action of a document editor
|
||||
document-edit=The icon for the action to edit a document
|
||||
object-flip-horizontal=The icon for the action to flip an object horizontally
|
||||
object-flip-vertical=The icon for the action to flip an object vertically
|
||||
object-rotate-left=The icon for the rotate left action performed on an object
|
||||
object-rotate-right=The icon for the rotate right action performed on an object
|
||||
insert-image=The icon for the insert image action of an application
|
||||
insert-link=The icon for the insert link action of an application
|
||||
insert-object=The icon for the insert object action of an application
|
||||
insert-text=The icon for the insert text action of an application
|
||||
accessories-text-editor=The icon used for the desktop's text editing accessory program
|
||||
|
||||
[view]
|
||||
Name=View Controls
|
||||
Description=Icons for view controls in a user interface
|
||||
|
||||
view-list=The icon used for “List“ view mode
|
||||
view-grid=The icon used for “Grid“ view mode (as opposed to “List“)
|
||||
view-fullscreen=The icon used for the “Fullscreen” item in the application's “View” menu
|
||||
view-restore=The icon used by an application for leaving the fullscreen view, and returning to a normal windowed view
|
||||
zoom-fit-best=The icon used for the “Best Fit” item in the application's “View” menu
|
||||
zoom-in=The icon used for the “Zoom in” item in the application's “View” menu
|
||||
zoom-out=The icon used for the “Zoom Out” item in the application's “View” menu
|
||||
zoom-original=The icon used for the “Original Size” item in the application's “View” menu
|
||||
view-continuous=The icon used for a continuous view mode
|
||||
view-paged=The icon used for a paged view mode (as opposed to continuous)
|
||||
view-dual=The icon used for a side-by-side view of paginated content
|
||||
view-wrapped=The icon used to indicate a wrap-around to the beginning
|
||||
view-pin=The icon used for 'pin a view'
|
||||
|
||||
[calendar]
|
||||
Name=Calendar, Tasks and Alarms
|
||||
Description=Icons related to calendars, tasks and alarms
|
||||
|
||||
task-due=The icon used when a task is due soon
|
||||
task-past-due=The icon used when a task that was due, has been left incomplete
|
||||
appointment-soon=The icon used when an appointment will occur soon
|
||||
appointment-missed=The icon used when an appointment was missed
|
||||
alarm=The icon used for alarms when a task or appointment is due
|
||||
|
||||
[communication]
|
||||
Name=Communication
|
||||
Description=Icons related email, phone calls, IM and other forms of communication
|
||||
|
||||
mail-unread=The icon used for an electronic mail that is unread
|
||||
mail-read=The icon used for an electronic mail that is read
|
||||
mail-replied=The icon used for an electronic mail that has been replied to
|
||||
mail-attachment=The icon used for an electronic mail that contains attachments
|
||||
mail-mark-important=The icon for the mark as important action of an electronic mail application
|
||||
mail-send=The icon for the send action of an electronic mail application
|
||||
mail-send-receive=The icon for the send and receive action of an electronic mail application
|
||||
call-start=The icon used for initiating or accepting a call
|
||||
call-stop=The icon used for stopping a current call
|
||||
call-missed=The icon used to show a missed call
|
||||
user-available=The icon used when a user on a chat network is available to initiate a conversation with
|
||||
user-offline=The icon used when a user on a chat network is not available
|
||||
user-idle=The icon used when a user on a chat network has not been an active participant in any chats on the network, for an extended period of time
|
||||
user-invisible=The icon used when a user is on a chat network, but is invisible to others
|
||||
user-busy=The icon used when a user is on a chat network, and has marked himself as busy
|
||||
user-away=The icon used when a user on a chat network is away from their keyboard and the chat program
|
||||
user-status-pending=The icon used when the current user status on a chat network is not known
|
||||
|
||||
[devices]
|
||||
Name=Devices and Media
|
||||
Description=Icons for devices and media
|
||||
|
||||
audio-input-microphone=The icon used for the microphone audio input device
|
||||
camera-web=The fallback icon for web cameras
|
||||
camera-photo=The icon used for a digital still camera devices
|
||||
input-keyboard=The icon used for the keyboard input device
|
||||
printer=The icon used for a printer device
|
||||
video-display=The icon used for the monitor that video gets displayed to
|
||||
computer=The icon used for the computing device as a whole
|
||||
media-optical=The icon used for physical optical media such as CD and DVD
|
||||
phone=The icon used for phone devices which support connectivity to the PC, such as VoIP, cellular, or possibly landline phones
|
||||
input-dialpad=The icon used for dialpad input devices
|
||||
input-touchpad=The icon used for touchpad input devices
|
||||
scanner=The icon used for a scanner device
|
||||
audio-card=The icon used for the audio rendering device
|
||||
input-gaming=The icon used for the gaming input device
|
||||
input-mouse=The icon used for the mousing input device
|
||||
multimedia-player=The icon used for generic multimedia playing devices
|
||||
audio-headphones=The icon used for headphones
|
||||
audio-headset=The icon used for headsets
|
||||
display-projector=The icon used for projectors
|
||||
media-removable=The icon used for generic removable media
|
||||
printer-network=The icon used for printers which are connected via the network
|
||||
audio-speakers=The icon used for speakers
|
||||
camera-video=The fallback icon for video cameras
|
||||
drive-optical=The icon used for optical media drives such as CD and DVD
|
||||
drive-removable-media=The icon used for removable media drives
|
||||
input-tablet=The icon used for graphics tablet input devices
|
||||
network-wireless=The icon used for wireless network connections
|
||||
network-wired=The icon used for wired network connections
|
||||
media-floppy=The icon used for physical floppy disk media
|
||||
media-flash=The fallback icon used for flash media, such as memory stick and SD
|
||||
|
||||
[contenttypes]
|
||||
Name=Content Types
|
||||
Description=Icons for different types of data, such as audio or image files
|
||||
|
||||
application-certificate=
|
||||
application-rss+xml=
|
||||
application-x-appliance=
|
||||
audio-x-generic=The icon used for generic audio file types
|
||||
folder=The standard folder icon used to represent directories on local filesystems, mail folders, and other hierarchical groups
|
||||
text-x-generic=The icon used for generic text file types
|
||||
video-x-generic=The icon used for generic video file types
|
||||
x-office-calendar=The icon used for generic calendar file types
|
||||
|
||||
[emotes]
|
||||
Name=Emotes
|
||||
Description=Icons for emotions that are expressed through text chat applications such as :-) or :-P in IRC or instant messengers
|
||||
|
||||
face-angel=The icon used for the 0:-) emote
|
||||
face-angry=The icon used for the X-( emote
|
||||
face-cool=The icon used for the B-) emote
|
||||
face-crying=The icon used for the :'( emote
|
||||
face-devilish=The icon used for the >:-) emote
|
||||
face-embarrassed=The icon used for the :-[ emote
|
||||
face-kiss=The icon used for the :-* emote
|
||||
face-laugh=The icon used for the :-)) emote
|
||||
face-monkey=The icon used for the :-(|) emote
|
||||
face-plain=The icon used for the :-| emote
|
||||
face-raspberry=The icon used for the :-P emote
|
||||
face-sad=The icon used for the :-( emote
|
||||
face-shutmouth=The 'shut mouth' emote
|
||||
face-sick=The icon used for the :-& emote
|
||||
face-smile=The icon used for the :-) emote
|
||||
face-smile-big=The icon used for the :-D emote
|
||||
face-smirk=The icon used for the :-! emote
|
||||
face-surprise=The icon used for the :-0 emote
|
||||
face-tired=The icon used for the |-) emote
|
||||
face-uncertain=The icon used for the :-/ emote
|
||||
face-wink=The icon used for the ;-) emote
|
||||
face-worried=The icon used for the :-S emote
|
||||
face-yawn=
|
||||
|
||||
[general]
|
||||
Name=General
|
||||
Description=Generally useful icons that don't fit in a particular category
|
||||
|
||||
edit-find=The icon for generic search actions
|
||||
content-loading=The icon used to indicate that content is loading
|
||||
open-menu=The icon used for a menu button in the header bar
|
||||
view-more=The icon used for a “View More“ action
|
||||
tab-new=The icon used for a “New Tab“ action
|
||||
bookmark-new=The icon used for creating a new bookmark
|
||||
mark-location=The icon used to mark a location on a map
|
||||
find-location=The icon used for a “Search location“ action
|
||||
send-to=The icon used for a “Send to“ action
|
||||
object-select=The icon used for generic selection actions
|
||||
window-close=The icon used for actions that close a view, such as window or tab close button
|
||||
view-refresh=The icon used for the “Refresh” item in the application's “View” menu
|
||||
process-stop=The icon used for the “Stop” action in applications with actions that may take a while to process, such as web page loading in a browser
|
||||
action-unavailable=The icon used to indicate that an action is currently unavailable, such as “Pause“ when no media is playing
|
||||
document-print=The icon for the print action of an application
|
||||
printer-printing=The icon used while a print job is successfully being spooled to a printing device
|
||||
printer-warning=The icon used when a recoverable problem occurs while attempting to printing
|
||||
printer-error=The icon used when an error occurs while attempting to print
|
||||
dialog-information=The icon used when a dialog is opened to give information to the user that may be pertinent to the requested action
|
||||
dialog-question=The icon used when a dialog is opened to ask a simple question of the user
|
||||
dialog-warning=The icon used when a dialog is opened to warn the user of impending issues with the requested action
|
||||
dialog-password=The icon used when a dialog requesting the authentication credentials for a user is opened
|
||||
dialog-error=The icon used when a dialog is opened to explain an error condition to the user
|
||||
list-add=The icon for the add to list action
|
||||
list-remove=The icon for the remove from list action
|
||||
non-starred=The icon used to indicate that an object is not 'starred'
|
||||
semi-starred=The icon used to indicate that an object has is 'half-starred'
|
||||
starred=The icon used to indicate that an object is 'starred'
|
||||
star-new=The used for the “New Star“ action
|
||||
security-low=The icon used to indicate that the security level of a connection is presumed to be insecure, either by using weak encryption, or by using a certificate that the could not be automatically verified, and which the user has not chosent to trust
|
||||
security-medium=The icon used to indicate that the security level of a connection is presumed to be secure, using strong encryption, and a certificate that could not be automatically verified, but which the user has chosen to trust
|
||||
security-high=The icon used to indicate that the security level of a connection is known to be secure, using strong encryption and a valid certificate
|
||||
user-trash=The icon for the user's “Trash” place in the file system
|
||||
user-trash-full=The icon for the user's “Trash” in the file system, when there are items in the “Trash” waiting for disposal or recovery
|
||||
emblem-system=The icon used as an emblem for directories that contain system libraries, settings, and data
|
||||
avatar-default=The generic avatar icon, which is used to represent a user that doesn't have a personalized avatar
|
||||
emblem-synchronizing=The icon used as an emblem to indicate that a synchronizing operation is in process
|
||||
emblem-shared=The icon used as an emblem for files and directories that are shared to other users
|
||||
help-browser=The icon used for the desktop's help browsing application
|
||||
|
||||
[other]
|
||||
Name=Other
|
||||
Description=Icons which have may be too specialized and not of general interest
|
||||
|
||||
changes-allow=
|
||||
changes-prevent=
|
||||
view-sort-ascending=The icon used for the “Sort Ascending” item in the application's “View” menu, or in a button for changing the sort method for a list
|
||||
view-sort-descending=The icon used for the “Sort Descending” item in the application's “View” menu, or in a button for changing the sort method for a list
|
||||
document-revert=The icon for the action of reverting to a previous version of a document
|
||||
address-book-new=The icon used for the action to create a new address book
|
||||
application-exit=The icon used for exiting an application. Typically this is seen in the application's menus as File->Quit
|
||||
appointment-new=The icon used for the action to create a new appointment in a calendaring application
|
||||
contact-new=The icon used for the action to create a new contact in an address book application
|
||||
document-print-preview=The icon for the print preview action of an application
|
||||
folder-new=The icon for creating a new folder
|
||||
help-about=The icon for the About item in the Help menu
|
||||
help-contents=The icon for Contents item in the Help menu
|
||||
help-faq=The icon for the FAQ item in the Help menu
|
||||
list-remove-all=
|
||||
mail-forward=The icon for the forward action of an electronic mail application
|
||||
mail-mark-junk=The icon for the mark as junk action of an electronic mail application
|
||||
mail-mark-notjunk=The icon for the mark as not junk action of an electronic mail application
|
||||
mail-mark-read=The icon for the mark as read action of an electronic mail application
|
||||
mail-mark-unread=The icon for the mark as unread action of an electronic mail application
|
||||
mail-message-new=The icon for the compose new mail action of an electronic mail application
|
||||
mail-reply-all=The icon for the reply to all action of an electronic mail application
|
||||
mail-reply-sender=The icon for the reply to sender action of an electronic mail application
|
||||
pan-down=
|
||||
pan-end=
|
||||
pan-start=
|
||||
pan-up=
|
||||
system-lock-screen=The icon used for the “Lock Screen” item in the desktop's panel application
|
||||
system-log-out=The icon used for the “Log Out” item in the desktop's panel application
|
||||
system-run=The icon used for the “Run Application...” item in the desktop's panel application
|
||||
system-search=The icon used for the “Search” item in the desktop's panel application
|
||||
system-reboot=The icon used for the “Reboot” item in the desktop's panel application
|
||||
system-shutdown=The icon used for the “Shutdown” item in the desktop's panel application
|
||||
tools-check-spelling=The icon used for the “Check Spelling” item in the application's “Tools” menu
|
||||
window-maximize=
|
||||
window-minimize=
|
||||
window-restore=
|
||||
window-new=The icon used for the “New Window” item in the application's “Windows” menu
|
||||
accessories-calculator=The icon used for the desktop's calculator accessory program
|
||||
accessories-character-map=The icon used for the desktop's international and extended text character accessory program
|
||||
accessories-dictionary=The icon used for the desktop's dictionary accessory program
|
||||
multimedia-volume-control=The icon used for the desktop's hardware volume control application
|
||||
preferences-desktop-accessibility=The icon used for the desktop's accessibility preferences
|
||||
preferences-desktop-display=
|
||||
preferences-desktop-font=The icon used for the desktop's font preferences
|
||||
preferences-desktop-keyboard=The icon used for the desktop's keyboard preferences
|
||||
preferences-desktop-keyboard-shortcuts=
|
||||
preferences-desktop-locale=The icon used for the desktop's locale preferences
|
||||
preferences-desktop-remote-desktop=
|
||||
preferences-desktop-multimedia=The icon used for the desktop's multimedia preferences
|
||||
preferences-desktop-screensaver=The icon used for the desktop's screen saving preferences
|
||||
preferences-desktop-theme=The icon used for the desktop's theme preferences
|
||||
preferences-desktop-wallpaper=The icon used for the desktop's wallpaper preferences
|
||||
preferences-system-privacy=
|
||||
preferences-system-windows=
|
||||
system-file-manager=The icon used for the desktop's file management application
|
||||
system-software-install=The icon used for the desktop's software installer application
|
||||
system-software-update=The icon used for the desktop's software updating application
|
||||
system-users=
|
||||
user-info=
|
||||
utilities-system-monitor=The icon used for the desktop's system resource monitor application
|
||||
utilities-terminal=The icon used for the desktop's terminal emulation application.
|
||||
application-x-addon=
|
||||
application-x-executable=The icon used for executable file types
|
||||
font-x-generic=The icon used for generic font file types
|
||||
image-x-generic=The icon used for generic image file types
|
||||
package-x-generic=The icon used for generic package file types
|
||||
text-html=The icon used for HTML text file types
|
||||
text-x-generic-template=The icon used for generic text templates
|
||||
text-x-preview=
|
||||
text-x-script=The icon used for script file types, such as shell scripts
|
||||
x-office-address-book=The icon used for generic address book file types
|
||||
x-office-document=The icon used for generic document and letter file types
|
||||
x-office-document-template=
|
||||
x-office-presentation=The icon used for generic presentation file types
|
||||
x-office-presentation-template=
|
||||
x-office-spreadsheet=The icon used for generic spreadsheet file types
|
||||
x-office-spreadsheet-template=
|
||||
x-package-repository=
|
||||
applications-accessories=The icon for the “Accessories” sub-menu of the Programs menu
|
||||
applications-development=The icon for the “Programming” sub-menu of the Programs menu
|
||||
applications-engineering=The icon for the “Engineering” sub-menu of the Programs menu
|
||||
applications-games=The icon for the “Games” sub-menu of the Programs menu
|
||||
applications-graphics=The icon for the “Graphics” sub-menu of the Programs menu
|
||||
applications-internet=The icon for the “Internet” sub-menu of the Programs menu
|
||||
applications-multimedia=The icon for the “Multimedia” sub-menu of the Programs menu
|
||||
applications-office=The icon for the “Office” sub-menu of the Programs menu
|
||||
applications-other=The icon for the “Other” sub-menu of the Programs menu
|
||||
applications-science=The icon for the “Science” sub-menu of the Programs menu
|
||||
applications-system=The icon for the “System Tools” sub-menu of the Programs menu
|
||||
applications-utilities=The icon for the “Utilities” sub-menu of the Programs menu
|
||||
preferences-desktop=The icon for the “Desktop Preferences” category
|
||||
preferences-desktop-peripherals=The icon for the “Peripherals” sub-category of the “Desktop Preferences” category
|
||||
preferences-desktop-personal=The icon for the “Personal” sub-category of the “Desktop Preferences” category
|
||||
preferences-other=The icon for the “Other” preferences category
|
||||
preferences-system=The icon for the “System Preferences” category
|
||||
preferences-system-network=The icon for the “Network” sub-category of the “System Preferences” category
|
||||
system-help=The icon for the “Help” system category
|
||||
battery=The icon used for the system battery device
|
||||
computer-apple-ipad=
|
||||
colorimeter-colorhug=
|
||||
drive-harddisk=The icon used for hard disk drives
|
||||
drive-harddisk-ieee1394=
|
||||
drive-harddisk-system=
|
||||
drive-multidisk=
|
||||
media-optical-bd=
|
||||
media-optical-cd-audio=
|
||||
media-optical-dvd=
|
||||
media-tape=The icon used for generic physical tape media
|
||||
media-zip=
|
||||
modem=The icon used for modem devices
|
||||
multimedia-player-apple-ipod-touch=
|
||||
network-vpn=
|
||||
pda=This is the fallback icon for Personal Digital Assistant devices. Primary use of this icon is for PDA devices connected to the PC. Connection medium is not an important aspect of the icon. The metaphor for this fallback icon should be a generic PDA device icon
|
||||
phone-apple-iphone=
|
||||
uninterruptible-power-supply=
|
||||
emblem-default=The icon used as an emblem to specify the default selection of a printer for example
|
||||
emblem-documents=The icon used as an emblem for the directory where a user's documents are stored
|
||||
emblem-downloads=The icon used as an emblem for the directory where a user's downloads from the internet are stored
|
||||
emblem-favorite=The icon used as an emblem for files and directories that the user marks as favorites
|
||||
emblem-generic=
|
||||
emblem-important=The icon used as an emblem for files and directories that are marked as important by the user
|
||||
emblem-mail=The icon used as an emblem to specify the directory where the user's electronic mail is stored
|
||||
emblem-new=
|
||||
emblem-ok=
|
||||
emblem-package=
|
||||
emblem-photos=The icon used as an emblem to specify the directory where the user stores photographs
|
||||
emblem-readonly=The icon used as an emblem for files and directories which can not be written to by the user
|
||||
emblem-symbolic-link=The icon used as an emblem for files and direcotires that are links to other files or directories on the filesystem
|
||||
emblem-synchronized=The icon used as an emblem for files or directories that are configured to be synchronized to another device
|
||||
emblem-unreadable=The icon used as an emblem for files and directories that are inaccessible.
|
||||
emblem-urgent=
|
||||
emblem-videos=
|
||||
emblem-web=
|
||||
folder-documents=
|
||||
folder-download=The icon representing the location in the file system where downloaded files are stored
|
||||
folder-music=
|
||||
folder-pictures=
|
||||
folder-publicshare=
|
||||
folder-remote=The icon used for normal directories on a remote filesystem
|
||||
folder-saved-search=
|
||||
folder-templates=
|
||||
folder-videos=
|
||||
network-server=The icon used for individual host machines under the “Network Servers” place in the file manager
|
||||
network-workgroup=The icon for the “Network Servers” place in the desktop's file manager, and workgroups within the network
|
||||
start-here=The icon used by the desktop's main menu for accessing places, applications, and other features
|
||||
user-bookmarks=The icon for the user's special “Bookmarks” place
|
||||
user-desktop=The icon for the special “Desktop” directory of the user
|
||||
user-home=The icon for the special “Home” directory of the user
|
||||
airplane-mode=
|
||||
battery-caution-charging=
|
||||
battery-caution=The icon used when the battery is below 40%
|
||||
battery-empty-charging=
|
||||
battery-empty=
|
||||
battery-full-charged=
|
||||
battery-full-charging=
|
||||
battery-full=
|
||||
battery-good-charging=
|
||||
battery-good=
|
||||
battery-low-charging=
|
||||
battery-low=The icon used when the battery is below 20%
|
||||
battery-missing=
|
||||
bluetooth-active=
|
||||
bluetooth-disabled=
|
||||
channel-insecure=
|
||||
channel-secure=
|
||||
computer-fail=
|
||||
display-brightness=
|
||||
keyboard-brightness=
|
||||
folder-drag-accept=The icon used for a folder while an object is being dragged onto it, that is of a type that the directory can contain
|
||||
folder-open=The icon used for folders, while their contents are being displayed within the same window. This icon would normally be shown in a tree or list view, next to the main view of a folder's contents
|
||||
folder-visiting=The icon used for folders, while their contents are being displayed in another window. This icon would typically be used when using multiple windows to navigate the hierarchy, such as in Nautilus's spatial mode
|
||||
image-loading=The icon used when another image is being loaded, such as thumnails for larger images in the file manager
|
||||
image-missing=The icon used when another image could not be loaded
|
||||
mail-signed=The icon used for an electronic mail that contains a signature
|
||||
mail-signed-verified=The icon used for an electronic mail that contains a signature which has also been verified by the security system
|
||||
network-cellular-3g=
|
||||
network-cellular-4g=
|
||||
network-cellular-edge=
|
||||
network-cellular-gprs=
|
||||
network-cellular-umts=
|
||||
network-cellular-acquiring=
|
||||
network-cellular-connected=
|
||||
network-cellular-no-route=
|
||||
network-cellular-offline=
|
||||
network-cellular-signal-excellent=
|
||||
network-cellular-signal-good=
|
||||
network-cellular-signal-ok=
|
||||
network-cellular-signal-weak=
|
||||
network-cellular-signal-none=
|
||||
network-vpn-acquiring=
|
||||
network-vpn=
|
||||
network-wired-acquiring=
|
||||
network-wired-disconnected=
|
||||
network-wired-no-route=
|
||||
network-wired-offline=
|
||||
network-wireless-acquiring=
|
||||
network-wireless-connected=
|
||||
network-wireless-encrypted=
|
||||
network-wireless-hotspot=
|
||||
network-wireless-no-route=
|
||||
network-wireless-offline=
|
||||
network-wireless-signal-excellent=
|
||||
network-wireless-signal-good=
|
||||
network-wireless-signal-ok=
|
||||
network-wireless-signal-weak=
|
||||
network-wireless-signal-none=
|
||||
rotation-allowed=
|
||||
rotation-locked=
|
||||
software-update-available=The icon used when an update is available for software installed on the computing device, through the system software update program
|
||||
software-update-urgent=The icon used when an urgent update is available through the system software update program
|
||||
sync-error=The icon used when an error occurs while attempting to synchronize data from the computing device, to another device
|
||||
sync-synchronizing=The icon used while data is successfully synchronizing to another device
|
||||
touchpad-disabled=
|
||||
trophy-bronze=
|
||||
trophy-silver=
|
||||
trophy-gold=
|
||||
night-light=
|
||||
daytime-sunrise=
|
||||
daytime-sunset=
|
||||
on=
|
||||
off=
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/iconbrowser/gtk">
|
||||
<file preprocess="xml-stripblanks">window.ui</file>
|
||||
<file>icon.list</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -0,0 +1,160 @@
|
||||
#include "config.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "iconbrowserapp.h"
|
||||
#include "iconbrowserwin.h"
|
||||
|
||||
#include "profile_conf.h"
|
||||
|
||||
struct _IconBrowserApp
|
||||
{
|
||||
GtkApplication parent;
|
||||
};
|
||||
|
||||
struct _IconBrowserAppClass
|
||||
{
|
||||
GtkApplicationClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(IconBrowserApp, icon_browser_app, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
icon_browser_app_init (IconBrowserApp *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer app)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (app));
|
||||
}
|
||||
|
||||
static void
|
||||
inspector_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer app)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
about_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkApplication *app = user_data;
|
||||
const char *authors[] = {
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
char *icon_theme;
|
||||
char *version;
|
||||
GString *s;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
|
||||
g_object_get (gtk_settings_get_default (),
|
||||
"gtk-icon-theme-name", &icon_theme,
|
||||
NULL);
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
|
||||
if (os_name && os_version)
|
||||
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nIcon theme\n\t%s", icon_theme);
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Icon Browser (Development)"
|
||||
: "GTK Icon Browser",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to browse themed icons",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.IconBrowser4",
|
||||
"title", "About GTK Icon Browser",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
g_free (icon_theme);
|
||||
g_free (os_name);
|
||||
g_free (os_version);
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL },
|
||||
{ "inspector", inspector_activated, NULL, NULL, NULL },
|
||||
{ "about", about_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
icon_browser_app_startup (GApplication *app)
|
||||
{
|
||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
|
||||
G_APPLICATION_CLASS (icon_browser_app_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);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_app_activate (GApplication *app)
|
||||
{
|
||||
IconBrowserWindow *win;
|
||||
|
||||
win = icon_browser_window_new (ICON_BROWSER_APP (app));
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
|
||||
|
||||
gtk_window_set_icon_name (GTK_WINDOW (win), "org.gtk.IconBrowser4");
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_app_class_init (IconBrowserAppClass *class)
|
||||
{
|
||||
G_APPLICATION_CLASS (class)->startup = icon_browser_app_startup;
|
||||
G_APPLICATION_CLASS (class)->activate = icon_browser_app_activate;
|
||||
}
|
||||
|
||||
IconBrowserApp *
|
||||
icon_browser_app_new (void)
|
||||
{
|
||||
return g_object_new (ICON_BROWSER_APP_TYPE,
|
||||
"application-id", "org.gtk.IconBrowser4",
|
||||
NULL);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define ICON_BROWSER_APP_TYPE (icon_browser_app_get_type ())
|
||||
#define ICON_BROWSER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ICON_BROWSER_APP_TYPE, IconBrowserApp))
|
||||
|
||||
|
||||
typedef struct _IconBrowserApp IconBrowserApp;
|
||||
typedef struct _IconBrowserAppClass IconBrowserAppClass;
|
||||
|
||||
|
||||
GType icon_browser_app_get_type (void);
|
||||
IconBrowserApp *icon_browser_app_new (void);
|
||||
@@ -0,0 +1,156 @@
|
||||
#include "iconbrowsercontext.h"
|
||||
|
||||
struct _IbContext
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *id;
|
||||
char *name;
|
||||
char *description;
|
||||
};
|
||||
|
||||
struct _IbContextClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_ID = 1,
|
||||
PROP_NAME,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_NUM_PROPERTIES
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (IbContext, ib_context, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
ib_context_init (IbContext *context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_finalize (GObject *object)
|
||||
{
|
||||
IbContext *context = IB_CONTEXT (object);
|
||||
|
||||
g_free (context->id);
|
||||
g_free (context->name);
|
||||
g_free (context->description);
|
||||
|
||||
G_OBJECT_CLASS (ib_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbContext *context = IB_CONTEXT (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
g_free (context->id);
|
||||
context->id = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_free (context->name);
|
||||
context->name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_free (context->description);
|
||||
context->description = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbContext *context = IB_CONTEXT (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
g_value_set_string (value, context->id);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, context->name);
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_value_set_string (value, context->description);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_class_init (IbContextClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->finalize = ib_context_finalize;
|
||||
object_class->set_property = ib_context_set_property;
|
||||
object_class->get_property = ib_context_get_property;
|
||||
|
||||
pspec = g_param_spec_string ("id", "Id", "Id",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_ID, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("name", "Name", "Name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("description", "Description", "Description",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
|
||||
}
|
||||
|
||||
IbContext *
|
||||
ib_context_new (const char *id,
|
||||
const char *name,
|
||||
const char *description)
|
||||
{
|
||||
return g_object_new (IB_TYPE_CONTEXT,
|
||||
"id", id,
|
||||
"name", name,
|
||||
"description", description,
|
||||
NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_context_get_id (IbContext *context)
|
||||
{
|
||||
return context->id;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_context_get_name (IbContext *context)
|
||||
{
|
||||
return context->name;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_context_get_description (IbContext *context)
|
||||
{
|
||||
return context->description;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk.h>
|
||||
|
||||
#define IB_TYPE_CONTEXT (ib_context_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (IbContext, ib_context, IB, CONTEXT, GObject)
|
||||
|
||||
IbContext *ib_context_new (const char *id,
|
||||
const char *name,
|
||||
const char *description);
|
||||
|
||||
const char *ib_context_get_id (IbContext *context);
|
||||
const char *ib_context_get_name (IbContext *context);
|
||||
const char *ib_context_get_description (IbContext *context);
|
||||
@@ -0,0 +1,228 @@
|
||||
#include "iconbrowsericon.h"
|
||||
|
||||
struct _IbIcon
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gboolean use_symbolic;
|
||||
|
||||
char *regular_name;
|
||||
char *symbolic_name;
|
||||
char *description;
|
||||
char *context;
|
||||
};
|
||||
|
||||
struct _IbIconClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_NAME = 1,
|
||||
PROP_REGULAR_NAME,
|
||||
PROP_SYMBOLIC_NAME,
|
||||
PROP_USE_SYMBOLIC,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_CONTEXT,
|
||||
PROP_NUM_PROPERTIES
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (IbIcon, ib_icon, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
ib_icon_init (IbIcon *icon)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_finalize (GObject *object)
|
||||
{
|
||||
IbIcon *icon = IB_ICON (object);
|
||||
|
||||
g_free (icon->regular_name);
|
||||
g_free (icon->symbolic_name);
|
||||
g_free (icon->description);
|
||||
g_free (icon->context);
|
||||
|
||||
G_OBJECT_CLASS (ib_icon_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbIcon *icon = IB_ICON (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_REGULAR_NAME:
|
||||
g_free (icon->regular_name);
|
||||
icon->regular_name = g_value_dup_string (value);
|
||||
if (!icon->use_symbolic)
|
||||
g_object_notify (object, "name");
|
||||
break;
|
||||
|
||||
case PROP_SYMBOLIC_NAME:
|
||||
g_free (icon->symbolic_name);
|
||||
icon->symbolic_name = g_value_dup_string (value);
|
||||
if (icon->use_symbolic)
|
||||
g_object_notify (object, "name");
|
||||
break;
|
||||
|
||||
case PROP_USE_SYMBOLIC:
|
||||
icon->use_symbolic = g_value_get_boolean (value);
|
||||
g_object_notify (object, "name");
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_free (icon->description);
|
||||
icon->description = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_CONTEXT:
|
||||
g_free (icon->context);
|
||||
icon->context = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbIcon *icon = IB_ICON (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, ib_icon_get_name (icon));
|
||||
break;
|
||||
|
||||
case PROP_REGULAR_NAME:
|
||||
g_value_set_string (value, icon->regular_name);
|
||||
break;
|
||||
|
||||
case PROP_SYMBOLIC_NAME:
|
||||
g_value_set_string (value, icon->symbolic_name);
|
||||
break;
|
||||
|
||||
case PROP_USE_SYMBOLIC:
|
||||
g_value_set_boolean (value, icon->use_symbolic);
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_value_set_string (value, icon->description);
|
||||
break;
|
||||
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_string (value, icon->context);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_class_init (IbIconClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->finalize = ib_icon_finalize;
|
||||
object_class->set_property = ib_icon_set_property;
|
||||
object_class->get_property = ib_icon_get_property;
|
||||
|
||||
pspec = g_param_spec_string ("name", "Name", "Name",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("regular-name", "Regular Name", "Regular Name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_REGULAR_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("symbolic-name", "Symbolic Name", "Symbolic Name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_SYMBOLIC_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_boolean ("use-symbolic", "Use Symbolic", "Use Symbolic",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_USE_SYMBOLIC, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("description", "Description", "Description",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("context", "Context", "Context",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_CONTEXT, pspec);
|
||||
}
|
||||
|
||||
IbIcon *
|
||||
ib_icon_new (const char *regular_name,
|
||||
const char *symbolic_name,
|
||||
const char *description,
|
||||
const char *context)
|
||||
{
|
||||
return g_object_new (IB_TYPE_ICON,
|
||||
"regular-name", regular_name,
|
||||
"symbolic-name", symbolic_name,
|
||||
"description", description,
|
||||
"context", context,
|
||||
NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_name (IbIcon *icon)
|
||||
{
|
||||
if (icon->use_symbolic)
|
||||
return icon->symbolic_name;
|
||||
else
|
||||
return icon->regular_name;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_regular_name (IbIcon *icon)
|
||||
{
|
||||
return icon->regular_name;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_symbolic_name (IbIcon *icon)
|
||||
{
|
||||
return icon->symbolic_name;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ib_icon_get_use_symbolic (IbIcon *icon)
|
||||
{
|
||||
return icon->use_symbolic;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_description (IbIcon *icon)
|
||||
{
|
||||
return icon->description;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_context (IbIcon *icon)
|
||||
{
|
||||
return icon->context;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk.h>
|
||||
|
||||
#define IB_TYPE_ICON (ib_icon_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (IbIcon, ib_icon, IB, ICON, GObject)
|
||||
|
||||
IbIcon *ib_icon_new (const char *regular_name,
|
||||
const char *symbolic_name,
|
||||
const char *description,
|
||||
const char *context);
|
||||
|
||||
const char *ib_icon_get_name (IbIcon *icon);
|
||||
const char *ib_icon_get_regular_name (IbIcon *icon);
|
||||
const char *ib_icon_get_symbolic_name (IbIcon *icon);
|
||||
gboolean ib_icon_get_use_symbolic (IbIcon *icon);
|
||||
const char *ib_icon_get_description (IbIcon *icon);
|
||||
const char *ib_icon_get_context (IbIcon *icon);
|
||||
@@ -0,0 +1,460 @@
|
||||
#include <string.h>
|
||||
#include "iconbrowserapp.h"
|
||||
#include "iconbrowserwin.h"
|
||||
#include "iconbrowsericon.h"
|
||||
#include "iconbrowsercontext.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
struct _IconBrowserWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
GtkWidget *symbolic_radio;
|
||||
GtkWidget *searchbar;
|
||||
GListModel *icon_filter_model;
|
||||
GListStore *icon_store;
|
||||
GListModel *context_model;
|
||||
GListStore *context_store;
|
||||
GtkFilter *name_filter;
|
||||
GtkFilter *search_mode_filter;
|
||||
GtkWidget *details;
|
||||
GtkWidget *image1;
|
||||
GtkWidget *image2;
|
||||
GtkWidget *image3;
|
||||
GtkWidget *image4;
|
||||
GtkWidget *image5;
|
||||
GtkWidget *image6;
|
||||
GtkWidget *image7;
|
||||
GtkWidget *image8;
|
||||
GtkWidget *label8;
|
||||
GtkWidget *description;
|
||||
};
|
||||
|
||||
struct _IconBrowserWindowClass
|
||||
{
|
||||
GtkApplicationWindowClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(IconBrowserWindow, icon_browser_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static GtkIconTheme *
|
||||
icon_browser_window_get_icon_theme (IconBrowserWindow *win)
|
||||
{
|
||||
return gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (win)));
|
||||
}
|
||||
|
||||
static void
|
||||
add_icon (IconBrowserWindow *win,
|
||||
const char *name,
|
||||
const char *description,
|
||||
const char *context)
|
||||
{
|
||||
GtkIconTheme *icon_theme = icon_browser_window_get_icon_theme (win);
|
||||
char *regular_name;
|
||||
char *symbolic_name;
|
||||
IbIcon *icon;
|
||||
|
||||
regular_name = g_strdup (name);
|
||||
if (!gtk_icon_theme_has_icon (icon_theme, regular_name))
|
||||
{
|
||||
g_free (regular_name);
|
||||
regular_name = NULL;
|
||||
}
|
||||
|
||||
symbolic_name = g_strconcat (name, "-symbolic", NULL);
|
||||
if (!gtk_icon_theme_has_icon (icon_theme, symbolic_name))
|
||||
{
|
||||
g_free (symbolic_name);
|
||||
symbolic_name = NULL;
|
||||
}
|
||||
|
||||
icon = ib_icon_new (regular_name, symbolic_name, description, context);
|
||||
g_object_bind_property (win->symbolic_radio, "active",
|
||||
icon, "use-symbolic",
|
||||
G_BINDING_DEFAULT);
|
||||
g_list_store_append (win->icon_store, icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
static void
|
||||
add_context (IconBrowserWindow *win,
|
||||
const char *id,
|
||||
const char *name,
|
||||
const char *description)
|
||||
{
|
||||
IbContext *context;
|
||||
|
||||
context = ib_context_new (id, name, description);
|
||||
g_list_store_append (win->context_store, context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
populate (IconBrowserWindow *win)
|
||||
{
|
||||
GFile *file;
|
||||
GKeyFile *kf;
|
||||
char *data;
|
||||
gsize length;
|
||||
char **groups;
|
||||
int i;
|
||||
|
||||
file = g_file_new_for_uri ("resource:/org/gtk/iconbrowser/gtk/icon.list");
|
||||
g_file_load_contents (file, NULL, &data, &length, NULL, NULL);
|
||||
|
||||
kf = g_key_file_new ();
|
||||
g_key_file_load_from_data (kf, data, length, G_KEY_FILE_NONE, NULL);
|
||||
|
||||
groups = g_key_file_get_groups (kf, &length);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
const char *context;
|
||||
const char *name;
|
||||
const char *description;
|
||||
char **keys;
|
||||
gsize len;
|
||||
int j;
|
||||
|
||||
context = groups[i];
|
||||
name = g_key_file_get_string (kf, context, "Name", NULL);
|
||||
description = g_key_file_get_string (kf, context, "Description", NULL);
|
||||
add_context (win, context, name, description);
|
||||
|
||||
keys = g_key_file_get_keys (kf, context, &len, NULL);
|
||||
for (j = 0; j < len; j++)
|
||||
{
|
||||
const char *key = keys[j];
|
||||
const char *value;
|
||||
|
||||
if (strcmp (key, "Name") == 0 || strcmp (key, "Description") == 0)
|
||||
continue;
|
||||
|
||||
value = g_key_file_get_string (kf, context, key, NULL);
|
||||
|
||||
add_icon (win, key, value, context);
|
||||
}
|
||||
g_strfreev (keys);
|
||||
}
|
||||
g_strfreev (groups);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
filter_by_icon_name (gpointer item,
|
||||
gpointer data)
|
||||
{
|
||||
return ib_icon_get_name (IB_ICON (item)) != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
symbolic_toggled (IconBrowserWindow *win)
|
||||
{
|
||||
gtk_filter_changed (win->name_filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_to_clipboard (GtkButton *button,
|
||||
IconBrowserWindow *win)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (win));
|
||||
gdk_clipboard_set_text (clipboard, gtk_window_get_title (GTK_WINDOW (win->details)));
|
||||
}
|
||||
|
||||
static void
|
||||
set_image (GtkWidget *image, const char *name, int size)
|
||||
{
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
|
||||
}
|
||||
|
||||
static void
|
||||
item_activated (GtkGridView *view,
|
||||
guint position,
|
||||
IconBrowserWindow *win)
|
||||
{
|
||||
GListModel *model = G_LIST_MODEL (gtk_grid_view_get_model (view));
|
||||
IbIcon *icon = g_list_model_get_item (model, position);
|
||||
const char *name;
|
||||
const char *description;
|
||||
gboolean symbolic;
|
||||
|
||||
name = ib_icon_get_name (icon);
|
||||
description = ib_icon_get_description (icon);
|
||||
symbolic = ib_icon_get_use_symbolic (icon);
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (win->details), name);
|
||||
set_image (win->image1, name, 8);
|
||||
set_image (win->image2, name, 16);
|
||||
set_image (win->image3, name, 18);
|
||||
set_image (win->image4, name, 24);
|
||||
set_image (win->image5, name, 32);
|
||||
set_image (win->image6, name, 48);
|
||||
set_image (win->image7, name, 64);
|
||||
gtk_widget_set_visible (win->image8, symbolic);
|
||||
gtk_widget_set_visible (win->label8, symbolic);
|
||||
if (symbolic)
|
||||
set_image (win->image8, name, 64);
|
||||
gtk_widget_set_visible (win->description, description && description[0]);
|
||||
if (description && description[0])
|
||||
gtk_label_set_text (GTK_LABEL (win->description), description);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win->details));
|
||||
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
get_image_paintable (GtkImage *image)
|
||||
{
|
||||
const char *icon_name;
|
||||
GtkIconTheme *icon_theme;
|
||||
GtkIconPaintable *icon;
|
||||
int size;
|
||||
|
||||
switch (gtk_image_get_storage_type (image))
|
||||
{
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
return g_object_ref (gtk_image_get_paintable (image));
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
icon_name = gtk_image_get_icon_name (image);
|
||||
size = gtk_image_get_pixel_size (image);
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
|
||||
icon = gtk_icon_theme_lookup_icon (icon_theme,
|
||||
icon_name,
|
||||
NULL,
|
||||
size, 1,
|
||||
gtk_widget_get_direction (GTK_WIDGET (image)),
|
||||
0);
|
||||
if (icon == NULL)
|
||||
{
|
||||
g_print ("no icon for %s\n", icon_name);
|
||||
return NULL;
|
||||
}
|
||||
return GDK_PAINTABLE (icon);
|
||||
case GTK_IMAGE_GICON:
|
||||
case GTK_IMAGE_EMPTY:
|
||||
default:
|
||||
g_warning ("Image storage type %d not handled",
|
||||
gtk_image_get_storage_type (image));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
w = gdk_paintable_get_intrinsic_width (paintable);
|
||||
h = gdk_paintable_get_intrinsic_height (paintable);
|
||||
gtk_drag_source_set_icon (source, paintable, w, h);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
drag_prepare_texture (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
GtkSnapshot *snapshot;
|
||||
double width, height;
|
||||
GskRenderNode *node;
|
||||
GskRenderer *renderer;
|
||||
GdkTexture *texture;
|
||||
GdkContentProvider *ret;
|
||||
|
||||
if (!GDK_IS_PAINTABLE (paintable))
|
||||
return NULL;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
width = gdk_paintable_get_intrinsic_width (paintable);
|
||||
height = gdk_paintable_get_intrinsic_height (paintable);
|
||||
gdk_paintable_snapshot (paintable, snapshot, width, height);
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
|
||||
renderer = gtk_native_get_renderer (gtk_widget_get_native (widget));
|
||||
texture = gsk_renderer_render_texture (renderer, node, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
ret = gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, texture);
|
||||
|
||||
g_object_unref (texture);
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
drag_prepare_file (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkContentProvider *content;
|
||||
GtkIconTheme *icon_theme;
|
||||
const char *name;
|
||||
GtkIconPaintable *info;
|
||||
|
||||
name = gtk_image_get_icon_name (GTK_IMAGE (widget));
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
|
||||
|
||||
info = gtk_icon_theme_lookup_icon (icon_theme,
|
||||
name,
|
||||
NULL,
|
||||
32, 1,
|
||||
gtk_widget_get_direction (widget),
|
||||
0);
|
||||
content = gdk_content_provider_new_typed (G_TYPE_FILE, gtk_icon_paintable_get_file (info));
|
||||
g_object_unref (info);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_image_dnd (GtkWidget *image)
|
||||
{
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_texture), image);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_scalable_image_dnd (GtkWidget *image)
|
||||
{
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_file), image);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
static void
|
||||
search_mode_toggled (GtkSearchBar *searchbar,
|
||||
GParamSpec *pspec,
|
||||
IconBrowserWindow *win)
|
||||
{
|
||||
if (gtk_search_bar_get_search_mode (searchbar))
|
||||
gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (win->context_model), GTK_INVALID_LIST_POSITION);
|
||||
else if (gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (win->context_model)) == GTK_INVALID_LIST_POSITION)
|
||||
gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (win->context_model), 0);
|
||||
|
||||
gtk_filter_changed (win->search_mode_filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||
}
|
||||
|
||||
static void
|
||||
selected_name_changed (GtkSingleSelection *selection,
|
||||
GParamSpec *pspec,
|
||||
IconBrowserWindow *win)
|
||||
{
|
||||
if (gtk_single_selection_get_selected (selection) != GTK_INVALID_LIST_POSITION)
|
||||
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (win->searchbar), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_window_init (IconBrowserWindow *win)
|
||||
{
|
||||
GtkFilter *filter;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
|
||||
setup_image_dnd (win->image1);
|
||||
setup_image_dnd (win->image2);
|
||||
setup_image_dnd (win->image3);
|
||||
setup_image_dnd (win->image4);
|
||||
setup_image_dnd (win->image5);
|
||||
setup_image_dnd (win->image6);
|
||||
setup_image_dnd (win->image7);
|
||||
setup_scalable_image_dnd (win->image8);
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (win->details), GTK_WINDOW (win));
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (win->searchbar), GTK_WIDGET (win));
|
||||
|
||||
populate (win);
|
||||
|
||||
filter = gtk_filter_list_model_get_filter (GTK_FILTER_LIST_MODEL (win->icon_filter_model));
|
||||
|
||||
win->name_filter = GTK_FILTER (gtk_custom_filter_new (filter_by_icon_name, NULL, NULL));
|
||||
|
||||
gtk_multi_filter_append (GTK_MULTI_FILTER (filter), g_object_ref (win->name_filter));
|
||||
|
||||
g_signal_connect (win->searchbar, "notify::search-mode-enabled", G_CALLBACK (search_mode_toggled), win);
|
||||
g_signal_connect (win->context_model, "notify::selected", G_CALLBACK (selected_name_changed), win);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_window_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), ICON_BROWSER_WINDOW_TYPE);
|
||||
|
||||
G_OBJECT_CLASS (icon_browser_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_window_finalize (GObject *object)
|
||||
{
|
||||
IconBrowserWindow *win = ICON_BROWSER_WINDOW (object);
|
||||
|
||||
g_clear_object (&win->name_filter);
|
||||
|
||||
G_OBJECT_CLASS (icon_browser_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_window_class_init (IconBrowserWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = icon_browser_window_dispose;
|
||||
object_class->finalize = icon_browser_window_finalize;
|
||||
|
||||
g_type_ensure (IB_TYPE_ICON);
|
||||
g_type_ensure (IB_TYPE_CONTEXT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/iconbrowser/gtk/window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, symbolic_radio);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, searchbar);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_store);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_filter_model);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_model);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_store);
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, details);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image1);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image2);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image3);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image4);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image5);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image6);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image7);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image8);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, label8);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, description);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, search_mode_filter);
|
||||
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), item_activated);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
|
||||
}
|
||||
|
||||
IconBrowserWindow *
|
||||
icon_browser_window_new (IconBrowserApp *app)
|
||||
{
|
||||
return g_object_new (ICON_BROWSER_WINDOW_TYPE, "application", app, NULL);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "iconbrowserapp.h"
|
||||
|
||||
|
||||
#define ICON_BROWSER_WINDOW_TYPE (icon_browser_window_get_type ())
|
||||
#define ICON_BROWSER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ICON_BROWSER_WINDOW_TYPE, IconBrowserWindow))
|
||||
|
||||
|
||||
typedef struct _IconBrowserWindow IconBrowserWindow;
|
||||
typedef struct _IconBrowserWindowClass IconBrowserWindowClass;
|
||||
|
||||
|
||||
GType icon_browser_window_get_type (void);
|
||||
IconBrowserWindow *icon_browser_window_new (IconBrowserApp *app);
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <iconbrowserapp.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return g_application_run (G_APPLICATION (icon_browser_app_new ()), argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
iconbrowser_sources = [
|
||||
'main.c',
|
||||
'iconbrowserapp.c',
|
||||
'iconbrowserwin.c',
|
||||
'iconbrowsericon.c',
|
||||
'iconbrowsercontext.c'
|
||||
]
|
||||
|
||||
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
|
||||
'iconbrowser.gresource.xml',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-icon-browser',
|
||||
sources: [iconbrowser_sources, iconbrowser_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, profile_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
foreach size: ['scalable', 'symbolic']
|
||||
install_subdir('data/' + size, install_dir: icontheme_dir)
|
||||
endforeach
|
||||
|
||||
# desktop file
|
||||
install_data('org.gtk.IconBrowser4.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# appdata
|
||||
configure_file(
|
||||
input: 'org.gtk.IconBrowser4.appdata.xml.in',
|
||||
output: 'org.gtk.IconBrowser4.appdata.xml',
|
||||
configuration: appdata_config,
|
||||
install_dir: gtk_appdatadir
|
||||
)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.IconBrowser4</id>
|
||||
<launchable type="desktop-id">org.gtk.IconBrowser4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Icon Browser</name>
|
||||
<summary>Program to browse themed icons</summary>
|
||||
<description>
|
||||
<p>
|
||||
GTK Icon Browser is a simple application to show themed icons that
|
||||
are available on the system.
|
||||
</p>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot>
|
||||
<image>https://static.gnome.org/appdata/gtk4-icon-browser/gtk-icon-browser1.png</image>
|
||||
<caption>Icon Browser</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://static.gnome.org/appdata/gtk4-icon-browser/gtk-icon-browser2.png</image>
|
||||
<caption>Search</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<kudos>
|
||||
<kudo>HiDpiIcon</kudo>
|
||||
<kudo>ModernToolkit</kudo>
|
||||
</kudos>
|
||||
<url type="homepage">https://www.gtk.org</url>
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@BUILD_VERSION@">
|
||||
<description>
|
||||
<p>A new build of GTK.</p>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
||||
@@ -0,0 +1,9 @@
|
||||
[Desktop Entry]
|
||||
Name=Icon Browser
|
||||
Comment=An application that shows themed icons
|
||||
Exec=gtk4-icon-browser
|
||||
Icon=org.gtk.IconBrowser4
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=Development;GTK;
|
||||
@@ -0,0 +1,482 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="gear_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspector</attribute>
|
||||
<attribute name="action">app.inspector</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About GTK Icon Browser</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<template class="IconBrowserWindow" parent="GtkApplicationWindow">
|
||||
<property name="title" translatable="yes">Icon Browser</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<child type="title">
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="normal_radio">
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="label" translatable="yes">Normal</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="symbolic_radio">
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="label" translatable="yes">Symbolic</property>
|
||||
<property name="group">normal_radio</property>
|
||||
<signal name="notify::active" handler="symbolic_toggled" swapped="yes" after="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="gear_menu_button">
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="search">
|
||||
<property name="focus-on-click">0</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage" id="search-icon">
|
||||
<property name="icon-name">edit-find-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<style>
|
||||
<class name="sidebar"/>
|
||||
</style>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<style>
|
||||
<class name="navigation-sidebar"/>
|
||||
</style>
|
||||
<property name="model">
|
||||
<object class="GtkSingleSelection" id="context_model">
|
||||
<property name="model">
|
||||
<object class="GListStore" id="context_store">
|
||||
<property name="item-type">IbContext</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes">
|
||||
<![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="name" type="IbContext">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="content_box">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkSearchBar" id="searchbar">
|
||||
<property name="search-mode-enabled" bind-source="search" bind-property="active" bind-flags="bidirectional"/>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="searchentry">
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="sw">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkGridView" id="list">
|
||||
<style>
|
||||
<class name="content-view"/>
|
||||
</style>
|
||||
<signal name="activate" handler="item_activated"/>
|
||||
<property name="single-click-activate">1</property>
|
||||
<property name="model">
|
||||
<object class="GtkNoSelection">
|
||||
<property name="model">
|
||||
<object class="GtkFilterListModel" id="icon_filter_model">
|
||||
<property name="filter">
|
||||
<object class="GtkEveryFilter">
|
||||
<child>
|
||||
<object class="GtkStringFilter">
|
||||
<property name="expression">
|
||||
<lookup name="name" type="IbIcon"/>
|
||||
</property>
|
||||
<binding name="search">
|
||||
<lookup name="text" type="GtkSearchEntry">
|
||||
searchentry
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAnyFilter">
|
||||
<child>
|
||||
<object class="GtkBoolFilter" id="search_mode_filter">
|
||||
<property name="expression">
|
||||
<lookup name="search-mode-enabled">
|
||||
searchbar
|
||||
</lookup>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStringFilter">
|
||||
<property name="ignore-case">0</property>
|
||||
<property name="match-mode">exact</property>
|
||||
<property name="expression">
|
||||
<lookup name="context" type="IbIcon"/>
|
||||
</property>
|
||||
<binding name="search">
|
||||
<lookup name="id" type="IbContext">
|
||||
<lookup name="selected-item" type="GtkSingleSelection">
|
||||
context_model
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="model">
|
||||
<object class="GListStore" id="icon_store">
|
||||
<property name="item-type">IbIcon</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes">
|
||||
<![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="pixel-size">48</property>
|
||||
<binding name="icon-name">
|
||||
<lookup name="name" type="IbIcon">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<binding name="label">
|
||||
<lookup name="name" type="IbIcon">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
<object class="GtkDialog" id="details">
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="row-spacing">18</property>
|
||||
<property name="column-spacing">18</property>
|
||||
<property name="halign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image3">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image4">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">3</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image5">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image6">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image7">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image8">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<layout>
|
||||
<property name="column">7</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">8×8</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">16×16</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">18×18</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">24×24</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">3</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">32×32</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">48×48</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">64×64</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label">scalable</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">7</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Copy to Clipboard</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">20</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<signal name="clicked" handler="copy_to_clipboard"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="description">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="max-width-chars">60</property>
|
||||
<property name="valign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
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')
|
||||
|
||||
@@ -112,7 +112,7 @@ activate_about (GSimpleAction *action,
|
||||
? "GTK Node Editor (Development)"
|
||||
: "GTK Node Editor",
|
||||
"version", version,
|
||||
"copyright", "© 2019—2024 The GTK Team",
|
||||
"copyright", "© 2019—2021 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to test GTK rendering",
|
||||
@@ -121,12 +121,8 @@ activate_about (GSimpleAction *action,
|
||||
"title", "About GTK Node Editor",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
|
||||
"Artwork by", (const char *[]) { "Jakub Steiner", NULL });
|
||||
gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
|
||||
"Maintained by", (const char *[]) { "The GTK Team", NULL });
|
||||
|
||||
gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
|
||||
"Artwork by", (const char *[]) { "Jakub Steiner", NULL });
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
|
||||
|
||||
@@ -576,6 +576,18 @@ activate_about (GSimpleAction *action,
|
||||
int i;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
const char *authors[] = {
|
||||
"Alexander Larsson",
|
||||
NULL
|
||||
};
|
||||
const char *artists[] = {
|
||||
"Jakub Steiner",
|
||||
NULL
|
||||
};
|
||||
const char *maintainers[] = {
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
GtkWidget *dialog;
|
||||
|
||||
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||
@@ -619,21 +631,19 @@ activate_about (GSimpleAction *action,
|
||||
? "GTK Print Editor (Development)"
|
||||
: "GTK Print Editor",
|
||||
"version", version,
|
||||
"copyright", "© 2006-2024 Red Hat, Inc",
|
||||
"copyright", "© 2006-2021 Red Hat, Inc",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK printing",
|
||||
"authors", (const char *[]) { "Alexander Larsson", NULL },
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.PrintEditor4",
|
||||
"title", "About GTK Print Editor",
|
||||
"system-information", sysinfo->str,
|
||||
NULL);
|
||||
|
||||
gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
|
||||
_("Artwork by"), (const char *[]) { "Jakub Steiner", NULL });
|
||||
|
||||
_("Artwork by"), artists);
|
||||
gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
|
||||
_("Maintained by"), (const char *[]) { "The GTK Team", NULL });
|
||||
_("Maintained by"), maintainers);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
|
||||
|
||||
@@ -294,6 +294,15 @@ activate_about (GSimpleAction *action,
|
||||
GtkApplication *app = user_data;
|
||||
GtkWindow *window;
|
||||
GtkWidget *button;
|
||||
const char *authors[] = {
|
||||
"Andrea Cimitan",
|
||||
"Cosimo Cecchi",
|
||||
NULL
|
||||
};
|
||||
const char *maintainers[] = {
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
char *version;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
@@ -338,18 +347,18 @@ activate_about (GSimpleAction *action,
|
||||
? "GTK Widget Factory (Development)"
|
||||
: "GTK Widget Factory",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2024 The GTK Team",
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK themes and widgets",
|
||||
"authors", (const char *[]) { "Andrea Cimitan", "Cosimo Cecchi", NULL },
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.WidgetFactory4",
|
||||
"title", "About GTK Widget Factory",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
|
||||
_("Maintained by"), (const char *[]) { "The GTK Team", NULL });
|
||||
_("Maintained by"), maintainers);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ if get_option('documentation')
|
||||
gdk_gir[0],
|
||||
],
|
||||
depends: gdk_gir[0],
|
||||
suite: ['docs'],
|
||||
suite: ['docs', 'failing'],
|
||||
)
|
||||
|
||||
if x11_enabled
|
||||
@@ -69,18 +69,6 @@ if get_option('documentation')
|
||||
install: true,
|
||||
install_dir: docs_dir,
|
||||
)
|
||||
|
||||
test('doc-check-gdk-x11',
|
||||
gidocgen,
|
||||
args: [
|
||||
'check',
|
||||
'--config', gdk4x11_toml,
|
||||
'--add-include-path=@0@'.format(meson.current_build_dir() / '../../../gtk'),
|
||||
gdk_x11_gir[0],
|
||||
],
|
||||
depends: gdk_x11_gir[0],
|
||||
suite: ['docs', 'failing'],
|
||||
)
|
||||
endif
|
||||
|
||||
if wayland_enabled
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
.. _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,6 +98,7 @@ 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
|
||||
|
||||
@@ -205,8 +205,7 @@ Other libraries, such as libadwaita, may provide replacements as well.
|
||||
|
||||
## gtk_show_uri is being replaced
|
||||
|
||||
Instead of `gtk_show_uri()`, you should use [class@Gtk.UriLauncher]
|
||||
or [class@Gtk.FileLauncher].
|
||||
Instead of `gtk_show_uri()`, you should use [class@Gtk.UriLauncher]or [class@Gtk.FileLauncher].
|
||||
|
||||
## GtkStatusbar is going away
|
||||
|
||||
|
||||
@@ -474,8 +474,6 @@ 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.
|
||||
|
||||
@@ -113,12 +113,6 @@ static int gdk_initialized = 0; /* 1 if the library is initi
|
||||
* 0 otherwise.
|
||||
*/
|
||||
|
||||
gboolean
|
||||
gdk_is_initialized (void)
|
||||
{
|
||||
return gdk_initialized != 0;
|
||||
}
|
||||
|
||||
static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "misc", GDK_DEBUG_MISC, "Miscellaneous information" },
|
||||
{ "events", GDK_DEBUG_EVENTS, "Information about events" },
|
||||
@@ -366,12 +360,13 @@ gdk_display_open_default (void)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
gdk_ensure_initialized ();
|
||||
g_return_val_if_fail (gdk_initialized, NULL);
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
if (display)
|
||||
return display;
|
||||
|
||||
if (!display)
|
||||
display = gdk_display_open (NULL);
|
||||
display = gdk_display_open (NULL);
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
+1
-1
@@ -478,4 +478,4 @@ gdk_cicp_params_get_cicp (GdkCicpParams *self)
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
+1
-24
@@ -172,35 +172,12 @@ gdk_color_state_get_rec2100_linear (void)
|
||||
return GDK_COLOR_STATE_REC2100_LINEAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_state_get_oklab:
|
||||
*
|
||||
* Returns the color state object representing the oklab color space.
|
||||
*
|
||||
* This is a perceptually uniform color state.
|
||||
*
|
||||
* Returns: the color state object for oklab
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
GdkColorState *
|
||||
gdk_color_state_get_oklab (void)
|
||||
{
|
||||
return GDK_COLOR_STATE_OKLAB;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_state_get_oklch:
|
||||
*
|
||||
* Returns the color state object representing the oklch color space.
|
||||
*
|
||||
* This is the polar variant of oklab, in which the hue is encoded as
|
||||
* a polar coordinate.
|
||||
*
|
||||
* Returns: the color state object for oklch
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
GdkColorState *
|
||||
gdk_color_state_get_oklch (void)
|
||||
{
|
||||
@@ -1068,4 +1045,4 @@ gdk_color_state_clamp (GdkColorState *self,
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
+1
-1
@@ -63,6 +63,6 @@ GDK_AVAILABLE_IN_4_16
|
||||
GdkCicpParams *gdk_color_state_create_cicp_params (GdkColorState *self);
|
||||
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorState, gdk_color_state_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorState, gdk_color_state_unref);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+2
-3
@@ -1198,9 +1198,8 @@ gdk_display_get_app_launch_context (GdkDisplay *display)
|
||||
GdkDisplay *
|
||||
gdk_display_open (const char *display_name)
|
||||
{
|
||||
gdk_ensure_initialized ();
|
||||
|
||||
return gdk_display_manager_open_display (gdk_display_manager_get (), display_name);
|
||||
return gdk_display_manager_open_display (gdk_display_manager_get (),
|
||||
display_name);
|
||||
}
|
||||
|
||||
gulong
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "gdkdisplaymanagerprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkprivate.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
@@ -295,8 +294,6 @@ gdk_display_manager_get (void)
|
||||
{
|
||||
static GdkDisplayManager *manager = NULL;
|
||||
|
||||
gdk_ensure_initialized ();
|
||||
|
||||
if (manager == NULL)
|
||||
manager = g_object_new (GDK_TYPE_DISPLAY_MANAGER, NULL);
|
||||
|
||||
@@ -332,8 +329,6 @@ gdk_display_manager_get_default_display (GdkDisplayManager *manager)
|
||||
GdkDisplay *
|
||||
gdk_display_get_default (void)
|
||||
{
|
||||
gdk_ensure_initialized ();
|
||||
|
||||
return gdk_display_manager_get_default_display (gdk_display_manager_get ());
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,6 @@ GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
||||
const GdkDmabufFormats *formats2);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkDmabufFormats, gdk_dmabuf_formats_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkDmabufFormats, gdk_dmabuf_formats_unref);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+1
-1
@@ -3444,4 +3444,4 @@ gdk_grab_broken_event_get_implicit (GdkEvent *event)
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
+10
-6
@@ -382,6 +382,8 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
return 0;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
|
||||
|
||||
priv->egl_context = ctx;
|
||||
gdk_gl_context_set_version (context, &supported_versions[j]);
|
||||
gdk_gl_context_set_is_legacy (context, legacy);
|
||||
@@ -1750,20 +1752,22 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
{
|
||||
int i, max_texture_size;
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
gdk_debug_message ("%s version: %d.%d (%s)",
|
||||
gdk_debug_message ("%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Max texture size: %d\n",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
|
||||
priv->is_legacy ? "legacy" : "core");
|
||||
gdk_debug_message ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
gdk_debug_message ("Max texture size: %d", max_texture_size);
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
max_texture_size);
|
||||
gdk_debug_message ("Enabled features (use GDK_GL_DISABLE env var to disable):");
|
||||
for (i = 0; i < G_N_ELEMENTS (gdk_gl_feature_keys); i++)
|
||||
{
|
||||
gdk_debug_message (" %s: %s",
|
||||
gdk_gl_feature_keys[i].key,
|
||||
(priv->features & gdk_gl_feature_keys[i].value) ? "✓" :
|
||||
(priv->features & gdk_gl_feature_keys[i].value) ? "YES" :
|
||||
((disabled_features & gdk_gl_feature_keys[i].value) ? "disabled via env var" :
|
||||
(((supported_features & gdk_gl_feature_keys[i].value) == 0) ? "✗" :
|
||||
(((supported_features & gdk_gl_feature_keys[i].value) == 0) ? "not supported" :
|
||||
"Hum, what? This should not happen.")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,6 @@
|
||||
/* Private API for use in GTK+ */
|
||||
|
||||
void gdk_pre_parse (void);
|
||||
gboolean gdk_is_initialized (void);
|
||||
|
||||
#define gdk_ensure_initialized() \
|
||||
G_STMT_START { \
|
||||
if (!gdk_is_initialized ()) \
|
||||
g_error ("%s() was called before gtk_init()", G_STRFUNC); \
|
||||
} G_STMT_END
|
||||
|
||||
gboolean gdk_running_in_sandbox (void);
|
||||
gboolean gdk_should_use_portal (void);
|
||||
|
||||
+9
-59
@@ -35,7 +35,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
static const GdkDebugKey gdk_vulkan_feature_keys[] = {
|
||||
static const GdkDebugKey gsk_vulkan_feature_keys[] = {
|
||||
{ "dmabuf", GDK_VULKAN_FEATURE_DMABUF, "Never import Dmabufs" },
|
||||
{ "ycbcr", GDK_VULKAN_FEATURE_YCBCR, "Do not support Ycbcr textures (also disables dmabufs)" },
|
||||
{ "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" },
|
||||
@@ -419,10 +419,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
VkDevice device;
|
||||
guint i;
|
||||
|
||||
GDK_DEBUG (VULKAN, "(Re)creating the swapchain for surface of size %dx%d",
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface));
|
||||
|
||||
device = gdk_vulkan_context_get_device (context);
|
||||
|
||||
/*
|
||||
@@ -460,10 +456,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
|
||||
GDK_DEBUG (VULKAN, "Using surface present mode %s",
|
||||
surface_present_mode_to_string (present_mode));
|
||||
GDK_DEBUG (VULKAN, "Using extent %dx%d",
|
||||
capabilities.currentExtent.width,
|
||||
capabilities.currentExtent.height);
|
||||
|
||||
|
||||
/*
|
||||
* Per https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#VkSurfaceCapabilitiesKHR
|
||||
@@ -476,10 +468,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
|
||||
capabilities.currentExtent.width = MAX (1, (int) ceil (gdk_surface_get_width (surface) * scale));
|
||||
capabilities.currentExtent.height = MAX (1, (int) ceil (gdk_surface_get_height (surface) * scale));
|
||||
|
||||
GDK_DEBUG (VULKAN, "Effective extent %dx%d",
|
||||
capabilities.currentExtent.width,
|
||||
capabilities.currentExtent.height);
|
||||
}
|
||||
|
||||
res = GDK_VK_CHECK (vkCreateSwapchainKHR, device,
|
||||
@@ -566,20 +554,12 @@ physical_device_supports_extension (VkPhysicalDevice device,
|
||||
{
|
||||
VkExtensionProperties *extensions;
|
||||
uint32_t n_device_extensions;
|
||||
static gboolean first = TRUE;
|
||||
|
||||
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, NULL);
|
||||
|
||||
extensions = g_newa (VkExtensionProperties, n_device_extensions);
|
||||
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, extensions);
|
||||
|
||||
if (first)
|
||||
{
|
||||
first = FALSE;
|
||||
for (uint32_t i = 0; i < n_device_extensions; i++)
|
||||
GDK_DEBUG (VULKAN, "%s", extensions[i].extensionName);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < n_device_extensions; i++)
|
||||
{
|
||||
if (g_str_equal (extensions[i].extensionName, extension_name))
|
||||
@@ -706,37 +686,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (acquire_result == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
const VkPipelineStageFlags mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
|
||||
vkQueueSubmit (gdk_vulkan_context_get_queue (context),
|
||||
1,
|
||||
&(VkSubmitInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &priv->draw_semaphore,
|
||||
.pWaitDstStageMask = &mask,
|
||||
},
|
||||
VK_NULL_HANDLE);
|
||||
vkQueueWaitIdle (gdk_vulkan_context_get_queue (context));
|
||||
|
||||
if (gdk_vulkan_context_has_feature (context, GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE))
|
||||
{
|
||||
PFN_vkReleaseSwapchainImagesEXT vkReleaseSwapchainImagesEXT;
|
||||
|
||||
vkReleaseSwapchainImagesEXT = (PFN_vkReleaseSwapchainImagesEXT) vkGetDeviceProcAddr (gdk_vulkan_context_get_device (context), "vkReleaseSwapchainImagesEXT");
|
||||
|
||||
vkReleaseSwapchainImagesEXT (gdk_vulkan_context_get_device (context),
|
||||
&(VkReleaseSwapchainImagesInfoEXT) {
|
||||
.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT,
|
||||
.pNext = NULL,
|
||||
.swapchain = priv->swapchain,
|
||||
.imageIndexCount = 1,
|
||||
.pImageIndices = &priv->draw_index,
|
||||
});
|
||||
}
|
||||
}
|
||||
GDK_DEBUG (VULKAN, "Recreating the swapchain");
|
||||
|
||||
if (gdk_vulkan_context_check_swapchain (context, &error))
|
||||
continue;
|
||||
@@ -1474,8 +1424,8 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
|
||||
skip_features = gdk_parse_debug_var ("GDK_VULKAN_DISABLE",
|
||||
"GDK_VULKAN_DISABLE can be set to a list of Vulkan features to disable.\n",
|
||||
gdk_vulkan_feature_keys,
|
||||
G_N_ELEMENTS (gdk_vulkan_feature_keys));
|
||||
gsk_vulkan_feature_keys,
|
||||
G_N_ELEMENTS (gsk_vulkan_feature_keys));
|
||||
if (skip_features & GDK_VULKAN_FEATURE_YCBCR)
|
||||
skip_features |= GDK_VULKAN_FEATURE_DMABUF;
|
||||
|
||||
@@ -1622,13 +1572,13 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
display->vulkan_features = features;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, VULKAN, "Enabled features (use GDK_VULKAN_DISABLE env var to disable):");
|
||||
for (i = 0; i < G_N_ELEMENTS (gdk_vulkan_feature_keys); i++)
|
||||
for (i = 0; i < G_N_ELEMENTS (gsk_vulkan_feature_keys); i++)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, VULKAN, " %s: %s",
|
||||
gdk_vulkan_feature_keys[i].key,
|
||||
(features & gdk_vulkan_feature_keys[i].value) ? "✓" :
|
||||
((skip_features & gdk_vulkan_feature_keys[i].value) ? "disabled via env var" :
|
||||
(((device_features & gdk_vulkan_feature_keys[i].value) == 0) ? "✗" :
|
||||
gsk_vulkan_feature_keys[i].key,
|
||||
(features & gsk_vulkan_feature_keys[i].value) ? "YES" :
|
||||
((skip_features & gsk_vulkan_feature_keys[i].value) ? "disabled via env var" :
|
||||
(((device_features & gsk_vulkan_feature_keys[i].value) == 0) ? "not supported" :
|
||||
"Hum, what? This should not happen.")));
|
||||
}
|
||||
|
||||
|
||||
@@ -298,4 +298,4 @@ gdk_save_jpeg (GdkTexture *texture)
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -653,4 +653,4 @@ gdk_save_png (GdkTexture *texture)
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -512,4 +512,4 @@ gdk_load_tiff (GBytes *input_bytes,
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -146,6 +146,14 @@ typedef NSString *CALayerContentsGravity;
|
||||
inManualResize = NO;
|
||||
inMove = NO;
|
||||
|
||||
/* We need to deliver the event to the proper drag gestures or we
|
||||
* will leave the window in inconsistent state that requires clicking
|
||||
* in the window to cancel the gesture.
|
||||
*
|
||||
* TODO: Can we improve grab breaking to fix this?
|
||||
*/
|
||||
_gdk_macos_display_send_event ([self gdkDisplay], event);
|
||||
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
|
||||
|
||||
/* Reset gravity */
|
||||
|
||||
@@ -391,7 +391,7 @@ _gdk_macos_pasteboard_register_drag_types (NSWindow *window)
|
||||
/* Default to an url type (think gobject://internal)
|
||||
* to support internal, GType-based DnD.
|
||||
*/
|
||||
if ([ret count] == 0)
|
||||
if (n_mime_types == 0)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
gsize n_gtypes;
|
||||
|
||||
@@ -548,12 +548,6 @@ gdk_registry_handle_global (void *data,
|
||||
&wp_single_pixel_buffer_manager_v1_interface,
|
||||
MIN (version, 1));
|
||||
}
|
||||
else if (strcmp (interface, xdg_system_bell_v1_interface.name) == 0)
|
||||
{
|
||||
display_wayland->system_bell =
|
||||
wl_registry_bind (display_wayland->wl_registry, id,
|
||||
&xdg_system_bell_v1_interface, 1);
|
||||
}
|
||||
|
||||
g_hash_table_insert (display_wayland->known_globals,
|
||||
GUINT_TO_POINTER (id), g_strdup (interface));
|
||||
@@ -774,7 +768,6 @@ gdk_wayland_display_dispose (GObject *object)
|
||||
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
|
||||
g_clear_pointer (&display_wayland->dmabuf_formats_info, dmabuf_formats_info_free);
|
||||
g_clear_pointer (&display_wayland->color, gdk_wayland_color_free);
|
||||
g_clear_pointer (&display_wayland->system_bell, xdg_system_bell_v1_destroy);
|
||||
|
||||
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
|
||||
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);
|
||||
@@ -821,32 +814,23 @@ gdk_wayland_display_get_name (GdkDisplay *display)
|
||||
|
||||
void
|
||||
gdk_wayland_display_system_bell (GdkDisplay *display,
|
||||
GdkSurface *surface)
|
||||
GdkSurface *window)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
struct gtk_surface1 *gtk_surface = NULL;
|
||||
struct wl_surface *wl_surface = NULL;
|
||||
struct gtk_surface1 *gtk_surface;
|
||||
gint64 now_ms;
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
if (!display_wayland->gtk_shell &&
|
||||
!display_wayland->system_bell)
|
||||
if (!display_wayland->gtk_shell)
|
||||
return;
|
||||
|
||||
if (surface)
|
||||
{
|
||||
if (GDK_IS_WAYLAND_TOPLEVEL (surface))
|
||||
{
|
||||
GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (surface);
|
||||
|
||||
gtk_surface = gdk_wayland_toplevel_get_gtk_surface (toplevel);
|
||||
}
|
||||
|
||||
wl_surface = gdk_wayland_surface_get_wl_surface (surface);
|
||||
}
|
||||
if (window && GDK_IS_WAYLAND_TOPLEVEL (window))
|
||||
gtk_surface = gdk_wayland_toplevel_get_gtk_surface (GDK_WAYLAND_TOPLEVEL (window));
|
||||
else
|
||||
gtk_surface = NULL;
|
||||
|
||||
now_ms = g_get_monotonic_time () / 1000;
|
||||
if (now_ms - display_wayland->last_bell_time_ms < MIN_SYSTEM_BELL_DELAY_MS)
|
||||
@@ -854,10 +838,7 @@ gdk_wayland_display_system_bell (GdkDisplay *display,
|
||||
|
||||
display_wayland->last_bell_time_ms = now_ms;
|
||||
|
||||
if (display_wayland->system_bell)
|
||||
xdg_system_bell_v1_ring (display_wayland->system_bell, wl_surface);
|
||||
else
|
||||
gtk_shell1_system_bell (display_wayland->gtk_shell, gtk_surface);
|
||||
gtk_shell1_system_bell (display_wayland->gtk_shell, gtk_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <gdk/wayland/presentation-time-client-protocol.h>
|
||||
#include <gdk/wayland/single-pixel-buffer-v1-client-protocol.h>
|
||||
#include <gdk/wayland/xdg-dialog-v1-client-protocol.h>
|
||||
#include <gdk/wayland/xdg-system-bell-v1-client-protocol.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkkeys.h>
|
||||
@@ -107,7 +106,6 @@ struct _GdkWaylandDisplay
|
||||
struct zxdg_shell_v6 *zxdg_shell_v6;
|
||||
struct xdg_wm_dialog_v1 *xdg_wm_dialog;
|
||||
struct gtk_shell1 *gtk_shell;
|
||||
struct xdg_system_bell_v1 *system_bell;
|
||||
struct wl_data_device_manager *data_device_manager;
|
||||
struct wl_subcompositor *subcompositor;
|
||||
struct zwp_pointer_gestures_v1 *pointer_gestures;
|
||||
|
||||
@@ -1485,4 +1485,4 @@ _gdk_wayland_surface_set_grab_seat (GdkSurface *surface,
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -1482,4 +1482,4 @@ gdk_wayland_surface_get_wl_surface (GdkSurface *surface)
|
||||
}
|
||||
|
||||
/* }}}} */
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -2765,4 +2765,4 @@ gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel,
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker: */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -151,11 +151,6 @@ proto_sources = [
|
||||
'stability': 'private',
|
||||
'version': 4,
|
||||
},
|
||||
{
|
||||
'name': 'xdg-system-bell',
|
||||
'stability': 'private',
|
||||
'version': 1,
|
||||
},
|
||||
]
|
||||
|
||||
gdk_wayland_gen_headers = []
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_system_bell_v1">
|
||||
<copyright>
|
||||
Copyright © 2016, 2023 Red Hat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="xdg_system_bell_v1" version="1">
|
||||
<description summary="system bell">
|
||||
This global interface enables clients to ring the system bell.
|
||||
|
||||
Warning! The protocol described in this file is currently in the testing
|
||||
phase. Backward compatible changes may be added together with the
|
||||
corresponding interface version bump. Backward incompatible changes can
|
||||
only be done by creating a new major version of the extension.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the system bell object">
|
||||
Notify that the object will no longer be used.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="ring">
|
||||
<description summary="ring the system bell">
|
||||
This requests rings the system bell on behalf of a client. How ringing
|
||||
the bell is implemented is up to the compositor. It may be an audible
|
||||
sound, a visual feedback of some kind, or any other thing including
|
||||
nothing.
|
||||
|
||||
The passed surface should correspond to a toplevel like surface role,
|
||||
or be null, meaning the client doesn't have a particular toplevel it
|
||||
wants to associate the bell ringing with. See the xdg-shell protocol
|
||||
extension for a toplevel like surface role.
|
||||
</description>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
allow-null="true" summary="associated surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkclipboard-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
|
||||
#include "gdkdebugprivate.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
@@ -63,7 +62,7 @@ gdk_win32_clipboard_request_contentformats (GdkWin32Clipboard *cb)
|
||||
UINT w32_formats_allocated;
|
||||
gsize i;
|
||||
GArray *formatpairs;
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (cb));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
DWORD error_code;
|
||||
|
||||
SetLastError (0);
|
||||
@@ -95,7 +94,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_clipdrop_add_win32_format_to_pairs (clipdrop, w32_formats[i], formatpairs, NULL);
|
||||
_gdk_win32_add_w32format_to_pairs (w32_formats[i], formatpairs, NULL);
|
||||
|
||||
g_free (w32_formats);
|
||||
|
||||
@@ -165,7 +164,7 @@ gdk_win32_clipboard_claim (GdkClipboard *clipboard,
|
||||
GdkContentProvider *content)
|
||||
{
|
||||
if (local)
|
||||
_gdk_win32_advertise_clipboard_contentformats (clipboard, NULL, content ? formats : NULL);
|
||||
_gdk_win32_advertise_clipboard_contentformats (NULL, content ? formats : NULL);
|
||||
|
||||
return GDK_CLIPBOARD_CLASS (gdk_win32_clipboard_parent_class)->claim (clipboard, formats, local, content);
|
||||
}
|
||||
@@ -233,7 +232,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 (clipboard, task, contentformats);
|
||||
_gdk_win32_retrieve_clipboard_contentformats (task, contentformats);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -297,8 +296,3 @@ 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,7 +18,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdk/gdkclipboard.h"
|
||||
#include "gdkprivate-win32.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -34,7 +33,5 @@ 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
|
||||
|
||||
|
||||
+177
-203
@@ -279,7 +279,6 @@ 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"
|
||||
@@ -301,6 +300,15 @@ 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
|
||||
@@ -429,6 +437,11 @@ 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
|
||||
@@ -472,7 +485,7 @@ _gdk_win32_format_uses_hdata (UINT w32format)
|
||||
static gboolean
|
||||
clipboard_hwnd_created (gpointer user_data)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_display_get_default ());
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
clipdrop->clipboard_hwnd = (HWND) user_data;
|
||||
|
||||
@@ -505,7 +518,7 @@ clipboard_render_hdata_ready (GObject *clipboard,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkWin32ClipboardRenderAndStream render_and_stream = *(GdkWin32ClipboardRenderAndStream *) user_data;
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (clipboard));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
g_free (user_data);
|
||||
|
||||
@@ -540,11 +553,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 (clipdrop, &render->pair, &error);
|
||||
GOutputStream *stream = gdk_win32_hdata_output_stream_new (&render->pair, &error);
|
||||
GdkWin32ClipboardRenderAndStream *render_and_stream;
|
||||
|
||||
if (stream == NULL)
|
||||
@@ -671,32 +684,28 @@ 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 (GdkWin32Clipdrop *clipdrop,
|
||||
HWND hwnd)
|
||||
try_open_clipboard (HWND hwnd)
|
||||
{
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == hwnd)
|
||||
if (clipboard_thread_data->clipboard_opened_for == hwnd)
|
||||
return NO_ERROR;
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE)
|
||||
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
API_CALL (CloseClipboard, ());
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
|
||||
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!OpenClipboard (hwnd))
|
||||
return GetLastError ();
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = hwnd;
|
||||
clipboard_thread_data->clipboard_opened_for = hwnd;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ClipboardThreadAdvertise *adv)
|
||||
process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
{
|
||||
DWORD error_code;
|
||||
int i;
|
||||
@@ -711,7 +720,7 @@ process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > adv->parent.start_time)
|
||||
if (clipboard_thread_data->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,
|
||||
@@ -721,7 +730,7 @@ process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
error_code = try_open_clipboard (clipdrop, adv->unset ? NULL : CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
error_code = try_open_clipboard (adv->unset ? NULL : clipboard_thread_data->clipboard_hwnd);
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -735,10 +744,10 @@ process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = TRUE;
|
||||
clipboard_thread_data->ignore_destroy_clipboard = TRUE;
|
||||
if (!EmptyClipboard ())
|
||||
{
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = FALSE;
|
||||
clipboard_thread_data->ignore_destroy_clipboard = FALSE;
|
||||
error_code = GetLastError ();
|
||||
send_response (adv->parent.item_type,
|
||||
adv->parent.opaque_task,
|
||||
@@ -747,7 +756,7 @@ process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = FALSE;
|
||||
clipboard_thread_data->ignore_destroy_clipboard = FALSE;
|
||||
|
||||
if (adv->unset)
|
||||
return FALSE;
|
||||
@@ -759,10 +768,10 @@ process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
SetClipboardData (pair->w32format, NULL);
|
||||
}
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement))
|
||||
g_array_free (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), TRUE);
|
||||
if (clipboard_thread_data->cached_advertisement)
|
||||
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) = adv->pairs;
|
||||
clipboard_thread_data->cached_advertisement = adv->pairs;
|
||||
|
||||
/* To enure that we don't free it later on */
|
||||
adv->pairs = NULL;
|
||||
@@ -775,8 +784,7 @@ process_advertise (GdkWin32Clipdrop *clipdrop,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_store (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ClipboardThreadStore *store)
|
||||
process_store (GdkWin32ClipboardThreadStore *store)
|
||||
{
|
||||
DWORD error_code;
|
||||
int i;
|
||||
@@ -791,7 +799,7 @@ process_store (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > store->parent.start_time)
|
||||
if (clipboard_thread_data->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,
|
||||
@@ -801,7 +809,7 @@ process_store (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -823,7 +831,7 @@ process_store (GdkWin32Clipdrop *clipdrop,
|
||||
* that we already own, otherwise we're just killing stuff that some other
|
||||
* process put in there, which is not nice.
|
||||
*/
|
||||
if (GetClipboardOwner () != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
|
||||
if (GetClipboardOwner () != clipboard_thread_data->clipboard_hwnd)
|
||||
{
|
||||
send_response (store->parent.item_type,
|
||||
store->parent.opaque_task,
|
||||
@@ -902,8 +910,7 @@ grab_data_from_hdata (GdkWin32ClipboardThreadRetrieve *retr,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_retrieve (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ClipboardThreadRetrieve *retr)
|
||||
process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
|
||||
{
|
||||
DWORD error_code;
|
||||
int i;
|
||||
@@ -924,7 +931,7 @@ process_retrieve (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > retr->parent.start_time)
|
||||
if (clipboard_thread_data->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,
|
||||
@@ -944,10 +951,10 @@ process_retrieve (GdkWin32Clipdrop *clipdrop,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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));
|
||||
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
|
||||
else
|
||||
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for));
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_opened_for);
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -1014,7 +1021,7 @@ process_retrieve (GdkWin32Clipdrop *clipdrop,
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_win32_clipdrop_transmute_windows_data (clipdrop, pair->w32format, pair->contentformat, hdata, &data, &data_len);
|
||||
_gdk_win32_transmute_windows_data (pair->w32format, pair->contentformat, hdata, &data, &data_len);
|
||||
|
||||
if (data == NULL)
|
||||
return FALSE;
|
||||
@@ -1033,14 +1040,14 @@ process_retrieve (GdkWin32Clipdrop *clipdrop,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_clipboard_queue (GdkWin32Clipdrop *clipdrop)
|
||||
process_clipboard_queue ()
|
||||
{
|
||||
GdkWin32ClipboardThreadQueueItem *placeholder;
|
||||
GList *p;
|
||||
gboolean try_again;
|
||||
GList *p_next;
|
||||
|
||||
for (p = CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), p_next = NULL; p; p = p_next)
|
||||
for (p = clipboard_thread_data->dequeued_items, p_next = NULL; p; p = p_next)
|
||||
{
|
||||
placeholder = (GdkWin32ClipboardThreadQueueItem *) p->data;
|
||||
p_next = p->next;
|
||||
@@ -1048,35 +1055,35 @@ process_clipboard_queue (GdkWin32Clipdrop *clipdrop)
|
||||
switch (placeholder->item_type)
|
||||
{
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE:
|
||||
try_again = process_advertise (clipdrop, (GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
try_again = process_advertise ((GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE:
|
||||
try_again = process_retrieve (clipdrop, (GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
try_again = process_retrieve ((GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_STORE:
|
||||
try_again = process_store (clipdrop, (GdkWin32ClipboardThreadStore *) placeholder);
|
||||
try_again = process_store ((GdkWin32ClipboardThreadStore *) placeholder);
|
||||
break;
|
||||
}
|
||||
|
||||
if (try_again)
|
||||
return FALSE;
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items) = g_list_delete_link (CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), p);
|
||||
clipboard_thread_data->dequeued_items = g_list_delete_link (clipboard_thread_data->dequeued_items, p);
|
||||
free_queue_item (placeholder);
|
||||
}
|
||||
|
||||
while ((placeholder = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, input_queue))) != NULL)
|
||||
while ((placeholder = g_async_queue_try_pop (clipboard_thread_data->input_queue)) != NULL)
|
||||
{
|
||||
switch (placeholder->item_type)
|
||||
{
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE:
|
||||
try_again = process_advertise (clipdrop, (GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
try_again = process_advertise ((GdkWin32ClipboardThreadAdvertise *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE:
|
||||
try_again = process_retrieve (clipdrop, (GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
try_again = process_retrieve ((GdkWin32ClipboardThreadRetrieve *) placeholder);
|
||||
break;
|
||||
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_STORE:
|
||||
try_again = process_store (clipdrop, (GdkWin32ClipboardThreadStore *) placeholder);
|
||||
try_again = process_store ((GdkWin32ClipboardThreadStore *) placeholder);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1086,7 +1093,7 @@ process_clipboard_queue (GdkWin32Clipdrop *clipdrop)
|
||||
continue;
|
||||
}
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items) = g_list_append (CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), placeholder);
|
||||
clipboard_thread_data->dequeued_items = g_list_append (clipboard_thread_data->dequeued_items, placeholder);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1117,37 +1124,23 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
{
|
||||
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 ||
|
||||
if (message == thread_wakeup_message ||
|
||||
message == WM_TIMER)
|
||||
{
|
||||
gboolean queue_is_empty = FALSE;
|
||||
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
if (clipboard_thread_data == 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 (clipdrop);
|
||||
queue_is_empty = process_clipboard_queue ();
|
||||
|
||||
if (queue_is_empty && CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer))
|
||||
if (queue_is_empty && clipboard_thread_data->wakeup_timer)
|
||||
{
|
||||
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;
|
||||
API_CALL (KillTimer, (clipboard_thread_data->clipboard_hwnd, clipboard_thread_data->wakeup_timer));
|
||||
clipboard_thread_data->wakeup_timer = 0;
|
||||
}
|
||||
|
||||
/* Close the clipboard after each queue run, if it's open.
|
||||
@@ -1156,21 +1149,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 (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE)
|
||||
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
API_CALL (CloseClipboard, ());
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
|
||||
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (queue_is_empty ||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) != 0)
|
||||
clipboard_thread_data->wakeup_timer != 0)
|
||||
return 0;
|
||||
|
||||
if (SetTimer (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), 1, 1000, NULL))
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) = 1;
|
||||
if (SetTimer (clipboard_thread_data->clipboard_hwnd, 1, 1000, NULL))
|
||||
clipboard_thread_data->wakeup_timer = 1;
|
||||
else
|
||||
g_critical ("Failed to set a timer for the clipboard HWND 0x%p: %lu",
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd),
|
||||
clipboard_thread_data->clipboard_hwnd,
|
||||
GetLastError ());
|
||||
}
|
||||
|
||||
@@ -1178,7 +1171,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
{
|
||||
case WM_DESTROY: /* unregister the clipboard listener */
|
||||
{
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
if (clipboard_thread_data == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
@@ -1199,7 +1192,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
/*
|
||||
GdkEvent *event;
|
||||
*/
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
if (clipboard_thread_data == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
@@ -1217,7 +1210,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
/* FIXME: grab and print clipboard formats without opening the clipboard
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE ||
|
||||
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE ||
|
||||
OpenClipboard (hwnd))
|
||||
{
|
||||
UINT nFormat = 0;
|
||||
@@ -1225,7 +1218,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
while ((nFormat = EnumClipboardFormats (nFormat)) != 0)
|
||||
g_print ("%s ", _gdk_win32_cf_to_string (nFormat));
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == INVALID_HANDLE_VALUE)
|
||||
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
|
||||
CloseClipboard ();
|
||||
}
|
||||
else
|
||||
@@ -1237,22 +1230,22 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
|
||||
GDK_NOTE (DND, g_print (" \n"));
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, stored_hwnd_owner) != hwnd_owner)
|
||||
if (clipboard_thread_data->stored_hwnd_owner != hwnd_owner)
|
||||
{
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, stored_hwnd_owner) = hwnd_owner;
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) = g_get_monotonic_time ();
|
||||
clipboard_thread_data->stored_hwnd_owner = hwnd_owner;
|
||||
clipboard_thread_data->owner_change_time = g_get_monotonic_time ();
|
||||
|
||||
if (hwnd_owner != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
|
||||
{
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement))
|
||||
g_array_free (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), TRUE);
|
||||
if (clipboard_thread_data->cached_advertisement)
|
||||
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) = NULL;
|
||||
clipboard_thread_data->cached_advertisement = NULL;
|
||||
}
|
||||
|
||||
API_CALL (PostMessage, (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipboard_thread_data->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
if (hwnd_owner != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_owner_changed, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1263,13 +1256,13 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
}
|
||||
case WM_RENDERALLFORMATS:
|
||||
{
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
if (clipboard_thread_data == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement == NULL))
|
||||
if (clipboard_thread_data->cached_advertisement == NULL)
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
|
||||
if (API_CALL (OpenClipboard, (hwnd)))
|
||||
@@ -1278,10 +1271,10 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
GdkWin32ContentFormatPair *pair;
|
||||
|
||||
for (pair = NULL, i = 0;
|
||||
i < CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement)->len;
|
||||
i < clipboard_thread_data->cached_advertisement->len;
|
||||
i++)
|
||||
{
|
||||
pair = &g_array_index (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), GdkWin32ContentFormatPair, i);
|
||||
pair = &g_array_index (clipboard_thread_data->cached_advertisement, GdkWin32ContentFormatPair, i);
|
||||
|
||||
if (pair->w32format != 0)
|
||||
SendMessage (hwnd, WM_RENDERFORMAT, pair->w32format, 0);
|
||||
@@ -1302,20 +1295,20 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
|
||||
GDK_NOTE (EVENTS, g_print (" %s", _gdk_win32_cf_to_string (wparam)));
|
||||
|
||||
if (clipdrop->clipboard_thread_items == NULL)
|
||||
if (clipboard_thread_data == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) == NULL)
|
||||
if (clipboard_thread_data->cached_advertisement == NULL)
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
|
||||
for (pair = NULL, i = 0;
|
||||
i < CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement)->len;
|
||||
i < clipboard_thread_data->cached_advertisement->len;
|
||||
i++)
|
||||
{
|
||||
pair = &g_array_index (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), GdkWin32ContentFormatPair, i);
|
||||
pair = &g_array_index (clipboard_thread_data->cached_advertisement, GdkWin32ContentFormatPair, i);
|
||||
|
||||
if (pair->w32format == wparam)
|
||||
break;
|
||||
@@ -1330,13 +1323,13 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
}
|
||||
|
||||
/* Clear the queue */
|
||||
while ((render = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue))) != NULL)
|
||||
while ((render = g_async_queue_try_pop (clipboard_thread_data->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 (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue), CLIPBOARD_RENDER_TIMEOUT);
|
||||
returned_render = g_async_queue_timeout_pop (clipboard_thread_data->render_queue, CLIPBOARD_RENDER_TIMEOUT);
|
||||
|
||||
/* We should get back the same pointer, ignore everything else. */
|
||||
while (returned_render != NULL && returned_render != render)
|
||||
@@ -1350,7 +1343,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 (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue));
|
||||
returned_render = g_async_queue_try_pop (clipboard_thread_data->render_queue);
|
||||
}
|
||||
|
||||
/* Just in case */
|
||||
@@ -1410,7 +1403,7 @@ _clipboard_hwnd_procedure (HWND hwnd,
|
||||
* Creates a hidden HWND and add a clipboard listener
|
||||
*/
|
||||
static gboolean
|
||||
register_clipboard_notification (GdkWin32Clipdrop *clipdrop)
|
||||
register_clipboard_notification ()
|
||||
{
|
||||
WNDCLASS wclass = { 0, };
|
||||
ATOM klass;
|
||||
@@ -1424,24 +1417,23 @@ register_clipboard_notification (GdkWin32Clipdrop *clipdrop)
|
||||
if (!klass)
|
||||
return FALSE;
|
||||
|
||||
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd) =
|
||||
CreateWindow (MAKEINTRESOURCE (klass),
|
||||
NULL, WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL,
|
||||
this_module (), clipdrop);
|
||||
clipboard_thread_data->clipboard_hwnd = CreateWindow (MAKEINTRESOURCE (klass),
|
||||
NULL, WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL,
|
||||
this_module (), NULL);
|
||||
|
||||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd) == NULL)
|
||||
if (clipboard_thread_data->clipboard_hwnd == NULL)
|
||||
goto failed;
|
||||
|
||||
SetLastError (0);
|
||||
|
||||
if (AddClipboardFormatListener (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd)) == FALSE)
|
||||
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_hwnd) == FALSE)
|
||||
{
|
||||
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
|
||||
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), NULL);
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) clipboard_thread_data->clipboard_hwnd, NULL);
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -1455,21 +1447,20 @@ static gpointer
|
||||
_gdk_win32_clipboard_thread_main (gpointer data)
|
||||
{
|
||||
MSG msg;
|
||||
clipdrop_thread_items *items = (clipdrop_thread_items*) data;
|
||||
GAsyncQueue *queue = items->queue;
|
||||
GAsyncQueue *queue = (GAsyncQueue *) data;
|
||||
GAsyncQueue *render_queue = (GAsyncQueue *) g_async_queue_pop (queue);
|
||||
|
||||
g_assert (items->clipdrop->clipboard_thread_items == NULL);
|
||||
g_assert (clipboard_thread_data == NULL);
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
if (!register_clipboard_notification (items->clipdrop))
|
||||
if (!register_clipboard_notification ())
|
||||
{
|
||||
g_async_queue_unref (queue);
|
||||
g_clear_pointer (&items->clipdrop->clipboard_thread_items, g_free);
|
||||
g_clear_pointer (&clipboard_thread_data, g_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1481,33 +1472,26 @@ _gdk_win32_clipboard_thread_main (gpointer data)
|
||||
}
|
||||
|
||||
/* Just in case, as this should only happen when we shut down */
|
||||
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_hwnd));
|
||||
CloseHandle (CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_hwnd));
|
||||
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
|
||||
CloseHandle (clipboard_thread_data->clipboard_hwnd);
|
||||
g_async_queue_unref (queue);
|
||||
g_clear_pointer (&items->clipdrop->clipboard_thread_items, g_free);
|
||||
g_clear_pointer (&clipboard_thread_data, g_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32Clipdrop, gdk_win32_clipdrop, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_clipdrop_class_init (GdkWin32ClipdropClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
}
|
||||
|
||||
object_class->finalize = gdk_win32_clipdrop_finalize;
|
||||
void
|
||||
_gdk_win32_clipdrop_init (void)
|
||||
{
|
||||
_win32_main_thread = g_thread_self ();
|
||||
_win32_clipdrop = GDK_WIN32_CLIPDROP (g_object_new (GDK_TYPE_WIN32_CLIPDROP, NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1521,9 +1505,8 @@ gdk_win32_clipdrop_init (GdkWin32Clipdrop *win32_clipdrop)
|
||||
GArray *comp;
|
||||
GdkWin32ContentFormatPair fmt;
|
||||
HMODULE user32;
|
||||
clipdrop_thread_items cb_items, dnd_items;
|
||||
|
||||
win32_clipdrop->thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
|
||||
thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
|
||||
|
||||
user32 = LoadLibrary (L"user32.dll");
|
||||
win32_clipdrop->GetUpdatedClipboardFormats = (GetUpdatedClipboardFormatsFunc) GetProcAddress (user32, "GetUpdatedClipboardFormats");
|
||||
@@ -1815,17 +1798,14 @@ 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,
|
||||
&cb_items);
|
||||
g_async_queue_ref (win32_clipdrop->clipboard_open_thread_queue));
|
||||
|
||||
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,
|
||||
&dnd_items);
|
||||
g_async_queue_ref (win32_clipdrop->dnd_queue));
|
||||
win32_clipdrop->dnd_thread_id = GPOINTER_TO_UINT (g_async_queue_pop (win32_clipdrop->dnd_queue));
|
||||
}
|
||||
|
||||
@@ -1947,11 +1927,11 @@ _gdk_win32_get_clipboard_format_name_as_interned_mimetype (char *w32format_name)
|
||||
}
|
||||
|
||||
static GArray *
|
||||
get_compatibility_w32formats_for_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
const char *contentformat)
|
||||
get_compatibility_w32formats_for_contentformat (const char *contentformat)
|
||||
{
|
||||
GArray *result = NULL;
|
||||
int i;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
result = g_hash_table_lookup (clipdrop->compatibility_w32formats, contentformat);
|
||||
|
||||
@@ -1965,7 +1945,7 @@ get_compatibility_w32formats_for_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
|
||||
/* 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 (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_PNG));
|
||||
_gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_PNG));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1973,10 +1953,10 @@ get_compatibility_w32formats_for_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
}
|
||||
|
||||
static GArray *
|
||||
_gdk_win32_get_compatibility_contentformats_for_w32format (GdkWin32Clipdrop *clipdrop,
|
||||
UINT w32format)
|
||||
_gdk_win32_get_compatibility_contentformats_for_w32format (UINT w32format)
|
||||
{
|
||||
GArray *result = NULL;
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
result = g_hash_table_lookup (clipdrop->compatibility_contentformats, GINT_TO_POINTER (w32format));
|
||||
|
||||
@@ -2003,10 +1983,9 @@ _gdk_win32_get_compatibility_contentformats_for_w32format (GdkWin32Clipdrop *cli
|
||||
* (builder already takes care of that for itself).
|
||||
*/
|
||||
void
|
||||
gdk_win32_clipdrop_add_win32_format_to_pairs (GdkWin32Clipdrop *clipdrop,
|
||||
UINT w32format,
|
||||
GArray *pairs,
|
||||
GdkContentFormatsBuilder *builder)
|
||||
_gdk_win32_add_w32format_to_pairs (UINT w32format,
|
||||
GArray *pairs,
|
||||
GdkContentFormatsBuilder *builder)
|
||||
{
|
||||
gboolean predef;
|
||||
char *w32format_name = _gdk_win32_get_clipboard_format_name (w32format, &predef);
|
||||
@@ -2038,7 +2017,7 @@ gdk_win32_clipdrop_add_win32_format_to_pairs (GdkWin32Clipdrop *clipdrop
|
||||
gdk_content_formats_builder_add_mime_type (builder, interned_w32format_name);
|
||||
}
|
||||
|
||||
comp_pairs = _gdk_win32_get_compatibility_contentformats_for_w32format (clipdrop, w32format);
|
||||
comp_pairs = _gdk_win32_get_compatibility_contentformats_for_w32format (w32format);
|
||||
|
||||
if (pairs != NULL && comp_pairs != NULL)
|
||||
for (i = 0; i < comp_pairs->len; i++)
|
||||
@@ -2569,12 +2548,11 @@ transmute_image_bmp_to_cf_dib (const guchar *data,
|
||||
}
|
||||
|
||||
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)
|
||||
_gdk_win32_transmute_windows_data (UINT from_w32format,
|
||||
const char *to_contentformat,
|
||||
HANDLE hdata,
|
||||
guchar **set_data,
|
||||
gsize *set_data_length)
|
||||
{
|
||||
const guchar *data;
|
||||
SIZE_T hdata_length;
|
||||
@@ -2594,37 +2572,37 @@ gdk_win32_clipdrop_transmute_windows_data (GdkWin32Clipdrop *clipdrop,
|
||||
|
||||
length = (gsize) hdata_length;
|
||||
|
||||
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)))
|
||||
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)))
|
||||
{
|
||||
/* No transmutation needed */
|
||||
*set_data = g_memdup2 (data, length);
|
||||
*set_data_length = length;
|
||||
}
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (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 (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (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 (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
else if (to_contentformat == _gdk_win32_clipdrop_atom (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 (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
|
||||
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
|
||||
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))
|
||||
{
|
||||
transmute_cf_shell_id_list_to_text_uri_list (data, length, set_data, set_data_length, NULL);
|
||||
res = TRUE;
|
||||
@@ -2643,48 +2621,47 @@ out:
|
||||
}
|
||||
|
||||
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)
|
||||
_gdk_win32_transmute_contentformat (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 (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)))
|
||||
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)))
|
||||
{
|
||||
/* No conversion needed */
|
||||
*set_data = g_memdup2 (data, length);
|
||||
*set_data_length = length;
|
||||
}
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (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 (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (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 (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (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 (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
|
||||
else if (from_contentformat == _gdk_win32_clipdrop_atom (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 (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
|
||||
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
|
||||
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))
|
||||
{
|
||||
transmute_text_uri_list_to_shell_id_list (data, length, set_data, set_data_length, NULL);
|
||||
}
|
||||
@@ -2700,9 +2677,8 @@ gdk_win32_clipdrop_transmute_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
|
||||
const char *contentformat,
|
||||
GArray *array)
|
||||
_gdk_win32_add_contentformat_to_pairs (const char *contentformat,
|
||||
GArray *array)
|
||||
{
|
||||
int added_count = 0;
|
||||
wchar_t *contentformat_w;
|
||||
@@ -2747,7 +2723,7 @@ _gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
|
||||
g_array_append_val (array, fmt);
|
||||
added_count += 1;
|
||||
|
||||
comp_pairs = get_compatibility_w32formats_for_contentformat (clip_drop, contentformat);
|
||||
comp_pairs = get_compatibility_w32formats_for_contentformat (contentformat);
|
||||
for (i = 0; comp_pairs != NULL && i < comp_pairs->len; i++)
|
||||
{
|
||||
int j;
|
||||
@@ -2771,11 +2747,10 @@ _gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_advertise_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
_gdk_win32_advertise_clipboard_contentformats (GTask *task,
|
||||
GdkContentFormats *contentformats)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32ClipboardThreadAdvertise *adv = g_new0 (GdkWin32ClipboardThreadAdvertise, 1);
|
||||
const char * const *mime_types;
|
||||
gsize mime_types_len;
|
||||
@@ -2800,21 +2775,20 @@ _gdk_win32_advertise_clipboard_contentformats (GdkClipboard *cb,
|
||||
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 (clipdrop, mime_types[i], adv->pairs);
|
||||
_gdk_win32_add_contentformat_to_pairs (mime_types[i], adv->pairs);
|
||||
}
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, adv);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_retrieve_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
_gdk_win32_retrieve_clipboard_contentformats (GTask *task,
|
||||
GdkContentFormats *contentformats)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32ClipboardThreadRetrieve *retr = g_new0 (GdkWin32ClipboardThreadRetrieve, 1);
|
||||
const char * const *mime_types;
|
||||
gsize mime_types_len;
|
||||
@@ -2832,10 +2806,10 @@ _gdk_win32_retrieve_clipboard_contentformats (GdkClipboard *cb,
|
||||
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 (clipdrop, mime_types[i], retr->pairs);
|
||||
_gdk_win32_add_contentformat_to_pairs (mime_types[i], retr->pairs);
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, retr);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -2905,7 +2879,7 @@ clipboard_store_hdata_ready (GObject *clipboard,
|
||||
if (!no_other_streams)
|
||||
return;
|
||||
|
||||
clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (clipboard));
|
||||
clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
store = g_new0 (GdkWin32ClipboardThreadStore, 1);
|
||||
|
||||
@@ -2916,7 +2890,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, clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
g_free (prep);
|
||||
}
|
||||
@@ -2930,7 +2904,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
gsize i;
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32ClipboardStorePrep *prep;
|
||||
|
||||
g_assert (clipdrop->clipboard_hwnd != NULL);
|
||||
@@ -2943,7 +2917,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 (clipdrop, mime_types[i], pairs);
|
||||
_gdk_win32_add_contentformat_to_pairs (mime_types[i], pairs);
|
||||
|
||||
if (pairs->len <= 0)
|
||||
{
|
||||
@@ -2961,7 +2935,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 (clipdrop, pair, NULL);
|
||||
el.stream = gdk_win32_hdata_output_stream_new (pair, NULL);
|
||||
|
||||
if (!el.stream)
|
||||
continue;
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
|
||||
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(c, i) (_gdk_atom_array_index (c->known_atoms, i))
|
||||
#define _gdk_win32_clipdrop_atom(i) (_gdk_atom_array_index (_gdk_win32_clipdrop_get ()->known_atoms, i))
|
||||
#define _gdk_cf_array_index(a, i) (g_array_index (a, UINT, i))
|
||||
#define _gdk_win32_clipdrop_cf(c,i) (_gdk_cf_array_index (c->known_clipboard_formats, i))
|
||||
#define _gdk_win32_clipdrop_cf(i) (_gdk_cf_array_index (_gdk_win32_clipdrop_get ()->known_clipboard_formats, i))
|
||||
|
||||
/* Maps GDK contentformats to w32formats or vice versa, depending on the
|
||||
* semantics of the array that holds these.
|
||||
@@ -113,15 +114,6 @@ 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,
|
||||
@@ -232,15 +224,6 @@ 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
|
||||
@@ -250,46 +233,44 @@ 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);
|
||||
int _gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
|
||||
const char *target,
|
||||
void _gdk_win32_add_w32format_to_pairs (UINT format,
|
||||
GArray *array,
|
||||
GdkContentFormatsBuilder *builder);
|
||||
int _gdk_win32_add_contentformat_to_pairs (const char *target,
|
||||
GArray *array);
|
||||
|
||||
void _gdk_win32_clipboard_default_output_done (GObject *clipboard,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data);
|
||||
gboolean gdk_win32_clipdrop_transmute_contentformat (GdkWin32Clipdrop *clipdrop,
|
||||
const char *from_contentformat,
|
||||
gboolean _gdk_win32_transmute_contentformat (const char *from_contentformat,
|
||||
UINT to_w32format,
|
||||
const guchar *data,
|
||||
gsize length,
|
||||
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_transmute_windows_data (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 (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
void _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
|
||||
GdkContentFormats *contentformats);
|
||||
|
||||
void _gdk_win32_advertise_clipboard_contentformats (GdkClipboard *cb,
|
||||
GTask *task,
|
||||
void _gdk_win32_advertise_clipboard_contentformats (GTask *task,
|
||||
GdkContentFormats *contentformats);
|
||||
|
||||
void gdk_win32_clipdrop_add_win32_format_to_pairs (GdkWin32Clipdrop *clipdrop,
|
||||
UINT format,
|
||||
GArray *array,
|
||||
GdkContentFormatsBuilder *builder);
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,6 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
POINT point;
|
||||
HWND hwnd, hwndc;
|
||||
int scale;
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
if (surface)
|
||||
{
|
||||
@@ -84,11 +83,13 @@ 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 (display, &point);
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
|
||||
if (hwnd)
|
||||
ScreenToClient (hwnd, &point);
|
||||
@@ -104,7 +105,7 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc);
|
||||
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
else
|
||||
*child_surface = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
@@ -166,9 +167,8 @@ _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 (display, &screen_pt))
|
||||
if (!_gdk_win32_get_cursor_pos (&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_display_handle_table_lookup_ (display, hwnd);
|
||||
surface = gdk_win32_handle_table_lookup_ (hwnd);
|
||||
|
||||
if (surface && (win_x || win_y))
|
||||
{
|
||||
|
||||
@@ -65,7 +65,6 @@ 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)
|
||||
@@ -75,11 +74,13 @@ 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 (display, &point);
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
|
||||
if (hwnd)
|
||||
ScreenToClient (hwnd, &point);
|
||||
@@ -95,7 +96,7 @@ gdk_device_winpointer_query_state (GdkDevice *device,
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc);
|
||||
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
else
|
||||
*child_surface = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
@@ -143,9 +144,8 @@ 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 (display, &screen_pt))
|
||||
if (!_gdk_win32_get_cursor_pos (&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_display_handle_table_lookup_ (display, hwnd);
|
||||
surface = gdk_win32_handle_table_lookup_ (hwnd);
|
||||
|
||||
if (surface && (win_x || win_y))
|
||||
{
|
||||
|
||||
@@ -73,7 +73,6 @@ 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)
|
||||
@@ -83,11 +82,13 @@ 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 (display, &point);
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
|
||||
if (hwnd)
|
||||
ScreenToClient (hwnd, &point);
|
||||
@@ -103,7 +104,7 @@ gdk_device_wintab_query_state (GdkDevice *device,
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc);
|
||||
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
else
|
||||
*child_surface = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
|
||||
+110
-205
@@ -45,6 +45,11 @@
|
||||
#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);
|
||||
@@ -55,39 +60,22 @@ 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);
|
||||
|
||||
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_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;
|
||||
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 (GdkDisplay *display,
|
||||
create_pointer (GdkDeviceManagerWin32 *device_manager,
|
||||
GType g_type,
|
||||
const char *name,
|
||||
gboolean has_cursor)
|
||||
@@ -96,12 +84,12 @@ create_pointer (GdkDisplay *display,
|
||||
"name", name,
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", has_cursor,
|
||||
"display", display,
|
||||
"display", _gdk_display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_keyboard (GdkDisplay *display,
|
||||
create_keyboard (GdkDeviceManagerWin32 *device_manager,
|
||||
GType g_type,
|
||||
const char *name)
|
||||
{
|
||||
@@ -109,7 +97,7 @@ create_keyboard (GdkDisplay *display,
|
||||
"name", name,
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
"display", _gdk_display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -125,38 +113,6 @@ 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);
|
||||
|
||||
@@ -259,13 +215,8 @@ 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 (GdkDeviceManagerWin32 *device_manager,
|
||||
int index)
|
||||
print_cursor (int index)
|
||||
{
|
||||
int size;
|
||||
int i;
|
||||
@@ -290,13 +241,13 @@ print_cursor (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT minbuttons;
|
||||
UINT capabilities;
|
||||
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
|
||||
name = g_malloc (size + 1);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
|
||||
g_print ("NAME: %s\n", name);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
|
||||
g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
|
||||
(*p_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);
|
||||
@@ -314,16 +265,16 @@ print_cursor (GdkDeviceManagerWin32 *device_manager,
|
||||
BIT (ROTATION);
|
||||
#undef BIT
|
||||
g_print ("\n");
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
|
||||
g_print ("BUTTONS: %d\n", buttons);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
|
||||
g_print ("BUTTONBITS: %d\n", buttonbits);
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
|
||||
g_print ("BTNNAMES:");
|
||||
if (size > 0)
|
||||
{
|
||||
btnnames = g_malloc (size + 1);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
|
||||
p = btnnames;
|
||||
while (*p)
|
||||
{
|
||||
@@ -332,47 +283,47 @@ print_cursor (GdkDeviceManagerWin32 *device_manager,
|
||||
}
|
||||
}
|
||||
g_print ("\n");
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
|
||||
g_print ("BUTTONMAP:");
|
||||
for (i = 0; i < buttons; i++)
|
||||
g_print (" %d", buttonmap[i]);
|
||||
g_print ("\n");
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
|
||||
g_print ("SYSBTNMAP:");
|
||||
for (i = 0; i < buttons; i++)
|
||||
g_print (" %d", sysbtnmap[i]);
|
||||
g_print ("\n");
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
|
||||
g_print ("NPBUTTON: %d\n", npbutton);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
|
||||
g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
|
||||
g_print ("NPRESPONSE:");
|
||||
if (size > 0)
|
||||
{
|
||||
npresponse = g_malloc (size);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
|
||||
for (i = 0; i < size / sizeof (UINT); i++)
|
||||
g_print (" %d", npresponse[i]);
|
||||
}
|
||||
g_print ("\n");
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
|
||||
g_print ("TPBUTTON: %d\n", tpbutton);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
|
||||
g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
|
||||
size = WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
|
||||
size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
|
||||
g_print ("TPRESPONSE:");
|
||||
if (size > 0)
|
||||
{
|
||||
tpresponse = g_malloc (size);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
|
||||
for (i = 0; i < size / sizeof (UINT); i++)
|
||||
g_print (" %d", tpresponse[i]);
|
||||
}
|
||||
g_print ("\n");
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
|
||||
g_print ("PHYSID: %#x\n", (guint) physid);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
|
||||
g_print ("CAPABILITIES: %#x:", capabilities);
|
||||
#define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
|
||||
BIT (MULTIMODE);
|
||||
@@ -382,14 +333,14 @@ print_cursor (GdkDeviceManagerWin32 *device_manager,
|
||||
g_print ("\n");
|
||||
if (capabilities & CRC_MULTIMODE)
|
||||
{
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
|
||||
g_print ("MODE: %d\n", mode);
|
||||
}
|
||||
if (capabilities & CRC_AGGREGATE)
|
||||
{
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
|
||||
g_print ("MINPKTDATA: %d\n", minpktdata);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
|
||||
(*p_WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
|
||||
g_print ("MINBUTTONS: %d\n", minbuttons);
|
||||
}
|
||||
}
|
||||
@@ -422,8 +373,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
|
||||
wintab_initialized = TRUE;
|
||||
|
||||
device_manager->wintab_items = g_new0 (wintab_items, 1);
|
||||
device_manager->wintab_items->wintab_contexts = NULL;
|
||||
wintab_contexts = NULL;
|
||||
|
||||
n = GetSystemDirectoryA (&dummy, 0);
|
||||
|
||||
@@ -446,35 +396,41 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
if ((wintab32 = LoadLibraryA (wintab32_dll_path)) == NULL)
|
||||
return;
|
||||
|
||||
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))
|
||||
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)
|
||||
return;
|
||||
|
||||
if (!WINTAB_API_CALL (device_manager, WTInfoA) (0, 0, NULL))
|
||||
if (!(*p_WTInfoA) (0, 0, NULL))
|
||||
return;
|
||||
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
|
||||
(*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
|
||||
GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
|
||||
HIBYTE (specversion), LOBYTE (specversion)));
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
|
||||
(*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
|
||||
(*p_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 */
|
||||
device_manager->wintab_items->wintab_surface = gdk_win32_drag_surface_new (display);
|
||||
wintab_surface = gdk_win32_drag_surface_new (display);
|
||||
|
||||
g_object_ref (device_manager->wintab_items->wintab_surface);
|
||||
g_object_ref (wintab_surface);
|
||||
|
||||
for (devix = 0; devix < ndevices; devix++)
|
||||
{
|
||||
@@ -486,25 +442,25 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
* cursor. This seems much more natural.
|
||||
*/
|
||||
|
||||
WINTAB_API_CALL (device_manager, WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
|
||||
(*p_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
|
||||
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);
|
||||
(*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);
|
||||
|
||||
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 (WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
|
||||
if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
|
||||
defcontext_done = TRUE;
|
||||
#if DEBUG_WINTAB
|
||||
if (defcontext_done)
|
||||
@@ -515,7 +471,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
}
|
||||
|
||||
if (!defcontext_done)
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
|
||||
(*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
|
||||
#if DEBUG_WINTAB
|
||||
GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
|
||||
#endif
|
||||
@@ -537,10 +493,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
print_lc(&lc)));
|
||||
#endif
|
||||
hctx = g_new (HCTX, 1);
|
||||
if ((*hctx =
|
||||
WINTAB_API_CALL (device_manager, WTOpenA) (GDK_SURFACE_HWND (device_manager->wintab_items->wintab_surface),
|
||||
&lc,
|
||||
TRUE)) == NULL)
|
||||
if ((*hctx = (*p_WTOpenA) (GDK_SURFACE_HWND (wintab_surface), &lc, TRUE)) == NULL)
|
||||
{
|
||||
g_warning ("gdk_input_wintab_init: WTOpen failed");
|
||||
return;
|
||||
@@ -548,12 +501,11 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
GDK_NOTE (INPUT, g_print ("opened Wintab device %u %p\n",
|
||||
devix, *hctx));
|
||||
|
||||
device_manager->wintab_items->wintab_contexts =
|
||||
g_list_append (device_manager->wintab_items->wintab_contexts, hctx);
|
||||
wintab_contexts = g_list_append (wintab_contexts, hctx);
|
||||
#if 0
|
||||
WINTAB_API_CALL (device_manager, WTEnable) (*hctx, TRUE);
|
||||
(*p_WTEnable) (*hctx, TRUE);
|
||||
#endif
|
||||
WINTAB_API_CALL (device_manager, WTOverlap) (*hctx, TRUE);
|
||||
(*p_WTOverlap) (*hctx, TRUE);
|
||||
|
||||
#if DEBUG_WINTAB
|
||||
GDK_NOTE (INPUT, (g_print("context for device %u after WTOpen:\n", devix),
|
||||
@@ -566,7 +518,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 (WINTAB_API_CALL (device_manager, WTQueueSizeSet) (*hctx, i))
|
||||
if ((*p_WTQueueSizeSet) (*hctx, i))
|
||||
{
|
||||
GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
|
||||
break;
|
||||
@@ -577,10 +529,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 (device_manager, cursorix)));
|
||||
GDK_NOTE (INPUT, (g_print("Cursor %u:\n", cursorix), print_cursor (cursorix)));
|
||||
#endif
|
||||
active = FALSE;
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
|
||||
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
|
||||
if (!active)
|
||||
continue;
|
||||
|
||||
@@ -592,11 +544,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.
|
||||
*/
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
|
||||
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
|
||||
if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
|
||||
continue;
|
||||
|
||||
WINTAB_API_CALL (device_manager, WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
|
||||
(*p_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);
|
||||
|
||||
@@ -618,7 +570,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
|
||||
device->hctx = *hctx;
|
||||
device->cursor = cursorix;
|
||||
WINTAB_API_CALL (device_manager, WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
|
||||
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
|
||||
|
||||
if (device->pktdata & PK_X)
|
||||
{
|
||||
@@ -718,7 +670,7 @@ wintab_default_display_notify_cb (GdkDisplayManager *display_manager)
|
||||
|
||||
g_assert (display != NULL);
|
||||
|
||||
device_manager = GDK_WIN32_DISPLAY (display)->device_manager;
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
|
||||
g_assert (display_manager != NULL);
|
||||
|
||||
default_display_opened = TRUE;
|
||||
@@ -735,16 +687,16 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
const char *api_preference = NULL;
|
||||
gboolean have_api_preference = TRUE;
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
|
||||
display_win32 = GDK_WIN32_DISPLAY (device_manager->display);
|
||||
display_win32 = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
|
||||
device_manager->core_pointer =
|
||||
create_pointer (device_manager->display,
|
||||
create_pointer (device_manager,
|
||||
GDK_TYPE_DEVICE_VIRTUAL,
|
||||
"Virtual Core Pointer",
|
||||
TRUE);
|
||||
device_manager->system_pointer =
|
||||
create_pointer (device_manager->display,
|
||||
create_pointer (device_manager,
|
||||
GDK_TYPE_DEVICE_WIN32,
|
||||
"System Aggregated Pointer",
|
||||
FALSE);
|
||||
@@ -754,11 +706,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->display,
|
||||
create_keyboard (device_manager,
|
||||
GDK_TYPE_DEVICE_VIRTUAL,
|
||||
"Virtual Core Keyboard");
|
||||
device_manager->system_keyboard =
|
||||
create_keyboard (device_manager->display,
|
||||
create_keyboard (device_manager,
|
||||
GDK_TYPE_DEVICE_WIN32,
|
||||
"System Aggregated Keyboard");
|
||||
_gdk_device_virtual_set_active (device_manager->core_keyboard,
|
||||
@@ -771,12 +723,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 (device_manager->display, seat);
|
||||
gdk_display_add_seat (_gdk_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);
|
||||
|
||||
display_win32->device_manager = device_manager;
|
||||
_gdk_device_manager = device_manager;
|
||||
|
||||
api_preference = g_getenv ("GDK_WIN32_TABLET_INPUT_API");
|
||||
if (g_strcmp0 (api_preference, "none") == 0)
|
||||
@@ -802,7 +754,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 (device_manager);
|
||||
gboolean init_successful = gdk_winpointer_initialize ();
|
||||
|
||||
if (!init_successful && !have_api_preference)
|
||||
{
|
||||
@@ -831,44 +783,6 @@ 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)
|
||||
{
|
||||
@@ -876,19 +790,10 @@ 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 (GdkDeviceManagerWin32 *device_manager)
|
||||
_gdk_wintab_set_tablet_active (void)
|
||||
{
|
||||
GList *tmp_list;
|
||||
HCTX *hctx;
|
||||
@@ -896,18 +801,18 @@ _gdk_wintab_set_tablet_active (GdkDeviceManagerWin32 *device_manager)
|
||||
/* Bring the contexts to the top of the overlap order when one of the
|
||||
* application's HWNDs is activated */
|
||||
|
||||
if (!device_manager->wintab_items->wintab_contexts)
|
||||
if (!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 = device_manager->wintab_items->wintab_contexts;
|
||||
tmp_list = wintab_contexts;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
hctx = (HCTX *) (tmp_list->data);
|
||||
WINTAB_API_CALL (device_manager, WTOverlap) (*hctx, TRUE);
|
||||
(*p_WTOverlap) (*hctx, TRUE);
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
@@ -1028,13 +933,13 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
*/
|
||||
static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
|
||||
|
||||
device_manager = GDK_WIN32_DISPLAY (display)->device_manager;
|
||||
if (surface != device_manager->wintab_items->wintab_surface)
|
||||
if (surface != 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)
|
||||
@@ -1046,7 +951,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
|
||||
if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
|
||||
{
|
||||
if (!WINTAB_API_CALL (device_manager, WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
|
||||
if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1071,12 +976,12 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
{
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
GDK_DEVICE (source_device));
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core += 1;
|
||||
_gdk_input_ignore_core += 1;
|
||||
}
|
||||
}
|
||||
else if (source_device != NULL &&
|
||||
source_device->sends_core &&
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core == 0)
|
||||
_gdk_input_ignore_core == 0)
|
||||
{
|
||||
/* A fallback for cases when two devices (disabled and enabled)
|
||||
* were in proximity simultaneously.
|
||||
@@ -1092,7 +997,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
*/
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
GDK_DEVICE (source_device));
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core += 1;
|
||||
_gdk_input_ignore_core += 1;
|
||||
}
|
||||
|
||||
if (source_device == NULL)
|
||||
@@ -1101,7 +1006,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 (GDK_WIN32_DISPLAY (display)->display_surface_record->modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
|
||||
if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
|
||||
{
|
||||
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
|
||||
return NULL;
|
||||
@@ -1255,7 +1160,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
{
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
GDK_DEVICE (source_device));
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core += 1;
|
||||
_gdk_input_ignore_core += 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1263,11 +1168,11 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
case WT_PROXIMITY:
|
||||
if (LOWORD (msg->lParam) == 0)
|
||||
{
|
||||
if (GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core > 0)
|
||||
if (_gdk_input_ignore_core > 0)
|
||||
{
|
||||
GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core -= 1;
|
||||
_gdk_input_ignore_core -= 1;
|
||||
|
||||
if (GDK_WIN32_DISPLAY (display)->pointer_device_items->input_ignore_core == 0)
|
||||
if (_gdk_input_ignore_core == 0)
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer,
|
||||
device_manager->system_pointer);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkDeviceManagerWin32 GdkDeviceManagerWin32;
|
||||
typedef struct _GdkDeviceManagerWin32Class GdkDeviceManagerWin32Class;
|
||||
typedef struct _wintab_items wintab_items;
|
||||
|
||||
struct _GdkDeviceManagerWin32
|
||||
{
|
||||
@@ -44,23 +43,11 @@ 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
|
||||
@@ -70,10 +57,10 @@ struct _GdkDeviceManagerWin32Class
|
||||
|
||||
GType gdk_device_manager_win32_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _gdk_wintab_set_tablet_active (GdkDeviceManagerWin32 *device_manager);
|
||||
GdkEvent *gdk_wintab_make_event (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
GdkSurface *surface);
|
||||
void _gdk_wintab_set_tablet_active (void);
|
||||
GdkEvent * gdk_wintab_make_event (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
GdkSurface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+57
-132
@@ -28,7 +28,6 @@
|
||||
#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"
|
||||
@@ -39,6 +38,7 @@
|
||||
|
||||
#include <dwmapi.h>
|
||||
|
||||
#include "gdkwin32langnotification.h"
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
@@ -47,6 +47,8 @@
|
||||
# define IMAGE_FILE_MACHINE_ARM64 0xAA64
|
||||
#endif
|
||||
|
||||
static int debug_indent = 0;
|
||||
|
||||
/**
|
||||
* gdk_win32_display_add_filter:
|
||||
* @display: a `GdkWin32Display`
|
||||
@@ -437,7 +439,7 @@ inner_display_change_hwnd_procedure (HWND hwnd,
|
||||
}
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (GetWindowLongPtr (hwnd, GWLP_USERDATA));
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
|
||||
_gdk_win32_screen_on_displaychange_event (GDK_WIN32_SCREEN (win32_display->screen));
|
||||
return 0;
|
||||
@@ -456,37 +458,16 @@ display_change_hwnd_procedure (HWND hwnd,
|
||||
LPARAM lparam)
|
||||
{
|
||||
LRESULT retval;
|
||||
GdkDisplay *display;
|
||||
|
||||
if (message == WM_NCCREATE)
|
||||
{
|
||||
CREATESTRUCT *cs = (CREATESTRUCT *)lparam;
|
||||
display = (GdkDisplay *)cs->lpCreateParams;
|
||||
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;
|
||||
|
||||
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" : "")));
|
||||
}
|
||||
GDK_NOTE (EVENTS, g_print (" => %" G_GINT64_FORMAT "%s", (gint64) retval, (debug_indent == 0 ? "\n" : "")));
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -510,7 +491,7 @@ register_display_change_notification (GdkDisplay *display)
|
||||
display_win32->hwnd = CreateWindow (MAKEINTRESOURCE (klass),
|
||||
NULL, WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL,
|
||||
this_module (), display);
|
||||
this_module (), NULL);
|
||||
if (!display_win32->hwnd)
|
||||
{
|
||||
UnregisterClass (MAKEINTRESOURCE (klass), this_module ());
|
||||
@@ -521,66 +502,58 @@ 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 (display)) == 0)
|
||||
if (display_name == NULL ||
|
||||
g_ascii_strcasecmp (display_name,
|
||||
gdk_display_get_name (_gdk_display)) == 0)
|
||||
{
|
||||
if (display != NULL)
|
||||
{
|
||||
GDK_NOTE (MISC, g_print ("... return existing gdkdisplay\n"));
|
||||
return display;
|
||||
}
|
||||
if (_gdk_display != NULL)
|
||||
{
|
||||
GDK_NOTE (MISC, g_print ("... return _gdk_display\n"));
|
||||
return _gdk_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;
|
||||
}
|
||||
|
||||
if (g_once_init_enter (&display_inited))
|
||||
{
|
||||
display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
|
||||
_gdk_display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
|
||||
win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
|
||||
win32_display = GDK_WIN32_DISPLAY (display);
|
||||
win32_display->screen = g_object_new (GDK_TYPE_WIN32_SCREEN, NULL);
|
||||
|
||||
win32_display->screen = g_object_new (GDK_TYPE_WIN32_SCREEN,
|
||||
"display", display,
|
||||
NULL);
|
||||
_gdk_events_init (_gdk_display);
|
||||
|
||||
_gdk_events_init (display);
|
||||
_gdk_input_ignore_core = 0;
|
||||
|
||||
win32_display->device_manager = g_object_new (GDK_TYPE_DEVICE_MANAGER_WIN32,
|
||||
"display", display,
|
||||
NULL);
|
||||
gdk_dmanipulation_initialize (win32_display);
|
||||
_gdk_device_manager = g_object_new (GDK_TYPE_DEVICE_MANAGER_WIN32,
|
||||
NULL);
|
||||
_gdk_device_manager->display = _gdk_display;
|
||||
|
||||
gdk_win32_display_lang_notification_init (win32_display);
|
||||
_gdk_drag_init ();
|
||||
_gdk_win32_lang_notification_init ();
|
||||
_gdk_drag_init ();
|
||||
|
||||
display->clipboard = gdk_win32_clipboard_new (display);
|
||||
display->primary_clipboard = gdk_clipboard_new (display);
|
||||
_gdk_display->clipboard = gdk_win32_clipboard_new (_gdk_display);
|
||||
_gdk_display->primary_clipboard = gdk_clipboard_new (_gdk_display);
|
||||
|
||||
/* Precalculate display name */
|
||||
gdk_display_get_name (display);
|
||||
/* Precalculate display name */
|
||||
(void) gdk_display_get_name (_gdk_display);
|
||||
|
||||
register_display_change_notification (display);
|
||||
register_display_change_notification (_gdk_display);
|
||||
|
||||
g_signal_emit_by_name (display, "opened");
|
||||
g_signal_emit_by_name (_gdk_display, "opened");
|
||||
|
||||
/* Precalculate keymap, see #6203 */
|
||||
gdk_display_get_keymap (display);
|
||||
/* Precalculate keymap, see #6203 */
|
||||
(void) _gdk_win32_display_get_keymap (_gdk_display);
|
||||
|
||||
GDK_NOTE (MISC, g_print ("... gdk_display now set up\n"));
|
||||
GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n"));
|
||||
|
||||
g_once_init_leave (&display_inited, 1);
|
||||
}
|
||||
|
||||
return display;
|
||||
return _gdk_display;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32Display, gdk_win32_display, GDK_TYPE_DISPLAY)
|
||||
@@ -666,7 +639,7 @@ gdk_win32_display_beep (GdkDisplay *display)
|
||||
static void
|
||||
gdk_win32_display_flush (GdkDisplay * display)
|
||||
{
|
||||
g_return_if_fail (display == gdk_display_get_default());
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
|
||||
GdiFlush ();
|
||||
}
|
||||
@@ -674,7 +647,7 @@ gdk_win32_display_flush (GdkDisplay * display)
|
||||
static void
|
||||
gdk_win32_display_sync (GdkDisplay * display)
|
||||
{
|
||||
g_return_if_fail (display == gdk_display_get_default());
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
|
||||
GdiFlush ();
|
||||
}
|
||||
@@ -714,22 +687,9 @@ 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_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);
|
||||
_gdk_win32_lang_notification_exit ();
|
||||
|
||||
g_list_store_remove_all (G_LIST_STORE (display_win32->monitors));
|
||||
g_object_unref (display_win32->monitors);
|
||||
@@ -1064,45 +1024,13 @@ _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);
|
||||
|
||||
@@ -1247,6 +1175,17 @@ 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
|
||||
@@ -1332,22 +1271,6 @@ 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)
|
||||
{
|
||||
@@ -1385,4 +1308,6 @@ 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,37 +23,13 @@
|
||||
|
||||
#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,
|
||||
@@ -137,52 +113,6 @@ 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;
|
||||
@@ -195,27 +125,17 @@ 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;
|
||||
|
||||
struct {
|
||||
guint disallow_swap_exchange : 1;
|
||||
} wgl_quirks;
|
||||
guint wgl_support_gdi : 1;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
guint hasEglKHRCreateContext : 1;
|
||||
@@ -264,11 +184,9 @@ 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);
|
||||
|
||||
GdkWin32Clipdrop *gdk_win32_display_get_clipdrop (GdkDisplay *display);
|
||||
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
GdkSurface *surface,
|
||||
HMONITOR hmonitor);
|
||||
|
||||
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
|
||||
|
||||
|
||||
+79
-103
@@ -217,8 +217,8 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
/* accessors to thread data structs in GdkWin32Clipdrop/GdkWin32Drag */
|
||||
#define OBJECT_DND_THREAD_MEMBER(o,m) ((GdkWin32DnDThread *)(o->dnd_thread_items))->m
|
||||
/* Just to avoid calling RegisterWindowMessage() every time */
|
||||
static UINT thread_wakeup_message;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -362,22 +362,27 @@ 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 (GdkDisplay *display)
|
||||
dnd_queue_is_empty ()
|
||||
{
|
||||
return g_atomic_int_get (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter)) == 0;
|
||||
return g_atomic_int_get (&_win32_clipdrop->dnd_queue_counter) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
decrement_dnd_queue_counter (GdkDisplay *display)
|
||||
decrement_dnd_queue_counter ()
|
||||
{
|
||||
g_atomic_int_dec_and_test (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter));
|
||||
g_atomic_int_dec_and_test (&_win32_clipdrop->dnd_queue_counter);
|
||||
}
|
||||
|
||||
static void
|
||||
increment_dnd_queue_counter (GdkDisplay *display)
|
||||
increment_dnd_queue_counter ()
|
||||
{
|
||||
g_atomic_int_inc (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter));
|
||||
g_atomic_int_inc (&_win32_clipdrop->dnd_queue_counter);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -422,15 +427,13 @@ free_queue_item (GdkWin32DnDThreadQueueItem *item)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_dnd_queue (GdkDrag *drag,
|
||||
gboolean timed,
|
||||
process_dnd_queue (gboolean timed,
|
||||
guint64 end_time,
|
||||
GdkWin32DnDThreadGetData *getdata_check)
|
||||
{
|
||||
GdkWin32DnDThreadQueueItem *item;
|
||||
GdkWin32DnDThreadUpdateDragState *updatestate;
|
||||
GdkWin32DnDThreadDoDragDrop *ddd;
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
@@ -441,17 +444,17 @@ process_dnd_queue (GdkDrag *drag,
|
||||
if (current_time >= end_time)
|
||||
break;
|
||||
|
||||
item = g_async_queue_timeout_pop (OBJECT_DND_THREAD_MEMBER (drag_win32, input_queue), end_time - current_time);
|
||||
item = g_async_queue_timeout_pop (dnd_thread_data->input_queue, end_time - current_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
item = g_async_queue_try_pop (OBJECT_DND_THREAD_MEMBER (drag_win32, input_queue));
|
||||
item = g_async_queue_try_pop (dnd_thread_data->input_queue);
|
||||
}
|
||||
|
||||
if (item == NULL)
|
||||
break;
|
||||
|
||||
decrement_dnd_queue_counter (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
decrement_dnd_queue_counter ();
|
||||
|
||||
switch (item->item_type)
|
||||
{
|
||||
@@ -487,7 +490,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_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
gpointer table_value = g_hash_table_lookup (clipdrop->active_source_drags, drag);
|
||||
|
||||
if (ddd == table_value)
|
||||
@@ -543,7 +546,7 @@ received_drag_context_data (GObject *drag,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkWin32DnDThreadGetData *getdata = (GdkWin32DnDThreadGetData *) user_data;
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
if (!gdk_drag_write_finish (GDK_DRAG (drag), result, &error))
|
||||
{
|
||||
@@ -568,17 +571,17 @@ received_drag_context_data (GObject *drag,
|
||||
}
|
||||
|
||||
g_clear_object (&getdata->stream);
|
||||
increment_dnd_queue_counter (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
|
||||
increment_dnd_queue_counter ();
|
||||
g_async_queue_push (clipdrop->dnd_queue, getdata);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, 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)",
|
||||
@@ -590,7 +593,7 @@ get_data_response (gpointer user_data)
|
||||
if (ddd)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GOutputStream *stream = gdk_win32_hdata_output_stream_new (clipdrop, &getdata->pair, &error);
|
||||
GOutputStream *stream = gdk_win32_hdata_output_stream_new (&getdata->pair, &error);
|
||||
|
||||
if (stream)
|
||||
{
|
||||
@@ -607,9 +610,9 @@ get_data_response (gpointer user_data)
|
||||
}
|
||||
}
|
||||
|
||||
increment_dnd_queue_counter (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
|
||||
increment_dnd_queue_counter ();
|
||||
g_async_queue_push (clipdrop->dnd_queue, getdata);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -619,13 +622,11 @@ do_drag_drop (GdkWin32DnDThreadDoDragDrop *ddd)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
GdkWin32Drag *drag = ddd->base.opaque_context;
|
||||
dnd_thread_data->src_object = ddd->src_object;
|
||||
dnd_thread_data->src_context = ddd->src_context;
|
||||
|
||||
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),
|
||||
hr = DoDragDrop (&dnd_thread_data->src_object->ido,
|
||||
&dnd_thread_data->src_context->ids,
|
||||
ddd->allowed_drop_effects,
|
||||
&ddd->received_drop_effect);
|
||||
|
||||
@@ -637,18 +638,15 @@ do_drag_drop (GdkWin32DnDThreadDoDragDrop *ddd)
|
||||
gpointer
|
||||
_gdk_win32_dnd_thread_main (gpointer data)
|
||||
{
|
||||
|
||||
clipdrop_thread_items *clipdrop_items = (clipdrop_thread_items *) data;
|
||||
GAsyncQueue *queue = clipdrop_items->queue;
|
||||
GdkWin32Clipdrop *clipdrop = clipdrop_items->clipdrop;
|
||||
GAsyncQueue *queue = (GAsyncQueue *) data;
|
||||
GdkWin32DnDThreadQueueItem *item;
|
||||
MSG msg;
|
||||
HRESULT hr;
|
||||
|
||||
g_assert (clipdrop->dnd_thread_items == NULL);
|
||||
g_assert (dnd_thread_data == NULL);
|
||||
|
||||
clipdrop->dnd_thread_items = g_new0 (GdkWin32DnDThread, 1);
|
||||
OBJECT_DND_THREAD_MEMBER (clipdrop, input_queue) = queue;
|
||||
dnd_thread_data = g_new0 (GdkWin32DnDThread, 1);
|
||||
dnd_thread_data->input_queue = queue;
|
||||
|
||||
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
@@ -660,6 +658,8 @@ _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,13 +667,11 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
|
||||
while (GetMessage (&msg, NULL, 0, 0))
|
||||
{
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
|
||||
if (!dnd_queue_is_empty (display))
|
||||
if (!dnd_queue_is_empty ())
|
||||
{
|
||||
while ((item = g_async_queue_try_pop (queue)) != NULL)
|
||||
{
|
||||
decrement_dnd_queue_counter (display);
|
||||
decrement_dnd_queue_counter ();
|
||||
|
||||
if (item->item_type != GDK_WIN32_DND_THREAD_QUEUE_ITEM_DO_DRAG_DROP)
|
||||
{
|
||||
@@ -682,7 +680,7 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
}
|
||||
|
||||
do_drag_drop ((GdkWin32DnDThreadDoDragDrop *) item);
|
||||
API_CALL (PostThreadMessage, (GetCurrentThreadId (), clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (GetCurrentThreadId (), thread_wakeup_message, 0, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -693,8 +691,7 @@ _gdk_win32_dnd_thread_main (gpointer data)
|
||||
}
|
||||
|
||||
g_async_queue_unref (queue);
|
||||
|
||||
g_clear_pointer (&clipdrop->dnd_thread_items, g_free);
|
||||
g_clear_pointer (&dnd_thread_data, g_free);
|
||||
|
||||
OleUninitialize ();
|
||||
CoUninitialize ();
|
||||
@@ -706,25 +703,6 @@ 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,
|
||||
@@ -732,7 +710,8 @@ move_drag_surface (GdkDrag *drag,
|
||||
{
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
|
||||
g_assert (check_drag_display_thread_status (drag, TRUE));
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
|
||||
gdk_win32_surface_move (drag_win32->drag_surface,
|
||||
x_root - drag_win32->hot_x,
|
||||
@@ -743,7 +722,8 @@ move_drag_surface (GdkDrag *drag,
|
||||
static void
|
||||
gdk_win32_drag_init (GdkWin32Drag *drag)
|
||||
{
|
||||
g_assert (check_drag_display_thread_status (GDK_DRAG (drag), TRUE));
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
|
||||
drag->handle_events = TRUE;
|
||||
drag->dest_hwnd = INVALID_HANDLE_VALUE;
|
||||
@@ -758,14 +738,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);
|
||||
@@ -806,8 +786,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -832,17 +810,17 @@ static enum_formats *enum_formats_new (GArray *formats);
|
||||
* Does not give a reference.
|
||||
*/
|
||||
GdkDrag *
|
||||
gdk_win32_find_drag_for_dest_surface (GdkSurface *surface)
|
||||
_gdk_win32_find_drag_for_dest_hwnd (HWND dest_hwnd)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GdkWin32Drag *drag_win32;
|
||||
GdkWin32DnDThreadDoDragDrop *ddd;
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (surface));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
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 == GDK_SURFACE_HWND (surface))
|
||||
if (ddd->src_context->dest_window_handle == dest_hwnd)
|
||||
return GDK_DRAG (drag_win32);
|
||||
|
||||
return NULL;
|
||||
@@ -919,8 +897,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 (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsourcenotify_dragentertarget %p (SDC %p) 0x%p\n", This, ctx, hwndTarget));
|
||||
|
||||
@@ -940,8 +918,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 (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsourcenotify_dragleavetarget %p (SDC %p) 0x%p\n", This, ctx, ctx->dest_window_handle));
|
||||
|
||||
@@ -1042,8 +1020,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 (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
|
||||
GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag state %d\n", ctx->util_data.state));
|
||||
|
||||
@@ -1079,13 +1057,14 @@ static gboolean
|
||||
give_feedback (gpointer user_data)
|
||||
{
|
||||
GdkWin32DnDThreadGiveFeedback *feedback = (GdkWin32DnDThreadGiveFeedback *) user_data;
|
||||
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));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
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));
|
||||
|
||||
@@ -1106,8 +1085,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 (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
|
||||
feedback = g_new0 (GdkWin32DnDThreadGiveFeedback, 1);
|
||||
feedback->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_GIVE_FEEDBACK;
|
||||
@@ -1245,8 +1224,8 @@ idataobject_getdata (LPDATAOBJECT This,
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
|
||||
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
|
||||
if (!dnd_queue_is_empty ())
|
||||
process_dnd_queue (FALSE, 0, NULL);
|
||||
|
||||
getdata = g_new0 (GdkWin32DnDThreadGetData, 1);
|
||||
getdata->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_GET_DATA;
|
||||
@@ -1254,7 +1233,7 @@ idataobject_getdata (LPDATAOBJECT This,
|
||||
getdata->pair = *pair;
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, get_data_response, getdata, NULL);
|
||||
|
||||
if (!process_dnd_queue (ctx->drag, TRUE, g_get_monotonic_time () + G_USEC_PER_SEC * 30, getdata))
|
||||
if (!process_dnd_queue (TRUE, g_get_monotonic_time () + G_USEC_PER_SEC * 30, getdata))
|
||||
return E_FAIL;
|
||||
|
||||
if (getdata->produced_data_medium.tymed == TYMED_NULL)
|
||||
@@ -1290,9 +1269,8 @@ idataobject_querygetdata (LPDATAOBJECT This,
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
data_object *ctx = (data_object *) This;
|
||||
|
||||
g_assert (check_drag_display_thread_status (ctx->drag, FALSE));
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread != g_thread_self ());
|
||||
|
||||
hr = query (This, pFormatEtc, NULL);
|
||||
|
||||
@@ -1331,9 +1309,8 @@ idataobject_enumformatetc (LPDATAOBJECT This,
|
||||
DWORD dwDirection,
|
||||
LPENUMFORMATETC *ppEnumFormatEtc)
|
||||
{
|
||||
data_object *ctx = (data_object *) This;
|
||||
|
||||
g_assert (check_drag_display_thread_status (ctx->drag, FALSE));
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread != g_thread_self ());
|
||||
|
||||
if (dwDirection != DATADIR_GET)
|
||||
{
|
||||
@@ -1621,9 +1598,7 @@ 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 (gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface)),
|
||||
mime_types[i],
|
||||
result->formats);
|
||||
added_count = _gdk_win32_add_contentformat_to_pairs (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));
|
||||
@@ -1679,7 +1654,7 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
|
||||
{
|
||||
GdkDrag *drag;
|
||||
GdkWin32Drag *drag_win32;
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (surface));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
double px, py;
|
||||
int x_root, y_root;
|
||||
GdkWin32DnDThreadDoDragDrop *ddd;
|
||||
@@ -1734,9 +1709,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 (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
increment_dnd_queue_counter ();
|
||||
g_async_queue_push (clipdrop->dnd_queue, ddd);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
|
||||
|
||||
drag_win32->util_data.state = GDK_WIN32_DND_PENDING;
|
||||
|
||||
@@ -1775,9 +1750,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 (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
increment_dnd_queue_counter ();
|
||||
g_async_queue_push (clipdrop->dnd_queue, status);
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1785,10 +1760,11 @@ gdk_win32_drag_drop (GdkDrag *drag,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
|
||||
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
gpointer ddd;
|
||||
|
||||
g_assert (check_drag_display_thread_status (drag, TRUE));
|
||||
g_assert (_win32_main_thread == NULL ||
|
||||
_win32_main_thread == g_thread_self ());
|
||||
|
||||
g_return_if_fail (drag != NULL);
|
||||
|
||||
@@ -1900,7 +1876,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_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
|
||||
clipdrop = _gdk_win32_clipdrop_get ();
|
||||
ddd = g_hash_table_lookup (clipdrop->active_source_drags, drag);
|
||||
|
||||
if (success)
|
||||
@@ -2058,7 +2034,7 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
|
||||
key_state = manufacture_keystate_from_GMT (state);
|
||||
|
||||
clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (event->surface));
|
||||
clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
GDK_NOTE (DND, g_print ("Post WM_MOUSEMOVE keystate=%lu\n", key_state));
|
||||
|
||||
|
||||
@@ -269,8 +269,7 @@ idroptarget_release (LPDROPTARGET This)
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
query_object_formats (GdkDisplay *display,
|
||||
LPDATAOBJECT pDataObj,
|
||||
query_object_formats (LPDATAOBJECT pDataObj,
|
||||
GArray *w32format_contentformat_map)
|
||||
{
|
||||
IEnumFORMATETC *pfmt = NULL;
|
||||
@@ -299,7 +298,7 @@ query_object_formats (GdkDisplay *display,
|
||||
GDK_NOTE (DND, g_print ("supported unnamed? source format 0x%x\n", fmt.cfFormat));
|
||||
|
||||
g_free (registered_name);
|
||||
gdk_win32_clipdrop_add_win32_format_to_pairs (gdk_win32_display_get_clipdrop (display), fmt.cfFormat, w32format_contentformat_map, builder);
|
||||
_gdk_win32_add_w32format_to_pairs (fmt.cfFormat, w32format_contentformat_map, builder);
|
||||
hr = IEnumFORMATETC_Next (pfmt, 1, &fmt, NULL);
|
||||
}
|
||||
|
||||
@@ -491,12 +490,12 @@ idroptarget_dragenter (LPDROPTARGET This,
|
||||
drag = NULL;
|
||||
|
||||
if (ctx->surface)
|
||||
drag = gdk_win32_find_drag_for_dest_surface (ctx->surface);
|
||||
drag = _gdk_win32_find_drag_for_dest_hwnd (GDK_SURFACE_HWND (ctx->surface));
|
||||
|
||||
display = gdk_surface_get_display (ctx->surface);
|
||||
|
||||
droptarget_w32format_contentformat_map = g_array_new (FALSE, FALSE, sizeof (GdkWin32ContentFormatPair));
|
||||
formats = query_object_formats (display, pDataObj, droptarget_w32format_contentformat_map);
|
||||
formats = query_object_formats (pDataObj, droptarget_w32format_contentformat_map);
|
||||
drop = gdk_drop_new (display,
|
||||
gdk_seat_get_pointer (gdk_display_get_default_seat (display)),
|
||||
drag,
|
||||
@@ -1111,12 +1110,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
_gdk_win32_transmute_windows_data (pair->w32format, pair->contentformat, storage.hGlobal, &data, &data_len);
|
||||
}
|
||||
|
||||
ReleaseStgMedium (&storage);
|
||||
|
||||
+243
-242
File diff suppressed because it is too large
Load Diff
@@ -270,20 +270,17 @@ 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 bool
|
||||
find_pixel_format_with_defined_swap_method (HDC hdc,
|
||||
int formats[],
|
||||
UINT count,
|
||||
UINT *index,
|
||||
int *swap_method)
|
||||
static int
|
||||
find_pixel_format_with_defined_swap_flag (HDC hdc,
|
||||
int formats[],
|
||||
UINT count)
|
||||
{
|
||||
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");
|
||||
@@ -291,15 +288,10 @@ find_pixel_format_with_defined_swap_method (HDC hdc,
|
||||
}
|
||||
|
||||
if (value != WGL_SWAP_UNDEFINED_ARB)
|
||||
{
|
||||
*index = i;
|
||||
*swap_method = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
return formats[i];
|
||||
}
|
||||
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -345,8 +337,6 @@ 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 { \
|
||||
@@ -367,9 +357,10 @@ choose_pixel_format_arb_attribs (GdkWin32Display *display_win32,
|
||||
|
||||
attribs_add_static_array (&attribs, attribs_base);
|
||||
|
||||
attribs_commit (&attribs);
|
||||
if (display_win32->wgl_support_gdi)
|
||||
attribs_add (&attribs, WGL_SUPPORT_GDI_ARB, GL_TRUE);
|
||||
|
||||
attribs_add (&attribs, WGL_SUPPORT_GDI_ARB, GL_TRUE);
|
||||
attribs_commit (&attribs);
|
||||
|
||||
attribs_add_static_array (&attribs, attribs_ancillary_buffers);
|
||||
|
||||
@@ -392,40 +383,26 @@ choose_pixel_format_arb_attribs (GdkWin32Display *display_win32,
|
||||
|
||||
/* Do we have a defined swap method? */
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
format = find_pixel_format_with_defined_swap_flag (hdc, formats, count);
|
||||
if (format > 0)
|
||||
goto done;
|
||||
|
||||
/* Nope, but we can try to ask for it explicitly */
|
||||
|
||||
const int swap_methods[] =
|
||||
{
|
||||
(display_win32->wgl_quirks.disallow_swap_exchange) ? 0 : WGL_SWAP_EXCHANGE_ARB,
|
||||
const int swap_methods[] = {
|
||||
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));
|
||||
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;
|
||||
}
|
||||
}
|
||||
format = find_pixel_format_with_defined_swap_flag (hdc, formats, count);
|
||||
if (format > 0)
|
||||
goto done;
|
||||
|
||||
attribs_reset (&attribs);
|
||||
}
|
||||
@@ -443,27 +420,25 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
get_distance (PIXELFORMATDESCRIPTOR *pfd,
|
||||
DWORD swap_flags)
|
||||
get_distance (PIXELFORMATDESCRIPTOR *pfd)
|
||||
{
|
||||
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;
|
||||
int is_transparent = (pfd->dwFlags & PFD_SUPPORT_GDI) != 0;
|
||||
int ancillary_bits = pfd->cStencilBits + pfd->cDepthBits + pfd->cAccumBits;
|
||||
|
||||
int opacity_distance = !is_transparent * 5000;
|
||||
int quality_distance = !is_double_buffered * 1000;
|
||||
int performance_distance = !is_swap_defined * 200;
|
||||
int memory_distance = !is_mono + ancillary_bits;
|
||||
|
||||
return opacity_distance +
|
||||
quality_distance +
|
||||
return quality_distance +
|
||||
performance_distance +
|
||||
memory_distance;
|
||||
}
|
||||
|
||||
/* ChoosePixelFormat ignores some fields and flags, which makes it
|
||||
/* ChoosePixelFormat ignored 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.
|
||||
@@ -479,9 +454,8 @@ choose_pixel_format_opengl32 (GdkWin32Display *display_win32,
|
||||
const DWORD skip_flags = PFD_GENERIC_FORMAT |
|
||||
PFD_GENERIC_ACCELERATED;
|
||||
const DWORD required_flags = PFD_DRAW_TO_WINDOW |
|
||||
PFD_SUPPORT_OPENGL;
|
||||
const DWORD best_swap_flags = PFD_SWAP_COPY |
|
||||
(display_win32->wgl_quirks.disallow_swap_exchange ? 0 : PFD_SWAP_EXCHANGE);
|
||||
PFD_SUPPORT_OPENGL |
|
||||
(display_win32->wgl_support_gdi ? PFD_SUPPORT_GDI : 0);
|
||||
|
||||
struct {
|
||||
int index;
|
||||
@@ -507,7 +481,7 @@ choose_pixel_format_opengl32 (GdkWin32Display *display_win32,
|
||||
pfd.cBlueBits != 8 || pfd.cAlphaBits != 8))
|
||||
continue;
|
||||
|
||||
current.distance = get_distance (&pfd, best_swap_flags);
|
||||
current.distance = get_distance (&pfd);
|
||||
|
||||
if (best.index == 0 || current.distance < best.distance)
|
||||
best = current;
|
||||
@@ -621,11 +595,15 @@ create_dummy_gl_window (void)
|
||||
}
|
||||
|
||||
static bool
|
||||
check_vendor_is_nvidia (void)
|
||||
check_driver_is_d3d12 (void)
|
||||
{
|
||||
const char *vendor = (const char *) glGetString (GL_VENDOR);
|
||||
const char *renderer = (const char *) glGetString (GL_RENDERER);
|
||||
|
||||
return g_ascii_strncasecmp (vendor, "NVIDIA", strlen ("NVIDIA")) == 0;
|
||||
return vendor != NULL &&
|
||||
g_ascii_strncasecmp (vendor, "MICROSOFT", strlen ("MICROSOFT")) == 0 &&
|
||||
renderer != NULL &&
|
||||
g_ascii_strncasecmp (renderer, "D3D12", strlen ("D3D12")) == 0;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
@@ -640,7 +618,6 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
|
||||
return NULL;
|
||||
|
||||
|
||||
/* acquire and cache dummy Window (HWND & HDC) and
|
||||
* dummy GL Context, it is used to query functions
|
||||
* and used for other stuff as well
|
||||
@@ -681,7 +658,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
display_win32->hasGlWINSwapHint =
|
||||
epoxy_has_gl_extension ("GL_WIN_swap_hint");
|
||||
|
||||
display_win32->wgl_quirks.disallow_swap_exchange = check_vendor_is_nvidia ();
|
||||
display_win32->wgl_support_gdi = check_driver_is_d3d12();
|
||||
|
||||
context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
|
||||
"display", display,
|
||||
@@ -700,7 +677,7 @@ 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"
|
||||
" - Quirks / disallow swap exchange: %s\n"
|
||||
" - GDI compatibility required: %s\n"
|
||||
" - Checked extensions:\n"
|
||||
"\t* WGL_ARB_pixel_format: %s\n"
|
||||
"\t* WGL_ARB_create_context: %s\n"
|
||||
@@ -710,7 +687,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
major, minor,
|
||||
glGetString (GL_VENDOR),
|
||||
glGetString (GL_RENDERER),
|
||||
display_win32->wgl_quirks.disallow_swap_exchange ? "enabled" : "disabled",
|
||||
display_win32->wgl_support_gdi ? "yes" : "no",
|
||||
display_win32->hasWglARBPixelFormat ? "yes" : "no",
|
||||
display_win32->hasWglARBCreateContext ? "yes" : "no",
|
||||
display_win32->hasWglEXTSwapControl ? "yes" : "no",
|
||||
@@ -1118,15 +1095,16 @@ 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:
|
||||
if (!display_win32->wgl_quirks.disallow_swap_exchange)
|
||||
context_wgl->swap_method = SWAP_METHOD_EXCHANGE;
|
||||
context_wgl->swap_method = SWAP_METHOD_EXCHANGE;
|
||||
break;
|
||||
default:
|
||||
context_wgl->swap_method = SWAP_METHOD_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1141,7 +1119,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) && !display_win32->wgl_quirks.disallow_swap_exchange)
|
||||
else if (pfd.dwFlags & PFD_SWAP_EXCHANGE)
|
||||
context_wgl->swap_method = SWAP_METHOD_EXCHANGE;
|
||||
else
|
||||
context_wgl->swap_method = SWAP_METHOD_UNDEFINED;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* 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,7 +37,6 @@ typedef struct _GdkWin32HDataOutputStreamPrivate GdkWin32HDataOutputStreamPriva
|
||||
struct _GdkWin32HDataOutputStreamPrivate
|
||||
{
|
||||
HANDLE handle;
|
||||
GdkWin32Clipdrop *clipdrop;
|
||||
guchar *data;
|
||||
gsize data_allocated_size;
|
||||
gsize data_length;
|
||||
@@ -205,13 +204,12 @@ gdk_win32_hdata_output_stream_close (GOutputStream *output_stream,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gdk_win32_clipdrop_transmute_contentformat (priv->clipdrop,
|
||||
priv->pair.contentformat,
|
||||
priv->pair.w32format,
|
||||
priv->data,
|
||||
priv->data_length,
|
||||
&transmuted_data,
|
||||
&transmuted_data_length))
|
||||
if (!_gdk_win32_transmute_contentformat (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"),
|
||||
@@ -345,8 +343,7 @@ gdk_win32_hdata_output_stream_init (GdkWin32HDataOutputStream *stream)
|
||||
}
|
||||
|
||||
GOutputStream *
|
||||
gdk_win32_hdata_output_stream_new (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ContentFormatPair *pair,
|
||||
gdk_win32_hdata_output_stream_new (GdkWin32ContentFormatPair *pair,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32HDataOutputStream *stream;
|
||||
@@ -372,7 +369,6 @@ gdk_win32_hdata_output_stream_new (GdkWin32Clipdrop *clipdrop,
|
||||
|
||||
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,8 +51,7 @@ struct GdkWin32HDataOutputStreamClass
|
||||
|
||||
GType gdk_win32_hdata_output_stream_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GOutputStream *gdk_win32_hdata_output_stream_new (GdkWin32Clipdrop *clipdrop,
|
||||
GdkWin32ContentFormatPair *pair,
|
||||
GOutputStream *gdk_win32_hdata_output_stream_new (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 "gdkdisplay-win32.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
#include "gdkinput-dmanipulation.h"
|
||||
@@ -48,6 +48,9 @@
|
||||
|
||||
typedef BOOL
|
||||
(WINAPI *getPointerType_t)(UINT32 pointerId, POINTER_INPUT_TYPE *pointerType);
|
||||
static getPointerType_t getPointerType;
|
||||
|
||||
static IDirectManipulationManager *dmanipulation_manager;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -200,13 +203,12 @@ 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 (display, &cursor);
|
||||
_gdk_win32_get_cursor_pos (&cursor);
|
||||
|
||||
ScreenToClient (GDK_SURFACE_HWND (self->surface), &cursor);
|
||||
|
||||
@@ -264,14 +266,13 @@ 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 (display, &cursor);
|
||||
_gdk_win32_get_cursor_pos (&cursor);
|
||||
|
||||
ScreenToClient (GDK_SURFACE_HWND (self->surface), &cursor);
|
||||
|
||||
@@ -326,7 +327,7 @@ dmanip_event_handler_new (GdkSurface *surface,
|
||||
handler->gesture = gesture;
|
||||
|
||||
handler->surface = surface;
|
||||
handler->device = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface))->device_manager->core_pointer;
|
||||
handler->device = _gdk_device_manager->core_pointer;
|
||||
|
||||
dmanip_event_handler_running_state_clear (handler);
|
||||
|
||||
@@ -377,28 +378,6 @@ 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,
|
||||
@@ -409,7 +388,6 @@ 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,
|
||||
@@ -463,14 +441,11 @@ failed:
|
||||
/* {{{ Public */
|
||||
|
||||
|
||||
void gdk_dmanipulation_initialize (GdkWin32Display *display)
|
||||
void gdk_dmanipulation_initialize (void)
|
||||
{
|
||||
if (display->dmanip_items == NULL)
|
||||
if (!getPointerType)
|
||||
{
|
||||
IDirectManipulationManager *dmanipulation_manager;
|
||||
getPointerType_t getPointerType;
|
||||
HMODULE user32_mod;
|
||||
HRESULT hr;
|
||||
|
||||
user32_mod = LoadLibraryW (L"user32.dll");
|
||||
if (!user32_mod)
|
||||
@@ -484,22 +459,20 @@ void gdk_dmanipulation_initialize (GdkWin32Display *display)
|
||||
|
||||
if (!getPointerType)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gdk_win32_ensure_com ())
|
||||
if (!gdk_win32_ensure_com ())
|
||||
return;
|
||||
|
||||
display->dmanip_items = g_new0 (dmanip_items, 1);
|
||||
display->dmanip_items->getPointerType = getPointerType;
|
||||
if (dmanipulation_manager == NULL)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
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);
|
||||
@@ -514,7 +487,6 @@ 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;
|
||||
@@ -536,8 +508,6 @@ 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);
|
||||
}
|
||||
@@ -547,9 +517,6 @@ 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,8 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void gdk_dmanipulation_initialize (GdkWin32Display *display);
|
||||
void gdk_win32_display_close_dmanip_manager (GdkDisplay *display);
|
||||
void gdk_dmanipulation_initialize (void);
|
||||
|
||||
void gdk_dmanipulation_initialize_surface (GdkSurface *surface);
|
||||
void gdk_dmanipulation_finalize_surface (GdkSurface *surface);
|
||||
|
||||
+150
-191
@@ -25,7 +25,7 @@
|
||||
#include "gdkdevice-winpointer.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicetoolprivate.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
|
||||
@@ -65,44 +65,40 @@ typedef BOOL
|
||||
typedef BOOL
|
||||
(WINAPI *setWindowFeedbackSetting_t)(HWND hwnd, FEEDBACK_TYPE feedback, DWORD dwFlags, UINT32 size, const VOID *configuration);
|
||||
|
||||
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 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;
|
||||
|
||||
#define WINPOINTER_API(dm,f) ((GdkDeviceManagerWin32WinpointerFuncs *)dm->winpointer_funcs)->f
|
||||
static ATOM notifications_window_class;
|
||||
static HWND notifications_window_handle;
|
||||
|
||||
static GPtrArray *ignored_interactions;
|
||||
|
||||
static inline void
|
||||
winpointer_ignore_interaction (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT32 pointer_id)
|
||||
winpointer_ignore_interaction (UINT32 pointer_id)
|
||||
{
|
||||
g_ptr_array_add (device_manager->ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
g_ptr_array_add (ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
}
|
||||
|
||||
static inline void
|
||||
winpointer_remove_ignored_interaction (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT32 pointer_id)
|
||||
winpointer_remove_ignored_interaction (UINT32 pointer_id)
|
||||
{
|
||||
g_ptr_array_remove_fast (device_manager->ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
g_ptr_array_remove_fast (ignored_interactions, GUINT_TO_POINTER (pointer_id));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
winpointer_should_ignore_interaction (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT32 pointer_id)
|
||||
winpointer_should_ignore_interaction (UINT32 pointer_id)
|
||||
{
|
||||
return g_ptr_array_find (device_manager->ignored_interactions, GUINT_TO_POINTER (pointer_id), NULL);
|
||||
return g_ptr_array_find (ignored_interactions, GUINT_TO_POINTER (pointer_id), NULL);
|
||||
}
|
||||
|
||||
static inline guint32
|
||||
@@ -140,12 +136,11 @@ copy_axes (double *axes)
|
||||
}
|
||||
|
||||
static GdkDeviceWinpointer*
|
||||
winpointer_find_device_with_source (GdkDeviceManagerWin32 *device_manager,
|
||||
HANDLE device_handle,
|
||||
UINT32 cursor_id,
|
||||
GdkInputSource input_source)
|
||||
winpointer_find_device_with_source (HANDLE device_handle,
|
||||
UINT32 cursor_id,
|
||||
GdkInputSource input_source)
|
||||
{
|
||||
for (GList *l = device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
for (GList *l = _gdk_device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
{
|
||||
GdkDeviceWinpointer *device = (GdkDeviceWinpointer*) l->data;
|
||||
|
||||
@@ -162,10 +157,9 @@ winpointer_find_device_with_source (GdkDeviceManagerWin32 *device_manager,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_get_event_type (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg,
|
||||
POINTER_INFO *info,
|
||||
GdkEventType *evt_type)
|
||||
winpointer_get_event_type (MSG *msg,
|
||||
POINTER_INFO *info,
|
||||
GdkEventType *evt_type)
|
||||
{
|
||||
switch (info->pointerType)
|
||||
{
|
||||
@@ -195,7 +189,7 @@ winpointer_get_event_type (GdkDeviceManagerWin32 *device_manager,
|
||||
if (IS_POINTER_CANCELED_WPARAM (msg->wParam) ||
|
||||
!HAS_POINTER_CONFIDENCE_WPARAM (msg->wParam))
|
||||
{
|
||||
winpointer_ignore_interaction (device_manager, GET_POINTERID_WPARAM (msg->wParam));
|
||||
winpointer_ignore_interaction (GET_POINTERID_WPARAM (msg->wParam));
|
||||
|
||||
if (((info->pointerFlags & POINTER_FLAG_INCONTACT) &&
|
||||
(info->pointerFlags & POINTER_FLAG_UPDATE)) ||
|
||||
@@ -255,11 +249,10 @@ 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 = device_manager->core_pointer;
|
||||
core_device = _gdk_device_manager->core_pointer;
|
||||
|
||||
if (!winpointer_get_event_type (device_manager, msg, info, &evt_type))
|
||||
if (!winpointer_get_event_type (msg, info, &evt_type))
|
||||
return;
|
||||
|
||||
time = winpointer_get_time (msg, info);
|
||||
@@ -406,16 +399,14 @@ 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 (!WINPOINTER_API (device_manager, getPointerType) (pointer_id, &type))
|
||||
if (!getPointerType (pointer_id, &type))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WINPOINTER_API (device_manager, getPointerCursorId) (pointer_id, &cursor_id))
|
||||
if (!getPointerCursorId (pointer_id, &cursor_id))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerCursorId");
|
||||
return;
|
||||
@@ -424,7 +415,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
if (winpointer_should_filter_message (msg, type))
|
||||
return;
|
||||
|
||||
if (winpointer_should_ignore_interaction (device_manager, pointer_id))
|
||||
if (winpointer_should_ignore_interaction (pointer_id))
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
@@ -440,7 +431,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
do
|
||||
{
|
||||
infos = g_new0 (POINTER_PEN_INFO, history_count);
|
||||
if (!WINPOINTER_API (device_manager, getPointerPenInfoHistory) (pointer_id, &history_count, infos))
|
||||
if (!getPointerPenInfoHistory (pointer_id, &history_count, infos))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerPenInfoHistory");
|
||||
g_free (infos);
|
||||
@@ -452,7 +443,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
if (G_UNLIKELY (history_count == 0))
|
||||
return;
|
||||
|
||||
device = winpointer_find_device_with_source (device_manager, infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
device = winpointer_find_device_with_source (infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
if (G_UNLIKELY (!device))
|
||||
{
|
||||
g_free (infos);
|
||||
@@ -493,7 +484,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
do
|
||||
{
|
||||
infos = g_new0 (POINTER_TOUCH_INFO, history_count);
|
||||
if (!WINPOINTER_API (device_manager, getPointerTouchInfoHistory) (pointer_id, &history_count, infos))
|
||||
if (!getPointerTouchInfoHistory (pointer_id, &history_count, infos))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerTouchInfoHistory");
|
||||
g_free (infos);
|
||||
@@ -505,7 +496,7 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
if (G_UNLIKELY (history_count == 0))
|
||||
return;
|
||||
|
||||
device = winpointer_find_device_with_source (device_manager, infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_TOUCHSCREEN);
|
||||
device = winpointer_find_device_with_source (infos->pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_TOUCHSCREEN);
|
||||
if (G_UNLIKELY (!device))
|
||||
{
|
||||
g_free (infos);
|
||||
@@ -533,23 +524,21 @@ gdk_winpointer_input_events (GdkSurface *surface,
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
GdkWin32Display *display_win32,
|
||||
guint32 *time)
|
||||
gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
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 (!WINPOINTER_API (device_manager, getPointerType) (pointer_id, &type))
|
||||
if (!getPointerType (pointer_id, &type))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!WINPOINTER_API (device_manager, getPointerCursorId) (pointer_id, &cursor_id))
|
||||
if (!getPointerCursorId (pointer_id, &cursor_id))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerCursorId");
|
||||
return FALSE;
|
||||
@@ -561,13 +550,13 @@ gdk_winpointer_get_message_info (MSG *msg,
|
||||
{
|
||||
POINTER_PEN_INFO pen_info;
|
||||
|
||||
if (!WINPOINTER_API (device_manager, getPointerPenInfo) (pointer_id, &pen_info))
|
||||
if (!getPointerPenInfo (pointer_id, &pen_info))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerPenInfo");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*device = (GdkDevice*) winpointer_find_device_with_source (device_manager, pen_info.pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
*device = (GdkDevice*) winpointer_find_device_with_source (pen_info.pointerInfo.sourceDevice, cursor_id, GDK_SOURCE_PEN);
|
||||
*time = winpointer_get_time (msg, &pen_info.pointerInfo);
|
||||
}
|
||||
break;
|
||||
@@ -575,14 +564,13 @@ gdk_winpointer_get_message_info (MSG *msg,
|
||||
{
|
||||
POINTER_TOUCH_INFO touch_info;
|
||||
|
||||
if (!WINPOINTER_API (device_manager, getPointerTouchInfo) (pointer_id, &touch_info))
|
||||
if (!getPointerTouchInfo (pointer_id, &touch_info))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerTouchInfo");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*device = GDK_DEVICE (winpointer_find_device_with_source (device_manager,
|
||||
touch_info.pointerInfo.sourceDevice,
|
||||
*device = GDK_DEVICE (winpointer_find_device_with_source (touch_info.pointerInfo.sourceDevice,
|
||||
cursor_id,
|
||||
GDK_SOURCE_TOUCHSCREEN));
|
||||
|
||||
@@ -599,13 +587,12 @@ gdk_winpointer_get_message_info (MSG *msg,
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_winpointer_should_forward_message (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg)
|
||||
gdk_winpointer_should_forward_message (MSG *msg)
|
||||
{
|
||||
UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
|
||||
POINTER_INPUT_TYPE type = PT_POINTER;
|
||||
|
||||
if (!WINPOINTER_API (device_manager, getPointerType) (pointer_id, &type))
|
||||
if (!getPointerType (pointer_id, &type))
|
||||
{
|
||||
WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
|
||||
return TRUE;
|
||||
@@ -615,10 +602,9 @@ gdk_winpointer_should_forward_message (GdkDeviceManagerWin32 *device_manager,
|
||||
}
|
||||
|
||||
void
|
||||
gdk_winpointer_interaction_ended (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg)
|
||||
gdk_winpointer_interaction_ended (MSG *msg)
|
||||
{
|
||||
winpointer_remove_ignored_interaction (device_manager, GET_POINTERID_WPARAM (msg->wParam));
|
||||
winpointer_remove_ignored_interaction (GET_POINTERID_WPARAM (msg->wParam));
|
||||
}
|
||||
|
||||
static inline double
|
||||
@@ -640,13 +626,12 @@ utils_rect_is_degenerate (RECT *rect)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_device_update_scale_factors (GdkDeviceWinpointer *device,
|
||||
GdkDeviceManagerWin32 *device_manager)
|
||||
winpointer_device_update_scale_factors (GdkDeviceWinpointer *device)
|
||||
{
|
||||
RECT device_rect;
|
||||
RECT display_rect;
|
||||
|
||||
if (!WINPOINTER_API (device_manager, getPointerDeviceRects) (device->device_handle, &device_rect, &display_rect))
|
||||
if (!getPointerDeviceRects (device->device_handle, &device_rect, &display_rect))
|
||||
{
|
||||
WIN32_API_FAILED ("GetPointerDeviceRects");
|
||||
return FALSE;
|
||||
@@ -731,9 +716,8 @@ winpointer_get_device_details (HANDLE device,
|
||||
}
|
||||
|
||||
static void
|
||||
winpointer_create_device (GdkDeviceManagerWin32 *device_manager,
|
||||
POINTER_DEVICE_INFO *info,
|
||||
GdkInputSource source)
|
||||
winpointer_create_device (POINTER_DEVICE_INFO *info,
|
||||
GdkInputSource source)
|
||||
{
|
||||
GdkDeviceWinpointer *device = NULL;
|
||||
GdkSeat *seat = NULL;
|
||||
@@ -747,12 +731,12 @@ winpointer_create_device (GdkDeviceManagerWin32 *device_manager,
|
||||
UINT32 num_cursors = 0;
|
||||
GdkAxisFlags axes_flags = 0;
|
||||
|
||||
seat = gdk_display_get_default_seat (device_manager->display);
|
||||
seat = gdk_display_get_default_seat (_gdk_display);
|
||||
|
||||
memset (pid, 0, VID_PID_CHARS + 1);
|
||||
memset (vid, 0, VID_PID_CHARS + 1);
|
||||
|
||||
if (!WINPOINTER_API (device_manager, getPointerDeviceCursors) (info->device, &num_cursors, NULL))
|
||||
if (!getPointerDeviceCursors (info->device, &num_cursors, NULL))
|
||||
{
|
||||
WIN32_API_FAILED ("GetPointerDeviceCursors");
|
||||
return;
|
||||
@@ -796,7 +780,7 @@ winpointer_create_device (GdkDeviceManagerWin32 *device_manager,
|
||||
}
|
||||
|
||||
device = g_object_new (GDK_TYPE_DEVICE_WINPOINTER,
|
||||
"display", device_manager->display,
|
||||
"display", _gdk_display,
|
||||
"seat", seat,
|
||||
"has-cursor", TRUE,
|
||||
"source", source,
|
||||
@@ -836,7 +820,7 @@ winpointer_create_device (GdkDeviceManagerWin32 *device_manager,
|
||||
device->start_cursor_id = info->startingCursorId;
|
||||
device->end_cursor_id = info->startingCursorId + num_cursors - 1;
|
||||
|
||||
if (!winpointer_device_update_scale_factors (device, device_manager))
|
||||
if (!winpointer_device_update_scale_factors (device))
|
||||
{
|
||||
g_set_object (&device, NULL);
|
||||
goto cleanup;
|
||||
@@ -860,10 +844,10 @@ winpointer_create_device (GdkDeviceManagerWin32 *device_manager,
|
||||
break;
|
||||
}
|
||||
|
||||
device_manager->winpointer_devices = g_list_append (device_manager->winpointer_devices, device);
|
||||
_gdk_device_manager->winpointer_devices = g_list_append (_gdk_device_manager->winpointer_devices, 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_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_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), GDK_DEVICE (device));
|
||||
|
||||
@@ -875,17 +859,16 @@ cleanup:
|
||||
}
|
||||
|
||||
static void
|
||||
winpointer_create_devices (GdkDeviceManagerWin32 *device_manager,
|
||||
POINTER_DEVICE_INFO *info)
|
||||
winpointer_create_devices (POINTER_DEVICE_INFO *info)
|
||||
{
|
||||
switch (info->pointerDeviceType)
|
||||
{
|
||||
case POINTER_DEVICE_TYPE_INTEGRATED_PEN:
|
||||
case POINTER_DEVICE_TYPE_EXTERNAL_PEN:
|
||||
winpointer_create_device (device_manager, info, GDK_SOURCE_PEN);
|
||||
winpointer_create_device (info, GDK_SOURCE_PEN);
|
||||
break;
|
||||
case POINTER_DEVICE_TYPE_TOUCH:
|
||||
winpointer_create_device (device_manager, info, GDK_SOURCE_TOUCHSCREEN);
|
||||
winpointer_create_device (info, GDK_SOURCE_TOUCHSCREEN);
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
@@ -911,10 +894,9 @@ winpointer_find_device_in_system_list (GdkDeviceWinpointer *device,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_find_system_device_in_device_manager (GdkDeviceManagerWin32 *device_manager,
|
||||
POINTER_DEVICE_INFO *info)
|
||||
winpointer_find_system_device_in_device_manager (POINTER_DEVICE_INFO *info)
|
||||
{
|
||||
for (GList *l = device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
for (GList *l = _gdk_device_manager->winpointer_devices; l != NULL; l = l->next)
|
||||
{
|
||||
GdkDeviceWinpointer *device = GDK_DEVICE_WINPOINTER (l->data);
|
||||
|
||||
@@ -929,7 +911,7 @@ winpointer_find_system_device_in_device_manager (GdkDeviceManagerWin32 *device_m
|
||||
}
|
||||
|
||||
static void
|
||||
winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
winpointer_enumerate_devices (void)
|
||||
{
|
||||
POINTER_DEVICE_INFO *infos = NULL;
|
||||
UINT32 infos_count = 0;
|
||||
@@ -939,7 +921,7 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
do
|
||||
{
|
||||
infos = g_new0 (POINTER_DEVICE_INFO, infos_count);
|
||||
if (!WINPOINTER_API (device_manager, getPointerDevices) (&infos_count, infos))
|
||||
if (!getPointerDevices (&infos_count, infos))
|
||||
{
|
||||
WIN32_API_FAILED ("GetPointerDevices");
|
||||
g_free (infos);
|
||||
@@ -948,7 +930,7 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
}
|
||||
while (infos_count > 0 && !infos);
|
||||
|
||||
current = device_manager->winpointer_devices;
|
||||
current = _gdk_device_manager->winpointer_devices;
|
||||
|
||||
while (current != NULL)
|
||||
{
|
||||
@@ -959,7 +941,7 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (device));
|
||||
|
||||
device_manager->winpointer_devices = g_list_delete_link (device_manager->winpointer_devices,
|
||||
_gdk_device_manager->winpointer_devices = g_list_delete_link (_gdk_device_manager->winpointer_devices,
|
||||
current);
|
||||
|
||||
gdk_device_update_tool (GDK_DEVICE (device), NULL);
|
||||
@@ -971,7 +953,7 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
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 (device_manager->core_pointer, GDK_DEVICE (device));
|
||||
_gdk_device_remove_physical_device (_gdk_device_manager->core_pointer, GDK_DEVICE (device));
|
||||
|
||||
gdk_seat_default_remove_physical_device (GDK_SEAT_DEFAULT (seat), GDK_DEVICE (device));
|
||||
|
||||
@@ -979,7 +961,7 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
}
|
||||
else
|
||||
{
|
||||
winpointer_device_update_scale_factors (device, device_manager);
|
||||
winpointer_device_update_scale_factors (device);
|
||||
}
|
||||
|
||||
current = next;
|
||||
@@ -988,9 +970,9 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
|
||||
/* create new gdk devices */
|
||||
for (i = 0; i < infos_count; i++)
|
||||
{
|
||||
if (!winpointer_find_system_device_in_device_manager (device_manager, &infos[i]))
|
||||
if (!winpointer_find_system_device_in_device_manager (&infos[i]))
|
||||
{
|
||||
winpointer_create_devices (device_manager, &infos[i]);
|
||||
winpointer_create_devices (&infos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1003,31 +985,20 @@ 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:
|
||||
device_manager = (GdkDeviceManagerWin32 *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
|
||||
winpointer_enumerate_devices (device_manager);
|
||||
winpointer_enumerate_devices ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProcW (hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static HWND
|
||||
winpointer_notif_window_create (GdkDeviceManagerWin32 *device_manager)
|
||||
static gboolean
|
||||
winpointer_notif_window_create (void)
|
||||
{
|
||||
WNDCLASSEXW wndclassex;
|
||||
ATOM notifications_window_class;
|
||||
HWND notification_window_hwnd = NULL;
|
||||
|
||||
memset (&wndclassex, 0, sizeof (wndclassex));
|
||||
wndclassex.cbSize = sizeof (wndclassex);
|
||||
@@ -1035,111 +1006,100 @@ winpointer_notif_window_create (GdkDeviceManagerWin32 *device_manager)
|
||||
wndclassex.lpfnWndProc = winpointer_notifications_window_procedure;
|
||||
wndclassex.hInstance = this_module ();
|
||||
|
||||
notifications_window_class = RegisterClassExW (&wndclassex);
|
||||
|
||||
if (notifications_window_class != 0)
|
||||
if ((notifications_window_class = RegisterClassExW (&wndclassex)) == 0)
|
||||
{
|
||||
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);
|
||||
|
||||
if (notification_window_hwnd == NULL)
|
||||
WIN32_API_FAILED ("CreateWindowExW");
|
||||
WIN32_API_FAILED ("RegisterClassExW");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
WIN32_API_FAILED ("RegisterClassExW");
|
||||
|
||||
return notification_window_hwnd;
|
||||
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)))
|
||||
{
|
||||
WIN32_API_FAILED ("CreateWindowExW");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
winpointer_ensure_procedures (GdkDeviceManagerWin32 *device_manager)
|
||||
winpointer_ensure_procedures (void)
|
||||
{
|
||||
GdkDeviceManagerWin32WinpointerFuncs *funcs = NULL;
|
||||
static gsize user32_dll_checked = 0;
|
||||
static HMODULE user32_dll = NULL;
|
||||
|
||||
if (g_once_init_enter (&user32_dll_checked))
|
||||
if (!user32_dll)
|
||||
{
|
||||
HMODULE user32_dll = NULL;
|
||||
|
||||
user32_dll = LoadLibraryW (L"user32.dll");
|
||||
if (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;
|
||||
WIN32_API_FAILED ("LoadLibraryW");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
WIN32_API_FAILED ("LoadLibraryW");
|
||||
|
||||
g_once_init_leave (&user32_dll_checked, 1);
|
||||
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");
|
||||
}
|
||||
|
||||
return (device_manager->winpointer_funcs != NULL);
|
||||
return registerPointerDeviceNotifications &&
|
||||
getPointerDevices &&
|
||||
getPointerDeviceCursors &&
|
||||
getPointerDeviceRects &&
|
||||
getPointerType &&
|
||||
getPointerCursorId &&
|
||||
getPointerPenInfo &&
|
||||
getPointerTouchInfo &&
|
||||
getPointerPenInfoHistory &&
|
||||
getPointerTouchInfoHistory &&
|
||||
setGestureConfig;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_winpointer_initialize (GdkDeviceManagerWin32 *device_manager)
|
||||
gdk_winpointer_initialize (void)
|
||||
{
|
||||
HWND notification_hwnd = NULL;
|
||||
if (!winpointer_ensure_procedures (device_manager))
|
||||
if (!winpointer_ensure_procedures ())
|
||||
return FALSE;
|
||||
|
||||
notification_hwnd = winpointer_notif_window_create (device_manager);
|
||||
if (notification_hwnd == NULL)
|
||||
if (!winpointer_notif_window_create ())
|
||||
return FALSE;
|
||||
|
||||
if (!WINPOINTER_API (device_manager, registerPointerDeviceNotifications) (notification_hwnd, FALSE))
|
||||
if (!registerPointerDeviceNotifications (notifications_window_handle, FALSE))
|
||||
{
|
||||
WIN32_API_FAILED ("RegisterPointerDeviceNotifications");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
device_manager->winpointer_notification_hwnd = notification_hwnd;
|
||||
device_manager->ignored_interactions = g_ptr_array_new ();
|
||||
ignored_interactions = g_ptr_array_new ();
|
||||
|
||||
winpointer_enumerate_devices (device_manager);
|
||||
winpointer_enumerate_devices ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1160,14 +1120,13 @@ gdk_winpointer_initialize_surface (GdkSurface *surface)
|
||||
TABLET_DISABLE_FLICKS |
|
||||
TABLET_DISABLE_FLICKFALLBACKKEYS);
|
||||
|
||||
GdkDeviceManagerWin32 *device_manager = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface))->device_manager;
|
||||
winpointer_ensure_procedures (device_manager);
|
||||
winpointer_ensure_procedures ();
|
||||
|
||||
key = GlobalAddAtom (MICROSOFT_TABLETPENSERVICE_PROPERTY);
|
||||
API_CALL (SetPropW, (hwnd, (LPCWSTR)(guintptr)key, val));
|
||||
GlobalDeleteAtom (key);
|
||||
|
||||
if (WINPOINTER_API (device_manager, setGestureConfig) != NULL)
|
||||
if (setGestureConfig != NULL)
|
||||
{
|
||||
GESTURECONFIG gesture_config;
|
||||
memset (&gesture_config, 0, sizeof (gesture_config));
|
||||
@@ -1176,10 +1135,10 @@ gdk_winpointer_initialize_surface (GdkSurface *surface)
|
||||
gesture_config.dwWant = 0;
|
||||
gesture_config.dwBlock = GC_ALLGESTURES;
|
||||
|
||||
API_CALL (WINPOINTER_API (device_manager,setGestureConfig), (hwnd, 0, 1, &gesture_config, sizeof (gesture_config)));
|
||||
API_CALL (setGestureConfig, (hwnd, 0, 1, &gesture_config, sizeof (gesture_config)));
|
||||
}
|
||||
|
||||
if (WINPOINTER_API (device_manager, setWindowFeedbackSetting) != NULL)
|
||||
if (setWindowFeedbackSetting != NULL)
|
||||
{
|
||||
FEEDBACK_TYPE feedbacks[] = {
|
||||
FEEDBACK_TOUCH_CONTACTVISUALIZATION,
|
||||
@@ -1200,7 +1159,7 @@ gdk_winpointer_initialize_surface (GdkSurface *surface)
|
||||
{
|
||||
BOOL setting = FALSE;
|
||||
|
||||
API_CALL (WINPOINTER_API (device_manager, setWindowFeedbackSetting), (hwnd, feedbacks[i], 0, sizeof (BOOL), &setting));
|
||||
API_CALL (setWindowFeedbackSetting, (hwnd, feedbacks[i], 0, sizeof (BOOL), &setting));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "winpointer.h"
|
||||
|
||||
gboolean gdk_winpointer_initialize (GdkDeviceManagerWin32 *device_manager);
|
||||
gboolean gdk_winpointer_initialize (void);
|
||||
|
||||
void gdk_winpointer_initialize_surface (GdkSurface *surface);
|
||||
void gdk_winpointer_finalize_surface (GdkSurface *surface);
|
||||
@@ -30,15 +30,12 @@ typedef void
|
||||
POINT *screen_pt,
|
||||
guint32 time_);
|
||||
|
||||
gboolean gdk_winpointer_should_forward_message (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg);
|
||||
gboolean gdk_winpointer_should_forward_message (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,
|
||||
GdkWin32Display *display_win32,
|
||||
guint32 *time_);
|
||||
void gdk_winpointer_interaction_ended (GdkDeviceManagerWin32 *device_manager,
|
||||
MSG *msg);
|
||||
gboolean gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
guint32 *time_);
|
||||
void gdk_winpointer_interaction_ended (MSG *msg);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user